SetupDiGetDeviceInterfaceDetail

本文介绍如何使用SetupDiGetDeviceInterfaceDetail函数获取设备接口的详细信息。通常需要两步:先获取所需缓冲区大小,再分配缓冲区并获取接口详情。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SetupDiGetDeviceInterfaceDetail

该函数返回设备接口的详细信息。

BOOL SetupDiGetDeviceInterfaceDetail(
  _In_       HDEVINFO                         DeviceInfoSet,
  _In_       PSP_DEVICE_INTERFACE_DATA        DeviceInterfaceData,
  _Out_opt_  PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
  _In_       DWORD                            DeviceInterfaceDetailDataSize,
  _Out_opt_  PDWORD                           RequiredSize,
  _Out_opt_  PSP_DEVINFO_DATA                 DeviceInfoData
);

参数

  • DeviceInfoSet
      指向设备信息集的指针,它包含了所要接收信息的接口。该句柄通常由SetupDiGetClassDevs函数返回。
  • DeviceInterfaceData
      一个指向 SP_DEVICE_INTERFACE_DATA结构的指针,该结构指定了 DeviceInfoSet 参数中设备的接口。这个类型的指针通常由 SetupDiEnumDeviceInterfaces 函数返回。
  • DeviceInterfaceDetailData
      一个指向SP_DEVICE_INTERFACE_DETAIL_DATA结构的指针,该结构用于接收指定接口的信息。该参数是可选的且可以为NULL。如果DeviceInterfaceDetailSize 参数为0,该参数必须为NULL。如果该参数被指定,主调者必须在调用该函数之前,设置 SP_DEVICE_INTERFACE_DETAIL_DATA 结构的 cbSize 成员为 sizeof(SP_DEVICE_INTERFAC_DETAIL_DATA)。cbSize 成员总是包含数据结构的固定部分的长度。
  • DeviceInterfaceDetailDataSize
     DeviceInterfaceDetailData 参数指定的缓冲的大小。该缓冲的大小不能小于 (offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA, DevicePath) + sizeof(TCHAR)) 字节。
    如果 DeviceInterfaceDetailData 参数为NULL,该参数必须为0.
  • RequiredSize
      一个指向变量的指针,该变量接收请求的 DeviceInterfaceDetailData 缓冲的大小。这个大小包含了结构的固定部分的大小再加上设备路径字符串的长度。该参数是可选的,也可以是NULL。
  • DeviceInfoData
      一个指向缓冲的指针,该缓冲接收关于支持请求的接口的设备的信息。主调者必须设置 DeviceInfoData.cbSize 成员为 sizeof(SP_DEVINFO_DATA)。该参数是可选的,也可以为NULL。

返回值

如果函数顺利完成,则返回TRUE,如果有错误,则返回FALSE。

备注

使用该函数来获得接口的细节,通常需要两个步骤:
1、获得请求的缓冲大小。
  调用SetupDiGetDeviceInterfaceDetail,并指定参数DeviceInterfaceDetailData = NULL,DeviceInterfaceDetailDataSize = 0, 以及一个有效的 RequiredSize 变量。调用之后函数会返回失败,并且在 RequiredSize中返回所需的缓冲区大小,通过调用GetLastError可以获取到ERROR_INSUFFICIENT_BUFFER。

2、分配一个合适的缓冲并再次调用函数来获得接口细节。
  由该函数返回的接口细节包括设备路径。不要试图解析设备路径符号名字。设备路径可以跨系统重用。该函数可以被用来获得DeviceInfoData。如果接口存在,但DeviceInterfaceDetailData 为NULL,该函数会失败。

要求

Versions: The SetupDiGetDeviceInterfaceDetail function is available in Microsoft Windows 2000 and later versions of Windows.

Headers: Declared in Setupapi.h. Include Setupapi.h.

Library: Contained in Setupapi.lib. Link to Setupapi.lib.

BOOL CKbdLEDDlg::GetKeyboardDevicePath(void) { HDEVINFO hDevInfo; DWORD dwIndex; ULONG nLen; DWORD dwSize; DWORD dwRegType; char *pszName; char cDevicePath[DEVICEPATHNAME_MAX]; char cClass[128]; GUID KeyboardGuid; SP_DEVICE_INTERFACE_DATA sDeviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceDetailData; SP_DEVINFO_DATA sDevInfo; KeyboardGuid = GUID_DEVINTERFACE_KEYBOARD; hDevInfo = SetupDiGetClassDevs(&KeyboardGuid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hDevInfo == INVALID_HANDLE_VALUE) { return TRUE; } dwIndex = 0; ZeroMemory(&sDeviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA)); sDeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); while (1) { if (SetupDiEnumDeviceInterfaces(hDevInfo, 0, &KeyboardGuid, dwIndex++, &sDeviceInterfaceData) == FALSE) { break; } nLen = 0; //詳細情報サイズを取得 SetupDiGetDeviceInterfaceDetail(hDevInfo, &sDeviceInterfaceData, NULL, 0, &nLen, NULL); pDeviceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + sizeof(TCHAR) * nLen); if (pDeviceDetailData == NULL) { SetupDiDestroyDeviceInfoList(hDevInfo); return TRUE; } pDeviceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); ZeroMemory(&sDevInfo, sizeof(SP_DEVINFO_DATA)); sDevInfo.cbSize = sizeof(SP_DEVINFO_DATA); //詳細情報を取得 if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &sDeviceInterfaceData, pDeviceDetailData, nLen, &nLen, &sDevInfo) == FALSE) { free(pDeviceDetailData); return TRUE; } strcpy_s(cDevicePath, pDeviceDetailData->DevicePath); free(pDeviceDetailData); dwSize = 0; SetupDiGetDeviceRegistryProperty(hDevInfo, &sDevInfo, SPDRP_CLASS, &dwRegType, NULL, 0, &dwSize); pszName = (char *)malloc(sizeof(char) * dwSize); if (pszName == NULL) { SetupDiDestroyDeviceInfoList(hDevInfo); return TRUE; } if (SetupDiGetDeviceRegistryProperty(hDevInfo, &sDevInfo, SPDRP_CLASS, &dwRegType, (BYTE*)pszName, dwSize, &dwSize) == FALSE) { free(pszName); continue; } strcpy_s(cClass, pszName); free(pszName); if (!strcmp(cClass, "Keyboard")) { strcpy_s(cKeyboardDevicePath[nKeyboardCount], cDevicePath); nKeyboardCount++; } } SetupDiDestroyDeviceInfoList(hDevInfo); return FALSE; }每一行代码都要给出详细的解释,解释的详细一些,并且对所包含的知识点进行拓展
03-08
BOOL CKbdLEDDlg::GetKeyboardDevicePath(void) { HDEVINFO hDevInfo; DWORD dwIndex; ULONG nLen; DWORD dwSize; DWORD dwRegType; char *pszName; char cDevicePath[DEVICEPATHNAME_MAX]; char cClass[128]; GUID KeyboardGuid; SP_DEVICE_INTERFACE_DATA sDeviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceDetailData; SP_DEVINFO_DATA sDevInfo; KeyboardGuid = GUID_DEVINTERFACE_KEYBOARD; hDevInfo = SetupDiGetClassDevs(&KeyboardGuid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hDevInfo == INVALID_HANDLE_VALUE) { return TRUE; } dwIndex = 0; ZeroMemory(&sDeviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA)); sDeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); while (1) { if (SetupDiEnumDeviceInterfaces(hDevInfo, 0, &KeyboardGuid, dwIndex++, &sDeviceInterfaceData) == FALSE) { break; } nLen = 0; //詳細情報サイズを取得 SetupDiGetDeviceInterfaceDetail(hDevInfo, &sDeviceInterfaceData, NULL, 0, &nLen, NULL); pDeviceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + sizeof(TCHAR) * nLen); if (pDeviceDetailData == NULL) { SetupDiDestroyDeviceInfoList(hDevInfo); return TRUE; } pDeviceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); ZeroMemory(&sDevInfo, sizeof(SP_DEVINFO_DATA)); sDevInfo.cbSize = sizeof(SP_DEVINFO_DATA); //詳細情報を取得 if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &sDeviceInterfaceData, pDeviceDetailData, nLen, &nLen, &sDevInfo) == FALSE) { free(pDeviceDetailData); return TRUE; } strcpy_s(cDevicePath, pDeviceDetailData->DevicePath); free(pDeviceDetailData); dwSize = 0; SetupDiGetDeviceRegistryProperty(hDevInfo, &sDevInfo, SPDRP_CLASS, &dwRegType, NULL, 0, &dwSize); pszName = (char *)malloc(sizeof(char) * dwSize); if (pszName == NULL) { SetupDiDestroyDeviceInfoList(hDevInfo); return TRUE; } if (SetupDiGetDeviceRegistryProperty(hDevInfo, &sDevInfo, SPDRP_CLASS, &dwRegType, (BYTE*)pszName, dwSize, &dwSize) == FALSE) { free(pszName); continue; } strcpy_s(cClass, pszName); free(pszName); if (!strcmp(cClass, "Keyboard")) { strcpy_s(cKeyboardDevicePath[nKeyboardCount], cDevicePath); nKeyboardCount++; } } SetupDiDestroyDeviceInfoList(hDevInfo); return FALSE; }
03-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值