aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine/exeengine.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-01-03 15:35:14 -0600
committerSean Hall <r.sean.hall@gmail.com>2022-01-04 19:19:43 -0600
commit1f5314302b3c8bc1977aed79df1d05c52608f382 (patch)
treef0fef3a4462352c914a4cc9413515d07f2244703 /src/burn/engine/exeengine.cpp
parentdb44f6cf3b1eb476e47384f2eccba5712808def5 (diff)
downloadwix-1f5314302b3c8bc1977aed79df1d05c52608f382.tar.gz
wix-1f5314302b3c8bc1977aed79df1d05c52608f382.tar.bz2
wix-1f5314302b3c8bc1977aed79df1d05c52608f382.zip
Don't assume Exe packages with Burn protocol are bundles.
Related to #3693
Diffstat (limited to 'src/burn/engine/exeengine.cpp')
-rw-r--r--src/burn/engine/exeengine.cpp177
1 files changed, 46 insertions, 131 deletions
diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp
index b728f599..45349ed0 100644
--- a/src/burn/engine/exeengine.cpp
+++ b/src/burn/engine/exeengine.cpp
@@ -3,23 +3,6 @@
3#include "precomp.h" 3#include "precomp.h"
4 4
5 5
6// internal function declarations
7
8static HRESULT HandleExitCode(
9 __in BURN_PACKAGE* pPackage,
10 __in DWORD dwExitCode,
11 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
12 );
13static HRESULT ParseCommandLineArgumentsFromXml(
14 __in IXMLDOMNode* pixnExePackage,
15 __in BURN_PACKAGE* pPackage
16 );
17static HRESULT ParseExitCodesFromXml(
18 __in IXMLDOMNode* pixnExePackage,
19 __in BURN_PACKAGE* pPackage
20 );
21
22
23// function definitions 6// function definitions
24 7
25extern "C" HRESULT ExeEngineParsePackageFromXml( 8extern "C" HRESULT ExeEngineParsePackageFromXml(
@@ -82,10 +65,10 @@ extern "C" HRESULT ExeEngineParsePackageFromXml(
82 ExitOnFailure(hr, "Failed to get @Protocol."); 65 ExitOnFailure(hr, "Failed to get @Protocol.");
83 } 66 }
84 67
85 hr = ParseExitCodesFromXml(pixnExePackage, pPackage); 68 hr = ExeEngineParseExitCodesFromXml(pixnExePackage, &pPackage->Exe.rgExitCodes, &pPackage->Exe.cExitCodes);
86 ExitOnFailure(hr, "Failed to parse exit codes."); 69 ExitOnFailure(hr, "Failed to parse exit codes.");
87 70
88 hr = ParseCommandLineArgumentsFromXml(pixnExePackage, pPackage); 71 hr = ExeEngineParseCommandLineArgumentsFromXml(pixnExePackage, &pPackage->Exe.rgCommandLineArguments, &pPackage->Exe.cCommandLineArguments);
89 ExitOnFailure(hr, "Failed to parse command lines."); 72 ExitOnFailure(hr, "Failed to parse command lines.");
90 73
91LExit: 74LExit:
@@ -104,8 +87,6 @@ extern "C" void ExeEnginePackageUninitialize(
104 ReleaseStr(pPackage->Exe.sczInstallArguments); 87 ReleaseStr(pPackage->Exe.sczInstallArguments);
105 ReleaseStr(pPackage->Exe.sczRepairArguments); 88 ReleaseStr(pPackage->Exe.sczRepairArguments);
106 ReleaseStr(pPackage->Exe.sczUninstallArguments); 89 ReleaseStr(pPackage->Exe.sczUninstallArguments);
107 ReleaseStr(pPackage->Exe.sczIgnoreDependencies);
108 //ReleaseStr(pPackage->Exe.sczProgressSwitch);
109 ReleaseMem(pPackage->Exe.rgExitCodes); 90 ReleaseMem(pPackage->Exe.rgExitCodes);
110 91
111 // free command-line arguments 92 // free command-line arguments
@@ -113,11 +94,7 @@ extern "C" void ExeEnginePackageUninitialize(
113 { 94 {
114 for (DWORD i = 0; i < pPackage->Exe.cCommandLineArguments; ++i) 95 for (DWORD i = 0; i < pPackage->Exe.cCommandLineArguments; ++i)
115 { 96 {
116 BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument = &pPackage->Exe.rgCommandLineArguments[i]; 97 ExeEngineCommandLineArgumentUninitialize(pPackage->Exe.rgCommandLineArguments + i);
117 ReleaseStr(pCommandLineArgument->sczInstallArgument);
118 ReleaseStr(pCommandLineArgument->sczUninstallArgument);
119 ReleaseStr(pCommandLineArgument->sczRepairArgument);
120 ReleaseStr(pCommandLineArgument->sczCondition);
121 } 98 }
122 MemFree(pPackage->Exe.rgCommandLineArguments); 99 MemFree(pPackage->Exe.rgCommandLineArguments);
123 } 100 }
@@ -126,6 +103,16 @@ extern "C" void ExeEnginePackageUninitialize(
126 memset(&pPackage->Exe, 0, sizeof(pPackage->Exe)); 103 memset(&pPackage->Exe, 0, sizeof(pPackage->Exe));
127} 104}
128 105
106extern "C" void ExeEngineCommandLineArgumentUninitialize(
107 __in BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument
108 )
109{
110 ReleaseStr(pCommandLineArgument->sczInstallArgument);
111 ReleaseStr(pCommandLineArgument->sczUninstallArgument);
112 ReleaseStr(pCommandLineArgument->sczRepairArgument);
113 ReleaseStr(pCommandLineArgument->sczCondition);
114}
115
129extern "C" HRESULT ExeEngineDetectPackage( 116extern "C" HRESULT ExeEngineDetectPackage(
130 __in BURN_PACKAGE* pPackage, 117 __in BURN_PACKAGE* pPackage,
131 __in BURN_VARIABLES* pVariables 118 __in BURN_VARIABLES* pVariables
@@ -264,7 +251,6 @@ LExit:
264// PlanAdd - adds the calculated execute and rollback actions for the package. 251// PlanAdd - adds the calculated execute and rollback actions for the package.
265// 252//
266extern "C" HRESULT ExeEnginePlanAddPackage( 253extern "C" HRESULT ExeEnginePlanAddPackage(
267 __in_opt DWORD *pdwInsertSequence,
268 __in BURN_PACKAGE* pPackage, 254 __in BURN_PACKAGE* pPackage,
269 __in BURN_PLAN* pPlan, 255 __in BURN_PLAN* pPlan,
270 __in BURN_LOGGING* pLog, 256 __in BURN_LOGGING* pLog,
@@ -274,46 +260,19 @@ extern "C" HRESULT ExeEnginePlanAddPackage(
274 HRESULT hr = S_OK; 260 HRESULT hr = S_OK;
275 BURN_EXECUTE_ACTION* pAction = NULL; 261 BURN_EXECUTE_ACTION* pAction = NULL;
276 262
277 hr = DependencyPlanPackage(pdwInsertSequence, pPackage, pPlan); 263 hr = DependencyPlanPackage(NULL, pPackage, pPlan);
278 ExitOnFailure(hr, "Failed to plan package dependency actions."); 264 ExitOnFailure(hr, "Failed to plan package dependency actions.");
279 265
280 // add execute action 266 // add execute action
281 if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute) 267 if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute)
282 { 268 {
283 if (NULL != pdwInsertSequence) 269 hr = PlanAppendExecuteAction(pPlan, &pAction);
284 { 270 ExitOnFailure(hr, "Failed to append execute action.");
285 hr = PlanInsertExecuteAction(*pdwInsertSequence, pPlan, &pAction);
286 ExitOnFailure(hr, "Failed to insert execute action.");
287 }
288 else
289 {
290 hr = PlanAppendExecuteAction(pPlan, &pAction);
291 ExitOnFailure(hr, "Failed to append execute action.");
292 }
293 271
294 pAction->type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE; 272 pAction->type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE;
295 pAction->exePackage.pPackage = pPackage; 273 pAction->exePackage.pPackage = pPackage;
296 pAction->exePackage.fFireAndForget = (BOOTSTRAPPER_ACTION_UPDATE_REPLACE == pPlan->action);
297 pAction->exePackage.action = pPackage->execute; 274 pAction->exePackage.action = pPackage->execute;
298 275
299 if (pPackage->Exe.sczIgnoreDependencies)
300 {
301 hr = StrAllocString(&pAction->exePackage.sczIgnoreDependencies, pPackage->Exe.sczIgnoreDependencies, 0);
302 ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore.");
303 }
304
305 if (pPackage->Exe.wzAncestors)
306 {
307 hr = StrAllocString(&pAction->exePackage.sczAncestors, pPackage->Exe.wzAncestors, 0);
308 ExitOnFailure(hr, "Failed to allocate the list of ancestors.");
309 }
310
311 if (pPackage->Exe.wzEngineWorkingDirectory)
312 {
313 hr = StrAllocString(&pAction->exePackage.sczEngineWorkingDirectory, pPackage->Exe.wzEngineWorkingDirectory, 0);
314 ExitOnFailure(hr, "Failed to allocate the custom working directory.");
315 }
316
317 LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, NULL); // ignore errors. 276 LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, NULL); // ignore errors.
318 } 277 }
319 278
@@ -327,18 +286,6 @@ extern "C" HRESULT ExeEnginePlanAddPackage(
327 pAction->exePackage.pPackage = pPackage; 286 pAction->exePackage.pPackage = pPackage;
328 pAction->exePackage.action = pPackage->rollback; 287 pAction->exePackage.action = pPackage->rollback;
329 288
330 if (pPackage->Exe.sczIgnoreDependencies)
331 {
332 hr = StrAllocString(&pAction->exePackage.sczIgnoreDependencies, pPackage->Exe.sczIgnoreDependencies, 0);
333 ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore.");
334 }
335
336 if (pPackage->Exe.wzAncestors)
337 {
338 hr = StrAllocString(&pAction->exePackage.sczAncestors, pPackage->Exe.wzAncestors, 0);
339 ExitOnFailure(hr, "Failed to allocate the list of ancestors.");
340 }
341
342 LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, NULL); // ignore errors. 289 LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, NULL); // ignore errors.
343 } 290 }
344 291
@@ -452,13 +399,13 @@ extern "C" HRESULT ExeEngineExecutePackage(
452 hr = VariableFormatString(pVariables, sczArguments, &sczArgumentsFormatted, NULL); 399 hr = VariableFormatString(pVariables, sczArguments, &sczArgumentsFormatted, NULL);
453 ExitOnFailure(hr, "Failed to format argument string."); 400 ExitOnFailure(hr, "Failed to format argument string.");
454 401
455 hr = StrAllocFormattedSecure(&sczCommand, L"\"%ls\" %s", sczExecutablePath, sczArgumentsFormatted); 402 hr = StrAllocFormattedSecure(&sczCommand, L"\"%ls\" %ls", sczExecutablePath, sczArgumentsFormatted);
456 ExitOnFailure(hr, "Failed to create executable command."); 403 ExitOnFailure(hr, "Failed to create executable command.");
457 404
458 hr = VariableFormatStringObfuscated(pVariables, sczArguments, &sczArgumentsObfuscated, NULL); 405 hr = VariableFormatStringObfuscated(pVariables, sczArguments, &sczArgumentsObfuscated, NULL);
459 ExitOnFailure(hr, "Failed to format obfuscated argument string."); 406 ExitOnFailure(hr, "Failed to format obfuscated argument string.");
460 407
461 hr = StrAllocFormatted(&sczCommandObfuscated, L"\"%ls\" %s", sczExecutablePath, sczArgumentsObfuscated); 408 hr = StrAllocFormatted(&sczCommandObfuscated, L"\"%ls\" %ls", sczExecutablePath, sczArgumentsObfuscated);
462 } 409 }
463 else 410 else
464 { 411 {
@@ -469,47 +416,15 @@ extern "C" HRESULT ExeEngineExecutePackage(
469 } 416 }
470 ExitOnFailure(hr, "Failed to create obfuscated executable command."); 417 ExitOnFailure(hr, "Failed to create obfuscated executable command.");
471 418
472 if (pPackage->Exe.fSupportsAncestors)
473 {
474 // Add the list of dependencies to ignore, if any, to the burn command line.
475 if (pExecuteAction->exePackage.sczIgnoreDependencies && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol)
476 {
477 hr = StrAllocFormattedSecure(&sczCommand, L"%ls -%ls=%ls", sczCommand, BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pExecuteAction->exePackage.sczIgnoreDependencies);
478 ExitOnFailure(hr, "Failed to append the list of dependencies to ignore to the command line.");
479
480 hr = StrAllocFormatted(&sczCommandObfuscated, L"%ls -%ls=%ls", sczCommandObfuscated, BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pExecuteAction->exePackage.sczIgnoreDependencies);
481 ExitOnFailure(hr, "Failed to append the list of dependencies to ignore to the obfuscated command line.");
482 }
483
484 // Add the list of ancestors, if any, to the burn command line.
485 if (pExecuteAction->exePackage.sczAncestors)
486 {
487 hr = StrAllocFormattedSecure(&sczCommand, L"%ls -%ls=%ls", sczCommand, BURN_COMMANDLINE_SWITCH_ANCESTORS, pExecuteAction->exePackage.sczAncestors);
488 ExitOnFailure(hr, "Failed to append the list of ancestors to the command line.");
489
490 hr = StrAllocFormatted(&sczCommandObfuscated, L"%ls -%ls=%ls", sczCommandObfuscated, BURN_COMMANDLINE_SWITCH_ANCESTORS, pExecuteAction->exePackage.sczAncestors);
491 ExitOnFailure(hr, "Failed to append the list of ancestors to the obfuscated command line.");
492 }
493 }
494
495 if (BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol)
496 {
497 hr = CoreAppendEngineWorkingDirectoryToCommandLine(pExecuteAction->exePackage.sczEngineWorkingDirectory, &sczCommand, &sczCommandObfuscated);
498 ExitOnFailure(hr, "Failed to append the custom working directory to the exepackage command line.");
499
500 hr = CoreAppendFileHandleSelfToCommandLine(sczExecutablePath, &hExecutableFile, &sczCommand, &sczCommandObfuscated);
501 ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF);
502 }
503
504 // Log before we add the secret pipe name and client token for embedded processes. 419 // Log before we add the secret pipe name and client token for embedded processes.
505 LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->exePackage.action), sczExecutablePath, sczCommandObfuscated); 420 LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->exePackage.action), sczExecutablePath, sczCommandObfuscated);
506 421
507 if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol) 422 if (!pPackage->Exe.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol)
508 { 423 {
509 hr = EmbeddedRunBundle(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode); 424 hr = EmbeddedRunBundle(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode);
510 ExitOnFailure(hr, "Failed to run bundle as embedded from path: %ls", sczExecutablePath); 425 ExitOnFailure(hr, "Failed to run exe with Burn protocol from path: %ls", sczExecutablePath);
511 } 426 }
512 else if (!pExecuteAction->exePackage.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_NETFX4 == pPackage->Exe.protocol) 427 else if (!pPackage->Exe.fFireAndForget && BURN_EXE_PROTOCOL_TYPE_NETFX4 == pPackage->Exe.protocol)
513 { 428 {
514 hr = NetFxRunChainer(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode); 429 hr = NetFxRunChainer(sczExecutablePath, sczCommand, pfnGenericMessageHandler, pvContext, &dwExitCode);
515 ExitOnFailure(hr, "Failed to run netfx chainer: %ls", sczExecutablePath); 430 ExitOnFailure(hr, "Failed to run netfx chainer: %ls", sczExecutablePath);
@@ -524,7 +439,7 @@ extern "C" HRESULT ExeEngineExecutePackage(
524 ExitWithLastError(hr, "Failed to CreateProcess on path: %ls", sczExecutablePath); 439 ExitWithLastError(hr, "Failed to CreateProcess on path: %ls", sczExecutablePath);
525 } 440 }
526 441
527 if (pExecuteAction->exePackage.fFireAndForget) 442 if (pPackage->Exe.fFireAndForget)
528 { 443 {
529 ::WaitForInputIdle(pi.hProcess, 5000); 444 ::WaitForInputIdle(pi.hProcess, 5000);
530 ExitFunction(); 445 ExitFunction();
@@ -547,7 +462,7 @@ extern "C" HRESULT ExeEngineExecutePackage(
547 } while (HRESULT_FROM_WIN32(WAIT_TIMEOUT) == hr); 462 } while (HRESULT_FROM_WIN32(WAIT_TIMEOUT) == hr);
548 } 463 }
549 464
550 hr = HandleExitCode(pPackage, dwExitCode, pRestart); 465 hr = ExeEngineHandleExitCode(pPackage->Exe.rgExitCodes, pPackage->Exe.cExitCodes, dwExitCode, pRestart);
551 ExitOnRootFailure(hr, "Process returned error: 0x%x", dwExitCode); 466 ExitOnRootFailure(hr, "Process returned error: 0x%x", dwExitCode);
552 467
553LExit: 468LExit:
@@ -595,12 +510,10 @@ LExit:
595 return; 510 return;
596} 511}
597 512
598 513extern "C" HRESULT ExeEngineParseExitCodesFromXml(
599// internal helper functions 514 __in IXMLDOMNode* pixnPackage,
600 515 __inout BURN_EXE_EXIT_CODE** prgExitCodes,
601static HRESULT ParseExitCodesFromXml( 516 __inout DWORD* pcExitCodes
602 __in IXMLDOMNode* pixnExePackage,
603 __in BURN_PACKAGE* pPackage
604 ) 517 )
605{ 518{
606 HRESULT hr = S_OK; 519 HRESULT hr = S_OK;
@@ -610,7 +523,7 @@ static HRESULT ParseExitCodesFromXml(
610 LPWSTR scz = NULL; 523 LPWSTR scz = NULL;
611 524
612 // select exit code nodes 525 // select exit code nodes
613 hr = XmlSelectNodes(pixnExePackage, L"ExitCode", &pixnNodes); 526 hr = XmlSelectNodes(pixnPackage, L"ExitCode", &pixnNodes);
614 ExitOnFailure(hr, "Failed to select exit code nodes."); 527 ExitOnFailure(hr, "Failed to select exit code nodes.");
615 528
616 // get exit code node count 529 // get exit code node count
@@ -620,15 +533,15 @@ static HRESULT ParseExitCodesFromXml(
620 if (cNodes) 533 if (cNodes)
621 { 534 {
622 // allocate memory for exit codes 535 // allocate memory for exit codes
623 pPackage->Exe.rgExitCodes = (BURN_EXE_EXIT_CODE*) MemAlloc(sizeof(BURN_EXE_EXIT_CODE) * cNodes, TRUE); 536 *prgExitCodes = (BURN_EXE_EXIT_CODE*) MemAlloc(sizeof(BURN_EXE_EXIT_CODE) * cNodes, TRUE);
624 ExitOnNull(pPackage->Exe.rgExitCodes, hr, E_OUTOFMEMORY, "Failed to allocate memory for exit code structs."); 537 ExitOnNull(*prgExitCodes, hr, E_OUTOFMEMORY, "Failed to allocate memory for exit code structs.");
625 538
626 pPackage->Exe.cExitCodes = cNodes; 539 *pcExitCodes = cNodes;
627 540
628 // parse package elements 541 // parse package elements
629 for (DWORD i = 0; i < cNodes; ++i) 542 for (DWORD i = 0; i < cNodes; ++i)
630 { 543 {
631 BURN_EXE_EXIT_CODE* pExitCode = &pPackage->Exe.rgExitCodes[i]; 544 BURN_EXE_EXIT_CODE* pExitCode = *prgExitCodes + i;
632 545
633 hr = XmlNextElement(pixnNodes, &pixnNode, NULL); 546 hr = XmlNextElement(pixnNodes, &pixnNode, NULL);
634 ExitOnFailure(hr, "Failed to get next node."); 547 ExitOnFailure(hr, "Failed to get next node.");
@@ -666,9 +579,10 @@ LExit:
666 return hr; 579 return hr;
667} 580}
668 581
669static HRESULT ParseCommandLineArgumentsFromXml( 582extern "C" HRESULT ExeEngineParseCommandLineArgumentsFromXml(
670 __in IXMLDOMNode* pixnExePackage, 583 __in IXMLDOMNode* pixnPackage,
671 __in BURN_PACKAGE* pPackage 584 __inout BURN_EXE_COMMAND_LINE_ARGUMENT** prgCommandLineArguments,
585 __inout DWORD* pcCommandLineArguments
672 ) 586 )
673{ 587{
674 HRESULT hr = S_OK; 588 HRESULT hr = S_OK;
@@ -678,7 +592,7 @@ static HRESULT ParseCommandLineArgumentsFromXml(
678 LPWSTR scz = NULL; 592 LPWSTR scz = NULL;
679 593
680 // Select command-line argument nodes. 594 // Select command-line argument nodes.
681 hr = XmlSelectNodes(pixnExePackage, L"CommandLine", &pixnNodes); 595 hr = XmlSelectNodes(pixnPackage, L"CommandLine", &pixnNodes);
682 ExitOnFailure(hr, "Failed to select command-line argument nodes."); 596 ExitOnFailure(hr, "Failed to select command-line argument nodes.");
683 597
684 // Get command-line argument node count. 598 // Get command-line argument node count.
@@ -687,15 +601,15 @@ static HRESULT ParseCommandLineArgumentsFromXml(
687 601
688 if (cNodes) 602 if (cNodes)
689 { 603 {
690 pPackage->Exe.rgCommandLineArguments = (BURN_EXE_COMMAND_LINE_ARGUMENT*) MemAlloc(sizeof(BURN_EXE_COMMAND_LINE_ARGUMENT) * cNodes, TRUE); 604 *prgCommandLineArguments = (BURN_EXE_COMMAND_LINE_ARGUMENT*) MemAlloc(sizeof(BURN_EXE_COMMAND_LINE_ARGUMENT) * cNodes, TRUE);
691 ExitOnNull(pPackage->Exe.rgCommandLineArguments, hr, E_OUTOFMEMORY, "Failed to allocate memory for command-line argument structs."); 605 ExitOnNull(*prgCommandLineArguments, hr, E_OUTOFMEMORY, "Failed to allocate memory for command-line argument structs.");
692 606
693 pPackage->Exe.cCommandLineArguments = cNodes; 607 *pcCommandLineArguments = cNodes;
694 608
695 // Parse command-line argument elements. 609 // Parse command-line argument elements.
696 for (DWORD i = 0; i < cNodes; ++i) 610 for (DWORD i = 0; i < cNodes; ++i)
697 { 611 {
698 BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument = &pPackage->Exe.rgCommandLineArguments[i]; 612 BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument = *prgCommandLineArguments + i;
699 613
700 hr = XmlNextElement(pixnNodes, &pixnNode, NULL); 614 hr = XmlNextElement(pixnNodes, &pixnNode, NULL);
701 ExitOnFailure(hr, "Failed to get next command-line argument node."); 615 ExitOnFailure(hr, "Failed to get next command-line argument node.");
@@ -731,8 +645,9 @@ LExit:
731 return hr; 645 return hr;
732} 646}
733 647
734static HRESULT HandleExitCode( 648extern "C" HRESULT ExeEngineHandleExitCode(
735 __in BURN_PACKAGE* pPackage, 649 __in BURN_EXE_EXIT_CODE* rgCustomExitCodes,
650 __in DWORD cCustomExitCodes,
736 __in DWORD dwExitCode, 651 __in DWORD dwExitCode,
737 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 652 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
738 ) 653 )
@@ -740,9 +655,9 @@ static HRESULT HandleExitCode(
740 HRESULT hr = S_OK; 655 HRESULT hr = S_OK;
741 BURN_EXE_EXIT_CODE_TYPE typeCode = BURN_EXE_EXIT_CODE_TYPE_NONE; 656 BURN_EXE_EXIT_CODE_TYPE typeCode = BURN_EXE_EXIT_CODE_TYPE_NONE;
742 657
743 for (DWORD i = 0; i < pPackage->Exe.cExitCodes; ++i) 658 for (DWORD i = 0; i < cCustomExitCodes; ++i)
744 { 659 {
745 BURN_EXE_EXIT_CODE* pExitCode = &pPackage->Exe.rgExitCodes[i]; 660 BURN_EXE_EXIT_CODE* pExitCode = rgCustomExitCodes + i;
746 661
747 // If this is a wildcard, use the last one we come across. 662 // If this is a wildcard, use the last one we come across.
748 if (pExitCode->fWildcard) 663 if (pExitCode->fWildcard)