调用IOCTLSTORAGE_GET_MEDIA_SERIAL_NUMBER时句柄无效

Invalid handle when calling IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER

本文关键字:句柄 NUMBER 无效 MEDIA IOCTLSTORAGE GET 调用 SERIAL      更新时间:2023-10-16

有人有c/c++IOCTL调用的经验吗?基本上,我试图确定USB记忆棒插入的端口。我有所有的USB信息和音量信息。为了链接这两个信息块,我需要驱动程序密钥或序列号。然而,当调用DeviceIoControl时,我得到了无效的句柄作为"最后一个错误代码"

我的驱动器USB驱动器安装到c:\中的目录(不是驱动器号)请参阅下面的

//get a handle on the volume
HANDLE hVolume;
DWORD dwAccessFlags;
dwAccessFlags = GENERIC_READ | GENERIC_WRITE;  
hVolume = CreateFile(L"C:_USBMP1",
    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;

如果查看DeviceIoControl函数的备注部分,它会显示:

要检索设备的句柄,必须使用设备名称或与设备关联的驱动程序名称调用CreateFile函数。要指定设备名称,请使用以下格式:
\.DeviceName

DeviceIoControl可以接受特定设备的句柄。例如,要打开逻辑驱动器a的句柄:使用CreateFile,请指定\.a:。或者,可以使用名称\.PhysicalDrive0\.PhysicalDrive1等打开系统上物理驱动器的句柄。

您没有打开设备句柄,因此DeviceIoControl在这种情况下不起作用。

我看到的第一个大问题是,必须使用FILE_FLAG_BACKUP_SEMANTICS标志调用CreateFile函数,才能获得目录的有效句柄。因此,对于初学者来说,请尝试:

hVolume = CreateFile( L"C:_USBMP1",  
                      dwAccessFlags,  
                      FILE_SHARE_READ | FILE_SHARE_WRITE,  
                      NULL,  
                      OPEN_EXISTING,  
                      FILE_FLAG_BACKUP_SEMANTICS,  
                      NULL );

嗯。。。我认为从CreateFile获得的句柄是安装驱动器的目录的句柄,而不是驱动器本身。为了确保获得所需设备的句柄,您应该使用设备路径,例如\.DeviceHarddiskVolume1。WinObj或DeviceTree可能会帮助您找到usb驱动器的路径。