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