diff options
Diffstat (limited to 'src/Driver/Ntdriver.c')
-rw-r--r-- | src/Driver/Ntdriver.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c index 6d218517..148f88b8 100644 --- a/src/Driver/Ntdriver.c +++ b/src/Driver/Ntdriver.c @@ -1211,120 +1211,120 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION } } } break; case IOCTL_DISK_GET_PARTITION_INFO: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_PARTITION_INFO)\n"); if (ValidateIOBufferSize (Irp, sizeof (PARTITION_INFORMATION), ValidateOutput)) { PPARTITION_INFORMATION outputBuffer = (PPARTITION_INFORMATION) Irp->AssociatedIrp.SystemBuffer; outputBuffer->PartitionType = Extension->PartitionType; outputBuffer->BootIndicator = FALSE; outputBuffer->RecognizedPartition = TRUE; outputBuffer->RewritePartition = FALSE; outputBuffer->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionLength.QuadPart= Extension->DiskLength; outputBuffer->PartitionNumber = 1; - outputBuffer->HiddenSectors = 0; + outputBuffer->HiddenSectors = BYTES_PER_MB / Extension->BytesPerSector; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION); } break; case IOCTL_DISK_GET_PARTITION_INFO_EX: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_PARTITION_INFO_EX)\n"); if (ValidateIOBufferSize (Irp, sizeof (PARTITION_INFORMATION_EX), ValidateOutput)) { PPARTITION_INFORMATION_EX outputBuffer = (PPARTITION_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer; outputBuffer->PartitionStyle = PARTITION_STYLE_MBR; outputBuffer->RewritePartition = FALSE; outputBuffer->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionLength.QuadPart= Extension->DiskLength; outputBuffer->PartitionNumber = 1; outputBuffer->Mbr.PartitionType = Extension->PartitionType; outputBuffer->Mbr.BootIndicator = FALSE; outputBuffer->Mbr.RecognizedPartition = TRUE; - outputBuffer->Mbr.HiddenSectors = 0; + outputBuffer->Mbr.HiddenSectors = BYTES_PER_MB / Extension->BytesPerSector; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION_EX); } break; case IOCTL_DISK_GET_DRIVE_LAYOUT: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_DRIVE_LAYOUT)\n"); if (ValidateIOBufferSize (Irp, sizeof (DRIVE_LAYOUT_INFORMATION), ValidateOutput)) { BOOL bFullBuffer = (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= (sizeof (DRIVE_LAYOUT_INFORMATION) + 3*sizeof(PARTITION_INFORMATION)))? TRUE : FALSE; PDRIVE_LAYOUT_INFORMATION outputBuffer = (PDRIVE_LAYOUT_INFORMATION) Irp->AssociatedIrp.SystemBuffer; outputBuffer->PartitionCount = bFullBuffer? 4 : 1; outputBuffer->Signature = GetCrc32((unsigned char*) &(Extension->UniqueVolumeId), 4); outputBuffer->PartitionEntry->PartitionType = Extension->PartitionType; outputBuffer->PartitionEntry->BootIndicator = FALSE; outputBuffer->PartitionEntry->RecognizedPartition = TRUE; outputBuffer->PartitionEntry->RewritePartition = FALSE; outputBuffer->PartitionEntry->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength; outputBuffer->PartitionEntry->PartitionNumber = 1; - outputBuffer->PartitionEntry->HiddenSectors = 0; + outputBuffer->PartitionEntry->HiddenSectors = BYTES_PER_MB / Extension->BytesPerSector; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (DRIVE_LAYOUT_INFORMATION); if (bFullBuffer) { Irp->IoStatus.Information += 3*sizeof(PARTITION_INFORMATION); memset (((BYTE*) Irp->AssociatedIrp.SystemBuffer) + sizeof (DRIVE_LAYOUT_INFORMATION), 0, 3*sizeof(PARTITION_INFORMATION)); } } break; case IOCTL_DISK_GET_DRIVE_LAYOUT_EX: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_DRIVE_LAYOUT_EX)\n"); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; if (EnableExtendedIoctlSupport) { if (ValidateIOBufferSize (Irp, sizeof (DRIVE_LAYOUT_INFORMATION_EX), ValidateOutput)) { BOOL bFullBuffer = (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= (sizeof (DRIVE_LAYOUT_INFORMATION_EX) + 3*sizeof(PARTITION_INFORMATION_EX)))? TRUE : FALSE; PDRIVE_LAYOUT_INFORMATION_EX outputBuffer = (PDRIVE_LAYOUT_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer; outputBuffer->PartitionCount = bFullBuffer? 4 : 1; outputBuffer->PartitionStyle = PARTITION_STYLE_MBR; outputBuffer->Mbr.Signature = GetCrc32((unsigned char*) &(Extension->UniqueVolumeId), 4); outputBuffer->PartitionEntry->PartitionStyle = PARTITION_STYLE_MBR; outputBuffer->PartitionEntry->Mbr.BootIndicator = FALSE; outputBuffer->PartitionEntry->Mbr.RecognizedPartition = TRUE; outputBuffer->PartitionEntry->RewritePartition = FALSE; outputBuffer->PartitionEntry->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength; outputBuffer->PartitionEntry->PartitionNumber = 1; - outputBuffer->PartitionEntry->Mbr.HiddenSectors = 0; + outputBuffer->PartitionEntry->Mbr.HiddenSectors = BYTES_PER_MB / Extension->BytesPerSector; outputBuffer->PartitionEntry->Mbr.PartitionType = Extension->PartitionType; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (DRIVE_LAYOUT_INFORMATION_EX); if (bFullBuffer) { Irp->IoStatus.Information += 3*sizeof(PARTITION_INFORMATION_EX); } } } break; case IOCTL_DISK_GET_LENGTH_INFO: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_LENGTH_INFO)\n"); if (!ValidateIOBufferSize (Irp, sizeof (GET_LENGTH_INFORMATION), ValidateOutput)) { Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION); } else @@ -1429,41 +1429,46 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION case IOCTL_VOLUME_ONLINE: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_ONLINE)\n"); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; break; case IOCTL_VOLUME_POST_ONLINE: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_POST_ONLINE)\n"); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; if (EnableExtendedIoctlSupport) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; } break; case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)\n"); // Vista's, Windows 8.1 and later filesystem defragmenter fails if IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS does not succeed. - if (ValidateIOBufferSize(Irp, sizeof(VOLUME_DISK_EXTENTS), ValidateOutput)) + if (!AllowWindowsDefrag || !Extension->bRawDevice) // We don't support defragmentation for file-hosted volumes + { + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + } + else if (ValidateIOBufferSize(Irp, sizeof(VOLUME_DISK_EXTENTS), ValidateOutput)) { VOLUME_DISK_EXTENTS* extents = (VOLUME_DISK_EXTENTS*)Irp->AssociatedIrp.SystemBuffer; // Windows 10 filesystem defragmenter works only if we report an extent with a real disk number // So in the case of a VeraCrypt disk based volume, we use the disk number // of the underlaying physical disk and we report a single extent extents->NumberOfDiskExtents = 1; extents->Extents[0].DiskNumber = Extension->DeviceNumber; extents->Extents[0].StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk extents->Extents[0].ExtentLength.QuadPart = Extension->DiskLength; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof(*extents); } break; case IOCTL_STORAGE_READ_CAPACITY: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_READ_CAPACITY)\n"); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; @@ -2578,69 +2583,69 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } EnsureNullTerminatedString (mount->wszVolume, sizeof (mount->wszVolume)); EnsureNullTerminatedString (mount->wszLabel, sizeof (mount->wszLabel)); Irp->IoStatus.Information = sizeof (MOUNT_STRUCT); Irp->IoStatus.Status = MountDevice (DeviceObject, mount); burn (&mount->VolumePassword, sizeof (mount->VolumePassword)); burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword)); burn (&mount->pkcs5_prf, sizeof (mount->pkcs5_prf)); burn (&mount->VolumePim, sizeof (mount->VolumePim)); burn (&mount->ProtectedHidVolPkcs5Prf, sizeof (mount->ProtectedHidVolPkcs5Prf)); burn (&mount->ProtectedHidVolPim, sizeof (mount->ProtectedHidVolPim)); } break; - case TC_IOCTL_DISMOUNT_VOLUME: + case TC_IOCTL_UNMOUNT_VOLUME: if (ValidateIOBufferSize (Irp, sizeof (UNMOUNT_STRUCT), ValidateInputOutput)) { UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; PDEVICE_OBJECT ListDevice = GetVirtualVolumeDeviceObject (unmount->nDosDriveNo); if (irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (UNMOUNT_STRUCT)) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } unmount->nReturnCode = ERR_DRIVE_NOT_FOUND; if (ListDevice) { PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; if (IsVolumeAccessibleByCurrentUser (ListExtension)) unmount->nReturnCode = UnmountDevice (unmount, ListDevice, unmount->ignoreOpenFiles); } Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT); Irp->IoStatus.Status = STATUS_SUCCESS; } break; - case TC_IOCTL_DISMOUNT_ALL_VOLUMES: + case TC_IOCTL_UNMOUNT_ALL_VOLUMES: if (ValidateIOBufferSize (Irp, sizeof (UNMOUNT_STRUCT), ValidateInputOutput)) { UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; if (irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (UNMOUNT_STRUCT)) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } unmount->nReturnCode = UnmountAllDevices (unmount, unmount->ignoreOpenFiles); Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT); Irp->IoStatus.Status = STATUS_SUCCESS; } break; case VC_IOCTL_EMERGENCY_CLEAR_ALL_KEYS: EmergencyClearAllKeys (Irp); @@ -3165,42 +3170,42 @@ void TCGetDosNameFromNumber (LPWSTR dosname,int cbDosName, int nDriveNo, DeviceN RtlStringCbCopyW (dosname, cbDosName, (LPWSTR) DOS_MOUNT_PREFIX_GLOBAL); } else { RtlStringCbCopyW (dosname, cbDosName, (LPWSTR) DOS_MOUNT_PREFIX_DEFAULT); } RtlStringCbCatW (dosname, cbDosName, tmp); } #if defined(_DEBUG) || defined (_DEBUG_TRACE) LPWSTR TCTranslateCode (ULONG ulCode) { switch (ulCode) { #define TC_CASE_RET_NAME(CODE) case CODE : return L###CODE TC_CASE_RET_NAME (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP); TC_CASE_RET_NAME (TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE); TC_CASE_RET_NAME (TC_IOCTL_BOOT_ENCRYPTION_SETUP); - TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_ALL_VOLUMES); - TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_VOLUME); + TC_CASE_RET_NAME (TC_IOCTL_UNMOUNT_ALL_VOLUMES); + TC_CASE_RET_NAME (TC_IOCTL_UNMOUNT_VOLUME); TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES); TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME); TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT); TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS); TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_LOADER_VERSION); TC_CASE_RET_NAME (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT); TC_CASE_RET_NAME (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS); TC_CASE_RET_NAME (TC_IOCTL_GET_DEVICE_REFCOUNT); TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_GEOMETRY); TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_PARTITION_INFO); TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVER_VERSION); TC_CASE_RET_NAME (TC_IOCTL_GET_MOUNTED_VOLUMES); TC_CASE_RET_NAME (TC_IOCTL_GET_PASSWORD_CACHE_STATUS); TC_CASE_RET_NAME (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG); TC_CASE_RET_NAME (TC_IOCTL_GET_PORTABLE_MODE_STATUS); TC_CASE_RET_NAME (TC_IOCTL_SET_PORTABLE_MODE_STATUS); TC_CASE_RET_NAME (TC_IOCTL_GET_RESOLVED_SYMLINK); TC_CASE_RET_NAME (TC_IOCTL_GET_SYSTEM_DRIVE_DUMP_CONFIG); TC_CASE_RET_NAME (TC_IOCTL_GET_VOLUME_PROPERTIES); TC_CASE_RET_NAME (TC_IOCTL_GET_WARNING_FLAGS); @@ -3363,41 +3368,41 @@ VOID TCUnloadDriver (PDRIVER_OBJECT DriverObject) Dump ("TCUnloadDriver BEGIN\n"); UNREFERENCED_PARAMETER(DriverObject); OnShutdownPending(); if (IsBootDriveMounted()) TC_BUG_CHECK (STATUS_INVALID_DEVICE_STATE); EncryptionThreadPoolStop(); TCDeleteDeviceObject (RootDeviceObject, (PEXTENSION) RootDeviceObject->DeviceExtension); Dump ("TCUnloadDriver END\n"); } void OnShutdownPending () { UNMOUNT_STRUCT unmount; memset (&unmount, 0, sizeof (unmount)); unmount.ignoreOpenFiles = TRUE; - while (SendDeviceIoControlRequest (RootDeviceObject, TC_IOCTL_DISMOUNT_ALL_VOLUMES, &unmount, sizeof (unmount), &unmount, sizeof (unmount)) == STATUS_INSUFFICIENT_RESOURCES || unmount.HiddenVolumeProtectionTriggered) + while (SendDeviceIoControlRequest (RootDeviceObject, TC_IOCTL_UNMOUNT_ALL_VOLUMES, &unmount, sizeof (unmount), &unmount, sizeof (unmount)) == STATUS_INSUFFICIENT_RESOURCES || unmount.HiddenVolumeProtectionTriggered) unmount.HiddenVolumeProtectionTriggered = FALSE; while (SendDeviceIoControlRequest (RootDeviceObject, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0) == STATUS_INSUFFICIENT_RESOURCES); } typedef struct { PWSTR deviceName; ULONG IoControlCode; void *InputBuffer; ULONG InputBufferSize; void *OutputBuffer; ULONG OutputBufferSize; NTSTATUS Status; KEVENT WorkItemCompletedEvent; } TCDeviceIoControlWorkItemArgs; static VOID TCDeviceIoControlWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, TCDeviceIoControlWorkItemArgs *arg) { UNREFERENCED_PARAMETER(rootDeviceObject); arg->Status = TCDeviceIoControl (arg->deviceName, arg->IoControlCode, arg->InputBuffer, arg->InputBufferSize, arg->OutputBuffer, arg->OutputBufferSize); KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); } NTSTATUS TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode, void *InputBuffer, ULONG InputBufferSize, void *OutputBuffer, ULONG OutputBufferSize) |