ReactOS 0.4.16-dev-1506-g117cd33
ObHandle.c
Go to the documentation of this file.
1/*
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>
6 */
7
8#include <kmt_test.h>
9#define NDEBUG
10#include <debug.h>
11
12#define CheckObject(Handle, Pointers, Handles, Attrib, Access) do \
13{ \
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); \
22} while (0)
23
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)
27
29
30static
31VOID
34{
36 HANDLE NewHandle;
37 ULONG i, PtrCnt1, PtrCnt2;
38 struct
39 {
41 ULONG RequestedAttributes;
44 ULONG ExpectedAttributes;
45 } Tests[] =
46 {
51 { DIRECTORY_QUERY, 0, 0,
52 DIRECTORY_QUERY, 0 },
57 /* 5 */
59 DIRECTORY_QUERY, 0 },
62 };
63
65 {
66#ifdef _M_IX86
67 PtrCnt1 = 65UL;
68 PtrCnt2 = 31UL;
69#else
70 PtrCnt1 = 65537UL;
71 PtrCnt2 = 32767UL;
72#endif
73 }
74
75 else
76 {
77 PtrCnt1 = 3UL;
78 PtrCnt2 = 2UL;
79 }
80
81 for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
82 {
84 Tests[i].RequestedAttributes == OBJ_KERNEL_HANDLE)
85 {
86 skip(FALSE, "Invalid on NT 6.1+\n");
87 continue;
88 }
89
90 trace("Test %lu\n", i);
91 Status = ZwDuplicateObject(ZwCurrentProcess(),
92 Handle,
94 &NewHandle,
96 Tests[i].RequestedAttributes,
97 Tests[i].Options);
99 if (!skip(NT_SUCCESS(Status), "DuplicateHandle failed\n"))
100 {
101 ok(IsUserHandle(NewHandle), "New handle = %p\n", NewHandle);
102 CheckObject(NewHandle, PtrCnt1, 2UL, Tests[i].ExpectedAttributes, Tests[i].GrantedAccess);
104 PtrCnt1--;
105 CheckObject(Handle, PtrCnt1, 2UL, 0UL, DIRECTORY_ALL_ACCESS);
107 PtrCnt1--;
108
109 Status = ObCloseHandle(NewHandle, UserMode);
111 CheckObject(Handle, PtrCnt2, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
113 PtrCnt2 -= 2;
114 }
115 }
116
117 /* If TargetProcess is the System process, we do get a kernel handle */
118 Status = ZwDuplicateObject(ZwCurrentProcess(),
119 Handle,
121 &NewHandle,
124 0);
126 if (!skip(NT_SUCCESS(Status), "DuplicateHandle failed\n"))
127 {
128 ok(IsKernelHandle(NewHandle), "New handle = %p\n", NewHandle);
129 CheckObject(NewHandle, PtrCnt1, 2UL, 0, DIRECTORY_ALL_ACCESS);
131 PtrCnt1--;
132 CheckObject(Handle, PtrCnt1, 2UL, 0UL, DIRECTORY_ALL_ACCESS);
134 PtrCnt1--;
135 Status = ObCloseHandle(NewHandle, UserMode);
137 CheckObject(NewHandle, PtrCnt1, 2UL, 0, DIRECTORY_ALL_ACCESS);
139 PtrCnt1--;
140 CheckObject(Handle, PtrCnt1, 2UL, 0UL, DIRECTORY_ALL_ACCESS);
141
142 if (IsKernelHandle(NewHandle))
143 {
144 Status = ObCloseHandle(NewHandle, KernelMode);
147 PtrCnt2--;
148 CheckObject(Handle, PtrCnt2, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
149 }
150 }
151}
152
153START_TEST(ObHandle)
154{
157 HANDLE KernelDirectoryHandle;
158 HANDLE UserDirectoryHandle;
159
162 NULL,
168 if (skip(NT_SUCCESS(Status), "No handle for system process\n"))
169 {
171 }
172
174 NULL,
175 0,
176 NULL,
177 NULL);
178 Status = ZwCreateDirectoryObject(&UserDirectoryHandle,
182 if (!skip(NT_SUCCESS(Status), "No directory handle\n"))
183 {
184 ok(IsUserHandle(UserDirectoryHandle), "User handle = %p\n", UserDirectoryHandle);
186#ifdef _M_IX86
187 CheckObject(UserDirectoryHandle, 33UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
188#else
189 CheckObject(UserDirectoryHandle, 32769UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
190#endif
191 else
192 CheckObject(UserDirectoryHandle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
193
194 TestDuplicate(UserDirectoryHandle);
195
196 Status = ObCloseHandle(UserDirectoryHandle, UserMode);
198 }
199
201 NULL,
203 NULL,
204 NULL);
205 Status = ZwCreateDirectoryObject(&KernelDirectoryHandle,
209 if (!skip(NT_SUCCESS(Status), "No directory handle\n"))
210 {
211 ok(IsKernelHandle(KernelDirectoryHandle), "Kernel handle = %p\n", KernelDirectoryHandle);
213#ifdef _M_IX86
214 CheckObject(KernelDirectoryHandle, 33UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
215#else
216 CheckObject(KernelDirectoryHandle, 32769UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
217#endif
218 else
219 CheckObject(KernelDirectoryHandle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
220
221 TestDuplicate(KernelDirectoryHandle);
222
223 Status = ObCloseHandle(KernelDirectoryHandle, UserMode);
226#ifdef _M_IX86
227 CheckObject(KernelDirectoryHandle, 17UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
228#else
229 CheckObject(KernelDirectoryHandle, 32753UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
230#endif
231 else
232 CheckObject(KernelDirectoryHandle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
233
234 Status = ObCloseHandle(KernelDirectoryHandle, KernelMode);
236 }
237
238 /* Tests for closing handles */
240 /* NtClose must accept everything */
241 DPRINT("Closing null handle (NtClose)\n");
244 DPRINT("Closing null kernel handle (NtClose)\n");
245 Status = NtClose(LongToHandle(0x80000000));
247 DPRINT("Closing -1 handle (NtClose)\n");
248 Status = NtClose(LongToHandle(0x7FFFFFFF));
250 DPRINT("Closing -1 kernel handle (NtClose)\n");
251 Status = NtClose(LongToHandle(0xFFFFFFFF));
254 else
256 DPRINT("Closing 123 handle (NtClose)\n");
260 else if (GetNTVersion() != _WIN32_WINNT_WS03)
262 DPRINT("Closing 123 kernel handle (NtClose)\n");
263 Status = NtClose(LongToHandle(123 | 0x80000000));
265
266 /* ObCloseHandle with UserMode accepts everything */
267 DPRINT("Closing null handle (ObCloseHandle, UserMode)\n");
270 DPRINT("Closing null kernel handle (ObCloseHandle, UserMode)\n");
273 DPRINT("Closing -1 handle (ObCloseHandle, UserMode)\n");
276 DPRINT("Closing -1 kernel handle (ObCloseHandle, UserMode)\n");
280 else
282 DPRINT("Closing 123 handle (ObCloseHandle, UserMode)\n");
285 DPRINT("Closing 123 kernel handle (ObCloseHandle, UserMode)\n");
286 Status = ObCloseHandle(LongToHandle(123 | 0x80000000), UserMode);
288
289 /* ZwClose only accepts 0 and -1 */
290 DPRINT("Closing null handle (ZwClose)\n");
293 DPRINT("Closing null kernel handle (ZwClose)\n");
294 Status = ZwClose(LongToHandle(0x80000000));
296 /* INVALID_KERNEL_HANDLE, 0x7FFFFFFF
297 Status = ZwClose((HANDLE)0x7FFFFFFF);*/
298 DPRINT("Closing -1 kernel handle (ZwClose)\n");
299 Status = ZwClose(LongToHandle(0xFFFFFFFF));
302 else
304 /* INVALID_KERNEL_HANDLE, 0x7B, 1, 0, 0
305 Status = ZwClose(LongToHandle(123));
306 Status = ZwClose(LongToHandle(123 | 0x80000000));*/
307
308 /* ObCloseHandle with KernelMode accepts only 0 and -1 */
309 DPRINT("Closing null handle (ObCloseHandle, KernelMode)\n");
312 DPRINT("Closing null kernel handle (ObCloseHandle, KernelMode)\n");
315 /* INVALID_KERNEL_HANDLE, 0x7FFFFFFF, 1, 0, 0
316 Status = ObCloseHandle((HANDLE)0x7FFFFFFF, KernelMode);*/
317 DPRINT("Closing -1 kernel handle (ObCloseHandle, KernelMode)\n");
321 else
323 /* INVALID_KERNEL_HANDLE, 0x7B, 1, 0, 0
324 Status = ObCloseHandle(LongToHandle(123), KernelMode);
325 Status = ObCloseHandle(LongToHandle(123 | 0x80000000), KernelMode);*/
327
329 {
331 }
332}
#define CheckObject(Handle, Pointers, Handles, Attrib, Access)
Definition: ObHandle.c:12
#define IsKernelHandle(h)
Definition: ObHandle.c:26
static HANDLE SystemProcessHandle
Definition: ObHandle.c:28
#define IsUserHandle(h)
Definition: ObHandle.c:25
static VOID TestDuplicate(_In_ HANDLE Handle)
Definition: ObHandle.c:32
struct test_data Tests[]
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define ok_eq_hex(value, expected)
Definition: apitest.h:62
#define GetNTVersion()
Definition: apitest.h:17
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
#define LongToHandle(h)
Definition: basetsd.h:82
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_INHERIT
Definition: winternl.h:225
#define KmtStartSeh()
Definition: kmt_test.h:285
#define KmtEndSeh(ExpectedStatus)
Definition: kmt_test.h:291
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:153
#define _In_
Definition: no_sal2.h:158
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
POBJECT_TYPE PsProcessType
Definition: process.c:20
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2742
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
#define _WIN32_WINNT_WIN10
Definition: sdkddkver.h:32
#define _WIN32_WINNT_WS03
Definition: sdkddkver.h:23
#define _WIN32_WINNT_WIN8
Definition: sdkddkver.h:29
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
#define UL
Definition: tui.h:164
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3534
#define DUPLICATE_SAME_ACCESS
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:20
#define ZwCurrentProcess()