aboutsummaryrefslogtreecommitdiff
path: root/src/ca
diff options
context:
space:
mode:
Diffstat (limited to 'src/ca')
-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
7 files changed, 680 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