3 #include "fsrtl_glue.h"
9 This is the main test function. It is called from DriverEntry.
11 There is a DbgBreakPoint() call at the beginning of DriverEntry.
12 In order to run the test again, simply type
19 BOOLEAN
FsRtlTest_StartTest() {
21 IO_STATUS_BLOCK IoStatus
;
22 NTSTATUS Return
= TRUE
;
30 LARGE_INTEGER OldSize
;
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
;
38 /* Allocate a 100KB buffer to do IOs */
39 Buffer
= ExAllocatePool(PagedPool
,100*_1KB
);
41 FsRtlTest_OpenTestFile(&Fh
, &Pfo
);
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
;
49 /* Try to cache without caching having been initialized. This should fail.*/
51 FSRTL_TEST("No cache map test.",!FsRtlCopyWrite(Pfo
,AllocationSize
,Length
,TRUE
,0,Buffer
,&IoStatus
,NULL
));
53 /* We are going to build a 100k file */
54 /* This will inititate caching and build some size */
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
));
61 /* Extending the file by 1/2 sector, 256 bytes. */
62 Offset
.QuadPart
= 0x7fffffffffff;
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
));
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
)));
77 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */
80 FSRTL_TEST("65KB IO Test",!FsRtlCopyWrite(Pfo
,&Offset
,Length
,TRUE
,0,Buffer
,&IoStatus
,NULL
));
82 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */
84 FSRTL_TEST("64KB IO Test",FsRtlCopyWrite(Pfo
,&Offset
,Length
,TRUE
,0,Buffer
,&IoStatus
,NULL
))
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))
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
))
102 ObDereferenceObject(Pfo
);
113 /* ------------------------------------------------------------------------*/
114 /* ------------------------------------------------------------------------*/
115 /* ------------------------------------------------------------------------*/
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
);
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
;
126 /* Try to cache without caching having been initialized. This should fail.*/
128 FSRTL_TEST("No cache map test. Wait = FALSE",!FsRtlCopyWrite(Pfo
,AllocationSize
,Length
,FALSE
,0,Buffer
,&IoStatus
,NULL
));
130 /* We are going to build a 100k file */
131 /* This will inititate caching and build some size */
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
));
138 /* Extending the file by 1/2 sector, 256 bytes. */
139 Offset
.QuadPart
= 0x7fffffffffff;
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
));
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
)));
154 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */
157 FSRTL_TEST("65KB IO Test. Wait = FALSE",!FsRtlCopyWrite(Pfo
,&Offset
,Length
,FALSE
,0,Buffer
,&IoStatus
,NULL
));
159 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */
161 FSRTL_TEST("64KB IO Test. Wait = FALSE",FsRtlCopyWrite(Pfo
,&Offset
,Length
,FALSE
,0,Buffer
,&IoStatus
,NULL
))
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))
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
))
178 /* ------------------------------------------------------------------------------------------
179 ------------------------------------------------------------------------------------------
180 ------------------------------------------------------------------------------------------
183 /* Testing FsRtlCopyRead() function */
185 Offset
.LowPart
= 0x0;
186 Offset
.HighPart
= 0x0;
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
));
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
));
199 /* Testing read past the end of the file */
200 Offset
.QuadPart
= FileSize
->QuadPart
- (5 * _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
)));
205 Offset
.QuadPart
= FileSize
->QuadPart
+ 1;
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));
211 /* Testing a 64KB read with Wait = TRUE */
212 Offset
.LowPart
= 0x0;
213 Offset
.HighPart
= 0x0;
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
));
225 ObDereferenceObject(Pfo
);
235 if (Buffer
!= NULL
) {
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
){
248 Return
= ZwWriteFile(
263 /* This function fills the buffer with a test pattern */
264 void FsRtlTest_FillBuffer(LARGE_INTEGER Start
, ULONG Length
, PVOID Buffer
) {
266 PULONGLONG Index
= (PULONGLONG
) Buffer
;
268 for (i
=0; i
<Length
/sizeof(ULONGLONG
); i
++) {
269 Index
[i
] = Start
.QuadPart
+ i
;
275 /* This function opens a test file with the FILE_DELETE_ON_CLOSE flag
276 and reference the file object
278 NTSTATUS
FsRtlTest_OpenTestFile(PHANDLE Pfh
, PFILE_OBJECT
*Ppfo
) {
279 UNICODE_STRING FileName
;
280 OBJECT_ATTRIBUTES oa
;
281 IO_STATUS_BLOCK IoStatus
;
284 RtlInitUnicodeString(&FileName
,L
"\\??\\C:\\fsrtl.bin");
286 InitializeObjectAttributes(
294 Return
= IoCreateFile(Pfh
,
299 FILE_ATTRIBUTE_NORMAL
,
302 FILE_SYNCHRONOUS_IO_ALERT
| FILE_DELETE_ON_CLOSE
,
309 Return
= ObReferenceObjectByHandle(
320 /* All the testing is done from driver entry */
321 NTSTATUS
DriverEntry( IN PDRIVER_OBJECT DriverObject
, IN PUNICODE_STRING RegistryPath
)
323 PDEVICE_OBJECT DeviceObject
;
325 UNICODE_STRING uniName
, uniDOSName
;
328 DbgPrint("Loading the FSRTL test driver.\n");
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
;
336 if (!FsRtlTest_StartTest()) {
337 DbgPrint("FsRtl test failed.\n");
339 DbgPrint("FsRtl test OK.\n");
342 return STATUS_SUCCESS
;
350 NTSTATUS
FsRtlTest_DispatchCreateClose( IN PDEVICE_OBJECT devObj
, IN PIRP Irp
)
352 DbgPrint(("FsRtl: Open / Close\n"));
354 Irp
->IoStatus
.Information
= 0;
355 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
356 IoCompleteRequest( Irp
, IO_NO_INCREMENT
);
358 return STATUS_SUCCESS
;
361 VOID
FsRtlTest_Unload( IN PDRIVER_OBJECT DriverObject
)
363 DbgPrint(("FsRtl: Unloading.\n"));