21xrx.com
2025-04-23 03:29:17 Wednesday
文章检索 我的文章 写文章
"C++获取PCIe信息"
2023-06-22 00:22:55 深夜i     60     0
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可以简化代码,但可能无法获取一些细节信息。根据实际需求,选择合适的方式即可。

  
  

评论区

    相似文章
请求出错了