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);
165 START_TEST(IoReadWrite
)
168 UNICODE_STRING CachedFileName
= RTL_CONSTANT_STRING(L
"\\Device\\Kmtest-IoReadWrite\\Cached");
169 UNICODE_STRING NonCachedFileName
= RTL_CONSTANT_STRING(L
"\\Device\\Kmtest-IoReadWrite\\NonCached");
170 OBJECT_ATTRIBUTES ObjectAttributes
;
171 IO_STATUS_BLOCK IoStatus
;
174 KmtLoadDriver(L
"IoReadWrite", FALSE
);
177 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
178 InitializeObjectAttributes(&ObjectAttributes
,
180 OBJ_CASE_INSENSITIVE
,
183 Status
= NtOpenFile(&FileHandle
,
188 FILE_NON_DIRECTORY_FILE
|
189 FILE_SYNCHRONOUS_IO_NONALERT
);
190 ok_eq_hex(Status
, STATUS_SUCCESS
);
191 if (!skip(NT_SUCCESS(Status
), "No file\n"))
193 ok_eq_hex(IoStatus
.Status
, STATUS_SUCCESS
);
194 ok_eq_ulongptr(IoStatus
.Information
, FILE_OPENED
);
195 trace("Non-Cached, no FastIo, direct return\n");
196 TestRead(FileHandle
, FALSE
, FALSE
, FALSE
);
197 trace("Non-Cached, allow FastIo, direct return\n");
198 TestRead(FileHandle
, FALSE
, TRUE
, FALSE
);
199 trace("Non-Cached, no FastIo, pending return\n");
200 TestRead(FileHandle
, FALSE
, FALSE
, TRUE
);
201 trace("Non-Cached, allow FastIo, pending return\n");
202 TestRead(FileHandle
, FALSE
, TRUE
, TRUE
);
206 RtlFillMemory(&IoStatus
, sizeof(IoStatus
), 0x55);
207 InitializeObjectAttributes(&ObjectAttributes
,
209 OBJ_CASE_INSENSITIVE
,
212 Status
= NtOpenFile(&FileHandle
,
217 FILE_NON_DIRECTORY_FILE
|
218 FILE_SYNCHRONOUS_IO_NONALERT
);
219 ok_eq_hex(Status
, STATUS_SUCCESS
);
220 if (!skip(NT_SUCCESS(Status
), "No file\n"))
222 ok_eq_hex(IoStatus
.Status
, STATUS_SUCCESS
);
223 ok_eq_ulongptr(IoStatus
.Information
, FILE_OPENED
);
224 trace("Cached, no FastIo, direct return\n");
225 TestRead(FileHandle
, TRUE
, FALSE
, FALSE
);
226 trace("Cached, allow FastIo, direct return\n");
227 TestRead(FileHandle
, TRUE
, TRUE
, FALSE
);
228 trace("Cached, no FastIo, pending return\n");
229 TestRead(FileHandle
, TRUE
, FALSE
, TRUE
);
230 trace("Cached, allow FastIo, pending return\n");
231 TestRead(FileHandle
, TRUE
, TRUE
, TRUE
);