diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/api/wix/WixToolset.Data/Symbols/WixBundleRollbackBoundarySymbol.cs | 8 | ||||
-rw-r--r-- | src/burn/engine/elevation.cpp | 15 | ||||
-rw-r--r-- | src/burn/engine/logging.cpp | 35 | ||||
-rw-r--r-- | src/burn/engine/logging.h | 7 | ||||
-rw-r--r-- | src/burn/engine/package.cpp | 62 | ||||
-rw-r--r-- | src/burn/engine/package.h | 1 | ||||
-rw-r--r-- | src/burn/engine/plan.cpp | 6 | ||||
-rw-r--r-- | src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs | 2 | ||||
-rw-r--r-- | src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs | 25 | ||||
-rw-r--r-- | src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs | 6 | ||||
-rw-r--r-- | src/wix/WixToolset.Core/Compiler_Bundle.cs | 26 | ||||
-rw-r--r-- | src/wix/test/WixToolsetTest.CoreIntegration/MsiTransactionFixture.cs | 11 |
12 files changed, 158 insertions, 46 deletions
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleRollbackBoundarySymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleRollbackBoundarySymbol.cs index e54e898e..1f91cef2 100644 --- a/src/api/wix/WixToolset.Data/Symbols/WixBundleRollbackBoundarySymbol.cs +++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleRollbackBoundarySymbol.cs | |||
@@ -12,6 +12,7 @@ namespace WixToolset.Data | |||
12 | { | 12 | { |
13 | new IntermediateFieldDefinition(nameof(WixBundleRollbackBoundarySymbolFields.Vital), IntermediateFieldType.Number), | 13 | new IntermediateFieldDefinition(nameof(WixBundleRollbackBoundarySymbolFields.Vital), IntermediateFieldType.Number), |
14 | new IntermediateFieldDefinition(nameof(WixBundleRollbackBoundarySymbolFields.Transaction), IntermediateFieldType.Number), | 14 | new IntermediateFieldDefinition(nameof(WixBundleRollbackBoundarySymbolFields.Transaction), IntermediateFieldType.Number), |
15 | new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.LogPathVariable), IntermediateFieldType.String), | ||
15 | }, | 16 | }, |
16 | typeof(WixBundleRollbackBoundarySymbol)); | 17 | typeof(WixBundleRollbackBoundarySymbol)); |
17 | } | 18 | } |
@@ -23,6 +24,7 @@ namespace WixToolset.Data.Symbols | |||
23 | { | 24 | { |
24 | Vital, | 25 | Vital, |
25 | Transaction, | 26 | Transaction, |
27 | LogPathVariable, | ||
26 | } | 28 | } |
27 | 29 | ||
28 | public class WixBundleRollbackBoundarySymbol : IntermediateSymbol | 30 | public class WixBundleRollbackBoundarySymbol : IntermediateSymbol |
@@ -48,5 +50,11 @@ namespace WixToolset.Data.Symbols | |||
48 | get => (bool?)this.Fields[(int)WixBundleRollbackBoundarySymbolFields.Transaction]; | 50 | get => (bool?)this.Fields[(int)WixBundleRollbackBoundarySymbolFields.Transaction]; |
49 | set => this.Set((int)WixBundleRollbackBoundarySymbolFields.Transaction, value); | 51 | set => this.Set((int)WixBundleRollbackBoundarySymbolFields.Transaction, value); |
50 | } | 52 | } |
53 | |||
54 | public string LogPathVariable | ||
55 | { | ||
56 | get => (string)this.Fields[(int)WixBundleRollbackBoundarySymbolFields.LogPathVariable]; | ||
57 | set => this.Set((int)WixBundleRollbackBoundarySymbolFields.LogPathVariable, value); | ||
58 | } | ||
51 | } | 59 | } |
52 | } \ No newline at end of file | 60 | } \ No newline at end of file |
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index 0e1cf0b7..ba6b1dd3 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
@@ -3246,7 +3246,10 @@ static HRESULT OnMsiBeginTransaction( | |||
3246 | hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary); | 3246 | hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary); |
3247 | ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId); | 3247 | ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId); |
3248 | 3248 | ||
3249 | pRollbackBoundary->sczLogPath = sczLogPath; | 3249 | if (sczLogPath && *sczLogPath) |
3250 | { | ||
3251 | pRollbackBoundary->sczLogPath = sczLogPath; | ||
3252 | } | ||
3250 | 3253 | ||
3251 | hr = MsiEngineBeginTransaction(pRollbackBoundary); | 3254 | hr = MsiEngineBeginTransaction(pRollbackBoundary); |
3252 | 3255 | ||
@@ -3284,7 +3287,10 @@ static HRESULT OnMsiCommitTransaction( | |||
3284 | hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary); | 3287 | hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary); |
3285 | ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId); | 3288 | ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId); |
3286 | 3289 | ||
3287 | pRollbackBoundary->sczLogPath = sczLogPath; | 3290 | if (sczLogPath && *sczLogPath) |
3291 | { | ||
3292 | pRollbackBoundary->sczLogPath = sczLogPath; | ||
3293 | } | ||
3288 | 3294 | ||
3289 | hr = MsiEngineCommitTransaction(pRollbackBoundary); | 3295 | hr = MsiEngineCommitTransaction(pRollbackBoundary); |
3290 | 3296 | ||
@@ -3322,7 +3328,10 @@ static HRESULT OnMsiRollbackTransaction( | |||
3322 | hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary); | 3328 | hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary); |
3323 | ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId); | 3329 | ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId); |
3324 | 3330 | ||
3325 | pRollbackBoundary->sczLogPath = sczLogPath; | 3331 | if (sczLogPath && *sczLogPath) |
3332 | { | ||
3333 | pRollbackBoundary->sczLogPath = sczLogPath; | ||
3334 | } | ||
3326 | 3335 | ||
3327 | hr = MsiEngineRollbackTransaction(pRollbackBoundary); | 3336 | hr = MsiEngineRollbackTransaction(pRollbackBoundary); |
3328 | 3337 | ||
diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp index 9aaf60ed..33295acd 100644 --- a/src/burn/engine/logging.cpp +++ b/src/burn/engine/logging.cpp | |||
@@ -242,11 +242,6 @@ extern "C" HRESULT LoggingSetPackageVariable( | |||
242 | // Make sure that no package log files are created when logging has been disabled via Log element. | 242 | // Make sure that no package log files are created when logging has been disabled via Log element. |
243 | if (BURN_LOGGING_STATE_DISABLED == pLog->state) | 243 | if (BURN_LOGGING_STATE_DISABLED == pLog->state) |
244 | { | 244 | { |
245 | if (psczLogPath) | ||
246 | { | ||
247 | *psczLogPath = NULL; | ||
248 | } | ||
249 | |||
250 | ExitFunction(); | 245 | ExitFunction(); |
251 | } | 246 | } |
252 | 247 | ||
@@ -272,6 +267,36 @@ LExit: | |||
272 | return hr; | 267 | return hr; |
273 | } | 268 | } |
274 | 269 | ||
270 | extern "C" HRESULT LoggingSetTransactionVariable( | ||
271 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary, | ||
272 | __in_z_opt LPCWSTR wzSuffix, | ||
273 | __in BURN_LOGGING* pLog, | ||
274 | __in BURN_VARIABLES* pVariables | ||
275 | ) | ||
276 | { | ||
277 | HRESULT hr = S_OK; | ||
278 | |||
279 | // Make sure that no log files are created when logging has been disabled via Log element. | ||
280 | if (BURN_LOGGING_STATE_DISABLED == pLog->state) | ||
281 | { | ||
282 | ExitFunction(); | ||
283 | } | ||
284 | |||
285 | if (pRollbackBoundary && pRollbackBoundary->sczLogPathVariable && *pRollbackBoundary->sczLogPathVariable) | ||
286 | { | ||
287 | hr = StrAllocFormatted(&pRollbackBoundary->sczLogPath, L"%ls%hs%ls_%03u_%ls.%ls", pLog->sczPrefix, wzSuffix && *wzSuffix ? "_" : "", wzSuffix && *wzSuffix ? wzSuffix : L"", vdwPackageSequence, pRollbackBoundary->sczId, pLog->sczExtension); | ||
288 | ExitOnFailure(hr, "Failed to allocate path for transaction log."); | ||
289 | |||
290 | hr = VariableSetString(pVariables, pRollbackBoundary->sczLogPathVariable, pRollbackBoundary->sczLogPath, FALSE, FALSE); | ||
291 | ExitOnFailure(hr, "Failed to set log path into variable."); | ||
292 | } | ||
293 | |||
294 | LExit: | ||
295 | ++vdwPackageSequence; | ||
296 | |||
297 | return hr; | ||
298 | } | ||
299 | |||
275 | extern "C" LPCSTR LoggingBurnActionToString( | 300 | extern "C" LPCSTR LoggingBurnActionToString( |
276 | __in BOOTSTRAPPER_ACTION action | 301 | __in BOOTSTRAPPER_ACTION action |
277 | ) | 302 | ) |
diff --git a/src/burn/engine/logging.h b/src/burn/engine/logging.h index 492e14b6..367b94a3 100644 --- a/src/burn/engine/logging.h +++ b/src/burn/engine/logging.h | |||
@@ -62,6 +62,13 @@ HRESULT LoggingSetPackageVariable( | |||
62 | __out_opt LPWSTR* psczLogPath | 62 | __out_opt LPWSTR* psczLogPath |
63 | ); | 63 | ); |
64 | 64 | ||
65 | HRESULT LoggingSetTransactionVariable( | ||
66 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary, | ||
67 | __in_z_opt LPCWSTR wzSuffix, | ||
68 | __in BURN_LOGGING* pLog, | ||
69 | __in BURN_VARIABLES* pVariables | ||
70 | ); | ||
71 | |||
65 | LPCSTR LoggingBurnActionToString( | 72 | LPCSTR LoggingBurnActionToString( |
66 | __in BOOTSTRAPPER_ACTION action | 73 | __in BOOTSTRAPPER_ACTION action |
67 | ); | 74 | ); |
diff --git a/src/burn/engine/package.cpp b/src/burn/engine/package.cpp index cd871bc5..bea48cb5 100644 --- a/src/burn/engine/package.cpp +++ b/src/burn/engine/package.cpp | |||
@@ -36,6 +36,7 @@ extern "C" HRESULT PackagesParseFromXml( | |||
36 | BSTR bstrNodeName = NULL; | 36 | BSTR bstrNodeName = NULL; |
37 | DWORD cMspPackages = 0; | 37 | DWORD cMspPackages = 0; |
38 | LPWSTR scz = NULL; | 38 | LPWSTR scz = NULL; |
39 | BOOL fFoundXml = FALSE; | ||
39 | 40 | ||
40 | // select rollback boundary nodes | 41 | // select rollback boundary nodes |
41 | hr = XmlSelectNodes(pixnBundle, L"RollbackBoundary", &pixnNodes); | 42 | hr = XmlSelectNodes(pixnBundle, L"RollbackBoundary", &pixnNodes); |
@@ -63,15 +64,19 @@ extern "C" HRESULT PackagesParseFromXml( | |||
63 | 64 | ||
64 | // @Id | 65 | // @Id |
65 | hr = XmlGetAttributeEx(pixnNode, L"Id", &pRollbackBoundary->sczId); | 66 | hr = XmlGetAttributeEx(pixnNode, L"Id", &pRollbackBoundary->sczId); |
66 | ExitOnFailure(hr, "Failed to get @Id."); | 67 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Id."); |
67 | 68 | ||
68 | // @Vital | 69 | // @Vital |
69 | hr = XmlGetYesNoAttribute(pixnNode, L"Vital", &pRollbackBoundary->fVital); | 70 | hr = XmlGetYesNoAttribute(pixnNode, L"Vital", &pRollbackBoundary->fVital); |
70 | ExitOnFailure(hr, "Failed to get @Vital."); | 71 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Vital."); |
71 | 72 | ||
72 | // @Transaction | 73 | // @Transaction |
73 | hr = XmlGetYesNoAttribute(pixnNode, L"Transaction", &pRollbackBoundary->fTransactionAuthored); | 74 | hr = XmlGetYesNoAttribute(pixnNode, L"Transaction", &pRollbackBoundary->fTransactionAuthored); |
74 | ExitOnFailure(hr, "Failed to get @Transaction."); | 75 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Transaction."); |
76 | |||
77 | // @LogPathVariable | ||
78 | hr = XmlGetAttributeEx(pixnNode, L"LogPathVariable", &pRollbackBoundary->sczLogPathVariable); | ||
79 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @LogPathVariable."); | ||
75 | 80 | ||
76 | // prepare next iteration | 81 | // prepare next iteration |
77 | ReleaseNullObject(pixnNode); | 82 | ReleaseNullObject(pixnNode); |
@@ -110,11 +115,13 @@ extern "C" HRESULT PackagesParseFromXml( | |||
110 | 115 | ||
111 | // @Id | 116 | // @Id |
112 | hr = XmlGetAttributeEx(pixnNode, L"Id", &pPackage->sczId); | 117 | hr = XmlGetAttributeEx(pixnNode, L"Id", &pPackage->sczId); |
113 | ExitOnFailure(hr, "Failed to get @Id."); | 118 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Id."); |
114 | 119 | ||
115 | // @Cache | 120 | // @Cache |
116 | hr = XmlGetAttributeEx(pixnNode, L"Cache", &scz); | 121 | hr = XmlGetAttributeEx(pixnNode, L"Cache", &scz); |
117 | if (SUCCEEDED(hr)) | 122 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Cache."); |
123 | |||
124 | if (fFoundXml) | ||
118 | { | 125 | { |
119 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"remove", -1)) | 126 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"remove", -1)) |
120 | { | 127 | { |
@@ -134,72 +141,62 @@ extern "C" HRESULT PackagesParseFromXml( | |||
134 | ExitOnRootFailure(hr, "Invalid cache type: %ls", scz); | 141 | ExitOnRootFailure(hr, "Invalid cache type: %ls", scz); |
135 | } | 142 | } |
136 | } | 143 | } |
137 | ExitOnFailure(hr, "Failed to get @Cache."); | ||
138 | 144 | ||
139 | // @CacheId | 145 | // @CacheId |
140 | hr = XmlGetAttributeEx(pixnNode, L"CacheId", &pPackage->sczCacheId); | 146 | hr = XmlGetAttributeEx(pixnNode, L"CacheId", &pPackage->sczCacheId); |
141 | ExitOnFailure(hr, "Failed to get @CacheId."); | 147 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @CacheId."); |
142 | 148 | ||
143 | // @Size | 149 | // @Size |
144 | hr = XmlGetAttributeUInt64(pixnNode, L"Size", &pPackage->qwSize); | 150 | hr = XmlGetAttributeUInt64(pixnNode, L"Size", &pPackage->qwSize); |
145 | ExitOnFailure(hr, "Failed to get @Size."); | 151 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Size."); |
146 | 152 | ||
147 | // @InstallSize | 153 | // @InstallSize |
148 | hr = XmlGetAttributeUInt64(pixnNode, L"InstallSize", &pPackage->qwInstallSize); | 154 | hr = XmlGetAttributeUInt64(pixnNode, L"InstallSize", &pPackage->qwInstallSize); |
149 | ExitOnFailure(hr, "Failed to get @InstallSize."); | 155 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallSize."); |
150 | 156 | ||
151 | // @PerMachine | 157 | // @PerMachine |
152 | hr = XmlGetYesNoAttribute(pixnNode, L"PerMachine", &pPackage->fPerMachine); | 158 | hr = XmlGetYesNoAttribute(pixnNode, L"PerMachine", &pPackage->fPerMachine); |
153 | ExitOnFailure(hr, "Failed to get @PerMachine."); | 159 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @PerMachine."); |
154 | 160 | ||
155 | // @Permanent | 161 | // @Permanent |
156 | hr = XmlGetYesNoAttribute(pixnNode, L"Permanent", &pPackage->fUninstallable); | 162 | hr = XmlGetYesNoAttribute(pixnNode, L"Permanent", &pPackage->fUninstallable); |
157 | ExitOnFailure(hr, "Failed to get @Permanent."); | 163 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Permanent."); |
158 | pPackage->fUninstallable = !pPackage->fUninstallable; // TODO: change "Uninstallable" variable name to permanent, until then Uninstallable is the opposite of Permanent so fix the variable. | 164 | pPackage->fUninstallable = !pPackage->fUninstallable; // TODO: change "Uninstallable" variable name to permanent, until then Uninstallable is the opposite of Permanent so fix the variable. |
159 | pPackage->fCanAffectRegistration = pPackage->fUninstallable; | 165 | pPackage->fCanAffectRegistration = pPackage->fUninstallable; |
160 | 166 | ||
161 | // @Vital | 167 | // @Vital |
162 | hr = XmlGetYesNoAttribute(pixnNode, L"Vital", &pPackage->fVital); | 168 | hr = XmlGetYesNoAttribute(pixnNode, L"Vital", &pPackage->fVital); |
163 | ExitOnFailure(hr, "Failed to get @Vital."); | 169 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Vital."); |
164 | 170 | ||
165 | // @LogPathVariable | 171 | // @LogPathVariable |
166 | hr = XmlGetAttributeEx(pixnNode, L"LogPathVariable", &pPackage->sczLogPathVariable); | 172 | hr = XmlGetAttributeEx(pixnNode, L"LogPathVariable", &pPackage->sczLogPathVariable); |
167 | if (E_NOTFOUND != hr) | 173 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @LogPathVariable."); |
168 | { | ||
169 | ExitOnFailure(hr, "Failed to get @LogPathVariable."); | ||
170 | } | ||
171 | 174 | ||
172 | // @RollbackLogPathVariable | 175 | // @RollbackLogPathVariable |
173 | hr = XmlGetAttributeEx(pixnNode, L"RollbackLogPathVariable", &pPackage->sczRollbackLogPathVariable); | 176 | hr = XmlGetAttributeEx(pixnNode, L"RollbackLogPathVariable", &pPackage->sczRollbackLogPathVariable); |
174 | if (E_NOTFOUND != hr) | 177 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RollbackLogPathVariable."); |
175 | { | ||
176 | ExitOnFailure(hr, "Failed to get @RollbackLogPathVariable."); | ||
177 | } | ||
178 | 178 | ||
179 | // @InstallCondition | 179 | // @InstallCondition |
180 | hr = XmlGetAttributeEx(pixnNode, L"InstallCondition", &pPackage->sczInstallCondition); | 180 | hr = XmlGetAttributeEx(pixnNode, L"InstallCondition", &pPackage->sczInstallCondition); |
181 | if (E_NOTFOUND != hr) | 181 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallCondition."); |
182 | { | ||
183 | ExitOnFailure(hr, "Failed to get @InstallCondition."); | ||
184 | } | ||
185 | 182 | ||
186 | // @RollbackBoundaryForward | 183 | // @RollbackBoundaryForward |
187 | hr = XmlGetAttributeEx(pixnNode, L"RollbackBoundaryForward", &scz); | 184 | hr = XmlGetAttributeEx(pixnNode, L"RollbackBoundaryForward", &scz); |
188 | if (E_NOTFOUND != hr) | 185 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RollbackBoundaryForward."); |
189 | { | ||
190 | ExitOnFailure(hr, "Failed to get @RollbackBoundaryForward."); | ||
191 | 186 | ||
192 | hr = FindRollbackBoundaryById(pPackages, scz, &pPackage->pRollbackBoundaryForward); | 187 | if (fFoundXml) |
188 | { | ||
189 | hr = FindRollbackBoundaryById(pPackages, scz, &pPackage->pRollbackBoundaryForward); | ||
193 | ExitOnFailure(hr, "Failed to find forward transaction boundary: %ls", scz); | 190 | ExitOnFailure(hr, "Failed to find forward transaction boundary: %ls", scz); |
194 | } | 191 | } |
195 | 192 | ||
196 | // @RollbackBoundaryBackward | 193 | // @RollbackBoundaryBackward |
197 | hr = XmlGetAttributeEx(pixnNode, L"RollbackBoundaryBackward", &scz); | 194 | hr = XmlGetAttributeEx(pixnNode, L"RollbackBoundaryBackward", &scz); |
198 | if (E_NOTFOUND != hr) | 195 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RollbackBoundaryBackward."); |
199 | { | ||
200 | ExitOnFailure(hr, "Failed to get @RollbackBoundaryBackward."); | ||
201 | 196 | ||
202 | hr = FindRollbackBoundaryById(pPackages, scz, &pPackage->pRollbackBoundaryBackward); | 197 | if (fFoundXml) |
198 | { | ||
199 | hr = FindRollbackBoundaryById(pPackages, scz, &pPackage->pRollbackBoundaryBackward); | ||
203 | ExitOnFailure(hr, "Failed to find backward transaction boundary: %ls", scz); | 200 | ExitOnFailure(hr, "Failed to find backward transaction boundary: %ls", scz); |
204 | } | 201 | } |
205 | 202 | ||
@@ -378,6 +375,7 @@ extern "C" void PackagesUninitialize( | |||
378 | { | 375 | { |
379 | ReleaseStr(pPackages->rgRollbackBoundaries[i].sczId); | 376 | ReleaseStr(pPackages->rgRollbackBoundaries[i].sczId); |
380 | ReleaseStr(pPackages->rgRollbackBoundaries[i].sczLogPath); | 377 | ReleaseStr(pPackages->rgRollbackBoundaries[i].sczLogPath); |
378 | ReleaseStr(pPackages->rgRollbackBoundaries[i].sczLogPathVariable); | ||
381 | } | 379 | } |
382 | MemFree(pPackages->rgRollbackBoundaries); | 380 | MemFree(pPackages->rgRollbackBoundaries); |
383 | } | 381 | } |
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index 3d8233d1..f2a1c304 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h | |||
@@ -195,6 +195,7 @@ typedef struct _BURN_ROLLBACK_BOUNDARY | |||
195 | BOOL fTransactionAuthored; | 195 | BOOL fTransactionAuthored; |
196 | BOOL fTransaction; | 196 | BOOL fTransaction; |
197 | BOOL fActiveTransaction; // only valid during Apply. | 197 | BOOL fActiveTransaction; // only valid during Apply. |
198 | LPWSTR sczLogPathVariable; | ||
198 | LPWSTR sczLogPath; | 199 | LPWSTR sczLogPath; |
199 | } BURN_ROLLBACK_BOUNDARY; | 200 | } BURN_ROLLBACK_BOUNDARY; |
200 | 201 | ||
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index 85d958a6..58981352 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
@@ -1709,8 +1709,8 @@ LExit: | |||
1709 | extern "C" HRESULT PlanRollbackBoundaryBegin( | 1709 | extern "C" HRESULT PlanRollbackBoundaryBegin( |
1710 | __in BURN_PLAN* pPlan, | 1710 | __in BURN_PLAN* pPlan, |
1711 | __in BURN_USER_EXPERIENCE* pUX, | 1711 | __in BURN_USER_EXPERIENCE* pUX, |
1712 | __in BURN_LOGGING* /*pLog*/, | 1712 | __in BURN_LOGGING* pLog, |
1713 | __in BURN_VARIABLES* /*pVariables*/, | 1713 | __in BURN_VARIABLES* pVariables, |
1714 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary | 1714 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary |
1715 | ) | 1715 | ) |
1716 | { | 1716 | { |
@@ -1744,6 +1744,8 @@ extern "C" HRESULT PlanRollbackBoundaryBegin( | |||
1744 | } | 1744 | } |
1745 | else | 1745 | else |
1746 | { | 1746 | { |
1747 | LoggingSetTransactionVariable(pRollbackBoundary, NULL, pLog, pVariables); // ignore errors. | ||
1748 | |||
1747 | // Add begin MSI transaction to execute plan. | 1749 | // Add begin MSI transaction to execute plan. |
1748 | hr = PlanExecuteCheckpoint(pPlan); | 1750 | hr = PlanExecuteCheckpoint(pPlan); |
1749 | ExitOnFailure(hr, "Failed to append checkpoint before MSI transaction begin action."); | 1751 | ExitOnFailure(hr, "Failed to append checkpoint before MSI transaction begin action."); |
diff --git a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs index 97007022..cd00232a 100644 --- a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs | |||
@@ -393,7 +393,7 @@ namespace WixToolset.Core.Burn | |||
393 | // Generate the core-defined BA manifest tables... | 393 | // Generate the core-defined BA manifest tables... |
394 | string baManifestPath; | 394 | string baManifestPath; |
395 | { | 395 | { |
396 | var command = new CreateBootstrapperApplicationManifestCommand(section, bundleSymbol, orderedFacades, uxPayloadIndex, payloadSymbols, packagesPayloads, this.IntermediateFolder, this.InternalBurnBackendHelper); | 396 | var command = new CreateBootstrapperApplicationManifestCommand(section, bundleSymbol, boundaries, orderedFacades, uxPayloadIndex, payloadSymbols, packagesPayloads, this.IntermediateFolder, this.InternalBurnBackendHelper); |
397 | command.Execute(); | 397 | command.Execute(); |
398 | 398 | ||
399 | var baManifestPayload = command.BootstrapperApplicationManifestPayloadRow; | 399 | var baManifestPayload = command.BootstrapperApplicationManifestPayloadRow; |
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs index 764a38ab..42e3381a 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs | |||
@@ -15,10 +15,11 @@ namespace WixToolset.Core.Burn.Bundles | |||
15 | 15 | ||
16 | internal class CreateBootstrapperApplicationManifestCommand | 16 | internal class CreateBootstrapperApplicationManifestCommand |
17 | { | 17 | { |
18 | public CreateBootstrapperApplicationManifestCommand(IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<PackageFacade> chainPackages, int lastUXPayloadIndex, Dictionary<string, WixBundlePayloadSymbol> payloadSymbols, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, string intermediateFolder, IInternalBurnBackendHelper internalBurnBackendHelper) | 18 | public CreateBootstrapperApplicationManifestCommand(IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, IEnumerable<PackageFacade> chainPackages, int lastUXPayloadIndex, Dictionary<string, WixBundlePayloadSymbol> payloadSymbols, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, string intermediateFolder, IInternalBurnBackendHelper internalBurnBackendHelper) |
19 | { | 19 | { |
20 | this.Section = section; | 20 | this.Section = section; |
21 | this.BundleSymbol = bundleSymbol; | 21 | this.BundleSymbol = bundleSymbol; |
22 | this.RollbackBoundaries = boundaries; | ||
22 | this.ChainPackages = chainPackages; | 23 | this.ChainPackages = chainPackages; |
23 | this.LastUXPayloadIndex = lastUXPayloadIndex; | 24 | this.LastUXPayloadIndex = lastUXPayloadIndex; |
24 | this.Payloads = payloadSymbols; | 25 | this.Payloads = payloadSymbols; |
@@ -31,6 +32,8 @@ namespace WixToolset.Core.Burn.Bundles | |||
31 | 32 | ||
32 | private WixBundleSymbol BundleSymbol { get; } | 33 | private WixBundleSymbol BundleSymbol { get; } |
33 | 34 | ||
35 | private IEnumerable<WixBundleRollbackBoundarySymbol> RollbackBoundaries { get; } | ||
36 | |||
34 | private IEnumerable<PackageFacade> ChainPackages { get; } | 37 | private IEnumerable<PackageFacade> ChainPackages { get; } |
35 | 38 | ||
36 | private IInternalBurnBackendHelper InternalBurnBackendHelper { get; } | 39 | private IInternalBurnBackendHelper InternalBurnBackendHelper { get; } |
@@ -70,6 +73,8 @@ namespace WixToolset.Core.Burn.Bundles | |||
70 | 73 | ||
71 | this.WriteCommandLineInfo(writer); | 74 | this.WriteCommandLineInfo(writer); |
72 | 75 | ||
76 | this.WriteRollbackBoundaryInfo(writer); | ||
77 | |||
73 | this.WritePackageInfo(writer); | 78 | this.WritePackageInfo(writer); |
74 | 79 | ||
75 | this.WriteFeatureInfo(writer); | 80 | this.WriteFeatureInfo(writer); |
@@ -116,6 +121,24 @@ namespace WixToolset.Core.Burn.Bundles | |||
116 | writer.WriteEndElement(); | 121 | writer.WriteEndElement(); |
117 | } | 122 | } |
118 | 123 | ||
124 | private void WriteRollbackBoundaryInfo(XmlTextWriter writer) | ||
125 | { | ||
126 | foreach (var rollbackBoundary in this.RollbackBoundaries) | ||
127 | { | ||
128 | writer.WriteStartElement("WixRollbackBoundary"); | ||
129 | writer.WriteAttributeString("Id", rollbackBoundary.Id.Id); | ||
130 | writer.WriteAttributeString("Vital", rollbackBoundary.Vital == false ? "no" : "yes"); | ||
131 | writer.WriteAttributeString("Transaction", rollbackBoundary.Transaction == true ? "yes" : "no"); | ||
132 | |||
133 | if (!String.IsNullOrEmpty(rollbackBoundary.LogPathVariable)) | ||
134 | { | ||
135 | writer.WriteAttributeString("LogPathVariable", rollbackBoundary.LogPathVariable); | ||
136 | } | ||
137 | |||
138 | writer.WriteEndElement(); | ||
139 | } | ||
140 | } | ||
141 | |||
119 | private void WritePackageInfo(XmlTextWriter writer) | 142 | private void WritePackageInfo(XmlTextWriter writer) |
120 | { | 143 | { |
121 | foreach (var package in this.ChainPackages) | 144 | foreach (var package in this.ChainPackages) |
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs index 27b1f234..19dc7933 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs | |||
@@ -188,6 +188,12 @@ namespace WixToolset.Core.Burn.Bundles | |||
188 | writer.WriteAttributeString("Id", rollbackBoundary.Id.Id); | 188 | writer.WriteAttributeString("Id", rollbackBoundary.Id.Id); |
189 | writer.WriteAttributeString("Vital", rollbackBoundary.Vital == false ? "no" : "yes"); | 189 | writer.WriteAttributeString("Vital", rollbackBoundary.Vital == false ? "no" : "yes"); |
190 | writer.WriteAttributeString("Transaction", rollbackBoundary.Transaction == true ? "yes" : "no"); | 190 | writer.WriteAttributeString("Transaction", rollbackBoundary.Transaction == true ? "yes" : "no"); |
191 | |||
192 | if (!String.IsNullOrEmpty(rollbackBoundary.LogPathVariable)) | ||
193 | { | ||
194 | writer.WriteAttributeString("LogPathVariable", rollbackBoundary.LogPathVariable); | ||
195 | } | ||
196 | |||
191 | writer.WriteEndElement(); | 197 | writer.WriteEndElement(); |
192 | } | 198 | } |
193 | 199 | ||
diff --git a/src/wix/WixToolset.Core/Compiler_Bundle.cs b/src/wix/WixToolset.Core/Compiler_Bundle.cs index 20af017d..851561d1 100644 --- a/src/wix/WixToolset.Core/Compiler_Bundle.cs +++ b/src/wix/WixToolset.Core/Compiler_Bundle.cs | |||
@@ -1860,6 +1860,7 @@ namespace WixToolset.Core | |||
1860 | Identifier id = null; | 1860 | Identifier id = null; |
1861 | var vital = YesNoType.Yes; | 1861 | var vital = YesNoType.Yes; |
1862 | var transaction = YesNoType.No; | 1862 | var transaction = YesNoType.No; |
1863 | string logPathVariable = null; | ||
1863 | 1864 | ||
1864 | // This list lets us evaluate extension attributes *after* all core attributes | 1865 | // This list lets us evaluate extension attributes *after* all core attributes |
1865 | // have been parsed and dealt with, regardless of authoring order. | 1866 | // have been parsed and dealt with, regardless of authoring order. |
@@ -1885,6 +1886,9 @@ namespace WixToolset.Core | |||
1885 | case "Transaction": | 1886 | case "Transaction": |
1886 | transaction = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); | 1887 | transaction = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); |
1887 | break; | 1888 | break; |
1889 | case "LogPathVariable": | ||
1890 | logPathVariable = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); | ||
1891 | break; | ||
1888 | default: | 1892 | default: |
1889 | allowed = false; | 1893 | allowed = false; |
1890 | break; | 1894 | break; |
@@ -1932,9 +1936,21 @@ namespace WixToolset.Core | |||
1932 | 1936 | ||
1933 | this.Core.ParseForExtensionElements(node); | 1937 | this.Core.ParseForExtensionElements(node); |
1934 | 1938 | ||
1939 | if (transaction == YesNoType.Yes) | ||
1940 | { | ||
1941 | if (logPathVariable == null) | ||
1942 | { | ||
1943 | logPathVariable = String.Concat("WixBundleLog_", id.Id); | ||
1944 | } | ||
1945 | } | ||
1946 | else if (logPathVariable != null) | ||
1947 | { | ||
1948 | this.Core.Write(ErrorMessages.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "LogPathVariable", logPathVariable, "Transaction")); | ||
1949 | } | ||
1950 | |||
1935 | if (!this.Core.EncounteredError) | 1951 | if (!this.Core.EncounteredError) |
1936 | { | 1952 | { |
1937 | this.CreateRollbackBoundary(sourceLineNumbers, id, vital, transaction, parentType, parentId, previousType, previousId); | 1953 | this.CreateRollbackBoundary(sourceLineNumbers, id, vital, transaction, logPathVariable, parentType, parentId, previousType, previousId); |
1938 | } | 1954 | } |
1939 | 1955 | ||
1940 | return id.Id; | 1956 | return id.Id; |
@@ -2759,11 +2775,12 @@ namespace WixToolset.Core | |||
2759 | /// <param name="id">Identifier for the rollback boundary.</param> | 2775 | /// <param name="id">Identifier for the rollback boundary.</param> |
2760 | /// <param name="vital">Indicates whether the rollback boundary is vital or not.</param> | 2776 | /// <param name="vital">Indicates whether the rollback boundary is vital or not.</param> |
2761 | /// <param name="transaction">Indicates whether the rollback boundary will use an MSI transaction.</param> | 2777 | /// <param name="transaction">Indicates whether the rollback boundary will use an MSI transaction.</param> |
2778 | /// <param name="logPathVariable">The variable for the path of the MSI transaction log.</param> | ||
2762 | /// <param name="parentType">Type of parent group.</param> | 2779 | /// <param name="parentType">Type of parent group.</param> |
2763 | /// <param name="parentId">Identifier of parent group.</param> | 2780 | /// <param name="parentId">Identifier of parent group.</param> |
2764 | /// <param name="previousType">Type of previous item, if any.</param> | 2781 | /// <param name="previousType">Type of previous item, if any.</param> |
2765 | /// <param name="previousId">Identifier of previous item, if any.</param> | 2782 | /// <param name="previousId">Identifier of previous item, if any.</param> |
2766 | private void CreateRollbackBoundary(SourceLineNumber sourceLineNumbers, Identifier id, YesNoType vital, YesNoType transaction, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId) | 2783 | private void CreateRollbackBoundary(SourceLineNumber sourceLineNumbers, Identifier id, YesNoType vital, YesNoType transaction, string logPathVariable, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId) |
2767 | { | 2784 | { |
2768 | this.Core.AddSymbol(new WixChainItemSymbol(sourceLineNumbers, id)); | 2785 | this.Core.AddSymbol(new WixChainItemSymbol(sourceLineNumbers, id)); |
2769 | 2786 | ||
@@ -2777,6 +2794,11 @@ namespace WixToolset.Core | |||
2777 | if (YesNoType.NotSet != transaction) | 2794 | if (YesNoType.NotSet != transaction) |
2778 | { | 2795 | { |
2779 | rollbackBoundary.Transaction = (transaction == YesNoType.Yes); | 2796 | rollbackBoundary.Transaction = (transaction == YesNoType.Yes); |
2797 | |||
2798 | if (logPathVariable != null) | ||
2799 | { | ||
2800 | rollbackBoundary.LogPathVariable = logPathVariable; | ||
2801 | } | ||
2780 | } | 2802 | } |
2781 | 2803 | ||
2782 | this.CreateChainPackageMetaRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Package, id.Id, previousType, previousId, null); | 2804 | this.CreateChainPackageMetaRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Package, id.Id, previousType, previousId, null); |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/MsiTransactionFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/MsiTransactionFixture.cs index a566b490..573ae4b4 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/MsiTransactionFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/MsiTransactionFixture.cs | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | namespace WixToolsetTest.CoreIntegration | 3 | namespace WixToolsetTest.CoreIntegration |
4 | { | 4 | { |
5 | using System.Collections.Generic; | ||
5 | using System.IO; | 6 | using System.IO; |
6 | using WixBuildTools.TestSupport; | 7 | using WixBuildTools.TestSupport; |
7 | using WixToolset.Core.TestPackage; | 8 | using WixToolset.Core.TestPackage; |
@@ -50,6 +51,8 @@ namespace WixToolsetTest.CoreIntegration | |||
50 | var intermediateFolder = Path.Combine(baseFolder, "obj"); | 51 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
51 | var binFolder = Path.Combine(baseFolder, "bin"); | 52 | var binFolder = Path.Combine(baseFolder, "bin"); |
52 | var exePath = Path.Combine(binFolder, "test.exe"); | 53 | var exePath = Path.Combine(binFolder, "test.exe"); |
54 | var baFolderPath = Path.Combine(baseFolder, "ba"); | ||
55 | var extractFolderPath = Path.Combine(baseFolder, "extract"); | ||
53 | 56 | ||
54 | BuildMsiPackages(folder, intermediateFolder, binFolder); | 57 | BuildMsiPackages(folder, intermediateFolder, binFolder); |
55 | 58 | ||
@@ -68,6 +71,14 @@ namespace WixToolsetTest.CoreIntegration | |||
68 | result.AssertSuccess(); | 71 | result.AssertSuccess(); |
69 | 72 | ||
70 | Assert.True(File.Exists(exePath)); | 73 | Assert.True(File.Exists(exePath)); |
74 | |||
75 | var extractResult = BundleExtractor.ExtractBAContainer(null, exePath, baFolderPath, extractFolderPath); | ||
76 | extractResult.AssertSuccess(); | ||
77 | |||
78 | var rollbackBoundaries = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:RollbackBoundary"); | ||
79 | Assert.Equal(2, rollbackBoundaries.Count); | ||
80 | Assert.Equal("<RollbackBoundary Id='WixDefaultBoundary' Vital='yes' Transaction='no' />", rollbackBoundaries[0].GetTestXml()); | ||
81 | Assert.Equal("<RollbackBoundary Id='rba31DvS6_ninGllmavuS.cp4RYckk' Vital='yes' Transaction='yes' LogPathVariable='WixBundleLog_rba31DvS6_ninGllmavuS.cp4RYckk' />", rollbackBoundaries[1].GetTestXml()); | ||
71 | } | 82 | } |
72 | } | 83 | } |
73 | 84 | ||