Posted to tcl by patthoyts at Thu Mar 01 12:55:28 GMT 2007view raw

  1. /* lscomport.c - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>
  2. *
  3. * List all COM ports (esp. including USB devices)
  4. *
  5. */
  6.  
  7. #define STRICT
  8. #define WIN32_LEAN_AND_MEAN
  9. #include <windows.h>
  10. #include <tchar.h>
  11. #include <setupapi.h>
  12. #include <stdio.h>
  13.  
  14. #ifdef _MSC_VER
  15. #pragma comment(lib, "advapi32")
  16. #pragma comment(lib, "setupapi")
  17. #pragma comment(lib, "user32")
  18. #endif
  19.  
  20. typedef struct tagSERIALPORTINFO
  21. {
  22. int nPortNumber;
  23. LPTSTR pszPortName;
  24. LPTSTR pszFriendlyName;
  25. struct tagSERIALPORTINFO* next;
  26. } SERIALPORTINFO, *LPSERIALPORTINFO;
  27.  
  28. BOOL GetSerialPortInfo(LPSERIALPORTINFO *ppInfo);
  29.  
  30. /* ---------------------------------------------------------------------- */
  31.  
  32. int
  33. _tmain(int argc, TCHAR *argv[])
  34. {
  35. LPSERIALPORTINFO pPortInfo = 0;
  36. GetSerialPortInfo(&pPortInfo);
  37. while (pPortInfo) {
  38. LPSERIALPORTINFO p = pPortInfo;
  39. pPortInfo = pPortInfo->next;
  40. _tprintf(_T("Port %d '%s'\n"), p->nPortNumber, p->pszFriendlyName);
  41. HeapFree(GetProcessHeap(), 0, p->pszPortName);
  42. HeapFree(GetProcessHeap(), 0, p->pszFriendlyName);
  43. HeapFree(GetProcessHeap(), 0, p);
  44. }
  45. return 0;
  46. }
  47.  
  48. /* ---------------------------------------------------------------------- */
  49.  
  50. static HANDLE
  51. SetupEnumeratePorts()
  52. {
  53. HDEVINFO hDevices = INVALID_HANDLE_VALUE;
  54. DWORD dwGuids = 0;
  55. BOOL br = SetupDiClassGuidsFromName(_T("Ports"), 0, 0, &dwGuids);
  56. if (dwGuids) {
  57. LPGUID pguids = (LPGUID)HeapAlloc(GetProcessHeap(), 0, sizeof(GUID) * dwGuids);
  58. if (pguids) {
  59. br = SetupDiClassGuidsFromName(_T("Ports"), pguids, dwGuids, &dwGuids);
  60. if (br) {
  61. hDevices = SetupDiGetClassDevs(pguids, NULL, NULL, DIGCF_PRESENT);
  62. }
  63. HeapFree(GetProcessHeap(), 0, pguids);
  64. }
  65. }
  66. return hDevices;
  67. }
  68.  
  69. static BOOL
  70. EndEnumeratePorts(HANDLE hDevices)
  71. {
  72. if (SetupDiDestroyDeviceInfoList(hDevices)) {
  73. return TRUE;
  74. }
  75. return FALSE;
  76. }
  77.  
  78. BOOL
  79. GetSerialPortInfo(LPSERIALPORTINFO *ppInfo)
  80. {
  81. HANDLE hDevices = SetupEnumeratePorts();
  82. BOOL br = TRUE;
  83. LPSERIALPORTINFO pHead = 0, pTail = 0;
  84. DWORD nDevice = 0;
  85.  
  86. for (nDevice = 0; br ; nDevice++)
  87. {
  88. DWORD cbData = 0;
  89. SP_DEVINFO_DATA deviceData;
  90.  
  91. deviceData.cbSize = sizeof(SP_DEVINFO_DATA);
  92. br = SetupDiEnumDeviceInfo(hDevices, nDevice, &deviceData);
  93. if (br)
  94. {
  95. TCHAR sz[16] = {0};
  96. HKEY hkey = SetupDiOpenDevRegKey(hDevices, &deviceData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
  97. if (hkey)
  98. {
  99. DWORD cbSize = 16 * sizeof(TCHAR);
  100. RegQueryValueEx(hkey, _T("PortName"), NULL, NULL, (LPBYTE)sz, &cbSize);
  101. RegCloseKey(hkey);
  102. }
  103. CharUpper(sz);
  104. if (sz[0] == _T('C') && sz[1] == _T('O') && sz[2] == _T('M'))
  105. {
  106. LPSERIALPORTINFO pInfo =
  107. (LPSERIALPORTINFO)HeapAlloc(GetProcessHeap(), 0, sizeof(SERIALPORTINFO));
  108. pInfo->next = 0;
  109. pInfo->pszPortName =
  110. (LPTSTR)HeapAlloc(GetProcessHeap(), 0, sizeof(TCHAR) * (lstrlen(sz) + 1));
  111. lstrcpy(pInfo->pszPortName, sz);
  112. pInfo->nPortNumber = _ttoi(&sz[3]);
  113.  
  114. SetupDiGetDeviceRegistryProperty(hDevices, &deviceData, SPDRP_FRIENDLYNAME,
  115. NULL, NULL, 0, &cbData);
  116. if (cbData)
  117. {
  118. pInfo->pszFriendlyName =
  119. (LPTSTR)HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(TCHAR));
  120. br = SetupDiGetDeviceRegistryProperty(hDevices, &deviceData, SPDRP_FRIENDLYNAME,
  121. NULL, (LPBYTE)pInfo->pszFriendlyName, cbData, NULL);
  122. pInfo->pszFriendlyName[cbData] = 0;
  123. }
  124.  
  125. if (pTail == 0)
  126. {
  127. pHead = pTail = pInfo;
  128. }
  129. else
  130. {
  131. pTail->next = pInfo;
  132. pTail = pInfo;
  133. }
  134. }
  135. }
  136. }
  137. EndEnumeratePorts(hDevices);
  138. *ppInfo = pHead;
  139. return br;
  140. }