Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.139.97.157] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Всем привет!
Мне нужно получить имя (прошитый в устройстве идентификатор) физического диска. Не метку логического диска, не GUID, не "\Device\HarddiskVolume1" или т.п. А то, что выдаёт wmic diskdrive list brief в столбцах Caption и Model, например: Generic STORAGE DEVICE USB Device JetFlash Transcend 16GB USB Device ST2000DM006-2DM164 ST31000528AS ST2000DM001-1CH164 PLEXTOR PX-128M6Pro USB DISK 2.0 USB Device PowerShell и т.п. вещи не интересуют, нужно получить программно. Вроде есть вариант через WMI. Но хочется на чистом WinAPI. p.s. Есть ещё вариант через SMART, но это не прокатит с флешками (только харды) + нужны права админа. |
Сообщ.
#2
,
|
|
|
Может как-то так? или так
|
Сообщ.
#3
,
|
|
|
JoeUser, спасибо
Я, правда, сам тоже нашёл: IOCTL_STORAGE_QUERY_PROPERTY. Запрос StorageDeviceProperty, поле ProductIdOffset. Навороченный какой код (второй). Надо посмотреть, что там. Но там, я вижу, тоже есть этот IOCTL_STORAGE_QUERY_PROPERTY. |
Сообщ.
#4
,
|
|
|
Да, автор второго кода - мастер по жести!
switch (*cP) { case '0': i64Id += 0; break; case '1': i64Id += 1; break; case '2': i64Id += 2; break; case '3': i64Id += 3; break; case '4': i64Id += 4; break; case '5': i64Id += 5; break; case '6': i64Id += 6; break; case '7': i64Id += 7; break; case '8': i64Id += 8; break; case '9': i64Id += 9; break; case 'a': case 'A': i64Id += 10; break; case 'b': case 'B': i64Id += 11; break; case 'c': case 'C': i64Id += 12; break; case 'd': case 'D': i64Id += 13; break; case 'e': case 'E': i64Id += 14; break; case 'f': case 'F': i64Id += 15; break; case 'g': case 'G': i64Id += 16; break; case 'h': case 'H': i64Id += 17; break; case 'i': case 'I': i64Id += 18; break; case 'j': case 'J': i64Id += 19; break; case 'k': case 'K': i64Id += 20; break; case 'l': case 'L': i64Id += 21; break; case 'm': case 'M': i64Id += 22; break; case 'n': case 'N': i64Id += 23; break; case 'o': case 'O': i64Id += 24; break; case 'p': case 'P': i64Id += 25; break; case 'q': case 'Q': i64Id += 26; break; case 'r': case 'R': i64Id += 27; break; case 's': case 'S': i64Id += 28; break; case 't': case 'T': i64Id += 29; break; case 'u': case 'U': i64Id += 30; break; case 'v': case 'V': i64Id += 31; break; case 'w': case 'W': i64Id += 32; break; case 'x': case 'X': i64Id += 33; break; case 'y': case 'Y': i64Id += 34; break; case 'z': case 'Z': i64Id += 35; break; } } |
Сообщ.
#5
,
|
|
|
Цитата JoeUser @ Да, автор второго кода - мастер по жести! Начитаются бородатых анекдотов, а потом код пишут... https://www.anekdot.ru/id/-9934695/ |
Сообщ.
#6
,
|
|
|
Давай я облегчу жизъть
#include <windows.h> #include <iostream> #include <iomanip> #include <vector> #include <string> void getDevInfo(HANDLE hDev) { STORAGE_PROPERTY_QUERY inBuf; std::vector<unsigned char> buf; DWORD retSize; // unused inBuf.PropertyId = StorageDeviceProperty; inBuf.QueryType = PropertyStandardQuery; buf.resize(sizeof(STORAGE_DEVICE_DESCRIPTOR)); STORAGE_DEVICE_DESCRIPTOR *outBuf = reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(&buf.front()); outBuf->Version = sizeof(*outBuf); if (DeviceIoControl(hDev, IOCTL_STORAGE_QUERY_PROPERTY, &inBuf, sizeof(inBuf), outBuf, buf.size(), &retSize, NULL) == FALSE) { std::cerr << "DeviceIoControl (1st) failed. Code error is " << GetLastError() << std::endl; return; } buf.resize(outBuf->Size); outBuf = reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(&buf.front()); if (DeviceIoControl(hDev, IOCTL_STORAGE_QUERY_PROPERTY, &inBuf, sizeof(inBuf), outBuf, buf.size(), &retSize, NULL) == FALSE) { std::cerr << "DeviceIoControl (2nd) failed. Code error is " << GetLastError() << std::endl; return; } if (outBuf->VendorIdOffset != 0) std::cout << "Vendor is " << &buf[outBuf->VendorIdOffset] << '\n'; if (outBuf->ProductIdOffset != 0) std::cout << "Product is " << &buf[outBuf->ProductIdOffset] << '\n'; if (outBuf->ProductRevisionOffset != 0) std::cout << "Revision is " << &buf[outBuf->ProductRevisionOffset] << '\n'; if (outBuf->SerialNumberOffset != 0) std::cout << "S/N is " << &buf[outBuf->SerialNumberOffset] << '\n'; std::cout << "\nRawData is:" << '\n'; for (int i = 0; i < outBuf->RawPropertiesLength; ++i) { unsigned byte = static_cast<unsigned>(outBuf->RawDeviceProperties[i]) & 0xFF; std::cout << '[' << i << "]\t" << std::setfill('0') << " (0x" << std::setw(2) << std::hex << std::uppercase << byte << std::setfill(' ') << ") " << std::setw(3) << std::dec << byte << ' ' << outBuf->RawDeviceProperties[i] << '\n'; } std::cout << std::endl; } int main() { for (int i = 0; ; ++i) { std::string nameDev = "\\\\.\\PhysicalDrive" + std::to_string(i); HANDLE hDev = CreateFile(nameDev.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDev == INVALID_HANDLE_VALUE) break; std::cout << nameDev << " info\n" << std::string(nameDev.length() + 5, '=') << '\n'; getDevInfo(hDev); CloseHandle(hDev); } } Добавлено Но вообще как-то мало инфы. Подозреваю, что сюда ещё SMART можно затесать. |
Сообщ.
#7
,
|
|
|
Цитата Qraizer @ Кстати, номера могут иметь дыры.if (hDev == INVALID_HANDLE_VALUE) break; Т.е. запросто могут быть диски 0, 1, 3, 6, допустим. |
Сообщ.
#8
,
|
|
|
Я знаю, ну так это ж пример использования. Основное в getDevInfo(), ибо в ваших примерах как-то многословно всё. И на Сях, что не добавляет ясности.
Я вот не в курсе, как нормально дыры обходить. Только через SetupAPI получить все железки с нужным классом и переэнумить руками. Где-то был похожий код, но другой, там RSы ищутся. Если найду, приложу, там тоже не всё так гладко. |
Сообщ.
#9
,
|
|
|
Цитата Qraizer @ Да, я тоже через SetupAPI только видел. Сегодня ковырял rufus, там так же. Что такое RS'ы?Только через SetupAPI получить все железки с нужным классом и переэнумить руками. Где-то был похожий код, но другой, там RSы ищутся. Если найду, приложу, там тоже не всё так гладко. Я обычно тупо делаю перебор номеров от 0 до 15. Кстати, какое кол-во дисков может быть максимум? |
Сообщ.
#10
,
|
|
|
Цитата Jin X @ COM-порты. Но там и задача была сложнее: нужно было найти конкретный девайс по его COMномеру:, отыскать его родительное устройство, проверить, что оно конкретная USB-шелезяка и выторкнуть/перевоткнуть. Шелезяку, не COM.Что такое RS'ы? Цитата Jin X @ Теоретически олимпиллиард. Вот тут можно посмотреть на дикую смесь C и Плюсов, но он не даст полной инфы. Впрочем, это зависит от того, какие устройства вообще интересуют. Я обычно тупо делаю перебор номеров от 0 до 15. Кстати, какое кол-во дисков может быть максимум? |
Сообщ.
#11
,
|
|
|
Цитата Qraizer @ Там тоже ж SetupAPI.Вот тут можно посмотреть на дикую смесь C и Плюсов, но он не даст полной инфы. Почему не даст? |
Сообщ.
#12
,
|
|
|
Ну а как быть, например, с floppy или cdrom? Разве они не физические? Но я ж написал:
Цитата Qraizer @ Впрочем, это зависит от того, какие устройства вообще интересуют. |
Сообщ.
#13
,
|
|
|
Цитата Qraizer @ CD вообще перечисляются через \\.\CdRomX.Ну а как быть, например, с floppy или cdrom? А floppy есть в списках \\.\PsysicalDriveX ? |
Сообщ.
#14
,
|
|
|
Флешки должны быть. А их дофига воткнуть можно.
|
Сообщ.
#15
,
|
|
|
Jin X, посмотри тут (запусти), может тебе это даст какую-то полезную инфу перед непосредственным опросом устройств.
|