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/RemoveFoldersEx.cpp | |
| parent | aea4e48d8408689c5749d154dddcfb99ddfb257b (diff) | |
| download | wix-13c4becf524dbd12b92f099320726aa0b59f3bbc.tar.gz wix-13c4becf524dbd12b92f099320726aa0b59f3bbc.tar.bz2 wix-13c4becf524dbd12b92f099320726aa0b59f3bbc.zip | |
Add Condition to RemoveFoldersEx
Diffstat (limited to 'src/ca/RemoveFoldersEx.cpp')
| -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; |
