Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.147.104.248] |
|
Сообщ.
#1
,
|
|
|
Доброго времени суток!
Требуется работать с физическими дисками. Как это делать - нашёл и разобрался. Интересует функция для поиска и перечисления физических дисков. В какую сторону копать, подскажите, плз. |
Сообщ.
#2
,
|
|
|
Именно физических? Хз, попробуй открывать на чтение в цикле "\\\\.\\PHYSICALDRIVE0" "\\\\.\\PHYSICALDRIVE1" и т.д.
Добавлено WMI посмотри еще. |
Сообщ.
#3
,
|
|
|
Причем, если же CreateFile() вернет INVALID_HANDLE_VALUE, то для правильного подсчета \\.\PHYSICALDRIVEx надо еще см. GetLastError() потому, что диск может быть открыт ранее в Exclusive режиме и т.п.
|
Сообщ.
#4
,
|
|
|
Да, перебор отлично работает, спасибо!
Если кому вдруг понадобится - вот код: void MainWindow::enumDrives() { WCHAR wDriveName[512]; HANDLE hDrive; for (int drive = 0;; drive++) { wsprintf(wDriveName, L"\\\\.\\PHYSICALDRIVE%d", drive); if ((hDrive = CreateFile(wDriveName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_FILE_NOT_FOUND) break; } else { ui->drivesCombo->addItem(QString::fromWCharArray(wDriveName)); CloseHandle(hDrive); } } } Ориентирован, правда, на Qt, но без труда переделывается =) |
Сообщ.
#5
,
|
|
|
Хрен твоей программой я бы пользоваться не стал.
Ну, во-первых, кто сказал, что дисков (физических) может быть 32? А почему не может быть 40? Во-вторых, если диск найден и был открыт через CreateFile(), то кто будет закрывать описатель и освобождать выделенные ресурсы? Ну и в-третьих, есть подозрение, что автору нужны не "физические" диски, а тома ж/д, имеющиеся в системе (навроде: C:, D: и т.п.). В последнем случае спасут GetLogicalDrives() + GetDriveType(). Ну а уж если хочется еще и такие красивые имена получить, то можно воспользоваться ф-цией QueryDosDevice(). |
Сообщ.
#6
,
|
|
|
Цитата ALXR @ Ну, во-первых, кто сказал, что дисков (физических) может быть 32? Может. Но мой софт ориентирован не на мегакластеры, а на десктопы. Думаю, кому надо, тот без труда сможет это исправить. Цитата ALXR @ Во-вторых, если диск найден и был открыт через CreateFile(), то кто будет закрывать описатель и освобождать выделенные ресурсы? Согласен. В своей программе это я исправил почти сразу. Тут забыл. Цитата ALXR @ Ну и в-третьих, есть подозрение, что автору нужны не "физические" диски, а тома ж/д, имеющиеся в системе Нет, автора интересуют именно физические диски, ибо надо прописывать MBR |
Сообщ.
#7
,
|
|
|
Цитата Хрен @ А зачем без нужды уменьшать функционал? А потом мы удивляемся, что продаются отдельные версии для нормальных ОСей, и отдельные, значительно дороже, для серверных. Но мой софт ориентирован не на мегакластеры, а на десктопы. |
Сообщ.
#8
,
|
|
|
Цитата Qraizer @ продаются отдельные версии для нормальных ОСей, и отдельные, значительно дороже, для серверных. Эм... ну, цену, пожалуй, завышают специально, а не потому что кто-то на скорую руку набросал и ему потом влом было исправить. Но в принципе, тоже верно, исправил |
Сообщ.
#9
,
|
|
|
Цитата Хрен @ В том-то и дело. Если там в натуре какое-то жёсткое отличие, один разговор, а когда вмешивается маркетинг, типа, "давайте пару строк изменим, и якобы специальные серверные версии будет продавать дороже", обидно. Эм... ну, цену, пожалуй, завышают специально, а не потому что кто-то на скорую руку набросал и ему потом влом было исправить. |
Сообщ.
#10
,
|
|
|
Цитата Хрен @ Нет, автора интересуют именно физические диски Искомое можно получить, например, через SetupAPI. Что-то в таком духе (псевдо-код): Напишем небольшую перечислялку, исходя из того, что у нас есть HDEVINFO function SYSTEM_DEVICES_FillClassArrayEx(const hSysDevices: HDEVINFO; CheckGUID: TCheckGUID_CallBack): ULONG; var DeviceInfoData: SP_DEVINFO_DATA; dwIndex: DWORD; begin ...... dwIndex := 0; ZeroMemory(@DeviceInfoData, SizeOf(SP_DEVINFO_DATA)); DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA); while SetupDiEnumDeviceInfo(hSysDevices, dwIndex, DeviceInfoData) do begin // Проверяем нужный ли нам GUID мы получили if CheckGUID(@DeviceInfoData.ClassGuid) then begin // Здесь проверяем был ли у нас уже такой GUID или он встретился первый раз // Если, втречался, то относим все последующее описание деваса к нему же // Получаем "описание" класса SetupDiGetClassDescriptionExW(@DeviceInfoData.ClassGuid, ...); // пытаемся получить "дружественное" имя Result := SetupDiGetDeviceRegistryPropertyW(hSysDevices, DeviceInfoData, SPDRP_FRIENDLYNAME, ...); if Result <> ERROR_SUCCESS then // Если не получилось, берем то какое есть :) Result := SetupDiGetDeviceRegistryPropertyW(hSysDevices, DeviceInfoData, SPDRP_DEVICEDESC, ...); // Ну и имя самого девайса: Result := SetupDiGetDeviceRegistryPropertyW(hSysDevices, DeviceInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, ...); end; Inc(dwIndex); end; end; Ну и вызов этого безобразия будет выглядеть, примерно так: function SYSTEM_DEVICES_FillClassArray(CheckGUID: TCheckGUID_CallBack): ULONG; var hSysDevices: HDEVINFO; Flags: ULONG; begin // Здесь вовсю можно играться с этим флагом :) Flags := DIGCF_ALLCLASSES or DIGCF_DEVICEINTERFACE or DIGCF_PRESENT; hSysDevices := SetupDiGetClassDevsExW(nil, nil, 0, dwFlags, nil, nil, nil); if hSysDevices <> PINVALID_HANDLE_VALUE then try Result := SYSTEM_DEVICES_FillClassArrayEx(hSysDevices, CheckGUID); finally SetupDiDestroyDeviceInfoList(hSysDevices); end else Result := GetLastError; end; В Каллбэке CheckGUID: TCheckGUID_CallBack можно использовать следующие GUID: SysClassGuid_CDROM, SysClassGuid_DiskDrive, SysClassGuid_FloppyDisk Имена собственнолапные, но сами значения GUID можно найти в MSDN Например, для диска он такой: Name: DiskDrive GUID: {4d36e967-e325-11ce-bfc1-08002be10318} Таким макаром удается получить список всех, нужных нам девайсов, установленных в системе. Виртуальные диски типа TrueCrypt сюда не попадают. Их можно попробовать получить, играя с флагом и фильтруемыми GUID или с помощю MountMeneger`а (ZwOpenMountMeneger) |
Сообщ.
#11
,
|
|
|
Riply
Ему нужно на С++ |
Сообщ.
#12
,
|
|
|
Цитата aster_x @ Ему нужно на С++ Данный пример переводится из Delphi на С простой заменой begin`ов на { |
Сообщ.
#13
,
|
|
|
Тогда нужно добавить!
Try Finally ENd; Нужно убрать вообще. |