Я использую:
DWORD d = GetLogicalDrives();
for (int i = 0; i < 26; i++)
{
if ((1 << i) & d) // drive letter 'A' + i present on computer
{
wstring s = std::wstring(L"\\\\.\\") + wchar_t('A' + i) + L":";
PARTITION_INFORMATION diskInfo;
DWORD dwResult;
HANDLE dev = CreateFile(LPWSTR(s.c_str()), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &diskInfo, sizeof(diskInfo), &dwResult, NULL);
CloseHandle(dev);
if (diskInfo.PartitionType == PARTITION_IFS)
{
...
}
}
}
для перечисления всех разделов NTFS компьютера.
Он работает на моей Windows 7, на Windows 8.1, на которой я пробовал, и на компьютере с Windows 10.
Но это не удается на другом компьютере с Windows 10: на этом том C:
имеет значение diskInfo.PartitionType
, равное 0x00
, вместо 0x07
(PARTITION_IFS
).
Это значение (см. здесь ):
PARTITION_ENTRY_UNUSED : 0x00 : неиспользуемый раздел записи.
Это странно, так как, я могу подтвердить, раздел действительно NTFS.
Вопросы:
Известно ли, что
IOCTL_DISK_GET_PARTITION_INFO
не дает стопроцентной надежности для получения типа раздела?Какой способ перечисления всех томов NTFS может быть более надежным?
Примечание. Я также рассматривал использование IOCTL_DISK_GET_PARTITION_INFO_EX
a> вместо IOCTL_DISK_GET_PARTITION_INFO
, но затем структура PARTITION_INFORMATION_EX
не дает информации о PartitionType
, тогда как структура PARTITION_INFORMATION
предоставляет доступ к PartitionType
.
CreateFile()
иDeviceIoControl()
действительно успешны, прежде чем оцениватьdiskInfo.PartitionType
. Другой способ найти разделы NTFS — использоватьGetLogicalDrives/Strings()
иGetVolumeInformation()
, параметрlpFileSystemNameBuffer
вернет имя файловой системы на каждом запрашиваемом диске... - person Remy Lebeau   schedule 20.03.2019GetLogicalDrives/Strings()
. Это уменьшит количество дисков, которые вы пытаетесь запросить, даже если вы придерживаетесьCreateFile()
/DeviceIoControl()
. Вместо того, чтобы вслепую перебирать все 26 букв алфавита, вам нужно запрашивать только те, которые действительно назначены диску. - person Remy Lebeau   schedule 20.03.2019GetLogicalDrives
, я не включил его сюда, потому что думал, что он не имеет отношения к проблеме, но вы правы: это важная часть, поэтому я отредактировал вопрос, чтобы включить Это. (Извините, я должен был включить это раньше). С текущим кодом, что бы вы изменили? Если у вас есть возможность, не могли бы вы опубликовать пример кода в ответе? Заранее спасибо. - person Basj   schedule 20.03.2019wmi
запрос для перечисления всех разделы, что-то вроде PowerShellGet-WmiObject -Class "Win32_Volume" -Namespace "ROOT\CIMV2" | Select-Object -Property DriveLetter, Label, FileSystem, DeviceId
(начиная с Windows 8, используйте-namespace "ROOT\Microsoft\Windows\Storage" -classname "MSFT_Volume"
и-Property DriveLetter, FileSystemLabel, FileSystem, UniqueId
). - person JosefZ   schedule 20.03.2019IOCTL_DISK_GET_PARTITION_INFO_EX
для проверки типа раздела - person RbMm   schedule 20.03.2019GetLogicalDrives
,DeviceIoControl
,IOCTL_DISK_GET_PARTITION_INFO
противIOCTL_DISK_GET_PARTITION_INFO_EX
,Get-WMiObject
,GetVolumeInformationW
и т. д., так что мы легко можем запутаться. Хороший ответ был бы очень полезен для людей, которые хотят в будущем перечислять тома NTFS. - person Basj   schedule 20.03.2019ret = DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &diskInfo, sizeof(diskInfo), &lpBytesReturned, NULL);
на компьютере, где произошел сбой, я однажды получил0
0
дляlpBytesReturned
иret
. После перезагрузки у меня было2005860068
0
. В обоих случаях0
вместоret
указывает на сбой. Любая идея, как я могу исследовать дальше? - person Basj   schedule 20.03.2019CreateFile()
перед вызовомDeviceIoControl()
.CreateFile()
возвращаетINVALID_HANDLE_VALUE
в случае ошибки. Кроме того, вам нужно использоватьGetLastError()
, чтобы узнать, ПОЧЕМУ каждая из этих функций не работает. Например:dev = CreateFile(...); if (dev == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); ... } else { ret = DeviceIoControl(dev, ...); if (ret == FALSE) { DWORD err = GetLastError(); ... } CloseHandle(dev); }
- person Remy Lebeau   schedule 20.03.2019CreateFile
завершается успешно, аDeviceIoControl
терпит неудачу (возвращает0
/FALSE
).GetLastError()
это1
. Я посмотрел здесь, но не нашел причина ошибки. - person Basj   schedule 20.03.2019IOCTL_DISK_GET_PARTITION_INFO_EX
вместоIOCTL_DISK_GET_PARTITION_INFO
, но тогда структураPARTITION_INFORMATION_EX
не дает информации оPartitionType
, тогда как структураPARTITION_INFORMATION
дает доступ кPartitionType
. Что вы думаете? - person Basj   schedule 20.03.2019ERROR_INVALID_FUNCTION
. Это означает, чтоIOCTL_DISK_GET_PARTITION_INFO
не поддерживается устройством, которое вы передалиDeviceIoControl()
. - person Remy Lebeau   schedule 21.03.2019PARTITION_INFORMATION_EX
, кажется, не дает информации оPartitionType
- да, это так.PARTITION_INFORMATION_EX
имеет полеPartitionStyle
, которое говорит вам, следует ли смотреть на полеMbr
илиGpt
для получения дополнительной информации. Обе эти структуры имеют полеPartitionType
.Mbr.PartitionType
этоBYTE
,Gpt.PartitionType
этоGUID
. - person Remy Lebeau   schedule 21.03.2019