aboutsummaryrefslogtreecommitdiff
path: root/src/ext/ComPlus/ca/cppartexec.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/cppartexec.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/cppartexec.cpp')
-rw-r--r--src/ext/ComPlus/ca/cppartexec.cpp690
1 files changed, 690 insertions, 0 deletions
diff --git a/src/ext/ComPlus/ca/cppartexec.cpp b/src/ext/ComPlus/ca/cppartexec.cpp
new file mode 100644
index 00000000..673bdaf9
--- /dev/null
+++ b/src/ext/ComPlus/ca/cppartexec.cpp
@@ -0,0 +1,690 @@
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_PARTITION_ATTRIBUTES
9{
10 int iActionType;
11 int iActionCost;
12 LPWSTR pwzKey;
13 LPWSTR pwzID;
14 LPWSTR pwzName;
15 CPI_PROPERTY* pPropList;
16};
17
18struct CPI_PARTITION_USER_ATTRIBUTES
19{
20 int iActionType;
21 int iActionCost;
22 LPWSTR pwzKey;
23 LPWSTR pwzAccount;
24 LPWSTR pwzPartID;
25};
26
27
28// prototypes for private helper functions
29
30static HRESULT ReadPartitionAttributes(
31 LPWSTR* ppwzData,
32 CPI_PARTITION_ATTRIBUTES* pAttrs
33 );
34static void FreePartitionAttributes(
35 CPI_PARTITION_ATTRIBUTES* pAttrs
36 );
37static HRESULT CreatePartition(
38 CPI_PARTITION_ATTRIBUTES* pAttrs
39 );
40static HRESULT RemovePartition(
41 CPI_PARTITION_ATTRIBUTES* pAttrs
42 );
43static HRESULT ReadPartitionUserAttributes(
44 LPWSTR* ppwzData,
45 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
46 );
47static void FreePartitionUserAttributes(
48 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
49 );
50static HRESULT CreatePartitionUser(
51 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
52 );
53static HRESULT RemovePartitionUser(
54 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
55 );
56
57
58// function definitions
59
60HRESULT CpiConfigurePartitions(
61 LPWSTR* ppwzData,
62 HANDLE hRollbackFile
63 )
64{
65 HRESULT hr = S_OK;
66
67 CPI_PARTITION_ATTRIBUTES attrs;
68 ::ZeroMemory(&attrs, sizeof(attrs));
69
70 // read action text
71 hr = CpiActionStartMessage(ppwzData, FALSE);
72 ExitOnFailure(hr, "Failed to send action start message");
73
74 // ger partition count
75 int iCnt = 0;
76 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
77 ExitOnFailure(hr, "Failed to read count");
78
79 // write count to rollback file
80 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
81 ExitOnFailure(hr, "Failed to write count to rollback file");
82
83 for (int i = 0; i < iCnt; i++)
84 {
85 // read partition attributes from CustomActionData
86 hr = ReadPartitionAttributes(ppwzData, &attrs);
87 ExitOnFailure(hr, "Failed to read attributes");
88
89 // progress message
90 hr = CpiActionDataMessage(1, attrs.pwzName);
91 ExitOnFailure(hr, "Failed to send progress messages");
92
93 if (S_FALSE == hr)
94 ExitFunction();
95
96 // write key to rollback file
97 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
98 ExitOnFailure(hr, "Failed to write key to rollback file");
99
100 // action
101 switch (attrs.iActionType)
102 {
103 case atCreate:
104 hr = CreatePartition(&attrs);
105 ExitOnFailure(hr, "Failed to create partition, key: %S", attrs.pwzKey);
106 break;
107 case atRemove:
108 hr = RemovePartition(&attrs);
109 ExitOnFailure(hr, "Failed to remove partition, key: %S", attrs.pwzKey);
110 break;
111 }
112
113 // write completion status to rollback file
114 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
115 ExitOnFailure(hr, "Failed to write completion status to rollback file");
116
117 // progress
118 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
119 ExitOnFailure(hr, "Failed to update progress");
120 }
121
122 hr = S_OK;
123
124LExit:
125 // clean up
126 FreePartitionAttributes(&attrs);
127
128 return hr;
129}
130
131HRESULT CpiRollbackConfigurePartitions(
132 LPWSTR* ppwzData,
133 CPI_ROLLBACK_DATA* pRollbackDataList
134 )
135{
136 HRESULT hr = S_OK;
137
138 int iRollbackStatus;
139
140 CPI_PARTITION_ATTRIBUTES attrs;
141 ::ZeroMemory(&attrs, sizeof(attrs));
142
143 // read action text
144 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
145 ExitOnFailure(hr, "Failed to send action start message");
146
147 // get count
148 int iCnt = 0;
149 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
150 ExitOnFailure(hr, "Failed to read count");
151
152 for (int i = 0; i < iCnt; i++)
153 {
154 // read partition attributes from CustomActionData
155 hr = ReadPartitionAttributes(ppwzData, &attrs);
156 ExitOnFailure(hr, "Failed to read attributes");
157
158 // rollback status
159 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
160
161 if (S_FALSE == hr)
162 continue; // not found, nothing to rollback
163
164 // progress message
165 hr = CpiActionDataMessage(1, attrs.pwzName);
166 ExitOnFailure(hr, "Failed to send progress messages");
167
168 if (S_FALSE == hr)
169 ExitFunction();
170
171 // action
172 switch (attrs.iActionType)
173 {
174 case atCreate:
175 hr = CreatePartition(&attrs);
176 if (FAILED(hr))
177 WcaLog(LOGMSG_STANDARD, "Failed to create partition, hr: 0x%x, key: %S", hr, attrs.pwzKey);
178 break;
179 case atRemove:
180 hr = RemovePartition(&attrs);
181 if (FAILED(hr))
182 WcaLog(LOGMSG_STANDARD, "Failed to remove partition, hr: 0x%x, key: %S", hr, attrs.pwzKey);
183 break;
184 }
185
186 // check rollback status
187 if (0 == iRollbackStatus)
188 continue; // operation did not complete, skip progress
189
190 // progress
191 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
192 ExitOnFailure(hr, "Failed to update progress");
193 }
194
195 hr = S_OK;
196
197LExit:
198 // clean up
199 FreePartitionAttributes(&attrs);
200
201 return hr;
202}
203
204HRESULT CpiConfigurePartitionUsers(
205 LPWSTR* ppwzData,
206 HANDLE hRollbackFile
207 )
208{
209 HRESULT hr = S_OK;
210
211 CPI_PARTITION_USER_ATTRIBUTES attrs;
212 ::ZeroMemory(&attrs, sizeof(attrs));
213
214 // read action text
215 hr = CpiActionStartMessage(ppwzData, FALSE);
216 ExitOnFailure(hr, "Failed to send action start message");
217
218 // ger partition count
219 int iCnt = 0;
220 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
221 ExitOnFailure(hr, "Failed to read count");
222
223 // write count to rollback file
224 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
225 ExitOnFailure(hr, "Failed to write count to rollback file");
226
227 for (int i = 0; i < iCnt; i++)
228 {
229 // read partition attributes from CustomActionData
230 hr = ReadPartitionUserAttributes(ppwzData, &attrs);
231 ExitOnFailure(hr, "Failed to read attributes");
232
233 // progress message
234 hr = CpiActionDataMessage(1, attrs.pwzAccount);
235 ExitOnFailure(hr, "Failed to send progress messages");
236
237 if (S_FALSE == hr)
238 ExitFunction();
239
240 // write key to rollback file
241 hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
242 ExitOnFailure(hr, "Failed to write key to rollback file");
243
244 // action
245 switch (attrs.iActionType)
246 {
247 case atCreate:
248 hr = CreatePartitionUser(&attrs);
249 ExitOnFailure(hr, "Failed to create partition user, key: %S", attrs.pwzKey);
250 break;
251 case atRemove:
252 hr = RemovePartitionUser(&attrs);
253 ExitOnFailure(hr, "Failed to remove partition user, key: %S", attrs.pwzKey);
254 break;
255 }
256
257 // write completion status to rollback file
258 hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
259 ExitOnFailure(hr, "Failed to write completion status to rollback file");
260
261 // progress
262 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
263 ExitOnFailure(hr, "Failed to update progress");
264 }
265
266 hr = S_OK;
267
268LExit:
269 // clean up
270 FreePartitionUserAttributes(&attrs);
271
272 return hr;
273}
274
275HRESULT CpiRollbackConfigurePartitionUsers(
276 LPWSTR* ppwzData,
277 CPI_ROLLBACK_DATA* pRollbackDataList
278 )
279{
280 HRESULT hr = S_OK;
281
282 int iRollbackStatus;
283
284 CPI_PARTITION_USER_ATTRIBUTES attrs;
285 ::ZeroMemory(&attrs, sizeof(attrs));
286
287 // read action text
288 hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
289 ExitOnFailure(hr, "Failed to send action start message");
290
291 // get count
292 int iCnt = 0;
293 hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
294 ExitOnFailure(hr, "Failed to read count");
295
296 for (int i = 0; i < iCnt; i++)
297 {
298 // read partition attributes from CustomActionData
299 hr = ReadPartitionUserAttributes(ppwzData, &attrs);
300 ExitOnFailure(hr, "Failed to read attributes");
301
302 // rollback status
303 hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
304
305 if (S_FALSE == hr)
306 continue; // not found, nothing to rollback
307
308 // progress message
309 hr = CpiActionDataMessage(1, attrs.pwzAccount);
310 ExitOnFailure(hr, "Failed to send progress messages");
311
312 if (S_FALSE == hr)
313 ExitFunction();
314
315 // action
316 switch (attrs.iActionType)
317 {
318 case atCreate:
319 hr = CreatePartitionUser(&attrs);
320 ExitOnFailure(hr, "Failed to create partition user, key: %S", attrs.pwzKey);
321 break;
322 case atRemove:
323 hr = RemovePartitionUser(&attrs);
324 ExitOnFailure(hr, "Failed to remove partition user, key: %S", attrs.pwzKey);
325 break;
326 }
327
328 // check rollback status
329 if (0 == iRollbackStatus)
330 continue; // operation did not complete, skip progress
331
332 // progress
333 hr = WcaProgressMessage(attrs.iActionCost, FALSE);
334 ExitOnFailure(hr, "Failed to update progress");
335 }
336
337 hr = S_OK;
338
339LExit:
340 // clean up
341 FreePartitionUserAttributes(&attrs);
342
343 return hr;
344}
345
346
347// helper function definitions
348
349static HRESULT ReadPartitionAttributes(
350 LPWSTR* ppwzData,
351 CPI_PARTITION_ATTRIBUTES* pAttrs
352 )
353{
354 HRESULT hr = S_OK;
355
356 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
357 ExitOnFailure(hr, "Failed to read action type");
358 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
359 ExitOnFailure(hr, "Failed to read action cost");
360 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
361 ExitOnFailure(hr, "Failed to read key");
362 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzID);
363 ExitOnFailure(hr, "Failed to read id");
364 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName);
365 ExitOnFailure(hr, "Failed to read name");
366 hr = CpiReadPropertyList(ppwzData, &pAttrs->pPropList);
367 ExitOnFailure(hr, "Failed to read properties");
368
369 hr = S_OK;
370
371LExit:
372 return hr;
373}
374
375static void FreePartitionAttributes(
376 CPI_PARTITION_ATTRIBUTES* pAttrs
377 )
378{
379 ReleaseStr(pAttrs->pwzKey);
380 ReleaseStr(pAttrs->pwzID);
381 ReleaseStr(pAttrs->pwzName);
382
383 if (pAttrs->pPropList)
384 CpiFreePropertyList(pAttrs->pPropList);
385}
386
387static HRESULT CreatePartition(
388 CPI_PARTITION_ATTRIBUTES* pAttrs
389 )
390{
391 HRESULT hr = S_OK;
392
393 ICatalogCollection* piPartColl = NULL;
394 ICatalogObject* piPartObj = NULL;
395
396 long lChanges = 0;
397
398 // log
399 WcaLog(LOGMSG_VERBOSE, "Creating partition, key: %S", pAttrs->pwzKey);
400
401 // get partitions collection
402 hr = CpiExecGetPartitionsCollection(&piPartColl);
403 ExitOnFailure(hr, "Failed to get partitions collection");
404
405 // check if partition exists
406 hr = CpiFindCollectionObjectByStringKey(piPartColl, pAttrs->pwzID, &piPartObj);
407 ExitOnFailure(hr, "Failed to find partition");
408
409 if (S_FALSE == hr)
410 {
411 // create partition
412 hr = CpiAddCollectionObject(piPartColl, &piPartObj);
413 ExitOnFailure(hr, "Failed to add partition to collection");
414
415 hr = CpiPutCollectionObjectValue(piPartObj, L"ID", pAttrs->pwzID);
416 ExitOnFailure(hr, "Failed to set partition id property");
417
418 hr = CpiPutCollectionObjectValue(piPartObj, L"Name", pAttrs->pwzName);
419 ExitOnFailure(hr, "Failed to set partition name property");
420 }
421
422 // properties
423 hr = CpiPutCollectionObjectValues(piPartObj, pAttrs->pPropList);
424 ExitOnFailure(hr, "Failed to write properties");
425
426 // save changes
427 hr = piPartColl->SaveChanges(&lChanges);
428 if (COMADMIN_E_OBJECTERRORS == hr)
429 CpiLogCatalogErrorInfo();
430 ExitOnFailure(hr, "Failed to save changes");
431
432 // log
433 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
434
435 hr = S_OK;
436
437LExit:
438 // clean up
439 ReleaseObject(piPartColl);
440 ReleaseObject(piPartObj);
441
442 return hr;
443}
444
445static HRESULT RemovePartition(
446 CPI_PARTITION_ATTRIBUTES* pAttrs
447 )
448{
449 HRESULT hr = S_OK;
450
451 ICatalogCollection* piPartColl = NULL;
452
453 long lChanges = 0;
454
455 // log
456 WcaLog(LOGMSG_VERBOSE, "Removing partition, key: %S", pAttrs->pwzKey);
457
458 // get partitions collection
459 hr = CpiExecGetPartitionsCollection(&piPartColl);
460 ExitOnFailure(hr, "Failed to get partitions collection");
461
462 // remove
463 hr = CpiRemoveCollectionObject(piPartColl, pAttrs->pwzID, NULL, TRUE);
464 ExitOnFailure(hr, "Failed to remove partition");
465
466 if (S_FALSE == hr)
467 {
468 // partition not found
469 WcaLog(LOGMSG_VERBOSE, "Partition not found, nothing to delete, key: %S", pAttrs->pwzKey);
470 ExitFunction1(hr = S_OK);
471 }
472
473 // save changes
474 hr = piPartColl->SaveChanges(&lChanges);
475 if (COMADMIN_E_OBJECTERRORS == hr)
476 CpiLogCatalogErrorInfo();
477 ExitOnFailure(hr, "Failed to save changes");
478
479 // log
480 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
481
482 hr = S_OK;
483
484LExit:
485 // clean up
486 ReleaseObject(piPartColl);
487
488 return hr;
489}
490
491static HRESULT ReadPartitionUserAttributes(
492 LPWSTR* ppwzData,
493 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
494 )
495{
496 HRESULT hr = S_OK;
497
498 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
499 ExitOnFailure(hr, "Failed to read action type");
500 hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
501 ExitOnFailure(hr, "Failed to read action cost");
502 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
503 ExitOnFailure(hr, "Failed to read key");
504 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAccount);
505 ExitOnFailure(hr, "Failed to read account name");
506 hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
507 ExitOnFailure(hr, "Failed to read partition id");
508
509 hr = S_OK;
510
511LExit:
512 return hr;
513}
514
515static void FreePartitionUserAttributes(
516 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
517 )
518{
519 ReleaseStr(pAttrs->pwzKey);
520 ReleaseStr(pAttrs->pwzAccount);
521 ReleaseStr(pAttrs->pwzPartID);
522}
523
524static HRESULT CreatePartitionUser(
525 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
526 )
527{
528 HRESULT hr = S_OK;
529 UINT er = ERROR_SUCCESS;
530
531 ICatalogCollection* piUserColl = NULL;
532 ICatalogObject* piUserObj = NULL;
533
534 PSID pSid = NULL;
535 long lChanges = 0;
536
537 // log
538 WcaLog(LOGMSG_VERBOSE, "Setting default partition for user, key: %S", pAttrs->pwzKey);
539
540 // get partition users collection
541 hr = CpiGetPartitionUsersCollection(&piUserColl);
542 ExitOnFailure(hr, "Failed to get partition users collection");
543
544 // get SID for account
545 do {
546 er = ERROR_SUCCESS;
547 hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
548 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
549 {
550 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
551 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
552 switch (er)
553 {
554 case IDABORT:
555 ExitFunction(); // exit with error code from CpiAccountNameToSid()
556 case IDRETRY:
557 break;
558 case IDIGNORE:
559 default:
560 ExitFunction1(hr = S_OK);
561 }
562 }
563 else
564 ExitOnFailure(hr, "Failed to get SID for account");
565 } while (IDRETRY == er);
566
567 // remove any existing entry
568 hr = CpiRemoveUserCollectionObject(piUserColl, pSid);
569 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
570 {
571 WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
572 hr = S_FALSE;
573 }
574 else
575 ExitOnFailure(hr, "Failed to remove user");
576
577 if (S_OK == hr)
578 WcaLog(LOGMSG_VERBOSE, "Existing default partition for user was removed, key: %S", pAttrs->pwzKey);
579
580 // add partition user
581 hr = CpiAddCollectionObject(piUserColl, &piUserObj);
582 ExitOnFailure(hr, "Failed to add partition to collection");
583
584 hr = CpiPutCollectionObjectValue(piUserObj, L"AccountName", pAttrs->pwzAccount);
585 ExitOnFailure(hr, "Failed to set account name property");
586
587 hr = CpiPutCollectionObjectValue(piUserObj, L"DefaultPartitionID", pAttrs->pwzPartID);
588 ExitOnFailure(hr, "Failed to set default partition id property");
589
590 // save changes
591 hr = piUserColl->SaveChanges(&lChanges);
592 if (COMADMIN_E_OBJECTERRORS == hr)
593 CpiLogCatalogErrorInfo();
594 ExitOnFailure(hr, "Failed to save changes");
595
596 // log
597 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
598
599 hr = S_OK;
600
601LExit:
602 // clean up
603 ReleaseObject(piUserColl);
604 ReleaseObject(piUserObj);
605
606 if (pSid)
607 ::HeapFree(::GetProcessHeap(), 0, pSid);
608
609 return hr;
610}
611
612static HRESULT RemovePartitionUser(
613 CPI_PARTITION_USER_ATTRIBUTES* pAttrs
614 )
615{
616 HRESULT hr = S_OK;
617 UINT er = ERROR_SUCCESS;
618
619 ICatalogCollection* piUserColl = NULL;
620
621 PSID pSid = NULL;
622 long lChanges = 0;
623
624 // log
625 WcaLog(LOGMSG_VERBOSE, "Removing default partition for user, key: %S", pAttrs->pwzKey);
626
627 // get partition users collection
628 hr = CpiGetPartitionUsersCollection(&piUserColl);
629 ExitOnFailure(hr, "Failed to get partition users collection");
630
631 // get SID for account
632 do {
633 er = ERROR_SUCCESS;
634 hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
635 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
636 {
637 WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
638 er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
639 switch (er)
640 {
641 case IDABORT:
642 ExitFunction(); // exit with error code from CpiAccountNameToSid()
643 case IDRETRY:
644 break;
645 case IDIGNORE:
646 default:
647 ExitFunction1(hr = S_OK);
648 }
649 }
650 else
651 ExitOnFailure(hr, "Failed to get SID for account");
652 } while (IDRETRY == er);
653
654 // remove
655 hr = CpiRemoveUserCollectionObject(piUserColl, pSid);
656 if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
657 {
658 WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
659 hr = S_FALSE;
660 }
661 else
662 ExitOnFailure(hr, "Failed to remove user");
663
664 if (S_FALSE == hr)
665 {
666 // user not found
667 WcaLog(LOGMSG_VERBOSE, "Default partition for user not found, nothing to delete, key: %S", pAttrs->pwzKey);
668 ExitFunction1(hr = S_OK);
669 }
670
671 // save changes
672 hr = piUserColl->SaveChanges(&lChanges);
673 if (COMADMIN_E_OBJECTERRORS == hr)
674 CpiLogCatalogErrorInfo();
675 ExitOnFailure(hr, "Failed to save changes");
676
677 // log
678 WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
679
680 hr = S_OK;
681
682LExit:
683 // clean up
684 ReleaseObject(piUserColl);
685
686 if (pSid)
687 ::HeapFree(::GetProcessHeap(), 0, pSid);
688
689 return hr;
690}