2012-03-21 85 views
0

任何人都有c/C++ IOCTL调用的经验吗? 基本上我试图确定一个USB记忆棒插入什么端口。 我有所有的USB信息和音量信息。可以链接这两个信息块,我需要驱动程序密钥或序列号。 但是打电话时的DeviceIoControl我越来越无效的句柄“最后的错误代码”安装目录在C调用IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER时出现无效句柄

我的驱动器的USB驱动器:\(不是驱动器号)请参见下面

//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; 
+1

为什么无用的错误隐藏在所有地方都投了? C风格在那!为什么要调用'new'来获得'MEDIA_SERIAL_NUMBER_DATA'结构? – 2012-03-21 16:42:07

+0

谢谢比利,其实我需要我能得到的所有帮助。我是一个Java开发人员,这个东西很可怕! :-)理想情况下,我也想为此编写单元测试,但我猜这是不可能的。 – Derek 2012-03-21 21:18:51

回答

0

嗯...我认为你从CreateFile得到的句柄是你把驱动器挂载到的目录的句柄,而不是驱动器本身。为确保获得所需设备的句柄,您应该使用设备路径,例如\\.\Device\HarddiskVolume1WinObjDeviceTree可能可以帮助您找到USB驱动器的路径。

+1

HarddiskVolume1不是设备,它是一个卷。您必须按照'DeviceIoControl'文档中指出的那样对物理设备句柄进行调用,例如'\\。\ PhysicalDrive0'。 – 2012-03-21 16:45:59

+0

我只是提供了一个设备路径的例子。 – Camford 2012-03-21 17:24:32

+0

但它不是一个设备路径。这是我的全部观点。 – 2012-03-21 19:13:50

2

如果你看一下在DeviceIoControl功能备注部分,它说:

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

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

您不打开设备句柄,因此DeviceIoControl不适用于这种情况。

1

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

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