2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for RtlGetFullPathName_UstrEx
5 * PROGRAMMER: Thomas Faber <thfabba@gmx.de>
8 #define WIN32_NO_STATUS
10 #include <pseh/pseh2.h>
11 #include <ndk/rtlfuncs.h>
16 RtlGetFullPathName_UstrEx(
17 IN PUNICODE_STRING FileName,
18 IN PUNICODE_STRING StaticString,
19 IN PUNICODE_STRING DynamicString,
20 IN PUNICODE_STRING *StringUsed,
21 IN PSIZE_T FilePartSize OPTIONAL,
22 OUT PBOOLEAN NameInvalid,
23 OUT RTL_PATH_TYPE* PathType,
24 OUT PSIZE_T LengthNeeded OPTIONAL
28 #define StartSeh() ExceptionStatus = STATUS_SUCCESS; _SEH2_TRY {
29 #define EndSeh(ExpectedStatus) } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; ok(ExceptionStatus == ExpectedStatus, "Exception %lx, expected %lx\n", ExceptionStatus, ExpectedStatus)
31 #define ok_eq_ustr(str1, str2) do { \
32 ok((str1)->Buffer == (str2)->Buffer, "Buffer modified\n"); \
33 ok((str1)->Length == (str2)->Length, "Length modified\n"); \
34 ok((str1)->MaximumLength == (str2)->MaximumLength, "MaximumLength modified\n"); \
40 PCUNICODE_STRING String
,
43 USHORT Length
= wcslen(Expected
) * sizeof(WCHAR
);
45 BOOLEAN Result
= TRUE
;
48 if (String
->Length
!= Length
)
50 ok(0, "String length is %u, expected %u\n", String
->Length
, Length
);
54 EqualLength
= RtlCompareMemory(String
->Buffer
, Expected
, Length
);
55 if (EqualLength
!= Length
)
57 ok(0, "String is '%wZ', expected '%S'\n", String
, Expected
);
61 if (String
->Buffer
[String
->Length
/ sizeof(WCHAR
)] != UNICODE_NULL
)
63 ok(0, "Not null terminated\n");
67 /* the function nulls the rest of the buffer! */
68 for (i
= String
->Length
+ sizeof(UNICODE_NULL
); i
< String
->MaximumLength
; i
++)
70 UCHAR Char
= ((PUCHAR
)String
->Buffer
)[i
];
73 ok(0, "Found 0x%x at offset %lu, expected 0x%x\n", Char
, (ULONG
)i
, 0);
74 /* don't count this as a failure unless the string was actually wrong */
76 /* don't flood the log */
84 #define RtlPathTypeNotSet 123
85 #define InvalidPointer ((PVOID)0x0123456789ABCDEFULL)
87 /* winetest_platform is "windows" for us, so broken() doesn't do what it should :( */
96 PrefixCurrentPathWithoutLastPart
103 /* TODO: don't duplicate this here and in the RtlGetFullPathName_U test */
107 PREFIX_TYPE PrefixType
;
109 RTL_PATH_TYPE PathType
;
110 PREFIX_TYPE FilePartPrefixType
;
114 { L
"C:", PrefixCurrentPath
, L
"", RtlPathTypeDriveRelative
, PrefixCurrentPathWithoutLastPart
},
115 { L
"C:\\", PrefixNone
, L
"C:\\", RtlPathTypeDriveAbsolute
},
116 { L
"C:\\test", PrefixNone
, L
"C:\\test", RtlPathTypeDriveAbsolute
, PrefixCurrentDrive
},
117 { L
"C:\\test\\", PrefixNone
, L
"C:\\test\\", RtlPathTypeDriveAbsolute
},
118 { L
"C:/test/", PrefixNone
, L
"C:\\test\\", RtlPathTypeDriveAbsolute
},
120 { L
"C:\\\\test", PrefixNone
, L
"C:\\test", RtlPathTypeDriveAbsolute
, PrefixCurrentDrive
},
121 { L
"test", PrefixCurrentPath
, L
"\\test", RtlPathTypeRelative
, PrefixCurrentPath
, sizeof(WCHAR
) },
122 { L
"\\test", PrefixCurrentDrive
, L
"test", RtlPathTypeRooted
, PrefixCurrentDrive
},
123 { L
"/test", PrefixCurrentDrive
, L
"test", RtlPathTypeRooted
, PrefixCurrentDrive
},
124 { L
".\\test", PrefixCurrentPath
, L
"\\test", RtlPathTypeRelative
, PrefixCurrentPath
, sizeof(WCHAR
) },
126 { L
"\\.", PrefixCurrentDrive
, L
"", RtlPathTypeRooted
},
127 { L
"\\.\\", PrefixCurrentDrive
, L
"", RtlPathTypeRooted
},
128 { L
"\\\\.", PrefixNone
, L
"\\\\.\\", RtlPathTypeRootLocalDevice
},
129 { L
"\\\\.\\", PrefixNone
, L
"\\\\.\\", RtlPathTypeLocalDevice
},
130 { L
"\\\\.\\Something\\", PrefixNone
, L
"\\\\.\\Something\\", RtlPathTypeLocalDevice
},
132 { L
"\\??\\", PrefixCurrentDrive
, L
"??\\", RtlPathTypeRooted
},
133 { L
"\\??\\C:", PrefixCurrentDrive
, L
"??\\C:", RtlPathTypeRooted
, PrefixCurrentDrive
, 3 * sizeof(WCHAR
) },
134 { L
"\\??\\C:\\", PrefixCurrentDrive
, L
"??\\C:\\", RtlPathTypeRooted
},
135 { L
"\\??\\C:\\test", PrefixCurrentDrive
, L
"??\\C:\\test", RtlPathTypeRooted
, PrefixCurrentDrive
, 6 * sizeof(WCHAR
) },
136 { L
"\\??\\C:\\test\\", PrefixCurrentDrive
, L
"??\\C:\\test\\", RtlPathTypeRooted
},
138 { L
"\\\\??\\", PrefixNone
, L
"\\\\??\\", RtlPathTypeUncAbsolute
},
139 { L
"\\\\??\\C:", PrefixNone
, L
"\\\\??\\C:", RtlPathTypeUncAbsolute
},
140 { L
"\\\\??\\C:\\", PrefixNone
, L
"\\\\??\\C:\\", RtlPathTypeUncAbsolute
},
141 { L
"\\\\??\\C:\\test", PrefixNone
, L
"\\\\??\\C:\\test", RtlPathTypeUncAbsolute
, PrefixNone
, sizeof(L
"\\\\??\\C:\\") },
142 { L
"\\\\??\\C:\\test\\", PrefixNone
, L
"\\\\??\\C:\\test\\", RtlPathTypeUncAbsolute
},
144 NTSTATUS Status
, ExceptionStatus
;
145 UNICODE_STRING FileName
;
146 UNICODE_STRING FullPathName
;
147 WCHAR FullPathNameBuffer
[MAX_PATH
];
148 UNICODE_STRING TempString
;
149 PUNICODE_STRING StringUsed
;
152 RTL_PATH_TYPE PathType
;
154 WCHAR ExpectedPathName
[MAX_PATH
];
155 SIZE_T ExpectedFilePartSize
;
156 const INT TestCount
= sizeof(TestCases
) / sizeof(TestCases
[0]);
159 for (i
= 0; i
< TestCount
; i
++)
161 trace("i = %d\n", i
);
162 switch (TestCases
[i
].PrefixType
)
165 ExpectedPathName
[0] = UNICODE_NULL
;
167 case PrefixCurrentDrive
:
168 GetCurrentDirectoryW(sizeof(ExpectedPathName
) / sizeof(WCHAR
), ExpectedPathName
);
169 ExpectedPathName
[3] = UNICODE_NULL
;
171 case PrefixCurrentPath
:
174 Length
= GetCurrentDirectoryW(sizeof(ExpectedPathName
) / sizeof(WCHAR
), ExpectedPathName
);
175 if (Length
== 3 && TestCases
[i
].FullPathName
[0])
176 ExpectedPathName
[2] = UNICODE_NULL
;
180 skip(0, "Invalid test!\n");
183 wcscat(ExpectedPathName
, TestCases
[i
].FullPathName
);
184 RtlInitUnicodeString(&FileName
, TestCases
[i
].FileName
);
185 RtlInitEmptyUnicodeString(&FullPathName
, FullPathNameBuffer
, sizeof(FullPathNameBuffer
));
186 RtlFillMemory(FullPathName
.Buffer
, FullPathName
.MaximumLength
, 0xAA);
187 TempString
= FileName
;
188 PathType
= RtlPathTypeNotSet
;
189 StringUsed
= InvalidPointer
;
191 NameInvalid
= (BOOLEAN
)-1;
194 Status
= RtlGetFullPathName_UstrEx(&FileName
,
202 ok(Status
== STATUS_SUCCESS
, "status = %lx\n", Status
);
203 EndSeh(STATUS_SUCCESS
);
204 ok_eq_ustr(&FileName
, &TempString
);
205 ok(FullPathName
.Buffer
== FullPathNameBuffer
, "Buffer modified\n");
206 ok(FullPathName
.MaximumLength
== sizeof(FullPathNameBuffer
), "MaximumLength modified\n");
207 ok(CheckStringBuffer(&FullPathName
, ExpectedPathName
),
208 "Wrong path name '%wZ', expected '%S'\n", &FullPathName
, ExpectedPathName
);
209 ok(StringUsed
== &FullPathName
, "StringUsed = %p, expected %p\n", StringUsed
, &FullPathName
);
210 switch (TestCases
[i
].FilePartPrefixType
)
213 ExpectedFilePartSize
= 0;
215 case PrefixCurrentDrive
:
216 ExpectedFilePartSize
= sizeof(L
"C:\\");
218 case PrefixCurrentPath
:
219 ExpectedFilePartSize
= GetCurrentDirectoryW(0, NULL
) * sizeof(WCHAR
);
220 if (ExpectedFilePartSize
== sizeof(L
"C:\\"))
221 ExpectedFilePartSize
-= sizeof(WCHAR
);
223 case PrefixCurrentPathWithoutLastPart
:
225 WCHAR CurrentPath
[MAX_PATH
];
227 ExpectedFilePartSize
= GetCurrentDirectoryW(sizeof(CurrentPath
) / sizeof(WCHAR
), CurrentPath
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
228 if (ExpectedFilePartSize
== sizeof(L
"C:\\"))
229 ExpectedFilePartSize
= 0;
232 BackSlash
= wcsrchr(CurrentPath
, L
'\\');
234 ExpectedFilePartSize
-= wcslen(BackSlash
+ 1) * sizeof(WCHAR
);
236 ok(0, "GetCurrentDirectory returned %S\n", CurrentPath
);
241 skip(0, "Invalid test!\n");
244 ExpectedFilePartSize
+= TestCases
[i
].FilePartSize
;
245 if (ExpectedFilePartSize
!= 0)
246 ExpectedFilePartSize
= (ExpectedFilePartSize
- sizeof(UNICODE_NULL
)) / sizeof(WCHAR
);
247 ok(FilePartSize
== ExpectedFilePartSize
,
248 "FilePartSize = %lu, expected %lu\n", (ULONG
)FilePartSize
, (ULONG
)ExpectedFilePartSize
);
249 ok(NameInvalid
== FALSE
, "NameInvalid = %u\n", NameInvalid
);
250 ok(PathType
== TestCases
[i
].PathType
, "PathType = %d, expected %d\n", PathType
, TestCases
[i
].PathType
);
251 ok(LengthNeeded
== 0, "LengthNeeded = %lu\n", (ULONG
)LengthNeeded
);
255 START_TEST(RtlGetFullPathName_UstrEx
)
257 NTSTATUS Status
, ExceptionStatus
;
258 UNICODE_STRING FileName
;
259 UNICODE_STRING TempString
;
260 UNICODE_STRING StaticString
;
261 PUNICODE_STRING StringUsed
;
264 RTL_PATH_TYPE PathType
;
267 /* NULL parameters */
269 RtlGetFullPathName_UstrEx(NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
270 EndSeh(STATUS_ACCESS_VIOLATION
);
272 RtlInitUnicodeString(&FileName
, NULL
);
273 TempString
= FileName
;
275 RtlGetFullPathName_UstrEx(&FileName
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
276 EndSeh(STATUS_ACCESS_VIOLATION
);
277 ok_eq_ustr(&FileName
, &TempString
);
279 RtlInitUnicodeString(&FileName
, L
"");
280 TempString
= FileName
;
282 RtlGetFullPathName_UstrEx(&FileName
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
283 EndSeh(STATUS_ACCESS_VIOLATION
);
284 ok_eq_ustr(&FileName
, &TempString
);
286 PathType
= RtlPathTypeNotSet
;
288 RtlGetFullPathName_UstrEx(NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &PathType
, NULL
);
289 EndSeh(STATUS_ACCESS_VIOLATION
);
290 ok(PathType
== RtlPathTypeUnknown
||
291 broken(PathType
== RtlPathTypeNotSet
) /* Win7 */, "PathType = %d\n", PathType
);
293 /* Check what else is initialized before it crashes */
294 PathType
= RtlPathTypeNotSet
;
295 StringUsed
= InvalidPointer
;
297 NameInvalid
= (BOOLEAN
)-1;
300 RtlGetFullPathName_UstrEx(NULL
, NULL
, NULL
, &StringUsed
, &FilePartSize
, &NameInvalid
, &PathType
, &LengthNeeded
);
301 EndSeh(STATUS_ACCESS_VIOLATION
);
302 ok(StringUsed
== NULL
, "StringUsed = %p\n", StringUsed
);
303 ok(FilePartSize
== 0, "FilePartSize = %lu\n", (ULONG
)FilePartSize
);
304 ok(NameInvalid
== FALSE
, "NameInvalid = %u\n", NameInvalid
);
305 ok(PathType
== RtlPathTypeUnknown
||
306 broken(PathType
== RtlPathTypeNotSet
) /* Win7 */, "PathType = %d\n", PathType
);
307 ok(LengthNeeded
== 0, "LengthNeeded = %lu\n", (ULONG
)LengthNeeded
);
309 RtlInitUnicodeString(&FileName
, L
"");
310 TempString
= FileName
;
311 StringUsed
= InvalidPointer
;
313 NameInvalid
= (BOOLEAN
)-1;
316 RtlGetFullPathName_UstrEx(&FileName
, NULL
, NULL
, &StringUsed
, &FilePartSize
, &NameInvalid
, NULL
, &LengthNeeded
);
317 EndSeh(STATUS_ACCESS_VIOLATION
);
318 ok_eq_ustr(&FileName
, &TempString
);
319 ok(StringUsed
== NULL
, "StringUsed = %p\n", StringUsed
);
320 ok(FilePartSize
== 0, "FilePartSize = %lu\n", (ULONG
)FilePartSize
);
321 ok(NameInvalid
== FALSE
||
322 broken(NameInvalid
== (BOOLEAN
)-1) /* Win7 */, "NameInvalid = %u\n", NameInvalid
);
323 ok(LengthNeeded
== 0, "LengthNeeded = %lu\n", (ULONG
)LengthNeeded
);
325 /* This is the first one that doesn't crash. FileName and PathType cannot be NULL */
326 RtlInitUnicodeString(&FileName
, NULL
);
327 TempString
= FileName
;
328 PathType
= RtlPathTypeNotSet
;
330 Status
= RtlGetFullPathName_UstrEx(&FileName
, NULL
, NULL
, NULL
, NULL
, NULL
, &PathType
, NULL
);
331 ok(Status
== STATUS_OBJECT_NAME_INVALID
, "status = %lx\n", Status
);
332 EndSeh(STATUS_SUCCESS
);
333 ok_eq_ustr(&FileName
, &TempString
);
334 ok(PathType
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
);
336 RtlInitUnicodeString(&FileName
, L
"");
337 TempString
= FileName
;
338 PathType
= RtlPathTypeNotSet
;
340 Status
= RtlGetFullPathName_UstrEx(&FileName
, NULL
, NULL
, NULL
, NULL
, NULL
, &PathType
, NULL
);
341 ok(Status
== STATUS_OBJECT_NAME_INVALID
, "status = %lx\n", Status
);
342 EndSeh(STATUS_SUCCESS
);
343 ok_eq_ustr(&FileName
, &TempString
);
344 ok(PathType
== RtlPathTypeUnknown
, "PathType = %d\n", PathType
);
346 /* Give it a valid path */
347 RtlInitUnicodeString(&FileName
, L
"C:\\test");
348 TempString
= FileName
;
349 PathType
= RtlPathTypeNotSet
;
351 Status
= RtlGetFullPathName_UstrEx(&FileName
, NULL
, NULL
, NULL
, NULL
, NULL
, &PathType
, NULL
);
352 ok(Status
== STATUS_BUFFER_TOO_SMALL
, "status = %lx\n", Status
);
353 EndSeh(STATUS_SUCCESS
);
354 ok_eq_ustr(&FileName
, &TempString
);
355 ok(PathType
== RtlPathTypeDriveAbsolute
, "PathType = %d\n", PathType
);
357 /* Zero-length static string */
358 RtlInitUnicodeString(&FileName
, L
"C:\\test");
359 TempString
= FileName
;
360 RtlInitUnicodeString(&StaticString
, NULL
);
361 PathType
= RtlPathTypeNotSet
;
363 Status
= RtlGetFullPathName_UstrEx(&FileName
, &StaticString
, NULL
, NULL
, NULL
, NULL
, &PathType
, NULL
);
364 ok(Status
== STATUS_BUFFER_TOO_SMALL
, "status = %lx\n", Status
);
365 EndSeh(STATUS_SUCCESS
);
366 ok_eq_ustr(&FileName
, &TempString
);
367 ok(PathType
== RtlPathTypeDriveAbsolute
, "PathType = %d\n", PathType
);
369 /* TODO: play around with StaticString and DynamicString */
371 /* Check the actual functionality with different paths */