|
|
1.1.1.3 ! root 1: /* The source code contained in this file has been derived from the source code ! 2: of Encryption for the Masses 2.02a by Paul Le Roux. Modifications and ! 3: additions to that source code contained in this file are Copyright (c) 2004 ! 4: TrueCrypt Team and Copyright (c) 2004 TrueCrypt Foundation. Unmodified ! 5: parts are Copyright (c) 1998-99 Paul Le Roux. This is a TrueCrypt Foundation ! 6: release. Please see the file license.txt for full license details. */ 1.1 root 7: 8: #include "TCdefs.h" 9: #include "crypto.h" 10: #include "volumes.h" 11: 12: #include "apidrvr.h" 13: #include "ntdriver.h" 14: #include "ntvol.h" 15: #include "ntrawdv.h" 16: #include "ntfiledv.h" 17: 18: #include "cache.h" 19: 20: //#ifdef _DEBUG 21: //#define EXTRA_INFO 1 22: //#endif 23: 24: #pragma warning( disable : 4127 ) 25: 26: #define FIRST_READ_SIZE SECTOR_SIZE*2 27: 28: NTSTATUS 29: TCOpenVolume (PDEVICE_OBJECT DeviceObject, 30: PEXTENSION Extension, 31: MOUNT_STRUCT * mount, 32: PWSTR pwszMountVolume, 33: BOOL bRawDevice) 34: { 35: struct msdos_boot_sector *boot_sector = NULL; 36: FILE_STANDARD_INFORMATION FileStandardInfo; 37: FILE_BASIC_INFORMATION FileBasicInfo; 38: OBJECT_ATTRIBUTES oaFileAttributes; 39: UNICODE_STRING FullFileName; 40: IO_STATUS_BLOCK IoStatusBlock; 41: LARGE_INTEGER lDiskLength; 42: char *readBuffer; 43: NTSTATUS ntStatus; 44: 45: Extension->pfoDeviceFile = NULL; 46: Extension->hDeviceFile = NULL; 47: 48: readBuffer = TCalloc (FIRST_READ_SIZE); 49: if (readBuffer == NULL) 50: { 51: ntStatus = STATUS_INSUFFICIENT_RESOURCES; 52: goto error; 53: } 54: 55: RtlInitUnicodeString (&FullFileName, pwszMountVolume); 56: 57: InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE, 58: NULL, NULL); 59: 60: ntStatus = ZwCreateFile (&Extension->hDeviceFile, 61: GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 62: &oaFileAttributes, 63: &IoStatusBlock, 64: NULL, 65: FILE_ATTRIBUTE_NORMAL | 66: FILE_ATTRIBUTE_SYSTEM, 67: 0, 68: FILE_OPEN, 69: FILE_WRITE_THROUGH | 70: FILE_NO_INTERMEDIATE_BUFFERING | 71: FILE_SYNCHRONOUS_IO_NONALERT, 72: NULL, 73: 0); 74: 75: /* 26-4-99 NT for some partitions returns this code, it is really a 76: access denied */ 77: if (ntStatus == 0xc000001b) 78: { 79: ntStatus = STATUS_ACCESS_DENIED; 80: } 81: 82: if (ntStatus == STATUS_ACCESS_DENIED) 83: { 84: ntStatus = ZwCreateFile (&Extension->hDeviceFile, 85: GENERIC_READ | SYNCHRONIZE, 86: &oaFileAttributes, 87: &IoStatusBlock, 88: NULL, 89: FILE_ATTRIBUTE_NORMAL | 90: FILE_ATTRIBUTE_SYSTEM, 91: 0, 92: FILE_OPEN, 93: FILE_WRITE_THROUGH | 94: FILE_NO_INTERMEDIATE_BUFFERING | 95: FILE_SYNCHRONOUS_IO_NONALERT, 96: NULL, 97: 0); 98: Extension->bReadOnly = TRUE; 99: } 100: else 101: Extension->bReadOnly = FALSE; 102: 103: /* 26-4-99 NT for some partitions returns this code, it is really a 104: access denied */ 105: if (ntStatus == 0xc000001b) 106: { 107: /* Partitions which return this code can still be opened with 108: FILE_SHARE_READ but this causes NT problems elsewhere in 109: particular if you do FILE_SHARE_READ NT will die later if 110: anyone even tries to open the partition (or file for that 111: matter...) */ 112: ntStatus = STATUS_SHARING_VIOLATION; 113: } 114: 115: if (!NT_SUCCESS (ntStatus)) 116: { 117: goto error; 118: } 119: 120: ntStatus = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL, 121: &IoStatusBlock, readBuffer, FIRST_READ_SIZE, NULL, NULL); 122: 123: if (!NT_SUCCESS (ntStatus)) 124: { 125: Dump ("Read failed: NTSTATUS 0x%08x\n", ntStatus); 126: } 127: else if (IoStatusBlock.Information != FIRST_READ_SIZE) 128: { 129: Dump ("Read didn't read enough data in: %lu / %lu\n", IoStatusBlock.Information, FIRST_READ_SIZE); 130: ntStatus = STATUS_UNSUCCESSFUL; 131: } 132: 133: if (!NT_SUCCESS (ntStatus)) 134: { 135: goto error; 136: } 137: 138: 139: KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE); 140: 141: if (bRawDevice == FALSE) 142: { 143: ntStatus = ZwQueryInformationFile (Extension->hDeviceFile, 144: &IoStatusBlock, 145: &FileBasicInfo, 146: sizeof (FileBasicInfo), 147: FileBasicInformation); 148: 149: if (NT_SUCCESS (ntStatus)) 150: ntStatus = ZwQueryInformationFile (Extension->hDeviceFile, 151: &IoStatusBlock, 152: &FileStandardInfo, 153: sizeof (FileStandardInfo), 154: FileStandardInformation); 155: 156: if (!NT_SUCCESS (ntStatus)) 157: { 158: Dump ("ZwQueryInformationFile failed while opening file: NTSTATUS 0x%08x\n", 159: ntStatus); 160: goto error; 161: } 162: else 163: lDiskLength.QuadPart = FileStandardInfo.EndOfFile.QuadPart; 164: 165: if (FileBasicInfo.FileAttributes & FILE_ATTRIBUTE_COMPRESSED) 166: { 167: Dump ("File \"%ls\" is marked as compressed - not supported!\n", pwszMountVolume); 168: mount->nReturnCode = ERR_COMPRESSION_NOT_SUPPORTED; 169: ntStatus = STATUS_SUCCESS; 170: goto error; 171: } 172: 173: ntStatus = ObReferenceObjectByHandle (Extension->hDeviceFile, 174: FILE_ALL_ACCESS, 175: *IoFileObjectType, 176: KernelMode, 177: &Extension->pfoDeviceFile, 178: 0); 179: 180: if (!NT_SUCCESS (ntStatus)) 181: { 182: goto error; 183: } 184: 185: /* Get the FSD device for the file (probably either NTFS or 186: FAT) */ 187: Extension->pFsdDevice = IoGetRelatedDeviceObject (Extension->pfoDeviceFile); 188: 189: DeviceObject->StackSize = (CCHAR) (Extension->pFsdDevice->StackSize + 1); 190: 191: } 192: else 193: { 194: DISK_GEOMETRY dg; 195: 196: ZwClose (Extension->hDeviceFile); 197: Extension->hDeviceFile = NULL; 198: 199: if (Extension->bReadOnly == TRUE) 200: ntStatus = IoGetDeviceObjectPointer (&FullFileName, 201: FILE_READ_DATA, 202: &Extension->pfoDeviceFile, 203: &Extension->pFsdDevice); 204: else 205: ntStatus = IoGetDeviceObjectPointer (&FullFileName, 206: FILE_ALL_ACCESS, 207: &Extension->pfoDeviceFile, 208: &Extension->pFsdDevice); 209: 210: if (!NT_SUCCESS (ntStatus)) 211: { 212: goto error; 213: } 214: 215: DeviceObject->StackSize = (CCHAR) (Extension->pFsdDevice->StackSize + 1); 216: 217: 218: if (wcscmp (Extension->pFsdDevice->DriverObject->DriverName.Buffer, WIDE ("\\FileSystem\\RAW")) != 0) 219: { 220: /* FAT/NTFS "knows" about this device */ 221: ntStatus = STATUS_SHARING_VIOLATION; 222: goto error; 223: } 224: 225: ntStatus = TCSendDeviceIoControlRequest (DeviceObject, 226: Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY, 227: (char *) &dg, sizeof (dg)); 228: 229: if (!NT_SUCCESS (ntStatus)) 230: { 231: goto error; 232: } 233: 234: if (dg.MediaType == FixedMedia) 235: { 236: PARTITION_INFORMATION pi; 237: 238: ntStatus = TCSendDeviceIoControlRequest (DeviceObject, 239: Extension, IOCTL_DISK_GET_PARTITION_INFO, 240: (char *) &pi, sizeof (pi)); 241: 242: if (!NT_SUCCESS (ntStatus)) 243: { 244: goto error; 245: } 246: else 247: lDiskLength.QuadPart = pi.PartitionLength.QuadPart; 248: 249: } 250: else 251: { 252: lDiskLength.QuadPart = dg.Cylinders.QuadPart * dg.SectorsPerTrack * 253: dg.TracksPerCylinder * dg.BytesPerSector; 254: } 255: 256: 257: } 258: 259: if (lDiskLength.QuadPart < MIN_VOLUME_SIZE || lDiskLength.QuadPart > MAX_VOLUME_SIZE) 260: { 261: /* Volume too large or too small for us to handle... */ 262: mount->nReturnCode = ERR_VOL_SIZE_WRONG; 263: ntStatus = STATUS_SUCCESS; 264: goto error; 265: } 266: else 267: Extension->DiskLength = lDiskLength.QuadPart; 268: 269: /* Attempt to recognize the volume */ 270: 271: KeWaitForMutexObject (&driverMutex, Executive, KernelMode, 272: FALSE, NULL); 273: 274: mount->nReturnCode = VolumeReadHeaderCache ( 275: mount->bCache, 276: readBuffer, 277: mount->szPassword, 278: strlen (mount->szPassword), 279: &Extension->cryptoInfo); 280: 281: KeReleaseMutex (&driverMutex, FALSE); 282: 283: if (mount->nReturnCode == 0) 284: { 285: /* There's one extra sector than there should be */ 286: Extension->DiskLength -= SECTOR_SIZE; 287: 288: Extension->TracksPerCylinder = 1; 289: Extension->SectorsPerTrack = 1; 1.1.1.3 ! root 290: Extension->BytesPerSector = 512; ! 291: Extension->NumberOfCylinders = Extension->DiskLength / 512; ! 292: Extension->PartitionType = 0; 1.1 root 293: Extension->bRawDevice = bRawDevice; 294: 295: if (wcslen (pwszMountVolume) < 64) 296: wcscpy (Extension->wszVolume, pwszMountVolume); 297: else 298: { 299: memcpy (Extension->wszVolume, pwszMountVolume, 60 * 2); 300: Extension->wszVolume[60] = (WCHAR) '.'; 301: Extension->wszVolume[61] = (WCHAR) '.'; 302: Extension->wszVolume[62] = (WCHAR) '.'; 303: Extension->wszVolume[63] = (WCHAR) 0; 304: } 305: 306: Extension->mountTime = mount->time; 307: 308: TCfree (readBuffer); 309: 310: return STATUS_SUCCESS; 311: } 312: 313: 314: /* Failed due to some non-OS reason so we drop through and return NT 315: SUCCESS then nReturnCode is checked later in user-mode */ 316: 317: if (mount->nReturnCode == ERR_OUTOFMEMORY) 318: ntStatus = STATUS_INSUFFICIENT_RESOURCES; 319: else 320: ntStatus = STATUS_SUCCESS; 321: 322: error: 323: 324: /* Close the hDeviceFile */ 325: if (Extension->hDeviceFile != NULL) 326: ZwClose (Extension->hDeviceFile); 327: 328: /* The cryptoInfo pointer is deallocated if the readheader routines 329: fail so there is no need to deallocate here */ 330: 331: /* Dereference the user-mode file object */ 332: if (Extension->pfoDeviceFile != NULL) 333: ObDereferenceObject (Extension->pfoDeviceFile); 334: 335: /* Free the tmp IO buffer */ 336: if (readBuffer != NULL) 337: TCfree (readBuffer); 338: 339: return ntStatus; 340: } 341: 342: void 343: TCCloseVolume (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) 344: { 345: if (DeviceObject); /* Remove compiler warning */ 346: 347: if (Extension->hDeviceFile != NULL) 348: ZwClose (Extension->hDeviceFile); 349: ObDereferenceObject (Extension->pfoDeviceFile); 350: crypto_close (Extension->cryptoInfo); 351: 352: } 353: 354: /* This rountine can be called at any IRQL so we need to tread carefully. Not 355: even DbgPrint or KdPrint are called here as the kernel sometimes faults if 356: they are called at high IRQL */ 357: 358: NTSTATUS 359: TCCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID pUserBuffer) 360: { 361: PIO_STACK_LOCATION irpSp; 362: PEXTENSION Extension; 363: NTSTATUS ntStatus; 364: 365: Extension = (PEXTENSION) DeviceObject->DeviceExtension; 366: 367: /* Check to make sure the DeviceObject passed in is actually ours! */ 368: if (Extension->lMagicNumber != 0xabfeacde) 369: KeBugCheck ((ULONG) 0xabfeacde); 370: 371: ASSERT (Extension->nDosDriveNo >= 0 && Extension->nDosDriveNo <= 0x19); 372: 373: #ifdef USE_KERNEL_MUTEX 374: KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode, 375: FALSE, NULL); 376: #endif 377: 378: #if EXTRA_INFO 379: Dump ("Completing IRP...BEGIN\n"); 380: Dump ("COMPLETION USER BUFFER IS 0x%08x MDL ADDRESS IS 0x%08x\n", Irp->UserBuffer, Irp->MdlAddress); 381: Dump ("COMPLETION Irp->Tail.Overlay.OriginalFileObject = 0x%08x\n", Irp->Tail.Overlay.OriginalFileObject); 382: Dump ("Completing DeviceObject 0x%08x Irp 0x%08x\n", DeviceObject, Irp); 383: #endif 384: 385: /* Note: The Irp stack location we get back here is our one, we setup 386: the next stack location with a copy of this stack data in the send 387: function... here we always get back our own stack location, so 388: it's possible to use Read.Key to store extra pointers if needed. */ 389: irpSp = IoGetCurrentIrpStackLocation (Irp); 390: 391: ntStatus = Irp->IoStatus.Status; 392: 393: if (ntStatus == STATUS_TOO_LATE) 394: KeBugCheck ((ULONG) 0x50ff); 395: 396: if (Irp->PendingReturned) /* From Windows NT File System 397: Internals */ 398: IoMarkIrpPending (Irp); 399: 400: if (Extension->bRawDevice == FALSE) 401: { 402: /* Note: For some reason even though we used DIRECT_IO 403: sometimes the Irp's come back to use with MDLs !! if we 404: get an MDL here we need to free it up otherwise later when 405: we call IoFreeIrp the system will trap */ 406: 407: PMDL pMdl, pNextMdl; 408: 409: pMdl = Irp->MdlAddress; 410: 411: while (pMdl != NULL) 412: { 413: pNextMdl = pMdl->Next; 414: 415: MmUnmapLockedPages (MmGetSystemAddressForMdlSafe (pMdl, HighPagePriority), pMdl); 416: MmUnlockPages (pMdl); 417: IoFreeMdl (pMdl); 418: 419: pMdl = pNextMdl; 420: } 421: } 422: 423: if (NT_SUCCESS (Irp->IoStatus.Status) && irpSp->MajorFunction == IRP_MJ_READ) 424: { 425: __int64 tmpOffset = irpSp->Parameters.Read.ByteOffset.QuadPart; 426: ULONG tmpLength = irpSp->Parameters.Read.Length; 427: PUCHAR CurrentAddress; 428: 429: if (Extension->bRawDevice == TRUE) 430: CurrentAddress = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority); 431: else 432: CurrentAddress = Irp->UserBuffer; 433: 434: if (tmpLength > 0) 435: { 436: /* Decrypt the data on read */ 437: Extension->cryptoInfo->decrypt_sector ((ULONG *) CurrentAddress, 438: tmpOffset / SECTOR_SIZE, 439: tmpLength / SECTOR_SIZE, 440: &Extension->cryptoInfo->ks[0], 441: Extension->cryptoInfo->iv, 442: Extension->cryptoInfo->cipher); 443: } 444: 445: if (Extension->bRawDevice == FALSE) 446: { 447: PIRP OldIrp = (PIRP) pUserBuffer; 448: PUCHAR OriginalAddress; 449: CurrentAddress = Irp->UserBuffer; 450: OriginalAddress = MmGetSystemAddressForMdlSafe (OldIrp->MdlAddress, HighPagePriority); 451: memcpy (OriginalAddress, CurrentAddress, Irp->IoStatus.Information); 452: } 453: 454: } 455: 456: if (NT_SUCCESS (Irp->IoStatus.Status) && irpSp->MajorFunction == IRP_MJ_WRITE) 457: { 458: PUCHAR CurrentAddress; 459: PUCHAR OriginalAddress; 460: 461: if (Extension->bRawDevice == TRUE) 462: { 463: CurrentAddress = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority); 464: OriginalAddress = MmGetSystemAddressForMdlSafe ((PMDL) pUserBuffer, HighPagePriority); 465: } 466: else 467: { 468: PIRP OldIrp = (PIRP) pUserBuffer; 469: CurrentAddress = Irp->UserBuffer; 470: OriginalAddress = MmGetSystemAddressForMdlSafe (OldIrp->MdlAddress, HighPagePriority); 471: } 472: 473: //if (NT_SUCCESS (Irp->IoStatus.Status)) 474: //{ 475: // __int64 tmpOffset = irpSp->Parameters.Read.ByteOffset.QuadPart; 476: //} 477: } 478: 479: if (Extension->bRawDevice == TRUE && irpSp->MajorFunction == IRP_MJ_WRITE) 480: { 481: PUCHAR tmpBuffer = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority); 482: /* Free the temp buffer we allocated */ 483: TCfree (tmpBuffer); 484: /* Free the Mdl we allocated */ 485: IoFreeMdl (Irp->MdlAddress); 486: /* Reset the Irp */ 487: Irp->MdlAddress = pUserBuffer; 488: } 489: 490: if (Extension->bRawDevice == TRUE && irpSp->MajorFunction == IRP_MJ_READ) 491: { 492: /* Nothing to do */ 493: } 494: 495: #if EXTRA_INFO 496: Dump ("COMPLETION OLD USER BUFFER IS 0x%08x MDL ADDRESS IS 0x%08x\n", Irp->UserBuffer, Irp->MdlAddress); 497: Dump ("COMPLETION OLD Irp->Tail.Overlay.OriginalFileObject = 0x%08x\n", Irp->Tail.Overlay.OriginalFileObject); 498: Dump ("Completing IRP 0x%08x NTSTATUS 0x%08x information %lu END\n", (ULONG) irpSp->MajorFunction, 499: Irp->IoStatus.Status, Irp->IoStatus.Information); 500: #endif 501: 502: if (Extension->bRawDevice == FALSE) 503: { 504: PIRP OldIrp = (PIRP) pUserBuffer; 505: PVOID tmpBuffer = Irp->UserBuffer; 506: BOOL bFreeBuffer = irpSp->MajorFunction == IRP_MJ_WRITE || irpSp->MajorFunction == IRP_MJ_READ; 507: 508: OldIrp->IoStatus.Status = Irp->IoStatus.Status; 509: OldIrp->IoStatus.Information = Irp->IoStatus.Information; 510: 511: IoCompleteRequest (OldIrp, IO_DISK_INCREMENT); 512: 513: #if EXTRA_INFO 514: Dump ("About to free allocated IRP\n"); 515: #endif 516: 517: Irp->UserBuffer = NULL; 518: 519: /* Free the allocated IRP. Note: This must be done before we 520: free tmpBuffer! */ 521: IoFreeIrp (Irp); 522: 523: /* Note: From here on we cannot touch the Irp or irpSp */ 524: 525: #if EXTRA_INFO 526: Dump ("Free allocated buffer = %d\n", bFreeBuffer); 527: #endif 528: 529: if (bFreeBuffer == TRUE) 530: TCfree (tmpBuffer); 531: 532: ntStatus = STATUS_MORE_PROCESSING_REQUIRED; 533: } 534: 535: #ifdef USE_KERNEL_MUTEX 536: KeReleaseMutex (&Extension->KernelMutex, FALSE); 537: #endif 538: 539: return ntStatus; 540: } 541: 542: NTSTATUS 543: TCReadWrite (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp) 544: { 545: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); 546: PUCHAR tmpBuffer = NULL;/* Remove compiler warning */ 547: NTSTATUS ntStatus; 548: 549: // Dump ("TCReadWrite BEGIN\n"); 550: 551: /* Check for invalid parameters. It is an error for the starting 552: offset + length to go past the end of the buffer, or for the 553: length to not be a proper multiple of the sector size. Others are 554: possible, but we don't check them since we trust the file system 555: and they aren't deadly. */ 556: if (irpSp->Parameters.Read.ByteOffset.QuadPart + irpSp->Parameters.Read.Length > Extension->DiskLength 557: || (irpSp->Parameters.Read.Length & (Extension->BytesPerSector - 1))) 558: { 559: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INVALID_PARAMETER, 0); 560: } 561: else 562: { 563: if (irpSp->Parameters.Read.Length == 0) 564: { 565: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INVALID_PARAMETER, 0); 566: } 567: } 568: 569: #if EXTRA_INFO 570: Dump ("USER BUFFER IS 0x%08x MDL ADDRESS IS 0x%08x\n", Irp->UserBuffer, Irp->MdlAddress); 571: Dump ("Irp->Tail.Overlay.OriginalFileObject = 0x%08x\n", Irp->Tail.Overlay.OriginalFileObject); 572: Dump ("irpSp->FileObject = 0x%08x\n", irpSp->FileObject); 573: 574: if (Irp->Tail.Overlay.OriginalFileObject != NULL) 575: { 576: if (Irp->Tail.Overlay.OriginalFileObject->FileName.Length != 0) 577: Dump ("Irp->Tail.Overlay.OriginalFileObject = %ls\n", Irp->Tail.Overlay.OriginalFileObject->FileName.Buffer); 578: else 579: Dump ("Irp->Tail.Overlay.OriginalFileObject = %ls\n", WIDE ("null value")); 580: 581: } 582: 583: if (irpSp->FileObject != NULL) 584: { 585: if (irpSp->FileObject->FileName.Length != 0) 586: Dump ("irpSp->FileObject = %ls\n", irpSp->FileObject->FileName.Buffer); 587: else 588: Dump ("irpSp->FileObject = %ls\n", WIDE ("null value")); 589: 590: } 591: #endif 592: 593: if (Extension->bReadOnly == TRUE && irpSp->MajorFunction == IRP_MJ_WRITE) 594: return COMPLETE_IRP (DeviceObject, Irp, STATUS_MEDIA_WRITE_PROTECTED, 0); 595: 596: if (Extension->bRawDevice == FALSE || irpSp->MajorFunction == IRP_MJ_WRITE) 597: { 598: tmpBuffer = TCalloc (irpSp->Parameters.Read.Length); 599: if (tmpBuffer == NULL) 600: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INSUFFICIENT_RESOURCES, 0); 601: } 602: 603: if (irpSp->MajorFunction == IRP_MJ_READ) 604: { 605: // Dump ("Read: 0x%08x for %lu bytes...\n", irpSp->Parameters.Read.ByteOffset.LowPart, 606: // irpSp->Parameters.Read.Length); 607: 608: /* Fixup the parameters to handle this particular volume type */ 609: irpSp->Parameters.Read.ByteOffset.QuadPart += SECTOR_SIZE; 610: 611: if (Extension->bRawDevice == TRUE) 612: ntStatus = TCSendIRP_RawDevice (DeviceObject, Extension, 613: NULL, IRP_READ_OPERATION | IRP_NOCACHE, 614: irpSp->MajorFunction, 615: Irp); 616: else 617: ntStatus = TCSendIRP_FileDevice (DeviceObject, Extension, 618: tmpBuffer, IRP_READ_OPERATION | IRP_NOCACHE, 619: irpSp->MajorFunction, 620: Irp); 621: } 622: else 623: { 624: PUCHAR CurrentAddress; 625: 626: // Dump ("Write: 0x%08x for %lu bytes...\n", irpSp->Parameters.Read.ByteOffset.LowPart, 627: // irpSp->Parameters.Read.Length); 628: 629: CurrentAddress = (PUCHAR) MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority); 630: 631: /* Fixup the parameters to handle this particular volume type */ 632: irpSp->Parameters.Read.ByteOffset.QuadPart += SECTOR_SIZE; 633: 634: memcpy (tmpBuffer, CurrentAddress, irpSp->Parameters.Read.Length); 635: 636: /* Encrypt the data */ 637: Extension->cryptoInfo->encrypt_sector ((ULONG *) tmpBuffer, 638: irpSp->Parameters.Read.ByteOffset.QuadPart / SECTOR_SIZE, 639: irpSp->Parameters.Read.Length / SECTOR_SIZE, 640: &Extension->cryptoInfo->ks[0], 641: Extension->cryptoInfo->iv, 642: Extension->cryptoInfo->cipher); 643: 644: if (Extension->bRawDevice == TRUE) 645: { 646: PMDL tmpBufferMdl = IoAllocateMdl (tmpBuffer, irpSp->Parameters.Read.Length, FALSE, FALSE, NULL); 647: PMDL pTrueMdl = Irp->MdlAddress; 648: 649: if (tmpBufferMdl == NULL) 650: { 651: TCfree (tmpBuffer); 652: return COMPLETE_IRP (DeviceObject, Irp, STATUS_INSUFFICIENT_RESOURCES, 0); 653: } 654: 655: MmBuildMdlForNonPagedPool (tmpBufferMdl); 656: 657: Irp->MdlAddress = tmpBufferMdl; 658: 659: #if EXTRA_INFO 660: Dump ("NEW MDL ADDRESS IS 0x%08x UserBuffer = 0x%08x\n", Irp->MdlAddress, Irp->UserBuffer); 661: #endif 662: 663: ntStatus = TCSendIRP_RawDevice (DeviceObject, Extension, 664: pTrueMdl, IRP_WRITE_OPERATION | IRP_NOCACHE, 665: irpSp->MajorFunction, 666: Irp); 667: } 668: else 669: { 670: ntStatus = TCSendIRP_FileDevice (DeviceObject, Extension, 671: tmpBuffer, IRP_WRITE_OPERATION | IRP_NOCACHE, 672: irpSp->MajorFunction, 673: Irp); 674: } 675: 676: } 677: 678: // Dump ("TCReadWrite END\n"); 679: return ntStatus; 680: } 681: 682: NTSTATUS 683: TCSendDeviceIoControlRequest (PDEVICE_OBJECT DeviceObject, 684: PEXTENSION Extension, 685: ULONG IoControlCode, 686: char *OutputBuffer, 687: int OutputBufferSize) 688: { 689: IO_STATUS_BLOCK IoStatusBlock; 690: NTSTATUS ntStatus; 691: PIRP Irp; 692: 693: if (DeviceObject); /* Remove compiler warning */ 694: 695: KeClearEvent (&Extension->keVolumeEvent); 696: 697: Irp = IoBuildDeviceIoControlRequest (IoControlCode, 698: Extension->pFsdDevice, 699: NULL, 0, 700: OutputBuffer, OutputBufferSize, 701: FALSE, 702: &Extension->keVolumeEvent, 703: &IoStatusBlock); 704: 705: if (Irp == NULL) 706: { 707: Dump ("IRP allocation failed\n"); 708: return STATUS_INSUFFICIENT_RESOURCES; 709: } 710: 711: ntStatus = IoCallDriver (Extension->pFsdDevice, Irp); 712: if (ntStatus == STATUS_PENDING) 713: { 714: KeWaitForSingleObject (&Extension->keVolumeEvent, UserRequest, UserMode, FALSE, NULL); 715: ntStatus = IoStatusBlock.Status; 716: } 717: 718: return ntStatus; 719: } 720: 721: NTSTATUS 722: COMPLETE_IRP (PDEVICE_OBJECT DeviceObject, 723: PIRP Irp, 724: NTSTATUS IrpStatus, 725: ULONG IrpInformation) 726: { 727: Irp->IoStatus.Status = IrpStatus; 728: Irp->IoStatus.Information = IrpInformation; 729: 730: if (DeviceObject); /* Remove compiler warning */ 731: 732: #ifdef _DEBUG 733: if (!NT_SUCCESS (IrpStatus)) 734: { 735: PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); 736: Dump ("COMPLETE_IRP FAILING IRP %ls Flags 0x%08x vpb 0x%08x NTSTATUS 0x%08x\n", TCTranslateCode (irpSp->MajorFunction), 737: (ULONG) DeviceObject->Flags, (ULONG) DeviceObject->Vpb->Flags, IrpStatus); 738: } 739: //else 740: //{ 741: // PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); 742: // Dump ("COMPLETE_IRP SUCCESS IRP %ls Flags 0x%08x vpb 0x%08x NTSTATUS 0x%08x\n", TCTranslateCode (irpSp->MajorFunction), 743: // (ULONG) DeviceObject->Flags, (ULONG) DeviceObject->Vpb->Flags, IrpStatus); 744: //} 745: #endif 746: IoCompleteRequest (Irp, IO_NO_INCREMENT); 747: return IrpStatus; 748: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.