[USB]
[reactos.git] / rostests / winetests / ntdll / om.c
1 /*
2 * Unit test suite for object manager functions
3 *
4 * Copyright 2005 Robert Shearman
5 * Copyright 2005 Vitaliy Margolen
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "ntdll_test.h"
23 #include "winternl.h"
24 #include "stdio.h"
25 #include "winnt.h"
26 #include "stdlib.h"
27
28 static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*, BOOL, LPCSTR);
29 static NTSTATUS (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
30 static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
31 static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
32 static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN, BOOLEAN);
33 static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN );
34 static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
35 static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG );
36 static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE );
37 static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER,
38 ULONG, ULONG, HANDLE );
39 static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG );
40 static NTSTATUS (WINAPI *pNtClose) ( HANDLE );
41 static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
42 ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, PLARGE_INTEGER );
43 static NTSTATUS (WINAPI *pNtOpenDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
44 static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
45 static NTSTATUS (WINAPI *pNtOpenSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
46 static NTSTATUS (WINAPI *pNtCreateSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PUNICODE_STRING);
47 static NTSTATUS (WINAPI *pNtQuerySymbolicLinkObject)(HANDLE,PUNICODE_STRING,PULONG);
48 static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG);
49 static NTSTATUS (WINAPI *pNtReleaseSemaphore)(HANDLE handle, ULONG count, PULONG previous);
50
51
52 static void test_case_sensitive (void)
53 {
54 static const WCHAR buffer1[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','t','e','s','t',0};
55 static const WCHAR buffer2[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','T','e','s','t',0};
56 static const WCHAR buffer3[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','T','E','s','t',0};
57 static const WCHAR buffer4[] = {'\\','B','A','S','E','N','a','m','e','d','O','b','j','e','c','t','s','\\','t','e','s','t',0};
58 NTSTATUS status;
59 OBJECT_ATTRIBUTES attr;
60 UNICODE_STRING str;
61 HANDLE Event, Mutant, h;
62
63 pRtlInitUnicodeString(&str, buffer1);
64 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
65 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
66 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
67
68 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
69 ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
70 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status);
71
72 pRtlInitUnicodeString(&str, buffer2);
73 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
74 status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE);
75 ok(status == STATUS_SUCCESS, "Failed to create Event(%08x)\n", status);
76
77 pRtlInitUnicodeString(&str, buffer3);
78 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
79 status = pNtOpenMutant(&h, GENERIC_ALL, &attr);
80 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
81 "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
82
83 pNtClose(Mutant);
84
85 pRtlInitUnicodeString(&str, buffer4);
86 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
87 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
88 ok(status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
89 "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status);
90
91 status = pNtCreateEvent(&h, GENERIC_ALL, &attr, FALSE, FALSE);
92 ok(status == STATUS_OBJECT_NAME_COLLISION,
93 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status);
94
95 attr.Attributes = 0;
96 status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
97 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
98 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
99
100 pNtClose(Event);
101 }
102
103 static void test_namespace_pipe(void)
104 {
105 static const WCHAR buffer1[] = {'\\','?','?','\\','P','I','P','E','\\','t','e','s','t','\\','p','i','p','e',0};
106 static const WCHAR buffer2[] = {'\\','?','?','\\','P','I','P','E','\\','T','E','S','T','\\','P','I','P','E',0};
107 static const WCHAR buffer3[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t','\\','p','i','p','e',0};
108 static const WCHAR buffer4[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t',0};
109 OBJECT_ATTRIBUTES attr;
110 UNICODE_STRING str;
111 IO_STATUS_BLOCK iosb;
112 NTSTATUS status;
113 LARGE_INTEGER timeout;
114 HANDLE pipe, h;
115
116 timeout.QuadPart = -10000;
117
118 pRtlInitUnicodeString(&str, buffer1);
119 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
120 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
121 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
122 ok(status == STATUS_SUCCESS, "Failed to create NamedPipe(%08x)\n", status);
123
124 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
125 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
126 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
127 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
128
129 pRtlInitUnicodeString(&str, buffer2);
130 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
131 status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
132 FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout);
133 ok(status == STATUS_INSTANCE_NOT_AVAILABLE,
134 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status);
135
136 h = CreateFileA("\\\\.\\pipe\\test\\pipe", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
137 OPEN_EXISTING, 0, 0 );
138 ok(h != INVALID_HANDLE_VALUE, "Failed to open NamedPipe (%u)\n", GetLastError());
139 pNtClose(h);
140
141 pRtlInitUnicodeString(&str, buffer3);
142 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
143 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN);
144 ok(status == STATUS_OBJECT_PATH_NOT_FOUND ||
145 status == STATUS_PIPE_NOT_AVAILABLE ||
146 status == STATUS_OBJECT_NAME_INVALID, /* vista */
147 "NtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
148
149 pRtlInitUnicodeString(&str, buffer4);
150 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL);
151 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN);
152 ok(status == STATUS_OBJECT_NAME_NOT_FOUND ||
153 status == STATUS_OBJECT_NAME_INVALID, /* vista */
154 "NtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08x)\n", status);
155
156 pNtClose(pipe);
157 }
158
159 #define DIRECTORY_QUERY (0x0001)
160 #define SYMBOLIC_LINK_QUERY 0x0001
161
162 #define DIR_TEST_CREATE_FAILURE(h,e) \
163 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr);\
164 ok(status == e,"NtCreateDirectoryObject should have failed with %s got(%08x)\n", #e, status);
165 #define DIR_TEST_OPEN_FAILURE(h,e) \
166 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr);\
167 ok(status == e,"NtOpenDirectoryObject should have failed with %s got(%08x)\n", #e, status);
168 #define DIR_TEST_CREATE_OPEN_FAILURE(h,n,e) \
169 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
170 DIR_TEST_CREATE_FAILURE(h,e) DIR_TEST_OPEN_FAILURE(h,e)\
171 pRtlFreeUnicodeString(&str);
172
173 #define DIR_TEST_CREATE_SUCCESS(h) \
174 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr); \
175 ok(status == STATUS_SUCCESS, "Failed to create Directory(%08x)\n", status);
176 #define DIR_TEST_OPEN_SUCCESS(h) \
177 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr); \
178 ok(status == STATUS_SUCCESS, "Failed to open Directory(%08x)\n", status);
179 #define DIR_TEST_CREATE_OPEN_SUCCESS(h,n) \
180 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
181 DIR_TEST_CREATE_SUCCESS(&h) pNtClose(h); DIR_TEST_OPEN_SUCCESS(&h) pNtClose(h); \
182 pRtlFreeUnicodeString(&str);
183
184 static BOOL is_correct_dir( HANDLE dir, const char *name )
185 {
186 NTSTATUS status;
187 UNICODE_STRING str;
188 OBJECT_ATTRIBUTES attr;
189 HANDLE h = 0;
190
191 pRtlCreateUnicodeStringFromAsciiz(&str, name);
192 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
193 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
194 pRtlFreeUnicodeString(&str);
195 if (h) pNtClose( h );
196 return (status == STATUS_OBJECT_NAME_EXISTS);
197 }
198
199 /* return a handle to the BaseNamedObjects dir where kernel32 objects get created */
200 static HANDLE get_base_dir(void)
201 {
202 static const char objname[] = "om.c_get_base_dir_obj";
203 NTSTATUS status;
204 UNICODE_STRING str;
205 OBJECT_ATTRIBUTES attr;
206 HANDLE dir, h;
207 unsigned int i;
208
209 h = CreateMutexA(NULL, FALSE, objname);
210 ok(h != 0, "CreateMutexA failed got ret=%p (%d)\n", h, GetLastError());
211 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
212
213 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local");
214 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
215 pRtlFreeUnicodeString(&str);
216 if (!status && is_correct_dir( dir, objname )) goto done;
217 if (!status) pNtClose( dir );
218
219 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
220 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
221 pRtlFreeUnicodeString(&str);
222 if (!status && is_correct_dir( dir, objname )) goto done;
223 if (!status) pNtClose( dir );
224
225 for (i = 0; i < 20; i++)
226 {
227 char name[40];
228 sprintf( name, "\\BaseNamedObjects\\Session\\%u", i );
229 pRtlCreateUnicodeStringFromAsciiz(&str, name );
230 status = pNtOpenDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
231 pRtlFreeUnicodeString(&str);
232 if (!status && is_correct_dir( dir, objname )) goto done;
233 if (!status) pNtClose( dir );
234 }
235 dir = 0;
236
237 done:
238 pNtClose( h );
239 return dir;
240 }
241
242 static void test_name_collisions(void)
243 {
244 NTSTATUS status;
245 UNICODE_STRING str;
246 OBJECT_ATTRIBUTES attr;
247 HANDLE dir, h, h1, h2;
248 DWORD winerr;
249 LARGE_INTEGER size;
250
251 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
252 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
253 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_COLLISION)
254 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
255
256 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_EXISTS)
257 pNtClose(h);
258 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
259 ok(status == STATUS_OBJECT_TYPE_MISMATCH,
260 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
261 pRtlFreeUnicodeString(&str);
262
263 pRtlCreateUnicodeStringFromAsciiz(&str, "\\??\\PIPE\\om.c-mutant");
264 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
265 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_OBJECT_PATH_NOT_FOUND,
266 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
267 pRtlFreeUnicodeString(&str);
268
269 if (!(dir = get_base_dir()))
270 {
271 win_skip( "couldn't find the BaseNamedObjects dir\n" );
272 return;
273 }
274 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
275 InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL);
276 h = CreateMutexA(NULL, FALSE, "om.c-test");
277 ok(h != 0, "CreateMutexA failed got ret=%p (%d)\n", h, GetLastError());
278 status = pNtCreateMutant(&h1, GENERIC_ALL, &attr, FALSE);
279 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
280 "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
281 h2 = CreateMutexA(NULL, FALSE, "om.c-test");
282 winerr = GetLastError();
283 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
284 "CreateMutexA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
285 pNtClose(h);
286 pNtClose(h1);
287 pNtClose(h2);
288
289 h = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
290 ok(h != 0, "CreateEventA failed got ret=%p (%d)\n", h, GetLastError());
291 status = pNtCreateEvent(&h1, GENERIC_ALL, &attr, FALSE, FALSE);
292 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
293 "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
294 h2 = CreateEventA(NULL, FALSE, FALSE, "om.c-test");
295 winerr = GetLastError();
296 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
297 "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
298 pNtClose(h);
299 pNtClose(h1);
300 pNtClose(h2);
301
302 h = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
303 ok(h != 0, "CreateSemaphoreA failed got ret=%p (%d)\n", h, GetLastError());
304 status = pNtCreateSemaphore(&h1, GENERIC_ALL, &attr, 1, 2);
305 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
306 "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
307 h2 = CreateSemaphoreA(NULL, 1, 2, "om.c-test");
308 winerr = GetLastError();
309 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
310 "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
311 pNtClose(h);
312 pNtClose(h1);
313 pNtClose(h2);
314
315 h = pCreateWaitableTimerA(NULL, TRUE, "om.c-test");
316 ok(h != 0, "CreateWaitableTimerA failed got ret=%p (%d)\n", h, GetLastError());
317 status = pNtCreateTimer(&h1, GENERIC_ALL, &attr, NotificationTimer);
318 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
319 "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
320 h2 = pCreateWaitableTimerA(NULL, TRUE, "om.c-test");
321 winerr = GetLastError();
322 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
323 "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
324 pNtClose(h);
325 pNtClose(h1);
326 pNtClose(h2);
327
328 h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
329 ok(h != 0, "CreateFileMappingA failed got ret=%p (%d)\n", h, GetLastError());
330 size.u.LowPart = 256;
331 size.u.HighPart = 0;
332 status = pNtCreateSection(&h1, SECTION_MAP_WRITE, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
333 ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL,
334 "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status);
335 h2 = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test");
336 winerr = GetLastError();
337 ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS,
338 "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2, winerr);
339 pNtClose(h);
340 pNtClose(h1);
341 pNtClose(h2);
342
343 pRtlFreeUnicodeString(&str);
344 pNtClose(dir);
345 }
346
347 static void test_directory(void)
348 {
349 NTSTATUS status;
350 UNICODE_STRING str;
351 OBJECT_ATTRIBUTES attr;
352 HANDLE dir, dir1, h;
353 BOOL is_nt4;
354
355 /* No name and/or no attributes */
356 status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
357 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
358 "NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
359 status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
360 ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER,
361 "NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
362
363 status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL);
364 ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08x)\n", status);
365 pNtClose(h);
366 status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL);
367 ok(status == STATUS_INVALID_PARAMETER,
368 "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
369
370 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
371 DIR_TEST_CREATE_SUCCESS(&dir)
372 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
373
374 /* Bad name */
375 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
376
377 pRtlCreateUnicodeStringFromAsciiz(&str, "");
378 DIR_TEST_CREATE_SUCCESS(&h)
379 pNtClose(h);
380 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
381 pRtlFreeUnicodeString(&str);
382 pNtClose(dir);
383
384 DIR_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD)
385 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID)
386 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID)
387 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID)
388 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
389
390 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
391 DIR_TEST_CREATE_SUCCESS(&h)
392 DIR_TEST_OPEN_SUCCESS(&dir1)
393 pRtlFreeUnicodeString(&str);
394 pNtClose(h);
395 pNtClose(dir1);
396
397
398 /* Use of root directory */
399
400 /* Can't use symlinks as a directory */
401 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local");
402 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
403 status = pNtOpenSymbolicLinkObject(&dir, SYMBOLIC_LINK_QUERY, &attr);
404 is_nt4 = (status == STATUS_OBJECT_NAME_NOT_FOUND); /* nt4 doesn't have Local\\ symlink */
405 if (!is_nt4)
406 {
407 WCHAR buffer[256];
408 ULONG len, full_len;
409
410 ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08x)\n", status);
411 pRtlFreeUnicodeString(&str);
412 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
413 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
414 DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH)
415 pRtlFreeUnicodeString(&str);
416
417 str.Buffer = buffer;
418 str.MaximumLength = sizeof(buffer);
419 len = 0xdeadbeef;
420 memset( buffer, 0xaa, sizeof(buffer) );
421 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
422 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08x\n", status );
423 if (status != STATUS_SUCCESS)
424 goto error;
425 full_len = str.Length + sizeof(WCHAR);
426 ok( len == full_len, "bad length %u/%u\n", len, full_len );
427 if (len == full_len)
428 ok( buffer[len / sizeof(WCHAR) - 1] == 0, "no terminating null\n" );
429
430 str.MaximumLength = str.Length;
431 len = 0xdeadbeef;
432 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
433 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08x\n", status );
434 ok( len == full_len, "bad length %u/%u\n", len, full_len );
435
436 str.MaximumLength = 0;
437 len = 0xdeadbeef;
438 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
439 ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08x\n", status );
440 ok( len == full_len, "bad length %u/%u\n", len, full_len );
441
442 str.MaximumLength = str.Length + sizeof(WCHAR);
443 len = 0xdeadbeef;
444 status = pNtQuerySymbolicLinkObject( dir, &str, &len );
445 ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08x\n", status );
446 ok( len == full_len, "bad length %u/%u\n", len, full_len );
447
448 error:
449 pNtClose(dir);
450 }
451
452 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
453 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
454 DIR_TEST_OPEN_SUCCESS(&dir)
455 pRtlFreeUnicodeString(&str);
456
457 InitializeObjectAttributes(&attr, NULL, 0, dir, NULL);
458 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_NAME_INVALID)
459
460 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
461 DIR_TEST_CREATE_OPEN_SUCCESS(h, "")
462 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
463 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD)
464 DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
465 DIR_TEST_CREATE_OPEN_FAILURE(&h, "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
466
467 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
468 DIR_TEST_CREATE_SUCCESS(&dir1)
469 DIR_TEST_OPEN_SUCCESS(&h)
470 pRtlFreeUnicodeString(&str);
471
472 pNtClose(h);
473 pNtClose(dir1);
474 pNtClose(dir);
475
476 /* Nested directories */
477 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
478 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
479 DIR_TEST_OPEN_SUCCESS(&dir)
480 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
481 DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
482 pRtlFreeUnicodeString(&str);
483 pNtClose(dir);
484
485 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
486 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
487 DIR_TEST_CREATE_SUCCESS(&dir)
488 pRtlFreeUnicodeString(&str);
489 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test\\one more level");
490 DIR_TEST_CREATE_SUCCESS(&h)
491 pRtlFreeUnicodeString(&str);
492 pNtClose(h);
493 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
494 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
495 DIR_TEST_CREATE_SUCCESS(&h)
496 pRtlFreeUnicodeString(&str);
497 pNtClose(h);
498
499 pNtClose(dir);
500
501 if (!is_nt4)
502 {
503 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
504 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Global\\om.c-test");
505 DIR_TEST_CREATE_SUCCESS(&dir)
506 pRtlFreeUnicodeString(&str);
507 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local\\om.c-test\\one more level");
508 DIR_TEST_CREATE_SUCCESS(&h)
509 pRtlFreeUnicodeString(&str);
510 pNtClose(h);
511 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
512 pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
513 DIR_TEST_CREATE_SUCCESS(&dir)
514 pRtlFreeUnicodeString(&str);
515 pNtClose(h);
516 pNtClose(dir);
517 }
518
519 /* Create other objects using RootDirectory */
520
521 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
522 pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects");
523 DIR_TEST_OPEN_SUCCESS(&dir)
524 pRtlFreeUnicodeString(&str);
525 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
526
527 /* Test invalid paths */
528 pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant");
529 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
530 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
531 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
532 pRtlFreeUnicodeString(&str);
533 pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant\\");
534 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
535 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
536 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
537 pRtlFreeUnicodeString(&str);
538
539 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c\\-mutant");
540 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
541 ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
542 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
543 pRtlFreeUnicodeString(&str);
544
545 pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-mutant");
546 status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
547 ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status);
548 pRtlFreeUnicodeString(&str);
549 pNtClose(h);
550
551 pNtClose(dir);
552 }
553
554 #define SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e2) \
555 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
556 pRtlCreateUnicodeStringFromAsciiz(&target, t);\
557 status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\
558 ok(status == e || status == e2, \
559 "NtCreateSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
560 status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\
561 ok(status == e || status == e2, \
562 "NtOpenSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
563 pRtlFreeUnicodeString(&target);\
564 pRtlFreeUnicodeString(&str);
565
566 #define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e)
567
568 static void test_symboliclink(void)
569 {
570 NTSTATUS status;
571 UNICODE_STRING str, target;
572 OBJECT_ATTRIBUTES attr;
573 HANDLE dir, link, h;
574 IO_STATUS_BLOCK iosb;
575
576 /* No name and/or no attributes */
577 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
578 SYMLNK_TEST_CREATE_OPEN_FAILURE2(NULL, "", "", STATUS_ACCESS_VIOLATION, STATUS_INVALID_PARAMETER)
579
580 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL);
581 ok(status == STATUS_ACCESS_VIOLATION,
582 "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status);
583 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL);
584 ok(status == STATUS_INVALID_PARAMETER,
585 "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
586
587 /* No attributes */
588 pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
589 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, &target);
590 ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_VIOLATION, /* nt4 */
591 "NtCreateSymbolicLinkObject failed(%08x)\n", status);
592 pRtlFreeUnicodeString(&target);
593 if (!status) pNtClose(h);
594
595 InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
596 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
597 ok(status == STATUS_INVALID_PARAMETER ||
598 broken(status == STATUS_SUCCESS), /* nt4 */
599 "NtCreateSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status);
600 if (!status) pNtClose(h);
601 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
602 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
603 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
604
605 /* Bad name */
606 pRtlCreateUnicodeStringFromAsciiz(&target, "anywhere");
607 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
608
609 pRtlCreateUnicodeStringFromAsciiz(&str, "");
610 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
611 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status);
612 status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr);
613 ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
614 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status);
615 pNtClose(link);
616 pRtlFreeUnicodeString(&str);
617
618 pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
619 status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target);
620 todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH,
621 "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status);
622 pRtlFreeUnicodeString(&str);
623 pRtlFreeUnicodeString(&target);
624
625 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", "->Somewhere", STATUS_OBJECT_PATH_SYNTAX_BAD)
626 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
627 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
628 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", "->Somewhere", STATUS_OBJECT_NAME_INVALID)
629 SYMLNK_TEST_CREATE_OPEN_FAILURE2(&h, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere",
630 STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND)
631
632
633 /* Compound test */
634 if (!(dir = get_base_dir()))
635 {
636 win_skip( "couldn't find the BaseNamedObjects dir\n" );
637 return;
638 }
639
640 InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
641 pRtlCreateUnicodeStringFromAsciiz(&str, "test-link");
642 pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices");
643 status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
644 ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status);
645 pRtlFreeUnicodeString(&str);
646 pRtlFreeUnicodeString(&target);
647
648 pRtlCreateUnicodeStringFromAsciiz(&str, "test-link\\NUL");
649 status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN);
650 todo_wine ok(status == STATUS_SUCCESS, "Failed to open NUL device(%08x)\n", status);
651 pRtlFreeUnicodeString(&str);
652
653 pNtClose(h);
654 pNtClose(link);
655 pNtClose(dir);
656 }
657
658 static void test_query_object(void)
659 {
660 static const WCHAR name[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',
661 '\\','t','e','s','t','_','e','v','e','n','t'};
662 static const WCHAR type_event[] = {'E','v','e','n','t'};
663 static const WCHAR type_file[] = {'F','i','l','e'};
664 HANDLE handle;
665 char buffer[1024];
666 NTSTATUS status;
667 ULONG len, expected_len;
668 UNICODE_STRING *str;
669 char dir[MAX_PATH];
670
671 handle = CreateEventA( NULL, FALSE, FALSE, "test_event" );
672
673 len = 0;
674 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
675 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
676 ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
677
678 len = 0;
679 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, 0, &len );
680 todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
681 todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
682
683 len = 0;
684 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
685 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
686 ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
687
688 len = 0;
689 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(OBJECT_TYPE_INFORMATION), &len );
690 todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
691 todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
692
693 len = 0;
694 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
695 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
696 ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
697 str = (UNICODE_STRING *)buffer;
698 ok( sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR) == len, "unexpected len %u\n", len );
699 ok( str->Length >= sizeof(name), "unexpected len %u\n", str->Length );
700 /* there can be a \\Sessions prefix in the name */
701 ok( !memcmp( str->Buffer + (str->Length - sizeof(name)) / sizeof(WCHAR), name, sizeof(name) ),
702 "wrong name %s\n", wine_dbgstr_w(str->Buffer) );
703
704 len -= sizeof(WCHAR);
705 status = pNtQueryObject( handle, ObjectNameInformation, buffer, len, &len );
706 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
707 ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
708
709 len = 0;
710 memset( buffer, 0, sizeof(buffer) );
711 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
712 todo_wine ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
713 todo_wine ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
714 str = (UNICODE_STRING *)buffer;
715 todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR), "unexpected len %u\n", len );
716 todo_wine ok( str->Buffer && !memcmp( str->Buffer, type_event, sizeof(type_file) ),
717 "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
718
719 len -= sizeof(WCHAR);
720 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, len, &len );
721 todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
722 todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
723
724 pNtClose( handle );
725
726 handle = CreateEventA( NULL, FALSE, FALSE, NULL );
727 len = 0;
728 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
729 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
730 ok( len == sizeof(UNICODE_STRING), "unexpected len %u\n", len );
731 str = (UNICODE_STRING *)buffer;
732 ok( str->Length == 0, "unexpected len %u\n", len );
733 ok( str->Buffer == NULL, "unexpected ptr %p\n", str->Buffer );
734 pNtClose( handle );
735
736 GetWindowsDirectoryA( dir, MAX_PATH );
737 handle = CreateFileA( dir, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
738 FILE_FLAG_BACKUP_SEMANTICS, 0 );
739 len = 0;
740 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
741 ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
742 ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
743 str = (UNICODE_STRING *)buffer;
744 expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR);
745 ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */
746 "unexpected len %u\n", len );
747 trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len );
748
749 len = 0;
750 status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
751 ok( status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INSUFFICIENT_RESOURCES),
752 "NtQueryObject failed %x\n", status );
753 ok( len == expected_len || broken(!len || len == sizeof(UNICODE_STRING)),
754 "unexpected len %u\n", len );
755
756 len = 0;
757 status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
758 ok( status == STATUS_BUFFER_OVERFLOW || broken(status == STATUS_INSUFFICIENT_RESOURCES
759 || status == STATUS_INFO_LENGTH_MISMATCH),
760 "NtQueryObject failed %x\n", status );
761 ok( len == expected_len || broken(!len),
762 "unexpected len %u\n", len );
763
764 len = 0;
765 memset( buffer, 0, sizeof(buffer) );
766 status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
767 todo_wine ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
768 todo_wine ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
769 str = (UNICODE_STRING *)buffer;
770 expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
771 todo_wine ok( len >= expected_len, "unexpected len %u\n", len );
772 todo_wine ok( str->Buffer && !memcmp( str->Buffer, type_file, sizeof(type_file) ),
773 "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
774
775 pNtClose( handle );
776 }
777
778 static void test_type_mismatch(void)
779 {
780 HANDLE h;
781 NTSTATUS res;
782 OBJECT_ATTRIBUTES attr;
783
784 attr.Length = sizeof(attr);
785 attr.RootDirectory = 0;
786 attr.ObjectName = NULL;
787 attr.Attributes = 0;
788 attr.SecurityDescriptor = NULL;
789 attr.SecurityQualityOfService = NULL;
790
791 res = pNtCreateEvent( &h, 0, &attr, 0, 0 );
792 ok(!res, "can't create event: %x\n", res);
793
794 res = pNtReleaseSemaphore( h, 30, NULL );
795 ok(res == STATUS_OBJECT_TYPE_MISMATCH, "expected 0xc0000024, got %x\n", res);
796
797 pNtClose( h );
798 }
799
800 START_TEST(om)
801 {
802 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
803 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
804
805 if (!hntdll)
806 {
807 skip("not running on NT, skipping test\n");
808 return;
809 }
810
811 pCreateWaitableTimerA = (void *)GetProcAddress(hkernel32, "CreateWaitableTimerA");
812
813 pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
814 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
815 pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent");
816 pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant");
817 pNtOpenMutant = (void *)GetProcAddress(hntdll, "NtOpenMutant");
818 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
819 pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
820 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
821 pNtCreateNamedPipeFile = (void *)GetProcAddress(hntdll, "NtCreateNamedPipeFile");
822 pNtOpenDirectoryObject = (void *)GetProcAddress(hntdll, "NtOpenDirectoryObject");
823 pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject");
824 pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject");
825 pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject");
826 pNtQuerySymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject");
827 pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
828 pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer");
829 pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection");
830 pNtQueryObject = (void *)GetProcAddress(hntdll, "NtQueryObject");
831 pNtReleaseSemaphore = (void *)GetProcAddress(hntdll, "NtReleaseSemaphore");
832
833 test_case_sensitive();
834 test_namespace_pipe();
835 test_name_collisions();
836 test_directory();
837 test_symboliclink();
838 test_query_object();
839 test_type_mismatch();
840 }