aboutsummaryrefslogtreecommitdiff
path: root/src/api/burn/balutil/balinfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/burn/balutil/balinfo.cpp')
-rw-r--r--src/api/burn/balutil/balinfo.cpp203
1 files changed, 203 insertions, 0 deletions
diff --git a/src/api/burn/balutil/balinfo.cpp b/src/api/burn/balutil/balinfo.cpp
index 3abb9286..5927ef72 100644
--- a/src/api/burn/balutil/balinfo.cpp
+++ b/src/api/burn/balutil/balinfo.cpp
@@ -11,7 +11,88 @@ static HRESULT ParseBalPackageInfoFromXml(
11 __in BAL_INFO_PACKAGES* pPackages, 11 __in BAL_INFO_PACKAGES* pPackages,
12 __in IXMLDOMDocument* pixdManifest 12 __in IXMLDOMDocument* pixdManifest
13 ); 13 );
14static HRESULT ParseOverridableVariablesFromXml(
15 __in BAL_INFO_OVERRIDABLE_VARIABLES* pOverridableVariables,
16 __in IXMLDOMDocument* pixdManifest
17 );
18
19
20DAPI_(HRESULT) BalInfoParseCommandLine(
21 __in BAL_INFO_COMMAND* pCommand,
22 __in LPCWSTR wzCommandLine
23 )
24{
25 HRESULT hr = S_OK;
26 int argc = 0;
27 LPWSTR* argv = NULL;
28 BOOL fUnknownArg = FALSE;
29
30 BalInfoUninitializeCommandLine(pCommand);
31
32 if (!wzCommandLine || !*wzCommandLine)
33 {
34 ExitFunction();
35 }
36
37 hr = AppParseCommandLine(wzCommandLine, &argc, &argv);
38 ExitOnFailure(hr, "Failed to parse command line.");
14 39
40 for (int i = 0; i < argc; ++i)
41 {
42 fUnknownArg = FALSE;
43
44 if (argv[i][0] == L'-' || argv[i][0] == L'/')
45 {
46 fUnknownArg = TRUE;
47 }
48 else
49 {
50 const wchar_t* pwc = wcschr(argv[i], L'=');
51 if (!pwc)
52 {
53 fUnknownArg = TRUE;
54 }
55 else
56 {
57 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pCommand->rgVariableNames), pCommand->cVariables, 1, sizeof(LPWSTR), 5);
58 ExitOnFailure(hr, "Failed to ensure size for variable names.");
59
60 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pCommand->rgVariableValues), pCommand->cVariables, 1, sizeof(LPWSTR), 5);
61 ExitOnFailure(hr, "Failed to ensure size for variable values.");
62
63 LPWSTR* psczVariableName = pCommand->rgVariableNames + pCommand->cVariables;
64 LPWSTR* psczVariableValue = pCommand->rgVariableValues + pCommand->cVariables;
65 pCommand->cVariables += 1;
66
67 hr = StrAllocString(psczVariableName, argv[i], pwc - argv[i]);
68 BalExitOnFailure(hr, "Failed to copy variable name.");
69
70 hr = StrAllocString(psczVariableValue, ++pwc, 0);
71 BalExitOnFailure(hr, "Failed to copy variable value.");
72 }
73 }
74
75 if (fUnknownArg)
76 {
77 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pCommand->rgUnknownArgs), pCommand->cUnknownArgs, 1, sizeof(LPWSTR), 5);
78 BalExitOnFailure(hr, "Failed to ensure size for unknown args.");
79
80 LPWSTR* psczArg = pCommand->rgUnknownArgs + pCommand->cUnknownArgs;
81 pCommand->cUnknownArgs += 1;
82
83 StrAllocString(psczArg, argv[i], 0);
84 BalExitOnFailure(hr, "Failed to copy unknown arg.");
85 }
86 }
87
88LExit:
89 if (argv)
90 {
91 AppFreeCommandLineArgs(argv);
92 }
93
94 return hr;
95}
15 96
16DAPI_(HRESULT) BalInfoParseFromXml( 97DAPI_(HRESULT) BalInfoParseFromXml(
17 __in BAL_INFO_BUNDLE* pBundle, 98 __in BAL_INFO_BUNDLE* pBundle,
@@ -45,6 +126,9 @@ DAPI_(HRESULT) BalInfoParseFromXml(
45 } 126 }
46 } 127 }
47 128
129 hr = ParseOverridableVariablesFromXml(&pBundle->overridableVariables, pixdManifest);
130 BalExitOnFailure(hr, "Failed to parse overridable variables from bootstrapper application data.");
131
48 hr = ParsePackagesFromXml(&pBundle->packages, pixdManifest); 132 hr = ParsePackagesFromXml(&pBundle->packages, pixdManifest);
49 BalExitOnFailure(hr, "Failed to parse package information from bootstrapper application data."); 133 BalExitOnFailure(hr, "Failed to parse package information from bootstrapper application data.");
50 134
@@ -163,12 +247,76 @@ DAPI_(void) BalInfoUninitialize(
163 247
164 ReleaseMem(pBundle->packages.rgPackages); 248 ReleaseMem(pBundle->packages.rgPackages);
165 249
250 for (DWORD i = 0; i < pBundle->overridableVariables.cVariables; ++i)
251 {
252 ReleaseStr(pBundle->overridableVariables.rgVariables[i].sczName);
253 }
254
255 ReleaseMem(pBundle->overridableVariables.rgVariables);
256 ReleaseDict(pBundle->overridableVariables.sdVariables);
257
166 ReleaseStr(pBundle->sczName); 258 ReleaseStr(pBundle->sczName);
167 ReleaseStr(pBundle->sczLogVariable); 259 ReleaseStr(pBundle->sczLogVariable);
168 memset(pBundle, 0, sizeof(BAL_INFO_BUNDLE)); 260 memset(pBundle, 0, sizeof(BAL_INFO_BUNDLE));
169} 261}
170 262
171 263
264DAPI_(void) BalInfoUninitializeCommandLine(
265 __in BAL_INFO_COMMAND* pCommand
266 )
267{
268 for (DWORD i = 0; i < pCommand->cUnknownArgs; ++i)
269 {
270 ReleaseNullStrSecure(pCommand->rgUnknownArgs[i]);
271 }
272
273 ReleaseMem(pCommand->rgUnknownArgs);
274
275 for (DWORD i = 0; i < pCommand->cVariables; ++i)
276 {
277 ReleaseNullStrSecure(pCommand->rgVariableNames[i]);
278 ReleaseNullStrSecure(pCommand->rgVariableValues[i]);
279 }
280
281 ReleaseMem(pCommand->rgVariableNames);
282 ReleaseMem(pCommand->rgVariableValues);
283
284 memset(pCommand, 0, sizeof(BAL_INFO_COMMAND));
285}
286
287
288DAPI_(HRESULT) BalSetOverridableVariablesFromEngine(
289 __in BAL_INFO_OVERRIDABLE_VARIABLES* pOverridableVariables,
290 __in BAL_INFO_COMMAND* pCommand,
291 __in IBootstrapperEngine* pEngine
292 )
293{
294 HRESULT hr = S_OK;
295 BAL_INFO_OVERRIDABLE_VARIABLE* pOverridableVariable = NULL;
296
297 for (DWORD i = 0; i < pCommand->cVariables; ++i)
298 {
299 LPCWSTR wzVariableName = pCommand->rgVariableNames[i];
300 LPCWSTR wzVariableValue = pCommand->rgVariableValues[i];
301
302 hr = DictGetValue(pOverridableVariables->sdVariables, wzVariableName, reinterpret_cast<void**>(&pOverridableVariable));
303 if (E_NOTFOUND == hr)
304 {
305 BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Ignoring attempt to set non-overridable variable: '%ls'.", wzVariableName);
306 hr = S_OK;
307 continue;
308 }
309 BalExitOnFailure(hr, "Failed to check the dictionary of overridable variables.");
310
311 hr = pEngine->SetVariableString(pOverridableVariable->sczName, wzVariableValue, FALSE);
312 BalExitOnFailure(hr, "Failed to set variable: '%ls'.", pOverridableVariable->sczName);
313 }
314
315LExit:
316 return hr;
317}
318
319
172static HRESULT ParsePackagesFromXml( 320static HRESULT ParsePackagesFromXml(
173 __in BAL_INFO_PACKAGES* pPackages, 321 __in BAL_INFO_PACKAGES* pPackages,
174 __in IXMLDOMDocument* pixdManifest 322 __in IXMLDOMDocument* pixdManifest
@@ -371,3 +519,58 @@ LExit:
371 519
372 return hr; 520 return hr;
373} 521}
522
523
524static HRESULT ParseOverridableVariablesFromXml(
525 __in BAL_INFO_OVERRIDABLE_VARIABLES* pOverridableVariables,
526 __in IXMLDOMDocument* pixdManifest
527 )
528{
529 HRESULT hr = S_OK;
530 IXMLDOMNode* pNode = NULL;
531 IXMLDOMNodeList* pNodes = NULL;
532 BAL_INFO_OVERRIDABLE_VARIABLE* pOverridableVariable = NULL;
533
534 // Get the list of variables users can override on the command line.
535 hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixStdbaOverridableVariable", &pNodes);
536 if (S_FALSE == hr)
537 {
538 ExitFunction1(hr = S_OK);
539 }
540 ExitOnFailure(hr, "Failed to select overridable variable nodes.");
541
542 hr = pNodes->get_length(reinterpret_cast<long*>(&pOverridableVariables->cVariables));
543 ExitOnFailure(hr, "Failed to get overridable variable node count.");
544
545 if (pOverridableVariables->cVariables)
546 {
547 hr = DictCreateWithEmbeddedKey(&pOverridableVariables->sdVariables, pOverridableVariables->cVariables, reinterpret_cast<void**>(&pOverridableVariables->rgVariables), offsetof(BAL_INFO_OVERRIDABLE_VARIABLE, sczName), DICT_FLAG_NONE);
548 ExitOnFailure(hr, "Failed to create the overridable variables string dictionary.");
549
550 hr = MemAllocArray(reinterpret_cast<LPVOID*>(&pOverridableVariables->rgVariables), sizeof(pOverridableVariable), pOverridableVariables->cVariables);
551 ExitOnFailure(hr, "Failed to create the overridable variables array.");
552
553 for (DWORD i = 0; i < pOverridableVariables->cVariables; ++i)
554 {
555 pOverridableVariable = pOverridableVariables->rgVariables + i;
556
557 hr = XmlNextElement(pNodes, &pNode, NULL);
558 ExitOnFailure(hr, "Failed to get next node.");
559
560 // @Name
561 hr = XmlGetAttributeEx(pNode, L"Name", &pOverridableVariable->sczName);
562 ExitOnFailure(hr, "Failed to get name for overridable variable.");
563
564 hr = DictAddValue(pOverridableVariables->sdVariables, pOverridableVariable);
565 ExitOnFailure(hr, "Failed to add \"%ls\" to the string dictionary.", pOverridableVariable->sczName);
566
567 // prepare next iteration
568 ReleaseNullObject(pNode);
569 }
570 }
571
572LExit:
573 ReleaseObject(pNode);
574 ReleaseObject(pNodes);
575 return hr;
576}