ReactOS 0.4.16-dev-112-g52265ae
IoCreateFile.c File Reference
#include <kmt_test.h>
Include dependency graph for IoCreateFile.c:

Go to the source code of this file.

Functions

static VOID NTAPI KernelModeTest (IN PVOID Context)
 
static VOID NTAPI TestSymlinks (VOID)
 
VOID NTAPI UserModeTest (VOID)
 
 START_TEST (IoCreateFile)
 

Variables

static UNICODE_STRING SystemRoot = RTL_CONSTANT_STRING(L"\\SystemRoot\\")
 
static UNICODE_STRING Regedit = RTL_CONSTANT_STRING(L"regedit.exe")
 
static UNICODE_STRING Foobar = RTL_CONSTANT_STRING(L"foobar.exe")
 
static UNICODE_STRING SystemRootRegedit = RTL_CONSTANT_STRING(L"\\SystemRoot\\regedit.exe")
 
static UNICODE_STRING SystemRootFoobar = RTL_CONSTANT_STRING(L"\\SystemRoot\\foobar.exe")
 
static UNICODE_STRING SystemRootFoobarFoobar = RTL_CONSTANT_STRING(L"\\SystemRoot\\foobar\\foobar.exe")
 
static UNICODE_STRING FoobarFoobar = RTL_CONSTANT_STRING(L"foobar\\foobar.exe")
 

Function Documentation

◆ KernelModeTest()

static VOID NTAPI KernelModeTest ( IN PVOID  Context)
static

Definition at line 21 of file IoCreateFile.c.

22{
26 HANDLE ParentHandle, SystemRootHandle, TargetHandle;
27 PFILE_OBJECT ParentFileObject, TargetFileObject, SystemRootFileObject;
28
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;
43 IoStatusBlock.Information = 0xFFFFFFFF;
47 NULL, NULL);
57 {
62 (PVOID *)&TargetFileObject,
63 NULL);
65 }
66
67 ok(TargetFileObject != NULL, "Not target to continue!\n");
68 if (TargetFileObject == NULL)
69 {
71 {
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;
85 NULL, NULL);
86 Status = IoCreateFile(&ParentHandle,
90 NULL,
91 0,
95 NULL,
96 0,
98 NULL,
102 if (Status == STATUS_SUCCESS)
103 {
104 Status = ObReferenceObjectByHandle(ParentHandle,
108 (PVOID *)&ParentFileObject,
109 NULL);
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 */
129 ObCloseHandle(ParentHandle, KernelMode);
130 }
131
132 /* Do the same with relative open */
133 IoStatusBlock.Status = 0xFFFFFFFF;
134 IoStatusBlock.Information = 0xFFFFFFFF;
136 &SystemRoot,
138 NULL, NULL);
139 Status = ZwOpenFile(&SystemRootHandle,
147 if (Status == STATUS_SUCCESS)
148 {
149 IoStatusBlock.Status = 0xFFFFFFFF;
150 IoStatusBlock.Information = 0xFFFFFFFF;
152 &Regedit,
154 SystemRootHandle,
155 NULL);
156 Status = IoCreateFile(&ParentHandle,
160 NULL,
161 0,
163 FILE_OPEN,
165 NULL,
166 0,
168 NULL,
172 if (Status == STATUS_SUCCESS)
173 {
174 Status = ObReferenceObjectByHandle(ParentHandle,
178 (PVOID *)&ParentFileObject,
179 NULL);
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,
192 (PVOID *)&SystemRootFileObject,
193 NULL);
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 }
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;
222 NULL, NULL);
223 Status = IoCreateFile(&ParentHandle,
227 NULL,
228 0,
230 FILE_OPEN,
232 NULL,
233 0,
235 NULL,
239 if (Status == STATUS_SUCCESS)
240 {
241 Status = ObReferenceObjectByHandle(ParentHandle,
245 (PVOID *)&ParentFileObject,
246 NULL);
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 }
259 ObCloseHandle(ParentHandle, KernelMode);
260 }
261
262 IoStatusBlock.Status = 0xFFFFFFFF;
263 IoStatusBlock.Information = 0xFFFFFFFF;
265 &SystemRoot,
267 NULL, NULL);
268 Status = ZwOpenFile(&SystemRootHandle,
276 if (Status == STATUS_SUCCESS)
277 {
278 IoStatusBlock.Status = 0xFFFFFFFF;
279 IoStatusBlock.Information = 0xFFFFFFFF;
281 &Foobar,
283 SystemRootHandle,
284 NULL);
285 Status = IoCreateFile(&ParentHandle,
289 NULL,
290 0,
292 FILE_OPEN,
294 NULL,
295 0,
297 NULL,
301 if (Status == STATUS_SUCCESS)
302 {
303 Status = ObReferenceObjectByHandle(ParentHandle,
307 (PVOID *)&ParentFileObject,
308 NULL);
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,
321 (PVOID *)&SystemRootFileObject,
322 NULL);
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 }
334 ObCloseHandle(ParentHandle, KernelMode);
335 }
336 ObCloseHandle(SystemRootHandle, KernelMode);
337 }
338
339 ObDereferenceObject(TargetFileObject);
341
342 /* *** */
343
344 /* Direct target open of something that doesn't exist */
345 IoStatusBlock.Status = 0xFFFFFFFF;
346 IoStatusBlock.Information = 0xFFFFFFFF;
350 NULL, NULL);
351 Status = IoCreateFile(&ParentHandle,
355 NULL,
356 0,
358 FILE_OPEN,
360 NULL,
361 0,
363 NULL,
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;
376 &SystemRoot,
378 NULL, NULL);
379 Status = ZwOpenFile(&SystemRootHandle,
387 if (Status == STATUS_SUCCESS)
388 {
389 IoStatusBlock.Status = 0xFFFFFFFF;
390 IoStatusBlock.Information = 0xFFFFFFFF;
394 SystemRootHandle,
395 NULL);
396 Status = IoCreateFile(&ParentHandle,
400 NULL,
401 0,
403 FILE_OPEN,
405 NULL,
406 0,
408 NULL,
411 ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
412 if (Status == STATUS_SUCCESS)
413 {
414 ObCloseHandle(ParentHandle, KernelMode);
415 }
416 ObCloseHandle(SystemRootHandle, KernelMode);
417 }
418}
static UNICODE_STRING Regedit
Definition: IoCreateFile.c:11
static UNICODE_STRING Foobar
Definition: IoCreateFile.c:12
static UNICODE_STRING SystemRootRegedit
Definition: IoCreateFile.c:13
static UNICODE_STRING SystemRootFoobar
Definition: IoCreateFile.c:14
static UNICODE_STRING SystemRoot
Definition: IoCreateFile.c:10
static UNICODE_STRING SystemRootFoobarFoobar
Definition: IoCreateFile.c:15
static UNICODE_STRING FoobarFoobar
Definition: IoCreateFile.c:16
#define ok_eq_pointer(value, expected)
Definition: apitest.h:59
#define ok_eq_hex(value, expected)
Definition: apitest.h:77
#define ok_eq_long(value, expected)
Definition: apitest.h:62
#define ok(value,...)
Definition: atltest.h:57
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define FILE_SHARE_READ
Definition: compat.h:136
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define ExGetPreviousMode
Definition: ex.h:140
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
Status
Definition: gdiplustypes.h:25
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:431
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_DOES_NOT_EXIST
Definition: nt_native.h:773
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_EXISTS
Definition: nt_native.h:772
#define GENERIC_WRITE
Definition: nt_native.h:90
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
NTSTATUS NTAPI IoCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options)
Definition: file.c:3010
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define IO_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:7352
* PFILE_OBJECT
Definition: iotypes.h:1998
@ CreateFileTypeNone
Definition: iotypes.h:535
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( IoCreateFile  )

Definition at line 872 of file IoCreateFile.c.

873{
874 PKTHREAD ThreadHandle;
875
876 TestSymlinks();
877
878 /* Justify the next comment/statement */
879 UserModeTest();
880
881 /* We've to be in kernel mode, so spawn a thread */
882 ThreadHandle = KmtStartThread(KernelModeTest, NULL);
883 KmtFinishThread(ThreadHandle, NULL);
884}
static VOID NTAPI TestSymlinks(VOID)
Definition: IoCreateFile.c:423
static VOID NTAPI KernelModeTest(IN PVOID Context)
Definition: IoCreateFile.c:21
VOID NTAPI UserModeTest(VOID)
Definition: IoCreateFile.c:787
PKTHREAD KmtStartThread(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext OPTIONAL)
VOID KmtFinishThread(IN PKTHREAD Thread OPTIONAL, IN PKEVENT Event OPTIONAL)

◆ TestSymlinks()

static VOID NTAPI TestSymlinks ( VOID  )
static

Definition at line 423 of file IoCreateFile.c.

424{
425 HANDLE ReparseHandle;
429 PREPARSE_DATA_BUFFER Reparse;
433 ULONG Size;
434
435 /* Get Windows/ReactOS directory */
437 &SystemRoot,
439 NULL,
440 NULL);
441 Status = ZwOpenFile(&ReparseHandle,
447 if (skip(NT_SUCCESS(Status), "Opening \\SystemRoot failed: %lx\n", Status))
448 {
449 return;
450 }
451
452 Status = ObReferenceObjectByHandle(ReparseHandle,
455 UserMode,
456 (PVOID *)&FileObject,
457 NULL);
458 if (skip(NT_SUCCESS(Status), "Querying name failed: %lx\n", Status))
459 {
460 ZwClose(ReparseHandle);
461 return;
462 }
463
464 SysDir.Buffer = ExAllocatePool(NonPagedPool, FileObject->FileName.Length + sizeof(L"\\??\\C:"));
465 if (skip(SysDir.Buffer != NULL, "Allocating memory failed\n"))
466 {
468 ZwClose(ReparseHandle);
469 return;
470 }
471
472 SysDir.Length = sizeof(L"\\??\\C:") - sizeof(UNICODE_NULL);
473 SysDir.MaximumLength = FileObject->FileName.Length + sizeof(L"\\??\\C:");
474 RtlCopyMemory(SysDir.Buffer, L"\\??\\C:", sizeof(L"\\??\\C:") - sizeof(UNICODE_NULL));
475 RtlAppendUnicodeStringToString(&SysDir, &FileObject->FileName);
476
477 Foobar.Buffer = ExAllocatePool(NonPagedPool, FileObject->FileName.Length + sizeof(L"\\foobar.exe"));
478 if (skip(Foobar.Buffer != NULL, "Allocating memory failed\n"))
479 {
480 ExFreePool(SysDir.Buffer);
482 ZwClose(ReparseHandle);
483 return;
484 }
485
486 Foobar.Length = 0;
487 Foobar.MaximumLength = FileObject->FileName.Length + sizeof(L"\\foobar.exe");
489 RtlCopyMemory(&Foobar.Buffer[Foobar.Length / sizeof(WCHAR)], L"\\foobar.exe", sizeof(L"\\foobar.exe") - sizeof(UNICODE_NULL));
490 Foobar.Length += (sizeof(L"\\foobar.exe") - sizeof(UNICODE_NULL));
491
492 Regedit.Buffer = ExAllocatePool(NonPagedPool, FileObject->FileName.Length + sizeof(L"\\regedit.exe"));
493 if (skip(Regedit.Buffer != NULL, "Allocating memory failed\n"))
494 {
496 ExFreePool(SysDir.Buffer);
498 ZwClose(ReparseHandle);
499 return;
500 }
501
502 Regedit.Length = 0;
503 Regedit.MaximumLength = FileObject->FileName.Length + sizeof(L"\\regedit.exe");
505 RtlCopyMemory(&Regedit.Buffer[Regedit.Length / sizeof(WCHAR)], L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));
506 Regedit.Length += (sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));
507
509 ZwClose(ReparseHandle);
510
511 ToDelete.DeleteFile = TRUE;
512 Size = FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + SysDir.Length * 2 + sizeof(L"\\regedit.exe") * 2 - sizeof(L"\\??\\") - sizeof(UNICODE_NULL);
513
517 NULL,
518 NULL);
519 Status = ZwCreateFile(&ReparseHandle,
523 NULL,
528 NULL,
529 0);
531 if (skip(NT_SUCCESS(Status), "Creating file failed: %lx\n", Status))
532 {
535 ExFreePool(SysDir.Buffer);
536 return;
537 }
538
539 Reparse = ExAllocatePool(NonPagedPool, Size);
540 RtlZeroMemory(Reparse, Size);
542 Reparse->ReparseDataLength = 12 + SysDir.Length * 2 + sizeof(L"\\regedit.exe") * 2 - sizeof(L"\\??\\") - sizeof(UNICODE_NULL);
543 Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength = SysDir.Length + sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL);
544 Reparse->SymbolicLinkReparseBuffer.PrintNameLength = SysDir.Length + sizeof(L"\\regedit.exe") - sizeof(L"\\??\\");
545 Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset = Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
546 RtlCopyMemory(Reparse->SymbolicLinkReparseBuffer.PathBuffer,
547 (WCHAR *)((ULONG_PTR)SysDir.Buffer + sizeof(L"\\??\\") - sizeof(UNICODE_NULL)),
548 SysDir.Length - sizeof(L"\\??\\") + sizeof(UNICODE_NULL));
549 RtlCopyMemory((WCHAR *)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + SysDir.Length - sizeof(L"\\??\\") + sizeof(UNICODE_NULL)),
550 L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));
551 RtlCopyMemory((WCHAR *)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset),
552 SysDir.Buffer, SysDir.Length);
553 RtlCopyMemory((WCHAR *)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset + SysDir.Length),
554 L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));
555
556 Status = ZwFsControlFile(ReparseHandle,
557 NULL,
558 NULL,
559 NULL,
562 Reparse,
563 Size,
564 NULL,
565 0);
567 if (!NT_SUCCESS(Status))
568 {
569 ZwClose(ReparseHandle);
570
571 Status = ZwCreateFile(&ReparseHandle,
575 NULL,
577 0,
580 NULL,
581 0);
582 if (skip(NT_SUCCESS(Status), "Creating symlink failed: %lx\n", Status))
583 {
584 Status = ZwOpenFile(&ReparseHandle,
585 DELETE,
591 ZwClose(ReparseHandle);
594 ExFreePool(SysDir.Buffer);
595 ExFreePool(Reparse);
596 return;
597 }
598
599 Status = ZwFsControlFile(ReparseHandle,
600 NULL,
601 NULL,
602 NULL,
605 Reparse,
606 Size,
607 NULL,
608 0);
609 }
610
611 if (skip(NT_SUCCESS(Status), "Creating symlink failed: %lx\n", Status))
612 {
613 ZwSetInformationFile(ReparseHandle,
615 &ToDelete,
616 sizeof(ToDelete),
618 ZwClose(ReparseHandle);
621 ExFreePool(SysDir.Buffer);
622 ExFreePool(Reparse);
623 return;
624 }
625
626 ZwClose(ReparseHandle);
627
628 Status = ZwCreateFile(&ReparseHandle,
632 NULL,
635 FILE_OPEN,
637 NULL,
638 0);
639 ok(Status == STATUS_SUCCESS || /* Windows Vista+ */
640 Status == STATUS_IO_REPARSE_TAG_NOT_HANDLED, /* Windows 2003 (SP1, SP2) */
641 "ZwCreateFile returned unexpected status: %lx\n", Status);
642 if (NT_SUCCESS(Status))
643 {
644 Status = ObReferenceObjectByHandle(ReparseHandle,
647 UserMode,
648 (PVOID *)&FileObject,
649 NULL);
651 if (NT_SUCCESS(Status))
652 {
654 "Expected: %wZ. Opened: %wZ\n", &Regedit, &FileObject->FileName);
656 }
657
658 ZwClose(ReparseHandle);
659 }
660
662
663 Status = IoCreateFile(&ReparseHandle,
667 NULL,
670 FILE_OPEN,
672 NULL,
673 0,
675 NULL,
677 ok(Status == STATUS_STOPPED_ON_SYMLINK || /* Windows Vista+ */
678 Status == STATUS_IO_REPARSE_TAG_NOT_HANDLED, /* Windows 2003 (SP1, SP2) */
679 "ZwCreateFile returned unexpected status: %lx\n", Status);
680 if (NT_SUCCESS(Status))
681 {
682 ZwClose(ReparseHandle);
683 }
684
685 Status = ZwCreateFile(&ReparseHandle,
689 NULL,
692 FILE_OPEN,
694 NULL,
695 0);
696 if (skip(NT_SUCCESS(Status), "Creating opening reparse point: %lx\n", Status))
697 {
698 Status = ZwOpenFile(&ReparseHandle,
699 DELETE,
705 ZwClose(ReparseHandle);
707 ExFreePool(SysDir.Buffer);
708 ExFreePool(Reparse);
709 return;
710 }
711
712 Status = ObReferenceObjectByHandle(ReparseHandle,
715 UserMode,
716 (PVOID *)&FileObject,
717 NULL);
719 if (NT_SUCCESS(Status))
720 {
721 ok(RtlCompareUnicodeString(&Foobar, &FileObject->FileName, TRUE) == 0,
722 "Expected: %wZ. Opened: %wZ\n", &Foobar, &FileObject->FileName);
724 }
725
727
728 RtlZeroMemory(Reparse, Size);
729 Status = ZwFsControlFile(ReparseHandle,
730 NULL,
731 NULL,
732 NULL,
735 NULL,
736 0,
737 Reparse,
738 Size);
741 if (NT_SUCCESS(Status))
742 {
744 UNICODE_STRING ReparsePath, FullPath;
745
747 ok_eq_hex(Reparse->ReparseDataLength, 12 + SysDir.Length * 2 + sizeof(L"\\regedit.exe") * 2 - sizeof(L"\\??\\") - sizeof(UNICODE_NULL));
748 ok_eq_hex(Reparse->SymbolicLinkReparseBuffer.Flags, 0);
749
750 FullPath.Length = 0;
751 FullPath.MaximumLength = SysDir.Length + sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL);
752 Buffer = FullPath.Buffer = ExAllocatePool(NonPagedPool, FullPath.MaximumLength);
753 if (!skip(Buffer != NULL, "Memory allocation failed!\n"))
754 {
755 RtlCopyUnicodeString(&FullPath, &SysDir);
756 RtlCopyMemory(&FullPath.Buffer[FullPath.Length / sizeof(WCHAR)], L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));
757 FullPath.Length += (sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));
758 ReparsePath.Buffer = (PWSTR)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset);
759 ReparsePath.Length = ReparsePath.MaximumLength = Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength;
760 ok(RtlCompareUnicodeString(&ReparsePath, &FullPath, TRUE) == 0, "Expected: %wZ. Got: %wZ\n", &ReparsePath, &FullPath);
761
762 FullPath.Length -= (sizeof(L"\\??\\") - sizeof(UNICODE_NULL));
763 FullPath.MaximumLength -= (sizeof(L"\\??\\") - sizeof(UNICODE_NULL));
764 FullPath.Buffer = (PWSTR)((ULONG_PTR)Buffer + sizeof(L"\\??\\") - sizeof(UNICODE_NULL));
765 ReparsePath.Buffer = (PWSTR)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.PrintNameOffset);
766 ReparsePath.Length = ReparsePath.MaximumLength = Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
767 ok(RtlCompareUnicodeString(&ReparsePath, &FullPath, TRUE) == 0, "Expected: %wZ. Got: %wZ\n", &ReparsePath, &FullPath);
768
770 }
771 }
772
773 ExFreePool(SysDir.Buffer);
774 ExFreePool(Reparse);
775
776 ZwSetInformationFile(ReparseHandle,
778 &ToDelete,
779 sizeof(ToDelete),
781 ZwClose(ReparseHandle);
782}
#define skip(...)
Definition: atltest.h:64
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
Definition: bufpool.h:45
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
@ FileDispositionInformation
Definition: from_kernel.h:74
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
#define UserMode
Definition: asm.h:35
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define DELETE
Definition: nt_native.h:57
#define UNICODE_NULL
NTSYSAPI NTSTATUS NTAPI ZwFsControlFile(IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, OUT PVOID OutputBuffer, IN ULONG OutputBufferSize)
#define STATUS_IO_REPARSE_TAG_NOT_HANDLED
Definition: ntstatus.h:757
#define STATUS_STOPPED_ON_SYMLINK
Definition: ntstatus.h:224
#define L(x)
Definition: ntvdm.h:50
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:746
#define FSCTL_SET_REPARSE_POINT
Definition: winioctl.h:747
WCHAR PathBuffer[1]
Definition: shellext.h:176
struct _REPARSE_DATA_BUFFER::@312::@314 SymbolicLinkReparseBuffer
USHORT ReparseDataLength
Definition: shellext.h:166
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:541
#define IO_STOP_ON_SYMLINK
Definition: iotypes.h:7353
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by START_TEST().

◆ UserModeTest()

VOID NTAPI UserModeTest ( VOID  )

Definition at line 787 of file IoCreateFile.c.

788{
792 HANDLE ParentHandle, SystemRootHandle;
793
794 ok(ExGetPreviousMode() == UserMode, "KernelMode returned!\n");
795
796 /* Attempt direct target open */
797 IoStatusBlock.Status = 0xFFFFFFFF;
798 IoStatusBlock.Information = 0xFFFFFFFF;
802 NULL, NULL);
803 Status = IoCreateFile(&ParentHandle,
807 NULL,
808 0,
810 FILE_OPEN,
812 NULL,
813 0,
815 NULL,
818 ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
819 if (Status == STATUS_SUCCESS)
820 {
821 ObCloseHandle(ParentHandle, UserMode);
822 }
823
824 /* Attempt relative target open */
825 IoStatusBlock.Status = 0xFFFFFFFF;
826 IoStatusBlock.Information = 0xFFFFFFFF;
828 &SystemRoot,
830 NULL, NULL);
831 Status = ZwOpenFile(&SystemRootHandle,
839 if (Status == STATUS_SUCCESS)
840 {
841 IoStatusBlock.Status = 0xFFFFFFFF;
842 IoStatusBlock.Information = 0xFFFFFFFF;
844 &Regedit,
846 SystemRootHandle,
847 NULL);
848 Status = IoCreateFile(&ParentHandle,
852 NULL,
853 0,
855 FILE_OPEN,
857 NULL,
858 0,
860 NULL,
863 ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
864 if (Status == STATUS_SUCCESS)
865 {
866 ObCloseHandle(ParentHandle, KernelMode);
867 }
868 ObCloseHandle(SystemRootHandle, KernelMode);
869 }
870}
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242

Referenced by START_TEST().

Variable Documentation

◆ Foobar

UNICODE_STRING Foobar = RTL_CONSTANT_STRING(L"foobar.exe")
static

Definition at line 12 of file IoCreateFile.c.

Referenced by KernelModeTest(), and TestSymlinks().

◆ FoobarFoobar

UNICODE_STRING FoobarFoobar = RTL_CONSTANT_STRING(L"foobar\\foobar.exe")
static

Definition at line 16 of file IoCreateFile.c.

Referenced by KernelModeTest().

◆ Regedit

UNICODE_STRING Regedit = RTL_CONSTANT_STRING(L"regedit.exe")
static

Definition at line 11 of file IoCreateFile.c.

Referenced by KernelModeTest(), TestSymlinks(), and UserModeTest().

◆ SystemRoot

UNICODE_STRING SystemRoot = RTL_CONSTANT_STRING(L"\\SystemRoot\\")
static

Definition at line 10 of file IoCreateFile.c.

Referenced by KernelModeTest(), TestSymlinks(), and UserModeTest().

◆ SystemRootFoobar

UNICODE_STRING SystemRootFoobar = RTL_CONSTANT_STRING(L"\\SystemRoot\\foobar.exe")
static

Definition at line 14 of file IoCreateFile.c.

Referenced by KernelModeTest(), and TestSymlinks().

◆ SystemRootFoobarFoobar

UNICODE_STRING SystemRootFoobarFoobar = RTL_CONSTANT_STRING(L"\\SystemRoot\\foobar\\foobar.exe")
static

Definition at line 15 of file IoCreateFile.c.

Referenced by KernelModeTest().

◆ SystemRootRegedit

UNICODE_STRING SystemRootRegedit = RTL_CONSTANT_STRING(L"\\SystemRoot\\regedit.exe")
static

Definition at line 13 of file IoCreateFile.c.

Referenced by KernelModeTest(), and UserModeTest().