summaryrefslogtreecommitdiff
path: root/src/ext/ComPlus/ca/cpapprolesched.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/ComPlus/ca/cpapprolesched.cpp')
-rw-r--r--src/ext/ComPlus/ca/cpapprolesched.cpp843
1 files changed, 843 insertions, 0 deletions
diff --git a/src/ext/ComPlus/ca/cpapprolesched.cpp b/src/ext/ComPlus/ca/cpapprolesched.cpp
new file mode 100644
index 00000000..a268d156
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpapprolesched.cpp
@@ -0,0 +1,843 @@
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// sql queries
7
8LPCWSTR vcsApplicationRoleQuery =
9 L"SELECT `ApplicationRole`, `Application_`, `Component_`, `Name` FROM `ComPlusApplicationRole`";
10enum eApplicationRoleQuery { arqApplicationRole = 1, arqApplication, arqComponent, arqName };
11
12LPCWSTR vcsUserInApplicationRoleQuery =
13 L"SELECT `UserInApplicationRole`, `ApplicationRole_`, `ComPlusUserInApplicationRole`.`Component_`, `Domain`, `Name` FROM `ComPlusUserInApplicationRole`, `User` WHERE `User_` = `User`";
14LPCWSTR vcsGroupInApplicationRoleQuery =
15 L"SELECT `GroupInApplicationRole`, `ApplicationRole_`, `ComPlusGroupInApplicationRole`.`Component_`, `Domain`, `Name` FROM `ComPlusGroupInApplicationRole`, `Group` WHERE `Group_` = `Group`";
16enum eTrusteeInApplicationRoleQuery { tiarqUserInApplicationRole = 1, tiarqApplicationRole, tiarqComponent, tiarqDomain, tiarqName };
17
18LPCWSTR vcsApplicationRolePropertyQuery =
19 L"SELECT `Name`, `Value` FROM `ComPlusApplicationRoleProperty` WHERE `ApplicationRole_` = ?";
20
21
22// property definitions
23
24CPI_PROPERTY_DEFINITION pdlApplicationRoleProperties[] =
25{
26 {L"Description", cpptString, 500},
27 {NULL, cpptNone, 0}
28};
29
30
31// prototypes for private helper functions
32
33static HRESULT TrusteesInApplicationRolesRead(
34 LPCWSTR pwzQuery,
35 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
36 CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList
37 );
38static void FreeApplicationRole(
39 CPI_APPLICATION_ROLE* pItm
40 );
41static void FreeUserInApplicationRole(
42 CPI_USER_IN_APPLICATION_ROLE* pItm
43 );
44//static HRESULT GetUsersCollForApplicationRole(
45// CPI_APPLICATION_ROLE* pAppRole,
46// ICatalogCollection** ppiUsersColl
47// );
48static HRESULT FindObjectForApplicationRole(
49 CPI_APPLICATION_ROLE* pItm,
50 ICatalogObject** ppiRoleObj
51 );
52static HRESULT AddApplicationRoleToActionData(
53 CPI_APPLICATION_ROLE* pItm,
54 int iActionType,
55 int iActionCost,
56 LPWSTR* ppwzActionData
57 );
58static HRESULT AddUserInApplicationRoleToActionData(
59 CPI_USER_IN_APPLICATION_ROLE* pItm,
60 int iActionType,
61 int iActionCost,
62 LPWSTR* ppwzActionData
63 );
64
65
66// function definitions
67
68void CpiApplicationRoleListFree(
69 CPI_APPLICATION_ROLE_LIST* pList
70 )
71{
72 CPI_APPLICATION_ROLE* pItm = pList->pFirst;
73
74 while (pItm)
75 {
76 CPI_APPLICATION_ROLE* pDelete = pItm;
77 pItm = pItm->pNext;
78 FreeApplicationRole(pDelete);
79 }
80}
81
82HRESULT CpiApplicationRolesRead(
83 CPI_APPLICATION_LIST* pAppList,
84 CPI_APPLICATION_ROLE_LIST* pAppRoleList
85 )
86{
87 HRESULT hr = S_OK;
88 UINT er = ERROR_SUCCESS;
89
90 PMSIHANDLE hView, hRec;
91
92 CPI_APPLICATION_ROLE* pItm = NULL;
93 LPWSTR pwzData = NULL;
94 BOOL fMatchingArchitecture = FALSE;
95
96 // loop through all application roles
97 hr = WcaOpenExecuteView(vcsApplicationRoleQuery, &hView);
98 ExitOnFailure(hr, "Failed to execute view on ComPlusApplicationRole table");
99
100 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
101 {
102 // get component
103 hr = WcaGetRecordString(hRec, arqComponent, &pwzData);
104 ExitOnFailure(hr, "Failed to get component");
105
106 // check if the component is our processor architecture
107 if (pwzData && *pwzData)
108 {
109 hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
110 ExitOnFailure(hr, "Failed to get component architecture.");
111
112 if (!fMatchingArchitecture)
113 {
114 continue; // not the same architecture, ignore
115 }
116 }
117
118 // create entry
119 pItm = (CPI_APPLICATION_ROLE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_APPLICATION_ROLE));
120 if (!pItm)
121 ExitFunction1(hr = E_OUTOFMEMORY);
122
123 // get component install state
124 if (pwzData && *pwzData)
125 {
126 pItm->fHasComponent = TRUE;
127
128 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
129 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
130 }
131
132 // get key
133 hr = WcaGetRecordString(hRec, arqApplicationRole, &pwzData);
134 ExitOnFailure(hr, "Failed to get key");
135 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
136
137 // get application
138 hr = WcaGetRecordString(hRec, arqApplication, &pwzData);
139 ExitOnFailure(hr, "Failed to get application");
140
141 hr = CpiApplicationFindByKey(pAppList, pwzData, &pItm->pApplication);
142 if (S_FALSE == hr)
143 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
144 ExitOnFailure(hr, "Failed to find application, key: %S", pwzData);
145
146 // get name
147 hr = WcaGetRecordFormattedString(hRec, arqName, &pwzData);
148 ExitOnFailure(hr, "Failed to get name");
149 StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
150
151 // get properties
152 if (CpiTableExists(cptComPlusApplicationRoleProperty))
153 {
154 hr = CpiPropertiesRead(vcsApplicationRolePropertyQuery, pItm->wzKey, pdlApplicationRoleProperties, &pItm->pProperties, &pItm->iPropertyCount);
155 ExitOnFailure(hr, "Failed to get properties");
156 }
157
158 // set references & increment counters
159 if (pItm->fHasComponent)
160 {
161 if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
162 {
163 CpiApplicationAddReferenceInstall(pItm->pApplication);
164 pAppRoleList->iInstallCount++;
165 }
166 if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
167 {
168 CpiApplicationAddReferenceUninstall(pItm->pApplication);
169 pAppRoleList->iUninstallCount++;
170 }
171 }
172
173 // add entry
174 if (pAppRoleList->pFirst)
175 pItm->pNext = pAppRoleList->pFirst;
176 pAppRoleList->pFirst = pItm;
177 pItm = NULL;
178 }
179
180 if (E_NOMOREITEMS == hr)
181 hr = S_OK;
182
183LExit:
184 // clean up
185 if (pItm)
186 FreeApplicationRole(pItm);
187
188 ReleaseStr(pwzData);
189
190 return hr;
191}
192
193HRESULT CpiApplicationRolesVerifyInstall(
194 CPI_APPLICATION_ROLE_LIST* pList
195 )
196{
197 HRESULT hr = S_OK;
198 UINT er = ERROR_SUCCESS;
199
200 ICatalogObject* piRoleObj = NULL;
201
202 for (CPI_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
203 {
204 // referenced locaters or roles that are being installed
205 if (!pItm->fReferencedForInstall && !(pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction)))
206 continue;
207
208 // if the role is referensed and is not a locater, it must be installed
209 if (pItm->fReferencedForInstall && pItm->fHasComponent && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction))
210 MessageExitOnFailure(hr = E_FAIL, msierrComPlusApplicationRoleDependency, "An application role is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey);
211
212 // role is a locater
213 if (!pItm->fHasComponent)
214 {
215 // get collection object for role
216 hr = FindObjectForApplicationRole(pItm, &piRoleObj);
217 ExitOnFailure(hr, "Failed to find collection object for role");
218
219 // if the role was not found
220 if (S_FALSE == hr)
221 MessageExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), msierrComPlusApplicationRoleNotFound, "An application role required by this installation was not found, key: %S", pItm->wzKey);
222 }
223
224 // role is supposed to be created
225 else if (!CpiIsInstalled(pItm->isInstalled))
226 {
227 do {
228 // find roles with conflicting name or id
229 hr = FindObjectForApplicationRole(pItm, NULL);
230 ExitOnFailure(hr, "Failed to find collection object for role");
231
232 if (S_OK == hr)
233 {
234 er = WcaErrorMessage(msierrComPlusApplicationRoleConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
235 switch (er)
236 {
237 case IDABORT:
238 ExitOnFailure(hr = E_FAIL, "An application with a conflictiong name exists, key: %S", pItm->wzKey);
239 break;
240 case IDRETRY:
241 break;
242 case IDIGNORE:
243 default:
244 hr = S_FALSE; // indicate that this is not a conflict
245 }
246 }
247 } while (S_OK == hr); // hr = S_FALSE if we don't have any conflicts
248 }
249
250 // clean up
251 ReleaseNullObject(piRoleObj);
252 }
253
254 hr = S_OK;
255
256LExit:
257 // clean up
258 ReleaseObject(piRoleObj);
259
260 return hr;
261}
262
263HRESULT CpiApplicationRolesVerifyUninstall(
264 CPI_APPLICATION_ROLE_LIST* pList
265 )
266{
267 HRESULT hr = S_OK;
268
269 for (CPI_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
270 {
271 // referenced locaters or roles that are being installed
272 if (!pItm->fReferencedForUninstall && !(pItm->fHasComponent && WcaIsUninstalling(pItm->isInstalled, pItm->isAction)))
273 continue;
274
275 // get collection object for role
276 hr = FindObjectForApplicationRole(pItm, NULL);
277 ExitOnFailure(hr, "Failed to find collection object for role");
278
279 // if the role was not found
280 if (S_FALSE == hr)
281 {
282 pItm->fObjectNotFound = TRUE;
283 if (pItm->fHasComponent)
284 pList->iUninstallCount--; // elements with the fObjectNotFound flag set will not be scheduled for uninstall
285 }
286 }
287
288 hr = S_OK;
289
290LExit:
291 return hr;
292}
293
294void CpiApplicationRoleAddReferenceInstall(
295 CPI_APPLICATION_ROLE* pItm
296 )
297{
298 pItm->fReferencedForInstall = TRUE;
299 CpiApplicationAddReferenceInstall(pItm->pApplication);
300}
301
302void CpiApplicationRoleAddReferenceUninstall(
303 CPI_APPLICATION_ROLE* pItm
304 )
305{
306 pItm->fReferencedForUninstall = TRUE;
307 CpiApplicationAddReferenceUninstall(pItm->pApplication);
308}
309
310HRESULT CpiApplicationRolesInstall(
311 CPI_APPLICATION_ROLE_LIST* pList,
312 int iRunMode,
313 LPWSTR* ppwzActionData,
314 int* piProgress
315 )
316{
317 HRESULT hr = S_OK;
318
319 int iActionType;
320
321 // add action text
322 hr = CpiAddActionTextToActionData(L"CreateComPlusApplicationRoles", ppwzActionData);
323 ExitOnFailure(hr, "Failed to add action text to custom action data");
324
325 // add count to action data
326 hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData);
327 ExitOnFailure(hr, "Failed to add count to custom action data");
328
329 // add roles to custom action data
330 for (CPI_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
331 {
332 // roles that are being installed only
333 if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
334 continue;
335
336 // action type
337 if (rmRollback == iRunMode)
338 {
339 if (CpiIsInstalled(pItm->isInstalled))
340 iActionType = atNoOp;
341 else
342 iActionType = atRemove;
343 }
344 else
345 iActionType = atCreate;
346
347 // add to action data
348 hr = AddApplicationRoleToActionData(pItm, iActionType, COST_APPLICATION_ROLE_CREATE, ppwzActionData);
349 ExitOnFailure(hr, "Failed to add application role to custom action data, key: %S", pItm->wzKey);
350 }
351
352 // add progress tics
353 if (piProgress)
354 *piProgress += COST_APPLICATION_ROLE_CREATE * pList->iInstallCount;
355
356 hr = S_OK;
357
358LExit:
359 return hr;
360}
361
362HRESULT CpiApplicationRolesUninstall(
363 CPI_APPLICATION_ROLE_LIST* pList,
364 int iRunMode,
365 LPWSTR* ppwzActionData,
366 int* piProgress
367 )
368{
369 HRESULT hr = S_OK;
370
371 int iActionType;
372
373 // add action text
374 hr = CpiAddActionTextToActionData(L"RemoveComPlusApplicationRoles", ppwzActionData);
375 ExitOnFailure(hr, "Failed to add action text to custom action data");
376
377 // add count to action data
378 hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
379 ExitOnFailure(hr, "Failed to add count to custom action data");
380
381 // add roles to custom action data
382 for (CPI_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
383 {
384 // roles that are being uninstalled only
385 if (pItm->fObjectNotFound || !WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
386 continue;
387
388 // action type
389 if (rmRollback == iRunMode)
390 iActionType = atCreate;
391 else
392 iActionType = atRemove;
393
394 // add to action data
395 hr = AddApplicationRoleToActionData(pItm, iActionType, COST_APPLICATION_ROLE_DELETE, ppwzActionData);
396 ExitOnFailure(hr, "Failed to add application role to custom action data, key: %S", pItm->wzKey);
397 }
398
399 // add progress tics
400 if (piProgress)
401 *piProgress += COST_APPLICATION_ROLE_DELETE * pList->iUninstallCount;
402
403 hr = S_OK;
404
405LExit:
406 return hr;
407}
408
409HRESULT CpiApplicationRoleFindByKey(
410 CPI_APPLICATION_ROLE_LIST* pList,
411 LPCWSTR pwzKey,
412 CPI_APPLICATION_ROLE** ppAppRole
413 )
414{
415 for (CPI_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
416 {
417 if (0 == lstrcmpW(pItm->wzKey, pwzKey))
418 {
419 *ppAppRole = pItm;
420 return S_OK;
421 }
422 }
423
424 return S_FALSE;
425}
426
427void CpiUserInApplicationRoleListFree(
428 CPI_USER_IN_APPLICATION_ROLE_LIST* pList
429 )
430{
431 CPI_USER_IN_APPLICATION_ROLE* pItm = pList->pFirst;
432
433 while (pItm)
434 {
435 CPI_USER_IN_APPLICATION_ROLE* pDelete = pItm;
436 pItm = pItm->pNext;
437 FreeUserInApplicationRole(pDelete);
438 }
439}
440
441HRESULT CpiUsersInApplicationRolesRead(
442 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
443 CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList
444 )
445{
446 HRESULT hr = S_OK;
447
448 // read users in application roles
449 if (CpiTableExists(cptComPlusUserInApplicationRole))
450 {
451 hr = TrusteesInApplicationRolesRead(vcsUserInApplicationRoleQuery, pAppRoleList, pUsrInAppRoleList);
452 ExitOnFailure(hr, "Failed to read users in application roles");
453 }
454
455 // read groups in application roles
456 if (CpiTableExists(cptComPlusGroupInApplicationRole))
457 {
458 hr = TrusteesInApplicationRolesRead(vcsGroupInApplicationRoleQuery, pAppRoleList, pUsrInAppRoleList);
459 ExitOnFailure(hr, "Failed to read groups in application roles");
460 }
461
462 hr = S_OK;
463
464LExit:
465 return hr;
466}
467
468HRESULT CpiUsersInApplicationRolesInstall(
469 CPI_USER_IN_APPLICATION_ROLE_LIST* pList,
470 int iRunMode,
471 LPWSTR* ppwzActionData,
472 int* piProgress
473 )
474{
475 HRESULT hr = S_OK;
476
477 int iActionType;
478
479 // add action text
480 hr = CpiAddActionTextToActionData(L"AddUsersToComPlusApplicationRoles", ppwzActionData);
481 ExitOnFailure(hr, "Failed to add action text to custom action data");
482
483 // add count to action data
484 hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData);
485 ExitOnFailure(hr, "Failed to add count to custom action data");
486
487 // add roles to custom action data
488 for (CPI_USER_IN_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
489 {
490 // roles that are being installed only
491 if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
492 continue;
493
494 // action type
495 if (rmRollback == iRunMode)
496 {
497 if (CpiIsInstalled(pItm->isInstalled))
498 iActionType = atNoOp;
499 else
500 iActionType = atRemove;
501 }
502 else
503 iActionType = atCreate;
504
505 // add to action data
506 hr = AddUserInApplicationRoleToActionData(pItm, iActionType, COST_USER_IN_APPLICATION_ROLE_CREATE, ppwzActionData);
507 ExitOnFailure(hr, "Failed to add user in application role to custom action data, key: %S", pItm->wzKey);
508 }
509
510 // add progress tics
511 if (piProgress)
512 *piProgress += COST_USER_IN_APPLICATION_ROLE_CREATE * pList->iInstallCount;
513
514 hr = S_OK;
515
516LExit:
517 return hr;
518}
519
520HRESULT CpiUsersInApplicationRolesUninstall(
521 CPI_USER_IN_APPLICATION_ROLE_LIST* pList,
522 int iRunMode,
523 LPWSTR* ppwzActionData,
524 int* piProgress
525 )
526{
527 HRESULT hr = S_OK;
528
529 int iActionType;
530
531 // add action text
532 hr = CpiAddActionTextToActionData(L"RemoveUsersFromComPlusAppRoles", ppwzActionData);
533 ExitOnFailure(hr, "Failed to add action text to custom action data");
534
535 // add count to action data
536 hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
537 ExitOnFailure(hr, "Failed to add count to custom action data");
538
539 // add roles to custom action data
540 for (CPI_USER_IN_APPLICATION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
541 {
542 // roles that are being uninstalled only
543 if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
544 continue;
545
546 // action type
547 if (rmRollback == iRunMode)
548 iActionType = atCreate;
549 else
550 iActionType = atRemove;
551
552 // add to action data
553 hr = AddUserInApplicationRoleToActionData(pItm, iActionType, COST_USER_IN_APPLICATION_ROLE_DELETE, ppwzActionData);
554 ExitOnFailure(hr, "Failed to add user in application role to custom action data, key: %S", pItm->wzKey);
555 }
556
557 // add progress tics
558 if (piProgress)
559 *piProgress += COST_USER_IN_APPLICATION_ROLE_DELETE * pList->iUninstallCount;
560
561 hr = S_OK;
562
563LExit:
564 return hr;
565}
566
567
568// helper function definitions
569
570static HRESULT TrusteesInApplicationRolesRead(
571 LPCWSTR pwzQuery,
572 CPI_APPLICATION_ROLE_LIST* pAppRoleList,
573 CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList
574 )
575{
576 HRESULT hr = S_OK;
577 UINT er = ERROR_SUCCESS;
578
579 PMSIHANDLE hView, hRec;
580
581 CPI_USER_IN_APPLICATION_ROLE* pItm = NULL;
582 LPWSTR pwzData = NULL;
583 LPWSTR pwzDomain = NULL;
584 LPWSTR pwzName = NULL;
585 BOOL fMatchingArchitecture = FALSE;
586
587 // loop through all application roles
588 hr = WcaOpenExecuteView(pwzQuery, &hView);
589 ExitOnFailure(hr, "Failed to execute view on table");
590
591 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
592 {
593 // get component
594 hr = WcaGetRecordString(hRec, tiarqComponent, &pwzData);
595 ExitOnFailure(hr, "Failed to get component");
596
597 // check if the component is our processor architecture
598 hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
599 ExitOnFailure(hr, "Failed to get component architecture.");
600
601 if (!fMatchingArchitecture)
602 {
603 continue; // not the same architecture, ignore
604 }
605
606 // create entry
607 pItm = (CPI_USER_IN_APPLICATION_ROLE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_USER_IN_APPLICATION_ROLE));
608 if (!pItm)
609 ExitFunction1(hr = E_OUTOFMEMORY);
610
611 // get component install state
612 er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
613 ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
614
615 // get key
616 hr = WcaGetRecordString(hRec, tiarqUserInApplicationRole, &pwzData);
617 ExitOnFailure(hr, "Failed to get key");
618 StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
619
620 // get application role
621 hr = WcaGetRecordString(hRec, tiarqApplicationRole, &pwzData);
622 ExitOnFailure(hr, "Failed to get application role");
623
624 hr = CpiApplicationRoleFindByKey(pAppRoleList, pwzData, &pItm->pApplicationRole);
625 if (S_FALSE == hr)
626 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
627 ExitOnFailure(hr, "Failed to find application role, key: %S", pwzData);
628
629 // get user domain
630 hr = WcaGetRecordFormattedString(hRec, tiarqDomain, &pwzDomain);
631 ExitOnFailure(hr, "Failed to get domain");
632
633 // get user name
634 hr = WcaGetRecordFormattedString(hRec, tiarqName, &pwzName);
635 ExitOnFailure(hr, "Failed to get name");
636
637 // build account name
638 hr = CpiBuildAccountName(pwzDomain, pwzName, &pItm->pwzAccount);
639 ExitOnFailure(hr, "Failed to build account name");
640
641 // set references & increment counters
642 if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
643 {
644 CpiApplicationRoleAddReferenceInstall(pItm->pApplicationRole);
645 pUsrInAppRoleList->iInstallCount++;
646 }
647 if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
648 {
649 CpiApplicationRoleAddReferenceUninstall(pItm->pApplicationRole);
650 pUsrInAppRoleList->iUninstallCount++;
651 }
652
653 // add entry
654 if (pUsrInAppRoleList->pFirst)
655 pItm->pNext = pUsrInAppRoleList->pFirst;
656 pUsrInAppRoleList->pFirst = pItm;
657 pItm = NULL;
658 }
659
660 if (E_NOMOREITEMS == hr)
661 hr = S_OK;
662
663LExit:
664 // clean up
665 if (pItm)
666 FreeUserInApplicationRole(pItm);
667
668 ReleaseStr(pwzData);
669 ReleaseStr(pwzDomain);
670 ReleaseStr(pwzName);
671
672 return hr;
673}
674
675static void FreeApplicationRole(
676 CPI_APPLICATION_ROLE* pItm
677 )
678{
679 if (pItm->pProperties)
680 CpiPropertiesFreeList(pItm->pProperties);
681
682 ReleaseObject(pItm->piUsersColl);
683
684 ::HeapFree(::GetProcessHeap(), 0, pItm);
685}
686
687static void FreeUserInApplicationRole(
688 CPI_USER_IN_APPLICATION_ROLE* pItm
689 )
690{
691 ReleaseStr(pItm->pwzAccount);
692
693 ::HeapFree(::GetProcessHeap(), 0, pItm);
694}
695
696//static HRESULT GetUsersCollForApplicationRole(
697// CPI_APPLICATION_ROLE* pAppRole,
698// ICatalogCollection** ppiUsersColl
699// )
700//{
701// HRESULT hr = S_OK;
702//
703// ICatalogCollection* piRoleColl = NULL;
704// ICatalogObject* piRoleObj = NULL;
705//
706// // if a previous attempt to locate the collection object failed
707// if (pAppRole->fObjectNotFound)
708// ExitFunction1(hr = S_FALSE);
709//
710// // get applications collection
711// if (!pAppRole->piUsersColl)
712// {
713// // get collection object for role
714// hr = FindObjectForApplicationRole(pAppRole, &piRoleObj);
715// ExitOnFailure(hr, "Failed to find collection object for role");
716//
717// if (S_FALSE == hr)
718// ExitFunction(); // exit with hr = S_FALSE
719//
720// // get users collection
721// hr = CpiGetCatalogCollection(piRoleColl, piRoleObj, L"UsersInRole", &pAppRole->piUsersColl);
722// ExitOnFailure(hr, "Failed to get users in role collection");
723// }
724//
725// // return value
726// *ppiUsersColl = pAppRole->piUsersColl;
727// (*ppiUsersColl)->AddRef();
728//
729// hr = S_OK;
730//
731//LExit:
732// // clean up
733// ReleaseObject(piRoleColl);
734// ReleaseObject(piRoleObj);
735//
736// return hr;
737//}
738
739static HRESULT FindObjectForApplicationRole(
740 CPI_APPLICATION_ROLE* pItm,
741 ICatalogObject** ppiRoleObj
742 )
743{
744 HRESULT hr = S_OK;
745
746 ICatalogCollection* piRoleColl = NULL;
747
748 // get roles collection
749 hr = CpiGetRolesCollForApplication(pItm->pApplication, &piRoleColl);
750 ExitOnFailure(hr, "Failed to get collection");
751
752 if (S_FALSE == hr)
753 ExitFunction(); // exit with hr = S_FALSE
754
755 // find role object
756 hr = CpiFindCollectionObject(piRoleColl, NULL, pItm->wzName, ppiRoleObj);
757 ExitOnFailure(hr, "Failed to find object");
758
759 // exit with hr from CpiFindCollectionObject()
760
761LExit:
762 // clean up
763 ReleaseObject(piRoleColl);
764
765 return hr;
766}
767
768static HRESULT AddApplicationRoleToActionData(
769 CPI_APPLICATION_ROLE* pItm,
770 int iActionType,
771 int iActionCost,
772 LPWSTR* ppwzActionData
773 )
774{
775 HRESULT hr = S_OK;
776
777 // add action information to custom action data
778 hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
779 ExitOnFailure(hr, "Failed to add action type to custom action data");
780 hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
781 ExitOnFailure(hr, "Failed to add action cost to custom action data");
782
783 // add application role information to custom action data
784 hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
785 ExitOnFailure(hr, "Failed to add application role key to custom action data");
786 hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData);
787 ExitOnFailure(hr, "Failed to add application role name to custom action data");
788
789 // add application information to custom action data
790 hr = WcaWriteStringToCaData(pItm->pApplication->wzID, ppwzActionData);
791 ExitOnFailure(hr, "Failed to add application id to custom action data");
792
793 // add partition information to custom action data
794 hr = WcaWriteStringToCaData(pItm->pApplication->pPartition ? pItm->pApplication->pPartition->wzID : L"", ppwzActionData);
795 ExitOnFailure(hr, "Failed to add partition id to custom action data");
796
797 // add properties to custom action data
798 hr = CpiAddPropertiesToActionData(atCreate == iActionType ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
799 ExitOnFailure(hr, "Failed to add properties to custom action data");
800
801 hr = S_OK;
802
803LExit:
804 return hr;
805}
806
807static HRESULT AddUserInApplicationRoleToActionData(
808 CPI_USER_IN_APPLICATION_ROLE* pItm,
809 int iActionType,
810 int iActionCost,
811 LPWSTR* ppwzActionData
812 )
813{
814 HRESULT hr = S_OK;
815
816 // add action information to custom action data
817 hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
818 ExitOnFailure(hr, "Failed to add action type to custom action data");
819 hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
820 ExitOnFailure(hr, "Failed to add action cost to custom action data");
821
822 // add application role information to custom action data
823 hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
824 ExitOnFailure(hr, "Failed to add key to custom action data");
825 hr = WcaWriteStringToCaData(pItm->pApplicationRole->wzName, ppwzActionData);
826 ExitOnFailure(hr, "Failed to add role name to custom action data");
827 hr = WcaWriteStringToCaData(pItm->pwzAccount, ppwzActionData);
828 ExitOnFailure(hr, "Failed to add user account to custom action data");
829
830 // add application information to custom action data
831 CPI_APPLICATION* pApplication = pItm->pApplicationRole->pApplication;
832 hr = WcaWriteStringToCaData(pApplication->wzID, ppwzActionData);
833 ExitOnFailure(hr, "Failed to add application id to custom action data");
834
835 // add partition information to custom action data
836 hr = WcaWriteStringToCaData(pApplication->pPartition ? pApplication->pPartition->wzID : L"", ppwzActionData);
837 ExitOnFailure(hr, "Failed to add partition id to custom action data");
838
839 hr = S_OK;
840
841LExit:
842 return hr;
843}