我正在尝试使用SetupDiGetDeviceInterfaceDetail()函数获取设备的路径,但每次调用它时它都会崩溃。我一直在研究这个问题超过12个小时,但仍然无法找出它有什么问题...有人能看出他们是否能找到导致这种情况发生的原因?下面是代码:
//DeviceManager.h
#include <windows.h>
//#include <hidsdi.h>
#include <setupapi.h>
#include <iostream>
#include <cfgmgr32.h>
#include <tchar.h>
#include <devpkey.h>
#include <string>
extern "C"{
#include <hidsdi.h>
}
//#pragma comment (lib, "setupapi.lib")
class DeviceManager
{
public:
DeviceManager();
~DeviceManager();
void ListAllDevices();
void GetDeviceHandler();
//HANDLE PSMove;
//byte reportBuffer[57];
GUID guid;
//private:
HDEVINFO deviceInfoSet; //A list of all the devices
SP_DEVINFO_DATA deviceInfoData; //A device from deviceInfoSet
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailedData;
};
//DeviceManager.cpp
#include"DeviceManager.h"
DeviceManager::DeviceManager()
{
//deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA;
//deviceInterfaceDetailedData = new SP_DEVICE_INTERFACE_DETAIL_DATA;
HidD_GetHidGuid(&guid);
deviceInfoSet = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); //Gets all Devices
GetDeviceHandler();
}
DeviceManager::~DeviceManager()
{
}
void DeviceManager::ListAllDevices()
{
DWORD deviceIndex = 0;
deviceInfoData.cbSize = sizeof(deviceInfoData);
while(SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, &deviceInfoData))
{
deviceInfoData.cbSize = sizeof(deviceInfoData);
ULONG tcharSize;
CM_Get_Device_ID_Size(&tcharSize, deviceInfoData.DevInst, 0);
TCHAR* deviceIDBuffer = new TCHAR[tcharSize]; //the device ID will be stored in this array, so the tcharSize needs to be big enough to hold all the info.
//Or we can use MAX_DEVICE_ID_LEN, which is 200
CM_Get_Device_ID(deviceInfoData.DevInst, deviceIDBuffer, MAX_PATH, 0); //gets the devices ID - a long string that looks like a file path.
std::cout << deviceIDBuffer << std::endl;
deviceIndex++;
}
}
void DeviceManager::GetDeviceHandler()
{
DWORD deviceIndex = 0;
SP_DEVINFO_DATA deviceInfoData;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailedData;
deviceInfoData.cbSize = sizeof(deviceInfoData);
while(SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, &deviceInfoData))
{
TCHAR deviceID[MAX_DEVICE_ID_LEN];
CM_Get_Device_ID(deviceInfoData.DevInst, deviceID, MAX_DEVICE_ID_LEN, 0);
//std::cout << deviceID << std::endl;
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if(SetupDiEnumDeviceInterfaces(deviceInfoSet, &deviceInfoData, &guid, 0, &deviceInterfaceData))
{
DWORD bufferLength = 0;
//deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
deviceInterfaceData.cbSize = 2048;
//std::cout << "it works not" << std::endl;
if(SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &bufferLength, NULL))
{
//deviceInterfaceData.cbSize = sizeof(bufferLength);
std::cout << "It works!" << std::endl;
}
else
{
std::cout << GetLastError() << std::endl;
}
}
else
{
//std::cout << GetLastError() << std::endl;
}
deviceIndex++;
}
}
//mainapp.cpp
#pragma once
int main()
{
DeviceManager deviceManager;
return 0;
}
在DeviceManager的GetDeviceHandler()函数中调用SetupDiGetDeviceInterfaceDetail函数。
请帮忙。感谢。
更新:我发现它在第一个SetupDiGetDeviceInterfaceDetail失败并返回122错误(ERROR_INSUFFICIENT_BUFFER)。但我只是想获得所需的缓冲区大小,所以这怎么可能?
更新2:对,我已经通过将deviceInterfaceData.cbsize设置为2048(用于测试目的的巨大空间)稍微更改了函数(参见上面的代码),现在我得到了一个ERROR_INVALID_PARAMETER。这变得越来越混乱......我给出的参数如何无效?只是没有意义。唯一的区别是我通过引用而不是指针,否则我将得到访问冲突错误...
答案 0 :(得分:2)
找到这个主题之后,我想分享一下我使用完全相同的来源的问题,我从通话中得到了ERROR_INVALID_USER_BUFFER。
原因是这一行:
deviceInterfaceDetailedData->cbSize =
sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
在我的四字节对齐编译器上设置值8而不是所需的值5。
答案 1 :(得分:1)
这是根据MSDN定义:
获取所需的缓冲区大小。使用NULLDeviceInterfaceDetailData指针,一个零的DeviceInterfaceDetailDataSize和一个有效的RequiredSize变量调用SetupDiGetDeviceInterfaceDetail。 响应此类调用,此函数返回RequiredSize所需的缓冲区大小,并因GetLastError返回ERROR_INSUFFICIENT_BUFFER而失败。
因此,在ERROR_INSUFFICIENT_BUFFER错误之后只需使用requiredSize值。
答案 2 :(得分:1)
您没有为SP_DEVICE_INTERFACE_DETAIL_DATA
正确分配内存。
删除SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailedData;
并尝试将其放入if
块中:
// Get the required bufferLength
SetupDiGetDeviceInterfaceDetail(deviceInfoSet,
&deviceInterfaceData,
nullptr,
0,
&bufferLength,
nullptr);
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
std::cout << "Failed to get bufferLength. Error "
<< GetLastError() << '\n';
return;
}
// Create device interface detailed information struct pointer
// and allocate memory to it.
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailedData(nullptr);
deviceInterfaceDetailedData =
static_cast<PSP_INTERFACE_DEVICE_DETAIL_DATA>(malloc(bufferLength));
if(deviceInterfaceDetailedData == nullptr)
{
std::cout << "Failed to allocate memory. Error "
<< GetLastError() << '\n';
return;
}
deviceInterfaceDetailedData->cbSize =
sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
// Get detailed information
if(SetupDiGetDeviceInterfaceDetail(deviceInfoSet,
&deviceInterfaceData,
deviceInterfaceDetailedData,
bufferLength,
&bufferLength,
nullptr))
{
//deviceInterfaceData.cbSize = sizeof(bufferLength);
std::cout << "It works!" << std::endl;
}
else
{
std::cout << GetLastError() << std::endl;
}
free(deviceInterfaceDetailedData);
我没有查看剩下的代码,它也可能有错误,但这可以回答你原来的问题。