ReactOS  r76032
CcCopyRead_drv.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: Test driver for CcCopyRead function
5  * PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 
10 #define NDEBUG
11 #include <debug.h>
12 
13 typedef struct _TEST_FCB
14 {
19 
22 static KMT_IRP_HANDLER TestIrpHandler;
24 
25 static
26 BOOLEAN
27 NTAPI
37 {
38  IoStatus->Status = STATUS_NOT_SUPPORTED;
39  return FALSE;
40 }
41 
47  _Inout_ INT *Flags)
48 {
50 
51  PAGED_CODE();
52 
53  UNREFERENCED_PARAMETER(RegistryPath);
54 
55  *DeviceName = L"CcCopyRead";
56  *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE |
57  TESTENTRY_BUFFERED_IO_DEVICE |
58  TESTENTRY_NO_READONLY_DEVICE;
59 
63 
64  TestFastIoDispatch.FastIoRead = FastIoRead;
65  DriverObject->FastIoDispatch = &TestFastIoDispatch;
66 
67 
68  return Status;
69 }
70 
71 VOID
74 {
75  PAGED_CODE();
76 }
77 
78 BOOLEAN
79 NTAPI
83 {
84  return TRUE;
85 }
86 
87 VOID
88 NTAPI
91 {
92  return;
93 }
94 
95 BOOLEAN
96 NTAPI
100 {
101  return TRUE;
102 }
103 
104 VOID
105 NTAPI
108 {
109  return;
110 }
111 
117 };
118 
119 static
120 PVOID
122  _In_ _Out_ PIRP Irp,
124 {
125  PMDL Mdl;
126 
127  if (Irp->MdlAddress == NULL)
128  {
129  Mdl = IoAllocateMdl(Irp->UserBuffer, BufferLength, FALSE, FALSE, Irp);
130  if (Mdl == NULL)
131  {
132  return NULL;
133  }
134 
135  _SEH2_TRY
136  {
137  MmProbeAndLockPages(Mdl, Irp->RequestorMode, IoWriteAccess);
138  }
140  {
141  IoFreeMdl(Mdl);
142  Irp->MdlAddress = NULL;
143  _SEH2_YIELD(return NULL);
144  }
145  _SEH2_END;
146  }
147 
148  return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
149 }
150 
151 
152 static
153 NTSTATUS
156  _In_ PIRP Irp,
157  _In_ PIO_STACK_LOCATION IoStack)
158 {
160  PTEST_FCB Fcb;
161  CACHE_UNINITIALIZE_EVENT CacheUninitEvent;
162 
163  PAGED_CODE();
164 
165  DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction);
166  ASSERT(IoStack->MajorFunction == IRP_MJ_CLEANUP ||
167  IoStack->MajorFunction == IRP_MJ_CREATE ||
168  IoStack->MajorFunction == IRP_MJ_READ);
169 
170  Status = STATUS_NOT_SUPPORTED;
171  Irp->IoStatus.Information = 0;
172 
173  if (IoStack->MajorFunction == IRP_MJ_CREATE)
174  {
175  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR))
176  {
177  TestDeviceObject = DeviceObject;
178  TestFileObject = IoStack->FileObject;
179  }
180  Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI');
181  RtlZeroMemory(Fcb, sizeof(*Fcb));
183  FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
184  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
185  IoStack->FileObject->FileName.Buffer[1] == 'B')
186  {
187  Fcb->Header.AllocationSize.QuadPart = 1000000;
188  Fcb->Header.FileSize.QuadPart = 1000000;
189  Fcb->Header.ValidDataLength.QuadPart = 1000000;
190  }
191  else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
192  IoStack->FileObject->FileName.Buffer[1] == 'S')
193  {
194  Fcb->Header.AllocationSize.QuadPart = 1004;
195  Fcb->Header.FileSize.QuadPart = 1004;
196  Fcb->Header.ValidDataLength.QuadPart = 1004;
197  }
198  else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
199  IoStack->FileObject->FileName.Buffer[1] == 'R')
200  {
201  Fcb->Header.AllocationSize.QuadPart = 62;
202  Fcb->Header.FileSize.QuadPart = 62;
203  Fcb->Header.ValidDataLength.QuadPart = 62;
204  }
205  else
206  {
207  Fcb->Header.AllocationSize.QuadPart = 512;
208  Fcb->Header.FileSize.QuadPart = 512;
209  Fcb->Header.ValidDataLength.QuadPart = 512;
210  }
211  Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
212  IoStack->FileObject->FsContext = Fcb;
213  IoStack->FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
214 
215  CcInitializeCacheMap(IoStack->FileObject,
216  (PCC_FILE_SIZES)&Fcb->Header.AllocationSize,
217  FALSE, &Callbacks, NULL);
218 
219  Irp->IoStatus.Information = FILE_OPENED;
220  Status = STATUS_SUCCESS;
221  }
222  else if (IoStack->MajorFunction == IRP_MJ_READ)
223  {
224  BOOLEAN Ret;
225  ULONG Length;
226  PVOID Buffer;
228 
229  Offset = IoStack->Parameters.Read.ByteOffset;
230  Length = IoStack->Parameters.Read.Length;
231  Fcb = IoStack->FileObject->FsContext;
232 
233  ok_eq_pointer(DeviceObject, TestDeviceObject);
234  ok_eq_pointer(IoStack->FileObject, TestFileObject);
235 
236  if (!FlagOn(Irp->Flags, IRP_NOCACHE))
237  {
238  ok(Offset.QuadPart % PAGE_SIZE != 0, "Offset is aligned: %I64i\n", Offset.QuadPart);
239  ok(Length % PAGE_SIZE != 0, "Length is aligned: %I64i\n", Length);
240 
241  Buffer = Irp->AssociatedIrp.SystemBuffer;
242  ok(Buffer != NULL, "Null pointer!\n");
243 
244  _SEH2_TRY
245  {
246  Ret = CcCopyRead(IoStack->FileObject, &Offset, Length, TRUE, Buffer,
247  &Irp->IoStatus);
248  ok_bool_true(Ret, "CcCopyRead");
249  }
251  {
252  Irp->IoStatus.Status = _SEH2_GetExceptionCode();
253  }
254  _SEH2_END;
255 
256  Status = Irp->IoStatus.Status;
257 
258  if (NT_SUCCESS(Status))
259  {
260  if (Offset.QuadPart <= 1000LL && Offset.QuadPart + Length > 1000LL)
261  {
262  ok_eq_hex(*(PUSHORT)((ULONG_PTR)Buffer + (ULONG_PTR)(1000LL - Offset.QuadPart)), 0xFFFF);
263  }
264  else
265  {
266  ok_eq_hex(*(PUSHORT)Buffer, 0xBABA);
267  }
268  }
269  }
270  else
271  {
272  PMDL Mdl;
273 
274  ok((Offset.QuadPart % PAGE_SIZE == 0 || Offset.QuadPart == 0), "Offset is not aligned: %I64i\n", Offset.QuadPart);
275  ok(Length % PAGE_SIZE == 0, "Length is not aligned: %I64i\n", Length);
276 
277  ok(Irp->AssociatedIrp.SystemBuffer == NULL, "A SystemBuffer was allocated!\n");
278  Buffer = MapAndLockUserBuffer(Irp, Length);
279  ok(Buffer != NULL, "Null pointer!\n");
280  RtlFillMemory(Buffer, Length, 0xBA);
281 
282  Status = STATUS_SUCCESS;
283  if (Offset.QuadPart <= 1000LL && Offset.QuadPart + Length > 1000LL)
284  {
285  *(PUSHORT)((ULONG_PTR)Buffer + (ULONG_PTR)(1000LL - Offset.QuadPart)) = 0xFFFF;
286  }
287 
288  Mdl = Irp->MdlAddress;
289  ok(Mdl != NULL, "Null pointer for MDL!\n");
290  ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) != 0, "MDL not locked\n");
291  ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0, "MDL from non paged\n");
292  ok((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0, "Non paging IO\n");
293  ok((Irp->Flags & IRP_PAGING_IO) != 0, "Non paging IO\n");
294  }
295 
296  if (NT_SUCCESS(Status))
297  {
298  Irp->IoStatus.Information = Length;
299  IoStack->FileObject->CurrentByteOffset.QuadPart = Offset.QuadPart + Length;
300  }
301  }
302  else if (IoStack->MajorFunction == IRP_MJ_CLEANUP)
303  {
304  KeInitializeEvent(&CacheUninitEvent.Event, NotificationEvent, FALSE);
305  CcUninitializeCacheMap(IoStack->FileObject, NULL, &CacheUninitEvent);
306  KeWaitForSingleObject(&CacheUninitEvent.Event, Executive, KernelMode, FALSE, NULL);
307  Fcb = IoStack->FileObject->FsContext;
308  ExFreePoolWithTag(Fcb, 'FwrI');
309  IoStack->FileObject->FsContext = NULL;
310  Status = STATUS_SUCCESS;
311  }
312 
313  if (Status == STATUS_PENDING)
314  {
315  IoMarkIrpPending(Irp);
317  Status = STATUS_PENDING;
318  }
319  else
320  {
321  Irp->IoStatus.Status = Status;
323  }
324 
325  return Status;
326 }
#define MDL_IO_PAGE_READ
Definition: mmtypes.h:24
DWORD *typedef PVOID
Definition: winlogon.h:52
const uint16_t * PCWSTR
Definition: typedefs.h:55
static PVOID MapAndLockUserBuffer(_In_ _Out_ PIRP Irp, _In_ ULONG BufferLength)
#define TRUE
Definition: types.h:120
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define LL
Definition: tui.h:72
VOID NTAPI ReleaseFromLazyWrite(_In_ PVOID Context)
Definition: bidi.c:75
_In_ PIRP Irp
Definition: csq.h:116
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:315
__wchar_t WCHAR
Definition: xmlstorage.h:180
return STATUS_SUCCESS
Definition: btrfs.c:2664
_In_ PLARGE_INTEGER _In_ ULONG _In_ BOOLEAN _In_ ULONG LockKey
Definition: npfs.h:636
#define ok_eq_pointer(value, expected)
#define FILE_OPENED
Definition: nt_native.h:769
BOOLEAN NTAPI AcquireForReadAhead(_In_ PVOID Context, _In_ BOOLEAN Wait)
#define IRP_NOCACHE
static CACHE_MANAGER_CALLBACKS Callbacks
static PFILE_OBJECT TestFileObject
_In_ PLARGE_INTEGER _In_ ULONG _In_ BOOLEAN _In_ ULONG _Out_ PVOID _Out_ PIO_STATUS_BLOCK _In_ PDEVICE_OBJECT DeviceObject
Definition: npfs.h:636
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
PVOID PMDL
Definition: usb.h:39
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
int32_t INT
Definition: typedefs.h:56
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define ok_bool_true(value, desc)
Definition: kmt_test.h:211
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FALSE
Definition: types.h:117
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#define _SEH2_END
Definition: pseh2_64.h:7
VOID NTAPI ReleaseFromReadAhead(_In_ PVOID Context)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:557
_In_ PFILE_OBJECT FileObject
Definition: classpnp.h:1229
#define _Out_
Definition: no_sal2.h:323
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1177
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
static BOOLEAN NTAPI FastIoRead(_In_ PFILE_OBJECT FileObject, _In_ PLARGE_INTEGER FileOffset, _In_ ULONG Length, _In_ BOOLEAN Wait, _In_ ULONG LockKey, _Out_ PVOID Buffer, _Out_ PIO_STATUS_BLOCK IoStatus, _In_ PDEVICE_OBJECT DeviceObject)
NTSTATUS KmtRegisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler)
FAST_MUTEX
Definition: extypes.h:17
unsigned char BOOLEAN
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define STATUS_PENDING
Definition: ntstatus.h:82
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:193
static PDEVICE_OBJECT TestDeviceObject
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
unsigned short * PUSHORT
Definition: retypes.h:2
SECTION_OBJECT_POINTERS SectionObjectPointers
struct _TEST_FCB * PTEST_FCB
#define _Inout_
Definition: no_sal2.h:244
#define PAGED_CODE()
Definition: video.h:57
* PFILE_OBJECT
Definition: iotypes.h:1949
UINTN VOID * Buffer
Definition: acefiex.h:370
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
BOOLEAN NTAPI CcCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: copysup.c:43
VOID TestUnload(_In_ PDRIVER_OBJECT DriverObject)
VOID UINTN Length
Definition: acefiex.h:744
FSRTL_ADVANCED_FCB_HEADER Header
#define PAGE_SIZE
Definition: env_spec_w32.h:49
BOOLEAN NTAPI AcquireForLazyWrite(_In_ PVOID Context, _In_ BOOLEAN Wait)
#define FlagOn(_F, _SF)
Definition: ext2fs.h:178
Status
Definition: gdiplustypes.h:24
_In_ PLARGE_INTEGER _In_ ULONG _In_ BOOLEAN _In_ ULONG _Out_ PVOID _Out_ PIO_STATUS_BLOCK IoStatus
Definition: npfs.h:636
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
struct _TEST_FCB TEST_FCB
#define _In_
Definition: no_sal2.h:204
static FAST_IO_DISPATCH TestFastIoDispatch
PFAST_IO_READ FastIoRead
Definition: iotypes.h:1686
LONG NTSTATUS
Definition: DriverTester.h:11
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:905
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:284
#define _SEH2_TRY
Definition: pseh2_64.h:5
_In_ BOOLEAN Wait
Definition: cctypes.h:23
#define IRP_PAGING_IO
static KMT_IRP_HANDLER TestIrpHandler
#define IRP_MJ_READ
Definition: rdpdr.c:46
_In_ PLARGE_INTEGER FileOffset
Definition: cctypes.h:53
FAST_MUTEX HeaderMutex
#define IRP_MJ_CLEANUP
PVOID PIRP
Definition: usb.h:38
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#define ok(value,...)
Definition: CImage.cpp:33
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ok_eq_hex(value, expected)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1097
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
IoMarkIrpPending(Irp)
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
NTSTATUS TestEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PCUNICODE_STRING RegistryPath, _Out_ PCWSTR *DeviceName, _Inout_ INT *Flags)
LONGLONG QuadPart
Definition: typedefs.h:112