aboutsummaryrefslogtreecommitdiff
path: root/src/ext/ComPlus/ca/cpsubsexec.cpp
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-05-04 11:41:55 -0700
committerRob Mensching <rob@firegiant.com>2021-05-04 11:41:55 -0700
commit337124bed6a57b40fca11c5c2f5b554f570522a6 (patch)
tree06e8552b11852309a2275e4bd63ee61320061876 /src/ext/ComPlus/ca/cpsubsexec.cpp
parenteab57c2ddebc3dc8cebc22f5337f50062f415c0d (diff)
downloadwix-337124bed6a57b40fca11c5c2f5b554f570522a6.tar.gz
wix-337124bed6a57b40fca11c5c2f5b554f570522a6.tar.bz2
wix-337124bed6a57b40fca11c5c2f5b554f570522a6.zip
Move ComPlus.wixext into ext
Diffstat (limited to 'src/ext/ComPlus/ca/cpsubsexec.cpp')
-rw-r--r--src/ext/ComPlus/ca/cpsubsexec.cpp411
1 files changed, 411 insertions, 0 deletions
diff --git a/src/ext/ComPlus/ca/cpsubsexec.cpp b/src/ext/ComPlus/ca/cpsubsexec.cpp
new file mode 100644
index 00000000..bbcf9853
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpsubsexec.cpp
@@ -0,0 +1,411 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5
6// private structs
7
8struct CPI_SUBSCRIPTION_ATTRIBUTES
9{
10 int iActionType;
11 int iActionCost;
12 LPWSTR pwzKey;
13 LPWSTR pwzID;
14 LPWSTR pwzName;
15 LPWSTR pwzEventCLSID;
16 LPWSTR pwzPublisherID;
17 LPWSTR pwzCompCLSID;
18 LPWSTR pwzAppID;
19 LPWSTR pwzPartID;
20 CPI_PROPERTY* pPropList;
21};
22
23
24// prototypes for private helper functions
25
26static HRESULT ReadSubscriptionAttributes(
27 LPWSTR* ppwzData,
28 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
29 );
30static void FreeSubscriptionAttributes(
31 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
32 );
33static HRESULT CreateSubscription(
34 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
35 );
36static HRESULT RemoveSubscription(
37 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
38 );
39
40
41// function definitions
42
43HRESULT CpiConfigureSubscriptions(
44 LPWSTR* ppwzData,
45 HANDLE hRollbackFile
46 )
47{
48 HRESULT hr = S_OK;
49
50 CPI_SUBSCRIPTION_ATTRIBUTES attrs;
51 ::ZeroMemory(&attrs, sizeof(attrs));
52
53 // read action text
54 hr = CpiActionStartMessage(ppwzData, FALSE);
55 ExitOnFailure(hr, "Failed to send action start message");
56
57 // ger count
58 int iCnt = 0;
59 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
60 ExitOnFailure(hr, "Failed to read count");
61
62 // write count to rollback file
63 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
64 ExitOnFailure(hr, "Failed to write count to rollback file");
65
66 for (int i = 0; i < iCnt; i++)
67 {
68 // read attributes from CustomActionData
69 hr = ReadSubscriptionAttributes(ppwzData, &attrs);
70 ExitOnFailure(hr, "Failed to read attributes");
71
72 // progress message
73 hr = CpiActionDataMessage(1, attrs.pwzName);
74 ExitOnFailure(hr, "Failed to send progress messages");
75
76 if (S_FALSE == hr)
77 ExitFunction();
78
79 // write key to rollback file
80 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
81 ExitOnFailure(hr, "Failed to write key to rollback file");
82
83 // action
84 switch (attrs.iActionType)
85 {
86 case atCreate:
87 hr = CreateSubscription(&attrs);
88 ExitOnFailure(hr, "Failed to create subscription, key: %S", attrs.pwzKey);
89 break;
90 case atRemove:
91 hr = RemoveSubscription(&attrs);
92 ExitOnFailure(hr, "Failed to remove subscription, key: %S", attrs.pwzKey);
93 break;
94 }
95
96 // write completion status to rollback file
97 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
98 ExitOnFailure(hr, "Failed to write completion status to rollback file");
99
100 // progress
101 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
102 ExitOnFailure(hr, "Failed to update progress");
103 }
104
105 hr = S_OK;
106
107LExit:
108 // clean up
109 FreeSubscriptionAttributes(&attrs);
110
111 return hr;
112}
113
114HRESULT CpiRollbackConfigureSubscriptions(
115 LPWSTR* ppwzData,
116 CPI_ROLLBACK_DATA* pRollbackDataList
117 )
118{
119 HRESULT hr = S_OK;
120
121 int iRollbackStatus;
122
123 CPI_SUBSCRIPTION_ATTRIBUTES attrs;
124 ::ZeroMemory(&attrs, sizeof(attrs));
125
126 // read action text
127 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
128 ExitOnFailure(hr, "Failed to send action start message");
129
130 // ger count
131 int iCnt = 0;
132 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
133 ExitOnFailure(hr, "Failed to read count");
134
135 for (int i = 0; i < iCnt; i++)
136 {
137 // read attributes from CustomActionData
138 hr = ReadSubscriptionAttributes(ppwzData, &attrs);
139 ExitOnFailure(hr, "Failed to read attributes");
140
141 // rollback status
142 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
143
144 if (S_FALSE == hr)
145 continue; // not found, nothing to rollback
146
147 // progress message
148 hr = CpiActionDataMessage(1, attrs.pwzName);
149 ExitOnFailure(hr, "Failed to send progress messages");
150
151 if (S_FALSE == hr)
152 ExitFunction();
153
154 // action
155 switch (attrs.iActionType)
156 {
157 case atCreate:
158 hr = CreateSubscription(&attrs);
159 if (FAILED(hr))
160 WcaLog(LOGMSG_STANDARD, "Failed to create subscription, hr: 0x%x, key: %S", hr, attrs.pwzKey);
161 break;
162 case atRemove:
163 hr = RemoveSubscription(&attrs);
164 if (FAILED(hr))
165 WcaLog(LOGMSG_STANDARD, "Failed to remove subscription, hr: 0x%x, key: %S", hr, attrs.pwzKey);
166 break;
167 }
168
169 // check rollback status
170 if (0 == iRollbackStatus)
171 continue; // operation did not complete, skip progress
172
173 // progress
174 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
175 ExitOnFailure(hr, "Failed to update progress");
176 }
177
178 hr = S_OK;
179
180LExit:
181 // clean up
182 FreeSubscriptionAttributes(&attrs);
183
184 return hr;
185}
186
187
188// helper function definitions
189
190static HRESULT ReadSubscriptionAttributes(
191 LPWSTR* ppwzData,
192 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
193 )
194{
195 HRESULT hr = S_OK;
196
197 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
198 ExitOnFailure(hr, "Failed to read action type");
199 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
200 ExitOnFailure(hr, "Failed to read action cost");
201 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
202 ExitOnFailure(hr, "Failed to read key");
203 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzID);
204 ExitOnFailure(hr, "Failed to read id");
205 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName);
206 ExitOnFailure(hr, "Failed to read name");
207 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzEventCLSID);
208 ExitOnFailure(hr, "Failed to read event clsid");
209 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPublisherID);
210 ExitOnFailure(hr, "Failed to read publisher id");
211 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzCompCLSID);
212 ExitOnFailure(hr, "Failed to read component clsid");
213 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAppID);
214 ExitOnFailure(hr, "Failed to read application id");
215 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
216 ExitOnFailure(hr, "Failed to read partition id");
217
218 hr = CpiReadPropertyList(ppwzData, &pAttrs->pPropList);
219 ExitOnFailure(hr, "Failed to read properties");
220
221 hr = S_OK;
222
223LExit:
224 return hr;
225}
226
227static void FreeSubscriptionAttributes(
228 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
229 )
230{
231 ReleaseStr(pAttrs->pwzKey);
232 ReleaseStr(pAttrs->pwzID);
233 ReleaseStr(pAttrs->pwzName);
234 ReleaseStr(pAttrs->pwzEventCLSID);
235 ReleaseStr(pAttrs->pwzPublisherID);
236 ReleaseStr(pAttrs->pwzCompCLSID);
237 ReleaseStr(pAttrs->pwzAppID);
238 ReleaseStr(pAttrs->pwzPartID);
239
240 if (pAttrs->pPropList)
241 CpiFreePropertyList(pAttrs->pPropList);
242}
243
244static HRESULT CreateSubscription(
245 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
246 )
247{
248 HRESULT hr = S_OK;
249 UINT er = ERROR_SUCCESS;
250
251 ICatalogCollection* piSubsColl = NULL;
252 ICatalogObject* piSubsObj = NULL;
253
254 PSID pSid = NULL;
255 long lChanges = 0;
256
257 // log
258 WcaLog(LOGMSG_VERBOSE, "Creating subscription, key: %S", pAttrs->pwzKey);
259
260 // get subscriptions collection
261 hr = CpiGetSubscriptionsCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzCompCLSID, &piSubsColl);
262 if (S_FALSE == hr)
263 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
264 ExitOnFailure(hr, "Failed to get subscriptions collection");
265
266 // check if subscription exists
267 hr = CpiFindCollectionObjectByStringKey(piSubsColl, pAttrs->pwzID, &piSubsObj);
268 ExitOnFailure(hr, "Failed to find subscription");
269
270 if (S_FALSE == hr)
271 {
272 // create subscription
273 hr = CpiAddCollectionObject(piSubsColl, &piSubsObj);
274 ExitOnFailure(hr, "Failed to add subscription to collection");
275
276 hr = CpiPutCollectionObjectValue(piSubsObj, L"ID", pAttrs->pwzID);
277 ExitOnFailure(hr, "Failed to set subscription id property");
278
279 hr = CpiPutCollectionObjectValue(piSubsObj, L"Name", pAttrs->pwzName);
280 ExitOnFailure(hr, "Failed to set subscription name property");
281
282 if (pAttrs->pwzEventCLSID && *pAttrs->pwzEventCLSID)
283 {
284 hr = CpiPutCollectionObjectValue(piSubsObj, L"EventCLSID", pAttrs->pwzEventCLSID);
285 ExitOnFailure(hr, "Failed to set role event clsid property");
286 }
287
288 if (pAttrs->pwzPublisherID && *pAttrs->pwzPublisherID)
289 {
290 hr = CpiPutCollectionObjectValue(piSubsObj, L"PublisherID", pAttrs->pwzPublisherID);
291 ExitOnFailure(hr, "Failed to set role publisher id property");
292 }
293 }
294
295 // properties
296 for (CPI_PROPERTY* pItm = pAttrs->pPropList; pItm; pItm = pItm->pNext)
297 {
298 // UserName property
299 if (0 == lstrcmpW(pItm->wzName, L"UserName"))
300 {
301 // get SID for account
302 do {
303 er = ERROR_SUCCESS;
304 hr = CpiAccountNameToSid(pItm->pwzValue, &pSid);
305 if (!::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
306 {
307 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr)
308 {
309 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pItm->pwzValue);
310 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
311 switch (er)
312 {
313 case IDABORT:
314 ExitFunction(); // exit with error code from CpiAccountNameToSid()
315 case IDRETRY:
316 break;
317 case IDIGNORE:
318 default:
319 hr = S_FALSE;
320 }
321 }
322 else
323 ExitOnFailure(hr, "Failed to get SID for account, account: '%S'", pItm->pwzValue);
324 }
325 else if (FAILED(hr))
326 {
327 WcaLog(LOGMSG_STANDARD, "Failed to get SID for account, hr: 0x%x, account: '%S'", hr, pItm->pwzValue);
328 hr = S_FALSE;
329 }
330 } while (IDRETRY == er);
331
332 if (S_FALSE == hr)
333 continue;
334
335 // convert SID back to account name
336 hr = CpiSidToAccountName(pSid, &pItm->pwzValue);
337 ExitOnFailure(hr, "Failed to convert SID to account name");
338 }
339
340 // set property
341 hr = CpiPutCollectionObjectValue(piSubsObj, pItm->wzName, pItm->pwzValue);
342 ExitOnFailure(hr, "Failed to set object property value, name: %S", pItm->wzName);
343 }
344
345 // save changes
346 hr = piSubsColl->SaveChanges(&lChanges);
347 if (COMADMIN_E_OBJECTERRORS == hr)
348 CpiLogCatalogErrorInfo();
349 ExitOnFailure(hr, "Failed to save changes");
350
351 // log
352 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
353
354 hr = S_OK;
355
356LExit:
357 // clean up
358 ReleaseObject(piSubsColl);
359 ReleaseObject(piSubsObj);
360
361 if (pSid)
362 ::HeapFree(::GetProcessHeap(), 0, pSid);
363
364 return hr;
365}
366
367static HRESULT RemoveSubscription(
368 CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
369 )
370{
371 HRESULT hr = S_OK;
372
373 ICatalogCollection* piSubsColl = NULL;
374
375 long lChanges = 0;
376
377 // log
378 WcaLog(LOGMSG_VERBOSE, "Removing subscription, key: %S", pAttrs->pwzKey);
379
380 // get subscriptions collection
381 hr = CpiGetSubscriptionsCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzCompCLSID, &piSubsColl);
382 ExitOnFailure(hr, "Failed to get subscriptions collection");
383
384 if (S_FALSE == hr)
385 {
386 // subscription not found
387 WcaLog(LOGMSG_VERBOSE, "Unable to retrieve subscriptions collection, nothing to delete, key: %S", pAttrs->pwzKey);
388 ExitFunction1(hr = S_OK);
389 }
390
391 // remove
392 hr = CpiRemoveCollectionObject(piSubsColl, pAttrs->pwzID, NULL, FALSE);
393 ExitOnFailure(hr, "Failed to remove subscriptions");
394
395 // save changes
396 hr = piSubsColl->SaveChanges(&lChanges);
397 if (COMADMIN_E_OBJECTERRORS == hr)
398 CpiLogCatalogErrorInfo();
399 ExitOnFailure(hr, "Failed to save changes");
400
401 // log
402 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
403
404 hr = S_OK;
405
406LExit:
407 // clean up
408 ReleaseObject(piSubsColl);
409
410 return hr;
411}