main
cpp 1,309 lines 60.4 KB
Raw
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 using namespace System;
6 using namespace System::IO;
7 using namespace Xunit;
8 using namespace WixInternal::TestSupport;
9
10 // from PathCch.h
11 #ifndef PATHCCH_ALLOW_LONG_PATHS
12 #define PATHCCH_ALLOW_LONG_PATHS 0x01
13 #endif
14
15 namespace DutilTests
16 {
17 public ref class PathUtil
18 {
19 public:
20 [Fact]
21 void PathBackslashFixedTerminateTest()
22 {
23 HRESULT hr = S_OK;
24 WCHAR wzEmpty[1] = { L'\0' };
25 WCHAR wzSingleLetter[1] = { L'a' };
26 WCHAR wzSingleBackslash[1] = { L'\\' };
27 WCHAR wzSingleForwardSlash[1] = { L'/' };
28 WCHAR wzSingleLetterNullTerminated[2] = { L'a', L'\0' };
29 WCHAR wzSingleBackslashNullTerminated[2] = { L'\\', L'\0' };
30 WCHAR wzSingleForwardSlashNullTerminated[2] = { L'/', L'\0' };
31 WCHAR wzExtraSpaceLetterNullTerminated[3] = { L'a', L'\0', L'\0' };
32 WCHAR wzExtraSpaceBackslashNullTerminated[3] = { L'\\', L'\0', L'\0' };
33 WCHAR wzExtraSpaceForwardSlashNullTerminated[3] = { L'/', L'\0', L'\0' };
34
35 hr = PathFixedBackslashTerminate(wzEmpty, 0);
36 NativeAssert::SpecificReturnCode(E_INSUFFICIENT_BUFFER, hr, "PathFixedBackslashTerminate: zero-length, {0}", wzEmpty);
37
38 hr = PathFixedBackslashTerminate(wzEmpty, countof(wzEmpty));
39 NativeAssert::SpecificReturnCode(E_INSUFFICIENT_BUFFER, hr, "PathFixedBackslashTerminate: '' (length 1), {0}", wzEmpty);
40
41 hr = PathFixedBackslashTerminate(wzSingleLetter, countof(wzSingleLetter));
42 NativeAssert::SpecificReturnCode(E_INVALIDARG, hr, "PathFixedBackslashTerminate: 'a' (length 1)");
43
44 hr = PathFixedBackslashTerminate(wzSingleBackslash, countof(wzSingleBackslash));
45 NativeAssert::SpecificReturnCode(E_INVALIDARG, hr, "PathFixedBackslashTerminate: '\\' (length 1)");
46
47 hr = PathFixedBackslashTerminate(wzSingleForwardSlash, countof(wzSingleForwardSlash));
48 NativeAssert::SpecificReturnCode(E_INVALIDARG, hr, "PathFixedBackslashTerminate: '/' (length 1)");
49
50 hr = PathFixedBackslashTerminate(wzSingleLetterNullTerminated, countof(wzSingleLetterNullTerminated));
51 NativeAssert::SpecificReturnCode(E_INSUFFICIENT_BUFFER, hr, "PathFixedBackslashTerminate: 'a' (length 2)");
52
53 hr = PathFixedBackslashTerminate(wzSingleBackslashNullTerminated, countof(wzSingleBackslashNullTerminated));
54 NativeAssert::Succeeded(hr, "PathFixedBackslashTerminate: '\\' (length 2)");
55 NativeAssert::StringEqual(L"\\", wzSingleBackslashNullTerminated);
56
57 hr = PathFixedBackslashTerminate(wzSingleForwardSlashNullTerminated, countof(wzSingleForwardSlashNullTerminated));
58 NativeAssert::Succeeded(hr, "PathFixedBackslashTerminate: '/' (length 2)");
59 NativeAssert::StringEqual(L"\\", wzSingleForwardSlashNullTerminated);
60
61 hr = PathFixedBackslashTerminate(wzExtraSpaceLetterNullTerminated, countof(wzExtraSpaceLetterNullTerminated));
62 NativeAssert::Succeeded(hr, "PathFixedBackslashTerminate: 'a' (length 3)");
63 NativeAssert::StringEqual(L"a\\", wzExtraSpaceLetterNullTerminated);
64
65 hr = PathFixedBackslashTerminate(wzExtraSpaceBackslashNullTerminated, countof(wzExtraSpaceBackslashNullTerminated));
66 NativeAssert::Succeeded(hr, "PathFixedBackslashTerminate: '\\' (length 3)");
67 NativeAssert::StringEqual(L"\\", wzExtraSpaceBackslashNullTerminated);
68
69 hr = PathFixedBackslashTerminate(wzExtraSpaceForwardSlashNullTerminated, countof(wzExtraSpaceForwardSlashNullTerminated));
70 NativeAssert::Succeeded(hr, "PathFixedBackslashTerminate: '/' (length 3)");
71 NativeAssert::StringEqual(L"\\", wzExtraSpaceForwardSlashNullTerminated);
72 }
73
74 [Fact]
75 void PathBackslashTerminateTest()
76 {
77 HRESULT hr = S_OK;
78 LPWSTR sczPath = NULL;
79 LPCWSTR rgwzPaths[16] =
80 {
81 L"", L"\\",
82 L"a", L"a\\",
83 L"\\", L"\\",
84 L"a\\", L"a\\",
85 L"/", L"\\",
86 L"a/", L"a\\",
87 L"\\\\", L"\\\\",
88 L"//", L"/\\",
89 };
90
91 try
92 {
93 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
94 {
95 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
96 NativeAssert::Succeeded(hr, "Failed to copy string");
97
98 hr = PathBackslashTerminate(&sczPath);
99 NativeAssert::Succeeded(hr, "PathBackslashTerminate: {0}", rgwzPaths[i]);
100 NativeAssert::StringEqual(rgwzPaths[i + 1], sczPath);
101 }
102 }
103 finally
104 {
105 ReleaseStr(sczPath);
106 }
107 }
108
109 [Fact]
110 void PathCanonicalizeForComparisonFallbackTest()
111 {
112 Path2FunctionForceFallback();
113
114 try
115 {
116 PathCanonicalizeForComparisonTestCore(FALSE);
117 }
118 finally
119 {
120 Path2FunctionAllowFallback();
121 }
122 }
123
124 [Fact]
125 void PathCanonicalizeForComparisonTest()
126 {
127 PathCanonicalizeForComparisonTestCore(TRUE);
128 }
129
130 void PathCanonicalizeForComparisonTestCore(BOOL fLongPathSupported)
131 {
132 HRESULT hr = S_OK;
133 LPWSTR sczCanonicalized = NULL;
134
135 try
136 {
137 hr = PathCanonicalizeForComparison(L"C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", 0, &sczCanonicalized);
138 if (!fLongPathSupported)
139 {
140 Assert::Equal<HRESULT>(HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE), hr);
141 }
142 else
143 {
144 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
145 NativeAssert::StringEqual(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized);
146 }
147
148 hr = PathCanonicalizeForComparison(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", 0, &sczCanonicalized);
149 if (!fLongPathSupported)
150 {
151 Assert::Equal<HRESULT>(HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE), hr);
152 }
153 else
154 {
155 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
156 NativeAssert::StringEqual(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized);
157 }
158
159 hr = PathCanonicalizeForComparison(L"\\\\server", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
160 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
161 NativeAssert::StringEqual(L"\\\\server", sczCanonicalized);
162
163 hr = PathCanonicalizeForComparison(L"\\\\server", 0, &sczCanonicalized);
164 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
165 NativeAssert::StringEqual(L"\\\\server", sczCanonicalized);
166
167 hr = PathCanonicalizeForComparison(L"\\\\server\\", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
168 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
169 NativeAssert::StringEqual(L"\\\\server\\", sczCanonicalized);
170
171 hr = PathCanonicalizeForComparison(L"\\\\server\\share", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
172 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
173 NativeAssert::StringEqual(L"\\\\server\\share", sczCanonicalized);
174
175 hr = PathCanonicalizeForComparison(L"\\\\server\\share\\", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
176 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
177 NativeAssert::StringEqual(L"\\\\server\\share\\", sczCanonicalized);
178
179 hr = PathCanonicalizeForComparison(L"\\\\.\\UNC\\server\\share\\..\\unc.exe", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
180 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
181 NativeAssert::StringEqual(L"\\\\?\\UNC\\server\\share\\unc.exe", sczCanonicalized);
182
183 hr = PathCanonicalizeForComparison(L"\\\\..\\share\\otherdir\\unc.exe", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
184 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
185 NativeAssert::StringEqual(L"\\\\..\\share\\otherdir\\unc.exe", sczCanonicalized);
186
187 hr = PathCanonicalizeForComparison(L"\\\\..\\share\\otherdir\\unc.exe", 0, &sczCanonicalized);
188 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
189 NativeAssert::StringEqual(L"\\\\share\\otherdir\\unc.exe", sczCanonicalized);
190
191 hr = PathCanonicalizeForComparison(L"\\\\.\\UNC\\share\\otherdir\\unc.exe", 0, &sczCanonicalized);
192 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
193 NativeAssert::StringEqual(L"\\\\UNC\\share\\otherdir\\unc.exe", sczCanonicalized);
194
195 hr = PathCanonicalizeForComparison(L"\\\\server\\share\\..\\..\\otherdir\\unc.exe", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
196 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
197 NativeAssert::StringEqual(L"\\\\server\\share\\otherdir\\unc.exe", sczCanonicalized);
198
199 hr = PathCanonicalizeForComparison(L"\\\\server\\share\\..\\..\\otherdir\\unc.exe", 0, &sczCanonicalized);
200 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
201 NativeAssert::StringEqual(L"\\\\otherdir\\unc.exe", sczCanonicalized);
202
203 hr = PathCanonicalizeForComparison(L"\\??\\UNC\\server\\share\\dir", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
204 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
205 NativeAssert::StringEqual(L"\\\\?\\UNC\\server\\share\\dir", sczCanonicalized);
206
207 hr = PathCanonicalizeForComparison(L"\\\\?\\UNC\\server\\share\\..\\..\\otherdir\\unc.exe", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
208 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
209 NativeAssert::StringEqual(L"\\\\?\\UNC\\server\\share\\otherdir\\unc.exe", sczCanonicalized);
210
211 hr = PathCanonicalizeForComparison(L"\\\\?\\UNC\\server\\share\\..\\..\\otherdir\\unc.exe", 0, &sczCanonicalized);
212 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
213 NativeAssert::StringEqual(L"\\\\otherdir\\unc.exe", sczCanonicalized);
214
215 hr = PathCanonicalizeForComparison(L"C:\\dir\\subdir\\..\\..\\..\\otherdir\\pastroot.exe", 0, &sczCanonicalized);
216 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
217 NativeAssert::StringEqual(L"C:\\otherdir\\pastroot.exe", sczCanonicalized);
218
219 hr = PathCanonicalizeForComparison(L"\\\\?\\C:\\dir\\subdir\\..\\..\\..\\otherdir\\pastroot.exe", 0, &sczCanonicalized);
220 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
221 NativeAssert::StringEqual(L"C:\\otherdir\\pastroot.exe", sczCanonicalized);
222
223 hr = PathCanonicalizeForComparison(L"\\\\?\\C:dir\\subdir\\..\\..\\..\\otherdir\\pastroot.exe", 0, &sczCanonicalized);
224 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
225 NativeAssert::StringEqual(L"\\otherdir\\pastroot.exe", sczCanonicalized);
226
227 hr = PathCanonicalizeForComparison(L"C:dir\\subdir\\..\\..\\..\\otherdir\\pastrelativeroot.exe", 0, &sczCanonicalized);
228 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
229 NativeAssert::StringEqual(L"\\otherdir\\pastrelativeroot.exe", sczCanonicalized);
230
231 hr = PathCanonicalizeForComparison(L"A:dir\\subdir\\..\\..\\otherdir\\relativeroot.exe", 0, &sczCanonicalized);
232 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
233 NativeAssert::StringEqual(L"\\otherdir\\relativeroot.exe", sczCanonicalized);
234
235 hr = PathCanonicalizeForComparison(L"C:dir\\subdir\\otherdir\\relativeroot.exe", 0, &sczCanonicalized);
236 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
237 NativeAssert::StringEqual(L"C:dir\\subdir\\otherdir\\relativeroot.exe", sczCanonicalized);
238
239 hr = PathCanonicalizeForComparison(L"C:\\dir\\subdir\\..\\..\\otherdir\\backslashes.exe", 0, &sczCanonicalized);
240 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
241 NativeAssert::StringEqual(L"C:\\otherdir\\backslashes.exe", sczCanonicalized);
242
243 hr = PathCanonicalizeForComparison(L"C:\\dir\\subdir\\..\\..\\otherdir\\\\consecutivebackslashes.exe", 0, &sczCanonicalized);
244 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
245 NativeAssert::StringEqual(L"C:\\otherdir\\consecutivebackslashes.exe", sczCanonicalized);
246
247 hr = PathCanonicalizeForComparison(L"C:/dir/subdir/../../otherdir/forwardslashes.exe", 0, &sczCanonicalized);
248 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
249 NativeAssert::StringEqual(L"C:\\otherdir\\forwardslashes.exe", sczCanonicalized);
250
251 hr = PathCanonicalizeForComparison(L"\\\\?\\C:\\test\\..\\validlongpath.exe", 0, &sczCanonicalized);
252 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
253 NativeAssert::StringEqual(L"C:\\validlongpath.exe", sczCanonicalized);
254
255 hr = PathCanonicalizeForComparison(L"\\\\?\\test\\..\\invalidlongpath.exe", 0, &sczCanonicalized);
256 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
257 NativeAssert::StringEqual(L"\\\\?\\invalidlongpath.exe", sczCanonicalized);
258
259 hr = PathCanonicalizeForComparison(L"\\??\\test\\..\\invalidlongpath.exe", 0, &sczCanonicalized);
260 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
261 NativeAssert::StringEqual(L"\\\\?\\invalidlongpath.exe", sczCanonicalized);
262
263 hr = PathCanonicalizeForComparison(L"C:\\.\\invalid:pathchars?.exe", 0, &sczCanonicalized);
264 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
265 NativeAssert::StringEqual(L"C:\\invalid:pathchars?.exe", sczCanonicalized);
266
267 hr = PathCanonicalizeForComparison(L"C:\\addprefix.exe", PATH_CANONICALIZE_APPEND_EXTENDED_PATH_PREFIX, &sczCanonicalized);
268 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
269 NativeAssert::StringEqual(L"\\\\?\\C:\\addprefix.exe", sczCanonicalized);
270
271 hr = PathCanonicalizeForComparison(L"C:\\addbackslash.exe", PATH_CANONICALIZE_BACKSLASH_TERMINATE, &sczCanonicalized);
272 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
273 NativeAssert::StringEqual(L"C:\\addbackslash.exe\\", sczCanonicalized);
274 }
275 finally
276 {
277 ReleaseStr(sczCanonicalized);
278 }
279 }
280
281 [Fact]
282 void PathAllocCanonicalizePathTest()
283 {
284 HRESULT hr = S_OK;
285 LPWSTR sczCanonicalized = NULL;
286
287 try
288 {
289 hr = PathAllocCanonicalizePath(L"C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized);
290 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
291 NativeAssert::StringEqual(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized);
292
293 hr = PathAllocCanonicalizePath(L"abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized);
294 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
295 NativeAssert::StringEqual(L"abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized);
296
297 hr = PathAllocCanonicalizePath(L"\\\\server\\share\\..\\..\\otherdir\\unc.exe", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized);
298 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
299 NativeAssert::StringEqual(L"\\\\otherdir\\unc.exe", sczCanonicalized); // This is surprising.
300
301 hr = PathAllocCanonicalizePath(L"C:\\dir\\subdir\\..\\..\\otherdir\\backslashes.exe", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized);
302 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
303 NativeAssert::StringEqual(L"C:\\otherdir\\backslashes.exe", sczCanonicalized);
304
305 hr = PathAllocCanonicalizePath(L"C:/dir/subdir/../../otherdir/forwardslashes.exe", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized);
306 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
307 NativeAssert::StringEqual(L"C:/dir/subdir/../../otherdir/forwardslashes.exe", sczCanonicalized);
308
309 hr = PathAllocCanonicalizePath(L"\\\\?\\C:\\test\\..\\validlongpath.exe", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized);
310 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
311 NativeAssert::StringEqual(L"C:\\validlongpath.exe", sczCanonicalized);
312
313 hr = PathAllocCanonicalizePath(L"\\\\?\\test\\..\\invalidlongpath.exe", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized);
314 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
315 NativeAssert::StringEqual(L"\\\\?\\invalidlongpath.exe", sczCanonicalized);
316
317 hr = PathAllocCanonicalizePath(L"C:\\.\\invalid:pathchars?.exe", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized);
318 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
319 NativeAssert::StringEqual(L"C:\\invalid:pathchars?.exe", sczCanonicalized);
320 }
321 finally
322 {
323 ReleaseStr(sczCanonicalized);
324 }
325 }
326
327 [Fact]
328 void PathConcatTest()
329 {
330 HRESULT hr = S_OK;
331 LPWSTR sczPath = NULL;
332 LPCWSTR rgwzPaths[54] =
333 {
334 L"a", NULL, L"a",
335 L"a", L"", L"a",
336 L"C:\\", L"a", L"C:\\a",
337 L"\\a", L"b", L"\\a\\b",
338 L"a", L"b", L"a\\b",
339 L"C:\\", L"..\\a", L"C:\\..\\a",
340 L"C:\\a", L"..\\b", L"C:\\a\\..\\b",
341 L"\\\\server\\share", L"..\\a", L"\\\\server\\share\\..\\a",
342 L"\\\\server\\share\\a", L"..\\b", L"\\\\server\\share\\a\\..\\b",
343 NULL, L"b", L"b",
344 L"", L"b", L"b",
345 L"a", L"\\b", L"\\b",
346 L"a", L"b:", L"b:",
347 L"a", L"b:\\", L"b:\\",
348 L"a", L"\\\\?\\b", L"\\\\?\\b",
349 L"a", L"\\\\?\\UNC\\b", L"\\\\?\\UNC\\b",
350 L"a", L"\\b", L"\\b",
351 L"a", L"\\\\", L"\\\\",
352 };
353
354 try
355 {
356 for (DWORD i = 0; i < countof(rgwzPaths); i += 3)
357 {
358 hr = PathConcat(rgwzPaths[i], rgwzPaths[i + 1], &sczPath);
359 NativeAssert::Succeeded(hr, "PathConcat: {0}, {1}", rgwzPaths[i], rgwzPaths[i + 1]);
360 NativeAssert::StringEqual(rgwzPaths[i + 2], sczPath);
361 }
362 }
363 finally
364 {
365 ReleaseStr(sczPath);
366 }
367 }
368
369 [Fact]
370 void PathCompareCanonicalizeEqualTest()
371 {
372 HRESULT hr = S_OK;
373 LPWSTR sczPath = NULL;
374 BOOL fEqual = FALSE;
375 LPCWSTR rgwzPaths[14] =
376 {
377 L"C:\\simplepath", L"C:\\simplepath",
378 L"\\\\server\\share\\dir\\dir2\\..\\otherdir\\unc.exe", L"\\\\server\\share\\dir\\otherdir\\unc.exe",
379 L"\\\\server\\share\\..\\..\\otherdir\\unc.exe", L"\\\\server\\share\\otherdir\\unc.exe",
380 L"\\\\?\\UNC\\server\\share\\..\\..\\otherdir\\unc.exe", L"\\\\?\\UNC\\server\\share\\otherdir\\unc.exe",
381 L"C:\\dir\\subdir\\..\\..\\..\\otherdir\\pastroot.exe", L"C:\\otherdir\\pastroot.exe",
382 L"\\\\?\\C:\\dir\\subdir\\..\\..\\..\\otherdir\\pastroot.exe", L"C:\\..\\otherdir\\pastroot.exe",
383 L"\\??\\C:\\dir", L"\\\\?\\C:\\dir",
384 };
385
386 try
387 {
388 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
389 {
390 hr = PathCompareCanonicalized(rgwzPaths[i], rgwzPaths[i + 1], &fEqual);
391 NativeAssert::Succeeded(hr, "PathCompareCanonicalized: {0}, {1}", rgwzPaths[i], rgwzPaths[i + 1]);
392 Assert::True(fEqual, String::Format("PathCompareCanonicalized: {0}, {1}", gcnew String(rgwzPaths[i]), gcnew String(rgwzPaths[i + 1])));
393 }
394 }
395 finally
396 {
397 ReleaseStr(sczPath);
398 }
399 }
400
401 [Fact]
402 void PathCompareCanonicalizeNotEqualTest()
403 {
404 HRESULT hr = S_OK;
405 LPWSTR sczPath = NULL;
406 BOOL fEqual = FALSE;
407 LPCWSTR rgwzPaths[8] =
408 {
409 L"C:\\simplepath", L"D:\\simplepath",
410 L"\\\\..\\share\\otherdir\\unc.exe", L"\\\\share\\otherdir\\unc.exe",
411 L"\\\\server\\.\\otherdir\\unc.exe", L"\\\\server\\otherdir\\unc.exe",
412 L"\\\\server\\\\otherdir\\unc.exe", L"\\\\server\\otherdir\\unc.exe",
413 };
414
415 try
416 {
417 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
418 {
419 hr = PathCompareCanonicalized(rgwzPaths[i], rgwzPaths[i + 1], &fEqual);
420 NativeAssert::Succeeded(hr, "PathCompareCanonicalized: {0}, {1}", rgwzPaths[i], rgwzPaths[i + 1]);
421 Assert::False(fEqual, String::Format("PathCompareCanonicalized: {0}, {1}", gcnew String(rgwzPaths[i]), gcnew String(rgwzPaths[i + 1])));
422 }
423 }
424 finally
425 {
426 ReleaseStr(sczPath);
427 }
428 }
429
430 [Fact]
431 void PathConcatRelativeToBaseTest()
432 {
433 HRESULT hr = S_OK;
434 LPWSTR sczPath = NULL;
435 LPCWSTR rgwzPaths[27] =
436 {
437 L"a", NULL, L"a",
438 L"a", L"", L"a",
439 L"C:\\", L"a", L"C:\\a",
440 L"\\a", L"b", L"\\a\\b",
441 L"a", L"b", L"a\\b",
442 L"C:\\", L"..\\a", L"C:\\a",
443 L"C:\\a", L"..\\b", L"C:\\a\\b",
444 L"\\\\server\\share", L"..\\a", L"\\\\server\\share\\a",
445 L"\\\\server\\share\\a", L"..\\b", L"\\\\server\\share\\a\\b",
446 };
447
448 try
449 {
450 for (DWORD i = 0; i < countof(rgwzPaths); i += 3)
451 {
452 hr = PathConcatRelativeToBase(rgwzPaths[i], rgwzPaths[i + 1], &sczPath);
453 NativeAssert::Succeeded(hr, "PathConcatRelativeToBase: {0}, {1}", rgwzPaths[i], rgwzPaths[i + 1]);
454 NativeAssert::StringEqual(rgwzPaths[i + 2], sczPath);
455 }
456 }
457 finally
458 {
459 ReleaseStr(sczPath);
460 }
461 }
462
463 [Fact]
464 void PathConcatRelativeToBaseFailureTest()
465 {
466 HRESULT hr = S_OK;
467 LPWSTR sczPath = NULL;
468 LPCWSTR rgwzPaths[18] =
469 {
470 NULL, L"b",
471 L"", L"b",
472 L"a", L"\\b",
473 L"a", L"b:",
474 L"a", L"b:\\",
475 L"a", L"\\\\?\\b",
476 L"a", L"\\\\?\\UNC\\b",
477 L"a", L"\\b",
478 L"a", L"\\\\",
479 };
480
481 try
482 {
483 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
484 {
485 hr = PathConcatRelativeToBase(rgwzPaths[i], rgwzPaths[i + 1], &sczPath);
486 NativeAssert::SpecificReturnCode(hr, E_INVALIDARG, "PathConcatRelativeToBase: {0}, {1}", rgwzPaths[i], rgwzPaths[i + 1]);
487 }
488 }
489 finally
490 {
491 ReleaseStr(sczPath);
492 }
493 }
494
495 [Fact]
496 void PathDirectoryContainsPathTest()
497 {
498 HRESULT hr = S_OK;
499
500 hr = PathDirectoryContainsPath(L"", L"");
501 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
502
503 hr = PathDirectoryContainsPath(L"C:\\Directory", L"");
504 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
505
506 hr = PathDirectoryContainsPath(L"", L"C:\\Directory");
507 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
508
509 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\Directory");
510 Assert::Equal<HRESULT>(S_FALSE, hr);
511
512 hr = PathDirectoryContainsPath(L"C:\\Dir", L"C:\\Directory");
513 Assert::Equal<HRESULT>(S_FALSE, hr);
514
515 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\");
516 Assert::Equal<HRESULT>(S_FALSE, hr);
517
518 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\DirectoryPlus");
519 Assert::Equal<HRESULT>(S_FALSE, hr);
520
521 hr = PathDirectoryContainsPath(L"C:\\Directory\\", L"C:\\DirectoryPlus");
522 Assert::Equal<HRESULT>(S_FALSE, hr);
523
524 hr = PathDirectoryContainsPath(L"C:\\Directory\\", L"C:\\Directory\\../Plus");
525 Assert::Equal<HRESULT>(S_FALSE, hr);
526
527 hr = PathDirectoryContainsPath(L"C:\\Directory\\", L"C:\\Directory/../Plus");
528 Assert::Equal<HRESULT>(S_FALSE, hr);
529
530 hr = PathDirectoryContainsPath(L"\\\\server\\share\\Directory", L"\\\\server\\share\\DirectoryPlus");
531 Assert::Equal<HRESULT>(S_FALSE, hr);
532
533 hr = PathDirectoryContainsPath(L"\\\\server\\share\\Directory", L"\\\\discarded\\..\\server\\share\\Directory\\Plus");
534 Assert::Equal<HRESULT>(S_FALSE, hr);
535
536 hr = PathDirectoryContainsPath(L"..\\..", L"..\\..\\plus");
537 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
538
539 hr = PathDirectoryContainsPath(L"..\\..", L"\\..\\..\\plus");
540 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
541
542 hr = PathDirectoryContainsPath(L"\\..\\..", L"\\..\\..\\plus");
543 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
544
545 hr = PathDirectoryContainsPath(L"C:..\\..", L"C:..\\..\\plus");
546 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
547
548 hr = PathDirectoryContainsPath(L"\\\\server\\share\\Directory", L"\\\\server\\share\\Directory\\Plus");
549 Assert::Equal<HRESULT>(S_OK, hr);
550
551 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\directory\\plus");
552 Assert::Equal<HRESULT>(S_OK, hr);
553
554 hr = PathDirectoryContainsPath(L"C:\\Directory\\", L"C:\\Directory\\Plus");
555 Assert::Equal<HRESULT>(S_OK, hr);
556
557 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\.\\Directory\\Plus");
558 Assert::Equal<HRESULT>(S_OK, hr);
559
560 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\Directory/Plus");
561 Assert::Equal<HRESULT>(S_OK, hr);
562
563 hr = PathDirectoryContainsPath(L"C:\\Directory\\", L"C:\\Directory/Plus");
564 Assert::Equal<HRESULT>(S_OK, hr);
565
566 hr = PathDirectoryContainsPath(L"\\\\?\\C:\\Directory", L"C:\\Directory\\Plus");
567 Assert::Equal<HRESULT>(S_OK, hr);
568 }
569
570 [Fact]
571 void PathExpandEnvironmentVariablesTest()
572 {
573 HRESULT hr = S_OK;
574 LPWSTR sczExpanded = NULL;
575 LPCWSTR rgwzPaths[4] =
576 {
577 L"", L"",
578 L"\\\\?\\", L"%TEMP%;%PATH%;C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789",
579 };
580
581 try
582 {
583 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
584 {
585 hr = PathExpand(&sczExpanded, rgwzPaths[i + 1], PATH_EXPAND_ENVIRONMENT);
586 NativeAssert::Succeeded(hr, "PathExpand: {0}", rgwzPaths[i + 1]);
587 WixAssert::StringEqual((gcnew String(rgwzPaths[i])) + Environment::ExpandEnvironmentVariables(gcnew String(rgwzPaths[i + 1])), gcnew String(sczExpanded), false);
588 }
589 }
590 finally
591 {
592 ReleaseStr(sczExpanded);
593 }
594 }
595
596 [Fact]
597 void PathExpandFullPathTest()
598 {
599 HRESULT hr = S_OK;
600 LPWSTR sczExpanded = NULL;
601 LPCWSTR wzGreaterThanMaxPathString = L"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\\a.txt";
602
603 try
604 {
605 hr = PathExpand(&sczExpanded, wzGreaterThanMaxPathString, PATH_EXPAND_FULLPATH);
606 NativeAssert::Succeeded(hr, "Failed to expand greater than MAX_PATH string.");
607 WixAssert::StringEqual((gcnew String("\\\\?\\")) + Path::Combine(Environment::CurrentDirectory, gcnew String(wzGreaterThanMaxPathString)), gcnew String(sczExpanded), false);
608 }
609 finally
610 {
611 ReleaseStr(sczExpanded);
612 }
613 }
614
615 [Fact]
616 void PathExpandAllTest()
617 {
618 HRESULT hr = S_OK;
619 LPWSTR sczExpanded = NULL;
620 LPCWSTR wzRelativeEnvironmentVariableString = L"%USERNAME%\\abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\\a.txt";
621
622 try
623 {
624 hr = PathExpand(&sczExpanded, wzRelativeEnvironmentVariableString, PATH_EXPAND_ENVIRONMENT | PATH_EXPAND_FULLPATH);
625 NativeAssert::Succeeded(hr, "Failed to expand path.");
626 WixAssert::StringEqual((gcnew String("\\\\?\\")) + Path::Combine(Environment::CurrentDirectory, Environment::ExpandEnvironmentVariables(gcnew String(wzRelativeEnvironmentVariableString))), gcnew String(sczExpanded), false);
627 }
628 finally
629 {
630 ReleaseStr(sczExpanded);
631 }
632 }
633
634 [Fact]
635 void PathForCurrentProcessTest()
636 {
637 HRESULT hr = S_OK;
638 LPWSTR sczPath = NULL;
639
640 try
641 {
642 hr = PathForCurrentProcess(&sczPath, NULL);
643 NativeAssert::Succeeded(hr, "Failed to get current process path.");
644
645 WixAssert::StringEqual(System::Diagnostics::Process::GetCurrentProcess()->MainModule->FileName, gcnew String(sczPath), false);
646 }
647 finally
648 {
649 ReleaseStr(sczPath);
650 }
651 }
652
653 [Fact]
654 void PathGetDirectoryTest()
655 {
656 HRESULT hr = S_OK;
657 LPWSTR sczPath = NULL;
658 LPCWSTR rgwzPaths[20] =
659 {
660 L"C:\\a\\b", L"C:\\a\\",
661 L"C:\\a\\b\\", L"C:\\a\\b\\",
662 L"C:\\a", L"C:\\",
663 L"C:\\", L"C:\\",
664 L"\"C:\\a\\b\\c\"", L"\"C:\\a\\b\\",
665 L"\"C:\\a\\b\\\"c", L"\"C:\\a\\b\\",
666 L"\"C:\\a\\b\"\\c", L"\"C:\\a\\b\"\\",
667 L"\"C:\\a\\\"b\\c", L"\"C:\\a\\\"b\\",
668 L"C:\\a\"\\\"b\\c", L"C:\\a\"\\\"b\\",
669 L"C:\\a\"\\b\\c\"", L"C:\\a\"\\b\\",
670 };
671
672 try
673 {
674 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
675 {
676 hr = PathGetDirectory(rgwzPaths[i], &sczPath);
677 NativeAssert::Succeeded(hr, "PathGetDirectory: {0}", rgwzPaths[i]);
678 NativeAssert::StringEqual(rgwzPaths[i + 1], sczPath);
679 }
680 }
681 finally
682 {
683 ReleaseStr(sczPath);
684 }
685 }
686
687 [Fact]
688 void PathGetParentPathTest()
689 {
690 HRESULT hr = S_OK;
691 LPWSTR sczPath = NULL;
692 LPCWSTR rgwzPaths[20] =
693 {
694 L"C:\\a\\b", L"C:\\a\\",
695 L"C:\\a\\b\\", L"C:\\a\\",
696 L"C:\\a", L"C:\\",
697 L"C:\\", NULL,
698 L"\"C:\\a\\b\\c\"", L"\"C:\\a\\b\\",
699 L"\"C:\\a\\b\\\"c", L"\"C:\\a\\b\\",
700 L"\"C:\\a\\b\"\\c", L"\"C:\\a\\b\"\\",
701 L"\"C:\\a\\\"b\\c", L"\"C:\\a\\\"b\\",
702 L"C:\\a\"\\\"b\\c", L"C:\\a\"\\\"b\\",
703 L"C:\\a\"\\b\\c\"", L"C:\\a\"\\b\\",
704 };
705
706 try
707 {
708 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
709 {
710 hr = PathGetParentPath(rgwzPaths[i], &sczPath, NULL);
711 NativeAssert::Succeeded(hr, "PathGetParentPath: {0}", rgwzPaths[i]);
712 NativeAssert::StringEqual(rgwzPaths[i + 1], sczPath);
713 }
714 }
715 finally
716 {
717 ReleaseStr(sczPath);
718 }
719 }
720
721 [Fact]
722 void PathGetFullPathNameTest()
723 {
724 HRESULT hr = S_OK;
725 LPWSTR sczPath = NULL;
726 LPCWSTR wzFileName = NULL;
727 LPCWSTR rgwzPaths[33] =
728 {
729 L"C:\\", L"C:\\", NULL,
730 L"C:\\file", L"C:\\file", L"file",
731 L"C:\\..\\file", L"C:\\file", L"file",
732 L"C:\\dir\\..\\file.txt", L"C:\\file.txt", L"file.txt",
733 L"C:\\dir\\\\file.txt.txt", L"C:\\dir\\file.txt.txt", L"file.txt.txt",
734 L"C:\\dir/.file", L"C:\\dir\\.file", L".file",
735 L"\\\\?\\C:\\file", L"\\\\?\\C:\\file", L"file",
736 L"\\\\server\\share\\file", L"\\\\server\\share\\file", L"file",
737 L"\\\\server\\share\\..\\file", L"\\\\server\\share\\file", L"file",
738 L"\\\\?\\UNC\\server\\share\\file", L"\\\\?\\UNC\\server\\share\\file", L"file",
739 L"C:\\abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\\a.txt", L"C:\\abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\\a.txt", L"a.txt",
740 };
741
742 try
743 {
744 for (DWORD i = 0; i < countof(rgwzPaths); i += 3)
745 {
746 hr = PathGetFullPathName(rgwzPaths[i], &sczPath, &wzFileName, NULL);
747 NativeAssert::Succeeded(hr, "PathGetFullPathName: {0}", rgwzPaths[i]);
748 NativeAssert::StringEqual(rgwzPaths[i + 1], sczPath);
749 NativeAssert::StringEqual(rgwzPaths[i + 2], wzFileName);
750 }
751 }
752 finally
753 {
754 ReleaseStr(sczPath);
755 }
756 }
757
758 [Fact]
759 void PathGetFullPathNameRelativeTest()
760 {
761 HRESULT hr = S_OK;
762 LPWSTR sczPath = NULL;
763 LPCWSTR rgwzPaths[4] =
764 {
765 L"",
766 L"a.txt",
767 L"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\\a.txt",
768 };
769
770 try
771 {
772 for (DWORD i = 0; i < countof(rgwzPaths); ++i)
773 {
774 hr = PathGetFullPathName(rgwzPaths[i], &sczPath, NULL, NULL);
775 NativeAssert::Succeeded(hr, "PathGetFullPathName: {0}", rgwzPaths[i]);
776 WixAssert::StringEqual(Path::Combine(Environment::CurrentDirectory, gcnew String(rgwzPaths[i])), gcnew String(sczPath), false);
777 }
778 }
779 finally
780 {
781 ReleaseStr(sczPath);
782 }
783 }
784
785 [Fact]
786 void PathGetHierarchyArrayTest()
787 {
788 HRESULT hr = S_OK;
789 LPWSTR *rgsczPaths = NULL;
790 UINT cPaths = 0;
791
792 try
793 {
794 hr = PathGetHierarchyArray(L"c:\\foo\\bar\\bas\\a.txt", &rgsczPaths, &cPaths);
795 NativeAssert::Succeeded(hr, "Failed to get parent directories array for regular file path");
796 Assert::Equal<DWORD>(5, cPaths);
797 NativeAssert::StringEqual(L"c:\\", rgsczPaths[0]);
798 NativeAssert::StringEqual(L"c:\\foo\\", rgsczPaths[1]);
799 NativeAssert::StringEqual(L"c:\\foo\\bar\\", rgsczPaths[2]);
800 NativeAssert::StringEqual(L"c:\\foo\\bar\\bas\\", rgsczPaths[3]);
801 NativeAssert::StringEqual(L"c:\\foo\\bar\\bas\\a.txt", rgsczPaths[4]);
802 ReleaseNullStrArray(rgsczPaths, cPaths);
803
804 hr = PathGetHierarchyArray(L"c:\\foo\\bar\\bas\\", &rgsczPaths, &cPaths);
805 NativeAssert::Succeeded(hr, "Failed to get parent directories array for regular directory path");
806 Assert::Equal<DWORD>(4, cPaths);
807 NativeAssert::StringEqual(L"c:\\", rgsczPaths[0]);
808 NativeAssert::StringEqual(L"c:\\foo\\", rgsczPaths[1]);
809 NativeAssert::StringEqual(L"c:\\foo\\bar\\", rgsczPaths[2]);
810 NativeAssert::StringEqual(L"c:\\foo\\bar\\bas\\", rgsczPaths[3]);
811 ReleaseNullStrArray(rgsczPaths, cPaths);
812
813 hr = PathGetHierarchyArray(L"\\\\server\\share\\subdir\\file.txt", &rgsczPaths, &cPaths);
814 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC file path");
815 Assert::Equal<DWORD>(3, cPaths);
816 NativeAssert::StringEqual(L"\\\\server\\share\\", rgsczPaths[0]);
817 NativeAssert::StringEqual(L"\\\\server\\share\\subdir\\", rgsczPaths[1]);
818 NativeAssert::StringEqual(L"\\\\server\\share\\subdir\\file.txt", rgsczPaths[2]);
819 ReleaseNullStrArray(rgsczPaths, cPaths);
820
821 hr = PathGetHierarchyArray(L"\\\\server\\share\\subdir\\", &rgsczPaths, &cPaths);
822 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path");
823 Assert::Equal<DWORD>(2, cPaths);
824 NativeAssert::StringEqual(L"\\\\server\\share\\", rgsczPaths[0]);
825 NativeAssert::StringEqual(L"\\\\server\\share\\subdir\\", rgsczPaths[1]);
826 ReleaseNullStrArray(rgsczPaths, cPaths);
827
828 hr = PathGetHierarchyArray(L"Software\\Microsoft\\Windows\\ValueName", &rgsczPaths, &cPaths);
829 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path");
830 Assert::Equal<DWORD>(4, cPaths);
831 NativeAssert::StringEqual(L"Software\\", rgsczPaths[0]);
832 NativeAssert::StringEqual(L"Software\\Microsoft\\", rgsczPaths[1]);
833 NativeAssert::StringEqual(L"Software\\Microsoft\\Windows\\", rgsczPaths[2]);
834 NativeAssert::StringEqual(L"Software\\Microsoft\\Windows\\ValueName", rgsczPaths[3]);
835 ReleaseNullStrArray(rgsczPaths, cPaths);
836
837 hr = PathGetHierarchyArray(L"Software\\Microsoft\\Windows\\", &rgsczPaths, &cPaths);
838 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path");
839 Assert::Equal<DWORD>(3, cPaths);
840 NativeAssert::StringEqual(L"Software\\", rgsczPaths[0]);
841 NativeAssert::StringEqual(L"Software\\Microsoft\\", rgsczPaths[1]);
842 NativeAssert::StringEqual(L"Software\\Microsoft\\Windows\\", rgsczPaths[2]);
843 ReleaseNullStrArray(rgsczPaths, cPaths);
844
845 hr = PathGetHierarchyArray(L"Software", &rgsczPaths, &cPaths);
846 NativeAssert::Succeeded(hr, "Failed to get parent directories array for relative path");
847 Assert::Equal<DWORD>(1, cPaths);
848 NativeAssert::StringEqual(L"Software", rgsczPaths[0]);
849 ReleaseNullStrArray(rgsczPaths, cPaths);
850
851 hr = PathGetHierarchyArray(L"c:/foo/bar/bas/a.txt", &rgsczPaths, &cPaths);
852 NativeAssert::Succeeded(hr, "Failed to get parent directories array for regular file path");
853 Assert::Equal<DWORD>(5, cPaths);
854 NativeAssert::StringEqual(L"c:/", rgsczPaths[0]);
855 NativeAssert::StringEqual(L"c:/foo/", rgsczPaths[1]);
856 NativeAssert::StringEqual(L"c:/foo/bar/", rgsczPaths[2]);
857 NativeAssert::StringEqual(L"c:/foo/bar/bas/", rgsczPaths[3]);
858 NativeAssert::StringEqual(L"c:/foo/bar/bas/a.txt", rgsczPaths[4]);
859 ReleaseNullStrArray(rgsczPaths, cPaths);
860
861 hr = PathGetHierarchyArray(L"c:/foo/bar/bas/", &rgsczPaths, &cPaths);
862 NativeAssert::Succeeded(hr, "Failed to get parent directories array for regular directory path");
863 Assert::Equal<DWORD>(4, cPaths);
864 NativeAssert::StringEqual(L"c:/", rgsczPaths[0]);
865 NativeAssert::StringEqual(L"c:/foo/", rgsczPaths[1]);
866 NativeAssert::StringEqual(L"c:/foo/bar/", rgsczPaths[2]);
867 NativeAssert::StringEqual(L"c:/foo/bar/bas/", rgsczPaths[3]);
868 ReleaseNullStrArray(rgsczPaths, cPaths);
869
870 hr = PathGetHierarchyArray(L"//server/share/subdir/file.txt", &rgsczPaths, &cPaths);
871 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC file path");
872 Assert::Equal<DWORD>(3, cPaths);
873 NativeAssert::StringEqual(L"//server/share/", rgsczPaths[0]);
874 NativeAssert::StringEqual(L"//server/share/subdir/", rgsczPaths[1]);
875 NativeAssert::StringEqual(L"//server/share/subdir/file.txt", rgsczPaths[2]);
876 ReleaseNullStrArray(rgsczPaths, cPaths);
877
878 hr = PathGetHierarchyArray(L"//server/share/subdir/", &rgsczPaths, &cPaths);
879 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path");
880 Assert::Equal<DWORD>(2, cPaths);
881 NativeAssert::StringEqual(L"//server/share/", rgsczPaths[0]);
882 NativeAssert::StringEqual(L"//server/share/subdir/", rgsczPaths[1]);
883 ReleaseNullStrArray(rgsczPaths, cPaths);
884
885 hr = PathGetHierarchyArray(L"Software/Microsoft/Windows/ValueName", &rgsczPaths, &cPaths);
886 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path");
887 Assert::Equal<DWORD>(4, cPaths);
888 NativeAssert::StringEqual(L"Software/", rgsczPaths[0]);
889 NativeAssert::StringEqual(L"Software/Microsoft/", rgsczPaths[1]);
890 NativeAssert::StringEqual(L"Software/Microsoft/Windows/", rgsczPaths[2]);
891 NativeAssert::StringEqual(L"Software/Microsoft/Windows/ValueName", rgsczPaths[3]);
892 ReleaseNullStrArray(rgsczPaths, cPaths);
893
894 hr = PathGetHierarchyArray(L"Software/Microsoft/Windows/", &rgsczPaths, &cPaths);
895 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path");
896 Assert::Equal<DWORD>(3, cPaths);
897 NativeAssert::StringEqual(L"Software/", rgsczPaths[0]);
898 NativeAssert::StringEqual(L"Software/Microsoft/", rgsczPaths[1]);
899 NativeAssert::StringEqual(L"Software/Microsoft/Windows/", rgsczPaths[2]);
900 ReleaseNullStrArray(rgsczPaths, cPaths);
901 }
902 finally
903 {
904 ReleaseStrArray(rgsczPaths, cPaths);
905 }
906 }
907
908 [Fact]
909 void PathGetSystemTempPathsTest()
910 {
911 HRESULT hr = S_OK;
912 LPWSTR* rgsczPaths = NULL;
913 DWORD cPaths = 0;
914 DWORD cPathsOriginal = 0;
915
916 try
917 {
918 hr = PathGetSystemTempPaths(&rgsczPaths, &cPaths);
919 NativeAssert::Succeeded(hr, "PathGetSystemTempPaths failed.");
920
921 Assert::InRange<DWORD>(cPaths, 1, 3);
922 WixAssert::StringEqual(Environment::ExpandEnvironmentVariables("%windir%\\temp\\"), gcnew String(rgsczPaths[cPaths - 1]), true);
923
924 cPathsOriginal = cPaths;
925
926 hr = PathGetSystemTempPaths(&rgsczPaths, &cPaths);
927 NativeAssert::Succeeded(hr, "PathGetSystemTempPaths failed.");
928 Assert::Equal(cPathsOriginal * 2, cPaths);
929 }
930 finally
931 {
932 ReleaseStrArray(rgsczPaths, cPaths);
933 }
934 }
935
936 [Fact]
937 void PathGetTempPathTest()
938 {
939 HRESULT hr = S_OK;
940 LPCWSTR wzEnvName = L"TMP";
941 LPCWSTR wzEnvName2 = L"TEMP";
942 LPCWSTR wzLongTempPath = L"C:\\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\\cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\\";
943 LPWSTR sczTempPath = NULL;
944 WCHAR wzOriginalTemp[MAX_PATH + 1] = { };
945 WCHAR wzOriginalTemp2[MAX_PATH + 1] = { };
946 DWORD cch = 0;
947 DWORD cch2 = 0;
948 SIZE_T cchTemp = 0;
949 size_t cchTemp2 = 0;
950
951 try
952 {
953 cch = ::GetEnvironmentVariableW(wzEnvName, wzOriginalTemp, countof(wzOriginalTemp));
954 Assert::NotEqual<DWORD>(0, cch);
955
956 if (!::SetEnvironmentVariableW(wzEnvName, wzLongTempPath))
957 {
958 Assert::Equal<DWORD>(0xFFFFFFFF, ::GetLastError());
959 }
960
961 cch2 = ::GetEnvironmentVariableW(wzEnvName2, wzOriginalTemp2, countof(wzOriginalTemp2));
962 Assert::NotEqual<DWORD>(0, cch2);
963
964 hr = PathGetTempPath(&sczTempPath, &cchTemp);
965 NativeAssert::Succeeded(hr, "Failed to get temp path.");
966
967 PathFixedBackslashTerminate(wzOriginalTemp2, countof(wzOriginalTemp2));
968
969 hr = ::StringCchLengthW(wzOriginalTemp2, countof(wzOriginalTemp2), &cchTemp2);
970 NativeAssert::Succeeded(hr, "Failed to get temp path length.");
971
972 NativeAssert::StringEqual(wzOriginalTemp2, sczTempPath);
973 Assert::Equal<SIZE_T>(cchTemp2, cchTemp);
974 }
975 finally
976 {
977 if (cch)
978 {
979 ::SetEnvironmentVariableW(wzEnvName, wzOriginalTemp);
980 }
981
982 ReleaseStr(sczTempPath);
983 }
984 }
985
986 [Fact]
987 void PathGetVolumePathNameTest()
988 {
989 HRESULT hr = S_OK;
990 LPWSTR sczVolumePathName = NULL;
991
992 try
993 {
994 hr = StrAlloc(&sczVolumePathName, 1);
995 NativeAssert::Succeeded(hr, "Failed to alloc volume path name.");
996
997 hr = PathGetVolumePathName(L"C:\\Windows", &sczVolumePathName);
998 NativeAssert::Succeeded(hr, "PathGetVolumePathName failed.");
999
1000 NativeAssert::StringEqual(L"C:\\", sczVolumePathName);
1001 }
1002 finally
1003 {
1004 ReleaseStr(sczVolumePathName);
1005 }
1006 }
1007
1008 [Fact]
1009 void PathNormalizeSlashesFixedTest()
1010 {
1011 HRESULT hr = S_OK;
1012 LPWSTR sczPath = NULL;
1013 LPCWSTR rgwzPaths[54] =
1014 {
1015 L"", L"",
1016 L"\\", L"\\",
1017 L"\\\\", L"\\\\",
1018 L"\\\\\\", L"\\\\\\",
1019 L"\\\\?\\UNC\\", L"\\\\?\\UNC\\",
1020 L"C:\\\\foo2", L"C:\\foo2",
1021 L"\\\\?\\C:\\\\foo2", L"\\\\?\\C:\\foo2",
1022 L"\\\\a\\b\\", L"\\\\a\\b\\",
1023 L"\\\\?\\UNC\\a\\b\\\\c\\", L"\\\\?\\UNC\\a\\b\\c\\",
1024 L"\\\\?\\UNC\\a\\b\\\\", L"\\\\?\\UNC\\a\\b\\",
1025 L"\\\\?\\UNC\\test\\unc\\path\\to\\\\something", L"\\\\?\\UNC\\test\\unc\\path\\to\\something",
1026 L"\\\\?\\C:\\\\foo\\\\bar.txt", L"\\\\?\\C:\\foo\\bar.txt",
1027 L"\\??\\C:\\\\foo\\bar.txt", L"\\??\\C:\\foo\\bar.txt",
1028 L"\\??\\\\C:\\\\foo\\bar.txt", L"\\??\\\\C:\\foo\\bar.txt",
1029 L"/", L"\\",
1030 L"//", L"\\\\",
1031 L"///", L"\\\\\\",
1032 L"//?/UNC/", L"\\\\?\\UNC\\",
1033 L"C://foo2", L"C:\\foo2",
1034 L"//?/C://foo2", L"\\\\?\\C:\\foo2",
1035 L"//a/b/", L"\\\\a\\b\\",
1036 L"//?/UNC/a/b//c/", L"\\\\?\\UNC\\a\\b\\c\\",
1037 L"//?/UNC/a/b//", L"\\\\?\\UNC\\a\\b\\",
1038 L"//?/UNC/test/unc/path/to//something", L"\\\\?\\UNC\\test\\unc\\path\\to\\something",
1039 L"//?/C://foo//bar.txt", L"\\\\?\\C:\\foo\\bar.txt",
1040 L"/??/C://foo/bar.txt", L"\\??\\C:\\foo\\bar.txt",
1041 L"/??//C://foo/bar.txt", L"\\??\\\\C:\\foo\\bar.txt",
1042 };
1043
1044 try
1045 {
1046 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
1047 {
1048 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
1049 NativeAssert::Succeeded(hr, "Failed to copy string");
1050
1051 hr = PathFixedNormalizeSlashes(sczPath);
1052 NativeAssert::Succeeded(hr, "PathNormalizeSlashes: {0}", rgwzPaths[i]);
1053 NativeAssert::StringEqual(rgwzPaths[i + 1], sczPath);
1054 }
1055 }
1056 finally
1057 {
1058 ReleaseStr(sczPath);
1059 }
1060 }
1061
1062 [Fact]
1063 void PathPrefixTest()
1064 {
1065 HRESULT hr = S_OK;
1066 LPWSTR sczPath = NULL;
1067 LPCWSTR rgwzPaths[24] =
1068 {
1069 L"\\\\", L"\\\\?\\UNC\\",
1070 L"C:\\\\foo2", L"\\\\?\\C:\\\\foo2",
1071 L"\\\\a\\b\\", L"\\\\?\\UNC\\a\\b\\",
1072 L"\\\\?\\UNC\\test\\unc\\path\\to\\something", L"\\\\?\\UNC\\test\\unc\\path\\to\\something",
1073 L"\\\\?\\C:\\foo\\bar.txt", L"\\\\?\\C:\\foo\\bar.txt",
1074 L"\\??\\C:\\foo\\bar.txt", L"\\??\\C:\\foo\\bar.txt",
1075 L"//", L"\\\\?\\UNC\\",
1076 L"C://foo2", L"\\\\?\\C://foo2",
1077 L"//a/b/", L"\\\\?\\UNC\\a/b/",
1078 L"//?/UNC/test/unc/path/to/something", L"//?/UNC/test/unc/path/to/something",
1079 L"//?/C:/foo/bar.txt", L"//?/C:/foo/bar.txt",
1080 L"/??/C:/foo/bar.txt", L"/??/C:/foo/bar.txt",
1081 };
1082
1083 try
1084 {
1085 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
1086 {
1087 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
1088 NativeAssert::Succeeded(hr, "Failed to copy string");
1089
1090 hr = PathPrefix(&sczPath, 0, 0);
1091 NativeAssert::Succeeded(hr, "PathPrefix: {0}", rgwzPaths[i]);
1092 NativeAssert::StringEqual(rgwzPaths[i], sczPath);
1093
1094 hr = PathPrefix(&sczPath, 0, PATH_PREFIX_SHORT_PATHS);
1095 NativeAssert::Succeeded(hr, "PathPrefix (SHORT_PATHS): {0}", rgwzPaths[i]);
1096 NativeAssert::StringEqual(rgwzPaths[i + 1], sczPath);
1097 }
1098 }
1099 finally
1100 {
1101 ReleaseStr(sczPath);
1102 }
1103 }
1104
1105 [Fact]
1106 void PathPrefixFailureTest()
1107 {
1108 HRESULT hr = S_OK;
1109 LPWSTR sczPath = NULL;
1110 LPCWSTR rgwzPaths[12] =
1111 {
1112 L"\\",
1113 L"/",
1114 L"C:",
1115 L"C:foo.txt",
1116 L"",
1117 L"\\?",
1118 L"/?",
1119 L"\\dir",
1120 L"/dir",
1121 L"dir",
1122 L"dir\\subdir",
1123 L"dir/subdir",
1124 };
1125
1126 try
1127 {
1128 for (DWORD i = 0; i < countof(rgwzPaths); ++i)
1129 {
1130 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
1131 NativeAssert::Succeeded(hr, "Failed to copy string");
1132
1133 hr = PathPrefix(&sczPath, 0, PATH_PREFIX_EXPECT_FULLY_QUALIFIED);
1134 NativeAssert::SpecificReturnCode(E_INVALIDARG, hr, "PathPrefix: {0}, {1}", rgwzPaths[i], sczPath);
1135 }
1136 }
1137 finally
1138 {
1139 ReleaseStr(sczPath);
1140 }
1141 }
1142
1143 [Fact]
1144 void PathIsRootedAndFullyQualifiedTest()
1145 {
1146 LPCWSTR rgwzPaths[30] =
1147 {
1148 L"//", L"",
1149 L"///", L"",
1150 L"C:/", L"",
1151 L"C://", L"/",
1152 L"C:/foo1", L"foo1",
1153 L"C://foo2", L"/foo2",
1154 L"//test/unc/path/to/something", L"path/to/something",
1155 L"//a/b/c/d/e", L"c/d/e",
1156 L"//a/b/", L"",
1157 L"//a/b", L"",
1158 L"//test/unc", L"",
1159 L"//Server", L"",
1160 L"//Server/Foo.txt", L"",
1161 L"//Server/Share/Foo.txt", L"Foo.txt",
1162 L"//Server/Share/Test/Foo.txt", L"Test/Foo.txt",
1163 };
1164
1165 ValidateSkipPastRoot(rgwzPaths, countof(rgwzPaths), FALSE, TRUE, TRUE);
1166 }
1167
1168 [Fact]
1169 void PathIsRootedAndFullyQualifiedWithPrefixTest()
1170 {
1171 LPCWSTR rgwzPaths[12] =
1172 {
1173 L"//?/UNC/test/unc/path/to/something", L"path/to/something",
1174 L"//?/UNC/test/unc", L"",
1175 L"//?/UNC/a/b1", L"",
1176 L"//?/UNC/a/b2/", L"",
1177 L"//?/C:/foo/bar.txt", L"foo/bar.txt",
1178 L"/??/C:/foo/bar.txt", L"foo/bar.txt",
1179 };
1180
1181 ValidateSkipPastRoot(rgwzPaths, countof(rgwzPaths), TRUE, TRUE, TRUE);
1182 }
1183
1184 [Fact]
1185 void PathIsRootedButNotFullyQualifiedTest()
1186 {
1187 LPCWSTR rgwzPaths[14] =
1188 {
1189 L"/", L"",
1190 L"a:", L"",
1191 L"A:", L"",
1192 L"z:", L"",
1193 L"Z:", L"",
1194 L"C:foo.txt", L"foo.txt",
1195 L"/dir", L"dir",
1196 };
1197
1198 ValidateSkipPastRoot(rgwzPaths, countof(rgwzPaths), FALSE, FALSE, TRUE);
1199 }
1200
1201 [Fact]
1202 void PathIsNotRootedAndNotFullyQualifiedTest()
1203 {
1204 LPCWSTR rgwzPaths[18] =
1205 {
1206 NULL, NULL,
1207 L"", NULL,
1208 L"dir", NULL,
1209 L"dir/subdir", NULL,
1210 L"@:/foo", NULL, // 064 = @ 065 = A
1211 L"[://", NULL, // 091 = [ 090 = Z
1212 L"`:/foo ", NULL, // 096 = ` 097 = a
1213 L"{://", NULL, // 123 = { 122 = z
1214 L"[:", NULL,
1215 };
1216
1217 ValidateSkipPastRoot(rgwzPaths, countof(rgwzPaths), FALSE, FALSE, FALSE);
1218 }
1219
1220 void ValidateSkipPastRoot(LPCWSTR* rgwzPaths, DWORD cPaths, BOOL fExpectedPrefix, BOOL fExpectedFullyQualified, BOOL fExpectedRooted)
1221 {
1222 HRESULT hr = S_OK;
1223 LPWSTR sczPath = NULL;
1224 LPWSTR sczSkipRootPath = NULL;
1225 LPCWSTR wzSkipRootPath = NULL;
1226 BOOL fHasPrefix = FALSE;
1227
1228 try
1229 {
1230 for (DWORD i = 0; i < cPaths; i += 2)
1231 {
1232 wzSkipRootPath = PathSkipPastRoot(rgwzPaths[i], &fHasPrefix, NULL, NULL);
1233 NativeAssert::StringEqual(rgwzPaths[i + 1], wzSkipRootPath);
1234 ValidateExtendedPrefixPath(rgwzPaths[i], fExpectedPrefix, fHasPrefix);
1235 ValidateFullyQualifiedPath(rgwzPaths[i], fExpectedFullyQualified);
1236 ValidateRootedPath(rgwzPaths[i], fExpectedRooted);
1237
1238 if (rgwzPaths[i])
1239 {
1240 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
1241 NativeAssert::Succeeded(hr, "Failed to copy string");
1242
1243 PathFixedReplaceForwardSlashes(sczPath);
1244 }
1245
1246 if (rgwzPaths[i + 1])
1247 {
1248 hr = StrAllocString(&sczSkipRootPath, rgwzPaths[i + 1], 0);
1249 NativeAssert::Succeeded(hr, "Failed to copy string");
1250
1251 PathFixedReplaceForwardSlashes(sczSkipRootPath);
1252 }
1253
1254 wzSkipRootPath = PathSkipPastRoot(sczPath, &fHasPrefix, NULL, NULL);
1255 NativeAssert::StringEqual(sczSkipRootPath, wzSkipRootPath);
1256 ValidateExtendedPrefixPath(sczPath, fExpectedPrefix, fHasPrefix);
1257 ValidateFullyQualifiedPath(sczPath, fExpectedFullyQualified);
1258 ValidateRootedPath(sczPath, fExpectedRooted);
1259 }
1260 }
1261 finally
1262 {
1263 ReleaseStr(sczPath);
1264 ReleaseStr(sczSkipRootPath);
1265 }
1266 }
1267
1268 void ValidateExtendedPrefixPath(LPCWSTR wzPath, BOOL fExpected, BOOL fHasExtendedPrefix)
1269 {
1270 String^ message = String::Format("HasExtendedPrefix: {0}", gcnew String(wzPath));
1271 if (fExpected)
1272 {
1273 Assert::True(fHasExtendedPrefix, message);
1274 }
1275 else
1276 {
1277 Assert::False(fHasExtendedPrefix, message);
1278 }
1279 }
1280
1281 void ValidateFullyQualifiedPath(LPCWSTR wzPath, BOOL fExpected)
1282 {
1283 BOOL fRooted = PathIsFullyQualified(wzPath);
1284 String^ message = String::Format("IsFullyQualified: {0}", gcnew String(wzPath));
1285 if (fExpected)
1286 {
1287 Assert::True(fRooted, message);
1288 }
1289 else
1290 {
1291 Assert::False(fRooted, message);
1292 }
1293 }
1294
1295 void ValidateRootedPath(LPCWSTR wzPath, BOOL fExpected)
1296 {
1297 BOOL fRooted = PathIsRooted(wzPath);
1298 String^ message = String::Format("IsRooted: {0}", gcnew String(wzPath));
1299 if (fExpected)
1300 {
1301 Assert::True(fRooted, message);
1302 }
1303 else
1304 {
1305 Assert::False(fRooted, message);
1306 }
1307 }
1308 };
1309 }