diff options
Diffstat (limited to 'src/ext/ComPlus/ca/cpapprolesched.cpp')
-rw-r--r-- | src/ext/ComPlus/ca/cpapprolesched.cpp | 843 |
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 | |||
8 | LPCWSTR vcsApplicationRoleQuery = | ||
9 | L"SELECT `ApplicationRole`, `Application_`, `Component_`, `Name` FROM `ComPlusApplicationRole`"; | ||
10 | enum eApplicationRoleQuery { arqApplicationRole = 1, arqApplication, arqComponent, arqName }; | ||
11 | |||
12 | LPCWSTR vcsUserInApplicationRoleQuery = | ||
13 | L"SELECT `UserInApplicationRole`, `ApplicationRole_`, `ComPlusUserInApplicationRole`.`Component_`, `Domain`, `Name` FROM `ComPlusUserInApplicationRole`, `User` WHERE `User_` = `User`"; | ||
14 | LPCWSTR vcsGroupInApplicationRoleQuery = | ||
15 | L"SELECT `GroupInApplicationRole`, `ApplicationRole_`, `ComPlusGroupInApplicationRole`.`Component_`, `Domain`, `Name` FROM `ComPlusGroupInApplicationRole`, `Group` WHERE `Group_` = `Group`"; | ||
16 | enum eTrusteeInApplicationRoleQuery { tiarqUserInApplicationRole = 1, tiarqApplicationRole, tiarqComponent, tiarqDomain, tiarqName }; | ||
17 | |||
18 | LPCWSTR vcsApplicationRolePropertyQuery = | ||
19 | L"SELECT `Name`, `Value` FROM `ComPlusApplicationRoleProperty` WHERE `ApplicationRole_` = ?"; | ||
20 | |||
21 | |||
22 | // property definitions | ||
23 | |||
24 | CPI_PROPERTY_DEFINITION pdlApplicationRoleProperties[] = | ||
25 | { | ||
26 | {L"Description", cpptString, 500}, | ||
27 | {NULL, cpptNone, 0} | ||
28 | }; | ||
29 | |||
30 | |||
31 | // prototypes for private helper functions | ||
32 | |||
33 | static HRESULT TrusteesInApplicationRolesRead( | ||
34 | LPCWSTR pwzQuery, | ||
35 | CPI_APPLICATION_ROLE_LIST* pAppRoleList, | ||
36 | CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList | ||
37 | ); | ||
38 | static void FreeApplicationRole( | ||
39 | CPI_APPLICATION_ROLE* pItm | ||
40 | ); | ||
41 | static void FreeUserInApplicationRole( | ||
42 | CPI_USER_IN_APPLICATION_ROLE* pItm | ||
43 | ); | ||
44 | //static HRESULT GetUsersCollForApplicationRole( | ||
45 | // CPI_APPLICATION_ROLE* pAppRole, | ||
46 | // ICatalogCollection** ppiUsersColl | ||
47 | // ); | ||
48 | static HRESULT FindObjectForApplicationRole( | ||
49 | CPI_APPLICATION_ROLE* pItm, | ||
50 | ICatalogObject** ppiRoleObj | ||
51 | ); | ||
52 | static HRESULT AddApplicationRoleToActionData( | ||
53 | CPI_APPLICATION_ROLE* pItm, | ||
54 | int iActionType, | ||
55 | int iActionCost, | ||
56 | LPWSTR* ppwzActionData | ||
57 | ); | ||
58 | static 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 | |||
68 | void 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 | |||
82 | HRESULT 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 | |||
183 | LExit: | ||
184 | // clean up | ||
185 | if (pItm) | ||
186 | FreeApplicationRole(pItm); | ||
187 | |||
188 | ReleaseStr(pwzData); | ||
189 | |||
190 | return hr; | ||
191 | } | ||
192 | |||
193 | HRESULT 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 | |||
256 | LExit: | ||
257 | // clean up | ||
258 | ReleaseObject(piRoleObj); | ||
259 | |||
260 | return hr; | ||
261 | } | ||
262 | |||
263 | HRESULT 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 | |||
290 | LExit: | ||
291 | return hr; | ||
292 | } | ||
293 | |||
294 | void CpiApplicationRoleAddReferenceInstall( | ||
295 | CPI_APPLICATION_ROLE* pItm | ||
296 | ) | ||
297 | { | ||
298 | pItm->fReferencedForInstall = TRUE; | ||
299 | CpiApplicationAddReferenceInstall(pItm->pApplication); | ||
300 | } | ||
301 | |||
302 | void CpiApplicationRoleAddReferenceUninstall( | ||
303 | CPI_APPLICATION_ROLE* pItm | ||
304 | ) | ||
305 | { | ||
306 | pItm->fReferencedForUninstall = TRUE; | ||
307 | CpiApplicationAddReferenceUninstall(pItm->pApplication); | ||
308 | } | ||
309 | |||
310 | HRESULT 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 | |||
358 | LExit: | ||
359 | return hr; | ||
360 | } | ||
361 | |||
362 | HRESULT 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 | |||
405 | LExit: | ||
406 | return hr; | ||
407 | } | ||
408 | |||
409 | HRESULT 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 | |||
427 | void 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 | |||
441 | HRESULT 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 | |||
464 | LExit: | ||
465 | return hr; | ||
466 | } | ||
467 | |||
468 | HRESULT 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 | |||
516 | LExit: | ||
517 | return hr; | ||
518 | } | ||
519 | |||
520 | HRESULT 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 | |||
563 | LExit: | ||
564 | return hr; | ||
565 | } | ||
566 | |||
567 | |||
568 | // helper function definitions | ||
569 | |||
570 | static 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 | |||
663 | LExit: | ||
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 | |||
675 | static 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 | |||
687 | static 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 | |||
739 | static 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 | |||
761 | LExit: | ||
762 | // clean up | ||
763 | ReleaseObject(piRoleColl); | ||
764 | |||
765 | return hr; | ||
766 | } | ||
767 | |||
768 | static 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 | |||
803 | LExit: | ||
804 | return hr; | ||
805 | } | ||
806 | |||
807 | static 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 | |||
841 | LExit: | ||
842 | return hr; | ||
843 | } | ||