aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ca/cost.h5
-rw-r--r--src/ca/dllmain.cpp26
-rw-r--r--src/ca/precomp.h17
-rw-r--r--src/ca/wixhttpca.cpp525
-rw-r--r--src/ca/wixhttpca.def9
-rw-r--r--src/ca/wixhttpca.vcxproj58
-rw-r--r--src/ca/wixhttpca.vcxproj.filters40
-rw-r--r--src/wixext/HttpCompiler.cs280
-rw-r--r--src/wixext/HttpConstants.cs19
-rw-r--r--src/wixext/HttpDecompiler.cs135
-rw-r--r--src/wixext/HttpExtensionData.cs64
-rw-r--r--src/wixext/WixHttpExtension.csproj48
-rw-r--r--src/wixext/http.xsd148
-rw-r--r--src/wixext/messages.xml13
-rw-r--r--src/wixext/tables.xml28
-rw-r--r--src/wixlib/HttpExtension.wixproj26
-rw-r--r--src/wixlib/HttpExtension.wxs11
-rw-r--r--src/wixlib/HttpExtension_Platform.wxi40
-rw-r--r--src/wixlib/HttpExtension_x86.wxs8
-rw-r--r--src/wixlib/en-us.wxl12
20 files changed, 1512 insertions, 0 deletions
diff --git a/src/ca/cost.h b/src/ca/cost.h
new file mode 100644
index 00000000..283758b0
--- /dev/null
+++ b/src/ca/cost.h
@@ -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
5const UINT COST_HTTP_URL_ACL = 2000;
diff --git a/src/ca/dllmain.cpp b/src/ca/dllmain.cpp
new file mode 100644
index 00000000..b4c8c037
--- /dev/null
+++ b/src/ca/dllmain.cpp
@@ -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/********************************************************************
6DllMain - standard entry point for all WiX CustomActions
7
8********************************************************************/
9extern "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}
diff --git a/src/ca/precomp.h b/src/ca/precomp.h
new file mode 100644
index 00000000..ec74006b
--- /dev/null
+++ b/src/ca/precomp.h
@@ -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"
diff --git a/src/ca/wixhttpca.cpp b/src/ca/wixhttpca.cpp
new file mode 100644
index 00000000..58b46c0f
--- /dev/null
+++ b/src/ca/wixhttpca.cpp
@@ -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
5static HRESULT AppendUrlAce(
6 __in LPWSTR wzSecurityPrincipal,
7 __in int iRights,
8 __in LPWSTR* psczSDDL
9 );
10static HRESULT WriteHttpUrlReservation(
11 __in WCA_TODO action,
12 __in LPWSTR wzUrl,
13 __in LPWSTR wzSDDL,
14 __in int iHandleExisting,
15 __in LPWSTR* psczCustomActionData
16 );
17static HRESULT AddUrlReservation(
18 __in LPWSTR wzUrl,
19 __in LPWSTR wzSddl
20 );
21static HRESULT GetUrlReservation(
22 __in LPWSTR wzUrl,
23 __deref_out_z LPWSTR* psczSddl
24 );
25static HRESULT RemoveUrlReservation(
26 __in LPWSTR wzUrl
27 );
28
29HTTPAPI_VERSION vcHttpVersion = HTTPAPI_VERSION_1;
30ULONG vcHttpFlags = HTTP_INITIALIZE_CONFIG;
31
32LPCWSTR vcsHttpUrlReservationQuery =
33 L"SELECT `WixHttpUrlReservation`.`WixHttpUrlReservation`, `WixHttpUrlReservation`.`HandleExisting`, `WixHttpUrlReservation`.`Sddl`, `WixHttpUrlReservation`.`Url`, `WixHttpUrlReservation`.`Component_` "
34 L"FROM `WixHttpUrlReservation`";
35enum eHttpUrlReservationQuery { hurqId = 1, hurqHandleExisting, hurqSDDL, hurqUrl, hurqComponent };
36
37LPCWSTR vcsHttpUrlAceQuery =
38 L"SELECT `WixHttpUrlAce`.`SecurityPrincipal`, `WixHttpUrlAce`.`Rights` "
39 L"FROM `WixHttpUrlAce` "
40 L"WHERE `WixHttpUrlAce`.`WixHttpUrlReservation_`=?";
41enum eHttpUrlAceQuery { huaqSecurityPrincipal = 1, huaqRights };
42
43enum eHandleExisting { heReplace = 0, heIgnore = 1, heFail = 2 };
44
45/******************************************************************
46 SchedHttpUrlReservations - immediate custom action worker to
47 prepare configuring URL reservations.
48
49********************************************************************/
50static 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 }
213LExit:
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
231static 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
259LExit:
260 ReleaseStr(sczSid);
261
262 return hr;
263}
264
265static 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
287LExit:
288 return hr;
289}
290
291/******************************************************************
292 SchedHttpUrlReservationsInstall - immediate custom action entry
293 point to prepare adding URL reservations.
294
295********************************************************************/
296extern "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********************************************************************/
308extern "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********************************************************************/
320extern "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
420LExit:
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
433static 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
456LExit:
457 return hr;
458}
459
460static 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
496LExit:
497 ReleaseMem(pSet);
498
499 return hr;
500}
501
502static 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
523LExit:
524 return hr;
525}
diff --git a/src/ca/wixhttpca.def b/src/ca/wixhttpca.def
new file mode 100644
index 00000000..5368c946
--- /dev/null
+++ b/src/ca/wixhttpca.def
@@ -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
4LIBRARY "wixhttpca"
5
6EXPORTS
7 SchedHttpUrlReservationsInstall
8 SchedHttpUrlReservationsUninstall
9 ExecHttpUrlReservations
diff --git a/src/ca/wixhttpca.vcxproj b/src/ca/wixhttpca.vcxproj
new file mode 100644
index 00000000..89dbc79a
--- /dev/null
+++ b/src/ca/wixhttpca.vcxproj
@@ -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>
diff --git a/src/ca/wixhttpca.vcxproj.filters b/src/ca/wixhttpca.vcxproj.filters
new file mode 100644
index 00000000..354653c1
--- /dev/null
+++ b/src/ca/wixhttpca.vcxproj.filters
@@ -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
diff --git a/src/wixext/HttpCompiler.cs b/src/wixext/HttpCompiler.cs
new file mode 100644
index 00000000..c694ccde
--- /dev/null
+++ b/src/wixext/HttpCompiler.cs
@@ -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
3namespace 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}
diff --git a/src/wixext/HttpConstants.cs b/src/wixext/HttpConstants.cs
new file mode 100644
index 00000000..7760d03f
--- /dev/null
+++ b/src/wixext/HttpConstants.cs
@@ -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
3namespace 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}
diff --git a/src/wixext/HttpDecompiler.cs b/src/wixext/HttpDecompiler.cs
new file mode 100644
index 00000000..043ee1e1
--- /dev/null
+++ b/src/wixext/HttpDecompiler.cs
@@ -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
3namespace 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}
diff --git a/src/wixext/HttpExtensionData.cs b/src/wixext/HttpExtensionData.cs
new file mode 100644
index 00000000..db79a6c1
--- /dev/null
+++ b/src/wixext/HttpExtensionData.cs
@@ -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
3namespace 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}
diff --git a/src/wixext/WixHttpExtension.csproj b/src/wixext/WixHttpExtension.csproj
new file mode 100644
index 00000000..74af503f
--- /dev/null
+++ b/src/wixext/WixHttpExtension.csproj
@@ -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>
diff --git a/src/wixext/http.xsd b/src/wixext/http.xsd
new file mode 100644
index 00000000..b96a6ded
--- /dev/null
+++ b/src/wixext/http.xsd
@@ -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>
diff --git a/src/wixext/messages.xml b/src/wixext/messages.xml
new file mode 100644
index 00000000..6dcdc366
--- /dev/null
+++ b/src/wixext/messages.xml
@@ -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>
diff --git a/src/wixext/tables.xml b/src/wixext/tables.xml
new file mode 100644
index 00000000..576fc2a7
--- /dev/null
+++ b/src/wixext/tables.xml
@@ -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>
diff --git a/src/wixlib/HttpExtension.wixproj b/src/wixlib/HttpExtension.wixproj
new file mode 100644
index 00000000..738579db
--- /dev/null
+++ b/src/wixlib/HttpExtension.wixproj
@@ -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>
diff --git a/src/wixlib/HttpExtension.wxs b/src/wixlib/HttpExtension.wxs
new file mode 100644
index 00000000..e2b3534d
--- /dev/null
+++ b/src/wixlib/HttpExtension.wxs
@@ -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>
diff --git a/src/wixlib/HttpExtension_Platform.wxi b/src/wixlib/HttpExtension_Platform.wxi
new file mode 100644
index 00000000..11c3aa2b
--- /dev/null
+++ b/src/wixlib/HttpExtension_Platform.wxi
@@ -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>
diff --git a/src/wixlib/HttpExtension_x86.wxs b/src/wixlib/HttpExtension_x86.wxs
new file mode 100644
index 00000000..00a3dc18
--- /dev/null
+++ b/src/wixlib/HttpExtension_x86.wxs
@@ -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>
diff --git a/src/wixlib/en-us.wxl b/src/wixlib/en-us.wxl
new file mode 100644
index 00000000..2c43af06
--- /dev/null
+++ b/src/wixlib/en-us.wxl
@@ -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>