aboutsummaryrefslogtreecommitdiff
path: root/src/burn
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn')
-rw-r--r--src/burn/engine/core.cpp2
-rw-r--r--src/burn/engine/externalengine.cpp86
-rw-r--r--src/burn/engine/pseudobundle.cpp77
-rw-r--r--src/burn/engine/pseudobundle.h12
-rw-r--r--src/burn/engine/userexperience.cpp44
-rw-r--r--src/burn/engine/userexperience.h9
6 files changed, 195 insertions, 35 deletions
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp
index bbd0ff96..812c7261 100644
--- a/src/burn/engine/core.cpp
+++ b/src/burn/engine/core.cpp
@@ -1193,7 +1193,7 @@ extern "C" HRESULT CoreCreateUpdateBundleCommandLine(
1193{ 1193{
1194 HRESULT hr = S_OK; 1194 HRESULT hr = S_OK;
1195 1195
1196 hr = CoreRecreateCommandLine(psczCommandLine, BOOTSTRAPPER_ACTION_INSTALL, pInternalCommand, pCommand, BOOTSTRAPPER_RELATION_NONE, FALSE); 1196 hr = CoreRecreateCommandLine(psczCommandLine, BOOTSTRAPPER_ACTION_INSTALL, pInternalCommand, pCommand, BOOTSTRAPPER_RELATION_UPDATE, FALSE);
1197 ExitOnFailure(hr, "Failed to recreate update bundle command-line."); 1197 ExitOnFailure(hr, "Failed to recreate update bundle command-line.");
1198 1198
1199LExit: 1199LExit:
diff --git a/src/burn/engine/externalengine.cpp b/src/burn/engine/externalengine.cpp
index da84c83d..abe9b8bc 100644
--- a/src/burn/engine/externalengine.cpp
+++ b/src/burn/engine/externalengine.cpp
@@ -269,64 +269,82 @@ HRESULT ExternalEngineSetUpdate(
269 ) 269 )
270{ 270{
271 HRESULT hr = S_OK; 271 HRESULT hr = S_OK;
272 BOOL fLeaveCriticalSection = FALSE;
272 LPWSTR sczFilePath = NULL; 273 LPWSTR sczFilePath = NULL;
273 LPWSTR sczCommandline = NULL; 274 LPWSTR sczCommandline = NULL;
275 LPWSTR sczPreviousId = NULL;
276 LPCWSTR wzNewId = NULL;
274 UUID guid = { }; 277 UUID guid = { };
275 WCHAR wzGuid[39]; 278 WCHAR wzGuid[39];
276 RPC_STATUS rs = RPC_S_OK; 279 RPC_STATUS rs = RPC_S_OK;
280 BOOL fRemove = (!wzLocalSource || !*wzLocalSource) && (!wzDownloadSource || !*wzDownloadSource);
281
282 UserExperienceOnSetUpdateBegin(&pEngineState->userExperience);
277 283
278 ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive); 284 ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive);
285 fLeaveCriticalSection = TRUE;
279 hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience); 286 hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience);
280 ExitOnFailure(hr, "Engine is active, cannot change engine state."); 287 ExitOnFailure(hr, "Engine is active, cannot change engine state.");
281 288
282 if ((!wzLocalSource || !*wzLocalSource) && (!wzDownloadSource || !*wzDownloadSource)) 289 if (!fRemove)
283 {
284 UpdateUninitialize(&pEngineState->update);
285 }
286 else if (BOOTSTRAPPER_UPDATE_HASH_TYPE_NONE == hashType && (0 != cbHash || rgbHash))
287 { 290 {
288 hr = E_INVALIDARG; 291 if (BOOTSTRAPPER_UPDATE_HASH_TYPE_NONE == hashType && (0 != cbHash || rgbHash))
292 {
293 ExitFunction1(hr = E_INVALIDARG);
294 }
295 else if (BOOTSTRAPPER_UPDATE_HASH_TYPE_SHA512 == hashType && (SHA512_HASH_LEN != cbHash || !rgbHash))
296 {
297 ExitFunction1(hr = E_INVALIDARG);
298 }
289 } 299 }
290 else if (BOOTSTRAPPER_UPDATE_HASH_TYPE_SHA512 == hashType && (SHA512_HASH_LEN != cbHash || !rgbHash)) 300
301 sczPreviousId = pEngineState->update.package.sczId;
302 pEngineState->update.package.sczId = NULL;
303 UpdateUninitialize(&pEngineState->update);
304
305 if (fRemove)
291 { 306 {
292 hr = E_INVALIDARG; 307 ExitFunction();
293 } 308 }
294 else
295 {
296 UpdateUninitialize(&pEngineState->update);
297 309
298 hr = CoreCreateUpdateBundleCommandLine(&sczCommandline, &pEngineState->internalCommand, &pEngineState->command); 310 hr = CoreCreateUpdateBundleCommandLine(&sczCommandline, &pEngineState->internalCommand, &pEngineState->command);
299 ExitOnFailure(hr, "Failed to create command-line for update bundle."); 311 ExitOnFailure(hr, "Failed to create command-line for update bundle.");
300 312
301 // Bundles would fail to use the downloaded update bundle, as the running bundle would be one of the search paths. 313 // Bundles would fail to use the downloaded update bundle, as the running bundle would be one of the search paths.
302 // Here I am generating a random guid, but in the future it would be nice if the feed would provide the ID of the update. 314 // Here I am generating a random guid, but in the future it would be nice if the feed would provide the ID of the update.
303 rs = ::UuidCreate(&guid); 315 rs = ::UuidCreate(&guid);
304 hr = HRESULT_FROM_RPC(rs); 316 hr = HRESULT_FROM_RPC(rs);
305 ExitOnFailure(hr, "Failed to create bundle update guid."); 317 ExitOnFailure(hr, "Failed to create bundle update guid.");
306 318
307 if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) 319 if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid)))
308 { 320 {
309 hr = E_OUTOFMEMORY; 321 hr = E_OUTOFMEMORY;
310 ExitOnRootFailure(hr, "Failed to convert bundle update guid into string."); 322 ExitOnRootFailure(hr, "Failed to convert bundle update guid into string.");
311 } 323 }
312 324
313 hr = StrAllocFormatted(&sczFilePath, L"%ls\\%ls", wzGuid, pEngineState->registration.sczExecutableName); 325 hr = StrAllocFormatted(&sczFilePath, L"%ls\\%ls", wzGuid, pEngineState->registration.sczExecutableName);
314 ExitOnFailure(hr, "Failed to build bundle update file path."); 326 ExitOnFailure(hr, "Failed to build bundle update file path.");
315 327
316 if (!wzLocalSource || !*wzLocalSource) 328 if (!wzLocalSource || !*wzLocalSource)
317 { 329 {
318 wzLocalSource = sczFilePath; 330 wzLocalSource = sczFilePath;
319 } 331 }
320 332
321 hr = PseudoBundleInitialize(FILEMAKEVERSION(rmj, rmm, rup, rpr), &pEngineState->update.package, FALSE, pEngineState->registration.sczId, BOOTSTRAPPER_RELATION_UPDATE, BOOTSTRAPPER_PACKAGE_STATE_ABSENT, FALSE, sczFilePath, wzLocalSource, wzDownloadSource, qwSize, TRUE, sczCommandline, NULL, NULL, NULL, rgbHash, cbHash); 333 hr = PseudoBundleInitializeUpdateBundle(&pEngineState->update.package, wzGuid, pEngineState->registration.sczId, sczFilePath, wzLocalSource, wzDownloadSource, qwSize, sczCommandline, rgbHash, cbHash);
322 ExitOnFailure(hr, "Failed to set update bundle."); 334 ExitOnFailure(hr, "Failed to set update bundle.");
323 335
324 pEngineState->update.fUpdateAvailable = TRUE; 336 pEngineState->update.fUpdateAvailable = TRUE;
325 } 337 wzNewId = wzGuid;
326 338
327LExit: 339LExit:
328 ::LeaveCriticalSection(&pEngineState->userExperience.csEngineActive); 340 if (fLeaveCriticalSection)
341 {
342 ::LeaveCriticalSection(&pEngineState->userExperience.csEngineActive);
343 }
344
345 UserExperienceOnSetUpdateComplete(&pEngineState->userExperience, hr, sczPreviousId, wzNewId);
329 346
347 ReleaseStr(sczPreviousId);
330 ReleaseStr(sczCommandline); 348 ReleaseStr(sczCommandline);
331 ReleaseStr(sczFilePath); 349 ReleaseStr(sczFilePath);
332 350
diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp
index 52b7bd8a..91c6c14f 100644
--- a/src/burn/engine/pseudobundle.cpp
+++ b/src/burn/engine/pseudobundle.cpp
@@ -240,3 +240,80 @@ LExit:
240 ReleaseStr(sczArguments); 240 ReleaseStr(sczArguments);
241 return hr; 241 return hr;
242} 242}
243
244extern "C" HRESULT PseudoBundleInitializeUpdateBundle(
245 __in BURN_PACKAGE* pPackage,
246 __in_z LPCWSTR wzId,
247 __in_z LPCWSTR wzCacheId,
248 __in_z LPCWSTR wzFilePath,
249 __in_z LPCWSTR wzLocalSource,
250 __in_z_opt LPCWSTR wzDownloadSource,
251 __in DWORD64 qwSize,
252 __in_z LPCWSTR wzInstallArguments,
253 __in_opt const BYTE* pbHash,
254 __in const DWORD cbHash
255 )
256{
257 HRESULT hr = S_OK;
258 BURN_PAYLOAD* pPayload = NULL;
259
260 // Initialize the single payload, and fill out all the necessary fields
261 pPackage->payloads.rgItems = (BURN_PAYLOAD_GROUP_ITEM*)MemAlloc(sizeof(BURN_PAYLOAD_GROUP_ITEM), TRUE);
262 ExitOnNull(pPackage->payloads.rgItems, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload group inside of update bundle struct");
263 pPackage->payloads.cItems = 1;
264
265 pPayload = (BURN_PAYLOAD*)MemAlloc(sizeof(BURN_PAYLOAD), TRUE);
266 ExitOnNull(pPayload, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload inside of update bundle struct");
267 pPackage->payloads.rgItems[0].pPayload = pPayload;
268 pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL;
269 pPayload->qwFileSize = qwSize;
270 pPayload->verification = BURN_PAYLOAD_VERIFICATION_UPDATE_BUNDLE;
271
272 hr = StrAllocString(&pPayload->sczKey, wzId, 0);
273 ExitOnFailure(hr, "Failed to copy key for pseudo bundle payload.");
274
275 hr = StrAllocString(&pPayload->sczFilePath, wzFilePath, 0);
276 ExitOnFailure(hr, "Failed to copy filename for pseudo bundle.");
277
278 hr = StrAllocString(&pPayload->sczSourcePath, wzLocalSource, 0);
279 ExitOnFailure(hr, "Failed to copy local source path for pseudo bundle.");
280
281 if (wzDownloadSource && *wzDownloadSource)
282 {
283 hr = StrAllocString(&pPayload->downloadSource.sczUrl, wzDownloadSource, 0);
284 ExitOnFailure(hr, "Failed to copy download source for pseudo bundle.");
285 }
286
287 if (pbHash)
288 {
289 pPayload->pbHash = static_cast<BYTE*>(MemAlloc(cbHash, FALSE));
290 ExitOnNull(pPayload->pbHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for update bundle payload hash.");
291
292 pPayload->cbHash = cbHash;
293 memcpy_s(pPayload->pbHash, pPayload->cbHash, pbHash, cbHash);
294 }
295
296 pPackage->Exe.fPseudoBundle = TRUE;
297
298 pPackage->type = BURN_PACKAGE_TYPE_EXE;
299 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
300 pPackage->qwInstallSize = qwSize;
301 pPackage->qwSize = qwSize;
302 pPackage->fVital = TRUE;
303
304 hr = StrAllocString(&pPackage->sczId, wzId, 0);
305 ExitOnFailure(hr, "Failed to copy id for update bundle.");
306
307 hr = StrAllocString(&pPackage->sczCacheId, wzCacheId, 0);
308 ExitOnFailure(hr, "Failed to copy cache id for update bundle.");
309
310 hr = StrAllocString(&pPackage->Exe.sczInstallArguments, wzInstallArguments, 0);
311 ExitOnFailure(hr, "Failed to copy install arguments for update bundle package");
312
313 // Assume the update bundle has the same engine version as this one.
314 pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_BURN;
315 pPackage->Exe.fSupportsAncestors = TRUE;
316
317LExit:
318 return hr;
319} \ No newline at end of file
diff --git a/src/burn/engine/pseudobundle.h b/src/burn/engine/pseudobundle.h
index aa26d29d..0fd4cbdb 100644
--- a/src/burn/engine/pseudobundle.h
+++ b/src/burn/engine/pseudobundle.h
@@ -32,6 +32,18 @@ HRESULT PseudoBundleInitializePassthrough(
32 __in BOOTSTRAPPER_COMMAND* pCommand, 32 __in BOOTSTRAPPER_COMMAND* pCommand,
33 __in BURN_PACKAGE* pPackage 33 __in BURN_PACKAGE* pPackage
34 ); 34 );
35HRESULT PseudoBundleInitializeUpdateBundle(
36 __in BURN_PACKAGE* pPackage,
37 __in_z LPCWSTR wzId,
38 __in_z LPCWSTR wzCacheId,
39 __in_z LPCWSTR wzFilePath,
40 __in_z LPCWSTR wzLocalSource,
41 __in_z_opt LPCWSTR wzDownloadSource,
42 __in DWORD64 qwSize,
43 __in_z LPCWSTR wzInstallArguments,
44 __in_opt const BYTE* pbHash,
45 __in const DWORD cbHash
46 );
35 47
36#if defined(__cplusplus) 48#if defined(__cplusplus)
37} 49}
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp
index 2bd6ecaf..a6d670ea 100644
--- a/src/burn/engine/userexperience.cpp
+++ b/src/burn/engine/userexperience.cpp
@@ -2241,6 +2241,50 @@ LExit:
2241 return hr; 2241 return hr;
2242} 2242}
2243 2243
2244EXTERN_C BAAPI UserExperienceOnSetUpdateBegin(
2245 __in BURN_USER_EXPERIENCE* pUserExperience
2246 )
2247{
2248 HRESULT hr = S_OK;
2249 BA_ONSETUPDATEBEGIN_ARGS args = { };
2250 BA_ONSETUPDATEBEGIN_RESULTS results = { };
2251
2252 args.cbSize = sizeof(args);
2253
2254 results.cbSize = sizeof(results);
2255
2256 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATEBEGIN, &args, &results);
2257 ExitOnFailure(hr, "BA OnSetUpdateBegin failed.");
2258
2259LExit:
2260 return hr;
2261}
2262
2263EXTERN_C BAAPI UserExperienceOnSetUpdateComplete(
2264 __in BURN_USER_EXPERIENCE* pUserExperience,
2265 __in HRESULT hrStatus,
2266 __in_z_opt LPCWSTR wzPreviousPackageId,
2267 __in_z_opt LPCWSTR wzNewPackageId
2268 )
2269{
2270 HRESULT hr = S_OK;
2271 BA_ONSETUPDATECOMPLETE_ARGS args = { };
2272 BA_ONSETUPDATECOMPLETE_RESULTS results = { };
2273
2274 args.cbSize = sizeof(args);
2275 args.hrStatus = hrStatus;
2276 args.wzPreviousPackageId = wzPreviousPackageId;
2277 args.wzNewPackageId = wzNewPackageId;
2278
2279 results.cbSize = sizeof(results);
2280
2281 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE, &args, &results);
2282 ExitOnFailure(hr, "BA OnSetUpdateComplete failed.");
2283
2284LExit:
2285 return hr;
2286}
2287
2244EXTERN_C BAAPI UserExperienceOnShutdown( 2288EXTERN_C BAAPI UserExperienceOnShutdown(
2245 __in BURN_USER_EXPERIENCE* pUserExperience, 2289 __in BURN_USER_EXPERIENCE* pUserExperience,
2246 __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction 2290 __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h
index 2493569b..f7ac962c 100644
--- a/src/burn/engine/userexperience.h
+++ b/src/burn/engine/userexperience.h
@@ -505,6 +505,15 @@ BAAPI UserExperienceOnRollbackMsiTransactionComplete(
505 __in LPCWSTR wzTransactionId, 505 __in LPCWSTR wzTransactionId,
506 __in HRESULT hrStatus 506 __in HRESULT hrStatus
507 ); 507 );
508BAAPI UserExperienceOnSetUpdateBegin(
509 __in BURN_USER_EXPERIENCE* pUserExperience
510 );
511BAAPI UserExperienceOnSetUpdateComplete(
512 __in BURN_USER_EXPERIENCE* pUserExperience,
513 __in HRESULT hrStatus,
514 __in_z_opt LPCWSTR wzPreviousPackageId,
515 __in_z_opt LPCWSTR wzNewPackageId
516 );
508BAAPI UserExperienceOnShutdown( 517BAAPI UserExperienceOnShutdown(
509 __in BURN_USER_EXPERIENCE* pUserExperience, 518 __in BURN_USER_EXPERIENCE* pUserExperience,
510 __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction 519 __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction