[KMTESTS:OB]
[reactos.git] / rostests / kmtests / ntos_ob / ObHandle.c
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
10 #include <ndk/obfuncs.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
28 static
29 VOID
30 TestDuplicate(
31 _In_ HANDLE Handle)
32 {
33 NTSTATUS Status;
34 HANDLE NewHandle;
35 struct
36 {
37 ACCESS_MASK DesiredAccess;
38 ULONG RequestedAttributes;
39 ULONG Options;
40 ACCESS_MASK GrantedAccess;
41 ULONG ExpectedAttributes;
42 } Tests[] =
43 {
44 { DIRECTORY_ALL_ACCESS, 0, 0,
45 DIRECTORY_ALL_ACCESS, 0 },
46 { DIRECTORY_ALL_ACCESS, OBJ_KERNEL_HANDLE, 0,
47 DIRECTORY_ALL_ACCESS, 0 },
48 { DIRECTORY_QUERY, 0, 0,
49 DIRECTORY_QUERY, 0 },
50 { DIRECTORY_QUERY, OBJ_INHERIT, 0,
51 DIRECTORY_QUERY, OBJ_INHERIT },
52 { DIRECTORY_QUERY, OBJ_INHERIT, DUPLICATE_SAME_ACCESS,
53 DIRECTORY_ALL_ACCESS, OBJ_INHERIT },
54 /* 5 */
55 { DIRECTORY_QUERY, OBJ_INHERIT, DUPLICATE_SAME_ATTRIBUTES,
56 DIRECTORY_QUERY, 0 },
57 { DIRECTORY_QUERY, OBJ_INHERIT, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES,
58 DIRECTORY_ALL_ACCESS, 0 },
59 };
60 ULONG i;
61
62 for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
63 {
64 trace("Test %lu\n", i);
65 Status = ZwDuplicateObject(ZwCurrentProcess(),
66 Handle,
67 ZwCurrentProcess(),
68 &NewHandle,
69 Tests[i].DesiredAccess,
70 Tests[i].RequestedAttributes,
71 Tests[i].Options);
72 ok_eq_hex(Status, STATUS_SUCCESS);
73 if (!skip(NT_SUCCESS(Status), "DuplicateHandle failed\n"))
74 {
75 ok(IsUserHandle(NewHandle), "New handle = %p\n", NewHandle);
76 CheckObject(NewHandle, 3UL, 2UL, Tests[i].ExpectedAttributes, Tests[i].GrantedAccess);
77 CheckObject(Handle, 3UL, 2UL, 0UL, DIRECTORY_ALL_ACCESS);
78
79 Status = ObCloseHandle(NewHandle, UserMode);
80 ok_eq_hex(Status, STATUS_SUCCESS);
81 CheckObject(Handle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
82 }
83 }
84 }
85
86 START_TEST(ObHandle)
87 {
88 NTSTATUS Status;
89 OBJECT_ATTRIBUTES ObjectAttributes;
90 HANDLE KernelDirectoryHandle;
91 HANDLE UserDirectoryHandle;
92
93 InitializeObjectAttributes(&ObjectAttributes,
94 NULL,
95 0,
96 NULL,
97 NULL);
98 Status = ZwCreateDirectoryObject(&UserDirectoryHandle,
99 DIRECTORY_ALL_ACCESS,
100 &ObjectAttributes);
101 ok_eq_hex(Status, STATUS_SUCCESS);
102 if (!skip(NT_SUCCESS(Status), "No directory handle\n"))
103 {
104 ok(IsUserHandle(UserDirectoryHandle), "User handle = %p\n", UserDirectoryHandle);
105 CheckObject(UserDirectoryHandle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
106
107 TestDuplicate(UserDirectoryHandle);
108
109 Status = ObCloseHandle(UserDirectoryHandle, UserMode);
110 ok_eq_hex(Status, STATUS_SUCCESS);
111 }
112
113 InitializeObjectAttributes(&ObjectAttributes,
114 NULL,
115 OBJ_KERNEL_HANDLE,
116 NULL,
117 NULL);
118 Status = ZwCreateDirectoryObject(&KernelDirectoryHandle,
119 DIRECTORY_ALL_ACCESS,
120 &ObjectAttributes);
121 ok_eq_hex(Status, STATUS_SUCCESS);
122 if (!skip(NT_SUCCESS(Status), "No directory handle\n"))
123 {
124 ok(IsKernelHandle(KernelDirectoryHandle), "Kernel handle = %p\n", KernelDirectoryHandle);
125 CheckObject(KernelDirectoryHandle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
126
127 TestDuplicate(KernelDirectoryHandle);
128
129 Status = ObCloseHandle(KernelDirectoryHandle, UserMode);
130 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
131 CheckObject(KernelDirectoryHandle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS);
132
133 Status = ObCloseHandle(KernelDirectoryHandle, KernelMode);
134 ok_eq_hex(Status, STATUS_SUCCESS);
135 }
136 }