2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Object Handle test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
12 #define CheckObject(Handle, Pointers, Handles, Attrib, Access) 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_hex(ObjectInfo.Attributes, Attrib); \
19 ok_eq_hex(ObjectInfo.GrantedAccess, Access); \
20 ok_eq_ulong(ObjectInfo.PointerCount, Pointers); \
21 ok_eq_ulong(ObjectInfo.HandleCount, Handles); \
24 #define KERNEL_HANDLE_FLAG ((ULONG_PTR)0xFFFFFFFF80000000)
25 #define IsUserHandle(h) (((ULONG_PTR)(h) & KERNEL_HANDLE_FLAG) == 0)
26 #define IsKernelHandle(h) (((ULONG_PTR)(h) & KERNEL_HANDLE_FLAG) == KERNEL_HANDLE_FLAG)
28 static HANDLE SystemProcessHandle
;
39 ACCESS_MASK DesiredAccess
;
40 ULONG RequestedAttributes
;
42 ACCESS_MASK GrantedAccess
;
43 ULONG ExpectedAttributes
;
46 { DIRECTORY_ALL_ACCESS
, 0, 0,
47 DIRECTORY_ALL_ACCESS
, 0 },
48 { DIRECTORY_ALL_ACCESS
, OBJ_KERNEL_HANDLE
, 0,
49 DIRECTORY_ALL_ACCESS
, 0 },
50 { DIRECTORY_QUERY
, 0, 0,
52 { DIRECTORY_QUERY
, OBJ_INHERIT
, 0,
53 DIRECTORY_QUERY
, OBJ_INHERIT
},
54 { DIRECTORY_QUERY
, OBJ_INHERIT
, DUPLICATE_SAME_ACCESS
,
55 DIRECTORY_ALL_ACCESS
, OBJ_INHERIT
},
57 { DIRECTORY_QUERY
, OBJ_INHERIT
, DUPLICATE_SAME_ATTRIBUTES
,
59 { DIRECTORY_QUERY
, OBJ_INHERIT
, DUPLICATE_SAME_ACCESS
| DUPLICATE_SAME_ATTRIBUTES
,
60 DIRECTORY_ALL_ACCESS
, 0 },
64 for (i
= 0; i
< RTL_NUMBER_OF(Tests
); i
++)
66 trace("Test %lu\n", i
);
67 Status
= ZwDuplicateObject(ZwCurrentProcess(),
71 Tests
[i
].DesiredAccess
,
72 Tests
[i
].RequestedAttributes
,
74 ok_eq_hex(Status
, STATUS_SUCCESS
);
75 if (!skip(NT_SUCCESS(Status
), "DuplicateHandle failed\n"))
77 ok(IsUserHandle(NewHandle
), "New handle = %p\n", NewHandle
);
78 CheckObject(NewHandle
, 3UL, 2UL, Tests
[i
].ExpectedAttributes
, Tests
[i
].GrantedAccess
);
79 CheckObject(Handle
, 3UL, 2UL, 0UL, DIRECTORY_ALL_ACCESS
);
81 Status
= ObCloseHandle(NewHandle
, UserMode
);
82 ok_eq_hex(Status
, STATUS_SUCCESS
);
83 CheckObject(Handle
, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS
);
87 /* If TargetProcess is the System process, we do get a kernel handle */
88 Status
= ZwDuplicateObject(ZwCurrentProcess(),
95 ok_eq_hex(Status
, STATUS_SUCCESS
);
96 if (!skip(NT_SUCCESS(Status
), "DuplicateHandle failed\n"))
98 ok(IsKernelHandle(NewHandle
), "New handle = %p\n", NewHandle
);
99 CheckObject(NewHandle
, 3UL, 2UL, 0, DIRECTORY_ALL_ACCESS
);
100 CheckObject(Handle
, 3UL, 2UL, 0UL, DIRECTORY_ALL_ACCESS
);
102 Status
= ObCloseHandle(NewHandle
, UserMode
);
103 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
104 CheckObject(NewHandle
, 3UL, 2UL, 0, DIRECTORY_ALL_ACCESS
);
105 CheckObject(Handle
, 3UL, 2UL, 0UL, DIRECTORY_ALL_ACCESS
);
107 if (IsKernelHandle(NewHandle
))
109 Status
= ObCloseHandle(NewHandle
, KernelMode
);
110 ok_eq_hex(Status
, STATUS_SUCCESS
);
111 CheckObject(Handle
, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS
);
119 OBJECT_ATTRIBUTES ObjectAttributes
;
120 HANDLE KernelDirectoryHandle
;
121 HANDLE UserDirectoryHandle
;
123 Status
= ObOpenObjectByPointer(PsInitialSystemProcess
,
129 &SystemProcessHandle
);
130 ok_eq_hex(Status
, STATUS_SUCCESS
);
131 if (skip(NT_SUCCESS(Status
), "No handle for system process\n"))
133 SystemProcessHandle
= NULL
;
136 InitializeObjectAttributes(&ObjectAttributes
,
141 Status
= ZwCreateDirectoryObject(&UserDirectoryHandle
,
142 DIRECTORY_ALL_ACCESS
,
144 ok_eq_hex(Status
, STATUS_SUCCESS
);
145 if (!skip(NT_SUCCESS(Status
), "No directory handle\n"))
147 ok(IsUserHandle(UserDirectoryHandle
), "User handle = %p\n", UserDirectoryHandle
);
148 CheckObject(UserDirectoryHandle
, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS
);
150 TestDuplicate(UserDirectoryHandle
);
152 Status
= ObCloseHandle(UserDirectoryHandle
, UserMode
);
153 ok_eq_hex(Status
, STATUS_SUCCESS
);
156 InitializeObjectAttributes(&ObjectAttributes
,
161 Status
= ZwCreateDirectoryObject(&KernelDirectoryHandle
,
162 DIRECTORY_ALL_ACCESS
,
164 ok_eq_hex(Status
, STATUS_SUCCESS
);
165 if (!skip(NT_SUCCESS(Status
), "No directory handle\n"))
167 ok(IsKernelHandle(KernelDirectoryHandle
), "Kernel handle = %p\n", KernelDirectoryHandle
);
168 CheckObject(KernelDirectoryHandle
, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS
);
170 TestDuplicate(KernelDirectoryHandle
);
172 Status
= ObCloseHandle(KernelDirectoryHandle
, UserMode
);
173 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
174 CheckObject(KernelDirectoryHandle
, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS
);
176 Status
= ObCloseHandle(KernelDirectoryHandle
, KernelMode
);
177 ok_eq_hex(Status
, STATUS_SUCCESS
);
180 /* Tests for closing handles */
182 /* NtClose must accept everything */
183 DPRINT("Closing null handle (NtClose)\n");
184 Status
= NtClose(NULL
);
185 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
186 DPRINT("Closing null kernel handle (NtClose)\n");
187 Status
= NtClose((HANDLE
)0x80000000);
188 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
189 DPRINT("Closing -1 handle (NtClose)\n");
190 Status
= NtClose((HANDLE
)0x7FFFFFFF);
191 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
192 DPRINT("Closing -1 kernel handle (NtClose)\n");
193 Status
= NtClose((HANDLE
)0xFFFFFFFF);
194 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
195 DPRINT("Closing 123 handle (NtClose)\n");
196 Status
= NtClose((HANDLE
)123);
197 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
198 DPRINT("Closing 123 kernel handle (NtClose)\n");
199 Status
= NtClose((HANDLE
)(123 | 0x80000000));
200 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
202 /* ObCloseHandle with UserMode accepts everything */
203 DPRINT("Closing null handle (ObCloseHandle, UserMode)\n");
204 Status
= ObCloseHandle(NULL
, UserMode
);
205 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
206 DPRINT("Closing null kernel handle (ObCloseHandle, UserMode)\n");
207 Status
= ObCloseHandle((HANDLE
)0x80000000, UserMode
);
208 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
209 DPRINT("Closing -1 handle (ObCloseHandle, UserMode)\n");
210 Status
= ObCloseHandle((HANDLE
)0x7FFFFFFF, UserMode
);
211 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
212 DPRINT("Closing -1 kernel handle (ObCloseHandle, UserMode)\n");
213 Status
= ObCloseHandle((HANDLE
)0xFFFFFFFF, UserMode
);
214 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
215 DPRINT("Closing 123 handle (ObCloseHandle, UserMode)\n");
216 Status
= ObCloseHandle((HANDLE
)123, UserMode
);
217 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
218 DPRINT("Closing 123 kernel handle (ObCloseHandle, UserMode)\n");
219 Status
= ObCloseHandle((HANDLE
)(123 | 0x80000000), UserMode
);
220 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
222 /* ZwClose only accepts 0 and -1 */
223 DPRINT("Closing null handle (ZwClose)\n");
224 Status
= ZwClose(NULL
);
225 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
226 DPRINT("Closing null kernel handle (ZwClose)\n");
227 Status
= ZwClose((HANDLE
)0x80000000);
228 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
229 /* INVALID_KERNEL_HANDLE, 0x7FFFFFFF
230 Status = ZwClose((HANDLE)0x7FFFFFFF);*/
231 DPRINT("Closing -1 kernel handle (ZwClose)\n");
232 Status
= ZwClose((HANDLE
)0xFFFFFFFF);
233 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
234 /* INVALID_KERNEL_HANDLE, 0x7B, 1, 0, 0
235 Status = ZwClose((HANDLE)123);
236 Status = ZwClose((HANDLE)(123 | 0x80000000));*/
238 /* ObCloseHandle with KernelMode accepts only 0 and -1 */
239 DPRINT("Closing null handle (ObCloseHandle, KernelMode)\n");
240 Status
= ObCloseHandle(NULL
, KernelMode
);
241 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
242 DPRINT("Closing null kernel handle (ObCloseHandle, KernelMode)\n");
243 Status
= ObCloseHandle((HANDLE
)0x80000000, KernelMode
);
244 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
245 /* INVALID_KERNEL_HANDLE, 0x7FFFFFFF, 1, 0, 0
246 Status = ObCloseHandle((HANDLE)0x7FFFFFFF, KernelMode);*/
247 DPRINT("Closing -1 kernel handle (ObCloseHandle, KernelMode)\n");
248 Status
= ObCloseHandle((HANDLE
)0xFFFFFFFF, KernelMode
);
249 ok_eq_hex(Status
, STATUS_INVALID_HANDLE
);
250 /* INVALID_KERNEL_HANDLE, 0x7B, 1, 0, 0
251 Status = ObCloseHandle((HANDLE)123, KernelMode);
252 Status = ObCloseHandle((HANDLE)(123 | 0x80000000), KernelMode);*/
253 KmtEndSeh(STATUS_SUCCESS
);
255 if (SystemProcessHandle
)
257 ObCloseHandle(SystemProcessHandle
, KernelMode
);