aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine/cache.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-08-03 15:41:18 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-08-04 10:03:57 -0500
commit6d7a275edafb3ae0f3cff94d66503a82dafb71f7 (patch)
treefae8f75e2cd1d7b179b0ed93e15625d68ba7c441 /src/burn/engine/cache.cpp
parented57d171f6fb6bb4e180696cc12caa568599566a (diff)
downloadwix-6d7a275edafb3ae0f3cff94d66503a82dafb71f7.tar.gz
wix-6d7a275edafb3ae0f3cff94d66503a82dafb71f7.tar.bz2
wix-6d7a275edafb3ae0f3cff94d66503a82dafb71f7.zip
Replace static cache internals with a struct.
Initialize them explicitly to make it clearer when that happens.
Diffstat (limited to 'src/burn/engine/cache.cpp')
-rw-r--r--src/burn/engine/cache.cpp505
1 files changed, 259 insertions, 246 deletions
diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp
index a35b83bc..54328091 100644
--- a/src/burn/engine/cache.cpp
+++ b/src/burn/engine/cache.cpp
@@ -9,40 +9,37 @@ static const LPCWSTR PACKAGE_CACHE_FOLDER_NAME = L"Package Cache";
9static const DWORD FILE_OPERATION_RETRY_COUNT = 3; 9static const DWORD FILE_OPERATION_RETRY_COUNT = 3;
10static const DWORD FILE_OPERATION_RETRY_WAIT = 2000; 10static const DWORD FILE_OPERATION_RETRY_WAIT = 2000;
11 11
12static BOOL vfInitializedCache = FALSE;
13static BOOL vfRunningFromCache = FALSE;
14static LPWSTR vsczSourceProcessFolder = NULL;
15static LPWSTR vsczWorkingFolder = NULL;
16static LPWSTR vsczDefaultUserPackageCache = NULL;
17static LPWSTR vsczDefaultMachinePackageCache = NULL;
18static LPWSTR vsczCurrentMachinePackageCache = NULL;
19
20static HRESULT CacheVerifyPayloadSignature( 12static HRESULT CacheVerifyPayloadSignature(
21 __in BURN_PAYLOAD* pPayload, 13 __in BURN_PAYLOAD* pPayload,
22 __in_z LPCWSTR wzUnverifiedPayloadPath, 14 __in_z LPCWSTR wzUnverifiedPayloadPath,
23 __in HANDLE hFile 15 __in HANDLE hFile
24 ); 16 );
25static HRESULT CalculateWorkingFolder( 17static HRESULT CalculateWorkingFolder(
26 __in_z LPCWSTR wzBundleId, 18 __in BURN_CACHE* pCache,
27 __deref_out_z LPWSTR* psczWorkingFolder 19 __in BURN_ENGINE_COMMAND* pInternalCommand
28 ); 20 );
29static HRESULT GetLastUsedSourceFolder( 21static HRESULT GetLastUsedSourceFolder(
30 __in BURN_VARIABLES* pVariables, 22 __in BURN_VARIABLES* pVariables,
31 __out_z LPWSTR* psczLastSource 23 __out_z LPWSTR* psczLastSource
32 ); 24 );
33static HRESULT SecurePerMachineCacheRoot(); 25static HRESULT SecurePerMachineCacheRoot(
26 __in BURN_CACHE* pCache
27 );
34static HRESULT CreateCompletedPath( 28static HRESULT CreateCompletedPath(
29 __in BURN_CACHE* pCache,
35 __in BOOL fPerMachine, 30 __in BOOL fPerMachine,
36 __in LPCWSTR wzCacheId, 31 __in LPCWSTR wzCacheId,
37 __in LPCWSTR wzFilePath, 32 __in LPCWSTR wzFilePath,
38 __out_z LPWSTR* psczCachePath 33 __out_z LPWSTR* psczCachePath
39 ); 34 );
40static HRESULT CreateUnverifiedPath( 35static HRESULT CreateUnverifiedPath(
36 __in BURN_CACHE* pCache,
41 __in BOOL fPerMachine, 37 __in BOOL fPerMachine,
42 __in_z LPCWSTR wzPayloadId, 38 __in_z LPCWSTR wzPayloadId,
43 __out_z LPWSTR* psczUnverifiedPayloadPath 39 __out_z LPWSTR* psczUnverifiedPayloadPath
44 ); 40 );
45static HRESULT GetRootPath( 41static HRESULT GetRootPath(
42 __in BURN_CACHE* pCache,
46 __in BOOL fPerMachine, 43 __in BOOL fPerMachine,
47 __in BOOL fAllowRedirect, 44 __in BOOL fAllowRedirect,
48 __deref_out_z LPWSTR* psczRootPath 45 __deref_out_z LPWSTR* psczRootPath
@@ -101,6 +98,7 @@ static HRESULT SecurePath(
101 __in LPCWSTR wzPath 98 __in LPCWSTR wzPath
102 ); 99 );
103static HRESULT CopyEngineToWorkingFolder( 100static HRESULT CopyEngineToWorkingFolder(
101 __in BURN_CACHE* pCache,
104 __in_z LPCWSTR wzSourcePath, 102 __in_z LPCWSTR wzSourcePath,
105 __in_z LPCWSTR wzWorkingFolderName, 103 __in_z LPCWSTR wzWorkingFolderName,
106 __in_z LPCWSTR wzExecutableName, 104 __in_z LPCWSTR wzExecutableName,
@@ -114,6 +112,7 @@ static HRESULT CopyEngineWithSignatureFixup(
114 __in BURN_SECTION* pSection 112 __in BURN_SECTION* pSection
115 ); 113 );
116static HRESULT RemoveBundleOrPackage( 114static HRESULT RemoveBundleOrPackage(
115 __in BURN_CACHE* pCache,
117 __in BOOL fBundle, 116 __in BOOL fBundle,
118 __in BOOL fPerMachine, 117 __in BOOL fPerMachine,
119 __in_z LPCWSTR wzBundleOrPackageId, 118 __in_z LPCWSTR wzBundleOrPackageId,
@@ -158,11 +157,79 @@ static HRESULT SendCacheCompleteMessage(
158 157
159 158
160extern "C" HRESULT CacheInitialize( 159extern "C" HRESULT CacheInitialize(
160 __in BURN_CACHE* pCache,
161 __in BURN_ENGINE_COMMAND* pInternalCommand
162 )
163{
164 Assert(!pCache->fInitializedCache);
165
166 HRESULT hr = S_OK;
167 LPWSTR sczAppData = NULL;
168 int nCompare = 0;
169
170 // Cache paths are initialized once so they cannot be changed while the engine is caching payloads.
171 // Always construct the default machine package cache path so we can determine if we're redirected.
172 hr = PathGetKnownFolder(CSIDL_COMMON_APPDATA, &sczAppData);
173 ExitOnFailure(hr, "Failed to find local %hs appdata directory.", "per-machine");
174
175 hr = PathConcat(sczAppData, PACKAGE_CACHE_FOLDER_NAME, &pCache->sczDefaultMachinePackageCache);
176 ExitOnFailure(hr, "Failed to construct %hs package cache directory name.", "per-machine");
177
178 hr = PathBackslashTerminate(&pCache->sczDefaultMachinePackageCache);
179 ExitOnFailure(hr, "Failed to backslash terminate default %hs package cache directory name.", "per-machine");
180
181
182 // The machine package cache can be redirected through policy.
183 hr = PolcReadString(POLICY_BURN_REGISTRY_PATH, L"PackageCache", NULL, &pCache->sczCurrentMachinePackageCache);
184 ExitOnFailure(hr, "Failed to read PackageCache policy directory.");
185
186 if (pCache->sczCurrentMachinePackageCache)
187 {
188 hr = PathBackslashTerminate(&pCache->sczCurrentMachinePackageCache);
189 ExitOnFailure(hr, "Failed to backslash terminate redirected per-machine package cache directory name.");
190 }
191 else
192 {
193 hr = StrAllocString(&pCache->sczCurrentMachinePackageCache, pCache->sczDefaultMachinePackageCache, 0);
194 ExitOnFailure(hr, "Failed to copy default package cache directory to current package cache directory.");
195 }
196
197 hr = PathCompare(pCache->sczDefaultMachinePackageCache, pCache->sczCurrentMachinePackageCache, &nCompare);
198 ExitOnFailure(hr, "Failed to compare default and current package cache directories.");
199
200 pCache->fCustomMachinePackageCache = CSTR_EQUAL != nCompare;
201
202
203 hr = PathGetKnownFolder(CSIDL_LOCAL_APPDATA, &sczAppData);
204 ExitOnFailure(hr, "Failed to find local %hs appdata directory.", "per-user");
205
206 hr = PathConcat(sczAppData, PACKAGE_CACHE_FOLDER_NAME, &pCache->sczDefaultUserPackageCache);
207 ExitOnFailure(hr, "Failed to construct %hs package cache directory name.", "per-user");
208
209 hr = PathBackslashTerminate(&pCache->sczDefaultUserPackageCache);
210 ExitOnFailure(hr, "Failed to backslash terminate default %hs package cache directory name.", "per-user");
211
212
213 hr = CalculateWorkingFolder(pCache, pInternalCommand);
214
215 pCache->fInitializedCache = TRUE;
216
217LExit:
218 ReleaseStr(sczAppData);
219
220 return hr;
221}
222
223
224extern "C" HRESULT CacheInitializeSources(
225 __in BURN_CACHE* pCache,
161 __in BURN_REGISTRATION* pRegistration, 226 __in BURN_REGISTRATION* pRegistration,
162 __in BURN_VARIABLES* pVariables, 227 __in BURN_VARIABLES* pVariables,
163 __in_z_opt LPCWSTR wzSourceProcessPath 228 __in BURN_ENGINE_COMMAND* pInternalCommand
164 ) 229 )
165{ 230{
231 Assert(!pCache->fInitializedCacheSources);
232
166 HRESULT hr = S_OK; 233 HRESULT hr = S_OK;
167 LPWSTR sczCurrentPath = NULL; 234 LPWSTR sczCurrentPath = NULL;
168 LPWSTR sczCompletedFolder = NULL; 235 LPWSTR sczCompletedFolder = NULL;
@@ -170,66 +237,64 @@ extern "C" HRESULT CacheInitialize(
170 LPWSTR sczOriginalSource = NULL; 237 LPWSTR sczOriginalSource = NULL;
171 LPWSTR sczOriginalSourceFolder = NULL; 238 LPWSTR sczOriginalSourceFolder = NULL;
172 int nCompare = 0; 239 int nCompare = 0;
240 LPCWSTR wzSourceProcessPath = pInternalCommand->sczSourceProcessPath;
173 241
174 if (!vfInitializedCache) 242 hr = PathForCurrentProcess(&sczCurrentPath, NULL);
175 { 243 ExitOnFailure(hr, "Failed to get current process path.");
176 hr = PathForCurrentProcess(&sczCurrentPath, NULL);
177 ExitOnFailure(hr, "Failed to get current process path.");
178 244
179 // Determine if we are running from the package cache or not. 245 // Determine if we are running from the package cache or not.
180 hr = CacheGetCompletedPath(pRegistration->fPerMachine, pRegistration->sczId, &sczCompletedFolder); 246 hr = CacheGetCompletedPath(pCache, pRegistration->fPerMachine, pRegistration->sczId, &sczCompletedFolder);
181 ExitOnFailure(hr, "Failed to get completed path for bundle."); 247 ExitOnFailure(hr, "Failed to get completed path for bundle.");
182 248
183 hr = PathConcat(sczCompletedFolder, pRegistration->sczExecutableName, &sczCompletedPath); 249 hr = PathConcat(sczCompletedFolder, pRegistration->sczExecutableName, &sczCompletedPath);
184 ExitOnFailure(hr, "Failed to combine working path with engine file name."); 250 ExitOnFailure(hr, "Failed to combine working path with engine file name.");
185 251
186 hr = PathCompare(sczCurrentPath, sczCompletedPath, &nCompare); 252 hr = PathCompare(sczCurrentPath, sczCompletedPath, &nCompare);
187 ExitOnFailure(hr, "Failed to compare current path for bundle: %ls", sczCurrentPath); 253 ExitOnFailure(hr, "Failed to compare current path for bundle: %ls", sczCurrentPath);
188 254
189 vfRunningFromCache = (CSTR_EQUAL == nCompare); 255 pCache->fRunningFromCache = (CSTR_EQUAL == nCompare);
190 256
191 // If a source process path was not provided (e.g. we are not being 257 // If a source process path was not provided (e.g. we are not being
192 // run in a clean room) then use the current process path as the 258 // run in a clean room) then use the current process path as the
193 // source process path. 259 // source process path.
194 if (!wzSourceProcessPath) 260 if (!wzSourceProcessPath)
195 { 261 {
196 wzSourceProcessPath = sczCurrentPath; 262 wzSourceProcessPath = sczCurrentPath;
197 } 263 }
198 264
199 hr = PathGetDirectory(wzSourceProcessPath, &vsczSourceProcessFolder); 265 hr = PathGetDirectory(wzSourceProcessPath, &pCache->sczSourceProcessFolder);
200 ExitOnFailure(hr, "Failed to initialize cache source folder."); 266 ExitOnFailure(hr, "Failed to initialize cache source folder.");
201 267
202 // If we're not running from the cache, ensure the original source is set. 268 // If we're not running from the cache, ensure the original source is set.
203 if (!vfRunningFromCache) 269 if (!pCache->fRunningFromCache)
270 {
271 // If the original source has not been set already then set it where the bundle is
272 // running from right now. This value will be persisted and we'll use it when launched
273 // from the clean room or package cache since none of our packages will be relative to
274 // those locations.
275 hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, &sczOriginalSource);
276 if (E_NOTFOUND == hr)
204 { 277 {
205 // If the original source has not been set already then set it where the bundle is 278 hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, wzSourceProcessPath, FALSE, FALSE);
206 // running from right now. This value will be persisted and we'll use it when launched 279 ExitOnFailure(hr, "Failed to set original source variable.");
207 // from the clean room or package cache since none of our packages will be relative to
208 // those locations.
209 hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, &sczOriginalSource);
210 if (E_NOTFOUND == hr)
211 {
212 hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, wzSourceProcessPath, FALSE, FALSE);
213 ExitOnFailure(hr, "Failed to set original source variable.");
214 280
215 hr = StrAllocString(&sczOriginalSource, wzSourceProcessPath, 0); 281 hr = StrAllocString(&sczOriginalSource, wzSourceProcessPath, 0);
216 ExitOnFailure(hr, "Failed to copy current path to original source."); 282 ExitOnFailure(hr, "Failed to copy current path to original source.");
217 } 283 }
218 284
219 hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, &sczOriginalSourceFolder); 285 hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, &sczOriginalSourceFolder);
220 if (E_NOTFOUND == hr) 286 if (E_NOTFOUND == hr)
221 { 287 {
222 hr = PathGetDirectory(sczOriginalSource, &sczOriginalSourceFolder); 288 hr = PathGetDirectory(sczOriginalSource, &sczOriginalSourceFolder);
223 ExitOnFailure(hr, "Failed to get directory from original source path."); 289 ExitOnFailure(hr, "Failed to get directory from original source path.");
224 290
225 hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, sczOriginalSourceFolder, FALSE, FALSE); 291 hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, sczOriginalSourceFolder, FALSE, FALSE);
226 ExitOnFailure(hr, "Failed to set original source directory variable."); 292 ExitOnFailure(hr, "Failed to set original source directory variable.");
227 }
228 } 293 }
229
230 vfInitializedCache = TRUE;
231 } 294 }
232 295
296 pCache->fInitializedCacheSources = TRUE;
297
233LExit: 298LExit:
234 ReleaseStr(sczCurrentPath); 299 ReleaseStr(sczCurrentPath);
235 ReleaseStr(sczCompletedFolder); 300 ReleaseStr(sczCompletedFolder);
@@ -241,99 +306,85 @@ LExit:
241} 306}
242 307
243extern "C" HRESULT CacheEnsureWorkingFolder( 308extern "C" HRESULT CacheEnsureWorkingFolder(
244 __in_z_opt LPCWSTR wzBundleId, 309 __in BURN_CACHE* pCache,
245 __deref_out_z_opt LPWSTR* psczWorkingFolder 310 __deref_out_z_opt LPWSTR* psczWorkingFolder
246 ) 311 )
247{ 312{
248 HRESULT hr = S_OK; 313 Assert(pCache->fInitializedCache);
249 LPWSTR sczWorkingFolder = NULL;
250 314
251 hr = CalculateWorkingFolder(wzBundleId, &sczWorkingFolder); 315 HRESULT hr = S_OK;
252 ExitOnFailure(hr, "Failed to calculate working folder to ensure it exists.");
253 316
254 hr = DirEnsureExists(sczWorkingFolder, NULL); 317 hr = DirEnsureExists(pCache->sczWorkingFolder, NULL);
255 ExitOnFailure(hr, "Failed create working folder."); 318 ExitOnFailure(hr, "Failed create working folder.");
256 319
257 // Best effort to ensure our working folder is not encrypted. 320 // Best effort to ensure our working folder is not encrypted.
258 ::DecryptFileW(sczWorkingFolder, 0); 321 ::DecryptFileW(pCache->sczWorkingFolder, 0);
259 322
260 if (psczWorkingFolder) 323 if (psczWorkingFolder)
261 { 324 {
262 hr = StrAllocString(psczWorkingFolder, sczWorkingFolder, 0); 325 hr = StrAllocString(psczWorkingFolder, pCache->sczWorkingFolder, 0);
263 ExitOnFailure(hr, "Failed to copy working folder."); 326 ExitOnFailure(hr, "Failed to copy working folder.");
264 } 327 }
265 328
266LExit: 329LExit:
267 ReleaseStr(sczWorkingFolder);
268
269 return hr; 330 return hr;
270} 331}
271 332
272extern "C" HRESULT CacheCalculateBundleWorkingPath( 333extern "C" HRESULT CacheCalculateBundleWorkingPath(
273 __in_z LPCWSTR wzBundleId, 334 __in BURN_CACHE* pCache,
274 __in LPCWSTR wzExecutableName, 335 __in LPCWSTR wzExecutableName,
275 __deref_out_z LPWSTR* psczWorkingPath 336 __deref_out_z LPWSTR* psczWorkingPath
276 ) 337 )
277{ 338{
278 Assert(vfInitializedCache); 339 Assert(pCache->fInitializedCache);
279 340
280 HRESULT hr = S_OK; 341 HRESULT hr = S_OK;
281 LPWSTR sczWorkingFolder = NULL;
282 342
283 // If the bundle is running out of the package cache then we use that as the 343 // If the bundle is running out of the package cache then we use that as the
284 // working folder since we feel safe in the package cache. 344 // working folder since we feel safe in the package cache.
285 if (vfRunningFromCache) 345 if (CacheBundleRunningFromCache(pCache))
286 { 346 {
287 hr = PathForCurrentProcess(psczWorkingPath, NULL); 347 hr = PathForCurrentProcess(psczWorkingPath, NULL);
288 ExitOnFailure(hr, "Failed to get current process path."); 348 ExitOnFailure(hr, "Failed to get current process path.");
289 } 349 }
290 else // Otherwise, use the real working folder. 350 else // Otherwise, use the real working folder.
291 { 351 {
292 hr = CalculateWorkingFolder(wzBundleId, &sczWorkingFolder); 352 hr = StrAllocFormatted(psczWorkingPath, L"%ls%ls\\%ls", pCache->sczWorkingFolder, BUNDLE_WORKING_FOLDER_NAME, wzExecutableName);
293 ExitOnFailure(hr, "Failed to get working folder for bundle.");
294
295 hr = StrAllocFormatted(psczWorkingPath, L"%ls%ls\\%ls", sczWorkingFolder, BUNDLE_WORKING_FOLDER_NAME, wzExecutableName);
296 ExitOnFailure(hr, "Failed to calculate the bundle working path."); 353 ExitOnFailure(hr, "Failed to calculate the bundle working path.");
297 } 354 }
298 355
299LExit: 356LExit:
300 ReleaseStr(sczWorkingFolder);
301
302 return hr; 357 return hr;
303} 358}
304 359
305extern "C" HRESULT CacheCalculateBundleLayoutWorkingPath( 360extern "C" HRESULT CacheCalculateBundleLayoutWorkingPath(
361 __in BURN_CACHE* pCache,
306 __in_z LPCWSTR wzBundleId, 362 __in_z LPCWSTR wzBundleId,
307 __deref_out_z LPWSTR* psczWorkingPath 363 __deref_out_z LPWSTR* psczWorkingPath
308 ) 364 )
309{ 365{
310 HRESULT hr = S_OK; 366 Assert(pCache->fInitializedCache);
311 LPWSTR sczWorkingFolder = NULL;
312 367
313 hr = CalculateWorkingFolder(wzBundleId, psczWorkingPath); 368 HRESULT hr = S_OK;
314 ExitOnFailure(hr, "Failed to get working folder for bundle layout.");
315 369
316 hr = StrAllocConcat(psczWorkingPath, wzBundleId, 0); 370 hr = PathConcat(pCache->sczWorkingFolder, wzBundleId, psczWorkingPath);
317 ExitOnFailure(hr, "Failed to append bundle id for bundle layout working path."); 371 ExitOnFailure(hr, "Failed to append bundle id for bundle layout working path.");
318 372
319LExit: 373LExit:
320 ReleaseStr(sczWorkingFolder);
321
322 return hr; 374 return hr;
323} 375}
324 376
325extern "C" HRESULT CacheCalculatePayloadWorkingPath( 377extern "C" HRESULT CacheCalculatePayloadWorkingPath(
326 __in_z LPCWSTR wzBundleId, 378 __in BURN_CACHE* pCache,
327 __in BURN_PAYLOAD* pPayload, 379 __in BURN_PAYLOAD* pPayload,
328 __deref_out_z LPWSTR* psczWorkingPath 380 __deref_out_z LPWSTR* psczWorkingPath
329 ) 381 )
330{ 382{
331 HRESULT hr = S_OK; 383 Assert(pCache->fInitializedCache);
332 384
333 hr = CalculateWorkingFolder(wzBundleId, psczWorkingPath); 385 HRESULT hr = S_OK;
334 ExitOnFailure(hr, "Failed to get working folder for payload.");
335 386
336 hr = StrAllocConcat(psczWorkingPath, pPayload->sczKey, 0); 387 hr = PathConcat(pCache->sczWorkingFolder, pPayload->sczKey, psczWorkingPath);
337 ExitOnFailure(hr, "Failed to append Id as payload unverified path."); 388 ExitOnFailure(hr, "Failed to append Id as payload unverified path.");
338 389
339LExit: 390LExit:
@@ -341,17 +392,16 @@ LExit:
341} 392}
342 393
343extern "C" HRESULT CacheCalculateContainerWorkingPath( 394extern "C" HRESULT CacheCalculateContainerWorkingPath(
344 __in_z LPCWSTR wzBundleId, 395 __in BURN_CACHE* pCache,
345 __in BURN_CONTAINER* pContainer, 396 __in BURN_CONTAINER* pContainer,
346 __deref_out_z LPWSTR* psczWorkingPath 397 __deref_out_z LPWSTR* psczWorkingPath
347 ) 398 )
348{ 399{
349 HRESULT hr = S_OK; 400 Assert(pCache->fInitializedCache);
350 401
351 hr = CalculateWorkingFolder(wzBundleId, psczWorkingPath); 402 HRESULT hr = S_OK;
352 ExitOnFailure(hr, "Failed to get working folder for container.");
353 403
354 hr = StrAllocConcat(psczWorkingPath, pContainer->sczHash, 0); 404 hr = PathConcat(pCache->sczWorkingFolder, pContainer->sczHash, psczWorkingPath);
355 ExitOnFailure(hr, "Failed to append hash as container unverified path."); 405 ExitOnFailure(hr, "Failed to append hash as container unverified path.");
356 406
357LExit: 407LExit:
@@ -359,6 +409,7 @@ LExit:
359} 409}
360 410
361extern "C" HRESULT CacheGetPerMachineRootCompletedPath( 411extern "C" HRESULT CacheGetPerMachineRootCompletedPath(
412 __in BURN_CACHE* pCache,
362 __out_z LPWSTR* psczCurrentRootCompletedPath, 413 __out_z LPWSTR* psczCurrentRootCompletedPath,
363 __out_z LPWSTR* psczDefaultRootCompletedPath 414 __out_z LPWSTR* psczDefaultRootCompletedPath
364 ) 415 )
@@ -368,15 +419,15 @@ extern "C" HRESULT CacheGetPerMachineRootCompletedPath(
368 *psczCurrentRootCompletedPath = NULL; 419 *psczCurrentRootCompletedPath = NULL;
369 *psczDefaultRootCompletedPath = NULL; 420 *psczDefaultRootCompletedPath = NULL;
370 421
371 hr = SecurePerMachineCacheRoot(); 422 hr = SecurePerMachineCacheRoot(pCache);
372 ExitOnFailure(hr, "Failed to secure per-machine cache root."); 423 ExitOnFailure(hr, "Failed to secure per-machine cache root.");
373 424
374 hr = GetRootPath(TRUE, TRUE, psczCurrentRootCompletedPath); 425 hr = GetRootPath(pCache, TRUE, TRUE, psczCurrentRootCompletedPath);
375 ExitOnFailure(hr, "Failed to get per-machine cache root."); 426 ExitOnFailure(hr, "Failed to get per-machine cache root.");
376 427
377 if (S_FALSE == hr) 428 if (S_FALSE == hr)
378 { 429 {
379 hr = GetRootPath(TRUE, FALSE, psczDefaultRootCompletedPath); 430 hr = GetRootPath(pCache, TRUE, FALSE, psczDefaultRootCompletedPath);
380 ExitOnFailure(hr, "Failed to get default per-machine cache root."); 431 ExitOnFailure(hr, "Failed to get default per-machine cache root.");
381 432
382 hr = S_FALSE; 433 hr = S_FALSE;
@@ -387,6 +438,7 @@ LExit:
387} 438}
388 439
389extern "C" HRESULT CacheGetCompletedPath( 440extern "C" HRESULT CacheGetCompletedPath(
441 __in BURN_CACHE* pCache,
390 __in BOOL fPerMachine, 442 __in BOOL fPerMachine,
391 __in_z LPCWSTR wzCacheId, 443 __in_z LPCWSTR wzCacheId,
392 __deref_out_z LPWSTR* psczCompletedPath 444 __deref_out_z LPWSTR* psczCompletedPath
@@ -398,7 +450,7 @@ extern "C" HRESULT CacheGetCompletedPath(
398 LPWSTR sczCurrentCompletedPath = NULL; 450 LPWSTR sczCurrentCompletedPath = NULL;
399 LPWSTR sczDefaultCompletedPath = NULL; 451 LPWSTR sczDefaultCompletedPath = NULL;
400 452
401 hr = GetRootPath(fPerMachine, TRUE, &sczRootPath); 453 hr = GetRootPath(pCache, fPerMachine, TRUE, &sczRootPath);
402 ExitOnFailure(hr, "Failed to get %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user"); 454 ExitOnFailure(hr, "Failed to get %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user");
403 455
404 // GetRootPath returns S_FALSE if the package cache is redirected elsewhere. 456 // GetRootPath returns S_FALSE if the package cache is redirected elsewhere.
@@ -414,7 +466,7 @@ extern "C" HRESULT CacheGetCompletedPath(
414 // If neither package cache directory exists return the (possibly) redirected package cache directory. 466 // If neither package cache directory exists return the (possibly) redirected package cache directory.
415 if (fRedirected && !DirExists(sczCurrentCompletedPath, NULL)) 467 if (fRedirected && !DirExists(sczCurrentCompletedPath, NULL))
416 { 468 {
417 hr = GetRootPath(fPerMachine, FALSE, &sczRootPath); 469 hr = GetRootPath(pCache, fPerMachine, FALSE, &sczRootPath);
418 ExitOnFailure(hr, "Failed to get old %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user"); 470 ExitOnFailure(hr, "Failed to get old %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user");
419 471
420 hr = PathConcat(sczRootPath, wzCacheId, &sczDefaultCompletedPath); 472 hr = PathConcat(sczRootPath, wzCacheId, &sczDefaultCompletedPath);
@@ -462,6 +514,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
462 __in_z LPCWSTR wzSourcePath, 514 __in_z LPCWSTR wzSourcePath,
463 __in_z LPCWSTR wzDestinationPath, 515 __in_z LPCWSTR wzDestinationPath,
464 __in_z_opt LPCWSTR wzLayoutDirectory, 516 __in_z_opt LPCWSTR wzLayoutDirectory,
517 __in BURN_CACHE* pCache,
465 __in BURN_VARIABLES* pVariables, 518 __in BURN_VARIABLES* pVariables,
466 __inout LPWSTR** prgSearchPaths, 519 __inout LPWSTR** prgSearchPaths,
467 __out DWORD* pcSearchPaths, 520 __out DWORD* pcSearchPaths,
@@ -469,6 +522,8 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
469 __out DWORD* pdwDestinationSearchPath 522 __out DWORD* pdwDestinationSearchPath
470 ) 523 )
471{ 524{
525 AssertSz(pCache->fInitializedCacheSources, "Cache sources weren't initialized");
526
472 HRESULT hr = S_OK; 527 HRESULT hr = S_OK;
473 LPWSTR sczCurrentPath = NULL; 528 LPWSTR sczCurrentPath = NULL;
474 LPWSTR sczLastSourceFolder = NULL; 529 LPWSTR sczLastSourceFolder = NULL;
@@ -481,11 +536,9 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
481 DWORD dwLikelySearchPath = 0; 536 DWORD dwLikelySearchPath = 0;
482 DWORD dwDestinationSearchPath = 0; 537 DWORD dwDestinationSearchPath = 0;
483 538
484 AssertSz(vfInitializedCache, "Cache wasn't initialized");
485
486 hr = GetLastUsedSourceFolder(pVariables, &sczLastSourceFolder); 539 hr = GetLastUsedSourceFolder(pVariables, &sczLastSourceFolder);
487 fPreferSourcePathLocation = !vfRunningFromCache || FAILED(hr); 540 fPreferSourcePathLocation = !pCache->fRunningFromCache || FAILED(hr);
488 fTryLastFolder = SUCCEEDED(hr) && sczLastSourceFolder && *sczLastSourceFolder && CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, vsczSourceProcessFolder, -1, sczLastSourceFolder, -1); 541 fTryLastFolder = SUCCEEDED(hr) && sczLastSourceFolder && *sczLastSourceFolder && CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pCache->sczSourceProcessFolder, -1, sczLastSourceFolder, -1);
489 fTryRelativePath = CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, wzSourcePath, -1, wzRelativePath, -1); 542 fTryRelativePath = CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, wzSourcePath, -1, wzRelativePath, -1);
490 fSourceIsAbsolute = PathIsAbsolute(wzSourcePath); 543 fSourceIsAbsolute = PathIsAbsolute(wzSourcePath);
491 544
@@ -528,7 +581,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
528 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS); 581 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
529 ExitOnFailure(hr, "Failed to ensure size for search paths array."); 582 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
530 583
531 hr = PathConcat(vsczSourceProcessFolder, wzSourcePath, &sczCurrentPath); 584 hr = PathConcat(pCache->sczSourceProcessFolder, wzSourcePath, &sczCurrentPath);
532 ExitOnFailure(hr, "Failed to combine source process folder with source."); 585 ExitOnFailure(hr, "Failed to combine source process folder with source.");
533 586
534 // If we're not running from cache or we couldn't get the last source, 587 // If we're not running from cache or we couldn't get the last source,
@@ -580,7 +633,7 @@ extern "C" HRESULT CacheGetLocalSourcePaths(
580 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS); 633 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgSearchPaths), cSearchPaths + 1, sizeof(LPWSTR), BURN_CACHE_MAX_SEARCH_PATHS);
581 ExitOnFailure(hr, "Failed to ensure size for search paths array."); 634 ExitOnFailure(hr, "Failed to ensure size for search paths array.");
582 635
583 hr = PathConcat(vsczSourceProcessFolder, wzRelativePath, &sczCurrentPath); 636 hr = PathConcat(pCache->sczSourceProcessFolder, wzRelativePath, &sczCurrentPath);
584 ExitOnFailure(hr, "Failed to combine source process folder with relative."); 637 ExitOnFailure(hr, "Failed to combine source process folder with relative.");
585 638
586 if (fPreferSourcePathLocation) 639 if (fPreferSourcePathLocation)
@@ -761,12 +814,17 @@ extern "C" void CacheSendErrorCallback(
761 } 814 }
762} 815}
763 816
764extern "C" BOOL CacheBundleRunningFromCache() 817extern "C" BOOL CacheBundleRunningFromCache(
818 __in BURN_CACHE* pCache
819 )
765{ 820{
766 return vfRunningFromCache; 821 AssertSz(pCache->fInitializedCacheSources, "Cache sources weren't initialized");
822
823 return pCache->fRunningFromCache;
767} 824}
768 825
769HRESULT CachePreparePackage( 826extern "C" HRESULT CachePreparePackage(
827 __in BURN_CACHE* pCache,
770 __in BURN_PACKAGE* pPackage 828 __in BURN_PACKAGE* pPackage
771 ) 829 )
772{ 830{
@@ -774,13 +832,14 @@ HRESULT CachePreparePackage(
774 832
775 if (!pPackage->sczCacheFolder) 833 if (!pPackage->sczCacheFolder)
776 { 834 {
777 hr = CreateCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, NULL, &pPackage->sczCacheFolder); 835 hr = CreateCompletedPath(pCache, pPackage->fPerMachine, pPackage->sczCacheId, NULL, &pPackage->sczCacheFolder);
778 } 836 }
779 837
780 return hr; 838 return hr;
781} 839}
782 840
783extern "C" HRESULT CacheBundleToCleanRoom( 841extern "C" HRESULT CacheBundleToCleanRoom(
842 __in BURN_CACHE* pCache,
784 __in BURN_SECTION* pSection, 843 __in BURN_SECTION* pSection,
785 __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath 844 __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath
786 ) 845 )
@@ -794,7 +853,7 @@ extern "C" HRESULT CacheBundleToCleanRoom(
794 853
795 wzExecutableName = PathFile(sczSourcePath); 854 wzExecutableName = PathFile(sczSourcePath);
796 855
797 hr = CopyEngineToWorkingFolder(sczSourcePath, BUNDLE_CLEAN_ROOM_WORKING_FOLDER_NAME, wzExecutableName, pSection, psczCleanRoomBundlePath); 856 hr = CopyEngineToWorkingFolder(pCache, sczSourcePath, BUNDLE_CLEAN_ROOM_WORKING_FOLDER_NAME, wzExecutableName, pSection, psczCleanRoomBundlePath);
798 ExitOnFailure(hr, "Failed to cache bundle to clean room."); 857 ExitOnFailure(hr, "Failed to cache bundle to clean room.");
799 858
800LExit: 859LExit:
@@ -804,13 +863,13 @@ LExit:
804} 863}
805 864
806extern "C" HRESULT CacheBundleToWorkingDirectory( 865extern "C" HRESULT CacheBundleToWorkingDirectory(
807 __in_z LPCWSTR /*wzBundleId*/, 866 __in BURN_CACHE* pCache,
808 __in_z LPCWSTR wzExecutableName, 867 __in_z LPCWSTR wzExecutableName,
809 __in BURN_SECTION* pSection, 868 __in BURN_SECTION* pSection,
810 __deref_out_z_opt LPWSTR* psczEngineWorkingPath 869 __deref_out_z_opt LPWSTR* psczEngineWorkingPath
811 ) 870 )
812{ 871{
813 Assert(vfInitializedCache); 872 Assert(pCache->fInitializedCache);
814 873
815 HRESULT hr = S_OK; 874 HRESULT hr = S_OK;
816 LPWSTR sczSourcePath = NULL; 875 LPWSTR sczSourcePath = NULL;
@@ -821,14 +880,14 @@ extern "C" HRESULT CacheBundleToWorkingDirectory(
821 880
822 // If the bundle is running out of the package cache then we don't need to copy it to 881 // If the bundle is running out of the package cache then we don't need to copy it to
823 // the working folder since we feel safe in the package cache and will run from there. 882 // the working folder since we feel safe in the package cache and will run from there.
824 if (vfRunningFromCache) 883 if (CacheBundleRunningFromCache(pCache))
825 { 884 {
826 hr = StrAllocString(psczEngineWorkingPath, sczSourcePath, 0); 885 hr = StrAllocString(psczEngineWorkingPath, sczSourcePath, 0);
827 ExitOnFailure(hr, "Failed to use current process path as target path."); 886 ExitOnFailure(hr, "Failed to use current process path as target path.");
828 } 887 }
829 else // otherwise, carry on putting the bundle in the working folder. 888 else // otherwise, carry on putting the bundle in the working folder.
830 { 889 {
831 hr = CopyEngineToWorkingFolder(sczSourcePath, BUNDLE_WORKING_FOLDER_NAME, wzExecutableName, pSection, psczEngineWorkingPath); 890 hr = CopyEngineToWorkingFolder(pCache, sczSourcePath, BUNDLE_WORKING_FOLDER_NAME, wzExecutableName, pSection, psczEngineWorkingPath);
832 ExitOnFailure(hr, "Failed to copy engine to working folder."); 891 ExitOnFailure(hr, "Failed to copy engine to working folder.");
833 } 892 }
834 893
@@ -866,6 +925,7 @@ LExit:
866} 925}
867 926
868extern "C" HRESULT CacheCompleteBundle( 927extern "C" HRESULT CacheCompleteBundle(
928 __in BURN_CACHE* pCache,
869 __in BOOL fPerMachine, 929 __in BOOL fPerMachine,
870 __in_z LPCWSTR wzExecutableName, 930 __in_z LPCWSTR wzExecutableName,
871 __in_z LPCWSTR wzBundleId, 931 __in_z LPCWSTR wzBundleId,
@@ -882,7 +942,7 @@ extern "C" HRESULT CacheCompleteBundle(
882 LPWSTR sczSourceDirectory = NULL; 942 LPWSTR sczSourceDirectory = NULL;
883 LPWSTR sczPayloadSourcePath = NULL; 943 LPWSTR sczPayloadSourcePath = NULL;
884 944
885 hr = CreateCompletedPath(fPerMachine, wzBundleId, NULL, &sczTargetDirectory); 945 hr = CreateCompletedPath(pCache, fPerMachine, wzBundleId, NULL, &sczTargetDirectory);
886 ExitOnFailure(hr, "Failed to create completed cache path for bundle."); 946 ExitOnFailure(hr, "Failed to create completed cache path for bundle.");
887 947
888 hr = PathConcat(sczTargetDirectory, wzExecutableName, &sczTargetPath); 948 hr = PathConcat(sczTargetDirectory, wzExecutableName, &sczTargetPath);
@@ -976,6 +1036,7 @@ LExit:
976} 1036}
977 1037
978extern "C" HRESULT CacheCompletePayload( 1038extern "C" HRESULT CacheCompletePayload(
1039 __in BURN_CACHE* pCache,
979 __in BOOL fPerMachine, 1040 __in BOOL fPerMachine,
980 __in BURN_PAYLOAD* pPayload, 1041 __in BURN_PAYLOAD* pPayload,
981 __in_z LPCWSTR wzCacheId, 1042 __in_z LPCWSTR wzCacheId,
@@ -990,7 +1051,7 @@ extern "C" HRESULT CacheCompletePayload(
990 LPWSTR sczCachedPath = NULL; 1051 LPWSTR sczCachedPath = NULL;
991 LPWSTR sczUnverifiedPayloadPath = NULL; 1052 LPWSTR sczUnverifiedPayloadPath = NULL;
992 1053
993 hr = CreateCompletedPath(fPerMachine, wzCacheId, pPayload->sczFilePath, &sczCachedPath); 1054 hr = CreateCompletedPath(pCache, fPerMachine, wzCacheId, pPayload->sczFilePath, &sczCachedPath);
994 ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", wzCacheId); 1055 ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", wzCacheId);
995 1056
996 // If the cached file matches what we expected, we're good. 1057 // If the cached file matches what we expected, we're good.
@@ -1000,7 +1061,7 @@ extern "C" HRESULT CacheCompletePayload(
1000 ExitFunction(); 1061 ExitFunction();
1001 } 1062 }
1002 1063
1003 hr = CreateUnverifiedPath(fPerMachine, pPayload->sczKey, &sczUnverifiedPayloadPath); 1064 hr = CreateUnverifiedPath(pCache, fPerMachine, pPayload->sczKey, &sczUnverifiedPayloadPath);
1004 ExitOnFailure(hr, "Failed to create unverified path."); 1065 ExitOnFailure(hr, "Failed to create unverified path.");
1005 1066
1006 // If the working path exists, let's get it into the unverified path so we can reset the ACLs and verify the file. 1067 // If the working path exists, let's get it into the unverified path so we can reset the ACLs and verify the file.
@@ -1091,36 +1152,30 @@ LExit:
1091} 1152}
1092 1153
1093extern "C" HRESULT CacheRemoveWorkingFolder( 1154extern "C" HRESULT CacheRemoveWorkingFolder(
1094 __in_z_opt LPCWSTR wzBundleId 1155 __in BURN_CACHE* pCache
1095 ) 1156 )
1096{ 1157{
1097 HRESULT hr = S_OK; 1158 HRESULT hr = S_OK;
1098 LPWSTR sczWorkingFolder = NULL;
1099 1159
1100 if (vfInitializedCache) 1160 if (pCache->fInitializedCacheSources)
1101 { 1161 {
1102 hr = CalculateWorkingFolder(wzBundleId, &sczWorkingFolder);
1103 ExitOnFailure(hr, "Failed to calculate the working folder to remove it.");
1104
1105 // Try to clean out everything in the working folder. 1162 // Try to clean out everything in the working folder.
1106 hr = DirEnsureDeleteEx(sczWorkingFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE); 1163 hr = DirEnsureDeleteEx(pCache->sczWorkingFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE);
1107 TraceError(hr, "Could not delete bundle engine working folder."); 1164 TraceError(hr, "Could not delete bundle engine working folder.");
1108 } 1165 }
1109 1166
1110LExit:
1111 ReleaseStr(sczWorkingFolder);
1112
1113 return hr; 1167 return hr;
1114} 1168}
1115 1169
1116extern "C" HRESULT CacheRemoveBundle( 1170extern "C" HRESULT CacheRemoveBundle(
1171 __in BURN_CACHE* pCache,
1117 __in BOOL fPerMachine, 1172 __in BOOL fPerMachine,
1118 __in_z LPCWSTR wzBundleId 1173 __in_z LPCWSTR wzBundleId
1119 ) 1174 )
1120{ 1175{
1121 HRESULT hr = S_OK; 1176 HRESULT hr = S_OK;
1122 1177
1123 hr = RemoveBundleOrPackage(TRUE, fPerMachine, wzBundleId, wzBundleId); 1178 hr = RemoveBundleOrPackage(pCache, TRUE, fPerMachine, wzBundleId, wzBundleId);
1124 ExitOnFailure(hr, "Failed to remove bundle id: %ls.", wzBundleId); 1179 ExitOnFailure(hr, "Failed to remove bundle id: %ls.", wzBundleId);
1125 1180
1126LExit: 1181LExit:
@@ -1128,6 +1183,7 @@ LExit:
1128} 1183}
1129 1184
1130extern "C" HRESULT CacheRemovePackage( 1185extern "C" HRESULT CacheRemovePackage(
1186 __in BURN_CACHE* pCache,
1131 __in BOOL fPerMachine, 1187 __in BOOL fPerMachine,
1132 __in_z LPCWSTR wzPackageId, 1188 __in_z LPCWSTR wzPackageId,
1133 __in_z LPCWSTR wzCacheId 1189 __in_z LPCWSTR wzCacheId
@@ -1135,7 +1191,7 @@ extern "C" HRESULT CacheRemovePackage(
1135{ 1191{
1136 HRESULT hr = S_OK; 1192 HRESULT hr = S_OK;
1137 1193
1138 hr = RemoveBundleOrPackage(FALSE, fPerMachine, wzPackageId, wzCacheId); 1194 hr = RemoveBundleOrPackage(pCache, FALSE, fPerMachine, wzPackageId, wzCacheId);
1139 ExitOnFailure(hr, "Failed to remove package id: %ls.", wzPackageId); 1195 ExitOnFailure(hr, "Failed to remove package id: %ls.", wzPackageId);
1140 1196
1141LExit: 1197LExit:
@@ -1194,9 +1250,11 @@ LExit:
1194 1250
1195extern "C" void CacheCleanup( 1251extern "C" void CacheCleanup(
1196 __in BOOL fPerMachine, 1252 __in BOOL fPerMachine,
1197 __in_z LPCWSTR wzBundleId 1253 __in BURN_CACHE* pCache
1198 ) 1254 )
1199{ 1255{
1256 Assert(pCache->fInitializedCache);
1257
1200 HRESULT hr = S_OK; 1258 HRESULT hr = S_OK;
1201 LPWSTR sczFolder = NULL; 1259 LPWSTR sczFolder = NULL;
1202 LPWSTR sczFiles = NULL; 1260 LPWSTR sczFiles = NULL;
@@ -1205,7 +1263,7 @@ extern "C" void CacheCleanup(
1205 WIN32_FIND_DATAW wfd = { }; 1263 WIN32_FIND_DATAW wfd = { };
1206 size_t cchFileName = 0; 1264 size_t cchFileName = 0;
1207 1265
1208 hr = CacheGetCompletedPath(fPerMachine, UNVERIFIED_CACHE_FOLDER_NAME, &sczFolder); 1266 hr = CacheGetCompletedPath(pCache, fPerMachine, UNVERIFIED_CACHE_FOLDER_NAME, &sczFolder);
1209 if (SUCCEEDED(hr)) 1267 if (SUCCEEDED(hr))
1210 { 1268 {
1211 hr = DirEnsureDeleteEx(sczFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE); 1269 hr = DirEnsureDeleteEx(sczFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE);
@@ -1213,10 +1271,9 @@ extern "C" void CacheCleanup(
1213 1271
1214 if (!fPerMachine) 1272 if (!fPerMachine)
1215 { 1273 {
1216 hr = CalculateWorkingFolder(wzBundleId, &sczFolder); 1274 if (pCache->sczWorkingFolder)
1217 if (SUCCEEDED(hr))
1218 { 1275 {
1219 hr = PathConcat(sczFolder, L"*.*", &sczFiles); 1276 hr = PathConcat(pCache->sczWorkingFolder, L"*.*", &sczFiles);
1220 if (SUCCEEDED(hr)) 1277 if (SUCCEEDED(hr))
1221 { 1278 {
1222 hFind = ::FindFirstFileW(sczFiles, &wfd); 1279 hFind = ::FindFirstFileW(sczFiles, &wfd);
@@ -1238,7 +1295,7 @@ extern "C" void CacheCleanup(
1238 continue; 1295 continue;
1239 } 1296 }
1240 1297
1241 hr = PathConcatCch(sczFolder, 0, wfd.cFileName, cchFileName, &sczDelete); 1298 hr = PathConcatCch(pCache->sczWorkingFolder, 0, wfd.cFileName, cchFileName, &sczDelete);
1242 if (SUCCEEDED(hr)) 1299 if (SUCCEEDED(hr))
1243 { 1300 {
1244 hr = FileEnsureDelete(sczDelete); 1301 hr = FileEnsureDelete(sczDelete);
@@ -1259,63 +1316,61 @@ extern "C" void CacheCleanup(
1259 ReleaseStr(sczFolder); 1316 ReleaseStr(sczFolder);
1260} 1317}
1261 1318
1262extern "C" void CacheUninitialize() 1319extern "C" void CacheUninitialize(
1320 __in BURN_CACHE* pCache
1321 )
1263{ 1322{
1264 ReleaseNullStr(vsczCurrentMachinePackageCache); 1323 ReleaseNullStr(pCache->sczCurrentMachinePackageCache);
1265 ReleaseNullStr(vsczDefaultMachinePackageCache); 1324 ReleaseNullStr(pCache->sczDefaultMachinePackageCache);
1266 ReleaseNullStr(vsczDefaultUserPackageCache); 1325 ReleaseNullStr(pCache->sczDefaultUserPackageCache);
1267 ReleaseNullStr(vsczWorkingFolder); 1326 ReleaseNullStr(pCache->sczWorkingFolder);
1268 ReleaseNullStr(vsczSourceProcessFolder); 1327 ReleaseNullStr(pCache->sczSourceProcessFolder);
1269 1328
1270 vfRunningFromCache = FALSE; 1329 pCache->fRunningFromCache = FALSE;
1271 vfInitializedCache = FALSE; 1330 pCache->fInitializedCache = FALSE;
1331 pCache->fInitializedCacheSources = FALSE;
1332 pCache->fPerMachineCacheRootVerified = FALSE;
1333 pCache->fOriginalPerMachineCacheRootVerified = FALSE;
1334 pCache->fUnverifiedCacheFolderCreated = FALSE;
1335 pCache->fCustomMachinePackageCache = FALSE;
1272} 1336}
1273 1337
1274// Internal functions. 1338// Internal functions.
1275 1339
1276static HRESULT CalculateWorkingFolder( 1340static HRESULT CalculateWorkingFolder(
1277 __in_z_opt LPCWSTR /*wzBundleId*/, 1341 __in BURN_CACHE* pCache,
1278 __deref_out_z LPWSTR* psczWorkingFolder 1342 __in BURN_ENGINE_COMMAND* pInternalCommand
1279 ) 1343 )
1280{ 1344{
1281 HRESULT hr = S_OK; 1345 HRESULT hr = S_OK;
1282 RPC_STATUS rs = RPC_S_OK; 1346 RPC_STATUS rs = RPC_S_OK;
1283 BOOL fElevated = FALSE;
1284 LPWSTR sczTempPath = NULL; 1347 LPWSTR sczTempPath = NULL;
1285 UUID guid = {}; 1348 UUID guid = {};
1286 WCHAR wzGuid[39]; 1349 WCHAR wzGuid[39];
1287 1350
1288 if (!vsczWorkingFolder) 1351 if (pInternalCommand->fInitiallyElevated)
1289 { 1352 {
1290 ProcElevated(::GetCurrentProcess(), &fElevated); 1353 hr = PathGetSystemTempPath(&sczTempPath);
1291 1354 ExitOnFailure(hr, "Failed to get system temp folder path for working folder.");
1292 if (fElevated) 1355 }
1293 { 1356 else
1294 hr = PathGetSystemTempPath(&sczTempPath); 1357 {
1295 ExitOnFailure(hr, "Failed to get system temp folder path for working folder."); 1358 hr = PathGetTempPath(&sczTempPath);
1296 } 1359 ExitOnFailure(hr, "Failed to get temp folder path for working folder.");
1297 else 1360 }
1298 {
1299 hr = PathGetTempPath(&sczTempPath);
1300 ExitOnFailure(hr, "Failed to get temp folder path for working folder.");
1301 }
1302
1303 rs = ::UuidCreate(&guid);
1304 hr = HRESULT_FROM_RPC(rs);
1305 ExitOnFailure(hr, "Failed to create working folder guid.");
1306 1361
1307 if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) 1362 rs = ::UuidCreate(&guid);
1308 { 1363 hr = HRESULT_FROM_RPC(rs);
1309 hr = E_OUTOFMEMORY; 1364 ExitOnFailure(hr, "Failed to create working folder guid.");
1310 ExitOnRootFailure(hr, "Failed to convert working folder guid into string.");
1311 }
1312 1365
1313 hr = StrAllocFormatted(&vsczWorkingFolder, L"%ls%ls\\", sczTempPath, wzGuid); 1366 if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid)))
1314 ExitOnFailure(hr, "Failed to append bundle id on to temp path for working folder."); 1367 {
1368 hr = E_OUTOFMEMORY;
1369 ExitOnRootFailure(hr, "Failed to convert working folder guid into string.");
1315 } 1370 }
1316 1371
1317 hr = StrAllocString(psczWorkingFolder, vsczWorkingFolder, 0); 1372 hr = StrAllocFormatted(&pCache->sczWorkingFolder, L"%ls%ls\\", sczTempPath, wzGuid);
1318 ExitOnFailure(hr, "Failed to copy working folder path."); 1373 ExitOnFailure(hr, "Failed to append random guid on to temp path for working folder.");
1319 1374
1320LExit: 1375LExit:
1321 ReleaseStr(sczTempPath); 1376 ReleaseStr(sczTempPath);
@@ -1324,78 +1379,33 @@ LExit:
1324} 1379}
1325 1380
1326static HRESULT GetRootPath( 1381static HRESULT GetRootPath(
1382 __in BURN_CACHE* pCache,
1327 __in BOOL fPerMachine, 1383 __in BOOL fPerMachine,
1328 __in BOOL fAllowRedirect, 1384 __in BOOL fAllowRedirect,
1329 __deref_out_z LPWSTR* psczRootPath 1385 __deref_out_z LPWSTR* psczRootPath
1330 ) 1386 )
1331{ 1387{
1388 Assert(pCache->fInitializedCache);
1389
1332 HRESULT hr = S_OK; 1390 HRESULT hr = S_OK;
1333 LPWSTR sczAppData = NULL;
1334 int nCompare = 0;
1335 1391
1336 // Cache paths are initialized once so they cannot be changed while the engine is caching payloads.
1337 if (fPerMachine) 1392 if (fPerMachine)
1338 { 1393 {
1339 // Always construct the default machine package cache path so we can determine if we're redirected. 1394 BOOL fRedirect = fAllowRedirect && pCache->fCustomMachinePackageCache;
1340 if (!vsczDefaultMachinePackageCache)
1341 {
1342 hr = PathGetKnownFolder(CSIDL_COMMON_APPDATA, &sczAppData);
1343 ExitOnFailure(hr, "Failed to find local %hs appdata directory.", "per-machine");
1344
1345 hr = PathConcat(sczAppData, PACKAGE_CACHE_FOLDER_NAME, &vsczDefaultMachinePackageCache);
1346 ExitOnFailure(hr, "Failed to construct %hs package cache directory name.", "per-machine");
1347
1348 hr = PathBackslashTerminate(&vsczDefaultMachinePackageCache);
1349 ExitOnFailure(hr, "Failed to backslash terminate default %hs package cache directory name.", "per-machine");
1350 }
1351 1395
1352 if (!vsczCurrentMachinePackageCache) 1396 hr = StrAllocString(psczRootPath, fRedirect ? pCache->sczCurrentMachinePackageCache : pCache->sczDefaultMachinePackageCache, 0);
1353 {
1354 hr = PolcReadString(POLICY_BURN_REGISTRY_PATH, L"PackageCache", NULL, &vsczCurrentMachinePackageCache);
1355 ExitOnFailure(hr, "Failed to read PackageCache policy directory.");
1356
1357 if (vsczCurrentMachinePackageCache)
1358 {
1359 hr = PathBackslashTerminate(&vsczCurrentMachinePackageCache);
1360 ExitOnFailure(hr, "Failed to backslash terminate redirected per-machine package cache directory name.");
1361 }
1362 else
1363 {
1364 hr = StrAllocString(&vsczCurrentMachinePackageCache, vsczDefaultMachinePackageCache, 0);
1365 ExitOnFailure(hr, "Failed to copy default package cache directory to current package cache directory.");
1366 }
1367 }
1368
1369 hr = StrAllocString(psczRootPath, fAllowRedirect ? vsczCurrentMachinePackageCache : vsczDefaultMachinePackageCache, 0);
1370 ExitOnFailure(hr, "Failed to copy %hs package cache root directory.", "per-machine"); 1397 ExitOnFailure(hr, "Failed to copy %hs package cache root directory.", "per-machine");
1371 1398
1372 hr = PathCompare(vsczDefaultMachinePackageCache, *psczRootPath, &nCompare);
1373 ExitOnFailure(hr, "Failed to compare default and current package cache directories.");
1374
1375 // Return S_FALSE if the current location is not the default location (redirected). 1399 // Return S_FALSE if the current location is not the default location (redirected).
1376 hr = CSTR_EQUAL == nCompare ? S_OK : S_FALSE; 1400 hr = fRedirect ? S_FALSE : S_OK;
1377 } 1401 }
1378 else 1402 else
1379 { 1403 {
1380 if (!vsczDefaultUserPackageCache) 1404 hr = StrAllocString(psczRootPath, pCache->sczDefaultUserPackageCache, 0);
1381 {
1382 hr = PathGetKnownFolder(CSIDL_LOCAL_APPDATA, &sczAppData);
1383 ExitOnFailure(hr, "Failed to find local %hs appdata directory.", "per-user");
1384
1385 hr = PathConcat(sczAppData, PACKAGE_CACHE_FOLDER_NAME, &vsczDefaultUserPackageCache);
1386 ExitOnFailure(hr, "Failed to construct %hs package cache directory name.", "per-user");
1387
1388 hr = PathBackslashTerminate(&vsczDefaultUserPackageCache);
1389 ExitOnFailure(hr, "Failed to backslash terminate default %hs package cache directory name.", "per-user");
1390 }
1391
1392 hr = StrAllocString(psczRootPath, vsczDefaultUserPackageCache, 0);
1393 ExitOnFailure(hr, "Failed to copy %hs package cache root directory.", "per-user"); 1405 ExitOnFailure(hr, "Failed to copy %hs package cache root directory.", "per-user");
1394 } 1406 }
1395 1407
1396LExit: 1408LExit:
1397 ReleaseStr(sczAppData);
1398
1399 return hr; 1409 return hr;
1400} 1410}
1401 1411
@@ -1416,20 +1426,19 @@ static HRESULT GetLastUsedSourceFolder(
1416 return hr; 1426 return hr;
1417} 1427}
1418 1428
1419static HRESULT SecurePerMachineCacheRoot() 1429static HRESULT SecurePerMachineCacheRoot(
1430 __in BURN_CACHE* pCache
1431 )
1420{ 1432{
1421 static BOOL fPerMachineCacheRootVerified = FALSE;
1422 static BOOL fOriginalPerMachineCacheRootVerified = FALSE;
1423
1424 HRESULT hr = S_OK; 1433 HRESULT hr = S_OK;
1425 BOOL fRedirected = FALSE; 1434 BOOL fRedirected = FALSE;
1426 LPWSTR sczCacheDirectory = NULL; 1435 LPWSTR sczCacheDirectory = NULL;
1427 1436
1428 if (!fPerMachineCacheRootVerified) 1437 if (!pCache->fPerMachineCacheRootVerified)
1429 { 1438 {
1430 // If we are doing a permachine install but have not yet verified that the root cache folder 1439 // If we are doing a permachine install but have not yet verified that the root cache folder
1431 // was created with the correct ACLs yet, do that now. 1440 // was created with the correct ACLs yet, do that now.
1432 hr = GetRootPath(TRUE, TRUE, &sczCacheDirectory); 1441 hr = GetRootPath(pCache, TRUE, TRUE, &sczCacheDirectory);
1433 ExitOnFailure(hr, "Failed to get cache directory."); 1442 ExitOnFailure(hr, "Failed to get cache directory.");
1434 1443
1435 fRedirected = S_FALSE == hr; 1444 fRedirected = S_FALSE == hr;
@@ -1440,19 +1449,19 @@ static HRESULT SecurePerMachineCacheRoot()
1440 hr = SecurePath(sczCacheDirectory); 1449 hr = SecurePath(sczCacheDirectory);
1441 ExitOnFailure(hr, "Failed to secure cache directory: %ls", sczCacheDirectory); 1450 ExitOnFailure(hr, "Failed to secure cache directory: %ls", sczCacheDirectory);
1442 1451
1443 fPerMachineCacheRootVerified = TRUE; 1452 pCache->fPerMachineCacheRootVerified = TRUE;
1444 1453
1445 if (!fRedirected) 1454 if (!fRedirected)
1446 { 1455 {
1447 fOriginalPerMachineCacheRootVerified = TRUE; 1456 pCache->fOriginalPerMachineCacheRootVerified = TRUE;
1448 } 1457 }
1449 } 1458 }
1450 1459
1451 if (!fOriginalPerMachineCacheRootVerified) 1460 if (!pCache->fOriginalPerMachineCacheRootVerified)
1452 { 1461 {
1453 // If we are doing a permachine install but have not yet verified that the original root cache folder 1462 // If we are doing a permachine install but have not yet verified that the original root cache folder
1454 // was created with the correct ACLs yet, do that now. 1463 // was created with the correct ACLs yet, do that now.
1455 hr = GetRootPath(TRUE, FALSE, &sczCacheDirectory); 1464 hr = GetRootPath(pCache, TRUE, FALSE, &sczCacheDirectory);
1456 ExitOnFailure(hr, "Failed to get original cache directory."); 1465 ExitOnFailure(hr, "Failed to get original cache directory.");
1457 1466
1458 hr = DirEnsureExists(sczCacheDirectory, NULL); 1467 hr = DirEnsureExists(sczCacheDirectory, NULL);
@@ -1461,7 +1470,7 @@ static HRESULT SecurePerMachineCacheRoot()
1461 hr = SecurePath(sczCacheDirectory); 1470 hr = SecurePath(sczCacheDirectory);
1462 ExitOnFailure(hr, "Failed to secure original cache directory: %ls", sczCacheDirectory); 1471 ExitOnFailure(hr, "Failed to secure original cache directory: %ls", sczCacheDirectory);
1463 1472
1464 fOriginalPerMachineCacheRootVerified = TRUE; 1473 pCache->fOriginalPerMachineCacheRootVerified = TRUE;
1465 } 1474 }
1466 1475
1467LExit: 1476LExit:
@@ -1471,6 +1480,7 @@ LExit:
1471} 1480}
1472 1481
1473static HRESULT CreateCompletedPath( 1482static HRESULT CreateCompletedPath(
1483 __in BURN_CACHE* pCache,
1474 __in BOOL fPerMachine, 1484 __in BOOL fPerMachine,
1475 __in LPCWSTR wzId, 1485 __in LPCWSTR wzId,
1476 __in LPCWSTR wzFilePath, 1486 __in LPCWSTR wzFilePath,
@@ -1483,12 +1493,12 @@ static HRESULT CreateCompletedPath(
1483 1493
1484 if (fPerMachine) 1494 if (fPerMachine)
1485 { 1495 {
1486 hr = SecurePerMachineCacheRoot(); 1496 hr = SecurePerMachineCacheRoot(pCache);
1487 ExitOnFailure(hr, "Failed to secure per-machine cache root."); 1497 ExitOnFailure(hr, "Failed to secure per-machine cache root.");
1488 } 1498 }
1489 1499
1490 // Get the cache completed path. 1500 // Get the cache completed path.
1491 hr = CacheGetCompletedPath(fPerMachine, wzId, &sczCacheDirectory); 1501 hr = CacheGetCompletedPath(pCache, fPerMachine, wzId, &sczCacheDirectory);
1492 ExitOnFailure(hr, "Failed to get cache directory."); 1502 ExitOnFailure(hr, "Failed to get cache directory.");
1493 1503
1494 // Ensure it exists. 1504 // Ensure it exists.
@@ -1523,25 +1533,26 @@ LExit:
1523} 1533}
1524 1534
1525static HRESULT CreateUnverifiedPath( 1535static HRESULT CreateUnverifiedPath(
1536 __in BURN_CACHE* pCache,
1526 __in BOOL fPerMachine, 1537 __in BOOL fPerMachine,
1527 __in_z LPCWSTR wzPayloadId, 1538 __in_z LPCWSTR wzPayloadId,
1528 __out_z LPWSTR* psczUnverifiedPayloadPath 1539 __out_z LPWSTR* psczUnverifiedPayloadPath
1529 ) 1540 )
1530{ 1541{
1531 static BOOL fUnverifiedCacheFolderCreated = FALSE;
1532
1533 HRESULT hr = S_OK; 1542 HRESULT hr = S_OK;
1534 LPWSTR sczUnverifiedCacheFolder = NULL; 1543 LPWSTR sczUnverifiedCacheFolder = NULL;
1535 1544
1536 hr = CacheGetCompletedPath(fPerMachine, UNVERIFIED_CACHE_FOLDER_NAME, &sczUnverifiedCacheFolder); 1545 hr = CacheGetCompletedPath(pCache, fPerMachine, UNVERIFIED_CACHE_FOLDER_NAME, &sczUnverifiedCacheFolder);
1537 ExitOnFailure(hr, "Failed to get cache directory."); 1546 ExitOnFailure(hr, "Failed to get cache directory.");
1538 1547
1539 if (!fUnverifiedCacheFolderCreated) 1548 if (!pCache->fUnverifiedCacheFolderCreated)
1540 { 1549 {
1541 hr = DirEnsureExists(sczUnverifiedCacheFolder, NULL); 1550 hr = DirEnsureExists(sczUnverifiedCacheFolder, NULL);
1542 ExitOnFailure(hr, "Failed to create unverified cache directory: %ls", sczUnverifiedCacheFolder); 1551 ExitOnFailure(hr, "Failed to create unverified cache directory: %ls", sczUnverifiedCacheFolder);
1543 1552
1544 ResetPathPermissions(fPerMachine, sczUnverifiedCacheFolder); 1553 ResetPathPermissions(fPerMachine, sczUnverifiedCacheFolder);
1554
1555 pCache->fUnverifiedCacheFolderCreated = TRUE;
1545 } 1556 }
1546 1557
1547 hr = PathConcat(sczUnverifiedCacheFolder, wzPayloadId, psczUnverifiedPayloadPath); 1558 hr = PathConcat(sczUnverifiedCacheFolder, wzPayloadId, psczUnverifiedPayloadPath);
@@ -1946,6 +1957,7 @@ LExit:
1946 1957
1947 1958
1948static HRESULT CopyEngineToWorkingFolder( 1959static HRESULT CopyEngineToWorkingFolder(
1960 __in BURN_CACHE* pCache,
1949 __in_z LPCWSTR wzSourcePath, 1961 __in_z LPCWSTR wzSourcePath,
1950 __in_z LPCWSTR wzWorkingFolderName, 1962 __in_z LPCWSTR wzWorkingFolderName,
1951 __in_z LPCWSTR wzExecutableName, 1963 __in_z LPCWSTR wzExecutableName,
@@ -1961,7 +1973,7 @@ static HRESULT CopyEngineToWorkingFolder(
1961 LPWSTR sczPayloadSourcePath = NULL; 1973 LPWSTR sczPayloadSourcePath = NULL;
1962 LPWSTR sczPayloadTargetPath = NULL; 1974 LPWSTR sczPayloadTargetPath = NULL;
1963 1975
1964 hr = CacheEnsureWorkingFolder(NULL, &sczWorkingFolder); 1976 hr = CacheEnsureWorkingFolder(pCache, &sczWorkingFolder);
1965 ExitOnFailure(hr, "Failed to create working path to copy engine."); 1977 ExitOnFailure(hr, "Failed to create working path to copy engine.");
1966 1978
1967 hr = PathConcat(sczWorkingFolder, wzWorkingFolderName, &sczTargetDirectory); 1979 hr = PathConcat(sczWorkingFolder, wzWorkingFolderName, &sczTargetDirectory);
@@ -2064,6 +2076,7 @@ LExit:
2064 2076
2065 2077
2066static HRESULT RemoveBundleOrPackage( 2078static HRESULT RemoveBundleOrPackage(
2079 __in BURN_CACHE* pCache,
2067 __in BOOL fBundle, 2080 __in BOOL fBundle,
2068 __in BOOL fPerMachine, 2081 __in BOOL fPerMachine,
2069 __in_z LPCWSTR wzBundleOrPackageId, 2082 __in_z LPCWSTR wzBundleOrPackageId,
@@ -2074,7 +2087,7 @@ static HRESULT RemoveBundleOrPackage(
2074 LPWSTR sczRootCacheDirectory = NULL; 2087 LPWSTR sczRootCacheDirectory = NULL;
2075 LPWSTR sczDirectory = NULL; 2088 LPWSTR sczDirectory = NULL;
2076 2089
2077 hr = CacheGetCompletedPath(fPerMachine, wzCacheId, &sczDirectory); 2090 hr = CacheGetCompletedPath(pCache, fPerMachine, wzCacheId, &sczDirectory);
2078 ExitOnFailure(hr, "Failed to calculate cache path."); 2091 ExitOnFailure(hr, "Failed to calculate cache path.");
2079 2092
2080 LogId(REPORT_STANDARD, fBundle ? MSG_UNCACHE_BUNDLE : MSG_UNCACHE_PACKAGE, wzBundleOrPackageId, sczDirectory); 2093 LogId(REPORT_STANDARD, fBundle ? MSG_UNCACHE_BUNDLE : MSG_UNCACHE_PACKAGE, wzBundleOrPackageId, sczDirectory);
@@ -2103,14 +2116,14 @@ static HRESULT RemoveBundleOrPackage(
2103 else 2116 else
2104 { 2117 {
2105 // Try to remove root package cache in the off chance it is now empty. 2118 // Try to remove root package cache in the off chance it is now empty.
2106 hr = GetRootPath(fPerMachine, TRUE, &sczRootCacheDirectory); 2119 hr = GetRootPath(pCache, fPerMachine, TRUE, &sczRootCacheDirectory);
2107 ExitOnFailure(hr, "Failed to get %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user"); 2120 ExitOnFailure(hr, "Failed to get %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user");
2108 DirEnsureDeleteEx(sczRootCacheDirectory, DIR_DELETE_SCHEDULE); 2121 DirEnsureDeleteEx(sczRootCacheDirectory, DIR_DELETE_SCHEDULE);
2109 2122
2110 // GetRootPath returns S_FALSE if the package cache is redirected elsewhere. 2123 // GetRootPath returns S_FALSE if the package cache is redirected elsewhere.
2111 if (S_FALSE == hr) 2124 if (S_FALSE == hr)
2112 { 2125 {
2113 hr = GetRootPath(fPerMachine, FALSE, &sczRootCacheDirectory); 2126 hr = GetRootPath(pCache, fPerMachine, FALSE, &sczRootCacheDirectory);
2114 ExitOnFailure(hr, "Failed to get old %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user"); 2127 ExitOnFailure(hr, "Failed to get old %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user");
2115 DirEnsureDeleteEx(sczRootCacheDirectory, DIR_DELETE_SCHEDULE); 2128 DirEnsureDeleteEx(sczRootCacheDirectory, DIR_DELETE_SCHEDULE);
2116 } 2129 }