diff options
author | Rob Mensching <rob@firegiant.com> | 2021-04-11 12:22:57 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2021-04-12 19:28:07 -0700 |
commit | 13c4becf524dbd12b92f099320726aa0b59f3bbc (patch) | |
tree | 28155ea32d18a3b1868c7743e4889a797456c26c /src/ca | |
parent | aea4e48d8408689c5749d154dddcfb99ddfb257b (diff) | |
download | wix-13c4becf524dbd12b92f099320726aa0b59f3bbc.tar.gz wix-13c4becf524dbd12b92f099320726aa0b59f3bbc.tar.bz2 wix-13c4becf524dbd12b92f099320726aa0b59f3bbc.zip |
Add Condition to RemoveFoldersEx
Diffstat (limited to 'src/ca')
-rw-r--r-- | src/ca/RemoveFoldersEx.cpp | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/src/ca/RemoveFoldersEx.cpp b/src/ca/RemoveFoldersEx.cpp index ce64c2c2..cbc7f4bb 100644 --- a/src/ca/RemoveFoldersEx.cpp +++ b/src/ca/RemoveFoldersEx.cpp | |||
@@ -2,8 +2,11 @@ | |||
2 | 2 | ||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | ||
5 | LPCWSTR vcsRemoveFolderExQuery = L"SELECT `Wix4RemoveFolderEx`, `Component_`, `Property`, `InstallMode` FROM `Wix4RemoveFolderEx`"; | 5 | LPCWSTR vcsRemoveFolderExQuery = |
6 | enum eRemoveFolderExQuery { rfqId = 1, rfqComponent, rfqProperty, feqMode }; | 6 | L"SELECT `Wix4RemoveFolderEx`, `Component_`, `Property`, `InstallMode`, `WixRemoveFolderEx`.`Condition`, `Component`.`Attributes`" |
7 | L"FROM `Wix4RemoveFolderEx``,`Component` " | ||
8 | L"WHERE `Wix4RemoveFolderEx`.`Component_`=`Component`.`Component`"; | ||
9 | enum eRemoveFolderExQuery { rfqId = 1, rfqComponent, rfqProperty, rfqMode, rfqCondition, rfqComponentAttributes }; | ||
7 | 10 | ||
8 | static HRESULT RecursePath( | 11 | static HRESULT RecursePath( |
9 | __in_z LPCWSTR wzPath, | 12 | __in_z LPCWSTR wzPath, |
@@ -11,6 +14,7 @@ static HRESULT RecursePath( | |||
11 | __in_z LPCWSTR wzComponent, | 14 | __in_z LPCWSTR wzComponent, |
12 | __in_z LPCWSTR wzProperty, | 15 | __in_z LPCWSTR wzProperty, |
13 | __in int iMode, | 16 | __in int iMode, |
17 | __in BOOL fDisableWow64Redirection, | ||
14 | __inout DWORD* pdwCounter, | 18 | __inout DWORD* pdwCounter, |
15 | __inout MSIHANDLE* phTable, | 19 | __inout MSIHANDLE* phTable, |
16 | __inout MSIHANDLE* phColumns | 20 | __inout MSIHANDLE* phColumns |
@@ -24,6 +28,12 @@ static HRESULT RecursePath( | |||
24 | WIN32_FIND_DATAW wfd; | 28 | WIN32_FIND_DATAW wfd; |
25 | LPWSTR sczNext = NULL; | 29 | LPWSTR sczNext = NULL; |
26 | 30 | ||
31 | if (fDisableWow64Redirection) | ||
32 | { | ||
33 | hr = WcaDisableWow64FSRedirection(); | ||
34 | ExitOnFailure(hr, "Custom action was told to act on a 64-bit component, but was unable to disable filesystem redirection through the Wow64 API."); | ||
35 | } | ||
36 | |||
27 | // First recurse down to all the child directories. | 37 | // First recurse down to all the child directories. |
28 | hr = StrAllocFormatted(&sczSearch, L"%s*", wzPath); | 38 | hr = StrAllocFormatted(&sczSearch, L"%s*", wzPath); |
29 | ExitOnFailure(hr, "Failed to allocate file search string in path: %S", wzPath); | 39 | ExitOnFailure(hr, "Failed to allocate file search string in path: %S", wzPath); |
@@ -34,7 +44,7 @@ static HRESULT RecursePath( | |||
34 | er = ::GetLastError(); | 44 | er = ::GetLastError(); |
35 | if (ERROR_PATH_NOT_FOUND == er) | 45 | if (ERROR_PATH_NOT_FOUND == er) |
36 | { | 46 | { |
37 | WcaLog(LOGMSG_STANDARD, "Search path not found: %ls", sczSearch); | 47 | WcaLog(LOGMSG_STANDARD, "Search path not found: %ls; skipping", sczSearch); |
38 | ExitFunction1(hr = S_FALSE); | 48 | ExitFunction1(hr = S_FALSE); |
39 | } | 49 | } |
40 | else | 50 | else |
@@ -55,7 +65,8 @@ static HRESULT RecursePath( | |||
55 | hr = StrAllocFormatted(&sczNext, L"%s%s\\", wzPath, wfd.cFileName); | 65 | hr = StrAllocFormatted(&sczNext, L"%s%s\\", wzPath, wfd.cFileName); |
56 | ExitOnFailure(hr, "Failed to concat filename '%S' to string: %S", wfd.cFileName, wzPath); | 66 | ExitOnFailure(hr, "Failed to concat filename '%S' to string: %S", wfd.cFileName, wzPath); |
57 | 67 | ||
58 | hr = RecursePath(sczNext, wzId, wzComponent, wzProperty, iMode, pdwCounter, phTable, phColumns); | 68 | // Don't re-disable redirection; if it was necessary, we've already done it. |
69 | hr = RecursePath(sczNext, wzId, wzComponent, wzProperty, iMode, FALSE, pdwCounter, phTable, phColumns); | ||
59 | ExitOnFailure(hr, "Failed to recurse path: %S", sczNext); | 70 | ExitOnFailure(hr, "Failed to recurse path: %S", sczNext); |
60 | } while (::FindNextFileW(hFind, &wfd)); | 71 | } while (::FindNextFileW(hFind, &wfd)); |
61 | 72 | ||
@@ -81,10 +92,10 @@ static HRESULT RecursePath( | |||
81 | 92 | ||
82 | // Add the row to remove any files and another row to remove the folder. | 93 | // Add the row to remove any files and another row to remove the folder. |
83 | hr = WcaAddTempRecord(phTable, phColumns, L"RemoveFile", NULL, 1, 5, L"RfxFiles", wzComponent, L"*.*", sczProperty, iMode); | 94 | hr = WcaAddTempRecord(phTable, phColumns, L"RemoveFile", NULL, 1, 5, L"RfxFiles", wzComponent, L"*.*", sczProperty, iMode); |
84 | ExitOnFailure(hr, "Failed to add row to remove all files for Wix4RemoveFolderEx row: %S under path:", wzId, wzPath); | 95 | ExitOnFailure(hr, "Failed to add row to remove all files for Wix4RemoveFolderEx row: %ls under path: %ls", wzId, wzPath); |
85 | 96 | ||
86 | hr = WcaAddTempRecord(phTable, phColumns, L"RemoveFile", NULL, 1, 5, L"RfxFolder", wzComponent, NULL, sczProperty, iMode); | 97 | hr = WcaAddTempRecord(phTable, phColumns, L"RemoveFile", NULL, 1, 5, L"RfxFolder", wzComponent, NULL, sczProperty, iMode); |
87 | ExitOnFailure(hr, "Failed to add row to remove folder for Wix4RemoveFolderEx row: %S under path: %S", wzId, wzPath); | 98 | ExitOnFailure(hr, "Failed to add row to remove folder for Wix4RemoveFolderEx row: %ls under path: %ls", wzId, wzPath); |
88 | 99 | ||
89 | LExit: | 100 | LExit: |
90 | if (INVALID_HANDLE_VALUE != hFind) | 101 | if (INVALID_HANDLE_VALUE != hFind) |
@@ -92,6 +103,11 @@ LExit: | |||
92 | ::FindClose(hFind); | 103 | ::FindClose(hFind); |
93 | } | 104 | } |
94 | 105 | ||
106 | if (fDisableWow64Redirection) | ||
107 | { | ||
108 | WcaRevertWow64FSRedirection(); | ||
109 | } | ||
110 | |||
95 | ReleaseStr(sczNext); | 111 | ReleaseStr(sczNext); |
96 | ReleaseStr(sczProperty); | 112 | ReleaseStr(sczProperty); |
97 | ReleaseStr(sczSearch); | 113 | ReleaseStr(sczSearch); |
@@ -110,9 +126,12 @@ extern "C" UINT WINAPI WixRemoveFoldersEx( | |||
110 | LPWSTR sczId = NULL; | 126 | LPWSTR sczId = NULL; |
111 | LPWSTR sczComponent = NULL; | 127 | LPWSTR sczComponent = NULL; |
112 | LPWSTR sczProperty = NULL; | 128 | LPWSTR sczProperty = NULL; |
129 | LPWSTR sczCondition = NULL; | ||
113 | LPWSTR sczPath = NULL; | 130 | LPWSTR sczPath = NULL; |
114 | LPWSTR sczExpandedPath = NULL; | 131 | LPWSTR sczExpandedPath = NULL; |
115 | int iMode = 0; | 132 | int iMode = 0; |
133 | int iComponentAttributes; | ||
134 | BOOL f64BitComponent = FALSE; | ||
116 | DWORD dwCounter = 0; | 135 | DWORD dwCounter = 0; |
117 | DWORD_PTR cchLen = 0; | 136 | DWORD_PTR cchLen = 0; |
118 | MSIHANDLE hTable = NULL; | 137 | MSIHANDLE hTable = NULL; |
@@ -121,6 +140,8 @@ extern "C" UINT WINAPI WixRemoveFoldersEx( | |||
121 | hr = WcaInitialize(hInstall, "WixRemoveFoldersEx"); | 140 | hr = WcaInitialize(hInstall, "WixRemoveFoldersEx"); |
122 | ExitOnFailure(hr, "Failed to initialize WixRemoveFoldersEx."); | 141 | ExitOnFailure(hr, "Failed to initialize WixRemoveFoldersEx."); |
123 | 142 | ||
143 | WcaInitializeWow64(); | ||
144 | |||
124 | // anything to do? | 145 | // anything to do? |
125 | if (S_OK != WcaTableExists(L"Wix4RemoveFolderEx")) | 146 | if (S_OK != WcaTableExists(L"Wix4RemoveFolderEx")) |
126 | { | 147 | { |
@@ -137,18 +158,40 @@ extern "C" UINT WINAPI WixRemoveFoldersEx( | |||
137 | hr = WcaGetRecordString(hRec, rfqId, &sczId); | 158 | hr = WcaGetRecordString(hRec, rfqId, &sczId); |
138 | ExitOnFailure(hr, "Failed to get remove folder identity."); | 159 | ExitOnFailure(hr, "Failed to get remove folder identity."); |
139 | 160 | ||
161 | hr = WcaGetRecordString(hRec, rfqCondition, &sczCondition); | ||
162 | ExitOnFailure(hr, "Failed to get remove folder condition."); | ||
163 | |||
164 | if (sczCondition && *sczCondition) | ||
165 | { | ||
166 | MSICONDITION condition = ::MsiEvaluateConditionW(hInstall, sczCondition); | ||
167 | if (MSICONDITION_TRUE == condition) | ||
168 | { | ||
169 | WcaLog(LOGMSG_STANDARD, "True condition for row %S: %S; processing.", sczId, sczCondition); | ||
170 | } | ||
171 | else | ||
172 | { | ||
173 | WcaLog(LOGMSG_STANDARD, "False or invalid condition for row %S: %S; skipping.", sczId, sczCondition); | ||
174 | continue; | ||
175 | } | ||
176 | } | ||
177 | |||
140 | hr = WcaGetRecordString(hRec, rfqComponent, &sczComponent); | 178 | hr = WcaGetRecordString(hRec, rfqComponent, &sczComponent); |
141 | ExitOnFailure(hr, "Failed to get remove folder component."); | 179 | ExitOnFailure(hr, "Failed to get remove folder component."); |
142 | 180 | ||
143 | hr = WcaGetRecordString(hRec, rfqProperty, &sczProperty); | 181 | hr = WcaGetRecordString(hRec, rfqProperty, &sczProperty); |
144 | ExitOnFailure(hr, "Failed to get remove folder property."); | 182 | ExitOnFailure(hr, "Failed to get remove folder property."); |
145 | 183 | ||
146 | hr = WcaGetRecordInteger(hRec, feqMode, &iMode); | 184 | hr = WcaGetRecordInteger(hRec, rfqMode, &iMode); |
147 | ExitOnFailure(hr, "Failed to get remove folder mode"); | 185 | ExitOnFailure(hr, "Failed to get remove folder mode"); |
148 | 186 | ||
149 | hr = WcaGetProperty(sczProperty, &sczPath); | 187 | hr = WcaGetProperty(sczProperty, &sczPath); |
150 | ExitOnFailure(hr, "Failed to resolve remove folder property: %S for row: %S", sczProperty, sczId); | 188 | ExitOnFailure(hr, "Failed to resolve remove folder property: %S for row: %S", sczProperty, sczId); |
151 | 189 | ||
190 | hr = WcaGetRecordInteger(hRec, rfqComponentAttributes, &iComponentAttributes); | ||
191 | ExitOnFailure(hr, "failed to get component attributes for row: %ls", sczId); | ||
192 | |||
193 | f64BitComponent = iComponentAttributes & msidbComponentAttributes64bit; | ||
194 | |||
152 | // fail early if the property isn't set as you probably don't want your installers trying to delete SystemFolder | 195 | // fail early if the property isn't set as you probably don't want your installers trying to delete SystemFolder |
153 | // StringCchLengthW succeeds only if the string is zero characters plus 1 for the terminating null | 196 | // StringCchLengthW succeeds only if the string is zero characters plus 1 for the terminating null |
154 | hr = ::StringCchLengthW(sczPath, 1, reinterpret_cast<UINT_PTR*>(&cchLen)); | 197 | hr = ::StringCchLengthW(sczPath, 1, reinterpret_cast<UINT_PTR*>(&cchLen)); |
@@ -164,7 +207,7 @@ extern "C" UINT WINAPI WixRemoveFoldersEx( | |||
164 | ExitOnFailure(hr, "Failed to backslash-terminate path: %S", sczExpandedPath); | 207 | ExitOnFailure(hr, "Failed to backslash-terminate path: %S", sczExpandedPath); |
165 | 208 | ||
166 | WcaLog(LOGMSG_STANDARD, "Recursing path: %S for row: %S.", sczExpandedPath, sczId); | 209 | WcaLog(LOGMSG_STANDARD, "Recursing path: %S for row: %S.", sczExpandedPath, sczId); |
167 | hr = RecursePath(sczExpandedPath, sczId, sczComponent, sczProperty, iMode, &dwCounter, &hTable, &hColumns); | 210 | hr = RecursePath(sczExpandedPath, sczId, sczComponent, sczProperty, iMode, f64BitComponent, &dwCounter, &hTable, &hColumns); |
168 | ExitOnFailure(hr, "Failed while navigating path: %S for row: %S", sczPath, sczId); | 211 | ExitOnFailure(hr, "Failed while navigating path: %S for row: %S", sczPath, sczId); |
169 | } | 212 | } |
170 | 213 | ||
@@ -176,6 +219,8 @@ extern "C" UINT WINAPI WixRemoveFoldersEx( | |||
176 | ExitOnFailure(hr, "Failure occured while processing Wix4RemoveFolderEx table"); | 219 | ExitOnFailure(hr, "Failure occured while processing Wix4RemoveFolderEx table"); |
177 | 220 | ||
178 | LExit: | 221 | LExit: |
222 | WcaFinalizeWow64(); | ||
223 | |||
179 | if (hColumns) | 224 | if (hColumns) |
180 | { | 225 | { |
181 | ::MsiCloseHandle(hColumns); | 226 | ::MsiCloseHandle(hColumns); |
@@ -190,6 +235,7 @@ LExit: | |||
190 | ReleaseStr(sczPath); | 235 | ReleaseStr(sczPath); |
191 | ReleaseStr(sczProperty); | 236 | ReleaseStr(sczProperty); |
192 | ReleaseStr(sczComponent); | 237 | ReleaseStr(sczComponent); |
238 | ReleaseStr(sczCondition); | ||
193 | ReleaseStr(sczId); | 239 | ReleaseStr(sczId); |
194 | 240 | ||
195 | DWORD er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; | 241 | DWORD er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; |