1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2026-01-04 12:48:12 -06:00

Windows: use large output buffer for IOCTL_DISK_GET_DRIVE_GEOMETRY_EX calls to avoid failure with disk drivers that don't support returning only sizeof(DISK_GEOMETRY_EX).

This commit is contained in:
Mounir IDRASSI
2017-07-27 00:02:20 +02:00
parent c29ee8331a
commit 72b7147021
5 changed files with 160 additions and 157 deletions

View File

@@ -8505,11 +8505,14 @@ BOOL GetPhysicalDriveGeometry (int driveNumber, PDISK_GEOMETRY_EX diskGeometry)
DWORD bytesRead = 0; DWORD bytesRead = 0;
ZeroMemory (diskGeometry, sizeof (DISK_GEOMETRY_EX)); ZeroMemory (diskGeometry, sizeof (DISK_GEOMETRY_EX));
BYTE dgBuffer[256];
if ( DeviceIoControl (hDev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, diskGeometry, sizeof (DISK_GEOMETRY_EX), &bytesRead, NULL) if ( DeviceIoControl (hDev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, dgBuffer, sizeof (dgBuffer), &bytesRead, NULL)
&& (bytesRead == sizeof (DISK_GEOMETRY_EX)) && (bytesRead >= (sizeof (DISK_GEOMETRY) + sizeof (LARGE_INTEGER)))
&& diskGeometry->Geometry.BytesPerSector) && ((PDISK_GEOMETRY_EX) dgBuffer)->Geometry.BytesPerSector)
{ {
memcpy (&diskGeometry->Geometry, &((PDISK_GEOMETRY_EX) dgBuffer)->Geometry, sizeof (DISK_GEOMETRY));
diskGeometry->DiskSize.QuadPart = ((PDISK_GEOMETRY_EX) dgBuffer)->DiskSize.QuadPart;
bResult = TRUE; bResult = TRUE;
} }
@@ -10910,15 +10913,15 @@ int OpenVolume (OpenVolumeContext *context, const wchar_t *volumePath, Password
} }
else else
{ {
DISK_GEOMETRY_EX driveInfo; BYTE dgBuffer[256];
if (!DeviceIoControl (context->HostFileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &driveInfo, sizeof (driveInfo), &dwResult, NULL)) if (!DeviceIoControl (context->HostFileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, dgBuffer, sizeof (dgBuffer), &dwResult, NULL))
{ {
status = ERR_OS_ERROR; status = ERR_OS_ERROR;
goto error; goto error;
} }
context->HostSize = driveInfo.DiskSize.QuadPart; context->HostSize = ((PDISK_GEOMETRY_EX) dgBuffer)->DiskSize.QuadPart;
} }
if (context->HostSize == 0) if (context->HostSize == 0)
@@ -11106,10 +11109,10 @@ BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
continue; continue;
DISK_GEOMETRY_EX driveInfo; BYTE dgBuffer[256];
DWORD dwResult; DWORD dwResult;
if (!DeviceIoControl (handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &driveInfo, sizeof (driveInfo), &dwResult, NULL)) if (!DeviceIoControl (handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, dgBuffer, sizeof (dgBuffer), &dwResult, NULL))
{ {
CloseHandle (handle); CloseHandle (handle);
continue; continue;
@@ -12063,95 +12066,95 @@ void UpdateMountableHostDeviceList (bool bFromService)
} }
else else
{ {
HANDLE disk = CreateFile( It->Path.c_str(), HANDLE disk = CreateFile( It->Path.c_str(),
0, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL );
if ( INVALID_HANDLE_VALUE != disk)
{
bool bIsDynamic = false;
bool bHasPartition = false;
if (DeviceIoControl(
disk,
IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
NULL, NULL,
OPEN_EXISTING,
0, 0,
NULL ); (LPVOID) buffer.data(),
if ( INVALID_HANDLE_VALUE != disk) (DWORD) buffer.size(),
{ (LPDWORD) &bytesReturned,
bool bIsDynamic = false; NULL) && (bytesReturned >= sizeof (DRIVE_LAYOUT_INFORMATION_EX)))
bool bHasPartition = false; {
if (DeviceIoControl( PDRIVE_LAYOUT_INFORMATION_EX layout = (PDRIVE_LAYOUT_INFORMATION_EX) buffer.data();
disk, // sanity checks
IOCTL_DISK_GET_DRIVE_LAYOUT_EX, if (layout->PartitionCount <= 256)
NULL,
0,
(LPVOID) buffer.data(),
(DWORD) buffer.size(),
(LPDWORD) &bytesReturned,
NULL) && (bytesReturned >= sizeof (DRIVE_LAYOUT_INFORMATION_EX)))
{ {
PDRIVE_LAYOUT_INFORMATION_EX layout = (PDRIVE_LAYOUT_INFORMATION_EX) buffer.data(); for (DWORD i = 0; i < layout->PartitionCount; i++)
// sanity checks
if (layout->PartitionCount <= 256)
{ {
for (DWORD i = 0; i < layout->PartitionCount; i++) if (layout->PartitionEntry[i].PartitionStyle == PARTITION_STYLE_MBR)
{ {
if (layout->PartitionEntry[i].PartitionStyle == PARTITION_STYLE_MBR) if (layout->PartitionEntry[i].Mbr.PartitionType == 0)
continue;
bHasPartition = true;
/* skip dynamic volume */
if (layout->PartitionEntry[i].Mbr.PartitionType == PARTITION_LDM)
{ {
if (layout->PartitionEntry[i].Mbr.PartitionType == 0) bIsDynamic = true;
continue; /* remove any partition that may have been added */
while (!mountableDevices.empty() && (mountableDevices.back().SystemNumber == It->SystemNumber))
bHasPartition = true; mountableDevices.pop_back ();
break;
/* skip dynamic volume */
if (layout->PartitionEntry[i].Mbr.PartitionType == PARTITION_LDM)
{
bIsDynamic = true;
/* remove any partition that may have been added */
while (!mountableDevices.empty() && (mountableDevices.back().SystemNumber == It->SystemNumber))
mountableDevices.pop_back ();
break;
}
} }
}
if (layout->PartitionEntry[i].PartitionStyle == PARTITION_STYLE_GPT) if (layout->PartitionEntry[i].PartitionStyle == PARTITION_STYLE_GPT)
{
if (IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_ENTRY_UNUSED_GUID))
continue;
bHasPartition = true;
/* skip dynamic volume */
if ( IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_LDM_METADATA_GUID)
|| IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_LDM_DATA_GUID)
)
{ {
if (IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_ENTRY_UNUSED_GUID)) bIsDynamic = true;
continue; /* remove any partition that may have been added */
while (!mountableDevices.empty() && (mountableDevices.back().SystemNumber == It->SystemNumber))
bHasPartition = true; mountableDevices.pop_back ();
break;
/* skip dynamic volume */
if ( IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_LDM_METADATA_GUID)
|| IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_LDM_DATA_GUID)
)
{
bIsDynamic = true;
/* remove any partition that may have been added */
while (!mountableDevices.empty() && (mountableDevices.back().SystemNumber == It->SystemNumber))
mountableDevices.pop_back ();
break;
}
} }
}
WCHAR path[MAX_PATH]; WCHAR path[MAX_PATH];
StringCbPrintfW (path, sizeof(path), L"\\\\?\\GLOBALROOT\\Device\\Harddisk%d\\Partition%d", It->SystemNumber, layout->PartitionEntry[i].PartitionNumber); StringCbPrintfW (path, sizeof(path), L"\\\\?\\GLOBALROOT\\Device\\Harddisk%d\\Partition%d", It->SystemNumber, layout->PartitionEntry[i].PartitionNumber);
HANDLE handle = CreateFile( path, HANDLE handle = CreateFile( path,
0, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, NULL,
OPEN_EXISTING, OPEN_EXISTING,
0, 0,
NULL ); NULL );
if ((handle != INVALID_HANDLE_VALUE) || (GetLastError () == ERROR_ACCESS_DENIED)) if ((handle != INVALID_HANDLE_VALUE) || (GetLastError () == ERROR_ACCESS_DENIED))
{ {
AddDeviceToList (mountableDevices, It->SystemNumber, layout->PartitionEntry[i].PartitionNumber); AddDeviceToList (mountableDevices, It->SystemNumber, layout->PartitionEntry[i].PartitionNumber);
if (handle != INVALID_HANDLE_VALUE) if (handle != INVALID_HANDLE_VALUE)
CloseHandle (handle); CloseHandle (handle);
}
} }
} }
} }
}
if (bIsDynamic) if (bIsDynamic)
dynamicVolumesPresent = true; dynamicVolumesPresent = true;
if (!bHasPartition) if (!bHasPartition)
AddDeviceToList (mountableDevices, It->SystemNumber, 0); AddDeviceToList (mountableDevices, It->SystemNumber, 0);
CloseHandle (disk); CloseHandle (disk);
} }
@@ -12221,79 +12224,79 @@ wstring FindDeviceByVolumeID (const BYTE volumeID [VOLUME_ID_SIZE])
/* not mounted. Look for it in the local drives*/ /* not mounted. Look for it in the local drives*/
EnterCriticalSection (&csMountableDevices); EnterCriticalSection (&csMountableDevices);
std::vector<HostDevice> newDevices = mountableDevices; std::vector<HostDevice> newDevices = mountableDevices;
LeaveCriticalSection (&csMountableDevices); LeaveCriticalSection (&csMountableDevices);
EnterCriticalSection (&csVolumeIdCandidates); EnterCriticalSection (&csVolumeIdCandidates);
finally_do ({ LeaveCriticalSection (&csVolumeIdCandidates); }); finally_do ({ LeaveCriticalSection (&csVolumeIdCandidates); });
/* remove any devices that don't exist anymore */ /* remove any devices that don't exist anymore */
for (std::vector<HostDevice>::iterator It = volumeIdCandidates.begin(); for (std::vector<HostDevice>::iterator It = volumeIdCandidates.begin();
It != volumeIdCandidates.end();) It != volumeIdCandidates.end();)
{ {
bool bFound = false; bool bFound = false;
for (std::vector<HostDevice>::iterator newIt = newDevices.begin();
newIt != newDevices.end(); newIt++)
{
if (It->Path == newIt->Path)
{
bFound = true;
break;
}
}
if (bFound)
It++;
else
It = volumeIdCandidates.erase (It);
}
/* Add newly inserted devices and compute their VolumeID */
for (std::vector<HostDevice>::iterator newIt = newDevices.begin(); for (std::vector<HostDevice>::iterator newIt = newDevices.begin();
newIt != newDevices.end(); newIt++) newIt != newDevices.end(); newIt++)
{ {
if (It->Path == newIt->Path) bool bFound = false;
for (std::vector<HostDevice>::iterator It = volumeIdCandidates.begin();
It != volumeIdCandidates.end(); It++)
{ {
bFound = true; if (It->Path == newIt->Path)
break; {
bFound = true;
break;
}
}
if (!bFound)
{
/* new device/partition. Compute its Volume IDs */
OPEN_TEST_STRUCT openTest = {0};
if (OpenDevice (newIt->Path.c_str(), &openTest, TRUE, TRUE)
&& (openTest.VolumeIDComputed[TC_VOLUME_TYPE_NORMAL] && openTest.VolumeIDComputed[TC_VOLUME_TYPE_HIDDEN])
)
{
memcpy (newIt->VolumeIDs, openTest.volumeIDs, sizeof (newIt->VolumeIDs));
newIt->HasVolumeIDs = true;
}
else
newIt->HasVolumeIDs = false;
volumeIdCandidates.push_back (*newIt);
} }
} }
if (bFound)
It++;
else
It = volumeIdCandidates.erase (It);
}
/* Add newly inserted devices and compute their VolumeID */
for (std::vector<HostDevice>::iterator newIt = newDevices.begin();
newIt != newDevices.end(); newIt++)
{
bool bFound = false;
for (std::vector<HostDevice>::iterator It = volumeIdCandidates.begin(); for (std::vector<HostDevice>::iterator It = volumeIdCandidates.begin();
It != volumeIdCandidates.end(); It++) It != volumeIdCandidates.end(); It++)
{ {
if (It->Path == newIt->Path) if ( It->HasVolumeIDs &&
{ ( (0 == memcmp (volumeID, It->VolumeIDs[TC_VOLUME_TYPE_NORMAL], VOLUME_ID_SIZE))
bFound = true; || (0 == memcmp (volumeID, It->VolumeIDs[TC_VOLUME_TYPE_HIDDEN], VOLUME_ID_SIZE))
break; )
}
}
if (!bFound)
{
/* new device/partition. Compute its Volume IDs */
OPEN_TEST_STRUCT openTest = {0};
if (OpenDevice (newIt->Path.c_str(), &openTest, TRUE, TRUE)
&& (openTest.VolumeIDComputed[TC_VOLUME_TYPE_NORMAL] && openTest.VolumeIDComputed[TC_VOLUME_TYPE_HIDDEN])
) )
{ {
memcpy (newIt->VolumeIDs, openTest.volumeIDs, sizeof (newIt->VolumeIDs)); return It->Path;
newIt->HasVolumeIDs = true;
} }
else
newIt->HasVolumeIDs = false;
volumeIdCandidates.push_back (*newIt);
} }
}
for (std::vector<HostDevice>::iterator It = volumeIdCandidates.begin();
It != volumeIdCandidates.end(); It++)
{
if ( It->HasVolumeIDs &&
( (0 == memcmp (volumeID, It->VolumeIDs[TC_VOLUME_TYPE_NORMAL], VOLUME_ID_SIZE))
|| (0 == memcmp (volumeID, It->VolumeIDs[TC_VOLUME_TYPE_HIDDEN], VOLUME_ID_SIZE))
)
)
{
return It->Path;
}
}
return L""; return L"";
} }

View File

@@ -187,7 +187,6 @@ int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5,
BOOL bTimeStampValid = FALSE; BOOL bTimeStampValid = FALSE;
LARGE_INTEGER headerOffset; LARGE_INTEGER headerOffset;
BOOL backupHeader; BOOL backupHeader;
DISK_GEOMETRY_EX driveInfo;
if (oldPassword->Length == 0 || newPassword->Length == 0) return -1; if (oldPassword->Length == 0 || newPassword->Length == 0) return -1;
@@ -236,12 +235,13 @@ int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5,
} }
else else
{ {
BYTE dgBuffer[256];
PARTITION_INFORMATION diskInfo; PARTITION_INFORMATION diskInfo;
DWORD dwResult; DWORD dwResult;
BOOL bResult; BOOL bResult;
bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0,
&driveInfo, sizeof (driveInfo), &dwResult, NULL); dgBuffer, sizeof (dgBuffer), &dwResult, NULL);
if (!bResult) if (!bResult)
goto error; goto error;
@@ -254,7 +254,7 @@ int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5,
} }
else else
{ {
hostSize = driveInfo.DiskSize.QuadPart; hostSize = ((PDISK_GEOMETRY_EX) dgBuffer)->DiskSize.QuadPart;
} }
if (hostSize == 0) if (hostSize == 0)

View File

@@ -559,17 +559,17 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
} }
else else
{ {
DISK_GEOMETRY_EX driveInfo; BYTE dgBuffer[256];
bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0,
&driveInfo, sizeof (driveInfo), &dwResult, NULL); dgBuffer, sizeof (dgBuffer), &dwResult, NULL);
if (!bResult) if (!bResult)
goto error; goto error;
hostSize = driveInfo.DiskSize.QuadPart; hostSize = ((PDISK_GEOMETRY_EX) dgBuffer)->DiskSize.QuadPart;
HostSectorSize = driveInfo.Geometry.BytesPerSector; HostSectorSize = ((PDISK_GEOMETRY_EX) dgBuffer)->Geometry.BytesPerSector;
} }
if (hostSize == 0) if (hostSize == 0)

View File

@@ -772,7 +772,7 @@ int EncryptPartitionInPlaceResume (HANDLE dev,
Password *password = volParams->password; Password *password = volParams->password;
int pkcs5_prf = volParams->pkcs5; int pkcs5_prf = volParams->pkcs5;
int pim = volParams->pim; int pim = volParams->pim;
DISK_GEOMETRY_EX driveGeometry; DISK_GEOMETRY driveGeometry;
HWND hwndDlg = volParams->hwndDlg; HWND hwndDlg = volParams->hwndDlg;
@@ -855,13 +855,13 @@ int EncryptPartitionInPlaceResume (HANDLE dev,
NULL); NULL);
if (!DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &driveGeometry, sizeof (driveGeometry), &dwResult, NULL)) if (!DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &driveGeometry, sizeof (driveGeometry), &dwResult, NULL))
{ {
nStatus = ERR_OS_ERROR; nStatus = ERR_OS_ERROR;
goto closing_seq; goto closing_seq;
} }
sectorSize = driveGeometry.Geometry.BytesPerSector; sectorSize = driveGeometry.BytesPerSector;
nStatus = OpenBackupHeader (dev, devicePath, password, pkcs5_prf, pim, &masterCryptoInfo, headerCryptoInfo, deviceSize); nStatus = OpenBackupHeader (dev, devicePath, password, pkcs5_prf, pim, &masterCryptoInfo, headerCryptoInfo, deviceSize);
@@ -1282,7 +1282,7 @@ int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile
HWND hwndDlg = volParams->hwndDlg; HWND hwndDlg = volParams->hwndDlg;
int pkcs5_prf = volParams->pkcs5; int pkcs5_prf = volParams->pkcs5;
int pim = volParams->pim; int pim = volParams->pim;
DISK_GEOMETRY_EX driveGeometry; DISK_GEOMETRY driveGeometry;
buf = (char *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE); buf = (char *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE);
@@ -1357,15 +1357,15 @@ int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile
NULL); NULL);
if (!DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &driveGeometry, sizeof (driveGeometry), &dwResult, NULL)) if (!DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &driveGeometry, sizeof (driveGeometry), &dwResult, NULL))
{ {
nStatus = ERR_OS_ERROR; nStatus = ERR_OS_ERROR;
goto closing_seq; goto closing_seq;
} }
if ( (driveGeometry.Geometry.BytesPerSector == 0) if ( (driveGeometry.BytesPerSector == 0)
|| (driveGeometry.Geometry.BytesPerSector > TC_MAX_VOLUME_SECTOR_SIZE) || (driveGeometry.BytesPerSector > TC_MAX_VOLUME_SECTOR_SIZE)
|| (driveGeometry.Geometry.BytesPerSector % ENCRYPTION_DATA_UNIT_SIZE != 0) || (driveGeometry.BytesPerSector % ENCRYPTION_DATA_UNIT_SIZE != 0)
) )
{ {
Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg); Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg);
@@ -1373,7 +1373,7 @@ int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile
goto closing_seq; goto closing_seq;
} }
sectorSize = driveGeometry.Geometry.BytesPerSector; sectorSize = driveGeometry.BytesPerSector;
tmpSectorBuf = (byte *) TCalloc (sectorSize); tmpSectorBuf = (byte *) TCalloc (sectorSize);

View File

@@ -10448,15 +10448,15 @@ int RestoreVolumeHeader (HWND hwndDlg, const wchar_t *lpszVolume)
} }
else else
{ {
DISK_GEOMETRY_EX driveInfo; BYTE dgBuffer[256];
bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0,
&driveInfo, sizeof (driveInfo), &dwResult, NULL); dgBuffer, sizeof (dgBuffer), &dwResult, NULL);
if (!bResult) if (!bResult)
goto error; goto error;
hostSize = driveInfo.DiskSize.QuadPart; hostSize = ((PDISK_GEOMETRY_EX) dgBuffer)->DiskSize.QuadPart;
} }
if (hostSize == 0) if (hostSize == 0)