21xrx.com
2024-09-20 00:50:30 Friday
登录
文章检索 我的文章 写文章
"C++获取PCIe信息"
2023-06-22 00:22:55 深夜i     --     --
C++ PCI Express PCIe 驱动程序 设备信息

C++获取PCIe信息

在计算机系统中,PCIe总线是用于连接外部设备到主板的一种高速通信接口。为了能够更好地管理和控制PCIe设备,需要获取PCIe信息。C++是一种高级编程语言,它提供了丰富的API和类库,可以轻松地获取PCIe信息。以下将介绍如何使用C++获取PCIe信息。

1.使用WinAPI获取PCIe信息

WinAPI是Windows操作系统的核心API,它提供了许多函数和结构体可以方便地获取PCIe信息,其中最常用的函数是DeviceIoControl和SetupDiEnumDeviceInfo。

DeviceIoControl函数用于与设备进行通信,通过它可以获取设备的信息,比如VID和PID等。示例代码如下:


HANDLE hDevice = CreateFile(_T("\\\\.\\PCI"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

if (hDevice == INVALID_HANDLE_VALUE)

  // error handling

DWORD dwBytesReturned = 0;

BYTE buffer[4096] = { 0 };

BOOL bResult = DeviceIoControl(hDevice, IOCTL_PCI_QUERY_CAPABILITIES, NULL, 0, buffer, sizeof(buffer), &dwBytesReturned, NULL);

if (!bResult)

  // error handling

// parse the buffer to get the desired information

SetupDiEnumDeviceInfo函数用于获取指定设备的属性信息,它返回一个SP_DEVINFO_DATA结构体,通过它可以获取设备的VID、PID、名称等信息。示例代码如下:


HDEVINFO hDevInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);

if (hDevInfoSet == INVALID_HANDLE_VALUE)

  // error handling

SP_DEVINFO_DATA devInfoData = { sizeof(SP_DEVINFO_DATA) };

for (DWORD dwIndex = 0; SetupDiEnumDeviceInfo(hDevInfoSet, dwIndex, &devInfoData); ++dwIndex)

{

  TCHAR szDeviceName[MAX_PATH] = { 0 };

  DWORD dwSize = 0;

  if (!SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)szDeviceName, sizeof(szDeviceName), &dwSize) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)

  

    // error handling

  

  // parse the device name to get the desired information

}

SetupDiDestroyDeviceInfoList(hDevInfoSet);

2.使用WMI获取PCIe信息

WMI(Windows Management Instrumentation)是一种管理技术,它提供了统一的接口和协议,用于在Windows操作系统中管理和监控系统资源。通过WMI,可以轻松地获取PCIe设备的信息,如VID、PID、名称、制造商等。示例代码如下:


CoInitialize(NULL);

IWbemLocator* pLocator = NULL;

HRESULT hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLocator);

if (FAILED(hr))

  // error handling

IWbemServices* pServices = NULL;

hr = pLocator->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pServices);

if (FAILED(hr))

  // error handling

hr = CoSetProxyBlanket(pServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);

if (FAILED(hr))

  // error handling

IEnumWbemClassObject* pEnum = NULL;

hr = pServices->ExecQuery(_bstr_t(L"WQL"), _bstr_t(L"SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnum);

if (FAILED(hr))

  // error handling

IWbemClassObject* pObject = NULL;

ULONG uReturned = 0;

while (pEnum && SUCCEEDED(pEnum->Next(WBEM_INFINITE, 1, &pObject, &uReturned)) && uReturned)

{

  VARIANT varManufacturer;

  VariantInit(&varManufacturer);

  hr = pObject->Get(_bstr_t(L"Manufacturer"), 0, &varManufacturer, NULL, NULL);

  // parse varManufacturer to get the manufacturer name

  VARIANT varCaption;

  VariantInit(&varCaption);

  hr = pObject->Get(_bstr_t(L"Caption"), 0, &varCaption, NULL, NULL);

  // parse varCaption to get the device name

  VARIANT varDeviceID;

  VariantInit(&varDeviceID);

  hr = pObject->Get(_bstr_t(L"DeviceID"), 0, &varDeviceID, NULL, NULL);

  // parse varDeviceID to get the vendor ID and product ID

  VariantClear(&varManufacturer);

  VariantClear(&varCaption);

  VariantClear(&varDeviceID);

  pObject->Release();

}

CoUninitialize();

总结

C++可以通过WinAPI和WMI来获取PCIe设备的信息,常用的信息包括VID、PID、名称、制造商等。使用WinAPI可以获得更加详细的设备信息,但需要手动解析数据,使用WMI可以简化代码,但可能无法获取一些细节信息。根据实际需求,选择合适的方式即可。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复
    相似文章