[NTDLL_APITEST]
[reactos.git] / rostests / apitests / ntdll / NtReadFile.c
1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for NtReadFile
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <apitest.h>
9
10 #define WIN32_NO_STATUS
11 #include <winreg.h>
12 #include <ndk/cmfuncs.h>
13 #include <ndk/iofuncs.h>
14 #include <ndk/mmfuncs.h>
15 #include <ndk/obfuncs.h>
16 #include <ndk/psfuncs.h>
17 #include <ndk/rtlfuncs.h>
18
19 static
20 BOOL
21 Is64BitSystem(VOID)
22 {
23 #ifdef _WIN64
24 return TRUE;
25 #else
26 NTSTATUS Status;
27 ULONG_PTR IsWow64;
28
29 Status = NtQueryInformationProcess(NtCurrentProcess(),
30 ProcessWow64Information,
31 &IsWow64,
32 sizeof(IsWow64),
33 NULL);
34 if (NT_SUCCESS(Status))
35 {
36 return IsWow64 != 0;
37 }
38
39 return FALSE;
40 #endif
41 }
42
43 static
44 ULONG
45 SizeOfMdl(VOID)
46 {
47 return Is64BitSystem() ? 48 : 28;
48 }
49
50 START_TEST(NtReadFile)
51 {
52 NTSTATUS Status;
53 HANDLE FileHandle;
54 UNICODE_STRING FileName = RTL_CONSTANT_STRING(L"\\SystemRoot\\ntdll-apitest-NtReadFile-test.bin");
55 PVOID Buffer;
56 SIZE_T BufferSize;
57 LARGE_INTEGER ByteOffset;
58 OBJECT_ATTRIBUTES ObjectAttributes;
59 IO_STATUS_BLOCK IoStatus;
60 FILE_DISPOSITION_INFORMATION DispositionInfo;
61 ULONG TooLargeDataSize = (MAXUSHORT + 1 - SizeOfMdl()) / sizeof(ULONG_PTR) * PAGE_SIZE; // 0x3FF9000 on x86
62 ULONG LargeMdlMaxDataSize = TooLargeDataSize - PAGE_SIZE;
63
64 trace("System is %d bits, Size of MDL: %lu\n", Is64BitSystem() ? 64 : 32, SizeOfMdl());
65 trace("Max MDL data size: 0x%lx bytes\n", LargeMdlMaxDataSize);
66
67 ByteOffset.QuadPart = 0;
68
69 Buffer = NULL;
70 BufferSize = TooLargeDataSize;
71 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
72 &Buffer,
73 0,
74 &BufferSize,
75 MEM_RESERVE | MEM_COMMIT,
76 PAGE_READWRITE);
77 if (!NT_SUCCESS(Status))
78 {
79 skip("Failed to allocate memory, status %lx\n", Status);
80 return;
81 }
82
83 InitializeObjectAttributes(&ObjectAttributes,
84 &FileName,
85 OBJ_CASE_INSENSITIVE,
86 NULL,
87 NULL);
88 Status = NtCreateFile(&FileHandle,
89 FILE_READ_DATA | FILE_WRITE_DATA | DELETE | SYNCHRONIZE,
90 &ObjectAttributes,
91 &IoStatus,
92 NULL,
93 0,
94 0,
95 FILE_SUPERSEDE,
96 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
97 FILE_NO_INTERMEDIATE_BUFFERING,
98 NULL,
99 0);
100 ok_hex(Status, STATUS_SUCCESS);
101
102 ByteOffset.QuadPart = 0x10000;
103 Status = NtWriteFile(FileHandle,
104 NULL,
105 NULL,
106 NULL,
107 &IoStatus,
108 Buffer,
109 BufferSize - 0x10000,
110 &ByteOffset,
111 NULL);
112 ok_hex(Status, STATUS_SUCCESS);
113 ByteOffset.QuadPart = 0;
114
115 /* non-cached, max size -- succeeds */
116 Status = NtReadFile(FileHandle,
117 NULL,
118 NULL,
119 NULL,
120 &IoStatus,
121 Buffer,
122 LargeMdlMaxDataSize - PAGE_SIZE,
123 &ByteOffset,
124 NULL);
125 ok_hex(Status, STATUS_SUCCESS);
126
127 /* non-cached, max size -- succeeds */
128 Status = NtReadFile(FileHandle,
129 NULL,
130 NULL,
131 NULL,
132 &IoStatus,
133 Buffer,
134 LargeMdlMaxDataSize,
135 &ByteOffset,
136 NULL);
137 ok_hex(Status, STATUS_SUCCESS);
138
139 /* non-cached, too large -- fails to allocate MDL
140 * Note: this returns STATUS_SUCCESS on Win7 -- higher MDL size limit */
141 Status = NtReadFile(FileHandle,
142 NULL,
143 NULL,
144 NULL,
145 &IoStatus,
146 Buffer,
147 LargeMdlMaxDataSize + PAGE_SIZE,
148 &ByteOffset,
149 NULL);
150 ok_hex(Status, STATUS_INSUFFICIENT_RESOURCES);
151
152 /* non-cached, unaligned -- fails with invalid parameter */
153 Status = NtReadFile(FileHandle,
154 NULL,
155 NULL,
156 NULL,
157 &IoStatus,
158 Buffer,
159 LargeMdlMaxDataSize + 1,
160 &ByteOffset,
161 NULL);
162 ok_hex(Status, STATUS_INVALID_PARAMETER);
163
164 DispositionInfo.DeleteFile = TRUE;
165 Status = NtSetInformationFile(FileHandle,
166 &IoStatus,
167 &DispositionInfo,
168 sizeof(DispositionInfo),
169 FileDispositionInformation);
170 ok_hex(Status, STATUS_SUCCESS);
171 Status = NtClose(FileHandle);
172 ok_hex(Status, STATUS_SUCCESS);
173
174 Status = NtCreateFile(&FileHandle,
175 FILE_READ_DATA | FILE_WRITE_DATA | DELETE | SYNCHRONIZE,
176 &ObjectAttributes,
177 &IoStatus,
178 NULL,
179 0,
180 0,
181 FILE_SUPERSEDE,
182 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
183 NULL,
184 0);
185 ok_hex(Status, STATUS_SUCCESS);
186
187 ByteOffset.QuadPart = 0x10000;
188 Status = NtWriteFile(FileHandle,
189 NULL,
190 NULL,
191 NULL,
192 &IoStatus,
193 Buffer,
194 BufferSize - 0x10000,
195 &ByteOffset,
196 NULL);
197 ok_hex(Status, STATUS_SUCCESS);
198 ByteOffset.QuadPart = 0;
199
200 /* cached: succeeds with arbitrary length */
201 Status = NtReadFile(FileHandle,
202 NULL,
203 NULL,
204 NULL,
205 &IoStatus,
206 Buffer,
207 LargeMdlMaxDataSize,
208 &ByteOffset,
209 NULL);
210 ok_hex(Status, STATUS_SUCCESS);
211
212 Status = NtReadFile(FileHandle,
213 NULL,
214 NULL,
215 NULL,
216 &IoStatus,
217 Buffer,
218 LargeMdlMaxDataSize + 1,
219 &ByteOffset,
220 NULL);
221 ok_hex(Status, STATUS_SUCCESS);
222
223 Status = NtReadFile(FileHandle,
224 NULL,
225 NULL,
226 NULL,
227 &IoStatus,
228 Buffer,
229 TooLargeDataSize,
230 &ByteOffset,
231 NULL);
232 ok_hex(Status, STATUS_SUCCESS);
233
234 DispositionInfo.DeleteFile = TRUE;
235 Status = NtSetInformationFile(FileHandle,
236 &IoStatus,
237 &DispositionInfo,
238 sizeof(DispositionInfo),
239 FileDispositionInformation);
240 ok_hex(Status, STATUS_SUCCESS);
241 Status = NtClose(FileHandle);
242 ok_hex(Status, STATUS_SUCCESS);
243
244 Status = NtFreeVirtualMemory(NtCurrentProcess(),
245 &Buffer,
246 &BufferSize,
247 MEM_RELEASE);
248 ok_hex(Status, STATUS_SUCCESS);
249 }