2009-10-12 03:35:35 +00:00
# include <ntifs.h>
# 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 ; i < Length / sizeof ( ULONGLONG ) ; i + + ) {
Index [ i ] = Start . QuadPart + i ;
}
return ;
}
/* This function opens a test file with the FILE_DELETE_ON_CLOSE flag
and reference the file object
*/
NTSTATUS FsRtlTest_OpenTestFile ( PHANDLE Pfh , PFILE_OBJECT * Ppfo ) {
UNICODE_STRING FileName ;
OBJECT_ATTRIBUTES oa ;
IO_STATUS_BLOCK IoStatus ;
NTSTATUS Return ;
RtlInitUnicodeString ( & FileName , L " \\ ?? \\ C: \\ fsrtl.bin " ) ;
InitializeObjectAttributes (
& oa ,
& FileName ,
OBJ_KERNEL_HANDLE ,
NULL ,
NULL ;
) ;
Return = IoCreateFile ( Pfh ,
GENERIC_WRITE ,
& oa ,
& IoStatus ,
0 ,
FILE_ATTRIBUTE_NORMAL ,
0 ,
FILE_OVERWRITE_IF ,
FILE_SYNCHRONOUS_IO_ALERT | FILE_DELETE_ON_CLOSE ,
NULL ,
0 ,
CreateFileTypeNone ,
NULL ,
0 ) ;
Return = ObReferenceObjectByHandle (
* Pfh ,
GENERIC_WRITE ,
NULL ,
KernelMode ,
Ppfo ,
NULL
) ;
}
NTSTATUS FsRtlTest_OpenTestDirectory ( PHANDLE Pfh , PFILE_OBJECT * Ppfo ) {
UNICODE_STRING FileName ;
OBJECT_ATTRIBUTES oa ;
IO_STATUS_BLOCK IoStatus ;
NTSTATUS Return ;
RtlInitUnicodeString ( & FileName , L " \\ ?? \\ C: \\ testdir01 " ) ;
InitializeObjectAttributes (
& oa ,
& FileName ,
OBJ_KERNEL_HANDLE ,
NULL ,
NULL ;
) ;
Return = IoCreateFile ( Pfh ,
GENERIC_WRITE ,
& oa ,
& IoStatus ,
0 ,
FILE_ATTRIBUTE_NORMAL ,
0 ,
FILE_OPEN_IF ,
FILE_DIRECTORY_FILE , FILE_SYNCHRONOUS_IO_ALERT | FILE_DELETE_ON_CLOSE ,
NULL ,
0 ,
CreateFileTypeNone ,
NULL ,
0 ) ;
Return = ObReferenceObjectByHandle (
* Pfh ,
GENERIC_WRITE ,
NULL ,
KernelMode ,
Ppfo ,
NULL
) ;
}
/* All the testing is done from driver entry */
NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject , IN PUNICODE_STRING RegistryPath )
{
PDEVICE_OBJECT DeviceObject ;
NTSTATUS mStatus ;
UNICODE_STRING uniName , uniDOSName ;
PDEVOBJ_EXTENSION x ;
DbgPrint ( " Loading the FSRTL test driver. \n " ) ;
DbgBreakPoint ( ) ;
/* register device functions */
DriverObject - > MajorFunction [ 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 " ) ) ;
}