server: Check for DELETE access in NtMakeTemporaryObject().
[wine.git] / dlls / ntdll / tests / om.c
blob4b1664412950577531b09751aecc0d43c0bf6435
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 memset( &iosb, 0xcc, sizeof(iosb) );
416 status = pNtCreateNamedPipeFile( &h1, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
417 FILE_SHARE_READ|FILE_SHARE_WRITE,
418 FILE_OPEN_IF, FILE_PIPE_FULL_DUPLEX,
419 FALSE, FALSE, FALSE, 10, 256, 256, NULL );
420 ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
421 ok( iosb.Status == STATUS_SUCCESS, "wrong status %08lx\n", status);
422 ok( iosb.Information == FILE_OPENED, "wrong info %Ix\n", iosb.Information );
423 pNtClose(h1);
425 h1 = CreateNamedPipeA( "\\\\.\\pipe\\named_pipe", PIPE_ACCESS_DUPLEX,
426 PIPE_READMODE_BYTE, 10, 256, 256, 1000, NULL );
427 winerr = GetLastError();
428 ok(h1 != 0 && winerr == ERROR_ALREADY_EXISTS, "CreateNamedPipeA got ret=%p (%ld)\n", h1, winerr);
429 pNtClose(h1);
430 pNtClose(h);
433 static void test_all_kernel_objects( UINT line, OBJECT_ATTRIBUTES *attr,
434 NTSTATUS create_expect, NTSTATUS open_expect )
436 UNICODE_STRING target;
437 LARGE_INTEGER size;
438 NTSTATUS status, status2;
439 HANDLE ret, ret2;
441 RtlInitUnicodeString( &target, L"\\DosDevices" );
442 size.QuadPart = 4096;
444 ret = ret2 = (HANDLE)0xdeadbeef;
445 status = pNtCreateMutant( &ret, GENERIC_ALL, attr, FALSE );
446 ok( status == create_expect, "%u: NtCreateMutant failed %lx\n", line, status );
447 status2 = pNtOpenMutant( &ret2, GENERIC_ALL, attr );
448 ok( status2 == open_expect, "%u: NtOpenMutant failed %lx\n", line, status2 );
449 if (!status) pNtClose( ret );
450 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
451 "%u: NtCreateMutant handle %p\n", line, ret );
452 if (!status2) pNtClose( ret2 );
453 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
454 "%u: NtOpenMutant handle %p\n", line, ret );
456 ret = ret2 = (HANDLE)0xdeadbeef;
457 status = pNtCreateSemaphore( &ret, GENERIC_ALL, attr, 1, 2 );
458 ok( status == create_expect, "%u: NtCreateSemaphore failed %lx\n", line, status );
459 status2 = pNtOpenSemaphore( &ret2, GENERIC_ALL, attr );
460 ok( status2 == open_expect, "%u: NtOpenSemaphore failed %lx\n", line, status2 );
461 if (!status) pNtClose( ret );
462 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
463 "%u: NtCreateSemaphore handle %p\n", line, ret );
464 if (!status2) pNtClose( ret2 );
465 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
466 "%u: NtOpenSemaphore handle %p\n", line, ret );
467 ret = (HANDLE)0xdeadbeef;
468 status = pNtCreateSemaphore( &ret, GENERIC_ALL, attr, 2, 1 );
469 ok( status == STATUS_INVALID_PARAMETER ||
470 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
471 "%u: NtCreateSemaphore failed %lx\n", line, status );
472 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
473 "%u: NtCreateSemaphore handle %p\n", line, ret );
475 ret = ret2 = (HANDLE)0xdeadbeef;
476 status = pNtCreateEvent( &ret, GENERIC_ALL, attr, SynchronizationEvent, 0 );
477 ok( status == create_expect, "%u: NtCreateEvent failed %lx\n", line, status );
478 status2 = pNtOpenEvent( &ret2, GENERIC_ALL, attr );
479 ok( status2 == open_expect, "%u: NtOpenEvent failed %lx\n", line, status2 );
480 if (!status) pNtClose( ret );
481 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
482 "%u: NtCreateEvent handle %p\n", line, ret );
483 if (!status2) pNtClose( ret2 );
484 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
485 "%u: NtOpenEvent handle %p\n", line, ret );
486 ret = (HANDLE)0xdeadbeef;
487 status = pNtCreateEvent( &ret, GENERIC_ALL, attr, 2, 0 );
488 ok( status == STATUS_INVALID_PARAMETER ||
489 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
490 "%u: NtCreateEvent failed %lx\n", line, status );
491 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
492 "%u: NtCreateEvent handle %p\n", line, ret );
494 ret = ret2 = (HANDLE)0xdeadbeef;
495 status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, attr, 0 );
496 ok( status == create_expect, "%u: NtCreateKeyedEvent failed %lx\n", line, status );
497 status2 = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, attr );
498 ok( status2 == open_expect, "%u: NtOpenKeyedEvent failed %lx\n", line, status2 );
499 if (!status) pNtClose( ret );
500 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
501 "%u: NtCreateKeyedEvent handle %p\n", line, ret );
502 if (!status2) pNtClose( ret2 );
503 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
504 "%u: NtOpenKeyedEvent handle %p\n", line, ret );
506 ret = ret2 = (HANDLE)0xdeadbeef;
507 status = pNtCreateTimer( &ret, GENERIC_ALL, attr, NotificationTimer );
508 ok( status == create_expect, "%u: NtCreateTimer failed %lx\n", line, status );
509 status2 = pNtOpenTimer( &ret2, GENERIC_ALL, attr );
510 ok( status2 == open_expect, "%u: NtOpenTimer failed %lx\n", line, status2 );
511 if (!status) pNtClose( ret );
512 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
513 "%u: NtCreateTimer handle %p\n", line, ret );
514 if (!status2) pNtClose( ret2 );
515 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
516 "%u: NtOpenTimer handle %p\n", line, ret );
517 ret = (HANDLE)0xdeadbeef;
518 status = pNtCreateTimer( &ret, GENERIC_ALL, attr, 2 );
519 ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PARAMETER_4 ||
520 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
521 "%u: NtCreateTimer failed %lx\n", line, status );
522 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
523 "%u: NtCreateTimer handle %p\n", line, ret );
525 ret = ret2 = (HANDLE)0xdeadbeef;
526 status = pNtCreateIoCompletion( &ret, GENERIC_ALL, attr, 0 );
527 ok( status == create_expect, "%u: NtCreateIoCompletion failed %lx\n", line, status );
528 status2 = pNtOpenIoCompletion( &ret2, GENERIC_ALL, attr );
529 ok( status2 == open_expect, "%u: NtOpenIoCompletion failed %lx\n", line, status2 );
530 if (!status) pNtClose( ret );
531 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
532 "%u: NtCreateIoCompletion handle %p\n", line, ret );
533 if (!status2) pNtClose( ret2 );
534 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
535 "%u: NtOpenIoCompletion handle %p\n", line, ret );
537 ret = ret2 = (HANDLE)0xdeadbeef;
538 status = pNtCreateJobObject( &ret, GENERIC_ALL, attr );
539 ok( status == create_expect, "%u: NtCreateJobObject failed %lx\n", line, status );
540 status2 = pNtOpenJobObject( &ret2, GENERIC_ALL, attr );
541 ok( status2 == open_expect, "%u: NtOpenJobObject failed %lx\n", line, status2 );
542 if (!status) pNtClose( ret );
543 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
544 "%u: NtCreateJobObject handle %p\n", line, ret );
545 if (!status2) pNtClose( ret2 );
546 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
547 "%u: NtOpenJobObject handle %p\n", line, ret );
549 ret = ret2 = (HANDLE)0xdeadbeef;
550 status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, attr );
551 ok( status == create_expect, "%u: NtCreateDirectoryObject failed %lx\n", line, status );
552 status2 = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, attr );
553 ok( status2 == open_expect, "%u: NtOpenDirectoryObject failed %lx\n", line, status2 );
554 if (!status) pNtClose( ret );
555 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
556 "%u: NtCreateDirectoryObject handle %p\n", line, ret );
557 if (!status2) pNtClose( ret2 );
558 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
559 "%u: NtOpenDirectoryObject handle %p\n", line, ret );
561 ret = ret2 = (HANDLE)0xdeadbeef;
562 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, attr, &target );
563 ok( status == create_expect, "%u: NtCreateSymbolicLinkObject failed %lx\n", line, status );
564 status2 = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, attr );
565 ok( status2 == open_expect, "%u: NtOpenSymbolicLinkObject failed %lx\n", line, status2 );
566 if (!status) pNtClose( ret );
567 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
568 "%u: NtCreateSymbolicLinkObject handle %p\n", line, ret );
569 if (!status2) pNtClose( ret2 );
570 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
571 "%u: NtOpenSymbolicLinkObject handle %p\n", line, ret );
572 ret = (HANDLE)0xdeadbeef;
573 target.MaximumLength = 0;
574 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, attr, &target );
575 ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PARAMETER_4 ||
576 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
577 "%u: NtCreateSymbolicLinkObject failed %lx\n", line, status );
578 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
579 "%u: NtCreateSymbolicLinkObject handle %p\n", line, ret );
581 ret = ret2 = (HANDLE)0xdeadbeef;
582 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, attr, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
583 ok( status == create_expect, "%u: NtCreateSection failed %lx\n", line, status );
584 status2 = pNtOpenSection( &ret2, SECTION_MAP_WRITE, attr );
585 ok( status2 == open_expect, "%u: NtOpenSection failed %lx\n", line, status2 );
586 if (!status) pNtClose( ret );
587 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
588 "%u: NtCreateSection handle %p\n", line, ret );
589 if (!status2) pNtClose( ret2 );
590 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
591 "%u: NtOpenSection handle %p\n", line, ret );
592 ret = (HANDLE)0xdeadbeef;
593 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, attr, &size, 0x1234, SEC_COMMIT, 0 );
594 ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PAGE_PROTECTION ||
595 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
596 "%u: NtCreateSection failed %lx\n", line, status );
597 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
598 "%u: NtCreateSection handle %p\n", line, ret );
600 ret = ret2 = (HANDLE)0xdeadbeef;
601 status = pNtCreateDebugObject( &ret, DEBUG_ALL_ACCESS, attr, 0 );
602 ok( status == create_expect, "%u: NtCreateDebugObject failed %lx\n", line, status );
603 if (!status) pNtClose( ret );
604 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
605 "%u: NtCreateDebugObject handle %p\n", line, ret );
606 status = pNtCreateDebugObject( &ret2, DEBUG_ALL_ACCESS, attr, 0xdead );
607 ok( status == STATUS_INVALID_PARAMETER ||
608 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
609 "%u: NtCreateDebugObject failed %lx\n", line, status );
610 ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
611 "%u: NtCreateDebugObject handle %p\n", line, ret );
614 static void test_name_limits(void)
616 static const WCHAR pipeW[] = L"\\Device\\NamedPipe\\";
617 static const WCHAR mailslotW[] = L"\\Device\\MailSlot\\";
618 static const WCHAR registryW[] = L"\\REGISTRY\\Machine\\SOFTWARE\\Microsoft\\";
619 OBJECT_ATTRIBUTES attr, attr2, attr3;
620 IO_STATUS_BLOCK iosb;
621 LARGE_INTEGER size, timeout;
622 UNICODE_STRING str, str2, target;
623 NTSTATUS status;
624 HANDLE ret, ret2;
625 DWORD i;
627 InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
628 InitializeObjectAttributes( &attr2, &str, 0, (HANDLE)0xdeadbeef, NULL );
629 InitializeObjectAttributes( &attr3, &str, 0, 0, NULL );
630 str.Buffer = HeapAlloc( GetProcessHeap(), 0, 65536 + sizeof(registryW));
631 str.MaximumLength = 65534;
632 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i] = 'a';
633 size.QuadPart = 4096;
634 RtlInitUnicodeString( &target, L"\\DosDevices" );
636 attr.RootDirectory = get_base_dir();
637 str.Length = 0;
638 status = pNtCreateMutant( &ret, GENERIC_ALL, &attr2, FALSE );
639 ok( status == STATUS_SUCCESS, "%u: NtCreateMutant failed %lx\n", str.Length, status );
640 attr3.RootDirectory = ret;
641 status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr );
642 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenMutant failed %lx\n", str.Length, status );
643 status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr3 );
644 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
645 "%u: NtOpenMutant failed %lx\n", str.Length, status );
646 pNtClose( ret );
647 status = pNtCreateSemaphore( &ret, GENERIC_ALL, &attr2, 1, 2 );
648 ok( status == STATUS_SUCCESS, "%u: NtCreateSemaphore failed %lx\n", str.Length, status );
649 attr3.RootDirectory = ret;
650 status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr );
651 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSemaphore failed %lx\n", str.Length, status );
652 status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr3 );
653 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
654 "%u: NtOpenSemaphore failed %lx\n", str.Length, status );
655 pNtClose( ret );
656 status = pNtCreateEvent( &ret, GENERIC_ALL, &attr2, SynchronizationEvent, 0 );
657 ok( status == STATUS_SUCCESS, "%u: NtCreateEvent failed %lx\n", str.Length, status );
658 attr3.RootDirectory = ret;
659 status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr );
660 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenEvent failed %lx\n", str.Length, status );
661 status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr3 );
662 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
663 "%u: NtOpenEvent failed %lx\n", str.Length, status );
664 pNtClose( ret );
665 status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, &attr2, 0 );
666 ok( status == STATUS_SUCCESS, "%u: NtCreateKeyedEvent failed %lx\n", str.Length, status );
667 attr3.RootDirectory = ret;
668 status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr );
669 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenKeyedEvent failed %lx\n", str.Length, status );
670 status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr3 );
671 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
672 "%u: NtOpenKeyedEvent failed %lx\n", str.Length, status );
673 pNtClose( ret );
674 status = pNtCreateTimer( &ret, GENERIC_ALL, &attr2, NotificationTimer );
675 ok( status == STATUS_SUCCESS, "%u: NtCreateTimer failed %lx\n", str.Length, status );
676 attr3.RootDirectory = ret;
677 status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr );
678 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenTimer failed %lx\n", str.Length, status );
679 status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr3 );
680 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
681 "%u: NtOpenTimer failed %lx\n", str.Length, status );
682 pNtClose( ret );
683 status = pNtCreateIoCompletion( &ret, GENERIC_ALL, &attr2, 0 );
684 ok( status == STATUS_SUCCESS, "%u: NtCreateCompletion failed %lx\n", str.Length, status );
685 attr3.RootDirectory = ret;
686 status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr );
687 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenCompletion failed %lx\n", str.Length, status );
688 status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr3 );
689 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
690 "%u: NtOpenCompletion failed %lx\n", str.Length, status );
691 pNtClose( ret );
692 status = pNtCreateJobObject( &ret, GENERIC_ALL, &attr2 );
693 ok( status == STATUS_SUCCESS, "%u: NtCreateJobObject failed %lx\n", str.Length, status );
694 attr3.RootDirectory = ret;
695 status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr );
696 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenJobObject failed %lx\n", str.Length, status );
697 status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr3 );
698 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
699 "%u: NtOpenJobObject failed %lx\n", str.Length, status );
700 pNtClose( ret );
701 status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, &attr2 );
702 ok( status == STATUS_SUCCESS, "%u: NtCreateDirectoryObject failed %lx\n", str.Length, status );
703 attr3.RootDirectory = ret;
704 status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr );
705 ok( status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_DENIED), /* winxp */
706 "%u: NtOpenDirectoryObject failed %lx\n", str.Length, status );
707 if (!status) pNtClose( ret2 );
708 status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr3 );
709 ok( status == STATUS_SUCCESS, "%u: NtOpenDirectoryObject failed %lx\n", str.Length, status );
710 pNtClose( ret2 );
711 pNtClose( ret );
712 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, &attr2, &target );
713 ok( status == STATUS_SUCCESS, "%u: NtCreateSymbolicLinkObject failed %lx\n", str.Length, status );
714 attr3.RootDirectory = ret;
715 status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr );
716 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSymbolicLinkObject failed %lx\n", str.Length, status );
717 status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr3 );
718 ok( status == STATUS_SUCCESS, "%u: NtOpenSymbolicLinkObject failed %lx\n", str.Length, status );
719 pNtClose( ret2 );
720 pNtClose( ret );
721 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, &attr2, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
722 ok( status == STATUS_SUCCESS, "%u: NtCreateSection failed %lx\n", str.Length, status );
723 attr3.RootDirectory = ret;
724 status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr );
725 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSection failed %lx\n", str.Length, status );
726 status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr3 );
727 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
728 "%u: NtOpenSection failed %lx\n", str.Length, status );
729 pNtClose( ret );
731 str.Length = 67;
732 test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
734 str.Length = 65532;
735 test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS );
737 str.Length = 65534;
738 test_all_kernel_objects( __LINE__, &attr, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
740 str.Length = 128;
741 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
743 if (attr.Length == sizeof(attr))
744 test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS );
745 else
746 test_all_kernel_objects( __LINE__, &attr, STATUS_INVALID_PARAMETER, STATUS_INVALID_PARAMETER );
748 attr.Length = sizeof(attr);
750 /* null attributes or ObjectName, with or without RootDirectory */
751 attr3.RootDirectory = 0;
752 attr2.ObjectName = attr3.ObjectName = NULL;
753 test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
754 test_all_kernel_objects( __LINE__, &attr3, STATUS_SUCCESS, STATUS_OBJECT_PATH_SYNTAX_BAD );
755 attr2.ObjectName = attr3.ObjectName = (void *)0xdeadbeef;
756 test_all_kernel_objects( __LINE__, &attr2, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
757 test_all_kernel_objects( __LINE__, &attr3, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
758 attr2.ObjectName = attr3.ObjectName = &str2;
759 str2.Buffer = (WCHAR *)((char *)pipeW + 1); /* misaligned buffer */
760 str2.Length = 3;
761 test_all_kernel_objects( __LINE__, &attr2, STATUS_DATATYPE_MISALIGNMENT, STATUS_DATATYPE_MISALIGNMENT );
762 test_all_kernel_objects( __LINE__, &attr3, STATUS_DATATYPE_MISALIGNMENT, STATUS_DATATYPE_MISALIGNMENT );
763 str2.Buffer = (WCHAR *)0xdeadbee0;
764 str2.Length = 2;
765 test_all_kernel_objects( __LINE__, &attr2, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
766 test_all_kernel_objects( __LINE__, &attr3, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
768 attr3.ObjectName = &str2;
769 pRtlInitUnicodeString( &str2, L"\\BaseNamedObjects\\Local" );
770 status = pNtOpenSymbolicLinkObject( &ret, SYMBOLIC_LINK_QUERY, &attr3 );
771 ok( status == STATUS_SUCCESS, "can't open BaseNamedObjects\\Local %lx\n", status );
772 attr3.ObjectName = &str;
773 attr3.RootDirectory = ret;
774 test_all_kernel_objects( __LINE__, &attr3, STATUS_OBJECT_TYPE_MISMATCH, STATUS_OBJECT_TYPE_MISMATCH );
775 pNtClose( attr3.RootDirectory );
777 status = pNtCreateMutant( &ret, GENERIC_ALL, NULL, FALSE );
778 ok( status == STATUS_SUCCESS, "NULL: NtCreateMutant failed %lx\n", status );
779 pNtClose( ret );
780 status = pNtCreateMutant( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, FALSE );
781 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateMutant failed %lx\n", status );
782 ret = (HANDLE)0xdeadbeef;
783 status = pNtOpenMutant( &ret, GENERIC_ALL, NULL );
784 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenMutant failed %lx\n", status );
785 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
786 status = pNtOpenMutant( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
787 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenMutant failed %lx\n", status );
789 status = pNtCreateSemaphore( &ret, GENERIC_ALL, NULL, 1, 2 );
790 ok( status == STATUS_SUCCESS, "NULL: NtCreateSemaphore failed %lx\n", status );
791 pNtClose( ret );
792 status = pNtCreateSemaphore( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, 1, 2 );
793 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateSemaphore failed %lx\n", status );
794 ret = (HANDLE)0xdeadbeef;
795 status = pNtOpenSemaphore( &ret, GENERIC_ALL, NULL );
796 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSemaphore failed %lx\n", status );
797 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
798 status = pNtOpenSemaphore( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
799 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenSemaphore failed %lx\n", status );
801 status = pNtCreateEvent( &ret, GENERIC_ALL, NULL, SynchronizationEvent, 0 );
802 ok( status == STATUS_SUCCESS, "NULL: NtCreateEvent failed %lx\n", status );
803 pNtClose( ret );
804 status = pNtCreateEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, SynchronizationEvent, 0 );
805 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateEvent failed %lx\n", status );
806 ret = (HANDLE)0xdeadbeef;
807 status = pNtOpenEvent( &ret, GENERIC_ALL, NULL );
808 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenEvent failed %lx\n", status );
809 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
810 status = pNtOpenEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
811 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenEvent failed %lx\n", status );
813 status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, NULL, 0 );
814 ok( status == STATUS_SUCCESS, "NULL: NtCreateKeyedEvent failed %lx\n", status );
815 pNtClose( ret );
816 status = pNtCreateKeyedEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, 0 );
817 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKeyedEvent failed %lx\n", status );
818 ret = (HANDLE)0xdeadbeef;
819 status = pNtOpenKeyedEvent( &ret, GENERIC_ALL, NULL );
820 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenKeyedEvent failed %lx\n", status );
821 ok( !ret, "handle set %p\n", ret );
822 status = pNtOpenKeyedEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
823 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKeyedEvent failed %lx\n", status );
825 status = pNtCreateTimer( &ret, GENERIC_ALL, NULL, NotificationTimer );
826 ok( status == STATUS_SUCCESS, "NULL: NtCreateTimer failed %lx\n", status );
827 pNtClose( ret );
828 status = pNtCreateTimer( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, NotificationTimer );
829 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateTimer failed %lx\n", status );
830 ret = (HANDLE)0xdeadbeef;
831 status = pNtOpenTimer( &ret, GENERIC_ALL, NULL );
832 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenTimer failed %lx\n", status );
833 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
834 status = pNtOpenTimer( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
835 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenTimer failed %lx\n", status );
837 status = pNtCreateIoCompletion( &ret, GENERIC_ALL, NULL, 0 );
838 ok( status == STATUS_SUCCESS, "NULL: NtCreateCompletion failed %lx\n", status );
839 pNtClose( ret );
840 status = pNtCreateIoCompletion( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, 0 );
841 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateCompletion failed %lx\n", status );
842 ret = (HANDLE)0xdeadbeef;
843 status = pNtOpenIoCompletion( &ret, GENERIC_ALL, NULL );
844 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenCompletion failed %lx\n", status );
845 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
846 status = pNtOpenIoCompletion( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
847 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenCompletion failed %lx\n", status );
849 status = pNtCreateJobObject( &ret, GENERIC_ALL, NULL );
850 ok( status == STATUS_SUCCESS, "NULL: NtCreateJobObject failed %lx\n", status );
851 pNtClose( ret );
852 status = pNtCreateJobObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
853 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateJobObject failed %lx\n", status );
854 ret = (HANDLE)0xdeadbeef;
855 status = pNtOpenJobObject( &ret, GENERIC_ALL, NULL );
856 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenJobObject failed %lx\n", status );
857 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
858 status = pNtOpenJobObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
859 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenJobObject failed %lx\n", status );
861 status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, NULL );
862 ok( status == STATUS_SUCCESS, "NULL: NtCreateDirectoryObject failed %lx\n", status );
863 pNtClose( ret );
864 status = pNtCreateDirectoryObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
865 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateDirectoryObject failed %lx\n", status );
866 ret = (HANDLE)0xdeadbeef;
867 status = pNtOpenDirectoryObject( &ret, GENERIC_ALL, NULL );
868 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenDirectoryObject failed %lx\n", status );
869 ok( !ret, "handle set %p\n", ret );
870 status = pNtOpenDirectoryObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
871 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenDirectoryObject failed %lx\n", status );
873 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, NULL, &target );
874 ok( status == STATUS_ACCESS_VIOLATION || broken( status == STATUS_SUCCESS), /* winxp */
875 "NULL: NtCreateSymbolicLinkObject failed %lx\n", status );
876 if (!status) pNtClose( ret );
877 status = pNtCreateSymbolicLinkObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, &target );
878 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateSymbolicLinkObject failed %lx\n", status );
879 ret = (HANDLE)0xdeadbeef;
880 status = pNtOpenSymbolicLinkObject( &ret, GENERIC_ALL, NULL );
881 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSymbolicLinkObject failed %lx\n", status );
882 ok( !ret, "handle set %p\n", ret );
883 status = pNtOpenSymbolicLinkObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
884 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenSymbolicLinkObject failed %lx\n", status );
886 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
887 ok( status == STATUS_SUCCESS, "NULL: NtCreateSection failed %lx\n", status );
888 pNtClose( ret );
889 status = pNtCreateSection( (HANDLE *)0xdeadbee0, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
890 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateSection failed %lx\n", status );
891 ret = (HANDLE)0xdeadbeef;
892 status = pNtOpenSection( &ret, SECTION_MAP_WRITE, NULL );
893 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSection failed %lx\n", status );
894 ok( !ret, "handle set %p\n", ret );
895 status = pNtOpenSection( (HANDLE *)0xdeadbee0, SECTION_MAP_WRITE, NULL );
896 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenSection failed %lx\n", status );
897 attr2.ObjectName = attr3.ObjectName = &str;
899 /* named pipes */
900 wcscpy( str.Buffer, pipeW );
901 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + wcslen( pipeW )] = 'a';
902 str.Length = 0;
903 attr.RootDirectory = 0;
904 attr.Attributes = OBJ_CASE_INSENSITIVE;
905 timeout.QuadPart = -10000;
906 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
907 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
908 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
909 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
910 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
911 ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
912 str.Length = 67;
913 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
914 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
915 ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
916 str.Length = 128;
917 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
919 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
920 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
921 if (attr.Length == sizeof(attr))
923 ok( status == STATUS_SUCCESS, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
924 pNtClose( ret );
926 else ok( status == STATUS_INVALID_PARAMETER,
927 "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
929 attr.Length = sizeof(attr);
930 str.Length = 65532;
931 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &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_SUCCESS, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
934 pNtClose( ret );
935 str.Length = 65534;
936 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
937 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
938 ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
939 attr3.RootDirectory = 0;
940 attr2.ObjectName = attr3.ObjectName = NULL;
941 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
942 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
943 ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateNamedPipeFile failed %lx\n", status );
944 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr3, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
945 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
946 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateNamedPipeFile failed %lx\n", status );
947 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, NULL, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
948 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
949 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateNamedPipeFile failed %lx\n", status );
950 attr2.ObjectName = attr3.ObjectName = &str;
952 /* mailslots */
953 wcscpy( str.Buffer, mailslotW );
954 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + wcslen( mailslotW )] = 'a';
955 str.Length = 0;
956 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
957 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
958 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
959 ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
960 str.Length = 67;
961 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
962 ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
963 str.Length = 128;
964 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
966 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
967 if (attr.Length == sizeof(attr))
969 ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
970 pNtClose( ret );
972 else ok( status == STATUS_INVALID_PARAMETER,
973 "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
975 attr.Length = sizeof(attr);
976 str.Length = 65532;
977 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
978 ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
979 pNtClose( ret );
980 str.Length = 65534;
981 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
982 ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
983 attr3.RootDirectory = 0;
984 attr2.ObjectName = attr3.ObjectName = NULL;
985 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
986 ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateMailslotFile failed %lx\n", status );
987 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr3, &iosb, 0, 0, 0, NULL );
988 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateMailslotFile failed %lx\n", status );
989 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, NULL, &iosb, 0, 0, 0, NULL );
990 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateMailslotFile failed %lx\n", status );
991 attr2.ObjectName = attr3.ObjectName = &str;
993 /* registry keys */
994 wcscpy( str.Buffer, registryW );
995 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + wcslen(registryW)] = 'a';
996 str.Length = 0;
997 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
998 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateKey failed %lx\n", str.Length, status );
999 status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL );
1000 ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateKey failed %lx\n", str.Length, status );
1001 status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 );
1002 ok( status == STATUS_INVALID_HANDLE, "%u: NtOpenKey failed %lx\n", str.Length, status );
1003 str.Length = (wcslen( registryW ) + 250) * sizeof(WCHAR) + 1;
1004 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1005 ok( status == STATUS_OBJECT_NAME_INVALID ||
1006 status == STATUS_INVALID_PARAMETER ||
1007 broken( status == STATUS_SUCCESS ), /* wow64 */
1008 "%u: NtCreateKey failed %lx\n", str.Length, status );
1009 if (!status)
1011 pNtDeleteKey( ret );
1012 pNtClose( ret );
1014 str.Length = (wcslen( registryW ) + 256) * sizeof(WCHAR);
1015 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1016 ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED,
1017 "%u: NtCreateKey failed %lx\n", str.Length, status );
1018 status = pNtCreateKey( (HANDLE *)0xdeadbee0, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1019 ok( status == STATUS_ACCESS_VIOLATION, "%u: NtCreateKey failed %lx\n", str.Length, status );
1020 if (!status)
1022 status = pNtOpenKey( &ret2, KEY_READ, &attr );
1023 ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %lx\n", str.Length, status );
1024 pNtClose( ret2 );
1025 status = pNtOpenKey( (HANDLE *)0xdeadbee0, KEY_READ, &attr );
1026 ok( status == STATUS_ACCESS_VIOLATION, "%u: NtOpenKey failed %lx\n", str.Length, status );
1027 attr3.RootDirectory = ret;
1028 str.Length = 0;
1029 status = pNtOpenKey( &ret2, KEY_READ, &attr3 );
1030 ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %lx\n", str.Length, status );
1031 pNtClose( ret2 );
1032 pNtDeleteKey( ret );
1033 pNtClose( ret );
1035 str.Length = (wcslen( registryW ) + 256) * sizeof(WCHAR);
1036 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
1038 if (attr.Length == sizeof(attr))
1040 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1041 ok( status == STATUS_SUCCESS, "%u: NtCreateKey failed %lx\n", str.Length, status );
1042 status = pNtOpenKey( &ret2, KEY_READ, &attr );
1043 ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %lx\n", str.Length, status );
1044 pNtClose( ret2 );
1045 pNtDeleteKey( ret );
1046 pNtClose( ret );
1048 else
1050 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1051 ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %lx\n", str.Length, status );
1052 status = pNtOpenKey( &ret2, KEY_READ, &attr );
1053 ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %lx\n", str.Length, status );
1056 attr.Length = sizeof(attr);
1058 str.Length = (wcslen( registryW ) + 256) * sizeof(WCHAR) + 1;
1059 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1060 ok( status == STATUS_OBJECT_NAME_INVALID ||
1061 status == STATUS_INVALID_PARAMETER ||
1062 broken( status == STATUS_SUCCESS ), /* win7 */
1063 "%u: NtCreateKey failed %lx\n", str.Length, status );
1064 if (!status)
1066 pNtDeleteKey( ret );
1067 pNtClose( ret );
1069 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1070 ok( status == STATUS_OBJECT_NAME_INVALID ||
1071 status == STATUS_INVALID_PARAMETER ||
1072 broken( status == STATUS_OBJECT_NAME_NOT_FOUND ), /* wow64 */
1073 "%u: NtOpenKey failed %lx\n", str.Length, status );
1074 str.Length++;
1075 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1076 ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %lx\n", str.Length, status );
1077 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1078 ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %lx\n", str.Length, status );
1079 str.Length = 2000;
1080 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1081 ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %lx\n", str.Length, status );
1082 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1083 ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %lx\n", str.Length, status );
1084 /* some Windows versions change the error past 2050 chars, others past 4066 chars, some don't */
1085 str.Length = 5000;
1086 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1087 ok( status == STATUS_BUFFER_OVERFLOW ||
1088 status == STATUS_BUFFER_TOO_SMALL ||
1089 status == STATUS_INVALID_PARAMETER,
1090 "%u: NtCreateKey failed %lx\n", str.Length, status );
1091 ret = (HANDLE)0xdeadbeef;
1092 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1093 ok( status == STATUS_BUFFER_OVERFLOW ||
1094 status == STATUS_BUFFER_TOO_SMALL ||
1095 status == STATUS_INVALID_PARAMETER,
1096 "%u: NtOpenKey failed %lx\n", str.Length, status );
1097 ok( !ret, "handle set %p\n", ret );
1098 str.Length = 65534;
1099 ret = (HANDLE)0xdeadbeef;
1100 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1101 ok( status == STATUS_OBJECT_NAME_INVALID ||
1102 status == STATUS_BUFFER_OVERFLOW ||
1103 status == STATUS_BUFFER_TOO_SMALL,
1104 "%u: NtCreateKey failed %lx\n", str.Length, status );
1105 ok( !ret, "handle set %p\n", ret );
1106 ret = (HANDLE)0xdeadbeef;
1107 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1108 ok( status == STATUS_OBJECT_NAME_INVALID ||
1109 status == STATUS_BUFFER_OVERFLOW ||
1110 status == STATUS_BUFFER_TOO_SMALL,
1111 "%u: NtOpenKey failed %lx\n", str.Length, status );
1112 ok( !ret, "handle set %p\n", ret );
1113 attr3.RootDirectory = 0;
1114 attr2.ObjectName = attr3.ObjectName = NULL;
1115 status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL );
1116 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE /* vista wow64 */,
1117 "NULL: NtCreateKey failed %lx\n", status );
1118 status = pNtCreateKey( &ret, GENERIC_ALL, &attr3, 0, NULL, 0, NULL );
1119 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %lx\n", status );
1120 status = pNtCreateKey( &ret, GENERIC_ALL, NULL, 0, NULL, 0, NULL );
1121 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %lx\n", status );
1122 status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 );
1123 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE /* vista wow64 */,
1124 "NULL: NtOpenKey failed %lx\n", status );
1125 status = pNtOpenKey( &ret, GENERIC_ALL, &attr3 );
1126 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %lx\n", status );
1127 status = pNtOpenKey( &ret, GENERIC_ALL, NULL );
1128 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %lx\n", status );
1129 attr2.ObjectName = attr3.ObjectName = &str;
1131 HeapFree( GetProcessHeap(), 0, str.Buffer );
1134 static void test_directory(void)
1136 NTSTATUS status;
1137 UNICODE_STRING str;
1138 OBJECT_ATTRIBUTES attr;
1139 HANDLE dir, dir1, h, h2;
1140 WCHAR buffer[256];
1141 ULONG len, full_len;
1143 /* No name and/or no attributes */
1144 status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
1145 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER /* wow64 */, "got %#lx\n", status);
1146 status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
1147 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER /* wow64 */, "got %#lx\n", status);
1149 status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL);
1150 ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08lx)\n", status);
1151 pNtClose(h);
1152 status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL);
1153 ok(status == STATUS_INVALID_PARAMETER,
1154 "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status);
1156 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
1157 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1158 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1159 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1160 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08lx\n", status );
1162 /* Bad name */
1163 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1165 RtlInitUnicodeString(&str, L"");
1166 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1167 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1168 pNtClose(h);
1169 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1170 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08lx\n", status );
1171 pNtClose(dir);
1173 check_create_open_dir( NULL, L"BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD );
1174 check_create_open_dir( NULL, L"\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID );
1175 check_create_open_dir( NULL, L"\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID );
1176 check_create_open_dir( NULL, L"\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID );
1177 check_create_open_dir( NULL, L"\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND );
1179 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test");
1180 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1181 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1182 status = pNtOpenDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
1183 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1184 pNtClose(h);
1185 pNtClose(dir1);
1188 /* Use of root directory */
1190 /* Can't use symlinks as a directory */
1191 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\Local");
1192 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1193 status = pNtOpenSymbolicLinkObject(&dir, SYMBOLIC_LINK_QUERY, &attr);
1195 ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08lx)\n", status);
1196 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1197 RtlInitUnicodeString(&str, L"one more level");
1198 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1199 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtCreateDirectoryObject got %08lx\n", status );
1201 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\Local\\om.c-test" );
1202 InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
1203 status = pNtCreateDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
1204 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1205 RtlInitUnicodeString( &str, L"om.c-test" );
1206 InitializeObjectAttributes( &attr, &str, 0, dir, NULL );
1207 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1208 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "Failed to open directory %08lx\n", status );
1210 RtlInitUnicodeString( &str, L"om.c-event" );
1211 InitializeObjectAttributes( &attr, &str, 0, dir1, NULL );
1212 status = pNtCreateEvent( &h, GENERIC_ALL, &attr, SynchronizationEvent, 0 );
1213 ok( status == STATUS_SUCCESS, "NtCreateEvent failed %lx\n", status );
1214 status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
1215 ok( status == STATUS_SUCCESS, "NtOpenEvent failed %lx\n", status );
1216 pNtClose( h2 );
1217 RtlInitUnicodeString( &str, L"om.c-test\\om.c-event" );
1218 InitializeObjectAttributes( &attr, &str, 0, dir, NULL );
1219 status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
1220 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtOpenEvent failed %lx\n", status );
1221 RtlInitUnicodeString( &str, L"\\BasedNamedObjects\\Local\\om.c-test\\om.c-event" );
1222 InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
1223 status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
1224 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtOpenEvent failed %lx\n", status );
1225 pNtClose( h );
1226 pNtClose( dir1 );
1228 str.Buffer = buffer;
1229 str.MaximumLength = sizeof(buffer);
1230 len = 0xdeadbeef;
1231 memset( buffer, 0xaa, sizeof(buffer) );
1232 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1233 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1234 full_len = str.Length + sizeof(WCHAR);
1235 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1236 ok( buffer[len / sizeof(WCHAR) - 1] == 0, "no terminating null\n" );
1238 str.MaximumLength = str.Length;
1239 str.Length = 0x4444;
1240 len = 0xdeadbeef;
1241 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1242 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1243 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1244 ok( str.Length == 0x4444, "len set to %x\n", str.Length );
1246 str.MaximumLength = 0;
1247 str.Length = 0x4444;
1248 len = 0xdeadbeef;
1249 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1250 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1251 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1252 ok( str.Length == 0x4444, "len set to %x\n", str.Length );
1254 str.MaximumLength = full_len;
1255 str.Length = 0x4444;
1256 len = 0xdeadbeef;
1257 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1258 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1259 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1260 ok( str.Length == full_len - sizeof(WCHAR), "len set to %x\n", str.Length );
1262 pNtClose(dir);
1264 RtlInitUnicodeString(&str, L"\\BaseNamedObjects");
1265 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1266 status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1267 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1269 InitializeObjectAttributes(&attr, NULL, 0, dir, NULL);
1270 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1271 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenDirectoryObject got %08lx\n", status );
1273 check_create_open_dir( dir, L"", STATUS_SUCCESS );
1274 check_create_open_dir( dir, L"\\", STATUS_OBJECT_PATH_SYNTAX_BAD );
1275 check_create_open_dir( dir, L"\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD );
1276 check_create_open_dir( dir, L"\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD );
1277 check_create_open_dir( dir, L"om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND );
1279 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1280 RtlInitUnicodeString(&str, L"om.c-test");
1281 status = pNtCreateDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
1282 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1283 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1284 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1286 pNtClose(h);
1287 pNtClose(dir1);
1288 pNtClose(dir);
1290 /* Nested directories */
1291 RtlInitUnicodeString(&str, L"\\");
1292 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1293 status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1294 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1295 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1296 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1297 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08lx\n", status );
1298 pNtClose(dir);
1300 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1301 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test");
1302 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1303 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1304 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test\\one more level");
1305 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1306 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1307 pNtClose(h);
1308 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1309 RtlInitUnicodeString(&str, L"one more level");
1310 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1311 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1312 pNtClose(h);
1314 pNtClose(dir);
1316 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1317 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\Global\\om.c-test");
1318 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1319 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1320 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\Local\\om.c-test\\one more level");
1321 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1322 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1323 pNtClose(h);
1324 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1325 RtlInitUnicodeString(&str, L"one more level");
1326 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1327 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1328 pNtClose(h);
1329 pNtClose(dir);
1331 /* Create other objects using RootDirectory */
1333 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1334 RtlInitUnicodeString(&str, L"\\BaseNamedObjects");
1335 status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1336 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1337 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1339 /* Test invalid paths */
1340 RtlInitUnicodeString(&str, L"\\om.c-mutant");
1341 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1342 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1343 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
1344 RtlInitUnicodeString(&str, L"\\om.c-mutant\\");
1345 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1346 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1347 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
1349 RtlInitUnicodeString(&str, L"om.c\\-mutant");
1350 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1351 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
1352 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status);
1354 RtlInitUnicodeString(&str, L"om.c-mutant");
1355 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1356 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08lx)\n", status);
1357 pNtClose(h);
1359 pNtClose(dir);
1362 static void test_symboliclink(void)
1364 NTSTATUS status;
1365 UNICODE_STRING str, target;
1366 OBJECT_ATTRIBUTES attr;
1367 HANDLE dir, link, h, h2;
1368 IO_STATUS_BLOCK iosb;
1370 /* No name and/or no attributes */
1371 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
1372 RtlInitUnicodeString(&target, L"\\DosDevices");
1373 status = pNtCreateSymbolicLinkObject( NULL, SYMBOLIC_LINK_QUERY, &attr, &target );
1374 ok(status == STATUS_ACCESS_VIOLATION, "got %#lx\n", status);
1375 status = pNtOpenSymbolicLinkObject( NULL, SYMBOLIC_LINK_QUERY, &attr );
1376 ok(status == STATUS_ACCESS_VIOLATION, "got %#lx\n", status);
1378 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL);
1379 ok(status == STATUS_ACCESS_VIOLATION,
1380 "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status);
1381 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL);
1382 ok(status == STATUS_INVALID_PARAMETER,
1383 "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status);
1385 /* No attributes */
1386 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, &target);
1387 ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_VIOLATION, /* nt4 */
1388 "NtCreateSymbolicLinkObject failed(%08lx)\n", status);
1390 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
1391 memset(&target, 0, sizeof(target));
1392 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1393 ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
1394 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
1395 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1396 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
1398 /* Bad name */
1399 RtlInitUnicodeString(&target, L"anywhere");
1400 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1402 RtlInitUnicodeString(&str, L"");
1403 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1404 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08lx)\n", status);
1405 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
1406 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1407 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
1408 pNtClose(link);
1410 RtlInitUnicodeString(&str, L"\\");
1411 attr.Attributes = OBJ_OPENIF;
1412 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target);
1413 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
1414 "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
1415 attr.Attributes = 0;
1416 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target);
1417 todo_wine
1418 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
1419 "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
1421 RtlInitUnicodeString( &target, L"->Somewhere");
1423 RtlInitUnicodeString( &str, L"BaseNamedObjects" );
1424 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1425 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtCreateSymbolicLinkObject got %08lx\n", status );
1426 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1427 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenSymbolicLinkObject got %08lx\n", status );
1429 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\" );
1430 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1431 ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08lx\n", status );
1432 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1433 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08lx\n", status );
1435 RtlInitUnicodeString( &str, L"\\\\BaseNamedObjects" );
1436 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1437 ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08lx\n", status );
1438 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1439 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08lx\n", status );
1441 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\\\om.c-test" );
1442 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1443 ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08lx\n", status );
1444 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1445 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08lx\n", status );
1447 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\" );
1448 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1449 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "got %#lx\n", status );
1450 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1451 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "got %#lx\n", status );
1453 /* Compound test */
1454 dir = get_base_dir();
1455 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1456 RtlInitUnicodeString(&str, L"test-link");
1457 RtlInitUnicodeString(&target, L"\\DosDevices");
1458 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1459 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08lx)\n", status);
1461 RtlInitUnicodeString(&str, L"test-link\\NUL");
1462 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
1463 ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08lx)\n", status);
1464 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE);
1465 ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08lx)\n", status);
1467 pNtClose(h);
1468 pNtClose(link);
1469 pNtClose(dir);
1471 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1472 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test");
1473 status = pNtCreateDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
1474 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1476 RtlInitUnicodeString(&str, L"\\DosDevices\\test_link");
1477 RtlInitUnicodeString(&target, L"\\BaseNamedObjects");
1478 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1479 ok(status == STATUS_SUCCESS && !!link, "Got unexpected status %#lx.\n", status);
1481 status = NtCreateFile(&h, GENERIC_READ | SYNCHRONIZE, &attr, &iosb, NULL, 0,
1482 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 );
1483 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1485 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1486 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1487 pNtClose(h);
1489 attr.Attributes = OBJ_OPENIF;
1490 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1491 ok(status == STATUS_SUCCESS || broken( status == STATUS_OBJECT_NAME_EXISTS ), /* <= win10 1507 */
1492 "Got unexpected status %#lx.\n", status);
1493 pNtClose(h);
1494 attr.Attributes = 0;
1495 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1496 ok(status == STATUS_OBJECT_NAME_COLLISION, "Got unexpected status %#lx.\n", status);
1497 pNtClose(h);
1499 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1500 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\" );
1501 status = NtCreateFile(&h, GENERIC_READ | SYNCHRONIZE, &attr, &iosb, NULL, 0,
1502 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 );
1503 ok(status == STATUS_OBJECT_NAME_INVALID, "Got unexpected status %#lx.\n", status);
1505 InitializeObjectAttributes(&attr, &str, 0, link, NULL);
1506 RtlInitUnicodeString( &str, L"om.c-test\\test_object" );
1507 status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
1508 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1510 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1511 RtlInitUnicodeString( &str, L"\\DosDevices\\test_link\\om.c-test\\test_object" );
1512 status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
1513 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1514 status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
1515 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1516 pNtClose(h2);
1517 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\test_object" );
1518 status = pNtCreateMutant( &h2, GENERIC_ALL, &attr, FALSE );
1519 ok(status == STATUS_OBJECT_NAME_COLLISION, "Got unexpected status %#lx.\n", status);
1521 InitializeObjectAttributes(&attr, &str, 0, link, NULL);
1522 RtlInitUnicodeString( &str, L"om.c-test\\test_object" );
1523 status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
1524 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1526 pNtClose(h);
1528 status = pNtOpenMutant( &h, GENERIC_ALL, &attr );
1529 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1531 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1532 RtlInitUnicodeString( &str, L"test_object" );
1533 status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
1534 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1535 status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
1536 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1537 pNtClose(h);
1538 pNtClose(h2);
1540 pNtClose(link);
1541 pNtClose(dir);
1544 #define test_file_info(a) _test_file_info(__LINE__,a)
1545 static void _test_file_info(unsigned line, HANDLE handle)
1547 IO_STATUS_BLOCK io;
1548 char buf[256];
1549 NTSTATUS status;
1551 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), 0xdeadbeef);
1552 ok_(__FILE__,line)(status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED /* Vista+ */,
1553 "expected STATUS_NOT_IMPLEMENTED, got %lx\n", status);
1555 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), FileAccessInformation);
1556 ok_(__FILE__,line)(status == STATUS_SUCCESS, "FileAccessInformation returned %lx\n", status);
1558 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf),
1559 FileIoCompletionNotificationInformation);
1560 ok_(__FILE__,line)(status == STATUS_SUCCESS || broken(status == STATUS_INVALID_INFO_CLASS) /* XP */,
1561 "FileIoCompletionNotificationInformation returned %lx\n", status);
1564 #define test_no_file_info(a) _test_no_file_info(__LINE__,a)
1565 static void _test_no_file_info(unsigned line, HANDLE handle)
1567 IO_STATUS_BLOCK io;
1568 char buf[256];
1569 NTSTATUS status;
1571 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), 0xdeadbeef);
1572 ok_(__FILE__,line)(status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED /* Vista+ */,
1573 "expected STATUS_NOT_IMPLEMENTED, got %lx\n", status);
1575 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), FileAccessInformation);
1576 ok_(__FILE__,line)(status == STATUS_OBJECT_TYPE_MISMATCH,
1577 "FileAccessInformation returned %lx\n", status);
1579 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf),
1580 FileIoCompletionNotificationInformation);
1581 ok_(__FILE__,line)(status == STATUS_OBJECT_TYPE_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* XP */,
1582 "FileIoCompletionNotificationInformation returned %lx\n", status);
1585 static OBJECT_TYPE_INFORMATION all_types[256];
1587 static void add_object_type( OBJECT_TYPE_INFORMATION *info )
1589 unsigned int i;
1591 for (i = 0; i < ARRAY_SIZE(all_types); i++)
1593 if (!all_types[i].TypeName.Buffer) break;
1594 if (!RtlCompareUnicodeString( &all_types[i].TypeName, &info->TypeName, FALSE )) break;
1596 ok( i < ARRAY_SIZE(all_types), "too many types\n" );
1598 if (all_types[i].TypeName.Buffer) /* existing type */
1600 ok( !memcmp( &all_types[i].GenericMapping, &info->GenericMapping, sizeof(GENERIC_MAPPING) ),
1601 "%u: mismatched mappings %08lx,%08lx,%08lx,%08lx / %08lx,%08lx,%08lx,%08lx\n", i,
1602 all_types[i].GenericMapping.GenericRead, all_types[i].GenericMapping.GenericWrite,
1603 all_types[i].GenericMapping.GenericExecute, all_types[i].GenericMapping.GenericAll,
1604 info->GenericMapping.GenericRead, info->GenericMapping.GenericWrite,
1605 info->GenericMapping.GenericExecute, info->GenericMapping.GenericAll );
1606 ok( all_types[i].ValidAccessMask == info->ValidAccessMask,
1607 "%u: mismatched access mask %08lx / %08lx\n", i,
1608 all_types[i].ValidAccessMask, info->ValidAccessMask );
1610 else /* add it */
1612 all_types[i] = *info;
1613 RtlDuplicateUnicodeString( 1, &info->TypeName, &all_types[i].TypeName );
1615 ok( info->TotalNumberOfObjects <= info->HighWaterNumberOfObjects, "%s: wrong object counts %lu/%lu\n",
1616 debugstr_w( all_types[i].TypeName.Buffer ),
1617 info->TotalNumberOfObjects, info->HighWaterNumberOfObjects );
1618 ok( info->TotalNumberOfHandles <= info->HighWaterNumberOfHandles, "%s: wrong handle counts %lu/%lu\n",
1619 debugstr_w( all_types[i].TypeName.Buffer ),
1620 info->TotalNumberOfHandles, info->HighWaterNumberOfHandles );
1623 static BOOL compare_unicode_string( const UNICODE_STRING *string, const WCHAR *expect )
1625 return string->Length == wcslen( expect ) * sizeof(WCHAR)
1626 && !wcsnicmp( string->Buffer, expect, string->Length / sizeof(WCHAR) );
1629 #define test_object_type(a,b) _test_object_type(__LINE__,a,b)
1630 static void _test_object_type( unsigned line, HANDLE handle, const WCHAR *expected_name )
1632 char buffer[1024];
1633 OBJECT_TYPE_INFORMATION *type = (OBJECT_TYPE_INFORMATION *)buffer;
1634 UNICODE_STRING expect;
1635 ULONG len = 0;
1636 NTSTATUS status;
1638 RtlInitUnicodeString( &expect, expected_name );
1640 memset( buffer, 0, sizeof(buffer) );
1641 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
1642 ok_(__FILE__,line)( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1643 ok_(__FILE__,line)( len > sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1644 ok_(__FILE__,line)( len >= sizeof(*type) + type->TypeName.Length, "unexpected len %lu\n", len );
1645 ok_(__FILE__,line)(compare_unicode_string( &type->TypeName, expected_name ), "wrong name %s\n",
1646 debugstr_w( type->TypeName.Buffer ));
1647 add_object_type( type );
1650 #define test_object_name(a,b,c) _test_object_name(__LINE__,a,b,c)
1651 static void _test_object_name( unsigned line, HANDLE handle, const WCHAR *expected_name, BOOL todo )
1653 char buffer[1024];
1654 UNICODE_STRING *str = (UNICODE_STRING *)buffer, expect;
1655 ULONG len = 0;
1656 NTSTATUS status;
1658 RtlInitUnicodeString( &expect, expected_name );
1660 memset( buffer, 0, sizeof(buffer) );
1661 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1662 ok_(__FILE__,line)( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1663 ok_(__FILE__,line)( len >= sizeof(OBJECT_NAME_INFORMATION) + str->Length, "unexpected len %lu\n", len );
1664 todo_wine_if (todo)
1665 ok_(__FILE__,line)(compare_unicode_string( str, expected_name ), "got %s, expected %s\n",
1666 debugstr_w(str->Buffer), debugstr_w(expected_name));
1669 static void test_query_object(void)
1671 static const WCHAR name[] = L"\\BaseNamedObjects\\test_event";
1672 HANDLE handle, client;
1673 char buffer[1024];
1674 NTSTATUS status;
1675 ULONG len, expected_len;
1676 OBJECT_BASIC_INFORMATION info;
1677 OBJECT_ATTRIBUTES attr;
1678 UNICODE_STRING path, target, *str;
1679 char dir[MAX_PATH], tmp_path[MAX_PATH], file1[MAX_PATH + 16];
1680 WCHAR expect[100];
1681 LARGE_INTEGER size;
1683 InitializeObjectAttributes( &attr, &path, 0, 0, 0 );
1685 handle = CreateEventA( NULL, FALSE, FALSE, "test_event" );
1687 status = pNtQueryObject( handle, ObjectBasicInformation, NULL, 0, NULL );
1688 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1690 status = pNtQueryObject( handle, ObjectBasicInformation, &info, 0, NULL );
1691 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1693 status = pNtQueryObject( handle, ObjectBasicInformation, NULL, 0, &len );
1694 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1696 len = 0;
1697 status = pNtQueryObject( handle, ObjectBasicInformation, &info, sizeof(OBJECT_BASIC_INFORMATION), &len );
1698 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1699 ok( len >= sizeof(OBJECT_BASIC_INFORMATION), "unexpected len %lu\n", len );
1701 len = 0;
1702 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
1703 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1704 ok( len >= sizeof(UNICODE_STRING) + sizeof(name), "unexpected len %lu\n", len );
1706 len = 0;
1707 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, 0, &len );
1708 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1709 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(L"Event"), "unexpected len %lu\n", len );
1711 len = 0;
1712 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &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 len = 0;
1717 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(OBJECT_TYPE_INFORMATION), &len );
1718 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1719 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(L"Event"), "unexpected len %lu\n", len );
1721 len = 0;
1722 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1723 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1724 ok( len > sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1725 str = (UNICODE_STRING *)buffer;
1726 ok( sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR) == len, "unexpected len %lu\n", len );
1727 ok( str->Length >= sizeof(name) - sizeof(WCHAR), "unexpected len %u\n", str->Length );
1728 ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_event") * sizeof(WCHAR),
1729 "name too short %s\n", wine_dbgstr_w(str->Buffer) );
1730 /* check for \\Sessions prefix in the name */
1731 swprintf( expect, ARRAY_SIZE(expect), L"\\Sessions\\%u%s", NtCurrentTeb()->Peb->SessionId, name );
1732 ok( (str->Length == wcslen( expect ) * sizeof(WCHAR) && !wcscmp( str->Buffer, expect )) ||
1733 broken( !wcscmp( str->Buffer, name )), /* winxp */
1734 "wrong name %s\n", wine_dbgstr_w(str->Buffer) );
1735 trace( "got %s len %lu\n", wine_dbgstr_w(str->Buffer), len );
1737 len -= sizeof(WCHAR);
1738 status = pNtQueryObject( handle, ObjectNameInformation, buffer, len, &len );
1739 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1740 ok( len >= sizeof(UNICODE_STRING) + sizeof(name), "unexpected len %lu\n", len );
1742 test_object_type( handle, L"Event" );
1744 len -= sizeof(WCHAR);
1745 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, len, &len );
1746 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1747 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(L"Event"), "unexpected len %lu\n", len );
1749 test_no_file_info( handle );
1750 pNtClose( handle );
1752 handle = CreateEventA( NULL, FALSE, FALSE, NULL );
1753 len = 0;
1754 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1755 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1756 ok( len == sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1757 str = (UNICODE_STRING *)buffer;
1758 ok( str->Length == 0, "unexpected len %lu\n", len );
1759 ok( str->Buffer == NULL, "unexpected ptr %p\n", str->Buffer );
1760 test_no_file_info( handle );
1761 pNtClose( handle );
1763 GetWindowsDirectoryA( dir, MAX_PATH );
1764 handle = CreateFileA( dir, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1765 FILE_FLAG_BACKUP_SEMANTICS, 0 );
1766 len = 0;
1767 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1768 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1769 ok( len > sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1770 str = (UNICODE_STRING *)buffer;
1771 expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR);
1772 ok( len == expected_len, "unexpected len %lu\n", len );
1773 trace( "got %s len %lu\n", wine_dbgstr_w(str->Buffer), len );
1775 len = 0;
1776 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
1777 ok( status == STATUS_INFO_LENGTH_MISMATCH, "got %#lx\n", status );
1778 ok( len == expected_len || broken(!len /* XP */ || len == sizeof(UNICODE_STRING) /* 2003 */),
1779 "unexpected len %lu\n", len );
1781 len = 0;
1782 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
1783 ok( status == STATUS_BUFFER_OVERFLOW, "got %#lx\n", status);
1784 ok( len == expected_len, "unexpected len %lu\n", len );
1786 test_object_type( handle, L"File" );
1788 pNtClose( handle );
1790 GetTempPathA(MAX_PATH, tmp_path);
1791 GetTempFileNameA(tmp_path, "foo", 0, file1);
1792 handle = CreateFileA(file1, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0);
1793 test_object_type(handle, L"File");
1794 test_file_info( handle );
1795 pNtClose( handle );
1796 DeleteFileA( file1 );
1798 status = pNtCreateIoCompletion( &handle, IO_COMPLETION_ALL_ACCESS, NULL, 0 );
1799 ok( status == STATUS_SUCCESS, "NtCreateIoCompletion failed %lx\n", status);
1801 test_object_type( handle, L"IoCompletion" );
1802 test_no_file_info( handle );
1804 pNtClose( handle );
1806 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_debug" );
1807 status = pNtCreateDebugObject( &handle, DEBUG_ALL_ACCESS, &attr, 0 );
1808 ok(!status, "NtCreateDebugObject failed: %lx\n", status);
1809 test_object_name( handle, L"\\BaseNamedObjects\\test_debug", FALSE );
1810 test_object_type( handle, L"DebugObject" );
1811 test_no_file_info( handle );
1812 pNtClose(handle);
1814 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_mutant" );
1815 status = pNtCreateMutant( &handle, MUTANT_ALL_ACCESS, &attr, 0 );
1816 ok(!status, "NtCreateMutant failed: %lx\n", status);
1817 test_object_name( handle, L"\\BaseNamedObjects\\test_mutant", FALSE );
1818 test_object_type( handle, L"Mutant" );
1819 test_no_file_info( handle );
1820 pNtClose(handle);
1822 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_sem" );
1823 status = pNtCreateSemaphore( &handle, SEMAPHORE_ALL_ACCESS, &attr, 1, 2 );
1824 ok(!status, "NtCreateSemaphore failed: %lx\n", status);
1825 test_object_name( handle, L"\\BaseNamedObjects\\test_sem", FALSE );
1826 test_object_type( handle, L"Semaphore" );
1827 test_no_file_info( handle );
1828 pNtClose(handle);
1830 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_keyed" );
1831 status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr, 0 );
1832 ok(!status, "NtCreateKeyedEvent failed: %lx\n", status);
1833 test_object_name( handle, L"\\BaseNamedObjects\\test_keyed", FALSE );
1834 test_object_type( handle, L"KeyedEvent" );
1835 test_no_file_info( handle );
1836 pNtClose(handle);
1838 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_compl" );
1839 status = pNtCreateIoCompletion( &handle, IO_COMPLETION_ALL_ACCESS, &attr, 0 );
1840 ok(!status, "NtCreateIoCompletion failed: %lx\n", status);
1841 test_object_name( handle, L"\\BaseNamedObjects\\test_compl", FALSE );
1842 test_object_type( handle, L"IoCompletion" );
1843 test_no_file_info( handle );
1844 pNtClose(handle);
1846 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_job" );
1847 status = pNtCreateJobObject( &handle, JOB_OBJECT_ALL_ACCESS, &attr );
1848 ok(!status, "NtCreateJobObject failed: %lx\n", status);
1849 test_object_name( handle, L"\\BaseNamedObjects\\test_job", FALSE );
1850 test_object_type( handle, L"Job" );
1851 test_no_file_info( handle );
1852 pNtClose(handle);
1854 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_timer" );
1855 status = pNtCreateTimer( &handle, TIMER_ALL_ACCESS, &attr, NotificationTimer );
1856 ok(!status, "NtCreateTimer failed: %lx\n", status);
1857 test_object_type( handle, L"Timer" );
1858 test_no_file_info( handle );
1859 pNtClose(handle);
1861 RtlInitUnicodeString( &path, L"\\DosDevices\\test_link" );
1862 RtlInitUnicodeString( &target, L"\\DosDevices" );
1863 status = pNtCreateSymbolicLinkObject( &handle, SYMBOLIC_LINK_ALL_ACCESS, &attr, &target );
1864 ok(!status, "NtCreateSymbolicLinkObject failed: %lx\n", status);
1865 test_object_type( handle, L"SymbolicLink" );
1866 test_no_file_info( handle );
1867 pNtClose(handle);
1869 handle = GetProcessWindowStation();
1870 swprintf( expect, ARRAY_SIZE(expect), L"\\Sessions\\%u\\Windows\\WindowStations\\WinSta0", NtCurrentTeb()->Peb->SessionId );
1871 test_object_name( handle, expect, FALSE );
1872 test_object_type( handle, L"WindowStation" );
1873 test_no_file_info( handle );
1875 handle = GetThreadDesktop( GetCurrentThreadId() );
1876 test_object_name( handle, L"\\Default", FALSE );
1877 test_object_type( handle, L"Desktop" );
1878 test_no_file_info( handle );
1880 status = pNtCreateDirectoryObject( &handle, DIRECTORY_QUERY, NULL );
1881 ok(status == STATUS_SUCCESS, "Failed to create Directory %08lx\n", status);
1883 test_object_type( handle, L"Directory" );
1884 test_no_file_info( handle );
1886 pNtClose( handle );
1888 size.u.LowPart = 256;
1889 size.u.HighPart = 0;
1890 status = pNtCreateSection( &handle, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
1891 ok( status == STATUS_SUCCESS , "NtCreateSection returned %lx\n", status );
1893 test_object_type( handle, L"Section" );
1894 test_no_file_info( handle );
1896 pNtClose( handle );
1898 handle = CreateMailslotA( "\\\\.\\mailslot\\test_mailslot", 100, 1000, NULL );
1899 ok( handle != INVALID_HANDLE_VALUE, "CreateMailslot failed err %lu\n", GetLastError() );
1901 test_object_name( handle, L"\\Device\\Mailslot\\test_mailslot", FALSE );
1902 test_object_type( handle, L"File" );
1903 test_file_info( handle );
1905 client = CreateFileA( "\\\\.\\mailslot\\test_mailslot", 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
1906 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1908 len = 0;
1909 status = pNtQueryObject( client, ObjectNameInformation, buffer, sizeof(buffer), &len );
1910 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1911 str = (UNICODE_STRING *)buffer;
1912 ok( len == sizeof(UNICODE_STRING) + str->MaximumLength, "unexpected len %lu\n", len );
1913 todo_wine
1914 ok( compare_unicode_string( str, L"\\Device\\Mailslot" ) ||
1915 compare_unicode_string( str, L"\\Device\\Mailslot\\test_mailslot" ) /* win8+ */,
1916 "wrong name %s\n", debugstr_w( str->Buffer ));
1918 test_object_type( client, L"File" );
1919 test_file_info( client );
1921 pNtClose( client );
1922 pNtClose( handle );
1924 handle = CreateFileA( "\\\\.\\mailslot", 0, 0, NULL, OPEN_EXISTING, 0, 0 );
1925 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1927 test_object_name( handle, L"\\Device\\Mailslot", FALSE );
1928 test_object_type( handle, L"File" );
1929 test_file_info( handle );
1931 pNtClose( handle );
1933 handle = CreateNamedPipeA( "\\\\.\\pipe\\test_pipe", PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE,
1934 1, 1000, 1000, 1000, NULL );
1935 ok( handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed err %lu\n", GetLastError() );
1937 test_object_name( handle, L"\\Device\\NamedPipe\\test_pipe", FALSE );
1938 test_object_type( handle, L"File" );
1939 test_file_info( handle );
1941 client = CreateFileA( "\\\\.\\pipe\\test_pipe", GENERIC_READ | GENERIC_WRITE,
1942 0, NULL, OPEN_EXISTING, 0, 0 );
1943 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1945 test_object_type( client, L"File" );
1946 test_file_info( client );
1948 pNtClose( client );
1949 pNtClose( handle );
1951 handle = CreateFileA( "\\\\.\\pipe", 0, 0, NULL, OPEN_EXISTING, 0, 0 );
1952 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1954 test_object_name( handle, L"\\Device\\NamedPipe", FALSE );
1955 test_object_type( handle, L"File" );
1956 test_file_info( handle );
1958 pNtClose( handle );
1960 handle = CreateFileA( "\\\\.\\pipe\\", 0, 0, NULL, OPEN_EXISTING, 0, 0 );
1961 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%lu)\n", GetLastError() );
1963 test_object_name( handle, L"\\Device\\NamedPipe\\", TRUE );
1964 test_object_type( handle, L"File" );
1965 test_file_info( handle );
1967 pNtClose( handle );
1969 RtlInitUnicodeString( &path, L"\\REGISTRY\\Machine" );
1970 status = pNtCreateKey( &handle, KEY_READ, &attr, 0, 0, 0, 0 );
1971 ok( status == STATUS_SUCCESS, "NtCreateKey failed status %lx\n", status );
1973 test_object_name( handle, L"\\REGISTRY\\MACHINE", FALSE );
1974 test_object_type( handle, L"Key" );
1976 pNtClose( handle );
1978 test_object_name( GetCurrentProcess(), L"", FALSE );
1979 test_object_type( GetCurrentProcess(), L"Process" );
1980 test_no_file_info( GetCurrentProcess() );
1982 test_object_name( GetCurrentThread(), L"", FALSE );
1983 test_object_type( GetCurrentThread(), L"Thread" );
1984 test_no_file_info( GetCurrentThread() );
1986 status = pNtOpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &handle);
1987 ok(!status, "OpenProcessToken failed: %lx\n", status);
1989 test_object_name( handle, L"", FALSE );
1990 test_object_type( handle, L"Token" );
1991 test_no_file_info( handle );
1993 pNtClose(handle);
1995 handle = CreateFileA( "nul", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
1996 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1997 test_object_name( handle, L"\\Device\\Null", TRUE );
1998 test_object_type( handle, L"File" );
1999 test_file_info( handle );
2000 pNtClose( handle );
2003 static void test_type_mismatch(void)
2005 HANDLE h;
2006 NTSTATUS res;
2007 OBJECT_ATTRIBUTES attr;
2009 attr.Length = sizeof(attr);
2010 attr.RootDirectory = 0;
2011 attr.ObjectName = NULL;
2012 attr.Attributes = 0;
2013 attr.SecurityDescriptor = NULL;
2014 attr.SecurityQualityOfService = NULL;
2016 res = pNtCreateEvent( &h, 0, &attr, NotificationEvent, 0 );
2017 ok(!res, "can't create event: %lx\n", res);
2019 res = pNtReleaseSemaphore( h, 30, NULL );
2020 ok(res == STATUS_OBJECT_TYPE_MISMATCH, "expected 0xc0000024, got %lx\n", res);
2022 pNtClose( h );
2025 static void test_null_device(void)
2027 OBJECT_ATTRIBUTES attr;
2028 IO_STATUS_BLOCK iosb;
2029 UNICODE_STRING str;
2030 NTSTATUS status;
2031 DWORD num_bytes;
2032 OVERLAPPED ov;
2033 char buf[64];
2034 HANDLE null;
2035 BOOL ret;
2037 memset(buf, 0xAA, sizeof(buf));
2038 memset(&ov, 0, sizeof(ov));
2039 ov.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
2041 RtlInitUnicodeString(&str, L"\\Device\\Null");
2042 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
2043 status = pNtOpenSymbolicLinkObject(&null, SYMBOLIC_LINK_QUERY, &attr);
2044 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
2045 "expected STATUS_OBJECT_TYPE_MISMATCH, got %08lx\n", status);
2047 status = pNtOpenFile(&null, GENERIC_READ | GENERIC_WRITE, &attr, &iosb,
2048 FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
2049 ok(status == STATUS_SUCCESS,
2050 "expected STATUS_SUCCESS, got %08lx\n", status);
2052 test_object_type(null, L"File");
2054 SetLastError(0xdeadbeef);
2055 ret = WriteFile(null, buf, sizeof(buf), &num_bytes, NULL);
2056 ok(!ret, "WriteFile unexpectedly succeeded\n");
2057 ok(GetLastError() == ERROR_INVALID_PARAMETER,
2058 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
2060 SetLastError(0xdeadbeef);
2061 ret = ReadFile(null, buf, sizeof(buf), &num_bytes, NULL);
2062 ok(!ret, "ReadFile unexpectedly succeeded\n");
2063 ok(GetLastError() == ERROR_INVALID_PARAMETER,
2064 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
2066 num_bytes = 0xdeadbeef;
2067 SetLastError(0xdeadbeef);
2068 ret = WriteFile(null, buf, sizeof(buf), &num_bytes, &ov);
2069 ok(ret, "got error %lu\n", GetLastError());
2070 ok(num_bytes == sizeof(buf), "expected num_bytes = %lu, got %lu\n",
2071 (DWORD)sizeof(buf), num_bytes);
2073 num_bytes = 0xdeadbeef;
2074 SetLastError(0xdeadbeef);
2075 ret = ReadFile(null, buf, sizeof(buf), &num_bytes, &ov);
2076 ok(!ret, "expected failure\n");
2077 ok(GetLastError() == ERROR_HANDLE_EOF, "got error %lu\n", GetLastError());
2079 pNtClose(null);
2081 null = CreateFileA("\\\\.\\Null", GENERIC_READ | GENERIC_WRITE,
2082 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2083 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2084 ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
2085 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
2086 "expected ERROR_FILE_NOT_FOUND, got %lu\n", GetLastError());
2088 null = CreateFileA("\\\\.\\Device\\Null", GENERIC_READ | GENERIC_WRITE,
2089 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2090 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2091 ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
2092 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
2093 "expected ERROR_PATH_NOT_FOUND, got %lu\n", GetLastError());
2095 CloseHandle(ov.hEvent);
2098 static void test_process(void)
2100 OBJECT_ATTRIBUTES attr;
2101 CLIENT_ID cid;
2102 NTSTATUS status;
2103 HANDLE process;
2105 if (!pNtOpenProcess)
2107 win_skip( "NtOpenProcess not supported, skipping test\n" );
2108 return;
2111 InitializeObjectAttributes( &attr, NULL, 0, 0, NULL );
2113 cid.UniqueProcess = 0;
2114 cid.UniqueThread = 0;
2115 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, NULL, &cid );
2116 todo_wine ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcess returned %lx\n", status );
2117 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, NULL );
2118 todo_wine ok( status == STATUS_INVALID_PARAMETER_MIX, "NtOpenProcess returned %lx\n", status );
2120 cid.UniqueProcess = 0;
2121 cid.UniqueThread = 0;
2122 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2123 ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %lx\n", status );
2125 cid.UniqueProcess = ULongToHandle( 0xdeadbeef );
2126 cid.UniqueThread = ULongToHandle( 0xdeadbeef );
2127 process = (HANDLE)0xdeadbeef;
2128 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2129 ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %lx\n", status );
2130 ok( !process || broken(process == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", process );
2132 cid.UniqueProcess = ULongToHandle( GetCurrentThreadId() );
2133 cid.UniqueThread = 0;
2134 process = (HANDLE)0xdeadbeef;
2135 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2136 ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %lx\n", status );
2137 ok( !process || broken(process == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", process );
2139 cid.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
2140 cid.UniqueThread = 0;
2141 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2142 ok( !status, "NtOpenProcess returned %lx\n", status );
2143 pNtClose( process );
2145 cid.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
2146 cid.UniqueThread = ULongToHandle( GetCurrentThreadId() );
2147 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2148 ok( !status, "NtOpenProcess returned %lx\n", status );
2149 pNtClose( process );
2150 status = pNtOpenProcess( (HANDLE *)0xdeadbee0, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2151 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcess returned %lx\n", status );
2154 static void test_token(void)
2156 NTSTATUS status;
2157 HANDLE handle, handle2;
2159 status = pNtOpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS, (HANDLE *)0xdeadbee0 );
2160 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcessToken failed: %lx\n", status);
2161 status = pNtOpenThreadToken( GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, (HANDLE *)0xdeadbee0 );
2162 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcessToken failed: %lx\n", status);
2163 handle = (HANDLE)0xdeadbeef;
2164 status = pNtOpenProcessToken( (HANDLE)0xdead, TOKEN_ALL_ACCESS, &handle );
2165 ok( status == STATUS_INVALID_HANDLE, "NtOpenProcessToken failed: %lx\n", status);
2166 ok( !handle || broken(handle == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", handle );
2167 handle = (HANDLE)0xdeadbeef;
2168 status = pNtOpenThreadToken( (HANDLE)0xdead, TOKEN_ALL_ACCESS, TRUE, &handle );
2169 ok( status == STATUS_INVALID_HANDLE, "NtOpenThreadToken failed: %lx\n", status);
2170 ok( !handle || broken(handle == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", handle );
2172 status = pNtOpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS, &handle );
2173 ok( status == STATUS_SUCCESS, "NtOpenProcessToken failed: %lx\n", status);
2174 status = pNtDuplicateToken( handle, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, &handle2 );
2175 ok( status == STATUS_SUCCESS, "NtOpenProcessToken failed: %lx\n", status);
2176 pNtClose( handle2 );
2177 status = pNtDuplicateToken( handle, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, (HANDLE *)0xdeadbee0 );
2178 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcessToken failed: %lx\n", status);
2179 handle2 = (HANDLE)0xdeadbeef;
2180 status = pNtDuplicateToken( (HANDLE)0xdead, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, &handle2 );
2181 ok( status == STATUS_INVALID_HANDLE, "NtOpenProcessToken failed: %lx\n", status);
2182 ok( !handle2 || broken(handle2 == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", handle2 );
2183 pNtClose( handle );
2186 #define DEBUG_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2187 #define DEBUG_GENERIC_READ (STANDARD_RIGHTS_READ|DEBUG_READ_EVENT)
2188 #define DEBUG_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|DEBUG_PROCESS_ASSIGN)
2189 #define DESKTOP_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|DESKTOP_SWITCHDESKTOP)
2190 #define DESKTOP_GENERIC_READ (STANDARD_RIGHTS_READ|DESKTOP_ENUMERATE|DESKTOP_READOBJECTS)
2191 #define DESKTOP_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|DESKTOP_WRITEOBJECTS|DESKTOP_JOURNALPLAYBACK|\
2192 DESKTOP_JOURNALRECORD|DESKTOP_HOOKCONTROL|DESKTOP_CREATEMENU| \
2193 DESKTOP_CREATEWINDOW)
2194 #define DIRECTORY_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|DIRECTORY_TRAVERSE|DIRECTORY_QUERY)
2195 #define DIRECTORY_GENERIC_READ (STANDARD_RIGHTS_READ|DIRECTORY_TRAVERSE|DIRECTORY_QUERY)
2196 #define DIRECTORY_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|DIRECTORY_CREATE_SUBDIRECTORY|\
2197 DIRECTORY_CREATE_OBJECT)
2198 #define EVENT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2199 #define EVENT_GENERIC_READ (STANDARD_RIGHTS_READ|EVENT_QUERY_STATE)
2200 #define EVENT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|EVENT_MODIFY_STATE)
2201 #define IO_COMPLETION_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2202 #define IO_COMPLETION_GENERIC_READ (STANDARD_RIGHTS_READ|IO_COMPLETION_QUERY_STATE)
2203 #define IO_COMPLETION_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|IO_COMPLETION_MODIFY_STATE)
2204 #define JOB_OBJECT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2205 #define JOB_OBJECT_GENERIC_READ (STANDARD_RIGHTS_READ|JOB_OBJECT_QUERY)
2206 #define JOB_OBJECT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|JOB_OBJECT_TERMINATE|\
2207 JOB_OBJECT_SET_ATTRIBUTES|JOB_OBJECT_ASSIGN_PROCESS)
2208 #define KEY_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|KEY_CREATE_LINK|KEY_NOTIFY|\
2209 KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE)
2210 #define KEY_GENERIC_READ (STANDARD_RIGHTS_READ|KEY_NOTIFY|KEY_ENUMERATE_SUB_KEYS|\
2211 KEY_QUERY_VALUE)
2212 #define KEY_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|KEY_CREATE_SUB_KEY|KEY_SET_VALUE)
2213 #define KEYEDEVENT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE)
2214 #define KEYEDEVENT_GENERIC_READ (STANDARD_RIGHTS_READ|KEYEDEVENT_WAIT)
2215 #define KEYEDEVENT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|KEYEDEVENT_WAKE)
2216 #define MUTANT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2217 #define MUTANT_GENERIC_READ (STANDARD_RIGHTS_READ|MUTANT_QUERY_STATE)
2218 #define MUTANT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE)
2219 #define PROCESS_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE|\
2220 PROCESS_QUERY_LIMITED_INFORMATION|PROCESS_TERMINATE)
2221 #define PROCESS_GENERIC_READ (STANDARD_RIGHTS_READ|PROCESS_VM_READ|PROCESS_QUERY_INFORMATION)
2222 #define PROCESS_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|PROCESS_SUSPEND_RESUME|\
2223 PROCESS_SET_INFORMATION|PROCESS_SET_QUOTA|PROCESS_CREATE_PROCESS|\
2224 PROCESS_DUP_HANDLE|PROCESS_VM_WRITE|PROCESS_VM_OPERATION|\
2225 PROCESS_CREATE_THREAD)
2226 #define SECTION_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SECTION_MAP_EXECUTE)
2227 #define SECTION_GENERIC_READ (STANDARD_RIGHTS_READ|SECTION_QUERY|SECTION_MAP_READ)
2228 #define SECTION_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|SECTION_MAP_WRITE)
2229 #define SEMAPHORE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2230 #define SEMAPHORE_GENERIC_READ (STANDARD_RIGHTS_READ|SEMAPHORE_QUERY_STATE)
2231 #define SEMAPHORE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|SEMAPHORE_MODIFY_STATE)
2232 #define SYMBOLIC_LINK_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYMBOLIC_LINK_QUERY)
2233 #define SYMBOLIC_LINK_GENERIC_READ (STANDARD_RIGHTS_READ|SYMBOLIC_LINK_QUERY)
2234 #define SYMBOLIC_LINK_GENERIC_WRITE (STANDARD_RIGHTS_WRITE)
2235 #define THREAD_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE|THREAD_RESUME|\
2236 THREAD_QUERY_LIMITED_INFORMATION)
2237 #define THREAD_GENERIC_READ (STANDARD_RIGHTS_READ|THREAD_QUERY_INFORMATION|THREAD_GET_CONTEXT)
2238 #define THREAD_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|THREAD_SET_LIMITED_INFORMATION|\
2239 THREAD_SET_INFORMATION|THREAD_SET_CONTEXT|THREAD_SUSPEND_RESUME|\
2240 THREAD_TERMINATE|0x04)
2241 #define TIMER_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2242 #define TIMER_GENERIC_READ (STANDARD_RIGHTS_READ|TIMER_QUERY_STATE)
2243 #define TIMER_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|TIMER_MODIFY_STATE)
2244 #define TOKEN_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|TOKEN_IMPERSONATE|TOKEN_ASSIGN_PRIMARY)
2245 #define TOKEN_GENERIC_READ (STANDARD_RIGHTS_READ|TOKEN_QUERY_SOURCE|TOKEN_QUERY|TOKEN_DUPLICATE)
2246 #define TOKEN_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|TOKEN_ADJUST_SESSIONID|TOKEN_ADJUST_DEFAULT|\
2247 TOKEN_ADJUST_GROUPS|TOKEN_ADJUST_PRIVILEGES)
2248 #define TYPE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE)
2249 #define TYPE_GENERIC_READ (STANDARD_RIGHTS_READ)
2250 #define TYPE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE)
2251 #define WINSTA_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|WINSTA_EXITWINDOWS|WINSTA_ACCESSGLOBALATOMS)
2252 #define WINSTA_GENERIC_READ (STANDARD_RIGHTS_READ|WINSTA_READSCREEN|WINSTA_ENUMERATE|\
2253 WINSTA_READATTRIBUTES|WINSTA_ENUMDESKTOPS)
2254 #define WINSTA_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|WINSTA_WRITEATTRIBUTES|WINSTA_CREATEDESKTOP|\
2255 WINSTA_ACCESSCLIPBOARD)
2257 #undef WINSTA_ALL_ACCESS
2258 #undef DESKTOP_ALL_ACCESS
2259 #define WINSTA_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x37f)
2260 #define DESKTOP_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x1ff)
2261 #define DEVICE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1ff)
2262 #define TYPE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x1)
2264 static void *align_ptr( void *ptr )
2266 ULONG_PTR align = sizeof(DWORD_PTR) - 1;
2267 return (void *)(((DWORD_PTR)ptr + align) & ~align);
2270 static void test_duplicate_object(void)
2272 NTSTATUS status;
2273 HANDLE handle;
2275 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2276 &handle, PROCESS_ALL_ACCESS, 0, 0 );
2277 ok( !status, "NtDuplicateObject failed %lx\n", status );
2278 pNtClose( handle );
2279 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2280 NULL, PROCESS_ALL_ACCESS, 0, 0 );
2281 ok( !status, "NtDuplicateObject failed %lx\n", status );
2283 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2284 (HANDLE *)0xdeadbee0, PROCESS_ALL_ACCESS, 0, 0 );
2285 ok( status == STATUS_ACCESS_VIOLATION, "NtDuplicateObject failed %lx\n", status );
2287 handle = (HANDLE)0xdeadbeef;
2288 status = pNtDuplicateObject( GetCurrentProcess(), (HANDLE)0xdead, GetCurrentProcess(),
2289 &handle, PROCESS_ALL_ACCESS, 0, 0 );
2290 ok( status == STATUS_INVALID_HANDLE, "NtDuplicateObject failed %lx\n", status );
2291 ok( !handle, "handle set %p\n", handle );
2293 handle = (HANDLE)0xdeadbeef;
2294 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2295 &handle, ~0u, 0, 0 );
2296 todo_wine
2297 ok( status == STATUS_ACCESS_DENIED, "NtDuplicateObject failed %lx\n", status );
2298 todo_wine
2299 ok( !handle, "handle set %p\n", handle );
2300 if (!status) pNtClose( handle );
2303 static void test_object_types(void)
2305 static const struct { const WCHAR *name; GENERIC_MAPPING mapping; ULONG mask, broken; } tests[] =
2307 #define TYPE(name,gen,extra,broken) { name, { gen ## _GENERIC_READ, gen ## _GENERIC_WRITE, \
2308 gen ## _GENERIC_EXECUTE, gen ## _ALL_ACCESS }, gen ## _ALL_ACCESS | extra, broken }
2309 TYPE( L"DebugObject", DEBUG, 0, 0 ),
2310 TYPE( L"Desktop", DESKTOP, 0, 0 ),
2311 TYPE( L"Device", FILE, 0, 0 ),
2312 TYPE( L"Directory", DIRECTORY, 0, 0 ),
2313 TYPE( L"Event", EVENT, 0, 0 ),
2314 TYPE( L"File", FILE, 0, 0 ),
2315 TYPE( L"IoCompletion", IO_COMPLETION, 0, 0 ),
2316 TYPE( L"Job", JOB_OBJECT, 0, JOB_OBJECT_IMPERSONATE ),
2317 TYPE( L"Key", KEY, SYNCHRONIZE, 0 ),
2318 TYPE( L"KeyedEvent", KEYEDEVENT, SYNCHRONIZE, 0 ),
2319 TYPE( L"Mutant", MUTANT, 0, 0 ),
2320 TYPE( L"Process", PROCESS, 0, 0 ),
2321 TYPE( L"Section", SECTION, SYNCHRONIZE, 0 ),
2322 TYPE( L"Semaphore", SEMAPHORE, 0, 0 ),
2323 TYPE( L"SymbolicLink", SYMBOLIC_LINK, 0, 0xfffe ),
2324 TYPE( L"Thread", THREAD, 0, THREAD_RESUME ),
2325 TYPE( L"Timer", TIMER, 0, 0 ),
2326 TYPE( L"Token", TOKEN, SYNCHRONIZE, 0 ),
2327 TYPE( L"Type", TYPE, SYNCHRONIZE, 0 ),
2328 TYPE( L"WindowStation", WINSTA, 0, 0 ),
2329 #undef TYPE
2331 unsigned int i, j;
2332 BOOLEAN tested[ARRAY_SIZE(all_types)] = { 0 };
2333 char buffer[256];
2334 OBJECT_TYPES_INFORMATION *info = (OBJECT_TYPES_INFORMATION *)buffer;
2335 GENERIC_MAPPING map;
2336 NTSTATUS status;
2337 ULONG len, retlen;
2339 memset( buffer, 0xcc, sizeof(buffer) );
2340 status = pNtQueryObject( NULL, ObjectTypesInformation, info, sizeof(buffer), &len );
2341 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
2342 ok( info->NumberOfTypes < 100 || info->NumberOfTypes == 0xcccccccc, /* wow64 */
2343 "wrong number of types %lu\n", info->NumberOfTypes );
2345 info = malloc( len + 16 ); /* Windows gets the length wrong on WoW64 and overflows the buffer */
2346 memset( info, 0xcc, sizeof(*info) );
2347 status = pNtQueryObject( NULL, ObjectTypesInformation, info, len, &retlen );
2348 ok( retlen <= len + 16, "wrong len %lx/%lx\n", len, retlen );
2349 ok( len == retlen || broken( retlen >= len - 32 && retlen <= len + 32 ), /* wow64 */
2350 "wrong len %lx/%lx\n", len, retlen );
2351 ok( !status, "NtQueryObject failed %lx\n", status );
2352 if (!status)
2354 OBJECT_TYPE_INFORMATION *type = align_ptr( info + 1 );
2355 for (i = 0; i < info->NumberOfTypes; i++)
2357 add_object_type( type );
2358 type = align_ptr( (char *)type->TypeName.Buffer + type->TypeName.MaximumLength );
2361 free( info );
2363 for (i = 0; i < ARRAY_SIZE(tests); i++)
2365 for (j = 0; j < ARRAY_SIZE(all_types); j++)
2367 if (!all_types[j].TypeName.Buffer) continue;
2368 if (wcscmp( tests[i].name, all_types[j].TypeName.Buffer )) continue;
2369 map = all_types[j].GenericMapping;
2370 ok( !memcmp( &map, &tests[i].mapping, sizeof(GENERIC_MAPPING) ) ||
2371 broken( !((map.GenericRead ^ tests[i].mapping.GenericRead) & ~tests[i].broken) &&
2372 !((map.GenericWrite ^ tests[i].mapping.GenericWrite) & ~tests[i].broken) &&
2373 !((map.GenericExecute ^ tests[i].mapping.GenericExecute) & ~tests[i].broken) &&
2374 !((map.GenericAll ^ tests[i].mapping.GenericAll) & ~tests[i].broken) ),
2375 "%s: mismatched mappings %08lx,%08lx,%08lx,%08lx / %08lx,%08lx,%08lx,%08lx\n",
2376 debugstr_w( tests[i].name ),
2377 all_types[j].GenericMapping.GenericRead, all_types[j].GenericMapping.GenericWrite,
2378 all_types[j].GenericMapping.GenericExecute, all_types[j].GenericMapping.GenericAll,
2379 tests[i].mapping.GenericRead, tests[i].mapping.GenericWrite,
2380 tests[i].mapping.GenericExecute, tests[i].mapping.GenericAll );
2381 ok( all_types[j].ValidAccessMask == tests[i].mask ||
2382 broken( !((all_types[j].ValidAccessMask ^ tests[i].mask) & ~tests[i].broken) ),
2383 "%s: mismatched access mask %08lx / %08lx\n", debugstr_w( tests[i].name ),
2384 all_types[j].ValidAccessMask, tests[i].mask );
2385 tested[j] = TRUE;
2386 break;
2388 ok( j < ARRAY_SIZE(all_types), "type %s not found\n", debugstr_w(tests[i].name) );
2390 for (j = 0; j < ARRAY_SIZE(all_types); j++)
2392 if (!all_types[j].TypeName.Buffer) continue;
2393 if (tested[j]) continue;
2394 trace( "not tested: %s\n", debugstr_w(all_types[j].TypeName.Buffer ));
2398 static DWORD WINAPI test_get_next_thread_proc( void *arg )
2400 HANDLE event = (HANDLE)arg;
2402 WaitForSingleObject(event, INFINITE);
2403 return 0;
2406 static void test_get_next_thread(void)
2408 HANDLE hprocess = GetCurrentProcess();
2409 HANDLE handle, thread, event, prev;
2410 NTSTATUS status;
2411 DWORD thread_id;
2412 BOOL found;
2414 if (!pNtGetNextThread)
2416 win_skip("NtGetNextThread is not available.\n");
2417 return;
2420 event = CreateEventA(NULL, FALSE, FALSE, NULL);
2422 thread = CreateThread( NULL, 0, test_get_next_thread_proc, event, 0, &thread_id );
2424 status = pNtGetNextThread(hprocess, NULL, THREAD_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, NULL);
2425 ok(status == STATUS_ACCESS_VIOLATION, "Got unexpected status %#lx.\n", status);
2427 found = FALSE;
2428 prev = NULL;
2429 while (!(status = pNtGetNextThread(hprocess, prev, THREAD_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle)))
2431 if (prev)
2433 if (GetThreadId(handle) == thread_id)
2434 found = TRUE;
2435 pNtClose(prev);
2437 else
2439 ok(GetThreadId(handle) == GetCurrentThreadId(), "Got unexpected thread id %04lx, current %04lx.\n",
2440 GetThreadId(handle), GetCurrentThreadId());
2442 prev = handle;
2443 handle = (HANDLE)0xdeadbeef;
2445 pNtClose(prev);
2446 ok(!handle, "Got unexpected handle %p.\n", handle);
2447 ok(status == STATUS_NO_MORE_ENTRIES, "Unexpected status %#lx.\n", status);
2448 ok(found, "Thread not found.\n");
2450 handle = (HANDLE)0xdeadbeef;
2451 status = pNtGetNextThread((void *)0xdeadbeef, 0, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle);
2452 ok(status == STATUS_INVALID_HANDLE, "Unexpected status %#lx.\n", status);
2453 ok(!handle, "Got unexpected handle %p.\n", handle);
2454 handle = (HANDLE)0xdeadbeef;
2455 status = pNtGetNextThread(hprocess, (void *)0xdeadbeef, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle);
2456 ok(status == STATUS_INVALID_HANDLE, "Unexpected status %#lx.\n", status);
2457 ok(!handle, "Got unexpected handle %p.\n", handle);
2459 /* Reversed search is only supported on recent enough Win10. */
2460 status = pNtGetNextThread(hprocess, 0, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 1, &handle);
2461 ok(!status || broken(status == STATUS_INVALID_PARAMETER), "Unexpected status %#lx.\n", status);
2462 if (!status)
2463 pNtClose(handle);
2465 status = pNtGetNextThread(hprocess, 0, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 2, &handle);
2466 ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %#lx.\n", status);
2468 SetEvent(event);
2469 WaitForSingleObject(thread, INFINITE);
2471 found = FALSE;
2472 prev = NULL;
2473 while (!(status = pNtGetNextThread(hprocess, prev, THREAD_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle)))
2475 if (prev)
2476 pNtClose(prev);
2477 if (GetThreadId(handle) == thread_id)
2478 found = TRUE;
2479 prev = handle;
2481 pNtClose(prev);
2482 ok(found, "Thread not found.\n");
2484 CloseHandle(thread);
2487 static void test_globalroot(void)
2489 NTSTATUS status;
2490 IO_STATUS_BLOCK iosb;
2491 UNICODE_STRING str;
2492 OBJECT_ATTRIBUTES attr;
2493 HANDLE h;
2494 WCHAR buffer[256];
2495 ULONG len, full_len, i;
2496 static const struct { const WCHAR *name, *target; } symlinks[] = {
2497 { L"\\??\\GLOBALROOT", L"" },
2498 { L"\\??\\GLOBALROOT\\??\\GLOBALROOT", L"" },
2499 { L"\\??\\GLOBALROOT\\??\\GLOBALROOT\\??\\GLOBALROOT", L"" },
2500 { L"\\??\\GLOBALROOT\\DosDevices", L"\\??" },
2501 { L"\\??\\GLOBALROOT\\BaseNamedObjects\\Global", NULL },
2504 for (i = 0; i < ARRAY_SIZE(symlinks); i++)
2506 pRtlInitUnicodeString(&str, symlinks[i].name);
2507 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
2508 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
2509 ok(status == STATUS_SUCCESS, "NtOpenSymbolicLinkObject failed %08lx\n", status);
2511 str.Buffer = buffer;
2512 str.MaximumLength = sizeof(buffer);
2513 len = 0xdeadbeef;
2514 memset( buffer, 0xaa, sizeof(buffer) );
2515 status = pNtQuerySymbolicLinkObject( h, &str, &len);
2516 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08lx\n", status );
2517 full_len = str.Length + sizeof(WCHAR);
2518 ok( len == full_len, "bad length %lu (expected %lu)\n", len, full_len );
2519 ok( buffer[len / sizeof(WCHAR) - 1] == 0, "no terminating null\n" );
2521 if (symlinks[i].target)
2523 ok( compare_unicode_string( &str, symlinks[i].target ),
2524 "symlink %s: target expected %s, got %s\n",
2525 debugstr_w( symlinks[i].name ),
2526 debugstr_w( symlinks[i].target ),
2527 debugstr_w( str.Buffer ) );
2530 pNtClose(h);
2533 pRtlInitUnicodeString(&str, L"\\??\\GLOBALROOT\\Device\\Null");
2534 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
2535 status = pNtOpenFile(&h, GENERIC_READ | GENERIC_WRITE, &attr, &iosb,
2536 FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
2537 ok(status == STATUS_SUCCESS,
2538 "expected STATUS_SUCCESS, got %08lx\n", status);
2540 test_object_type(h, L"File");
2542 pNtClose(h);
2545 static void test_object_identity(void)
2547 NTSTATUS status;
2548 HANDLE h1, h2;
2550 if (!pNtCompareObjects)
2552 win_skip("NtCompareObjects is not available.\n");
2553 return;
2556 status = pNtCompareObjects( GetCurrentProcess(), GetCurrentProcess() );
2557 ok( status == STATUS_SUCCESS, "comparing GetCurrentProcess() to self failed with %08lx\n", status );
2559 status = pNtCompareObjects( GetCurrentThread(), GetCurrentThread() );
2560 ok( status == STATUS_SUCCESS, "comparing GetCurrentThread() to self failed with %08lx\n", status );
2562 status = pNtCompareObjects( GetCurrentProcess(), GetCurrentThread() );
2563 ok( status == STATUS_NOT_SAME_OBJECT, "comparing GetCurrentProcess() to GetCurrentThread() returned %08lx\n", status );
2565 h1 = NULL;
2566 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2567 &h1, 0, 0, DUPLICATE_SAME_ACCESS );
2568 ok( status == STATUS_SUCCESS, "failed to duplicate current process handle: %08lx\n", status);
2570 status = pNtCompareObjects( GetCurrentProcess(), h1 );
2571 ok( status == STATUS_SUCCESS, "comparing GetCurrentProcess() with %p failed with %08lx\n", h1, status );
2573 pNtClose( h1 );
2575 h1 = CreateFileA( "\\\\.\\NUL", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
2576 ok( h1 != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
2578 h2 = NULL;
2579 status = pNtDuplicateObject( GetCurrentProcess(), h1, GetCurrentProcess(),
2580 &h2, 0, 0, DUPLICATE_SAME_ACCESS );
2581 ok( status == STATUS_SUCCESS, "failed to duplicate handle %p: %08lx\n", h1, status);
2583 status = pNtCompareObjects( h1, h2 );
2584 ok( status == STATUS_SUCCESS, "comparing %p with %p failed with %08lx\n", h1, h2, status );
2586 pNtClose( h2 );
2588 h2 = CreateFileA( "\\\\.\\NUL", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
2589 ok( h2 != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
2591 status = pNtCompareObjects( h1, h2 );
2592 ok( status == STATUS_NOT_SAME_OBJECT, "comparing %p with %p returned %08lx\n", h1, h2, status );
2594 pNtClose( h2 );
2595 pNtClose( h1 );
2598 static void test_query_directory(void)
2600 static const DIRECTORY_BASIC_INFORMATION empty_info;
2601 char buffer[200];
2602 DIRECTORY_BASIC_INFORMATION *info = (void *)buffer;
2603 ULONG context, size, needed_size;
2604 const WCHAR *name1, *name2;
2605 HANDLE dir, child1, child2;
2606 OBJECT_ATTRIBUTES attr;
2607 UNICODE_STRING string;
2608 NTSTATUS status;
2609 BOOL is_wow64 = FALSE;
2611 #ifndef _WIN64
2612 if (!IsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
2613 #endif
2615 RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest" );
2616 InitializeObjectAttributes( &attr, &string, 0, 0, NULL );
2617 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
2618 ok( !status, "got %#lx\n", status );
2620 context = 0xdeadbeef;
2621 size = 0xdeadbeef;
2622 status = NtQueryDirectoryObject( dir, info, 0, TRUE, TRUE, &context, &size );
2623 ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2624 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2625 ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2627 context = 0xdeadbeef;
2628 size = 0xdeadbeef;
2629 status = NtQueryDirectoryObject( dir, info, 0, FALSE, TRUE, &context, &size );
2630 todo_wine ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2631 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2632 todo_wine ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2634 context = 0xdeadbeef;
2635 size = 0xdeadbeef;
2636 memset( buffer, 0xcc, sizeof(buffer) );
2637 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2638 ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2639 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2640 ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2641 if (size == sizeof(*info))
2642 ok( !memcmp( &info[0], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2644 context = 0xdeadbeef;
2645 size = 0xdeadbeef;
2646 memset( buffer, 0xcc, sizeof(buffer) );
2647 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), FALSE, TRUE, &context, &size );
2648 todo_wine ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2649 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2650 todo_wine ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2651 if (size == sizeof(*info))
2652 ok( !memcmp( &info[0], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2654 RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest\\Telamon" );
2655 status = NtCreateMutant( &child1, GENERIC_ALL, &attr, FALSE );
2656 ok( !status, "got %#lx\n", status );
2658 RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest\\Oileus" );
2659 status = NtCreateMutant( &child2, GENERIC_ALL, &attr, FALSE );
2660 ok( !status, "got %#lx\n", status );
2662 context = 0xdeadbeef;
2663 size = 0xdeadbeef;
2664 status = NtQueryDirectoryObject( NULL, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2665 ok( status == STATUS_INVALID_HANDLE, "got %#lx\n", status );
2666 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2667 ok( size == 0xdeadbeef || broken(!size) /* WoW64 */, "got size %lu\n", size);
2669 size = 0xdeadbeef;
2670 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, NULL, &size );
2671 ok( status == STATUS_ACCESS_VIOLATION, "got %#lx\n", status );
2672 ok( size == 0xdeadbeef, "got size %lu\n", size);
2674 context = 0xdeadbeef;
2675 size = 0xdeadbeef;
2676 memset( buffer, 0xcc, sizeof(buffer) );
2677 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2678 ok( !status, "got %#lx\n", status );
2679 ok( context == 1, "got context %#lx\n", context );
2680 ok( size && size < sizeof(buffer), "got size %lu\n", size );
2681 if (!wcscmp( info[0].ObjectName.Buffer, L"Oileus" ))
2683 name1 = L"Oileus";
2684 name2 = L"Telamon";
2686 else
2688 name1 = L"Telamon";
2689 name2 = L"Oileus";
2691 check_unicode_string( &info[0].ObjectName, name1 );
2692 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2693 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2695 memset( buffer, 0xcc, sizeof(buffer) );
2696 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
2697 ok( !status, "got %#lx\n", status );
2698 ok( context == 2, "got context %#lx\n", context );
2699 check_unicode_string( &info[0].ObjectName, name2 );
2700 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2701 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2703 size = 0xdeadbeef;
2704 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
2705 ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2706 ok( context == 2, "got context %#lx\n", context );
2707 ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2709 memset( buffer, 0xcc, sizeof(buffer) );
2710 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2711 ok( !status, "got %#lx\n", status );
2712 ok( context == 1, "got context %#lx\n", context );
2713 check_unicode_string( &info[0].ObjectName, name1 );
2714 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2715 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2717 needed_size = size;
2719 size = 0xdeadbeef;
2720 context = 0xdeadbeef;
2721 status = NtQueryDirectoryObject( dir, info, 0, TRUE, TRUE, &context, &size );
2722 ok( status == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", status );
2723 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2724 ok( size == needed_size, "expected size %lu, got %lu\n", needed_size, size );
2726 size = 0xdeadbeef;
2727 memset( buffer, 0xcc, sizeof(buffer) );
2728 status = NtQueryDirectoryObject( dir, info, needed_size - 1, TRUE, TRUE, &context, &size );
2729 ok( status == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", status );
2730 ok( size == needed_size, "expected size %lu, got %lu\n", needed_size, size );
2732 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, NULL );
2733 ok( !status, "got %#lx\n", status );
2735 context = 0;
2736 memset( buffer, 0xcc, sizeof(buffer) );
2737 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
2738 ok( !status, "got %#lx\n", status );
2739 ok( context == 1, "got context %#lx\n", context );
2740 check_unicode_string( &info[0].ObjectName, name1 );
2741 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2742 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2744 memset( buffer, 0xcc, sizeof(buffer) );
2745 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), FALSE, TRUE, &context, &size );
2746 todo_wine ok( !status, "got %#lx\n", status );
2747 if (!status)
2749 ok( context == 2, "got context %#lx\n", context );
2750 check_unicode_string( &info[0].ObjectName, name1 );
2751 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2752 check_unicode_string( &info[1].ObjectName, name2 );
2753 check_unicode_string( &info[1].ObjectTypeName, L"Mutant" );
2754 ok( !memcmp( &info[2], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2757 needed_size = size;
2758 size = 0xdeadbeef;
2759 context = 0xdeadbeef;
2760 memset( buffer, 0xcc, sizeof(buffer) );
2761 status = NtQueryDirectoryObject( dir, info, needed_size - 1, FALSE, TRUE, &context, &size );
2762 todo_wine ok( status == STATUS_MORE_ENTRIES, "got %#lx\n", status );
2763 if (status == STATUS_MORE_ENTRIES)
2765 ok( context == 1, "got context %#lx\n", context );
2766 ok( size > 0 && size < needed_size, "got size %lu\n", size );
2767 check_unicode_string( &info[0].ObjectName, name1 );
2768 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2769 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2772 size = 0xdeadbeef;
2773 context = 0xdeadbeef;
2774 memset( buffer, 0xcc, sizeof(buffer) );
2775 status = NtQueryDirectoryObject( dir, info, sizeof(*info), FALSE, TRUE, &context, &size );
2776 todo_wine ok( status == STATUS_MORE_ENTRIES
2777 || broken(status == STATUS_BUFFER_TOO_SMALL) /* wow64 */, "got %#lx\n", status );
2778 if (status == STATUS_MORE_ENTRIES)
2780 ok( !context, "got context %#lx\n", context );
2781 ok( size == sizeof(*info), "got size %lu\n", size );
2782 ok( !memcmp( &info[0], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2785 size = 0xdeadbeef;
2786 context = 0xdeadbeef;
2787 status = NtQueryDirectoryObject( dir, info, 0, FALSE, TRUE, &context, &size );
2788 todo_wine ok( status == STATUS_MORE_ENTRIES
2789 || broken(status == STATUS_BUFFER_TOO_SMALL) /* wow64 */, "got %#lx\n", status );
2790 if (status == STATUS_MORE_ENTRIES)
2792 ok( !context, "got context %#lx\n", context );
2793 ok( size == sizeof(*info), "got size %lu\n", size );
2796 context = 1;
2797 memset( buffer, 0xcc, sizeof(buffer) );
2798 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), FALSE, FALSE, &context, &size );
2799 todo_wine ok( !status, "got %#lx\n", status );
2800 if (!status)
2802 ok( context == 2, "got context %#lx\n", context );
2803 check_unicode_string( &info[0].ObjectName, name2 );
2804 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2805 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2808 pNtClose( child1 );
2809 pNtClose( child2 );
2810 pNtClose( dir );
2813 #define test_object_name_with_null(a,b) _test_object_name_with_null(__LINE__,a,b)
2814 static void _test_object_name_with_null(unsigned line, HANDLE handle, UNICODE_STRING *expect)
2816 char buffer[1024];
2817 UNICODE_STRING *str = (UNICODE_STRING *)buffer;
2818 ULONG len = 0;
2819 NTSTATUS status;
2821 memset(buffer, 0, sizeof(buffer));
2822 status = pNtQueryObject(handle, ObjectNameInformation, buffer, sizeof(buffer), &len);
2823 ok_(__FILE__,line)(status == STATUS_SUCCESS, "got %08lx\n", status);
2824 ok_(__FILE__,line)(len >= sizeof(OBJECT_NAME_INFORMATION) + str->Length, "got %lu\n", len);
2825 ok_(__FILE__,line)(str->Length == expect->Length, "got %u, expected %u\n", str->Length, expect->Length);
2826 ok_(__FILE__,line)(!wcsnicmp(str->Buffer, expect->Buffer, str->Length/sizeof(WCHAR)), "got %s, expected %s\n",
2827 debugstr_w(str->Buffer), debugstr_w(expect->Buffer));
2830 static void test_null_in_object_name(void)
2832 WCHAR name[256], name3[256], *p, *name_exp, *name3_exp;
2833 HANDLE handle, handle2;
2834 NTSTATUS status;
2835 OBJECT_ATTRIBUTES attr, attr2, attr3;
2836 UNICODE_STRING nameU, name2U, name3U, name2U_exp, name3U_exp;
2837 LARGE_INTEGER size;
2838 #ifndef _WIN64
2839 BOOL is_wow64 = FALSE;
2840 #endif
2842 trace("running as %d bit\n", (int)sizeof(void *) * 8);
2844 swprintf(name, ARRAY_SIZE(name), L"\\Sessions\\%u\\BaseNamedObjects\\wine_test", NtCurrentTeb()->Peb->SessionId);
2845 swprintf(name3, ARRAY_SIZE(name3), L"\\Sessions\\%u\\BaseNamedObjects\\wine_test", NtCurrentTeb()->Peb->SessionId);
2846 p = wcsrchr(name3, '\\');
2847 p[5] = 0; /* => \\wine\0test */
2849 RtlInitUnicodeString(&nameU, name);
2850 InitializeObjectAttributes(&attr, &nameU, 0, 0, NULL);
2852 name2U = nameU;
2853 name2U.Length += sizeof(WCHAR); /* add terminating \0 to string length */
2854 InitializeObjectAttributes(&attr2, &name2U, 0, 0, NULL);
2856 name3U = nameU;
2857 name3U.Buffer = name3;
2858 InitializeObjectAttributes(&attr3, &name3U, 0, 0, NULL);
2860 status = pNtCreateEvent(&handle, GENERIC_ALL, &attr, NotificationEvent, FALSE);
2861 ok(!status, "got %08lx\n", status);
2862 test_object_name(handle, name, FALSE);
2863 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr);
2864 ok(!status, "got %08lx\n", status);
2865 test_object_name(handle2, name, FALSE);
2866 pNtClose(handle2);
2867 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr2);
2868 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2869 pNtClose(handle);
2870 status = pNtCreateEvent(&handle, GENERIC_ALL, &attr2, NotificationEvent, FALSE);
2871 ok(!status, "got %08lx\n", status);
2872 test_object_name_with_null(handle, &name2U);
2873 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr2);
2874 ok(!status, "got %08lx\n", status);
2875 test_object_name_with_null(handle2, &name2U);
2876 pNtClose(handle2);
2877 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr);
2878 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2879 pNtClose(handle);
2880 status = pNtCreateEvent(&handle, GENERIC_ALL, &attr3, NotificationEvent, FALSE);
2881 ok(!status, "got %08lx\n", status);
2882 test_object_name_with_null(handle, &name3U);
2883 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr3);
2884 ok(!status, "got %08lx\n", status);
2885 test_object_name_with_null(handle2, &name3U);
2886 pNtClose(handle2);
2887 pNtClose(handle);
2889 status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr, 0);
2890 ok(!status, "got %08lx\n", status);
2891 test_object_name(handle, name, FALSE);
2892 pNtClose(handle);
2893 status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr2, 0);
2894 ok(!status, "got %08lx\n", status);
2895 test_object_name_with_null(handle, &name2U);
2896 pNtClose(handle);
2897 status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr3, 0);
2898 ok(!status, "got %08lx\n", status);
2899 test_object_name_with_null(handle, &name3U);
2900 pNtClose(handle);
2902 status = pNtCreateMutant(&handle, GENERIC_ALL, &attr, 0);
2903 ok(!status, "got %08lx\n", status);
2904 test_object_name(handle, name, FALSE);
2905 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr);
2906 ok(!status, "got %08lx\n", status);
2907 test_object_name(handle2, name, FALSE);
2908 pNtClose(handle2);
2909 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr2);
2910 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2911 pNtClose(handle);
2912 status = pNtCreateMutant(&handle, GENERIC_ALL, &attr2, 0);
2913 ok(!status, "got %08lx\n", status);
2914 test_object_name_with_null(handle, &name2U);
2915 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr2);
2916 ok(!status, "got %08lx\n", status);
2917 test_object_name_with_null(handle2, &name2U);
2918 pNtClose(handle2);
2919 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr);
2920 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2921 pNtClose(handle);
2922 status = pNtCreateMutant(&handle, GENERIC_ALL, &attr3, 0);
2923 ok(!status, "got %08lx\n", status);
2924 test_object_name_with_null(handle, &name3U);
2925 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr3);
2926 ok(!status, "got %08lx\n", status);
2927 test_object_name_with_null(handle2, &name3U);
2928 pNtClose(handle2);
2929 pNtClose(handle);
2931 status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr, 1, 2);
2932 ok(!status, "got %08lx\n", status);
2933 test_object_name(handle, name, FALSE);
2934 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr);
2935 ok(!status, "got %08lx\n", status);
2936 test_object_name(handle2, name, FALSE);
2937 pNtClose(handle2);
2938 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr2);
2939 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2940 pNtClose(handle);
2941 status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr2, 1, 2);
2942 ok(!status, "got %08lx\n", status);
2943 test_object_name_with_null(handle, &name2U);
2944 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr2);
2945 ok(!status, "got %08lx\n", status);
2946 test_object_name_with_null(handle2, &name2U);
2947 pNtClose(handle2);
2948 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr);
2949 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2950 pNtClose(handle);
2951 status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr3, 1, 2);
2952 ok(!status, "got %08lx\n", status);
2953 test_object_name_with_null(handle, &name3U);
2954 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr3);
2955 ok(!status, "got %08lx\n", status);
2956 test_object_name_with_null(handle2, &name3U);
2957 pNtClose(handle2);
2958 pNtClose(handle);
2960 status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr, 0);
2961 ok(!status, "got %08lx\n", status);
2962 test_object_name(handle, name, FALSE);
2963 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr);
2964 ok(!status, "got %08lx\n", status);
2965 test_object_name(handle2, name, FALSE);
2966 pNtClose(handle2);
2967 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr2);
2968 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2969 pNtClose(handle);
2970 status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr2, 0);
2971 ok(!status, "got %08lx\n", status);
2972 test_object_name_with_null(handle, &name2U);
2973 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr2);
2974 ok(!status, "got %08lx\n", status);
2975 test_object_name_with_null(handle2, &name2U);
2976 pNtClose(handle2);
2977 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr);
2978 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2979 pNtClose(handle);
2980 status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr3, 0);
2981 ok(!status, "got %08lx\n", status);
2982 test_object_name_with_null(handle, &name3U);
2983 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr3);
2984 ok(!status, "got %08lx\n", status);
2985 test_object_name_with_null(handle2, &name3U);
2986 pNtClose(handle2);
2987 pNtClose(handle);
2989 status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr, 0);
2990 ok(!status, "got %08lx\n", status);
2991 test_object_name(handle, name, FALSE);
2992 status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr);
2993 ok(!status, "got %08lx\n", status);
2994 test_object_name(handle2, name, FALSE);
2995 pNtClose(handle2);
2996 pNtClose(handle);
2997 status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr2, 0);
2998 ok(!status, "got %08lx\n", status);
2999 test_object_name_with_null(handle, &name2U);
3000 status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr2);
3001 ok(!status, "got %08lx\n", status);
3002 test_object_name_with_null(handle2, &name2U);
3003 pNtClose(handle2);
3004 pNtClose(handle);
3005 status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr3, 0);
3006 ok(!status, "got %08lx\n", status);
3007 test_object_name_with_null(handle, &name3U);
3008 status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr3);
3009 ok(!status, "got %08lx\n", status);
3010 test_object_name_with_null(handle2, &name3U);
3011 pNtClose(handle2);
3012 pNtClose(handle);
3014 status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr);
3015 ok(!status, "got %08lx\n", status);
3016 test_object_name(handle, name, FALSE);
3017 status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr);
3018 ok(!status, "got %08lx\n", status);
3019 test_object_name(handle2, name, FALSE);
3020 pNtClose(handle2);
3021 pNtClose(handle);
3022 status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr2);
3023 ok(!status, "got %08lx\n", status);
3024 test_object_name_with_null(handle, &name2U);
3025 status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr2);
3026 ok(!status, "got %08lx\n", status);
3027 test_object_name_with_null(handle2, &name2U);
3028 pNtClose(handle2);
3029 pNtClose(handle);
3030 status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr3);
3031 ok(!status, "got %08lx\n", status);
3032 test_object_name_with_null(handle, &name3U);
3033 status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr3);
3034 ok(!status, "got %08lx\n", status);
3035 test_object_name_with_null(handle2, &name3U);
3036 pNtClose(handle2);
3037 pNtClose(handle);
3039 status = pNtCreateTimer(&handle, GENERIC_ALL, &attr, NotificationTimer);
3040 ok(!status, "got %08lx\n", status);
3041 test_object_name(handle, name, FALSE);
3042 status = pNtOpenTimer(&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 = pNtCreateTimer(&handle, GENERIC_ALL, &attr2, NotificationTimer);
3048 ok(!status, "got %08lx\n", status);
3049 test_object_name_with_null(handle, &name2U);
3050 status = pNtOpenTimer(&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 = pNtCreateTimer(&handle, GENERIC_ALL, &attr3, NotificationTimer);
3056 ok(!status, "got %08lx\n", status);
3057 test_object_name_with_null(handle, &name3U);
3058 status = pNtOpenTimer(&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 size.QuadPart = 4096;
3065 status = pNtCreateSection(&handle, GENERIC_ALL, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
3066 ok(!status, "got %08lx\n", status);
3067 test_object_name(handle, name, FALSE);
3068 status = pNtOpenSection(&handle2, GENERIC_ALL, &attr);
3069 ok(!status, "got %08lx\n", status);
3070 test_object_name(handle2, name, FALSE);
3071 pNtClose(handle2);
3072 pNtClose(handle);
3073 status = pNtCreateSection(&handle, GENERIC_ALL, &attr2, &size, PAGE_READWRITE, SEC_COMMIT, 0);
3074 ok(!status, "got %08lx\n", status);
3075 test_object_name_with_null(handle, &name2U);
3076 status = pNtOpenSection(&handle2, GENERIC_ALL, &attr2);
3077 ok(!status, "got %08lx\n", status);
3078 test_object_name_with_null(handle2, &name2U);
3079 pNtClose(handle2);
3080 pNtClose(handle);
3081 status = pNtCreateSection(&handle, GENERIC_ALL, &attr3, &size, PAGE_READWRITE, SEC_COMMIT, 0);
3082 ok(!status, "got %08lx\n", status);
3083 test_object_name_with_null(handle, &name3U);
3084 status = pNtOpenSection(&handle2, GENERIC_ALL, &attr3);
3085 ok(!status, "got %08lx\n", status);
3086 test_object_name_with_null(handle2, &name3U);
3087 pNtClose(handle2);
3088 pNtClose(handle);
3090 wcscpy(name, L"\\Registry\\Machine\\Software\\wine_test");
3091 wcscpy(name3, L"\\Registry\\Machine\\Software\\wine_test");
3092 p = wcsrchr(name3, '\\');
3093 p[5] = 0; /* => \\wine\0test */
3095 RtlInitUnicodeString(&nameU, name);
3096 name2U = nameU;
3097 name3U = nameU;
3098 name3U.Buffer = name3;
3099 #ifdef _WIN64
3100 name_exp = name;
3101 name3_exp = name3;
3102 name2U_exp = name2U;
3103 #else
3104 if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)
3106 name_exp = (WCHAR *)L"\\Registry\\Machine\\Software\\WOW6432Node\\wine_test";
3107 name3_exp =(WCHAR *) L"\\Registry\\Machine\\Software\\WOW6432Node\\wine\0test";
3109 else
3111 name_exp = name;
3112 name3_exp = name3;
3114 RtlInitUnicodeString(&name2U_exp, name_exp);
3115 #endif
3116 name3U_exp = name2U_exp;
3117 name3U_exp.Buffer = name3_exp;
3118 name2U.Length += sizeof(WCHAR); /* add terminating \0 to string length */
3119 name2U_exp.Length += sizeof(WCHAR); /* add terminating \0 to string length */
3121 status = pNtCreateKey(&handle, GENERIC_ALL, &attr, 0, NULL, 0, NULL);
3122 ok(!status || status == STATUS_ACCESS_DENIED || broken(status == STATUS_OBJECT_PATH_NOT_FOUND) /* win8 */, "got %08lx\n", status);
3123 if (!status)
3125 test_object_name(handle, name_exp, FALSE);
3126 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr);
3127 ok(!status, "got %08lx\n", status);
3128 test_object_name(handle2, name_exp, FALSE);
3129 pNtClose(handle2);
3130 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr2);
3131 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
3132 pNtDeleteKey(handle);
3133 pNtClose(handle);
3134 status = pNtCreateKey(&handle, GENERIC_ALL, &attr2, 0, NULL, 0, NULL);
3135 ok(!status, "got %08lx\n", status);
3136 test_object_name_with_null(handle, &name2U_exp);
3137 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr2);
3138 ok(!status, "got %08lx\n", status);
3139 test_object_name_with_null(handle, &name2U_exp);
3140 pNtClose(handle2);
3141 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr);
3142 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
3143 pNtDeleteKey(handle);
3144 pNtClose(handle);
3145 status = pNtCreateKey(&handle, GENERIC_ALL, &attr3, 0, NULL, 0, NULL);
3146 ok(!status, "got %08lx\n", status);
3147 test_object_name_with_null(handle, &name3U_exp);
3148 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr3);
3149 ok(!status, "got %08lx\n", status);
3150 test_object_name_with_null(handle, &name3U_exp);
3151 pNtClose(handle2);
3152 pNtDeleteKey(handle);
3153 pNtClose(handle);
3155 else
3156 skip("Limited access to \\Registry\\Machine\\Software key, skipping the tests\n");
3159 static void test_object_permanence(void)
3161 static const struct object_permanence_test {
3162 const char *name;
3163 ULONG initial_attr;
3164 ACCESS_MASK access;
3165 BOOLEAN make_temporary;
3166 BOOLEAN make_permanent;
3167 NTSTATUS make_temp_status;
3168 } tests[] = {
3170 .name = "permanent object persists",
3171 .initial_attr = OBJ_PERMANENT,
3172 .access = GENERIC_ALL,
3175 .name = "NtMakeTemporaryObject() succeeds",
3176 .initial_attr = OBJ_PERMANENT,
3177 .access = GENERIC_ALL,
3178 .make_temporary = TRUE,
3179 .make_temp_status = STATUS_SUCCESS,
3182 .name = "NtMakeTemporaryObject() fails w/o DELETE access",
3183 .initial_attr = OBJ_PERMANENT,
3184 .access = EVENT_ALL_ACCESS & ~DELETE,
3185 .make_temporary = TRUE,
3186 .make_temp_status = STATUS_ACCESS_DENIED,
3189 .name = "NtMakePermanentObject() succeeds even if already permanent",
3190 .initial_attr = OBJ_PERMANENT,
3191 .access = EVENT_ALL_ACCESS & ~DELETE,
3192 .make_permanent = TRUE,
3195 .name = "NtMakePermanentObject() reverses effect of NtMakeTemporaryObject()",
3196 .initial_attr = OBJ_PERMANENT,
3197 .access = GENERIC_ALL,
3198 .make_temporary = TRUE,
3199 .make_temp_status = STATUS_SUCCESS,
3200 .make_permanent = TRUE,
3204 .name = "temporary object disappears",
3205 .initial_attr = 0,
3206 .access = GENERIC_ALL,
3209 .name = "NtMakeTemporaryObject() succeeds even if already temporary",
3210 .initial_attr = 0,
3211 .access = GENERIC_ALL,
3212 .make_temporary = TRUE,
3213 .make_temp_status = STATUS_SUCCESS,
3216 .name = "NtMakeTemporaryObject() fails w/o DELETE access even if already temporary",
3217 .initial_attr = 0,
3218 .access = EVENT_ALL_ACCESS & ~DELETE,
3219 .make_temporary = TRUE,
3220 .make_temp_status = STATUS_ACCESS_DENIED,
3223 .name = "NtMakePermanentObject() makes an object persist",
3224 .initial_attr = 0,
3225 .access = EVENT_ALL_ACCESS & ~DELETE,
3226 .make_permanent = TRUE,
3229 .name = "NtMakePermanentObject() is not annulled by calling NtMakeTemporaryObject() on an already temporary object",
3230 .initial_attr = 0,
3231 .access = GENERIC_ALL,
3232 .make_temporary = TRUE,
3233 .make_temp_status = STATUS_SUCCESS,
3234 .make_permanent = TRUE,
3237 const struct object_permanence_test *test;
3238 HANDLE process_token = NULL, thread_token = NULL;
3239 SECURITY_QUALITY_OF_SERVICE token_qos = {
3240 .Length = sizeof(token_qos),
3241 .ImpersonationLevel = SecurityDelegation,
3242 .ContextTrackingMode = SECURITY_STATIC_TRACKING,
3243 .EffectiveOnly = FALSE,
3245 OBJECT_ATTRIBUTES token_attr = {
3246 .Length = sizeof(token_attr),
3247 .SecurityQualityOfService = &token_qos,
3249 TOKEN_PRIVILEGES new_privs = {
3250 .PrivilegeCount = 1,
3251 .Privileges = {
3253 .Luid = { .LowPart = SE_CREATE_PERMANENT_PRIVILEGE },
3254 .Attributes = SE_PRIVILEGE_ENABLED,
3258 NTSTATUS status;
3259 BOOL creatpermapriv = FALSE;
3261 status = NtOpenProcessToken( GetCurrentProcess(), TOKEN_DUPLICATE, &process_token );
3262 ok( status == STATUS_SUCCESS, "NtOpenProcessToken returned %08lx\n", status );
3264 status = NtDuplicateToken( process_token, TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES,
3265 &token_attr, FALSE, TokenImpersonation, &thread_token );
3266 ok( status == STATUS_SUCCESS, "NtDuplicateToken returned %08lx\n", status );
3267 NtClose( process_token );
3269 status = NtAdjustPrivilegesToken( thread_token, FALSE, &new_privs, sizeof(new_privs), NULL, NULL );
3270 ok( status == STATUS_SUCCESS || status == STATUS_NOT_ALL_ASSIGNED, "NtAdjustPrivilegesToken returned %08lx\n", status );
3271 creatpermapriv = (status == STATUS_SUCCESS);
3273 status = NtSetInformationThread( GetCurrentThread(), ThreadImpersonationToken, &thread_token, sizeof(thread_token) );
3274 ok( status == STATUS_SUCCESS, "NtSetInformationThread returned %08lx\n", status );
3275 NtClose( thread_token );
3277 if (!creatpermapriv) skip( "no privileges, tests may be limited\n" );
3279 for (test = &tests[0]; test != &tests[ARRAY_SIZE(tests)]; test++)
3281 NTSTATUS make_perma_status = creatpermapriv ? STATUS_SUCCESS : STATUS_PRIVILEGE_NOT_HELD;
3282 HANDLE handle, handle2;
3283 OBJECT_BASIC_INFORMATION obi;
3284 OBJECT_ATTRIBUTES attr;
3285 UNICODE_STRING name;
3286 BOOL is_permanent;
3287 ULONG len = 0;
3289 winetest_push_context( "test#%Iu", test - &tests[0] );
3290 trace( "(%s)\n", test->name );
3292 RtlInitUnicodeString( &name, L"\\BaseNamedObjects\\test_object_permanence" );
3293 InitializeObjectAttributes( &attr, &name, test->initial_attr, 0, NULL );
3294 status = NtCreateEvent( &handle, test->access, &attr, NotificationEvent, FALSE );
3295 if (test->initial_attr & OBJ_PERMANENT)
3297 todo_wine_if(status == STATUS_SUCCESS || status == STATUS_PRIVILEGE_NOT_HELD)
3298 ok( status == make_perma_status, "NtCreateEvent returned %08lx (expected %08lx)\n", status, make_perma_status );
3300 else
3302 ok( status == STATUS_SUCCESS, "NtCreateEvent returned %08lx\n", status );
3304 if (NT_ERROR(status))
3306 winetest_pop_context();
3307 continue;
3309 is_permanent = (test->initial_attr & OBJ_PERMANENT) != 0;
3311 status = NtQueryObject( handle, ObjectBasicInformation, &obi, sizeof(obi), &len );
3312 ok( status == STATUS_SUCCESS, "NtQueryObject returned %08lx\n", status );
3313 todo_wine_if(test->initial_attr != 0)
3314 ok( obi.Attributes == test->initial_attr, "expected attr %08lx, got %08lx\n", test->initial_attr, obi.Attributes );
3316 if (test->make_temporary)
3318 if (test->make_temp_status == STATUS_ACCESS_DENIED)
3319 ok( !(obi.GrantedAccess & DELETE), "expected no DELETE access in %08lx\n", obi.GrantedAccess );
3320 if (test->make_temp_status == STATUS_SUCCESS)
3321 ok( !!(obi.GrantedAccess & DELETE), "expected DELETE access in %08lx\n", obi.GrantedAccess );
3323 status = NtMakeTemporaryObject( handle );
3324 ok( status == test->make_temp_status, "NtMakeTemporaryObject returned %08lx\n", status );
3325 if (!NT_ERROR(status)) is_permanent = FALSE;
3328 if (winetest_debug > 1)
3329 trace( "NOTE: object still has unclosed handle (%p) and shouldn't be deleted", handle );
3331 winetest_push_context( "first handle (%p) still open", handle );
3332 status = NtOpenEvent( &handle2, GENERIC_ALL, &attr );
3333 ok( status == STATUS_SUCCESS, "NtOpenEvent returned %08lx\n", status );
3334 if (!NT_ERROR(status))
3336 ULONG expect_attr = (obi.Attributes & ~OBJ_PERMANENT) | (is_permanent ? OBJ_PERMANENT : 0);
3337 OBJECT_BASIC_INFORMATION obi2;
3339 status = NtQueryObject( handle2, ObjectBasicInformation, &obi2, sizeof(obi2), &len );
3340 ok( status == STATUS_SUCCESS, "NtQueryObject returned %08lx\n", status );
3341 todo_wine_if(expect_attr != 0)
3342 ok( obi2.Attributes == expect_attr, "expected attr %08lx, got %08lx\n", expect_attr, obi2.Attributes );
3344 NtClose( handle2 );
3346 winetest_pop_context();
3348 if (test->make_permanent)
3350 status = NtMakePermanentObject( handle );
3351 todo_wine_if(status == STATUS_SUCCESS || status == STATUS_PRIVILEGE_NOT_HELD)
3352 ok( status == make_perma_status, "NtMakePermanentObject returned %08lx expected (%08lx)\n", status, make_perma_status );
3353 if (!NT_ERROR(status)) is_permanent = TRUE;
3356 if (winetest_debug > 1)
3357 trace( "NOTE: about to close earlier handle (%p) which should be the last", handle );
3358 NtClose( handle );
3360 winetest_push_context( "first handle closed" );
3361 status = NtOpenEvent( &handle, GENERIC_ALL, &attr );
3362 ok( status == (is_permanent ? STATUS_SUCCESS : STATUS_OBJECT_NAME_NOT_FOUND), "NtOpenEvent returned %08lx\n", status );
3363 if (!NT_ERROR(status))
3365 ULONG expect_attr = (obi.Attributes & ~OBJ_PERMANENT) | (is_permanent ? OBJ_PERMANENT : 0);
3366 OBJECT_BASIC_INFORMATION obi_new;
3368 status = NtQueryObject( handle, ObjectBasicInformation, &obi_new, sizeof(obi_new), &len );
3369 ok( status == STATUS_SUCCESS, "NtQueryObject returned %08lx\n", status );
3370 todo_wine_if(expect_attr != 0)
3371 ok( obi_new.Attributes == expect_attr, "expected attr %08lx, got %08lx\n", expect_attr, obi_new.Attributes );
3373 /* ensure object is deleted */
3374 NtMakeTemporaryObject( handle );
3375 NtClose( handle );
3377 winetest_pop_context();
3379 winetest_pop_context();
3382 thread_token = NULL;
3383 status = NtSetInformationThread( GetCurrentThread(), ThreadImpersonationToken, &thread_token, sizeof(thread_token) );
3384 ok( status == STATUS_SUCCESS, "NtSetInformationThread returned %08lx\n", status );
3387 START_TEST(om)
3389 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
3391 pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent");
3392 pNtCreateJobObject = (void *)GetProcAddress(hntdll, "NtCreateJobObject");
3393 pNtOpenJobObject = (void *)GetProcAddress(hntdll, "NtOpenJobObject");
3394 pNtCreateKey = (void *)GetProcAddress(hntdll, "NtCreateKey");
3395 pNtOpenKey = (void *)GetProcAddress(hntdll, "NtOpenKey");
3396 pNtDeleteKey = (void *)GetProcAddress(hntdll, "NtDeleteKey");
3397 pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile");
3398 pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant");
3399 pNtOpenEvent = (void *)GetProcAddress(hntdll, "NtOpenEvent");
3400 pNtOpenMutant = (void *)GetProcAddress(hntdll, "NtOpenMutant");
3401 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
3402 pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
3403 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
3404 pNtCreateNamedPipeFile = (void *)GetProcAddress(hntdll, "NtCreateNamedPipeFile");
3405 pNtOpenDirectoryObject = (void *)GetProcAddress(hntdll, "NtOpenDirectoryObject");
3406 pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject");
3407 pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject");
3408 pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject");
3409 pNtQuerySymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject");
3410 pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
3411 pNtOpenSemaphore = (void *)GetProcAddress(hntdll, "NtOpenSemaphore");
3412 pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer");
3413 pNtOpenTimer = (void *)GetProcAddress(hntdll, "NtOpenTimer");
3414 pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection");
3415 pNtOpenSection = (void *)GetProcAddress(hntdll, "NtOpenSection");
3416 pNtQueryObject = (void *)GetProcAddress(hntdll, "NtQueryObject");
3417 pNtReleaseSemaphore = (void *)GetProcAddress(hntdll, "NtReleaseSemaphore");
3418 pNtCreateKeyedEvent = (void *)GetProcAddress(hntdll, "NtCreateKeyedEvent");
3419 pNtOpenKeyedEvent = (void *)GetProcAddress(hntdll, "NtOpenKeyedEvent");
3420 pNtCreateIoCompletion = (void *)GetProcAddress(hntdll, "NtCreateIoCompletion");
3421 pNtOpenIoCompletion = (void *)GetProcAddress(hntdll, "NtOpenIoCompletion");
3422 pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile");
3423 pNtOpenProcess = (void *)GetProcAddress(hntdll, "NtOpenProcess");
3424 pNtCreateDebugObject = (void *)GetProcAddress(hntdll, "NtCreateDebugObject");
3425 pNtGetNextThread = (void *)GetProcAddress(hntdll, "NtGetNextThread");
3426 pNtOpenProcessToken = (void *)GetProcAddress(hntdll, "NtOpenProcessToken");
3427 pNtOpenThreadToken = (void *)GetProcAddress(hntdll, "NtOpenThreadToken");
3428 pNtDuplicateToken = (void *)GetProcAddress(hntdll, "NtDuplicateToken");
3429 pNtDuplicateObject = (void *)GetProcAddress(hntdll, "NtDuplicateObject");
3430 pNtCompareObjects = (void *)GetProcAddress(hntdll, "NtCompareObjects");
3432 test_null_in_object_name();
3433 test_case_sensitive();
3434 test_namespace_pipe();
3435 test_name_collisions();
3436 test_name_limits();
3437 test_directory();
3438 test_symboliclink();
3439 test_query_object();
3440 test_type_mismatch();
3441 test_null_device();
3442 test_process();
3443 test_token();
3444 test_duplicate_object();
3445 test_object_types();
3446 test_get_next_thread();
3447 test_globalroot();
3448 test_object_identity();
3449 test_query_directory();
3450 test_object_permanence();