aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn/engine')
-rw-r--r--src/burn/engine/approvedexe.h9
-rw-r--r--src/burn/engine/core.h7
-rw-r--r--src/burn/engine/logging.cpp41
-rw-r--r--src/burn/engine/logging.h4
-rw-r--r--src/burn/engine/manifest.cpp22
-rw-r--r--src/burn/engine/package.cpp8
-rw-r--r--src/burn/engine/package.h1
-rw-r--r--src/burn/engine/platform.h10
-rw-r--r--src/burn/engine/registration.cpp2
-rw-r--r--src/burn/engine/variable.cpp140
-rw-r--r--src/burn/engine/variable.h1
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 @@
6extern "C" { 6extern "C" {
7#endif 7#endif
8 8
9// forward declare
10
11enum BURN_MODE;
12typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT BOOTSTRAPPER_ENGINE_CONTEXT;
13typedef struct _BURN_CACHE BURN_CACHE;
14typedef struct _BURN_DEPENDENCIES BURN_DEPENDENCIES;
15typedef struct _BURN_ENGINE_COMMAND BURN_ENGINE_COMMAND;
16typedef struct _BURN_LOGGING BURN_LOGGING;
17
18// structs 9// structs
19 10
20typedef struct _BURN_APPROVED_EXE 11typedef 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";
38const LPCWSTR BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT = L"burn.system.component"; 38const LPCWSTR BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT = L"burn.system.component";
39const LPCWSTR BURN_COMMANDLINE_SWITCH_PREFIX = L"burn."; 39const LPCWSTR BURN_COMMANDLINE_SWITCH_PREFIX = L"burn.";
40 40
41const LPCWSTR BURN_BUNDLE_LAYOUT_DIRECTORY = L"WixBundleLayoutDirectory";
42const LPCWSTR BURN_BUNDLE_ACTION = L"WixBundleAction"; 41const LPCWSTR BURN_BUNDLE_ACTION = L"WixBundleAction";
43const LPCWSTR BURN_BUNDLE_ACTIVE_PARENT = L"WixBundleActiveParent"; 42const LPCWSTR BURN_BUNDLE_ACTIVE_PARENT = L"WixBundleActiveParent";
44const LPCWSTR BURN_BUNDLE_COMMAND_LINE_ACTION = L"WixBundleCommandLineAction"; 43const LPCWSTR BURN_BUNDLE_COMMAND_LINE_ACTION = L"WixBundleCommandLineAction";
@@ -48,17 +47,17 @@ const LPCWSTR BURN_BUNDLE_FORCED_RESTART_PACKAGE = L"WixBundleForcedRestartPacka
48const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled"; 47const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled";
49const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated"; 48const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated";
50const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey"; 49const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey";
51const LPCWSTR BURN_BUNDLE_MANUFACTURER = L"WixBundleManufacturer";
52const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_PATH = L"WixBundleSourceProcessPath"; 50const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_PATH = L"WixBundleSourceProcessPath";
53const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_FOLDER = L"WixBundleSourceProcessFolder"; 51const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_FOLDER = L"WixBundleSourceProcessFolder";
54const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag"; 52const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag";
55const LPCWSTR BURN_BUNDLE_UILEVEL = L"WixBundleUILevel"; 53const LPCWSTR BURN_BUNDLE_UILEVEL = L"WixBundleUILevel";
56const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion"; 54const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion";
57const 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.
57const LPCWSTR BURN_BUNDLE_LAYOUT_DIRECTORY = L"WixBundleLayoutDirectory";
60const LPCWSTR BURN_BUNDLE_NAME = L"WixBundleName"; 58const LPCWSTR BURN_BUNDLE_NAME = L"WixBundleName";
61const LPCWSTR BURN_BUNDLE_INPROGRESS_NAME = L"WixBundleInProgressName"; 59const LPCWSTR BURN_BUNDLE_INPROGRESS_NAME = L"WixBundleInProgressName";
60const LPCWSTR BURN_BUNDLE_MANUFACTURER = L"WixBundleManufacturer";
62const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE = L"WixBundleOriginalSource"; 61const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE = L"WixBundleOriginalSource";
63const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = L"WixBundleOriginalSourceFolder"; 62const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = L"WixBundleOriginalSourceFolder";
64const LPCWSTR BURN_BUNDLE_LAST_USED_SOURCE = L"WixBundleLastUsedSource"; 63const 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
31extern "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
56LExit:
57 ReleaseObject(pixnLog);
58
59 return hr;
60}
61
31extern "C" HRESULT LoggingOpen( 62extern "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
275LExit: 301LExit:
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
44HRESULT LoggingParseFromXml(
45 __in BURN_LOGGING* pLog,
46 __in IXMLDOMNode* pixnBundle
47 );
44HRESULT LoggingOpen( 48HRESULT 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
168LExit: 151LExit:
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 @@
8extern "C" { 8extern "C" {
9#endif 9#endif
10 10
11// forward declare
12
13enum BURN_MODE;
14typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT BOOTSTRAPPER_ENGINE_CONTEXT;
15typedef struct _BURN_CACHE BURN_CACHE;
16typedef struct _BURN_DEPENDENCIES BURN_DEPENDENCIES;
17typedef struct _BURN_ENGINE_COMMAND BURN_ENGINE_COMMAND;
18typedef struct _BURN_LOGGING BURN_LOGGING;
19typedef 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
449LExit: 449LExit:
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,
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";
13const LPCWSTR VARIABLE_LOGONUSER = L"LogonUser"; 13const LPCWSTR VARIABLE_LOGONUSER = L"LogonUser";
14const LPCWSTR VARIABLE_INSTALLERNAME = L"InstallerName"; 14const LPCWSTR VARIABLE_INSTALLERNAME = L"InstallerName";
15const LPCWSTR VARIABLE_INSTALLERVERSION = L"InstallerVersion"; 15const LPCWSTR VARIABLE_INSTALLERVERSION = L"InstallerVersion";
16const LPCWSTR VARIABLE_REBOOTPENDING = L"RebootPending";
16 17
17 18
18// typedefs 19// typedefs