ReactOS  0.4.14-dev-41-g31d7680
IoCreateFile.c
Go to the documentation of this file.
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\\");
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
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;
45  &SystemRoot,
47  NULL, NULL);
56  if (Status == STATUS_SUCCESS)
57  {
61  KernelMode,
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,
93  FILE_OPEN,
95  NULL,
96  0,
98  NULL,
102  if (Status == STATUS_SUCCESS)
103  {
104  Status = ObReferenceObjectByHandle(ParentHandle,
107  KernelMode,
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,
142  &IoStatusBlock,
147  if (Status == STATUS_SUCCESS)
148  {
149  IoStatusBlock.Status = 0xFFFFFFFF;
150  IoStatusBlock.Information = 0xFFFFFFFF;
152  &Regedit,
154  SystemRootHandle,
155  NULL);
156  Status = IoCreateFile(&ParentHandle,
159  &IoStatusBlock,
160  NULL,
161  0,
163  FILE_OPEN,
165  NULL,
166  0,
168  NULL,
172  if (Status == STATUS_SUCCESS)
173  {
174  Status = ObReferenceObjectByHandle(ParentHandle,
177  KernelMode,
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,
191  KernelMode,
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,
226  &IoStatusBlock,
227  NULL,
228  0,
230  FILE_OPEN,
232  NULL,
233  0,
235  NULL,
239  if (Status == STATUS_SUCCESS)
240  {
241  Status = ObReferenceObjectByHandle(ParentHandle,
244  KernelMode,
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,
271  &IoStatusBlock,
276  if (Status == STATUS_SUCCESS)
277  {
278  IoStatusBlock.Status = 0xFFFFFFFF;
279  IoStatusBlock.Information = 0xFFFFFFFF;
281  &Foobar,
283  SystemRootHandle,
284  NULL);
285  Status = IoCreateFile(&ParentHandle,
288  &IoStatusBlock,
289  NULL,
290  0,
292  FILE_OPEN,
294  NULL,
295  0,
297  NULL,
301  if (Status == STATUS_SUCCESS)
302  {
303  Status = ObReferenceObjectByHandle(ParentHandle,
306  KernelMode,
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,
320  KernelMode,
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,
354  &IoStatusBlock,
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,
382  &IoStatusBlock,
387  if (Status == STATUS_SUCCESS)
388  {
389  IoStatusBlock.Status = 0xFFFFFFFF;
390  IoStatusBlock.Information = 0xFFFFFFFF;
392  &FoobarFoobar,
394  SystemRootHandle,
395  NULL);
396  Status = IoCreateFile(&ParentHandle,
399  &IoStatusBlock,
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 }
419 
420 static
421 VOID
422 NTAPI
424 {
425  HANDLE ReparseHandle;
429  PREPARSE_DATA_BUFFER Reparse;
432  UNICODE_STRING SysDir, Foobar, Regedit;
433  ULONG Size;
434 
435  /* Get Windows/ReactOS directory */
437  &SystemRoot,
439  NULL,
440  NULL);
441  Status = ZwOpenFile(&ReparseHandle,
444  &IoStatusBlock,
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");
488  RtlCopyUnicodeString(&Foobar, &FileObject->FileName);
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,
522  &IoStatusBlock,
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,
560  &IoStatusBlock,
562  Reparse,
563  Size,
564  NULL,
565  0);
567  if (!NT_SUCCESS(Status))
568  {
569  ZwClose(ReparseHandle);
570 
571  Status = ZwCreateFile(&ReparseHandle,
574  &IoStatusBlock,
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,
587  &IoStatusBlock,
591  ZwClose(ReparseHandle);
594  ExFreePool(SysDir.Buffer);
595  ExFreePool(Reparse);
596  return;
597  }
598 
599  Status = ZwFsControlFile(ReparseHandle,
600  NULL,
601  NULL,
602  NULL,
603  &IoStatusBlock,
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,
614  &IoStatusBlock,
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,
629  GENERIC_READ,
631  &IoStatusBlock,
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  {
653  ok(RtlCompareUnicodeString(&Regedit, &FileObject->FileName, TRUE) == 0,
654  "Expected: %wZ. Opened: %wZ\n", &Regedit, &FileObject->FileName);
656  }
657 
658  ZwClose(ReparseHandle);
659  }
660 
662 
663  Status = IoCreateFile(&ReparseHandle,
664  GENERIC_READ,
666  &IoStatusBlock,
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,
688  &IoStatusBlock,
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,
701  &IoStatusBlock,
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,
733  &IoStatusBlock,
735  NULL,
736  0,
737  Reparse,
738  Size);
741  if (NT_SUCCESS(Status))
742  {
743  PWSTR Buffer;
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,
777  &IoStatusBlock,
778  &ToDelete,
779  sizeof(ToDelete),
781  ZwClose(ReparseHandle);
782 }
783 
784 //static
785 VOID
786 NTAPI
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,
806  &IoStatusBlock,
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,
834  &IoStatusBlock,
839  if (Status == STATUS_SUCCESS)
840  {
841  IoStatusBlock.Status = 0xFFFFFFFF;
842  IoStatusBlock.Information = 0xFFFFFFFF;
844  &Regedit,
846  SystemRootHandle,
847  NULL);
848  Status = IoCreateFile(&ParentHandle,
851  &IoStatusBlock,
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 }
871 
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
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IN
Definition: typedefs.h:38
#define FILE_EXISTS
Definition: nt_native.h:772
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
PKTHREAD KmtStartThread(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext OPTIONAL)
GLint x0
Definition: linetemp.h:95
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define ok_eq_pointer(value, expected)
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_IO_REPARSE_TAG_NOT_HANDLED
Definition: ntstatus.h:743
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:97
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define STATUS_STOPPED_ON_SYMLINK
Definition: ntstatus.h:212
#define FILE_SHARE_READ
Definition: compat.h:125
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define IO_STOP_ON_SYMLINK
Definition: iotypes.h:6997
static UNICODE_STRING Regedit
Definition: IoCreateFile.c:11
uint32_t ULONG_PTR
Definition: typedefs.h:63
WCHAR PathBuffer[1]
Definition: shellext.h:152
static UNICODE_STRING SystemRootFoobar
Definition: IoCreateFile.c:14
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:496
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:509
static UNICODE_STRING FoobarFoobar
Definition: IoCreateFile.c:16
#define FILE_READ_DATA
Definition: nt_native.h:628
#define GENERIC_WRITE
Definition: nt_native.h:90
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)
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
static VOID NTAPI KernelModeTest(IN PVOID Context)
Definition: IoCreateFile.c:21
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static UNICODE_STRING SystemRoot
Definition: IoCreateFile.c:10
struct _REPARSE_DATA_BUFFER::@301::@303 SymbolicLinkReparseBuffer
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
* PFILE_OBJECT
Definition: iotypes.h:1955
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_DOES_NOT_EXIST
Definition: nt_native.h:773
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)
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
USHORT ReparseDataLength
Definition: shellext.h:142
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define GENERIC_READ
Definition: compat.h:124
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define SYNCHRONIZE
Definition: nt_native.h:61
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
VOID KmtFinishThread(IN PKTHREAD Thread OPTIONAL, IN PKEVENT Event OPTIONAL)
Status
Definition: gdiplustypes.h:24
#define FILE_OPEN
Definition: from_kernel.h:54
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
static UNICODE_STRING SystemRootRegedit
Definition: IoCreateFile.c:13
#define ok(value,...)
Definition: atltest.h:57
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
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:3009
#define skip(...)
Definition: atltest.h:64
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
unsigned int ULONG
Definition: retypes.h:1
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
START_TEST(IoCreateFile)
Definition: IoCreateFile.c:872
#define ok_eq_hex(value, expected)
#define FSCTL_SET_REPARSE_POINT
Definition: winioctl.h:98
static UNICODE_STRING SystemRootFoobarFoobar
Definition: IoCreateFile.c:15
static UNICODE_STRING Foobar
Definition: IoCreateFile.c:12
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define IO_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:6996
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:429
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:6884
#define ok_eq_long(value, expected)
Definition: kmt_test.h:240
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define DELETE
Definition: nt_native.h:57
VOID NTAPI UserModeTest(VOID)
Definition: IoCreateFile.c:787
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14