aboutsummaryrefslogtreecommitdiff
path: root/src/ext/ComPlus/ca/cpappexec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/ComPlus/ca/cpappexec.cpp')
-rw-r--r--src/ext/ComPlus/ca/cpappexec.cpp344
1 files changed, 344 insertions, 0 deletions
diff --git a/src/ext/ComPlus/ca/cpappexec.cpp b/src/ext/ComPlus/ca/cpappexec.cpp
new file mode 100644
index 00000000..48948210
--- /dev/null
+++ b/src/ext/ComPlus/ca/cpappexec.cpp
@@ -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
8struct 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
22static HRESULT ReadApplicationAttributes(
23 LPWSTR* ppwzData,
24 CPI_APPLICATION_ATTRIBUTES* pAttrs
25 );
26static void FreeApplicationAttributes(
27 CPI_APPLICATION_ATTRIBUTES* pAttrs
28 );
29static HRESULT CreateApplication(
30 CPI_APPLICATION_ATTRIBUTES* pAttrs
31 );
32static HRESULT RemoveApplication(
33 CPI_APPLICATION_ATTRIBUTES* pAttrs
34 );
35
36
37// function definitions
38
39HRESULT 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
103LExit:
104 // clean up
105 FreeApplicationAttributes(&attrs);
106
107 return hr;
108}
109
110HRESULT 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
176LExit:
177 // clean up
178 FreeApplicationAttributes(&attrs);
179
180 return hr;
181}
182
183
184// helper function definitions
185
186static 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
210LExit:
211 return hr;
212}
213
214static 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
227static 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 = CpiExecGetApplicationsCollection(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
285LExit:
286 // clean up
287 ReleaseObject(piAppColl);
288 ReleaseObject(piAppObj);
289
290 return hr;
291}
292
293static 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 = CpiExecGetApplicationsCollection(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
339LExit:
340 // clean up
341 ReleaseObject(piAppColl);
342
343 return hr;
344}