What typedef BOOL (WINAPI *FN_SetupDiGetDeviceProperty)?
What typedef BOOL (WINAPI *FN_SetupDiGetDeviceProperty)?
我在这里找到了一些代码,列出了计算机上的所有USB设备。代码如下:
#include <windows.h>
#include <devguid.h> // for GUID_DEVCLASS_CDROM etc
#include <setupapi.h>
#include <cfgmgr32.h> // for MAX_DEVICE_ID_LEN, CM_Get_Parent and CM_Get_Device_ID
#define INITGUID
#include "c:WinDDK7600.16385.1incapidevpkey.h"
#include <tchar.h>
#include <stdio.h>
#include <iostream>
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
#pragma comment (lib, "setupapi.lib")
typedef BOOL (WINAPI *FN_SetupDiGetDeviceProperty)(
__in HDEVINFO DeviceInfoSet,
__in PSP_DEVINFO_DATA DeviceInfoData,
__in const DEVPROPKEY *PropertyKey,
__out DEVPROPTYPE *PropertyType,
__out_opt PBYTE PropertyBuffer,
__in DWORD PropertyBufferSize,
__out_opt PDWORD RequiredSize,
__in DWORD Flags
);
// List all USB devices with some additional information
void ListUsbDevices(void)
{
unsigned i, j;
DWORD dwSize, dwPropertyRegDataType;
DEVPROPTYPE ulPropertyType;
OSVERSIONINFO osvi;
CONFIGRET r;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
const static LPCTSTR arPrefix[3] = {TEXT("VID_"), TEXT("PID_"), TEXT("MI_")};
TCHAR szDeviceInstanceID [MAX_DEVICE_ID_LEN];
TCHAR szDesc[1024];
LPTSTR pszToken, pszNextToken;
TCHAR szVid[MAX_DEVICE_ID_LEN], szPid[MAX_DEVICE_ID_LEN], szMi[MAX_DEVICE_ID_LEN];
#ifdef UNICODE
FN_SetupDiGetDeviceProperty fn_SetupDiGetDeviceProperty = (FN_SetupDiGetDeviceProperty)
GetProcAddress (GetModuleHandle (TEXT("Setupapi.dll")), "SetupDiGetDevicePropertyW");
#else
FN_SetupDiGetDeviceProperty fn_SetupDiGetDeviceProperty = (FN_SetupDiGetDeviceProperty)
GetProcAddress(GetModuleHandle(TEXT("Setupapi.dll")), "SetupDiGetDevicePropertyA");
#endif
// List all connected USB devices
hDevInfo = SetupDiGetClassDevs (NULL, TEXT("USB"), NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
if (hDevInfo == INVALID_HANDLE_VALUE)
return;
// Find the ones that are driverless
for (i = 0; ; i++) {
DeviceInfoData.cbSize = sizeof (DeviceInfoData);
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData))
break;
r = CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID , MAX_PATH, 0);
if (r != CR_SUCCESS)
continue;
_tprintf (TEXT("%sn"), szDeviceInstanceID );
if (SetupDiGetDeviceRegistryProperty (hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC,
&dwPropertyRegDataType, (BYTE*)szDesc,
sizeof(szDesc), // The size, in bytes
&dwSize))
_tprintf (TEXT(" Device Description: "%s"n"), szDesc);
// Retreive the device description as reported by the device itself
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if ( (GetVersionEx(&osvi) != 0)
&& (osvi.dwBuildNumber >= 7000) ) {
// On Vista and earlier, we can use only SPDRP_DEVICEDESC
// On Windows 7, the information we want ("Bus reported device description") is
// accessed through DEVPKEY_Device_BusReportedDeviceDesc
if (fn_SetupDiGetDeviceProperty && fn_SetupDiGetDeviceProperty (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_BusReportedDeviceDesc,
&ulPropertyType, (BYTE*)szDesc, sizeof(szDesc), &dwSize, 0))
_tprintf (TEXT(" Bus Reported Device Description: "%s"n"), szDesc);
}
pszToken = _tcstok_s (szDeviceInstanceID , TEXT("\#&"), &pszNextToken);
while(pszToken != NULL)
{
szVid[0] = TEXT(' ');
szPid[0] = TEXT(' ');
szMi[0] = TEXT(' ');
for (j = 0; j < 3; j++) {
if (_tcsncmp(pszToken, arPrefix[j], lstrlen(arPrefix[j])) == 0) {
switch(j) {
case 0:
_tcscpy_s(szVid, ARRAY_SIZE(szVid), pszToken);
break;
case 1:
_tcscpy_s(szPid, ARRAY_SIZE(szPid), pszToken);
break;
case 2:
_tcscpy_s(szMi, ARRAY_SIZE(szMi), pszToken);
break;
default:
break;
}
}
}
if (szVid[0] != TEXT(' '))
_tprintf (TEXT(" vid: "%s"n"), szVid);
if (szPid[0] != TEXT(' '))
_tprintf (TEXT(" pid: "%s"n"), szPid);
if (szMi[0] != TEXT(' '))
_tprintf (TEXT(" mi: "%s"n"), szMi);
pszToken = _tcstok_s (NULL, TEXT("\#&"), &pszNextToken);
//VID and PID for the playstation Move.
if( szVid[4] == TEXT('8') &&
szVid[5] == TEXT('8') &&
szVid[6] == TEXT('8') &&
szVid[7] == TEXT('8') &&
szPid[4] == TEXT('0') &&
szPid[5] == TEXT('3') &&
szPid[6] == TEXT('0') &&
szPid[7] == TEXT('8'))
{
std::cout << "PlayStation Move Detected!" << std::endl;
break;
}
}
}
return;
}
int main()
{
int iQuit;
ListUsbDevices();
std::cin >> iQuit;
return 0;
}
为什么我们需要先定义FN_SetupDiGetDeviceProperty代码块?它到底是做什么的?我认为SetupDiGetDeviceProperty函数是WDK的一部分,因此我们可以立即使用它?
typedef BOOL (WINAPI *FN_SetupDiGetDeviceProperty)(
__in HDEVINFO DeviceInfoSet,
__in PSP_DEVINFO_DATA DeviceInfoData,
__in const DEVPROPKEY *PropertyKey,
__out DEVPROPTYPE *PropertyType,
__out_opt PBYTE PropertyBuffer,
__in DWORD PropertyBufferSize,
__out_opt PDWORD RequiredSize,
__in DWORD Flags
);
上面的代码将FN_SetupDiGetDeviceProperty
定义为指向函数的指针,该函数采用该(长)参数列表并返回BOOL
。 WINAPI
是一个宏,指定函数的调用约定(__stdcall
、__cdecl
等)。
稍后在代码中,函数指针fn_SetupDiGetDeviceProperty
将有条件地设置为 SetupDiGetDevicePropertyW
或 SetupDiGetDevicePropertyA
,具体取决于是否使用定义的UNICODE
宏进行编译。
实际上,DLL 导出的没有名为SetupDiGetDeviceProperty
函数。如果你挖掘你正在使用的库的标题,你会发现像这样的东西:
#ifdef UNICODE
#define SetupDiGetDeviceProperty SetupDiGetDevicePropertyW
#else
#define SetupDiGetDeviceProperty SetupDiGetDevicePropertyA
#endif
因此,当您调用SetupDiGetDeviceProperty
时,您实际上是在调用函数的 2 个变体 (A/W) 之一。
编译器使用预处理器指令来动态编译函数指针,以调用哪个版本的函数:支持 unicode 的版本或支持 ansi 的版本。是的,有了正确的库引用和包含,你应该能够在没有 loadlibrary() 的情况下直接调用它。
相关文章:
- 没有找到相关文章