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 { "\\\\.\\CONIN$", 6 },
84 { "\\\\.\\CONOUT$", 6 },
88 const struct test
*test
;
89 WCHAR buffer
[MAX_PATH
];
92 if (!pRtlDetermineDosPathNameType_U
)
94 win_skip("RtlDetermineDosPathNameType_U is not available\n");
98 for (test
= tests
; test
->path
; test
++)
100 pRtlMultiByteToUnicodeN( buffer
, sizeof(buffer
), NULL
, test
->path
, strlen(test
->path
)+1 );
101 ret
= pRtlDetermineDosPathNameType_U( buffer
);
102 ok( ret
== test
->ret
, "Wrong result %d/%d for %s\n", ret
, test
->ret
, test
->path
);
107 static void test_RtlIsDosDeviceName_U(void)
117 static const struct test tests
[] =
119 { "\\\\.\\CON", 8, 6, TRUE
}, /* fails on win8 */
120 { "\\\\.\\con", 8, 6, TRUE
}, /* fails on win8 */
121 { "\\\\.\\CON2", 0, 0 },
123 { "\\\\foo\\nul", 0, 0 },
124 { "c:\\nul:", 6, 6 },
125 { "c:\\nul\\", 0, 0 },
126 { "c:\\nul\\foo", 0, 0 },
127 { "c:\\nul::", 6, 6, TRUE
}, /* fails on nt4 */
128 { "c:\\nul::::::", 6, 6, TRUE
}, /* fails on nt4 */
130 { "c:prn.......", 4, 6 },
131 { "c:prn... ...", 4, 6 },
132 { "c:NUL .... ", 4, 6, TRUE
}, /* fails on nt4 */
133 { "c: . . .", 0, 0 },
135 { " . . . :", 0, 0 },
137 { "c:nul. . . :", 4, 6 },
138 { "c:nul . . :", 4, 6, TRUE
}, /* fails on nt4 */
140 { "c:prn:aaa", 4, 6, TRUE
}, /* fails on win9x */
141 { "c:PRN:.txt", 4, 6 },
142 { "c:aux:.txt...", 4, 6 },
143 { "c:prn:.txt:", 4, 6 },
144 { "c:nul:aaa", 4, 6, TRUE
}, /* fails on win9x */
150 { "c:\\lpt0.txt", 0, 0 },
151 { "CONIN$", 0, 12, TRUE
}, /* fails on winxp */
152 { "CONOUT$", 0, 14, TRUE
}, /* fails on winxp */
156 { "\\??\\CONIN$", 8, 12, TRUE
}, /* fails on winxp */
157 { "\\??\\CONOUT$", 8, 14, TRUE
}, /* fails on winxp */
158 { "\\??\\CONERR$", 0, 0 },
159 { "\\??\\CON", 8, 6 },
160 { "c:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
161 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
162 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
163 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
164 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
165 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
166 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\nul.txt", 1000, 6 },
170 const struct test
*test
;
174 if (!pRtlIsDosDeviceName_U
)
176 win_skip("RtlIsDosDeviceName_U is not available\n");
180 for (test
= tests
; test
->path
; test
++)
182 pRtlMultiByteToUnicodeN( buffer
, sizeof(buffer
), NULL
, test
->path
, strlen(test
->path
)+1 );
183 ret
= pRtlIsDosDeviceName_U( buffer
);
184 ok( ret
== MAKELONG( test
->len
, test
->pos
) ||
185 (test
->fails
&& broken( ret
== 0 )),
186 "Wrong result (%d,%d)/(%d,%d) for %s\n",
187 HIWORD(ret
), LOWORD(ret
), test
->pos
, test
->len
, test
->path
);
191 static void test_RtlIsNameLegalDOS8Dot3(void)
200 static const struct test tests
[] =
202 { "12345678", TRUE
, FALSE
},
203 { "123 5678", TRUE
, TRUE
},
204 { "12345678.", FALSE
, 2 /*not set*/ },
205 { "1234 678.", FALSE
, 2 /*not set*/ },
206 { "12345678.a", TRUE
, FALSE
},
207 { "12345678.a ", FALSE
, 2 /*not set*/ },
208 { "12345678.a c", TRUE
, TRUE
},
209 { " 2345678.a ", FALSE
, 2 /*not set*/ },
210 { "1 345678.abc", TRUE
, TRUE
},
211 { "1 8.a c", TRUE
, TRUE
},
212 { "1 3 5 7 .abc", FALSE
, 2 /*not set*/ },
213 { "12345678. c", TRUE
, TRUE
},
214 { "123456789.a", FALSE
, 2 /*not set*/ },
215 { "12345.abcd", FALSE
, 2 /*not set*/ },
216 { "12345.ab d", FALSE
, 2 /*not set*/ },
217 { ".abc", FALSE
, 2 /*not set*/ },
218 { "12.abc.d", FALSE
, 2 /*not set*/ },
219 { ".", TRUE
, FALSE
},
220 { "..", TRUE
, FALSE
},
221 { "...", FALSE
, 2 /*not set*/ },
222 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", FALSE
, 2 /*not set*/ },
226 const struct test
*test
;
228 OEM_STRING oem
, oem_ret
;
233 if (!pRtlIsNameLegalDOS8Dot3
)
235 win_skip("RtlIsNameLegalDOS8Dot3 is not available\n");
239 ustr
.MaximumLength
= sizeof(buffer
);
240 ustr
.Buffer
= buffer
;
241 for (test
= tests
; test
->path
; test
++)
244 strcpy(path
, test
->path
);
246 oem
.Length
= strlen(test
->path
);
247 oem
.MaximumLength
= oem
.Length
+ 1;
248 pRtlOemStringToUnicodeString( &ustr
, &oem
, FALSE
);
250 oem_ret
.Length
= oem_ret
.MaximumLength
= sizeof(buff2
);
251 oem_ret
.Buffer
= buff2
;
252 ret
= pRtlIsNameLegalDOS8Dot3( &ustr
, &oem_ret
, &spaces
);
253 ok( ret
== test
->result
, "Wrong result %d/%d for '%s'\n", ret
, test
->result
, test
->path
);
254 ok( spaces
== test
->spaces
, "Wrong spaces value %d/%d for '%s'\n", spaces
, test
->spaces
, test
->path
);
255 if (strlen(test
->path
) <= 12)
259 strcpy( str
, test
->path
);
260 RtlInitString( &test_str
, str
);
261 RtlUpperString( &test_str
, &test_str
);
262 ok( !RtlCompareString(&oem_ret
, &test_str
, FALSE
),
263 "Wrong string '%.*s'/'%s'\n", oem_ret
.Length
, oem_ret
.Buffer
, test
->path
);
267 static void test_RtlGetFullPathName_U(void)
269 static const WCHAR emptyW
[] = {0};
270 static const WCHAR deadbeefW
[] = {'d','e','a','d','b','e','e','f',0};
277 const char *alt_rname
;
278 const char *alt_rfile
;
281 static const struct test tests
[] =
283 { "c:/test", "c:\\test", "test"},
284 { "c:/test/", "c:\\test\\", NULL
},
285 { "c:/test ", "c:\\test", "test"},
286 { "c:/test.", "c:\\test", "test"},
287 { "c:/test .... .. ", "c:\\test", "test"},
288 { "c:/test/ .... .. ", "c:\\test\\", NULL
},
289 { "c:/test/..", "c:\\", NULL
},
290 { "c:/test/.. ", "c:\\test\\", NULL
},
291 { "c:/TEST", "c:\\TEST", "TEST"},
292 { "c:/test/file", "c:\\test\\file", "file"},
293 { "c:/test./file", "c:\\test\\file", "file"},
294 { "c:/test.. /file", "c:\\test.. \\file","file"},
295 { "c:/test/././file", "c:\\test\\file", "file"},
296 { "c:/test\\.\\.\\file", "c:\\test\\file", "file"},
297 { "c:/test/\\.\\.\\file", "c:\\test\\file", "file"},
298 { "c:/test\\\\.\\.\\file", "c:\\test\\file", "file"},
299 { "c:/test\\test1\\..\\.\\file", "c:\\test\\file", "file"},
300 { "c:///test\\.\\.\\file//", "c:\\test\\file\\", NULL
,
301 "c:\\test\\file", "file"}, /* nt4 */
302 { "c:///test\\..\\file\\..\\//", "c:\\", NULL
},
303 { "c:/test../file", "c:\\test.\\file", "file",
304 "c:\\test..\\file", "file"}, /* vista */
305 { "c:\\test", "c:\\test", "test"},
306 { "C:\\test", "C:\\test", "test"},
307 { "c:/", "c:\\", NULL
},
308 { "c:.", "C:\\windows", "windows"},
309 { "c:foo", "C:\\windows\\foo", "foo"},
310 { "c:foo/bar", "C:\\windows\\foo\\bar", "bar"},
311 { "c:./foo", "C:\\windows\\foo", "foo"},
312 { "\\foo", "C:\\foo", "foo"},
313 { "foo", "C:\\windows\\foo", "foo"},
314 { ".", "C:\\windows", "windows"},
315 { "..", "C:\\", NULL
},
316 { "...", "C:\\windows\\", NULL
},
317 { "./foo", "C:\\windows\\foo", "foo"},
318 { "foo/..", "C:\\windows", "windows"},
319 { "AUX", "\\\\.\\AUX", NULL
},
320 { "COM1", "\\\\.\\COM1", NULL
},
321 { "?<>*\"|:", "C:\\windows\\?<>*\"|:", "?<>*\"|:"},
323 { "\\\\foo", "\\\\foo", NULL
},
324 { "//foo", "\\\\foo", NULL
},
325 { "\\/foo", "\\\\foo", NULL
},
326 { "//", "\\\\", NULL
},
327 { "//foo/", "\\\\foo\\", NULL
},
329 { "//.", "\\\\.\\", NULL
},
330 { "//./", "\\\\.\\", NULL
},
331 { "//.//", "\\\\.\\", NULL
},
332 { "//./foo", "\\\\.\\foo", "foo"},
333 { "//./foo/", "\\\\.\\foo\\", NULL
},
334 { "//./foo/bar", "\\\\.\\foo\\bar", "bar"},
335 { "//./foo/.", "\\\\.\\foo", "foo"},
336 { "//./foo/..", "\\\\.\\", NULL
},
338 { "//?/", "\\\\?\\", NULL
},
339 { "//?//", "\\\\?\\", NULL
},
340 { "//?/foo", "\\\\?\\foo", "foo"},
341 { "//?/foo/", "\\\\?\\foo\\", NULL
},
342 { "//?/foo/bar", "\\\\?\\foo\\bar", "bar"},
343 { "//?/foo/.", "\\\\?\\foo", "foo"},
344 { "//?/foo/..", "\\\\?\\", NULL
},
346 { "CONIN$", "\\\\.\\CONIN$", NULL
,
347 "C:\\windows\\CONIN$", "CONIN$"},
348 { "CONOUT$", "\\\\.\\CONOUT$", NULL
,
349 "C:\\windows\\CONOUT$", "CONOUT$"},
351 /* RtlGetFullPathName_U() can't understand the global namespace prefix */
352 { "\\??\\foo", "C:\\??\\foo", "foo"},
356 const struct test
*test
;
357 WCHAR pathbufW
[2*MAX_PATH
], rbufferW
[MAX_PATH
];
358 char rbufferA
[MAX_PATH
], rfileA
[MAX_PATH
], curdir
[MAX_PATH
];
364 GetCurrentDirectoryA(sizeof(curdir
), curdir
);
365 SetCurrentDirectoryA("C:\\windows\\");
367 file_part
= (WCHAR
*)0xdeadbeef;
368 lstrcpyW(rbufferW
, deadbeefW
);
369 ret
= pRtlGetFullPathName_U(NULL
, MAX_PATH
, rbufferW
, &file_part
);
370 ok(!ret
, "Expected RtlGetFullPathName_U to return 0, got %u\n", ret
);
371 ok(!lstrcmpW(rbufferW
, deadbeefW
),
372 "Expected the output buffer to be untouched, got %s\n", wine_dbgstr_w(rbufferW
));
373 ok(file_part
== (WCHAR
*)0xdeadbeef ||
374 file_part
== NULL
, /* Win7 */
375 "Expected file part pointer to be untouched, got %p\n", file_part
);
377 file_part
= (WCHAR
*)0xdeadbeef;
378 lstrcpyW(rbufferW
, deadbeefW
);
379 ret
= pRtlGetFullPathName_U(emptyW
, MAX_PATH
, rbufferW
, &file_part
);
380 ok(!ret
, "Expected RtlGetFullPathName_U to return 0, got %u\n", ret
);
381 ok(!lstrcmpW(rbufferW
, deadbeefW
),
382 "Expected the output buffer to be untouched, got %s\n", wine_dbgstr_w(rbufferW
));
383 ok(file_part
== (WCHAR
*)0xdeadbeef ||
384 file_part
== NULL
, /* Win7 */
385 "Expected file part pointer to be untouched, got %p\n", file_part
);
387 for (test
= tests
; test
->path
; test
++)
389 len
= strlen(test
->rname
) * sizeof(WCHAR
);
390 pRtlMultiByteToUnicodeN(pathbufW
, sizeof(pathbufW
), NULL
, test
->path
, strlen(test
->path
)+1 );
391 ret
= pRtlGetFullPathName_U( pathbufW
,MAX_PATH
, rbufferW
, &file_part
);
392 ok( ret
== len
|| (test
->alt_rname
&& ret
== strlen(test
->alt_rname
)*sizeof(WCHAR
)),
393 "Wrong result %d/%d for \"%s\"\n", ret
, len
, test
->path
);
394 ok(pRtlUnicodeToMultiByteN(rbufferA
,MAX_PATH
,&reslen
,rbufferW
,(lstrlenW(rbufferW
) + 1) * sizeof(WCHAR
)) == STATUS_SUCCESS
,
395 "RtlUnicodeToMultiByteN failed\n");
396 ok(!lstrcmpA(rbufferA
,test
->rname
) || (test
->alt_rname
&& !lstrcmpA(rbufferA
,test
->alt_rname
)),
397 "Got \"%s\" expected \"%s\"\n",rbufferA
,test
->rname
);
400 ok(pRtlUnicodeToMultiByteN(rfileA
,MAX_PATH
,&reslen
,file_part
,(lstrlenW(file_part
) + 1) * sizeof(WCHAR
)) == STATUS_SUCCESS
,
401 "RtlUnicodeToMultiByteN failed\n");
402 ok((test
->rfile
&& !lstrcmpA(rfileA
,test
->rfile
)) ||
403 (test
->alt_rfile
&& !lstrcmpA(rfileA
,test
->alt_rfile
)),
404 "Got \"%s\" expected \"%s\"\n",rfileA
,test
->rfile
);
408 ok( !test
->rfile
, "Got NULL expected \"%s\"\n", test
->rfile
);
412 SetCurrentDirectoryA(curdir
);
415 static void test_RtlDosPathNameToNtPathName_U(void)
417 static const WCHAR broken_global_prefix
[] = L
"\\??\\C:\\??";
419 char curdir
[MAX_PATH
];
420 UNICODE_STRING nameW
;
430 int file_offset
; /* offset to file part */
435 {L
"c:\\", L
"\\??\\c:\\", -1},
436 {L
"c:/", L
"\\??\\c:\\", -1},
437 {L
"c:/foo", L
"\\??\\c:\\foo", 7},
438 {L
"c:/foo.", L
"\\??\\c:\\foo", 7},
439 {L
"c:/foo/", L
"\\??\\c:\\foo\\", -1},
440 {L
"c:/foo//", L
"\\??\\c:\\foo\\", -1},
441 {L
"C:/foo", L
"\\??\\C:\\foo", 7},
442 {L
"C:/foo/bar", L
"\\??\\C:\\foo\\bar", 11},
443 {L
"C:/foo/bar", L
"\\??\\C:\\foo\\bar", 11},
444 {L
"c:.", L
"\\??\\C:\\windows", 7},
445 {L
"c:foo", L
"\\??\\C:\\windows\\foo", 15},
446 {L
"c:foo/bar", L
"\\??\\C:\\windows\\foo\\bar", 19},
447 {L
"c:./foo", L
"\\??\\C:\\windows\\foo", 15},
448 {L
"c:/./foo", L
"\\??\\c:\\foo", 7},
449 {L
"c:/..", L
"\\??\\c:\\", -1},
450 {L
"c:/foo/.", L
"\\??\\c:\\foo", 7},
451 {L
"c:/foo/./bar", L
"\\??\\c:\\foo\\bar", 11},
452 {L
"c:/foo/../bar", L
"\\??\\c:\\bar", 7},
453 {L
"\\foo", L
"\\??\\C:\\foo", 7},
454 {L
"foo", L
"\\??\\C:\\windows\\foo", 15},
455 {L
".", L
"\\??\\C:\\windows", 7},
456 {L
"./", L
"\\??\\C:\\windows\\", -1},
457 {L
"..", L
"\\??\\C:\\", -1},
458 {L
"...", L
"\\??\\C:\\windows\\", -1},
459 {L
"./foo", L
"\\??\\C:\\windows\\foo", 15},
460 {L
"foo/..", L
"\\??\\C:\\windows", 7},
461 {L
"AUX" , L
"\\??\\AUX", -1},
462 {L
"COM1" , L
"\\??\\COM1", -1},
463 {L
"?<>*\"|:", L
"\\??\\C:\\windows\\?<>*\"|:", 15},
464 {L
"?:", L
"\\??\\?:\\", -1},
466 {L
"\\\\foo", L
"\\??\\UNC\\foo", -1},
467 {L
"//foo", L
"\\??\\UNC\\foo", -1},
468 {L
"\\/foo", L
"\\??\\UNC\\foo", -1},
469 {L
"//", L
"\\??\\UNC\\", -1},
470 {L
"//foo/", L
"\\??\\UNC\\foo\\", -1},
472 {L
"//.", L
"\\??\\", -1},
473 {L
"//./", L
"\\??\\", -1},
474 {L
"//.//", L
"\\??\\", -1},
475 {L
"//./foo", L
"\\??\\foo", 4},
476 {L
"//./foo/", L
"\\??\\foo\\", -1},
477 {L
"//./foo/bar", L
"\\??\\foo\\bar", 8},
478 {L
"//./foo/.", L
"\\??\\foo", 4},
479 {L
"//./foo/..", L
"\\??\\", -1},
481 {L
"//?", L
"\\??\\", -1},
482 {L
"//?/", L
"\\??\\", -1},
483 {L
"//?//", L
"\\??\\", -1},
484 {L
"//?/foo", L
"\\??\\foo", 4},
485 {L
"//?/foo/", L
"\\??\\foo\\", -1},
486 {L
"//?/foo/bar", L
"\\??\\foo\\bar", 8},
487 {L
"//?/foo/.", L
"\\??\\foo", 4},
488 {L
"//?/foo/..", L
"\\??\\", -1},
490 {L
"\\\\.", L
"\\??\\", -1},
491 {L
"\\\\.\\", L
"\\??\\", -1},
492 {L
"\\\\.\\/", L
"\\??\\", -1},
493 {L
"\\\\.\\foo", L
"\\??\\foo", 4},
494 {L
"\\\\.\\foo/", L
"\\??\\foo\\", -1},
495 {L
"\\\\.\\foo/bar", L
"\\??\\foo\\bar", 8},
496 {L
"\\\\.\\foo/.", L
"\\??\\foo", 4},
497 {L
"\\\\.\\foo/..", L
"\\??\\", -1},
499 {L
"\\\\?", L
"\\??\\", -1},
500 {L
"\\\\?\\", L
"\\??\\", -1},
502 {L
"\\\\?\\/", L
"\\??\\/", 4},
503 {L
"\\\\?\\foo", L
"\\??\\foo", 4},
504 {L
"\\\\?\\foo/", L
"\\??\\foo/", 4},
505 {L
"\\\\?\\foo/bar", L
"\\??\\foo/bar", 4},
506 {L
"\\\\?\\foo/.", L
"\\??\\foo/.", 4},
507 {L
"\\\\?\\foo/..", L
"\\??\\foo/..", 4},
508 {L
"\\\\?\\\\", L
"\\??\\\\", -1},
509 {L
"\\\\?\\\\\\", L
"\\??\\\\\\", -1},
510 {L
"\\\\?\\foo\\", L
"\\??\\foo\\", -1},
511 {L
"\\\\?\\foo\\bar",L
"\\??\\foo\\bar", 8},
512 {L
"\\\\?\\foo\\.", L
"\\??\\foo\\.", 8},
513 {L
"\\\\?\\foo\\..", L
"\\??\\foo\\..", 8},
515 {L
"\\??", L
"\\??\\C:\\??", 7},
516 {L
"\\??\\", L
"\\??\\C:\\??\\", -1},
518 {L
"\\??\\/", L
"\\??\\/", 4},
519 {L
"\\??\\foo", L
"\\??\\foo", 4},
520 {L
"\\??\\foo/", L
"\\??\\foo/", 4},
521 {L
"\\??\\foo/bar", L
"\\??\\foo/bar", 4},
522 {L
"\\??\\foo/.", L
"\\??\\foo/.", 4},
523 {L
"\\??\\foo/..", L
"\\??\\foo/..", 4},
524 {L
"\\??\\\\", L
"\\??\\\\", -1},
525 {L
"\\??\\\\\\", L
"\\??\\\\\\", -1},
526 {L
"\\??\\foo\\", L
"\\??\\foo\\", -1},
527 {L
"\\??\\foo\\bar", L
"\\??\\foo\\bar", 8},
528 {L
"\\??\\foo\\.", L
"\\??\\foo\\.", 8},
529 {L
"\\??\\foo\\..", L
"\\??\\foo\\..", 8},
531 {L
"CONIN$", L
"\\??\\CONIN$", -1, L
"\\??\\C:\\windows\\CONIN$" /* winxp */ },
532 {L
"CONOUT$", L
"\\??\\CONOUT$", -1, L
"\\??\\C:\\windows\\CONOUT$" /* winxp */ },
533 {L
"cOnOuT$", L
"\\??\\cOnOuT$", -1, L
"\\??\\C:\\windows\\cOnOuT$" /* winxp */ },
534 {L
"CONERR$", L
"\\??\\C:\\windows\\CONERR$", 15},
537 GetCurrentDirectoryA(sizeof(curdir
), curdir
);
538 SetCurrentDirectoryA("C:\\windows\\");
540 ret
= pRtlDosPathNameToNtPathName_U(NULL
, &nameW
, &file_part
, NULL
);
541 ok(!ret
, "Got %d.\n", ret
);
543 ret
= pRtlDosPathNameToNtPathName_U(L
"", &nameW
, &file_part
, NULL
);
544 ok(!ret
, "Got %d.\n", ret
);
546 ret
= pRtlDosPathNameToNtPathName_U(L
" ", &nameW
, &file_part
, NULL
);
547 ok(!ret
, "Got %d.\n", ret
);
549 if (pRtlDosPathNameToNtPathName_U_WithStatus
)
551 status
= pRtlDosPathNameToNtPathName_U_WithStatus(NULL
, &nameW
, &file_part
, NULL
);
552 ok(status
== STATUS_OBJECT_NAME_INVALID
|| status
== STATUS_OBJECT_PATH_NOT_FOUND
/* 2003 */,
553 "Got status %#x.\n", status
);
555 status
= pRtlDosPathNameToNtPathName_U_WithStatus(L
"", &nameW
, &file_part
, NULL
);
556 ok(status
== STATUS_OBJECT_NAME_INVALID
|| status
== STATUS_OBJECT_PATH_NOT_FOUND
/* 2003 */,
557 "Got status %#x.\n", status
);
559 status
= pRtlDosPathNameToNtPathName_U_WithStatus(L
" ", &nameW
, &file_part
, NULL
);
560 ok(status
== STATUS_OBJECT_NAME_INVALID
|| status
== STATUS_OBJECT_PATH_NOT_FOUND
/* 2003 */,
561 "Got status %#x.\n", status
);
564 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
566 ret
= pRtlDosPathNameToNtPathName_U(tests
[i
].dos
, &nameW
, &file_part
, NULL
);
567 ok(ret
== TRUE
, "%s: Got %d.\n", debugstr_w(tests
[i
].dos
), ret
);
569 if (pRtlDosPathNameToNtPathName_U_WithStatus
)
571 RtlFreeUnicodeString(&nameW
);
572 status
= pRtlDosPathNameToNtPathName_U_WithStatus(tests
[i
].dos
, &nameW
, &file_part
, NULL
);
573 ok(status
== STATUS_SUCCESS
, "%s: Got status %#x.\n", debugstr_w(tests
[i
].dos
), status
);
576 if (!wcsncmp(tests
[i
].dos
, L
"\\??\\", 4) && tests
[i
].dos
[4] &&
577 broken(!wcsncmp(nameW
.Buffer
, broken_global_prefix
, wcslen(broken_global_prefix
))))
579 /* Windows version prior to 2003 don't interpret the \??\ prefix */
583 ok(!wcscmp(nameW
.Buffer
, tests
[i
].nt
) || broken(!wcscmp(nameW
.Buffer
, tests
[i
].alt_nt
)), "%s: Expected %s, got %s.\n",
584 debugstr_w(tests
[i
].dos
), debugstr_w(tests
[i
].nt
), debugstr_w(nameW
.Buffer
));
586 if (!wcscmp(nameW
.Buffer
, tests
[i
].nt
))
588 if (tests
[i
].file_offset
> 0)
589 ok(file_part
== nameW
.Buffer
+ tests
[i
].file_offset
,
590 "%s: Expected file part %s, got %s.\n", debugstr_w(tests
[i
].dos
),
591 debugstr_w(nameW
.Buffer
+ tests
[i
].file_offset
), debugstr_w(file_part
));
593 ok(file_part
== NULL
, "%s: Expected NULL file part, got %s.\n",
594 debugstr_w(tests
[i
].dos
), debugstr_w(file_part
));
597 RtlFreeUnicodeString(&nameW
);
600 SetCurrentDirectoryA(curdir
);
605 HMODULE mod
= GetModuleHandleA("ntdll.dll");
608 win_skip("Not running on NT, skipping tests\n");
612 pRtlMultiByteToUnicodeN
= (void *)GetProcAddress(mod
,"RtlMultiByteToUnicodeN");
613 pRtlUnicodeToMultiByteN
= (void *)GetProcAddress(mod
,"RtlUnicodeToMultiByteN");
614 pRtlDetermineDosPathNameType_U
= (void *)GetProcAddress(mod
,"RtlDetermineDosPathNameType_U");
615 pRtlIsDosDeviceName_U
= (void *)GetProcAddress(mod
,"RtlIsDosDeviceName_U");
616 pRtlOemStringToUnicodeString
= (void *)GetProcAddress(mod
,"RtlOemStringToUnicodeString");
617 pRtlIsNameLegalDOS8Dot3
= (void *)GetProcAddress(mod
,"RtlIsNameLegalDOS8Dot3");
618 pRtlGetFullPathName_U
= (void *)GetProcAddress(mod
,"RtlGetFullPathName_U");
619 pRtlDosPathNameToNtPathName_U
= (void *)GetProcAddress(mod
, "RtlDosPathNameToNtPathName_U");
620 pRtlDosPathNameToNtPathName_U_WithStatus
= (void *)GetProcAddress(mod
, "RtlDosPathNameToNtPathName_U_WithStatus");
622 test_RtlDetermineDosPathNameType_U();
623 test_RtlIsDosDeviceName_U();
624 test_RtlIsNameLegalDOS8Dot3();
625 test_RtlGetFullPathName_U();
626 test_RtlDosPathNameToNtPathName_U();