ntdll: Add support for file I/O on device files.
[wine.git] / dlls / ntdll / tests / om.c
bloba7ac95f814c51e919d8aed60a25c22024d9e82e4
1 /*
2 * Unit test suite for object manager functions
4 * Copyright 2005 Robert Shearman
5 * Copyright 2005 Vitaliy Margolen
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.
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.
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
22 #include "ntdll_test.h"
23 #include "winternl.h"
24 #include "stdio.h"
25 #include "winnt.h"
26 #include "stdlib.h"
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 *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN );
37 static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
38 static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG );
39 static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE );
40 static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER,
41 ULONG, ULONG, HANDLE );
42 static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG );
43 static NTSTATUS (WINAPI *pNtClose) ( HANDLE );
44 static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
45 ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, PLARGE_INTEGER );
46 static NTSTATUS (WINAPI *pNtOpenDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
47 static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
48 static NTSTATUS (WINAPI *pNtOpenSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
49 static NTSTATUS (WINAPI *pNtCreateSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PUNICODE_STRING);
50 static NTSTATUS (WINAPI *pNtQuerySymbolicLinkObject)(HANDLE,PUNICODE_STRING,PULONG);
51 static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG);
52 static NTSTATUS (WINAPI *pNtReleaseSemaphore)(HANDLE, ULONG, PULONG);
53 static NTSTATUS (WINAPI *pNtCreateKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG );
54 static NTSTATUS (WINAPI *pNtOpenKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES * );
55 static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
56 static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
58 #define KEYEDEVENT_WAIT 0x0001
59 #define KEYEDEVENT_WAKE 0x0002
60 #define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x0003)
62 static void test_case_sensitive (void)
64 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};
65 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};
66 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};
67 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};
68 NTSTATUS status;
69 OBJECT_ATTRIBUTES attr;
70 UNICODE_STRING str;
71 HANDLE Event, Mutant, h;
73 pRtlInitUnicodeString(&str, buffer1);
74 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
75 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
76 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
78 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
79 ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
80 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status);
82 pRtlInitUnicodeString(&str, buffer2);
83 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
84 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
85 ok(status == STATUS_SUCCESS, "Failed to create Event(%08x)\n", status);
87 pRtlInitUnicodeString(&str, buffer3);
88 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
89 status = pNtOpenMutant(&h, GENERIC_ALL, &attr);
90 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
91 "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
93 pNtClose(Mutant);
95 pRtlInitUnicodeString(&str, buffer4);
96 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
97 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
98 ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
99 "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status);
101 status = pNtCreateEvent(&h, GENERIC_ALL, &attr, FALSE, FALSE);
102 ok(status == STATUS_OBJECT_NAME_COLLISION,
103 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status);
105 attr.Attributes = 0;
106 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
107 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
108 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
110 pNtClose(Event);
113 static void test_namespace_pipe(void)
115 static const WCHAR buffer1[] = {'\\','?','?','\\','P','I','P','E','\\','t','e','s','t','\\','p','i','p','e',0};
116 static const WCHAR buffer2[] = {'\\','?','?','\\','P','I','P','E','\\','T','E','S','T','\\','P','I','P','E',0};
117 static const WCHAR buffer3[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t','\\','p','i','p','e',0};
118 static const WCHAR buffer4[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t',0};
119 OBJECT_ATTRIBUTES attr;
120 UNICODE_STRING str;
121 IO_STATUS_BLOCK iosb;
122 NTSTATUS status;
123 LARGE_INTEGER timeout;
124 HANDLE pipe, h;
126 timeout.QuadPart = -10000;
128 pRtlInitUnicodeString(&str, buffer1);
129 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
130 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
131 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
132 ok(status == STATUS_SUCCESS, "Failed to create NamedPipe(%08x)\n", status);
134 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
135 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
136 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
137 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
139 pRtlInitUnicodeString(&str, buffer2);
140 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
141 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
142 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
143 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
144 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
146 h = CreateFileA("\\\\.\\pipe\\test\\pipe", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
147 OPEN_EXISTING, 0, 0 );
148 ok(h != INVALID_HANDLE_VALUE, "Failed to open NamedPipe (%u)\n", GetLastError());
149 pNtClose(h);
151 pRtlInitUnicodeString(&str, buffer3);
152 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
153 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
154 ok(status == STATUS_OBJECT_PATH_NOT_FOUND ||
155 status == STATUS_PIPE_NOT_AVAILABLE ||
156 status == STATUS_OBJECT_NAME_INVALID || /* vista */
157 status == STATUS_OBJECT_NAME_NOT_FOUND, /* win8 */
158 "NtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
160 pRtlInitUnicodeString(&str, buffer4);
161 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
162 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
163 ok(status == STATUS_OBJECT_NAME_NOT_FOUND ||
164 status == STATUS_OBJECT_NAME_INVALID, /* vista */
165 "NtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08x)\n", status);
167 pNtClose(pipe);
170 #define DIRECTORY_QUERY (0x0001)
171 #define SYMBOLIC_LINK_QUERY 0x0001
173 #define DIR_TEST_CREATE_FAILURE(h,e) \
174 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr);\
175 ok(status == e,"NtCreateDirectoryObject should have failed with %s got(%08x)\n", #e, status);
176 #define DIR_TEST_OPEN_FAILURE(h,e) \
177 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr);\
178 ok(status == e,"NtOpenDirectoryObject should have failed with %s got(%08x)\n", #e, status);
179 #define DIR_TEST_CREATE_OPEN_FAILURE(h,n,e) \
180 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
181 DIR_TEST_CREATE_FAILURE(h,e) DIR_TEST_OPEN_FAILURE(h,e)\
182 pRtlFreeUnicodeString(&str);
184 #define DIR_TEST_CREATE_SUCCESS(h) \
185 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr); \
186 ok(status == STATUS_SUCCESS, "Failed to create Directory(%08x)\n", status);
187 #define DIR_TEST_OPEN_SUCCESS(h) \
188 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr); \
189 ok(status == STATUS_SUCCESS, "Failed to open Directory(%08x)\n", status);
190 #define DIR_TEST_CREATE_OPEN_SUCCESS(h,n) \
191 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
192 DIR_TEST_CREATE_SUCCESS(&h) pNtClose(h); DIR_TEST_OPEN_SUCCESS(&h) pNtClose(h); \
193 pRtlFreeUnicodeString(&str);
195 static BOOL is_correct_dir( HANDLE dir, const char *name )
197 NTSTATUS status;
198 UNICODE_STRING str;
199 OBJECT_ATTRIBUTES attr;
200 HANDLE h = 0;
202 pRtlCreateUnicodeStringFromAsciiz(&str, name);
203 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
204 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
205 pRtlFreeUnicodeString(&str);
206 if (h) pNtClose( h );
207 return (status == STATUS_OBJECT_NAME_EXISTS);
210 /* return a handle to the BaseNamedObjects dir where kernel32 objects get created */
211 static HANDLE get_base_dir(void)
213 static const char objname[] = "om.c_get_base_dir_obj";
214 NTSTATUS status;
215 UNICODE_STRING str;
216 OBJECT_ATTRIBUTES attr;
217 HANDLE dir, h;
218 unsigned int i;
220 h = CreateMutexA(NULL, FALSE, objname);
221 ok(h != 0, "CreateMutexA failed got ret=%p (%d)\n", h, GetLastError());
222 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
224 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local");
225 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
226 pRtlFreeUnicodeString(&str);
227 if (!status && is_correct_dir( dir, objname )) goto done;
228 if (!status) pNtClose( dir );
230 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
231 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
232 pRtlFreeUnicodeString(&str);
233 if (!status && is_correct_dir( dir, objname )) goto done;
234 if (!status) pNtClose( dir );
236 for (i = 0; i < 20; i++)
238 char name[40];
239 sprintf( name, "\\BaseNamedObjects\\Session\\%u", i );
240 pRtlCreateUnicodeStringFromAsciiz(&str, name );
241 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
242 pRtlFreeUnicodeString(&str);
243 if (!status && is_correct_dir( dir, objname )) goto done;
244 if (!status) pNtClose( dir );
246 dir = 0;
248 done:
249 pNtClose( h );
250 return dir;
253 static void test_name_collisions(void)
255 NTSTATUS status;
256 UNICODE_STRING str;
257 OBJECT_ATTRIBUTES attr;
258 HANDLE dir, h, h1, h2;
259 DWORD winerr;
260 LARGE_INTEGER size;
262 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
263 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
264 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_COLLISION)
265 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
267 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_EXISTS)
268 pNtClose(h);
269 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
270 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
271 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
272 pRtlFreeUnicodeString(&str);
274 pRtlCreateUnicodeStringFromAsciiz(&str, "\\??\\PIPE\\om.c-mutant");
275 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
276 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_OBJECT_PATH_NOT_FOUND,
277 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
278 pRtlFreeUnicodeString(&str);
280 if (!(dir = get_base_dir()))
282 win_skip( "couldn't find the BaseNamedObjects dir\n" );
283 return;
285 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
286 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
287 h = CreateMutexA(NULL, FALSE, "om.c-test");
288 ok(h != 0, "CreateMutexA failed got ret=%p (%d)\n", h, GetLastError());
289 status = pNtCreateMutant(&h1, GENERIC_ALL, &attr, FALSE);
290 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
291 "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
292 h2 = CreateMutexA(NULL, FALSE, "om.c-test");
293 winerr = GetLastError();
294 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
295 "CreateMutexA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
296 pNtClose(h);
297 pNtClose(h1);
298 pNtClose(h2);
300 h = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
301 ok(h != 0, "CreateEventA failed got ret=%p (%d)\n", h, GetLastError());
302 status = pNtCreateEvent(&h1, GENERIC_ALL, &attr, FALSE, FALSE);
303 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
304 "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
305 h2 = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
306 winerr = GetLastError();
307 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
308 "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
309 pNtClose(h);
310 pNtClose(h1);
311 pNtClose(h2);
313 h = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
314 ok(h != 0, "CreateSemaphoreA failed got ret=%p (%d)\n", h, GetLastError());
315 status = pNtCreateSemaphore(&h1, GENERIC_ALL, &attr, 1, 2);
316 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
317 "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
318 h2 = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
319 winerr = GetLastError();
320 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
321 "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
322 pNtClose(h);
323 pNtClose(h1);
324 pNtClose(h2);
326 h = pCreateWaitableTimerA(NULL, TRUE, "om.c-test");
327 ok(h != 0, "CreateWaitableTimerA failed got ret=%p (%d)\n", h, GetLastError());
328 status = pNtCreateTimer(&h1, GENERIC_ALL, &attr, NotificationTimer);
329 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
330 "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
331 h2 = pCreateWaitableTimerA(NULL, TRUE, "om.c-test");
332 winerr = GetLastError();
333 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
334 "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
335 pNtClose(h);
336 pNtClose(h1);
337 pNtClose(h2);
339 h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
340 ok(h != 0, "CreateFileMappingA failed got ret=%p (%d)\n", h, GetLastError());
341 size.u.LowPart = 256;
342 size.u.HighPart = 0;
343 status = pNtCreateSection(&h1, SECTION_MAP_WRITE, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
344 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
345 "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
346 h2 = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
347 winerr = GetLastError();
348 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
349 "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
350 pNtClose(h);
351 pNtClose(h1);
352 pNtClose(h2);
354 pRtlFreeUnicodeString(&str);
355 pNtClose(dir);
358 static void test_directory(void)
360 NTSTATUS status;
361 UNICODE_STRING str;
362 OBJECT_ATTRIBUTES attr;
363 HANDLE dir, dir1, h;
364 BOOL is_nt4;
366 /* No name and/or no attributes */
367 status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
368 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
369 "NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
370 status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
371 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
372 "NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
374 status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL);
375 ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08x)\n", status);
376 pNtClose(h);
377 status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL);
378 ok(status == STATUS_INVALID_PARAMETER,
379 "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
381 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
382 DIR_TEST_CREATE_SUCCESS(&dir)
383 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
385 /* Bad name */
386 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
388 pRtlCreateUnicodeStringFromAsciiz(&str, "");
389 DIR_TEST_CREATE_SUCCESS(&h)
390 pNtClose(h);
391 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
392 pRtlFreeUnicodeString(&str);
393 pNtClose(dir);
395 DIR_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD)
396 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID)
397 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID)
398 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID)
399 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
401 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
402 DIR_TEST_CREATE_SUCCESS(&h)
403 DIR_TEST_OPEN_SUCCESS(&dir1)
404 pRtlFreeUnicodeString(&str);
405 pNtClose(h);
406 pNtClose(dir1);
409 /* Use of root directory */
411 /* Can't use symlinks as a directory */
412 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local");
413 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
414 status = pNtOpenSymbolicLinkObject(&dir, SYMBOLIC_LINK_QUERY, &attr);
415 is_nt4 = (status == STATUS_OBJECT_NAME_NOT_FOUND); /* nt4 doesn't have Local\\ symlink */
416 if (!is_nt4)
418 WCHAR buffer[256];
419 ULONG len, full_len;
421 ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08x)\n", status);
422 pRtlFreeUnicodeString(&str);
423 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
424 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
425 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH)
426 pRtlFreeUnicodeString(&str);
428 str.Buffer = buffer;
429 str.MaximumLength = sizeof(buffer);
430 len = 0xdeadbeef;
431 memset( buffer, 0xaa, sizeof(buffer) );
432 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
433 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08x\n", status );
434 if (status != STATUS_SUCCESS)
435 goto error;
436 full_len = str.Length + sizeof(WCHAR);
437 ok( len == full_len, "bad length %u/%u\n", len, full_len );
438 if (len == full_len)
439 ok( buffer[len / sizeof(WCHAR) - 1] == 0, "no terminating null\n" );
441 str.MaximumLength = str.Length;
442 len = 0xdeadbeef;
443 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
444 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08x\n", status );
445 ok( len == full_len, "bad length %u/%u\n", len, full_len );
447 str.MaximumLength = 0;
448 len = 0xdeadbeef;
449 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
450 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08x\n", status );
451 ok( len == full_len, "bad length %u/%u\n", len, full_len );
453 str.MaximumLength = str.Length + sizeof(WCHAR);
454 len = 0xdeadbeef;
455 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
456 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08x\n", status );
457 ok( len == full_len, "bad length %u/%u\n", len, full_len );
459 error:
460 pNtClose(dir);
463 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
464 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
465 DIR_TEST_OPEN_SUCCESS(&dir)
466 pRtlFreeUnicodeString(&str);
468 InitializeObjectAttributes(&attr, NULL, 0, dir, NULL);
469 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_NAME_INVALID)
471 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
472 DIR_TEST_CREATE_OPEN_SUCCESS(h, "")
473 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
474 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD)
475 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
476 DIR_TEST_CREATE_OPEN_FAILURE(&h, "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
478 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
479 DIR_TEST_CREATE_SUCCESS(&dir1)
480 DIR_TEST_OPEN_SUCCESS(&h)
481 pRtlFreeUnicodeString(&str);
483 pNtClose(h);
484 pNtClose(dir1);
485 pNtClose(dir);
487 /* Nested directories */
488 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
489 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
490 DIR_TEST_OPEN_SUCCESS(&dir)
491 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
492 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
493 pRtlFreeUnicodeString(&str);
494 pNtClose(dir);
496 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
497 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
498 DIR_TEST_CREATE_SUCCESS(&dir)
499 pRtlFreeUnicodeString(&str);
500 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test\\one more level");
501 DIR_TEST_CREATE_SUCCESS(&h)
502 pRtlFreeUnicodeString(&str);
503 pNtClose(h);
504 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
505 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
506 DIR_TEST_CREATE_SUCCESS(&h)
507 pRtlFreeUnicodeString(&str);
508 pNtClose(h);
510 pNtClose(dir);
512 if (!is_nt4)
514 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
515 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Global\\om.c-test");
516 DIR_TEST_CREATE_SUCCESS(&dir)
517 pRtlFreeUnicodeString(&str);
518 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local\\om.c-test\\one more level");
519 DIR_TEST_CREATE_SUCCESS(&h)
520 pRtlFreeUnicodeString(&str);
521 pNtClose(h);
522 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
523 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
524 DIR_TEST_CREATE_SUCCESS(&dir)
525 pRtlFreeUnicodeString(&str);
526 pNtClose(h);
527 pNtClose(dir);
530 /* Create other objects using RootDirectory */
532 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
533 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
534 DIR_TEST_OPEN_SUCCESS(&dir)
535 pRtlFreeUnicodeString(&str);
536 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
538 /* Test invalid paths */
539 pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant");
540 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
541 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
542 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
543 pRtlFreeUnicodeString(&str);
544 pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant\\");
545 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
546 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
547 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
548 pRtlFreeUnicodeString(&str);
550 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c\\-mutant");
551 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
552 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
553 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
554 pRtlFreeUnicodeString(&str);
556 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-mutant");
557 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
558 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
559 pRtlFreeUnicodeString(&str);
560 pNtClose(h);
562 pNtClose(dir);
565 #define SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e2) \
566 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
567 pRtlCreateUnicodeStringFromAsciiz(&target, t);\
568 status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\
569 ok(status == e || status == e2, \
570 "NtCreateSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
571 status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\
572 ok(status == e || status == e2, \
573 "NtOpenSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
574 pRtlFreeUnicodeString(&target);\
575 pRtlFreeUnicodeString(&str);
577 #define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e)
579 static void test_symboliclink(void)
581 NTSTATUS status;
582 UNICODE_STRING str, target;
583 OBJECT_ATTRIBUTES attr;
584 HANDLE dir, link, h;
585 IO_STATUS_BLOCK iosb;
587 /* No name and/or no attributes */
588 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
589 SYMLNK_TEST_CREATE_OPEN_FAILURE2(NULL, "", "", STATUS_ACCESS_VIOLATION, STATUS_INVALID_PARAMETER)
591 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL);
592 ok(status == STATUS_ACCESS_VIOLATION,
593 "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
594 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL);
595 ok(status == STATUS_INVALID_PARAMETER,
596 "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
598 /* No attributes */
599 pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
600 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, &target);
601 ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_VIOLATION, /* nt4 */
602 "NtCreateSymbolicLinkObject failed(%08x)\n", status);
603 pRtlFreeUnicodeString(&target);
604 if (!status) pNtClose(h);
606 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
607 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
608 ok(status == STATUS_INVALID_PARAMETER ||
609 broken(status == STATUS_SUCCESS), /* nt4 */
610 "NtCreateSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
611 if (!status) pNtClose(h);
612 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
613 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
614 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
616 /* Bad name */
617 pRtlCreateUnicodeStringFromAsciiz(&target, "anywhere");
618 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
620 pRtlCreateUnicodeStringFromAsciiz(&str, "");
621 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
622 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status);
623 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
624 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
625 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
626 pNtClose(link);
627 pRtlFreeUnicodeString(&str);
629 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
630 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target);
631 todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH,
632 "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
633 pRtlFreeUnicodeString(&str);
634 pRtlFreeUnicodeString(&target);
636 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", "->Somewhere", STATUS_OBJECT_PATH_SYNTAX_BAD)
637 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
638 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
639 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
640 SYMLNK_TEST_CREATE_OPEN_FAILURE2(&h, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere",
641 STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND)
644 /* Compound test */
645 if (!(dir = get_base_dir()))
647 win_skip( "couldn't find the BaseNamedObjects dir\n" );
648 return;
651 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
652 pRtlCreateUnicodeStringFromAsciiz(&str, "test-link");
653 pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
654 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
655 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status);
656 pRtlFreeUnicodeString(&str);
657 pRtlFreeUnicodeString(&target);
659 pRtlCreateUnicodeStringFromAsciiz(&str, "test-link\\NUL");
660 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
661 ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08x)\n", status);
662 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE);
663 ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08x)\n", status);
664 pRtlFreeUnicodeString(&str);
666 pNtClose(h);
667 pNtClose(link);
668 pNtClose(dir);
671 static void test_query_object(void)
673 static const WCHAR name[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',
674 '\\','t','e','s','t','_','e','v','e','n','t'};
675 static const WCHAR type_event[] = {'E','v','e','n','t'};
676 static const WCHAR type_file[] = {'F','i','l','e'};
677 HANDLE handle;
678 char buffer[1024];
679 NTSTATUS status;
680 ULONG len, expected_len;
681 UNICODE_STRING *str;
682 char dir[MAX_PATH];
684 handle = CreateEventA( NULL, FALSE, FALSE, "test_event" );
686 len = 0;
687 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
688 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
689 ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
691 len = 0;
692 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, 0, &len );
693 todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
694 todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
696 len = 0;
697 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
698 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
699 ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
701 len = 0;
702 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(OBJECT_TYPE_INFORMATION), &len );
703 todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
704 todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
706 len = 0;
707 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
708 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
709 ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
710 str = (UNICODE_STRING *)buffer;
711 ok( sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR) == len, "unexpected len %u\n", len );
712 ok( str->Length >= sizeof(name), "unexpected len %u\n", str->Length );
713 /* there can be a \\Sessions prefix in the name */
714 ok( !memcmp( str->Buffer + (str->Length - sizeof(name)) / sizeof(WCHAR), name, sizeof(name) ),
715 "wrong name %s\n", wine_dbgstr_w(str->Buffer) );
717 len -= sizeof(WCHAR);
718 status = pNtQueryObject( handle, ObjectNameInformation, buffer, len, &len );
719 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
720 ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
722 len = 0;
723 memset( buffer, 0, sizeof(buffer) );
724 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
725 todo_wine ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
726 todo_wine ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
727 str = (UNICODE_STRING *)buffer;
728 todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR), "unexpected len %u\n", len );
729 todo_wine ok( str->Buffer && !memcmp( str->Buffer, type_event, sizeof(type_event) ),
730 "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
732 len -= sizeof(WCHAR);
733 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, len, &len );
734 todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
735 todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
737 pNtClose( handle );
739 handle = CreateEventA( NULL, FALSE, FALSE, NULL );
740 len = 0;
741 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
742 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
743 ok( len == sizeof(UNICODE_STRING), "unexpected len %u\n", len );
744 str = (UNICODE_STRING *)buffer;
745 ok( str->Length == 0, "unexpected len %u\n", len );
746 ok( str->Buffer == NULL, "unexpected ptr %p\n", str->Buffer );
747 pNtClose( handle );
749 GetWindowsDirectoryA( dir, MAX_PATH );
750 handle = CreateFileA( dir, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
751 FILE_FLAG_BACKUP_SEMANTICS, 0 );
752 len = 0;
753 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
754 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
755 ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
756 str = (UNICODE_STRING *)buffer;
757 expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR);
758 ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */
759 "unexpected len %u\n", len );
760 trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len );
762 len = 0;
763 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
764 ok( status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INSUFFICIENT_RESOURCES),
765 "NtQueryObject failed %x\n", status );
766 ok( len == expected_len || broken(!len || len == sizeof(UNICODE_STRING)),
767 "unexpected len %u\n", len );
769 len = 0;
770 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
771 ok( status == STATUS_BUFFER_OVERFLOW || broken(status == STATUS_INSUFFICIENT_RESOURCES
772 || status == STATUS_INFO_LENGTH_MISMATCH),
773 "NtQueryObject failed %x\n", status );
774 ok( len == expected_len || broken(!len),
775 "unexpected len %u\n", len );
777 len = 0;
778 memset( buffer, 0, sizeof(buffer) );
779 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
780 todo_wine ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
781 todo_wine ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
782 str = (UNICODE_STRING *)buffer;
783 expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
784 todo_wine ok( len >= expected_len, "unexpected len %u\n", len );
785 todo_wine ok( str->Buffer && !memcmp( str->Buffer, type_file, sizeof(type_file) ),
786 "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
788 pNtClose( handle );
791 static void test_type_mismatch(void)
793 HANDLE h;
794 NTSTATUS res;
795 OBJECT_ATTRIBUTES attr;
797 attr.Length = sizeof(attr);
798 attr.RootDirectory = 0;
799 attr.ObjectName = NULL;
800 attr.Attributes = 0;
801 attr.SecurityDescriptor = NULL;
802 attr.SecurityQualityOfService = NULL;
804 res = pNtCreateEvent( &h, 0, &attr, 0, 0 );
805 ok(!res, "can't create event: %x\n", res);
807 res = pNtReleaseSemaphore( h, 30, NULL );
808 ok(res == STATUS_OBJECT_TYPE_MISMATCH, "expected 0xc0000024, got %x\n", res);
810 pNtClose( h );
813 static void test_event(void)
815 HANDLE Event;
816 HANDLE Event2;
817 NTSTATUS status;
818 UNICODE_STRING str;
819 OBJECT_ATTRIBUTES attr;
820 EVENT_BASIC_INFORMATION info;
821 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};
823 pRtlInitUnicodeString(&str, eventName);
824 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
826 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, 1, 0);
827 ok( status == STATUS_SUCCESS, "NtCreateEvent failed %08x\n", status );
829 status = pNtPulseEvent(Event, NULL);
830 ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
832 status = pNtQueryEvent(Event, EventBasicInformation, &info, sizeof(info), NULL);
833 ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
834 ok( info.EventType == 1 && info.EventState == 0,
835 "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
837 status = pNtOpenEvent(&Event2, GENERIC_ALL, &attr);
838 ok( status == STATUS_SUCCESS, "NtOpenEvent failed %08x\n", status );
840 pNtClose(Event);
842 status = pNtQueryEvent(Event2, EventBasicInformation, &info, sizeof(info), NULL);
843 ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
844 ok( info.EventType == 1 && info.EventState == 0,
845 "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
847 pNtClose(Event2);
850 static const WCHAR keyed_nameW[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',
851 '\\','W','i','n','e','T','e','s','t','E','v','e','n','t',0};
853 static DWORD WINAPI keyed_event_thread( void *arg )
855 HANDLE handle;
856 NTSTATUS status;
857 LARGE_INTEGER timeout;
858 OBJECT_ATTRIBUTES attr;
859 UNICODE_STRING str;
860 ULONG_PTR i;
862 attr.Length = sizeof(attr);
863 attr.RootDirectory = 0;
864 attr.ObjectName = &str;
865 attr.Attributes = 0;
866 attr.SecurityDescriptor = NULL;
867 attr.SecurityQualityOfService = NULL;
868 RtlInitUnicodeString( &str, keyed_nameW );
870 status = pNtOpenKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr );
871 ok( !status, "NtOpenKeyedEvent failed %x\n", status );
873 for (i = 0; i < 20; i++)
875 if (i & 1)
876 status = pNtWaitForKeyedEvent( handle, (void *)(i * 2), 0, NULL );
877 else
878 status = pNtReleaseKeyedEvent( handle, (void *)(i * 2), 0, NULL );
879 ok( status == STATUS_SUCCESS, "%li: failed %x\n", i, status );
880 Sleep( 20 - i );
883 status = pNtReleaseKeyedEvent( handle, (void *)0x1234, 0, NULL );
884 ok( status == STATUS_SUCCESS, "NtReleaseKeyedEvent %x\n", status );
886 timeout.QuadPart = -10000;
887 status = pNtWaitForKeyedEvent( handle, (void *)0x5678, 0, &timeout );
888 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
889 status = pNtReleaseKeyedEvent( handle, (void *)0x9abc, 0, &timeout );
890 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
892 NtClose( handle );
893 return 0;
896 static void test_keyed_events(void)
898 OBJECT_ATTRIBUTES attr;
899 UNICODE_STRING str;
900 HANDLE handle, event, thread;
901 NTSTATUS status;
902 LARGE_INTEGER timeout;
903 ULONG_PTR i;
905 if (!pNtCreateKeyedEvent)
907 win_skip( "Keyed events not supported\n" );
908 return;
911 attr.Length = sizeof(attr);
912 attr.RootDirectory = 0;
913 attr.ObjectName = &str;
914 attr.Attributes = 0;
915 attr.SecurityDescriptor = NULL;
916 attr.SecurityQualityOfService = NULL;
917 RtlInitUnicodeString( &str, keyed_nameW );
919 status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS | SYNCHRONIZE, &attr, 0 );
920 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
922 status = WaitForSingleObject( handle, 1000 );
923 ok( status == 0, "WaitForSingleObject %x\n", status );
925 timeout.QuadPart = -100000;
926 status = pNtWaitForKeyedEvent( handle, (void *)255, 0, &timeout );
927 ok( status == STATUS_INVALID_PARAMETER_1, "NtWaitForKeyedEvent %x\n", status );
928 status = pNtReleaseKeyedEvent( handle, (void *)255, 0, &timeout );
929 ok( status == STATUS_INVALID_PARAMETER_1, "NtReleaseKeyedEvent %x\n", status );
931 status = pNtWaitForKeyedEvent( handle, (void *)254, 0, &timeout );
932 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
933 status = pNtReleaseKeyedEvent( handle, (void *)254, 0, &timeout );
934 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
936 status = pNtWaitForKeyedEvent( handle, NULL, 0, &timeout );
937 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
938 status = pNtReleaseKeyedEvent( handle, NULL, 0, &timeout );
939 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
941 status = pNtWaitForKeyedEvent( (HANDLE)0xdeadbeef, (void *)9, 0, &timeout );
942 ok( status == STATUS_INVALID_PARAMETER_1, "NtWaitForKeyedEvent %x\n", status );
943 status = pNtReleaseKeyedEvent( (HANDLE)0xdeadbeef, (void *)9, 0, &timeout );
944 ok( status == STATUS_INVALID_PARAMETER_1, "NtReleaseKeyedEvent %x\n", status );
946 status = pNtWaitForKeyedEvent( (HANDLE)0xdeadbeef, (void *)8, 0, &timeout );
947 ok( status == STATUS_INVALID_HANDLE, "NtWaitForKeyedEvent %x\n", status );
948 status = pNtReleaseKeyedEvent( (HANDLE)0xdeadbeef, (void *)8, 0, &timeout );
949 ok( status == STATUS_INVALID_HANDLE, "NtReleaseKeyedEvent %x\n", status );
951 thread = CreateThread( NULL, 0, keyed_event_thread, 0, 0, NULL );
952 for (i = 0; i < 20; i++)
954 if (i & 1)
955 status = pNtReleaseKeyedEvent( handle, (void *)(i * 2), 0, NULL );
956 else
957 status = pNtWaitForKeyedEvent( handle, (void *)(i * 2), 0, NULL );
958 ok( status == STATUS_SUCCESS, "%li: failed %x\n", i, status );
959 Sleep( i );
961 status = pNtWaitForKeyedEvent( handle, (void *)0x1234, 0, &timeout );
962 ok( status == STATUS_SUCCESS, "NtWaitForKeyedEvent %x\n", status );
963 status = pNtWaitForKeyedEvent( handle, (void *)0x5678, 0, &timeout );
964 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
965 status = pNtReleaseKeyedEvent( handle, (void *)0x9abc, 0, &timeout );
966 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
968 ok( WaitForSingleObject( thread, 30000 ) == 0, "wait failed\n" );
970 NtClose( handle );
972 /* test access rights */
974 status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_WAIT, &attr, 0 );
975 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
976 status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
977 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
978 status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
979 ok( status == STATUS_ACCESS_DENIED, "NtReleaseKeyedEvent %x\n", status );
980 NtClose( handle );
982 status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_WAKE, &attr, 0 );
983 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
984 status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
985 ok( status == STATUS_ACCESS_DENIED, "NtWaitForKeyedEvent %x\n", status );
986 status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
987 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
988 NtClose( handle );
990 status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr, 0 );
991 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
992 status = WaitForSingleObject( handle, 1000 );
993 ok( status == WAIT_FAILED && GetLastError() == ERROR_ACCESS_DENIED,
994 "WaitForSingleObject %x err %u\n", status, GetLastError() );
995 status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
996 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
997 status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
998 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
999 NtClose( handle );
1001 /* GENERIC_READ gives wait access */
1002 status = pNtCreateKeyedEvent( &handle, GENERIC_READ, &attr, 0 );
1003 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1004 status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1005 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1006 status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1007 ok( status == STATUS_ACCESS_DENIED, "NtReleaseKeyedEvent %x\n", status );
1008 NtClose( handle );
1010 /* GENERIC_WRITE gives wake access */
1011 status = pNtCreateKeyedEvent( &handle, GENERIC_WRITE, &attr, 0 );
1012 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1013 status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1014 ok( status == STATUS_ACCESS_DENIED, "NtWaitForKeyedEvent %x\n", status );
1015 status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1016 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1018 /* it's not an event */
1019 status = pNtPulseEvent( handle, NULL );
1020 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtPulseEvent %x\n", status );
1022 status = pNtCreateEvent( &event, GENERIC_ALL, &attr, FALSE, FALSE );
1023 ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
1024 "CreateEvent %x\n", status );
1026 NtClose( handle );
1028 status = pNtCreateEvent( &event, GENERIC_ALL, &attr, FALSE, FALSE );
1029 ok( status == 0, "CreateEvent %x\n", status );
1030 status = pNtWaitForKeyedEvent( event, (void *)8, 0, &timeout );
1031 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtWaitForKeyedEvent %x\n", status );
1032 status = pNtReleaseKeyedEvent( event, (void *)8, 0, &timeout );
1033 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtReleaseKeyedEvent %x\n", status );
1034 NtClose( event );
1037 static void test_null_device(void)
1039 OBJECT_ATTRIBUTES attr;
1040 IO_STATUS_BLOCK iosb;
1041 UNICODE_STRING str;
1042 NTSTATUS status;
1043 DWORD num_bytes;
1044 OVERLAPPED ov;
1045 char buf[64];
1046 HANDLE null;
1047 BOOL ret;
1049 memset(buf, 0xAA, sizeof(buf));
1050 memset(&ov, 0, sizeof(ov));
1051 ov.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
1053 pRtlCreateUnicodeStringFromAsciiz(&str, "\\Device\\Null");
1054 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
1055 status = pNtOpenSymbolicLinkObject(&null, SYMBOLIC_LINK_QUERY, &attr);
1056 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
1057 "expected STATUS_OBJECT_TYPE_MISMATCH, got %08x\n", status);
1059 status = pNtOpenFile(&null, GENERIC_READ | GENERIC_WRITE, &attr, &iosb,
1060 FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
1061 ok(status == STATUS_SUCCESS,
1062 "expected STATUS_SUCCESS, got %08x\n", status);
1064 SetLastError(0xdeadbeef);
1065 ret = WriteFile(null, buf, sizeof(buf), &num_bytes, NULL);
1066 ok(!ret, "WriteFile unexpectedly succeeded\n");
1067 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1068 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1070 SetLastError(0xdeadbeef);
1071 ret = ReadFile(null, buf, sizeof(buf), &num_bytes, NULL);
1072 ok(!ret, "ReadFile unexpectedly succeeded\n");
1073 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1074 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1076 num_bytes = 0xdeadbeef;
1077 SetLastError(0xdeadbeef);
1078 ret = WriteFile(null, buf, sizeof(buf), &num_bytes, &ov);
1079 if (ret || GetLastError() != ERROR_IO_PENDING)
1081 ok(ret, "WriteFile failed with error %u\n", GetLastError());
1083 else
1085 num_bytes = 0xdeadbeef;
1086 ret = GetOverlappedResult(null, &ov, &num_bytes, TRUE);
1087 ok(ret, "GetOverlappedResult failed with error %u\n", GetLastError());
1089 ok(num_bytes == sizeof(buf), "expected num_bytes = %u, got %u\n",
1090 (DWORD)sizeof(buf), num_bytes);
1092 num_bytes = 0xdeadbeef;
1093 SetLastError(0xdeadbeef);
1094 ret = ReadFile(null, buf, sizeof(buf), &num_bytes, &ov);
1095 if (ret || GetLastError() != ERROR_IO_PENDING)
1097 ok(!ret, "ReadFile unexpectedly succeeded\n");
1099 else
1101 num_bytes = 0xdeadbeef;
1102 ret = GetOverlappedResult(null, &ov, &num_bytes, TRUE);
1103 ok(!ret, "GetOverlappedResult unexpectedly succeeded\n");
1105 ok(GetLastError() == ERROR_HANDLE_EOF,
1106 "expected ERROR_HANDLE_EOF, got %u\n", GetLastError());
1108 pNtClose(null);
1110 null = CreateFileA("\\\\.\\Null", GENERIC_READ | GENERIC_WRITE,
1111 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1112 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1113 ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
1114 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1115 "expected ERROR_FILE_NOT_FOUND, got %u\n", GetLastError());
1117 null = CreateFileA("\\\\.\\Device\\Null", GENERIC_READ | GENERIC_WRITE,
1118 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1119 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1120 ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
1121 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
1122 "expected ERROR_PATH_NOT_FOUND, got %u\n", GetLastError());
1124 pRtlFreeUnicodeString(&str);
1125 CloseHandle(ov.hEvent);
1128 START_TEST(om)
1130 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
1131 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
1133 if (!hntdll)
1135 skip("not running on NT, skipping test\n");
1136 return;
1139 pCreateWaitableTimerA = (void *)GetProcAddress(hkernel32, "CreateWaitableTimerA");
1141 pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
1142 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
1143 pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent");
1144 pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant");
1145 pNtOpenEvent = (void *)GetProcAddress(hntdll, "NtOpenEvent");
1146 pNtQueryEvent = (void *)GetProcAddress(hntdll, "NtQueryEvent");
1147 pNtPulseEvent = (void *)GetProcAddress(hntdll, "NtPulseEvent");
1148 pNtOpenMutant = (void *)GetProcAddress(hntdll, "NtOpenMutant");
1149 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
1150 pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
1151 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
1152 pNtCreateNamedPipeFile = (void *)GetProcAddress(hntdll, "NtCreateNamedPipeFile");
1153 pNtOpenDirectoryObject = (void *)GetProcAddress(hntdll, "NtOpenDirectoryObject");
1154 pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject");
1155 pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject");
1156 pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject");
1157 pNtQuerySymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject");
1158 pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
1159 pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer");
1160 pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection");
1161 pNtQueryObject = (void *)GetProcAddress(hntdll, "NtQueryObject");
1162 pNtReleaseSemaphore = (void *)GetProcAddress(hntdll, "NtReleaseSemaphore");
1163 pNtCreateKeyedEvent = (void *)GetProcAddress(hntdll, "NtCreateKeyedEvent");
1164 pNtOpenKeyedEvent = (void *)GetProcAddress(hntdll, "NtOpenKeyedEvent");
1165 pNtWaitForKeyedEvent = (void *)GetProcAddress(hntdll, "NtWaitForKeyedEvent");
1166 pNtReleaseKeyedEvent = (void *)GetProcAddress(hntdll, "NtReleaseKeyedEvent");
1168 test_case_sensitive();
1169 test_namespace_pipe();
1170 test_name_collisions();
1171 test_directory();
1172 test_symboliclink();
1173 test_query_object();
1174 test_type_mismatch();
1175 test_event();
1176 test_keyed_events();
1177 test_null_device();