ReactOS  0.4.14-dev-999-g61c8d34
IoReadWrite_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 Read/Write operations
5  * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 #include "IoReadWrite.h"
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 typedef struct _TEST_FCB
15 {
21 
22 static KMT_IRP_HANDLER TestIrpHandler;
23 static FAST_IO_READ TestFastIoRead;
24 static FAST_IO_WRITE TestFastIoWrite;
25 
31 
37  _Inout_ INT *Flags)
38 {
40 
41  PAGED_CODE();
42 
44 
45  *DeviceName = L"IoReadWrite";
46  *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE |
47  TESTENTRY_BUFFERED_IO_DEVICE |
48  TESTENTRY_NO_READONLY_DEVICE;
49 
53 
58 
59  return Status;
60 }
61 
62 VOID
65 {
66  PAGED_CODE();
67 }
68 
69 static
70 BOOLEAN
71 NTAPI
75 {
77  ok(0, "Unexpected call to AcquireForLazyWrite\n");
78  return TRUE;
79 }
80 
81 static
82 VOID
83 NTAPI
86 {
88  ok(0, "Unexpected call to ReleaseFromLazyWrite\n");
89 }
90 
91 static
92 BOOLEAN
93 NTAPI
97 {
99  ok(0, "Unexpected call to AcquireForReadAhead\n");
100  return TRUE;
101 }
102 
103 static
104 VOID
105 NTAPI
108 {
110  ok(0, "Unexpected call to ReleaseFromReadAhead\n");
111 }
112 
113 static
114 NTSTATUS
116  _In_ PVOID Buffer,
117  _In_ ULONG Length,
121 {
122  if (FileOffset >= TEST_FILE_SIZE)
123  {
124  trace("FileOffset %I64d > file size\n", FileOffset);
125  IoStatus->Status = STATUS_END_OF_FILE;
126  IoStatus->Information = 0;
127  }
128  else if (Length == 0 || Buffer == NULL)
129  {
131  IoStatus->Information = TEST_FILE_SIZE - FileOffset;
132  }
133  else
134  {
138  IoStatus->Information = Length;
139  }
141  return STATUS_PENDING;
142  return IoStatus->Status;
143 }
144 
145 static
146 BOOLEAN
147 NTAPI
151  _In_ ULONG Length,
152  _In_ BOOLEAN Wait,
157 {
158  PTEST_FCB Fcb;
160 
161  //trace("FastIoRead: %p %lx %I64d+%lu -> %p\n", FileObject, LockKey, FileOffset->QuadPart, Length, Buffer);
163  ok_bool_true(Wait, "Wait is");
165  Fcb = FileObject->FsContext;
166  ok_bool_true(Fcb->Cached, "Cached is");
167 
169  ok((ULONG_PTR)Buffer < MM_USER_PROBE_ADDRESS, "Buffer is %p\n", Buffer);
170  ok((ULONG_PTR)FileOffset > MM_USER_PROBE_ADDRESS, "FileOffset is %p\n", FileOffset);
171  ok((ULONG_PTR)IoStatus > MM_USER_PROBE_ADDRESS, "IoStatus is %p\n", IoStatus);
172  _SEH2_TRY
173  {
175  }
177  {
178  IoStatus->Status = _SEH2_GetExceptionCode();
179  return FALSE;
180  }
181  _SEH2_END;
182 
183  if (Status == STATUS_PENDING)
184  return FALSE;
185 
186  if (LockKey & KEY_USE_FASTIO)
187  return TRUE;
188  else
189  return FALSE;
190 }
191 
192 static
193 NTSTATUS
195  _In_ PVOID Buffer,
196  _In_ ULONG Length,
200 {
201  ULONG i;
202  PUCHAR BufferBytes = Buffer;
203 
204  for (i = 0; i < Length; i++)
205  ok(BufferBytes[i] == KEY_GET_DATA(LockKey), "Buffer[%lu] = 0x%x, expected 0x%x\n", i, BufferBytes[i], KEY_GET_DATA(LockKey));
207  IoStatus->Information = Length;
208 
210  return STATUS_PENDING;
211  return IoStatus->Status;
212 }
213 
214 static
215 BOOLEAN
216 NTAPI
220  _In_ ULONG Length,
221  _In_ BOOLEAN Wait,
223  _In_ PVOID Buffer,
226 {
227  PTEST_FCB Fcb;
229 
230  //trace("FastIoWrite: %p %lx %p -> %I64d+%lu\n", FileObject, LockKey, Buffer, FileOffset->QuadPart, Length);
232  ok_bool_true(Wait, "Wait is");
234  Fcb = FileObject->FsContext;
235  ok_bool_true(Fcb->Cached, "Cached is");
236 
238  ok((ULONG_PTR)Buffer < MM_USER_PROBE_ADDRESS, "Buffer is %p\n", Buffer);
239  ok((ULONG_PTR)FileOffset > MM_USER_PROBE_ADDRESS, "FileOffset is %p\n", FileOffset);
240  ok((ULONG_PTR)IoStatus > MM_USER_PROBE_ADDRESS, "IoStatus is %p\n", IoStatus);
241  _SEH2_TRY
242  {
244  }
246  {
247  IoStatus->Status = _SEH2_GetExceptionCode();
248  return FALSE;
249  }
250  _SEH2_END;
251 
252  if (Status == STATUS_PENDING)
253  return FALSE;
254 
255  if (LockKey & KEY_USE_FASTIO)
256  return TRUE;
257  else
258  return FALSE;
259 }
260 
261 static
262 NTSTATUS
265  _In_ PIRP Irp,
266  _In_ PIO_STACK_LOCATION IoStack)
267 {
269  PTEST_FCB Fcb;
271  CACHE_UNINITIALIZE_EVENT CacheUninitEvent;
272 
273  PAGED_CODE();
274 
275  DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction);
276  ASSERT(IoStack->MajorFunction == IRP_MJ_CREATE ||
277  IoStack->MajorFunction == IRP_MJ_CLEANUP ||
278  IoStack->MajorFunction == IRP_MJ_READ ||
279  IoStack->MajorFunction == IRP_MJ_WRITE);
280 
282  Irp->IoStatus.Information = 0;
283 
284  if (IoStack->MajorFunction == IRP_MJ_CREATE)
285  {
286  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR))
287  {
289  TestFileObject = IoStack->FileObject;
290  }
291  Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI');
292  RtlZeroMemory(Fcb, sizeof(*Fcb));
293  ExInitializeFastMutex(&Fcb->HeaderMutex);
294  FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
295  Fcb->Header.AllocationSize.QuadPart = TEST_FILE_SIZE;
296  Fcb->Header.FileSize.QuadPart = TEST_FILE_SIZE;
297  Fcb->Header.ValidDataLength.QuadPart = TEST_FILE_SIZE;
298  IoStack->FileObject->FsContext = Fcb;
299  IoStack->FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
300  if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
301  IoStack->FileObject->FileName.Buffer[1] != 'N')
302  {
303  Fcb->Cached = TRUE;
304  Callbacks.AcquireForLazyWrite = TestAcquireForLazyWrite;
305  Callbacks.ReleaseFromLazyWrite = TestReleaseFromLazyWrite;
306  Callbacks.AcquireForReadAhead = TestAcquireForReadAhead;
307  Callbacks.ReleaseFromReadAhead = TestReleaseFromReadAhead;
308  CcInitializeCacheMap(IoStack->FileObject,
309  (PCC_FILE_SIZES)&Fcb->Header.AllocationSize,
310  FALSE,
311  &Callbacks,
312  NULL);
313  }
314  Irp->IoStatus.Information = FILE_OPENED;
316  }
317  else if (IoStack->MajorFunction == IRP_MJ_CLEANUP)
318  {
319  KeInitializeEvent(&CacheUninitEvent.Event, NotificationEvent, FALSE);
320  CcUninitializeCacheMap(IoStack->FileObject, NULL, &CacheUninitEvent);
321  KeWaitForSingleObject(&CacheUninitEvent.Event, Executive, KernelMode, FALSE, NULL);
322  Fcb = IoStack->FileObject->FsContext;
323  ExFreePoolWithTag(Fcb, 'FwrI');
324  IoStack->FileObject->FsContext = NULL;
326  }
327  else if (IoStack->MajorFunction == IRP_MJ_READ)
328  {
329  //trace("IRP_MJ_READ: %p %lx %I64d+%lu -> %p\n", IoStack->FileObject, IoStack->Parameters.Read.Key, IoStack->Parameters.Read.ByteOffset.QuadPart, IoStack->Parameters.Read.Length, Irp->AssociatedIrp.SystemBuffer);
331  ok_eq_pointer(IoStack->FileObject, TestFileObject);
332  Fcb = IoStack->FileObject->FsContext;
333  if (Fcb->Cached)
334  ok_eq_hex(IoStack->Parameters.Read.Key, TestLastFastReadKey);
335  ok(Irp->AssociatedIrp.SystemBuffer == NULL ||
336  (ULONG_PTR)Irp->AssociatedIrp.SystemBuffer > MM_USER_PROBE_ADDRESS,
337  "Buffer is %p\n",
338  Irp->AssociatedIrp.SystemBuffer);
339  Status = TestCommonRead(Irp->AssociatedIrp.SystemBuffer,
340  IoStack->Parameters.Read.Length,
341  IoStack->Parameters.Read.ByteOffset.QuadPart,
342  IoStack->Parameters.Read.Key,
343  &Irp->IoStatus);
344  }
345  else if (IoStack->MajorFunction == IRP_MJ_WRITE)
346  {
347  //trace("IRP_MJ_WRITE: %p %lx %I64d+%lu -> %p\n", IoStack->FileObject, IoStack->Parameters.Write.Key, IoStack->Parameters.Write.ByteOffset.QuadPart, IoStack->Parameters.Write.Length, Irp->AssociatedIrp.SystemBuffer);
349  ok_eq_pointer(IoStack->FileObject, TestFileObject);
350  Fcb = IoStack->FileObject->FsContext;
351  if (Fcb->Cached)
352  ok_eq_hex(IoStack->Parameters.Write.Key, TestLastFastWriteKey);
353  ok(Irp->AssociatedIrp.SystemBuffer == NULL ||
354  (ULONG_PTR)Irp->AssociatedIrp.SystemBuffer > MM_USER_PROBE_ADDRESS,
355  "Buffer is %p\n",
356  Irp->AssociatedIrp.SystemBuffer);
357  Status = TestCommonWrite(Irp->AssociatedIrp.SystemBuffer,
358  IoStack->Parameters.Write.Length,
359  IoStack->Parameters.Write.ByteOffset.QuadPart,
360  IoStack->Parameters.Write.Key,
361  &Irp->IoStatus);
362  }
363 
364  if (Status == STATUS_PENDING)
365  {
369  }
370  else
371  {
372  Irp->IoStatus.Status = Status;
374  }
375 
376  return Status;
377 }
const uint16_t * PCWSTR
Definition: typedefs.h:56
#define TRUE
Definition: types.h:120
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
static PDEVICE_OBJECT TestDeviceObject
#define KEY_GET_DATA(key)
Definition: IoReadWrite.h:89
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:2650
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS TestEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PCUNICODE_STRING RegistryPath, _Out_ PCWSTR *DeviceName, _Inout_ INT *Flags)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define ok_eq_pointer(value, expected)
unsigned char * PUCHAR
Definition: retypes.h:3
static KMT_IRP_HANDLER TestIrpHandler
struct _TEST_FCB TEST_FCB
LONG NTSTATUS
Definition: precomp.h:26
VOID TestUnload(_In_ PDRIVER_OBJECT DriverObject)
#define FILE_OPENED
Definition: nt_native.h:769
WCHAR DeviceName[]
Definition: adapter.cpp:21
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:57
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
#define KEY_RETURN_PENDING
Definition: IoReadWrite.h:86
#define STATUS_END_OF_FILE
Definition: shellext.h:67
uint32_t ULONG_PTR
Definition: typedefs.h:64
static BOOLEAN NTAPI TestAcquireForReadAhead(_In_ PVOID Context, _In_ BOOLEAN Wait)
#define ok_bool_true(value, desc)
Definition: kmt_test.h:256
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
static FAST_IO_READ TestFastIoRead
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _Out_
Definition: no_sal2.h:323
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
NTSTATUS KmtRegisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler)
FAST_MUTEX
Definition: extypes.h:17
static FAST_IO_WRITE TestFastIoWrite
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2650
int64_t LONGLONG
Definition: typedefs.h:67
#define TEST_FILE_SIZE
Definition: IoReadWrite.h:11
#define trace
Definition: atltest.h:70
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
__wchar_t WCHAR
Definition: xmlstorage.h:180
#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
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define MM_USER_PROBE_ADDRESS
Definition: armddk.h:19
SECTION_OBJECT_POINTERS SectionObjectPointers
#define _Inout_
Definition: no_sal2.h:244
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static VOID NTAPI TestReleaseFromLazyWrite(_In_ PVOID Context)
* PFILE_OBJECT
Definition: iotypes.h:1955
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
static FAST_IO_DISPATCH TestFastIoDispatch
FSRTL_ADVANCED_FCB_HEADER Header
BOOLEAN Cached
static ULONG TestLastFastReadKey
static NTSTATUS TestCommonWrite(_In_ PVOID Buffer, _In_ ULONG Length, _In_ LONGLONG FileOffset, _In_ ULONG LockKey, _Out_ PIO_STATUS_BLOCK IoStatus)
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
PFAST_IO_READ FastIoRead
Definition: iotypes.h:1692
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
_SEH2_END
Definition: create.c:4424
static NTSTATUS TestCommonRead(_In_ PVOID Buffer, _In_ ULONG Length, _In_ LONGLONG FileOffset, _In_ ULONG LockKey, _Out_ PIO_STATUS_BLOCK IoStatus)
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
PFAST_IO_WRITE FastIoWrite
Definition: iotypes.h:1693
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:284
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define ok(value,...)
Definition: atltest.h:57
#define min(a, b)
Definition: monoChain.cc:55
#define KEY_USE_FASTIO
Definition: IoReadWrite.h:85
#define IRP_MJ_READ
Definition: rdpdr.c:46
FAST_MUTEX HeaderMutex
struct _FAST_IO_DISPATCH * FastIoDispatch
Definition: iotypes.h:2177
static BOOLEAN NTAPI TestAcquireForLazyWrite(_In_ PVOID Context, _In_ BOOLEAN Wait)
#define IRP_MJ_CLEANUP
static ULONG TestLastFastWriteKey
static PFILE_OBJECT TestFileObject
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
static NTSTATUS TestGetReturnStatus(_In_ ULONG LockKey)
Definition: IoReadWrite.h:41
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:28
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ok_eq_hex(value, expected)
static VOID NTAPI TestReleaseFromReadAhead(_In_ PVOID Context)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
_In_ PFCB Fcb
Definition: cdprocs.h:151
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
IoMarkIrpPending(Irp)
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:514
struct _TEST_FCB * PTEST_FCB
IN BOOLEAN Wait
Definition: fatprocs.h:1529