USB DevicePath

这段代码展示了如何在Windows环境下使用SetupAPI和设备注册表属性来枚举并获取USB设备及其位置信息,包括设备描述、硬件ID和在Hub中的位置。同时,它还涉及到了HID设备的处理,通过打开设备文件句柄来进一步操作。此外,代码还列举了设备类别的注册表项,用于设备接口的枚举和详细信息获取。
#include <windows.h>
#include <stdio.h>

#include <devguid.h>
#include <Ntddmou.h>
#include <SetupAPI.h>
#pragma comment(lib,"SetupAPI.lib")

#include <string>
#include <vector>
#include <iostream>

DEFINE_GUID(GUID_DEVCLASS_USB, 0x36FC9E60, 0xC465, 0x11CF, 0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
int PrintAllUsbDevicesLocationInfo()
{
	DWORD i;
	HDEVINFO hDevInfo = { 0 };
	TCHAR szDescBuf[MAX_PATH] = { 0 };
	TCHAR szLocationBuf[MAX_PATH] = { 0 };
	TCHAR szHwId[MAX_PATH] = { 0 };
	SP_DEVINFO_DATA DeviceInfoData = { 0 };
	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
	// 得到所有USB设备 HDEVINFO
	// 第一个参数不能设置为GUID_DEVCLASS_USB,因为hid设备类为HIDClass,以及一些其他设备的设备也不一定是USB
	hDevInfo = SetupDiGetClassDevs(NULL, TEXT("USB"), 0, DIGCF_ALLCLASSES | DIGCF_PRESENT);
	if (hDevInfo == INVALID_HANDLE_VALUE)
		return 0;
	int cnt = 0;
	// 循环列举
	for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++)
	{
		if (!SetupDiGetDeviceRegistryProperty(hDevInfo,
			&DeviceInfoData,
			SPDRP_HARDWAREID,
			NULL,
			(PBYTE)szHwId,
			MAX_PATH - 1,
			NULL))
		{
			continue;
		}
		if (!SetupDiGetDeviceRegistryProperty(hDevInfo,
			&DeviceInfoData,
			SPDRP_DEVICEDESC,
			NULL,
			(PBYTE)szDescBuf,
			MAX_PATH - 1,
			NULL))
		{
			continue;
		}
		// 获取设备在Hub中的Port位置
		if (!SetupDiGetDeviceRegistryProperty(hDevInfo,
			&DeviceInfoData,
			SPDRP_LOCATION_INFORMATION,
			NULL,
			(PBYTE)szLocationBuf,
			MAX_PATH - 1,
			NULL))
		{
			continue;
		}
		if (wcsstr(szLocationBuf, L"Port"))
		{
			printf("Desc:%ws\r\n", szDescBuf);
			printf("HardwareId:%ws\r\n", szHwId);
			printf("Location:%ws\r\n\r\n", szLocationBuf);
			cnt++;
		}
	}
	//  释放
	SetupDiDestroyDeviceInfoList(hDevInfo);
	printf("total usb devices num = %d\r\n", cnt);
	return 0;
}

DEFINE_GUID(GUID_DEVCLASS_HID, 0xa5dcbf10L, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed);
DEFINE_GUID(UsbClassGuid, 0xa5dcbf10L, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed);

int main()
{
	HDEVINFO hDevInfo{ 0 };
	SP_DEVICE_INTERFACE_DATA spDevData{ 0 };
	PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail = 0;
	BOOL bRes = TRUE;
	int nCount = 0;
	hDevInfo = ::SetupDiGetClassDevs(&GUID_DEVCLASS_USB, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
	if (hDevInfo != INVALID_HANDLE_VALUE)
	{
		// {D4B491E1-1087-45DD-B377-92EA7E64979C}
		static const GUID ddd = { 0xa5dcbf10L, 0x6530, 0x11d2, { 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed } };

		pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, 1024);
		pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		while (bRes)
		{
			spDevData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
			bRes = ::SetupDiEnumDeviceInterfaces(hDevInfo, NULL, (LPGUID)&ddd, nCount, &spDevData);
			DWORD e = GetLastError();
			if (bRes)
			{
				bRes = ::SetupDiGetInterfaceDeviceDetail(hDevInfo, &spDevData, pDetail, 1024, NULL, NULL);
				if (bRes)
				{
					std::wcout << L"success : " << pDetail->DevicePath << std::endl;

					HANDLE h = CreateFileW(pDetail->DevicePath,//&guidHID_1,//
						GENERIC_READ | GENERIC_WRITE,
						FILE_SHARE_READ | FILE_SHARE_WRITE,
						NULL,
						OPEN_EXISTING,
						FILE_ATTRIBUTE_NORMAL/*|
						FILE_FLAG_OVERLAPPED*/,
						NULL);

					std::cout << "handle is " << (int)h << std::endl;

					nCount++;
				}
			}
		}
		::GlobalFree(pDetail);
		::SetupDiDestroyDeviceInfoList(hDevInfo);
	}

	system("pause");
	return 0;
}

#define GUID_STRING_LEN   (39)
#define MAX_DEVICE_ID_LEN (200) // as defined in cfgmgr32.h

BYTE  BinaryBuffer[4096];
TCHAR DevInstIdBuffer[MAX_DEVICE_ID_LEN];

#define REGSTR_PATH_DEVICE_CLASSES TEXT("System\\CurrentControlSet\\Control\\DeviceClasses")
int mainca(
	IN int   argc,
	IN char* argv[]
)
{
	HDEVINFO hDevInfo;
	DWORD i, j;
	HKEY hKeyDevClassRoot;
	FILETIME LastWriteTime;
	TCHAR InterfaceGuidString[GUID_STRING_LEN];
	WCHAR TempGuidString[GUID_STRING_LEN];
	GUID ClassGuid;
	SP_INTERFACE_DEVICE_DATA InterfaceDeviceData;
	PSP_INTERFACE_DEVICE_DETAIL_DATA InterfaceDeviceDetailData;
	SP_DEVINFO_DATA DeviceInfoData;
	DWORD DataBufferSize;

	hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_INTERFACEDEVICE | DIGCF_DEVICEINTERFACE);

	if (hDevInfo == INVALID_HANDLE_VALUE) {
		wprintf(L"SetupDiGetClassDevs failed with %lx\n", GetLastError());
		return -1;
	}

	HDEVINFO hDevInfo2 = SetupDiCreateDeviceInfoList(0, 0);
	if (hDevInfo2 == INVALID_HANDLE_VALUE)
	{
		printf("SetupDiCreateDeviceInfoList failed\n");
		return -1;
	}

	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
		REGSTR_PATH_DEVICE_CLASSES,
		0,
		KEY_READ,
		&hKeyDevClassRoot) != ERROR_SUCCESS) {
		wprintf(L"Couldn't open DeviceClasses key!\n");
		return -1;
	}

	InterfaceDeviceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
	InterfaceDeviceDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)BinaryBuffer;
	InterfaceDeviceDetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

	for (i = 0, DataBufferSize = GUID_STRING_LEN;
		RegEnumKeyEx(hKeyDevClassRoot,
			i,
			InterfaceGuidString,
			&DataBufferSize,
			NULL,
			NULL,
			NULL,
			&LastWriteTime) == ERROR_SUCCESS;
		i++, DataBufferSize = GUID_STRING_LEN)
	{
		//if (CLSIDFromString(T2OLE(InterfaceGuidString), &ClassGuid) != NOERROR) {
		//	wprintf(L"We couldn't convert %s into a GUID--skip it.\n", T2W(InterfaceGuidString));
		//	continue;
		//}
		//else {
		//	wprintf(L"We're enumerating interface class %s\n", T2W(InterfaceGuidString));
		//}

		for (j = 0;
			SetupDiEnumInterfaceDevice(hDevInfo, NULL, &ClassGuid, j, &InterfaceDeviceData);
			j++)
		{
			StringFromGUID2(InterfaceDeviceData.InterfaceClassGuid, TempGuidString, GUID_STRING_LEN);
			wprintf(L"For class %s, here's one:\n", TempGuidString);

			if (!SetupDiGetInterfaceDeviceDetail(hDevInfo,
				&InterfaceDeviceData,
				InterfaceDeviceDetailData,
				sizeof(BinaryBuffer),
				NULL,
				&DeviceInfoData)) {
				wprintf(L"SetupDiGetInterfaceDeviceDetail failed with %lx\n", GetLastError());
				continue;
			}

			//wprintf(L"     %s (%lx)\n", T2W(InterfaceDeviceDetailData->DevicePath), InterfaceDeviceData.Flags);
			wprintf(L"     (associated device instance is:\n");

			if (!SetupDiGetDeviceInstanceId(hDevInfo,
				&DeviceInfoData,
				DevInstIdBuffer,
				MAX_DEVICE_ID_LEN,
				NULL)) {
				wprintf(L"SetupDiGetDeviceInstanceId failed with %lx\n", GetLastError());
				continue;
			}

			//wprintf(L"    %s\n\n", T2W(DevInstIdBuffer));

			{
				SP_DEVINFO_DATA DevInfoData;
				DevInfoData.cbSize = sizeof(DevInfoData);
				DWORD cbRequiredSize;
				DWORD rgbInterfaceDeviceDetailData[0x1000];
				PSP_INTERFACE_DEVICE_DETAIL_DATA pInterfaceDeviceDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)rgbInterfaceDeviceDetailData;
				pInterfaceDeviceDetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

				BOOL f = SetupDiGetInterfaceDeviceDetail(
					hDevInfo,
					&InterfaceDeviceData,
					pInterfaceDeviceDetailData,
					sizeof(rgbInterfaceDeviceDetailData),
					0,
					&DevInfoData);
				if (!f)
				{
					wprintf(L"SetupDiGetInterfaceDeviceDetail failed\n");
					continue;
				}

				HKEY hkey = SetupDiOpenDevRegKey(
					hDevInfo,
					&DevInfoData,
					DICS_FLAG_GLOBAL,
					0,
					DIREG_DRV,
					KEY_READ);

				if (hkey == INVALID_HANDLE_VALUE) {
					wprintf(L"SetupDiOpenInterfaceDeviceRegKey failed with %lx\n", GetLastError());
					continue;
				}
				RegCloseKey(hkey);

				{
					SP_INTERFACE_DEVICE_DATA InterfaceDeviceData;
					InterfaceDeviceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
					SP_DEVINFO_DATA DevInfoData;
					f = SetupDiOpenInterfaceDevice(
						hDevInfo2,
						InterfaceDeviceDetailData->DevicePath,
						0,
						&InterfaceDeviceData);

					if (!f)
					{
						printf("SetupDiOpenInterfaceDevice failed %08x\n", GetLastError());
						continue;
					}
				}
			}
		}
	}

	SetupDiDestroyDeviceInfoList(hDevInfo);

	printf("now from the saved list\n");

	{
		for (j = 0;
			SetupDiEnumInterfaceDevice(hDevInfo2, NULL, &ClassGuid, j, &InterfaceDeviceData);
			j++)
		{
			StringFromGUID2(InterfaceDeviceData.InterfaceClassGuid, TempGuidString, GUID_STRING_LEN);
			wprintf(L"For class %s, here's one:\n", TempGuidString);

			if (!SetupDiGetInterfaceDeviceDetail(hDevInfo2,
				&InterfaceDeviceData,
				InterfaceDeviceDetailData,
				sizeof(BinaryBuffer),
				NULL,
				&DeviceInfoData)) {
				wprintf(L"SetupDiGetInterfaceDeviceDetail failed with %lx\n", GetLastError());
				continue;
			}

			//wprintf(L"     %s (%lx)\n", T2W(InterfaceDeviceDetailData->DevicePath), InterfaceDeviceData.Flags);
			wprintf(L"     (associated device instance is:\n");

			if (!SetupDiGetDeviceInstanceId(hDevInfo2,
				&DeviceInfoData,
				DevInstIdBuffer,
				MAX_DEVICE_ID_LEN,
				NULL)) {
				wprintf(L"SetupDiGetDeviceInstanceId failed with %lx\n", GetLastError());
				continue;
			}

			//wprintf(L"    %s\n\n", T2W(DevInstIdBuffer));

			{
				SP_DEVINFO_DATA DevInfoData;
				DevInfoData.cbSize = sizeof(DevInfoData);
				DWORD cbRequiredSize;
				DWORD rgbInterfaceDeviceDetailData[0x1000];
				PSP_INTERFACE_DEVICE_DETAIL_DATA pInterfaceDeviceDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)rgbInterfaceDeviceDetailData;
				pInterfaceDeviceDetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

				BOOL f = SetupDiGetInterfaceDeviceDetail(
					hDevInfo2,
					&InterfaceDeviceData,
					pInterfaceDeviceDetailData,
					sizeof(rgbInterfaceDeviceDetailData),
					0,
					&DevInfoData);
				if (!f)
				{
					wprintf(L"SetupDiGetInterfaceDeviceDetail failed\n");
					continue;
				}

				HKEY hkey = SetupDiOpenDevRegKey(
					hDevInfo2,
					&DevInfoData,
					DICS_FLAG_GLOBAL,
					0,
					DIREG_DRV,
					KEY_READ);

				if (hkey == INVALID_HANDLE_VALUE) {
					wprintf(L"SetupDiOpenInterfaceDeviceRegKey failed with %lx\n", GetLastError());
					continue;
				}
				RegCloseKey(hkey);
			}
		}
	}

	SetupDiDestroyDeviceInfoList(hDevInfo2);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值