diff options
Diffstat (limited to 'src/burn/engine/exeengine.cpp')
-rw-r--r-- | src/burn/engine/exeengine.cpp | 177 |
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 | |||
8 | static HRESULT HandleExitCode( | ||
9 | __in BURN_PACKAGE* pPackage, | ||
10 | __in DWORD dwExitCode, | ||
11 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
12 | ); | ||
13 | static HRESULT ParseCommandLineArgumentsFromXml( | ||
14 | __in IXMLDOMNode* pixnExePackage, | ||
15 | __in BURN_PACKAGE* pPackage | ||
16 | ); | ||
17 | static HRESULT ParseExitCodesFromXml( | ||
18 | __in IXMLDOMNode* pixnExePackage, | ||
19 | __in BURN_PACKAGE* pPackage | ||
20 | ); | ||
21 | |||
22 | |||
23 | // function definitions | 6 | // function definitions |
24 | 7 | ||
25 | extern "C" HRESULT ExeEngineParsePackageFromXml( | 8 | extern "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 | ||
91 | LExit: | 74 | LExit: |
@@ -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 | ||
106 | extern "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 | |||
129 | extern "C" HRESULT ExeEngineDetectPackage( | 116 | extern "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 | // |
266 | extern "C" HRESULT ExeEnginePlanAddPackage( | 253 | extern "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 | ||
553 | LExit: | 468 | LExit: |
@@ -595,12 +510,10 @@ LExit: | |||
595 | return; | 510 | return; |
596 | } | 511 | } |
597 | 512 | ||
598 | 513 | extern "C" HRESULT ExeEngineParseExitCodesFromXml( | |
599 | // internal helper functions | 514 | __in IXMLDOMNode* pixnPackage, |
600 | 515 | __inout BURN_EXE_EXIT_CODE** prgExitCodes, | |
601 | static 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 | ||
669 | static HRESULT ParseCommandLineArgumentsFromXml( | 582 | extern "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 | ||
734 | static HRESULT HandleExitCode( | 648 | extern "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) |