2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Object Referencing test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
12 #define CheckObject(Handle, Pointers, Handles) do \
14 PUBLIC_OBJECT_BASIC_INFORMATION ObjectInfo; \
15 Status = ZwQueryObject(Handle, ObjectBasicInformation, \
16 &ObjectInfo, sizeof ObjectInfo, NULL); \
17 ok_eq_hex(Status, STATUS_SUCCESS); \
18 ok_eq_ulong(ObjectInfo.PointerCount, Pointers); \
19 ok_eq_ulong(ObjectInfo.HandleCount, Handles); \
22 static POBJECT_TYPE ObDirectoryObjectType
;
28 IN PUNICODE_STRING Name OPTIONAL
,
29 IN PUNICODE_STRING NameUpper OPTIONAL
,
30 IN BOOLEAN CaseSensitive
,
31 IN ULONG AdditionalReferences
,
41 CheckObject(Handle
, 2LU + AdditionalReferences
, 1LU);
43 Status
= ObReferenceObjectByHandle(Handle
, DIRECTORY_ALL_ACCESS
, NULL
, KernelMode
, &Object
, NULL
);
44 ok_eq_hex(Status
, STATUS_SUCCESS
);
45 ok(Object
!= NULL
, "ObReferenceObjectByHandle returned NULL object\n");
46 CheckObject(Handle
, 3LU + AdditionalReferences
, 1LU);
48 Status
= ObReferenceObjectByHandle(Handle
, DIRECTORY_ALL_ACCESS
, NULL
, KernelMode
, &Object2
, NULL
);
49 ok_eq_hex(Status
, STATUS_SUCCESS
);
50 ok(Object
!= NULL
, "ObReferenceObjectByHandle returned NULL object\n");
51 ok_eq_pointer(Object
, Object2
);
52 CheckObject(Handle
, 4LU + AdditionalReferences
, 1LU);
54 if (!skip(Object
!= NULL
, "No object to reference!\n"))
56 Ret
= ObReferenceObject(Object
);
57 ok_eq_longptr(Ret
, (LONG_PTR
)4 + AdditionalReferences
);
58 CheckObject(Handle
, 5LU + AdditionalReferences
, 1LU);
60 Ret
= ObReferenceObject(Object
);
61 ok_eq_longptr(Ret
, (LONG_PTR
)5 + AdditionalReferences
);
62 CheckObject(Handle
, 6LU + AdditionalReferences
, 1LU);
64 Status
= ObReferenceObjectByPointer(Object
, DIRECTORY_ALL_ACCESS
, NULL
, KernelMode
);
65 ok_eq_hex(Status
, STATUS_SUCCESS
);
66 CheckObject(Handle
, 7LU + AdditionalReferences
, 1LU);
68 Status
= ObReferenceObjectByPointer(Object
, DIRECTORY_ALL_ACCESS
, NULL
, KernelMode
);
69 ok_eq_hex(Status
, STATUS_SUCCESS
);
70 CheckObject(Handle
, 8LU + AdditionalReferences
, 1LU);
72 Ret
= ObDereferenceObject(Object
);
73 ok_eq_longptr(Ret
, (LONG_PTR
)6 + AdditionalReferences
);
74 CheckObject(Handle
, 7LU + AdditionalReferences
, 1LU);
76 Ret
= ObDereferenceObject(Object
);
77 ok_eq_longptr(Ret
, (LONG_PTR
)5 + AdditionalReferences
);
78 CheckObject(Handle
, 6LU + AdditionalReferences
, 1LU);
80 Ret
= ObDereferenceObject(Object
);
81 ok_eq_longptr(Ret
, (LONG_PTR
)4 + AdditionalReferences
);
82 CheckObject(Handle
, 5LU + AdditionalReferences
, 1LU);
84 Ret
= ObDereferenceObject(Object
);
85 ok_eq_longptr(Ret
, (LONG_PTR
)3 + AdditionalReferences
);
86 CheckObject(Handle
, 4LU + AdditionalReferences
, 1LU);
89 if (Name
&& !skip(ObDirectoryObjectType
!= NULL
, "No directory object type\n"))
91 Status
= ObReferenceObjectByName(Name
, 0, NULL
, DIRECTORY_ALL_ACCESS
, ObDirectoryObjectType
, KernelMode
, NULL
, &Object3
);
92 ok_eq_hex(Status
, STATUS_SUCCESS
);
93 CheckObject(Handle
, 5LU + AdditionalReferences
, 1LU);
96 if (NameUpper
&& !skip(ObDirectoryObjectType
!= NULL
, "No directory object type\n"))
98 Status
= ObReferenceObjectByName(NameUpper
, 0, NULL
, DIRECTORY_ALL_ACCESS
, ObDirectoryObjectType
, KernelMode
, NULL
, &Object4
);
99 ok_eq_hex(Status
, CaseSensitive
? STATUS_OBJECT_NAME_NOT_FOUND
: STATUS_SUCCESS
);
100 CheckObject(Handle
, 5LU + AdditionalReferences
+ !CaseSensitive
, 1LU);
103 if (NameUpper
&& !skip(Object4
!= NULL
, "No object to dereference\n"))
105 Ret
= ObDereferenceObject(Object4
);
106 ok_eq_longptr(Ret
, (LONG_PTR
)4 + AdditionalReferences
);
107 CheckObject(Handle
, 5LU + AdditionalReferences
, 1LU);
109 if (Name
&& !skip(Object3
!= NULL
, "No object to dereference\n"))
111 Ret
= ObDereferenceObject(Object3
);
112 ok_eq_longptr(Ret
, (LONG_PTR
)3 + AdditionalReferences
);
113 CheckObject(Handle
, 4LU + AdditionalReferences
, 1LU);
115 if (!skip(Object2
!= NULL
, "No object to dereference\n"))
117 Ret
= ObDereferenceObject(Object2
);
118 ok_eq_longptr(Ret
, (LONG_PTR
)2 + AdditionalReferences
);
119 CheckObject(Handle
, 3LU + AdditionalReferences
, 1LU);
121 if (!skip(Object
!= NULL
, "No object to dereference\n"))
123 Ret
= ObDereferenceObject(Object
);
124 ok_eq_longptr(Ret
, (LONG_PTR
)1 + AdditionalReferences
);
125 CheckObject(Handle
, 2LU + AdditionalReferences
, 1LU);
128 CheckObject(Handle
, 2LU + AdditionalReferences
, 1LU);
132 Status
= ZwMakeTemporaryObject(Handle
);
133 ok_eq_hex(Status
, STATUS_SUCCESS
);
134 CheckObject(Handle
, 2LU + AdditionalReferences
, 1LU);
136 Status
= ZwMakeTemporaryObject(Handle
);
137 ok_eq_hex(Status
, STATUS_SUCCESS
);
138 CheckObject(Handle
, 2LU + AdditionalReferences
, 1LU);
142 START_TEST(ObReference
)
145 HANDLE DirectoryHandle
= NULL
;
146 OBJECT_ATTRIBUTES ObjectAttributes
;
147 UNICODE_STRING Name
, *pName
;
148 UNICODE_STRING NameUpper
, *pNameUpper
;
154 ULONG AdditionalReferences
;
158 { NULL
, OBJ_CASE_INSENSITIVE
, 0 },
159 { NULL
, OBJ_KERNEL_HANDLE
, 0 },
160 { NULL
, OBJ_PERMANENT
, 0 },
161 { NULL
, OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
, 0 },
162 { NULL
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, 0 },
163 { NULL
, OBJ_KERNEL_HANDLE
| OBJ_PERMANENT
, 0 },
164 { NULL
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
| OBJ_PERMANENT
, 0 },
165 { L
"\\YayDirectory0", 0, 1 },
166 { L
"\\YayDirectory1", OBJ_CASE_INSENSITIVE
, 1 },
167 { L
"\\YayDirectory2", OBJ_KERNEL_HANDLE
, 1 },
168 { L
"\\YayDirectory3", OBJ_PERMANENT
, 1 },
169 { L
"\\YayDirectory4", OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
, 1 },
170 { L
"\\YayDirectory5", OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, 1 },
171 { L
"\\YayDirectory6", OBJ_KERNEL_HANDLE
| OBJ_PERMANENT
, 1 },
172 { L
"\\YayDirectory7", OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
| OBJ_PERMANENT
, 1 },
174 HANDLE ObjectTypeHandle
;
176 /* ObReferenceObjectByName needs the object type... so get it... */
177 RtlInitUnicodeString(&Name
, L
"\\ObjectTypes\\Directory");
178 InitializeObjectAttributes(&ObjectAttributes
, &Name
, OBJ_KERNEL_HANDLE
, NULL
, NULL
);
179 Status
= ObOpenObjectByName(&ObjectAttributes
, NULL
, KernelMode
, NULL
, 0, NULL
, &ObjectTypeHandle
);
180 ok_eq_hex(Status
, STATUS_SUCCESS
);
181 ok(ObjectTypeHandle
!= NULL
, "ObjectTypeHandle = NULL\n");
182 if (!skip(Status
== STATUS_SUCCESS
&& ObjectTypeHandle
, "No handle\n"))
184 Status
= ObReferenceObjectByHandle(ObjectTypeHandle
, 0, NULL
, KernelMode
, (PVOID
)&ObDirectoryObjectType
, NULL
);
185 ok_eq_hex(Status
, STATUS_SUCCESS
);
186 ok(ObDirectoryObjectType
!= NULL
, "ObDirectoryObjectType = NULL\n");
187 Status
= ZwClose(ObjectTypeHandle
);
188 ok_eq_hex(Status
, STATUS_SUCCESS
);
191 for (i
= 0; i
< sizeof Tests
/ sizeof Tests
[0]; ++i
)
193 DPRINT("Run %d\n", i
);
196 RtlInitUnicodeString(&Name
, Tests
[i
].Name
);
198 Status
= RtlUpcaseUnicodeString(&NameUpper
, &Name
, TRUE
);
199 ok_eq_hex(Status
, STATUS_SUCCESS
);
200 if (skip(Status
== STATUS_SUCCESS
, "No upper case name\n"))
203 pNameUpper
= &NameUpper
;
210 InitializeObjectAttributes(&ObjectAttributes
, pName
, Tests
[i
].Flags
, NULL
, NULL
);
211 Status
= ZwCreateDirectoryObject(&DirectoryHandle
, DIRECTORY_ALL_ACCESS
, &ObjectAttributes
);
212 ok_eq_hex(Status
, STATUS_SUCCESS
);
213 ok(DirectoryHandle
!= NULL
, "DirectoryHandle = NULL\n");
215 if (!skip(Status
== STATUS_SUCCESS
&& DirectoryHandle
, "Cannot proceed without an object"))
217 TestReference(DirectoryHandle
, pName
, pNameUpper
, FALSE
, Tests
[i
].AdditionalReferences
, (Tests
[i
].Flags
& OBJ_PERMANENT
) != 0);
218 /* try again for good measure */
219 TestReference(DirectoryHandle
, pName
, pNameUpper
, FALSE
, Tests
[i
].AdditionalReferences
, FALSE
);
221 Status
= ZwClose(DirectoryHandle
);
222 ok_eq_hex(Status
, STATUS_SUCCESS
);
223 DirectoryHandle
= NULL
;
227 RtlFreeUnicodeString(pNameUpper
);
232 Status
= ZwClose(DirectoryHandle
);
233 ok_eq_hex(Status
, STATUS_SUCCESS
);
236 /* parameter tests */
237 /* bugcheck at APC_LEVEL
238 Status = ObReferenceObject(NULL);
239 Status = ObReferenceObjectByPointer(NULL, 0, NULL, UserMode);
240 Status = ObReferenceObjectByPointer(NULL, 0, NULL, KernelMode);*/
243 /* TODO: this belongs in an ObHandle test if we ever have one */
244 /* NtClose must accept everything */
245 DPRINT("Closing null handle (NtClose)\n");
246 Status
= NtClose(NULL
);
247 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
248 DPRINT("Closing null kernel handle (NtClose)\n");
249 Status
= NtClose((HANDLE
)0x80000000);
250 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
251 DPRINT("Closing -1 handle (NtClose)\n");
252 Status
= NtClose((HANDLE
)0x7FFFFFFF);
253 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
254 DPRINT("Closing -1 kernel handle (NtClose)\n");
255 Status
= NtClose((HANDLE
)0xFFFFFFFF);
256 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
257 DPRINT("Closing 123 handle (NtClose)\n");
258 Status
= NtClose((HANDLE
)123);
259 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
260 DPRINT("Closing 123 kernel handle (NtClose)\n");
261 Status
= NtClose((HANDLE
)(123 | 0x80000000));
262 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
264 /* ObCloseHandle with UserMode accepts everything */
265 DPRINT("Closing null handle (ObCloseHandle, UserMode)\n");
266 Status
= ObCloseHandle(NULL
, UserMode
);
267 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
268 DPRINT("Closing null kernel handle (ObCloseHandle, UserMode)\n");
269 Status
= ObCloseHandle((HANDLE
)0x80000000, UserMode
);
270 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
271 DPRINT("Closing -1 handle (ObCloseHandle, UserMode)\n");
272 Status
= ObCloseHandle((HANDLE
)0x7FFFFFFF, UserMode
);
273 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
274 DPRINT("Closing -1 kernel handle (ObCloseHandle, UserMode)\n");
275 Status
= ObCloseHandle((HANDLE
)0xFFFFFFFF, UserMode
);
276 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
277 DPRINT("Closing 123 handle (ObCloseHandle, UserMode)\n");
278 Status
= ObCloseHandle((HANDLE
)123, UserMode
);
279 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
280 DPRINT("Closing 123 kernel handle (ObCloseHandle, UserMode)\n");
281 Status
= ObCloseHandle((HANDLE
)(123 | 0x80000000), UserMode
);
282 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
284 /* ZwClose only accepts 0 and -1 */
285 DPRINT("Closing null handle (ZwClose)\n");
286 Status
= ZwClose(NULL
);
287 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
288 DPRINT("Closing null kernel handle (ZwClose)\n");
289 Status
= ZwClose((HANDLE
)0x80000000);
290 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
291 /* INVALID_KERNEL_HANDLE, 0x7FFFFFFF
292 Status = ZwClose((HANDLE)0x7FFFFFFF);*/
293 DPRINT("Closing -1 kernel handle (ZwClose)\n");
294 Status
= ZwClose((HANDLE
)0xFFFFFFFF);
295 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
296 /* INVALID_KERNEL_HANDLE, 0x7B, 1, 0, 0
297 Status = ZwClose((HANDLE)123);
298 Status = ZwClose((HANDLE)(123 | 0x80000000));*/
300 /* ObCloseHandle with KernelMode accepts only 0 and -1 */
301 DPRINT("Closing null handle (ObCloseHandle, KernelMode)\n");
302 Status
= ObCloseHandle(NULL
, KernelMode
);
303 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
304 DPRINT("Closing null kernel handle (ObCloseHandle, KernelMode)\n");
305 Status
= ObCloseHandle((HANDLE
)0x80000000, KernelMode
);
306 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
307 /* INVALID_KERNEL_HANDLE, 0x7FFFFFFF, 1, 0, 0
308 Status = ObCloseHandle((HANDLE)0x7FFFFFFF, KernelMode);*/
309 DPRINT("Closing -1 kernel handle (ObCloseHandle, KernelMode)\n");
310 Status
= ObCloseHandle((HANDLE
)0xFFFFFFFF, KernelMode
);
311 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
312 /* INVALID_KERNEL_HANDLE, 0x7B, 1, 0, 0
313 Status = ObCloseHandle((HANDLE)123, KernelMode);
314 Status = ObCloseHandle((HANDLE)(123 | 0x80000000), KernelMode);*/
315 KmtEndSeh(STATUS_SUCCESS
);
317 if (ObDirectoryObjectType
)
319 ObDereferenceObject(ObDirectoryObjectType
);
320 ObDirectoryObjectType
= NULL
;