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 | |
| 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')
| -rw-r--r-- | src/burn/engine/approvedexe.h | 9 | ||||
| -rw-r--r-- | src/burn/engine/core.h | 7 | ||||
| -rw-r--r-- | src/burn/engine/logging.cpp | 41 | ||||
| -rw-r--r-- | src/burn/engine/logging.h | 4 | ||||
| -rw-r--r-- | src/burn/engine/manifest.cpp | 22 | ||||
| -rw-r--r-- | src/burn/engine/package.cpp | 8 | ||||
| -rw-r--r-- | src/burn/engine/package.h | 1 | ||||
| -rw-r--r-- | src/burn/engine/platform.h | 10 | ||||
| -rw-r--r-- | src/burn/engine/registration.cpp | 2 | ||||
| -rw-r--r-- | src/burn/engine/variable.cpp | 140 | ||||
| -rw-r--r-- | src/burn/engine/variable.h | 1 |
11 files changed, 180 insertions, 65 deletions
diff --git a/src/burn/engine/approvedexe.h b/src/burn/engine/approvedexe.h index cbfda601..7a68c174 100644 --- a/src/burn/engine/approvedexe.h +++ b/src/burn/engine/approvedexe.h | |||
| @@ -6,15 +6,6 @@ | |||
| 6 | extern "C" { | 6 | extern "C" { |
| 7 | #endif | 7 | #endif |
| 8 | 8 | ||
| 9 | // forward declare | ||
| 10 | |||
| 11 | enum BURN_MODE; | ||
| 12 | typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT BOOTSTRAPPER_ENGINE_CONTEXT; | ||
| 13 | typedef struct _BURN_CACHE BURN_CACHE; | ||
| 14 | typedef struct _BURN_DEPENDENCIES BURN_DEPENDENCIES; | ||
| 15 | typedef struct _BURN_ENGINE_COMMAND BURN_ENGINE_COMMAND; | ||
| 16 | typedef struct _BURN_LOGGING BURN_LOGGING; | ||
| 17 | |||
| 18 | // structs | 9 | // structs |
| 19 | 10 | ||
| 20 | typedef struct _BURN_APPROVED_EXE | 11 | typedef struct _BURN_APPROVED_EXE |
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h index 31f63ed4..c75d42de 100644 --- a/src/burn/engine/core.h +++ b/src/burn/engine/core.h | |||
| @@ -38,7 +38,6 @@ const LPCWSTR BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN = L"burn.splash.screen"; | |||
| 38 | const LPCWSTR BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT = L"burn.system.component"; | 38 | const LPCWSTR BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT = L"burn.system.component"; |
| 39 | const LPCWSTR BURN_COMMANDLINE_SWITCH_PREFIX = L"burn."; | 39 | const LPCWSTR BURN_COMMANDLINE_SWITCH_PREFIX = L"burn."; |
| 40 | 40 | ||
| 41 | const LPCWSTR BURN_BUNDLE_LAYOUT_DIRECTORY = L"WixBundleLayoutDirectory"; | ||
| 42 | const LPCWSTR BURN_BUNDLE_ACTION = L"WixBundleAction"; | 41 | const LPCWSTR BURN_BUNDLE_ACTION = L"WixBundleAction"; |
| 43 | const LPCWSTR BURN_BUNDLE_ACTIVE_PARENT = L"WixBundleActiveParent"; | 42 | const LPCWSTR BURN_BUNDLE_ACTIVE_PARENT = L"WixBundleActiveParent"; |
| 44 | const LPCWSTR BURN_BUNDLE_COMMAND_LINE_ACTION = L"WixBundleCommandLineAction"; | 43 | const LPCWSTR BURN_BUNDLE_COMMAND_LINE_ACTION = L"WixBundleCommandLineAction"; |
| @@ -48,17 +47,17 @@ const LPCWSTR BURN_BUNDLE_FORCED_RESTART_PACKAGE = L"WixBundleForcedRestartPacka | |||
| 48 | const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled"; | 47 | const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled"; |
| 49 | const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated"; | 48 | const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated"; |
| 50 | const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey"; | 49 | const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey"; |
| 51 | const LPCWSTR BURN_BUNDLE_MANUFACTURER = L"WixBundleManufacturer"; | ||
| 52 | const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_PATH = L"WixBundleSourceProcessPath"; | 50 | const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_PATH = L"WixBundleSourceProcessPath"; |
| 53 | const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_FOLDER = L"WixBundleSourceProcessFolder"; | 51 | const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_FOLDER = L"WixBundleSourceProcessFolder"; |
| 54 | const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag"; | 52 | const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag"; |
| 55 | const LPCWSTR BURN_BUNDLE_UILEVEL = L"WixBundleUILevel"; | 53 | const LPCWSTR BURN_BUNDLE_UILEVEL = L"WixBundleUILevel"; |
| 56 | const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion"; | 54 | const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion"; |
| 57 | const LPCWSTR BURN_REBOOT_PENDING = L"RebootPending"; | ||
| 58 | 55 | ||
| 59 | // The following constants must stay in sync with src\api\wix\WixToolset.Data\Burn\BurnConstants.cs | 56 | // The following well-known variables are settable by the BA. |
| 57 | const LPCWSTR BURN_BUNDLE_LAYOUT_DIRECTORY = L"WixBundleLayoutDirectory"; | ||
| 60 | const LPCWSTR BURN_BUNDLE_NAME = L"WixBundleName"; | 58 | const LPCWSTR BURN_BUNDLE_NAME = L"WixBundleName"; |
| 61 | const LPCWSTR BURN_BUNDLE_INPROGRESS_NAME = L"WixBundleInProgressName"; | 59 | const LPCWSTR BURN_BUNDLE_INPROGRESS_NAME = L"WixBundleInProgressName"; |
| 60 | const LPCWSTR BURN_BUNDLE_MANUFACTURER = L"WixBundleManufacturer"; | ||
| 62 | const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE = L"WixBundleOriginalSource"; | 61 | const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE = L"WixBundleOriginalSource"; |
| 63 | const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = L"WixBundleOriginalSourceFolder"; | 62 | const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = L"WixBundleOriginalSourceFolder"; |
| 64 | const LPCWSTR BURN_BUNDLE_LAST_USED_SOURCE = L"WixBundleLastUsedSource"; | 63 | const LPCWSTR BURN_BUNDLE_LAST_USED_SOURCE = L"WixBundleLastUsedSource"; |
diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp index 68f0c35b..ae056921 100644 --- a/src/burn/engine/logging.cpp +++ b/src/burn/engine/logging.cpp | |||
| @@ -28,6 +28,37 @@ static HRESULT GetNonSessionSpecificTempFolder( | |||
| 28 | 28 | ||
| 29 | // function definitions | 29 | // function definitions |
| 30 | 30 | ||
| 31 | extern "C" HRESULT LoggingParseFromXml( | ||
| 32 | __in BURN_LOGGING* pLog, | ||
| 33 | __in IXMLDOMNode* pixnBundle | ||
| 34 | ) | ||
| 35 | { | ||
| 36 | HRESULT hr = S_OK; | ||
| 37 | IXMLDOMNode* pixnLog = NULL; | ||
| 38 | BOOL fXmlFound = FALSE; | ||
| 39 | |||
| 40 | // parse the log element, if present. | ||
| 41 | hr = XmlSelectSingleNode(pixnBundle, L"Log", &pixnLog); | ||
| 42 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get Log element."); | ||
| 43 | |||
| 44 | if (fXmlFound) | ||
| 45 | { | ||
| 46 | hr = XmlGetAttributeEx(pixnLog, L"PathVariable", &pLog->sczPathVariable); | ||
| 47 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get Log/@PathVariable."); | ||
| 48 | |||
| 49 | hr = XmlGetAttributeEx(pixnLog, L"Prefix", &pLog->sczPrefix); | ||
| 50 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get Log/@Prefix attribute."); | ||
| 51 | |||
| 52 | hr = XmlGetAttributeEx(pixnLog, L"Extension", &pLog->sczExtension); | ||
| 53 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get Log/@Extension attribute."); | ||
| 54 | } | ||
| 55 | |||
| 56 | LExit: | ||
| 57 | ReleaseObject(pixnLog); | ||
| 58 | |||
| 59 | return hr; | ||
| 60 | } | ||
| 61 | |||
| 31 | extern "C" HRESULT LoggingOpen( | 62 | extern "C" HRESULT LoggingOpen( |
| 32 | __in BURN_LOGGING* pLog, | 63 | __in BURN_LOGGING* pLog, |
| 33 | __in BURN_ENGINE_COMMAND* pInternalCommand, | 64 | __in BURN_ENGINE_COMMAND* pInternalCommand, |
| @@ -244,7 +275,6 @@ extern "C" HRESULT LoggingSetCompatiblePackageVariable( | |||
| 244 | ) | 275 | ) |
| 245 | { | 276 | { |
| 246 | HRESULT hr = S_OK; | 277 | HRESULT hr = S_OK; |
| 247 | LPWSTR sczLogPathVariable = NULL; | ||
| 248 | LPWSTR sczLogPath = NULL; | 278 | LPWSTR sczLogPath = NULL; |
| 249 | 279 | ||
| 250 | // Make sure that no package log files are created when logging has been disabled via Log element. | 280 | // Make sure that no package log files are created when logging has been disabled via Log element. |
| @@ -253,16 +283,12 @@ extern "C" HRESULT LoggingSetCompatiblePackageVariable( | |||
| 253 | ExitFunction(); | 283 | ExitFunction(); |
| 254 | } | 284 | } |
| 255 | 285 | ||
| 256 | if (pPackage->sczLogPathVariable && *pPackage->sczLogPathVariable) | 286 | if (pPackage->sczCompatibleLogPathVariable && *pPackage->sczCompatibleLogPathVariable) |
| 257 | { | 287 | { |
| 258 | // Format a suitable log path variable from the original package. | ||
| 259 | hr = StrAllocFormatted(&sczLogPathVariable, L"%ls_Compatible", pPackage->sczLogPathVariable); | ||
| 260 | ExitOnFailure(hr, "Failed to format log path variable for compatible package."); | ||
| 261 | |||
| 262 | hr = StrAllocFormatted(&sczLogPath, L"%ls_%03u_%ls_%ls.%ls", pLog->sczPrefix, vdwPackageSequence, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, pLog->sczExtension); | 288 | hr = StrAllocFormatted(&sczLogPath, L"%ls_%03u_%ls_%ls.%ls", pLog->sczPrefix, vdwPackageSequence, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, pLog->sczExtension); |
| 263 | ExitOnFailure(hr, "Failed to allocate path for package log."); | 289 | ExitOnFailure(hr, "Failed to allocate path for package log."); |
| 264 | 290 | ||
| 265 | hr = VariableSetString(pVariables, sczLogPathVariable, sczLogPath, FALSE, FALSE); | 291 | hr = VariableSetString(pVariables, pPackage->sczCompatibleLogPathVariable, sczLogPath, FALSE, FALSE); |
| 266 | ExitOnFailure(hr, "Failed to set log path into variable."); | 292 | ExitOnFailure(hr, "Failed to set log path into variable."); |
| 267 | 293 | ||
| 268 | if (psczLogPath) | 294 | if (psczLogPath) |
| @@ -273,7 +299,6 @@ extern "C" HRESULT LoggingSetCompatiblePackageVariable( | |||
| 273 | } | 299 | } |
| 274 | 300 | ||
| 275 | LExit: | 301 | LExit: |
| 276 | ReleaseStr(sczLogPathVariable); | ||
| 277 | ReleaseStr(sczLogPath); | 302 | ReleaseStr(sczLogPath); |
| 278 | 303 | ||
| 279 | return hr; | 304 | return hr; |
diff --git a/src/burn/engine/logging.h b/src/burn/engine/logging.h index 000b04f8..5597bb57 100644 --- a/src/burn/engine/logging.h +++ b/src/burn/engine/logging.h | |||
| @@ -41,6 +41,10 @@ typedef struct _BURN_LOGGING | |||
| 41 | 41 | ||
| 42 | // function declarations | 42 | // function declarations |
| 43 | 43 | ||
| 44 | HRESULT LoggingParseFromXml( | ||
| 45 | __in BURN_LOGGING* pLog, | ||
| 46 | __in IXMLDOMNode* pixnBundle | ||
| 47 | ); | ||
| 44 | HRESULT LoggingOpen( | 48 | HRESULT LoggingOpen( |
| 45 | __in BURN_LOGGING* pLog, | 49 | __in BURN_LOGGING* pLog, |
| 46 | __in BURN_ENGINE_COMMAND* pInternalCommand, | 50 | __in BURN_ENGINE_COMMAND* pInternalCommand, |
diff --git a/src/burn/engine/manifest.cpp b/src/burn/engine/manifest.cpp index 0cd10dbb..c0d67c19 100644 --- a/src/burn/engine/manifest.cpp +++ b/src/burn/engine/manifest.cpp | |||
| @@ -67,31 +67,14 @@ static HRESULT ParseFromXml( | |||
| 67 | { | 67 | { |
| 68 | HRESULT hr = S_OK; | 68 | HRESULT hr = S_OK; |
| 69 | IXMLDOMElement* pixeBundle = NULL; | 69 | IXMLDOMElement* pixeBundle = NULL; |
| 70 | IXMLDOMNode* pixnLog = NULL; | ||
| 71 | IXMLDOMNode* pixnChain = NULL; | 70 | IXMLDOMNode* pixnChain = NULL; |
| 72 | 71 | ||
| 73 | // get bundle element | 72 | // get bundle element |
| 74 | hr = pixdDocument->get_documentElement(&pixeBundle); | 73 | hr = pixdDocument->get_documentElement(&pixeBundle); |
| 75 | ExitOnFailure(hr, "Failed to get bundle element."); | 74 | ExitOnFailure(hr, "Failed to get bundle element."); |
| 76 | 75 | ||
| 77 | // parse the log element, if present. | 76 | hr = LoggingParseFromXml(&pEngineState->log, pixeBundle); |
| 78 | hr = XmlSelectSingleNode(pixeBundle, L"Log", &pixnLog); | 77 | ExitOnFailure(hr, "Failed to parse logging."); |
| 79 | ExitOnFailure(hr, "Failed to get Log element."); | ||
| 80 | |||
| 81 | if (S_OK == hr) | ||
| 82 | { | ||
| 83 | hr = XmlGetAttributeEx(pixnLog, L"PathVariable", &pEngineState->log.sczPathVariable); | ||
| 84 | if (E_NOTFOUND != hr) | ||
| 85 | { | ||
| 86 | ExitOnFailure(hr, "Failed to get Log/@PathVariable."); | ||
| 87 | } | ||
| 88 | |||
| 89 | hr = XmlGetAttributeEx(pixnLog, L"Prefix", &pEngineState->log.sczPrefix); | ||
| 90 | ExitOnFailure(hr, "Failed to get Log/@Prefix attribute."); | ||
| 91 | |||
| 92 | hr = XmlGetAttributeEx(pixnLog, L"Extension", &pEngineState->log.sczExtension); | ||
| 93 | ExitOnFailure(hr, "Failed to get Log/@Extension attribute."); | ||
| 94 | } | ||
| 95 | 78 | ||
| 96 | // get the chain element | 79 | // get the chain element |
| 97 | hr = XmlSelectSingleNode(pixeBundle, L"Chain", &pixnChain); | 80 | hr = XmlSelectSingleNode(pixeBundle, L"Chain", &pixnChain); |
| @@ -167,7 +150,6 @@ static HRESULT ParseFromXml( | |||
| 167 | 150 | ||
| 168 | LExit: | 151 | LExit: |
| 169 | ReleaseObject(pixnChain); | 152 | ReleaseObject(pixnChain); |
| 170 | ReleaseObject(pixnLog); | ||
| 171 | ReleaseObject(pixeBundle); | 153 | ReleaseObject(pixeBundle); |
| 172 | return hr; | 154 | return hr; |
| 173 | } | 155 | } |
diff --git a/src/burn/engine/package.cpp b/src/burn/engine/package.cpp index c56f74c8..fe8af497 100644 --- a/src/burn/engine/package.cpp +++ b/src/burn/engine/package.cpp | |||
| @@ -174,6 +174,13 @@ extern "C" HRESULT PackagesParseFromXml( | |||
| 174 | hr = XmlGetAttributeEx(pixnNode, L"RollbackLogPathVariable", &pPackage->sczRollbackLogPathVariable); | 174 | hr = XmlGetAttributeEx(pixnNode, L"RollbackLogPathVariable", &pPackage->sczRollbackLogPathVariable); |
| 175 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RollbackLogPathVariable."); | 175 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RollbackLogPathVariable."); |
| 176 | 176 | ||
| 177 | if (pPackage->sczLogPathVariable && *pPackage->sczLogPathVariable) | ||
| 178 | { | ||
| 179 | // Format a suitable log path variable from the original package. | ||
| 180 | hr = StrAllocFormatted(&pPackage->sczCompatibleLogPathVariable, L"%ls_Compatible", pPackage->sczLogPathVariable); | ||
| 181 | ExitOnFailure(hr, "Failed to format log path variable for compatible package."); | ||
| 182 | } | ||
| 183 | |||
| 177 | // @InstallCondition | 184 | // @InstallCondition |
| 178 | hr = XmlGetAttributeEx(pixnNode, L"InstallCondition", &pPackage->sczInstallCondition); | 185 | hr = XmlGetAttributeEx(pixnNode, L"InstallCondition", &pPackage->sczInstallCondition); |
| 179 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallCondition."); | 186 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallCondition."); |
| @@ -365,6 +372,7 @@ extern "C" void PackageUninitialize( | |||
| 365 | ReleaseStr(pPackage->sczId); | 372 | ReleaseStr(pPackage->sczId); |
| 366 | ReleaseStr(pPackage->sczLogPathVariable); | 373 | ReleaseStr(pPackage->sczLogPathVariable); |
| 367 | ReleaseStr(pPackage->sczRollbackLogPathVariable); | 374 | ReleaseStr(pPackage->sczRollbackLogPathVariable); |
| 375 | ReleaseStr(pPackage->sczCompatibleLogPathVariable); | ||
| 368 | ReleaseStr(pPackage->sczInstallCondition); | 376 | ReleaseStr(pPackage->sczInstallCondition); |
| 369 | ReleaseStr(pPackage->sczRepairCondition); | 377 | ReleaseStr(pPackage->sczRepairCondition); |
| 370 | ReleaseStr(pPackage->sczCacheId); | 378 | ReleaseStr(pPackage->sczCacheId); |
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index e8d49e53..e45c775d 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h | |||
| @@ -262,6 +262,7 @@ typedef struct _BURN_PACKAGE | |||
| 262 | 262 | ||
| 263 | LPWSTR sczLogPathVariable; // name of the variable that will be set to the log path. | 263 | LPWSTR sczLogPathVariable; // name of the variable that will be set to the log path. |
| 264 | LPWSTR sczRollbackLogPathVariable; // name of the variable that will be set to the rollback path. | 264 | LPWSTR sczRollbackLogPathVariable; // name of the variable that will be set to the rollback path. |
| 265 | LPWSTR sczCompatibleLogPathVariable; | ||
| 265 | 266 | ||
| 266 | LPWSTR sczInstallCondition; | 267 | LPWSTR sczInstallCondition; |
| 267 | LPWSTR sczRepairCondition; | 268 | LPWSTR sczRepairCondition; |
diff --git a/src/burn/engine/platform.h b/src/burn/engine/platform.h index 876b02c2..49d8f3e9 100644 --- a/src/burn/engine/platform.h +++ b/src/burn/engine/platform.h | |||
| @@ -8,6 +8,16 @@ | |||
| 8 | extern "C" { | 8 | extern "C" { |
| 9 | #endif | 9 | #endif |
| 10 | 10 | ||
| 11 | // forward declare | ||
| 12 | |||
| 13 | enum BURN_MODE; | ||
| 14 | typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT BOOTSTRAPPER_ENGINE_CONTEXT; | ||
| 15 | typedef struct _BURN_CACHE BURN_CACHE; | ||
| 16 | typedef struct _BURN_DEPENDENCIES BURN_DEPENDENCIES; | ||
| 17 | typedef struct _BURN_ENGINE_COMMAND BURN_ENGINE_COMMAND; | ||
| 18 | typedef struct _BURN_LOGGING BURN_LOGGING; | ||
| 19 | typedef struct _BURN_PACKAGES BURN_PACKAGES; | ||
| 20 | |||
| 11 | 21 | ||
| 12 | // typedefs | 22 | // typedefs |
| 13 | 23 | ||
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp index d0e5c677..484c08ac 100644 --- a/src/burn/engine/registration.cpp +++ b/src/burn/engine/registration.cpp | |||
| @@ -443,7 +443,7 @@ extern "C" HRESULT RegistrationSetDynamicVariables( | |||
| 443 | hr = VariableSetNumeric(pVariables, BURN_BUNDLE_INSTALLED, llInstalled, TRUE); | 443 | hr = VariableSetNumeric(pVariables, BURN_BUNDLE_INSTALLED, llInstalled, TRUE); |
| 444 | ExitOnFailure(hr, "Failed to set the bundle installed built-in variable."); | 444 | ExitOnFailure(hr, "Failed to set the bundle installed built-in variable."); |
| 445 | 445 | ||
| 446 | hr = VariableSetNumeric(pVariables, BURN_REBOOT_PENDING, IsWuRebootPending() || IsRegistryRebootPending(), TRUE); | 446 | hr = VariableSetNumeric(pVariables, VARIABLE_REBOOTPENDING, IsWuRebootPending() || IsRegistryRebootPending(), TRUE); |
| 447 | ExitOnFailure(hr, "Failed to overwrite the bundle reboot-pending built-in variable."); | 447 | ExitOnFailure(hr, "Failed to overwrite the bundle reboot-pending built-in variable."); |
| 448 | 448 | ||
| 449 | LExit: | 449 | LExit: |
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, |
diff --git a/src/burn/engine/variable.h b/src/burn/engine/variable.h index 9ed86ca7..f8d3e1e2 100644 --- a/src/burn/engine/variable.h +++ b/src/burn/engine/variable.h | |||
| @@ -13,6 +13,7 @@ const LPCWSTR VARIABLE_DATE = L"Date"; | |||
| 13 | const LPCWSTR VARIABLE_LOGONUSER = L"LogonUser"; | 13 | const LPCWSTR VARIABLE_LOGONUSER = L"LogonUser"; |
| 14 | const LPCWSTR VARIABLE_INSTALLERNAME = L"InstallerName"; | 14 | const LPCWSTR VARIABLE_INSTALLERNAME = L"InstallerName"; |
| 15 | const LPCWSTR VARIABLE_INSTALLERVERSION = L"InstallerVersion"; | 15 | const LPCWSTR VARIABLE_INSTALLERVERSION = L"InstallerVersion"; |
| 16 | const LPCWSTR VARIABLE_REBOOTPENDING = L"RebootPending"; | ||
| 16 | 17 | ||
| 17 | 18 | ||
| 18 | // typedefs | 19 | // typedefs |
