mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-24 12:03:28 +01:00
Windows: Implement workaround on Windows 10 to make VeraCrypt encrypted disks visible to Windows defragmenter
This commit is contained in:
parent
2fea18c3f5
commit
20889d4553
@ -1263,8 +1263,10 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
|
|||||||
|
|
||||||
case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS:
|
case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS:
|
||||||
Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)\n");
|
Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)\n");
|
||||||
// Vista's filesystem defragmenter fails if IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS does not succeed.
|
// Vista's and Windows 10 filesystem defragmenter fails if IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS does not succeed.
|
||||||
if (!(OsMajorVersion == 6 && OsMinorVersion == 0))
|
if (!(OsMajorVersion == 6 && OsMinorVersion == 0)
|
||||||
|
&& !(OsMajorVersion == 10 && EnableExtendedIoctlSupport && Extension->bRawDevice)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
|
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
@ -1272,10 +1274,24 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
|
|||||||
else if (ValidateIOBufferSize (Irp, sizeof (VOLUME_DISK_EXTENTS), ValidateOutput))
|
else if (ValidateIOBufferSize (Irp, sizeof (VOLUME_DISK_EXTENTS), ValidateOutput))
|
||||||
{
|
{
|
||||||
VOLUME_DISK_EXTENTS *extents = (VOLUME_DISK_EXTENTS *) Irp->AssociatedIrp.SystemBuffer;
|
VOLUME_DISK_EXTENTS *extents = (VOLUME_DISK_EXTENTS *) Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
|
|
||||||
// No extent data can be returned as this is not a physical drive.
|
if (OsMajorVersion == 10)
|
||||||
memset (extents, 0, sizeof (*extents));
|
{
|
||||||
extents->NumberOfDiskExtents = 0;
|
// 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 = Extension->BytesPerSector;
|
||||||
|
extents->Extents[0].ExtentLength.QuadPart = Extension->DiskLength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Vista: No extent data can be returned as this is not a physical drive.
|
||||||
|
memset (extents, 0, sizeof (*extents));
|
||||||
|
extents->NumberOfDiskExtents = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = sizeof (*extents);
|
Irp->IoStatus.Information = sizeof (*extents);
|
||||||
|
@ -66,6 +66,7 @@ typedef struct EXTENSION
|
|||||||
ULONG HostMaximumTransferLength;
|
ULONG HostMaximumTransferLength;
|
||||||
ULONG HostMaximumPhysicalPages;
|
ULONG HostMaximumPhysicalPages;
|
||||||
ULONG HostAlignmentMask;
|
ULONG HostAlignmentMask;
|
||||||
|
ULONG DeviceNumber;
|
||||||
|
|
||||||
BOOL IncursSeekPenalty;
|
BOOL IncursSeekPenalty;
|
||||||
BOOL TrimEnabled;
|
BOOL TrimEnabled;
|
||||||
|
@ -72,6 +72,8 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
|||||||
Extension->IncursSeekPenalty = TRUE;
|
Extension->IncursSeekPenalty = TRUE;
|
||||||
Extension->TrimEnabled = FALSE;
|
Extension->TrimEnabled = FALSE;
|
||||||
|
|
||||||
|
Extension->DeviceNumber = (ULONG) -1;
|
||||||
|
|
||||||
RtlInitUnicodeString (&FullFileName, pwszMountVolume);
|
RtlInitUnicodeString (&FullFileName, pwszMountVolume);
|
||||||
InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | (forceAccessCheck ? OBJ_FORCE_ACCESS_CHECK : 0) | OBJ_KERNEL_HANDLE, NULL, NULL);
|
InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | (forceAccessCheck ? OBJ_FORCE_ACCESS_CHECK : 0) | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||||
KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE);
|
KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE);
|
||||||
@ -94,6 +96,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
|||||||
DISK_GEOMETRY_EX dg;
|
DISK_GEOMETRY_EX dg;
|
||||||
STORAGE_PROPERTY_QUERY storagePropertyQuery = {0};
|
STORAGE_PROPERTY_QUERY storagePropertyQuery = {0};
|
||||||
byte* dgBuffer;
|
byte* dgBuffer;
|
||||||
|
STORAGE_DEVICE_NUMBER storageDeviceNumber;
|
||||||
|
|
||||||
ntStatus = IoGetDeviceObjectPointer (&FullFileName,
|
ntStatus = IoGetDeviceObjectPointer (&FullFileName,
|
||||||
FILE_READ_DATA | FILE_READ_ATTRIBUTES,
|
FILE_READ_DATA | FILE_READ_ATTRIBUTES,
|
||||||
@ -147,6 +150,13 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
|||||||
|
|
||||||
TCfree (dgBuffer);
|
TCfree (dgBuffer);
|
||||||
|
|
||||||
|
if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension,
|
||||||
|
IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
||||||
|
(char*) &storageDeviceNumber, sizeof (storageDeviceNumber))))
|
||||||
|
{
|
||||||
|
Extension->DeviceNumber = storageDeviceNumber.DeviceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
lDiskLength.QuadPart = dg.DiskSize.QuadPart;
|
lDiskLength.QuadPart = dg.DiskSize.QuadPart;
|
||||||
Extension->HostBytesPerSector = dg.Geometry.BytesPerSector;
|
Extension->HostBytesPerSector = dg.Geometry.BytesPerSector;
|
||||||
Extension->HostBytesPerPhysicalSector = dg.Geometry.BytesPerSector;
|
Extension->HostBytesPerPhysicalSector = dg.Geometry.BytesPerSector;
|
||||||
|
Loading…
Reference in New Issue
Block a user