[SHELL32] Fix Control_RunDLLW (#5400)
[reactos.git] / modules / rostests / winetests / ntdll / om.c
1 /*
2 * Unit test suite for object manager functions
3 *
4 * Copyright 2005 Robert Shearman
5 * Copyright 2005 Vitaliy Margolen
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "ntdll_test.h"
23 #include "winternl.h"
24 #include "stdio.h"
25 #include "winnt.h"
26 #include "stdlib.h"
27
28 static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*, BOOL, LPCSTR);
29 static 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 }