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 <thomas.faber@reactos.org>
10 #define WIN32_NO_STATUS
11 #include <ndk/rtlfuncs.h>
16 RtlGetFullPathName_Ustr(
17 IN PCUNICODE_STRING FileName,
20 OUT PCWSTR *ShortName,
21 OUT PBOOLEAN InvalidName,
22 OUT RTL_PATH_TYPE* PathType
26 /* This seems to be a struct of some kind in Windows 7... returns 0 or 32 in the second member */
27 typedef struct _PATH_TYPE_AND_UNKNOWN
31 } PATH_TYPE_AND_UNKNOWN
;
36 *RtlGetFullPathName_Ustr
)(
37 IN PCUNICODE_STRING FileName
,
40 OUT PCWSTR
*ShortName
,
41 OUT PBOOLEAN InvalidName
,
42 OUT PATH_TYPE_AND_UNKNOWN
*PathType
44 //= (PVOID)0x7c83086c // 2003 sp1 x86
45 //= (PVOID)0x77ef49f0 // 2003 sp1 x64
46 //= (PVOID)0x7769a3dd // win7 sp1 wow64
49 #define ok_eq_ustr(str1, str2) do { \
50 ok((str1)->Buffer == (str2)->Buffer, "Buffer modified\n"); \
51 ok((str1)->Length == (str2)->Length, "Length modified\n"); \
52 ok((str1)->MaximumLength == (str2)->MaximumLength, "MaximumLength modified\n"); \
63 SIZE_T ExpectedLength
= wcslen(Expected
) * sizeof(WCHAR
);
65 BOOLEAN Result
= TRUE
;
68 if (Length
!= ExpectedLength
)
70 ok(0, "String length is %lu, expected %lu\n", (ULONG
)Length
, (ULONG
)ExpectedLength
);
74 EqualLength
= RtlCompareMemory(Buffer
, Expected
, Length
);
75 if (EqualLength
!= Length
)
77 ok(0, "String is '%S', expected '%S'\n", Buffer
, Expected
);
81 if (Buffer
[Length
/ sizeof(WCHAR
)] != UNICODE_NULL
)
83 ok(0, "Not null terminated\n");
87 /* The function nulls the rest of the buffer! */
88 for (i
= Length
+ sizeof(UNICODE_NULL
); i
< MaximumLength
; i
++)
90 UCHAR Char
= ((PUCHAR
)Buffer
)[i
];
93 ok(0, "Found 0x%x at offset %lu, expected 0x%x\n", Char
, (ULONG
)i
, 0);
94 /* Don't count this as a failure unless the string was actually wrong */
96 /* Don't flood the log */
111 PUCHAR Array
= Buffer
;
114 for (i
= 0; i
< Size
; i
++)
115 if (Array
[i
] != Value
)
117 trace("Expected %x, found %x at offset %lu\n", Value
, Array
[i
], (ULONG
)i
);
123 #define RtlPathTypeNotSet 123
125 /* winetest_platform is "windows" for us, so broken() doesn't do what it should :( */
134 PrefixCurrentPathWithoutLastPart
141 /* TODO: don't duplicate this in the other tests */
142 /* TODO: Drive Relative tests don't work yet if the current drive isn't C: */
146 PREFIX_TYPE PrefixType
;
148 RTL_PATH_TYPE PathType
;
149 PREFIX_TYPE FilePartPrefixType
;
153 { L
"C:", PrefixCurrentPath
, L
"", RtlPathTypeDriveRelative
, PrefixCurrentPathWithoutLastPart
},
154 { L
"C:\\", PrefixNone
, L
"C:\\", RtlPathTypeDriveAbsolute
},
155 { L
"C:\\test", PrefixNone
, L
"C:\\test", RtlPathTypeDriveAbsolute
, PrefixCurrentDrive
},
156 { L
"C:\\test\\", PrefixNone
, L
"C:\\test\\", RtlPathTypeDriveAbsolute
},
157 { L
"C:/test/", PrefixNone
, L
"C:\\test\\", RtlPathTypeDriveAbsolute
},
159 { L
"C:\\\\test", PrefixNone
, L
"C:\\test", RtlPathTypeDriveAbsolute
, PrefixCurrentDrive
},
160 { L
"test", PrefixCurrentPath
, L
"\\test", RtlPathTypeRelative
, PrefixCurrentPath
, sizeof(WCHAR
) },
161 { L
"\\test", PrefixCurrentDrive
, L
"test", RtlPathTypeRooted
, PrefixCurrentDrive
},
162 { L
"/test", PrefixCurrentDrive
, L
"test", RtlPathTypeRooted
, PrefixCurrentDrive
},
163 { L
".\\test", PrefixCurrentPath
, L
"\\test", RtlPathTypeRelative
, PrefixCurrentPath
, sizeof(WCHAR
) },
165 { L
"\\.", PrefixCurrentDrive
, L
"", RtlPathTypeRooted
},
166 { L
"\\.\\", PrefixCurrentDrive
, L
"", RtlPathTypeRooted
},
167 { L
"\\\\.", PrefixNone
, L
"\\\\.\\", RtlPathTypeRootLocalDevice
},
168 { L
"\\\\.\\", PrefixNone
, L
"\\\\.\\", RtlPathTypeLocalDevice
},
169 { L
"\\\\.\\Something\\", PrefixNone
, L
"\\\\.\\Something\\", RtlPathTypeLocalDevice
},
171 { L
"\\??\\", PrefixCurrentDrive
, L
"??\\", RtlPathTypeRooted
},
172 { L
"\\??\\C:", PrefixCurrentDrive
, L
"??\\C:", RtlPathTypeRooted
, PrefixCurrentDrive
, 3 * sizeof(WCHAR
) },
173 { L
"\\??\\C:\\", PrefixCurrentDrive
, L
"??\\C:\\", RtlPathTypeRooted
},
174 { L
"\\??\\C:\\test", PrefixCurrentDrive
, L
"??\\C:\\test", RtlPathTypeRooted
, PrefixCurrentDrive
, 6 * sizeof(WCHAR
) },
175 { L
"\\??\\C:\\test\\", PrefixCurrentDrive
, L
"??\\C:\\test\\", RtlPathTypeRooted
},
177 { L
"\\\\??\\", PrefixNone
, L
"\\\\??\\", RtlPathTypeUncAbsolute
},
178 { L
"\\\\??\\C:", PrefixNone
, L
"\\\\??\\C:", RtlPathTypeUncAbsolute
},
179 { L
"\\\\??\\C:\\", PrefixNone
, L
"\\\\??\\C:\\", RtlPathTypeUncAbsolute
},
180 { L
"\\\\??\\C:\\test", PrefixNone
, L
"\\\\??\\C:\\test", RtlPathTypeUncAbsolute
, PrefixNone
, sizeof(L
"\\\\??\\C:\\") },
181 { L
"\\\\??\\C:\\test\\", PrefixNone
, L
"\\\\??\\C:\\test\\", RtlPathTypeUncAbsolute
},
184 UNICODE_STRING FileName
;
185 WCHAR FullPathNameBuffer
[MAX_PATH
];
186 UNICODE_STRING TempString
;
187 const WCHAR
*ShortName
;
189 PATH_TYPE_AND_UNKNOWN PathType
;
190 WCHAR ExpectedPathName
[MAX_PATH
];
191 SIZE_T ExpectedFilePartSize
;
192 const WCHAR
*ExpectedShortName
;
193 const INT TestCount
= sizeof(TestCases
) / sizeof(TestCases
[0]);
197 for (i
= 0; i
< TestCount
; i
++)
199 trace("i = %d\n", i
);
200 switch (TestCases
[i
].PrefixType
)
203 ExpectedPathName
[0] = UNICODE_NULL
;
205 case PrefixCurrentDrive
:
206 GetCurrentDirectoryW(sizeof(ExpectedPathName
) / sizeof(WCHAR
), ExpectedPathName
);
207 ExpectedPathName
[3] = UNICODE_NULL
;
209 case PrefixCurrentPath
:
212 Length
= GetCurrentDirectoryW(sizeof(ExpectedPathName
) / sizeof(WCHAR
), ExpectedPathName
);
213 if (Length
== 3 && TestCases
[i
].FullPathName
[0])
214 ExpectedPathName
[2] = UNICODE_NULL
;
218 skip("Invalid test!\n");
221 wcscat(ExpectedPathName
, TestCases
[i
].FullPathName
);
222 RtlInitUnicodeString(&FileName
, TestCases
[i
].FileName
);
223 RtlFillMemory(FullPathNameBuffer
, sizeof(FullPathNameBuffer
), 0xAA);
224 TempString
= FileName
;
225 PathType
.Type
= RtlPathTypeNotSet
;
226 PathType
.Unknown
= 1234;
227 ShortName
= InvalidPointer
;
228 NameInvalid
= (BOOLEAN
)-1;
231 Length
= RtlGetFullPathName_Ustr(&FileName
,
232 sizeof(FullPathNameBuffer
),
237 EndSeh(STATUS_SUCCESS
);
238 ok_eq_ustr(&FileName
, &TempString
);
239 Okay
= CheckStringBuffer(FullPathNameBuffer
, Length
, sizeof(FullPathNameBuffer
), ExpectedPathName
);
240 ok(Okay
, "Wrong path name '%S', expected '%S'\n", FullPathNameBuffer
, ExpectedPathName
);
241 switch (TestCases
[i
].FilePartPrefixType
)
244 ExpectedFilePartSize
= 0;
246 case PrefixCurrentDrive
:
247 ExpectedFilePartSize
= sizeof(L
"C:\\");
249 case PrefixCurrentPath
:
250 ExpectedFilePartSize
= GetCurrentDirectoryW(0, NULL
) * sizeof(WCHAR
);
251 if (ExpectedFilePartSize
== sizeof(L
"C:\\"))
252 ExpectedFilePartSize
-= sizeof(WCHAR
);
254 case PrefixCurrentPathWithoutLastPart
:
256 WCHAR CurrentPath
[MAX_PATH
];
258 ExpectedFilePartSize
= GetCurrentDirectoryW(sizeof(CurrentPath
) / sizeof(WCHAR
), CurrentPath
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
259 if (ExpectedFilePartSize
== sizeof(L
"C:\\"))
260 ExpectedFilePartSize
= 0;
263 BackSlash
= wcsrchr(CurrentPath
, L
'\\');
265 ExpectedFilePartSize
-= wcslen(BackSlash
+ 1) * sizeof(WCHAR
);
267 ok(0, "GetCurrentDirectory returned %S\n", CurrentPath
);
272 skip("Invalid test!\n");
275 ExpectedFilePartSize
+= TestCases
[i
].FilePartSize
;
276 if (ExpectedFilePartSize
== 0)
278 ExpectedShortName
= NULL
;
282 ExpectedFilePartSize
= (ExpectedFilePartSize
- sizeof(UNICODE_NULL
)) / sizeof(WCHAR
);
283 ExpectedShortName
= FullPathNameBuffer
+ ExpectedFilePartSize
;
285 ok(ShortName
== ExpectedShortName
,
286 "ShortName = %p, expected %p\n", ShortName
, ExpectedShortName
);
287 ok(NameInvalid
== FALSE
, "NameInvalid = %u\n", NameInvalid
);
288 ok(PathType
.Type
== TestCases
[i
].PathType
, "PathType = %d, expected %d\n", PathType
.Type
, TestCases
[i
].PathType
);
289 ok(PathType
.Unknown
== 1234 ||
290 broken(PathType
.Unknown
== 0) ||
291 broken(PathType
.Unknown
== 32), "Unknown = %lu\n", PathType
.Unknown
);
295 START_TEST(RtlGetFullPathName_Ustr
)
298 UNICODE_STRING FileName
;
299 UNICODE_STRING TempString
;
302 BOOLEAN NameInvalidArray
[sizeof(ULONGLONG
)];
303 PATH_TYPE_AND_UNKNOWN PathType
;
306 if (!RtlGetFullPathName_Ustr
)
308 RtlGetFullPathName_Ustr
= (PVOID
)GetProcAddress(GetModuleHandleW(L
"ntdll"), "RtlGetFullPathName_Ustr");
309 if (!RtlGetFullPathName_Ustr
)
311 skip("RtlGetFullPathName_Ustr unavailable\n");
316 /* NULL parameters */
318 RtlGetFullPathName_Ustr(NULL
, 0, NULL
, NULL
, NULL
, NULL
);
319 EndSeh(STATUS_ACCESS_VIOLATION
);
321 RtlInitUnicodeString(&FileName
, NULL
);
322 TempString
= FileName
;
324 RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, NULL
);
325 EndSeh(STATUS_ACCESS_VIOLATION
);
326 ok_eq_ustr(&FileName
, &TempString
);
328 RtlInitUnicodeString(&FileName
, L
"");
329 TempString
= FileName
;
331 RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, NULL
);
332 EndSeh(STATUS_ACCESS_VIOLATION
);
333 ok_eq_ustr(&FileName
, &TempString
);
335 PathType
.Type
= RtlPathTypeNotSet
;
336 PathType
.Unknown
= 1234;
338 RtlGetFullPathName_Ustr(NULL
, 0, NULL
, NULL
, NULL
, &PathType
);
339 EndSeh(STATUS_ACCESS_VIOLATION
);
340 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
341 ok(PathType
.Unknown
== 1234 ||
342 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %lu\n", PathType
.Unknown
);
344 /* check what else is initialized before it crashes */
345 PathType
.Type
= RtlPathTypeNotSet
;
346 PathType
.Unknown
= 1234;
347 ShortName
= InvalidPointer
;
348 NameInvalid
= (BOOLEAN
)-1;
350 RtlGetFullPathName_Ustr(NULL
, 0, NULL
, &ShortName
, &NameInvalid
, &PathType
);
351 EndSeh(STATUS_ACCESS_VIOLATION
);
352 ok(NameInvalid
== FALSE
, "NameInvalid = %u\n", NameInvalid
);
353 ok(ShortName
== InvalidPointer
||
354 broken(ShortName
== NULL
) /* Win7 */, "ShortName = %p\n", ShortName
);
355 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
356 ok(PathType
.Unknown
== 1234 ||
357 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %lu\n", PathType
.Unknown
);
359 RtlInitUnicodeString(&FileName
, L
"");
360 TempString
= FileName
;
361 ShortName
= InvalidPointer
;
362 NameInvalid
= (BOOLEAN
)-1;
364 RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, &ShortName
, &NameInvalid
, NULL
);
365 EndSeh(STATUS_ACCESS_VIOLATION
);
366 ok_eq_ustr(&FileName
, &TempString
);
367 ok(ShortName
== InvalidPointer
||
368 broken(ShortName
== NULL
) /* Win7 */, "ShortName = %p\n", ShortName
);
369 ok(NameInvalid
== FALSE
, "NameInvalid = %u\n", NameInvalid
);
371 /* This is the first one that doesn't crash. FileName and PathType cannot be NULL */
372 RtlInitUnicodeString(&FileName
, NULL
);
373 TempString
= FileName
;
374 PathType
.Type
= RtlPathTypeNotSet
;
375 PathType
.Unknown
= 1234;
377 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, &PathType
);
378 ok(Length
== 0, "Length = %lu\n", Length
);
379 EndSeh(STATUS_SUCCESS
);
380 ok_eq_ustr(&FileName
, &TempString
);
381 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
382 ok(PathType
.Unknown
== 1234 ||
383 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %lu\n", PathType
.Unknown
);
385 RtlInitUnicodeString(&FileName
, L
"");
386 TempString
= FileName
;
387 PathType
.Type
= RtlPathTypeNotSet
;
388 PathType
.Unknown
= 1234;
390 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, &PathType
);
391 ok(Length
== 0, "Length = %lu\n", Length
);
392 EndSeh(STATUS_SUCCESS
);
393 ok_eq_ustr(&FileName
, &TempString
);
394 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
395 ok(PathType
.Unknown
== 1234 ||
396 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %lu\n", PathType
.Unknown
);
398 /* Show that NameInvalid is indeed BOOLEAN */
399 RtlInitUnicodeString(&FileName
, L
"");
400 TempString
= FileName
;
401 PathType
.Type
= RtlPathTypeNotSet
;
402 PathType
.Unknown
= 1234;
403 RtlFillMemory(NameInvalidArray
, sizeof(NameInvalidArray
), 0x55);
405 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NameInvalidArray
, &PathType
);
406 ok(Length
== 0, "Length = %lu\n", Length
);
407 EndSeh(STATUS_SUCCESS
);
408 ok_eq_ustr(&FileName
, &TempString
);
409 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
410 ok(PathType
.Unknown
== 1234 ||
411 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %lu\n", PathType
.Unknown
);
412 ok(NameInvalidArray
[0] == FALSE
, "NameInvalid = %u\n", NameInvalidArray
[0]);
413 Okay
= CheckBuffer(NameInvalidArray
+ 1, sizeof(NameInvalidArray
) - sizeof(NameInvalidArray
[0]), 0x55);
414 ok(Okay
, "CheckBuffer failed\n");
416 /* Give it a valid path */
417 RtlInitUnicodeString(&FileName
, L
"C:\\test");
418 TempString
= FileName
;
419 PathType
.Type
= RtlPathTypeNotSet
;
420 PathType
.Unknown
= 1234;
422 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, &PathType
);
423 ok(Length
== sizeof(L
"C:\\test"), "Length = %lu\n", Length
);
424 EndSeh(STATUS_SUCCESS
);
425 ok_eq_ustr(&FileName
, &TempString
);
426 ok(PathType
.Type
== RtlPathTypeDriveAbsolute
, "PathType = %d\n", PathType
.Type
);
427 ok(PathType
.Unknown
== 1234 ||
428 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %lu\n", PathType
.Unknown
);
430 /* check the actual functionality with different paths */