VeraCrypt
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2018-08-18 11:13:20 +0200
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2018-08-18 16:47:23 +0200
commit20889d4553a132cd8749a73853715fd3a0f237e5 (patch)
tree59a10b0fff93d43fcde3cb0e1a0123939d5351d3
parent2fea18c3f50599e0b51a731cc8f89a8d99c9df86 (diff)
downloadVeraCrypt-20889d4553a132cd8749a73853715fd3a0f237e5.tar.gz
VeraCrypt-20889d4553a132cd8749a73853715fd3a0f237e5.zip
Windows: Implement workaround on Windows 10 to make VeraCrypt encrypted disks visible to Windows defragmenter
-rw-r--r--src/Driver/Ntdriver.c26
-rw-r--r--src/Driver/Ntdriver.h1
-rw-r--r--src/Driver/Ntvol.c10
3 files changed, 32 insertions, 5 deletions
diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c
index e7451a8f..6e774724 100644
--- a/src/Driver/Ntdriver.c
+++ b/src/Driver/Ntdriver.c
@@ -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;
@@ -1272,10 +1274,24 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
else if (ValidateIOBufferSize (Irp, sizeof (VOLUME_DISK_EXTENTS), ValidateOutput))
{
VOLUME_DISK_EXTENTS *extents = (VOLUME_DISK_EXTENTS *) Irp->AssociatedIrp.SystemBuffer;
+
- // No extent data can be returned as this is not a physical drive.
- memset (extents, 0, sizeof (*extents));
- extents->NumberOfDiskExtents = 0;
+ 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);
diff --git a/src/Driver/Ntdriver.h b/src/Driver/Ntdriver.h
index 8403f212..b679952a 100644
--- a/src/Driver/Ntdriver.h
+++ b/src/Driver/Ntdriver.h
@@ -66,6 +66,7 @@ typedef struct EXTENSION
ULONG HostMaximumTransferLength;
ULONG HostMaximumPhysicalPages;
ULONG HostAlignmentMask;
+ ULONG DeviceNumber;
BOOL IncursSeekPenalty;
BOOL TrimEnabled;
diff --git a/src/Driver/Ntvol.c b/src/Driver/Ntvol.c
index c8552ab3..852aafd0 100644
--- a/src/Driver/Ntvol.c
+++ b/src/Driver/Ntvol.c
@@ -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;