aboutsummaryrefslogtreecommitdiff
path: root/src/ext/ComPlus/ca/cppartrolesched.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/ComPlus/ca/cppartrolesched.cpp')
-rw-r--r--src/ext/ComPlus/ca/cppartrolesched.cpp421
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
8LPCWSTR vcsPartitionRoleQuery =
9 L"SELECT `PartitionRole`, `Partition_`, `Component_`, `Name` FROM `ComPlusPartitionRole`";
10enum ePartitionRoleQuery { prqPartitionRole = 1, prqPartition, prqComponent, prqName };
11
12LPCWSTR vcsUserInPartitionRoleQuery =
13 L"SELECT `UserInPartitionRole`, `PartitionRole_`, `ComPlusUserInPartitionRole`.`Component_`, `Domain`, `Name` FROM `ComPlusUserInPartitionRole`, `User` WHERE `User_` = `User`";
14LPCWSTR vcsGroupInPartitionRoleQuery =
15 L"SELECT `GroupInPartitionRole`, `PartitionRole_`, `ComPlusGroupInPartitionRole`.`Component_`, `Domain`, `Name` FROM `ComPlusGroupInPartitionRole`, `Group` WHERE `Group_` = `Group`";
16enum eTrusteeInPartitionRoleQuery { tiprqUserInPartitionRole = 1, tiprqPartitionRole, tiprqComponent, tiprqDomain, tiprqName };
17
18
19// prototypes for private helper functions
20
21static HRESULT TrusteesInPartitionRolesRead(
22 LPCWSTR pwzQuery,
23 CPI_PARTITION_ROLE_LIST* pPartRoleList,
24 CPI_USER_IN_PARTITION_ROLE_LIST* pUsrInPartRoleList
25 );
26static void FreePartitionRole(
27 CPI_PARTITION_ROLE* pItm
28 );
29static void FreeUserInPartitionRole(
30 CPI_USER_IN_PARTITION_ROLE* pItm
31 );
32static 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
42void 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
56HRESULT 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
106LExit:
107 // clean up
108 if (pItm)
109 FreePartitionRole(pItm);
110
111 ReleaseStr(pwzData);
112
113 return hr;
114}
115
116HRESULT 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
134void 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
148HRESULT 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
171LExit:
172 return hr;
173}
174
175HRESULT 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
223LExit:
224 return hr;
225}
226
227HRESULT 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
270LExit:
271 return hr;
272}
273
274
275// helper function definitions
276
277static 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
362LExit:
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
374static void FreePartitionRole(
375 CPI_PARTITION_ROLE* pItm
376 )
377{
378 ::HeapFree(::GetProcessHeap(), 0, pItm);
379}
380
381static void FreeUserInPartitionRole(
382 CPI_USER_IN_PARTITION_ROLE* pItm
383 )
384{
385 ReleaseStr(pItm->pwzAccount);
386
387 ::HeapFree(::GetProcessHeap(), 0, pItm);
388}
389
390static 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
419LExit:
420 return hr;
421}