2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test driver for CcSetFileSizes function
5 * PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
13 #define IOCTL_START_TEST 1
14 #define IOCTL_FINISH_TEST 2
16 typedef struct _TEST_FCB
18 FSRTL_ADVANCED_FCB_HEADER Header
;
19 SECTION_OBJECT_POINTERS SectionObjectPointers
;
20 FAST_MUTEX HeaderMutex
;
21 } TEST_FCB
, *PTEST_FCB
;
23 static ULONG TestTestId
= -1;
24 static PFILE_OBJECT TestFileObject
;
25 static PDEVICE_OBJECT TestDeviceObject
;
26 static KMT_IRP_HANDLER TestIrpHandler
;
27 static KMT_MESSAGE_HANDLER TestMessageHandler
;
31 _In_ PDRIVER_OBJECT DriverObject
,
32 _In_ PCUNICODE_STRING RegistryPath
,
33 _Out_ PCWSTR
*DeviceName
,
36 NTSTATUS Status
= STATUS_SUCCESS
;
40 UNREFERENCED_PARAMETER(RegistryPath
);
42 *DeviceName
= L
"CcSetFileSizes";
43 *Flags
= TESTENTRY_NO_EXCLUSIVE_DEVICE
|
44 TESTENTRY_BUFFERED_IO_DEVICE
|
45 TESTENTRY_NO_READONLY_DEVICE
;
47 KmtRegisterIrpHandler(IRP_MJ_READ
, NULL
, TestIrpHandler
);
48 KmtRegisterMessageHandler(0, NULL
, TestMessageHandler
);
55 _In_ PDRIVER_OBJECT DriverObject
)
94 static CACHE_MANAGER_CALLBACKS Callbacks
= {
101 static CC_FILE_SIZES NewFileSizes
= {
102 RTL_CONSTANT_LARGE_INTEGER((LONGLONG
)VACB_MAPPING_GRANULARITY
), // .AllocationSize
103 RTL_CONSTANT_LARGE_INTEGER((LONGLONG
)VACB_MAPPING_GRANULARITY
), // .FileSize
104 RTL_CONSTANT_LARGE_INTEGER((LONGLONG
)VACB_MAPPING_GRANULARITY
) // .ValidDataLength
109 MapAndLockUserBuffer(
111 _In_ ULONG BufferLength
)
115 if (Irp
->MdlAddress
== NULL
)
117 Mdl
= IoAllocateMdl(Irp
->UserBuffer
, BufferLength
, FALSE
, FALSE
, Irp
);
125 MmProbeAndLockPages(Mdl
, Irp
->RequestorMode
, IoWriteAccess
);
127 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
130 Irp
->MdlAddress
= NULL
;
131 _SEH2_YIELD(return NULL
);
136 return MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);
143 PDEVICE_OBJECT DeviceObject
)
149 LARGE_INTEGER Offset
;
150 IO_STATUS_BLOCK IoStatus
;
152 ok_eq_pointer(TestFileObject
, NULL
);
153 ok_eq_pointer(TestDeviceObject
, NULL
);
154 ok_eq_ulong(TestTestId
, -1);
156 TestDeviceObject
= DeviceObject
;
158 TestFileObject
= IoCreateStreamFileObject(NULL
, DeviceObject
);
159 if (!skip(TestFileObject
!= NULL
, "Failed to allocate FO\n"))
161 Fcb
= ExAllocatePool(NonPagedPool
, sizeof(TEST_FCB
));
162 if (!skip(Fcb
!= NULL
, "ExAllocatePool failed\n"))
164 RtlZeroMemory(Fcb
, sizeof(TEST_FCB
));
165 ExInitializeFastMutex(&Fcb
->HeaderMutex
);
166 FsRtlSetupAdvancedHeader(&Fcb
->Header
, &Fcb
->HeaderMutex
);
168 TestFileObject
->FsContext
= Fcb
;
169 TestFileObject
->SectionObjectPointer
= &Fcb
->SectionObjectPointers
;
170 Fcb
->Header
.AllocationSize
.QuadPart
= VACB_MAPPING_GRANULARITY
;
171 Fcb
->Header
.FileSize
.QuadPart
= VACB_MAPPING_GRANULARITY
- PAGE_SIZE
;
172 Fcb
->Header
.ValidDataLength
.QuadPart
= VACB_MAPPING_GRANULARITY
- PAGE_SIZE
;
174 if (TestId
> 1 && TestId
< 4)
176 Fcb
->Header
.AllocationSize
.QuadPart
= VACB_MAPPING_GRANULARITY
- PAGE_SIZE
;
180 CcInitializeCacheMap(TestFileObject
, (PCC_FILE_SIZES
)&Fcb
->Header
.AllocationSize
, TRUE
, &Callbacks
, NULL
);
181 KmtEndSeh(STATUS_SUCCESS
);
183 if (!skip(CcIsFileCached(TestFileObject
) == TRUE
, "CcInitializeCacheMap failed\n"))
185 trace("Starting test: %d\n", TestId
);
187 if (TestId
== 0 || TestId
== 2)
191 Ret
= CcMapData(TestFileObject
, &Offset
, VACB_MAPPING_GRANULARITY
- PAGE_SIZE
, MAP_WAIT
, &Bcb
, (PVOID
*)&Buffer
);
192 KmtEndSeh(STATUS_SUCCESS
);
194 if (!skip(Ret
== TRUE
, "CcMapData failed\n"))
196 ok_eq_ulong(Buffer
[(VACB_MAPPING_GRANULARITY
- PAGE_SIZE
- sizeof(ULONG
)) / sizeof(ULONG
)], 0xBABABABA);
201 CcSetFileSizes(TestFileObject
, &NewFileSizes
);
202 KmtEndSeh(STATUS_SUCCESS
);
204 Fcb
->Header
.AllocationSize
.QuadPart
= VACB_MAPPING_GRANULARITY
;
205 Fcb
->Header
.FileSize
.QuadPart
= VACB_MAPPING_GRANULARITY
;
209 Ret
= CcMapData(TestFileObject
, &Offset
, VACB_MAPPING_GRANULARITY
, MAP_WAIT
, &Bcb
, (PVOID
*)&Buffer
);
210 KmtEndSeh(STATUS_SUCCESS
);
212 if (!skip(Ret
== TRUE
, "CcMapData failed\n"))
214 ok_eq_ulong(Buffer
[(VACB_MAPPING_GRANULARITY
- sizeof(ULONG
)) / sizeof(ULONG
)], 0xBABABABA);
219 else if (TestId
== 1 || TestId
== 3)
221 Buffer
= ExAllocatePool(NonPagedPool
, PAGE_SIZE
);
222 if (!skip(Buffer
!= NULL
, "ExAllocatePool failed\n"))
225 Offset
.QuadPart
= VACB_MAPPING_GRANULARITY
- 2 * PAGE_SIZE
;
228 Ret
= CcCopyRead(TestFileObject
, &Offset
, PAGE_SIZE
, TRUE
, Buffer
, &IoStatus
);
229 KmtEndSeh(STATUS_SUCCESS
);
231 ok_eq_ulong(Buffer
[(PAGE_SIZE
- sizeof(ULONG
)) / sizeof(ULONG
)], 0xBABABABA);
234 CcSetFileSizes(TestFileObject
, &NewFileSizes
);
235 KmtEndSeh(STATUS_SUCCESS
);
237 Fcb
->Header
.AllocationSize
.QuadPart
= VACB_MAPPING_GRANULARITY
;
238 Fcb
->Header
.FileSize
.QuadPart
= VACB_MAPPING_GRANULARITY
;
239 RtlZeroMemory(Buffer
, PAGE_SIZE
);
241 Offset
.QuadPart
= VACB_MAPPING_GRANULARITY
- PAGE_SIZE
;
244 Ret
= CcCopyRead(TestFileObject
, &Offset
, PAGE_SIZE
, TRUE
, Buffer
, &IoStatus
);
245 KmtEndSeh(STATUS_SUCCESS
);
247 ok_eq_ulong(Buffer
[(PAGE_SIZE
- sizeof(ULONG
)) / sizeof(ULONG
)], 0xBABABABA);
262 PDEVICE_OBJECT DeviceObject
)
264 LARGE_INTEGER Zero
= RTL_CONSTANT_LARGE_INTEGER(0LL);
265 CACHE_UNINITIALIZE_EVENT CacheUninitEvent
;
267 ok_eq_pointer(TestDeviceObject
, DeviceObject
);
268 ok_eq_ulong(TestTestId
, TestId
);
270 if (!skip(TestFileObject
!= NULL
, "No test FO\n"))
272 if (CcIsFileCached(TestFileObject
))
274 KeInitializeEvent(&CacheUninitEvent
.Event
, NotificationEvent
, FALSE
);
275 CcUninitializeCacheMap(TestFileObject
, &Zero
, &CacheUninitEvent
);
276 KeWaitForSingleObject(&CacheUninitEvent
.Event
, Executive
, KernelMode
, FALSE
, NULL
);
279 if (TestFileObject
->FsContext
!= NULL
)
281 ExFreePool(TestFileObject
->FsContext
);
282 TestFileObject
->FsContext
= NULL
;
283 TestFileObject
->SectionObjectPointer
= NULL
;
286 ObDereferenceObject(TestFileObject
);
289 TestFileObject
= NULL
;
290 TestDeviceObject
= NULL
;
298 _In_ PDEVICE_OBJECT DeviceObject
,
299 _In_ ULONG ControlCode
,
300 _In_opt_ PVOID Buffer
,
301 _In_ SIZE_T InLength
,
302 _Inout_ PSIZE_T OutLength
)
304 NTSTATUS Status
= STATUS_SUCCESS
;
306 FsRtlEnterFileSystem();
310 case IOCTL_START_TEST
:
311 ok_eq_ulong((ULONG
)InLength
, sizeof(ULONG
));
312 PerformTest(*(PULONG
)Buffer
, DeviceObject
);
315 case IOCTL_FINISH_TEST
:
316 ok_eq_ulong((ULONG
)InLength
, sizeof(ULONG
));
317 CleanupTest(*(PULONG
)Buffer
, DeviceObject
);
321 Status
= STATUS_NOT_IMPLEMENTED
;
325 FsRtlExitFileSystem();
333 _In_ PDEVICE_OBJECT DeviceObject
,
335 _In_ PIO_STACK_LOCATION IoStack
)
341 DPRINT("IRP %x/%x\n", IoStack
->MajorFunction
, IoStack
->MinorFunction
);
342 ASSERT(IoStack
->MajorFunction
== IRP_MJ_READ
);
344 FsRtlEnterFileSystem();
346 Status
= STATUS_NOT_SUPPORTED
;
347 Irp
->IoStatus
.Information
= 0;
349 if (IoStack
->MajorFunction
== IRP_MJ_READ
)
355 LARGE_INTEGER Offset
;
357 Offset
= IoStack
->Parameters
.Read
.ByteOffset
;
358 Length
= IoStack
->Parameters
.Read
.Length
;
359 Fcb
= IoStack
->FileObject
->FsContext
;
361 ok_eq_pointer(DeviceObject
, TestDeviceObject
);
362 ok_eq_pointer(IoStack
->FileObject
, TestFileObject
);
363 ok(Fcb
!= NULL
, "Null FCB\n");
365 ok(FlagOn(Irp
->Flags
, IRP_NOCACHE
), "Not coming from Cc\n");
368 ok((Offset
.QuadPart
% PAGE_SIZE
== 0 || Offset
.QuadPart
== 0), "Offset is not aligned: %I64i\n", Offset
.QuadPart
);
369 ok(Length
% PAGE_SIZE
== 0, "Length is not aligned: %I64i\n", Length
);
371 ok(Irp
->AssociatedIrp
.SystemBuffer
== NULL
, "A SystemBuffer was allocated!\n");
372 Buffer
= MapAndLockUserBuffer(Irp
, Length
);
373 ok(Buffer
!= NULL
, "Null pointer!\n");
375 if (Offset
.QuadPart
< Fcb
->Header
.FileSize
.QuadPart
)
377 RtlFillMemory(Buffer
, min(Length
, Fcb
->Header
.FileSize
.QuadPart
- Offset
.QuadPart
), 0xBA);
378 Buffer
= (PVOID
)((ULONG_PTR
)Buffer
+ (ULONG_PTR
)min(Length
, Fcb
->Header
.FileSize
.QuadPart
- Offset
.QuadPart
));
380 if (Length
> (Fcb
->Header
.FileSize
.QuadPart
- Offset
.QuadPart
))
382 RtlFillMemory(Buffer
, Length
- Fcb
->Header
.FileSize
.QuadPart
, 0xBD);
387 RtlFillMemory(Buffer
, Length
, 0xBD);
390 Status
= STATUS_SUCCESS
;
392 Mdl
= Irp
->MdlAddress
;
393 ok(Mdl
!= NULL
, "Null pointer for MDL!\n");
394 ok((Mdl
->MdlFlags
& MDL_PAGES_LOCKED
) != 0, "MDL not locked\n");
395 ok((Mdl
->MdlFlags
& MDL_SOURCE_IS_NONPAGED_POOL
) == 0, "MDL from non paged\n");
396 ok((Mdl
->MdlFlags
& MDL_IO_PAGE_READ
) != 0, "Non paging IO\n");
397 ok((Irp
->Flags
& IRP_PAGING_IO
) != 0, "Non paging IO\n");
399 Irp
->IoStatus
.Information
= Length
;
402 if (Status
== STATUS_PENDING
)
404 IoMarkIrpPending(Irp
);
405 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
406 Status
= STATUS_PENDING
;
410 Irp
->IoStatus
.Status
= Status
;
411 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
414 FsRtlExitFileSystem();