[BMFD]
[reactos.git] / rostests / apitests / ntdll / RtlDosSearchPath_U.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for RtlDosSearchPath_U
5 * PROGRAMMER: Thomas Faber <thfabba@gmx.de>
6 */
7
8 #define WIN32_NO_STATUS
9 #define UNICODE
10 #include <stdio.h>
11 #include <wine/test.h>
12 #include <pseh/pseh2.h>
13 #include <ndk/rtlfuncs.h>
14
15 /*
16 ULONG
17 NTAPI
18 RtlDosSearchPath_U(
19 IN PCWSTR Path,
20 IN PCWSTR FileName,
21 IN PCWSTR Extension,
22 IN ULONG BufferSize,
23 OUT PWSTR Buffer,
24 OUT PWSTR *PartName
25 );
26 */
27
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)
30
31 static
32 BOOLEAN
33 CheckStringBuffer(
34 PCWSTR Buffer,
35 SIZE_T Length,
36 SIZE_T MaximumLength,
37 PCWSTR Expected)
38 {
39 SIZE_T ExpectedLength = wcslen(Expected) * sizeof(WCHAR);
40 SIZE_T EqualLength;
41 BOOLEAN Result = TRUE;
42 SIZE_T i;
43
44 if (Length != ExpectedLength)
45 {
46 ok(0, "String length is %lu, expected %lu\n", (ULONG)Length, (ULONG)ExpectedLength);
47 Result = FALSE;
48 }
49
50 EqualLength = RtlCompareMemory(Buffer, Expected, Length);
51 if (EqualLength != Length)
52 {
53 ok(0, "String is '%S', expected '%S'\n", Buffer, Expected);
54 Result = FALSE;
55 }
56
57 if (Buffer[Length / sizeof(WCHAR)] != UNICODE_NULL)
58 {
59 ok(0, "Not null terminated\n");
60 Result = FALSE;
61 }
62
63 /* the function nulls the rest of the buffer! */
64 for (i = Length + sizeof(UNICODE_NULL); i < MaximumLength; i++)
65 {
66 UCHAR Char = ((PUCHAR)Buffer)[i];
67 if (Char != 0)
68 {
69 ok(0, "Found 0x%x at offset %lu, expected 0x%x\n", Char, (ULONG)i, 0);
70 /* don't count this as a failure unless the string was actually wrong */
71 //Result = FALSE;
72 /* don't flood the log */
73 break;
74 }
75 }
76
77 return Result;
78 }
79
80 static
81 BOOLEAN
82 CheckBuffer(
83 PVOID Buffer,
84 SIZE_T Size,
85 UCHAR Value)
86 {
87 PUCHAR Array = Buffer;
88 SIZE_T i;
89
90 for (i = 0; i < Size; i++)
91 if (Array[i] != Value)
92 {
93 trace("Expected %x, found %x at offset %lu\n", Value, Array[i], (ULONG)i);
94 return FALSE;
95 }
96 return TRUE;
97 }
98
99 #define InvalidPointer ((PVOID)0x0123456789ABCDEFULL)
100
101 START_TEST(RtlDosSearchPath_U)
102 {
103 NTSTATUS ExceptionStatus;
104 ULONG Length;
105 WCHAR Buffer[MAX_PATH];
106 PWSTR PartName;
107 BOOLEAN Okay;
108 BOOL Success;
109 WCHAR FileName[MAX_PATH];
110 WCHAR CustomPath[MAX_PATH] = L"RtlDosSearchPath_U_TestPath";
111 HANDLE Handle;
112
113 swprintf(FileName, L"C:\\%ls", CustomPath);
114 /* Make sure this directory doesn't exist */
115 while (GetFileAttributes(FileName) != INVALID_FILE_ATTRIBUTES)
116 {
117 wcscat(CustomPath, L"X");
118 swprintf(FileName, L"C:\\%ls", CustomPath);
119 }
120 Success = CreateDirectory(FileName, NULL);
121 ok(Success, "CreateDirectory failed, results might not be accurate\n");
122 swprintf(FileName, L"C:\\%ls\\ThisFolderExists", CustomPath);
123 Success = CreateDirectory(FileName, NULL);
124 ok(Success, "CreateDirectory failed, results might not be accurate\n");
125 swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\ThisFileExists", CustomPath);
126 Handle = CreateFile(FileName, 0, 0, NULL, CREATE_NEW, 0, NULL);
127 ok(Handle != INVALID_HANDLE_VALUE, "CreateFile failed, results might not be accurate\n");
128 if (Handle != INVALID_HANDLE_VALUE)
129 CloseHandle(Handle);
130
131 /* NULL parameters */
132 StartSeh() RtlDosSearchPath_U(NULL, NULL, NULL, 0, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
133 StartSeh() Length = RtlDosSearchPath_U(NULL, L"", NULL, 0, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
134 StartSeh() Length = RtlDosSearchPath_U(NULL, L"", NULL, 0, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
135 StartSeh() Length = RtlDosSearchPath_U(NULL, L"", NULL, 1, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
136 StartSeh() Length = RtlDosSearchPath_U(NULL, L"", NULL, 2, Buffer, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
137 StartSeh() Length = RtlDosSearchPath_U(L"", NULL, NULL, 0, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION);
138
139 /* Empty strings - first one that doesn't crash */
140 StartSeh()
141 Length = RtlDosSearchPath_U(L"", L"", NULL, 0, NULL, NULL);
142 ok(Length == 0, "Length %lu\n", Length);
143 EndSeh(STATUS_SUCCESS);
144
145 /* Check what's initialized */
146 PartName = InvalidPointer;
147 StartSeh()
148 Length = RtlDosSearchPath_U(L"", L"", NULL, 0, NULL, &PartName);
149 ok(Length == 0, "Length = %lu\n", Length);
150 EndSeh(STATUS_SUCCESS);
151 ok(PartName == InvalidPointer, "PartName = %p\n", PartName);
152
153 RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
154 StartSeh()
155 Length = RtlDosSearchPath_U(L"", L"", NULL, sizeof(Buffer), Buffer, NULL);
156 ok(Length == 0, "Length %lu\n", Length);
157 EndSeh(STATUS_SUCCESS);
158 Okay = CheckBuffer(Buffer, sizeof(Buffer), 0x55);
159 ok(Okay, "CheckBuffer failed\n");
160
161 PartName = InvalidPointer;
162 RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
163 StartSeh()
164 Length = RtlDosSearchPath_U(L"", L"", NULL, sizeof(Buffer), Buffer, &PartName);
165 ok(Length == 0, "Length %lu\n", Length);
166 EndSeh(STATUS_SUCCESS);
167 ok(PartName == InvalidPointer, "PartName = %p\n", PartName);
168 Okay = CheckBuffer(Buffer, sizeof(Buffer), 0x55);
169 ok(Okay, "CheckBuffer failed\n");
170
171 /* Empty path string searches in current directory */
172 swprintf(FileName, L"C:\\%ls\\ThisFolderExists", CustomPath);
173 Success = SetCurrentDirectory(FileName);
174 ok(Success, "SetCurrentDirectory failed\n");
175 PartName = InvalidPointer;
176 RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
177 StartSeh()
178 Length = RtlDosSearchPath_U(L"", L"ThisFileExists", NULL, sizeof(Buffer), Buffer, &PartName);
179 ok(Length == wcslen(FileName) * sizeof(WCHAR) + sizeof(L"\\ThisFileExists") - sizeof(UNICODE_NULL), "Length %lu\n", Length);
180 EndSeh(STATUS_SUCCESS);
181 ok(PartName == &Buffer[wcslen(FileName) + 1], "PartName = %p\n", PartName);
182 wcscat(FileName, L"\\ThisFileExists");
183 Okay = CheckStringBuffer(Buffer, Length, sizeof(Buffer), FileName);
184 ok(Okay, "CheckStringBuffer failed\n");
185
186 /* Absolute path in FileName is also okay */
187 PartName = InvalidPointer;
188 RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
189 StartSeh()
190 Length = RtlDosSearchPath_U(L"", L"C:\\", NULL, sizeof(Buffer), Buffer, &PartName);
191 ok(Length == sizeof(L"C:\\") - sizeof(UNICODE_NULL), "Length %lu\n", Length);
192 EndSeh(STATUS_SUCCESS);
193 ok(PartName == NULL, "PartName = %p\n", PartName);
194 Okay = CheckStringBuffer(Buffer, Length, sizeof(Buffer), L"C:\\");
195 ok(Okay, "CheckStringBuffer failed\n");
196
197 /* Empty FileName also works */
198 PartName = InvalidPointer;
199 RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
200 StartSeh()
201 Length = RtlDosSearchPath_U(L"C:\\", L"", NULL, sizeof(Buffer), Buffer, &PartName);
202 ok(Length == sizeof(L"C:\\") - sizeof(UNICODE_NULL), "Length %lu\n", Length);
203 EndSeh(STATUS_SUCCESS);
204 ok(PartName == NULL, "PartName = %p\n", PartName);
205 Okay = CheckStringBuffer(Buffer, Length, sizeof(Buffer), L"C:\\");
206 ok(Okay, "CheckStringBuffer failed\n");
207
208 /* Clean up test folder */
209 SetCurrentDirectory(L"C:\\");
210 swprintf(FileName, L"C:\\%ls\\ThisFolderExists\\ThisFileExists", CustomPath);
211 Success = DeleteFile(FileName);
212 ok(Success, "DeleteFile failed, test might leave stale file\n");
213 swprintf(FileName, L"C:\\%ls\\ThisFolderExists", CustomPath);
214 Success = RemoveDirectory(FileName);
215 ok(Success, "RemoveDirectory failed %(lu), test might leave stale directory\n", GetLastError());
216 swprintf(FileName, L"C:\\%ls", CustomPath);
217 Success = RemoveDirectory(FileName);
218 ok(Success, "RemoveDirectory failed (%lu), test might leave stale directory\n", GetLastError());
219 }