ntdll: Pass the correct value to NtClose in the tests.
[wine] / dlls / ntdll / tests / 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 NTSTATUS (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
29 static VOID     (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
30 static VOID     (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
31 static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN, BOOLEAN);
32 static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN );
33 static NTSTATUS (WINAPI *pNtOpenMutant)  ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
34 static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG );
35 static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE );
36 static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER,
37                                             ULONG, ULONG, HANDLE );
38 static NTSTATUS (WINAPI *pNtOpenFile)    ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG );
39 static NTSTATUS (WINAPI *pNtClose)       ( HANDLE );
40 static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
41                                        ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, PLARGE_INTEGER );
42 static NTSTATUS (WINAPI *pNtOpenDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
43 static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
44 static NTSTATUS (WINAPI *pNtOpenSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
45 static NTSTATUS (WINAPI *pNtCreateSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PUNICODE_STRING);
46
47
48 static void test_case_sensitive (void)
49 {
50     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};
51     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};
52     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};
53     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};
54     NTSTATUS status;
55     OBJECT_ATTRIBUTES attr;
56     UNICODE_STRING str;
57     HANDLE Event, Mutant, h;
58
59     pRtlInitUnicodeString(&str, buffer1);
60     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
61     status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
62     ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
63
64     status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
65     ok(status == STATUS_OBJECT_NAME_COLLISION,
66         "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status);
67
68     pRtlInitUnicodeString(&str, buffer2);
69     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
70     status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
71     ok(status == STATUS_SUCCESS, "Failed to create Event(%08x)\n", status);
72
73     pRtlInitUnicodeString(&str, buffer3);
74     InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
75     status = pNtOpenMutant(&h, GENERIC_ALL, &attr);
76     ok(status == STATUS_OBJECT_TYPE_MISMATCH,
77         "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
78
79     pNtClose(Mutant);
80
81     pRtlInitUnicodeString(&str, buffer4);
82     InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
83     status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
84     ok(status == STATUS_OBJECT_NAME_COLLISION,
85         "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status);
86
87     status = pNtCreateEvent(&h, GENERIC_ALL, &attr, FALSE, FALSE);
88     ok(status == STATUS_OBJECT_NAME_COLLISION,
89         "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status);
90
91     attr.Attributes = 0;
92     status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
93     ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
94         "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
95
96     pNtClose(Event);
97 }
98
99 static void test_namespace_pipe(void)
100 {
101     static const WCHAR buffer1[] = {'\\','?','?','\\','P','I','P','E','\\','t','e','s','t','\\','p','i','p','e',0};
102     static const WCHAR buffer2[] = {'\\','?','?','\\','P','I','P','E','\\','T','E','S','T','\\','P','I','P','E',0};
103     static const WCHAR buffer3[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t','\\','p','i','p','e',0};
104     static const WCHAR buffer4[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t',0};
105     OBJECT_ATTRIBUTES attr;
106     UNICODE_STRING str;
107     IO_STATUS_BLOCK iosb;
108     NTSTATUS status;
109     LARGE_INTEGER timeout;
110     HANDLE pipe, h;
111
112     timeout.QuadPart = -10000;
113
114     pRtlInitUnicodeString(&str, buffer1);
115     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
116     status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
117                                     FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
118     ok(status == STATUS_SUCCESS, "Failed to create NamedPipe(%08x)\n", status);
119
120     status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
121                                     FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
122     ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
123         "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
124
125     pRtlInitUnicodeString(&str, buffer2);
126     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
127     status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
128                                     FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
129     ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
130         "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
131
132     attr.Attributes = OBJ_CASE_INSENSITIVE;
133     status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN);
134     ok(status == STATUS_SUCCESS, "Failed to open NamedPipe(%08x)\n", status);
135     pNtClose(h);
136
137     pRtlInitUnicodeString(&str, buffer3);
138     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
139     status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN);
140     ok(status == STATUS_OBJECT_PATH_NOT_FOUND || status == STATUS_PIPE_NOT_AVAILABLE,
141         "pNtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
142
143     pRtlInitUnicodeString(&str, buffer4);
144     InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
145     status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN);
146     ok(status == STATUS_OBJECT_NAME_NOT_FOUND,
147         "pNtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08x)\n", status);
148
149     pNtClose(pipe);
150 }
151
152 #define DIRECTORY_QUERY (0x0001)
153 #define SYMBOLIC_LINK_QUERY 0x0001
154
155 #define DIR_TEST_CREATE_FAILURE(h,e) \
156     status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr);\
157     ok(status == e,"NtCreateDirectoryObject should have failed with %s got(%08x)\n", #e, status);
158 #define DIR_TEST_OPEN_FAILURE(h,e) \
159     status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr);\
160     ok(status == e,"NtOpenDirectoryObject should have failed with %s got(%08x)\n", #e, status);
161 #define DIR_TEST_CREATE_OPEN_FAILURE(h,n,e) \
162     pRtlCreateUnicodeStringFromAsciiz(&str, n);\
163     DIR_TEST_CREATE_FAILURE(h,e) DIR_TEST_OPEN_FAILURE(h,e)\
164     pRtlFreeUnicodeString(&str);
165
166 #define DIR_TEST_CREATE_SUCCESS(h) \
167     status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr); \
168     ok(status == STATUS_SUCCESS, "Failed to create Directory(%08x)\n", status);
169 #define DIR_TEST_OPEN_SUCCESS(h) \
170     status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr); \
171     ok(status == STATUS_SUCCESS, "Failed to open Directory(%08x)\n", status);
172 #define DIR_TEST_CREATE_OPEN_SUCCESS(h,n) \
173     pRtlCreateUnicodeStringFromAsciiz(&str, n);\
174     DIR_TEST_CREATE_SUCCESS(&h) pNtClose(h); DIR_TEST_OPEN_SUCCESS(&h) pNtClose(h); \
175     pRtlFreeUnicodeString(&str);
176
177 static void test_name_collisions(void)
178 {
179     NTSTATUS status;
180     UNICODE_STRING str;
181     OBJECT_ATTRIBUTES attr;
182     HANDLE dir, h, h1, h2;
183     DWORD winerr;
184     LARGE_INTEGER size;
185
186     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
187     pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
188     DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_COLLISION)
189     InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
190
191     DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_EXISTS)
192     pNtClose(h);
193     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
194     ok(status == STATUS_OBJECT_TYPE_MISMATCH,
195         "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
196     pRtlFreeUnicodeString(&str);
197
198     pRtlCreateUnicodeStringFromAsciiz(&str, "\\??\\PIPE\\om.c-mutant");
199     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
200     ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_OBJECT_PATH_NOT_FOUND,
201         "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
202     pRtlFreeUnicodeString(&str);
203
204
205     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
206     DIR_TEST_OPEN_SUCCESS(&dir)
207     pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
208     InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
209     
210     h = CreateMutexA(NULL, FALSE, "om.c-test");
211     ok(h != 0, "CreateMutexA failed got ret=%p (%d)\n", h, GetLastError());
212     status = pNtCreateMutant(&h1, GENERIC_ALL, &attr, FALSE);
213     ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
214         "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
215     h2 = CreateMutexA(NULL, FALSE, "om.c-test");
216     winerr = GetLastError();
217     ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
218         "CreateMutexA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
219     pNtClose(h);
220     pNtClose(h1);
221     pNtClose(h2);
222
223     h = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
224     ok(h != 0, "CreateEventA failed got ret=%p (%d)\n", h, GetLastError());
225     status = pNtCreateEvent(&h1, GENERIC_ALL, &attr, FALSE, FALSE);
226     ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
227         "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
228     h2 = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
229     winerr = GetLastError();
230     ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
231         "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
232     pNtClose(h);
233     pNtClose(h1);
234     pNtClose(h2);
235
236     h = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
237     ok(h != 0, "CreateSemaphoreA failed got ret=%p (%d)\n", h, GetLastError());
238     status = pNtCreateSemaphore(&h1, GENERIC_ALL, &attr, 1, 2);
239     ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
240         "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
241     h2 = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
242     winerr = GetLastError();
243     ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
244         "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
245     pNtClose(h);
246     pNtClose(h1);
247     pNtClose(h2);
248     
249     h = CreateWaitableTimerA(NULL, TRUE, "om.c-test");
250     ok(h != 0, "CreateWaitableTimerA failed got ret=%p (%d)\n", h, GetLastError());
251     status = pNtCreateTimer(&h1, GENERIC_ALL, &attr, NotificationTimer);
252     ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
253         "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
254     h2 = CreateWaitableTimerA(NULL, TRUE, "om.c-test");
255     winerr = GetLastError();
256     ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
257         "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
258     pNtClose(h);
259     pNtClose(h1);
260     pNtClose(h2);
261
262     h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
263     ok(h != 0, "CreateFileMappingA failed got ret=%p (%d)\n", h, GetLastError());
264     size.u.LowPart = 256;
265     size.u.HighPart = 0;
266     status = pNtCreateSection(&h1, SECTION_MAP_WRITE, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
267     ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
268         "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
269     h2 = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
270     winerr = GetLastError();
271     ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
272         "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
273     pNtClose(h);
274     pNtClose(h1);
275     pNtClose(h2);
276
277     pRtlFreeUnicodeString(&str);
278     pNtClose(dir);
279 }
280
281 static void test_directory(void)
282 {
283     NTSTATUS status;
284     UNICODE_STRING str;
285     OBJECT_ATTRIBUTES attr;
286     HANDLE dir, dir1, h;
287
288     /* No name and/or no attributes */
289     status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
290     ok(status == STATUS_ACCESS_VIOLATION,
291         "NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
292     status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
293     ok(status == STATUS_ACCESS_VIOLATION,
294         "NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
295
296     status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL);
297     ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08x)\n", status);
298     pNtClose(h);
299     status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL);
300     ok(status == STATUS_INVALID_PARAMETER,
301         "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
302
303     InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
304     DIR_TEST_CREATE_SUCCESS(&dir)
305     DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
306
307     /* Bad name */
308     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
309
310     pRtlCreateUnicodeStringFromAsciiz(&str, "");
311     DIR_TEST_CREATE_SUCCESS(&h)
312     pNtClose(h);
313     DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
314     pRtlFreeUnicodeString(&str);
315     pNtClose(dir);
316
317     DIR_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD)
318     DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID)
319     DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID)
320     DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID)
321     DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
322
323     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
324     DIR_TEST_CREATE_SUCCESS(&h)
325     DIR_TEST_OPEN_SUCCESS(&dir1)
326     pRtlFreeUnicodeString(&str);
327     pNtClose(h);
328     pNtClose(dir1);
329
330
331     /* Use of root directory */
332
333     /* Can't use symlinks as a directory */
334     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local");
335     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
336     status = pNtOpenSymbolicLinkObject(&dir, SYMBOLIC_LINK_QUERY, &attr);
337     ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08x)\n", status);
338     pRtlFreeUnicodeString(&str);
339     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
340     pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
341     DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH)
342     pRtlFreeUnicodeString(&str);
343     pNtClose(h);
344     pNtClose(dir);
345
346     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
347     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
348     DIR_TEST_OPEN_SUCCESS(&dir)
349     pRtlFreeUnicodeString(&str);
350
351     InitializeObjectAttributes(&attr, NULL, 0, dir, NULL);
352     DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_NAME_INVALID)
353
354     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
355     DIR_TEST_CREATE_OPEN_SUCCESS(h, "")
356     DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
357     DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD)
358     DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
359     DIR_TEST_CREATE_OPEN_FAILURE(&h, "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
360
361     pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
362     DIR_TEST_CREATE_SUCCESS(&dir1)
363     DIR_TEST_OPEN_SUCCESS(&h)
364     pRtlFreeUnicodeString(&str);
365
366     pNtClose(h);
367     pNtClose(dir1);
368     pNtClose(dir);
369
370     /* Nested directories */
371     pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
372     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
373     DIR_TEST_OPEN_SUCCESS(&dir)
374     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
375     DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
376     pRtlFreeUnicodeString(&str);
377     pNtClose(dir);
378
379     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
380     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
381     DIR_TEST_CREATE_SUCCESS(&dir)
382     pRtlFreeUnicodeString(&str);
383     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test\\one more level");
384     DIR_TEST_CREATE_SUCCESS(&h)
385     pRtlFreeUnicodeString(&str);
386     pNtClose(h);
387     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
388     pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
389     DIR_TEST_CREATE_SUCCESS(&h)
390     pRtlFreeUnicodeString(&str);
391     pNtClose(h);
392
393     pNtClose(dir);
394
395     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
396     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Global\\om.c-test");
397     DIR_TEST_CREATE_SUCCESS(&dir)
398     pRtlFreeUnicodeString(&str);
399     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local\\om.c-test\\one more level");
400     DIR_TEST_CREATE_SUCCESS(&h)
401     pRtlFreeUnicodeString(&str);
402     pNtClose(h);
403     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
404     pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
405     DIR_TEST_CREATE_SUCCESS(&dir)
406     pRtlFreeUnicodeString(&str);
407     pNtClose(h);
408
409     pNtClose(dir);
410
411
412     /* Create other objects using RootDirectory */
413
414     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
415     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
416     DIR_TEST_OPEN_SUCCESS(&dir)
417     pRtlFreeUnicodeString(&str);
418     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
419
420     /* Test inavalid paths */
421     pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant");
422     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
423     ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
424         "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
425     pRtlFreeUnicodeString(&str);
426     pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant\\");
427     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
428     ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
429         "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
430     pRtlFreeUnicodeString(&str);
431
432     pRtlCreateUnicodeStringFromAsciiz(&str, "om.c\\-mutant");
433     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
434     ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
435         "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
436     pRtlFreeUnicodeString(&str);
437
438     pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-mutant");
439     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
440     ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
441     pRtlFreeUnicodeString(&str);
442     pNtClose(h);
443
444     pNtClose(dir);
445 }
446
447 #define SYMLNK_TEST_CREATE_FAILURE(h,e) \
448     status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\
449     ok(status == e,"NtCreateSymbolicLinkObject should have failed with %s got(%08x)\n", #e, status);
450 #define SYMLNK_TEST_OPEN_FAILURE(h,e) \
451     status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\
452     ok(status == e,"NtOpenSymbolicLinkObject should have failed with %s got(%08x)\n", #e, status);
453 #define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) \
454     pRtlCreateUnicodeStringFromAsciiz(&str, n);\
455     pRtlCreateUnicodeStringFromAsciiz(&target, t);\
456     SYMLNK_TEST_CREATE_FAILURE(h,e)\
457     SYMLNK_TEST_OPEN_FAILURE(h,e)\
458     pRtlFreeUnicodeString(&target);\
459     pRtlFreeUnicodeString(&str);
460
461 #define SYMLNK_TEST_CREATE_SUCCESS(h) \
462     status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target); \
463     ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status);
464 #define SYMLNK_TEST_OPEN_SUCCESS(h) \
465     status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr); \
466     ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08x)\n", status);
467
468 static void test_symboliclink(void)
469 {
470     NTSTATUS status;
471     UNICODE_STRING str, target;
472     OBJECT_ATTRIBUTES attr;
473     HANDLE dir, link, h;
474     IO_STATUS_BLOCK iosb;
475
476     /* No name and/or no attributes */
477     SYMLNK_TEST_CREATE_OPEN_FAILURE(NULL, "", "", STATUS_ACCESS_VIOLATION)
478
479     status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL);
480     ok(status == STATUS_ACCESS_VIOLATION,
481         "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
482     status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL);
483     ok(status == STATUS_INVALID_PARAMETER,
484         "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
485
486     /* No attributes */
487     pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
488     status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, &target);
489     ok(status == STATUS_SUCCESS, "NtCreateSymbolicLinkObject failed(%08x)\n", status);
490     pRtlFreeUnicodeString(&target);
491     pNtClose(h);
492
493     InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
494     SYMLNK_TEST_CREATE_FAILURE(&link, STATUS_INVALID_PARAMETER)
495     SYMLNK_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
496
497     /* Bad name */
498     pRtlCreateUnicodeStringFromAsciiz(&target, "anywhere");
499     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
500
501     pRtlCreateUnicodeStringFromAsciiz(&str, "");
502     SYMLNK_TEST_CREATE_SUCCESS(&link)
503     SYMLNK_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
504     pNtClose(link);
505     pRtlFreeUnicodeString(&str);
506
507     pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
508     todo_wine {SYMLNK_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH)}
509     pRtlFreeUnicodeString(&str);
510     pRtlFreeUnicodeString(&target);
511
512     SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", "->Somewhere", STATUS_OBJECT_PATH_SYNTAX_BAD)
513     SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
514     SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
515     SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
516     SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
517
518
519     /* Compaund test */
520     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
521     DIR_TEST_OPEN_SUCCESS(&dir)
522     pRtlFreeUnicodeString(&str);
523
524     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
525     pRtlCreateUnicodeStringFromAsciiz(&str, "Local\\test-link");
526     pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
527     SYMLNK_TEST_CREATE_SUCCESS(&link)
528     pRtlFreeUnicodeString(&str);
529     pRtlFreeUnicodeString(&target);
530
531     pRtlCreateUnicodeStringFromAsciiz(&str, "Local\\test-link\\PIPE");
532     status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN);
533     todo_wine ok(status == STATUS_SUCCESS, "Failed to open NamedPipe(%08x)\n", status);
534     pRtlFreeUnicodeString(&str);
535
536     pNtClose(h);
537     pNtClose(link);
538     pNtClose(dir);
539 }
540
541 START_TEST(om)
542 {
543     HMODULE hntdll = GetModuleHandleA("ntdll.dll");
544     if (!hntdll)
545     {
546         skip("not running on NT, skipping test\n");
547         return;
548     }
549
550     pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
551     pRtlFreeUnicodeString   = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
552     pNtCreateEvent          = (void *)GetProcAddress(hntdll, "NtCreateEvent");
553     pNtCreateMutant         = (void *)GetProcAddress(hntdll, "NtCreateMutant");
554     pNtOpenMutant           = (void *)GetProcAddress(hntdll, "NtOpenMutant");
555     pNtOpenFile             = (void *)GetProcAddress(hntdll, "NtOpenFile");
556     pNtClose                = (void *)GetProcAddress(hntdll, "NtClose");
557     pRtlInitUnicodeString   = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
558     pNtCreateNamedPipeFile  = (void *)GetProcAddress(hntdll, "NtCreateNamedPipeFile");
559     pNtOpenDirectoryObject  = (void *)GetProcAddress(hntdll, "NtOpenDirectoryObject");
560     pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject");
561     pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject");
562     pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject");
563     pNtCreateSemaphore      =  (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
564     pNtCreateTimer          =  (void *)GetProcAddress(hntdll, "NtCreateTimer");
565     pNtCreateSection        =  (void *)GetProcAddress(hntdll, "NtCreateSection");
566
567     test_case_sensitive();
568     test_namespace_pipe();
569     test_name_collisions();
570     test_directory();
571     test_symboliclink();
572 }