xref: /reactos/modules/rostests/winetests/ntdll/om.c (revision 279107d5)
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 BOOLEAN  (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 *pNtOpenEvent)   ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES);
34 static NTSTATUS (WINAPI *pNtPulseEvent)  ( HANDLE, PULONG );
35 static NTSTATUS (WINAPI *pNtQueryEvent)  ( HANDLE, EVENT_INFORMATION_CLASS, PVOID, ULONG, PULONG );
36 static NTSTATUS (WINAPI *pNtCreateJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
37 static NTSTATUS (WINAPI *pNtOpenJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
38 static NTSTATUS (WINAPI *pNtCreateKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG,
39                                         const UNICODE_STRING *, ULONG, PULONG );
40 static NTSTATUS (WINAPI *pNtOpenKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
41 static NTSTATUS (WINAPI *pNtDeleteKey)( HANDLE );
42 static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
43                                                  ULONG, ULONG, ULONG, PLARGE_INTEGER );
44 static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN );
45 static NTSTATUS (WINAPI *pNtOpenMutant)  ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
46 static NTSTATUS (WINAPI *pNtQueryMutant) ( HANDLE, MUTANT_INFORMATION_CLASS, PVOID, ULONG, PULONG );
47 static NTSTATUS (WINAPI *pNtReleaseMutant)( HANDLE, PLONG );
48 static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG );
49 static NTSTATUS (WINAPI *pNtOpenSemaphore)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
50 static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE );
51 static NTSTATUS (WINAPI *pNtOpenTimer)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
52 static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER,
53                                             ULONG, ULONG, HANDLE );
54 static NTSTATUS (WINAPI *pNtOpenSection)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
55 static NTSTATUS (WINAPI *pNtOpenFile)    ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG );
56 static NTSTATUS (WINAPI *pNtClose)       ( HANDLE );
57 static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
58                                        ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, PLARGE_INTEGER );
59 static NTSTATUS (WINAPI *pNtOpenDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
60 static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
61 static NTSTATUS (WINAPI *pNtOpenSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
62 static NTSTATUS (WINAPI *pNtCreateSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PUNICODE_STRING);
63 static NTSTATUS (WINAPI *pNtQuerySymbolicLinkObject)(HANDLE,PUNICODE_STRING,PULONG);
64 static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG);
65 static NTSTATUS (WINAPI *pNtReleaseSemaphore)(HANDLE, ULONG, PULONG);
66 static NTSTATUS (WINAPI *pNtCreateKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG );
67 static NTSTATUS (WINAPI *pNtOpenKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES * );
68 static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
69 static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
70 static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG);
71 static NTSTATUS (WINAPI *pNtOpenIoCompletion)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
72 static NTSTATUS (WINAPI *pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
73 
74 #define KEYEDEVENT_WAIT       0x0001
75 #define KEYEDEVENT_WAKE       0x0002
76 #define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x0003)
77 
78 #define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
79 
80 static LPCSTR wine_dbgstr_us( const UNICODE_STRING *us )
81 {
82     if (!us) return "(null)";
83     return wine_dbgstr_wn(us->Buffer, us->Length / sizeof(WCHAR));
84 }
85 
86 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
87 {
88     if (n <= 0) return 0;
89     while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
90     return *str1 - *str2;
91 }
92 
93 static void test_case_sensitive (void)
94 {
95     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};
96     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};
97     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};
98     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};
99     NTSTATUS status;
100     OBJECT_ATTRIBUTES attr;
101     UNICODE_STRING str;
102     HANDLE Event, Mutant, h;
103 
104     pRtlInitUnicodeString(&str, buffer1);
105     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
106     status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
107     ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
108 
109     status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
110     ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
111         "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status);
112 
113     pRtlInitUnicodeString(&str, buffer2);
114     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
115     status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
116     ok(status == STATUS_SUCCESS, "Failed to create Event(%08x)\n", status);
117 
118     pRtlInitUnicodeString(&str, buffer3);
119     InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
120     status = pNtOpenMutant(&h, GENERIC_ALL, &attr);
121     ok(status == STATUS_OBJECT_TYPE_MISMATCH,
122         "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
123 
124     pNtClose(Mutant);
125 
126     pRtlInitUnicodeString(&str, buffer4);
127     InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
128     status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
129     ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
130         "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status);
131 
132     status = pNtCreateEvent(&h, GENERIC_ALL, &attr, FALSE, FALSE);
133     ok(status == STATUS_OBJECT_NAME_COLLISION,
134         "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status);
135 
136     attr.Attributes = 0;
137     status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
138     ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
139         "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
140 
141     pNtClose(Event);
142 }
143 
144 static void test_namespace_pipe(void)
145 {
146     static const WCHAR buffer1[] = {'\\','?','?','\\','P','I','P','E','\\','t','e','s','t','\\','p','i','p','e',0};
147     static const WCHAR buffer2[] = {'\\','?','?','\\','P','I','P','E','\\','T','E','S','T','\\','P','I','P','E',0};
148     static const WCHAR buffer3[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t','\\','p','i','p','e',0};
149     static const WCHAR buffer4[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t',0};
150     OBJECT_ATTRIBUTES attr;
151     UNICODE_STRING str;
152     IO_STATUS_BLOCK iosb;
153     NTSTATUS status;
154     LARGE_INTEGER timeout;
155     HANDLE pipe, h;
156 
157     timeout.QuadPart = -10000;
158 
159     pRtlInitUnicodeString(&str, buffer1);
160     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
161     status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
162                                     FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
163     ok(status == STATUS_SUCCESS, "Failed to create NamedPipe(%08x)\n", status);
164 
165     status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
166                                     FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
167     ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
168         "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
169 
170     pRtlInitUnicodeString(&str, buffer2);
171     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
172     status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
173                                     FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
174     ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
175         "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
176 
177     h = CreateFileA("\\\\.\\pipe\\test\\pipe", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
178                     OPEN_EXISTING, 0, 0 );
179     ok(h != INVALID_HANDLE_VALUE, "Failed to open NamedPipe (%u)\n", GetLastError());
180     pNtClose(h);
181 
182     pRtlInitUnicodeString(&str, buffer3);
183     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
184     status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
185     ok(status == STATUS_OBJECT_PATH_NOT_FOUND ||
186        status == STATUS_PIPE_NOT_AVAILABLE ||
187        status == STATUS_OBJECT_NAME_INVALID || /* vista */
188        status == STATUS_OBJECT_NAME_NOT_FOUND, /* win8 */
189         "NtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
190 
191     pRtlInitUnicodeString(&str, buffer4);
192     InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
193     status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
194     ok(status == STATUS_OBJECT_NAME_NOT_FOUND ||
195        status == STATUS_OBJECT_NAME_INVALID, /* vista */
196         "NtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08x)\n", status);
197 
198     str.Length -= 4 * sizeof(WCHAR);
199     status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
200     ok(status == STATUS_SUCCESS, "NtOpenFile should have succeeded got %08x\n", status);
201     pNtClose( h );
202 
203     str.Length -= sizeof(WCHAR);
204     status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
205     ok(status == STATUS_SUCCESS, "NtOpenFile should have succeeded got %08x\n", status);
206     pNtClose( h );
207 
208     pNtClose(pipe);
209 }
210 
211 #define DIRECTORY_QUERY (0x0001)
212 #define SYMBOLIC_LINK_QUERY 0x0001
213 
214 #define DIR_TEST_CREATE_OPEN(n,e) \
215     do { \
216         HANDLE h; \
217         pRtlCreateUnicodeStringFromAsciiz(&str, n); \
218         status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr ); \
219         ok( status == e, "NtCreateDirectoryObject(%s) got %08x\n", n, status ); \
220         if (!status) pNtClose( h ); \
221         status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr ); \
222         ok( status == e, "NtOpenDirectoryObject(%s) got %08x\n", n, status ); \
223         if (!status) pNtClose( h ); \
224         pRtlFreeUnicodeString(&str); \
225     } while(0)
226 
227 static BOOL is_correct_dir( HANDLE dir, const char *name )
228 {
229     NTSTATUS status;
230     UNICODE_STRING str;
231     OBJECT_ATTRIBUTES attr;
232     HANDLE h = 0;
233 
234     pRtlCreateUnicodeStringFromAsciiz(&str, name);
235     InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
236     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
237     pRtlFreeUnicodeString(&str);
238     if (h) pNtClose( h );
239     return (status == STATUS_OBJECT_NAME_EXISTS);
240 }
241 
242 /* return a handle to the BaseNamedObjects dir where kernel32 objects get created */
243 static HANDLE get_base_dir(void)
244 {
245     static const char objname[] = "om.c_get_base_dir_obj";
246     NTSTATUS status;
247     UNICODE_STRING str;
248     OBJECT_ATTRIBUTES attr;
249     HANDLE dir, h;
250     char name[40];
251 
252     h = CreateMutexA(NULL, FALSE, objname);
253     ok(h != 0, "CreateMutexA failed got ret=%p (%d)\n", h, GetLastError());
254     InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
255 
256     sprintf( name, "\\BaseNamedObjects\\Session\\%u", NtCurrentTeb()->Peb->SessionId );
257     pRtlCreateUnicodeStringFromAsciiz(&str, name );
258     status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
259     pRtlFreeUnicodeString(&str);
260     if (!status && is_correct_dir( dir, objname )) goto done;
261     if (!status) pNtClose( dir );
262 
263     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
264     status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
265     pRtlFreeUnicodeString(&str);
266     if (!status && is_correct_dir( dir, objname )) goto done;
267     if (!status) pNtClose( dir );
268 
269     dir = 0;
270 
271 done:
272     pNtClose( h );
273     return dir;
274 }
275 
276 static void test_name_collisions(void)
277 {
278     NTSTATUS status;
279     UNICODE_STRING str;
280     OBJECT_ATTRIBUTES attr;
281     HANDLE dir, h, h1, h2;
282     DWORD winerr;
283     LARGE_INTEGER size;
284 
285     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
286     pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
287     status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
288     ok( status == STATUS_OBJECT_NAME_COLLISION, "NtCreateDirectoryObject got %08x\n", status );
289     InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
290 
291     status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
292     ok( status == STATUS_OBJECT_NAME_EXISTS, "NtCreateDirectoryObject got %08x\n", status );
293     pNtClose(h);
294     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
295     ok(status == STATUS_OBJECT_TYPE_MISMATCH,
296         "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
297     pRtlFreeUnicodeString(&str);
298 
299     pRtlCreateUnicodeStringFromAsciiz(&str, "\\??\\PIPE\\om.c-mutant");
300     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
301     ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_OBJECT_PATH_NOT_FOUND,
302         "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
303     pRtlFreeUnicodeString(&str);
304 
305     if (!(dir = get_base_dir()))
306     {
307         win_skip( "couldn't find the BaseNamedObjects dir\n" );
308         return;
309     }
310     pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
311     InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
312     h = CreateMutexA(NULL, FALSE, "om.c-test");
313     ok(h != 0, "CreateMutexA failed got ret=%p (%d)\n", h, GetLastError());
314     status = pNtCreateMutant(&h1, GENERIC_ALL, &attr, FALSE);
315     ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
316         "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
317     h2 = CreateMutexA(NULL, FALSE, "om.c-test");
318     winerr = GetLastError();
319     ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
320         "CreateMutexA 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 = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
326     ok(h != 0, "CreateEventA failed got ret=%p (%d)\n", h, GetLastError());
327     status = pNtCreateEvent(&h1, GENERIC_ALL, &attr, FALSE, FALSE);
328     ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
329         "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
330     h2 = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
331     winerr = GetLastError();
332     ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
333         "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
334     pNtClose(h);
335     pNtClose(h1);
336     pNtClose(h2);
337 
338     h = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
339     ok(h != 0, "CreateSemaphoreA failed got ret=%p (%d)\n", h, GetLastError());
340     status = pNtCreateSemaphore(&h1, GENERIC_ALL, &attr, 1, 2);
341     ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
342         "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
343     h2 = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
344     winerr = GetLastError();
345     ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
346         "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
347     pNtClose(h);
348     pNtClose(h1);
349     pNtClose(h2);
350 
351     h = pCreateWaitableTimerA(NULL, TRUE, "om.c-test");
352     ok(h != 0, "CreateWaitableTimerA failed got ret=%p (%d)\n", h, GetLastError());
353     status = pNtCreateTimer(&h1, GENERIC_ALL, &attr, NotificationTimer);
354     ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
355         "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
356     h2 = pCreateWaitableTimerA(NULL, TRUE, "om.c-test");
357     winerr = GetLastError();
358     ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
359         "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
360     pNtClose(h);
361     pNtClose(h1);
362     pNtClose(h2);
363 
364     h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
365     ok(h != 0, "CreateFileMappingA failed got ret=%p (%d)\n", h, GetLastError());
366     size.u.LowPart = 256;
367     size.u.HighPart = 0;
368     status = pNtCreateSection(&h1, SECTION_MAP_WRITE, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
369     ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
370         "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
371     h2 = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
372     winerr = GetLastError();
373     ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
374         "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
375     pNtClose(h);
376     pNtClose(h1);
377     pNtClose(h2);
378 
379     pRtlFreeUnicodeString(&str);
380     pNtClose(dir);
381 }
382 
383 static void test_all_kernel_objects( UINT line, OBJECT_ATTRIBUTES *attr,
384                                      NTSTATUS create_expect, NTSTATUS open_expect )
385 {
386     UNICODE_STRING target;
387     LARGE_INTEGER size;
388     NTSTATUS status, status2;
389     HANDLE ret, ret2;
390 
391     pRtlCreateUnicodeStringFromAsciiz( &target, "\\DosDevices" );
392     size.QuadPart = 4096;
393 
394     status = pNtCreateMutant( &ret, GENERIC_ALL, attr, FALSE );
395     ok( status == create_expect, "%u: NtCreateMutant failed %x\n", line, status );
396     status2 = pNtOpenMutant( &ret2, GENERIC_ALL, attr );
397     ok( status2 == open_expect, "%u: NtOpenMutant failed %x\n", line, status2 );
398     if (!status) pNtClose( ret );
399     if (!status2) pNtClose( ret2 );
400     status = pNtCreateSemaphore( &ret, GENERIC_ALL, attr, 1, 2 );
401     ok( status == create_expect, "%u: NtCreateSemaphore failed %x\n", line, status );
402     status2 = pNtOpenSemaphore( &ret2, GENERIC_ALL, attr );
403     ok( status2 == open_expect, "%u: NtOpenSemaphore failed %x\n", line, status2 );
404     if (!status) pNtClose( ret );
405     if (!status2) pNtClose( ret2 );
406     status = pNtCreateEvent( &ret, GENERIC_ALL, attr, 1, 0 );
407     ok( status == create_expect, "%u: NtCreateEvent failed %x\n", line, status );
408     status2 = pNtOpenEvent( &ret2, GENERIC_ALL, attr );
409     ok( status2 == open_expect, "%u: NtOpenEvent failed %x\n", line, status2 );
410     if (!status) pNtClose( ret );
411     if (!status2) pNtClose( ret2 );
412     status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, attr, 0 );
413     ok( status == create_expect, "%u: NtCreateKeyedEvent failed %x\n", line, status );
414     status2 = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, attr );
415     ok( status2 == open_expect, "%u: NtOpenKeyedEvent failed %x\n", line, status2 );
416     if (!status) pNtClose( ret );
417     if (!status2) pNtClose( ret2 );
418     status = pNtCreateTimer( &ret, GENERIC_ALL, attr, NotificationTimer );
419     ok( status == create_expect, "%u: NtCreateTimer failed %x\n", line, status );
420     status2 = pNtOpenTimer( &ret2, GENERIC_ALL, attr );
421     ok( status2 == open_expect, "%u: NtOpenTimer failed %x\n", line, status2 );
422     if (!status) pNtClose( ret );
423     if (!status2) pNtClose( ret2 );
424     status = pNtCreateIoCompletion( &ret, GENERIC_ALL, attr, 0 );
425     ok( status == create_expect, "%u: NtCreateCompletion failed %x\n", line, status );
426     status2 = pNtOpenIoCompletion( &ret2, GENERIC_ALL, attr );
427     ok( status2 == open_expect, "%u: NtOpenCompletion failed %x\n", line, status2 );
428     if (!status) pNtClose( ret );
429     if (!status2) pNtClose( ret2 );
430     status = pNtCreateJobObject( &ret, GENERIC_ALL, attr );
431     ok( status == create_expect, "%u: NtCreateJobObject failed %x\n", line, status );
432     status2 = pNtOpenJobObject( &ret2, GENERIC_ALL, attr );
433     ok( status2 == open_expect, "%u: NtOpenJobObject failed %x\n", line, status2 );
434     if (!status) pNtClose( ret );
435     if (!status2) pNtClose( ret2 );
436     status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, attr );
437     ok( status == create_expect, "%u: NtCreateDirectoryObject failed %x\n", line, status );
438     status2 = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, attr );
439     ok( status2 == open_expect, "%u: NtOpenDirectoryObject failed %x\n", line, status2 );
440     if (!status) pNtClose( ret );
441     if (!status2) pNtClose( ret2 );
442     status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, attr, &target );
443     ok( status == create_expect, "%u: NtCreateSymbolicLinkObject failed %x\n", line, status );
444     status2 = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, attr );
445     ok( status2 == open_expect, "%u: NtOpenSymbolicLinkObject failed %x\n", line, status2 );
446     if (!status) pNtClose( ret );
447     if (!status2) pNtClose( ret2 );
448     status = pNtCreateSection( &ret, SECTION_MAP_WRITE, attr, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
449     ok( status == create_expect, "%u: NtCreateSection failed %x\n", line, status );
450     status2 = pNtOpenSection( &ret2, SECTION_MAP_WRITE, attr );
451     ok( status2 == open_expect, "%u: NtOpenSection failed %x\n", line, status2 );
452     if (!status) pNtClose( ret );
453     if (!status2) pNtClose( ret2 );
454     pRtlFreeUnicodeString( &target );
455 }
456 
457 static void test_name_limits(void)
458 {
459     static const WCHAR localW[]    = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','L','o','c','a','l',0};
460     static const WCHAR pipeW[]     = {'\\','D','e','v','i','c','e','\\','N','a','m','e','d','P','i','p','e','\\'};
461     static const WCHAR mailslotW[] = {'\\','D','e','v','i','c','e','\\','M','a','i','l','S','l','o','t','\\'};
462     static const WCHAR registryW[] = {'\\','R','E','G','I','S','T','R','Y','\\','M','a','c','h','i','n','e','\\','S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\'};
463     OBJECT_ATTRIBUTES attr, attr2, attr3;
464     IO_STATUS_BLOCK iosb;
465     LARGE_INTEGER size, timeout;
466     UNICODE_STRING str, str2, target;
467     NTSTATUS status;
468     HANDLE ret, ret2;
469     DWORD i;
470 
471     InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
472     InitializeObjectAttributes( &attr2, &str, 0, (HANDLE)0xdeadbeef, NULL );
473     InitializeObjectAttributes( &attr3, &str, 0, 0, NULL );
474     str.Buffer = HeapAlloc( GetProcessHeap(), 0, 65536 + sizeof(registryW));
475     str.MaximumLength = 65534;
476     for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i] = 'a';
477     size.QuadPart = 4096;
478     pRtlCreateUnicodeStringFromAsciiz( &target, "\\DosDevices" );
479 
480     if (!(attr.RootDirectory = get_base_dir()))
481     {
482         win_skip( "couldn't find the BaseNamedObjects dir\n" );
483         return;
484     }
485 
486     str.Length = 0;
487     status = pNtCreateMutant( &ret, GENERIC_ALL, &attr2, FALSE );
488     ok( status == STATUS_SUCCESS, "%u: NtCreateMutant failed %x\n", str.Length, status );
489     attr3.RootDirectory = ret;
490     status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr );
491     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenMutant failed %x\n", str.Length, status );
492     status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr3 );
493     ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE,
494         "%u: NtOpenMutant failed %x\n", str.Length, status );
495     pNtClose( ret );
496     status = pNtCreateSemaphore( &ret, GENERIC_ALL, &attr2, 1, 2 );
497     ok( status == STATUS_SUCCESS, "%u: NtCreateSemaphore failed %x\n", str.Length, status );
498     attr3.RootDirectory = ret;
499     status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr );
500     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSemaphore failed %x\n", str.Length, status );
501     status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr3 );
502     ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE,
503         "%u: NtOpenSemaphore failed %x\n", str.Length, status );
504     pNtClose( ret );
505     status = pNtCreateEvent( &ret, GENERIC_ALL, &attr2, 1, 0 );
506     ok( status == STATUS_SUCCESS, "%u: NtCreateEvent failed %x\n", str.Length, status );
507     attr3.RootDirectory = ret;
508     status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr );
509     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenEvent failed %x\n", str.Length, status );
510     status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr3 );
511     ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE,
512         "%u: NtOpenEvent failed %x\n", str.Length, status );
513     pNtClose( ret );
514     status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, &attr2, 0 );
515     ok( status == STATUS_SUCCESS, "%u: NtCreateKeyedEvent failed %x\n", str.Length, status );
516     attr3.RootDirectory = ret;
517     status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr );
518     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenKeyedEvent failed %x\n", str.Length, status );
519     status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr3 );
520     ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE,
521         "%u: NtOpenKeyedEvent failed %x\n", str.Length, status );
522     pNtClose( ret );
523     status = pNtCreateTimer( &ret, GENERIC_ALL, &attr2, NotificationTimer );
524     ok( status == STATUS_SUCCESS, "%u: NtCreateTimer failed %x\n", str.Length, status );
525     attr3.RootDirectory = ret;
526     status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr );
527     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenTimer failed %x\n", str.Length, status );
528     status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr3 );
529     ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE,
530         "%u: NtOpenTimer failed %x\n", str.Length, status );
531     pNtClose( ret );
532     status = pNtCreateIoCompletion( &ret, GENERIC_ALL, &attr2, 0 );
533     ok( status == STATUS_SUCCESS, "%u: NtCreateCompletion failed %x\n", str.Length, status );
534     attr3.RootDirectory = ret;
535     status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr );
536     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenCompletion failed %x\n", str.Length, status );
537     status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr3 );
538     ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE,
539         "%u: NtOpenCompletion failed %x\n", str.Length, status );
540     pNtClose( ret );
541     status = pNtCreateJobObject( &ret, GENERIC_ALL, &attr2 );
542     ok( status == STATUS_SUCCESS, "%u: NtCreateJobObject failed %x\n", str.Length, status );
543     attr3.RootDirectory = ret;
544     status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr );
545     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenJobObject failed %x\n", str.Length, status );
546     status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr3 );
547     ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE,
548         "%u: NtOpenJobObject failed %x\n", str.Length, status );
549     pNtClose( ret );
550     status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, &attr2 );
551     ok( status == STATUS_SUCCESS, "%u: NtCreateDirectoryObject failed %x\n", str.Length, status );
552     attr3.RootDirectory = ret;
553     status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr );
554     ok( status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_DENIED), /* winxp */
555         "%u: NtOpenDirectoryObject failed %x\n", str.Length, status );
556     if (!status) pNtClose( ret2 );
557     status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr3 );
558     ok( status == STATUS_SUCCESS, "%u: NtOpenDirectoryObject failed %x\n", str.Length, status );
559     pNtClose( ret2 );
560     pNtClose( ret );
561     status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, &attr2, &target );
562     ok( status == STATUS_SUCCESS, "%u: NtCreateSymbolicLinkObject failed %x\n", str.Length, status );
563     attr3.RootDirectory = ret;
564     status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr );
565     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSymbolicLinkObject failed %x\n", str.Length, status );
566     status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr3 );
567     ok( status == STATUS_SUCCESS, "%u: NtOpenSymbolicLinkObject failed %x\n", str.Length, status );
568     pNtClose( ret2 );
569     pNtClose( ret );
570     status = pNtCreateSection( &ret, SECTION_MAP_WRITE, &attr2, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
571     ok( status == STATUS_SUCCESS, "%u: NtCreateSection failed %x\n", str.Length, status );
572     attr3.RootDirectory = ret;
573     status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr );
574     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSection failed %x\n", str.Length, status );
575     status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr3 );
576     ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE,
577         "%u: NtOpenSection failed %x\n", str.Length, status );
578     pNtClose( ret );
579 
580     str.Length = 67;
581     test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
582 
583     str.Length = 65532;
584     test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS );
585 
586     str.Length = 65534;
587     test_all_kernel_objects( __LINE__, &attr, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
588 
589     str.Length = 128;
590     for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
591     {
592         if (attr.Length == sizeof(attr))
593             test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS );
594         else
595             test_all_kernel_objects( __LINE__, &attr, STATUS_INVALID_PARAMETER, STATUS_INVALID_PARAMETER );
596     }
597     attr.Length = sizeof(attr);
598 
599     /* null attributes or ObjectName, with or without RootDirectory */
600     attr3.RootDirectory = 0;
601     attr2.ObjectName = attr3.ObjectName = NULL;
602     test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
603     test_all_kernel_objects( __LINE__, &attr3, STATUS_SUCCESS, STATUS_OBJECT_PATH_SYNTAX_BAD );
604 
605     attr3.ObjectName = &str2;
606     pRtlInitUnicodeString( &str2, localW );
607     status = pNtOpenSymbolicLinkObject( &ret, SYMBOLIC_LINK_QUERY, &attr3 );
608     ok( status == STATUS_SUCCESS, "can't open BaseNamedObjects\\Local %x\n", status );
609     attr3.ObjectName = &str;
610     attr3.RootDirectory = ret;
611     test_all_kernel_objects( __LINE__, &attr3, STATUS_OBJECT_TYPE_MISMATCH, STATUS_OBJECT_TYPE_MISMATCH );
612     pNtClose( attr3.RootDirectory );
613 
614     status = pNtCreateMutant( &ret, GENERIC_ALL, NULL, FALSE );
615     ok( status == STATUS_SUCCESS, "NULL: NtCreateMutant failed %x\n", status );
616     pNtClose( ret );
617     status = pNtOpenMutant( &ret, GENERIC_ALL, NULL );
618     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenMutant failed %x\n", status );
619     status = pNtCreateSemaphore( &ret, GENERIC_ALL, NULL, 1, 2 );
620     ok( status == STATUS_SUCCESS, "NULL: NtCreateSemaphore failed %x\n", status );
621     pNtClose( ret );
622     status = pNtOpenSemaphore( &ret, GENERIC_ALL, NULL );
623     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSemaphore failed %x\n", status );
624     status = pNtCreateEvent( &ret, GENERIC_ALL, NULL, 1, 0 );
625     ok( status == STATUS_SUCCESS, "NULL: NtCreateEvent failed %x\n", status );
626     pNtClose( ret );
627     status = pNtOpenEvent( &ret, GENERIC_ALL, NULL );
628     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenEvent failed %x\n", status );
629     status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, NULL, 0 );
630     ok( status == STATUS_SUCCESS, "NULL: NtCreateKeyedEvent failed %x\n", status );
631     pNtClose( ret );
632     status = pNtOpenKeyedEvent( &ret, GENERIC_ALL, NULL );
633     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenKeyedEvent failed %x\n", status );
634     status = pNtCreateTimer( &ret, GENERIC_ALL, NULL, NotificationTimer );
635     ok( status == STATUS_SUCCESS, "NULL: NtCreateTimer failed %x\n", status );
636     pNtClose( ret );
637     status = pNtOpenTimer( &ret, GENERIC_ALL, NULL );
638     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenTimer failed %x\n", status );
639     status = pNtCreateIoCompletion( &ret, GENERIC_ALL, NULL, 0 );
640     ok( status == STATUS_SUCCESS, "NULL: NtCreateCompletion failed %x\n", status );
641     pNtClose( ret );
642     status = pNtOpenIoCompletion( &ret, GENERIC_ALL, NULL );
643     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenCompletion failed %x\n", status );
644     status = pNtCreateJobObject( &ret, GENERIC_ALL, NULL );
645     ok( status == STATUS_SUCCESS, "NULL: NtCreateJobObject failed %x\n", status );
646     pNtClose( ret );
647     status = pNtOpenJobObject( &ret, GENERIC_ALL, NULL );
648     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenJobObject failed %x\n", status );
649     status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, NULL );
650     ok( status == STATUS_SUCCESS, "NULL: NtCreateDirectoryObject failed %x\n", status );
651     pNtClose( ret );
652     status = pNtOpenDirectoryObject( &ret, GENERIC_ALL, NULL );
653     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenDirectoryObject failed %x\n", status );
654     status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, NULL, &target );
655     ok( status == STATUS_ACCESS_VIOLATION || broken( status == STATUS_SUCCESS), /* winxp */
656         "NULL: NtCreateSymbolicLinkObject failed %x\n", status );
657     if (!status) pNtClose( ret );
658     status = pNtOpenSymbolicLinkObject( &ret, GENERIC_ALL, NULL );
659     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSymbolicLinkObject failed %x\n", status );
660     status = pNtCreateSection( &ret, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
661     ok( status == STATUS_SUCCESS, "NULL: NtCreateSection failed %x\n", status );
662     pNtClose( ret );
663     status = pNtOpenSection( &ret, SECTION_MAP_WRITE, NULL );
664     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSection failed %x\n", status );
665     attr2.ObjectName = attr3.ObjectName = &str;
666 
667     /* named pipes */
668     memcpy( str.Buffer, pipeW, sizeof(pipeW) );
669     for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(pipeW)/sizeof(WCHAR)] = 'a';
670     str.Length = 0;
671     attr.RootDirectory = 0;
672     attr.Attributes = OBJ_CASE_INSENSITIVE;
673     timeout.QuadPart = -10000;
674     status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
675                                      FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
676     ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status );
677     status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
678                                      FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
679     ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status );
680     str.Length = 67;
681     status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
682                                      FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
683     ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status );
684     str.Length = 128;
685     for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
686     {
687         status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
688                                       FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
689         if (attr.Length == sizeof(attr))
690         {
691             ok( status == STATUS_SUCCESS, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status );
692             pNtClose( ret );
693         }
694         else ok( status == STATUS_INVALID_PARAMETER,
695                  "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status );
696     }
697     attr.Length = sizeof(attr);
698     str.Length = 65532;
699     status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
700                                      FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
701     ok( status == STATUS_SUCCESS, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status );
702     pNtClose( ret );
703     str.Length = 65534;
704     status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
705                                      FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
706     ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status );
707     attr3.RootDirectory = 0;
708     attr2.ObjectName = attr3.ObjectName = NULL;
709     status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
710                                      FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
711     ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateNamedPipeFile failed %x\n", status );
712     status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr3, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
713                                      FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
714     ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateNamedPipeFile failed %x\n", status );
715     status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, NULL, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
716                                      FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
717     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateNamedPipeFile failed %x\n", status );
718     attr2.ObjectName = attr3.ObjectName = &str;
719 
720     /* mailslots */
721     memcpy( str.Buffer, mailslotW, sizeof(mailslotW) );
722     for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(mailslotW)/sizeof(WCHAR)] = 'a';
723     str.Length = 0;
724     status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
725     ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateMailslotFile failed %x\n", str.Length, status );
726     status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
727     ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateMailslotFile failed %x\n", str.Length, status );
728     str.Length = 67;
729     status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
730     ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %x\n", str.Length, status );
731     str.Length = 128;
732     for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
733     {
734         status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
735         if (attr.Length == sizeof(attr))
736         {
737             ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %x\n", str.Length, status );
738             pNtClose( ret );
739         }
740         else ok( status == STATUS_INVALID_PARAMETER,
741                  "%u: NtCreateMailslotFile failed %x\n", str.Length, status );
742     }
743     attr.Length = sizeof(attr);
744     str.Length = 65532;
745     status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
746     ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %x\n", str.Length, status );
747     pNtClose( ret );
748     str.Length = 65534;
749     status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
750     ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %x\n", str.Length, status );
751     attr3.RootDirectory = 0;
752     attr2.ObjectName = attr3.ObjectName = NULL;
753     status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
754     ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateMailslotFile failed %x\n", status );
755     status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr3, &iosb, 0, 0, 0, NULL );
756     ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateMailslotFile failed %x\n", status );
757     status = pNtCreateMailslotFile( &ret, GENERIC_ALL, NULL, &iosb, 0, 0, 0, NULL );
758     ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateMailslotFile failed %x\n", status );
759     attr2.ObjectName = attr3.ObjectName = &str;
760 
761     /* registry keys */
762     memcpy( str.Buffer, registryW, sizeof(registryW) );
763     for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(registryW)/sizeof(WCHAR)] = 'a';
764     str.Length = 0;
765     status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
766     todo_wine
767     ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateKey failed %x\n", str.Length, status );
768     status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL );
769     ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateKey failed %x\n", str.Length, status );
770     status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 );
771     ok( status == STATUS_INVALID_HANDLE, "%u: NtOpenKey failed %x\n", str.Length, status );
772     str.Length = sizeof(registryW) + 250 * sizeof(WCHAR) + 1;
773     status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
774     ok( status == STATUS_OBJECT_NAME_INVALID ||
775         status == STATUS_INVALID_PARAMETER ||
776         broken( status == STATUS_SUCCESS ), /* wow64 */
777         "%u: NtCreateKey failed %x\n", str.Length, status );
778     if (!status)
779     {
780         pNtDeleteKey( ret );
781         pNtClose( ret );
782     }
783     str.Length = sizeof(registryW) + 256 * sizeof(WCHAR);
784     status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
785     ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED,
786         "%u: NtCreateKey failed %x\n", str.Length, status );
787     if (!status)
788     {
789         status = pNtOpenKey( &ret2, KEY_READ, &attr );
790         ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %x\n", str.Length, status );
791         pNtClose( ret2 );
792         attr3.RootDirectory = ret;
793         str.Length = 0;
794         status = pNtOpenKey( &ret2, KEY_READ, &attr3 );
795         ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %x\n", str.Length, status );
796         pNtClose( ret2 );
797         pNtDeleteKey( ret );
798         pNtClose( ret );
799 
800         str.Length = sizeof(registryW) + 256 * sizeof(WCHAR);
801         for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
802         {
803             if (attr.Length == sizeof(attr))
804             {
805                 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
806                 ok( status == STATUS_SUCCESS, "%u: NtCreateKey failed %x\n", str.Length, status );
807                 status = pNtOpenKey( &ret2, KEY_READ, &attr );
808                 ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %x\n", str.Length, status );
809                 pNtClose( ret2 );
810                 pNtDeleteKey( ret );
811                 pNtClose( ret );
812             }
813             else
814             {
815                 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
816                 ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %x\n", str.Length, status );
817                 status = pNtOpenKey( &ret2, KEY_READ, &attr );
818                 ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %x\n", str.Length, status );
819             }
820         }
821         attr.Length = sizeof(attr);
822     }
823     str.Length = sizeof(registryW) + 256 * sizeof(WCHAR) + 1;
824     status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
825     ok( status == STATUS_OBJECT_NAME_INVALID ||
826         status == STATUS_INVALID_PARAMETER ||
827         broken( status == STATUS_SUCCESS ), /* win7 */
828         "%u: NtCreateKey failed %x\n", str.Length, status );
829     if (!status)
830     {
831         pNtDeleteKey( ret );
832         pNtClose( ret );
833     }
834     status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
835     ok( status == STATUS_OBJECT_NAME_INVALID ||
836         status == STATUS_INVALID_PARAMETER ||
837         broken( status == STATUS_OBJECT_NAME_NOT_FOUND ), /* wow64 */
838         "%u: NtOpenKey failed %x\n", str.Length, status );
839     str.Length++;
840     status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
841     ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %x\n", str.Length, status );
842     status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
843     todo_wine
844     ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %x\n", str.Length, status );
845     str.Length = 2000;
846     status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
847     ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %x\n", str.Length, status );
848     status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
849     todo_wine
850     ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %x\n", str.Length, status );
851     /* some Windows versions change the error past 2050 chars, others past 4066 chars, some don't */
852     str.Length = 5000;
853     status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
854     ok( status == STATUS_BUFFER_OVERFLOW ||
855         status == STATUS_BUFFER_TOO_SMALL ||
856         status == STATUS_INVALID_PARAMETER,
857         "%u: NtCreateKey failed %x\n", str.Length, status );
858     status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
859     todo_wine
860     ok( status == STATUS_BUFFER_OVERFLOW ||
861         status == STATUS_BUFFER_TOO_SMALL ||
862         status == STATUS_INVALID_PARAMETER,
863          "%u: NtOpenKey failed %x\n", str.Length, status );
864     str.Length = 65534;
865     status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
866     ok( status == STATUS_OBJECT_NAME_INVALID ||
867         status == STATUS_BUFFER_OVERFLOW ||
868         status == STATUS_BUFFER_TOO_SMALL,
869         "%u: NtCreateKey failed %x\n", str.Length, status );
870     status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
871     todo_wine
872     ok( status == STATUS_OBJECT_NAME_INVALID ||
873         status == STATUS_BUFFER_OVERFLOW ||
874         status == STATUS_BUFFER_TOO_SMALL,
875          "%u: NtOpenKey failed %x\n", str.Length, status );
876     attr3.RootDirectory = 0;
877     attr2.ObjectName = attr3.ObjectName = NULL;
878     status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL );
879     todo_wine
880     ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE,
881         "NULL: NtCreateKey failed %x\n", status );
882     status = pNtCreateKey( &ret, GENERIC_ALL, &attr3, 0, NULL, 0, NULL );
883     todo_wine
884     ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %x\n", status );
885     status = pNtCreateKey( &ret, GENERIC_ALL, NULL, 0, NULL, 0, NULL );
886     ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %x\n", status );
887     status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 );
888     ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE,
889         "NULL: NtOpenKey failed %x\n", status );
890     status = pNtOpenKey( &ret, GENERIC_ALL, &attr3 );
891     ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %x\n", status );
892     status = pNtOpenKey( &ret, GENERIC_ALL, NULL );
893     ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %x\n", status );
894     attr2.ObjectName = attr3.ObjectName = &str;
895 
896     pRtlFreeUnicodeString( &str );
897     pRtlFreeUnicodeString( &target );
898 }
899 
900 static void test_directory(void)
901 {
902     NTSTATUS status;
903     UNICODE_STRING str;
904     OBJECT_ATTRIBUTES attr;
905     HANDLE dir, dir1, h, h2;
906     BOOL is_nt4;
907 
908     /* No name and/or no attributes */
909     status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
910     ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
911         "NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
912     status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
913     ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
914         "NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
915 
916     status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL);
917     ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08x)\n", status);
918     pNtClose(h);
919     status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL);
920     ok(status == STATUS_INVALID_PARAMETER,
921         "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
922 
923     InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
924     status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
925     ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status );
926     status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
927     ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08x\n", status );
928 
929     /* Bad name */
930     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
931 
932     pRtlCreateUnicodeStringFromAsciiz(&str, "");
933     status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
934     ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status );
935     pNtClose(h);
936     status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
937     ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08x\n", status );
938     pRtlFreeUnicodeString(&str);
939     pNtClose(dir);
940 
941     DIR_TEST_CREATE_OPEN( "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD );
942     DIR_TEST_CREATE_OPEN( "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID );
943     DIR_TEST_CREATE_OPEN( "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID );
944     DIR_TEST_CREATE_OPEN( "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID );
945     DIR_TEST_CREATE_OPEN( "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND );
946 
947     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
948     status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
949     ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status );
950     status = pNtOpenDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
951     ok( status == STATUS_SUCCESS, "Failed to open directory %08x\n", status );
952     pRtlFreeUnicodeString(&str);
953     pNtClose(h);
954     pNtClose(dir1);
955 
956 
957     /* Use of root directory */
958 
959     /* Can't use symlinks as a directory */
960     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local");
961     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
962     status = pNtOpenSymbolicLinkObject(&dir, SYMBOLIC_LINK_QUERY, &attr);
963     is_nt4 = (status == STATUS_OBJECT_NAME_NOT_FOUND);  /* nt4 doesn't have Local\\ symlink */
964     if (!is_nt4)
965     {
966         WCHAR buffer[256];
967         ULONG len, full_len;
968 
969         ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08x)\n", status);
970         pRtlFreeUnicodeString(&str);
971         InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
972         pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
973         status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
974         ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtCreateDirectoryObject got %08x\n", status );
975         pRtlFreeUnicodeString(&str);
976 
977         pRtlCreateUnicodeStringFromAsciiz( &str, "\\BaseNamedObjects\\Local\\om.c-test" );
978         InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
979         status = pNtCreateDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
980         ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status );
981         pRtlFreeUnicodeString( &str );
982         pRtlCreateUnicodeStringFromAsciiz( &str, "om.c-test" );
983         InitializeObjectAttributes( &attr, &str, 0, dir, NULL );
984         status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
985         ok( status == STATUS_OBJECT_TYPE_MISMATCH, "Failed to open directory %08x\n", status );
986         if (!status) pNtClose(h);
987         pRtlFreeUnicodeString( &str );
988 
989         pRtlCreateUnicodeStringFromAsciiz( &str, "om.c-event" );
990         InitializeObjectAttributes( &attr, &str, 0, dir1, NULL );
991         status = pNtCreateEvent( &h, GENERIC_ALL, &attr, 1, 0 );
992         ok( status == STATUS_SUCCESS, "NtCreateEvent failed %x\n", status );
993         status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
994         ok( status == STATUS_SUCCESS, "NtOpenEvent failed %x\n", status );
995         pNtClose( h2 );
996         pRtlFreeUnicodeString( &str );
997         pRtlCreateUnicodeStringFromAsciiz( &str, "om.c-test\\om.c-event" );
998         InitializeObjectAttributes( &attr, &str, 0, dir, NULL );
999         status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
1000         ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtOpenEvent failed %x\n", status );
1001         pRtlFreeUnicodeString( &str );
1002         pRtlCreateUnicodeStringFromAsciiz( &str, "\\BasedNamedObjects\\Local\\om.c-test\\om.c-event" );
1003         InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
1004         status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
1005         ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtOpenEvent failed %x\n", status );
1006         pRtlFreeUnicodeString( &str );
1007         pNtClose( h );
1008         pNtClose( dir1 );
1009 
1010         str.Buffer = buffer;
1011         str.MaximumLength = sizeof(buffer);
1012         len = 0xdeadbeef;
1013         memset( buffer, 0xaa, sizeof(buffer) );
1014         status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1015         ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08x\n", status );
1016         if (status != STATUS_SUCCESS)
1017             goto error;
1018         full_len = str.Length + sizeof(WCHAR);
1019         ok( len == full_len, "bad length %u/%u\n", len, full_len );
1020         if (len == full_len)
1021             ok( buffer[len / sizeof(WCHAR) - 1] == 0, "no terminating null\n" );
1022 
1023         str.MaximumLength = str.Length;
1024         len = 0xdeadbeef;
1025         status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1026         ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08x\n", status );
1027         ok( len == full_len, "bad length %u/%u\n", len, full_len );
1028 
1029         str.MaximumLength = 0;
1030         len = 0xdeadbeef;
1031         status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1032         ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08x\n", status );
1033         ok( len == full_len, "bad length %u/%u\n", len, full_len );
1034 
1035         str.MaximumLength = str.Length + sizeof(WCHAR);
1036         len = 0xdeadbeef;
1037         status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1038         ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08x\n", status );
1039         ok( len == full_len, "bad length %u/%u\n", len, full_len );
1040 
1041 error:
1042         pNtClose(dir);
1043     }
1044 
1045     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
1046     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1047     status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1048     ok( status == STATUS_SUCCESS, "Failed to open directory %08x\n", status );
1049     pRtlFreeUnicodeString(&str);
1050 
1051     InitializeObjectAttributes(&attr, NULL, 0, dir, NULL);
1052     status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1053     ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenDirectoryObject got %08x\n", status );
1054 
1055     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1056     DIR_TEST_CREATE_OPEN( "", STATUS_SUCCESS );
1057     DIR_TEST_CREATE_OPEN( "\\", STATUS_OBJECT_PATH_SYNTAX_BAD );
1058     DIR_TEST_CREATE_OPEN( "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD );
1059     DIR_TEST_CREATE_OPEN( "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD );
1060     DIR_TEST_CREATE_OPEN( "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND );
1061 
1062     pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
1063     status = pNtCreateDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
1064     ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status );
1065     status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1066     ok( status == STATUS_SUCCESS, "Failed to open directory %08x\n", status );
1067     pRtlFreeUnicodeString(&str);
1068 
1069     pNtClose(h);
1070     pNtClose(dir1);
1071     pNtClose(dir);
1072 
1073     /* Nested directories */
1074     pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
1075     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1076     status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1077     ok( status == STATUS_SUCCESS, "Failed to open directory %08x\n", status );
1078     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1079     status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1080     ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08x\n", status );
1081     pRtlFreeUnicodeString(&str);
1082     pNtClose(dir);
1083 
1084     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1085     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
1086     status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1087     ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status );
1088     pRtlFreeUnicodeString(&str);
1089     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test\\one more level");
1090     status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1091     ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status );
1092     pRtlFreeUnicodeString(&str);
1093     pNtClose(h);
1094     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1095     pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
1096     status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1097     ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status );
1098     pRtlFreeUnicodeString(&str);
1099     pNtClose(h);
1100 
1101     pNtClose(dir);
1102 
1103     if (!is_nt4)
1104     {
1105         InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1106         pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Global\\om.c-test");
1107         status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1108         ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status );
1109         pRtlFreeUnicodeString(&str);
1110         pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local\\om.c-test\\one more level");
1111         status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1112         ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status );
1113         pRtlFreeUnicodeString(&str);
1114         pNtClose(h);
1115         InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1116         pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
1117         status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1118         ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status );
1119         pRtlFreeUnicodeString(&str);
1120         pNtClose(h);
1121         pNtClose(dir);
1122     }
1123 
1124     /* Create other objects using RootDirectory */
1125 
1126     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1127     pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
1128     status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1129     ok( status == STATUS_SUCCESS, "Failed to open directory %08x\n", status );
1130     pRtlFreeUnicodeString(&str);
1131     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1132 
1133     /* Test invalid paths */
1134     pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant");
1135     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1136     ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1137         "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
1138     pRtlFreeUnicodeString(&str);
1139     pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant\\");
1140     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1141     ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1142         "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
1143     pRtlFreeUnicodeString(&str);
1144 
1145     pRtlCreateUnicodeStringFromAsciiz(&str, "om.c\\-mutant");
1146     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1147     ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
1148         "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
1149     pRtlFreeUnicodeString(&str);
1150 
1151     pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-mutant");
1152     status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1153     ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
1154     pRtlFreeUnicodeString(&str);
1155     pNtClose(h);
1156 
1157     pNtClose(dir);
1158 }
1159 
1160 static void test_symboliclink(void)
1161 {
1162     NTSTATUS status;
1163     UNICODE_STRING str, target;
1164     OBJECT_ATTRIBUTES attr;
1165     HANDLE dir, link, h;
1166     IO_STATUS_BLOCK iosb;
1167 
1168     /* No name and/or no attributes */
1169     InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
1170     pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
1171     status = pNtCreateSymbolicLinkObject( NULL, SYMBOLIC_LINK_QUERY, &attr, &target );
1172     ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
1173        "NtCreateSymbolicLinkObject got %08x\n", status );
1174     status = pNtOpenSymbolicLinkObject( NULL, SYMBOLIC_LINK_QUERY, &attr );
1175     ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
1176        "NtOpenSymbolicLinkObject got %08x\n", status );
1177 
1178     status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL);
1179     ok(status == STATUS_ACCESS_VIOLATION,
1180         "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
1181     status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL);
1182     ok(status == STATUS_INVALID_PARAMETER,
1183         "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
1184 
1185     /* No attributes */
1186     status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, &target);
1187     ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_VIOLATION, /* nt4 */
1188        "NtCreateSymbolicLinkObject failed(%08x)\n", status);
1189     pRtlFreeUnicodeString(&target);
1190     if (!status) pNtClose(h);
1191 
1192     InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
1193     status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1194     ok(status == STATUS_INVALID_PARAMETER ||
1195        broken(status == STATUS_SUCCESS),  /* nt4 */
1196        "NtCreateSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
1197     if (!status) pNtClose(h);
1198     status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
1199     ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1200        "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
1201 
1202     /* Bad name */
1203     pRtlCreateUnicodeStringFromAsciiz(&target, "anywhere");
1204     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1205 
1206     pRtlCreateUnicodeStringFromAsciiz(&str, "");
1207     status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1208     ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status);
1209     status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
1210     ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1211        "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
1212     pNtClose(link);
1213     pRtlFreeUnicodeString(&str);
1214 
1215     pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
1216     status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target);
1217     todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH,
1218                  "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
1219     pRtlFreeUnicodeString(&str);
1220     pRtlFreeUnicodeString(&target);
1221 
1222     pRtlCreateUnicodeStringFromAsciiz( &target, "->Somewhere");
1223 
1224     pRtlCreateUnicodeStringFromAsciiz( &str, "BaseNamedObjects" );
1225     status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1226     ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtCreateSymbolicLinkObject got %08x\n", status );
1227     status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1228     ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenSymbolicLinkObject got %08x\n", status );
1229     pRtlFreeUnicodeString( &str );
1230 
1231     pRtlCreateUnicodeStringFromAsciiz( &str, "\\BaseNamedObjects\\" );
1232     status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1233     ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08x\n", status );
1234     status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1235     ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08x\n", status );
1236     pRtlFreeUnicodeString( &str );
1237 
1238     pRtlCreateUnicodeStringFromAsciiz( &str, "\\\\BaseNamedObjects" );
1239     status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1240     ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08x\n", status );
1241     status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1242     ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08x\n", status );
1243     pRtlFreeUnicodeString( &str );
1244 
1245     pRtlCreateUnicodeStringFromAsciiz( &str, "\\BaseNamedObjects\\\\om.c-test" );
1246     status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1247     ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08x\n", status );
1248     status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1249     ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08x\n", status );
1250     pRtlFreeUnicodeString( &str );
1251 
1252     pRtlCreateUnicodeStringFromAsciiz( &str, "\\BaseNamedObjects\\om.c-test\\" );
1253     status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1254     ok( status == STATUS_OBJECT_NAME_INVALID || status == STATUS_OBJECT_PATH_NOT_FOUND,
1255         "NtCreateSymbolicLinkObject got %08x\n", status );
1256     status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1257     ok( status == STATUS_OBJECT_NAME_INVALID || status == STATUS_OBJECT_PATH_NOT_FOUND,
1258         "NtOpenSymbolicLinkObject got %08x\n", status );
1259     pRtlFreeUnicodeString( &str );
1260     pRtlFreeUnicodeString(&target);
1261 
1262     /* Compound test */
1263     if (!(dir = get_base_dir()))
1264     {
1265         win_skip( "couldn't find the BaseNamedObjects dir\n" );
1266         return;
1267     }
1268 
1269     InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1270     pRtlCreateUnicodeStringFromAsciiz(&str, "test-link");
1271     pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
1272     status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1273     ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status);
1274     pRtlFreeUnicodeString(&str);
1275     pRtlFreeUnicodeString(&target);
1276 
1277     pRtlCreateUnicodeStringFromAsciiz(&str, "test-link\\NUL");
1278     status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
1279     ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08x)\n", status);
1280     status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE);
1281     ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08x)\n", status);
1282     pRtlFreeUnicodeString(&str);
1283 
1284     pNtClose(h);
1285     pNtClose(link);
1286     pNtClose(dir);
1287 }
1288 
1289 static void test_query_object(void)
1290 {
1291     static const WCHAR name[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',
1292                                  '\\','t','e','s','t','_','e','v','e','n','t'};
1293     static const WCHAR type_event[] = {'E','v','e','n','t'};
1294     static const WCHAR type_file[] = {'F','i','l','e'};
1295     static const WCHAR type_iocompletion[] = {'I','o','C','o','m','p','l','e','t','i','o','n'};
1296     static const WCHAR type_directory[] = {'D','i','r','e','c','t','o','r','y'};
1297     static const WCHAR type_section[] = {'S','e','c','t','i','o','n'};
1298     HANDLE handle;
1299     char buffer[1024];
1300     NTSTATUS status;
1301     ULONG len, expected_len;
1302     OBJECT_ATTRIBUTES attr;
1303     UNICODE_STRING path, session, *str;
1304     char dir[MAX_PATH], tmp_path[MAX_PATH], file1[MAX_PATH + 16];
1305     LARGE_INTEGER size;
1306 
1307     sprintf( tmp_path, "\\Sessions\\%u", NtCurrentTeb()->Peb->SessionId );
1308     pRtlCreateUnicodeStringFromAsciiz( &session, tmp_path );
1309     InitializeObjectAttributes( &attr, &path, 0, 0, 0 );
1310 
1311     handle = CreateEventA( NULL, FALSE, FALSE, "test_event" );
1312 
1313     len = 0;
1314     status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
1315     ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
1316     ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
1317 
1318     len = 0;
1319     status = pNtQueryObject( handle, ObjectTypeInformation, buffer, 0, &len );
1320     ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
1321     ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
1322 
1323     len = 0;
1324     status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
1325     ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
1326     ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
1327 
1328     len = 0;
1329     status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(OBJECT_TYPE_INFORMATION), &len );
1330     ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
1331     ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
1332 
1333     len = 0;
1334     status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1335     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
1336     ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
1337     str = (UNICODE_STRING *)buffer;
1338     ok( sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR) == len, "unexpected len %u\n", len );
1339     ok( str->Length >= sizeof(name), "unexpected len %u\n", str->Length );
1340     ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_event") * sizeof(WCHAR),
1341         "name too short %s\n", wine_dbgstr_w(str->Buffer) );
1342     /* check for \\Sessions prefix in the name */
1343     ok( (str->Length > session.Length &&
1344          !memcmp( str->Buffer, session.Buffer, session.Length ) &&
1345          !memcmp( str->Buffer + session.Length / sizeof(WCHAR), name, sizeof(name) )) ||
1346         broken( !memcmp( str->Buffer, name, sizeof(name) )), /* winxp */
1347         "wrong name %s\n", wine_dbgstr_w(str->Buffer) );
1348     trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len );
1349 
1350     len -= sizeof(WCHAR);
1351     status = pNtQueryObject( handle, ObjectNameInformation, buffer, len, &len );
1352     ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
1353     ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
1354 
1355     len = 0;
1356     memset( buffer, 0, sizeof(buffer) );
1357     status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
1358     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
1359     ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
1360     str = (UNICODE_STRING *)buffer;
1361     ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR), "unexpected len %u\n", len );
1362     ok( str->Buffer && !memcmp( str->Buffer, type_event, sizeof(type_event) ),
1363                   "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
1364 
1365     len -= sizeof(WCHAR);
1366     status = pNtQueryObject( handle, ObjectTypeInformation, buffer, len, &len );
1367     ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
1368     ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
1369 
1370     pNtClose( handle );
1371 
1372     handle = CreateEventA( NULL, FALSE, FALSE, NULL );
1373     len = 0;
1374     status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1375     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
1376     ok( len == sizeof(UNICODE_STRING), "unexpected len %u\n", len );
1377     str = (UNICODE_STRING *)buffer;
1378     ok( str->Length == 0, "unexpected len %u\n", len );
1379     ok( str->Buffer == NULL, "unexpected ptr %p\n", str->Buffer );
1380     pNtClose( handle );
1381 
1382     GetWindowsDirectoryA( dir, MAX_PATH );
1383     handle = CreateFileA( dir, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1384                           FILE_FLAG_BACKUP_SEMANTICS, 0 );
1385     len = 0;
1386     status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1387     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
1388     ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
1389     str = (UNICODE_STRING *)buffer;
1390     expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR);
1391     ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */
1392         "unexpected len %u\n", len );
1393     trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len );
1394 
1395     len = 0;
1396     status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
1397     ok( status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INSUFFICIENT_RESOURCES),
1398         "NtQueryObject failed %x\n", status );
1399     ok( len == expected_len || broken(!len || len == sizeof(UNICODE_STRING)),
1400         "unexpected len %u\n", len );
1401 
1402     len = 0;
1403     status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
1404     ok( status == STATUS_BUFFER_OVERFLOW || broken(status == STATUS_INSUFFICIENT_RESOURCES
1405             || status == STATUS_INFO_LENGTH_MISMATCH),
1406         "NtQueryObject failed %x\n", status );
1407     ok( len == expected_len || broken(!len),
1408         "unexpected len %u\n", len );
1409 
1410     len = 0;
1411     memset( buffer, 0, sizeof(buffer) );
1412     status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
1413     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
1414     ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
1415     str = (UNICODE_STRING *)buffer;
1416     expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
1417     ok( len >= expected_len, "unexpected len %u\n", len );
1418     ok( str->Buffer && !memcmp( str->Buffer, type_file, sizeof(type_file) ),
1419                   "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
1420 
1421     pNtClose( handle );
1422 
1423     GetTempPathA(MAX_PATH, tmp_path);
1424     GetTempFileNameA(tmp_path, "foo", 0, file1);
1425     handle = CreateFileA(file1, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0);
1426     len = 0;
1427     memset( buffer, 0, sizeof(buffer) );
1428     status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
1429     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
1430     ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
1431     str = (UNICODE_STRING *)buffer;
1432     expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
1433     ok( len >= expected_len, "unexpected len %u\n", len );
1434     ok( str->Buffer && !memcmp( str->Buffer, type_file, sizeof(type_file) ),
1435                   "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
1436     DeleteFileA( file1 );
1437     pNtClose( handle );
1438 
1439     status = pNtCreateIoCompletion( &handle, IO_COMPLETION_ALL_ACCESS, NULL, 0 );
1440     ok( status == STATUS_SUCCESS, "NtCreateIoCompletion failed %x\n", status);
1441     len = 0;
1442     memset( buffer, 0, sizeof(buffer) );
1443     status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
1444     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
1445     ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
1446     str = (UNICODE_STRING *)buffer;
1447     expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
1448     ok( len >= expected_len, "unexpected len %u\n", len );
1449     ok( str->Buffer && !memcmp( str->Buffer, type_iocompletion, sizeof(type_iocompletion) ),
1450                   "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
1451     pNtClose( handle );
1452 
1453     status = pNtCreateDirectoryObject( &handle, DIRECTORY_QUERY, NULL );
1454     ok(status == STATUS_SUCCESS, "Failed to create Directory %08x\n", status);
1455     len = 0;
1456     memset( buffer, 0, sizeof(buffer) );
1457     status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
1458     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
1459     ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
1460     str = (UNICODE_STRING *)buffer;
1461     expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
1462     ok( len >= expected_len, "unexpected len %u\n", len );
1463     ok( str->Buffer && !memcmp( str->Buffer, type_directory, sizeof(type_directory) ),
1464                   "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
1465     pNtClose( handle );
1466 
1467     size.u.LowPart = 256;
1468     size.u.HighPart = 0;
1469     status = pNtCreateSection( &handle, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
1470     ok( status == STATUS_SUCCESS , "NtCreateSection returned %x\n", status );
1471     len = 0;
1472     memset( buffer, 0, sizeof(buffer) );
1473     status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
1474     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
1475     ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
1476     str = (UNICODE_STRING *)buffer;
1477     expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
1478     ok( len >= expected_len, "unexpected len %u\n", len );
1479     ok( str->Buffer && !memcmp( str->Buffer, type_section, sizeof(type_section) ),
1480                   "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
1481     pNtClose( handle );
1482 
1483     handle = CreateMailslotA( "\\\\.\\mailslot\\test_mailslot", 100, 1000, NULL );
1484     ok( handle != INVALID_HANDLE_VALUE, "CreateMailslot failed err %u\n", GetLastError() );
1485     len = 0;
1486     status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1487     ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status );
1488     str = (UNICODE_STRING *)buffer;
1489     ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
1490     str = (UNICODE_STRING *)buffer;
1491     expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR);
1492     ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */
1493         "unexpected len %u\n", len );
1494     ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_mailslot") * sizeof(WCHAR),
1495         "name too short %s\n", wine_dbgstr_w(str->Buffer) );
1496     trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len );
1497     pNtClose( handle );
1498 
1499     handle = CreateNamedPipeA( "\\\\.\\pipe\\test_pipe", PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE,
1500                                1, 1000, 1000, 1000, NULL );
1501     ok( handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed err %u\n", GetLastError() );
1502     len = 0;
1503     status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1504     ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status );
1505     str = (UNICODE_STRING *)buffer;
1506     ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
1507     str = (UNICODE_STRING *)buffer;
1508     expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR);
1509     ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */
1510         "unexpected len %u\n", len );
1511     ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_pipe") * sizeof(WCHAR),
1512         "name too short %s\n", wine_dbgstr_w(str->Buffer) );
1513     trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len );
1514     pNtClose( handle );
1515 
1516     pRtlCreateUnicodeStringFromAsciiz( &path, "\\REGISTRY\\Machine\\Software\\Classes" );
1517     status = pNtCreateKey( &handle, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
1518     ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED,
1519         "NtCreateKey failed status %x\n", status );
1520     pRtlFreeUnicodeString( &path );
1521     if (status == STATUS_SUCCESS)
1522     {
1523         len = 0;
1524         status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1525         ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status );
1526         str = (UNICODE_STRING *)buffer;
1527         todo_wine
1528         ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
1529         str = (UNICODE_STRING *)buffer;
1530         expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR);
1531         todo_wine
1532         ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */
1533             "unexpected len %u\n", len );
1534         todo_wine
1535         ok( len > sizeof(UNICODE_STRING) + sizeof("\\Classes") * sizeof(WCHAR),
1536             "name too short %s\n", wine_dbgstr_w(str->Buffer) );
1537         trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len );
1538         pNtClose( handle );
1539     }
1540     pRtlFreeUnicodeString( &session );
1541 }
1542 
1543 static BOOL winver_equal_or_newer(WORD major, WORD minor)
1544 {
1545     OSVERSIONINFOEXW info = {sizeof(info)};
1546     ULONGLONG mask = 0;
1547 
1548     info.dwMajorVersion = major;
1549     info.dwMinorVersion = minor;
1550 
1551     VER_SET_CONDITION(mask, VER_MAJORVERSION, VER_GREATER_EQUAL);
1552     VER_SET_CONDITION(mask, VER_MINORVERSION, VER_GREATER_EQUAL);
1553 
1554     return VerifyVersionInfoW(&info, VER_MAJORVERSION | VER_MINORVERSION, mask);
1555 }
1556 
1557 static void test_query_object_types(void)
1558 {
1559     static const WCHAR typeW[] = {'T','y','p','e'};
1560     static const WCHAR eventW[] = {'E','v','e','n','t'};
1561     SYSTEM_HANDLE_INFORMATION_EX *shi;
1562     OBJECT_TYPES_INFORMATION *buffer;
1563     OBJECT_TYPE_INFORMATION *type;
1564     NTSTATUS status;
1565     HANDLE handle;
1566     BOOL found;
1567     ULONG len, i, event_type_index = 0;
1568 
1569     buffer = HeapAlloc( GetProcessHeap(), 0, sizeof(OBJECT_TYPES_INFORMATION) );
1570     ok( buffer != NULL, "Failed to allocate memory\n" );
1571 
1572     status = pNtQueryObject( NULL, ObjectTypesInformation, buffer, sizeof(OBJECT_TYPES_INFORMATION), &len );
1573     ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
1574     ok( len, "len is zero\n");
1575 
1576     buffer = HeapReAlloc( GetProcessHeap(), 0, buffer, len );
1577     ok( buffer != NULL, "Failed to allocate memory\n" );
1578 
1579     memset( buffer, 0, len );
1580     status = pNtQueryObject( NULL, ObjectTypesInformation, buffer, len, &len );
1581     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
1582     ok( buffer->NumberOfTypes, "NumberOfTypes is zero\n" );
1583 
1584     type = (OBJECT_TYPE_INFORMATION *)(buffer + 1);
1585     for (i = 0; i < buffer->NumberOfTypes; i++)
1586     {
1587         USHORT length = type->TypeName.MaximumLength;
1588         trace( "Type %u: %s\n", i, wine_dbgstr_us(&type->TypeName) );
1589 
1590         if (i == 0)
1591         {
1592             ok( type->TypeName.Length == sizeof(typeW) && !strncmpW(typeW, type->TypeName.Buffer, 4),
1593                 "Expected 'Type' as first type, got %s\n", wine_dbgstr_us(&type->TypeName) );
1594         }
1595         if (type->TypeName.Length == sizeof(eventW) && !strncmpW(eventW, type->TypeName.Buffer, 5))
1596         {
1597             if (winver_equal_or_newer( 6, 2 ))
1598                 event_type_index = type->TypeIndex;
1599             else
1600                 event_type_index = winver_equal_or_newer( 6, 1 ) ? i + 2 : i + 1;
1601         }
1602 
1603         type = (OBJECT_TYPE_INFORMATION *)ROUND_UP( (DWORD_PTR)(type + 1) + length, sizeof(DWORD_PTR) );
1604     }
1605 
1606     HeapFree( GetProcessHeap(), 0, buffer );
1607 
1608     ok( event_type_index, "Could not find object type for events\n" );
1609 
1610     handle = CreateEventA( NULL, FALSE, FALSE, NULL );
1611     ok( handle != NULL, "Failed to create event\n" );
1612 
1613     shi = HeapAlloc( GetProcessHeap(), 0, sizeof(*shi) );
1614     ok( shi != NULL, "Failed to allocate memory\n" );
1615 
1616     status = pNtQuerySystemInformation( SystemExtendedHandleInformation, shi, sizeof(*shi), &len );
1617     ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status );
1618 
1619     shi = HeapReAlloc( GetProcessHeap(), 0, shi, len );
1620     ok( shi != NULL, "Failed to allocate memory\n" );
1621 
1622     status = pNtQuerySystemInformation( SystemExtendedHandleInformation, shi, len, &len );
1623     ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status );
1624 
1625     found = FALSE;
1626     for (i = 0; i < shi->Count; i++)
1627     {
1628         if (shi->Handle[i].UniqueProcessId != GetCurrentProcessId())
1629             continue;
1630         if ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue != handle)
1631             continue;
1632 
1633         ok( shi->Handle[i].ObjectTypeIndex == event_type_index, "Event type does not match: %u vs %u\n",
1634             shi->Handle[i].ObjectTypeIndex, event_type_index );
1635 
1636         found = TRUE;
1637         break;
1638     }
1639     ok( found, "Expected to find event handle %p (pid %x) in handle list\n", handle, GetCurrentProcessId() );
1640 
1641     HeapFree( GetProcessHeap(), 0, shi );
1642     CloseHandle( handle );
1643 }
1644 
1645 static void test_type_mismatch(void)
1646 {
1647     HANDLE h;
1648     NTSTATUS res;
1649     OBJECT_ATTRIBUTES attr;
1650 
1651     attr.Length                   = sizeof(attr);
1652     attr.RootDirectory            = 0;
1653     attr.ObjectName               = NULL;
1654     attr.Attributes               = 0;
1655     attr.SecurityDescriptor       = NULL;
1656     attr.SecurityQualityOfService = NULL;
1657 
1658     res = pNtCreateEvent( &h, 0, &attr, 0, 0 );
1659     ok(!res, "can't create event: %x\n", res);
1660 
1661     res = pNtReleaseSemaphore( h, 30, NULL );
1662     ok(res == STATUS_OBJECT_TYPE_MISMATCH, "expected 0xc0000024, got %x\n", res);
1663 
1664     pNtClose( h );
1665 }
1666 
1667 static void test_event(void)
1668 {
1669     HANDLE Event;
1670     HANDLE Event2;
1671     NTSTATUS status;
1672     UNICODE_STRING str;
1673     OBJECT_ATTRIBUTES attr;
1674     EVENT_BASIC_INFORMATION info;
1675     static const WCHAR eventName[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','t','e','s','t','E','v','e','n','t',0};
1676 
1677     pRtlInitUnicodeString(&str, eventName);
1678     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1679 
1680     status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, 1, 0);
1681     ok( status == STATUS_SUCCESS, "NtCreateEvent failed %08x\n", status );
1682 
1683     status = pNtPulseEvent(Event, NULL);
1684     ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
1685 
1686     status = pNtQueryEvent(Event, EventBasicInformation, &info, sizeof(info), NULL);
1687     ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
1688     ok( info.EventType == 1 && info.EventState == 0,
1689         "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
1690 
1691     status = pNtOpenEvent(&Event2, GENERIC_ALL, &attr);
1692     ok( status == STATUS_SUCCESS, "NtOpenEvent failed %08x\n", status );
1693 
1694     pNtClose(Event);
1695 
1696     status = pNtQueryEvent(Event2, EventBasicInformation, &info, sizeof(info), NULL);
1697     ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
1698     ok( info.EventType == 1 && info.EventState == 0,
1699         "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
1700 
1701     pNtClose(Event2);
1702 }
1703 
1704 static const WCHAR keyed_nameW[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',
1705                                     '\\','W','i','n','e','T','e','s','t','E','v','e','n','t',0};
1706 
1707 static DWORD WINAPI keyed_event_thread( void *arg )
1708 {
1709     HANDLE handle;
1710     NTSTATUS status;
1711     LARGE_INTEGER timeout;
1712     OBJECT_ATTRIBUTES attr;
1713     UNICODE_STRING str;
1714     ULONG_PTR i;
1715 
1716     attr.Length                   = sizeof(attr);
1717     attr.RootDirectory            = 0;
1718     attr.ObjectName               = &str;
1719     attr.Attributes               = 0;
1720     attr.SecurityDescriptor       = NULL;
1721     attr.SecurityQualityOfService = NULL;
1722     RtlInitUnicodeString( &str, keyed_nameW );
1723 
1724     status = pNtOpenKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr );
1725     ok( !status, "NtOpenKeyedEvent failed %x\n", status );
1726 
1727     for (i = 0; i < 20; i++)
1728     {
1729         if (i & 1)
1730             status = pNtWaitForKeyedEvent( handle, (void *)(i * 2), 0, NULL );
1731         else
1732             status = pNtReleaseKeyedEvent( handle, (void *)(i * 2), 0, NULL );
1733         ok( status == STATUS_SUCCESS, "%li: failed %x\n", i, status );
1734         Sleep( 20 - i );
1735     }
1736 
1737     status = pNtReleaseKeyedEvent( handle, (void *)0x1234, 0, NULL );
1738     ok( status == STATUS_SUCCESS, "NtReleaseKeyedEvent %x\n", status );
1739 
1740     timeout.QuadPart = -10000;
1741     status = pNtWaitForKeyedEvent( handle, (void *)0x5678, 0, &timeout );
1742     ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1743     status = pNtReleaseKeyedEvent( handle, (void *)0x9abc, 0, &timeout );
1744     ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1745 
1746     NtClose( handle );
1747     return 0;
1748 }
1749 
1750 static void test_keyed_events(void)
1751 {
1752     OBJECT_ATTRIBUTES attr;
1753     UNICODE_STRING str;
1754     HANDLE handle, event, thread;
1755     NTSTATUS status;
1756     LARGE_INTEGER timeout;
1757     ULONG_PTR i;
1758 
1759     if (!pNtCreateKeyedEvent)
1760     {
1761         win_skip( "Keyed events not supported\n" );
1762         return;
1763     }
1764 
1765     attr.Length                   = sizeof(attr);
1766     attr.RootDirectory            = 0;
1767     attr.ObjectName               = &str;
1768     attr.Attributes               = 0;
1769     attr.SecurityDescriptor       = NULL;
1770     attr.SecurityQualityOfService = NULL;
1771     RtlInitUnicodeString( &str, keyed_nameW );
1772 
1773     status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS | SYNCHRONIZE, &attr, 0 );
1774     ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1775 
1776     status = WaitForSingleObject( handle, 1000 );
1777     ok( status == 0, "WaitForSingleObject %x\n", status );
1778 
1779     timeout.QuadPart = -100000;
1780     status = pNtWaitForKeyedEvent( handle, (void *)255, 0, &timeout );
1781     ok( status == STATUS_INVALID_PARAMETER_1, "NtWaitForKeyedEvent %x\n", status );
1782     status = pNtReleaseKeyedEvent( handle, (void *)255, 0, &timeout );
1783     ok( status == STATUS_INVALID_PARAMETER_1, "NtReleaseKeyedEvent %x\n", status );
1784 
1785     status = pNtWaitForKeyedEvent( handle, (void *)254, 0, &timeout );
1786     ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1787     status = pNtReleaseKeyedEvent( handle, (void *)254, 0, &timeout );
1788     ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1789 
1790     status = pNtWaitForKeyedEvent( handle, NULL, 0, &timeout );
1791     ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1792     status = pNtReleaseKeyedEvent( handle, NULL, 0, &timeout );
1793     ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1794 
1795     status = pNtWaitForKeyedEvent( (HANDLE)0xdeadbeef, (void *)9, 0, &timeout );
1796     ok( status == STATUS_INVALID_PARAMETER_1, "NtWaitForKeyedEvent %x\n", status );
1797     status = pNtReleaseKeyedEvent( (HANDLE)0xdeadbeef, (void *)9, 0, &timeout );
1798     ok( status == STATUS_INVALID_PARAMETER_1, "NtReleaseKeyedEvent %x\n", status );
1799 
1800     status = pNtWaitForKeyedEvent( (HANDLE)0xdeadbeef, (void *)8, 0, &timeout );
1801     ok( status == STATUS_INVALID_HANDLE, "NtWaitForKeyedEvent %x\n", status );
1802     status = pNtReleaseKeyedEvent( (HANDLE)0xdeadbeef, (void *)8, 0, &timeout );
1803     ok( status == STATUS_INVALID_HANDLE, "NtReleaseKeyedEvent %x\n", status );
1804 
1805     thread = CreateThread( NULL, 0, keyed_event_thread, 0, 0, NULL );
1806     for (i = 0; i < 20; i++)
1807     {
1808         if (i & 1)
1809             status = pNtReleaseKeyedEvent( handle, (void *)(i * 2), 0, NULL );
1810         else
1811             status = pNtWaitForKeyedEvent( handle, (void *)(i * 2), 0, NULL );
1812         ok( status == STATUS_SUCCESS, "%li: failed %x\n", i, status );
1813         Sleep( i );
1814     }
1815     status = pNtWaitForKeyedEvent( handle, (void *)0x1234, 0, &timeout );
1816     ok( status == STATUS_SUCCESS, "NtWaitForKeyedEvent %x\n", status );
1817     status = pNtWaitForKeyedEvent( handle, (void *)0x5678, 0, &timeout );
1818     ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1819     status = pNtReleaseKeyedEvent( handle, (void *)0x9abc, 0, &timeout );
1820     ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1821 
1822     ok( WaitForSingleObject( thread, 30000 ) == 0, "wait failed\n" );
1823 
1824     NtClose( handle );
1825 
1826     /* test access rights */
1827 
1828     status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_WAIT, &attr, 0 );
1829     ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1830     status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1831     ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1832     status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1833     ok( status == STATUS_ACCESS_DENIED, "NtReleaseKeyedEvent %x\n", status );
1834     NtClose( handle );
1835 
1836     status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_WAKE, &attr, 0 );
1837     ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1838     status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1839     ok( status == STATUS_ACCESS_DENIED, "NtWaitForKeyedEvent %x\n", status );
1840     status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1841     ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1842     NtClose( handle );
1843 
1844     status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr, 0 );
1845     ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1846     status = WaitForSingleObject( handle, 1000 );
1847     ok( status == WAIT_FAILED && GetLastError() == ERROR_ACCESS_DENIED,
1848         "WaitForSingleObject %x err %u\n", status, GetLastError() );
1849     status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1850     ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1851     status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1852     ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1853     NtClose( handle );
1854 
1855     /* GENERIC_READ gives wait access */
1856     status = pNtCreateKeyedEvent( &handle, GENERIC_READ, &attr, 0 );
1857     ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1858     status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1859     ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1860     status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1861     ok( status == STATUS_ACCESS_DENIED, "NtReleaseKeyedEvent %x\n", status );
1862     NtClose( handle );
1863 
1864     /* GENERIC_WRITE gives wake access */
1865     status = pNtCreateKeyedEvent( &handle, GENERIC_WRITE, &attr, 0 );
1866     ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1867     status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1868     ok( status == STATUS_ACCESS_DENIED, "NtWaitForKeyedEvent %x\n", status );
1869     status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1870     ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1871 
1872     /* it's not an event */
1873     status = pNtPulseEvent( handle, NULL );
1874     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtPulseEvent %x\n", status );
1875 
1876     status = pNtCreateEvent( &event, GENERIC_ALL, &attr, FALSE, FALSE );
1877     ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
1878         "CreateEvent %x\n", status );
1879 
1880     NtClose( handle );
1881 
1882     status = pNtCreateEvent( &event, GENERIC_ALL, &attr, FALSE, FALSE );
1883     ok( status == 0, "CreateEvent %x\n", status );
1884     status = pNtWaitForKeyedEvent( event, (void *)8, 0, &timeout );
1885     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtWaitForKeyedEvent %x\n", status );
1886     status = pNtReleaseKeyedEvent( event, (void *)8, 0, &timeout );
1887     ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtReleaseKeyedEvent %x\n", status );
1888     NtClose( event );
1889 }
1890 
1891 static void test_null_device(void)
1892 {
1893     OBJECT_ATTRIBUTES attr;
1894     IO_STATUS_BLOCK iosb;
1895     UNICODE_STRING str;
1896     NTSTATUS status;
1897     DWORD num_bytes;
1898     OVERLAPPED ov;
1899     char buf[64];
1900     HANDLE null;
1901     BOOL ret;
1902 
1903     memset(buf, 0xAA, sizeof(buf));
1904     memset(&ov, 0, sizeof(ov));
1905     ov.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
1906 
1907     pRtlCreateUnicodeStringFromAsciiz(&str, "\\Device\\Null");
1908     InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
1909     status = pNtOpenSymbolicLinkObject(&null, SYMBOLIC_LINK_QUERY, &attr);
1910     ok(status == STATUS_OBJECT_TYPE_MISMATCH,
1911        "expected STATUS_OBJECT_TYPE_MISMATCH, got %08x\n", status);
1912 
1913     status = pNtOpenFile(&null, GENERIC_READ | GENERIC_WRITE, &attr, &iosb,
1914                          FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
1915     ok(status == STATUS_SUCCESS,
1916        "expected STATUS_SUCCESS, got %08x\n", status);
1917 
1918     SetLastError(0xdeadbeef);
1919     ret = WriteFile(null, buf, sizeof(buf), &num_bytes, NULL);
1920     ok(!ret, "WriteFile unexpectedly succeeded\n");
1921     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1922        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1923 
1924     SetLastError(0xdeadbeef);
1925     ret = ReadFile(null, buf, sizeof(buf), &num_bytes, NULL);
1926     ok(!ret, "ReadFile unexpectedly succeeded\n");
1927     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1928        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1929 
1930     num_bytes = 0xdeadbeef;
1931     SetLastError(0xdeadbeef);
1932     ret = WriteFile(null, buf, sizeof(buf), &num_bytes, &ov);
1933     if (ret || GetLastError() != ERROR_IO_PENDING)
1934     {
1935         ok(ret, "WriteFile failed with error %u\n", GetLastError());
1936     }
1937     else
1938     {
1939         num_bytes = 0xdeadbeef;
1940         ret = GetOverlappedResult(null, &ov, &num_bytes, TRUE);
1941         ok(ret, "GetOverlappedResult failed with error %u\n", GetLastError());
1942     }
1943     ok(num_bytes == sizeof(buf), "expected num_bytes = %u, got %u\n",
1944        (DWORD)sizeof(buf), num_bytes);
1945 
1946     num_bytes = 0xdeadbeef;
1947     SetLastError(0xdeadbeef);
1948     ret = ReadFile(null, buf, sizeof(buf), &num_bytes, &ov);
1949     if (ret || GetLastError() != ERROR_IO_PENDING)
1950     {
1951         ok(!ret, "ReadFile unexpectedly succeeded\n");
1952     }
1953     else
1954     {
1955         num_bytes = 0xdeadbeef;
1956         ret = GetOverlappedResult(null, &ov, &num_bytes, TRUE);
1957         ok(!ret, "GetOverlappedResult unexpectedly succeeded\n");
1958     }
1959     ok(GetLastError() == ERROR_HANDLE_EOF,
1960        "expected ERROR_HANDLE_EOF, got %u\n", GetLastError());
1961 
1962     pNtClose(null);
1963 
1964     null = CreateFileA("\\\\.\\Null", GENERIC_READ | GENERIC_WRITE,
1965                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1966                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1967     ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
1968     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1969        "expected ERROR_FILE_NOT_FOUND, got %u\n", GetLastError());
1970 
1971     null = CreateFileA("\\\\.\\Device\\Null", GENERIC_READ | GENERIC_WRITE,
1972                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1973                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1974     ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
1975     ok(GetLastError() == ERROR_PATH_NOT_FOUND,
1976        "expected ERROR_PATH_NOT_FOUND, got %u\n", GetLastError());
1977 
1978     pRtlFreeUnicodeString(&str);
1979     CloseHandle(ov.hEvent);
1980 }
1981 
1982 static DWORD WINAPI mutant_thread( void *arg )
1983 {
1984     MUTANT_BASIC_INFORMATION info;
1985     NTSTATUS status;
1986     HANDLE mutant;
1987     DWORD ret;
1988 
1989     mutant = arg;
1990     ret = WaitForSingleObject( mutant, 1000 );
1991     ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
1992 
1993     memset(&info, 0xcc, sizeof(info));
1994     status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
1995     ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
1996     ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
1997     ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
1998     ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
1999     /* abandon mutant */
2000 
2001     return 0;
2002 }
2003 
2004 static void test_mutant(void)
2005 {
2006     static const WCHAR name[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',
2007                                  '\\','t','e','s','t','_','m','u','t','a','n','t',0};
2008     MUTANT_BASIC_INFORMATION info;
2009     OBJECT_ATTRIBUTES attr;
2010     UNICODE_STRING str;
2011     NTSTATUS status;
2012     HANDLE mutant;
2013     HANDLE thread;
2014     DWORD ret;
2015     ULONG len;
2016     LONG prev;
2017 
2018     pRtlInitUnicodeString(&str, name);
2019     InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
2020     status = pNtCreateMutant(&mutant, GENERIC_ALL, &attr, TRUE);
2021     ok( status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status );
2022 
2023     /* bogus */
2024     status = pNtQueryMutant(mutant, MutantBasicInformation, &info, 0, NULL);
2025     ok( status == STATUS_INFO_LENGTH_MISMATCH,
2026         "Failed to NtQueryMutant, expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status );
2027     status = pNtQueryMutant(mutant, 0x42, &info, sizeof(info), NULL);
2028     ok( status == STATUS_INVALID_INFO_CLASS || broken(status == STATUS_NOT_IMPLEMENTED), /* 32-bit on Vista/2k8 */
2029         "Failed to NtQueryMutant, expected STATUS_INVALID_INFO_CLASS, got %08x\n", status );
2030     status = pNtQueryMutant((HANDLE)0xdeadbeef, MutantBasicInformation, &info, sizeof(info), NULL);
2031     ok( status == STATUS_INVALID_HANDLE,
2032         "Failed to NtQueryMutant, expected STATUS_INVALID_HANDLE, got %08x\n", status );
2033 
2034     /* new */
2035     len = -1;
2036     memset(&info, 0xcc, sizeof(info));
2037     status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), &len);
2038     ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
2039     ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
2040     ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
2041     ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
2042     ok( len == sizeof(info), "got %u\n", len );
2043 
2044     ret = WaitForSingleObject( mutant, 1000 );
2045     ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
2046 
2047     memset(&info, 0xcc, sizeof(info));
2048     status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
2049     ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
2050     ok( info.CurrentCount == -1, "expected -1, got %d\n", info.CurrentCount );
2051     ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
2052     ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
2053 
2054     prev = 0xdeadbeef;
2055     status = pNtReleaseMutant(mutant, &prev);
2056     ok( status == STATUS_SUCCESS, "NtQueryRelease failed %08x\n", status );
2057     ok( prev == -1, "NtQueryRelease failed, expected -1, got %d\n", prev );
2058 
2059     prev = 0xdeadbeef;
2060     status = pNtReleaseMutant(mutant, &prev);
2061     ok( status == STATUS_SUCCESS, "NtQueryRelease failed %08x\n", status );
2062     ok( prev == 0, "NtQueryRelease failed, expected 0, got %d\n", prev );
2063 
2064     memset(&info, 0xcc, sizeof(info));
2065     status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
2066     ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
2067     ok( info.CurrentCount == 1, "expected 1, got %d\n", info.CurrentCount );
2068     ok( info.OwnedByCaller == FALSE, "expected FALSE, got %d\n", info.OwnedByCaller );
2069     ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
2070 
2071     /* abandoned */
2072     thread = CreateThread( NULL, 0, mutant_thread, mutant, 0, NULL );
2073     ret = WaitForSingleObject( thread, 1000 );
2074     ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
2075     CloseHandle( thread );
2076 
2077     memset(&info, 0xcc, sizeof(info));
2078     status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
2079     ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
2080     ok( info.CurrentCount == 1, "expected 0, got %d\n", info.CurrentCount );
2081     ok( info.OwnedByCaller == FALSE, "expected FALSE, got %d\n", info.OwnedByCaller );
2082     ok( info.AbandonedState == TRUE, "expected TRUE, got %d\n", info.AbandonedState );
2083 
2084     ret = WaitForSingleObject( mutant, 1000 );
2085     ok( ret == WAIT_ABANDONED_0, "WaitForSingleObject failed %08x\n", ret );
2086 
2087     memset(&info, 0xcc, sizeof(info));
2088     status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
2089     ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
2090     ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
2091     ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
2092     ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
2093 
2094     NtClose( mutant );
2095 }
2096 
2097 START_TEST(om)
2098 {
2099     HMODULE hntdll = GetModuleHandleA("ntdll.dll");
2100     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
2101 
2102     if (!hntdll)
2103     {
2104         skip("not running on NT, skipping test\n");
2105         return;
2106     }
2107 
2108     pCreateWaitableTimerA = (void *)GetProcAddress(hkernel32, "CreateWaitableTimerA");
2109 
2110     pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
2111     pRtlFreeUnicodeString   = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
2112     pNtCreateEvent          = (void *)GetProcAddress(hntdll, "NtCreateEvent");
2113     pNtCreateJobObject      = (void *)GetProcAddress(hntdll, "NtCreateJobObject");
2114     pNtOpenJobObject        = (void *)GetProcAddress(hntdll, "NtOpenJobObject");
2115     pNtCreateKey            = (void *)GetProcAddress(hntdll, "NtCreateKey");
2116     pNtOpenKey              = (void *)GetProcAddress(hntdll, "NtOpenKey");
2117     pNtDeleteKey            = (void *)GetProcAddress(hntdll, "NtDeleteKey");
2118     pNtCreateMailslotFile   = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile");
2119     pNtCreateMutant         = (void *)GetProcAddress(hntdll, "NtCreateMutant");
2120     pNtOpenEvent            = (void *)GetProcAddress(hntdll, "NtOpenEvent");
2121     pNtQueryEvent           = (void *)GetProcAddress(hntdll, "NtQueryEvent");
2122     pNtPulseEvent           = (void *)GetProcAddress(hntdll, "NtPulseEvent");
2123     pNtOpenMutant           = (void *)GetProcAddress(hntdll, "NtOpenMutant");
2124     pNtQueryMutant          = (void *)GetProcAddress(hntdll, "NtQueryMutant");
2125     pNtReleaseMutant        = (void *)GetProcAddress(hntdll, "NtReleaseMutant");
2126     pNtOpenFile             = (void *)GetProcAddress(hntdll, "NtOpenFile");
2127     pNtClose                = (void *)GetProcAddress(hntdll, "NtClose");
2128     pRtlInitUnicodeString   = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
2129     pNtCreateNamedPipeFile  = (void *)GetProcAddress(hntdll, "NtCreateNamedPipeFile");
2130     pNtOpenDirectoryObject  = (void *)GetProcAddress(hntdll, "NtOpenDirectoryObject");
2131     pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject");
2132     pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject");
2133     pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject");
2134     pNtQuerySymbolicLinkObject  = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject");
2135     pNtCreateSemaphore      =  (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
2136     pNtOpenSemaphore        =  (void *)GetProcAddress(hntdll, "NtOpenSemaphore");
2137     pNtCreateTimer          =  (void *)GetProcAddress(hntdll, "NtCreateTimer");
2138     pNtOpenTimer            =  (void *)GetProcAddress(hntdll, "NtOpenTimer");
2139     pNtCreateSection        =  (void *)GetProcAddress(hntdll, "NtCreateSection");
2140     pNtOpenSection          =  (void *)GetProcAddress(hntdll, "NtOpenSection");
2141     pNtQueryObject          =  (void *)GetProcAddress(hntdll, "NtQueryObject");
2142     pNtReleaseSemaphore     =  (void *)GetProcAddress(hntdll, "NtReleaseSemaphore");
2143     pNtCreateKeyedEvent     =  (void *)GetProcAddress(hntdll, "NtCreateKeyedEvent");
2144     pNtOpenKeyedEvent       =  (void *)GetProcAddress(hntdll, "NtOpenKeyedEvent");
2145     pNtWaitForKeyedEvent    =  (void *)GetProcAddress(hntdll, "NtWaitForKeyedEvent");
2146     pNtReleaseKeyedEvent    =  (void *)GetProcAddress(hntdll, "NtReleaseKeyedEvent");
2147     pNtCreateIoCompletion   =  (void *)GetProcAddress(hntdll, "NtCreateIoCompletion");
2148     pNtOpenIoCompletion     =  (void *)GetProcAddress(hntdll, "NtOpenIoCompletion");
2149     pNtQuerySystemInformation = (void *)GetProcAddress(hntdll, "NtQuerySystemInformation");
2150 
2151     test_case_sensitive();
2152     test_namespace_pipe();
2153     test_name_collisions();
2154     test_name_limits();
2155     test_directory();
2156     test_symboliclink();
2157     test_query_object();
2158     test_query_object_types();
2159     test_type_mismatch();
2160     test_event();
2161     test_mutant();
2162     test_keyed_events();
2163     test_null_device();
2164 }
2165