429dbc29bc96199eaac2982b13777745c5cbf24a
[reactos.git] / rostests / kmtests / ntos_io / IoReadWrite_user.c
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
13 TestRead(
14 _In_ HANDLE FileHandle,
15 _In_ BOOLEAN Cached,
16 _In_ BOOLEAN UseFastIo,
17 _In_ BOOLEAN ReturnPending)
18 {
19 NTSTATUS Status;
20 IO_STATUS_BLOCK IoStatus;
21 HANDLE EventHandle;
22 UCHAR Buffer[32];
23 LARGE_INTEGER Offset;
24 ULONG BaseKey, StatusKey, Key;
25 DWORD WaitStatus;
26
27 BaseKey = (UseFastIo ? KEY_USE_FASTIO : 0) |
28 (ReturnPending ? KEY_RETURN_PENDING : 0);
29
30 EventHandle = CreateEventW(NULL, TRUE, FALSE, NULL);
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);
36 ResetEvent(EventHandle);
37 RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
38 Key = BaseKey | StatusKey | KEY_DATA(0x11);
39 Offset.QuadPart = 0;
40 Status = NtReadFile(FileHandle,
41 EventHandle,
42 NULL,
43 NULL,
44 &IoStatus,
45 NULL,
46 0,
47 &Offset,
48 &Key);
49 WaitStatus = WaitForSingleObject(EventHandle, 0);
50 if (ReturnPending)
51 ok_eq_hex(Status, STATUS_ACCESS_VIOLATION);
52 else
53 ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW);
54 if (Cached && UseFastIo && !ReturnPending)
55 {
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);
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()
68 ResetEvent(EventHandle);
69 RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
70 Key = BaseKey | StatusKey | KEY_DATA(0x22);
71 Offset.QuadPart = 0;
72 Status = NtReadFile(FileHandle,
73 EventHandle,
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);
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);
87
88 ResetEvent(EventHandle);
89 RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
90 RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
91 Key = BaseKey | StatusKey | KEY_DATA(0x33);
92 Offset.QuadPart = 0;
93 Status = NtReadFile(FileHandle,
94 EventHandle,
95 NULL,
96 NULL,
97 &IoStatus,
98 Buffer,
99 0,
100 &Offset,
101 &Key);
102 WaitStatus = WaitForSingleObject(EventHandle, 0);
103 if (ReturnPending)
104 ok_eq_hex(Status, STATUS_ACCESS_VIOLATION);
105 else
106 ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW);
107 if (Cached && UseFastIo && !ReturnPending)
108 {
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);
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
121 ResetEvent(EventHandle);
122 RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
123 RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
124 Key = BaseKey | StatusKey | KEY_DATA(0x44);
125 Offset.QuadPart = 0;
126 Status = NtReadFile(FileHandle,
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);
156 ok_eq_uint(Buffer[TEST_FILE_SIZE], 0x55);
157 }
158 else
159 {
160 ok_eq_uint(Buffer[0], 0x55);
161 }
162 }
163 }
164
165 START_TEST(IoReadWrite)
166 {
167 HANDLE FileHandle;
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;
172 NTSTATUS Status;
173
174 KmtLoadDriver(L"IoReadWrite", FALSE);
175 KmtOpenDriver();
176
177 RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
178 InitializeObjectAttributes(&ObjectAttributes,
179 &NonCachedFileName,
180 OBJ_CASE_INSENSITIVE,
181 NULL,
182 NULL);
183 Status = NtOpenFile(&FileHandle,
184 FILE_ALL_ACCESS,
185 &ObjectAttributes,
186 &IoStatus,
187 0,
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"))
192 {
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);
203 NtClose(FileHandle);
204 }
205
206 RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
207 InitializeObjectAttributes(&ObjectAttributes,
208 &CachedFileName,
209 OBJ_CASE_INSENSITIVE,
210 NULL,
211 NULL);
212 Status = NtOpenFile(&FileHandle,
213 FILE_ALL_ACCESS,
214 &ObjectAttributes,
215 &IoStatus,
216 0,
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"))
221 {
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);
232 NtClose(FileHandle);
233 }
234
235 KmtCloseDriver();
236 KmtUnloadDriver();
237 }