2 * Unit test suite for ntdll path functions
4 * Copyright 2002 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "ntdll_test.h"
24 static NTSTATUS (WINAPI
*pRtlMultiByteToUnicodeN
)( LPWSTR dst
, DWORD dstlen
, LPDWORD reslen
,
25 LPCSTR src
, DWORD srclen
);
26 static NTSTATUS (WINAPI
*pRtlUnicodeToMultiByteN
)(LPSTR
,DWORD
,LPDWORD
,LPCWSTR
,DWORD
);
27 static UINT (WINAPI
*pRtlDetermineDosPathNameType_U
)( PCWSTR path
);
28 static ULONG (WINAPI
*pRtlIsDosDeviceName_U
)( PCWSTR dos_name
);
29 static NTSTATUS (WINAPI
*pRtlOemStringToUnicodeString
)(UNICODE_STRING
*, const STRING
*, BOOLEAN
);
30 static BOOLEAN (WINAPI
*pRtlIsNameLegalDOS8Dot3
)(const UNICODE_STRING
*,POEM_STRING
,PBOOLEAN
);
31 static DWORD (WINAPI
*pRtlGetFullPathName_U
)(const WCHAR
*,ULONG
,WCHAR
*,WCHAR
**);
32 static BOOLEAN (WINAPI
*pRtlDosPathNameToNtPathName_U
)(const WCHAR
*, UNICODE_STRING
*, WCHAR
**, CURDIR
*);
33 static NTSTATUS (WINAPI
*pRtlDosPathNameToNtPathName_U_WithStatus
)(const WCHAR
*, UNICODE_STRING
*, WCHAR
**, CURDIR
*);
35 static void test_RtlDetermineDosPathNameType_U(void)
43 static const struct test tests
[] =
83 const struct test
*test
;
84 WCHAR buffer
[MAX_PATH
];
87 if (!pRtlDetermineDosPathNameType_U
)
89 win_skip("RtlDetermineDosPathNameType_U is not available\n");
93 for (test
= tests
; test
->path
; test
++)
95 pRtlMultiByteToUnicodeN( buffer
, sizeof(buffer
), NULL
, test
->path
, strlen(test
->path
)+1 );
96 ret
= pRtlDetermineDosPathNameType_U( buffer
);
97 ok( ret
== test
->ret
, "Wrong result %d/%d for %s\n", ret
, test
->ret
, test
->path
);
102 static void test_RtlIsDosDeviceName_U(void)
112 static const struct test tests
[] =
114 { "\\\\.\\CON", 8, 6, TRUE
}, /* fails on win8 */
115 { "\\\\.\\con", 8, 6, TRUE
}, /* fails on win8 */
116 { "\\\\.\\CON2", 0, 0 },
118 { "\\\\foo\\nul", 0, 0 },
119 { "c:\\nul:", 6, 6 },
120 { "c:\\nul\\", 0, 0 },
121 { "c:\\nul\\foo", 0, 0 },
122 { "c:\\nul::", 6, 6, TRUE
}, /* fails on nt4 */
123 { "c:\\nul::::::", 6, 6, TRUE
}, /* fails on nt4 */
125 { "c:prn.......", 4, 6 },
126 { "c:prn... ...", 4, 6 },
127 { "c:NUL .... ", 4, 6, TRUE
}, /* fails on nt4 */
128 { "c: . . .", 0, 0 },
130 { " . . . :", 0, 0 },
132 { "c:nul. . . :", 4, 6 },
133 { "c:nul . . :", 4, 6, TRUE
}, /* fails on nt4 */
135 { "c:prn:aaa", 4, 6, TRUE
}, /* fails on win9x */
136 { "c:PRN:.txt", 4, 6 },
137 { "c:aux:.txt...", 4, 6 },
138 { "c:prn:.txt:", 4, 6 },
139 { "c:nul:aaa", 4, 6, TRUE
}, /* fails on win9x */
145 { "c:\\lpt0.txt", 0, 0 },
146 { "c:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
147 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
148 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
149 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
150 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
151 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
152 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\nul.txt", 1000, 6 },
156 const struct test
*test
;
160 if (!pRtlIsDosDeviceName_U
)
162 win_skip("RtlIsDosDeviceName_U is not available\n");
166 for (test
= tests
; test
->path
; test
++)
168 pRtlMultiByteToUnicodeN( buffer
, sizeof(buffer
), NULL
, test
->path
, strlen(test
->path
)+1 );
169 ret
= pRtlIsDosDeviceName_U( buffer
);
170 ok( ret
== MAKELONG( test
->len
, test
->pos
) ||
171 (test
->fails
&& broken( ret
== 0 )),
172 "Wrong result (%d,%d)/(%d,%d) for %s\n",
173 HIWORD(ret
), LOWORD(ret
), test
->pos
, test
->len
, test
->path
);
177 static void test_RtlIsNameLegalDOS8Dot3(void)
186 static const struct test tests
[] =
188 { "12345678", TRUE
, FALSE
},
189 { "123 5678", TRUE
, TRUE
},
190 { "12345678.", FALSE
, 2 /*not set*/ },
191 { "1234 678.", FALSE
, 2 /*not set*/ },
192 { "12345678.a", TRUE
, FALSE
},
193 { "12345678.a ", FALSE
, 2 /*not set*/ },
194 { "12345678.a c", TRUE
, TRUE
},
195 { " 2345678.a ", FALSE
, 2 /*not set*/ },
196 { "1 345678.abc", TRUE
, TRUE
},
197 { "1 8.a c", TRUE
, TRUE
},
198 { "1 3 5 7 .abc", FALSE
, 2 /*not set*/ },
199 { "12345678. c", TRUE
, TRUE
},
200 { "123456789.a", FALSE
, 2 /*not set*/ },
201 { "12345.abcd", FALSE
, 2 /*not set*/ },
202 { "12345.ab d", FALSE
, 2 /*not set*/ },
203 { ".abc", FALSE
, 2 /*not set*/ },
204 { "12.abc.d", FALSE
, 2 /*not set*/ },
205 { ".", TRUE
, FALSE
},
206 { "..", TRUE
, FALSE
},
207 { "...", FALSE
, 2 /*not set*/ },
208 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", FALSE
, 2 /*not set*/ },
212 const struct test
*test
;
214 OEM_STRING oem
, oem_ret
;
219 if (!pRtlIsNameLegalDOS8Dot3
)
221 win_skip("RtlIsNameLegalDOS8Dot3 is not available\n");
225 ustr
.MaximumLength
= sizeof(buffer
);
226 ustr
.Buffer
= buffer
;
227 for (test
= tests
; test
->path
; test
++)
230 strcpy(path
, test
->path
);
232 oem
.Length
= strlen(test
->path
);
233 oem
.MaximumLength
= oem
.Length
+ 1;
234 pRtlOemStringToUnicodeString( &ustr
, &oem
, FALSE
);
236 oem_ret
.Length
= oem_ret
.MaximumLength
= sizeof(buff2
);
237 oem_ret
.Buffer
= buff2
;
238 ret
= pRtlIsNameLegalDOS8Dot3( &ustr
, &oem_ret
, &spaces
);
239 ok( ret
== test
->result
, "Wrong result %d/%d for '%s'\n", ret
, test
->result
, test
->path
);
240 ok( spaces
== test
->spaces
, "Wrong spaces value %d/%d for '%s'\n", spaces
, test
->spaces
, test
->path
);
241 if (strlen(test
->path
) <= 12)
245 strcpy( str
, test
->path
);
246 RtlInitString( &test_str
, str
);
247 RtlUpperString( &test_str
, &test_str
);
248 ok( !RtlCompareString(&oem_ret
, &test_str
, FALSE
),
249 "Wrong string '%.*s'/'%s'\n", oem_ret
.Length
, oem_ret
.Buffer
, test
->path
);
253 static void test_RtlGetFullPathName_U(void)
255 static const WCHAR emptyW
[] = {0};
256 static const WCHAR deadbeefW
[] = {'d','e','a','d','b','e','e','f',0};
263 const char *alt_rname
;
264 const char *alt_rfile
;
267 static const struct test tests
[] =
269 { "c:/test", "c:\\test", "test"},
270 { "c:/test/", "c:\\test\\", NULL
},
271 { "c:/test ", "c:\\test", "test"},
272 { "c:/test.", "c:\\test", "test"},
273 { "c:/test .... .. ", "c:\\test", "test"},
274 { "c:/test/ .... .. ", "c:\\test\\", NULL
},
275 { "c:/test/..", "c:\\", NULL
},
276 { "c:/test/.. ", "c:\\test\\", NULL
},
277 { "c:/TEST", "c:\\TEST", "TEST"},
278 { "c:/test/file", "c:\\test\\file", "file"},
279 { "c:/test./file", "c:\\test\\file", "file"},
280 { "c:/test.. /file", "c:\\test.. \\file","file"},
281 { "c:/test/././file", "c:\\test\\file", "file"},
282 { "c:/test\\.\\.\\file", "c:\\test\\file", "file"},
283 { "c:/test/\\.\\.\\file", "c:\\test\\file", "file"},
284 { "c:/test\\\\.\\.\\file", "c:\\test\\file", "file"},
285 { "c:/test\\test1\\..\\.\\file", "c:\\test\\file", "file"},
286 { "c:///test\\.\\.\\file//", "c:\\test\\file\\", NULL
,
287 "c:\\test\\file", "file"}, /* nt4 */
288 { "c:///test\\..\\file\\..\\//", "c:\\", NULL
},
289 { "c:/test../file", "c:\\test.\\file", "file",
290 "c:\\test..\\file", "file"}, /* vista */
291 { "c:\\test", "c:\\test", "test"},
292 { "C:\\test", "C:\\test", "test"},
293 { "c:/", "c:\\", NULL
},
294 { "c:.", "C:\\windows", "windows"},
295 { "c:foo", "C:\\windows\\foo", "foo"},
296 { "c:foo/bar", "C:\\windows\\foo\\bar", "bar"},
297 { "c:./foo", "C:\\windows\\foo", "foo"},
298 { "\\foo", "C:\\foo", "foo"},
299 { "foo", "C:\\windows\\foo", "foo"},
300 { ".", "C:\\windows", "windows"},
301 { "..", "C:\\", NULL
},
302 { "...", "C:\\windows\\", NULL
},
303 { "./foo", "C:\\windows\\foo", "foo"},
304 { "foo/..", "C:\\windows", "windows"},
305 { "AUX", "\\\\.\\AUX", NULL
},
306 { "COM1", "\\\\.\\COM1", NULL
},
307 { "?<>*\"|:", "C:\\windows\\?<>*\"|:", "?<>*\"|:"},
309 { "\\\\foo", "\\\\foo", NULL
},
310 { "//foo", "\\\\foo", NULL
},
311 { "\\/foo", "\\\\foo", NULL
},
312 { "//", "\\\\", NULL
},
313 { "//foo/", "\\\\foo\\", NULL
},
315 { "//.", "\\\\.\\", NULL
},
316 { "//./", "\\\\.\\", NULL
},
317 { "//.//", "\\\\.\\", NULL
},
318 { "//./foo", "\\\\.\\foo", "foo"},
319 { "//./foo/", "\\\\.\\foo\\", NULL
},
320 { "//./foo/bar", "\\\\.\\foo\\bar", "bar"},
321 { "//./foo/.", "\\\\.\\foo", "foo"},
322 { "//./foo/..", "\\\\.\\", NULL
},
324 { "//?/", "\\\\?\\", NULL
},
325 { "//?//", "\\\\?\\", NULL
},
326 { "//?/foo", "\\\\?\\foo", "foo"},
327 { "//?/foo/", "\\\\?\\foo\\", NULL
},
328 { "//?/foo/bar", "\\\\?\\foo\\bar", "bar"},
329 { "//?/foo/.", "\\\\?\\foo", "foo"},
330 { "//?/foo/..", "\\\\?\\", NULL
},
332 /* RtlGetFullPathName_U() can't understand the global namespace prefix */
333 { "\\??\\foo", "C:\\??\\foo", "foo"},
337 const struct test
*test
;
338 WCHAR pathbufW
[2*MAX_PATH
], rbufferW
[MAX_PATH
];
339 char rbufferA
[MAX_PATH
], rfileA
[MAX_PATH
], curdir
[MAX_PATH
];
345 GetCurrentDirectoryA(sizeof(curdir
), curdir
);
346 SetCurrentDirectoryA("C:\\windows\\");
348 file_part
= (WCHAR
*)0xdeadbeef;
349 lstrcpyW(rbufferW
, deadbeefW
);
350 ret
= pRtlGetFullPathName_U(NULL
, MAX_PATH
, rbufferW
, &file_part
);
351 ok(!ret
, "Expected RtlGetFullPathName_U to return 0, got %u\n", ret
);
352 ok(!lstrcmpW(rbufferW
, deadbeefW
),
353 "Expected the output buffer to be untouched, got %s\n", wine_dbgstr_w(rbufferW
));
354 ok(file_part
== (WCHAR
*)0xdeadbeef ||
355 file_part
== NULL
, /* Win7 */
356 "Expected file part pointer to be untouched, got %p\n", file_part
);
358 file_part
= (WCHAR
*)0xdeadbeef;
359 lstrcpyW(rbufferW
, deadbeefW
);
360 ret
= pRtlGetFullPathName_U(emptyW
, MAX_PATH
, rbufferW
, &file_part
);
361 ok(!ret
, "Expected RtlGetFullPathName_U to return 0, got %u\n", ret
);
362 ok(!lstrcmpW(rbufferW
, deadbeefW
),
363 "Expected the output buffer to be untouched, got %s\n", wine_dbgstr_w(rbufferW
));
364 ok(file_part
== (WCHAR
*)0xdeadbeef ||
365 file_part
== NULL
, /* Win7 */
366 "Expected file part pointer to be untouched, got %p\n", file_part
);
368 for (test
= tests
; test
->path
; test
++)
370 len
= strlen(test
->rname
) * sizeof(WCHAR
);
371 pRtlMultiByteToUnicodeN(pathbufW
, sizeof(pathbufW
), NULL
, test
->path
, strlen(test
->path
)+1 );
372 ret
= pRtlGetFullPathName_U( pathbufW
,MAX_PATH
, rbufferW
, &file_part
);
373 ok( ret
== len
|| (test
->alt_rname
&& ret
== strlen(test
->alt_rname
)*sizeof(WCHAR
)),
374 "Wrong result %d/%d for \"%s\"\n", ret
, len
, test
->path
);
375 ok(pRtlUnicodeToMultiByteN(rbufferA
,MAX_PATH
,&reslen
,rbufferW
,(lstrlenW(rbufferW
) + 1) * sizeof(WCHAR
)) == STATUS_SUCCESS
,
376 "RtlUnicodeToMultiByteN failed\n");
377 ok(!lstrcmpA(rbufferA
,test
->rname
) || (test
->alt_rname
&& !lstrcmpA(rbufferA
,test
->alt_rname
)),
378 "Got \"%s\" expected \"%s\"\n",rbufferA
,test
->rname
);
381 ok(pRtlUnicodeToMultiByteN(rfileA
,MAX_PATH
,&reslen
,file_part
,(lstrlenW(file_part
) + 1) * sizeof(WCHAR
)) == STATUS_SUCCESS
,
382 "RtlUnicodeToMultiByteN failed\n");
383 ok((test
->rfile
&& !lstrcmpA(rfileA
,test
->rfile
)) ||
384 (test
->alt_rfile
&& !lstrcmpA(rfileA
,test
->alt_rfile
)),
385 "Got \"%s\" expected \"%s\"\n",rfileA
,test
->rfile
);
389 ok( !test
->rfile
, "Got NULL expected \"%s\"\n", test
->rfile
);
393 SetCurrentDirectoryA(curdir
);
396 static void test_RtlDosPathNameToNtPathName_U(void)
398 static const WCHAR broken_global_prefix
[] = {'\\','?','?','\\','C',':','\\','?','?'};
400 char curdir
[MAX_PATH
];
401 WCHAR path
[MAX_PATH
];
402 UNICODE_STRING nameW
;
412 int file_offset
; /* offset to file part */
419 { "c:\\", "\\??\\c:\\", -1, STATUS_SUCCESS
},
420 { "c:/", "\\??\\c:\\", -1, STATUS_SUCCESS
},
421 { "c:/foo", "\\??\\c:\\foo", 7, STATUS_SUCCESS
},
422 { "c:/foo.", "\\??\\c:\\foo", 7, STATUS_SUCCESS
},
423 { "c:/foo/", "\\??\\c:\\foo\\", -1, STATUS_SUCCESS
},
424 { "c:/foo//", "\\??\\c:\\foo\\", -1, STATUS_SUCCESS
},
425 { "C:/foo", "\\??\\C:\\foo", 7, STATUS_SUCCESS
},
426 { "C:/foo/bar", "\\??\\C:\\foo\\bar", 11, STATUS_SUCCESS
},
427 { "C:/foo/bar", "\\??\\C:\\foo\\bar", 11, STATUS_SUCCESS
},
428 { "c:.", "\\??\\C:\\windows", 7, STATUS_SUCCESS
},
429 { "c:foo", "\\??\\C:\\windows\\foo", 15, STATUS_SUCCESS
},
430 { "c:foo/bar", "\\??\\C:\\windows\\foo\\bar", 19, STATUS_SUCCESS
},
431 { "c:./foo", "\\??\\C:\\windows\\foo", 15, STATUS_SUCCESS
},
432 { "c:/./foo", "\\??\\c:\\foo", 7, STATUS_SUCCESS
},
433 { "c:/foo/.", "\\??\\c:\\foo", 7, STATUS_SUCCESS
},
434 { "c:/foo/./bar", "\\??\\c:\\foo\\bar", 11, STATUS_SUCCESS
},
435 { "c:/foo/../bar", "\\??\\c:\\bar", 7, STATUS_SUCCESS
},
436 { "\\foo", "\\??\\C:\\foo", 7, STATUS_SUCCESS
},
437 { "foo", "\\??\\C:\\windows\\foo", 15, STATUS_SUCCESS
},
438 { ".", "\\??\\C:\\windows", 7, STATUS_SUCCESS
},
439 { "./", "\\??\\C:\\windows\\", -1, STATUS_SUCCESS
},
440 { "..", "\\??\\C:\\", -1, STATUS_SUCCESS
},
441 { "...", "\\??\\C:\\windows\\", -1, STATUS_SUCCESS
},
442 { "./foo", "\\??\\C:\\windows\\foo", 15, STATUS_SUCCESS
},
443 { "foo/..", "\\??\\C:\\windows", 7, STATUS_SUCCESS
},
444 { "AUX" , "\\??\\AUX", -1, STATUS_SUCCESS
},
445 { "COM1" , "\\??\\COM1", -1, STATUS_SUCCESS
},
446 { "?<>*\"|:", "\\??\\C:\\windows\\?<>*\"|:", 15, STATUS_SUCCESS
},
448 { "", NULL
, -1, STATUS_OBJECT_NAME_INVALID
, STATUS_OBJECT_PATH_NOT_FOUND
},
449 { NULL
, NULL
, -1, STATUS_OBJECT_NAME_INVALID
, STATUS_OBJECT_PATH_NOT_FOUND
},
450 { " ", NULL
, -1, STATUS_OBJECT_NAME_INVALID
, STATUS_OBJECT_PATH_NOT_FOUND
},
452 { "\\\\foo", "\\??\\UNC\\foo", -1, STATUS_SUCCESS
},
453 { "//foo", "\\??\\UNC\\foo", -1, STATUS_SUCCESS
},
454 { "\\/foo", "\\??\\UNC\\foo", -1, STATUS_SUCCESS
},
455 { "//", "\\??\\UNC\\", -1, STATUS_SUCCESS
},
456 { "//foo/", "\\??\\UNC\\foo\\", -1, STATUS_SUCCESS
},
458 { "//.", "\\??\\", -1, STATUS_SUCCESS
},
459 { "//./", "\\??\\", -1, STATUS_SUCCESS
},
460 { "//.//", "\\??\\", -1, STATUS_SUCCESS
},
461 { "//./foo", "\\??\\foo", 4, STATUS_SUCCESS
},
462 { "//./foo/", "\\??\\foo\\", -1, STATUS_SUCCESS
},
463 { "//./foo/bar", "\\??\\foo\\bar", 8, STATUS_SUCCESS
},
464 { "//./foo/.", "\\??\\foo", 4, STATUS_SUCCESS
},
465 { "//./foo/..", "\\??\\", -1, STATUS_SUCCESS
},
467 { "//?", "\\??\\", -1, STATUS_SUCCESS
},
468 { "//?/", "\\??\\", -1, STATUS_SUCCESS
},
469 { "//?//", "\\??\\", -1, STATUS_SUCCESS
},
470 { "//?/foo", "\\??\\foo", 4, STATUS_SUCCESS
},
471 { "//?/foo/", "\\??\\foo\\", -1, STATUS_SUCCESS
},
472 { "//?/foo/bar", "\\??\\foo\\bar", 8, STATUS_SUCCESS
},
473 { "//?/foo/.", "\\??\\foo", 4, STATUS_SUCCESS
},
474 { "//?/foo/..", "\\??\\", -1, STATUS_SUCCESS
},
476 { "\\\\?", "\\??\\", -1, STATUS_SUCCESS
},
477 { "\\\\?\\", "\\??\\", -1, STATUS_SUCCESS
},
479 { "\\\\?\\/", "\\??\\/", 4, STATUS_SUCCESS
},
480 { "\\\\?\\foo", "\\??\\foo", 4, STATUS_SUCCESS
},
481 { "\\\\?\\foo/", "\\??\\foo/", 4, STATUS_SUCCESS
},
482 { "\\\\?\\foo/bar", "\\??\\foo/bar", 4, STATUS_SUCCESS
},
483 { "\\\\?\\foo/.", "\\??\\foo/.", 4, STATUS_SUCCESS
},
484 { "\\\\?\\foo/..", "\\??\\foo/..", 4, STATUS_SUCCESS
},
485 { "\\\\?\\\\", "\\??\\\\", -1, STATUS_SUCCESS
},
486 { "\\\\?\\\\\\", "\\??\\\\\\", -1, STATUS_SUCCESS
},
487 { "\\\\?\\foo\\", "\\??\\foo\\", -1, STATUS_SUCCESS
},
488 { "\\\\?\\foo\\bar", "\\??\\foo\\bar", 8, STATUS_SUCCESS
},
489 { "\\\\?\\foo\\.", "\\??\\foo\\.", 8, STATUS_SUCCESS
},
490 { "\\\\?\\foo\\..", "\\??\\foo\\..", 8, STATUS_SUCCESS
},
492 { "\\??", "\\??\\C:\\??", 7, STATUS_SUCCESS
},
493 { "\\??\\", "\\??\\C:\\??\\", -1, STATUS_SUCCESS
},
495 { "\\??\\/", "\\??\\/", 4, STATUS_SUCCESS
},
496 { "\\??\\foo", "\\??\\foo", 4, STATUS_SUCCESS
},
497 { "\\??\\foo/", "\\??\\foo/", 4, STATUS_SUCCESS
},
498 { "\\??\\foo/bar", "\\??\\foo/bar", 4, STATUS_SUCCESS
},
499 { "\\??\\foo/.", "\\??\\foo/.", 4, STATUS_SUCCESS
},
500 { "\\??\\foo/..", "\\??\\foo/..", 4, STATUS_SUCCESS
},
501 { "\\??\\\\", "\\??\\\\", -1, STATUS_SUCCESS
},
502 { "\\??\\\\\\", "\\??\\\\\\", -1, STATUS_SUCCESS
},
503 { "\\??\\foo\\", "\\??\\foo\\", -1, STATUS_SUCCESS
},
504 { "\\??\\foo\\bar", "\\??\\foo\\bar", 8, STATUS_SUCCESS
},
505 { "\\??\\foo\\.", "\\??\\foo\\.", 8, STATUS_SUCCESS
},
506 { "\\??\\foo\\..", "\\??\\foo\\..", 8, STATUS_SUCCESS
},
509 GetCurrentDirectoryA(sizeof(curdir
), curdir
);
510 SetCurrentDirectoryA("C:\\windows\\");
512 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
514 MultiByteToWideChar(CP_ACP
, 0, tests
[i
].dos
, -1, path
, ARRAY_SIZE(path
));
515 ret
= pRtlDosPathNameToNtPathName_U(path
, &nameW
, &file_part
, NULL
);
517 if (pRtlDosPathNameToNtPathName_U_WithStatus
)
519 RtlFreeUnicodeString(&nameW
);
520 status
= pRtlDosPathNameToNtPathName_U_WithStatus(path
, &nameW
, &file_part
, NULL
);
521 ok(status
== tests
[i
].status
|| status
== tests
[i
].alt_status
,
522 "%s: Expected status %#x, got %#x.\n", tests
[i
].dos
, tests
[i
].status
, status
);
525 expect
= (tests
[i
].status
== STATUS_SUCCESS
);
526 ok(ret
== expect
, "%s: Expected %#x, got %#x.\n", tests
[i
].dos
, expect
, ret
);
528 if (ret
!= TRUE
) continue;
530 if (!strncmp(tests
[i
].dos
, "\\??\\", 4) && tests
[i
].dos
[4] &&
531 broken(!memcmp(nameW
.Buffer
, broken_global_prefix
, sizeof(broken_global_prefix
))))
533 /* Windows version prior to 2003 don't interpret the \??\ prefix */
537 MultiByteToWideChar(CP_ACP
, 0, tests
[i
].nt
, -1, path
, ARRAY_SIZE(path
));
538 ok(!lstrcmpW(nameW
.Buffer
, path
), "%s: Expected %s, got %s.\n",
539 tests
[i
].dos
, tests
[i
].nt
, wine_dbgstr_w(nameW
.Buffer
));
541 if (tests
[i
].file_offset
> 0)
542 ok(file_part
== nameW
.Buffer
+ tests
[i
].file_offset
,
543 "%s: Expected file part %s, got %s.\n", tests
[i
].dos
,
544 wine_dbgstr_w(nameW
.Buffer
+ tests
[i
].file_offset
), wine_dbgstr_w(file_part
));
546 ok(file_part
== NULL
, "%s: Expected NULL file part, got %s.\n",
547 tests
[i
].dos
, wine_dbgstr_w(file_part
));
549 RtlFreeUnicodeString(&nameW
);
552 SetCurrentDirectoryA(curdir
);
557 HMODULE mod
= GetModuleHandleA("ntdll.dll");
560 win_skip("Not running on NT, skipping tests\n");
564 pRtlMultiByteToUnicodeN
= (void *)GetProcAddress(mod
,"RtlMultiByteToUnicodeN");
565 pRtlUnicodeToMultiByteN
= (void *)GetProcAddress(mod
,"RtlUnicodeToMultiByteN");
566 pRtlDetermineDosPathNameType_U
= (void *)GetProcAddress(mod
,"RtlDetermineDosPathNameType_U");
567 pRtlIsDosDeviceName_U
= (void *)GetProcAddress(mod
,"RtlIsDosDeviceName_U");
568 pRtlOemStringToUnicodeString
= (void *)GetProcAddress(mod
,"RtlOemStringToUnicodeString");
569 pRtlIsNameLegalDOS8Dot3
= (void *)GetProcAddress(mod
,"RtlIsNameLegalDOS8Dot3");
570 pRtlGetFullPathName_U
= (void *)GetProcAddress(mod
,"RtlGetFullPathName_U");
571 pRtlDosPathNameToNtPathName_U
= (void *)GetProcAddress(mod
, "RtlDosPathNameToNtPathName_U");
572 pRtlDosPathNameToNtPathName_U_WithStatus
= (void *)GetProcAddress(mod
, "RtlDosPathNameToNtPathName_U_WithStatus");
574 test_RtlDetermineDosPathNameType_U();
575 test_RtlIsDosDeviceName_U();
576 test_RtlIsNameLegalDOS8Dot3();
577 test_RtlGetFullPathName_U();
578 test_RtlDosPathNameToNtPathName_U();