ReactOS  0.4.14-dev-50-g13bb5e2
IoFilesystem.c
Go to the documentation of this file.
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 File System test
5  * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 
10 /* FIXME: Test this stuff on non-FAT volumes */
11 
12 static
16  _Out_ PVOID *Info,
19 {
22  PVOID Buffer;
23 
24  *Info = NULL;
25  if (*Length)
26  {
28  if (skip(Buffer != NULL, "Failed to allocate %Iu bytes\n", *Length))
30 
31  RtlFillMemory(Buffer, *Length, 0xdd);
32  }
33  else
34  {
35  Buffer = NULL;
36  }
37  RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
38  _SEH2_TRY
39  {
40  Status = ZwQueryInformationFile(FileHandle,
41  &IoStatus,
42  Buffer,
43  *Length,
45  }
47  {
49  ok(0, "Exception %lx querying class %d with length %Iu\n",
51  }
52  _SEH2_END;
53  if (Status == STATUS_PENDING)
54  {
55  Status = ZwWaitForSingleObject(FileHandle, FALSE, NULL);
57  Status = IoStatus.Status;
58  }
59 
60  *Length = IoStatus.Information;
61  if (NT_SUCCESS(Status))
62  {
63  *Info = Buffer;
64  }
65  else if (Buffer)
66  {
68  }
69  return Status;
70 }
71 
72 static
73 VOID
75 {
77  UNICODE_STRING FileName = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntoskrnl.exe");
78  UNICODE_STRING Ntoskrnl = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
82  PFILE_ALL_INFORMATION FileAllInfo;
83  SIZE_T Length;
84  ULONG NameLength;
85  PWCHAR Name;
86  UNICODE_STRING NamePart;
87 
89  &FileName,
91  NULL,
92  NULL);
96  &IoStatus,
99  if (Status == STATUS_PENDING)
100  {
101  Status = ZwWaitForSingleObject(FileHandle, FALSE, NULL);
103  Status = IoStatus.Status;
104  }
106  if (skip(NT_SUCCESS(Status), "No file handle, %lx\n", Status))
107  return;
108 
109  /* NtQueryInformationFile doesn't do length checks for kernel callers in a free build */
110  if (KmtIsCheckedBuild)
111  {
112  /* Zero length */
113  Length = 0;
116  ok_eq_size(Length, (ULONG_PTR)0x5555555555555555);
117  if (FileAllInfo)
118  KmtFreeGuarded(FileAllInfo);
119 
120  /* One less than the minimum */
121  Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) - 1;
124  ok_eq_size(Length, (ULONG_PTR)0x5555555555555555);
125  if (FileAllInfo)
126  KmtFreeGuarded(FileAllInfo);
127 
128  /* No space for the name -- fastfat handles this gracefully, ntfs doesn't.
129  * But the Io manager makes it fail on checked builds, so it's
130  * technically illegal
131  */
132  Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName);
135  ok_eq_size(Length, (ULONG_PTR)0x5555555555555555);
136  if (FileAllInfo)
137  KmtFreeGuarded(FileAllInfo);
138  }
139 
140  /* The minimum allowed */
141  Length = sizeof(FILE_ALL_INFORMATION);
145  if (FileAllInfo)
146  KmtFreeGuarded(FileAllInfo);
147 
148  /* Plenty of space -- determine NameLength and copy the name */
149  Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + MAX_PATH * sizeof(WCHAR);
152  if (skip(NT_SUCCESS(Status) && FileAllInfo != NULL, "No info\n"))
153  {
154  goto NoInfo;
155  }
156 
157  NameLength = FileAllInfo->NameInformation.FileNameLength;
158  ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength);
159  Name = ExAllocatePoolWithTag(PagedPool, NameLength + sizeof(UNICODE_NULL), 'sFmK');
160  if (!skip(Name != NULL, "Could not allocate %lu bytes\n", NameLength + (ULONG)sizeof(UNICODE_NULL)))
161  {
163  FileAllInfo->NameInformation.FileName,
164  NameLength);
165  Name[NameLength / sizeof(WCHAR)] = UNICODE_NULL;
166  ok(Name[0] == L'\\', "Name is %ls, expected first char to be \\\n", Name);
167  ok(NameLength >= Ntoskrnl.Length + sizeof(WCHAR), "NameLength %lu too short\n", NameLength);
168  if (NameLength >= Ntoskrnl.Length)
169  {
170  NamePart.Buffer = Name + (NameLength - Ntoskrnl.Length) / sizeof(WCHAR);
171  NamePart.Length = Ntoskrnl.Length;
172  NamePart.MaximumLength = NamePart.Length;
173  ok(RtlEqualUnicodeString(&NamePart, &Ntoskrnl, TRUE),
174  "Name ends in '%wZ', expected %wZ\n", &NamePart, &Ntoskrnl);
175  }
176  ExFreePoolWithTag(Name, 'sFmK');
177  }
178  ok(FileAllInfo->NameInformation.FileName[NameLength / sizeof(WCHAR)] == 0xdddd,
179  "Char past FileName is %x\n",
180  FileAllInfo->NameInformation.FileName[NameLength / sizeof(WCHAR)]);
181  if (FileAllInfo)
182  KmtFreeGuarded(FileAllInfo);
183 
184  /* One char less than needed */
185  Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - sizeof(WCHAR);
188  ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - sizeof(WCHAR));
189  if (FileAllInfo)
190  KmtFreeGuarded(FileAllInfo);
191 
192  /* One byte less than needed */
193  Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - 1;
196  ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - 1);
197  if (FileAllInfo)
198  KmtFreeGuarded(FileAllInfo);
199 
200  /* Exactly the required size */
201  Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength;
204  ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength);
205  if (FileAllInfo)
206  KmtFreeGuarded(FileAllInfo);
207 
208  /* One byte more than needed */
209  Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength + 1;
212  ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength);
213  if (FileAllInfo)
214  KmtFreeGuarded(FileAllInfo);
215 
216  /* One char more than needed */
217  Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength + sizeof(WCHAR);
220  ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength);
221  if (FileAllInfo)
222  KmtFreeGuarded(FileAllInfo);
223 
224 NoInfo:
227 }
228 
229 static
230 VOID
234  _In_ PCWSTR Template,
235  _In_ PCWSTR SystemDriveName,
236  _In_ PCWSTR SystemRootName)
237 {
238  UNICODE_STRING SystemDriveTemplate = RTL_CONSTANT_STRING(L"C:");
239  UNICODE_STRING SystemRootTemplate = RTL_CONSTANT_STRING(L"ReactOS");
240  ULONG SystemDriveLength;
241  ULONG SystemRootLength;
242  PWCHAR Dest = Buffer;
244 
245  SystemDriveLength = wcslen(SystemDriveName) * sizeof(WCHAR);
246  SystemRootLength = wcslen(SystemRootName) * sizeof(WCHAR);
247 
248  RtlInitUnicodeString(&String, Template);
249  ASSERT(String.Length % sizeof(WCHAR) == 0);
250  while (String.Length)
251  {
252  if (RtlPrefixUnicodeString(&SystemDriveTemplate, &String, TRUE))
253  {
254  ASSERT((Dest - Buffer) * sizeof(WCHAR) + SystemDriveLength < BufferSize);
255  RtlCopyMemory(Dest,
256  SystemDriveName,
257  SystemDriveLength);
258  Dest += SystemDriveLength / sizeof(WCHAR);
259 
260  String.Buffer += SystemDriveTemplate.Length / sizeof(WCHAR);
261  String.Length -= SystemDriveTemplate.Length;
262  String.MaximumLength -= SystemDriveTemplate.Length;
263  continue;
264  }
265 
266  if (RtlPrefixUnicodeString(&SystemRootTemplate, &String, TRUE))
267  {
268  ASSERT((Dest - Buffer) * sizeof(WCHAR) + SystemRootLength < BufferSize);
269  RtlCopyMemory(Dest,
270  SystemRootName,
271  SystemRootLength);
272  Dest += SystemRootLength / sizeof(WCHAR);
273 
274  String.Buffer += SystemRootTemplate.Length / sizeof(WCHAR);
275  String.Length -= SystemRootTemplate.Length;
276  String.MaximumLength -= SystemRootTemplate.Length;
277  continue;
278  }
279 
280  ASSERT(Dest - Buffer < BufferSize / sizeof(WCHAR));
281  *Dest++ = String.Buffer[0];
282 
283  String.Buffer++;
284  String.Length -= sizeof(WCHAR);
285  String.MaximumLength -= sizeof(WCHAR);
286  }
287  ASSERT(Dest - Buffer < BufferSize / sizeof(WCHAR));
288  *Dest = UNICODE_NULL;
289 }
290 
291 static
292 VOID
294 {
296  struct
297  {
298  PCWSTR ParentPathTemplate;
299  PCWSTR RelativePathTemplate;
302  BOOLEAN IsDrive;
303  } Tests[] =
304  {
305  { NULL, L"C:\\", TRUE, STATUS_SUCCESS, TRUE },
306  { NULL, L"C:\\\\", TRUE, STATUS_SUCCESS, TRUE },
307  { NULL, L"C:\\\\\\", TRUE, STATUS_OBJECT_NAME_INVALID, TRUE },
308  { NULL, L"C:\\ReactOS", TRUE, STATUS_SUCCESS },
309  { NULL, L"C:\\ReactOS\\", TRUE, STATUS_SUCCESS },
310  { NULL, L"C:\\ReactOS\\\\", TRUE, STATUS_SUCCESS },
311  { NULL, L"C:\\ReactOS\\\\\\", TRUE, STATUS_OBJECT_NAME_INVALID },
312  { NULL, L"C:\\\\ReactOS", TRUE, STATUS_SUCCESS },
313  { NULL, L"C:\\\\ReactOS\\", TRUE, STATUS_SUCCESS },
314  { NULL, L"C:\\ReactOS\\explorer.exe", FALSE, STATUS_SUCCESS },
315  { NULL, L"C:\\ReactOS\\\\explorer.exe", FALSE, STATUS_OBJECT_NAME_INVALID },
316  { NULL, L"C:\\ReactOS\\explorer.exe\\", FALSE, STATUS_OBJECT_NAME_INVALID },
317  { NULL, L"C:\\ReactOS\\explorer.exe\\file", FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
318  { NULL, L"C:\\ReactOS\\explorer.exe\\\\", FALSE, STATUS_OBJECT_NAME_INVALID },
319  /* This will never return STATUS_NOT_A_DIRECTORY. IsDirectory=TRUE is a little hacky but achieves that without special handling */
320  { NULL, L"C:\\ReactOS\\explorer.exe\\\\\\", TRUE, STATUS_OBJECT_NAME_INVALID },
321  { L"C:\\", L"", TRUE, STATUS_SUCCESS },
322  { L"C:\\", L"\\", TRUE, STATUS_OBJECT_NAME_INVALID },
323  { L"C:\\", L"ReactOS", TRUE, STATUS_SUCCESS },
324  { L"C:\\", L"\\ReactOS", TRUE, STATUS_OBJECT_NAME_INVALID },
325  { L"C:\\", L"ReactOS\\", TRUE, STATUS_SUCCESS },
326  { L"C:\\", L"\\ReactOS\\", TRUE, STATUS_OBJECT_NAME_INVALID },
327  { L"C:\\ReactOS", L"", TRUE, STATUS_SUCCESS },
328  { L"C:\\ReactOS", L"explorer.exe", FALSE, STATUS_SUCCESS },
329  { L"C:\\ReactOS\\explorer.exe", L"", FALSE, STATUS_SUCCESS },
330  { L"C:\\ReactOS\\explorer.exe", L"file", FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
331  /* Let's try some nonexistent things */
332  { NULL, L"C:\\ReactOS\\IDoNotExist", FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
333  { NULL, L"C:\\ReactOS\\IDoNotExist\\file", FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
334  { NULL, L"C:\\ReactOS\\IDoNotExist\\file?", FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
335  { NULL, L"C:\\ReactOS\\IDoNotExist\\file\\\\",TRUE,STATUS_OBJECT_PATH_NOT_FOUND },
336  { NULL, L"C:\\ReactOS\\IDoNotExist\\file\\\\\\",TRUE,STATUS_OBJECT_PATH_NOT_FOUND },
337  { NULL, L"C:\\ReactOS\\AmIInvalid?", FALSE, STATUS_OBJECT_NAME_INVALID },
338  { NULL, L"C:\\ReactOS\\.", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
339  { NULL, L"C:\\ReactOS\\..", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
340  { NULL, L"C:\\ReactOS\\...", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
341  { NULL, L"C:\\ReactOS\\.\\system32", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
342  { NULL, L"C:\\ReactOS\\..\\ReactOS", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
343  { L"C:\\", L".", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
344  { L"C:\\", L"..", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
345  { L"C:\\", L"...", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
346  { L"C:\\", L".\\ReactOS", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
347  { L"C:\\", L"..\\ReactOS", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
348  { L"C:\\ReactOS", L".", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
349  { L"C:\\ReactOS", L"..", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
350  { L"C:\\ReactOS", L"...", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
351  { L"C:\\ReactOS", L".\\system32", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
352  { L"C:\\ReactOS", L"..\\ReactOS", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
353  /* Volume open */
354  { NULL, L"C:", FALSE, STATUS_SUCCESS, TRUE },
355  { L"C:", L"", FALSE, STATUS_SUCCESS, TRUE },
356  { L"C:", L"\\", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
357  { L"C:", L"file", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
358  };
359  ULONG i;
362  UNICODE_STRING ParentPath;
363  UNICODE_STRING RelativePath;
364  HANDLE ParentHandle;
367  HANDLE SymbolicLinkHandle = NULL;
368  WCHAR LinkNameBuffer[128];
369  UNICODE_STRING SymbolicLinkName;
370  PWSTR SystemDriveName;
371  PWSTR SystemRootName;
372  PWCHAR Buffer = NULL;
373  BOOLEAN TrailingBackslash;
375  FILE_DISPOSITION_INFORMATION DispositionInfo;
376 
377  /* Query \SystemRoot */
379  &SystemRoot,
381  NULL,
382  NULL);
383  Status = ZwOpenSymbolicLinkObject(&SymbolicLinkHandle,
384  GENERIC_READ,
386  if (skip(NT_SUCCESS(Status), "Failed to open SystemRoot, %lx\n", Status))
387  return;
388 
389  RtlInitEmptyUnicodeString(&SymbolicLinkName,
390  LinkNameBuffer,
391  sizeof(LinkNameBuffer));
392  Status = ZwQuerySymbolicLinkObject(SymbolicLinkHandle,
393  &SymbolicLinkName,
394  NULL);
395  ObCloseHandle(SymbolicLinkHandle, KernelMode);
396  if (skip(NT_SUCCESS(Status), "Failed to query SystemRoot, %lx\n", Status))
397  return;
398 
399  /* Split SymbolicLinkName into drive and path */
400  SystemDriveName = SymbolicLinkName.Buffer;
401  SystemRootName = SymbolicLinkName.Buffer + SymbolicLinkName.Length / sizeof(WCHAR);
402  *SystemRootName-- = UNICODE_NULL;
403  while (*SystemRootName != L'\\')
404  {
405  ASSERT(SystemRootName > SymbolicLinkName.Buffer);
406  SystemRootName--;
407  }
408  *SystemRootName++ = UNICODE_NULL;
409  trace("System Drive: '%ls'\n", SystemDriveName);
410  trace("System Root: '%ls'\n", SystemRootName);
411 
412  /* Allocate path buffer */
414  if (skip(Buffer != NULL, "No buffer\n"))
415  return;
416 
417  /* Finally run some tests! */
418  for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
419  {
420  /* Open parent directory first */
421  ParentHandle = NULL;
422  if (Tests[i].ParentPathTemplate)
423  {
425  MAXUSHORT,
426  Tests[i].ParentPathTemplate,
427  SystemDriveName,
428  SystemRootName);
429  RtlInitUnicodeString(&ParentPath, Buffer);
431  &ParentPath,
433  NULL,
434  NULL);
435  Status = ZwOpenFile(&ParentHandle,
436  GENERIC_READ,
438  &IoStatus,
440  0);
442  "[%lu] Status = %lx, expected STATUS_SUCCESS\n", i, Status);
443  if (skip(NT_SUCCESS(Status), "No parent handle %lu\n", i))
444  continue;
445  }
446 
447  /* Now open the relative file: */
449  MAXUSHORT,
450  Tests[i].RelativePathTemplate,
451  SystemDriveName,
452  SystemRootName);
453  RtlInitUnicodeString(&RelativePath, Buffer);
455  &RelativePath,
457  ParentHandle,
458  NULL);
459  TrailingBackslash = FALSE;
460  if (wcslen(Buffer) && Buffer[wcslen(Buffer) - 1] == L'\\')
461  TrailingBackslash = TRUE;
462 
463  /* (1) No flags */
465  GENERIC_READ,
467  &IoStatus,
469  0);
470  ok(Status == Tests[i].Status,
471  "[%lu] Status = %lx, expected %lx\n", i, Status, Tests[i].Status);
472  if (NT_SUCCESS(Status))
474 
475  /* (2) Directory File */
477  GENERIC_READ,
479  &IoStatus,
482  if (Tests[i].IsDirectory || (!TrailingBackslash && !NT_SUCCESS(Tests[i].Status)))
483  ok(Status == Tests[i].Status,
484  "[%lu] Status = %lx, expected %lx\n", i, Status, Tests[i].Status);
485  else
487  "[%lu] Status = %lx, expected STATUS_NOT_A_DIRECTORY\n", i, Status);
488  if (NT_SUCCESS(Status))
490 
491  /* (3) Non-Directory File */
493  GENERIC_READ,
495  &IoStatus,
500  "[%lu] Status = %lx, expected STATUS_FILE_IS_A_DIRECTORY\n", i, Status);
501  else
502  ok(Status == Tests[i].Status,
503  "[%lu] Status = %lx, expected %lx\n", i, Status, Tests[i].Status);
504  if (NT_SUCCESS(Status))
506 
507  /* (4) Directory + Non-Directory */
509  GENERIC_READ,
511  &IoStatus,
514  if (Tests[i].Status == STATUS_OBJECT_NAME_INVALID && Tests[i].IsDrive)
516  "[%lu] Status = %lx, expected STATUS_OBJECT_NAME_INVALID\n", i, Status);
517  else
519  "[%lu] Status = %lx, expected STATUS_INVALID_PARAMETER\n", i, Status);
520  if (NT_SUCCESS(Status))
522 
523  /* (5) Try to create it */
524  AllocationSize.QuadPart = 0;
525  Status = ZwCreateFile(&FileHandle,
528  &IoStatus,
532  FILE_CREATE,
533  0,
534  NULL,
535  0);
538  "[%lu] Status = %lx, expected STATUS_SUCCESS\n", i, Status);
539  else if (Tests[i].Status == STATUS_OBJECT_NAME_INVALID && Tests[i].IsDrive)
541  "[%lu] Status = %lx, expected STATUS_OBJECT_NAME_INVALID\n", i, Status);
542  else if (Tests[i].IsDrive)
544  "[%lu] Status = %lx, expected STATUS_ACCESS_DENIED\n", i, Status);
545  else if (Tests[i].Status == STATUS_SUCCESS)
547  "[%lu] Status = %lx, expected STATUS_OBJECT_NAME_COLLISION\n", i, Status);
548  else
549  ok(Status == Tests[i].Status,
550  "[%lu] Status = %lx, expected %lx; %ls -- %ls\n", i, Status, Tests[i].Status, Tests[i].ParentPathTemplate, Tests[i].RelativePathTemplate);
551  if (NT_SUCCESS(Status))
552  {
553  if (IoStatus.Information == FILE_CREATED)
554  {
555  DispositionInfo.DeleteFile = TRUE;
556  Status = ZwSetInformationFile(FileHandle,
557  &IoStatus,
558  &DispositionInfo,
559  sizeof(DispositionInfo),
562  "[%lu] Status = %lx, expected STATUS_SUCCESS\n", i, Status);
563  }
565  }
566 
567  /* And close */
568  ObCloseHandle(ParentHandle, KernelMode);
569  }
570 
571  ExFreePoolWithTag(Buffer, 'sFmK');
572 }
573 
574 static
575 VOID
577 {
579  struct
580  {
581  PCWSTR ParentPath;
582  PCWSTR RelativePath;
583  } Tests[] =
584  {
585  { 0, L"\\SystemRoot\\system32\\drivers\\etc\\hosts" },
586  { L"\\SystemRoot", L"system32\\drivers\\etc\\hosts" },
587  { L"\\SystemRoot\\system32", L"drivers\\etc\\hosts" },
588  { L"\\SystemRoot\\system32\\drivers", L"etc\\hosts" },
589  { L"\\SystemRoot\\system32\\drivers\\etc", L"hosts" },
590  };
593  UNICODE_STRING ParentPath;
594  UNICODE_STRING RelativePath;
595  HANDLE ParentHandle[RTL_NUMBER_OF(Tests)] = { NULL };
598  PFILE_OBJECT SystemRootObject = NULL;
599  UCHAR Buffer[32];
602  ULONG i;
603 
604  /* We need an event for ZwReadFile */
606  NULL,
608  NULL,
609  NULL);
610  Status = ZwCreateEvent(&EventHandle,
611  SYNCHRONIZE,
614  FALSE);
615  if (skip(NT_SUCCESS(Status), "No event\n"))
616  goto Cleanup;
617 
618  /* Open all test files and get their FILE_OBJECT pointers */
619  for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
620  {
621  if (Tests[i].ParentPath)
622  {
623  RtlInitUnicodeString(&ParentPath, Tests[i].ParentPath);
625  &ParentPath,
627  NULL,
628  NULL);
629  Status = ZwOpenFile(&ParentHandle[i],
630  GENERIC_READ,
632  &IoStatus,
634  0);
636  if (skip(NT_SUCCESS(Status), "No parent handle %lu\n", i))
637  goto Cleanup;
638  }
639 
640  RtlInitUnicodeString(&RelativePath, Tests[i].RelativePath);
642  &RelativePath,
644  ParentHandle[i],
645  NULL);
649  &IoStatus,
651  0);
653  if (skip(NT_SUCCESS(Status), "No file handle %lu\n", i))
654  goto Cleanup;
655 
659  KernelMode,
660  (PVOID*)&FileObject[i],
661  NULL);
663  if (skip(NT_SUCCESS(Status), "No file object %lu\n", i))
664  goto Cleanup;
665  }
666 
667  /* Also get a file object for the SystemRoot directory */
668  Status = ObReferenceObjectByHandle(ParentHandle[1],
669  GENERIC_READ,
671  KernelMode,
672  (PVOID*)&SystemRootObject,
673  NULL);
675  if (skip(NT_SUCCESS(Status), "No SystemRoot object\n"))
676  goto Cleanup;
677 
678  /* Before read, caching is not initialized */
679  ok_eq_pointer(SystemRootObject->SectionObjectPointer, NULL);
680  for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
681  {
682  ok(FileObject[i]->SectionObjectPointer != NULL, "FileObject[%lu]->SectionObjectPointer = NULL\n", i);
684  "FileObject[%lu]->SectionObjectPointer = %p, expected %p\n",
686  }
687  if (!skip(FileObject[0]->SectionObjectPointer != NULL, "No section object pointers\n"))
688  ok_eq_pointer(FileObject[0]->SectionObjectPointer->SharedCacheMap, NULL);
689 
690  /* Perform a read on one handle to initialize caching */
691  FileOffset.QuadPart = 0;
692  Status = ZwReadFile(FileHandle[0],
693  EventHandle,
694  NULL,
695  NULL,
696  &IoStatus,
697  Buffer,
698  sizeof(Buffer),
699  &FileOffset,
700  NULL);
701  if (Status == STATUS_PENDING)
702  {
703  Status = ZwWaitForSingleObject(EventHandle, FALSE, NULL);
705  Status = IoStatus.Status;
706  }
708 
709  /* Now we see a SharedCacheMap for the file */
710  ok_eq_pointer(SystemRootObject->SectionObjectPointer, NULL);
711  for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
712  {
713  ok(FileObject[i]->SectionObjectPointer != NULL, "FileObject[%lu]->SectionObjectPointer = NULL\n", i);
715  "FileObject[%lu]->SectionObjectPointer = %p, expected %p\n",
717  }
718  if (!skip(FileObject[0]->SectionObjectPointer != NULL, "No section object pointers\n"))
719  ok(FileObject[0]->SectionObjectPointer->SharedCacheMap != NULL, "SharedCacheMap is NULL\n");
720 
721 Cleanup:
722  if (SystemRootObject)
723  ObDereferenceObject(SystemRootObject);
724  if (EventHandle)
726  for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
727  {
728  if (FileObject[i])
730  if (FileHandle[i])
732  if (ParentHandle[i])
733  ObCloseHandle(ParentHandle[i], KernelMode);
734  }
735 }
736 
737 START_TEST(IoFilesystem)
738 {
742 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
BOOLEAN BOOLEAN VOID VOID BOOLEAN BOOLEAN PVOID KmtAllocateGuarded(SIZE_T SizeRequested)
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
USHORT MaximumLength
Definition: env_spec_w32.h:370
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
#define ok_eq_size(value, expected)
Definition: kmt_test.h:247
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _FILE_ALL_INFORMATION FILE_ALL_INFORMATION
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 FILE_CREATE
Definition: from_kernel.h:55
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
static WCHAR String[]
Definition: stringtable.c:55
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:75
uint16_t * PWCHAR
Definition: typedefs.h:54
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
struct TraceInfo Info
#define FILE_SHARE_READ
Definition: compat.h:125
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1368
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOLEAN KmtIsCheckedBuild
static NTSTATUS QueryFileInfo(_In_ HANDLE FileHandle, _Out_ PVOID *Info, _Inout_ PSIZE_T Length, _In_ FILE_INFORMATION_CLASS FileInformationClass)
Definition: IoFilesystem.c:14
HANDLE FileHandle
Definition: stats.c:38
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
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
ULONG_PTR * PSIZE_T
Definition: typedefs.h:78
#define UNICODE_NULL
struct NameRec_ * Name
Definition: cdprocs.h:464
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _Out_writes_bytes_(size)
Definition: no_sal2.h:370
#define _Out_
Definition: no_sal2.h:323
Definition: bufpool.h:45
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
#define trace
Definition: atltest.h:70
static const WCHAR SystemRoot[]
Definition: reg.c:38
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define MAX_PATH
Definition: compat.h:26
#define BufferSize
Definition: classpnp.h:419
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define _Inout_
Definition: no_sal2.h:244
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1955
static VOID TestRelativeNames(VOID)
Definition: IoFilesystem.c:293
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
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)
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
_Must_inspect_result_ _In_ PFLT_INSTANCE _Out_ PBOOLEAN IsDirectory
Definition: fltkernel.h:1139
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define GENERIC_READ
Definition: compat.h:124
static const WCHAR Cleanup[]
Definition: register.c:80
#define SYNCHRONIZE
Definition: nt_native.h:61
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:310
ULONG_PTR SIZE_T
Definition: typedefs.h:78
_SEH2_END
Definition: create.c:4424
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define ok(value,...)
Definition: atltest.h:57
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
static VOID TestSharedCacheMap(VOID)
Definition: IoFilesystem.c:576
#define FILE_CREATED
Definition: nt_native.h:770
#define MAXUSHORT
Definition: typedefs.h:81
#define skip(...)
Definition: atltest.h:64
START_TEST(IoFilesystem)
Definition: IoFilesystem.c:737
unsigned int ULONG
Definition: retypes.h:1
VOID KmtFreeGuarded(PVOID Pointer)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ok_eq_hex(value, expected)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
struct test_data Tests[]
static VOID TestAllInformation(VOID)
Definition: IoFilesystem.c:74
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define DELETE
Definition: nt_native.h:57
static VOID Substitute(_Out_writes_bytes_(BufferSize) PWCHAR Buffer, _In_ ULONG BufferSize, _In_ PCWSTR Template, _In_ PCWSTR SystemDriveName, _In_ PCWSTR SystemRootName)
Definition: IoFilesystem.c:231
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:855