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