[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 #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
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
137 /* Tests for closing handles */
138 KmtStartSeh()
139 /* NtClose must accept everything */
140 DPRINT("Closing null handle (NtClose)\n");
141 Status = NtClose(NULL);
142 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
143 DPRINT("Closing null kernel handle (NtClose)\n");
144 Status = NtClose((HANDLE)0x80000000);
145 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
146 DPRINT("Closing -1 handle (NtClose)\n");
147 Status = NtClose((HANDLE)0x7FFFFFFF);
148 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
149 DPRINT("Closing -1 kernel handle (NtClose)\n");
150 Status = NtClose((HANDLE)0xFFFFFFFF);
151 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
152 DPRINT("Closing 123 handle (NtClose)\n");
153 Status = NtClose((HANDLE)123);
154 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
155 DPRINT("Closing 123 kernel handle (NtClose)\n");
156 Status = NtClose((HANDLE)(123 | 0x80000000));
157 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
158
159 /* ObCloseHandle with UserMode accepts everything */
160 DPRINT("Closing null handle (ObCloseHandle, UserMode)\n");
161 Status = ObCloseHandle(NULL, UserMode);
162 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
163 DPRINT("Closing null kernel handle (ObCloseHandle, UserMode)\n");
164 Status = ObCloseHandle((HANDLE)0x80000000, UserMode);
165 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
166 DPRINT("Closing -1 handle (ObCloseHandle, UserMode)\n");
167 Status = ObCloseHandle((HANDLE)0x7FFFFFFF, UserMode);
168 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
169 DPRINT("Closing -1 kernel handle (ObCloseHandle, UserMode)\n");
170 Status = ObCloseHandle((HANDLE)0xFFFFFFFF, UserMode);
171 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
172 DPRINT("Closing 123 handle (ObCloseHandle, UserMode)\n");
173 Status = ObCloseHandle((HANDLE)123, UserMode);
174 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
175 DPRINT("Closing 123 kernel handle (ObCloseHandle, UserMode)\n");
176 Status = ObCloseHandle((HANDLE)(123 | 0x80000000), UserMode);
177 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
178
179 /* ZwClose only accepts 0 and -1 */
180 DPRINT("Closing null handle (ZwClose)\n");
181 Status = ZwClose(NULL);
182 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
183 DPRINT("Closing null kernel handle (ZwClose)\n");
184 Status = ZwClose((HANDLE)0x80000000);
185 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
186 /* INVALID_KERNEL_HANDLE, 0x7FFFFFFF
187 Status = ZwClose((HANDLE)0x7FFFFFFF);*/
188 DPRINT("Closing -1 kernel handle (ZwClose)\n");
189 Status = ZwClose((HANDLE)0xFFFFFFFF);
190 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
191 /* INVALID_KERNEL_HANDLE, 0x7B, 1, 0, 0
192 Status = ZwClose((HANDLE)123);
193 Status = ZwClose((HANDLE)(123 | 0x80000000));*/
194
195 /* ObCloseHandle with KernelMode accepts only 0 and -1 */
196 DPRINT("Closing null handle (ObCloseHandle, KernelMode)\n");
197 Status = ObCloseHandle(NULL, KernelMode);
198 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
199 DPRINT("Closing null kernel handle (ObCloseHandle, KernelMode)\n");
200 Status = ObCloseHandle((HANDLE)0x80000000, KernelMode);
201 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
202 /* INVALID_KERNEL_HANDLE, 0x7FFFFFFF, 1, 0, 0
203 Status = ObCloseHandle((HANDLE)0x7FFFFFFF, KernelMode);*/
204 DPRINT("Closing -1 kernel handle (ObCloseHandle, KernelMode)\n");
205 Status = ObCloseHandle((HANDLE)0xFFFFFFFF, KernelMode);
206 ok_eq_hex(Status, STATUS_INVALID_HANDLE);
207 /* INVALID_KERNEL_HANDLE, 0x7B, 1, 0, 0
208 Status = ObCloseHandle((HANDLE)123, KernelMode);
209 Status = ObCloseHandle((HANDLE)(123 | 0x80000000), KernelMode);*/
210 KmtEndSeh(STATUS_SUCCESS);
211 }