6de3c42e19590088233e7ed42a6902d5a8d046e3
[reactos.git] / rostests / kmtests / ntos_io / IoCreateFile.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Io Regressions KM-Test (IoCreateFile)
5 * PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
6 */
7
8 #include <kmt_test.h>
9
10 static UNICODE_STRING SystemRoot = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
11 static UNICODE_STRING Regedit = RTL_CONSTANT_STRING(L"regedit.exe");
12 static UNICODE_STRING Foobar = RTL_CONSTANT_STRING(L"foobar.exe");
13 static UNICODE_STRING SystemRootRegedit = RTL_CONSTANT_STRING(L"\\SystemRoot\\regedit.exe");
14 static UNICODE_STRING SystemRootFoobar = RTL_CONSTANT_STRING(L"\\SystemRoot\\foobar.exe");
15 static UNICODE_STRING SystemRootFoobarFoobar = RTL_CONSTANT_STRING(L"\\SystemRoot\\foobar\\foobar.exe");
16 static UNICODE_STRING FoobarFoobar = RTL_CONSTANT_STRING(L"foobar\\foobar.exe");
17
18 static
19 VOID
20 NTAPI
21 KernelModeTest(IN PVOID Context)
22 {
23 NTSTATUS Status;
24 IO_STATUS_BLOCK IoStatusBlock;
25 OBJECT_ATTRIBUTES ObjectAttributes;
26 HANDLE ParentHandle, SystemRootHandle, TargetHandle;
27 PFILE_OBJECT ParentFileObject, TargetFileObject, SystemRootFileObject;
28
29 UNREFERENCED_PARAMETER(Context);
30
31 /* Kernelmode mandatory for IoCreateFile */
32 ok(ExGetPreviousMode() == KernelMode, "UserMode returned!\n");
33
34 /* First of all, open \\SystemRoot
35 * We're interested in 3 pieces of information about it:
36 * -> Its target (it's a symlink): \Windows or \ReactOS
37 * -> Its associated File Object
38 * -> Its associated FCB
39 */
40 TargetFileObject = NULL;
41 IoStatusBlock.Status = 0xFFFFFFFF;
42 TargetHandle = INVALID_HANDLE_VALUE;
43 IoStatusBlock.Information = 0xFFFFFFFF;
44 InitializeObjectAttributes(&ObjectAttributes,
45 &SystemRoot,
46 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
47 NULL, NULL);
48 Status = ZwOpenFile(&TargetHandle,
49 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
50 &ObjectAttributes,
51 &IoStatusBlock,
52 FILE_SHARE_READ | FILE_SHARE_WRITE,
53 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
54 ok_eq_hex(Status, STATUS_SUCCESS);
55 ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
56 if (Status == STATUS_SUCCESS)
57 {
58 Status = ObReferenceObjectByHandle(TargetHandle,
59 FILE_READ_DATA,
60 *IoFileObjectType,
61 KernelMode,
62 (PVOID *)&TargetFileObject,
63 NULL);
64 ok_eq_hex(Status, STATUS_SUCCESS);
65 }
66
67 ok(TargetFileObject != NULL, "Not target to continue!\n");
68 if (TargetFileObject == NULL)
69 {
70 if (TargetHandle != INVALID_HANDLE_VALUE)
71 {
72 ObCloseHandle(TargetHandle, KernelMode);
73 }
74 return;
75 }
76
77 /* Open target directory of \SystemRoot\Regedit.exe
78 * This must lead to \SystemRoot opening
79 */
80 IoStatusBlock.Status = 0xFFFFFFFF;
81 IoStatusBlock.Information = 0xFFFFFFFF;
82 InitializeObjectAttributes(&ObjectAttributes,
83 &SystemRootRegedit,
84 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
85 NULL, NULL);
86 Status = IoCreateFile(&ParentHandle,
87 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
88 &ObjectAttributes,
89 &IoStatusBlock,
90 NULL,
91 0,
92 FILE_SHARE_READ | FILE_SHARE_WRITE,
93 FILE_OPEN,
94 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
95 NULL,
96 0,
97 CreateFileTypeNone,
98 NULL,
99 IO_OPEN_TARGET_DIRECTORY);
100 ok_eq_hex(Status, STATUS_SUCCESS);
101 ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
102 if (Status == STATUS_SUCCESS)
103 {
104 Status = ObReferenceObjectByHandle(ParentHandle,
105 FILE_READ_DATA,
106 *IoFileObjectType,
107 KernelMode,
108 (PVOID *)&ParentFileObject,
109 NULL);
110 ok_eq_hex(Status, STATUS_SUCCESS);
111 if (Status == STATUS_SUCCESS)
112 {
113 /* At that point, file object must point to \SystemRoot
114 * But must not be the same FO than target (diverted file object)
115 * This means FCB & FileName are equal
116 * But CCB & FO are different
117 * CCB must be != NULL, otherwise it means open failed
118 */
119 ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
120 ok_eq_pointer(ParentFileObject->RelatedFileObject, NULL);
121 ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
122 ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
123 ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
124 ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
125 ObDereferenceObject(ParentFileObject);
126 }
127 /* Because target exists FSD must signal it */
128 ok_eq_long(IoStatusBlock.Information, FILE_EXISTS);
129 ObCloseHandle(ParentHandle, KernelMode);
130 }
131
132 /* Do the same with relative open */
133 IoStatusBlock.Status = 0xFFFFFFFF;
134 IoStatusBlock.Information = 0xFFFFFFFF;
135 InitializeObjectAttributes(&ObjectAttributes,
136 &SystemRoot,
137 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
138 NULL, NULL);
139 Status = ZwOpenFile(&SystemRootHandle,
140 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
141 &ObjectAttributes,
142 &IoStatusBlock,
143 FILE_SHARE_READ | FILE_SHARE_WRITE,
144 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
145 ok_eq_hex(Status, STATUS_SUCCESS);
146 ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
147 if (Status == STATUS_SUCCESS)
148 {
149 IoStatusBlock.Status = 0xFFFFFFFF;
150 IoStatusBlock.Information = 0xFFFFFFFF;
151 InitializeObjectAttributes(&ObjectAttributes,
152 &Regedit,
153 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
154 SystemRootHandle,
155 NULL);
156 Status = IoCreateFile(&ParentHandle,
157 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
158 &ObjectAttributes,
159 &IoStatusBlock,
160 NULL,
161 0,
162 FILE_SHARE_READ | FILE_SHARE_WRITE,
163 FILE_OPEN,
164 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
165 NULL,
166 0,
167 CreateFileTypeNone,
168 NULL,
169 IO_OPEN_TARGET_DIRECTORY);
170 ok_eq_hex(Status, STATUS_SUCCESS);
171 ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
172 if (Status == STATUS_SUCCESS)
173 {
174 Status = ObReferenceObjectByHandle(ParentHandle,
175 FILE_READ_DATA,
176 *IoFileObjectType,
177 KernelMode,
178 (PVOID *)&ParentFileObject,
179 NULL);
180 ok_eq_hex(Status, STATUS_SUCCESS);
181 if (Status == STATUS_SUCCESS)
182 {
183 ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
184 ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
185 ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
186 ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
187 ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
188 Status = ObReferenceObjectByHandle(SystemRootHandle,
189 FILE_READ_DATA,
190 *IoFileObjectType,
191 KernelMode,
192 (PVOID *)&SystemRootFileObject,
193 NULL);
194 ok_eq_hex(Status, STATUS_SUCCESS);
195 if (Status == STATUS_SUCCESS)
196 {
197 ok_eq_pointer(ParentFileObject->RelatedFileObject, SystemRootFileObject);
198 ok(ParentFileObject->RelatedFileObject != TargetFileObject, "File objects must be different\n");
199 ok(SystemRootFileObject != TargetFileObject, "File objects must be different\n");
200 ObDereferenceObject(SystemRootFileObject);
201 }
202 ObDereferenceObject(ParentFileObject);
203 }
204 ok_eq_long(IoStatusBlock.Information, FILE_EXISTS);
205 ObCloseHandle(ParentHandle, KernelMode);
206 }
207 ObCloseHandle(SystemRootHandle, KernelMode);
208 }
209
210 /* *** */
211
212 /* Now redo the same scheme, but using a target that doesn't exist
213 * The difference will be in IoStatusBlock.Information, the FSD will
214 * inform that the target doesn't exist.
215 * Clear for rename :-)
216 */
217 IoStatusBlock.Status = 0xFFFFFFFF;
218 IoStatusBlock.Information = 0xFFFFFFFF;
219 InitializeObjectAttributes(&ObjectAttributes,
220 &SystemRootFoobar,
221 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
222 NULL, NULL);
223 Status = IoCreateFile(&ParentHandle,
224 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
225 &ObjectAttributes,
226 &IoStatusBlock,
227 NULL,
228 0,
229 FILE_SHARE_READ | FILE_SHARE_WRITE,
230 FILE_OPEN,
231 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
232 NULL,
233 0,
234 CreateFileTypeNone,
235 NULL,
236 IO_OPEN_TARGET_DIRECTORY);
237 ok_eq_hex(Status, STATUS_SUCCESS);
238 ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
239 if (Status == STATUS_SUCCESS)
240 {
241 Status = ObReferenceObjectByHandle(ParentHandle,
242 FILE_READ_DATA,
243 *IoFileObjectType,
244 KernelMode,
245 (PVOID *)&ParentFileObject,
246 NULL);
247 ok_eq_hex(Status, STATUS_SUCCESS);
248 if (Status == STATUS_SUCCESS)
249 {
250 ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
251 ok_eq_pointer(ParentFileObject->RelatedFileObject, NULL);
252 ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
253 ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
254 ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
255 ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
256 ObDereferenceObject(ParentFileObject);
257 }
258 ok_eq_long(IoStatusBlock.Information, FILE_DOES_NOT_EXIST);
259 ObCloseHandle(ParentHandle, KernelMode);
260 }
261
262 IoStatusBlock.Status = 0xFFFFFFFF;
263 IoStatusBlock.Information = 0xFFFFFFFF;
264 InitializeObjectAttributes(&ObjectAttributes,
265 &SystemRoot,
266 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
267 NULL, NULL);
268 Status = ZwOpenFile(&SystemRootHandle,
269 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
270 &ObjectAttributes,
271 &IoStatusBlock,
272 FILE_SHARE_READ | FILE_SHARE_WRITE,
273 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
274 ok_eq_hex(Status, STATUS_SUCCESS);
275 ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
276 if (Status == STATUS_SUCCESS)
277 {
278 IoStatusBlock.Status = 0xFFFFFFFF;
279 IoStatusBlock.Information = 0xFFFFFFFF;
280 InitializeObjectAttributes(&ObjectAttributes,
281 &Foobar,
282 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
283 SystemRootHandle,
284 NULL);
285 Status = IoCreateFile(&ParentHandle,
286 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
287 &ObjectAttributes,
288 &IoStatusBlock,
289 NULL,
290 0,
291 FILE_SHARE_READ | FILE_SHARE_WRITE,
292 FILE_OPEN,
293 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
294 NULL,
295 0,
296 CreateFileTypeNone,
297 NULL,
298 IO_OPEN_TARGET_DIRECTORY);
299 ok_eq_hex(Status, STATUS_SUCCESS);
300 ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
301 if (Status == STATUS_SUCCESS)
302 {
303 Status = ObReferenceObjectByHandle(ParentHandle,
304 FILE_READ_DATA,
305 *IoFileObjectType,
306 KernelMode,
307 (PVOID *)&ParentFileObject,
308 NULL);
309 ok_eq_hex(Status, STATUS_SUCCESS);
310 if (Status == STATUS_SUCCESS)
311 {
312 ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
313 ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
314 ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
315 ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
316 ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
317 Status = ObReferenceObjectByHandle(SystemRootHandle,
318 FILE_READ_DATA,
319 *IoFileObjectType,
320 KernelMode,
321 (PVOID *)&SystemRootFileObject,
322 NULL);
323 ok_eq_hex(Status, STATUS_SUCCESS);
324 if (Status == STATUS_SUCCESS)
325 {
326 ok_eq_pointer(ParentFileObject->RelatedFileObject, SystemRootFileObject);
327 ok(ParentFileObject->RelatedFileObject != TargetFileObject, "File objects must be different\n");
328 ok(SystemRootFileObject != TargetFileObject, "File objects must be different\n");
329 ObDereferenceObject(SystemRootFileObject);
330 }
331 ObDereferenceObject(ParentFileObject);
332 }
333 ok_eq_long(IoStatusBlock.Information, FILE_DOES_NOT_EXIST);
334 ObCloseHandle(ParentHandle, KernelMode);
335 }
336 ObCloseHandle(SystemRootHandle, KernelMode);
337 }
338
339 ObDereferenceObject(TargetFileObject);
340 ObCloseHandle(TargetHandle, KernelMode);
341
342 /* *** */
343
344 /* Direct target open of something that doesn't exist */
345 IoStatusBlock.Status = 0xFFFFFFFF;
346 IoStatusBlock.Information = 0xFFFFFFFF;
347 InitializeObjectAttributes(&ObjectAttributes,
348 &SystemRootFoobarFoobar,
349 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
350 NULL, NULL);
351 Status = IoCreateFile(&ParentHandle,
352 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
353 &ObjectAttributes,
354 &IoStatusBlock,
355 NULL,
356 0,
357 FILE_SHARE_READ | FILE_SHARE_WRITE,
358 FILE_OPEN,
359 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
360 NULL,
361 0,
362 CreateFileTypeNone,
363 NULL,
364 IO_OPEN_TARGET_DIRECTORY);
365 ok_eq_hex(Status, STATUS_OBJECT_PATH_NOT_FOUND);
366 ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
367 if (Status == STATUS_SUCCESS)
368 {
369 ObCloseHandle(ParentHandle, KernelMode);
370 }
371
372 /* Relative target open of something that doesn't exist */
373 IoStatusBlock.Status = 0xFFFFFFFF;
374 IoStatusBlock.Information = 0xFFFFFFFF;
375 InitializeObjectAttributes(&ObjectAttributes,
376 &SystemRoot,
377 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
378 NULL, NULL);
379 Status = ZwOpenFile(&SystemRootHandle,
380 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
381 &ObjectAttributes,
382 &IoStatusBlock,
383 FILE_SHARE_READ | FILE_SHARE_WRITE,
384 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
385 ok_eq_hex(Status, STATUS_SUCCESS);
386 ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
387 if (Status == STATUS_SUCCESS)
388 {
389 IoStatusBlock.Status = 0xFFFFFFFF;
390 IoStatusBlock.Information = 0xFFFFFFFF;
391 InitializeObjectAttributes(&ObjectAttributes,
392 &FoobarFoobar,
393 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
394 SystemRootHandle,
395 NULL);
396 Status = IoCreateFile(&ParentHandle,
397 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
398 &ObjectAttributes,
399 &IoStatusBlock,
400 NULL,
401 0,
402 FILE_SHARE_READ | FILE_SHARE_WRITE,
403 FILE_OPEN,
404 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
405 NULL,
406 0,
407 CreateFileTypeNone,
408 NULL,
409 IO_OPEN_TARGET_DIRECTORY);
410 ok_eq_hex(Status, STATUS_OBJECT_PATH_NOT_FOUND);
411 ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
412 if (Status == STATUS_SUCCESS)
413 {
414 ObCloseHandle(ParentHandle, KernelMode);
415 }
416 ObCloseHandle(SystemRootHandle, KernelMode);
417 }
418 }
419
420 static
421 VOID
422 NTAPI
423 UserModeTest(VOID)
424 {
425 NTSTATUS Status;
426 IO_STATUS_BLOCK IoStatusBlock;
427 OBJECT_ATTRIBUTES ObjectAttributes;
428 HANDLE ParentHandle, SystemRootHandle;
429
430 ok(ExGetPreviousMode() == UserMode, "KernelMode returned!\n");
431
432 /* Attempt direct target open */
433 IoStatusBlock.Status = 0xFFFFFFFF;
434 IoStatusBlock.Information = 0xFFFFFFFF;
435 InitializeObjectAttributes(&ObjectAttributes,
436 &SystemRootRegedit,
437 OBJ_CASE_INSENSITIVE,
438 NULL, NULL);
439 Status = IoCreateFile(&ParentHandle,
440 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
441 &ObjectAttributes,
442 &IoStatusBlock,
443 NULL,
444 0,
445 FILE_SHARE_READ | FILE_SHARE_WRITE,
446 FILE_OPEN,
447 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
448 NULL,
449 0,
450 CreateFileTypeNone,
451 NULL,
452 IO_OPEN_TARGET_DIRECTORY);
453 ok_eq_hex(Status, STATUS_ACCESS_VIOLATION);
454 ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
455 if (Status == STATUS_SUCCESS)
456 {
457 ObCloseHandle(ParentHandle, UserMode);
458 }
459
460 /* Attempt relative target open */
461 IoStatusBlock.Status = 0xFFFFFFFF;
462 IoStatusBlock.Information = 0xFFFFFFFF;
463 InitializeObjectAttributes(&ObjectAttributes,
464 &SystemRoot,
465 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
466 NULL, NULL);
467 Status = ZwOpenFile(&SystemRootHandle,
468 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
469 &ObjectAttributes,
470 &IoStatusBlock,
471 FILE_SHARE_READ | FILE_SHARE_WRITE,
472 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
473 ok_eq_hex(Status, STATUS_SUCCESS);
474 ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
475 if (Status == STATUS_SUCCESS)
476 {
477 IoStatusBlock.Status = 0xFFFFFFFF;
478 IoStatusBlock.Information = 0xFFFFFFFF;
479 InitializeObjectAttributes(&ObjectAttributes,
480 &Regedit,
481 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
482 SystemRootHandle,
483 NULL);
484 Status = IoCreateFile(&ParentHandle,
485 GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
486 &ObjectAttributes,
487 &IoStatusBlock,
488 NULL,
489 0,
490 FILE_SHARE_READ | FILE_SHARE_WRITE,
491 FILE_OPEN,
492 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
493 NULL,
494 0,
495 CreateFileTypeNone,
496 NULL,
497 IO_OPEN_TARGET_DIRECTORY);
498 ok_eq_hex(Status, STATUS_ACCESS_VIOLATION);
499 ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
500 if (Status == STATUS_SUCCESS)
501 {
502 ObCloseHandle(ParentHandle, KernelMode);
503 }
504 ObCloseHandle(SystemRootHandle, KernelMode);
505 }
506 }
507
508 START_TEST(IoCreateFile)
509 {
510 NTSTATUS Status;
511 OBJECT_ATTRIBUTES ObjectAttributes;
512 HANDLE ThreadHandle;
513 PVOID ThreadObject = NULL;
514
515 /* Justify the next comment/statement */
516 UserModeTest();
517
518 /* We've to be in kernel mode, so spawn a thread */
519 InitializeObjectAttributes(&ObjectAttributes,
520 NULL,
521 OBJ_KERNEL_HANDLE,
522 NULL,
523 NULL);
524 Status = PsCreateSystemThread(&ThreadHandle,
525 SYNCHRONIZE,
526 &ObjectAttributes,
527 NULL,
528 NULL,
529 KernelModeTest,
530 NULL);
531 ok_eq_hex(Status, STATUS_SUCCESS);
532 if (Status == STATUS_SUCCESS)
533 {
534 /* Then, just wait on our thread to finish */
535 Status = ObReferenceObjectByHandle(ThreadHandle,
536 SYNCHRONIZE,
537 *PsThreadType,
538 KernelMode,
539 &ThreadObject,
540 NULL);
541 ObCloseHandle(ThreadHandle, KernelMode);
542
543 Status = KeWaitForSingleObject(ThreadObject,
544 Executive,
545 KernelMode,
546 FALSE,
547 NULL);
548 ok_eq_hex(Status, STATUS_SUCCESS);
549 ObDereferenceObject(ThreadObject);
550 }
551 }