sync rostests to r44455
[reactos.git] / rostests / winetests / ntdll / om.c
1 /*
2 * Unit test suite for object manager functions
3 *
4 * Copyright 2005 Robert Shearman
5 * Copyright 2005 Vitaliy Margolen
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "ntdll_test.h"
23 #include "winternl.h"
24 #include "stdio.h"
25 #include "winnt.h"
26 #include "stdlib.h"
27
28 static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*, BOOL, LPCSTR);
29 static NTSTATUS (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
30 static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
31 static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
32 static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN, BOOLEAN);
33 static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN );
34 static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
35 static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG );
36 static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE );
37 static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER,
38 ULONG, ULONG, HANDLE );
39 static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG );
40 static NTSTATUS (WINAPI *pNtClose) ( HANDLE );
41 static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
42 ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, PLARGE_INTEGER );
43 static NTSTATUS (WINAPI *pNtOpenDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
44 static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
45 static NTSTATUS (WINAPI *pNtOpenSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
46 static NTSTATUS (WINAPI *pNtCreateSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PUNICODE_STRING);
47
48
49 static void test_case_sensitive (void)
50 {
51 static const WCHAR buffer1[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','t','e','s','t',0};
52 static const WCHAR buffer2[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','T','e','s','t',0};
53 static const WCHAR buffer3[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','T','E','s','t',0};
54 static const WCHAR buffer4[] = {'\\','B','A','S','E','N','a','m','e','d','O','b','j','e','c','t','s','\\','t','e','s','t',0};
55 NTSTATUS status;
56 OBJECT_ATTRIBUTES attr;
57 UNICODE_STRING str;
58 HANDLE Event, Mutant, h;
59
60 pRtlInitUnicodeString(&str, buffer1);
61 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
62 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
63 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
64
65 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
66 ok(status == STATUS_OBJECT_NAME_COLLISION,
67 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status);
68
69 pRtlInitUnicodeString(&str, buffer2);
70 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
71 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
72 ok(status == STATUS_SUCCESS, "Failed to create Event(%08x)\n", status);
73
74 pRtlInitUnicodeString(&str, buffer3);
75 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
76 status = pNtOpenMutant(&h, GENERIC_ALL, &attr);
77 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
78 "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
79
80 pNtClose(Mutant);
81
82 pRtlInitUnicodeString(&str, buffer4);
83 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
84 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
85 ok(status == STATUS_OBJECT_NAME_COLLISION,
86 "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status);
87
88 status = pNtCreateEvent(&h, GENERIC_ALL, &attr, FALSE, FALSE);
89 ok(status == STATUS_OBJECT_NAME_COLLISION,
90 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status);
91
92 attr.Attributes = 0;
93 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
94 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
95 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
96
97 pNtClose(Event);
98 }
99
100 static void test_namespace_pipe(void)
101 {
102 static const WCHAR buffer1[] = {'\\','?','?','\\','P','I','P','E','\\','t','e','s','t','\\','p','i','p','e',0};
103 static const WCHAR buffer2[] = {'\\','?','?','\\','P','I','P','E','\\','T','E','S','T','\\','P','I','P','E',0};
104 static const WCHAR buffer3[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t','\\','p','i','p','e',0};
105 static const WCHAR buffer4[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t',0};
106 OBJECT_ATTRIBUTES attr;
107 UNICODE_STRING str;
108 IO_STATUS_BLOCK iosb;
109 NTSTATUS status;
110 LARGE_INTEGER timeout;
111 HANDLE pipe, h;
112
113 timeout.QuadPart = -10000;
114
115 pRtlInitUnicodeString(&str, buffer1);
116 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
117 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
118 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
119 ok(status == STATUS_SUCCESS, "Failed to create NamedPipe(%08x)\n", status);
120
121 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
122 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
123 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
124 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
125
126 pRtlInitUnicodeString(&str, buffer2);
127 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
128 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
129 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
130 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
131 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
132
133 h = CreateFileA("\\\\.\\pipe\\test\\pipe", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
134 OPEN_EXISTING, 0, 0 );
135 ok(h != INVALID_HANDLE_VALUE, "Failed to open NamedPipe (%u)\n", GetLastError());
136 pNtClose(h);
137
138 pRtlInitUnicodeString(&str, buffer3);
139 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
140 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN);
141 ok(status == STATUS_OBJECT_PATH_NOT_FOUND ||
142 status == STATUS_PIPE_NOT_AVAILABLE ||
143 status == STATUS_OBJECT_NAME_INVALID, /* vista */
144 "NtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
145
146 pRtlInitUnicodeString(&str, buffer4);
147 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
148 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN);
149 ok(status == STATUS_OBJECT_NAME_NOT_FOUND ||
150 status == STATUS_OBJECT_NAME_INVALID, /* vista */
151 "NtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08x)\n", status);
152
153 pNtClose(pipe);
154 }
155
156 #define DIRECTORY_QUERY (0x0001)
157 #define SYMBOLIC_LINK_QUERY 0x0001
158
159 #define DIR_TEST_CREATE_FAILURE(h,e) \
160 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr);\
161 ok(status == e,"NtCreateDirectoryObject should have failed with %s got(%08x)\n", #e, status);
162 #define DIR_TEST_OPEN_FAILURE(h,e) \
163 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr);\
164 ok(status == e,"NtOpenDirectoryObject should have failed with %s got(%08x)\n", #e, status);
165 #define DIR_TEST_CREATE_OPEN_FAILURE(h,n,e) \
166 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
167 DIR_TEST_CREATE_FAILURE(h,e) DIR_TEST_OPEN_FAILURE(h,e)\
168 pRtlFreeUnicodeString(&str);
169
170 #define DIR_TEST_CREATE_SUCCESS(h) \
171 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr); \
172 ok(status == STATUS_SUCCESS, "Failed to create Directory(%08x)\n", status);
173 #define DIR_TEST_OPEN_SUCCESS(h) \
174 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr); \
175 ok(status == STATUS_SUCCESS, "Failed to open Directory(%08x)\n", status);
176 #define DIR_TEST_CREATE_OPEN_SUCCESS(h,n) \
177 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
178 DIR_TEST_CREATE_SUCCESS(&h) pNtClose(h); DIR_TEST_OPEN_SUCCESS(&h) pNtClose(h); \
179 pRtlFreeUnicodeString(&str);
180
181 static BOOL is_correct_dir( HANDLE dir, const char *name )
182 {
183 NTSTATUS status;
184 UNICODE_STRING str;
185 OBJECT_ATTRIBUTES attr;
186 HANDLE h = 0;
187
188 pRtlCreateUnicodeStringFromAsciiz(&str, name);
189 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
190 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
191 pRtlFreeUnicodeString(&str);
192 if (h) pNtClose( h );
193 return (status == STATUS_OBJECT_NAME_EXISTS);
194 }
195
196 /* return a handle to the BaseNamedObjects dir where kernel32 objects get created */
197 static HANDLE get_base_dir(void)
198 {
199 static const char objname[] = "om.c_get_base_dir_obj";
200 NTSTATUS status;
201 UNICODE_STRING str;
202 OBJECT_ATTRIBUTES attr;
203 HANDLE dir, h;
204 unsigned int i;
205
206 h = CreateMutexA(NULL, FALSE, objname);
207 ok(h != 0, "CreateMutexA failed got ret=%p (%d)\n", h, GetLastError());
208 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
209
210 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local");
211 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
212 pRtlFreeUnicodeString(&str);
213 if (!status && is_correct_dir( dir, objname )) goto done;
214 if (!status) pNtClose( dir );
215
216 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
217 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
218 pRtlFreeUnicodeString(&str);
219 if (!status && is_correct_dir( dir, objname )) goto done;
220 if (!status) pNtClose( dir );
221
222 for (i = 0; i < 20; i++)
223 {
224 char name[40];
225 sprintf( name, "\\BaseNamedObjects\\Session\\%u", i );
226 pRtlCreateUnicodeStringFromAsciiz(&str, name );
227 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
228 pRtlFreeUnicodeString(&str);
229 if (!status && is_correct_dir( dir, objname )) goto done;
230 if (!status) pNtClose( dir );
231 }
232 dir = 0;
233
234 done:
235 pNtClose( h );
236 return dir;
237 }
238
239 static void test_name_collisions(void)
240 {
241 NTSTATUS status;
242 UNICODE_STRING str;
243 OBJECT_ATTRIBUTES attr;
244 HANDLE dir, h, h1, h2;
245 DWORD winerr;
246 LARGE_INTEGER size;
247
248 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
249 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
250 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_COLLISION)
251 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
252
253 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_EXISTS)
254 pNtClose(h);
255 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
256 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
257 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
258 pRtlFreeUnicodeString(&str);
259
260 pRtlCreateUnicodeStringFromAsciiz(&str, "\\??\\PIPE\\om.c-mutant");
261 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
262 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_OBJECT_PATH_NOT_FOUND,
263 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
264 pRtlFreeUnicodeString(&str);
265
266 if (!(dir = get_base_dir()))
267 {
268 win_skip( "couldn't find the BaseNamedObjects dir\n" );
269 return;
270 }
271 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
272 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
273 h = CreateMutexA(NULL, FALSE, "om.c-test");
274 ok(h != 0, "CreateMutexA failed got ret=%p (%d)\n", h, GetLastError());
275 status = pNtCreateMutant(&h1, GENERIC_ALL, &attr, FALSE);
276 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
277 "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
278 h2 = CreateMutexA(NULL, FALSE, "om.c-test");
279 winerr = GetLastError();
280 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
281 "CreateMutexA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
282 pNtClose(h);
283 pNtClose(h1);
284 pNtClose(h2);
285
286 h = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
287 ok(h != 0, "CreateEventA failed got ret=%p (%d)\n", h, GetLastError());
288 status = pNtCreateEvent(&h1, GENERIC_ALL, &attr, FALSE, FALSE);
289 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
290 "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
291 h2 = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
292 winerr = GetLastError();
293 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
294 "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
295 pNtClose(h);
296 pNtClose(h1);
297 pNtClose(h2);
298
299 h = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
300 ok(h != 0, "CreateSemaphoreA failed got ret=%p (%d)\n", h, GetLastError());
301 status = pNtCreateSemaphore(&h1, GENERIC_ALL, &attr, 1, 2);
302 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
303 "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
304 h2 = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
305 winerr = GetLastError();
306 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
307 "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
308 pNtClose(h);
309 pNtClose(h1);
310 pNtClose(h2);
311
312 h = pCreateWaitableTimerA(NULL, TRUE, "om.c-test");
313 ok(h != 0, "CreateWaitableTimerA failed got ret=%p (%d)\n", h, GetLastError());
314 status = pNtCreateTimer(&h1, GENERIC_ALL, &attr, NotificationTimer);
315 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
316 "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
317 h2 = pCreateWaitableTimerA(NULL, TRUE, "om.c-test");
318 winerr = GetLastError();
319 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
320 "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
321 pNtClose(h);
322 pNtClose(h1);
323 pNtClose(h2);
324
325 h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
326 ok(h != 0, "CreateFileMappingA failed got ret=%p (%d)\n", h, GetLastError());
327 size.u.LowPart = 256;
328 size.u.HighPart = 0;
329 status = pNtCreateSection(&h1, SECTION_MAP_WRITE, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
330 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
331 "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
332 h2 = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
333 winerr = GetLastError();
334 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
335 "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
336 pNtClose(h);
337 pNtClose(h1);
338 pNtClose(h2);
339
340 pRtlFreeUnicodeString(&str);
341 pNtClose(dir);
342 }
343
344 static void test_directory(void)
345 {
346 NTSTATUS status;
347 UNICODE_STRING str;
348 OBJECT_ATTRIBUTES attr;
349 HANDLE dir, dir1, h;
350 BOOL is_nt4;
351
352 /* No name and/or no attributes */
353 status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
354 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
355 "NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
356 status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
357 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
358 "NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
359
360 status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL);
361 ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08x)\n", status);
362 pNtClose(h);
363 status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL);
364 ok(status == STATUS_INVALID_PARAMETER,
365 "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
366
367 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
368 DIR_TEST_CREATE_SUCCESS(&dir)
369 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
370
371 /* Bad name */
372 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
373
374 pRtlCreateUnicodeStringFromAsciiz(&str, "");
375 DIR_TEST_CREATE_SUCCESS(&h)
376 pNtClose(h);
377 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
378 pRtlFreeUnicodeString(&str);
379 pNtClose(dir);
380
381 DIR_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD)
382 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID)
383 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID)
384 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID)
385 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
386
387 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
388 DIR_TEST_CREATE_SUCCESS(&h)
389 DIR_TEST_OPEN_SUCCESS(&dir1)
390 pRtlFreeUnicodeString(&str);
391 pNtClose(h);
392 pNtClose(dir1);
393
394
395 /* Use of root directory */
396
397 /* Can't use symlinks as a directory */
398 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local");
399 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
400 status = pNtOpenSymbolicLinkObject(&dir, SYMBOLIC_LINK_QUERY, &attr);
401 is_nt4 = (status == STATUS_OBJECT_NAME_NOT_FOUND); /* nt4 doesn't have Local\\ symlink */
402 if (!is_nt4)
403 {
404 ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08x)\n", status);
405 pRtlFreeUnicodeString(&str);
406 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
407 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
408 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH)
409 pRtlFreeUnicodeString(&str);
410 pNtClose(h);
411 pNtClose(dir);
412 }
413
414 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
415 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
416 DIR_TEST_OPEN_SUCCESS(&dir)
417 pRtlFreeUnicodeString(&str);
418
419 InitializeObjectAttributes(&attr, NULL, 0, dir, NULL);
420 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_NAME_INVALID)
421
422 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
423 DIR_TEST_CREATE_OPEN_SUCCESS(h, "")
424 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
425 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD)
426 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
427 DIR_TEST_CREATE_OPEN_FAILURE(&h, "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
428
429 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
430 DIR_TEST_CREATE_SUCCESS(&dir1)
431 DIR_TEST_OPEN_SUCCESS(&h)
432 pRtlFreeUnicodeString(&str);
433
434 pNtClose(h);
435 pNtClose(dir1);
436 pNtClose(dir);
437
438 /* Nested directories */
439 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
440 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
441 DIR_TEST_OPEN_SUCCESS(&dir)
442 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
443 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
444 pRtlFreeUnicodeString(&str);
445 pNtClose(dir);
446
447 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
448 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
449 DIR_TEST_CREATE_SUCCESS(&dir)
450 pRtlFreeUnicodeString(&str);
451 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test\\one more level");
452 DIR_TEST_CREATE_SUCCESS(&h)
453 pRtlFreeUnicodeString(&str);
454 pNtClose(h);
455 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
456 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
457 DIR_TEST_CREATE_SUCCESS(&h)
458 pRtlFreeUnicodeString(&str);
459 pNtClose(h);
460
461 pNtClose(dir);
462
463 if (!is_nt4)
464 {
465 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
466 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Global\\om.c-test");
467 DIR_TEST_CREATE_SUCCESS(&dir)
468 pRtlFreeUnicodeString(&str);
469 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local\\om.c-test\\one more level");
470 DIR_TEST_CREATE_SUCCESS(&h)
471 pRtlFreeUnicodeString(&str);
472 pNtClose(h);
473 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
474 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
475 DIR_TEST_CREATE_SUCCESS(&dir)
476 pRtlFreeUnicodeString(&str);
477 pNtClose(h);
478 pNtClose(dir);
479 }
480
481 /* Create other objects using RootDirectory */
482
483 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
484 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
485 DIR_TEST_OPEN_SUCCESS(&dir)
486 pRtlFreeUnicodeString(&str);
487 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
488
489 /* Test invalid paths */
490 pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant");
491 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
492 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
493 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
494 pRtlFreeUnicodeString(&str);
495 pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant\\");
496 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
497 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
498 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
499 pRtlFreeUnicodeString(&str);
500
501 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c\\-mutant");
502 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
503 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
504 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
505 pRtlFreeUnicodeString(&str);
506
507 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-mutant");
508 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
509 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
510 pRtlFreeUnicodeString(&str);
511 pNtClose(h);
512
513 pNtClose(dir);
514 }
515
516 #define SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e2) \
517 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
518 pRtlCreateUnicodeStringFromAsciiz(&target, t);\
519 status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\
520 ok(status == e || status == e2, \
521 "NtCreateSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
522 status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\
523 ok(status == e || status == e2, \
524 "NtOpenSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
525 pRtlFreeUnicodeString(&target);\
526 pRtlFreeUnicodeString(&str);
527
528 #define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e)
529
530 static void test_symboliclink(void)
531 {
532 NTSTATUS status;
533 UNICODE_STRING str, target;
534 OBJECT_ATTRIBUTES attr;
535 HANDLE dir, link, h;
536 IO_STATUS_BLOCK iosb;
537
538 /* No name and/or no attributes */
539 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
540 SYMLNK_TEST_CREATE_OPEN_FAILURE2(NULL, "", "", STATUS_ACCESS_VIOLATION, STATUS_INVALID_PARAMETER)
541
542 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL);
543 ok(status == STATUS_ACCESS_VIOLATION,
544 "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
545 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL);
546 ok(status == STATUS_INVALID_PARAMETER,
547 "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
548
549 /* No attributes */
550 pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
551 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, &target);
552 ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_VIOLATION, /* nt4 */
553 "NtCreateSymbolicLinkObject failed(%08x)\n", status);
554 pRtlFreeUnicodeString(&target);
555 if (!status) pNtClose(h);
556
557 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
558 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
559 ok(status == STATUS_INVALID_PARAMETER ||
560 broken(status == STATUS_SUCCESS), /* nt4 */
561 "NtCreateSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
562 if (!status) pNtClose(h);
563 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
564 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
565 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
566
567 /* Bad name */
568 pRtlCreateUnicodeStringFromAsciiz(&target, "anywhere");
569 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
570
571 pRtlCreateUnicodeStringFromAsciiz(&str, "");
572 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
573 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status);
574 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
575 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
576 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
577 pNtClose(link);
578 pRtlFreeUnicodeString(&str);
579
580 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
581 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target);
582 todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH,
583 "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
584 pRtlFreeUnicodeString(&str);
585 pRtlFreeUnicodeString(&target);
586
587 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", "->Somewhere", STATUS_OBJECT_PATH_SYNTAX_BAD)
588 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
589 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
590 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
591 SYMLNK_TEST_CREATE_OPEN_FAILURE2(&h, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere",
592 STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND)
593
594
595 /* Compound test */
596 if (!(dir = get_base_dir()))
597 {
598 win_skip( "couldn't find the BaseNamedObjects dir\n" );
599 return;
600 }
601
602 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
603 pRtlCreateUnicodeStringFromAsciiz(&str, "test-link");
604 pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
605 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
606 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status);
607 pRtlFreeUnicodeString(&str);
608 pRtlFreeUnicodeString(&target);
609
610 pRtlCreateUnicodeStringFromAsciiz(&str, "test-link\\NUL");
611 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN);
612 todo_wine ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08x)\n", status);
613 pRtlFreeUnicodeString(&str);
614
615 pNtClose(h);
616 pNtClose(link);
617 pNtClose(dir);
618 }
619
620 START_TEST(om)
621 {
622 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
623 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
624
625 if (!hntdll)
626 {
627 skip("not running on NT, skipping test\n");
628 return;
629 }
630
631 pCreateWaitableTimerA = (void *)GetProcAddress(hkernel32, "CreateWaitableTimerA");
632
633 pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
634 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
635 pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent");
636 pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant");
637 pNtOpenMutant = (void *)GetProcAddress(hntdll, "NtOpenMutant");
638 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
639 pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
640 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
641 pNtCreateNamedPipeFile = (void *)GetProcAddress(hntdll, "NtCreateNamedPipeFile");
642 pNtOpenDirectoryObject = (void *)GetProcAddress(hntdll, "NtOpenDirectoryObject");
643 pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject");
644 pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject");
645 pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject");
646 pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
647 pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer");
648 pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection");
649
650 test_case_sensitive();
651 test_namespace_pipe();
652 test_name_collisions();
653 test_directory();
654 test_symboliclink();
655 }