From 72b7147021a18ea6a045514fa7cad7772c4bb811 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Thu, 27 Jul 2017 00:02:20 +0200 Subject: 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). --- src/Common/Dlgcode.c | 271 ++++++++++++++++++++-------------------- src/Common/Password.c | 6 +- src/ExpandVolume/ExpandVolume.c | 8 +- src/Format/InPlace.c | 18 +-- src/Mount/Mount.c | 6 +- 5 files changed, 156 insertions(+), 153 deletions(-) (limited to 'src') diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index a5c5a293..a6362dfb 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -8505,11 +8505,14 @@ BOOL GetPhysicalDriveGeometry (int driveNumber, PDISK_GEOMETRY_EX diskGeometry) DWORD bytesRead = 0; 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) - && (bytesRead == sizeof (DISK_GEOMETRY_EX)) - && diskGeometry->Geometry.BytesPerSector) + if ( DeviceIoControl (hDev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, dgBuffer, sizeof (dgBuffer), &bytesRead, NULL) + && (bytesRead >= (sizeof (DISK_GEOMETRY) + sizeof (LARGE_INTEGER))) + && ((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; } @@ -10910,15 +10913,15 @@ int OpenVolume (OpenVolumeContext *context, const wchar_t *volumePath, Password } 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; goto error; } - context->HostSize = driveInfo.DiskSize.QuadPart; + context->HostSize = ((PDISK_GEOMETRY_EX) dgBuffer)->DiskSize.QuadPart; } if (context->HostSize == 0) @@ -11106,10 +11109,10 @@ BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly) if (handle == INVALID_HANDLE_VALUE) continue; - DISK_GEOMETRY_EX driveInfo; + BYTE dgBuffer[256]; 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); continue; @@ -12063,95 +12066,95 @@ void UpdateMountableHostDeviceList (bool bFromService) } else { - HANDLE disk = CreateFile( It->Path.c_str(), - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE, + HANDLE disk = CreateFile( It->Path.c_str(), + 0, + 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, - 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, - 0, - (LPVOID) buffer.data(), - (DWORD) buffer.size(), - (LPDWORD) &bytesReturned, - NULL) && (bytesReturned >= sizeof (DRIVE_LAYOUT_INFORMATION_EX))) + (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(); + // sanity checks + if (layout->PartitionCount <= 256) { - PDRIVE_LAYOUT_INFORMATION_EX layout = (PDRIVE_LAYOUT_INFORMATION_EX) buffer.data(); - // sanity checks - if (layout->PartitionCount <= 256) + for (DWORD i = 0; i < layout->PartitionCount; i++) { - 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; + if (layout->PartitionEntry[i].Mbr.PartitionType == 0) + continue; - bHasPartition = true; + bHasPartition = true; - /* 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) + /* skip dynamic volume */ + if (layout->PartitionEntry[i].Mbr.PartitionType == PARTITION_LDM) { - if (IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_ENTRY_UNUSED_GUID)) - continue; + bIsDynamic = true; + /* remove any partition that may have been added */ + while (!mountableDevices.empty() && (mountableDevices.back().SystemNumber == It->SystemNumber)) + mountableDevices.pop_back (); + break; + } + } - bHasPartition = true; + if (layout->PartitionEntry[i].PartitionStyle == PARTITION_STYLE_GPT) + { + if (IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_ENTRY_UNUSED_GUID)) + continue; - /* 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; - } - } + bHasPartition = true; - WCHAR path[MAX_PATH]; - StringCbPrintfW (path, sizeof(path), L"\\\\?\\GLOBALROOT\\Device\\Harddisk%d\\Partition%d", It->SystemNumber, layout->PartitionEntry[i].PartitionNumber); - HANDLE handle = CreateFile( path, - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - 0, - NULL ); - if ((handle != INVALID_HANDLE_VALUE) || (GetLastError () == ERROR_ACCESS_DENIED)) + /* skip dynamic volume */ + if ( IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_LDM_METADATA_GUID) + || IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_LDM_DATA_GUID) + ) { - AddDeviceToList (mountableDevices, It->SystemNumber, layout->PartitionEntry[i].PartitionNumber); - if (handle != INVALID_HANDLE_VALUE) - CloseHandle (handle); + 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]; + StringCbPrintfW (path, sizeof(path), L"\\\\?\\GLOBALROOT\\Device\\Harddisk%d\\Partition%d", It->SystemNumber, layout->PartitionEntry[i].PartitionNumber); + HANDLE handle = CreateFile( path, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL ); + if ((handle != INVALID_HANDLE_VALUE) || (GetLastError () == ERROR_ACCESS_DENIED)) + { + AddDeviceToList (mountableDevices, It->SystemNumber, layout->PartitionEntry[i].PartitionNumber); + if (handle != INVALID_HANDLE_VALUE) + CloseHandle (handle); + } } } + } - if (bIsDynamic) - dynamicVolumesPresent = true; + if (bIsDynamic) + dynamicVolumesPresent = true; - if (!bHasPartition) - AddDeviceToList (mountableDevices, It->SystemNumber, 0); + if (!bHasPartition) + AddDeviceToList (mountableDevices, It->SystemNumber, 0); CloseHandle (disk); } @@ -12221,79 +12224,79 @@ wstring FindDeviceByVolumeID (const BYTE volumeID [VOLUME_ID_SIZE]) /* not mounted. Look for it in the local drives*/ - EnterCriticalSection (&csMountableDevices); - std::vector newDevices = mountableDevices; - LeaveCriticalSection (&csMountableDevices); + EnterCriticalSection (&csMountableDevices); + std::vector newDevices = mountableDevices; + LeaveCriticalSection (&csMountableDevices); - EnterCriticalSection (&csVolumeIdCandidates); - finally_do ({ LeaveCriticalSection (&csVolumeIdCandidates); }); + EnterCriticalSection (&csVolumeIdCandidates); + finally_do ({ LeaveCriticalSection (&csVolumeIdCandidates); }); - /* remove any devices that don't exist anymore */ - for (std::vector::iterator It = volumeIdCandidates.begin(); - It != volumeIdCandidates.end();) - { - bool bFound = false; - for (std::vector::iterator newIt = newDevices.begin(); - newIt != newDevices.end(); newIt++) + /* remove any devices that don't exist anymore */ + for (std::vector::iterator It = volumeIdCandidates.begin(); + It != volumeIdCandidates.end();) { - if (It->Path == newIt->Path) + bool bFound = false; + for (std::vector::iterator newIt = newDevices.begin(); + newIt != newDevices.end(); newIt++) { - bFound = true; - break; + if (It->Path == newIt->Path) + { + bFound = true; + break; + } } + + if (bFound) + It++; + else + It = volumeIdCandidates.erase (It); } - if (bFound) - It++; - else - It = volumeIdCandidates.erase (It); - } + /* Add newly inserted devices and compute their VolumeID */ + for (std::vector::iterator newIt = newDevices.begin(); + newIt != newDevices.end(); newIt++) + { + bool bFound = false; - /* Add newly inserted devices and compute their VolumeID */ - for (std::vector::iterator newIt = newDevices.begin(); - newIt != newDevices.end(); newIt++) - { - bool bFound = false; + for (std::vector::iterator It = volumeIdCandidates.begin(); + It != volumeIdCandidates.end(); It++) + { + if (It->Path == newIt->Path) + { + bFound = true; + break; + } + } - for (std::vector::iterator It = volumeIdCandidates.begin(); - It != volumeIdCandidates.end(); It++) - { - if (It->Path == newIt->Path) + if (!bFound) { - bFound = true; - break; + /* 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) + for (std::vector::iterator It = volumeIdCandidates.begin(); + It != volumeIdCandidates.end(); It++) { - /* 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]) + 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)) + ) ) { - memcpy (newIt->VolumeIDs, openTest.volumeIDs, sizeof (newIt->VolumeIDs)); - newIt->HasVolumeIDs = true; + return It->Path; } - else - newIt->HasVolumeIDs = false; - volumeIdCandidates.push_back (*newIt); } - } - - for (std::vector::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""; } diff --git a/src/Common/Password.c b/src/Common/Password.c index 8ba91374..5643cef0 100644 --- a/src/Common/Password.c +++ b/src/Common/Password.c @@ -187,7 +187,6 @@ int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5, BOOL bTimeStampValid = FALSE; LARGE_INTEGER headerOffset; BOOL backupHeader; - DISK_GEOMETRY_EX driveInfo; 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 { + BYTE dgBuffer[256]; PARTITION_INFORMATION diskInfo; DWORD dwResult; BOOL bResult; bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, - &driveInfo, sizeof (driveInfo), &dwResult, NULL); + dgBuffer, sizeof (dgBuffer), &dwResult, NULL); if (!bResult) goto error; @@ -254,7 +254,7 @@ int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5, } else { - hostSize = driveInfo.DiskSize.QuadPart; + hostSize = ((PDISK_GEOMETRY_EX) dgBuffer)->DiskSize.QuadPart; } if (hostSize == 0) diff --git a/src/ExpandVolume/ExpandVolume.c b/src/ExpandVolume/ExpandVolume.c index 3ed22575..9e9252c3 100644 --- a/src/ExpandVolume/ExpandVolume.c +++ b/src/ExpandVolume/ExpandVolume.c @@ -559,17 +559,17 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas } else { - DISK_GEOMETRY_EX driveInfo; + BYTE dgBuffer[256]; bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, - &driveInfo, sizeof (driveInfo), &dwResult, NULL); + dgBuffer, sizeof (dgBuffer), &dwResult, NULL); if (!bResult) 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) diff --git a/src/Format/InPlace.c b/src/Format/InPlace.c index 224a3c1f..b2f1b386 100644 --- a/src/Format/InPlace.c +++ b/src/Format/InPlace.c @@ -772,7 +772,7 @@ int EncryptPartitionInPlaceResume (HANDLE dev, Password *password = volParams->password; int pkcs5_prf = volParams->pkcs5; int pim = volParams->pim; - DISK_GEOMETRY_EX driveGeometry; + DISK_GEOMETRY driveGeometry; HWND hwndDlg = volParams->hwndDlg; @@ -855,13 +855,13 @@ int EncryptPartitionInPlaceResume (HANDLE dev, 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; goto closing_seq; } - sectorSize = driveGeometry.Geometry.BytesPerSector; + sectorSize = driveGeometry.BytesPerSector; 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; int pkcs5_prf = volParams->pkcs5; int pim = volParams->pim; - DISK_GEOMETRY_EX driveGeometry; + DISK_GEOMETRY driveGeometry; buf = (char *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE); @@ -1357,15 +1357,15 @@ int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile 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; goto closing_seq; } - if ( (driveGeometry.Geometry.BytesPerSector == 0) - || (driveGeometry.Geometry.BytesPerSector > TC_MAX_VOLUME_SECTOR_SIZE) - || (driveGeometry.Geometry.BytesPerSector % ENCRYPTION_DATA_UNIT_SIZE != 0) + if ( (driveGeometry.BytesPerSector == 0) + || (driveGeometry.BytesPerSector > TC_MAX_VOLUME_SECTOR_SIZE) + || (driveGeometry.BytesPerSector % ENCRYPTION_DATA_UNIT_SIZE != 0) ) { Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg); @@ -1373,7 +1373,7 @@ int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile goto closing_seq; } - sectorSize = driveGeometry.Geometry.BytesPerSector; + sectorSize = driveGeometry.BytesPerSector; tmpSectorBuf = (byte *) TCalloc (sectorSize); diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index b3773b1a..ec612a16 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -10448,15 +10448,15 @@ int RestoreVolumeHeader (HWND hwndDlg, const wchar_t *lpszVolume) } else { - DISK_GEOMETRY_EX driveInfo; + BYTE dgBuffer[256]; bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, - &driveInfo, sizeof (driveInfo), &dwResult, NULL); + dgBuffer, sizeof (dgBuffer), &dwResult, NULL); if (!bResult) goto error; - hostSize = driveInfo.DiskSize.QuadPart; + hostSize = ((PDISK_GEOMETRY_EX) dgBuffer)->DiskSize.QuadPart; } if (hostSize == 0) -- cgit v1.2.3