diff options
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/uriutil.cpp')
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/uriutil.cpp | 553 |
1 files changed, 553 insertions, 0 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/uriutil.cpp b/src/libs/dutil/WixToolset.DUtil/uriutil.cpp new file mode 100644 index 00000000..7913c22e --- /dev/null +++ b/src/libs/dutil/WixToolset.DUtil/uriutil.cpp | |||
@@ -0,0 +1,553 @@ | |||
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 | // Exit macros | ||
7 | #define UriExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_URIUTIL, x, s, __VA_ARGS__) | ||
8 | #define UriExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_URIUTIL, x, s, __VA_ARGS__) | ||
9 | #define UriExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_URIUTIL, x, s, __VA_ARGS__) | ||
10 | #define UriExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_URIUTIL, x, s, __VA_ARGS__) | ||
11 | #define UriExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_URIUTIL, x, s, __VA_ARGS__) | ||
12 | #define UriExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_URIUTIL, x, s, __VA_ARGS__) | ||
13 | #define UriExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_URIUTIL, p, x, e, s, __VA_ARGS__) | ||
14 | #define UriExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_URIUTIL, p, x, s, __VA_ARGS__) | ||
15 | #define UriExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_URIUTIL, p, x, e, s, __VA_ARGS__) | ||
16 | #define UriExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_URIUTIL, p, x, s, __VA_ARGS__) | ||
17 | #define UriExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_URIUTIL, e, x, s, __VA_ARGS__) | ||
18 | #define UriExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_URIUTIL, g, x, s, __VA_ARGS__) | ||
19 | |||
20 | |||
21 | // | ||
22 | // UriCanonicalize - canonicalizes a URI. | ||
23 | // | ||
24 | extern "C" HRESULT DAPI UriCanonicalize( | ||
25 | __inout_z LPWSTR* psczUri | ||
26 | ) | ||
27 | { | ||
28 | HRESULT hr = S_OK; | ||
29 | WCHAR wz[INTERNET_MAX_URL_LENGTH] = { }; | ||
30 | DWORD cch = countof(wz); | ||
31 | |||
32 | if (!::InternetCanonicalizeUrlW(*psczUri, wz, &cch, ICU_DECODE)) | ||
33 | { | ||
34 | UriExitWithLastError(hr, "Failed to canonicalize URI."); | ||
35 | } | ||
36 | |||
37 | hr = StrAllocString(psczUri, wz, cch); | ||
38 | UriExitOnFailure(hr, "Failed copy canonicalized URI."); | ||
39 | |||
40 | LExit: | ||
41 | return hr; | ||
42 | } | ||
43 | |||
44 | |||
45 | // | ||
46 | // UriCrack - cracks a URI into constituent parts. | ||
47 | // | ||
48 | extern "C" HRESULT DAPI UriCrack( | ||
49 | __in_z LPCWSTR wzUri, | ||
50 | __out_opt INTERNET_SCHEME* pScheme, | ||
51 | __deref_opt_out_z LPWSTR* psczHostName, | ||
52 | __out_opt INTERNET_PORT* pPort, | ||
53 | __deref_opt_out_z LPWSTR* psczUser, | ||
54 | __deref_opt_out_z LPWSTR* psczPassword, | ||
55 | __deref_opt_out_z LPWSTR* psczPath, | ||
56 | __deref_opt_out_z LPWSTR* psczQueryString | ||
57 | ) | ||
58 | { | ||
59 | HRESULT hr = S_OK; | ||
60 | URL_COMPONENTSW components = { }; | ||
61 | WCHAR wzHostName[INTERNET_MAX_HOST_NAME_LENGTH + 1]; | ||
62 | WCHAR wzUserName[INTERNET_MAX_USER_NAME_LENGTH + 1]; | ||
63 | WCHAR wzPassword[INTERNET_MAX_PASSWORD_LENGTH + 1]; | ||
64 | WCHAR wzPath[INTERNET_MAX_PATH_LENGTH + 1]; | ||
65 | WCHAR wzQueryString[INTERNET_MAX_PATH_LENGTH + 1]; | ||
66 | |||
67 | components.dwStructSize = sizeof(URL_COMPONENTSW); | ||
68 | |||
69 | if (psczHostName) | ||
70 | { | ||
71 | components.lpszHostName = wzHostName; | ||
72 | components.dwHostNameLength = countof(wzHostName); | ||
73 | } | ||
74 | |||
75 | if (psczUser) | ||
76 | { | ||
77 | components.lpszUserName = wzUserName; | ||
78 | components.dwUserNameLength = countof(wzUserName); | ||
79 | } | ||
80 | |||
81 | if (psczPassword) | ||
82 | { | ||
83 | components.lpszPassword = wzPassword; | ||
84 | components.dwPasswordLength = countof(wzPassword); | ||
85 | } | ||
86 | |||
87 | if (psczPath) | ||
88 | { | ||
89 | components.lpszUrlPath = wzPath; | ||
90 | components.dwUrlPathLength = countof(wzPath); | ||
91 | } | ||
92 | |||
93 | if (psczQueryString) | ||
94 | { | ||
95 | components.lpszExtraInfo = wzQueryString; | ||
96 | components.dwExtraInfoLength = countof(wzQueryString); | ||
97 | } | ||
98 | |||
99 | if (!::InternetCrackUrlW(wzUri, 0, ICU_DECODE | ICU_ESCAPE, &components)) | ||
100 | { | ||
101 | UriExitWithLastError(hr, "Failed to crack URI."); | ||
102 | } | ||
103 | |||
104 | if (pScheme) | ||
105 | { | ||
106 | *pScheme = components.nScheme; | ||
107 | } | ||
108 | |||
109 | if (psczHostName) | ||
110 | { | ||
111 | hr = StrAllocString(psczHostName, components.lpszHostName, components.dwHostNameLength); | ||
112 | UriExitOnFailure(hr, "Failed to copy host name."); | ||
113 | } | ||
114 | |||
115 | if (pPort) | ||
116 | { | ||
117 | *pPort = components.nPort; | ||
118 | } | ||
119 | |||
120 | if (psczUser) | ||
121 | { | ||
122 | hr = StrAllocString(psczUser, components.lpszUserName, components.dwUserNameLength); | ||
123 | UriExitOnFailure(hr, "Failed to copy user name."); | ||
124 | } | ||
125 | |||
126 | if (psczPassword) | ||
127 | { | ||
128 | hr = StrAllocString(psczPassword, components.lpszPassword, components.dwPasswordLength); | ||
129 | UriExitOnFailure(hr, "Failed to copy password."); | ||
130 | } | ||
131 | |||
132 | if (psczPath) | ||
133 | { | ||
134 | hr = StrAllocString(psczPath, components.lpszUrlPath, components.dwUrlPathLength); | ||
135 | UriExitOnFailure(hr, "Failed to copy path."); | ||
136 | } | ||
137 | |||
138 | if (psczQueryString) | ||
139 | { | ||
140 | hr = StrAllocString(psczQueryString, components.lpszExtraInfo, components.dwExtraInfoLength); | ||
141 | UriExitOnFailure(hr, "Failed to copy query string."); | ||
142 | } | ||
143 | |||
144 | LExit: | ||
145 | return hr; | ||
146 | } | ||
147 | |||
148 | |||
149 | // | ||
150 | // UriCrackEx - cracks a URI into URI_INFO. | ||
151 | // | ||
152 | extern "C" HRESULT DAPI UriCrackEx( | ||
153 | __in_z LPCWSTR wzUri, | ||
154 | __in URI_INFO* pUriInfo | ||
155 | ) | ||
156 | { | ||
157 | HRESULT hr = S_OK; | ||
158 | |||
159 | hr = UriCrack(wzUri, &pUriInfo->scheme, &pUriInfo->sczHostName, &pUriInfo->port, &pUriInfo->sczUser, &pUriInfo->sczPassword, &pUriInfo->sczPath, &pUriInfo->sczQueryString); | ||
160 | UriExitOnFailure(hr, "Failed to crack URI."); | ||
161 | |||
162 | LExit: | ||
163 | return hr; | ||
164 | } | ||
165 | |||
166 | |||
167 | // | ||
168 | // UriInfoUninitialize - frees the memory in a URI_INFO struct. | ||
169 | // | ||
170 | extern "C" void DAPI UriInfoUninitialize( | ||
171 | __in URI_INFO* pUriInfo | ||
172 | ) | ||
173 | { | ||
174 | ReleaseStr(pUriInfo->sczHostName); | ||
175 | ReleaseStr(pUriInfo->sczUser); | ||
176 | ReleaseStr(pUriInfo->sczPassword); | ||
177 | ReleaseStr(pUriInfo->sczPath); | ||
178 | ReleaseStr(pUriInfo->sczQueryString); | ||
179 | memset(pUriInfo, 0, sizeof(URI_INFO)); | ||
180 | } | ||
181 | |||
182 | |||
183 | // | ||
184 | // UriCreate - creates a URI from constituent parts. | ||
185 | // | ||
186 | extern "C" HRESULT DAPI UriCreate( | ||
187 | __inout_z LPWSTR* psczUri, | ||
188 | __in INTERNET_SCHEME scheme, | ||
189 | __in_z_opt LPWSTR wzHostName, | ||
190 | __in INTERNET_PORT port, | ||
191 | __in_z_opt LPWSTR wzUser, | ||
192 | __in_z_opt LPWSTR wzPassword, | ||
193 | __in_z_opt LPWSTR wzPath, | ||
194 | __in_z_opt LPWSTR wzQueryString | ||
195 | ) | ||
196 | { | ||
197 | HRESULT hr = S_OK; | ||
198 | WCHAR wz[INTERNET_MAX_URL_LENGTH] = { }; | ||
199 | DWORD cch = countof(wz); | ||
200 | URL_COMPONENTSW components = { }; | ||
201 | |||
202 | components.dwStructSize = sizeof(URL_COMPONENTSW); | ||
203 | components.nScheme = scheme; | ||
204 | components.lpszHostName = wzHostName; | ||
205 | components.nPort = port; | ||
206 | components.lpszUserName = wzUser; | ||
207 | components.lpszPassword = wzPassword; | ||
208 | components.lpszUrlPath = wzPath; | ||
209 | components.lpszExtraInfo = wzQueryString; | ||
210 | |||
211 | if (!::InternetCreateUrlW(&components, ICU_ESCAPE, wz, &cch)) | ||
212 | { | ||
213 | UriExitWithLastError(hr, "Failed to create URI."); | ||
214 | } | ||
215 | |||
216 | hr = StrAllocString(psczUri, wz, cch); | ||
217 | UriExitOnFailure(hr, "Failed copy created URI."); | ||
218 | |||
219 | LExit: | ||
220 | return hr; | ||
221 | } | ||
222 | |||
223 | |||
224 | // | ||
225 | // UriGetServerAndResource - gets the server and resource as independent strings from a URI. | ||
226 | // | ||
227 | // NOTE: This function is useful for the InternetConnect/HttpRequest APIs. | ||
228 | // | ||
229 | extern "C" HRESULT DAPI UriGetServerAndResource( | ||
230 | __in_z LPCWSTR wzUri, | ||
231 | __out_z LPWSTR* psczServer, | ||
232 | __out_z LPWSTR* psczResource | ||
233 | ) | ||
234 | { | ||
235 | HRESULT hr = S_OK; | ||
236 | INTERNET_SCHEME scheme = INTERNET_SCHEME_UNKNOWN; | ||
237 | LPWSTR sczHostName = NULL; | ||
238 | INTERNET_PORT port = INTERNET_INVALID_PORT_NUMBER; | ||
239 | LPWSTR sczUser = NULL; | ||
240 | LPWSTR sczPassword = NULL; | ||
241 | LPWSTR sczPath = NULL; | ||
242 | LPWSTR sczQueryString = NULL; | ||
243 | |||
244 | hr = UriCrack(wzUri, &scheme, &sczHostName, &port, &sczUser, &sczPassword, &sczPath, &sczQueryString); | ||
245 | UriExitOnFailure(hr, "Failed to crack URI."); | ||
246 | |||
247 | hr = UriCreate(psczServer, scheme, sczHostName, port, sczUser, sczPassword, NULL, NULL); | ||
248 | UriExitOnFailure(hr, "Failed to allocate server URI."); | ||
249 | |||
250 | hr = UriCreate(psczResource, INTERNET_SCHEME_UNKNOWN, NULL, INTERNET_INVALID_PORT_NUMBER, NULL, NULL, sczPath, sczQueryString); | ||
251 | UriExitOnFailure(hr, "Failed to allocate resource URI."); | ||
252 | |||
253 | LExit: | ||
254 | ReleaseStr(sczQueryString); | ||
255 | ReleaseStr(sczPath); | ||
256 | ReleaseStr(sczPassword); | ||
257 | ReleaseStr(sczUser); | ||
258 | ReleaseStr(sczHostName); | ||
259 | |||
260 | return hr; | ||
261 | } | ||
262 | |||
263 | |||
264 | // | ||
265 | // UriFile - returns the file part of the URI. | ||
266 | // | ||
267 | extern "C" HRESULT DAPI UriFile( | ||
268 | __deref_out_z LPWSTR* psczFile, | ||
269 | __in_z LPCWSTR wzUri | ||
270 | ) | ||
271 | { | ||
272 | HRESULT hr = S_OK; | ||
273 | WCHAR wz[MAX_PATH + 1]; | ||
274 | DWORD cch = countof(wz); | ||
275 | URL_COMPONENTSW uc = { }; | ||
276 | |||
277 | uc.dwStructSize = sizeof(uc); | ||
278 | uc.lpszUrlPath = wz; | ||
279 | uc.dwUrlPathLength = cch; | ||
280 | |||
281 | if (!::InternetCrackUrlW(wzUri, 0, ICU_DECODE | ICU_ESCAPE, &uc)) | ||
282 | { | ||
283 | UriExitWithLastError(hr, "Failed to crack URI."); | ||
284 | } | ||
285 | |||
286 | // Copy only the file name. Fortunately, PathFile() understands that | ||
287 | // forward slashes can be directory separators like backslashes. | ||
288 | hr = StrAllocString(psczFile, PathFile(wz), 0); | ||
289 | UriExitOnFailure(hr, "Failed to copy file name"); | ||
290 | |||
291 | LExit: | ||
292 | return hr; | ||
293 | } | ||
294 | |||
295 | |||
296 | /******************************************************************* | ||
297 | UriProtocol - determines the protocol of a URI. | ||
298 | |||
299 | ********************************************************************/ | ||
300 | extern "C" HRESULT DAPI UriProtocol( | ||
301 | __in_z LPCWSTR wzUri, | ||
302 | __out URI_PROTOCOL* pProtocol | ||
303 | ) | ||
304 | { | ||
305 | Assert(wzUri && *wzUri); | ||
306 | Assert(pProtocol); | ||
307 | |||
308 | HRESULT hr = S_OK; | ||
309 | |||
310 | if ((L'h' == wzUri[0] || L'H' == wzUri[0]) && | ||
311 | (L't' == wzUri[1] || L'T' == wzUri[1]) && | ||
312 | (L't' == wzUri[2] || L'T' == wzUri[2]) && | ||
313 | (L'p' == wzUri[3] || L'P' == wzUri[3]) && | ||
314 | (L's' == wzUri[4] || L'S' == wzUri[4]) && | ||
315 | L':' == wzUri[5] && | ||
316 | L'/' == wzUri[6] && | ||
317 | L'/' == wzUri[7]) | ||
318 | { | ||
319 | *pProtocol = URI_PROTOCOL_HTTPS; | ||
320 | } | ||
321 | else if ((L'h' == wzUri[0] || L'H' == wzUri[0]) && | ||
322 | (L't' == wzUri[1] || L'T' == wzUri[1]) && | ||
323 | (L't' == wzUri[2] || L'T' == wzUri[2]) && | ||
324 | (L'p' == wzUri[3] || L'P' == wzUri[3]) && | ||
325 | L':' == wzUri[4] && | ||
326 | L'/' == wzUri[5] && | ||
327 | L'/' == wzUri[6]) | ||
328 | { | ||
329 | *pProtocol = URI_PROTOCOL_HTTP; | ||
330 | } | ||
331 | else if ((L'f' == wzUri[0] || L'F' == wzUri[0]) && | ||
332 | (L't' == wzUri[1] || L'T' == wzUri[1]) && | ||
333 | (L'p' == wzUri[2] || L'P' == wzUri[2]) && | ||
334 | L':' == wzUri[3] && | ||
335 | L'/' == wzUri[4] && | ||
336 | L'/' == wzUri[5]) | ||
337 | { | ||
338 | *pProtocol = URI_PROTOCOL_FTP; | ||
339 | } | ||
340 | else if ((L'f' == wzUri[0] || L'F' == wzUri[0]) && | ||
341 | (L'i' == wzUri[1] || L'I' == wzUri[1]) && | ||
342 | (L'l' == wzUri[2] || L'L' == wzUri[2]) && | ||
343 | (L'e' == wzUri[3] || L'E' == wzUri[3]) && | ||
344 | L':' == wzUri[4] && | ||
345 | L'/' == wzUri[5] && | ||
346 | L'/' == wzUri[6]) | ||
347 | { | ||
348 | *pProtocol = URI_PROTOCOL_FILE; | ||
349 | } | ||
350 | else | ||
351 | { | ||
352 | *pProtocol = URI_PROTOCOL_UNKNOWN; | ||
353 | } | ||
354 | |||
355 | return hr; | ||
356 | } | ||
357 | |||
358 | |||
359 | /******************************************************************* | ||
360 | UriRoot - returns the root of the path specified in the URI. | ||
361 | |||
362 | examples: | ||
363 | file:///C:\path\path -> C:\ | ||
364 | file://server/share/path/path -> \\server\share | ||
365 | http://www.example.com/path/path -> http://www.example.com/ | ||
366 | ftp://ftp.example.com/path/path -> ftp://www.example.com/ | ||
367 | |||
368 | NOTE: This function should only be used on cannonicalized URIs. | ||
369 | It does not cannonicalize itself. | ||
370 | ********************************************************************/ | ||
371 | extern "C" HRESULT DAPI UriRoot( | ||
372 | __in_z LPCWSTR wzUri, | ||
373 | __out LPWSTR* ppwzRoot, | ||
374 | __out_opt URI_PROTOCOL* pProtocol | ||
375 | ) | ||
376 | { | ||
377 | Assert(wzUri && *wzUri); | ||
378 | Assert(ppwzRoot); | ||
379 | |||
380 | HRESULT hr = S_OK; | ||
381 | URI_PROTOCOL protocol = URI_PROTOCOL_UNKNOWN; | ||
382 | LPCWSTR pwcSlash = NULL; | ||
383 | |||
384 | hr = UriProtocol(wzUri, &protocol); | ||
385 | UriExitOnFailure(hr, "Invalid URI."); | ||
386 | |||
387 | switch (protocol) | ||
388 | { | ||
389 | case URI_PROTOCOL_FILE: | ||
390 | if (L'/' == wzUri[7]) // file path | ||
391 | { | ||
392 | if (((L'a' <= wzUri[8] && L'z' >= wzUri[8]) || (L'A' <= wzUri[8] && L'Z' >= wzUri[8])) && L':' == wzUri[9]) | ||
393 | { | ||
394 | hr = StrAlloc(ppwzRoot, 4); | ||
395 | UriExitOnFailure(hr, "Failed to allocate string for root of URI."); | ||
396 | *ppwzRoot[0] = wzUri[8]; | ||
397 | *ppwzRoot[1] = L':'; | ||
398 | *ppwzRoot[2] = L'\\'; | ||
399 | *ppwzRoot[3] = L'\0'; | ||
400 | } | ||
401 | else | ||
402 | { | ||
403 | hr = E_INVALIDARG; | ||
404 | UriExitOnFailure(hr, "Invalid file path in URI."); | ||
405 | } | ||
406 | } | ||
407 | else // UNC share | ||
408 | { | ||
409 | pwcSlash = wcschr(wzUri + 8, L'/'); | ||
410 | if (!pwcSlash) | ||
411 | { | ||
412 | hr = E_INVALIDARG; | ||
413 | UriExitOnFailure(hr, "Invalid server name in URI."); | ||
414 | } | ||
415 | else | ||
416 | { | ||
417 | hr = StrAllocString(ppwzRoot, L"\\\\", 64); | ||
418 | UriExitOnFailure(hr, "Failed to allocate string for root of URI."); | ||
419 | |||
420 | pwcSlash = wcschr(pwcSlash + 1, L'/'); | ||
421 | if (pwcSlash) | ||
422 | { | ||
423 | hr = StrAllocConcat(ppwzRoot, wzUri + 8, pwcSlash - wzUri - 8); | ||
424 | UriExitOnFailure(hr, "Failed to add server/share to root of URI."); | ||
425 | } | ||
426 | else | ||
427 | { | ||
428 | hr = StrAllocConcat(ppwzRoot, wzUri + 8, 0); | ||
429 | UriExitOnFailure(hr, "Failed to add server/share to root of URI."); | ||
430 | } | ||
431 | |||
432 | // replace all slashes with backslashes to be truly UNC. | ||
433 | for (LPWSTR pwc = *ppwzRoot; pwc && *pwc; ++pwc) | ||
434 | { | ||
435 | if (L'/' == *pwc) | ||
436 | { | ||
437 | *pwc = L'\\'; | ||
438 | } | ||
439 | } | ||
440 | } | ||
441 | } | ||
442 | break; | ||
443 | |||
444 | case URI_PROTOCOL_FTP: | ||
445 | pwcSlash = wcschr(wzUri + 6, L'/'); | ||
446 | if (pwcSlash) | ||
447 | { | ||
448 | hr = StrAllocString(ppwzRoot, wzUri, pwcSlash - wzUri); | ||
449 | UriExitOnFailure(hr, "Failed allocate root from URI."); | ||
450 | } | ||
451 | else | ||
452 | { | ||
453 | hr = StrAllocString(ppwzRoot, wzUri, 0); | ||
454 | UriExitOnFailure(hr, "Failed allocate root from URI."); | ||
455 | } | ||
456 | break; | ||
457 | |||
458 | case URI_PROTOCOL_HTTP: | ||
459 | pwcSlash = wcschr(wzUri + 7, L'/'); | ||
460 | if (pwcSlash) | ||
461 | { | ||
462 | hr = StrAllocString(ppwzRoot, wzUri, pwcSlash - wzUri); | ||
463 | UriExitOnFailure(hr, "Failed allocate root from URI."); | ||
464 | } | ||
465 | else | ||
466 | { | ||
467 | hr = StrAllocString(ppwzRoot, wzUri, 0); | ||
468 | UriExitOnFailure(hr, "Failed allocate root from URI."); | ||
469 | } | ||
470 | break; | ||
471 | |||
472 | default: | ||
473 | hr = E_INVALIDARG; | ||
474 | UriExitOnFailure(hr, "Unknown URI protocol."); | ||
475 | } | ||
476 | |||
477 | if (pProtocol) | ||
478 | { | ||
479 | *pProtocol = protocol; | ||
480 | } | ||
481 | |||
482 | LExit: | ||
483 | return hr; | ||
484 | } | ||
485 | |||
486 | |||
487 | extern "C" HRESULT DAPI UriResolve( | ||
488 | __in_z LPCWSTR wzUri, | ||
489 | __in_opt LPCWSTR wzBaseUri, | ||
490 | __out LPWSTR* ppwzResolvedUri, | ||
491 | __out_opt URI_PROTOCOL* pResolvedProtocol | ||
492 | ) | ||
493 | { | ||
494 | UNREFERENCED_PARAMETER(wzUri); | ||
495 | UNREFERENCED_PARAMETER(wzBaseUri); | ||
496 | UNREFERENCED_PARAMETER(ppwzResolvedUri); | ||
497 | UNREFERENCED_PARAMETER(pResolvedProtocol); | ||
498 | |||
499 | HRESULT hr = E_NOTIMPL; | ||
500 | #if 0 | ||
501 | URI_PROTOCOL protocol = URI_PROTOCOL_UNKNOWN; | ||
502 | |||
503 | hr = UriProtocol(wzUri, &protocol); | ||
504 | UriExitOnFailure(hr, "Failed to determine protocol for URL: %ls", wzUri); | ||
505 | |||
506 | UriExitOnNull(ppwzResolvedUri, hr, E_INVALIDARG, "Failed to resolve URI, because no method of output was provided"); | ||
507 | |||
508 | if (URI_PROTOCOL_UNKNOWN == protocol) | ||
509 | { | ||
510 | UriExitOnNull(wzBaseUri, hr, E_INVALIDARG, "Failed to resolve URI - base URI provided was NULL"); | ||
511 | |||
512 | if (L'/' == *wzUri || L'\\' == *wzUri) | ||
513 | { | ||
514 | hr = UriRoot(wzBaseUri, ppwzResolvedUri, &protocol); | ||
515 | UriExitOnFailure(hr, "Failed to get root from URI: %ls", wzBaseUri); | ||
516 | |||
517 | hr = StrAllocConcat(ppwzResolvedUri, wzUri, 0); | ||
518 | UriExitOnFailure(hr, "Failed to concat file to base URI."); | ||
519 | } | ||
520 | else | ||
521 | { | ||
522 | hr = UriProtocol(wzBaseUri, &protocol); | ||
523 | UriExitOnFailure(hr, "Failed to get protocol of base URI: %ls", wzBaseUri); | ||
524 | |||
525 | LPCWSTR pwcFile = const_cast<LPCWSTR> (UriFile(wzBaseUri)); | ||
526 | if (!pwcFile) | ||
527 | { | ||
528 | hr = E_INVALIDARG; | ||
529 | UriExitOnFailure(hr, "Failed to get file from base URI: %ls", wzBaseUri); | ||
530 | } | ||
531 | |||
532 | hr = StrAllocString(ppwzResolvedUri, wzBaseUri, pwcFile - wzBaseUri); | ||
533 | UriExitOnFailure(hr, "Failed to allocate string for resolved URI."); | ||
534 | |||
535 | hr = StrAllocConcat(ppwzResolvedUri, wzUri, 0); | ||
536 | UriExitOnFailure(hr, "Failed to concat file to resolved URI."); | ||
537 | } | ||
538 | } | ||
539 | else | ||
540 | { | ||
541 | hr = StrAllocString(ppwzResolvedUri, wzUri, 0); | ||
542 | UriExitOnFailure(hr, "Failed to copy resolved URI."); | ||
543 | } | ||
544 | |||
545 | if (pResolvedProtocol) | ||
546 | { | ||
547 | *pResolvedProtocol = protocol; | ||
548 | } | ||
549 | |||
550 | LExit: | ||
551 | #endif | ||
552 | return hr; | ||
553 | } | ||