NTSTATUS DumpFilterEntry (PFILTER_EXTENSION filterExtension, PFILTER_INITIALIZATION_DATA filterInitData) { GetSystemDriveDumpConfigRequest dumpConfig; PHYSICAL_ADDRESS highestAcceptableWriteBufferAddr; STORAGE_DEVICE_NUMBER storageDeviceNumber; PARTITION_INFORMATION partitionInfo; LONG version; NTSTATUS status; Dump ("DumpFilterEntry type=%d\n", filterExtension->DumpType); filterInitData->MajorVersion = DUMP_FILTER_MAJOR_VERSION; filterInitData->MinorVersion = DUMP_FILTER_MINOR_VERSION; filterInitData->Flags |= DUMP_FILTER_CRITICAL; // Check driver version of the main device status = TCDeviceIoControl (NT_ROOT_PREFIX, TC_IOCTL_GET_DRIVER_VERSION, NULL, 0, &version, sizeof (version)); if (!NT_SUCCESS (status)) goto err; if (version != VERSION_NUM) { status = STATUS_INVALID_PARAMETER; goto err; } // Get dump configuration from the main device status = TCDeviceIoControl (NT_ROOT_PREFIX, TC_IOCTL_GET_SYSTEM_DRIVE_DUMP_CONFIG, NULL, 0, &dumpConfig, sizeof (dumpConfig)); if (!NT_SUCCESS (status)) goto err; BootDriveFilterExtension = dumpConfig.BootDriveFilterExtension; if (BootDriveFilterExtension->MagicNumber != TC_BOOT_DRIVE_FILTER_EXTENSION_MAGIC_NUMBER) { status = STATUS_CRC_ERROR; goto err; } // KeSaveFloatingPointState() may generate a bug check during crash dump #if !defined (_WIN64) if (filterExtension->DumpType == DumpTypeCrashdump) dumpConfig.HwEncryptionEnabled = FALSE; #endif EnableHwEncryption (dumpConfig.HwEncryptionEnabled); if (!AutoTestAlgorithms()) { status = STATUS_INVALID_PARAMETER; goto err; } // Check dump volume is located on the system drive status = SendDeviceIoControlRequest (filterExtension->DeviceObject, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &storageDeviceNumber, sizeof (storageDeviceNumber)); if (!NT_SUCCESS (status)) goto err; if (!BootDriveFilterExtension->SystemStorageDeviceNumberValid) { status = STATUS_INVALID_PARAMETER; goto err; } if (storageDeviceNumber.DeviceNumber != BootDriveFilterExtension->SystemStorageDeviceNumber) { status = STATUS_ACCESS_DENIED; goto err; } // Check dump volume is located within the scope of system encryption status = SendDeviceIoControlRequest (filterExtension->DeviceObject, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &partitionInfo, sizeof (partitionInfo)); if (!NT_SUCCESS (status)) goto err; DumpPartitionOffset = partitionInfo.StartingOffset; if (DumpPartitionOffset.QuadPart < BootDriveFilterExtension->ConfiguredEncryptedAreaStart || DumpPartitionOffset.QuadPart > BootDriveFilterExtension->ConfiguredEncryptedAreaEnd) { status = STATUS_ACCESS_DENIED; goto err; } // Allocate buffer for encryption if (filterInitData->MaxPagesPerWrite == 0) { status = STATUS_INVALID_PARAMETER; goto err; } WriteFilterBufferSize = filterInitData->MaxPagesPerWrite * PAGE_SIZE; #ifdef _WIN64 highestAcceptableWriteBufferAddr.QuadPart = 0x7FFffffFFFFLL; #else highestAcceptableWriteBufferAddr.QuadPart = 0xffffFFFFLL; #endif WriteFilterBuffer = MmAllocateContiguousMemory (WriteFilterBufferSize, highestAcceptableWriteBufferAddr); if (!WriteFilterBuffer) { status = STATUS_INSUFFICIENT_RESOURCES; goto err; } filterInitData->DumpStart = DumpFilterStart; filterInitData->DumpWrite = DumpFilterWrite; filterInitData->DumpFinish = DumpFilterFinish; filterInitData->DumpUnload = DumpFilterUnload; Dump ("Dump filter loaded type=%d\n", filterExtension->DumpType); return STATUS_SUCCESS; err: Dump ("DumpFilterEntry error %x\n", status); return status; }
static NTSTATUS DispatchControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilterExtension *Extension, PIO_STACK_LOCATION irpSp) { NTSTATUS status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); if (!NT_SUCCESS (status)) return TCCompleteIrp (Irp, status, 0); if (IsHiddenSystemRunning()) { switch (irpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_DISK_IS_WRITABLE: { // All volumes except the system volume must be read-only DriveFilterExtension *bootDriveExtension = GetBootDriveFilterExtension(); STORAGE_DEVICE_NUMBER storageDeviceNumber; if (!bootDriveExtension->SystemStorageDeviceNumberValid) TC_BUG_CHECK (STATUS_INVALID_PARAMETER); status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &storageDeviceNumber, sizeof (storageDeviceNumber)); if (NT_SUCCESS (status) && bootDriveExtension->SystemStorageDeviceNumber == storageDeviceNumber.DeviceNumber) { PARTITION_INFORMATION_EX partition; status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &partition, sizeof (partition)); if (NT_SUCCESS (status) && partition.StartingOffset.QuadPart == bootDriveExtension->ConfiguredEncryptedAreaStart) { IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); } } IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); ++HiddenSysLeakProtectionCount; return TCCompleteDiskIrp (Irp, STATUS_MEDIA_WRITE_PROTECTED, 0); } case TC_IOCTL_DISK_IS_WRITABLE: Dump ("TC_IOCTL_DISK_IS_WRITABLE pdo=%p\n", Extension->Pdo); if (!ProbingHostDeviceForWrite) break; // Probe the real state of the device as the user is mounting a TrueCrypt volume. // Volume filter may be attached to a merged drive+volume PDO. First test if TC_IOCTL_DISK_IS_WRITABLE works for the underlying device. status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, TC_IOCTL_DISK_IS_WRITABLE, NULL, 0, NULL, 0); if (NT_SUCCESS (status) || status == STATUS_MEDIA_WRITE_PROTECTED) { IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return TCCompleteDiskIrp (Irp, status, 0); } status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_DISK_IS_WRITABLE, NULL, 0, NULL, 0); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return TCCompleteDiskIrp (Irp, status, 0); case IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES: // Filter IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES to enable potential future use of hidden systems on drives that use the trim operation but not wear-leveling (if any appear in future). The documentation forbids users to create hidden volumes/systems on drives that use wear-leveling and consequently also on drives that use trim (as trim is used only by drives that use wear-leveling, as of 2010). IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); } } status = PassIrp (Extension->LowerDeviceObject, Irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return status; }