diff options
Diffstat (limited to 'src/ext/ComPlus/ca/cppartrolesched.cpp')
-rw-r--r-- | src/ext/ComPlus/ca/cppartrolesched.cpp | 421 |
1 files changed, 421 insertions, 0 deletions
diff --git a/src/ext/ComPlus/ca/cppartrolesched.cpp b/src/ext/ComPlus/ca/cppartrolesched.cpp new file mode 100644 index 00000000..a988f8e3 --- /dev/null +++ b/src/ext/ComPlus/ca/cppartrolesched.cpp | |||
@@ -0,0 +1,421 @@ | |||
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 vcsPartitionRoleQuery = | ||
9 | L"SELECT `PartitionRole`, `Partition_`, `Component_`, `Name` FROM `ComPlusPartitionRole`"; | ||
10 | enum ePartitionRoleQuery { prqPartitionRole = 1, prqPartition, prqComponent, prqName }; | ||
11 | |||
12 | LPCWSTR vcsUserInPartitionRoleQuery = | ||
13 | L"SELECT `UserInPartitionRole`, `PartitionRole_`, `ComPlusUserInPartitionRole`.`Component_`, `Domain`, `Name` FROM `ComPlusUserInPartitionRole`, `User` WHERE `User_` = `User`"; | ||
14 | LPCWSTR vcsGroupInPartitionRoleQuery = | ||
15 | L"SELECT `GroupInPartitionRole`, `PartitionRole_`, `ComPlusGroupInPartitionRole`.`Component_`, `Domain`, `Name` FROM `ComPlusGroupInPartitionRole`, `Group` WHERE `Group_` = `Group`"; | ||
16 | enum eTrusteeInPartitionRoleQuery { tiprqUserInPartitionRole = 1, tiprqPartitionRole, tiprqComponent, tiprqDomain, tiprqName }; | ||
17 | |||
18 | |||
19 | // prototypes for private helper functions | ||
20 | |||
21 | static HRESULT TrusteesInPartitionRolesRead( | ||
22 | LPCWSTR pwzQuery, | ||
23 | CPI_PARTITION_ROLE_LIST* pPartRoleList, | ||
24 | CPI_USER_IN_PARTITION_ROLE_LIST* pUsrInPartRoleList | ||
25 | ); | ||
26 | static void FreePartitionRole( | ||
27 | CPI_PARTITION_ROLE* pItm | ||
28 | ); | ||
29 | static void FreeUserInPartitionRole( | ||
30 | CPI_USER_IN_PARTITION_ROLE* pItm | ||
31 | ); | ||
32 | static HRESULT AddUserInPartitionRoleToActionData( | ||
33 | CPI_USER_IN_PARTITION_ROLE* pItm, | ||
34 | int iActionType, | ||
35 | int iActionCost, | ||
36 | LPWSTR* ppwzActionData | ||
37 | ); | ||
38 | |||
39 | |||
40 | // function definitions | ||
41 | |||
42 | void CpiPartitionRoleListFree( | ||
43 | CPI_PARTITION_ROLE_LIST* pList | ||
44 | ) | ||
45 | { | ||
46 | CPI_PARTITION_ROLE* pItm = pList->pFirst; | ||
47 | |||
48 | while (pItm) | ||
49 | { | ||
50 | CPI_PARTITION_ROLE* pDelete = pItm; | ||
51 | pItm = pItm->pNext; | ||
52 | FreePartitionRole(pDelete); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | HRESULT CpiPartitionRolesRead( | ||
57 | CPI_PARTITION_LIST* pPartList, | ||
58 | CPI_PARTITION_ROLE_LIST* pPartRoleList | ||
59 | ) | ||
60 | { | ||
61 | HRESULT hr = S_OK; | ||
62 | PMSIHANDLE hView, hRec; | ||
63 | CPI_PARTITION_ROLE* pItm = NULL; | ||
64 | LPWSTR pwzData = NULL; | ||
65 | |||
66 | // loop through all application roles | ||
67 | hr = WcaOpenExecuteView(vcsPartitionRoleQuery, &hView); | ||
68 | ExitOnFailure(hr, "Failed to execute view on ComPlusPartitionRole table"); | ||
69 | |||
70 | while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) | ||
71 | { | ||
72 | // create entry | ||
73 | pItm = (CPI_PARTITION_ROLE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PARTITION_ROLE)); | ||
74 | if (!pItm) | ||
75 | ExitFunction1(hr = E_OUTOFMEMORY); | ||
76 | |||
77 | // get key | ||
78 | hr = WcaGetRecordString(hRec, prqPartitionRole, &pwzData); | ||
79 | ExitOnFailure(hr, "Failed to get key"); | ||
80 | StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); | ||
81 | |||
82 | // get partition | ||
83 | hr = WcaGetRecordString(hRec, prqPartition, &pwzData); | ||
84 | ExitOnFailure(hr, "Failed to get application"); | ||
85 | |||
86 | hr = CpiPartitionFindByKey(pPartList, pwzData, &pItm->pPartition); | ||
87 | if (S_FALSE == hr) | ||
88 | hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); | ||
89 | ExitOnFailure(hr, "Failed to find partition, key: %S", pwzData); | ||
90 | |||
91 | // get name | ||
92 | hr = WcaGetRecordFormattedString(hRec, prqName, &pwzData); | ||
93 | ExitOnFailure(hr, "Failed to get name"); | ||
94 | StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData); | ||
95 | |||
96 | // add entry | ||
97 | if (pPartRoleList->pFirst) | ||
98 | pItm->pNext = pPartRoleList->pFirst; | ||
99 | pPartRoleList->pFirst = pItm; | ||
100 | pItm = NULL; | ||
101 | } | ||
102 | |||
103 | if (E_NOMOREITEMS == hr) | ||
104 | hr = S_OK; | ||
105 | |||
106 | LExit: | ||
107 | // clean up | ||
108 | if (pItm) | ||
109 | FreePartitionRole(pItm); | ||
110 | |||
111 | ReleaseStr(pwzData); | ||
112 | |||
113 | return hr; | ||
114 | } | ||
115 | |||
116 | HRESULT CpiPartitionRoleFindByKey( | ||
117 | CPI_PARTITION_ROLE_LIST* pList, | ||
118 | LPCWSTR pwzKey, | ||
119 | CPI_PARTITION_ROLE** ppPartRole | ||
120 | ) | ||
121 | { | ||
122 | for (CPI_PARTITION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) | ||
123 | { | ||
124 | if (0 == lstrcmpW(pItm->wzKey, pwzKey)) | ||
125 | { | ||
126 | *ppPartRole = pItm; | ||
127 | return S_OK; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | return E_FAIL; | ||
132 | } | ||
133 | |||
134 | void CpiUserInPartitionRoleListFree( | ||
135 | CPI_USER_IN_PARTITION_ROLE_LIST* pList | ||
136 | ) | ||
137 | { | ||
138 | CPI_USER_IN_PARTITION_ROLE* pItm = pList->pFirst; | ||
139 | |||
140 | while (pItm) | ||
141 | { | ||
142 | CPI_USER_IN_PARTITION_ROLE* pDelete = pItm; | ||
143 | pItm = pItm->pNext; | ||
144 | FreeUserInPartitionRole(pDelete); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | HRESULT CpiUsersInPartitionRolesRead( | ||
149 | CPI_PARTITION_ROLE_LIST* pPartRoleList, | ||
150 | CPI_USER_IN_PARTITION_ROLE_LIST* pUsrInPartRoleList | ||
151 | ) | ||
152 | { | ||
153 | HRESULT hr = S_OK; | ||
154 | |||
155 | // read users in partition roles | ||
156 | if (CpiTableExists(cptComPlusUserInPartitionRole)) | ||
157 | { | ||
158 | hr = TrusteesInPartitionRolesRead(vcsUserInPartitionRoleQuery, pPartRoleList, pUsrInPartRoleList); | ||
159 | ExitOnFailure(hr, "Failed to read users in partition roles"); | ||
160 | } | ||
161 | |||
162 | // read groups in partition roles | ||
163 | if (CpiTableExists(cptComPlusGroupInPartitionRole)) | ||
164 | { | ||
165 | hr = TrusteesInPartitionRolesRead(vcsGroupInPartitionRoleQuery, pPartRoleList, pUsrInPartRoleList); | ||
166 | ExitOnFailure(hr, "Failed to read groups in partition roles"); | ||
167 | } | ||
168 | |||
169 | hr = S_OK; | ||
170 | |||
171 | LExit: | ||
172 | return hr; | ||
173 | } | ||
174 | |||
175 | HRESULT CpiUsersInPartitionRolesInstall( | ||
176 | CPI_USER_IN_PARTITION_ROLE_LIST* pList, | ||
177 | int iRunMode, | ||
178 | LPWSTR* ppwzActionData, | ||
179 | int* piProgress | ||
180 | ) | ||
181 | { | ||
182 | HRESULT hr = S_OK; | ||
183 | |||
184 | int iActionType; | ||
185 | |||
186 | // add action text | ||
187 | hr = CpiAddActionTextToActionData(L"AddUsersToComPlusPartitionRoles", ppwzActionData); | ||
188 | ExitOnFailure(hr, "Failed to add action text to custom action data"); | ||
189 | |||
190 | // add count to action data | ||
191 | hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData); | ||
192 | ExitOnFailure(hr, "Failed to add count to custom action data"); | ||
193 | |||
194 | // add roles to custom action data | ||
195 | for (CPI_USER_IN_PARTITION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) | ||
196 | { | ||
197 | // roles that are being installed only | ||
198 | if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction)) | ||
199 | continue; | ||
200 | |||
201 | // action type | ||
202 | if (rmRollback == iRunMode) | ||
203 | { | ||
204 | if (CpiIsInstalled(pItm->isInstalled)) | ||
205 | iActionType = atNoOp; | ||
206 | else | ||
207 | iActionType = atRemove; | ||
208 | } | ||
209 | else | ||
210 | iActionType = atCreate; | ||
211 | |||
212 | // add to action data | ||
213 | hr = AddUserInPartitionRoleToActionData(pItm, iActionType, COST_USER_IN_APPLICATION_ROLE_CREATE, ppwzActionData); | ||
214 | ExitOnFailure(hr, "Failed to add user in partition role to custom action data, key: %S", pItm->wzKey); | ||
215 | } | ||
216 | |||
217 | // add progress tics | ||
218 | if (piProgress) | ||
219 | *piProgress += COST_USER_IN_APPLICATION_ROLE_CREATE * pList->iInstallCount; | ||
220 | |||
221 | hr = S_OK; | ||
222 | |||
223 | LExit: | ||
224 | return hr; | ||
225 | } | ||
226 | |||
227 | HRESULT CpiUsersInPartitionRolesUninstall( | ||
228 | CPI_USER_IN_PARTITION_ROLE_LIST* pList, | ||
229 | int iRunMode, | ||
230 | LPWSTR* ppwzActionData, | ||
231 | int* piProgress | ||
232 | ) | ||
233 | { | ||
234 | HRESULT hr = S_OK; | ||
235 | |||
236 | int iActionType; | ||
237 | |||
238 | // add action text | ||
239 | hr = CpiAddActionTextToActionData(L"RemoveUsersFromComPlusPartRoles", ppwzActionData); | ||
240 | ExitOnFailure(hr, "Failed to add action text to custom action data"); | ||
241 | |||
242 | // add count to action data | ||
243 | hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData); | ||
244 | ExitOnFailure(hr, "Failed to add count to custom action data"); | ||
245 | |||
246 | // add roles to custom action data | ||
247 | for (CPI_USER_IN_PARTITION_ROLE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) | ||
248 | { | ||
249 | // roles that are being uninstalled only | ||
250 | if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) | ||
251 | continue; | ||
252 | |||
253 | // action type | ||
254 | if (rmRollback == iRunMode) | ||
255 | iActionType = atCreate; | ||
256 | else | ||
257 | iActionType = atRemove; | ||
258 | |||
259 | // add to action data | ||
260 | hr = AddUserInPartitionRoleToActionData(pItm, iActionType, COST_USER_IN_APPLICATION_ROLE_DELETE, ppwzActionData); | ||
261 | ExitOnFailure(hr, "Failed to add user in partition role to custom action data, key: %S", pItm->wzKey); | ||
262 | } | ||
263 | |||
264 | // add progress tics | ||
265 | if (piProgress) | ||
266 | *piProgress += COST_USER_IN_APPLICATION_ROLE_DELETE * pList->iUninstallCount; | ||
267 | |||
268 | hr = S_OK; | ||
269 | |||
270 | LExit: | ||
271 | return hr; | ||
272 | } | ||
273 | |||
274 | |||
275 | // helper function definitions | ||
276 | |||
277 | static HRESULT TrusteesInPartitionRolesRead( | ||
278 | LPCWSTR pwzQuery, | ||
279 | CPI_PARTITION_ROLE_LIST* pPartRoleList, | ||
280 | CPI_USER_IN_PARTITION_ROLE_LIST* pUsrInPartRoleList | ||
281 | ) | ||
282 | { | ||
283 | HRESULT hr = S_OK; | ||
284 | UINT er = ERROR_SUCCESS; | ||
285 | |||
286 | PMSIHANDLE hView, hRec; | ||
287 | |||
288 | CPI_USER_IN_PARTITION_ROLE* pItm = NULL; | ||
289 | LPWSTR pwzData = NULL; | ||
290 | LPWSTR pwzDomain = NULL; | ||
291 | LPWSTR pwzName = NULL; | ||
292 | BOOL fMatchingArchitecture = FALSE; | ||
293 | |||
294 | // loop through all application roles | ||
295 | hr = WcaOpenExecuteView(pwzQuery, &hView); | ||
296 | ExitOnFailure(hr, "Failed to execute view on table"); | ||
297 | |||
298 | while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) | ||
299 | { | ||
300 | // get component | ||
301 | hr = WcaGetRecordString(hRec, tiprqComponent, &pwzData); | ||
302 | ExitOnFailure(hr, "Failed to get component"); | ||
303 | |||
304 | // check if the component is our processor architecture | ||
305 | hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture); | ||
306 | ExitOnFailure(hr, "Failed to get component architecture."); | ||
307 | |||
308 | if (!fMatchingArchitecture) | ||
309 | { | ||
310 | continue; // not the same architecture, ignore | ||
311 | } | ||
312 | |||
313 | // create entry | ||
314 | pItm = (CPI_USER_IN_PARTITION_ROLE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_USER_IN_PARTITION_ROLE)); | ||
315 | if (!pItm) | ||
316 | ExitFunction1(hr = E_OUTOFMEMORY); | ||
317 | |||
318 | // get component install state | ||
319 | er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); | ||
320 | ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); | ||
321 | |||
322 | // get key | ||
323 | hr = WcaGetRecordString(hRec, tiprqUserInPartitionRole, &pwzData); | ||
324 | ExitOnFailure(hr, "Failed to get key"); | ||
325 | StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); | ||
326 | |||
327 | // get partition role | ||
328 | hr = WcaGetRecordString(hRec, tiprqPartitionRole, &pwzData); | ||
329 | ExitOnFailure(hr, "Failed to get partition role"); | ||
330 | |||
331 | hr = CpiPartitionRoleFindByKey(pPartRoleList, pwzData, &pItm->pPartitionRole); | ||
332 | ExitOnFailure(hr, "Failed to find partition role, key: %S", pwzData); | ||
333 | |||
334 | // get user domain | ||
335 | hr = WcaGetRecordFormattedString(hRec, tiprqDomain, &pwzDomain); | ||
336 | ExitOnFailure(hr, "Failed to get domain"); | ||
337 | |||
338 | // get user name | ||
339 | hr = WcaGetRecordFormattedString(hRec, tiprqName, &pwzName); | ||
340 | ExitOnFailure(hr, "Failed to get name"); | ||
341 | |||
342 | // build account name | ||
343 | hr = CpiBuildAccountName(pwzDomain, pwzName, &pItm->pwzAccount); | ||
344 | ExitOnFailure(hr, "Failed to build account name"); | ||
345 | |||
346 | // increment counters | ||
347 | if (WcaIsInstalling(pItm->isInstalled, pItm->isAction)) | ||
348 | pUsrInPartRoleList->iInstallCount++; | ||
349 | if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) | ||
350 | pUsrInPartRoleList->iUninstallCount++; | ||
351 | |||
352 | // add entry | ||
353 | if (pUsrInPartRoleList->pFirst) | ||
354 | pItm->pNext = pUsrInPartRoleList->pFirst; | ||
355 | pUsrInPartRoleList->pFirst = pItm; | ||
356 | pItm = NULL; | ||
357 | } | ||
358 | |||
359 | if (E_NOMOREITEMS == hr) | ||
360 | hr = S_OK; | ||
361 | |||
362 | LExit: | ||
363 | // clean up | ||
364 | if (pItm) | ||
365 | FreeUserInPartitionRole(pItm); | ||
366 | |||
367 | ReleaseStr(pwzData); | ||
368 | ReleaseStr(pwzDomain); | ||
369 | ReleaseStr(pwzName); | ||
370 | |||
371 | return hr; | ||
372 | } | ||
373 | |||
374 | static void FreePartitionRole( | ||
375 | CPI_PARTITION_ROLE* pItm | ||
376 | ) | ||
377 | { | ||
378 | ::HeapFree(::GetProcessHeap(), 0, pItm); | ||
379 | } | ||
380 | |||
381 | static void FreeUserInPartitionRole( | ||
382 | CPI_USER_IN_PARTITION_ROLE* pItm | ||
383 | ) | ||
384 | { | ||
385 | ReleaseStr(pItm->pwzAccount); | ||
386 | |||
387 | ::HeapFree(::GetProcessHeap(), 0, pItm); | ||
388 | } | ||
389 | |||
390 | static HRESULT AddUserInPartitionRoleToActionData( | ||
391 | CPI_USER_IN_PARTITION_ROLE* pItm, | ||
392 | int iActionType, | ||
393 | int iActionCost, | ||
394 | LPWSTR* ppwzActionData | ||
395 | ) | ||
396 | { | ||
397 | HRESULT hr = S_OK; | ||
398 | |||
399 | // add action information to custom action data | ||
400 | hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData); | ||
401 | ExitOnFailure(hr, "Failed to add action type to custom action data"); | ||
402 | hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData); | ||
403 | ExitOnFailure(hr, "Failed to add action cost to custom action data"); | ||
404 | |||
405 | // add application role information to custom action data | ||
406 | hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData); | ||
407 | ExitOnFailure(hr, "Failed to add key to custom action data"); | ||
408 | hr = WcaWriteStringToCaData(pItm->pPartitionRole->wzName, ppwzActionData); | ||
409 | ExitOnFailure(hr, "Failed to add role name to custom action data"); | ||
410 | hr = WcaWriteStringToCaData(pItm->pwzAccount, ppwzActionData); | ||
411 | ExitOnFailure(hr, "Failed to add user account to custom action data"); | ||
412 | |||
413 | // add partition information to custom action data | ||
414 | hr = WcaWriteStringToCaData(pItm->pPartitionRole->pPartition->wzID, ppwzActionData); | ||
415 | ExitOnFailure(hr, "Failed to add partition id to custom action data"); | ||
416 | |||
417 | hr = S_OK; | ||
418 | |||
419 | LExit: | ||
420 | return hr; | ||
421 | } | ||