[NTDLL_WINETEST] Sync with Wine Staging 1.7.55. CORE-10536
[reactos.git] / rostests / winetests / ntdll / om.c
1 /*
2 * Unit test suite for object manager functions
3 *
4 * Copyright 2005 Robert Shearman
5 * Copyright 2005 Vitaliy Margolen
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "ntdll_test.h"
23 #include "wine/winternl.h"
24 #include "stdio.h"
25 #include "winnt.h"
26 #include "stdlib.h"
27
28 static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*, BOOL, LPCSTR);
29 static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
30 static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
31 static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
32 static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN, BOOLEAN);
33 static NTSTATUS (WINAPI *pNtOpenEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES);
34 static NTSTATUS (WINAPI *pNtPulseEvent) ( HANDLE, PULONG );
35 static NTSTATUS (WINAPI *pNtQueryEvent) ( HANDLE, EVENT_INFORMATION_CLASS, PVOID, ULONG, PULONG );
36 static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN );
37 static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
38 static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG );
39 static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE );
40 static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER,
41 ULONG, ULONG, HANDLE );
42 static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG );
43 static NTSTATUS (WINAPI *pNtClose) ( HANDLE );
44 static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
45 ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, PLARGE_INTEGER );
46 static NTSTATUS (WINAPI *pNtOpenDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
47 static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
48 static NTSTATUS (WINAPI *pNtOpenSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
49 static NTSTATUS (WINAPI *pNtCreateSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PUNICODE_STRING);
50 static NTSTATUS (WINAPI *pNtQuerySymbolicLinkObject)(HANDLE,PUNICODE_STRING,PULONG);
51 static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG);
52 static NTSTATUS (WINAPI *pNtReleaseSemaphore)(HANDLE, ULONG, PULONG);
53 static NTSTATUS (WINAPI *pNtCreateKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG );
54 static NTSTATUS (WINAPI *pNtOpenKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES * );
55 static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
56 static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
57 static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG);
58
59 #define KEYEDEVENT_WAIT 0x0001
60 #define KEYEDEVENT_WAKE 0x0002
61 #define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x0003)
62
63 static void test_case_sensitive (void)
64 {
65 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};
66 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};
67 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};
68 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};
69 NTSTATUS status;
70 OBJECT_ATTRIBUTES attr;
71 UNICODE_STRING str;
72 HANDLE Event, Mutant, h;
73
74 pRtlInitUnicodeString(&str, buffer1);
75 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
76 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
77 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
78
79 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
80 ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
81 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status);
82
83 pRtlInitUnicodeString(&str, buffer2);
84 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
85 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
86 ok(status == STATUS_SUCCESS, "Failed to create Event(%08x)\n", status);
87
88 pRtlInitUnicodeString(&str, buffer3);
89 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
90 status = pNtOpenMutant(&h, GENERIC_ALL, &attr);
91 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
92 "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
93
94 pNtClose(Mutant);
95
96 pRtlInitUnicodeString(&str, buffer4);
97 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
98 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
99 ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
100 "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status);
101
102 status = pNtCreateEvent(&h, GENERIC_ALL, &attr, FALSE, FALSE);
103 ok(status == STATUS_OBJECT_NAME_COLLISION,
104 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status);
105
106 attr.Attributes = 0;
107 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
108 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
109 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
110
111 pNtClose(Event);
112 }
113
114 static void test_namespace_pipe(void)
115 {
116 static const WCHAR buffer1[] = {'\\','?','?','\\','P','I','P','E','\\','t','e','s','t','\\','p','i','p','e',0};
117 static const WCHAR buffer2[] = {'\\','?','?','\\','P','I','P','E','\\','T','E','S','T','\\','P','I','P','E',0};
118 static const WCHAR buffer3[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t','\\','p','i','p','e',0};
119 static const WCHAR buffer4[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t',0};
120 OBJECT_ATTRIBUTES attr;
121 UNICODE_STRING str;
122 IO_STATUS_BLOCK iosb;
123 NTSTATUS status;
124 LARGE_INTEGER timeout;
125 HANDLE pipe, h;
126
127 timeout.QuadPart = -10000;
128
129 pRtlInitUnicodeString(&str, buffer1);
130 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
131 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
132 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
133 ok(status == STATUS_SUCCESS, "Failed to create NamedPipe(%08x)\n", status);
134
135 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
136 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
137 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
138 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
139
140 pRtlInitUnicodeString(&str, buffer2);
141 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
142 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
143 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
144 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
145 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
146
147 h = CreateFileA("\\\\.\\pipe\\test\\pipe", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
148 OPEN_EXISTING, 0, 0 );
149 ok(h != INVALID_HANDLE_VALUE, "Failed to open NamedPipe (%u)\n", GetLastError());
150 pNtClose(h);
151
152 pRtlInitUnicodeString(&str, buffer3);
153 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
154 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
155 ok(status == STATUS_OBJECT_PATH_NOT_FOUND ||
156 status == STATUS_PIPE_NOT_AVAILABLE ||
157 status == STATUS_OBJECT_NAME_INVALID || /* vista */
158 status == STATUS_OBJECT_NAME_NOT_FOUND, /* win8 */
159 "NtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
160
161 pRtlInitUnicodeString(&str, buffer4);
162 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
163 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
164 ok(status == STATUS_OBJECT_NAME_NOT_FOUND ||
165 status == STATUS_OBJECT_NAME_INVALID, /* vista */
166 "NtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08x)\n", status);
167
168 pNtClose(pipe);
169 }
170
171 #define DIRECTORY_QUERY (0x0001)
172 #define SYMBOLIC_LINK_QUERY 0x0001
173
174 #define DIR_TEST_CREATE_FAILURE(h,e) \
175 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr);\
176 ok(status == e,"NtCreateDirectoryObject should have failed with %s got(%08x)\n", #e, status);
177 #define DIR_TEST_OPEN_FAILURE(h,e) \
178 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr);\
179 ok(status == e,"NtOpenDirectoryObject should have failed with %s got(%08x)\n", #e, status);
180 #define DIR_TEST_CREATE_OPEN_FAILURE(h,n,e) \
181 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
182 DIR_TEST_CREATE_FAILURE(h,e) DIR_TEST_OPEN_FAILURE(h,e)\
183 pRtlFreeUnicodeString(&str);
184
185 #define DIR_TEST_CREATE_SUCCESS(h) \
186 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr); \
187 ok(status == STATUS_SUCCESS, "Failed to create Directory(%08x)\n", status);
188 #define DIR_TEST_OPEN_SUCCESS(h) \
189 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr); \
190 ok(status == STATUS_SUCCESS, "Failed to open Directory(%08x)\n", status);
191 #define DIR_TEST_CREATE_OPEN_SUCCESS(h,n) \
192 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
193 DIR_TEST_CREATE_SUCCESS(&h) pNtClose(h); DIR_TEST_OPEN_SUCCESS(&h) pNtClose(h); \
194 pRtlFreeUnicodeString(&str);
195
196 static BOOL is_correct_dir( HANDLE dir, const char *name )
197 {
198 NTSTATUS status;
199 UNICODE_STRING str;
200 OBJECT_ATTRIBUTES attr;
201 HANDLE h = 0;
202
203 pRtlCreateUnicodeStringFromAsciiz(&str, name);
204 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
205 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
206 pRtlFreeUnicodeString(&str);
207 if (h) pNtClose( h );
208 return (status == STATUS_OBJECT_NAME_EXISTS);
209 }
210
211 /* return a handle to the BaseNamedObjects dir where kernel32 objects get created */
212 static HANDLE get_base_dir(void)
213 {
214 static const char objname[] = "om.c_get_base_dir_obj";
215 NTSTATUS status;
216 UNICODE_STRING str;
217 OBJECT_ATTRIBUTES attr;
218 HANDLE dir, h;
219 unsigned int i;
220
221 h = CreateMutexA(NULL, FALSE, objname);
222 ok(h != 0, "CreateMutexA failed got ret=%p (%d)\n", h, GetLastError());
223 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
224
225 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local");
226 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
227 pRtlFreeUnicodeString(&str);
228 if (!status && is_correct_dir( dir, objname )) goto done;
229 if (!status) pNtClose( dir );
230
231 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
232 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
233 pRtlFreeUnicodeString(&str);
234 if (!status && is_correct_dir( dir, objname )) goto done;
235 if (!status) pNtClose( dir );
236
237 for (i = 0; i < 20; i++)
238 {
239 char name[40];
240 sprintf( name, "\\BaseNamedObjects\\Session\\%u", i );
241 pRtlCreateUnicodeStringFromAsciiz(&str, name );
242 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
243 pRtlFreeUnicodeString(&str);
244 if (!status && is_correct_dir( dir, objname )) goto done;
245 if (!status) pNtClose( dir );
246 }
247 dir = 0;
248
249 done:
250 pNtClose( h );
251 return dir;
252 }
253
254 static void test_name_collisions(void)
255 {
256 NTSTATUS status;
257 UNICODE_STRING str;
258 OBJECT_ATTRIBUTES attr;
259 HANDLE dir, h, h1, h2;
260 DWORD winerr;
261 LARGE_INTEGER size;
262
263 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
264 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
265 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_COLLISION)
266 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
267
268 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_EXISTS)
269 pNtClose(h);
270 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
271 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
272 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
273 pRtlFreeUnicodeString(&str);
274
275 pRtlCreateUnicodeStringFromAsciiz(&str, "\\??\\PIPE\\om.c-mutant");
276 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
277 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_OBJECT_PATH_NOT_FOUND,
278 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
279 pRtlFreeUnicodeString(&str);
280
281 if (!(dir = get_base_dir()))
282 {
283 win_skip( "couldn't find the BaseNamedObjects dir\n" );
284 return;
285 }
286 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
287 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
288 h = CreateMutexA(NULL, FALSE, "om.c-test");
289 ok(h != 0, "CreateMutexA failed got ret=%p (%d)\n", h, GetLastError());
290 status = pNtCreateMutant(&h1, GENERIC_ALL, &attr, FALSE);
291 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
292 "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
293 h2 = CreateMutexA(NULL, FALSE, "om.c-test");
294 winerr = GetLastError();
295 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
296 "CreateMutexA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
297 pNtClose(h);
298 pNtClose(h1);
299 pNtClose(h2);
300
301 h = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
302 ok(h != 0, "CreateEventA failed got ret=%p (%d)\n", h, GetLastError());
303 status = pNtCreateEvent(&h1, GENERIC_ALL, &attr, FALSE, FALSE);
304 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
305 "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
306 h2 = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
307 winerr = GetLastError();
308 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
309 "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
310 pNtClose(h);
311 pNtClose(h1);
312 pNtClose(h2);
313
314 h = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
315 ok(h != 0, "CreateSemaphoreA failed got ret=%p (%d)\n", h, GetLastError());
316 status = pNtCreateSemaphore(&h1, GENERIC_ALL, &attr, 1, 2);
317 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
318 "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
319 h2 = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
320 winerr = GetLastError();
321 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
322 "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
323 pNtClose(h);
324 pNtClose(h1);
325 pNtClose(h2);
326
327 h = pCreateWaitableTimerA(NULL, TRUE, "om.c-test");
328 ok(h != 0, "CreateWaitableTimerA failed got ret=%p (%d)\n", h, GetLastError());
329 status = pNtCreateTimer(&h1, GENERIC_ALL, &attr, NotificationTimer);
330 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
331 "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
332 h2 = pCreateWaitableTimerA(NULL, TRUE, "om.c-test");
333 winerr = GetLastError();
334 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
335 "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
336 pNtClose(h);
337 pNtClose(h1);
338 pNtClose(h2);
339
340 h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
341 ok(h != 0, "CreateFileMappingA failed got ret=%p (%d)\n", h, GetLastError());
342 size.u.LowPart = 256;
343 size.u.HighPart = 0;
344 status = pNtCreateSection(&h1, SECTION_MAP_WRITE, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
345 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
346 "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
347 h2 = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
348 winerr = GetLastError();
349 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
350 "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
351 pNtClose(h);
352 pNtClose(h1);
353 pNtClose(h2);
354
355 pRtlFreeUnicodeString(&str);
356 pNtClose(dir);
357 }
358
359 static void test_directory(void)
360 {
361 NTSTATUS status;
362 UNICODE_STRING str;
363 OBJECT_ATTRIBUTES attr;
364 HANDLE dir, dir1, h;
365 BOOL is_nt4;
366
367 /* No name and/or no attributes */
368 status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
369 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
370 "NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
371 status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
372 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
373 "NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
374
375 status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL);
376 ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08x)\n", status);
377 pNtClose(h);
378 status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL);
379 ok(status == STATUS_INVALID_PARAMETER,
380 "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
381
382 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
383 DIR_TEST_CREATE_SUCCESS(&dir)
384 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
385
386 /* Bad name */
387 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
388
389 pRtlCreateUnicodeStringFromAsciiz(&str, "");
390 DIR_TEST_CREATE_SUCCESS(&h)
391 pNtClose(h);
392 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
393 pRtlFreeUnicodeString(&str);
394 pNtClose(dir);
395
396 DIR_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD)
397 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID)
398 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID)
399 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID)
400 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
401
402 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
403 DIR_TEST_CREATE_SUCCESS(&h)
404 DIR_TEST_OPEN_SUCCESS(&dir1)
405 pRtlFreeUnicodeString(&str);
406 pNtClose(h);
407 pNtClose(dir1);
408
409
410 /* Use of root directory */
411
412 /* Can't use symlinks as a directory */
413 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local");
414 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
415 status = pNtOpenSymbolicLinkObject(&dir, SYMBOLIC_LINK_QUERY, &attr);
416 is_nt4 = (status == STATUS_OBJECT_NAME_NOT_FOUND); /* nt4 doesn't have Local\\ symlink */
417 if (!is_nt4)
418 {
419 WCHAR buffer[256];
420 ULONG len, full_len;
421
422 ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08x)\n", status);
423 pRtlFreeUnicodeString(&str);
424 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
425 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
426 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH)
427 pRtlFreeUnicodeString(&str);
428
429 str.Buffer = buffer;
430 str.MaximumLength = sizeof(buffer);
431 len = 0xdeadbeef;
432 memset( buffer, 0xaa, sizeof(buffer) );
433 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
434 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08x\n", status );
435 if (status != STATUS_SUCCESS)
436 goto error;
437 full_len = str.Length + sizeof(WCHAR);
438 ok( len == full_len, "bad length %u/%u\n", len, full_len );
439 if (len == full_len)
440 ok( buffer[len / sizeof(WCHAR) - 1] == 0, "no terminating null\n" );
441
442 str.MaximumLength = str.Length;
443 len = 0xdeadbeef;
444 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
445 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08x\n", status );
446 ok( len == full_len, "bad length %u/%u\n", len, full_len );
447
448 str.MaximumLength = 0;
449 len = 0xdeadbeef;
450 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
451 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08x\n", status );
452 ok( len == full_len, "bad length %u/%u\n", len, full_len );
453
454 str.MaximumLength = str.Length + sizeof(WCHAR);
455 len = 0xdeadbeef;
456 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
457 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08x\n", status );
458 ok( len == full_len, "bad length %u/%u\n", len, full_len );
459
460 error:
461 pNtClose(dir);
462 }
463
464 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
465 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
466 DIR_TEST_OPEN_SUCCESS(&dir)
467 pRtlFreeUnicodeString(&str);
468
469 InitializeObjectAttributes(&attr, NULL, 0, dir, NULL);
470 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_NAME_INVALID)
471
472 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
473 DIR_TEST_CREATE_OPEN_SUCCESS(h, "")
474 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
475 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD)
476 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
477 DIR_TEST_CREATE_OPEN_FAILURE(&h, "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
478
479 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
480 DIR_TEST_CREATE_SUCCESS(&dir1)
481 DIR_TEST_OPEN_SUCCESS(&h)
482 pRtlFreeUnicodeString(&str);
483
484 pNtClose(h);
485 pNtClose(dir1);
486 pNtClose(dir);
487
488 /* Nested directories */
489 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
490 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
491 DIR_TEST_OPEN_SUCCESS(&dir)
492 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
493 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
494 pRtlFreeUnicodeString(&str);
495 pNtClose(dir);
496
497 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
498 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
499 DIR_TEST_CREATE_SUCCESS(&dir)
500 pRtlFreeUnicodeString(&str);
501 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test\\one more level");
502 DIR_TEST_CREATE_SUCCESS(&h)
503 pRtlFreeUnicodeString(&str);
504 pNtClose(h);
505 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
506 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
507 DIR_TEST_CREATE_SUCCESS(&h)
508 pRtlFreeUnicodeString(&str);
509 pNtClose(h);
510
511 pNtClose(dir);
512
513 if (!is_nt4)
514 {
515 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
516 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Global\\om.c-test");
517 DIR_TEST_CREATE_SUCCESS(&dir)
518 pRtlFreeUnicodeString(&str);
519 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local\\om.c-test\\one more level");
520 DIR_TEST_CREATE_SUCCESS(&h)
521 pRtlFreeUnicodeString(&str);
522 pNtClose(h);
523 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
524 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
525 DIR_TEST_CREATE_SUCCESS(&dir)
526 pRtlFreeUnicodeString(&str);
527 pNtClose(h);
528 pNtClose(dir);
529 }
530
531 /* Create other objects using RootDirectory */
532
533 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
534 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
535 DIR_TEST_OPEN_SUCCESS(&dir)
536 pRtlFreeUnicodeString(&str);
537 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
538
539 /* Test invalid paths */
540 pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant");
541 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
542 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
543 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
544 pRtlFreeUnicodeString(&str);
545 pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant\\");
546 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
547 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
548 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
549 pRtlFreeUnicodeString(&str);
550
551 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c\\-mutant");
552 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
553 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
554 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
555 pRtlFreeUnicodeString(&str);
556
557 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-mutant");
558 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
559 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
560 pRtlFreeUnicodeString(&str);
561 pNtClose(h);
562
563 pNtClose(dir);
564 }
565
566 #define SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e2) \
567 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
568 pRtlCreateUnicodeStringFromAsciiz(&target, t);\
569 status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\
570 ok(status == e || status == e2, \
571 "NtCreateSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
572 status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\
573 ok(status == e || status == e2, \
574 "NtOpenSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
575 pRtlFreeUnicodeString(&target);\
576 pRtlFreeUnicodeString(&str);
577
578 #define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e)
579
580 static void test_symboliclink(void)
581 {
582 NTSTATUS status;
583 UNICODE_STRING str, target;
584 OBJECT_ATTRIBUTES attr;
585 HANDLE dir, link, h;
586 IO_STATUS_BLOCK iosb;
587
588 /* No name and/or no attributes */
589 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
590 SYMLNK_TEST_CREATE_OPEN_FAILURE2(NULL, "", "", STATUS_ACCESS_VIOLATION, STATUS_INVALID_PARAMETER)
591
592 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL);
593 ok(status == STATUS_ACCESS_VIOLATION,
594 "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
595 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL);
596 ok(status == STATUS_INVALID_PARAMETER,
597 "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
598
599 /* No attributes */
600 pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
601 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, &target);
602 ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_VIOLATION, /* nt4 */
603 "NtCreateSymbolicLinkObject failed(%08x)\n", status);
604 pRtlFreeUnicodeString(&target);
605 if (!status) pNtClose(h);
606
607 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
608 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
609 ok(status == STATUS_INVALID_PARAMETER ||
610 broken(status == STATUS_SUCCESS), /* nt4 */
611 "NtCreateSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
612 if (!status) pNtClose(h);
613 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
614 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
615 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
616
617 /* Bad name */
618 pRtlCreateUnicodeStringFromAsciiz(&target, "anywhere");
619 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
620
621 pRtlCreateUnicodeStringFromAsciiz(&str, "");
622 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
623 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status);
624 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
625 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
626 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
627 pNtClose(link);
628 pRtlFreeUnicodeString(&str);
629
630 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
631 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target);
632 todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH,
633 "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
634 pRtlFreeUnicodeString(&str);
635 pRtlFreeUnicodeString(&target);
636
637 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", "->Somewhere", STATUS_OBJECT_PATH_SYNTAX_BAD)
638 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
639 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
640 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
641 SYMLNK_TEST_CREATE_OPEN_FAILURE2(&h, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere",
642 STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND)
643
644
645 /* Compound test */
646 if (!(dir = get_base_dir()))
647 {
648 win_skip( "couldn't find the BaseNamedObjects dir\n" );
649 return;
650 }
651
652 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
653 pRtlCreateUnicodeStringFromAsciiz(&str, "test-link");
654 pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
655 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
656 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status);
657 pRtlFreeUnicodeString(&str);
658 pRtlFreeUnicodeString(&target);
659
660 pRtlCreateUnicodeStringFromAsciiz(&str, "test-link\\NUL");
661 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
662 ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08x)\n", status);
663 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE);
664 ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08x)\n", status);
665 pRtlFreeUnicodeString(&str);
666
667 pNtClose(h);
668 pNtClose(link);
669 pNtClose(dir);
670 }
671
672 static void test_query_object(void)
673 {
674 static const WCHAR name[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',
675 '\\','t','e','s','t','_','e','v','e','n','t'};
676 static const WCHAR type_event[] = {'E','v','e','n','t'};
677 static const WCHAR type_file[] = {'F','i','l','e'};
678 static const WCHAR type_iocompletion[] = {'I','o','C','o','m','p','l','e','t','i','o','n'};
679 static const WCHAR type_directory[] = {'D','i','r','e','c','t','o','r','y'};
680 static const WCHAR type_section[] = {'S','e','c','t','i','o','n'};
681 HANDLE handle;
682 char buffer[1024];
683 NTSTATUS status;
684 ULONG len, expected_len;
685 UNICODE_STRING *str;
686 char dir[MAX_PATH], tmp_path[MAX_PATH], file1[MAX_PATH + 16];
687 LARGE_INTEGER size;
688
689 handle = CreateEventA( NULL, FALSE, FALSE, "test_event" );
690
691 len = 0;
692 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
693 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
694 ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
695
696 len = 0;
697 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, 0, &len );
698 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
699 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
700
701 len = 0;
702 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
703 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
704 ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
705
706 len = 0;
707 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(OBJECT_TYPE_INFORMATION), &len );
708 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
709 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
710
711 len = 0;
712 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
713 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
714 ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
715 str = (UNICODE_STRING *)buffer;
716 ok( sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR) == len, "unexpected len %u\n", len );
717 ok( str->Length >= sizeof(name), "unexpected len %u\n", str->Length );
718 /* there can be a \\Sessions prefix in the name */
719 ok( !memcmp( str->Buffer + (str->Length - sizeof(name)) / sizeof(WCHAR), name, sizeof(name) ),
720 "wrong name %s\n", wine_dbgstr_w(str->Buffer) );
721
722 len -= sizeof(WCHAR);
723 status = pNtQueryObject( handle, ObjectNameInformation, buffer, len, &len );
724 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
725 ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
726
727 len = 0;
728 memset( buffer, 0, sizeof(buffer) );
729 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
730 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
731 ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
732 str = (UNICODE_STRING *)buffer;
733 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR), "unexpected len %u\n", len );
734 ok( str->Buffer && !memcmp( str->Buffer, type_event, sizeof(type_event) ),
735 "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
736
737 len -= sizeof(WCHAR);
738 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, len, &len );
739 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
740 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
741
742 pNtClose( handle );
743
744 handle = CreateEventA( NULL, FALSE, FALSE, NULL );
745 len = 0;
746 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
747 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
748 ok( len == sizeof(UNICODE_STRING), "unexpected len %u\n", len );
749 str = (UNICODE_STRING *)buffer;
750 ok( str->Length == 0, "unexpected len %u\n", len );
751 ok( str->Buffer == NULL, "unexpected ptr %p\n", str->Buffer );
752 pNtClose( handle );
753
754 GetWindowsDirectoryA( dir, MAX_PATH );
755 handle = CreateFileA( dir, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
756 FILE_FLAG_BACKUP_SEMANTICS, 0 );
757 len = 0;
758 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
759 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
760 ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
761 str = (UNICODE_STRING *)buffer;
762 expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR);
763 ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */
764 "unexpected len %u\n", len );
765 trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len );
766
767 len = 0;
768 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
769 ok( status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INSUFFICIENT_RESOURCES),
770 "NtQueryObject failed %x\n", status );
771 ok( len == expected_len || broken(!len || len == sizeof(UNICODE_STRING)),
772 "unexpected len %u\n", len );
773
774 len = 0;
775 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
776 ok( status == STATUS_BUFFER_OVERFLOW || broken(status == STATUS_INSUFFICIENT_RESOURCES
777 || status == STATUS_INFO_LENGTH_MISMATCH),
778 "NtQueryObject failed %x\n", status );
779 ok( len == expected_len || broken(!len),
780 "unexpected len %u\n", len );
781
782 len = 0;
783 memset( buffer, 0, sizeof(buffer) );
784 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
785 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
786 ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
787 str = (UNICODE_STRING *)buffer;
788 expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
789 ok( len >= expected_len, "unexpected len %u\n", len );
790 ok( str->Buffer && !memcmp( str->Buffer, type_file, sizeof(type_file) ),
791 "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
792
793 pNtClose( handle );
794
795 GetTempPathA(MAX_PATH, tmp_path);
796 GetTempFileNameA(tmp_path, "foo", 0, file1);
797 handle = CreateFileA(file1, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0);
798 len = 0;
799 memset( buffer, 0, sizeof(buffer) );
800 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
801 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
802 ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
803 str = (UNICODE_STRING *)buffer;
804 expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
805 ok( len >= expected_len, "unexpected len %u\n", len );
806 ok( str->Buffer && !memcmp( str->Buffer, type_file, sizeof(type_file) ),
807 "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
808 DeleteFileA( file1 );
809 pNtClose( handle );
810
811 status = pNtCreateIoCompletion( &handle, IO_COMPLETION_ALL_ACCESS, NULL, 0 );
812 ok( status == STATUS_SUCCESS, "NtCreateIoCompletion failed %x\n", status);
813 len = 0;
814 memset( buffer, 0, sizeof(buffer) );
815 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
816 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
817 ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
818 str = (UNICODE_STRING *)buffer;
819 expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
820 ok( len >= expected_len, "unexpected len %u\n", len );
821 ok( str->Buffer && !memcmp( str->Buffer, type_iocompletion, sizeof(type_iocompletion) ),
822 "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
823 pNtClose( handle );
824
825 status = pNtCreateDirectoryObject( &handle, DIRECTORY_QUERY, NULL );
826 ok(status == STATUS_SUCCESS, "Failed to create Directory %08x\n", status);
827 len = 0;
828 memset( buffer, 0, sizeof(buffer) );
829 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
830 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
831 ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
832 str = (UNICODE_STRING *)buffer;
833 expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
834 ok( len >= expected_len, "unexpected len %u\n", len );
835 ok( str->Buffer && !memcmp( str->Buffer, type_directory, sizeof(type_directory) ),
836 "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
837 pNtClose( handle );
838
839 size.u.LowPart = 256;
840 size.u.HighPart = 0;
841 status = pNtCreateSection( &handle, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
842 ok( status == STATUS_SUCCESS , "NtCreateSection returned %x\n", status );
843 len = 0;
844 memset( buffer, 0, sizeof(buffer) );
845 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
846 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
847 ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
848 str = (UNICODE_STRING *)buffer;
849 expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
850 ok( len >= expected_len, "unexpected len %u\n", len );
851 ok( str->Buffer && !memcmp( str->Buffer, type_section, sizeof(type_section) ),
852 "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
853 pNtClose( handle );
854 }
855
856 static void test_type_mismatch(void)
857 {
858 HANDLE h;
859 NTSTATUS res;
860 OBJECT_ATTRIBUTES attr;
861
862 attr.Length = sizeof(attr);
863 attr.RootDirectory = 0;
864 attr.ObjectName = NULL;
865 attr.Attributes = 0;
866 attr.SecurityDescriptor = NULL;
867 attr.SecurityQualityOfService = NULL;
868
869 res = pNtCreateEvent( &h, 0, &attr, 0, 0 );
870 ok(!res, "can't create event: %x\n", res);
871
872 res = pNtReleaseSemaphore( h, 30, NULL );
873 ok(res == STATUS_OBJECT_TYPE_MISMATCH, "expected 0xc0000024, got %x\n", res);
874
875 pNtClose( h );
876 }
877
878 static void test_event(void)
879 {
880 HANDLE Event;
881 HANDLE Event2;
882 NTSTATUS status;
883 UNICODE_STRING str;
884 OBJECT_ATTRIBUTES attr;
885 EVENT_BASIC_INFORMATION info;
886 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};
887
888 pRtlInitUnicodeString(&str, eventName);
889 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
890
891 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, 1, 0);
892 ok( status == STATUS_SUCCESS, "NtCreateEvent failed %08x\n", status );
893
894 status = pNtPulseEvent(Event, NULL);
895 ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
896
897 status = pNtQueryEvent(Event, EventBasicInformation, &info, sizeof(info), NULL);
898 ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
899 ok( info.EventType == 1 && info.EventState == 0,
900 "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
901
902 status = pNtOpenEvent(&Event2, GENERIC_ALL, &attr);
903 ok( status == STATUS_SUCCESS, "NtOpenEvent failed %08x\n", status );
904
905 pNtClose(Event);
906
907 status = pNtQueryEvent(Event2, EventBasicInformation, &info, sizeof(info), NULL);
908 ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
909 ok( info.EventType == 1 && info.EventState == 0,
910 "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
911
912 pNtClose(Event2);
913 }
914
915 static const WCHAR keyed_nameW[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',
916 '\\','W','i','n','e','T','e','s','t','E','v','e','n','t',0};
917
918 static DWORD WINAPI keyed_event_thread( void *arg )
919 {
920 HANDLE handle;
921 NTSTATUS status;
922 LARGE_INTEGER timeout;
923 OBJECT_ATTRIBUTES attr;
924 UNICODE_STRING str;
925 ULONG_PTR i;
926
927 attr.Length = sizeof(attr);
928 attr.RootDirectory = 0;
929 attr.ObjectName = &str;
930 attr.Attributes = 0;
931 attr.SecurityDescriptor = NULL;
932 attr.SecurityQualityOfService = NULL;
933 RtlInitUnicodeString( &str, keyed_nameW );
934
935 status = pNtOpenKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr );
936 ok( !status, "NtOpenKeyedEvent failed %x\n", status );
937
938 for (i = 0; i < 20; i++)
939 {
940 if (i & 1)
941 status = pNtWaitForKeyedEvent( handle, (void *)(i * 2), 0, NULL );
942 else
943 status = pNtReleaseKeyedEvent( handle, (void *)(i * 2), 0, NULL );
944 ok( status == STATUS_SUCCESS, "%li: failed %x\n", i, status );
945 Sleep( 20 - i );
946 }
947
948 status = pNtReleaseKeyedEvent( handle, (void *)0x1234, 0, NULL );
949 ok( status == STATUS_SUCCESS, "NtReleaseKeyedEvent %x\n", status );
950
951 timeout.QuadPart = -10000;
952 status = pNtWaitForKeyedEvent( handle, (void *)0x5678, 0, &timeout );
953 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
954 status = pNtReleaseKeyedEvent( handle, (void *)0x9abc, 0, &timeout );
955 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
956
957 NtClose( handle );
958 return 0;
959 }
960
961 static void test_keyed_events(void)
962 {
963 OBJECT_ATTRIBUTES attr;
964 UNICODE_STRING str;
965 HANDLE handle, event, thread;
966 NTSTATUS status;
967 LARGE_INTEGER timeout;
968 ULONG_PTR i;
969
970 if (!pNtCreateKeyedEvent)
971 {
972 win_skip( "Keyed events not supported\n" );
973 return;
974 }
975
976 attr.Length = sizeof(attr);
977 attr.RootDirectory = 0;
978 attr.ObjectName = &str;
979 attr.Attributes = 0;
980 attr.SecurityDescriptor = NULL;
981 attr.SecurityQualityOfService = NULL;
982 RtlInitUnicodeString( &str, keyed_nameW );
983
984 status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS | SYNCHRONIZE, &attr, 0 );
985 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
986
987 status = WaitForSingleObject( handle, 1000 );
988 ok( status == 0, "WaitForSingleObject %x\n", status );
989
990 timeout.QuadPart = -100000;
991 status = pNtWaitForKeyedEvent( handle, (void *)255, 0, &timeout );
992 ok( status == STATUS_INVALID_PARAMETER_1, "NtWaitForKeyedEvent %x\n", status );
993 status = pNtReleaseKeyedEvent( handle, (void *)255, 0, &timeout );
994 ok( status == STATUS_INVALID_PARAMETER_1, "NtReleaseKeyedEvent %x\n", status );
995
996 status = pNtWaitForKeyedEvent( handle, (void *)254, 0, &timeout );
997 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
998 status = pNtReleaseKeyedEvent( handle, (void *)254, 0, &timeout );
999 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1000
1001 status = pNtWaitForKeyedEvent( handle, NULL, 0, &timeout );
1002 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1003 status = pNtReleaseKeyedEvent( handle, NULL, 0, &timeout );
1004 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1005
1006 status = pNtWaitForKeyedEvent( (HANDLE)0xdeadbeef, (void *)9, 0, &timeout );
1007 ok( status == STATUS_INVALID_PARAMETER_1, "NtWaitForKeyedEvent %x\n", status );
1008 status = pNtReleaseKeyedEvent( (HANDLE)0xdeadbeef, (void *)9, 0, &timeout );
1009 ok( status == STATUS_INVALID_PARAMETER_1, "NtReleaseKeyedEvent %x\n", status );
1010
1011 status = pNtWaitForKeyedEvent( (HANDLE)0xdeadbeef, (void *)8, 0, &timeout );
1012 ok( status == STATUS_INVALID_HANDLE, "NtWaitForKeyedEvent %x\n", status );
1013 status = pNtReleaseKeyedEvent( (HANDLE)0xdeadbeef, (void *)8, 0, &timeout );
1014 ok( status == STATUS_INVALID_HANDLE, "NtReleaseKeyedEvent %x\n", status );
1015
1016 thread = CreateThread( NULL, 0, keyed_event_thread, 0, 0, NULL );
1017 for (i = 0; i < 20; i++)
1018 {
1019 if (i & 1)
1020 status = pNtReleaseKeyedEvent( handle, (void *)(i * 2), 0, NULL );
1021 else
1022 status = pNtWaitForKeyedEvent( handle, (void *)(i * 2), 0, NULL );
1023 ok( status == STATUS_SUCCESS, "%li: failed %x\n", i, status );
1024 Sleep( i );
1025 }
1026 status = pNtWaitForKeyedEvent( handle, (void *)0x1234, 0, &timeout );
1027 ok( status == STATUS_SUCCESS, "NtWaitForKeyedEvent %x\n", status );
1028 status = pNtWaitForKeyedEvent( handle, (void *)0x5678, 0, &timeout );
1029 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1030 status = pNtReleaseKeyedEvent( handle, (void *)0x9abc, 0, &timeout );
1031 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1032
1033 ok( WaitForSingleObject( thread, 30000 ) == 0, "wait failed\n" );
1034
1035 NtClose( handle );
1036
1037 /* test access rights */
1038
1039 status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_WAIT, &attr, 0 );
1040 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1041 status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1042 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1043 status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1044 ok( status == STATUS_ACCESS_DENIED, "NtReleaseKeyedEvent %x\n", status );
1045 NtClose( handle );
1046
1047 status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_WAKE, &attr, 0 );
1048 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1049 status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1050 ok( status == STATUS_ACCESS_DENIED, "NtWaitForKeyedEvent %x\n", status );
1051 status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1052 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1053 NtClose( handle );
1054
1055 status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr, 0 );
1056 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1057 status = WaitForSingleObject( handle, 1000 );
1058 ok( status == WAIT_FAILED && GetLastError() == ERROR_ACCESS_DENIED,
1059 "WaitForSingleObject %x err %u\n", status, GetLastError() );
1060 status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1061 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1062 status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1063 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1064 NtClose( handle );
1065
1066 /* GENERIC_READ gives wait access */
1067 status = pNtCreateKeyedEvent( &handle, GENERIC_READ, &attr, 0 );
1068 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1069 status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1070 ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
1071 status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1072 ok( status == STATUS_ACCESS_DENIED, "NtReleaseKeyedEvent %x\n", status );
1073 NtClose( handle );
1074
1075 /* GENERIC_WRITE gives wake access */
1076 status = pNtCreateKeyedEvent( &handle, GENERIC_WRITE, &attr, 0 );
1077 ok( !status, "NtCreateKeyedEvent failed %x\n", status );
1078 status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
1079 ok( status == STATUS_ACCESS_DENIED, "NtWaitForKeyedEvent %x\n", status );
1080 status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
1081 ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
1082
1083 /* it's not an event */
1084 status = pNtPulseEvent( handle, NULL );
1085 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtPulseEvent %x\n", status );
1086
1087 status = pNtCreateEvent( &event, GENERIC_ALL, &attr, FALSE, FALSE );
1088 ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
1089 "CreateEvent %x\n", status );
1090
1091 NtClose( handle );
1092
1093 status = pNtCreateEvent( &event, GENERIC_ALL, &attr, FALSE, FALSE );
1094 ok( status == 0, "CreateEvent %x\n", status );
1095 status = pNtWaitForKeyedEvent( event, (void *)8, 0, &timeout );
1096 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtWaitForKeyedEvent %x\n", status );
1097 status = pNtReleaseKeyedEvent( event, (void *)8, 0, &timeout );
1098 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtReleaseKeyedEvent %x\n", status );
1099 NtClose( event );
1100 }
1101
1102 static void test_null_device(void)
1103 {
1104 OBJECT_ATTRIBUTES attr;
1105 IO_STATUS_BLOCK iosb;
1106 UNICODE_STRING str;
1107 NTSTATUS status;
1108 DWORD num_bytes;
1109 OVERLAPPED ov;
1110 char buf[64];
1111 HANDLE null;
1112 BOOL ret;
1113
1114 memset(buf, 0xAA, sizeof(buf));
1115 memset(&ov, 0, sizeof(ov));
1116 ov.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
1117
1118 pRtlCreateUnicodeStringFromAsciiz(&str, "\\Device\\Null");
1119 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
1120 status = pNtOpenSymbolicLinkObject(&null, SYMBOLIC_LINK_QUERY, &attr);
1121 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
1122 "expected STATUS_OBJECT_TYPE_MISMATCH, got %08x\n", status);
1123
1124 status = pNtOpenFile(&null, GENERIC_READ | GENERIC_WRITE, &attr, &iosb,
1125 FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
1126 ok(status == STATUS_SUCCESS,
1127 "expected STATUS_SUCCESS, got %08x\n", status);
1128
1129 SetLastError(0xdeadbeef);
1130 ret = WriteFile(null, buf, sizeof(buf), &num_bytes, NULL);
1131 ok(!ret, "WriteFile unexpectedly succeeded\n");
1132 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1133 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1134
1135 SetLastError(0xdeadbeef);
1136 ret = ReadFile(null, buf, sizeof(buf), &num_bytes, NULL);
1137 ok(!ret, "ReadFile unexpectedly succeeded\n");
1138 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1139 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1140
1141 num_bytes = 0xdeadbeef;
1142 SetLastError(0xdeadbeef);
1143 ret = WriteFile(null, buf, sizeof(buf), &num_bytes, &ov);
1144 if (ret || GetLastError() != ERROR_IO_PENDING)
1145 {
1146 ok(ret, "WriteFile failed with error %u\n", GetLastError());
1147 }
1148 else
1149 {
1150 num_bytes = 0xdeadbeef;
1151 ret = GetOverlappedResult(null, &ov, &num_bytes, TRUE);
1152 ok(ret, "GetOverlappedResult failed with error %u\n", GetLastError());
1153 }
1154 ok(num_bytes == sizeof(buf), "expected num_bytes = %u, got %u\n",
1155 (DWORD)sizeof(buf), num_bytes);
1156
1157 num_bytes = 0xdeadbeef;
1158 SetLastError(0xdeadbeef);
1159 ret = ReadFile(null, buf, sizeof(buf), &num_bytes, &ov);
1160 if (ret || GetLastError() != ERROR_IO_PENDING)
1161 {
1162 ok(!ret, "ReadFile unexpectedly succeeded\n");
1163 }
1164 else
1165 {
1166 num_bytes = 0xdeadbeef;
1167 ret = GetOverlappedResult(null, &ov, &num_bytes, TRUE);
1168 ok(!ret, "GetOverlappedResult unexpectedly succeeded\n");
1169 }
1170 ok(GetLastError() == ERROR_HANDLE_EOF,
1171 "expected ERROR_HANDLE_EOF, got %u\n", GetLastError());
1172
1173 pNtClose(null);
1174
1175 null = CreateFileA("\\\\.\\Null", GENERIC_READ | GENERIC_WRITE,
1176 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1177 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1178 ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
1179 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
1180 "expected ERROR_FILE_NOT_FOUND, got %u\n", GetLastError());
1181
1182 null = CreateFileA("\\\\.\\Device\\Null", GENERIC_READ | GENERIC_WRITE,
1183 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1184 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1185 ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
1186 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
1187 "expected ERROR_PATH_NOT_FOUND, got %u\n", GetLastError());
1188
1189 pRtlFreeUnicodeString(&str);
1190 CloseHandle(ov.hEvent);
1191 }
1192
1193 START_TEST(om)
1194 {
1195 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
1196 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
1197
1198 if (!hntdll)
1199 {
1200 skip("not running on NT, skipping test\n");
1201 return;
1202 }
1203
1204 pCreateWaitableTimerA = (void *)GetProcAddress(hkernel32, "CreateWaitableTimerA");
1205
1206 pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
1207 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
1208 pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent");
1209 pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant");
1210 pNtOpenEvent = (void *)GetProcAddress(hntdll, "NtOpenEvent");
1211 pNtQueryEvent = (void *)GetProcAddress(hntdll, "NtQueryEvent");
1212 pNtPulseEvent = (void *)GetProcAddress(hntdll, "NtPulseEvent");
1213 pNtOpenMutant = (void *)GetProcAddress(hntdll, "NtOpenMutant");
1214 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
1215 pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
1216 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
1217 pNtCreateNamedPipeFile = (void *)GetProcAddress(hntdll, "NtCreateNamedPipeFile");
1218 pNtOpenDirectoryObject = (void *)GetProcAddress(hntdll, "NtOpenDirectoryObject");
1219 pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject");
1220 pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject");
1221 pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject");
1222 pNtQuerySymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject");
1223 pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
1224 pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer");
1225 pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection");
1226 pNtQueryObject = (void *)GetProcAddress(hntdll, "NtQueryObject");
1227 pNtReleaseSemaphore = (void *)GetProcAddress(hntdll, "NtReleaseSemaphore");
1228 pNtCreateKeyedEvent = (void *)GetProcAddress(hntdll, "NtCreateKeyedEvent");
1229 pNtOpenKeyedEvent = (void *)GetProcAddress(hntdll, "NtOpenKeyedEvent");
1230 pNtWaitForKeyedEvent = (void *)GetProcAddress(hntdll, "NtWaitForKeyedEvent");
1231 pNtReleaseKeyedEvent = (void *)GetProcAddress(hntdll, "NtReleaseKeyedEvent");
1232 pNtCreateIoCompletion = (void *)GetProcAddress(hntdll, "NtCreateIoCompletion");
1233
1234 test_case_sensitive();
1235 test_namespace_pipe();
1236 test_name_collisions();
1237 test_directory();
1238 test_symboliclink();
1239 test_query_object();
1240 test_type_mismatch();
1241 test_event();
1242 test_keyed_events();
1243 test_null_device();
1244 }