ReactOS  0.4.14-dev-831-gef8c9239
IoReadWrite_user.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 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 static
12 VOID
16  _In_ BOOLEAN UseFastIo,
17  _In_ BOOLEAN ReturnPending)
18 {
22  UCHAR Buffer[32];
24  ULONG BaseKey, StatusKey, Key;
25  DWORD WaitStatus;
26 
27  BaseKey = (UseFastIo ? KEY_USE_FASTIO : 0) |
28  (ReturnPending ? KEY_RETURN_PENDING : 0);
29 
31  ok(EventHandle != NULL, "CreateEvent failed with %lu\n", GetLastError());
32 
33  for (StatusKey = KEY_SUCCEED ; StatusKey != 0xff; StatusKey = KEY_NEXT(StatusKey))
34  {
35  //trace("\tSTATUS KEY: %lx\n", StatusKey);
37  RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
38  Key = BaseKey | StatusKey | KEY_DATA(0x11);
39  Offset.QuadPart = 0;
42  NULL,
43  NULL,
44  &IoStatus,
45  NULL,
46  0,
47  &Offset,
48  &Key);
49  WaitStatus = WaitForSingleObject(EventHandle, 0);
50  if (ReturnPending)
52  else
54  if (Cached && UseFastIo && !ReturnPending)
55  {
56  ok_eq_ulong(WaitStatus, WAIT_OBJECT_0);
59  }
60  else
61  {
62  ok_eq_ulong(WaitStatus, WAIT_TIMEOUT);
63  ok_eq_hex(IoStatus.Status, 0x55555555);
64  ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555);
65  }
66 
67  KmtStartSeh()
69  RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
70  Key = BaseKey | StatusKey | KEY_DATA(0x22);
71  Offset.QuadPart = 0;
74  NULL,
75  NULL,
76  &IoStatus,
77  NULL,
78  sizeof(Buffer),
79  &Offset,
80  &Key);
81  WaitStatus = WaitForSingleObject(EventHandle, 0);
82  ok_eq_ulong(WaitStatus, WAIT_TIMEOUT);
84  ok_eq_hex(IoStatus.Status, 0x55555555);
85  ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555);
87 
89  RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
90  RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
91  Key = BaseKey | StatusKey | KEY_DATA(0x33);
92  Offset.QuadPart = 0;
95  NULL,
96  NULL,
97  &IoStatus,
98  Buffer,
99  0,
100  &Offset,
101  &Key);
102  WaitStatus = WaitForSingleObject(EventHandle, 0);
103  if (ReturnPending)
105  else
107  if (Cached && UseFastIo && !ReturnPending)
108  {
109  ok_eq_ulong(WaitStatus, WAIT_OBJECT_0);
111  ok_eq_ulongptr(IoStatus.Information, TEST_FILE_SIZE);
112  }
113  else
114  {
115  ok_eq_ulong(WaitStatus, WAIT_TIMEOUT);
116  ok_eq_hex(IoStatus.Status, 0x55555555);
117  ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555);
118  }
119  ok_eq_uint(Buffer[0], 0x55);
120 
122  RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
123  RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
124  Key = BaseKey | StatusKey | KEY_DATA(0x44);
125  Offset.QuadPart = 0;
127  EventHandle,
128  NULL,
129  NULL,
130  &IoStatus,
131  Buffer,
132  sizeof(Buffer),
133  &Offset,
134  &Key);
135  WaitStatus = WaitForSingleObject(EventHandle, 0);
136  ok_eq_hex(Status, TestGetReturnStatus(StatusKey));
137  if ((Cached && UseFastIo && !ReturnPending &&
138  (StatusKey == KEY_SUCCEED || StatusKey == KEY_FAIL_OVERFLOW || StatusKey == KEY_FAIL_EOF)) ||
139  !KEY_ERROR(StatusKey))
140  {
141  ok_eq_ulong(WaitStatus, WAIT_OBJECT_0);
142  ok_eq_hex(IoStatus.Status, TestGetReturnStatus(StatusKey));
143  ok_eq_ulongptr(IoStatus.Information, TEST_FILE_SIZE);
144  }
145  else
146  {
147  ok_eq_ulong(WaitStatus, WAIT_TIMEOUT);
148  ok_eq_hex(IoStatus.Status, 0x55555555);
149  ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555);
150  }
151  if ((StatusKey != KEY_FAIL_VERIFY_REQUIRED && !KEY_ERROR(StatusKey)) ||
152  Cached)
153  {
154  ok_eq_uint(Buffer[0], 0x44);
155  ok_eq_uint(Buffer[TEST_FILE_SIZE - 1], 0x44);
157  }
158  else
159  {
160  ok_eq_uint(Buffer[0], 0x55);
161  }
162  }
163 }
164 
165 static
166 VOID
170  _In_ BOOLEAN UseFastIo,
171  _In_ BOOLEAN ReturnPending)
172 {
176  UCHAR Buffer[32];
178  ULONG BaseKey, StatusKey, Key;
179  DWORD WaitStatus;
180 
181  BaseKey = (UseFastIo ? KEY_USE_FASTIO : 0) |
182  (ReturnPending ? KEY_RETURN_PENDING : 0);
183 
185  ok(EventHandle != NULL, "CreateEvent failed with %lu\n", GetLastError());
186 
187  for (StatusKey = KEY_SUCCEED ; StatusKey != 0xff; StatusKey = KEY_NEXT(StatusKey))
188  {
189  //trace("\tSTATUS KEY: %lx\n", StatusKey);
191  RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
192  Key = BaseKey | StatusKey | KEY_DATA(0x11);
193  Offset.QuadPart = 0;
195  EventHandle,
196  NULL,
197  NULL,
198  &IoStatus,
199  NULL,
200  0,
201  &Offset,
202  &Key);
203  WaitStatus = WaitForSingleObject(EventHandle, 0);
204  ok_eq_hex(Status, TestGetReturnStatus(StatusKey));
205  if (!KEY_ERROR(StatusKey))
206  {
207  ok_eq_ulong(WaitStatus, WAIT_OBJECT_0);
208  ok_eq_hex(IoStatus.Status, TestGetReturnStatus(StatusKey));
209  ok_eq_ulongptr(IoStatus.Information, 0);
210  }
211  else
212  {
213  ok_eq_ulong(WaitStatus, WAIT_TIMEOUT);
214  ok_eq_hex(IoStatus.Status, 0x55555555);
215  ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555);
216  }
217 
218  KmtStartSeh()
220  RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
221  Key = BaseKey | StatusKey | KEY_DATA(0x22);
222  Offset.QuadPart = 0;
224  EventHandle,
225  NULL,
226  NULL,
227  &IoStatus,
228  NULL,
229  sizeof(Buffer),
230  &Offset,
231  &Key);
232  WaitStatus = WaitForSingleObject(EventHandle, 0);
233  ok_eq_ulong(WaitStatus, WAIT_TIMEOUT);
235  ok_eq_hex(IoStatus.Status, 0x55555555);
236  ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555);
238 
240  RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
241  RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
242  Key = BaseKey | StatusKey | KEY_DATA(0x33);
243  Offset.QuadPart = 0;
245  EventHandle,
246  NULL,
247  NULL,
248  &IoStatus,
249  Buffer,
250  0,
251  &Offset,
252  &Key);
253  WaitStatus = WaitForSingleObject(EventHandle, 0);
254  ok_eq_hex(Status, TestGetReturnStatus(StatusKey));
255  if (!KEY_ERROR(StatusKey))
256  {
257  ok_eq_ulong(WaitStatus, WAIT_OBJECT_0);
258  ok_eq_hex(IoStatus.Status, TestGetReturnStatus(StatusKey));
259  ok_eq_ulongptr(IoStatus.Information, 0);
260  }
261  else
262  {
263  ok_eq_ulong(WaitStatus, WAIT_TIMEOUT);
264  ok_eq_hex(IoStatus.Status, 0x55555555);
265  ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555);
266  }
267 
269  RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
270  RtlFillMemory(Buffer, sizeof(Buffer), 0x44);
271  Key = BaseKey | StatusKey | KEY_DATA(0x44);
272  Offset.QuadPart = 0;
274  EventHandle,
275  NULL,
276  NULL,
277  &IoStatus,
278  Buffer,
279  sizeof(Buffer),
280  &Offset,
281  &Key);
282  WaitStatus = WaitForSingleObject(EventHandle, 0);
283  ok_eq_hex(Status, TestGetReturnStatus(StatusKey));
284  if (!KEY_ERROR(StatusKey))
285  {
286  ok_eq_ulong(WaitStatus, WAIT_OBJECT_0);
287  ok_eq_hex(IoStatus.Status, TestGetReturnStatus(StatusKey));
288  ok_eq_ulongptr(IoStatus.Information, sizeof(Buffer));
289  }
290  else
291  {
292  ok_eq_ulong(WaitStatus, WAIT_TIMEOUT);
293  ok_eq_hex(IoStatus.Status, 0x55555555);
294  ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555);
295  }
296  }
297 }
298 
299 START_TEST(IoReadWrite)
300 {
302  UNICODE_STRING CachedFileName = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-IoReadWrite\\Cached");
303  UNICODE_STRING NonCachedFileName = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-IoReadWrite\\NonCached");
307 
308  KmtLoadDriver(L"IoReadWrite", FALSE);
309  KmtOpenDriver();
310 
311  RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
313  &NonCachedFileName,
315  NULL,
316  NULL);
320  &IoStatus,
321  0,
325  if (!skip(NT_SUCCESS(Status), "No file\n"))
326  {
328  ok_eq_ulongptr(IoStatus.Information, FILE_OPENED);
329  trace("Non-Cached read, no FastIo, direct return\n");
331  trace("Non-Cached read, allow FastIo, direct return\n");
333  trace("Non-Cached read, no FastIo, pending return\n");
335  trace("Non-Cached read, allow FastIo, pending return\n");
337 
338  trace("Non-Cached write, no FastIo, direct return\n");
340  trace("Non-Cached write, allow FastIo, direct return\n");
342  trace("Non-Cached write, no FastIo, pending return\n");
344  trace("Non-Cached write, allow FastIo, pending return\n");
347  }
348 
349  RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
351  &CachedFileName,
353  NULL,
354  NULL);
358  &IoStatus,
359  0,
363  if (!skip(NT_SUCCESS(Status), "No file\n"))
364  {
366  ok_eq_ulongptr(IoStatus.Information, FILE_OPENED);
367  trace("Cached read, no FastIo, direct return\n");
369  trace("Cached read, allow FastIo, direct return\n");
371  trace("Cached read, no FastIo, pending return\n");
373  trace("Cached read, allow FastIo, pending return\n");
375 
376  trace("Cached write, no FastIo, direct return\n");
378  trace("Cached write, allow FastIo, direct return\n");
380  trace("Cached write, no FastIo, pending return\n");
382  trace("Cached write, allow FastIo, pending return\n");
385  }
386 
387  KmtCloseDriver();
388  KmtUnloadDriver();
389 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define ok_eq_ulong(value, expected)
static VOID TestWrite(_In_ HANDLE FileHandle, _In_ BOOLEAN Cached, _In_ BOOLEAN UseFastIo, _In_ BOOLEAN ReturnPending)
#define TRUE
Definition: types.h:120
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG Key
Definition: fatprocs.h:2697
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
#define KEY_FAIL_OVERFLOW
Definition: IoReadWrite.h:19
#define KEY_DATA(c)
Definition: IoReadWrite.h:88
LONG NTSTATUS
Definition: precomp.h:26
#define KmtEndSeh(ExpectedStatus)
Definition: kmt_test.h:283
#define FILE_OPENED
Definition: nt_native.h:769
#define ok_eq_ulongptr(value, expected)
Definition: kmt_test.h:249
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define KEY_ERROR(key)
Definition: IoReadWrite.h:38
_In_ ULONG _In_ BOOLEAN Cached
Definition: ndis.h:3788
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
#define KEY_RETURN_PENDING
Definition: IoReadWrite.h:86
uint32_t ULONG_PTR
Definition: typedefs.h:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE FileHandle
Definition: stats.c:38
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3951
#define TEST_FILE_SIZE
Definition: IoReadWrite.h:11
VOID KmtCloseDriver(VOID)
Definition: support.c:200
#define WAIT_OBJECT_0
Definition: winbase.h:387
#define trace
Definition: atltest.h:70
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KEY_SUCCEED
Definition: IoReadWrite.h:13
#define KEY_FAIL_VERIFY_REQUIRED
Definition: IoReadWrite.h:22
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define WAIT_TIMEOUT
Definition: dderror.h:14
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define KmtStartSeh()
Definition: kmt_test.h:277
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
VOID KmtUnloadDriver(VOID)
Definition: support.c:155
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
#define ok(value,...)
Definition: atltest.h:57
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
#define KEY_USE_FASTIO
Definition: IoReadWrite.h:85
#define skip(...)
Definition: atltest.h:64
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define KEY_NEXT(key)
Definition: IoReadWrite.h:33
#define KEY_FAIL_EOF
Definition: IoReadWrite.h:28
unsigned int ULONG
Definition: retypes.h:1
static NTSTATUS TestGetReturnStatus(_In_ ULONG LockKey)
Definition: IoReadWrite.h:41
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define ok_eq_hex(value, expected)
#define ok_eq_uint(value, expected)
Definition: kmt_test.h:239
VOID KmtLoadDriver(IN PCWSTR ServiceName, IN BOOLEAN RestartIfRunning)
Definition: support.c:127
START_TEST(IoReadWrite)
VOID KmtOpenDriver(VOID)
Definition: support.c:174
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
static VOID TestRead(_In_ HANDLE FileHandle, _In_ BOOLEAN Cached, _In_ BOOLEAN UseFastIo, _In_ BOOLEAN ReturnPending)
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:855