Sync with trunk revision 64099.
[reactos.git] / 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 PFILE_OBJECT Pfo = NULL;
22
23 HANDLE DirFh = NULL;
24 PFILE_OBJECT DirPfo = NULL;
25
26
27 IO_STATUS_BLOCK IoStatus;
28 BOOLEAN Return;
29 NTSTATUS Status = STATUS_SUCCESS;
30 LONGLONG i = 0;
31
32 PCHAR Buffer;
33 PMDL MdlChain = 0;
34
35 LARGE_INTEGER Offset;
36 ULONG Length = 0;
37 LARGE_INTEGER OldSize;
38
39 /* Parameters we are going to use in the test from the FCB */
40 PFSRTL_COMMON_FCB_HEADER FcbHeader;
41 PLARGE_INTEGER AllocationSize;
42 PLARGE_INTEGER ValidDataLength;
43 PLARGE_INTEGER FileSize;
44
45 PDEVICE_OBJECT pRelatedDo = NULL;
46
47 /* Allocate a 100KB buffer to do IOs */
48 Buffer = ExAllocatePool(PagedPool,100*_1KB);
49
50 /* ------------------------------------------------------------------------
51 TESTING:
52 BOOLEAN
53 NTAPI
54 FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
55 IN PLARGE_INTEGER FileOffset,
56 IN ULONG Length,
57 IN BOOLEAN Wait,
58 IN ULONG LockKey,
59 OUT PVOID Buffer,
60 OUT PIO_STATUS_BLOCK IoStatus,
61 IN PDEVICE_OBJECT DeviceObject)
62
63 with Wait = TRUE
64
65 ------------------------------------------------------------------------ */
66 FsRtlTest_OpenTestFile(&Fh, &Pfo);
67 FSRTL_TEST("Opening Test File.",((Pfo != NULL) && (Fh != NULL)));
68
69 /* Extract the test variable from the FCB struct */
70 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext;
71 AllocationSize = &FcbHeader->AllocationSize;
72 ValidDataLength = &FcbHeader->ValidDataLength;
73 FileSize = &FcbHeader->FileSize;
74
75 /* Try to cache without caching having been initialized. This should fail.*/
76 Length = 10*_1KB;
77 FSRTL_TEST("FsRtlCopyWrite() - No cache map test.",!FsRtlCopyWrite(Pfo,AllocationSize,Length,TRUE,0,Buffer,&IoStatus,NULL));
78
79 /* We are going to build a 100k file */
80 /* This will inititate caching and build some size */
81 Offset.QuadPart = 0;
82 Length = 100*_1KB;
83 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus);
84 FSRTL_TEST("FsRtlCopyWrite() - Building 100k filesize.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
85 Return = TRUE;
86
87 /* Extending the file by 1/2 sector, 256 bytes. */
88 Offset.QuadPart = 0x7fffffffffff;
89 Length = 0x100;
90 Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus);
91 FSRTL_TEST("FsRtlCopyWrite() - Extending by 1/2 sector.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
92 Return = TRUE;
93
94 /* Append to the file past the allocation size*/
95 Offset.LowPart = 0xFFFFFFFF;
96 Offset.HighPart = 0xFFFFFFFF;
97 OldSize.QuadPart = FileSize->QuadPart;
98 Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart);
99 FSRTL_TEST("FsRtlCopyWrite() - Testing extending past allocation size",!FsRtlCopyWrite(Pfo,&Offset,Length+1,TRUE,0,Buffer,&IoStatus,NULL));
100 FSRTL_TEST("FsRtlCopyWrite() - Testing extending not past allocation size",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL));
101 FSRTL_TEST("FsRtlCopyWrite() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length)));
102
103 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */
104 Offset.QuadPart = 0;
105 Length = 65*_1KB;
106 FSRTL_TEST("FsRtlCopyWrite() - 65KB IO Test",!FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL));
107
108 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */
109 Length = 64*_1KB;
110 FSRTL_TEST("FsRtlCopyWrite() - 64KB IO Test",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL))
111
112 /* Test the fast Io questionable flag
113 This test fails and should succeed. I am not sure why. When FsRtlCopyWrite() queries the FastIoTable of the related
114 device object, it comes back with no.
115 FcbHeader->IsFastIoPossible = FastIoIsQuestionable;
116 FSRTL_TEST("FastIo is questionable flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL))
117 */
118
119 /* Test the fast Io not possible flag */
120 FcbHeader->IsFastIoPossible = FastIoIsNotPossible;
121 FSRTL_TEST("FsRtlCopyWrite() - FastIo is not possible flag",!FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL))
122 /* Set the flag back to what it was */
123 FcbHeader->IsFastIoPossible = FastIoIsPossible;
124 FSRTL_TEST("FsRtlCopyWrite() - FastIo is possbile flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL))
125
126 if (Pfo)
127 {
128 ObDereferenceObject(Pfo);
129 Pfo = NULL;
130 }
131
132 if (Fh)
133 {
134 ZwClose(Fh);
135 Fh = NULL;
136 }
137
138 /* ------------------------------------------------------------------------
139 TESTING:
140 BOOLEAN
141 NTAPI
142 FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
143 IN PLARGE_INTEGER FileOffset,
144 IN ULONG Length,
145 IN BOOLEAN Wait,
146 IN ULONG LockKey,
147 OUT PVOID Buffer,
148 OUT PIO_STATUS_BLOCK IoStatus,
149 IN PDEVICE_OBJECT DeviceObject)
150
151 with Wait = FALSE
152
153 ------------------------------------------------------------------------ */
154
155 /* We are going to repeat the same bunch of tests but with Wait = FALSE. So we exercise the second part of the function. */
156 FsRtlTest_OpenTestFile(&Fh, &Pfo);
157
158 /* Extract the test variable from the FCB struct */
159 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext;
160 AllocationSize = &FcbHeader->AllocationSize;
161 ValidDataLength = &FcbHeader->ValidDataLength;
162 FileSize = &FcbHeader->FileSize;
163
164 /* Try to cache without caching having been initialized. This should fail.*/
165 Length = 10*_1KB;
166 FSRTL_TEST("FsRtlCopyWrite() - No cache map test. Wait = FALSE",!FsRtlCopyWrite(Pfo,AllocationSize,Length,FALSE,0,Buffer,&IoStatus,NULL));
167
168 /* We are going to build a 100k file */
169 /* This will inititate caching and build some size */
170 Offset.QuadPart = 0;
171 Length = 100*_1KB;
172 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus);
173 FSRTL_TEST("FsRtlCopyWrite() - Building 100k filesize. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
174 Return = TRUE;
175
176 /* Extending the file by 1/2 sector, 256 bytes. */
177 Offset.QuadPart = 0x7fffffffffff;
178 Length = 0x100;
179 Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus);
180 FSRTL_TEST("FsRtlCopyWrite() - Extending by 1/2 sector. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
181 Return = TRUE;
182
183 /* Append to the file past the allocation size*/
184 Offset.LowPart = 0xFFFFFFFF;
185 Offset.HighPart = 0xFFFFFFFF;
186 OldSize.QuadPart = FileSize->QuadPart;
187 Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart);
188 FSRTL_TEST("FsRtlCopyWrite() - Testing extending past allocation size Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length+1,FALSE,0,Buffer,&IoStatus,NULL));
189 FSRTL_TEST("FsRtlCopyWrite() - Testing extending not past allocation size. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL));
190 FSRTL_TEST("FsRtlCopyWrite() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length)));
191
192 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */
193 Offset.QuadPart = 0;
194 Length = 65*_1KB;
195 FSRTL_TEST("FsRtlCopyWrite() - 65KB IO Test. Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL));
196
197 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */
198 Length = 64*_1KB;
199 FSRTL_TEST("FsRtlCopyWrite() - 64KB IO Test. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL))
200
201 /* Test the fast Io questionable flag
202 This test fails and should succeed. I am not sure why. When FsRtlCopyWrite() queries the FastIoTable of the related
203 device object, it comes back with no.
204 FcbHeader->IsFastIoPossible = FastIoIsQuestionable;
205 FSRTL_TEST("FastIo is questionable flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL))
206 */
207
208 /* Test the fast Io not possible flag */
209 FcbHeader->IsFastIoPossible = FastIoIsNotPossible;
210 FSRTL_TEST("FsRtlCopyWrite() - FastIo is not possible flag. Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL))
211 /* Set the flag back to what it was */
212 FcbHeader->IsFastIoPossible = FastIoIsPossible;
213 FSRTL_TEST("FsRtlCopyWrite() - FastIo is possbile flag. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL))
214
215
216 /* ------------------------------------------------------------------------------------------
217 TESTING:
218
219 BOOLEAN
220 NTAPI
221 FsRtlCopyRead(IN PFILE_OBJECT FileObject,
222 IN PLARGE_INTEGER FileOffset,
223 IN ULONG Length,
224 IN BOOLEAN Wait,
225 IN ULONG LockKey,
226 OUT PVOID Buffer,
227 OUT PIO_STATUS_BLOCK IoStatus,
228 IN PDEVICE_OBJECT DeviceObject)
229
230 ------------------------------------------------------------------------------------------ */
231
232 Offset.LowPart = 0x0;
233 Offset.HighPart = 0x0;
234 Length = 0x10000;
235
236 /* Testing a 64KB read with Wait = TRUE */
237 Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL);
238 FSRTL_TEST("FsRtlCopyRead() - Testing 64k IO Wait=TRUE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
239 Return = TRUE;
240
241 /* Testing a 64KB read with Wait = FALSE */
242 Return = FsRtlCopyRead(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL);
243 FSRTL_TEST("FsRtlCopyRead() - Testing 64k IO Wait=FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
244 Return = TRUE;
245
246 /* Testing read past the end of the file */
247 Offset.QuadPart = FileSize->QuadPart - (5 * _1KB);
248 Length = 10 * _1KB;
249 Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL);
250 FSRTL_TEST("FsRtlCopyRead() - Testing reading past end of file but starting before EOF",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status) && IoStatus.Information == (FileSize->QuadPart-Offset.QuadPart)));
251
252 Offset.QuadPart = FileSize->QuadPart + 1;
253 Length = 10 * _1KB;
254 Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL);
255 FSRTL_TEST("FsRtlCopyRead() - Testing reading past end of file but starting after EOF",(NT_SUCCESS(Return) && (IoStatus.Status == STATUS_END_OF_FILE) && IoStatus.Information == 0));
256
257
258 /* Testing a 64KB read with Wait = TRUE */
259 Offset.LowPart = 0x0;
260 Offset.HighPart = 0x0;
261 Length = 0x10000;
262 FcbHeader->IsFastIoPossible = FastIoIsNotPossible;
263 FSRTL_TEST("FsRtlCopyRead() - FastIo is not possible flag. Wait = FALSE",!FsRtlCopyRead(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL));
264 FSRTL_TEST("FsRtlCopyRead() - FastIo is not possible flag. Wait = TRUE",!FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL));
265 FcbHeader->IsFastIoPossible = FastIoIsPossible;
266 Return = TRUE;
267
268 if (Pfo)
269 {
270 ObDereferenceObject(Pfo);
271 Pfo = NULL;
272 }
273
274 if (Fh)
275 {
276 ZwClose(Fh);
277 Fh = NULL;
278 }
279
280 /* ------------------------------------------------------------------------
281 TESTING:
282 BOOLEAN
283 NTAPI
284 FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject,
285 IN PLARGE_INTEGER FileOffset,
286 IN ULONG Length,
287 IN ULONG LockKey,
288 OUT PMDL *MdlChain,
289 OUT PIO_STATUS_BLOCK IoStatus,
290 IN PDEVICE_OBJECT DeviceObject)
291
292 ------------------------------------------------------------------------ */
293
294 /* We are going to repeat the same bunch of tests but with Wait = FALSE. So we exercise the second part of the function. */
295 FsRtlTest_OpenTestFile(&Fh, &Pfo);
296
297 /* Extract the test variable from the FCB struct */
298 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext;
299 AllocationSize = &FcbHeader->AllocationSize;
300 ValidDataLength = &FcbHeader->ValidDataLength;
301 FileSize = &FcbHeader->FileSize;
302
303 /* Try to cache without caching having been initialized. This should fail.*/
304 Length = 10*_1KB;
305 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - No cache map test. Wait = FALSE",
306 !FsRtlPrepareMdlWriteDev(Pfo,AllocationSize,Length,0,MdlChain,&IoStatus,NULL));
307
308 /* We are going to build a 100k file */
309 /* This will inititate caching and build some size */
310 Offset.QuadPart = 0;
311 Length = 100*_1KB;
312 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus);
313 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Building 100k filesize. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
314 Return = TRUE;
315
316 /* Extending the file by 1/2 sector, 256 bytes. */
317 Offset.QuadPart = 0x7fffffffffff;
318 Length = 0x100;
319 Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus);
320 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Extending by 1/2 sector. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
321 Return = TRUE;
322
323
324 pRelatedDo = IoGetRelatedDeviceObject(Pfo);
325 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Did we get related DO ?",pRelatedDo);
326
327
328 /* Append to the file past the allocation size*/
329 Offset.QuadPart = FileSize->QuadPart;
330 OldSize.QuadPart = FileSize->QuadPart;
331 Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart);
332 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Testing extending past allocation size.",
333 !FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length+1,0,&MdlChain,&IoStatus,pRelatedDo));
334
335 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Testing extending not past allocation size.",
336 FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,pRelatedDo));
337 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length)));
338 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Release the MDL.",FsRtlMdlWriteCompleteDev(Pfo,&Offset,MdlChain,pRelatedDo));
339
340
341 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */
342 Offset.QuadPart = 0;
343 MdlChain = NULL;
344 Length = 65*_1KB;
345 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - 65KB IO Test.",
346 FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,pRelatedDo));
347 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Release the MDL.",FsRtlMdlWriteCompleteDev(Pfo,&Offset,MdlChain,pRelatedDo));
348
349 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */
350 Length = 64*_1KB;
351 MdlChain = NULL;
352 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - 64KB IO Test.",
353 FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL))
354 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Release the MDL.",FsRtlMdlWriteCompleteDev(Pfo,&Offset,MdlChain,NULL));
355
356 /* Test the fast Io not possible flag */
357 FcbHeader->IsFastIoPossible = FastIoIsNotPossible;
358 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - FastIo is not possible flag.",
359 !FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL))
360
361 if (Pfo)
362 {
363 ObDereferenceObject(Pfo);
364 Pfo = NULL;
365 }
366
367 if (Fh)
368 {
369 ZwClose(Fh);
370 Fh = NULL;
371 }
372
373 /* ------------------------------------------------------------------------
374 TESTING:
375 BOOLEAN
376 NTAPI
377 FsRtlPrepareMdlWrite( IN PFILE_OBJECT FileObject,
378 IN PLARGE_INTEGER FileOffset,
379 IN ULONG Length,
380 IN ULONG LockKey,
381 OUT PMDL *MdlChain,
382 OUT PIO_STATUS_BLOCK IoStatus,
383 IN PDEVICE_OBJECT DeviceObject)
384
385 ------------------------------------------------------------------------ */
386
387 /* We are going to repeat the same bunch of tests but with Wait = FALSE. So we exercise the second part of the function. */
388 FsRtlTest_OpenTestFile(&Fh, &Pfo);
389
390 /* Extract the test variable from the FCB struct */
391 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext;
392 AllocationSize = &FcbHeader->AllocationSize;
393 ValidDataLength = &FcbHeader->ValidDataLength;
394 FileSize = &FcbHeader->FileSize;
395
396 /* Try to cache without caching having been initialized. This should fail.*/
397 Length = 10*_1KB;
398 FSRTL_TEST("FsRtlPrepareMdlWrite() - No cache map test. Wait = FALSE",
399 !FsRtlPrepareMdlWrite(Pfo,AllocationSize,Length,0,MdlChain,&IoStatus));
400
401 /* We are going to build a 100k file */
402 /* This will inititate caching and build some size */
403 Offset.QuadPart = 0;
404 Length = 100*_1KB;
405 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus);
406 FSRTL_TEST("FsRtlPrepareMdlWrite() - Building 100k filesize. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
407 Return = TRUE;
408
409 /* Extending the file by 1/2 sector, 256 bytes. */
410 Offset.QuadPart = 0x7fffffffffff;
411 Length = 0x100;
412 Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus);
413 FSRTL_TEST("FsRtlPrepareMdlWrite() - Extending by 1/2 sector. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
414 Return = TRUE;
415
416
417 /* Append to the file past the allocation size*/
418 MdlChain = NULL;
419 Offset.QuadPart = FileSize->QuadPart;
420 OldSize.QuadPart = FileSize->QuadPart;
421 Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart);
422 FSRTL_TEST("FsRtlPrepareMdlWrite() - Testing extending past allocation size.",
423 !FsRtlPrepareMdlWrite(Pfo,&Offset,Length+1,0,&MdlChain,&IoStatus));
424
425 FSRTL_TEST("FsRtlPrepareMdlWrite() - Testing extending not past allocation size.",
426 FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus));
427 FSRTL_TEST("FsRtlPrepareMdlWrite() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length)));
428 FSRTL_TEST("FsRtlPrepareMdlWrite() - Release the MDL.",FsRtlMdlWriteComplete(Pfo,&Offset,MdlChain));
429
430
431 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */
432 Offset.QuadPart = 0;
433 MdlChain = NULL;
434 Length = 65*_1KB;
435 FSRTL_TEST("FsRtlPrepareMdlWrite() - 65KB IO Test.",
436 !FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus));
437 //FSRTL_TEST("FsRtlPrepareMdlWrite() - Release the MDL.",FsRtlMdlWriteComplete(Pfo,&Offset,MdlChain));
438
439 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */
440 Length = 64*_1KB;
441 MdlChain = NULL;
442 FSRTL_TEST("FsRtlPrepareMdlWrite() - 64KB IO Test.",
443 FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus))
444 FSRTL_TEST("FsRtlPrepareMdlWrite() - Release the MDL.",FsRtlMdlWriteComplete(Pfo,&Offset,MdlChain));
445
446 /* Test the fast Io not possible flag */
447 FcbHeader->IsFastIoPossible = FastIoIsNotPossible;
448 FSRTL_TEST("FsRtlPrepareMdlWrite() - FastIo is not possible flag.",
449 !FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus))
450
451 if (Pfo)
452 {
453 ObDereferenceObject(Pfo);
454 Pfo = NULL;
455 }
456
457 if (Fh)
458 {
459 ZwClose(Fh);
460 Fh = NULL;
461 }
462
463 /* ------------------------------------------------------------------------------------------
464 TESTING:
465
466 FsRtlMdlReadDev(IN PFILE_OBJECT FileObject,
467 IN PLARGE_INTEGER FileOffset,
468 IN ULONG Length,
469 IN ULONG LockKey,
470 OUT PMDL *MdlChain,
471 OUT PIO_STATUS_BLOCK IoStatus,
472 IN PDEVICE_OBJECT DeviceObject)
473
474 FsRtlMdlReadCompleteDev(IN PFILE_OBJECT FileObject,
475 IN PMDL MemoryDescriptorList,
476 IN PDEVICE_OBJECT DeviceObject)
477
478 ------------------------------------------------------------------------------------------
479 */
480
481 FsRtlTest_OpenTestFile(&Fh, &Pfo);
482
483 /* Extract the test variable from the FCB struct */
484 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext;
485 AllocationSize = &FcbHeader->AllocationSize;
486 ValidDataLength = &FcbHeader->ValidDataLength;
487 FileSize = &FcbHeader->FileSize;
488
489
490 /* We are going to build a 100k file */
491 /* This will inititate caching and build some size */
492 Offset.QuadPart = 0;
493 Length = 100*_1KB;
494 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus);
495 FSRTL_TEST("FsRtlMdlReadDev() - Building 100k filesize.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
496 Return = TRUE;
497
498
499 Offset.LowPart = 0x0;
500 Offset.HighPart = 0x0;
501 Length = 0x10000;
502
503 /* Testing a 64KB read */
504 MdlChain = NULL;
505 Return = FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL);
506 FSRTL_TEST("FsRtlMdlReadDev() - Testing 64k IO",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
507 FSRTL_TEST("FsRtlMdlReadDev() - Releasing the MDL",FsRtlMdlReadCompleteDev(Pfo,MdlChain,NULL));
508
509
510 /* Testing read past the end of the file */
511 Offset.QuadPart = FileSize->QuadPart - (5 * _1KB);
512 Length = 10 * _1KB;
513 MdlChain = NULL;
514 Return = FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL);
515 FSRTL_TEST("FsRtlMdlReadDev() - Testing reading past end of file but starting before EOF",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status) && IoStatus.Information == (FileSize->QuadPart-Offset.QuadPart)));
516 FSRTL_TEST("FsRtlMdlReadDev() - Releasing the MDL",FsRtlMdlReadCompleteDev(Pfo,MdlChain,NULL));
517
518 Offset.QuadPart = FileSize->QuadPart + 1;
519 Length = 10 * _1KB;
520 MdlChain = NULL;
521 Return = FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL);
522 FSRTL_TEST("FsRtlMdlReadDev() - Testing reading past end of file but starting after EOF",(NT_SUCCESS(Return) && (IoStatus.Status == STATUS_END_OF_FILE) && IoStatus.Information == 0));
523
524 /* Testing FastIoIsNotPossible */
525 Offset.LowPart = 0x0;
526 Offset.HighPart = 0x0;
527 MdlChain = NULL;
528 Length = 0x10000;
529 FcbHeader->IsFastIoPossible = FastIoIsNotPossible;
530 FSRTL_TEST("FsRtlMdlReadDev() - FastIo is not possible flag. Wait = TRUE",!FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL));
531
532 Return = TRUE;
533
534 if (Pfo)
535 {
536 ObDereferenceObject(Pfo);
537 Pfo = NULL;
538 }
539
540 if (Fh)
541 {
542 ZwClose(Fh);
543 Fh = NULL;
544 }
545
546 /* ------------------------------------------------------------------------------------------
547 TESTING:
548
549 FsRtlMdlRead(IN PFILE_OBJECT FileObject,
550 IN PLARGE_INTEGER FileOffset,
551 IN ULONG Length,
552 IN ULONG LockKey,
553 OUT PMDL *MdlChain,
554 OUT PIO_STATUS_BLOCK IoStatus)
555
556 FsRtlMdlReadComplete(IN PFILE_OBJECT FileObject,
557 IN PMDL MemoryDescriptorList)
558
559 ------------------------------------------------------------------------------------------
560 */
561
562 FsRtlTest_OpenTestFile(&Fh, &Pfo);
563
564 /* Extract the test variable from the FCB struct */
565 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext;
566 AllocationSize = &FcbHeader->AllocationSize;
567 ValidDataLength = &FcbHeader->ValidDataLength;
568 FileSize = &FcbHeader->FileSize;
569
570
571 /* We are going to build a 100k file */
572 /* This will inititate caching and build some size */
573 Offset.QuadPart = 0;
574 Length = 100*_1KB;
575 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus);
576 FSRTL_TEST("FsRtlMdlRead() - Building 100k filesize.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
577 Return = TRUE;
578
579
580 Offset.LowPart = 0x0;
581 Offset.HighPart = 0x0;
582 Length = 0x10000;
583
584 /* Testing a 64KB read */
585 MdlChain = NULL;
586 Return = FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus);
587 FSRTL_TEST("FsRtlMdlRead() - Testing 64k IO",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length));
588 FSRTL_TEST("FsRtlMdlRead() - Releasing the MDL",FsRtlMdlReadComplete(Pfo,MdlChain));
589
590
591 /* Testing read past the end of the file */
592 Offset.QuadPart = FileSize->QuadPart - (5 * _1KB);
593 Length = 10 * _1KB;
594 MdlChain = NULL;
595 Return = FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus);
596 FSRTL_TEST("FsRtlMdlRead() - Testing reading past end of file but starting before EOF",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status) && IoStatus.Information == (FileSize->QuadPart-Offset.QuadPart)));
597 FSRTL_TEST("FsRtlMdlRead() - Releasing the MDL",FsRtlMdlReadComplete(Pfo,MdlChain));
598
599 Offset.QuadPart = FileSize->QuadPart + 1;
600 Length = 10 * _1KB;
601 MdlChain = NULL;
602 Return = FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus);
603 FSRTL_TEST("FsRtlMdlRead() - Testing reading past end of file but starting after EOF",(NT_SUCCESS(Return) && (IoStatus.Status == STATUS_END_OF_FILE) && IoStatus.Information == 0));
604
605 /* Testing FastIoIsNotPossible */
606 Offset.LowPart = 0x0;
607 Offset.HighPart = 0x0;
608 MdlChain = NULL;
609 Length = 0x10000;
610 FcbHeader->IsFastIoPossible = FastIoIsNotPossible;
611 FSRTL_TEST("FsRtlMdlRead() - FastIo is not possible flag. Wait = TRUE",!FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus));
612
613 Return = TRUE;
614
615 if (Pfo)
616 {
617 ObDereferenceObject(Pfo);
618 Pfo = NULL;
619 }
620
621 if (Fh)
622 {
623 ZwClose(Fh);
624 Fh = NULL;
625 }
626
627
628
629 /* ------------------------------------------------------------------------------------------
630 TESTING:
631
632 FsRtlGetFileSize(IN PFILE_OBJECT FileObject,
633 IN OUT PLARGE_INTEGER FileSize)
634
635 ------------------------------------------------------------------------------------------
636 */
637 FsRtlTest_OpenTestFile(&Fh, &Pfo);
638 FSRTL_TEST("FsRtlGetFileSize() - Opening Test File.",((Pfo != NULL) && (Fh != NULL)));
639
640 FsRtlTest_OpenTestDirectory(&DirFh, &DirPfo);
641 FSRTL_TEST("FsRtlGetFileSize() - Opening Test Directory.",((DirPfo != NULL) && (DirFh != NULL)));
642
643 Status = FsRtlGetFileSize(Pfo,&OldSize);
644 FSRTL_TEST("FsRtlGetFileSize() - Get the size of a real file",NT_SUCCESS(Status));
645
646 Status = FsRtlGetFileSize(DirPfo,&OldSize);
647 FSRTL_TEST("FsRtlGetFileSize() - Get the size of a directory file",(Status == STATUS_FILE_IS_A_DIRECTORY));
648
649
650 /* The test if over. Do clean up */
651
652 Cleanup:
653
654 if (DirPfo)
655 {
656 ObDereferenceObject(DirPfo);
657 DirPfo = NULL;
658 }
659
660 if (DirFh)
661 {
662 ZwClose(DirFh);
663 DirFh = NULL;
664 }
665 if (Pfo)
666 {
667 ObDereferenceObject(Pfo);
668 Pfo = NULL;
669 }
670
671 if (Fh)
672 {
673 ZwClose(Fh);
674 Fh = NULL;
675 }
676
677 if (Buffer != NULL) {
678 ExFreePool(Buffer);
679 Buffer = NULL;
680 }
681
682 return Return;
683
684 }
685
686 /* This function is just a wrapper around ZwWriteFile */
687 NTSTATUS FsRltTest_WritefileZw(HANDLE fh, PLARGE_INTEGER Offset, ULONG Length, PVOID Buffer, PIO_STATUS_BLOCK pIoStatus){
688 NTSTATUS Return;
689
690 Return = ZwWriteFile(
691 fh,
692 NULL,
693 NULL,
694 NULL,
695 pIoStatus,
696 Buffer,
697 Length,
698 Offset,
699 NULL
700 );
701
702 return Return;
703 }
704
705 /* This function fills the buffer with a test pattern */
706 void FsRtlTest_FillBuffer(LARGE_INTEGER Start, ULONG Length, PVOID Buffer) {
707 ULONG i = 0;
708 PULONGLONG Index = (PULONGLONG) Buffer;
709
710 for (i=0; i<Length/sizeof(ULONGLONG); i++) {
711 Index[i] = Start.QuadPart + i;
712 }
713
714 return;
715 }
716
717 /* This function opens a test file with the FILE_DELETE_ON_CLOSE flag
718 and reference the file object
719 */
720 NTSTATUS FsRtlTest_OpenTestFile(PHANDLE Pfh, PFILE_OBJECT *Ppfo) {
721 UNICODE_STRING FileName;
722 OBJECT_ATTRIBUTES oa;
723 IO_STATUS_BLOCK IoStatus;
724 NTSTATUS Return;
725
726 RtlInitUnicodeString(&FileName,L"\\??\\C:\\fsrtl.bin");
727
728 InitializeObjectAttributes(
729 &oa,
730 &FileName,
731 OBJ_KERNEL_HANDLE,
732 NULL,
733 NULL;
734 );
735
736 Return = IoCreateFile(Pfh,
737 GENERIC_WRITE,
738 &oa,
739 &IoStatus,
740 0,
741 FILE_ATTRIBUTE_NORMAL,
742 0,
743 FILE_OVERWRITE_IF ,
744 FILE_SYNCHRONOUS_IO_ALERT | FILE_DELETE_ON_CLOSE,
745 NULL,
746 0,
747 CreateFileTypeNone,
748 NULL,
749 0);
750
751 Return = ObReferenceObjectByHandle(
752 *Pfh,
753 GENERIC_WRITE,
754 NULL,
755 KernelMode,
756 Ppfo,
757 NULL
758 );
759 }
760
761 NTSTATUS FsRtlTest_OpenTestDirectory(PHANDLE Pfh, PFILE_OBJECT *Ppfo) {
762 UNICODE_STRING FileName;
763 OBJECT_ATTRIBUTES oa;
764 IO_STATUS_BLOCK IoStatus;
765 NTSTATUS Return;
766
767 RtlInitUnicodeString(&FileName,L"\\??\\C:\\testdir01");
768
769 InitializeObjectAttributes(
770 &oa,
771 &FileName,
772 OBJ_KERNEL_HANDLE,
773 NULL,
774 NULL;
775 );
776
777 Return = IoCreateFile(Pfh,
778 GENERIC_WRITE,
779 &oa,
780 &IoStatus,
781 0,
782 FILE_ATTRIBUTE_NORMAL,
783 0,
784 FILE_OPEN_IF,
785 FILE_DIRECTORY_FILE,FILE_SYNCHRONOUS_IO_ALERT | FILE_DELETE_ON_CLOSE,
786 NULL,
787 0,
788 CreateFileTypeNone,
789 NULL,
790 0);
791
792 Return = ObReferenceObjectByHandle(
793 *Pfh,
794 GENERIC_WRITE,
795 NULL,
796 KernelMode,
797 Ppfo,
798 NULL
799 );
800 }
801
802 /* All the testing is done from driver entry */
803 NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
804 {
805 PDEVICE_OBJECT DeviceObject;
806 NTSTATUS mStatus;
807 UNICODE_STRING uniName, uniDOSName;
808 PDEVOBJ_EXTENSION x;
809
810 DbgPrint("Loading the FSRTL test driver.\n");
811 DbgBreakPoint();
812
813 /* register device functions */
814 DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRtlTest_DispatchCreateClose;
815 DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRtlTest_DispatchCreateClose;
816 DriverObject->DriverUnload = FsRtlTest_Unload;
817
818 if (!FsRtlTest_StartTest()) {
819 DbgPrint("FsRtl test failed.\n");
820 } else {
821 DbgPrint("FsRtl test OK.\n");
822 }
823
824 return STATUS_SUCCESS;
825 }
826
827
828
829
830
831
832 NTSTATUS FsRtlTest_DispatchCreateClose( IN PDEVICE_OBJECT devObj, IN PIRP Irp )
833 {
834 DbgPrint(("FsRtl: Open / Close\n"));
835
836 Irp->IoStatus.Information = 0;
837 Irp->IoStatus.Status = STATUS_SUCCESS;
838 IoCompleteRequest( Irp, IO_NO_INCREMENT );
839
840 return STATUS_SUCCESS;
841 }
842
843 VOID FsRtlTest_Unload( IN PDRIVER_OBJECT DriverObject )
844 {
845 DbgPrint(("FsRtl: Unloading.\n"));
846 }
847
848