Неверный дескриптор при вызове IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER - PullRequest
0 голосов
/ 21 марта 2012

У кого-нибудь есть опыт вызовов IOCTL на c / c ++? В основном я пытаюсь определить, к какому порту подключен USB-накопитель. У меня есть вся информация USB и объем информации. Очевидно, чтобы связать эти 2 блока информации, мне нужен либо ключ драйвера, либо серийный номер. Однако при вызове DeviceIoControl я получаю неверный дескриптор как «код последней ошибки»

Мой диск USB-накопитель подключен к каталогу в c: \ (не буква диска). См. Ниже

//get a handle on the volume
HANDLE hVolume;
DWORD dwAccessFlags;

dwAccessFlags = GENERIC_READ | GENERIC_WRITE;  

hVolume = CreateFile(L"C:\_USB\MP1",
    dwAccessFlags,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    0,
    NULL );
if (hVolume == INVALID_HANDLE_VALUE) {
    printf("Invalid Handle");
}

//use the handle
MEDIA_SERIAL_NUMBER_DATA* pserialNumberData = new MEDIA_SERIAL_NUMBER_DATA;
wstring result;
//HANDLE hVolume = OpenVolume(vname.substr(0, vname.length() - 1).c_str());
DWORD   bytesReturned = 0;
LPDWORD lpBytesReturned = &bytesReturned;

OVERLAPPED over;
LPOVERLAPPED lpOver = &over;
BOOL success = 1;
success = DeviceIoControl(
    (HANDLE) hVolume,                      // handle to device
     IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, // dwIoControlCode
     NULL,                                  // lpInBuffer
     0,                                     // nInBufferSize
    (LPVOID) pserialNumberData,                  // output buffer
    (DWORD) sizeof(MEDIA_SERIAL_NUMBER_DATA),                       // size of output buffer
    (LPDWORD) lpBytesReturned,             // number of bytes returned
    (LPOVERLAPPED) lpOver            // OVERLAPPED structure
    );
wcout << L"--> GetSn() DeviceIoControl success " << success << endl;
wcout << L"--> GetSn() DeviceIoControl Last error number " << GetLastError() << endl;
wcout << L"--> GetSn() DeviceIoControl Bytes Returned " << bytesReturned << endl;
wcout << L"--> GetSn() DeviceIoControl struct size " << sizeof(MEDIA_SERIAL_NUMBER_DATA) << endl;

Ответы [ 3 ]

2 голосов
/ 21 марта 2012

Если вы посмотрите на раздел «Примечания» для функции DeviceIoControl , там написано:

Чтобы получить дескриптор устройства, вы должны вызвать функцию CreateFile слибо имя устройства, либо имя драйвера, связанного с устройством.Чтобы указать имя устройства, используйте следующий формат:
\\.\DeviceName

DeviceIoControl может принимать дескриптор для определенного устройства.Например, чтобы открыть дескриптор логического диска A: с помощью CreateFile укажите \\.\a:.Кроме того, вы можете использовать имена \\.\PhysicalDrive0, \\.\PhysicalDrive1 и т. Д., Чтобы открывать дескрипторы физических дисков в системе.

Вы не открываете дескриптор устройства, и, следовательно, DeviceIoControlне будет работать для этого случая.

1 голос
/ 14 июня 2012

Первая большая проблема, которую я вижу, заключается в том, что функция CreateFile должна вызываться с флагом FILE_FLAG_BACKUP_SEMANTICS, чтобы получить действительный дескриптор каталога.Итак, для начала попробуйте:

hVolume = CreateFile( L"C:\_USB\MP1",  
                      dwAccessFlags,  
                      FILE_SHARE_READ | FILE_SHARE_WRITE,  
                      NULL,  
                      OPEN_EXISTING,  
                      FILE_FLAG_BACKUP_SEMANTICS,  
                      NULL );
0 голосов
/ 21 марта 2012

Хммм ... Я думаю, что дескриптор, который вы получаете от CreateFile - это дескриптор каталога, к которому вы подключили диск, а не сам диск. Чтобы быть уверенным, что вы получите дескриптор нужного устройства, вы должны использовать путь к устройству, например, \\.\Device\HarddiskVolume1. WinObj или DeviceTree , вероятно, может помочь вам найти путь к USB-накопителю.

...