ReactOS  0.4.10-dev-346-g2ae1675
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 {
161  PTEST_FCB Fcb;
162  CACHE_UNINITIALIZE_EVENT CacheUninitEvent;
163 
164  PAGED_CODE();
165 
166  DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction);
167  ASSERT(IoStack->MajorFunction == IRP_MJ_CLEANUP ||
168  IoStack->MajorFunction == IRP_MJ_CREATE ||
169  IoStack->MajorFunction == IRP_MJ_READ);
170 
171  Status = STATUS_NOT_SUPPORTED;
172  Irp->IoStatus.Information = 0;
173 
174  if (IoStack->MajorFunction == IRP_MJ_CREATE)
175  {
176  ok_irql(PASSIVE_LEVEL);
177 
178  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR))
179  {
180  TestDeviceObject = DeviceObject;
181  TestFileObject = IoStack->FileObject;
182  }
183  Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI');
184  RtlZeroMemory(Fcb, sizeof(*Fcb));
186  FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
187  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
188  IoStack->FileObject->FileName.Buffer[1] == 'B')
189  {
190  Fcb->Header.AllocationSize.QuadPart = 1000000;
191  Fcb->Header.FileSize.QuadPart = 1000000;
192  Fcb->Header.ValidDataLength.QuadPart = 1000000;
193  }
194  else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
195  IoStack->FileObject->FileName.Buffer[1] == 'S')
196  {
197  Fcb->Header.AllocationSize.QuadPart = 1004;
198  Fcb->Header.FileSize.QuadPart = 1004;
199  Fcb->Header.ValidDataLength.QuadPart = 1004;
200  }
201  else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
202  IoStack->FileObject->FileName.Buffer[1] == 'R')
203  {
204  Fcb->Header.AllocationSize.QuadPart = 62;
205  Fcb->Header.FileSize.QuadPart = 62;
206  Fcb->Header.ValidDataLength.QuadPart = 62;
207  }
208  else
209  {
210  Fcb->Header.AllocationSize.QuadPart = 512;
211  Fcb->Header.FileSize.QuadPart = 512;
212  Fcb->Header.ValidDataLength.QuadPart = 512;
213  }
214  Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
215  IoStack->FileObject->FsContext = Fcb;
216  IoStack->FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
217 
218  CcInitializeCacheMap(IoStack->FileObject,
219  (PCC_FILE_SIZES)&Fcb->Header.AllocationSize,
220  FALSE, &Callbacks, NULL);
221 
222  Irp->IoStatus.Information = FILE_OPENED;
223  Status = STATUS_SUCCESS;
224  }
225  else if (IoStack->MajorFunction == IRP_MJ_READ)
226  {
227  BOOLEAN Ret;
228  ULONG Length;
229  PVOID Buffer;
231 
232  Offset = IoStack->Parameters.Read.ByteOffset;
233  Length = IoStack->Parameters.Read.Length;
234  Fcb = IoStack->FileObject->FsContext;
235 
236  ok_eq_pointer(DeviceObject, TestDeviceObject);
237  ok_eq_pointer(IoStack->FileObject, TestFileObject);
238 
239  if (!FlagOn(Irp->Flags, IRP_NOCACHE))
240  {
241  ok_irql(PASSIVE_LEVEL);
242  ok(Offset.QuadPart % PAGE_SIZE != 0, "Offset is aligned: %I64i\n", Offset.QuadPart);
243  ok(Length % PAGE_SIZE != 0, "Length is aligned: %I64i\n", Length);
244 
245  Buffer = Irp->AssociatedIrp.SystemBuffer;
246  ok(Buffer != NULL, "Null pointer!\n");
247 
248  _SEH2_TRY
249  {
250  Ret = CcCopyRead(IoStack->FileObject, &Offset, Length, TRUE, Buffer,
251  &Irp->IoStatus);
252  ok_bool_true(Ret, "CcCopyRead");
253  }
255  {
256  Irp->IoStatus.Status = _SEH2_GetExceptionCode();
257  }
258  _SEH2_END;
259 
260  Status = Irp->IoStatus.Status;
261 
262  if (NT_SUCCESS(Status))
263  {
264  if (Offset.QuadPart <= 1000LL && Offset.QuadPart + Length > 1000LL)
265  {
266  ok_eq_hex(*(PUSHORT)((ULONG_PTR)Buffer + (ULONG_PTR)(1000LL - Offset.QuadPart)), 0xFFFF);
267  }
268  else
269  {
270  ok_eq_hex(*(PUSHORT)Buffer, 0xBABA);
271  }
272  }
273  }
274  else
275  {
276  PMDL Mdl;
277 
278  ok_irql(APC_LEVEL);
279  ok((Offset.QuadPart % PAGE_SIZE == 0 || Offset.QuadPart == 0), "Offset is not aligned: %I64i\n", Offset.QuadPart);
280  ok(Length % PAGE_SIZE == 0, "Length is not aligned: %I64i\n", Length);
281 
282  ok(Irp->AssociatedIrp.SystemBuffer == NULL, "A SystemBuffer was allocated!\n");
283  Buffer = MapAndLockUserBuffer(Irp, Length);
284  ok(Buffer != NULL, "Null pointer!\n");
285  RtlFillMemory(Buffer, Length, 0xBA);
286 
287  Status = STATUS_SUCCESS;
288  if (Offset.QuadPart <= 1000LL && Offset.QuadPart + Length > 1000LL)
289  {
290  *(PUSHORT)((ULONG_PTR)Buffer + (ULONG_PTR)(1000LL - Offset.QuadPart)) = 0xFFFF;
291  }
292 
293  Mdl = Irp->MdlAddress;
294  ok(Mdl != NULL, "Null pointer for MDL!\n");
295  ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) != 0, "MDL not locked\n");
296  ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0, "MDL from non paged\n");
297  ok((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0, "Non paging IO\n");
298  ok((Irp->Flags & IRP_PAGING_IO) != 0, "Non paging IO\n");
299  }
300 
301  if (NT_SUCCESS(Status))
302  {
303  Irp->IoStatus.Information = Length;
304  IoStack->FileObject->CurrentByteOffset.QuadPart = Offset.QuadPart + Length;
305  }
306  }
307  else if (IoStack->MajorFunction == IRP_MJ_CLEANUP)
308  {
309  ok_irql(PASSIVE_LEVEL);
310  KeInitializeEvent(&CacheUninitEvent.Event, NotificationEvent, FALSE);
311  CcUninitializeCacheMap(IoStack->FileObject, &Zero, &CacheUninitEvent);
312  KeWaitForSingleObject(&CacheUninitEvent.Event, Executive, KernelMode, FALSE, NULL);
313  Fcb = IoStack->FileObject->FsContext;
314  ExFreePoolWithTag(Fcb, 'FwrI');
315  IoStack->FileObject->FsContext = NULL;
316  Status = STATUS_SUCCESS;
317  }
318 
319  if (Status == STATUS_PENDING)
320  {
321  IoMarkIrpPending(Irp);
323  Status = STATUS_PENDING;
324  }
325  else
326  {
327  Irp->IoStatus.Status = Status;
329  }
330 
331  return Status;
332 }
#define MDL_IO_PAGE_READ
Definition: mmtypes.h:24
DWORD *typedef PVOID
Definition: winlogon.h:52
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)
PFILE_OBJECT FileObject
Definition: cdfs.h:204
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
_In_ PIRP Irp
Definition: csq.h:116
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
__wchar_t WCHAR
Definition: xmlstorage.h:180
return STATUS_SUCCESS
Definition: btrfs.c:2690
#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
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
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define ok_bool_true(value, desc)
Definition: kmt_test.h:256
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define RTL_CONSTANT_LARGE_INTEGER(quad_part)
Definition: rtltypes.h:414
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
VOID NTAPI ReleaseFromReadAhead(_In_ PVOID Context)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
#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:1240
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
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)
#define ok(value,...)
Definition: CComObject.cpp:34
FAST_MUTEX
Definition: extypes.h:17
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2650
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#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
* PFILE_OBJECT
Definition: iotypes.h:1954
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)
static const WCHAR L[]
Definition: oid.c:1087
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:179
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
Status
Definition: gdiplustypes.h:24
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:1691
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
_SEH2_END
Definition: create.c:4424
#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
_In_ BOOLEAN Wait
Definition: cctypes.h:23
#define IRP_PAGING_IO
static KMT_IRP_HANDLER TestIrpHandler
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:402
#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 _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ok_eq_hex(value, expected)
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
_In_ PFCB Fcb
Definition: cdprocs.h:151
IoMarkIrpPending(Irp)
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define APC_LEVEL
Definition: env_spec_w32.h:695
NTSTATUS TestEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PCUNICODE_STRING RegistryPath, _Out_ PCWSTR *DeviceName, _Inout_ INT *Flags)
LONGLONG QuadPart
Definition: typedefs.h:112