#include "usbinfo.h"
#include <windows.h>
#include <stdio.h>
#include <Shlwapi.h>
#include <conio.h>
extern "C" {
// Declare the C libraries used
#include <setupapi.h> // Must link in setupapi.lib
#include <hidsdi.h> // Must link in hid.lib
}
static /*const*/ GUID GUID_DEVINTERFACE_USB_DEVICE =
{ 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };
TCHAR * GetErrString(TCHAR *str, DWORD errcode)
{
LPVOID lpbuf;
if (FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errcode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpbuf,
0,
NULL
))
{
lstrcpy(str, (LPCWSTR)lpbuf);
LocalFree(lpbuf);
}
return str;
}
char *w2c(char *pcstr, const wchar_t *pwstr, size_t len)
{
int nlength = wcslen(pwstr);
//获取转换后的长度
int nbytes = WideCharToMultiByte(0, // specify the code page used to perform the conversion
0, // no special flags to handle unmapped characters
pwstr, // wide character string to convert
nlength, // the number of wide characters in that string
NULL, // no output buffer given, we just want to know how long it needs to be
0,
NULL, // no replacement character given
NULL); // we don't want to know if a character didn't make it through the translation
// make sure the buffer is big enough for this, making it larger if necessary
if (nbytes > len) nbytes = len;
// 通过以上得到的结果,转换unicode 字符为ascii 字符
WideCharToMultiByte(0, // specify the code page used to perform the conversion
0, // no special flags to handle unmapped characters
pwstr, // wide character string to convert
nlength, // the number of wide characters in that string
pcstr, // put the output ascii characters at the end of the buffer
nbytes, // there is at least this much space there
NULL, // no replacement character given
NULL);
return pcstr;
}
UsbInfo::UsbInfo(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
info = "";
}
UsbInfo::~UsbInfo()
{
}
void UsbInfo::getInfo()
{
char szTraceBuf[256];
// Get device interface info set handle for all devices attached to system
HDEVINFO hDevInfo = SetupDiGetClassDevs(
&GUID_DEVINTERFACE_USB_DEVICE, /* CONST GUID * ClassGuid - USB class GUID */
NULL, /* PCTSTR Enumerator */
NULL, /* HWND hwndParent */
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE /* DWORD Flags */
);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
sprintf(szTraceBuf, "SetupDiClassDevs() failed. GetLastError() " \
"returns: 0x%x\n", GetLastError());
OutputDebugStringA(szTraceBuf);
return ;
}
sprintf(szTraceBuf, "Device info set handle for all devices attached to " \
"system: 0x%x\n", hDevInfo);
OutputDebugStringA(szTraceBuf);
info = QStringLiteral("%1\r\n").arg(szTraceBuf);
// Retrieve a context structure for a device interface of a device
// information set.
DWORD dwIndex = 0;
SP_DEVICE_INTERFACE_DATA devInterfaceData;
ZeroMemory(&devInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA));
devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
BOOL bRet = FALSE;
ULONG neededLength, requiredLength;
PSP_DEVICE_INTERFACE_DETAIL_DATA ClassDeviceData;
HIDD_ATTRIBUTES attributes;
while (TRUE)
{
bRet = SetupDiEnumDeviceInterfaces(
hDevInfo, /* HDEVINFO DeviceInfoSet */
NULL, /* PSP_DEVINFO_DATA DeviceInfoData */
&GUID_DEVINTERFACE_USB_DEVICE, /* CONST GUID * InterfaceClassGuid */
dwIndex,
&devInterfaceData /* PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData */
);
if (!bRet)
{
TCHAR buffer[1024];
TCHAR szTraceBuf[1024];
GetErrString(buffer, GetLastError());
wsprintf(szTraceBuf, L"SetupDiEnumDeviceInterfaces failed msg:%s", buffer);
OutputDebugStringW(szTraceBuf);
if (GetLastError() == ERROR_NO_MORE_ITEMS)
{
break;
}
}
else{
// 发现一个HID设备,获取设备的详细信息
// 第一次调用SetupDiGetDeviceInterfaceDetail得到ClassDeviceData的大小,但返回错误
SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData,
NULL, 0, &requiredLength, NULL);
neededLength = requiredLength;
ClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(neededLength);
ClassDeviceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
//第二次调用SetupDiGetDeviceInterfaceDetail
// 使用 合适的neededLength.
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData,
ClassDeviceData, neededLength, &requiredLength, NULL))
{
free(ClassDeviceData);
SetupDiDestroyDeviceInfoList(hDevInfo);
return ;
}
// 建立HID设备的句柄
HANDLE handle = CreateFile(ClassDeviceData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
// 获取 attributes 以便得到Vendor ID 和 Product ID
HidD_GetAttributes(handle, &attributes);
TCHAR buffer[1024];
wsprintf(buffer, L"name:%s pid=%d vid=%d version=%d \n", ClassDeviceData->DevicePath, attributes.ProductID, attributes.VendorID, attributes.VersionNumber);
OutputDebugStringW(buffer);
CloseHandle(handle);
free(ClassDeviceData);
info = info + QString::fromWCharArray(buffer);
}
dwIndex++;
}
sprintf(szTraceBuf, "Number of device interface sets representing all " \
"devices attached to system: %d\n", dwIndex);
OutputDebugStringA(szTraceBuf);
SetupDiDestroyDeviceInfoList(hDevInfo);
}
void UsbInfo::on_btn_get_clicked()
{
getInfo();
ui.textEdit->append(info);
}
void UsbInfo::on_btn_clear_clicked()
{
ui.textEdit->clear();
}
评论2