xref: /reactos/ntoskrnl/tests/fsrtl.c (revision 40462c92)
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 
849