diff options
author | Rob Mensching <rob@firegiant.com> | 2021-01-09 01:37:43 -0800 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2021-01-09 01:41:08 -0800 |
commit | 923d3edd21da412b0fd6a09dfd3391913fe18c56 (patch) | |
tree | 7e6559d70829a39fd846820d6e3732174c1d0531 /src/ca | |
parent | a46b1cf9bd6f7dfca72b238a1bb1c838dde558ae (diff) | |
download | wix-923d3edd21da412b0fd6a09dfd3391913fe18c56.tar.gz wix-923d3edd21da412b0fd6a09dfd3391913fe18c56.tar.bz2 wix-923d3edd21da412b0fd6a09dfd3391913fe18c56.zip |
Modularize XmlConfig/@ElementId and add tests for XmlConfig
Fixes wixtoolset/issues#4698
Closes wixtoolset/issues#5447
Diffstat (limited to 'src/ca')
-rw-r--r-- | src/ca/XmlConfig.cpp | 101 |
1 files changed, 61 insertions, 40 deletions
diff --git a/src/ca/XmlConfig.cpp b/src/ca/XmlConfig.cpp index afd3dafb..0c2fae37 100644 --- a/src/ca/XmlConfig.cpp +++ b/src/ca/XmlConfig.cpp | |||
@@ -30,10 +30,10 @@ enum eXmlPreserveDate | |||
30 | }; | 30 | }; |
31 | 31 | ||
32 | LPCWSTR vcsXmlConfigQuery = | 32 | LPCWSTR vcsXmlConfigQuery = |
33 | L"SELECT `Wix4XmlConfig`.`Wix4XmlConfig`, `Wix4XmlConfig`.`File`, `Wix4XmlConfig`.`ElementPath`, `Wix4XmlConfig`.`VerifyPath`, `Wix4XmlConfig`.`Name`, " | 33 | L"SELECT `Wix4XmlConfig`.`Wix4XmlConfig`, `Wix4XmlConfig`.`File`, `Wix4XmlConfig`.`ElementId`, `Wix4XmlConfig`.`ElementPath`, `Wix4XmlConfig`.`VerifyPath`, `Wix4XmlConfig`.`Name`, " |
34 | L"`Wix4XmlConfig`.`Value`, `Wix4XmlConfig`.`Flags`, `Wix4XmlConfig`.`Component_`, `Component`.`Attributes` " | 34 | L"`Wix4XmlConfig`.`Value`, `Wix4XmlConfig`.`Flags`, `Wix4XmlConfig`.`Component_`, `Component`.`Attributes` " |
35 | L"FROM `Wix4XmlConfig`,`Component` WHERE `Wix4XmlConfig`.`Component_`=`Component`.`Component` ORDER BY `File`, `Sequence`"; | 35 | L"FROM `Wix4XmlConfig`,`Component` WHERE `Wix4XmlConfig`.`Component_`=`Component`.`Component` ORDER BY `File`, `Sequence`"; |
36 | enum eXmlConfigQuery { xfqXmlConfig = 1, xfqFile, xfqElementPath, xfqVerifyPath, xfqName, xfqValue, xfqXmlFlags, xfqComponent, xfqCompAttributes }; | 36 | enum eXmlConfigQuery { xfqXmlConfig = 1, xfqFile, xfqElementId, xfqElementPath, xfqVerifyPath, xfqName, xfqValue, xfqXmlFlags, xfqComponent, xfqCompAttributes }; |
37 | 37 | ||
38 | struct XML_CONFIG_CHANGE | 38 | struct XML_CONFIG_CHANGE |
39 | { | 39 | { |
@@ -44,6 +44,7 @@ struct XML_CONFIG_CHANGE | |||
44 | INSTALLSTATE isAction; | 44 | INSTALLSTATE isAction; |
45 | 45 | ||
46 | WCHAR wzFile[MAX_PATH]; | 46 | WCHAR wzFile[MAX_PATH]; |
47 | LPWSTR pwzElementId; | ||
47 | LPWSTR pwzElementPath; | 48 | LPWSTR pwzElementPath; |
48 | LPWSTR pwzVerifyPath; | 49 | LPWSTR pwzVerifyPath; |
49 | WCHAR wzName[MAX_DARWIN_COLUMN]; | 50 | WCHAR wzName[MAX_DARWIN_COLUMN]; |
@@ -72,26 +73,32 @@ static HRESULT FreeXmlConfigChangeList( | |||
72 | pxfcDelete = pxfcList; | 73 | pxfcDelete = pxfcList; |
73 | pxfcList = pxfcList->pxfcNext; | 74 | pxfcList = pxfcList->pxfcNext; |
74 | 75 | ||
76 | if (pxfcDelete->pwzElementId) | ||
77 | { | ||
78 | hr = MemFree(pxfcDelete->pwzElementId); | ||
79 | ExitOnFailure(hr, "failed to free xml config element id in change list item"); | ||
80 | } | ||
81 | |||
75 | if (pxfcDelete->pwzElementPath) | 82 | if (pxfcDelete->pwzElementPath) |
76 | { | 83 | { |
77 | hr = MemFree(pxfcDelete->pwzElementPath); | 84 | hr = MemFree(pxfcDelete->pwzElementPath); |
78 | ExitOnFailure(hr, "failed to free xml file element path in change list item"); | 85 | ExitOnFailure(hr, "failed to free xml config element path in change list item"); |
79 | } | 86 | } |
80 | 87 | ||
81 | if (pxfcDelete->pwzVerifyPath) | 88 | if (pxfcDelete->pwzVerifyPath) |
82 | { | 89 | { |
83 | hr = MemFree(pxfcDelete->pwzVerifyPath); | 90 | hr = MemFree(pxfcDelete->pwzVerifyPath); |
84 | ExitOnFailure(hr, "failed to free xml file verify path in change list item"); | 91 | ExitOnFailure(hr, "failed to free xml config verify path in change list item"); |
85 | } | 92 | } |
86 | 93 | ||
87 | if (pxfcDelete->pwzValue) | 94 | if (pxfcDelete->pwzValue) |
88 | { | 95 | { |
89 | hr = MemFree(pxfcDelete->pwzValue); | 96 | hr = MemFree(pxfcDelete->pwzValue); |
90 | ExitOnFailure(hr, "failed to free xml file value in change list item"); | 97 | ExitOnFailure(hr, "failed to free xml config value in change list item"); |
91 | } | 98 | } |
92 | 99 | ||
93 | hr = MemFree(pxfcDelete); | 100 | hr = MemFree(pxfcDelete); |
94 | ExitOnFailure(hr, "failed to free xml file change list item"); | 101 | ExitOnFailure(hr, "failed to free xml config change list item"); |
95 | } | 102 | } |
96 | 103 | ||
97 | LExit: | 104 | LExit: |
@@ -191,6 +198,10 @@ static HRESULT ReadXmlConfigTable( | |||
191 | hr = WcaGetRecordInteger(hRec, xfqXmlFlags, &(*ppxfcTail)->iXmlFlags); | 198 | hr = WcaGetRecordInteger(hRec, xfqXmlFlags, &(*ppxfcTail)->iXmlFlags); |
192 | ExitOnFailure(hr, "failed to get Wix4XmlConfig flags for Wix4XmlConfig: %ls", (*ppxfcTail)->wzId); | 199 | ExitOnFailure(hr, "failed to get Wix4XmlConfig flags for Wix4XmlConfig: %ls", (*ppxfcTail)->wzId); |
193 | 200 | ||
201 | // Get the Element Id | ||
202 | hr = WcaGetRecordFormattedString(hRec, xfqElementId, &(*ppxfcTail)->pwzElementId); | ||
203 | ExitOnFailure(hr, "failed to get Element Id for Wix4XmlConfig: %ls", (*ppxfcTail)->wzId); | ||
204 | |||
194 | // Get the Element Path | 205 | // Get the Element Path |
195 | hr = WcaGetRecordFormattedString(hRec, xfqElementPath, &(*ppxfcTail)->pwzElementPath); | 206 | hr = WcaGetRecordFormattedString(hRec, xfqElementPath, &(*ppxfcTail)->pwzElementPath); |
196 | ExitOnFailure(hr, "failed to get Element Path for Wix4XmlConfig: %ls", (*ppxfcTail)->wzId); | 207 | ExitOnFailure(hr, "failed to get Element Path for Wix4XmlConfig: %ls", (*ppxfcTail)->wzId); |
@@ -259,45 +270,55 @@ static HRESULT ProcessChanges( | |||
259 | pxfcCheck = *ppxfcHead; | 270 | pxfcCheck = *ppxfcHead; |
260 | while (pxfcCheck) | 271 | while (pxfcCheck) |
261 | { | 272 | { |
262 | if (0 == lstrcmpW(pxfc->pwzElementPath, pxfcCheck->wzId) && 0 == pxfc->iXmlFlags | 273 | if (pxfc->pwzElementId) |
263 | && XMLCONFIG_CREATE & pxfcCheck->iXmlFlags && XMLCONFIG_ELEMENT & pxfcCheck->iXmlFlags) | ||
264 | { | 274 | { |
265 | // We found a match. First, take it out of the current list | 275 | if (0 == lstrcmpW(pxfc->pwzElementId, pxfcCheck->wzId) |
266 | if (pxfc->pxfcPrev) | 276 | && 0 == pxfc->iXmlFlags |
277 | && XMLCONFIG_CREATE & pxfcCheck->iXmlFlags | ||
278 | && XMLCONFIG_ELEMENT & pxfcCheck->iXmlFlags) | ||
267 | { | 279 | { |
268 | pxfc->pxfcPrev->pxfcNext = pxfc->pxfcNext; | 280 | // We found a match. First, take it out of the current list |
269 | } | 281 | if (pxfc->pxfcPrev) |
270 | else // it was the head. Update the head | 282 | { |
271 | { | 283 | pxfc->pxfcPrev->pxfcNext = pxfc->pxfcNext; |
272 | *ppxfcHead = pxfc->pxfcNext; | 284 | } |
273 | } | 285 | else // it was the head. Update the head |
286 | { | ||
287 | *ppxfcHead = pxfc->pxfcNext; | ||
288 | } | ||
274 | 289 | ||
275 | if (pxfc->pxfcNext) | 290 | if (pxfc->pxfcNext) |
276 | { | 291 | { |
277 | pxfc->pxfcNext->pxfcPrev = pxfc->pxfcPrev; | 292 | pxfc->pxfcNext->pxfcPrev = pxfc->pxfcPrev; |
278 | } | 293 | } |
279 | 294 | ||
280 | pxfc->pxfcNext = NULL; | 295 | pxfc->pxfcNext = NULL; |
281 | pxfc->pxfcPrev = NULL; | 296 | pxfc->pxfcPrev = NULL; |
282 | 297 | ||
283 | // Now, add this node to the end of the matched node's additional changes list | 298 | // Now, add this node to the end of the matched node's additional changes list |
284 | if (!pxfcCheck->pxfcAdditionalChanges) | 299 | if (!pxfcCheck->pxfcAdditionalChanges) |
285 | { | 300 | { |
286 | pxfcCheck->pxfcAdditionalChanges = pxfc; | 301 | pxfcCheck->pxfcAdditionalChanges = pxfc; |
287 | pxfcCheck->cAdditionalChanges = 1; | 302 | pxfcCheck->cAdditionalChanges = 1; |
303 | } | ||
304 | else | ||
305 | { | ||
306 | pxfcLast = pxfcCheck->pxfcAdditionalChanges; | ||
307 | cAdditionalChanges = 1; | ||
308 | while (pxfcLast->pxfcNext) | ||
309 | { | ||
310 | pxfcLast = pxfcLast->pxfcNext; | ||
311 | ++cAdditionalChanges; | ||
312 | } | ||
313 | pxfcLast->pxfcNext = pxfc; | ||
314 | pxfc->pxfcPrev = pxfcLast; | ||
315 | pxfcCheck->cAdditionalChanges = ++cAdditionalChanges; | ||
316 | } | ||
288 | } | 317 | } |
289 | else | 318 | else |
290 | { | 319 | { |
291 | pxfcLast = pxfcCheck->pxfcAdditionalChanges; | 320 | hr = E_NOTFOUND; |
292 | cAdditionalChanges = 1; | 321 | ExitOnRootFailure(hr, "failed to find matching ElementId: %ls", pxfc->pwzElementId); |
293 | while (pxfcLast->pxfcNext) | ||
294 | { | ||
295 | pxfcLast = pxfcLast->pxfcNext; | ||
296 | ++cAdditionalChanges; | ||
297 | } | ||
298 | pxfcLast->pxfcNext = pxfc; | ||
299 | pxfc->pxfcPrev = pxfcLast; | ||
300 | pxfcCheck->cAdditionalChanges = ++cAdditionalChanges; | ||
301 | } | 322 | } |
302 | } | 323 | } |
303 | 324 | ||
@@ -381,9 +402,10 @@ static HRESULT WriteChangeData( | |||
381 | 402 | ||
382 | HRESULT hr = S_OK; | 403 | HRESULT hr = S_OK; |
383 | XML_CONFIG_CHANGE* pxfcAdditionalChanges = NULL; | 404 | XML_CONFIG_CHANGE* pxfcAdditionalChanges = NULL; |
405 | LPCWSTR wzElementPath = pxfc->pwzElementId ? pxfc->pwzElementId : pxfc->pwzElementPath; | ||
384 | 406 | ||
385 | hr = WcaWriteStringToCaData(pxfc->pwzElementPath, ppwzCustomActionData); | 407 | hr = WcaWriteStringToCaData(wzElementPath, ppwzCustomActionData); |
386 | ExitOnFailure(hr, "failed to write ElementPath to custom action data: %ls", pxfc->pwzElementPath); | 408 | ExitOnFailure(hr, "failed to write ElementPath to custom action data: %ls", wzElementPath); |
387 | 409 | ||
388 | hr = WcaWriteStringToCaData(pxfc->pwzVerifyPath, ppwzCustomActionData); | 410 | hr = WcaWriteStringToCaData(pxfc->pwzVerifyPath, ppwzCustomActionData); |
389 | ExitOnFailure(hr, "failed to write VerifyPath to custom action data: %ls", pxfc->pwzVerifyPath); | 411 | ExitOnFailure(hr, "failed to write VerifyPath to custom action data: %ls", pxfc->pwzVerifyPath); |
@@ -1111,4 +1133,3 @@ LExit: | |||
1111 | } | 1133 | } |
1112 | return WcaFinalize(er); | 1134 | return WcaFinalize(er); |
1113 | } | 1135 | } |
1114 | |||