mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 19:08:26 -06:00
Windows Driver: Implement querying physical sector size of veraCrypt volume through IOCTL_STORAGE_QUERY_PROPERTY
This commit is contained in:
@@ -103,6 +103,7 @@ typedef struct
|
|||||||
int pkcs5_prf;
|
int pkcs5_prf;
|
||||||
int ProtectedHidVolPkcs5Prf;
|
int ProtectedHidVolPkcs5Prf;
|
||||||
BOOL bTrueCryptMode;
|
BOOL bTrueCryptMode;
|
||||||
|
uint32 BytesPerPhysicalSector;
|
||||||
} MOUNT_STRUCT;
|
} MOUNT_STRUCT;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
#include "Resource.h"
|
#include "Resource.h"
|
||||||
|
|
||||||
@@ -6230,6 +6231,48 @@ void BroadcastDeviceChange (WPARAM message, int nDosDriveNo, DWORD driveMap)
|
|||||||
IgnoreWmDeviceChange = FALSE;
|
IgnoreWmDeviceChange = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL GetPhysicalDriveAlignment(UINT nDriveNumber, STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR* pDesc)
|
||||||
|
{
|
||||||
|
DWORD dwRet = NO_ERROR;
|
||||||
|
|
||||||
|
if (!pDesc)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// Format physical drive path (may be '\\.\PhysicalDrive0', '\\.\PhysicalDrive1' and so on).
|
||||||
|
TCHAR strDrivePath[512];
|
||||||
|
StringCbPrintf(strDrivePath, sizeof(strDrivePath), _T("\\\\.\\PhysicalDrive%u"), nDriveNumber);
|
||||||
|
|
||||||
|
// Get a handle to physical drive
|
||||||
|
HANDLE hDevice = ::CreateFile(strDrivePath, 0, FILE_SHARE_READ,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
|
||||||
|
if(INVALID_HANDLE_VALUE == hDevice)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// Set the input data structure
|
||||||
|
STORAGE_PROPERTY_QUERY storagePropertyQuery;
|
||||||
|
ZeroMemory(&storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY));
|
||||||
|
storagePropertyQuery.PropertyId = StorageAccessAlignmentProperty;
|
||||||
|
storagePropertyQuery.QueryType = PropertyStandardQuery;
|
||||||
|
|
||||||
|
// Get the necessary output buffer size
|
||||||
|
DWORD dwBytesReturned = 0;
|
||||||
|
BOOL bRet = ::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
|
||||||
|
&storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
|
||||||
|
pDesc, sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR),
|
||||||
|
&dwBytesReturned, NULL);
|
||||||
|
dwRet = ::GetLastError();
|
||||||
|
::CloseHandle(hDevice);
|
||||||
|
|
||||||
|
if (!bRet)
|
||||||
|
{
|
||||||
|
SetLastError (dwRet);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
|
|
||||||
// implementation of the generic wait dialog mechanism
|
// implementation of the generic wait dialog mechanism
|
||||||
@@ -6477,7 +6520,42 @@ retry:
|
|||||||
{
|
{
|
||||||
DWORD bps, flags, d;
|
DWORD bps, flags, d;
|
||||||
if (GetDiskFreeSpace (root, &d, &bps, &d, &d))
|
if (GetDiskFreeSpace (root, &d, &bps, &d, &d))
|
||||||
|
{
|
||||||
mount.BytesPerSector = bps;
|
mount.BytesPerSector = bps;
|
||||||
|
mount.BytesPerPhysicalSector = bps;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsOSAtLeast (WIN_VISTA))
|
||||||
|
{
|
||||||
|
if ( (strlen(root) >= 2)
|
||||||
|
&& (root[1] == ':')
|
||||||
|
&& (toupper(root[0]) >= 'A' && toupper(root[0]) <= 'Z')
|
||||||
|
)
|
||||||
|
{
|
||||||
|
string drivePath = "\\\\.\\X:";
|
||||||
|
HANDLE dev = INVALID_HANDLE_VALUE;
|
||||||
|
VOLUME_DISK_EXTENTS extents = {0};
|
||||||
|
DWORD dwResult = 0;
|
||||||
|
drivePath[4] = root[0];
|
||||||
|
|
||||||
|
if ((dev = CreateFile (drivePath.c_str(),0, 0, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
if (DeviceIoControl (dev, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &extents, sizeof(extents), &dwResult, NULL))
|
||||||
|
{
|
||||||
|
if (extents.NumberOfDiskExtents > 0)
|
||||||
|
{
|
||||||
|
STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR desc;
|
||||||
|
if (GetPhysicalDriveAlignment (extents.Extents[0].DiskNumber, &desc))
|
||||||
|
{
|
||||||
|
mount.BytesPerSector = desc.BytesPerLogicalSector;
|
||||||
|
mount.BytesPerPhysicalSector = desc.BytesPerPhysicalSector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle (dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Read-only host filesystem
|
// Read-only host filesystem
|
||||||
if (!mount.bMountReadOnly && GetVolumeInformation (root, NULL, 0, NULL, &d, &flags, NULL, 0))
|
if (!mount.bMountReadOnly && GetVolumeInformation (root, NULL, 0, NULL, &d, &flags, NULL, 0))
|
||||||
|
|||||||
@@ -120,8 +120,8 @@ NTSTATUS DriverAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo)
|
|||||||
|
|
||||||
if (VolumeClassFilterRegistered && BootArgsValid && BootArgs.HiddenSystemPartitionStart != 0)
|
if (VolumeClassFilterRegistered && BootArgsValid && BootArgs.HiddenSystemPartitionStart != 0)
|
||||||
{
|
{
|
||||||
PWSTR interfaceLinks;
|
PWSTR interfaceLinks = NULL;
|
||||||
if (NT_SUCCESS (IoGetDeviceInterfaces (&GUID_DEVINTERFACE_VOLUME, pdo, DEVICE_INTERFACE_INCLUDE_NONACTIVE, &interfaceLinks)))
|
if (NT_SUCCESS (IoGetDeviceInterfaces (&GUID_DEVINTERFACE_VOLUME, pdo, DEVICE_INTERFACE_INCLUDE_NONACTIVE, &interfaceLinks)) && interfaceLinks)
|
||||||
{
|
{
|
||||||
if (interfaceLinks[0] != UNICODE_NULL)
|
if (interfaceLinks[0] != UNICODE_NULL)
|
||||||
{
|
{
|
||||||
@@ -628,6 +628,42 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IOCTL_STORAGE_QUERY_PROPERTY:
|
||||||
|
if (ValidateIOBufferSize (Irp, sizeof (STORAGE_PROPERTY_QUERY), ValidateInput))
|
||||||
|
{
|
||||||
|
PSTORAGE_PROPERTY_QUERY pStoragePropQuery = (PSTORAGE_PROPERTY_QUERY) Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
STORAGE_QUERY_TYPE type = pStoragePropQuery->QueryType;
|
||||||
|
|
||||||
|
if (type == PropertyExistsQuery)
|
||||||
|
{
|
||||||
|
if (pStoragePropQuery->PropertyId == StorageAccessAlignmentProperty)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == PropertyStandardQuery)
|
||||||
|
{
|
||||||
|
if (pStoragePropQuery->PropertyId == StorageAccessAlignmentProperty)
|
||||||
|
{
|
||||||
|
if (ValidateIOBufferSize (Irp, sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR), ValidateOutput))
|
||||||
|
{
|
||||||
|
PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR outputBuffer = (PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR) Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
|
outputBuffer->Version = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR);
|
||||||
|
outputBuffer->Size = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR);
|
||||||
|
outputBuffer->BytesPerLogicalSector = Extension->BytesPerSector;
|
||||||
|
outputBuffer->BytesPerPhysicalSector = Extension->HostBytesPerPhysicalSector;
|
||||||
|
outputBuffer->BytesOffsetForSectorAlignment = Extension->BytesOffsetForSectorAlignment;
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case IOCTL_DISK_GET_PARTITION_INFO:
|
case IOCTL_DISK_GET_PARTITION_INFO:
|
||||||
if (ValidateIOBufferSize (Irp, sizeof (PARTITION_INFORMATION), ValidateOutput))
|
if (ValidateIOBufferSize (Irp, sizeof (PARTITION_INFORMATION), ValidateOutput))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ typedef struct EXTENSION
|
|||||||
UCHAR PartitionType; /* Partition info */
|
UCHAR PartitionType; /* Partition info */
|
||||||
|
|
||||||
uint32 HostBytesPerSector;
|
uint32 HostBytesPerSector;
|
||||||
|
uint32 HostBytesPerPhysicalSector;
|
||||||
|
ULONG BytesOffsetForSectorAlignment;
|
||||||
|
|
||||||
KEVENT keVolumeEvent; /* Event structure used when setting up a device */
|
KEVENT keVolumeEvent; /* Event structure used when setting up a device */
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
|||||||
PARTITION_INFORMATION_EX pix;
|
PARTITION_INFORMATION_EX pix;
|
||||||
LARGE_INTEGER diskLengthInfo;
|
LARGE_INTEGER diskLengthInfo;
|
||||||
DISK_GEOMETRY dg;
|
DISK_GEOMETRY dg;
|
||||||
|
STORAGE_PROPERTY_QUERY storagePropertyQuery = {0};
|
||||||
|
STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR storageDescriptor = {0};
|
||||||
|
|
||||||
ntStatus = IoGetDeviceObjectPointer (&FullFileName,
|
ntStatus = IoGetDeviceObjectPointer (&FullFileName,
|
||||||
FILE_READ_DATA | FILE_READ_ATTRIBUTES,
|
FILE_READ_DATA | FILE_READ_ATTRIBUTES,
|
||||||
@@ -97,6 +99,21 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
|||||||
lDiskLength.QuadPart = dg.Cylinders.QuadPart * dg.SectorsPerTrack * dg.TracksPerCylinder * dg.BytesPerSector;
|
lDiskLength.QuadPart = dg.Cylinders.QuadPart * dg.SectorsPerTrack * dg.TracksPerCylinder * dg.BytesPerSector;
|
||||||
Extension->HostBytesPerSector = dg.BytesPerSector;
|
Extension->HostBytesPerSector = dg.BytesPerSector;
|
||||||
|
|
||||||
|
storagePropertyQuery.PropertyId = StorageAccessAlignmentProperty;
|
||||||
|
storagePropertyQuery.QueryType = PropertyStandardQuery;
|
||||||
|
|
||||||
|
/* IOCTL_STORAGE_QUERY_PROPERTY supported only on Vista and above */
|
||||||
|
if (NT_SUCCESS (TCSendHostDeviceIoControlRequestEx (DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY,
|
||||||
|
(char*) &storagePropertyQuery, sizeof(storagePropertyQuery),
|
||||||
|
(char *) &storageDescriptor, sizeof (storageDescriptor))))
|
||||||
|
{
|
||||||
|
Extension->HostBytesPerPhysicalSector = storageDescriptor.BytesPerPhysicalSector;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Extension->HostBytesPerPhysicalSector = dg.BytesPerSector;
|
||||||
|
}
|
||||||
|
|
||||||
// Drive geometry is used only when IOCTL_DISK_GET_PARTITION_INFO fails
|
// Drive geometry is used only when IOCTL_DISK_GET_PARTITION_INFO fails
|
||||||
if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO_EX, (char *) &pix, sizeof (pix))))
|
if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO_EX, (char *) &pix, sizeof (pix))))
|
||||||
{
|
{
|
||||||
@@ -144,6 +161,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Extension->HostBytesPerSector = mount->BytesPerSector;
|
Extension->HostBytesPerSector = mount->BytesPerSector;
|
||||||
|
Extension->HostBytesPerPhysicalSector = mount->BytesPerPhysicalSector;
|
||||||
|
|
||||||
if (Extension->HostBytesPerSector != TC_SECTOR_SIZE_FILE_HOSTED_VOLUME)
|
if (Extension->HostBytesPerSector != TC_SECTOR_SIZE_FILE_HOSTED_VOLUME)
|
||||||
disableBuffering = FALSE;
|
disableBuffering = FALSE;
|
||||||
@@ -746,9 +764,11 @@ void TCCloseVolume (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS TCSendHostDeviceIoControlRequest (PDEVICE_OBJECT DeviceObject,
|
NTSTATUS TCSendHostDeviceIoControlRequestEx (PDEVICE_OBJECT DeviceObject,
|
||||||
PEXTENSION Extension,
|
PEXTENSION Extension,
|
||||||
ULONG IoControlCode,
|
ULONG IoControlCode,
|
||||||
|
void *InputBuffer,
|
||||||
|
ULONG InputBufferSize,
|
||||||
void *OutputBuffer,
|
void *OutputBuffer,
|
||||||
ULONG OutputBufferSize)
|
ULONG OutputBufferSize)
|
||||||
{
|
{
|
||||||
@@ -762,7 +782,7 @@ NTSTATUS TCSendHostDeviceIoControlRequest (PDEVICE_OBJECT DeviceObject,
|
|||||||
|
|
||||||
Irp = IoBuildDeviceIoControlRequest (IoControlCode,
|
Irp = IoBuildDeviceIoControlRequest (IoControlCode,
|
||||||
Extension->pFsdDevice,
|
Extension->pFsdDevice,
|
||||||
NULL, 0,
|
InputBuffer, InputBufferSize,
|
||||||
OutputBuffer, OutputBufferSize,
|
OutputBuffer, OutputBufferSize,
|
||||||
FALSE,
|
FALSE,
|
||||||
&Extension->keVolumeEvent,
|
&Extension->keVolumeEvent,
|
||||||
@@ -787,6 +807,15 @@ NTSTATUS TCSendHostDeviceIoControlRequest (PDEVICE_OBJECT DeviceObject,
|
|||||||
return ntStatus;
|
return ntStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS TCSendHostDeviceIoControlRequest (PDEVICE_OBJECT DeviceObject,
|
||||||
|
PEXTENSION Extension,
|
||||||
|
ULONG IoControlCode,
|
||||||
|
void *OutputBuffer,
|
||||||
|
ULONG OutputBufferSize)
|
||||||
|
{
|
||||||
|
return TCSendHostDeviceIoControlRequestEx (DeviceObject, Extension, IoControlCode, NULL, 0, OutputBuffer, OutputBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS COMPLETE_IRP (PDEVICE_OBJECT DeviceObject,
|
NTSTATUS COMPLETE_IRP (PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
NTSTATUS IrpStatus,
|
NTSTATUS IrpStatus,
|
||||||
|
|||||||
@@ -15,5 +15,6 @@ NTSTATUS TCOpenVolume ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension , MOU
|
|||||||
void TCCloseVolume ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension );
|
void TCCloseVolume ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension );
|
||||||
NTSTATUS TCCompletion ( PDEVICE_OBJECT DeviceObject , PIRP Irp , PVOID pUserBuffer );
|
NTSTATUS TCCompletion ( PDEVICE_OBJECT DeviceObject , PIRP Irp , PVOID pUserBuffer );
|
||||||
static NTSTATUS TCSendHostDeviceIoControlRequest ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension , ULONG IoControlCode , void *OutputBuffer , ULONG OutputBufferSize );
|
static NTSTATUS TCSendHostDeviceIoControlRequest ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension , ULONG IoControlCode , void *OutputBuffer , ULONG OutputBufferSize );
|
||||||
|
static NTSTATUS TCSendHostDeviceIoControlRequestEx ( PDEVICE_OBJECT DeviceObject , PEXTENSION Extension , ULONG IoControlCode , void *InputBuffer , ULONG InputBufferSize , void *OutputBuffer , ULONG OutputBufferSize );
|
||||||
NTSTATUS COMPLETE_IRP ( PDEVICE_OBJECT DeviceObject , PIRP Irp , NTSTATUS IrpStatus , ULONG_PTR IrpInformation );
|
NTSTATUS COMPLETE_IRP ( PDEVICE_OBJECT DeviceObject , PIRP Irp , NTSTATUS IrpStatus , ULONG_PTR IrpInformation );
|
||||||
static void RestoreTimeStamp ( PEXTENSION Extension );
|
static void RestoreTimeStamp ( PEXTENSION Extension );
|
||||||
|
|||||||
Reference in New Issue
Block a user