ntdll: Fix the prototype of NtDuplicateToken().
[wine.git] / dlls / ntdll / tests / om.c
blob6e5a9ef64b1fb2f202b49db7904d89a180bf1648
1 /*
2 * Unit test suite for object manager functions
4 * Copyright 2005 Robert Shearman
5 * Copyright 2005 Vitaliy Margolen
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "ntdll_test.h"
23 #include "winternl.h"
24 #include "winuser.h"
25 #include "ddk/wdm.h"
26 #include "stdio.h"
27 #include "winnt.h"
28 #include "stdlib.h"
30 static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
31 static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, EVENT_TYPE, BOOLEAN);
32 static NTSTATUS (WINAPI *pNtOpenEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES);
33 static NTSTATUS (WINAPI *pNtCreateJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
34 static NTSTATUS (WINAPI *pNtOpenJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
35 static NTSTATUS (WINAPI *pNtCreateKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG,
36 const UNICODE_STRING *, ULONG, PULONG );
37 static NTSTATUS (WINAPI *pNtOpenKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
38 static NTSTATUS (WINAPI *pNtDeleteKey)( HANDLE );
39 static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
40 ULONG, ULONG, ULONG, PLARGE_INTEGER );
41 static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN );
42 static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
43 static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG );
44 static NTSTATUS (WINAPI *pNtOpenSemaphore)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
45 static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE );
46 static NTSTATUS (WINAPI *pNtOpenTimer)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
47 static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER,
48 ULONG, ULONG, HANDLE );
49 static NTSTATUS (WINAPI *pNtOpenSection)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
50 static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG );
51 static NTSTATUS (WINAPI *pNtClose) ( HANDLE );
52 static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
53 ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, PLARGE_INTEGER );
54 static NTSTATUS (WINAPI *pNtOpenDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
55 static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
56 static NTSTATUS (WINAPI *pNtOpenSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
57 static NTSTATUS (WINAPI *pNtCreateSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PUNICODE_STRING);
58 static NTSTATUS (WINAPI *pNtQuerySymbolicLinkObject)(HANDLE,PUNICODE_STRING,PULONG);
59 static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG);
60 static NTSTATUS (WINAPI *pNtReleaseSemaphore)(HANDLE, ULONG, PULONG);
61 static NTSTATUS (WINAPI *pNtCreateKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG );
62 static NTSTATUS (WINAPI *pNtOpenKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES * );
63 static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG);
64 static NTSTATUS (WINAPI *pNtOpenIoCompletion)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
65 static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, void *, ULONG, FILE_INFORMATION_CLASS);
66 static NTSTATUS (WINAPI *pNtOpenProcess)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, const CLIENT_ID * );
67 static NTSTATUS (WINAPI *pNtCreateDebugObject)( HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *, ULONG );
68 static NTSTATUS (WINAPI *pNtGetNextThread)(HANDLE process, HANDLE thread, ACCESS_MASK access, ULONG attributes,
69 ULONG flags, HANDLE *handle);
70 static NTSTATUS (WINAPI *pNtOpenProcessToken)(HANDLE,DWORD,HANDLE*);
71 static NTSTATUS (WINAPI *pNtOpenThreadToken)(HANDLE,DWORD,BOOLEAN,HANDLE*);
72 static NTSTATUS (WINAPI *pNtDuplicateToken)(HANDLE,ACCESS_MASK,OBJECT_ATTRIBUTES*,BOOLEAN,TOKEN_TYPE,HANDLE*);
73 static NTSTATUS (WINAPI *pNtDuplicateObject)(HANDLE,HANDLE,HANDLE,HANDLE*,ACCESS_MASK,ULONG,ULONG);
74 static NTSTATUS (WINAPI *pNtCompareObjects)(HANDLE,HANDLE);
76 #define KEYEDEVENT_WAIT 0x0001
77 #define KEYEDEVENT_WAKE 0x0002
78 #define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x0003)
79 #define DESKTOP_ALL_ACCESS 0x01ff
81 #define check_unicode_string(a, b) check_unicode_string_(__LINE__, a, b)
82 static void check_unicode_string_( int line, const UNICODE_STRING *string, const WCHAR *expect )
84 size_t len = wcslen( expect ) * sizeof(WCHAR);
86 ok_(__FILE__, line)( !wcscmp( string->Buffer, expect ), "got string %s\n", debugstr_w( string->Buffer ));
87 ok_(__FILE__, line)( string->Length == len, "got length %u\n", string->Length );
88 ok_(__FILE__, line)( string->MaximumLength == len + sizeof(WCHAR), "got max length %u\n", string->MaximumLength );
91 static void test_case_sensitive (void)
93 NTSTATUS status;
94 OBJECT_ATTRIBUTES attr;
95 UNICODE_STRING str;
96 HANDLE Event, Mutant, h;
98 pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\test");
99 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
100 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
101 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08lx)\n", status);
103 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, NotificationEvent, FALSE);
104 ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH /* Vista+ */, "got %#lx\n", status);
106 pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\Test");
107 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
108 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, NotificationEvent, FALSE);
109 ok(status == STATUS_SUCCESS, "Failed to create Event(%08lx)\n", status);
111 pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\TEst");
112 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
113 status = pNtOpenMutant(&h, GENERIC_ALL, &attr);
114 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
115 "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
117 pNtClose(Mutant);
119 pRtlInitUnicodeString(&str, L"\\BASENamedObjects\\test");
120 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
121 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
122 ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH /* Vista+ */, "got %#lx\n", status);
124 status = pNtCreateEvent(&h, GENERIC_ALL, &attr, NotificationEvent, FALSE);
125 ok(status == STATUS_OBJECT_NAME_COLLISION,
126 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08lx)\n", status);
128 attr.Attributes = 0;
129 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
130 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
131 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status);
133 pNtClose(Event);
136 static void test_namespace_pipe(void)
138 OBJECT_ATTRIBUTES attr;
139 UNICODE_STRING str;
140 IO_STATUS_BLOCK iosb;
141 NTSTATUS status;
142 LARGE_INTEGER timeout;
143 HANDLE pipe, h;
145 timeout.QuadPart = -10000;
147 pRtlInitUnicodeString(&str, L"\\??\\PIPE\\test\\pipe");
148 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
149 status = pNtCreateNamedPipeFile((HANDLE *)0xdeadbee0, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
150 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
151 ok(status == STATUS_ACCESS_VIOLATION, "Failed to create NamedPipe(%08lx)\n", status);
153 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
154 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
155 ok(status == STATUS_SUCCESS, "Failed to create NamedPipe(%08lx)\n", status);
157 h = (HANDLE)0xdeadbeef;
158 status = pNtCreateNamedPipeFile(&h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
159 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
160 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
161 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08lx)\n", status);
162 ok( !h || broken(h == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", h );
164 pRtlInitUnicodeString(&str, L"\\??\\PIPE\\TEST\\PIPE");
165 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
166 h = (HANDLE)0xdeadbeef;
167 status = pNtCreateNamedPipeFile(&h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
168 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
169 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
170 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08lx)\n", status);
171 ok( !h || broken(h == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", h );
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 (%lu)\n", GetLastError());
176 pNtClose(h);
178 pRtlInitUnicodeString(&str, L"\\??\\pipe\\test\\pipe");
179 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
180 h = (HANDLE)0xdeadbeef;
181 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
182 ok(status == STATUS_OBJECT_PATH_NOT_FOUND ||
183 status == STATUS_PIPE_NOT_AVAILABLE ||
184 status == STATUS_OBJECT_NAME_INVALID || /* vista */
185 status == STATUS_OBJECT_NAME_NOT_FOUND, /* win8 */
186 "NtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status);
187 ok( !h || broken(h == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", h );
189 pRtlInitUnicodeString(&str, L"\\??\\pipe\\test");
190 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
191 h = (HANDLE)0xdeadbeef;
192 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
193 ok(status == STATUS_OBJECT_NAME_NOT_FOUND ||
194 status == STATUS_OBJECT_NAME_INVALID, /* vista */
195 "NtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08lx)\n", status);
196 ok( !h || broken(h == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", h );
198 str.Length -= 4 * sizeof(WCHAR);
199 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
200 ok(status == STATUS_SUCCESS, "NtOpenFile should have succeeded got %08lx\n", status);
201 pNtClose( h );
203 str.Length -= sizeof(WCHAR);
204 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
205 ok(status == STATUS_SUCCESS, "NtOpenFile should have succeeded got %08lx\n", status);
206 pNtClose( h );
208 pNtClose(pipe);
211 #define check_create_open_dir(parent, name, status) check_create_open_dir_(__LINE__, parent, name, status)
212 static void check_create_open_dir_( int line, HANDLE parent, const WCHAR *name, NTSTATUS expect )
214 OBJECT_ATTRIBUTES attr;
215 UNICODE_STRING str;
216 NTSTATUS status;
217 HANDLE h;
219 RtlInitUnicodeString( &str, name );
220 InitializeObjectAttributes( &attr, &str, 0, parent, NULL );
221 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
222 ok_(__FILE__, line)( status == expect, "NtCreateDirectoryObject(%s) got %08lx\n", debugstr_w(name), status );
223 if (!status) pNtClose( h );
225 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
226 ok_(__FILE__, line)( status == expect, "NtOpenDirectoryObject(%s) got %08lx\n", debugstr_w(name), status );
227 if (!status) pNtClose( h );
230 static BOOL is_correct_dir( HANDLE dir, const WCHAR *name )
232 NTSTATUS status;
233 UNICODE_STRING str;
234 OBJECT_ATTRIBUTES attr;
235 HANDLE h = 0;
237 RtlInitUnicodeString( &str, name );
238 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
239 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
240 if (h) pNtClose( h );
241 return (status == STATUS_OBJECT_NAME_EXISTS);
244 /* return a handle to the BaseNamedObjects dir where kernel32 objects get created */
245 static HANDLE get_base_dir(void)
247 static const WCHAR objname[] = L"om.c_get_base_dir_obj";
248 NTSTATUS status;
249 UNICODE_STRING str;
250 OBJECT_ATTRIBUTES attr;
251 HANDLE dir, h;
252 WCHAR name[40];
254 h = CreateMutexW( NULL, FALSE, objname );
255 ok(h != 0, "CreateMutexA failed got ret=%p (%ld)\n", h, GetLastError());
256 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
258 swprintf( name, ARRAY_SIZE(name), L"\\BaseNamedObjects\\Session\\%u", NtCurrentTeb()->Peb->SessionId );
259 RtlInitUnicodeString( &str, name );
260 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
261 ok(!status, "got %#lx\n", status);
262 ok(is_correct_dir( dir, objname ), "wrong dir\n");
264 pNtClose( h );
265 return dir;
268 static void test_name_collisions(void)
270 NTSTATUS status;
271 UNICODE_STRING str;
272 OBJECT_ATTRIBUTES attr;
273 HANDLE dir, h, h1, h2;
274 DWORD winerr;
275 LARGE_INTEGER size, timeout;
276 IO_STATUS_BLOCK iosb;
278 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
279 RtlInitUnicodeString(&str, L"\\");
280 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
281 ok( status == STATUS_OBJECT_NAME_COLLISION, "NtCreateDirectoryObject got %08lx\n", status );
282 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
284 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
285 ok( status == STATUS_OBJECT_NAME_EXISTS, "NtCreateDirectoryObject got %08lx\n", status );
286 pNtClose(h);
287 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
288 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
289 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
291 RtlInitUnicodeString(&str, L"\\??\\PIPE\\om.c-mutant");
292 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
293 todo_wine ok(status == STATUS_OBJECT_PATH_NOT_FOUND, "got %#lx\n", status);
295 dir = get_base_dir();
296 RtlInitUnicodeString(&str, L"om.c-test");
297 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
298 h = CreateMutexA(NULL, FALSE, "om.c-test");
299 ok(h != 0, "CreateMutexA failed got ret=%p (%ld)\n", h, GetLastError());
300 status = pNtCreateMutant(&h1, GENERIC_ALL, &attr, FALSE);
301 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
302 "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status);
303 h2 = CreateMutexA(NULL, FALSE, "om.c-test");
304 winerr = GetLastError();
305 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
306 "CreateMutexA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr);
307 pNtClose(h);
308 pNtClose(h1);
309 pNtClose(h2);
311 h = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
312 ok(h != 0, "CreateEventA failed got ret=%p (%ld)\n", h, GetLastError());
313 status = pNtCreateEvent(&h1, GENERIC_ALL, &attr, NotificationEvent, FALSE);
314 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
315 "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status);
316 h2 = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
317 winerr = GetLastError();
318 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
319 "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr);
320 pNtClose(h);
321 pNtClose(h1);
322 pNtClose(h2);
324 h = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
325 ok(h != 0, "CreateSemaphoreA failed got ret=%p (%ld)\n", h, GetLastError());
326 status = pNtCreateSemaphore(&h1, GENERIC_ALL, &attr, 1, 2);
327 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
328 "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status);
329 h2 = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
330 winerr = GetLastError();
331 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
332 "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr);
333 pNtClose(h);
334 pNtClose(h1);
335 pNtClose(h2);
337 h = CreateWaitableTimerA(NULL, TRUE, "om.c-test");
338 ok(h != 0, "CreateWaitableTimerA failed got ret=%p (%ld)\n", h, GetLastError());
339 status = pNtCreateTimer(&h1, GENERIC_ALL, &attr, NotificationTimer);
340 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
341 "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status);
342 h2 = CreateWaitableTimerA(NULL, TRUE, "om.c-test");
343 winerr = GetLastError();
344 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
345 "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr);
346 pNtClose(h);
347 pNtClose(h1);
348 pNtClose(h2);
350 h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
351 ok(h != 0, "CreateFileMappingA failed got ret=%p (%ld)\n", h, GetLastError());
352 size.u.LowPart = 256;
353 size.u.HighPart = 0;
354 status = pNtCreateSection(&h1, SECTION_MAP_WRITE, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
355 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
356 "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status);
357 h2 = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
358 winerr = GetLastError();
359 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
360 "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr);
361 pNtClose(h);
362 pNtClose(h1);
363 pNtClose(h2);
365 pNtClose(dir);
367 RtlInitUnicodeString(&str, L"\\??\\PIPE\\named_pipe");
368 attr.RootDirectory = 0;
369 timeout.QuadPart = -10000;
370 status = pNtCreateNamedPipeFile( &h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
371 FILE_SHARE_READ|FILE_SHARE_WRITE,
372 FILE_OPEN, FILE_PIPE_FULL_DUPLEX,
373 FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
374 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "failed to create pipe %08lx\n", status);
376 memset( &iosb, 0xcc, sizeof(iosb) );
377 status = pNtCreateNamedPipeFile( &h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
378 FILE_SHARE_READ|FILE_SHARE_WRITE,
379 FILE_OPEN_IF, FILE_PIPE_FULL_DUPLEX,
380 FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
381 ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
382 ok( iosb.Status == STATUS_SUCCESS, "wrong status %08lx\n", status);
383 ok( iosb.Information == FILE_CREATED, "wrong info %Ix\n", iosb.Information );
384 pNtClose( h );
386 memset( &iosb, 0xcc, sizeof(iosb) );
387 status = pNtCreateNamedPipeFile( &h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
388 FILE_SHARE_READ|FILE_SHARE_WRITE,
389 FILE_CREATE, FILE_PIPE_FULL_DUPLEX,
390 FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
391 ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
392 ok( iosb.Status == STATUS_SUCCESS, "wrong status %08lx\n", status);
393 ok( iosb.Information == FILE_CREATED, "wrong info %Ix\n", iosb.Information );
395 memset( &iosb, 0xcc, sizeof(iosb) );
396 status = pNtCreateNamedPipeFile( &h1, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
397 FILE_SHARE_READ|FILE_SHARE_WRITE,
398 FILE_OPEN, FILE_PIPE_FULL_DUPLEX,
399 FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
400 ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
401 ok( iosb.Status == STATUS_SUCCESS, "wrong status %08lx\n", status);
402 ok( iosb.Information == FILE_OPENED, "wrong info %Ix\n", iosb.Information );
403 pNtClose(h1);
405 memset( &iosb, 0xcc, sizeof(iosb) );
406 status = pNtCreateNamedPipeFile( &h1, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
407 FILE_SHARE_READ|FILE_SHARE_WRITE,
408 FILE_OPEN_IF, FILE_PIPE_FULL_DUPLEX,
409 FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
410 ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
411 ok( iosb.Status == STATUS_SUCCESS, "wrong status %08lx\n", status);
412 ok( iosb.Information == FILE_OPENED, "wrong info %Ix\n", iosb.Information );
413 pNtClose(h1);
415 h1 = CreateNamedPipeA( "\\\\.\\pipe\\named_pipe", PIPE_ACCESS_DUPLEX,
416 PIPE_READMODE_BYTE, 10, 256, 256, 1000, NULL );
417 winerr = GetLastError();
418 ok(h1 != 0 && winerr == ERROR_ALREADY_EXISTS, "CreateNamedPipeA got ret=%p (%ld)\n", h1, winerr);
419 pNtClose(h1);
420 pNtClose(h);
423 static void test_all_kernel_objects( UINT line, OBJECT_ATTRIBUTES *attr,
424 NTSTATUS create_expect, NTSTATUS open_expect )
426 UNICODE_STRING target;
427 LARGE_INTEGER size;
428 NTSTATUS status, status2;
429 HANDLE ret, ret2;
431 RtlInitUnicodeString( &target, L"\\DosDevices" );
432 size.QuadPart = 4096;
434 ret = ret2 = (HANDLE)0xdeadbeef;
435 status = pNtCreateMutant( &ret, GENERIC_ALL, attr, FALSE );
436 ok( status == create_expect, "%u: NtCreateMutant failed %lx\n", line, status );
437 status2 = pNtOpenMutant( &ret2, GENERIC_ALL, attr );
438 ok( status2 == open_expect, "%u: NtOpenMutant failed %lx\n", line, status2 );
439 if (!status) pNtClose( ret );
440 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
441 "%u: NtCreateMutant handle %p\n", line, ret );
442 if (!status2) pNtClose( ret2 );
443 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
444 "%u: NtOpenMutant handle %p\n", line, ret );
446 ret = ret2 = (HANDLE)0xdeadbeef;
447 status = pNtCreateSemaphore( &ret, GENERIC_ALL, attr, 1, 2 );
448 ok( status == create_expect, "%u: NtCreateSemaphore failed %lx\n", line, status );
449 status2 = pNtOpenSemaphore( &ret2, GENERIC_ALL, attr );
450 ok( status2 == open_expect, "%u: NtOpenSemaphore failed %lx\n", line, status2 );
451 if (!status) pNtClose( ret );
452 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
453 "%u: NtCreateSemaphore handle %p\n", line, ret );
454 if (!status2) pNtClose( ret2 );
455 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
456 "%u: NtOpenSemaphore handle %p\n", line, ret );
457 ret = (HANDLE)0xdeadbeef;
458 status = pNtCreateSemaphore( &ret, GENERIC_ALL, attr, 2, 1 );
459 ok( status == STATUS_INVALID_PARAMETER ||
460 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
461 "%u: NtCreateSemaphore failed %lx\n", line, status );
462 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
463 "%u: NtCreateSemaphore handle %p\n", line, ret );
465 ret = ret2 = (HANDLE)0xdeadbeef;
466 status = pNtCreateEvent( &ret, GENERIC_ALL, attr, SynchronizationEvent, 0 );
467 ok( status == create_expect, "%u: NtCreateEvent failed %lx\n", line, status );
468 status2 = pNtOpenEvent( &ret2, GENERIC_ALL, attr );
469 ok( status2 == open_expect, "%u: NtOpenEvent failed %lx\n", line, status2 );
470 if (!status) pNtClose( ret );
471 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
472 "%u: NtCreateEvent handle %p\n", line, ret );
473 if (!status2) pNtClose( ret2 );
474 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
475 "%u: NtOpenEvent handle %p\n", line, ret );
476 ret = (HANDLE)0xdeadbeef;
477 status = pNtCreateEvent( &ret, GENERIC_ALL, attr, 2, 0 );
478 ok( status == STATUS_INVALID_PARAMETER ||
479 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
480 "%u: NtCreateEvent failed %lx\n", line, status );
481 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
482 "%u: NtCreateEvent handle %p\n", line, ret );
484 ret = ret2 = (HANDLE)0xdeadbeef;
485 status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, attr, 0 );
486 ok( status == create_expect, "%u: NtCreateKeyedEvent failed %lx\n", line, status );
487 status2 = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, attr );
488 ok( status2 == open_expect, "%u: NtOpenKeyedEvent failed %lx\n", line, status2 );
489 if (!status) pNtClose( ret );
490 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
491 "%u: NtCreateKeyedEvent handle %p\n", line, ret );
492 if (!status2) pNtClose( ret2 );
493 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
494 "%u: NtOpenKeyedEvent handle %p\n", line, ret );
496 ret = ret2 = (HANDLE)0xdeadbeef;
497 status = pNtCreateTimer( &ret, GENERIC_ALL, attr, NotificationTimer );
498 ok( status == create_expect, "%u: NtCreateTimer failed %lx\n", line, status );
499 status2 = pNtOpenTimer( &ret2, GENERIC_ALL, attr );
500 ok( status2 == open_expect, "%u: NtOpenTimer failed %lx\n", line, status2 );
501 if (!status) pNtClose( ret );
502 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
503 "%u: NtCreateTimer handle %p\n", line, ret );
504 if (!status2) pNtClose( ret2 );
505 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
506 "%u: NtOpenTimer handle %p\n", line, ret );
507 ret = (HANDLE)0xdeadbeef;
508 status = pNtCreateTimer( &ret, GENERIC_ALL, attr, 2 );
509 ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PARAMETER_4 ||
510 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
511 "%u: NtCreateTimer failed %lx\n", line, status );
512 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
513 "%u: NtCreateTimer handle %p\n", line, ret );
515 ret = ret2 = (HANDLE)0xdeadbeef;
516 status = pNtCreateIoCompletion( &ret, GENERIC_ALL, attr, 0 );
517 ok( status == create_expect, "%u: NtCreateIoCompletion failed %lx\n", line, status );
518 status2 = pNtOpenIoCompletion( &ret2, GENERIC_ALL, attr );
519 ok( status2 == open_expect, "%u: NtOpenIoCompletion failed %lx\n", line, status2 );
520 if (!status) pNtClose( ret );
521 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
522 "%u: NtCreateIoCompletion handle %p\n", line, ret );
523 if (!status2) pNtClose( ret2 );
524 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
525 "%u: NtOpenIoCompletion handle %p\n", line, ret );
527 ret = ret2 = (HANDLE)0xdeadbeef;
528 status = pNtCreateJobObject( &ret, GENERIC_ALL, attr );
529 ok( status == create_expect, "%u: NtCreateJobObject failed %lx\n", line, status );
530 status2 = pNtOpenJobObject( &ret2, GENERIC_ALL, attr );
531 ok( status2 == open_expect, "%u: NtOpenJobObject failed %lx\n", line, status2 );
532 if (!status) pNtClose( ret );
533 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
534 "%u: NtCreateJobObject handle %p\n", line, ret );
535 if (!status2) pNtClose( ret2 );
536 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
537 "%u: NtOpenJobObject handle %p\n", line, ret );
539 ret = ret2 = (HANDLE)0xdeadbeef;
540 status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, attr );
541 ok( status == create_expect, "%u: NtCreateDirectoryObject failed %lx\n", line, status );
542 status2 = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, attr );
543 ok( status2 == open_expect, "%u: NtOpenDirectoryObject failed %lx\n", line, status2 );
544 if (!status) pNtClose( ret );
545 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
546 "%u: NtCreateDirectoryObject handle %p\n", line, ret );
547 if (!status2) pNtClose( ret2 );
548 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
549 "%u: NtOpenDirectoryObject handle %p\n", line, ret );
551 ret = ret2 = (HANDLE)0xdeadbeef;
552 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, attr, &target );
553 ok( status == create_expect, "%u: NtCreateSymbolicLinkObject failed %lx\n", line, status );
554 status2 = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, attr );
555 ok( status2 == open_expect, "%u: NtOpenSymbolicLinkObject failed %lx\n", line, status2 );
556 if (!status) pNtClose( ret );
557 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
558 "%u: NtCreateSymbolicLinkObject handle %p\n", line, ret );
559 if (!status2) pNtClose( ret2 );
560 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
561 "%u: NtOpenSymbolicLinkObject handle %p\n", line, ret );
562 ret = (HANDLE)0xdeadbeef;
563 target.MaximumLength = 0;
564 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, attr, &target );
565 ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PARAMETER_4 ||
566 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
567 "%u: NtCreateSymbolicLinkObject failed %lx\n", line, status );
568 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
569 "%u: NtCreateSymbolicLinkObject handle %p\n", line, ret );
571 ret = ret2 = (HANDLE)0xdeadbeef;
572 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, attr, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
573 ok( status == create_expect, "%u: NtCreateSection failed %lx\n", line, status );
574 status2 = pNtOpenSection( &ret2, SECTION_MAP_WRITE, attr );
575 ok( status2 == open_expect, "%u: NtOpenSection failed %lx\n", line, status2 );
576 if (!status) pNtClose( ret );
577 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
578 "%u: NtCreateSection handle %p\n", line, ret );
579 if (!status2) pNtClose( ret2 );
580 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
581 "%u: NtOpenSection handle %p\n", line, ret );
582 ret = (HANDLE)0xdeadbeef;
583 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, attr, &size, 0x1234, SEC_COMMIT, 0 );
584 ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PAGE_PROTECTION ||
585 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
586 "%u: NtCreateSection failed %lx\n", line, status );
587 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
588 "%u: NtCreateSection handle %p\n", line, ret );
590 ret = ret2 = (HANDLE)0xdeadbeef;
591 status = pNtCreateDebugObject( &ret, DEBUG_ALL_ACCESS, attr, 0 );
592 ok( status == create_expect, "%u: NtCreateDebugObject failed %lx\n", line, status );
593 if (!status) pNtClose( ret );
594 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
595 "%u: NtCreateDebugObject handle %p\n", line, ret );
596 status = pNtCreateDebugObject( &ret2, DEBUG_ALL_ACCESS, attr, 0xdead );
597 ok( status == STATUS_INVALID_PARAMETER ||
598 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
599 "%u: NtCreateDebugObject failed %lx\n", line, status );
600 ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
601 "%u: NtCreateDebugObject handle %p\n", line, ret );
604 static void test_name_limits(void)
606 static const WCHAR pipeW[] = L"\\Device\\NamedPipe\\";
607 static const WCHAR mailslotW[] = L"\\Device\\MailSlot\\";
608 static const WCHAR registryW[] = L"\\REGISTRY\\Machine\\SOFTWARE\\Microsoft\\";
609 OBJECT_ATTRIBUTES attr, attr2, attr3;
610 IO_STATUS_BLOCK iosb;
611 LARGE_INTEGER size, timeout;
612 UNICODE_STRING str, str2, target;
613 NTSTATUS status;
614 HANDLE ret, ret2;
615 DWORD i;
617 InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
618 InitializeObjectAttributes( &attr2, &str, 0, (HANDLE)0xdeadbeef, NULL );
619 InitializeObjectAttributes( &attr3, &str, 0, 0, NULL );
620 str.Buffer = HeapAlloc( GetProcessHeap(), 0, 65536 + sizeof(registryW));
621 str.MaximumLength = 65534;
622 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i] = 'a';
623 size.QuadPart = 4096;
624 RtlInitUnicodeString( &target, L"\\DosDevices" );
626 attr.RootDirectory = get_base_dir();
627 str.Length = 0;
628 status = pNtCreateMutant( &ret, GENERIC_ALL, &attr2, FALSE );
629 ok( status == STATUS_SUCCESS, "%u: NtCreateMutant failed %lx\n", str.Length, status );
630 attr3.RootDirectory = ret;
631 status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr );
632 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenMutant failed %lx\n", str.Length, status );
633 status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr3 );
634 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
635 "%u: NtOpenMutant failed %lx\n", str.Length, status );
636 pNtClose( ret );
637 status = pNtCreateSemaphore( &ret, GENERIC_ALL, &attr2, 1, 2 );
638 ok( status == STATUS_SUCCESS, "%u: NtCreateSemaphore failed %lx\n", str.Length, status );
639 attr3.RootDirectory = ret;
640 status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr );
641 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSemaphore failed %lx\n", str.Length, status );
642 status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr3 );
643 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
644 "%u: NtOpenSemaphore failed %lx\n", str.Length, status );
645 pNtClose( ret );
646 status = pNtCreateEvent( &ret, GENERIC_ALL, &attr2, SynchronizationEvent, 0 );
647 ok( status == STATUS_SUCCESS, "%u: NtCreateEvent failed %lx\n", str.Length, status );
648 attr3.RootDirectory = ret;
649 status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr );
650 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenEvent failed %lx\n", str.Length, status );
651 status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr3 );
652 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
653 "%u: NtOpenEvent failed %lx\n", str.Length, status );
654 pNtClose( ret );
655 status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, &attr2, 0 );
656 ok( status == STATUS_SUCCESS, "%u: NtCreateKeyedEvent failed %lx\n", str.Length, status );
657 attr3.RootDirectory = ret;
658 status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr );
659 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenKeyedEvent failed %lx\n", str.Length, status );
660 status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr3 );
661 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
662 "%u: NtOpenKeyedEvent failed %lx\n", str.Length, status );
663 pNtClose( ret );
664 status = pNtCreateTimer( &ret, GENERIC_ALL, &attr2, NotificationTimer );
665 ok( status == STATUS_SUCCESS, "%u: NtCreateTimer failed %lx\n", str.Length, status );
666 attr3.RootDirectory = ret;
667 status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr );
668 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenTimer failed %lx\n", str.Length, status );
669 status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr3 );
670 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
671 "%u: NtOpenTimer failed %lx\n", str.Length, status );
672 pNtClose( ret );
673 status = pNtCreateIoCompletion( &ret, GENERIC_ALL, &attr2, 0 );
674 ok( status == STATUS_SUCCESS, "%u: NtCreateCompletion failed %lx\n", str.Length, status );
675 attr3.RootDirectory = ret;
676 status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr );
677 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenCompletion failed %lx\n", str.Length, status );
678 status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr3 );
679 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
680 "%u: NtOpenCompletion failed %lx\n", str.Length, status );
681 pNtClose( ret );
682 status = pNtCreateJobObject( &ret, GENERIC_ALL, &attr2 );
683 ok( status == STATUS_SUCCESS, "%u: NtCreateJobObject failed %lx\n", str.Length, status );
684 attr3.RootDirectory = ret;
685 status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr );
686 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenJobObject failed %lx\n", str.Length, status );
687 status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr3 );
688 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
689 "%u: NtOpenJobObject failed %lx\n", str.Length, status );
690 pNtClose( ret );
691 status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, &attr2 );
692 ok( status == STATUS_SUCCESS, "%u: NtCreateDirectoryObject failed %lx\n", str.Length, status );
693 attr3.RootDirectory = ret;
694 status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr );
695 ok( status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_DENIED), /* winxp */
696 "%u: NtOpenDirectoryObject failed %lx\n", str.Length, status );
697 if (!status) pNtClose( ret2 );
698 status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr3 );
699 ok( status == STATUS_SUCCESS, "%u: NtOpenDirectoryObject failed %lx\n", str.Length, status );
700 pNtClose( ret2 );
701 pNtClose( ret );
702 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, &attr2, &target );
703 ok( status == STATUS_SUCCESS, "%u: NtCreateSymbolicLinkObject failed %lx\n", str.Length, status );
704 attr3.RootDirectory = ret;
705 status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr );
706 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSymbolicLinkObject failed %lx\n", str.Length, status );
707 status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr3 );
708 ok( status == STATUS_SUCCESS, "%u: NtOpenSymbolicLinkObject failed %lx\n", str.Length, status );
709 pNtClose( ret2 );
710 pNtClose( ret );
711 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, &attr2, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
712 ok( status == STATUS_SUCCESS, "%u: NtCreateSection failed %lx\n", str.Length, status );
713 attr3.RootDirectory = ret;
714 status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr );
715 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSection failed %lx\n", str.Length, status );
716 status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr3 );
717 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
718 "%u: NtOpenSection failed %lx\n", str.Length, status );
719 pNtClose( ret );
721 str.Length = 67;
722 test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
724 str.Length = 65532;
725 test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS );
727 str.Length = 65534;
728 test_all_kernel_objects( __LINE__, &attr, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
730 str.Length = 128;
731 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
733 if (attr.Length == sizeof(attr))
734 test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS );
735 else
736 test_all_kernel_objects( __LINE__, &attr, STATUS_INVALID_PARAMETER, STATUS_INVALID_PARAMETER );
738 attr.Length = sizeof(attr);
740 /* null attributes or ObjectName, with or without RootDirectory */
741 attr3.RootDirectory = 0;
742 attr2.ObjectName = attr3.ObjectName = NULL;
743 test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
744 test_all_kernel_objects( __LINE__, &attr3, STATUS_SUCCESS, STATUS_OBJECT_PATH_SYNTAX_BAD );
745 attr2.ObjectName = attr3.ObjectName = (void *)0xdeadbeef;
746 test_all_kernel_objects( __LINE__, &attr2, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
747 test_all_kernel_objects( __LINE__, &attr3, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
748 attr2.ObjectName = attr3.ObjectName = &str2;
749 str2.Buffer = (WCHAR *)0xdeadbeef;
750 str2.Length = 3;
751 test_all_kernel_objects( __LINE__, &attr2, STATUS_DATATYPE_MISALIGNMENT, STATUS_DATATYPE_MISALIGNMENT );
752 test_all_kernel_objects( __LINE__, &attr3, STATUS_DATATYPE_MISALIGNMENT, STATUS_DATATYPE_MISALIGNMENT );
753 str2.Buffer = (WCHAR *)0xdeadbee0;
754 str2.Length = 2;
755 test_all_kernel_objects( __LINE__, &attr2, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
756 test_all_kernel_objects( __LINE__, &attr3, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
758 attr3.ObjectName = &str2;
759 pRtlInitUnicodeString( &str2, L"\\BaseNamedObjects\\Local" );
760 status = pNtOpenSymbolicLinkObject( &ret, SYMBOLIC_LINK_QUERY, &attr3 );
761 ok( status == STATUS_SUCCESS, "can't open BaseNamedObjects\\Local %lx\n", status );
762 attr3.ObjectName = &str;
763 attr3.RootDirectory = ret;
764 test_all_kernel_objects( __LINE__, &attr3, STATUS_OBJECT_TYPE_MISMATCH, STATUS_OBJECT_TYPE_MISMATCH );
765 pNtClose( attr3.RootDirectory );
767 status = pNtCreateMutant( &ret, GENERIC_ALL, NULL, FALSE );
768 ok( status == STATUS_SUCCESS, "NULL: NtCreateMutant failed %lx\n", status );
769 pNtClose( ret );
770 status = pNtCreateMutant( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, FALSE );
771 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateMutant failed %lx\n", status );
772 ret = (HANDLE)0xdeadbeef;
773 status = pNtOpenMutant( &ret, GENERIC_ALL, NULL );
774 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenMutant failed %lx\n", status );
775 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
776 status = pNtOpenMutant( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
777 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenMutant failed %lx\n", status );
779 status = pNtCreateSemaphore( &ret, GENERIC_ALL, NULL, 1, 2 );
780 ok( status == STATUS_SUCCESS, "NULL: NtCreateSemaphore failed %lx\n", status );
781 pNtClose( ret );
782 status = pNtCreateSemaphore( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, 1, 2 );
783 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateSemaphore failed %lx\n", status );
784 ret = (HANDLE)0xdeadbeef;
785 status = pNtOpenSemaphore( &ret, GENERIC_ALL, NULL );
786 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSemaphore failed %lx\n", status );
787 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
788 status = pNtOpenSemaphore( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
789 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenSemaphore failed %lx\n", status );
791 status = pNtCreateEvent( &ret, GENERIC_ALL, NULL, SynchronizationEvent, 0 );
792 ok( status == STATUS_SUCCESS, "NULL: NtCreateEvent failed %lx\n", status );
793 pNtClose( ret );
794 status = pNtCreateEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, SynchronizationEvent, 0 );
795 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateEvent failed %lx\n", status );
796 ret = (HANDLE)0xdeadbeef;
797 status = pNtOpenEvent( &ret, GENERIC_ALL, NULL );
798 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenEvent failed %lx\n", status );
799 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
800 status = pNtOpenEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
801 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenEvent failed %lx\n", status );
803 status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, NULL, 0 );
804 ok( status == STATUS_SUCCESS, "NULL: NtCreateKeyedEvent failed %lx\n", status );
805 pNtClose( ret );
806 status = pNtCreateKeyedEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, 0 );
807 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKeyedEvent failed %lx\n", status );
808 ret = (HANDLE)0xdeadbeef;
809 status = pNtOpenKeyedEvent( &ret, GENERIC_ALL, NULL );
810 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenKeyedEvent failed %lx\n", status );
811 ok( !ret, "handle set %p\n", ret );
812 status = pNtOpenKeyedEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
813 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKeyedEvent failed %lx\n", status );
815 status = pNtCreateTimer( &ret, GENERIC_ALL, NULL, NotificationTimer );
816 ok( status == STATUS_SUCCESS, "NULL: NtCreateTimer failed %lx\n", status );
817 pNtClose( ret );
818 status = pNtCreateTimer( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, NotificationTimer );
819 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateTimer failed %lx\n", status );
820 ret = (HANDLE)0xdeadbeef;
821 status = pNtOpenTimer( &ret, GENERIC_ALL, NULL );
822 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenTimer failed %lx\n", status );
823 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
824 status = pNtOpenTimer( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
825 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenTimer failed %lx\n", status );
827 status = pNtCreateIoCompletion( &ret, GENERIC_ALL, NULL, 0 );
828 ok( status == STATUS_SUCCESS, "NULL: NtCreateCompletion failed %lx\n", status );
829 pNtClose( ret );
830 status = pNtCreateIoCompletion( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, 0 );
831 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateCompletion failed %lx\n", status );
832 ret = (HANDLE)0xdeadbeef;
833 status = pNtOpenIoCompletion( &ret, GENERIC_ALL, NULL );
834 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenCompletion failed %lx\n", status );
835 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
836 status = pNtOpenIoCompletion( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
837 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenCompletion failed %lx\n", status );
839 status = pNtCreateJobObject( &ret, GENERIC_ALL, NULL );
840 ok( status == STATUS_SUCCESS, "NULL: NtCreateJobObject failed %lx\n", status );
841 pNtClose( ret );
842 status = pNtCreateJobObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
843 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateJobObject failed %lx\n", status );
844 ret = (HANDLE)0xdeadbeef;
845 status = pNtOpenJobObject( &ret, GENERIC_ALL, NULL );
846 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenJobObject failed %lx\n", status );
847 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
848 status = pNtOpenJobObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
849 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenJobObject failed %lx\n", status );
851 status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, NULL );
852 ok( status == STATUS_SUCCESS, "NULL: NtCreateDirectoryObject failed %lx\n", status );
853 pNtClose( ret );
854 status = pNtCreateDirectoryObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
855 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateDirectoryObject failed %lx\n", status );
856 ret = (HANDLE)0xdeadbeef;
857 status = pNtOpenDirectoryObject( &ret, GENERIC_ALL, NULL );
858 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenDirectoryObject failed %lx\n", status );
859 ok( !ret, "handle set %p\n", ret );
860 status = pNtOpenDirectoryObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
861 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenDirectoryObject failed %lx\n", status );
863 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, NULL, &target );
864 ok( status == STATUS_ACCESS_VIOLATION || broken( status == STATUS_SUCCESS), /* winxp */
865 "NULL: NtCreateSymbolicLinkObject failed %lx\n", status );
866 if (!status) pNtClose( ret );
867 status = pNtCreateSymbolicLinkObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, &target );
868 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateSymbolicLinkObject failed %lx\n", status );
869 ret = (HANDLE)0xdeadbeef;
870 status = pNtOpenSymbolicLinkObject( &ret, GENERIC_ALL, NULL );
871 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSymbolicLinkObject failed %lx\n", status );
872 ok( !ret, "handle set %p\n", ret );
873 status = pNtOpenSymbolicLinkObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
874 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenSymbolicLinkObject failed %lx\n", status );
876 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
877 ok( status == STATUS_SUCCESS, "NULL: NtCreateSection failed %lx\n", status );
878 pNtClose( ret );
879 status = pNtCreateSection( (HANDLE *)0xdeadbee0, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
880 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateSection failed %lx\n", status );
881 ret = (HANDLE)0xdeadbeef;
882 status = pNtOpenSection( &ret, SECTION_MAP_WRITE, NULL );
883 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSection failed %lx\n", status );
884 ok( !ret, "handle set %p\n", ret );
885 status = pNtOpenSection( (HANDLE *)0xdeadbee0, SECTION_MAP_WRITE, NULL );
886 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenSection failed %lx\n", status );
887 attr2.ObjectName = attr3.ObjectName = &str;
889 /* named pipes */
890 wcscpy( str.Buffer, pipeW );
891 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + wcslen( pipeW )] = 'a';
892 str.Length = 0;
893 attr.RootDirectory = 0;
894 attr.Attributes = OBJ_CASE_INSENSITIVE;
895 timeout.QuadPart = -10000;
896 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
897 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
898 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
899 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
900 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
901 ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
902 str.Length = 67;
903 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
904 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
905 ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
906 str.Length = 128;
907 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
909 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
910 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
911 if (attr.Length == sizeof(attr))
913 ok( status == STATUS_SUCCESS, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
914 pNtClose( ret );
916 else ok( status == STATUS_INVALID_PARAMETER,
917 "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
919 attr.Length = sizeof(attr);
920 str.Length = 65532;
921 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
922 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
923 ok( status == STATUS_SUCCESS, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
924 pNtClose( ret );
925 str.Length = 65534;
926 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
927 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
928 ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
929 attr3.RootDirectory = 0;
930 attr2.ObjectName = attr3.ObjectName = NULL;
931 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
932 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
933 ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateNamedPipeFile failed %lx\n", status );
934 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr3, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
935 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
936 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateNamedPipeFile failed %lx\n", status );
937 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, NULL, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
938 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
939 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateNamedPipeFile failed %lx\n", status );
940 attr2.ObjectName = attr3.ObjectName = &str;
942 /* mailslots */
943 wcscpy( str.Buffer, mailslotW );
944 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + wcslen( mailslotW )] = 'a';
945 str.Length = 0;
946 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
947 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
948 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
949 ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
950 str.Length = 67;
951 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
952 ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
953 str.Length = 128;
954 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
956 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
957 if (attr.Length == sizeof(attr))
959 ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
960 pNtClose( ret );
962 else ok( status == STATUS_INVALID_PARAMETER,
963 "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
965 attr.Length = sizeof(attr);
966 str.Length = 65532;
967 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
968 ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
969 pNtClose( ret );
970 str.Length = 65534;
971 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
972 ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
973 attr3.RootDirectory = 0;
974 attr2.ObjectName = attr3.ObjectName = NULL;
975 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
976 ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateMailslotFile failed %lx\n", status );
977 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr3, &iosb, 0, 0, 0, NULL );
978 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateMailslotFile failed %lx\n", status );
979 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, NULL, &iosb, 0, 0, 0, NULL );
980 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateMailslotFile failed %lx\n", status );
981 attr2.ObjectName = attr3.ObjectName = &str;
983 /* registry keys */
984 wcscpy( str.Buffer, registryW );
985 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + wcslen(registryW)] = 'a';
986 str.Length = 0;
987 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
988 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateKey failed %lx\n", str.Length, status );
989 status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL );
990 ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateKey failed %lx\n", str.Length, status );
991 status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 );
992 ok( status == STATUS_INVALID_HANDLE, "%u: NtOpenKey failed %lx\n", str.Length, status );
993 str.Length = (wcslen( registryW ) + 250) * sizeof(WCHAR) + 1;
994 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
995 ok( status == STATUS_OBJECT_NAME_INVALID ||
996 status == STATUS_INVALID_PARAMETER ||
997 broken( status == STATUS_SUCCESS ), /* wow64 */
998 "%u: NtCreateKey failed %lx\n", str.Length, status );
999 if (!status)
1001 pNtDeleteKey( ret );
1002 pNtClose( ret );
1004 str.Length = (wcslen( registryW ) + 256) * sizeof(WCHAR);
1005 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1006 ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED,
1007 "%u: NtCreateKey failed %lx\n", str.Length, status );
1008 status = pNtCreateKey( (HANDLE *)0xdeadbee0, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1009 ok( status == STATUS_ACCESS_VIOLATION, "%u: NtCreateKey failed %lx\n", str.Length, status );
1010 if (!status)
1012 status = pNtOpenKey( &ret2, KEY_READ, &attr );
1013 ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %lx\n", str.Length, status );
1014 pNtClose( ret2 );
1015 status = pNtOpenKey( (HANDLE *)0xdeadbee0, KEY_READ, &attr );
1016 ok( status == STATUS_ACCESS_VIOLATION, "%u: NtOpenKey failed %lx\n", str.Length, status );
1017 attr3.RootDirectory = ret;
1018 str.Length = 0;
1019 status = pNtOpenKey( &ret2, KEY_READ, &attr3 );
1020 ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %lx\n", str.Length, status );
1021 pNtClose( ret2 );
1022 pNtDeleteKey( ret );
1023 pNtClose( ret );
1025 str.Length = (wcslen( registryW ) + 256) * sizeof(WCHAR);
1026 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
1028 if (attr.Length == sizeof(attr))
1030 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1031 ok( status == STATUS_SUCCESS, "%u: NtCreateKey failed %lx\n", str.Length, status );
1032 status = pNtOpenKey( &ret2, KEY_READ, &attr );
1033 ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %lx\n", str.Length, status );
1034 pNtClose( ret2 );
1035 pNtDeleteKey( ret );
1036 pNtClose( ret );
1038 else
1040 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1041 ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %lx\n", str.Length, status );
1042 status = pNtOpenKey( &ret2, KEY_READ, &attr );
1043 ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %lx\n", str.Length, status );
1046 attr.Length = sizeof(attr);
1048 str.Length = (wcslen( registryW ) + 256) * sizeof(WCHAR) + 1;
1049 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1050 ok( status == STATUS_OBJECT_NAME_INVALID ||
1051 status == STATUS_INVALID_PARAMETER ||
1052 broken( status == STATUS_SUCCESS ), /* win7 */
1053 "%u: NtCreateKey failed %lx\n", str.Length, status );
1054 if (!status)
1056 pNtDeleteKey( ret );
1057 pNtClose( ret );
1059 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1060 ok( status == STATUS_OBJECT_NAME_INVALID ||
1061 status == STATUS_INVALID_PARAMETER ||
1062 broken( status == STATUS_OBJECT_NAME_NOT_FOUND ), /* wow64 */
1063 "%u: NtOpenKey failed %lx\n", str.Length, status );
1064 str.Length++;
1065 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1066 ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %lx\n", str.Length, status );
1067 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1068 ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %lx\n", str.Length, status );
1069 str.Length = 2000;
1070 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1071 ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %lx\n", str.Length, status );
1072 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1073 ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %lx\n", str.Length, status );
1074 /* some Windows versions change the error past 2050 chars, others past 4066 chars, some don't */
1075 str.Length = 5000;
1076 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1077 ok( status == STATUS_BUFFER_OVERFLOW ||
1078 status == STATUS_BUFFER_TOO_SMALL ||
1079 status == STATUS_INVALID_PARAMETER,
1080 "%u: NtCreateKey failed %lx\n", str.Length, status );
1081 ret = (HANDLE)0xdeadbeef;
1082 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1083 ok( status == STATUS_BUFFER_OVERFLOW ||
1084 status == STATUS_BUFFER_TOO_SMALL ||
1085 status == STATUS_INVALID_PARAMETER,
1086 "%u: NtOpenKey failed %lx\n", str.Length, status );
1087 ok( !ret, "handle set %p\n", ret );
1088 str.Length = 65534;
1089 ret = (HANDLE)0xdeadbeef;
1090 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1091 ok( status == STATUS_OBJECT_NAME_INVALID ||
1092 status == STATUS_BUFFER_OVERFLOW ||
1093 status == STATUS_BUFFER_TOO_SMALL,
1094 "%u: NtCreateKey failed %lx\n", str.Length, status );
1095 ok( !ret, "handle set %p\n", ret );
1096 ret = (HANDLE)0xdeadbeef;
1097 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1098 ok( status == STATUS_OBJECT_NAME_INVALID ||
1099 status == STATUS_BUFFER_OVERFLOW ||
1100 status == STATUS_BUFFER_TOO_SMALL,
1101 "%u: NtOpenKey failed %lx\n", str.Length, status );
1102 ok( !ret, "handle set %p\n", ret );
1103 attr3.RootDirectory = 0;
1104 attr2.ObjectName = attr3.ObjectName = NULL;
1105 status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL );
1106 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE /* vista wow64 */,
1107 "NULL: NtCreateKey failed %lx\n", status );
1108 status = pNtCreateKey( &ret, GENERIC_ALL, &attr3, 0, NULL, 0, NULL );
1109 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %lx\n", status );
1110 status = pNtCreateKey( &ret, GENERIC_ALL, NULL, 0, NULL, 0, NULL );
1111 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %lx\n", status );
1112 status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 );
1113 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE /* vista wow64 */,
1114 "NULL: NtOpenKey failed %lx\n", status );
1115 status = pNtOpenKey( &ret, GENERIC_ALL, &attr3 );
1116 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %lx\n", status );
1117 status = pNtOpenKey( &ret, GENERIC_ALL, NULL );
1118 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %lx\n", status );
1119 attr2.ObjectName = attr3.ObjectName = &str;
1121 HeapFree( GetProcessHeap(), 0, str.Buffer );
1124 static void test_directory(void)
1126 NTSTATUS status;
1127 UNICODE_STRING str;
1128 OBJECT_ATTRIBUTES attr;
1129 HANDLE dir, dir1, h, h2;
1130 WCHAR buffer[256];
1131 ULONG len, full_len;
1133 /* No name and/or no attributes */
1134 status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
1135 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER /* wow64 */, "got %#lx\n", status);
1136 status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
1137 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER /* wow64 */, "got %#lx\n", status);
1139 status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL);
1140 ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08lx)\n", status);
1141 pNtClose(h);
1142 status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL);
1143 ok(status == STATUS_INVALID_PARAMETER,
1144 "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status);
1146 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
1147 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1148 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1149 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1150 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08lx\n", status );
1152 /* Bad name */
1153 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1155 RtlInitUnicodeString(&str, L"");
1156 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1157 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1158 pNtClose(h);
1159 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1160 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08lx\n", status );
1161 pNtClose(dir);
1163 check_create_open_dir( NULL, L"BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD );
1164 check_create_open_dir( NULL, L"\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID );
1165 check_create_open_dir( NULL, L"\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID );
1166 check_create_open_dir( NULL, L"\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID );
1167 check_create_open_dir( NULL, L"\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND );
1169 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test");
1170 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1171 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1172 status = pNtOpenDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
1173 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1174 pNtClose(h);
1175 pNtClose(dir1);
1178 /* Use of root directory */
1180 /* Can't use symlinks as a directory */
1181 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\Local");
1182 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1183 status = pNtOpenSymbolicLinkObject(&dir, SYMBOLIC_LINK_QUERY, &attr);
1185 ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08lx)\n", status);
1186 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1187 RtlInitUnicodeString(&str, L"one more level");
1188 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1189 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtCreateDirectoryObject got %08lx\n", status );
1191 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\Local\\om.c-test" );
1192 InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
1193 status = pNtCreateDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
1194 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1195 RtlInitUnicodeString( &str, L"om.c-test" );
1196 InitializeObjectAttributes( &attr, &str, 0, dir, NULL );
1197 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1198 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "Failed to open directory %08lx\n", status );
1200 RtlInitUnicodeString( &str, L"om.c-event" );
1201 InitializeObjectAttributes( &attr, &str, 0, dir1, NULL );
1202 status = pNtCreateEvent( &h, GENERIC_ALL, &attr, SynchronizationEvent, 0 );
1203 ok( status == STATUS_SUCCESS, "NtCreateEvent failed %lx\n", status );
1204 status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
1205 ok( status == STATUS_SUCCESS, "NtOpenEvent failed %lx\n", status );
1206 pNtClose( h2 );
1207 RtlInitUnicodeString( &str, L"om.c-test\\om.c-event" );
1208 InitializeObjectAttributes( &attr, &str, 0, dir, NULL );
1209 status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
1210 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtOpenEvent failed %lx\n", status );
1211 RtlInitUnicodeString( &str, L"\\BasedNamedObjects\\Local\\om.c-test\\om.c-event" );
1212 InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
1213 status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
1214 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtOpenEvent failed %lx\n", status );
1215 pNtClose( h );
1216 pNtClose( dir1 );
1218 str.Buffer = buffer;
1219 str.MaximumLength = sizeof(buffer);
1220 len = 0xdeadbeef;
1221 memset( buffer, 0xaa, sizeof(buffer) );
1222 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1223 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1224 full_len = str.Length + sizeof(WCHAR);
1225 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1226 ok( buffer[len / sizeof(WCHAR) - 1] == 0, "no terminating null\n" );
1228 str.MaximumLength = str.Length;
1229 str.Length = 0x4444;
1230 len = 0xdeadbeef;
1231 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1232 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1233 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1234 ok( str.Length == 0x4444, "len set to %x\n", str.Length );
1236 str.MaximumLength = 0;
1237 str.Length = 0x4444;
1238 len = 0xdeadbeef;
1239 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1240 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1241 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1242 ok( str.Length == 0x4444, "len set to %x\n", str.Length );
1244 str.MaximumLength = full_len;
1245 str.Length = 0x4444;
1246 len = 0xdeadbeef;
1247 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1248 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1249 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1250 ok( str.Length == full_len - sizeof(WCHAR), "len set to %x\n", str.Length );
1252 pNtClose(dir);
1254 RtlInitUnicodeString(&str, L"\\BaseNamedObjects");
1255 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1256 status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1257 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1259 InitializeObjectAttributes(&attr, NULL, 0, dir, NULL);
1260 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1261 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenDirectoryObject got %08lx\n", status );
1263 check_create_open_dir( dir, L"", STATUS_SUCCESS );
1264 check_create_open_dir( dir, L"\\", STATUS_OBJECT_PATH_SYNTAX_BAD );
1265 check_create_open_dir( dir, L"\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD );
1266 check_create_open_dir( dir, L"\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD );
1267 check_create_open_dir( dir, L"om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND );
1269 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1270 RtlInitUnicodeString(&str, L"om.c-test");
1271 status = pNtCreateDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
1272 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1273 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1274 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1276 pNtClose(h);
1277 pNtClose(dir1);
1278 pNtClose(dir);
1280 /* Nested directories */
1281 RtlInitUnicodeString(&str, L"\\");
1282 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1283 status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1284 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1285 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1286 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1287 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08lx\n", status );
1288 pNtClose(dir);
1290 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1291 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test");
1292 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1293 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1294 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test\\one more level");
1295 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1296 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1297 pNtClose(h);
1298 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1299 RtlInitUnicodeString(&str, L"one more level");
1300 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1301 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1302 pNtClose(h);
1304 pNtClose(dir);
1306 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1307 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\Global\\om.c-test");
1308 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1309 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1310 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\Local\\om.c-test\\one more level");
1311 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1312 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1313 pNtClose(h);
1314 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1315 RtlInitUnicodeString(&str, L"one more level");
1316 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1317 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1318 pNtClose(h);
1319 pNtClose(dir);
1321 /* Create other objects using RootDirectory */
1323 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1324 RtlInitUnicodeString(&str, L"\\BaseNamedObjects");
1325 status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1326 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1327 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1329 /* Test invalid paths */
1330 RtlInitUnicodeString(&str, L"\\om.c-mutant");
1331 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1332 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1333 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
1334 RtlInitUnicodeString(&str, L"\\om.c-mutant\\");
1335 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1336 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1337 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
1339 RtlInitUnicodeString(&str, L"om.c\\-mutant");
1340 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1341 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
1342 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status);
1344 RtlInitUnicodeString(&str, L"om.c-mutant");
1345 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1346 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08lx)\n", status);
1347 pNtClose(h);
1349 pNtClose(dir);
1352 static void test_symboliclink(void)
1354 NTSTATUS status;
1355 UNICODE_STRING str, target;
1356 OBJECT_ATTRIBUTES attr;
1357 HANDLE dir, link, h, h2;
1358 IO_STATUS_BLOCK iosb;
1360 /* No name and/or no attributes */
1361 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
1362 RtlInitUnicodeString(&target, L"\\DosDevices");
1363 status = pNtCreateSymbolicLinkObject( NULL, SYMBOLIC_LINK_QUERY, &attr, &target );
1364 ok(status == STATUS_ACCESS_VIOLATION, "got %#lx\n", status);
1365 status = pNtOpenSymbolicLinkObject( NULL, SYMBOLIC_LINK_QUERY, &attr );
1366 ok(status == STATUS_ACCESS_VIOLATION, "got %#lx\n", status);
1368 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL);
1369 ok(status == STATUS_ACCESS_VIOLATION,
1370 "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status);
1371 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL);
1372 ok(status == STATUS_INVALID_PARAMETER,
1373 "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status);
1375 /* No attributes */
1376 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, &target);
1377 ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_VIOLATION, /* nt4 */
1378 "NtCreateSymbolicLinkObject failed(%08lx)\n", status);
1380 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
1381 memset(&target, 0, sizeof(target));
1382 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1383 ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
1384 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
1385 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1386 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
1388 /* Bad name */
1389 RtlInitUnicodeString(&target, L"anywhere");
1390 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1392 RtlInitUnicodeString(&str, L"");
1393 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1394 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08lx)\n", status);
1395 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
1396 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1397 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
1398 pNtClose(link);
1400 RtlInitUnicodeString(&str, L"\\");
1401 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target);
1402 todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH,
1403 "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
1405 RtlInitUnicodeString( &target, L"->Somewhere");
1407 RtlInitUnicodeString( &str, L"BaseNamedObjects" );
1408 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1409 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtCreateSymbolicLinkObject got %08lx\n", status );
1410 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1411 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenSymbolicLinkObject got %08lx\n", status );
1413 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\" );
1414 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1415 ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08lx\n", status );
1416 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1417 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08lx\n", status );
1419 RtlInitUnicodeString( &str, L"\\\\BaseNamedObjects" );
1420 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1421 ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08lx\n", status );
1422 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1423 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08lx\n", status );
1425 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\\\om.c-test" );
1426 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1427 ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08lx\n", status );
1428 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1429 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08lx\n", status );
1431 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\" );
1432 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1433 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "got %#lx\n", status );
1434 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1435 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "got %#lx\n", status );
1437 /* Compound test */
1438 dir = get_base_dir();
1439 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1440 RtlInitUnicodeString(&str, L"test-link");
1441 RtlInitUnicodeString(&target, L"\\DosDevices");
1442 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1443 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08lx)\n", status);
1445 RtlInitUnicodeString(&str, L"test-link\\NUL");
1446 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
1447 ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08lx)\n", status);
1448 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE);
1449 ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08lx)\n", status);
1451 pNtClose(h);
1452 pNtClose(link);
1453 pNtClose(dir);
1455 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1456 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test");
1457 status = pNtCreateDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
1458 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1460 RtlInitUnicodeString(&str, L"\\DosDevices\\test_link");
1461 RtlInitUnicodeString(&target, L"\\BaseNamedObjects");
1462 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1463 ok(status == STATUS_SUCCESS && !!link, "Got unexpected status %#lx.\n", status);
1465 status = NtCreateFile(&h, GENERIC_READ | SYNCHRONIZE, &attr, &iosb, NULL, 0,
1466 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 );
1467 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1469 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1470 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1471 pNtClose(h);
1473 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1474 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\" );
1475 status = NtCreateFile(&h, GENERIC_READ | SYNCHRONIZE, &attr, &iosb, NULL, 0,
1476 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 );
1477 ok(status == STATUS_OBJECT_NAME_INVALID, "Got unexpected status %#lx.\n", status);
1479 InitializeObjectAttributes(&attr, &str, 0, link, NULL);
1480 RtlInitUnicodeString( &str, L"om.c-test\\test_object" );
1481 status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
1482 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1484 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1485 RtlInitUnicodeString( &str, L"\\DosDevices\\test_link\\om.c-test\\test_object" );
1486 status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
1487 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1488 status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
1489 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1490 pNtClose(h2);
1491 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\test_object" );
1492 status = pNtCreateMutant( &h2, GENERIC_ALL, &attr, FALSE );
1493 ok(status == STATUS_OBJECT_NAME_COLLISION, "Got unexpected status %#lx.\n", status);
1495 InitializeObjectAttributes(&attr, &str, 0, link, NULL);
1496 RtlInitUnicodeString( &str, L"om.c-test\\test_object" );
1497 status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
1498 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1500 pNtClose(h);
1502 status = pNtOpenMutant( &h, GENERIC_ALL, &attr );
1503 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1505 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1506 RtlInitUnicodeString( &str, L"test_object" );
1507 status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
1508 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1509 status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
1510 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1511 pNtClose(h);
1512 pNtClose(h2);
1514 pNtClose(link);
1515 pNtClose(dir);
1518 #define test_file_info(a) _test_file_info(__LINE__,a)
1519 static void _test_file_info(unsigned line, HANDLE handle)
1521 IO_STATUS_BLOCK io;
1522 char buf[256];
1523 NTSTATUS status;
1525 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), 0xdeadbeef);
1526 ok_(__FILE__,line)(status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED /* Vista+ */,
1527 "expected STATUS_NOT_IMPLEMENTED, got %lx\n", status);
1529 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), FileAccessInformation);
1530 ok_(__FILE__,line)(status == STATUS_SUCCESS, "FileAccessInformation returned %lx\n", status);
1532 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf),
1533 FileIoCompletionNotificationInformation);
1534 ok_(__FILE__,line)(status == STATUS_SUCCESS || broken(status == STATUS_INVALID_INFO_CLASS) /* XP */,
1535 "FileIoCompletionNotificationInformation returned %lx\n", status);
1538 #define test_no_file_info(a) _test_no_file_info(__LINE__,a)
1539 static void _test_no_file_info(unsigned line, HANDLE handle)
1541 IO_STATUS_BLOCK io;
1542 char buf[256];
1543 NTSTATUS status;
1545 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), 0xdeadbeef);
1546 ok_(__FILE__,line)(status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED /* Vista+ */,
1547 "expected STATUS_NOT_IMPLEMENTED, got %lx\n", status);
1549 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), FileAccessInformation);
1550 ok_(__FILE__,line)(status == STATUS_OBJECT_TYPE_MISMATCH,
1551 "FileAccessInformation returned %lx\n", status);
1553 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf),
1554 FileIoCompletionNotificationInformation);
1555 ok_(__FILE__,line)(status == STATUS_OBJECT_TYPE_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* XP */,
1556 "FileIoCompletionNotificationInformation returned %lx\n", status);
1559 static OBJECT_TYPE_INFORMATION all_types[256];
1561 static void add_object_type( OBJECT_TYPE_INFORMATION *info )
1563 unsigned int i;
1565 for (i = 0; i < ARRAY_SIZE(all_types); i++)
1567 if (!all_types[i].TypeName.Buffer) break;
1568 if (!RtlCompareUnicodeString( &all_types[i].TypeName, &info->TypeName, FALSE )) break;
1570 ok( i < ARRAY_SIZE(all_types), "too many types\n" );
1572 if (all_types[i].TypeName.Buffer) /* existing type */
1574 ok( !memcmp( &all_types[i].GenericMapping, &info->GenericMapping, sizeof(GENERIC_MAPPING) ),
1575 "%u: mismatched mappings %08lx,%08lx,%08lx,%08lx / %08lx,%08lx,%08lx,%08lx\n", i,
1576 all_types[i].GenericMapping.GenericRead, all_types[i].GenericMapping.GenericWrite,
1577 all_types[i].GenericMapping.GenericExecute, all_types[i].GenericMapping.GenericAll,
1578 info->GenericMapping.GenericRead, info->GenericMapping.GenericWrite,
1579 info->GenericMapping.GenericExecute, info->GenericMapping.GenericAll );
1580 ok( all_types[i].ValidAccessMask == info->ValidAccessMask,
1581 "%u: mismatched access mask %08lx / %08lx\n", i,
1582 all_types[i].ValidAccessMask, info->ValidAccessMask );
1584 else /* add it */
1586 all_types[i] = *info;
1587 RtlDuplicateUnicodeString( 1, &info->TypeName, &all_types[i].TypeName );
1589 ok( info->TotalNumberOfObjects <= info->HighWaterNumberOfObjects, "%s: wrong object counts %lu/%lu\n",
1590 debugstr_w( all_types[i].TypeName.Buffer ),
1591 info->TotalNumberOfObjects, info->HighWaterNumberOfObjects );
1592 ok( info->TotalNumberOfHandles <= info->HighWaterNumberOfHandles, "%s: wrong handle counts %lu/%lu\n",
1593 debugstr_w( all_types[i].TypeName.Buffer ),
1594 info->TotalNumberOfHandles, info->HighWaterNumberOfHandles );
1597 static BOOL compare_unicode_string( const UNICODE_STRING *string, const WCHAR *expect )
1599 return string->Length == wcslen( expect ) * sizeof(WCHAR)
1600 && !wcsnicmp( string->Buffer, expect, string->Length / sizeof(WCHAR) );
1603 #define test_object_type(a,b) _test_object_type(__LINE__,a,b)
1604 static void _test_object_type( unsigned line, HANDLE handle, const WCHAR *expected_name )
1606 char buffer[1024];
1607 OBJECT_TYPE_INFORMATION *type = (OBJECT_TYPE_INFORMATION *)buffer;
1608 UNICODE_STRING expect;
1609 ULONG len = 0;
1610 NTSTATUS status;
1612 RtlInitUnicodeString( &expect, expected_name );
1614 memset( buffer, 0, sizeof(buffer) );
1615 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
1616 ok_(__FILE__,line)( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1617 ok_(__FILE__,line)( len > sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1618 ok_(__FILE__,line)( len >= sizeof(*type) + type->TypeName.Length, "unexpected len %lu\n", len );
1619 ok_(__FILE__,line)(compare_unicode_string( &type->TypeName, expected_name ), "wrong name %s\n",
1620 debugstr_w( type->TypeName.Buffer ));
1621 add_object_type( type );
1624 #define test_object_name(a,b,c) _test_object_name(__LINE__,a,b,c)
1625 static void _test_object_name( unsigned line, HANDLE handle, const WCHAR *expected_name, BOOL todo )
1627 char buffer[1024];
1628 UNICODE_STRING *str = (UNICODE_STRING *)buffer, expect;
1629 ULONG len = 0;
1630 NTSTATUS status;
1632 RtlInitUnicodeString( &expect, expected_name );
1634 memset( buffer, 0, sizeof(buffer) );
1635 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1636 ok_(__FILE__,line)( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1637 ok_(__FILE__,line)( len >= sizeof(OBJECT_NAME_INFORMATION) + str->Length, "unexpected len %lu\n", len );
1638 todo_wine_if (todo)
1639 ok_(__FILE__,line)(compare_unicode_string( str, expected_name ), "got %s, expected %s\n",
1640 debugstr_w(str->Buffer), debugstr_w(expected_name));
1643 static void test_query_object(void)
1645 static const WCHAR name[] = L"\\BaseNamedObjects\\test_event";
1646 HANDLE handle, client;
1647 char buffer[1024];
1648 NTSTATUS status;
1649 ULONG len, expected_len;
1650 OBJECT_BASIC_INFORMATION info;
1651 OBJECT_ATTRIBUTES attr;
1652 UNICODE_STRING path, target, *str;
1653 char dir[MAX_PATH], tmp_path[MAX_PATH], file1[MAX_PATH + 16];
1654 WCHAR expect[100];
1655 LARGE_INTEGER size;
1657 InitializeObjectAttributes( &attr, &path, 0, 0, 0 );
1659 handle = CreateEventA( NULL, FALSE, FALSE, "test_event" );
1661 status = pNtQueryObject( handle, ObjectBasicInformation, NULL, 0, NULL );
1662 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1664 status = pNtQueryObject( handle, ObjectBasicInformation, &info, 0, NULL );
1665 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1667 status = pNtQueryObject( handle, ObjectBasicInformation, NULL, 0, &len );
1668 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1670 len = 0;
1671 status = pNtQueryObject( handle, ObjectBasicInformation, &info, sizeof(OBJECT_BASIC_INFORMATION), &len );
1672 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1673 ok( len >= sizeof(OBJECT_BASIC_INFORMATION), "unexpected len %lu\n", len );
1675 len = 0;
1676 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
1677 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1678 ok( len >= sizeof(UNICODE_STRING) + sizeof(name), "unexpected len %lu\n", len );
1680 len = 0;
1681 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, 0, &len );
1682 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1683 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(L"Event"), "unexpected len %lu\n", len );
1685 len = 0;
1686 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
1687 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1688 ok( len >= sizeof(UNICODE_STRING) + sizeof(name), "unexpected len %lu\n", len );
1690 len = 0;
1691 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(OBJECT_TYPE_INFORMATION), &len );
1692 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1693 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(L"Event"), "unexpected len %lu\n", len );
1695 len = 0;
1696 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1697 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1698 ok( len > sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1699 str = (UNICODE_STRING *)buffer;
1700 ok( sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR) == len, "unexpected len %lu\n", len );
1701 ok( str->Length >= sizeof(name) - sizeof(WCHAR), "unexpected len %u\n", str->Length );
1702 ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_event") * sizeof(WCHAR),
1703 "name too short %s\n", wine_dbgstr_w(str->Buffer) );
1704 /* check for \\Sessions prefix in the name */
1705 swprintf( expect, ARRAY_SIZE(expect), L"\\Sessions\\%u%s", NtCurrentTeb()->Peb->SessionId, name );
1706 ok( (str->Length == wcslen( expect ) * sizeof(WCHAR) && !wcscmp( str->Buffer, expect )) ||
1707 broken( !wcscmp( str->Buffer, name )), /* winxp */
1708 "wrong name %s\n", wine_dbgstr_w(str->Buffer) );
1709 trace( "got %s len %lu\n", wine_dbgstr_w(str->Buffer), len );
1711 len -= sizeof(WCHAR);
1712 status = pNtQueryObject( handle, ObjectNameInformation, buffer, len, &len );
1713 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1714 ok( len >= sizeof(UNICODE_STRING) + sizeof(name), "unexpected len %lu\n", len );
1716 test_object_type( handle, L"Event" );
1718 len -= sizeof(WCHAR);
1719 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, len, &len );
1720 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1721 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(L"Event"), "unexpected len %lu\n", len );
1723 test_no_file_info( handle );
1724 pNtClose( handle );
1726 handle = CreateEventA( NULL, FALSE, FALSE, NULL );
1727 len = 0;
1728 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1729 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1730 ok( len == sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1731 str = (UNICODE_STRING *)buffer;
1732 ok( str->Length == 0, "unexpected len %lu\n", len );
1733 ok( str->Buffer == NULL, "unexpected ptr %p\n", str->Buffer );
1734 test_no_file_info( handle );
1735 pNtClose( handle );
1737 GetWindowsDirectoryA( dir, MAX_PATH );
1738 handle = CreateFileA( dir, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1739 FILE_FLAG_BACKUP_SEMANTICS, 0 );
1740 len = 0;
1741 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1742 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1743 ok( len > sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1744 str = (UNICODE_STRING *)buffer;
1745 expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR);
1746 ok( len == expected_len, "unexpected len %lu\n", len );
1747 trace( "got %s len %lu\n", wine_dbgstr_w(str->Buffer), len );
1749 len = 0;
1750 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
1751 ok( status == STATUS_INFO_LENGTH_MISMATCH, "got %#lx\n", status );
1752 ok( len == expected_len || broken(!len /* XP */ || len == sizeof(UNICODE_STRING) /* 2003 */),
1753 "unexpected len %lu\n", len );
1755 len = 0;
1756 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
1757 ok( status == STATUS_BUFFER_OVERFLOW, "got %#lx\n", status);
1758 ok( len == expected_len, "unexpected len %lu\n", len );
1760 test_object_type( handle, L"File" );
1762 pNtClose( handle );
1764 GetTempPathA(MAX_PATH, tmp_path);
1765 GetTempFileNameA(tmp_path, "foo", 0, file1);
1766 handle = CreateFileA(file1, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0);
1767 test_object_type(handle, L"File");
1768 test_file_info( handle );
1769 pNtClose( handle );
1770 DeleteFileA( file1 );
1772 status = pNtCreateIoCompletion( &handle, IO_COMPLETION_ALL_ACCESS, NULL, 0 );
1773 ok( status == STATUS_SUCCESS, "NtCreateIoCompletion failed %lx\n", status);
1775 test_object_type( handle, L"IoCompletion" );
1776 test_no_file_info( handle );
1778 pNtClose( handle );
1780 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_debug" );
1781 status = pNtCreateDebugObject( &handle, DEBUG_ALL_ACCESS, &attr, 0 );
1782 ok(!status, "NtCreateDebugObject failed: %lx\n", status);
1783 test_object_name( handle, L"\\BaseNamedObjects\\test_debug", FALSE );
1784 test_object_type( handle, L"DebugObject" );
1785 test_no_file_info( handle );
1786 pNtClose(handle);
1788 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_mutant" );
1789 status = pNtCreateMutant( &handle, MUTANT_ALL_ACCESS, &attr, 0 );
1790 ok(!status, "NtCreateMutant failed: %lx\n", status);
1791 test_object_name( handle, L"\\BaseNamedObjects\\test_mutant", FALSE );
1792 test_object_type( handle, L"Mutant" );
1793 test_no_file_info( handle );
1794 pNtClose(handle);
1796 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_sem" );
1797 status = pNtCreateSemaphore( &handle, SEMAPHORE_ALL_ACCESS, &attr, 1, 2 );
1798 ok(!status, "NtCreateSemaphore failed: %lx\n", status);
1799 test_object_name( handle, L"\\BaseNamedObjects\\test_sem", FALSE );
1800 test_object_type( handle, L"Semaphore" );
1801 test_no_file_info( handle );
1802 pNtClose(handle);
1804 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_keyed" );
1805 status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr, 0 );
1806 ok(!status, "NtCreateKeyedEvent failed: %lx\n", status);
1807 test_object_name( handle, L"\\BaseNamedObjects\\test_keyed", FALSE );
1808 test_object_type( handle, L"KeyedEvent" );
1809 test_no_file_info( handle );
1810 pNtClose(handle);
1812 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_compl" );
1813 status = pNtCreateIoCompletion( &handle, IO_COMPLETION_ALL_ACCESS, &attr, 0 );
1814 ok(!status, "NtCreateIoCompletion failed: %lx\n", status);
1815 test_object_name( handle, L"\\BaseNamedObjects\\test_compl", FALSE );
1816 test_object_type( handle, L"IoCompletion" );
1817 test_no_file_info( handle );
1818 pNtClose(handle);
1820 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_job" );
1821 status = pNtCreateJobObject( &handle, JOB_OBJECT_ALL_ACCESS, &attr );
1822 ok(!status, "NtCreateJobObject failed: %lx\n", status);
1823 test_object_name( handle, L"\\BaseNamedObjects\\test_job", FALSE );
1824 test_object_type( handle, L"Job" );
1825 test_no_file_info( handle );
1826 pNtClose(handle);
1828 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_timer" );
1829 status = pNtCreateTimer( &handle, TIMER_ALL_ACCESS, &attr, NotificationTimer );
1830 ok(!status, "NtCreateTimer failed: %lx\n", status);
1831 test_object_type( handle, L"Timer" );
1832 test_no_file_info( handle );
1833 pNtClose(handle);
1835 RtlInitUnicodeString( &path, L"\\DosDevices\\test_link" );
1836 RtlInitUnicodeString( &target, L"\\DosDevices" );
1837 status = pNtCreateSymbolicLinkObject( &handle, SYMBOLIC_LINK_ALL_ACCESS, &attr, &target );
1838 ok(!status, "NtCreateSymbolicLinkObject failed: %lx\n", status);
1839 test_object_type( handle, L"SymbolicLink" );
1840 test_no_file_info( handle );
1841 pNtClose(handle);
1843 handle = GetProcessWindowStation();
1844 swprintf( expect, ARRAY_SIZE(expect), L"\\Sessions\\%u\\Windows\\WindowStations\\WinSta0", NtCurrentTeb()->Peb->SessionId );
1845 test_object_name( handle, expect, FALSE );
1846 test_object_type( handle, L"WindowStation" );
1847 test_no_file_info( handle );
1849 handle = GetThreadDesktop( GetCurrentThreadId() );
1850 test_object_name( handle, L"\\Default", FALSE );
1851 test_object_type( handle, L"Desktop" );
1852 test_no_file_info( handle );
1854 status = pNtCreateDirectoryObject( &handle, DIRECTORY_QUERY, NULL );
1855 ok(status == STATUS_SUCCESS, "Failed to create Directory %08lx\n", status);
1857 test_object_type( handle, L"Directory" );
1858 test_no_file_info( handle );
1860 pNtClose( handle );
1862 size.u.LowPart = 256;
1863 size.u.HighPart = 0;
1864 status = pNtCreateSection( &handle, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
1865 ok( status == STATUS_SUCCESS , "NtCreateSection returned %lx\n", status );
1867 test_object_type( handle, L"Section" );
1868 test_no_file_info( handle );
1870 pNtClose( handle );
1872 handle = CreateMailslotA( "\\\\.\\mailslot\\test_mailslot", 100, 1000, NULL );
1873 ok( handle != INVALID_HANDLE_VALUE, "CreateMailslot failed err %lu\n", GetLastError() );
1875 test_object_name( handle, L"\\Device\\Mailslot\\test_mailslot", FALSE );
1876 test_object_type( handle, L"File" );
1877 test_file_info( handle );
1879 client = CreateFileA( "\\\\.\\mailslot\\test_mailslot", 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
1880 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1882 len = 0;
1883 status = pNtQueryObject( client, ObjectNameInformation, buffer, sizeof(buffer), &len );
1884 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1885 str = (UNICODE_STRING *)buffer;
1886 ok( len == sizeof(UNICODE_STRING) + str->MaximumLength, "unexpected len %lu\n", len );
1887 todo_wine
1888 ok( compare_unicode_string( str, L"\\Device\\Mailslot" ) ||
1889 compare_unicode_string( str, L"\\Device\\Mailslot\\test_mailslot" ) /* win8+ */,
1890 "wrong name %s\n", debugstr_w( str->Buffer ));
1892 test_object_type( client, L"File" );
1893 test_file_info( client );
1895 pNtClose( client );
1896 pNtClose( handle );
1898 handle = CreateFileA( "\\\\.\\mailslot", 0, 0, NULL, OPEN_EXISTING, 0, 0 );
1899 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1901 test_object_name( handle, L"\\Device\\Mailslot", FALSE );
1902 test_object_type( handle, L"File" );
1903 test_file_info( handle );
1905 pNtClose( handle );
1907 handle = CreateNamedPipeA( "\\\\.\\pipe\\test_pipe", PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE,
1908 1, 1000, 1000, 1000, NULL );
1909 ok( handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed err %lu\n", GetLastError() );
1911 test_object_name( handle, L"\\Device\\NamedPipe\\test_pipe", FALSE );
1912 test_object_type( handle, L"File" );
1913 test_file_info( handle );
1915 client = CreateFileA( "\\\\.\\pipe\\test_pipe", GENERIC_READ | GENERIC_WRITE,
1916 0, NULL, OPEN_EXISTING, 0, 0 );
1917 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1919 test_object_type( client, L"File" );
1920 test_file_info( client );
1922 pNtClose( client );
1923 pNtClose( handle );
1925 handle = CreateFileA( "\\\\.\\pipe", 0, 0, NULL, OPEN_EXISTING, 0, 0 );
1926 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1928 test_object_name( handle, L"\\Device\\NamedPipe", FALSE );
1929 test_object_type( handle, L"File" );
1930 test_file_info( handle );
1932 pNtClose( handle );
1934 handle = CreateFileA( "\\\\.\\pipe\\", 0, 0, NULL, OPEN_EXISTING, 0, 0 );
1935 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%lu)\n", GetLastError() );
1937 test_object_name( handle, L"\\Device\\NamedPipe\\", TRUE );
1938 test_object_type( handle, L"File" );
1939 test_file_info( handle );
1941 pNtClose( handle );
1943 RtlInitUnicodeString( &path, L"\\REGISTRY\\Machine" );
1944 status = pNtCreateKey( &handle, KEY_READ, &attr, 0, 0, 0, 0 );
1945 ok( status == STATUS_SUCCESS, "NtCreateKey failed status %lx\n", status );
1947 test_object_name( handle, L"\\REGISTRY\\MACHINE", FALSE );
1948 test_object_type( handle, L"Key" );
1950 pNtClose( handle );
1952 test_object_name( GetCurrentProcess(), L"", FALSE );
1953 test_object_type( GetCurrentProcess(), L"Process" );
1954 test_no_file_info( GetCurrentProcess() );
1956 test_object_name( GetCurrentThread(), L"", FALSE );
1957 test_object_type( GetCurrentThread(), L"Thread" );
1958 test_no_file_info( GetCurrentThread() );
1960 status = pNtOpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &handle);
1961 ok(!status, "OpenProcessToken failed: %lx\n", status);
1963 test_object_name( handle, L"", FALSE );
1964 test_object_type( handle, L"Token" );
1965 test_no_file_info( handle );
1967 pNtClose(handle);
1969 handle = CreateFileA( "nul", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
1970 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1971 test_object_name( handle, L"\\Device\\Null", TRUE );
1972 test_object_type( handle, L"File" );
1973 test_file_info( handle );
1974 pNtClose( handle );
1977 static void test_type_mismatch(void)
1979 HANDLE h;
1980 NTSTATUS res;
1981 OBJECT_ATTRIBUTES attr;
1983 attr.Length = sizeof(attr);
1984 attr.RootDirectory = 0;
1985 attr.ObjectName = NULL;
1986 attr.Attributes = 0;
1987 attr.SecurityDescriptor = NULL;
1988 attr.SecurityQualityOfService = NULL;
1990 res = pNtCreateEvent( &h, 0, &attr, NotificationEvent, 0 );
1991 ok(!res, "can't create event: %lx\n", res);
1993 res = pNtReleaseSemaphore( h, 30, NULL );
1994 ok(res == STATUS_OBJECT_TYPE_MISMATCH, "expected 0xc0000024, got %lx\n", res);
1996 pNtClose( h );
1999 static void test_null_device(void)
2001 OBJECT_ATTRIBUTES attr;
2002 IO_STATUS_BLOCK iosb;
2003 UNICODE_STRING str;
2004 NTSTATUS status;
2005 DWORD num_bytes;
2006 OVERLAPPED ov;
2007 char buf[64];
2008 HANDLE null;
2009 BOOL ret;
2011 memset(buf, 0xAA, sizeof(buf));
2012 memset(&ov, 0, sizeof(ov));
2013 ov.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
2015 RtlInitUnicodeString(&str, L"\\Device\\Null");
2016 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
2017 status = pNtOpenSymbolicLinkObject(&null, SYMBOLIC_LINK_QUERY, &attr);
2018 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
2019 "expected STATUS_OBJECT_TYPE_MISMATCH, got %08lx\n", status);
2021 status = pNtOpenFile(&null, GENERIC_READ | GENERIC_WRITE, &attr, &iosb,
2022 FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
2023 ok(status == STATUS_SUCCESS,
2024 "expected STATUS_SUCCESS, got %08lx\n", status);
2026 test_object_type(null, L"File");
2028 SetLastError(0xdeadbeef);
2029 ret = WriteFile(null, buf, sizeof(buf), &num_bytes, NULL);
2030 ok(!ret, "WriteFile unexpectedly succeeded\n");
2031 ok(GetLastError() == ERROR_INVALID_PARAMETER,
2032 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
2034 SetLastError(0xdeadbeef);
2035 ret = ReadFile(null, buf, sizeof(buf), &num_bytes, NULL);
2036 ok(!ret, "ReadFile unexpectedly succeeded\n");
2037 ok(GetLastError() == ERROR_INVALID_PARAMETER,
2038 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
2040 num_bytes = 0xdeadbeef;
2041 SetLastError(0xdeadbeef);
2042 ret = WriteFile(null, buf, sizeof(buf), &num_bytes, &ov);
2043 ok(ret, "got error %lu\n", GetLastError());
2044 ok(num_bytes == sizeof(buf), "expected num_bytes = %lu, got %lu\n",
2045 (DWORD)sizeof(buf), num_bytes);
2047 num_bytes = 0xdeadbeef;
2048 SetLastError(0xdeadbeef);
2049 ret = ReadFile(null, buf, sizeof(buf), &num_bytes, &ov);
2050 ok(!ret, "expected failure\n");
2051 ok(GetLastError() == ERROR_HANDLE_EOF, "got error %lu\n", GetLastError());
2053 pNtClose(null);
2055 null = CreateFileA("\\\\.\\Null", GENERIC_READ | GENERIC_WRITE,
2056 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2057 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2058 ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
2059 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
2060 "expected ERROR_FILE_NOT_FOUND, got %lu\n", GetLastError());
2062 null = CreateFileA("\\\\.\\Device\\Null", GENERIC_READ | GENERIC_WRITE,
2063 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2064 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2065 ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
2066 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
2067 "expected ERROR_PATH_NOT_FOUND, got %lu\n", GetLastError());
2069 CloseHandle(ov.hEvent);
2072 static void test_process(void)
2074 OBJECT_ATTRIBUTES attr;
2075 CLIENT_ID cid;
2076 NTSTATUS status;
2077 HANDLE process;
2079 if (!pNtOpenProcess)
2081 win_skip( "NtOpenProcess not supported, skipping test\n" );
2082 return;
2085 InitializeObjectAttributes( &attr, NULL, 0, 0, NULL );
2087 cid.UniqueProcess = 0;
2088 cid.UniqueThread = 0;
2089 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, NULL, &cid );
2090 todo_wine ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcess returned %lx\n", status );
2091 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, NULL );
2092 todo_wine ok( status == STATUS_INVALID_PARAMETER_MIX, "NtOpenProcess returned %lx\n", status );
2094 cid.UniqueProcess = 0;
2095 cid.UniqueThread = 0;
2096 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2097 ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %lx\n", status );
2099 cid.UniqueProcess = ULongToHandle( 0xdeadbeef );
2100 cid.UniqueThread = ULongToHandle( 0xdeadbeef );
2101 process = (HANDLE)0xdeadbeef;
2102 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2103 ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %lx\n", status );
2104 ok( !process || broken(process == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", process );
2106 cid.UniqueProcess = ULongToHandle( GetCurrentThreadId() );
2107 cid.UniqueThread = 0;
2108 process = (HANDLE)0xdeadbeef;
2109 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2110 ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %lx\n", status );
2111 ok( !process || broken(process == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", process );
2113 cid.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
2114 cid.UniqueThread = 0;
2115 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2116 ok( !status, "NtOpenProcess returned %lx\n", status );
2117 pNtClose( process );
2119 cid.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
2120 cid.UniqueThread = ULongToHandle( GetCurrentThreadId() );
2121 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2122 ok( !status, "NtOpenProcess returned %lx\n", status );
2123 pNtClose( process );
2124 status = pNtOpenProcess( (HANDLE *)0xdeadbee0, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2125 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcess returned %lx\n", status );
2128 static void test_token(void)
2130 NTSTATUS status;
2131 HANDLE handle, handle2;
2133 status = pNtOpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS, (HANDLE *)0xdeadbee0 );
2134 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcessToken failed: %lx\n", status);
2135 status = pNtOpenThreadToken( GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, (HANDLE *)0xdeadbee0 );
2136 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcessToken failed: %lx\n", status);
2137 handle = (HANDLE)0xdeadbeef;
2138 status = pNtOpenProcessToken( (HANDLE)0xdead, TOKEN_ALL_ACCESS, &handle );
2139 ok( status == STATUS_INVALID_HANDLE, "NtOpenProcessToken failed: %lx\n", status);
2140 ok( !handle || broken(handle == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", handle );
2141 handle = (HANDLE)0xdeadbeef;
2142 status = pNtOpenThreadToken( (HANDLE)0xdead, TOKEN_ALL_ACCESS, TRUE, &handle );
2143 ok( status == STATUS_INVALID_HANDLE, "NtOpenThreadToken failed: %lx\n", status);
2144 ok( !handle || broken(handle == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", handle );
2146 status = pNtOpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS, &handle );
2147 ok( status == STATUS_SUCCESS, "NtOpenProcessToken failed: %lx\n", status);
2148 status = pNtDuplicateToken( handle, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, &handle2 );
2149 ok( status == STATUS_SUCCESS, "NtOpenProcessToken failed: %lx\n", status);
2150 pNtClose( handle2 );
2151 status = pNtDuplicateToken( handle, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, (HANDLE *)0xdeadbee0 );
2152 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcessToken failed: %lx\n", status);
2153 handle2 = (HANDLE)0xdeadbeef;
2154 status = pNtDuplicateToken( (HANDLE)0xdead, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, &handle2 );
2155 ok( status == STATUS_INVALID_HANDLE, "NtOpenProcessToken failed: %lx\n", status);
2156 ok( !handle2 || broken(handle2 == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", handle2 );
2157 pNtClose( handle );
2160 #define DEBUG_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2161 #define DEBUG_GENERIC_READ (STANDARD_RIGHTS_READ|DEBUG_READ_EVENT)
2162 #define DEBUG_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|DEBUG_PROCESS_ASSIGN)
2163 #define DESKTOP_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|DESKTOP_SWITCHDESKTOP)
2164 #define DESKTOP_GENERIC_READ (STANDARD_RIGHTS_READ|DESKTOP_ENUMERATE|DESKTOP_READOBJECTS)
2165 #define DESKTOP_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|DESKTOP_WRITEOBJECTS|DESKTOP_JOURNALPLAYBACK|\
2166 DESKTOP_JOURNALRECORD|DESKTOP_HOOKCONTROL|DESKTOP_CREATEMENU| \
2167 DESKTOP_CREATEWINDOW)
2168 #define DIRECTORY_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|DIRECTORY_TRAVERSE|DIRECTORY_QUERY)
2169 #define DIRECTORY_GENERIC_READ (STANDARD_RIGHTS_READ|DIRECTORY_TRAVERSE|DIRECTORY_QUERY)
2170 #define DIRECTORY_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|DIRECTORY_CREATE_SUBDIRECTORY|\
2171 DIRECTORY_CREATE_OBJECT)
2172 #define EVENT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2173 #define EVENT_GENERIC_READ (STANDARD_RIGHTS_READ|EVENT_QUERY_STATE)
2174 #define EVENT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|EVENT_MODIFY_STATE)
2175 #define IO_COMPLETION_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2176 #define IO_COMPLETION_GENERIC_READ (STANDARD_RIGHTS_READ|IO_COMPLETION_QUERY_STATE)
2177 #define IO_COMPLETION_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|IO_COMPLETION_MODIFY_STATE)
2178 #define JOB_OBJECT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2179 #define JOB_OBJECT_GENERIC_READ (STANDARD_RIGHTS_READ|JOB_OBJECT_QUERY)
2180 #define JOB_OBJECT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|JOB_OBJECT_TERMINATE|\
2181 JOB_OBJECT_SET_ATTRIBUTES|JOB_OBJECT_ASSIGN_PROCESS)
2182 #define KEY_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|KEY_CREATE_LINK|KEY_NOTIFY|\
2183 KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE)
2184 #define KEY_GENERIC_READ (STANDARD_RIGHTS_READ|KEY_NOTIFY|KEY_ENUMERATE_SUB_KEYS|\
2185 KEY_QUERY_VALUE)
2186 #define KEY_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|KEY_CREATE_SUB_KEY|KEY_SET_VALUE)
2187 #define KEYEDEVENT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE)
2188 #define KEYEDEVENT_GENERIC_READ (STANDARD_RIGHTS_READ|KEYEDEVENT_WAIT)
2189 #define KEYEDEVENT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|KEYEDEVENT_WAKE)
2190 #define MUTANT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2191 #define MUTANT_GENERIC_READ (STANDARD_RIGHTS_READ|MUTANT_QUERY_STATE)
2192 #define MUTANT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE)
2193 #define PROCESS_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE|\
2194 PROCESS_QUERY_LIMITED_INFORMATION|PROCESS_TERMINATE)
2195 #define PROCESS_GENERIC_READ (STANDARD_RIGHTS_READ|PROCESS_VM_READ|PROCESS_QUERY_INFORMATION)
2196 #define PROCESS_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|PROCESS_SUSPEND_RESUME|\
2197 PROCESS_SET_INFORMATION|PROCESS_SET_QUOTA|PROCESS_CREATE_PROCESS|\
2198 PROCESS_DUP_HANDLE|PROCESS_VM_WRITE|PROCESS_VM_OPERATION|\
2199 PROCESS_CREATE_THREAD)
2200 #define SECTION_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SECTION_MAP_EXECUTE)
2201 #define SECTION_GENERIC_READ (STANDARD_RIGHTS_READ|SECTION_QUERY|SECTION_MAP_READ)
2202 #define SECTION_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|SECTION_MAP_WRITE)
2203 #define SEMAPHORE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2204 #define SEMAPHORE_GENERIC_READ (STANDARD_RIGHTS_READ|SEMAPHORE_QUERY_STATE)
2205 #define SEMAPHORE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|SEMAPHORE_MODIFY_STATE)
2206 #define SYMBOLIC_LINK_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYMBOLIC_LINK_QUERY)
2207 #define SYMBOLIC_LINK_GENERIC_READ (STANDARD_RIGHTS_READ|SYMBOLIC_LINK_QUERY)
2208 #define SYMBOLIC_LINK_GENERIC_WRITE (STANDARD_RIGHTS_WRITE)
2209 #define THREAD_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE|THREAD_RESUME|\
2210 THREAD_QUERY_LIMITED_INFORMATION)
2211 #define THREAD_GENERIC_READ (STANDARD_RIGHTS_READ|THREAD_QUERY_INFORMATION|THREAD_GET_CONTEXT)
2212 #define THREAD_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|THREAD_SET_LIMITED_INFORMATION|\
2213 THREAD_SET_INFORMATION|THREAD_SET_CONTEXT|THREAD_SUSPEND_RESUME|\
2214 THREAD_TERMINATE|0x04)
2215 #define TIMER_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2216 #define TIMER_GENERIC_READ (STANDARD_RIGHTS_READ|TIMER_QUERY_STATE)
2217 #define TIMER_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|TIMER_MODIFY_STATE)
2218 #define TOKEN_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|TOKEN_IMPERSONATE|TOKEN_ASSIGN_PRIMARY)
2219 #define TOKEN_GENERIC_READ (STANDARD_RIGHTS_READ|TOKEN_QUERY_SOURCE|TOKEN_QUERY|TOKEN_DUPLICATE)
2220 #define TOKEN_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|TOKEN_ADJUST_SESSIONID|TOKEN_ADJUST_DEFAULT|\
2221 TOKEN_ADJUST_GROUPS|TOKEN_ADJUST_PRIVILEGES)
2222 #define TYPE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE)
2223 #define TYPE_GENERIC_READ (STANDARD_RIGHTS_READ)
2224 #define TYPE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE)
2225 #define WINSTA_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|WINSTA_EXITWINDOWS|WINSTA_ACCESSGLOBALATOMS)
2226 #define WINSTA_GENERIC_READ (STANDARD_RIGHTS_READ|WINSTA_READSCREEN|WINSTA_ENUMERATE|\
2227 WINSTA_READATTRIBUTES|WINSTA_ENUMDESKTOPS)
2228 #define WINSTA_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|WINSTA_WRITEATTRIBUTES|WINSTA_CREATEDESKTOP|\
2229 WINSTA_ACCESSCLIPBOARD)
2231 #undef WINSTA_ALL_ACCESS
2232 #undef DESKTOP_ALL_ACCESS
2233 #define WINSTA_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x37f)
2234 #define DESKTOP_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x1ff)
2235 #define DEVICE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1ff)
2236 #define TYPE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x1)
2238 static void *align_ptr( void *ptr )
2240 ULONG align = sizeof(DWORD_PTR) - 1;
2241 return (void *)(((DWORD_PTR)ptr + align) & ~align);
2244 static void test_duplicate_object(void)
2246 NTSTATUS status;
2247 HANDLE handle;
2249 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2250 &handle, PROCESS_ALL_ACCESS, 0, 0 );
2251 ok( !status, "NtDuplicateObject failed %lx\n", status );
2252 pNtClose( handle );
2253 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2254 NULL, PROCESS_ALL_ACCESS, 0, 0 );
2255 ok( !status, "NtDuplicateObject failed %lx\n", status );
2257 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2258 (HANDLE *)0xdeadbee0, PROCESS_ALL_ACCESS, 0, 0 );
2259 ok( status == STATUS_ACCESS_VIOLATION, "NtDuplicateObject failed %lx\n", status );
2261 handle = (HANDLE)0xdeadbeef;
2262 status = pNtDuplicateObject( GetCurrentProcess(), (HANDLE)0xdead, GetCurrentProcess(),
2263 &handle, PROCESS_ALL_ACCESS, 0, 0 );
2264 ok( status == STATUS_INVALID_HANDLE, "NtDuplicateObject failed %lx\n", status );
2265 ok( !handle, "handle set %p\n", handle );
2267 handle = (HANDLE)0xdeadbeef;
2268 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2269 &handle, ~0u, 0, 0 );
2270 todo_wine
2271 ok( status == STATUS_ACCESS_DENIED, "NtDuplicateObject failed %lx\n", status );
2272 todo_wine
2273 ok( !handle, "handle set %p\n", handle );
2274 if (!status) pNtClose( handle );
2277 static void test_object_types(void)
2279 static const struct { const WCHAR *name; GENERIC_MAPPING mapping; ULONG mask, broken; } tests[] =
2281 #define TYPE(name,gen,extra,broken) { name, { gen ## _GENERIC_READ, gen ## _GENERIC_WRITE, \
2282 gen ## _GENERIC_EXECUTE, gen ## _ALL_ACCESS }, gen ## _ALL_ACCESS | extra, broken }
2283 TYPE( L"DebugObject", DEBUG, 0, 0 ),
2284 TYPE( L"Desktop", DESKTOP, 0, 0 ),
2285 TYPE( L"Device", FILE, 0, 0 ),
2286 TYPE( L"Directory", DIRECTORY, 0, 0 ),
2287 TYPE( L"Event", EVENT, 0, 0 ),
2288 TYPE( L"File", FILE, 0, 0 ),
2289 TYPE( L"IoCompletion", IO_COMPLETION, 0, 0 ),
2290 TYPE( L"Job", JOB_OBJECT, 0, JOB_OBJECT_IMPERSONATE ),
2291 TYPE( L"Key", KEY, SYNCHRONIZE, 0 ),
2292 TYPE( L"KeyedEvent", KEYEDEVENT, SYNCHRONIZE, 0 ),
2293 TYPE( L"Mutant", MUTANT, 0, 0 ),
2294 TYPE( L"Process", PROCESS, 0, 0 ),
2295 TYPE( L"Section", SECTION, SYNCHRONIZE, 0 ),
2296 TYPE( L"Semaphore", SEMAPHORE, 0, 0 ),
2297 TYPE( L"SymbolicLink", SYMBOLIC_LINK, 0, 0xfffe ),
2298 TYPE( L"Thread", THREAD, 0, THREAD_RESUME ),
2299 TYPE( L"Timer", TIMER, 0, 0 ),
2300 TYPE( L"Token", TOKEN, SYNCHRONIZE, 0 ),
2301 TYPE( L"Type", TYPE, SYNCHRONIZE, 0 ),
2302 TYPE( L"WindowStation", WINSTA, 0, 0 ),
2303 #undef TYPE
2305 unsigned int i, j;
2306 BOOLEAN tested[ARRAY_SIZE(all_types)] = { 0 };
2307 char buffer[256];
2308 OBJECT_TYPES_INFORMATION *info = (OBJECT_TYPES_INFORMATION *)buffer;
2309 GENERIC_MAPPING map;
2310 NTSTATUS status;
2311 ULONG len, retlen;
2313 memset( buffer, 0xcc, sizeof(buffer) );
2314 status = pNtQueryObject( NULL, ObjectTypesInformation, info, sizeof(buffer), &len );
2315 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
2316 ok( info->NumberOfTypes < 100 || info->NumberOfTypes == 0xcccccccc, /* wow64 */
2317 "wrong number of types %lu\n", info->NumberOfTypes );
2319 info = malloc( len + 16 ); /* Windows gets the length wrong on WoW64 and overflows the buffer */
2320 memset( info, 0xcc, sizeof(*info) );
2321 status = pNtQueryObject( NULL, ObjectTypesInformation, info, len, &retlen );
2322 ok( retlen <= len + 16, "wrong len %lx/%lx\n", len, retlen );
2323 ok( len == retlen || broken( retlen >= len - 32 && retlen <= len + 32 ), /* wow64 */
2324 "wrong len %lx/%lx\n", len, retlen );
2325 ok( !status, "NtQueryObject failed %lx\n", status );
2326 if (!status)
2328 OBJECT_TYPE_INFORMATION *type = align_ptr( info + 1 );
2329 for (i = 0; i < info->NumberOfTypes; i++)
2331 add_object_type( type );
2332 type = align_ptr( (char *)type->TypeName.Buffer + type->TypeName.MaximumLength );
2335 free( info );
2337 for (i = 0; i < ARRAY_SIZE(tests); i++)
2339 for (j = 0; j < ARRAY_SIZE(all_types); j++)
2341 if (!all_types[j].TypeName.Buffer) continue;
2342 if (wcscmp( tests[i].name, all_types[j].TypeName.Buffer )) continue;
2343 map = all_types[j].GenericMapping;
2344 ok( !memcmp( &map, &tests[i].mapping, sizeof(GENERIC_MAPPING) ) ||
2345 broken( !((map.GenericRead ^ tests[i].mapping.GenericRead) & ~tests[i].broken) &&
2346 !((map.GenericWrite ^ tests[i].mapping.GenericWrite) & ~tests[i].broken) &&
2347 !((map.GenericExecute ^ tests[i].mapping.GenericExecute) & ~tests[i].broken) &&
2348 !((map.GenericAll ^ tests[i].mapping.GenericAll) & ~tests[i].broken) ),
2349 "%s: mismatched mappings %08lx,%08lx,%08lx,%08lx / %08lx,%08lx,%08lx,%08lx\n",
2350 debugstr_w( tests[i].name ),
2351 all_types[j].GenericMapping.GenericRead, all_types[j].GenericMapping.GenericWrite,
2352 all_types[j].GenericMapping.GenericExecute, all_types[j].GenericMapping.GenericAll,
2353 tests[i].mapping.GenericRead, tests[i].mapping.GenericWrite,
2354 tests[i].mapping.GenericExecute, tests[i].mapping.GenericAll );
2355 ok( all_types[j].ValidAccessMask == tests[i].mask ||
2356 broken( !((all_types[j].ValidAccessMask ^ tests[i].mask) & ~tests[i].broken) ),
2357 "%s: mismatched access mask %08lx / %08lx\n", debugstr_w( tests[i].name ),
2358 all_types[j].ValidAccessMask, tests[i].mask );
2359 tested[j] = TRUE;
2360 break;
2362 ok( j < ARRAY_SIZE(all_types), "type %s not found\n", debugstr_w(tests[i].name) );
2364 for (j = 0; j < ARRAY_SIZE(all_types); j++)
2366 if (!all_types[j].TypeName.Buffer) continue;
2367 if (tested[j]) continue;
2368 trace( "not tested: %s\n", debugstr_w(all_types[j].TypeName.Buffer ));
2372 static DWORD WINAPI test_get_next_thread_proc( void *arg )
2374 HANDLE event = (HANDLE)arg;
2376 WaitForSingleObject(event, INFINITE);
2377 return 0;
2380 static void test_get_next_thread(void)
2382 HANDLE hprocess = GetCurrentProcess();
2383 HANDLE handle, thread, event, prev;
2384 NTSTATUS status;
2385 DWORD thread_id;
2386 BOOL found;
2388 if (!pNtGetNextThread)
2390 win_skip("NtGetNextThread is not available.\n");
2391 return;
2394 event = CreateEventA(NULL, FALSE, FALSE, NULL);
2396 thread = CreateThread( NULL, 0, test_get_next_thread_proc, event, 0, &thread_id );
2398 status = pNtGetNextThread(hprocess, NULL, THREAD_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, NULL);
2399 ok(status == STATUS_ACCESS_VIOLATION, "Got unexpected status %#lx.\n", status);
2401 found = FALSE;
2402 prev = NULL;
2403 while (!(status = pNtGetNextThread(hprocess, prev, THREAD_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle)))
2405 if (prev)
2407 if (GetThreadId(handle) == thread_id)
2408 found = TRUE;
2409 pNtClose(prev);
2411 else
2413 ok(GetThreadId(handle) == GetCurrentThreadId(), "Got unexpected thread id %04lx, current %04lx.\n",
2414 GetThreadId(handle), GetCurrentThreadId());
2416 prev = handle;
2417 handle = (HANDLE)0xdeadbeef;
2419 pNtClose(prev);
2420 ok(!handle, "Got unexpected handle %p.\n", handle);
2421 ok(status == STATUS_NO_MORE_ENTRIES, "Unexpected status %#lx.\n", status);
2422 ok(found, "Thread not found.\n");
2424 handle = (HANDLE)0xdeadbeef;
2425 status = pNtGetNextThread((void *)0xdeadbeef, 0, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle);
2426 ok(status == STATUS_INVALID_HANDLE, "Unexpected status %#lx.\n", status);
2427 ok(!handle, "Got unexpected handle %p.\n", handle);
2428 handle = (HANDLE)0xdeadbeef;
2429 status = pNtGetNextThread(hprocess, (void *)0xdeadbeef, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle);
2430 ok(status == STATUS_INVALID_HANDLE, "Unexpected status %#lx.\n", status);
2431 ok(!handle, "Got unexpected handle %p.\n", handle);
2433 /* Reversed search is only supported on recent enough Win10. */
2434 status = pNtGetNextThread(hprocess, 0, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 1, &handle);
2435 ok(!status || broken(status == STATUS_INVALID_PARAMETER), "Unexpected status %#lx.\n", status);
2436 if (!status)
2437 pNtClose(handle);
2439 status = pNtGetNextThread(hprocess, 0, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 2, &handle);
2440 ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %#lx.\n", status);
2442 SetEvent(event);
2443 WaitForSingleObject(thread, INFINITE);
2445 found = FALSE;
2446 prev = NULL;
2447 while (!(status = pNtGetNextThread(hprocess, prev, THREAD_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle)))
2449 if (prev)
2450 pNtClose(prev);
2451 if (GetThreadId(handle) == thread_id)
2452 found = TRUE;
2453 prev = handle;
2455 pNtClose(prev);
2456 ok(found, "Thread not found.\n");
2458 CloseHandle(thread);
2461 static void test_globalroot(void)
2463 NTSTATUS status;
2464 IO_STATUS_BLOCK iosb;
2465 UNICODE_STRING str;
2466 OBJECT_ATTRIBUTES attr;
2467 HANDLE h;
2468 WCHAR buffer[256];
2469 ULONG len, full_len, i;
2470 static const struct { const WCHAR *name, *target; } symlinks[] = {
2471 { L"\\??\\GLOBALROOT", L"" },
2472 { L"\\??\\GLOBALROOT\\??\\GLOBALROOT", L"" },
2473 { L"\\??\\GLOBALROOT\\??\\GLOBALROOT\\??\\GLOBALROOT", L"" },
2474 { L"\\??\\GLOBALROOT\\DosDevices", L"\\??" },
2475 { L"\\??\\GLOBALROOT\\BaseNamedObjects\\Global", NULL },
2478 for (i = 0; i < ARRAY_SIZE(symlinks); i++)
2480 pRtlInitUnicodeString(&str, symlinks[i].name);
2481 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
2482 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
2483 ok(status == STATUS_SUCCESS, "NtOpenSymbolicLinkObject failed %08lx\n", status);
2485 str.Buffer = buffer;
2486 str.MaximumLength = sizeof(buffer);
2487 len = 0xdeadbeef;
2488 memset( buffer, 0xaa, sizeof(buffer) );
2489 status = pNtQuerySymbolicLinkObject( h, &str, &len);
2490 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08lx\n", status );
2491 full_len = str.Length + sizeof(WCHAR);
2492 ok( len == full_len, "bad length %lu (expected %lu)\n", len, full_len );
2493 ok( buffer[len / sizeof(WCHAR) - 1] == 0, "no terminating null\n" );
2495 if (symlinks[i].target)
2497 ok( compare_unicode_string( &str, symlinks[i].target ),
2498 "symlink %s: target expected %s, got %s\n",
2499 debugstr_w( symlinks[i].name ),
2500 debugstr_w( symlinks[i].target ),
2501 debugstr_w( str.Buffer ) );
2504 pNtClose(h);
2507 pRtlInitUnicodeString(&str, L"\\??\\GLOBALROOT\\Device\\Null");
2508 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
2509 status = pNtOpenFile(&h, GENERIC_READ | GENERIC_WRITE, &attr, &iosb,
2510 FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
2511 ok(status == STATUS_SUCCESS,
2512 "expected STATUS_SUCCESS, got %08lx\n", status);
2514 test_object_type(h, L"File");
2516 pNtClose(h);
2519 static void test_object_identity(void)
2521 NTSTATUS status;
2522 HANDLE h1, h2;
2524 if (!pNtCompareObjects)
2526 skip("NtCompareObjects is not available.\n");
2527 return;
2530 status = pNtCompareObjects( GetCurrentProcess(), GetCurrentProcess() );
2531 ok( status == STATUS_SUCCESS, "comparing GetCurrentProcess() to self failed with %08lx\n", status );
2533 status = pNtCompareObjects( GetCurrentThread(), GetCurrentThread() );
2534 ok( status == STATUS_SUCCESS, "comparing GetCurrentThread() to self failed with %08lx\n", status );
2536 status = pNtCompareObjects( GetCurrentProcess(), GetCurrentThread() );
2537 ok( status == STATUS_NOT_SAME_OBJECT, "comparing GetCurrentProcess() to GetCurrentThread() returned %08lx\n", status );
2539 h1 = NULL;
2540 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2541 &h1, 0, 0, DUPLICATE_SAME_ACCESS );
2542 ok( status == STATUS_SUCCESS, "failed to duplicate current process handle: %08lx\n", status);
2544 status = pNtCompareObjects( GetCurrentProcess(), h1 );
2545 ok( status == STATUS_SUCCESS, "comparing GetCurrentProcess() with %p failed with %08lx\n", h1, status );
2547 pNtClose( h1 );
2549 h1 = CreateFileA( "\\\\.\\NUL", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
2550 ok( h1 != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
2552 h2 = NULL;
2553 status = pNtDuplicateObject( GetCurrentProcess(), h1, GetCurrentProcess(),
2554 &h2, 0, 0, DUPLICATE_SAME_ACCESS );
2555 ok( status == STATUS_SUCCESS, "failed to duplicate handle %p: %08lx\n", h1, status);
2557 status = pNtCompareObjects( h1, h2 );
2558 ok( status == STATUS_SUCCESS, "comparing %p with %p failed with %08lx\n", h1, h2, status );
2560 pNtClose( h2 );
2562 h2 = CreateFileA( "\\\\.\\NUL", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
2563 ok( h2 != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
2565 status = pNtCompareObjects( h1, h2 );
2566 ok( status == STATUS_NOT_SAME_OBJECT, "comparing %p with %p returned %08lx\n", h1, h2, status );
2568 pNtClose( h2 );
2569 pNtClose( h1 );
2572 static void test_query_directory(void)
2574 static const DIRECTORY_BASIC_INFORMATION empty_info;
2575 char buffer[200];
2576 DIRECTORY_BASIC_INFORMATION *info = (void *)buffer;
2577 ULONG context, size, needed_size;
2578 const WCHAR *name1, *name2;
2579 HANDLE dir, child1, child2;
2580 OBJECT_ATTRIBUTES attr;
2581 UNICODE_STRING string;
2582 NTSTATUS status;
2583 BOOL is_wow64 = FALSE;
2585 #ifndef _WIN64
2586 if (!IsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
2587 #endif
2589 RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest" );
2590 InitializeObjectAttributes( &attr, &string, 0, 0, NULL );
2591 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
2592 ok( !status, "got %#lx\n", status );
2594 context = 0xdeadbeef;
2595 size = 0xdeadbeef;
2596 status = NtQueryDirectoryObject( dir, info, 0, TRUE, TRUE, &context, &size );
2597 ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2598 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2599 ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2601 context = 0xdeadbeef;
2602 size = 0xdeadbeef;
2603 status = NtQueryDirectoryObject( dir, info, 0, FALSE, TRUE, &context, &size );
2604 todo_wine ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2605 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2606 todo_wine ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2608 context = 0xdeadbeef;
2609 size = 0xdeadbeef;
2610 memset( buffer, 0xcc, sizeof(buffer) );
2611 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2612 ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2613 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2614 ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2615 if (size == sizeof(*info))
2616 ok( !memcmp( &info[0], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2618 context = 0xdeadbeef;
2619 size = 0xdeadbeef;
2620 memset( buffer, 0xcc, sizeof(buffer) );
2621 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), FALSE, TRUE, &context, &size );
2622 todo_wine ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2623 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2624 todo_wine ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2625 if (size == sizeof(*info))
2626 ok( !memcmp( &info[0], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2628 RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest\\Telamon" );
2629 status = NtCreateMutant( &child1, GENERIC_ALL, &attr, FALSE );
2630 ok( !status, "got %#lx\n", status );
2632 RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest\\Oileus" );
2633 status = NtCreateMutant( &child2, GENERIC_ALL, &attr, FALSE );
2634 ok( !status, "got %#lx\n", status );
2636 context = 0xdeadbeef;
2637 size = 0xdeadbeef;
2638 status = NtQueryDirectoryObject( NULL, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2639 ok( status == STATUS_INVALID_HANDLE, "got %#lx\n", status );
2640 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2641 ok( size == 0xdeadbeef || broken(!size) /* WoW64 */, "got size %lu\n", size);
2643 size = 0xdeadbeef;
2644 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, NULL, &size );
2645 ok( status == STATUS_ACCESS_VIOLATION, "got %#lx\n", status );
2646 ok( size == 0xdeadbeef, "got size %lu\n", size);
2648 context = 0xdeadbeef;
2649 size = 0xdeadbeef;
2650 memset( buffer, 0xcc, sizeof(buffer) );
2651 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2652 ok( !status, "got %#lx\n", status );
2653 ok( context == 1, "got context %#lx\n", context );
2654 ok( size && size < sizeof(buffer), "got size %lu\n", size );
2655 if (!wcscmp( info[0].ObjectName.Buffer, L"Oileus" ))
2657 name1 = L"Oileus";
2658 name2 = L"Telamon";
2660 else
2662 name1 = L"Telamon";
2663 name2 = L"Oileus";
2665 check_unicode_string( &info[0].ObjectName, name1 );
2666 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2667 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2669 memset( buffer, 0xcc, sizeof(buffer) );
2670 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
2671 ok( !status, "got %#lx\n", status );
2672 ok( context == 2, "got context %#lx\n", context );
2673 check_unicode_string( &info[0].ObjectName, name2 );
2674 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2675 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2677 size = 0xdeadbeef;
2678 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
2679 ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2680 ok( context == 2, "got context %#lx\n", context );
2681 ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2683 memset( buffer, 0xcc, sizeof(buffer) );
2684 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2685 ok( !status, "got %#lx\n", status );
2686 ok( context == 1, "got context %#lx\n", context );
2687 check_unicode_string( &info[0].ObjectName, name1 );
2688 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2689 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2691 needed_size = size;
2693 size = 0xdeadbeef;
2694 context = 0xdeadbeef;
2695 status = NtQueryDirectoryObject( dir, info, 0, TRUE, TRUE, &context, &size );
2696 ok( status == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", status );
2697 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2698 ok( size == needed_size, "expected size %lu, got %lu\n", needed_size, size );
2700 size = 0xdeadbeef;
2701 memset( buffer, 0xcc, sizeof(buffer) );
2702 status = NtQueryDirectoryObject( dir, info, needed_size - 1, TRUE, TRUE, &context, &size );
2703 ok( status == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", status );
2704 ok( size == needed_size, "expected size %lu, got %lu\n", needed_size, size );
2706 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, NULL );
2707 ok( !status, "got %#lx\n", status );
2709 context = 0;
2710 memset( buffer, 0xcc, sizeof(buffer) );
2711 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
2712 ok( !status, "got %#lx\n", status );
2713 ok( context == 1, "got context %#lx\n", context );
2714 check_unicode_string( &info[0].ObjectName, name1 );
2715 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2716 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2718 memset( buffer, 0xcc, sizeof(buffer) );
2719 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), FALSE, TRUE, &context, &size );
2720 todo_wine ok( !status, "got %#lx\n", status );
2721 if (!status)
2723 ok( context == 2, "got context %#lx\n", context );
2724 check_unicode_string( &info[0].ObjectName, name1 );
2725 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2726 check_unicode_string( &info[1].ObjectName, name2 );
2727 check_unicode_string( &info[1].ObjectTypeName, L"Mutant" );
2728 ok( !memcmp( &info[2], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2731 needed_size = size;
2732 size = 0xdeadbeef;
2733 context = 0xdeadbeef;
2734 memset( buffer, 0xcc, sizeof(buffer) );
2735 status = NtQueryDirectoryObject( dir, info, needed_size - 1, FALSE, TRUE, &context, &size );
2736 todo_wine ok( status == STATUS_MORE_ENTRIES, "got %#lx\n", status );
2737 if (status == STATUS_MORE_ENTRIES)
2739 ok( context == 1, "got context %#lx\n", context );
2740 ok( size > 0 && size < needed_size, "got size %lu\n", size );
2741 check_unicode_string( &info[0].ObjectName, name1 );
2742 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2743 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2746 size = 0xdeadbeef;
2747 context = 0xdeadbeef;
2748 memset( buffer, 0xcc, sizeof(buffer) );
2749 status = NtQueryDirectoryObject( dir, info, sizeof(*info), FALSE, TRUE, &context, &size );
2750 todo_wine ok( status == STATUS_MORE_ENTRIES
2751 || broken(status == STATUS_BUFFER_TOO_SMALL) /* wow64 */, "got %#lx\n", status );
2752 if (status == STATUS_MORE_ENTRIES)
2754 ok( !context, "got context %#lx\n", context );
2755 ok( size == sizeof(*info), "got size %lu\n", size );
2756 ok( !memcmp( &info[0], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2759 size = 0xdeadbeef;
2760 context = 0xdeadbeef;
2761 status = NtQueryDirectoryObject( dir, info, 0, FALSE, TRUE, &context, &size );
2762 todo_wine ok( status == STATUS_MORE_ENTRIES
2763 || broken(status == STATUS_BUFFER_TOO_SMALL) /* wow64 */, "got %#lx\n", status );
2764 if (status == STATUS_MORE_ENTRIES)
2766 ok( !context, "got context %#lx\n", context );
2767 ok( size == sizeof(*info), "got size %lu\n", size );
2770 context = 1;
2771 memset( buffer, 0xcc, sizeof(buffer) );
2772 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), FALSE, FALSE, &context, &size );
2773 todo_wine ok( !status, "got %#lx\n", status );
2774 if (!status)
2776 ok( context == 2, "got context %#lx\n", context );
2777 check_unicode_string( &info[0].ObjectName, name2 );
2778 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2779 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2782 pNtClose( child1 );
2783 pNtClose( child2 );
2784 pNtClose( dir );
2787 #define test_object_name_with_null(a,b) _test_object_name_with_null(__LINE__,a,b)
2788 static void _test_object_name_with_null(unsigned line, HANDLE handle, UNICODE_STRING *expect)
2790 char buffer[1024];
2791 UNICODE_STRING *str = (UNICODE_STRING *)buffer;
2792 ULONG len = 0;
2793 NTSTATUS status;
2795 memset(buffer, 0, sizeof(buffer));
2796 status = pNtQueryObject(handle, ObjectNameInformation, buffer, sizeof(buffer), &len);
2797 ok_(__FILE__,line)(status == STATUS_SUCCESS, "got %08lx\n", status);
2798 ok_(__FILE__,line)(len >= sizeof(OBJECT_NAME_INFORMATION) + str->Length, "got %lu\n", len);
2799 ok_(__FILE__,line)(str->Length == expect->Length, "got %u, expected %u\n", str->Length, expect->Length);
2800 ok_(__FILE__,line)(!wcsnicmp(str->Buffer, expect->Buffer, str->Length/sizeof(WCHAR)), "got %s, expected %s\n",
2801 debugstr_w(str->Buffer), debugstr_w(expect->Buffer));
2804 static void test_null_in_object_name(void)
2806 WCHAR name[256], name3[256], *p, *name_exp, *name3_exp;
2807 HANDLE handle, handle2;
2808 NTSTATUS status;
2809 OBJECT_ATTRIBUTES attr, attr2, attr3;
2810 UNICODE_STRING nameU, name2U, name3U, name2U_exp, name3U_exp;
2811 LARGE_INTEGER size;
2812 #ifndef _WIN64
2813 BOOL is_wow64 = FALSE;
2814 #endif
2816 trace("running as %d bit\n", (int)sizeof(void *) * 8);
2818 swprintf(name, ARRAY_SIZE(name), L"\\Sessions\\%u\\BaseNamedObjects\\wine_test", NtCurrentTeb()->Peb->SessionId);
2819 swprintf(name3, ARRAY_SIZE(name3), L"\\Sessions\\%u\\BaseNamedObjects\\wine_test", NtCurrentTeb()->Peb->SessionId);
2820 p = wcsrchr(name3, '\\');
2821 p[5] = 0; /* => \\wine\0test */
2823 RtlInitUnicodeString(&nameU, name);
2824 InitializeObjectAttributes(&attr, &nameU, 0, 0, NULL);
2826 name2U = nameU;
2827 name2U.Length += sizeof(WCHAR); /* add terminating \0 to string length */
2828 InitializeObjectAttributes(&attr2, &name2U, 0, 0, NULL);
2830 name3U = nameU;
2831 name3U.Buffer = name3;
2832 InitializeObjectAttributes(&attr3, &name3U, 0, 0, NULL);
2834 status = pNtCreateEvent(&handle, GENERIC_ALL, &attr, NotificationEvent, FALSE);
2835 ok(!status, "got %08lx\n", status);
2836 test_object_name(handle, name, FALSE);
2837 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr);
2838 ok(!status, "got %08lx\n", status);
2839 test_object_name(handle2, name, FALSE);
2840 pNtClose(handle2);
2841 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr2);
2842 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2843 pNtClose(handle);
2844 status = pNtCreateEvent(&handle, GENERIC_ALL, &attr2, NotificationEvent, FALSE);
2845 ok(!status, "got %08lx\n", status);
2846 test_object_name_with_null(handle, &name2U);
2847 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr2);
2848 ok(!status, "got %08lx\n", status);
2849 test_object_name_with_null(handle2, &name2U);
2850 pNtClose(handle2);
2851 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr);
2852 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2853 pNtClose(handle);
2854 status = pNtCreateEvent(&handle, GENERIC_ALL, &attr3, NotificationEvent, FALSE);
2855 ok(!status, "got %08lx\n", status);
2856 test_object_name_with_null(handle, &name3U);
2857 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr3);
2858 ok(!status, "got %08lx\n", status);
2859 test_object_name_with_null(handle2, &name3U);
2860 pNtClose(handle2);
2861 pNtClose(handle);
2863 status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr, 0);
2864 ok(!status, "got %08lx\n", status);
2865 test_object_name(handle, name, FALSE);
2866 pNtClose(handle);
2867 status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr2, 0);
2868 ok(!status, "got %08lx\n", status);
2869 test_object_name_with_null(handle, &name2U);
2870 pNtClose(handle);
2871 status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr3, 0);
2872 ok(!status, "got %08lx\n", status);
2873 test_object_name_with_null(handle, &name3U);
2874 pNtClose(handle);
2876 status = pNtCreateMutant(&handle, GENERIC_ALL, &attr, 0);
2877 ok(!status, "got %08lx\n", status);
2878 test_object_name(handle, name, FALSE);
2879 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr);
2880 ok(!status, "got %08lx\n", status);
2881 test_object_name(handle2, name, FALSE);
2882 pNtClose(handle2);
2883 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr2);
2884 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2885 pNtClose(handle);
2886 status = pNtCreateMutant(&handle, GENERIC_ALL, &attr2, 0);
2887 ok(!status, "got %08lx\n", status);
2888 test_object_name_with_null(handle, &name2U);
2889 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr2);
2890 ok(!status, "got %08lx\n", status);
2891 test_object_name_with_null(handle2, &name2U);
2892 pNtClose(handle2);
2893 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr);
2894 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2895 pNtClose(handle);
2896 status = pNtCreateMutant(&handle, GENERIC_ALL, &attr3, 0);
2897 ok(!status, "got %08lx\n", status);
2898 test_object_name_with_null(handle, &name3U);
2899 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr3);
2900 ok(!status, "got %08lx\n", status);
2901 test_object_name_with_null(handle2, &name3U);
2902 pNtClose(handle2);
2903 pNtClose(handle);
2905 status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr, 1, 2);
2906 ok(!status, "got %08lx\n", status);
2907 test_object_name(handle, name, FALSE);
2908 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr);
2909 ok(!status, "got %08lx\n", status);
2910 test_object_name(handle2, name, FALSE);
2911 pNtClose(handle2);
2912 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr2);
2913 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2914 pNtClose(handle);
2915 status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr2, 1, 2);
2916 ok(!status, "got %08lx\n", status);
2917 test_object_name_with_null(handle, &name2U);
2918 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr2);
2919 ok(!status, "got %08lx\n", status);
2920 test_object_name_with_null(handle2, &name2U);
2921 pNtClose(handle2);
2922 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr);
2923 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2924 pNtClose(handle);
2925 status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr3, 1, 2);
2926 ok(!status, "got %08lx\n", status);
2927 test_object_name_with_null(handle, &name3U);
2928 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr3);
2929 ok(!status, "got %08lx\n", status);
2930 test_object_name_with_null(handle2, &name3U);
2931 pNtClose(handle2);
2932 pNtClose(handle);
2934 status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr, 0);
2935 ok(!status, "got %08lx\n", status);
2936 test_object_name(handle, name, FALSE);
2937 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr);
2938 ok(!status, "got %08lx\n", status);
2939 test_object_name(handle2, name, FALSE);
2940 pNtClose(handle2);
2941 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr2);
2942 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2943 pNtClose(handle);
2944 status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr2, 0);
2945 ok(!status, "got %08lx\n", status);
2946 test_object_name_with_null(handle, &name2U);
2947 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr2);
2948 ok(!status, "got %08lx\n", status);
2949 test_object_name_with_null(handle2, &name2U);
2950 pNtClose(handle2);
2951 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr);
2952 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2953 pNtClose(handle);
2954 status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr3, 0);
2955 ok(!status, "got %08lx\n", status);
2956 test_object_name_with_null(handle, &name3U);
2957 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr3);
2958 ok(!status, "got %08lx\n", status);
2959 test_object_name_with_null(handle2, &name3U);
2960 pNtClose(handle2);
2961 pNtClose(handle);
2963 status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr, 0);
2964 ok(!status, "got %08lx\n", status);
2965 test_object_name(handle, name, FALSE);
2966 status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr);
2967 ok(!status, "got %08lx\n", status);
2968 test_object_name(handle2, name, FALSE);
2969 pNtClose(handle2);
2970 pNtClose(handle);
2971 status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr2, 0);
2972 ok(!status, "got %08lx\n", status);
2973 test_object_name_with_null(handle, &name2U);
2974 status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr2);
2975 ok(!status, "got %08lx\n", status);
2976 test_object_name_with_null(handle2, &name2U);
2977 pNtClose(handle2);
2978 pNtClose(handle);
2979 status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr3, 0);
2980 ok(!status, "got %08lx\n", status);
2981 test_object_name_with_null(handle, &name3U);
2982 status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr3);
2983 ok(!status, "got %08lx\n", status);
2984 test_object_name_with_null(handle2, &name3U);
2985 pNtClose(handle2);
2986 pNtClose(handle);
2988 status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr);
2989 ok(!status, "got %08lx\n", status);
2990 test_object_name(handle, name, FALSE);
2991 status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr);
2992 ok(!status, "got %08lx\n", status);
2993 test_object_name(handle2, name, FALSE);
2994 pNtClose(handle2);
2995 pNtClose(handle);
2996 status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr2);
2997 ok(!status, "got %08lx\n", status);
2998 test_object_name_with_null(handle, &name2U);
2999 status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr2);
3000 ok(!status, "got %08lx\n", status);
3001 test_object_name_with_null(handle2, &name2U);
3002 pNtClose(handle2);
3003 pNtClose(handle);
3004 status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr3);
3005 ok(!status, "got %08lx\n", status);
3006 test_object_name_with_null(handle, &name3U);
3007 status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr3);
3008 ok(!status, "got %08lx\n", status);
3009 test_object_name_with_null(handle2, &name3U);
3010 pNtClose(handle2);
3011 pNtClose(handle);
3013 status = pNtCreateTimer(&handle, GENERIC_ALL, &attr, NotificationTimer);
3014 ok(!status, "got %08lx\n", status);
3015 test_object_name(handle, name, FALSE);
3016 status = pNtOpenTimer(&handle2, GENERIC_ALL, &attr);
3017 ok(!status, "got %08lx\n", status);
3018 test_object_name(handle2, name, FALSE);
3019 pNtClose(handle2);
3020 pNtClose(handle);
3021 status = pNtCreateTimer(&handle, GENERIC_ALL, &attr2, NotificationTimer);
3022 ok(!status, "got %08lx\n", status);
3023 test_object_name_with_null(handle, &name2U);
3024 status = pNtOpenTimer(&handle2, GENERIC_ALL, &attr2);
3025 ok(!status, "got %08lx\n", status);
3026 test_object_name_with_null(handle2, &name2U);
3027 pNtClose(handle2);
3028 pNtClose(handle);
3029 status = pNtCreateTimer(&handle, GENERIC_ALL, &attr3, NotificationTimer);
3030 ok(!status, "got %08lx\n", status);
3031 test_object_name_with_null(handle, &name3U);
3032 status = pNtOpenTimer(&handle2, GENERIC_ALL, &attr3);
3033 ok(!status, "got %08lx\n", status);
3034 test_object_name_with_null(handle2, &name3U);
3035 pNtClose(handle2);
3036 pNtClose(handle);
3038 size.QuadPart = 4096;
3039 status = pNtCreateSection(&handle, GENERIC_ALL, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
3040 ok(!status, "got %08lx\n", status);
3041 test_object_name(handle, name, FALSE);
3042 status = pNtOpenSection(&handle2, GENERIC_ALL, &attr);
3043 ok(!status, "got %08lx\n", status);
3044 test_object_name(handle2, name, FALSE);
3045 pNtClose(handle2);
3046 pNtClose(handle);
3047 status = pNtCreateSection(&handle, GENERIC_ALL, &attr2, &size, PAGE_READWRITE, SEC_COMMIT, 0);
3048 ok(!status, "got %08lx\n", status);
3049 test_object_name_with_null(handle, &name2U);
3050 status = pNtOpenSection(&handle2, GENERIC_ALL, &attr2);
3051 ok(!status, "got %08lx\n", status);
3052 test_object_name_with_null(handle2, &name2U);
3053 pNtClose(handle2);
3054 pNtClose(handle);
3055 status = pNtCreateSection(&handle, GENERIC_ALL, &attr3, &size, PAGE_READWRITE, SEC_COMMIT, 0);
3056 ok(!status, "got %08lx\n", status);
3057 test_object_name_with_null(handle, &name3U);
3058 status = pNtOpenSection(&handle2, GENERIC_ALL, &attr3);
3059 ok(!status, "got %08lx\n", status);
3060 test_object_name_with_null(handle2, &name3U);
3061 pNtClose(handle2);
3062 pNtClose(handle);
3064 wcscpy(name, L"\\Registry\\Machine\\Software\\wine_test");
3065 wcscpy(name3, L"\\Registry\\Machine\\Software\\wine_test");
3066 p = wcsrchr(name3, '\\');
3067 p[5] = 0; /* => \\wine\0test */
3069 RtlInitUnicodeString(&nameU, name);
3070 name2U = nameU;
3071 name3U = nameU;
3072 name3U.Buffer = name3;
3073 #ifdef _WIN64
3074 name_exp = name;
3075 name3_exp = name3;
3076 name2U_exp = name2U;
3077 #else
3078 if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)
3080 name_exp = (WCHAR *)L"\\Registry\\Machine\\Software\\WOW6432Node\\wine_test";
3081 name3_exp =(WCHAR *) L"\\Registry\\Machine\\Software\\WOW6432Node\\wine\0test";
3083 else
3085 name_exp = name;
3086 name3_exp = name3;
3088 RtlInitUnicodeString(&name2U_exp, name_exp);
3089 #endif
3090 name3U_exp = name2U_exp;
3091 name3U_exp.Buffer = name3_exp;
3092 name2U.Length += sizeof(WCHAR); /* add terminating \0 to string length */
3093 name2U_exp.Length += sizeof(WCHAR); /* add terminating \0 to string length */
3095 status = pNtCreateKey(&handle, GENERIC_ALL, &attr, 0, NULL, 0, NULL);
3096 ok(!status || status == STATUS_ACCESS_DENIED || broken(status == STATUS_OBJECT_PATH_NOT_FOUND) /* win8 */, "got %08lx\n", status);
3097 if (!status)
3099 test_object_name(handle, name_exp, FALSE);
3100 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr);
3101 ok(!status, "got %08lx\n", status);
3102 test_object_name(handle2, name_exp, FALSE);
3103 pNtClose(handle2);
3104 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr2);
3105 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
3106 pNtDeleteKey(handle);
3107 pNtClose(handle);
3108 status = pNtCreateKey(&handle, GENERIC_ALL, &attr2, 0, NULL, 0, NULL);
3109 ok(!status, "got %08lx\n", status);
3110 test_object_name_with_null(handle, &name2U_exp);
3111 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr2);
3112 ok(!status, "got %08lx\n", status);
3113 test_object_name_with_null(handle, &name2U_exp);
3114 pNtClose(handle2);
3115 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr);
3116 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
3117 pNtDeleteKey(handle);
3118 pNtClose(handle);
3119 status = pNtCreateKey(&handle, GENERIC_ALL, &attr3, 0, NULL, 0, NULL);
3120 ok(!status, "got %08lx\n", status);
3121 test_object_name_with_null(handle, &name3U_exp);
3122 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr3);
3123 ok(!status, "got %08lx\n", status);
3124 test_object_name_with_null(handle, &name3U_exp);
3125 pNtClose(handle2);
3126 pNtDeleteKey(handle);
3127 pNtClose(handle);
3129 else
3130 skip("Limited access to \\Registry\\Machine\\Software key, skipping the tests\n");
3133 START_TEST(om)
3135 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
3137 pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent");
3138 pNtCreateJobObject = (void *)GetProcAddress(hntdll, "NtCreateJobObject");
3139 pNtOpenJobObject = (void *)GetProcAddress(hntdll, "NtOpenJobObject");
3140 pNtCreateKey = (void *)GetProcAddress(hntdll, "NtCreateKey");
3141 pNtOpenKey = (void *)GetProcAddress(hntdll, "NtOpenKey");
3142 pNtDeleteKey = (void *)GetProcAddress(hntdll, "NtDeleteKey");
3143 pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile");
3144 pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant");
3145 pNtOpenEvent = (void *)GetProcAddress(hntdll, "NtOpenEvent");
3146 pNtOpenMutant = (void *)GetProcAddress(hntdll, "NtOpenMutant");
3147 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
3148 pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
3149 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
3150 pNtCreateNamedPipeFile = (void *)GetProcAddress(hntdll, "NtCreateNamedPipeFile");
3151 pNtOpenDirectoryObject = (void *)GetProcAddress(hntdll, "NtOpenDirectoryObject");
3152 pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject");
3153 pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject");
3154 pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject");
3155 pNtQuerySymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject");
3156 pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
3157 pNtOpenSemaphore = (void *)GetProcAddress(hntdll, "NtOpenSemaphore");
3158 pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer");
3159 pNtOpenTimer = (void *)GetProcAddress(hntdll, "NtOpenTimer");
3160 pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection");
3161 pNtOpenSection = (void *)GetProcAddress(hntdll, "NtOpenSection");
3162 pNtQueryObject = (void *)GetProcAddress(hntdll, "NtQueryObject");
3163 pNtReleaseSemaphore = (void *)GetProcAddress(hntdll, "NtReleaseSemaphore");
3164 pNtCreateKeyedEvent = (void *)GetProcAddress(hntdll, "NtCreateKeyedEvent");
3165 pNtOpenKeyedEvent = (void *)GetProcAddress(hntdll, "NtOpenKeyedEvent");
3166 pNtCreateIoCompletion = (void *)GetProcAddress(hntdll, "NtCreateIoCompletion");
3167 pNtOpenIoCompletion = (void *)GetProcAddress(hntdll, "NtOpenIoCompletion");
3168 pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile");
3169 pNtOpenProcess = (void *)GetProcAddress(hntdll, "NtOpenProcess");
3170 pNtCreateDebugObject = (void *)GetProcAddress(hntdll, "NtCreateDebugObject");
3171 pNtGetNextThread = (void *)GetProcAddress(hntdll, "NtGetNextThread");
3172 pNtOpenProcessToken = (void *)GetProcAddress(hntdll, "NtOpenProcessToken");
3173 pNtOpenThreadToken = (void *)GetProcAddress(hntdll, "NtOpenThreadToken");
3174 pNtDuplicateToken = (void *)GetProcAddress(hntdll, "NtDuplicateToken");
3175 pNtDuplicateObject = (void *)GetProcAddress(hntdll, "NtDuplicateObject");
3176 pNtCompareObjects = (void *)GetProcAddress(hntdll, "NtCompareObjects");
3178 test_null_in_object_name();
3179 test_case_sensitive();
3180 test_namespace_pipe();
3181 test_name_collisions();
3182 test_name_limits();
3183 test_directory();
3184 test_symboliclink();
3185 test_query_object();
3186 test_type_mismatch();
3187 test_null_device();
3188 test_process();
3189 test_token();
3190 test_duplicate_object();
3191 test_object_types();
3192 test_get_next_thread();
3193 test_globalroot();
3194 test_object_identity();
3195 test_query_directory();