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>
9 #include "IoReadWrite.h"
14 _In_ HANDLE FileHandle
,
16 _In_ BOOLEAN UseFastIo
,
17 _In_ BOOLEAN ReturnPending
)
20 IO_STATUS_BLOCK IoStatus
;
24 ULONG BaseKey
, StatusKey
, Key
;
27 BaseKey
= (UseFastIo
? KEY_USE_FASTIO
: 0) |
28 (ReturnPending
? KEY_RETURN_PENDING
: 0);
30 EventHandle
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
31 ok(EventHandle
!= NULL
, "CreateEvent failed with %lu\n", GetLastError());
33 for (StatusKey
= KEY_SUCCEED
; StatusKey
!= 0xff; StatusKey
= KEY_NEXT(StatusKey
))
35 //trace("\tSTATUS KEY: %lx\n", StatusKey);
36 ResetEvent(EventHandle
);
37 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
38 Key
= BaseKey
| StatusKey
| KEY_DATA(0x11);
40 Status
= NtReadFile(FileHandle
,
49 WaitStatus
= WaitForSingleObject(EventHandle
, 0);
51 ok_eq_hex(Status
, STATUS_ACCESS_VIOLATION
);
53 ok_eq_hex(Status
, STATUS_BUFFER_OVERFLOW
);
54 if (Cached
&& UseFastIo
&& !ReturnPending
)
56 ok_eq_ulong(WaitStatus
, WAIT_OBJECT_0
);
57 ok_eq_hex(IoStatus
.Status
, STATUS_BUFFER_OVERFLOW
);
58 ok_eq_ulongptr(IoStatus
.Information
, TEST_FILE_SIZE
);
62 ok_eq_ulong(WaitStatus
, WAIT_TIMEOUT
);
63 ok_eq_hex(IoStatus
.Status
, 0x55555555);
64 ok_eq_ulongptr(IoStatus
.Information
, (ULONG_PTR
)0x5555555555555555);
68 ResetEvent(EventHandle
);
69 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
70 Key
= BaseKey
| StatusKey
| KEY_DATA(0x22);
72 Status
= NtReadFile(FileHandle
,
81 WaitStatus
= WaitForSingleObject(EventHandle
, 0);
82 ok_eq_ulong(WaitStatus
, WAIT_TIMEOUT
);
83 ok_eq_hex(Status
, STATUS_ACCESS_VIOLATION
);
84 ok_eq_hex(IoStatus
.Status
, 0x55555555);
85 ok_eq_ulongptr(IoStatus
.Information
, (ULONG_PTR
)0x5555555555555555);
86 KmtEndSeh(STATUS_SUCCESS
);
88 ResetEvent(EventHandle
);
89 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
90 RtlFillMemory(Buffer
, sizeof(Buffer
), 0x55);
91 Key
= BaseKey
| StatusKey
| KEY_DATA(0x33);
93 Status
= NtReadFile(FileHandle
,
102 WaitStatus
= WaitForSingleObject(EventHandle
, 0);
104 ok_eq_hex(Status
, STATUS_ACCESS_VIOLATION
);
106 ok_eq_hex(Status
, STATUS_BUFFER_OVERFLOW
);
107 if (Cached
&& UseFastIo
&& !ReturnPending
)
109 ok_eq_ulong(WaitStatus
, WAIT_OBJECT_0
);
110 ok_eq_hex(IoStatus
.Status
, STATUS_BUFFER_OVERFLOW
);
111 ok_eq_ulongptr(IoStatus
.Information
, TEST_FILE_SIZE
);
115 ok_eq_ulong(WaitStatus
, WAIT_TIMEOUT
);
116 ok_eq_hex(IoStatus
.Status
, 0x55555555);
117 ok_eq_ulongptr(IoStatus
.Information
, (ULONG_PTR
)0x5555555555555555);
119 ok_eq_uint(Buffer
[0], 0x55);
121 ResetEvent(EventHandle
);
122 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
123 RtlFillMemory(Buffer
, sizeof(Buffer
), 0x55);
124 Key
= BaseKey
| StatusKey
| KEY_DATA(0x44);
126 Status
= NtReadFile(FileHandle
,
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
))
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
);
147 ok_eq_ulong(WaitStatus
, WAIT_TIMEOUT
);
148 ok_eq_hex(IoStatus
.Status
, 0x55555555);
149 ok_eq_ulongptr(IoStatus
.Information
, (ULONG_PTR
)0x5555555555555555);
151 if ((StatusKey
!= KEY_FAIL_VERIFY_REQUIRED
&& !KEY_ERROR(StatusKey
)) ||
154 ok_eq_uint(Buffer
[0], 0x44);
155 ok_eq_uint(Buffer
[TEST_FILE_SIZE
- 1], 0x44);
156 ok_eq_uint(Buffer
[TEST_FILE_SIZE
], 0x55);
160 ok_eq_uint(Buffer
[0], 0x55);
168 _In_ HANDLE FileHandle
,
170 _In_ BOOLEAN UseFastIo
,
171 _In_ BOOLEAN ReturnPending
)
174 IO_STATUS_BLOCK IoStatus
;
177 LARGE_INTEGER Offset
;
178 ULONG BaseKey
, StatusKey
, Key
;
181 BaseKey
= (UseFastIo
? KEY_USE_FASTIO
: 0) |
182 (ReturnPending
? KEY_RETURN_PENDING
: 0);
184 EventHandle
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
185 ok(EventHandle
!= NULL
, "CreateEvent failed with %lu\n", GetLastError());
187 for (StatusKey
= KEY_SUCCEED
; StatusKey
!= 0xff; StatusKey
= KEY_NEXT(StatusKey
))
189 //trace("\tSTATUS KEY: %lx\n", StatusKey);
190 ResetEvent(EventHandle
);
191 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
192 Key
= BaseKey
| StatusKey
| KEY_DATA(0x11);
194 Status
= NtWriteFile(FileHandle
,
203 WaitStatus
= WaitForSingleObject(EventHandle
, 0);
204 ok_eq_hex(Status
, TestGetReturnStatus(StatusKey
));
205 if (!KEY_ERROR(StatusKey
))
207 ok_eq_ulong(WaitStatus
, WAIT_OBJECT_0
);
208 ok_eq_hex(IoStatus
.Status
, TestGetReturnStatus(StatusKey
));
209 ok_eq_ulongptr(IoStatus
.Information
, 0);
213 ok_eq_ulong(WaitStatus
, WAIT_TIMEOUT
);
214 ok_eq_hex(IoStatus
.Status
, 0x55555555);
215 ok_eq_ulongptr(IoStatus
.Information
, (ULONG_PTR
)0x5555555555555555);
219 ResetEvent(EventHandle
);
220 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
221 Key
= BaseKey
| StatusKey
| KEY_DATA(0x22);
223 Status
= NtWriteFile(FileHandle
,
232 WaitStatus
= WaitForSingleObject(EventHandle
, 0);
233 ok_eq_ulong(WaitStatus
, WAIT_TIMEOUT
);
234 ok_eq_hex(Status
, STATUS_ACCESS_VIOLATION
);
235 ok_eq_hex(IoStatus
.Status
, 0x55555555);
236 ok_eq_ulongptr(IoStatus
.Information
, (ULONG_PTR
)0x5555555555555555);
237 KmtEndSeh(STATUS_SUCCESS
);
239 ResetEvent(EventHandle
);
240 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
241 RtlFillMemory(Buffer
, sizeof(Buffer
), 0x55);
242 Key
= BaseKey
| StatusKey
| KEY_DATA(0x33);
244 Status
= NtWriteFile(FileHandle
,
253 WaitStatus
= WaitForSingleObject(EventHandle
, 0);
254 ok_eq_hex(Status
, TestGetReturnStatus(StatusKey
));
255 if (!KEY_ERROR(StatusKey
))
257 ok_eq_ulong(WaitStatus
, WAIT_OBJECT_0
);
258 ok_eq_hex(IoStatus
.Status
, TestGetReturnStatus(StatusKey
));
259 ok_eq_ulongptr(IoStatus
.Information
, 0);
263 ok_eq_ulong(WaitStatus
, WAIT_TIMEOUT
);
264 ok_eq_hex(IoStatus
.Status
, 0x55555555);
265 ok_eq_ulongptr(IoStatus
.Information
, (ULONG_PTR
)0x5555555555555555);
268 ResetEvent(EventHandle
);
269 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
270 RtlFillMemory(Buffer
, sizeof(Buffer
), 0x44);
271 Key
= BaseKey
| StatusKey
| KEY_DATA(0x44);
273 Status
= NtWriteFile(FileHandle
,
282 WaitStatus
= WaitForSingleObject(EventHandle
, 0);
283 ok_eq_hex(Status
, TestGetReturnStatus(StatusKey
));
284 if (!KEY_ERROR(StatusKey
))
286 ok_eq_ulong(WaitStatus
, WAIT_OBJECT_0
);
287 ok_eq_hex(IoStatus
.Status
, TestGetReturnStatus(StatusKey
));
288 ok_eq_ulongptr(IoStatus
.Information
, sizeof(Buffer
));
292 ok_eq_ulong(WaitStatus
, WAIT_TIMEOUT
);
293 ok_eq_hex(IoStatus
.Status
, 0x55555555);
294 ok_eq_ulongptr(IoStatus
.Information
, (ULONG_PTR
)0x5555555555555555);
299 START_TEST(IoReadWrite
)
302 UNICODE_STRING CachedFileName
= RTL_CONSTANT_STRING(L
"\\Device\\Kmtest-IoReadWrite\\Cached");
303 UNICODE_STRING NonCachedFileName
= RTL_CONSTANT_STRING(L
"\\Device\\Kmtest-IoReadWrite\\NonCached");
304 OBJECT_ATTRIBUTES ObjectAttributes
;
305 IO_STATUS_BLOCK IoStatus
;
308 KmtLoadDriver(L
"IoReadWrite", FALSE
);
311 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
312 InitializeObjectAttributes(&ObjectAttributes
,
314 OBJ_CASE_INSENSITIVE
,
317 Status
= NtOpenFile(&FileHandle
,
322 FILE_NON_DIRECTORY_FILE
|
323 FILE_SYNCHRONOUS_IO_NONALERT
);
324 ok_eq_hex(Status
, STATUS_SUCCESS
);
325 if (!skip(NT_SUCCESS(Status
), "No file\n"))
327 ok_eq_hex(IoStatus
.Status
, STATUS_SUCCESS
);
328 ok_eq_ulongptr(IoStatus
.Information
, FILE_OPENED
);
329 trace("Non-Cached read, no FastIo, direct return\n");
330 TestRead(FileHandle
, FALSE
, FALSE
, FALSE
);
331 trace("Non-Cached read, allow FastIo, direct return\n");
332 TestRead(FileHandle
, FALSE
, TRUE
, FALSE
);
333 trace("Non-Cached read, no FastIo, pending return\n");
334 TestRead(FileHandle
, FALSE
, FALSE
, TRUE
);
335 trace("Non-Cached read, allow FastIo, pending return\n");
336 TestRead(FileHandle
, FALSE
, TRUE
, TRUE
);
338 trace("Non-Cached write, no FastIo, direct return\n");
339 TestWrite(FileHandle
, FALSE
, FALSE
, FALSE
);
340 trace("Non-Cached write, allow FastIo, direct return\n");
341 TestWrite(FileHandle
, FALSE
, TRUE
, FALSE
);
342 trace("Non-Cached write, no FastIo, pending return\n");
343 TestWrite(FileHandle
, FALSE
, FALSE
, TRUE
);
344 trace("Non-Cached write, allow FastIo, pending return\n");
345 TestWrite(FileHandle
, FALSE
, TRUE
, TRUE
);
349 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
350 InitializeObjectAttributes(&ObjectAttributes
,
352 OBJ_CASE_INSENSITIVE
,
355 Status
= NtOpenFile(&FileHandle
,
360 FILE_NON_DIRECTORY_FILE
|
361 FILE_SYNCHRONOUS_IO_NONALERT
);
362 ok_eq_hex(Status
, STATUS_SUCCESS
);
363 if (!skip(NT_SUCCESS(Status
), "No file\n"))
365 ok_eq_hex(IoStatus
.Status
, STATUS_SUCCESS
);
366 ok_eq_ulongptr(IoStatus
.Information
, FILE_OPENED
);
367 trace("Cached read, no FastIo, direct return\n");
368 TestRead(FileHandle
, TRUE
, FALSE
, FALSE
);
369 trace("Cached read, allow FastIo, direct return\n");
370 TestRead(FileHandle
, TRUE
, TRUE
, FALSE
);
371 trace("Cached read, no FastIo, pending return\n");
372 TestRead(FileHandle
, TRUE
, FALSE
, TRUE
);
373 trace("Cached read, allow FastIo, pending return\n");
374 TestRead(FileHandle
, TRUE
, TRUE
, TRUE
);
376 trace("Cached write, no FastIo, direct return\n");
377 TestWrite(FileHandle
, TRUE
, FALSE
, FALSE
);
378 trace("Cached write, allow FastIo, direct return\n");
379 TestWrite(FileHandle
, TRUE
, TRUE
, FALSE
);
380 trace("Cached write, no FastIo, pending return\n");
381 TestWrite(FileHandle
, TRUE
, FALSE
, TRUE
);
382 trace("Cached write, allow FastIo, pending return\n");
383 TestWrite(FileHandle
, TRUE
, TRUE
, TRUE
);