Posted to tcl by patthoyts at Thu Mar 01 12:55:28 GMT 2007view raw
- /* lscomport.c - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>
- *
- * List all COM ports (esp. including USB devices)
- *
- */
- #define STRICT
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <tchar.h>
- #include <setupapi.h>
- #include <stdio.h>
- #ifdef _MSC_VER
- #pragma comment(lib, "advapi32")
- #pragma comment(lib, "setupapi")
- #pragma comment(lib, "user32")
- #endif
- typedef struct tagSERIALPORTINFO
- {
- int nPortNumber;
- LPTSTR pszPortName;
- LPTSTR pszFriendlyName;
- struct tagSERIALPORTINFO* next;
- } SERIALPORTINFO, *LPSERIALPORTINFO;
- BOOL GetSerialPortInfo(LPSERIALPORTINFO *ppInfo);
- /* ---------------------------------------------------------------------- */
- int
- _tmain(int argc, TCHAR *argv[])
- {
- LPSERIALPORTINFO pPortInfo = 0;
- GetSerialPortInfo(&pPortInfo);
- while (pPortInfo) {
- LPSERIALPORTINFO p = pPortInfo;
- pPortInfo = pPortInfo->next;
- _tprintf(_T("Port %d '%s'\n"), p->nPortNumber, p->pszFriendlyName);
- HeapFree(GetProcessHeap(), 0, p->pszPortName);
- HeapFree(GetProcessHeap(), 0, p->pszFriendlyName);
- HeapFree(GetProcessHeap(), 0, p);
- }
- return 0;
- }
- /* ---------------------------------------------------------------------- */
- static HANDLE
- SetupEnumeratePorts()
- {
- HDEVINFO hDevices = INVALID_HANDLE_VALUE;
- DWORD dwGuids = 0;
- BOOL br = SetupDiClassGuidsFromName(_T("Ports"), 0, 0, &dwGuids);
- if (dwGuids) {
- LPGUID pguids = (LPGUID)HeapAlloc(GetProcessHeap(), 0, sizeof(GUID) * dwGuids);
- if (pguids) {
- br = SetupDiClassGuidsFromName(_T("Ports"), pguids, dwGuids, &dwGuids);
- if (br) {
- hDevices = SetupDiGetClassDevs(pguids, NULL, NULL, DIGCF_PRESENT);
- }
- HeapFree(GetProcessHeap(), 0, pguids);
- }
- }
- return hDevices;
- }
- static BOOL
- EndEnumeratePorts(HANDLE hDevices)
- {
- if (SetupDiDestroyDeviceInfoList(hDevices)) {
- return TRUE;
- }
- return FALSE;
- }
- BOOL
- GetSerialPortInfo(LPSERIALPORTINFO *ppInfo)
- {
- 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;
- deviceData.cbSize = sizeof(SP_DEVINFO_DATA);
- br = SetupDiEnumDeviceInfo(hDevices, nDevice, &deviceData);
- if (br)
- {
- TCHAR sz[16] = {0};
- HKEY hkey = SetupDiOpenDevRegKey(hDevices, &deviceData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
- if (hkey)
- {
- DWORD cbSize = 16 * sizeof(TCHAR);
- RegQueryValueEx(hkey, _T("PortName"), NULL, NULL, (LPBYTE)sz, &cbSize);
- RegCloseKey(hkey);
- }
- CharUpper(sz);
- if (sz[0] == _T('C') && sz[1] == _T('O') && sz[2] == _T('M'))
- {
- LPSERIALPORTINFO pInfo =
- (LPSERIALPORTINFO)HeapAlloc(GetProcessHeap(), 0, sizeof(SERIALPORTINFO));
- pInfo->next = 0;
- pInfo->pszPortName =
- (LPTSTR)HeapAlloc(GetProcessHeap(), 0, sizeof(TCHAR) * (lstrlen(sz) + 1));
- lstrcpy(pInfo->pszPortName, sz);
- pInfo->nPortNumber = _ttoi(&sz[3]);
- SetupDiGetDeviceRegistryProperty(hDevices, &deviceData, SPDRP_FRIENDLYNAME,
- NULL, NULL, 0, &cbData);
- if (cbData)
- {
- 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
- {
- pTail->next = pInfo;
- pTail = pInfo;
- }
- }
- }
- }
- EndEnumeratePorts(hDevices);
- *ppInfo = pHead;
- return br;
- }