ReactOS 0.4.15-dev-8231-g29a56f3
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
12static
19{
23
24 *Info = NULL;
25 if (*Length)
26 {
28 if (skip(Buffer != NULL, "Failed to allocate %Iu bytes\n", *Length))
30
32 }
33 else
34 {
35 Buffer = NULL;
36 }
37 RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
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 }
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
72static
73VOID
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;
84 ULONG NameLength;
86 UNICODE_STRING NamePart;
87
89 &FileName,
91 NULL,
92 NULL);
96 &IoStatus,
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 */
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 */
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
225 Length = sizeof(*FileEofInfo);
227 // Checked build: STATUS_INVALID_INFO_CLASS, Free build: STATUS_INVALID_PARAMETER
228 ok(Status == STATUS_INVALID_PARAMETER || Status == STATUS_INVALID_INFO_CLASS, "Wrong Status = %lx\n", Status);
229 ok_eq_size(Length, (SIZE_T)0x5555555555555555ULL);
230 if (FileEofInfo)
231 KmtFreeGuarded(FileEofInfo);
232
233NoInfo:
236}
237
238static
239VOID
243 _In_ PCWSTR Template,
244 _In_ PCWSTR SystemDriveName,
245 _In_ PCWSTR SystemRootName)
246{
247 UNICODE_STRING SystemDriveTemplate = RTL_CONSTANT_STRING(L"C:");
248 UNICODE_STRING SystemRootTemplate = RTL_CONSTANT_STRING(L"ReactOS");
249 ULONG SystemDriveLength;
250 ULONG SystemRootLength;
251 PWCHAR Dest = Buffer;
253
254 SystemDriveLength = (ULONG)wcslen(SystemDriveName) * sizeof(WCHAR);
255 SystemRootLength = (ULONG)wcslen(SystemRootName) * sizeof(WCHAR);
256
257 RtlInitUnicodeString(&String, Template);
258 ASSERT(String.Length % sizeof(WCHAR) == 0);
259 while (String.Length)
260 {
261 if (RtlPrefixUnicodeString(&SystemDriveTemplate, &String, TRUE))
262 {
263 ASSERT((Dest - Buffer) * sizeof(WCHAR) + SystemDriveLength < BufferSize);
264 RtlCopyMemory(Dest,
265 SystemDriveName,
266 SystemDriveLength);
267 Dest += SystemDriveLength / sizeof(WCHAR);
268
269 String.Buffer += SystemDriveTemplate.Length / sizeof(WCHAR);
270 String.Length -= SystemDriveTemplate.Length;
271 String.MaximumLength -= SystemDriveTemplate.Length;
272 continue;
273 }
274
275 if (RtlPrefixUnicodeString(&SystemRootTemplate, &String, TRUE))
276 {
277 ASSERT((Dest - Buffer) * sizeof(WCHAR) + SystemRootLength < BufferSize);
278 RtlCopyMemory(Dest,
279 SystemRootName,
280 SystemRootLength);
281 Dest += SystemRootLength / sizeof(WCHAR);
282
283 String.Buffer += SystemRootTemplate.Length / sizeof(WCHAR);
284 String.Length -= SystemRootTemplate.Length;
285 String.MaximumLength -= SystemRootTemplate.Length;
286 continue;
287 }
288
289 ASSERT(Dest - Buffer < BufferSize / sizeof(WCHAR));
290 *Dest++ = String.Buffer[0];
291
292 String.Buffer++;
293 String.Length -= sizeof(WCHAR);
294 String.MaximumLength -= sizeof(WCHAR);
295 }
296 ASSERT(Dest - Buffer < BufferSize / sizeof(WCHAR));
297 *Dest = UNICODE_NULL;
298}
299
300static
301VOID
303{
305 struct
306 {
307 PCWSTR ParentPathTemplate;
308 PCWSTR RelativePathTemplate;
311 BOOLEAN IsDrive;
312 } Tests[] =
313 {
314 { NULL, L"C:\\", TRUE, STATUS_SUCCESS, TRUE },
315 { NULL, L"C:\\\\", TRUE, STATUS_SUCCESS, TRUE },
316 { NULL, L"C:\\\\\\", TRUE, STATUS_OBJECT_NAME_INVALID, TRUE },
317 { NULL, L"C:\\ReactOS", TRUE, STATUS_SUCCESS },
318 { NULL, L"C:\\ReactOS\\", TRUE, STATUS_SUCCESS },
319 { NULL, L"C:\\ReactOS\\\\", TRUE, STATUS_SUCCESS },
320 { NULL, L"C:\\ReactOS\\\\\\", TRUE, STATUS_OBJECT_NAME_INVALID },
321 { NULL, L"C:\\\\ReactOS", TRUE, STATUS_SUCCESS },
322 { NULL, L"C:\\\\ReactOS\\", TRUE, STATUS_SUCCESS },
323 { NULL, L"C:\\ReactOS\\explorer.exe", FALSE, STATUS_SUCCESS },
324 { NULL, L"C:\\ReactOS\\\\explorer.exe", FALSE, STATUS_OBJECT_NAME_INVALID },
325 { NULL, L"C:\\ReactOS\\explorer.exe\\", FALSE, STATUS_OBJECT_NAME_INVALID },
326 { NULL, L"C:\\ReactOS\\explorer.exe\\file", FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
327 { NULL, L"C:\\ReactOS\\explorer.exe\\\\", FALSE, STATUS_OBJECT_NAME_INVALID },
328 /* This will never return STATUS_NOT_A_DIRECTORY. IsDirectory=TRUE is a little hacky but achieves that without special handling */
329 { NULL, L"C:\\ReactOS\\explorer.exe\\\\\\", TRUE, STATUS_OBJECT_NAME_INVALID },
330 { L"C:\\", L"", TRUE, STATUS_SUCCESS },
331 { L"C:\\", L"\\", TRUE, STATUS_OBJECT_NAME_INVALID },
332 { L"C:\\", L"ReactOS", TRUE, STATUS_SUCCESS },
333 { L"C:\\", L"\\ReactOS", TRUE, STATUS_OBJECT_NAME_INVALID },
334 { L"C:\\", L"ReactOS\\", TRUE, STATUS_SUCCESS },
335 { L"C:\\", L"\\ReactOS\\", TRUE, STATUS_OBJECT_NAME_INVALID },
336 { L"C:\\ReactOS", L"", TRUE, STATUS_SUCCESS },
337 { L"C:\\ReactOS", L"explorer.exe", FALSE, STATUS_SUCCESS },
338 { L"C:\\ReactOS\\explorer.exe", L"", FALSE, STATUS_SUCCESS },
339 { L"C:\\ReactOS\\explorer.exe", L"file", FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
340 /* Let's try some nonexistent things */
341 { NULL, L"C:\\ReactOS\\IDoNotExist", FALSE, STATUS_OBJECT_NAME_NOT_FOUND },
342 { NULL, L"C:\\ReactOS\\IDoNotExist\\file", FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
343 { NULL, L"C:\\ReactOS\\IDoNotExist\\file?", FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
344 { NULL, L"C:\\ReactOS\\IDoNotExist\\file\\\\",TRUE,STATUS_OBJECT_PATH_NOT_FOUND },
345 { NULL, L"C:\\ReactOS\\IDoNotExist\\file\\\\\\",TRUE,STATUS_OBJECT_PATH_NOT_FOUND },
346 { NULL, L"C:\\ReactOS\\AmIInvalid?", FALSE, STATUS_OBJECT_NAME_INVALID },
347 { NULL, L"C:\\ReactOS\\.", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
348 { NULL, L"C:\\ReactOS\\..", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
349 { NULL, L"C:\\ReactOS\\...", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
350 { NULL, L"C:\\ReactOS\\.\\system32", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
351 { NULL, L"C:\\ReactOS\\..\\ReactOS", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
352 { L"C:\\", L".", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
353 { L"C:\\", L"..", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
354 { L"C:\\", L"...", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
355 { L"C:\\", L".\\ReactOS", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
356 { L"C:\\", L"..\\ReactOS", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
357 { L"C:\\ReactOS", L".", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
358 { L"C:\\ReactOS", L"..", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
359 { L"C:\\ReactOS", L"...", TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
360 { L"C:\\ReactOS", L".\\system32", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
361 { L"C:\\ReactOS", L"..\\ReactOS", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
362 /* Volume open */
363 { NULL, L"C:", FALSE, STATUS_SUCCESS, TRUE },
364 { L"C:", L"", FALSE, STATUS_SUCCESS, TRUE },
365 { L"C:", L"\\", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
366 { L"C:", L"file", TRUE, STATUS_OBJECT_PATH_NOT_FOUND },
367 };
368 ULONG i;
371 UNICODE_STRING ParentPath;
372 UNICODE_STRING RelativePath;
373 HANDLE ParentHandle;
376 HANDLE SymbolicLinkHandle = NULL;
377 WCHAR LinkNameBuffer[128];
379 PWSTR SystemDriveName;
380 PWSTR SystemRootName;
382 BOOLEAN TrailingBackslash;
384 FILE_DISPOSITION_INFORMATION DispositionInfo;
385
386 /* Query \SystemRoot */
388 &SystemRoot,
390 NULL,
391 NULL);
392 Status = ZwOpenSymbolicLinkObject(&SymbolicLinkHandle,
395 if (skip(NT_SUCCESS(Status), "Failed to open SystemRoot, %lx\n", Status))
396 return;
397
398 RtlInitEmptyUnicodeString(&SymbolicLinkName,
399 LinkNameBuffer,
400 sizeof(LinkNameBuffer));
401 Status = ZwQuerySymbolicLinkObject(SymbolicLinkHandle,
403 NULL);
404 ObCloseHandle(SymbolicLinkHandle, KernelMode);
405 if (skip(NT_SUCCESS(Status), "Failed to query SystemRoot, %lx\n", Status))
406 return;
407
408 /* Split SymbolicLinkName into drive and path */
409 SystemDriveName = SymbolicLinkName.Buffer;
410 SystemRootName = SymbolicLinkName.Buffer + SymbolicLinkName.Length / sizeof(WCHAR);
411 *SystemRootName-- = UNICODE_NULL;
412 while (*SystemRootName != L'\\')
413 {
414 ASSERT(SystemRootName > SymbolicLinkName.Buffer);
415 SystemRootName--;
416 }
417 *SystemRootName++ = UNICODE_NULL;
418 trace("System Drive: '%ls'\n", SystemDriveName);
419 trace("System Root: '%ls'\n", SystemRootName);
420
421 /* Allocate path buffer */
423 if (skip(Buffer != NULL, "No buffer\n"))
424 return;
425
426 /* Finally run some tests! */
427 for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
428 {
429 /* Open parent directory first */
430 ParentHandle = NULL;
431 if (Tests[i].ParentPathTemplate)
432 {
434 MAXUSHORT,
435 Tests[i].ParentPathTemplate,
436 SystemDriveName,
437 SystemRootName);
438 RtlInitUnicodeString(&ParentPath, Buffer);
440 &ParentPath,
442 NULL,
443 NULL);
444 Status = ZwOpenFile(&ParentHandle,
447 &IoStatus,
449 0);
451 "[%lu] Status = %lx, expected STATUS_SUCCESS\n", i, Status);
452 if (skip(NT_SUCCESS(Status), "No parent handle %lu\n", i))
453 continue;
454 }
455
456 /* Now open the relative file: */
458 MAXUSHORT,
459 Tests[i].RelativePathTemplate,
460 SystemDriveName,
461 SystemRootName);
462 RtlInitUnicodeString(&RelativePath, Buffer);
464 &RelativePath,
466 ParentHandle,
467 NULL);
468 TrailingBackslash = FALSE;
469 if (wcslen(Buffer) && Buffer[wcslen(Buffer) - 1] == L'\\')
470 TrailingBackslash = TRUE;
471
472 /* (1) No flags */
476 &IoStatus,
478 0);
479 ok(Status == Tests[i].Status,
480 "[%lu] Status = %lx, expected %lx\n", i, Status, Tests[i].Status);
481 if (NT_SUCCESS(Status))
483
484 /* (2) Directory File */
488 &IoStatus,
491 if (Tests[i].IsDirectory || (!TrailingBackslash && !NT_SUCCESS(Tests[i].Status)))
492 ok(Status == Tests[i].Status,
493 "[%lu] Status = %lx, expected %lx\n", i, Status, Tests[i].Status);
494 else
496 "[%lu] Status = %lx, expected STATUS_NOT_A_DIRECTORY\n", i, Status);
497 if (NT_SUCCESS(Status))
499
500 /* (3) Non-Directory File */
504 &IoStatus,
509 "[%lu] Status = %lx, expected STATUS_FILE_IS_A_DIRECTORY\n", i, Status);
510 else
511 ok(Status == Tests[i].Status,
512 "[%lu] Status = %lx, expected %lx\n", i, Status, Tests[i].Status);
513 if (NT_SUCCESS(Status))
515
516 /* (4) Directory + Non-Directory */
520 &IoStatus,
523 if (Tests[i].Status == STATUS_OBJECT_NAME_INVALID && Tests[i].IsDrive)
525 "[%lu] Status = %lx, expected STATUS_OBJECT_NAME_INVALID\n", i, Status);
526 else
528 "[%lu] Status = %lx, expected STATUS_INVALID_PARAMETER\n", i, Status);
529 if (NT_SUCCESS(Status))
531
532 /* (5) Try to create it */
533 AllocationSize.QuadPart = 0;
534 Status = ZwCreateFile(&FileHandle,
537 &IoStatus,
542 0,
543 NULL,
544 0);
547 "[%lu] Status = %lx, expected STATUS_SUCCESS\n", i, Status);
548 else if (Tests[i].Status == STATUS_OBJECT_NAME_INVALID && Tests[i].IsDrive)
550 "[%lu] Status = %lx, expected STATUS_OBJECT_NAME_INVALID\n", i, Status);
551 else if (Tests[i].IsDrive)
553 "[%lu] Status = %lx, expected STATUS_ACCESS_DENIED\n", i, Status);
554 else if (Tests[i].Status == STATUS_SUCCESS)
556 "[%lu] Status = %lx, expected STATUS_OBJECT_NAME_COLLISION\n", i, Status);
557 else
558 ok(Status == Tests[i].Status,
559 "[%lu] Status = %lx, expected %lx; %ls -- %ls\n", i, Status, Tests[i].Status, Tests[i].ParentPathTemplate, Tests[i].RelativePathTemplate);
560 if (NT_SUCCESS(Status))
561 {
562 if (IoStatus.Information == FILE_CREATED)
563 {
564 DispositionInfo.DeleteFile = TRUE;
565 Status = ZwSetInformationFile(FileHandle,
566 &IoStatus,
567 &DispositionInfo,
568 sizeof(DispositionInfo),
571 "[%lu] Status = %lx, expected STATUS_SUCCESS\n", i, Status);
572 }
574 }
575
576 /* And close */
577 ObCloseHandle(ParentHandle, KernelMode);
578 }
579
580 ExFreePoolWithTag(Buffer, 'sFmK');
581}
582
583static
584VOID
586{
588 struct
589 {
590 PCWSTR ParentPath;
591 PCWSTR RelativePath;
592 } Tests[] =
593 {
594 { 0, L"\\SystemRoot\\system32\\drivers\\etc\\hosts" },
595 { L"\\SystemRoot", L"system32\\drivers\\etc\\hosts" },
596 { L"\\SystemRoot\\system32", L"drivers\\etc\\hosts" },
597 { L"\\SystemRoot\\system32\\drivers", L"etc\\hosts" },
598 { L"\\SystemRoot\\system32\\drivers\\etc", L"hosts" },
599 };
602 UNICODE_STRING ParentPath;
603 UNICODE_STRING RelativePath;
604 HANDLE ParentHandle[RTL_NUMBER_OF(Tests)] = { NULL };
607 PFILE_OBJECT SystemRootObject = NULL;
608 UCHAR Buffer[32];
611 ULONG i;
612
613 /* We need an event for ZwReadFile */
615 NULL,
617 NULL,
618 NULL);
619 Status = ZwCreateEvent(&EventHandle,
623 FALSE);
624 if (skip(NT_SUCCESS(Status), "No event\n"))
625 goto Cleanup;
626
627 /* Open all test files and get their FILE_OBJECT pointers */
628 for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
629 {
630 if (Tests[i].ParentPath)
631 {
632 RtlInitUnicodeString(&ParentPath, Tests[i].ParentPath);
634 &ParentPath,
636 NULL,
637 NULL);
638 Status = ZwOpenFile(&ParentHandle[i],
641 &IoStatus,
643 0);
645 if (skip(NT_SUCCESS(Status), "No parent handle %lu\n", i))
646 goto Cleanup;
647 }
648
649 RtlInitUnicodeString(&RelativePath, Tests[i].RelativePath);
651 &RelativePath,
653 ParentHandle[i],
654 NULL);
658 &IoStatus,
660 0);
662 if (skip(NT_SUCCESS(Status), "No file handle %lu\n", i))
663 goto Cleanup;
664
669 (PVOID*)&FileObject[i],
670 NULL);
672 if (skip(NT_SUCCESS(Status), "No file object %lu\n", i))
673 goto Cleanup;
674 }
675
676 /* Also get a file object for the SystemRoot directory */
677 Status = ObReferenceObjectByHandle(ParentHandle[1],
681 (PVOID*)&SystemRootObject,
682 NULL);
684 if (skip(NT_SUCCESS(Status), "No SystemRoot object\n"))
685 goto Cleanup;
686
687 /* Before read, caching is not initialized */
688 ok_eq_pointer(SystemRootObject->SectionObjectPointer, NULL);
689 for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
690 {
691 ok(FileObject[i]->SectionObjectPointer != NULL, "FileObject[%lu]->SectionObjectPointer = NULL\n", i);
693 "FileObject[%lu]->SectionObjectPointer = %p, expected %p\n",
695 }
696 if (!skip(FileObject[0]->SectionObjectPointer != NULL, "No section object pointers\n"))
698
699 /* Perform a read on one handle to initialize caching */
700 FileOffset.QuadPart = 0;
701 Status = ZwReadFile(FileHandle[0],
703 NULL,
704 NULL,
705 &IoStatus,
706 Buffer,
707 sizeof(Buffer),
708 &FileOffset,
709 NULL);
710 if (Status == STATUS_PENDING)
711 {
712 Status = ZwWaitForSingleObject(EventHandle, FALSE, NULL);
714 Status = IoStatus.Status;
715 }
717
718 /* Now we see a SharedCacheMap for the file */
719 ok_eq_pointer(SystemRootObject->SectionObjectPointer, NULL);
720 for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
721 {
722 ok(FileObject[i]->SectionObjectPointer != NULL, "FileObject[%lu]->SectionObjectPointer = NULL\n", i);
724 "FileObject[%lu]->SectionObjectPointer = %p, expected %p\n",
726 }
727 if (!skip(FileObject[0]->SectionObjectPointer != NULL, "No section object pointers\n"))
728 ok(FileObject[0]->SectionObjectPointer->SharedCacheMap != NULL, "SharedCacheMap is NULL\n");
729
730Cleanup:
731 if (SystemRootObject)
732 ObDereferenceObject(SystemRootObject);
733 if (EventHandle)
735 for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
736 {
737 if (FileObject[i])
739 if (FileHandle[i])
741 if (ParentHandle[i])
742 ObCloseHandle(ParentHandle[i], KernelMode);
743 }
744}
745
746START_TEST(IoFilesystem)
747{
751}
static NTSTATUS QueryFileInfo(_In_ HANDLE FileHandle, _Out_ PVOID *Info, _Inout_ PSIZE_T Length, _In_ FILE_INFORMATION_CLASS FileInformationClass)
Definition: IoFilesystem.c:14
static VOID Substitute(_Out_writes_bytes_(BufferSize) PWCHAR Buffer, _In_ ULONG BufferSize, _In_ PCWSTR Template, _In_ PCWSTR SystemDriveName, _In_ PCWSTR SystemRootName)
Definition: IoFilesystem.c:240
static VOID TestAllInformation(VOID)
Definition: IoFilesystem.c:74
static VOID TestRelativeNames(VOID)
Definition: IoFilesystem.c:302
static VOID TestSharedCacheMap(VOID)
Definition: IoFilesystem.c:585
unsigned char BOOLEAN
struct test_data Tests[]
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
struct NameRec_ * Name
Definition: cdprocs.h:460
#define ok_eq_pointer(value, expected)
Definition: apitest.h:59
#define ok_eq_hex(value, expected)
Definition: apitest.h:77
#define ok_eq_size(value, expected)
Definition: apitest.h:69
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR SystemRoot[]
Definition: reg.c:38
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
static const WCHAR Cleanup[]
Definition: register.c:80
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define IsDirectory(Fcb)
Definition: ext2fs.h:283
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:322
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileAllInformation
Definition: from_kernel.h:79
@ FileDispositionInformation
Definition: from_kernel.h:74
#define FILE_CREATE
Definition: from_kernel.h:55
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
Definition: fsrtlfuncs.h:1369
Status
Definition: gdiplustypes.h:25
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 EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
struct _FILE_ALL_INFORMATION FILE_ALL_INFORMATION
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
VOID KmtFreeGuarded(PVOID Pointer)
BOOLEAN BOOLEAN VOID VOID BOOLEAN BOOLEAN PVOID KmtAllocateGuarded(SIZE_T SizeRequested)
BOOLEAN KmtIsCheckedBuild
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _Inout_
Definition: ms_sal.h:378
#define _Out_writes_bytes_(size)
Definition: ms_sal.h:350
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#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)
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define FILE_CREATED
Definition: nt_native.h:770
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define DELETE
Definition: nt_native.h:57
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define L(x)
Definition: ntvdm.h:50
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 _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
FILE_NAME_INFORMATION NameInformation
Definition: winternl.h:804
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING SymbolicLinkName
Definition: wdfdevice.h:3739
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:857
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180