aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine/variable.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-08-01 17:07:25 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-08-02 09:15:14 -0500
commitaacd6b677332f2e262d0df67603c246cd65d833e (patch)
tree05d4e5a127fc2b5feec6f74144bd195f337a8281 /src/burn/engine/variable.cpp
parent457ef57f96c1706a63e8f848be3e07a58e7de6a3 (diff)
downloadwix-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.cpp140
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
17typedef 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 );
80static HRESULT AddWellKnownVariable(
81 __in BURN_VARIABLES* pVariables,
82 __in LPCWSTR wzVariable,
83 __in BOOL fPersisted
84 );
74static HRESULT GetVariable( 85static 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 );
95static HRESULT InsertUserVariable(
96 __in BURN_VARIABLES* pVariables,
97 __in_z LPCWSTR wzVariable,
98 __in DWORD iPosition
99 );
84static HRESULT InsertVariable( 100static 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
294LExit: 329LExit:
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
1462static 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
1495LExit:
1496 return hr;
1497}
1498
1424static HRESULT GetVariable( 1499static 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
1575static 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
1590LExit:
1591 return hr;
1592}
1593
1500static HRESULT InsertVariable( 1594static HRESULT InsertVariable(
1501 __in BURN_VARIABLES* pVariables, 1595 __in BURN_VARIABLES* pVariables,
1502 __in_z LPCWSTR wzVariable, 1596 __in_z LPCWSTR wzVariable,