#include #include "ntndk.h" #include "fsrtl_glue.h" #include "fastio.h" #include "fsrtl.h" /* This is the main test function. It is called from DriverEntry. There is a DbgBreakPoint() call at the beginning of DriverEntry. In order to run the test again, simply type net stop fsrtl net start fsrtl Author: Dom Cote */ BOOLEAN FsRtlTest_StartTest() { HANDLE Fh = NULL; PFILE_OBJECT Pfo = NULL; HANDLE DirFh = NULL; PFILE_OBJECT DirPfo = NULL; IO_STATUS_BLOCK IoStatus; BOOLEAN Return; NTSTATUS Status = STATUS_SUCCESS; LONGLONG i = 0; PCHAR Buffer; PMDL MdlChain = 0; LARGE_INTEGER Offset; ULONG Length = 0; LARGE_INTEGER OldSize; /* Parameters we are going to use in the test from the FCB */ PFSRTL_COMMON_FCB_HEADER FcbHeader; PLARGE_INTEGER AllocationSize; PLARGE_INTEGER ValidDataLength; PLARGE_INTEGER FileSize; PDEVICE_OBJECT pRelatedDo = NULL; /* Allocate a 100KB buffer to do IOs */ Buffer = ExAllocatePool(PagedPool,100*_1KB); /* ------------------------------------------------------------------------ TESTING: BOOLEAN NTAPI FsRtlCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject) with Wait = TRUE ------------------------------------------------------------------------ */ FsRtlTest_OpenTestFile(&Fh, &Pfo); FSRTL_TEST("Opening Test File.",((Pfo != NULL) && (Fh != NULL))); /* Extract the test variable from the FCB struct */ FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; AllocationSize = &FcbHeader->AllocationSize; ValidDataLength = &FcbHeader->ValidDataLength; FileSize = &FcbHeader->FileSize; /* Try to cache without caching having been initialized. This should fail.*/ Length = 10*_1KB; FSRTL_TEST("FsRtlCopyWrite() - No cache map test.",!FsRtlCopyWrite(Pfo,AllocationSize,Length,TRUE,0,Buffer,&IoStatus,NULL)); /* We are going to build a 100k file */ /* This will inititate caching and build some size */ Offset.QuadPart = 0; Length = 100*_1KB; Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); FSRTL_TEST("FsRtlCopyWrite() - Building 100k filesize.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; /* Extending the file by 1/2 sector, 256 bytes. */ Offset.QuadPart = 0x7fffffffffff; Length = 0x100; Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus); FSRTL_TEST("FsRtlCopyWrite() - Extending by 1/2 sector.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; /* Append to the file past the allocation size*/ Offset.LowPart = 0xFFFFFFFF; Offset.HighPart = 0xFFFFFFFF; OldSize.QuadPart = FileSize->QuadPart; Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart); FSRTL_TEST("FsRtlCopyWrite() - Testing extending past allocation size",!FsRtlCopyWrite(Pfo,&Offset,Length+1,TRUE,0,Buffer,&IoStatus,NULL)); FSRTL_TEST("FsRtlCopyWrite() - Testing extending not past allocation size",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)); FSRTL_TEST("FsRtlCopyWrite() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length))); /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */ Offset.QuadPart = 0; Length = 65*_1KB; FSRTL_TEST("FsRtlCopyWrite() - 65KB IO Test",!FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)); /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */ Length = 64*_1KB; FSRTL_TEST("FsRtlCopyWrite() - 64KB IO Test",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)) /* Test the fast Io questionable flag This test fails and should succeed. I am not sure why. When FsRtlCopyWrite() queries the FastIoTable of the related device object, it comes back with no. FcbHeader->IsFastIoPossible = FastIoIsQuestionable; FSRTL_TEST("FastIo is questionable flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)) */ /* Test the fast Io not possible flag */ FcbHeader->IsFastIoPossible = FastIoIsNotPossible; FSRTL_TEST("FsRtlCopyWrite() - FastIo is not possible flag",!FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)) /* Set the flag back to what it was */ FcbHeader->IsFastIoPossible = FastIoIsPossible; FSRTL_TEST("FsRtlCopyWrite() - FastIo is possbile flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)) if (Pfo) { ObDereferenceObject(Pfo); Pfo = NULL; } if (Fh) { ZwClose(Fh); Fh = NULL; } /* ------------------------------------------------------------------------ TESTING: BOOLEAN NTAPI FsRtlCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject) with Wait = FALSE ------------------------------------------------------------------------ */ /* We are going to repeat the same bunch of tests but with Wait = FALSE. So we exercise the second part of the function. */ FsRtlTest_OpenTestFile(&Fh, &Pfo); /* Extract the test variable from the FCB struct */ FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; AllocationSize = &FcbHeader->AllocationSize; ValidDataLength = &FcbHeader->ValidDataLength; FileSize = &FcbHeader->FileSize; /* Try to cache without caching having been initialized. This should fail.*/ Length = 10*_1KB; FSRTL_TEST("FsRtlCopyWrite() - No cache map test. Wait = FALSE",!FsRtlCopyWrite(Pfo,AllocationSize,Length,FALSE,0,Buffer,&IoStatus,NULL)); /* We are going to build a 100k file */ /* This will inititate caching and build some size */ Offset.QuadPart = 0; Length = 100*_1KB; Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); FSRTL_TEST("FsRtlCopyWrite() - Building 100k filesize. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; /* Extending the file by 1/2 sector, 256 bytes. */ Offset.QuadPart = 0x7fffffffffff; Length = 0x100; Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus); FSRTL_TEST("FsRtlCopyWrite() - Extending by 1/2 sector. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; /* Append to the file past the allocation size*/ Offset.LowPart = 0xFFFFFFFF; Offset.HighPart = 0xFFFFFFFF; OldSize.QuadPart = FileSize->QuadPart; Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart); FSRTL_TEST("FsRtlCopyWrite() - Testing extending past allocation size Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length+1,FALSE,0,Buffer,&IoStatus,NULL)); FSRTL_TEST("FsRtlCopyWrite() - Testing extending not past allocation size. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)); FSRTL_TEST("FsRtlCopyWrite() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length))); /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */ Offset.QuadPart = 0; Length = 65*_1KB; FSRTL_TEST("FsRtlCopyWrite() - 65KB IO Test. Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)); /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */ Length = 64*_1KB; FSRTL_TEST("FsRtlCopyWrite() - 64KB IO Test. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)) /* Test the fast Io questionable flag This test fails and should succeed. I am not sure why. When FsRtlCopyWrite() queries the FastIoTable of the related device object, it comes back with no. FcbHeader->IsFastIoPossible = FastIoIsQuestionable; FSRTL_TEST("FastIo is questionable flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)) */ /* Test the fast Io not possible flag */ FcbHeader->IsFastIoPossible = FastIoIsNotPossible; FSRTL_TEST("FsRtlCopyWrite() - FastIo is not possible flag. Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)) /* Set the flag back to what it was */ FcbHeader->IsFastIoPossible = FastIoIsPossible; FSRTL_TEST("FsRtlCopyWrite() - FastIo is possbile flag. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)) /* ------------------------------------------------------------------------------------------ TESTING: BOOLEAN NTAPI FsRtlCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject) ------------------------------------------------------------------------------------------ */ Offset.LowPart = 0x0; Offset.HighPart = 0x0; Length = 0x10000; /* Testing a 64KB read with Wait = TRUE */ Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL); FSRTL_TEST("FsRtlCopyRead() - Testing 64k IO Wait=TRUE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; /* Testing a 64KB read with Wait = FALSE */ Return = FsRtlCopyRead(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL); FSRTL_TEST("FsRtlCopyRead() - Testing 64k IO Wait=FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; /* Testing read past the end of the file */ Offset.QuadPart = FileSize->QuadPart - (5 * _1KB); Length = 10 * _1KB; Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL); 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))); Offset.QuadPart = FileSize->QuadPart + 1; Length = 10 * _1KB; Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL); 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)); /* Testing a 64KB read with Wait = TRUE */ Offset.LowPart = 0x0; Offset.HighPart = 0x0; Length = 0x10000; FcbHeader->IsFastIoPossible = FastIoIsNotPossible; FSRTL_TEST("FsRtlCopyRead() - FastIo is not possible flag. Wait = FALSE",!FsRtlCopyRead(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)); FSRTL_TEST("FsRtlCopyRead() - FastIo is not possible flag. Wait = TRUE",!FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)); FcbHeader->IsFastIoPossible = FastIoIsPossible; Return = TRUE; if (Pfo) { ObDereferenceObject(Pfo); Pfo = NULL; } if (Fh) { ZwClose(Fh); Fh = NULL; } /* ------------------------------------------------------------------------ TESTING: BOOLEAN NTAPI FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject) ------------------------------------------------------------------------ */ /* We are going to repeat the same bunch of tests but with Wait = FALSE. So we exercise the second part of the function. */ FsRtlTest_OpenTestFile(&Fh, &Pfo); /* Extract the test variable from the FCB struct */ FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; AllocationSize = &FcbHeader->AllocationSize; ValidDataLength = &FcbHeader->ValidDataLength; FileSize = &FcbHeader->FileSize; /* Try to cache without caching having been initialized. This should fail.*/ Length = 10*_1KB; FSRTL_TEST("FsRtlPrepareMdlWriteDev() - No cache map test. Wait = FALSE", !FsRtlPrepareMdlWriteDev(Pfo,AllocationSize,Length,0,MdlChain,&IoStatus,NULL)); /* We are going to build a 100k file */ /* This will inititate caching and build some size */ Offset.QuadPart = 0; Length = 100*_1KB; Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Building 100k filesize. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; /* Extending the file by 1/2 sector, 256 bytes. */ Offset.QuadPart = 0x7fffffffffff; Length = 0x100; Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus); FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Extending by 1/2 sector. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; pRelatedDo = IoGetRelatedDeviceObject(Pfo); FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Did we get related DO ?",pRelatedDo); /* Append to the file past the allocation size*/ Offset.QuadPart = FileSize->QuadPart; OldSize.QuadPart = FileSize->QuadPart; Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart); FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Testing extending past allocation size.", !FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length+1,0,&MdlChain,&IoStatus,pRelatedDo)); FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Testing extending not past allocation size.", FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,pRelatedDo)); FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length))); FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Release the MDL.",FsRtlMdlWriteCompleteDev(Pfo,&Offset,MdlChain,pRelatedDo)); /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */ Offset.QuadPart = 0; MdlChain = NULL; Length = 65*_1KB; FSRTL_TEST("FsRtlPrepareMdlWriteDev() - 65KB IO Test.", FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,pRelatedDo)); FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Release the MDL.",FsRtlMdlWriteCompleteDev(Pfo,&Offset,MdlChain,pRelatedDo)); /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */ Length = 64*_1KB; MdlChain = NULL; FSRTL_TEST("FsRtlPrepareMdlWriteDev() - 64KB IO Test.", FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL)) FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Release the MDL.",FsRtlMdlWriteCompleteDev(Pfo,&Offset,MdlChain,NULL)); /* Test the fast Io not possible flag */ FcbHeader->IsFastIoPossible = FastIoIsNotPossible; FSRTL_TEST("FsRtlPrepareMdlWriteDev() - FastIo is not possible flag.", !FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL)) if (Pfo) { ObDereferenceObject(Pfo); Pfo = NULL; } if (Fh) { ZwClose(Fh); Fh = NULL; } /* ------------------------------------------------------------------------ TESTING: BOOLEAN NTAPI FsRtlPrepareMdlWrite( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject) ------------------------------------------------------------------------ */ /* We are going to repeat the same bunch of tests but with Wait = FALSE. So we exercise the second part of the function. */ FsRtlTest_OpenTestFile(&Fh, &Pfo); /* Extract the test variable from the FCB struct */ FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; AllocationSize = &FcbHeader->AllocationSize; ValidDataLength = &FcbHeader->ValidDataLength; FileSize = &FcbHeader->FileSize; /* Try to cache without caching having been initialized. This should fail.*/ Length = 10*_1KB; FSRTL_TEST("FsRtlPrepareMdlWrite() - No cache map test. Wait = FALSE", !FsRtlPrepareMdlWrite(Pfo,AllocationSize,Length,0,MdlChain,&IoStatus)); /* We are going to build a 100k file */ /* This will inititate caching and build some size */ Offset.QuadPart = 0; Length = 100*_1KB; Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); FSRTL_TEST("FsRtlPrepareMdlWrite() - Building 100k filesize. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; /* Extending the file by 1/2 sector, 256 bytes. */ Offset.QuadPart = 0x7fffffffffff; Length = 0x100; Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus); FSRTL_TEST("FsRtlPrepareMdlWrite() - Extending by 1/2 sector. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; /* Append to the file past the allocation size*/ MdlChain = NULL; Offset.QuadPart = FileSize->QuadPart; OldSize.QuadPart = FileSize->QuadPart; Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart); FSRTL_TEST("FsRtlPrepareMdlWrite() - Testing extending past allocation size.", !FsRtlPrepareMdlWrite(Pfo,&Offset,Length+1,0,&MdlChain,&IoStatus)); FSRTL_TEST("FsRtlPrepareMdlWrite() - Testing extending not past allocation size.", FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus)); FSRTL_TEST("FsRtlPrepareMdlWrite() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length))); FSRTL_TEST("FsRtlPrepareMdlWrite() - Release the MDL.",FsRtlMdlWriteComplete(Pfo,&Offset,MdlChain)); /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */ Offset.QuadPart = 0; MdlChain = NULL; Length = 65*_1KB; FSRTL_TEST("FsRtlPrepareMdlWrite() - 65KB IO Test.", !FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus)); //FSRTL_TEST("FsRtlPrepareMdlWrite() - Release the MDL.",FsRtlMdlWriteComplete(Pfo,&Offset,MdlChain)); /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */ Length = 64*_1KB; MdlChain = NULL; FSRTL_TEST("FsRtlPrepareMdlWrite() - 64KB IO Test.", FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus)) FSRTL_TEST("FsRtlPrepareMdlWrite() - Release the MDL.",FsRtlMdlWriteComplete(Pfo,&Offset,MdlChain)); /* Test the fast Io not possible flag */ FcbHeader->IsFastIoPossible = FastIoIsNotPossible; FSRTL_TEST("FsRtlPrepareMdlWrite() - FastIo is not possible flag.", !FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus)) if (Pfo) { ObDereferenceObject(Pfo); Pfo = NULL; } if (Fh) { ZwClose(Fh); Fh = NULL; } /* ------------------------------------------------------------------------------------------ TESTING: FsRtlMdlReadDev(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject) FsRtlMdlReadCompleteDev(IN PFILE_OBJECT FileObject, IN PMDL MemoryDescriptorList, IN PDEVICE_OBJECT DeviceObject) ------------------------------------------------------------------------------------------ */ FsRtlTest_OpenTestFile(&Fh, &Pfo); /* Extract the test variable from the FCB struct */ FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; AllocationSize = &FcbHeader->AllocationSize; ValidDataLength = &FcbHeader->ValidDataLength; FileSize = &FcbHeader->FileSize; /* We are going to build a 100k file */ /* This will inititate caching and build some size */ Offset.QuadPart = 0; Length = 100*_1KB; Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); FSRTL_TEST("FsRtlMdlReadDev() - Building 100k filesize.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; Offset.LowPart = 0x0; Offset.HighPart = 0x0; Length = 0x10000; /* Testing a 64KB read */ MdlChain = NULL; Return = FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL); FSRTL_TEST("FsRtlMdlReadDev() - Testing 64k IO",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); FSRTL_TEST("FsRtlMdlReadDev() - Releasing the MDL",FsRtlMdlReadCompleteDev(Pfo,MdlChain,NULL)); /* Testing read past the end of the file */ Offset.QuadPart = FileSize->QuadPart - (5 * _1KB); Length = 10 * _1KB; MdlChain = NULL; Return = FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL); 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))); FSRTL_TEST("FsRtlMdlReadDev() - Releasing the MDL",FsRtlMdlReadCompleteDev(Pfo,MdlChain,NULL)); Offset.QuadPart = FileSize->QuadPart + 1; Length = 10 * _1KB; MdlChain = NULL; Return = FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL); 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)); /* Testing FastIoIsNotPossible */ Offset.LowPart = 0x0; Offset.HighPart = 0x0; MdlChain = NULL; Length = 0x10000; FcbHeader->IsFastIoPossible = FastIoIsNotPossible; FSRTL_TEST("FsRtlMdlReadDev() - FastIo is not possible flag. Wait = TRUE",!FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL)); Return = TRUE; if (Pfo) { ObDereferenceObject(Pfo); Pfo = NULL; } if (Fh) { ZwClose(Fh); Fh = NULL; } /* ------------------------------------------------------------------------------------------ TESTING: FsRtlMdlRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus) FsRtlMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MemoryDescriptorList) ------------------------------------------------------------------------------------------ */ FsRtlTest_OpenTestFile(&Fh, &Pfo); /* Extract the test variable from the FCB struct */ FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; AllocationSize = &FcbHeader->AllocationSize; ValidDataLength = &FcbHeader->ValidDataLength; FileSize = &FcbHeader->FileSize; /* We are going to build a 100k file */ /* This will inititate caching and build some size */ Offset.QuadPart = 0; Length = 100*_1KB; Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); FSRTL_TEST("FsRtlMdlRead() - Building 100k filesize.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); Return = TRUE; Offset.LowPart = 0x0; Offset.HighPart = 0x0; Length = 0x10000; /* Testing a 64KB read */ MdlChain = NULL; Return = FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus); FSRTL_TEST("FsRtlMdlRead() - Testing 64k IO",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); FSRTL_TEST("FsRtlMdlRead() - Releasing the MDL",FsRtlMdlReadComplete(Pfo,MdlChain)); /* Testing read past the end of the file */ Offset.QuadPart = FileSize->QuadPart - (5 * _1KB); Length = 10 * _1KB; MdlChain = NULL; Return = FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus); 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))); FSRTL_TEST("FsRtlMdlRead() - Releasing the MDL",FsRtlMdlReadComplete(Pfo,MdlChain)); Offset.QuadPart = FileSize->QuadPart + 1; Length = 10 * _1KB; MdlChain = NULL; Return = FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus); 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)); /* Testing FastIoIsNotPossible */ Offset.LowPart = 0x0; Offset.HighPart = 0x0; MdlChain = NULL; Length = 0x10000; FcbHeader->IsFastIoPossible = FastIoIsNotPossible; FSRTL_TEST("FsRtlMdlRead() - FastIo is not possible flag. Wait = TRUE",!FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus)); Return = TRUE; if (Pfo) { ObDereferenceObject(Pfo); Pfo = NULL; } if (Fh) { ZwClose(Fh); Fh = NULL; } /* ------------------------------------------------------------------------------------------ TESTING: FsRtlGetFileSize(IN PFILE_OBJECT FileObject, IN OUT PLARGE_INTEGER FileSize) ------------------------------------------------------------------------------------------ */ FsRtlTest_OpenTestFile(&Fh, &Pfo); FSRTL_TEST("FsRtlGetFileSize() - Opening Test File.",((Pfo != NULL) && (Fh != NULL))); FsRtlTest_OpenTestDirectory(&DirFh, &DirPfo); FSRTL_TEST("FsRtlGetFileSize() - Opening Test Directory.",((DirPfo != NULL) && (DirFh != NULL))); Status = FsRtlGetFileSize(Pfo,&OldSize); FSRTL_TEST("FsRtlGetFileSize() - Get the size of a real file",NT_SUCCESS(Status)); Status = FsRtlGetFileSize(DirPfo,&OldSize); FSRTL_TEST("FsRtlGetFileSize() - Get the size of a directory file",(Status == STATUS_FILE_IS_A_DIRECTORY)); /* The test if over. Do clean up */ Cleanup: if (DirPfo) { ObDereferenceObject(DirPfo); DirPfo = NULL; } if (DirFh) { ZwClose(DirFh); DirFh = NULL; } if (Pfo) { ObDereferenceObject(Pfo); Pfo = NULL; } if (Fh) { ZwClose(Fh); Fh = NULL; } if (Buffer != NULL) { ExFreePool(Buffer); Buffer = NULL; } return Return; } /* This function is just a wrapper around ZwWriteFile */ NTSTATUS FsRltTest_WritefileZw(HANDLE fh, PLARGE_INTEGER Offset, ULONG Length, PVOID Buffer, PIO_STATUS_BLOCK pIoStatus){ NTSTATUS Return; Return = ZwWriteFile( fh, NULL, NULL, NULL, pIoStatus, Buffer, Length, Offset, NULL ); return Return; } /* This function fills the buffer with a test pattern */ void FsRtlTest_FillBuffer(LARGE_INTEGER Start, ULONG Length, PVOID Buffer) { ULONG i = 0; PULONGLONG Index = (PULONGLONG) Buffer; for (i=0; iMajorFunction[IRP_MJ_CREATE] = FsRtlTest_DispatchCreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRtlTest_DispatchCreateClose; DriverObject->DriverUnload = FsRtlTest_Unload; if (!FsRtlTest_StartTest()) { DbgPrint("FsRtl test failed.\n"); } else { DbgPrint("FsRtl test OK.\n"); } return STATUS_SUCCESS; } NTSTATUS FsRtlTest_DispatchCreateClose( IN PDEVICE_OBJECT devObj, IN PIRP Irp ) { DbgPrint(("FsRtl: Open / Close\n")); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_SUCCESS; } VOID FsRtlTest_Unload( IN PDRIVER_OBJECT DriverObject ) { DbgPrint(("FsRtl: Unloading.\n")); }