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