- Italian translation by Daniele Forsi (dforsi at gmail dot com)
[reactos.git] / reactos / ntoskrnl / tests / fsrtl.c
1 #include <ntifs.h>
2 #include "ntndk.h"
3 #include "fsrtl_glue.h"
4
5 #include "fastio.h"
6 #include "fsrtl.h"
7
8 /*
9 This is the main test function. It is called from DriverEntry.
10
11 There is a DbgBreakPoint() call at the beginning of DriverEntry.
12 In order to run the test again, simply type
13 net stop fsrtl
14 net start fsrtl
15
16 Author: Dom Cote
17 */
18
19 BOOLEAN FsRtlTest_StartTest() {
20 HANDLE Fh = NULL;
21 IO_STATUS_BLOCK IoStatus;
22 NTSTATUS Return = TRUE;
23 PFILE_OBJECT Pfo;
24 LONGLONG i = 0;
25
26 PCHAR Buffer;
27
28 LARGE_INTEGER Offset;
29 ULONG Length = 0;
30 LARGE_INTEGER OldSize;
31
32 /* Parameters we are going to use in the test from the FCB */
33 PFSRTL_COMMON_FCB_HEADER FcbHeader;
34 PLARGE_INTEGER AllocationSize;
35 PLARGE_INTEGER ValidDataLength;
36 PLARGE_INTEGER FileSize;
37
38 /* Allocate a 100KB buffer to do IOs */
39 Buffer = ExAllocatePool(PagedPool,100*_1KB);
40
41 FsRtlTest_OpenTestFile(&Fh, &Pfo);
42
43 /* Extract the test variable from the FCB struct */
44 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext;
45 AllocationSize = &FcbHeader->AllocationSize;
46 ValidDataLength = &FcbHeader->ValidDataLength;
47 FileSize = &FcbHeader->FileSize;
48
49 /* Try to cache without caching having been initialized. This should fail.*/
50 Length = 10*_1KB;
51 FSRTL_TEST("No cache map test.",!FsRtlCopyWrite(Pfo,AllocationSize,Length,TRUE,0,Buffer,&IoStatus,NULL));
52
53 /* We are going to build a 100k file */
54 /* This will inititate caching and build some size */
55 Offset.QuadPart = 0;
56 Length = 100*_1KB;
57 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus);
58 FSRTL_TEST("Building 100k filesize.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
59 Return = TRUE;
60
61 /* Extending the file by 1/2 sector, 256 bytes. */
62 Offset.QuadPart = 0x7fffffffffff;
63 Length = 0x100;
64 Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus);
65 FSRTL_TEST("Extending by 1/2 sector.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
66 Return = TRUE;
67
68 /* Append to the file past the allocation size*/
69 Offset.LowPart = 0xFFFFFFFF;
70 Offset.HighPart = 0xFFFFFFFF;
71 OldSize.QuadPart = FileSize->QuadPart;
72 Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart);
73 FSRTL_TEST("Testing extending past allocation size",!FsRtlCopyWrite(Pfo,&Offset,Length+1,TRUE,0,Buffer,&IoStatus,NULL));
74 FSRTL_TEST("Testing extending not past allocation size",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL));
75 FSRTL_TEST("Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length)));
76
77 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */
78 Offset.QuadPart = 0;
79 Length = 65*_1KB;
80 FSRTL_TEST("65KB IO Test",!FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL));
81
82 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */
83 Length = 64*_1KB;
84 FSRTL_TEST("64KB IO Test",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL))
85
86 /* Test the fast Io questionable flag
87 This test fails and should succeed. I am not sure why. When FsRtlCopyWrite() queries the FastIoTable of the related
88 device object, it comes back with no.
89 FcbHeader->IsFastIoPossible = FastIoIsQuestionable;
90 FSRTL_TEST("FastIo is questionable flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL))
91 */
92
93 /* Test the fast Io not possible flag */
94 FcbHeader->IsFastIoPossible = FastIoIsNotPossible;
95 FSRTL_TEST("FastIo is not possible flag",!FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL))
96 /* Set the flag back to what it was */
97 FcbHeader->IsFastIoPossible = FastIoIsPossible;
98 FSRTL_TEST("FastIo is possbile flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL))
99
100 if (Pfo)
101 {
102 ObDereferenceObject(Pfo);
103 Pfo = NULL;
104 }
105
106 if (Fh)
107 {
108 ZwClose(Fh);
109 Fh = NULL;
110 }
111
112
113 /* ------------------------------------------------------------------------*/
114 /* ------------------------------------------------------------------------*/
115 /* ------------------------------------------------------------------------*/
116
117 /* We are going to repeat the same bunch of tests but with Wait = FALSE. So we exercise the second part of the function. */
118 FsRtlTest_OpenTestFile(&Fh, &Pfo);
119
120 /* Extract the test variable from the FCB struct */
121 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext;
122 AllocationSize = &FcbHeader->AllocationSize;
123 ValidDataLength = &FcbHeader->ValidDataLength;
124 FileSize = &FcbHeader->FileSize;
125
126 /* Try to cache without caching having been initialized. This should fail.*/
127 Length = 10*_1KB;
128 FSRTL_TEST("No cache map test. Wait = FALSE",!FsRtlCopyWrite(Pfo,AllocationSize,Length,FALSE,0,Buffer,&IoStatus,NULL));
129
130 /* We are going to build a 100k file */
131 /* This will inititate caching and build some size */
132 Offset.QuadPart = 0;
133 Length = 100*_1KB;
134 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus);
135 FSRTL_TEST("Building 100k filesize. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
136 Return = TRUE;
137
138 /* Extending the file by 1/2 sector, 256 bytes. */
139 Offset.QuadPart = 0x7fffffffffff;
140 Length = 0x100;
141 Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus);
142 FSRTL_TEST("Extending by 1/2 sector. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
143 Return = TRUE;
144
145 /* Append to the file past the allocation size*/
146 Offset.LowPart = 0xFFFFFFFF;
147 Offset.HighPart = 0xFFFFFFFF;
148 OldSize.QuadPart = FileSize->QuadPart;
149 Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart);
150 FSRTL_TEST("Testing extending past allocation size Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length+1,FALSE,0,Buffer,&IoStatus,NULL));
151 FSRTL_TEST("Testing extending not past allocation size. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL));
152 FSRTL_TEST("Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length)));
153
154 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */
155 Offset.QuadPart = 0;
156 Length = 65*_1KB;
157 FSRTL_TEST("65KB IO Test. Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL));
158
159 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */
160 Length = 64*_1KB;
161 FSRTL_TEST("64KB IO Test. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL))
162
163 /* Test the fast Io questionable flag
164 This test fails and should succeed. I am not sure why. When FsRtlCopyWrite() queries the FastIoTable of the related
165 device object, it comes back with no.
166 FcbHeader->IsFastIoPossible = FastIoIsQuestionable;
167 FSRTL_TEST("FastIo is questionable flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL))
168 */
169
170 /* Test the fast Io not possible flag */
171 FcbHeader->IsFastIoPossible = FastIoIsNotPossible;
172 FSRTL_TEST("FastIo is not possible flag. Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL))
173 /* Set the flag back to what it was */
174 FcbHeader->IsFastIoPossible = FastIoIsPossible;
175 FSRTL_TEST("FastIo is possbile flag. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL))
176
177
178 /* ------------------------------------------------------------------------------------------
179 ------------------------------------------------------------------------------------------
180 ------------------------------------------------------------------------------------------
181 */
182
183 /* Testing FsRtlCopyRead() function */
184
185 Offset.LowPart = 0x0;
186 Offset.HighPart = 0x0;
187 Length = 0x10000;
188
189 /* Testing a 64KB read with Wait = TRUE */
190 Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL);
191 FSRTL_TEST("Testing 64k IO Wait=TRUE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
192 Return = TRUE;
193
194 /* Testing a 64KB read with Wait = FALSE */
195 Return = FsRtlCopyRead(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL);
196 FSRTL_TEST("Testing 64k IO Wait=FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
197 Return = TRUE;
198
199 /* Testing read past the end of the file */
200 Offset.QuadPart = FileSize->QuadPart - (5 * _1KB);
201 Length = 10 * _1KB;
202 Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL);
203 FSRTL_TEST("Testing reading past end of file but starting before EOF",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status) && IoStatus.Information == (FileSize->QuadPart-Offset.QuadPart)));
204
205 Offset.QuadPart = FileSize->QuadPart + 1;
206 Length = 10 * _1KB;
207 Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL);
208 FSRTL_TEST("Testing reading past end of file but starting after EOF",(NT_SUCCESS(Return) && (IoStatus.Status == STATUS_END_OF_FILE) && IoStatus.Information == 0));
209
210
211 /* Testing a 64KB read with Wait = TRUE */
212 Offset.LowPart = 0x0;
213 Offset.HighPart = 0x0;
214 Length = 0x10000;
215 FcbHeader->IsFastIoPossible = FastIoIsNotPossible;
216 FSRTL_TEST("FastIo is not possible flag. Wait = FALSE",!FsRtlCopyRead(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL));
217 FSRTL_TEST("FastIo is not possible flag. Wait = TRUE",!FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL));
218
219 Return = TRUE;
220
221 Cleanup:
222
223 if (Pfo)
224 {
225 ObDereferenceObject(Pfo);
226 Pfo = NULL;
227 }
228
229 if (Fh)
230 {
231 ZwClose(Fh);
232 Fh = NULL;
233 }
234
235 if (Buffer != NULL) {
236 ExFreePool(Buffer);
237 Buffer = NULL;
238 }
239
240 return Return;
241
242 }
243
244 /* This function is just a wrapper around ZwWriteFile */
245 NTSTATUS FsRltTest_WritefileZw(HANDLE fh, PLARGE_INTEGER Offset, ULONG Length, PVOID Buffer, PIO_STATUS_BLOCK pIoStatus){
246 NTSTATUS Return;
247
248 Return = ZwWriteFile(
249 fh,
250 NULL,
251 NULL,
252 NULL,
253 pIoStatus,
254 Buffer,
255 Length,
256 Offset,
257 NULL
258 );
259
260 return Return;
261 }
262
263 /* This function fills the buffer with a test pattern */
264 void FsRtlTest_FillBuffer(LARGE_INTEGER Start, ULONG Length, PVOID Buffer) {
265 ULONG i = 0;
266 PULONGLONG Index = (PULONGLONG) Buffer;
267
268 for (i=0; i<Length/sizeof(ULONGLONG); i++) {
269 Index[i] = Start.QuadPart + i;
270 }
271
272 return;
273 }
274
275 /* This function opens a test file with the FILE_DELETE_ON_CLOSE flag
276 and reference the file object
277 */
278 NTSTATUS FsRtlTest_OpenTestFile(PHANDLE Pfh, PFILE_OBJECT *Ppfo) {
279 UNICODE_STRING FileName;
280 OBJECT_ATTRIBUTES oa;
281 IO_STATUS_BLOCK IoStatus;
282 NTSTATUS Return;
283
284 RtlInitUnicodeString(&FileName,L"\\??\\C:\\fsrtl.bin");
285
286 InitializeObjectAttributes(
287 &oa,
288 &FileName,
289 OBJ_KERNEL_HANDLE,
290 NULL,
291 NULL;
292 );
293
294 Return = IoCreateFile(Pfh,
295 GENERIC_WRITE,
296 &oa,
297 &IoStatus,
298 0,
299 FILE_ATTRIBUTE_NORMAL,
300 0,
301 FILE_OVERWRITE_IF ,
302 FILE_SYNCHRONOUS_IO_ALERT | FILE_DELETE_ON_CLOSE,
303 NULL,
304 0,
305 CreateFileTypeNone,
306 NULL,
307 0);
308
309 Return = ObReferenceObjectByHandle(
310 *Pfh,
311 GENERIC_WRITE,
312 NULL,
313 KernelMode,
314 Ppfo,
315 NULL
316 );
317 }
318
319
320 /* All the testing is done from driver entry */
321 NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
322 {
323 PDEVICE_OBJECT DeviceObject;
324 NTSTATUS mStatus;
325 UNICODE_STRING uniName, uniDOSName;
326 PDEVOBJ_EXTENSION x;
327
328 DbgPrint("Loading the FSRTL test driver.\n");
329 DbgBreakPoint();
330
331 /* register device functions */
332 DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRtlTest_DispatchCreateClose;
333 DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRtlTest_DispatchCreateClose;
334 DriverObject->DriverUnload = FsRtlTest_Unload;
335
336 if (!FsRtlTest_StartTest()) {
337 DbgPrint("FsRtl test failed.\n");
338 } else {
339 DbgPrint("FsRtl test OK.\n");
340 }
341
342 return STATUS_SUCCESS;
343 }
344
345
346
347
348
349
350 NTSTATUS FsRtlTest_DispatchCreateClose( IN PDEVICE_OBJECT devObj, IN PIRP Irp )
351 {
352 DbgPrint(("FsRtl: Open / Close\n"));
353
354 Irp->IoStatus.Information = 0;
355 Irp->IoStatus.Status = STATUS_SUCCESS;
356 IoCompleteRequest( Irp, IO_NO_INCREMENT );
357
358 return STATUS_SUCCESS;
359 }
360
361 VOID FsRtlTest_Unload( IN PDRIVER_OBJECT DriverObject )
362 {
363 DbgPrint(("FsRtl: Unloading.\n"));
364 }
365
366