ReactOS  0.4.11-dev-433-g473ca91
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 {
20 
23 static KMT_IRP_HANDLER TestIrpHandler;
25 
26 static
27 BOOLEAN
28 NTAPI
38 {
39  IoStatus->Status = STATUS_NOT_SUPPORTED;
40  return FALSE;
41 }
42 
48  _Inout_ INT *Flags)
49 {
51 
52  PAGED_CODE();
53 
54  UNREFERENCED_PARAMETER(RegistryPath);
55 
56  *DeviceName = L"CcCopyRead";
57  *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE |
58  TESTENTRY_BUFFERED_IO_DEVICE |
59  TESTENTRY_NO_READONLY_DEVICE;
60 
64 
65  TestFastIoDispatch.FastIoRead = FastIoRead;
66  DriverObject->FastIoDispatch = &TestFastIoDispatch;
67 
68 
69  return Status;
70 }
71 
72 VOID
75 {
76  PAGED_CODE();
77 }
78 
79 BOOLEAN
80 NTAPI
84 {
85  return TRUE;
86 }
87 
88 VOID
89 NTAPI
92 {
93  return;
94 }
95 
96 BOOLEAN
97 NTAPI
100  _In_ BOOLEAN Wait)
101 {
102  return TRUE;
103 }
104 
105 VOID
106 NTAPI
109 {
110  return;
111 }
112 
118 };
119 
120 static
121 PVOID
123  _In_ _Out_ PIRP Irp,
125 {
126  PMDL Mdl;
127 
128  if (Irp->MdlAddress == NULL)
129  {
130  Mdl = IoAllocateMdl(Irp->UserBuffer, BufferLength, FALSE, FALSE, Irp);
131  if (Mdl == NULL)
132  {
133  return NULL;
134  }
135 
136  _SEH2_TRY
137  {
138  MmProbeAndLockPages(Mdl, Irp->RequestorMode, IoWriteAccess);
139  }
141  {
142  IoFreeMdl(Mdl);
143  Irp->MdlAddress = NULL;
144  _SEH2_YIELD(return NULL);
145  }
146  _SEH2_END;
147  }
148 
149  return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
150 }
151 
152 
153 static
154 NTSTATUS
157  _In_ PIRP Irp,
158  _In_ PIO_STACK_LOCATION IoStack)
159 {
162  PTEST_FCB Fcb;
163  CACHE_UNINITIALIZE_EVENT CacheUninitEvent;
164 
165  PAGED_CODE();
166 
167  DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction);
168  ASSERT(IoStack->MajorFunction == IRP_MJ_CLEANUP ||
169  IoStack->MajorFunction == IRP_MJ_CREATE ||
170  IoStack->MajorFunction == IRP_MJ_READ);
171 
172  Status = STATUS_NOT_SUPPORTED;
173  Irp->IoStatus.Information = 0;
174 
175  if (IoStack->MajorFunction == IRP_MJ_CREATE)
176  {
177  ok_irql(PASSIVE_LEVEL);
178 
179  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR))
180  {
181  TestDeviceObject = DeviceObject;
182  TestFileObject = IoStack->FileObject;
183  }
184  Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI');
185  RtlZeroMemory(Fcb, sizeof(*Fcb));
187  FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
188  Fcb->BigFile = FALSE;
189  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
190  IoStack->FileObject->FileName.Buffer[1] == 'B')
191  {
192  Fcb->Header.AllocationSize.QuadPart = 1000000;
193  Fcb->Header.FileSize.QuadPart = 1000000;
194  Fcb->Header.ValidDataLength.QuadPart = 1000000;
195  }
196  else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
197  IoStack->FileObject->FileName.Buffer[1] == 'S')
198  {
199  Fcb->Header.AllocationSize.QuadPart = 1004;
200  Fcb->Header.FileSize.QuadPart = 1004;
201  Fcb->Header.ValidDataLength.QuadPart = 1004;
202  }
203  else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
204  IoStack->FileObject->FileName.Buffer[1] == 'R')
205  {
206  Fcb->Header.AllocationSize.QuadPart = 62;
207  Fcb->Header.FileSize.QuadPart = 62;
208  Fcb->Header.ValidDataLength.QuadPart = 62;
209  }
210  else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
211  IoStack->FileObject->FileName.Buffer[1] == 'F')
212  {
213  Fcb->Header.AllocationSize.QuadPart = 4294967296;
214  Fcb->Header.FileSize.QuadPart = 4294967296;
215  Fcb->Header.ValidDataLength.QuadPart = 4294967296;
216  Fcb->BigFile = TRUE;
217  }
218  else
219  {
220  Fcb->Header.AllocationSize.QuadPart = 512;
221  Fcb->Header.FileSize.QuadPart = 512;
222  Fcb->Header.ValidDataLength.QuadPart = 512;
223  }
224  Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
225  IoStack->FileObject->FsContext = Fcb;
226  IoStack->FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
227 
228  CcInitializeCacheMap(IoStack->FileObject,
229  (PCC_FILE_SIZES)&Fcb->Header.AllocationSize,
230  FALSE, &Callbacks, NULL);
231 
232  Irp->IoStatus.Information = FILE_OPENED;
233  Status = STATUS_SUCCESS;
234  }
235  else if (IoStack->MajorFunction == IRP_MJ_READ)
236  {
237  BOOLEAN Ret;
238  ULONG Length;
239  PVOID Buffer;
241 
242  Offset = IoStack->Parameters.Read.ByteOffset;
243  Length = IoStack->Parameters.Read.Length;
244  Fcb = IoStack->FileObject->FsContext;
245 
246  ok_eq_pointer(DeviceObject, TestDeviceObject);
247  ok_eq_pointer(IoStack->FileObject, TestFileObject);
248 
249  if (!FlagOn(Irp->Flags, IRP_NOCACHE))
250  {
251  ok_irql(PASSIVE_LEVEL);
252 
253  /* We don't want to test alignement for big files (not the purpose of the test) */
254  if (!Fcb->BigFile)
255  {
256  ok(Offset.QuadPart % PAGE_SIZE != 0, "Offset is aligned: %I64i\n", Offset.QuadPart);
257  ok(Length % PAGE_SIZE != 0, "Length is aligned: %I64i\n", Length);
258  }
259 
260  Buffer = Irp->AssociatedIrp.SystemBuffer;
261  ok(Buffer != NULL, "Null pointer!\n");
262 
263  _SEH2_TRY
264  {
265  Ret = CcCopyRead(IoStack->FileObject, &Offset, Length, TRUE, Buffer,
266  &Irp->IoStatus);
267  ok_bool_true(Ret, "CcCopyRead");
268  }
270  {
271  Irp->IoStatus.Status = _SEH2_GetExceptionCode();
272  }
273  _SEH2_END;
274 
275  Status = Irp->IoStatus.Status;
276 
277  if (NT_SUCCESS(Status))
278  {
279  if (Offset.QuadPart <= 1000LL && Offset.QuadPart + Length > 1000LL)
280  {
281  ok_eq_hex(*(PUSHORT)((ULONG_PTR)Buffer + (ULONG_PTR)(1000LL - Offset.QuadPart)), 0xFFFF);
282  }
283  else
284  {
285  ok_eq_hex(*(PUSHORT)Buffer, 0xBABA);
286  }
287  }
288  }
289  else
290  {
291  PMDL Mdl;
292 
293  ok_irql(APC_LEVEL);
294  ok((Offset.QuadPart % PAGE_SIZE == 0 || Offset.QuadPart == 0), "Offset is not aligned: %I64i\n", Offset.QuadPart);
295  ok(Length % PAGE_SIZE == 0, "Length is not aligned: %I64i\n", Length);
296 
297  ok(Irp->AssociatedIrp.SystemBuffer == NULL, "A SystemBuffer was allocated!\n");
298  Buffer = MapAndLockUserBuffer(Irp, Length);
299  ok(Buffer != NULL, "Null pointer!\n");
300  RtlFillMemory(Buffer, Length, 0xBA);
301 
302  Status = STATUS_SUCCESS;
303  if (Offset.QuadPart <= 1000LL && Offset.QuadPart + Length > 1000LL)
304  {
305  *(PUSHORT)((ULONG_PTR)Buffer + (ULONG_PTR)(1000LL - Offset.QuadPart)) = 0xFFFF;
306  }
307 
308  Mdl = Irp->MdlAddress;
309  ok(Mdl != NULL, "Null pointer for MDL!\n");
310  ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) != 0, "MDL not locked\n");
311  ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0, "MDL from non paged\n");
312  ok((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0, "Non paging IO\n");
313  ok((Irp->Flags & IRP_PAGING_IO) != 0, "Non paging IO\n");
314  }
315 
316  if (NT_SUCCESS(Status))
317  {
318  Irp->IoStatus.Information = Length;
319  IoStack->FileObject->CurrentByteOffset.QuadPart = Offset.QuadPart + Length;
320  }
321  }
322  else if (IoStack->MajorFunction == IRP_MJ_CLEANUP)
323  {
324  ok_irql(PASSIVE_LEVEL);
325  KeInitializeEvent(&CacheUninitEvent.Event, NotificationEvent, FALSE);
326  CcUninitializeCacheMap(IoStack->FileObject, &Zero, &CacheUninitEvent);
327  KeWaitForSingleObject(&CacheUninitEvent.Event, Executive, KernelMode, FALSE, NULL);
328  Fcb = IoStack->FileObject->FsContext;
329  ExFreePoolWithTag(Fcb, 'FwrI');
330  IoStack->FileObject->FsContext = NULL;
331  Status = STATUS_SUCCESS;
332  }
333 
334  if (Status == STATUS_PENDING)
335  {
336  IoMarkIrpPending(Irp);
338  Status = STATUS_PENDING;
339  }
340  else
341  {
342  Irp->IoStatus.Status = Status;
344  }
345 
346  return Status;
347 }
#define MDL_IO_PAGE_READ
Definition: mmtypes.h:24
DWORD *typedef PVOID
Definition: winlogon.h:61
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: ntfs.h:509
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
#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
BOOLEAN BigFile
#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
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#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
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:935
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
return STATUS_SUCCESS
Definition: btrfs.c:2710
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