1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for RtlGetFullPathName_U
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 /*
11 ULONG
12 NTAPI
13 RtlGetFullPathName_U(
14 IN PCWSTR FileName,
15 IN ULONG Size,
16 IN PWSTR Buffer,
17 OUT PWSTR *ShortName
18 );
19 */
20
21 static
22 BOOLEAN
CheckStringBuffer(PCWSTR Buffer,SIZE_T Length,SIZE_T MaximumLength,PCWSTR Expected)23 CheckStringBuffer(
24 PCWSTR Buffer,
25 SIZE_T Length,
26 SIZE_T MaximumLength,
27 PCWSTR Expected)
28 {
29 SIZE_T ExpectedLength = wcslen(Expected) * sizeof(WCHAR);
30 SIZE_T EqualLength;
31 BOOLEAN Result = TRUE;
32 SIZE_T i;
33
34 if (Length != ExpectedLength)
35 {
36 ok(0, "String length is %lu, expected %lu\n", (ULONG)Length, (ULONG)ExpectedLength);
37 Result = FALSE;
38 }
39
40 EqualLength = RtlCompareMemory(Buffer, Expected, Length);
41 if (EqualLength != Length)
42 {
43 ok(0, "String is '%S', expected '%S'\n", Buffer, Expected);
44 Result = FALSE;
45 }
46
47 if (Buffer[Length / sizeof(WCHAR)] != UNICODE_NULL)
48 {
49 ok(0, "Not null terminated\n");
50 Result = FALSE;
51 }
52
53 /* The function nulls the rest of the buffer! */
54 for (i = Length + sizeof(UNICODE_NULL); i < MaximumLength; i++)
55 {
56 UCHAR Char = ((PUCHAR)Buffer)[i];
57 if (Char != 0)
58 {
59 ok(0, "Found 0x%x at offset %lu, expected 0x%x\n", Char, (ULONG)i, 0);
60 /* Don't count this as a failure unless the string was actually wrong */
61 //Result = FALSE;
62 /* Don't flood the log */
63 break;
64 }
65 }
66
67 return Result;
68 }
69
70 /* winetest_platform is "windows" for us, so broken() doesn't do what it should :( */
71 #undef broken
72 #define broken(x) 0
73
74 typedef enum
75 {
76 PrefixNone,
77 PrefixCurrentDrive,
78 PrefixCurrentPath,
79 PrefixCurrentPathWithoutLastPart
80 } PREFIX_TYPE;
81
82 static
83 VOID
RunTestCases(VOID)84 RunTestCases(VOID)
85 {
86 /* TODO: don't duplicate this in the other tests */
87 /* TODO: Drive Relative tests don't work yet if the current drive isn't C: */
88 struct
89 {
90 ULONG Line;
91 PCWSTR FileName;
92 PREFIX_TYPE PrefixType;
93 PCWSTR FullPathName;
94 PREFIX_TYPE FilePartPrefixType;
95 SIZE_T FilePartSize;
96 } TestCases[] =
97 {
98 // { __LINE__, L"C:", PrefixCurrentPath, L"", PrefixCurrentPathWithoutLastPart },
99 { __LINE__, L"C:\\", PrefixNone, L"C:\\" },
100 { __LINE__, L"C:\\test", PrefixNone, L"C:\\test", PrefixCurrentDrive },
101 { __LINE__, L"C:\\test\\", PrefixNone, L"C:\\test\\" },
102 { __LINE__, L"C:/test/", PrefixNone, L"C:\\test\\" },
103
104 { __LINE__, L"C:\\\\test", PrefixNone, L"C:\\test", PrefixCurrentDrive },
105 { __LINE__, L"test", PrefixCurrentPath, L"\\test", PrefixCurrentPath, sizeof(WCHAR) },
106 { __LINE__, L"\\test", PrefixCurrentDrive, L"test", PrefixCurrentDrive },
107 { __LINE__, L"/test", PrefixCurrentDrive, L"test", PrefixCurrentDrive },
108 { __LINE__, L".\\test", PrefixCurrentPath, L"\\test", PrefixCurrentPath, sizeof(WCHAR) },
109
110 { __LINE__, L"\\.", PrefixCurrentDrive, L"" },
111 { __LINE__, L"\\.\\", PrefixCurrentDrive, L"" },
112 { __LINE__, L"\\\\.", PrefixNone, L"\\\\.\\" },
113 { __LINE__, L"\\\\.\\", PrefixNone, L"\\\\.\\" },
114 { __LINE__, L"\\\\.\\Something\\", PrefixNone, L"\\\\.\\Something\\" },
115
116 { __LINE__, L"\\??\\", PrefixCurrentDrive, L"??\\" },
117 { __LINE__, L"\\??\\C:", PrefixCurrentDrive, L"??\\C:", PrefixCurrentDrive, 3 * sizeof(WCHAR) },
118 { __LINE__, L"\\??\\C:\\", PrefixCurrentDrive, L"??\\C:\\" },
119 { __LINE__, L"\\??\\C:\\test", PrefixCurrentDrive, L"??\\C:\\test", PrefixCurrentDrive, 6 * sizeof(WCHAR) },
120 { __LINE__, L"\\??\\C:\\test\\", PrefixCurrentDrive, L"??\\C:\\test\\" },
121
122 { __LINE__, L"\\\\??\\", PrefixNone, L"\\\\??\\" },
123 { __LINE__, L"\\\\??\\C:", PrefixNone, L"\\\\??\\C:" },
124 { __LINE__, L"\\\\??\\C:\\", PrefixNone, L"\\\\??\\C:\\" },
125 { __LINE__, L"\\\\??\\C:\\test", PrefixNone, L"\\\\??\\C:\\test", PrefixNone, sizeof(L"\\\\??\\C:\\") },
126 { __LINE__, L"\\\\??\\C:\\test\\", PrefixNone, L"\\\\??\\C:\\test\\" },
127 };
128 WCHAR FullPathNameBuffer[MAX_PATH];
129 PWSTR ShortName;
130 SIZE_T Length;
131 WCHAR ExpectedPathName[MAX_PATH];
132 SIZE_T FilePartSize;
133 SIZE_T ExpectedFilePartSize;
134 const INT TestCount = sizeof(TestCases) / sizeof(TestCases[0]);
135 INT i;
136 BOOLEAN Okay;
137
138 for (i = 0; i < TestCount; i++)
139 {
140 trace("i = %d\n", i);
141 switch (TestCases[i].PrefixType)
142 {
143 case PrefixNone:
144 ExpectedPathName[0] = UNICODE_NULL;
145 break;
146 case PrefixCurrentDrive:
147 GetCurrentDirectoryW(sizeof(ExpectedPathName) / sizeof(WCHAR), ExpectedPathName);
148 ExpectedPathName[3] = UNICODE_NULL;
149 break;
150 case PrefixCurrentPath:
151 Length = GetCurrentDirectoryW(sizeof(ExpectedPathName) / sizeof(WCHAR), ExpectedPathName);
152 if (Length == 3 && TestCases[i].FullPathName[0])
153 ExpectedPathName[2] = UNICODE_NULL;
154 break;
155 default:
156 skip("Invalid test!\n");
157 continue;
158 }
159 wcscat(ExpectedPathName, TestCases[i].FullPathName);
160 RtlFillMemory(FullPathNameBuffer, sizeof(FullPathNameBuffer), 0xAA);
161 Length = 0;
162 StartSeh()
163 Length = RtlGetFullPathName_U(TestCases[i].FileName,
164 sizeof(FullPathNameBuffer),
165 FullPathNameBuffer,
166 &ShortName);
167 EndSeh(STATUS_SUCCESS);
168
169 Okay = CheckStringBuffer(FullPathNameBuffer, Length, sizeof(FullPathNameBuffer), ExpectedPathName);
170 ok(Okay, "Line %lu: Wrong path name '%S', expected '%S'\n", TestCases[i].Line, FullPathNameBuffer, ExpectedPathName);
171
172 if (!ShortName)
173 FilePartSize = 0;
174 else
175 FilePartSize = ShortName - FullPathNameBuffer;
176
177 switch (TestCases[i].FilePartPrefixType)
178 {
179 case PrefixNone:
180 ExpectedFilePartSize = 0;
181 break;
182 case PrefixCurrentDrive:
183 ExpectedFilePartSize = sizeof(L"C:\\");
184 break;
185 case PrefixCurrentPath:
186 ExpectedFilePartSize = GetCurrentDirectoryW(0, NULL) * sizeof(WCHAR);
187 if (ExpectedFilePartSize == sizeof(L"C:\\"))
188 ExpectedFilePartSize -= sizeof(WCHAR);
189 break;
190 case PrefixCurrentPathWithoutLastPart:
191 {
192 WCHAR CurrentPath[MAX_PATH];
193 PCWSTR BackSlash;
194 ExpectedFilePartSize = GetCurrentDirectoryW(sizeof(CurrentPath) / sizeof(WCHAR), CurrentPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
195 if (ExpectedFilePartSize == sizeof(L"C:\\"))
196 ExpectedFilePartSize = 0;
197 else
198 {
199 BackSlash = wcsrchr(CurrentPath, L'\\');
200 if (BackSlash)
201 ExpectedFilePartSize -= wcslen(BackSlash + 1) * sizeof(WCHAR);
202 else
203 ok(0, "Line %lu: GetCurrentDirectory returned %S\n", TestCases[i].Line, CurrentPath);
204 }
205 break;
206 }
207 default:
208 skip("Invalid test!\n");
209 continue;
210 }
211 ExpectedFilePartSize += TestCases[i].FilePartSize;
212 if (ExpectedFilePartSize != 0)
213 ExpectedFilePartSize = (ExpectedFilePartSize - sizeof(UNICODE_NULL)) / sizeof(WCHAR);
214 ok(FilePartSize == ExpectedFilePartSize,
215 "Line %lu: FilePartSize = %lu, expected %lu\n", TestCases[i].Line, (ULONG)FilePartSize, (ULONG)ExpectedFilePartSize);
216 }
217 }
218
START_TEST(RtlGetFullPathName_U)219 START_TEST(RtlGetFullPathName_U)
220 {
221 PCWSTR FileName;
222 PWSTR ShortName;
223 ULONG Length;
224
225 /* Parameter checks */
226 StartSeh()
227 Length = RtlGetFullPathName_U(NULL, 0, NULL, NULL);
228 ok(Length == 0, "Length = %lu\n", Length);
229 EndSeh(STATUS_SUCCESS);
230
231 StartSeh()
232 Length = RtlGetFullPathName_U(L"", 0, NULL, NULL);
233 ok(Length == 0, "Length = %lu\n", Length);
234 EndSeh(STATUS_SUCCESS);
235
236 ShortName = InvalidPointer;
237 StartSeh()
238 Length = RtlGetFullPathName_U(NULL, 0, NULL, &ShortName);
239 ok(Length == 0, "Length = %lu\n", Length);
240 EndSeh(STATUS_SUCCESS);
241 ok(ShortName == InvalidPointer ||
242 broken(ShortName == NULL) /* Win7 */, "ShortName = %p\n", ShortName);
243
244 StartSeh()
245 Length = RtlGetFullPathName_U(L"", 0, NULL, NULL);
246 ok(Length == 0, "Length = %lu\n", Length);
247 EndSeh(STATUS_SUCCESS);
248
249 ShortName = InvalidPointer;
250 StartSeh()
251 Length = RtlGetFullPathName_U(L"", 0, NULL, &ShortName);
252 ok(Length == 0, "Length = %lu\n", Length);
253 EndSeh(STATUS_SUCCESS);
254 ok(ShortName == InvalidPointer ||
255 broken(ShortName == NULL) /* Win7 */, "ShortName = %p\n", ShortName);
256
257 StartSeh()
258 Length = RtlGetFullPathName_U(L"C:\\test", 0, NULL, NULL);
259 ok(Length == sizeof(L"C:\\test"), "Length = %lu\n", Length);
260 EndSeh(STATUS_SUCCESS);
261
262 FileName = L"C:\\test";
263 ShortName = InvalidPointer;
264 StartSeh()
265 Length = RtlGetFullPathName_U(FileName, 0, NULL, &ShortName);
266 ok(Length == sizeof(L"C:\\test"), "Length = %lu\n", Length);
267 EndSeh(STATUS_SUCCESS);
268 ok(ShortName == InvalidPointer ||
269 broken(ShortName == NULL) /* Win7 */, "ShortName = %p\n", ShortName);
270
271 /* Check the actual functionality with different paths */
272 RunTestCases();
273 }
274