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
*pNtQueryObject
)(HANDLE
,OBJECT_INFORMATION_CLASS
,PVOID
,ULONG
,PULONG
);
50 static void test_case_sensitive (void)
52 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};
53 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};
54 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};
55 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};
57 OBJECT_ATTRIBUTES attr
;
59 HANDLE Event
, Mutant
, h
;
61 pRtlInitUnicodeString(&str
, buffer1
);
62 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
63 status
= pNtCreateMutant(&Mutant
, GENERIC_ALL
, &attr
, FALSE
);
64 ok(status
== STATUS_SUCCESS
, "Failed to create Mutant(%08x)\n", status
);
66 status
= pNtCreateEvent(&Event
, GENERIC_ALL
, &attr
, FALSE
, FALSE
);
67 ok(status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_OBJECT_TYPE_MISMATCH
,
68 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status
);
70 pRtlInitUnicodeString(&str
, buffer2
);
71 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
72 status
= pNtCreateEvent(&Event
, GENERIC_ALL
, &attr
, FALSE
, FALSE
);
73 ok(status
== STATUS_SUCCESS
, "Failed to create Event(%08x)\n", status
);
75 pRtlInitUnicodeString(&str
, buffer3
);
76 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
77 status
= pNtOpenMutant(&h
, GENERIC_ALL
, &attr
);
78 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
,
79 "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status
);
83 pRtlInitUnicodeString(&str
, buffer4
);
84 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
85 status
= pNtCreateMutant(&Mutant
, GENERIC_ALL
, &attr
, FALSE
);
86 ok(status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_OBJECT_TYPE_MISMATCH
,
87 "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION or STATUS_OBJECT_TYPE_MISMATCH got (%08x)\n", status
);
89 status
= pNtCreateEvent(&h
, GENERIC_ALL
, &attr
, FALSE
, FALSE
);
90 ok(status
== STATUS_OBJECT_NAME_COLLISION
,
91 "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08x)\n", status
);
94 status
= pNtCreateMutant(&Mutant
, GENERIC_ALL
, &attr
, FALSE
);
95 ok(status
== STATUS_OBJECT_PATH_NOT_FOUND
,
96 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status
);
101 static void test_namespace_pipe(void)
103 static const WCHAR buffer1
[] = {'\\','?','?','\\','P','I','P','E','\\','t','e','s','t','\\','p','i','p','e',0};
104 static const WCHAR buffer2
[] = {'\\','?','?','\\','P','I','P','E','\\','T','E','S','T','\\','P','I','P','E',0};
105 static const WCHAR buffer3
[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t','\\','p','i','p','e',0};
106 static const WCHAR buffer4
[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t',0};
107 OBJECT_ATTRIBUTES attr
;
109 IO_STATUS_BLOCK iosb
;
111 LARGE_INTEGER timeout
;
114 timeout
.QuadPart
= -10000;
116 pRtlInitUnicodeString(&str
, buffer1
);
117 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
118 status
= pNtCreateNamedPipeFile(&pipe
, GENERIC_READ
|GENERIC_WRITE
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
119 FILE_CREATE
, FILE_PIPE_FULL_DUPLEX
, FALSE
, FALSE
, FALSE
, 1, 256, 256, &timeout
);
120 ok(status
== STATUS_SUCCESS
, "Failed to create NamedPipe(%08x)\n", status
);
122 status
= pNtCreateNamedPipeFile(&pipe
, GENERIC_READ
|GENERIC_WRITE
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
123 FILE_CREATE
, FILE_PIPE_FULL_DUPLEX
, FALSE
, FALSE
, FALSE
, 1, 256, 256, &timeout
);
124 ok(status
== STATUS_INSTANCE_NOT_AVAILABLE
,
125 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status
);
127 pRtlInitUnicodeString(&str
, buffer2
);
128 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
129 status
= pNtCreateNamedPipeFile(&pipe
, GENERIC_READ
|GENERIC_WRITE
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
130 FILE_CREATE
, FILE_PIPE_FULL_DUPLEX
, FALSE
, FALSE
, FALSE
, 1, 256, 256, &timeout
);
131 ok(status
== STATUS_INSTANCE_NOT_AVAILABLE
,
132 "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08x)\n", status
);
134 h
= CreateFileA("\\\\.\\pipe\\test\\pipe", GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
,
135 OPEN_EXISTING
, 0, 0 );
136 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open NamedPipe (%u)\n", GetLastError());
139 pRtlInitUnicodeString(&str
, buffer3
);
140 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
141 status
= pNtOpenFile(&h
, GENERIC_READ
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
);
142 ok(status
== STATUS_OBJECT_PATH_NOT_FOUND
||
143 status
== STATUS_PIPE_NOT_AVAILABLE
||
144 status
== STATUS_OBJECT_NAME_INVALID
, /* vista */
145 "NtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status
);
147 pRtlInitUnicodeString(&str
, buffer4
);
148 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
149 status
= pNtOpenFile(&h
, GENERIC_READ
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
);
150 ok(status
== STATUS_OBJECT_NAME_NOT_FOUND
||
151 status
== STATUS_OBJECT_NAME_INVALID
, /* vista */
152 "NtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08x)\n", status
);
157 #define DIRECTORY_QUERY (0x0001)
158 #define SYMBOLIC_LINK_QUERY 0x0001
160 #define DIR_TEST_CREATE_FAILURE(h,e) \
161 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr);\
162 ok(status == e,"NtCreateDirectoryObject should have failed with %s got(%08x)\n", #e, status);
163 #define DIR_TEST_OPEN_FAILURE(h,e) \
164 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr);\
165 ok(status == e,"NtOpenDirectoryObject should have failed with %s got(%08x)\n", #e, status);
166 #define DIR_TEST_CREATE_OPEN_FAILURE(h,n,e) \
167 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
168 DIR_TEST_CREATE_FAILURE(h,e) DIR_TEST_OPEN_FAILURE(h,e)\
169 pRtlFreeUnicodeString(&str);
171 #define DIR_TEST_CREATE_SUCCESS(h) \
172 status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr); \
173 ok(status == STATUS_SUCCESS, "Failed to create Directory(%08x)\n", status);
174 #define DIR_TEST_OPEN_SUCCESS(h) \
175 status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr); \
176 ok(status == STATUS_SUCCESS, "Failed to open Directory(%08x)\n", status);
177 #define DIR_TEST_CREATE_OPEN_SUCCESS(h,n) \
178 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
179 DIR_TEST_CREATE_SUCCESS(&h) pNtClose(h); DIR_TEST_OPEN_SUCCESS(&h) pNtClose(h); \
180 pRtlFreeUnicodeString(&str);
182 static BOOL
is_correct_dir( HANDLE dir
, const char *name
)
186 OBJECT_ATTRIBUTES attr
;
189 pRtlCreateUnicodeStringFromAsciiz(&str
, name
);
190 InitializeObjectAttributes(&attr
, &str
, OBJ_OPENIF
, dir
, NULL
);
191 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
192 pRtlFreeUnicodeString(&str
);
193 if (h
) pNtClose( h
);
194 return (status
== STATUS_OBJECT_NAME_EXISTS
);
197 /* return a handle to the BaseNamedObjects dir where kernel32 objects get created */
198 static HANDLE
get_base_dir(void)
200 static const char objname
[] = "om.c_get_base_dir_obj";
203 OBJECT_ATTRIBUTES attr
;
207 h
= CreateMutexA(NULL
, FALSE
, objname
);
208 ok(h
!= 0, "CreateMutexA failed got ret=%p (%d)\n", h
, GetLastError());
209 InitializeObjectAttributes(&attr
, &str
, OBJ_OPENIF
, 0, NULL
);
211 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\Local");
212 status
= pNtOpenDirectoryObject(&dir
, DIRECTORY_QUERY
, &attr
);
213 pRtlFreeUnicodeString(&str
);
214 if (!status
&& is_correct_dir( dir
, objname
)) goto done
;
215 if (!status
) pNtClose( dir
);
217 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects");
218 status
= pNtOpenDirectoryObject(&dir
, DIRECTORY_QUERY
, &attr
);
219 pRtlFreeUnicodeString(&str
);
220 if (!status
&& is_correct_dir( dir
, objname
)) goto done
;
221 if (!status
) pNtClose( dir
);
223 for (i
= 0; i
< 20; i
++)
226 sprintf( name
, "\\BaseNamedObjects\\Session\\%u", i
);
227 pRtlCreateUnicodeStringFromAsciiz(&str
, name
);
228 status
= pNtOpenDirectoryObject(&dir
, DIRECTORY_QUERY
, &attr
);
229 pRtlFreeUnicodeString(&str
);
230 if (!status
&& is_correct_dir( dir
, objname
)) goto done
;
231 if (!status
) pNtClose( dir
);
240 static void test_name_collisions(void)
244 OBJECT_ATTRIBUTES attr
;
245 HANDLE dir
, h
, h1
, h2
;
249 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
250 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\");
251 DIR_TEST_CREATE_FAILURE(&h
, STATUS_OBJECT_NAME_COLLISION
)
252 InitializeObjectAttributes(&attr
, &str
, OBJ_OPENIF
, 0, NULL
);
254 DIR_TEST_CREATE_FAILURE(&h
, STATUS_OBJECT_NAME_EXISTS
)
256 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
257 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
,
258 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status
);
259 pRtlFreeUnicodeString(&str
);
261 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\??\\PIPE\\om.c-mutant");
262 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
263 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_OBJECT_PATH_NOT_FOUND
,
264 "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status
);
265 pRtlFreeUnicodeString(&str
);
267 if (!(dir
= get_base_dir()))
269 win_skip( "couldn't find the BaseNamedObjects dir\n" );
272 pRtlCreateUnicodeStringFromAsciiz(&str
, "om.c-test");
273 InitializeObjectAttributes(&attr
, &str
, OBJ_OPENIF
, dir
, NULL
);
274 h
= CreateMutexA(NULL
, FALSE
, "om.c-test");
275 ok(h
!= 0, "CreateMutexA failed got ret=%p (%d)\n", h
, GetLastError());
276 status
= pNtCreateMutant(&h1
, GENERIC_ALL
, &attr
, FALSE
);
277 ok(status
== STATUS_OBJECT_NAME_EXISTS
&& h1
!= NULL
,
278 "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status
);
279 h2
= CreateMutexA(NULL
, FALSE
, "om.c-test");
280 winerr
= GetLastError();
281 ok(h2
!= 0 && winerr
== ERROR_ALREADY_EXISTS
,
282 "CreateMutexA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2
, winerr
);
287 h
= CreateEventA(NULL
, FALSE
, FALSE
, "om.c-test");
288 ok(h
!= 0, "CreateEventA failed got ret=%p (%d)\n", h
, GetLastError());
289 status
= pNtCreateEvent(&h1
, GENERIC_ALL
, &attr
, FALSE
, FALSE
);
290 ok(status
== STATUS_OBJECT_NAME_EXISTS
&& h1
!= NULL
,
291 "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status
);
292 h2
= CreateEventA(NULL
, FALSE
, FALSE
, "om.c-test");
293 winerr
= GetLastError();
294 ok(h2
!= 0 && winerr
== ERROR_ALREADY_EXISTS
,
295 "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2
, winerr
);
300 h
= CreateSemaphoreA(NULL
, 1, 2, "om.c-test");
301 ok(h
!= 0, "CreateSemaphoreA failed got ret=%p (%d)\n", h
, GetLastError());
302 status
= pNtCreateSemaphore(&h1
, GENERIC_ALL
, &attr
, 1, 2);
303 ok(status
== STATUS_OBJECT_NAME_EXISTS
&& h1
!= NULL
,
304 "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status
);
305 h2
= CreateSemaphoreA(NULL
, 1, 2, "om.c-test");
306 winerr
= GetLastError();
307 ok(h2
!= 0 && winerr
== ERROR_ALREADY_EXISTS
,
308 "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2
, winerr
);
313 h
= pCreateWaitableTimerA(NULL
, TRUE
, "om.c-test");
314 ok(h
!= 0, "CreateWaitableTimerA failed got ret=%p (%d)\n", h
, GetLastError());
315 status
= pNtCreateTimer(&h1
, GENERIC_ALL
, &attr
, NotificationTimer
);
316 ok(status
== STATUS_OBJECT_NAME_EXISTS
&& h1
!= NULL
,
317 "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status
);
318 h2
= pCreateWaitableTimerA(NULL
, TRUE
, "om.c-test");
319 winerr
= GetLastError();
320 ok(h2
!= 0 && winerr
== ERROR_ALREADY_EXISTS
,
321 "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2
, winerr
);
326 h
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 256, "om.c-test");
327 ok(h
!= 0, "CreateFileMappingA failed got ret=%p (%d)\n", h
, GetLastError());
328 size
.u
.LowPart
= 256;
330 status
= pNtCreateSection(&h1
, SECTION_MAP_WRITE
, &attr
, &size
, PAGE_READWRITE
, SEC_COMMIT
, 0);
331 ok(status
== STATUS_OBJECT_NAME_EXISTS
&& h1
!= NULL
,
332 "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08x)\n", status
);
333 h2
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 256, "om.c-test");
334 winerr
= GetLastError();
335 ok(h2
!= 0 && winerr
== ERROR_ALREADY_EXISTS
,
336 "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%d)\n", h2
, winerr
);
341 pRtlFreeUnicodeString(&str
);
345 static void test_directory(void)
349 OBJECT_ATTRIBUTES attr
;
353 /* No name and/or no attributes */
354 status
= pNtCreateDirectoryObject(NULL
, DIRECTORY_QUERY
, &attr
);
355 ok(status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_PARAMETER
,
356 "NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status
);
357 status
= pNtOpenDirectoryObject(NULL
, DIRECTORY_QUERY
, &attr
);
358 ok(status
== STATUS_ACCESS_VIOLATION
|| status
== STATUS_INVALID_PARAMETER
,
359 "NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status
);
361 status
= pNtCreateDirectoryObject(&h
, DIRECTORY_QUERY
, NULL
);
362 ok(status
== STATUS_SUCCESS
, "Failed to create Directory without attributes(%08x)\n", status
);
364 status
= pNtOpenDirectoryObject(&h
, DIRECTORY_QUERY
, NULL
);
365 ok(status
== STATUS_INVALID_PARAMETER
,
366 "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status
);
368 InitializeObjectAttributes(&attr
, NULL
, 0, 0, NULL
);
369 DIR_TEST_CREATE_SUCCESS(&dir
)
370 DIR_TEST_OPEN_FAILURE(&h
, STATUS_OBJECT_PATH_SYNTAX_BAD
)
373 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
375 pRtlCreateUnicodeStringFromAsciiz(&str
, "");
376 DIR_TEST_CREATE_SUCCESS(&h
)
378 DIR_TEST_OPEN_FAILURE(&h
, STATUS_OBJECT_PATH_SYNTAX_BAD
)
379 pRtlFreeUnicodeString(&str
);
382 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD
)
383 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID
)
384 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID
)
385 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID
)
386 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND
)
388 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\om.c-test");
389 DIR_TEST_CREATE_SUCCESS(&h
)
390 DIR_TEST_OPEN_SUCCESS(&dir1
)
391 pRtlFreeUnicodeString(&str
);
396 /* Use of root directory */
398 /* Can't use symlinks as a directory */
399 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\Local");
400 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
401 status
= pNtOpenSymbolicLinkObject(&dir
, SYMBOLIC_LINK_QUERY
, &attr
);
402 is_nt4
= (status
== STATUS_OBJECT_NAME_NOT_FOUND
); /* nt4 doesn't have Local\\ symlink */
405 ok(status
== STATUS_SUCCESS
, "Failed to open SymbolicLink(%08x)\n", status
);
406 pRtlFreeUnicodeString(&str
);
407 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
408 pRtlCreateUnicodeStringFromAsciiz(&str
, "one more level");
409 DIR_TEST_CREATE_FAILURE(&h
, STATUS_OBJECT_TYPE_MISMATCH
)
410 pRtlFreeUnicodeString(&str
);
415 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects");
416 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
417 DIR_TEST_OPEN_SUCCESS(&dir
)
418 pRtlFreeUnicodeString(&str
);
420 InitializeObjectAttributes(&attr
, NULL
, 0, dir
, NULL
);
421 DIR_TEST_OPEN_FAILURE(&h
, STATUS_OBJECT_NAME_INVALID
)
423 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
424 DIR_TEST_CREATE_OPEN_SUCCESS(h
, "")
425 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD
)
426 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD
)
427 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD
)
428 DIR_TEST_CREATE_OPEN_FAILURE(&h
, "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND
)
430 pRtlCreateUnicodeStringFromAsciiz(&str
, "om.c-test");
431 DIR_TEST_CREATE_SUCCESS(&dir1
)
432 DIR_TEST_OPEN_SUCCESS(&h
)
433 pRtlFreeUnicodeString(&str
);
439 /* Nested directories */
440 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\");
441 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
442 DIR_TEST_OPEN_SUCCESS(&dir
)
443 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
444 DIR_TEST_OPEN_FAILURE(&h
, STATUS_OBJECT_PATH_SYNTAX_BAD
)
445 pRtlFreeUnicodeString(&str
);
448 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
449 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\om.c-test");
450 DIR_TEST_CREATE_SUCCESS(&dir
)
451 pRtlFreeUnicodeString(&str
);
452 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\om.c-test\\one more level");
453 DIR_TEST_CREATE_SUCCESS(&h
)
454 pRtlFreeUnicodeString(&str
);
456 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
457 pRtlCreateUnicodeStringFromAsciiz(&str
, "one more level");
458 DIR_TEST_CREATE_SUCCESS(&h
)
459 pRtlFreeUnicodeString(&str
);
466 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
467 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\Global\\om.c-test");
468 DIR_TEST_CREATE_SUCCESS(&dir
)
469 pRtlFreeUnicodeString(&str
);
470 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects\\Local\\om.c-test\\one more level");
471 DIR_TEST_CREATE_SUCCESS(&h
)
472 pRtlFreeUnicodeString(&str
);
474 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
475 pRtlCreateUnicodeStringFromAsciiz(&str
, "one more level");
476 DIR_TEST_CREATE_SUCCESS(&dir
)
477 pRtlFreeUnicodeString(&str
);
482 /* Create other objects using RootDirectory */
484 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
485 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\BaseNamedObjects");
486 DIR_TEST_OPEN_SUCCESS(&dir
)
487 pRtlFreeUnicodeString(&str
);
488 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
490 /* Test invalid paths */
491 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\om.c-mutant");
492 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
493 ok(status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
494 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status
);
495 pRtlFreeUnicodeString(&str
);
496 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\om.c-mutant\\");
497 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
498 ok(status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
499 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status
);
500 pRtlFreeUnicodeString(&str
);
502 pRtlCreateUnicodeStringFromAsciiz(&str
, "om.c\\-mutant");
503 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
504 ok(status
== STATUS_OBJECT_PATH_NOT_FOUND
,
505 "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status
);
506 pRtlFreeUnicodeString(&str
);
508 pRtlCreateUnicodeStringFromAsciiz(&str
, "om.c-mutant");
509 status
= pNtCreateMutant(&h
, GENERIC_ALL
, &attr
, FALSE
);
510 ok(status
== STATUS_SUCCESS
, "Failed to create Mutant(%08x)\n", status
);
511 pRtlFreeUnicodeString(&str
);
517 #define SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e2) \
518 pRtlCreateUnicodeStringFromAsciiz(&str, n);\
519 pRtlCreateUnicodeStringFromAsciiz(&target, t);\
520 status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\
521 ok(status == e || status == e2, \
522 "NtCreateSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
523 status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\
524 ok(status == e || status == e2, \
525 "NtOpenSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\
526 pRtlFreeUnicodeString(&target);\
527 pRtlFreeUnicodeString(&str);
529 #define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e)
531 static void test_symboliclink(void)
534 UNICODE_STRING str
, target
;
535 OBJECT_ATTRIBUTES attr
;
537 IO_STATUS_BLOCK iosb
;
539 /* No name and/or no attributes */
540 InitializeObjectAttributes(&attr
, NULL
, 0, 0, NULL
);
541 SYMLNK_TEST_CREATE_OPEN_FAILURE2(NULL
, "", "", STATUS_ACCESS_VIOLATION
, STATUS_INVALID_PARAMETER
)
543 status
= pNtCreateSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, NULL
, NULL
);
544 ok(status
== STATUS_ACCESS_VIOLATION
,
545 "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08x)\n", status
);
546 status
= pNtOpenSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, NULL
);
547 ok(status
== STATUS_INVALID_PARAMETER
,
548 "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status
);
551 pRtlCreateUnicodeStringFromAsciiz(&target
, "\\DosDevices");
552 status
= pNtCreateSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, NULL
, &target
);
553 ok(status
== STATUS_SUCCESS
|| status
== STATUS_ACCESS_VIOLATION
, /* nt4 */
554 "NtCreateSymbolicLinkObject failed(%08x)\n", status
);
555 pRtlFreeUnicodeString(&target
);
556 if (!status
) pNtClose(h
);
558 InitializeObjectAttributes(&attr
, NULL
, 0, 0, NULL
);
559 status
= pNtCreateSymbolicLinkObject(&link
, SYMBOLIC_LINK_QUERY
, &attr
, &target
);
560 ok(status
== STATUS_INVALID_PARAMETER
||
561 broken(status
== STATUS_SUCCESS
), /* nt4 */
562 "NtCreateSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status
);
563 if (!status
) pNtClose(h
);
564 status
= pNtOpenSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, &attr
);
565 ok(status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
566 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status
);
569 pRtlCreateUnicodeStringFromAsciiz(&target
, "anywhere");
570 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
572 pRtlCreateUnicodeStringFromAsciiz(&str
, "");
573 status
= pNtCreateSymbolicLinkObject(&link
, SYMBOLIC_LINK_QUERY
, &attr
, &target
);
574 ok(status
== STATUS_SUCCESS
, "Failed to create SymbolicLink(%08x)\n", status
);
575 status
= pNtOpenSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, &attr
);
576 ok(status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
577 "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status
);
579 pRtlFreeUnicodeString(&str
);
581 pRtlCreateUnicodeStringFromAsciiz(&str
, "\\");
582 status
= pNtCreateSymbolicLinkObject(&h
, SYMBOLIC_LINK_QUERY
, &attr
, &target
);
583 todo_wine
ok(status
== STATUS_OBJECT_TYPE_MISMATCH
,
584 "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status
);
585 pRtlFreeUnicodeString(&str
);
586 pRtlFreeUnicodeString(&target
);
588 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h
, "BaseNamedObjects", "->Somewhere", STATUS_OBJECT_PATH_SYNTAX_BAD
)
589 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h
, "\\BaseNamedObjects\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID
)
590 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h
, "\\\\BaseNamedObjects", "->Somewhere", STATUS_OBJECT_NAME_INVALID
)
591 SYMLNK_TEST_CREATE_OPEN_FAILURE(&h
, "\\BaseNamedObjects\\\\om.c-test", "->Somewhere", STATUS_OBJECT_NAME_INVALID
)
592 SYMLNK_TEST_CREATE_OPEN_FAILURE2(&h
, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere",
593 STATUS_OBJECT_NAME_INVALID
, STATUS_OBJECT_PATH_NOT_FOUND
)
597 if (!(dir
= get_base_dir()))
599 win_skip( "couldn't find the BaseNamedObjects dir\n" );
603 InitializeObjectAttributes(&attr
, &str
, 0, dir
, NULL
);
604 pRtlCreateUnicodeStringFromAsciiz(&str
, "test-link");
605 pRtlCreateUnicodeStringFromAsciiz(&target
, "\\DosDevices");
606 status
= pNtCreateSymbolicLinkObject(&link
, SYMBOLIC_LINK_QUERY
, &attr
, &target
);
607 ok(status
== STATUS_SUCCESS
, "Failed to create SymbolicLink(%08x)\n", status
);
608 pRtlFreeUnicodeString(&str
);
609 pRtlFreeUnicodeString(&target
);
611 pRtlCreateUnicodeStringFromAsciiz(&str
, "test-link\\NUL");
612 status
= pNtOpenFile(&h
, GENERIC_READ
, &attr
, &iosb
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
);
613 todo_wine
ok(status
== STATUS_SUCCESS
, "Failed to open NUL device(%08x)\n", status
);
614 pRtlFreeUnicodeString(&str
);
621 static void test_query_object(void)
623 static const WCHAR name
[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',
624 '\\','t','e','s','t','_','e','v','e','n','t'};
632 handle
= CreateEventA( NULL
, FALSE
, FALSE
, "test_event" );
635 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, 0, &len
);
636 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryObject failed %x\n", status
);
637 ok( len
>= sizeof(UNICODE_STRING
) + sizeof(name
) + sizeof(WCHAR
), "unexpected len %u\n", len
);
640 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, sizeof(UNICODE_STRING
), &len
);
641 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryObject failed %x\n", status
);
642 ok( len
>= sizeof(UNICODE_STRING
) + sizeof(name
) + sizeof(WCHAR
), "unexpected len %u\n", len
);
645 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, sizeof(buffer
), &len
);
646 ok( status
== STATUS_SUCCESS
, "NtQueryObject failed %x\n", status
);
647 ok( len
> sizeof(UNICODE_STRING
), "unexpected len %u\n", len
);
648 str
= (UNICODE_STRING
*)buffer
;
649 ok( sizeof(UNICODE_STRING
) + str
->Length
+ sizeof(WCHAR
) == len
, "unexpected len %u\n", len
);
650 ok( str
->Length
>= sizeof(name
), "unexpected len %u\n", str
->Length
);
651 /* there can be a \\Sessions prefix in the name */
652 ok( !memcmp( str
->Buffer
+ (str
->Length
- sizeof(name
)) / sizeof(WCHAR
), name
, sizeof(name
) ),
653 "wrong name %s\n", wine_dbgstr_w(str
->Buffer
) );
655 len
-= sizeof(WCHAR
);
656 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, len
, &len
);
657 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryObject failed %x\n", status
);
658 ok( len
>= sizeof(UNICODE_STRING
) + sizeof(name
) + sizeof(WCHAR
), "unexpected len %u\n", len
);
662 handle
= CreateEventA( NULL
, FALSE
, FALSE
, NULL
);
664 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, sizeof(buffer
), &len
);
665 ok( status
== STATUS_SUCCESS
, "NtQueryObject failed %x\n", status
);
666 ok( len
== sizeof(UNICODE_STRING
), "unexpected len %u\n", len
);
667 str
= (UNICODE_STRING
*)buffer
;
668 ok( str
->Length
== 0, "unexpected len %u\n", len
);
669 ok( str
->Buffer
== NULL
, "unexpected ptr %p\n", str
->Buffer
);
672 GetWindowsDirectoryA( dir
, MAX_PATH
);
673 handle
= CreateFileA( dir
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
674 FILE_FLAG_BACKUP_SEMANTICS
, 0 );
676 status
= pNtQueryObject( handle
, ObjectNameInformation
, buffer
, sizeof(buffer
), &len
);
677 ok( status
== STATUS_SUCCESS
, "NtQueryObject failed %x\n", status
);
678 ok( len
> sizeof(UNICODE_STRING
), "unexpected len %u\n", len
);
679 str
= (UNICODE_STRING
*)buffer
;
680 ok( sizeof(UNICODE_STRING
) + str
->Length
+ sizeof(WCHAR
) == len
||
681 broken(sizeof(UNICODE_STRING
) + str
->Length
== len
), /* NT4 */
682 "unexpected len %u\n", len
);
683 trace( "got %s len %u\n", wine_dbgstr_w(str
->Buffer
), len
);
689 HMODULE hntdll
= GetModuleHandleA("ntdll.dll");
690 HMODULE hkernel32
= GetModuleHandleA("kernel32.dll");
694 skip("not running on NT, skipping test\n");
698 pCreateWaitableTimerA
= (void *)GetProcAddress(hkernel32
, "CreateWaitableTimerA");
700 pRtlCreateUnicodeStringFromAsciiz
= (void *)GetProcAddress(hntdll
, "RtlCreateUnicodeStringFromAsciiz");
701 pRtlFreeUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlFreeUnicodeString");
702 pNtCreateEvent
= (void *)GetProcAddress(hntdll
, "NtCreateEvent");
703 pNtCreateMutant
= (void *)GetProcAddress(hntdll
, "NtCreateMutant");
704 pNtOpenMutant
= (void *)GetProcAddress(hntdll
, "NtOpenMutant");
705 pNtOpenFile
= (void *)GetProcAddress(hntdll
, "NtOpenFile");
706 pNtClose
= (void *)GetProcAddress(hntdll
, "NtClose");
707 pRtlInitUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlInitUnicodeString");
708 pNtCreateNamedPipeFile
= (void *)GetProcAddress(hntdll
, "NtCreateNamedPipeFile");
709 pNtOpenDirectoryObject
= (void *)GetProcAddress(hntdll
, "NtOpenDirectoryObject");
710 pNtCreateDirectoryObject
= (void *)GetProcAddress(hntdll
, "NtCreateDirectoryObject");
711 pNtOpenSymbolicLinkObject
= (void *)GetProcAddress(hntdll
, "NtOpenSymbolicLinkObject");
712 pNtCreateSymbolicLinkObject
= (void *)GetProcAddress(hntdll
, "NtCreateSymbolicLinkObject");
713 pNtCreateSemaphore
= (void *)GetProcAddress(hntdll
, "NtCreateSemaphore");
714 pNtCreateTimer
= (void *)GetProcAddress(hntdll
, "NtCreateTimer");
715 pNtCreateSection
= (void *)GetProcAddress(hntdll
, "NtCreateSection");
716 pNtQueryObject
= (void *)GetProcAddress(hntdll
, "NtQueryObject");
718 test_case_sensitive();
719 test_namespace_pipe();
720 test_name_collisions();