2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for RtlGetFullPathName_Ustr
5 * PROGRAMMER: Thomas Faber <thfabba@gmx.de>
8 #define WIN32_NO_STATUS
10 #include <wine/test.h>
11 #include <pseh/pseh2.h>
12 #include <ndk/rtlfuncs.h>
17 RtlGetFullPathName_Ustr(
18 IN PCUNICODE_STRING FileName,
21 OUT PCWSTR *ShortName,
22 OUT PBOOLEAN InvalidName,
23 OUT RTL_PATH_TYPE* PathType
27 /* This seems to be a struct of some kind in Windows 7... returns 0 or 32 in the second member */
28 typedef struct _PATH_TYPE_AND_UNKNOWN
32 } PATH_TYPE_AND_UNKNOWN
;
37 *RtlGetFullPathName_Ustr
)(
38 IN PCUNICODE_STRING FileName
,
41 OUT PCWSTR
*ShortName
,
42 OUT PBOOLEAN InvalidName
,
43 OUT PATH_TYPE_AND_UNKNOWN
*PathType
45 //= (PVOID)0x7c83086c // 2003 sp1 x86
46 //= (PVOID)0x77ef49f0 // 2003 sp1 x64
47 //= (PVOID)0x7769a3dd // win7 sp1 wow64
50 #define StartSeh() ExceptionStatus = STATUS_SUCCESS; _SEH2_TRY {
51 #define EndSeh(ExpectedStatus) } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; ok(ExceptionStatus == ExpectedStatus, "Exception %lx, expected %lx\n", ExceptionStatus, ExpectedStatus)
53 #define ok_eq_ustr(str1, str2) do { \
54 ok((str1)->Buffer == (str2)->Buffer, "Buffer modified\n"); \
55 ok((str1)->Length == (str2)->Length, "Length modified\n"); \
56 ok((str1)->MaximumLength == (str2)->MaximumLength, "MaximumLength modified\n"); \
67 SIZE_T ExpectedLength
= wcslen(Expected
) * sizeof(WCHAR
);
69 BOOLEAN Result
= TRUE
;
72 if (Length
!= ExpectedLength
)
74 ok(0, "String length is %lu, expected %lu\n", (ULONG
)Length
, (ULONG
)ExpectedLength
);
78 EqualLength
= RtlCompareMemory(Buffer
, Expected
, Length
);
79 if (EqualLength
!= Length
)
81 ok(0, "String is '%S', expected '%S'\n", Buffer
, Expected
);
85 if (Buffer
[Length
/ sizeof(WCHAR
)] != UNICODE_NULL
)
87 ok(0, "Not null terminated\n");
91 /* The function nulls the rest of the buffer! */
92 for (i
= Length
+ sizeof(UNICODE_NULL
); i
< MaximumLength
; i
++)
94 UCHAR Char
= ((PUCHAR
)Buffer
)[i
];
97 ok(0, "Found 0x%x at offset %lu, expected 0x%x\n", Char
, (ULONG
)i
, 0);
98 /* Don't count this as a failure unless the string was actually wrong */
100 /* Don't flood the log */
115 PUCHAR Array
= Buffer
;
118 for (i
= 0; i
< Size
; i
++)
119 if (Array
[i
] != Value
)
121 trace("Expected %x, found %x at offset %lu\n", Value
, Array
[i
], (ULONG
)i
);
127 #define RtlPathTypeNotSet 123
128 #define InvalidPointer ((PVOID)0x0123456789ABCDEFULL)
130 /* winetest_platform is "windows" for us, so broken() doesn't do what it should :( */
139 PrefixCurrentPathWithoutLastPart
146 /* TODO: don't duplicate this in the other tests */
147 /* TODO: Drive Relative tests don't work yet if the current drive isn't C: */
151 PREFIX_TYPE PrefixType
;
153 RTL_PATH_TYPE PathType
;
154 PREFIX_TYPE FilePartPrefixType
;
158 { L
"C:", PrefixCurrentPath
, L
"", RtlPathTypeDriveRelative
, PrefixCurrentPathWithoutLastPart
},
159 { L
"C:\\", PrefixNone
, L
"C:\\", RtlPathTypeDriveAbsolute
},
160 { L
"C:\\test", PrefixNone
, L
"C:\\test", RtlPathTypeDriveAbsolute
, PrefixCurrentDrive
},
161 { L
"C:\\test\\", PrefixNone
, L
"C:\\test\\", RtlPathTypeDriveAbsolute
},
162 { L
"C:/test/", PrefixNone
, L
"C:\\test\\", RtlPathTypeDriveAbsolute
},
164 { L
"C:\\\\test", PrefixNone
, L
"C:\\test", RtlPathTypeDriveAbsolute
, PrefixCurrentDrive
},
165 { L
"test", PrefixCurrentPath
, L
"\\test", RtlPathTypeRelative
, PrefixCurrentPath
, sizeof(WCHAR
) },
166 { L
"\\test", PrefixCurrentDrive
, L
"test", RtlPathTypeRooted
, PrefixCurrentDrive
},
167 { L
"/test", PrefixCurrentDrive
, L
"test", RtlPathTypeRooted
, PrefixCurrentDrive
},
168 { L
".\\test", PrefixCurrentPath
, L
"\\test", RtlPathTypeRelative
, PrefixCurrentPath
, sizeof(WCHAR
) },
170 { L
"\\.", PrefixCurrentDrive
, L
"", RtlPathTypeRooted
},
171 { L
"\\.\\", PrefixCurrentDrive
, L
"", RtlPathTypeRooted
},
172 { L
"\\\\.", PrefixNone
, L
"\\\\.\\", RtlPathTypeRootLocalDevice
},
173 { L
"\\\\.\\", PrefixNone
, L
"\\\\.\\", RtlPathTypeLocalDevice
},
174 { L
"\\\\.\\Something\\", PrefixNone
, L
"\\\\.\\Something\\", RtlPathTypeLocalDevice
},
176 { L
"\\??\\", PrefixCurrentDrive
, L
"??\\", RtlPathTypeRooted
},
177 { L
"\\??\\C:", PrefixCurrentDrive
, L
"??\\C:", RtlPathTypeRooted
, PrefixCurrentDrive
, 3 * sizeof(WCHAR
) },
178 { L
"\\??\\C:\\", PrefixCurrentDrive
, L
"??\\C:\\", RtlPathTypeRooted
},
179 { L
"\\??\\C:\\test", PrefixCurrentDrive
, L
"??\\C:\\test", RtlPathTypeRooted
, PrefixCurrentDrive
, 6 * sizeof(WCHAR
) },
180 { L
"\\??\\C:\\test\\", PrefixCurrentDrive
, L
"??\\C:\\test\\", RtlPathTypeRooted
},
182 { L
"\\\\??\\", PrefixNone
, L
"\\\\??\\", RtlPathTypeUncAbsolute
},
183 { L
"\\\\??\\C:", PrefixNone
, L
"\\\\??\\C:", RtlPathTypeUncAbsolute
},
184 { L
"\\\\??\\C:\\", PrefixNone
, L
"\\\\??\\C:\\", RtlPathTypeUncAbsolute
},
185 { L
"\\\\??\\C:\\test", PrefixNone
, L
"\\\\??\\C:\\test", RtlPathTypeUncAbsolute
, PrefixNone
, sizeof(L
"\\\\??\\C:\\") },
186 { L
"\\\\??\\C:\\test\\", PrefixNone
, L
"\\\\??\\C:\\test\\", RtlPathTypeUncAbsolute
},
188 NTSTATUS ExceptionStatus
;
190 UNICODE_STRING FileName
;
191 WCHAR FullPathNameBuffer
[MAX_PATH
];
192 UNICODE_STRING TempString
;
193 const WCHAR
*ShortName
;
195 PATH_TYPE_AND_UNKNOWN PathType
;
196 WCHAR ExpectedPathName
[MAX_PATH
];
197 SIZE_T ExpectedFilePartSize
;
198 const WCHAR
*ExpectedShortName
;
199 const INT TestCount
= sizeof(TestCases
) / sizeof(TestCases
[0]);
203 for (i
= 0; i
< TestCount
; i
++)
205 trace("i = %d\n", i
);
206 switch (TestCases
[i
].PrefixType
)
209 ExpectedPathName
[0] = UNICODE_NULL
;
211 case PrefixCurrentDrive
:
212 GetCurrentDirectoryW(sizeof(ExpectedPathName
) / sizeof(WCHAR
), ExpectedPathName
);
213 ExpectedPathName
[3] = UNICODE_NULL
;
215 case PrefixCurrentPath
:
218 Length
= GetCurrentDirectoryW(sizeof(ExpectedPathName
) / sizeof(WCHAR
), ExpectedPathName
);
219 if (Length
== 3 && TestCases
[i
].FullPathName
[0])
220 ExpectedPathName
[2] = UNICODE_NULL
;
224 skip(0, "Invalid test!\n");
227 wcscat(ExpectedPathName
, TestCases
[i
].FullPathName
);
228 RtlInitUnicodeString(&FileName
, TestCases
[i
].FileName
);
229 RtlFillMemory(FullPathNameBuffer
, sizeof(FullPathNameBuffer
), 0xAA);
230 TempString
= FileName
;
231 PathType
.Type
= RtlPathTypeNotSet
;
232 PathType
.Unknown
= 1234;
233 ShortName
= InvalidPointer
;
234 NameInvalid
= (BOOLEAN
)-1;
237 Length
= RtlGetFullPathName_Ustr(&FileName
,
238 sizeof(FullPathNameBuffer
),
243 EndSeh(STATUS_SUCCESS
);
244 ok_eq_ustr(&FileName
, &TempString
);
245 Okay
= CheckStringBuffer(FullPathNameBuffer
, Length
, sizeof(FullPathNameBuffer
), ExpectedPathName
);
246 ok(Okay
, "Wrong path name '%S', expected '%S'\n", FullPathNameBuffer
, ExpectedPathName
);
247 switch (TestCases
[i
].FilePartPrefixType
)
250 ExpectedFilePartSize
= 0;
252 case PrefixCurrentDrive
:
253 ExpectedFilePartSize
= sizeof(L
"C:\\");
255 case PrefixCurrentPath
:
256 ExpectedFilePartSize
= GetCurrentDirectoryW(0, NULL
) * sizeof(WCHAR
);
257 if (ExpectedFilePartSize
== sizeof(L
"C:\\"))
258 ExpectedFilePartSize
-= sizeof(WCHAR
);
260 case PrefixCurrentPathWithoutLastPart
:
262 WCHAR CurrentPath
[MAX_PATH
];
264 ExpectedFilePartSize
= GetCurrentDirectoryW(sizeof(CurrentPath
) / sizeof(WCHAR
), CurrentPath
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
265 if (ExpectedFilePartSize
== sizeof(L
"C:\\"))
266 ExpectedFilePartSize
= 0;
269 BackSlash
= wcsrchr(CurrentPath
, L
'\\');
271 ExpectedFilePartSize
-= wcslen(BackSlash
+ 1) * sizeof(WCHAR
);
273 ok(0, "GetCurrentDirectory returned %S\n", CurrentPath
);
278 skip(0, "Invalid test!\n");
281 ExpectedFilePartSize
+= TestCases
[i
].FilePartSize
;
282 if (ExpectedFilePartSize
== 0)
284 ExpectedShortName
= NULL
;
288 ExpectedFilePartSize
= (ExpectedFilePartSize
- sizeof(UNICODE_NULL
)) / sizeof(WCHAR
);
289 ExpectedShortName
= FullPathNameBuffer
+ ExpectedFilePartSize
;
291 ok(ShortName
== ExpectedShortName
,
292 "ShortName = %p, expected %p\n", ShortName
, ExpectedShortName
);
293 ok(NameInvalid
== FALSE
, "NameInvalid = %u\n", NameInvalid
);
294 ok(PathType
.Type
== TestCases
[i
].PathType
, "PathType = %d, expected %d\n", PathType
.Type
, TestCases
[i
].PathType
);
295 ok(PathType
.Unknown
== 1234 ||
296 broken(PathType
.Unknown
== 0) ||
297 broken(PathType
.Unknown
== 32), "Unknown = %d\n", PathType
.Unknown
);
301 START_TEST(RtlGetFullPathName_Ustr
)
303 NTSTATUS ExceptionStatus
;
305 UNICODE_STRING FileName
;
306 UNICODE_STRING TempString
;
309 BOOLEAN NameInvalidArray
[sizeof(ULONGLONG
)];
310 PATH_TYPE_AND_UNKNOWN PathType
;
313 if (!RtlGetFullPathName_Ustr
)
315 RtlGetFullPathName_Ustr
= (PVOID
)GetProcAddress(GetModuleHandle(L
"ntdll"), "RtlGetFullPathName_Ustr");
316 if (!RtlGetFullPathName_Ustr
)
318 skip("RtlGetFullPathName_Ustr unavailable\n");
323 /* NULL parameters */
325 RtlGetFullPathName_Ustr(NULL
, 0, NULL
, NULL
, NULL
, NULL
);
326 EndSeh(STATUS_ACCESS_VIOLATION
);
328 RtlInitUnicodeString(&FileName
, NULL
);
329 TempString
= FileName
;
331 RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, NULL
);
332 EndSeh(STATUS_ACCESS_VIOLATION
);
333 ok_eq_ustr(&FileName
, &TempString
);
335 RtlInitUnicodeString(&FileName
, L
"");
336 TempString
= FileName
;
338 RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, NULL
);
339 EndSeh(STATUS_ACCESS_VIOLATION
);
340 ok_eq_ustr(&FileName
, &TempString
);
342 PathType
.Type
= RtlPathTypeNotSet
;
343 PathType
.Unknown
= 1234;
345 RtlGetFullPathName_Ustr(NULL
, 0, NULL
, NULL
, NULL
, &PathType
);
346 EndSeh(STATUS_ACCESS_VIOLATION
);
347 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
348 ok(PathType
.Unknown
== 1234 ||
349 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
351 /* check what else is initialized before it crashes */
352 PathType
.Type
= RtlPathTypeNotSet
;
353 PathType
.Unknown
= 1234;
354 ShortName
= InvalidPointer
;
355 NameInvalid
= (BOOLEAN
)-1;
357 RtlGetFullPathName_Ustr(NULL
, 0, NULL
, &ShortName
, &NameInvalid
, &PathType
);
358 EndSeh(STATUS_ACCESS_VIOLATION
);
359 ok(NameInvalid
== FALSE
, "NameInvalid = %u\n", NameInvalid
);
360 ok(ShortName
== InvalidPointer
||
361 broken(ShortName
== NULL
) /* Win7 */, "ShortName = %p\n", ShortName
);
362 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
363 ok(PathType
.Unknown
== 1234 ||
364 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
366 RtlInitUnicodeString(&FileName
, L
"");
367 TempString
= FileName
;
368 ShortName
= InvalidPointer
;
369 NameInvalid
= (BOOLEAN
)-1;
371 RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, &ShortName
, &NameInvalid
, NULL
);
372 EndSeh(STATUS_ACCESS_VIOLATION
);
373 ok_eq_ustr(&FileName
, &TempString
);
374 ok(ShortName
== InvalidPointer
||
375 broken(ShortName
== NULL
) /* Win7 */, "ShortName = %p\n", ShortName
);
376 ok(NameInvalid
== FALSE
, "NameInvalid = %u\n", NameInvalid
);
378 /* This is the first one that doesn't crash. FileName and PathType cannot be NULL */
379 RtlInitUnicodeString(&FileName
, NULL
);
380 TempString
= FileName
;
381 PathType
.Type
= RtlPathTypeNotSet
;
382 PathType
.Unknown
= 1234;
384 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, &PathType
);
385 ok(Length
== 0, "Length = %lu\n", Length
);
386 EndSeh(STATUS_SUCCESS
);
387 ok_eq_ustr(&FileName
, &TempString
);
388 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
389 ok(PathType
.Unknown
== 1234 ||
390 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
392 RtlInitUnicodeString(&FileName
, L
"");
393 TempString
= FileName
;
394 PathType
.Type
= RtlPathTypeNotSet
;
395 PathType
.Unknown
= 1234;
397 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, &PathType
);
398 ok(Length
== 0, "Length = %lu\n", Length
);
399 EndSeh(STATUS_SUCCESS
);
400 ok_eq_ustr(&FileName
, &TempString
);
401 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
402 ok(PathType
.Unknown
== 1234 ||
403 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
405 /* Show that NameInvalid is indeed BOOLEAN */
406 RtlInitUnicodeString(&FileName
, L
"");
407 TempString
= FileName
;
408 PathType
.Type
= RtlPathTypeNotSet
;
409 PathType
.Unknown
= 1234;
410 RtlFillMemory(NameInvalidArray
, sizeof(NameInvalidArray
), 0x55);
412 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NameInvalidArray
, &PathType
);
413 ok(Length
== 0, "Length = %lu\n", Length
);
414 EndSeh(STATUS_SUCCESS
);
415 ok_eq_ustr(&FileName
, &TempString
);
416 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
417 ok(PathType
.Unknown
== 1234 ||
418 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
419 ok(NameInvalidArray
[0] == FALSE
, "NameInvalid = %u\n", NameInvalidArray
[0]);
420 Okay
= CheckBuffer(NameInvalidArray
+ 1, sizeof(NameInvalidArray
) - sizeof(NameInvalidArray
[0]), 0x55);
421 ok(Okay
, "CheckBuffer failed\n");
423 /* Give it a valid path */
424 RtlInitUnicodeString(&FileName
, L
"C:\\test");
425 TempString
= FileName
;
426 PathType
.Type
= RtlPathTypeNotSet
;
427 PathType
.Unknown
= 1234;
429 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, &PathType
);
430 ok(Length
== sizeof(L
"C:\\test"), "Length = %lu\n", Length
);
431 EndSeh(STATUS_SUCCESS
);
432 ok_eq_ustr(&FileName
, &TempString
);
433 ok(PathType
.Type
== RtlPathTypeDriveAbsolute
, "PathType = %d\n", PathType
.Type
);
434 ok(PathType
.Unknown
== 1234 ||
435 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
437 /* check the actual functionality with different paths */