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 <thfabba@gmx.de>
10 #define CheckObject(Handle, Pointers, Handles) do \
12 PUBLIC_OBJECT_BASIC_INFORMATION ObjectInfo; \
13 Status = ZwQueryObject(Handle, ObjectBasicInformation, \
14 &ObjectInfo, sizeof ObjectInfo, NULL); \
15 ok_eq_hex(Status, STATUS_SUCCESS); \
16 ok_eq_ulong(ObjectInfo.PointerCount, Pointers); \
17 ok_eq_ulong(ObjectInfo.HandleCount, Handles); \
20 static POBJECT_TYPE ObDirectoryObjectType
;
26 IN PUNICODE_STRING Name OPTIONAL
,
27 IN PUNICODE_STRING NameUpper OPTIONAL
,
28 IN BOOLEAN CaseSensitive
,
29 IN ULONG AdditionalReferences
,
39 CheckObject(Handle
, 2LU + AdditionalReferences
, 1LU);
41 Status
= ObReferenceObjectByHandle(Handle
, DIRECTORY_ALL_ACCESS
, NULL
, KernelMode
, &Object
, NULL
);
42 ok_eq_hex(Status
, STATUS_SUCCESS
);
43 ok(Object
!= NULL
, "ObReferenceObjectByHandle returned NULL object\n");
44 CheckObject(Handle
, 3LU + AdditionalReferences
, 1LU);
46 Status
= ObReferenceObjectByHandle(Handle
, DIRECTORY_ALL_ACCESS
, NULL
, KernelMode
, &Object2
, NULL
);
47 ok_eq_hex(Status
, STATUS_SUCCESS
);
48 ok(Object
!= NULL
, "ObReferenceObjectByHandle returned NULL object\n");
49 ok_eq_pointer(Object
, Object2
);
50 CheckObject(Handle
, 4LU + AdditionalReferences
, 1LU);
52 if (!skip(Object
!= NULL
, "No object to reference!\n"))
54 Ret
= ObReferenceObject(Object
);
55 ok_eq_longptr(Ret
, (LONG_PTR
)4 + AdditionalReferences
);
56 CheckObject(Handle
, 5LU + AdditionalReferences
, 1LU);
58 Ret
= ObReferenceObject(Object
);
59 ok_eq_longptr(Ret
, (LONG_PTR
)5 + AdditionalReferences
);
60 CheckObject(Handle
, 6LU + AdditionalReferences
, 1LU);
62 Status
= ObReferenceObjectByPointer(Object
, DIRECTORY_ALL_ACCESS
, NULL
, KernelMode
);
63 ok_eq_hex(Status
, STATUS_SUCCESS
);
64 CheckObject(Handle
, 7LU + AdditionalReferences
, 1LU);
66 Status
= ObReferenceObjectByPointer(Object
, DIRECTORY_ALL_ACCESS
, NULL
, KernelMode
);
67 ok_eq_hex(Status
, STATUS_SUCCESS
);
68 CheckObject(Handle
, 8LU + AdditionalReferences
, 1LU);
70 Ret
= ObDereferenceObject(Object
);
71 ok_eq_longptr(Ret
, (LONG_PTR
)6 + AdditionalReferences
);
72 CheckObject(Handle
, 7LU + AdditionalReferences
, 1LU);
74 Ret
= ObDereferenceObject(Object
);
75 ok_eq_longptr(Ret
, (LONG_PTR
)5 + AdditionalReferences
);
76 CheckObject(Handle
, 6LU + AdditionalReferences
, 1LU);
78 Ret
= ObDereferenceObject(Object
);
79 ok_eq_longptr(Ret
, (LONG_PTR
)4 + AdditionalReferences
);
80 CheckObject(Handle
, 5LU + AdditionalReferences
, 1LU);
82 Ret
= ObDereferenceObject(Object
);
83 ok_eq_longptr(Ret
, (LONG_PTR
)3 + AdditionalReferences
);
84 CheckObject(Handle
, 4LU + AdditionalReferences
, 1LU);
87 if (Name
&& !skip(ObDirectoryObjectType
!= NULL
, "No directory object type\n"))
89 Status
= ObReferenceObjectByName(Name
, 0, NULL
, DIRECTORY_ALL_ACCESS
, ObDirectoryObjectType
, KernelMode
, NULL
, &Object3
);
90 ok_eq_hex(Status
, STATUS_SUCCESS
);
91 CheckObject(Handle
, 5LU + AdditionalReferences
, 1LU);
94 if (NameUpper
&& !skip(ObDirectoryObjectType
!= NULL
, "No directory object type\n"))
96 Status
= ObReferenceObjectByName(NameUpper
, 0, NULL
, DIRECTORY_ALL_ACCESS
, ObDirectoryObjectType
, KernelMode
, NULL
, &Object4
);
97 ok_eq_hex(Status
, CaseSensitive
? STATUS_OBJECT_NAME_NOT_FOUND
: STATUS_SUCCESS
);
98 CheckObject(Handle
, 5LU + AdditionalReferences
+ !CaseSensitive
, 1LU);
101 if (NameUpper
&& !skip(Object4
!= NULL
, "No object to dereference\n"))
103 Ret
= ObDereferenceObject(Object4
);
104 ok_eq_longptr(Ret
, (LONG_PTR
)4 + AdditionalReferences
);
105 CheckObject(Handle
, 5LU + AdditionalReferences
, 1LU);
107 if (Name
&& !skip(Object3
!= NULL
, "No object to dereference\n"))
109 Ret
= ObDereferenceObject(Object3
);
110 ok_eq_longptr(Ret
, (LONG_PTR
)3 + AdditionalReferences
);
111 CheckObject(Handle
, 4LU + AdditionalReferences
, 1LU);
113 if (!skip(Object2
!= NULL
, "No object to dereference\n"))
115 Ret
= ObDereferenceObject(Object2
);
116 ok_eq_longptr(Ret
, (LONG_PTR
)2 + AdditionalReferences
);
117 CheckObject(Handle
, 3LU + AdditionalReferences
, 1LU);
119 if (!skip(Object
!= NULL
, "No object to dereference\n"))
121 Ret
= ObDereferenceObject(Object
);
122 ok_eq_longptr(Ret
, (LONG_PTR
)1 + AdditionalReferences
);
123 CheckObject(Handle
, 2LU + AdditionalReferences
, 1LU);
126 CheckObject(Handle
, 2LU + AdditionalReferences
, 1LU);
130 Status
= ZwMakeTemporaryObject(Handle
);
131 ok_eq_hex(Status
, STATUS_SUCCESS
);
132 CheckObject(Handle
, 2LU + AdditionalReferences
, 1LU);
134 Status
= ZwMakeTemporaryObject(Handle
);
135 ok_eq_hex(Status
, STATUS_SUCCESS
);
136 CheckObject(Handle
, 2LU + AdditionalReferences
, 1LU);
140 START_TEST(ObReference
)
143 NTSTATUS ExceptionStatus
;
144 HANDLE DirectoryHandle
= NULL
;
145 OBJECT_ATTRIBUTES ObjectAttributes
;
146 UNICODE_STRING Name
, *pName
;
147 UNICODE_STRING NameUpper
, *pNameUpper
;
153 ULONG AdditionalReferences
;
157 { NULL
, OBJ_CASE_INSENSITIVE
, 0 },
158 { NULL
, OBJ_KERNEL_HANDLE
, 0 },
159 { NULL
, OBJ_PERMANENT
, 0 },
160 { NULL
, OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
, 0 },
161 { NULL
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, 0 },
162 { NULL
, OBJ_KERNEL_HANDLE
| OBJ_PERMANENT
, 0 },
163 { NULL
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
| OBJ_PERMANENT
, 0 },
164 { L
"\\YayDirectory0", 0, 1 },
165 { L
"\\YayDirectory1", OBJ_CASE_INSENSITIVE
, 1 },
166 { L
"\\YayDirectory2", OBJ_KERNEL_HANDLE
, 1 },
167 { L
"\\YayDirectory3", OBJ_PERMANENT
, 1 },
168 { L
"\\YayDirectory4", OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
, 1 },
169 { L
"\\YayDirectory5", OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, 1 },
170 { L
"\\YayDirectory6", OBJ_KERNEL_HANDLE
| OBJ_PERMANENT
, 1 },
171 { L
"\\YayDirectory7", OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
| OBJ_PERMANENT
, 1 },
173 HANDLE ObjectTypeHandle
;
175 /* ObReferenceObjectByName needs the object type... so get it... */
176 RtlInitUnicodeString(&Name
, L
"\\ObjectTypes\\Directory");
177 InitializeObjectAttributes(&ObjectAttributes
, &Name
, OBJ_KERNEL_HANDLE
, NULL
, NULL
);
178 Status
= ObOpenObjectByName(&ObjectAttributes
, NULL
, KernelMode
, NULL
, 0, NULL
, &ObjectTypeHandle
);
179 ok_eq_hex(Status
, STATUS_SUCCESS
);
180 ok(ObjectTypeHandle
!= NULL
, "ObjectTypeHandle = NULL\n");
181 if (!skip(Status
== STATUS_SUCCESS
&& ObjectTypeHandle
, "No handle\n"))
183 Status
= ObReferenceObjectByHandle(ObjectTypeHandle
, 0, NULL
, KernelMode
, (PVOID
)&ObDirectoryObjectType
, NULL
);
184 ok_eq_hex(Status
, STATUS_SUCCESS
);
185 ok(ObDirectoryObjectType
!= NULL
, "ObDirectoryObjectType = NULL\n");
186 Status
= ZwClose(ObjectTypeHandle
);
187 ok_eq_hex(Status
, STATUS_SUCCESS
);
190 for (i
= 0; i
< sizeof Tests
/ sizeof Tests
[0]; ++i
)
194 RtlInitUnicodeString(&Name
, Tests
[i
].Name
);
196 Status
= RtlUpcaseUnicodeString(&NameUpper
, &Name
, TRUE
);
197 ok_eq_hex(Status
, STATUS_SUCCESS
);
198 if (skip(Status
== STATUS_SUCCESS
, "No upper case name\n"))
201 pNameUpper
= &NameUpper
;
208 InitializeObjectAttributes(&ObjectAttributes
, pName
, Tests
[i
].Flags
, NULL
, NULL
);
209 Status
= ZwCreateDirectoryObject(&DirectoryHandle
, DIRECTORY_ALL_ACCESS
, &ObjectAttributes
);
210 ok_eq_hex(Status
, STATUS_SUCCESS
);
211 ok(DirectoryHandle
!= NULL
, "DirectoryHandle = NULL\n");
213 if (!skip(Status
== STATUS_SUCCESS
&& DirectoryHandle
, "Cannot proceed without an object"))
215 TestReference(DirectoryHandle
, pName
, pNameUpper
, FALSE
, Tests
[i
].AdditionalReferences
, (Tests
[i
].Flags
& OBJ_PERMANENT
) != 0);
216 /* try again for good measure */
217 TestReference(DirectoryHandle
, pName
, pNameUpper
, FALSE
, Tests
[i
].AdditionalReferences
, FALSE
);
219 Status
= ZwClose(DirectoryHandle
);
220 ok_eq_hex(Status
, STATUS_SUCCESS
);
221 DirectoryHandle
= NULL
;
225 RtlFreeUnicodeString(pNameUpper
);
230 Status
= ZwClose(DirectoryHandle
);
231 ok_eq_hex(Status
, STATUS_SUCCESS
);
234 /* parameter tests */
235 /* bugcheck at APC_LEVEL
236 Status = ObReferenceObject(NULL);
237 Status = ObReferenceObjectByPointer(NULL, 0, NULL, UserMode);
238 Status = ObReferenceObjectByPointer(NULL, 0, NULL, KernelMode);*/
240 ExceptionStatus
= STATUS_SUCCESS
;
242 Status
= ZwClose(NULL
);
243 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
244 Status
= ZwClose((HANDLE
)-1);
245 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
246 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
) {
247 ExceptionStatus
= _SEH2_GetExceptionCode();
249 ok_eq_hex(ExceptionStatus
, STATUS_SUCCESS
);
251 if (ObDirectoryObjectType
)
253 ObDereferenceObject(ObDirectoryObjectType
);
254 ObDirectoryObjectType
= NULL
;