* List all COM ports (esp. including USB devices)
*
*/
+#define _WIN32_WINNT _WIN32_WINNT_WIN10
+#define _WIN32_IE _WIN32_IE_IE100
-#define STRICT
-#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
-#include <setupapi.h>
+#include <SetupAPI.h>
+#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
-#ifdef _MSC_VER
+#if _MSC_VER >= 1200
#pragma comment(lib, "advapi32")
#pragma comment(lib, "setupapi")
#pragma comment(lib, "user32")
typedef struct tagSERIALPORTINFO
{
int nPortNumber;
+ WORD vid;
+ WORD pid;
LPTSTR pszPortName;
LPTSTR pszFriendlyName;
+ LPTSTR pszHardwareId;
struct tagSERIALPORTINFO* next;
} SERIALPORTINFO, *LPSERIALPORTINFO;
-BOOL GetSerialPortInfo(LPSERIALPORTINFO *ppInfo);
+/**
+ * Creates a linked list of SERIALPORTINFO items attached to the provided pointer.
+ */
+BOOL GetSerialPortInfo(LPSERIALPORTINFO *ppInfo);
/* ---------------------------------------------------------------------- */
int
_tmain(int argc, TCHAR *argv[])
{
- LPSERIALPORTINFO pPortInfo = 0;
+ LPSERIALPORTINFO pPortInfo = NULL;
GetSerialPortInfo(&pPortInfo);
while (pPortInfo) {
LPSERIALPORTINFO p = pPortInfo;
pPortInfo = pPortInfo->next;
- _tprintf(_T("Port %d '%s'\n"), p->nPortNumber, p->pszFriendlyName);
+ _tprintf(_T("Port %d '%s' [%04hX:%04hX] %s\n"),
+ p->nPortNumber, p->pszFriendlyName, p->vid, p->pid, p->pszHardwareId);
HeapFree(GetProcessHeap(), 0, p->pszPortName);
HeapFree(GetProcessHeap(), 0, p->pszFriendlyName);
+ HeapFree(GetProcessHeap(), 0, p->pszHardwareId);
HeapFree(GetProcessHeap(), 0, p);
}
return 0;
{
HDEVINFO hDevices = INVALID_HANDLE_VALUE;
DWORD dwGuids = 0;
- BOOL br = SetupDiClassGuidsFromName(_T("Ports"), 0, 0, &dwGuids);
+ BOOL br = SetupDiClassGuidsFromName(_T("Ports"), NULL, 0, &dwGuids);
if (dwGuids) {
LPGUID pguids = (LPGUID)HeapAlloc(GetProcessHeap(), 0, sizeof(GUID) * dwGuids);
if (pguids) {
}
BOOL
-GetSerialPortInfo(LPSERIALPORTINFO *ppInfo)
+GetSerialPortInfo(LPSERIALPORTINFO *pList)
{
HANDLE hDevices = SetupEnumeratePorts();
BOOL br = TRUE;
- LPSERIALPORTINFO pHead = 0, pTail = 0;
DWORD nDevice = 0;
for (nDevice = 0; br ; nDevice++)
{
DWORD cbData = 0;
- SP_DEVINFO_DATA deviceData;
+ SP_DEVINFO_DATA deviceData = { 0 };
deviceData.cbSize = sizeof(SP_DEVINFO_DATA);
br = SetupDiEnumDeviceInfo(hDevices, nDevice, &deviceData);
HKEY hkey = SetupDiOpenDevRegKey(hDevices, &deviceData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
if (hkey)
{
- DWORD cbSize = 16 * sizeof(TCHAR);
+ DWORD cbSize = sizeof(sz);
RegQueryValueEx(hkey, _T("PortName"), NULL, NULL, (LPBYTE)sz, &cbSize);
RegCloseKey(hkey);
}
if (sz[0] == _T('C') && sz[1] == _T('O') && sz[2] == _T('M'))
{
LPSERIALPORTINFO pInfo =
- (LPSERIALPORTINFO)HeapAlloc(GetProcessHeap(), 0, sizeof(SERIALPORTINFO));
+ (LPSERIALPORTINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SERIALPORTINFO));
pInfo->next = 0;
pInfo->pszPortName =
- (LPTSTR)HeapAlloc(GetProcessHeap(), 0, sizeof(TCHAR) * (lstrlen(sz) + 1));
+ (LPTSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TCHAR) * ((size_t)lstrlen(sz) + 1));
lstrcpy(pInfo->pszPortName, sz);
pInfo->nPortNumber = _ttoi(&sz[3]);
- SetupDiGetDeviceRegistryProperty(hDevices, &deviceData, SPDRP_FRIENDLYNAME,
- NULL, NULL, 0, &cbData);
+ SetupDiGetDeviceRegistryProperty(hDevices, &deviceData, SPDRP_FRIENDLYNAME, NULL, NULL, 0, &cbData);
if (cbData)
{
- pInfo->pszFriendlyName =
- (LPTSTR)HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(TCHAR));
+ pInfo->pszFriendlyName = (LPTSTR)HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(TCHAR));
br = SetupDiGetDeviceRegistryProperty(hDevices, &deviceData, SPDRP_FRIENDLYNAME,
NULL, (LPBYTE)pInfo->pszFriendlyName, cbData, NULL);
pInfo->pszFriendlyName[cbData] = 0;
}
- if (pTail == 0)
- {
- pHead = pTail = pInfo;
- }
- else
+ // Get the hardware ID (contains the VID:PID is a USB device)
+ SetupDiGetDeviceRegistryProperty(hDevices, &deviceData, SPDRP_HARDWAREID, NULL, NULL, 0, &cbData);
+ if (cbData)
{
- pTail->next = pInfo;
- pTail = pInfo;
+ pInfo->pszHardwareId = (LPTSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbData + sizeof(TCHAR));
+ br = SetupDiGetDeviceRegistryProperty(hDevices, &deviceData, SPDRP_HARDWAREID, NULL, (LPBYTE)pInfo->pszHardwareId, cbData, NULL);
+ pInfo->pszHardwareId[cbData] = 0;
+ _stscanf_s(pInfo->pszHardwareId, _T("USB\\VID_%04hx&PID_%04hx"), &pInfo->vid, &pInfo->pid);
}
+
+ *pList = pInfo;
+ pList = &(pInfo->next);
}
}
}
EndEnumeratePorts(hDevices);
- *ppInfo = pHead;
return br;
}