检测本机所有的串并端口(vs2003调试通过)

检测本机所有的串并端口
#include <setupapi.h>
typedef HKEY (__stdcall SETUPDIOPENDEVREGKEY)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM);
typedef BOOL (__stdcall SETUPDICLASSGUIDSFROMNAME)(LPCTSTR, LPGUID, DWORD, PDWORD);
typedef BOOL (__stdcall SETUPDIDESTROYDEVICEINFOLIST)(HDEVINFO);
typedef BOOL (__stdcall SETUPDIENUMDEVICEINFO)(HDEVINFO, DWORD, PSP_DEVINFO_DATA);
typedef HDEVINFO (__stdcall SETUPDIGETCLASSDEVS)(LPGUID, LPCTSTR, HWND, DWORD);
typedef BOOL (__stdcall SETUPDIGETDEVICEREGISTRYPROPERTY)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD);

BOOL IsNumeric(LPCTSTR pszString, BOOL bIgnoreColon)
{
 int nLen = _tcslen(pszString);
 if (nLen == 0)
  return FALSE;

 //Assume the best
 BOOL bNumeric = TRUE;

 for (int i=0; i<nLen && bNumeric; i++)
 {
  bNumeric = (_istdigit(pszString[i]) != 0);
  if (bIgnoreColon && (pszString[i] == _T(':')))
   bNumeric = TRUE;
 }

 return bNumeric;
}
void TestPorts()
{
 CString strUsbstring = "USB Serial Port";
 BOOL bFound = FALSE;

 HINSTANCE hSetupAPI = LoadLibrary(_T("SETUPAPI.DLL"));
 if (hSetupAPI == NULL){
  AfxMessageBox("加载动态连接库失败!");
  return;
 }

 SETUPDIOPENDEVREGKEY* lpfnLPSETUPDIOPENDEVREGKEY = (SETUPDIOPENDEVREGKEY*) GetProcAddress(hSetupAPI, "SetupDiOpenDevRegKey");
#ifdef _UNICODE
 SETUPDICLASSGUIDSFROMNAME* lpfnSETUPDICLASSGUIDSFROMNAME = (SETUPDICLASSGUIDSFROMNAME*) GetProcAddress(hSetupAPI, "SetupDiClassGuidsFromNameW");
 SETUPDIGETCLASSDEVS* lpfnSETUPDIGETCLASSDEVS = (SETUPDIGETCLASSDEVS*) GetProcAddress(hSetupAPI, "SetupDiGetClassDevsW");
 SETUPDIGETDEVICEREGISTRYPROPERTY* lpfnSETUPDIGETDEVICEREGISTRYPROPERTY = (SETUPDIGETDEVICEREGISTRYPROPERTY*) GetProcAddress(hSetupAPI, "SetupDiGetDeviceRegistryPropertyW");
#else
 SETUPDICLASSGUIDSFROMNAME* lpfnSETUPDICLASSGUIDSFROMNAME = (SETUPDICLASSGUIDSFROMNAME*) GetProcAddress(hSetupAPI, "SetupDiClassGuidsFromNameA");
 SETUPDIGETCLASSDEVS* lpfnSETUPDIGETCLASSDEVS = (SETUPDIGETCLASSDEVS*) GetProcAddress(hSetupAPI, "SetupDiGetClassDevsA");
 SETUPDIGETDEVICEREGISTRYPROPERTY* lpfnSETUPDIGETDEVICEREGISTRYPROPERTY = (SETUPDIGETDEVICEREGISTRYPROPERTY*) GetProcAddress(hSetupAPI, "SetupDiGetDeviceRegistryPropertyA");
#endif
 SETUPDIDESTROYDEVICEINFOLIST* lpfnSETUPDIDESTROYDEVICEINFOLIST = (SETUPDIDESTROYDEVICEINFOLIST*) GetProcAddress(hSetupAPI, "SetupDiDestroyDeviceInfoList");
 SETUPDIENUMDEVICEINFO* lpfnSETUPDIENUMDEVICEINFO = (SETUPDIENUMDEVICEINFO*) GetProcAddress(hSetupAPI, "SetupDiEnumDeviceInfo");

 if ((lpfnLPSETUPDIOPENDEVREGKEY == NULL) || (lpfnSETUPDICLASSGUIDSFROMNAME == NULL) || (lpfnSETUPDIDESTROYDEVICEINFOLIST == NULL) ||
  (lpfnSETUPDIENUMDEVICEINFO == NULL) || (lpfnSETUPDIGETCLASSDEVS == NULL) || (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY == NULL))
 {
  //Unload the setup dll
  FreeLibrary(hSetupAPI);

  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  
  AfxMessageBox("加载函数失败!");
  return;
 }

 //First need to convert the name "Ports" to a GUID using SetupDiClassGuidsFromName
 DWORD dwGuids = 0;
 lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), NULL, 0, &dwGuids);
 if (dwGuids == 0)
 {
  //Unload the setup dll
  FreeLibrary(hSetupAPI);
  AfxMessageBox("第一次执行转化GUID失败!");

  return;
 }

 //Allocate the needed memory
 GUID* pGuids = new GUID[dwGuids];

 //Call the function again
 if (!lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), pGuids, dwGuids, &dwGuids))
 {
  //Free up the memory before we return
  delete [] pGuids;

  //Unload the setup dll
  FreeLibrary(hSetupAPI);
  AfxMessageBox("第二次执行转化GUID失败!");

  return;
 }

 //Now create a "device information set" which is required to enumerate all the ports
 HDEVINFO hDevInfoSet = lpfnSETUPDIGETCLASSDEVS(pGuids, NULL, NULL, DIGCF_PRESENT);
 if (hDevInfoSet == INVALID_HANDLE_VALUE)
 {
  //Free up the memory before we return
  delete [] pGuids;

  //Unload the setup dll
  FreeLibrary(hSetupAPI);
  AfxMessageBox("取得设备信息集失败!");

  return;
 }

 //Finished with the Guids by this time
 delete [] pGuids;
 pGuids = NULL;

 //Finally do the enumeration
 BOOL bMoreItems = TRUE;
 int nIndex = 0;
 SP_DEVINFO_DATA devInfo;
 while (bMoreItems)
 {
  //Enumerate the current device
  devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
  bMoreItems = lpfnSETUPDIENUMDEVICEINFO(hDevInfoSet, nIndex, &devInfo);
  if (bMoreItems)
  {
   //Did we find a serial port for this device
   BOOL bAdded = FALSE;

   //Get the registry key which stores the ports settings
   HKEY hDeviceKey = lpfnLPSETUPDIOPENDEVREGKEY(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
   TCHAR pszPortName[256];
   memset(pszPortName,0,sizeof(pszPortName));
   if (hDeviceKey)
   {
    //Read in the name of the port
    //TCHAR pszPortName[256];
    DWORD dwSize = sizeof(pszPortName);
    DWORD dwType = 0;
    if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, (LPBYTE) pszPortName, &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ))
    {
     //If it looks like "COMX" then
     //add it to the array which will be returned
     int nLen = _tcslen(pszPortName);
     if (nLen > 3)
     {
      if ((_tcsnicmp(pszPortName, _T("COM"), 3) == 0) && IsNumeric(&pszPortName[3], FALSE))
      {
       //Work out the port number
       int nPort = _ttoi(&pszPortName[3]);
       CString ssstr(_T("发现串口"));
       CString ssstr1;
       ssstr1.Format("%d",nPort);
       ssstr.Append(ssstr1);
       AfxMessageBox(ssstr);
       //ports.Add(nPort);
       
       bAdded = TRUE;
      }else if  ((_tcsnicmp(pszPortName, _T("LPT"), 3) == 0) && IsNumeric(&pszPortName[3], FALSE))
      {
              int nPort = _ttoi(&pszPortName[3]);
       CString ssstr(_T("发现并口"));
       CString ssstr1;
       ssstr1.Format("%d",nPort);
       ssstr.Append(ssstr1);
       AfxMessageBox(ssstr);
       //ports.Add(nPort);
       
       bAdded = TRUE;
      }
     }
    }

    //Close the key now that we are finished with it
    RegCloseKey(hDeviceKey);
   }

   //If the port was a serial port, then also try to get its friendly name
   if (bAdded)
   {
    TCHAR pszFriendlyName[256];
    DWORD dwSize = sizeof(pszFriendlyName);
    DWORD dwType = 0;
    if (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY(hDevInfoSet, &devInfo, SPDRP_DEVICEDESC, &dwType, (PBYTE)pszFriendlyName, dwSize, &dwSize) && (dwType == REG_SZ))
     //     sFriendlyNames.Add(pszFriendlyName);
     //    else
     //     sFriendlyNames.Add(_T(""));
    {
     //校验com口是否是usb虚拟设备
     CString strName = pszFriendlyName;
     if(strName.Find(strUsbstring) != -1)
     {
      //是usb虚拟设备
      //AfxMessageBox(pszPortName);
      //AfxMessageBox(strName);
      CString szComName = pszPortName;
      bFound = TRUE;
      AfxMessageBox("这是一个USB虚拟COM口!");
      AfxMessageBox(szComName);
     }
    }
   }

   AfxMessageBox(pszPortName);
  }

  ++nIndex;
 }

 //Free up the "device information set" now that we are finished with it
 lpfnSETUPDIDESTROYDEVICEINFOLIST(hDevInfoSet);

 //Unload the setup dll
 FreeLibrary(hSetupAPI);

 CString sssss;
 sssss.Format("共找到%d个端口",(nIndex-1));
 AfxMessageBox(sssss);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值