@joebigelow / wix / commits / 4d30ab70

Import code from old v4 repo

Sean Hall committed Jan 20, 2019 at 09:19 UTC 4d30ab70573f9734d7fd3cd4d54c02173fa281db
20 files changed +1512
src/ca/cost.h new
+5
@@ -0,0 +1,5 @@
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 +const UINT COST_HTTP_URL_ACL = 2000;
src/ca/dllmain.cpp new
+26
@@ -0,0 +1,26 @@
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 hInstance,
11 + IN ULONG ulReason,
12 + IN LPVOID)
13 +{
14 + switch(ulReason)
15 + {
16 + case DLL_PROCESS_ATTACH:
17 + WcaGlobalInitialize(hInstance);
18 + break;
19 +
20 + case DLL_PROCESS_DETACH:
21 + WcaGlobalFinalize();
22 + break;
23 + }
24 +
25 + return TRUE;
26 +}
src/ca/precomp.h new
+17
@@ -0,0 +1,17 @@
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 +#include <http.h>
6 +#include <msiquery.h>
7 +#include <strsafe.h>
8 +
9 +#include "wcautil.h"
10 +#include "cryputil.h"
11 +#include "dutil.h"
12 +#include "memutil.h"
13 +#include "strutil.h"
14 +#include "aclutil.h"
15 +
16 +#include "CustomMsiErrors.h"
17 +#include "cost.h"
src/ca/wixhttpca.cpp new
+525
@@ -0,0 +1,525 @@
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 +static HRESULT AppendUrlAce(
6 + __in LPWSTR wzSecurityPrincipal,
7 + __in int iRights,
8 + __in LPWSTR* psczSDDL
9 + );
10 +static HRESULT WriteHttpUrlReservation(
11 + __in WCA_TODO action,
12 + __in LPWSTR wzUrl,
13 + __in LPWSTR wzSDDL,
14 + __in int iHandleExisting,
15 + __in LPWSTR* psczCustomActionData
16 + );
17 +static HRESULT AddUrlReservation(
18 + __in LPWSTR wzUrl,
19 + __in LPWSTR wzSddl
20 + );
21 +static HRESULT GetUrlReservation(
22 + __in LPWSTR wzUrl,
23 + __deref_out_z LPWSTR* psczSddl
24 + );
25 +static HRESULT RemoveUrlReservation(
26 + __in LPWSTR wzUrl
27 + );
28 +
29 +HTTPAPI_VERSION vcHttpVersion = HTTPAPI_VERSION_1;
30 +ULONG vcHttpFlags = HTTP_INITIALIZE_CONFIG;
31 +
32 +LPCWSTR vcsHttpUrlReservationQuery =
33 + L"SELECT `WixHttpUrlReservation`.`WixHttpUrlReservation`, `WixHttpUrlReservation`.`HandleExisting`, `WixHttpUrlReservation`.`Sddl`, `WixHttpUrlReservation`.`Url`, `WixHttpUrlReservation`.`Component_` "
34 + L"FROM `WixHttpUrlReservation`";
35 +enum eHttpUrlReservationQuery { hurqId = 1, hurqHandleExisting, hurqSDDL, hurqUrl, hurqComponent };
36 +
37 +LPCWSTR vcsHttpUrlAceQuery =
38 + L"SELECT `WixHttpUrlAce`.`SecurityPrincipal`, `WixHttpUrlAce`.`Rights` "
39 + L"FROM `WixHttpUrlAce` "
40 + L"WHERE `WixHttpUrlAce`.`WixHttpUrlReservation_`=?";
41 +enum eHttpUrlAceQuery { huaqSecurityPrincipal = 1, huaqRights };
42 +
43 +enum eHandleExisting { heReplace = 0, heIgnore = 1, heFail = 2 };
44 +
45 +/******************************************************************
46 + SchedHttpUrlReservations - immediate custom action worker to
47 + prepare configuring URL reservations.
48 +
49 +********************************************************************/
50 +static UINT SchedHttpUrlReservations(
51 + __in MSIHANDLE hInstall,
52 + __in WCA_TODO todoSched
53 + )
54 +{
55 + HRESULT hr = S_OK;
56 + UINT er = ERROR_SUCCESS;
57 + BOOL fAceTableExists = FALSE;
58 + BOOL fHttpInitialized = FALSE;
59 + DWORD cUrlReservations = 0;
60 +
61 + PMSIHANDLE hView = NULL;
62 + PMSIHANDLE hRec = NULL;
63 + PMSIHANDLE hQueryReq = NULL;
64 + PMSIHANDLE hAceView = NULL;
65 +
66 + LPWSTR sczCustomActionData = NULL;
67 + LPWSTR sczRollbackCustomActionData = NULL;
68 +
69 + LPWSTR sczId = NULL;
70 + LPWSTR sczComponent = NULL;
71 + WCA_TODO todoComponent = WCA_TODO_UNKNOWN;
72 + LPWSTR sczUrl = NULL;
73 + LPWSTR sczSecurityPrincipal = NULL;
74 + int iRights = 0;
75 + int iHandleExisting = 0;
76 +
77 + LPWSTR sczExistingSDDL = NULL;
78 + LPWSTR sczSDDL = NULL;
79 +
80 + // Initialize.
81 + hr = WcaInitialize(hInstall, "SchedHttpUrlReservations");
82 + ExitOnFailure(hr, "Failed to initialize.");
83 +
84 + // Anything to do?
85 + hr = WcaTableExists(L"WixHttpUrlReservation");
86 + ExitOnFailure(hr, "Failed to check if the WixHttpUrlReservation table exists.");
87 + if (S_FALSE == hr)
88 + {
89 + WcaLog(LOGMSG_STANDARD, "WixHttpUrlReservation table doesn't exist, so there are no URL reservations to configure.");
90 + ExitFunction();
91 + }
92 +
93 + hr = WcaTableExists(L"WixHttpUrlAce");
94 + ExitOnFailure(hr, "Failed to check if the WixHttpUrlAce table exists.");
95 + fAceTableExists = S_OK == hr;
96 +
97 + // Query and loop through all the URL reservations.
98 + hr = WcaOpenExecuteView(vcsHttpUrlReservationQuery, &hView);
99 + ExitOnFailure(hr, "Failed to open view on the WixHttpUrlReservation table.");
100 +
101 + hr = HRESULT_FROM_WIN32(::HttpInitialize(vcHttpVersion, vcHttpFlags, NULL));
102 + ExitOnFailure(hr, "Failed to initialize HTTP Server configuration.");
103 +
104 + fHttpInitialized = TRUE;
105 +
106 + while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
107 + {
108 + hr = WcaGetRecordString(hRec, hurqId, &sczId);
109 + ExitOnFailure(hr, "Failed to get WixHttpUrlReservation.WixHttpUrlReservation");
110 +
111 + hr = WcaGetRecordString(hRec, hurqComponent, &sczComponent);
112 + ExitOnFailure(hr, "Failed to get WixHttpUrlReservation.Component_");
113 +
114 + // Figure out what we're doing for this reservation, treating reinstall the same as install.
115 + todoComponent = WcaGetComponentToDo(sczComponent);
116 + if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched)
117 + {
118 + WcaLog(LOGMSG_STANDARD, "Component '%ls' action state (%d) doesn't match request (%d) for UrlReservation '%ls'.", sczComponent, todoComponent, todoSched, sczId);
119 + continue;
120 + }
121 +
122 + hr = WcaGetRecordFormattedString(hRec, hurqUrl, &sczUrl);
123 + ExitOnFailure(hr, "Failed to get WixHttpUrlReservation.Url");
124 +
125 + hr = WcaGetRecordInteger(hRec, hurqHandleExisting, &iHandleExisting);
126 + ExitOnFailure(hr, "Failed to get WixHttpUrlReservation.HandleExisting");
127 +
128 + if (::MsiRecordIsNull(hRec, hurqSDDL))
129 + {
130 + hr = StrAllocString(&sczSDDL, L"D:", 2);
131 + ExitOnFailure(hr, "Failed to allocate SDDL string.");
132 +
133 + // Skip creating the SDDL on uninstall, since it's never used and the lookup(s) could fail.
134 + if (fAceTableExists && WCA_TODO_UNINSTALL != todoComponent)
135 + {
136 + hQueryReq = ::MsiCreateRecord(1);
137 + hr = WcaSetRecordString(hQueryReq, 1, sczId);
138 + ExitOnFailure(hr, "Failed to create record for querying WixHttpUrlAce table for reservation %ls", sczId);
139 +
140 + hr = WcaOpenView(vcsHttpUrlAceQuery, &hAceView);
141 + ExitOnFailure(hr, "Failed to open view on WixHttpUrlAce table for reservation %ls", sczId);
142 + hr = WcaExecuteView(hAceView, hQueryReq);
143 + ExitOnFailure(hr, "Failed to execute view on WixHttpUrlAce table for reservation %ls", sczId);
144 +
145 + while (S_OK == (hr = WcaFetchRecord(hAceView, &hRec)))
146 + {
147 + hr = WcaGetRecordFormattedString(hRec, huaqSecurityPrincipal, &sczSecurityPrincipal);
148 + ExitOnFailure(hr, "Failed to get WixHttpUrlAce.SecurityPrincipal");
149 +
150 + hr = WcaGetRecordInteger(hRec, huaqRights, &iRights);
151 + ExitOnFailure(hr, "Failed to get WixHttpUrlAce.Rights");
152 +
153 + hr = AppendUrlAce(sczSecurityPrincipal, iRights, &sczSDDL);
154 + ExitOnFailure(hr, "Failed to append URL ACE.");
155 + }
156 +
157 + if (E_NOMOREITEMS == hr)
158 + {
159 + hr = S_OK;
160 + }
161 + ExitOnFailure(hr, "Failed to enumerate selected rows from WixHttpUrlAce table.");
162 + }
163 + }
164 + else
165 + {
166 + hr = WcaGetRecordFormattedString(hRec, hurqSDDL, &sczSDDL);
167 + ExitOnFailure(hr, "Failed to get WixHttpUrlReservation.SDDL");
168 + }
169 +
170 + hr = GetUrlReservation(sczUrl, &sczExistingSDDL);
171 + ExitOnFailure(hr, "Failed to get the existing SDDL for %ls", sczUrl);
172 +
173 + hr = WriteHttpUrlReservation(todoComponent, sczUrl, sczExistingSDDL ? sczExistingSDDL : L"", iHandleExisting, &sczRollbackCustomActionData);
174 + ExitOnFailure(hr, "Failed to write URL Reservation to rollback custom action data.");
175 +
176 + hr = WriteHttpUrlReservation(todoComponent, sczUrl, sczSDDL, iHandleExisting, &sczCustomActionData);
177 + ExitOnFailure(hr, "Failed to write URL reservation to custom action data.");
178 + ++cUrlReservations;
179 + }
180 +
181 + // Reaching the end of the list is not an error.
182 + if (E_NOMOREITEMS == hr)
183 + {
184 + hr = S_OK;
185 + }
186 + ExitOnFailure(hr, "Failure occurred while processing WixHttpUrlReservation table.");
187 +
188 + // Schedule ExecHttpUrlReservations if there's anything to do.
189 + if (cUrlReservations)
190 + {
191 + WcaLog(LOGMSG_STANDARD, "Scheduling URL reservations (%ls)", sczCustomActionData);
192 + WcaLog(LOGMSG_STANDARD, "Scheduling rollback URL reservations (%ls)", sczRollbackCustomActionData);
193 +
194 + if (WCA_TODO_INSTALL == todoSched)
195 + {
196 + hr = WcaDoDeferredAction(L"WixRollbackHttpUrlReservationsInstall", sczRollbackCustomActionData, cUrlReservations * COST_HTTP_URL_ACL);
197 + ExitOnFailure(hr, "Failed to schedule install URL reservations rollback.");
198 + hr = WcaDoDeferredAction(L"WixExecHttpUrlReservationsInstall", sczCustomActionData, cUrlReservations * COST_HTTP_URL_ACL);
199 + ExitOnFailure(hr, "Failed to schedule install URL reservations execution.");
200 + }
201 + else
202 + {
203 + hr = WcaDoDeferredAction(L"WixRollbackHttpUrlReservationsUninstall", sczRollbackCustomActionData, cUrlReservations * COST_HTTP_URL_ACL);
204 + ExitOnFailure(hr, "Failed to schedule uninstall URL reservations rollback.");
205 + hr = WcaDoDeferredAction(L"WixExecHttpUrlReservationsUninstall", sczCustomActionData, cUrlReservations * COST_HTTP_URL_ACL);
206 + ExitOnFailure(hr, "Failed to schedule uninstall URL reservations execution.");
207 + }
208 + }
209 + else
210 + {
211 + WcaLog(LOGMSG_STANDARD, "No URL reservations scheduled.");
212 + }
213 +LExit:
214 + ReleaseStr(sczSDDL);
215 + ReleaseStr(sczExistingSDDL);
216 + ReleaseStr(sczSecurityPrincipal);
217 + ReleaseStr(sczUrl)
218 + ReleaseStr(sczComponent);
219 + ReleaseStr(sczId);
220 + ReleaseStr(sczRollbackCustomActionData);
221 + ReleaseStr(sczCustomActionData);
222 +
223 + if (fHttpInitialized)
224 + {
225 + ::HttpTerminate(vcHttpFlags, NULL);
226 + }
227 +
228 + return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er);
229 +}
230 +
231 +static HRESULT AppendUrlAce(
232 + __in LPWSTR wzSecurityPrincipal,
233 + __in int iRights,
234 + __in LPWSTR* psczSDDL
235 + )
236 +{
237 + HRESULT hr = S_OK;
238 + LPCWSTR wzSid = NULL;
239 + LPWSTR sczSid = NULL;
240 +
241 + Assert(wzSecurityPrincipal && *wzSecurityPrincipal);
242 + Assert(psczSDDL && *psczSDDL);
243 +
244 + // As documented in the xsd, if the first char is '*', then the rest of the string is a SID string, e.g. *S-1-5-18.
245 + if (L'*' == wzSecurityPrincipal[0])
246 + {
247 + wzSid = &wzSecurityPrincipal[1];
248 + }
249 + else
250 + {
251 + hr = AclGetAccountSidStringEx(NULL, wzSecurityPrincipal, &sczSid);
252 + ExitOnFailure(hr, "Failed to lookup the SID for account %ls", wzSecurityPrincipal);
253 +
254 + wzSid = sczSid;
255 + }
256 +
257 + hr = StrAllocFormatted(psczSDDL, L"%ls(A;;%#x;;;%ls)", *psczSDDL, iRights, wzSid);
258 +
259 +LExit:
260 + ReleaseStr(sczSid);
261 +
262 + return hr;
263 +}
264 +
265 +static HRESULT WriteHttpUrlReservation(
266 + __in WCA_TODO action,
267 + __in LPWSTR wzUrl,
268 + __in LPWSTR wzSDDL,
269 + __in int iHandleExisting,
270 + __in LPWSTR* psczCustomActionData
271 + )
272 +{
273 + HRESULT hr = S_OK;
274 +
275 + hr = WcaWriteIntegerToCaData(action, psczCustomActionData);
276 + ExitOnFailure(hr, "Failed to write action to custom action data.");
277 +
278 + hr = WcaWriteStringToCaData(wzUrl, psczCustomActionData);
279 + ExitOnFailure(hr, "Failed to write URL to custom action data.");
280 +
281 + hr = WcaWriteStringToCaData(wzSDDL, psczCustomActionData);
282 + ExitOnFailure(hr, "Failed to write SDDL to custom action data.");
283 +
284 + hr = WcaWriteIntegerToCaData(iHandleExisting, psczCustomActionData);
285 + ExitOnFailure(hr, "Failed to write HandleExisting to custom action data.")
286 +
287 +LExit:
288 + return hr;
289 +}
290 +
291 +/******************************************************************
292 + SchedHttpUrlReservationsInstall - immediate custom action entry
293 + point to prepare adding URL reservations.
294 +
295 +********************************************************************/
296 +extern "C" UINT __stdcall SchedHttpUrlReservationsInstall(
297 + __in MSIHANDLE hInstall
298 + )
299 +{
300 + return SchedHttpUrlReservations(hInstall, WCA_TODO_INSTALL);
301 +}
302 +
303 +/******************************************************************
304 + SchedHttpUrlReservationsUninstall - immediate custom action entry
305 + point to prepare removing URL reservations.
306 +
307 +********************************************************************/
308 +extern "C" UINT __stdcall SchedHttpUrlReservationsUninstall(
309 + __in MSIHANDLE hInstall
310 + )
311 +{
312 + return SchedHttpUrlReservations(hInstall, WCA_TODO_UNINSTALL);
313 +}
314 +
315 +/******************************************************************
316 + ExecHttpUrlReservations - deferred custom action entry point to
317 + register and remove URL reservations.
318 +
319 +********************************************************************/
320 +extern "C" UINT __stdcall ExecHttpUrlReservations(
321 + __in MSIHANDLE hInstall
322 + )
323 +{
324 + HRESULT hr = S_OK;
325 + BOOL fHttpInitialized = FALSE;
326 + LPWSTR sczCustomActionData = NULL;
327 + LPWSTR wz = NULL;
328 + int iTodo = WCA_TODO_UNKNOWN;
329 + LPWSTR sczUrl = NULL;
330 + LPWSTR sczSDDL = NULL;
331 + eHandleExisting handleExisting = heIgnore;
332 + BOOL fRollback = ::MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK);
333 + BOOL fRemove = FALSE;
334 + BOOL fAdd = FALSE;
335 + BOOL fFailOnExisting = FALSE;
336 +
337 + // Initialize.
338 + hr = WcaInitialize(hInstall, "ExecHttpUrlReservations");
339 + ExitOnFailure(hr, "Failed to initialize.");
340 +
341 + hr = HRESULT_FROM_WIN32(::HttpInitialize(vcHttpVersion, vcHttpFlags, NULL));
342 + ExitOnFailure(hr, "Failed to initialize HTTP Server configuration.");
343 +
344 + fHttpInitialized = TRUE;
345 +
346 + hr = WcaGetProperty(L"CustomActionData", &sczCustomActionData);
347 + ExitOnFailure(hr, "Failed to get CustomActionData.");
348 + WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", sczCustomActionData);
349 +
350 + wz = sczCustomActionData;
351 + while (wz && *wz)
352 + {
353 + // Extract the custom action data and if rolling back, swap INSTALL and UNINSTALL.
354 + hr = WcaReadIntegerFromCaData(&wz, &iTodo);
355 + ExitOnFailure(hr, "Failed to read todo from custom action data.");
356 +
357 + hr = WcaReadStringFromCaData(&wz, &sczUrl);
358 + ExitOnFailure(hr, "Failed to read Url from custom action data.");
359 +
360 + hr = WcaReadStringFromCaData(&wz, &sczSDDL);
361 + ExitOnFailure(hr, "Failed to read SDDL from custom action data.");
362 +
363 + hr = WcaReadIntegerFromCaData(&wz, reinterpret_cast<int*>(&handleExisting));
364 + ExitOnFailure(hr, "Failed to read HandleExisting from custom action data.");
365 +
366 + switch (iTodo)
367 + {
368 + case WCA_TODO_INSTALL:
369 + case WCA_TODO_REINSTALL:
370 + fRemove = heReplace == handleExisting || fRollback;
371 + fAdd = !fRollback || *sczSDDL;
372 + fFailOnExisting = heFail == handleExisting && !fRollback;
373 + break;
374 +
375 + case WCA_TODO_UNINSTALL:
376 + fRemove = !fRollback;
377 + fAdd = fRollback && *sczSDDL;
378 + fFailOnExisting = FALSE;
379 + break;
380 + }
381 +
382 + if (fRemove)
383 + {
384 + WcaLog(LOGMSG_STANDARD, "Removing reservation for URL '%ls'", sczUrl);
385 + hr = RemoveUrlReservation(sczUrl);
386 + if (FAILED(hr))
387 + {
388 + if (fRollback)
389 + {
390 + WcaLogError(hr, "Failed to remove reservation for URL '%ls'", sczUrl);
391 + }
392 + else
393 + {
394 + ExitOnFailure(hr, "Failed to remove reservation for URL '%ls'", sczUrl);
395 + }
396 + }
397 + }
398 + if (fAdd)
399 + {
400 + WcaLog(LOGMSG_STANDARD, "Adding reservation for URL '%ls' with SDDL '%ls'", sczUrl, sczSDDL);
401 + hr = AddUrlReservation(sczUrl, sczSDDL);
402 + if (S_FALSE == hr && fFailOnExisting)
403 + {
404 + hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
405 + }
406 + if (FAILED(hr))
407 + {
408 + if (fRollback)
409 + {
410 + WcaLogError(hr, "Failed to add reservation for URL '%ls' with SDDL '%ls'", sczUrl, sczSDDL);
411 + }
412 + else
413 + {
414 + ExitOnFailure(hr, "Failed to add reservation for URL '%ls' with SDDL '%ls'", sczUrl, sczSDDL);
415 + }
416 + }
417 + }
418 + }
419 +
420 +LExit:
421 + ReleaseStr(sczSDDL);
422 + ReleaseStr(sczUrl);
423 + ReleaseStr(sczCustomActionData);
424 +
425 + if (fHttpInitialized)
426 + {
427 + ::HttpTerminate(vcHttpFlags, NULL);
428 + }
429 +
430 + return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS);
431 +}
432 +
433 +static HRESULT AddUrlReservation(
434 + __in LPWSTR wzUrl,
435 + __in LPWSTR wzSddl
436 + )
437 +{
438 + HRESULT hr = S_OK;
439 + DWORD er = ERROR_SUCCESS;
440 + HTTP_SERVICE_CONFIG_URLACL_SET set = { };
441 +
442 + set.KeyDesc.pUrlPrefix = wzUrl;
443 + set.ParamDesc.pStringSecurityDescriptor = wzSddl;
444 +
445 + er = ::HttpSetServiceConfiguration(NULL, HttpServiceConfigUrlAclInfo, &set, sizeof(set), NULL);
446 + if (ERROR_ALREADY_EXISTS == er)
447 + {
448 + hr = S_FALSE;
449 + }
450 + else
451 + {
452 + hr = HRESULT_FROM_WIN32(er);
453 + }
454 + ExitOnFailure(hr, "Failed to add URL reservation: %ls, ACL: %ls", wzUrl, wzSddl);
455 +
456 +LExit:
457 + return hr;
458 +}
459 +
460 +static HRESULT GetUrlReservation(
461 + __in LPWSTR wzUrl,
462 + __deref_out_z LPWSTR* psczSddl
463 + )
464 +{
465 + HRESULT hr = S_OK;
466 + DWORD er = ERROR_SUCCESS;
467 + HTTP_SERVICE_CONFIG_URLACL_QUERY query = { };
468 + HTTP_SERVICE_CONFIG_URLACL_SET* pSet = NULL;
469 + ULONG cbSet = 0;
470 +
471 + query.QueryDesc = HttpServiceConfigQueryExact;
472 + query.KeyDesc.pUrlPrefix = wzUrl;
473 +
474 + er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigUrlAclInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL);
475 + if (ERROR_INSUFFICIENT_BUFFER == er)
476 + {
477 + pSet = reinterpret_cast<HTTP_SERVICE_CONFIG_URLACL_SET*>(MemAlloc(cbSet, TRUE));
478 + ExitOnNull(pSet, hr, E_OUTOFMEMORY, "Failed to allocate query URLACL buffer.");
479 +
480 + er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigUrlAclInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL);
481 + }
482 +
483 + if (ERROR_SUCCESS == er)
484 + {
485 + hr = StrAllocString(psczSddl, pSet->ParamDesc.pStringSecurityDescriptor, 0);
486 + }
487 + else if (ERROR_FILE_NOT_FOUND == er)
488 + {
489 + hr = S_FALSE;
490 + }
491 + else
492 + {
493 + hr = HRESULT_FROM_WIN32(er);
494 + }
495 +
496 +LExit:
497 + ReleaseMem(pSet);
498 +
499 + return hr;
500 +}
501 +
502 +static HRESULT RemoveUrlReservation(
503 + __in LPWSTR wzUrl
504 + )
505 +{
506 + HRESULT hr = S_OK;
507 + DWORD er = ERROR_SUCCESS;
508 + HTTP_SERVICE_CONFIG_URLACL_SET set = { };
509 +
510 + set.KeyDesc.pUrlPrefix = wzUrl;
511 +
512 + er = ::HttpDeleteServiceConfiguration(NULL, HttpServiceConfigUrlAclInfo, &set, sizeof(set), NULL);
513 + if (ERROR_FILE_NOT_FOUND == er)
514 + {
515 + hr = S_FALSE;
516 + }
517 + else
518 + {
519 + hr = HRESULT_FROM_WIN32(er);
520 + }
521 + ExitOnFailure(hr, "Failed to remove URL reservation: %ls", wzUrl);
522 +
523 +LExit:
524 + return hr;
525 +}
src/ca/wixhttpca.def new
+9
@@ -0,0 +1,9 @@
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 +LIBRARY "wixhttpca"
5 +
6 +EXPORTS
7 + SchedHttpUrlReservationsInstall
8 + SchedHttpUrlReservationsUninstall
9 + ExecHttpUrlReservations
src/ca/wixhttpca.vcxproj new
+58
@@ -0,0 +1,58 @@
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" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
6 + <ItemGroup Label="ProjectConfigurations">
7 + <ProjectConfiguration Include="Debug|Win32">
8 + <Configuration>Debug</Configuration>
9 + <Platform>Win32</Platform>
10 + </ProjectConfiguration>
11 + <ProjectConfiguration Include="Release|Win32">
12 + <Configuration>Release</Configuration>
13 + <Platform>Win32</Platform>
14 + </ProjectConfiguration>
15 + </ItemGroup>
16 + <ItemGroup Label="ProjectConfigurations">
17 + <ProjectConfiguration Include="Debug|ARM">
18 + <Configuration>Debug</Configuration>
19 + <Platform>ARM</Platform>
20 + </ProjectConfiguration>
21 + <ProjectConfiguration Include="Release|ARM">
22 + <Configuration>Release</Configuration>
23 + <Platform>ARM</Platform>
24 + </ProjectConfiguration>
25 + </ItemGroup>
26 +
27 + <PropertyGroup Label="Globals">
28 + <ProjectGuid>{90743805-C043-47C7-B5FF-8F5EE5C8A2DE}</ProjectGuid>
29 + <ConfigurationType>DynamicLibrary</ConfigurationType>
30 + <CharacterSet>Unicode</CharacterSet>
31 + <TargetName>wixhttpca</TargetName>
32 + <ProjectModuleDefinitionFile>wixhttpca.def</ProjectModuleDefinitionFile>
33 + </PropertyGroup>
34 +
35 + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), wix.proj))\tools\WixBuild.props" />
36 +
37 + <PropertyGroup>
38 + <ProjectAdditionalIncludeDirectories>$(WixRoot)src\libs\dutil\inc;$(WixRoot)src\libs\wcautil</ProjectAdditionalIncludeDirectories>
39 + <ProjectAdditionalLinkLibraries>crypt32.lib;httpapi.lib;msi.lib;dutil.lib;wcautil.lib</ProjectAdditionalLinkLibraries>
40 + </PropertyGroup>
41 +
42 + <ItemGroup>
43 + <ClCompile Include="dllmain.cpp" />
44 + <ClCompile Include="wixhttpca.cpp" />
45 + </ItemGroup>
46 + <ItemGroup>
47 + <ClInclude Include="cost.h" />
48 + <ClInclude Include="precomp.h" />
49 + </ItemGroup>
50 + <ItemGroup>
51 + <None Include="wixhttpca.def" />
52 + </ItemGroup>
53 + <ItemGroup>
54 + <ResourceCompile Include="wixhttpca.rc" />
55 + </ItemGroup>
56 +
57 + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), wix.proj))\tools\WixBuild.targets" />
58 +</Project>
src/ca/wixhttpca.vcxproj.filters new
+40
@@ -0,0 +1,40 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 + <ItemGroup>
4 + <Filter Include="Source Files">
5 + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
6 + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
7 + </Filter>
8 + <Filter Include="Header Files">
9 + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
10 + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
11 + </Filter>
12 + <Filter Include="Resource Files">
13 + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
14 + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
15 + </Filter>
16 + </ItemGroup>
17 + <ItemGroup>
18 + <ClCompile Include="wixhttpca.cpp">
19 + <Filter>Source Files</Filter>
20 + </ClCompile>
21 + <ClCompile Include="dllmain.cpp">
22 + <Filter>Source Files</Filter>
23 + </ClCompile>
24 + </ItemGroup>
25 + <ItemGroup>
26 + <ClInclude Include="precomp.h">
27 + <Filter>Header Files</Filter>
28 + </ClInclude>
29 + </ItemGroup>
30 + <ItemGroup>
31 + <ResourceCompile Include="wixhttpca.rc">
32 + <Filter>Resource Files</Filter>
33 + </ResourceCompile>
34 + </ItemGroup>
35 + <ItemGroup>
36 + <None Include="wixhttpca.def">
37 + <Filter>Source Files</Filter>
38 + </None>
39 + </ItemGroup>
40 +</Project>
\ No newline at end of file
src/wixext/HttpCompiler.cs new
+280
@@ -0,0 +1,280 @@
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.Generic;
7 + using System.Globalization;
8 + using System.Xml.Linq;
9 + using WixToolset.Data;
10 + using WixToolset.Extensibility;
11 +
12 + /// <summary>
13 + /// The compiler for the WiX Toolset Http Extension.
14 + /// </summary>
15 + public sealed class HttpCompiler : CompilerExtension
16 + {
17 + /// <summary>
18 + /// Instantiate a new HttpCompiler.
19 + /// </summary>
20 + public HttpCompiler()
21 + {
22 + this.Namespace = "http://wixtoolset.org/schemas/v4/wxs/http";
23 + }
24 +
25 + /// <summary>
26 + /// Processes an element for the Compiler.
27 + /// </summary>
28 + /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
29 + /// <param name="parentElement">Parent element of element to process.</param>
30 + /// <param name="element">Element to process.</param>
31 + /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
32 + public override void ParseElement(XElement parentElement, XElement element, IDictionary<string, string> context)
33 + {
34 + switch (parentElement.Name.LocalName)
35 + {
36 + case "ServiceInstall":
37 + string serviceInstallName = context["ServiceInstallName"];
38 + string serviceUser = String.IsNullOrEmpty(serviceInstallName) ? null : String.Concat("NT SERVICE\\", serviceInstallName);
39 + string serviceComponentId = context["ServiceInstallComponentId"];
40 +
41 + switch (element.Name.LocalName)
42 + {
43 + case "UrlReservation":
44 + this.ParseUrlReservationElement(element, serviceComponentId, serviceUser);
45 + break;
46 + default:
47 + this.Core.UnexpectedElement(parentElement, element);
48 + break;
49 + }
50 + break;
51 + case "Component":
52 + string componentId = context["ComponentId"];
53 +
54 + switch (element.Name.LocalName)
55 + {
56 + case "UrlReservation":
57 + this.ParseUrlReservationElement(element, componentId, null);
58 + break;
59 + default:
60 + this.Core.UnexpectedElement(parentElement, element);
61 + break;
62 + }
63 + break;
64 + default:
65 + this.Core.UnexpectedElement(parentElement, element);
66 + break;
67 + }
68 + }
69 +
70 + /// <summary>
71 + /// Parses a UrlReservation element.
72 + /// </summary>
73 + /// <param name="node">The element to parse.</param>
74 + /// <param name="componentId">Identifier of the component that owns this URL reservation.</param>
75 + /// <param name="securityPrincipal">The security principal of the parent element (null if nested under Component).</param>
76 + private void ParseUrlReservationElement(XElement node, string componentId, string securityPrincipal)
77 + {
78 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
79 + Identifier id = null;
80 + int handleExisting = HttpConstants.heReplace;
81 + string handleExistingValue = null;
82 + string sddl = null;
83 + string url = null;
84 + bool foundACE = false;
85 +
86 + foreach (XAttribute attrib in node.Attributes())
87 + {
88 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
89 + {
90 + switch (attrib.Name.LocalName)
91 + {
92 + case "Id":
93 + id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
94 + break;
95 + case "HandleExisting":
96 + handleExistingValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
97 + switch (handleExistingValue)
98 + {
99 + case "replace":
100 + handleExisting = HttpConstants.heReplace;
101 + break;
102 + case "ignore":
103 + handleExisting = HttpConstants.heIgnore;
104 + break;
105 + case "fail":
106 + handleExisting = HttpConstants.heFail;
107 + break;
108 + default:
109 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "HandleExisting", handleExistingValue, "replace", "ignore", "fail"));
110 + break;
111 + }
112 + break;
113 + case "Sddl":
114 + sddl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
115 + break;
116 + case "Url":
117 + url = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
118 + break;
119 + default:
120 + this.Core.UnexpectedAttribute(node, attrib);
121 + break;
122 + }
123 + }
124 + else
125 + {
126 + this.Core.ParseExtensionAttribute(node, attrib);
127 + }
128 + }
129 +
130 + // Need the element ID for child element processing, so generate now if not authored.
131 + if (null == id)
132 + {
133 + id = this.Core.CreateIdentifier("url", componentId, securityPrincipal, url);
134 + }
135 +
136 + // Parse UrlAce children.
137 + foreach (XElement child in node.Elements())
138 + {
139 + if (this.Namespace == child.Name.Namespace)
140 + {
141 + switch (child.Name.LocalName)
142 + {
143 + case "UrlAce":
144 + if (null != sddl)
145 + {
146 + this.Core.OnMessage(WixErrors.IllegalParentAttributeWhenNested(sourceLineNumbers, "UrlReservation", "Sddl", "UrlAce"));
147 + }
148 + else
149 + {
150 + foundACE = true;
151 + this.ParseUrlAceElement(child, id.Id, securityPrincipal);
152 + }
153 + break;
154 + default:
155 + this.Core.UnexpectedElement(node, child);
156 + break;
157 + }
158 + }
159 + else
160 + {
161 + this.Core.ParseExtensionElement(node, child);
162 + }
163 + }
164 +
165 + // Url is required.
166 + if (null == url)
167 + {
168 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Url"));
169 + }
170 +
171 + // Security is required.
172 + if (null == sddl && !foundACE)
173 + {
174 + this.Core.OnMessage(HttpErrors.NoSecuritySpecified(sourceLineNumbers));
175 + }
176 +
177 + if (!this.Core.EncounteredError)
178 + {
179 + Row row = this.Core.CreateRow(sourceLineNumbers, "WixHttpUrlReservation");
180 + row[0] = id.Id;
181 + row[1] = handleExisting;
182 + row[2] = sddl;
183 + row[3] = url;
184 + row[4] = componentId;
185 +
186 + if (this.Core.CurrentPlatform == Platform.ARM)
187 + {
188 + // Ensure ARM version of the CA is referenced.
189 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "WixSchedHttpUrlReservationsInstall_ARM");
190 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "WixSchedHttpUrlReservationsUninstall_ARM");
191 + }
192 + else
193 + {
194 + // All other supported platforms use x86.
195 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "WixSchedHttpUrlReservationsInstall");
196 + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "WixSchedHttpUrlReservationsUninstall");
197 + }
198 + }
199 + }
200 +
201 + /// <summary>
202 + /// Parses a UrlAce element.
203 + /// </summary>
204 + /// <param name="node">The element to parse.</param>
205 + /// <param name="urlReservationId">The URL reservation ID.</param>
206 + /// <param name="defaultSecurityPrincipal">The default security principal.</param>
207 + private void ParseUrlAceElement(XElement node, string urlReservationId, string defaultSecurityPrincipal)
208 + {
209 + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
210 + Identifier id = null;
211 + string securityPrincipal = defaultSecurityPrincipal;
212 + int rights = HttpConstants.GENERIC_ALL;
213 + string rightsValue = null;
214 +
215 + foreach (XAttribute attrib in node.Attributes())
216 + {
217 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
218 + {
219 + switch (attrib.Name.LocalName)
220 + {
221 + case "Id":
222 + id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
223 + break;
224 + case "SecurityPrincipal":
225 + securityPrincipal = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
226 + break;
227 + case "Rights":
228 + rightsValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
229 + switch (rightsValue)
230 + {
231 + case "all":
232 + rights = HttpConstants.GENERIC_ALL;
233 + break;
234 + case "delegate":
235 + rights = HttpConstants.GENERIC_WRITE;
236 + break;
237 + case "register":
238 + rights = HttpConstants.GENERIC_EXECUTE;
239 + break;
240 + default:
241 + this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Rights", rightsValue, "all", "delegate", "register"));
242 + break;
243 + }
244 + break;
245 + default:
246 + this.Core.UnexpectedAttribute(node, attrib);
247 + break;
248 + }
249 + }
250 + else
251 + {
252 + this.Core.ParseExtensionAttribute(node, attrib);
253 + }
254 + }
255 +
256 + // Generate Id now if not authored.
257 + if (null == id)
258 + {
259 + id = this.Core.CreateIdentifier("ace", urlReservationId, securityPrincipal, rightsValue);
260 + }
261 +
262 + this.Core.ParseForExtensionElements(node);
263 +
264 + // SecurityPrincipal is required.
265 + if (null == securityPrincipal)
266 + {
267 + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SecurityPrincipal"));
268 + }
269 +
270 + if (!this.Core.EncounteredError)
271 + {
272 + Row row = this.Core.CreateRow(sourceLineNumbers, "WixHttpUrlAce");
273 + row[0] = id.Id;
274 + row[1] = urlReservationId;
275 + row[2] = securityPrincipal;
276 + row[3] = rights;
277 + }
278 + }
279 + }
280 +}
src/wixext/HttpConstants.cs new
+19
@@ -0,0 +1,19 @@
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 +
7 + internal static class HttpConstants
8 + {
9 + // from winnt.h
10 + public const int GENERIC_ALL = 0x10000000;
11 + public const int GENERIC_EXECUTE = 0x20000000;
12 + public const int GENERIC_WRITE = 0x40000000;
13 +
14 + // from wixhttpca.cpp
15 + public const int heReplace = 0;
16 + public const int heIgnore = 1;
17 + public const int heFail = 2;
18 + }
19 +}
src/wixext/HttpDecompiler.cs new
+135
@@ -0,0 +1,135 @@
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.Diagnostics;
8 + using System.Globalization;
9 + using WixToolset.Data;
10 + using WixToolset.Extensibility;
11 + using Http = WixToolset.Extensions.Serialize.Http;
12 + using Wix = WixToolset.Data.Serialize;
13 +
14 + /// <summary>
15 + /// The decompiler for the WiX Toolset Http Extension.
16 + /// </summary>
17 + public sealed class HttpDecompiler : DecompilerExtension
18 + {
19 + /// <summary>
20 + /// Creates a decompiler for Http Extension.
21 + /// </summary>
22 + public HttpDecompiler()
23 + {
24 + this.TableDefinitions = HttpExtensionData.GetExtensionTableDefinitions();
25 + }
26 +
27 + /// <summary>
28 + /// Get the extensions library to be removed.
29 + /// </summary>
30 + /// <param name="tableDefinitions">Table definitions for library.</param>
31 + /// <returns>Library to remove from decompiled output.</returns>
32 + public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions)
33 + {
34 + return HttpExtensionData.GetExtensionLibrary(tableDefinitions);
35 + }
36 +
37 + /// <summary>
38 + /// Decompiles an extension table.
39 + /// </summary>
40 + /// <param name="table">The table to decompile.</param>
41 + public override void DecompileTable(Table table)
42 + {
43 + switch (table.Name)
44 + {
45 + case "WixHttpUrlReservation":
46 + this.DecompileWixHttpUrlReservationTable(table);
47 + break;
48 + case "WixHttpUrlAce":
49 + this.DecompileWixHttpUrlAceTable(table);
50 + break;
51 + default:
52 + base.DecompileTable(table);
53 + break;
54 + }
55 + }
56 +
57 + /// <summary>
58 + /// Decompile the WixHttpUrlReservation table.
59 + /// </summary>
60 + /// <param name="table">The table to decompile.</param>
61 + private void DecompileWixHttpUrlReservationTable(Table table)
62 + {
63 + foreach (Row row in table.Rows)
64 + {
65 + Http.UrlReservation urlReservation = new Http.UrlReservation();
66 + urlReservation.Id = (string)row[0];
67 + switch((int)row[1])
68 + {
69 + case HttpConstants.heReplace:
70 + default:
71 + urlReservation.HandleExisting = Http.UrlReservation.HandleExistingType.replace;
72 + break;
73 + case HttpConstants.heIgnore:
74 + urlReservation.HandleExisting = Http.UrlReservation.HandleExistingType.ignore;
75 + break;
76 + case HttpConstants.heFail:
77 + urlReservation.HandleExisting = Http.UrlReservation.HandleExistingType.fail;
78 + break;
79 + }
80 + urlReservation.Sddl = (string)row[2];
81 + urlReservation.Url = (string)row[3];
82 +
83 + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[4]);
84 + if (null != component)
85 + {
86 + component.AddChild(urlReservation);
87 + }
88 + else
89 + {
90 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
91 + }
92 + this.Core.IndexElement(row, urlReservation);
93 + }
94 + }
95 +
96 +
97 + /// <summary>
98 + /// Decompile the WixHttpUrlAce table.
99 + /// </summary>
100 + /// <param name="table">The table to decompile.</param>
101 + private void DecompileWixHttpUrlAceTable(Table table)
102 + {
103 + foreach (Row row in table.Rows)
104 + {
105 + Http.UrlAce urlace = new Http.UrlAce();
106 + urlace.Id = (string)row[0];
107 + urlace.SecurityPrincipal = (string)row[2];
108 + switch (Convert.ToInt32(row[3]))
109 + {
110 + case HttpConstants.GENERIC_ALL:
111 + default:
112 + urlace.Rights = Http.UrlAce.RightsType.all;
113 + break;
114 + case HttpConstants.GENERIC_EXECUTE:
115 + urlace.Rights = Http.UrlAce.RightsType.register;
116 + break;
117 + case HttpConstants.GENERIC_WRITE:
118 + urlace.Rights = Http.UrlAce.RightsType.@delegate;
119 + break;
120 + }
121 +
122 + string reservationId = (string)row[1];
123 + Http.UrlReservation urlReservation = (Http.UrlReservation)this.Core.GetIndexedElement("WixHttpUrlReservation", reservationId);
124 + if (null != urlReservation)
125 + {
126 + urlReservation.AddChild(urlace);
127 + }
128 + else
129 + {
130 + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, urlace.Id, "WixHttpUrlReservation_", reservationId, "WixHttpUrlReservation"));
131 + }
132 + }
133 + }
134 + }
135 +}
src/wixext/HttpExtensionData.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 Http Extension.
12 + /// </summary>
13 + public sealed class HttpExtensionData : 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 HttpExtensionData.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 HttpExtensionData.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.http.wixlib", tableDefinitions);
62 + }
63 + }
64 +}
src/wixext/WixHttpExtension.csproj new
+48
@@ -0,0 +1,48 @@
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>{AAFC3C7F-D818-4B1D-AF3F-A331EA917F3F}</ProjectGuid>
8 + <AssemblyName>WixHttpExtension</AssemblyName>
9 + <OutputType>Library</OutputType>
10 + <RootNamespace>WixToolset.Extensions</RootNamespace>
11 + </PropertyGroup>
12 + <ItemGroup>
13 + <Compile Include="AssemblyInfo.cs" />
14 + <Compile Include="HttpCompiler.cs" />
15 + <Compile Include="HttpConstants.cs" />
16 + <Compile Include="HttpDecompiler.cs" />
17 + <Compile Include="HttpExtensionData.cs" />
18 + <MsgGenSource Include="Data\messages.xml">
19 + <ResourcesLogicalName>$(RootNamespace).Data.Messages.resources</ResourcesLogicalName>
20 + </MsgGenSource>
21 + <EmbeddedFlattenedResource Include="Data\tables.xml">
22 + <LogicalName>$(RootNamespace).Data.tables.xml</LogicalName>
23 + </EmbeddedFlattenedResource>
24 + <EmbeddedFlattenedResource Include="Xsd\http.xsd">
25 + <LogicalName>$(RootNamespace).Xsd.http.xsd</LogicalName>
26 + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
27 + </EmbeddedFlattenedResource>
28 + <XsdGenSource Include="Xsd\http.xsd">
29 + <CommonNamespace>WixToolset.Data.Serialize</CommonNamespace>
30 + <Namespace>WixToolset.Extensions.Serialize.Http</Namespace>
31 + </XsdGenSource>
32 + <EmbeddedResource Include="$(OutputPath)\http.wixlib">
33 + <Link>Data\http.wixlib</Link>
34 + </EmbeddedResource>
35 + </ItemGroup>
36 + <ItemGroup>
37 + <Reference Include="System" />
38 + <Reference Include="System.Xml" />
39 + <Reference Include="System.Xml.Linq" />
40 + <ProjectReference Include="..\..\..\libs\WixToolset.Data\WixToolset.Data.csproj" />
41 + <ProjectReference Include="..\..\..\libs\WixToolset.Extensibility\WixToolset.Extensibility.csproj" />
42 + <ProjectReference Include="..\..\..\tools\wix\Wix.csproj" />
43 + <ProjectReference Include="..\wixlib\HttpExtension.wixproj">
44 + <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
45 + </ProjectReference>
46 + </ItemGroup>
47 + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), wix.proj))\tools\WixBuild.targets" />
48 +</Project>
src/wixext/http.xsd new
+148
@@ -0,0 +1,148 @@
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:xs="http://www.w3.org/2001/XMLSchema"
6 + xmlns:xse="http://wixtoolset.org/schemas/XmlSchemaExtension"
7 + xmlns:html="http://www.w3.org/1999/xhtml"
8 + targetNamespace="http://wixtoolset.org/schemas/v4/wxs/http"
9 + xmlns="http://wixtoolset.org/schemas/v4/wxs/http">
10 + <xs:annotation>
11 + <xs:documentation>
12 + The source code schema for the Windows Installer XML Toolset Http Extension.
13 + </xs:documentation>
14 + </xs:annotation>
15 +
16 + <xs:import namespace="http://wixtoolset.org/schemas/v4/wxs" />
17 +
18 + <xs:element name="UrlReservation">
19 + <xs:annotation>
20 + <xs:documentation>
21 + Makes a reservation record for the HTTP Server API configuration store on Windows XP SP2,
22 + Windows Server 2003, and later. For more information about the HTTP Server API, see
23 + <html:a href="http://msdn.microsoft.com/library/windows/desktop/aa364510.aspx">
24 + HTTP Server API
25 + </html:a>.
26 + </xs:documentation>
27 + <xs:appinfo>
28 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
29 + <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="ServiceInstall" />
30 + </xs:appinfo>
31 + </xs:annotation>
32 +
33 + <xs:complexType>
34 + <xs:choice minOccurs="0" maxOccurs="unbounded">
35 + <xs:annotation>
36 + <xs:documentation>
37 + The access control entries for the access control list.
38 + </xs:documentation>
39 + </xs:annotation>
40 + <xs:element ref="UrlAce" />
41 + </xs:choice>
42 +
43 + <xs:attribute name="HandleExisting">
44 + <xs:annotation>
45 + <xs:documentation>
46 + Specifies the behavior when trying to install a URL reservation and it already exists.
47 + </xs:documentation>
48 + </xs:annotation>
49 + <xs:simpleType>
50 + <xs:restriction base="xs:NMTOKEN">
51 + <xs:enumeration value="replace">
52 + <xs:annotation>
53 + <xs:documentation>
54 + Replaces the existing URL reservation (the default).
55 + </xs:documentation>
56 + </xs:annotation>
57 + </xs:enumeration>
58 + <xs:enumeration value="ignore">
59 + <xs:annotation>
60 + <xs:documentation>
61 + Keeps the existing URL reservation.
62 + </xs:documentation>
63 + </xs:annotation>
64 + </xs:enumeration>
65 + <xs:enumeration value="fail">
66 + <xs:annotation>
67 + <xs:documentation>
68 + The installation fails.
69 + </xs:documentation>
70 + </xs:annotation>
71 + </xs:enumeration>
72 + </xs:restriction>
73 + </xs:simpleType>
74 + </xs:attribute>
75 +
76 + <xs:attribute name="Id" type="xs:string">
77 + <xs:annotation>
78 + <xs:documentation>
79 + Unique ID of this URL reservation.
80 + If this attribute is not specified, an identifier will be generated automatically.
81 + </xs:documentation>
82 + </xs:annotation>
83 + </xs:attribute>
84 +
85 + <xs:attribute name="Sddl" type="xs:string">
86 + <xs:annotation>
87 + <xs:documentation>
88 + Security descriptor to apply to the URL reservation.
89 + Can't be specified when using children UrlAce elements.
90 + </xs:documentation>
91 + </xs:annotation>
92 + </xs:attribute>
93 +
94 + <xs:attribute name="Url" type="xs:string" use="required">
95 + <xs:annotation>
96 + <xs:documentation>
97 + The <html:a href="http://msdn.microsoft.com/library/windows/desktop/aa364698.aspx">UrlPrefix</html:a>
98 + string that defines the portion of the URL namespace to which this reservation pertains.
99 + </xs:documentation>
100 + </xs:annotation>
101 + </xs:attribute>
102 + </xs:complexType>
103 + </xs:element>
104 +
105 + <xs:element name="UrlAce">
106 + <xs:annotation>
107 + <xs:documentation>
108 + The security principal and which rights to assign to them for the URL reservation.
109 + </xs:documentation>
110 + </xs:annotation>
111 + <xs:complexType>
112 + <xs:attribute name="Id" type="xs:string">
113 + <xs:annotation>
114 + <xs:documentation>
115 + Unique ID of this URL ACE.
116 + If this attribute is not specified, an identifier will be generated automatically.
117 + </xs:documentation>
118 + </xs:annotation>
119 + </xs:attribute>
120 +
121 + <xs:attribute name="SecurityPrincipal" type="xs:string">
122 + <xs:annotation>
123 + <xs:documentation>
124 + The security principal for this ACE. When the UrlReservation is under a ServiceInstall element, this defaults to
125 + "NT SERVICE\ServiceInstallName". This may be either a SID or an account name in a format that
126 + <html:a href="http://msdn.microsoft.com/library/windows/desktop/aa379159.aspx">LookupAccountName</html:a>
127 + supports. When using a SID, an asterisk must be prepended. For example, "*S-1-5-18".
128 + </xs:documentation>
129 + </xs:annotation>
130 + </xs:attribute>
131 +
132 + <xs:attribute name="Rights">
133 + <xs:annotation>
134 + <xs:documentation>
135 + Rights for this ACE. Default is "all".
136 + </xs:documentation>
137 + </xs:annotation>
138 + <xs:simpleType>
139 + <xs:restriction base="xs:NMTOKEN">
140 + <xs:enumeration value="register" />
141 + <xs:enumeration value="delegate" />
142 + <xs:enumeration value="all" />
143 + </xs:restriction>
144 + </xs:simpleType>
145 + </xs:attribute>
146 + </xs:complexType>
147 + </xs:element>
148 +</xs:schema>
src/wixext/messages.xml new
+13
@@ -0,0 +1,13 @@
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="HttpErrors" ContainerName="HttpErrorEventArgs" BaseContainerName="MessageEventArgs" Level="Error">
7 + <Message Id="NoSecuritySpecified" Number="6701">
8 + <Instance>
9 + The UrlReservation element doesn't identify the security for the reservation. You must either specify the Sddl attribute, or provide child UrlAce elements.
10 + </Instance>
11 + </Message>
12 + </Class>
13 +</Messages>
src/wixext/tables.xml new
+28
@@ -0,0 +1,28 @@
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="WixHttpUrlReservation">
7 + <columnDefinition name="WixHttpUrlReservation" type="string" length="72" primaryKey="yes" modularize="column"
8 + category="identifier" description="The non-localized primary key for the table." />
9 + <columnDefinition name="HandleExisting" type="number" length="4" nullable="no"
10 + minValue="0" maxValue="2" description="The behavior when trying to install a URL reservation and it already exists." />
11 + <columnDefinition name="Sddl" type="string" length="0" modularize="property" nullable="yes"
12 + category="formatted" description="Security descriptor for the URL reservation." />
13 + <columnDefinition name="Url" type="string" length="0" modularize="property" nullable="no"
14 + category="formatted" description="URL to be reserved." />
15 + <columnDefinition name="Component_" type="string" length="72" modularize="column"
16 + keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into the Component table referencing the component that controls the URL reservation." />
17 + </tableDefinition>
18 + <tableDefinition name="WixHttpUrlAce">
19 + <columnDefinition name="WixHttpUrlAce" type="string" length="72" primaryKey="yes" modularize="column"
20 + category="identifier" description="The non-localized primary key for the table." />
21 + <columnDefinition name="WixHttpUrlReservation_" type="string" length="72" keyTable="WixHttpUrlReservation" keyColumn="1" modularize="column"
22 + category="identifier" description="Foreign key into the WixHttpUrlReservation table." />
23 + <columnDefinition name="SecurityPrincipal" type="string" length="0" modularize="property"
24 + category="formatted" description="The security principal for this ACE." />
25 + <columnDefinition name="Rights" type="number" length="4" nullable="no"
26 + minValue="0" maxValue="1073741824" description="The rights for this ACE." />
27 + </tableDefinition>
28 +</tableDefinitions>
src/wixlib/HttpExtension.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>{055C1517-4CED-4199-BCDE-A383E5C4EF78}</ProjectGuid>
8 + <OutputName>http</OutputName>
9 + <OutputType>Library</OutputType>
10 + <BindFiles>true</BindFiles>
11 + <Pedantic>true</Pedantic>
12 + <Cultures>en-us</Cultures>
13 + </PropertyGroup>
14 +
15 + <ItemGroup>
16 + <Compile Include="HttpExtension.wxs" />
17 + <Compile Include="HttpExtension_x86.wxs" />
18 + <EmbeddedResource Include="en-us.wxl" />
19 + </ItemGroup>
20 +
21 + <ItemGroup>
22 + <ProjectReference Include="..\ca\wixhttpca.vcxproj" />
23 + </ItemGroup>
24 +
25 + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), wix.proj))\tools\WixBuild.targets" />
26 +</Project>
src/wixlib/HttpExtension.wxs new
+11
@@ -0,0 +1,11 @@
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 + <Fragment>
8 + <UI Id="WixHttpErrors">
9 + </UI>
10 + </Fragment>
11 +</Wix>
src/wixlib/HttpExtension_Platform.wxi new
+40
@@ -0,0 +1,40 @@
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 +<Include xmlns="http://wixtoolset.org/schemas/v4/wxs">
6 + <?include caSuffix.wxi ?>
7 + <Fragment>
8 + <UIRef Id="WixHttpErrors" />
9 + <UI>
10 + <ProgressText Action="WixSchedHttpUrlReservationsInstall$(var.Suffix)">!(loc.WixSchedHttpUrlReservationsInstall)</ProgressText>
11 + <ProgressText Action="WixSchedHttpUrlReservationsUninstall$(var.Suffix)">!(loc.WixSchedHttpUrlReservationsUninstall)</ProgressText>
12 + <ProgressText Action="WixRollbackHttpUrlReservationsInstall$(var.DeferredSuffix)">!(loc.WixRollbackHttpUrlReservationsInstall)</ProgressText>
13 + <ProgressText Action="WixExecHttpUrlReservationsInstall$(var.DeferredSuffix)">!(loc.WixExecHttpUrlReservationsInstall)</ProgressText>
14 + <ProgressText Action="WixRollbackHttpUrlReservationsUninstall$(var.DeferredSuffix)">!(loc.WixRollbackHttpUrlReservationsUninstall)</ProgressText>
15 + <ProgressText Action="WixExecHttpUrlReservationsUninstall$(var.DeferredSuffix)">!(loc.WixExecHttpUrlReservationsUninstall)</ProgressText>
16 + </UI>
17 +
18 + <CustomAction Id="WixSchedHttpUrlReservationsInstall$(var.Suffix)" BinaryKey="WixHttpCA$(var.Suffix)" DllEntry="SchedHttpUrlReservationsInstall" Execute="immediate" Return="check" SuppressModularization="yes" />
19 + <CustomAction Id="WixSchedHttpUrlReservationsUninstall$(var.Suffix)" BinaryKey="WixHttpCA$(var.Suffix)" DllEntry="SchedHttpUrlReservationsUninstall" Execute="immediate" Return="check" SuppressModularization="yes" />
20 + <CustomAction Id="WixRollbackHttpUrlReservationsInstall$(var.DeferredSuffix)" BinaryKey="WixHttpCA$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" />
21 + <CustomAction Id="WixExecHttpUrlReservationsInstall$(var.DeferredSuffix)" BinaryKey="WixHttpCA$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" />
22 + <CustomAction Id="WixRollbackHttpUrlReservationsUninstall$(var.DeferredSuffix)" BinaryKey="WixHttpCA$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" />
23 + <CustomAction Id="WixExecHttpUrlReservationsUninstall$(var.DeferredSuffix)" BinaryKey="WixHttpCA$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" />
24 +
25 + <!--
26 + We need the HTTP server on Windows XP SP2 or later.
27 + -->
28 + <InstallExecuteSequence>
29 + <Custom Action="WixSchedHttpUrlReservationsUninstall$(var.Suffix)" Before="RemoveFiles" Overridable="yes">
30 + <![CDATA[ VersionNT >= 600 OR (VersionNT >= 501 AND ((MsiNTProductType = 1 AND ServicePackLevel >= 2) OR (MsiNTProductType > 1))) ]]>
31 + </Custom>
32 + <Custom Action="WixSchedHttpUrlReservationsInstall$(var.Suffix)" After="InstallFiles" Overridable="yes">
33 + <![CDATA[ VersionNT >= 600 OR (VersionNT >= 501 AND ((MsiNTProductType = 1 AND ServicePackLevel >= 2) OR (MsiNTProductType > 1))) ]]>
34 + </Custom>
35 + </InstallExecuteSequence>
36 + </Fragment>
37 + <Fragment>
38 + <Binary Id="WixHttpCA$(var.Suffix)" SourceFile="!(bindpath.$(var.platform))wixhttpca.dll" />
39 + </Fragment>
40 +</Include>
src/wixlib/HttpExtension_x86.wxs new
+8
@@ -0,0 +1,8 @@
1 +<?xml version="1.0"?>
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 + <?define platform=x86 ?>
7 + <?include HttpExtension_Platform.wxi ?>
8 +</Wix>
src/wixlib/en-us.wxl new
+12
@@ -0,0 +1,12 @@
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="WixSchedHttpUrlReservationsInstall" Overridable="yes">Preparing to configure Windows HTTP Server</String>
7 + <String Id="WixSchedHttpUrlReservationsUninstall" Overridable="yes">Preparing to configure Windows HTTP Server</String>
8 + <String Id="WixRollbackHttpUrlReservationsInstall" Overridable="yes">Rolling back Windows HTTP Server configuration</String>
9 + <String Id="WixExecHttpUrlReservationsInstall" Overridable="yes">Configuring Windows HTTP Server</String>
10 + <String Id="WixRollbackHttpUrlReservationsUninstall" Overridable="yes">Rolling back Windows HTTP Server configuration</String>
11 + <String Id="WixExecHttpUrlReservationsUninstall" Overridable="yes">Configuring Windows HTTP Server</String>
12 +</WixLocalization>