diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-08-01 17:07:25 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-08-02 09:15:14 -0500 |
commit | aacd6b677332f2e262d0df67603c246cd65d833e (patch) | |
tree | 05d4e5a127fc2b5feec6f74144bd195f337a8281 /src/burn/engine/variable.cpp | |
parent | 457ef57f96c1706a63e8f848be3e07a58e7de6a3 (diff) | |
download | wix-aacd6b677332f2e262d0df67603c246cd65d833e.tar.gz wix-aacd6b677332f2e262d0df67603c246cd65d833e.tar.bz2 wix-aacd6b677332f2e262d0df67603c246cd65d833e.zip |
Store list of persisted well-known variables in Burn.
This allows it to reject Variables declared in the manifest that start with the reserved prefix 'Wix'.
Diffstat (limited to 'src/burn/engine/variable.cpp')
-rw-r--r-- | src/burn/engine/variable.cpp | 140 |
1 files changed, 117 insertions, 23 deletions
diff --git a/src/burn/engine/variable.cpp b/src/burn/engine/variable.cpp index 8d208a66..81fa31b7 100644 --- a/src/burn/engine/variable.cpp +++ b/src/burn/engine/variable.cpp | |||
@@ -14,6 +14,12 @@ typedef const struct _BUILT_IN_VARIABLE_DECLARATION | |||
14 | BOOL fOverridable; | 14 | BOOL fOverridable; |
15 | } BUILT_IN_VARIABLE_DECLARATION; | 15 | } BUILT_IN_VARIABLE_DECLARATION; |
16 | 16 | ||
17 | typedef const struct _WELL_KNOWN_VARIABLE_DECLARATION | ||
18 | { | ||
19 | LPCWSTR wzVariable; | ||
20 | BOOL fPersist; | ||
21 | } WELL_KNOWN_VARIABLE_DECLARATION; | ||
22 | |||
17 | 23 | ||
18 | // constants | 24 | // constants |
19 | 25 | ||
@@ -71,6 +77,11 @@ static HRESULT AddBuiltInVariable( | |||
71 | __in BOOL fPersist, | 77 | __in BOOL fPersist, |
72 | __in BOOL fOverridable | 78 | __in BOOL fOverridable |
73 | ); | 79 | ); |
80 | static HRESULT AddWellKnownVariable( | ||
81 | __in BURN_VARIABLES* pVariables, | ||
82 | __in LPCWSTR wzVariable, | ||
83 | __in BOOL fPersisted | ||
84 | ); | ||
74 | static HRESULT GetVariable( | 85 | static HRESULT GetVariable( |
75 | __in BURN_VARIABLES* pVariables, | 86 | __in BURN_VARIABLES* pVariables, |
76 | __in_z LPCWSTR wzVariable, | 87 | __in_z LPCWSTR wzVariable, |
@@ -81,6 +92,11 @@ static HRESULT FindVariableIndexByName( | |||
81 | __in_z LPCWSTR wzVariable, | 92 | __in_z LPCWSTR wzVariable, |
82 | __out DWORD* piVariable | 93 | __out DWORD* piVariable |
83 | ); | 94 | ); |
95 | static HRESULT InsertUserVariable( | ||
96 | __in BURN_VARIABLES* pVariables, | ||
97 | __in_z LPCWSTR wzVariable, | ||
98 | __in DWORD iPosition | ||
99 | ); | ||
84 | static HRESULT InsertVariable( | 100 | static HRESULT InsertVariable( |
85 | __in BURN_VARIABLES* pVariables, | 101 | __in BURN_VARIABLES* pVariables, |
86 | __in_z LPCWSTR wzVariable, | 102 | __in_z LPCWSTR wzVariable, |
@@ -248,7 +264,7 @@ extern "C" HRESULT VariableInitialize( | |||
248 | #endif | 264 | #endif |
249 | {L"ProgramFiles6432Folder", InitializeVariable6432Folder, CSIDL_PROGRAM_FILES}, | 265 | {L"ProgramFiles6432Folder", InitializeVariable6432Folder, CSIDL_PROGRAM_FILES}, |
250 | {L"ProgramMenuFolder", InitializeVariableCsidlFolder, CSIDL_PROGRAMS}, | 266 | {L"ProgramMenuFolder", InitializeVariableCsidlFolder, CSIDL_PROGRAMS}, |
251 | {L"RebootPending", InitializeVariableNumeric, 0}, | 267 | {VARIABLE_REBOOTPENDING, InitializeVariableNumeric, 0}, |
252 | {L"SendToFolder", InitializeVariableCsidlFolder, CSIDL_SENDTO}, | 268 | {L"SendToFolder", InitializeVariableCsidlFolder, CSIDL_SENDTO}, |
253 | {L"ServicePackLevel", InitializeVariableVersionNT, OS_INFO_VARIABLE_ServicePackLevel}, | 269 | {L"ServicePackLevel", InitializeVariableVersionNT, OS_INFO_VARIABLE_ServicePackLevel}, |
254 | {L"StartMenuFolder", InitializeVariableCsidlFolder, CSIDL_STARTMENU}, | 270 | {L"StartMenuFolder", InitializeVariableCsidlFolder, CSIDL_STARTMENU}, |
@@ -283,6 +299,17 @@ extern "C" HRESULT VariableInitialize( | |||
283 | {BURN_BUNDLE_VERSION, InitializeVariableVersion, (DWORD_PTR)L"0", FALSE, TRUE}, | 299 | {BURN_BUNDLE_VERSION, InitializeVariableVersion, (DWORD_PTR)L"0", FALSE, TRUE}, |
284 | }; | 300 | }; |
285 | 301 | ||
302 | const WELL_KNOWN_VARIABLE_DECLARATION vrgWellKnownVariableNames[] = | ||
303 | { | ||
304 | { BURN_BUNDLE_LAYOUT_DIRECTORY }, | ||
305 | { BURN_BUNDLE_NAME, TRUE }, | ||
306 | { BURN_BUNDLE_INPROGRESS_NAME, TRUE }, | ||
307 | { BURN_BUNDLE_LAST_USED_SOURCE, TRUE }, | ||
308 | { BURN_BUNDLE_MANUFACTURER, TRUE }, | ||
309 | { BURN_BUNDLE_ORIGINAL_SOURCE, TRUE }, | ||
310 | { BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, TRUE }, | ||
311 | }; | ||
312 | |||
286 | for (DWORD i = 0; i < countof(vrgBuiltInVariables); ++i) | 313 | for (DWORD i = 0; i < countof(vrgBuiltInVariables); ++i) |
287 | { | 314 | { |
288 | BUILT_IN_VARIABLE_DECLARATION* pBuiltInVariable = &vrgBuiltInVariables[i]; | 315 | BUILT_IN_VARIABLE_DECLARATION* pBuiltInVariable = &vrgBuiltInVariables[i]; |
@@ -291,6 +318,14 @@ extern "C" HRESULT VariableInitialize( | |||
291 | ExitOnFailure(hr, "Failed to add built-in variable: %ls.", pBuiltInVariable->wzVariable); | 318 | ExitOnFailure(hr, "Failed to add built-in variable: %ls.", pBuiltInVariable->wzVariable); |
292 | } | 319 | } |
293 | 320 | ||
321 | for (DWORD i = 0; i < countof(vrgWellKnownVariableNames); ++i) | ||
322 | { | ||
323 | WELL_KNOWN_VARIABLE_DECLARATION* pWellKnownVariable = &vrgWellKnownVariableNames[i]; | ||
324 | |||
325 | hr = AddWellKnownVariable(pVariables, pWellKnownVariable->wzVariable, pWellKnownVariable->fPersist); | ||
326 | ExitOnFailure(hr, "Failed to add well-known variable: %ls.", pWellKnownVariable->wzVariable); | ||
327 | } | ||
328 | |||
294 | LExit: | 329 | LExit: |
295 | return hr; | 330 | return hr; |
296 | } | 331 | } |
@@ -301,6 +336,7 @@ extern "C" HRESULT VariablesParseFromXml( | |||
301 | ) | 336 | ) |
302 | { | 337 | { |
303 | HRESULT hr = S_OK; | 338 | HRESULT hr = S_OK; |
339 | BOOL fXmlFound = FALSE; | ||
304 | IXMLDOMNode* pixnCommandLine = NULL; | 340 | IXMLDOMNode* pixnCommandLine = NULL; |
305 | IXMLDOMNodeList* pixnNodes = NULL; | 341 | IXMLDOMNodeList* pixnNodes = NULL; |
306 | IXMLDOMNode* pixnNode = NULL; | 342 | IXMLDOMNode* pixnNode = NULL; |
@@ -315,17 +351,13 @@ extern "C" HRESULT VariablesParseFromXml( | |||
315 | 351 | ||
316 | ::EnterCriticalSection(&pVariables->csAccess); | 352 | ::EnterCriticalSection(&pVariables->csAccess); |
317 | 353 | ||
318 | // select registration node | 354 | // select command-line node |
319 | hr = XmlSelectSingleNode(pixnBundle, L"CommandLine", &pixnCommandLine); | 355 | hr = XmlSelectSingleNode(pixnBundle, L"CommandLine", &pixnCommandLine); |
320 | if (S_FALSE == hr) | 356 | ExitOnRequiredXmlQueryFailure(hr, "Failed to select CommandLine node."); |
321 | { | ||
322 | hr = E_NOTFOUND; | ||
323 | } | ||
324 | ExitOnFailure(hr, "Failed to select CommandLine node."); | ||
325 | 357 | ||
326 | // @Variables | 358 | // @Variables |
327 | hr = XmlGetAttributeEx(pixnCommandLine, L"Variables", &scz); | 359 | hr = XmlGetAttributeEx(pixnCommandLine, L"Variables", &scz); |
328 | ExitOnFailure(hr, "Failed to get CommandLine/@Variables."); | 360 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get CommandLine/@Variables."); |
329 | 361 | ||
330 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"upperCase", -1)) | 362 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"upperCase", -1)) |
331 | { | 363 | { |
@@ -337,8 +369,7 @@ extern "C" HRESULT VariablesParseFromXml( | |||
337 | } | 369 | } |
338 | else | 370 | else |
339 | { | 371 | { |
340 | hr = E_INVALIDARG; | 372 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for CommandLine/@Variables: %ls", scz); |
341 | ExitOnFailure(hr, "Invalid value for CommandLine/@Variables: %ls", scz); | ||
342 | } | 373 | } |
343 | 374 | ||
344 | // select variable nodes | 375 | // select variable nodes |
@@ -357,28 +388,28 @@ extern "C" HRESULT VariablesParseFromXml( | |||
357 | 388 | ||
358 | // @Id | 389 | // @Id |
359 | hr = XmlGetAttributeEx(pixnNode, L"Id", &sczId); | 390 | hr = XmlGetAttributeEx(pixnNode, L"Id", &sczId); |
360 | ExitOnFailure(hr, "Failed to get @Id."); | 391 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Id."); |
361 | 392 | ||
362 | // @Hidden | 393 | // @Hidden |
363 | hr = XmlGetYesNoAttribute(pixnNode, L"Hidden", &fHidden); | 394 | hr = XmlGetYesNoAttribute(pixnNode, L"Hidden", &fHidden); |
364 | ExitOnFailure(hr, "Failed to get @Hidden."); | 395 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Hidden."); |
365 | 396 | ||
366 | // @Persisted | 397 | // @Persisted |
367 | hr = XmlGetYesNoAttribute(pixnNode, L"Persisted", &fPersisted); | 398 | hr = XmlGetYesNoAttribute(pixnNode, L"Persisted", &fPersisted); |
368 | ExitOnFailure(hr, "Failed to get @Persisted."); | 399 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Persisted."); |
369 | 400 | ||
370 | // @Value | 401 | // @Value |
371 | hr = XmlGetAttributeEx(pixnNode, L"Value", &scz); | 402 | hr = XmlGetAttributeEx(pixnNode, L"Value", &scz); |
372 | if (E_NOTFOUND != hr) | 403 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get @Value."); |
373 | { | ||
374 | ExitOnFailure(hr, "Failed to get @Value."); | ||
375 | 404 | ||
405 | if (fXmlFound) | ||
406 | { | ||
376 | hr = BVariantSetString(&value, scz, 0, FALSE); | 407 | hr = BVariantSetString(&value, scz, 0, FALSE); |
377 | ExitOnFailure(hr, "Failed to set variant value."); | 408 | ExitOnFailure(hr, "Failed to set variant value."); |
378 | 409 | ||
379 | // @Type | 410 | // @Type |
380 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); | 411 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); |
381 | ExitOnFailure(hr, "Failed to get @Type."); | 412 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); |
382 | 413 | ||
383 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"formatted", -1)) | 414 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"formatted", -1)) |
384 | { | 415 | { |
@@ -414,8 +445,7 @@ extern "C" HRESULT VariablesParseFromXml( | |||
414 | } | 445 | } |
415 | else | 446 | else |
416 | { | 447 | { |
417 | hr = E_INVALIDARG; | 448 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); |
418 | ExitOnFailure(hr, "Invalid value for @Type: %ls", scz); | ||
419 | } | 449 | } |
420 | } | 450 | } |
421 | else | 451 | else |
@@ -444,14 +474,18 @@ extern "C" HRESULT VariablesParseFromXml( | |||
444 | // insert element if not found | 474 | // insert element if not found |
445 | if (S_FALSE == hr) | 475 | if (S_FALSE == hr) |
446 | { | 476 | { |
447 | hr = InsertVariable(pVariables, sczId, iVariable); | 477 | hr = InsertUserVariable(pVariables, sczId, iVariable); |
448 | ExitOnFailure(hr, "Failed to insert variable '%ls'.", sczId); | 478 | ExitOnFailure(hr, "Failed to insert variable '%ls'.", sczId); |
449 | } | 479 | } |
450 | else if (BURN_VARIABLE_INTERNAL_TYPE_NORMAL < pVariables->rgVariables[iVariable].internalType) | 480 | else if (BURN_VARIABLE_INTERNAL_TYPE_NORMAL < pVariables->rgVariables[iVariable].internalType) |
451 | { | 481 | { |
452 | hr = E_INVALIDARG; | 482 | ExitWithRootFailure(hr, E_INVALIDARG, "Attempt to add built-in variable: %ls", sczId); |
453 | ExitOnRootFailure(hr, "Attempt to set built-in variable value: %ls", sczId); | ||
454 | } | 483 | } |
484 | else | ||
485 | { | ||
486 | ExitWithRootFailure(hr, E_INVALIDARG, "Attempt to add variable again: %ls", sczId); | ||
487 | } | ||
488 | |||
455 | pVariables->rgVariables[iVariable].fHidden = fHidden; | 489 | pVariables->rgVariables[iVariable].fHidden = fHidden; |
456 | pVariables->rgVariables[iVariable].fPersisted = fPersisted; | 490 | pVariables->rgVariables[iVariable].fPersisted = fPersisted; |
457 | 491 | ||
@@ -1409,8 +1443,12 @@ static HRESULT AddBuiltInVariable( | |||
1409 | hr = InsertVariable(pVariables, wzVariable, iVariable); | 1443 | hr = InsertVariable(pVariables, wzVariable, iVariable); |
1410 | ExitOnFailure(hr, "Failed to insert variable."); | 1444 | ExitOnFailure(hr, "Failed to insert variable."); |
1411 | } | 1445 | } |
1446 | else | ||
1447 | { | ||
1448 | ExitWithRootFailure(hr, E_INVALIDSTATE, "Attempted to add built-in variable again: %ls", wzVariable); | ||
1449 | } | ||
1412 | 1450 | ||
1413 | // set variable values | 1451 | // set variable details |
1414 | pVariable = &pVariables->rgVariables[iVariable]; | 1452 | pVariable = &pVariables->rgVariables[iVariable]; |
1415 | pVariable->fPersisted = fPersist; | 1453 | pVariable->fPersisted = fPersist; |
1416 | pVariable->internalType = fOverridable ? BURN_VARIABLE_INTERNAL_TYPE_OVERRIDABLE_BUILTIN : BURN_VARIABLE_INTERNAL_TYPE_BUILTIN; | 1454 | pVariable->internalType = fOverridable ? BURN_VARIABLE_INTERNAL_TYPE_OVERRIDABLE_BUILTIN : BURN_VARIABLE_INTERNAL_TYPE_BUILTIN; |
@@ -1421,6 +1459,43 @@ LExit: | |||
1421 | return hr; | 1459 | return hr; |
1422 | } | 1460 | } |
1423 | 1461 | ||
1462 | static HRESULT AddWellKnownVariable( | ||
1463 | __in BURN_VARIABLES* pVariables, | ||
1464 | __in LPCWSTR wzVariable, | ||
1465 | __in BOOL fPersisted | ||
1466 | ) | ||
1467 | { | ||
1468 | HRESULT hr = S_OK; | ||
1469 | DWORD iVariable = 0; | ||
1470 | BURN_VARIABLE* pVariable = NULL; | ||
1471 | |||
1472 | hr = FindVariableIndexByName(pVariables, wzVariable, &iVariable); | ||
1473 | ExitOnFailure(hr, "Failed to find variable value."); | ||
1474 | |||
1475 | // insert element if not found | ||
1476 | if (S_FALSE == hr) | ||
1477 | { | ||
1478 | hr = InsertVariable(pVariables, wzVariable, iVariable); | ||
1479 | ExitOnFailure(hr, "Failed to insert variable."); | ||
1480 | } | ||
1481 | else if (BURN_VARIABLE_INTERNAL_TYPE_NORMAL != pVariables->rgVariables[iVariable].internalType) | ||
1482 | { | ||
1483 | ExitWithRootFailure(hr, E_INVALIDSTATE, "Attempted to add built-in variable as a well-known variable: %ls", wzVariable); | ||
1484 | } | ||
1485 | else | ||
1486 | { | ||
1487 | ExitWithRootFailure(hr, E_INVALIDSTATE, "Attempted to add well-known variable again: %ls", wzVariable); | ||
1488 | } | ||
1489 | |||
1490 | // set variable details | ||
1491 | pVariable = &pVariables->rgVariables[iVariable]; | ||
1492 | pVariable->fPersisted = fPersisted; | ||
1493 | pVariable->internalType = BURN_VARIABLE_INTERNAL_TYPE_NORMAL; | ||
1494 | |||
1495 | LExit: | ||
1496 | return hr; | ||
1497 | } | ||
1498 | |||
1424 | static HRESULT GetVariable( | 1499 | static HRESULT GetVariable( |
1425 | __in BURN_VARIABLES* pVariables, | 1500 | __in BURN_VARIABLES* pVariables, |
1426 | __in_z LPCWSTR wzVariable, | 1501 | __in_z LPCWSTR wzVariable, |
@@ -1497,6 +1572,25 @@ LExit: | |||
1497 | return hr; | 1572 | return hr; |
1498 | } | 1573 | } |
1499 | 1574 | ||
1575 | static HRESULT InsertUserVariable( | ||
1576 | __in BURN_VARIABLES* pVariables, | ||
1577 | __in_z LPCWSTR wzVariable, | ||
1578 | __in DWORD iPosition | ||
1579 | ) | ||
1580 | { | ||
1581 | HRESULT hr = S_OK; | ||
1582 | |||
1583 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, wzVariable, 3, L"Wix", 3)) | ||
1584 | { | ||
1585 | ExitWithRootFailure(hr, E_INVALIDARG, "Attempted to insert variable with reserved prefix: %ls", wzVariable); | ||
1586 | } | ||
1587 | |||
1588 | hr = InsertVariable(pVariables, wzVariable, iPosition); | ||
1589 | |||
1590 | LExit: | ||
1591 | return hr; | ||
1592 | } | ||
1593 | |||
1500 | static HRESULT InsertVariable( | 1594 | static HRESULT InsertVariable( |
1501 | __in BURN_VARIABLES* pVariables, | 1595 | __in BURN_VARIABLES* pVariables, |
1502 | __in_z LPCWSTR wzVariable, | 1596 | __in_z LPCWSTR wzVariable, |