include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / ntdll / tests / om.c
blobfb45fe777b712f01f7b42aad96f0602fcc6b56c7
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 <stdarg.h>
23 #include <stdio.h>
24 #include <stdlib.h>
26 #include "ntstatus.h"
27 #define WIN32_NO_STATUS
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winternl.h"
31 #include "winuser.h"
32 #include "ddk/wdm.h"
33 #include "wine/test.h"
35 static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
36 static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, EVENT_TYPE, BOOLEAN);
37 static NTSTATUS (WINAPI *pNtOpenEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES);
38 static NTSTATUS (WINAPI *pNtCreateJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
39 static NTSTATUS (WINAPI *pNtOpenJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
40 static NTSTATUS (WINAPI *pNtCreateKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG,
41 const UNICODE_STRING *, ULONG, PULONG );
42 static NTSTATUS (WINAPI *pNtOpenKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
43 static NTSTATUS (WINAPI *pNtDeleteKey)( HANDLE );
44 static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
45 ULONG, ULONG, ULONG, PLARGE_INTEGER );
46 static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN );
47 static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
48 static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG );
49 static NTSTATUS (WINAPI *pNtOpenSemaphore)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
50 static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE );
51 static NTSTATUS (WINAPI *pNtOpenTimer)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
52 static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER,
53 ULONG, ULONG, HANDLE );
54 static NTSTATUS (WINAPI *pNtOpenSection)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
55 static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG );
56 static NTSTATUS (WINAPI *pNtClose) ( HANDLE );
57 static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
58 ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, PLARGE_INTEGER );
59 static NTSTATUS (WINAPI *pNtOpenDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
60 static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
61 static NTSTATUS (WINAPI *pNtOpenSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
62 static NTSTATUS (WINAPI *pNtCreateSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PUNICODE_STRING);
63 static NTSTATUS (WINAPI *pNtQuerySymbolicLinkObject)(HANDLE,PUNICODE_STRING,PULONG);
64 static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG);
65 static NTSTATUS (WINAPI *pNtReleaseSemaphore)(HANDLE, ULONG, PULONG);
66 static NTSTATUS (WINAPI *pNtCreateKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG );
67 static NTSTATUS (WINAPI *pNtOpenKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES * );
68 static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG);
69 static NTSTATUS (WINAPI *pNtOpenIoCompletion)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
70 static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, void *, ULONG, FILE_INFORMATION_CLASS);
71 static NTSTATUS (WINAPI *pNtOpenProcess)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, const CLIENT_ID * );
72 static NTSTATUS (WINAPI *pNtCreateDebugObject)( HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *, ULONG );
73 static NTSTATUS (WINAPI *pNtGetNextThread)(HANDLE process, HANDLE thread, ACCESS_MASK access, ULONG attributes,
74 ULONG flags, HANDLE *handle);
75 static NTSTATUS (WINAPI *pNtOpenProcessToken)(HANDLE,DWORD,HANDLE*);
76 static NTSTATUS (WINAPI *pNtOpenThreadToken)(HANDLE,DWORD,BOOLEAN,HANDLE*);
77 static NTSTATUS (WINAPI *pNtDuplicateToken)(HANDLE,ACCESS_MASK,OBJECT_ATTRIBUTES*,BOOLEAN,TOKEN_TYPE,HANDLE*);
78 static NTSTATUS (WINAPI *pNtDuplicateObject)(HANDLE,HANDLE,HANDLE,HANDLE*,ACCESS_MASK,ULONG,ULONG);
79 static NTSTATUS (WINAPI *pNtCompareObjects)(HANDLE,HANDLE);
81 #define KEYEDEVENT_WAIT 0x0001
82 #define KEYEDEVENT_WAKE 0x0002
83 #define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x0003)
84 #define DESKTOP_ALL_ACCESS 0x01ff
86 #define check_unicode_string(a, b) check_unicode_string_(__LINE__, a, b)
87 static void check_unicode_string_( int line, const UNICODE_STRING *string, const WCHAR *expect )
89 size_t len = wcslen( expect ) * sizeof(WCHAR);
91 ok_(__FILE__, line)( !wcscmp( string->Buffer, expect ), "got string %s\n", debugstr_w( string->Buffer ));
92 ok_(__FILE__, line)( string->Length == len, "got length %u\n", string->Length );
93 ok_(__FILE__, line)( string->MaximumLength == len + sizeof(WCHAR), "got max length %u\n", string->MaximumLength );
96 static void test_case_sensitive (void)
98 NTSTATUS status;
99 OBJECT_ATTRIBUTES attr;
100 UNICODE_STRING str;
101 HANDLE Event, Mutant, h;
103 pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\test");
104 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
105 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
106 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08lx)\n", status);
108 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, NotificationEvent, FALSE);
109 ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH /* Vista+ */, "got %#lx\n", status);
111 pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\Test");
112 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
113 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, NotificationEvent, FALSE);
114 ok(status == STATUS_SUCCESS, "Failed to create Event(%08lx)\n", status);
116 pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\TEst");
117 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
118 status = pNtOpenMutant(&h, GENERIC_ALL, &attr);
119 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
120 "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
122 pNtClose(Mutant);
124 pRtlInitUnicodeString(&str, L"\\BASENamedObjects\\test");
125 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
126 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
127 ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH /* Vista+ */, "got %#lx\n", status);
129 status = pNtCreateEvent(&h, GENERIC_ALL, &attr, NotificationEvent, FALSE);
130 ok(status == STATUS_OBJECT_NAME_COLLISION,
131 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08lx)\n", status);
133 attr.Attributes = 0;
134 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
135 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
136 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status);
138 pNtClose(Event);
141 static void test_namespace_pipe(void)
143 OBJECT_ATTRIBUTES attr;
144 UNICODE_STRING str;
145 IO_STATUS_BLOCK iosb;
146 NTSTATUS status;
147 LARGE_INTEGER timeout;
148 HANDLE pipe, h;
150 timeout.QuadPart = -10000;
152 pRtlInitUnicodeString(&str, L"\\??\\PIPE\\test\\pipe");
153 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
154 status = pNtCreateNamedPipeFile((HANDLE *)0xdeadbee0, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
155 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
156 ok(status == STATUS_ACCESS_VIOLATION, "Failed to create NamedPipe(%08lx)\n", status);
158 status = pNtCreateNamedPipeFile(&pipe, 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_SUCCESS, "Failed to create NamedPipe(%08lx)\n", status);
162 h = (HANDLE)0xdeadbeef;
163 status = pNtCreateNamedPipeFile(&h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
164 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
165 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
166 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08lx)\n", status);
167 ok( !h || broken(h == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", h );
169 pRtlInitUnicodeString(&str, L"\\??\\PIPE\\TEST\\PIPE");
170 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
171 h = (HANDLE)0xdeadbeef;
172 status = pNtCreateNamedPipeFile(&h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
173 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
174 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
175 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08lx)\n", status);
176 ok( !h || broken(h == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", h );
178 h = CreateFileA("\\\\.\\pipe\\test\\pipe", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
179 OPEN_EXISTING, 0, 0 );
180 ok(h != INVALID_HANDLE_VALUE, "Failed to open NamedPipe (%lu)\n", GetLastError());
181 pNtClose(h);
183 pRtlInitUnicodeString(&str, L"\\??\\pipe\\test\\pipe");
184 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
185 h = (HANDLE)0xdeadbeef;
186 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
187 ok(status == STATUS_OBJECT_PATH_NOT_FOUND ||
188 status == STATUS_PIPE_NOT_AVAILABLE ||
189 status == STATUS_OBJECT_NAME_INVALID || /* vista */
190 status == STATUS_OBJECT_NAME_NOT_FOUND, /* win8 */
191 "NtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status);
192 ok( !h || broken(h == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", h );
194 pRtlInitUnicodeString(&str, L"\\??\\pipe\\test");
195 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
196 h = (HANDLE)0xdeadbeef;
197 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
198 ok(status == STATUS_OBJECT_NAME_NOT_FOUND ||
199 status == STATUS_OBJECT_NAME_INVALID, /* vista */
200 "NtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08lx)\n", status);
201 ok( !h || broken(h == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", h );
203 str.Length -= 4 * 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 str.Length -= sizeof(WCHAR);
209 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
210 ok(status == STATUS_SUCCESS, "NtOpenFile should have succeeded got %08lx\n", status);
211 pNtClose( h );
213 pNtClose(pipe);
216 #define check_create_open_dir(parent, name, status) check_create_open_dir_(__LINE__, parent, name, status)
217 static void check_create_open_dir_( int line, HANDLE parent, const WCHAR *name, NTSTATUS expect )
219 OBJECT_ATTRIBUTES attr;
220 UNICODE_STRING str;
221 NTSTATUS status;
222 HANDLE h;
224 RtlInitUnicodeString( &str, name );
225 InitializeObjectAttributes( &attr, &str, 0, parent, NULL );
226 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
227 ok_(__FILE__, line)( status == expect, "NtCreateDirectoryObject(%s) got %08lx\n", debugstr_w(name), status );
228 if (!status) pNtClose( h );
230 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
231 ok_(__FILE__, line)( status == expect, "NtOpenDirectoryObject(%s) got %08lx\n", debugstr_w(name), status );
232 if (!status) pNtClose( h );
235 static BOOL is_correct_dir( HANDLE dir, const WCHAR *name )
237 NTSTATUS status;
238 UNICODE_STRING str;
239 OBJECT_ATTRIBUTES attr;
240 HANDLE h = 0;
242 RtlInitUnicodeString( &str, name );
243 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
244 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
245 if (h) pNtClose( h );
246 return (status == STATUS_OBJECT_NAME_EXISTS);
249 /* return a handle to the BaseNamedObjects dir where kernel32 objects get created */
250 static HANDLE get_base_dir(void)
252 static const WCHAR objname[] = L"om.c_get_base_dir_obj";
253 NTSTATUS status;
254 UNICODE_STRING str;
255 OBJECT_ATTRIBUTES attr;
256 HANDLE dir, h;
257 WCHAR name[40];
259 h = CreateMutexW( NULL, FALSE, objname );
260 ok(h != 0, "CreateMutexA failed got ret=%p (%ld)\n", h, GetLastError());
261 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
263 swprintf( name, ARRAY_SIZE(name), L"\\BaseNamedObjects\\Session\\%u", NtCurrentTeb()->Peb->SessionId );
264 RtlInitUnicodeString( &str, name );
265 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
266 ok(!status, "got %#lx\n", status);
267 ok(is_correct_dir( dir, objname ), "wrong dir\n");
269 pNtClose( h );
270 return dir;
273 static void test_name_collisions(void)
275 NTSTATUS status;
276 UNICODE_STRING str;
277 OBJECT_ATTRIBUTES attr;
278 HANDLE dir, h, h1, h2;
279 DWORD winerr;
280 LARGE_INTEGER size, timeout;
281 IO_STATUS_BLOCK iosb;
283 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
284 RtlInitUnicodeString(&str, L"\\");
285 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
286 ok( status == STATUS_OBJECT_NAME_COLLISION, "NtCreateDirectoryObject got %08lx\n", status );
287 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
289 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
290 ok( status == STATUS_OBJECT_NAME_EXISTS, "NtCreateDirectoryObject got %08lx\n", status );
291 pNtClose(h);
292 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
293 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
294 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
296 RtlInitUnicodeString(&str, L"\\??\\PIPE\\om.c-mutant");
297 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
298 todo_wine ok(status == STATUS_OBJECT_PATH_NOT_FOUND, "got %#lx\n", status);
300 dir = get_base_dir();
301 RtlInitUnicodeString(&str, L"om.c-test");
302 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
303 h = CreateMutexA(NULL, FALSE, "om.c-test");
304 ok(h != 0, "CreateMutexA failed got ret=%p (%ld)\n", h, GetLastError());
305 status = pNtCreateMutant(&h1, GENERIC_ALL, &attr, FALSE);
306 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
307 "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status);
308 h2 = CreateMutexA(NULL, FALSE, "om.c-test");
309 winerr = GetLastError();
310 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
311 "CreateMutexA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr);
312 pNtClose(h);
313 pNtClose(h1);
314 pNtClose(h2);
316 h = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
317 ok(h != 0, "CreateEventA failed got ret=%p (%ld)\n", h, GetLastError());
318 status = pNtCreateEvent(&h1, GENERIC_ALL, &attr, NotificationEvent, FALSE);
319 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
320 "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status);
321 h2 = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
322 winerr = GetLastError();
323 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
324 "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr);
325 pNtClose(h);
326 pNtClose(h1);
327 pNtClose(h2);
329 h = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
330 ok(h != 0, "CreateSemaphoreA failed got ret=%p (%ld)\n", h, GetLastError());
331 status = pNtCreateSemaphore(&h1, GENERIC_ALL, &attr, 1, 2);
332 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
333 "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status);
334 h2 = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
335 winerr = GetLastError();
336 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
337 "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr);
338 pNtClose(h);
339 pNtClose(h1);
340 pNtClose(h2);
342 h = CreateWaitableTimerA(NULL, TRUE, "om.c-test");
343 ok(h != 0, "CreateWaitableTimerA failed got ret=%p (%ld)\n", h, GetLastError());
344 status = pNtCreateTimer(&h1, GENERIC_ALL, &attr, NotificationTimer);
345 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
346 "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status);
347 h2 = CreateWaitableTimerA(NULL, TRUE, "om.c-test");
348 winerr = GetLastError();
349 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
350 "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr);
351 pNtClose(h);
352 pNtClose(h1);
353 pNtClose(h2);
355 h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
356 ok(h != 0, "CreateFileMappingA failed got ret=%p (%ld)\n", h, GetLastError());
357 size.u.LowPart = 256;
358 size.u.HighPart = 0;
359 status = pNtCreateSection(&h1, SECTION_MAP_WRITE, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
360 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
361 "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status);
362 h2 = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
363 winerr = GetLastError();
364 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
365 "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr);
366 pNtClose(h);
367 pNtClose(h1);
368 pNtClose(h2);
370 pNtClose(dir);
372 RtlInitUnicodeString(&str, L"\\??\\PIPE\\named_pipe");
373 attr.RootDirectory = 0;
374 timeout.QuadPart = -10000;
375 status = pNtCreateNamedPipeFile( &h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
376 FILE_SHARE_READ|FILE_SHARE_WRITE,
377 FILE_OPEN, FILE_PIPE_FULL_DUPLEX,
378 FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
379 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "failed to create pipe %08lx\n", status);
381 memset( &iosb, 0xcc, sizeof(iosb) );
382 status = pNtCreateNamedPipeFile( &h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
383 FILE_SHARE_READ|FILE_SHARE_WRITE,
384 FILE_OPEN_IF, FILE_PIPE_FULL_DUPLEX,
385 FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
386 ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
387 ok( iosb.Status == STATUS_SUCCESS, "wrong status %08lx\n", status);
388 ok( iosb.Information == FILE_CREATED, "wrong info %Ix\n", iosb.Information );
389 pNtClose( h );
391 memset( &iosb, 0xcc, sizeof(iosb) );
392 status = pNtCreateNamedPipeFile( &h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
393 FILE_SHARE_READ|FILE_SHARE_WRITE,
394 FILE_CREATE, FILE_PIPE_FULL_DUPLEX,
395 FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
396 ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
397 ok( iosb.Status == STATUS_SUCCESS, "wrong status %08lx\n", status);
398 ok( iosb.Information == FILE_CREATED, "wrong info %Ix\n", iosb.Information );
400 memset( &iosb, 0xcc, sizeof(iosb) );
401 status = pNtCreateNamedPipeFile( &h1, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
402 FILE_SHARE_READ|FILE_SHARE_WRITE,
403 FILE_OPEN, FILE_PIPE_FULL_DUPLEX,
404 FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
405 ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
406 ok( iosb.Status == STATUS_SUCCESS, "wrong status %08lx\n", status);
407 ok( iosb.Information == FILE_OPENED, "wrong info %Ix\n", iosb.Information );
408 pNtClose(h1);
410 memset( &iosb, 0xcc, sizeof(iosb) );
411 status = pNtCreateNamedPipeFile( &h1, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
412 FILE_SHARE_READ|FILE_SHARE_WRITE,
413 FILE_OPEN_IF, FILE_PIPE_FULL_DUPLEX,
414 FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
415 ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
416 ok( iosb.Status == STATUS_SUCCESS, "wrong status %08lx\n", status);
417 ok( iosb.Information == FILE_OPENED, "wrong info %Ix\n", iosb.Information );
418 pNtClose(h1);
420 memset( &iosb, 0xcc, sizeof(iosb) );
421 status = pNtCreateNamedPipeFile( &h1, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
422 FILE_SHARE_READ|FILE_SHARE_WRITE,
423 FILE_OPEN_IF, FILE_PIPE_FULL_DUPLEX,
424 FALSE, FALSE, FALSE, 10, 256, 256, NULL );
425 ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
426 ok( iosb.Status == STATUS_SUCCESS, "wrong status %08lx\n", status);
427 ok( iosb.Information == FILE_OPENED, "wrong info %Ix\n", iosb.Information );
428 pNtClose(h1);
430 h1 = CreateNamedPipeA( "\\\\.\\pipe\\named_pipe", PIPE_ACCESS_DUPLEX,
431 PIPE_READMODE_BYTE, 10, 256, 256, 1000, NULL );
432 winerr = GetLastError();
433 ok(h1 != 0 && winerr == ERROR_ALREADY_EXISTS, "CreateNamedPipeA got ret=%p (%ld)\n", h1, winerr);
434 pNtClose(h1);
435 pNtClose(h);
438 static void test_all_kernel_objects( UINT line, OBJECT_ATTRIBUTES *attr,
439 NTSTATUS create_expect, NTSTATUS open_expect )
441 UNICODE_STRING target;
442 LARGE_INTEGER size;
443 NTSTATUS status, status2;
444 HANDLE ret, ret2;
446 RtlInitUnicodeString( &target, L"\\DosDevices" );
447 size.QuadPart = 4096;
449 ret = ret2 = (HANDLE)0xdeadbeef;
450 status = pNtCreateMutant( &ret, GENERIC_ALL, attr, FALSE );
451 ok( status == create_expect, "%u: NtCreateMutant failed %lx\n", line, status );
452 status2 = pNtOpenMutant( &ret2, GENERIC_ALL, attr );
453 ok( status2 == open_expect, "%u: NtOpenMutant failed %lx\n", line, status2 );
454 if (!status) pNtClose( ret );
455 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
456 "%u: NtCreateMutant handle %p\n", line, ret );
457 if (!status2) pNtClose( ret2 );
458 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
459 "%u: NtOpenMutant handle %p\n", line, ret );
461 ret = ret2 = (HANDLE)0xdeadbeef;
462 status = pNtCreateSemaphore( &ret, GENERIC_ALL, attr, 1, 2 );
463 ok( status == create_expect, "%u: NtCreateSemaphore failed %lx\n", line, status );
464 status2 = pNtOpenSemaphore( &ret2, GENERIC_ALL, attr );
465 ok( status2 == open_expect, "%u: NtOpenSemaphore failed %lx\n", line, status2 );
466 if (!status) pNtClose( ret );
467 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
468 "%u: NtCreateSemaphore handle %p\n", line, ret );
469 if (!status2) pNtClose( ret2 );
470 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
471 "%u: NtOpenSemaphore handle %p\n", line, ret );
472 ret = (HANDLE)0xdeadbeef;
473 status = pNtCreateSemaphore( &ret, GENERIC_ALL, attr, 2, 1 );
474 ok( status == STATUS_INVALID_PARAMETER ||
475 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
476 "%u: NtCreateSemaphore failed %lx\n", line, status );
477 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
478 "%u: NtCreateSemaphore handle %p\n", line, ret );
480 ret = ret2 = (HANDLE)0xdeadbeef;
481 status = pNtCreateEvent( &ret, GENERIC_ALL, attr, SynchronizationEvent, 0 );
482 ok( status == create_expect, "%u: NtCreateEvent failed %lx\n", line, status );
483 status2 = pNtOpenEvent( &ret2, GENERIC_ALL, attr );
484 ok( status2 == open_expect, "%u: NtOpenEvent failed %lx\n", line, status2 );
485 if (!status) pNtClose( ret );
486 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
487 "%u: NtCreateEvent handle %p\n", line, ret );
488 if (!status2) pNtClose( ret2 );
489 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
490 "%u: NtOpenEvent handle %p\n", line, ret );
491 ret = (HANDLE)0xdeadbeef;
492 status = pNtCreateEvent( &ret, GENERIC_ALL, attr, 2, 0 );
493 ok( status == STATUS_INVALID_PARAMETER ||
494 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
495 "%u: NtCreateEvent failed %lx\n", line, status );
496 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
497 "%u: NtCreateEvent handle %p\n", line, ret );
499 ret = ret2 = (HANDLE)0xdeadbeef;
500 status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, attr, 0 );
501 ok( status == create_expect, "%u: NtCreateKeyedEvent failed %lx\n", line, status );
502 status2 = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, attr );
503 ok( status2 == open_expect, "%u: NtOpenKeyedEvent failed %lx\n", line, status2 );
504 if (!status) pNtClose( ret );
505 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
506 "%u: NtCreateKeyedEvent handle %p\n", line, ret );
507 if (!status2) pNtClose( ret2 );
508 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
509 "%u: NtOpenKeyedEvent handle %p\n", line, ret );
511 ret = ret2 = (HANDLE)0xdeadbeef;
512 status = pNtCreateTimer( &ret, GENERIC_ALL, attr, NotificationTimer );
513 ok( status == create_expect, "%u: NtCreateTimer failed %lx\n", line, status );
514 status2 = pNtOpenTimer( &ret2, GENERIC_ALL, attr );
515 ok( status2 == open_expect, "%u: NtOpenTimer failed %lx\n", line, status2 );
516 if (!status) pNtClose( ret );
517 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
518 "%u: NtCreateTimer handle %p\n", line, ret );
519 if (!status2) pNtClose( ret2 );
520 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
521 "%u: NtOpenTimer handle %p\n", line, ret );
522 ret = (HANDLE)0xdeadbeef;
523 status = pNtCreateTimer( &ret, GENERIC_ALL, attr, 2 );
524 ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PARAMETER_4 ||
525 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
526 "%u: NtCreateTimer failed %lx\n", line, status );
527 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
528 "%u: NtCreateTimer handle %p\n", line, ret );
530 ret = ret2 = (HANDLE)0xdeadbeef;
531 status = pNtCreateIoCompletion( &ret, GENERIC_ALL, attr, 0 );
532 ok( status == create_expect, "%u: NtCreateIoCompletion failed %lx\n", line, status );
533 status2 = pNtOpenIoCompletion( &ret2, GENERIC_ALL, attr );
534 ok( status2 == open_expect, "%u: NtOpenIoCompletion failed %lx\n", line, status2 );
535 if (!status) pNtClose( ret );
536 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
537 "%u: NtCreateIoCompletion handle %p\n", line, ret );
538 if (!status2) pNtClose( ret2 );
539 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
540 "%u: NtOpenIoCompletion handle %p\n", line, ret );
542 ret = ret2 = (HANDLE)0xdeadbeef;
543 status = pNtCreateJobObject( &ret, GENERIC_ALL, attr );
544 ok( status == create_expect, "%u: NtCreateJobObject failed %lx\n", line, status );
545 status2 = pNtOpenJobObject( &ret2, GENERIC_ALL, attr );
546 ok( status2 == open_expect, "%u: NtOpenJobObject failed %lx\n", line, status2 );
547 if (!status) pNtClose( ret );
548 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
549 "%u: NtCreateJobObject handle %p\n", line, ret );
550 if (!status2) pNtClose( ret2 );
551 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
552 "%u: NtOpenJobObject handle %p\n", line, ret );
554 ret = ret2 = (HANDLE)0xdeadbeef;
555 status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, attr );
556 ok( status == create_expect, "%u: NtCreateDirectoryObject failed %lx\n", line, status );
557 status2 = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, attr );
558 ok( status2 == open_expect, "%u: NtOpenDirectoryObject failed %lx\n", line, status2 );
559 if (!status) pNtClose( ret );
560 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
561 "%u: NtCreateDirectoryObject handle %p\n", line, ret );
562 if (!status2) pNtClose( ret2 );
563 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
564 "%u: NtOpenDirectoryObject handle %p\n", line, ret );
566 ret = ret2 = (HANDLE)0xdeadbeef;
567 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, attr, &target );
568 ok( status == create_expect, "%u: NtCreateSymbolicLinkObject failed %lx\n", line, status );
569 status2 = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, attr );
570 ok( status2 == open_expect, "%u: NtOpenSymbolicLinkObject failed %lx\n", line, status2 );
571 if (!status) pNtClose( ret );
572 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
573 "%u: NtCreateSymbolicLinkObject handle %p\n", line, ret );
574 if (!status2) pNtClose( ret2 );
575 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
576 "%u: NtOpenSymbolicLinkObject handle %p\n", line, ret );
577 ret = (HANDLE)0xdeadbeef;
578 target.MaximumLength = 0;
579 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, attr, &target );
580 ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PARAMETER_4 ||
581 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
582 "%u: NtCreateSymbolicLinkObject failed %lx\n", line, status );
583 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
584 "%u: NtCreateSymbolicLinkObject handle %p\n", line, ret );
586 ret = ret2 = (HANDLE)0xdeadbeef;
587 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, attr, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
588 ok( status == create_expect, "%u: NtCreateSection failed %lx\n", line, status );
589 status2 = pNtOpenSection( &ret2, SECTION_MAP_WRITE, attr );
590 ok( status2 == open_expect, "%u: NtOpenSection failed %lx\n", line, status2 );
591 if (!status) pNtClose( ret );
592 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
593 "%u: NtCreateSection handle %p\n", line, ret );
594 if (!status2) pNtClose( ret2 );
595 else ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
596 "%u: NtOpenSection handle %p\n", line, ret );
597 ret = (HANDLE)0xdeadbeef;
598 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, attr, &size, 0x1234, SEC_COMMIT, 0 );
599 ok( status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PAGE_PROTECTION ||
600 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
601 "%u: NtCreateSection failed %lx\n", line, status );
602 ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
603 "%u: NtCreateSection handle %p\n", line, ret );
605 ret = ret2 = (HANDLE)0xdeadbeef;
606 status = pNtCreateDebugObject( &ret, DEBUG_ALL_ACCESS, attr, 0 );
607 ok( status == create_expect, "%u: NtCreateDebugObject failed %lx\n", line, status );
608 if (!status) pNtClose( ret );
609 else ok( !ret || broken( ret == (HANDLE)0xdeadbeef ) /* vista */,
610 "%u: NtCreateDebugObject handle %p\n", line, ret );
611 status = pNtCreateDebugObject( &ret2, DEBUG_ALL_ACCESS, attr, 0xdead );
612 ok( status == STATUS_INVALID_PARAMETER ||
613 (status == STATUS_ACCESS_VIOLATION && create_expect == STATUS_ACCESS_VIOLATION),
614 "%u: NtCreateDebugObject failed %lx\n", line, status );
615 ok( !ret2 || broken( ret2 == (HANDLE)0xdeadbeef ) /* vista */,
616 "%u: NtCreateDebugObject handle %p\n", line, ret );
619 static void test_name_limits(void)
621 static const WCHAR pipeW[] = L"\\Device\\NamedPipe\\";
622 static const WCHAR mailslotW[] = L"\\Device\\MailSlot\\";
623 static const WCHAR registryW[] = L"\\REGISTRY\\Machine\\SOFTWARE\\Microsoft\\";
624 OBJECT_ATTRIBUTES attr, attr2, attr3;
625 IO_STATUS_BLOCK iosb;
626 LARGE_INTEGER size, timeout;
627 UNICODE_STRING str, str2, target;
628 NTSTATUS status;
629 HANDLE ret, ret2;
630 DWORD i;
632 InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
633 InitializeObjectAttributes( &attr2, &str, 0, (HANDLE)0xdeadbeef, NULL );
634 InitializeObjectAttributes( &attr3, &str, 0, 0, NULL );
635 str.Buffer = HeapAlloc( GetProcessHeap(), 0, 65536 + sizeof(registryW));
636 str.MaximumLength = 65534;
637 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i] = 'a';
638 size.QuadPart = 4096;
639 RtlInitUnicodeString( &target, L"\\DosDevices" );
641 attr.RootDirectory = get_base_dir();
642 str.Length = 0;
643 status = pNtCreateMutant( &ret, GENERIC_ALL, &attr2, FALSE );
644 ok( status == STATUS_SUCCESS, "%u: NtCreateMutant failed %lx\n", str.Length, status );
645 attr3.RootDirectory = ret;
646 status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr );
647 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenMutant failed %lx\n", str.Length, status );
648 status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr3 );
649 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
650 "%u: NtOpenMutant failed %lx\n", str.Length, status );
651 pNtClose( ret );
652 status = pNtCreateSemaphore( &ret, GENERIC_ALL, &attr2, 1, 2 );
653 ok( status == STATUS_SUCCESS, "%u: NtCreateSemaphore failed %lx\n", str.Length, status );
654 attr3.RootDirectory = ret;
655 status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr );
656 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSemaphore failed %lx\n", str.Length, status );
657 status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr3 );
658 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
659 "%u: NtOpenSemaphore failed %lx\n", str.Length, status );
660 pNtClose( ret );
661 status = pNtCreateEvent( &ret, GENERIC_ALL, &attr2, SynchronizationEvent, 0 );
662 ok( status == STATUS_SUCCESS, "%u: NtCreateEvent failed %lx\n", str.Length, status );
663 attr3.RootDirectory = ret;
664 status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr );
665 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenEvent failed %lx\n", str.Length, status );
666 status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr3 );
667 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
668 "%u: NtOpenEvent failed %lx\n", str.Length, status );
669 pNtClose( ret );
670 status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, &attr2, 0 );
671 ok( status == STATUS_SUCCESS, "%u: NtCreateKeyedEvent failed %lx\n", str.Length, status );
672 attr3.RootDirectory = ret;
673 status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr );
674 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenKeyedEvent failed %lx\n", str.Length, status );
675 status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr3 );
676 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
677 "%u: NtOpenKeyedEvent failed %lx\n", str.Length, status );
678 pNtClose( ret );
679 status = pNtCreateTimer( &ret, GENERIC_ALL, &attr2, NotificationTimer );
680 ok( status == STATUS_SUCCESS, "%u: NtCreateTimer failed %lx\n", str.Length, status );
681 attr3.RootDirectory = ret;
682 status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr );
683 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenTimer failed %lx\n", str.Length, status );
684 status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr3 );
685 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
686 "%u: NtOpenTimer failed %lx\n", str.Length, status );
687 pNtClose( ret );
688 status = pNtCreateIoCompletion( &ret, GENERIC_ALL, &attr2, 0 );
689 ok( status == STATUS_SUCCESS, "%u: NtCreateCompletion failed %lx\n", str.Length, status );
690 attr3.RootDirectory = ret;
691 status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr );
692 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenCompletion failed %lx\n", str.Length, status );
693 status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr3 );
694 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
695 "%u: NtOpenCompletion failed %lx\n", str.Length, status );
696 pNtClose( ret );
697 status = pNtCreateJobObject( &ret, GENERIC_ALL, &attr2 );
698 ok( status == STATUS_SUCCESS, "%u: NtCreateJobObject failed %lx\n", str.Length, status );
699 attr3.RootDirectory = ret;
700 status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr );
701 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenJobObject failed %lx\n", str.Length, status );
702 status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr3 );
703 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
704 "%u: NtOpenJobObject failed %lx\n", str.Length, status );
705 pNtClose( ret );
706 status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, &attr2 );
707 ok( status == STATUS_SUCCESS, "%u: NtCreateDirectoryObject failed %lx\n", str.Length, status );
708 attr3.RootDirectory = ret;
709 status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr );
710 ok( status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_DENIED), /* winxp */
711 "%u: NtOpenDirectoryObject failed %lx\n", str.Length, status );
712 if (!status) pNtClose( ret2 );
713 status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr3 );
714 ok( status == STATUS_SUCCESS, "%u: NtOpenDirectoryObject failed %lx\n", str.Length, status );
715 pNtClose( ret2 );
716 pNtClose( ret );
717 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, &attr2, &target );
718 ok( status == STATUS_SUCCESS, "%u: NtCreateSymbolicLinkObject failed %lx\n", str.Length, status );
719 attr3.RootDirectory = ret;
720 status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr );
721 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSymbolicLinkObject failed %lx\n", str.Length, status );
722 status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr3 );
723 ok( status == STATUS_SUCCESS, "%u: NtOpenSymbolicLinkObject failed %lx\n", str.Length, status );
724 pNtClose( ret2 );
725 pNtClose( ret );
726 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, &attr2, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
727 ok( status == STATUS_SUCCESS, "%u: NtCreateSection failed %lx\n", str.Length, status );
728 attr3.RootDirectory = ret;
729 status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr );
730 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSection failed %lx\n", str.Length, status );
731 status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr3 );
732 ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE /* < 7 */,
733 "%u: NtOpenSection failed %lx\n", str.Length, status );
734 pNtClose( ret );
736 str.Length = 67;
737 test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
739 str.Length = 65532;
740 test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS );
742 str.Length = 65534;
743 test_all_kernel_objects( __LINE__, &attr, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
745 str.Length = 128;
746 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
748 if (attr.Length == sizeof(attr))
749 test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS );
750 else
751 test_all_kernel_objects( __LINE__, &attr, STATUS_INVALID_PARAMETER, STATUS_INVALID_PARAMETER );
753 attr.Length = sizeof(attr);
755 /* null attributes or ObjectName, with or without RootDirectory */
756 attr3.RootDirectory = 0;
757 attr2.ObjectName = attr3.ObjectName = NULL;
758 test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID );
759 test_all_kernel_objects( __LINE__, &attr3, STATUS_SUCCESS, STATUS_OBJECT_PATH_SYNTAX_BAD );
760 attr2.ObjectName = attr3.ObjectName = (void *)0xdeadbeef;
761 test_all_kernel_objects( __LINE__, &attr2, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
762 test_all_kernel_objects( __LINE__, &attr3, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
763 attr2.ObjectName = attr3.ObjectName = &str2;
764 str2.Buffer = (WCHAR *)((char *)pipeW + 1); /* misaligned buffer */
765 str2.Length = 3;
766 test_all_kernel_objects( __LINE__, &attr2, STATUS_DATATYPE_MISALIGNMENT, STATUS_DATATYPE_MISALIGNMENT );
767 test_all_kernel_objects( __LINE__, &attr3, STATUS_DATATYPE_MISALIGNMENT, STATUS_DATATYPE_MISALIGNMENT );
768 str2.Buffer = (WCHAR *)0xdeadbee0;
769 str2.Length = 2;
770 test_all_kernel_objects( __LINE__, &attr2, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
771 test_all_kernel_objects( __LINE__, &attr3, STATUS_ACCESS_VIOLATION, STATUS_ACCESS_VIOLATION );
773 attr3.ObjectName = &str2;
774 pRtlInitUnicodeString( &str2, L"\\BaseNamedObjects\\Local" );
775 status = pNtOpenSymbolicLinkObject( &ret, SYMBOLIC_LINK_QUERY, &attr3 );
776 ok( status == STATUS_SUCCESS, "can't open BaseNamedObjects\\Local %lx\n", status );
777 attr3.ObjectName = &str;
778 attr3.RootDirectory = ret;
779 test_all_kernel_objects( __LINE__, &attr3, STATUS_OBJECT_TYPE_MISMATCH, STATUS_OBJECT_TYPE_MISMATCH );
780 pNtClose( attr3.RootDirectory );
782 status = pNtCreateMutant( &ret, GENERIC_ALL, NULL, FALSE );
783 ok( status == STATUS_SUCCESS, "NULL: NtCreateMutant failed %lx\n", status );
784 pNtClose( ret );
785 status = pNtCreateMutant( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, FALSE );
786 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateMutant failed %lx\n", status );
787 ret = (HANDLE)0xdeadbeef;
788 status = pNtOpenMutant( &ret, GENERIC_ALL, NULL );
789 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenMutant failed %lx\n", status );
790 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
791 status = pNtOpenMutant( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
792 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenMutant failed %lx\n", status );
794 status = pNtCreateSemaphore( &ret, GENERIC_ALL, NULL, 1, 2 );
795 ok( status == STATUS_SUCCESS, "NULL: NtCreateSemaphore failed %lx\n", status );
796 pNtClose( ret );
797 status = pNtCreateSemaphore( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, 1, 2 );
798 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateSemaphore failed %lx\n", status );
799 ret = (HANDLE)0xdeadbeef;
800 status = pNtOpenSemaphore( &ret, GENERIC_ALL, NULL );
801 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSemaphore failed %lx\n", status );
802 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
803 status = pNtOpenSemaphore( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
804 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenSemaphore failed %lx\n", status );
806 status = pNtCreateEvent( &ret, GENERIC_ALL, NULL, SynchronizationEvent, 0 );
807 ok( status == STATUS_SUCCESS, "NULL: NtCreateEvent failed %lx\n", status );
808 pNtClose( ret );
809 status = pNtCreateEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, SynchronizationEvent, 0 );
810 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateEvent failed %lx\n", status );
811 ret = (HANDLE)0xdeadbeef;
812 status = pNtOpenEvent( &ret, GENERIC_ALL, NULL );
813 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenEvent failed %lx\n", status );
814 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
815 status = pNtOpenEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
816 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenEvent failed %lx\n", status );
818 status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, NULL, 0 );
819 ok( status == STATUS_SUCCESS, "NULL: NtCreateKeyedEvent failed %lx\n", status );
820 pNtClose( ret );
821 status = pNtCreateKeyedEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, 0 );
822 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKeyedEvent failed %lx\n", status );
823 ret = (HANDLE)0xdeadbeef;
824 status = pNtOpenKeyedEvent( &ret, GENERIC_ALL, NULL );
825 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenKeyedEvent failed %lx\n", status );
826 ok( !ret, "handle set %p\n", ret );
827 status = pNtOpenKeyedEvent( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
828 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKeyedEvent failed %lx\n", status );
830 status = pNtCreateTimer( &ret, GENERIC_ALL, NULL, NotificationTimer );
831 ok( status == STATUS_SUCCESS, "NULL: NtCreateTimer failed %lx\n", status );
832 pNtClose( ret );
833 status = pNtCreateTimer( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, NotificationTimer );
834 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateTimer failed %lx\n", status );
835 ret = (HANDLE)0xdeadbeef;
836 status = pNtOpenTimer( &ret, GENERIC_ALL, NULL );
837 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenTimer failed %lx\n", status );
838 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
839 status = pNtOpenTimer( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
840 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenTimer failed %lx\n", status );
842 status = pNtCreateIoCompletion( &ret, GENERIC_ALL, NULL, 0 );
843 ok( status == STATUS_SUCCESS, "NULL: NtCreateCompletion failed %lx\n", status );
844 pNtClose( ret );
845 status = pNtCreateIoCompletion( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, 0 );
846 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateCompletion failed %lx\n", status );
847 ret = (HANDLE)0xdeadbeef;
848 status = pNtOpenIoCompletion( &ret, GENERIC_ALL, NULL );
849 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenCompletion failed %lx\n", status );
850 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
851 status = pNtOpenIoCompletion( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
852 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenCompletion failed %lx\n", status );
854 status = pNtCreateJobObject( &ret, GENERIC_ALL, NULL );
855 ok( status == STATUS_SUCCESS, "NULL: NtCreateJobObject failed %lx\n", status );
856 pNtClose( ret );
857 status = pNtCreateJobObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
858 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateJobObject failed %lx\n", status );
859 ret = (HANDLE)0xdeadbeef;
860 status = pNtOpenJobObject( &ret, GENERIC_ALL, NULL );
861 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenJobObject failed %lx\n", status );
862 ok( !ret || broken(ret == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", ret );
863 status = pNtOpenJobObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
864 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenJobObject failed %lx\n", status );
866 status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, NULL );
867 ok( status == STATUS_SUCCESS, "NULL: NtCreateDirectoryObject failed %lx\n", status );
868 pNtClose( ret );
869 status = pNtCreateDirectoryObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
870 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateDirectoryObject failed %lx\n", status );
871 ret = (HANDLE)0xdeadbeef;
872 status = pNtOpenDirectoryObject( &ret, GENERIC_ALL, NULL );
873 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenDirectoryObject failed %lx\n", status );
874 ok( !ret, "handle set %p\n", ret );
875 status = pNtOpenDirectoryObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
876 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenDirectoryObject failed %lx\n", status );
878 status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, NULL, &target );
879 ok( status == STATUS_ACCESS_VIOLATION || broken( status == STATUS_SUCCESS), /* winxp */
880 "NULL: NtCreateSymbolicLinkObject failed %lx\n", status );
881 if (!status) pNtClose( ret );
882 status = pNtCreateSymbolicLinkObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL, &target );
883 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateSymbolicLinkObject failed %lx\n", status );
884 ret = (HANDLE)0xdeadbeef;
885 status = pNtOpenSymbolicLinkObject( &ret, GENERIC_ALL, NULL );
886 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSymbolicLinkObject failed %lx\n", status );
887 ok( !ret, "handle set %p\n", ret );
888 status = pNtOpenSymbolicLinkObject( (HANDLE *)0xdeadbee0, GENERIC_ALL, NULL );
889 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenSymbolicLinkObject failed %lx\n", status );
891 status = pNtCreateSection( &ret, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
892 ok( status == STATUS_SUCCESS, "NULL: NtCreateSection failed %lx\n", status );
893 pNtClose( ret );
894 status = pNtCreateSection( (HANDLE *)0xdeadbee0, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
895 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateSection failed %lx\n", status );
896 ret = (HANDLE)0xdeadbeef;
897 status = pNtOpenSection( &ret, SECTION_MAP_WRITE, NULL );
898 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSection failed %lx\n", status );
899 ok( !ret, "handle set %p\n", ret );
900 status = pNtOpenSection( (HANDLE *)0xdeadbee0, SECTION_MAP_WRITE, NULL );
901 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenSection failed %lx\n", status );
902 attr2.ObjectName = attr3.ObjectName = &str;
904 /* named pipes */
905 wcscpy( str.Buffer, pipeW );
906 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + wcslen( pipeW )] = 'a';
907 str.Length = 0;
908 attr.RootDirectory = 0;
909 attr.Attributes = OBJ_CASE_INSENSITIVE;
910 timeout.QuadPart = -10000;
911 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
912 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
913 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
914 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
915 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
916 ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
917 str.Length = 67;
918 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
919 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
920 ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
921 str.Length = 128;
922 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
924 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
925 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
926 if (attr.Length == sizeof(attr))
928 ok( status == STATUS_SUCCESS, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
929 pNtClose( ret );
931 else ok( status == STATUS_INVALID_PARAMETER,
932 "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
934 attr.Length = sizeof(attr);
935 str.Length = 65532;
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_SUCCESS, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
939 pNtClose( ret );
940 str.Length = 65534;
941 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &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, "%u: NtCreateNamedPipeFile failed %lx\n", str.Length, status );
944 attr3.RootDirectory = 0;
945 attr2.ObjectName = attr3.ObjectName = NULL;
946 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
947 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
948 ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateNamedPipeFile failed %lx\n", status );
949 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr3, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
950 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
951 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateNamedPipeFile failed %lx\n", status );
952 status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, NULL, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
953 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout );
954 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateNamedPipeFile failed %lx\n", status );
955 attr2.ObjectName = attr3.ObjectName = &str;
957 /* mailslots */
958 wcscpy( str.Buffer, mailslotW );
959 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + wcslen( mailslotW )] = 'a';
960 str.Length = 0;
961 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
962 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
963 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
964 ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
965 str.Length = 67;
966 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
967 ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
968 str.Length = 128;
969 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
971 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
972 if (attr.Length == sizeof(attr))
974 ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
975 pNtClose( ret );
977 else ok( status == STATUS_INVALID_PARAMETER,
978 "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
980 attr.Length = sizeof(attr);
981 str.Length = 65532;
982 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
983 ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
984 pNtClose( ret );
985 str.Length = 65534;
986 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
987 ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %lx\n", str.Length, status );
988 attr3.RootDirectory = 0;
989 attr2.ObjectName = attr3.ObjectName = NULL;
990 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL );
991 ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateMailslotFile failed %lx\n", status );
992 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr3, &iosb, 0, 0, 0, NULL );
993 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateMailslotFile failed %lx\n", status );
994 status = pNtCreateMailslotFile( &ret, GENERIC_ALL, NULL, &iosb, 0, 0, 0, NULL );
995 ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateMailslotFile failed %lx\n", status );
996 attr2.ObjectName = attr3.ObjectName = &str;
998 /* registry keys */
999 wcscpy( str.Buffer, registryW );
1000 for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + wcslen(registryW)] = 'a';
1001 str.Length = 0;
1002 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1003 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateKey failed %lx\n", str.Length, status );
1004 status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL );
1005 ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateKey failed %lx\n", str.Length, status );
1006 status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 );
1007 ok( status == STATUS_INVALID_HANDLE, "%u: NtOpenKey failed %lx\n", str.Length, status );
1008 str.Length = (wcslen( registryW ) + 250) * sizeof(WCHAR) + 1;
1009 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1010 ok( status == STATUS_OBJECT_NAME_INVALID ||
1011 status == STATUS_INVALID_PARAMETER ||
1012 broken( status == STATUS_SUCCESS ), /* wow64 */
1013 "%u: NtCreateKey failed %lx\n", str.Length, status );
1014 if (!status)
1016 pNtDeleteKey( ret );
1017 pNtClose( ret );
1019 str.Length = (wcslen( registryW ) + 256) * sizeof(WCHAR);
1020 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1021 ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED,
1022 "%u: NtCreateKey failed %lx\n", str.Length, status );
1023 status = pNtCreateKey( (HANDLE *)0xdeadbee0, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1024 ok( status == STATUS_ACCESS_VIOLATION, "%u: NtCreateKey failed %lx\n", str.Length, status );
1025 if (!status)
1027 status = pNtOpenKey( &ret2, KEY_READ, &attr );
1028 ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %lx\n", str.Length, status );
1029 pNtClose( ret2 );
1030 status = pNtOpenKey( (HANDLE *)0xdeadbee0, KEY_READ, &attr );
1031 ok( status == STATUS_ACCESS_VIOLATION, "%u: NtOpenKey failed %lx\n", str.Length, status );
1032 attr3.RootDirectory = ret;
1033 str.Length = 0;
1034 status = pNtOpenKey( &ret2, KEY_READ, &attr3 );
1035 ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %lx\n", str.Length, status );
1036 pNtClose( ret2 );
1037 pNtDeleteKey( ret );
1038 pNtClose( ret );
1040 str.Length = (wcslen( registryW ) + 256) * sizeof(WCHAR);
1041 for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++)
1043 if (attr.Length == sizeof(attr))
1045 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1046 ok( status == STATUS_SUCCESS, "%u: NtCreateKey failed %lx\n", str.Length, status );
1047 status = pNtOpenKey( &ret2, KEY_READ, &attr );
1048 ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %lx\n", str.Length, status );
1049 pNtClose( ret2 );
1050 pNtDeleteKey( ret );
1051 pNtClose( ret );
1053 else
1055 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1056 ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %lx\n", str.Length, status );
1057 status = pNtOpenKey( &ret2, KEY_READ, &attr );
1058 ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %lx\n", str.Length, status );
1061 attr.Length = sizeof(attr);
1063 str.Length = (wcslen( registryW ) + 256) * sizeof(WCHAR) + 1;
1064 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1065 ok( status == STATUS_OBJECT_NAME_INVALID ||
1066 status == STATUS_INVALID_PARAMETER ||
1067 broken( status == STATUS_SUCCESS ), /* win7 */
1068 "%u: NtCreateKey failed %lx\n", str.Length, status );
1069 if (!status)
1071 pNtDeleteKey( ret );
1072 pNtClose( ret );
1074 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1075 ok( status == STATUS_OBJECT_NAME_INVALID ||
1076 status == STATUS_INVALID_PARAMETER ||
1077 broken( status == STATUS_OBJECT_NAME_NOT_FOUND ), /* wow64 */
1078 "%u: NtOpenKey failed %lx\n", str.Length, status );
1079 str.Length++;
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 str.Length = 2000;
1085 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1086 ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %lx\n", str.Length, status );
1087 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1088 ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %lx\n", str.Length, status );
1089 /* some Windows versions change the error past 2050 chars, others past 4066 chars, some don't */
1090 str.Length = 5000;
1091 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1092 ok( status == STATUS_BUFFER_OVERFLOW ||
1093 status == STATUS_BUFFER_TOO_SMALL ||
1094 status == STATUS_INVALID_PARAMETER,
1095 "%u: NtCreateKey failed %lx\n", str.Length, status );
1096 ret = (HANDLE)0xdeadbeef;
1097 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1098 ok( status == STATUS_BUFFER_OVERFLOW ||
1099 status == STATUS_BUFFER_TOO_SMALL ||
1100 status == STATUS_INVALID_PARAMETER,
1101 "%u: NtOpenKey failed %lx\n", str.Length, status );
1102 ok( !ret, "handle set %p\n", ret );
1103 str.Length = 65534;
1104 ret = (HANDLE)0xdeadbeef;
1105 status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
1106 ok( status == STATUS_OBJECT_NAME_INVALID ||
1107 status == STATUS_BUFFER_OVERFLOW ||
1108 status == STATUS_BUFFER_TOO_SMALL,
1109 "%u: NtCreateKey failed %lx\n", str.Length, status );
1110 ok( !ret, "handle set %p\n", ret );
1111 ret = (HANDLE)0xdeadbeef;
1112 status = pNtOpenKey( &ret, GENERIC_ALL, &attr );
1113 ok( status == STATUS_OBJECT_NAME_INVALID ||
1114 status == STATUS_BUFFER_OVERFLOW ||
1115 status == STATUS_BUFFER_TOO_SMALL,
1116 "%u: NtOpenKey failed %lx\n", str.Length, status );
1117 ok( !ret, "handle set %p\n", ret );
1118 attr3.RootDirectory = 0;
1119 attr2.ObjectName = attr3.ObjectName = NULL;
1120 status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL );
1121 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE /* vista wow64 */,
1122 "NULL: NtCreateKey failed %lx\n", status );
1123 status = pNtCreateKey( &ret, GENERIC_ALL, &attr3, 0, NULL, 0, NULL );
1124 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %lx\n", status );
1125 status = pNtCreateKey( &ret, GENERIC_ALL, NULL, 0, NULL, 0, NULL );
1126 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %lx\n", status );
1127 status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 );
1128 ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE /* vista wow64 */,
1129 "NULL: NtOpenKey failed %lx\n", status );
1130 status = pNtOpenKey( &ret, GENERIC_ALL, &attr3 );
1131 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %lx\n", status );
1132 status = pNtOpenKey( &ret, GENERIC_ALL, NULL );
1133 ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %lx\n", status );
1134 attr2.ObjectName = attr3.ObjectName = &str;
1136 HeapFree( GetProcessHeap(), 0, str.Buffer );
1139 static void test_directory(void)
1141 NTSTATUS status;
1142 UNICODE_STRING str;
1143 OBJECT_ATTRIBUTES attr;
1144 HANDLE dir, dir1, h, h2;
1145 WCHAR buffer[256];
1146 ULONG len, full_len;
1148 /* No name and/or no attributes */
1149 status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
1150 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER /* wow64 */, "got %#lx\n", status);
1151 status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
1152 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER /* wow64 */, "got %#lx\n", status);
1154 status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL);
1155 ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08lx)\n", status);
1156 pNtClose(h);
1157 status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL);
1158 ok(status == STATUS_INVALID_PARAMETER,
1159 "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status);
1161 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
1162 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1163 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1164 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1165 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08lx\n", status );
1167 /* Bad name */
1168 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1170 RtlInitUnicodeString(&str, L"");
1171 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1172 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1173 pNtClose(h);
1174 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1175 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08lx\n", status );
1176 pNtClose(dir);
1178 check_create_open_dir( NULL, L"BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD );
1179 check_create_open_dir( NULL, L"\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID );
1180 check_create_open_dir( NULL, L"\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID );
1181 check_create_open_dir( NULL, L"\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID );
1182 check_create_open_dir( NULL, L"\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND );
1184 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test");
1185 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1186 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1187 status = pNtOpenDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
1188 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1189 pNtClose(h);
1190 pNtClose(dir1);
1193 /* Use of root directory */
1195 /* Can't use symlinks as a directory */
1196 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\Local");
1197 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1198 status = pNtOpenSymbolicLinkObject(&dir, SYMBOLIC_LINK_QUERY, &attr);
1200 ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08lx)\n", status);
1201 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1202 RtlInitUnicodeString(&str, L"one more level");
1203 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1204 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtCreateDirectoryObject got %08lx\n", status );
1206 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\Local\\om.c-test" );
1207 InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
1208 status = pNtCreateDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
1209 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1210 RtlInitUnicodeString( &str, L"om.c-test" );
1211 InitializeObjectAttributes( &attr, &str, 0, dir, NULL );
1212 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1213 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "Failed to open directory %08lx\n", status );
1215 RtlInitUnicodeString( &str, L"om.c-event" );
1216 InitializeObjectAttributes( &attr, &str, 0, dir1, NULL );
1217 status = pNtCreateEvent( &h, GENERIC_ALL, &attr, SynchronizationEvent, 0 );
1218 ok( status == STATUS_SUCCESS, "NtCreateEvent failed %lx\n", status );
1219 status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
1220 ok( status == STATUS_SUCCESS, "NtOpenEvent failed %lx\n", status );
1221 pNtClose( h2 );
1222 RtlInitUnicodeString( &str, L"om.c-test\\om.c-event" );
1223 InitializeObjectAttributes( &attr, &str, 0, dir, NULL );
1224 status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
1225 ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtOpenEvent failed %lx\n", status );
1226 RtlInitUnicodeString( &str, L"\\BasedNamedObjects\\Local\\om.c-test\\om.c-event" );
1227 InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
1228 status = pNtOpenEvent( &h2, GENERIC_ALL, &attr );
1229 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtOpenEvent failed %lx\n", status );
1230 pNtClose( h );
1231 pNtClose( dir1 );
1233 str.Buffer = buffer;
1234 str.MaximumLength = sizeof(buffer);
1235 len = 0xdeadbeef;
1236 memset( buffer, 0xaa, sizeof(buffer) );
1237 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1238 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1239 full_len = str.Length + sizeof(WCHAR);
1240 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1241 ok( buffer[len / sizeof(WCHAR) - 1] == 0, "no terminating null\n" );
1243 str.MaximumLength = str.Length;
1244 str.Length = 0x4444;
1245 len = 0xdeadbeef;
1246 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1247 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1248 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1249 ok( str.Length == 0x4444, "len set to %x\n", str.Length );
1251 str.MaximumLength = 0;
1252 str.Length = 0x4444;
1253 len = 0xdeadbeef;
1254 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1255 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1256 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1257 ok( str.Length == 0x4444, "len set to %x\n", str.Length );
1259 str.MaximumLength = full_len;
1260 str.Length = 0x4444;
1261 len = 0xdeadbeef;
1262 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
1263 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08lx\n", status );
1264 ok( len == full_len, "bad length %lu/%lu\n", len, full_len );
1265 ok( str.Length == full_len - sizeof(WCHAR), "len set to %x\n", str.Length );
1267 pNtClose(dir);
1269 RtlInitUnicodeString(&str, L"\\BaseNamedObjects");
1270 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1271 status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1272 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1274 InitializeObjectAttributes(&attr, NULL, 0, dir, NULL);
1275 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1276 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenDirectoryObject got %08lx\n", status );
1278 check_create_open_dir( dir, L"", STATUS_SUCCESS );
1279 check_create_open_dir( dir, L"\\", STATUS_OBJECT_PATH_SYNTAX_BAD );
1280 check_create_open_dir( dir, L"\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD );
1281 check_create_open_dir( dir, L"\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD );
1282 check_create_open_dir( dir, L"om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND );
1284 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1285 RtlInitUnicodeString(&str, L"om.c-test");
1286 status = pNtCreateDirectoryObject( &dir1, DIRECTORY_QUERY, &attr );
1287 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1288 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1289 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1291 pNtClose(h);
1292 pNtClose(dir1);
1293 pNtClose(dir);
1295 /* Nested directories */
1296 RtlInitUnicodeString(&str, L"\\");
1297 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1298 status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1299 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1300 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1301 status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1302 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08lx\n", status );
1303 pNtClose(dir);
1305 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1306 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test");
1307 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1308 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1309 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test\\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);
1313 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1314 RtlInitUnicodeString(&str, L"one more level");
1315 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1316 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1317 pNtClose(h);
1319 pNtClose(dir);
1321 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1322 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\Global\\om.c-test");
1323 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1324 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1325 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\Local\\om.c-test\\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 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1330 RtlInitUnicodeString(&str, L"one more level");
1331 status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr );
1332 ok( status == STATUS_SUCCESS, "Failed to create directory %08lx\n", status );
1333 pNtClose(h);
1334 pNtClose(dir);
1336 /* Create other objects using RootDirectory */
1338 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1339 RtlInitUnicodeString(&str, L"\\BaseNamedObjects");
1340 status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
1341 ok( status == STATUS_SUCCESS, "Failed to open directory %08lx\n", status );
1342 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1344 /* Test invalid paths */
1345 RtlInitUnicodeString(&str, L"\\om.c-mutant");
1346 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1347 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1348 "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_SYNTAX_BAD,
1352 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
1354 RtlInitUnicodeString(&str, L"om.c\\-mutant");
1355 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1356 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
1357 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status);
1359 RtlInitUnicodeString(&str, L"om.c-mutant");
1360 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
1361 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08lx)\n", status);
1362 pNtClose(h);
1364 pNtClose(dir);
1367 static void test_symboliclink(void)
1369 NTSTATUS status;
1370 UNICODE_STRING str, target;
1371 OBJECT_ATTRIBUTES attr;
1372 HANDLE dir, link, h, h2;
1373 IO_STATUS_BLOCK iosb;
1375 /* No name and/or no attributes */
1376 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
1377 RtlInitUnicodeString(&target, L"\\DosDevices");
1378 status = pNtCreateSymbolicLinkObject( NULL, SYMBOLIC_LINK_QUERY, &attr, &target );
1379 ok(status == STATUS_ACCESS_VIOLATION, "got %#lx\n", status);
1380 status = pNtOpenSymbolicLinkObject( NULL, SYMBOLIC_LINK_QUERY, &attr );
1381 ok(status == STATUS_ACCESS_VIOLATION, "got %#lx\n", status);
1383 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL);
1384 ok(status == STATUS_ACCESS_VIOLATION,
1385 "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status);
1386 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL);
1387 ok(status == STATUS_INVALID_PARAMETER,
1388 "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status);
1390 /* No attributes */
1391 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, &target);
1392 ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_VIOLATION, /* nt4 */
1393 "NtCreateSymbolicLinkObject failed(%08lx)\n", status);
1395 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
1396 memset(&target, 0, sizeof(target));
1397 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1398 ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
1399 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
1400 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1401 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
1403 /* Bad name */
1404 RtlInitUnicodeString(&target, L"anywhere");
1405 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1407 RtlInitUnicodeString(&str, L"");
1408 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1409 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08lx)\n", status);
1410 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
1411 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
1412 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
1413 pNtClose(link);
1415 RtlInitUnicodeString(&str, L"\\");
1416 attr.Attributes = OBJ_OPENIF;
1417 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target);
1418 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
1419 "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
1420 attr.Attributes = 0;
1421 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target);
1422 todo_wine
1423 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
1424 "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
1426 RtlInitUnicodeString( &target, L"->Somewhere");
1428 RtlInitUnicodeString( &str, L"BaseNamedObjects" );
1429 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1430 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtCreateSymbolicLinkObject got %08lx\n", status );
1431 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1432 ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenSymbolicLinkObject got %08lx\n", status );
1434 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\" );
1435 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1436 ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08lx\n", status );
1437 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1438 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08lx\n", status );
1440 RtlInitUnicodeString( &str, L"\\\\BaseNamedObjects" );
1441 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1442 ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08lx\n", status );
1443 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1444 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08lx\n", status );
1446 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\\\om.c-test" );
1447 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1448 ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08lx\n", status );
1449 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1450 ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08lx\n", status );
1452 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\" );
1453 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1454 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "got %#lx\n", status );
1455 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1456 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "got %#lx\n", status );
1458 /* Compound test */
1459 dir = get_base_dir();
1460 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1461 RtlInitUnicodeString(&str, L"test-link");
1462 RtlInitUnicodeString(&target, L"\\DosDevices");
1463 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1464 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08lx)\n", status);
1466 RtlInitUnicodeString(&str, L"test-link\\NUL");
1467 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0);
1468 ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08lx)\n", status);
1469 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE);
1470 ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08lx)\n", status);
1472 pNtClose(h);
1473 pNtClose(link);
1474 pNtClose(dir);
1476 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1477 RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test");
1478 status = pNtCreateDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
1479 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1481 RtlInitUnicodeString(&str, L"\\DosDevices\\test_link");
1482 RtlInitUnicodeString(&target, L"\\BaseNamedObjects");
1483 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
1484 ok(status == STATUS_SUCCESS && !!link, "Got unexpected status %#lx.\n", status);
1486 status = NtCreateFile(&h, GENERIC_READ | SYNCHRONIZE, &attr, &iosb, NULL, 0,
1487 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 );
1488 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1490 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
1491 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1492 pNtClose(h);
1494 attr.Attributes = OBJ_OPENIF;
1495 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1496 ok(status == STATUS_SUCCESS || broken( status == STATUS_OBJECT_NAME_EXISTS ), /* <= win10 1507 */
1497 "Got unexpected status %#lx.\n", status);
1498 pNtClose(h);
1499 attr.Attributes = 0;
1500 status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target );
1501 ok(status == STATUS_OBJECT_NAME_COLLISION, "Got unexpected status %#lx.\n", status);
1502 pNtClose(h);
1504 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1505 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\" );
1506 status = NtCreateFile(&h, GENERIC_READ | SYNCHRONIZE, &attr, &iosb, NULL, 0,
1507 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 );
1508 ok(status == STATUS_OBJECT_NAME_INVALID, "Got unexpected status %#lx.\n", status);
1510 InitializeObjectAttributes(&attr, &str, 0, link, NULL);
1511 RtlInitUnicodeString( &str, L"om.c-test\\test_object" );
1512 status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
1513 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1515 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
1516 RtlInitUnicodeString( &str, L"\\DosDevices\\test_link\\om.c-test\\test_object" );
1517 status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
1518 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1519 status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
1520 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1521 pNtClose(h2);
1522 RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\test_object" );
1523 status = pNtCreateMutant( &h2, GENERIC_ALL, &attr, FALSE );
1524 ok(status == STATUS_OBJECT_NAME_COLLISION, "Got unexpected status %#lx.\n", status);
1526 InitializeObjectAttributes(&attr, &str, 0, link, NULL);
1527 RtlInitUnicodeString( &str, L"om.c-test\\test_object" );
1528 status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
1529 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1531 pNtClose(h);
1533 status = pNtOpenMutant( &h, GENERIC_ALL, &attr );
1534 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
1536 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
1537 RtlInitUnicodeString( &str, L"test_object" );
1538 status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
1539 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1540 status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
1541 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
1542 pNtClose(h);
1543 pNtClose(h2);
1545 pNtClose(link);
1546 pNtClose(dir);
1549 #define test_file_info(a) _test_file_info(__LINE__,a)
1550 static void _test_file_info(unsigned line, HANDLE handle)
1552 IO_STATUS_BLOCK io;
1553 char buf[256];
1554 NTSTATUS status;
1556 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), 0xdeadbeef);
1557 ok_(__FILE__,line)(status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED /* Vista+ */,
1558 "expected STATUS_NOT_IMPLEMENTED, got %lx\n", status);
1560 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), FileAccessInformation);
1561 ok_(__FILE__,line)(status == STATUS_SUCCESS, "FileAccessInformation returned %lx\n", status);
1563 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf),
1564 FileIoCompletionNotificationInformation);
1565 ok_(__FILE__,line)(status == STATUS_SUCCESS || broken(status == STATUS_INVALID_INFO_CLASS) /* XP */,
1566 "FileIoCompletionNotificationInformation returned %lx\n", status);
1569 #define test_no_file_info(a) _test_no_file_info(__LINE__,a)
1570 static void _test_no_file_info(unsigned line, HANDLE handle)
1572 IO_STATUS_BLOCK io;
1573 char buf[256];
1574 NTSTATUS status;
1576 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), 0xdeadbeef);
1577 ok_(__FILE__,line)(status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED /* Vista+ */,
1578 "expected STATUS_NOT_IMPLEMENTED, got %lx\n", status);
1580 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf), FileAccessInformation);
1581 ok_(__FILE__,line)(status == STATUS_OBJECT_TYPE_MISMATCH,
1582 "FileAccessInformation returned %lx\n", status);
1584 status = pNtQueryInformationFile(handle, &io, buf, sizeof(buf),
1585 FileIoCompletionNotificationInformation);
1586 ok_(__FILE__,line)(status == STATUS_OBJECT_TYPE_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* XP */,
1587 "FileIoCompletionNotificationInformation returned %lx\n", status);
1590 static OBJECT_TYPE_INFORMATION all_types[256];
1592 static void add_object_type( OBJECT_TYPE_INFORMATION *info )
1594 unsigned int i;
1596 for (i = 0; i < ARRAY_SIZE(all_types); i++)
1598 if (!all_types[i].TypeName.Buffer) break;
1599 if (!RtlCompareUnicodeString( &all_types[i].TypeName, &info->TypeName, FALSE )) break;
1601 ok( i < ARRAY_SIZE(all_types), "too many types\n" );
1603 if (all_types[i].TypeName.Buffer) /* existing type */
1605 ok( !memcmp( &all_types[i].GenericMapping, &info->GenericMapping, sizeof(GENERIC_MAPPING) ),
1606 "%u: mismatched mappings %08lx,%08lx,%08lx,%08lx / %08lx,%08lx,%08lx,%08lx\n", i,
1607 all_types[i].GenericMapping.GenericRead, all_types[i].GenericMapping.GenericWrite,
1608 all_types[i].GenericMapping.GenericExecute, all_types[i].GenericMapping.GenericAll,
1609 info->GenericMapping.GenericRead, info->GenericMapping.GenericWrite,
1610 info->GenericMapping.GenericExecute, info->GenericMapping.GenericAll );
1611 ok( all_types[i].ValidAccessMask == info->ValidAccessMask,
1612 "%u: mismatched access mask %08lx / %08lx\n", i,
1613 all_types[i].ValidAccessMask, info->ValidAccessMask );
1615 else /* add it */
1617 all_types[i] = *info;
1618 RtlDuplicateUnicodeString( 1, &info->TypeName, &all_types[i].TypeName );
1620 ok( info->TotalNumberOfObjects <= info->HighWaterNumberOfObjects, "%s: wrong object counts %lu/%lu\n",
1621 debugstr_w( all_types[i].TypeName.Buffer ),
1622 info->TotalNumberOfObjects, info->HighWaterNumberOfObjects );
1623 ok( info->TotalNumberOfHandles <= info->HighWaterNumberOfHandles, "%s: wrong handle counts %lu/%lu\n",
1624 debugstr_w( all_types[i].TypeName.Buffer ),
1625 info->TotalNumberOfHandles, info->HighWaterNumberOfHandles );
1628 static BOOL compare_unicode_string( const UNICODE_STRING *string, const WCHAR *expect )
1630 return string->Length == wcslen( expect ) * sizeof(WCHAR)
1631 && !wcsnicmp( string->Buffer, expect, string->Length / sizeof(WCHAR) );
1634 #define test_object_type(a,b) _test_object_type(__LINE__,a,b)
1635 static void _test_object_type( unsigned line, HANDLE handle, const WCHAR *expected_name )
1637 char buffer[1024];
1638 OBJECT_TYPE_INFORMATION *type = (OBJECT_TYPE_INFORMATION *)buffer;
1639 UNICODE_STRING expect;
1640 ULONG len = 0;
1641 NTSTATUS status;
1643 RtlInitUnicodeString( &expect, expected_name );
1645 memset( buffer, 0, sizeof(buffer) );
1646 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
1647 ok_(__FILE__,line)( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1648 ok_(__FILE__,line)( len > sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1649 ok_(__FILE__,line)( len >= sizeof(*type) + type->TypeName.Length, "unexpected len %lu\n", len );
1650 ok_(__FILE__,line)(compare_unicode_string( &type->TypeName, expected_name ), "wrong name %s\n",
1651 debugstr_w( type->TypeName.Buffer ));
1652 add_object_type( type );
1655 #define test_object_name(a,b,c) _test_object_name(__LINE__,a,b,c)
1656 static void _test_object_name( unsigned line, HANDLE handle, const WCHAR *expected_name, BOOL todo )
1658 char buffer[1024];
1659 UNICODE_STRING *str = (UNICODE_STRING *)buffer, expect;
1660 ULONG len = 0;
1661 NTSTATUS status;
1663 RtlInitUnicodeString( &expect, expected_name );
1665 memset( buffer, 0, sizeof(buffer) );
1666 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1667 ok_(__FILE__,line)( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1668 ok_(__FILE__,line)( len >= sizeof(OBJECT_NAME_INFORMATION) + str->Length, "unexpected len %lu\n", len );
1669 todo_wine_if (todo)
1670 ok_(__FILE__,line)(compare_unicode_string( str, expected_name ), "got %s, expected %s\n",
1671 debugstr_w(str->Buffer), debugstr_w(expected_name));
1674 static void test_query_object(void)
1676 static const WCHAR name[] = L"\\BaseNamedObjects\\test_event";
1677 HANDLE handle, client;
1678 char buffer[1024];
1679 NTSTATUS status;
1680 ULONG len, expected_len;
1681 OBJECT_BASIC_INFORMATION info;
1682 OBJECT_ATTRIBUTES attr;
1683 UNICODE_STRING path, target, *str;
1684 char dir[MAX_PATH], tmp_path[MAX_PATH], file1[MAX_PATH + 16];
1685 WCHAR expect[100];
1686 LARGE_INTEGER size;
1688 InitializeObjectAttributes( &attr, &path, 0, 0, 0 );
1690 handle = CreateEventA( NULL, FALSE, FALSE, "test_event" );
1692 status = pNtQueryObject( handle, ObjectBasicInformation, NULL, 0, NULL );
1693 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1695 status = pNtQueryObject( handle, ObjectBasicInformation, &info, 0, NULL );
1696 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1698 status = pNtQueryObject( handle, ObjectBasicInformation, NULL, 0, &len );
1699 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1701 len = 0;
1702 status = pNtQueryObject( handle, ObjectBasicInformation, &info, sizeof(OBJECT_BASIC_INFORMATION), &len );
1703 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1704 ok( len >= sizeof(OBJECT_BASIC_INFORMATION), "unexpected len %lu\n", len );
1706 len = 0;
1707 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
1708 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1709 ok( len >= sizeof(UNICODE_STRING) + sizeof(name), "unexpected len %lu\n", len );
1711 len = 0;
1712 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, 0, &len );
1713 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1714 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(L"Event"), "unexpected len %lu\n", len );
1716 len = 0;
1717 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
1718 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1719 ok( len >= sizeof(UNICODE_STRING) + sizeof(name), "unexpected len %lu\n", len );
1721 len = 0;
1722 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(OBJECT_TYPE_INFORMATION), &len );
1723 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1724 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(L"Event"), "unexpected len %lu\n", len );
1726 len = 0;
1727 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1728 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1729 ok( len > sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1730 str = (UNICODE_STRING *)buffer;
1731 ok( sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR) == len, "unexpected len %lu\n", len );
1732 ok( str->Length >= sizeof(name) - sizeof(WCHAR), "unexpected len %u\n", str->Length );
1733 ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_event") * sizeof(WCHAR),
1734 "name too short %s\n", wine_dbgstr_w(str->Buffer) );
1735 /* check for \\Sessions prefix in the name */
1736 swprintf( expect, ARRAY_SIZE(expect), L"\\Sessions\\%u%s", NtCurrentTeb()->Peb->SessionId, name );
1737 ok( (str->Length == wcslen( expect ) * sizeof(WCHAR) && !wcscmp( str->Buffer, expect )) ||
1738 broken( !wcscmp( str->Buffer, name )), /* winxp */
1739 "wrong name %s\n", wine_dbgstr_w(str->Buffer) );
1740 trace( "got %s len %lu\n", wine_dbgstr_w(str->Buffer), len );
1742 len -= sizeof(WCHAR);
1743 status = pNtQueryObject( handle, ObjectNameInformation, buffer, len, &len );
1744 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1745 ok( len >= sizeof(UNICODE_STRING) + sizeof(name), "unexpected len %lu\n", len );
1747 test_object_type( handle, L"Event" );
1749 len -= sizeof(WCHAR);
1750 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, len, &len );
1751 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
1752 ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(L"Event"), "unexpected len %lu\n", len );
1754 test_no_file_info( handle );
1755 pNtClose( handle );
1757 handle = CreateEventA( NULL, FALSE, FALSE, NULL );
1758 len = 0;
1759 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1760 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1761 ok( len == sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1762 str = (UNICODE_STRING *)buffer;
1763 ok( str->Length == 0, "unexpected len %lu\n", len );
1764 ok( str->Buffer == NULL, "unexpected ptr %p\n", str->Buffer );
1765 test_no_file_info( handle );
1766 pNtClose( handle );
1768 GetWindowsDirectoryA( dir, MAX_PATH );
1769 handle = CreateFileA( dir, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1770 FILE_FLAG_BACKUP_SEMANTICS, 0 );
1771 len = 0;
1772 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
1773 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1774 ok( len > sizeof(UNICODE_STRING), "unexpected len %lu\n", len );
1775 str = (UNICODE_STRING *)buffer;
1776 expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR);
1777 ok( len == expected_len, "unexpected len %lu\n", len );
1778 trace( "got %s len %lu\n", wine_dbgstr_w(str->Buffer), len );
1780 len = 0;
1781 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
1782 ok( status == STATUS_INFO_LENGTH_MISMATCH, "got %#lx\n", status );
1783 ok( len == expected_len || broken(!len /* XP */ || len == sizeof(UNICODE_STRING) /* 2003 */),
1784 "unexpected len %lu\n", len );
1786 len = 0;
1787 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
1788 ok( status == STATUS_BUFFER_OVERFLOW, "got %#lx\n", status);
1789 ok( len == expected_len, "unexpected len %lu\n", len );
1791 test_object_type( handle, L"File" );
1793 pNtClose( handle );
1795 GetTempPathA(MAX_PATH, tmp_path);
1796 GetTempFileNameA(tmp_path, "foo", 0, file1);
1797 handle = CreateFileA(file1, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0);
1798 test_object_type(handle, L"File");
1799 test_file_info( handle );
1800 pNtClose( handle );
1801 DeleteFileA( file1 );
1803 status = pNtCreateIoCompletion( &handle, IO_COMPLETION_ALL_ACCESS, NULL, 0 );
1804 ok( status == STATUS_SUCCESS, "NtCreateIoCompletion failed %lx\n", status);
1806 test_object_type( handle, L"IoCompletion" );
1807 test_no_file_info( handle );
1809 pNtClose( handle );
1811 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_debug" );
1812 status = pNtCreateDebugObject( &handle, DEBUG_ALL_ACCESS, &attr, 0 );
1813 ok(!status, "NtCreateDebugObject failed: %lx\n", status);
1814 test_object_name( handle, L"\\BaseNamedObjects\\test_debug", FALSE );
1815 test_object_type( handle, L"DebugObject" );
1816 test_no_file_info( handle );
1817 pNtClose(handle);
1819 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_mutant" );
1820 status = pNtCreateMutant( &handle, MUTANT_ALL_ACCESS, &attr, 0 );
1821 ok(!status, "NtCreateMutant failed: %lx\n", status);
1822 test_object_name( handle, L"\\BaseNamedObjects\\test_mutant", FALSE );
1823 test_object_type( handle, L"Mutant" );
1824 test_no_file_info( handle );
1825 pNtClose(handle);
1827 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_sem" );
1828 status = pNtCreateSemaphore( &handle, SEMAPHORE_ALL_ACCESS, &attr, 1, 2 );
1829 ok(!status, "NtCreateSemaphore failed: %lx\n", status);
1830 test_object_name( handle, L"\\BaseNamedObjects\\test_sem", FALSE );
1831 test_object_type( handle, L"Semaphore" );
1832 test_no_file_info( handle );
1833 pNtClose(handle);
1835 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_keyed" );
1836 status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr, 0 );
1837 ok(!status, "NtCreateKeyedEvent failed: %lx\n", status);
1838 test_object_name( handle, L"\\BaseNamedObjects\\test_keyed", FALSE );
1839 test_object_type( handle, L"KeyedEvent" );
1840 test_no_file_info( handle );
1841 pNtClose(handle);
1843 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_compl" );
1844 status = pNtCreateIoCompletion( &handle, IO_COMPLETION_ALL_ACCESS, &attr, 0 );
1845 ok(!status, "NtCreateIoCompletion failed: %lx\n", status);
1846 test_object_name( handle, L"\\BaseNamedObjects\\test_compl", FALSE );
1847 test_object_type( handle, L"IoCompletion" );
1848 test_no_file_info( handle );
1849 pNtClose(handle);
1851 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_job" );
1852 status = pNtCreateJobObject( &handle, JOB_OBJECT_ALL_ACCESS, &attr );
1853 ok(!status, "NtCreateJobObject failed: %lx\n", status);
1854 test_object_name( handle, L"\\BaseNamedObjects\\test_job", FALSE );
1855 test_object_type( handle, L"Job" );
1856 test_no_file_info( handle );
1857 pNtClose(handle);
1859 RtlInitUnicodeString( &path, L"\\BaseNamedObjects\\test_timer" );
1860 status = pNtCreateTimer( &handle, TIMER_ALL_ACCESS, &attr, NotificationTimer );
1861 ok(!status, "NtCreateTimer failed: %lx\n", status);
1862 test_object_type( handle, L"Timer" );
1863 test_no_file_info( handle );
1864 pNtClose(handle);
1866 RtlInitUnicodeString( &path, L"\\DosDevices\\test_link" );
1867 RtlInitUnicodeString( &target, L"\\DosDevices" );
1868 status = pNtCreateSymbolicLinkObject( &handle, SYMBOLIC_LINK_ALL_ACCESS, &attr, &target );
1869 ok(!status, "NtCreateSymbolicLinkObject failed: %lx\n", status);
1870 test_object_type( handle, L"SymbolicLink" );
1871 test_no_file_info( handle );
1872 pNtClose(handle);
1874 handle = GetProcessWindowStation();
1875 swprintf( expect, ARRAY_SIZE(expect), L"\\Sessions\\%u\\Windows\\WindowStations\\WinSta0", NtCurrentTeb()->Peb->SessionId );
1876 test_object_name( handle, expect, FALSE );
1877 test_object_type( handle, L"WindowStation" );
1878 test_no_file_info( handle );
1880 handle = GetThreadDesktop( GetCurrentThreadId() );
1881 test_object_name( handle, L"\\Default", FALSE );
1882 test_object_type( handle, L"Desktop" );
1883 test_no_file_info( handle );
1885 status = pNtCreateDirectoryObject( &handle, DIRECTORY_QUERY, NULL );
1886 ok(status == STATUS_SUCCESS, "Failed to create Directory %08lx\n", status);
1888 test_object_type( handle, L"Directory" );
1889 test_no_file_info( handle );
1891 pNtClose( handle );
1893 size.u.LowPart = 256;
1894 size.u.HighPart = 0;
1895 status = pNtCreateSection( &handle, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 );
1896 ok( status == STATUS_SUCCESS , "NtCreateSection returned %lx\n", status );
1898 test_object_type( handle, L"Section" );
1899 test_no_file_info( handle );
1901 pNtClose( handle );
1903 handle = CreateMailslotA( "\\\\.\\mailslot\\test_mailslot", 100, 1000, NULL );
1904 ok( handle != INVALID_HANDLE_VALUE, "CreateMailslot failed err %lu\n", GetLastError() );
1906 test_object_name( handle, L"\\Device\\Mailslot\\test_mailslot", FALSE );
1907 test_object_type( handle, L"File" );
1908 test_file_info( handle );
1910 client = CreateFileA( "\\\\.\\mailslot\\test_mailslot", 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
1911 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1913 len = 0;
1914 status = pNtQueryObject( client, ObjectNameInformation, buffer, sizeof(buffer), &len );
1915 ok( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
1916 str = (UNICODE_STRING *)buffer;
1917 ok( len == sizeof(UNICODE_STRING) + str->MaximumLength, "unexpected len %lu\n", len );
1918 todo_wine
1919 ok( compare_unicode_string( str, L"\\Device\\Mailslot" ) ||
1920 compare_unicode_string( str, L"\\Device\\Mailslot\\test_mailslot" ) /* win8+ */,
1921 "wrong name %s\n", debugstr_w( str->Buffer ));
1923 test_object_type( client, L"File" );
1924 test_file_info( client );
1926 pNtClose( client );
1927 pNtClose( handle );
1929 handle = CreateFileA( "\\\\.\\mailslot", 0, 0, NULL, OPEN_EXISTING, 0, 0 );
1930 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1932 test_object_name( handle, L"\\Device\\Mailslot", FALSE );
1933 test_object_type( handle, L"File" );
1934 test_file_info( handle );
1936 pNtClose( handle );
1938 handle = CreateNamedPipeA( "\\\\.\\pipe\\test_pipe", PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE,
1939 1, 1000, 1000, 1000, NULL );
1940 ok( handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed err %lu\n", GetLastError() );
1942 test_object_name( handle, L"\\Device\\NamedPipe\\test_pipe", FALSE );
1943 test_object_type( handle, L"File" );
1944 test_file_info( handle );
1946 client = CreateFileA( "\\\\.\\pipe\\test_pipe", GENERIC_READ | GENERIC_WRITE,
1947 0, NULL, OPEN_EXISTING, 0, 0 );
1948 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1950 test_object_type( client, L"File" );
1951 test_file_info( client );
1953 pNtClose( client );
1954 pNtClose( handle );
1956 handle = CreateFileA( "\\\\.\\pipe", 0, 0, NULL, OPEN_EXISTING, 0, 0 );
1957 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
1959 test_object_name( handle, L"\\Device\\NamedPipe", FALSE );
1960 test_object_type( handle, L"File" );
1961 test_file_info( handle );
1963 pNtClose( handle );
1965 handle = CreateFileA( "\\\\.\\pipe\\", 0, 0, NULL, OPEN_EXISTING, 0, 0 );
1966 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%lu)\n", GetLastError() );
1968 test_object_name( handle, L"\\Device\\NamedPipe\\", TRUE );
1969 test_object_type( handle, L"File" );
1970 test_file_info( handle );
1972 pNtClose( handle );
1974 RtlInitUnicodeString( &path, L"\\REGISTRY\\Machine" );
1975 status = pNtCreateKey( &handle, KEY_READ, &attr, 0, 0, 0, 0 );
1976 ok( status == STATUS_SUCCESS, "NtCreateKey failed status %lx\n", status );
1978 test_object_name( handle, L"\\REGISTRY\\MACHINE", FALSE );
1979 test_object_type( handle, L"Key" );
1981 pNtClose( handle );
1983 test_object_name( GetCurrentProcess(), L"", FALSE );
1984 test_object_type( GetCurrentProcess(), L"Process" );
1985 test_no_file_info( GetCurrentProcess() );
1987 test_object_name( GetCurrentThread(), L"", FALSE );
1988 test_object_type( GetCurrentThread(), L"Thread" );
1989 test_no_file_info( GetCurrentThread() );
1991 status = pNtOpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &handle);
1992 ok(!status, "OpenProcessToken failed: %lx\n", status);
1994 test_object_name( handle, L"", FALSE );
1995 test_object_type( handle, L"Token" );
1996 test_no_file_info( handle );
1998 pNtClose(handle);
2000 handle = CreateFileA( "nul", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2001 ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
2002 test_object_name( handle, L"\\Device\\Null", TRUE );
2003 test_object_type( handle, L"File" );
2004 test_file_info( handle );
2005 pNtClose( handle );
2008 static void test_type_mismatch(void)
2010 HANDLE h;
2011 NTSTATUS res;
2012 OBJECT_ATTRIBUTES attr;
2014 attr.Length = sizeof(attr);
2015 attr.RootDirectory = 0;
2016 attr.ObjectName = NULL;
2017 attr.Attributes = 0;
2018 attr.SecurityDescriptor = NULL;
2019 attr.SecurityQualityOfService = NULL;
2021 res = pNtCreateEvent( &h, 0, &attr, NotificationEvent, 0 );
2022 ok(!res, "can't create event: %lx\n", res);
2024 res = pNtReleaseSemaphore( h, 30, NULL );
2025 ok(res == STATUS_OBJECT_TYPE_MISMATCH, "expected 0xc0000024, got %lx\n", res);
2027 pNtClose( h );
2030 static void test_null_device(void)
2032 OBJECT_ATTRIBUTES attr;
2033 IO_STATUS_BLOCK iosb;
2034 UNICODE_STRING str;
2035 NTSTATUS status;
2036 DWORD num_bytes;
2037 OVERLAPPED ov;
2038 char buf[64];
2039 HANDLE null;
2040 BOOL ret;
2042 memset(buf, 0xAA, sizeof(buf));
2043 memset(&ov, 0, sizeof(ov));
2044 ov.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
2046 RtlInitUnicodeString(&str, L"\\Device\\Null");
2047 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
2048 status = pNtOpenSymbolicLinkObject(&null, SYMBOLIC_LINK_QUERY, &attr);
2049 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
2050 "expected STATUS_OBJECT_TYPE_MISMATCH, got %08lx\n", status);
2052 status = pNtOpenFile(&null, GENERIC_READ | GENERIC_WRITE, &attr, &iosb,
2053 FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
2054 ok(status == STATUS_SUCCESS,
2055 "expected STATUS_SUCCESS, got %08lx\n", status);
2057 test_object_type(null, L"File");
2059 SetLastError(0xdeadbeef);
2060 ret = WriteFile(null, buf, sizeof(buf), &num_bytes, NULL);
2061 ok(!ret, "WriteFile unexpectedly succeeded\n");
2062 ok(GetLastError() == ERROR_INVALID_PARAMETER,
2063 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
2065 SetLastError(0xdeadbeef);
2066 ret = ReadFile(null, buf, sizeof(buf), &num_bytes, NULL);
2067 ok(!ret, "ReadFile unexpectedly succeeded\n");
2068 ok(GetLastError() == ERROR_INVALID_PARAMETER,
2069 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
2071 num_bytes = 0xdeadbeef;
2072 SetLastError(0xdeadbeef);
2073 ret = WriteFile(null, buf, sizeof(buf), &num_bytes, &ov);
2074 ok(ret, "got error %lu\n", GetLastError());
2075 ok(num_bytes == sizeof(buf), "expected num_bytes = %lu, got %lu\n",
2076 (DWORD)sizeof(buf), num_bytes);
2078 num_bytes = 0xdeadbeef;
2079 SetLastError(0xdeadbeef);
2080 ret = ReadFile(null, buf, sizeof(buf), &num_bytes, &ov);
2081 ok(!ret, "expected failure\n");
2082 ok(GetLastError() == ERROR_HANDLE_EOF, "got error %lu\n", GetLastError());
2084 pNtClose(null);
2086 null = CreateFileA("\\\\.\\Null", GENERIC_READ | GENERIC_WRITE,
2087 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2088 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2089 ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
2090 ok(GetLastError() == ERROR_FILE_NOT_FOUND,
2091 "expected ERROR_FILE_NOT_FOUND, got %lu\n", GetLastError());
2093 null = CreateFileA("\\\\.\\Device\\Null", GENERIC_READ | GENERIC_WRITE,
2094 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2095 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2096 ok(null == INVALID_HANDLE_VALUE, "CreateFileA unexpectedly succeeded\n");
2097 ok(GetLastError() == ERROR_PATH_NOT_FOUND,
2098 "expected ERROR_PATH_NOT_FOUND, got %lu\n", GetLastError());
2100 CloseHandle(ov.hEvent);
2103 static void test_process(void)
2105 OBJECT_ATTRIBUTES attr;
2106 CLIENT_ID cid;
2107 NTSTATUS status;
2108 HANDLE process;
2110 if (!pNtOpenProcess)
2112 win_skip( "NtOpenProcess not supported, skipping test\n" );
2113 return;
2116 InitializeObjectAttributes( &attr, NULL, 0, 0, NULL );
2118 cid.UniqueProcess = 0;
2119 cid.UniqueThread = 0;
2120 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, NULL, &cid );
2121 todo_wine ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcess returned %lx\n", status );
2122 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, NULL );
2123 todo_wine ok( status == STATUS_INVALID_PARAMETER_MIX, "NtOpenProcess returned %lx\n", status );
2125 cid.UniqueProcess = 0;
2126 cid.UniqueThread = 0;
2127 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2128 ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %lx\n", status );
2130 cid.UniqueProcess = ULongToHandle( 0xdeadbeef );
2131 cid.UniqueThread = ULongToHandle( 0xdeadbeef );
2132 process = (HANDLE)0xdeadbeef;
2133 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2134 ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %lx\n", status );
2135 ok( !process || broken(process == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", process );
2137 cid.UniqueProcess = ULongToHandle( GetCurrentThreadId() );
2138 cid.UniqueThread = 0;
2139 process = (HANDLE)0xdeadbeef;
2140 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2141 ok( status == STATUS_INVALID_CID, "NtOpenProcess returned %lx\n", status );
2142 ok( !process || broken(process == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", process );
2144 cid.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
2145 cid.UniqueThread = 0;
2146 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2147 ok( !status, "NtOpenProcess returned %lx\n", status );
2148 pNtClose( process );
2150 cid.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
2151 cid.UniqueThread = ULongToHandle( GetCurrentThreadId() );
2152 status = pNtOpenProcess( &process, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2153 ok( !status, "NtOpenProcess returned %lx\n", status );
2154 pNtClose( process );
2155 status = pNtOpenProcess( (HANDLE *)0xdeadbee0, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
2156 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcess returned %lx\n", status );
2159 static void test_token(void)
2161 NTSTATUS status;
2162 HANDLE handle, handle2;
2164 status = pNtOpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS, (HANDLE *)0xdeadbee0 );
2165 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcessToken failed: %lx\n", status);
2166 status = pNtOpenThreadToken( GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, (HANDLE *)0xdeadbee0 );
2167 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcessToken failed: %lx\n", status);
2168 handle = (HANDLE)0xdeadbeef;
2169 status = pNtOpenProcessToken( (HANDLE)0xdead, TOKEN_ALL_ACCESS, &handle );
2170 ok( status == STATUS_INVALID_HANDLE, "NtOpenProcessToken failed: %lx\n", status);
2171 ok( !handle || broken(handle == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", handle );
2172 handle = (HANDLE)0xdeadbeef;
2173 status = pNtOpenThreadToken( (HANDLE)0xdead, TOKEN_ALL_ACCESS, TRUE, &handle );
2174 ok( status == STATUS_INVALID_HANDLE, "NtOpenThreadToken failed: %lx\n", status);
2175 ok( !handle || broken(handle == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", handle );
2177 status = pNtOpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS, &handle );
2178 ok( status == STATUS_SUCCESS, "NtOpenProcessToken failed: %lx\n", status);
2179 status = pNtDuplicateToken( handle, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, &handle2 );
2180 ok( status == STATUS_SUCCESS, "NtOpenProcessToken failed: %lx\n", status);
2181 pNtClose( handle2 );
2182 status = pNtDuplicateToken( handle, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, (HANDLE *)0xdeadbee0 );
2183 ok( status == STATUS_ACCESS_VIOLATION, "NtOpenProcessToken failed: %lx\n", status);
2184 handle2 = (HANDLE)0xdeadbeef;
2185 status = pNtDuplicateToken( (HANDLE)0xdead, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, &handle2 );
2186 ok( status == STATUS_INVALID_HANDLE, "NtOpenProcessToken failed: %lx\n", status);
2187 ok( !handle2 || broken(handle2 == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", handle2 );
2188 pNtClose( handle );
2191 #define DEBUG_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2192 #define DEBUG_GENERIC_READ (STANDARD_RIGHTS_READ|DEBUG_READ_EVENT)
2193 #define DEBUG_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|DEBUG_PROCESS_ASSIGN)
2194 #define DESKTOP_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|DESKTOP_SWITCHDESKTOP)
2195 #define DESKTOP_GENERIC_READ (STANDARD_RIGHTS_READ|DESKTOP_ENUMERATE|DESKTOP_READOBJECTS)
2196 #define DESKTOP_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|DESKTOP_WRITEOBJECTS|DESKTOP_JOURNALPLAYBACK|\
2197 DESKTOP_JOURNALRECORD|DESKTOP_HOOKCONTROL|DESKTOP_CREATEMENU| \
2198 DESKTOP_CREATEWINDOW)
2199 #define DIRECTORY_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|DIRECTORY_TRAVERSE|DIRECTORY_QUERY)
2200 #define DIRECTORY_GENERIC_READ (STANDARD_RIGHTS_READ|DIRECTORY_TRAVERSE|DIRECTORY_QUERY)
2201 #define DIRECTORY_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|DIRECTORY_CREATE_SUBDIRECTORY|\
2202 DIRECTORY_CREATE_OBJECT)
2203 #define EVENT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2204 #define EVENT_GENERIC_READ (STANDARD_RIGHTS_READ|EVENT_QUERY_STATE)
2205 #define EVENT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|EVENT_MODIFY_STATE)
2206 #define IO_COMPLETION_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2207 #define IO_COMPLETION_GENERIC_READ (STANDARD_RIGHTS_READ|IO_COMPLETION_QUERY_STATE)
2208 #define IO_COMPLETION_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|IO_COMPLETION_MODIFY_STATE)
2209 #define JOB_OBJECT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2210 #define JOB_OBJECT_GENERIC_READ (STANDARD_RIGHTS_READ|JOB_OBJECT_QUERY)
2211 #define JOB_OBJECT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|JOB_OBJECT_TERMINATE|\
2212 JOB_OBJECT_SET_ATTRIBUTES|JOB_OBJECT_ASSIGN_PROCESS)
2213 #define KEY_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|KEY_CREATE_LINK|KEY_NOTIFY|\
2214 KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE)
2215 #define KEY_GENERIC_READ (STANDARD_RIGHTS_READ|KEY_NOTIFY|KEY_ENUMERATE_SUB_KEYS|\
2216 KEY_QUERY_VALUE)
2217 #define KEY_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|KEY_CREATE_SUB_KEY|KEY_SET_VALUE)
2218 #define KEYEDEVENT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE)
2219 #define KEYEDEVENT_GENERIC_READ (STANDARD_RIGHTS_READ|KEYEDEVENT_WAIT)
2220 #define KEYEDEVENT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|KEYEDEVENT_WAKE)
2221 #define MUTANT_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2222 #define MUTANT_GENERIC_READ (STANDARD_RIGHTS_READ|MUTANT_QUERY_STATE)
2223 #define MUTANT_GENERIC_WRITE (STANDARD_RIGHTS_WRITE)
2224 #define PROCESS_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE|\
2225 PROCESS_QUERY_LIMITED_INFORMATION|PROCESS_TERMINATE)
2226 #define PROCESS_GENERIC_READ (STANDARD_RIGHTS_READ|PROCESS_VM_READ|PROCESS_QUERY_INFORMATION)
2227 #define PROCESS_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|PROCESS_SUSPEND_RESUME|\
2228 PROCESS_SET_INFORMATION|PROCESS_SET_QUOTA|PROCESS_CREATE_PROCESS|\
2229 PROCESS_DUP_HANDLE|PROCESS_VM_WRITE|PROCESS_VM_OPERATION|\
2230 PROCESS_CREATE_THREAD)
2231 #define SECTION_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SECTION_MAP_EXECUTE)
2232 #define SECTION_GENERIC_READ (STANDARD_RIGHTS_READ|SECTION_QUERY|SECTION_MAP_READ)
2233 #define SECTION_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|SECTION_MAP_WRITE)
2234 #define SEMAPHORE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2235 #define SEMAPHORE_GENERIC_READ (STANDARD_RIGHTS_READ|SEMAPHORE_QUERY_STATE)
2236 #define SEMAPHORE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|SEMAPHORE_MODIFY_STATE)
2237 #define SYMBOLIC_LINK_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYMBOLIC_LINK_QUERY)
2238 #define SYMBOLIC_LINK_GENERIC_READ (STANDARD_RIGHTS_READ|SYMBOLIC_LINK_QUERY)
2239 #define SYMBOLIC_LINK_GENERIC_WRITE (STANDARD_RIGHTS_WRITE)
2240 #define THREAD_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE|THREAD_RESUME|\
2241 THREAD_QUERY_LIMITED_INFORMATION)
2242 #define THREAD_GENERIC_READ (STANDARD_RIGHTS_READ|THREAD_QUERY_INFORMATION|THREAD_GET_CONTEXT)
2243 #define THREAD_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|THREAD_SET_LIMITED_INFORMATION|\
2244 THREAD_SET_INFORMATION|THREAD_SET_CONTEXT|THREAD_SUSPEND_RESUME|\
2245 THREAD_TERMINATE|0x04)
2246 #define TIMER_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE)
2247 #define TIMER_GENERIC_READ (STANDARD_RIGHTS_READ|TIMER_QUERY_STATE)
2248 #define TIMER_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|TIMER_MODIFY_STATE)
2249 #define TOKEN_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|TOKEN_IMPERSONATE|TOKEN_ASSIGN_PRIMARY)
2250 #define TOKEN_GENERIC_READ (STANDARD_RIGHTS_READ|TOKEN_QUERY_SOURCE|TOKEN_QUERY|TOKEN_DUPLICATE)
2251 #define TOKEN_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|TOKEN_ADJUST_SESSIONID|TOKEN_ADJUST_DEFAULT|\
2252 TOKEN_ADJUST_GROUPS|TOKEN_ADJUST_PRIVILEGES)
2253 #define TYPE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE)
2254 #define TYPE_GENERIC_READ (STANDARD_RIGHTS_READ)
2255 #define TYPE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE)
2256 #define WINSTA_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|WINSTA_EXITWINDOWS|WINSTA_ACCESSGLOBALATOMS)
2257 #define WINSTA_GENERIC_READ (STANDARD_RIGHTS_READ|WINSTA_READSCREEN|WINSTA_ENUMERATE|\
2258 WINSTA_READATTRIBUTES|WINSTA_ENUMDESKTOPS)
2259 #define WINSTA_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|WINSTA_WRITEATTRIBUTES|WINSTA_CREATEDESKTOP|\
2260 WINSTA_ACCESSCLIPBOARD)
2262 #undef WINSTA_ALL_ACCESS
2263 #undef DESKTOP_ALL_ACCESS
2264 #define WINSTA_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x37f)
2265 #define DESKTOP_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x1ff)
2266 #define DEVICE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1ff)
2267 #define TYPE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x1)
2269 static void *align_ptr( void *ptr )
2271 ULONG_PTR align = sizeof(DWORD_PTR) - 1;
2272 return (void *)(((DWORD_PTR)ptr + align) & ~align);
2275 static void test_duplicate_object(void)
2277 NTSTATUS status;
2278 HANDLE handle;
2280 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2281 &handle, PROCESS_ALL_ACCESS, 0, 0 );
2282 ok( !status, "NtDuplicateObject failed %lx\n", status );
2283 pNtClose( handle );
2284 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2285 NULL, PROCESS_ALL_ACCESS, 0, 0 );
2286 ok( !status, "NtDuplicateObject failed %lx\n", status );
2288 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2289 (HANDLE *)0xdeadbee0, PROCESS_ALL_ACCESS, 0, 0 );
2290 ok( status == STATUS_ACCESS_VIOLATION, "NtDuplicateObject failed %lx\n", status );
2292 handle = (HANDLE)0xdeadbeef;
2293 status = pNtDuplicateObject( GetCurrentProcess(), (HANDLE)0xdead, GetCurrentProcess(),
2294 &handle, PROCESS_ALL_ACCESS, 0, 0 );
2295 ok( status == STATUS_INVALID_HANDLE, "NtDuplicateObject failed %lx\n", status );
2296 ok( !handle, "handle set %p\n", handle );
2298 handle = (HANDLE)0xdeadbeef;
2299 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2300 &handle, ~0u, 0, 0 );
2301 todo_wine
2302 ok( status == STATUS_ACCESS_DENIED, "NtDuplicateObject failed %lx\n", status );
2303 todo_wine
2304 ok( !handle, "handle set %p\n", handle );
2305 if (!status) pNtClose( handle );
2308 static void test_object_types(void)
2310 static const struct { const WCHAR *name; GENERIC_MAPPING mapping; ULONG mask, broken; } tests[] =
2312 #define TYPE(name,gen,extra,broken) { name, { gen ## _GENERIC_READ, gen ## _GENERIC_WRITE, \
2313 gen ## _GENERIC_EXECUTE, gen ## _ALL_ACCESS }, gen ## _ALL_ACCESS | extra, broken }
2314 TYPE( L"DebugObject", DEBUG, 0, 0 ),
2315 TYPE( L"Desktop", DESKTOP, 0, 0 ),
2316 TYPE( L"Device", FILE, 0, 0 ),
2317 TYPE( L"Directory", DIRECTORY, 0, 0 ),
2318 TYPE( L"Event", EVENT, 0, 0 ),
2319 TYPE( L"File", FILE, 0, 0 ),
2320 TYPE( L"IoCompletion", IO_COMPLETION, 0, 0 ),
2321 TYPE( L"Job", JOB_OBJECT, 0, JOB_OBJECT_IMPERSONATE ),
2322 TYPE( L"Key", KEY, SYNCHRONIZE, 0 ),
2323 TYPE( L"KeyedEvent", KEYEDEVENT, SYNCHRONIZE, 0 ),
2324 TYPE( L"Mutant", MUTANT, 0, 0 ),
2325 TYPE( L"Process", PROCESS, 0, 0 ),
2326 TYPE( L"Section", SECTION, SYNCHRONIZE, 0 ),
2327 TYPE( L"Semaphore", SEMAPHORE, 0, 0 ),
2328 TYPE( L"SymbolicLink", SYMBOLIC_LINK, 0, 0xfffe ),
2329 TYPE( L"Thread", THREAD, 0, THREAD_RESUME ),
2330 TYPE( L"Timer", TIMER, 0, 0 ),
2331 TYPE( L"Token", TOKEN, SYNCHRONIZE, 0 ),
2332 TYPE( L"Type", TYPE, SYNCHRONIZE, 0 ),
2333 TYPE( L"WindowStation", WINSTA, 0, 0 ),
2334 #undef TYPE
2336 unsigned int i, j;
2337 BOOLEAN tested[ARRAY_SIZE(all_types)] = { 0 };
2338 char buffer[256];
2339 OBJECT_TYPES_INFORMATION *info = (OBJECT_TYPES_INFORMATION *)buffer;
2340 GENERIC_MAPPING map;
2341 NTSTATUS status;
2342 ULONG len, retlen;
2344 memset( buffer, 0xcc, sizeof(buffer) );
2345 status = pNtQueryObject( NULL, ObjectTypesInformation, info, sizeof(buffer), &len );
2346 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %lx\n", status );
2347 ok( info->NumberOfTypes < 100 || info->NumberOfTypes == 0xcccccccc, /* wow64 */
2348 "wrong number of types %lu\n", info->NumberOfTypes );
2350 info = malloc( len + 16 ); /* Windows gets the length wrong on WoW64 and overflows the buffer */
2351 memset( info, 0xcc, sizeof(*info) );
2352 status = pNtQueryObject( NULL, ObjectTypesInformation, info, len, &retlen );
2353 ok( retlen <= len + 16, "wrong len %lx/%lx\n", len, retlen );
2354 ok( len == retlen || broken( retlen >= len - 32 && retlen <= len + 32 ), /* wow64 */
2355 "wrong len %lx/%lx\n", len, retlen );
2356 ok( !status, "NtQueryObject failed %lx\n", status );
2357 if (!status)
2359 OBJECT_TYPE_INFORMATION *type = align_ptr( info + 1 );
2360 for (i = 0; i < info->NumberOfTypes; i++)
2362 add_object_type( type );
2363 type = align_ptr( (char *)type->TypeName.Buffer + type->TypeName.MaximumLength );
2366 free( info );
2368 for (i = 0; i < ARRAY_SIZE(tests); i++)
2370 for (j = 0; j < ARRAY_SIZE(all_types); j++)
2372 if (!all_types[j].TypeName.Buffer) continue;
2373 if (wcscmp( tests[i].name, all_types[j].TypeName.Buffer )) continue;
2374 map = all_types[j].GenericMapping;
2375 ok( !memcmp( &map, &tests[i].mapping, sizeof(GENERIC_MAPPING) ) ||
2376 broken( !((map.GenericRead ^ tests[i].mapping.GenericRead) & ~tests[i].broken) &&
2377 !((map.GenericWrite ^ tests[i].mapping.GenericWrite) & ~tests[i].broken) &&
2378 !((map.GenericExecute ^ tests[i].mapping.GenericExecute) & ~tests[i].broken) &&
2379 !((map.GenericAll ^ tests[i].mapping.GenericAll) & ~tests[i].broken) ),
2380 "%s: mismatched mappings %08lx,%08lx,%08lx,%08lx / %08lx,%08lx,%08lx,%08lx\n",
2381 debugstr_w( tests[i].name ),
2382 all_types[j].GenericMapping.GenericRead, all_types[j].GenericMapping.GenericWrite,
2383 all_types[j].GenericMapping.GenericExecute, all_types[j].GenericMapping.GenericAll,
2384 tests[i].mapping.GenericRead, tests[i].mapping.GenericWrite,
2385 tests[i].mapping.GenericExecute, tests[i].mapping.GenericAll );
2386 ok( all_types[j].ValidAccessMask == tests[i].mask ||
2387 broken( !((all_types[j].ValidAccessMask ^ tests[i].mask) & ~tests[i].broken) ),
2388 "%s: mismatched access mask %08lx / %08lx\n", debugstr_w( tests[i].name ),
2389 all_types[j].ValidAccessMask, tests[i].mask );
2390 tested[j] = TRUE;
2391 break;
2393 ok( j < ARRAY_SIZE(all_types), "type %s not found\n", debugstr_w(tests[i].name) );
2395 for (j = 0; j < ARRAY_SIZE(all_types); j++)
2397 if (!all_types[j].TypeName.Buffer) continue;
2398 if (tested[j]) continue;
2399 trace( "not tested: %s\n", debugstr_w(all_types[j].TypeName.Buffer ));
2403 static DWORD WINAPI test_get_next_thread_proc( void *arg )
2405 HANDLE event = (HANDLE)arg;
2407 WaitForSingleObject(event, INFINITE);
2408 return 0;
2411 static void test_get_next_thread(void)
2413 HANDLE hprocess = GetCurrentProcess();
2414 HANDLE handle, thread, event, prev;
2415 NTSTATUS status;
2416 DWORD thread_id;
2417 BOOL found;
2419 if (!pNtGetNextThread)
2421 win_skip("NtGetNextThread is not available.\n");
2422 return;
2425 event = CreateEventA(NULL, FALSE, FALSE, NULL);
2427 thread = CreateThread( NULL, 0, test_get_next_thread_proc, event, 0, &thread_id );
2429 status = pNtGetNextThread(hprocess, NULL, THREAD_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, NULL);
2430 ok(status == STATUS_ACCESS_VIOLATION, "Got unexpected status %#lx.\n", status);
2432 found = FALSE;
2433 prev = NULL;
2434 while (!(status = pNtGetNextThread(hprocess, prev, THREAD_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle)))
2436 if (prev)
2438 if (GetThreadId(handle) == thread_id)
2439 found = TRUE;
2440 pNtClose(prev);
2442 else
2444 ok(GetThreadId(handle) == GetCurrentThreadId(), "Got unexpected thread id %04lx, current %04lx.\n",
2445 GetThreadId(handle), GetCurrentThreadId());
2447 prev = handle;
2448 handle = (HANDLE)0xdeadbeef;
2450 pNtClose(prev);
2451 ok(!handle, "Got unexpected handle %p.\n", handle);
2452 ok(status == STATUS_NO_MORE_ENTRIES, "Unexpected status %#lx.\n", status);
2453 ok(found, "Thread not found.\n");
2455 handle = (HANDLE)0xdeadbeef;
2456 status = pNtGetNextThread((void *)0xdeadbeef, 0, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle);
2457 ok(status == STATUS_INVALID_HANDLE, "Unexpected status %#lx.\n", status);
2458 ok(!handle, "Got unexpected handle %p.\n", handle);
2459 handle = (HANDLE)0xdeadbeef;
2460 status = pNtGetNextThread(hprocess, (void *)0xdeadbeef, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle);
2461 ok(status == STATUS_INVALID_HANDLE, "Unexpected status %#lx.\n", status);
2462 ok(!handle, "Got unexpected handle %p.\n", handle);
2464 /* Reversed search is only supported on recent enough Win10. */
2465 status = pNtGetNextThread(hprocess, 0, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 1, &handle);
2466 ok(!status || broken(status == STATUS_INVALID_PARAMETER), "Unexpected status %#lx.\n", status);
2467 if (!status)
2468 pNtClose(handle);
2470 status = pNtGetNextThread(hprocess, 0, PROCESS_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 2, &handle);
2471 ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %#lx.\n", status);
2473 SetEvent(event);
2474 WaitForSingleObject(thread, INFINITE);
2476 found = FALSE;
2477 prev = NULL;
2478 while (!(status = pNtGetNextThread(hprocess, prev, THREAD_QUERY_LIMITED_INFORMATION, OBJ_INHERIT, 0, &handle)))
2480 if (prev)
2481 pNtClose(prev);
2482 if (GetThreadId(handle) == thread_id)
2483 found = TRUE;
2484 prev = handle;
2486 pNtClose(prev);
2487 ok(found, "Thread not found.\n");
2489 CloseHandle(thread);
2492 static void test_globalroot(void)
2494 NTSTATUS status;
2495 IO_STATUS_BLOCK iosb;
2496 UNICODE_STRING str;
2497 OBJECT_ATTRIBUTES attr;
2498 HANDLE h;
2499 WCHAR buffer[256];
2500 ULONG len, full_len, i;
2501 static const struct { const WCHAR *name, *target; } symlinks[] = {
2502 { L"\\??\\GLOBALROOT", L"" },
2503 { L"\\??\\GLOBALROOT\\??\\GLOBALROOT", L"" },
2504 { L"\\??\\GLOBALROOT\\??\\GLOBALROOT\\??\\GLOBALROOT", L"" },
2505 { L"\\??\\GLOBALROOT\\DosDevices", L"\\??" },
2506 { L"\\??\\GLOBALROOT\\BaseNamedObjects\\Global", NULL },
2509 for (i = 0; i < ARRAY_SIZE(symlinks); i++)
2511 pRtlInitUnicodeString(&str, symlinks[i].name);
2512 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
2513 status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
2514 ok(status == STATUS_SUCCESS, "NtOpenSymbolicLinkObject failed %08lx\n", status);
2516 str.Buffer = buffer;
2517 str.MaximumLength = sizeof(buffer);
2518 len = 0xdeadbeef;
2519 memset( buffer, 0xaa, sizeof(buffer) );
2520 status = pNtQuerySymbolicLinkObject( h, &str, &len);
2521 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08lx\n", status );
2522 full_len = str.Length + sizeof(WCHAR);
2523 ok( len == full_len, "bad length %lu (expected %lu)\n", len, full_len );
2524 ok( buffer[len / sizeof(WCHAR) - 1] == 0, "no terminating null\n" );
2526 if (symlinks[i].target)
2528 ok( compare_unicode_string( &str, symlinks[i].target ),
2529 "symlink %s: target expected %s, got %s\n",
2530 debugstr_w( symlinks[i].name ),
2531 debugstr_w( symlinks[i].target ),
2532 debugstr_w( str.Buffer ) );
2535 pNtClose(h);
2538 pRtlInitUnicodeString(&str, L"\\??\\GLOBALROOT\\Device\\Null");
2539 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
2540 status = pNtOpenFile(&h, GENERIC_READ | GENERIC_WRITE, &attr, &iosb,
2541 FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
2542 ok(status == STATUS_SUCCESS,
2543 "expected STATUS_SUCCESS, got %08lx\n", status);
2545 test_object_type(h, L"File");
2547 pNtClose(h);
2550 static void test_object_identity(void)
2552 NTSTATUS status;
2553 HANDLE h1, h2;
2555 if (!pNtCompareObjects)
2557 win_skip("NtCompareObjects is not available.\n");
2558 return;
2561 status = pNtCompareObjects( GetCurrentProcess(), GetCurrentProcess() );
2562 ok( status == STATUS_SUCCESS, "comparing GetCurrentProcess() to self failed with %08lx\n", status );
2564 status = pNtCompareObjects( GetCurrentThread(), GetCurrentThread() );
2565 ok( status == STATUS_SUCCESS, "comparing GetCurrentThread() to self failed with %08lx\n", status );
2567 status = pNtCompareObjects( GetCurrentProcess(), GetCurrentThread() );
2568 ok( status == STATUS_NOT_SAME_OBJECT, "comparing GetCurrentProcess() to GetCurrentThread() returned %08lx\n", status );
2570 h1 = NULL;
2571 status = pNtDuplicateObject( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
2572 &h1, 0, 0, DUPLICATE_SAME_ACCESS );
2573 ok( status == STATUS_SUCCESS, "failed to duplicate current process handle: %08lx\n", status);
2575 status = pNtCompareObjects( GetCurrentProcess(), h1 );
2576 ok( status == STATUS_SUCCESS, "comparing GetCurrentProcess() with %p failed with %08lx\n", h1, status );
2578 pNtClose( h1 );
2580 h1 = CreateFileA( "\\\\.\\NUL", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
2581 ok( h1 != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
2583 h2 = NULL;
2584 status = pNtDuplicateObject( GetCurrentProcess(), h1, GetCurrentProcess(),
2585 &h2, 0, 0, DUPLICATE_SAME_ACCESS );
2586 ok( status == STATUS_SUCCESS, "failed to duplicate handle %p: %08lx\n", h1, status);
2588 status = pNtCompareObjects( h1, h2 );
2589 ok( status == STATUS_SUCCESS, "comparing %p with %p failed with %08lx\n", h1, h2, status );
2591 pNtClose( h2 );
2593 h2 = CreateFileA( "\\\\.\\NUL", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
2594 ok( h2 != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError() );
2596 status = pNtCompareObjects( h1, h2 );
2597 ok( status == STATUS_NOT_SAME_OBJECT, "comparing %p with %p returned %08lx\n", h1, h2, status );
2599 pNtClose( h2 );
2600 pNtClose( h1 );
2603 static void test_query_directory(void)
2605 static const DIRECTORY_BASIC_INFORMATION empty_info;
2606 char buffer[200];
2607 DIRECTORY_BASIC_INFORMATION *info = (void *)buffer;
2608 ULONG context, size, needed_size;
2609 const WCHAR *name1, *name2;
2610 HANDLE dir, child1, child2;
2611 OBJECT_ATTRIBUTES attr;
2612 UNICODE_STRING string;
2613 NTSTATUS status;
2614 BOOL is_wow64 = FALSE;
2616 #ifndef _WIN64
2617 if (!IsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
2618 #endif
2620 RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest" );
2621 InitializeObjectAttributes( &attr, &string, 0, 0, NULL );
2622 status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
2623 ok( !status, "got %#lx\n", status );
2625 context = 0xdeadbeef;
2626 size = 0xdeadbeef;
2627 status = NtQueryDirectoryObject( dir, info, 0, TRUE, TRUE, &context, &size );
2628 ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2629 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2630 ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2632 context = 0xdeadbeef;
2633 size = 0xdeadbeef;
2634 status = NtQueryDirectoryObject( dir, info, 0, FALSE, TRUE, &context, &size );
2635 ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2636 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2637 ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2639 context = 0xdeadbeef;
2640 size = 0xdeadbeef;
2641 memset( buffer, 0xcc, sizeof(buffer) );
2642 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2643 ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2644 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2645 ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2646 if (size == sizeof(*info))
2647 ok( !memcmp( &info[0], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2649 context = 0xdeadbeef;
2650 size = 0xdeadbeef;
2651 memset( buffer, 0xcc, sizeof(buffer) );
2652 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), FALSE, TRUE, &context, &size );
2653 ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2654 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2655 ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2656 if (size == sizeof(*info))
2657 ok( !memcmp( &info[0], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2659 RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest\\Telamon" );
2660 status = NtCreateMutant( &child1, GENERIC_ALL, &attr, FALSE );
2661 ok( !status, "got %#lx\n", status );
2663 RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest\\Oileus" );
2664 status = NtCreateMutant( &child2, GENERIC_ALL, &attr, FALSE );
2665 ok( !status, "got %#lx\n", status );
2667 context = 0xdeadbeef;
2668 size = 0xdeadbeef;
2669 status = NtQueryDirectoryObject( NULL, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2670 ok( status == STATUS_INVALID_HANDLE, "got %#lx\n", status );
2671 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2672 ok( size == 0xdeadbeef || broken(!size) /* WoW64 */, "got size %lu\n", size);
2674 size = 0xdeadbeef;
2675 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, NULL, &size );
2676 ok( status == STATUS_ACCESS_VIOLATION, "got %#lx\n", status );
2677 ok( size == 0xdeadbeef, "got size %lu\n", size);
2679 context = 0xdeadbeef;
2680 size = 0xdeadbeef;
2681 memset( buffer, 0xcc, sizeof(buffer) );
2682 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2683 ok( !status, "got %#lx\n", status );
2684 ok( context == 1, "got context %#lx\n", context );
2685 ok( size && size < sizeof(buffer), "got size %lu\n", size );
2686 if (!wcscmp( info[0].ObjectName.Buffer, L"Oileus" ))
2688 name1 = L"Oileus";
2689 name2 = L"Telamon";
2691 else
2693 name1 = L"Telamon";
2694 name2 = L"Oileus";
2696 check_unicode_string( &info[0].ObjectName, name1 );
2697 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2698 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2700 memset( buffer, 0xcc, sizeof(buffer) );
2701 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
2702 ok( !status, "got %#lx\n", status );
2703 ok( context == 2, "got context %#lx\n", context );
2704 check_unicode_string( &info[0].ObjectName, name2 );
2705 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2706 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2708 size = 0xdeadbeef;
2709 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
2710 ok( status == STATUS_NO_MORE_ENTRIES, "got %#lx\n", status );
2711 ok( context == 2, "got context %#lx\n", context );
2712 ok( size == sizeof(*info) || (is_wow64 && !size), "got size %lu\n", size );
2714 memset( buffer, 0xcc, sizeof(buffer) );
2715 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
2716 ok( !status, "got %#lx\n", status );
2717 ok( context == 1, "got context %#lx\n", context );
2718 check_unicode_string( &info[0].ObjectName, name1 );
2719 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2720 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2722 needed_size = size;
2724 size = 0xdeadbeef;
2725 context = 0xdeadbeef;
2726 status = NtQueryDirectoryObject( dir, info, 0, TRUE, TRUE, &context, &size );
2727 ok( status == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", status );
2728 ok( context == 0xdeadbeef, "got context %#lx\n", context );
2729 ok( size == needed_size, "expected size %lu, got %lu\n", needed_size, size );
2731 size = 0xdeadbeef;
2732 memset( buffer, 0xcc, sizeof(buffer) );
2733 status = NtQueryDirectoryObject( dir, info, needed_size - 1, TRUE, TRUE, &context, &size );
2734 ok( status == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", status );
2735 ok( size == needed_size, "expected size %lu, got %lu\n", needed_size, size );
2737 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, NULL );
2738 ok( !status, "got %#lx\n", status );
2740 context = 0;
2741 memset( buffer, 0xcc, sizeof(buffer) );
2742 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
2743 ok( !status, "got %#lx\n", status );
2744 ok( context == 1, "got context %#lx\n", context );
2745 check_unicode_string( &info[0].ObjectName, name1 );
2746 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2747 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2749 memset( buffer, 0xcc, sizeof(buffer) );
2750 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), FALSE, TRUE, &context, &size );
2751 ok( !status, "got %#lx\n", status );
2752 ok( context == 2, "got context %#lx\n", context );
2753 check_unicode_string( &info[0].ObjectName, name1 );
2754 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2755 check_unicode_string( &info[1].ObjectName, name2 );
2756 check_unicode_string( &info[1].ObjectTypeName, L"Mutant" );
2757 ok( !memcmp( &info[2], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2759 needed_size = size;
2760 size = 0xdeadbeef;
2761 context = 0xdeadbeef;
2762 memset( buffer, 0xcc, sizeof(buffer) );
2763 status = NtQueryDirectoryObject( dir, info, needed_size - 1, FALSE, TRUE, &context, &size );
2764 ok( status == STATUS_MORE_ENTRIES, "got %#lx\n", status );
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" );
2771 size = 0xdeadbeef;
2772 context = 0xdeadbeef;
2773 memset( buffer, 0xcc, sizeof(buffer) );
2774 status = NtQueryDirectoryObject( dir, info, sizeof(*info), FALSE, TRUE, &context, &size );
2775 ok( status == STATUS_MORE_ENTRIES
2776 || broken(status == STATUS_BUFFER_TOO_SMALL) /* wow64 */, "got %#lx\n", status );
2777 if (status == STATUS_MORE_ENTRIES)
2779 ok( !context, "got context %#lx\n", context );
2780 ok( size == sizeof(*info), "got size %lu\n", size );
2781 ok( !memcmp( &info[0], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2784 size = 0xdeadbeef;
2785 context = 0xdeadbeef;
2786 status = NtQueryDirectoryObject( dir, info, 0, FALSE, TRUE, &context, &size );
2787 ok( status == STATUS_MORE_ENTRIES
2788 || broken(status == STATUS_BUFFER_TOO_SMALL) /* wow64 */, "got %#lx\n", status );
2789 if (status == STATUS_MORE_ENTRIES)
2791 ok( !context, "got context %#lx\n", context );
2792 ok( size == sizeof(*info), "got size %lu\n", size );
2795 context = 1;
2796 memset( buffer, 0xcc, sizeof(buffer) );
2797 status = NtQueryDirectoryObject( dir, info, sizeof(buffer), FALSE, FALSE, &context, &size );
2798 ok( !status, "got %#lx\n", status );
2799 ok( context == 2, "got context %#lx\n", context );
2800 check_unicode_string( &info[0].ObjectName, name2 );
2801 check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
2802 ok( !memcmp( &info[1], &empty_info, sizeof(*info) ), "entry was not cleared\n" );
2804 pNtClose( child1 );
2805 pNtClose( child2 );
2806 pNtClose( dir );
2809 #define test_object_name_with_null(a,b) _test_object_name_with_null(__LINE__,a,b)
2810 static void _test_object_name_with_null(unsigned line, HANDLE handle, UNICODE_STRING *expect)
2812 char buffer[1024];
2813 UNICODE_STRING *str = (UNICODE_STRING *)buffer;
2814 ULONG len = 0;
2815 NTSTATUS status;
2817 memset(buffer, 0, sizeof(buffer));
2818 status = pNtQueryObject(handle, ObjectNameInformation, buffer, sizeof(buffer), &len);
2819 ok_(__FILE__,line)(status == STATUS_SUCCESS, "got %08lx\n", status);
2820 ok_(__FILE__,line)(len >= sizeof(OBJECT_NAME_INFORMATION) + str->Length, "got %lu\n", len);
2821 ok_(__FILE__,line)(str->Length == expect->Length, "got %u, expected %u\n", str->Length, expect->Length);
2822 ok_(__FILE__,line)(!wcsnicmp(str->Buffer, expect->Buffer, str->Length/sizeof(WCHAR)), "got %s, expected %s\n",
2823 debugstr_w(str->Buffer), debugstr_w(expect->Buffer));
2826 static void test_null_in_object_name(void)
2828 WCHAR name[256], name3[256], *p, *name_exp, *name3_exp;
2829 HANDLE handle, handle2;
2830 NTSTATUS status;
2831 OBJECT_ATTRIBUTES attr, attr2, attr3;
2832 UNICODE_STRING nameU, name2U, name3U, name2U_exp, name3U_exp;
2833 LARGE_INTEGER size;
2834 #ifndef _WIN64
2835 BOOL is_wow64 = FALSE;
2836 #endif
2838 trace("running as %d bit\n", (int)sizeof(void *) * 8);
2840 swprintf(name, ARRAY_SIZE(name), L"\\Sessions\\%u\\BaseNamedObjects\\wine_test", NtCurrentTeb()->Peb->SessionId);
2841 swprintf(name3, ARRAY_SIZE(name3), L"\\Sessions\\%u\\BaseNamedObjects\\wine_test", NtCurrentTeb()->Peb->SessionId);
2842 p = wcsrchr(name3, '\\');
2843 p[5] = 0; /* => \\wine\0test */
2845 RtlInitUnicodeString(&nameU, name);
2846 InitializeObjectAttributes(&attr, &nameU, 0, 0, NULL);
2848 name2U = nameU;
2849 name2U.Length += sizeof(WCHAR); /* add terminating \0 to string length */
2850 InitializeObjectAttributes(&attr2, &name2U, 0, 0, NULL);
2852 name3U = nameU;
2853 name3U.Buffer = name3;
2854 InitializeObjectAttributes(&attr3, &name3U, 0, 0, NULL);
2856 status = pNtCreateEvent(&handle, GENERIC_ALL, &attr, NotificationEvent, FALSE);
2857 ok(!status, "got %08lx\n", status);
2858 test_object_name(handle, name, FALSE);
2859 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr);
2860 ok(!status, "got %08lx\n", status);
2861 test_object_name(handle2, name, FALSE);
2862 pNtClose(handle2);
2863 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr2);
2864 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2865 pNtClose(handle);
2866 status = pNtCreateEvent(&handle, GENERIC_ALL, &attr2, NotificationEvent, FALSE);
2867 ok(!status, "got %08lx\n", status);
2868 test_object_name_with_null(handle, &name2U);
2869 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr2);
2870 ok(!status, "got %08lx\n", status);
2871 test_object_name_with_null(handle2, &name2U);
2872 pNtClose(handle2);
2873 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr);
2874 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2875 pNtClose(handle);
2876 status = pNtCreateEvent(&handle, GENERIC_ALL, &attr3, NotificationEvent, FALSE);
2877 ok(!status, "got %08lx\n", status);
2878 test_object_name_with_null(handle, &name3U);
2879 status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr3);
2880 ok(!status, "got %08lx\n", status);
2881 test_object_name_with_null(handle2, &name3U);
2882 pNtClose(handle2);
2883 pNtClose(handle);
2885 status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr, 0);
2886 ok(!status, "got %08lx\n", status);
2887 test_object_name(handle, name, FALSE);
2888 pNtClose(handle);
2889 status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr2, 0);
2890 ok(!status, "got %08lx\n", status);
2891 test_object_name_with_null(handle, &name2U);
2892 pNtClose(handle);
2893 status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr3, 0);
2894 ok(!status, "got %08lx\n", status);
2895 test_object_name_with_null(handle, &name3U);
2896 pNtClose(handle);
2898 status = pNtCreateMutant(&handle, GENERIC_ALL, &attr, 0);
2899 ok(!status, "got %08lx\n", status);
2900 test_object_name(handle, name, FALSE);
2901 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr);
2902 ok(!status, "got %08lx\n", status);
2903 test_object_name(handle2, name, FALSE);
2904 pNtClose(handle2);
2905 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr2);
2906 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2907 pNtClose(handle);
2908 status = pNtCreateMutant(&handle, GENERIC_ALL, &attr2, 0);
2909 ok(!status, "got %08lx\n", status);
2910 test_object_name_with_null(handle, &name2U);
2911 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr2);
2912 ok(!status, "got %08lx\n", status);
2913 test_object_name_with_null(handle2, &name2U);
2914 pNtClose(handle2);
2915 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr);
2916 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2917 pNtClose(handle);
2918 status = pNtCreateMutant(&handle, GENERIC_ALL, &attr3, 0);
2919 ok(!status, "got %08lx\n", status);
2920 test_object_name_with_null(handle, &name3U);
2921 status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr3);
2922 ok(!status, "got %08lx\n", status);
2923 test_object_name_with_null(handle2, &name3U);
2924 pNtClose(handle2);
2925 pNtClose(handle);
2927 status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr, 1, 2);
2928 ok(!status, "got %08lx\n", status);
2929 test_object_name(handle, name, FALSE);
2930 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr);
2931 ok(!status, "got %08lx\n", status);
2932 test_object_name(handle2, name, FALSE);
2933 pNtClose(handle2);
2934 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr2);
2935 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2936 pNtClose(handle);
2937 status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr2, 1, 2);
2938 ok(!status, "got %08lx\n", status);
2939 test_object_name_with_null(handle, &name2U);
2940 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr2);
2941 ok(!status, "got %08lx\n", status);
2942 test_object_name_with_null(handle2, &name2U);
2943 pNtClose(handle2);
2944 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr);
2945 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2946 pNtClose(handle);
2947 status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr3, 1, 2);
2948 ok(!status, "got %08lx\n", status);
2949 test_object_name_with_null(handle, &name3U);
2950 status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr3);
2951 ok(!status, "got %08lx\n", status);
2952 test_object_name_with_null(handle2, &name3U);
2953 pNtClose(handle2);
2954 pNtClose(handle);
2956 status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr, 0);
2957 ok(!status, "got %08lx\n", status);
2958 test_object_name(handle, name, FALSE);
2959 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr);
2960 ok(!status, "got %08lx\n", status);
2961 test_object_name(handle2, name, FALSE);
2962 pNtClose(handle2);
2963 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr2);
2964 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2965 pNtClose(handle);
2966 status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr2, 0);
2967 ok(!status, "got %08lx\n", status);
2968 test_object_name_with_null(handle, &name2U);
2969 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr2);
2970 ok(!status, "got %08lx\n", status);
2971 test_object_name_with_null(handle2, &name2U);
2972 pNtClose(handle2);
2973 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr);
2974 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
2975 pNtClose(handle);
2976 status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr3, 0);
2977 ok(!status, "got %08lx\n", status);
2978 test_object_name_with_null(handle, &name3U);
2979 status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr3);
2980 ok(!status, "got %08lx\n", status);
2981 test_object_name_with_null(handle2, &name3U);
2982 pNtClose(handle2);
2983 pNtClose(handle);
2985 status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr, 0);
2986 ok(!status, "got %08lx\n", status);
2987 test_object_name(handle, name, FALSE);
2988 status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr);
2989 ok(!status, "got %08lx\n", status);
2990 test_object_name(handle2, name, FALSE);
2991 pNtClose(handle2);
2992 pNtClose(handle);
2993 status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr2, 0);
2994 ok(!status, "got %08lx\n", status);
2995 test_object_name_with_null(handle, &name2U);
2996 status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr2);
2997 ok(!status, "got %08lx\n", status);
2998 test_object_name_with_null(handle2, &name2U);
2999 pNtClose(handle2);
3000 pNtClose(handle);
3001 status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr3, 0);
3002 ok(!status, "got %08lx\n", status);
3003 test_object_name_with_null(handle, &name3U);
3004 status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr3);
3005 ok(!status, "got %08lx\n", status);
3006 test_object_name_with_null(handle2, &name3U);
3007 pNtClose(handle2);
3008 pNtClose(handle);
3010 status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr);
3011 ok(!status, "got %08lx\n", status);
3012 test_object_name(handle, name, FALSE);
3013 status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr);
3014 ok(!status, "got %08lx\n", status);
3015 test_object_name(handle2, name, FALSE);
3016 pNtClose(handle2);
3017 pNtClose(handle);
3018 status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr2);
3019 ok(!status, "got %08lx\n", status);
3020 test_object_name_with_null(handle, &name2U);
3021 status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr2);
3022 ok(!status, "got %08lx\n", status);
3023 test_object_name_with_null(handle2, &name2U);
3024 pNtClose(handle2);
3025 pNtClose(handle);
3026 status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr3);
3027 ok(!status, "got %08lx\n", status);
3028 test_object_name_with_null(handle, &name3U);
3029 status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr3);
3030 ok(!status, "got %08lx\n", status);
3031 test_object_name_with_null(handle2, &name3U);
3032 pNtClose(handle2);
3033 pNtClose(handle);
3035 status = pNtCreateTimer(&handle, GENERIC_ALL, &attr, NotificationTimer);
3036 ok(!status, "got %08lx\n", status);
3037 test_object_name(handle, name, FALSE);
3038 status = pNtOpenTimer(&handle2, GENERIC_ALL, &attr);
3039 ok(!status, "got %08lx\n", status);
3040 test_object_name(handle2, name, FALSE);
3041 pNtClose(handle2);
3042 pNtClose(handle);
3043 status = pNtCreateTimer(&handle, GENERIC_ALL, &attr2, NotificationTimer);
3044 ok(!status, "got %08lx\n", status);
3045 test_object_name_with_null(handle, &name2U);
3046 status = pNtOpenTimer(&handle2, GENERIC_ALL, &attr2);
3047 ok(!status, "got %08lx\n", status);
3048 test_object_name_with_null(handle2, &name2U);
3049 pNtClose(handle2);
3050 pNtClose(handle);
3051 status = pNtCreateTimer(&handle, GENERIC_ALL, &attr3, NotificationTimer);
3052 ok(!status, "got %08lx\n", status);
3053 test_object_name_with_null(handle, &name3U);
3054 status = pNtOpenTimer(&handle2, GENERIC_ALL, &attr3);
3055 ok(!status, "got %08lx\n", status);
3056 test_object_name_with_null(handle2, &name3U);
3057 pNtClose(handle2);
3058 pNtClose(handle);
3060 size.QuadPart = 4096;
3061 status = pNtCreateSection(&handle, GENERIC_ALL, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
3062 ok(!status, "got %08lx\n", status);
3063 test_object_name(handle, name, FALSE);
3064 status = pNtOpenSection(&handle2, GENERIC_ALL, &attr);
3065 ok(!status, "got %08lx\n", status);
3066 test_object_name(handle2, name, FALSE);
3067 pNtClose(handle2);
3068 pNtClose(handle);
3069 status = pNtCreateSection(&handle, GENERIC_ALL, &attr2, &size, PAGE_READWRITE, SEC_COMMIT, 0);
3070 ok(!status, "got %08lx\n", status);
3071 test_object_name_with_null(handle, &name2U);
3072 status = pNtOpenSection(&handle2, GENERIC_ALL, &attr2);
3073 ok(!status, "got %08lx\n", status);
3074 test_object_name_with_null(handle2, &name2U);
3075 pNtClose(handle2);
3076 pNtClose(handle);
3077 status = pNtCreateSection(&handle, GENERIC_ALL, &attr3, &size, PAGE_READWRITE, SEC_COMMIT, 0);
3078 ok(!status, "got %08lx\n", status);
3079 test_object_name_with_null(handle, &name3U);
3080 status = pNtOpenSection(&handle2, GENERIC_ALL, &attr3);
3081 ok(!status, "got %08lx\n", status);
3082 test_object_name_with_null(handle2, &name3U);
3083 pNtClose(handle2);
3084 pNtClose(handle);
3086 wcscpy(name, L"\\Registry\\Machine\\Software\\wine_test");
3087 wcscpy(name3, L"\\Registry\\Machine\\Software\\wine_test");
3088 p = wcsrchr(name3, '\\');
3089 p[5] = 0; /* => \\wine\0test */
3091 RtlInitUnicodeString(&nameU, name);
3092 name2U = nameU;
3093 name3U = nameU;
3094 name3U.Buffer = name3;
3095 #ifdef _WIN64
3096 name_exp = name;
3097 name3_exp = name3;
3098 name2U_exp = name2U;
3099 #else
3100 if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)
3102 name_exp = (WCHAR *)L"\\Registry\\Machine\\Software\\WOW6432Node\\wine_test";
3103 name3_exp =(WCHAR *) L"\\Registry\\Machine\\Software\\WOW6432Node\\wine\0test";
3105 else
3107 name_exp = name;
3108 name3_exp = name3;
3110 RtlInitUnicodeString(&name2U_exp, name_exp);
3111 #endif
3112 name3U_exp = name2U_exp;
3113 name3U_exp.Buffer = name3_exp;
3114 name2U.Length += sizeof(WCHAR); /* add terminating \0 to string length */
3115 name2U_exp.Length += sizeof(WCHAR); /* add terminating \0 to string length */
3117 status = pNtCreateKey(&handle, GENERIC_ALL, &attr, 0, NULL, 0, NULL);
3118 ok(!status || status == STATUS_ACCESS_DENIED || broken(status == STATUS_OBJECT_PATH_NOT_FOUND) /* win8 */, "got %08lx\n", status);
3119 if (!status)
3121 test_object_name(handle, name_exp, FALSE);
3122 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr);
3123 ok(!status, "got %08lx\n", status);
3124 test_object_name(handle2, name_exp, FALSE);
3125 pNtClose(handle2);
3126 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr2);
3127 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
3128 pNtDeleteKey(handle);
3129 pNtClose(handle);
3130 status = pNtCreateKey(&handle, GENERIC_ALL, &attr2, 0, NULL, 0, NULL);
3131 ok(!status, "got %08lx\n", status);
3132 test_object_name_with_null(handle, &name2U_exp);
3133 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr2);
3134 ok(!status, "got %08lx\n", status);
3135 test_object_name_with_null(handle, &name2U_exp);
3136 pNtClose(handle2);
3137 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr);
3138 ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
3139 pNtDeleteKey(handle);
3140 pNtClose(handle);
3141 status = pNtCreateKey(&handle, GENERIC_ALL, &attr3, 0, NULL, 0, NULL);
3142 ok(!status, "got %08lx\n", status);
3143 test_object_name_with_null(handle, &name3U_exp);
3144 status = pNtOpenKey(&handle2, GENERIC_ALL, &attr3);
3145 ok(!status, "got %08lx\n", status);
3146 test_object_name_with_null(handle, &name3U_exp);
3147 pNtClose(handle2);
3148 pNtDeleteKey(handle);
3149 pNtClose(handle);
3151 else
3152 skip("Limited access to \\Registry\\Machine\\Software key, skipping the tests\n");
3155 static void test_object_permanence(void)
3157 static const struct object_permanence_test {
3158 const char *name;
3159 ULONG initial_attr;
3160 ACCESS_MASK access;
3161 BOOLEAN make_temporary;
3162 BOOLEAN make_permanent;
3163 NTSTATUS make_temp_status;
3164 } tests[] = {
3166 .name = "permanent object persists",
3167 .initial_attr = OBJ_PERMANENT,
3168 .access = GENERIC_ALL,
3171 .name = "NtMakeTemporaryObject() succeeds",
3172 .initial_attr = OBJ_PERMANENT,
3173 .access = GENERIC_ALL,
3174 .make_temporary = TRUE,
3175 .make_temp_status = STATUS_SUCCESS,
3178 .name = "NtMakeTemporaryObject() fails w/o DELETE access",
3179 .initial_attr = OBJ_PERMANENT,
3180 .access = EVENT_ALL_ACCESS & ~DELETE,
3181 .make_temporary = TRUE,
3182 .make_temp_status = STATUS_ACCESS_DENIED,
3185 .name = "NtMakePermanentObject() succeeds even if already permanent",
3186 .initial_attr = OBJ_PERMANENT,
3187 .access = EVENT_ALL_ACCESS & ~DELETE,
3188 .make_permanent = TRUE,
3191 .name = "NtMakePermanentObject() reverses effect of NtMakeTemporaryObject()",
3192 .initial_attr = OBJ_PERMANENT,
3193 .access = GENERIC_ALL,
3194 .make_temporary = TRUE,
3195 .make_temp_status = STATUS_SUCCESS,
3196 .make_permanent = TRUE,
3200 .name = "temporary object disappears",
3201 .initial_attr = 0,
3202 .access = GENERIC_ALL,
3205 .name = "NtMakeTemporaryObject() succeeds even if already temporary",
3206 .initial_attr = 0,
3207 .access = GENERIC_ALL,
3208 .make_temporary = TRUE,
3209 .make_temp_status = STATUS_SUCCESS,
3212 .name = "NtMakeTemporaryObject() fails w/o DELETE access even if already temporary",
3213 .initial_attr = 0,
3214 .access = EVENT_ALL_ACCESS & ~DELETE,
3215 .make_temporary = TRUE,
3216 .make_temp_status = STATUS_ACCESS_DENIED,
3219 .name = "NtMakePermanentObject() makes an object persist",
3220 .initial_attr = 0,
3221 .access = EVENT_ALL_ACCESS & ~DELETE,
3222 .make_permanent = TRUE,
3225 .name = "NtMakePermanentObject() is not annulled by calling NtMakeTemporaryObject() on an already temporary object",
3226 .initial_attr = 0,
3227 .access = GENERIC_ALL,
3228 .make_temporary = TRUE,
3229 .make_temp_status = STATUS_SUCCESS,
3230 .make_permanent = TRUE,
3233 const struct object_permanence_test *test;
3234 HANDLE process_token = NULL, thread_token = NULL;
3235 SECURITY_QUALITY_OF_SERVICE token_qos = {
3236 .Length = sizeof(token_qos),
3237 .ImpersonationLevel = SecurityDelegation,
3238 .ContextTrackingMode = SECURITY_STATIC_TRACKING,
3239 .EffectiveOnly = FALSE,
3241 OBJECT_ATTRIBUTES token_attr = {
3242 .Length = sizeof(token_attr),
3243 .SecurityQualityOfService = &token_qos,
3245 TOKEN_PRIVILEGES new_privs = {
3246 .PrivilegeCount = 1,
3247 .Privileges = {
3249 .Luid = { .LowPart = SE_CREATE_PERMANENT_PRIVILEGE },
3250 .Attributes = SE_PRIVILEGE_ENABLED,
3254 NTSTATUS status;
3255 BOOL creatpermapriv = FALSE;
3257 status = NtOpenProcessToken( GetCurrentProcess(), TOKEN_DUPLICATE, &process_token );
3258 ok( status == STATUS_SUCCESS, "NtOpenProcessToken returned %08lx\n", status );
3260 status = NtDuplicateToken( process_token, TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES,
3261 &token_attr, FALSE, TokenImpersonation, &thread_token );
3262 ok( status == STATUS_SUCCESS, "NtDuplicateToken returned %08lx\n", status );
3263 NtClose( process_token );
3265 status = NtAdjustPrivilegesToken( thread_token, FALSE, &new_privs, sizeof(new_privs), NULL, NULL );
3266 ok( status == STATUS_SUCCESS || status == STATUS_NOT_ALL_ASSIGNED, "NtAdjustPrivilegesToken returned %08lx\n", status );
3267 creatpermapriv = (status == STATUS_SUCCESS);
3269 status = NtSetInformationThread( GetCurrentThread(), ThreadImpersonationToken, &thread_token, sizeof(thread_token) );
3270 ok( status == STATUS_SUCCESS, "NtSetInformationThread returned %08lx\n", status );
3271 NtClose( thread_token );
3273 if (!creatpermapriv) skip( "no privileges, tests may be limited\n" );
3275 for (test = &tests[0]; test != &tests[ARRAY_SIZE(tests)]; test++)
3277 NTSTATUS make_perma_status = creatpermapriv ? STATUS_SUCCESS : STATUS_PRIVILEGE_NOT_HELD;
3278 HANDLE handle, handle2;
3279 OBJECT_BASIC_INFORMATION obi;
3280 OBJECT_ATTRIBUTES attr;
3281 UNICODE_STRING name;
3282 BOOL is_permanent;
3283 ULONG len = 0;
3285 winetest_push_context( "test#%Iu", test - &tests[0] );
3286 trace( "(%s)\n", test->name );
3288 RtlInitUnicodeString( &name, L"\\BaseNamedObjects\\test_object_permanence" );
3289 InitializeObjectAttributes( &attr, &name, test->initial_attr, 0, NULL );
3290 status = NtCreateEvent( &handle, test->access, &attr, NotificationEvent, FALSE );
3291 if (test->initial_attr & OBJ_PERMANENT)
3293 todo_wine_if(status == STATUS_SUCCESS || status == STATUS_PRIVILEGE_NOT_HELD)
3294 ok( status == make_perma_status, "NtCreateEvent returned %08lx (expected %08lx)\n", status, make_perma_status );
3296 else
3298 ok( status == STATUS_SUCCESS, "NtCreateEvent returned %08lx\n", status );
3300 if (NT_ERROR(status))
3302 winetest_pop_context();
3303 continue;
3305 is_permanent = (test->initial_attr & OBJ_PERMANENT) != 0;
3307 status = NtQueryObject( handle, ObjectBasicInformation, &obi, sizeof(obi), &len );
3308 ok( status == STATUS_SUCCESS, "NtQueryObject returned %08lx\n", status );
3309 todo_wine_if(test->initial_attr != 0)
3310 ok( obi.Attributes == test->initial_attr, "expected attr %08lx, got %08lx\n", test->initial_attr, obi.Attributes );
3312 if (test->make_temporary)
3314 if (test->make_temp_status == STATUS_ACCESS_DENIED)
3315 ok( !(obi.GrantedAccess & DELETE), "expected no DELETE access in %08lx\n", obi.GrantedAccess );
3316 if (test->make_temp_status == STATUS_SUCCESS)
3317 ok( !!(obi.GrantedAccess & DELETE), "expected DELETE access in %08lx\n", obi.GrantedAccess );
3319 status = NtMakeTemporaryObject( handle );
3320 ok( status == test->make_temp_status, "NtMakeTemporaryObject returned %08lx\n", status );
3321 if (!NT_ERROR(status)) is_permanent = FALSE;
3324 if (winetest_debug > 1)
3325 trace( "NOTE: object still has unclosed handle (%p) and shouldn't be deleted", handle );
3327 winetest_push_context( "first handle (%p) still open", handle );
3328 status = NtOpenEvent( &handle2, GENERIC_ALL, &attr );
3329 ok( status == STATUS_SUCCESS, "NtOpenEvent returned %08lx\n", status );
3330 if (!NT_ERROR(status))
3332 ULONG expect_attr = (obi.Attributes & ~OBJ_PERMANENT) | (is_permanent ? OBJ_PERMANENT : 0);
3333 OBJECT_BASIC_INFORMATION obi2;
3335 status = NtQueryObject( handle2, ObjectBasicInformation, &obi2, sizeof(obi2), &len );
3336 ok( status == STATUS_SUCCESS, "NtQueryObject returned %08lx\n", status );
3337 todo_wine_if(expect_attr != 0)
3338 ok( obi2.Attributes == expect_attr, "expected attr %08lx, got %08lx\n", expect_attr, obi2.Attributes );
3340 NtClose( handle2 );
3342 winetest_pop_context();
3344 if (test->make_permanent)
3346 status = NtMakePermanentObject( handle );
3347 todo_wine_if(status == STATUS_SUCCESS || status == STATUS_PRIVILEGE_NOT_HELD)
3348 ok( status == make_perma_status, "NtMakePermanentObject returned %08lx expected (%08lx)\n", status, make_perma_status );
3349 if (!NT_ERROR(status)) is_permanent = TRUE;
3352 if (winetest_debug > 1)
3353 trace( "NOTE: about to close earlier handle (%p) which should be the last", handle );
3354 NtClose( handle );
3356 winetest_push_context( "first handle closed" );
3357 status = NtOpenEvent( &handle, GENERIC_ALL, &attr );
3358 ok( status == (is_permanent ? STATUS_SUCCESS : STATUS_OBJECT_NAME_NOT_FOUND), "NtOpenEvent returned %08lx\n", status );
3359 if (!NT_ERROR(status))
3361 ULONG expect_attr = (obi.Attributes & ~OBJ_PERMANENT) | (is_permanent ? OBJ_PERMANENT : 0);
3362 OBJECT_BASIC_INFORMATION obi_new;
3364 status = NtQueryObject( handle, ObjectBasicInformation, &obi_new, sizeof(obi_new), &len );
3365 ok( status == STATUS_SUCCESS, "NtQueryObject returned %08lx\n", status );
3366 todo_wine_if(expect_attr != 0)
3367 ok( obi_new.Attributes == expect_attr, "expected attr %08lx, got %08lx\n", expect_attr, obi_new.Attributes );
3369 /* ensure object is deleted */
3370 NtMakeTemporaryObject( handle );
3371 NtClose( handle );
3373 winetest_pop_context();
3375 winetest_pop_context();
3378 thread_token = NULL;
3379 status = NtSetInformationThread( GetCurrentThread(), ThreadImpersonationToken, &thread_token, sizeof(thread_token) );
3380 ok( status == STATUS_SUCCESS, "NtSetInformationThread returned %08lx\n", status );
3383 START_TEST(om)
3385 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
3387 pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent");
3388 pNtCreateJobObject = (void *)GetProcAddress(hntdll, "NtCreateJobObject");
3389 pNtOpenJobObject = (void *)GetProcAddress(hntdll, "NtOpenJobObject");
3390 pNtCreateKey = (void *)GetProcAddress(hntdll, "NtCreateKey");
3391 pNtOpenKey = (void *)GetProcAddress(hntdll, "NtOpenKey");
3392 pNtDeleteKey = (void *)GetProcAddress(hntdll, "NtDeleteKey");
3393 pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile");
3394 pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant");
3395 pNtOpenEvent = (void *)GetProcAddress(hntdll, "NtOpenEvent");
3396 pNtOpenMutant = (void *)GetProcAddress(hntdll, "NtOpenMutant");
3397 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
3398 pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
3399 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
3400 pNtCreateNamedPipeFile = (void *)GetProcAddress(hntdll, "NtCreateNamedPipeFile");
3401 pNtOpenDirectoryObject = (void *)GetProcAddress(hntdll, "NtOpenDirectoryObject");
3402 pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject");
3403 pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject");
3404 pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject");
3405 pNtQuerySymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject");
3406 pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
3407 pNtOpenSemaphore = (void *)GetProcAddress(hntdll, "NtOpenSemaphore");
3408 pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer");
3409 pNtOpenTimer = (void *)GetProcAddress(hntdll, "NtOpenTimer");
3410 pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection");
3411 pNtOpenSection = (void *)GetProcAddress(hntdll, "NtOpenSection");
3412 pNtQueryObject = (void *)GetProcAddress(hntdll, "NtQueryObject");
3413 pNtReleaseSemaphore = (void *)GetProcAddress(hntdll, "NtReleaseSemaphore");
3414 pNtCreateKeyedEvent = (void *)GetProcAddress(hntdll, "NtCreateKeyedEvent");
3415 pNtOpenKeyedEvent = (void *)GetProcAddress(hntdll, "NtOpenKeyedEvent");
3416 pNtCreateIoCompletion = (void *)GetProcAddress(hntdll, "NtCreateIoCompletion");
3417 pNtOpenIoCompletion = (void *)GetProcAddress(hntdll, "NtOpenIoCompletion");
3418 pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile");
3419 pNtOpenProcess = (void *)GetProcAddress(hntdll, "NtOpenProcess");
3420 pNtCreateDebugObject = (void *)GetProcAddress(hntdll, "NtCreateDebugObject");
3421 pNtGetNextThread = (void *)GetProcAddress(hntdll, "NtGetNextThread");
3422 pNtOpenProcessToken = (void *)GetProcAddress(hntdll, "NtOpenProcessToken");
3423 pNtOpenThreadToken = (void *)GetProcAddress(hntdll, "NtOpenThreadToken");
3424 pNtDuplicateToken = (void *)GetProcAddress(hntdll, "NtDuplicateToken");
3425 pNtDuplicateObject = (void *)GetProcAddress(hntdll, "NtDuplicateObject");
3426 pNtCompareObjects = (void *)GetProcAddress(hntdll, "NtCompareObjects");
3428 test_null_in_object_name();
3429 test_case_sensitive();
3430 test_namespace_pipe();
3431 test_name_collisions();
3432 test_name_limits();
3433 test_directory();
3434 test_symboliclink();
3435 test_query_object();
3436 test_type_mismatch();
3437 test_null_device();
3438 test_process();
3439 test_token();
3440 test_duplicate_object();
3441 test_object_types();
3442 test_get_next_thread();
3443 test_globalroot();
3444 test_object_identity();
3445 test_query_directory();
3446 test_object_permanence();