2 * Unit test suite for object manager functions
4 * Copyright 2005 Robert Shearman
5 * Copyright 2005 Vitaliy Margolen
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "ntdll_test.h"
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
);
51 static void test_case_sensitive (void)
53 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};
54 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};
55 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};
56 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 OBJECT_ATTRIBUTES attr
;
60 HANDLE Event
, Mutant
, h
;
62 pRtlInitUnicodeString(&str
, buffer1
);
63 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
64 status
= pNtCreateMutant(&Mutant
, GENERIC_ALL
, &attr
, FALSE
);
65 ok(status
== STATUS_SUCCESS
, "Failed to create Mutant(%08x)\n", status
);
67 status
= pNtCreateEvent(&Event
, GENERIC_ALL
, &attr
, FALSE
, FALSE
);
68 ok(status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_OBJECT_TYPE_MISMATCH
,
69 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status
);
71 pRtlInitUnicodeString(&str
, buffer2
);
72 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
73 status
= pNtCreateEvent(&Event
, GENERIC_ALL
, &attr
, FALSE
, FALSE
);
74 ok(status
== STATUS_SUCCESS
, "Failed to create Event(%08x)\n", status
);
76 pRtlInitUnicodeString(&str
, buffer3
);
77 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
78 status
= pNtOpenMutant(&h
, GENERIC_ALL
, &attr
);
79 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
,
80 "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status
);
84 pRtlInitUnicodeString(&str
, buffer4
);
85 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
86 status
= pNtCreateMutant(&Mutant
, GENERIC_ALL
, &attr
, FALSE
);
87 ok(status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_OBJECT_TYPE_MISMATCH
,
88 "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status
);
90 status
= pNtCreateEvent(&h
, GENERIC_ALL
, &attr
, FALSE
, FALSE
);
91 ok(status
== STATUS_OBJECT_NAME_COLLISION
,
92 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status
);
95 status
= pNtCreateMutant(&Mutant
, GENERIC_ALL
, &attr
, FALSE
);
96 ok(status
== STATUS_OBJECT_PATH_NOT_FOUND
,
97 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status
);
102 static void test_namespace_pipe(void)
104 static const WCHAR buffer1
[] = {'\\','?','?','\\','P','I','P','E','\\','t','e','s','t','\\','p','i','p','e',0};
105 static const WCHAR buffer2
[] = {'\\','?','?','\\','P','I','P','E','\\','T','E','S','T','\\','P','I','P','E',0};
106 static const WCHAR buffer3
[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t','\\','p','i','p','e',0};
107 static const WCHAR buffer4
[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t',0};
108 OBJECT_ATTRIBUTES attr
;
110 IO_STATUS_BLOCK iosb
;
112 LARGE_INTEGER timeout
;
115 timeout
.QuadPart
= -10000;
117 pRtlInitUnicodeString(&str
, buffer1
);
118 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
119 status
= pNtCreateNamedPipeFile(&pipe
, GENERIC_READ
|GENERIC_WRITE
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
120 FILE_CREATE
, FILE_PIPE_FULL_DUPLEX
, FALSE
, FALSE
, FALSE
, 1, 256, 256, &timeout
);
121 ok(status
== STATUS_SUCCESS
, "Failed to create NamedPipe(%08x)\n", status
);
123 status
= pNtCreateNamedPipeFile(&pipe
, GENERIC_READ
|GENERIC_WRITE
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
124 FILE_CREATE
, FILE_PIPE_FULL_DUPLEX
, FALSE
, FALSE
, FALSE
, 1, 256, 256, &timeout
);
125 ok(status
== STATUS_INSTANCE_NOT_AVAILABLE
,
126 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status
);
128 pRtlInitUnicodeString(&str
, buffer2
);
129 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
130 status
= pNtCreateNamedPipeFile(&pipe
, GENERIC_READ
|GENERIC_WRITE
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
131 FILE_CREATE
, FILE_PIPE_FULL_DUPLEX
, FALSE
, FALSE
, FALSE
, 1, 256, 256, &timeout
);
132 ok(status
== STATUS_INSTANCE_NOT_AVAILABLE
,
133 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status
);
135 h
= CreateFileA("\\\\.\\pipe\\test\\pipe", GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
,
136 OPEN_EXISTING
, 0, 0 );
137 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open NamedPipe (%u)\n", GetLastError());
140 pRtlInitUnicodeString(&str
, buffer3
);
141 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
142 status
= pNtOpenFile(&h
, GENERIC_READ
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
);
143 ok(status
== STATUS_OBJECT_PATH_NOT_FOUND
||
144 status
== STATUS_PIPE_NOT_AVAILABLE
||
145 status
== STATUS_OBJECT_NAME_INVALID
, /* vista */
146 "NtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status
);
148 pRtlInitUnicodeString(&str
, buffer4
);
149 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
150 status
= pNtOpenFile(&h
, GENERIC_READ
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
);
151 ok(status
== STATUS_OBJECT_NAME_NOT_FOUND
||
152 status
== STATUS_OBJECT_NAME_INVALID
, /* vista */
153 "NtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08x)\n", status
);
158 #define DIRECTORY_QUERY (0x0001)
159 #define SYMBOLIC_LINK_QUERY 0x0001
161 #define DIR_TEST_CREATE_FAILURE(h,e) \
162 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr);\
163 ok(status == e,"NtCreateDirectoryObject should have failed with %s got(%08x)\n", #e, status);
164 #define DIR_TEST_OPEN_FAILURE(h,e) \
165 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr);\
166 ok(status == e,"NtOpenDirectoryObject should have failed with %s got(%08x)\n", #e, status);
167 #define DIR_TEST_CREATE_OPEN_FAILURE(h,n,e) \
168 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
169 DIR_TEST_CREATE_FAILURE(h,e) DIR_TEST_OPEN_FAILURE(h,e)\
170 pRtlFreeUnicodeString(&str);
172 #define DIR_TEST_CREATE_SUCCESS(h) \
173 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr); \
174 ok(status == STATUS_SUCCESS, "Failed to create Directory(%08x)\n", status);
175 #define DIR_TEST_OPEN_SUCCESS(h) \
176 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr); \
177 ok(status == STATUS_SUCCESS, "Failed to open Directory(%08x)\n", status);
178 #define DIR_TEST_CREATE_OPEN_SUCCESS(h,n) \
179 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
180 DIR_TEST_CREATE_SUCCESS(&h) pNtClose(h); DIR_TEST_OPEN_SUCCESS(&h) pNtClose(h); \
181 pRtlFreeUnicodeString(&str);
183 static BOOL
is_correct_dir( HANDLE dir
, const char *name
)
187 OBJECT_ATTRIBUTES attr
;
190 pRtlCreateUnicodeStringFromAsciiz(&str
, name
);
191 InitializeObjectAttributes(&attr
, &str
, OBJ_OPENIF
, dir
, NULL
);
192 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
193 pRtlFreeUnicodeString(&str
);
194 if (h
) pNtClose( h
);
195 return (status
== STATUS_OBJECT_NAME_EXISTS
);
198 /* return a handle to the BaseNamedObjects dir where kernel32 objects get created */
199 static HANDLE
get_base_dir(void)
201 static const char objname
[] = "om.c_get_base_dir_obj";
204 OBJECT_ATTRIBUTES attr
;
208 h
= CreateMutexA(NULL
, FALSE
, objname
);
209 ok(h
!= 0, "CreateMutexA failed got ret=%p (%d)\n", h
, GetLastError());
210 InitializeObjectAttributes(&attr
, &str
, OBJ_OPENIF
, 0, NULL
);
212 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\Local");
213 status
= pNtOpenDirectoryObject(&dir
, DIRECTORY_QUERY
, &attr
);
214 pRtlFreeUnicodeString(&str
);
215 if (!status
&& is_correct_dir( dir
, objname
)) goto done
;
216 if (!status
) pNtClose( dir
);
218 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects");
219 status
= pNtOpenDirectoryObject(&dir
, DIRECTORY_QUERY
, &attr
);
220 pRtlFreeUnicodeString(&str
);
221 if (!status
&& is_correct_dir( dir
, objname
)) goto done
;
222 if (!status
) pNtClose( dir
);
224 for (i
= 0; i
< 20; i
++)
227 sprintf( name
, "\\BaseNamedObjects\\Session\\%u", i
);
228 pRtlCreateUnicodeStringFromAsciiz(&str
, name
);
229 status
= pNtOpenDirectoryObject(&dir
, DIRECTORY_QUERY
, &attr
);
230 pRtlFreeUnicodeString(&str
);
231 if (!status
&& is_correct_dir( dir
, objname
)) goto done
;
232 if (!status
) pNtClose( dir
);
241 static void test_name_collisions(void)
245 OBJECT_ATTRIBUTES attr
;
246 HANDLE dir
, h
, h1
, h2
;
250 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
251 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\");
252 DIR_TEST_CREATE_FAILURE(&h
, STATUS_OBJECT_NAME_COLLISION
)
253 InitializeObjectAttributes(&attr
, &str
, OBJ_OPENIF
, 0, NULL
);
255 DIR_TEST_CREATE_FAILURE(&h
, STATUS_OBJECT_NAME_EXISTS
)
257 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
258 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
,
259 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status
);
260 pRtlFreeUnicodeString(&str
);
262 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\??\\PIPE\\om.c-mutant");
263 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
264 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_OBJECT_PATH_NOT_FOUND
,
265 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status
);
266 pRtlFreeUnicodeString(&str
);
268 if (!(dir
= get_base_dir()))
270 win_skip( "couldn't find the BaseNamedObjects dir\n" );
273 pRtlCreateUnicodeStringFromAsciiz(&str
, "om.c-test");
274 InitializeObjectAttributes(&attr
, &str
, OBJ_OPENIF
, dir
, NULL
);
275 h
= CreateMutexA(NULL
, FALSE
, "om.c-test");
276 ok(h
!= 0, "CreateMutexA failed got ret=%p (%d)\n", h
, GetLastError());
277 status
= pNtCreateMutant(&h1
, GENERIC_ALL
, &attr
, FALSE
);
278 ok(status
== STATUS_OBJECT_NAME_EXISTS
&& h1
!= NULL
,
279 "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status
);
280 h2
= CreateMutexA(NULL
, FALSE
, "om.c-test");
281 winerr
= GetLastError();
282 ok(h2
!= 0 && winerr
== ERROR_ALREADY_EXISTS
,
283 "CreateMutexA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2
, winerr
);
288 h
= CreateEventA(NULL
, FALSE
, FALSE
, "om.c-test");
289 ok(h
!= 0, "CreateEventA failed got ret=%p (%d)\n", h
, GetLastError());
290 status
= pNtCreateEvent(&h1
, GENERIC_ALL
, &attr
, FALSE
, FALSE
);
291 ok(status
== STATUS_OBJECT_NAME_EXISTS
&& h1
!= NULL
,
292 "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status
);
293 h2
= CreateEventA(NULL
, FALSE
, FALSE
, "om.c-test");
294 winerr
= GetLastError();
295 ok(h2
!= 0 && winerr
== ERROR_ALREADY_EXISTS
,
296 "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2
, winerr
);
301 h
= CreateSemaphoreA(NULL
, 1, 2, "om.c-test");
302 ok(h
!= 0, "CreateSemaphoreA failed got ret=%p (%d)\n", h
, GetLastError());
303 status
= pNtCreateSemaphore(&h1
, GENERIC_ALL
, &attr
, 1, 2);
304 ok(status
== STATUS_OBJECT_NAME_EXISTS
&& h1
!= NULL
,
305 "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status
);
306 h2
= CreateSemaphoreA(NULL
, 1, 2, "om.c-test");
307 winerr
= GetLastError();
308 ok(h2
!= 0 && winerr
== ERROR_ALREADY_EXISTS
,
309 "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2
, winerr
);
314 h
= pCreateWaitableTimerA(NULL
, TRUE
, "om.c-test");
315 ok(h
!= 0, "CreateWaitableTimerA failed got ret=%p (%d)\n", h
, GetLastError());
316 status
= pNtCreateTimer(&h1
, GENERIC_ALL
, &attr
, NotificationTimer
);
317 ok(status
== STATUS_OBJECT_NAME_EXISTS
&& h1
!= NULL
,
318 "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status
);
319 h2
= pCreateWaitableTimerA(NULL
, TRUE
, "om.c-test");
320 winerr
= GetLastError();
321 ok(h2
!= 0 && winerr
== ERROR_ALREADY_EXISTS
,
322 "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2
, winerr
);
327 h
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 256, "om.c-test");
328 ok(h
!= 0, "CreateFileMappingA failed got ret=%p (%d)\n", h
, GetLastError());
329 size
.u
.LowPart
= 256;
331 status
= pNtCreateSection(&h1
, SECTION_MAP_WRITE
, &attr
, &size
, PAGE_READWRITE
, SEC_COMMIT
, 0);
332 ok(status
== STATUS_OBJECT_NAME_EXISTS
&& h1
!= NULL
,
333 "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status
);
334 h2
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 256, "om.c-test");
335 winerr
= GetLastError();
336 ok(h2
!= 0 && winerr
== ERROR_ALREADY_EXISTS
,
337 "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2
, winerr
);
342 pRtlFreeUnicodeString(&str
);
346 static void test_directory(void)
350 OBJECT_ATTRIBUTES attr
;
354 /* No name and/or no attributes */
355 status
= pNtCreateDirectoryObject(NULL
, DIRECTORY_QUERY
, &attr
);
356 ok(status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_PARAMETER
,
357 "NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status
);
358 status
= pNtOpenDirectoryObject(NULL
, DIRECTORY_QUERY
, &attr
);
359 ok(status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_PARAMETER
,
360 "NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status
);
362 status
= pNtCreateDirectoryObject(&h
, DIRECTORY_QUERY
, NULL
);
363 ok(status
== STATUS_SUCCESS
, "Failed to create Directory without attributes(%08x)\n", status
);
365 status
= pNtOpenDirectoryObject(&h
, DIRECTORY_QUERY
, NULL
);
366 ok(status
== STATUS_INVALID_PARAMETER
,
367 "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status
);
369 InitializeObjectAttributes(&attr
, NULL
, 0, 0, NULL
);
370 DIR_TEST_CREATE_SUCCESS(&dir
)
371 DIR_TEST_OPEN_FAILURE(&h
, STATUS_OBJECT_PATH_SYNTAX_BAD
)
374 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
376 pRtlCreateUnicodeStringFromAsciiz(&str
, "");
377 DIR_TEST_CREATE_SUCCESS(&h
)
379 DIR_TEST_OPEN_FAILURE(&h
, STATUS_OBJECT_PATH_SYNTAX_BAD
)
380 pRtlFreeUnicodeString(&str
);
383 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD
)
384 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID
)
385 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID
)
386 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID
)
387 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND
)
389 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\om.c-test");
390 DIR_TEST_CREATE_SUCCESS(&h
)
391 DIR_TEST_OPEN_SUCCESS(&dir1
)
392 pRtlFreeUnicodeString(&str
);
397 /* Use of root directory */
399 /* Can't use symlinks as a directory */
400 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\Local");
401 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
402 status
= pNtOpenSymbolicLinkObject(&dir
, SYMBOLIC_LINK_QUERY
, &attr
);
403 is_nt4
= (status
== STATUS_OBJECT_NAME_NOT_FOUND
); /* nt4 doesn't have Local\\ symlink */
409 ok(status
== STATUS_SUCCESS
, "Failed to open SymbolicLink(%08x)\n", status
);
410 pRtlFreeUnicodeString(&str
);
411 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
412 pRtlCreateUnicodeStringFromAsciiz(&str
, "one more level");
413 DIR_TEST_CREATE_FAILURE(&h
, STATUS_OBJECT_TYPE_MISMATCH
)
414 pRtlFreeUnicodeString(&str
);
417 str
.MaximumLength
= sizeof(buffer
);
419 memset( buffer
, 0xaa, sizeof(buffer
) );
420 status
= pNtQuerySymbolicLinkObject( dir
, &str
, &len
);
421 ok( status
== STATUS_SUCCESS
, "NtQuerySymbolicLinkObject failed %08x\n", status
);
422 if (status
!= STATUS_SUCCESS
)
424 full_len
= str
.Length
+ sizeof(WCHAR
);
425 ok( len
== full_len
, "bad length %u/%u\n", len
, full_len
);
427 ok( buffer
[len
/ sizeof(WCHAR
) - 1] == 0, "no terminating null\n" );
429 str
.MaximumLength
= str
.Length
;
431 status
= pNtQuerySymbolicLinkObject( dir
, &str
, &len
);
432 ok( status
== STATUS_BUFFER_TOO_SMALL
, "NtQuerySymbolicLinkObject failed %08x\n", status
);
433 ok( len
== full_len
, "bad length %u/%u\n", len
, full_len
);
435 str
.MaximumLength
= 0;
437 status
= pNtQuerySymbolicLinkObject( dir
, &str
, &len
);
438 ok( status
== STATUS_BUFFER_TOO_SMALL
, "NtQuerySymbolicLinkObject failed %08x\n", status
);
439 ok( len
== full_len
, "bad length %u/%u\n", len
, full_len
);
441 str
.MaximumLength
= str
.Length
+ sizeof(WCHAR
);
443 status
= pNtQuerySymbolicLinkObject( dir
, &str
, &len
);
444 ok( status
== STATUS_SUCCESS
, "NtQuerySymbolicLinkObject failed %08x\n", status
);
445 ok( len
== full_len
, "bad length %u/%u\n", len
, full_len
);
451 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects");
452 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
453 DIR_TEST_OPEN_SUCCESS(&dir
)
454 pRtlFreeUnicodeString(&str
);
456 InitializeObjectAttributes(&attr
, NULL
, 0, dir
, NULL
);
457 DIR_TEST_OPEN_FAILURE(&h
, STATUS_OBJECT_NAME_INVALID
)
459 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
460 DIR_TEST_CREATE_OPEN_SUCCESS(h
, "")
461 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD
)
462 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\om.c-test", 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_NOT_FOUND
)
466 pRtlCreateUnicodeStringFromAsciiz(&str
, "om.c-test");
467 DIR_TEST_CREATE_SUCCESS(&dir1
)
468 DIR_TEST_OPEN_SUCCESS(&h
)
469 pRtlFreeUnicodeString(&str
);
475 /* Nested directories */
476 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\");
477 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
478 DIR_TEST_OPEN_SUCCESS(&dir
)
479 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
480 DIR_TEST_OPEN_FAILURE(&h
, STATUS_OBJECT_PATH_SYNTAX_BAD
)
481 pRtlFreeUnicodeString(&str
);
484 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
485 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\om.c-test");
486 DIR_TEST_CREATE_SUCCESS(&dir
)
487 pRtlFreeUnicodeString(&str
);
488 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\om.c-test\\one more level");
489 DIR_TEST_CREATE_SUCCESS(&h
)
490 pRtlFreeUnicodeString(&str
);
492 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
493 pRtlCreateUnicodeStringFromAsciiz(&str
, "one more level");
494 DIR_TEST_CREATE_SUCCESS(&h
)
495 pRtlFreeUnicodeString(&str
);
502 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
503 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\Global\\om.c-test");
504 DIR_TEST_CREATE_SUCCESS(&dir
)
505 pRtlFreeUnicodeString(&str
);
506 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\Local\\om.c-test\\one more level");
507 DIR_TEST_CREATE_SUCCESS(&h
)
508 pRtlFreeUnicodeString(&str
);
510 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
511 pRtlCreateUnicodeStringFromAsciiz(&str
, "one more level");
512 DIR_TEST_CREATE_SUCCESS(&dir
)
513 pRtlFreeUnicodeString(&str
);
518 /* Create other objects using RootDirectory */
520 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
521 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects");
522 DIR_TEST_OPEN_SUCCESS(&dir
)
523 pRtlFreeUnicodeString(&str
);
524 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
526 /* Test invalid paths */
527 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\om.c-mutant");
528 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
529 ok(status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
530 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status
);
531 pRtlFreeUnicodeString(&str
);
532 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\om.c-mutant\\");
533 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
534 ok(status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
535 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status
);
536 pRtlFreeUnicodeString(&str
);
538 pRtlCreateUnicodeStringFromAsciiz(&str
, "om.c\\-mutant");
539 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
540 ok(status
== STATUS_OBJECT_PATH_NOT_FOUND
,
541 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status
);
542 pRtlFreeUnicodeString(&str
);
544 pRtlCreateUnicodeStringFromAsciiz(&str
, "om.c-mutant");
545 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
546 ok(status
== STATUS_SUCCESS
, "Failed to create Mutant(%08x)\n", status
);
547 pRtlFreeUnicodeString(&str
);
553 #define SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e2) \
554 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
555 pRtlCreateUnicodeStringFromAsciiz(&target, t);\
556 status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\
557 ok(status == e || status == e2, \
558 "NtCreateSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
559 status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\
560 ok(status == e || status == e2, \
561 "NtOpenSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
562 pRtlFreeUnicodeString(&target);\
563 pRtlFreeUnicodeString(&str);
565 #define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e)
567 static void test_symboliclink(void)
570 UNICODE_STRING str
, target
;
571 OBJECT_ATTRIBUTES attr
;
573 IO_STATUS_BLOCK iosb
;
575 /* No name and/or no attributes */
576 InitializeObjectAttributes(&attr
, NULL
, 0, 0, NULL
);
577 SYMLNK_TEST_CREATE_OPEN_FAILURE2(NULL
, "", "", STATUS_ACCESS_VIOLATION
, STATUS_INVALID_PARAMETER
)
579 status
= pNtCreateSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, NULL
, NULL
);
580 ok(status
== STATUS_ACCESS_VIOLATION
,
581 "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status
);
582 status
= pNtOpenSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, NULL
);
583 ok(status
== STATUS_INVALID_PARAMETER
,
584 "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status
);
587 pRtlCreateUnicodeStringFromAsciiz(&target
, "\\DosDevices");
588 status
= pNtCreateSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, NULL
, &target
);
589 ok(status
== STATUS_SUCCESS
|| status
== STATUS_ACCESS_VIOLATION
, /* nt4 */
590 "NtCreateSymbolicLinkObject failed(%08x)\n", status
);
591 pRtlFreeUnicodeString(&target
);
592 if (!status
) pNtClose(h
);
594 InitializeObjectAttributes(&attr
, NULL
, 0, 0, NULL
);
595 status
= pNtCreateSymbolicLinkObject(&link
, SYMBOLIC_LINK_QUERY
, &attr
, &target
);
596 ok(status
== STATUS_INVALID_PARAMETER
||
597 broken(status
== STATUS_SUCCESS
), /* nt4 */
598 "NtCreateSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status
);
599 if (!status
) pNtClose(h
);
600 status
= pNtOpenSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, &attr
);
601 ok(status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
602 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status
);
605 pRtlCreateUnicodeStringFromAsciiz(&target
, "anywhere");
606 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
608 pRtlCreateUnicodeStringFromAsciiz(&str
, "");
609 status
= pNtCreateSymbolicLinkObject(&link
, SYMBOLIC_LINK_QUERY
, &attr
, &target
);
610 ok(status
== STATUS_SUCCESS
, "Failed to create SymbolicLink(%08x)\n", status
);
611 status
= pNtOpenSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, &attr
);
612 ok(status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
613 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status
);
615 pRtlFreeUnicodeString(&str
);
617 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\");
618 status
= pNtCreateSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, &attr
, &target
);
619 todo_wine
ok(status
== STATUS_OBJECT_TYPE_MISMATCH
,
620 "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status
);
621 pRtlFreeUnicodeString(&str
);
622 pRtlFreeUnicodeString(&target
);
624 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h
, "BaseNamedObjects", "->Somewhere", STATUS_OBJECT_PATH_SYNTAX_BAD
)
625 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h
, "\\BaseNamedObjects\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID
)
626 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h
, "\\\\BaseNamedObjects", "->Somewhere", STATUS_OBJECT_NAME_INVALID
)
627 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h
, "\\BaseNamedObjects\\\\om.c-test", "->Somewhere", STATUS_OBJECT_NAME_INVALID
)
628 SYMLNK_TEST_CREATE_OPEN_FAILURE2(&h
, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere",
629 STATUS_OBJECT_NAME_INVALID
, STATUS_OBJECT_PATH_NOT_FOUND
)
633 if (!(dir
= get_base_dir()))
635 win_skip( "couldn't find the BaseNamedObjects dir\n" );
639 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
640 pRtlCreateUnicodeStringFromAsciiz(&str
, "test-link");
641 pRtlCreateUnicodeStringFromAsciiz(&target
, "\\DosDevices");
642 status
= pNtCreateSymbolicLinkObject(&link
, SYMBOLIC_LINK_QUERY
, &attr
, &target
);
643 ok(status
== STATUS_SUCCESS
, "Failed to create SymbolicLink(%08x)\n", status
);
644 pRtlFreeUnicodeString(&str
);
645 pRtlFreeUnicodeString(&target
);
647 pRtlCreateUnicodeStringFromAsciiz(&str
, "test-link\\NUL");
648 status
= pNtOpenFile(&h
, GENERIC_READ
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
);
649 todo_wine
ok(status
== STATUS_SUCCESS
, "Failed to open NUL device(%08x)\n", status
);
650 pRtlFreeUnicodeString(&str
);
657 static void test_query_object(void)
659 static const WCHAR name
[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',
660 '\\','t','e','s','t','_','e','v','e','n','t'};
668 handle
= CreateEventA( NULL
, FALSE
, FALSE
, "test_event" );
671 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, 0, &len
);
672 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryObject failed %x\n", status
);
673 ok( len
>= sizeof(UNICODE_STRING
) + sizeof(name
) + sizeof(WCHAR
), "unexpected len %u\n", len
);
676 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, sizeof(UNICODE_STRING
), &len
);
677 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryObject failed %x\n", status
);
678 ok( len
>= sizeof(UNICODE_STRING
) + sizeof(name
) + sizeof(WCHAR
), "unexpected len %u\n", len
);
681 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, sizeof(buffer
), &len
);
682 ok( status
== STATUS_SUCCESS
, "NtQueryObject failed %x\n", status
);
683 ok( len
> sizeof(UNICODE_STRING
), "unexpected len %u\n", len
);
684 str
= (UNICODE_STRING
*)buffer
;
685 ok( sizeof(UNICODE_STRING
) + str
->Length
+ sizeof(WCHAR
) == len
, "unexpected len %u\n", len
);
686 ok( str
->Length
>= sizeof(name
), "unexpected len %u\n", str
->Length
);
687 /* there can be a \\Sessions prefix in the name */
688 ok( !memcmp( str
->Buffer
+ (str
->Length
- sizeof(name
)) / sizeof(WCHAR
), name
, sizeof(name
) ),
689 "wrong name %s\n", wine_dbgstr_w(str
->Buffer
) );
691 len
-= sizeof(WCHAR
);
692 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, len
, &len
);
693 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryObject failed %x\n", status
);
694 ok( len
>= sizeof(UNICODE_STRING
) + sizeof(name
) + sizeof(WCHAR
), "unexpected len %u\n", len
);
698 handle
= CreateEventA( NULL
, FALSE
, FALSE
, NULL
);
700 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, sizeof(buffer
), &len
);
701 ok( status
== STATUS_SUCCESS
, "NtQueryObject failed %x\n", status
);
702 ok( len
== sizeof(UNICODE_STRING
), "unexpected len %u\n", len
);
703 str
= (UNICODE_STRING
*)buffer
;
704 ok( str
->Length
== 0, "unexpected len %u\n", len
);
705 ok( str
->Buffer
== NULL
, "unexpected ptr %p\n", str
->Buffer
);
708 GetWindowsDirectoryA( dir
, MAX_PATH
);
709 handle
= CreateFileA( dir
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
710 FILE_FLAG_BACKUP_SEMANTICS
, 0 );
712 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, sizeof(buffer
), &len
);
713 ok( status
== STATUS_SUCCESS
, "NtQueryObject failed %x\n", status
);
714 ok( len
> sizeof(UNICODE_STRING
), "unexpected len %u\n", len
);
715 str
= (UNICODE_STRING
*)buffer
;
716 ok( sizeof(UNICODE_STRING
) + str
->Length
+ sizeof(WCHAR
) == len
||
717 broken(sizeof(UNICODE_STRING
) + str
->Length
== len
), /* NT4 */
718 "unexpected len %u\n", len
);
719 trace( "got %s len %u\n", wine_dbgstr_w(str
->Buffer
), len
);
725 HMODULE hntdll
= GetModuleHandleA("ntdll.dll");
726 HMODULE hkernel32
= GetModuleHandleA("kernel32.dll");
730 skip("not running on NT, skipping test\n");
734 pCreateWaitableTimerA
= (void *)GetProcAddress(hkernel32
, "CreateWaitableTimerA");
736 pRtlCreateUnicodeStringFromAsciiz
= (void *)GetProcAddress(hntdll
, "RtlCreateUnicodeStringFromAsciiz");
737 pRtlFreeUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlFreeUnicodeString");
738 pNtCreateEvent
= (void *)GetProcAddress(hntdll
, "NtCreateEvent");
739 pNtCreateMutant
= (void *)GetProcAddress(hntdll
, "NtCreateMutant");
740 pNtOpenMutant
= (void *)GetProcAddress(hntdll
, "NtOpenMutant");
741 pNtOpenFile
= (void *)GetProcAddress(hntdll
, "NtOpenFile");
742 pNtClose
= (void *)GetProcAddress(hntdll
, "NtClose");
743 pRtlInitUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlInitUnicodeString");
744 pNtCreateNamedPipeFile
= (void *)GetProcAddress(hntdll
, "NtCreateNamedPipeFile");
745 pNtOpenDirectoryObject
= (void *)GetProcAddress(hntdll
, "NtOpenDirectoryObject");
746 pNtCreateDirectoryObject
= (void *)GetProcAddress(hntdll
, "NtCreateDirectoryObject");
747 pNtOpenSymbolicLinkObject
= (void *)GetProcAddress(hntdll
, "NtOpenSymbolicLinkObject");
748 pNtCreateSymbolicLinkObject
= (void *)GetProcAddress(hntdll
, "NtCreateSymbolicLinkObject");
749 pNtQuerySymbolicLinkObject
= (void *)GetProcAddress(hntdll
, "NtQuerySymbolicLinkObject");
750 pNtCreateSemaphore
= (void *)GetProcAddress(hntdll
, "NtCreateSemaphore");
751 pNtCreateTimer
= (void *)GetProcAddress(hntdll
, "NtCreateTimer");
752 pNtCreateSection
= (void *)GetProcAddress(hntdll
, "NtCreateSection");
753 pNtQueryObject
= (void *)GetProcAddress(hntdll
, "NtQueryObject");
755 test_case_sensitive();
756 test_namespace_pipe();
757 test_name_collisions();