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 <pseh/pseh2.h>
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)0x7769a3dd // win7 sp1 wow64
48 #define StartSeh() ExceptionStatus = STATUS_SUCCESS; _SEH2_TRY {
49 #define EndSeh(ExpectedStatus) } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; ok(ExceptionStatus == ExpectedStatus, "Exception %lx, expected %lx\n", ExceptionStatus, ExpectedStatus)
51 #define ok_eq_ustr(str1, str2) do { \
52 ok((str1)->Buffer == (str2)->Buffer, "Buffer modified\n"); \
53 ok((str1)->Length == (str2)->Length, "Length modified\n"); \
54 ok((str1)->MaximumLength == (str2)->MaximumLength, "MaximumLength modified\n"); \
65 USHORT ExpectedLength
= wcslen(Expected
) * sizeof(WCHAR
);
67 BOOLEAN Result
= TRUE
;
70 if (Length
!= ExpectedLength
)
72 ok(0, "String length is %u, expected %u\n", Length
, ExpectedLength
);
76 EqualLength
= RtlCompareMemory(Buffer
, Expected
, Length
);
77 if (EqualLength
!= Length
)
79 ok(0, "String is '%S', expected '%S'\n", Buffer
, Expected
);
83 if (Buffer
[Length
/ sizeof(WCHAR
)] != UNICODE_NULL
)
85 ok(0, "Not null terminated\n");
89 /* The function nulls the rest of the buffer! */
90 for (i
= Length
+ sizeof(UNICODE_NULL
); i
< MaximumLength
; i
++)
92 UCHAR Char
= ((PUCHAR
)Buffer
)[i
];
95 ok(0, "Found 0x%x at offset %lu, expected 0x%x\n", Char
, (ULONG
)i
, 0);
96 /* Don't count this as a failure unless the string was actually wrong */
98 /* Don't flood the log */
113 PUCHAR Array
= Buffer
;
116 for (i
= 0; i
< Size
; i
++)
117 if (Array
[i
] != Value
)
119 trace("Expected %x, found %x at offset %lu\n", Value
, Array
[i
], (ULONG
)i
);
125 #define RtlPathTypeNotSet 123
126 #define InvalidPointer ((PVOID)0x0123456789ABCDEFULL)
128 /* winetest_platform is "windows" for us, so broken() doesn't do what it should :( */
137 PrefixCurrentPathWithoutLastPart
144 /* TODO: don't duplicate this in the other tests */
145 /* TODO: Drive Relative tests don't work yet if the current drive isn't C: */
149 PREFIX_TYPE PrefixType
;
151 RTL_PATH_TYPE PathType
;
152 PREFIX_TYPE FilePartPrefixType
;
156 { L
"C:", PrefixCurrentPath
, L
"", RtlPathTypeDriveRelative
, PrefixCurrentPathWithoutLastPart
},
157 { L
"C:\\", PrefixNone
, L
"C:\\", RtlPathTypeDriveAbsolute
},
158 { L
"C:\\test", PrefixNone
, L
"C:\\test", RtlPathTypeDriveAbsolute
, PrefixCurrentDrive
},
159 { L
"C:\\test\\", PrefixNone
, L
"C:\\test\\", RtlPathTypeDriveAbsolute
},
160 { L
"C:/test/", PrefixNone
, L
"C:\\test\\", RtlPathTypeDriveAbsolute
},
162 { L
"C:\\\\test", PrefixNone
, L
"C:\\test", RtlPathTypeDriveAbsolute
, PrefixCurrentDrive
},
163 { L
"test", PrefixCurrentPath
, L
"\\test", RtlPathTypeRelative
, PrefixCurrentPath
, sizeof(WCHAR
) },
164 { L
"\\test", PrefixCurrentDrive
, L
"test", RtlPathTypeRooted
, PrefixCurrentDrive
},
165 { L
"/test", PrefixCurrentDrive
, L
"test", RtlPathTypeRooted
, PrefixCurrentDrive
},
166 { L
".\\test", PrefixCurrentPath
, L
"\\test", RtlPathTypeRelative
, PrefixCurrentPath
, sizeof(WCHAR
) },
168 { L
"\\.", PrefixCurrentDrive
, L
"", RtlPathTypeRooted
},
169 { L
"\\.\\", PrefixCurrentDrive
, L
"", RtlPathTypeRooted
},
170 { L
"\\\\.", PrefixNone
, L
"\\\\.\\", RtlPathTypeRootLocalDevice
},
171 { L
"\\\\.\\", PrefixNone
, L
"\\\\.\\", RtlPathTypeLocalDevice
},
172 { L
"\\\\.\\Something\\", PrefixNone
, L
"\\\\.\\Something\\", RtlPathTypeLocalDevice
},
174 { L
"\\??\\", PrefixCurrentDrive
, L
"??\\", RtlPathTypeRooted
},
175 { L
"\\??\\C:", PrefixCurrentDrive
, L
"??\\C:", RtlPathTypeRooted
, PrefixCurrentDrive
, 3 * sizeof(WCHAR
) },
176 { L
"\\??\\C:\\", PrefixCurrentDrive
, L
"??\\C:\\", RtlPathTypeRooted
},
177 { L
"\\??\\C:\\test", PrefixCurrentDrive
, L
"??\\C:\\test", RtlPathTypeRooted
, PrefixCurrentDrive
, 6 * sizeof(WCHAR
) },
178 { L
"\\??\\C:\\test\\", PrefixCurrentDrive
, L
"??\\C:\\test\\", RtlPathTypeRooted
},
180 { L
"\\\\??\\", PrefixNone
, L
"\\\\??\\", RtlPathTypeUncAbsolute
},
181 { L
"\\\\??\\C:", PrefixNone
, L
"\\\\??\\C:", RtlPathTypeUncAbsolute
},
182 { L
"\\\\??\\C:\\", PrefixNone
, L
"\\\\??\\C:\\", RtlPathTypeUncAbsolute
},
183 { L
"\\\\??\\C:\\test", PrefixNone
, L
"\\\\??\\C:\\test", RtlPathTypeUncAbsolute
, PrefixNone
, sizeof(L
"\\\\??\\C:\\") },
184 { L
"\\\\??\\C:\\test\\", PrefixNone
, L
"\\\\??\\C:\\test\\", RtlPathTypeUncAbsolute
},
186 NTSTATUS ExceptionStatus
;
188 UNICODE_STRING FileName
;
189 WCHAR FullPathNameBuffer
[MAX_PATH
];
190 UNICODE_STRING TempString
;
191 const WCHAR
*ShortName
;
193 PATH_TYPE_AND_UNKNOWN PathType
;
194 WCHAR ExpectedPathName
[MAX_PATH
];
195 SIZE_T ExpectedFilePartSize
;
196 const WCHAR
*ExpectedShortName
;
197 const INT TestCount
= sizeof(TestCases
) / sizeof(TestCases
[0]);
200 for (i
= 0; i
< TestCount
; i
++)
202 trace("i = %d\n", i
);
203 switch (TestCases
[i
].PrefixType
)
206 ExpectedPathName
[0] = UNICODE_NULL
;
208 case PrefixCurrentDrive
:
209 GetCurrentDirectoryW(sizeof(ExpectedPathName
) / sizeof(WCHAR
), ExpectedPathName
);
210 ExpectedPathName
[3] = UNICODE_NULL
;
212 case PrefixCurrentPath
:
215 Length
= GetCurrentDirectoryW(sizeof(ExpectedPathName
) / sizeof(WCHAR
), ExpectedPathName
);
216 if (Length
== 3 && TestCases
[i
].FullPathName
[0])
217 ExpectedPathName
[2] = UNICODE_NULL
;
221 skip(0, "Invalid test!\n");
224 wcscat(ExpectedPathName
, TestCases
[i
].FullPathName
);
225 RtlInitUnicodeString(&FileName
, TestCases
[i
].FileName
);
226 RtlFillMemory(FullPathNameBuffer
, sizeof(FullPathNameBuffer
), 0xAA);
227 TempString
= FileName
;
228 PathType
.Type
= RtlPathTypeNotSet
;
229 PathType
.Unknown
= 1234;
230 ShortName
= InvalidPointer
;
231 NameInvalid
= (BOOLEAN
)-1;
234 Length
= RtlGetFullPathName_Ustr(&FileName
,
235 sizeof(FullPathNameBuffer
),
240 EndSeh(STATUS_SUCCESS
);
241 ok_eq_ustr(&FileName
, &TempString
);
242 ok(CheckStringBuffer(FullPathNameBuffer
, Length
, sizeof(FullPathNameBuffer
), ExpectedPathName
),
243 "Wrong path name '%S', expected '%S'\n", FullPathNameBuffer
, ExpectedPathName
);
244 switch (TestCases
[i
].FilePartPrefixType
)
247 ExpectedFilePartSize
= 0;
249 case PrefixCurrentDrive
:
250 ExpectedFilePartSize
= sizeof(L
"C:\\");
252 case PrefixCurrentPath
:
253 ExpectedFilePartSize
= GetCurrentDirectoryW(0, NULL
) * sizeof(WCHAR
);
254 if (ExpectedFilePartSize
== sizeof(L
"C:\\"))
255 ExpectedFilePartSize
-= sizeof(WCHAR
);
257 case PrefixCurrentPathWithoutLastPart
:
259 WCHAR CurrentPath
[MAX_PATH
];
261 ExpectedFilePartSize
= GetCurrentDirectoryW(sizeof(CurrentPath
) / sizeof(WCHAR
), CurrentPath
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
262 if (ExpectedFilePartSize
== sizeof(L
"C:\\"))
263 ExpectedFilePartSize
= 0;
266 BackSlash
= wcsrchr(CurrentPath
, L
'\\');
268 ExpectedFilePartSize
-= wcslen(BackSlash
+ 1) * sizeof(WCHAR
);
270 ok(0, "GetCurrentDirectory returned %S\n", CurrentPath
);
275 skip(0, "Invalid test!\n");
278 ExpectedFilePartSize
+= TestCases
[i
].FilePartSize
;
279 if (ExpectedFilePartSize
== 0)
281 ExpectedShortName
= NULL
;
285 ExpectedFilePartSize
= (ExpectedFilePartSize
- sizeof(UNICODE_NULL
)) / sizeof(WCHAR
);
286 ExpectedShortName
= FullPathNameBuffer
+ ExpectedFilePartSize
;
288 ok(ShortName
== ExpectedShortName
,
289 "ShortName = %p, expected %p\n", ShortName
, ExpectedShortName
);
290 ok(NameInvalid
== FALSE
, "NameInvalid = %u\n", NameInvalid
);
291 ok(PathType
.Type
== TestCases
[i
].PathType
, "PathType = %d, expected %d\n", PathType
.Type
, TestCases
[i
].PathType
);
292 ok(PathType
.Unknown
== 1234 ||
293 broken(PathType
.Unknown
== 0) ||
294 broken(PathType
.Unknown
== 32), "Unknown = %d\n", PathType
.Unknown
);
298 START_TEST(RtlGetFullPathName_Ustr
)
300 NTSTATUS ExceptionStatus
;
302 UNICODE_STRING FileName
;
303 UNICODE_STRING TempString
;
306 BOOLEAN NameInvalidArray
[sizeof(ULONGLONG
)];
307 PATH_TYPE_AND_UNKNOWN PathType
;
309 if (!RtlGetFullPathName_Ustr
)
312 /* NULL parameters */
314 RtlGetFullPathName_Ustr(NULL
, 0, NULL
, NULL
, NULL
, NULL
);
315 EndSeh(STATUS_ACCESS_VIOLATION
);
317 RtlInitUnicodeString(&FileName
, NULL
);
318 TempString
= FileName
;
320 RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, NULL
);
321 EndSeh(STATUS_ACCESS_VIOLATION
);
322 ok_eq_ustr(&FileName
, &TempString
);
324 RtlInitUnicodeString(&FileName
, L
"");
325 TempString
= FileName
;
327 RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, NULL
);
328 EndSeh(STATUS_ACCESS_VIOLATION
);
329 ok_eq_ustr(&FileName
, &TempString
);
331 PathType
.Type
= RtlPathTypeNotSet
;
332 PathType
.Unknown
= 1234;
334 RtlGetFullPathName_Ustr(NULL
, 0, NULL
, NULL
, NULL
, &PathType
);
335 EndSeh(STATUS_ACCESS_VIOLATION
);
336 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
337 ok(PathType
.Unknown
== 1234 ||
338 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
340 /* check what else is initialized before it crashes */
341 PathType
.Type
= RtlPathTypeNotSet
;
342 PathType
.Unknown
= 1234;
343 ShortName
= InvalidPointer
;
344 NameInvalid
= (BOOLEAN
)-1;
346 RtlGetFullPathName_Ustr(NULL
, 0, NULL
, &ShortName
, &NameInvalid
, &PathType
);
347 EndSeh(STATUS_ACCESS_VIOLATION
);
348 ok(NameInvalid
== FALSE
, "NameInvalid = %u\n", NameInvalid
);
349 ok(ShortName
== InvalidPointer
||
350 broken(ShortName
== NULL
) /* Win7 */, "ShortName = %p\n", ShortName
);
351 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
352 ok(PathType
.Unknown
== 1234 ||
353 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
355 RtlInitUnicodeString(&FileName
, L
"");
356 TempString
= FileName
;
357 ShortName
= InvalidPointer
;
358 NameInvalid
= (BOOLEAN
)-1;
360 RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, &ShortName
, &NameInvalid
, NULL
);
361 EndSeh(STATUS_ACCESS_VIOLATION
);
362 ok_eq_ustr(&FileName
, &TempString
);
363 ok(ShortName
== InvalidPointer
||
364 broken(ShortName
== NULL
) /* Win7 */, "ShortName = %p\n", ShortName
);
365 ok(NameInvalid
== FALSE
, "NameInvalid = %u\n", NameInvalid
);
367 /* This is the first one that doesn't crash. FileName and PathType cannot be NULL */
368 RtlInitUnicodeString(&FileName
, NULL
);
369 TempString
= FileName
;
370 PathType
.Type
= RtlPathTypeNotSet
;
371 PathType
.Unknown
= 1234;
373 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, &PathType
);
374 ok(Length
== 0, "Length = %lu\n", Length
);
375 EndSeh(STATUS_SUCCESS
);
376 ok_eq_ustr(&FileName
, &TempString
);
377 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
378 ok(PathType
.Unknown
== 1234 ||
379 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
381 RtlInitUnicodeString(&FileName
, L
"");
382 TempString
= FileName
;
383 PathType
.Type
= RtlPathTypeNotSet
;
384 PathType
.Unknown
= 1234;
386 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, &PathType
);
387 ok(Length
== 0, "Length = %lu\n", Length
);
388 EndSeh(STATUS_SUCCESS
);
389 ok_eq_ustr(&FileName
, &TempString
);
390 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
391 ok(PathType
.Unknown
== 1234 ||
392 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
394 /* Show that NameInvalid is indeed BOOLEAN */
395 RtlInitUnicodeString(&FileName
, L
"");
396 TempString
= FileName
;
397 PathType
.Type
= RtlPathTypeNotSet
;
398 PathType
.Unknown
= 1234;
399 RtlFillMemory(NameInvalidArray
, sizeof(NameInvalidArray
), 0x55);
401 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NameInvalidArray
, &PathType
);
402 ok(Length
== 0, "Length = %lu\n", Length
);
403 EndSeh(STATUS_SUCCESS
);
404 ok_eq_ustr(&FileName
, &TempString
);
405 ok(PathType
.Type
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
.Type
);
406 ok(PathType
.Unknown
== 1234 ||
407 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
408 ok(NameInvalidArray
[0] == FALSE
, "NameInvalid = %u\n", NameInvalidArray
[0]);
409 ok(CheckBuffer(NameInvalidArray
+ 1, sizeof(NameInvalidArray
) - sizeof(NameInvalidArray
[0]), 0x55), "CheckBuffer failed\n");
411 /* Give it a valid path */
412 RtlInitUnicodeString(&FileName
, L
"C:\\test");
413 TempString
= FileName
;
414 PathType
.Type
= RtlPathTypeNotSet
;
415 PathType
.Unknown
= 1234;
417 Length
= RtlGetFullPathName_Ustr(&FileName
, 0, NULL
, NULL
, NULL
, &PathType
);
418 ok(Length
== sizeof(L
"C:\\test"), "Length = %lu\n", Length
);
419 EndSeh(STATUS_SUCCESS
);
420 ok_eq_ustr(&FileName
, &TempString
);
421 ok(PathType
.Type
== RtlPathTypeDriveAbsolute
, "PathType = %d\n", PathType
.Type
);
422 ok(PathType
.Unknown
== 1234 ||
423 broken(PathType
.Unknown
== 0) /* Win7 */, "Unknown = %d\n", PathType
.Unknown
);
425 /* check the actual functionality with different paths */