Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 调用IOCTL\u存储\u获取\u媒体\u序列号时句柄无效_C++_Windows_Ioctl - Fatal编程技术网

C++ 调用IOCTL\u存储\u获取\u媒体\u序列号时句柄无效

C++ 调用IOCTL\u存储\u获取\u媒体\u序列号时句柄无效,c++,windows,ioctl,C++,Windows,Ioctl,有没有人有过c/c++IOCTL调用的经验? 基本上,我试图确定USB记忆棒插入的端口。 我有所有的USB信息和音量信息。显然,要链接这两个信息块,我需要驾驶员钥匙或序列号。 然而,当调用DeviceIoControl时,我得到了无效的句柄作为“最后一个错误代码” 我的驱动器USB驱动器安装在c:\(不是驱动器号)目录中,请参见下文 //get a handle on the volume HANDLE hVolume; DWORD dwAccessFlags; dwAccessFlags =

有没有人有过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:\_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;
//获取卷的句柄
手柄体积;
德沃德·德沃兹;
dwAccessFlags=通用_读取|通用_写入;
hVolume=CreateFile(L“C:\\ U USB\MP1”,
德国国旗,
文件共享读取文件共享写入,
无效的
开放式,
0,
无效);
if(hVolume==无效的句柄值){
printf(“无效句柄”);
}
//用把手
媒体序列号数据*pserialNumberData=新媒体序列号数据;
结果;
//HANDLE hVolume=OpenVolume(vname.substr(0,vname.length()-1.c_str());
DWORD字节返回=0;
LPDWORD lpBytesReturned=&bytesReturned;
重叠;
lpoverlappled lpOver=&over;
布尔成功=1;
成功=设备控制(
(HANDLE)hVolume,//句柄到设备
IOCTL\u存储\u获取\u媒体\u序列号,//dwIoControlCode
NULL,//lpInBuffer
0,//nInBufferSize
(LPVOID)pSerialNumber数据,//输出缓冲区
(DWORD)sizeof(媒体\u序列号\u数据),//输出缓冲区的大小
(LPDWORD)lpBytesReturned,//返回的字节数
(LPOVERLAPPED)lpOver//重叠结构
);

wcoutHmmm。。。我认为您从CreateFile获得的句柄是您将驱动器装载到的目录的句柄,而不是驱动器本身。为确保获得所需设备的句柄,应使用设备路径,例如
\\.\device\HarddiskVolume1
。或者可以帮助您找到usb驱动器的路径。

Hmmm。。。我认为您从CreateFile获得的句柄是您将驱动器装载到的目录的句柄,而不是驱动器本身。为确保获得所需设备的句柄,应使用设备路径,例如
\\.\device\HarddiskVolume1
。或者可以帮助您找到usb驱动器的路径。

如果您查看功能的备注部分,它会显示:

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

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


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

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

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

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


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

我看到的第一个大问题是,必须使用FILE_标志\u BACKUP_语义标志调用CreateFile函数,才能获得目录的有效句柄。因此,首先,请尝试:

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

我看到的第一个大问题是,必须使用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 );

为什么不必要的bug到处都是?C风格的演员!为什么要调用
new
获取
MEDIA\u SERIAL\u NUMBER\u DATA
结构?谢谢比利,实际上我需要所有能得到的帮助。我是一名Java开发人员,这东西很吓人!!:-)理想情况下,我也想为此编写单元测试,但我猜这是不可能的。为什么不必要的错误到处都隐藏?C风格的演员!为什么要调用
new
获取
MEDIA\u SERIAL\u NUMBER\u DATA
结构?谢谢比利,实际上我需要所有能得到的帮助。我是一名Java开发人员,这东西很吓人!!:-)理想情况下,我也想为此编写单元测试,但我猜这是不可能的。硬盘卷1不是一个设备,它是一个卷。您必须对物理设备句柄进行调用,例如
\\.\PhysicalDrive0
,如
DeviceIoControl
文档中所示。我只是提供了一个设备路径的示例。HarddiskVolume1不是一个设备,而是一个卷。您必须对物理设备句柄进行调用,例如
\\.\PhysicalDrive0
,如
DeviceIoControl
文档中所示。我只是提供了一个设备路径的示例。