Windows: Implement workaround on Windows 10 to make VeraCrypt encrypted disks visible to Windows defragmenter

This commit is contained in:
Mounir IDRASSI 2018-08-18 11:13:20 +02:00
parent 2fea18c3f5
commit 20889d4553
No known key found for this signature in database
GPG Key ID: DD0C382D5FCFB8FC
3 changed files with 32 additions and 5 deletions

View File

@ -1263,8 +1263,10 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS:
Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)\n");
// Vista's filesystem defragmenter fails if IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS does not succeed.
if (!(OsMajorVersion == 6 && OsMinorVersion == 0))
// Vista's and Windows 10 filesystem defragmenter fails if IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS does not succeed.
if (!(OsMajorVersion == 6 && OsMinorVersion == 0)
&& !(OsMajorVersion == 10 && EnableExtendedIoctlSupport && Extension->bRawDevice)
)
{
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
@ -1273,9 +1275,23 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
{
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)
{
// 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.Information = sizeof (*extents);

View File

@ -66,6 +66,7 @@ typedef struct EXTENSION
ULONG HostMaximumTransferLength;
ULONG HostMaximumPhysicalPages;
ULONG HostAlignmentMask;
ULONG DeviceNumber;
BOOL IncursSeekPenalty;
BOOL TrimEnabled;

View File

@ -72,6 +72,8 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
Extension->IncursSeekPenalty = TRUE;
Extension->TrimEnabled = FALSE;
Extension->DeviceNumber = (ULONG) -1;
RtlInitUnicodeString (&FullFileName, pwszMountVolume);
InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | (forceAccessCheck ? OBJ_FORCE_ACCESS_CHECK : 0) | OBJ_KERNEL_HANDLE, NULL, NULL);
KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE);
@ -94,6 +96,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
DISK_GEOMETRY_EX dg;
STORAGE_PROPERTY_QUERY storagePropertyQuery = {0};
byte* dgBuffer;
STORAGE_DEVICE_NUMBER storageDeviceNumber;
ntStatus = IoGetDeviceObjectPointer (&FullFileName,
FILE_READ_DATA | FILE_READ_ATTRIBUTES,
@ -147,6 +150,13 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
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;
Extension->HostBytesPerSector = dg.Geometry.BytesPerSector;
Extension->HostBytesPerPhysicalSector = dg.Geometry.BytesPerSector;