ReactOS  0.4.15-dev-1070-ge1a01de
CcCopyWrite_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 CcCopyWrite 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 {
40  return FALSE;
41 }
42 
43 static
44 BOOLEAN
45 NTAPI
55 {
57  return FALSE;
58 }
59 
65  _Inout_ INT *Flags)
66 {
68 
69  PAGED_CODE();
70 
72 
73  *DeviceName = L"CcCopyWrite";
74  *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE |
75  TESTENTRY_BUFFERED_IO_DEVICE |
76  TESTENTRY_NO_READONLY_DEVICE;
77 
83 
87 
88 
89  return Status;
90 }
91 
92 VOID
95 {
96  PAGED_CODE();
97 }
98 
99 BOOLEAN
100 NTAPI
103  _In_ BOOLEAN Wait)
104 {
105  return TRUE;
106 }
107 
108 VOID
109 NTAPI
112 {
113  return;
114 }
115 
116 BOOLEAN
117 NTAPI
120  _In_ BOOLEAN Wait)
121 {
122  return TRUE;
123 }
124 
125 VOID
126 NTAPI
129 {
130  return;
131 }
132 
138 };
139 
140 static
141 PVOID
143  _In_ _Out_ PIRP Irp,
145 {
146  PMDL Mdl;
147 
148  if (Irp->MdlAddress == NULL)
149  {
150  Mdl = IoAllocateMdl(Irp->UserBuffer, BufferLength, FALSE, FALSE, Irp);
151  if (Mdl == NULL)
152  {
153  return NULL;
154  }
155 
156  _SEH2_TRY
157  {
158  MmProbeAndLockPages(Mdl, Irp->RequestorMode, IoWriteAccess);
159  }
161  {
162  IoFreeMdl(Mdl);
163  Irp->MdlAddress = NULL;
164  _SEH2_YIELD(return NULL);
165  }
166  _SEH2_END;
167  }
168 
170 }
171 
172 
173 static
174 NTSTATUS
177  _In_ PIRP Irp,
178  _In_ PIO_STACK_LOCATION IoStack)
179 {
182  PTEST_FCB Fcb;
183  CACHE_UNINITIALIZE_EVENT CacheUninitEvent;
184 
185  PAGED_CODE();
186 
187  DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction);
188  ASSERT(IoStack->MajorFunction == IRP_MJ_CLEANUP ||
189  IoStack->MajorFunction == IRP_MJ_CREATE ||
190  IoStack->MajorFunction == IRP_MJ_READ ||
191  IoStack->MajorFunction == IRP_MJ_WRITE ||
192  IoStack->MajorFunction == IRP_MJ_FLUSH_BUFFERS);
193 
195  Irp->IoStatus.Information = 0;
196 
197  if (IoStack->MajorFunction == IRP_MJ_CREATE)
198  {
199  ok_irql(PASSIVE_LEVEL);
200 
201  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR))
202  {
204  TestFileObject = IoStack->FileObject;
205  }
206  Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI');
207  RtlZeroMemory(Fcb, sizeof(*Fcb));
208  ExInitializeFastMutex(&Fcb->HeaderMutex);
209  FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
210  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
211  IoStack->FileObject->FileName.Buffer[1] == 'B')
212  {
213  Fcb->Header.AllocationSize.QuadPart = 1000000;
214  Fcb->Header.FileSize.QuadPart = 1000000;
215  Fcb->Header.ValidDataLength.QuadPart = 1000000;
216  }
217  else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
218  IoStack->FileObject->FileName.Buffer[1] == 'S')
219  {
220  Fcb->Header.AllocationSize.QuadPart = 512;
221  Fcb->Header.FileSize.QuadPart = 512;
222  Fcb->Header.ValidDataLength.QuadPart = 512;
223  }
224  else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
225  IoStack->FileObject->FileName.Buffer[1] == 'V')
226  {
227  Fcb->Header.AllocationSize.QuadPart = 62;
228  Fcb->Header.FileSize.QuadPart = 62;
229  Fcb->Header.ValidDataLength.QuadPart = 62;
230  }
231  else
232  {
233  Fcb->Header.AllocationSize.QuadPart = 1004;
234  Fcb->Header.FileSize.QuadPart = 1004;
235  Fcb->Header.ValidDataLength.QuadPart = 1004;
236  }
237  Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
238  IoStack->FileObject->FsContext = Fcb;
239  IoStack->FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
240 
241  CcInitializeCacheMap(IoStack->FileObject,
242  (PCC_FILE_SIZES)&Fcb->Header.AllocationSize,
243  FALSE, &Callbacks, NULL);
244 
245  Irp->IoStatus.Information = FILE_OPENED;
247  }
248  else if (IoStack->MajorFunction == IRP_MJ_READ)
249  {
250  PMDL Mdl;
251  ULONG Length;
252  PVOID Buffer;
254 
255  Offset = IoStack->Parameters.Read.ByteOffset;
256  Length = IoStack->Parameters.Read.Length;
257  Fcb = IoStack->FileObject->FsContext;
258 
260  ok_eq_pointer(IoStack->FileObject, TestFileObject);
261 
262  ok(BooleanFlagOn(Irp->Flags, IRP_NOCACHE), "IRP not coming from Cc!\n");
263  ok_irql(APC_LEVEL);
264  ok((Offset.QuadPart == 0 || Offset.QuadPart == 4096 || Offset.QuadPart == 8192), "Unexpected offset: %I64i\n", Offset.QuadPart);
265  ok(Length % PAGE_SIZE == 0, "Length is not aligned: %I64i\n", Length);
266 
267  ok(Irp->AssociatedIrp.SystemBuffer == NULL, "A SystemBuffer was allocated!\n");
269  ok(Buffer != NULL, "Null pointer!\n");
270  RtlFillMemory(Buffer, Length, 0xBA);
271 
273 
274  Mdl = Irp->MdlAddress;
275  ok(Mdl != NULL, "Null pointer for MDL!\n");
276  ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) != 0, "MDL not locked\n");
277  ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0, "MDL from non paged\n");
278  ok((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0, "Non paging IO\n");
279  ok((Irp->Flags & IRP_PAGING_IO) != 0, "Non paging IO\n");
280 
281  Irp->IoStatus.Information = Length;
282  IoStack->FileObject->CurrentByteOffset.QuadPart = Offset.QuadPart + Length;
283  }
284  else if (IoStack->MajorFunction == IRP_MJ_WRITE)
285  {
286  PMDL Mdl;
287  ULONG Length;
288  PVOID Buffer;
290 
291  Offset = IoStack->Parameters.Read.ByteOffset;
292  Length = IoStack->Parameters.Read.Length;
293  Fcb = IoStack->FileObject->FsContext;
294 
295  if (!FlagOn(Irp->Flags, IRP_NOCACHE))
296  {
297  BOOLEAN Ret;
298 
299  ok_irql(PASSIVE_LEVEL);
300 
301  Buffer = Irp->AssociatedIrp.SystemBuffer;
302  ok(Buffer != NULL, "Null pointer!\n");
303 
304  Fcb->WriteLength = Length;
305 
306  _SEH2_TRY
307  {
308  Ret = CcCopyWrite(IoStack->FileObject, &Offset, Length, TRUE, Buffer);
309  ok_bool_true(Ret, "CcCopyWrite");
310  }
312  {
313  Irp->IoStatus.Status = _SEH2_GetExceptionCode();
314  }
315  _SEH2_END;
316 
317  Status = Irp->IoStatus.Status;
318  }
319  else
320  {
321  ok_irql(PASSIVE_LEVEL);
322  ok((Offset.QuadPart == 0 || Offset.QuadPart == 4096), "Unexpected offset: %I64i\n", Offset.QuadPart);
323  ok_eq_ulong(Length, ROUND_TO_PAGES(Fcb->WriteLength));
324 
325  ok(Irp->AssociatedIrp.SystemBuffer == NULL, "A SystemBuffer was allocated!\n");
327  ok(Buffer != NULL, "Null pointer!\n");
328 
330 
331  Mdl = Irp->MdlAddress;
332  ok(Mdl != NULL, "Null pointer for MDL!\n");
333  ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) != 0, "MDL not locked\n");
334  ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0, "MDL from non paged\n");
335  ok((Mdl->MdlFlags & MDL_IO_PAGE_READ) == 0, "MDL for read paging IO\n");
336  ok((Irp->Flags & IRP_PAGING_IO) != 0, "Non paging IO\n");
337  }
338  }
339  else if (IoStack->MajorFunction == IRP_MJ_FLUSH_BUFFERS)
340  {
342 
343  Fcb = IoStack->FileObject->FsContext;
345 
347  }
348  else if (IoStack->MajorFunction == IRP_MJ_CLEANUP)
349  {
350  ok_irql(PASSIVE_LEVEL);
351  KeInitializeEvent(&CacheUninitEvent.Event, NotificationEvent, FALSE);
352  CcUninitializeCacheMap(IoStack->FileObject, &Zero, &CacheUninitEvent);
353  KeWaitForSingleObject(&CacheUninitEvent.Event, Executive, KernelMode, FALSE, NULL);
354  Fcb = IoStack->FileObject->FsContext;
355  ExFreePoolWithTag(Fcb, 'FwrI');
356  IoStack->FileObject->FsContext = NULL;
358  }
359 
360  if (Status == STATUS_PENDING)
361  {
365  }
366  else
367  {
368  Irp->IoStatus.Status = Status;
370  }
371 
372  return Status;
373 }
#define MDL_IO_PAGE_READ
Definition: mmtypes.h:24
#define ok_eq_ulong(value, expected)
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define LL
Definition: tui.h:84
#define IRP_MJ_FLUSH_BUFFERS
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
PFILE_OBJECT FileObject
Definition: ntfs.h:516
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2659
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define ok_eq_pointer(value, expected)
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_OPENED
Definition: nt_native.h:769
#define IRP_NOCACHE
static PDEVICE_OBJECT TestDeviceObject
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
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:58
_SEH2_TRY
Definition: create.c:4226
VOID TestUnload(_In_ PDRIVER_OBJECT DriverObject)
#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:416
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
static PVOID MapAndLockUserBuffer(_In_ _Out_ PIRP Irp, _In_ ULONG BufferLength)
#define FALSE
Definition: types.h:117
ULONG WriteLength
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
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 NTAPI ReleaseFromLazyWrite(_In_ PVOID Context)
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
NTSTATUS KmtRegisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler)
FAST_MUTEX
Definition: extypes.h:17
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2659
_In_z_ PWSTR RegistryPath
Definition: classp.h:1930
static FAST_IO_DISPATCH TestFastIoDispatch
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
BOOLEAN NTAPI AcquireForReadAhead(_In_ PVOID Context, _In_ BOOLEAN Wait)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
_In_ UCHAR BufferLength
Definition: scsi.h:4067
#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:195
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
SECTION_OBJECT_POINTERS SectionObjectPointers
#define _Inout_
Definition: no_sal2.h:244
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1978
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS TestEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PCUNICODE_STRING RegistryPath, _Out_ PCWSTR *DeviceName, _Inout_ INT *Flags)
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
FSRTL_ADVANCED_FCB_HEADER Header
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129
#define _In_
Definition: no_sal2.h:204
VOID NTAPI ReleaseFromReadAhead(_In_ PVOID Context)
PFAST_IO_READ FastIoRead
Definition: iotypes.h:1715
_SEH2_END
Definition: create.c:4400
static CACHE_MANAGER_CALLBACKS Callbacks
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
PFAST_IO_WRITE FastIoWrite
Definition: iotypes.h:1716
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:935
static KMT_IRP_HANDLER TestIrpHandler
#define ROUND_TO_PAGES(Size)
BOOLEAN NTAPI AcquireForLazyWrite(_In_ PVOID Context, _In_ BOOLEAN Wait)
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define ok(value,...)
Definition: atltest.h:57
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define IRP_PAGING_IO
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:411
#define IRP_MJ_READ
Definition: rdpdr.c:46
FAST_MUTEX HeaderMutex
struct _FAST_IO_DISPATCH * FastIoDispatch
Definition: iotypes.h:2265
#define IRP_MJ_CLEANUP
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
_In_ PFCB Fcb
Definition: cdprocs.h:159
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
struct _TEST_FCB TEST_FCB
return STATUS_SUCCESS
Definition: btrfs.c:3014
IoMarkIrpPending(Irp)
#define APC_LEVEL
Definition: env_spec_w32.h:695
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:514
static BOOLEAN NTAPI FastIoWrite(_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)
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)
#define PAGED_CODE()
IN BOOLEAN Wait
Definition: fatprocs.h:1538
struct _TEST_FCB * PTEST_FCB
static PFILE_OBJECT TestFileObject