aboutsummaryrefslogtreecommitdiff
path: root/src/ca
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-04-11 12:22:57 -0700
committerRob Mensching <rob@firegiant.com>2021-04-12 19:28:07 -0700
commit13c4becf524dbd12b92f099320726aa0b59f3bbc (patch)
tree28155ea32d18a3b1868c7743e4889a797456c26c /src/ca
parentaea4e48d8408689c5749d154dddcfb99ddfb257b (diff)
downloadwix-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.cpp62
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
5LPCWSTR vcsRemoveFolderExQuery = L"SELECT `Wix4RemoveFolderEx`, `Component_`, `Property`, `InstallMode` FROM `Wix4RemoveFolderEx`"; 5LPCWSTR vcsRemoveFolderExQuery =
6enum 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`";
9enum eRemoveFolderExQuery { rfqId = 1, rfqComponent, rfqProperty, rfqMode, rfqCondition, rfqComponentAttributes };
7 10
8static HRESULT RecursePath( 11static 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
89LExit: 100LExit:
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
178LExit: 221LExit:
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;