#if defined(OS_WINDOWS) struct SSerInfo { CString strDevPath; // Device path for use with CreateFile() CString strPortName; // Simple name (i.e. COM1) CString strFriendlyName; // Full name to be displayed to a user CString strPortDesc; // friendly name without the COMx }; void EnumSerialPorts(CArray &asi, BOOL bIgnoreBusyPorts) { // Clear the output array asi.RemoveAll(); EnumPortsWdm(asi); for (int ii=0; ii=_T('0')) && (*pt1<=_T('9'))) { rsi.strPortName += *pt1++; } pt -= 2; pt1 = fName.GetBuffer(); rsi.strPortDesc.Empty(); while (pt1 <= pt) { rsi.strPortDesc += *pt1++; } } } void EnumPortsWdm(CArray &asi) { CString strErr; // Create a device information set that will be the container for // the device interfaces. GUID *guidDev = (GUID*) &GUID_CLASS_COMPORT; HDEVINFO hDevInfo = INVALID_HANDLE_VALUE; SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL; try { hDevInfo = SetupDiGetClassDevs( guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); if(hDevInfo == INVALID_HANDLE_VALUE) { strErr.Format(_T("SetupDiGetClassDevs failed. (err=%lx)"), GetLastError()); throw strErr; } // Enumerate the serial ports BOOL bOk = TRUE; SP_DEVICE_INTERFACE_DATA ifcData; DWORD dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256; pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*) new char[dwDetDataSize]; // This is required, according to the documentation. Yes, // it's weird. ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); for (DWORD ii=0; bOk; ii++) { bOk = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guidDev, ii, &ifcData); if (bOk) { // Got a device. Get the details. SP_DEVINFO_DATA devdata = {sizeof(SP_DEVINFO_DATA)}; bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifcData, pDetData, dwDetDataSize, NULL, &devdata); if (bOk) { CString strDevPath(pDetData->DevicePath); // Got a path to the device. Try to get some more info. TCHAR fname[256]; BOOL bSuccess = SetupDiGetDeviceRegistryProperty( hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL, (PBYTE)fname, sizeof(fname), NULL); if (bSuccess) { // Add an entry to the array SSerInfo si; si.strDevPath = strDevPath; si.strFriendlyName = fname; asi.Add(si); } } else { strErr.Format(_T("SetupDiGetDeviceInterfaceDetail failed. (err=%lx)"), GetLastError()); throw strErr; } } else { DWORD err = GetLastError(); if (err != ERROR_NO_MORE_ITEMS) { strErr.Format(_T("SetupDiEnumDeviceInterfaces failed. (err=%lx)"), err); throw strErr; } } } } catch (CString strCatchErr) { strErr = strCatchErr; } if (pDetData != NULL) delete [] (char*)pDetData; if (hDevInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hDevInfo); if (!strErr.IsEmpty()) throw strErr; } #endif /* OS_WINDOWS */