1 #include <ntifs.h> 2 #include "ntndk.h" 3 #include "fsrtl_glue.h" 4 5 #include "fastio.h" 6 #include "fsrtl.h" 7 8 /* 9 This is the main test function. It is called from DriverEntry. 10 11 There is a DbgBreakPoint() call at the beginning of DriverEntry. 12 In order to run the test again, simply type 13 net stop fsrtl 14 net start fsrtl 15 16 Author: Dom Cote 17 */ 18 19 BOOLEAN FsRtlTest_StartTest() { 20 HANDLE Fh = NULL; 21 PFILE_OBJECT Pfo = NULL; 22 23 HANDLE DirFh = NULL; 24 PFILE_OBJECT DirPfo = NULL; 25 26 27 IO_STATUS_BLOCK IoStatus; 28 BOOLEAN Return; 29 NTSTATUS Status = STATUS_SUCCESS; 30 LONGLONG i = 0; 31 32 PCHAR Buffer; 33 PMDL MdlChain = 0; 34 35 LARGE_INTEGER Offset; 36 ULONG Length = 0; 37 LARGE_INTEGER OldSize; 38 39 /* Parameters we are going to use in the test from the FCB */ 40 PFSRTL_COMMON_FCB_HEADER FcbHeader; 41 PLARGE_INTEGER AllocationSize; 42 PLARGE_INTEGER ValidDataLength; 43 PLARGE_INTEGER FileSize; 44 45 PDEVICE_OBJECT pRelatedDo = NULL; 46 47 /* Allocate a 100KB buffer to do IOs */ 48 Buffer = ExAllocatePool(PagedPool,100*_1KB); 49 50 /* ------------------------------------------------------------------------ 51 TESTING: 52 BOOLEAN 53 NTAPI 54 FsRtlCopyWrite(IN PFILE_OBJECT FileObject, 55 IN PLARGE_INTEGER FileOffset, 56 IN ULONG Length, 57 IN BOOLEAN Wait, 58 IN ULONG LockKey, 59 OUT PVOID Buffer, 60 OUT PIO_STATUS_BLOCK IoStatus, 61 IN PDEVICE_OBJECT DeviceObject) 62 63 with Wait = TRUE 64 65 ------------------------------------------------------------------------ */ 66 FsRtlTest_OpenTestFile(&Fh, &Pfo); 67 FSRTL_TEST("Opening Test File.",((Pfo != NULL) && (Fh != NULL))); 68 69 /* Extract the test variable from the FCB struct */ 70 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; 71 AllocationSize = &FcbHeader->AllocationSize; 72 ValidDataLength = &FcbHeader->ValidDataLength; 73 FileSize = &FcbHeader->FileSize; 74 75 /* Try to cache without caching having been initialized. This should fail.*/ 76 Length = 10*_1KB; 77 FSRTL_TEST("FsRtlCopyWrite() - No cache map test.",!FsRtlCopyWrite(Pfo,AllocationSize,Length,TRUE,0,Buffer,&IoStatus,NULL)); 78 79 /* We are going to build a 100k file */ 80 /* This will inititate caching and build some size */ 81 Offset.QuadPart = 0; 82 Length = 100*_1KB; 83 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); 84 FSRTL_TEST("FsRtlCopyWrite() - Building 100k filesize.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 85 Return = TRUE; 86 87 /* Extending the file by 1/2 sector, 256 bytes. */ 88 Offset.QuadPart = 0x7fffffffffff; 89 Length = 0x100; 90 Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus); 91 FSRTL_TEST("FsRtlCopyWrite() - Extending by 1/2 sector.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 92 Return = TRUE; 93 94 /* Append to the file past the allocation size*/ 95 Offset.LowPart = 0xFFFFFFFF; 96 Offset.HighPart = 0xFFFFFFFF; 97 OldSize.QuadPart = FileSize->QuadPart; 98 Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart); 99 FSRTL_TEST("FsRtlCopyWrite() - Testing extending past allocation size",!FsRtlCopyWrite(Pfo,&Offset,Length+1,TRUE,0,Buffer,&IoStatus,NULL)); 100 FSRTL_TEST("FsRtlCopyWrite() - Testing extending not past allocation size",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)); 101 FSRTL_TEST("FsRtlCopyWrite() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length))); 102 103 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */ 104 Offset.QuadPart = 0; 105 Length = 65*_1KB; 106 FSRTL_TEST("FsRtlCopyWrite() - 65KB IO Test",!FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)); 107 108 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */ 109 Length = 64*_1KB; 110 FSRTL_TEST("FsRtlCopyWrite() - 64KB IO Test",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)) 111 112 /* Test the fast Io questionable flag 113 This test fails and should succeed. I am not sure why. When FsRtlCopyWrite() queries the FastIoTable of the related 114 device object, it comes back with no. 115 FcbHeader->IsFastIoPossible = FastIoIsQuestionable; 116 FSRTL_TEST("FastIo is questionable flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)) 117 */ 118 119 /* Test the fast Io not possible flag */ 120 FcbHeader->IsFastIoPossible = FastIoIsNotPossible; 121 FSRTL_TEST("FsRtlCopyWrite() - FastIo is not possible flag",!FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)) 122 /* Set the flag back to what it was */ 123 FcbHeader->IsFastIoPossible = FastIoIsPossible; 124 FSRTL_TEST("FsRtlCopyWrite() - FastIo is possbile flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)) 125 126 if (Pfo) 127 { 128 ObDereferenceObject(Pfo); 129 Pfo = NULL; 130 } 131 132 if (Fh) 133 { 134 ZwClose(Fh); 135 Fh = NULL; 136 } 137 138 /* ------------------------------------------------------------------------ 139 TESTING: 140 BOOLEAN 141 NTAPI 142 FsRtlCopyWrite(IN PFILE_OBJECT FileObject, 143 IN PLARGE_INTEGER FileOffset, 144 IN ULONG Length, 145 IN BOOLEAN Wait, 146 IN ULONG LockKey, 147 OUT PVOID Buffer, 148 OUT PIO_STATUS_BLOCK IoStatus, 149 IN PDEVICE_OBJECT DeviceObject) 150 151 with Wait = FALSE 152 153 ------------------------------------------------------------------------ */ 154 155 /* We are going to repeat the same bunch of tests but with Wait = FALSE. So we exercise the second part of the function. */ 156 FsRtlTest_OpenTestFile(&Fh, &Pfo); 157 158 /* Extract the test variable from the FCB struct */ 159 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; 160 AllocationSize = &FcbHeader->AllocationSize; 161 ValidDataLength = &FcbHeader->ValidDataLength; 162 FileSize = &FcbHeader->FileSize; 163 164 /* Try to cache without caching having been initialized. This should fail.*/ 165 Length = 10*_1KB; 166 FSRTL_TEST("FsRtlCopyWrite() - No cache map test. Wait = FALSE",!FsRtlCopyWrite(Pfo,AllocationSize,Length,FALSE,0,Buffer,&IoStatus,NULL)); 167 168 /* We are going to build a 100k file */ 169 /* This will inititate caching and build some size */ 170 Offset.QuadPart = 0; 171 Length = 100*_1KB; 172 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); 173 FSRTL_TEST("FsRtlCopyWrite() - Building 100k filesize. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 174 Return = TRUE; 175 176 /* Extending the file by 1/2 sector, 256 bytes. */ 177 Offset.QuadPart = 0x7fffffffffff; 178 Length = 0x100; 179 Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus); 180 FSRTL_TEST("FsRtlCopyWrite() - Extending by 1/2 sector. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 181 Return = TRUE; 182 183 /* Append to the file past the allocation size*/ 184 Offset.LowPart = 0xFFFFFFFF; 185 Offset.HighPart = 0xFFFFFFFF; 186 OldSize.QuadPart = FileSize->QuadPart; 187 Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart); 188 FSRTL_TEST("FsRtlCopyWrite() - Testing extending past allocation size Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length+1,FALSE,0,Buffer,&IoStatus,NULL)); 189 FSRTL_TEST("FsRtlCopyWrite() - Testing extending not past allocation size. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)); 190 FSRTL_TEST("FsRtlCopyWrite() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length))); 191 192 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */ 193 Offset.QuadPart = 0; 194 Length = 65*_1KB; 195 FSRTL_TEST("FsRtlCopyWrite() - 65KB IO Test. Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)); 196 197 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */ 198 Length = 64*_1KB; 199 FSRTL_TEST("FsRtlCopyWrite() - 64KB IO Test. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)) 200 201 /* Test the fast Io questionable flag 202 This test fails and should succeed. I am not sure why. When FsRtlCopyWrite() queries the FastIoTable of the related 203 device object, it comes back with no. 204 FcbHeader->IsFastIoPossible = FastIoIsQuestionable; 205 FSRTL_TEST("FastIo is questionable flag",FsRtlCopyWrite(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)) 206 */ 207 208 /* Test the fast Io not possible flag */ 209 FcbHeader->IsFastIoPossible = FastIoIsNotPossible; 210 FSRTL_TEST("FsRtlCopyWrite() - FastIo is not possible flag. Wait = FALSE",!FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)) 211 /* Set the flag back to what it was */ 212 FcbHeader->IsFastIoPossible = FastIoIsPossible; 213 FSRTL_TEST("FsRtlCopyWrite() - FastIo is possbile flag. Wait = FALSE",FsRtlCopyWrite(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)) 214 215 216 /* ------------------------------------------------------------------------------------------ 217 TESTING: 218 219 BOOLEAN 220 NTAPI 221 FsRtlCopyRead(IN PFILE_OBJECT FileObject, 222 IN PLARGE_INTEGER FileOffset, 223 IN ULONG Length, 224 IN BOOLEAN Wait, 225 IN ULONG LockKey, 226 OUT PVOID Buffer, 227 OUT PIO_STATUS_BLOCK IoStatus, 228 IN PDEVICE_OBJECT DeviceObject) 229 230 ------------------------------------------------------------------------------------------ */ 231 232 Offset.LowPart = 0x0; 233 Offset.HighPart = 0x0; 234 Length = 0x10000; 235 236 /* Testing a 64KB read with Wait = TRUE */ 237 Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL); 238 FSRTL_TEST("FsRtlCopyRead() - Testing 64k IO Wait=TRUE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 239 Return = TRUE; 240 241 /* Testing a 64KB read with Wait = FALSE */ 242 Return = FsRtlCopyRead(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL); 243 FSRTL_TEST("FsRtlCopyRead() - Testing 64k IO Wait=FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 244 Return = TRUE; 245 246 /* Testing read past the end of the file */ 247 Offset.QuadPart = FileSize->QuadPart - (5 * _1KB); 248 Length = 10 * _1KB; 249 Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL); 250 FSRTL_TEST("FsRtlCopyRead() - Testing reading past end of file but starting before EOF",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status) && IoStatus.Information == (FileSize->QuadPart-Offset.QuadPart))); 251 252 Offset.QuadPart = FileSize->QuadPart + 1; 253 Length = 10 * _1KB; 254 Return = FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL); 255 FSRTL_TEST("FsRtlCopyRead() - Testing reading past end of file but starting after EOF",(NT_SUCCESS(Return) && (IoStatus.Status == STATUS_END_OF_FILE) && IoStatus.Information == 0)); 256 257 258 /* Testing a 64KB read with Wait = TRUE */ 259 Offset.LowPart = 0x0; 260 Offset.HighPart = 0x0; 261 Length = 0x10000; 262 FcbHeader->IsFastIoPossible = FastIoIsNotPossible; 263 FSRTL_TEST("FsRtlCopyRead() - FastIo is not possible flag. Wait = FALSE",!FsRtlCopyRead(Pfo,&Offset,Length,FALSE,0,Buffer,&IoStatus,NULL)); 264 FSRTL_TEST("FsRtlCopyRead() - FastIo is not possible flag. Wait = TRUE",!FsRtlCopyRead(Pfo,&Offset,Length,TRUE,0,Buffer,&IoStatus,NULL)); 265 FcbHeader->IsFastIoPossible = FastIoIsPossible; 266 Return = TRUE; 267 268 if (Pfo) 269 { 270 ObDereferenceObject(Pfo); 271 Pfo = NULL; 272 } 273 274 if (Fh) 275 { 276 ZwClose(Fh); 277 Fh = NULL; 278 } 279 280 /* ------------------------------------------------------------------------ 281 TESTING: 282 BOOLEAN 283 NTAPI 284 FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject, 285 IN PLARGE_INTEGER FileOffset, 286 IN ULONG Length, 287 IN ULONG LockKey, 288 OUT PMDL *MdlChain, 289 OUT PIO_STATUS_BLOCK IoStatus, 290 IN PDEVICE_OBJECT DeviceObject) 291 292 ------------------------------------------------------------------------ */ 293 294 /* We are going to repeat the same bunch of tests but with Wait = FALSE. So we exercise the second part of the function. */ 295 FsRtlTest_OpenTestFile(&Fh, &Pfo); 296 297 /* Extract the test variable from the FCB struct */ 298 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; 299 AllocationSize = &FcbHeader->AllocationSize; 300 ValidDataLength = &FcbHeader->ValidDataLength; 301 FileSize = &FcbHeader->FileSize; 302 303 /* Try to cache without caching having been initialized. This should fail.*/ 304 Length = 10*_1KB; 305 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - No cache map test. Wait = FALSE", 306 !FsRtlPrepareMdlWriteDev(Pfo,AllocationSize,Length,0,MdlChain,&IoStatus,NULL)); 307 308 /* We are going to build a 100k file */ 309 /* This will inititate caching and build some size */ 310 Offset.QuadPart = 0; 311 Length = 100*_1KB; 312 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); 313 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Building 100k filesize. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 314 Return = TRUE; 315 316 /* Extending the file by 1/2 sector, 256 bytes. */ 317 Offset.QuadPart = 0x7fffffffffff; 318 Length = 0x100; 319 Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus); 320 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Extending by 1/2 sector. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 321 Return = TRUE; 322 323 324 pRelatedDo = IoGetRelatedDeviceObject(Pfo); 325 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Did we get related DO ?",pRelatedDo); 326 327 328 /* Append to the file past the allocation size*/ 329 Offset.QuadPart = FileSize->QuadPart; 330 OldSize.QuadPart = FileSize->QuadPart; 331 Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart); 332 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Testing extending past allocation size.", 333 !FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length+1,0,&MdlChain,&IoStatus,pRelatedDo)); 334 335 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Testing extending not past allocation size.", 336 FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,pRelatedDo)); 337 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length))); 338 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Release the MDL.",FsRtlMdlWriteCompleteDev(Pfo,&Offset,MdlChain,pRelatedDo)); 339 340 341 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */ 342 Offset.QuadPart = 0; 343 MdlChain = NULL; 344 Length = 65*_1KB; 345 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - 65KB IO Test.", 346 FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,pRelatedDo)); 347 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Release the MDL.",FsRtlMdlWriteCompleteDev(Pfo,&Offset,MdlChain,pRelatedDo)); 348 349 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */ 350 Length = 64*_1KB; 351 MdlChain = NULL; 352 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - 64KB IO Test.", 353 FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL)) 354 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - Release the MDL.",FsRtlMdlWriteCompleteDev(Pfo,&Offset,MdlChain,NULL)); 355 356 /* Test the fast Io not possible flag */ 357 FcbHeader->IsFastIoPossible = FastIoIsNotPossible; 358 FSRTL_TEST("FsRtlPrepareMdlWriteDev() - FastIo is not possible flag.", 359 !FsRtlPrepareMdlWriteDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL)) 360 361 if (Pfo) 362 { 363 ObDereferenceObject(Pfo); 364 Pfo = NULL; 365 } 366 367 if (Fh) 368 { 369 ZwClose(Fh); 370 Fh = NULL; 371 } 372 373 /* ------------------------------------------------------------------------ 374 TESTING: 375 BOOLEAN 376 NTAPI 377 FsRtlPrepareMdlWrite( IN PFILE_OBJECT FileObject, 378 IN PLARGE_INTEGER FileOffset, 379 IN ULONG Length, 380 IN ULONG LockKey, 381 OUT PMDL *MdlChain, 382 OUT PIO_STATUS_BLOCK IoStatus, 383 IN PDEVICE_OBJECT DeviceObject) 384 385 ------------------------------------------------------------------------ */ 386 387 /* We are going to repeat the same bunch of tests but with Wait = FALSE. So we exercise the second part of the function. */ 388 FsRtlTest_OpenTestFile(&Fh, &Pfo); 389 390 /* Extract the test variable from the FCB struct */ 391 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; 392 AllocationSize = &FcbHeader->AllocationSize; 393 ValidDataLength = &FcbHeader->ValidDataLength; 394 FileSize = &FcbHeader->FileSize; 395 396 /* Try to cache without caching having been initialized. This should fail.*/ 397 Length = 10*_1KB; 398 FSRTL_TEST("FsRtlPrepareMdlWrite() - No cache map test. Wait = FALSE", 399 !FsRtlPrepareMdlWrite(Pfo,AllocationSize,Length,0,MdlChain,&IoStatus)); 400 401 /* We are going to build a 100k file */ 402 /* This will inititate caching and build some size */ 403 Offset.QuadPart = 0; 404 Length = 100*_1KB; 405 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); 406 FSRTL_TEST("FsRtlPrepareMdlWrite() - Building 100k filesize. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 407 Return = TRUE; 408 409 /* Extending the file by 1/2 sector, 256 bytes. */ 410 Offset.QuadPart = 0x7fffffffffff; 411 Length = 0x100; 412 Return = FsRltTest_WritefileZw(Fh,NULL,Length, Buffer, &IoStatus); 413 FSRTL_TEST("FsRtlPrepareMdlWrite() - Extending by 1/2 sector. Wait = FALSE",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 414 Return = TRUE; 415 416 417 /* Append to the file past the allocation size*/ 418 MdlChain = NULL; 419 Offset.QuadPart = FileSize->QuadPart; 420 OldSize.QuadPart = FileSize->QuadPart; 421 Length = (ULONG) (AllocationSize->QuadPart -ValidDataLength->QuadPart); 422 FSRTL_TEST("FsRtlPrepareMdlWrite() - Testing extending past allocation size.", 423 !FsRtlPrepareMdlWrite(Pfo,&Offset,Length+1,0,&MdlChain,&IoStatus)); 424 425 FSRTL_TEST("FsRtlPrepareMdlWrite() - Testing extending not past allocation size.", 426 FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus)); 427 FSRTL_TEST("FsRtlPrepareMdlWrite() - Check filesize",(FileSize->QuadPart = (OldSize.QuadPart+Length))); 428 FSRTL_TEST("FsRtlPrepareMdlWrite() - Release the MDL.",FsRtlMdlWriteComplete(Pfo,&Offset,MdlChain)); 429 430 431 /* Try do write a 65kb IO and check that if fails. Maximum IO size for thus function is 64KB */ 432 Offset.QuadPart = 0; 433 MdlChain = NULL; 434 Length = 65*_1KB; 435 FSRTL_TEST("FsRtlPrepareMdlWrite() - 65KB IO Test.", 436 !FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus)); 437 //FSRTL_TEST("FsRtlPrepareMdlWrite() - Release the MDL.",FsRtlMdlWriteComplete(Pfo,&Offset,MdlChain)); 438 439 /* Try do write a 64kb IO. Maximum IO size for thus function is 64KB */ 440 Length = 64*_1KB; 441 MdlChain = NULL; 442 FSRTL_TEST("FsRtlPrepareMdlWrite() - 64KB IO Test.", 443 FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus)) 444 FSRTL_TEST("FsRtlPrepareMdlWrite() - Release the MDL.",FsRtlMdlWriteComplete(Pfo,&Offset,MdlChain)); 445 446 /* Test the fast Io not possible flag */ 447 FcbHeader->IsFastIoPossible = FastIoIsNotPossible; 448 FSRTL_TEST("FsRtlPrepareMdlWrite() - FastIo is not possible flag.", 449 !FsRtlPrepareMdlWrite(Pfo,&Offset,Length,0,&MdlChain,&IoStatus)) 450 451 if (Pfo) 452 { 453 ObDereferenceObject(Pfo); 454 Pfo = NULL; 455 } 456 457 if (Fh) 458 { 459 ZwClose(Fh); 460 Fh = NULL; 461 } 462 463 /* ------------------------------------------------------------------------------------------ 464 TESTING: 465 466 FsRtlMdlReadDev(IN PFILE_OBJECT FileObject, 467 IN PLARGE_INTEGER FileOffset, 468 IN ULONG Length, 469 IN ULONG LockKey, 470 OUT PMDL *MdlChain, 471 OUT PIO_STATUS_BLOCK IoStatus, 472 IN PDEVICE_OBJECT DeviceObject) 473 474 FsRtlMdlReadCompleteDev(IN PFILE_OBJECT FileObject, 475 IN PMDL MemoryDescriptorList, 476 IN PDEVICE_OBJECT DeviceObject) 477 478 ------------------------------------------------------------------------------------------ 479 */ 480 481 FsRtlTest_OpenTestFile(&Fh, &Pfo); 482 483 /* Extract the test variable from the FCB struct */ 484 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; 485 AllocationSize = &FcbHeader->AllocationSize; 486 ValidDataLength = &FcbHeader->ValidDataLength; 487 FileSize = &FcbHeader->FileSize; 488 489 490 /* We are going to build a 100k file */ 491 /* This will inititate caching and build some size */ 492 Offset.QuadPart = 0; 493 Length = 100*_1KB; 494 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); 495 FSRTL_TEST("FsRtlMdlReadDev() - Building 100k filesize.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 496 Return = TRUE; 497 498 499 Offset.LowPart = 0x0; 500 Offset.HighPart = 0x0; 501 Length = 0x10000; 502 503 /* Testing a 64KB read */ 504 MdlChain = NULL; 505 Return = FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL); 506 FSRTL_TEST("FsRtlMdlReadDev() - Testing 64k IO",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 507 FSRTL_TEST("FsRtlMdlReadDev() - Releasing the MDL",FsRtlMdlReadCompleteDev(Pfo,MdlChain,NULL)); 508 509 510 /* Testing read past the end of the file */ 511 Offset.QuadPart = FileSize->QuadPart - (5 * _1KB); 512 Length = 10 * _1KB; 513 MdlChain = NULL; 514 Return = FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL); 515 FSRTL_TEST("FsRtlMdlReadDev() - Testing reading past end of file but starting before EOF",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status) && IoStatus.Information == (FileSize->QuadPart-Offset.QuadPart))); 516 FSRTL_TEST("FsRtlMdlReadDev() - Releasing the MDL",FsRtlMdlReadCompleteDev(Pfo,MdlChain,NULL)); 517 518 Offset.QuadPart = FileSize->QuadPart + 1; 519 Length = 10 * _1KB; 520 MdlChain = NULL; 521 Return = FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL); 522 FSRTL_TEST("FsRtlMdlReadDev() - Testing reading past end of file but starting after EOF",(NT_SUCCESS(Return) && (IoStatus.Status == STATUS_END_OF_FILE) && IoStatus.Information == 0)); 523 524 /* Testing FastIoIsNotPossible */ 525 Offset.LowPart = 0x0; 526 Offset.HighPart = 0x0; 527 MdlChain = NULL; 528 Length = 0x10000; 529 FcbHeader->IsFastIoPossible = FastIoIsNotPossible; 530 FSRTL_TEST("FsRtlMdlReadDev() - FastIo is not possible flag. Wait = TRUE",!FsRtlMdlReadDev(Pfo,&Offset,Length,0,&MdlChain,&IoStatus,NULL)); 531 532 Return = TRUE; 533 534 if (Pfo) 535 { 536 ObDereferenceObject(Pfo); 537 Pfo = NULL; 538 } 539 540 if (Fh) 541 { 542 ZwClose(Fh); 543 Fh = NULL; 544 } 545 546 /* ------------------------------------------------------------------------------------------ 547 TESTING: 548 549 FsRtlMdlRead(IN PFILE_OBJECT FileObject, 550 IN PLARGE_INTEGER FileOffset, 551 IN ULONG Length, 552 IN ULONG LockKey, 553 OUT PMDL *MdlChain, 554 OUT PIO_STATUS_BLOCK IoStatus) 555 556 FsRtlMdlReadComplete(IN PFILE_OBJECT FileObject, 557 IN PMDL MemoryDescriptorList) 558 559 ------------------------------------------------------------------------------------------ 560 */ 561 562 FsRtlTest_OpenTestFile(&Fh, &Pfo); 563 564 /* Extract the test variable from the FCB struct */ 565 FcbHeader = (PFSRTL_COMMON_FCB_HEADER)Pfo->FsContext; 566 AllocationSize = &FcbHeader->AllocationSize; 567 ValidDataLength = &FcbHeader->ValidDataLength; 568 FileSize = &FcbHeader->FileSize; 569 570 571 /* We are going to build a 100k file */ 572 /* This will inititate caching and build some size */ 573 Offset.QuadPart = 0; 574 Length = 100*_1KB; 575 Return = FsRltTest_WritefileZw(Fh,&Offset,Length, Buffer, &IoStatus); 576 FSRTL_TEST("FsRtlMdlRead() - Building 100k filesize.",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 577 Return = TRUE; 578 579 580 Offset.LowPart = 0x0; 581 Offset.HighPart = 0x0; 582 Length = 0x10000; 583 584 /* Testing a 64KB read */ 585 MdlChain = NULL; 586 Return = FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus); 587 FSRTL_TEST("FsRtlMdlRead() - Testing 64k IO",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status ) && IoStatus.Information == Length)); 588 FSRTL_TEST("FsRtlMdlRead() - Releasing the MDL",FsRtlMdlReadComplete(Pfo,MdlChain)); 589 590 591 /* Testing read past the end of the file */ 592 Offset.QuadPart = FileSize->QuadPart - (5 * _1KB); 593 Length = 10 * _1KB; 594 MdlChain = NULL; 595 Return = FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus); 596 FSRTL_TEST("FsRtlMdlRead() - Testing reading past end of file but starting before EOF",(NT_SUCCESS(Return) && NT_SUCCESS(IoStatus.Status) && IoStatus.Information == (FileSize->QuadPart-Offset.QuadPart))); 597 FSRTL_TEST("FsRtlMdlRead() - Releasing the MDL",FsRtlMdlReadComplete(Pfo,MdlChain)); 598 599 Offset.QuadPart = FileSize->QuadPart + 1; 600 Length = 10 * _1KB; 601 MdlChain = NULL; 602 Return = FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus); 603 FSRTL_TEST("FsRtlMdlRead() - Testing reading past end of file but starting after EOF",(NT_SUCCESS(Return) && (IoStatus.Status == STATUS_END_OF_FILE) && IoStatus.Information == 0)); 604 605 /* Testing FastIoIsNotPossible */ 606 Offset.LowPart = 0x0; 607 Offset.HighPart = 0x0; 608 MdlChain = NULL; 609 Length = 0x10000; 610 FcbHeader->IsFastIoPossible = FastIoIsNotPossible; 611 FSRTL_TEST("FsRtlMdlRead() - FastIo is not possible flag. Wait = TRUE",!FsRtlMdlRead(Pfo,&Offset,Length,0,&MdlChain,&IoStatus)); 612 613 Return = TRUE; 614 615 if (Pfo) 616 { 617 ObDereferenceObject(Pfo); 618 Pfo = NULL; 619 } 620 621 if (Fh) 622 { 623 ZwClose(Fh); 624 Fh = NULL; 625 } 626 627 628 629 /* ------------------------------------------------------------------------------------------ 630 TESTING: 631 632 FsRtlGetFileSize(IN PFILE_OBJECT FileObject, 633 IN OUT PLARGE_INTEGER FileSize) 634 635 ------------------------------------------------------------------------------------------ 636 */ 637 FsRtlTest_OpenTestFile(&Fh, &Pfo); 638 FSRTL_TEST("FsRtlGetFileSize() - Opening Test File.",((Pfo != NULL) && (Fh != NULL))); 639 640 FsRtlTest_OpenTestDirectory(&DirFh, &DirPfo); 641 FSRTL_TEST("FsRtlGetFileSize() - Opening Test Directory.",((DirPfo != NULL) && (DirFh != NULL))); 642 643 Status = FsRtlGetFileSize(Pfo,&OldSize); 644 FSRTL_TEST("FsRtlGetFileSize() - Get the size of a real file",NT_SUCCESS(Status)); 645 646 Status = FsRtlGetFileSize(DirPfo,&OldSize); 647 FSRTL_TEST("FsRtlGetFileSize() - Get the size of a directory file",(Status == STATUS_FILE_IS_A_DIRECTORY)); 648 649 650 /* The test if over. Do clean up */ 651 652 Cleanup: 653 654 if (DirPfo) 655 { 656 ObDereferenceObject(DirPfo); 657 DirPfo = NULL; 658 } 659 660 if (DirFh) 661 { 662 ZwClose(DirFh); 663 DirFh = NULL; 664 } 665 if (Pfo) 666 { 667 ObDereferenceObject(Pfo); 668 Pfo = NULL; 669 } 670 671 if (Fh) 672 { 673 ZwClose(Fh); 674 Fh = NULL; 675 } 676 677 if (Buffer != NULL) { 678 ExFreePool(Buffer); 679 Buffer = NULL; 680 } 681 682 return Return; 683 684 } 685 686 /* This function is just a wrapper around ZwWriteFile */ 687 NTSTATUS FsRltTest_WritefileZw(HANDLE fh, PLARGE_INTEGER Offset, ULONG Length, PVOID Buffer, PIO_STATUS_BLOCK pIoStatus){ 688 NTSTATUS Return; 689 690 Return = ZwWriteFile( 691 fh, 692 NULL, 693 NULL, 694 NULL, 695 pIoStatus, 696 Buffer, 697 Length, 698 Offset, 699 NULL 700 ); 701 702 return Return; 703 } 704 705 /* This function fills the buffer with a test pattern */ 706 void FsRtlTest_FillBuffer(LARGE_INTEGER Start, ULONG Length, PVOID Buffer) { 707 ULONG i = 0; 708 PULONGLONG Index = (PULONGLONG) Buffer; 709 710 for (i=0; i<Length/sizeof(ULONGLONG); i++) { 711 Index[i] = Start.QuadPart + i; 712 } 713 714 return; 715 } 716 717 /* This function opens a test file with the FILE_DELETE_ON_CLOSE flag 718 and reference the file object 719 */ 720 NTSTATUS FsRtlTest_OpenTestFile(PHANDLE Pfh, PFILE_OBJECT *Ppfo) { 721 UNICODE_STRING FileName; 722 OBJECT_ATTRIBUTES oa; 723 IO_STATUS_BLOCK IoStatus; 724 NTSTATUS Return; 725 726 RtlInitUnicodeString(&FileName,L"\\??\\C:\\fsrtl.bin"); 727 728 InitializeObjectAttributes( 729 &oa, 730 &FileName, 731 OBJ_KERNEL_HANDLE, 732 NULL, 733 NULL; 734 ); 735 736 Return = IoCreateFile(Pfh, 737 GENERIC_WRITE, 738 &oa, 739 &IoStatus, 740 0, 741 FILE_ATTRIBUTE_NORMAL, 742 0, 743 FILE_OVERWRITE_IF , 744 FILE_SYNCHRONOUS_IO_ALERT | FILE_DELETE_ON_CLOSE, 745 NULL, 746 0, 747 CreateFileTypeNone, 748 NULL, 749 0); 750 751 Return = ObReferenceObjectByHandle( 752 *Pfh, 753 GENERIC_WRITE, 754 NULL, 755 KernelMode, 756 Ppfo, 757 NULL 758 ); 759 } 760 761 NTSTATUS FsRtlTest_OpenTestDirectory(PHANDLE Pfh, PFILE_OBJECT *Ppfo) { 762 UNICODE_STRING FileName; 763 OBJECT_ATTRIBUTES oa; 764 IO_STATUS_BLOCK IoStatus; 765 NTSTATUS Return; 766 767 RtlInitUnicodeString(&FileName,L"\\??\\C:\\testdir01"); 768 769 InitializeObjectAttributes( 770 &oa, 771 &FileName, 772 OBJ_KERNEL_HANDLE, 773 NULL, 774 NULL; 775 ); 776 777 Return = IoCreateFile(Pfh, 778 GENERIC_WRITE, 779 &oa, 780 &IoStatus, 781 0, 782 FILE_ATTRIBUTE_NORMAL, 783 0, 784 FILE_OPEN_IF, 785 FILE_DIRECTORY_FILE,FILE_SYNCHRONOUS_IO_ALERT | FILE_DELETE_ON_CLOSE, 786 NULL, 787 0, 788 CreateFileTypeNone, 789 NULL, 790 0); 791 792 Return = ObReferenceObjectByHandle( 793 *Pfh, 794 GENERIC_WRITE, 795 NULL, 796 KernelMode, 797 Ppfo, 798 NULL 799 ); 800 } 801 802 /* All the testing is done from driver entry */ 803 NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) 804 { 805 PDEVICE_OBJECT DeviceObject; 806 NTSTATUS mStatus; 807 UNICODE_STRING uniName, uniDOSName; 808 PDEVOBJ_EXTENSION x; 809 810 DbgPrint("Loading the FSRTL test driver.\n"); 811 DbgBreakPoint(); 812 813 /* register device functions */ 814 DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRtlTest_DispatchCreateClose; 815 DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRtlTest_DispatchCreateClose; 816 DriverObject->DriverUnload = FsRtlTest_Unload; 817 818 if (!FsRtlTest_StartTest()) { 819 DbgPrint("FsRtl test failed.\n"); 820 } else { 821 DbgPrint("FsRtl test OK.\n"); 822 } 823 824 return STATUS_SUCCESS; 825 } 826 827 828 829 830 831 832 NTSTATUS FsRtlTest_DispatchCreateClose( IN PDEVICE_OBJECT devObj, IN PIRP Irp ) 833 { 834 DbgPrint(("FsRtl: Open / Close\n")); 835 836 Irp->IoStatus.Information = 0; 837 Irp->IoStatus.Status = STATUS_SUCCESS; 838 IoCompleteRequest( Irp, IO_NO_INCREMENT ); 839 840 return STATUS_SUCCESS; 841 } 842 843 VOID FsRtlTest_Unload( IN PDRIVER_OBJECT DriverObject ) 844 { 845 DbgPrint(("FsRtl: Unloading.\n")); 846 } 847 848 849