@joebigelow / wix / commits / cbc09b6c

Import code from old v4 repo

Sean Hall committed Feb 4, 2019 at 20:05 UTC cbc09b6cd6d0d0b8bf095a88d4d8333616637f71
44 files changed +21074
src/ca/cpappexec.cpp new
+344
@@ -0,0 +1,344 @@
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 +
8 +struct CPI_APPLICATION_ATTRIBUTES
9 +{
10 + int iActionType;
11 + int iActionCost;
12 + LPWSTR pwzKey;
13 + LPWSTR pwzID;
14 + LPWSTR pwzName;
15 + LPWSTR pwzPartID;
16 + CPI_PROPERTY* pPropList;
17 +};
18 +
19 +
20 +// prototypes for private helper functions
21 +
22 +static HRESULT ReadApplicationAttributes(
23 + LPWSTR* ppwzData,
24 + CPI_APPLICATION_ATTRIBUTES* pAttrs
25 + );
26 +static void FreeApplicationAttributes(
27 + CPI_APPLICATION_ATTRIBUTES* pAttrs
28 + );
29 +static HRESULT CreateApplication(
30 + CPI_APPLICATION_ATTRIBUTES* pAttrs
31 + );
32 +static HRESULT RemoveApplication(
33 + CPI_APPLICATION_ATTRIBUTES* pAttrs
34 + );
35 +
36 +
37 +// function definitions
38 +
39 +HRESULT CpiConfigureApplications(
40 + LPWSTR* ppwzData,
41 + HANDLE hRollbackFile
42 + )
43 +{
44 + HRESULT hr = S_OK;
45 +
46 + CPI_APPLICATION_ATTRIBUTES attrs;
47 + ::ZeroMemory(&attrs, sizeof(attrs));
48 +
49 + // read action text
50 + hr = CpiActionStartMessage(ppwzData, FALSE);
51 + ExitOnFailure(hr, "Failed to send action start message");
52 +
53 + // get count
54 + int iCnt = 0;
55 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
56 + ExitOnFailure(hr, "Failed to read count");
57 +
58 + // write count to rollback file
59 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
60 + ExitOnFailure(hr, "Failed to write count to rollback file");
61 +
62 + for (int i = 0; i < iCnt; i++)
63 + {
64 + // read attributes from CustomActionData
65 + hr = ReadApplicationAttributes(ppwzData, &attrs);
66 + ExitOnFailure(hr, "Failed to read attributes");
67 +
68 + // progress message
69 + hr = CpiActionDataMessage(1, attrs.pwzName);
70 + ExitOnFailure(hr, "Failed to send progress messages");
71 +
72 + if (S_FALSE == hr)
73 + ExitFunction();
74 +
75 + // write key to rollback file
76 + hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
77 + ExitOnFailure(hr, "Failed to write key to rollback file");
78 +
79 + // action
80 + switch (attrs.iActionType)
81 + {
82 + case atCreate:
83 + hr = CreateApplication(&attrs);
84 + ExitOnFailure(hr, "Failed to create application, key: %S", attrs.pwzKey);
85 + break;
86 + case atRemove:
87 + hr = RemoveApplication(&attrs);
88 + ExitOnFailure(hr, "Failed to remove application, key: %S", attrs.pwzKey);
89 + break;
90 + }
91 +
92 + // write completion status to rollback file
93 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
94 + ExitOnFailure(hr, "Failed to write completion status to rollback file");
95 +
96 + // progress
97 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
98 + ExitOnFailure(hr, "Failed to update progress");
99 + }
100 +
101 + hr = S_OK;
102 +
103 +LExit:
104 + // clean up
105 + FreeApplicationAttributes(&attrs);
106 +
107 + return hr;
108 +}
109 +
110 +HRESULT CpiRollbackConfigureApplications(
111 + LPWSTR* ppwzData,
112 + CPI_ROLLBACK_DATA* pRollbackDataList
113 + )
114 +{
115 + HRESULT hr = S_OK;
116 +
117 + int iRollbackStatus;
118 +
119 + CPI_APPLICATION_ATTRIBUTES attrs;
120 + ::ZeroMemory(&attrs, sizeof(attrs));
121 +
122 + // read action text
123 + hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
124 + ExitOnFailure(hr, "Failed to send action start message");
125 +
126 + // get count
127 + int iCnt = 0;
128 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
129 + ExitOnFailure(hr, "Failed to read count");
130 +
131 + for (int i = 0; i < iCnt; i++)
132 + {
133 + // read attributes from CustomActionData
134 + hr = ReadApplicationAttributes(ppwzData, &attrs);
135 + ExitOnFailure(hr, "Failed to read attributes");
136 +
137 + // rollback status
138 + hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
139 +
140 + if (S_FALSE == hr)
141 + continue; // not found, nothing to rollback
142 +
143 + // progress message
144 + hr = CpiActionDataMessage(1, attrs.pwzName);
145 + ExitOnFailure(hr, "Failed to send progress messages");
146 +
147 + if (S_FALSE == hr)
148 + ExitFunction();
149 +
150 + // action
151 + switch (attrs.iActionType)
152 + {
153 + case atCreate:
154 + hr = CreateApplication(&attrs);
155 + if (FAILED(hr))
156 + WcaLog(LOGMSG_STANDARD, "Failed to create application, hr: 0x%x, key: %S", hr, attrs.pwzKey);
157 + break;
158 + case atRemove:
159 + hr = RemoveApplication(&attrs);
160 + if (FAILED(hr))
161 + WcaLog(LOGMSG_STANDARD, "Failed to remove application, hr: 0x%x, key: %S", hr, attrs.pwzKey);
162 + break;
163 + }
164 +
165 + // check rollback status
166 + if (0 == iRollbackStatus)
167 + continue; // operation did not complete, skip progress
168 +
169 + // progress
170 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
171 + ExitOnFailure(hr, "Failed to update progress");
172 + }
173 +
174 + hr = S_OK;
175 +
176 +LExit:
177 + // clean up
178 + FreeApplicationAttributes(&attrs);
179 +
180 + return hr;
181 +}
182 +
183 +
184 +// helper function definitions
185 +
186 +static HRESULT ReadApplicationAttributes(
187 + LPWSTR* ppwzData,
188 + CPI_APPLICATION_ATTRIBUTES* pAttrs
189 + )
190 +{
191 + HRESULT hr = S_OK;
192 +
193 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
194 + ExitOnFailure(hr, "Failed to read action type");
195 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
196 + ExitOnFailure(hr, "Failed to read action cost");
197 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
198 + ExitOnFailure(hr, "Failed to read key");
199 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzID);
200 + ExitOnFailure(hr, "Failed to read id");
201 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName);
202 + ExitOnFailure(hr, "Failed to read name");
203 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
204 + ExitOnFailure(hr, "Failed to read partition id");
205 + hr = CpiReadPropertyList(ppwzData, &pAttrs->pPropList);
206 + ExitOnFailure(hr, "Failed to read properties");
207 +
208 + hr = S_OK;
209 +
210 +LExit:
211 + return hr;
212 +}
213 +
214 +static void FreeApplicationAttributes(
215 + CPI_APPLICATION_ATTRIBUTES* pAttrs
216 + )
217 +{
218 + ReleaseStr(pAttrs->pwzKey);
219 + ReleaseStr(pAttrs->pwzID);
220 + ReleaseStr(pAttrs->pwzName);
221 + ReleaseStr(pAttrs->pwzPartID);
222 +
223 + if (pAttrs->pPropList)
224 + CpiFreePropertyList(pAttrs->pPropList);
225 +}
226 +
227 +static HRESULT CreateApplication(
228 + CPI_APPLICATION_ATTRIBUTES* pAttrs
229 + )
230 +{
231 + HRESULT hr = S_OK;
232 +
233 + ICatalogCollection* piAppColl = NULL;
234 + ICatalogObject* piAppObj = NULL;
235 +
236 + long lChanges = 0;
237 +
238 + // log
239 + WcaLog(LOGMSG_VERBOSE, "Creating application, key: %S", pAttrs->pwzKey);
240 +
241 + // get applications collection
242 + hr = CpiGetApplicationsCollection(pAttrs->pwzPartID, &piAppColl);
243 + if (S_FALSE == hr)
244 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
245 + ExitOnFailure(hr, "Failed to get applications collection");
246 +
247 + // check if application exists
248 + hr = CpiFindCollectionObjectByStringKey(piAppColl, pAttrs->pwzID, &piAppObj);
249 + ExitOnFailure(hr, "Failed to find application");
250 +
251 + if (S_FALSE == hr)
252 + {
253 + // create application
254 + hr = CpiAddCollectionObject(piAppColl, &piAppObj);
255 + ExitOnFailure(hr, "Failed to add application to collection");
256 +
257 + hr = CpiPutCollectionObjectValue(piAppObj, L"ID", pAttrs->pwzID);
258 + ExitOnFailure(hr, "Failed to set application id property");
259 +
260 + hr = CpiPutCollectionObjectValue(piAppObj, L"Name", pAttrs->pwzName);
261 + ExitOnFailure(hr, "Failed to set application name property");
262 +
263 + // save changes
264 + hr = piAppColl->SaveChanges(&lChanges);
265 + if (COMADMIN_E_OBJECTERRORS == hr)
266 + CpiLogCatalogErrorInfo();
267 + ExitOnFailure(hr, "Failed to add application");
268 + }
269 +
270 + // properties
271 + hr = CpiPutCollectionObjectValues(piAppObj, pAttrs->pPropList);
272 + ExitOnFailure(hr, "Failed to write properties");
273 +
274 + // save changes
275 + hr = piAppColl->SaveChanges(&lChanges);
276 + if (COMADMIN_E_OBJECTERRORS == hr)
277 + CpiLogCatalogErrorInfo();
278 + ExitOnFailure(hr, "Failed to save changes");
279 +
280 + // log
281 + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
282 +
283 + hr = S_OK;
284 +
285 +LExit:
286 + // clean up
287 + ReleaseObject(piAppColl);
288 + ReleaseObject(piAppObj);
289 +
290 + return hr;
291 +}
292 +
293 +static HRESULT RemoveApplication(
294 + CPI_APPLICATION_ATTRIBUTES* pAttrs
295 + )
296 +{
297 + HRESULT hr = S_OK;
298 +
299 + ICatalogCollection* piAppColl = NULL;
300 +
301 + long lChanges = 0;
302 +
303 + // log
304 + WcaLog(LOGMSG_VERBOSE, "Removing application, key: %S", pAttrs->pwzKey);
305 +
306 + // get applications collection
307 + hr = CpiGetApplicationsCollection(pAttrs->pwzPartID, &piAppColl);
308 + ExitOnFailure(hr, "Failed to get applications collection");
309 +
310 + if (S_FALSE == hr)
311 + {
312 + // applications collection not found
313 + WcaLog(LOGMSG_VERBOSE, "Unable to retrieve applications collection, nothing to delete, key: %S", pAttrs->pwzKey);
314 + ExitFunction1(hr = S_OK);
315 + }
316 +
317 + // remove
318 + hr = CpiRemoveCollectionObject(piAppColl, pAttrs->pwzID, NULL, TRUE);
319 + ExitOnFailure(hr, "Failed to remove application");
320 +
321 + if (S_FALSE == hr)
322 + {
323 + // application not found
324 + WcaLog(LOGMSG_VERBOSE, "Application not found, nothing to delete, key: %S", pAttrs->pwzKey);
325 + ExitFunction1(hr = S_OK);
326 + }
327 +
328 + // save changes
329 + hr = piAppColl->SaveChanges(&lChanges);
330 + if (COMADMIN_E_OBJECTERRORS == hr)
331 + CpiLogCatalogErrorInfo();
332 + ExitOnFailure(hr, "Failed to save changes");
333 +
334 + // log
335 + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
336 +
337 + hr = S_OK;
338 +
339 +LExit:
340 + // clean up
341 + ReleaseObject(piAppColl);
342 +
343 + return hr;
344 +}
src/ca/cpappexec.h new
+12
@@ -0,0 +1,12 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +HRESULT CpiConfigureApplications(
6 + LPWSTR* ppwzData,
7 + HANDLE hRollbackFile
8 + );
9 +HRESULT CpiRollbackConfigureApplications(
10 + LPWSTR* ppwzData,
11 + CPI_ROLLBACK_DATA* pRollbackDataList
12 + );
src/ca/cpapproleexec.cpp new
+720
@@ -0,0 +1,720 @@
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 +
8 +struct CPI_APPLICATION_ROLE_ATTRIBUTES
9 +{
10 + int iActionType;
11 + int iActionCost;
12 + LPWSTR pwzKey;
13 + LPWSTR pwzName;
14 + LPWSTR pwzAppID;
15 + LPWSTR pwzPartID;
16 + CPI_PROPERTY* pPropList;
17 +};
18 +
19 +struct CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES
20 +{
21 + int iActionType;
22 + int iActionCost;
23 + LPWSTR pwzKey;
24 + LPWSTR pwzRoleName;
25 + LPWSTR pwzAccount;
26 + LPWSTR pwzAppID;
27 + LPWSTR pwzPartID;
28 +};
29 +
30 +
31 +// prototypes for private helper functions
32 +
33 +static HRESULT ReadApplicationRoleAttributes(
34 + LPWSTR* ppwzData,
35 + CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
36 + );
37 +static void FreeApplicationRoleAttributes(
38 + CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
39 + );
40 +static HRESULT CreateApplicationRole(
41 + CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
42 + );
43 +static HRESULT RemoveApplicationRole(
44 + CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
45 + );
46 +static HRESULT ReadUsersInApplicationRoleAttributes(
47 + LPWSTR* ppwzData,
48 + CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
49 + );
50 +static void FreeUsersInApplicationRoleAttributes(
51 + CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
52 + );
53 +static HRESULT CreateUsersInApplicationRole(
54 + CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
55 + );
56 +static HRESULT RemoveUsersInApplicationRole(
57 + CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
58 + );
59 +
60 +
61 +// function definitions
62 +
63 +HRESULT CpiConfigureApplicationRoles(
64 + LPWSTR* ppwzData,
65 + HANDLE hRollbackFile
66 + )
67 +{
68 + HRESULT hr = S_OK;
69 +
70 + CPI_APPLICATION_ROLE_ATTRIBUTES attrs;
71 + ::ZeroMemory(&attrs, sizeof(attrs));
72 +
73 + // read action text
74 + hr = CpiActionStartMessage(ppwzData, FALSE);
75 + ExitOnFailure(hr, "Failed to send action start message");
76 +
77 + // ger count
78 + int iCnt = 0;
79 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
80 + ExitOnFailure(hr, "Failed to read count");
81 +
82 + // write count to rollback file
83 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
84 + ExitOnFailure(hr, "Failed to write count to rollback file");
85 +
86 + for (int i = 0; i < iCnt; i++)
87 + {
88 + // read attributes from CustomActionData
89 + hr = ReadApplicationRoleAttributes(ppwzData, &attrs);
90 + ExitOnFailure(hr, "Failed to read attributes");
91 +
92 + // progress message
93 + hr = CpiActionDataMessage(1, attrs.pwzName);
94 + ExitOnFailure(hr, "Failed to send progress messages");
95 +
96 + if (S_FALSE == hr)
97 + ExitFunction();
98 +
99 + // write key to rollback file
100 + hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
101 + ExitOnFailure(hr, "Failed to write key to rollback file");
102 +
103 + // action
104 + switch (attrs.iActionType)
105 + {
106 + case atCreate:
107 + hr = CreateApplicationRole(&attrs);
108 + ExitOnFailure(hr, "Failed to create application role, key: %S", attrs.pwzKey);
109 + break;
110 + case atRemove:
111 + hr = RemoveApplicationRole(&attrs);
112 + ExitOnFailure(hr, "Failed to remove application role, key: %S", attrs.pwzKey);
113 + break;
114 + }
115 +
116 + // write completion status to rollback file
117 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
118 + ExitOnFailure(hr, "Failed to write completion status to rollback file");
119 +
120 + // progress
121 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
122 + ExitOnFailure(hr, "Failed to update progress");
123 + }
124 +
125 + hr = S_OK;
126 +
127 +LExit:
128 + // clean up
129 + FreeApplicationRoleAttributes(&attrs);
130 +
131 + return hr;
132 +}
133 +
134 +HRESULT CpiRollbackConfigureApplicationRoles(
135 + LPWSTR* ppwzData,
136 + CPI_ROLLBACK_DATA* pRollbackDataList
137 + )
138 +{
139 + HRESULT hr = S_OK;
140 +
141 + int iRollbackStatus;
142 +
143 + CPI_APPLICATION_ROLE_ATTRIBUTES attrs;
144 + ::ZeroMemory(&attrs, sizeof(attrs));
145 +
146 + // read action text
147 + hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
148 + ExitOnFailure(hr, "Failed to send action start message");
149 +
150 + // get count
151 + int iCnt = 0;
152 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
153 + ExitOnFailure(hr, "Failed to read count");
154 +
155 + for (int i = 0; i < iCnt; i++)
156 + {
157 + // read attributes from CustomActionData
158 + hr = ReadApplicationRoleAttributes(ppwzData, &attrs);
159 + ExitOnFailure(hr, "Failed to read attributes");
160 +
161 + // rollback status
162 + hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
163 +
164 + if (S_FALSE == hr)
165 + continue; // not found, nothing to rollback
166 +
167 + // progress message
168 + hr = CpiActionDataMessage(1, attrs.pwzName);
169 + ExitOnFailure(hr, "Failed to send progress messages");
170 +
171 + if (S_FALSE == hr)
172 + ExitFunction();
173 +
174 + // action
175 + switch (attrs.iActionType)
176 + {
177 + case atCreate:
178 + hr = CreateApplicationRole(&attrs);
179 + if (FAILED(hr))
180 + WcaLog(LOGMSG_STANDARD, "Failed to create application role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
181 + break;
182 + case atRemove:
183 + hr = RemoveApplicationRole(&attrs);
184 + if (FAILED(hr))
185 + WcaLog(LOGMSG_STANDARD, "Failed to remove application role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
186 + break;
187 + }
188 +
189 + // check rollback status
190 + if (0 == iRollbackStatus)
191 + continue; // operation did not complete, skip progress
192 +
193 + // progress
194 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
195 + ExitOnFailure(hr, "Failed to update progress");
196 + }
197 +
198 + hr = S_OK;
199 +
200 +LExit:
201 + // clean up
202 + FreeApplicationRoleAttributes(&attrs);
203 +
204 + return hr;
205 +}
206 +
207 +HRESULT CpiConfigureUsersInApplicationRoles(
208 + LPWSTR* ppwzData,
209 + HANDLE hRollbackFile
210 + )
211 +{
212 + HRESULT hr = S_OK;
213 +
214 + CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES attrs;
215 + ::ZeroMemory(&attrs, sizeof(attrs));
216 +
217 + // read action text
218 + hr = CpiActionStartMessage(ppwzData, FALSE);
219 + ExitOnFailure(hr, "Failed to send action start message");
220 +
221 + // ger count
222 + int iCnt = 0;
223 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
224 + ExitOnFailure(hr, "Failed to read count");
225 +
226 + // write count to rollback file
227 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
228 + ExitOnFailure(hr, "Failed to write count to rollback file");
229 +
230 + for (int i = 0; i < iCnt; i++)
231 + {
232 + // read attributes from CustomActionData
233 + hr = ReadUsersInApplicationRoleAttributes(ppwzData, &attrs);
234 + ExitOnFailure(hr, "Failed to read attributes");
235 +
236 + // progress message
237 + hr = CpiActionDataMessage(1, attrs.pwzRoleName);
238 + ExitOnFailure(hr, "Failed to send progress messages");
239 +
240 + if (S_FALSE == hr)
241 + ExitFunction();
242 +
243 + // write key to rollback file
244 + hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
245 + ExitOnFailure(hr, "Failed to write key to rollback file");
246 +
247 + // action
248 + switch (attrs.iActionType)
249 + {
250 + case atCreate:
251 + hr = CreateUsersInApplicationRole(&attrs);
252 + ExitOnFailure(hr, "Failed to create user in application role, key: %S", attrs.pwzKey);
253 + break;
254 + case atRemove:
255 + hr = RemoveUsersInApplicationRole(&attrs);
256 + ExitOnFailure(hr, "Failed to remove user from application role, key: %S", attrs.pwzKey);
257 + break;
258 + }
259 +
260 + // write completion status to rollback file
261 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
262 + ExitOnFailure(hr, "Failed to write completion status to rollback file");
263 +
264 + // progress
265 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
266 + ExitOnFailure(hr, "Failed to update progress");
267 + }
268 +
269 + hr = S_OK;
270 +
271 +LExit:
272 + // clean up
273 + FreeUsersInApplicationRoleAttributes(&attrs);
274 +
275 + return hr;
276 +}
277 +
278 +HRESULT CpiRollbackConfigureUsersInApplicationRoles(
279 + LPWSTR* ppwzData,
280 + CPI_ROLLBACK_DATA* pRollbackDataList
281 + )
282 +{
283 + HRESULT hr = S_OK;
284 +
285 + int iRollbackStatus;
286 +
287 + CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES attrs;
288 + ::ZeroMemory(&attrs, sizeof(attrs));
289 +
290 + // read action text
291 + hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
292 + ExitOnFailure(hr, "Failed to send action start message");
293 +
294 + // get count
295 + int iCnt = 0;
296 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
297 + ExitOnFailure(hr, "Failed to read count");
298 +
299 + for (int i = 0; i < iCnt; i++)
300 + {
301 + // read attributes from CustomActionData
302 + hr = ReadUsersInApplicationRoleAttributes(ppwzData, &attrs);
303 + ExitOnFailure(hr, "Failed to read attributes");
304 +
305 + // rollback status
306 + hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
307 +
308 + if (S_FALSE == hr)
309 + continue; // not found, nothing to rollback
310 +
311 + // progress message
312 + hr = CpiActionDataMessage(1, attrs.pwzRoleName);
313 + ExitOnFailure(hr, "Failed to send progress messages");
314 +
315 + if (S_FALSE == hr)
316 + ExitFunction();
317 +
318 + // action
319 + switch (attrs.iActionType)
320 + {
321 + case atCreate:
322 + hr = CreateUsersInApplicationRole(&attrs);
323 + if (FAILED(hr))
324 + WcaLog(LOGMSG_STANDARD, "Failed to add user to application role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
325 + break;
326 + case atRemove:
327 + hr = RemoveUsersInApplicationRole(&attrs);
328 + if (FAILED(hr))
329 + WcaLog(LOGMSG_STANDARD, "Failed to remove user from application role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
330 + break;
331 + }
332 +
333 + // check rollback status
334 + if (0 == iRollbackStatus)
335 + continue; // operation did not complete, skip progress
336 +
337 + // progress
338 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
339 + ExitOnFailure(hr, "Failed to update progress");
340 + }
341 +
342 + hr = S_OK;
343 +
344 +LExit:
345 + // clean up
346 + FreeUsersInApplicationRoleAttributes(&attrs);
347 +
348 + return hr;
349 +}
350 +
351 +
352 +// helper function definitions
353 +
354 +static HRESULT ReadApplicationRoleAttributes(
355 + LPWSTR* ppwzData,
356 + CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
357 + )
358 +{
359 + HRESULT hr = S_OK;
360 +
361 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
362 + ExitOnFailure(hr, "Failed to read action type");
363 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
364 + ExitOnFailure(hr, "Failed to read action cost");
365 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
366 + ExitOnFailure(hr, "Failed to read key");
367 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName);
368 + ExitOnFailure(hr, "Failed to read name");
369 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAppID);
370 + ExitOnFailure(hr, "Failed to read application id");
371 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
372 + ExitOnFailure(hr, "Failed to read partition id");
373 + hr = CpiReadPropertyList(ppwzData, &pAttrs->pPropList);
374 + ExitOnFailure(hr, "Failed to read properties");
375 +
376 + hr = S_OK;
377 +
378 +LExit:
379 + return hr;
380 +}
381 +
382 +static void FreeApplicationRoleAttributes(
383 + CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
384 + )
385 +{
386 + ReleaseStr(pAttrs->pwzKey);
387 + ReleaseStr(pAttrs->pwzName);
388 + ReleaseStr(pAttrs->pwzAppID);
389 + ReleaseStr(pAttrs->pwzPartID);
390 +
391 + if (pAttrs->pPropList)
392 + CpiFreePropertyList(pAttrs->pPropList);
393 +}
394 +
395 +static HRESULT CreateApplicationRole(
396 + CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
397 + )
398 +{
399 + HRESULT hr = S_OK;
400 +
401 + ICatalogCollection* piRolesColl = NULL;
402 + ICatalogObject* piRoleObj = NULL;
403 +
404 + long lChanges = 0;
405 +
406 + // log
407 + WcaLog(LOGMSG_VERBOSE, "Creating application role, key: %S", pAttrs->pwzKey);
408 +
409 + // get roles collection
410 + hr = CpiGetRolesCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, &piRolesColl);
411 + if (S_FALSE == hr)
412 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
413 + ExitOnFailure(hr, "Failed to get roles collection");
414 +
415 + // check if role exists
416 + hr = CpiFindCollectionObjectByName(piRolesColl, pAttrs->pwzName, &piRoleObj);
417 + ExitOnFailure(hr, "Failed to find role");
418 +
419 + if (S_FALSE == hr)
420 + {
421 + // create role
422 + hr = CpiAddCollectionObject(piRolesColl, &piRoleObj);
423 + ExitOnFailure(hr, "Failed to add role to collection");
424 +
425 + hr = CpiPutCollectionObjectValue(piRoleObj, L"Name", pAttrs->pwzName);
426 + ExitOnFailure(hr, "Failed to set role name property");
427 + }
428 +
429 + // properties
430 + hr = CpiPutCollectionObjectValues(piRoleObj, pAttrs->pPropList);
431 + ExitOnFailure(hr, "Failed to write properties");
432 +
433 + // save changes
434 + hr = piRolesColl->SaveChanges(&lChanges);
435 + if (COMADMIN_E_OBJECTERRORS == hr)
436 + CpiLogCatalogErrorInfo();
437 + ExitOnFailure(hr, "Failed to save changes");
438 +
439 + // log
440 + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
441 +
442 + hr = S_OK;
443 +
444 +LExit:
445 + // clean up
446 + ReleaseObject(piRolesColl);
447 + ReleaseObject(piRoleObj);
448 +
449 + return hr;
450 +}
451 +
452 +static HRESULT RemoveApplicationRole(
453 + CPI_APPLICATION_ROLE_ATTRIBUTES* pAttrs
454 + )
455 +{
456 + HRESULT hr = S_OK;
457 +
458 + ICatalogCollection* piRolesColl = NULL;
459 +
460 + long lChanges = 0;
461 +
462 + // log
463 + WcaLog(LOGMSG_VERBOSE, "Removing application role, key: %S", pAttrs->pwzKey);
464 +
465 + // get roles collection
466 + hr = CpiGetRolesCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, &piRolesColl);
467 + ExitOnFailure(hr, "Failed to get roles collection");
468 +
469 + if (S_FALSE == hr)
470 + {
471 + // roles collection not found
472 + WcaLog(LOGMSG_VERBOSE, "Unable to retrieve roles collection, nothing to delete, key: %S", pAttrs->pwzKey);
473 + ExitFunction1(hr = S_OK);
474 + }
475 +
476 + // remove
477 + hr = CpiRemoveCollectionObject(piRolesColl, NULL, pAttrs->pwzName, FALSE);
478 + ExitOnFailure(hr, "Failed to remove role");
479 +
480 + if (S_FALSE == hr)
481 + {
482 + // role not found
483 + WcaLog(LOGMSG_VERBOSE, "Role not found, nothing to delete, key: %S", pAttrs->pwzKey);
484 + ExitFunction1(hr = S_OK);
485 + }
486 +
487 + // save changes
488 + hr = piRolesColl->SaveChanges(&lChanges);
489 + if (COMADMIN_E_OBJECTERRORS == hr)
490 + CpiLogCatalogErrorInfo();
491 + ExitOnFailure(hr, "Failed to save changes");
492 +
493 + // log
494 + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
495 +
496 + hr = S_OK;
497 +
498 +LExit:
499 + // clean up
500 + ReleaseObject(piRolesColl);
501 +
502 + return hr;
503 +}
504 +
505 +static HRESULT ReadUsersInApplicationRoleAttributes(
506 + LPWSTR* ppwzData,
507 + CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
508 + )
509 +{
510 + HRESULT hr = S_OK;
511 +
512 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
513 + ExitOnFailure(hr, "Failed to read action type");
514 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
515 + ExitOnFailure(hr, "Failed to read action cost");
516 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
517 + ExitOnFailure(hr, "Failed to read key");
518 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzRoleName);
519 + ExitOnFailure(hr, "Failed to read role name");
520 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAccount);
521 + ExitOnFailure(hr, "Failed to read account name");
522 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAppID);
523 + ExitOnFailure(hr, "Failed to read application id");
524 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
525 + ExitOnFailure(hr, "Failed to read partition id");
526 +
527 + hr = S_OK;
528 +
529 +LExit:
530 + return hr;
531 +}
532 +
533 +static void FreeUsersInApplicationRoleAttributes(
534 + CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
535 + )
536 +{
537 + ReleaseStr(pAttrs->pwzKey);
538 + ReleaseStr(pAttrs->pwzRoleName);
539 + ReleaseStr(pAttrs->pwzAccount);
540 + ReleaseStr(pAttrs->pwzAppID);
541 + ReleaseStr(pAttrs->pwzPartID);
542 +}
543 +
544 +static HRESULT CreateUsersInApplicationRole(
545 + CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
546 + )
547 +{
548 + HRESULT hr = S_OK;
549 + UINT er = ERROR_SUCCESS;
550 +
551 + ICatalogCollection* piUsrInRoleColl = NULL;
552 + ICatalogObject* piUsrInRoleObj = NULL;
553 +
554 + PSID pSid = NULL;
555 + long lChanges = 0;
556 +
557 + // log
558 + WcaLog(LOGMSG_VERBOSE, "Adding user to application role, key: %S", pAttrs->pwzKey);
559 +
560 + // get users in role collection
561 + hr = CpiGetUsersInRoleCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzRoleName, &piUsrInRoleColl);
562 + if (S_FALSE == hr)
563 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
564 + ExitOnFailure(hr, "Failed to get users in role collection");
565 +
566 + // get SID for account
567 + do {
568 + er = ERROR_SUCCESS;
569 + hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
570 + if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
571 + {
572 + WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
573 + er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
574 + switch (er)
575 + {
576 + case IDABORT:
577 + ExitFunction(); // exit with error code from CpiAccountNameToSid()
578 + case IDRETRY:
579 + break;
580 + case IDIGNORE:
581 + default:
582 + ExitFunction1(hr = S_OK);
583 + }
584 + }
585 + else
586 + ExitOnFailure(hr, "Failed to get SID for account");
587 + } while (IDRETRY == er);
588 +
589 + // find any existing entry
590 + hr = CpiFindUserCollectionObject(piUsrInRoleColl, pSid, NULL);
591 + if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
592 + WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
593 + else
594 + ExitOnFailure(hr, "Failed to find user in application role");
595 +
596 + if (S_OK == hr)
597 + {
598 + WcaLog(LOGMSG_VERBOSE, "User already assigned to application role, key: %S", pAttrs->pwzKey);
599 + ExitFunction(); // exit with hr = S_OK
600 + }
601 +
602 + // convert SID back to account name
603 + hr = CpiSidToAccountName(pSid, &pAttrs->pwzAccount);
604 + ExitOnFailure(hr, "Failed to convert SID to account name");
605 +
606 + // add user
607 + hr = CpiAddCollectionObject(piUsrInRoleColl, &piUsrInRoleObj);
608 + ExitOnFailure(hr, "Failed to add user in role to collection");
609 +
610 + hr = CpiPutCollectionObjectValue(piUsrInRoleObj, L"User", pAttrs->pwzAccount);
611 + ExitOnFailure(hr, "Failed to set role name property");
612 +
613 + // save changes
614 + hr = piUsrInRoleColl->SaveChanges(&lChanges);
615 + if (COMADMIN_E_OBJECTERRORS == hr)
616 + CpiLogCatalogErrorInfo();
617 + ExitOnFailure(hr, "Failed to save changes");
618 +
619 + // log
620 + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
621 +
622 + hr = S_OK;
623 +
624 +LExit:
625 + // clean up
626 + ReleaseObject(piUsrInRoleColl);
627 + ReleaseObject(piUsrInRoleObj);
628 +
629 + if (pSid)
630 + ::HeapFree(::GetProcessHeap(), 0, pSid);
631 +
632 + return hr;
633 +}
634 +
635 +static HRESULT RemoveUsersInApplicationRole(
636 + CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs
637 + )
638 +{
639 + HRESULT hr = S_OK;
640 + UINT er = ERROR_SUCCESS;
641 +
642 + ICatalogCollection* piUsrInRoleColl = NULL;
643 +
644 + PSID pSid = NULL;
645 + long lChanges = 0;
646 +
647 + // log
648 + WcaLog(LOGMSG_VERBOSE, "Removing user from application role, key: %S", pAttrs->pwzKey);
649 +
650 + // get users in role collection
651 + hr = CpiGetUsersInRoleCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzRoleName, &piUsrInRoleColl);
652 + ExitOnFailure(hr, "Failed to get users in role collection");
653 +
654 + if (S_FALSE == hr)
655 + {
656 + // users in role collection not found
657 + WcaLog(LOGMSG_VERBOSE, "Unable to retrieve users in role collection, nothing to delete, key: %S", pAttrs->pwzKey);
658 + ExitFunction1(hr = S_OK);
659 + }
660 +
661 + // get SID for account
662 + do {
663 + er = ERROR_SUCCESS;
664 + hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
665 + if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
666 + {
667 + WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
668 + er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
669 + switch (er)
670 + {
671 + case IDABORT:
672 + ExitFunction(); // exit with error code from CpiAccountNameToSid()
673 + case IDRETRY:
674 + break;
675 + case IDIGNORE:
676 + default:
677 + ExitFunction1(hr = S_OK);
678 + }
679 + }
680 + else
681 + ExitOnFailure(hr, "Failed to get SID for account");
682 + } while (IDRETRY == er);
683 +
684 + // remove
685 + hr = CpiRemoveUserCollectionObject(piUsrInRoleColl, pSid);
686 + if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
687 + {
688 + WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
689 + hr = S_FALSE;
690 + }
691 + else
692 + ExitOnFailure(hr, "Failed to remove user");
693 +
694 + if (S_FALSE == hr)
695 + {
696 + // role not found
697 + WcaLog(LOGMSG_VERBOSE, "User not found for application role, nothing to delete, key: %S", pAttrs->pwzKey);
698 + ExitFunction1(hr = S_OK);
699 + }
700 +
701 + // save changes
702 + hr = piUsrInRoleColl->SaveChanges(&lChanges);
703 + if (COMADMIN_E_OBJECTERRORS == hr)
704 + CpiLogCatalogErrorInfo();
705 + ExitOnFailure(hr, "Failed to save changes");
706 +
707 + // log
708 + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
709 +
710 + hr = S_OK;
711 +
712 +LExit:
713 + // clean up
714 + ReleaseObject(piUsrInRoleColl);
715 +
716 + if (pSid)
717 + ::HeapFree(::GetProcessHeap(), 0, pSid);
718 +
719 + return hr;
720 +}
src/ca/cpapproleexec.h new
+20
@@ -0,0 +1,20 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +HRESULT CpiConfigureApplicationRoles(
6 + LPWSTR* ppwzData,
7 + HANDLE hRollbackFile
8 + );
9 +HRESULT CpiRollbackConfigureApplicationRoles(
10 + LPWSTR* ppwzData,
11 + CPI_ROLLBACK_DATA* pRollbackDataList
12 + );
13 +HRESULT CpiConfigureUsersInApplicationRoles(
14 + LPWSTR* ppwzData,
15 + HANDLE hRollbackFile
16 + );
17 +HRESULT CpiRollbackConfigureUsersInApplicationRoles(
18 + LPWSTR* ppwzData,
19 + CPI_ROLLBACK_DATA* pRollbackDataList
20 + );
src/ca/cpapprolesched.cpp new
+843
@@ -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 +}
src/ca/cpapprolesched.h new
+112
@@ -0,0 +1,112 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +struct CPI_APPLICATION_ROLE
6 +{
7 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
8 + WCHAR wzName[MAX_DARWIN_COLUMN + 1];
9 +
10 + int iPropertyCount;
11 + CPI_PROPERTY* pProperties;
12 +
13 + BOOL fHasComponent;
14 + BOOL fReferencedForInstall;
15 + BOOL fReferencedForUninstall;
16 + BOOL fObjectNotFound;
17 +
18 + INSTALLSTATE isInstalled, isAction;
19 +
20 + CPI_APPLICATION* pApplication;
21 +
22 + ICatalogCollection* piUsersColl;
23 +
24 + CPI_APPLICATION_ROLE* pNext;
25 +};
26 +
27 +struct CPI_APPLICATION_ROLE_LIST
28 +{
29 + CPI_APPLICATION_ROLE* pFirst;
30 +
31 + int iInstallCount;
32 + int iUninstallCount;
33 +};
34 +
35 +struct CPI_USER_IN_APPLICATION_ROLE
36 +{
37 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
38 + LPWSTR pwzAccount;
39 +
40 + INSTALLSTATE isInstalled, isAction;
41 +
42 + CPI_APPLICATION_ROLE* pApplicationRole;
43 +
44 + CPI_USER_IN_APPLICATION_ROLE* pNext;
45 +};
46 +
47 +struct CPI_USER_IN_APPLICATION_ROLE_LIST
48 +{
49 + CPI_USER_IN_APPLICATION_ROLE* pFirst;
50 +
51 + int iInstallCount;
52 + int iUninstallCount;
53 +};
54 +
55 +
56 +// function prototypes
57 +
58 +void CpiApplicationRoleListFree(
59 + CPI_APPLICATION_ROLE_LIST* pList
60 + );
61 +HRESULT CpiApplicationRolesRead(
62 + CPI_APPLICATION_LIST* pAppList,
63 + CPI_APPLICATION_ROLE_LIST* pAppRoleList
64 + );
65 +HRESULT CpiApplicationRolesVerifyInstall(
66 + CPI_APPLICATION_ROLE_LIST* pList
67 + );
68 +HRESULT CpiApplicationRolesVerifyUninstall(
69 + CPI_APPLICATION_ROLE_LIST* pList
70 + );
71 +void CpiApplicationRoleAddReferenceInstall(
72 + CPI_APPLICATION_ROLE* pItm
73 + );
74 +void CpiApplicationRoleAddReferenceUninstall(
75 + CPI_APPLICATION_ROLE* pItm
76 + );
77 +HRESULT CpiApplicationRolesInstall(
78 + CPI_APPLICATION_ROLE_LIST* pList,
79 + int iRunMode,
80 + LPWSTR* ppwzActionData,
81 + int* piProgress
82 + );
83 +HRESULT CpiApplicationRolesUninstall(
84 + CPI_APPLICATION_ROLE_LIST* pList,
85 + int iRunMode,
86 + LPWSTR* ppwzActionData,
87 + int* piProgress
88 + );
89 +HRESULT CpiApplicationRoleFindByKey(
90 + CPI_APPLICATION_ROLE_LIST* pList,
91 + LPCWSTR pwzKey,
92 + CPI_APPLICATION_ROLE** ppAppRole
93 + );
94 +void CpiUserInApplicationRoleListFree(
95 + CPI_USER_IN_APPLICATION_ROLE_LIST* pList
96 + );
97 +HRESULT CpiUsersInApplicationRolesRead(
98 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
99 + CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList
100 + );
101 +HRESULT CpiUsersInApplicationRolesInstall(
102 + CPI_USER_IN_APPLICATION_ROLE_LIST* pList,
103 + int iRunMode,
104 + LPWSTR* ppwzActionData,
105 + int* piProgress
106 + );
107 +HRESULT CpiUsersInApplicationRolesUninstall(
108 + CPI_USER_IN_APPLICATION_ROLE_LIST* pList,
109 + int iRunMode,
110 + LPWSTR* ppwzActionData,
111 + int* piProgress
112 + );
src/ca/cpappsched.cpp new
+752
@@ -0,0 +1,752 @@
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 vcsApplicationQuery =
9 + L"SELECT `Application`, `Component_`, `Partition_`, `Id`, `Name` FROM `ComPlusApplication`";
10 +enum eApplicationQuery { aqApplication = 1, aqComponent, aqPartition, aqID, aqName };
11 +
12 +LPCWSTR vcsApplicationPropertyQuery =
13 + L"SELECT `Name`, `Value` FROM `ComPlusApplicationProperty` WHERE `Application_` = ?";
14 +
15 +
16 +// property definitions
17 +
18 +CPI_PROPERTY_DEFINITION pdlApplicationProperties[] =
19 +{
20 + {L"3GigSupportEnabled", cpptBoolean, 500},
21 + {L"AccessChecksLevel", cpptInteger, 500},
22 + {L"Activation", cpptInteger, 500},
23 + {L"ApplicationAccessChecksEnabled", cpptBoolean, 500},
24 + {L"ApplicationDirectory", cpptString, 501},
25 + {L"Authentication", cpptInteger, 500},
26 + {L"AuthenticationCapability", cpptInteger, 500},
27 + {L"Changeable", cpptBoolean, 500},
28 + {L"CommandLine", cpptString, 500},
29 + {L"ConcurrentApps", cpptInteger, 501},
30 + {L"CreatedBy", cpptString, 500},
31 + {L"CRMEnabled", cpptBoolean, 500},
32 + {L"CRMLogFile", cpptString, 500},
33 + {L"Deleteable", cpptBoolean, 500},
34 + {L"Description", cpptString, 500},
35 + {L"DumpEnabled", cpptBoolean, 501},
36 + {L"DumpOnException", cpptBoolean, 501},
37 + {L"DumpOnFailfast", cpptBoolean, 501},
38 + {L"DumpPath", cpptString, 501},
39 + {L"EventsEnabled", cpptBoolean, 500},
40 + {L"Identity", cpptString, 500},
41 + {L"ImpersonationLevel", cpptInteger, 500},
42 + {L"IsEnabled", cpptBoolean, 501},
43 + {L"MaxDumpCount", cpptInteger, 501},
44 + {L"Password", cpptString, 500},
45 + {L"QCAuthenticateMsgs", cpptInteger, 501},
46 + {L"QCListenerMaxThreads", cpptInteger, 501},
47 + {L"QueueListenerEnabled", cpptBoolean, 500},
48 + {L"QueuingEnabled", cpptBoolean, 500},
49 + {L"RecycleActivationLimit", cpptInteger, 501},
50 + {L"RecycleCallLimit", cpptInteger, 501},
51 + {L"RecycleExpirationTimeout", cpptInteger, 501},
52 + {L"RecycleLifetimeLimit", cpptInteger, 501},
53 + {L"RecycleMemoryLimit", cpptInteger, 501},
54 + {L"Replicable", cpptBoolean, 501},
55 + {L"RunForever", cpptBoolean, 500},
56 + {L"ShutdownAfter", cpptInteger, 500},
57 + {L"SoapActivated", cpptBoolean, 502},
58 + {L"SoapBaseUrl", cpptString, 502},
59 + {L"SoapMailTo", cpptString, 502},
60 + {L"SoapVRoot", cpptString, 502},
61 + {L"SRPEnabled", cpptBoolean, 501},
62 + {L"SRPTrustLevel", cpptInteger, 501},
63 + {NULL, cpptNone, 0}
64 +};
65 +
66 +
67 +// prototypes for private helper functions
68 +
69 +static void FreeApplication(
70 + CPI_APPLICATION* pItm
71 + );
72 +static HRESULT FindObjectForApplication(
73 + CPI_APPLICATION* pItm,
74 + BOOL fFindId,
75 + BOOL fFindName,
76 + ICatalogObject** ppiAppObj
77 + );
78 +static HRESULT AddApplicationToActionData(
79 + CPI_APPLICATION* pItm,
80 + int iActionType,
81 + int iActionCost,
82 + LPWSTR* ppwzActionData
83 + );
84 +
85 +
86 +// function definitions
87 +
88 +void CpiApplicationListFree(
89 + CPI_APPLICATION_LIST* pList
90 + )
91 +{
92 + CPI_APPLICATION* pItm = pList->pFirst;
93 +
94 + while (pItm)
95 + {
96 + CPI_APPLICATION* pDelete = pItm;
97 + pItm = pItm->pNext;
98 + FreeApplication(pDelete);
99 + }
100 +}
101 +
102 +HRESULT CpiApplicationsRead(
103 + CPI_PARTITION_LIST* pPartList,
104 + CPI_APPLICATION_LIST* pAppList
105 + )
106 +{
107 + HRESULT hr = S_OK;
108 + UINT er = ERROR_SUCCESS;
109 +
110 + int iVersionNT = 0;
111 +
112 + PMSIHANDLE hView, hRec;
113 +
114 + CPI_APPLICATION* pItm = NULL;
115 + LPWSTR pwzData = NULL;
116 + BOOL fMatchingArchitecture = FALSE;
117 +
118 + // get NT version
119 + hr = WcaGetIntProperty(L"VersionNT", &iVersionNT);
120 + ExitOnFailure(hr, "Failed to get VersionNT property");
121 +
122 + // loop through all applications
123 + hr = WcaOpenExecuteView(vcsApplicationQuery, &hView);
124 + ExitOnFailure(hr, "Failed to execute view on ComPlusApplication table");
125 +
126 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
127 + {
128 + // get component
129 + hr = WcaGetRecordString(hRec, aqComponent, &pwzData);
130 + ExitOnFailure(hr, "Failed to get component");
131 +
132 + // check if the component is our processor architecture
133 + if (pwzData && *pwzData)
134 + {
135 + hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
136 + ExitOnFailure(hr, "Failed to get component architecture.");
137 +
138 + if (!fMatchingArchitecture)
139 + {
140 + continue; // not the same architecture, ignore
141 + }
142 + }
143 +
144 + // create entry
145 + pItm = (CPI_APPLICATION*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_APPLICATION));
146 + if (!pItm)
147 + ExitFunction1(hr = E_OUTOFMEMORY);
148 +
149 + // get component install state
150 + if (pwzData && *pwzData)
151 + {
152 + pItm->fHasComponent = TRUE;
153 +
154 + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
155 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
156 + }
157 +
158 + // get key
159 + hr = WcaGetRecordString(hRec, aqApplication, &pwzData);
160 + ExitOnFailure(hr, "Failed to get key");
161 + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
162 +
163 + // get partition
164 + if (502 <= iVersionNT)
165 + {
166 + hr = WcaGetRecordString(hRec, aqPartition, &pwzData);
167 + ExitOnFailure(hr, "Failed to get partition");
168 +
169 + if (pwzData && *pwzData)
170 + {
171 + hr = CpiPartitionFindByKey(pPartList, pwzData, &pItm->pPartition);
172 + ExitOnFailure(hr, "Failed to find partition, key: %S", pwzData);
173 + }
174 + }
175 +
176 + // get id
177 + hr = WcaGetRecordFormattedString(hRec, aqID, &pwzData);
178 + ExitOnFailure(hr, "Failed to get id");
179 +
180 + if (pwzData && *pwzData)
181 + {
182 + hr = PcaGuidToRegFormat(pwzData, pItm->wzID, countof(pItm->wzID));
183 + ExitOnFailure(hr, "Failed to parse id guid value, key: %S, value: '%S'", pItm->wzKey, pwzData);
184 + }
185 +
186 + // get name
187 + hr = WcaGetRecordFormattedString(hRec, aqName, &pwzData);
188 + ExitOnFailure(hr, "Failed to get name");
189 + StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
190 +
191 + // if application is a locater, either an id or a name must be provided
192 + if (!pItm->fHasComponent && !*pItm->wzID && !*pItm->wzName)
193 + ExitOnFailure(hr = E_FAIL, "An application locater must have either an id or a name associated, key: %S", pItm->wzKey);
194 +
195 + // if application is not a locater, an name must be provided
196 + if (pItm->fHasComponent && !*pItm->wzName)
197 + ExitOnFailure(hr = E_FAIL, "An application must have a name associated, key: %S", pItm->wzKey);
198 +
199 + // get properties
200 + if (CpiTableExists(cptComPlusApplicationProperty) && pItm->fHasComponent)
201 + {
202 + hr = CpiPropertiesRead(vcsApplicationPropertyQuery, pItm->wzKey, pdlApplicationProperties, &pItm->pProperties, &pItm->iPropertyCount);
203 + ExitOnFailure(hr, "Failed to get properties");
204 + }
205 +
206 + // set references & increment counters
207 + if (pItm->fHasComponent)
208 + {
209 + if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
210 + {
211 + if (pItm->pPartition)
212 + CpiPartitionAddReferenceInstall(pItm->pPartition);
213 + pAppList->iInstallCount++;
214 + }
215 + if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
216 + {
217 + if (pItm->pPartition)
218 + CpiPartitionAddReferenceUninstall(pItm->pPartition);
219 + pAppList->iUninstallCount++;
220 + }
221 + }
222 +
223 + // add entry
224 + if (pAppList->pFirst)
225 + pItm->pNext = pAppList->pFirst;
226 + pAppList->pFirst = pItm;
227 + pItm = NULL;
228 + }
229 +
230 + if (E_NOMOREITEMS == hr)
231 + hr = S_OK;
232 +
233 +LExit:
234 + // clean up
235 + if (pItm)
236 + FreeApplication(pItm);
237 +
238 + ReleaseStr(pwzData);
239 +
240 + return hr;
241 +}
242 +
243 +HRESULT CpiApplicationsVerifyInstall(
244 + CPI_APPLICATION_LIST* pList
245 + )
246 +{
247 + HRESULT hr = S_OK;
248 + UINT er = ERROR_SUCCESS;
249 +
250 + ICatalogObject* piAppObj = NULL;
251 +
252 + for (CPI_APPLICATION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
253 + {
254 + // referenced locaters or applications that are being installed
255 + if (!pItm->fReferencedForInstall && !(pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction)))
256 + continue;
257 +
258 + // if the application is referensed and is not a locater, it must be installed
259 + if (pItm->fReferencedForInstall && pItm->fHasComponent && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction))
260 + MessageExitOnFailure(hr = E_FAIL, msierrComPlusApplicationDependency, "An application is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey);
261 +
262 + // application is supposed to exist
263 + if (!pItm->fHasComponent || CpiIsInstalled(pItm->isInstalled))
264 + {
265 + // get collection object for application
266 + hr = FindObjectForApplication(pItm, 0 != *pItm->wzID, 0 == *pItm->wzID, &piAppObj);
267 + ExitOnFailure(hr, "Failed to find collection object for application");
268 +
269 + // if the application was found
270 + if (S_OK == hr)
271 + {
272 + // if we don't have an id, copy id from object
273 + if (!*pItm->wzID)
274 + {
275 + hr = CpiGetKeyForObject(piAppObj, pItm->wzID, countof(pItm->wzID));
276 + ExitOnFailure(hr, "Failed to get id");
277 + }
278 + }
279 +
280 + // if the application was not found
281 + else
282 + {
283 + // if the application is a locater, this is an error
284 + if (!pItm->fHasComponent)
285 + MessageExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), msierrComPlusApplicationNotFound, "An application required by this installation was not found, key: %S", pItm->wzKey);
286 +
287 + // create a new id if one is missing
288 + if (!*pItm->wzID)
289 + {
290 + hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
291 + ExitOnFailure(hr, "Failed to create id");
292 + }
293 + }
294 + }
295 +
296 + // application is supposed to be created
297 + else
298 + {
299 + // check for conflicts
300 + do {
301 + if (*pItm->wzID)
302 + {
303 + // find applications with conflicting id
304 + hr = FindObjectForApplication(pItm, TRUE, FALSE, &piAppObj);
305 + ExitOnFailure(hr, "Failed to find collection object for application");
306 +
307 + if (S_FALSE == hr)
308 + {
309 + // find applications with conflicting name
310 + hr = FindObjectForApplication(pItm, FALSE, TRUE, &piAppObj);
311 + ExitOnFailure(hr, "Failed to find collection object for application");
312 +
313 + if (S_OK == hr)
314 + // "A application with a conflictiong name exists. retry cancel"
315 + er = WcaErrorMessage(msierrComPlusApplicationNameConflict, hr, INSTALLMESSAGE_ERROR | MB_RETRYCANCEL, 0);
316 + else
317 + break; // no conflicting entry found, break loop
318 + }
319 + else
320 + // "A application with a conflicting id exists. abort retry ignore"
321 + er = WcaErrorMessage(msierrComPlusApplicationIdConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
322 + }
323 + else
324 + {
325 + // find applications with conflicting name
326 + hr = FindObjectForApplication(pItm, FALSE, TRUE, &piAppObj);
327 + ExitOnFailure(hr, "Failed to find collection object for application");
328 +
329 + if (S_OK == hr)
330 + // "A subscription with a conflictiong name exists. abort retry ignore"
331 + er = WcaErrorMessage(msierrComPlusApplicationNameConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
332 + else
333 + break; // no conflicting entry found, break loop
334 + }
335 +
336 + switch (er)
337 + {
338 + case IDCANCEL:
339 + case IDABORT:
340 + ExitOnFailure(hr = E_FAIL, "An application with a conflictiong name or id exists, key: %S", pItm->wzKey);
341 + break;
342 + case IDRETRY:
343 + break;
344 + case IDIGNORE:
345 + default:
346 + // if we don't have an id, copy id from object
347 + if (!*pItm->wzID)
348 + {
349 + hr = CpiGetKeyForObject(piAppObj, pItm->wzID, countof(pItm->wzID));
350 + ExitOnFailure(hr, "Failed to get id");
351 + }
352 + hr = S_FALSE; // indicate that this is not a conflict
353 + }
354 + } while (S_OK == hr); // hr = S_FALSE if we don't have any conflicts
355 +
356 + // create a new id if one is missing
357 + if (!*pItm->wzID)
358 + {
359 + hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
360 + ExitOnFailure(hr, "Failed to create id");
361 + }
362 + }
363 +
364 + // clean up
365 + ReleaseNullObject(piAppObj);
366 + }
367 +
368 + hr = S_OK;
369 +
370 +LExit:
371 + // clean up
372 + ReleaseObject(piAppObj);
373 +
374 + return hr;
375 +}
376 +
377 +HRESULT CpiApplicationsVerifyUninstall(
378 + CPI_APPLICATION_LIST* pList
379 + )
380 +{
381 + HRESULT hr = S_OK;
382 + ICatalogObject* piAppObj = NULL;
383 +
384 + for (CPI_APPLICATION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
385 + {
386 + // referenced locaters or applications that are being installed
387 + if (!pItm->fReferencedForUninstall && !(pItm->fHasComponent && WcaIsUninstalling(pItm->isInstalled, pItm->isAction)))
388 + continue;
389 +
390 + // get collection object for application
391 + hr = FindObjectForApplication(pItm, 0 != *pItm->wzID, 0 == *pItm->wzID, &piAppObj);
392 + ExitOnFailure(hr, "Failed to find collection object for application");
393 +
394 + // if the application was found
395 + if (S_OK == hr)
396 + {
397 + // if we don't have an id, copy id from object
398 + if (!*pItm->wzID)
399 + {
400 + hr = CpiGetKeyForObject(piAppObj, pItm->wzID, countof(pItm->wzID));
401 + ExitOnFailure(hr, "Failed to get id");
402 + }
403 + }
404 +
405 + // if the application was not found
406 + else
407 + {
408 + pItm->fObjectNotFound = TRUE;
409 + if (pItm->fHasComponent)
410 + pList->iUninstallCount--; // elements with the fObjectNotFound flag set will not be scheduled for uninstall
411 + }
412 +
413 + // clean up
414 + ReleaseNullObject(piAppObj);
415 + }
416 +
417 + hr = S_OK;
418 +
419 +LExit:
420 + // clean up
421 + ReleaseObject(piAppObj);
422 +
423 + return hr;
424 +}
425 +
426 +void CpiApplicationAddReferenceInstall(
427 + CPI_APPLICATION* pItm
428 + )
429 +{
430 + pItm->fReferencedForInstall = TRUE;
431 + if (pItm->pPartition)
432 + CpiPartitionAddReferenceInstall(pItm->pPartition);
433 +}
434 +
435 +void CpiApplicationAddReferenceUninstall(
436 + CPI_APPLICATION* pItm
437 + )
438 +{
439 + pItm->fReferencedForUninstall = TRUE;
440 + if (pItm->pPartition)
441 + CpiPartitionAddReferenceUninstall(pItm->pPartition);
442 +}
443 +
444 +HRESULT CpiApplicationsInstall(
445 + CPI_APPLICATION_LIST* pList,
446 + int iRunMode,
447 + LPWSTR* ppwzActionData,
448 + int* piProgress
449 + )
450 +{
451 + HRESULT hr = S_OK;
452 +
453 + int iActionType;
454 +
455 + // add action text
456 + hr = CpiAddActionTextToActionData(L"CreateComPlusApplications", ppwzActionData);
457 + ExitOnFailure(hr, "Failed to add action text to custom action data");
458 +
459 + // add applicaton count to action data
460 + hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData);
461 + ExitOnFailure(hr, "Failed to add count to custom action data");
462 +
463 + // add applications to custom action data
464 + for (CPI_APPLICATION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
465 + {
466 + // applications that are being installed only
467 + if (!pItm->fHasComponent || !WcaIsInstalling(pItm->isInstalled, pItm->isAction))
468 + continue;
469 +
470 + // action type
471 + if (rmRollback == iRunMode)
472 + {
473 + if (CpiIsInstalled(pItm->isInstalled))
474 + iActionType = atNoOp;
475 + else
476 + iActionType = atRemove;
477 + }
478 + else
479 + iActionType = atCreate;
480 +
481 + // add to action data
482 + hr = AddApplicationToActionData(pItm, iActionType, COST_APPLICATION_CREATE, ppwzActionData);
483 + ExitOnFailure(hr, "Failed to add applicaton to custom action data, key: %S", pItm->wzKey);
484 + }
485 +
486 + // add progress tics
487 + if (piProgress)
488 + *piProgress += COST_APPLICATION_CREATE * pList->iInstallCount;
489 +
490 + hr = S_OK;
491 +
492 +LExit:
493 + return hr;
494 +}
495 +
496 +HRESULT CpiApplicationsUninstall(
497 + CPI_APPLICATION_LIST* pList,
498 + int iRunMode,
499 + LPWSTR* ppwzActionData,
500 + int* piProgress
501 + )
502 +{
503 + HRESULT hr = S_OK;
504 +
505 + int iActionType;
506 +
507 + // add action text
508 + hr = CpiAddActionTextToActionData(L"RemoveComPlusApplications", ppwzActionData);
509 + ExitOnFailure(hr, "Failed to add action text to custom action data");
510 +
511 + // add applicaton count to action data
512 + hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
513 + ExitOnFailure(hr, "Failed to add count to custom action data");
514 +
515 + // add applications to custom action data
516 + for (CPI_APPLICATION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
517 + {
518 + // applications that are being uninstalled only
519 + if (!pItm->fHasComponent || !WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
520 + continue;
521 +
522 + // action type
523 + if (rmRollback == iRunMode)
524 + iActionType = atCreate;
525 + else
526 + iActionType = atRemove;
527 +
528 + // add to action data
529 + hr = AddApplicationToActionData(pItm, iActionType, COST_APPLICATION_DELETE, ppwzActionData);
530 + ExitOnFailure(hr, "Failed to add applicaton to custom action data, key: %S", pItm->wzKey);
531 + }
532 +
533 + // add progress tics
534 + if (piProgress)
535 + *piProgress += COST_APPLICATION_DELETE * pList->iUninstallCount;
536 +
537 + hr = S_OK;
538 +
539 +LExit:
540 + return hr;
541 +}
542 +
543 +HRESULT CpiApplicationFindByKey(
544 + CPI_APPLICATION_LIST* pList,
545 + LPCWSTR pwzKey,
546 + CPI_APPLICATION** ppApp
547 + )
548 +{
549 + for (CPI_APPLICATION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
550 + {
551 + if (0 == lstrcmpW(pItm->wzKey, pwzKey))
552 + {
553 + *ppApp = pItm;
554 + return S_OK;
555 + }
556 + }
557 +
558 + return S_FALSE;
559 +}
560 +
561 +HRESULT CpiGetRolesCollForApplication(
562 + CPI_APPLICATION* pApp,
563 + ICatalogCollection** ppiRolesColl
564 + )
565 +{
566 + HRESULT hr = S_OK;
567 +
568 + ICatalogCollection* piAppColl = NULL;
569 + ICatalogObject* piAppObj = NULL;
570 +
571 + // if a previous attempt to locate the collection object failed
572 + if (pApp->fObjectNotFound)
573 + ExitFunction1(hr = S_FALSE);
574 +
575 + // get applications collection
576 + if (!pApp->piRolesColl)
577 + {
578 + // get applications collection
579 + if (pApp->pPartition)
580 + hr = CpiGetApplicationsCollForPartition(pApp->pPartition, &piAppColl);
581 + else
582 + hr = CpiGetApplicationsCollection(&piAppColl);
583 + ExitOnFailure(hr, "Failed to get applications collection");
584 +
585 + if (S_FALSE == hr)
586 + ExitFunction(); // exit with hr = S_FALSE
587 +
588 + // find application object
589 + hr = CpiFindCollectionObject(piAppColl, pApp->wzID, *pApp->wzID ? NULL : pApp->wzName, &piAppObj);
590 + ExitOnFailure(hr, "Failed to find application object");
591 +
592 + if (S_FALSE == hr)
593 + ExitFunction(); // exit with hr = S_FALSE
594 +
595 + // get roles collection
596 + hr = CpiGetCatalogCollection(piAppColl, piAppObj, L"Roles", &pApp->piRolesColl);
597 + ExitOnFailure(hr, "Failed to get roles collection");
598 + }
599 +
600 + // return value
601 + *ppiRolesColl = pApp->piRolesColl;
602 + (*ppiRolesColl)->AddRef();
603 +
604 + hr = S_OK;
605 +
606 +LExit:
607 + // clean up
608 + ReleaseObject(piAppColl);
609 + ReleaseObject(piAppObj);
610 +
611 + return hr;
612 +}
613 +
614 +HRESULT CpiGetComponentsCollForApplication(
615 + CPI_APPLICATION* pApp,
616 + ICatalogCollection** ppiCompsColl
617 + )
618 +{
619 + HRESULT hr = S_OK;
620 +
621 + ICatalogCollection* piAppColl = NULL;
622 + ICatalogObject* piAppObj = NULL;
623 +
624 + // if a previous attempt to locate the collection object failed
625 + if (pApp->fObjectNotFound)
626 + ExitFunction1(hr = S_FALSE);
627 +
628 + // get applications collection
629 + if (!pApp->piCompsColl)
630 + {
631 + // get applications collection
632 + if (pApp->pPartition)
633 + hr = CpiGetApplicationsCollForPartition(pApp->pPartition, &piAppColl);
634 + else
635 + hr = CpiGetApplicationsCollection(&piAppColl);
636 + ExitOnFailure(hr, "Failed to get applications collection");
637 +
638 + if (S_FALSE == hr)
639 + ExitFunction(); // exit with hr = S_FALSE
640 +
641 + // find application object
642 + hr = CpiFindCollectionObject(piAppColl, pApp->wzID, *pApp->wzID ? NULL : pApp->wzName, &piAppObj);
643 + ExitOnFailure(hr, "Failed to find application object");
644 +
645 + if (S_FALSE == hr)
646 + ExitFunction(); // exit with hr = S_FALSE
647 +
648 + // get roles collection
649 + hr = CpiGetCatalogCollection(piAppColl, piAppObj, L"Components", &pApp->piCompsColl);
650 + ExitOnFailure(hr, "Failed to get components collection");
651 + }
652 +
653 + // return value
654 + *ppiCompsColl = pApp->piCompsColl;
655 + (*ppiCompsColl)->AddRef();
656 +
657 + hr = S_OK;
658 +
659 +LExit:
660 + // clean up
661 + ReleaseObject(piAppColl);
662 + ReleaseObject(piAppObj);
663 +
664 + return hr;
665 +}
666 +
667 +
668 +// helper function definitions
669 +
670 +static void FreeApplication(
671 + CPI_APPLICATION* pItm
672 + )
673 +{
674 + if (pItm->pProperties)
675 + CpiPropertiesFreeList(pItm->pProperties);
676 +
677 + ReleaseObject(pItm->piRolesColl);
678 + ReleaseObject(pItm->piCompsColl);
679 +
680 + ::HeapFree(::GetProcessHeap(), 0, pItm);
681 +}
682 +
683 +static HRESULT FindObjectForApplication(
684 + CPI_APPLICATION* pItm,
685 + BOOL fFindId,
686 + BOOL fFindName,
687 + ICatalogObject** ppiAppObj
688 + )
689 +{
690 + HRESULT hr = S_OK;
691 +
692 + ICatalogCollection* piAppColl = NULL;
693 +
694 + // get applications collection
695 + if (pItm->pPartition)
696 + hr = CpiGetApplicationsCollForPartition(pItm->pPartition, &piAppColl);
697 + else
698 + hr = CpiGetApplicationsCollection(&piAppColl);
699 + ExitOnFailure(hr, "Failed to get applications collection");
700 +
701 + if (S_FALSE == hr)
702 + ExitFunction(); // exit with hr = S_FALSE
703 +
704 + // find application object
705 + hr = CpiFindCollectionObject(piAppColl, fFindId ? pItm->wzID : NULL, fFindName ? pItm->wzName : NULL, ppiAppObj);
706 + ExitOnFailure(hr, "Failed to find application object");
707 +
708 + // exit with hr from CpiFindCollectionObject()
709 +
710 +LExit:
711 + // clean up
712 + ReleaseObject(piAppColl);
713 +
714 + return hr;
715 +}
716 +
717 +static HRESULT AddApplicationToActionData(
718 + CPI_APPLICATION* pItm,
719 + int iActionType,
720 + int iActionCost,
721 + LPWSTR* ppwzActionData
722 + )
723 +{
724 + HRESULT hr = S_OK;
725 +
726 + // add action information to custom action data
727 + hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
728 + ExitOnFailure(hr, "Failed to add action type to custom action data");
729 + hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
730 + ExitOnFailure(hr, "Failed to add action cost to custom action data");
731 +
732 + // add application information to custom action data
733 + hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
734 + ExitOnFailure(hr, "Failed to add application key to custom action data");
735 + hr = WcaWriteStringToCaData(pItm->wzID, ppwzActionData);
736 + ExitOnFailure(hr, "Failed to add application id to custom action data");
737 + hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData);
738 + ExitOnFailure(hr, "Failed to add application name to custom action data");
739 +
740 + // add partition information to custom action data
741 + hr = WcaWriteStringToCaData(pItm->pPartition ? pItm->pPartition->wzID : L"", ppwzActionData);
742 + ExitOnFailure(hr, "Failed to add partition id to custom action data");
743 +
744 + // add properties to custom action data
745 + hr = CpiAddPropertiesToActionData(atCreate == iActionType ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
746 + ExitOnFailure(hr, "Failed to add properties to custom action data");
747 +
748 + hr = S_OK;
749 +
750 +LExit:
751 + return hr;
752 +}
src/ca/cpappsched.h new
+83
@@ -0,0 +1,83 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +struct CPI_APPLICATION
6 +{
7 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
8 + WCHAR wzID[CPI_MAX_GUID + 1];
9 + WCHAR wzName[MAX_DARWIN_COLUMN + 1];
10 +
11 + int iPropertyCount;
12 + CPI_PROPERTY* pProperties;
13 +
14 + BOOL fHasComponent;
15 + BOOL fReferencedForInstall;
16 + BOOL fReferencedForUninstall;
17 + BOOL fObjectNotFound;
18 +
19 + INSTALLSTATE isInstalled, isAction;
20 +
21 + CPI_PARTITION* pPartition;
22 +
23 + ICatalogCollection* piRolesColl;
24 + ICatalogCollection* piCompsColl;
25 +
26 + CPI_APPLICATION* pNext;
27 +};
28 +
29 +struct CPI_APPLICATION_LIST
30 +{
31 + CPI_APPLICATION* pFirst;
32 +
33 + int iInstallCount;
34 + int iUninstallCount;
35 +};
36 +
37 +
38 +// function prototypes
39 +
40 +void CpiApplicationListFree(
41 + CPI_APPLICATION_LIST* pList
42 + );
43 +HRESULT CpiApplicationsRead(
44 + CPI_PARTITION_LIST* pPartList,
45 + CPI_APPLICATION_LIST* pAppList
46 + );
47 +HRESULT CpiApplicationsVerifyInstall(
48 + CPI_APPLICATION_LIST* pList
49 + );
50 +HRESULT CpiApplicationsVerifyUninstall(
51 + CPI_APPLICATION_LIST* pList
52 + );
53 +void CpiApplicationAddReferenceInstall(
54 + CPI_APPLICATION* pItm
55 + );
56 +void CpiApplicationAddReferenceUninstall(
57 + CPI_APPLICATION* pItm
58 + );
59 +HRESULT CpiApplicationsInstall(
60 + CPI_APPLICATION_LIST* pList,
61 + int iRunMode,
62 + LPWSTR* ppwzActionData,
63 + int* piProgress
64 + );
65 +HRESULT CpiApplicationsUninstall(
66 + CPI_APPLICATION_LIST* pList,
67 + int iRunMode,
68 + LPWSTR* ppwzActionData,
69 + int* piProgress
70 + );
71 +HRESULT CpiApplicationFindByKey(
72 + CPI_APPLICATION_LIST* pList,
73 + LPCWSTR pwzKey,
74 + CPI_APPLICATION** ppApp
75 + );
76 +HRESULT CpiGetRolesCollForApplication(
77 + CPI_APPLICATION* pApp,
78 + ICatalogCollection** ppiRolesColl
79 + );
80 +HRESULT CpiGetComponentsCollForApplication(
81 + CPI_APPLICATION* pApp,
82 + ICatalogCollection** ppiCompsColl
83 + );
src/ca/cpasmexec.cpp new
+1888
@@ -0,0 +1,1888 @@
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 +// GAC related declarations
7 +
8 +typedef struct _FUSION_INSTALL_REFERENCE_
9 +{
10 + DWORD cbSize;
11 + DWORD dwFlags;
12 + GUID guidScheme;
13 + LPCWSTR szIdentifier;
14 + LPCWSTR szNonCannonicalData;
15 +} FUSION_INSTALL_REFERENCE;
16 +
17 +typedef struct _FUSION_INSTALL_REFERENCE_ *LPFUSION_INSTALL_REFERENCE;
18 +
19 +typedef const FUSION_INSTALL_REFERENCE *LPCFUSION_INSTALL_REFERENCE;
20 +
21 +typedef struct _ASSEMBLY_INFO
22 +{
23 + ULONG cbAssemblyInfo;
24 + DWORD dwAssemblyFlags;
25 + ULARGE_INTEGER uliAssemblySizeInKB;
26 + LPWSTR pszCurrentAssemblyPathBuf;
27 + ULONG cchBuf;
28 +} ASSEMBLY_INFO;
29 +
30 +typedef interface IAssemblyCacheItem IAssemblyCacheItem;
31 +
32 +MIDL_INTERFACE("e707dcde-d1cd-11d2-bab9-00c04f8eceae")
33 +IAssemblyCache : public IUnknown
34 +{
35 +public:
36 + virtual HRESULT STDMETHODCALLTYPE UninstallAssembly(
37 + /* [in] */ DWORD dwFlags,
38 + /* [in] */ LPCWSTR pszAssemblyName,
39 + /* [in] */ LPCFUSION_INSTALL_REFERENCE pRefData,
40 + /* [optional][out] */ ULONG *pulDisposition) = 0;
41 +
42 + virtual HRESULT STDMETHODCALLTYPE QueryAssemblyInfo(
43 + /* [in] */ DWORD dwFlags,
44 + /* [in] */ LPCWSTR pszAssemblyName,
45 + /* [out][in] */ ASSEMBLY_INFO *pAsmInfo) = 0;
46 +
47 + virtual HRESULT STDMETHODCALLTYPE CreateAssemblyCacheItem(
48 + /* [in] */ DWORD dwFlags,
49 + /* [in] */ PVOID pvReserved,
50 + /* [out] */ IAssemblyCacheItem **ppAsmItem,
51 + /* [optional][in] */ LPCWSTR pszAssemblyName) = 0;
52 +
53 + virtual HRESULT STDMETHODCALLTYPE CreateAssemblyScavenger(
54 + /* [out] */ IUnknown **ppUnkReserved) = 0;
55 +
56 + virtual HRESULT STDMETHODCALLTYPE InstallAssembly(
57 + /* [in] */ DWORD dwFlags,
58 + /* [in] */ LPCWSTR pszManifestFilePath,
59 + /* [in] */ LPCFUSION_INSTALL_REFERENCE pRefData) = 0;
60 +};
61 +
62 +typedef HRESULT (__stdcall *LoadLibraryShimFunc)(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll);
63 +typedef HRESULT (__stdcall *CreateAssemblyCacheFunc)(IAssemblyCache **ppAsmCache, DWORD dwReserved);
64 +
65 +
66 +// RegistrationHelper related declarations
67 +
68 +static const GUID CLSID_RegistrationHelper =
69 + { 0x89a86e7b, 0xc229, 0x4008, { 0x9b, 0xaa, 0x2f, 0x5c, 0x84, 0x11, 0xd7, 0xe0 } };
70 +
71 +enum eInstallationFlags {
72 + ifConfigureComponentsOnly = 16,
73 + ifFindOrCreateTargetApplication = 4,
74 + ifExpectExistingTypeLib = 1
75 +};
76 +
77 +
78 +// private constants
79 +
80 +enum eAssemblyAttributes
81 +{
82 + aaEventClass = (1 << 0),
83 + aaDotNetAssembly = (1 << 1),
84 + aaPathFromGAC = (1 << 2),
85 + aaRunInCommit = (1 << 3)
86 +};
87 +
88 +
89 +// private structs
90 +
91 +struct CPI_ROLE_ASSIGNMENT
92 +{
93 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
94 + WCHAR wzRoleName[MAX_DARWIN_COLUMN + 1];
95 +
96 + CPI_ROLE_ASSIGNMENT* pNext;
97 +};
98 +
99 +struct CPI_METHOD
100 +{
101 + WCHAR wzIndex[11 + 1];
102 + WCHAR wzName[MAX_DARWIN_COLUMN + 1];
103 +
104 + CPI_PROPERTY* pPropertyList;
105 + CPI_ROLE_ASSIGNMENT* pRoleAssignmentList;
106 +
107 + CPI_METHOD* pNext;
108 +};
109 +
110 +struct CPI_INTERFACE
111 +{
112 + WCHAR wzIID[CPI_MAX_GUID + 1];
113 +
114 + CPI_PROPERTY* pPropertyList;
115 + CPI_ROLE_ASSIGNMENT* pRoleAssignmentList;
116 + CPI_METHOD* pMethodList;
117 +
118 + CPI_INTERFACE* pNext;
119 +};
120 +
121 +struct CPI_COMPONENT
122 +{
123 + WCHAR wzCLSID[CPI_MAX_GUID + 1];
124 +
125 + CPI_PROPERTY* pPropertyList;
126 + CPI_ROLE_ASSIGNMENT* pRoleAssignmentList;
127 + CPI_INTERFACE* pInterfaceList;
128 +
129 + CPI_COMPONENT* pNext;
130 +};
131 +
132 +struct CPI_ASSEMBLY_ATTRIBUTES
133 +{
134 + int iActionType;
135 + int iActionCost;
136 + LPWSTR pwzKey;
137 + LPWSTR pwzAssemblyName;
138 + LPWSTR pwzDllPath;
139 + LPWSTR pwzTlbPath;
140 + LPWSTR pwzPSDllPath;
141 + LPWSTR pwzAppID;
142 + LPWSTR pwzPartID;
143 + int iAttributes;
144 + CPI_COMPONENT* pCompList;
145 +};
146 +
147 +struct CPI_ROLE_ASSIGNMENTS_ATTRIBUTES
148 +{
149 + int iActionType;
150 + int iActionCost;
151 + LPWSTR pwzKey;
152 + LPWSTR pwzAppID;
153 + LPWSTR pwzPartID;
154 + int iRoleCount;
155 + CPI_COMPONENT* pCompList;
156 +};
157 +
158 +
159 +// prototypes for private helper functions
160 +
161 +static HRESULT RegisterAssembly(
162 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
163 + );
164 +static HRESULT UnregisterAssembly(
165 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
166 + );
167 +static void InitAssemblyExec();
168 +static void UninitAssemblyExec();
169 +static HRESULT GetRegistrationHelper(
170 + IDispatch** ppiRegHlp
171 + );
172 +static HRESULT GetAssemblyCacheObject(
173 + IAssemblyCache** ppAssemblyCache
174 + );
175 +static HRESULT GetAssemblyPathFromGAC(
176 + LPCWSTR pwzAssemblyName,
177 + LPWSTR* ppwzAssemblyPath
178 + );
179 +static HRESULT RegisterDotNetAssembly(
180 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
181 + );
182 +static HRESULT RegisterNativeAssembly(
183 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
184 + );
185 +static HRESULT UnregisterDotNetAssembly(
186 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
187 + );
188 +static HRESULT RemoveComponents(
189 + ICatalogCollection* piCompColl,
190 + CPI_COMPONENT* pCompList
191 + );
192 +static HRESULT ReadAssemblyAttributes(
193 + LPWSTR* ppwzData,
194 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
195 + );
196 +static void FreeAssemblyAttributes(
197 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
198 + );
199 +static HRESULT ReadRoleAssignmentsAttributes(
200 + LPWSTR* ppwzData,
201 + CPI_ROLE_ASSIGNMENTS_ATTRIBUTES* pAttrs
202 + );
203 +static void FreeRoleAssignmentsAttributes(
204 + CPI_ROLE_ASSIGNMENTS_ATTRIBUTES* pAttrs
205 + );
206 +static HRESULT ConfigureComponents(
207 + LPCWSTR pwzPartID,
208 + LPCWSTR pwzAppID,
209 + CPI_COMPONENT* pCompList,
210 + BOOL fCreate,
211 + BOOL fProgress
212 + );
213 +static HRESULT ConfigureInterfaces(
214 + ICatalogCollection* piCompColl,
215 + ICatalogObject* piCompObj,
216 + CPI_INTERFACE* pIntfList,
217 + BOOL fCreate
218 + );
219 +static HRESULT ConfigureMethods(
220 + ICatalogCollection* piIntfColl,
221 + ICatalogObject* piIntfObj,
222 + CPI_METHOD* pMethList,
223 + BOOL fCreate
224 + );
225 +static HRESULT ConfigureRoleAssignments(
226 + LPCWSTR pwzCollName,
227 + ICatalogCollection* piCompColl,
228 + ICatalogObject* piCompObj,
229 + CPI_ROLE_ASSIGNMENT* pRoleList,
230 + BOOL fCreate
231 + );
232 +static HRESULT ReadComponentList(
233 + LPWSTR* ppwzData,
234 + CPI_COMPONENT** ppCompList
235 + );
236 +static HRESULT ReadInterfaceList(
237 + LPWSTR* ppwzData,
238 + CPI_INTERFACE** ppIntfList
239 + );
240 +static HRESULT ReadMethodList(
241 + LPWSTR* ppwzData,
242 + CPI_METHOD** ppMethList
243 + );
244 +static HRESULT ReadRoleAssignmentList(
245 + LPWSTR* ppwzData,
246 + CPI_ROLE_ASSIGNMENT** ppRoleList
247 + );
248 +static void FreeComponentList(
249 + CPI_COMPONENT* pList
250 + );
251 +static void FreeInterfaceList(
252 + CPI_INTERFACE* pList
253 + );
254 +static void FreeMethodList(
255 + CPI_METHOD* pList
256 + );
257 +static void FreeRoleAssignmentList(
258 + CPI_ROLE_ASSIGNMENT* pList
259 + );
260 +
261 +
262 +// variables
263 +
264 +static IDispatch* gpiRegHlp;
265 +static IAssemblyCache* gpAssemblyCache;
266 +static HMODULE ghMscoree;
267 +static HMODULE ghFusion;
268 +
269 +
270 +// function definitions
271 +
272 +HRESULT CpiConfigureAssemblies(
273 + LPWSTR* ppwzData,
274 + HANDLE hRollbackFile
275 + )
276 +{
277 + HRESULT hr = S_OK;
278 +
279 + CPI_ASSEMBLY_ATTRIBUTES attrs;
280 + ::ZeroMemory(&attrs, sizeof(attrs));
281 +
282 + // initialize
283 + InitAssemblyExec();
284 +
285 + // read action text
286 + hr = CpiActionStartMessage(ppwzData, FALSE);
287 + ExitOnFailure(hr, "Failed to send action start message");
288 +
289 + // get count
290 + int iCnt = 0;
291 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
292 + ExitOnFailure(hr, "Failed to read count");
293 +
294 + // write count to rollback file
295 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
296 + ExitOnFailure(hr, "Failed to write count to rollback file");
297 +
298 + for (int i = 0; i < iCnt; i++)
299 + {
300 + // read attributes from CustomActionData
301 + hr = ReadAssemblyAttributes(ppwzData, &attrs);
302 + ExitOnFailure(hr, "Failed to read assembly attributes");
303 +
304 + // write key to rollback file
305 + hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
306 + ExitOnFailure(hr, "Failed to write key to rollback file");
307 +
308 + // action
309 + switch (attrs.iActionType)
310 + {
311 + case atCreate:
312 + hr = RegisterAssembly(&attrs);
313 + ExitOnFailure(hr, "Failed to register assembly, key: %S", attrs.pwzKey);
314 + break;
315 + case atRemove:
316 + hr = UnregisterAssembly(&attrs);
317 + ExitOnFailure(hr, "Failed to unregister assembly, key: %S", attrs.pwzKey);
318 + break;
319 + default:
320 + hr = S_OK;
321 + break;
322 + }
323 +
324 + if (S_FALSE == hr)
325 + ExitFunction(); // aborted by user
326 +
327 + // write completion status to rollback file
328 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
329 + ExitOnFailure(hr, "Failed to write completion status to rollback file");
330 +
331 + // progress
332 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
333 + ExitOnFailure(hr, "Failed to update progress");
334 + }
335 +
336 + hr = S_OK;
337 +
338 +LExit:
339 + // clean up
340 + FreeAssemblyAttributes(&attrs);
341 +
342 + // uninitialize
343 + UninitAssemblyExec();
344 +
345 + return hr;
346 +}
347 +
348 +HRESULT CpiRollbackConfigureAssemblies(
349 + LPWSTR* ppwzData,
350 + CPI_ROLLBACK_DATA* pRollbackDataList
351 + )
352 +{
353 + HRESULT hr = S_OK;
354 +
355 + int iRollbackStatus;
356 +
357 + CPI_ASSEMBLY_ATTRIBUTES attrs;
358 + ::ZeroMemory(&attrs, sizeof(attrs));
359 +
360 + // initialize
361 + InitAssemblyExec();
362 +
363 + // read action text
364 + hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
365 + ExitOnFailure(hr, "Failed to send action start message");
366 +
367 + // get count
368 + int iCnt = 0;
369 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
370 + ExitOnFailure(hr, "Failed to read count");
371 +
372 + for (int i = 0; i < iCnt; i++)
373 + {
374 + // read attributes from CustomActionData
375 + hr = ReadAssemblyAttributes(ppwzData, &attrs);
376 + ExitOnFailure(hr, "Failed to read assembly attributes");
377 +
378 + // rollback status
379 + hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
380 +
381 + if (S_FALSE == hr)
382 + continue; // not found, nothing to rollback
383 +
384 + // action
385 + switch (attrs.iActionType)
386 + {
387 + case atCreate:
388 + hr = RegisterAssembly(&attrs);
389 + if (FAILED(hr))
390 + WcaLog(LOGMSG_STANDARD, "Failed to register assembly, hr: 0x%x, key: %S", hr, attrs.pwzKey);
391 + break;
392 + case atRemove:
393 + hr = UnregisterAssembly(&attrs);
394 + if (FAILED(hr))
395 + WcaLog(LOGMSG_STANDARD, "Failed to unregister assembly, hr: 0x%x, key: %S", hr, attrs.pwzKey);
396 + break;
397 + }
398 +
399 + // check rollback status
400 + if (0 == iRollbackStatus)
401 + continue; // operation did not complete, skip progress
402 +
403 + // progress
404 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
405 + ExitOnFailure(hr, "Failed to update progress");
406 + }
407 +
408 + hr = S_OK;
409 +
410 +LExit:
411 + // clean up
412 + FreeAssemblyAttributes(&attrs);
413 +
414 + // uninitialize
415 + UninitAssemblyExec();
416 +
417 + return hr;
418 +}
419 +
420 +HRESULT CpiConfigureRoleAssignments(
421 + LPWSTR* ppwzData,
422 + HANDLE hRollbackFile
423 + )
424 +{
425 + HRESULT hr = S_OK;
426 +
427 + CPI_ROLE_ASSIGNMENTS_ATTRIBUTES attrs;
428 + ::ZeroMemory(&attrs, sizeof(attrs));
429 +
430 + // read action text
431 + hr = CpiActionStartMessage(ppwzData, FALSE);
432 + ExitOnFailure(hr, "Failed to send action start message");
433 +
434 + // get count
435 + int iCnt = 0;
436 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
437 + ExitOnFailure(hr, "Failed to read count");
438 +
439 + // write count to rollback file
440 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
441 + ExitOnFailure(hr, "Failed to write count to rollback file");
442 +
443 + for (int i = 0; i < iCnt; i++)
444 + {
445 + // read attributes from CustomActionData
446 + hr = ReadRoleAssignmentsAttributes(ppwzData, &attrs);
447 + ExitOnFailure(hr, "Failed to read role assignments attributes");
448 +
449 + // write key to rollback file
450 + hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
451 + ExitOnFailure(hr, "Failed to write key to rollback file");
452 +
453 + // action
454 + if (atNoOp != attrs.iActionType)
455 + {
456 + hr = ConfigureComponents(attrs.pwzPartID, attrs.pwzAppID, attrs.pCompList, atCreate == attrs.iActionType, TRUE);
457 + ExitOnFailure(hr, "Failed to configure components");
458 +
459 + if (S_FALSE == hr)
460 + ExitFunction(); // aborted by user
461 + }
462 +
463 + // write completion status to rollback file
464 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
465 + ExitOnFailure(hr, "Failed to write completion status to rollback file");
466 +
467 + // progress
468 + hr = WcaProgressMessage(attrs.iActionCost * attrs.iRoleCount, FALSE);
469 + ExitOnFailure(hr, "Failed to update progress");
470 + }
471 +
472 + hr = S_OK;
473 +
474 +LExit:
475 + // clean up
476 + FreeRoleAssignmentsAttributes(&attrs);
477 +
478 + return hr;
479 +}
480 +
481 +HRESULT CpiRollbackConfigureRoleAssignments(
482 + LPWSTR* ppwzData,
483 + CPI_ROLLBACK_DATA* pRollbackDataList
484 + )
485 +{
486 + HRESULT hr = S_OK;
487 +
488 + int iRollbackStatus;
489 +
490 + CPI_ROLE_ASSIGNMENTS_ATTRIBUTES attrs;
491 + ::ZeroMemory(&attrs, sizeof(attrs));
492 +
493 + // read action text
494 + hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
495 + ExitOnFailure(hr, "Failed to send action start message");
496 +
497 + // get count
498 + int iCnt = 0;
499 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
500 + ExitOnFailure(hr, "Failed to read count");
501 +
502 + for (int i = 0; i < iCnt; i++)
503 + {
504 + // read attributes from CustomActionData
505 + hr = ReadRoleAssignmentsAttributes(ppwzData, &attrs);
506 + ExitOnFailure(hr, "Failed to read role assignments attributes");
507 +
508 + // rollback status
509 + hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
510 +
511 + if (S_FALSE == hr)
512 + continue; // not found, nothing to rollback
513 +
514 + // action
515 + if (atNoOp != attrs.iActionType)
516 + {
517 + hr = ConfigureComponents(attrs.pwzPartID, attrs.pwzAppID, attrs.pCompList, atCreate == attrs.iActionType, TRUE);
518 + ExitOnFailure(hr, "Failed to configure components");
519 +
520 + if (S_FALSE == hr)
521 + ExitFunction(); // aborted by user
522 + }
523 +
524 + // check rollback status
525 + if (0 == iRollbackStatus)
526 + continue; // operation did not complete, skip progress
527 +
528 + // progress
529 + hr = WcaProgressMessage(attrs.iActionCost * attrs.iRoleCount, FALSE);
530 + ExitOnFailure(hr, "Failed to update progress");
531 + }
532 +
533 + hr = S_OK;
534 +
535 +LExit:
536 + // clean up
537 + FreeRoleAssignmentsAttributes(&attrs);
538 +
539 + return hr;
540 +}
541 +
542 +
543 +// helper function definitions
544 +
545 +static HRESULT RegisterAssembly(
546 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
547 + )
548 +{
549 + HRESULT hr = S_OK;
550 +
551 + // progress message
552 + hr = CpiActionDataMessage(1, (pAttrs->iAttributes & aaPathFromGAC) ? pAttrs->pwzAssemblyName : pAttrs->pwzDllPath);
553 + ExitOnFailure(hr, "Failed to send progress messages");
554 +
555 + if (S_FALSE == hr)
556 + ExitFunction(); // aborted by user
557 +
558 + // log
559 + WcaLog(LOGMSG_VERBOSE, "Registering assembly, key: %S", pAttrs->pwzKey);
560 +
561 + // extract path from GAC
562 + if (pAttrs->iAttributes & aaPathFromGAC)
563 + {
564 + hr = GetAssemblyPathFromGAC(pAttrs->pwzAssemblyName, &pAttrs->pwzDllPath);
565 + if (S_FALSE == hr)
566 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
567 + ExitOnFailure(hr, "Failed to get path for assembly from GAC");
568 +
569 + // log
570 + WcaLog(LOGMSG_VERBOSE, "Assembly path extracted from GAC, key: %S, path: '%S'", pAttrs->pwzKey, pAttrs->pwzDllPath);
571 + }
572 +
573 + // .net assembly
574 + if (pAttrs->iAttributes & aaDotNetAssembly)
575 + {
576 + hr = RegisterDotNetAssembly(pAttrs);
577 + ExitOnFailure(hr, "Failed to register .NET assembly");
578 + }
579 +
580 + // native assembly
581 + else
582 + {
583 + hr = RegisterNativeAssembly(pAttrs);
584 + ExitOnFailure(hr, "Failed to register native assembly");
585 + }
586 +
587 + // configure components
588 + if (pAttrs->pCompList)
589 + {
590 + hr = ConfigureComponents(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pCompList, TRUE, FALSE);
591 + ExitOnFailure(hr, "Failed to configure components");
592 + }
593 +
594 + hr = S_OK;
595 +
596 +LExit:
597 + return hr;
598 +}
599 +
600 +static HRESULT UnregisterAssembly(
601 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
602 + )
603 +{
604 + HRESULT hr = S_OK;
605 +
606 + long lChanges = 0;
607 +
608 + ICatalogCollection* piColl = NULL;
609 + ICatalogObject* piObj = NULL;
610 +
611 + // progress message
612 + hr = CpiActionDataMessage(1, (pAttrs->iAttributes & aaPathFromGAC) ? pAttrs->pwzAssemblyName : pAttrs->pwzDllPath);
613 + ExitOnFailure(hr, "Failed to send progress messages");
614 +
615 + if (S_FALSE == hr)
616 + ExitFunction(); // aborted by user
617 +
618 + // log
619 + WcaLog(LOGMSG_VERBOSE, "Unregistering assembly, key: %S", pAttrs->pwzKey);
620 +
621 + // extract path from GAC
622 + if (pAttrs->iAttributes & aaPathFromGAC)
623 + {
624 + hr = GetAssemblyPathFromGAC(pAttrs->pwzAssemblyName, &pAttrs->pwzDllPath);
625 + ExitOnFailure(hr, "Failed to get path for assembly from GAC");
626 +
627 + if (S_FALSE == hr)
628 + {
629 + WcaLog(LOGMSG_VERBOSE, "Unable to locate assembly in GAC, assembly will not be unregistered from COM+, key: %S", pAttrs->pwzKey);
630 + ExitFunction1(hr = S_OK);
631 + }
632 +
633 + // log
634 + WcaLog(LOGMSG_VERBOSE, "Assembly path extracted from GAC, key: %S, path: '%S'", pAttrs->pwzKey, pAttrs->pwzDllPath);
635 + }
636 +
637 + // .NET assembly
638 + if (pAttrs->iAttributes & aaDotNetAssembly)
639 + {
640 + if (pAttrs->pwzAppID && *pAttrs->pwzAppID)
641 + {
642 + // When unregistering a .net assembly using the RegistrationHelper class, and the application is
643 + // left empty after all components in the assembly are removed, the RegistrationHelper class also
644 + // attempts to remove the application for some reason. However, it does not handle the situation
645 + // when the application has its deleteable property set to false, and will simply fail if this is
646 + // the case. This is the reason we are clearing the deleatable property of the application here.
647 + //
648 + // TODO: handle rollbacks
649 +
650 + // get applications collection
651 + hr = CpiGetApplicationsCollection(pAttrs->pwzPartID, &piColl);
652 + ExitOnFailure(hr, "Failed to get applications collection");
653 +
654 + if (S_FALSE == hr)
655 + {
656 + // applications collection not found
657 + WcaLog(LOGMSG_VERBOSE, "Unable to retrieve applications collection, nothing to delete, key: %S", pAttrs->pwzKey);
658 + ExitFunction1(hr = S_OK);
659 + }
660 +
661 + // find application object
662 + hr = CpiFindCollectionObjectByStringKey(piColl, pAttrs->pwzAppID, &piObj);
663 + ExitOnFailure(hr, "Failed to find application object");
664 +
665 + if (S_FALSE == hr)
666 + {
667 + // application not found
668 + WcaLog(LOGMSG_VERBOSE, "Unable to find application object, nothing to delete, key: %S", pAttrs->pwzKey);
669 + ExitFunction1(hr = S_OK);
670 + }
671 +
672 + // reset deleteable property
673 + hr = CpiResetObjectProperty(piColl, piObj, L"Deleteable");
674 + ExitOnFailure(hr, "Failed to reset deleteable property");
675 + }
676 +
677 + // unregister assembly
678 + hr = UnregisterDotNetAssembly(pAttrs);
679 + ExitOnFailure(hr, "Failed to unregister .NET assembly");
680 + }
681 +
682 + // native assembly
683 + else
684 + {
685 + // get components collection
686 + hr = CpiGetComponentsCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, &piColl);
687 + ExitOnFailure(hr, "Failed to get components collection");
688 +
689 + if (S_FALSE == hr)
690 + {
691 + // components collection not found
692 + WcaLog(LOGMSG_VERBOSE, "Unable to retrieve components collection, nothing to delete, key: %S", pAttrs->pwzKey);
693 + ExitFunction1(hr = S_OK);
694 + }
695 +
696 + // remove components
697 + hr = RemoveComponents(piColl, pAttrs->pCompList);
698 + ExitOnFailure(hr, "Failed to get remove components");
699 +
700 + // save changes
701 + hr = piColl->SaveChanges(&lChanges);
702 + if (COMADMIN_E_OBJECTERRORS == hr)
703 + CpiLogCatalogErrorInfo();
704 + ExitOnFailure(hr, "Failed to save changes");
705 + }
706 +
707 + hr = S_OK;
708 +
709 +LExit:
710 + // clean up
711 + ReleaseObject(piColl);
712 + ReleaseObject(piObj);
713 +
714 + return hr;
715 +}
716 +
717 +static void InitAssemblyExec()
718 +{
719 + gpiRegHlp = NULL;
720 + gpAssemblyCache = NULL;
721 + ghMscoree = NULL;
722 + ghFusion = NULL;
723 +}
724 +
725 +static void UninitAssemblyExec()
726 +{
727 + ReleaseObject(gpiRegHlp);
728 + ReleaseObject(gpAssemblyCache);
729 + if (ghFusion)
730 + ::FreeLibrary(ghFusion);
731 + if (ghMscoree)
732 + ::FreeLibrary(ghMscoree);
733 +}
734 +
735 +static HRESULT GetRegistrationHelper(
736 + IDispatch** ppiRegHlp
737 + )
738 +{
739 + HRESULT hr = S_OK;
740 +
741 + if (!gpiRegHlp)
742 + {
743 + // create registration helper object
744 + hr = ::CoCreateInstance(CLSID_RegistrationHelper, NULL, CLSCTX_ALL, IID_IDispatch, (void**)&gpiRegHlp);
745 + ExitOnFailure(hr, "Failed to create registration helper object");
746 + }
747 +
748 + gpiRegHlp->AddRef();
749 + *ppiRegHlp = gpiRegHlp;
750 +
751 + hr = S_OK;
752 +
753 +LExit:
754 + return hr;
755 +}
756 +
757 +static HRESULT GetAssemblyCacheObject(
758 + IAssemblyCache** ppAssemblyCache
759 + )
760 +{
761 + HRESULT hr = S_OK;
762 +
763 + if (!gpAssemblyCache)
764 + {
765 + // mscoree.dll
766 + if (!ghMscoree)
767 + {
768 + // load mscoree.dll
769 + ghMscoree = ::LoadLibraryW(L"mscoree.dll");
770 + ExitOnNull(ghMscoree, hr, E_FAIL, "Failed to load mscoree.dll");
771 + }
772 +
773 + // fusion.dll
774 + if (!ghFusion)
775 + {
776 + // get LoadLibraryShim function address
777 + LoadLibraryShimFunc pfnLoadLibraryShim = (LoadLibraryShimFunc)::GetProcAddress(ghMscoree, "LoadLibraryShim");
778 + ExitOnNull(pfnLoadLibraryShim, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for LoadLibraryShim() function");
779 +
780 + // load fusion.dll
781 + hr = pfnLoadLibraryShim(L"fusion.dll", NULL, NULL, &ghFusion);
782 + ExitOnFailure(hr, "Failed to load fusion.dll");
783 + }
784 +
785 + // get CreateAssemblyCache function address
786 + CreateAssemblyCacheFunc pfnCreateAssemblyCache = (CreateAssemblyCacheFunc)::GetProcAddress(ghFusion, "CreateAssemblyCache");
787 + ExitOnNull(pfnCreateAssemblyCache, hr, HRESULT_FROM_WIN32(::GetLastError()), "Failed get address for CreateAssemblyCache() function");
788 +
789 + // create AssemblyCache object
790 + hr = pfnCreateAssemblyCache(&gpAssemblyCache, 0);
791 + ExitOnFailure(hr, "Failed to create AssemblyCache object");
792 + }
793 +
794 + gpAssemblyCache->AddRef();
795 + *ppAssemblyCache = gpAssemblyCache;
796 +
797 + hr = S_OK;
798 +
799 +LExit:
800 + return hr;
801 +}
802 +
803 +static HRESULT GetAssemblyPathFromGAC(
804 + LPCWSTR pwzAssemblyName,
805 + LPWSTR* ppwzAssemblyPath
806 + )
807 +{
808 + HRESULT hr = S_OK;
809 +
810 + IAssemblyCache* pAssemblyCache = NULL;
811 +
812 + ASSEMBLY_INFO assemblyInfo;
813 + WCHAR wzPathBuf[MAX_PATH];
814 +
815 + ::ZeroMemory(&assemblyInfo, sizeof(ASSEMBLY_INFO));
816 + ::ZeroMemory(wzPathBuf, countof(wzPathBuf));
817 +
818 + // get AssemblyCache object
819 + hr = GetAssemblyCacheObject(&pAssemblyCache);
820 + ExitOnFailure(hr, "Failed to get AssemblyCache object");
821 +
822 + // get assembly info
823 + assemblyInfo.cbAssemblyInfo = sizeof(ASSEMBLY_INFO);
824 + assemblyInfo.pszCurrentAssemblyPathBuf = wzPathBuf;
825 + assemblyInfo.cchBuf = countof(wzPathBuf);
826 +
827 + hr = pAssemblyCache->QueryAssemblyInfo(0, pwzAssemblyName, &assemblyInfo);
828 + if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
829 + ExitFunction1(hr = S_FALSE);
830 + ExitOnFailure(hr, "Failed to get assembly info");
831 +
832 + // copy assembly path
833 + hr = StrAllocString(ppwzAssemblyPath, wzPathBuf, 0);
834 + ExitOnFailure(hr, "Failed to copy assembly path");
835 +
836 + hr = S_OK;
837 +
838 +LExit:
839 + // clean up
840 + ReleaseObject(pAssemblyCache);
841 +
842 + return hr;
843 +}
844 +
845 +static HRESULT RegisterDotNetAssembly(
846 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
847 + )
848 +{
849 + HRESULT hr = S_OK;
850 +
851 + IDispatch* piRegHlp = NULL;
852 +
853 + DISPID dispid;
854 + BSTR bstrMember = NULL;
855 +
856 + long lInstallationFlags = 0;
857 +
858 + VARIANTARG rgvarg[5];
859 + DISPPARAMS dispparams;
860 + EXCEPINFO excepInfo;
861 +
862 + BSTR bstrPartName = NULL;
863 + BSTR bstrAppName = NULL;
864 + BSTR bstrDllPath = NULL;
865 + BSTR bstrTlbPath = NULL;
866 +
867 + ::ZeroMemory(rgvarg, sizeof(rgvarg));
868 + ::ZeroMemory(&dispparams, sizeof(dispparams));
869 + ::ZeroMemory(&excepInfo, sizeof(excepInfo));
870 +
871 + bstrMember = ::SysAllocString(L"InstallAssembly_2");
872 + ExitOnNull(bstrMember, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for method name");
873 +
874 + // create BSTRs for parameters
875 + if (pAttrs->pwzPartID && *pAttrs->pwzPartID)
876 + {
877 + bstrPartName = ::SysAllocString(pAttrs->pwzPartID);
878 + ExitOnNull(bstrPartName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for partition id");
879 + }
880 +
881 + if (pAttrs->pwzAppID && *pAttrs->pwzAppID)
882 + {
883 + bstrAppName = ::SysAllocString(pAttrs->pwzAppID);
884 + ExitOnNull(bstrAppName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for application id");
885 + }
886 +
887 + bstrDllPath = ::SysAllocString(pAttrs->pwzDllPath);
888 + ExitOnNull(bstrDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for dll path");
889 +
890 + if (pAttrs->pwzTlbPath && *pAttrs->pwzTlbPath)
891 + {
892 + bstrTlbPath = ::SysAllocString(pAttrs->pwzTlbPath);
893 + ExitOnNull(bstrTlbPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for tlb path");
894 + }
895 +
896 + // get registration helper object
897 + hr = GetRegistrationHelper(&piRegHlp);
898 + ExitOnFailure(hr, "Failed to get registration helper object");
899 +
900 + // get dispatch id of InstallAssembly() method
901 + hr = piRegHlp->GetIDsOfNames(IID_NULL, &bstrMember, 1, LOCALE_USER_DEFAULT, &dispid);
902 + ExitOnFailure(hr, "Failed to get dispatch id of InstallAssembly() method");
903 +
904 + // set installation flags
905 + lInstallationFlags = ifExpectExistingTypeLib;
906 +
907 + if (!bstrAppName)
908 + lInstallationFlags |= ifFindOrCreateTargetApplication;
909 +
910 + // invoke InstallAssembly() method
911 + rgvarg[0].vt = VT_I4;
912 + rgvarg[0].lVal = lInstallationFlags;
913 + rgvarg[1].vt = VT_BYREF|VT_BSTR;
914 + rgvarg[1].pbstrVal = &bstrTlbPath;
915 + rgvarg[2].vt = VT_BSTR;
916 + rgvarg[2].bstrVal = bstrPartName;
917 + rgvarg[3].vt = VT_BYREF|VT_BSTR;
918 + rgvarg[3].pbstrVal = &bstrAppName;
919 + rgvarg[4].vt = VT_BSTR;
920 + rgvarg[4].bstrVal = bstrDllPath;
921 + dispparams.rgvarg = rgvarg;
922 + dispparams.cArgs = 5;
923 + dispparams.cNamedArgs = 0;
924 +
925 + hr = piRegHlp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, NULL, &excepInfo, NULL);
926 + if (DISP_E_EXCEPTION == hr)
927 + {
928 + // log exception information
929 + if (!excepInfo.pfnDeferredFillIn || (excepInfo.pfnDeferredFillIn && SUCCEEDED(excepInfo.pfnDeferredFillIn(&excepInfo))))
930 + {
931 + WcaLog(LOGMSG_STANDARD, "ExceptionInfo: Code='%hu', Source='%S', Description='%S', HelpFile='%S', HelpContext='%u'",
932 + excepInfo.wCode, excepInfo.bstrSource,
933 + excepInfo.bstrDescription ? excepInfo.bstrDescription : L"",
934 + excepInfo.bstrHelpFile ? excepInfo.bstrHelpFile : L"",
935 + excepInfo.dwHelpContext);
936 + }
937 + }
938 + ExitOnFailure(hr, "Failed to invoke RegistrationHelper.InstallAssembly() method");
939 +
940 + hr = S_OK;
941 +
942 +LExit:
943 + // clean up
944 + ReleaseObject(piRegHlp);
945 +
946 + ReleaseBSTR(bstrMember);
947 +
948 + ReleaseBSTR(excepInfo.bstrSource);
949 + ReleaseBSTR(excepInfo.bstrDescription);
950 + ReleaseBSTR(excepInfo.bstrHelpFile);
951 +
952 + ReleaseBSTR(bstrPartName);
953 + ReleaseBSTR(bstrAppName);
954 + ReleaseBSTR(bstrDllPath);
955 + ReleaseBSTR(bstrTlbPath);
956 +
957 + return hr;
958 +}
959 +
960 +static HRESULT RegisterNativeAssembly(
961 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
962 + )
963 +{
964 + HRESULT hr = S_OK;
965 +
966 + ICOMAdminCatalog* piCatalog = NULL;
967 + ICOMAdminCatalog2* piCatalog2 = NULL;
968 + BSTR bstrGlobPartID = NULL;
969 +
970 + BSTR bstrPartID = NULL;
971 + BSTR bstrAppID = NULL;
972 + BSTR bstrDllPath = NULL;
973 + BSTR bstrTlbPath = NULL;
974 + BSTR bstrPSDllPath = NULL;
975 +
976 + // create BSTRs for parameters
977 + if (pAttrs->pwzPartID && *pAttrs->pwzPartID)
978 + {
979 + bstrPartID = ::SysAllocString(pAttrs->pwzPartID);
980 + ExitOnNull(bstrPartID, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for partition id");
981 + }
982 +
983 + bstrAppID = ::SysAllocString(pAttrs->pwzAppID);
984 + ExitOnNull(bstrAppID, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for application id");
985 +
986 + bstrDllPath = ::SysAllocString(pAttrs->pwzDllPath);
987 + ExitOnNull(bstrDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for dll path");
988 +
989 + bstrTlbPath = ::SysAllocString(pAttrs->pwzTlbPath ? pAttrs->pwzTlbPath : L"");
990 + ExitOnNull(bstrTlbPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for tlb path");
991 +
992 + bstrPSDllPath = ::SysAllocString(pAttrs->pwzPSDllPath ? pAttrs->pwzPSDllPath : L"");
993 + ExitOnNull(bstrPSDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for tlb path");
994 +
995 + // get catalog
996 + hr = CpiGetAdminCatalog(&piCatalog);
997 + ExitOnFailure(hr, "Failed to get COM+ admin catalog");
998 +
999 + // get ICOMAdminCatalog2 interface
1000 + hr = piCatalog->QueryInterface(IID_ICOMAdminCatalog2, (void**)&piCatalog2);
1001 +
1002 + // COM+ 1.5 or later
1003 + if (E_NOINTERFACE != hr)
1004 + {
1005 + ExitOnFailure(hr, "Failed to get IID_ICOMAdminCatalog2 interface");
1006 +
1007 + // partition id
1008 + if (!bstrPartID)
1009 + {
1010 + // get global partition id
1011 + hr = piCatalog2->get_GlobalPartitionID(&bstrGlobPartID);
1012 + ExitOnFailure(hr, "Failed to get global partition id");
1013 + }
1014 +
1015 + // set current partition
1016 + hr = piCatalog2->put_CurrentPartition(bstrPartID ? bstrPartID : bstrGlobPartID);
1017 + ExitOnFailure(hr, "Failed to set current partition");
1018 + }
1019 +
1020 + // COM+ pre 1.5
1021 + else
1022 + {
1023 + // this version of COM+ does not support partitions, make sure a partition was not specified
1024 + if (bstrPartID)
1025 + ExitOnFailure(hr = E_FAIL, "Partitions are not supported by this version of COM+");
1026 + }
1027 +
1028 + // install event classes
1029 + if (pAttrs->iAttributes & aaEventClass)
1030 + {
1031 + hr = piCatalog->InstallEventClass(bstrAppID, bstrDllPath, bstrTlbPath, bstrPSDllPath);
1032 + if (COMADMIN_E_OBJECTERRORS == hr)
1033 + CpiLogCatalogErrorInfo();
1034 + ExitOnFailure(hr, "Failed to install event classes");
1035 + }
1036 +
1037 + // install components
1038 + else
1039 + {
1040 + hr = piCatalog->InstallComponent(bstrAppID, bstrDllPath, bstrTlbPath, bstrPSDllPath);
1041 + if (COMADMIN_E_OBJECTERRORS == hr)
1042 + CpiLogCatalogErrorInfo();
1043 + ExitOnFailure(hr, "Failed to install components");
1044 + }
1045 +
1046 + hr = S_OK;
1047 +
1048 +LExit:
1049 + // clean up
1050 + ReleaseObject(piCatalog);
1051 + ReleaseObject(piCatalog2);
1052 + ReleaseBSTR(bstrGlobPartID);
1053 +
1054 + ReleaseBSTR(bstrPartID);
1055 + ReleaseBSTR(bstrAppID);
1056 + ReleaseBSTR(bstrDllPath);
1057 + ReleaseBSTR(bstrTlbPath);
1058 + ReleaseBSTR(bstrPSDllPath);
1059 +
1060 + return hr;
1061 +}
1062 +
1063 +static HRESULT UnregisterDotNetAssembly(
1064 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
1065 + )
1066 +{
1067 + HRESULT hr = S_OK;
1068 +
1069 + IDispatch* piRegHlp = NULL;
1070 +
1071 + DISPID dispid;
1072 + BSTR bstrMember = NULL;
1073 +
1074 + VARIANTARG rgvarg[3];
1075 + DISPPARAMS dispparams;
1076 + EXCEPINFO excepInfo;
1077 +
1078 + BSTR bstrPartName = NULL;
1079 + BSTR bstrAppName = NULL;
1080 + BSTR bstrDllPath = NULL;
1081 +
1082 + ::ZeroMemory(rgvarg, sizeof(rgvarg));
1083 + ::ZeroMemory(&dispparams, sizeof(dispparams));
1084 + ::ZeroMemory(&excepInfo, sizeof(excepInfo));
1085 +
1086 + bstrMember = ::SysAllocString(L"UninstallAssembly_2");
1087 + ExitOnNull(bstrMember, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for method name");
1088 +
1089 + // create BSTRs for parameters
1090 + if (pAttrs->pwzPartID && *pAttrs->pwzPartID)
1091 + {
1092 + bstrPartName = ::SysAllocString(pAttrs->pwzPartID);
1093 + ExitOnNull(bstrPartName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for partition id");
1094 + }
1095 +
1096 + bstrAppName = ::SysAllocString(pAttrs->pwzAppID);
1097 + ExitOnNull(bstrAppName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for application id");
1098 +
1099 + bstrDllPath = ::SysAllocString(pAttrs->pwzDllPath);
1100 + ExitOnNull(bstrDllPath, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for dll path");
1101 +
1102 + // get registration helper object
1103 + hr = GetRegistrationHelper(&piRegHlp);
1104 + ExitOnFailure(hr, "Failed to get registration helper object");
1105 +
1106 + // get dispatch id of UninstallAssembly() method
1107 + hr = piRegHlp->GetIDsOfNames(IID_NULL, &bstrMember, 1, LOCALE_USER_DEFAULT, &dispid);
1108 + ExitOnFailure(hr, "Failed to get dispatch id of UninstallAssembly() method");
1109 +
1110 + // invoke UninstallAssembly() method
1111 + rgvarg[0].vt = VT_BSTR;
1112 + rgvarg[0].bstrVal = bstrPartName;
1113 + rgvarg[1].vt = VT_BSTR;
1114 + rgvarg[1].bstrVal = bstrAppName;
1115 + rgvarg[2].vt = VT_BSTR;
1116 + rgvarg[2].bstrVal = bstrDllPath;
1117 + dispparams.rgvarg = rgvarg;
1118 + dispparams.cArgs = 3;
1119 + dispparams.cNamedArgs = 0;
1120 +
1121 + hr = piRegHlp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, NULL, &excepInfo, NULL);
1122 + if (DISP_E_EXCEPTION == hr)
1123 + {
1124 + // log exception information
1125 + if (!excepInfo.pfnDeferredFillIn || (excepInfo.pfnDeferredFillIn && SUCCEEDED(excepInfo.pfnDeferredFillIn(&excepInfo))))
1126 + {
1127 + WcaLog(LOGMSG_STANDARD, "ExceptionInfo: Code='%hu', Source='%S', Description='%S', HelpFile='%S', HelpContext='%u'",
1128 + excepInfo.wCode, excepInfo.bstrSource,
1129 + excepInfo.bstrDescription ? excepInfo.bstrDescription : L"",
1130 + excepInfo.bstrHelpFile ? excepInfo.bstrHelpFile : L"",
1131 + excepInfo.dwHelpContext);
1132 + }
1133 + }
1134 + ExitOnFailure(hr, "Failed to invoke RegistrationHelper.UninstallAssembly() method");
1135 +
1136 + hr = S_OK;
1137 +
1138 +LExit:
1139 + // clean up
1140 + ReleaseObject(piRegHlp);
1141 +
1142 + ReleaseBSTR(bstrMember);
1143 +
1144 + ReleaseBSTR(excepInfo.bstrSource);
1145 + ReleaseBSTR(excepInfo.bstrDescription);
1146 + ReleaseBSTR(excepInfo.bstrHelpFile);
1147 +
1148 + ReleaseBSTR(bstrPartName);
1149 + ReleaseBSTR(bstrAppName);
1150 + ReleaseBSTR(bstrDllPath);
1151 +
1152 + return hr;
1153 +}
1154 +
1155 +static HRESULT RemoveComponents(
1156 + ICatalogCollection* piCompColl,
1157 + CPI_COMPONENT* pCompList
1158 + )
1159 +{
1160 + HRESULT hr = S_OK;
1161 +
1162 + for (CPI_COMPONENT* pItm = pCompList; pItm; pItm = pItm->pNext)
1163 + {
1164 + // remove
1165 + hr = CpiRemoveCollectionObject(piCompColl, pItm->wzCLSID, NULL, FALSE);
1166 + ExitOnFailure(hr, "Failed to remove component");
1167 +
1168 + if (S_FALSE == hr)
1169 + WcaLog(LOGMSG_VERBOSE, "Component not found, nothing to delete, key: %S", pItm->wzCLSID);
1170 + }
1171 +
1172 + hr = S_OK;
1173 +
1174 +LExit:
1175 + return hr;
1176 +}
1177 +
1178 +static HRESULT ReadAssemblyAttributes(
1179 + LPWSTR* ppwzData,
1180 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
1181 + )
1182 +{
1183 + HRESULT hr = S_OK;
1184 +
1185 + // read attributes
1186 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
1187 + ExitOnFailure(hr, "Failed to read action type");
1188 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
1189 + ExitOnFailure(hr, "Failed to read action cost");
1190 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
1191 + ExitOnFailure(hr, "Failed to read key");
1192 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAssemblyName);
1193 + ExitOnFailure(hr, "Failed to read assembly name");
1194 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzDllPath);
1195 + ExitOnFailure(hr, "Failed to read dll path");
1196 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzTlbPath);
1197 + ExitOnFailure(hr, "Failed to read tlb path");
1198 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPSDllPath);
1199 + ExitOnFailure(hr, "Failed to read proxy-stub dll path");
1200 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iAttributes);
1201 + ExitOnFailure(hr, "Failed to read attributes");
1202 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAppID);
1203 + ExitOnFailure(hr, "Failed to read application id");
1204 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
1205 + ExitOnFailure(hr, "Failed to read partition id");
1206 +
1207 + // free existing component list
1208 + if (pAttrs->pCompList)
1209 + {
1210 + FreeComponentList(pAttrs->pCompList);
1211 + pAttrs->pCompList = NULL;
1212 + }
1213 +
1214 + // read components
1215 + hr = ReadComponentList(ppwzData, &pAttrs->pCompList);
1216 + ExitOnFailure(hr, "Failed to read components");
1217 +
1218 + hr = S_OK;
1219 +
1220 +LExit:
1221 + return hr;
1222 +}
1223 +
1224 +static void FreeAssemblyAttributes(
1225 + CPI_ASSEMBLY_ATTRIBUTES* pAttrs
1226 + )
1227 +{
1228 + ReleaseStr(pAttrs->pwzKey);
1229 + ReleaseStr(pAttrs->pwzAssemblyName);
1230 + ReleaseStr(pAttrs->pwzDllPath);
1231 + ReleaseStr(pAttrs->pwzTlbPath);
1232 + ReleaseStr(pAttrs->pwzPSDllPath);
1233 + ReleaseStr(pAttrs->pwzAppID);
1234 + ReleaseStr(pAttrs->pwzPartID);
1235 +
1236 + if (pAttrs->pCompList)
1237 + FreeComponentList(pAttrs->pCompList);
1238 +}
1239 +
1240 +static HRESULT ReadRoleAssignmentsAttributes(
1241 + LPWSTR* ppwzData,
1242 + CPI_ROLE_ASSIGNMENTS_ATTRIBUTES* pAttrs
1243 + )
1244 +{
1245 + HRESULT hr = S_OK;
1246 +
1247 + // read attributes
1248 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
1249 + ExitOnFailure(hr, "Failed to read action type");
1250 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
1251 + ExitOnFailure(hr, "Failed to read action cost");
1252 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
1253 + ExitOnFailure(hr, "Failed to read key");
1254 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iRoleCount);
1255 + ExitOnFailure(hr, "Failed to read role assignments count");
1256 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAppID);
1257 + ExitOnFailure(hr, "Failed to read application id");
1258 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
1259 + ExitOnFailure(hr, "Failed to read partition id");
1260 +
1261 + // free existing component list
1262 + if (pAttrs->pCompList)
1263 + {
1264 + FreeComponentList(pAttrs->pCompList);
1265 + pAttrs->pCompList = NULL;
1266 + }
1267 +
1268 + // read components
1269 + hr = ReadComponentList(ppwzData, &pAttrs->pCompList);
1270 + ExitOnFailure(hr, "Failed to read components");
1271 +
1272 + hr = S_OK;
1273 +
1274 +LExit:
1275 + return hr;
1276 +}
1277 +
1278 +static void FreeRoleAssignmentsAttributes(
1279 + CPI_ROLE_ASSIGNMENTS_ATTRIBUTES* pAttrs
1280 + )
1281 +{
1282 + ReleaseStr(pAttrs->pwzKey);
1283 + ReleaseStr(pAttrs->pwzAppID);
1284 + ReleaseStr(pAttrs->pwzPartID);
1285 +
1286 + if (pAttrs->pCompList)
1287 + FreeComponentList(pAttrs->pCompList);
1288 +}
1289 +
1290 +
1291 +static HRESULT ConfigureComponents(
1292 + LPCWSTR pwzPartID,
1293 + LPCWSTR pwzAppID,
1294 + CPI_COMPONENT* pCompList,
1295 + BOOL fCreate,
1296 + BOOL fProgress
1297 + )
1298 +{
1299 + HRESULT hr = S_OK;
1300 +
1301 + ICatalogCollection* piCompColl = NULL;
1302 + ICatalogObject* piCompObj = NULL;
1303 +
1304 + long lChanges = 0;
1305 +
1306 + // get components collection
1307 + hr = CpiGetComponentsCollection(pwzPartID, pwzAppID, &piCompColl);
1308 + if (S_FALSE == hr)
1309 + if (fCreate)
1310 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1311 + else
1312 + ExitFunction1(hr = S_OK);
1313 + ExitOnFailure(hr, "Failed to get components collection");
1314 +
1315 + // read components
1316 + for (CPI_COMPONENT* pItm = pCompList; pItm; pItm = pItm->pNext)
1317 + {
1318 + // progress message
1319 + if (fProgress)
1320 + {
1321 + hr = CpiActionDataMessage(1, pItm->wzCLSID);
1322 + ExitOnFailure(hr, "Failed to send progress messages");
1323 +
1324 + if (S_FALSE == hr)
1325 + ExitFunction(); // aborted by user
1326 + }
1327 +
1328 + // find component
1329 + hr = CpiFindCollectionObjectByStringKey(piCompColl, pItm->wzCLSID, &piCompObj);
1330 + if (S_FALSE == hr)
1331 + if (fCreate)
1332 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1333 + else
1334 + continue;
1335 + ExitOnFailure(hr, "Failed to find component object");
1336 +
1337 + // properties
1338 + hr = CpiPutCollectionObjectValues(piCompObj, pItm->pPropertyList);
1339 + ExitOnFailure(hr, "Failed to write properties");
1340 +
1341 + // read roles
1342 + if (pItm->pRoleAssignmentList)
1343 + {
1344 + hr = ConfigureRoleAssignments(L"RolesForComponent", piCompColl, piCompObj, pItm->pRoleAssignmentList, fCreate);
1345 + ExitOnFailure(hr, "Failed to read roles");
1346 + }
1347 +
1348 + // read interfaces
1349 + if (pItm->pInterfaceList)
1350 + {
1351 + hr = ConfigureInterfaces(piCompColl, piCompObj, pItm->pInterfaceList, fCreate);
1352 + ExitOnFailure(hr, "Failed to read interfaces");
1353 + }
1354 +
1355 + // clean up
1356 + ReleaseNullObject(piCompObj);
1357 + }
1358 +
1359 + // save changes
1360 + hr = piCompColl->SaveChanges(&lChanges);
1361 + if (COMADMIN_E_OBJECTERRORS == hr)
1362 + CpiLogCatalogErrorInfo();
1363 + ExitOnFailure(hr, "Failed to save changes");
1364 +
1365 + hr = S_OK;
1366 +
1367 +LExit:
1368 + // clean up
1369 + ReleaseObject(piCompColl);
1370 + ReleaseObject(piCompObj);
1371 +
1372 + return hr;
1373 +}
1374 +
1375 +static HRESULT ConfigureInterfaces(
1376 + ICatalogCollection* piCompColl,
1377 + ICatalogObject* piCompObj,
1378 + CPI_INTERFACE* pIntfList,
1379 + BOOL fCreate
1380 + )
1381 +{
1382 + HRESULT hr = S_OK;
1383 +
1384 + ICatalogCollection* piIntfColl = NULL;
1385 + ICatalogObject* piIntfObj = NULL;
1386 +
1387 + long lChanges = 0;
1388 +
1389 + // get interfaces collection
1390 + hr = CpiGetInterfacesCollection(piCompColl, piCompObj, &piIntfColl);
1391 + if (S_FALSE == hr)
1392 + if (fCreate)
1393 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1394 + else
1395 + ExitFunction1(hr = S_OK);
1396 + ExitOnFailure(hr, "Failed to get interfaces collection");
1397 +
1398 + // read interfaces
1399 + for (CPI_INTERFACE* pItm = pIntfList; pItm; pItm = pItm->pNext)
1400 + {
1401 + // find interface
1402 + hr = CpiFindCollectionObjectByStringKey(piIntfColl, pItm->wzIID, &piIntfObj);
1403 + if (S_FALSE == hr)
1404 + if (fCreate)
1405 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1406 + else
1407 + continue;
1408 + ExitOnFailure(hr, "Failed to find interface object");
1409 +
1410 + // properties
1411 + hr = CpiPutCollectionObjectValues(piIntfObj, pItm->pPropertyList);
1412 + ExitOnFailure(hr, "Failed to write properties");
1413 +
1414 + // read roles
1415 + if (pItm->pRoleAssignmentList)
1416 + {
1417 + hr = ConfigureRoleAssignments(L"RolesForInterface", piIntfColl, piIntfObj, pItm->pRoleAssignmentList, fCreate);
1418 + ExitOnFailure(hr, "Failed to read roles");
1419 + }
1420 +
1421 + // read methods
1422 + if (pItm->pMethodList)
1423 + {
1424 + hr = ConfigureMethods(piIntfColl, piIntfObj, pItm->pMethodList, fCreate);
1425 + ExitOnFailure(hr, "Failed to read methods");
1426 + }
1427 +
1428 + // clean up
1429 + ReleaseNullObject(piIntfObj);
1430 + }
1431 +
1432 + // save changes
1433 + hr = piIntfColl->SaveChanges(&lChanges);
1434 + if (COMADMIN_E_OBJECTERRORS == hr)
1435 + CpiLogCatalogErrorInfo();
1436 + ExitOnFailure(hr, "Failed to save changes");
1437 +
1438 + hr = S_OK;
1439 +
1440 +LExit:
1441 + // clean up
1442 + ReleaseObject(piIntfColl);
1443 + ReleaseObject(piIntfObj);
1444 +
1445 + return hr;
1446 +}
1447 +
1448 +static HRESULT ConfigureMethods(
1449 + ICatalogCollection* piIntfColl,
1450 + ICatalogObject* piIntfObj,
1451 + CPI_METHOD* pMethList,
1452 + BOOL fCreate
1453 + )
1454 +{
1455 + HRESULT hr = S_OK;
1456 +
1457 + ICatalogCollection* piMethColl = NULL;
1458 + ICatalogObject* piMethObj = NULL;
1459 +
1460 + long lChanges = 0;
1461 +
1462 + // get methods collection
1463 + hr = CpiGetMethodsCollection(piIntfColl, piIntfObj, &piMethColl);
1464 + if (S_FALSE == hr)
1465 + if (fCreate)
1466 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1467 + else
1468 + ExitFunction1(hr = S_OK);
1469 + ExitOnFailure(hr, "Failed to get methods collection");
1470 +
1471 + // read methods
1472 + for (CPI_METHOD* pItm = pMethList; pItm; pItm = pItm->pNext)
1473 + {
1474 + // find method
1475 + if (*pItm->wzIndex)
1476 + hr = CpiFindCollectionObjectByIntegerKey(piMethColl, _wtol(pItm->wzIndex), &piMethObj);
1477 + else
1478 + hr = CpiFindCollectionObjectByName(piMethColl, pItm->wzName, &piMethObj);
1479 +
1480 + if (S_FALSE == hr)
1481 + if (fCreate)
1482 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1483 + else
1484 + continue;
1485 + ExitOnFailure(hr, "Failed to find method object");
1486 +
1487 + // properties
1488 + hr = CpiPutCollectionObjectValues(piMethObj, pItm->pPropertyList);
1489 + ExitOnFailure(hr, "Failed to write properties");
1490 +
1491 + // read roles
1492 + if (pItm->pRoleAssignmentList)
1493 + {
1494 + hr = ConfigureRoleAssignments(L"RolesForMethod", piMethColl, piMethObj, pItm->pRoleAssignmentList, fCreate);
1495 + ExitOnFailure(hr, "Failed to read roles");
1496 + }
1497 +
1498 + // clean up
1499 + ReleaseNullObject(piMethObj);
1500 + }
1501 +
1502 + // save changes
1503 + hr = piMethColl->SaveChanges(&lChanges);
1504 + if (COMADMIN_E_OBJECTERRORS == hr)
1505 + CpiLogCatalogErrorInfo();
1506 + ExitOnFailure(hr, "Failed to save changes");
1507 +
1508 + hr = S_OK;
1509 +
1510 +LExit:
1511 + // clean up
1512 + ReleaseObject(piMethColl);
1513 + ReleaseObject(piMethObj);
1514 +
1515 + return hr;
1516 +}
1517 +
1518 +static HRESULT ConfigureRoleAssignments(
1519 + LPCWSTR pwzCollName,
1520 + ICatalogCollection* piCompColl,
1521 + ICatalogObject* piCompObj,
1522 + CPI_ROLE_ASSIGNMENT* pRoleList,
1523 + BOOL fCreate
1524 + )
1525 +{
1526 + HRESULT hr = S_OK;
1527 +
1528 + ICatalogCollection* piRoleColl = NULL;
1529 + ICatalogObject* piRoleObj = NULL;
1530 +
1531 + long lChanges = 0;
1532 +
1533 + // get roles collection
1534 + hr = CpiGetCatalogCollection(piCompColl, piCompObj, pwzCollName, &piRoleColl);
1535 + if (S_FALSE == hr)
1536 + if (fCreate)
1537 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1538 + else
1539 + ExitFunction1(hr = S_OK);
1540 + ExitOnFailure(hr, "Failed to get role assignments collection");
1541 +
1542 + // read roles
1543 + for (CPI_ROLE_ASSIGNMENT* pItm = pRoleList; pItm; pItm = pItm->pNext)
1544 + {
1545 + if (fCreate)
1546 + {
1547 + // find existing role
1548 + hr = CpiFindCollectionObjectByName(piRoleColl, pItm->wzRoleName, NULL);
1549 + ExitOnFailure(hr, "Failed to find role, key: %S", pItm->wzKey);
1550 +
1551 + if (S_OK == hr)
1552 + continue; // role already exists
1553 +
1554 + // add object
1555 + hr = CpiAddCollectionObject(piRoleColl, &piRoleObj);
1556 + ExitOnFailure(hr, "Failed to add role assignment to collection");
1557 +
1558 + // role name
1559 + hr = CpiPutCollectionObjectValue(piRoleObj, L"Name", pItm->wzRoleName);
1560 + ExitOnFailure(hr, "Failed to set role name property, key: %S", pItm->wzKey);
1561 +
1562 + // clean up
1563 + ReleaseNullObject(piRoleObj);
1564 + }
1565 + else
1566 + {
1567 + // remove role
1568 + hr = CpiRemoveCollectionObject(piRoleColl, NULL, pItm->wzRoleName, FALSE);
1569 + ExitOnFailure(hr, "Failed to remove role, key: %S", pItm->wzKey);
1570 + }
1571 + }
1572 +
1573 + // save changes
1574 + hr = piRoleColl->SaveChanges(&lChanges);
1575 + if (COMADMIN_E_OBJECTERRORS == hr)
1576 + CpiLogCatalogErrorInfo();
1577 + ExitOnFailure(hr, "Failed to save changes");
1578 +
1579 + hr = S_OK;
1580 +
1581 +LExit:
1582 + // clean up
1583 + ReleaseObject(piRoleColl);
1584 + ReleaseObject(piRoleObj);
1585 +
1586 + return hr;
1587 +}
1588 +
1589 +static HRESULT ReadComponentList(
1590 + LPWSTR* ppwzData,
1591 + CPI_COMPONENT** ppCompList
1592 + )
1593 +{
1594 + HRESULT hr = S_OK;
1595 +
1596 + LPWSTR pwzData = NULL;
1597 +
1598 + CPI_COMPONENT* pItm = NULL;
1599 +
1600 + int iCnt = 0;
1601 +
1602 + // read count
1603 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
1604 + ExitOnFailure(hr, "Failed to read count");
1605 +
1606 + // read components
1607 + for (int i = 0; i < iCnt; i++)
1608 + {
1609 + pItm = (CPI_COMPONENT*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_COMPONENT));
1610 + if (!pItm)
1611 + ExitFunction1(hr = E_OUTOFMEMORY);
1612 +
1613 + // read clsid
1614 + hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1615 + ExitOnFailure(hr, "Failed to read clsid");
1616 + StringCchCopyW(pItm->wzCLSID, countof(pItm->wzCLSID), pwzData);
1617 +
1618 + // read properties
1619 + hr = CpiReadPropertyList(ppwzData, &pItm->pPropertyList);
1620 + ExitOnFailure(hr, "Failed to read properties");
1621 +
1622 + // read role assignments
1623 + hr = ReadRoleAssignmentList(ppwzData, &pItm->pRoleAssignmentList);
1624 + ExitOnFailure(hr, "Failed to read role assignments");
1625 +
1626 + // read interfaces
1627 + hr = ReadInterfaceList(ppwzData, &pItm->pInterfaceList);
1628 + ExitOnFailure(hr, "Failed to read interfaces");
1629 +
1630 + // add to list
1631 + if (*ppCompList)
1632 + pItm->pNext = *ppCompList;
1633 + *ppCompList = pItm;
1634 + pItm = NULL;
1635 + }
1636 +
1637 + hr = S_OK;
1638 +
1639 +LExit:
1640 + // clean up
1641 + ReleaseStr(pwzData);
1642 +
1643 + if (pItm)
1644 + FreeComponentList(pItm);
1645 +
1646 + return hr;
1647 +}
1648 +
1649 +static HRESULT ReadInterfaceList(
1650 + LPWSTR* ppwzData,
1651 + CPI_INTERFACE** ppIntfList
1652 + )
1653 +{
1654 + HRESULT hr = S_OK;
1655 +
1656 + LPWSTR pwzData = NULL;
1657 +
1658 + CPI_INTERFACE* pItm = NULL;
1659 +
1660 + int iCnt = 0;
1661 +
1662 + // read count
1663 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
1664 + ExitOnFailure(hr, "Failed to read count");
1665 +
1666 + // read interfaces
1667 + for (int i = 0; i < iCnt; i++)
1668 + {
1669 + pItm = (CPI_INTERFACE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_INTERFACE));
1670 + if (!pItm)
1671 + ExitFunction1(hr = E_OUTOFMEMORY);
1672 +
1673 + // read iid
1674 + hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1675 + ExitOnFailure(hr, "Failed to read iid");
1676 + StringCchCopyW(pItm->wzIID, countof(pItm->wzIID), pwzData);
1677 +
1678 + // read properties
1679 + hr = CpiReadPropertyList(ppwzData, &pItm->pPropertyList);
1680 + ExitOnFailure(hr, "Failed to read properties");
1681 +
1682 + // read role assignments
1683 + hr = ReadRoleAssignmentList(ppwzData, &pItm->pRoleAssignmentList);
1684 + ExitOnFailure(hr, "Failed to read role assignments");
1685 +
1686 + // read methods
1687 + hr = ReadMethodList(ppwzData, &pItm->pMethodList);
1688 + ExitOnFailure(hr, "Failed to read methods");
1689 +
1690 + // add to list
1691 + if (*ppIntfList)
1692 + pItm->pNext = *ppIntfList;
1693 + *ppIntfList = pItm;
1694 + pItm = NULL;
1695 + }
1696 +
1697 + hr = S_OK;
1698 +
1699 +LExit:
1700 + // clean up
1701 + ReleaseStr(pwzData);
1702 +
1703 + if (pItm)
1704 + FreeInterfaceList(pItm);
1705 +
1706 + return hr;
1707 +}
1708 +
1709 +static HRESULT ReadMethodList(
1710 + LPWSTR* ppwzData,
1711 + CPI_METHOD** ppMethList
1712 + )
1713 +{
1714 + HRESULT hr = S_OK;
1715 +
1716 + LPWSTR pwzData = NULL;
1717 +
1718 + CPI_METHOD* pItm = NULL;
1719 +
1720 + int iCnt = 0;
1721 +
1722 + // read count
1723 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
1724 + ExitOnFailure(hr, "Failed to read count");
1725 +
1726 + // read methods
1727 + for (int i = 0; i < iCnt; i++)
1728 + {
1729 + pItm = (CPI_METHOD*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_METHOD));
1730 + if (!pItm)
1731 + ExitFunction1(hr = E_OUTOFMEMORY);
1732 +
1733 + // read index
1734 + hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1735 + ExitOnFailure(hr, "Failed to read index");
1736 + StringCchCopyW(pItm->wzIndex, countof(pItm->wzIndex), pwzData);
1737 +
1738 + // read name
1739 + hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1740 + ExitOnFailure(hr, "Failed to read name");
1741 + StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
1742 +
1743 + // read properties
1744 + hr = CpiReadPropertyList(ppwzData, &pItm->pPropertyList);
1745 + ExitOnFailure(hr, "Failed to read properties");
1746 +
1747 + // read role assignments
1748 + hr = ReadRoleAssignmentList(ppwzData, &pItm->pRoleAssignmentList);
1749 + ExitOnFailure(hr, "Failed to read role assignments");
1750 +
1751 + // add to list
1752 + if (*ppMethList)
1753 + pItm->pNext = *ppMethList;
1754 + *ppMethList = pItm;
1755 + pItm = NULL;
1756 + }
1757 +
1758 + hr = S_OK;
1759 +
1760 +LExit:
1761 + // clean up
1762 + ReleaseStr(pwzData);
1763 +
1764 + if (pItm)
1765 + FreeMethodList(pItm);
1766 +
1767 + return hr;
1768 +}
1769 +
1770 +static HRESULT ReadRoleAssignmentList(
1771 + LPWSTR* ppwzData,
1772 + CPI_ROLE_ASSIGNMENT** ppRoleList
1773 + )
1774 +{
1775 + HRESULT hr = S_OK;
1776 +
1777 + LPWSTR pwzData = NULL;
1778 +
1779 + CPI_ROLE_ASSIGNMENT* pItm = NULL;
1780 +
1781 + int iCnt = 0;
1782 +
1783 + // read role count
1784 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
1785 + ExitOnFailure(hr, "Failed to read role assignments count");
1786 +
1787 + // read roles
1788 + for (int i = 0; i < iCnt; i++)
1789 + {
1790 + pItm = (CPI_ROLE_ASSIGNMENT*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_ROLE_ASSIGNMENT));
1791 + if (!pItm)
1792 + ExitFunction1(hr = E_OUTOFMEMORY);
1793 +
1794 + // read key
1795 + hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1796 + ExitOnFailure(hr, "Failed to read key");
1797 + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
1798 +
1799 + // read role name
1800 + hr = WcaReadStringFromCaData(ppwzData, &pwzData);
1801 + ExitOnFailure(hr, "Failed to read role name");
1802 + StringCchCopyW(pItm->wzRoleName, countof(pItm->wzRoleName), pwzData);
1803 +
1804 + // add to list
1805 + if (*ppRoleList)
1806 + pItm->pNext = *ppRoleList;
1807 + *ppRoleList = pItm;
1808 + pItm = NULL;
1809 + }
1810 +
1811 + hr = S_OK;
1812 +
1813 +LExit:
1814 + // clean up
1815 + ReleaseStr(pwzData);
1816 +
1817 + if (pItm)
1818 + FreeRoleAssignmentList(pItm);
1819 +
1820 + return hr;
1821 +}
1822 +
1823 +static void FreeComponentList(
1824 + CPI_COMPONENT* pList
1825 + )
1826 +{
1827 + while (pList)
1828 + {
1829 + if (pList->pPropertyList)
1830 + CpiFreePropertyList(pList->pPropertyList);
1831 + if (pList->pRoleAssignmentList)
1832 + FreeRoleAssignmentList(pList->pRoleAssignmentList);
1833 + if (pList->pInterfaceList)
1834 + FreeInterfaceList(pList->pInterfaceList);
1835 +
1836 + CPI_COMPONENT* pDelete = pList;
1837 + pList = pList->pNext;
1838 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
1839 + }
1840 +}
1841 +
1842 +static void FreeInterfaceList(
1843 + CPI_INTERFACE* pList
1844 + )
1845 +{
1846 + while (pList)
1847 + {
1848 + if (pList->pPropertyList)
1849 + CpiFreePropertyList(pList->pPropertyList);
1850 + if (pList->pRoleAssignmentList)
1851 + FreeRoleAssignmentList(pList->pRoleAssignmentList);
1852 + if (pList->pMethodList)
1853 + FreeMethodList(pList->pMethodList);
1854 +
1855 + CPI_INTERFACE* pDelete = pList;
1856 + pList = pList->pNext;
1857 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
1858 + }
1859 +}
1860 +
1861 +static void FreeMethodList(
1862 + CPI_METHOD* pList
1863 + )
1864 +{
1865 + while (pList)
1866 + {
1867 + if (pList->pPropertyList)
1868 + CpiFreePropertyList(pList->pPropertyList);
1869 + if (pList->pRoleAssignmentList)
1870 + FreeRoleAssignmentList(pList->pRoleAssignmentList);
1871 +
1872 + CPI_METHOD* pDelete = pList;
1873 + pList = pList->pNext;
1874 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
1875 + }
1876 +}
1877 +
1878 +static void FreeRoleAssignmentList(
1879 + CPI_ROLE_ASSIGNMENT* pList
1880 + )
1881 +{
1882 + while (pList)
1883 + {
1884 + CPI_ROLE_ASSIGNMENT* pDelete = pList;
1885 + pList = pList->pNext;
1886 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
1887 + }
1888 +}
src/ca/cpasmexec.h new
+20
@@ -0,0 +1,20 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +HRESULT CpiConfigureAssemblies(
6 + LPWSTR* ppwzData,
7 + HANDLE hRollbackFile
8 + );
9 +HRESULT CpiRollbackConfigureAssemblies(
10 + LPWSTR* ppwzData,
11 + CPI_ROLLBACK_DATA* pRollbackDataList
12 + );
13 +HRESULT CpiConfigureRoleAssignments(
14 + LPWSTR* ppwzData,
15 + HANDLE hRollbackFile
16 + );
17 +HRESULT CpiRollbackConfigureRoleAssignments(
18 + LPWSTR* ppwzData,
19 + CPI_ROLLBACK_DATA* pRollbackDataList
20 + );
src/ca/cpasmsched.cpp new
+2135
@@ -0,0 +1,2135 @@
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 vcsMsiAssemblyNameQuery =
9 + L"SELECT `Name`, `Value` FROM `MsiAssemblyName` WHERE `Component_` = ?";
10 +enum eMsiAssemblyNameQuery { manqName = 1, manqValue };
11 +
12 +LPCWSTR vcsModuleQuery =
13 + L"SELECT `ModuleID` FROM `ModuleSignature`";
14 +enum eModuleQuery { mqModule = 1 };
15 +
16 +LPCWSTR vcsAssemblyQuery =
17 + L"SELECT `Assembly`, `Component_`, `Application_`, `AssemblyName`, `DllPath`, `TlbPath`, `PSDllPath`, `Attributes` FROM `ComPlusAssembly`";
18 +enum eAssemblyQuery { aqAssembly = 1, aqComponent, aqApplication, aqAssemblyName, aqDllPath, aqTlbPath, aqPSDllPath, aqAttributes };
19 +
20 +LPCWSTR vcsComponentQuery =
21 + L"SELECT `ComPlusComponent`, `CLSID` FROM `ComPlusComponent` WHERE `Assembly_` = ?";
22 +enum eComponentQuery { cqComponent = 1, cqCLSID };
23 +
24 +LPCWSTR vcsComponentPropertyQuery =
25 + L"SELECT `Name`, `Value` FROM `ComPlusComponentProperty` WHERE `ComPlusComponent_` = ?";
26 +
27 +LPCWSTR vcsInterfaceQuery =
28 + L"SELECT `Interface`, `IID` FROM `ComPlusInterface` WHERE `ComPlusComponent_` = ?";
29 +enum eInterfaceQuery { iqInterface = 1, iqIID };
30 +
31 +LPCWSTR vcsInterfacePropertyQuery =
32 + L"SELECT `Name`, `Value` FROM `ComPlusInterfaceProperty` WHERE `Interface_` = ?";
33 +
34 +LPCWSTR vcsMethodQuery =
35 + L"SELECT `Method`, `Index`, `Name` FROM `ComPlusMethod` WHERE `Interface_` = ?";
36 +enum eMethodQuery { mqMethod = 1, mqIndex, mqName };
37 +
38 +LPCWSTR vcsMethodPropertyQuery =
39 + L"SELECT `Name`, `Value` FROM `ComPlusMethodProperty` WHERE `Method_` = ?";
40 +
41 +LPCWSTR vcsRoleForComponentQuery =
42 + L"SELECT `RoleForComponent`, `ApplicationRole_`, `Component_` FROM `ComPlusRoleForComponent` WHERE `ComPlusComponent_` = ?";
43 +LPCWSTR vcsRoleForInterfaceQuery =
44 + L"SELECT `RoleForInterface`, `ApplicationRole_`, `Component_` FROM `ComPlusRoleForInterface` WHERE `Interface_` = ?";
45 +LPCWSTR vcsRoleForMethodQuery =
46 + L"SELECT `RoleForMethod`, `ApplicationRole_`, `Component_` FROM `ComPlusRoleForMethod` WHERE `Method_` = ?";
47 +
48 +enum eRoleAssignmentQuery { raqKey = 1, raqApplicationRole, raqComponent };
49 +
50 +LPCWSTR vcsModuleComponentsQuery =
51 + L"SELECT `Component`, `ModuleID` FROM `ModuleComponents`";
52 +LPCWSTR vcsModuleDependencyQuery =
53 + L"SELECT `ModuleID`, `RequiredID` FROM `ModuleDependency`";
54 +LPCWSTR vcsAssemblyDependencyQuery =
55 + L"SELECT `Assembly_`, `RequiredAssembly_` FROM `ComPlusAssemblyDependency`";
56 +
57 +enum eKeyPairQuery { kpqFirstKey = 1, kpqSecondKey };
58 +
59 +
60 +// private structs
61 +
62 +struct CPI_KEY_PAIR
63 +{
64 + WCHAR wzFirstKey[MAX_DARWIN_KEY + 1];
65 + WCHAR wzSecondKey[MAX_DARWIN_KEY + 1];
66 +
67 + CPI_KEY_PAIR* pNext;
68 +};
69 +
70 +struct CPI_DEPENDENCY_CHAIN
71 +{
72 + LPCWSTR pwzKey;
73 +
74 + CPI_DEPENDENCY_CHAIN* pPrev;
75 +};
76 +
77 +struct CPI_MODULE
78 +{
79 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
80 +
81 + CPI_MODULE* pPrev;
82 + CPI_MODULE* pNext;
83 +};
84 +
85 +struct CPI_MODULE_LIST
86 +{
87 + CPI_MODULE* pFirst;
88 + CPI_MODULE* pLast;
89 +};
90 +
91 +
92 +// property definitions
93 +
94 +CPI_PROPERTY_DEFINITION pdlComponentProperties[] =
95 +{
96 + {L"AllowInprocSubscribers", cpptBoolean, 500},
97 + {L"ComponentAccessChecksEnabled", cpptBoolean, 500},
98 + {L"ComponentTransactionTimeout", cpptInteger, 500},
99 + {L"ComponentTransactionTimeoutEnabled", cpptBoolean, 500},
100 + {L"COMTIIntrinsics", cpptBoolean, 500},
101 + {L"ConstructionEnabled", cpptBoolean, 500},
102 + {L"ConstructorString", cpptString, 500},
103 + {L"CreationTimeout", cpptInteger, 500},
104 + {L"Description", cpptString, 500},
105 + {L"EventTrackingEnabled", cpptBoolean, 500},
106 + {L"ExceptionClass", cpptString, 500},
107 + {L"FireInParallel", cpptBoolean, 500},
108 + {L"IISIntrinsics", cpptBoolean, 500},
109 + {L"InitializesServerApplication", cpptBoolean, 500},
110 + {L"IsEnabled", cpptBoolean, 501},
111 + {L"IsPrivateComponent", cpptBoolean, 501},
112 + {L"JustInTimeActivation", cpptBoolean, 500},
113 + {L"LoadBalancingSupported", cpptBoolean, 500},
114 + {L"MaxPoolSize", cpptInteger, 500},
115 + {L"MinPoolSize", cpptInteger, 500},
116 + {L"MultiInterfacePublisherFilterCLSID", cpptString, 500},
117 + {L"MustRunInClientContext", cpptBoolean, 500},
118 + {L"MustRunInDefaultContext", cpptBoolean, 501},
119 + {L"ObjectPoolingEnabled", cpptBoolean, 500},
120 + {L"PublisherID", cpptString, 500},
121 + {L"SoapAssemblyName", cpptString, 502},
122 + {L"SoapTypeName", cpptString, 502},
123 + {L"Synchronization", cpptInteger, 500},
124 + {L"Transaction", cpptInteger, 500},
125 + {L"TxIsolationLevel", cpptInteger, 501},
126 + {NULL, cpptNone, 0}
127 +};
128 +
129 +CPI_PROPERTY_DEFINITION pdlInterfaceProperties[] =
130 +{
131 + {L"Description", cpptString, 500},
132 + {L"QueuingEnabled", cpptBoolean, 500},
133 + {NULL, cpptNone, 0}
134 +};
135 +
136 +CPI_PROPERTY_DEFINITION pdlMethodProperties[] =
137 +{
138 + {L"AutoComplete", cpptBoolean, 500},
139 + {L"Description", cpptString, 500},
140 + {NULL, cpptNone, 0}
141 +};
142 +
143 +
144 +// prototypes for private helper functions
145 +
146 +static HRESULT GetAssemblyName(
147 + LPCWSTR pwzComponent,
148 + LPWSTR* ppwzAssemblyName
149 + );
150 +static HRESULT KeyPairsRead(
151 + LPCWSTR pwzQuery,
152 + CPI_KEY_PAIR** ppKeyPairList
153 + );
154 +static HRESULT ModulesRead(
155 + CPI_MODULE_LIST* pModList
156 + );
157 +static HRESULT AssembliesRead(
158 + CPI_KEY_PAIR* pModCompList,
159 + CPI_APPLICATION_LIST* pAppList,
160 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
161 + CPI_ASSEMBLY_LIST* pAsmList
162 + );
163 +static HRESULT ComponentsRead(
164 + LPCWSTR pwzAsmKey,
165 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
166 + CPI_ASSEMBLY* pAsm
167 + );
168 +static HRESULT InterfacesRead(
169 + LPCWSTR pwzCompKey,
170 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
171 + CPI_ASSEMBLY* pAsm,
172 + CPI_COMPONENT* pComp
173 + );
174 +static HRESULT MethodsRead(
175 + LPCWSTR pwzIntfKey,
176 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
177 + CPI_ASSEMBLY* pAsm,
178 + CPI_INTERFACE* pIntf
179 + );
180 +static HRESULT RoleAssignmentsRead(
181 + LPCWSTR pwzQuery,
182 + LPCWSTR pwzKey,
183 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
184 + CPI_ROLE_ASSIGNMENT** ppRoleList,
185 + int* piInstallCount,
186 + int* piUninstallCount
187 + );
188 +static HRESULT TopSortModuleList(
189 + CPI_KEY_PAIR* pDepList,
190 + CPI_MODULE_LIST* pList
191 + );
192 +static HRESULT SwapDependentModules(
193 + CPI_DEPENDENCY_CHAIN* pdcPrev,
194 + CPI_KEY_PAIR* pDepList,
195 + CPI_MODULE_LIST* pList,
196 + CPI_MODULE* pRoot,
197 + CPI_MODULE* pItm
198 + );
199 +static HRESULT ModuleFindByKey(
200 + CPI_MODULE* pItm,
201 + LPCWSTR pwzKey,
202 + BOOL fReverse,
203 + CPI_MODULE** ppItm
204 + );
205 +static void SortAssemblyListByModule(
206 + CPI_MODULE_LIST* pModList,
207 + CPI_ASSEMBLY_LIST* pAsmList
208 + );
209 +static HRESULT TopSortAssemblyList(
210 + CPI_KEY_PAIR* pDepList,
211 + CPI_ASSEMBLY_LIST* pList
212 + );
213 +static HRESULT SwapDependentAssemblies(
214 + CPI_DEPENDENCY_CHAIN* pdcPrev,
215 + CPI_KEY_PAIR* pDepList,
216 + CPI_ASSEMBLY_LIST* pList,
217 + CPI_ASSEMBLY* pRoot,
218 + CPI_ASSEMBLY* pItm
219 + );
220 +static HRESULT AssemblyFindByKey(
221 + CPI_ASSEMBLY* pItm,
222 + LPCWSTR pwzKey,
223 + BOOL fReverse,
224 + CPI_ASSEMBLY** ppItm
225 + );
226 +static HRESULT AddAssemblyToActionData(
227 + CPI_ASSEMBLY* pItm,
228 + BOOL fInstall,
229 + int iActionType,
230 + int iActionCost,
231 + LPWSTR* ppwzActionData
232 + );
233 +static HRESULT AddRoleAssignmentsToActionData(
234 + CPI_ASSEMBLY* pItm,
235 + BOOL fInstall,
236 + int iActionType,
237 + int iActionCost,
238 + LPWSTR* ppwzActionData
239 + );
240 +static HRESULT AddComponentToActionData(
241 + CPI_COMPONENT* pItm,
242 + BOOL fInstall,
243 + BOOL fProps,
244 + BOOL fRoles,
245 + LPWSTR* ppwzActionData
246 + );
247 +static HRESULT AddInterfaceToActionData(
248 + CPI_INTERFACE* pItm,
249 + BOOL fInstall,
250 + BOOL fProps,
251 + BOOL fRoles,
252 + LPWSTR* ppwzActionData
253 + );
254 +static HRESULT AddMethodToActionData(
255 + CPI_METHOD* pItm,
256 + BOOL fInstall,
257 + BOOL fProps,
258 + BOOL fRoles,
259 + LPWSTR* ppwzActionData
260 + );
261 +static HRESULT AddRolesToActionData(
262 + int iRoleInstallCount,
263 + int iRoleUninstallCount,
264 + CPI_ROLE_ASSIGNMENT* pRoleList,
265 + BOOL fInstall,
266 + BOOL fRoles,
267 + LPWSTR* ppwzActionData
268 + );
269 +static HRESULT KeyPairFindByFirstKey(
270 + CPI_KEY_PAIR* pList,
271 + LPCWSTR pwzKey,
272 + CPI_KEY_PAIR** ppItm
273 + );
274 +static void AssemblyFree(
275 + CPI_ASSEMBLY* pItm
276 + );
277 +static void KeyPairsFreeList(
278 + CPI_KEY_PAIR* pList
279 + );
280 +void ModuleListFree(
281 + CPI_MODULE_LIST* pList
282 + );
283 +static void ModuleFree(
284 + CPI_MODULE* pItm
285 + );
286 +static void ComponentsFreeList(
287 + CPI_COMPONENT* pList
288 + );
289 +static void InterfacesFreeList(
290 + CPI_INTERFACE* pList
291 + );
292 +static void MethodsFreeList(
293 + CPI_METHOD* pList
294 + );
295 +static void RoleAssignmentsFreeList(
296 + CPI_ROLE_ASSIGNMENT* pList
297 + );
298 +
299 +
300 +// function definitions
301 +
302 +void CpiAssemblyListFree(
303 + CPI_ASSEMBLY_LIST* pList
304 + )
305 +{
306 + CPI_ASSEMBLY* pItm = pList->pFirst;
307 +
308 + while (pItm)
309 + {
310 + CPI_ASSEMBLY* pDelete = pItm;
311 + pItm = pItm->pNext;
312 + AssemblyFree(pDelete);
313 + }
314 +}
315 +
316 +HRESULT CpiAssembliesRead(
317 + CPI_APPLICATION_LIST* pAppList,
318 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
319 + CPI_ASSEMBLY_LIST* pAsmList
320 + )
321 +{
322 + HRESULT hr = S_OK;
323 + CPI_MODULE_LIST modList;
324 + CPI_KEY_PAIR* pModCompList = NULL;
325 + CPI_KEY_PAIR* pModDepList = NULL;
326 + CPI_KEY_PAIR* pAsmDepList = NULL;
327 +
328 + ::ZeroMemory(&modList, sizeof(CPI_MODULE_LIST));
329 +
330 + BOOL fModuleSignatureTable = (S_OK == WcaTableExists(L"ModuleSignature"));
331 + BOOL fModuleComponentsTable = (S_OK == WcaTableExists(L"ModuleComponents"));
332 + BOOL fModuleDependencyTable = (S_OK == WcaTableExists(L"ModuleDependency"));
333 +
334 + // read modules
335 + if (fModuleSignatureTable)
336 + {
337 + hr = ModulesRead(&modList);
338 + ExitOnFailure(hr, "Failed to read ModuleSignature table");
339 + }
340 +
341 + // read module components
342 + if (fModuleComponentsTable)
343 + {
344 + hr = KeyPairsRead(vcsModuleComponentsQuery, &pModCompList);
345 + ExitOnFailure(hr, "Failed to read ModuleComponents table");
346 + }
347 +
348 + // read module dependencies
349 + if (fModuleDependencyTable)
350 + {
351 + hr = KeyPairsRead(vcsModuleDependencyQuery, &pModDepList);
352 + ExitOnFailure(hr, "Failed to read ModuleDependency table");
353 + }
354 +
355 + // read assemblies
356 + hr = AssembliesRead(pModCompList, pAppList, pAppRoleList, pAsmList);
357 + ExitOnFailure(hr, "Failed to read ComPlusAssembly table");
358 +
359 + // read assembly dependencies
360 + if (CpiTableExists(cptComPlusAssemblyDependency))
361 + {
362 + hr = KeyPairsRead(vcsAssemblyDependencyQuery, &pAsmDepList);
363 + ExitOnFailure(hr, "Failed to read ComPlusAssemblyDependency table");
364 + }
365 +
366 + // sort modules
367 + if (modList.pFirst && pModDepList)
368 + {
369 + hr = TopSortModuleList(pModDepList, &modList);
370 + ExitOnFailure(hr, "Failed to sort modules");
371 + }
372 +
373 + // sort assemblies by module
374 + if (pAsmList->pFirst && modList.pFirst && pModDepList)
375 + SortAssemblyListByModule(&modList, pAsmList);
376 +
377 + // sort assemblies by dependency
378 + if (pAsmList->pFirst && pAsmDepList)
379 + {
380 + hr = TopSortAssemblyList(pAsmDepList, pAsmList);
381 + ExitOnFailure(hr, "Failed to sort assemblies");
382 + }
383 +
384 + hr = S_OK;
385 +
386 +LExit:
387 + // clean up
388 + ModuleListFree(&modList);
389 + if (pModCompList)
390 + KeyPairsFreeList(pModCompList);
391 + if (pModDepList)
392 + KeyPairsFreeList(pModDepList);
393 + if (pAsmDepList)
394 + KeyPairsFreeList(pAsmDepList);
395 +
396 + return hr;
397 +}
398 +
399 +HRESULT CpiAssembliesVerifyInstall(
400 + CPI_ASSEMBLY_LIST* pList
401 + )
402 +{
403 + HRESULT hr = S_OK;
404 +
405 + for (CPI_ASSEMBLY* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
406 + {
407 + // assemblies that are being installed
408 + if (!pItm->fReferencedForInstall && !pItm->iRoleAssignmentsInstallCount && !WcaIsInstalling(pItm->isInstalled, pItm->isAction))
409 + continue;
410 +
411 + // if the assembly is referensed, it must be installed
412 + if ((pItm->fReferencedForInstall || pItm->iRoleAssignmentsInstallCount) && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction))
413 + MessageExitOnFailure(hr = E_FAIL, msierrComPlusAssemblyDependency, "An assembly is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey);
414 + }
415 +
416 + hr = S_OK;
417 +
418 +LExit:
419 + return hr;
420 +}
421 +
422 +HRESULT CpiAssembliesVerifyUninstall(
423 + CPI_ASSEMBLY_LIST* pList
424 + )
425 +{
426 + HRESULT hr = S_OK;
427 +
428 + for (CPI_ASSEMBLY* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
429 + {
430 + // assemblies that are being uninstalled
431 + if (!pItm->fReferencedForUninstall && !pItm->iRoleAssignmentsUninstallCount && (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction) && !WcaIsReInstalling(pItm->isInstalled, pItm->isAction)))
432 + continue;
433 +
434 + // if the application is not present, there is no need to remove the components
435 + if (pItm->pApplication && pItm->pApplication->fObjectNotFound)
436 + {
437 + pItm->fIgnore = TRUE;
438 + pList->iUninstallCount--; // elements with the fIgnore flag set will not be scheduled for uninstall
439 + pList->iRoleUninstallCount--;
440 + }
441 + }
442 +
443 + hr = S_OK;
444 +
445 +//LExit:
446 + return hr;
447 +}
448 +
449 +HRESULT CpiAssembliesInstall(
450 + CPI_ASSEMBLY_LIST* pList,
451 + int iRunMode,
452 + LPWSTR* ppwzActionData,
453 + int* piProgress
454 + )
455 +{
456 + HRESULT hr = S_OK;
457 +
458 + int iActionType;
459 + int iCount = 0;
460 +
461 + // add action text
462 + hr = CpiAddActionTextToActionData(L"RegisterComPlusAssemblies", ppwzActionData);
463 + ExitOnFailure(hr, "Failed to add action text to custom action data");
464 +
465 + // assembly count
466 + switch (iRunMode)
467 + {
468 + case rmDeferred:
469 + iCount = pList->iInstallCount - pList->iCommitCount;
470 + break;
471 + case rmCommit:
472 + iCount = pList->iCommitCount;
473 + break;
474 + case rmRollback:
475 + iCount = pList->iInstallCount;
476 + break;
477 + }
478 +
479 + // add assembly count to action data
480 + hr = WcaWriteIntegerToCaData(iCount, ppwzActionData);
481 + ExitOnFailure(hr, "Failed to add count to custom action data");
482 +
483 + // add assemblies to custom action data in forward order
484 + for (CPI_ASSEMBLY* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
485 + {
486 + // assemblies that are being installed, or contains roll assignments to install
487 + if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
488 + continue;
489 +
490 + // assemblies that are being installed must be scheduled during the right type of action
491 + BOOL fRunInCommit = 0 != (pItm->iAttributes & aaRunInCommit);
492 + if (((rmCommit == iRunMode && !fRunInCommit) || (rmDeferred == iRunMode && fRunInCommit)))
493 + continue;
494 +
495 + // action type
496 + if (rmRollback == iRunMode)
497 + {
498 + if (CpiIsInstalled(pItm->isInstalled))
499 + iActionType = atNoOp;
500 + else
501 + iActionType = atRemove;
502 + }
503 + else
504 + iActionType = atCreate;
505 +
506 + // add to action data
507 + hr = AddAssemblyToActionData(pItm, TRUE, iActionType, COST_ASSEMBLY_REGISTER, ppwzActionData);
508 + ExitOnFailure(hr, "Failed to add assembly to custom action data, key: %S", pItm->wzKey);
509 + }
510 +
511 + // add progress tics
512 + if (piProgress)
513 + *piProgress += COST_ASSEMBLY_REGISTER * iCount;
514 +
515 + hr = S_OK;
516 +
517 +LExit:
518 + return hr;
519 +}
520 +
521 +HRESULT CpiAssembliesUninstall(
522 + CPI_ASSEMBLY_LIST* pList,
523 + int iRunMode,
524 + LPWSTR* ppwzActionData,
525 + int* piProgress
526 + )
527 +{
528 + HRESULT hr = S_OK;
529 +
530 + int iActionType;
531 +
532 + // add action text
533 + hr = CpiAddActionTextToActionData(L"UnregisterComPlusAssemblies", ppwzActionData);
534 + ExitOnFailure(hr, "Failed to add action text to custom action data");
535 +
536 + // add assembly count to action data
537 + hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
538 + ExitOnFailure(hr, "Failed to add count to custom action data");
539 +
540 + // add assemblies to custom action data in reverse order
541 + for (CPI_ASSEMBLY* pItm = pList->pLast; pItm; pItm = pItm->pPrev)
542 + {
543 + // assemblies that are being uninstalled
544 + if (pItm->fIgnore || (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction) && !WcaIsReInstalling(pItm->isInstalled, pItm->isAction)))
545 + continue;
546 +
547 + // action type
548 + if (rmRollback == iRunMode)
549 + iActionType = atCreate;
550 + else
551 + iActionType = atRemove;
552 +
553 + // add to action data
554 + hr = AddAssemblyToActionData(pItm, FALSE, iActionType, COST_ASSEMBLY_UNREGISTER, ppwzActionData);
555 + ExitOnFailure(hr, "Failed to add assembly to custom action data, key: %S", pItm->wzKey);
556 + }
557 +
558 + // add progress tics
559 + if (piProgress)
560 + *piProgress += COST_ASSEMBLY_UNREGISTER * pList->iUninstallCount;
561 +
562 + hr = S_OK;
563 +
564 +LExit:
565 + return hr;
566 +}
567 +
568 +HRESULT CpiRoleAssignmentsInstall(
569 + CPI_ASSEMBLY_LIST* pList,
570 + int iRunMode,
571 + LPWSTR* ppwzActionData,
572 + int* piProgress
573 + )
574 +{
575 + HRESULT hr = S_OK;
576 +
577 + int iActionType;
578 + int iCount = 0;
579 +
580 + // add action text
581 + hr = CpiAddActionTextToActionData(L"AddComPlusRoleAssignments", ppwzActionData);
582 + ExitOnFailure(hr, "Failed to add action text to custom action data");
583 +
584 + // assembly count
585 + switch (iRunMode)
586 + {
587 + case rmDeferred:
588 + iCount = pList->iRoleInstallCount - pList->iRoleCommitCount;
589 + break;
590 + case rmCommit:
591 + iCount = pList->iRoleCommitCount;
592 + break;
593 + case rmRollback:
594 + iCount = pList->iRoleInstallCount;
595 + break;
596 + }
597 +
598 + // add assembly count to action data
599 + hr = WcaWriteIntegerToCaData(iCount, ppwzActionData);
600 + ExitOnFailure(hr, "Failed to add count to custom action data");
601 +
602 + // add assemblies to custom action data in forward order
603 + for (CPI_ASSEMBLY* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
604 + {
605 + // assemblies that are being installed, or contains roll assignments to install
606 + if (!pItm->iRoleAssignmentsInstallCount)
607 + continue;
608 +
609 + // assemblies that are being installed must be scheduled during the right type of action
610 + BOOL fRunInCommit = 0 != (pItm->iAttributes & aaRunInCommit);
611 + if (((rmCommit == iRunMode && !fRunInCommit) || (rmDeferred == iRunMode && fRunInCommit)))
612 + continue;
613 +
614 + // action type
615 + if (rmRollback == iRunMode)
616 + {
617 + if (CpiIsInstalled(pItm->isInstalled))
618 + iActionType = atNoOp;
619 + else
620 + iActionType = atRemove;
621 + }
622 + else
623 + iActionType = atCreate;
624 +
625 + // add to action data
626 + hr = AddRoleAssignmentsToActionData(pItm, TRUE, iActionType, COST_ROLLASSIGNMENT_CREATE, ppwzActionData);
627 + ExitOnFailure(hr, "Failed to add assembly to custom action data, key: %S", pItm->wzKey);
628 +
629 + // add progress tics
630 + if (piProgress)
631 + *piProgress += COST_ROLLASSIGNMENT_CREATE * pItm->iRoleAssignmentsInstallCount;
632 + }
633 +
634 + hr = S_OK;
635 +
636 +LExit:
637 + return hr;
638 +}
639 +
640 +HRESULT CpiRoleAssignmentsUninstall(
641 + CPI_ASSEMBLY_LIST* pList,
642 + int iRunMode,
643 + LPWSTR* ppwzActionData,
644 + int* piProgress
645 + )
646 +{
647 + HRESULT hr = S_OK;
648 +
649 + int iActionType;
650 +
651 + // add action text
652 + hr = CpiAddActionTextToActionData(L"RemoveComPlusRoleAssignments", ppwzActionData);
653 + ExitOnFailure(hr, "Failed to add action text to custom action data");
654 +
655 + // add assembly count to action data
656 + hr = WcaWriteIntegerToCaData(pList->iRoleUninstallCount, ppwzActionData);
657 + ExitOnFailure(hr, "Failed to add count to custom action data");
658 +
659 + // add assemblies to custom action data in reverse order
660 + for (CPI_ASSEMBLY* pItm = pList->pLast; pItm; pItm = pItm->pPrev)
661 + {
662 + // assemblies that are being uninstalled
663 + if (pItm->fIgnore || !pItm->iRoleAssignmentsUninstallCount)
664 + continue;
665 +
666 + // action type
667 + if (rmRollback == iRunMode)
668 + iActionType = atCreate;
669 + else
670 + iActionType = atRemove;
671 +
672 + // add to action data
673 + hr = AddRoleAssignmentsToActionData(pItm, FALSE, iActionType, COST_ROLLASSIGNMENT_DELETE, ppwzActionData);
674 + ExitOnFailure(hr, "Failed to add assembly to custom action data, key: %S", pItm->wzKey);
675 +
676 + // add progress tics
677 + if (piProgress)
678 + *piProgress += COST_ROLLASSIGNMENT_DELETE * pItm->iRoleAssignmentsUninstallCount;
679 + }
680 +
681 + hr = S_OK;
682 +
683 +LExit:
684 + return hr;
685 +}
686 +
687 +HRESULT CpiGetSubscriptionsCollForComponent(
688 + CPI_ASSEMBLY* pAsm,
689 + CPI_COMPONENT* pComp,
690 + ICatalogCollection** ppiSubsColl
691 + )
692 +{
693 + HRESULT hr = S_OK;
694 +
695 + ICatalogCollection* piCompColl = NULL;
696 + ICatalogObject* piCompObj = NULL;
697 +
698 + // get applications collection
699 + if (!pComp->piSubsColl)
700 + {
701 + // get components collection for application
702 + hr = CpiGetComponentsCollForApplication(pAsm->pApplication, &piCompColl);
703 + ExitOnFailure(hr, "Failed to get components collection for application");
704 +
705 + if (S_FALSE == hr)
706 + ExitFunction(); // exit with hr = S_FALSE
707 +
708 + // find component object
709 + hr = CpiFindCollectionObject(piCompColl, pComp->wzCLSID, NULL, &piCompObj);
710 + ExitOnFailure(hr, "Failed to find component object");
711 +
712 + if (S_FALSE == hr)
713 + ExitFunction(); // exit with hr = S_FALSE
714 +
715 + // get roles collection
716 + hr = CpiGetCatalogCollection(piCompColl, piCompObj, L"SubscriptionsForComponent", &pComp->piSubsColl);
717 + ExitOnFailure(hr, "Failed to get subscriptions collection");
718 + }
719 +
720 + // return value
721 + *ppiSubsColl = pComp->piSubsColl;
722 + (*ppiSubsColl)->AddRef();
723 +
724 + hr = S_OK;
725 +
726 +LExit:
727 + // clean up
728 + ReleaseObject(piCompColl);
729 + ReleaseObject(piCompObj);
730 +
731 + return hr;
732 +}
733 +
734 +
735 +// helper function definitions
736 +
737 +static HRESULT GetAssemblyName(
738 + LPCWSTR pwzComponent,
739 + LPWSTR* ppwzAssemblyName
740 + )
741 +{
742 + HRESULT hr = S_OK;
743 +
744 + PMSIHANDLE hView, hRecKey, hRec;
745 +
746 + LPWSTR pwzKey = NULL;
747 +
748 + LPWSTR pwzName = NULL;
749 + LPWSTR pwzVersion = NULL;
750 + LPWSTR pwzCulture = NULL;
751 + LPWSTR pwzPublicKeyToken = NULL;
752 +
753 + // create parameter record
754 + hRecKey = ::MsiCreateRecord(1);
755 + ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
756 + hr = WcaSetRecordString(hRecKey, 1, pwzComponent);
757 + ExitOnFailure(hr, "Failed to set record string");
758 +
759 + // open view
760 + hr = WcaOpenView(vcsMsiAssemblyNameQuery, &hView);
761 + ExitOnFailure(hr, "Failed to open view on MsiAssemblyName table");
762 + hr = WcaExecuteView(hView, hRecKey);
763 + ExitOnFailure(hr, "Failed to execute view on MsiAssemblyName table");
764 +
765 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
766 + {
767 + // read key
768 + hr = WcaGetRecordString(hRec, manqName, &pwzKey);
769 + ExitOnFailure(hr, "Failed to get name");
770 +
771 + // read value
772 + if (0 == lstrcmpiW(L"name", pwzKey))
773 + hr = WcaGetRecordString(hRec, manqValue, &pwzName);
774 + else if (0 == lstrcmpiW(L"version", pwzKey))
775 + hr = WcaGetRecordString(hRec, manqValue, &pwzVersion);
776 + else if (0 == lstrcmpiW(L"culture", pwzKey))
777 + hr = WcaGetRecordString(hRec, manqValue, &pwzCulture);
778 + else if (0 == lstrcmpiW(L"publicKeyToken", pwzKey))
779 + hr = WcaGetRecordString(hRec, manqValue, &pwzPublicKeyToken);
780 + else
781 + {
782 + WcaLog(LOGMSG_VERBOSE, "Unknown name in MsiAssemblyName table: %S, %S", pwzComponent, pwzKey);
783 + hr = S_OK;
784 + }
785 +
786 + ExitOnFailure(hr, "Failed to get value");
787 + }
788 +
789 + if (E_NOMOREITEMS != hr)
790 + ExitOnFailure(hr, "Failed to fetch record");
791 +
792 + // verify
793 + if (!(pwzName && *pwzName) || !(pwzVersion && *pwzVersion))
794 + ExitOnFailure(hr = E_FAIL, "Incomplete assembly name");
795 +
796 + // build name string
797 + hr = StrAllocFormatted(ppwzAssemblyName, L"%s, Version=%s, Culture=%s, PublicKeyToken=%s",
798 + pwzName, pwzVersion,
799 + pwzCulture && *pwzCulture ? pwzCulture : L"Neutral",
800 + pwzPublicKeyToken && *pwzPublicKeyToken ? pwzPublicKeyToken : L"null");
801 + ExitOnFailure(hr, "Failed to build assembly name string");
802 +
803 + hr = S_OK;
804 +
805 +LExit:
806 + // clean up
807 + ReleaseStr(pwzKey);
808 + ReleaseStr(pwzName);
809 + ReleaseStr(pwzVersion);
810 + ReleaseStr(pwzCulture);
811 + ReleaseStr(pwzPublicKeyToken);
812 +
813 + return hr;
814 +}
815 +
816 +static HRESULT KeyPairsRead(
817 + LPCWSTR pwzQuery,
818 + CPI_KEY_PAIR** ppKeyPairList
819 + )
820 +{
821 + HRESULT hr = S_OK;
822 +
823 + PMSIHANDLE hView, hRec;
824 +
825 + CPI_KEY_PAIR* pItm = NULL;
826 + LPWSTR pwzData = NULL;
827 +
828 + // loop through all dependencies
829 + hr = WcaOpenExecuteView(pwzQuery, &hView);
830 + ExitOnFailure(hr, "Failed to execute view on table");
831 +
832 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
833 + {
834 + // create entry
835 + pItm = (CPI_KEY_PAIR*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_KEY_PAIR));
836 + if (!pItm)
837 + ExitFunction1(hr = E_OUTOFMEMORY);
838 +
839 + // get key
840 + hr = WcaGetRecordString(hRec, kpqFirstKey, &pwzData);
841 + ExitOnFailure(hr, "Failed to get first key");
842 + StringCchCopyW(pItm->wzFirstKey, countof(pItm->wzFirstKey), pwzData);
843 +
844 + // get key
845 + hr = WcaGetRecordString(hRec, kpqSecondKey, &pwzData);
846 + ExitOnFailure(hr, "Failed to get second key");
847 + StringCchCopyW(pItm->wzSecondKey, countof(pItm->wzSecondKey), pwzData);
848 +
849 + // add entry
850 + if (*ppKeyPairList)
851 + pItm->pNext = *ppKeyPairList;
852 + *ppKeyPairList = pItm;
853 + pItm = NULL;
854 + }
855 +
856 + if (E_NOMOREITEMS == hr)
857 + hr = S_OK;
858 +
859 +LExit:
860 + // clean up
861 + if (pItm)
862 + KeyPairsFreeList(pItm);
863 +
864 + ReleaseStr(pwzData);
865 +
866 + return hr;
867 +}
868 +
869 +static HRESULT ModulesRead(
870 + CPI_MODULE_LIST* pModList
871 + )
872 +{
873 + HRESULT hr = S_OK;
874 +
875 + PMSIHANDLE hView, hRec;
876 +
877 + CPI_MODULE* pItm = NULL;
878 + LPWSTR pwzData = NULL;
879 +
880 + // loop through all modules
881 + hr = WcaOpenExecuteView(vcsModuleQuery, &hView);
882 + ExitOnFailure(hr, "Failed to execute view on ModuleSignature table");
883 +
884 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
885 + {
886 + // create entry
887 + pItm = (CPI_MODULE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_MODULE));
888 + if (!pItm)
889 + ExitFunction1(hr = E_OUTOFMEMORY);
890 +
891 + // get key
892 + hr = WcaGetRecordString(hRec, mqModule, &pwzData);
893 + ExitOnFailure(hr, "Failed to get key");
894 + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
895 +
896 + // add entry
897 + if (pModList->pLast)
898 + {
899 + pModList->pLast->pNext = pItm;
900 + pItm->pPrev = pModList->pLast;
901 + }
902 + else
903 + pModList->pFirst = pItm;
904 + pModList->pLast = pItm;
905 + pItm = NULL;
906 + }
907 +
908 + if (E_NOMOREITEMS == hr)
909 + hr = S_OK;
910 +
911 +LExit:
912 + // clean up
913 + if (pItm)
914 + ModuleFree(pItm);
915 +
916 + ReleaseStr(pwzData);
917 +
918 + return hr;
919 +}
920 +
921 +static HRESULT AssembliesRead(
922 + CPI_KEY_PAIR* pModCompList,
923 + CPI_APPLICATION_LIST* pAppList,
924 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
925 + CPI_ASSEMBLY_LIST* pAsmList
926 + )
927 +{
928 + HRESULT hr = S_OK;
929 + UINT er = ERROR_SUCCESS;
930 +
931 + PMSIHANDLE hView, hRec;
932 +
933 + CPI_ASSEMBLY* pItm = NULL;
934 + CPI_KEY_PAIR* pModComp;
935 + LPWSTR pwzData = NULL;
936 + LPWSTR pwzComponent = NULL;
937 + BOOL fMatchingArchitecture = FALSE;
938 +
939 + // loop through all assemblies
940 + hr = WcaOpenExecuteView(vcsAssemblyQuery, &hView);
941 + ExitOnFailure(hr, "Failed to execute view on ComPlusAssembly table");
942 +
943 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
944 + {
945 + // get component
946 + hr = WcaGetRecordString(hRec, aqComponent, &pwzComponent);
947 + ExitOnFailure(hr, "Failed to get component");
948 +
949 + // check if the component is our processor architecture
950 + hr = CpiVerifyComponentArchitecure(pwzComponent, &fMatchingArchitecture);
951 + ExitOnFailure(hr, "Failed to get component architecture.");
952 +
953 + if (!fMatchingArchitecture)
954 + {
955 + continue; // not the same architecture, ignore
956 + }
957 +
958 + // create entry
959 + pItm = (CPI_ASSEMBLY*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_ASSEMBLY));
960 + if (!pItm)
961 + ExitFunction1(hr = E_OUTOFMEMORY);
962 +
963 + // get component install state
964 + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &pItm->isInstalled, &pItm->isAction);
965 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
966 +
967 + // get key
968 + hr = WcaGetRecordString(hRec, aqAssembly, &pwzData);
969 + ExitOnFailure(hr, "Failed to get key");
970 + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
971 +
972 + // get attributes
973 + hr = WcaGetRecordInteger(hRec, aqAttributes, &pItm->iAttributes);
974 + ExitOnFailure(hr, "Failed to get attributes");
975 +
976 + // get assembly name
977 + hr = WcaGetRecordFormattedString(hRec, aqAssemblyName, &pItm->pwzAssemblyName);
978 + ExitOnFailure(hr, "Failed to get assembly name");
979 +
980 + if (!*pItm->pwzAssemblyName && (pItm->iAttributes & aaPathFromGAC))
981 + {
982 + // get assembly name for component
983 + hr = GetAssemblyName(pwzComponent, &pItm->pwzAssemblyName);
984 + ExitOnFailure(hr, "Failed to get assembly name for component");
985 + }
986 +
987 + // get dll path
988 + hr = WcaGetRecordFormattedString(hRec, aqDllPath, &pItm->pwzDllPath);
989 + ExitOnFailure(hr, "Failed to get assembly dll path");
990 +
991 + // get module
992 + // TODO: if there is a very large number of components belonging to modules, this search might be slow
993 + hr = KeyPairFindByFirstKey(pModCompList, pwzData, &pModComp);
994 +
995 + if (S_OK == hr)
996 + StringCchCopyW(pItm->wzModule, countof(pItm->wzModule), pModComp->wzSecondKey);
997 +
998 + // get application
999 + hr = WcaGetRecordString(hRec, aqApplication, &pwzData);
1000 + ExitOnFailure(hr, "Failed to get application");
1001 +
1002 + if (pwzData && *pwzData)
1003 + {
1004 + hr = CpiApplicationFindByKey(pAppList, pwzData, &pItm->pApplication);
1005 + if (S_FALSE == hr)
1006 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1007 + ExitOnFailure(hr, "Failed to find application, key: %S", pwzData);
1008 + }
1009 +
1010 + // get tlb path
1011 + hr = WcaGetRecordFormattedString(hRec, aqTlbPath, &pItm->pwzTlbPath);
1012 + ExitOnFailure(hr, "Failed to get assembly tlb path");
1013 +
1014 + // get proxy-stub dll path
1015 + hr = WcaGetRecordFormattedString(hRec, aqPSDllPath, &pItm->pwzPSDllPath);
1016 + ExitOnFailure(hr, "Failed to get assembly proxy-stub DLL path");
1017 +
1018 + // read components
1019 + if (CpiTableExists(cptComPlusComponent))
1020 + {
1021 + hr = ComponentsRead(pItm->wzKey, pAppRoleList, pItm);
1022 + ExitOnFailure(hr, "Failed to read components for assembly");
1023 + }
1024 +
1025 + // set references & increment counters
1026 + if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
1027 + {
1028 + pAsmList->iInstallCount++;
1029 + if (pItm->iAttributes & aaRunInCommit)
1030 + pAsmList->iCommitCount++;
1031 + }
1032 + if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction) || WcaIsReInstalling(pItm->isInstalled, pItm->isAction))
1033 + pAsmList->iUninstallCount++;
1034 +
1035 + if (pItm->iRoleAssignmentsInstallCount)
1036 + {
1037 + pAsmList->iRoleInstallCount++;
1038 + if (pItm->iAttributes & aaRunInCommit)
1039 + pAsmList->iRoleCommitCount++;
1040 + }
1041 + if (pItm->iRoleAssignmentsUninstallCount)
1042 + pAsmList->iRoleUninstallCount++;
1043 +
1044 + if (pItm->pApplication)
1045 + {
1046 + if (pItm->iRoleAssignmentsInstallCount || WcaIsInstalling(pItm->isInstalled, pItm->isAction))
1047 + CpiApplicationAddReferenceInstall(pItm->pApplication);
1048 + if (pItm->iRoleAssignmentsUninstallCount || WcaIsUninstalling(pItm->isInstalled, pItm->isAction) || WcaIsReInstalling(pItm->isInstalled, pItm->isAction))
1049 + CpiApplicationAddReferenceUninstall(pItm->pApplication);
1050 + }
1051 +
1052 + // add entry
1053 + if (pAsmList->pLast)
1054 + {
1055 + pAsmList->pLast->pNext = pItm;
1056 + pItm->pPrev = pAsmList->pLast;
1057 + }
1058 + else
1059 + pAsmList->pFirst = pItm;
1060 + pAsmList->pLast = pItm;
1061 + pItm = NULL;
1062 + }
1063 +
1064 + if (E_NOMOREITEMS == hr)
1065 + hr = S_OK;
1066 +
1067 +LExit:
1068 + // clean up
1069 + if (pItm)
1070 + AssemblyFree(pItm);
1071 +
1072 + ReleaseStr(pwzData);
1073 + ReleaseStr(pwzComponent);
1074 +
1075 + return hr;
1076 +}
1077 +
1078 +static HRESULT TopSortModuleList(
1079 + CPI_KEY_PAIR* pDepList,
1080 + CPI_MODULE_LIST* pList
1081 + )
1082 +{
1083 + HRESULT hr = S_OK;
1084 +
1085 + // top sort list
1086 + for (CPI_MODULE* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
1087 + {
1088 + // append module
1089 + hr = SwapDependentModules(NULL, pDepList, pList, pItm, pItm);
1090 + ExitOnFailure(hr, "Failed to swap dependent modules");
1091 + }
1092 +
1093 + hr = S_OK;
1094 +
1095 +LExit:
1096 + return hr;
1097 +}
1098 +
1099 +static HRESULT SwapDependentModules(
1100 + CPI_DEPENDENCY_CHAIN* pdcPrev, // list containing the entire dependency chain
1101 + CPI_KEY_PAIR* pDepList, // module dependency list
1102 + CPI_MODULE_LIST* pList, // module list being sorted
1103 + CPI_MODULE* pRoot, // first module in the chain
1104 + CPI_MODULE* pItm // current module to test for dependencies
1105 + )
1106 +{
1107 + HRESULT hr = S_OK;
1108 +
1109 + CPI_MODULE* pDepItm;
1110 +
1111 + // find dependencies
1112 + for (CPI_KEY_PAIR* pDep = pDepList; pDep; pDep = pDep->pNext)
1113 + {
1114 + if (0 == lstrcmpW(pItm->wzKey, pDep->wzFirstKey))
1115 + {
1116 + CPI_DEPENDENCY_CHAIN dcItm;
1117 + dcItm.pwzKey = pItm->wzKey;
1118 + dcItm.pPrev = pdcPrev;
1119 +
1120 + // check for circular dependencies
1121 + for (CPI_DEPENDENCY_CHAIN* pdcItm = &dcItm; pdcItm; pdcItm = pdcItm->pPrev)
1122 + {
1123 + if (0 == lstrcmpW(pdcItm->pwzKey, pDep->wzSecondKey))
1124 + {
1125 + // circular dependency found
1126 + ExitOnFailure(hr = E_FAIL, "Circular module dependency found, key: %S", pDep->wzSecondKey);
1127 + }
1128 + }
1129 +
1130 + // make sure the item is not already in the list
1131 + hr = ModuleFindByKey(pRoot->pPrev, pDep->wzSecondKey, TRUE, &pDepItm); // find in reverse order
1132 +
1133 + if (S_OK == hr)
1134 + continue; // item found, move on
1135 +
1136 + // find item in the list
1137 + hr = ModuleFindByKey(pRoot->pNext, pDep->wzSecondKey, FALSE, &pDepItm); // find in forward order
1138 +
1139 + if (S_FALSE == hr)
1140 + {
1141 + // not found
1142 + ExitOnFailure(hr = E_FAIL, "Module dependency not found, key: %S", pDep->wzSecondKey);
1143 + }
1144 +
1145 + // if this item in turn has dependencies, they have to be swaped first
1146 + hr = SwapDependentModules(&dcItm, pDepList, pList, pRoot, pDepItm);
1147 + ExitOnFailure(hr, "Failed to swap dependent module");
1148 +
1149 + // remove item from its current position
1150 + pDepItm->pPrev->pNext = pDepItm->pNext; // pDepItm can never be the first item, no need to check pPrev
1151 + if (pDepItm->pNext)
1152 + pDepItm->pNext->pPrev = pDepItm->pPrev;
1153 + else
1154 + {
1155 + pList->pLast = pDepItm->pPrev;
1156 + pList->pLast->pNext = NULL;
1157 + }
1158 +
1159 + // insert before the current item
1160 + if (pRoot->pPrev)
1161 + pRoot->pPrev->pNext = pDepItm;
1162 + else
1163 + pList->pFirst = pDepItm;
1164 + pDepItm->pPrev = pRoot->pPrev;
1165 + pRoot->pPrev = pDepItm;
1166 + pDepItm->pNext = pRoot;
1167 + }
1168 + }
1169 +
1170 + hr = S_OK;
1171 +
1172 +LExit:
1173 + return hr;
1174 +}
1175 +
1176 +static HRESULT ModuleFindByKey(
1177 + CPI_MODULE* pItm,
1178 + LPCWSTR pwzKey,
1179 + BOOL fReverse,
1180 + CPI_MODULE** ppItm
1181 + )
1182 +{
1183 + for (; pItm; pItm = fReverse ? pItm->pPrev : pItm->pNext)
1184 + {
1185 + if (0 == lstrcmpW(pItm->wzKey, pwzKey))
1186 + {
1187 + *ppItm = pItm;
1188 + return S_OK;
1189 + }
1190 + }
1191 +
1192 + return S_FALSE;
1193 +}
1194 +
1195 +static void SortAssemblyListByModule(
1196 + CPI_MODULE_LIST* pModList,
1197 + CPI_ASSEMBLY_LIST* pAsmList
1198 + )
1199 +{
1200 + CPI_ASSEMBLY* pMoved = NULL; // first moved item
1201 +
1202 + // loop modules in reverse order
1203 + for (CPI_MODULE* pMod = pModList->pLast; pMod; pMod = pMod->pPrev)
1204 + {
1205 + // loop assemblies in forward order, starting with the first unmoved item
1206 + CPI_ASSEMBLY* pAsm = pMoved ? pMoved->pNext : pAsmList->pFirst;
1207 + while (pAsm)
1208 + {
1209 + CPI_ASSEMBLY* pNext = pAsm->pNext;
1210 +
1211 + // check if assembly belongs to the current module
1212 + if (0 == lstrcmpW(pMod->wzKey, pAsm->wzModule))
1213 + {
1214 + // if the item is not already first in the list
1215 + if (pAsm->pPrev)
1216 + {
1217 + // remove item from it's current position
1218 + pAsm->pPrev->pNext = pAsm->pNext;
1219 + if (pAsm->pNext)
1220 + pAsm->pNext->pPrev = pAsm->pPrev;
1221 + else
1222 + pAsmList->pLast = pAsm->pPrev;
1223 +
1224 + // insert item first in the list
1225 + pAsmList->pFirst->pPrev = pAsm;
1226 + pAsm->pNext = pAsmList->pFirst;
1227 + pAsm->pPrev = NULL;
1228 + pAsmList->pFirst = pAsm;
1229 + }
1230 +
1231 + // if we haven't moved any items yet, this is the first moved item
1232 + if (!pMoved)
1233 + pMoved = pAsm;
1234 + }
1235 +
1236 + pAsm = pNext;
1237 + }
1238 + }
1239 +}
1240 +
1241 +static HRESULT TopSortAssemblyList(
1242 + CPI_KEY_PAIR* pDepList,
1243 + CPI_ASSEMBLY_LIST* pList
1244 + )
1245 +{
1246 + HRESULT hr = S_OK;
1247 +
1248 + // top sort list
1249 + for (CPI_ASSEMBLY* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
1250 + {
1251 + // append module
1252 + hr = SwapDependentAssemblies(NULL, pDepList, pList, pItm, pItm);
1253 + ExitOnFailure(hr, "Failed to swap dependent assemblies");
1254 + }
1255 +
1256 + hr = S_OK;
1257 +
1258 +LExit:
1259 + return hr;
1260 +}
1261 +
1262 +static HRESULT SwapDependentAssemblies(
1263 + CPI_DEPENDENCY_CHAIN* pdcPrev, // list containing the entire dependency chain
1264 + CPI_KEY_PAIR* pDepList, // assembly dependency list
1265 + CPI_ASSEMBLY_LIST* pList, // assembly list being sorted
1266 + CPI_ASSEMBLY* pRoot, // first assembly in the chain
1267 + CPI_ASSEMBLY* pItm // current assembly to test for dependencies
1268 + )
1269 +{
1270 + HRESULT hr = S_OK;
1271 +
1272 + CPI_ASSEMBLY* pDepItm;
1273 +
1274 + // find dependencies
1275 + for (CPI_KEY_PAIR* pDep = pDepList; pDep; pDep = pDep->pNext)
1276 + {
1277 + if (0 == lstrcmpW(pItm->wzKey, pDep->wzFirstKey))
1278 + {
1279 + CPI_DEPENDENCY_CHAIN dcItm;
1280 + dcItm.pwzKey = pItm->wzKey;
1281 + dcItm.pPrev = pdcPrev;
1282 +
1283 + // check for circular dependencies
1284 + for (CPI_DEPENDENCY_CHAIN* pdcItm = &dcItm; pdcItm; pdcItm = pdcItm->pPrev)
1285 + {
1286 + if (0 == lstrcmpW(pdcItm->pwzKey, pDep->wzSecondKey))
1287 + {
1288 + // circular dependency found
1289 + ExitOnFailure(hr = E_FAIL, "Circular assembly dependency found, key: %S", pDep->wzSecondKey);
1290 + }
1291 + }
1292 +
1293 + // make sure the item is not already in the list
1294 + hr = AssemblyFindByKey(pRoot->pPrev, pDep->wzSecondKey, TRUE, &pDepItm); // find in reverse order
1295 +
1296 + if (S_OK == hr)
1297 + continue; // item found, move on
1298 +
1299 + // find item in the list
1300 + hr = AssemblyFindByKey(pRoot->pNext, pDep->wzSecondKey, FALSE, &pDepItm); // find in forward order
1301 +
1302 + if (S_FALSE == hr)
1303 + {
1304 + // not found
1305 + ExitOnFailure(hr = E_FAIL, "Assembly dependency not found, key: %S", pDep->wzSecondKey);
1306 + }
1307 +
1308 + // if the root item belongs to a module, this item must also belong to the same module
1309 + if (*pItm->wzModule)
1310 + {
1311 + if (0 != lstrcmpW(pDepItm->wzModule, pItm->wzModule))
1312 + ExitOnFailure(hr = E_FAIL, "An assembly dependency can only exist between two assemblies not belonging to modules, or belonging to the same module. assembly: %S, required assembly: %S", pItm->wzKey, pDepItm->wzKey);
1313 + }
1314 +
1315 + // if this item in turn has dependencies, they have to be swaped first
1316 + hr = SwapDependentAssemblies(&dcItm, pDepList, pList, pRoot, pDepItm);
1317 + ExitOnFailure(hr, "Failed to swap dependent assemblies");
1318 +
1319 + // remove item from its current position
1320 + pDepItm->pPrev->pNext = pDepItm->pNext; // pDepItm can never be the first item, no need to check pPrev
1321 + if (pDepItm->pNext)
1322 + pDepItm->pNext->pPrev = pDepItm->pPrev;
1323 + else
1324 + {
1325 + pList->pLast = pDepItm->pPrev;
1326 + pList->pLast->pNext = NULL;
1327 + }
1328 +
1329 + // insert before the current item
1330 + if (pRoot->pPrev)
1331 + pRoot->pPrev->pNext = pDepItm;
1332 + else
1333 + pList->pFirst = pDepItm;
1334 + pDepItm->pPrev = pRoot->pPrev;
1335 + pRoot->pPrev = pDepItm;
1336 + pDepItm->pNext = pRoot;
1337 + }
1338 + }
1339 +
1340 + hr = S_OK;
1341 +
1342 +LExit:
1343 + return hr;
1344 +}
1345 +
1346 +static HRESULT AssemblyFindByKey(
1347 + CPI_ASSEMBLY* pItm,
1348 + LPCWSTR pwzKey,
1349 + BOOL fReverse,
1350 + CPI_ASSEMBLY** ppItm
1351 + )
1352 +{
1353 + for (; pItm; pItm = fReverse ? pItm->pPrev : pItm->pNext)
1354 + {
1355 + if (0 == lstrcmpW(pItm->wzKey, pwzKey))
1356 + {
1357 + *ppItm = pItm;
1358 + return S_OK;
1359 + }
1360 + }
1361 +
1362 + return S_FALSE;
1363 +}
1364 +
1365 +static HRESULT ComponentsRead(
1366 + LPCWSTR pwzAsmKey,
1367 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
1368 + CPI_ASSEMBLY* pAsm
1369 + )
1370 +{
1371 + HRESULT hr = S_OK;
1372 + PMSIHANDLE hView;
1373 + PMSIHANDLE hRec;
1374 + PMSIHANDLE hRecKey;
1375 + CPI_COMPONENT* pItm = NULL;
1376 + LPWSTR pwzData = NULL;
1377 +
1378 + // create parameter record
1379 + hRecKey = ::MsiCreateRecord(1);
1380 + ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
1381 + hr = WcaSetRecordString(hRecKey, 1, pwzAsmKey);
1382 + ExitOnFailure(hr, "Failed to set record string");
1383 +
1384 + // open view
1385 + hr = WcaOpenView(vcsComponentQuery, &hView);
1386 + ExitOnFailure(hr, "Failed to open view on ComPlusComponent table");
1387 + hr = WcaExecuteView(hView, hRecKey);
1388 + ExitOnFailure(hr, "Failed to execute view on ComPlusComponent table");
1389 +
1390 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
1391 + {
1392 + // create entry
1393 + pItm = (CPI_COMPONENT*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_COMPONENT));
1394 + if (!pItm)
1395 + ExitFunction1(hr = E_OUTOFMEMORY);
1396 +
1397 + // get key
1398 + hr = WcaGetRecordString(hRec, cqComponent, &pwzData);
1399 + ExitOnFailure(hr, "Failed to get key");
1400 + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
1401 +
1402 + // get clsid
1403 + hr = WcaGetRecordFormattedString(hRec, cqCLSID, &pwzData);
1404 + ExitOnFailure(hr, "Failed to get clsid");
1405 + StringCchCopyW(pItm->wzCLSID, countof(pItm->wzCLSID), pwzData);
1406 +
1407 + // read properties
1408 + if (CpiTableExists(cptComPlusComponentProperty))
1409 + {
1410 + hr = CpiPropertiesRead(vcsComponentPropertyQuery, pItm->wzKey, pdlComponentProperties, &pItm->pProperties, &pItm->iPropertyCount);
1411 + ExitOnFailure(hr, "Failed to get component properties");
1412 + }
1413 +
1414 + // read roles
1415 + if (CpiTableExists(cptComPlusRoleForComponent))
1416 + {
1417 + hr = RoleAssignmentsRead(vcsRoleForComponentQuery, pItm->wzKey, pAppRoleList, &pItm->pRoles, &pItm->iRoleInstallCount, &pItm->iRoleUninstallCount);
1418 + ExitOnFailure(hr, "Failed to get roles for component");
1419 + }
1420 +
1421 + if (pItm->iRoleInstallCount)
1422 + pAsm->iRoleAssignmentsInstallCount++;
1423 + if (pItm->iRoleUninstallCount)
1424 + pAsm->iRoleAssignmentsUninstallCount++;
1425 +
1426 + // read interfaces
1427 + if (CpiTableExists(cptComPlusInterface))
1428 + {
1429 + hr = InterfacesRead(pItm->wzKey, pAppRoleList, pAsm, pItm);
1430 + ExitOnFailure(hr, "Failed to get interfaces for component");
1431 + }
1432 +
1433 + // add entry
1434 + pAsm->iComponentCount++;
1435 + if (pAsm->pComponents)
1436 + pItm->pNext = pAsm->pComponents;
1437 + pAsm->pComponents = pItm;
1438 + pItm = NULL;
1439 + }
1440 +
1441 + if (E_NOMOREITEMS == hr)
1442 + hr = S_OK;
1443 +
1444 +LExit:
1445 + // clean up
1446 + if (pItm)
1447 + ComponentsFreeList(pItm);
1448 +
1449 + ReleaseStr(pwzData);
1450 +
1451 + return hr;
1452 +}
1453 +
1454 +static HRESULT InterfacesRead(
1455 + LPCWSTR pwzCompKey,
1456 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
1457 + CPI_ASSEMBLY* pAsm,
1458 + CPI_COMPONENT* pComp
1459 + )
1460 +{
1461 + HRESULT hr = S_OK;
1462 + PMSIHANDLE hView;
1463 + PMSIHANDLE hRec;
1464 + PMSIHANDLE hRecKey;
1465 + CPI_INTERFACE* pItm = NULL;
1466 + LPWSTR pwzData = NULL;
1467 +
1468 + // create parameter record
1469 + hRecKey = ::MsiCreateRecord(1);
1470 + ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
1471 + hr = WcaSetRecordString(hRecKey, 1, pwzCompKey);
1472 + ExitOnFailure(hr, "Failed to set record string");
1473 +
1474 + // open view
1475 + hr = WcaOpenView(vcsInterfaceQuery, &hView);
1476 + ExitOnFailure(hr, "Failed to open view on ComPlusInterface table");
1477 + hr = WcaExecuteView(hView, hRecKey);
1478 + ExitOnFailure(hr, "Failed to execute view on ComPlusInterface table");
1479 +
1480 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
1481 + {
1482 + // create entry
1483 + pItm = (CPI_INTERFACE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_INTERFACE));
1484 + if (!pItm)
1485 + ExitFunction1(hr = E_OUTOFMEMORY);
1486 +
1487 + // get key
1488 + hr = WcaGetRecordString(hRec, iqInterface, &pwzData);
1489 + ExitOnFailure(hr, "Failed to get key");
1490 + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
1491 +
1492 + // get iid
1493 + hr = WcaGetRecordFormattedString(hRec, iqIID, &pwzData);
1494 + ExitOnFailure(hr, "Failed to get iid");
1495 + StringCchCopyW(pItm->wzIID, countof(pItm->wzIID), pwzData);
1496 +
1497 + // read properties
1498 + if (CpiTableExists(cptComPlusInterfaceProperty))
1499 + {
1500 + hr = CpiPropertiesRead(vcsInterfacePropertyQuery, pItm->wzKey, pdlInterfaceProperties, &pItm->pProperties, &pItm->iPropertyCount);
1501 + ExitOnFailure(hr, "Failed to get interface properties");
1502 + }
1503 +
1504 + // read roles
1505 + if (CpiTableExists(cptComPlusRoleForInterface))
1506 + {
1507 + hr = RoleAssignmentsRead(vcsRoleForInterfaceQuery, pItm->wzKey, pAppRoleList, &pItm->pRoles, &pItm->iRoleInstallCount, &pItm->iRoleUninstallCount);
1508 + ExitOnFailure(hr, "Failed to get roles for interface");
1509 + }
1510 +
1511 + if (pItm->iRoleInstallCount)
1512 + pAsm->iRoleAssignmentsInstallCount++;
1513 + if (pItm->iRoleUninstallCount)
1514 + pAsm->iRoleAssignmentsUninstallCount++;
1515 +
1516 + // read methods
1517 + if (CpiTableExists(cptComPlusMethod))
1518 + {
1519 + hr = MethodsRead(pItm->wzKey, pAppRoleList, pAsm, pItm);
1520 + ExitOnFailure(hr, "Failed to get methods for interface");
1521 + }
1522 +
1523 + // add entry
1524 + pComp->iInterfaceCount++;
1525 + if (pComp->pInterfaces)
1526 + pItm->pNext = pComp->pInterfaces;
1527 + pComp->pInterfaces = pItm;
1528 + pItm = NULL;
1529 + }
1530 +
1531 + if (E_NOMOREITEMS == hr)
1532 + hr = S_OK;
1533 +
1534 +LExit:
1535 + // clean up
1536 + if (pItm)
1537 + InterfacesFreeList(pItm);
1538 +
1539 + ReleaseStr(pwzData);
1540 +
1541 + return hr;
1542 +}
1543 +
1544 +static HRESULT MethodsRead(
1545 + LPCWSTR pwzIntfKey,
1546 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
1547 + CPI_ASSEMBLY* pAsm,
1548 + CPI_INTERFACE* pIntf
1549 + )
1550 +{
1551 + HRESULT hr = S_OK;
1552 + PMSIHANDLE hView, hRec, hRecKey;
1553 + CPI_METHOD* pItm = NULL;
1554 + LPWSTR pwzData = NULL;
1555 +
1556 + // create parameter record
1557 + hRecKey = ::MsiCreateRecord(1);
1558 + ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
1559 + hr = WcaSetRecordString(hRecKey, 1, pwzIntfKey);
1560 + ExitOnFailure(hr, "Failed to set record string");
1561 +
1562 + // open view
1563 + hr = WcaOpenView(vcsMethodQuery, &hView);
1564 + ExitOnFailure(hr, "Failed to open view on ComPlusMethod table");
1565 + hr = WcaExecuteView(hView, hRecKey);
1566 + ExitOnFailure(hr, "Failed to execute view on ComPlusMethod table");
1567 +
1568 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
1569 + {
1570 + // create entry
1571 + pItm = (CPI_METHOD*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_METHOD));
1572 + if (!pItm)
1573 + ExitFunction1(hr = E_OUTOFMEMORY);
1574 +
1575 + // get key
1576 + hr = WcaGetRecordString(hRec, iqInterface, &pwzData);
1577 + ExitOnFailure(hr, "Failed to get key");
1578 + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
1579 +
1580 + // get index
1581 + hr = WcaGetRecordFormattedString(hRec, mqIndex, &pwzData);
1582 + ExitOnFailure(hr, "Failed to get index");
1583 + StringCchCopyW(pItm->wzIndex, countof(pItm->wzIndex), pwzData);
1584 +
1585 + // get name
1586 + hr = WcaGetRecordFormattedString(hRec, mqName, &pwzData);
1587 + ExitOnFailure(hr, "Failed to get name");
1588 + StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
1589 +
1590 + // either an index or a name must be provided
1591 + if (!*pItm->wzIndex && !*pItm->wzName)
1592 + ExitOnFailure(hr = E_FAIL, "A method must have either an index or a name associated, key: %S", pItm->wzKey);
1593 +
1594 + // read properties
1595 + if (CpiTableExists(cptComPlusMethodProperty))
1596 + {
1597 + hr = CpiPropertiesRead(vcsMethodPropertyQuery, pItm->wzKey, pdlMethodProperties, &pItm->pProperties, &pItm->iPropertyCount);
1598 + ExitOnFailure(hr, "Failed to get method properties");
1599 + }
1600 +
1601 + // read roles
1602 + if (CpiTableExists(cptComPlusRoleForMethod))
1603 + {
1604 + hr = RoleAssignmentsRead(vcsRoleForMethodQuery, pItm->wzKey, pAppRoleList, &pItm->pRoles, &pItm->iRoleInstallCount, &pItm->iRoleUninstallCount);
1605 + ExitOnFailure(hr, "Failed to get roles for method");
1606 + }
1607 +
1608 + if (pItm->iRoleInstallCount)
1609 + pAsm->iRoleAssignmentsInstallCount++;
1610 + if (pItm->iRoleUninstallCount)
1611 + pAsm->iRoleAssignmentsUninstallCount++;
1612 +
1613 + // add entry
1614 + pIntf->iMethodCount++;
1615 + if (pIntf->pMethods)
1616 + pItm->pNext = pIntf->pMethods;
1617 + pIntf->pMethods = pItm;
1618 + pItm = NULL;
1619 + }
1620 +
1621 + if (E_NOMOREITEMS == hr)
1622 + hr = S_OK;
1623 +
1624 +LExit:
1625 + // clean up
1626 + if (pItm)
1627 + MethodsFreeList(pItm);
1628 +
1629 + ReleaseStr(pwzData);
1630 +
1631 + return hr;
1632 +}
1633 +
1634 +static HRESULT RoleAssignmentsRead(
1635 + LPCWSTR pwzQuery,
1636 + LPCWSTR pwzKey,
1637 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
1638 + CPI_ROLE_ASSIGNMENT** ppRoleList,
1639 + int* piInstallCount,
1640 + int* piUninstallCount
1641 + )
1642 +{
1643 + HRESULT hr = S_OK;
1644 + UINT er = ERROR_SUCCESS;
1645 +
1646 + PMSIHANDLE hView, hRec, hRecKey;
1647 +
1648 + CPI_ROLE_ASSIGNMENT* pItm = NULL;
1649 + LPWSTR pwzData = NULL;
1650 + BOOL fMatchingArchitecture = FALSE;
1651 +
1652 + // create parameter record
1653 + hRecKey = ::MsiCreateRecord(1);
1654 + ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
1655 + hr = WcaSetRecordString(hRecKey, 1, pwzKey);
1656 + ExitOnFailure(hr, "Failed to set record string");
1657 +
1658 + // open view
1659 + hr = WcaOpenView(pwzQuery, &hView);
1660 + ExitOnFailure(hr, "Failed to open view on role assignment table");
1661 + hr = WcaExecuteView(hView, hRecKey);
1662 + ExitOnFailure(hr, "Failed to execute view on role assignment table");
1663 +
1664 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
1665 + {
1666 + // get component
1667 + hr = WcaGetRecordString(hRec, raqComponent, &pwzData);
1668 + ExitOnFailure(hr, "Failed to get assembly component");
1669 +
1670 + // check if the component is our processor architecture
1671 + hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
1672 + ExitOnFailure(hr, "Failed to get component architecture.");
1673 +
1674 + if (!fMatchingArchitecture)
1675 + {
1676 + continue; // not the same architecture, ignore
1677 + }
1678 +
1679 + // create entry
1680 + pItm = (CPI_ROLE_ASSIGNMENT*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_ROLE_ASSIGNMENT));
1681 + if (!pItm)
1682 + ExitFunction1(hr = E_OUTOFMEMORY);
1683 +
1684 + // get component install state
1685 + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
1686 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
1687 +
1688 + // get key
1689 + hr = WcaGetRecordString(hRec, raqKey, &pwzData);
1690 + ExitOnFailure(hr, "Failed to get key");
1691 + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
1692 +
1693 + // get application role
1694 + hr = WcaGetRecordString(hRec, raqApplicationRole, &pwzData);
1695 + ExitOnFailure(hr, "Failed to get application role");
1696 +
1697 + hr = CpiApplicationRoleFindByKey(pAppRoleList, pwzData, &pItm->pApplicationRole);
1698 + if (S_FALSE == hr)
1699 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
1700 + ExitOnFailure(hr, "Failed to find application, key: %S", pwzData);
1701 +
1702 + // set references & increment counters
1703 + if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
1704 + {
1705 + CpiApplicationRoleAddReferenceInstall(pItm->pApplicationRole);
1706 + ++*piInstallCount;
1707 + }
1708 + if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
1709 + {
1710 + CpiApplicationRoleAddReferenceUninstall(pItm->pApplicationRole);
1711 + ++*piUninstallCount;
1712 + }
1713 +
1714 + // add entry
1715 + if (*ppRoleList)
1716 + pItm->pNext = *ppRoleList;
1717 + *ppRoleList = pItm;
1718 + pItm = NULL;
1719 + }
1720 +
1721 + if (E_NOMOREITEMS == hr)
1722 + hr = S_OK;
1723 +
1724 +LExit:
1725 + // clean up
1726 + if (pItm)
1727 + RoleAssignmentsFreeList(pItm);
1728 +
1729 + ReleaseStr(pwzData);
1730 +
1731 + return hr;
1732 +}
1733 +
1734 +static HRESULT AddAssemblyToActionData(
1735 + CPI_ASSEMBLY* pItm,
1736 + BOOL fInstall,
1737 + int iActionType,
1738 + int iActionCost,
1739 + LPWSTR* ppwzActionData
1740 + )
1741 +{
1742 + HRESULT hr = S_OK;
1743 +
1744 + // add action information to custom action data
1745 + hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
1746 + ExitOnFailure(hr, "Failed to add action type to custom action data");
1747 + hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
1748 + ExitOnFailure(hr, "Failed to add action cost to custom action data");
1749 +
1750 + // add assembly information to custom action data
1751 + hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
1752 + ExitOnFailure(hr, "Failed to add assembly key to custom action data");
1753 + hr = WcaWriteStringToCaData(pItm->pwzAssemblyName, ppwzActionData);
1754 + ExitOnFailure(hr, "Failed to add assembly name to custom action data");
1755 + hr = WcaWriteStringToCaData(pItm->pwzDllPath, ppwzActionData);
1756 + ExitOnFailure(hr, "Failed to add assembly dll path to custom action data");
1757 + hr = WcaWriteStringToCaData(atCreate == iActionType ? pItm->pwzTlbPath : L"", ppwzActionData);
1758 + ExitOnFailure(hr, "Failed to add assembly tlb path to custom action data");
1759 + hr = WcaWriteStringToCaData(atCreate == iActionType ? pItm->pwzPSDllPath : L"", ppwzActionData);
1760 + ExitOnFailure(hr, "Failed to add assembly proxy-stub dll path to custom action data");
1761 + hr = WcaWriteIntegerToCaData(pItm->iAttributes, ppwzActionData);
1762 + ExitOnFailure(hr, "Failed to add assembly attributes to custom action data");
1763 +
1764 + // add application information to custom action data
1765 + hr = WcaWriteStringToCaData(pItm->pApplication ? pItm->pApplication->wzID : L"", ppwzActionData);
1766 + ExitOnFailure(hr, "Failed to add application id to custom action data");
1767 +
1768 + // add partition information to custom action data
1769 + LPCWSTR pwzPartID = pItm->pApplication && pItm->pApplication->pPartition ? pItm->pApplication->pPartition->wzID : L"";
1770 + hr = WcaWriteStringToCaData(pwzPartID, ppwzActionData);
1771 + ExitOnFailure(hr, "Failed to add partition id to custom action data");
1772 +
1773 + // add components to custom action data
1774 + //
1775 + // components are needed acording to the following table:
1776 + //
1777 + // Native .NET
1778 + // --------------------------------------------
1779 + // NoOp | No | No
1780 + // Create | Yes | Yes
1781 + // Remove | Yes | No
1782 + //
1783 + int iCompCount = (atCreate == iActionType || (atRemove == iActionType && 0 == (pItm->iAttributes & aaDotNetAssembly))) ? pItm->iComponentCount : 0;
1784 + hr = WcaWriteIntegerToCaData(iCompCount, ppwzActionData);
1785 + ExitOnFailure(hr, "Failed to add component count to custom action data, key: %S", pItm->wzKey);
1786 +
1787 + if (iCompCount)
1788 + {
1789 + for (CPI_COMPONENT* pComp = pItm->pComponents; pComp; pComp = pComp->pNext)
1790 + {
1791 + hr = AddComponentToActionData(pComp, fInstall, atCreate == iActionType, FALSE, ppwzActionData);
1792 + ExitOnFailure(hr, "Failed to add component to custom action data, component: %S", pComp->wzKey);
1793 + }
1794 + }
1795 +
1796 + hr = S_OK;
1797 +
1798 +LExit:
1799 + return hr;
1800 +}
1801 +
1802 +static HRESULT AddRoleAssignmentsToActionData(
1803 + CPI_ASSEMBLY* pItm,
1804 + BOOL fInstall,
1805 + int iActionType,
1806 + int iActionCost,
1807 + LPWSTR* ppwzActionData
1808 + )
1809 +{
1810 + HRESULT hr = S_OK;
1811 +
1812 + // add action information to custom action data
1813 + hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
1814 + ExitOnFailure(hr, "Failed to add action type to custom action data");
1815 + hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
1816 + ExitOnFailure(hr, "Failed to add action cost to custom action data");
1817 +
1818 + // add assembly information to custom action data
1819 + hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
1820 + ExitOnFailure(hr, "Failed to add assembly key to custom action data");
1821 + hr = WcaWriteIntegerToCaData(fInstall ? pItm->iRoleAssignmentsInstallCount : pItm->iRoleAssignmentsUninstallCount, ppwzActionData);
1822 + ExitOnFailure(hr, "Failed to add role assignments count to custom action data");
1823 +
1824 + // add application information to custom action data
1825 + hr = WcaWriteStringToCaData(pItm->pApplication ? pItm->pApplication->wzID : L"", ppwzActionData);
1826 + ExitOnFailure(hr, "Failed to add application id to custom action data");
1827 +
1828 + // add partition information to custom action data
1829 + LPCWSTR pwzPartID = pItm->pApplication && pItm->pApplication->pPartition ? pItm->pApplication->pPartition->wzID : L"";
1830 + hr = WcaWriteStringToCaData(pwzPartID, ppwzActionData);
1831 + ExitOnFailure(hr, "Failed to add partition id to custom action data");
1832 +
1833 + // add components to custom action data
1834 + hr = WcaWriteIntegerToCaData(pItm->iComponentCount, ppwzActionData);
1835 + ExitOnFailure(hr, "Failed to add component count to custom action data");
1836 +
1837 + for (CPI_COMPONENT* pComp = pItm->pComponents; pComp; pComp = pComp->pNext)
1838 + {
1839 + hr = AddComponentToActionData(pComp, fInstall, FALSE, TRUE, ppwzActionData);
1840 + ExitOnFailure(hr, "Failed to add component to custom action data, component: %S", pComp->wzKey);
1841 + }
1842 +
1843 + hr = S_OK;
1844 +
1845 +LExit:
1846 + return hr;
1847 +}
1848 +
1849 +static HRESULT AddComponentToActionData(
1850 + CPI_COMPONENT* pItm,
1851 + BOOL fInstall,
1852 + BOOL fProps,
1853 + BOOL fRoles,
1854 + LPWSTR* ppwzActionData
1855 + )
1856 +{
1857 + HRESULT hr = S_OK;
1858 +
1859 + // add component information to custom action data
1860 + hr = WcaWriteStringToCaData(pItm->wzCLSID, ppwzActionData);
1861 + ExitOnFailure(hr, "Failed to add component CLSID to custom action data");
1862 +
1863 + // add properties to custom action data
1864 + hr = CpiAddPropertiesToActionData(fProps ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
1865 + ExitOnFailure(hr, "Failed to add properties to custom action data");
1866 +
1867 + // add roles to custom action data
1868 + hr = AddRolesToActionData(pItm->iRoleInstallCount, pItm->iRoleUninstallCount, pItm->pRoles, fInstall, fRoles, ppwzActionData);
1869 + ExitOnFailure(hr, "Failed to add roles to custom action data");
1870 +
1871 + // add interfaces to custom action data
1872 + int iIntfCount = (fProps || fRoles) ? pItm->iInterfaceCount : 0;
1873 + hr = WcaWriteIntegerToCaData(iIntfCount, ppwzActionData);
1874 + ExitOnFailure(hr, "Failed to add interface count to custom action data");
1875 +
1876 + if (iIntfCount)
1877 + {
1878 + for (CPI_INTERFACE* pIntf = pItm->pInterfaces; pIntf; pIntf = pIntf->pNext)
1879 + {
1880 + hr = AddInterfaceToActionData(pIntf, fInstall, fProps, fRoles, ppwzActionData);
1881 + ExitOnFailure(hr, "Failed to add interface custom action data, interface: %S", pIntf->wzKey);
1882 + }
1883 + }
1884 +
1885 + hr = S_OK;
1886 +
1887 +LExit:
1888 + return hr;
1889 +}
1890 +
1891 +static HRESULT AddInterfaceToActionData(
1892 + CPI_INTERFACE* pItm,
1893 + BOOL fInstall,
1894 + BOOL fProps,
1895 + BOOL fRoles,
1896 + LPWSTR* ppwzActionData
1897 + )
1898 +{
1899 + HRESULT hr = S_OK;
1900 +
1901 + // add interface information to custom action data
1902 + hr = WcaWriteStringToCaData(pItm->wzIID, ppwzActionData);
1903 + ExitOnFailure(hr, "Failed to add interface IID to custom action data");
1904 +
1905 + // add properties to custom action data
1906 + hr = CpiAddPropertiesToActionData(fProps ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
1907 + ExitOnFailure(hr, "Failed to add properties to custom action data");
1908 +
1909 + // add roles to custom action data
1910 + hr = AddRolesToActionData(pItm->iRoleInstallCount, pItm->iRoleUninstallCount, pItm->pRoles, fInstall, fRoles, ppwzActionData);
1911 + ExitOnFailure(hr, "Failed to add roles to custom action data");
1912 +
1913 + // add methods to custom action data
1914 + hr = WcaWriteIntegerToCaData(pItm->iMethodCount, ppwzActionData);
1915 + ExitOnFailure(hr, "Failed to add method count to custom action data");
1916 +
1917 + for (CPI_METHOD* pMeth = pItm->pMethods; pMeth; pMeth = pMeth->pNext)
1918 + {
1919 + hr = AddMethodToActionData(pMeth, fInstall, fProps, fRoles, ppwzActionData);
1920 + ExitOnFailure(hr, "Failed to add method custom action data, method: %S", pMeth->wzKey);
1921 + }
1922 +
1923 + hr = S_OK;
1924 +
1925 +LExit:
1926 + return hr;
1927 +}
1928 +
1929 +static HRESULT AddMethodToActionData(
1930 + CPI_METHOD* pItm,
1931 + BOOL fInstall,
1932 + BOOL fProps,
1933 + BOOL fRoles,
1934 + LPWSTR* ppwzActionData
1935 + )
1936 +{
1937 + HRESULT hr = S_OK;
1938 +
1939 + // add interface information to custom action data
1940 + hr = WcaWriteStringToCaData(pItm->wzIndex, ppwzActionData);
1941 + ExitOnFailure(hr, "Failed to add method index to custom action data");
1942 +
1943 + hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData);
1944 + ExitOnFailure(hr, "Failed to add method name to custom action data");
1945 +
1946 + // add properties to custom action data
1947 + hr = CpiAddPropertiesToActionData(fProps ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
1948 + ExitOnFailure(hr, "Failed to add properties to custom action data");
1949 +
1950 + // add roles to custom action data
1951 + hr = AddRolesToActionData(pItm->iRoleInstallCount, pItm->iRoleUninstallCount, pItm->pRoles, fInstall, fRoles, ppwzActionData);
1952 + ExitOnFailure(hr, "Failed to add roles to custom action data");
1953 +
1954 + hr = S_OK;
1955 +
1956 +LExit:
1957 + return hr;
1958 +}
1959 +
1960 +static HRESULT AddRolesToActionData(
1961 + int iRoleInstallCount,
1962 + int iRoleUninstallCount,
1963 + CPI_ROLE_ASSIGNMENT* pRoleList,
1964 + BOOL fInstall,
1965 + BOOL fRoles,
1966 + LPWSTR* ppwzActionData
1967 + )
1968 +{
1969 + HRESULT hr = S_OK;
1970 +
1971 + int iRoleCount = fRoles ? (fInstall ? iRoleInstallCount : iRoleUninstallCount) : 0;
1972 + hr = WcaWriteIntegerToCaData(iRoleCount, ppwzActionData);
1973 + ExitOnFailure(hr, "Failed to add role count to custom action data");
1974 +
1975 + if (iRoleCount)
1976 + {
1977 + for (CPI_ROLE_ASSIGNMENT* pRole = pRoleList; pRole; pRole = pRole->pNext)
1978 + {
1979 + // make sure the install state matches the create flag
1980 + if (fInstall ? !WcaIsInstalling(pRole->isInstalled, pRole->isAction) : !WcaIsUninstalling(pRole->isInstalled, pRole->isAction))
1981 + continue;
1982 +
1983 + hr = WcaWriteStringToCaData(pRole->pApplicationRole->wzKey, ppwzActionData);
1984 + ExitOnFailure(hr, "Failed to add key to custom action data, role: %S", pRole->wzKey);
1985 +
1986 + hr = WcaWriteStringToCaData(pRole->pApplicationRole->wzName, ppwzActionData);
1987 + ExitOnFailure(hr, "Failed to add role name to custom action data, role: %S", pRole->wzKey);
1988 + }
1989 + }
1990 +
1991 + hr = S_OK;
1992 +
1993 +LExit:
1994 + return hr;
1995 +}
1996 +
1997 +static HRESULT KeyPairFindByFirstKey(
1998 + CPI_KEY_PAIR* pList,
1999 + LPCWSTR pwzKey,
2000 + CPI_KEY_PAIR** ppItm
2001 + )
2002 +{
2003 + for (; pList; pList = pList->pNext)
2004 + {
2005 + if (0 == lstrcmpW(pList->wzFirstKey, pwzKey))
2006 + {
2007 + *ppItm = pList;
2008 + return S_OK;
2009 + }
2010 + }
2011 +
2012 + return S_FALSE;
2013 +}
2014 +
2015 +static void AssemblyFree(
2016 + CPI_ASSEMBLY* pItm
2017 + )
2018 +{
2019 + ReleaseStr(pItm->pwzAssemblyName);
2020 + ReleaseStr(pItm->pwzDllPath);
2021 + ReleaseStr(pItm->pwzTlbPath);
2022 + ReleaseStr(pItm->pwzPSDllPath);
2023 +
2024 + if (pItm->pComponents)
2025 + ComponentsFreeList(pItm->pComponents);
2026 +
2027 + ::HeapFree(::GetProcessHeap(), 0, pItm);
2028 +}
2029 +
2030 +static void KeyPairsFreeList(
2031 + CPI_KEY_PAIR* pList
2032 + )
2033 +{
2034 + while (pList)
2035 + {
2036 + CPI_KEY_PAIR* pDelete = pList;
2037 + pList = pList->pNext;
2038 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
2039 + }
2040 +}
2041 +
2042 +void ModuleListFree(
2043 + CPI_MODULE_LIST* pList
2044 + )
2045 +{
2046 + CPI_MODULE* pItm = pList->pFirst;
2047 +
2048 + while (pItm)
2049 + {
2050 + CPI_MODULE* pDelete = pItm;
2051 + pItm = pItm->pNext;
2052 + ModuleFree(pDelete);
2053 + }
2054 +}
2055 +
2056 +static void ModuleFree(
2057 + CPI_MODULE* pItm
2058 + )
2059 +{
2060 + ::HeapFree(::GetProcessHeap(), 0, pItm);
2061 +}
2062 +
2063 +static void ComponentsFreeList(
2064 + CPI_COMPONENT* pList
2065 + )
2066 +{
2067 + while (pList)
2068 + {
2069 + if (pList->pProperties)
2070 + CpiPropertiesFreeList(pList->pProperties);
2071 +
2072 + if (pList->pRoles)
2073 + RoleAssignmentsFreeList(pList->pRoles);
2074 +
2075 + if (pList->pInterfaces)
2076 + InterfacesFreeList(pList->pInterfaces);
2077 +
2078 + ReleaseObject(pList->piSubsColl);
2079 +
2080 + CPI_COMPONENT* pDelete = pList;
2081 + pList = pList->pNext;
2082 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
2083 + }
2084 +}
2085 +
2086 +static void InterfacesFreeList(
2087 + CPI_INTERFACE* pList
2088 + )
2089 +{
2090 + while (pList)
2091 + {
2092 + if (pList->pProperties)
2093 + CpiPropertiesFreeList(pList->pProperties);
2094 +
2095 + if (pList->pRoles)
2096 + RoleAssignmentsFreeList(pList->pRoles);
2097 +
2098 + if (pList->pMethods)
2099 + MethodsFreeList(pList->pMethods);
2100 +
2101 + CPI_INTERFACE* pDelete = pList;
2102 + pList = pList->pNext;
2103 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
2104 + }
2105 +}
2106 +
2107 +static void MethodsFreeList(
2108 + CPI_METHOD* pList
2109 + )
2110 +{
2111 + while (pList)
2112 + {
2113 + if (pList->pProperties)
2114 + CpiPropertiesFreeList(pList->pProperties);
2115 +
2116 + if (pList->pRoles)
2117 + RoleAssignmentsFreeList(pList->pRoles);
2118 +
2119 + CPI_METHOD* pDelete = pList;
2120 + pList = pList->pNext;
2121 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
2122 + }
2123 +}
2124 +
2125 +static void RoleAssignmentsFreeList(
2126 + CPI_ROLE_ASSIGNMENT* pList
2127 + )
2128 +{
2129 + while (pList)
2130 + {
2131 + CPI_ROLE_ASSIGNMENT* pDelete = pList;
2132 + pList = pList->pNext;
2133 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
2134 + }
2135 +}
src/ca/cpasmsched.h new
+168
@@ -0,0 +1,168 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +enum eAssemblyAttributes
6 +{
7 + aaEventClass = (1 << 0),
8 + aaDotNetAssembly = (1 << 1),
9 + aaPathFromGAC = (1 << 2),
10 + aaRunInCommit = (1 << 3)
11 +};
12 +
13 +
14 +// structs
15 +
16 +struct CPI_ROLE_ASSIGNMENT
17 +{
18 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
19 +
20 + INSTALLSTATE isInstalled, isAction;
21 +
22 + CPI_APPLICATION_ROLE* pApplicationRole;
23 +
24 + CPI_ROLE_ASSIGNMENT* pNext;
25 +};
26 +
27 +struct CPI_METHOD
28 +{
29 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
30 + WCHAR wzIndex[11 + 1];
31 + WCHAR wzName[MAX_DARWIN_COLUMN + 1];
32 +
33 + int iPropertyCount;
34 + CPI_PROPERTY* pProperties;
35 +
36 + int iRoleInstallCount;
37 + int iRoleUninstallCount;
38 + CPI_ROLE_ASSIGNMENT* pRoles;
39 +
40 + CPI_METHOD* pNext;
41 +};
42 +
43 +struct CPI_INTERFACE
44 +{
45 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
46 + WCHAR wzIID[CPI_MAX_GUID + 1];
47 +
48 + int iPropertyCount;
49 + CPI_PROPERTY* pProperties;
50 +
51 + int iRoleInstallCount;
52 + int iRoleUninstallCount;
53 + CPI_ROLE_ASSIGNMENT* pRoles;
54 +
55 + int iMethodCount;
56 + CPI_METHOD* pMethods;
57 +
58 + CPI_INTERFACE* pNext;
59 +};
60 +
61 +struct CPI_COMPONENT
62 +{
63 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
64 + WCHAR wzCLSID[CPI_MAX_GUID + 1];
65 +
66 + int iPropertyCount;
67 + CPI_PROPERTY* pProperties;
68 +
69 + int iRoleInstallCount;
70 + int iRoleUninstallCount;
71 + CPI_ROLE_ASSIGNMENT* pRoles;
72 +
73 + int iInterfaceCount;
74 + CPI_INTERFACE* pInterfaces;
75 +
76 + ICatalogCollection* piSubsColl;
77 +
78 + CPI_COMPONENT* pNext;
79 +};
80 +
81 +struct CPI_ASSEMBLY
82 +{
83 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
84 + WCHAR wzModule[MAX_DARWIN_KEY + 1];
85 + LPWSTR pwzAssemblyName;
86 + LPWSTR pwzDllPath;
87 + LPWSTR pwzTlbPath;
88 + LPWSTR pwzPSDllPath;
89 + int iAttributes;
90 +
91 + int iComponentCount;
92 + CPI_COMPONENT* pComponents;
93 +
94 + BOOL fReferencedForInstall;
95 + BOOL fReferencedForUninstall;
96 + BOOL fIgnore;
97 +
98 + int iRoleAssignmentsInstallCount;
99 + int iRoleAssignmentsUninstallCount;
100 +
101 + INSTALLSTATE isInstalled, isAction;
102 +
103 + CPI_APPLICATION* pApplication;
104 +
105 + CPI_ASSEMBLY* pPrev;
106 + CPI_ASSEMBLY* pNext;
107 +};
108 +
109 +struct CPI_ASSEMBLY_LIST
110 +{
111 + CPI_ASSEMBLY* pFirst;
112 + CPI_ASSEMBLY* pLast;
113 +
114 + int iInstallCount;
115 + int iCommitCount;
116 + int iUninstallCount;
117 +
118 + int iRoleInstallCount;
119 + int iRoleCommitCount;
120 + int iRoleUninstallCount;
121 +};
122 +
123 +
124 +// function prototypes
125 +
126 +void CpiAssemblyListFree(
127 + CPI_ASSEMBLY_LIST* pList
128 + );
129 +HRESULT CpiAssembliesRead(
130 + CPI_APPLICATION_LIST* pAppList,
131 + CPI_APPLICATION_ROLE_LIST* pAppRoleList,
132 + CPI_ASSEMBLY_LIST* pAsmList
133 + );
134 +HRESULT CpiAssembliesVerifyInstall(
135 + CPI_ASSEMBLY_LIST* pList
136 + );
137 +HRESULT CpiAssembliesVerifyUninstall(
138 + CPI_ASSEMBLY_LIST* pList
139 + );
140 +HRESULT CpiAssembliesInstall(
141 + CPI_ASSEMBLY_LIST* pList,
142 + int iRunMode,
143 + LPWSTR* ppwzActionData,
144 + int* piProgress
145 + );
146 +HRESULT CpiAssembliesUninstall(
147 + CPI_ASSEMBLY_LIST* pList,
148 + int iRunMode,
149 + LPWSTR* ppwzActionData,
150 + int* piProgress
151 + );
152 +HRESULT CpiRoleAssignmentsInstall(
153 + CPI_ASSEMBLY_LIST* pList,
154 + int iRunMode,
155 + LPWSTR* ppwzActionData,
156 + int* piProgress
157 + );
158 +HRESULT CpiRoleAssignmentsUninstall(
159 + CPI_ASSEMBLY_LIST* pList,
160 + int iRunMode,
161 + LPWSTR* ppwzActionData,
162 + int* piProgress
163 + );
164 +HRESULT CpiGetSubscriptionsCollForComponent(
165 + CPI_ASSEMBLY* pAsm,
166 + CPI_COMPONENT* pComp,
167 + ICatalogCollection** ppiSubsColl
168 + );
src/ca/cpcost.h new
+30
@@ -0,0 +1,30 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +#define COST_PARTITION_CREATE 10000
6 +#define COST_PARTITION_DELETE 10000
7 +
8 +#define COST_PARTITION_USER_CREATE 10000
9 +#define COST_PARTITION_USER_DELETE 10000
10 +
11 +#define COST_USER_IN_PARTITION_ROLE_CREATE 10000
12 +#define COST_USER_IN_PARTITION_ROLE_DELETE 10000
13 +
14 +#define COST_APPLICATION_CREATE 10000
15 +#define COST_APPLICATION_DELETE 10000
16 +
17 +#define COST_APPLICATION_ROLE_CREATE 10000
18 +#define COST_APPLICATION_ROLE_DELETE 10000
19 +
20 +#define COST_USER_IN_APPLICATION_ROLE_CREATE 10000
21 +#define COST_USER_IN_APPLICATION_ROLE_DELETE 10000
22 +
23 +#define COST_ASSEMBLY_REGISTER 50000
24 +#define COST_ASSEMBLY_UNREGISTER 10000
25 +
26 +#define COST_ROLLASSIGNMENT_CREATE 10000
27 +#define COST_ROLLASSIGNMENT_DELETE 10000
28 +
29 +#define COST_SUBSCRIPTION_CREATE 10000
30 +#define COST_SUBSCRIPTION_DELETE 10000
src/ca/cpexec.cpp new
+704
@@ -0,0 +1,704 @@
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 + DllMain - standard entry point for all WiX CustomActions
7 +
8 +********************************************************************/
9 +extern "C" BOOL WINAPI DllMain(
10 + IN HINSTANCE hInst,
11 + IN ULONG ulReason,
12 + IN LPVOID)
13 +{
14 + switch(ulReason)
15 + {
16 + case DLL_PROCESS_ATTACH:
17 + WcaGlobalInitialize(hInst);
18 + break;
19 +
20 + case DLL_PROCESS_DETACH:
21 + WcaGlobalFinalize();
22 + break;
23 + }
24 +
25 + return TRUE;
26 +}
27 +
28 +/********************************************************************
29 + ComPlusPrepare - CUSTOM ACTION ENTRY POINT
30 +
31 + Input: deferred CustomActionData - ComPlusPrepare
32 +********************************************************************/
33 +extern "C" UINT __stdcall ComPlusPrepare(MSIHANDLE hInstall)
34 +{
35 + HRESULT hr = S_OK;
36 + UINT er = ERROR_SUCCESS;
37 +
38 + LPWSTR pwzCustomActionData = NULL;
39 + LPWSTR pwzData = NULL;
40 +
41 + HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
42 +
43 + // initialize
44 + hr = WcaInitialize(hInstall, "ComPlusPrepare");
45 + ExitOnFailure(hr, "Failed to initialize ComPlusPrepare");
46 +
47 + // get custom action data
48 + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
49 + ExitOnFailure(hr, "Failed to get CustomActionData");
50 + pwzData = pwzCustomActionData;
51 +
52 + // create rollback file
53 + hRollbackFile = ::CreateFileW(pwzData, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, NULL);
54 + if (INVALID_HANDLE_VALUE == hRollbackFile)
55 + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to create rollback file, name: %S", pwzData);
56 +
57 + hr = S_OK;
58 +
59 +LExit:
60 + // clean up
61 + ReleaseStr(pwzCustomActionData);
62 +
63 + if (INVALID_HANDLE_VALUE != hRollbackFile)
64 + ::CloseHandle(hRollbackFile);
65 +
66 + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
67 + return WcaFinalize(er);
68 +}
69 +
70 +/********************************************************************
71 + ComPlusCleanup - CUSTOM ACTION ENTRY POINT
72 +
73 + Input: deferred CustomActionData - ComPlusCleanup
74 +********************************************************************/
75 +extern "C" UINT __stdcall ComPlusCleanup(MSIHANDLE hInstall)
76 +{
77 + HRESULT hr = S_OK;
78 + UINT er = ERROR_SUCCESS;
79 +
80 + LPWSTR pwzCustomActionData = NULL;
81 + LPWSTR pwzData = NULL;
82 +
83 + // initialize
84 + hr = WcaInitialize(hInstall, "ComPlusCleanup");
85 + ExitOnFailure(hr, "Failed to initialize ComPlusCleanup");
86 +
87 + // get custom action data
88 + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
89 + ExitOnFailure(hr, "Failed to get CustomActionData");
90 + pwzData = pwzCustomActionData;
91 +
92 + // delete rollback file
93 + if (!::DeleteFileW(pwzData))
94 + {
95 + // error, but not a showstopper
96 + hr = HRESULT_FROM_WIN32(::GetLastError());
97 + WcaLog(LOGMSG_STANDARD, "Failed to delete rollback file, hr: 0x%x, name: %S", hr, pwzData);
98 + }
99 +
100 + hr = S_OK;
101 +
102 +LExit:
103 + // clean up
104 + ReleaseStr(pwzCustomActionData);
105 +
106 + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
107 + return WcaFinalize(er);
108 +}
109 +
110 +/********************************************************************
111 + ComPlusInstallExecute - CUSTOM ACTION ENTRY POINT
112 +
113 + Input: deferred CustomActionData - ComPlusInstallExecute
114 +********************************************************************/
115 +extern "C" UINT __stdcall ComPlusInstallExecute(MSIHANDLE hInstall)
116 +{
117 + HRESULT hr = S_OK;
118 + UINT er = ERROR_SUCCESS;
119 +
120 + LPWSTR pwzCustomActionData = NULL;
121 + LPWSTR pwzData = NULL;
122 + LPWSTR pwzRollbackFileName = NULL;
123 +
124 + HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
125 +
126 + BOOL fInitializedCom = FALSE;
127 +
128 + // initialize
129 + hr = WcaInitialize(hInstall, "ComPlusInstallExecute");
130 + ExitOnFailure(hr, "Failed to initialize ComPlusInstallExecute");
131 +
132 + hr = ::CoInitialize(NULL);
133 + ExitOnFailure(hr, "Failed to initialize COM");
134 + fInitializedCom = TRUE;
135 +
136 + CpiInitialize();
137 +
138 + // get custom action data
139 + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
140 + ExitOnFailure(hr, "Failed to get CustomActionData");
141 + pwzData = pwzCustomActionData;
142 +
143 + // open rollback file
144 + hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName);
145 + ExitOnFailure(hr, "Failed to read rollback file name");
146 +
147 + hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
148 + if (INVALID_HANDLE_VALUE == hRollbackFile)
149 + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName);
150 +
151 + // create partitions
152 + hr = CpiConfigurePartitions(&pwzData, hRollbackFile);
153 + ExitOnFailure(hr, "Failed to create partitions");
154 + if (S_FALSE == hr) ExitFunction();
155 +
156 + // create users in partition roles
157 + hr = CpiConfigureUsersInPartitionRoles(&pwzData, hRollbackFile);
158 + ExitOnFailure(hr, "Failed to create users in partition roles");
159 + if (S_FALSE == hr) ExitFunction();
160 +
161 + // create partition users
162 + hr = CpiConfigurePartitionUsers(&pwzData, hRollbackFile);
163 + ExitOnFailure(hr, "Failed to add partition users");
164 + if (S_FALSE == hr) ExitFunction();
165 +
166 + // create applications
167 + hr = CpiConfigureApplications(&pwzData, hRollbackFile);
168 + ExitOnFailure(hr, "Failed to create applications");
169 + if (S_FALSE == hr) ExitFunction();
170 +
171 + // create application roles
172 + hr = CpiConfigureApplicationRoles(&pwzData, hRollbackFile);
173 + ExitOnFailure(hr, "Failed to create application roles");
174 + if (S_FALSE == hr) ExitFunction();
175 +
176 + // create users in application roles
177 + hr = CpiConfigureUsersInApplicationRoles(&pwzData, hRollbackFile);
178 + ExitOnFailure(hr, "Failed to create users in application roles");
179 + if (S_FALSE == hr) ExitFunction();
180 +
181 + // register assemblies
182 + hr = CpiConfigureAssemblies(&pwzData, hRollbackFile);
183 + ExitOnFailure(hr, "Failed to register assemblies");
184 + if (S_FALSE == hr) ExitFunction();
185 +
186 + // create role assignments
187 + hr = CpiConfigureRoleAssignments(&pwzData, hRollbackFile);
188 + ExitOnFailure(hr, "Failed to create role assignments");
189 + if (S_FALSE == hr) ExitFunction();
190 +
191 + // create subscriptions
192 + hr = CpiConfigureSubscriptions(&pwzData, hRollbackFile);
193 + ExitOnFailure(hr, "Failed to create subscriptions");
194 + if (S_FALSE == hr) ExitFunction();
195 +
196 + hr = S_OK;
197 +
198 +LExit:
199 + // clean up
200 + ReleaseStr(pwzCustomActionData);
201 + ReleaseStr(pwzRollbackFileName);
202 +
203 + if (INVALID_HANDLE_VALUE != hRollbackFile)
204 + ::CloseHandle(hRollbackFile);
205 +
206 + // unitialize
207 + CpiFinalize();
208 +
209 + if (fInitializedCom)
210 + ::CoUninitialize();
211 +
212 + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
213 + return WcaFinalize(er);
214 +}
215 +
216 +/********************************************************************
217 + ComPlusInstallExecuteCommit - CUSTOM ACTION ENTRY POINT
218 +
219 + Input: deferred CustomActionData - ComPlusInstallExecuteCommit
220 +********************************************************************/
221 +extern "C" UINT __stdcall ComPlusInstallExecuteCommit(MSIHANDLE hInstall)
222 +{
223 + HRESULT hr = S_OK;
224 + UINT er = ERROR_SUCCESS;
225 +
226 + LPWSTR pwzCustomActionData = NULL;
227 + LPWSTR pwzData = NULL;
228 + LPWSTR pwzRollbackFileName = NULL;
229 +
230 + HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
231 +
232 + BOOL fInitializedCom = FALSE;
233 +
234 + // initialize
235 + hr = WcaInitialize(hInstall, "ComPlusInstallExecuteCommit");
236 + ExitOnFailure(hr, "Failed to initialize ComPlusInstallExecuteCommit");
237 +
238 + hr = ::CoInitialize(NULL);
239 + ExitOnFailure(hr, "Failed to initialize COM");
240 + fInitializedCom = TRUE;
241 +
242 + CpiInitialize();
243 +
244 + // get custom action data
245 + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
246 + ExitOnFailure(hr, "Failed to get CustomActionData");
247 + pwzData = pwzCustomActionData;
248 +
249 + // open rollback file
250 + hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName);
251 + ExitOnFailure(hr, "Failed to read rollback file name");
252 +
253 + hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
254 + if (INVALID_HANDLE_VALUE == hRollbackFile)
255 + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName);
256 +
257 + if (INVALID_SET_FILE_POINTER == ::SetFilePointer(hRollbackFile, 0, NULL, FILE_END))
258 + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to set file pointer");
259 +
260 + // register assemblies
261 + hr = CpiConfigureAssemblies(&pwzData, hRollbackFile);
262 + ExitOnFailure(hr, "Failed to register assemblies");
263 + if (S_FALSE == hr) ExitFunction();
264 +
265 + // create role assignments
266 + hr = CpiConfigureRoleAssignments(&pwzData, hRollbackFile);
267 + ExitOnFailure(hr, "Failed to create role assignments");
268 + if (S_FALSE == hr) ExitFunction();
269 +
270 + // create subscriptions
271 + hr = CpiConfigureSubscriptions(&pwzData, hRollbackFile);
272 + ExitOnFailure(hr, "Failed to create subscriptions");
273 + if (S_FALSE == hr) ExitFunction();
274 +
275 + hr = S_OK;
276 +
277 +LExit:
278 + // clean up
279 + ReleaseStr(pwzCustomActionData);
280 +
281 + if (INVALID_HANDLE_VALUE != hRollbackFile)
282 + ::CloseHandle(hRollbackFile);
283 +
284 + // unitialize
285 + CpiFinalize();
286 +
287 + if (fInitializedCom)
288 + ::CoUninitialize();
289 +
290 + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
291 + return WcaFinalize(er);
292 +}
293 +
294 +/********************************************************************
295 + ComPlusRollbackInstallExecute - CUSTOM ACTION ENTRY POINT
296 +
297 + Input: deferred CustomActionData - ComPlusRollbackInstallExecute
298 +********************************************************************/
299 +extern "C" UINT __stdcall ComPlusRollbackInstallExecute(MSIHANDLE hInstall)
300 +{
301 + HRESULT hr = S_OK;
302 + UINT er = ERROR_SUCCESS;
303 +
304 + LPWSTR pwzCustomActionData = NULL;
305 + LPWSTR pwzData = NULL;
306 + LPWSTR pwzRollbackFileName = NULL;
307 +
308 + HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
309 +
310 + CPI_ROLLBACK_DATA* prdPartitions = NULL;
311 + CPI_ROLLBACK_DATA* prdUsersInPartitionRoles = NULL;
312 + CPI_ROLLBACK_DATA* prdPartitionUsers = NULL;
313 + CPI_ROLLBACK_DATA* prdApplications = NULL;
314 + CPI_ROLLBACK_DATA* prdApplicationRoles = NULL;
315 + CPI_ROLLBACK_DATA* prdUsersApplicationRoles = NULL;
316 + CPI_ROLLBACK_DATA* prdAssemblies = NULL;
317 + CPI_ROLLBACK_DATA* prdRoleAssignments = NULL;
318 + CPI_ROLLBACK_DATA* prdSubscriptions = NULL;
319 +
320 + BOOL fInitializedCom = FALSE;
321 +
322 + // initialize
323 + hr = WcaInitialize(hInstall, "ComPlusRollbackInstallExecute");
324 + ExitOnFailure(hr, "Failed to initialize ComPlusRollbackInstallExecute");
325 +
326 + hr = ::CoInitialize(NULL);
327 + ExitOnFailure(hr, "Failed to initialize COM");
328 + fInitializedCom = TRUE;
329 +
330 + CpiInitialize();
331 +
332 + // get custom action data
333 + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
334 + ExitOnFailure(hr, "Failed to get CustomActionData");
335 + pwzData = pwzCustomActionData;
336 +
337 + // open rollback file
338 + hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName);
339 + ExitOnFailure(hr, "Failed to read rollback file name");
340 +
341 + hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
342 + if (INVALID_HANDLE_VALUE == hRollbackFile)
343 + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName);
344 +
345 + // read rollback data (execute)
346 + hr = CpiReadRollbackDataList(hRollbackFile, &prdPartitions);
347 + ExitOnFailure(hr, "Failed to read partitions rollback data");
348 + hr = CpiReadRollbackDataList(hRollbackFile, &prdUsersInPartitionRoles);
349 + ExitOnFailure(hr, "Failed to read users in partition roles rollback data");
350 + hr = CpiReadRollbackDataList(hRollbackFile, &prdPartitionUsers);
351 + ExitOnFailure(hr, "Failed to read partition users rollback data");
352 + hr = CpiReadRollbackDataList(hRollbackFile, &prdApplications);
353 + ExitOnFailure(hr, "Failed to read applications rollback data");
354 + hr = CpiReadRollbackDataList(hRollbackFile, &prdApplicationRoles);
355 + ExitOnFailure(hr, "Failed to read application roles rollback data");
356 + hr = CpiReadRollbackDataList(hRollbackFile, &prdUsersApplicationRoles);
357 + ExitOnFailure(hr, "Failed to read users in application roles rollback data");
358 + hr = CpiReadRollbackDataList(hRollbackFile, &prdAssemblies);
359 + ExitOnFailure(hr, "Failed to read assemblies rollback data");
360 + hr = CpiReadRollbackDataList(hRollbackFile, &prdRoleAssignments);
361 + ExitOnFailure(hr, "Failed to read role assignments rollback data");
362 + hr = CpiReadRollbackDataList(hRollbackFile, &prdSubscriptions);
363 + ExitOnFailure(hr, "Failed to read subscription rollback data");
364 +
365 + // read rollback data (commit)
366 + hr = CpiReadRollbackDataList(hRollbackFile, &prdAssemblies);
367 + ExitOnFailure(hr, "Failed to read assemblies rollback data (commit)");
368 + hr = CpiReadRollbackDataList(hRollbackFile, &prdRoleAssignments);
369 + ExitOnFailure(hr, "Failed to read role assignments rollback data");
370 + hr = CpiReadRollbackDataList(hRollbackFile, &prdSubscriptions);
371 + ExitOnFailure(hr, "Failed to read subscription rollback data (commit)");
372 +
373 + ::CloseHandle(hRollbackFile);
374 + hRollbackFile = INVALID_HANDLE_VALUE;
375 +
376 + // rollback create subscriptions
377 + hr = CpiRollbackConfigureSubscriptions(&pwzData, prdSubscriptions);
378 + ExitOnFailure(hr, "Failed to rollback create subscriptions");
379 +
380 + // rollback create role assignments
381 + hr = CpiRollbackConfigureRoleAssignments(&pwzData, prdRoleAssignments);
382 + ExitOnFailure(hr, "Failed to rollback create role assignments");
383 +
384 + // rollback register assemblies
385 + hr = CpiRollbackConfigureAssemblies(&pwzData, prdAssemblies);
386 + ExitOnFailure(hr, "Failed to rollback register assemblies");
387 +
388 + // rollback create users in application roles
389 + hr = CpiRollbackConfigureUsersInApplicationRoles(&pwzData, prdUsersApplicationRoles);
390 + ExitOnFailure(hr, "Failed to rollback create users in application roles");
391 +
392 + // rollback create application roles
393 + hr = CpiRollbackConfigureApplicationRoles(&pwzData, prdApplicationRoles);
394 + ExitOnFailure(hr, "Failed to rollback create application roles");
395 +
396 + // rollback create applications
397 + hr = CpiRollbackConfigureApplications(&pwzData, prdApplications);
398 + ExitOnFailure(hr, "Failed to rollback create applications");
399 +
400 + // rollback create partition users
401 + hr = CpiRollbackConfigurePartitionUsers(&pwzData, prdPartitionUsers);
402 + ExitOnFailure(hr, "Failed to rollback create partition users");
403 +
404 + // rollback create users in partition roles
405 + hr = CpiRollbackConfigureUsersInPartitionRoles(&pwzData, prdUsersInPartitionRoles);
406 + ExitOnFailure(hr, "Failed to rollback create users in partition roles");
407 +
408 + // rollback create partitions
409 + hr = CpiRollbackConfigurePartitions(&pwzData, prdPartitions);
410 + ExitOnFailure(hr, "Failed to rollback create partitions");
411 +
412 + hr = S_OK;
413 +
414 +LExit:
415 + // clean up
416 + ReleaseStr(pwzCustomActionData);
417 + ReleaseStr(pwzRollbackFileName);
418 +
419 + if (INVALID_HANDLE_VALUE != hRollbackFile)
420 + ::CloseHandle(hRollbackFile);
421 +
422 + if (prdPartitions)
423 + CpiFreeRollbackDataList(prdPartitions);
424 + if (prdUsersInPartitionRoles)
425 + CpiFreeRollbackDataList(prdUsersInPartitionRoles);
426 + if (prdPartitionUsers)
427 + CpiFreeRollbackDataList(prdPartitionUsers);
428 + if (prdApplications)
429 + CpiFreeRollbackDataList(prdApplications);
430 + if (prdApplicationRoles)
431 + CpiFreeRollbackDataList(prdApplicationRoles);
432 + if (prdUsersApplicationRoles)
433 + CpiFreeRollbackDataList(prdUsersApplicationRoles);
434 + if (prdAssemblies)
435 + CpiFreeRollbackDataList(prdAssemblies);
436 + if (prdRoleAssignments)
437 + CpiFreeRollbackDataList(prdRoleAssignments);
438 + if (prdSubscriptions)
439 + CpiFreeRollbackDataList(prdSubscriptions);
440 +
441 + // unitialize
442 + CpiFinalize();
443 +
444 + if (fInitializedCom)
445 + ::CoUninitialize();
446 +
447 + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
448 + return WcaFinalize(er);
449 +}
450 +
451 +/********************************************************************
452 + ComPlusUninstallExecute - CUSTOM ACTION ENTRY POINT
453 +
454 + Input: deferred CustomActionData - ComPlusUninstallExecute
455 +********************************************************************/
456 +extern "C" UINT __stdcall ComPlusUninstallExecute(MSIHANDLE hInstall)
457 +{
458 + HRESULT hr = S_OK;
459 + UINT er = ERROR_SUCCESS;
460 +
461 + LPWSTR pwzCustomActionData = NULL;
462 + LPWSTR pwzData = NULL;
463 + LPWSTR pwzRollbackFileName = NULL;
464 +
465 + HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
466 +
467 + BOOL fInitializedCom = FALSE;
468 +
469 + // initialize
470 + hr = WcaInitialize(hInstall, "ComPlusUninstallExecute");
471 + ExitOnFailure(hr, "Failed to initialize ComPlusUninstallExecute");
472 +
473 + hr = ::CoInitialize(NULL);
474 + ExitOnFailure(hr, "Failed to initialize COM");
475 + fInitializedCom = TRUE;
476 +
477 + CpiInitialize();
478 +
479 + // get custom action data
480 + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
481 + ExitOnFailure(hr, "Failed to get CustomActionData");
482 + pwzData = pwzCustomActionData;
483 +
484 + // open rollback file
485 + hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName);
486 + ExitOnFailure(hr, "Failed to read rollback file name");
487 +
488 + hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
489 + if (INVALID_HANDLE_VALUE == hRollbackFile)
490 + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName);
491 +
492 + // delete subscriptions
493 + hr = CpiConfigureSubscriptions(&pwzData, hRollbackFile);
494 + ExitOnFailure(hr, "Failed to delete subscriptions");
495 + if (S_FALSE == hr) ExitFunction();
496 +
497 + // delete role assignments
498 + hr = CpiConfigureRoleAssignments(&pwzData, hRollbackFile);
499 + ExitOnFailure(hr, "Failed to delete role assignments");
500 + if (S_FALSE == hr) ExitFunction();
501 +
502 + // unregister assemblies
503 + hr = CpiConfigureAssemblies(&pwzData, hRollbackFile);
504 + ExitOnFailure(hr, "Failed to unregister assemblies");
505 + if (S_FALSE == hr) ExitFunction();
506 +
507 + // remove users in application roles
508 + hr = CpiConfigureUsersInApplicationRoles(&pwzData, hRollbackFile);
509 + ExitOnFailure(hr, "Failed to delete users in application roles");
510 + if (S_FALSE == hr) ExitFunction();
511 +
512 + // remove application roles
513 + hr = CpiConfigureApplicationRoles(&pwzData, hRollbackFile);
514 + ExitOnFailure(hr, "Failed to delete application roles");
515 + if (S_FALSE == hr) ExitFunction();
516 +
517 + // remove applications
518 + hr = CpiConfigureApplications(&pwzData, hRollbackFile);
519 + ExitOnFailure(hr, "Failed to remove applications");
520 + if (S_FALSE == hr) ExitFunction();
521 +
522 + // remove partition users
523 + hr = CpiConfigurePartitionUsers(&pwzData, hRollbackFile);
524 + ExitOnFailure(hr, "Failed to remove partition users");
525 + if (S_FALSE == hr) ExitFunction();
526 +
527 + // remove users in partition roles
528 + hr = CpiConfigureUsersInPartitionRoles(&pwzData, hRollbackFile);
529 + ExitOnFailure(hr, "Failed to delete users in partition roles");
530 + if (S_FALSE == hr) ExitFunction();
531 +
532 + // remove partitions
533 + hr = CpiConfigurePartitions(&pwzData, hRollbackFile);
534 + ExitOnFailure(hr, "Failed to delete partitions");
535 + if (S_FALSE == hr) ExitFunction();
536 +
537 + hr = S_OK;
538 +
539 +LExit:
540 + // clean up
541 + ReleaseStr(pwzCustomActionData);
542 + ReleaseStr(pwzRollbackFileName);
543 +
544 + if (INVALID_HANDLE_VALUE != hRollbackFile)
545 + ::CloseHandle(hRollbackFile);
546 +
547 + // unitialize
548 + CpiFinalize();
549 +
550 + if (fInitializedCom)
551 + ::CoUninitialize();
552 +
553 + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
554 + return WcaFinalize(er);
555 +}
556 +
557 +/********************************************************************
558 + ComPlusRollbackUninstallExecute - CUSTOM ACTION ENTRY POINT
559 +
560 + Input: deferred CustomActionData - ComPlusRollbackUninstallExecute
561 +********************************************************************/
562 +extern "C" UINT __stdcall ComPlusRollbackUninstallExecute(MSIHANDLE hInstall)
563 +{
564 + HRESULT hr = S_OK;
565 + UINT er = ERROR_SUCCESS;
566 +
567 + LPWSTR pwzCustomActionData = NULL;
568 + LPWSTR pwzData = NULL;
569 + LPWSTR pwzRollbackFileName = NULL;
570 +
571 + HANDLE hRollbackFile = INVALID_HANDLE_VALUE;
572 +
573 + CPI_ROLLBACK_DATA* prdPartitions = NULL;
574 + CPI_ROLLBACK_DATA* prdUsersInPartitionRoles = NULL;
575 + CPI_ROLLBACK_DATA* prdPartitionUsers = NULL;
576 + CPI_ROLLBACK_DATA* prdApplications = NULL;
577 + CPI_ROLLBACK_DATA* prdApplicationRoles = NULL;
578 + CPI_ROLLBACK_DATA* prdUsersApplicationRoles = NULL;
579 + CPI_ROLLBACK_DATA* prdAssemblies = NULL;
580 + CPI_ROLLBACK_DATA* prdRoleAssignments = NULL;
581 + CPI_ROLLBACK_DATA* prdSubscriptions = NULL;
582 +
583 + BOOL fInitializedCom = FALSE;
584 +
585 + // initialize
586 + hr = WcaInitialize(hInstall, "ComPlusRollbackUninstallExecute");
587 + ExitOnFailure(hr, "Failed to initialize ComPlusRollbackUninstallExecute");
588 +
589 + hr = ::CoInitialize(NULL);
590 + ExitOnFailure(hr, "Failed to initialize COM");
591 + fInitializedCom = TRUE;
592 +
593 + CpiInitialize();
594 +
595 + // get custom action data
596 + hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
597 + ExitOnFailure(hr, "Failed to get CustomActionData");
598 + pwzData = pwzCustomActionData;
599 +
600 + // open rollback file
601 + hr = WcaReadStringFromCaData(&pwzData, &pwzRollbackFileName);
602 + ExitOnFailure(hr, "Failed to read rollback file name");
603 +
604 + hRollbackFile = ::CreateFileW(pwzRollbackFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
605 + if (INVALID_HANDLE_VALUE == hRollbackFile)
606 + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to open rollback file, name: %S", pwzRollbackFileName);
607 +
608 + // read rollback data
609 + hr = CpiReadRollbackDataList(hRollbackFile, &prdSubscriptions);
610 + ExitOnFailure(hr, "Failed to read subscription rollback data");
611 + hr = CpiReadRollbackDataList(hRollbackFile, &prdRoleAssignments);
612 + ExitOnFailure(hr, "Failed to read role assignments rollback data");
613 + hr = CpiReadRollbackDataList(hRollbackFile, &prdAssemblies);
614 + ExitOnFailure(hr, "Failed to read assemblies rollback data");
615 + hr = CpiReadRollbackDataList(hRollbackFile, &prdUsersApplicationRoles);
616 + ExitOnFailure(hr, "Failed to read users in application roles rollback data");
617 + hr = CpiReadRollbackDataList(hRollbackFile, &prdApplicationRoles);
618 + ExitOnFailure(hr, "Failed to read application roles rollback data");
619 + hr = CpiReadRollbackDataList(hRollbackFile, &prdApplications);
620 + ExitOnFailure(hr, "Failed to read applications rollback data");
621 + hr = CpiReadRollbackDataList(hRollbackFile, &prdPartitionUsers);
622 + ExitOnFailure(hr, "Failed to read partition users rollback data");
623 + hr = CpiReadRollbackDataList(hRollbackFile, &prdUsersInPartitionRoles);
624 + ExitOnFailure(hr, "Failed to read users in partition roles rollback data");
625 + hr = CpiReadRollbackDataList(hRollbackFile, &prdPartitions);
626 + ExitOnFailure(hr, "Failed to read partitions rollback data");
627 +
628 + ::CloseHandle(hRollbackFile);
629 + hRollbackFile = INVALID_HANDLE_VALUE;
630 +
631 + // rollback remove partitions
632 + hr = CpiRollbackConfigurePartitions(&pwzData, prdPartitions);
633 + ExitOnFailure(hr, "Failed to rollback delete partitions");
634 +
635 + // rollback remove users in partition roles
636 + hr = CpiRollbackConfigureUsersInPartitionRoles(&pwzData, prdUsersInPartitionRoles);
637 + ExitOnFailure(hr, "Failed to rollback delete users in partition roles");
638 +
639 + // rollback remove partition users
640 + hr = CpiRollbackConfigurePartitionUsers(&pwzData, prdPartitionUsers);
641 + ExitOnFailure(hr, "Failed to rollback delete partition users");
642 +
643 + // rollback remove applications
644 + hr = CpiRollbackConfigureApplications(&pwzData, prdApplications);
645 + ExitOnFailure(hr, "Failed to rollback delete applications");
646 +
647 + // rollback remove application roles
648 + hr = CpiRollbackConfigureApplicationRoles(&pwzData, prdApplicationRoles);
649 + ExitOnFailure(hr, "Failed to rollback delete application roles");
650 +
651 + // rollback remove users in application roles
652 + hr = CpiRollbackConfigureUsersInApplicationRoles(&pwzData, prdUsersApplicationRoles);
653 + ExitOnFailure(hr, "Failed to rollback delete users in application roles");
654 +
655 + // rollback unregister assemblies
656 + hr = CpiRollbackConfigureAssemblies(&pwzData, prdAssemblies);
657 + ExitOnFailure(hr, "Failed to rollback unregister assemblies");
658 +
659 + // rollback delete role assignments
660 + hr = CpiRollbackConfigureRoleAssignments(&pwzData, prdAssemblies);
661 + ExitOnFailure(hr, "Failed to rollback delete role assignments");
662 +
663 + // rollback delete subscriptions
664 + hr = CpiRollbackConfigureSubscriptions(&pwzData, prdSubscriptions);
665 + ExitOnFailure(hr, "Failed to rollback delete subscriptions");
666 +
667 + hr = S_OK;
668 +
669 +LExit:
670 + // clean up
671 + ReleaseStr(pwzCustomActionData);
672 + ReleaseStr(pwzRollbackFileName);
673 +
674 + if (INVALID_HANDLE_VALUE != hRollbackFile)
675 + ::CloseHandle(hRollbackFile);
676 +
677 + if (prdPartitions)
678 + CpiFreeRollbackDataList(prdPartitions);
679 + if (prdUsersInPartitionRoles)
680 + CpiFreeRollbackDataList(prdUsersInPartitionRoles);
681 + if (prdPartitionUsers)
682 + CpiFreeRollbackDataList(prdPartitionUsers);
683 + if (prdApplications)
684 + CpiFreeRollbackDataList(prdApplications);
685 + if (prdApplicationRoles)
686 + CpiFreeRollbackDataList(prdApplicationRoles);
687 + if (prdUsersApplicationRoles)
688 + CpiFreeRollbackDataList(prdUsersApplicationRoles);
689 + if (prdAssemblies)
690 + CpiFreeRollbackDataList(prdAssemblies);
691 + if (prdRoleAssignments)
692 + CpiFreeRollbackDataList(prdRoleAssignments);
693 + if (prdSubscriptions)
694 + CpiFreeRollbackDataList(prdSubscriptions);
695 +
696 + // unitialize
697 + CpiFinalize();
698 +
699 + if (fInitializedCom)
700 + ::CoUninitialize();
701 +
702 + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
703 + return WcaFinalize(er);
704 +}
src/ca/cpexec.def new
+11
@@ -0,0 +1,11 @@
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 +
4 +EXPORTS
5 + ComPlusPrepare
6 + ComPlusCleanup
7 + ComPlusInstallExecute
8 + ComPlusInstallExecuteCommit
9 + ComPlusRollbackInstallExecute
10 + ComPlusUninstallExecute
11 + ComPlusRollbackUninstallExecute
src/ca/cppartexec.cpp new
+690
@@ -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 +
8 +struct 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 +
18 +struct 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 +
30 +static HRESULT ReadPartitionAttributes(
31 + LPWSTR* ppwzData,
32 + CPI_PARTITION_ATTRIBUTES* pAttrs
33 + );
34 +static void FreePartitionAttributes(
35 + CPI_PARTITION_ATTRIBUTES* pAttrs
36 + );
37 +static HRESULT CreatePartition(
38 + CPI_PARTITION_ATTRIBUTES* pAttrs
39 + );
40 +static HRESULT RemovePartition(
41 + CPI_PARTITION_ATTRIBUTES* pAttrs
42 + );
43 +static HRESULT ReadPartitionUserAttributes(
44 + LPWSTR* ppwzData,
45 + CPI_PARTITION_USER_ATTRIBUTES* pAttrs
46 + );
47 +static void FreePartitionUserAttributes(
48 + CPI_PARTITION_USER_ATTRIBUTES* pAttrs
49 + );
50 +static HRESULT CreatePartitionUser(
51 + CPI_PARTITION_USER_ATTRIBUTES* pAttrs
52 + );
53 +static HRESULT RemovePartitionUser(
54 + CPI_PARTITION_USER_ATTRIBUTES* pAttrs
55 + );
56 +
57 +
58 +// function definitions
59 +
60 +HRESULT 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 +
124 +LExit:
125 + // clean up
126 + FreePartitionAttributes(&attrs);
127 +
128 + return hr;
129 +}
130 +
131 +HRESULT 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 +
197 +LExit:
198 + // clean up
199 + FreePartitionAttributes(&attrs);
200 +
201 + return hr;
202 +}
203 +
204 +HRESULT 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 +
268 +LExit:
269 + // clean up
270 + FreePartitionUserAttributes(&attrs);
271 +
272 + return hr;
273 +}
274 +
275 +HRESULT 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 +
339 +LExit:
340 + // clean up
341 + FreePartitionUserAttributes(&attrs);
342 +
343 + return hr;
344 +}
345 +
346 +
347 +// helper function definitions
348 +
349 +static 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 +
371 +LExit:
372 + return hr;
373 +}
374 +
375 +static 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 +
387 +static 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 = CpiGetPartitionsCollection(&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 +
437 +LExit:
438 + // clean up
439 + ReleaseObject(piPartColl);
440 + ReleaseObject(piPartObj);
441 +
442 + return hr;
443 +}
444 +
445 +static 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 = CpiGetPartitionsCollection(&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 +
484 +LExit:
485 + // clean up
486 + ReleaseObject(piPartColl);
487 +
488 + return hr;
489 +}
490 +
491 +static 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 +
511 +LExit:
512 + return hr;
513 +}
514 +
515 +static void FreePartitionUserAttributes(
516 + CPI_PARTITION_USER_ATTRIBUTES* pAttrs
517 + )
518 +{
519 + ReleaseStr(pAttrs->pwzKey);
520 + ReleaseStr(pAttrs->pwzAccount);
521 + ReleaseStr(pAttrs->pwzPartID);
522 +}
523 +
524 +static 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 +
601 +LExit:
602 + // clean up
603 + ReleaseObject(piUserColl);
604 + ReleaseObject(piUserObj);
605 +
606 + if (pSid)
607 + ::HeapFree(::GetProcessHeap(), 0, pSid);
608 +
609 + return hr;
610 +}
611 +
612 +static 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 +
682 +LExit:
683 + // clean up
684 + ReleaseObject(piUserColl);
685 +
686 + if (pSid)
687 + ::HeapFree(::GetProcessHeap(), 0, pSid);
688 +
689 + return hr;
690 +}
src/ca/cppartexec.h new
+20
@@ -0,0 +1,20 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +HRESULT CpiConfigurePartitions(
6 + LPWSTR* ppwzData,
7 + HANDLE hRollbackFile
8 + );
9 +HRESULT CpiRollbackConfigurePartitions(
10 + LPWSTR* ppwzData,
11 + CPI_ROLLBACK_DATA* pRollbackDataList
12 + );
13 +HRESULT CpiConfigurePartitionUsers(
14 + LPWSTR* ppwzData,
15 + HANDLE hRollbackFile
16 + );
17 +HRESULT CpiRollbackConfigurePartitionUsers(
18 + LPWSTR* ppwzData,
19 + CPI_ROLLBACK_DATA* pRollbackDataList
20 + );
src/ca/cppartroleexec.cpp new
+397
@@ -0,0 +1,397 @@
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 +
8 +struct CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES
9 +{
10 + int iActionType;
11 + int iActionCost;
12 + LPWSTR pwzKey;
13 + LPWSTR pwzRoleName;
14 + LPWSTR pwzAccount;
15 + LPWSTR pwzPartID;
16 +};
17 +
18 +
19 +// prototypes for private helper functions
20 +
21 +static HRESULT ReadUserInPartitionRoleAttributes(
22 + LPWSTR* ppwzData,
23 + CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
24 + );
25 +static void FreeUserInPartitionRoleAttributes(
26 + CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
27 + );
28 +static HRESULT CreateUserInPartitionRole(
29 + CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
30 + );
31 +static HRESULT RemoveUserInPartitionRole(
32 + CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
33 + );
34 +
35 +
36 +// function definitions
37 +
38 +HRESULT CpiConfigureUsersInPartitionRoles(
39 + LPWSTR* ppwzData,
40 + HANDLE hRollbackFile
41 + )
42 +{
43 + HRESULT hr = S_OK;
44 +
45 + CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES attrs;
46 + ::ZeroMemory(&attrs, sizeof(attrs));
47 +
48 + // read action text
49 + hr = CpiActionStartMessage(ppwzData, FALSE);
50 + ExitOnFailure(hr, "Failed to send action start message");
51 +
52 + // ger count
53 + int iCnt = 0;
54 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
55 + ExitOnFailure(hr, "Failed to read count");
56 +
57 + // write count to rollback file
58 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
59 + ExitOnFailure(hr, "Failed to write count to rollback file");
60 +
61 + for (int i = 0; i < iCnt; i++)
62 + {
63 + // read attributes from CustomActionData
64 + hr = ReadUserInPartitionRoleAttributes(ppwzData, &attrs);
65 + ExitOnFailure(hr, "Failed to read attributes");
66 +
67 + // progress message
68 + hr = CpiActionDataMessage(1, attrs.pwzRoleName);
69 + ExitOnFailure(hr, "Failed to send progress messages");
70 +
71 + if (S_FALSE == hr)
72 + ExitFunction();
73 +
74 + // write key to rollback file
75 + hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
76 + ExitOnFailure(hr, "Failed to write key to rollback file");
77 +
78 + // action
79 + switch (attrs.iActionType)
80 + {
81 + case atCreate:
82 + hr = CreateUserInPartitionRole(&attrs);
83 + ExitOnFailure(hr, "Failed to add user to partition role, key: %S", attrs.pwzKey);
84 + break;
85 + case atRemove:
86 + hr = RemoveUserInPartitionRole(&attrs);
87 + ExitOnFailure(hr, "Failed to remove user from partition role, key: %S", attrs.pwzKey);
88 + break;
89 + }
90 +
91 + // write completion status to rollback file
92 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
93 + ExitOnFailure(hr, "Failed to write completion status to rollback file");
94 +
95 + // progress
96 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
97 + ExitOnFailure(hr, "Failed to update progress");
98 + }
99 +
100 + hr = S_OK;
101 +
102 +LExit:
103 + // clean up
104 + FreeUserInPartitionRoleAttributes(&attrs);
105 +
106 + return hr;
107 +}
108 +
109 +HRESULT CpiRollbackConfigureUsersInPartitionRoles(
110 + LPWSTR* ppwzData,
111 + CPI_ROLLBACK_DATA* pRollbackDataList
112 + )
113 +{
114 + HRESULT hr = S_OK;
115 +
116 + int iRollbackStatus;
117 +
118 + CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES attrs;
119 + ::ZeroMemory(&attrs, sizeof(attrs));
120 +
121 + // read action text
122 + hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
123 + ExitOnFailure(hr, "Failed to send action start message");
124 +
125 + // get count
126 + int iCnt = 0;
127 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
128 + ExitOnFailure(hr, "Failed to read count");
129 +
130 + for (int i = 0; i < iCnt; i++)
131 + {
132 + // read attributes from CustomActionData
133 + hr = ReadUserInPartitionRoleAttributes(ppwzData, &attrs);
134 + ExitOnFailure(hr, "Failed to read attributes");
135 +
136 + // rollback status
137 + hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
138 +
139 + if (S_FALSE == hr)
140 + continue; // not found, nothing to rollback
141 +
142 + // progress message
143 + hr = CpiActionDataMessage(1, attrs.pwzRoleName);
144 + ExitOnFailure(hr, "Failed to send progress messages");
145 +
146 + if (S_FALSE == hr)
147 + ExitFunction();
148 +
149 + // action
150 + switch (attrs.iActionType)
151 + {
152 + case atCreate:
153 + hr = CreateUserInPartitionRole(&attrs);
154 + if (FAILED(hr))
155 + WcaLog(LOGMSG_STANDARD, "Failed to add user to partition role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
156 + break;
157 + case atRemove:
158 + hr = RemoveUserInPartitionRole(&attrs);
159 + if (FAILED(hr))
160 + WcaLog(LOGMSG_STANDARD, "Failed to remove user from partition role, hr: 0x%x, key: %S", hr, attrs.pwzKey);
161 + break;
162 + }
163 +
164 + // check rollback status
165 + if (0 == iRollbackStatus)
166 + continue; // operation did not complete, skip progress
167 +
168 + // progress
169 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
170 + ExitOnFailure(hr, "Failed to update progress");
171 + }
172 +
173 + hr = S_OK;
174 +
175 +LExit:
176 + // clean up
177 + FreeUserInPartitionRoleAttributes(&attrs);
178 +
179 + return hr;
180 +}
181 +
182 +
183 +// helper function definitions
184 +
185 +static HRESULT ReadUserInPartitionRoleAttributes(
186 + LPWSTR* ppwzData,
187 + CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
188 + )
189 +{
190 + HRESULT hr = S_OK;
191 +
192 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
193 + ExitOnFailure(hr, "Failed to read action type");
194 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
195 + ExitOnFailure(hr, "Failed to read action cost");
196 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
197 + ExitOnFailure(hr, "Failed to read key");
198 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzRoleName);
199 + ExitOnFailure(hr, "Failed to read role name");
200 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAccount);
201 + ExitOnFailure(hr, "Failed to read account name");
202 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
203 + ExitOnFailure(hr, "Failed to read partition id");
204 +
205 + hr = S_OK;
206 +
207 +LExit:
208 + return hr;
209 +}
210 +
211 +static void FreeUserInPartitionRoleAttributes(
212 + CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
213 + )
214 +{
215 + ReleaseStr(pAttrs->pwzKey);
216 + ReleaseStr(pAttrs->pwzRoleName);
217 + ReleaseStr(pAttrs->pwzAccount);
218 + ReleaseStr(pAttrs->pwzPartID);
219 +}
220 +
221 +static HRESULT CreateUserInPartitionRole(
222 + CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
223 + )
224 +{
225 + HRESULT hr = S_OK;
226 + UINT er = ERROR_SUCCESS;
227 +
228 + ICatalogCollection* piUsrInRoleColl = NULL;
229 + ICatalogObject* piUsrInRoleObj = NULL;
230 +
231 + PSID pSid = NULL;
232 + long lChanges = 0;
233 +
234 + // log
235 + WcaLog(LOGMSG_VERBOSE, "Adding user to partition role, key: %S", pAttrs->pwzKey);
236 +
237 + // get users in partition role collection
238 + hr = CpiGetUsersInPartitionRoleCollection(pAttrs->pwzPartID, pAttrs->pwzRoleName, &piUsrInRoleColl);
239 + if (S_FALSE == hr)
240 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
241 + ExitOnFailure(hr, "Failed to get users in partition role collection");
242 +
243 + // get SID for account
244 + do {
245 + er = ERROR_SUCCESS;
246 + hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
247 + if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
248 + {
249 + WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
250 + er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
251 + switch (er)
252 + {
253 + case IDABORT:
254 + ExitFunction(); // exit with error code from CpiAccountNameToSid()
255 + case IDRETRY:
256 + break;
257 + case IDIGNORE:
258 + default:
259 + ExitFunction1(hr = S_OK);
260 + }
261 + }
262 + else
263 + ExitOnFailure(hr, "Failed to get SID for account");
264 + } while (IDRETRY == er);
265 +
266 + // find any existing entry
267 + hr = CpiFindUserCollectionObject(piUsrInRoleColl, pSid, NULL);
268 + if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
269 + WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
270 + else
271 + ExitOnFailure(hr, "Failed to find user in partition role");
272 +
273 + if (S_OK == hr)
274 + {
275 + WcaLog(LOGMSG_VERBOSE, "User already assigned to partition role, key: %S", pAttrs->pwzKey);
276 + ExitFunction(); // exit with hr = S_OK
277 + }
278 +
279 + // convert SID back to account name
280 + hr = CpiSidToAccountName(pSid, &pAttrs->pwzAccount);
281 + ExitOnFailure(hr, "Failed to convert SID to account name");
282 +
283 + // add user
284 + hr = CpiAddCollectionObject(piUsrInRoleColl, &piUsrInRoleObj);
285 + ExitOnFailure(hr, "Failed to add user in role to collection");
286 +
287 + hr = CpiPutCollectionObjectValue(piUsrInRoleObj, L"User", pAttrs->pwzAccount);
288 + ExitOnFailure(hr, "Failed to set role name property");
289 +
290 + // save changes
291 + hr = piUsrInRoleColl->SaveChanges(&lChanges);
292 + if (COMADMIN_E_OBJECTERRORS == hr)
293 + CpiLogCatalogErrorInfo();
294 + ExitOnFailure(hr, "Failed to save changes");
295 +
296 + // log
297 + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
298 +
299 + hr = S_OK;
300 +
301 +LExit:
302 + // clean up
303 + ReleaseObject(piUsrInRoleColl);
304 + ReleaseObject(piUsrInRoleObj);
305 +
306 + if (pSid)
307 + ::HeapFree(::GetProcessHeap(), 0, pSid);
308 +
309 + return hr;
310 +}
311 +
312 +static HRESULT RemoveUserInPartitionRole(
313 + CPI_USER_IN_PARTITION_ROLE_ATTRIBUTES* pAttrs
314 + )
315 +{
316 + HRESULT hr = S_OK;
317 + UINT er = ERROR_SUCCESS;
318 +
319 + ICatalogCollection* piUsrInRoleColl = NULL;
320 +
321 + PSID pSid = NULL;
322 + long lChanges = 0;
323 +
324 + // log
325 + WcaLog(LOGMSG_VERBOSE, "Removing user from partition role, key: %S", pAttrs->pwzKey);
326 +
327 + // get users in partition role collection
328 + hr = CpiGetUsersInPartitionRoleCollection(pAttrs->pwzPartID, pAttrs->pwzRoleName, &piUsrInRoleColl);
329 + ExitOnFailure(hr, "Failed to get users in partition role collection");
330 +
331 + if (S_FALSE == hr)
332 + {
333 + // users in role collection not found
334 + WcaLog(LOGMSG_VERBOSE, "Unable to retrieve users in partition role collection, nothing to delete, key: %S", pAttrs->pwzKey);
335 + ExitFunction1(hr = S_OK);
336 + }
337 +
338 + // get SID for account
339 + do {
340 + er = ERROR_SUCCESS;
341 + hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid);
342 + if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
343 + {
344 + WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount);
345 + er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
346 + switch (er)
347 + {
348 + case IDABORT:
349 + ExitFunction(); // exit with error code from CpiAccountNameToSid()
350 + case IDRETRY:
351 + break;
352 + case IDIGNORE:
353 + default:
354 + ExitFunction1(hr = S_OK);
355 + }
356 + }
357 + else
358 + ExitOnFailure(hr, "Failed to get SID for account");
359 + } while (IDRETRY == er);
360 +
361 + // remove
362 + hr = CpiRemoveUserCollectionObject(piUsrInRoleColl, pSid);
363 + if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr)
364 + {
365 + WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr);
366 + hr = S_FALSE;
367 + }
368 + else
369 + ExitOnFailure(hr, "Failed to remove user");
370 +
371 + if (S_FALSE == hr)
372 + {
373 + // role not found
374 + WcaLog(LOGMSG_VERBOSE, "User not found for partition role, nothing to delete, key: %S", pAttrs->pwzKey);
375 + ExitFunction1(hr = S_OK);
376 + }
377 +
378 + // save changes
379 + hr = piUsrInRoleColl->SaveChanges(&lChanges);
380 + if (COMADMIN_E_OBJECTERRORS == hr)
381 + CpiLogCatalogErrorInfo();
382 + ExitOnFailure(hr, "Failed to save changes");
383 +
384 + // log
385 + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
386 +
387 + hr = S_OK;
388 +
389 +LExit:
390 + // clean up
391 + ReleaseObject(piUsrInRoleColl);
392 +
393 + if (pSid)
394 + ::HeapFree(::GetProcessHeap(), 0, pSid);
395 +
396 + return hr;
397 +}
src/ca/cppartroleexec.h new
+12
@@ -0,0 +1,12 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +HRESULT CpiConfigureUsersInPartitionRoles(
6 + LPWSTR* ppwzData,
7 + HANDLE hRollbackFile
8 + );
9 +HRESULT CpiRollbackConfigureUsersInPartitionRoles(
10 + LPWSTR* ppwzData,
11 + CPI_ROLLBACK_DATA* pRollbackDataList
12 + );
src/ca/cppartrolesched.cpp new
+421
@@ -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 +}
src/ca/cppartrolesched.h new
+76
@@ -0,0 +1,76 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +struct CPI_PARTITION_ROLE
6 +{
7 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
8 + WCHAR wzName[MAX_DARWIN_COLUMN + 1];
9 +
10 + CPI_PARTITION* pPartition;
11 +
12 + ICatalogCollection* piUsersColl;
13 +
14 + CPI_PARTITION_ROLE* pNext;
15 +};
16 +
17 +struct CPI_PARTITION_ROLE_LIST
18 +{
19 + CPI_PARTITION_ROLE* pFirst;
20 +};
21 +
22 +struct CPI_USER_IN_PARTITION_ROLE
23 +{
24 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
25 + LPWSTR pwzAccount;
26 +
27 + INSTALLSTATE isInstalled, isAction;
28 +
29 + CPI_PARTITION_ROLE* pPartitionRole;
30 +
31 + CPI_USER_IN_PARTITION_ROLE* pNext;
32 +};
33 +
34 +struct CPI_USER_IN_PARTITION_ROLE_LIST
35 +{
36 + CPI_USER_IN_PARTITION_ROLE* pFirst;
37 +
38 + int iInstallCount;
39 + int iUninstallCount;
40 +};
41 +
42 +
43 +// function prototypes
44 +
45 +void CpiPartitionRoleListFree(
46 + CPI_PARTITION_ROLE_LIST* pList
47 + );
48 +HRESULT CpiPartitionRolesRead(
49 + CPI_PARTITION_LIST* pPartList,
50 + CPI_PARTITION_ROLE_LIST* pPartRoleList
51 + );
52 +HRESULT CpiPartitionRoleFindByKey(
53 + CPI_PARTITION_ROLE_LIST* pList,
54 + LPCWSTR pwzKey,
55 + CPI_PARTITION_ROLE** ppPartRole
56 + );
57 +
58 +void CpiUserInPartitionRoleListFree(
59 + CPI_USER_IN_PARTITION_ROLE_LIST* pList
60 + );
61 +HRESULT CpiUsersInPartitionRolesRead(
62 + CPI_PARTITION_ROLE_LIST* pPartRoleList,
63 + CPI_USER_IN_PARTITION_ROLE_LIST* pUsrInPartRoleList
64 + );
65 +HRESULT CpiUsersInPartitionRolesInstall(
66 + CPI_USER_IN_PARTITION_ROLE_LIST* pList,
67 + int iRunMode,
68 + LPWSTR* ppwzActionData,
69 + int* piProgress
70 + );
71 +HRESULT CpiUsersInPartitionRolesUninstall(
72 + CPI_USER_IN_PARTITION_ROLE_LIST* pList,
73 + int iRunMode,
74 + LPWSTR* ppwzActionData,
75 + int* piProgress
76 + );
src/ca/cppartsched.cpp new
+912
@@ -0,0 +1,912 @@
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 vcsPartitionQuery =
9 + L"SELECT `Partition`, `Component_`, `Id`, `Name` FROM `ComPlusPartition`";
10 +enum ePartitionQuery { pqPartition = 1, pqComponent, pqID, pqName };
11 +
12 +LPCWSTR vcsPartitionPropertyQuery =
13 + L"SELECT `Name`, `Value` FROM `ComPlusPartitionProperty` WHERE `Partition_` = ?";
14 +
15 +LPCWSTR vcsPartitionUserQuery =
16 + L"SELECT `PartitionUser`, `Partition_`, `ComPlusPartitionUser`.`Component_`, `Domain`, `Name` FROM `ComPlusPartitionUser`, `User` WHERE `User_` = `User`";
17 +enum ePartitionUserQuery { puqPartitionUser = 1, puqPartition, puqComponent, puqDomain, puqName };
18 +
19 +
20 +// property definitions
21 +
22 +CPI_PROPERTY_DEFINITION pdlPartitionProperties[] =
23 +{
24 + {L"Changeable", cpptBoolean, 502},
25 + {L"Deleteable", cpptBoolean, 502},
26 + {L"Description", cpptString, 502},
27 + {NULL, cpptNone, 0}
28 +};
29 +
30 +
31 +// prototypes for private helper functions
32 +
33 +static void FreePartition(
34 + CPI_PARTITION* pItm
35 + );
36 +static void FreePartitionUser(
37 + CPI_PARTITION_USER* pItm
38 + );
39 +static HRESULT AddPartitionToActionData(
40 + CPI_PARTITION* pItm,
41 + int iActionType,
42 + int iActionCost,
43 + LPWSTR* ppwzActionData
44 + );
45 +static HRESULT AddPartitionUserToActionData(
46 + CPI_PARTITION_USER* pItm,
47 + int iActionType,
48 + int iActionCost,
49 + LPWSTR* ppwzActionData
50 + );
51 +
52 +
53 +// function definitions
54 +
55 +void CpiPartitionListFree(
56 + CPI_PARTITION_LIST* pList
57 + )
58 +{
59 + CPI_PARTITION* pItm = pList->pFirst;
60 +
61 + while (pItm)
62 + {
63 + CPI_PARTITION* pDelete = pItm;
64 + pItm = pItm->pNext;
65 + FreePartition(pDelete);
66 + }
67 +}
68 +
69 +HRESULT CpiPartitionsRead(
70 + CPI_PARTITION_LIST* pPartList
71 + )
72 +{
73 + HRESULT hr = S_OK;
74 + UINT er = ERROR_SUCCESS;
75 +
76 + PMSIHANDLE hView, hRec;
77 +
78 + CPI_PARTITION* pItm = NULL;
79 + LPWSTR pwzData = NULL;
80 + BOOL fMatchingArchitecture = FALSE;
81 +
82 + // loop through all partitions
83 + hr = WcaOpenExecuteView(vcsPartitionQuery, &hView);
84 + ExitOnFailure(hr, "Failed to execute view on ComPlusPartition table");
85 +
86 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
87 + {
88 + // get component
89 + hr = WcaGetRecordString(hRec, pqComponent, &pwzData);
90 + ExitOnFailure(hr, "Failed to get component");
91 +
92 + // check if the component is our processor architecture
93 + if (pwzData && *pwzData)
94 + {
95 + hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
96 + ExitOnFailure(hr, "Failed to get component architecture.");
97 +
98 + if (!fMatchingArchitecture)
99 + {
100 + continue; // not the same architecture, ignore
101 + }
102 + }
103 +
104 + // create entry
105 + pItm = (CPI_PARTITION*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PARTITION));
106 + if (!pItm)
107 + ExitFunction1(hr = E_OUTOFMEMORY);
108 +
109 + // get component install state
110 + if (pwzData && *pwzData)
111 + {
112 + pItm->fHasComponent = TRUE;
113 +
114 + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
115 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
116 + }
117 +
118 + // get key
119 + hr = WcaGetRecordString(hRec, pqPartition, &pwzData);
120 + ExitOnFailure(hr, "Failed to get key");
121 + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
122 +
123 + // get id
124 + hr = WcaGetRecordFormattedString(hRec, pqID, &pwzData);
125 + ExitOnFailure(hr, "Failed to get id");
126 +
127 + if (pwzData && *pwzData)
128 + {
129 + hr = PcaGuidToRegFormat(pwzData, pItm->wzID, countof(pItm->wzID));
130 + ExitOnFailure(hr, "Failed to parse id guid value, key: %S, value: '%S'", pItm->wzKey, pwzData);
131 + }
132 +
133 + // get name
134 + hr = WcaGetRecordFormattedString(hRec, pqName, &pwzData);
135 + ExitOnFailure(hr, "Failed to get name");
136 + StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
137 +
138 + // if partition is a locater, either an id or a name must be provided
139 + if (!pItm->fHasComponent && !*pItm->wzID && !*pItm->wzName)
140 + ExitOnFailure(hr = E_FAIL, "A partition locater must have either an id or a name associated, key: %S", pItm->wzKey);
141 +
142 + // if partition is not a locater, an name must be provided
143 + if (pItm->fHasComponent && !*pItm->wzName)
144 + ExitOnFailure(hr = E_FAIL, "A partition must have a name associated, key: %S", pItm->wzKey);
145 +
146 + // get properties
147 + if (CpiTableExists(cptComPlusPartitionProperty) && pItm->fHasComponent)
148 + {
149 + hr = CpiPropertiesRead(vcsPartitionPropertyQuery, pItm->wzKey, pdlPartitionProperties, &pItm->pProperties, &pItm->iPropertyCount);
150 + ExitOnFailure(hr, "Failed to get properties");
151 + }
152 +
153 + // increment counters
154 + if (pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction))
155 + pPartList->iInstallCount++;
156 + if (pItm->fHasComponent && WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
157 + pPartList->iUninstallCount++;
158 +
159 + // add entry
160 + if (pPartList->pFirst)
161 + pItm->pNext = pPartList->pFirst;
162 + pPartList->pFirst = pItm;
163 + pItm = NULL;
164 + }
165 +
166 + if (E_NOMOREITEMS == hr)
167 + hr = S_OK;
168 +
169 +LExit:
170 + // clean up
171 + if (pItm)
172 + FreePartition(pItm);
173 +
174 + ReleaseStr(pwzData);
175 +
176 + return hr;
177 +}
178 +
179 +HRESULT CpiPartitionsVerifyInstall(
180 + CPI_PARTITION_LIST* pList
181 + )
182 +{
183 + HRESULT hr = S_OK;
184 + UINT er = ERROR_SUCCESS;
185 +
186 + ICatalogCollection* piPartColl = NULL;
187 + ICatalogObject* piPartObj = NULL;
188 +
189 + for (CPI_PARTITION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
190 + {
191 + // referenced locaters or partitions that are being installed
192 + if (!pItm->fReferencedForInstall && !(pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction)))
193 + continue;
194 +
195 + // if the partition is referensed and is not a locater, it must be installed
196 + if (pItm->fReferencedForInstall && pItm->fHasComponent && !CpiWillBeInstalled(pItm->isInstalled, pItm->isAction))
197 + MessageExitOnFailure(hr = E_FAIL, msierrComPlusPartitionDependency, "A partition is used by another entity being installed, but is not installed itself, key: %S", pItm->wzKey);
198 +
199 + // get partitions collection
200 + if (!piPartColl)
201 + {
202 + hr = CpiGetPartitionsCollection(&piPartColl);
203 + ExitOnFailure(hr, "Failed to get partitions collection");
204 + }
205 +
206 + // partition is supposed to exist
207 + if (!pItm->fHasComponent || CpiIsInstalled(pItm->isInstalled))
208 + {
209 + // get collection object for partition
210 + hr = CpiFindCollectionObject(piPartColl, pItm->wzID, *pItm->wzID ? NULL : pItm->wzName, &piPartObj);
211 + ExitOnFailure(hr, "Failed to find collection object for partition");
212 +
213 + // if the partition was found
214 + if (S_OK == hr)
215 + {
216 + // if we don't have an id, copy id from object
217 + if (!*pItm->wzID)
218 + {
219 + hr = CpiGetKeyForObject(piPartObj, pItm->wzID, countof(pItm->wzID));
220 + ExitOnFailure(hr, "Failed to get id");
221 + }
222 + }
223 +
224 + // if the partition was not found
225 + else
226 + {
227 + // if the application is a locater, this is an error
228 + if (!pItm->fHasComponent)
229 + MessageExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), msierrComPlusPartitionNotFound, "A partition required by this installation was not found, key: %S", pItm->wzKey);
230 +
231 + // create a new id if one is missing
232 + if (!*pItm->wzID)
233 + {
234 + hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
235 + ExitOnFailure(hr, "Failed to create id");
236 + }
237 + }
238 + }
239 +
240 + // partition is supposed to be created
241 + else
242 + {
243 + // check for conflicts
244 + do {
245 + if (*pItm->wzID)
246 + {
247 + // find partitions with conflicting id
248 + hr = CpiFindCollectionObject(piPartColl, pItm->wzID, NULL, &piPartObj);
249 + ExitOnFailure(hr, "Failed to find collection object for partition");
250 +
251 + if (S_FALSE == hr)
252 + {
253 + // find partitions with conflicting name
254 + hr = CpiFindCollectionObject(piPartColl, NULL, pItm->wzName, &piPartObj);
255 + ExitOnFailure(hr, "Failed to find collection object for partition");
256 +
257 + if (S_OK == hr)
258 + // "A partition with a conflictiong name exists. retry cancel"
259 + er = WcaErrorMessage(msierrComPlusPartitionNameConflict, hr, INSTALLMESSAGE_ERROR | MB_RETRYCANCEL, 0);
260 + else
261 + break; // no conflicting entry found, break loop
262 + }
263 + else
264 + // "A partition with a conflicting id exists. abort retry ignore"
265 + er = WcaErrorMessage(msierrComPlusPartitionIdConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
266 + }
267 + else
268 + {
269 + // find partitions with conflicting name
270 + hr = CpiFindCollectionObject(piPartColl, NULL, pItm->wzName, &piPartObj);
271 + ExitOnFailure(hr, "Failed to find collection object for partition");
272 +
273 + if (S_OK == hr)
274 + // "A partition with a conflictiong name exists. abort retry ignore"
275 + er = WcaErrorMessage(msierrComPlusPartitionNameConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
276 + else
277 + break; // no conflicting entry found, break loop
278 + }
279 +
280 + switch (er)
281 + {
282 + case IDCANCEL:
283 + case IDABORT:
284 + ExitOnFailure(hr = E_FAIL, "A partition with a conflictiong name or id exists, key: %S", pItm->wzKey);
285 + break;
286 + case IDRETRY:
287 + break;
288 + case IDIGNORE:
289 + default:
290 + // if we don't have an id, copy id from object
291 + if (!*pItm->wzID)
292 + {
293 + hr = CpiGetKeyForObject(piPartObj, pItm->wzID, countof(pItm->wzID));
294 + ExitOnFailure(hr, "Failed to get id");
295 + }
296 + hr = S_FALSE; // indicate that this is not a conflict
297 + }
298 + } while (S_OK == hr); // hr = S_FALSE if we don't have any conflicts
299 +
300 + // create a new id if one is missing
301 + if (!*pItm->wzID)
302 + {
303 + hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
304 + ExitOnFailure(hr, "Failed to create id");
305 + }
306 + }
307 +
308 + // clean up
309 + ReleaseNullObject(piPartObj);
310 + }
311 +
312 + hr = S_OK;
313 +
314 +LExit:
315 + // clean up
316 + ReleaseObject(piPartColl);
317 + ReleaseObject(piPartObj);
318 +
319 + return hr;
320 +}
321 +
322 +HRESULT CpiPartitionsVerifyUninstall(
323 + CPI_PARTITION_LIST* pList
324 + )
325 +{
326 + HRESULT hr = S_OK;
327 + ICatalogCollection* piPartColl = NULL;
328 + ICatalogObject* piPartObj = NULL;
329 +
330 + for (CPI_PARTITION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
331 + {
332 + // referenced locaters or partitions that are being uninstalled
333 + if (!pItm->fReferencedForUninstall && !(pItm->fHasComponent && WcaIsUninstalling(pItm->isInstalled, pItm->isAction)))
334 + continue;
335 +
336 + // get partitions collection
337 + if (!piPartColl)
338 + {
339 + hr = CpiGetPartitionsCollection(&piPartColl);
340 + ExitOnFailure(hr, "Failed to get partitions collection");
341 + }
342 +
343 + // get collection object for partition
344 + hr = CpiFindCollectionObject(piPartColl, pItm->wzID, *pItm->wzID ? NULL : pItm->wzName, &piPartObj);
345 + ExitOnFailure(hr, "Failed to find collection object for partition");
346 +
347 + // if the partition was found
348 + if (S_OK == hr)
349 + {
350 + // if we don't have an id, copy id from object
351 + if (!*pItm->wzID)
352 + {
353 + hr = CpiGetKeyForObject(piPartObj, pItm->wzID, countof(pItm->wzID));
354 + ExitOnFailure(hr, "Failed to get id");
355 + }
356 + }
357 +
358 + // if the partition was not found
359 + else
360 + {
361 + pItm->fObjectNotFound = TRUE;
362 + if (pItm->fHasComponent)
363 + pList->iUninstallCount--; // elements with the fObjectNotFound flag set will not be scheduled for uninstall
364 + }
365 +
366 + // clean up
367 + ReleaseNullObject(piPartObj);
368 + }
369 +
370 + hr = S_OK;
371 +
372 +LExit:
373 + // clean up
374 + ReleaseObject(piPartColl);
375 + ReleaseObject(piPartObj);
376 +
377 + return hr;
378 +}
379 +
380 +void CpiPartitionAddReferenceInstall(
381 + CPI_PARTITION* pItm
382 + )
383 +{
384 + pItm->fReferencedForInstall = TRUE;
385 +}
386 +
387 +void CpiPartitionAddReferenceUninstall(
388 + CPI_PARTITION* pItm
389 + )
390 +{
391 + pItm->fReferencedForUninstall = TRUE;
392 +}
393 +
394 +HRESULT CpiPartitionsInstall(
395 + CPI_PARTITION_LIST* pList,
396 + int iRunMode,
397 + LPWSTR* ppwzActionData,
398 + int* piProgress
399 + )
400 +{
401 + HRESULT hr = S_OK;
402 +
403 + int iActionType;
404 +
405 + // add action text
406 + hr = CpiAddActionTextToActionData(L"CreateComPlusPartitions", ppwzActionData);
407 + ExitOnFailure(hr, "Failed to add action text to custom action data");
408 +
409 + // add partition count to action data
410 + hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData);
411 + ExitOnFailure(hr, "Failed to add count to custom action data");
412 +
413 + // add applications to custom action data
414 + for (CPI_PARTITION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
415 + {
416 + // partitions that are being installed only
417 + if (!pItm->fHasComponent || !WcaIsInstalling(pItm->isInstalled, pItm->isAction))
418 + continue;
419 +
420 + // action type
421 + if (rmRollback == iRunMode)
422 + {
423 + if (CpiIsInstalled(pItm->isInstalled))
424 + iActionType = atNoOp;
425 + else
426 + iActionType = atRemove;
427 + }
428 + else
429 + iActionType = atCreate;
430 +
431 + // add to action data
432 + hr = AddPartitionToActionData(pItm, iActionType, COST_PARTITION_CREATE, ppwzActionData);
433 + ExitOnFailure(hr, "Failed to add partition to custom action data, key: %S", pItm->wzKey);
434 + }
435 +
436 + // add progress tics
437 + if (piProgress)
438 + *piProgress += COST_PARTITION_CREATE * pList->iInstallCount;
439 +
440 + hr = S_OK;
441 +
442 +LExit:
443 + return hr;
444 +}
445 +
446 +HRESULT CpiPartitionsUninstall(
447 + CPI_PARTITION_LIST* pList,
448 + int iRunMode,
449 + LPWSTR* ppwzActionData,
450 + int* piProgress
451 + )
452 +{
453 + HRESULT hr = S_OK;
454 +
455 + int iActionType;
456 +
457 + // add action text
458 + hr = CpiAddActionTextToActionData(L"RemoveComPlusPartitions", ppwzActionData);
459 + ExitOnFailure(hr, "Failed to add action text to custom action data");
460 +
461 + // add partition count to action data
462 + hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
463 + ExitOnFailure(hr, "Failed to add count to custom action data");
464 +
465 + // add partitions to custom action data
466 + for (CPI_PARTITION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
467 + {
468 + // partitions that are being uninstalled only
469 + if (!pItm->fHasComponent || pItm->fObjectNotFound || !WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
470 + continue;
471 +
472 + // action type
473 + if (rmRollback == iRunMode)
474 + iActionType = atCreate;
475 + else
476 + iActionType = atRemove;
477 +
478 + // add to action data
479 + hr = AddPartitionToActionData(pItm, iActionType, COST_PARTITION_DELETE, ppwzActionData);
480 + ExitOnFailure(hr, "Failed to add partition to custom action data, key:", pItm->wzKey);
481 + }
482 +
483 + // add progress tics
484 + if (piProgress)
485 + *piProgress += COST_PARTITION_DELETE * pList->iUninstallCount;
486 +
487 + hr = S_OK;
488 +
489 +LExit:
490 + return hr;
491 +}
492 +
493 +HRESULT CpiPartitionFindByKey(
494 + CPI_PARTITION_LIST* pList,
495 + LPCWSTR wzKey,
496 + CPI_PARTITION** ppItm
497 + )
498 +{
499 + for (CPI_PARTITION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
500 + {
501 + if (0 == lstrcmpW(pItm->wzKey, wzKey))
502 + {
503 + *ppItm = pItm;
504 + return S_OK;
505 + }
506 + }
507 +
508 + return S_FALSE;
509 +}
510 +
511 +HRESULT CpiGetApplicationsCollForPartition(
512 + CPI_PARTITION* pPart,
513 + ICatalogCollection** ppiAppColl
514 + )
515 +{
516 + HRESULT hr = S_OK;
517 +
518 + ICatalogCollection* piPartColl = NULL;
519 + ICatalogObject* piPartObj = NULL;
520 +
521 + // if a previous attempt to locate the collection object failed
522 + if (pPart->fObjectNotFound)
523 + ExitFunction1(hr = S_FALSE);
524 +
525 + // get applications collection
526 + if (!pPart->piApplicationsColl)
527 + {
528 + // get partitions collection from catalog
529 + hr = CpiGetPartitionsCollection(&piPartColl);
530 + ExitOnFailure(hr, "Failed to get partitions collection");
531 +
532 + // find application object
533 + hr = CpiFindCollectionObject(piPartColl, pPart->wzID, *pPart->wzID ? NULL : pPart->wzName, &piPartObj);
534 + ExitOnFailure(hr, "Failed to find partition object");
535 +
536 + if (S_FALSE == hr)
537 + {
538 + pPart->fObjectNotFound = TRUE;
539 + ExitFunction(); // exit with hr = S_FALSE
540 + }
541 +
542 + // get roles collection
543 + hr = CpiGetCatalogCollection(piPartColl, piPartObj, L"Applications", &pPart->piApplicationsColl);
544 + ExitOnFailure(hr, "Failed to get applications collection");
545 + }
546 +
547 + // return value
548 + *ppiAppColl = pPart->piApplicationsColl;
549 + (*ppiAppColl)->AddRef();
550 +
551 + hr = S_OK;
552 +
553 +LExit:
554 + // clean up
555 + ReleaseObject(piPartColl);
556 + ReleaseObject(piPartObj);
557 +
558 + return hr;
559 +}
560 +
561 +HRESULT CpiGetRolesCollForPartition(
562 + CPI_PARTITION* pPart,
563 + ICatalogCollection** ppiRolesColl
564 + )
565 +{
566 + HRESULT hr = S_OK;
567 +
568 + ICatalogCollection* piPartColl = NULL;
569 + ICatalogObject* piPartObj = NULL;
570 +
571 + // if a previous attempt to locate the collection object failed
572 + if (pPart->fObjectNotFound)
573 + ExitFunction1(hr = S_FALSE);
574 +
575 + // get applications collection
576 + if (!pPart->piRolesColl)
577 + {
578 + // get partitions collection from catalog
579 + hr = CpiGetPartitionsCollection(&piPartColl);
580 + ExitOnFailure(hr, "Failed to get partitions collection");
581 +
582 + // find partition object
583 + hr = CpiFindCollectionObject(piPartColl, pPart->wzID, *pPart->wzID ? NULL : pPart->wzName, &piPartObj);
584 + ExitOnFailure(hr, "Failed to find partition object");
585 +
586 + if (S_FALSE == hr)
587 + ExitFunction(); // exit with hr = S_FALSE
588 +
589 + // get roles collection
590 + hr = CpiGetCatalogCollection(piPartColl, piPartObj, L"RolesForPartition", &pPart->piRolesColl);
591 + ExitOnFailure(hr, "Failed to get roles collection");
592 + }
593 +
594 + // return value
595 + *ppiRolesColl = pPart->piRolesColl;
596 + (*ppiRolesColl)->AddRef();
597 +
598 + hr = S_OK;
599 +
600 +LExit:
601 + // clean up
602 + ReleaseObject(piPartColl);
603 + ReleaseObject(piPartObj);
604 +
605 + return hr;
606 +}
607 +
608 +void CpiPartitionUserListFree(
609 + CPI_PARTITION_USER_LIST* pList
610 + )
611 +{
612 + CPI_PARTITION_USER* pItm = pList->pFirst;
613 +
614 + while (pItm)
615 + {
616 + CPI_PARTITION_USER* pDelete = pItm;
617 + pItm = pItm->pNext;
618 + FreePartitionUser(pDelete);
619 + }
620 +}
621 +
622 +HRESULT CpiPartitionUsersRead(
623 + CPI_PARTITION_LIST* pPartList,
624 + CPI_PARTITION_USER_LIST* pPartUsrList
625 + )
626 +{
627 + HRESULT hr = S_OK;
628 + UINT er = ERROR_SUCCESS;
629 +
630 + PMSIHANDLE hView, hRec;
631 +
632 + CPI_PARTITION_USER* pItm = NULL;
633 + LPWSTR pwzData = NULL;
634 + LPWSTR pwzDomain = NULL;
635 + LPWSTR pwzName = NULL;
636 + BOOL fMatchingArchitecture = FALSE;
637 +
638 + // loop through all partition users
639 + hr = WcaOpenExecuteView(vcsPartitionUserQuery, &hView);
640 + ExitOnFailure(hr, "Failed to execute view on ComPlusPartitionUser table");
641 +
642 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
643 + {
644 + // get component
645 + hr = WcaGetRecordString(hRec, puqComponent, &pwzData);
646 + ExitOnFailure(hr, "Failed to get component");
647 +
648 + // check if the component is our processor architecture
649 + hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
650 + ExitOnFailure(hr, "Failed to get component architecture.");
651 +
652 + if (!fMatchingArchitecture)
653 + {
654 + continue; // not the same architecture, ignore
655 + }
656 +
657 + // create entry
658 + pItm = (CPI_PARTITION_USER*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PARTITION_USER));
659 + if (!pItm)
660 + ExitFunction1(hr = E_OUTOFMEMORY);
661 +
662 + // get component install state
663 + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
664 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
665 +
666 + // get key
667 + hr = WcaGetRecordString(hRec, puqPartitionUser, &pwzData);
668 + ExitOnFailure(hr, "Failed to get key");
669 + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
670 +
671 + // get partition
672 + hr = WcaGetRecordString(hRec, puqPartition, &pwzData);
673 + ExitOnFailure(hr, "Failed to get partition");
674 +
675 + hr = CpiPartitionFindByKey(pPartList, pwzData, &pItm->pPartition);
676 + if (S_FALSE == hr)
677 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
678 + ExitOnFailure(hr, "Failed to find partition, key: %S", pwzData);
679 +
680 + // get user domain
681 + hr = WcaGetRecordFormattedString(hRec, puqDomain, &pwzDomain);
682 + ExitOnFailure(hr, "Failed to get user domain");
683 +
684 + // get user name
685 + hr = WcaGetRecordFormattedString(hRec, puqName, &pwzName);
686 + ExitOnFailure(hr, "Failed to get user name");
687 +
688 + // build account name
689 + hr = CpiBuildAccountName(pwzDomain, pwzName, &pItm->pwzAccount);
690 + ExitOnFailure(hr, "Failed to build account name");
691 +
692 + // set references & increment counters
693 + if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
694 + {
695 + pItm->pPartition->fReferencedForInstall = TRUE;
696 + pPartUsrList->iInstallCount++;
697 + }
698 + if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
699 + {
700 + pItm->pPartition->fReferencedForUninstall = TRUE;
701 + pPartUsrList->iUninstallCount++;
702 + }
703 +
704 + // add entry
705 + if (pPartUsrList->pFirst)
706 + pItm->pNext = pPartUsrList->pFirst;
707 + pPartUsrList->pFirst = pItm;
708 + pItm = NULL;
709 + }
710 +
711 + if (E_NOMOREITEMS == hr)
712 + hr = S_OK;
713 +
714 +LExit:
715 + // clean up
716 + if (pItm)
717 + FreePartitionUser(pItm);
718 +
719 + ReleaseStr(pwzData);
720 + ReleaseStr(pwzDomain);
721 + ReleaseStr(pwzName);
722 +
723 + return hr;
724 +}
725 +
726 +HRESULT CpiPartitionUsersInstall(
727 + CPI_PARTITION_USER_LIST* pList,
728 + int iRunMode,
729 + LPWSTR* ppwzActionData,
730 + int* piProgress
731 + )
732 +{
733 + HRESULT hr = S_OK;
734 +
735 + int iActionType;
736 +
737 + // add action text
738 + hr = CpiAddActionTextToActionData(L"AddComPlusPartitionUsers", ppwzActionData);
739 + ExitOnFailure(hr, "Failed to add action text to custom action data");
740 +
741 + // add partition count to action data
742 + hr = WcaWriteIntegerToCaData(pList->iInstallCount, ppwzActionData);
743 + ExitOnFailure(hr, "Failed to add count to custom action data");
744 +
745 + // add applications to custom action data
746 + for (CPI_PARTITION_USER* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
747 + {
748 + // partitions that are being installed only
749 + if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
750 + continue;
751 +
752 + // action type
753 + if (rmRollback == iRunMode)
754 + {
755 + if (CpiIsInstalled(pItm->isInstalled))
756 + iActionType = atNoOp;
757 + else
758 + iActionType = atRemove;
759 + }
760 + else
761 + iActionType = atCreate;
762 +
763 + // add to action data
764 + hr = AddPartitionUserToActionData(pItm, iActionType, COST_PARTITION_USER_CREATE, ppwzActionData);
765 + ExitOnFailure(hr, "Failed to add partition user to custom action data, key: %S", pItm->wzKey);
766 + }
767 +
768 + // add progress tics
769 + if (piProgress)
770 + *piProgress += COST_PARTITION_USER_CREATE * pList->iInstallCount;
771 +
772 + hr = S_OK;
773 +
774 +LExit:
775 + return hr;
776 +}
777 +
778 +HRESULT CpiPartitionUsersUninstall(
779 + CPI_PARTITION_USER_LIST* pList,
780 + int iRunMode,
781 + LPWSTR* ppwzActionData,
782 + int* piProgress
783 + )
784 +{
785 + HRESULT hr = S_OK;
786 +
787 + int iActionType;
788 +
789 + // add action text
790 + hr = CpiAddActionTextToActionData(L"RemoveComPlusPartitionUsers", ppwzActionData);
791 + ExitOnFailure(hr, "Failed to add action text to custom action data");
792 +
793 + // add partition count to action data
794 + hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
795 + ExitOnFailure(hr, "Failed to add count to custom action data");
796 +
797 + // add partitions to custom action data
798 + for (CPI_PARTITION_USER* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
799 + {
800 + // partitions that are being uninstalled only
801 + if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
802 + continue;
803 +
804 + // action type
805 + if (rmRollback == iRunMode)
806 + iActionType = atCreate;
807 + else
808 + iActionType = atRemove;
809 +
810 + // add to action data
811 + hr = AddPartitionUserToActionData(pItm, iActionType, COST_PARTITION_USER_DELETE, ppwzActionData);
812 + ExitOnFailure(hr, "Failed to add partition user to custom action data, key: %S", pItm->wzKey);
813 + }
814 +
815 + // add progress tics
816 + if (piProgress)
817 + *piProgress += COST_PARTITION_USER_DELETE * pList->iUninstallCount;
818 +
819 + hr = S_OK;
820 +
821 +LExit:
822 + return hr;
823 +}
824 +
825 +
826 +// helper function definitions
827 +
828 +static void FreePartition(
829 + CPI_PARTITION* pItm
830 + )
831 +{
832 + if (pItm->pProperties)
833 + CpiPropertiesFreeList(pItm->pProperties);
834 +
835 + ReleaseObject(pItm->piApplicationsColl);
836 + ReleaseObject(pItm->piRolesColl);
837 +
838 + ::HeapFree(::GetProcessHeap(), 0, pItm);
839 +}
840 +
841 +static void FreePartitionUser(
842 + CPI_PARTITION_USER* pItm
843 + )
844 +{
845 + ReleaseStr(pItm->pwzAccount);
846 +
847 + ::HeapFree(::GetProcessHeap(), 0, pItm);
848 +}
849 +
850 +static HRESULT AddPartitionToActionData(
851 + CPI_PARTITION* pItm,
852 + int iActionType,
853 + int iActionCost,
854 + LPWSTR* ppwzActionData
855 + )
856 +{
857 + HRESULT hr = S_OK;
858 +
859 + // add action information to custom action data
860 + hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
861 + ExitOnFailure(hr, "Failed to add action type to custom action data");
862 + hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
863 + ExitOnFailure(hr, "Failed to add action cost to custom action data");
864 +
865 + // add partition information to custom action data
866 + hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
867 + ExitOnFailure(hr, "Failed to add partition key to custom action data");
868 + hr = WcaWriteStringToCaData(pItm->wzID, ppwzActionData);
869 + ExitOnFailure(hr, "Failed to add partition id to custom action data");
870 + hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData);
871 + ExitOnFailure(hr, "Failed to add partition name to custom action data");
872 +
873 + // add properties to custom action data
874 + hr = CpiAddPropertiesToActionData(atCreate == iActionType ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
875 + ExitOnFailure(hr, "Failed to add properties to custom action data");
876 +
877 + hr = S_OK;
878 +
879 +LExit:
880 + return hr;
881 +}
882 +
883 +static HRESULT AddPartitionUserToActionData(
884 + CPI_PARTITION_USER* pItm,
885 + int iActionType,
886 + int iActionCost,
887 + LPWSTR* ppwzActionData
888 + )
889 +{
890 + HRESULT hr = S_OK;
891 +
892 + // add action information to custom action data
893 + hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
894 + ExitOnFailure(hr, "Failed to add action type to custom action data");
895 + hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
896 + ExitOnFailure(hr, "Failed to add action cost to custom action data");
897 +
898 + // add partition user information to custom action data
899 + hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
900 + ExitOnFailure(hr, "Failed to add partition user key to custom action data");
901 + hr = WcaWriteStringToCaData(pItm->pwzAccount, ppwzActionData);
902 + ExitOnFailure(hr, "Failed to add user account to custom action data");
903 +
904 + // add partition information to custom action data
905 + hr = WcaWriteStringToCaData(atCreate == iActionType ? pItm->pPartition->wzID : L"", ppwzActionData);
906 + ExitOnFailure(hr, "Failed to add partition id to custom action data");
907 +
908 + hr = S_OK;
909 +
910 +LExit:
911 + return hr;
912 +}
src/ca/cppartsched.h new
+125
@@ -0,0 +1,125 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +struct CPI_PARTITION
6 +{
7 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
8 + WCHAR wzID[CPI_MAX_GUID + 1];
9 + WCHAR wzName[MAX_DARWIN_COLUMN + 1];
10 +
11 + int iPropertyCount;
12 + CPI_PROPERTY* pProperties;
13 +
14 + BOOL fHasComponent;
15 + BOOL fReferencedForInstall;
16 + BOOL fReferencedForUninstall;
17 + BOOL fObjectNotFound;
18 +
19 + INSTALLSTATE isInstalled, isAction;
20 +
21 + ICatalogCollection* piApplicationsColl;
22 + ICatalogCollection* piRolesColl;
23 +
24 + CPI_PARTITION* pNext;
25 +};
26 +
27 +struct CPI_PARTITION_LIST
28 +{
29 + CPI_PARTITION* pFirst;
30 +
31 + int iInstallCount;
32 + int iUninstallCount;
33 +};
34 +
35 +struct CPI_PARTITION_USER
36 +{
37 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
38 + LPWSTR pwzAccount;
39 +
40 + BOOL fNoFind;
41 +
42 + INSTALLSTATE isInstalled, isAction;
43 +
44 + CPI_PARTITION* pPartition;
45 +
46 + CPI_PARTITION_USER* pNext;
47 +};
48 +
49 +struct CPI_PARTITION_USER_LIST
50 +{
51 + CPI_PARTITION_USER* pFirst;
52 +
53 + int iInstallCount;
54 + int iUninstallCount;
55 +};
56 +
57 +
58 +// function prototypes
59 +
60 +void CpiPartitionListFree(
61 + CPI_PARTITION_LIST* pList
62 + );
63 +HRESULT CpiPartitionsRead(
64 + CPI_PARTITION_LIST* pPartList
65 + );
66 +HRESULT CpiPartitionsVerifyInstall(
67 + CPI_PARTITION_LIST* pList
68 + );
69 +HRESULT CpiPartitionsVerifyUninstall(
70 + CPI_PARTITION_LIST* pList
71 + );
72 +void CpiPartitionAddReferenceInstall(
73 + CPI_PARTITION* pItm
74 + );
75 +void CpiPartitionAddReferenceUninstall(
76 + CPI_PARTITION* pItm
77 + );
78 +HRESULT CpiPartitionsInstall(
79 + CPI_PARTITION_LIST* pList,
80 + int iRunMode,
81 + LPWSTR* ppwzActionData,
82 + int* piProgress
83 + );
84 +HRESULT CpiPartitionsUninstall(
85 + CPI_PARTITION_LIST* pList,
86 + int iRunMode,
87 + LPWSTR* ppwzActionData,
88 + int* piProgress
89 + );
90 +HRESULT CpiPartitionFindByKey(
91 + CPI_PARTITION_LIST* pList,
92 + LPCWSTR wzKey,
93 + CPI_PARTITION** ppItm
94 + );
95 +HRESULT CpiGetApplicationsCollForPartition(
96 + CPI_PARTITION* pPart,
97 + ICatalogCollection** ppiAppColl
98 + );
99 +HRESULT CpiGetPartitionUsersCollection(
100 + CPI_PARTITION* pPart,
101 + ICatalogCollection** ppiPartUsrColl
102 + );
103 +HRESULT CpiGetRolesCollForPartition(
104 + CPI_PARTITION* pPart,
105 + ICatalogCollection** ppiRolesColl
106 + );
107 +void CpiPartitionUserListFree(
108 + CPI_PARTITION_USER_LIST* pList
109 + );
110 +HRESULT CpiPartitionUsersRead(
111 + CPI_PARTITION_LIST* pPartList,
112 + CPI_PARTITION_USER_LIST* pPartUsrList
113 + );
114 +HRESULT CpiPartitionUsersInstall(
115 + CPI_PARTITION_USER_LIST* pList,
116 + int iRunMode,
117 + LPWSTR* ppwzActionData,
118 + int* piProgress
119 + );
120 +HRESULT CpiPartitionUsersUninstall(
121 + CPI_PARTITION_USER_LIST* pList,
122 + int iRunMode,
123 + LPWSTR* ppwzActionData,
124 + int* piProgress
125 + );
src/ca/cpsched.cpp new
+590
@@ -0,0 +1,590 @@
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 +#ifdef _WIN64
7 +#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare_64"
8 +#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare_64"
9 +#define CP_COMPLUSROLLBACKINSTALLEXECUTE L"ComPlusRollbackInstallExecute_64"
10 +#define CP_COMPLUSINSTALLEXECUTE L"ComPlusInstallExecute_64"
11 +#define CP_COMPLUSINSTALLEXECUTECOMMIT L"ComPlusInstallExecuteCommit_64"
12 +#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit_64"
13 +#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare_64"
14 +#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare_64"
15 +#define CP_COMPLUSROLLBACKUNINSTALLEXECUTE L"ComPlusRollbackUninstallExecute_64"
16 +#define CP_COMPLUSUNINSTALLEXECUTE L"ComPlusUninstallExecute_64"
17 +#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit_64"
18 +#else
19 +#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare"
20 +#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare"
21 +#define CP_COMPLUSROLLBACKINSTALLEXECUTE L"ComPlusRollbackInstallExecute"
22 +#define CP_COMPLUSINSTALLEXECUTE L"ComPlusInstallExecute"
23 +#define CP_COMPLUSINSTALLEXECUTECOMMIT L"ComPlusInstallExecuteCommit"
24 +#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit"
25 +#define CP_COMPLUSROLLBACKINSTALLPREPARE L"ComPlusRollbackInstallPrepare"
26 +#define CP_COMPLUSINSTALLPREPARE L"ComPlusInstallPrepare"
27 +#define CP_COMPLUSROLLBACKUNINSTALLEXECUTE L"ComPlusRollbackUninstallExecute"
28 +#define CP_COMPLUSUNINSTALLEXECUTE L"ComPlusUninstallExecute"
29 +#define CP_COMPLUSINSTALLCOMMIT L"ComPlusInstallCommit"
30 +#endif
31 +
32 +
33 +/********************************************************************
34 + DllMain - standard entry point for all WiX CustomActions
35 +
36 +********************************************************************/
37 +extern "C" BOOL WINAPI DllMain(
38 + IN HINSTANCE hInst,
39 + IN ULONG ulReason,
40 + IN LPVOID)
41 +{
42 + switch(ulReason)
43 + {
44 + case DLL_PROCESS_ATTACH:
45 + WcaGlobalInitialize(hInst);
46 + break;
47 +
48 + case DLL_PROCESS_DETACH:
49 + WcaGlobalFinalize();
50 + break;
51 + }
52 +
53 + return TRUE;
54 +}
55 +
56 +/********************************************************************
57 + ConfigureComPlusInstall - CUSTOM ACTION ENTRY POINT for installing COM+ components
58 +
59 +********************************************************************/
60 +extern "C" UINT __stdcall ConfigureComPlusInstall(MSIHANDLE hInstall)
61 +{
62 + HRESULT hr = S_OK;
63 + UINT er = ERROR_SUCCESS;
64 +
65 + BOOL fInitializedCom = FALSE;
66 +
67 + ICOMAdminCatalog* piCatalog = NULL;
68 +
69 + CPI_PARTITION_LIST partList;
70 + CPI_PARTITION_ROLE_LIST partRoleList;
71 + CPI_USER_IN_PARTITION_ROLE_LIST usrInPartRoleList;
72 + CPI_PARTITION_USER_LIST partUsrList;
73 + CPI_APPLICATION_LIST appList;
74 + CPI_APPLICATION_ROLE_LIST appRoleList;
75 + CPI_USER_IN_APPLICATION_ROLE_LIST usrInAppRoleList;
76 + CPI_ASSEMBLY_LIST asmList;
77 + CPI_SUBSCRIPTION_LIST subList;
78 +
79 + LPWSTR pwzRollbackFileName = NULL;
80 + LPWSTR pwzActionData = NULL;
81 + LPWSTR pwzRollbackActionData = NULL;
82 + LPWSTR pwzCommitActionData = NULL;
83 +
84 + int iVersionNT = 0;
85 + int iProgress = 0;
86 + int iCommitProgress = 0;
87 +
88 + ::ZeroMemory(&partList, sizeof(CPI_PARTITION_LIST));
89 + ::ZeroMemory(&partRoleList, sizeof(CPI_PARTITION_ROLE_LIST));
90 + ::ZeroMemory(&usrInPartRoleList, sizeof(CPI_USER_IN_PARTITION_ROLE_LIST));
91 + ::ZeroMemory(&partUsrList, sizeof(CPI_PARTITION_USER_LIST));
92 + ::ZeroMemory(&appList, sizeof(CPI_APPLICATION_LIST));
93 + ::ZeroMemory(&appRoleList, sizeof(CPI_APPLICATION_ROLE_LIST));
94 + ::ZeroMemory(&usrInAppRoleList, sizeof(CPI_USER_IN_APPLICATION_ROLE_LIST));
95 + ::ZeroMemory(&asmList, sizeof(CPI_ASSEMBLY_LIST));
96 + ::ZeroMemory(&subList, sizeof(CPI_SUBSCRIPTION_LIST));
97 +
98 + // initialize
99 + hr = WcaInitialize(hInstall, "ConfigureComPlusInstall");
100 + ExitOnFailure(hr, "Failed to initialize");
101 +
102 + hr = ::CoInitialize(NULL);
103 + ExitOnFailure(hr, "Failed to initialize COM");
104 + fInitializedCom = TRUE;
105 +
106 + CpiInitialize();
107 +
108 + // check for the prerequsite tables
109 + if (!CpiTableExists(cptComPlusPartition) && !CpiTableExists(cptComPlusApplication) && !CpiTableExists(cptComPlusAssembly))
110 + {
111 + WcaLog(LOGMSG_VERBOSE, "skipping install COM+ CustomAction, no ComPlusPartition, ComPlusApplication or ComPlusAssembly table present");
112 + ExitFunction1(hr = S_FALSE);
113 + }
114 +
115 + // make sure we can access the COM+ admin catalog
116 + do {
117 + hr = CpiGetAdminCatalog(&piCatalog);
118 + if (FAILED(hr))
119 + {
120 + WcaLog(LOGMSG_STANDARD, "Failed to get COM+ admin catalog");
121 + er = WcaErrorMessage(msierrComPlusCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
122 + switch (er)
123 + {
124 + case IDABORT:
125 + ExitFunction(); // exit with hr from CpiGetAdminCatalog() to kick off a rollback
126 + case IDRETRY:
127 + hr = S_FALSE;
128 + break;
129 + case IDIGNORE:
130 + default:
131 + ExitFunction1(hr = S_OK); // pretend everything is okay and bail
132 + }
133 + }
134 + } while (S_FALSE == hr);
135 +
136 + // get NT version
137 + hr = WcaGetIntProperty(L"VersionNT", &iVersionNT);
138 + ExitOnFailure(hr, "Failed to get VersionNT property");
139 +
140 + // read elements
141 + if (502 <= iVersionNT && CpiTableExists(cptComPlusPartition))
142 + {
143 + hr = CpiPartitionsRead(&partList);
144 + MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read ComPlusPartitions table");
145 + }
146 +
147 + if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionRole))
148 + {
149 + hr = CpiPartitionRolesRead(&partList, &partRoleList);
150 + MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read ComPlusPartitionRole table");
151 + }
152 +
153 + if (502 <= iVersionNT && (CpiTableExists(cptComPlusUserInPartitionRole) || CpiTableExists(cptComPlusGroupInPartitionRole)))
154 + {
155 + hr = CpiUsersInPartitionRolesRead(&partRoleList, &usrInPartRoleList);
156 + MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read ComPlusUserInPartitionRole table");
157 + }
158 +
159 + if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionUser))
160 + {
161 + hr = CpiPartitionUsersRead(&partList, &partUsrList);
162 + MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read ComPlusPartitionUser table");
163 + }
164 +
165 + if (CpiTableExists(cptComPlusApplication))
166 + {
167 + hr = CpiApplicationsRead(&partList, &appList);
168 + MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read ComPlusApplication table");
169 + }
170 +
171 + if (CpiTableExists(cptComPlusApplicationRole))
172 + {
173 + hr = CpiApplicationRolesRead(&appList, &appRoleList);
174 + MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read ComPlusApplicationRole table");
175 + }
176 +
177 + if (CpiTableExists(cptComPlusUserInApplicationRole) || CpiTableExists(cptComPlusGroupInApplicationRole))
178 + {
179 + hr = CpiUsersInApplicationRolesRead(&appRoleList, &usrInAppRoleList);
180 + MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read ComPlusUserInApplicationRole table");
181 + }
182 +
183 + if (CpiTableExists(cptComPlusAssembly))
184 + {
185 + hr = CpiAssembliesRead(&appList, &appRoleList, &asmList);
186 + MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read ComPlusAssembly table");
187 + }
188 +
189 + if (CpiTableExists(cptComPlusSubscription))
190 + {
191 + hr = CpiSubscriptionsRead(&asmList, &subList);
192 + MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read ComPlusSubscription table");
193 + }
194 +
195 + // verify elements
196 + hr = CpiPartitionsVerifyInstall(&partList);
197 + ExitOnFailure(hr, "Failed to verify partitions");
198 +
199 + hr = CpiApplicationsVerifyInstall(&appList);
200 + ExitOnFailure(hr, "Failed to verify applications");
201 +
202 + hr = CpiApplicationRolesVerifyInstall(&appRoleList);
203 + ExitOnFailure(hr, "Failed to verify application roles");
204 +
205 + hr = CpiAssembliesVerifyInstall(&asmList);
206 + ExitOnFailure(hr, "Failed to verify assemblies");
207 +
208 + if (subList.iInstallCount)
209 + {
210 + hr = CpiSubscriptionsVerifyInstall(&subList);
211 + ExitOnFailure(hr, "Failed to verify subscriptions");
212 + }
213 +
214 + // schedule
215 + if (partList.iInstallCount || appList.iInstallCount || usrInAppRoleList.iInstallCount ||
216 + appRoleList.iInstallCount || asmList.iInstallCount || asmList.iRoleInstallCount || subList.iInstallCount)
217 + {
218 + // create rollback file name
219 + hr = CpiGetTempFileName(&pwzRollbackFileName);
220 + ExitOnFailure(hr, "Failed to get rollback file name");
221 +
222 + // schedule rollback prepare custom action
223 + hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLPREPARE, pwzRollbackFileName, 0);
224 + ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallPrepare");
225 +
226 + // schedule prepare custom action
227 + hr = WcaDoDeferredAction(CP_COMPLUSINSTALLPREPARE, pwzRollbackFileName, 0);
228 + ExitOnFailure(hr, "Failed to schedule ComPlusInstallPrepare");
229 +
230 + // schedule rollback custom action
231 + hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzRollbackActionData);
232 + ExitOnFailure(hr, "Failed to add rollback file name to rollback custom action data");
233 +
234 + hr = CpiSubscriptionsInstall(&subList, rmRollback, &pwzRollbackActionData, NULL);
235 + ExitOnFailure(hr, "Failed to install subscriptions");
236 + hr = CpiRoleAssignmentsInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL);
237 + ExitOnFailure(hr, "Failed to install assemblies");
238 + hr = CpiAssembliesInstall(&asmList, rmRollback, &pwzRollbackActionData, NULL);
239 + ExitOnFailure(hr, "Failed to install assemblies");
240 + hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmRollback, &pwzRollbackActionData, NULL);
241 + ExitOnFailure(hr, "Failed to install users in application roles");
242 + hr = CpiApplicationRolesInstall(&appRoleList, rmRollback, &pwzRollbackActionData, NULL);
243 + ExitOnFailure(hr, "Failed to install application roles");
244 + hr = CpiApplicationsInstall(&appList, rmRollback, &pwzRollbackActionData, NULL);
245 + ExitOnFailure(hr, "Failed to install applications");
246 + hr = CpiPartitionUsersInstall(&partUsrList, rmRollback, &pwzRollbackActionData, NULL);
247 + ExitOnFailure(hr, "Failed to install partition users");
248 + hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmRollback, &pwzRollbackActionData, NULL);
249 + ExitOnFailure(hr, "Failed to install users in partition roles");
250 + hr = CpiPartitionsInstall(&partList, rmRollback, &pwzRollbackActionData, NULL);
251 + ExitOnFailure(hr, "Failed to install partitions");
252 +
253 + hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLEXECUTE, pwzRollbackActionData, 0);
254 + ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallExecute");
255 +
256 + // schedule install custom action
257 + hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzActionData);
258 + ExitOnFailure(hr, "Failed to add rollback file name to custom action data");
259 +
260 + hr = CpiPartitionsInstall(&partList, rmDeferred, &pwzActionData, &iProgress);
261 + ExitOnFailure(hr, "Failed to install partitions");
262 + hr = CpiUsersInPartitionRolesInstall(&usrInPartRoleList, rmDeferred, &pwzActionData, &iProgress);
263 + ExitOnFailure(hr, "Failed to install users in partition roles");
264 + hr = CpiPartitionUsersInstall(&partUsrList, rmDeferred, &pwzActionData, &iProgress);
265 + ExitOnFailure(hr, "Failed to install partition users");
266 + hr = CpiApplicationsInstall(&appList, rmDeferred, &pwzActionData, &iProgress);
267 + ExitOnFailure(hr, "Failed to install applications");
268 + hr = CpiApplicationRolesInstall(&appRoleList, rmDeferred, &pwzActionData, &iProgress);
269 + ExitOnFailure(hr, "Failed to install application roles");
270 + hr = CpiUsersInApplicationRolesInstall(&usrInAppRoleList, rmDeferred, &pwzActionData, &iProgress);
271 + ExitOnFailure(hr, "Failed to install users in application roles");
272 + hr = CpiAssembliesInstall(&asmList, rmDeferred, &pwzActionData, &iProgress);
273 + ExitOnFailure(hr, "Failed to install assemblies");
274 + hr = CpiRoleAssignmentsInstall(&asmList, rmDeferred, &pwzActionData, &iProgress);
275 + ExitOnFailure(hr, "Failed to install assemblies");
276 + hr = CpiSubscriptionsInstall(&subList, rmDeferred, &pwzActionData, &iProgress);
277 + ExitOnFailure(hr, "Failed to install subscriptions");
278 +
279 + hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTE, pwzActionData, iProgress);
280 + ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecute");
281 +
282 + // schedule install commit custom action
283 + hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzCommitActionData);
284 + ExitOnFailure(hr, "Failed to add rollback file name to commit custom action data");
285 +
286 + hr = CpiAssembliesInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress);
287 + ExitOnFailure(hr, "Failed to install assemblies");
288 + hr = CpiRoleAssignmentsInstall(&asmList, rmCommit, &pwzCommitActionData, &iCommitProgress);
289 + ExitOnFailure(hr, "Failed to install assemblies");
290 + hr = CpiSubscriptionsInstall(&subList, rmCommit, &pwzCommitActionData, &iCommitProgress);
291 + ExitOnFailure(hr, "Failed to install subscriptions");
292 +
293 + hr = WcaDoDeferredAction(CP_COMPLUSINSTALLEXECUTECOMMIT, pwzCommitActionData, iCommitProgress);
294 + ExitOnFailure(hr, "Failed to schedule ComPlusInstallExecuteCommit");
295 +
296 + // schedule commit custom action
297 + hr = WcaDoDeferredAction(CP_COMPLUSINSTALLCOMMIT, pwzRollbackFileName, 0);
298 + ExitOnFailure(hr, "Failed to schedule ComPlusInstallCommit");
299 + }
300 +
301 + hr = S_OK;
302 +
303 +LExit:
304 + // clean up
305 + ReleaseObject(piCatalog);
306 +
307 + ReleaseStr(pwzRollbackFileName);
308 + ReleaseStr(pwzActionData);
309 + ReleaseStr(pwzRollbackActionData);
310 + ReleaseStr(pwzCommitActionData);
311 +
312 + CpiPartitionListFree(&partList);
313 + CpiPartitionRoleListFree(&partRoleList);
314 + CpiUserInPartitionRoleListFree(&usrInPartRoleList);
315 + CpiPartitionUserListFree(&partUsrList);
316 + CpiApplicationListFree(&appList);
317 + CpiApplicationRoleListFree(&appRoleList);
318 + CpiUserInApplicationRoleListFree(&usrInAppRoleList);
319 + CpiAssemblyListFree(&asmList);
320 + CpiSubscriptionListFree(&subList);
321 +
322 + // unitialize
323 + CpiFinalize();
324 +
325 + if (fInitializedCom)
326 + ::CoUninitialize();
327 +
328 + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
329 + return WcaFinalize(er);
330 +}
331 +
332 +
333 +/********************************************************************
334 + ConfigureComPlusUninstall - CUSTOM ACTION ENTRY POINT for uninstalling COM+ components
335 +
336 +********************************************************************/
337 +extern "C" UINT __stdcall ConfigureComPlusUninstall(MSIHANDLE hInstall)
338 +{
339 + HRESULT hr = S_OK;
340 + UINT er = ERROR_SUCCESS;
341 +
342 + BOOL fInitializedCom = FALSE;
343 +
344 + ICOMAdminCatalog* piCatalog = NULL;
345 +
346 + CPI_PARTITION_LIST partList;
347 + CPI_PARTITION_ROLE_LIST partRoleList;
348 + CPI_USER_IN_PARTITION_ROLE_LIST usrInPartRoleList;
349 + CPI_PARTITION_USER_LIST partUsrList;
350 + CPI_APPLICATION_LIST appList;
351 + CPI_APPLICATION_ROLE_LIST appRoleList;
352 + CPI_USER_IN_APPLICATION_ROLE_LIST usrInAppRoleList;
353 + CPI_ASSEMBLY_LIST asmList;
354 + CPI_SUBSCRIPTION_LIST subList;
355 +
356 + LPWSTR pwzRollbackFileName = NULL;
357 + LPWSTR pwzActionData = NULL;
358 + LPWSTR pwzRollbackActionData = NULL;
359 +
360 + int iVersionNT = 0;
361 + int iProgress = 0;
362 +
363 + ::ZeroMemory(&partList, sizeof(CPI_PARTITION_LIST));
364 + ::ZeroMemory(&partRoleList, sizeof(CPI_PARTITION_ROLE_LIST));
365 + ::ZeroMemory(&usrInPartRoleList, sizeof(CPI_USER_IN_PARTITION_ROLE_LIST));
366 + ::ZeroMemory(&partUsrList, sizeof(CPI_PARTITION_USER_LIST));
367 + ::ZeroMemory(&appList, sizeof(CPI_APPLICATION_LIST));
368 + ::ZeroMemory(&appRoleList, sizeof(CPI_APPLICATION_ROLE_LIST));
369 + ::ZeroMemory(&usrInAppRoleList, sizeof(CPI_USER_IN_APPLICATION_ROLE_LIST));
370 + ::ZeroMemory(&asmList, sizeof(CPI_ASSEMBLY_LIST));
371 + ::ZeroMemory(&subList, sizeof(CPI_SUBSCRIPTION_LIST));
372 +
373 + // initialize
374 + hr = WcaInitialize(hInstall, "ConfigureComPlusUninstall");
375 + ExitOnFailure(hr, "Failed to initialize");
376 +
377 + hr = ::CoInitialize(NULL);
378 + ExitOnFailure(hr, "Failed to initialize COM");
379 + fInitializedCom = TRUE;
380 +
381 + CpiInitialize();
382 +
383 + // check for the prerequsite tables
384 + if (!CpiTableExists(cptComPlusPartition) && !CpiTableExists(cptComPlusApplication) && !CpiTableExists(cptComPlusAssembly))
385 + {
386 + WcaLog(LOGMSG_VERBOSE, "skipping uninstall COM+ CustomAction, no ComPlusPartition, ComPlusApplication or ComPlusAssembly table present");
387 + ExitFunction1(hr = S_FALSE);
388 + }
389 +
390 + // make sure we can access the COM+ admin catalog
391 + do {
392 + hr = CpiGetAdminCatalog(&piCatalog);
393 + if (FAILED(hr))
394 + {
395 + WcaLog(LOGMSG_STANDARD, "Failed to get COM+ admin catalog");
396 + er = WcaErrorMessage(msierrComPlusCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
397 + switch (er)
398 + {
399 + case IDABORT:
400 + ExitFunction(); // exit with hr from CpiGetAdminCatalog() to kick off a rollback
401 + case IDRETRY:
402 + hr = S_FALSE;
403 + break;
404 + case IDIGNORE:
405 + default:
406 + ExitFunction1(hr = S_OK); // pretend everything is okay and bail
407 + }
408 + }
409 + } while (S_FALSE == hr);
410 +
411 + // get NT version
412 + hr = WcaGetIntProperty(L"VersionNT", &iVersionNT);
413 + ExitOnFailure(hr, "Failed to get VersionNT property");
414 +
415 + // read elements
416 + if (502 <= iVersionNT && CpiTableExists(cptComPlusPartition))
417 + {
418 + hr = CpiPartitionsRead(&partList);
419 + MessageExitOnFailure(hr, msierrComPlusPartitionReadFailed, "Failed to read ComPlusPartitions table");
420 + }
421 +
422 + if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionRole))
423 + {
424 + hr = CpiPartitionRolesRead(&partList, &partRoleList);
425 + MessageExitOnFailure(hr, msierrComPlusPartitionRoleReadFailed, "Failed to read ComPlusPartitionRole table");
426 + }
427 +
428 + if (502 <= iVersionNT && (CpiTableExists(cptComPlusUserInPartitionRole) || CpiTableExists(cptComPlusGroupInPartitionRole)))
429 + {
430 + hr = CpiUsersInPartitionRolesRead(&partRoleList, &usrInPartRoleList);
431 + MessageExitOnFailure(hr, msierrComPlusUserInPartitionRoleReadFailed, "Failed to read ComPlusUserInPartitionRole table");
432 + }
433 +
434 + if (502 <= iVersionNT && CpiTableExists(cptComPlusPartitionUser))
435 + {
436 + hr = CpiPartitionUsersRead(&partList, &partUsrList);
437 + MessageExitOnFailure(hr, msierrComPlusPartitionUserReadFailed, "Failed to read ComPlusPartitionUser table");
438 + }
439 +
440 + if (CpiTableExists(cptComPlusApplication))
441 + {
442 + hr = CpiApplicationsRead(&partList, &appList);
443 + MessageExitOnFailure(hr, msierrComPlusApplicationReadFailed, "Failed to read ComPlusApplication table");
444 + }
445 +
446 + if (CpiTableExists(cptComPlusApplicationRole))
447 + {
448 + hr = CpiApplicationRolesRead(&appList, &appRoleList);
449 + MessageExitOnFailure(hr, msierrComPlusApplicationRoleReadFailed, "Failed to read ComPlusApplicationRole table");
450 + }
451 +
452 + if (CpiTableExists(cptComPlusUserInApplicationRole) || CpiTableExists(cptComPlusGroupInApplicationRole))
453 + {
454 + hr = CpiUsersInApplicationRolesRead(&appRoleList, &usrInAppRoleList);
455 + MessageExitOnFailure(hr, msierrComPlusUserInApplicationRoleReadFailed, "Failed to read ComPlusUserInApplicationRole table");
456 + }
457 +
458 + if (CpiTableExists(cptComPlusAssembly))
459 + {
460 + hr = CpiAssembliesRead(&appList, &appRoleList, &asmList);
461 + MessageExitOnFailure(hr, msierrComPlusAssembliesReadFailed, "Failed to read ComPlusAssembly table");
462 + }
463 +
464 + if (CpiTableExists(cptComPlusSubscription))
465 + {
466 + hr = CpiSubscriptionsRead(&asmList, &subList);
467 + MessageExitOnFailure(hr, msierrComPlusSubscriptionReadFailed, "Failed to read ComPlusSubscription table");
468 + }
469 +
470 + // verify elements
471 + hr = CpiPartitionsVerifyUninstall(&partList);
472 + ExitOnFailure(hr, "Failed to verify partitions");
473 +
474 + hr = CpiApplicationsVerifyUninstall(&appList);
475 + ExitOnFailure(hr, "Failed to verify applications");
476 +
477 + hr = CpiApplicationRolesVerifyUninstall(&appRoleList);
478 + ExitOnFailure(hr, "Failed to verify application roles");
479 +
480 + hr = CpiAssembliesVerifyUninstall(&asmList);
481 + ExitOnFailure(hr, "Failed to verify assemblies");
482 +
483 + if (subList.iUninstallCount)
484 + {
485 + hr = CpiSubscriptionsVerifyUninstall(&subList);
486 + ExitOnFailure(hr, "Failed to verify subscriptions");
487 + }
488 +
489 + // schedule
490 + if (partList.iUninstallCount || appList.iUninstallCount || appRoleList.iUninstallCount ||
491 + usrInAppRoleList.iUninstallCount || asmList.iUninstallCount || asmList.iRoleUninstallCount || subList.iUninstallCount)
492 + {
493 + // create rollback file name
494 + hr = CpiGetTempFileName(&pwzRollbackFileName);
495 + ExitOnFailure(hr, "Failed to get rollback file name");
496 +
497 + // schedule rollback prepare custom action
498 + hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKINSTALLPREPARE, pwzRollbackFileName, 0);
499 + ExitOnFailure(hr, "Failed to schedule ComPlusRollbackInstallPrepare");
500 +
501 + // schedule prepare custom action
502 + hr = WcaDoDeferredAction(CP_COMPLUSINSTALLPREPARE, pwzRollbackFileName, 0);
503 + ExitOnFailure(hr, "Failed to schedule ComPlusInstallPrepare");
504 +
505 + // schedule rollback custom action
506 + hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzRollbackActionData);
507 + ExitOnFailure(hr, "Failed to add rollback file name to rollback custom action data");
508 +
509 + hr = CpiPartitionsUninstall(&partList, rmRollback, &pwzRollbackActionData, NULL);
510 + ExitOnFailure(hr, "Failed to uninstall partitions");
511 + hr = CpiUsersInPartitionRolesUninstall(&usrInPartRoleList, rmRollback, &pwzRollbackActionData, NULL);
512 + ExitOnFailure(hr, "Failed to uninstall users in partition roles");
513 + hr = CpiPartitionUsersUninstall(&partUsrList, rmRollback, &pwzRollbackActionData, NULL);
514 + ExitOnFailure(hr, "Failed to uninstall partition users");
515 + hr = CpiApplicationsUninstall(&appList, rmRollback, &pwzRollbackActionData, NULL);
516 + ExitOnFailure(hr, "Failed to uninstall applications");
517 + hr = CpiApplicationRolesUninstall(&appRoleList, rmRollback, &pwzRollbackActionData, NULL);
518 + ExitOnFailure(hr, "Failed to uninstall application roles");
519 + hr = CpiUsersInApplicationRolesUninstall(&usrInAppRoleList, rmRollback, &pwzRollbackActionData, NULL);
520 + ExitOnFailure(hr, "Failed to uninstall users in application roles");
521 + hr = CpiAssembliesUninstall(&asmList, rmRollback, &pwzRollbackActionData, NULL);
522 + ExitOnFailure(hr, "Failed to uninstall assemblies");
523 + hr = CpiRoleAssignmentsUninstall(&asmList, rmRollback, &pwzRollbackActionData, NULL);
524 + ExitOnFailure(hr, "Failed to uninstall assemblies");
525 + hr = CpiSubscriptionsUninstall(&subList, rmRollback, &pwzRollbackActionData, NULL);
526 + ExitOnFailure(hr, "Failed to uninstall subscriptions");
527 +
528 + hr = WcaDoDeferredAction(CP_COMPLUSROLLBACKUNINSTALLEXECUTE, pwzRollbackActionData, 0);
529 + ExitOnFailure(hr, "Failed to schedule ComPlusRollbackUninstallExecute");
530 +
531 + // schedule install custom action
532 + hr = WcaWriteStringToCaData(pwzRollbackFileName, &pwzActionData);
533 + ExitOnFailure(hr, "Failed to add rollback file name to custom action data");
534 +
535 + hr = CpiSubscriptionsUninstall(&subList, rmDeferred, &pwzActionData, &iProgress);
536 + ExitOnFailure(hr, "Failed to uninstall subscriptions");
537 + hr = CpiRoleAssignmentsUninstall(&asmList, rmDeferred, &pwzActionData, &iProgress);
538 + ExitOnFailure(hr, "Failed to uninstall assemblies");
539 + hr = CpiAssembliesUninstall(&asmList, rmDeferred, &pwzActionData, &iProgress);
540 + ExitOnFailure(hr, "Failed to uninstall assemblies");
541 + hr = CpiUsersInApplicationRolesUninstall(&usrInAppRoleList, rmDeferred, &pwzActionData, &iProgress);
542 + ExitOnFailure(hr, "Failed to uninstall users in application roles");
543 + hr = CpiApplicationRolesUninstall(&appRoleList, rmDeferred, &pwzActionData, &iProgress);
544 + ExitOnFailure(hr, "Failed to uninstall application roles");
545 + hr = CpiApplicationsUninstall(&appList, rmDeferred, &pwzActionData, &iProgress);
546 + ExitOnFailure(hr, "Failed to uninstall applications");
547 + hr = CpiPartitionUsersUninstall(&partUsrList, rmDeferred, &pwzActionData, &iProgress);
548 + ExitOnFailure(hr, "Failed to uninstall partition users");
549 + hr = CpiUsersInPartitionRolesUninstall(&usrInPartRoleList, rmDeferred, &pwzActionData, &iProgress);
550 + ExitOnFailure(hr, "Failed to uninstall users in partition roles");
551 + hr = CpiPartitionsUninstall(&partList, rmDeferred, &pwzActionData, &iProgress);
552 + ExitOnFailure(hr, "Failed to uninstall partitions");
553 +
554 + hr = WcaDoDeferredAction(CP_COMPLUSUNINSTALLEXECUTE, pwzActionData, iProgress);
555 + ExitOnFailure(hr, "Failed to schedule ComPlusUninstallExecute");
556 +
557 + // schedule commit custom action
558 + hr = WcaDoDeferredAction(CP_COMPLUSINSTALLCOMMIT, pwzRollbackFileName, 0);
559 + ExitOnFailure(hr, "Failed to schedule ComPlusInstallCommit");
560 + }
561 +
562 + hr = S_OK;
563 +
564 +LExit:
565 + // clean up
566 + ReleaseObject(piCatalog);
567 +
568 + ReleaseStr(pwzRollbackFileName);
569 + ReleaseStr(pwzActionData);
570 + ReleaseStr(pwzRollbackActionData);
571 +
572 + CpiPartitionListFree(&partList);
573 + CpiPartitionRoleListFree(&partRoleList);
574 + CpiUserInPartitionRoleListFree(&usrInPartRoleList);
575 + CpiPartitionUserListFree(&partUsrList);
576 + CpiApplicationListFree(&appList);
577 + CpiApplicationRoleListFree(&appRoleList);
578 + CpiUserInApplicationRoleListFree(&usrInAppRoleList);
579 + CpiAssemblyListFree(&asmList);
580 + CpiSubscriptionListFree(&subList);
581 +
582 + // unitialize
583 + CpiFinalize();
584 +
585 + if (fInitializedCom)
586 + ::CoUninitialize();
587 +
588 + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
589 + return WcaFinalize(er);
590 +}
src/ca/cpsubsexec.cpp new
+411
@@ -0,0 +1,411 @@
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 +
8 +struct CPI_SUBSCRIPTION_ATTRIBUTES
9 +{
10 + int iActionType;
11 + int iActionCost;
12 + LPWSTR pwzKey;
13 + LPWSTR pwzID;
14 + LPWSTR pwzName;
15 + LPWSTR pwzEventCLSID;
16 + LPWSTR pwzPublisherID;
17 + LPWSTR pwzCompCLSID;
18 + LPWSTR pwzAppID;
19 + LPWSTR pwzPartID;
20 + CPI_PROPERTY* pPropList;
21 +};
22 +
23 +
24 +// prototypes for private helper functions
25 +
26 +static HRESULT ReadSubscriptionAttributes(
27 + LPWSTR* ppwzData,
28 + CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
29 + );
30 +static void FreeSubscriptionAttributes(
31 + CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
32 + );
33 +static HRESULT CreateSubscription(
34 + CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
35 + );
36 +static HRESULT RemoveSubscription(
37 + CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
38 + );
39 +
40 +
41 +// function definitions
42 +
43 +HRESULT CpiConfigureSubscriptions(
44 + LPWSTR* ppwzData,
45 + HANDLE hRollbackFile
46 + )
47 +{
48 + HRESULT hr = S_OK;
49 +
50 + CPI_SUBSCRIPTION_ATTRIBUTES attrs;
51 + ::ZeroMemory(&attrs, sizeof(attrs));
52 +
53 + // read action text
54 + hr = CpiActionStartMessage(ppwzData, FALSE);
55 + ExitOnFailure(hr, "Failed to send action start message");
56 +
57 + // ger count
58 + int iCnt = 0;
59 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
60 + ExitOnFailure(hr, "Failed to read count");
61 +
62 + // write count to rollback file
63 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, iCnt);
64 + ExitOnFailure(hr, "Failed to write count to rollback file");
65 +
66 + for (int i = 0; i < iCnt; i++)
67 + {
68 + // read attributes from CustomActionData
69 + hr = ReadSubscriptionAttributes(ppwzData, &attrs);
70 + ExitOnFailure(hr, "Failed to read attributes");
71 +
72 + // progress message
73 + hr = CpiActionDataMessage(1, attrs.pwzName);
74 + ExitOnFailure(hr, "Failed to send progress messages");
75 +
76 + if (S_FALSE == hr)
77 + ExitFunction();
78 +
79 + // write key to rollback file
80 + hr = CpiWriteKeyToRollbackFile(hRollbackFile, attrs.pwzKey);
81 + ExitOnFailure(hr, "Failed to write key to rollback file");
82 +
83 + // action
84 + switch (attrs.iActionType)
85 + {
86 + case atCreate:
87 + hr = CreateSubscription(&attrs);
88 + ExitOnFailure(hr, "Failed to create subscription, key: %S", attrs.pwzKey);
89 + break;
90 + case atRemove:
91 + hr = RemoveSubscription(&attrs);
92 + ExitOnFailure(hr, "Failed to remove subscription, key: %S", attrs.pwzKey);
93 + break;
94 + }
95 +
96 + // write completion status to rollback file
97 + hr = CpiWriteIntegerToRollbackFile(hRollbackFile, 1);
98 + ExitOnFailure(hr, "Failed to write completion status to rollback file");
99 +
100 + // progress
101 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
102 + ExitOnFailure(hr, "Failed to update progress");
103 + }
104 +
105 + hr = S_OK;
106 +
107 +LExit:
108 + // clean up
109 + FreeSubscriptionAttributes(&attrs);
110 +
111 + return hr;
112 +}
113 +
114 +HRESULT CpiRollbackConfigureSubscriptions(
115 + LPWSTR* ppwzData,
116 + CPI_ROLLBACK_DATA* pRollbackDataList
117 + )
118 +{
119 + HRESULT hr = S_OK;
120 +
121 + int iRollbackStatus;
122 +
123 + CPI_SUBSCRIPTION_ATTRIBUTES attrs;
124 + ::ZeroMemory(&attrs, sizeof(attrs));
125 +
126 + // read action text
127 + hr = CpiActionStartMessage(ppwzData, NULL == pRollbackDataList);
128 + ExitOnFailure(hr, "Failed to send action start message");
129 +
130 + // ger count
131 + int iCnt = 0;
132 + hr = WcaReadIntegerFromCaData(ppwzData, &iCnt);
133 + ExitOnFailure(hr, "Failed to read count");
134 +
135 + for (int i = 0; i < iCnt; i++)
136 + {
137 + // read attributes from CustomActionData
138 + hr = ReadSubscriptionAttributes(ppwzData, &attrs);
139 + ExitOnFailure(hr, "Failed to read attributes");
140 +
141 + // rollback status
142 + hr = CpiFindRollbackStatus(pRollbackDataList, attrs.pwzKey, &iRollbackStatus);
143 +
144 + if (S_FALSE == hr)
145 + continue; // not found, nothing to rollback
146 +
147 + // progress message
148 + hr = CpiActionDataMessage(1, attrs.pwzName);
149 + ExitOnFailure(hr, "Failed to send progress messages");
150 +
151 + if (S_FALSE == hr)
152 + ExitFunction();
153 +
154 + // action
155 + switch (attrs.iActionType)
156 + {
157 + case atCreate:
158 + hr = CreateSubscription(&attrs);
159 + if (FAILED(hr))
160 + WcaLog(LOGMSG_STANDARD, "Failed to create subscription, hr: 0x%x, key: %S", hr, attrs.pwzKey);
161 + break;
162 + case atRemove:
163 + hr = RemoveSubscription(&attrs);
164 + if (FAILED(hr))
165 + WcaLog(LOGMSG_STANDARD, "Failed to remove subscription, hr: 0x%x, key: %S", hr, attrs.pwzKey);
166 + break;
167 + }
168 +
169 + // check rollback status
170 + if (0 == iRollbackStatus)
171 + continue; // operation did not complete, skip progress
172 +
173 + // progress
174 + hr = WcaProgressMessage(attrs.iActionCost, FALSE);
175 + ExitOnFailure(hr, "Failed to update progress");
176 + }
177 +
178 + hr = S_OK;
179 +
180 +LExit:
181 + // clean up
182 + FreeSubscriptionAttributes(&attrs);
183 +
184 + return hr;
185 +}
186 +
187 +
188 +// helper function definitions
189 +
190 +static HRESULT ReadSubscriptionAttributes(
191 + LPWSTR* ppwzData,
192 + CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
193 + )
194 +{
195 + HRESULT hr = S_OK;
196 +
197 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionType);
198 + ExitOnFailure(hr, "Failed to read action type");
199 + hr = WcaReadIntegerFromCaData(ppwzData, &pAttrs->iActionCost);
200 + ExitOnFailure(hr, "Failed to read action cost");
201 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzKey);
202 + ExitOnFailure(hr, "Failed to read key");
203 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzID);
204 + ExitOnFailure(hr, "Failed to read id");
205 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzName);
206 + ExitOnFailure(hr, "Failed to read name");
207 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzEventCLSID);
208 + ExitOnFailure(hr, "Failed to read event clsid");
209 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPublisherID);
210 + ExitOnFailure(hr, "Failed to read publisher id");
211 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzCompCLSID);
212 + ExitOnFailure(hr, "Failed to read component clsid");
213 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzAppID);
214 + ExitOnFailure(hr, "Failed to read application id");
215 + hr = WcaReadStringFromCaData(ppwzData, &pAttrs->pwzPartID);
216 + ExitOnFailure(hr, "Failed to read partition id");
217 +
218 + hr = CpiReadPropertyList(ppwzData, &pAttrs->pPropList);
219 + ExitOnFailure(hr, "Failed to read properties");
220 +
221 + hr = S_OK;
222 +
223 +LExit:
224 + return hr;
225 +}
226 +
227 +static void FreeSubscriptionAttributes(
228 + CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
229 + )
230 +{
231 + ReleaseStr(pAttrs->pwzKey);
232 + ReleaseStr(pAttrs->pwzID);
233 + ReleaseStr(pAttrs->pwzName);
234 + ReleaseStr(pAttrs->pwzEventCLSID);
235 + ReleaseStr(pAttrs->pwzPublisherID);
236 + ReleaseStr(pAttrs->pwzCompCLSID);
237 + ReleaseStr(pAttrs->pwzAppID);
238 + ReleaseStr(pAttrs->pwzPartID);
239 +
240 + if (pAttrs->pPropList)
241 + CpiFreePropertyList(pAttrs->pPropList);
242 +}
243 +
244 +static HRESULT CreateSubscription(
245 + CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
246 + )
247 +{
248 + HRESULT hr = S_OK;
249 + UINT er = ERROR_SUCCESS;
250 +
251 + ICatalogCollection* piSubsColl = NULL;
252 + ICatalogObject* piSubsObj = NULL;
253 +
254 + PSID pSid = NULL;
255 + long lChanges = 0;
256 +
257 + // log
258 + WcaLog(LOGMSG_VERBOSE, "Creating subscription, key: %S", pAttrs->pwzKey);
259 +
260 + // get subscriptions collection
261 + hr = CpiGetSubscriptionsCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzCompCLSID, &piSubsColl);
262 + if (S_FALSE == hr)
263 + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
264 + ExitOnFailure(hr, "Failed to get subscriptions collection");
265 +
266 + // check if subscription exists
267 + hr = CpiFindCollectionObjectByStringKey(piSubsColl, pAttrs->pwzID, &piSubsObj);
268 + ExitOnFailure(hr, "Failed to find subscription");
269 +
270 + if (S_FALSE == hr)
271 + {
272 + // create subscription
273 + hr = CpiAddCollectionObject(piSubsColl, &piSubsObj);
274 + ExitOnFailure(hr, "Failed to add subscription to collection");
275 +
276 + hr = CpiPutCollectionObjectValue(piSubsObj, L"ID", pAttrs->pwzID);
277 + ExitOnFailure(hr, "Failed to set subscription id property");
278 +
279 + hr = CpiPutCollectionObjectValue(piSubsObj, L"Name", pAttrs->pwzName);
280 + ExitOnFailure(hr, "Failed to set subscription name property");
281 +
282 + if (pAttrs->pwzEventCLSID && *pAttrs->pwzEventCLSID)
283 + {
284 + hr = CpiPutCollectionObjectValue(piSubsObj, L"EventCLSID", pAttrs->pwzEventCLSID);
285 + ExitOnFailure(hr, "Failed to set role event clsid property");
286 + }
287 +
288 + if (pAttrs->pwzPublisherID && *pAttrs->pwzPublisherID)
289 + {
290 + hr = CpiPutCollectionObjectValue(piSubsObj, L"PublisherID", pAttrs->pwzPublisherID);
291 + ExitOnFailure(hr, "Failed to set role publisher id property");
292 + }
293 + }
294 +
295 + // properties
296 + for (CPI_PROPERTY* pItm = pAttrs->pPropList; pItm; pItm = pItm->pNext)
297 + {
298 + // UserName property
299 + if (0 == lstrcmpW(pItm->wzName, L"UserName"))
300 + {
301 + // get SID for account
302 + do {
303 + er = ERROR_SUCCESS;
304 + hr = CpiAccountNameToSid(pItm->pwzValue, &pSid);
305 + if (!::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK))
306 + {
307 + if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr)
308 + {
309 + WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pItm->pwzValue);
310 + er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
311 + switch (er)
312 + {
313 + case IDABORT:
314 + ExitFunction(); // exit with error code from CpiAccountNameToSid()
315 + case IDRETRY:
316 + break;
317 + case IDIGNORE:
318 + default:
319 + hr = S_FALSE;
320 + }
321 + }
322 + else
323 + ExitOnFailure(hr, "Failed to get SID for account, account: '%S'", pItm->pwzValue);
324 + }
325 + else if (FAILED(hr))
326 + {
327 + WcaLog(LOGMSG_STANDARD, "Failed to get SID for account, hr: 0x%x, account: '%S'", hr, pItm->pwzValue);
328 + hr = S_FALSE;
329 + }
330 + } while (IDRETRY == er);
331 +
332 + if (S_FALSE == hr)
333 + continue;
334 +
335 + // convert SID back to account name
336 + hr = CpiSidToAccountName(pSid, &pItm->pwzValue);
337 + ExitOnFailure(hr, "Failed to convert SID to account name");
338 + }
339 +
340 + // set property
341 + hr = CpiPutCollectionObjectValue(piSubsObj, pItm->wzName, pItm->pwzValue);
342 + ExitOnFailure(hr, "Failed to set object property value, name: %S", pItm->wzName);
343 + }
344 +
345 + // save changes
346 + hr = piSubsColl->SaveChanges(&lChanges);
347 + if (COMADMIN_E_OBJECTERRORS == hr)
348 + CpiLogCatalogErrorInfo();
349 + ExitOnFailure(hr, "Failed to save changes");
350 +
351 + // log
352 + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
353 +
354 + hr = S_OK;
355 +
356 +LExit:
357 + // clean up
358 + ReleaseObject(piSubsColl);
359 + ReleaseObject(piSubsObj);
360 +
361 + if (pSid)
362 + ::HeapFree(::GetProcessHeap(), 0, pSid);
363 +
364 + return hr;
365 +}
366 +
367 +static HRESULT RemoveSubscription(
368 + CPI_SUBSCRIPTION_ATTRIBUTES* pAttrs
369 + )
370 +{
371 + HRESULT hr = S_OK;
372 +
373 + ICatalogCollection* piSubsColl = NULL;
374 +
375 + long lChanges = 0;
376 +
377 + // log
378 + WcaLog(LOGMSG_VERBOSE, "Removing subscription, key: %S", pAttrs->pwzKey);
379 +
380 + // get subscriptions collection
381 + hr = CpiGetSubscriptionsCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzCompCLSID, &piSubsColl);
382 + ExitOnFailure(hr, "Failed to get subscriptions collection");
383 +
384 + if (S_FALSE == hr)
385 + {
386 + // subscription not found
387 + WcaLog(LOGMSG_VERBOSE, "Unable to retrieve subscriptions collection, nothing to delete, key: %S", pAttrs->pwzKey);
388 + ExitFunction1(hr = S_OK);
389 + }
390 +
391 + // remove
392 + hr = CpiRemoveCollectionObject(piSubsColl, pAttrs->pwzID, NULL, FALSE);
393 + ExitOnFailure(hr, "Failed to remove subscriptions");
394 +
395 + // save changes
396 + hr = piSubsColl->SaveChanges(&lChanges);
397 + if (COMADMIN_E_OBJECTERRORS == hr)
398 + CpiLogCatalogErrorInfo();
399 + ExitOnFailure(hr, "Failed to save changes");
400 +
401 + // log
402 + WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey);
403 +
404 + hr = S_OK;
405 +
406 +LExit:
407 + // clean up
408 + ReleaseObject(piSubsColl);
409 +
410 + return hr;
411 +}
src/ca/cpsubsexec.h new
+12
@@ -0,0 +1,12 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +HRESULT CpiConfigureSubscriptions(
6 + LPWSTR* ppwzData,
7 + HANDLE hRollbackFile
8 + );
9 +HRESULT CpiRollbackConfigureSubscriptions(
10 + LPWSTR* ppwzData,
11 + CPI_ROLLBACK_DATA* pRollbackDataList
12 + );
src/ca/cpsubssched.cpp new
+606
@@ -0,0 +1,606 @@
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 vcsSubscriptionQuery =
9 + L"SELECT `Subscription`, `ComPlusComponent_`, `Component_`, `Id`, `Name`, `EventCLSID`, `PublisherID` FROM `ComPlusSubscription`";
10 +enum eSubscriptionQuery { sqSubscription = 1, sqComPlusComponent, sqComponent, sqID, sqName, sqEventCLSID, sqPublisherID };
11 +
12 +LPCWSTR vcsSubscriptionPropertyQuery =
13 + L"SELECT `Name`, `Value` FROM `ComPlusSubscriptionProperty` WHERE `Subscription_` = ?";
14 +
15 +
16 +// property definitions
17 +
18 +CPI_PROPERTY_DEFINITION pdlSubscriptionProperties[] =
19 +{
20 + {L"Description", cpptString, 500},
21 + {L"Enabled", cpptBoolean, 500},
22 + {L"EventClassPartitionID", cpptString, 502},
23 + {L"FilterCriteria", cpptString, 500},
24 + {L"InterfaceID", cpptString, 500},
25 + {L"MachineName", cpptString, 500},
26 + {L"MethodName", cpptString, 500},
27 + {L"PerUser", cpptBoolean, 500},
28 + {L"Queued", cpptBoolean, 500},
29 + {L"SubscriberMoniker", cpptString, 500},
30 + {L"UserName", cpptUser, 500},
31 + {NULL, cpptNone, 0}
32 +};
33 +
34 +
35 +// prototypes for private helper functions
36 +
37 +static void FreeSubscription(
38 + CPI_SUBSCRIPTION* pItm
39 + );
40 +static HRESULT FindObjectForSubscription(
41 + CPI_SUBSCRIPTION* pItm,
42 + BOOL fFindId,
43 + BOOL fFindName,
44 + ICatalogObject** ppiSubsObj
45 + );
46 +static HRESULT AddSubscriptionToActionData(
47 + CPI_SUBSCRIPTION* pItm,
48 + int iActionType,
49 + int iActionCost,
50 + LPWSTR* ppwzActionData
51 + );
52 +static HRESULT ComponentFindByKey(
53 + CPI_ASSEMBLY_LIST* pAsmList,
54 + LPCWSTR pwzKey,
55 + CPI_ASSEMBLY** ppAsmItm,
56 + CPI_COMPONENT** ppCompItm
57 + );
58 +
59 +
60 +// function definitions
61 +
62 +void CpiSubscriptionListFree(
63 + CPI_SUBSCRIPTION_LIST* pList
64 + )
65 +{
66 + CPI_SUBSCRIPTION* pItm = pList->pFirst;
67 +
68 + while (pItm)
69 + {
70 + CPI_SUBSCRIPTION* pDelete = pItm;
71 + pItm = pItm->pNext;
72 + FreeSubscription(pDelete);
73 + }
74 +}
75 +
76 +HRESULT CpiSubscriptionsRead(
77 + CPI_ASSEMBLY_LIST* pAsmList,
78 + CPI_SUBSCRIPTION_LIST* pSubList
79 + )
80 +{
81 + HRESULT hr = S_OK;
82 + UINT er = ERROR_SUCCESS;
83 +
84 + PMSIHANDLE hView, hRec;
85 +
86 + CPI_SUBSCRIPTION* pItm = NULL;
87 + LPWSTR pwzData = NULL;
88 + BOOL fMatchingArchitecture = FALSE;
89 +
90 + // loop through all applications
91 + hr = WcaOpenExecuteView(vcsSubscriptionQuery, &hView);
92 + ExitOnFailure(hr, "Failed to execute view on ComPlusSubscription table");
93 +
94 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
95 + {
96 + // get component
97 + hr = WcaGetRecordString(hRec, sqComponent, &pwzData);
98 + ExitOnFailure(hr, "Failed to get component");
99 +
100 + // check if the component is our processor architecture
101 + hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture);
102 + ExitOnFailure(hr, "Failed to get component architecture.");
103 +
104 + if (!fMatchingArchitecture)
105 + {
106 + continue; // not the same architecture, ignore
107 + }
108 +
109 + // create entry
110 + pItm = (CPI_SUBSCRIPTION*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_SUBSCRIPTION));
111 + if (!pItm)
112 + ExitFunction1(hr = E_OUTOFMEMORY);
113 +
114 + // get component install state
115 + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction);
116 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state");
117 +
118 + // get key
119 + hr = WcaGetRecordString(hRec, sqSubscription, &pwzData);
120 + ExitOnFailure(hr, "Failed to get key");
121 + StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData);
122 +
123 + // get com+ component
124 + hr = WcaGetRecordString(hRec, sqComPlusComponent, &pwzData);
125 + ExitOnFailure(hr, "Failed to get COM+ component");
126 +
127 + hr = ComponentFindByKey(pAsmList, pwzData, &pItm->pAssembly, &pItm->pComponent);
128 +
129 + if (S_FALSE == hr)
130 + {
131 + // component not found
132 + ExitOnFailure(hr = E_FAIL, "Failed to find component, key: %S", pwzData);
133 + }
134 +
135 + // get id
136 + hr = WcaGetRecordFormattedString(hRec, sqID, &pwzData);
137 + ExitOnFailure(hr, "Failed to get id");
138 +
139 + if (pwzData && *pwzData)
140 + {
141 + hr = PcaGuidToRegFormat(pwzData, pItm->wzID, countof(pItm->wzID));
142 + ExitOnFailure(hr, "Failed to parse id guid value, key: %S, value: '%S'", pItm->wzKey, pwzData);
143 + }
144 +
145 + // get name
146 + hr = WcaGetRecordFormattedString(hRec, sqName, &pwzData);
147 + ExitOnFailure(hr, "Failed to get name");
148 + StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
149 +
150 + // get event clsid
151 + hr = WcaGetRecordFormattedString(hRec, sqEventCLSID, &pwzData);
152 + ExitOnFailure(hr, "Failed to get event clsid");
153 + StringCchCopyW(pItm->wzEventCLSID, countof(pItm->wzEventCLSID), pwzData);
154 +
155 + // get publisher id
156 + hr = WcaGetRecordFormattedString(hRec, sqPublisherID, &pwzData);
157 + ExitOnFailure(hr, "Failed to get publisher id");
158 + StringCchCopyW(pItm->wzPublisherID, countof(pItm->wzPublisherID), pwzData);
159 +
160 + // get properties
161 + if (CpiTableExists(cptComPlusSubscriptionProperty))
162 + {
163 + hr = CpiPropertiesRead(vcsSubscriptionPropertyQuery, pItm->wzKey, pdlSubscriptionProperties, &pItm->pProperties, &pItm->iPropertyCount);
164 + ExitOnFailure(hr, "Failed to get subscription properties");
165 + }
166 +
167 + // set references & increment counters
168 + if (WcaIsInstalling(pItm->isInstalled, pItm->isAction))
169 + {
170 + CpiApplicationAddReferenceInstall(pItm->pAssembly->pApplication);
171 + pItm->pAssembly->fReferencedForInstall = TRUE;
172 + pSubList->iInstallCount++;
173 + if (pItm->pAssembly->iAttributes & aaRunInCommit)
174 + pSubList->iCommitCount++;
175 + }
176 + if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
177 + {
178 + CpiApplicationAddReferenceUninstall(pItm->pAssembly->pApplication);
179 + pItm->pAssembly->fReferencedForUninstall = TRUE;
180 + pSubList->iUninstallCount++;
181 + }
182 +
183 + // add entry
184 + if (pSubList->pFirst)
185 + pItm->pNext = pSubList->pFirst;
186 + pSubList->pFirst = pItm;
187 + pItm = NULL;
188 + }
189 +
190 + if (E_NOMOREITEMS == hr)
191 + hr = S_OK;
192 +
193 +LExit:
194 + // clean up
195 + if (pItm)
196 + FreeSubscription(pItm);
197 +
198 + ReleaseStr(pwzData);
199 +
200 + return hr;
201 +}
202 +
203 +HRESULT CpiSubscriptionsVerifyInstall(
204 + CPI_SUBSCRIPTION_LIST* pList
205 + )
206 +{
207 + HRESULT hr = S_OK;
208 + UINT er = ERROR_SUCCESS;
209 +
210 + ICatalogObject* piSubsObj = NULL;
211 +
212 + for (CPI_SUBSCRIPTION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
213 + {
214 + // subscriptions that are being installed
215 + if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction))
216 + continue;
217 +
218 + // subscription is supposed to exist
219 + if (CpiIsInstalled(pItm->isInstalled))
220 + {
221 + // if we don't have an id
222 + if (!*pItm->wzID)
223 + {
224 + // find subscriptions with conflicting name
225 + hr = FindObjectForSubscription(pItm, FALSE, TRUE, &piSubsObj);
226 + ExitOnFailure(hr, "Failed to find collection object for subscription");
227 +
228 + // if the subscription was found
229 + if (S_OK == hr)
230 + {
231 + // get id from subscription object
232 + hr = CpiGetKeyForObject(piSubsObj, pItm->wzID, countof(pItm->wzID));
233 + ExitOnFailure(hr, "Failed to get id");
234 + }
235 +
236 + // if the subscription was not found
237 + else
238 + {
239 + // create a new id
240 + hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
241 + ExitOnFailure(hr, "Failed to create id");
242 + }
243 + }
244 + }
245 +
246 + // subscription is supposed to be created
247 + else
248 + {
249 + // check for conflicts
250 + do {
251 + if (*pItm->wzID)
252 + {
253 + // find subscriptions with conflicting id
254 + hr = FindObjectForSubscription(pItm, TRUE, FALSE, &piSubsObj);
255 + ExitOnFailure(hr, "Failed to find collection object for subscription");
256 +
257 + if (S_FALSE == hr)
258 + {
259 + // find subscriptions with conflicting name
260 + hr = FindObjectForSubscription(pItm, FALSE, TRUE, &piSubsObj);
261 + ExitOnFailure(hr, "Failed to find collection object for subscription");
262 +
263 + if (S_OK == hr)
264 + // "A subscription with a conflictiong name exists. retry cancel"
265 + er = WcaErrorMessage(msierrComPlusSubscriptionNameConflict, hr, INSTALLMESSAGE_ERROR | MB_RETRYCANCEL, 0);
266 + else
267 + break; // no conflicting entry found, break loop
268 + }
269 + else
270 + // "A subscription with a conflicting id exists. abort retry ignore"
271 + er = WcaErrorMessage(msierrComPlusSubscriptionIdConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
272 + }
273 + else
274 + {
275 + // find subscriptions with conflicting name
276 + hr = FindObjectForSubscription(pItm, FALSE, TRUE, &piSubsObj);
277 + ExitOnFailure(hr, "Failed to find collection object for subscription");
278 +
279 + if (S_OK == hr)
280 + // "A subscription with a conflictiong name exists. abort retry ignore"
281 + er = WcaErrorMessage(msierrComPlusSubscriptionNameConflict, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
282 + else
283 + break; // no conflicting entry found, break loop
284 + }
285 +
286 + switch (er)
287 + {
288 + case IDCANCEL:
289 + case IDABORT:
290 + ExitOnFailure(hr = E_FAIL, "A subscription with a conflictiong name or id exists, key: %S", pItm->wzKey);
291 + break;
292 + case IDRETRY:
293 + break;
294 + case IDIGNORE:
295 + default:
296 + // if we don't have an id, copy id from object
297 + if (!*pItm->wzID)
298 + {
299 + hr = CpiGetKeyForObject(piSubsObj, pItm->wzID, countof(pItm->wzID));
300 + ExitOnFailure(hr, "Failed to get id");
301 + }
302 + hr = S_FALSE; // indicate that this is not a conflict
303 + }
304 + } while (S_OK == hr); // hr = S_FALSE if we don't have any conflicts
305 +
306 + // create a new id if one is missing
307 + if (!*pItm->wzID)
308 + {
309 + hr = CpiCreateId(pItm->wzID, countof(pItm->wzID));
310 + ExitOnFailure(hr, "Failed to create id");
311 + }
312 + }
313 +
314 + // clean up
315 + ReleaseNullObject(piSubsObj);
316 + }
317 +
318 + hr = S_OK;
319 +
320 +LExit:
321 + // clean up
322 + ReleaseObject(piSubsObj);
323 +
324 + return hr;
325 +}
326 +
327 +HRESULT CpiSubscriptionsVerifyUninstall(
328 + CPI_SUBSCRIPTION_LIST* pList
329 + )
330 +{
331 + HRESULT hr = S_OK;
332 + ICatalogObject* piSubsObj = NULL;
333 +
334 + for (CPI_SUBSCRIPTION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
335 + {
336 + // subscriptions that are being installed
337 + if (!WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
338 + continue;
339 +
340 + // find subscriptions with conflicting name
341 + hr = FindObjectForSubscription(pItm, 0 != *pItm->wzID, 0 == *pItm->wzID, &piSubsObj);
342 + ExitOnFailure(hr, "Failed to find collection object for subscription");
343 +
344 + // if the subscription was found
345 + if (S_OK == hr)
346 + {
347 + // if we don't have an id, copy id from object
348 + if (!*pItm->wzID)
349 + {
350 + hr = CpiGetKeyForObject(piSubsObj, pItm->wzID, countof(pItm->wzID));
351 + ExitOnFailure(hr, "Failed to get id");
352 + }
353 + }
354 +
355 + // if the subscription was not found
356 + else
357 + {
358 + pItm->fObjectNotFound = TRUE;
359 + pList->iUninstallCount--; // elements with the fObjectNotFound flag set will not be scheduled for uninstall
360 + }
361 +
362 + // clean up
363 + ReleaseNullObject(piSubsObj);
364 + }
365 +
366 + hr = S_OK;
367 +
368 +LExit:
369 + // clean up
370 + ReleaseObject(piSubsObj);
371 +
372 + return hr;
373 +}
374 +
375 +HRESULT CpiSubscriptionsInstall(
376 + CPI_SUBSCRIPTION_LIST* pList,
377 + int iRunMode,
378 + LPWSTR* ppwzActionData,
379 + int* piProgress
380 + )
381 +{
382 + HRESULT hr = S_OK;
383 +
384 + int iActionType;
385 + int iCount = 0;
386 +
387 + // add action text
388 + hr = CpiAddActionTextToActionData(L"CreateSubscrComPlusComponents", ppwzActionData);
389 + ExitOnFailure(hr, "Failed to add action text to custom action data");
390 +
391 + // subscription count
392 + switch (iRunMode)
393 + {
394 + case rmDeferred:
395 + iCount = pList->iInstallCount - pList->iCommitCount;
396 + break;
397 + case rmCommit:
398 + iCount = pList->iCommitCount;
399 + break;
400 + case rmRollback:
401 + iCount = pList->iInstallCount;
402 + break;
403 + }
404 +
405 + // add subscription count to action data
406 + hr = WcaWriteIntegerToCaData(iCount, ppwzActionData);
407 + ExitOnFailure(hr, "Failed to add count to custom action data");
408 +
409 + // add assemblies to custom action data in forward order
410 + for (CPI_SUBSCRIPTION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
411 + {
412 + // roles that are being installed only
413 + if ((rmCommit == iRunMode && !(pItm->pAssembly->iAttributes & aaRunInCommit)) ||
414 + (rmDeferred == iRunMode && (pItm->pAssembly->iAttributes & aaRunInCommit)) ||
415 + !WcaIsInstalling(pItm->isInstalled, pItm->isAction))
416 + continue;
417 +
418 + // action type
419 + if (rmRollback == iRunMode)
420 + {
421 + if (CpiIsInstalled(pItm->isInstalled))
422 + iActionType = atNoOp;
423 + else
424 + iActionType = atRemove;
425 + }
426 + else
427 + iActionType = atCreate;
428 +
429 + // add to action data
430 + hr = AddSubscriptionToActionData(pItm, iActionType, COST_SUBSCRIPTION_CREATE, ppwzActionData);
431 + ExitOnFailure(hr, "Failed to add subscription to custom action data, key: %S", pItm->wzKey);
432 + }
433 +
434 + // add progress tics
435 + if (piProgress)
436 + *piProgress += COST_SUBSCRIPTION_CREATE * pList->iInstallCount;
437 +
438 + hr = S_OK;
439 +
440 +LExit:
441 + return hr;
442 +}
443 +
444 +HRESULT CpiSubscriptionsUninstall(
445 + CPI_SUBSCRIPTION_LIST* pList,
446 + int iRunMode,
447 + LPWSTR* ppwzActionData,
448 + int* piProgress
449 + )
450 +{
451 + HRESULT hr = S_OK;
452 +
453 + int iActionType;
454 +
455 + // add action text
456 + hr = CpiAddActionTextToActionData(L"RemoveSubscrComPlusComponents", ppwzActionData);
457 + ExitOnFailure(hr, "Failed to add action text to custom action data");
458 +
459 + // add subscription count to action data
460 + hr = WcaWriteIntegerToCaData(pList->iUninstallCount, ppwzActionData);
461 + ExitOnFailure(hr, "Failed to add count to custom action data");
462 +
463 + // add assemblies to custom action data in reverse order
464 + for (CPI_SUBSCRIPTION* pItm = pList->pFirst; pItm; pItm = pItm->pNext)
465 + {
466 + // roles that are being uninstalled only
467 + if (pItm->fObjectNotFound || !WcaIsUninstalling(pItm->isInstalled, pItm->isAction))
468 + continue;
469 +
470 + // action type
471 + if (rmRollback == iRunMode)
472 + iActionType = atCreate;
473 + else
474 + iActionType = atRemove;
475 +
476 + // add to action data
477 + hr = AddSubscriptionToActionData(pItm, iActionType, COST_SUBSCRIPTION_DELETE, ppwzActionData);
478 + ExitOnFailure(hr, "Failed to add subscription to custom action data, key: %S", pItm->wzKey);
479 + }
480 +
481 + // add progress tics
482 + if (piProgress)
483 + *piProgress += COST_SUBSCRIPTION_DELETE * pList->iUninstallCount;
484 +
485 + hr = S_OK;
486 +
487 +LExit:
488 + return hr;
489 +}
490 +
491 +
492 +// helper function definitions
493 +
494 +static void FreeSubscription(
495 + CPI_SUBSCRIPTION* pItm
496 + )
497 +{
498 + if (pItm->pProperties)
499 + CpiPropertiesFreeList(pItm->pProperties);
500 +
501 + ::HeapFree(::GetProcessHeap(), 0, pItm);
502 +}
503 +
504 +static HRESULT FindObjectForSubscription(
505 + CPI_SUBSCRIPTION* pItm,
506 + BOOL fFindId,
507 + BOOL fFindName,
508 + ICatalogObject** ppiSubsObj
509 + )
510 +{
511 + HRESULT hr = S_OK;
512 +
513 + ICatalogCollection* piSubsColl = NULL;
514 +
515 + // get applications collection
516 + hr = CpiGetSubscriptionsCollForComponent(pItm->pAssembly, pItm->pComponent, &piSubsColl);
517 + ExitOnFailure(hr, "Failed to get collection");
518 +
519 + if (S_FALSE == hr)
520 + ExitFunction(); // exit with hr = S_FALSE
521 +
522 + // find application object
523 + hr = CpiFindCollectionObject(piSubsColl, fFindId ? pItm->wzID : NULL, fFindName ? pItm->wzName : NULL, ppiSubsObj);
524 + ExitOnFailure(hr, "Failed to find object");
525 +
526 + // exit with hr from CpiFindCollectionObject()
527 +
528 +LExit:
529 + // clean up
530 + ReleaseObject(piSubsColl);
531 +
532 + return hr;
533 +}
534 +
535 +static HRESULT AddSubscriptionToActionData(
536 + CPI_SUBSCRIPTION* pItm,
537 + int iActionType,
538 + int iActionCost,
539 + LPWSTR* ppwzActionData
540 + )
541 +{
542 + HRESULT hr = S_OK;
543 +
544 + // add action information to custom action data
545 + hr = WcaWriteIntegerToCaData(iActionType, ppwzActionData);
546 + ExitOnFailure(hr, "Failed to add action type to custom action data");
547 + hr = WcaWriteIntegerToCaData(iActionCost, ppwzActionData);
548 + ExitOnFailure(hr, "Failed to add action cost to custom action data");
549 +
550 + // add application role information to custom action data
551 + hr = WcaWriteStringToCaData(pItm->wzKey, ppwzActionData);
552 + ExitOnFailure(hr, "Failed to add subscription key to custom action data");
553 + hr = WcaWriteStringToCaData(pItm->wzID, ppwzActionData);
554 + ExitOnFailure(hr, "Failed to add subscription id to custom action data");
555 + hr = WcaWriteStringToCaData(pItm->wzName, ppwzActionData);
556 + ExitOnFailure(hr, "Failed to add subscription name to custom action data");
557 + hr = WcaWriteStringToCaData(atCreate == iActionType ? pItm->wzEventCLSID : L"", ppwzActionData);
558 + ExitOnFailure(hr, "Failed to add assembly tlb path to custom action data");
559 + hr = WcaWriteStringToCaData(atCreate == iActionType ? pItm->wzPublisherID : L"", ppwzActionData);
560 + ExitOnFailure(hr, "Failed to add assembly proxy-stub dll path to custom action data");
561 +
562 + // add component information to custom action data
563 + hr = WcaWriteStringToCaData(pItm->pComponent->wzCLSID, ppwzActionData);
564 + ExitOnFailure(hr, "Failed to add application id to custom action data");
565 +
566 + // add application information to custom action data
567 + hr = WcaWriteStringToCaData(pItm->pAssembly->pApplication->wzID, ppwzActionData);
568 + ExitOnFailure(hr, "Failed to add application id to custom action data");
569 +
570 + // add partition information to custom action data
571 + LPCWSTR pwzPartID = pItm->pAssembly->pApplication->pPartition ? pItm->pAssembly->pApplication->pPartition->wzID : L"";
572 + hr = WcaWriteStringToCaData(pwzPartID, ppwzActionData);
573 + ExitOnFailure(hr, "Failed to add partition id to custom action data");
574 +
575 + // add properties to custom action data
576 + hr = CpiAddPropertiesToActionData(atCreate == iActionType ? pItm->iPropertyCount : 0, pItm->pProperties, ppwzActionData);
577 + ExitOnFailure(hr, "Failed to add properties to custom action data");
578 +
579 + hr = S_OK;
580 +
581 +LExit:
582 + return hr;
583 +}
584 +
585 +static HRESULT ComponentFindByKey(
586 + CPI_ASSEMBLY_LIST* pAsmList,
587 + LPCWSTR pwzKey,
588 + CPI_ASSEMBLY** ppAsmItm,
589 + CPI_COMPONENT** ppCompItm
590 + )
591 +{
592 + for (CPI_ASSEMBLY* pAsmItm = pAsmList->pFirst; pAsmItm; pAsmItm = pAsmItm->pNext)
593 + {
594 + for (CPI_COMPONENT* pCompItm = pAsmItm->pComponents; pCompItm; pCompItm = pCompItm->pNext)
595 + {
596 + if (0 == lstrcmpW(pCompItm->wzKey, pwzKey))
597 + {
598 + *ppAsmItm = pAsmItm;
599 + *ppCompItm = pCompItm;
600 + return S_OK;
601 + }
602 + }
603 + }
604 +
605 + return S_FALSE;
606 +}
src/ca/cpsubssched.h new
+62
@@ -0,0 +1,62 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +struct CPI_SUBSCRIPTION
6 +{
7 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
8 + WCHAR wzID[CPI_MAX_GUID + 1];
9 + WCHAR wzName[MAX_DARWIN_COLUMN + 1];
10 + WCHAR wzEventCLSID[CPI_MAX_GUID + 1];
11 + WCHAR wzPublisherID[CPI_MAX_GUID + 1];
12 +
13 + BOOL fObjectNotFound;
14 +
15 + int iPropertyCount;
16 + CPI_PROPERTY* pProperties;
17 +
18 + INSTALLSTATE isInstalled, isAction;
19 +
20 + CPI_ASSEMBLY* pAssembly;
21 + CPI_COMPONENT* pComponent;
22 +
23 + CPI_SUBSCRIPTION* pNext;
24 +};
25 +
26 +struct CPI_SUBSCRIPTION_LIST
27 +{
28 + CPI_SUBSCRIPTION* pFirst;
29 +
30 + int iInstallCount;
31 + int iCommitCount;
32 + int iUninstallCount;
33 +};
34 +
35 +
36 +// function prototypes
37 +
38 +void CpiSubscriptionListFree(
39 + CPI_SUBSCRIPTION_LIST* pList
40 + );
41 +HRESULT CpiSubscriptionsRead(
42 + CPI_ASSEMBLY_LIST* pAsmList,
43 + CPI_SUBSCRIPTION_LIST* pSubList
44 + );
45 +HRESULT CpiSubscriptionsVerifyInstall(
46 + CPI_SUBSCRIPTION_LIST* pList
47 + );
48 +HRESULT CpiSubscriptionsVerifyUninstall(
49 + CPI_SUBSCRIPTION_LIST* pList
50 + );
51 +HRESULT CpiSubscriptionsInstall(
52 + CPI_SUBSCRIPTION_LIST* pList,
53 + int iRunMode,
54 + LPWSTR* ppwzActionData,
55 + int* piProgress
56 + );
57 +HRESULT CpiSubscriptionsUninstall(
58 + CPI_SUBSCRIPTION_LIST* pList,
59 + int iRunMode,
60 + LPWSTR* ppwzActionData,
61 + int* piProgress
62 + );
src/ca/cputilexec.cpp new
+1881
@@ -0,0 +1,1881 @@
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 +
8 +struct CPI_WELLKNOWN_SID
9 +{
10 + LPCWSTR pwzName;
11 + SID_IDENTIFIER_AUTHORITY iaIdentifierAuthority;
12 + BYTE nSubAuthorityCount;
13 + DWORD dwSubAuthority[8];
14 +};
15 +
16 +
17 +// well known SIDs
18 +
19 +CPI_WELLKNOWN_SID wsWellKnownSids[] = {
20 + {L"\\Everyone", SECURITY_WORLD_SID_AUTHORITY, 1, {SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0}},
21 + {L"\\Administrators", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0}},
22 + {L"\\LocalSystem", SECURITY_NT_AUTHORITY, 1, {SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0}},
23 + {L"\\LocalService", SECURITY_NT_AUTHORITY, 1, {SECURITY_LOCAL_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0}},
24 + {L"\\NetworkService", SECURITY_NT_AUTHORITY, 1, {SECURITY_NETWORK_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0}},
25 + {L"\\AuthenticatedUser", SECURITY_NT_AUTHORITY, 1, {SECURITY_AUTHENTICATED_USER_RID, 0, 0, 0, 0, 0, 0, 0}},
26 + {L"\\Guests", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS, 0, 0, 0, 0, 0, 0}},
27 + {L"\\Users", SECURITY_NT_AUTHORITY, 2, {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0}},
28 + {L"\\CREATOR OWNER", SECURITY_NT_AUTHORITY, 1, {SECURITY_CREATOR_OWNER_RID, 0, 0, 0, 0, 0, 0, 0}},
29 + {NULL, SECURITY_NULL_SID_AUTHORITY, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
30 +};
31 +
32 +
33 +// prototypes for private helper functions
34 +
35 +static HRESULT FindUserCollectionObjectIndex(
36 + ICatalogCollection* piColl,
37 + PSID pSid,
38 + int* pi
39 + );
40 +static HRESULT CreateSidFromDomainRidPair(
41 + PSID pDomainSid,
42 + DWORD dwRid,
43 + PSID* ppSid
44 + );
45 +static HRESULT InitLsaUnicodeString(
46 + PLSA_UNICODE_STRING plusStr,
47 + LPCWSTR pwzStr,
48 + DWORD dwLen
49 + );
50 +static void FreeLsaUnicodeString(
51 + PLSA_UNICODE_STRING plusStr
52 + );
53 +static HRESULT WriteFileAll(
54 + HANDLE hFile,
55 + PBYTE pbBuffer,
56 + DWORD dwBufferLength
57 + );
58 +static HRESULT ReadFileAll(
59 + HANDLE hFile,
60 + PBYTE pbBuffer,
61 + DWORD dwBufferLength
62 + );
63 +
64 +
65 +// variables
66 +
67 +static ICOMAdminCatalog* gpiCatalog;
68 +
69 +
70 +// function definitions
71 +
72 +void CpiInitialize()
73 +{
74 + // collections
75 + gpiCatalog = NULL;
76 +}
77 +
78 +void CpiFinalize()
79 +{
80 + // collections
81 + ReleaseObject(gpiCatalog);
82 +}
83 +
84 +HRESULT CpiActionStartMessage(
85 + LPWSTR* ppwzActionData,
86 + BOOL fSuppress
87 + )
88 +{
89 + HRESULT hr = S_OK;
90 + UINT er = ERROR_SUCCESS;
91 +
92 + PMSIHANDLE hRec;
93 +
94 + LPWSTR pwzData = NULL;
95 +
96 + // create record
97 + hRec = ::MsiCreateRecord(3);
98 + ExitOnNull(hRec, hr, E_OUTOFMEMORY, "Failed to create record");
99 +
100 + // action name
101 + hr = WcaReadStringFromCaData(ppwzActionData, &pwzData);
102 + ExitOnFailure(hr, "Failed to action name");
103 +
104 + er = ::MsiRecordSetStringW(hRec, 1, pwzData);
105 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set action name");
106 +
107 + // description
108 + hr = WcaReadStringFromCaData(ppwzActionData, &pwzData);
109 + ExitOnFailure(hr, "Failed to description");
110 +
111 + er = ::MsiRecordSetStringW(hRec, 2, pwzData);
112 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set description");
113 +
114 + // template
115 + hr = WcaReadStringFromCaData(ppwzActionData, &pwzData);
116 + ExitOnFailure(hr, "Failed to template");
117 +
118 + er = ::MsiRecordSetStringW(hRec, 3, pwzData);
119 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set template");
120 +
121 + // message
122 + if (!fSuppress)
123 + {
124 + er = WcaProcessMessage(INSTALLMESSAGE_ACTIONSTART, hRec);
125 + if (0 == er || IDOK == er || IDYES == er)
126 + {
127 + hr = S_OK;
128 + }
129 + else if (IDABORT == er || IDCANCEL == er)
130 + {
131 + WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit
132 + hr = S_FALSE;
133 + }
134 + else
135 + hr = E_UNEXPECTED;
136 + }
137 +
138 +LExit:
139 + // clean up
140 + ReleaseStr(pwzData);
141 +
142 + return hr;
143 +}
144 +
145 +HRESULT CpiActionDataMessage(
146 + DWORD cArgs,
147 + ...
148 + )
149 +{
150 + HRESULT hr = S_OK;
151 + UINT er = ERROR_SUCCESS;
152 +
153 + PMSIHANDLE hRec;
154 + va_list args;
155 +
156 + // record
157 + hRec = ::MsiCreateRecord(cArgs);
158 + ExitOnNull(hRec, hr, E_OUTOFMEMORY, "Failed to create record");
159 +
160 + va_start(args, cArgs);
161 + for (DWORD i = 1; i <= cArgs; i++)
162 + {
163 + LPCWSTR pwzArg = va_arg(args, WCHAR*);
164 + if (pwzArg && *pwzArg)
165 + {
166 + er = ::MsiRecordSetStringW(hRec, i, pwzArg);
167 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set record field string");
168 + }
169 + }
170 + va_end(args);
171 +
172 + // message
173 + er = WcaProcessMessage(INSTALLMESSAGE_ACTIONDATA, hRec);
174 + if (0 == er || IDOK == er || IDYES == er)
175 + {
176 + hr = S_OK;
177 + }
178 + else if (IDABORT == er || IDCANCEL == er)
179 + {
180 + WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit
181 + hr = S_FALSE;
182 + }
183 + else
184 + hr = E_UNEXPECTED;
185 +
186 +LExit:
187 + return hr;
188 +}
189 +
190 +HRESULT CpiGetAdminCatalog(
191 + ICOMAdminCatalog** ppiCatalog
192 + )
193 +{
194 + HRESULT hr = S_OK;
195 +
196 + if (!gpiCatalog)
197 + {
198 + // get collection
199 + hr = ::CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_ALL, IID_ICOMAdminCatalog, (void**)&gpiCatalog);
200 + ExitOnFailure(hr, "Failed to create COM+ admin catalog object");
201 + }
202 +
203 + // return value
204 + gpiCatalog->AddRef();
205 + *ppiCatalog = gpiCatalog;
206 +
207 + hr = S_OK;
208 +
209 +LExit:
210 + return hr;
211 +}
212 +
213 +HRESULT CpiLogCatalogErrorInfo()
214 +{
215 + HRESULT hr = S_OK;
216 +
217 + ICOMAdminCatalog* piCatalog = NULL;
218 + ICatalogCollection* piErrColl = NULL;
219 + IDispatch* piDisp = NULL;
220 + ICatalogObject* piObj = NULL;
221 +
222 + LPWSTR pwzName = NULL;
223 + LPWSTR pwzErrorCode = NULL;
224 + LPWSTR pwzMajorRef = NULL;
225 + LPWSTR pwzMinorRef = NULL;
226 +
227 + // get catalog
228 + hr = CpiGetAdminCatalog(&piCatalog);
229 + ExitOnFailure(hr, "Failed to get COM+ admin catalog");
230 +
231 + // get error info collection
232 + hr = CpiGetCatalogCollection(L"ErrorInfo", &piErrColl);
233 + ExitOnFailure(hr, "Failed to get error info collection");
234 +
235 + // loop objects
236 + long lCnt;
237 + hr = piErrColl->get_Count(&lCnt);
238 + ExitOnFailure(hr, "Failed to get to number of items in collection");
239 +
240 + for (long i = 0; i < lCnt; i++)
241 + {
242 + // get ICatalogObject interface
243 + hr = piErrColl->get_Item(i, &piDisp);
244 + ExitOnFailure(hr, "Failed to get item from partitions collection");
245 +
246 + hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
247 + ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
248 +
249 + // get properties
250 + hr = CpiGetCollectionObjectValue(piObj, L"Name", &pwzName);
251 + ExitOnFailure(hr, "Failed to get name");
252 + hr = CpiGetCollectionObjectValue(piObj, L"ErrorCode", &pwzErrorCode);
253 + ExitOnFailure(hr, "Failed to get error code");
254 + hr = CpiGetCollectionObjectValue(piObj, L"MajorRef", &pwzMajorRef);
255 + ExitOnFailure(hr, "Failed to get major ref");
256 + hr = CpiGetCollectionObjectValue(piObj, L"MinorRef", &pwzMinorRef);
257 + ExitOnFailure(hr, "Failed to get minor ref");
258 +
259 + // write to log
260 + WcaLog(LOGMSG_STANDARD, "ErrorInfo: Name='%S', ErrorCode='%S', MajorRef='%S', MinorRef='%S'",
261 + pwzName, pwzErrorCode, pwzMajorRef, pwzMinorRef);
262 +
263 + // clean up
264 + ReleaseNullObject(piDisp);
265 + ReleaseNullObject(piObj);
266 + }
267 +
268 + hr = S_OK;
269 +
270 +LExit:
271 + // clean up
272 + ReleaseObject(piCatalog);
273 + ReleaseObject(piErrColl);
274 + ReleaseObject(piDisp);
275 + ReleaseObject(piObj);
276 +
277 + ReleaseStr(pwzName);
278 + ReleaseStr(pwzErrorCode);
279 + ReleaseStr(pwzMajorRef);
280 + ReleaseStr(pwzMinorRef);
281 +
282 + return hr;
283 +}
284 +
285 +HRESULT CpiGetCatalogCollection(
286 + LPCWSTR pwzName,
287 + ICatalogCollection** ppiColl
288 + )
289 +{
290 + HRESULT hr = S_OK;
291 +
292 + ICOMAdminCatalog* piCatalog = NULL;
293 + IDispatch* piDisp = NULL;
294 +
295 + BSTR bstrName = NULL;
296 +
297 + // copy name string
298 + bstrName = ::SysAllocString(pwzName);
299 + ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for collection name");
300 +
301 + // get catalog
302 + hr = CpiGetAdminCatalog(&piCatalog);
303 + ExitOnFailure(hr, "Failed to get COM+ admin catalog");
304 +
305 + // get collecton from catalog
306 + hr = piCatalog->GetCollection(bstrName, &piDisp);
307 + ExitOnFailure(hr, "Failed to get collection");
308 +
309 + hr = piDisp->QueryInterface(IID_ICatalogCollection, (void**)ppiColl);
310 + ExitOnFailure(hr, "Failed to get IID_ICatalogCollection interface");
311 +
312 + // populate collection
313 + hr = (*ppiColl)->Populate();
314 + if (COMADMIN_E_OBJECTERRORS == hr)
315 + CpiLogCatalogErrorInfo();
316 + ExitOnFailure(hr, "Failed to populate collection");
317 +
318 + hr = S_OK;
319 +
320 +LExit:
321 + // clean up
322 + ReleaseObject(piCatalog);
323 + ReleaseObject(piDisp);
324 + ReleaseBSTR(bstrName);
325 +
326 + return hr;
327 +}
328 +
329 +HRESULT CpiGetCatalogCollection(
330 + ICatalogCollection* piColl,
331 + ICatalogObject* piObj,
332 + LPCWSTR pwzName,
333 + ICatalogCollection** ppiColl
334 + )
335 +{
336 + HRESULT hr = S_OK;
337 +
338 + ICOMAdminCatalog* piCatalog = NULL;
339 + IDispatch* piDisp = NULL;
340 +
341 + BSTR bstrName = NULL;
342 +
343 + VARIANT vtKey;
344 + ::VariantInit(&vtKey);
345 +
346 + // copy name string
347 + bstrName = ::SysAllocString(pwzName);
348 + ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for collection name");
349 +
350 + // get catalog
351 + hr = CpiGetAdminCatalog(&piCatalog);
352 + ExitOnFailure(hr, "Failed to get COM+ admin catalog");
353 +
354 + // get key
355 + hr = piObj->get_Key(&vtKey);
356 + ExitOnFailure(hr, "Failed to get object key");
357 +
358 + // get collecton from catalog
359 + hr = piColl->GetCollection(bstrName, vtKey, &piDisp);
360 + ExitOnFailure(hr, "Failed to get collection");
361 +
362 + hr = piDisp->QueryInterface(IID_ICatalogCollection, (void**)ppiColl);
363 + ExitOnFailure(hr, "Failed to get IID_ICatalogCollection interface");
364 +
365 + // populate collection
366 + hr = (*ppiColl)->Populate();
367 + if (COMADMIN_E_OBJECTERRORS == hr)
368 + CpiLogCatalogErrorInfo();
369 + ExitOnFailure(hr, "Failed to populate collection");
370 +
371 + hr = S_OK;
372 +
373 +LExit:
374 + // clean up
375 + ReleaseObject(piCatalog);
376 + ReleaseObject(piDisp);
377 + ReleaseBSTR(bstrName);
378 + ::VariantClear(&vtKey);
379 +
380 + return hr;
381 +}
382 +
383 +HRESULT CpiAddCollectionObject(
384 + ICatalogCollection* piColl,
385 + ICatalogObject** ppiObj
386 + )
387 +{
388 + HRESULT hr = S_OK;
389 +
390 + IDispatch* piDisp = NULL;
391 +
392 + hr = piColl->Add(&piDisp);
393 + ExitOnFailure(hr, "Failed to add object to collection");
394 +
395 + hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)ppiObj);
396 + ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
397 +
398 + hr = S_OK;
399 +
400 +LExit:
401 + // clean up
402 + ReleaseObject(piDisp);
403 +
404 + return hr;
405 +}
406 +
407 +HRESULT CpiPutCollectionObjectValue(
408 + ICatalogObject* piObj,
409 + LPCWSTR pwzPropName,
410 + LPCWSTR pwzValue
411 + )
412 +{
413 + HRESULT hr = S_OK;
414 +
415 + BSTR bstrPropName = NULL;
416 +
417 + VARIANT vtVal;
418 + ::VariantInit(&vtVal);
419 +
420 + // allocate property name string
421 + bstrPropName = ::SysAllocString(pwzPropName);
422 + ExitOnNull(bstrPropName, hr, E_OUTOFMEMORY, "Failed to allocate property name string");
423 +
424 + // prepare value variant
425 + vtVal.vt = VT_BSTR;
426 + vtVal.bstrVal = ::SysAllocString(pwzValue);
427 + ExitOnNull(vtVal.bstrVal, hr, E_OUTOFMEMORY, "Failed to allocate property value string");
428 +
429 + // put value
430 + hr = piObj->put_Value(bstrPropName, vtVal);
431 + ExitOnFailure(hr, "Failed to put property value");
432 +
433 + hr = S_OK;
434 +
435 +LExit:
436 + // clean up
437 + ReleaseBSTR(bstrPropName);
438 + ::VariantClear(&vtVal);
439 +
440 + return hr;
441 +}
442 +
443 +HRESULT CpiPutCollectionObjectValues(
444 + ICatalogObject* piObj,
445 + CPI_PROPERTY* pPropList
446 + )
447 +{
448 + HRESULT hr = S_OK;
449 +
450 + for (CPI_PROPERTY* pItm = pPropList; pItm; pItm = pItm->pNext)
451 + {
452 + // set property
453 + hr = CpiPutCollectionObjectValue(piObj, pItm->wzName, pItm->pwzValue);
454 + ExitOnFailure(hr, "Failed to set object property value, name: %S", pItm->wzName);
455 + }
456 +
457 + hr = S_OK;
458 +
459 +LExit:
460 + return hr;
461 +}
462 +
463 +HRESULT CpiGetCollectionObjectValue(
464 + ICatalogObject* piObj,
465 + LPCWSTR szPropName,
466 + LPWSTR* ppwzValue
467 + )
468 +{
469 + HRESULT hr = S_OK;
470 +
471 + BSTR bstrPropName = NULL;
472 +
473 + VARIANT vtVal;
474 + ::VariantInit(&vtVal);
475 +
476 + // allocate property name string
477 + bstrPropName = ::SysAllocString(szPropName);
478 + ExitOnNull(bstrPropName, hr, E_OUTOFMEMORY, "Failed to allocate property name string");
479 +
480 + // get value
481 + hr = piObj->get_Value(bstrPropName, &vtVal);
482 + ExitOnFailure(hr, "Failed to get property value");
483 +
484 + hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
485 + ExitOnFailure(hr, "Failed to change variant type");
486 +
487 + hr = StrAllocString(ppwzValue, vtVal.bstrVal, ::SysStringLen(vtVal.bstrVal));
488 + ExitOnFailure(hr, "Failed to allocate memory for value string");
489 +
490 + hr = S_OK;
491 +
492 +LExit:
493 + // clean up
494 + ReleaseBSTR(bstrPropName);
495 + ::VariantClear(&vtVal);
496 +
497 + return hr;
498 +}
499 +
500 +HRESULT CpiResetObjectProperty(
501 + ICatalogCollection* piColl,
502 + ICatalogObject* piObj,
503 + LPCWSTR pwzPropName
504 + )
505 +{
506 + HRESULT hr = S_OK;
507 +
508 + BSTR bstrPropName = NULL;
509 +
510 + long lChanges = 0;
511 +
512 + VARIANT vtVal;
513 + ::VariantInit(&vtVal);
514 +
515 + // allocate property name string
516 + bstrPropName = ::SysAllocString(pwzPropName);
517 + ExitOnNull(bstrPropName, hr, E_OUTOFMEMORY, "Failed to allocate deleteable property name string");
518 +
519 + // get value
520 + hr = piObj->get_Value(bstrPropName, &vtVal);
521 + ExitOnFailure(hr, "Failed to get deleteable property value");
522 +
523 + hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BOOL);
524 + ExitOnFailure(hr, "Failed to change variant type");
525 +
526 + // if the deleteable property is set
527 + if (VARIANT_FALSE == vtVal.boolVal)
528 + {
529 + // clear property
530 + vtVal.boolVal = VARIANT_TRUE;
531 +
532 + hr = piObj->put_Value(bstrPropName, vtVal);
533 + ExitOnFailure(hr, "Failed to get property value");
534 +
535 + // save changes
536 + hr = piColl->SaveChanges(&lChanges);
537 + if (COMADMIN_E_OBJECTERRORS == hr)
538 + CpiLogCatalogErrorInfo();
539 + ExitOnFailure(hr, "Failed to save changes");
540 + }
541 +
542 + hr = S_OK;
543 +
544 +LExit:
545 + // clean up
546 + ReleaseBSTR(bstrPropName);
547 + ::VariantClear(&vtVal);
548 +
549 + return hr;
550 +}
551 +
552 +HRESULT CpiRemoveCollectionObject(
553 + ICatalogCollection* piColl,
554 + LPCWSTR pwzID,
555 + LPCWSTR pwzName,
556 + BOOL fResetDeleteable
557 + )
558 +{
559 + HRESULT hr = S_OK;
560 +
561 + IDispatch* piDisp = NULL;
562 + ICatalogObject* piObj = NULL;
563 +
564 + BOOL fMatch = FALSE;
565 +
566 + VARIANT vtVal;
567 + ::VariantInit(&vtVal);
568 +
569 + long lCnt;
570 + hr = piColl->get_Count(&lCnt);
571 + ExitOnFailure(hr, "Failed to get to number of items in collection");
572 +
573 + for (long i = 0; i < lCnt; i++)
574 + {
575 + // get ICatalogObject interface
576 + hr = piColl->get_Item(i, &piDisp);
577 + ExitOnFailure(hr, "Failed to get object from collection");
578 +
579 + hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
580 + ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
581 +
582 + // compare id
583 + if (pwzID && *pwzID)
584 + {
585 + hr = piObj->get_Key(&vtVal);
586 + ExitOnFailure(hr, "Failed to get key");
587 +
588 + hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
589 + ExitOnFailure(hr, "Failed to change variant type");
590 +
591 + if (0 == lstrcmpiW(vtVal.bstrVal, pwzID))
592 + fMatch = TRUE;
593 +
594 + ::VariantClear(&vtVal);
595 + }
596 +
597 + // compare name
598 + if (pwzName && *pwzName)
599 + {
600 + hr = piObj->get_Name(&vtVal);
601 + ExitOnFailure(hr, "Failed to get name");
602 +
603 + hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
604 + ExitOnFailure(hr, "Failed to change variant type");
605 +
606 + if (0 == lstrcmpW(vtVal.bstrVal, pwzName))
607 + fMatch = TRUE;
608 +
609 + ::VariantClear(&vtVal);
610 + }
611 +
612 + // if it's a match, remove it
613 + if (fMatch)
614 + {
615 + if (fResetDeleteable)
616 + {
617 + // reset deleteable property, if set
618 + hr = CpiResetObjectProperty(piColl, piObj, L"Deleteable");
619 + ExitOnFailure(hr, "Failed to reset deleteable property");
620 + }
621 +
622 + hr = piColl->Remove(i);
623 + ExitOnFailure(hr, "Failed to remove item from collection");
624 + break;
625 + }
626 +
627 + // release interface pointers
628 + ReleaseNullObject(piDisp);
629 + ReleaseNullObject(piObj);
630 + }
631 +
632 + hr = S_OK;
633 +
634 +LExit:
635 + // clean up
636 + ReleaseObject(piDisp);
637 + ReleaseObject(piObj);
638 +
639 + ::VariantClear(&vtVal);
640 +
641 + return hr;
642 +}
643 +
644 +HRESULT CpiRemoveUserCollectionObject(
645 + ICatalogCollection* piColl,
646 + PSID pSid
647 + )
648 +{
649 + HRESULT hr = S_OK;
650 +
651 + int i = 0;
652 +
653 + // find index
654 + hr = FindUserCollectionObjectIndex(piColl, pSid, &i);
655 + ExitOnFailure(hr, "Failed to find user collection index");
656 +
657 + if (S_FALSE == hr)
658 + ExitFunction(); // not found, exit with hr = S_FALSE
659 +
660 + // remove object
661 + hr = piColl->Remove(i);
662 + ExitOnFailure(hr, "Failed to remove object from collection");
663 +
664 + hr = S_OK;
665 +
666 +LExit:
667 + return hr;
668 +}
669 +
670 +HRESULT CpiFindCollectionObjectByStringKey(
671 + ICatalogCollection* piColl,
672 + LPCWSTR pwzKey,
673 + ICatalogObject** ppiObj
674 + )
675 +{
676 + HRESULT hr = S_OK;
677 +
678 + IDispatch* piDisp = NULL;
679 + ICatalogObject* piObj = NULL;
680 +
681 + VARIANT vtVal;
682 + ::VariantInit(&vtVal);
683 +
684 + long lCnt;
685 + hr = piColl->get_Count(&lCnt);
686 + ExitOnFailure(hr, "Failed to get to number of items in collection");
687 +
688 + for (long i = 0; i < lCnt; i++)
689 + {
690 + // get ICatalogObject interface
691 + hr = piColl->get_Item(i, &piDisp);
692 + ExitOnFailure(hr, "Failed to get object from collection");
693 +
694 + hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
695 + ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
696 +
697 + // compare key
698 + hr = piObj->get_Key(&vtVal);
699 + ExitOnFailure(hr, "Failed to get key");
700 +
701 + hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
702 + ExitOnFailure(hr, "Failed to change variant type");
703 +
704 + if (0 == lstrcmpiW(vtVal.bstrVal, pwzKey))
705 + {
706 + if (ppiObj)
707 + {
708 + *ppiObj = piObj;
709 + piObj = NULL;
710 + }
711 + ExitFunction1(hr = S_OK);
712 + }
713 +
714 + // clean up
715 + ReleaseNullObject(piDisp);
716 + ReleaseNullObject(piObj);
717 +
718 + ::VariantClear(&vtVal);
719 + }
720 +
721 + hr = S_FALSE;
722 +
723 +LExit:
724 + // clean up
725 + ReleaseObject(piDisp);
726 + ReleaseObject(piObj);
727 +
728 + ::VariantClear(&vtVal);
729 +
730 + return hr;
731 +}
732 +
733 +HRESULT CpiFindCollectionObjectByIntegerKey(
734 + ICatalogCollection* piColl,
735 + long lKey,
736 + ICatalogObject** ppiObj
737 + )
738 +{
739 + HRESULT hr = S_OK;
740 +
741 + IDispatch* piDisp = NULL;
742 + ICatalogObject* piObj = NULL;
743 +
744 + VARIANT vtVal;
745 + ::VariantInit(&vtVal);
746 +
747 + long lCnt;
748 + hr = piColl->get_Count(&lCnt);
749 + ExitOnFailure(hr, "Failed to get to number of items in collection");
750 +
751 + for (long i = 0; i < lCnt; i++)
752 + {
753 + // get ICatalogObject interface
754 + hr = piColl->get_Item(i, &piDisp);
755 + ExitOnFailure(hr, "Failed to get object from collection");
756 +
757 + hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
758 + ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
759 +
760 + // compare key
761 + hr = piObj->get_Key(&vtVal);
762 + ExitOnFailure(hr, "Failed to get key");
763 +
764 + hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_I4);
765 + ExitOnFailure(hr, "Failed to change variant type");
766 +
767 + if (vtVal.lVal == lKey)
768 + {
769 + if (ppiObj)
770 + {
771 + *ppiObj = piObj;
772 + piObj = NULL;
773 + }
774 + ExitFunction1(hr = S_OK);
775 + }
776 +
777 + // clean up
778 + ReleaseNullObject(piDisp);
779 + ReleaseNullObject(piObj);
780 +
781 + ::VariantClear(&vtVal);
782 + }
783 +
784 + hr = S_FALSE;
785 +
786 +LExit:
787 + // clean up
788 + ReleaseObject(piDisp);
789 + ReleaseObject(piObj);
790 +
791 + ::VariantClear(&vtVal);
792 +
793 + return hr;
794 +}
795 +
796 +HRESULT CpiFindCollectionObjectByName(
797 + ICatalogCollection* piColl,
798 + LPCWSTR pwzName,
799 + ICatalogObject** ppiObj
800 + )
801 +{
802 + HRESULT hr = S_OK;
803 +
804 + IDispatch* piDisp = NULL;
805 + ICatalogObject* piObj = NULL;
806 +
807 + VARIANT vtVal;
808 + ::VariantInit(&vtVal);
809 +
810 + long lCnt;
811 + hr = piColl->get_Count(&lCnt);
812 + ExitOnFailure(hr, "Failed to get to number of items in collection");
813 +
814 + for (long i = 0; i < lCnt; i++)
815 + {
816 + // get ICatalogObject interface
817 + hr = piColl->get_Item(i, &piDisp);
818 + ExitOnFailure(hr, "Failed to get object from collection");
819 +
820 + hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
821 + ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
822 +
823 + // compare key
824 + hr = piObj->get_Name(&vtVal);
825 + ExitOnFailure(hr, "Failed to get key");
826 +
827 + hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
828 + ExitOnFailure(hr, "Failed to change variant type");
829 +
830 + if (0 == lstrcmpW(vtVal.bstrVal, pwzName))
831 + {
832 + if (ppiObj)
833 + {
834 + *ppiObj = piObj;
835 + piObj = NULL;
836 + }
837 + ExitFunction1(hr = S_OK);
838 + }
839 +
840 + // clean up
841 + ReleaseNullObject(piDisp);
842 + ReleaseNullObject(piObj);
843 +
844 + ::VariantClear(&vtVal);
845 + }
846 +
847 + hr = S_FALSE;
848 +
849 +LExit:
850 + // clean up
851 + ReleaseObject(piDisp);
852 + ReleaseObject(piObj);
853 +
854 + ::VariantClear(&vtVal);
855 +
856 + return hr;
857 +}
858 +
859 +HRESULT CpiFindUserCollectionObject(
860 + ICatalogCollection* piColl,
861 + PSID pSid,
862 + ICatalogObject** ppiObj
863 + )
864 +{
865 + HRESULT hr = S_OK;
866 +
867 + int i = 0;
868 +
869 + IDispatch* piDisp = NULL;
870 +
871 + // find index
872 + hr = FindUserCollectionObjectIndex(piColl, pSid, &i);
873 + ExitOnFailure(hr, "Failed to find user collection index");
874 +
875 + if (S_FALSE == hr)
876 + ExitFunction(); // not found, exit with hr = S_FALSE
877 +
878 + // get object
879 + if (ppiObj)
880 + {
881 + hr = piColl->get_Item(i, &piDisp);
882 + ExitOnFailure(hr, "Failed to get object from collection");
883 +
884 + hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)ppiObj);
885 + ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
886 + }
887 +
888 + hr = S_OK;
889 +
890 +LExit:
891 + // clean up
892 + ReleaseObject(piDisp);
893 +
894 + return hr;
895 +}
896 +
897 +HRESULT CpiGetPartitionsCollection(
898 + ICatalogCollection** ppiPartColl
899 + )
900 +{
901 + HRESULT hr = S_OK;
902 +
903 + // get collection
904 + hr = CpiGetCatalogCollection(L"Partitions", ppiPartColl);
905 + ExitOnFailure(hr, "Failed to get catalog collection");
906 +
907 + hr = S_OK;
908 +
909 +LExit:
910 + return hr;
911 +}
912 +
913 +HRESULT CpiGetPartitionRolesCollection(
914 + LPCWSTR pwzPartID,
915 + ICatalogCollection** ppiRolesColl
916 + )
917 +{
918 + HRESULT hr = S_OK;
919 +
920 + ICatalogCollection* piPartColl = NULL;
921 + ICatalogObject* piPartObj = NULL;
922 +
923 + // get partitions collection
924 + hr = CpiGetPartitionsCollection(&piPartColl);
925 + ExitOnFailure(hr, "Failed to get partitions collection");
926 +
927 + if (S_FALSE == hr)
928 + ExitFunction(); // partitions collection not found, exit with hr = S_FALSE
929 +
930 + // find object
931 + hr = CpiFindCollectionObjectByStringKey(piPartColl, pwzPartID, &piPartObj);
932 + ExitOnFailure(hr, "Failed to find collection object");
933 +
934 + if (S_FALSE == hr)
935 + ExitFunction(); // partition not found, exit with hr = S_FALSE
936 +
937 + // get roles collection
938 + hr = CpiGetCatalogCollection(piPartColl, piPartObj, L"RolesForPartition", ppiRolesColl);
939 + ExitOnFailure(hr, "Failed to get catalog collection");
940 +
941 + hr = S_OK;
942 +
943 +LExit:
944 + // clean up
945 + ReleaseObject(piPartColl);
946 + ReleaseObject(piPartObj);
947 +
948 + return hr;
949 +}
950 +
951 +HRESULT CpiGetUsersInPartitionRoleCollection(
952 + LPCWSTR pwzPartID,
953 + LPCWSTR pwzRoleName,
954 + ICatalogCollection** ppiUsrInRoleColl
955 + )
956 +{
957 + HRESULT hr = S_OK;
958 +
959 + ICatalogCollection* piRoleColl = NULL;
960 + ICatalogObject* piRoleObj = NULL;
961 +
962 + // get roles collection
963 + hr = CpiGetPartitionRolesCollection(pwzPartID, &piRoleColl);
964 + ExitOnFailure(hr, "Failed to get roles collection");
965 +
966 + if (S_FALSE == hr)
967 + ExitFunction(); // partition roles collection not found, exit with hr = S_FALSE
968 +
969 + // find object
970 + hr = CpiFindCollectionObjectByName(piRoleColl, pwzRoleName, &piRoleObj);
971 + ExitOnFailure(hr, "Failed to find collection object");
972 +
973 + if (S_FALSE == hr)
974 + ExitFunction(); // user not found, exit with hr = S_FALSE
975 +
976 + // get roles collection
977 + hr = CpiGetCatalogCollection(piRoleColl, piRoleObj, L"UsersInPartitionRole", ppiUsrInRoleColl);
978 + ExitOnFailure(hr, "Failed to get catalog collection");
979 +
980 + hr = S_OK;
981 +
982 +LExit:
983 + // clean up
984 + ReleaseObject(piRoleColl);
985 + ReleaseObject(piRoleObj);
986 +
987 + return hr;
988 +}
989 +
990 +HRESULT CpiGetPartitionUsersCollection(
991 + ICatalogCollection** ppiUserColl
992 + )
993 +{
994 + HRESULT hr = S_OK;
995 +
996 + // get roles collection
997 + hr = CpiGetCatalogCollection(L"PartitionUsers", ppiUserColl);
998 + ExitOnFailure(hr, "Failed to get catalog collection");
999 +
1000 + hr = S_OK;
1001 +
1002 +LExit:
1003 + return hr;
1004 +}
1005 +
1006 +HRESULT CpiGetApplicationsCollection(
1007 + LPCWSTR pwzPartID,
1008 + ICatalogCollection** ppiAppColl
1009 + )
1010 +{
1011 + HRESULT hr = S_OK;
1012 +
1013 + ICOMAdminCatalog* piCatalog = NULL;
1014 + ICOMAdminCatalog2* piCatalog2 = NULL;
1015 + BSTR bstrGlobPartID = NULL;
1016 +
1017 + ICatalogCollection* piPartColl = NULL;
1018 + ICatalogObject* piPartObj = NULL;
1019 +
1020 + // get catalog
1021 + hr = CpiGetAdminCatalog(&piCatalog);
1022 + ExitOnFailure(hr, "Failed to get COM+ admin catalog");
1023 +
1024 + // get ICOMAdminCatalog2 interface
1025 + hr = piCatalog->QueryInterface(IID_ICOMAdminCatalog2, (void**)&piCatalog2);
1026 +
1027 + // COM+ 1.5 or later
1028 + if (E_NOINTERFACE != hr)
1029 + {
1030 + ExitOnFailure(hr, "Failed to get IID_ICOMAdminCatalog2 interface");
1031 +
1032 + // partition id
1033 + if (!pwzPartID || !*pwzPartID)
1034 + {
1035 + // get global partition id
1036 + hr = piCatalog2->get_GlobalPartitionID(&bstrGlobPartID);
1037 + ExitOnFailure(hr, "Failed to get global partition id");
1038 + }
1039 +
1040 + // get partitions collection
1041 + hr = CpiGetPartitionsCollection(&piPartColl);
1042 + ExitOnFailure(hr, "Failed to get partitions collection");
1043 +
1044 + // find object
1045 + hr = CpiFindCollectionObjectByStringKey(piPartColl, bstrGlobPartID ? bstrGlobPartID : pwzPartID, &piPartObj);
1046 + ExitOnFailure(hr, "Failed to find collection object");
1047 +
1048 + if (S_FALSE == hr)
1049 + ExitFunction(); // partition not found, exit with hr = S_FALSE
1050 +
1051 + // get applications collection
1052 + hr = CpiGetCatalogCollection(piPartColl, piPartObj, L"Applications", ppiAppColl);
1053 + ExitOnFailure(hr, "Failed to get catalog collection for partition");
1054 + }
1055 +
1056 + // COM+ pre 1.5
1057 + else
1058 + {
1059 + // this version of COM+ does not support partitions, make sure a partition was not specified
1060 + if (pwzPartID && *pwzPartID)
1061 + ExitOnFailure(hr = E_FAIL, "Partitions are not supported by this version of COM+");
1062 +
1063 + // get applications collection
1064 + hr = CpiGetCatalogCollection(L"Applications", ppiAppColl);
1065 + ExitOnFailure(hr, "Failed to get catalog collection");
1066 + }
1067 +
1068 + hr = S_OK;
1069 +
1070 +LExit:
1071 + // clean up
1072 + ReleaseObject(piCatalog);
1073 + ReleaseObject(piCatalog2);
1074 + ReleaseBSTR(bstrGlobPartID);
1075 +
1076 + ReleaseObject(piPartColl);
1077 + ReleaseObject(piPartObj);
1078 +
1079 + return hr;
1080 +}
1081 +
1082 +HRESULT CpiGetRolesCollection(
1083 + LPCWSTR pwzPartID,
1084 + LPCWSTR pwzAppID,
1085 + ICatalogCollection** ppiRolesColl
1086 + )
1087 +{
1088 + HRESULT hr = S_OK;
1089 +
1090 + ICatalogCollection* piAppColl = NULL;
1091 + ICatalogObject* piAppObj = NULL;
1092 +
1093 + // get applications collection
1094 + hr = CpiGetApplicationsCollection(pwzPartID, &piAppColl);
1095 + ExitOnFailure(hr, "Failed to get applications collection");
1096 +
1097 + if (S_FALSE == hr)
1098 + ExitFunction(); // applications collection not found, exit with hr = S_FALSE
1099 +
1100 + // find object
1101 + hr = CpiFindCollectionObjectByStringKey(piAppColl, pwzAppID, &piAppObj);
1102 + ExitOnFailure(hr, "Failed to find collection object");
1103 +
1104 + if (S_FALSE == hr)
1105 + ExitFunction(); // application not found, exit with hr = S_FALSE
1106 +
1107 + // get roles collection
1108 + hr = CpiGetCatalogCollection(piAppColl, piAppObj, L"Roles", ppiRolesColl);
1109 + ExitOnFailure(hr, "Failed to catalog collection");
1110 +
1111 + hr = S_OK;
1112 +
1113 +LExit:
1114 + // clean up
1115 + ReleaseObject(piAppColl);
1116 + ReleaseObject(piAppObj);
1117 +
1118 + return hr;
1119 +}
1120 +
1121 +HRESULT CpiGetUsersInRoleCollection(
1122 + LPCWSTR pwzPartID,
1123 + LPCWSTR pwzAppID,
1124 + LPCWSTR pwzRoleName,
1125 + ICatalogCollection** ppiUsrInRoleColl
1126 + )
1127 +{
1128 + HRESULT hr = S_OK;
1129 +
1130 + ICatalogCollection* piRoleColl = NULL;
1131 + ICatalogObject* piRoleObj = NULL;
1132 +
1133 + // get roles collection
1134 + hr = CpiGetRolesCollection(pwzPartID, pwzAppID, &piRoleColl);
1135 + ExitOnFailure(hr, "Failed to get roles collection");
1136 +
1137 + if (S_FALSE == hr)
1138 + ExitFunction(); // roles collection not found, exit with hr = S_FALSE
1139 +
1140 + // find object
1141 + hr = CpiFindCollectionObjectByName(piRoleColl, pwzRoleName, &piRoleObj);
1142 + ExitOnFailure(hr, "Failed to find collection object");
1143 +
1144 + if (S_FALSE == hr)
1145 + ExitFunction(); // role not found, exit with hr = S_FALSE
1146 +
1147 + // get roles collection
1148 + hr = CpiGetCatalogCollection(piRoleColl, piRoleObj, L"UsersInRole", ppiUsrInRoleColl);
1149 + ExitOnFailure(hr, "Failed to get catalog collection");
1150 +
1151 + hr = S_OK;
1152 +
1153 +LExit:
1154 + // clean up
1155 + ReleaseObject(piRoleColl);
1156 + ReleaseObject(piRoleObj);
1157 +
1158 + return hr;
1159 +}
1160 +
1161 +HRESULT CpiGetComponentsCollection(
1162 + LPCWSTR pwzPartID,
1163 + LPCWSTR pwzAppID,
1164 + ICatalogCollection** ppiCompsColl
1165 + )
1166 +{
1167 + HRESULT hr = S_OK;
1168 +
1169 + ICatalogCollection* piAppColl = NULL;
1170 + ICatalogObject* piAppObj = NULL;
1171 +
1172 + // get applications collection
1173 + hr = CpiGetApplicationsCollection(pwzPartID, &piAppColl);
1174 + ExitOnFailure(hr, "Failed to get applications collection");
1175 +
1176 + if (S_FALSE == hr)
1177 + ExitFunction(); // applications collection not found, exit with hr = S_FALSE
1178 +
1179 + // find object
1180 + hr = CpiFindCollectionObjectByStringKey(piAppColl, pwzAppID, &piAppObj);
1181 + ExitOnFailure(hr, "Failed to find collection object");
1182 +
1183 + if (S_FALSE == hr)
1184 + ExitFunction(); // application not found, exit with hr = S_FALSE
1185 +
1186 + // get components collection
1187 + hr = CpiGetCatalogCollection(piAppColl, piAppObj, L"Components", ppiCompsColl);
1188 + ExitOnFailure(hr, "Failed to get catalog collection");
1189 +
1190 + hr = S_OK;
1191 +
1192 +LExit:
1193 + // clean up
1194 + ReleaseObject(piAppColl);
1195 + ReleaseObject(piAppObj);
1196 +
1197 + return hr;
1198 +}
1199 +
1200 +HRESULT CpiGetInterfacesCollection(
1201 + ICatalogCollection* piCompColl,
1202 + ICatalogObject* piCompObj,
1203 + ICatalogCollection** ppiIntfColl
1204 + )
1205 +{
1206 + HRESULT hr = S_OK;
1207 +
1208 + // get interfaces collection
1209 + hr = CpiGetCatalogCollection(piCompColl, piCompObj, L"InterfacesForComponent", ppiIntfColl);
1210 + ExitOnFailure(hr, "Failed to get catalog collection");
1211 +
1212 + hr = S_OK;
1213 +
1214 +LExit:
1215 + return hr;
1216 +}
1217 +
1218 +HRESULT CpiGetMethodsCollection(
1219 + ICatalogCollection* piIntfColl,
1220 + ICatalogObject* piIntfObj,
1221 + ICatalogCollection** ppiMethColl
1222 + )
1223 +{
1224 + HRESULT hr = S_OK;
1225 +
1226 + // get interfaces collection
1227 + hr = CpiGetCatalogCollection(piIntfColl, piIntfObj, L"MethodsForInterface", ppiMethColl);
1228 + ExitOnFailure(hr, "Failed to get catalog collection");
1229 +
1230 + hr = S_OK;
1231 +
1232 +LExit:
1233 + return hr;
1234 +}
1235 +
1236 +HRESULT CpiGetSubscriptionsCollection(
1237 + LPCWSTR pwzPartID,
1238 + LPCWSTR pwzAppID,
1239 + LPCWSTR pwzCompCLSID,
1240 + ICatalogCollection** ppiSubsColl
1241 + )
1242 +{
1243 + HRESULT hr = S_OK;
1244 +
1245 + ICatalogCollection* piCompColl = NULL;
1246 + ICatalogObject* piCompObj = NULL;
1247 +
1248 + // get components collection
1249 + hr = CpiGetComponentsCollection(pwzPartID, pwzAppID, &piCompColl);
1250 + ExitOnFailure(hr, "Failed to get components collection");
1251 +
1252 + if (S_FALSE == hr)
1253 + ExitFunction(); // components collection not found, exit with hr = S_FALSE
1254 +
1255 + // find object
1256 + hr = CpiFindCollectionObjectByStringKey(piCompColl, pwzCompCLSID, &piCompObj);
1257 + ExitOnFailure(hr, "Failed to find collection object");
1258 +
1259 + if (S_FALSE == hr)
1260 + ExitFunction(); // component not found, exit with hr = S_FALSE
1261 +
1262 + // get subscriptions collection
1263 + hr = CpiGetCatalogCollection(piCompColl, piCompObj, L"SubscriptionsForComponent", ppiSubsColl);
1264 + ExitOnFailure(hr, "Failed to get catalog collection");
1265 +
1266 + hr = S_OK;
1267 +
1268 +LExit:
1269 + // clean up
1270 + ReleaseObject(piCompColl);
1271 + ReleaseObject(piCompObj);
1272 +
1273 + return hr;
1274 +}
1275 +
1276 +HRESULT CpiReadPropertyList(
1277 + LPWSTR* ppwzData,
1278 + CPI_PROPERTY** ppPropList
1279 + )
1280 +{
1281 + HRESULT hr = S_OK;
1282 +
1283 + CPI_PROPERTY* pItm = NULL;
1284 + LPWSTR pwzName = NULL;
1285 +
1286 + // clear list if it already contains items
1287 + if (*ppPropList)
1288 + CpiFreePropertyList(*ppPropList);
1289 + *ppPropList = NULL;
1290 +
1291 + // read property count
1292 + int iPropCnt = 0;
1293 + hr = WcaReadIntegerFromCaData(ppwzData, &iPropCnt);
1294 + ExitOnFailure(hr, "Failed to read property count");
1295 +
1296 + for (int i = 0; i < iPropCnt; i++)
1297 + {
1298 + // allocate new element
1299 + pItm = (CPI_PROPERTY*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PROPERTY));
1300 + if (!pItm)
1301 + ExitFunction1(hr = E_OUTOFMEMORY);
1302 +
1303 + // Name
1304 + hr = WcaReadStringFromCaData(ppwzData, &pwzName);
1305 + ExitOnFailure(hr, "Failed to read name");
1306 + StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzName);
1307 +
1308 + // Value
1309 + hr = WcaReadStringFromCaData(ppwzData, &pItm->pwzValue);
1310 + ExitOnFailure(hr, "Failed to read property value");
1311 +
1312 + // add to list
1313 + if (*ppPropList)
1314 + pItm->pNext = *ppPropList;
1315 + *ppPropList = pItm;
1316 + pItm = NULL;
1317 + }
1318 +
1319 + hr = S_OK;
1320 +
1321 +LExit:
1322 + // clean up
1323 + ReleaseStr(pwzName);
1324 +
1325 + if (pItm)
1326 + CpiFreePropertyList(pItm);
1327 +
1328 + return hr;
1329 +}
1330 +
1331 +void CpiFreePropertyList(
1332 + CPI_PROPERTY* pList
1333 + )
1334 +{
1335 + while (pList)
1336 + {
1337 + ReleaseStr(pList->pwzValue);
1338 +
1339 + CPI_PROPERTY* pDelete = pList;
1340 + pList = pList->pNext;
1341 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
1342 + }
1343 +}
1344 +
1345 +HRESULT CpiWriteKeyToRollbackFile(
1346 + HANDLE hFile,
1347 + LPCWSTR pwzKey
1348 + )
1349 +{
1350 + HRESULT hr = S_OK;
1351 +
1352 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
1353 + ::ZeroMemory(wzKey, sizeof(wzKey));
1354 + hr = StringCchCopyW(wzKey, countof(wzKey), pwzKey);
1355 + ExitOnFailure(hr, "Failed to copy key");
1356 +
1357 + hr = WriteFileAll(hFile, (PBYTE)wzKey, MAX_DARWIN_KEY * sizeof(WCHAR));
1358 + ExitOnFailure(hr, "Failed to write buffer");
1359 +
1360 + FlushFileBuffers(hFile);
1361 +
1362 + hr = S_OK;
1363 +
1364 +LExit:
1365 + return hr;
1366 +}
1367 +
1368 +HRESULT CpiWriteIntegerToRollbackFile(
1369 + HANDLE hFile,
1370 + int i
1371 + )
1372 +{
1373 + HRESULT hr = S_OK;
1374 +
1375 + hr = WriteFileAll(hFile, (PBYTE)&i, sizeof(int));
1376 + ExitOnFailure(hr, "Failed to write buffer");
1377 +
1378 + FlushFileBuffers(hFile);
1379 +
1380 + hr = S_OK;
1381 +
1382 +LExit:
1383 + return hr;
1384 +}
1385 +
1386 +HRESULT CpiReadRollbackDataList(
1387 + HANDLE hFile,
1388 + CPI_ROLLBACK_DATA** pprdList
1389 + )
1390 +{
1391 + HRESULT hr = S_OK;
1392 +
1393 + int iCount;
1394 +
1395 + CPI_ROLLBACK_DATA* pItm = NULL;
1396 +
1397 + // read count
1398 + hr = ReadFileAll(hFile, (PBYTE)&iCount, sizeof(int));
1399 + if (HRESULT_FROM_WIN32(ERROR_HANDLE_EOF) == hr)
1400 + ExitFunction1(hr = S_OK); // EOF reached, nothing left to read
1401 + ExitOnFailure(hr, "Failed to read count");
1402 +
1403 + for (int i = 0; i < iCount; i++)
1404 + {
1405 + // allocate new element
1406 + pItm = (CPI_ROLLBACK_DATA*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_ROLLBACK_DATA));
1407 + if (!pItm)
1408 + ExitFunction1(hr = E_OUTOFMEMORY);
1409 +
1410 + // read from file
1411 + hr = ReadFileAll(hFile, (PBYTE)pItm->wzKey, MAX_DARWIN_KEY * sizeof(WCHAR));
1412 + if (HRESULT_FROM_WIN32(ERROR_HANDLE_EOF) == hr)
1413 + break; // EOF reached, nothing left to read
1414 + ExitOnFailure(hr, "Failed to read key");
1415 +
1416 + hr = ReadFileAll(hFile, (PBYTE)&pItm->iStatus, sizeof(int));
1417 + if (HRESULT_FROM_WIN32(ERROR_HANDLE_EOF) == hr)
1418 + pItm->iStatus = 0; // EOF reached, the operation was interupted; set status to zero
1419 + else
1420 + ExitOnFailure(hr, "Failed to read status");
1421 +
1422 + // add to list
1423 + if (*pprdList)
1424 + pItm->pNext = *pprdList;
1425 + *pprdList = pItm;
1426 + pItm = NULL;
1427 + }
1428 +
1429 + hr = S_OK;
1430 +
1431 +LExit:
1432 + // clean up
1433 + if (pItm)
1434 + CpiFreeRollbackDataList(pItm);
1435 +
1436 + return hr;
1437 +}
1438 +
1439 +void CpiFreeRollbackDataList(
1440 + CPI_ROLLBACK_DATA* pList
1441 + )
1442 +{
1443 + while (pList)
1444 + {
1445 + CPI_ROLLBACK_DATA* pDelete = pList;
1446 + pList = pList->pNext;
1447 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
1448 + }
1449 +}
1450 +
1451 +HRESULT CpiFindRollbackStatus(
1452 + CPI_ROLLBACK_DATA* pList,
1453 + LPCWSTR pwzKey,
1454 + int* piStatus
1455 + )
1456 +{
1457 + HRESULT hr = S_OK;
1458 +
1459 + for (; pList; pList = pList->pNext)
1460 + {
1461 + if (0 == lstrcmpW(pList->wzKey, pwzKey))
1462 + {
1463 + *piStatus = pList->iStatus;
1464 + ExitFunction1(hr = S_OK);
1465 + }
1466 + }
1467 +
1468 + hr = S_FALSE;
1469 +
1470 +LExit:
1471 + return hr;
1472 +}
1473 +
1474 +HRESULT CpiAccountNameToSid(
1475 + LPCWSTR pwzAccountName,
1476 + PSID* ppSid
1477 + )
1478 +{
1479 + HRESULT hr = S_OK;
1480 + UINT er = ERROR_SUCCESS;
1481 + NTSTATUS st = 0;
1482 +
1483 + PSID pSid = NULL;
1484 + LSA_OBJECT_ATTRIBUTES loaAttributes;
1485 + LSA_HANDLE lsahPolicy = NULL;
1486 + LSA_UNICODE_STRING lusName;
1487 + PLSA_REFERENCED_DOMAIN_LIST plrdsDomains = NULL;
1488 + PLSA_TRANSLATED_SID pltsSid = NULL;
1489 +
1490 + ::ZeroMemory(&loaAttributes, sizeof(loaAttributes));
1491 + ::ZeroMemory(&lusName, sizeof(lusName));
1492 +
1493 + // identify well known SIDs
1494 + for (CPI_WELLKNOWN_SID* pWS = wsWellKnownSids; pWS->pwzName; pWS++)
1495 + {
1496 + if (0 == lstrcmpiW(pwzAccountName, pWS->pwzName))
1497 + {
1498 + // allocate SID buffer
1499 + pSid = (PSID)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, ::GetSidLengthRequired(pWS->nSubAuthorityCount));
1500 + ExitOnNull(pSid, hr, E_OUTOFMEMORY, "Failed to allocate buffer for SID");
1501 +
1502 + // initialize SID
1503 + ::InitializeSid(pSid, &pWS->iaIdentifierAuthority, pWS->nSubAuthorityCount);
1504 +
1505 + // copy sub autorities
1506 + for (DWORD i = 0; i < pWS->nSubAuthorityCount; i++)
1507 + *::GetSidSubAuthority(pSid, i) = pWS->dwSubAuthority[i];
1508 +
1509 + break;
1510 + }
1511 + }
1512 +
1513 + // lookup name
1514 + if (!pSid)
1515 + {
1516 + // open policy handle
1517 + st = ::LsaOpenPolicy(NULL, &loaAttributes, POLICY_ALL_ACCESS, &lsahPolicy);
1518 + er = ::LsaNtStatusToWinError(st);
1519 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to open policy handle");
1520 +
1521 + // create account name lsa unicode string
1522 + hr = InitLsaUnicodeString(&lusName, pwzAccountName, (DWORD)wcslen(pwzAccountName));
1523 + ExitOnFailure(hr, "Failed to initialize account name string");
1524 +
1525 + // lookup name
1526 + st = ::LsaLookupNames(lsahPolicy, 1, &lusName, &plrdsDomains, &pltsSid);
1527 + er = ::LsaNtStatusToWinError(st);
1528 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to lookup account names");
1529 +
1530 + if (SidTypeDomain == pltsSid->Use)
1531 + ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "Domain SIDs not supported");
1532 +
1533 + // convert sid
1534 + hr = CreateSidFromDomainRidPair(plrdsDomains->Domains[pltsSid->DomainIndex].Sid, pltsSid->RelativeId, &pSid);
1535 + ExitOnFailure(hr, "Failed to convert SID");
1536 + }
1537 +
1538 + *ppSid = pSid;
1539 + pSid = NULL;
1540 +
1541 + hr = S_OK;
1542 +
1543 +LExit:
1544 + // clean up
1545 + if (pSid)
1546 + ::HeapFree(::GetProcessHeap(), 0, pSid);
1547 + if (lsahPolicy)
1548 + ::LsaClose(lsahPolicy);
1549 + if (plrdsDomains)
1550 + ::LsaFreeMemory(plrdsDomains);
1551 + if (pltsSid)
1552 + ::LsaFreeMemory(pltsSid);
1553 + FreeLsaUnicodeString(&lusName);
1554 +
1555 + return hr;
1556 +}
1557 +
1558 +HRESULT CpiSidToAccountName(
1559 + PSID pSid,
1560 + LPWSTR* ppwzAccountName
1561 + )
1562 +{
1563 + HRESULT hr = S_OK;
1564 + UINT er = ERROR_SUCCESS;
1565 + NTSTATUS st = 0;
1566 +
1567 + LSA_OBJECT_ATTRIBUTES loaAttributes;
1568 + LSA_HANDLE lsahPolicy = NULL;
1569 + PLSA_REFERENCED_DOMAIN_LIST plrdsDomains = NULL;
1570 + PLSA_TRANSLATED_NAME pltnName = NULL;
1571 +
1572 + LPWSTR pwzDomain = NULL;
1573 + LPWSTR pwzName = NULL;
1574 +
1575 + ::ZeroMemory(&loaAttributes, sizeof(loaAttributes));
1576 +
1577 + // open policy handle
1578 + st = ::LsaOpenPolicy(NULL, &loaAttributes, POLICY_ALL_ACCESS, &lsahPolicy);
1579 + er = ::LsaNtStatusToWinError(st);
1580 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to open policy handle");
1581 +
1582 + // lookup SID
1583 + st = ::LsaLookupSids(lsahPolicy, 1, &pSid, &plrdsDomains, &pltnName);
1584 + er = ::LsaNtStatusToWinError(st);
1585 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed lookup SID");
1586 +
1587 + if (SidTypeDomain == pltnName->Use)
1588 + ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "Domain SIDs not supported");
1589 +
1590 + // format account name string
1591 + if (SidTypeWellKnownGroup != pltnName->Use)
1592 + {
1593 + PLSA_UNICODE_STRING plusDomain = &plrdsDomains->Domains[pltnName->DomainIndex].Name;
1594 + hr = StrAllocString(&pwzDomain, plusDomain->Buffer, plusDomain->Length / sizeof(WCHAR));
1595 + ExitOnFailure(hr, "Failed to allocate name string");
1596 + }
1597 +
1598 + hr = StrAllocString(&pwzName, pltnName->Name.Buffer, pltnName->Name.Length / sizeof(WCHAR));
1599 + ExitOnFailure(hr, "Failed to allocate domain string");
1600 +
1601 + hr = StrAllocFormatted(ppwzAccountName, L"%s\\%s", pwzDomain ? pwzDomain : L"", pwzName);
1602 + ExitOnFailure(hr, "Failed to format account name string");
1603 +
1604 + hr = S_OK;
1605 +
1606 +LExit:
1607 + // clean up
1608 + if (lsahPolicy)
1609 + ::LsaClose(lsahPolicy);
1610 + if (plrdsDomains)
1611 + ::LsaFreeMemory(plrdsDomains);
1612 + if (pltnName)
1613 + ::LsaFreeMemory(pltnName);
1614 +
1615 + ReleaseStr(pwzDomain);
1616 + ReleaseStr(pwzName);
1617 +
1618 + return hr;
1619 +}
1620 +
1621 +// helper function definitions
1622 +
1623 +static HRESULT FindUserCollectionObjectIndex(
1624 + ICatalogCollection* piColl,
1625 + PSID pSid,
1626 + int* pi
1627 + )
1628 +{
1629 + HRESULT hr = S_OK;
1630 + UINT er = ERROR_SUCCESS;
1631 + NTSTATUS st = 0;
1632 +
1633 + long i = 0;
1634 + long lCollCnt = 0;
1635 +
1636 + LSA_OBJECT_ATTRIBUTES loaAttributes;
1637 + LSA_HANDLE lsahPolicy = NULL;
1638 + PLSA_UNICODE_STRING plusNames = NULL;
1639 + PLSA_REFERENCED_DOMAIN_LIST plrdsDomains = NULL;
1640 + PLSA_TRANSLATED_SID pltsSids = NULL;
1641 +
1642 + IDispatch* piDisp = NULL;
1643 + ICatalogObject* piObj = NULL;
1644 + VARIANT vtVal;
1645 +
1646 + PSID pTmpSid = NULL;
1647 +
1648 + PLSA_TRANSLATED_SID pltsSid;
1649 +
1650 + ::VariantInit(&vtVal);
1651 + ::ZeroMemory(&loaAttributes, sizeof(loaAttributes));
1652 +
1653 + // open policy handle
1654 + st = ::LsaOpenPolicy(NULL, &loaAttributes, POLICY_ALL_ACCESS, &lsahPolicy);
1655 + er = ::LsaNtStatusToWinError(st);
1656 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to open policy handle");
1657 +
1658 + // get number of elements in collection
1659 + hr = piColl->get_Count(&lCollCnt);
1660 + ExitOnFailure(hr, "Failed to get to number of objects in collection");
1661 +
1662 + if (0 == lCollCnt)
1663 + ExitFunction1(hr = S_FALSE); // not found
1664 +
1665 + // allocate name buffer
1666 + plusNames = (PLSA_UNICODE_STRING)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LSA_UNICODE_STRING) * lCollCnt);
1667 + ExitOnNull(plusNames, hr, E_OUTOFMEMORY, "Failed to allocate names buffer");
1668 +
1669 + // get accounts in collection
1670 + for (i = 0; i < lCollCnt; i++)
1671 + {
1672 + // get ICatalogObject interface
1673 + hr = piColl->get_Item(i, &piDisp);
1674 + ExitOnFailure(hr, "Failed to get object from collection");
1675 +
1676 + hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
1677 + ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
1678 +
1679 + // get value
1680 + hr = piObj->get_Key(&vtVal);
1681 + ExitOnFailure(hr, "Failed to get key");
1682 +
1683 + hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
1684 + ExitOnFailure(hr, "Failed to change variant type");
1685 +
1686 + // copy account name string
1687 + hr = InitLsaUnicodeString(&plusNames[i], vtVal.bstrVal, ::SysStringLen(vtVal.bstrVal));
1688 + ExitOnFailure(hr, "Failed to initialize account name string");
1689 +
1690 + // clean up
1691 + ReleaseNullObject(piDisp);
1692 + ReleaseNullObject(piObj);
1693 + ::VariantClear(&vtVal);
1694 + }
1695 +
1696 + // lookup names
1697 + st = ::LsaLookupNames(lsahPolicy, lCollCnt, plusNames, &plrdsDomains, &pltsSids);
1698 + er = ::LsaNtStatusToWinError(st);
1699 + if (ERROR_NONE_MAPPED != er && ERROR_SOME_NOT_MAPPED != er)
1700 + ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to lookup account names");
1701 +
1702 + // compare SIDs
1703 + for (i = 0; i < lCollCnt; i++)
1704 + {
1705 + // get SID
1706 + pltsSid = &pltsSids[i];
1707 + if (SidTypeDomain == pltsSid->Use || SidTypeInvalid == pltsSid->Use || SidTypeUnknown == pltsSid->Use)
1708 + continue; // ignore...
1709 +
1710 + hr = CreateSidFromDomainRidPair(plrdsDomains->Domains[pltsSid->DomainIndex].Sid, pltsSid->RelativeId, &pTmpSid);
1711 + ExitOnFailure(hr, "Failed to convert SID");
1712 +
1713 + // compare SIDs
1714 + if (::EqualSid(pSid, pTmpSid))
1715 + {
1716 + *pi = i;
1717 + ExitFunction1(hr = S_OK);
1718 + }
1719 + }
1720 +
1721 + if (ERROR_NONE_MAPPED == er || ERROR_SOME_NOT_MAPPED == er)
1722 + hr = HRESULT_FROM_WIN32(er);
1723 + else
1724 + hr = S_FALSE; // not found
1725 +
1726 +LExit:
1727 + // clean up
1728 + ReleaseObject(piDisp);
1729 + ReleaseObject(piObj);
1730 + ::VariantClear(&vtVal);
1731 +
1732 + if (plusNames)
1733 + {
1734 + for (i = 0; i < lCollCnt; i++)
1735 + FreeLsaUnicodeString(&plusNames[i]);
1736 + ::HeapFree(::GetProcessHeap(), 0, plusNames);
1737 + }
1738 +
1739 + if (lsahPolicy)
1740 + ::LsaClose(lsahPolicy);
1741 + if (plrdsDomains)
1742 + ::LsaFreeMemory(plrdsDomains);
1743 + if (pltsSids)
1744 + ::LsaFreeMemory(pltsSids);
1745 +
1746 + if (pTmpSid)
1747 + ::HeapFree(::GetProcessHeap(), 0, pTmpSid);
1748 +
1749 + return hr;
1750 +}
1751 +
1752 +static HRESULT CreateSidFromDomainRidPair(
1753 + PSID pDomainSid,
1754 + DWORD dwRid,
1755 + PSID* ppSid
1756 + )
1757 +{
1758 + HRESULT hr = S_OK;
1759 + PSID pSid = NULL;
1760 +
1761 + // get domain SID sub authority count
1762 + UCHAR ucSubAuthorityCount = *::GetSidSubAuthorityCount(pDomainSid);
1763 +
1764 + // allocate SID buffer
1765 + DWORD dwLengthRequired = ::GetSidLengthRequired(ucSubAuthorityCount + (UCHAR)1);
1766 + if (*ppSid)
1767 + {
1768 + SIZE_T ccb = ::HeapSize(::GetProcessHeap(), 0, *ppSid);
1769 + if (-1 == ccb)
1770 + ExitOnFailure(hr = E_FAIL, "Failed to get size of SID buffer");
1771 +
1772 + if (ccb < dwLengthRequired)
1773 + {
1774 + pSid = (PSID)::HeapReAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, *ppSid, dwLengthRequired);
1775 + ExitOnNull(pSid, hr, E_OUTOFMEMORY, "Failed to reallocate buffer for SID, len: %d", dwLengthRequired);
1776 + *ppSid = pSid;
1777 + }
1778 + }
1779 + else
1780 + {
1781 + *ppSid = (PSID)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dwLengthRequired);
1782 + ExitOnNull(*ppSid, hr, E_OUTOFMEMORY, "Failed to allocate buffer for SID, len: %d", dwLengthRequired);
1783 + }
1784 +
1785 + ::InitializeSid(*ppSid, ::GetSidIdentifierAuthority(pDomainSid), ucSubAuthorityCount + (UCHAR)1);
1786 +
1787 + // copy sub autorities
1788 + DWORD i = 0;
1789 + for (; i < ucSubAuthorityCount; i++)
1790 + *::GetSidSubAuthority(*ppSid, i) = *::GetSidSubAuthority(pDomainSid, i);
1791 + *::GetSidSubAuthority(*ppSid, i) = dwRid;
1792 +
1793 + hr = S_OK;
1794 +
1795 +LExit:
1796 + return hr;
1797 +}
1798 +
1799 +static HRESULT InitLsaUnicodeString(
1800 + PLSA_UNICODE_STRING plusStr,
1801 + LPCWSTR pwzStr,
1802 + DWORD dwLen
1803 + )
1804 +{
1805 + HRESULT hr = S_OK;
1806 +
1807 + plusStr->Length = (USHORT)dwLen * sizeof(WCHAR);
1808 + plusStr->MaximumLength = (USHORT)(dwLen + 1) * sizeof(WCHAR);
1809 +
1810 + plusStr->Buffer = (WCHAR*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR) * (dwLen + 1));
1811 + ExitOnNull(plusStr->Buffer, hr, E_OUTOFMEMORY, "Failed to allocate account name string");
1812 +
1813 + hr = StringCchCopyW(plusStr->Buffer, dwLen + 1, pwzStr);
1814 + ExitOnFailure(hr, "Failed to copy buffer");
1815 +
1816 + hr = S_OK;
1817 +
1818 +LExit:
1819 + return hr;
1820 +}
1821 +
1822 +static void FreeLsaUnicodeString(
1823 + PLSA_UNICODE_STRING plusStr
1824 + )
1825 +{
1826 + if (plusStr->Buffer)
1827 + ::HeapFree(::GetProcessHeap(), 0, plusStr->Buffer);
1828 +}
1829 +
1830 +static HRESULT WriteFileAll(
1831 + HANDLE hFile,
1832 + PBYTE pbBuffer,
1833 + DWORD dwBufferLength
1834 + )
1835 +{
1836 + HRESULT hr = S_OK;
1837 +
1838 + DWORD dwBytesWritten;
1839 +
1840 + while (dwBufferLength)
1841 + {
1842 + if (!::WriteFile(hFile, pbBuffer, dwBufferLength, &dwBytesWritten, NULL))
1843 + ExitFunction1(hr = HRESULT_FROM_WIN32(::GetLastError()));
1844 +
1845 + dwBufferLength -= dwBytesWritten;
1846 + pbBuffer += dwBytesWritten;
1847 + }
1848 +
1849 + hr = S_OK;
1850 +
1851 +LExit:
1852 + return hr;
1853 +}
1854 +
1855 +static HRESULT ReadFileAll(
1856 + HANDLE hFile,
1857 + PBYTE pbBuffer,
1858 + DWORD dwBufferLength
1859 + )
1860 +{
1861 + HRESULT hr = S_OK;
1862 +
1863 + DWORD dwBytesRead;
1864 +
1865 + while (dwBufferLength)
1866 + {
1867 + if (!::ReadFile(hFile, pbBuffer, dwBufferLength, &dwBytesRead, NULL))
1868 + ExitFunction1(hr = HRESULT_FROM_WIN32(::GetLastError()));
1869 +
1870 + if (0 == dwBytesRead)
1871 + ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_HANDLE_EOF));
1872 +
1873 + dwBufferLength -= dwBytesRead;
1874 + pbBuffer += dwBytesRead;
1875 + }
1876 +
1877 + hr = S_OK;
1878 +
1879 +LExit:
1880 + return hr;
1881 +}
src/ca/cputilexec.h new
+193
@@ -0,0 +1,193 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +#define CPI_MAX_GUID 38
6 +
7 +enum eActionType { atNoOp = 0, atCreate, atRemove };
8 +
9 +
10 +// structs
11 +
12 +struct CPI_PROPERTY
13 +{
14 + WCHAR wzName[MAX_DARWIN_KEY + 1];
15 + LPWSTR pwzValue;
16 +
17 + CPI_PROPERTY* pNext;
18 +};
19 +
20 +struct CPI_ROLLBACK_DATA
21 +{
22 + WCHAR wzKey[MAX_DARWIN_KEY + 1];
23 + int iStatus;
24 +
25 + CPI_ROLLBACK_DATA* pNext;
26 +};
27 +
28 +
29 +// function prototypes
30 +
31 +void CpiInitialize();
32 +void CpiFinalize();
33 +HRESULT CpiActionStartMessage(
34 + LPWSTR* ppwzActionData,
35 + BOOL fSuppress
36 + );
37 +HRESULT CpiActionDataMessage(
38 + DWORD cArgs,
39 + ...
40 + );
41 +HRESULT CpiGetAdminCatalog(
42 + ICOMAdminCatalog** ppiCatalog
43 + );
44 +HRESULT CpiLogCatalogErrorInfo();
45 +HRESULT CpiGetCatalogCollection(
46 + LPCWSTR pwzName,
47 + ICatalogCollection** ppiColl
48 + );
49 +HRESULT CpiGetCatalogCollection(
50 + ICatalogCollection* piColl,
51 + ICatalogObject* piObj,
52 + LPCWSTR pwzName,
53 + ICatalogCollection** ppiColl
54 + );
55 +HRESULT CpiAddCollectionObject(
56 + ICatalogCollection* piColl,
57 + ICatalogObject** ppiObj
58 + );
59 +HRESULT CpiPutCollectionObjectValue(
60 + ICatalogObject* piObj,
61 + LPCWSTR pwzPropName,
62 + LPCWSTR pwzValue
63 + );
64 +HRESULT CpiPutCollectionObjectValues(
65 + ICatalogObject* piObj,
66 + CPI_PROPERTY* pPropList
67 + );
68 +HRESULT CpiGetCollectionObjectValue(
69 + ICatalogObject* piObj,
70 + LPCWSTR szPropName,
71 + LPWSTR* ppwzValue
72 + );
73 +HRESULT CpiResetObjectProperty(
74 + ICatalogCollection* piColl,
75 + ICatalogObject* piObj,
76 + LPCWSTR pwzPropName
77 + );
78 +HRESULT CpiRemoveCollectionObject(
79 + ICatalogCollection* piColl,
80 + LPCWSTR pwzID,
81 + LPCWSTR pwzName,
82 + BOOL fResetDeleteable
83 + );
84 +HRESULT CpiRemoveUserCollectionObject(
85 + ICatalogCollection* piColl,
86 + PSID pSid
87 + );
88 +HRESULT CpiFindCollectionObjectByStringKey(
89 + ICatalogCollection* piColl,
90 + LPCWSTR pwzKey,
91 + ICatalogObject** ppiObj
92 + );
93 +HRESULT CpiFindCollectionObjectByIntegerKey(
94 + ICatalogCollection* piColl,
95 + long lKey,
96 + ICatalogObject** ppiObj
97 + );
98 +HRESULT CpiFindCollectionObjectByName(
99 + ICatalogCollection* piColl,
100 + LPCWSTR pwzName,
101 + ICatalogObject** ppiObj
102 + );
103 +HRESULT CpiFindUserCollectionObject(
104 + ICatalogCollection* piColl,
105 + PSID pSid,
106 + ICatalogObject** ppiObj
107 + );
108 +HRESULT CpiGetPartitionsCollection(
109 + ICatalogCollection** ppiPartColl
110 + );
111 +HRESULT CpiGetPartitionRolesCollection(
112 + LPCWSTR pwzPartID,
113 + ICatalogCollection** ppiRolesColl
114 + );
115 +HRESULT CpiGetUsersInPartitionRoleCollection(
116 + LPCWSTR pwzPartID,
117 + LPCWSTR pwzRoleName,
118 + ICatalogCollection** ppiUsrInRoleColl
119 + );
120 +HRESULT CpiGetPartitionUsersCollection(
121 + ICatalogCollection** ppiUserColl
122 + );
123 +HRESULT CpiGetApplicationsCollection(
124 + LPCWSTR pwzPartID,
125 + ICatalogCollection** ppiAppColl
126 + );
127 +HRESULT CpiGetRolesCollection(
128 + LPCWSTR pwzPartID,
129 + LPCWSTR pwzAppID,
130 + ICatalogCollection** ppiRolesColl
131 + );
132 +HRESULT CpiGetUsersInRoleCollection(
133 + LPCWSTR pwzPartID,
134 + LPCWSTR pwzAppID,
135 + LPCWSTR pwzRoleName,
136 + ICatalogCollection** ppiUsrInRoleColl
137 + );
138 +HRESULT CpiGetComponentsCollection(
139 + LPCWSTR pwzPartID,
140 + LPCWSTR pwzAppID,
141 + ICatalogCollection** ppiCompsColl
142 + );
143 +HRESULT CpiGetInterfacesCollection(
144 + ICatalogCollection* piCompColl,
145 + ICatalogObject* piCompObj,
146 + ICatalogCollection** ppiIntfColl
147 + );
148 +HRESULT CpiGetMethodsCollection(
149 + ICatalogCollection* piIntfColl,
150 + ICatalogObject* piIntfObj,
151 + ICatalogCollection** ppiMethColl
152 + );
153 +HRESULT CpiGetSubscriptionsCollection(
154 + LPCWSTR pwzPartID,
155 + LPCWSTR pwzAppID,
156 + LPCWSTR pwzCompCLSID,
157 + ICatalogCollection** ppiCompsColl
158 + );
159 +HRESULT CpiReadPropertyList(
160 + LPWSTR* ppwzData,
161 + CPI_PROPERTY** ppPropList
162 + );
163 +void CpiFreePropertyList(
164 + CPI_PROPERTY* pList
165 + );
166 +HRESULT CpiWriteKeyToRollbackFile(
167 + HANDLE hFile,
168 + LPCWSTR pwzKey
169 + );
170 +HRESULT CpiWriteIntegerToRollbackFile(
171 + HANDLE hFile,
172 + int i
173 + );
174 +HRESULT CpiReadRollbackDataList(
175 + HANDLE hFile,
176 + CPI_ROLLBACK_DATA** pprdList
177 + );
178 +void CpiFreeRollbackDataList(
179 + CPI_ROLLBACK_DATA* pList
180 + );
181 +HRESULT CpiFindRollbackStatus(
182 + CPI_ROLLBACK_DATA* pList,
183 + LPCWSTR pwzKey,
184 + int* piStatus
185 + );
186 +HRESULT CpiAccountNameToSid(
187 + LPCWSTR pwzAccountName,
188 + PSID* ppSid
189 + );
190 +HRESULT CpiSidToAccountName(
191 + PSID pSid,
192 + LPWSTR* ppwzAccountName
193 + );
src/ca/cputilsched.cpp new
+885
@@ -0,0 +1,885 @@
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 vcsActionTextQuery =
9 + L"SELECT `Description`, `Template` FROM `ActionText` WHERE `Action` = ?";
10 +enum eActionTextQuery { atqDescription = 1, atqTemplate };
11 +
12 +LPCWSTR vcsComponentAttributesQuery =
13 + L"SELECT `Attributes` FROM `Component` WHERE `Component` = ?";
14 +enum eComponentAttributesQuery { caqAttributes = 1 };
15 +
16 +LPCWSTR vcsUserQuery = L"SELECT `Domain`, `Name` FROM `User` WHERE `User` = ?";
17 +enum eUserQuery { uqDomain = 1, uqName };
18 +
19 +enum ePropertyQuery { pqName = 1, pqValue };
20 +
21 +
22 +// prototypes for private helper functions
23 +
24 +static HRESULT FindPropertyDefinition(
25 + CPI_PROPERTY_DEFINITION* pPropDefList,
26 + LPCWSTR pwzName,
27 + CPI_PROPERTY_DEFINITION** ppPropDef
28 + );
29 +static HRESULT GetUserAccountName(
30 + LPCWSTR pwzKey,
31 + LPWSTR* ppwzAccount
32 + );
33 +
34 +
35 +// variables
36 +
37 +static ICOMAdminCatalog* gpiCatalog;
38 +static ICatalogCollection* gpiPartColl;
39 +static ICatalogCollection* gpiAppColl;
40 +
41 +static int giTables;
42 +
43 +
44 +// function definitions
45 +
46 +void CpiInitialize()
47 +{
48 + // collections
49 + gpiCatalog = NULL;
50 + gpiPartColl = NULL;
51 + gpiAppColl = NULL;
52 +
53 + // tables
54 + giTables = 0;
55 +
56 + if (S_OK == WcaTableExists(L"ComPlusPartition")) giTables |= cptComPlusPartition;
57 + if (S_OK == WcaTableExists(L"ComPlusPartitionProperty")) giTables |= cptComPlusPartitionProperty;
58 + if (S_OK == WcaTableExists(L"ComPlusPartitionRole")) giTables |= cptComPlusPartitionRole;
59 + if (S_OK == WcaTableExists(L"ComPlusUserInPartitionRole")) giTables |= cptComPlusUserInPartitionRole;
60 + if (S_OK == WcaTableExists(L"ComPlusGroupInPartitionRole")) giTables |= cptComPlusGroupInPartitionRole;
61 + if (S_OK == WcaTableExists(L"ComPlusPartitionUser")) giTables |= cptComPlusPartitionUser;
62 + if (S_OK == WcaTableExists(L"ComPlusApplication")) giTables |= cptComPlusApplication;
63 + if (S_OK == WcaTableExists(L"ComPlusApplicationProperty")) giTables |= cptComPlusApplicationProperty;
64 + if (S_OK == WcaTableExists(L"ComPlusApplicationRole")) giTables |= cptComPlusApplicationRole;
65 + if (S_OK == WcaTableExists(L"ComPlusApplicationRoleProperty")) giTables |= cptComPlusApplicationRoleProperty;
66 + if (S_OK == WcaTableExists(L"ComPlusUserInApplicationRole")) giTables |= cptComPlusUserInApplicationRole;
67 + if (S_OK == WcaTableExists(L"ComPlusGroupInApplicationRole")) giTables |= cptComPlusGroupInApplicationRole;
68 + if (S_OK == WcaTableExists(L"ComPlusAssembly")) giTables |= cptComPlusAssembly;
69 + if (S_OK == WcaTableExists(L"ComPlusAssemblyDependency")) giTables |= cptComPlusAssemblyDependency;
70 + if (S_OK == WcaTableExists(L"ComPlusComponent")) giTables |= cptComPlusComponent;
71 + if (S_OK == WcaTableExists(L"ComPlusComponentProperty")) giTables |= cptComPlusComponentProperty;
72 + if (S_OK == WcaTableExists(L"ComPlusRoleForComponent")) giTables |= cptComPlusRoleForComponent;
73 + if (S_OK == WcaTableExists(L"ComPlusInterface")) giTables |= cptComPlusInterface;
74 + if (S_OK == WcaTableExists(L"ComPlusInterfaceProperty")) giTables |= cptComPlusInterfaceProperty;
75 + if (S_OK == WcaTableExists(L"ComPlusRoleForInterface")) giTables |= cptComPlusRoleForInterface;
76 + if (S_OK == WcaTableExists(L"ComPlusMethod")) giTables |= cptComPlusMethod;
77 + if (S_OK == WcaTableExists(L"ComPlusMethodProperty")) giTables |= cptComPlusMethodProperty;
78 + if (S_OK == WcaTableExists(L"ComPlusRoleForMethod")) giTables |= cptComPlusRoleForMethod;
79 + if (S_OK == WcaTableExists(L"ComPlusSubscription")) giTables |= cptComPlusSubscription;
80 + if (S_OK == WcaTableExists(L"ComPlusSubscriptionProperty")) giTables |= cptComPlusSubscriptionProperty;
81 +}
82 +
83 +void CpiFinalize()
84 +{
85 + // collections
86 + ReleaseObject(gpiCatalog);
87 + ReleaseObject(gpiPartColl);
88 + ReleaseObject(gpiAppColl);
89 +}
90 +
91 +BOOL CpiTableExists(
92 + int iTable
93 + )
94 +{
95 + return (giTables & iTable) == iTable;
96 +}
97 +
98 +HRESULT CpiGetAdminCatalog(
99 + ICOMAdminCatalog** ppiCatalog
100 + )
101 +{
102 + HRESULT hr = S_OK;
103 +
104 + if (!gpiCatalog)
105 + {
106 + // get collection
107 + hr = ::CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_ALL, IID_ICOMAdminCatalog, (void**)&gpiCatalog);
108 + ExitOnFailure(hr, "Failed to create COM+ admin catalog object");
109 + }
110 +
111 + // return value
112 + gpiCatalog->AddRef();
113 + *ppiCatalog = gpiCatalog;
114 +
115 + hr = S_OK;
116 +
117 +LExit:
118 + return hr;
119 +}
120 +
121 +HRESULT CpiGetCatalogCollection(
122 + LPCWSTR pwzName,
123 + ICatalogCollection** ppiColl
124 + )
125 +{
126 + HRESULT hr = S_OK;
127 +
128 + ICOMAdminCatalog* piCatalog = NULL;
129 + IDispatch* piDisp = NULL;
130 + BSTR bstrName = NULL;
131 +
132 + // copy name string
133 + bstrName = ::SysAllocString(pwzName);
134 + ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for collection name");
135 +
136 + // get catalog
137 + hr = CpiGetAdminCatalog(&piCatalog);
138 + ExitOnFailure(hr, "Failed to get COM+ admin catalog");
139 +
140 + // get collecton from catalog
141 + hr = piCatalog->GetCollection(bstrName, &piDisp);
142 + ExitOnFailure(hr, "Failed to get collection");
143 +
144 + hr = piDisp->QueryInterface(IID_ICatalogCollection, (void**)ppiColl);
145 + ExitOnFailure(hr, "Failed to get IID_ICatalogCollection interface");
146 +
147 + // populate collection
148 + hr = (*ppiColl)->Populate();
149 + ExitOnFailure(hr, "Failed to populate collection");
150 +
151 + hr = S_OK;
152 +
153 +LExit:
154 + // clean up
155 + ReleaseObject(piCatalog);
156 + ReleaseObject(piDisp);
157 + ReleaseBSTR(bstrName);
158 +
159 + return hr;
160 +}
161 +
162 +HRESULT CpiGetCatalogCollection(
163 + ICatalogCollection* piColl,
164 + ICatalogObject* piObj,
165 + LPCWSTR pwzName,
166 + ICatalogCollection** ppiColl
167 + )
168 +{
169 + HRESULT hr = S_OK;
170 +
171 + ICOMAdminCatalog* piCatalog = NULL;
172 + IDispatch* piDisp = NULL;
173 + BSTR bstrName = NULL;
174 +
175 + VARIANT vtKey;
176 + ::VariantInit(&vtKey);
177 +
178 + // copy name string
179 + bstrName = ::SysAllocString(pwzName);
180 + ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "Failed to allocate BSTR for collection name");
181 +
182 + // get catalog
183 + hr = CpiGetAdminCatalog(&piCatalog);
184 + ExitOnFailure(hr, "Failed to get COM+ admin catalog");
185 +
186 + // get key
187 + hr = piObj->get_Key(&vtKey);
188 + ExitOnFailure(hr, "Failed to get object key");
189 +
190 + // get collecton from catalog
191 + hr = piColl->GetCollection(bstrName, vtKey, &piDisp);
192 + ExitOnFailure(hr, "Failed to get collection");
193 +
194 + hr = piDisp->QueryInterface(IID_ICatalogCollection, (void**)ppiColl);
195 + ExitOnFailure(hr, "Failed to get IID_ICatalogCollection interface");
196 +
197 + // populate collection
198 + hr = (*ppiColl)->Populate();
199 + ExitOnFailure(hr, "Failed to populate collection");
200 +
201 + hr = S_OK;
202 +
203 +LExit:
204 + // clean up
205 + ReleaseObject(piCatalog);
206 + ReleaseObject(piDisp);
207 + ReleaseBSTR(bstrName);
208 + ::VariantClear(&vtKey);
209 +
210 + return hr;
211 +}
212 +
213 +HRESULT CpiGetKeyForObject(
214 + ICatalogObject* piObj,
215 + LPWSTR pwzKey,
216 + SIZE_T cchKey
217 + )
218 +{
219 + HRESULT hr = S_OK;
220 +
221 + VARIANT vtKey;
222 + ::VariantInit(&vtKey);
223 +
224 + // get key
225 + hr = piObj->get_Key(&vtKey);
226 + ExitOnFailure(hr, "Failed to get key");
227 +
228 + // change variant type
229 + hr = ::VariantChangeType(&vtKey, &vtKey, 0, VT_BSTR);
230 + ExitOnFailure(hr, "Failed to change variant type");
231 +
232 + // copy key
233 + hr = StringCchCopyW(pwzKey, cchKey, vtKey.bstrVal);
234 + ExitOnFailure(hr, "Failed to copy key");
235 +
236 + hr = S_OK;
237 +
238 +LExit:
239 + // clean up
240 + ::VariantClear(&vtKey);
241 +
242 + return hr;
243 +}
244 +
245 +HRESULT CpiFindCollectionObject(
246 + ICatalogCollection* piColl,
247 + LPCWSTR pwzID,
248 + LPCWSTR pwzName,
249 + ICatalogObject** ppiObj
250 + )
251 +{
252 + HRESULT hr = S_OK;
253 +
254 + IDispatch* piDisp = NULL;
255 + ICatalogObject* piObj = NULL;
256 +
257 + VARIANT vtVal;
258 + ::VariantInit(&vtVal);
259 +
260 + long lCnt;
261 + hr = piColl->get_Count(&lCnt);
262 + ExitOnFailure(hr, "Failed to get to number of items in collection");
263 +
264 + for (long i = 0; i < lCnt; i++)
265 + {
266 + // get ICatalogObject interface
267 + hr = piColl->get_Item(i, &piDisp);
268 + ExitOnFailure(hr, "Failed to get object from collection");
269 +
270 + hr = piDisp->QueryInterface(IID_ICatalogObject, (void**)&piObj);
271 + ExitOnFailure(hr, "Failed to get IID_ICatalogObject interface");
272 +
273 + // compare id
274 + if (pwzID && *pwzID)
275 + {
276 + hr = piObj->get_Key(&vtVal);
277 + ExitOnFailure(hr, "Failed to get key");
278 +
279 + hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
280 + ExitOnFailure(hr, "Failed to change variant type");
281 +
282 + if (0 == lstrcmpiW(vtVal.bstrVal, pwzID))
283 + {
284 + if (ppiObj)
285 + {
286 + *ppiObj = piObj;
287 + piObj = NULL;
288 + }
289 + ExitFunction1(hr = S_OK);
290 + }
291 +
292 + ::VariantClear(&vtVal);
293 + }
294 +
295 + // compare name
296 + if (pwzName && *pwzName)
297 + {
298 + hr = piObj->get_Name(&vtVal);
299 + ExitOnFailure(hr, "Failed to get name");
300 +
301 + hr = ::VariantChangeType(&vtVal, &vtVal, 0, VT_BSTR);
302 + ExitOnFailure(hr, "Failed to change variant type");
303 +
304 + if (0 == lstrcmpW(vtVal.bstrVal, pwzName))
305 + {
306 + if (ppiObj)
307 + {
308 + *ppiObj = piObj;
309 + piObj = NULL;
310 + }
311 + ExitFunction1(hr = S_OK);
312 + }
313 +
314 + ::VariantClear(&vtVal);
315 + }
316 +
317 + // release interface pointers
318 + ReleaseNullObject(piDisp);
319 + ReleaseNullObject(piObj);
320 + }
321 +
322 + hr = S_FALSE;
323 +
324 +LExit:
325 + // clean up
326 + ReleaseObject(piDisp);
327 + ReleaseObject(piObj);
328 +
329 + ::VariantClear(&vtVal);
330 +
331 + return hr;
332 +}
333 +
334 +HRESULT CpiGetPartitionsCollection(
335 + ICatalogCollection** ppiPartColl
336 + )
337 +{
338 + HRESULT hr = S_OK;
339 +
340 + if (!gpiPartColl)
341 + {
342 + // get collection
343 + hr = CpiGetCatalogCollection(L"Partitions", &gpiPartColl);
344 + ExitOnFailure(hr, "Failed to get partitions collection");
345 + }
346 +
347 + // return value
348 + gpiPartColl->AddRef();
349 + *ppiPartColl = gpiPartColl;
350 +
351 + hr = S_OK;
352 +
353 +LExit:
354 + return hr;
355 +}
356 +
357 +HRESULT CpiGetApplicationsCollection(
358 + ICatalogCollection** ppiAppColl
359 + )
360 +{
361 + HRESULT hr = S_OK;
362 +
363 + ICOMAdminCatalog* piCatalog = NULL;
364 + ICOMAdminCatalog2* piCatalog2 = NULL;
365 + ICatalogCollection* piPartColl = NULL;
366 + ICatalogObject* piPartObj = NULL;
367 + BSTR bstrGlobPartID = NULL;
368 +
369 + if (!gpiAppColl)
370 + {
371 + // get catalog
372 + hr = CpiGetAdminCatalog(&piCatalog);
373 + ExitOnFailure(hr, "Failed to get COM+ admin catalog");
374 +
375 + // get ICOMAdminCatalog2 interface
376 + hr = piCatalog->QueryInterface(IID_ICOMAdminCatalog2, (void**)&piCatalog2);
377 +
378 + // COM+ 1.5 or later
379 + if (E_NOINTERFACE != hr)
380 + {
381 + ExitOnFailure(hr, "Failed to get IID_ICOMAdminCatalog2 interface");
382 +
383 + // get global partition id
384 + hr = piCatalog2->get_GlobalPartitionID(&bstrGlobPartID);
385 + ExitOnFailure(hr, "Failed to get global partition id");
386 +
387 + // get partitions collection
388 + hr = CpiGetPartitionsCollection(&piPartColl);
389 + ExitOnFailure(hr, "Failed to get partitions collection");
390 +
391 + // find object
392 + hr = CpiFindCollectionObject(piPartColl, bstrGlobPartID, NULL, &piPartObj);
393 + ExitOnFailure(hr, "Failed to find collection object");
394 +
395 + if (S_FALSE == hr)
396 + ExitFunction(); // partition not found, exit with hr = S_FALSE
397 +
398 + // get applications collection
399 + hr = CpiGetCatalogCollection(piPartColl, piPartObj, L"Applications", &gpiAppColl);
400 + ExitOnFailure(hr, "Failed to get applications collection");
401 + }
402 +
403 + // COM+ pre 1.5
404 + else
405 + {
406 + // get applications collection
407 + hr = CpiGetCatalogCollection(L"Applications", &gpiAppColl);
408 + ExitOnFailure(hr, "Failed to get applications collection");
409 + }
410 + }
411 +
412 + // return value
413 + gpiAppColl->AddRef();
414 + *ppiAppColl = gpiAppColl;
415 +
416 + hr = S_OK;
417 +
418 +LExit:
419 + // clean up
420 + ReleaseObject(piCatalog);
421 + ReleaseObject(piCatalog2);
422 + ReleaseObject(piPartColl);
423 + ReleaseObject(piPartObj);
424 + ReleaseBSTR(bstrGlobPartID);
425 +
426 + return hr;
427 +}
428 +
429 +HRESULT CpiAddActionTextToActionData(
430 + LPCWSTR pwzAction,
431 + LPWSTR* ppwzActionData
432 + )
433 +{
434 + HRESULT hr = S_OK;
435 +
436 + PMSIHANDLE hView, hRecKey, hRec;
437 +
438 + LPWSTR pwzDescription = NULL;
439 + LPWSTR pwzTemplate = NULL;
440 +
441 + if (S_OK == WcaTableExists(L"ActionText"))
442 + {
443 + // create parameter record
444 + hRecKey = ::MsiCreateRecord(1);
445 + ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
446 + hr = WcaSetRecordString(hRecKey, 1, pwzAction);
447 + ExitOnFailure(hr, "Failed to set record string");
448 +
449 + // open view
450 + hr = WcaOpenView(vcsActionTextQuery, &hView);
451 + ExitOnFailure(hr, "Failed to open view on ActionText table");
452 + hr = WcaExecuteView(hView, hRecKey);
453 + ExitOnFailure(hr, "Failed to execute view on ActionText table");
454 +
455 + // fetch record
456 + hr = WcaFetchSingleRecord(hView, &hRec);
457 + if (S_FALSE != hr)
458 + {
459 + ExitOnFailure(hr, "Failed to fetch action text record");
460 +
461 + // get description
462 + hr = WcaGetRecordString(hRec, atqDescription, &pwzDescription);
463 + ExitOnFailure(hr, "Failed to get description");
464 +
465 + // get template
466 + hr = WcaGetRecordString(hRec, atqTemplate, &pwzTemplate);
467 + ExitOnFailure(hr, "Failed to get template");
468 + }
469 + }
470 +
471 + // add action name to action data
472 + hr = WcaWriteStringToCaData(pwzAction, ppwzActionData);
473 + ExitOnFailure(hr, "Failed to add action name to custom action data");
474 +
475 + // add description to action data
476 + hr = WcaWriteStringToCaData(pwzDescription ? pwzDescription : L"", ppwzActionData);
477 + ExitOnFailure(hr, "Failed to add description to custom action data");
478 +
479 + // add template to action data
480 + hr = WcaWriteStringToCaData(pwzTemplate ? pwzTemplate : L"", ppwzActionData);
481 + ExitOnFailure(hr, "Failed to add template to custom action data");
482 +
483 + hr = S_OK;
484 +
485 +LExit:
486 + // clean up
487 + ReleaseStr(pwzDescription);
488 + ReleaseStr(pwzTemplate);
489 +
490 + return hr;
491 +}
492 +
493 +HRESULT CpiVerifyComponentArchitecure(
494 + LPCWSTR pwzComponent,
495 + BOOL* pfMatchingArchitecture
496 + )
497 +{
498 + HRESULT hr = S_OK;
499 +
500 + PMSIHANDLE hView, hRecKey, hRec;
501 +
502 + int iAttributes = 0;
503 +
504 + if (S_OK == WcaTableExists(L"Component"))
505 + {
506 + // create parameter record
507 + hRecKey = ::MsiCreateRecord(1);
508 + ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
509 + hr = WcaSetRecordString(hRecKey, 1, pwzComponent);
510 + ExitOnFailure(hr, "Failed to set record string");
511 +
512 + // open view
513 + hr = WcaOpenView(vcsComponentAttributesQuery, &hView);
514 + ExitOnFailure(hr, "Failed to open view on ActionText table");
515 + hr = WcaExecuteView(hView, hRecKey);
516 + ExitOnFailure(hr, "Failed to execute view on ActionText table");
517 +
518 + // fetch record
519 + hr = WcaFetchSingleRecord(hView, &hRec);
520 + if (S_FALSE != hr)
521 + {
522 + ExitOnFailure(hr, "Failed to fetch component record");
523 +
524 + hr = WcaGetRecordInteger(hRec, caqAttributes, &iAttributes);
525 + ExitOnFailure(hr, "Failed to get component attributes");
526 + }
527 + }
528 +
529 + // return values
530 +#ifdef _WIN64
531 + *pfMatchingArchitecture = 256 == (iAttributes & 256);
532 +#else
533 + *pfMatchingArchitecture = 256 != (iAttributes & 256);
534 +#endif
535 +
536 + hr = S_OK;
537 +
538 +LExit:
539 + return hr;
540 +}
541 +
542 +HRESULT CpiPropertiesRead(
543 + LPCWSTR pwzQuery,
544 + LPCWSTR pwzKey,
545 + CPI_PROPERTY_DEFINITION* pPropDefList,
546 + CPI_PROPERTY** ppPropList,
547 + int* piCount
548 + )
549 +{
550 + HRESULT hr = S_OK;
551 +
552 + PMSIHANDLE hView, hRecKey, hRec;
553 +
554 + CPI_PROPERTY* pItm = NULL;
555 + LPWSTR pwzData = NULL;
556 +
557 + int iVersionNT = 0;
558 +
559 + CPI_PROPERTY_DEFINITION* pPropDef;
560 +
561 + *piCount = 0;
562 +
563 + // get NT version
564 + hr = WcaGetIntProperty(L"VersionNT", &iVersionNT);
565 + ExitOnFailure(hr, "Failed to set record string");
566 +
567 + // create parameter record
568 + hRecKey = ::MsiCreateRecord(1);
569 + ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
570 + hr = WcaSetRecordString(hRecKey, 1, pwzKey);
571 + ExitOnFailure(hr, "Failed to set record string");
572 +
573 + // open view
574 + hr = WcaOpenView(pwzQuery, &hView);
575 + ExitOnFailure(hr, "Failed to open view on property table");
576 + hr = WcaExecuteView(hView, hRecKey);
577 + ExitOnFailure(hr, "Failed to execute view on property table");
578 +
579 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
580 + {
581 + // create entry
582 + pItm = (CPI_PROPERTY*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PROPERTY));
583 + if (!pItm)
584 + ExitFunction1(hr = E_OUTOFMEMORY);
585 +
586 + // get name
587 + hr = WcaGetRecordString(hRec, pqName, &pwzData);
588 + ExitOnFailure(hr, "Failed to get name");
589 + StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);
590 +
591 + // get value
592 + hr = WcaGetRecordFormattedString(hRec, pqValue, &pItm->pwzValue);
593 + ExitOnFailure(hr, "Failed to get value");
594 +
595 + // find property definition
596 + hr = FindPropertyDefinition(pPropDefList, pItm->wzName, &pPropDef);
597 + ExitOnFailure(hr, "Failed to find property definition");
598 +
599 + if (S_FALSE == hr)
600 + ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unknown property, key: %S, property: %S", pwzKey, pItm->wzName);
601 +
602 + // check version, ignore if catalog version is too low
603 + if (iVersionNT < pPropDef->iMinVersionNT)
604 + {
605 + WcaLog(LOGMSG_VERBOSE, "Skipping property since NT version is too low, key: %S, property: %S", pwzKey, pItm->wzName);
606 + CpiPropertiesFreeList(pItm);
607 + pItm = NULL;
608 + continue;
609 + }
610 +
611 + // if the property is a user, replace the User table key with a user account name
612 + if (cpptUser == pPropDef->iType)
613 + {
614 + hr = GetUserAccountName(pItm->pwzValue, &pItm->pwzValue);
615 + ExitOnFailure(hr, "Failed to get user account name");
616 + }
617 +
618 + // add entry
619 + ++*piCount;
620 + if (*ppPropList)
621 + pItm->pNext = *ppPropList;
622 + *ppPropList = pItm;
623 + pItm = NULL;
624 + }
625 +
626 + if (E_NOMOREITEMS == hr)
627 + hr = S_OK;
628 +
629 +LExit:
630 + // clean up
631 + if (pItm)
632 + CpiPropertiesFreeList(pItm);
633 +
634 + ReleaseStr(pwzData);
635 +
636 + return hr;
637 +}
638 +
639 +void CpiPropertiesFreeList(
640 + CPI_PROPERTY* pList
641 + )
642 +{
643 + while (pList)
644 + {
645 + ReleaseStr(pList->pwzValue);
646 +
647 + CPI_PROPERTY* pDelete = pList;
648 + pList = pList->pNext;
649 + ::HeapFree(::GetProcessHeap(), 0, pDelete);
650 + }
651 +}
652 +
653 +HRESULT CpiAddPropertiesToActionData(
654 + int iPropCount,
655 + CPI_PROPERTY* pPropList,
656 + LPWSTR* ppwzActionData
657 + )
658 +{
659 + HRESULT hr = S_OK;
660 +
661 + hr = WcaWriteIntegerToCaData(iPropCount, ppwzActionData);
662 + ExitOnFailure(hr, "Failed to add count to custom action data");
663 +
664 + if (iPropCount) // count might be 0 event thought there are elements in the list
665 + {
666 + for (CPI_PROPERTY* pProp = pPropList; pProp; pProp = pProp->pNext)
667 + {
668 + hr = WcaWriteStringToCaData(pProp->wzName, ppwzActionData);
669 + ExitOnFailure(hr, "Failed to add property name to custom action data, name: %S", pProp->wzName);
670 +
671 + hr = WcaWriteStringToCaData(pProp->pwzValue, ppwzActionData);
672 + ExitOnFailure(hr, "Failed to add property value to custom action data, name: %S", pProp->wzName);
673 + }
674 + }
675 +
676 + hr = S_OK;
677 +
678 +LExit:
679 + return hr;
680 +}
681 +
682 +HRESULT CpiBuildAccountName(
683 + LPCWSTR pwzDomain,
684 + LPCWSTR pwzName,
685 + LPWSTR* ppwzAccount
686 + )
687 +{
688 + HRESULT hr = S_OK;
689 +
690 + WCHAR wzComputerName[MAX_COMPUTERNAME_LENGTH + 1];
691 + ::ZeroMemory(wzComputerName, sizeof(wzComputerName));
692 +
693 + // if domain is '.', get computer name
694 + if (0 == lstrcmpW(pwzDomain, L"."))
695 + {
696 + DWORD dwSize = countof(wzComputerName);
697 + if (!::GetComputerNameW(wzComputerName, &dwSize))
698 + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to get computer name");
699 + }
700 +
701 + // build account name
702 + hr = StrAllocFormatted(ppwzAccount, L"%s\\%s", *wzComputerName ? wzComputerName : pwzDomain, pwzName);
703 + ExitOnFailure(hr, "Failed to build domain user name");
704 +
705 + hr = S_OK;
706 +
707 +LExit:
708 + return hr;
709 +}
710 +
711 +HRESULT CpiGetTempFileName(
712 + LPWSTR* ppwzTempFile
713 + )
714 +{
715 + HRESULT hr = S_OK;
716 +
717 + // get temp path
718 + WCHAR wzTempPath[MAX_PATH];
719 + DWORD dw = ::GetTempPathW(countof(wzTempPath), wzTempPath);
720 + if (countof(wzTempPath) <= dw)
721 + ExitOnFailure(hr = E_FAIL, "TEMP directory path too long");
722 +
723 + // get unique number
724 + LARGE_INTEGER liCount;
725 + if (!::QueryPerformanceCounter(&liCount))
726 + ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to query performance counter");
727 +
728 + // create temp file name
729 + hr = StrAllocFormatted(ppwzTempFile, L"%sCPI%I64X.tmp", wzTempPath, liCount.QuadPart);
730 + ExitOnFailure(hr, "Failed to create temp file name string");
731 +
732 + hr = S_OK;
733 +
734 +LExit:
735 + return hr;
736 +}
737 +
738 +HRESULT CpiCreateId(
739 + LPWSTR pwzDest,
740 + SIZE_T cchDest
741 + )
742 +{
743 + HRESULT hr = S_OK;
744 +
745 + GUID guid;
746 +
747 + // create new guid
748 + hr = ::CoCreateGuid(&guid);
749 + ExitOnFailure(hr, "Failed to create new guid");
750 +
751 + // convert guid to string
752 + if (0 == ::StringFromGUID2(guid, pwzDest, (int)cchDest))
753 + ExitOnFailure(hr = E_FAIL, "Failed to convert guid to string");
754 +
755 + hr = S_OK;
756 +
757 +LExit:
758 + return hr;
759 +}
760 +
761 +BOOL CpiIsInstalled(
762 + INSTALLSTATE isInstalled
763 + )
764 +{
765 + return INSTALLSTATE_LOCAL == isInstalled || INSTALLSTATE_SOURCE == isInstalled;
766 +}
767 +
768 +BOOL CpiWillBeInstalled(
769 + INSTALLSTATE isInstalled,
770 + INSTALLSTATE isAction
771 + )
772 +{
773 + return WcaIsInstalling(isInstalled, isAction) ||
774 + (CpiIsInstalled(isInstalled) && !WcaIsUninstalling(isInstalled, isAction));
775 +}
776 +
777 +HRESULT PcaGuidToRegFormat(
778 + LPWSTR pwzGuid,
779 + LPWSTR pwzDest,
780 + SIZE_T cchDest
781 + )
782 +{
783 + HRESULT hr = S_OK;
784 +
785 + GUID guid = GUID_NULL;
786 + int cch = 0;
787 +
788 + WCHAR wz[39];
789 + ::ZeroMemory(wz, sizeof(wz));
790 +
791 + cch = lstrlenW(pwzGuid);
792 +
793 + if (38 == cch && L'{' == pwzGuid[0] && L'}' == pwzGuid[37])
794 + StringCchCopyW(wz, countof(wz), pwzGuid);
795 + else if (36 == cch)
796 + StringCchPrintfW(wz, countof(wz), L"{%s}", pwzGuid);
797 + else
798 + ExitFunction1(hr = E_INVALIDARG);
799 +
800 + // convert string to guid
801 + hr = ::CLSIDFromString(wz, &guid);
802 + ExitOnFailure(hr, "Failed to parse guid string");
803 +
804 + // convert guid to string
805 + if (0 == ::StringFromGUID2(guid, pwzDest, (int)cchDest))
806 + ExitOnFailure(hr = E_FAIL, "Failed to convert guid to string");
807 +
808 + hr = S_OK;
809 +
810 +LExit:
811 + return hr;
812 +}
813 +
814 +
815 +// helper function definitions
816 +
817 +static HRESULT FindPropertyDefinition(
818 + CPI_PROPERTY_DEFINITION* pPropDefList,
819 + LPCWSTR pwzName,
820 + CPI_PROPERTY_DEFINITION** ppPropDef
821 + )
822 +{
823 + for (CPI_PROPERTY_DEFINITION* pItm = pPropDefList; pItm->pwzName; pItm++)
824 + {
825 + if (0 == lstrcmpW(pItm->pwzName, pwzName))
826 + {
827 + *ppPropDef = pItm;
828 + return S_OK;
829 + }
830 + }
831 +
832 + return S_FALSE;
833 +}
834 +
835 +static HRESULT GetUserAccountName(
836 + LPCWSTR pwzKey,
837 + LPWSTR* ppwzAccount
838 + )
839 +{
840 + HRESULT hr = S_OK;
841 +
842 + PMSIHANDLE hView, hRecKey, hRec;
843 +
844 + LPWSTR pwzDomain = NULL;
845 + LPWSTR pwzName = NULL;
846 +
847 + // create parameter record
848 + hRecKey = ::MsiCreateRecord(1);
849 + ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
850 + hr = WcaSetRecordString(hRecKey, 1, pwzKey);
851 + ExitOnFailure(hr, "Failed to set record string");
852 +
853 + // open view
854 + hr = WcaOpenView(vcsUserQuery, &hView);
855 + ExitOnFailure(hr, "Failed to open view on User table");
856 + hr = WcaExecuteView(hView, hRecKey);
857 + ExitOnFailure(hr, "Failed to execute view on User table");
858 +
859 + // fetch record
860 + hr = WcaFetchSingleRecord(hView, &hRec);
861 + if (S_FALSE == hr)
862 + ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "User not found, key: %S", pwzKey);
863 + ExitOnFailure(hr, "Failed to fetch user record");
864 +
865 + // get user domain
866 + hr = WcaGetRecordFormattedString(hRec, uqDomain, &pwzDomain);
867 + ExitOnFailure(hr, "Failed to get domain");
868 +
869 + // get user name
870 + hr = WcaGetRecordFormattedString(hRec, uqName, &pwzName);
871 + ExitOnFailure(hr, "Failed to get name");
872 +
873 + // build account name
874 + hr = CpiBuildAccountName(pwzDomain, pwzName, ppwzAccount);
875 + ExitOnFailure(hr, "Failed to build account name");
876 +
877 + hr = S_OK;
878 +
879 +LExit:
880 + // clean up
881 + ReleaseStr(pwzDomain);
882 + ReleaseStr(pwzName);
883 +
884 + return hr;
885 +}
src/ca/cputilsched.h new
+144
@@ -0,0 +1,144 @@
1 +#pragma once
2 +// 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.
3 +
4 +
5 +#define CPI_MAX_GUID 38
6 +
7 +enum eRunMode { rmDeferred = 1, rmCommit, rmRollback };
8 +
9 +enum eActionType { atNoOp = 0, atCreate, atRemove };
10 +
11 +enum eComPlusPropertyType { cpptNone = 0, cpptBoolean, cpptInteger, cpptString, cpptUser };
12 +
13 +enum eComPlusTables
14 +{
15 + cptComPlusPartition = (1 << 0),
16 + cptComPlusPartitionProperty = (1 << 1),
17 + cptComPlusPartitionRole = (1 << 2),
18 + cptComPlusUserInPartitionRole = (1 << 3),
19 + cptComPlusGroupInPartitionRole = (1 << 4),
20 + cptComPlusPartitionUser = (1 << 5),
21 + cptComPlusApplication = (1 << 6),
22 + cptComPlusApplicationProperty = (1 << 7),
23 + cptComPlusApplicationRole = (1 << 8),
24 + cptComPlusApplicationRoleProperty = (1 << 9),
25 + cptComPlusUserInApplicationRole = (1 << 10),
26 + cptComPlusGroupInApplicationRole = (1 << 11),
27 + cptComPlusAssembly = (1 << 12),
28 + cptComPlusAssemblyDependency = (1 << 13),
29 + cptComPlusComponent = (1 << 14),
30 + cptComPlusComponentProperty = (1 << 15),
31 + cptComPlusRoleForComponent = (1 << 16),
32 + cptComPlusInterface = (1 << 17),
33 + cptComPlusInterfaceProperty = (1 << 18),
34 + cptComPlusRoleForInterface = (1 << 19),
35 + cptComPlusMethod = (1 << 20),
36 + cptComPlusMethodProperty = (1 << 21),
37 + cptComPlusRoleForMethod = (1 << 22),
38 + cptComPlusSubscription = (1 << 23),
39 + cptComPlusSubscriptionProperty = (1 << 24)
40 +};
41 +
42 +
43 +// structs
44 +
45 +struct CPI_PROPERTY
46 +{
47 + WCHAR wzName[MAX_DARWIN_KEY + 1];
48 + LPWSTR pwzValue;
49 +
50 + CPI_PROPERTY* pNext;
51 +};
52 +
53 +struct CPI_PROPERTY_DEFINITION
54 +{
55 + LPCWSTR pwzName;
56 + int iType;
57 + int iMinVersionNT;
58 +};
59 +
60 +
61 +// function prototypes
62 +
63 +void CpiInitialize();
64 +void CpiFinalize();
65 +BOOL CpiTableExists(
66 + int iTable
67 + );
68 +HRESULT CpiGetAdminCatalog(
69 + ICOMAdminCatalog** ppiCatalog
70 + );
71 +HRESULT CpiGetCatalogCollection(
72 + LPCWSTR pwzName,
73 + ICatalogCollection** ppiColl
74 + );
75 +HRESULT CpiGetCatalogCollection(
76 + ICatalogCollection* piColl,
77 + ICatalogObject* piObj,
78 + LPCWSTR pwzName,
79 + ICatalogCollection** ppiColl
80 + );
81 +HRESULT CpiGetKeyForObject(
82 + ICatalogObject* piObj,
83 + LPWSTR pwzKey,
84 + SIZE_T cchKey
85 + );
86 +HRESULT CpiFindCollectionObject(
87 + ICatalogCollection* piColl,
88 + LPCWSTR pwzID,
89 + LPCWSTR pwzName,
90 + ICatalogObject** ppiObj
91 + );
92 +HRESULT CpiGetPartitionsCollection(
93 + ICatalogCollection** ppiPartColl
94 + );
95 +HRESULT CpiGetApplicationsCollection(
96 + ICatalogCollection** ppiAppColl
97 + );
98 +HRESULT CpiAddActionTextToActionData(
99 + LPCWSTR pwzAction,
100 + LPWSTR* ppwzActionData
101 + );
102 +HRESULT CpiVerifyComponentArchitecure(
103 + LPCWSTR pwzComponent,
104 + BOOL* pfMatchingArchitecture
105 + );
106 +HRESULT CpiPropertiesRead(
107 + LPCWSTR pwzQuery,
108 + LPCWSTR pwzKey,
109 + CPI_PROPERTY_DEFINITION* pPropDefList,
110 + CPI_PROPERTY** ppPropList,
111 + int* piCount
112 + );
113 +void CpiPropertiesFreeList(
114 + CPI_PROPERTY* pList
115 + );
116 +HRESULT CpiAddPropertiesToActionData(
117 + int iPropCount,
118 + CPI_PROPERTY* pPropList,
119 + LPWSTR* ppwzActionData
120 + );
121 +HRESULT CpiBuildAccountName(
122 + LPCWSTR pwzDomain,
123 + LPCWSTR pwzName,
124 + LPWSTR* ppwzAccount
125 + );
126 +HRESULT CpiGetTempFileName(
127 + LPWSTR* ppwzTempFile
128 + );
129 +HRESULT CpiCreateId(
130 + LPWSTR pwzDest,
131 + SIZE_T cchDest
132 + );
133 +BOOL CpiIsInstalled(
134 + INSTALLSTATE isInstalled
135 + );
136 +BOOL CpiWillBeInstalled(
137 + INSTALLSTATE isInstalled,
138 + INSTALLSTATE isAction
139 + );
140 +HRESULT PcaGuidToRegFormat(
141 + LPWSTR pwzGuid,
142 + LPWSTR pwzDest,
143 + SIZE_T cchDest
144 + );
src/wixext/ComPlusCompiler.cs new
+2188
@@ -0,0 +1,2188 @@
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 +namespace WixToolset.Extensions
4 +{
5 + using System;
6 + using System.Collections;
7 + using System.Collections.Generic;
8 + using System.Globalization;
9 + using System.Reflection;
10 + using System.Xml;
11 + using System.Xml.Linq;
12 + using System.Xml.Schema;
13 + using WixToolset.Data;
14 + using WixToolset.Extensibility;
15 +
16 + /// <summary>
17 + /// The compiler for the WiX Toolset Internet Information Services Extension.
18 + /// </summary>
19 + public sealed class ComPlusCompiler : CompilerExtension
20 + {
21 + /// <summary>
22 + /// Instantiate a new ComPlusCompiler.
23 + /// </summary>
24 + public ComPlusCompiler()
25 + {
26 + this.Namespace = "http://wixtoolset.org/schemas/v4/wxs/complus";
27 + }
28 +
29 + /// <summary>
30 + /// </summary>
31 + /// <remarks></remarks>
32 + public enum CpiAssemblyAttributes
33 + {
34 + EventClass = (1 << 0),
35 + DotNetAssembly = (1 << 1),
36 + DllPathFromGAC = (1 << 2),
37 + RegisterInCommit = (1 << 3)
38 + }
39 +
40 + /// <summary>
41 + /// Processes an element for the Compiler.
42 + /// </summary>
43 + /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
44 + /// <param name="parentElement">Parent element of element to process.</param>
45 + /// <param name="element">Element to process.</param>
46 + /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
47 + public override void ParseElement(XElement parentElement, XElement element, IDictionary<string, string> context)
48 + {
49 + switch (parentElement.Name.LocalName)
50 + {
51 + case "Component":
52 + string componentId = context["ComponentId"];
53 + string directoryId = context["DirectoryId"];
54 + bool win64 = Boolean.Parse(context["Win64"]);
55 +
56 + switch (element.Name.LocalName)
57 + {
58 + case "ComPlusPartition":
59 + this.ParseComPlusPartitionElement(element, componentId, win64);
60 + break;
61 + case "ComPlusPartitionRole":
62 + this.ParseComPlusPartitionRoleElement(element, componentId, null);
63 + break;
64 + case "ComPlusUserInPartitionRole":
65 + this.ParseComPlusUserInPartitionRoleElement(element, componentId, null);
66 + break;
67 + case "ComPlusGroupInPartitionRole":
68 + this.ParseComPlusGroupInPartitionRoleElement(element, componentId, null);
69 + break;
70 + case "ComPlusPartitionUser":
71 + this.ParseComPlusPartitionUserElement(element, componentId, null);
72 + break;
73 + case "ComPlusApplication":
74 + this.ParseComPlusApplicationElement(element, componentId, win64, null);
75 + break;
76 + case "ComPlusApplicationRole":
77 + this.ParseComPlusApplicationRoleElement(element, componentId, null);
78 + break;
79 + case "ComPlusUserInApplicationRole":
80 + this.ParseComPlusUserInApplicationRoleElement(element, componentId, null);
81 + break;
82 + case "ComPlusGroupInApplicationRole":
83 + this.ParseComPlusGroupInApplicationRoleElement(element, componentId, null);
84 + break;
85 + case "ComPlusAssembly":
86 + this.ParseComPlusAssemblyElement(element, componentId, win64, null);
87 + break;
88 + case "ComPlusRoleForComponent":
89 + this.ParseComPlusRoleForComponentElement(element, componentId, null);
90 + break;
91 + case "ComPlusRoleForInterface":
92 + this.ParseComPlusRoleForInterfaceElement(element, componentId, null);
93 + break;
94 + case "ComPlusRoleForMethod":
95 + this.ParseComPlusRoleForMethodElement(element, componentId, null);
96 + break;
97 + case "ComPlusSubscription":
98 + this.ParseComPlusSubscriptionElement(element, componentId, null);
99 + break;
100 + default:
101 + this.Core.UnexpectedElement(parentElement, element);
102 + break;
103 + }
104 + break;
105 + case "Fragment":
106 + case "Module":
107 + case "Product":
108 + switch (element.Name.LocalName)
109 + {
110 + case "ComPlusPartition":
111 + this.ParseComPlusPartitionElement(element, null, false);
112 + break;
113 + case "ComPlusPartitionRole":
114 + this.ParseComPlusPartitionRoleElement(element, null, null);
115 + break;
116 + case "ComPlusApplication":
117 + this.ParseComPlusApplicationElement(element, null, false, null);
118 + break;
119 + case "ComPlusApplicationRole":
120 + this.ParseComPlusApplicationRoleElement(element, null, null);
121 + break;
122 + default:
123 + this.Core.UnexpectedElement(parentElement, element);
124 + break;
125 + }
126 + break;
127 + default:
128 + this.Core.UnexpectedElement(parentElement, element);
129 + break;
130 + }
131 + }
132 +
133 + /// <summary>
134 + /// Parses a COM+ partition element.
135 + /// </summary>
136 + /// <param name="node">Element to parse.</param>
137 + /// <param name="componentKey">Identifier of parent component.</param>
138 + private void ParseComPlusPartitionElement(XElement node, string componentKey, bool win64)
139 + {
140 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
141 +
142 + string key = null;
143 + string id = null;
144 + string name = null;
145 +
146 + Hashtable properties = new Hashtable();
147 +
148 + foreach (XAttribute attrib in node.Attributes())
149 + {
150 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
151 + {
152 + switch (attrib.Name.LocalName)
153 + {
154 + case "Id":
155 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
156 + break;
157 + case "PartitionId":
158 + id = TryFormatGuidValue(this.Core.GetAttributeValue(sourceLineNumbers, attrib));
159 + break;
160 + case "Name":
161 + name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
162 + break;
163 + case "Changeable":
164 + this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
165 + break;
166 + case "Deleteable":
167 + if (null == componentKey)
168 + {
169 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
170 + }
171 + properties["Deleteable"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
172 + break;
173 + case "Description":
174 + if (null == componentKey)
175 + {
176 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
177 + }
178 + properties["Description"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
179 + break;
180 + default:
181 + this.Core.UnexpectedAttribute(node, attrib);
182 + break;
183 + }
184 + }
185 + else
186 + {
187 + this.Core.ParseExtensionAttribute(node, attrib);
188 + }
189 + }
190 +
191 + if (null != componentKey && null == name)
192 + {
193 + this.Core.OnMessage(ComPlusErrors.RequiredAttributeUnderComponent(sourceLineNumbers, node.Name.LocalName, "Name"));
194 + }
195 + if (null == componentKey && null == id && null == name)
196 + {
197 + this.Core.OnMessage(ComPlusErrors.RequiredAttributeNotUnderComponent(sourceLineNumbers, node.Name.LocalName, "Id", "Name"));
198 + }
199 +
200 + foreach (XElement child in node.Elements())
201 + {
202 + if (this.Namespace == child.Name.Namespace)
203 + {
204 + switch (child.Name.LocalName)
205 + {
206 + case "ComPlusPartitionRole":
207 + this.ParseComPlusPartitionRoleElement(child, componentKey, key);
208 + break;
209 + case "ComPlusPartitionUser":
210 + this.ParseComPlusPartitionUserElement(child, componentKey, key);
211 + break;
212 + case "ComPlusApplication":
213 + this.ParseComPlusApplicationElement(child, componentKey, win64, key);
214 + break;
215 + default:
216 + this.Core.UnexpectedElement(node, child);
217 + break;
218 + }
219 + }
220 + else
221 + {
222 + this.Core.ParseExtensionElement(node, child);
223 + }
224 + }
225 +
226 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusPartition");
227 + row[0] = key;
228 + row[1] = componentKey;
229 + row[2] = id;
230 + row[3] = name;
231 +
232 + IDictionaryEnumerator propertiesEnumerator = properties.GetEnumerator();
233 + while (propertiesEnumerator.MoveNext())
234 + {
235 + Row propertyRow = this.Core.CreateRow(sourceLineNumbers, "ComPlusPartitionProperty");
236 + propertyRow[0] = key;
237 + propertyRow[1] = (string)propertiesEnumerator.Key;
238 + propertyRow[2] = (string)propertiesEnumerator.Value;
239 + }
240 +
241 + if (componentKey != null)
242 + {
243 + if (win64)
244 + {
245 + if (this.Core.CurrentPlatform == Platform.IA64)
246 + {
247 + this.Core.OnMessage(WixErrors.UnsupportedPlatformForElement(sourceLineNumbers, "ia64", node.Name.LocalName));
248 + }
249 + else
250 + {
251 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusInstall_x64");
252 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusUninstall_x64");
253 + }
254 + }
255 + else
256 + {
257 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusInstall");
258 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusUninstall");
259 + }
260 + }
261 + }
262 +
263 + /// <summary>
264 + /// Parses a COM+ partition role element.
265 + /// </summary>
266 + /// <param name="node">Element to parse.</param>
267 + /// <param name="componentKey">Identifier of parent component.</param>
268 + /// <param name="applicationKey">Optional identifier of parent application.</param>
269 + private void ParseComPlusPartitionRoleElement(XElement node, string componentKey, string partitionKey)
270 + {
271 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
272 +
273 + string key = null;
274 + string name = null;
275 +
276 + foreach (XAttribute attrib in node.Attributes())
277 + {
278 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
279 + {
280 + switch (attrib.Name.LocalName)
281 + {
282 + case "Id":
283 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
284 + break;
285 + case "Partition":
286 + if (null != partitionKey)
287 + {
288 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
289 + }
290 + partitionKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
291 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusPartition", partitionKey);
292 + break;
293 + case "Name":
294 + name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
295 + break;
296 + default:
297 + this.Core.UnexpectedAttribute(node, attrib);
298 + break;
299 + }
300 + }
301 + else
302 + {
303 + this.Core.ParseExtensionAttribute(node, attrib);
304 + }
305 + }
306 +
307 + if (null == partitionKey)
308 + {
309 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Partition"));
310 + }
311 +
312 + foreach (XElement child in node.Elements())
313 + {
314 + if (this.Namespace == child.Name.Namespace)
315 + {
316 + switch (child.Name.LocalName)
317 + {
318 + case "ComPlusUserInPartitionRole":
319 + this.ParseComPlusUserInPartitionRoleElement(child, componentKey, key);
320 + break;
321 + case "ComPlusGroupInPartitionRole":
322 + this.ParseComPlusGroupInPartitionRoleElement(child, componentKey, key);
323 + break;
324 + default:
325 + this.Core.UnexpectedElement(node, child);
326 + break;
327 + }
328 + }
329 + else
330 + {
331 + this.Core.ParseExtensionElement(node, child);
332 + }
333 + }
334 +
335 + // add table row
336 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusPartitionRole");
337 + row[0] = key;
338 + row[1] = partitionKey;
339 + row[3] = name;
340 + }
341 +
342 + /// <summary>
343 + /// Parses a COM+ partition role user element.
344 + /// </summary>
345 + /// <param name="node">Element to parse.</param>
346 + /// <param name="componentKey">Identifier of parent component.</param>
347 + /// <param name="applicationKey">Optional identifier of parent application role.</param>
348 + private void ParseComPlusUserInPartitionRoleElement(XElement node, string componentKey, string partitionRoleKey)
349 + {
350 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
351 +
352 + string key = null;
353 + string user = null;
354 +
355 + foreach (XAttribute attrib in node.Attributes())
356 + {
357 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
358 + {
359 + switch (attrib.Name.LocalName)
360 + {
361 + case "Id":
362 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
363 + break;
364 + case "PartitionRole":
365 + if (null != partitionRoleKey)
366 + {
367 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
368 + }
369 + partitionRoleKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
370 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusPartitionRole", partitionRoleKey);
371 + break;
372 + case "User":
373 + user = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
374 + this.Core.CreateSimpleReference(sourceLineNumbers, "User", user);
375 + break;
376 + default:
377 + this.Core.UnexpectedAttribute(node, attrib);
378 + break;
379 + }
380 + }
381 + else
382 + {
383 + this.Core.ParseExtensionAttribute(node, attrib);
384 + }
385 + }
386 +
387 + if (null == partitionRoleKey)
388 + {
389 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PartitionRole"));
390 + }
391 +
392 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusUserInPartitionRole");
393 + row[0] = key;
394 + row[1] = partitionRoleKey;
395 + row[2] = componentKey;
396 + row[3] = user;
397 + }
398 +
399 + /// <summary>
400 + /// Parses a COM+ partition role user element.
401 + /// </summary>
402 + /// <param name="node">Element to parse.</param>
403 + /// <param name="componentKey">Identifier of parent component.</param>
404 + /// <param name="applicationKey">Optional identifier of parent application role.</param>
405 + private void ParseComPlusGroupInPartitionRoleElement(XElement node, string componentKey, string partitionRoleKey)
406 + {
407 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
408 +
409 + string key = null;
410 + string group = null;
411 +
412 + foreach (XAttribute attrib in node.Attributes())
413 + {
414 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
415 + {
416 + switch (attrib.Name.LocalName)
417 + {
418 + case "Id":
419 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
420 + break;
421 + case "PartitionRole":
422 + if (null != partitionRoleKey)
423 + {
424 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
425 + }
426 + partitionRoleKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
427 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusPartitionRole", partitionRoleKey);
428 + break;
429 + case "Group":
430 + group = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
431 + this.Core.CreateSimpleReference(sourceLineNumbers, "Group", group);
432 + break;
433 + default:
434 + this.Core.UnexpectedAttribute(node, attrib);
435 + break;
436 + }
437 + }
438 + else
439 + {
440 + this.Core.ParseExtensionAttribute(node, attrib);
441 + }
442 + }
443 +
444 + if (null == partitionRoleKey)
445 + {
446 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PartitionRole"));
447 + }
448 +
449 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusGroupInPartitionRole");
450 + row[0] = key;
451 + row[1] = partitionRoleKey;
452 + row[2] = componentKey;
453 + row[3] = group;
454 + }
455 +
456 + /// <summary>
457 + /// Parses a COM+ partition element.
458 + /// </summary>
459 + /// <param name="node">Element to parse.</param>
460 + /// <param name="componentKey">Identifier of parent component.</param>
461 + private void ParseComPlusPartitionUserElement(XElement node, string componentKey, string partitionKey)
462 + {
463 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
464 +
465 + string key = null;
466 + string user = null;
467 +
468 + foreach (XAttribute attrib in node.Attributes())
469 + {
470 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
471 + {
472 + switch (attrib.Name.LocalName)
473 + {
474 + case "Id":
475 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
476 + break;
477 + case "Partition":
478 + if (null != partitionKey)
479 + {
480 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
481 + }
482 + partitionKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
483 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusPartition", partitionKey);
484 + break;
485 + case "User":
486 + user = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
487 + this.Core.CreateSimpleReference(sourceLineNumbers, "User", user);
488 + break;
489 + default:
490 + this.Core.UnexpectedAttribute(node, attrib);
491 + break;
492 + }
493 + }
494 + else
495 + {
496 + this.Core.ParseExtensionAttribute(node, attrib);
497 + }
498 + }
499 +
500 + if (null == partitionKey)
501 + {
502 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Partition"));
503 + }
504 +
505 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusPartitionUser");
506 + row[0] = key;
507 + row[1] = partitionKey;
508 + row[2] = componentKey;
509 + row[3] = user;
510 + }
511 +
512 + /// <summary>
513 + /// Parses a COM+ application element.
514 + /// </summary>
515 + /// <param name="node">Element to parse.</param>
516 + /// <param name="componentKey">Identifier of parent component.</param>
517 + /// <param name="partitionKey">Optional identifier of parent partition.</param>
518 + private void ParseComPlusApplicationElement(XElement node, string componentKey, bool win64, string partitionKey)
519 + {
520 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
521 +
522 + string key = null;
523 + string id = null;
524 + string name = null;
525 +
526 + Hashtable properties = new Hashtable();
527 +
528 + foreach (XAttribute attrib in node.Attributes())
529 + {
530 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
531 + {
532 + switch (attrib.Name.LocalName)
533 + {
534 + case "Id":
535 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
536 + break;
537 + case "Partition":
538 + if (null != partitionKey)
539 + {
540 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
541 + }
542 + partitionKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
543 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusPartition", partitionKey);
544 + break;
545 + case "ApplicationId":
546 + id = TryFormatGuidValue(this.Core.GetAttributeValue(sourceLineNumbers, attrib));
547 + break;
548 + case "Name":
549 + name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
550 + break;
551 + case "ThreeGigSupportEnabled":
552 + if (null == componentKey)
553 + {
554 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
555 + }
556 + properties["3GigSupportEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
557 + break;
558 + case "AccessChecksLevel":
559 + if (null == componentKey)
560 + {
561 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
562 + }
563 + string accessChecksLevelValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
564 + switch (accessChecksLevelValue)
565 + {
566 + case "applicationLevel":
567 + properties["AccessChecksLevel"] = "0";
568 + break;
569 + case "applicationComponentLevel":
570 + properties["AccessChecksLevel"] = "1";
571 + break;
572 + default:
573 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "AccessChecksLevel", accessChecksLevelValue, "applicationLevel", "applicationComponentLevel"));
574 + break;
575 + }
576 + break;
577 + case "Activation":
578 + if (null == componentKey)
579 + {
580 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
581 + }
582 + string activationValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
583 + switch (activationValue)
584 + {
585 + case "inproc":
586 + properties["Activation"] = "Inproc";
587 + break;
588 + case "local":
589 + properties["Activation"] = "Local";
590 + break;
591 + default:
592 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "Activation", activationValue, "inproc", "local"));
593 + break;
594 + }
595 + break;
596 + case "ApplicationAccessChecksEnabled":
597 + if (null == componentKey)
598 + {
599 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
600 + }
601 + properties["ApplicationAccessChecksEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
602 + break;
603 + case "ApplicationDirectory":
604 + if (null == componentKey)
605 + {
606 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
607 + }
608 + properties["ApplicationDirectory"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
609 + break;
610 + case "Authentication":
611 + if (null == componentKey)
612 + {
613 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
614 + }
615 + string authenticationValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
616 + switch (authenticationValue)
617 + {
618 + case "default":
619 + properties["Authentication"] = "0";
620 + break;
621 + case "none":
622 + properties["Authentication"] = "1";
623 + break;
624 + case "connect":
625 + properties["Authentication"] = "2";
626 + break;
627 + case "call":
628 + properties["Authentication"] = "3";
629 + break;
630 + case "packet":
631 + properties["Authentication"] = "4";
632 + break;
633 + case "integrity":
634 + properties["Authentication"] = "5";
635 + break;
636 + case "privacy":
637 + properties["Authentication"] = "6";
638 + break;
639 + default:
640 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "Authentication", authenticationValue, "default", "none", "connect", "call", "packet", "integrity", "privacy"));
641 + break;
642 + }
643 + break;
644 + case "AuthenticationCapability":
645 + if (null == componentKey)
646 + {
647 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
648 + }
649 + string authenticationCapabilityValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
650 + switch (authenticationCapabilityValue)
651 + {
652 + case "none":
653 + properties["AuthenticationCapability"] = "0";
654 + break;
655 + case "secureReference":
656 + properties["AuthenticationCapability"] = "2";
657 + break;
658 + case "staticCloaking":
659 + properties["AuthenticationCapability"] = "32";
660 + break;
661 + case "dynamicCloaking":
662 + properties["AuthenticationCapability"] = "64";
663 + break;
664 + default:
665 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "AuthenticationCapability", authenticationCapabilityValue, "none", "secureReference", "staticCloaking", "dynamicCloaking"));
666 + break;
667 + }
668 + break;
669 + case "Changeable":
670 + this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
671 + break;
672 + case "CommandLine":
673 + if (null == componentKey)
674 + {
675 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
676 + }
677 + properties["CommandLine"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
678 + break;
679 + case "ConcurrentApps":
680 + if (null == componentKey)
681 + {
682 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
683 + }
684 + properties["ConcurrentApps"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
685 + break;
686 + case "CreatedBy":
687 + if (null == componentKey)
688 + {
689 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
690 + }
691 + properties["CreatedBy"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
692 + break;
693 + case "CRMEnabled":
694 + if (null == componentKey)
695 + {
696 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
697 + }
698 + properties["CRMEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
699 + break;
700 + case "CRMLogFile":
701 + if (null == componentKey)
702 + {
703 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
704 + }
705 + properties["CRMLogFile"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
706 + break;
707 + case "Deleteable":
708 + if (null == componentKey)
709 + {
710 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
711 + }
712 + properties["Deleteable"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
713 + break;
714 + case "Description":
715 + if (null == componentKey)
716 + {
717 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
718 + }
719 + properties["Description"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
720 + break;
721 + case "DumpEnabled":
722 + if (null == componentKey)
723 + {
724 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
725 + }
726 + properties["DumpEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
727 + break;
728 + case "DumpOnException":
729 + if (null == componentKey)
730 + {
731 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
732 + }
733 + properties["DumpOnException"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
734 + break;
735 + case "DumpOnFailfast":
736 + if (null == componentKey)
737 + {
738 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
739 + }
740 + properties["DumpOnFailfast"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
741 + break;
742 + case "DumpPath":
743 + if (null == componentKey)
744 + {
745 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
746 + }
747 + properties["DumpPath"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
748 + break;
749 + case "EventsEnabled":
750 + if (null == componentKey)
751 + {
752 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
753 + }
754 + properties["EventsEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
755 + break;
756 + case "Identity":
757 + if (null == componentKey)
758 + {
759 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
760 + }
761 + properties["Identity"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
762 + break;
763 + case "ImpersonationLevel":
764 + if (null == componentKey)
765 + {
766 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
767 + }
768 + string impersonationLevelValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
769 + switch (impersonationLevelValue)
770 + {
771 + case "anonymous":
772 + properties["ImpersonationLevel"] = "1";
773 + break;
774 + case "identify":
775 + properties["ImpersonationLevel"] = "2";
776 + break;
777 + case "impersonate":
778 + properties["ImpersonationLevel"] = "3";
779 + break;
780 + case "delegate":
781 + properties["ImpersonationLevel"] = "4";
782 + break;
783 + default:
784 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "ImpersonationLevel", impersonationLevelValue, "anonymous", "identify", "impersonate", "delegate"));
785 + break;
786 + }
787 + break;
788 + case "IsEnabled":
789 + if (null == componentKey)
790 + {
791 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
792 + }
793 + properties["IsEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
794 + break;
795 + case "MaxDumpCount":
796 + if (null == componentKey)
797 + {
798 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
799 + }
800 + properties["MaxDumpCount"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
801 + break;
802 + case "Password":
803 + if (null == componentKey)
804 + {
805 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
806 + }
807 + properties["Password"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
808 + break;
809 + case "QCAuthenticateMsgs":
810 + if (null == componentKey)
811 + {
812 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
813 + }
814 + string qcAuthenticateMsgsValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
815 + switch (qcAuthenticateMsgsValue)
816 + {
817 + case "secureApps":
818 + properties["QCAuthenticateMsgs"] = "0";
819 + break;
820 + case "off":
821 + properties["QCAuthenticateMsgs"] = "1";
822 + break;
823 + case "on":
824 + properties["QCAuthenticateMsgs"] = "2";
825 + break;
826 + default:
827 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "QCAuthenticateMsgs", qcAuthenticateMsgsValue, "secureApps", "off", "on"));
828 + break;
829 + }
830 + break;
831 + case "QCListenerMaxThreads":
832 + if (null == componentKey)
833 + {
834 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
835 + }
836 + properties["QCListenerMaxThreads"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
837 + break;
838 + case "QueueListenerEnabled":
839 + if (null == componentKey)
840 + {
841 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
842 + }
843 + properties["QueueListenerEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
844 + break;
845 + case "QueuingEnabled":
846 + if (null == componentKey)
847 + {
848 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
849 + }
850 + properties["QueuingEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
851 + break;
852 + case "RecycleActivationLimit":
853 + if (null == componentKey)
854 + {
855 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
856 + }
857 + properties["RecycleActivationLimit"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
858 + break;
859 + case "RecycleCallLimit":
860 + if (null == componentKey)
861 + {
862 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
863 + }
864 + properties["RecycleCallLimit"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
865 + break;
866 + case "RecycleExpirationTimeout":
867 + if (null == componentKey)
868 + {
869 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
870 + }
871 + properties["RecycleExpirationTimeout"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
872 + break;
873 + case "RecycleLifetimeLimit":
874 + if (null == componentKey)
875 + {
876 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
877 + }
878 + properties["RecycleLifetimeLimit"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
879 + break;
880 + case "RecycleMemoryLimit":
881 + if (null == componentKey)
882 + {
883 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
884 + }
885 + properties["RecycleMemoryLimit"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
886 + break;
887 + case "Replicable":
888 + if (null == componentKey)
889 + {
890 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
891 + }
892 + properties["Replicable"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
893 + break;
894 + case "RunForever":
895 + if (null == componentKey)
896 + {
897 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
898 + }
899 + properties["RunForever"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
900 + break;
901 + case "ShutdownAfter":
902 + if (null == componentKey)
903 + {
904 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
905 + }
906 + properties["ShutdownAfter"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
907 + break;
908 + case "SoapActivated":
909 + if (null == componentKey)
910 + {
911 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
912 + }
913 + properties["SoapActivated"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
914 + break;
915 + case "SoapBaseUrl":
916 + if (null == componentKey)
917 + {
918 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
919 + }
920 + properties["SoapBaseUrl"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
921 + break;
922 + case "SoapMailTo":
923 + if (null == componentKey)
924 + {
925 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
926 + }
927 + properties["SoapMailTo"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
928 + break;
929 + case "SoapVRoot":
930 + if (null == componentKey)
931 + {
932 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
933 + }
934 + properties["SoapVRoot"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
935 + break;
936 + case "SRPEnabled":
937 + if (null == componentKey)
938 + {
939 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
940 + }
941 + properties["SRPEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
942 + break;
943 + case "SRPTrustLevel":
944 + if (null == componentKey)
945 + {
946 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
947 + }
948 + string srpTrustLevelValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
949 + switch (srpTrustLevelValue)
950 + {
951 + case "disallowed":
952 + properties["SRPTrustLevel"] = "0";
953 + break;
954 + case "fullyTrusted":
955 + properties["SRPTrustLevel"] = "262144";
956 + break;
957 + default:
958 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "SRPTrustLevel", srpTrustLevelValue, "disallowed", "fullyTrusted"));
959 + break;
960 + }
961 + break;
962 + default:
963 + this.Core.UnexpectedAttribute(node, attrib);
964 + break;
965 + }
966 + }
967 + else
968 + {
969 + this.Core.ParseExtensionAttribute(node, attrib);
970 + }
971 + }
972 +
973 + if (null != componentKey && null == name)
974 + {
975 + this.Core.OnMessage(ComPlusErrors.RequiredAttributeUnderComponent(sourceLineNumbers, node.Name.LocalName, "Name"));
976 + }
977 + if (null == componentKey && null == id && null == name)
978 + {
979 + this.Core.OnMessage(ComPlusErrors.RequiredAttributeNotUnderComponent(sourceLineNumbers, node.Name.LocalName, "Id", "Name"));
980 + }
981 +
982 + foreach (XElement child in node.Elements())
983 + {
984 + if (this.Namespace == child.Name.Namespace)
985 + {
986 + switch (child.Name.LocalName)
987 + {
988 + case "ComPlusApplicationRole":
989 + this.ParseComPlusApplicationRoleElement(child, componentKey, key);
990 + break;
991 + case "ComPlusAssembly":
992 + this.ParseComPlusAssemblyElement(child, componentKey, win64, key);
993 + break;
994 + default:
995 + this.Core.UnexpectedElement(node, child);
996 + break;
997 + }
998 + }
999 + else
1000 + {
1001 + this.Core.ParseExtensionElement(node, child);
1002 + }
1003 + }
1004 +
1005 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusApplication");
1006 + row[0] = key;
1007 + row[1] = partitionKey;
1008 + row[2] = componentKey;
1009 + row[3] = id;
1010 + row[4] = name;
1011 +
1012 + IDictionaryEnumerator propertiesEnumerator = properties.GetEnumerator();
1013 + while (propertiesEnumerator.MoveNext())
1014 + {
1015 + Row propertyRow = this.Core.CreateRow(sourceLineNumbers, "ComPlusApplicationProperty");
1016 + propertyRow[0] = key;
1017 + propertyRow[1] = (string)propertiesEnumerator.Key;
1018 + propertyRow[2] = (string)propertiesEnumerator.Value;
1019 + }
1020 +
1021 + if (componentKey != null)
1022 + {
1023 + if (win64)
1024 + {
1025 + if (this.Core.CurrentPlatform == Platform.IA64)
1026 + {
1027 + this.Core.OnMessage(WixErrors.UnsupportedPlatformForElement(sourceLineNumbers, "ia64", node.Name.LocalName));
1028 + }
1029 + else
1030 + {
1031 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusInstall_x64");
1032 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusUninstall_x64");
1033 + }
1034 + }
1035 + else
1036 + {
1037 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusInstall");
1038 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusUninstall");
1039 + }
1040 + }
1041 + }
1042 +
1043 + /// <summary>
1044 + /// Parses a COM+ application role element.
1045 + /// </summary>
1046 + /// <param name="node">Element to parse.</param>
1047 + /// <param name="componentKey">Identifier of parent component.</param>
1048 + /// <param name="applicationKey">Optional identifier of parent application.</param>
1049 + private void ParseComPlusApplicationRoleElement(XElement node, string componentKey, string applicationKey)
1050 + {
1051 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1052 +
1053 + string key = null;
1054 + string name = null;
1055 +
1056 + Hashtable properties = new Hashtable();
1057 +
1058 + foreach (XAttribute attrib in node.Attributes())
1059 + {
1060 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1061 + {
1062 + switch (attrib.Name.LocalName)
1063 + {
1064 + case "Id":
1065 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1066 + break;
1067 + case "Application":
1068 + if (null != applicationKey)
1069 + {
1070 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1071 + }
1072 + applicationKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1073 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusApplication", applicationKey);
1074 + break;
1075 + case "Name":
1076 + name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1077 + break;
1078 + case "Description":
1079 + if (null == componentKey)
1080 + {
1081 + this.Core.OnMessage(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
1082 + }
1083 + properties["Description"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1084 + break;
1085 + default:
1086 + this.Core.UnexpectedAttribute(node, attrib);
1087 + break;
1088 + }
1089 + }
1090 + else
1091 + {
1092 + this.Core.ParseExtensionAttribute(node, attrib);
1093 + }
1094 + }
1095 +
1096 + if (null == applicationKey)
1097 + {
1098 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Application"));
1099 + }
1100 +
1101 + foreach (XElement child in node.Elements())
1102 + {
1103 + if (this.Namespace == child.Name.Namespace)
1104 + {
1105 + switch (child.Name.LocalName)
1106 + {
1107 + case "ComPlusUserInApplicationRole":
1108 + this.ParseComPlusUserInApplicationRoleElement(child, componentKey, key);
1109 + break;
1110 + case "ComPlusGroupInApplicationRole":
1111 + this.ParseComPlusGroupInApplicationRoleElement(child, componentKey, key);
1112 + break;
1113 + default:
1114 + this.Core.UnexpectedElement(node, child);
1115 + break;
1116 + }
1117 + }
1118 + else
1119 + {
1120 + this.Core.ParseExtensionElement(node, child);
1121 + }
1122 + }
1123 +
1124 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusApplicationRole");
1125 + row[0] = key;
1126 + row[1] = applicationKey;
1127 + row[2] = componentKey;
1128 + row[3] = name;
1129 +
1130 + IDictionaryEnumerator propertiesEnumerator = properties.GetEnumerator();
1131 + while (propertiesEnumerator.MoveNext())
1132 + {
1133 + Row propertyRow = this.Core.CreateRow(sourceLineNumbers, "ComPlusApplicationRoleProperty");
1134 + propertyRow[0] = key;
1135 + propertyRow[1] = (string)propertiesEnumerator.Key;
1136 + propertyRow[2] = (string)propertiesEnumerator.Value;
1137 + }
1138 + }
1139 +
1140 + /// <summary>
1141 + /// Parses a COM+ application role user element.
1142 + /// </summary>
1143 + /// <param name="node">Element to parse.</param>
1144 + /// <param name="componentKey">Identifier of parent component.</param>
1145 + /// <param name="applicationKey">Optional identifier of parent application role.</param>
1146 + private void ParseComPlusUserInApplicationRoleElement(XElement node, string componentKey, string applicationRoleKey)
1147 + {
1148 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1149 +
1150 + string key = null;
1151 + string user = null;
1152 +
1153 + foreach (XAttribute attrib in node.Attributes())
1154 + {
1155 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1156 + {
1157 + switch (attrib.Name.LocalName)
1158 + {
1159 + case "Id":
1160 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1161 + break;
1162 + case "ApplicationRole":
1163 + if (null != applicationRoleKey)
1164 + {
1165 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1166 + }
1167 + applicationRoleKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1168 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusApplicationRole", applicationRoleKey);
1169 + break;
1170 + case "User":
1171 + user = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1172 + this.Core.CreateSimpleReference(sourceLineNumbers, "User", user);
1173 + break;
1174 + default:
1175 + this.Core.UnexpectedAttribute(node, attrib);
1176 + break;
1177 + }
1178 + }
1179 + else
1180 + {
1181 + this.Core.ParseExtensionAttribute(node, attrib);
1182 + }
1183 + }
1184 +
1185 + if (null == applicationRoleKey)
1186 + {
1187 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ApplicationRole"));
1188 + }
1189 +
1190 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusUserInApplicationRole");
1191 + row[0] = key;
1192 + row[1] = applicationRoleKey;
1193 + row[2] = componentKey;
1194 + row[3] = user;
1195 + }
1196 +
1197 + /// <summary>
1198 + /// Parses a COM+ application role group element.
1199 + /// </summary>
1200 + /// <param name="node">Element to parse.</param>
1201 + /// <param name="componentKey">Identifier of parent component.</param>
1202 + /// <param name="applicationKey">Optional identifier of parent application role.</param>
1203 + private void ParseComPlusGroupInApplicationRoleElement(XElement node, string componentKey, string applicationRoleKey)
1204 + {
1205 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1206 +
1207 + string key = null;
1208 + string group = null;
1209 +
1210 + foreach (XAttribute attrib in node.Attributes())
1211 + {
1212 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1213 + {
1214 + switch (attrib.Name.LocalName)
1215 + {
1216 + case "Id":
1217 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1218 + break;
1219 + case "ApplicationRole":
1220 + if (null != applicationRoleKey)
1221 + {
1222 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1223 + }
1224 + applicationRoleKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1225 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusApplicationRole", applicationRoleKey);
1226 + break;
1227 + case "Group":
1228 + group = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1229 + this.Core.CreateSimpleReference(sourceLineNumbers, "Group", group);
1230 + break;
1231 + default:
1232 + this.Core.UnexpectedAttribute(node, attrib);
1233 + break;
1234 + }
1235 + }
1236 + else
1237 + {
1238 + this.Core.ParseExtensionAttribute(node, attrib);
1239 + }
1240 + }
1241 +
1242 + if (null == applicationRoleKey)
1243 + {
1244 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ApplicationRole"));
1245 + }
1246 +
1247 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusGroupInApplicationRole");
1248 + row[0] = key;
1249 + row[1] = applicationRoleKey;
1250 + row[2] = componentKey;
1251 + row[3] = group;
1252 + }
1253 +
1254 + /// <summary>
1255 + /// Parses a COM+ assembly element.
1256 + /// </summary>
1257 + /// <param name="node">Element to parse.</param>
1258 + /// <param name="componentKey">Identifier of parent component.</param>
1259 + /// <param name="applicationKey">Optional identifier of parent application.</param>
1260 + private void ParseComPlusAssemblyElement(XElement node, string componentKey, bool win64, string applicationKey)
1261 + {
1262 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1263 +
1264 + string key = null;
1265 + string assemblyName = null;
1266 + string dllPath = null;
1267 + string tlbPath = null;
1268 + string psDllPath = null;
1269 + int attributes = 0;
1270 +
1271 + bool hasComponents = false;
1272 +
1273 + foreach (XAttribute attrib in node.Attributes())
1274 + {
1275 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1276 + {
1277 + switch (attrib.Name.LocalName)
1278 + {
1279 + case "Id":
1280 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1281 + break;
1282 + case "Application":
1283 + if (null != applicationKey)
1284 + {
1285 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1286 + }
1287 + applicationKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1288 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusApplication", applicationKey);
1289 + break;
1290 + case "AssemblyName":
1291 + assemblyName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1292 + break;
1293 + case "DllPath":
1294 + dllPath = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1295 + break;
1296 + case "TlbPath":
1297 + tlbPath = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1298 + break;
1299 + case "PSDllPath":
1300 + psDllPath = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1301 + break;
1302 + case "Type":
1303 + string typeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1304 + switch (typeValue)
1305 + {
1306 + case ".net":
1307 + attributes |= (int)CpiAssemblyAttributes.DotNetAssembly;
1308 + break;
1309 + case "native":
1310 + attributes &= ~(int)CpiAssemblyAttributes.DotNetAssembly;
1311 + break;
1312 + default:
1313 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "ComPlusAssembly", "Type", typeValue, ".net", "native"));
1314 + break;
1315 + }
1316 + break;
1317 + case "EventClass":
1318 + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1319 + {
1320 + attributes |= (int)CpiAssemblyAttributes.EventClass;
1321 + }
1322 + else
1323 + {
1324 + attributes &= ~(int)CpiAssemblyAttributes.EventClass;
1325 + }
1326 + break;
1327 + case "DllPathFromGAC":
1328 + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1329 + {
1330 + attributes |= (int)CpiAssemblyAttributes.DllPathFromGAC;
1331 + }
1332 + else
1333 + {
1334 + attributes &= ~(int)CpiAssemblyAttributes.DllPathFromGAC;
1335 + }
1336 + break;
1337 + case "RegisterInCommit":
1338 + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1339 + {
1340 + attributes |= (int)CpiAssemblyAttributes.RegisterInCommit;
1341 + }
1342 + else
1343 + {
1344 + attributes &= ~(int)CpiAssemblyAttributes.RegisterInCommit;
1345 + }
1346 + break;
1347 + default:
1348 + this.Core.UnexpectedAttribute(node, attrib);
1349 + break;
1350 + }
1351 + }
1352 + else
1353 + {
1354 + this.Core.ParseExtensionAttribute(node, attrib);
1355 + }
1356 + }
1357 +
1358 + if (null == applicationKey && 0 == (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1359 + {
1360 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Application", "Type", "native"));
1361 + }
1362 + if (null != assemblyName && 0 == (attributes & (int)CpiAssemblyAttributes.DllPathFromGAC))
1363 + {
1364 + this.Core.OnMessage(ComPlusErrors.UnexpectedAttributeWithoutOtherValue(sourceLineNumbers, node.Name.LocalName, "AssemblyName", "DllPathFromGAC", "no"));
1365 + }
1366 + if (null == tlbPath && 0 != (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1367 + {
1368 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "TlbPath", "Type", ".net"));
1369 + }
1370 + if (null != psDllPath && 0 != (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1371 + {
1372 + this.Core.OnMessage(ComPlusErrors.UnexpectedAttributeWithOtherValue(sourceLineNumbers, node.Name.LocalName, "PSDllPath", "Type", ".net"));
1373 + }
1374 + if (0 != (attributes & (int)CpiAssemblyAttributes.EventClass) && 0 != (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1375 + {
1376 + this.Core.OnMessage(ComPlusErrors.UnexpectedAttributeWithOtherValue(sourceLineNumbers, node.Name.LocalName, "EventClass", "yes", "Type", ".net"));
1377 + }
1378 +
1379 + foreach (XElement child in node.Elements())
1380 + {
1381 + if (this.Namespace == child.Name.Namespace)
1382 + {
1383 + switch (child.Name.LocalName)
1384 + {
1385 + case "ComPlusAssemblyDependency":
1386 + this.ParseComPlusAssemblyDependencyElement(child, key);
1387 + break;
1388 + case "ComPlusComponent":
1389 + this.ParseComPlusComponentElement(child, componentKey, key);
1390 + hasComponents = true;
1391 + break;
1392 + default:
1393 + this.Core.UnexpectedElement(node, child);
1394 + break;
1395 + }
1396 + }
1397 + else
1398 + {
1399 + this.Core.ParseExtensionElement(node, child);
1400 + }
1401 + }
1402 +
1403 + if (0 == (attributes & (int)CpiAssemblyAttributes.DotNetAssembly) && !hasComponents)
1404 + {
1405 + this.Core.OnMessage(ComPlusWarnings.MissingComponents(sourceLineNumbers));
1406 + }
1407 +
1408 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusAssembly");
1409 + row[0] = key;
1410 + row[1] = applicationKey;
1411 + row[2] = componentKey;
1412 + row[3] = assemblyName;
1413 + row[4] = dllPath;
1414 + row[5] = tlbPath;
1415 + row[6] = psDllPath;
1416 + row[7] = attributes;
1417 +
1418 + if (win64)
1419 + {
1420 + if (this.Core.CurrentPlatform == Platform.IA64)
1421 + {
1422 + this.Core.OnMessage(WixErrors.UnsupportedPlatformForElement(sourceLineNumbers, "ia64", node.Name.LocalName));
1423 + }
1424 + else
1425 + {
1426 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusInstall_x64");
1427 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusUninstall_x64");
1428 + }
1429 + }
1430 + else
1431 + {
1432 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusInstall");
1433 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureComPlusUninstall");
1434 + }
1435 + }
1436 +
1437 + /// <summary>
1438 + /// Parses a COM+ assembly dependency element.
1439 + /// </summary>
1440 + /// <param name="node">Element to parse.</param>
1441 + /// <param name="assemblyKey">Identifier of parent assembly.</param>
1442 + private void ParseComPlusAssemblyDependencyElement(XElement node, string assemblyKey)
1443 + {
1444 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1445 +
1446 + string requiredAssemblyKey = null;
1447 +
1448 + foreach (XAttribute attrib in node.Attributes())
1449 + {
1450 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1451 + {
1452 + switch (attrib.Name.LocalName)
1453 + {
1454 + case "RequiredAssembly":
1455 + requiredAssemblyKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1456 + break;
1457 + default:
1458 + this.Core.UnexpectedAttribute(node, attrib);
1459 + break;
1460 + }
1461 + }
1462 + else
1463 + {
1464 + this.Core.ParseExtensionAttribute(node, attrib);
1465 + }
1466 + }
1467 +
1468 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusAssemblyDependency");
1469 + row[0] = assemblyKey;
1470 + row[1] = requiredAssemblyKey;
1471 + }
1472 +
1473 + /// <summary>
1474 + /// Parses a COM+ component element.
1475 + /// </summary>
1476 + /// <param name="node">Element to parse.</param>
1477 + /// <param name="componentKey">Identifier of parent component.</param>
1478 + /// <param name="assemblyKey">Identifier of parent assembly.</param>
1479 + private void ParseComPlusComponentElement(XElement node, string componentKey, string assemblyKey)
1480 + {
1481 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1482 +
1483 + string key = null;
1484 + string clsid = null;
1485 +
1486 + Hashtable properties = new Hashtable();
1487 +
1488 + foreach (XAttribute attrib in node.Attributes())
1489 + {
1490 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1491 + {
1492 + switch (attrib.Name.LocalName)
1493 + {
1494 + case "Id":
1495 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1496 + break;
1497 + case "CLSID":
1498 + clsid = "{" + this.Core.GetAttributeValue(sourceLineNumbers, attrib) + "}";
1499 + break;
1500 + case "AllowInprocSubscribers":
1501 + properties["AllowInprocSubscribers"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1502 + break;
1503 + case "ComponentAccessChecksEnabled":
1504 + properties["ComponentAccessChecksEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1505 + break;
1506 + case "ComponentTransactionTimeout":
1507 + properties["ComponentTransactionTimeout"] = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 3600).ToString();
1508 + break;
1509 + case "ComponentTransactionTimeoutEnabled":
1510 + properties["ComponentTransactionTimeoutEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1511 + break;
1512 + case "COMTIIntrinsics":
1513 + properties["COMTIIntrinsics"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1514 + break;
1515 + case "ConstructionEnabled":
1516 + properties["ConstructionEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1517 + break;
1518 + case "ConstructorString":
1519 + properties["ConstructorString"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1520 + break;
1521 + case "CreationTimeout":
1522 + properties["CreationTimeout"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1523 + break;
1524 + case "Description":
1525 + properties["Description"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1526 + break;
1527 + case "EventTrackingEnabled":
1528 + properties["EventTrackingEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1529 + break;
1530 + case "ExceptionClass":
1531 + properties["ExceptionClass"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1532 + break;
1533 + case "FireInParallel":
1534 + properties["FireInParallel"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1535 + break;
1536 + case "IISIntrinsics":
1537 + properties["IISIntrinsics"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1538 + break;
1539 + case "InitializesServerApplication":
1540 + properties["InitializesServerApplication"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1541 + break;
1542 + case "IsEnabled":
1543 + properties["IsEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1544 + break;
1545 + case "IsPrivateComponent":
1546 + properties["IsPrivateComponent"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1547 + break;
1548 + case "JustInTimeActivation":
1549 + properties["JustInTimeActivation"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1550 + break;
1551 + case "LoadBalancingSupported":
1552 + properties["LoadBalancingSupported"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1553 + break;
1554 + case "MaxPoolSize":
1555 + properties["MaxPoolSize"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1556 + break;
1557 + case "MinPoolSize":
1558 + properties["MinPoolSize"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1559 + break;
1560 + case "MultiInterfacePublisherFilterCLSID":
1561 + properties["MultiInterfacePublisherFilterCLSID"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1562 + break;
1563 + case "MustRunInClientContext":
1564 + properties["MustRunInClientContext"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1565 + break;
1566 + case "MustRunInDefaultContext":
1567 + properties["MustRunInDefaultContext"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1568 + break;
1569 + case "ObjectPoolingEnabled":
1570 + properties["ObjectPoolingEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1571 + break;
1572 + case "PublisherID":
1573 + properties["PublisherID"] = TryFormatGuidValue(this.Core.GetAttributeValue(sourceLineNumbers, attrib));
1574 + break;
1575 + case "SoapAssemblyName":
1576 + properties["SoapAssemblyName"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1577 + break;
1578 + case "SoapTypeName":
1579 + properties["SoapTypeName"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1580 + break;
1581 + case "Synchronization":
1582 + string synchronizationValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1583 + switch (synchronizationValue)
1584 + {
1585 + case "ignored":
1586 + properties["Synchronization"] = "0";
1587 + break;
1588 + case "none":
1589 + properties["Synchronization"] = "1";
1590 + break;
1591 + case "supported":
1592 + properties["Synchronization"] = "2";
1593 + break;
1594 + case "required":
1595 + properties["Synchronization"] = "3";
1596 + break;
1597 + case "requiresNew":
1598 + properties["Synchronization"] = "4";
1599 + break;
1600 + default:
1601 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "ComPlusComponent", "Synchronization", synchronizationValue, "ignored", "none", "supported", "required", "requiresNew"));
1602 + break;
1603 + }
1604 + break;
1605 + case "Transaction":
1606 + string transactionValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1607 + switch (transactionValue)
1608 + {
1609 + case "ignored":
1610 + properties["Transaction"] = "0";
1611 + break;
1612 + case "none":
1613 + properties["Transaction"] = "1";
1614 + break;
1615 + case "supported":
1616 + properties["Transaction"] = "2";
1617 + break;
1618 + case "required":
1619 + properties["Transaction"] = "3";
1620 + break;
1621 + case "requiresNew":
1622 + properties["Transaction"] = "4";
1623 + break;
1624 + default:
1625 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "ComPlusComponent", "Transaction", transactionValue, "ignored", "none", "supported", "required", "requiresNew"));
1626 + break;
1627 + }
1628 + break;
1629 + case "TxIsolationLevel":
1630 + string txIsolationLevelValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1631 + switch (txIsolationLevelValue)
1632 + {
1633 + case "any":
1634 + properties["TxIsolationLevel"] = "0";
1635 + break;
1636 + case "readUnCommitted":
1637 + properties["TxIsolationLevel"] = "1";
1638 + break;
1639 + case "readCommitted":
1640 + properties["TxIsolationLevel"] = "2";
1641 + break;
1642 + case "repeatableRead":
1643 + properties["TxIsolationLevel"] = "3";
1644 + break;
1645 + case "serializable":
1646 + properties["TxIsolationLevel"] = "4";
1647 + break;
1648 + default:
1649 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, "ComPlusComponent", "TxIsolationLevel", txIsolationLevelValue, "any", "readUnCommitted", "readCommitted", "repeatableRead", "serializable"));
1650 + break;
1651 + }
1652 + break;
1653 + default:
1654 + this.Core.UnexpectedAttribute(node, attrib);
1655 + break;
1656 + }
1657 + }
1658 + else
1659 + {
1660 + this.Core.ParseExtensionAttribute(node, attrib);
1661 + }
1662 + }
1663 +
1664 + foreach (XElement child in node.Elements())
1665 + {
1666 + if (this.Namespace == child.Name.Namespace)
1667 + {
1668 + switch (child.Name.LocalName)
1669 + {
1670 + case "ComPlusRoleForComponent":
1671 + this.ParseComPlusRoleForComponentElement(child, componentKey, key);
1672 + break;
1673 + case "ComPlusInterface":
1674 + this.ParseComPlusInterfaceElement(child, componentKey, key);
1675 + break;
1676 + case "ComPlusSubscription":
1677 + this.ParseComPlusSubscriptionElement(child, componentKey, key);
1678 + break;
1679 + default:
1680 + this.Core.UnexpectedElement(node, child);
1681 + break;
1682 + }
1683 + }
1684 + else
1685 + {
1686 + this.Core.ParseExtensionElement(node, child);
1687 + }
1688 + }
1689 +
1690 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusComponent");
1691 + row[0] = key;
1692 + row[1] = assemblyKey;
1693 + row[2] = clsid;
1694 +
1695 + IDictionaryEnumerator propertiesEnumerator = properties.GetEnumerator();
1696 + while (propertiesEnumerator.MoveNext())
1697 + {
1698 + Row propertyRow = this.Core.CreateRow(sourceLineNumbers, "ComPlusComponentProperty");
1699 + propertyRow[0] = key;
1700 + propertyRow[1] = (string)propertiesEnumerator.Key;
1701 + propertyRow[2] = (string)propertiesEnumerator.Value;
1702 + }
1703 + }
1704 +
1705 + /// <summary>
1706 + /// Parses a COM+ application role for component element.
1707 + /// </summary>
1708 + /// <param name="node">Element to parse.</param>
1709 + /// <param name="componentKey">Identifier of parent component.</param>
1710 + /// <param name="cpcomponentKey">Identifier of parent COM+ component.</param>
1711 + private void ParseComPlusRoleForComponentElement(XElement node, string componentKey, string cpcomponentKey)
1712 + {
1713 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1714 +
1715 + string key = null;
1716 + string applicationRoleKey = null;
1717 +
1718 + foreach (XAttribute attrib in node.Attributes())
1719 + {
1720 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1721 + {
1722 + switch (attrib.Name.LocalName)
1723 + {
1724 + case "Id":
1725 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1726 + break;
1727 + case "Component":
1728 + if (null != cpcomponentKey)
1729 + {
1730 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1731 + }
1732 + cpcomponentKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1733 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusComponent", cpcomponentKey);
1734 + break;
1735 + case "ApplicationRole":
1736 + applicationRoleKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1737 + break;
1738 + default:
1739 + this.Core.UnexpectedAttribute(node, attrib);
1740 + break;
1741 + }
1742 + }
1743 + else
1744 + {
1745 + this.Core.ParseExtensionAttribute(node, attrib);
1746 + }
1747 + }
1748 +
1749 + if (null == cpcomponentKey)
1750 + {
1751 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Component"));
1752 + }
1753 +
1754 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusRoleForComponent");
1755 + row[0] = key;
1756 + row[1] = cpcomponentKey;
1757 + row[2] = applicationRoleKey;
1758 + row[3] = componentKey;
1759 + }
1760 +
1761 + /// <summary>
1762 + /// Parses a COM+ interface element.
1763 + /// </summary>
1764 + /// <param name="node">Element to parse.</param>
1765 + /// <param name="componentKey">Identifier of parent component.</param>
1766 + /// <param name="cpcomponentKey">Identifier of parent COM+ component.</param>
1767 + private void ParseComPlusInterfaceElement(XElement node, string componentKey, string cpcomponentKey)
1768 + {
1769 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1770 +
1771 + // parse attributes
1772 + string key = null;
1773 + string iid = null;
1774 +
1775 + Hashtable properties = new Hashtable();
1776 +
1777 + foreach (XAttribute attrib in node.Attributes())
1778 + {
1779 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1780 + {
1781 + switch (attrib.Name.LocalName)
1782 + {
1783 + case "Id":
1784 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1785 + break;
1786 + case "IID":
1787 + iid = "{" + this.Core.GetAttributeValue(sourceLineNumbers, attrib) + "}";
1788 + break;
1789 + case "Description":
1790 + properties["Description"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1791 + break;
1792 + case "QueuingEnabled":
1793 + properties["QueuingEnabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1794 + break;
1795 + default:
1796 + this.Core.UnexpectedAttribute(node, attrib);
1797 + break;
1798 + }
1799 + }
1800 + else
1801 + {
1802 + this.Core.ParseExtensionAttribute(node, attrib);
1803 + }
1804 + }
1805 +
1806 + foreach (XElement child in node.Elements())
1807 + {
1808 + if (this.Namespace == child.Name.Namespace)
1809 + {
1810 + switch (child.Name.LocalName)
1811 + {
1812 + case "ComPlusRoleForInterface":
1813 + this.ParseComPlusRoleForInterfaceElement(child, componentKey, key);
1814 + break;
1815 + case "ComPlusMethod":
1816 + this.ParseComPlusMethodElement(child, componentKey, key);
1817 + break;
1818 + default:
1819 + this.Core.UnexpectedElement(node, child);
1820 + break;
1821 + }
1822 + }
1823 + else
1824 + {
1825 + this.Core.ParseExtensionElement(node, child);
1826 + }
1827 + }
1828 +
1829 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusInterface");
1830 + row[0] = key;
1831 + row[1] = cpcomponentKey;
1832 + row[2] = iid;
1833 +
1834 + IDictionaryEnumerator propertiesEnumerator = properties.GetEnumerator();
1835 + while (propertiesEnumerator.MoveNext())
1836 + {
1837 + Row propertyRow = this.Core.CreateRow(sourceLineNumbers, "ComPlusInterfaceProperty");
1838 + propertyRow[0] = key;
1839 + propertyRow[1] = (string)propertiesEnumerator.Key;
1840 + propertyRow[2] = (string)propertiesEnumerator.Value;
1841 + }
1842 + }
1843 +
1844 + /// <summary>
1845 + /// Parses a COM+ application role for interface element.
1846 + /// </summary>
1847 + /// <param name="node">Element to parse.</param>
1848 + /// <param name="componentKey">Identifier of parent component.</param>
1849 + /// <param name="interfaceKey">Identifier of parent interface.</param>
1850 + private void ParseComPlusRoleForInterfaceElement(XElement node, string componentKey, string interfaceKey)
1851 + {
1852 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1853 +
1854 + string key = null;
1855 + string applicationRoleKey = null;
1856 +
1857 + foreach (XAttribute attrib in node.Attributes())
1858 + {
1859 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1860 + {
1861 + switch (attrib.Name.LocalName)
1862 + {
1863 + case "Id":
1864 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1865 + break;
1866 + case "Interface":
1867 + if (null != interfaceKey)
1868 + {
1869 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1870 + }
1871 + interfaceKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1872 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusInterface", interfaceKey);
1873 + break;
1874 + case "ApplicationRole":
1875 + applicationRoleKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1876 + break;
1877 + default:
1878 + this.Core.UnexpectedAttribute(node, attrib);
1879 + break;
1880 + }
1881 + }
1882 + else
1883 + {
1884 + this.Core.ParseExtensionAttribute(node, attrib);
1885 + }
1886 + }
1887 +
1888 + if (null == interfaceKey)
1889 + {
1890 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Interface"));
1891 + }
1892 +
1893 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusRoleForInterface");
1894 + row[0] = key;
1895 + row[1] = interfaceKey;
1896 + row[2] = applicationRoleKey;
1897 + row[3] = componentKey;
1898 + }
1899 +
1900 + /// <summary>
1901 + /// Parses a COM+ method element.
1902 + /// </summary>
1903 + /// <param name="node">Element to parse.</param>
1904 + /// <param name="componentKey">Identifier of parent component.</param>
1905 + /// <param name="interfaceKey">Identifier of parent interface.</param>
1906 + private void ParseComPlusMethodElement(XElement node, string componentKey, string interfaceKey)
1907 + {
1908 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1909 +
1910 + string key = null;
1911 + int index = CompilerConstants.IntegerNotSet;
1912 + string name = null;
1913 +
1914 + Hashtable properties = new Hashtable();
1915 +
1916 + foreach (XAttribute attrib in node.Attributes())
1917 + {
1918 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1919 + {
1920 + switch (attrib.Name.LocalName)
1921 + {
1922 + case "Id":
1923 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1924 + break;
1925 + case "Index":
1926 + index = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
1927 + break;
1928 + case "Name":
1929 + name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1930 + break;
1931 + case "AutoComplete":
1932 + properties["AutoComplete"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1933 + break;
1934 + case "Description":
1935 + properties["Description"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1936 + break;
1937 + default:
1938 + this.Core.UnexpectedAttribute(node, attrib);
1939 + break;
1940 + }
1941 + }
1942 + else
1943 + {
1944 + this.Core.ParseExtensionAttribute(node, attrib);
1945 + }
1946 + }
1947 +
1948 + foreach (XElement child in node.Elements())
1949 + {
1950 + if (this.Namespace == child.Name.Namespace)
1951 + {
1952 + switch (child.Name.LocalName)
1953 + {
1954 + case "ComPlusRoleForMethod":
1955 + this.ParseComPlusRoleForMethodElement(child, componentKey, key);
1956 + break;
1957 + default:
1958 + this.Core.UnexpectedElement(node, child);
1959 + break;
1960 + }
1961 + }
1962 + else
1963 + {
1964 + this.Core.ParseExtensionElement(node, child);
1965 + }
1966 + }
1967 +
1968 + if (CompilerConstants.IntegerNotSet == index && null == name)
1969 + {
1970 + this.Core.OnMessage(ComPlusErrors.RequiredAttribute(sourceLineNumbers, node.Name.LocalName, "Index", "Name"));
1971 + }
1972 +
1973 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusMethod");
1974 + row[0] = key;
1975 + row[1] = interfaceKey;
1976 + if (CompilerConstants.IntegerNotSet != index)
1977 + {
1978 + row[2] = index;
1979 + }
1980 + row[3] = name;
1981 +
1982 + IDictionaryEnumerator propertiesEnumerator = properties.GetEnumerator();
1983 + while (propertiesEnumerator.MoveNext())
1984 + {
1985 + Row propertyRow = this.Core.CreateRow(sourceLineNumbers, "ComPlusMethodProperty");
1986 + propertyRow[0] = key;
1987 + propertyRow[1] = (string)propertiesEnumerator.Key;
1988 + propertyRow[2] = (string)propertiesEnumerator.Value;
1989 + }
1990 + }
1991 +
1992 + /// <summary>
1993 + /// Parses a COM+ application role for method element.
1994 + /// </summary>
1995 + /// <param name="node">Element to parse.</param>
1996 + /// <param name="componentKey">Identifier of parent component.</param>
1997 + /// <param name="methodKey">Identifier of parent method.</param>
1998 + private void ParseComPlusRoleForMethodElement(XElement node, string componentKey, string methodKey)
1999 + {
2000 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2001 +
2002 + string key = null;
2003 + string applicationRoleKey = null;
2004 +
2005 + foreach (XAttribute attrib in node.Attributes())
2006 + {
2007 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
2008 + {
2009 + switch (attrib.Name.LocalName)
2010 + {
2011 + case "Id":
2012 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2013 + break;
2014 + case "Method":
2015 + if (null != methodKey)
2016 + {
2017 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
2018 + }
2019 + methodKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2020 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusMethod", methodKey);
2021 + break;
2022 + case "ApplicationRole":
2023 + applicationRoleKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2024 + break;
2025 + default:
2026 + this.Core.UnexpectedAttribute(node, attrib);
2027 + break;
2028 + }
2029 + }
2030 + else
2031 + {
2032 + this.Core.ParseExtensionAttribute(node, attrib);
2033 + }
2034 + }
2035 +
2036 + if (null == methodKey)
2037 + {
2038 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Method"));
2039 + }
2040 +
2041 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusRoleForMethod");
2042 + row[0] = key;
2043 + row[1] = methodKey;
2044 + row[2] = applicationRoleKey;
2045 + row[3] = componentKey;
2046 + }
2047 +
2048 + /// <summary>
2049 + /// Parses a COM+ event subscription element.
2050 + /// </summary>
2051 + /// <param name="node">Element to parse.</param>
2052 + /// <param name="componentKey">Identifier of parent component.</param>
2053 + /// <param name="cpcomponentKey">Identifier of parent COM+ component.</param>
2054 + private void ParseComPlusSubscriptionElement(XElement node, string componentKey, string cpcomponentKey)
2055 + {
2056 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2057 +
2058 + string key = null;
2059 + string id = null;
2060 + string name = null;
2061 + string eventCLSID = null;
2062 + string publisherID = null;
2063 +
2064 + Hashtable properties = new Hashtable();
2065 +
2066 + foreach (XAttribute attrib in node.Attributes())
2067 + {
2068 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
2069 + {
2070 + switch (attrib.Name.LocalName)
2071 + {
2072 + case "Id":
2073 + key = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2074 + break;
2075 + case "Component":
2076 + if (null != cpcomponentKey)
2077 + {
2078 + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
2079 + }
2080 + cpcomponentKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2081 + this.Core.CreateSimpleReference(sourceLineNumbers, "ComPlusComponent", cpcomponentKey);
2082 + break;
2083 + case "SubscriptionId":
2084 + id = TryFormatGuidValue(this.Core.GetAttributeValue(sourceLineNumbers, attrib));
2085 + break;
2086 + case "Name":
2087 + name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2088 + break;
2089 + case "EventCLSID":
2090 + eventCLSID = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2091 + break;
2092 + case "PublisherID":
2093 + publisherID = TryFormatGuidValue(this.Core.GetAttributeValue(sourceLineNumbers, attrib));
2094 + break;
2095 + case "Description":
2096 + properties["Description"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2097 + break;
2098 + case "Enabled":
2099 + properties["Enabled"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
2100 + break;
2101 + case "EventClassPartitionID":
2102 + properties["EventClassPartitionID"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2103 + break;
2104 + case "FilterCriteria":
2105 + properties["FilterCriteria"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2106 + break;
2107 + case "InterfaceID":
2108 + properties["InterfaceID"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2109 + break;
2110 + case "MachineName":
2111 + properties["MachineName"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2112 + break;
2113 + case "MethodName":
2114 + properties["MethodName"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2115 + break;
2116 + case "PerUser":
2117 + properties["PerUser"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
2118 + break;
2119 + case "Queued":
2120 + properties["Queued"] = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
2121 + break;
2122 + case "SubscriberMoniker":
2123 + properties["SubscriberMoniker"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2124 + break;
2125 + case "UserName":
2126 + properties["UserName"] = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2127 + break;
2128 + default:
2129 + this.Core.UnexpectedAttribute(node, attrib);
2130 + break;
2131 + }
2132 + }
2133 + else
2134 + {
2135 + this.Core.ParseExtensionAttribute(node, attrib);
2136 + }
2137 + }
2138 +
2139 + if (null == cpcomponentKey)
2140 + {
2141 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Component"));
2142 + }
2143 +
2144 + this.Core.ParseForExtensionElements(node);
2145 +
2146 + Row row = this.Core.CreateRow(sourceLineNumbers, "ComPlusSubscription");
2147 + row[0] = key;
2148 + row[1] = cpcomponentKey;
2149 + row[2] = componentKey;
2150 + row[3] = id;
2151 + row[4] = name;
2152 + row[5] = eventCLSID;
2153 + row[6] = publisherID;
2154 +
2155 + IDictionaryEnumerator propertiesEnumerator = properties.GetEnumerator();
2156 + while (propertiesEnumerator.MoveNext())
2157 + {
2158 + Row propertyRow = this.Core.CreateRow(sourceLineNumbers, "ComPlusSubscriptionProperty");
2159 + propertyRow[0] = key;
2160 + propertyRow[1] = (string)propertiesEnumerator.Key;
2161 + propertyRow[2] = (string)propertiesEnumerator.Value;
2162 + }
2163 + }
2164 +
2165 + /// <summary>
2166 + /// Attempts to parse the input value as a GUID, and in case the value is a valid
2167 + /// GUID returnes it in the format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}".
2168 + /// </summary>
2169 + /// <param name="val"></param>
2170 + /// <returns></returns>
2171 + string TryFormatGuidValue(string val)
2172 + {
2173 + try
2174 + {
2175 + Guid guid = new Guid(val);
2176 + return guid.ToString("B").ToUpper();
2177 + }
2178 + catch (FormatException)
2179 + {
2180 + return val;
2181 + }
2182 + catch (OverflowException)
2183 + {
2184 + return val;
2185 + }
2186 + }
2187 + }
2188 +}
src/wixext/ComPlusDecompiler.cs new
+1843
@@ -0,0 +1,1843 @@
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 +namespace WixToolset.Extensions
4 +{
5 + using System;
6 + using System.Collections;
7 + using System.Globalization;
8 + using WixToolset.Data;
9 + using WixToolset.Extensibility;
10 + using ComPlus = WixToolset.Extensions.Serialize.ComPlus;
11 + using Wix = WixToolset.Data.Serialize;
12 +
13 + /// <summary>
14 + /// The decompiler for the WiX Toolset COM+ Extension.
15 + /// </summary>
16 + public sealed class ComPlusDecompiler : DecompilerExtension
17 + {
18 + /// <summary>
19 + /// Creates a decompiler for ComPlus Extension.
20 + /// </summary>
21 + public ComPlusDecompiler()
22 + {
23 + this.TableDefinitions = ComPlusExtensionData.GetExtensionTableDefinitions();
24 + }
25 +
26 + /// <summary>
27 + /// Get the extensions library to be removed.
28 + /// </summary>
29 + /// <param name="tableDefinitions">Table definitions for library.</param>
30 + /// <returns>Library to remove from decompiled output.</returns>
31 + public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions)
32 + {
33 + return ComPlusExtensionData.GetExtensionLibrary(tableDefinitions);
34 + }
35 +
36 + /// <summary>
37 + /// Decompiles an extension table.
38 + /// </summary>
39 + /// <param name="table">The table to decompile.</param>
40 + public override void DecompileTable(Table table)
41 + {
42 + switch (table.Name)
43 + {
44 + case "ComPlusPartition":
45 + this.DecompileComPlusPartitionTable(table);
46 + break;
47 + case "ComPlusPartitionProperty":
48 + this.DecompileComPlusPartitionPropertyTable(table);
49 + break;
50 + case "ComPlusPartitionRole":
51 + this.DecompileComPlusPartitionRoleTable(table);
52 + break;
53 + case "ComPlusUserInPartitionRole":
54 + this.DecompileComPlusUserInPartitionRoleTable(table);
55 + break;
56 + case "ComPlusGroupInPartitionRole":
57 + this.DecompileComPlusGroupInPartitionRoleTable(table);
58 + break;
59 + case "ComPlusPartitionUser":
60 + this.DecompileComPlusPartitionUserTable(table);
61 + break;
62 + case "ComPlusApplication":
63 + this.DecompileComPlusApplicationTable(table);
64 + break;
65 + case "ComPlusApplicationProperty":
66 + this.DecompileComPlusApplicationPropertyTable(table);
67 + break;
68 + case "ComPlusApplicationRole":
69 + this.DecompileComPlusApplicationRoleTable(table);
70 + break;
71 + case "ComPlusApplicationRoleProperty":
72 + this.DecompileComPlusApplicationRolePropertyTable(table);
73 + break;
74 + case "ComPlusUserInApplicationRole":
75 + this.DecompileComPlusUserInApplicationRoleTable(table);
76 + break;
77 + case "ComPlusGroupInApplicationRole":
78 + this.DecompileComPlusGroupInApplicationRoleTable(table);
79 + break;
80 + case "ComPlusAssembly":
81 + this.DecompileComPlusAssemblyTable(table);
82 + break;
83 + case "ComPlusComponent":
84 + this.DecompileComPlusComponentTable(table);
85 + break;
86 + case "ComPlusComponentProperty":
87 + this.DecompileComPlusComponentPropertyTable(table);
88 + break;
89 + case "ComPlusRoleForComponent":
90 + this.DecompileComPlusRoleForComponentTable(table);
91 + break;
92 + case "ComPlusInterface":
93 + this.DecompileComPlusInterfaceTable(table);
94 + break;
95 + case "ComPlusInterfaceProperty":
96 + this.DecompileComPlusInterfacePropertyTable(table);
97 + break;
98 + case "ComPlusRoleForInterface":
99 + this.DecompileComPlusRoleForInterfaceTable(table);
100 + break;
101 + case "ComPlusMethod":
102 + this.DecompileComPlusMethodTable(table);
103 + break;
104 + case "ComPlusMethodProperty":
105 + this.DecompileComPlusMethodPropertyTable(table);
106 + break;
107 + case "ComPlusRoleForMethod":
108 + this.DecompileComPlusRoleForMethodTable(table);
109 + break;
110 + case "ComPlusSubscription":
111 + this.DecompileComPlusSubscriptionTable(table);
112 + break;
113 + case "ComPlusSubscriptionProperty":
114 + this.DecompileComPlusSubscriptionPropertyTable(table);
115 + break;
116 + default:
117 + base.DecompileTable(table);
118 + break;
119 + }
120 + }
121 +
122 + /// <summary>
123 + /// Decompile the ComPlusPartition table.
124 + /// </summary>
125 + /// <param name="table">The table to decompile.</param>
126 + private void DecompileComPlusPartitionTable(Table table)
127 + {
128 + foreach (Row row in table.Rows)
129 + {
130 + ComPlus.ComPlusPartition partition = new ComPlus.ComPlusPartition();
131 +
132 + partition.Id = (string)row[0];
133 +
134 + if (null != row[2])
135 + {
136 + partition.PartitionId = (string)row[2];
137 + }
138 +
139 + if (null != row[3])
140 + {
141 + partition.Name = (string)row[3];
142 + }
143 +
144 + if (null != row[1])
145 + {
146 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]);
147 + if (null != component)
148 + {
149 + component.AddChild(partition);
150 + }
151 + else
152 + {
153 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component"));
154 + }
155 + }
156 + else
157 + {
158 + this.Core.RootElement.AddChild(partition);
159 + }
160 + this.Core.IndexElement(row, partition);
161 + }
162 + }
163 +
164 + /// <summary>
165 + /// Decompile the ComPlusPartitionProperty table.
166 + /// </summary>
167 + /// <param name="table">The table to decompile.</param>
168 + private void DecompileComPlusPartitionPropertyTable(Table table)
169 + {
170 + foreach (Row row in table.Rows)
171 + {
172 + ComPlus.ComPlusPartition partition = (ComPlus.ComPlusPartition)this.Core.GetIndexedElement("ComPlusPartition", (string)row[0]);
173 + if (null == partition)
174 + {
175 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Partition_", (string)row[0], "ComPlusPartition"));
176 + }
177 +
178 + switch ((string)row[1])
179 + {
180 + case "Changeable":
181 + switch ((string)row[2])
182 + {
183 + case "1":
184 + partition.Changeable = ComPlus.YesNoType.yes;
185 + break;
186 + case "0":
187 + partition.Changeable = ComPlus.YesNoType.no;
188 + break;
189 + default:
190 + // TODO: Warning
191 + break;
192 + }
193 + break;
194 + case "Deleteable":
195 + switch ((string)row[2])
196 + {
197 + case "1":
198 + partition.Deleteable = ComPlus.YesNoType.yes;
199 + break;
200 + case "0":
201 + partition.Deleteable = ComPlus.YesNoType.no;
202 + break;
203 + default:
204 + // TODO: Warning
205 + break;
206 + }
207 + break;
208 + case "Description":
209 + partition.Description = (string)row[2];
210 + break;
211 + default:
212 + // TODO: Warning
213 + break;
214 + }
215 + }
216 + }
217 +
218 + /// <summary>
219 + /// Decompile the ComPlusPartitionRole table.
220 + /// </summary>
221 + /// <param name="table">The table to decompile.</param>
222 + private void DecompileComPlusPartitionRoleTable(Table table)
223 + {
224 + foreach (Row row in table.Rows)
225 + {
226 + ComPlus.ComPlusPartitionRole partitionRole = new ComPlus.ComPlusPartitionRole();
227 +
228 + partitionRole.Id = (string)row[0];
229 + partitionRole.Partition = (string)row[1];
230 + partitionRole.Name = (string)row[3];
231 +
232 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
233 + if (null != component)
234 + {
235 + component.AddChild(partitionRole);
236 + }
237 + else
238 + {
239 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
240 + }
241 + }
242 + }
243 +
244 + /// <summary>
245 + /// Decompile the ComPlusUserInPartitionRole table.
246 + /// </summary>
247 + /// <param name="table">The table to decompile.</param>
248 + private void DecompileComPlusUserInPartitionRoleTable(Table table)
249 + {
250 + foreach (Row row in table.Rows)
251 + {
252 + ComPlus.ComPlusUserInPartitionRole userInPartitionRole = new ComPlus.ComPlusUserInPartitionRole();
253 +
254 + userInPartitionRole.Id = (string)row[0];
255 + userInPartitionRole.PartitionRole = (string)row[1];
256 + userInPartitionRole.User = (string)row[3];
257 +
258 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
259 + if (null != component)
260 + {
261 + component.AddChild(userInPartitionRole);
262 + }
263 + else
264 + {
265 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
266 + }
267 + }
268 + }
269 +
270 + /// <summary>
271 + /// Decompile the ComPlusGroupInPartitionRole table.
272 + /// </summary>
273 + /// <param name="table">The table to decompile.</param>
274 + private void DecompileComPlusGroupInPartitionRoleTable(Table table)
275 + {
276 + foreach (Row row in table.Rows)
277 + {
278 + ComPlus.ComPlusGroupInPartitionRole groupInPartitionRole = new ComPlus.ComPlusGroupInPartitionRole();
279 +
280 + groupInPartitionRole.Id = (string)row[0];
281 + groupInPartitionRole.PartitionRole = (string)row[1];
282 + groupInPartitionRole.Group = (string)row[3];
283 +
284 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
285 + if (null != component)
286 + {
287 + component.AddChild(groupInPartitionRole);
288 + }
289 + else
290 + {
291 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
292 + }
293 + }
294 + }
295 +
296 + /// <summary>
297 + /// Decompile the ComPlusPartitionUser table.
298 + /// </summary>
299 + /// <param name="table">The table to decompile.</param>
300 + private void DecompileComPlusPartitionUserTable(Table table)
301 + {
302 + foreach (Row row in table.Rows)
303 + {
304 + ComPlus.ComPlusPartitionUser partitionUser = new ComPlus.ComPlusPartitionUser();
305 +
306 + partitionUser.Id = (string)row[0];
307 + partitionUser.Partition = (string)row[1];
308 + partitionUser.User = (string)row[3];
309 +
310 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
311 + if (null != component)
312 + {
313 + component.AddChild(partitionUser);
314 + }
315 + else
316 + {
317 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
318 + }
319 + }
320 + }
321 +
322 + /// <summary>
323 + /// Decompile the ComPlusApplication table.
324 + /// </summary>
325 + /// <param name="table">The table to decompile.</param>
326 + private void DecompileComPlusApplicationTable(Table table)
327 + {
328 + foreach (Row row in table.Rows)
329 + {
330 + ComPlus.ComPlusApplication application = new ComPlus.ComPlusApplication();
331 +
332 + application.Id = (string)row[0];
333 + application.Partition = (string)row[1];
334 +
335 + if (null != row[3])
336 + {
337 + application.ApplicationId = (string)row[3];
338 + }
339 +
340 + if (null != row[4])
341 + {
342 + application.Name = (string)row[4];
343 + }
344 +
345 + if (null != row[2])
346 + {
347 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]);
348 + if (null != component)
349 + {
350 + component.AddChild(application);
351 + }
352 + else
353 + {
354 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
355 + }
356 + }
357 + else
358 + {
359 + this.Core.RootElement.AddChild(application);
360 + }
361 + this.Core.IndexElement(row, application);
362 + }
363 + }
364 +
365 + /// <summary>
366 + /// Decompile the ComPlusApplicationProperty table.
367 + /// </summary>
368 + /// <param name="table">The table to decompile.</param>
369 + private void DecompileComPlusApplicationPropertyTable(Table table)
370 + {
371 + foreach (Row row in table.Rows)
372 + {
373 + ComPlus.ComPlusApplication application = (ComPlus.ComPlusApplication)this.Core.GetIndexedElement("ComPlusApplication", (string)row[0]);
374 + if (null == application)
375 + {
376 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Application_", (string)row[0], "ComPlusApplication"));
377 + }
378 +
379 + switch ((string)row[1])
380 + {
381 + case "3GigSupportEnabled":
382 + switch ((string)row[2])
383 + {
384 + case "1":
385 + application.ThreeGigSupportEnabled = ComPlus.YesNoType.yes;
386 + break;
387 + case "0":
388 + application.ThreeGigSupportEnabled = ComPlus.YesNoType.no;
389 + break;
390 + default:
391 + // TODO: Warning
392 + break;
393 + }
394 + break;
395 + case "AccessChecksLevel":
396 + switch ((string)row[2])
397 + {
398 + case "0":
399 + application.AccessChecksLevel = ComPlus.ComPlusApplication.AccessChecksLevelType.applicationLevel;
400 + break;
401 + case "1":
402 + application.AccessChecksLevel = ComPlus.ComPlusApplication.AccessChecksLevelType.applicationComponentLevel;
403 + break;
404 + default:
405 + // TODO: Warning
406 + break;
407 + }
408 + break;
409 + case "Activation":
410 + switch ((string)row[2])
411 + {
412 + case "Inproc":
413 + application.Activation = ComPlus.ComPlusApplication.ActivationType.inproc;
414 + break;
415 + case "Local":
416 + application.Activation = ComPlus.ComPlusApplication.ActivationType.local;
417 + break;
418 + default:
419 + // TODO: Warning
420 + break;
421 + }
422 + break;
423 + case "ApplicationAccessChecksEnabled":
424 + switch ((string)row[2])
425 + {
426 + case "1":
427 + application.ApplicationAccessChecksEnabled = ComPlus.YesNoType.yes;
428 + break;
429 + case "0":
430 + application.ApplicationAccessChecksEnabled = ComPlus.YesNoType.no;
431 + break;
432 + default:
433 + // TODO: Warning
434 + break;
435 + }
436 + break;
437 + case "ApplicationDirectory":
438 + application.ApplicationDirectory = (string)row[2];
439 + break;
440 + case "Authentication":
441 + switch ((string)row[2])
442 + {
443 + case "0":
444 + application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.@default;
445 + break;
446 + case "1":
447 + application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.none;
448 + break;
449 + case "2":
450 + application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.connect;
451 + break;
452 + case "3":
453 + application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.call;
454 + break;
455 + case "4":
456 + application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.packet;
457 + break;
458 + case "5":
459 + application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.integrity;
460 + break;
461 + case "6":
462 + application.Authentication = ComPlus.ComPlusApplication.AuthenticationType.privacy;
463 + break;
464 + default:
465 + // TODO: Warning
466 + break;
467 + }
468 + break;
469 + case "AuthenticationCapability":
470 + switch ((string)row[2])
471 + {
472 + case "0":
473 + application.AuthenticationCapability = ComPlus.ComPlusApplication.AuthenticationCapabilityType.none;
474 + break;
475 + case "2":
476 + application.AuthenticationCapability = ComPlus.ComPlusApplication.AuthenticationCapabilityType.secureReference;
477 + break;
478 + case "32":
479 + application.AuthenticationCapability = ComPlus.ComPlusApplication.AuthenticationCapabilityType.staticCloaking;
480 + break;
481 + case "64":
482 + application.AuthenticationCapability = ComPlus.ComPlusApplication.AuthenticationCapabilityType.dynamicCloaking;
483 + break;
484 + default:
485 + // TODO: Warning
486 + break;
487 + }
488 + break;
489 + case "Changeable":
490 + switch ((string)row[2])
491 + {
492 + case "1":
493 + application.Changeable = ComPlus.YesNoType.yes;
494 + break;
495 + case "0":
496 + application.Changeable = ComPlus.YesNoType.no;
497 + break;
498 + default:
499 + // TODO: Warning
500 + break;
501 + }
502 + break;
503 + case "CommandLine":
504 + application.CommandLine = (string)row[2];
505 + break;
506 + case "ConcurrentApps":
507 + int concurrentApps;
508 + if (Int32.TryParse((string)row[2], out concurrentApps))
509 + {
510 + application.ConcurrentApps = concurrentApps;
511 + }
512 + else
513 + {
514 + // TODO: Warning
515 + }
516 + break;
517 + case "CreatedBy":
518 + application.CreatedBy = (string)row[2];
519 + break;
520 + case "CRMEnabled":
521 + switch ((string)row[2])
522 + {
523 + case "1":
524 + application.CRMEnabled = ComPlus.YesNoType.yes;
525 + break;
526 + case "0":
527 + application.CRMEnabled = ComPlus.YesNoType.no;
528 + break;
529 + default:
530 + // TODO: Warning
531 + break;
532 + }
533 + break;
534 + case "CRMLogFile":
535 + application.CRMLogFile = (string)row[2];
536 + break;
537 + case "Deleteable":
538 + switch ((string)row[2])
539 + {
540 + case "1":
541 + application.Deleteable = ComPlus.YesNoType.yes;
542 + break;
543 + case "0":
544 + application.Deleteable = ComPlus.YesNoType.no;
545 + break;
546 + default:
547 + // TODO: Warning
548 + break;
549 + }
550 + break;
551 + case "Description":
552 + application.Description = (string)row[2];
553 + break;
554 + case "DumpEnabled":
555 + switch ((string)row[2])
556 + {
557 + case "1":
558 + application.DumpEnabled = ComPlus.YesNoType.yes;
559 + break;
560 + case "0":
561 + application.DumpEnabled = ComPlus.YesNoType.no;
562 + break;
563 + default:
564 + // TODO: Warning
565 + break;
566 + }
567 + break;
568 + case "DumpOnException":
569 + switch ((string)row[2])
570 + {
571 + case "1":
572 + application.DumpOnException = ComPlus.YesNoType.yes;
573 + break;
574 + case "0":
575 + application.DumpOnException = ComPlus.YesNoType.no;
576 + break;
577 + default:
578 + // TODO: Warning
579 + break;
580 + }
581 + break;
582 + case "DumpOnFailfast":
583 + switch ((string)row[2])
584 + {
585 + case "1":
586 + application.DumpOnFailfast = ComPlus.YesNoType.yes;
587 + break;
588 + case "0":
589 + application.DumpOnFailfast = ComPlus.YesNoType.no;
590 + break;
591 + default:
592 + // TODO: Warning
593 + break;
594 + }
595 + break;
596 + case "DumpPath":
597 + application.DumpPath = (string)row[2];
598 + break;
599 + case "EventsEnabled":
600 + switch ((string)row[2])
601 + {
602 + case "1":
603 + application.EventsEnabled = ComPlus.YesNoType.yes;
604 + break;
605 + case "0":
606 + application.EventsEnabled = ComPlus.YesNoType.no;
607 + break;
608 + default:
609 + // TODO: Warning
610 + break;
611 + }
612 + break;
613 + case "Identity":
614 + application.Identity = (string)row[2];
615 + break;
616 + case "ImpersonationLevel":
617 + switch ((string)row[2])
618 + {
619 + case "1":
620 + application.ImpersonationLevel = ComPlus.ComPlusApplication.ImpersonationLevelType.anonymous;
621 + break;
622 + case "2":
623 + application.ImpersonationLevel = ComPlus.ComPlusApplication.ImpersonationLevelType.identify;
624 + break;
625 + case "3":
626 + application.ImpersonationLevel = ComPlus.ComPlusApplication.ImpersonationLevelType.impersonate;
627 + break;
628 + case "4":
629 + application.ImpersonationLevel = ComPlus.ComPlusApplication.ImpersonationLevelType.@delegate;
630 + break;
631 + default:
632 + // TODO: Warning
633 + break;
634 + }
635 + break;
636 + case "IsEnabled":
637 + switch ((string)row[2])
638 + {
639 + case "1":
640 + application.IsEnabled = ComPlus.YesNoType.yes;
641 + break;
642 + case "0":
643 + application.IsEnabled = ComPlus.YesNoType.no;
644 + break;
645 + default:
646 + // TODO: Warning
647 + break;
648 + }
649 + break;
650 + case "MaxDumpCount":
651 + int maxDumpCount;
652 + if (Int32.TryParse((string)row[2], out maxDumpCount))
653 + {
654 + application.MaxDumpCount = maxDumpCount;
655 + }
656 + else
657 + {
658 + // TODO: Warning
659 + }
660 + break;
661 + case "Password":
662 + application.Password = (string)row[2];
663 + break;
664 + case "QCAuthenticateMsgs":
665 + switch ((string)row[2])
666 + {
667 + case "0":
668 + application.QCAuthenticateMsgs = ComPlus.ComPlusApplication.QCAuthenticateMsgsType.secureApps;
669 + break;
670 + case "1":
671 + application.QCAuthenticateMsgs = ComPlus.ComPlusApplication.QCAuthenticateMsgsType.off;
672 + break;
673 + case "2":
674 + application.QCAuthenticateMsgs = ComPlus.ComPlusApplication.QCAuthenticateMsgsType.on;
675 + break;
676 + default:
677 + // TODO: Warning
678 + break;
679 + }
680 + break;
681 + case "QCListenerMaxThreads":
682 + int qcListenerMaxThreads;
683 + if (Int32.TryParse((string)row[2], out qcListenerMaxThreads))
684 + {
685 + application.QCListenerMaxThreads = qcListenerMaxThreads;
686 + }
687 + else
688 + {
689 + // TODO: Warning
690 + }
691 + break;
692 + case "QueueListenerEnabled":
693 + switch ((string)row[2])
694 + {
695 + case "1":
696 + application.QueueListenerEnabled = ComPlus.YesNoType.yes;
697 + break;
698 + case "0":
699 + application.QueueListenerEnabled = ComPlus.YesNoType.no;
700 + break;
701 + default:
702 + // TODO: Warning
703 + break;
704 + }
705 + break;
706 + case "QueuingEnabled":
707 + switch ((string)row[2])
708 + {
709 + case "1":
710 + application.QueuingEnabled = ComPlus.YesNoType.yes;
711 + break;
712 + case "0":
713 + application.QueuingEnabled = ComPlus.YesNoType.no;
714 + break;
715 + default:
716 + // TODO: Warning
717 + break;
718 + }
719 + break;
720 + case "RecycleActivationLimit":
721 + int recycleActivationLimit;
722 + if (Int32.TryParse((string)row[2], out recycleActivationLimit))
723 + {
724 + application.RecycleActivationLimit = recycleActivationLimit;
725 + }
726 + else
727 + {
728 + // TODO: Warning
729 + }
730 + break;
731 + case "RecycleCallLimit":
732 + int recycleCallLimit;
733 + if (Int32.TryParse((string)row[2], out recycleCallLimit))
734 + {
735 + application.RecycleCallLimit = recycleCallLimit;
736 + }
737 + else
738 + {
739 + // TODO: Warning
740 + }
741 + break;
742 + case "RecycleExpirationTimeout":
743 + int recycleExpirationTimeout;
744 + if (Int32.TryParse((string)row[2], out recycleExpirationTimeout))
745 + {
746 + application.RecycleExpirationTimeout = recycleExpirationTimeout;
747 + }
748 + else
749 + {
750 + // TODO: Warning
751 + }
752 + break;
753 + case "RecycleLifetimeLimit":
754 + int recycleLifetimeLimit;
755 + if (Int32.TryParse((string)row[2], out recycleLifetimeLimit))
756 + {
757 + application.RecycleLifetimeLimit = recycleLifetimeLimit;
758 + }
759 + else
760 + {
761 + // TODO: Warning
762 + }
763 + break;
764 + case "RecycleMemoryLimit":
765 + int recycleMemoryLimit;
766 + if (Int32.TryParse((string)row[2], out recycleMemoryLimit))
767 + {
768 + application.RecycleMemoryLimit = recycleMemoryLimit;
769 + }
770 + else
771 + {
772 + // TODO: Warning
773 + }
774 + break;
775 + case "Replicable":
776 + switch ((string)row[2])
777 + {
778 + case "1":
779 + application.Replicable = ComPlus.YesNoType.yes;
780 + break;
781 + case "0":
782 + application.Replicable = ComPlus.YesNoType.no;
783 + break;
784 + default:
785 + // TODO: Warning
786 + break;
787 + }
788 + break;
789 + case "RunForever":
790 + switch ((string)row[2])
791 + {
792 + case "1":
793 + application.RunForever = ComPlus.YesNoType.yes;
794 + break;
795 + case "0":
796 + application.RunForever = ComPlus.YesNoType.no;
797 + break;
798 + default:
799 + // TODO: Warning
800 + break;
801 + }
802 + break;
803 + case "ShutdownAfter":
804 + int shutdownAfter;
805 + if (Int32.TryParse((string)row[2], out shutdownAfter))
806 + {
807 + application.ShutdownAfter = shutdownAfter;
808 + }
809 + else
810 + {
811 + // TODO: Warning
812 + }
813 + break;
814 + case "SoapActivated":
815 + switch ((string)row[2])
816 + {
817 + case "1":
818 + application.SoapActivated = ComPlus.YesNoType.yes;
819 + break;
820 + case "0":
821 + application.SoapActivated = ComPlus.YesNoType.no;
822 + break;
823 + default:
824 + // TODO: Warning
825 + break;
826 + }
827 + break;
828 + case "SoapBaseUrl":
829 + application.SoapBaseUrl = (string)row[2];
830 + break;
831 + case "SoapMailTo":
832 + application.SoapMailTo = (string)row[2];
833 + break;
834 + case "SoapVRoot":
835 + application.SoapVRoot = (string)row[2];
836 + break;
837 + case "SRPEnabled":
838 + switch ((string)row[2])
839 + {
840 + case "1":
841 + application.SRPEnabled = ComPlus.YesNoType.yes;
842 + break;
843 + case "0":
844 + application.SRPEnabled = ComPlus.YesNoType.no;
845 + break;
846 + default:
847 + // TODO: Warning
848 + break;
849 + }
850 + break;
851 + case "SRPTrustLevel":
852 + switch ((string)row[2])
853 + {
854 + case "0":
855 + application.SRPTrustLevel = ComPlus.ComPlusApplication.SRPTrustLevelType.disallowed;
856 + break;
857 + case "262144":
858 + application.SRPTrustLevel = ComPlus.ComPlusApplication.SRPTrustLevelType.fullyTrusted;
859 + break;
860 + default:
861 + // TODO: Warning
862 + break;
863 + }
864 + break;
865 + default:
866 + // TODO: Warning
867 + break;
868 + }
869 + }
870 + }
871 +
872 + /// <summary>
873 + /// Decompile the ComPlusApplicationRole table.
874 + /// </summary>
875 + /// <param name="table">The table to decompile.</param>
876 + private void DecompileComPlusApplicationRoleTable(Table table)
877 + {
878 + foreach (Row row in table.Rows)
879 + {
880 + ComPlus.ComPlusApplicationRole applicationRole = new ComPlus.ComPlusApplicationRole();
881 +
882 + applicationRole.Id = (string)row[0];
883 + applicationRole.Application = (string)row[1];
884 +
885 + if (null != row[3])
886 + {
887 + applicationRole.Name = (string)row[3];
888 + }
889 +
890 + if (null != row[2])
891 + {
892 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
893 + if (null != component)
894 + {
895 + component.AddChild(applicationRole);
896 + }
897 + else
898 + {
899 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
900 + }
901 + }
902 + else
903 + {
904 + this.Core.RootElement.AddChild(applicationRole);
905 + }
906 + this.Core.IndexElement(row, applicationRole);
907 + }
908 + }
909 +
910 + /// <summary>
911 + /// Decompile the ComPlusApplicationRoleProperty table.
912 + /// </summary>
913 + /// <param name="table">The table to decompile.</param>
914 + private void DecompileComPlusApplicationRolePropertyTable(Table table)
915 + {
916 + foreach (Row row in table.Rows)
917 + {
918 + ComPlus.ComPlusApplicationRole applicationRole = (ComPlus.ComPlusApplicationRole)this.Core.GetIndexedElement("ComPlusApplicationRole", (string)row[0]);
919 + if (null == applicationRole)
920 + {
921 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ApplicationRole_", (string)row[0], "ComPlusApplicationRole"));
922 + }
923 +
924 + switch ((string)row[1])
925 + {
926 + case "Description":
927 + applicationRole.Description = (string)row[2];
928 + break;
929 + default:
930 + // TODO: Warning
931 + break;
932 + }
933 + }
934 + }
935 +
936 + /// <summary>
937 + /// Decompile the ComPlusUserInApplicationRole table.
938 + /// </summary>
939 + /// <param name="table">The table to decompile.</param>
940 + private void DecompileComPlusUserInApplicationRoleTable(Table table)
941 + {
942 + foreach (Row row in table.Rows)
943 + {
944 + ComPlus.ComPlusUserInApplicationRole userInApplicationRole = new ComPlus.ComPlusUserInApplicationRole();
945 +
946 + userInApplicationRole.Id = (string)row[0];
947 + userInApplicationRole.ApplicationRole = (string)row[1];
948 + userInApplicationRole.User = (string)row[3];
949 +
950 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
951 + if (null != component)
952 + {
953 + component.AddChild(userInApplicationRole);
954 + }
955 + else
956 + {
957 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
958 + }
959 + }
960 + }
961 +
962 + /// <summary>
963 + /// Decompile the ComPlusGroupInApplicationRole table.
964 + /// </summary>
965 + /// <param name="table">The table to decompile.</param>
966 + private void DecompileComPlusGroupInApplicationRoleTable(Table table)
967 + {
968 + foreach (Row row in table.Rows)
969 + {
970 + ComPlus.ComPlusGroupInApplicationRole groupInApplicationRole = new ComPlus.ComPlusGroupInApplicationRole();
971 +
972 + groupInApplicationRole.Id = (string)row[0];
973 + groupInApplicationRole.ApplicationRole = (string)row[1];
974 + groupInApplicationRole.Group = (string)row[3];
975 +
976 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
977 + if (null != component)
978 + {
979 + component.AddChild(groupInApplicationRole);
980 + }
981 + else
982 + {
983 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
984 + }
985 + }
986 + }
987 +
988 + /// <summary>
989 + /// Decompile the ComPlusAssembly table.
990 + /// </summary>
991 + /// <param name="table">The table to decompile.</param>
992 + private void DecompileComPlusAssemblyTable(Table table)
993 + {
994 + foreach (Row row in table.Rows)
995 + {
996 + ComPlus.ComPlusAssembly assembly = new ComPlus.ComPlusAssembly();
997 +
998 + assembly.Id = (string)row[0];
999 + assembly.Application = (string)row[1];
1000 +
1001 + if (null != row[3])
1002 + {
1003 + assembly.AssemblyName = (string)row[3];
1004 + }
1005 +
1006 + if (null != row[4])
1007 + {
1008 + assembly.DllPath = (string)row[4];
1009 + }
1010 +
1011 + if (null != row[5])
1012 + {
1013 + assembly.TlbPath = (string)row[5];
1014 + }
1015 +
1016 + if (null != row[6])
1017 + {
1018 + assembly.PSDllPath = (string)row[6];
1019 + }
1020 +
1021 + int attributes = (int)row[7];
1022 +
1023 + if (0 != (attributes & (int)ComPlusCompiler.CpiAssemblyAttributes.EventClass))
1024 + {
1025 + assembly.EventClass = ComPlus.YesNoType.yes;
1026 + }
1027 +
1028 + if (0 != (attributes & (int)ComPlusCompiler.CpiAssemblyAttributes.DotNetAssembly))
1029 + {
1030 + assembly.Type = ComPlus.ComPlusAssembly.TypeType.net;
1031 + }
1032 +
1033 + if (0 != (attributes & (int)ComPlusCompiler.CpiAssemblyAttributes.DllPathFromGAC))
1034 + {
1035 + assembly.DllPathFromGAC = ComPlus.YesNoType.yes;
1036 + }
1037 +
1038 + if (0 != (attributes & (int)ComPlusCompiler.CpiAssemblyAttributes.RegisterInCommit))
1039 + {
1040 + assembly.RegisterInCommit = ComPlus.YesNoType.yes;
1041 + }
1042 +
1043 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
1044 + if (null != component)
1045 + {
1046 + component.AddChild(assembly);
1047 + }
1048 + else
1049 + {
1050 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
1051 + }
1052 + this.Core.IndexElement(row, assembly);
1053 + }
1054 + }
1055 +
1056 + /// <summary>
1057 + /// Decompile the ComPlusAssemblyDependency table.
1058 + /// </summary>
1059 + /// <param name="table">The table to decompile.</param>
1060 + private void DecompileComPlusAssemblyDependencyTable(Table table)
1061 + {
1062 + foreach (Row row in table.Rows)
1063 + {
1064 + ComPlus.ComPlusAssemblyDependency assemblyDependency = new ComPlus.ComPlusAssemblyDependency();
1065 +
1066 + assemblyDependency.RequiredAssembly = (string)row[1];
1067 +
1068 + ComPlus.ComPlusAssembly assembly = (ComPlus.ComPlusAssembly)this.Core.GetIndexedElement("ComPlusAssembly", (string)row[0]);
1069 + if (null != assembly)
1070 + {
1071 + assembly.AddChild(assemblyDependency);
1072 + }
1073 + else
1074 + {
1075 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Assembly_", (string)row[0], "ComPlusAssembly"));
1076 + }
1077 + }
1078 + }
1079 +
1080 + /// <summary>
1081 + /// Decompile the ComPlusComponent table.
1082 + /// </summary>
1083 + /// <param name="table">The table to decompile.</param>
1084 + private void DecompileComPlusComponentTable(Table table)
1085 + {
1086 + foreach (Row row in table.Rows)
1087 + {
1088 + ComPlus.ComPlusComponent comPlusComponent = new ComPlus.ComPlusComponent();
1089 +
1090 + comPlusComponent.Id = (string)row[0];
1091 +
1092 + try
1093 + {
1094 + Guid clsid = new Guid((string)row[2]);
1095 + comPlusComponent.CLSID = clsid.ToString().ToUpper();
1096 + }
1097 + catch
1098 + {
1099 + // TODO: Warning
1100 + }
1101 +
1102 + ComPlus.ComPlusAssembly assembly = (ComPlus.ComPlusAssembly)this.Core.GetIndexedElement("ComPlusAssembly", (string)row[1]);
1103 + if (null != assembly)
1104 + {
1105 + assembly.AddChild(comPlusComponent);
1106 + }
1107 + else
1108 + {
1109 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Assembly_", (string)row[1], "ComPlusAssembly"));
1110 + }
1111 + this.Core.IndexElement(row, comPlusComponent);
1112 + }
1113 + }
1114 +
1115 + /// <summary>
1116 + /// Decompile the ComPlusComponentProperty table.
1117 + /// </summary>
1118 + /// <param name="table">The table to decompile.</param>
1119 + private void DecompileComPlusComponentPropertyTable(Table table)
1120 + {
1121 + foreach (Row row in table.Rows)
1122 + {
1123 + ComPlus.ComPlusComponent comPlusComponent = (ComPlus.ComPlusComponent)this.Core.GetIndexedElement("ComPlusComponent", (string)row[0]);
1124 + if (null == comPlusComponent)
1125 + {
1126 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ComPlusComponent_", (string)row[0], "ComPlusComponent"));
1127 + }
1128 +
1129 + switch ((string)row[1])
1130 + {
1131 + case "AllowInprocSubscribers":
1132 + switch ((string)row[2])
1133 + {
1134 + case "1":
1135 + comPlusComponent.AllowInprocSubscribers = ComPlus.YesNoType.yes;
1136 + break;
1137 + case "0":
1138 + comPlusComponent.AllowInprocSubscribers = ComPlus.YesNoType.no;
1139 + break;
1140 + default:
1141 + // TODO: Warning
1142 + break;
1143 + }
1144 + break;
1145 + case "ComponentAccessChecksEnabled":
1146 + switch ((string)row[2])
1147 + {
1148 + case "1":
1149 + comPlusComponent.ComponentAccessChecksEnabled = ComPlus.YesNoType.yes;
1150 + break;
1151 + case "0":
1152 + comPlusComponent.ComponentAccessChecksEnabled = ComPlus.YesNoType.no;
1153 + break;
1154 + default:
1155 + // TODO: Warning
1156 + break;
1157 + }
1158 + break;
1159 + case "ComponentTransactionTimeout":
1160 + int componentTransactionTimeout;
1161 + if (Int32.TryParse((string)row[2], out componentTransactionTimeout))
1162 + {
1163 + comPlusComponent.ComponentTransactionTimeout = componentTransactionTimeout;
1164 + }
1165 + else
1166 + {
1167 + // TODO: Warning
1168 + }
1169 + break;
1170 + case "ComponentTransactionTimeoutEnabled":
1171 + switch ((string)row[2])
1172 + {
1173 + case "1":
1174 + comPlusComponent.ComponentTransactionTimeoutEnabled = ComPlus.YesNoType.yes;
1175 + break;
1176 + case "0":
1177 + comPlusComponent.ComponentTransactionTimeoutEnabled = ComPlus.YesNoType.no;
1178 + break;
1179 + default:
1180 + // TODO: Warning
1181 + break;
1182 + }
1183 + break;
1184 + case "COMTIIntrinsics":
1185 + switch ((string)row[2])
1186 + {
1187 + case "1":
1188 + comPlusComponent.COMTIIntrinsics = ComPlus.YesNoType.yes;
1189 + break;
1190 + case "0":
1191 + comPlusComponent.COMTIIntrinsics = ComPlus.YesNoType.no;
1192 + break;
1193 + default:
1194 + // TODO: Warning
1195 + break;
1196 + }
1197 + break;
1198 + case "ConstructionEnabled":
1199 + switch ((string)row[2])
1200 + {
1201 + case "1":
1202 + comPlusComponent.ConstructionEnabled = ComPlus.YesNoType.yes;
1203 + break;
1204 + case "0":
1205 + comPlusComponent.ConstructionEnabled = ComPlus.YesNoType.no;
1206 + break;
1207 + default:
1208 + // TODO: Warning
1209 + break;
1210 + }
1211 + break;
1212 + case "ConstructorString":
1213 + comPlusComponent.ConstructorString = (string)row[2];
1214 + break;
1215 + case "CreationTimeout":
1216 + int creationTimeout;
1217 + if (Int32.TryParse((string)row[2], out creationTimeout))
1218 + {
1219 + comPlusComponent.CreationTimeout = creationTimeout;
1220 + }
1221 + else
1222 + {
1223 + // TODO: Warning
1224 + }
1225 + break;
1226 + case "Description":
1227 + comPlusComponent.Description = (string)row[2];
1228 + break;
1229 + case "EventTrackingEnabled":
1230 + switch ((string)row[2])
1231 + {
1232 + case "1":
1233 + comPlusComponent.EventTrackingEnabled = ComPlus.YesNoType.yes;
1234 + break;
1235 + case "0":
1236 + comPlusComponent.EventTrackingEnabled = ComPlus.YesNoType.no;
1237 + break;
1238 + default:
1239 + // TODO: Warning
1240 + break;
1241 + }
1242 + break;
1243 + case "ExceptionClass":
1244 + comPlusComponent.ExceptionClass = (string)row[2];
1245 + break;
1246 + case "FireInParallel":
1247 + switch ((string)row[2])
1248 + {
1249 + case "1":
1250 + comPlusComponent.FireInParallel = ComPlus.YesNoType.yes;
1251 + break;
1252 + case "0":
1253 + comPlusComponent.FireInParallel = ComPlus.YesNoType.no;
1254 + break;
1255 + default:
1256 + // TODO: Warning
1257 + break;
1258 + }
1259 + break;
1260 + case "IISIntrinsics":
1261 + switch ((string)row[2])
1262 + {
1263 + case "1":
1264 + comPlusComponent.IISIntrinsics = ComPlus.YesNoType.yes;
1265 + break;
1266 + case "0":
1267 + comPlusComponent.IISIntrinsics = ComPlus.YesNoType.no;
1268 + break;
1269 + default:
1270 + // TODO: Warning
1271 + break;
1272 + }
1273 + break;
1274 + case "InitializesServerApplication":
1275 + switch ((string)row[2])
1276 + {
1277 + case "1":
1278 + comPlusComponent.InitializesServerApplication = ComPlus.YesNoType.yes;
1279 + break;
1280 + case "0":
1281 + comPlusComponent.InitializesServerApplication = ComPlus.YesNoType.no;
1282 + break;
1283 + default:
1284 + // TODO: Warning
1285 + break;
1286 + }
1287 + break;
1288 + case "IsEnabled":
1289 + switch ((string)row[2])
1290 + {
1291 + case "1":
1292 + comPlusComponent.IsEnabled = ComPlus.YesNoType.yes;
1293 + break;
1294 + case "0":
1295 + comPlusComponent.IsEnabled = ComPlus.YesNoType.no;
1296 + break;
1297 + default:
1298 + // TODO: Warning
1299 + break;
1300 + }
1301 + break;
1302 + case "IsPrivateComponent":
1303 + switch ((string)row[2])
1304 + {
1305 + case "1":
1306 + comPlusComponent.IsPrivateComponent = ComPlus.YesNoType.yes;
1307 + break;
1308 + case "0":
1309 + comPlusComponent.IsPrivateComponent = ComPlus.YesNoType.no;
1310 + break;
1311 + default:
1312 + // TODO: Warning
1313 + break;
1314 + }
1315 + break;
1316 + case "JustInTimeActivation":
1317 + switch ((string)row[2])
1318 + {
1319 + case "1":
1320 + comPlusComponent.JustInTimeActivation = ComPlus.YesNoType.yes;
1321 + break;
1322 + case "0":
1323 + comPlusComponent.JustInTimeActivation = ComPlus.YesNoType.no;
1324 + break;
1325 + default:
1326 + // TODO: Warning
1327 + break;
1328 + }
1329 + break;
1330 + case "LoadBalancingSupported":
1331 + switch ((string)row[2])
1332 + {
1333 + case "1":
1334 + comPlusComponent.LoadBalancingSupported = ComPlus.YesNoType.yes;
1335 + break;
1336 + case "0":
1337 + comPlusComponent.LoadBalancingSupported = ComPlus.YesNoType.no;
1338 + break;
1339 + default:
1340 + // TODO: Warning
1341 + break;
1342 + }
1343 + break;
1344 + case "MaxPoolSize":
1345 + int maxPoolSize;
1346 + if (Int32.TryParse((string)row[2], out maxPoolSize))
1347 + {
1348 + comPlusComponent.MaxPoolSize = maxPoolSize;
1349 + }
1350 + else
1351 + {
1352 + // TODO: Warning
1353 + }
1354 + break;
1355 + case "MinPoolSize":
1356 + int minPoolSize;
1357 + if (Int32.TryParse((string)row[2], out minPoolSize))
1358 + {
1359 + comPlusComponent.MinPoolSize = minPoolSize;
1360 + }
1361 + else
1362 + {
1363 + // TODO: Warning
1364 + }
1365 + break;
1366 + case "MultiInterfacePublisherFilterCLSID":
1367 + comPlusComponent.MultiInterfacePublisherFilterCLSID = (string)row[2];
1368 + break;
1369 + case "MustRunInClientContext":
1370 + switch ((string)row[2])
1371 + {
1372 + case "1":
1373 + comPlusComponent.MustRunInClientContext = ComPlus.YesNoType.yes;
1374 + break;
1375 + case "0":
1376 + comPlusComponent.MustRunInClientContext = ComPlus.YesNoType.no;
1377 + break;
1378 + default:
1379 + // TODO: Warning
1380 + break;
1381 + }
1382 + break;
1383 + case "MustRunInDefaultContext":
1384 + switch ((string)row[2])
1385 + {
1386 + case "1":
1387 + comPlusComponent.MustRunInDefaultContext = ComPlus.YesNoType.yes;
1388 + break;
1389 + case "0":
1390 + comPlusComponent.MustRunInDefaultContext = ComPlus.YesNoType.no;
1391 + break;
1392 + default:
1393 + // TODO: Warning
1394 + break;
1395 + }
1396 + break;
1397 + case "ObjectPoolingEnabled":
1398 + switch ((string)row[2])
1399 + {
1400 + case "1":
1401 + comPlusComponent.ObjectPoolingEnabled = ComPlus.YesNoType.yes;
1402 + break;
1403 + case "0":
1404 + comPlusComponent.ObjectPoolingEnabled = ComPlus.YesNoType.no;
1405 + break;
1406 + default:
1407 + // TODO: Warning
1408 + break;
1409 + }
1410 + break;
1411 + case "PublisherID":
1412 + comPlusComponent.PublisherID = (string)row[2];
1413 + break;
1414 + case "SoapAssemblyName":
1415 + comPlusComponent.SoapAssemblyName = (string)row[2];
1416 + break;
1417 + case "SoapTypeName":
1418 + comPlusComponent.SoapTypeName = (string)row[2];
1419 + break;
1420 + case "Synchronization":
1421 + switch ((string)row[2])
1422 + {
1423 + case "0":
1424 + comPlusComponent.Synchronization = ComPlus.ComPlusComponent.SynchronizationType.ignored;
1425 + break;
1426 + case "1":
1427 + comPlusComponent.Synchronization = ComPlus.ComPlusComponent.SynchronizationType.none;
1428 + break;
1429 + case "2":
1430 + comPlusComponent.Synchronization = ComPlus.ComPlusComponent.SynchronizationType.supported;
1431 + break;
1432 + case "3":
1433 + comPlusComponent.Synchronization = ComPlus.ComPlusComponent.SynchronizationType.required;
1434 + break;
1435 + case "4":
1436 + comPlusComponent.Synchronization = ComPlus.ComPlusComponent.SynchronizationType.requiresNew;
1437 + break;
1438 + default:
1439 + // TODO: Warning
1440 + break;
1441 + }
1442 + break;
1443 + case "Transaction":
1444 + switch ((string)row[2])
1445 + {
1446 + case "0":
1447 + comPlusComponent.Transaction = ComPlus.ComPlusComponent.TransactionType.ignored;
1448 + break;
1449 + case "1":
1450 + comPlusComponent.Transaction = ComPlus.ComPlusComponent.TransactionType.none;
1451 + break;
1452 + case "2":
1453 + comPlusComponent.Transaction = ComPlus.ComPlusComponent.TransactionType.supported;
1454 + break;
1455 + case "3":
1456 + comPlusComponent.Transaction = ComPlus.ComPlusComponent.TransactionType.required;
1457 + break;
1458 + case "4":
1459 + comPlusComponent.Transaction = ComPlus.ComPlusComponent.TransactionType.requiresNew;
1460 + break;
1461 + default:
1462 + // TODO: Warning
1463 + break;
1464 + }
1465 + break;
1466 + case "TxIsolationLevel":
1467 + switch ((string)row[2])
1468 + {
1469 + case "0":
1470 + comPlusComponent.TxIsolationLevel = ComPlus.ComPlusComponent.TxIsolationLevelType.any;
1471 + break;
1472 + case "1":
1473 + comPlusComponent.TxIsolationLevel = ComPlus.ComPlusComponent.TxIsolationLevelType.readUnCommitted;
1474 + break;
1475 + case "2":
1476 + comPlusComponent.TxIsolationLevel = ComPlus.ComPlusComponent.TxIsolationLevelType.readCommitted;
1477 + break;
1478 + case "3":
1479 + comPlusComponent.TxIsolationLevel = ComPlus.ComPlusComponent.TxIsolationLevelType.repeatableRead;
1480 + break;
1481 + case "4":
1482 + comPlusComponent.TxIsolationLevel = ComPlus.ComPlusComponent.TxIsolationLevelType.serializable;
1483 + break;
1484 + default:
1485 + // TODO: Warning
1486 + break;
1487 + }
1488 + break;
1489 + default:
1490 + // TODO: Warning
1491 + break;
1492 + }
1493 + }
1494 + }
1495 +
1496 + /// <summary>
1497 + /// Decompile the ComPlusRoleForComponent table.
1498 + /// </summary>
1499 + /// <param name="table">The table to decompile.</param>
1500 + private void DecompileComPlusRoleForComponentTable(Table table)
1501 + {
1502 + foreach (Row row in table.Rows)
1503 + {
1504 + ComPlus.ComPlusRoleForComponent roleForComponent = new ComPlus.ComPlusRoleForComponent();
1505 +
1506 + roleForComponent.Id = (string)row[0];
1507 + roleForComponent.Component = (string)row[1];
1508 + roleForComponent.ApplicationRole = (string)row[2];
1509 +
1510 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[3]);
1511 + if (null != component)
1512 + {
1513 + component.AddChild(roleForComponent);
1514 + }
1515 + else
1516 + {
1517 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[3], "Component"));
1518 + }
1519 + }
1520 + }
1521 +
1522 + /// <summary>
1523 + /// Decompile the ComPlusInterface table.
1524 + /// </summary>
1525 + /// <param name="table">The table to decompile.</param>
1526 + private void DecompileComPlusInterfaceTable(Table table)
1527 + {
1528 + foreach (Row row in table.Rows)
1529 + {
1530 + ComPlus.ComPlusInterface comPlusInterface = new ComPlus.ComPlusInterface();
1531 +
1532 + comPlusInterface.Id = (string)row[0];
1533 +
1534 + try
1535 + {
1536 + Guid iid = new Guid((string)row[2]);
1537 + comPlusInterface.IID = iid.ToString().ToUpper();
1538 + }
1539 + catch
1540 + {
1541 + // TODO: Warning
1542 + }
1543 +
1544 + ComPlus.ComPlusComponent comPlusComponent = (ComPlus.ComPlusComponent)this.Core.GetIndexedElement("ComPlusComponent", (string)row[1]);
1545 + if (null != comPlusComponent)
1546 + {
1547 + comPlusComponent.AddChild(comPlusInterface);
1548 + }
1549 + else
1550 + {
1551 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ComPlusComponent_", (string)row[1], "ComPlusComponent"));
1552 + }
1553 + this.Core.IndexElement(row, comPlusInterface);
1554 + }
1555 + }
1556 +
1557 + /// <summary>
1558 + /// Decompile the ComPlusInterfaceProperty table.
1559 + /// </summary>
1560 + /// <param name="table">The table to decompile.</param>
1561 + private void DecompileComPlusInterfacePropertyTable(Table table)
1562 + {
1563 + foreach (Row row in table.Rows)
1564 + {
1565 + ComPlus.ComPlusInterface comPlusInterface = (ComPlus.ComPlusInterface)this.Core.GetIndexedElement("ComPlusInterface", (string)row[0]);
1566 + if (null == comPlusInterface)
1567 + {
1568 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Interface_", (string)row[0], "ComPlusInterface"));
1569 + }
1570 +
1571 + switch ((string)row[1])
1572 + {
1573 + case "Description":
1574 + comPlusInterface.Description = (string)row[2];
1575 + break;
1576 + case "QueuingEnabled":
1577 + switch ((string)row[2])
1578 + {
1579 + case "1":
1580 + comPlusInterface.QueuingEnabled = ComPlus.YesNoType.yes;
1581 + break;
1582 + case "0":
1583 + comPlusInterface.QueuingEnabled = ComPlus.YesNoType.no;
1584 + break;
1585 + default:
1586 + // TODO: Warning
1587 + break;
1588 + }
1589 + break;
1590 + default:
1591 + // TODO: Warning
1592 + break;
1593 + }
1594 + }
1595 + }
1596 +
1597 + /// <summary>
1598 + /// Decompile the ComPlusRoleForInterface table.
1599 + /// </summary>
1600 + /// <param name="table">The table to decompile.</param>
1601 + private void DecompileComPlusRoleForInterfaceTable(Table table)
1602 + {
1603 + foreach (Row row in table.Rows)
1604 + {
1605 + ComPlus.ComPlusRoleForInterface roleForInterface = new ComPlus.ComPlusRoleForInterface();
1606 +
1607 + roleForInterface.Id = (string)row[0];
1608 + roleForInterface.Interface = (string)row[1];
1609 + roleForInterface.ApplicationRole = (string)row[2];
1610 +
1611 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[3]);
1612 + if (null != component)
1613 + {
1614 + component.AddChild(roleForInterface);
1615 + }
1616 + else
1617 + {
1618 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[3], "Component"));
1619 + }
1620 + }
1621 + }
1622 +
1623 + /// <summary>
1624 + /// Decompile the ComPlusMethod table.
1625 + /// </summary>
1626 + /// <param name="table">The table to decompile.</param>
1627 + private void DecompileComPlusMethodTable(Table table)
1628 + {
1629 + foreach (Row row in table.Rows)
1630 + {
1631 + ComPlus.ComPlusMethod comPlusMethod = new ComPlus.ComPlusMethod();
1632 +
1633 + comPlusMethod.Id = (string)row[0];
1634 +
1635 + if (null != row[2])
1636 + {
1637 + comPlusMethod.Index = (int)row[2];
1638 + }
1639 +
1640 + if (null != row[3])
1641 + {
1642 + comPlusMethod.Name = (string)row[3];
1643 + }
1644 +
1645 + ComPlus.ComPlusInterface comPlusInterface = (ComPlus.ComPlusInterface)this.Core.GetIndexedElement("ComPlusInterface", (string)row[1]);
1646 + if (null != comPlusInterface)
1647 + {
1648 + comPlusInterface.AddChild(comPlusMethod);
1649 + }
1650 + else
1651 + {
1652 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Interface_", (string)row[1], "ComPlusInterface"));
1653 + }
1654 + this.Core.IndexElement(row, comPlusMethod);
1655 + }
1656 + }
1657 +
1658 + /// <summary>
1659 + /// Decompile the ComPlusMethodProperty table.
1660 + /// </summary>
1661 + /// <param name="table">The table to decompile.</param>
1662 + private void DecompileComPlusMethodPropertyTable(Table table)
1663 + {
1664 + foreach (Row row in table.Rows)
1665 + {
1666 + ComPlus.ComPlusMethod comPlusMethod = (ComPlus.ComPlusMethod)this.Core.GetIndexedElement("ComPlusMethod", (string)row[0]);
1667 + if (null == comPlusMethod)
1668 + {
1669 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Method_", (string)row[0], "ComPlusMethod"));
1670 + }
1671 +
1672 + switch ((string)row[1])
1673 + {
1674 + case "AutoComplete":
1675 + switch ((string)row[2])
1676 + {
1677 + case "1":
1678 + comPlusMethod.AutoComplete = ComPlus.YesNoType.yes;
1679 + break;
1680 + case "0":
1681 + comPlusMethod.AutoComplete = ComPlus.YesNoType.no;
1682 + break;
1683 + default:
1684 + // TODO: Warning
1685 + break;
1686 + }
1687 + break;
1688 + case "Description":
1689 + comPlusMethod.Description = (string)row[2];
1690 + break;
1691 + default:
1692 + // TODO: Warning
1693 + break;
1694 + }
1695 + }
1696 + }
1697 +
1698 + /// <summary>
1699 + /// Decompile the ComPlusRoleForMethod table.
1700 + /// </summary>
1701 + /// <param name="table">The table to decompile.</param>
1702 + private void DecompileComPlusRoleForMethodTable(Table table)
1703 + {
1704 + foreach (Row row in table.Rows)
1705 + {
1706 + ComPlus.ComPlusRoleForMethod roleForMethod = new ComPlus.ComPlusRoleForMethod();
1707 +
1708 + roleForMethod.Id = (string)row[0];
1709 + roleForMethod.Method = (string)row[1];
1710 + roleForMethod.ApplicationRole = (string)row[2];
1711 +
1712 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[3]);
1713 + if (null != component)
1714 + {
1715 + component.AddChild(roleForMethod);
1716 + }
1717 + else
1718 + {
1719 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[3], "Component"));
1720 + }
1721 + }
1722 + }
1723 +
1724 + /// <summary>
1725 + /// Decompile the ComPlusSubscription table.
1726 + /// </summary>
1727 + /// <param name="table">The table to decompile.</param>
1728 + private void DecompileComPlusSubscriptionTable(Table table)
1729 + {
1730 + foreach (Row row in table.Rows)
1731 + {
1732 + ComPlus.ComPlusSubscription subscription = new ComPlus.ComPlusSubscription();
1733 +
1734 + subscription.Id = (string)row[0];
1735 + subscription.Component = (string)row[1];
1736 + subscription.SubscriptionId = (string)row[3];
1737 + subscription.Name = (string)row[4];
1738 + subscription.EventCLSID = (string)row[5];
1739 + subscription.PublisherID = (string)row[6];
1740 +
1741 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
1742 + if (null != component)
1743 + {
1744 + component.AddChild(subscription);
1745 + }
1746 + else
1747 + {
1748 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
1749 + }
1750 + this.Core.IndexElement(row, subscription);
1751 + }
1752 + }
1753 +
1754 + /// <summary>
1755 + /// Decompile the ComPlusSubscriptionProperty table.
1756 + /// </summary>
1757 + /// <param name="table">The table to decompile.</param>
1758 + private void DecompileComPlusSubscriptionPropertyTable(Table table)
1759 + {
1760 + foreach (Row row in table.Rows)
1761 + {
1762 + ComPlus.ComPlusSubscription subscription = (ComPlus.ComPlusSubscription)this.Core.GetIndexedElement("ComPlusSubscription", (string)row[0]);
1763 + if (null == subscription)
1764 + {
1765 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Subscription_", (string)row[0], "ComPlusSubscription"));
1766 + }
1767 +
1768 + switch ((string)row[1])
1769 + {
1770 + case "Description":
1771 + subscription.Description = (string)row[2];
1772 + break;
1773 + case "Enabled":
1774 + switch ((string)row[2])
1775 + {
1776 + case "1":
1777 + subscription.Enabled = ComPlus.YesNoType.yes;
1778 + break;
1779 + case "0":
1780 + subscription.Enabled = ComPlus.YesNoType.no;
1781 + break;
1782 + default:
1783 + // TODO: Warning
1784 + break;
1785 + }
1786 + break;
1787 + case "EventClassPartitionID":
1788 + subscription.EventClassPartitionID = (string)row[2];
1789 + break;
1790 + case "FilterCriteria":
1791 + subscription.FilterCriteria = (string)row[2];
1792 + break;
1793 + case "InterfaceID":
1794 + subscription.InterfaceID = (string)row[2];
1795 + break;
1796 + case "MachineName":
1797 + subscription.MachineName = (string)row[2];
1798 + break;
1799 + case "MethodName":
1800 + subscription.MethodName = (string)row[2];
1801 + break;
1802 + case "PerUser":
1803 + switch ((string)row[2])
1804 + {
1805 + case "1":
1806 + subscription.PerUser = ComPlus.YesNoType.yes;
1807 + break;
1808 + case "0":
1809 + subscription.PerUser = ComPlus.YesNoType.no;
1810 + break;
1811 + default:
1812 + // TODO: Warning
1813 + break;
1814 + }
1815 + break;
1816 + case "Queued":
1817 + switch ((string)row[2])
1818 + {
1819 + case "1":
1820 + subscription.Queued = ComPlus.YesNoType.yes;
1821 + break;
1822 + case "0":
1823 + subscription.Queued = ComPlus.YesNoType.no;
1824 + break;
1825 + default:
1826 + // TODO: Warning
1827 + break;
1828 + }
1829 + break;
1830 + case "SubscriberMoniker":
1831 + subscription.SubscriberMoniker = (string)row[2];
1832 + break;
1833 + case "UserName":
1834 + subscription.UserName = (string)row[2];
1835 + break;
1836 + default:
1837 + // TODO: Warning
1838 + break;
1839 + }
1840 + }
1841 + }
1842 + }
1843 +}
src/wixext/ComPlusExtensionData.cs new
+64
@@ -0,0 +1,64 @@
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 +namespace WixToolset.Extensions
4 +{
5 + using System;
6 + using System.Reflection;
7 + using WixToolset.Data;
8 + using WixToolset.Extensibility;
9 +
10 + /// <summary>
11 + /// The WiX Toolset COM+ Extension.
12 + /// </summary>
13 + public sealed class ComPlusExtensionData : ExtensionData
14 + {
15 + /// <summary>
16 + /// Gets the default culture.
17 + /// </summary>
18 + /// <value>The default culture.</value>
19 + public override string DefaultCulture
20 + {
21 + get { return "en-us"; }
22 + }
23 +
24 + /// <summary>
25 + /// Gets the optional table definitions for this extension.
26 + /// </summary>
27 + /// <value>The optional table definitions for this extension.</value>
28 + public override TableDefinitionCollection TableDefinitions
29 + {
30 + get
31 + {
32 + return ComPlusExtensionData.GetExtensionTableDefinitions();
33 + }
34 + }
35 +
36 + /// <summary>
37 + /// Gets the library associated with this extension.
38 + /// </summary>
39 + /// <param name="tableDefinitions">The table definitions to use while loading the library.</param>
40 + /// <returns>The loaded library.</returns>
41 + public override Library GetLibrary(TableDefinitionCollection tableDefinitions)
42 + {
43 + return ComPlusExtensionData.GetExtensionLibrary(tableDefinitions);
44 + }
45 +
46 + /// <summary>
47 + /// Internal mechanism to access the extension's table definitions.
48 + /// </summary>
49 + /// <returns>Extension's table definitions.</returns>
50 + internal static TableDefinitionCollection GetExtensionTableDefinitions()
51 + {
52 + return ExtensionData.LoadTableDefinitionHelper(Assembly.GetExecutingAssembly(), "WixToolset.Extensions.Data.tables.xml");
53 + }
54 +
55 + /// <summary>
56 + /// Internal mechanism to access the extension's library.
57 + /// </summary>
58 + /// <returns>Extension's library.</returns>
59 + internal static Library GetExtensionLibrary(TableDefinitionCollection tableDefinitions)
60 + {
61 + return ExtensionData.LoadLibraryHelper(Assembly.GetExecutingAssembly(), "WixToolset.Extensions.Data.complus.wixlib", tableDefinitions);
62 + }
63 + }
64 +}
src/wixext/WixComPlusExtension.csproj new
+50
@@ -0,0 +1,50 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<!-- 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. -->
3 +
4 +
5 +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
6 + <PropertyGroup>
7 + <ProjectGuid>{1497B777-330B-4CFE-927A-22850CD24D64}</ProjectGuid>
8 + <AssemblyName>WixComPlusExtension</AssemblyName>
9 + <OutputType>Library</OutputType>
10 + <RootNamespace>WixToolset.Extensions</RootNamespace>
11 + </PropertyGroup>
12 + <ItemGroup>
13 + <Compile Include="AssemblyInfo.cs" />
14 + <Compile Include="ComPlusCompiler.cs" />
15 + <Compile Include="ComPlusDecompiler.cs" />
16 + <Compile Include="ComPlusExtensionData.cs" />
17 + <MsgGenSource Include="Data\messages.xml">
18 + <ResourcesLogicalName>$(RootNamespace).Data.Messages.resources</ResourcesLogicalName>
19 + </MsgGenSource>
20 + <EmbeddedFlattenedResource Include="Data\tables.xml">
21 + <LogicalName>$(RootNamespace).Data.tables.xml</LogicalName>
22 + </EmbeddedFlattenedResource>
23 + <EmbeddedFlattenedResource Include="Xsd\complus.xsd">
24 + <LogicalName>$(RootNamespace).Xsd.complus.xsd</LogicalName>
25 + </EmbeddedFlattenedResource>
26 + <XsdGenSource Include="Xsd\complus.xsd">
27 + <CommonNamespace>WixToolset.Data.Serialize</CommonNamespace>
28 + <Namespace>WixToolset.Extensions.Serialize.ComPlus</Namespace>
29 + </XsdGenSource>
30 + <None Include="Xsd\complus.xsd">
31 + <Link>complus.xsd</Link>
32 + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
33 + </None>
34 + <EmbeddedResource Include="$(OutputPath)\complus.wixlib">
35 + <Link>Data\complus.wixlib</Link>
36 + </EmbeddedResource>
37 + </ItemGroup>
38 + <ItemGroup>
39 + <Reference Include="System" />
40 + <Reference Include="System.Xml" />
41 + <Reference Include="System.Xml.Linq" />
42 + <ProjectReference Include="..\..\..\libs\WixToolset.Data\WixToolset.Data.csproj" />
43 + <ProjectReference Include="..\..\..\libs\WixToolset.Extensibility\WixToolset.Extensibility.csproj" />
44 + <ProjectReference Include="..\..\..\tools\wix\Wix.csproj" />
45 + <ProjectReference Include="..\wixlib\ComPlusExtension.wixproj">
46 + <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
47 + </ProjectReference>
48 + </ItemGroup>
49 + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), wix.proj))\tools\WixBuild.targets" />
50 +</Project>
src/wixext/complus.xsd new
+944
@@ -0,0 +1,944 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<!-- 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. -->
3 +
4 +
5 +<xs:schema xmlns:html="http://www.w3.org/1999/xhtml"
6 + xmlns:wix="http://wixtoolset.org/schemas/v4/wxs"
7 + xmlns:xs="http://www.w3.org/2001/XMLSchema"
8 + xmlns:xse=" http://wixtoolset.org/schemas/XmlSchemaExtension"
9 + targetNamespace="http://wixtoolset.org/schemas/v4/wxs/complus"
10 + xmlns="http://wixtoolset.org/schemas/v4/wxs/complus">
11 + <xs:annotation>
12 + <xs:documentation>
13 + The source code schema for the WiX Toolset COM+ Extension.
14 + </xs:documentation>
15 + </xs:annotation>
16 +
17 + <xs:import namespace="http://wixtoolset.org/schemas/v4/wxs" />
18 +
19 + <xs:element name="ComPlusPartition">
20 + <xs:annotation>
21 + <xs:appinfo>
22 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
23 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Fragment" />
24 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Module" />
25 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Product" />
26 + </xs:appinfo>
27 + <xs:documentation>
28 + Defines a COM+ partition. If this element is a child of a
29 + Component element, the partition will be created in association with this
30 + component. If the element is a child of any of the Fragment, Module or Product
31 + elements it is considered to be a locater, referencing an existing partition.
32 + </xs:documentation>
33 + </xs:annotation>
34 + <xs:complexType>
35 + <xs:sequence>
36 + <xs:choice minOccurs="0" maxOccurs="unbounded">
37 + <xs:element ref="ComPlusPartitionRole" />
38 + <xs:element ref="ComPlusPartitionUser" />
39 + <xs:element ref="ComPlusApplication" />
40 + </xs:choice>
41 + </xs:sequence>
42 + <xs:attribute name="Id" use="required" type="xs:string">
43 + <xs:annotation><xs:documentation>
44 + Identifier for the element.
45 + </xs:documentation></xs:annotation>
46 + </xs:attribute>
47 + <xs:attribute name="PartitionId" use="optional" type="xs:string">
48 + <xs:annotation><xs:documentation>
49 + Id for the partition. This attribute can be omitted, in
50 + which case an id will be generated on install. If the element is a locater,
51 + this attribute can be omitted if a value is provided for the Name attribute.
52 + </xs:documentation></xs:annotation>
53 + </xs:attribute>
54 + <xs:attribute name="Name" use="optional" type="xs:string">
55 + <xs:annotation><xs:documentation>
56 + Name of the partition. This attribute can be omitted if
57 + the element is a locater, and a value is provided for the PartitionId
58 + attribute.
59 + </xs:documentation></xs:annotation>
60 + </xs:attribute>
61 + <xs:attribute name="Changeable" use="optional" type="YesNoType" />
62 + <xs:attribute name="Deleteable" use="optional" type="YesNoType" />
63 + <xs:attribute name="Description" use="optional" type="xs:string" />
64 + </xs:complexType>
65 + </xs:element>
66 +
67 + <xs:element name="ComPlusPartitionRole">
68 + <xs:annotation>
69 + <xs:appinfo>
70 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
71 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Fragment" />
72 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Module" />
73 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Product" />
74 + </xs:appinfo>
75 + <xs:documentation>
76 + Defines a COM+ partition role. Partition roles can not be
77 + created; this element can only be used as a locater to reference an existing
78 + role.
79 + </xs:documentation>
80 + </xs:annotation>
81 + <xs:complexType>
82 + <xs:sequence>
83 + <xs:choice minOccurs="0" maxOccurs="unbounded">
84 + <xs:element ref="ComPlusUserInPartitionRole" />
85 + <xs:element ref="ComPlusGroupInPartitionRole" />
86 + </xs:choice>
87 + </xs:sequence>
88 + <xs:attribute name="Id" use="required" type="xs:string">
89 + <xs:annotation><xs:documentation>
90 + Identifier for the element.
91 + </xs:documentation></xs:annotation>
92 + </xs:attribute>
93 + <xs:attribute name="Partition" use="optional" type="xs:string">
94 + <xs:annotation><xs:documentation>
95 + The id of a ComPlusPartition element representing the partition
96 + the role belongs to.
97 + </xs:documentation></xs:annotation>
98 + </xs:attribute>
99 + <xs:attribute name="Name" use="required" type="xs:string">
100 + <xs:annotation><xs:documentation>
101 + Name of the partition role.
102 + </xs:documentation></xs:annotation>
103 + </xs:attribute>
104 + </xs:complexType>
105 + </xs:element>
106 +
107 + <xs:element name="ComPlusUserInPartitionRole">
108 + <xs:annotation>
109 + <xs:appinfo>
110 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
111 + </xs:appinfo>
112 + <xs:documentation>
113 + This element represents a user membership in a partition
114 + role. When the parent component of this element is installed, the user will be
115 + added to the associated partition role.
116 + </xs:documentation>
117 + </xs:annotation>
118 + <xs:complexType>
119 + <xs:attribute name="Id" use="required" type="xs:string">
120 + <xs:annotation><xs:documentation>
121 + Identifier for the element.
122 + </xs:documentation></xs:annotation>
123 + </xs:attribute>
124 + <xs:attribute name="PartitionRole" use="optional" type="xs:string">
125 + <xs:annotation><xs:documentation>
126 + The id of a ComPlusPartitionRole element representing the
127 + partition the user should be added to.
128 + </xs:documentation></xs:annotation>
129 + </xs:attribute>
130 + <xs:attribute name="User" use="required" type="xs:string">
131 + <xs:annotation><xs:documentation>
132 + Foreign key into the User table.
133 + </xs:documentation></xs:annotation>
134 + </xs:attribute>
135 + </xs:complexType>
136 + </xs:element>
137 +
138 + <xs:element name="ComPlusGroupInPartitionRole">
139 + <xs:annotation>
140 + <xs:appinfo>
141 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
142 + </xs:appinfo>
143 + <xs:documentation>
144 + This element represents a security group membership in a
145 + partition role. When the parent component of this element is installed, the
146 + security group will be added to the associated partition role.
147 + </xs:documentation>
148 + </xs:annotation>
149 + <xs:complexType>
150 + <xs:attribute name="Id" use="required" type="xs:string">
151 + <xs:annotation><xs:documentation>
152 + Identifier for the element.
153 + </xs:documentation></xs:annotation>
154 + </xs:attribute>
155 + <xs:attribute name="PartitionRole" use="optional" type="xs:string">
156 + <xs:annotation><xs:documentation>
157 + The id of a ComPlusPartitionRole element representing the
158 + partition the user should be added to.
159 + </xs:documentation></xs:annotation>
160 + </xs:attribute>
161 + <xs:attribute name="Group" use="required" type="xs:string">
162 + <xs:annotation><xs:documentation>
163 + Foreign key into the Group table.
164 + </xs:documentation></xs:annotation>
165 + </xs:attribute>
166 + </xs:complexType>
167 + </xs:element>
168 +
169 + <xs:element name="ComPlusPartitionUser">
170 + <xs:annotation>
171 + <xs:appinfo>
172 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
173 + </xs:appinfo>
174 + <xs:documentation>
175 + Represents a default partition definition for a user. When
176 + the parent component of this element is installed, the default partition of the
177 + user will be set to the referenced partition.
178 + </xs:documentation>
179 + </xs:annotation>
180 + <xs:complexType>
181 + <xs:attribute name="Id" use="required" type="xs:string">
182 + <xs:annotation><xs:documentation>
183 + Identifier for the element.
184 + </xs:documentation></xs:annotation>
185 + </xs:attribute>
186 + <xs:attribute name="Partition" use="optional" type="xs:string">
187 + <xs:annotation><xs:documentation>
188 + The id of a ComPlusPartition element representing the
189 + partition that will be the default partition for the user.
190 + </xs:documentation></xs:annotation>
191 + </xs:attribute>
192 + <xs:attribute name="User" use="required" type="xs:string">
193 + <xs:annotation><xs:documentation>
194 + Foreign key into the User table.
195 + </xs:documentation></xs:annotation>
196 + </xs:attribute>
197 + </xs:complexType>
198 + </xs:element>
199 +
200 + <xs:element name="ComPlusApplication">
201 + <xs:annotation>
202 + <xs:appinfo>
203 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
204 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Fragment" />
205 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Module" />
206 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Product" />
207 + </xs:appinfo>
208 + <xs:documentation>
209 + Defines a COM+ application. If this element is a descendent
210 + of a Component element, the application will be created in association with
211 + this component. If the element is a child of any of the Fragment, Module or
212 + Product elements it is considered to be a locater, referencing an existing
213 + application.
214 +
215 + If the element is a child of a ComPlusPartition element,
216 + or have its Partition attribute set, the application will be installed under
217 + the referenced partition.
218 + </xs:documentation>
219 + </xs:annotation>
220 + <xs:complexType>
221 + <xs:sequence>
222 + <xs:choice minOccurs="0" maxOccurs="unbounded">
223 + <xs:element ref="ComPlusApplicationRole" />
224 + <xs:element ref="ComPlusAssembly" />
225 + </xs:choice>
226 + </xs:sequence>
227 + <xs:attribute name="Id" use="required" type="xs:string">
228 + <xs:annotation><xs:documentation>
229 + Identifier for the element.
230 + </xs:documentation></xs:annotation>
231 + </xs:attribute>
232 + <xs:attribute name="Partition" use="optional" type="xs:string">
233 + <xs:annotation><xs:documentation>
234 + If the element is not a child of a ComPlusPartition
235 + element, this attribute can be provided with the id of a ComPlusPartition
236 + element representing the partition the application belongs to.
237 + </xs:documentation></xs:annotation>
238 + </xs:attribute>
239 + <xs:attribute name="ApplicationId" use="optional" type="xs:string">
240 + <xs:annotation><xs:documentation>
241 + Id for the application. This attribute can be omitted, in
242 + which case an id will be generated on install. If the element is a locater,
243 + this attribute can be omitted if a value is provided for the Name attribute.
244 + </xs:documentation></xs:annotation>
245 + </xs:attribute>
246 + <xs:attribute name="Name" use="optional" type="xs:string">
247 + <xs:annotation><xs:documentation>
248 + Name of the application. This attribute can be omitted if
249 + the element is a locater, and a value is provided for the PartitionId
250 + attribute.
251 + </xs:documentation></xs:annotation>
252 + </xs:attribute>
253 + <xs:attribute name="ThreeGigSupportEnabled" use="optional" type="YesNoType" />
254 + <xs:attribute name="AccessChecksLevel" use="optional">
255 + <xs:simpleType>
256 + <xs:restriction base="xs:NMTOKEN">
257 + <xs:enumeration value="applicationLevel" />
258 + <xs:enumeration value="applicationComponentLevel" />
259 + </xs:restriction>
260 + </xs:simpleType>
261 + </xs:attribute>
262 + <xs:attribute name="Activation" use="optional">
263 + <xs:simpleType>
264 + <xs:restriction base="xs:NMTOKEN">
265 + <xs:enumeration value="inproc" />
266 + <xs:enumeration value="local" />
267 + </xs:restriction>
268 + </xs:simpleType>
269 + </xs:attribute>
270 + <xs:attribute name="ApplicationAccessChecksEnabled" use="optional" type="YesNoType" />
271 + <xs:attribute name="ApplicationDirectory" use="optional" type="xs:string" />
272 + <xs:attribute name="Authentication" use="optional">
273 + <xs:simpleType>
274 + <xs:restriction base="xs:NMTOKEN">
275 + <xs:enumeration value="default" />
276 + <xs:enumeration value="none" />
277 + <xs:enumeration value="connect" />
278 + <xs:enumeration value="call" />
279 + <xs:enumeration value="packet" />
280 + <xs:enumeration value="integrity" />
281 + <xs:enumeration value="privacy" />
282 + </xs:restriction>
283 + </xs:simpleType>
284 + </xs:attribute>
285 + <xs:attribute name="AuthenticationCapability" use="optional">
286 + <xs:simpleType>
287 + <xs:restriction base="xs:NMTOKEN">
288 + <xs:enumeration value="none" />
289 + <xs:enumeration value="secureReference" />
290 + <xs:enumeration value="staticCloaking" />
291 + <xs:enumeration value="dynamicCloaking" />
292 + </xs:restriction>
293 + </xs:simpleType>
294 + </xs:attribute>
295 + <xs:attribute name="Changeable" use="optional" type="YesNoType" />
296 + <xs:attribute name="CommandLine" use="optional" type="xs:string" />
297 + <xs:attribute name="ConcurrentApps" use="optional" type="xs:int" />
298 + <xs:attribute name="CreatedBy" use="optional" type="xs:string" />
299 + <xs:attribute name="CRMEnabled" use="optional" type="YesNoType" />
300 + <xs:attribute name="CRMLogFile" use="optional" type="xs:string" />
301 + <xs:attribute name="Deleteable" use="optional" type="YesNoType" />
302 + <xs:attribute name="Description" use="optional" type="xs:string" />
303 + <xs:attribute name="DumpEnabled" use="optional" type="YesNoType" />
304 + <xs:attribute name="DumpOnException" use="optional" type="YesNoType" />
305 + <xs:attribute name="DumpOnFailfast" use="optional" type="YesNoType" />
306 + <xs:attribute name="DumpPath" use="optional" type="xs:string" />
307 + <xs:attribute name="EventsEnabled" use="optional" type="YesNoType" />
308 + <xs:attribute name="Identity" use="optional" type="xs:string" />
309 + <xs:attribute name="ImpersonationLevel" use="optional">
310 + <xs:simpleType>
311 + <xs:restriction base="xs:NMTOKEN">
312 + <xs:enumeration value="anonymous" />
313 + <xs:enumeration value="identify" />
314 + <xs:enumeration value="impersonate" />
315 + <xs:enumeration value="delegate" />
316 + </xs:restriction>
317 + </xs:simpleType>
318 + </xs:attribute>
319 + <xs:attribute name="IsEnabled" use="optional" type="YesNoType" />
320 + <xs:attribute name="MaxDumpCount" use="optional" type="xs:int" />
321 + <xs:attribute name="Password" use="optional" type="xs:string" />
322 + <xs:attribute name="QCAuthenticateMsgs" use="optional">
323 + <xs:simpleType>
324 + <xs:restriction base="xs:NMTOKEN">
325 + <xs:enumeration value="secureApps" />
326 + <xs:enumeration value="off" />
327 + <xs:enumeration value="on" />
328 + </xs:restriction>
329 + </xs:simpleType>
330 + </xs:attribute>
331 + <xs:attribute name="QCListenerMaxThreads" use="optional" type="xs:int" />
332 + <xs:attribute name="QueueListenerEnabled" use="optional" type="YesNoType" />
333 + <xs:attribute name="QueuingEnabled" use="optional" type="YesNoType" />
334 + <xs:attribute name="RecycleActivationLimit" use="optional" type="xs:int" />
335 + <xs:attribute name="RecycleCallLimit" use="optional" type="xs:int" />
336 + <xs:attribute name="RecycleExpirationTimeout" use="optional" type="xs:int" />
337 + <xs:attribute name="RecycleLifetimeLimit" use="optional" type="xs:int" />
338 + <xs:attribute name="RecycleMemoryLimit" use="optional" type="xs:int" />
339 + <xs:attribute name="Replicable" use="optional" type="YesNoType" />
340 + <xs:attribute name="RunForever" use="optional" type="YesNoType" />
341 + <xs:attribute name="ShutdownAfter" use="optional" type="xs:int" />
342 + <xs:attribute name="SoapActivated" use="optional" type="YesNoType" />
343 + <xs:attribute name="SoapBaseUrl" use="optional" type="xs:string" />
344 + <xs:attribute name="SoapMailTo" use="optional" type="xs:string" />
345 + <xs:attribute name="SoapVRoot" use="optional" type="xs:string" />
346 + <xs:attribute name="SRPEnabled" use="optional" type="YesNoType" />
347 + <xs:attribute name="SRPTrustLevel" use="optional">
348 + <xs:simpleType>
349 + <xs:restriction base="xs:NMTOKEN">
350 + <xs:enumeration value="disallowed" />
351 + <xs:enumeration value="fullyTrusted" />
352 + </xs:restriction>
353 + </xs:simpleType>
354 + </xs:attribute>
355 + </xs:complexType>
356 + </xs:element>
357 +
358 + <xs:element name="ComPlusApplicationRole">
359 + <xs:annotation>
360 + <xs:appinfo>
361 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
362 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Fragment" />
363 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Module" />
364 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Product" />
365 + </xs:appinfo>
366 + <xs:documentation>
367 + Defines an application role. If this element is a descendent
368 + of a Component element, the application role will be created in association
369 + with this component. If the element is a child of any of the Fragment, Module
370 + or Product elements it is considered to be a locater, referencing an existing
371 + application role.
372 + </xs:documentation>
373 + </xs:annotation>
374 + <xs:complexType>
375 + <xs:sequence>
376 + <xs:choice minOccurs="0" maxOccurs="unbounded">
377 + <xs:element ref="ComPlusUserInApplicationRole" />
378 + <xs:element ref="ComPlusGroupInApplicationRole" />
379 + </xs:choice>
380 + </xs:sequence>
381 + <xs:attribute name="Id" use="required" type="xs:string">
382 + <xs:annotation><xs:documentation>
383 + Identifier for the element.
384 + </xs:documentation></xs:annotation>
385 + </xs:attribute>
386 + <xs:attribute name="Application" use="optional" type="xs:string">
387 + <xs:annotation><xs:documentation>
388 + If the element is not a child of a ComPlusApplication
389 + element, this attribute should be provided with the id of a
390 + ComPlusApplication element representing the application the role belongs to.
391 + </xs:documentation></xs:annotation>
392 + </xs:attribute>
393 + <xs:attribute name="Name" use="required" type="xs:string">
394 + <xs:annotation><xs:documentation>
395 + Name of the application role.
396 + </xs:documentation></xs:annotation>
397 + </xs:attribute>
398 + <xs:attribute name="Description" use="optional" type="xs:string" />
399 + </xs:complexType>
400 + </xs:element>
401 +
402 + <xs:element name="ComPlusUserInApplicationRole">
403 + <xs:annotation>
404 + <xs:appinfo>
405 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
406 + </xs:appinfo>
407 + <xs:documentation>
408 + This element represents a user membership in an
409 + application role. When the parent component of this element is installed, the
410 + user will be added to the associated application role. This element must be a descendent
411 + of a Component element; it can not be a child of a ComPlusApplicationRole
412 + locater element. To reference a locater element use the ApplicationRole
413 + attribute.
414 + </xs:documentation>
415 + </xs:annotation>
416 + <xs:complexType>
417 + <xs:attribute name="Id" use="required" type="xs:string">
418 + <xs:annotation><xs:documentation>
419 + Identifier for the element.
420 + </xs:documentation></xs:annotation>
421 + </xs:attribute>
422 + <xs:attribute name="ApplicationRole" use="optional" type="xs:string">
423 + <xs:annotation><xs:documentation>
424 + If the element is not a child of a ComPlusApplicationRole
425 + element, this attribute should be provided with the id of a
426 + ComPlusApplicationRole element representing the application role the user is
427 + to be added to.
428 + </xs:documentation></xs:annotation>
429 + </xs:attribute>
430 + <xs:attribute name="User" use="required" type="xs:string">
431 + <xs:annotation><xs:documentation>
432 + Foreign key into the User table.
433 + </xs:documentation></xs:annotation>
434 + </xs:attribute>
435 + </xs:complexType>
436 + </xs:element>
437 +
438 + <xs:element name="ComPlusGroupInApplicationRole">
439 + <xs:annotation>
440 + <xs:appinfo>
441 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
442 + </xs:appinfo>
443 + <xs:documentation>
444 + This element represents a security group membership in an
445 + application role. When the parent component of this element is installed, the
446 + user will be added to the associated application role. This element must be a
447 + descendent of a Component element; it can not be a child of a
448 + ComPlusApplicationRole locater element. To reference a locater element use the
449 + ApplicationRole attribute.
450 + </xs:documentation>
451 + </xs:annotation>
452 + <xs:complexType>
453 + <xs:attribute name="Id" use="required" type="xs:string">
454 + <xs:annotation><xs:documentation>
455 + Identifier for the element.
456 + </xs:documentation></xs:annotation>
457 + </xs:attribute>
458 + <xs:attribute name="ApplicationRole" use="optional" type="xs:string">
459 + <xs:annotation><xs:documentation>
460 + If the element is not a child of a ComPlusApplicationRole
461 + element, this attribute should be provided with the id of a
462 + ComPlusApplicationRole element representing the application role the user is
463 + to be added to.
464 + </xs:documentation></xs:annotation>
465 + </xs:attribute>
466 + <xs:attribute name="Group" use="required" type="xs:string">
467 + <xs:annotation><xs:documentation>
468 + Foreign key into the Group table.
469 + </xs:documentation></xs:annotation>
470 + </xs:attribute>
471 + </xs:complexType>
472 + </xs:element>
473 +
474 + <xs:element name="ComPlusAssembly">
475 + <xs:annotation>
476 + <xs:documentation>
477 + Represents a DLL or assembly to be registered with COM+. If
478 + this element is a child of a ComPlusApplication element, the assembly will be
479 + registered in this application. Other ways the Application attribute must be
480 + set to an application. The element must be a descendent of a Component element,
481 + it can not be a child of a ComPlusApplication locator element.
482 + </xs:documentation>
483 + <xs:appinfo>
484 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
485 + <xse:remarks>
486 + <html:p>
487 + When installing a native assembly, all components
488 + contained in the assembly must be represented as ComPlusComponent elements
489 + under this element. Any component not listed will not be removed during
490 + uninstall.
491 + </html:p>
492 +
493 + <html:p>
494 + The fields DllPath, TlbPath and PSDllPath are formatted
495 + fields that should contain file paths to there respective file types. A typical
496 + value for DllPath for example, should be something like “[#MyAssembly_dll]”,
497 + where “MyAssembly_dll” is the key of the dll file in the File table.
498 + </html:p>
499 +
500 + <html:p>
501 + <html:b>Warning</html:b>: The assembly name provided in the AssemblyName
502 + attribute must be a fully specified assembly name, if a partial name is
503 + provided a random assembly matching the partial name will be selected.
504 + </html:p>
505 + </xse:remarks>
506 + </xs:appinfo>
507 + </xs:annotation>
508 + <xs:complexType>
509 + <xs:sequence>
510 + <xs:choice minOccurs="0" maxOccurs="unbounded">
511 + <xs:element ref="ComPlusAssemblyDependency" />
512 + <xs:element ref="ComPlusComponent" />
513 + </xs:choice>
514 + </xs:sequence>
515 + <xs:attribute name="Id" use="required" type="xs:string">
516 + <xs:annotation><xs:documentation>
517 + Identifier for the element.
518 + </xs:documentation></xs:annotation>
519 + </xs:attribute>
520 + <xs:attribute name="Application" use="optional" type="xs:string">
521 + <xs:annotation><xs:documentation>
522 + If the element is not a child of a ComPlusApplication
523 + element, this attribute should be provided with the id of a ComPlusApplication
524 + element representing the application the assembly is to be registered in.
525 + This attribute can be omitted for a .NET assembly even if the application is
526 + not a child of a ComPlusApplication element.
527 + </xs:documentation></xs:annotation>
528 + </xs:attribute>
529 + <xs:attribute name="AssemblyName" use="optional" type="xs:string">
530 + <xs:annotation><xs:documentation>
531 + The name of the assembly used to identify the assembly in
532 + the GAC. This attribute can be provided only if DllPathFromGAC is set to
533 + “yes”.
534 + </xs:documentation></xs:annotation>
535 + </xs:attribute>
536 + <xs:attribute name="DllPath" use="optional" type="xs:string">
537 + <xs:annotation><xs:documentation>
538 + The path to locate the assembly DLL during registration.
539 + This attribute should be provided if DllPathFromGAC is not set to “yes”.
540 + </xs:documentation></xs:annotation>
541 + </xs:attribute>
542 + <xs:attribute name="TlbPath" use="optional" type="xs:string">
543 + <xs:annotation><xs:documentation>
544 + An optional path to an external type lib for the assembly.
545 + This attribute must be provided if the Type attribute is set to “.net”.
546 + </xs:documentation></xs:annotation>
547 + </xs:attribute>
548 + <xs:attribute name="PSDllPath" use="optional" type="xs:string">
549 + <xs:annotation><xs:documentation>
550 + An optional path to an external proxy/stub DLL for the assembly.
551 + </xs:documentation></xs:annotation>
552 + </xs:attribute>
553 + <xs:attribute name="Type" use="required">
554 + <xs:annotation><xs:documentation>
555 + </xs:documentation></xs:annotation>
556 + <xs:simpleType>
557 + <xs:restriction base="xs:NMTOKEN">
558 + <xs:enumeration value="native" />
559 + <xs:enumeration value=".net" />
560 + </xs:restriction>
561 + </xs:simpleType>
562 + </xs:attribute>
563 + <xs:attribute name="EventClass" use="optional" type="YesNoType">
564 + <xs:annotation><xs:documentation>
565 + Indicates that the assembly is to be installed as an event
566 + class DLL. This attribute is only valid for native assemblies. The assembly
567 + will be installed with the COM+ catalog’s InstallEventClass() function.
568 + </xs:documentation></xs:annotation>
569 + </xs:attribute>
570 + <xs:attribute name="DllPathFromGAC" use="optional" type="YesNoType">
571 + <xs:annotation><xs:documentation>
572 + Indicates that the DLL path should be extracted from the
573 + GAC instead for being provided in the DllPath attribute. If this attribute is
574 + set to “yes”, the name of the assembly can be provided using the AssemblyName
575 + attribute. Or, if this AssemblyName attribute is missing, the name will be
576 + extracted from the MsiAssemblyName table using the id of the parent Component
577 + element.
578 + </xs:documentation></xs:annotation>
579 + </xs:attribute>
580 + <xs:attribute name="RegisterInCommit" use="optional" type="YesNoType">
581 + <xs:annotation><xs:documentation>
582 + Indicates that the assembly should be installed in the
583 + commit custom action instead of the normal deferred custom action. This is
584 + necessary when installing .NET assemblies to the GAC in the same
585 + installation, as the assemblies are not visible in the GAC until after the
586 + InstallFinalize action has run.
587 + </xs:documentation></xs:annotation>
588 + </xs:attribute>
589 + </xs:complexType>
590 + </xs:element>
591 +
592 + <xs:element name="ComPlusAssemblyDependency">
593 + <xs:annotation>
594 + <xs:documentation>
595 + Defines a dependency between two assemblies. This element
596 + affects the order in which assembles are registered. Any assemblies referenced
597 + by this element are guarantied to be registered before, and unregistered after,
598 + the assembly referenced by the parent ComPlusAssembly element.
599 + </xs:documentation>
600 + <xs:appinfo>
601 + <xse:remarks>
602 + It is only necessary to explicitly specify dependencies between
603 + assemblies contained in the same package (MSI or MSM). Assemblies merged in to a
604 + package from a merge module will always be installed before any assemblies
605 + specified in the base package. Assemblies merged in from different merge
606 + modules are sequenced using the ModuleDependency MSI table. It is not possible
607 + to have cross dependencies between merge modules or have an assembly in a merge
608 + module depend on an assembly in the base package.
609 + </xse:remarks>
610 + </xs:appinfo>
611 + </xs:annotation>
612 + <xs:complexType>
613 + <xs:attribute name="RequiredAssembly" use="required" type="xs:string">
614 + <xs:annotation><xs:documentation>
615 + Reference to the id of the assembly required by the parent
616 + ComPlusAssembly element.
617 + </xs:documentation></xs:annotation>
618 + </xs:attribute>
619 + </xs:complexType>
620 + </xs:element>
621 +
622 + <xs:element name="ComPlusComponent">
623 + <xs:annotation><xs:documentation>
624 + Represents a COM+ component in an assembly.
625 + </xs:documentation></xs:annotation>
626 + <xs:complexType>
627 + <xs:sequence>
628 + <xs:choice minOccurs="0" maxOccurs="unbounded">
629 + <xs:element ref="ComPlusRoleForComponent" />
630 + <xs:element ref="ComPlusInterface" />
631 + <xs:element ref="ComPlusSubscription" />
632 + </xs:choice>
633 + </xs:sequence>
634 + <xs:attribute name="Id" use="required" type="xs:string">
635 + <xs:annotation><xs:documentation>
636 + Identifier for the element.
637 + </xs:documentation></xs:annotation>
638 + </xs:attribute>
639 + <xs:attribute name="CLSID" use="required" type="uuid">
640 + <xs:annotation><xs:documentation>
641 + CLSID of the component.
642 + </xs:documentation></xs:annotation>
643 + </xs:attribute>
644 + <xs:attribute name="AllowInprocSubscribers" use="optional" type="YesNoType" />
645 + <xs:attribute name="ComponentAccessChecksEnabled" use="optional" type="YesNoType" />
646 + <xs:attribute name="ComponentTransactionTimeout" use="optional" type="xs:int" />
647 + <xs:attribute name="ComponentTransactionTimeoutEnabled" use="optional" type="YesNoType" />
648 + <xs:attribute name="COMTIIntrinsics" use="optional" type="YesNoType" />
649 + <xs:attribute name="ConstructionEnabled" use="optional" type="YesNoType" />
650 + <xs:attribute name="ConstructorString" use="optional" type="xs:string" />
651 + <xs:attribute name="CreationTimeout" use="optional" type="xs:int" />
652 + <xs:attribute name="Description" use="optional" type="xs:string" />
653 + <xs:attribute name="EventTrackingEnabled" use="optional" type="YesNoType" />
654 + <xs:attribute name="ExceptionClass" use="optional" type="xs:string" />
655 + <xs:attribute name="FireInParallel" use="optional" type="YesNoType" />
656 + <xs:attribute name="IISIntrinsics" use="optional" type="YesNoType" />
657 + <xs:attribute name="InitializesServerApplication" use="optional" type="YesNoType" />
658 + <xs:attribute name="IsEnabled" use="optional" type="YesNoType" />
659 + <xs:attribute name="IsPrivateComponent" use="optional" type="YesNoType" />
660 + <xs:attribute name="JustInTimeActivation" use="optional" type="YesNoType" />
661 + <xs:attribute name="LoadBalancingSupported" use="optional" type="YesNoType" />
662 + <xs:attribute name="MaxPoolSize" use="optional" type="xs:int" />
663 + <xs:attribute name="MinPoolSize" use="optional" type="xs:int" />
664 + <xs:attribute name="MultiInterfacePublisherFilterCLSID" use="optional" type="xs:string" />
665 + <xs:attribute name="MustRunInClientContext" use="optional" type="YesNoType" />
666 + <xs:attribute name="MustRunInDefaultContext" use="optional" type="YesNoType" />
667 + <xs:attribute name="ObjectPoolingEnabled" use="optional" type="YesNoType" />
668 + <xs:attribute name="PublisherID" use="optional" type="xs:string" />
669 + <xs:attribute name="SoapAssemblyName" use="optional" type="xs:string" />
670 + <xs:attribute name="SoapTypeName" use="optional" type="xs:string" />
671 + <xs:attribute name="Synchronization" use="optional">
672 + <xs:simpleType>
673 + <xs:restriction base="xs:NMTOKEN">
674 + <xs:enumeration value="ignored" />
675 + <xs:enumeration value="none" />
676 + <xs:enumeration value="supported" />
677 + <xs:enumeration value="required" />
678 + <xs:enumeration value="requiresNew" />
679 + </xs:restriction>
680 + </xs:simpleType>
681 + </xs:attribute>
682 + <xs:attribute name="Transaction" use="optional">
683 + <xs:simpleType>
684 + <xs:restriction base="xs:NMTOKEN">
685 + <xs:enumeration value="ignored" />
686 + <xs:enumeration value="none" />
687 + <xs:enumeration value="supported" />
688 + <xs:enumeration value="required" />
689 + <xs:enumeration value="requiresNew" />
690 + </xs:restriction>
691 + </xs:simpleType>
692 + </xs:attribute>
693 + <xs:attribute name="TxIsolationLevel" use="optional">
694 + <xs:simpleType>
695 + <xs:restriction base="xs:NMTOKEN">
696 + <xs:enumeration value="any" />
697 + <xs:enumeration value="readUnCommitted" />
698 + <xs:enumeration value="readCommitted" />
699 + <xs:enumeration value="repeatableRead" />
700 + <xs:enumeration value="serializable" />
701 + </xs:restriction>
702 + </xs:simpleType>
703 + </xs:attribute>
704 + </xs:complexType>
705 + </xs:element>
706 +
707 + <xs:element name="ComPlusRoleForComponent">
708 + <xs:annotation>
709 + <xs:appinfo>
710 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
711 + </xs:appinfo>
712 + <xs:documentation>
713 + Represents a role assignment to a COM+ component.
714 + </xs:documentation>
715 + </xs:annotation>
716 + <xs:complexType>
717 + <xs:attribute name="Id" use="required" type="xs:string">
718 + <xs:annotation><xs:documentation>
719 + Identifier for the element.
720 + </xs:documentation></xs:annotation>
721 + </xs:attribute>
722 + <xs:attribute name="Component" use="optional" type="xs:string">
723 + <xs:annotation><xs:documentation>
724 + If the element is not a child of a ComPlusComponent
725 + element, this attribute should be provided with the id of a ComPlusComponent
726 + element representing the component the role is to be added to.
727 + </xs:documentation></xs:annotation>
728 + </xs:attribute>
729 + <xs:attribute name="ApplicationRole" use="required" type="xs:string">
730 + <xs:annotation><xs:documentation>
731 + Id of the ComPlusApplicationRole element representing the
732 + role that shall be granted access to the component.
733 + </xs:documentation></xs:annotation>
734 + </xs:attribute>
735 + </xs:complexType>
736 + </xs:element>
737 +
738 + <xs:element name="ComPlusInterface">
739 + <xs:annotation><xs:documentation>
740 + Represents an interface for a COM+ component.
741 + </xs:documentation></xs:annotation>
742 + <xs:complexType>
743 + <xs:sequence>
744 + <xs:choice minOccurs="0" maxOccurs="unbounded">
745 + <xs:element ref="ComPlusRoleForInterface" />
746 + <xs:element ref="ComPlusMethod" />
747 + </xs:choice>
748 + </xs:sequence>
749 + <xs:attribute name="Id" use="required" type="xs:string">
750 + <xs:annotation><xs:documentation>
751 + Identifier for the element.
752 + </xs:documentation></xs:annotation>
753 + </xs:attribute>
754 + <xs:attribute name="IID" use="required" type="uuid">
755 + <xs:annotation><xs:documentation>
756 + IID of the interface.
757 + </xs:documentation></xs:annotation>
758 + </xs:attribute>
759 + <xs:attribute name="Description" use="optional" type="xs:string" />
760 + <xs:attribute name="QueuingEnabled" use="optional" type="YesNoType" />
761 + </xs:complexType>
762 + </xs:element>
763 +
764 + <xs:element name="ComPlusRoleForInterface">
765 + <xs:annotation>
766 + <xs:appinfo>
767 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
768 + </xs:appinfo>
769 + <xs:documentation>
770 + Represents a role assignment to an interface.
771 + </xs:documentation>
772 + </xs:annotation>
773 + <xs:complexType>
774 + <xs:attribute name="Id" use="required" type="xs:string">
775 + <xs:annotation><xs:documentation>
776 + Identifier for the element.
777 + </xs:documentation></xs:annotation>
778 + </xs:attribute>
779 + <xs:attribute name="Interface" use="optional" type="xs:string">
780 + <xs:annotation><xs:documentation>
781 + If the element is not a child of a ComPlusInterface
782 + element, this attribute should be provided with the id of a ComPlusInterface
783 + element representing the interface the role is to be added to.
784 + </xs:documentation></xs:annotation>
785 + </xs:attribute>
786 + <xs:attribute name="ApplicationRole" use="required" type="xs:string">
787 + <xs:annotation><xs:documentation>
788 + Id of the ComPlusApplicationRole element representing the
789 + role that shall be granted access to the interface.
790 + </xs:documentation></xs:annotation>
791 + </xs:attribute>
792 + </xs:complexType>
793 + </xs:element>
794 +
795 + <xs:element name="ComPlusMethod">
796 + <xs:annotation>
797 + <xs:documentation>
798 + Represents a method for an interface.
799 + </xs:documentation>
800 + </xs:annotation>
801 + <xs:complexType>
802 + <xs:sequence>
803 + <xs:element ref="ComPlusRoleForMethod" minOccurs="0" maxOccurs="unbounded" />
804 + </xs:sequence>
805 + <xs:attribute name="Id" use="required" type="xs:string">
806 + <xs:annotation>
807 + <xs:documentation>
808 + Identifier for the element.
809 + </xs:documentation>
810 + </xs:annotation>
811 + </xs:attribute>
812 + <xs:attribute name="Index" use="optional" type="xs:int">
813 + <xs:annotation>
814 + <xs:documentation>
815 + Dispatch id of the method. If this attribute is not set a
816 + value must be provided for the Name attribute.
817 + </xs:documentation>
818 + </xs:annotation>
819 + </xs:attribute>
820 + <xs:attribute name="Name" use="optional" type="xs:string">
821 + <xs:annotation>
822 + <xs:documentation>
823 + Name of the method. If this attribute is not set a value
824 + must be provided for the Index attribute.
825 + </xs:documentation>
826 + </xs:annotation>
827 + </xs:attribute>
828 + <xs:attribute name="AutoComplete" use="optional" type="YesNoType" />
829 + <xs:attribute name="Description" use="optional" type="xs:string" />
830 + </xs:complexType>
831 + </xs:element>
832 +
833 + <xs:element name="ComPlusRoleForMethod">
834 + <xs:annotation>
835 + <xs:appinfo>
836 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
837 + </xs:appinfo>
838 + <xs:documentation>
839 + Represents a role assignment to a COM+ method.
840 + </xs:documentation>
841 + </xs:annotation>
842 + <xs:complexType>
843 + <xs:attribute name="Id" use="required" type="xs:string">
844 + <xs:annotation><xs:documentation>
845 + Identifier for the element.
846 + </xs:documentation></xs:annotation>
847 + </xs:attribute>
848 + <xs:attribute name="Method" use="optional" type="xs:string">
849 + <xs:annotation><xs:documentation>
850 + If the element is not a child of a ComPlusMethod element,
851 + this attribute should be provided with the id of a ComPlusMethod element
852 + representing the method the role is to be added to.
853 + </xs:documentation></xs:annotation>
854 + </xs:attribute>
855 + <xs:attribute name="ApplicationRole" use="required" type="xs:string">
856 + <xs:annotation><xs:documentation>
857 + Id of the ComPlusApplicationRole element representing the
858 + role that shall be granted access to the method.
859 + </xs:documentation></xs:annotation>
860 + </xs:attribute>
861 + </xs:complexType>
862 + </xs:element>
863 +
864 + <xs:element name="ComPlusSubscription">
865 + <xs:annotation>
866 + <xs:appinfo>
867 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
868 + </xs:appinfo>
869 + <xs:documentation>
870 + Defines an event subscription for a COM+ component.
871 + </xs:documentation>
872 + </xs:annotation>
873 + <xs:complexType>
874 + <xs:attribute name="Id" use="required" type="xs:string">
875 + <xs:annotation><xs:documentation>
876 + Identifier for the element.
877 + </xs:documentation></xs:annotation>
878 + </xs:attribute>
879 + <xs:attribute name="Component" use="optional" type="xs:string">
880 + <xs:annotation><xs:documentation>
881 + If the element is not a child of a ComPlusComponent
882 + element, this attribute should be provided with the id of a ComPlusComponent
883 + element representing the component the subscription is to be created for.
884 + </xs:documentation></xs:annotation>
885 + </xs:attribute>
886 + <xs:attribute name="SubscriptionId" use="optional" type="xs:string">
887 + <xs:annotation><xs:documentation>
888 + Id of the subscription. If a value is not provided for
889 + this attribute, an id will be generated during installation.
890 + </xs:documentation></xs:annotation>
891 + </xs:attribute>
892 + <xs:attribute name="Name" use="required" type="xs:string">
893 + <xs:annotation><xs:documentation>
894 + Name of the subscription.
895 + </xs:documentation></xs:annotation>
896 + </xs:attribute>
897 + <xs:attribute name="EventCLSID" use="optional" type="xs:string">
898 + <xs:annotation><xs:documentation>
899 + CLSID of the event class for the subscription. If a value
900 + for this attribute is not provided, a value for the PublisherID attribute
901 + must be provided.
902 + </xs:documentation></xs:annotation>
903 + </xs:attribute>
904 + <xs:attribute name="PublisherID" use="optional" type="xs:string">
905 + <xs:annotation><xs:documentation>
906 + Publisher id for the subscription. If a value for this
907 + attribute is not provided, a value for the EventCLSID attribute must be
908 + provided.
909 + </xs:documentation></xs:annotation>
910 + </xs:attribute>
911 + <xs:attribute name="Description" use="optional" type="xs:string" />
912 + <xs:attribute name="Enabled" use="optional" type="YesNoType" />
913 + <xs:attribute name="EventClassPartitionID" use="optional" type="xs:string" />
914 + <xs:attribute name="FilterCriteria" use="optional" type="xs:string" />
915 + <xs:attribute name="InterfaceID" use="optional" type="xs:string" />
916 + <xs:attribute name="MachineName" use="optional" type="xs:string" />
917 + <xs:attribute name="MethodName" use="optional" type="xs:string" />
918 + <xs:attribute name="PerUser" use="optional" type="YesNoType" />
919 + <xs:attribute name="Queued" use="optional" type="YesNoType" />
920 + <xs:attribute name="SubscriberMoniker" use="optional" type="xs:string" />
921 + <xs:attribute name="UserName" use="optional" type="xs:string" />
922 + </xs:complexType>
923 + </xs:element>
924 +
925 + <xs:simpleType name="YesNoType">
926 + <xs:annotation>
927 + <xs:documentation>Values of this type will either be "yes" or "no".</xs:documentation>
928 + </xs:annotation>
929 + <xs:restriction base="xs:NMTOKEN">
930 + <xs:enumeration value="no" />
931 + <xs:enumeration value="yes" />
932 + </xs:restriction>
933 + </xs:simpleType>
934 +
935 + <xs:simpleType name="uuid">
936 + <xs:annotation>
937 + <xs:documentation>Values of this type will look like: "01234567-89AB-CDEF-0123-456789ABCDEF".</xs:documentation>
938 + </xs:annotation>
939 + <xs:restriction base="xs:string">
940 + <xs:pattern value="[0-9A-Fa-f]{8}\-?[0-9A-Fa-f]{4}\-?[0-9A-Fa-f]{4}\-?[0-9A-Fa-f]{4}\-?[0-9A-Fa-f]{12}" />
941 + </xs:restriction>
942 + </xs:simpleType>
943 +
944 +</xs:schema>
src/wixext/messages.xml new
+77
@@ -0,0 +1,77 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<!-- 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. -->
3 +
4 +
5 +<Messages Namespace="WixToolset.Extensions" Resources="Data.Messages" xmlns="http://schemas.microsoft.com/genmsgs/2004/07/messages">
6 + <Class Name="ComPlusErrors" ContainerName="ComPlusErrorEventArgs" BaseContainerName="MessageEventArgs">
7 + <Message Id="IllegalAttributeWithoutComponent" Number="6000">
8 + <Instance>
9 + The {0}/@{1} attribute cannot be specified unless the element has a component as an ancestor. A {0} that does not have a component ancestor is not installed.
10 + <Parameter Type="System.String" Name="elementName" />
11 + <Parameter Type="System.String" Name="attributeName" />
12 + </Instance>
13 + </Message>
14 + <Message Id="IllegalElementWithoutComponent" Number="6001">
15 + <Instance>
16 + The {0} element cannot be specified unless the element has a component as an ancestor. A {0} that does not have a component ancestor is not installed.
17 + <Parameter Type="System.String" Name="elementName" />
18 + </Instance>
19 + </Message>
20 + <Message Id="UnexpectedAttributeWithOtherValue" Number="6002">
21 + <Instance>
22 + The {0}/@{1} attribute cannot coexist with the {2} attribute's value of '{3}'.
23 + <Parameter Type="System.String" Name="elementName" />
24 + <Parameter Type="System.String" Name="attributeName" />
25 + <Parameter Type="System.String" Name="otherAttributeName" />
26 + <Parameter Type="System.String" Name="otherValue" />
27 + </Instance>
28 + <Instance>
29 + The {0}/@{1} attribute's value, '{2}', cannot coexist with the {3} attribute's value of '{4}'.
30 + <Parameter Type="System.String" Name="elementName" />
31 + <Parameter Type="System.String" Name="attributeName" />
32 + <Parameter Type="System.String" Name="value" />
33 + <Parameter Type="System.String" Name="otherAttributeName" />
34 + <Parameter Type="System.String" Name="otherValue" />
35 + </Instance>
36 + </Message>
37 + <Message Id="UnexpectedAttributeWithoutOtherValue" Number="6003">
38 + <Instance>
39 + The {0}/@{1} cannot be provided unless the {2} attribute is provided with a value of '{3}'.
40 + <Parameter Type="System.String" Name="elementName" />
41 + <Parameter Type="System.String" Name="attributeName" />
42 + <Parameter Type="System.String" Name="otherAttributeName" />
43 + <Parameter Type="System.String" Name="otherValue" />
44 + </Instance>
45 + </Message>
46 + <Message Id="RequiredAttributeUnderComponent" Number="6004">
47 + <Instance>
48 + The {0}/@{1} attribute must be provided when {0} element is nested under a component.
49 + <Parameter Type="System.String" Name="elementName" />
50 + <Parameter Type="System.String" Name="attributeName" />
51 + </Instance>
52 + </Message>
53 + <Message Id="RequiredAttribute" Number="6005">
54 + <Instance>
55 + A {0} element must have either a {1} attribute or a {2} attribute, or both set.
56 + <Parameter Type="System.String" Name="elementName" />
57 + <Parameter Type="System.String" Name="attributeName1" />
58 + <Parameter Type="System.String" Name="attributeName2" />
59 + </Instance>
60 + </Message>
61 + <Message Id="RequiredAttributeNotUnderComponent" Number="6006">
62 + <Instance>
63 + A {0} element not nested under a component must have either a {1} attribute or a {2} attribute, or both set.
64 + <Parameter Type="System.String" Name="elementName" />
65 + <Parameter Type="System.String" Name="attributeName1" />
66 + <Parameter Type="System.String" Name="attributeName2" />
67 + </Instance>
68 + </Message>
69 + </Class>
70 + <Class Name="ComPlusWarnings" ContainerName="ComPlusWarningEventArgs" BaseContainerName="MessageEventArgs">
71 + <Message Id="MissingComponents" Number="6007">
72 + <Instance>The ComPlusAssembly element has a Type attribute with a value of 'native', but the element does not contain any ComPlusComponent elements. All components contained in a native assembly must be listed, or they will not be correctly removed during uninstall.</Instance>
73 + </Message>
74 + </Class>
75 + <Class Name="ComPlusVerboses" ContainerName="ComPlusVerboseEventArgs" BaseContainerName="MessageEventArgs">
76 + </Class>
77 +</Messages>
src/wixext/tables.xml new
+250
@@ -0,0 +1,250 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<!-- 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. -->
3 +
4 +
5 +<tableDefinitions xmlns="http://wixtoolset.org/schemas/v4/wi/tables">
6 + <tableDefinition name="ComPlusPartition" createSymbols="yes">
7 + <columnDefinition name="Partition" type="string" length="72" primaryKey="yes" modularize="column"
8 + category="identifier" description=""/>
9 + <columnDefinition name="Component_" type="string" length="72" nullable="yes" modularize="column"
10 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
11 + <columnDefinition name="Id" type="string" length="72" nullable="yes" modularize="property"
12 + category="formatted" description=""/>
13 + <columnDefinition name="Name" type="string" length="255" nullable="yes" modularize="property"
14 + category="formatted" description=""/>
15 + </tableDefinition>
16 + <tableDefinition name="ComPlusPartitionProperty">
17 + <columnDefinition name="Partition_" type="string" length="72" primaryKey="yes" modularize="column"
18 + keyTable="ComPlusPartition" keyColumn="1" category="identifier" description=""/>
19 + <columnDefinition name="Name" type="string" length="72" primaryKey="yes" modularize="property"
20 + category="formatted" description=""/>
21 + <columnDefinition name="Value" type="string" length="255" modularize="property"
22 + category="formatted" description=""/>
23 + </tableDefinition>
24 + <tableDefinition name="ComPlusPartitionRole" createSymbols="yes">
25 + <columnDefinition name="PartitionRole" type="string" length="72" primaryKey="yes" modularize="column"
26 + category="identifier" description=""/>
27 + <columnDefinition name="Partition_" type="string" length="72" modularize="column"
28 + keyTable="ComPlusPartition" keyColumn="1" category="identifier" description=""/>
29 + <columnDefinition name="Component_" type="string" length="72" nullable="yes" modularize="column"
30 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
31 + <columnDefinition name="Name" type="string" length="255" modularize="property"
32 + category="formatted" description=""/>
33 + </tableDefinition>
34 + <tableDefinition name="ComPlusUserInPartitionRole" createSymbols="yes">
35 + <columnDefinition name="UserInPartitionRole" type="string" length="72" primaryKey="yes" modularize="column"
36 + category="identifier" description=""/>
37 + <columnDefinition name="PartitionRole_" type="string" length="72" modularize="column"
38 + keyTable="ComPlusPartitionRole" keyColumn="1" category="identifier" description=""/>
39 + <columnDefinition name="Component_" type="string" length="72" modularize="column"
40 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
41 + <columnDefinition name="User_" type="string" length="72" modularize="column"
42 + category="identifier" description=""/>
43 + </tableDefinition>
44 + <tableDefinition name="ComPlusGroupInPartitionRole" createSymbols="yes">
45 + <columnDefinition name="GroupInPartitionRole" type="string" length="72" primaryKey="yes" modularize="column"
46 + category="identifier" description=""/>
47 + <columnDefinition name="PartitionRole_" type="string" length="72" modularize="column"
48 + keyTable="ComPlusPartitionRole" keyColumn="1" category="identifier" description=""/>
49 + <columnDefinition name="Component_" type="string" length="72" modularize="column"
50 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
51 + <columnDefinition name="Group_" type="string" length="72" modularize="column"
52 + category="identifier" description=""/>
53 + </tableDefinition>
54 + <tableDefinition name="ComPlusPartitionUser" createSymbols="yes">
55 + <columnDefinition name="PartitionUser" type="string" length="72" primaryKey="yes" modularize="column"
56 + category="identifier" description=""/>
57 + <columnDefinition name="Partition_" type="string" length="72" modularize="column"
58 + keyTable="ComPlusPartition" keyColumn="1" category="identifier" description=""/>
59 + <columnDefinition name="Component_" type="string" length="72" modularize="column"
60 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
61 + <columnDefinition name="User_" type="string" length="72" modularize="column"
62 + category="identifier" description=""/>
63 + </tableDefinition>
64 + <tableDefinition name="ComPlusApplication" createSymbols="yes">
65 + <columnDefinition name="Application" type="string" length="72" primaryKey="yes" modularize="column"
66 + category="identifier" description=""/>
67 + <columnDefinition name="Partition_" type="string" length="72" nullable="yes" modularize="column"
68 + keyTable="ComPlusPartition" keyColumn="1" category="identifier" description=""/>
69 + <columnDefinition name="Component_" type="string" length="72" nullable="yes" modularize="column"
70 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
71 + <columnDefinition name="Id" type="string" length="72" nullable="yes" modularize="property"
72 + category="formatted" description=""/>
73 + <columnDefinition name="Name" type="string" length="255" nullable="yes" modularize="property"
74 + category="formatted" description=""/>
75 + </tableDefinition>
76 + <tableDefinition name="ComPlusApplicationProperty">
77 + <columnDefinition name="Application_" type="string" length="72" primaryKey="yes" modularize="column"
78 + keyTable="ComPlusApplication" keyColumn="1" category="identifier" description=""/>
79 + <columnDefinition name="Name" type="string" length="72" primaryKey="yes" modularize="property"
80 + category="formatted" description=""/>
81 + <columnDefinition name="Value" type="string" length="255" modularize="property"
82 + category="formatted" description=""/>
83 + </tableDefinition>
84 + <tableDefinition name="ComPlusApplicationRole" createSymbols="yes">
85 + <columnDefinition name="ApplicationRole" type="string" length="72" primaryKey="yes" modularize="column"
86 + category="identifier" description=""/>
87 + <columnDefinition name="Application_" type="string" length="72" modularize="column"
88 + keyTable="ComPlusApplication" keyColumn="1" category="identifier" description=""/>
89 + <columnDefinition name="Component_" type="string" length="72" nullable="yes" modularize="column"
90 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
91 + <columnDefinition name="Name" type="string" length="255" modularize="property"
92 + category="formatted" description=""/>
93 + </tableDefinition>
94 + <tableDefinition name="ComPlusApplicationRoleProperty">
95 + <columnDefinition name="ApplicationRole_" type="string" length="72" primaryKey="yes" modularize="column"
96 + keyTable="ComPlusApplicationRole" keyColumn="1" category="identifier" description=""/>
97 + <columnDefinition name="Name" type="string" length="72" primaryKey="yes" modularize="property"
98 + category="formatted" description=""/>
99 + <columnDefinition name="Value" type="string" length="255" modularize="property"
100 + category="formatted" description=""/>
101 + </tableDefinition>
102 + <tableDefinition name="ComPlusUserInApplicationRole" createSymbols="yes">
103 + <columnDefinition name="UserInApplicationRole" type="string" length="72" primaryKey="yes" modularize="column"
104 + category="identifier" description=""/>
105 + <columnDefinition name="ApplicationRole_" type="string" length="72" modularize="column"
106 + keyTable="ComPlusApplicationRole" keyColumn="1" category="identifier" description=""/>
107 + <columnDefinition name="Component_" type="string" length="72" modularize="column"
108 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
109 + <columnDefinition name="User_" type="string" length="72" modularize="column"
110 + category="identifier" description=""/>
111 + </tableDefinition>
112 + <tableDefinition name="ComPlusGroupInApplicationRole" createSymbols="yes">
113 + <columnDefinition name="GroupInApplicationRole" type="string" length="72" primaryKey="yes" modularize="column"
114 + category="identifier" description=""/>
115 + <columnDefinition name="ApplicationRole_" type="string" length="72" modularize="column"
116 + keyTable="ComPlusApplicationRole" keyColumn="1" category="identifier" description=""/>
117 + <columnDefinition name="Component_" type="string" length="72" modularize="column"
118 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
119 + <columnDefinition name="Group_" type="string" length="72" modularize="column"
120 + category="identifier" description=""/>
121 + </tableDefinition>
122 + <tableDefinition name="ComPlusAssembly" createSymbols="yes">
123 + <columnDefinition name="Assembly" type="string" length="72" primaryKey="yes" modularize="column"
124 + category="identifier" description=""/>
125 + <columnDefinition name="Application_" type="string" length="72" nullable="yes" modularize="column"
126 + keyTable="ComPlusApplication" keyColumn="1" category="identifier" description=""/>
127 + <columnDefinition name="Component_" type="string" length="72" modularize="column"
128 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
129 + <columnDefinition name="AssemblyName" type="string" length="255" nullable="yes" modularize="property"
130 + category="formatted" description=""/>
131 + <columnDefinition name="DllPath" type="string" length="255" nullable="yes" modularize="property"
132 + category="formatted" description=""/>
133 + <columnDefinition name="TlbPath" type="string" length="255" nullable="yes" modularize="property"
134 + category="formatted" description=""/>
135 + <columnDefinition name="PSDllPath" type="string" length="255" nullable="yes" modularize="property"
136 + category="formatted" description=""/>
137 + <columnDefinition name="Attributes" type="number" length="4"
138 + description=""/>
139 + </tableDefinition>
140 + <tableDefinition name="ComPlusAssemblyDependency">
141 + <columnDefinition name="Assembly_" type="string" length="72" primaryKey="yes" modularize="column"
142 + keyTable="ComPlusAssembly" keyColumn="1" category="identifier" description=""/>
143 + <columnDefinition name="RequiredAssembly_" type="string" length="72" primaryKey="yes" modularize="column"
144 + keyTable="ComPlusAssembly" keyColumn="1" category="identifier" description=""/>
145 + </tableDefinition>
146 + <tableDefinition name="ComPlusComponent" createSymbols="yes">
147 + <columnDefinition name="ComPlusComponent" type="string" length="72" primaryKey="yes" modularize="column"
148 + category="identifier" description=""/>
149 + <columnDefinition name="Assembly_" type="string" length="72" modularize="column"
150 + keyTable="ComPlusAssembly" keyColumn="1" category="identifier" description=""/>
151 + <columnDefinition name="CLSID" type="string" length="72" modularize="property"
152 + category="formatted" description=""/>
153 + </tableDefinition>
154 + <tableDefinition name="ComPlusComponentProperty">
155 + <columnDefinition name="ComPlusComponent_" type="string" length="72" primaryKey="yes" modularize="column"
156 + keyTable="ComPlusComponent" keyColumn="1" category="identifier" description=""/>
157 + <columnDefinition name="Name" type="string" length="72" primaryKey="yes" modularize="property"
158 + category="formatted" description=""/>
159 + <columnDefinition name="Value" type="string" length="255" modularize="property"
160 + category="formatted" description=""/>
161 + </tableDefinition>
162 + <tableDefinition name="ComPlusRoleForComponent" createSymbols="yes">
163 + <columnDefinition name="RoleForComponent" type="string" length="72" primaryKey="yes" modularize="column"
164 + category="identifier" description=""/>
165 + <columnDefinition name="ComPlusComponent_" type="string" length="72" modularize="column"
166 + keyTable="ComPlusComponent" keyColumn="1" category="identifier" description=""/>
167 + <columnDefinition name="ApplicationRole_" type="string" length="72" modularize="column"
168 + keyTable="ComPlusApplicationRole" keyColumn="1" category="identifier" description=""/>
169 + <columnDefinition name="Component_" type="string" length="72" modularize="column"
170 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
171 + </tableDefinition>
172 + <tableDefinition name="ComPlusInterface" createSymbols="yes">
173 + <columnDefinition name="Interface" type="string" length="72" primaryKey="yes" modularize="column"
174 + category="identifier" description=""/>
175 + <columnDefinition name="ComPlusComponent_" type="string" length="72" modularize="column"
176 + keyTable="ComPlusComponent" keyColumn="1" category="identifier" description=""/>
177 + <columnDefinition name="IID" type="string" length="72" modularize="property"
178 + category="formatted" description=""/>
179 + </tableDefinition>
180 + <tableDefinition name="ComPlusInterfaceProperty">
181 + <columnDefinition name="Interface_" type="string" length="72" primaryKey="yes" modularize="column"
182 + keyTable="ComPlusInterface" keyColumn="1" category="identifier" description=""/>
183 + <columnDefinition name="Name" type="string" length="72" primaryKey="yes" modularize="property"
184 + category="formatted" description=""/>
185 + <columnDefinition name="Value" type="string" length="255" modularize="property"
186 + category="formatted" description=""/>
187 + </tableDefinition>
188 + <tableDefinition name="ComPlusRoleForInterface" createSymbols="yes">
189 + <columnDefinition name="RoleForInterface" type="string" length="72" primaryKey="yes" modularize="column"
190 + category="identifier" description=""/>
191 + <columnDefinition name="Interface_" type="string" length="72" modularize="column"
192 + keyTable="ComPlusInterface" keyColumn="1" category="identifier" description=""/>
193 + <columnDefinition name="ApplicationRole_" type="string" length="72" modularize="column"
194 + keyTable="ComPlusApplicationRole" keyColumn="1" category="identifier" description=""/>
195 + <columnDefinition name="Component_" type="string" length="72" modularize="column"
196 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
197 + </tableDefinition>
198 + <tableDefinition name="ComPlusMethod" createSymbols="yes">
199 + <columnDefinition name="Method" type="string" length="72" primaryKey="yes" modularize="column"
200 + category="identifier" description=""/>
201 + <columnDefinition name="Interface_" type="string" length="72" modularize="column"
202 + keyTable="ComPlusInterface" keyColumn="1" category="identifier" description=""/>
203 + <columnDefinition name="Index" type="number" length="4" nullable="yes"
204 + description=""/>
205 + <columnDefinition name="Name" type="string" length="255" nullable="yes" modularize="property"
206 + category="formatted" description=""/>
207 + </tableDefinition>
208 + <tableDefinition name="ComPlusMethodProperty">
209 + <columnDefinition name="Method_" type="string" length="72" primaryKey="yes" modularize="column"
210 + keyTable="ComPlusMethod" keyColumn="1" category="identifier" description=""/>
211 + <columnDefinition name="Name" type="string" length="72" primaryKey="yes" modularize="property"
212 + category="formatted" description=""/>
213 + <columnDefinition name="Value" type="string" length="255" modularize="property"
214 + category="formatted" description=""/>
215 + </tableDefinition>
216 + <tableDefinition name="ComPlusRoleForMethod" createSymbols="yes">
217 + <columnDefinition name="RoleForMethod" type="string" length="72" primaryKey="yes" modularize="column"
218 + category="identifier" description=""/>
219 + <columnDefinition name="Method_" type="string" length="72" modularize="column"
220 + keyTable="ComPlusMethod" keyColumn="1" category="identifier" description=""/>
221 + <columnDefinition name="ApplicationRole_" type="string" length="72" modularize="column"
222 + keyTable="ComPlusApplicationRole" keyColumn="1" category="identifier" description=""/>
223 + <columnDefinition name="Component_" type="string" length="72" modularize="column"
224 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
225 + </tableDefinition>
226 + <tableDefinition name="ComPlusSubscription" createSymbols="yes">
227 + <columnDefinition name="Subscription" type="string" length="72" primaryKey="yes" modularize="column"
228 + category="identifier" description=""/>
229 + <columnDefinition name="ComPlusComponent_" type="string" length="72" primaryKey="yes" modularize="column"
230 + keyTable="ComPlusComponent" keyColumn="1" category="identifier" description=""/>
231 + <columnDefinition name="Component_" type="string" length="72" modularize="column"
232 + keyTable="Component" keyColumn="1" category="identifier" description=""/>
233 + <columnDefinition name="Id" type="string" length="72" nullable="yes" modularize="property"
234 + category="formatted" description=""/>
235 + <columnDefinition name="Name" type="string" length="255" modularize="property"
236 + category="formatted" description=""/>
237 + <columnDefinition name="EventCLSID" type="string" length="72" nullable="yes" modularize="property"
238 + category="formatted" description=""/>
239 + <columnDefinition name="PublisherID" type="string" length="72" nullable="yes" modularize="property"
240 + category="formatted" description=""/>
241 + </tableDefinition>
242 + <tableDefinition name="ComPlusSubscriptionProperty">
243 + <columnDefinition name="Subscription_" type="string" length="72" primaryKey="yes" modularize="column"
244 + keyTable="ComPlusSubscription" keyColumn="1" category="identifier" description=""/>
245 + <columnDefinition name="Name" type="string" length="72" primaryKey="yes" modularize="property"
246 + category="formatted" description=""/>
247 + <columnDefinition name="Value" type="string" length="255" modularize="property"
248 + category="formatted" description=""/>
249 + </tableDefinition>
250 +</tableDefinitions>
src/wixlib/ComPlusExtension.wixproj new
+26
@@ -0,0 +1,26 @@
1 +<?xml version="1.0" encoding="utf-8" ?>
2 +<!-- 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. -->
3 +
4 +
5 +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
6 + <PropertyGroup>
7 + <ProjectGuid>{E191E61E-E098-4F71-888F-51A79F952022}</ProjectGuid>
8 + <OutputName>complus</OutputName>
9 + <OutputType>Library</OutputType>
10 + <BindFiles>true</BindFiles>
11 + <SuppressSpecificWarnings>1086</SuppressSpecificWarnings>
12 + </PropertyGroup>
13 +
14 + <ItemGroup>
15 + <Compile Include="ComPlusExtension.wxs" />
16 + <EmbeddedResource Include="en-us.wxl" />
17 + <EmbeddedResource Include="es-es.wxl" />
18 + <EmbeddedResource Include="ja-jp.wxl" />
19 + </ItemGroup>
20 +
21 + <ItemGroup>
22 + <ProjectReference Include="..\ca\complusca.proj" />
23 + </ItemGroup>
24 +
25 + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), wix.proj))\tools\WixBuild.targets" />
26 +</Project>
src/wixlib/ComPlusExtension.wxs new
+139
@@ -0,0 +1,139 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<!-- 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. -->
3 +
4 +
5 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
6 + <?include caerr.wxi ?>
7 +
8 + <Fragment>
9 + <UI Id="ComPlusUI">
10 + <Error Id="$(var.msierrComPlusCannotConnect)">!(loc.msierrComPlusCannotConnect)</Error>
11 + <Error Id="$(var.msierrComPlusPartitionReadFailed)">!(loc.msierrComPlusPartitionReadFailed)</Error>
12 + <Error Id="$(var.msierrComPlusPartitionRoleReadFailed)">!(loc.msierrComPlusPartitionRoleReadFailed)</Error>
13 + <Error Id="$(var.msierrComPlusUserInPartitionRoleReadFailed)">!(loc.msierrComPlusUserInPartitionRoleReadFailed)</Error>
14 + <Error Id="$(var.msierrComPlusPartitionUserReadFailed)">!(loc.msierrComPlusPartitionUserReadFailed)</Error>
15 + <Error Id="$(var.msierrComPlusApplicationReadFailed)">!(loc.msierrComPlusApplicationReadFailed)</Error>
16 + <Error Id="$(var.msierrComPlusApplicationRoleReadFailed)">!(loc.msierrComPlusApplicationRoleReadFailed)</Error>
17 + <Error Id="$(var.msierrComPlusUserInApplicationRoleReadFailed)">!(loc.msierrComPlusUserInApplicationRoleReadFailed)</Error>
18 + <Error Id="$(var.msierrComPlusAssembliesReadFailed)">!(loc.msierrComPlusAssembliesReadFailed)</Error>
19 + <Error Id="$(var.msierrComPlusSubscriptionReadFailed)">!(loc.msierrComPlusSubscriptionReadFailed)</Error>
20 + <Error Id="$(var.msierrComPlusPartitionDependency)">!(loc.msierrComPlusPartitionDependency)</Error>
21 + <Error Id="$(var.msierrComPlusPartitionNotFound)">!(loc.msierrComPlusPartitionNotFound)</Error>
22 + <Error Id="$(var.msierrComPlusPartitionIdConflict)">!(loc.msierrComPlusPartitionIdConflict)</Error>
23 + <Error Id="$(var.msierrComPlusPartitionNameConflict)">!(loc.msierrComPlusPartitionNameConflict)</Error>
24 + <Error Id="$(var.msierrComPlusApplicationDependency)">!(loc.msierrComPlusApplicationDependency)</Error>
25 + <Error Id="$(var.msierrComPlusApplicationNotFound)">!(loc.msierrComPlusApplicationNotFound)</Error>
26 + <Error Id="$(var.msierrComPlusApplicationIdConflict)">!(loc.msierrComPlusApplicationIdConflict)</Error>
27 + <Error Id="$(var.msierrComPlusApplicationNameConflict)">!(loc.msierrComPlusApplicationNameConflict)</Error>
28 + <Error Id="$(var.msierrComPlusApplicationRoleDependency)">!(loc.msierrComPlusApplicationRoleDependency)</Error>
29 + <Error Id="$(var.msierrComPlusApplicationRoleNotFound)">!(loc.msierrComPlusApplicationRoleNotFound)</Error>
30 + <Error Id="$(var.msierrComPlusApplicationRoleConflict)">!(loc.msierrComPlusApplicationRoleConflict)</Error>
31 + <Error Id="$(var.msierrComPlusAssemblyDependency)">!(loc.msierrComPlusAssemblyDependency)</Error>
32 + <Error Id="$(var.msierrComPlusSubscriptionIdConflict)">!(loc.msierrComPlusSubscriptionIdConflict)</Error>
33 + <Error Id="$(var.msierrComPlusSubscriptionNameConflict)">!(loc.msierrComPlusSubscriptionNameConflict)</Error>
34 + <Error Id="$(var.msierrComPlusFailedLookupNames)">!(loc.msierrComPlusFailedLookupNames)</Error>
35 +
36 + <ProgressText Action="ComPlusInstallExecute">!(loc.ComPlusInstallExecute)</ProgressText>
37 + <ProgressText Action="ComPlusUninstallExecute">!(loc.ComPlusUninstallExecute)</ProgressText>
38 +
39 + <ProgressText Action="CreateComPlusPartitions" Template="!(loc.CreateComPlusPartitionsTemplate)">!(loc.CreateComPlusPartitions)</ProgressText>
40 + <ProgressText Action="RemoveComPlusPartitions" Template="!(loc.RemoveComPlusPartitionsTemplate)">!(loc.RemoveComPlusPartitions)</ProgressText>
41 + <ProgressText Action="AddUsersToComPlusPartitionRoles" Template="!(loc.AddUsersToComPlusPartitionRolesTemplate)">!(loc.AddUsersToComPlusPartitionRoles)</ProgressText>
42 + <ProgressText Action="RemoveUsersFromComPlusPartRoles" Template="!(loc.RemoveUsersFromComPlusPartitionRolesTemplate)">!(loc.RemoveUsersFromComPlusPartitionRoles)</ProgressText>
43 + <ProgressText Action="AddComPlusPartitionUsers" Template="!(loc.AddComPlusPartitionUsersTemplate)">!(loc.AddComPlusPartitionUsers)</ProgressText>
44 + <ProgressText Action="RemoveComPlusPartitionUsers" Template="!(loc.RemoveComPlusPartitionUsersTemplate)">!(loc.RemoveComPlusPartitionUsers)</ProgressText>
45 + <ProgressText Action="CreateComPlusApplications" Template="!(loc.CreateComPlusApplicationsTemplate)">!(loc.CreateComPlusApplications)</ProgressText>
46 + <ProgressText Action="RemoveComPlusApplications" Template="!(loc.RemoveComPlusApplicationsTemplate)">!(loc.RemoveComPlusApplications)</ProgressText>
47 + <ProgressText Action="CreateComPlusApplicationRoles" Template="!(loc.CreateComPlusApplicationRolesTemplate)">!(loc.CreateComPlusApplicationRoles)</ProgressText>
48 + <ProgressText Action="RemoveComPlusApplicationRoles" Template="!(loc.RemoveComPlusApplicationRolesTemplate)">!(loc.RemoveComPlusApplicationRoles)</ProgressText>
49 + <ProgressText Action="AddUsersToComPlusApplicationRoles" Template="!(loc.AddUsersToComPlusApplicationRolesTemplate)">!(loc.AddUsersToComPlusApplicationRoles)</ProgressText>
50 + <ProgressText Action="RemoveUsersFromComPlusAppRoles" Template="!(loc.RemoveUsersFromComPlusApplicationRolesTemplate)">!(loc.RemoveUsersFromComPlusApplicationRoles)</ProgressText>
51 + <ProgressText Action="RegisterComPlusAssemblies" Template="!(loc.RegisterComPlusAssembliesTemplate)">!(loc.RegisterComPlusAssemblies)</ProgressText>
52 + <ProgressText Action="UnregisterComPlusAssemblies" Template="!(loc.UnregisterComPlusAssembliesTemplate)">!(loc.UnregisterComPlusAssemblies)</ProgressText>
53 + <ProgressText Action="AddComPlusRoleAssignments" Template="!(loc.AddComPlusRoleAssignmentsTemplate)">!(loc.AddComPlusRoleAssignments)</ProgressText>
54 + <ProgressText Action="RemoveComPlusRoleAssignments" Template="!(loc.RemoveComPlusRoleAssignmentsTemplate)">!(loc.RemoveComPlusRoleAssignments)</ProgressText>
55 + <ProgressText Action="CreateSubscrComPlusComponents" Template="!(loc.CreateSubscriptionsComPlusComponentsTemplate)">!(loc.CreateSubscriptionsComPlusComponents)</ProgressText>
56 + <ProgressText Action="RemoveSubscrComPlusComponents" Template="!(loc.RemoveSubscriptionsComPlusComponentsTemplate)">!(loc.RemoveSubscriptionsComPlusComponents)</ProgressText>
57 + </UI>
58 + </Fragment>
59 +
60 + <Fragment>
61 + <UIRef Id="ComPlusUI" />
62 +
63 + <CustomAction Id="ConfigureComPlusInstall" BinaryKey="WixCPSched_x86" DllEntry="ConfigureComPlusInstall" Execute="immediate" Return="check" SuppressModularization="yes" />
64 + <CustomAction Id="ConfigureComPlusUninstall" BinaryKey="WixCPSched_x86" DllEntry="ConfigureComPlusUninstall" Execute="immediate" Return="check" SuppressModularization="yes" />
65 + <CustomAction Id="ComPlusInstallPrepare" BinaryKey="WixCPExec_x86" DllEntry="ComPlusPrepare" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
66 + <CustomAction Id="ComPlusRollbackInstallPrepare" BinaryKey="WixCPExec_x86" DllEntry="ComPlusCleanup" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
67 + <CustomAction Id="ComPlusInstallExecute" BinaryKey="WixCPExec_x86" DllEntry="ComPlusInstallExecute" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
68 + <CustomAction Id="ComPlusInstallExecuteCommit" BinaryKey="WixCPExec_x86" DllEntry="ComPlusInstallExecuteCommit" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
69 + <CustomAction Id="ComPlusRollbackInstallExecute" BinaryKey="WixCPExec_x86" DllEntry="ComPlusRollbackInstallExecute" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
70 + <CustomAction Id="ComPlusInstallCommit" BinaryKey="WixCPExec_x86" DllEntry="ComPlusCleanup" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
71 + <CustomAction Id="ComPlusUninstallPrepare" BinaryKey="WixCPExec_x86" DllEntry="ComPlusPrepare" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
72 + <CustomAction Id="ComPlusRollbackUninstallPrepare" BinaryKey="WixCPExec_x86" DllEntry="ComPlusCleanup" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
73 + <CustomAction Id="ComPlusUninstallExecute" BinaryKey="WixCPExec_x86" DllEntry="ComPlusUninstallExecute" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
74 + <CustomAction Id="ComPlusRollbackUninstallExecute" BinaryKey="WixCPExec_x86" DllEntry="ComPlusInstallExecute" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
75 + <CustomAction Id="ComPlusUninstallCommit" BinaryKey="WixCPExec_x86" DllEntry="ComPlusCleanup" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
76 +
77 + <Property Id="ComPlusInstallPrepare" Hidden="yes" SuppressModularization="yes" />
78 + <Property Id="ComPlusRollbackInstallPrepare" Hidden="yes" SuppressModularization="yes" />
79 + <Property Id="ComPlusInstallExecute" Hidden="yes" SuppressModularization="yes" />
80 + <Property Id="ComPlusInstallExecuteCommit" Hidden="yes" SuppressModularization="yes" />
81 + <Property Id="ComPlusRollbackInstallExecute" Hidden="yes" SuppressModularization="yes" />
82 + <Property Id="ComPlusInstallCommit" Hidden="yes" SuppressModularization="yes" />
83 + <Property Id="ComPlusUninstallPrepare" Hidden="yes" SuppressModularization="yes" />
84 + <Property Id="ComPlusRollbackUninstallPrepare" Hidden="yes" SuppressModularization="yes" />
85 + <Property Id="ComPlusUninstallExecute" Hidden="yes" SuppressModularization="yes" />
86 + <Property Id="ComPlusRollbackUninstallExecute" Hidden="yes" SuppressModularization="yes" />
87 + <Property Id="ComPlusUninstallCommit" Hidden="yes" SuppressModularization="yes" />
88 +
89 + <InstallExecuteSequence>
90 + <Custom Action="ConfigureComPlusUninstall" After="DeleteServices" Overridable="yes">VersionNT >= 500</Custom>
91 + <Custom Action="ConfigureComPlusInstall" Before="InstallServices" Overridable="yes">VersionNT >= 500</Custom>
92 + </InstallExecuteSequence>
93 + </Fragment>
94 +
95 + <Fragment>
96 + <UIRef Id="ComPlusUI" />
97 +
98 + <CustomAction Id="ConfigureComPlusInstall_x64" BinaryKey="WixCPSched_x64" DllEntry="ConfigureComPlusInstall" Execute="immediate" Return="check" SuppressModularization="yes" />
99 + <CustomAction Id="ConfigureComPlusUninstall_x64" BinaryKey="WixCPSched_x64" DllEntry="ConfigureComPlusUninstall" Execute="immediate" Return="check" SuppressModularization="yes" />
100 + <CustomAction Id="ComPlusInstallPrepare_64" BinaryKey="WixCPExec_x64" DllEntry="ComPlusPrepare" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
101 + <CustomAction Id="ComPlusRollbackInstallPrepare_64" BinaryKey="WixCPExec_x64" DllEntry="ComPlusCleanup" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
102 + <CustomAction Id="ComPlusInstallExecute_64" BinaryKey="WixCPExec_x64" DllEntry="ComPlusInstallExecute" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
103 + <CustomAction Id="ComPlusInstallExecuteCommit_64" BinaryKey="WixCPExec_x64" DllEntry="ComPlusInstallExecuteCommit" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
104 + <CustomAction Id="ComPlusRollbackInstallExecute_64" BinaryKey="WixCPExec_x64" DllEntry="ComPlusRollbackInstallExecute" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
105 + <CustomAction Id="ComPlusInstallCommit_64" BinaryKey="WixCPExec_x64" DllEntry="ComPlusCleanup" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
106 + <CustomAction Id="ComPlusUninstallPrepare_64" BinaryKey="WixCPExec_x64" DllEntry="ComPlusPrepare" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
107 + <CustomAction Id="ComPlusRollbackUninstallPrepare_64" BinaryKey="WixCPExec_x64" DllEntry="ComPlusCleanup" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
108 + <CustomAction Id="ComPlusUninstallExecute_64" BinaryKey="WixCPExec_x64" DllEntry="ComPlusUninstallExecute" Execute="deferred" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
109 + <CustomAction Id="ComPlusRollbackUninstallExecute_64" BinaryKey="WixCPExec_x64" DllEntry="ComPlusInstallExecute" Execute="rollback" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
110 + <CustomAction Id="ComPlusUninstallCommit_64" BinaryKey="WixCPExec_x64" DllEntry="ComPlusCleanup" Execute="commit" Return="check" Impersonate="no" HideTarget="yes" SuppressModularization="yes" />
111 +
112 + <Property Id="ComPlusInstallPrepare_64" Hidden="yes" SuppressModularization="yes" />
113 + <Property Id="ComPlusRollbackInstallPrepare_64" Hidden="yes" SuppressModularization="yes" />
114 + <Property Id="ComPlusInstallExecute_64" Hidden="yes" SuppressModularization="yes" />
115 + <Property Id="ComPlusInstallExecuteCommit_64" Hidden="yes" SuppressModularization="yes" />
116 + <Property Id="ComPlusRollbackInstallExecute_64" Hidden="yes" SuppressModularization="yes" />
117 + <Property Id="ComPlusInstallCommit_64" Hidden="yes" SuppressModularization="yes" />
118 + <Property Id="ComPlusUninstallPrepare_64" Hidden="yes" SuppressModularization="yes" />
119 + <Property Id="ComPlusRollbackUninstallPrepare_64" Hidden="yes" SuppressModularization="yes" />
120 + <Property Id="ComPlusUninstallExecute_64" Hidden="yes" SuppressModularization="yes" />
121 + <Property Id="ComPlusRollbackUninstallExecute_64" Hidden="yes" SuppressModularization="yes" />
122 + <Property Id="ComPlusUninstallCommit_64" Hidden="yes" SuppressModularization="yes" />
123 +
124 + <InstallExecuteSequence>
125 + <Custom Action="ConfigureComPlusUninstall_x64" After="DeleteServices" Overridable="yes">VersionNT >= 500</Custom>
126 + <Custom Action="ConfigureComPlusInstall_x64" Before="InstallServices" Overridable="yes">VersionNT >= 500</Custom>
127 + </InstallExecuteSequence>
128 + </Fragment>
129 +
130 + <Fragment>
131 + <Binary Id="WixCPExec_x86" SourceFile="!(bindpath.x86)\cpexec.dll"/>
132 + <Binary Id="WixCPSched_x86" SourceFile="!(bindpath.x86)\cpsched.dll"/>
133 + </Fragment>
134 +
135 + <Fragment>
136 + <Binary Id="WixCPExec_x64" SourceFile="!(bindpath.x64)\cpexec.dll"/>
137 + <Binary Id="WixCPSched_x64" SourceFile="!(bindpath.x64)\cpsched.dll"/>
138 + </Fragment>
139 +</Wix>
src/wixlib/en-us.wxl new
+71
@@ -0,0 +1,71 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<!-- 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. -->
3 +
4 +
5 +<WixLocalization Culture="en-us" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 + <String Id="msierrComPlusCannotConnect" Overridable="yes">Cannot connect to the COM+ admin catalog. ([2] [3] [4] [5])</String>
7 + <String Id="msierrComPlusPartitionReadFailed" Overridable="yes">Failed to read COM+ partitions. ([2] [3] [4] [5])</String>
8 + <String Id="msierrComPlusPartitionRoleReadFailed" Overridable="yes">Failed to read COM+ partition roles. ([2] [3] [4] [5])</String>
9 + <String Id="msierrComPlusUserInPartitionRoleReadFailed" Overridable="yes">Failed to read COM+ users in partition roles. ([2] [3] [4] [5])</String>
10 + <String Id="msierrComPlusPartitionUserReadFailed" Overridable="yes">Failed to read COM+ partition users. ([2] [3] [4] [5])</String>
11 + <String Id="msierrComPlusApplicationReadFailed" Overridable="yes">Failed to read COM+ applications. ([2] [3] [4] [5])</String>
12 + <String Id="msierrComPlusApplicationRoleReadFailed" Overridable="yes">Failed to read COM+ application roles. ([2] [3] [4] [5])</String>
13 + <String Id="msierrComPlusUserInApplicationRoleReadFailed" Overridable="yes">Failed to read COM+ users in application roles. ([2] [3] [4] [5])</String>
14 + <String Id="msierrComPlusAssembliesReadFailed" Overridable="yes">Failed to read COM+ assemblies. ([2] [3] [4] [5])</String>
15 + <String Id="msierrComPlusSubscriptionReadFailed" Overridable="yes">Failed to read COM+ event subscriptions. ([2] [3] [4] [5])</String>
16 + <String Id="msierrComPlusPartitionDependency" Overridable="yes">Another entity is dependent on a COM+ partition that is not being installed. ([2] [3] [4] [5])</String>
17 + <String Id="msierrComPlusPartitionNotFound" Overridable="yes">The COM+ partition was not found. ([2] [3] [4] [5])</String>
18 + <String Id="msierrComPlusPartitionIdConflict" Overridable="yes">A COM+ partition with the same id already exists. ([2] [3] [4] [5])</String>
19 + <String Id="msierrComPlusPartitionNameConflict" Overridable="yes">A COM+ partition with the same name already exists. ([2] [3] [4] [5])</String>
20 + <String Id="msierrComPlusApplicationDependency" Overridable="yes">Another entity is dependent on a COM+ application that is not being installed. ([2] [3] [4] [5])</String>
21 + <String Id="msierrComPlusApplicationNotFound" Overridable="yes">The COM+ application was not found. ([2] [3] [4] [5])</String>
22 + <String Id="msierrComPlusApplicationIdConflict" Overridable="yes">A COM+ application with the same id already exists. ([2] [3] [4] [5])</String>
23 + <String Id="msierrComPlusApplicationNameConflict" Overridable="yes">A COM+ application with the same name already exists. ([2] [3] [4] [5])</String>
24 + <String Id="msierrComPlusApplicationRoleDependency" Overridable="yes">Another entity is dependent on a COM+ application role that is not being installed. ([2] [3] [4] [5])</String>
25 + <String Id="msierrComPlusApplicationRoleNotFound" Overridable="yes">The COM+ application role was not found. ([2] [3] [4] [5])</String>
26 + <String Id="msierrComPlusApplicationRoleConflict" Overridable="yes">A COM+ application role with the same name already exists. ([2] [3] [4] [5])</String>
27 + <String Id="msierrComPlusAssemblyDependency" Overridable="yes">Another entity is dependent on a COM+ assembly that is not being installed. ([2] [3] [4] [5])</String>
28 + <String Id="msierrComPlusSubscriptionIdConflict" Overridable="yes">A COM+ component event subscription with the same id already exists. ([2] [3] [4] [5])</String>
29 + <String Id="msierrComPlusSubscriptionNameConflict" Overridable="yes">A COM+ component event subscription with the same name already exists. ([2] [3] [4] [5])</String>
30 + <String Id="msierrComPlusFailedLookupNames" Overridable="yes">Failed to lookup user account names. ([2] [3] [4] [5])</String>
31 +
32 + <String Id="ComPlusInstallExecute" Overridable="yes">Registering COM+ components</String>
33 + <String Id="ComPlusUninstallExecute" Overridable="yes">Unregistering COM+ components</String>
34 +
35 + <String Id="CreateComPlusPartitions" Overridable="yes">Creating COM+ partitions</String>
36 + <String Id="CreateComPlusPartitionsTemplate" Overridable="yes">Partition: [1]</String>
37 + <String Id="RemoveComPlusPartitions" Overridable="yes">Removing COM+ partitions</String>
38 + <String Id="RemoveComPlusPartitionsTemplate" Overridable="yes">Partition: [1]</String>
39 + <String Id="AddUsersToComPlusPartitionRoles" Overridable="yes">Adding users to COM+ partition roles</String>
40 + <String Id="AddUsersToComPlusPartitionRolesTemplate" Overridable="yes">Role: [1]</String>
41 + <String Id="RemoveUsersFromComPlusPartitionRoles" Overridable="yes">Removing users from COM+ partition roles</String>
42 + <String Id="RemoveUsersFromComPlusPartitionRolesTemplate" Overridable="yes">Role: [1]</String>
43 + <String Id="AddComPlusPartitionUsers" Overridable="yes">Setting default COM+ partitions for users</String>
44 + <String Id="AddComPlusPartitionUsersTemplate" Overridable="yes">User: [1]</String>
45 + <String Id="RemoveComPlusPartitionUsers" Overridable="yes">Removing default COM+ partitions for users</String>
46 + <String Id="RemoveComPlusPartitionUsersTemplate" Overridable="yes">User: [1]</String>
47 + <String Id="CreateComPlusApplications" Overridable="yes">Creating COM+ applications</String>
48 + <String Id="CreateComPlusApplicationsTemplate" Overridable="yes">Application: [1]</String>
49 + <String Id="RemoveComPlusApplications" Overridable="yes">Removing COM+ applications</String>
50 + <String Id="RemoveComPlusApplicationsTemplate" Overridable="yes">Application: [1]</String>
51 + <String Id="CreateComPlusApplicationRoles" Overridable="yes">Creating COM+ application roles</String>
52 + <String Id="CreateComPlusApplicationRolesTemplate" Overridable="yes">Role: [1]</String>
53 + <String Id="RemoveComPlusApplicationRoles" Overridable="yes">Removing COM+ application roles</String>
54 + <String Id="RemoveComPlusApplicationRolesTemplate" Overridable="yes">Role: [1]</String>
55 + <String Id="AddUsersToComPlusApplicationRoles" Overridable="yes">Adding users to COM+ application roles</String>
56 + <String Id="AddUsersToComPlusApplicationRolesTemplate" Overridable="yes">User: [1]</String>
57 + <String Id="RemoveUsersFromComPlusApplicationRoles" Overridable="yes">Removing users from COM+ application roles</String>
58 + <String Id="RemoveUsersFromComPlusApplicationRolesTemplate" Overridable="yes">User: [1]</String>
59 + <String Id="RegisterComPlusAssemblies" Overridable="yes">Registering COM+ components</String>
60 + <String Id="RegisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
61 + <String Id="UnregisterComPlusAssemblies" Overridable="yes">Unregistering COM+ components</String>
62 + <String Id="UnregisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
63 + <String Id="AddComPlusRoleAssignments" Overridable="yes">Assigning roles to COM+ components</String>
64 + <String Id="AddComPlusRoleAssignmentsTemplate" Overridable="yes">Component: [1]</String>
65 + <String Id="RemoveComPlusRoleAssignments" Overridable="yes">Removing role assignments from COM+ components</String>
66 + <String Id="RemoveComPlusRoleAssignmentsTemplate" Overridable="yes">Component: [1]</String>
67 + <String Id="CreateSubscriptionsComPlusComponents" Overridable="yes">Creating subscriptions for COM+ components</String>
68 + <String Id="CreateSubscriptionsComPlusComponentsTemplate" Overridable="yes">Subscription: [1]</String>
69 + <String Id="RemoveSubscriptionsComPlusComponents" Overridable="yes">Removing subscriptions for COM+ components</String>
70 + <String Id="RemoveSubscriptionsComPlusComponentsTemplate" Overridable="yes">Subscription: [1]</String>
71 +</WixLocalization>
src/wixlib/es-es.wxl new
+72
@@ -0,0 +1,72 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<!-- 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. -->
3 +
4 +
5 +<WixLocalization Culture="es-es" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 + <String Id="msierrComPlusCannotConnect" Overridable="yes">No se puede conectar al catálogo de administración de COM+. ([2] [3] [4] [5])</String>
7 + <String Id="msierrComPlusPartitionReadFailed" Overridable="yes">Falla al leer las particiones COM+. ([2] [3] [4] [5])</String>
8 + <String Id="msierrComPlusPartitionRoleReadFailed" Overridable="yes">Falla al leer los roles de las particiones COM+. ([2] [3] [4] [5])</String>
9 + <String Id="msierrComPlusUserInPartitionRoleReadFailed" Overridable="yes">Falla al leer los usuario en los roles de las particiones COM+. ([2] [3] [4] [5])</String>
10 + <String Id="msierrComPlusPartitionUserReadFailed" Overridable="yes">Falla al leer los usuario de las particiones COM+. ([2] [3] [4] [5])</String>
11 + <String Id="msierrComPlusApplicationReadFailed" Overridable="yes">Falla al leer las aplicaciones COM+. ([2] [3] [4] [5])</String>
12 + <String Id="msierrComPlusApplicationRoleReadFailed" Overridable="yes">Falla al leer los roles de las aplicaciones COM+. ([2] [3] [4] [5])</String>
13 + <String Id="msierrComPlusUserInApplicationRoleReadFailed" Overridable="yes">Falla al leer los usuario de las aplicaciones COM+. ([2] [3] [4] [5])</String>
14 + <String Id="msierrComPlusAssembliesReadFailed" Overridable="yes">Falla al leer los ensamblados COM+. ([2] [3] [4] [5])</String>
15 + <String Id="msierrComPlusSubscriptionReadFailed" Overridable="yes">Falla al leer las suscripciones a eventos COM+. ([2] [3] [4] [5])</String>
16 + <String Id="msierrComPlusPartitionDependency" Overridable="yes">Otra entidad es dependiente de una partición COM+ que no está siendo instalada. ([2] [3] [4] [5])</String>
17 + <String Id="msierrComPlusPartitionNotFound" Overridable="yes">La partición COM+ no pudo ser encontrada. ([2] [3] [4] [5])</String>
18 + <String Id="msierrComPlusPartitionIdConflict" Overridable="yes">Ya existe otra partición COM+ con el mismo id. ([2] [3] [4] [5])</String>
19 + <String Id="msierrComPlusPartitionNameConflict" Overridable="yes">Ya existe otra partición COM+ con el mismo nombre. ([2] [3] [4] [5])</String>
20 + <String Id="msierrComPlusApplicationDependency" Overridable="yes">Otra entidad es dependiente de una aplicación COM+ que no está siendo instalada. ([2] [3] [4] [5])</String>
21 + <String Id="msierrComPlusApplicationNotFound" Overridable="yes">La aplicación COM+ no pudo ser encontrada. ([2] [3] [4] [5])</String>
22 + <String Id="msierrComPlusApplicationIdConflict" Overridable="yes">Ya existe otra aplicación COM+ con el mismo id. ([2] [3] [4] [5])</String>
23 + <String Id="msierrComPlusApplicationNameConflict" Overridable="yes">Ya existe otra aplicación COM+ con el mismo nombre. ([2] [3] [4] [5])</String>
24 + <String Id="msierrComPlusApplicationRoleDependency" Overridable="yes">Otra entidad es dependiente de un rol de aplicación COM+ que no está siendo instalado. ([2] [3] [4] [5])</String>
25 + <String Id="msierrComPlusApplicationRoleNotFound" Overridable="yes">El rol de aplicación COM+ no pudo ser encontrado. ([2] [3] [4] [5])</String>
26 + <String Id="msierrComPlusApplicationRoleConflict" Overridable="yes">Ya existe otro rol de aplicación COM+ con el mismo nombre. ([2] [3] [4] [5])</String>
27 + <String Id="msierrComPlusAssemblyDependency" Overridable="yes">Otra entidad es dependiente de un ensamblado COM+ que no está siendo instalado. ([2] [3] [4] [5])</String>
28 + <String Id="msierrComPlusSubscriptionIdConflict" Overridable="yes">Ya existe otra suscripción de evento al componente COM+ con el mismo id. ([2] [3] [4] [5])</String>
29 + <String Id="msierrComPlusSubscriptionNameConflict" Overridable="yes">Ya existe otra suscripción de evento al componente COM+ con el mismo nombre. ([2] [3] [4] [5])</String>
30 + <String Id="msierrComPlusFailedLookupNames" Overridable="yes">Falla el la búsqueda de los nombres de usuario. ([2] [3] [4] [5])</String>
31 +
32 + <String Id="ComPlusInstallExecute" Overridable="yes">Registrando componentes COM+</String>
33 + <String Id="ComPlusUninstallExecute" Overridable="yes">Anular el registro de componentes COM+</String>
34 +
35 + <String Id="CreateComPlusPartitions" Overridable="yes">Creando particiones COM+</String>
36 + <String Id="CreateComPlusPartitionsTemplate" Overridable="yes">Particiones: [1]</String>
37 + <String Id="RemoveComPlusPartitions" Overridable="yes">Borrando particiones COM+</String>
38 + <String Id="RemoveComPlusPartitionsTemplate" Overridable="yes">Particiones: [1]</String>
39 + <String Id="AddUsersToComPlusPartitionRoles" Overridable="yes">Agregando usuarios a los roles de las particiones COM+</String>
40 + <String Id="AddUsersToComPlusPartitionRolesTemplate" Overridable="yes">Rol: [1]</String>
41 + <String Id="RemoveUsersFromComPlusPartitionRoles" Overridable="yes">Borrando usuarios a los roles de las particiones COM+</String>
42 + <String Id="RemoveUsersFromComPlusPartitionRolesTemplate" Overridable="yes">Rol: [1]</String>
43 + <String Id="AddComPlusPartitionUsers" Overridable="yes">Ajustando partición COM+ por omisión para los usuarios</String>
44 + <String Id="AddComPlusPartitionUsersTemplate" Overridable="yes">Usuario: [1]</String>
45 + <String Id="RemoveComPlusPartitionUsers" Overridable="yes">Borrando partición COM+ por omisión para los usuarios</String>
46 + <String Id="RemoveComPlusPartitionUsersTemplate" Overridable="yes">Usuario: [1]</String>
47 + <String Id="CreateComPlusApplications" Overridable="yes">Creando aplicación COM+</String>
48 + <String Id="CreateComPlusApplicationsTemplate" Overridable="yes">Aplicación: [1]</String>
49 + <String Id="RemoveComPlusApplications" Overridable="yes">Borrando aplicación COM+</String>
50 + <String Id="RemoveComPlusApplicationsTemplate" Overridable="yes">Aplicación: [1]</String>
51 + <String Id="CreateComPlusApplicationRoles" Overridable="yes">Creando roles de aplicación COM+</String>
52 + <String Id="CreateComPlusApplicationRolesTemplate" Overridable="yes">Rol: [1]</String>
53 + <String Id="RemoveComPlusApplicationRoles" Overridable="yes">Borrando roles de aplicación COM+</String>
54 + <String Id="RemoveComPlusApplicationRolesTemplate" Overridable="yes">Rol: [1]</String>
55 + <String Id="AddUsersToComPlusApplicationRoles" Overridable="yes">Agregando usuarios a los roles de aplicación COM+</String>
56 + <String Id="AddUsersToComPlusApplicationRolesTemplate" Overridable="yes">Usuario: [1]</String>
57 + <String Id="RemoveUsersFromComPlusApplicationRoles" Overridable="yes">Borrando usuarios a los roles de aplicación COM</String>
58 + <String Id="RemoveUsersFromComPlusApplicationRolesTemplate" Overridable="yes">Usuario: [1]</String>
59 + <String Id="RegisterComPlusAssemblies" Overridable="yes">Registrando componente COM+</String>
60 + <String Id="RegisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
61 + <String Id="UnregisterComPlusAssemblies" Overridable="yes">Anulando el registro de componentes COM+</String>
62 + <String Id="UnregisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
63 + <String Id="AddComPlusRoleAssignments" Overridable="yes">Asignando roles a los componentes COM+</String>
64 + <String Id="AddComPlusRoleAssignmentsTemplate" Overridable="yes">Componente: [1]</String>
65 + <String Id="RemoveComPlusRoleAssignments" Overridable="yes">Borrando asignación de roles a los componentes COM+</String>
66 + <String Id="RemoveComPlusRoleAssignmentsTemplate" Overridable="yes">Componente: [1]</String>
67 + <String Id="CreateSubscriptionsComPlusComponents" Overridable="yes">Creando suscripción a componentes COM+</String>
68 + <String Id="CreateSubscriptionsComPlusComponentsTemplate" Overridable="yes">Suscripción: [1]</String>
69 + <String Id="RemoveSubscriptionsComPlusComponents" Overridable="yes">Borrando suscripción a componentes COM+</String>
70 + <String Id="RemoveSubscriptionsComPlusComponentsTemplate" Overridable="yes">Suscripción: [1]</String>
71 +</WixLocalization>
72 +
src/wixlib/ja-jp.wxl new
+71
@@ -0,0 +1,71 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<!-- 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. -->
3 +
4 +
5 +<WixLocalization Culture="ja-jp" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 + <String Id="msierrComPlusCannotConnect" Overridable="yes">COM+ 管理カタログへ接続できません。 ([2] [3] [4] [5])</String>
7 + <String Id="msierrComPlusPartitionReadFailed" Overridable="yes">COM+ パーティションの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
8 + <String Id="msierrComPlusPartitionRoleReadFailed" Overridable="yes">COM+ パーティション役割の読み込みに失敗しました。 ([2] [3] [4] [5])</String>
9 + <String Id="msierrComPlusUserInPartitionRoleReadFailed" Overridable="yes">COM+ パーティション役割内ユーザーの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
10 + <String Id="msierrComPlusPartitionUserReadFailed" Overridable="yes">COM+ パーティション ユーザーの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
11 + <String Id="msierrComPlusApplicationReadFailed" Overridable="yes">COM+ アプリケーションの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
12 + <String Id="msierrComPlusApplicationRoleReadFailed" Overridable="yes">COM+ アプリケーション役割の読み込みに失敗しました。 ([2] [3] [4] [5])</String>
13 + <String Id="msierrComPlusUserInApplicationRoleReadFailed" Overridable="yes">COM+ アプリケーション役割内ユーザーの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
14 + <String Id="msierrComPlusAssembliesReadFailed" Overridable="yes">COM+ アセンブリの読み込みに失敗しました。 ([2] [3] [4] [5])</String>
15 + <String Id="msierrComPlusSubscriptionReadFailed" Overridable="yes">COM+ イベント登録の読み込みに失敗しました。 ([2] [3] [4] [5])</String>
16 + <String Id="msierrComPlusPartitionDependency" Overridable="yes">他のエンティティはインストールされない COM+ パーティションに依存します。 ([2] [3] [4] [5])</String>
17 + <String Id="msierrComPlusPartitionNotFound" Overridable="yes">COM+ パーティションは見つかりません ([2] [3] [4] [5])</String>
18 + <String Id="msierrComPlusPartitionIdConflict" Overridable="yes">同一 ID を持つ COM+ パーティションが既に存在します。 ([2] [3] [4] [5])</String>
19 + <String Id="msierrComPlusPartitionNameConflict" Overridable="yes">同一名称を持つ COM+ パーティションが既に存在します。 ([2] [3] [4] [5])</String>
20 + <String Id="msierrComPlusApplicationDependency" Overridable="yes">他のエンティティはインストールされない COM+ アプリケーションに依存します。 ([2] [3] [4] [5])</String>
21 + <String Id="msierrComPlusApplicationNotFound" Overridable="yes">COM+ アプリケーションは見つかりません。 ([2] [3] [4] [5])</String>
22 + <String Id="msierrComPlusApplicationIdConflict" Overridable="yes">同一 ID を持つ COM+ アプリケーションが既に存在します。 ([2] [3] [4] [5])</String>
23 + <String Id="msierrComPlusApplicationNameConflict" Overridable="yes">同一名称を持つ COM+ アプリケーションが既に存在します。 ([2] [3] [4] [5])</String>
24 + <String Id="msierrComPlusApplicationRoleDependency" Overridable="yes">他のエンティティはインストールされない COM+ アプリケーション役割に依存します。 ([2] [3] [4] [5])</String>
25 + <String Id="msierrComPlusApplicationRoleNotFound" Overridable="yes">COM+ アプリケーション役割は見つかりません。 ([2] [3] [4] [5])</String>
26 + <String Id="msierrComPlusApplicationRoleConflict" Overridable="yes">同一名称を持つ COM+ アプリケーション役割が既に存在します。 ([2] [3] [4] [5])</String>
27 + <String Id="msierrComPlusAssemblyDependency" Overridable="yes">他のエンティティはインストールされない COM+ アセンブリに依存します。 ([2] [3] [4] [5])</String>
28 + <String Id="msierrComPlusSubscriptionIdConflict" Overridable="yes">同一 ID を持つ COM+ コンポーネントのイベント登録が既に存在します。 ([2] [3] [4] [5])</String>
29 + <String Id="msierrComPlusSubscriptionNameConflict" Overridable="yes">同一名称を持つ COM+ コンポーネントのイベント登録が既に存在します。 ([2] [3] [4] [5])</String>
30 + <String Id="msierrComPlusFailedLookupNames" Overridable="yes">ユーザー アカウント名の照合に失敗しました。 ([2] [3] [4] [5])</String>
31 +
32 + <String Id="ComPlusInstallExecute" Overridable="yes">COM+ コンポーネントを登録しています</String>
33 + <String Id="ComPlusUninstallExecute" Overridable="yes">COM+ コンポーネント登録を解除しています</String>
34 +
35 + <String Id="CreateComPlusPartitions" Overridable="yes">COM+ パーティションを作成しています</String>
36 + <String Id="CreateComPlusPartitionsTemplate" Overridable="yes">パーティション: [1]</String>
37 + <String Id="RemoveComPlusPartitions" Overridable="yes">COM+ パーティションを削除しています</String>
38 + <String Id="RemoveComPlusPartitionsTemplate" Overridable="yes">パーティション: [1]</String>
39 + <String Id="AddUsersToComPlusPartitionRoles" Overridable="yes">ユーザーを COM+ パーティション役割に追加しています</String>
40 + <String Id="AddUsersToComPlusPartitionRolesTemplate" Overridable="yes">役割: [1]</String>
41 + <String Id="RemoveUsersFromComPlusPartitionRoles" Overridable="yes">ユーザを COM+ パーティション役割より削除しています</String>
42 + <String Id="RemoveUsersFromComPlusPartitionRolesTemplate" Overridable="yes">役割: [1]</String>
43 + <String Id="AddComPlusPartitionUsers" Overridable="yes">ユーザーのデフォルト COM+ 役割を設定しています</String>
44 + <String Id="AddComPlusPartitionUsersTemplate" Overridable="yes">ユーザー: [1]</String>
45 + <String Id="RemoveComPlusPartitionUsers" Overridable="yes">ユーザーのデフォルト COM+ パーティション役割を削除しています</String>
46 + <String Id="RemoveComPlusPartitionUsersTemplate" Overridable="yes">ユーザー: [1]</String>
47 + <String Id="CreateComPlusApplications" Overridable="yes">COM+ アプリケーションを作成しています</String>
48 + <String Id="CreateComPlusApplicationsTemplate" Overridable="yes">アプリケーション: [1]</String>
49 + <String Id="RemoveComPlusApplications" Overridable="yes">COM+ アプリケーションを削除しています</String>
50 + <String Id="RemoveComPlusApplicationsTemplate" Overridable="yes">アプリケーション: [1]</String>
51 + <String Id="CreateComPlusApplicationRoles" Overridable="yes">COM+ アプリケーション役割を作成しています</String>
52 + <String Id="CreateComPlusApplicationRolesTemplate" Overridable="yes">役割: [1]</String>
53 + <String Id="RemoveComPlusApplicationRoles" Overridable="yes">COM+ アプリケーション役割を削除しています</String>
54 + <String Id="RemoveComPlusApplicationRolesTemplate" Overridable="yes">役割: [1]</String>
55 + <String Id="AddUsersToComPlusApplicationRoles" Overridable="yes">ユーザーを COM+ アプリケーション役割に追加しています</String>
56 + <String Id="AddUsersToComPlusApplicationRolesTemplate" Overridable="yes">ユーザー: [1]</String>
57 + <String Id="RemoveUsersFromComPlusApplicationRoles" Overridable="yes">ユーザーを COM+ アプリケーション役割より削除しています</String>
58 + <String Id="RemoveUsersFromComPlusApplicationRolesTemplate" Overridable="yes">ユーザー: [1]</String>
59 + <String Id="RegisterComPlusAssemblies" Overridable="yes">COM+ コンポーネントを登録しています</String>
60 + <String Id="RegisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
61 + <String Id="UnregisterComPlusAssemblies" Overridable="yes">COM+ コンポーネント登録を解除しています</String>
62 + <String Id="UnregisterComPlusAssembliesTemplate" Overridable="yes">DLL: [1]</String>
63 + <String Id="AddComPlusRoleAssignments" Overridable="yes">COM+ コンポーネントへ役割を割り当てています</String>
64 + <String Id="AddComPlusRoleAssignmentsTemplate" Overridable="yes">コンポーネント: [1]</String>
65 + <String Id="RemoveComPlusRoleAssignments" Overridable="yes">COM+ コンポーネントより役割割当を削除しています</String>
66 + <String Id="RemoveComPlusRoleAssignmentsTemplate" Overridable="yes">コンポーネント: [1]</String>
67 + <String Id="CreateSubscriptionsComPlusComponents" Overridable="yes">COM+ コンポーネント用登録を作成しています</String>
68 + <String Id="CreateSubscriptionsComPlusComponentsTemplate" Overridable="yes">登録: [1]</String>
69 + <String Id="RemoveSubscriptionsComPlusComponents" Overridable="yes">COM+ コンポーネント用登録を削除しています</String>
70 + <String Id="RemoveSubscriptionsComPlusComponentsTemplate" Overridable="yes">登録: [1]</String>
71 +</WixLocalization>