aboutsummaryrefslogtreecommitdiff
path: root/src/libs/dutil/test/DUtilUnitTest
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-05-26 17:33:41 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-05-31 13:20:44 -0500
commitdea25f58e6119ef1acc5c5cc2a7c98e52cdff519 (patch)
tree853368043c98c9f8617744f8d8cb01b7a629e8a9 /src/libs/dutil/test/DUtilUnitTest
parentfb4f8c7108f43d2341ba299424646c4963b21188 (diff)
downloadwix-dea25f58e6119ef1acc5c5cc2a7c98e52cdff519.tar.gz
wix-dea25f58e6119ef1acc5c5cc2a7c98e52cdff519.tar.bz2
wix-dea25f58e6119ef1acc5c5cc2a7c98e52cdff519.zip
Add PathCanonicalizeForComparison.
Diffstat (limited to 'src/libs/dutil/test/DUtilUnitTest')
-rw-r--r--src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj2
-rw-r--r--src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp554
2 files changed, 512 insertions, 44 deletions
diff --git a/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj
index 1c821a7c..c37bdad1 100644
--- a/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj
+++ b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj
@@ -40,7 +40,7 @@
40 40
41 <PropertyGroup> 41 <PropertyGroup>
42 <ProjectAdditionalIncludeDirectories>..\..\WixToolset.DUtil\inc</ProjectAdditionalIncludeDirectories> 42 <ProjectAdditionalIncludeDirectories>..\..\WixToolset.DUtil\inc</ProjectAdditionalIncludeDirectories>
43 <ProjectAdditionalLinkLibraries>rpcrt4.lib;Mpr.lib;Ws2_32.lib;urlmon.lib;wininet.lib</ProjectAdditionalLinkLibraries> 43 <ProjectAdditionalLinkLibraries>rpcrt4.lib;Mpr.lib;Ws2_32.lib;shlwapi.lib;urlmon.lib;wininet.lib</ProjectAdditionalLinkLibraries>
44 </PropertyGroup> 44 </PropertyGroup>
45 45
46 <ItemGroup> 46 <ItemGroup>
diff --git a/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp b/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp
index 65856514..04d0b447 100644
--- a/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp
+++ b/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp
@@ -12,6 +12,290 @@ namespace DutilTests
12 { 12 {
13 public: 13 public:
14 [Fact] 14 [Fact]
15 void PathBackslashFixedTerminateTest()
16 {
17 HRESULT hr = S_OK;
18 WCHAR wzEmpty[1] = { L'\0' };
19 WCHAR wzSingleLetter[1] = { L'a' };
20 WCHAR wzSingleBackslash[1] = { L'\\' };
21 WCHAR wzSingleForwardSlash[1] = { L'/' };
22 WCHAR wzSingleLetterNullTerminated[2] = { L'a', L'\0' };
23 WCHAR wzSingleBackslashNullTerminated[2] = { L'\\', L'\0' };
24 WCHAR wzSingleForwardSlashNullTerminated[2] = { L'/', L'\0' };
25 WCHAR wzExtraSpaceLetterNullTerminated[3] = { L'a', L'\0', L'\0' };
26 WCHAR wzExtraSpaceBackslashNullTerminated[3] = { L'\\', L'\0', L'\0' };
27 WCHAR wzExtraSpaceForwardSlashNullTerminated[3] = { L'/', L'\0', L'\0' };
28
29 hr = PathFixedBackslashTerminate(wzEmpty, 0);
30 NativeAssert::SpecificReturnCode(E_INSUFFICIENT_BUFFER, hr, "PathFixedBackslashTerminate: zero-length, {0}", wzEmpty);
31
32 hr = PathFixedBackslashTerminate(wzEmpty, countof(wzEmpty));
33 NativeAssert::SpecificReturnCode(E_INSUFFICIENT_BUFFER, hr, "PathFixedBackslashTerminate: '' (length 1), {0}", wzEmpty);
34
35 hr = PathFixedBackslashTerminate(wzSingleLetter, countof(wzSingleLetter));
36 NativeAssert::SpecificReturnCode(E_INVALIDARG, hr, "PathFixedBackslashTerminate: 'a' (length 1)");
37
38 hr = PathFixedBackslashTerminate(wzSingleBackslash, countof(wzSingleBackslash));
39 NativeAssert::SpecificReturnCode(E_INVALIDARG, hr, "PathFixedBackslashTerminate: '\\' (length 1)");
40
41 hr = PathFixedBackslashTerminate(wzSingleForwardSlash, countof(wzSingleForwardSlash));
42 NativeAssert::SpecificReturnCode(E_INVALIDARG, hr, "PathFixedBackslashTerminate: '/' (length 1)");
43
44 hr = PathFixedBackslashTerminate(wzSingleLetterNullTerminated, countof(wzSingleLetterNullTerminated));
45 NativeAssert::SpecificReturnCode(E_INSUFFICIENT_BUFFER, hr, "PathFixedBackslashTerminate: 'a' (length 2)");
46
47 hr = PathFixedBackslashTerminate(wzSingleBackslashNullTerminated, countof(wzSingleBackslashNullTerminated));
48 NativeAssert::Succeeded(hr, "PathFixedBackslashTerminate: '\\' (length 2)");
49 NativeAssert::StringEqual(L"\\", wzSingleBackslashNullTerminated);
50
51 hr = PathFixedBackslashTerminate(wzSingleForwardSlashNullTerminated, countof(wzSingleForwardSlashNullTerminated));
52 NativeAssert::Succeeded(hr, "PathFixedBackslashTerminate: '/' (length 2)");
53 NativeAssert::StringEqual(L"\\", wzSingleForwardSlashNullTerminated);
54
55 hr = PathFixedBackslashTerminate(wzExtraSpaceLetterNullTerminated, countof(wzExtraSpaceLetterNullTerminated));
56 NativeAssert::Succeeded(hr, "PathFixedBackslashTerminate: 'a' (length 3)");
57 NativeAssert::StringEqual(L"a\\", wzExtraSpaceLetterNullTerminated);
58
59 hr = PathFixedBackslashTerminate(wzExtraSpaceBackslashNullTerminated, countof(wzExtraSpaceBackslashNullTerminated));
60 NativeAssert::Succeeded(hr, "PathFixedBackslashTerminate: '\\' (length 3)");
61 NativeAssert::StringEqual(L"\\", wzExtraSpaceBackslashNullTerminated);
62
63 hr = PathFixedBackslashTerminate(wzExtraSpaceForwardSlashNullTerminated, countof(wzExtraSpaceForwardSlashNullTerminated));
64 NativeAssert::Succeeded(hr, "PathFixedBackslashTerminate: '/' (length 3)");
65 NativeAssert::StringEqual(L"\\", wzExtraSpaceForwardSlashNullTerminated);
66 }
67
68 [Fact]
69 void PathBackslashTerminateTest()
70 {
71 HRESULT hr = S_OK;
72 LPWSTR sczPath = NULL;
73 LPCWSTR rgwzPaths[16] =
74 {
75 L"", L"\\",
76 L"a", L"a\\",
77 L"\\", L"\\",
78 L"a\\", L"a\\",
79 L"/", L"\\",
80 L"a/", L"a\\",
81 L"\\\\", L"\\\\",
82 L"//", L"/\\",
83 };
84
85 try
86 {
87 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
88 {
89 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
90 NativeAssert::Succeeded(hr, "Failed to copy string");
91
92 hr = PathBackslashTerminate(&sczPath);
93 NativeAssert::Succeeded(hr, "PathBackslashTerminate: {0}", rgwzPaths[i]);
94 NativeAssert::StringEqual(rgwzPaths[i + 1], sczPath);
95 }
96 }
97 finally
98 {
99 ReleaseStr(sczPath);
100 }
101 }
102
103 [Fact]
104 void PathCanonicalizeForComparisonTest()
105 {
106 HRESULT hr = S_OK;
107 LPWSTR sczCanonicalized = NULL;
108
109 try
110 {
111 hr = PathCanonicalizeForComparison(L"C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", 0, &sczCanonicalized);
112 Assert::Equal<HRESULT>(HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE), hr);
113
114 hr = PathCanonicalizeForComparison(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", 0, &sczCanonicalized);
115 Assert::Equal<HRESULT>(HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE), hr);
116
117 hr = PathCanonicalizeForComparison(L"\\\\server", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
118 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
119 NativeAssert::StringEqual(L"\\\\server", sczCanonicalized);
120
121 hr = PathCanonicalizeForComparison(L"\\\\server", 0, &sczCanonicalized);
122 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
123 NativeAssert::StringEqual(L"\\\\server", sczCanonicalized);
124
125 hr = PathCanonicalizeForComparison(L"\\\\server\\", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
126 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
127 NativeAssert::StringEqual(L"\\\\server\\", sczCanonicalized);
128
129 hr = PathCanonicalizeForComparison(L"\\\\server\\share", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
130 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
131 NativeAssert::StringEqual(L"\\\\server\\share", sczCanonicalized);
132
133 hr = PathCanonicalizeForComparison(L"\\\\server\\share\\", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
134 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
135 NativeAssert::StringEqual(L"\\\\server\\share\\", sczCanonicalized);
136
137 hr = PathCanonicalizeForComparison(L"\\\\.\\share\\otherdir\\unc.exe", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
138 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
139 NativeAssert::StringEqual(L"\\\\.\\share\\otherdir\\unc.exe", sczCanonicalized);
140
141 hr = PathCanonicalizeForComparison(L"\\\\.\\share\\otherdir\\unc.exe", 0, &sczCanonicalized);
142 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
143 NativeAssert::StringEqual(L"\\\\share\\otherdir\\unc.exe", sczCanonicalized);
144
145 hr = PathCanonicalizeForComparison(L"\\\\server\\share\\..\\..\\otherdir\\unc.exe", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
146 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
147 NativeAssert::StringEqual(L"\\\\server\\share\\otherdir\\unc.exe", sczCanonicalized);
148
149 hr = PathCanonicalizeForComparison(L"\\\\server\\share\\..\\..\\otherdir\\unc.exe", 0, &sczCanonicalized);
150 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
151 NativeAssert::StringEqual(L"\\\\otherdir\\unc.exe", sczCanonicalized);
152
153 hr = PathCanonicalizeForComparison(L"\\\\?\\UNC\\server\\share\\..\\..\\otherdir\\unc.exe", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
154 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
155 NativeAssert::StringEqual(L"\\\\?\\UNC\\server\\share\\otherdir\\unc.exe", sczCanonicalized);
156
157 hr = PathCanonicalizeForComparison(L"\\\\?\\UNC\\server\\share\\..\\..\\otherdir\\unc.exe", 0, &sczCanonicalized);
158 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
159 NativeAssert::StringEqual(L"\\\\otherdir\\unc.exe", sczCanonicalized);
160
161 hr = PathCanonicalizeForComparison(L"C:\\dir\\subdir\\..\\..\\..\\otherdir\\pastroot.exe", 0, &sczCanonicalized);
162 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
163 NativeAssert::StringEqual(L"C:\\otherdir\\pastroot.exe", sczCanonicalized);
164
165 hr = PathCanonicalizeForComparison(L"\\\\?\\C:\\dir\\subdir\\..\\..\\..\\otherdir\\pastroot.exe", 0, &sczCanonicalized);
166 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
167 NativeAssert::StringEqual(L"C:\\otherdir\\pastroot.exe", sczCanonicalized);
168
169 hr = PathCanonicalizeForComparison(L"\\\\?\\C:dir\\subdir\\..\\..\\..\\otherdir\\pastroot.exe", 0, &sczCanonicalized);
170 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
171 NativeAssert::StringEqual(L"\\otherdir\\pastroot.exe", sczCanonicalized);
172
173 hr = PathCanonicalizeForComparison(L"C:dir\\subdir\\..\\..\\..\\otherdir\\pastrelativeroot.exe", 0, &sczCanonicalized);
174 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
175 NativeAssert::StringEqual(L"\\otherdir\\pastrelativeroot.exe", sczCanonicalized);
176
177 hr = PathCanonicalizeForComparison(L"A:dir\\subdir\\..\\..\\otherdir\\relativeroot.exe", 0, &sczCanonicalized);
178 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
179 NativeAssert::StringEqual(L"\\otherdir\\relativeroot.exe", sczCanonicalized);
180
181 hr = PathCanonicalizeForComparison(L"C:dir\\subdir\\otherdir\\relativeroot.exe", 0, &sczCanonicalized);
182 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
183 NativeAssert::StringEqual(L"C:dir\\subdir\\otherdir\\relativeroot.exe", sczCanonicalized);
184
185 hr = PathCanonicalizeForComparison(L"C:\\dir\\subdir\\..\\..\\otherdir\\backslashes.exe", 0, &sczCanonicalized);
186 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
187 NativeAssert::StringEqual(L"C:\\otherdir\\backslashes.exe", sczCanonicalized);
188
189 hr = PathCanonicalizeForComparison(L"C:\\dir\\subdir\\..\\..\\otherdir\\\\consecutivebackslashes.exe", 0, &sczCanonicalized);
190 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
191 NativeAssert::StringEqual(L"C:\\otherdir\\consecutivebackslashes.exe", sczCanonicalized);
192
193 hr = PathCanonicalizeForComparison(L"C:/dir/subdir/../../otherdir/forwardslashes.exe", 0, &sczCanonicalized);
194 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
195 NativeAssert::StringEqual(L"C:\\otherdir\\forwardslashes.exe", sczCanonicalized);
196
197 hr = PathCanonicalizeForComparison(L"\\\\?\\C:\\test\\..\\validlongpath.exe", 0, &sczCanonicalized);
198 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
199 NativeAssert::StringEqual(L"C:\\validlongpath.exe", sczCanonicalized);
200
201 hr = PathCanonicalizeForComparison(L"\\\\?\\test\\..\\invalidlongpath.exe", 0, &sczCanonicalized);
202 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
203 NativeAssert::StringEqual(L"\\\\?\\invalidlongpath.exe", sczCanonicalized);
204
205 hr = PathCanonicalizeForComparison(L"C:\\.\\invalid:pathchars?.exe", 0, &sczCanonicalized);
206 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
207 NativeAssert::StringEqual(L"C:\\invalid:pathchars?.exe", sczCanonicalized);
208
209 hr = PathCanonicalizeForComparison(L"C:\\addprefix.exe", PATH_CANONICALIZE_APPEND_LONG_PATH_PREFIX, &sczCanonicalized);
210 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
211 NativeAssert::StringEqual(L"\\\\?\\C:\\addprefix.exe", sczCanonicalized);
212
213 hr = PathCanonicalizeForComparison(L"C:\\addbackslash.exe", PATH_CANONICALIZE_BACKSLASH_TERMINATE, &sczCanonicalized);
214 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
215 NativeAssert::StringEqual(L"C:\\addbackslash.exe\\", sczCanonicalized);
216 }
217 finally
218 {
219 ReleaseStr(sczCanonicalized);
220 }
221 }
222
223 [Fact]
224 void PathDirectoryContainsPathTest()
225 {
226 HRESULT hr = S_OK;
227
228 hr = PathDirectoryContainsPath(L"", L"");
229 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
230
231 hr = PathDirectoryContainsPath(L"C:\\Directory", L"");
232 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
233
234 hr = PathDirectoryContainsPath(L"", L"C:\\Directory");
235 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
236
237 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\Directory");
238 Assert::Equal<HRESULT>(S_FALSE, hr);
239
240 hr = PathDirectoryContainsPath(L"C:\\Dir", L"C:\\Directory");
241 Assert::Equal<HRESULT>(S_FALSE, hr);
242
243 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\");
244 Assert::Equal<HRESULT>(S_FALSE, hr);
245
246 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\DirectoryPlus");
247 Assert::Equal<HRESULT>(S_FALSE, hr);
248
249 hr = PathDirectoryContainsPath(L"C:\\Directory\\", L"C:\\DirectoryPlus");
250 Assert::Equal<HRESULT>(S_FALSE, hr);
251
252 hr = PathDirectoryContainsPath(L"C:\\Directory\\", L"C:\\Directory\\../Plus");
253 Assert::Equal<HRESULT>(S_FALSE, hr);
254
255 hr = PathDirectoryContainsPath(L"C:\\Directory\\", L"C:\\Directory/../Plus");
256 Assert::Equal<HRESULT>(S_FALSE, hr);
257
258 hr = PathDirectoryContainsPath(L"\\\\server\\share\\Directory", L"\\\\server\\share\\DirectoryPlus");
259 Assert::Equal<HRESULT>(S_FALSE, hr);
260
261 hr = PathDirectoryContainsPath(L"\\\\server\\share\\Directory", L"\\\\discarded\\..\\server\\share\\Directory\\Plus");
262 Assert::Equal<HRESULT>(S_FALSE, hr);
263
264 hr = PathDirectoryContainsPath(L"..\\..", L"..\\..\\plus");
265 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
266
267 hr = PathDirectoryContainsPath(L"..\\..", L"\\..\\..\\plus");
268 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
269
270 hr = PathDirectoryContainsPath(L"\\..\\..", L"\\..\\..\\plus");
271 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
272
273 hr = PathDirectoryContainsPath(L"C:..\\..", L"C:..\\..\\plus");
274 Assert::Equal<HRESULT>(E_INVALIDARG, hr);
275
276 hr = PathDirectoryContainsPath(L"\\\\server\\share\\Directory", L"\\\\server\\share\\Directory\\Plus");
277 Assert::Equal<HRESULT>(S_OK, hr);
278
279 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\directory\\plus");
280 Assert::Equal<HRESULT>(S_OK, hr);
281
282 hr = PathDirectoryContainsPath(L"C:\\Directory\\", L"C:\\Directory\\Plus");
283 Assert::Equal<HRESULT>(S_OK, hr);
284
285 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\.\\Directory\\Plus");
286 Assert::Equal<HRESULT>(S_OK, hr);
287
288 hr = PathDirectoryContainsPath(L"C:\\Directory", L"C:\\Directory/Plus");
289 Assert::Equal<HRESULT>(S_OK, hr);
290
291 hr = PathDirectoryContainsPath(L"C:\\Directory\\", L"C:\\Directory/Plus");
292 Assert::Equal<HRESULT>(S_OK, hr);
293
294 hr = PathDirectoryContainsPath(L"\\\\?\\C:\\Directory", L"C:\\Directory\\Plus");
295 Assert::Equal<HRESULT>(S_OK, hr);
296 }
297
298 [Fact]
15 void PathGetDirectoryTest() 299 void PathGetDirectoryTest()
16 { 300 {
17 HRESULT hr = S_OK; 301 HRESULT hr = S_OK;
@@ -103,6 +387,57 @@ namespace DutilTests
103 NativeAssert::StringEqual(L"Software\\Microsoft\\", rgsczPaths[1]); 387 NativeAssert::StringEqual(L"Software\\Microsoft\\", rgsczPaths[1]);
104 NativeAssert::StringEqual(L"Software\\Microsoft\\Windows\\", rgsczPaths[2]); 388 NativeAssert::StringEqual(L"Software\\Microsoft\\Windows\\", rgsczPaths[2]);
105 ReleaseNullStrArray(rgsczPaths, cPaths); 389 ReleaseNullStrArray(rgsczPaths, cPaths);
390
391 hr = PathGetHierarchyArray(L"c:/foo/bar/bas/a.txt", &rgsczPaths, &cPaths);
392 NativeAssert::Succeeded(hr, "Failed to get parent directories array for regular file path");
393 Assert::Equal<DWORD>(5, cPaths);
394 NativeAssert::StringEqual(L"c:/", rgsczPaths[0]);
395 NativeAssert::StringEqual(L"c:/foo/", rgsczPaths[1]);
396 NativeAssert::StringEqual(L"c:/foo/bar/", rgsczPaths[2]);
397 NativeAssert::StringEqual(L"c:/foo/bar/bas/", rgsczPaths[3]);
398 NativeAssert::StringEqual(L"c:/foo/bar/bas/a.txt", rgsczPaths[4]);
399 ReleaseNullStrArray(rgsczPaths, cPaths);
400
401 hr = PathGetHierarchyArray(L"c:/foo/bar/bas/", &rgsczPaths, &cPaths);
402 NativeAssert::Succeeded(hr, "Failed to get parent directories array for regular directory path");
403 Assert::Equal<DWORD>(4, cPaths);
404 NativeAssert::StringEqual(L"c:/", rgsczPaths[0]);
405 NativeAssert::StringEqual(L"c:/foo/", rgsczPaths[1]);
406 NativeAssert::StringEqual(L"c:/foo/bar/", rgsczPaths[2]);
407 NativeAssert::StringEqual(L"c:/foo/bar/bas/", rgsczPaths[3]);
408 ReleaseNullStrArray(rgsczPaths, cPaths);
409
410 hr = PathGetHierarchyArray(L"//server/share/subdir/file.txt", &rgsczPaths, &cPaths);
411 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC file path");
412 Assert::Equal<DWORD>(3, cPaths);
413 NativeAssert::StringEqual(L"//server/share/", rgsczPaths[0]);
414 NativeAssert::StringEqual(L"//server/share/subdir/", rgsczPaths[1]);
415 NativeAssert::StringEqual(L"//server/share/subdir/file.txt", rgsczPaths[2]);
416 ReleaseNullStrArray(rgsczPaths, cPaths);
417
418 hr = PathGetHierarchyArray(L"//server/share/subdir/", &rgsczPaths, &cPaths);
419 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path");
420 Assert::Equal<DWORD>(2, cPaths);
421 NativeAssert::StringEqual(L"//server/share/", rgsczPaths[0]);
422 NativeAssert::StringEqual(L"//server/share/subdir/", rgsczPaths[1]);
423 ReleaseNullStrArray(rgsczPaths, cPaths);
424
425 hr = PathGetHierarchyArray(L"Software/Microsoft/Windows/ValueName", &rgsczPaths, &cPaths);
426 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path");
427 Assert::Equal<DWORD>(4, cPaths);
428 NativeAssert::StringEqual(L"Software/", rgsczPaths[0]);
429 NativeAssert::StringEqual(L"Software/Microsoft/", rgsczPaths[1]);
430 NativeAssert::StringEqual(L"Software/Microsoft/Windows/", rgsczPaths[2]);
431 NativeAssert::StringEqual(L"Software/Microsoft/Windows/ValueName", rgsczPaths[3]);
432 ReleaseNullStrArray(rgsczPaths, cPaths);
433
434 hr = PathGetHierarchyArray(L"Software/Microsoft/Windows/", &rgsczPaths, &cPaths);
435 NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path");
436 Assert::Equal<DWORD>(3, cPaths);
437 NativeAssert::StringEqual(L"Software/", rgsczPaths[0]);
438 NativeAssert::StringEqual(L"Software/Microsoft/", rgsczPaths[1]);
439 NativeAssert::StringEqual(L"Software/Microsoft/Windows/", rgsczPaths[2]);
440 ReleaseNullStrArray(rgsczPaths, cPaths);
106 } 441 }
107 finally 442 finally
108 { 443 {
@@ -111,11 +446,65 @@ namespace DutilTests
111 } 446 }
112 447
113 [Fact] 448 [Fact]
449 void PathNormalizeSlashesFixedTest()
450 {
451 HRESULT hr = S_OK;
452 LPWSTR sczPath = NULL;
453 LPCWSTR rgwzPaths[54] =
454 {
455 L"", L"",
456 L"\\", L"\\",
457 L"\\\\", L"\\\\",
458 L"\\\\\\", L"\\\\\\",
459 L"\\\\?\\UNC\\", L"\\\\?\\UNC\\",
460 L"C:\\\\foo2", L"C:\\foo2",
461 L"\\\\?\\C:\\\\foo2", L"\\\\?\\C:\\foo2",
462 L"\\\\a\\b\\", L"\\\\a\\b\\",
463 L"\\\\?\\UNC\\a\\b\\\\c\\", L"\\\\?\\UNC\\a\\b\\c\\",
464 L"\\\\?\\UNC\\a\\b\\\\", L"\\\\?\\UNC\\a\\b\\",
465 L"\\\\?\\UNC\\test\\unc\\path\\to\\\\something", L"\\\\?\\UNC\\test\\unc\\path\\to\\something",
466 L"\\\\?\\C:\\\\foo\\\\bar.txt", L"\\\\?\\C:\\foo\\bar.txt",
467 L"\\??\\C:\\\\foo\\bar.txt", L"\\??\\C:\\foo\\bar.txt",
468 L"\\??\\\\C:\\\\foo\\bar.txt", L"\\??\\\\C:\\foo\\bar.txt",
469 L"/", L"\\",
470 L"//", L"\\\\",
471 L"///", L"\\\\\\",
472 L"//?/UNC/", L"\\\\?\\UNC\\",
473 L"C://foo2", L"C:\\foo2",
474 L"//?/C://foo2", L"\\\\?\\C:\\foo2",
475 L"//a/b/", L"\\\\a\\b\\",
476 L"//?/UNC/a/b//c/", L"\\\\?\\UNC\\a\\b\\c\\",
477 L"//?/UNC/a/b//", L"\\\\?\\UNC\\a\\b\\",
478 L"//?/UNC/test/unc/path/to//something", L"\\\\?\\UNC\\test\\unc\\path\\to\\something",
479 L"//?/C://foo//bar.txt", L"\\\\?\\C:\\foo\\bar.txt",
480 L"/??/C://foo/bar.txt", L"\\??\\C:\\foo\\bar.txt",
481 L"/??//C://foo/bar.txt", L"\\??\\\\C:\\foo\\bar.txt",
482 };
483
484 try
485 {
486 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
487 {
488 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
489 NativeAssert::Succeeded(hr, "Failed to copy string");
490
491 hr = PathFixedNormalizeSlashes(sczPath);
492 NativeAssert::Succeeded(hr, "PathNormalizeSlashes: {0}", rgwzPaths[i]);
493 NativeAssert::StringEqual(rgwzPaths[i + 1], sczPath);
494 }
495 }
496 finally
497 {
498 ReleaseStr(sczPath);
499 }
500 }
501
502 [Fact]
114 void PathPrefixTest() 503 void PathPrefixTest()
115 { 504 {
116 HRESULT hr = S_OK; 505 HRESULT hr = S_OK;
117 LPWSTR sczPath = NULL; 506 LPWSTR sczPath = NULL;
118 LPCWSTR rgwzPaths[12] = 507 LPCWSTR rgwzPaths[24] =
119 { 508 {
120 L"\\\\", L"\\\\?\\UNC\\", 509 L"\\\\", L"\\\\?\\UNC\\",
121 L"C:\\\\foo2", L"\\\\?\\C:\\\\foo2", 510 L"C:\\\\foo2", L"\\\\?\\C:\\\\foo2",
@@ -123,11 +512,17 @@ namespace DutilTests
123 L"\\\\?\\UNC\\test\\unc\\path\\to\\something", L"\\\\?\\UNC\\test\\unc\\path\\to\\something", 512 L"\\\\?\\UNC\\test\\unc\\path\\to\\something", L"\\\\?\\UNC\\test\\unc\\path\\to\\something",
124 L"\\\\?\\C:\\foo\\bar.txt", L"\\\\?\\C:\\foo\\bar.txt", 513 L"\\\\?\\C:\\foo\\bar.txt", L"\\\\?\\C:\\foo\\bar.txt",
125 L"\\??\\C:\\foo\\bar.txt", L"\\??\\C:\\foo\\bar.txt", 514 L"\\??\\C:\\foo\\bar.txt", L"\\??\\C:\\foo\\bar.txt",
515 L"//", L"\\\\?\\UNC\\",
516 L"C://foo2", L"\\\\?\\C://foo2",
517 L"//a/b/", L"\\\\?\\UNC\\a/b/",
518 L"//?/UNC/test/unc/path/to/something", L"//?/UNC/test/unc/path/to/something",
519 L"//?/C:/foo/bar.txt", L"//?/C:/foo/bar.txt",
520 L"/??/C:/foo/bar.txt", L"/??/C:/foo/bar.txt",
126 }; 521 };
127 522
128 try 523 try
129 { 524 {
130 for (DWORD i = 0; i < countof(rgwzPaths) / 2; i += 2) 525 for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
131 { 526 {
132 hr = StrAllocString(&sczPath, rgwzPaths[i], 0); 527 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
133 NativeAssert::Succeeded(hr, "Failed to copy string"); 528 NativeAssert::Succeeded(hr, "Failed to copy string");
@@ -148,16 +543,20 @@ namespace DutilTests
148 { 543 {
149 HRESULT hr = S_OK; 544 HRESULT hr = S_OK;
150 LPWSTR sczPath = NULL; 545 LPWSTR sczPath = NULL;
151 LPCWSTR rgwzPaths[8] = 546 LPCWSTR rgwzPaths[12] =
152 { 547 {
153 L"\\", 548 L"\\",
549 L"/",
154 L"C:", 550 L"C:",
155 L"C:foo.txt", 551 L"C:foo.txt",
156 L"", 552 L"",
157 L"\\?", 553 L"\\?",
554 L"/?",
158 L"\\dir", 555 L"\\dir",
556 L"/dir",
159 L"dir", 557 L"dir",
160 L"dir\\subdir", 558 L"dir\\subdir",
559 L"dir/subdir",
161 }; 560 };
162 561
163 try 562 try
@@ -180,93 +579,162 @@ namespace DutilTests
180 [Fact] 579 [Fact]
181 void PathIsRootedAndFullyQualifiedTest() 580 void PathIsRootedAndFullyQualifiedTest()
182 { 581 {
582 HRESULT hr = S_OK;
583 LPWSTR sczPath = NULL;
183 LPCWSTR rgwzPaths[15] = 584 LPCWSTR rgwzPaths[15] =
184 { 585 {
185 L"\\\\", 586 L"//",
186 L"\\\\\\", 587 L"///",
187 L"C:\\", 588 L"C:/",
188 L"C:\\\\", 589 L"C://",
189 L"C:\\foo1", 590 L"C:/foo1",
190 L"C:\\\\foo2", 591 L"C://foo2",
191 L"\\\\test\\unc\\path\\to\\something", 592 L"//test/unc/path/to/something",
192 L"\\\\a\\b\\c\\d\\e", 593 L"//a/b/c/d/e",
193 L"\\\\a\\b\\", 594 L"//a/b/",
194 L"\\\\a\\b", 595 L"//a/b",
195 L"\\\\test\\unc", 596 L"//test/unc",
196 L"\\\\Server", 597 L"//Server",
197 L"\\\\Server\\Foo.txt", 598 L"//Server/Foo.txt",
198 L"\\\\Server\\Share\\Foo.txt", 599 L"//Server/Share/Foo.txt",
199 L"\\\\Server\\Share\\Test\\Foo.txt", 600 L"//Server/Share/Test/Foo.txt",
200 }; 601 };
201 602
202 for (DWORD i = 0; i < countof(rgwzPaths); ++i) 603 try
203 { 604 {
204 ValidateFullyQualifiedPath(rgwzPaths[i], TRUE, FALSE); 605 for (DWORD i = 0; i < countof(rgwzPaths); ++i)
205 ValidateRootedPath(rgwzPaths[i], TRUE); 606 {
607 ValidateFullyQualifiedPath(rgwzPaths[i], TRUE, FALSE);
608 ValidateRootedPath(rgwzPaths[i], TRUE);
609
610 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
611 NativeAssert::Succeeded(hr, "Failed to copy string");
612
613 PathFixedReplaceForwardSlashes(sczPath);
614 ValidateFullyQualifiedPath(sczPath, TRUE, FALSE);
615 ValidateRootedPath(sczPath, TRUE);
616 }
617 }
618 finally
619 {
620 ReleaseStr(sczPath);
206 } 621 }
207 } 622 }
208 623
209 [Fact] 624 [Fact]
210 void PathIsRootedAndFullyQualifiedWithPrefixTest() 625 void PathIsRootedAndFullyQualifiedWithPrefixTest()
211 { 626 {
627 HRESULT hr = S_OK;
628 LPWSTR sczPath = NULL;
212 LPCWSTR rgwzPaths[6] = 629 LPCWSTR rgwzPaths[6] =
213 { 630 {
214 L"\\\\?\\UNC\\test\\unc\\path\\to\\something", 631 L"//?/UNC/test/unc/path/to/something",
215 L"\\\\?\\UNC\\test\\unc", 632 L"//?/UNC/test/unc",
216 L"\\\\?\\UNC\\a\\b1", 633 L"//?/UNC/a/b1",
217 L"\\\\?\\UNC\\a\\b2\\", 634 L"//?/UNC/a/b2/",
218 L"\\\\?\\C:\\foo\\bar.txt", 635 L"//?/C:/foo/bar.txt",
219 L"\\??\\C:\\foo\\bar.txt", 636 L"/??/C:/foo/bar.txt",
220 }; 637 };
221 638
222 for (DWORD i = 0; i < countof(rgwzPaths); ++i) 639 try
223 { 640 {
224 ValidateFullyQualifiedPath(rgwzPaths[i], TRUE, TRUE); 641 for (DWORD i = 0; i < countof(rgwzPaths); ++i)
225 ValidateRootedPath(rgwzPaths[i], TRUE); 642 {
643 ValidateFullyQualifiedPath(rgwzPaths[i], TRUE, TRUE);
644 ValidateRootedPath(rgwzPaths[i], TRUE);
645
646 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
647 NativeAssert::Succeeded(hr, "Failed to copy string");
648
649 PathFixedReplaceForwardSlashes(sczPath);
650 ValidateFullyQualifiedPath(sczPath, TRUE, TRUE);
651 ValidateRootedPath(sczPath, TRUE);
652 }
653 }
654 finally
655 {
656 ReleaseStr(sczPath);
226 } 657 }
227 } 658 }
228 659
229 [Fact] 660 [Fact]
230 void PathIsRootedButNotFullyQualifiedTest() 661 void PathIsRootedButNotFullyQualifiedTest()
231 { 662 {
663 HRESULT hr = S_OK;
664 LPWSTR sczPath = NULL;
232 LPCWSTR rgwzPaths[7] = 665 LPCWSTR rgwzPaths[7] =
233 { 666 {
234 L"\\", 667 L"/",
235 L"a:", 668 L"a:",
236 L"A:", 669 L"A:",
237 L"z:", 670 L"z:",
238 L"Z:", 671 L"Z:",
239 L"C:foo.txt", 672 L"C:foo.txt",
240 L"\\dir", 673 L"/dir",
241 }; 674 };
242 675
243 for (DWORD i = 0; i < countof(rgwzPaths); ++i) 676 try
244 { 677 {
245 ValidateFullyQualifiedPath(rgwzPaths[i], FALSE, FALSE); 678 for (DWORD i = 0; i < countof(rgwzPaths); ++i)
246 ValidateRootedPath(rgwzPaths[i], TRUE); 679 {
680 ValidateFullyQualifiedPath(rgwzPaths[i], FALSE, FALSE);
681 ValidateRootedPath(rgwzPaths[i], TRUE);
682
683 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
684 NativeAssert::Succeeded(hr, "Failed to copy string");
685
686 PathFixedReplaceForwardSlashes(sczPath);
687 ValidateFullyQualifiedPath(sczPath, FALSE, FALSE);
688 ValidateRootedPath(sczPath, TRUE);
689 }
690 }
691 finally
692 {
693 ReleaseStr(sczPath);
247 } 694 }
248 } 695 }
249 696
250 [Fact] 697 [Fact]
251 void PathIsNotRootedAndNotFullyQualifiedTest() 698 void PathIsNotRootedAndNotFullyQualifiedTest()
252 { 699 {
700 HRESULT hr = S_OK;
701 LPWSTR sczPath = NULL;
253 LPCWSTR rgwzPaths[9] = 702 LPCWSTR rgwzPaths[9] =
254 { 703 {
255 NULL, 704 NULL,
256 L"", 705 L"",
257 L"dir", 706 L"dir",
258 L"dir\\subdir", 707 L"dir/subdir",
259 L"@:\\foo", // 064 = @ 065 = A 708 L"@:/foo", // 064 = @ 065 = A
260 L"[:\\\\", // 091 = [ 090 = Z 709 L"[://", // 091 = [ 090 = Z
261 L"`:\\foo ", // 096 = ` 097 = a 710 L"`:/foo ", // 096 = ` 097 = a
262 L"{:\\\\", // 123 = { 122 = z 711 L"{://", // 123 = { 122 = z
263 L"[:", 712 L"[:",
264 }; 713 };
265 714
266 for (DWORD i = 0; i < countof(rgwzPaths); ++i) 715 try
267 { 716 {
268 ValidateFullyQualifiedPath(rgwzPaths[i], FALSE, FALSE); 717 for (DWORD i = 0; i < countof(rgwzPaths); ++i)
269 ValidateRootedPath(rgwzPaths[i], FALSE); 718 {
719 ValidateFullyQualifiedPath(rgwzPaths[i], FALSE, FALSE);
720 ValidateRootedPath(rgwzPaths[i], FALSE);
721
722 if (!rgwzPaths[i])
723 {
724 continue;
725 }
726
727 hr = StrAllocString(&sczPath, rgwzPaths[i], 0);
728 NativeAssert::Succeeded(hr, "Failed to copy string");
729
730 PathFixedReplaceForwardSlashes(sczPath);
731 ValidateFullyQualifiedPath(sczPath, FALSE, FALSE);
732 ValidateRootedPath(sczPath, FALSE);
733 }
734 }
735 finally
736 {
737 ReleaseStr(sczPath);
270 } 738 }
271 } 739 }
272 740