int GetPortNum( HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData) { HKEY hKey; hKey = SetupDiOpenDevRegKey(hDevInfo, pDevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if (hKey == INVALID_HANDLE_VALUE) return -1; int num; DWORD len; DWORD portNum; len = sizeof(portNum); if (RegQueryValueEx(hKey, C0C_REGSTR_VAL_PORT_NUM, NULL, NULL, (PBYTE)&portNum, &len) == ERROR_SUCCESS) num = portNum; else num = -1; RegCloseKey(hKey); return num; }
static gboolean compare_location_and_create_image_device_info_if_matching (const FridaDeviceInfo * device_info, gpointer user_data) { FridaFindImageDeviceContext * ctx = (FridaFindImageDeviceContext *) user_data; HKEY devkey = (HKEY) INVALID_HANDLE_VALUE; WCHAR * friendly_name = NULL; WCHAR * icon_url = NULL; if (_wcsicmp (device_info->location, ctx->location) != 0) goto keep_looking; devkey = SetupDiOpenDevRegKey (device_info->device_info_set, device_info->device_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if (devkey == INVALID_HANDLE_VALUE) goto keep_looking; friendly_name = frida_read_registry_string (devkey, L"FriendlyName"); if (friendly_name == NULL) goto keep_looking; icon_url = frida_read_registry_multi_string (devkey, L"Icons"); if (icon_url == NULL) goto keep_looking; ctx->image_device = frida_image_device_info_new (friendly_name, icon_url); RegCloseKey (devkey); return FALSE; keep_looking: g_free (icon_url); g_free (friendly_name); if (devkey != INVALID_HANDLE_VALUE) RegCloseKey (devkey); return TRUE; }
static BOOL RenameHostOnlyConnectionsCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext) { WCHAR DevName[256]; DWORD winEr; if (SetupDiGetDeviceRegistryPropertyW(hDevInfo, pDev, SPDRP_FRIENDLYNAME , /* IN DWORD Property,*/ NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/ (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/ sizeof(DevName), /* IN DWORD PropertyBufferSize,*/ NULL /*OUT PDWORD RequiredSize OPTIONAL*/ )) { HKEY hKey = SetupDiOpenDevRegKey(hDevInfo, pDev, DICS_FLAG_GLOBAL, /* IN DWORD Scope,*/ 0, /*IN DWORD HwProfile, */ DIREG_DRV, /* IN DWORD KeyType, */ KEY_READ /*IN REGSAM samDesired*/ ); NonStandardAssert(hKey != INVALID_HANDLE_VALUE); if (hKey != INVALID_HANDLE_VALUE) { WCHAR guid[50]; DWORD cbGuid=sizeof(guid); winEr = RegQueryValueExW(hKey, L"NetCfgInstanceId", /*__in_opt LPCTSTR lpValueName,*/ NULL, /*__reserved LPDWORD lpReserved,*/ NULL, /*__out_opt LPDWORD lpType,*/ (LPBYTE)guid, /*__out_opt LPBYTE lpData,*/ &cbGuid /*guid__inout_opt LPDWORD lpcbData*/ ); NonStandardAssert(winEr == ERROR_SUCCESS); if (winEr == ERROR_SUCCESS) { WCHAR ConnectoinName[128]; ULONG cbName = sizeof(ConnectoinName); HRESULT hr = VBoxNetCfgWinGenHostonlyConnectionName (DevName, ConnectoinName, &cbName); NonStandardAssert(hr == S_OK); if (SUCCEEDED(hr)) { hr = VBoxNetCfgWinRenameConnection(guid, ConnectoinName); NonStandardAssert(hr == S_OK); } } } RegCloseKey(hKey); } else { NonStandardAssert(0); } return TRUE; }
QList<SerialPortId> enumerateSerialPorts(int) { DWORD index=0; SP_DEVINFO_DATA info; GUID guid = GUID_DEVCLASS_PORTS; HDEVINFO infoset = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_PRESENT); QString valueName(16384, 0); QList<SerialPortId> list; for (index=0;;index++) { ZeroMemory(&info, sizeof(SP_DEVINFO_DATA)); info.cbSize = sizeof(SP_DEVINFO_DATA); if (!SetupDiEnumDeviceInfo(infoset, index, &info)) break; QString friendlyName; QString portName; DWORD size=0; SetupDiGetDeviceRegistryProperty(infoset, &info, SPDRP_FRIENDLYNAME, 0, 0, 0, &size); QByteArray ba(size, 0); if(SetupDiGetDeviceRegistryProperty(infoset, &info, SPDRP_FRIENDLYNAME, 0, (BYTE*)(ba.data()), size, 0)) { friendlyName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1); } HKEY key = SetupDiOpenDevRegKey(infoset, &info, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if(key != INVALID_HANDLE_VALUE) { //RegGetValue not supported on XP, SHRegGetValue not supported by mingw, so use the old method of enumerating all the values for (DWORD dwi=0;;dwi++) { DWORD vsize = valueName.size(); if (ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, 0, &size)) { if (valueName.startsWith("PortName")) { QByteArray ba(size, 0); vsize = valueName.size(); if(ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, (BYTE*)(ba.data()), &size)) { portName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1); } } } else { break; } } RegCloseKey(key); } SerialPortId id; id.portName = portName; id.friendlyName = friendlyName; list.append(id); } SetupDiDestroyDeviceInfoList(infoset); return list; }
bool GetSizeForDevID(wxString &TargetDevID, int *WidthMm, int *HeightMm) { HDEVINFO devInfo = SetupDiGetClassDevsEx( &GUID_CLASS_MONITOR, //class GUID NULL, //enumerator NULL, //HWND DIGCF_PRESENT, // Flags //DIGCF_ALLCLASSES| NULL, // device info, create a new one. NULL, // machine name, local machine NULL);// reserved if (NULL == devInfo) return false; bool bRes = false; for (ULONG i=0; ERROR_NO_MORE_ITEMS != GetLastError(); ++i) { SP_DEVINFO_DATA devInfoData; memset(&devInfoData,0,sizeof(devInfoData)); devInfoData.cbSize = sizeof(devInfoData); if (SetupDiEnumDeviceInfo(devInfo,i,&devInfoData)) { wchar_t Instance[80]; SetupDiGetDeviceInstanceId(devInfo, &devInfoData, Instance, MAX_PATH, NULL); wxString instance(Instance); if(instance.Upper().Find( TargetDevID.Upper() ) == wxNOT_FOUND ) continue; HKEY hDevRegKey = SetupDiOpenDevRegKey(devInfo,&devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if(!hDevRegKey || (hDevRegKey == INVALID_HANDLE_VALUE)) continue; bRes = GetMonitorSizeFromEDID(hDevRegKey, WidthMm, HeightMm); RegCloseKey(hDevRegKey); } } SetupDiDestroyDeviceInfoList(devInfo); return bRes; }
bool QextSerialEnumerator::getDeviceDetailsWin( QextPortInfo* portInfo, HDEVINFO devInfo, PSP_DEVINFO_DATA devData, WPARAM wParam ) { portInfo->friendName = getDeviceProperty(devInfo, devData, SPDRP_FRIENDLYNAME); if( wParam == DBT_DEVICEARRIVAL) portInfo->physName = getDeviceProperty(devInfo, devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME); portInfo->enumName = getDeviceProperty(devInfo, devData, SPDRP_ENUMERATOR_NAME); QString hardwareIDs = getDeviceProperty(devInfo, devData, SPDRP_HARDWAREID); HKEY devKey = SetupDiOpenDevRegKey(devInfo, devData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); portInfo->portName = QextSerialPort::fullPortNameWin( getRegKeyValue(devKey, TEXT("PortName")) ); QRegExp idRx("VID_(\\w+)&PID_(\\w+)&"); if( hardwareIDs.toUpper().contains(idRx) ) { bool dummy; portInfo->vendorID = idRx.cap(1).toInt(&dummy, 16); portInfo->productID = idRx.cap(2).toInt(&dummy, 16); //qDebug() << "got vid:" << vid << "pid:" << pid; } return true; }
DWORD OpenDeviceKey( HDEVINFO Handle, PSP_DEVINFO_DATA FILTERINFOData, DWORD KeyType, REGSAM DesiredAccess, OUT HKEY * OutKey) { HKEY hKey; /* try open device registry key */ hKey = SetupDiOpenDevRegKey(Handle, FILTERINFOData, DICS_FLAG_CONFIGSPECIFIC, 0, KeyType, DesiredAccess); if (hKey == INVALID_HANDLE_VALUE) return GetLastError(); /* store result */ *OutKey = hKey; return ERROR_SUCCESS; }
extern "C" DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask) { BOOL ok; DWORD ret = 0; GUID netGuid; HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DeviceInfoData; SP_DRVINFO_DATA DriverInfoData; SP_DEVINSTALL_PARAMS DeviceInstallParams; TCHAR className[MAX_PATH]; TCHAR temp[MAX_PATH]; DWORD index = 0; BOOL found = FALSE; BOOL registered = FALSE; BOOL destroyList = FALSE; PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail; DWORD detailBuf[2048]; // for our purposes, 8k buffer is more // than enough to obtain the hardware ID // of the loopback driver. HKEY hkey = NULL; DWORD cbSize; DWORD dwValueType; TCHAR pCfgGuidString[40]; // initialize the structure size DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA); // copy the net class GUID memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET)); // create an empty device info set associated with the net class GUID hDeviceInfo = SetupDiCreateDeviceInfoList(&netGuid, NULL); if (hDeviceInfo == INVALID_HANDLE_VALUE) return GetLastError(); // get the class name from GUID ok = SetupDiClassNameFromGuid(&netGuid, className, MAX_PATH, NULL); if (!ok) { ret = GetLastError(); goto cleanup; } // create a device info element and add the new device instance // key to registry ok = SetupDiCreateDeviceInfo(hDeviceInfo, className, &netGuid, NULL, NULL, DICD_GENERATE_ID, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // select the newly created device info to be the currently // selected member ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // build a list of class drivers ok = SetupDiBuildDriverInfoList(hDeviceInfo, &DeviceInfoData, SPDIT_CLASSDRIVER); if (!ok) { ret = GetLastError(); goto cleanup; } destroyList = TRUE; // enumerate the driver info list while (TRUE) { BOOL ret; ret = SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData, SPDIT_CLASSDRIVER, index, &DriverInfoData); // if the function failed and GetLastError() returned // ERROR_NO_MORE_ITEMS, then we have reached the end of the // list. Othewise there was something wrong with this // particular driver. if(!ret) { if(GetLastError() == ERROR_NO_MORE_ITEMS) break; else { index++; continue; } } pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf; pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); // if we successfully find the hardware ID and it turns out to // be the one for the loopback driver, then we are done. if (SetupDiGetDriverInfoDetail(hDeviceInfo, &DeviceInfoData, &DriverInfoData, pDriverInfoDetail, sizeof(detailBuf), NULL)) { TCHAR * t; // pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the // whole list and see if there is a match somewhere. t = pDriverInfoDetail->HardwareID; while (t && *t && t < (TCHAR *) &detailBuf[sizeof(detailBuf)/sizeof(detailBuf[0])]) { if (!_tcsicmp(t, DRIVERHWID)) break; t += _tcslen(t) + 1; } if (t && *t && t < (TCHAR *) &detailBuf[sizeof(detailBuf)/sizeof(detailBuf[0])]) { found = TRUE; break; } } index++; } if (!found) { ret = GetLastError(); ReportMessage(0,"Could not find the driver to install", DRIVER_DESC, NULL, 0); goto cleanup; } // set the loopback driver to be the currently selected ok = SetupDiSetSelectedDriver(hDeviceInfo, &DeviceInfoData, &DriverInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // register the phantom device to repare for install ok = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // registered, but remove if errors occur in the following code registered = TRUE; // ask the installer if we can install the device ok = SetupDiCallClassInstaller(DIF_ALLOW_INSTALL, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); if (ret != ERROR_DI_DO_DEFAULT) { goto cleanup; } else ret = 0; } // install the files first ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // get the device install parameters and disable filecopy DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); ok = SetupDiGetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, &DeviceInstallParams); if (ok) { DeviceInstallParams.Flags |= DI_NOFILECOPY; ok = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, &DeviceInstallParams); if (!ok) { ret = GetLastError(); goto cleanup; } } // // Register any device-specific co-installers for this device, // ok = SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // // install any installer-specified interfaces. // and then do the real install // ok = SetupDiCallClassInstaller(DIF_INSTALLINTERFACES, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } PAUSE; ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICE, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); PAUSE; goto cleanup; } /* Skip to the end if we aren't setting the name */ if (!pConnectionName) goto cleanup; // Figure out NetCfgInstanceId hkey = SetupDiOpenDevRegKey(hDeviceInfo, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ); if (hkey == INVALID_HANDLE_VALUE) { ret = GetLastError(); goto cleanup; } cbSize = sizeof(pCfgGuidString); ret = RegQueryValueEx(hkey, _T("NetCfgInstanceId"), NULL, &dwValueType, (LPBYTE)pCfgGuidString, &cbSize); RegCloseKey(hkey); ret = RenameConnection(pCfgGuidString, pConnectionName); if (ret) { ReportMessage(0,"Could not set the connection name", NULL, pConnectionName, 0); goto cleanup; } if (!ip) goto cleanup; ret = SetIpAddress(pCfgGuidString, ip, mask); if (ret) { ReportMessage(0,"Could not set the ip address and network mask",NULL,NULL,ret); goto cleanup; } ret = LoopbackBindings(pCfgGuidString); if (ret) { ReportMessage(0,"Could not properly set the bindings",NULL,NULL,0); goto cleanup; } ret = !UpdateHostsFile( pConnectionName, ip, "hosts", FALSE ); if (ret) { ReportMessage(0,"Could not update hosts file",NULL,NULL,0); goto cleanup; } ret = !UpdateHostsFile( pConnectionName, ip, "lmhosts", TRUE ); if (ret) { ReportMessage(0,"Could not update lmhosts file",NULL,NULL,0); goto cleanup; } cleanup: // an error has occured, but the device is registered, we must remove it if (ret != 0 && registered) SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData); found = SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData); // destroy the driver info list if (destroyList) SetupDiDestroyDriverInfoList(hDeviceInfo, &DeviceInfoData, SPDIT_CLASSDRIVER); // clean up the device info set if (hDeviceInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hDeviceInfo); return ret; };
BOOL CEnumerateSerial::EnumeratePorts() { int SPDRPlist[] = { SPDRP_HARDWAREID, SPDRP_DEVICEDESC, SPDRP_FRIENDLYNAME, SPDRP_MFG, SPDRP_LOCATION_INFORMATION, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, -1}; // Clear anything from previous enumerate... ResetPortList(); // First need to convert the name "Ports" to a GUID using SetupDiClassGuidsFromName... DWORD dwGuids = 0; SetupDiClassGuidsFromName(_T("Ports"), NULL, 0, &dwGuids); if (dwGuids == 0) return FALSE; // Allocate the needed memory... CHeapPtr<GUID> GuidArray; GUID *pGuids = (GUID*)GuidArray.Allocate(sizeof(GUID) * dwGuids); if (pGuids==NULL) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } // Call the function again... if (!SetupDiClassGuidsFromName(_T("Ports"), pGuids, dwGuids, &dwGuids)) return FALSE; // Now create a "device information set" which is required to enumerate all the ports... HDEVINFO hDevInfoSet = SetupDiGetClassDevs(pGuids, NULL, NULL, DIGCF_PRESENT); if (hDevInfoSet == INVALID_HANDLE_VALUE) return FALSE; // Finally do the enumeration... int nIndex = 0; SP_DEVINFO_DATA devInfo; CHeapPtr<TCHAR> tempstr(1000); CSerialPortInfo *portinfo = NULL; // Enumerate the current device... devInfo.cbSize = sizeof(SP_DEVINFO_DATA); while (SetupDiEnumDeviceInfo(hDevInfoSet, nIndex, &devInfo)) { portinfo = NULL; // Get the registry key which stores the ports settings... HKEY hDeviceKey = SetupDiOpenDevRegKey(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); if (hDeviceKey) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; // Read name of port. If formatted as "COMxx" then allocate a port slot... if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, reinterpret_cast<LPBYTE>((TCHAR*)tempstr), &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ)) if (_tcslen(tempstr) > 3) if ((_tcsnicmp(tempstr, _T("COM"), 3) == 0) && IsNumber(&(tempstr[3]))) portinfo = AddPort(_ttoi(&(tempstr[3]))); // Close the key now that we are finished with it... RegCloseKey(hDeviceKey); } // If a serial port, then try getting additional useful descriptive info... if (portinfo) { for (int i=0; SPDRPlist[i]>=0; i++) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRPlist[i], &dwType, reinterpret_cast<PBYTE>((TCHAR*)tempstr), dwSize, &dwSize) && ((dwType == REG_SZ) || (dwType == REG_MULTI_SZ))) switch (SPDRPlist[i]) { case SPDRP_MFG : portinfo->SetManufacturer(tempstr); break; case SPDRP_HARDWAREID : portinfo->SetHardwareID(tempstr); break; case SPDRP_DEVICEDESC : portinfo->SetDeviceDesc(tempstr); break; case SPDRP_FRIENDLYNAME : portinfo->SetFriendlyName(tempstr); break; case SPDRP_LOCATION_INFORMATION : portinfo->SetLocationInfo(tempstr); break; case SPDRP_PHYSICAL_DEVICE_OBJECT_NAME : portinfo->SetPhysLocation(tempstr); break; } } // Get COM port properties... HANDLE hPort = ::CreateFile(portinfo->GetPortDeviceName(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (hPort != INVALID_HANDLE_VALUE) { COMMPROP cp; GetCommProperties(hPort, &cp); portinfo->SetCommProp(cp); TRACE ("Port %d: CommProp: maxbaud=%08x settablebaud=%08x\n",portinfo->GetPortNum(),cp.dwMaxBaud,cp.dwSettableBaud); CloseHandle(hPort); } } ++nIndex; } // Free up the "device information set" now that we are finished with it SetupDiDestroyDeviceInfoList(hDevInfoSet); // Return the success indicator return TRUE; }
BOOL SetFilterAffinityMask( HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData, DWORD affinityMask ) { HKEY hkeyDeviceParams; LONG lRetVal; BOOL fToReturn = TRUE; // success // // Get a handle to the device's "Device Parameters" registry subkey // hkeyDeviceParams = SetupDiOpenDevRegKey( hDevInfo, pDevInfoData, DICS_FLAG_GLOBAL, //CPRINCE: SHOULD (CAN?) USE 'DICS_FLAG_CONFIGSPECIFIC' INSTEAD ??? 0, DIREG_DEV, KEY_WRITE // desired access ); if( INVALID_HANDLE_VALUE == hkeyDeviceParams ) { // Error opening device registry key... // // If error occurred because "Device Parameters" sub-key does // not exist, then try to create that sub-key. // NOTE: when we call GetLastError() here, we're getting an invalid // error code. So let's just _assume_ (yeah, I know) that the error // was because the key does not exist, and try to create it here. hkeyDeviceParams = SetupDiCreateDevRegKey( hDevInfo, pDevInfoData, DICS_FLAG_GLOBAL, //CPRINCE: SHOULD (CAN?) USE 'DICS_FLAG_CONFIGSPECIFIC' INSTEAD ??? 0, DIREG_DEV, NULL, NULL ); if( INVALID_HANDLE_VALUE == hkeyDeviceParams ) { // OK, we can't open and can't create the key. Let's // face it, we've failed, so return now. //MessageBox_FromErrorCode( GetLastError() ); return FALSE; } //ELSE: we were able to create the key, so keep going... } // // Set the desired registry value // lRetVal = RegSetValueEx( hkeyDeviceParams, FILTER_REGISTRY_VALUE, 0, REG_DWORD, (BYTE*)&affinityMask, sizeof(DWORD) ); if( ERROR_SUCCESS != lRetVal ) { //MessageBox_FromErrorCode( lRetVal ); fToReturn = FALSE; // failure } // // Close the registry key(s) we opened // lRetVal = RegCloseKey( hkeyDeviceParams ); if( ERROR_SUCCESS != lRetVal ) { //MessageBox_FromErrorCode( lRetVal ); fToReturn = FALSE; // failure } return fToReturn; }
BOOL GetFilterAffinityMask( HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData, DWORD* pAffinityMask ) { HKEY hkeyDeviceParams; LONG lRetVal; BOOL fToReturn = TRUE; // success DWORD regValueType; DWORD regValueSize; ASSERT( NULL != pAffinityMask ); // // Get a handle to the device's "Device Parameters" registry subkey // hkeyDeviceParams = SetupDiOpenDevRegKey( hDevInfo, pDevInfoData, DICS_FLAG_GLOBAL, //CPRINCE: SHOULD (CAN?) USE 'DICS_FLAG_CONFIGSPECIFIC' INSTEAD ??? 0, DIREG_DEV, KEY_QUERY_VALUE // desired access ); if( INVALID_HANDLE_VALUE == hkeyDeviceParams ) { // Probably just means that the "Device Parameters" subkey // does not exist, so return, but _don't_ display error message. return FALSE; // failure } // // Get the desired registry value // regValueSize = sizeof(DWORD); lRetVal = RegQueryValueEx( hkeyDeviceParams, FILTER_REGISTRY_VALUE, 0, ®ValueType, (BYTE*)pAffinityMask, ®ValueSize ); if( ERROR_SUCCESS != lRetVal ) { if( ERROR_FILE_NOT_FOUND == lRetVal ) { // Just means key didn't already exist. // So don't display error message. } else { //MessageBox_FromErrorCode( lRetVal ); } fToReturn = FALSE; // failure } else if( REG_DWORD != regValueType ) { fToReturn = FALSE; // failure } // // Close the registry key(s) we opened // lRetVal = RegCloseKey( hkeyDeviceParams ); if( ERROR_SUCCESS != lRetVal ) { //MessageBox_FromErrorCode( lRetVal ); fToReturn = FALSE; // failure } return fToReturn; }
/*++ Routine Description: FillPortSettingsDlg fill in the port settings dlg sheet Arguments: params: the data to fill in hDlg: address of the window Return Value: ULONG: returns error messages --*/ ULONG FillPortSettingsDlg( IN HWND DialogHwnd, IN PPORT_PARAMS Params ) { HKEY hDeviceKey; DWORD dwPortNameSize, dwError; TCHAR szCharBuffer[81]; // // Open the device key for the source device instance, and retrieve its // "PortName" value. // hDeviceKey = SetupDiOpenDevRegKey(Params->DeviceInfoSet, Params->DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if (INVALID_HANDLE_VALUE == hDeviceKey) { goto RetGetLastError; } dwPortNameSize = sizeof(Params->PortSettings.szComName); dwError = RegQueryValueEx(hDeviceKey, m_szPortName, // "PortName" NULL, NULL, (PBYTE)Params->PortSettings.szComName, &dwPortNameSize); RegCloseKey(hDeviceKey); if(ERROR_SUCCESS != dwError) { goto RetERROR; } // // create "com#:" // StringCchCopy(szCharBuffer, ARRAYSIZE(szCharBuffer), Params->PortSettings.szComName); StringCchCat(szCharBuffer, ARRAYSIZE(szCharBuffer), m_szColon); // // get values from system, fills in baudrate, parity, etc. // GetPortSettings(DialogHwnd, szCharBuffer, Params); if (!Params->ChangesEnabled) { EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_BAUDRATE), FALSE); EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_PARITY), FALSE); EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_DATABITS), FALSE); EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_STOPBITS), FALSE); EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_FLOWCTL), FALSE); } return 0; RetERROR: return dwError; RetGetLastError: return GetLastError(); } /* FillPortSettingsDlg */
BOOL ComPortDiscovery::QueryUsingSetupAPI(const GUID& guid, WORD dwFlags, CPortsArray& ports, CNamesArray& friendlyNames) { //Set our output parameters to sane defaults ports.clear(); friendlyNames.clear(); //Create a "device information set" for the specified GUID HDEVINFO hDevInfoSet = SetupDiGetClassDevs(&guid, NULL, NULL, dwFlags); if (hDevInfoSet == INVALID_HANDLE_VALUE) return FALSE; //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 = SetupDiEnumDeviceInfo(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 ATL::CRegKey deviceKey; deviceKey.Attach(SetupDiOpenDevRegKey(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE)); if (deviceKey != INVALID_HANDLE_VALUE) { int nPort = 0; if (QueryRegistryPortName(deviceKey, nPort)) { ports.push_back(nPort); bAdded = TRUE; } } //If the port was a serial port, then also try to get its friendly name if (bAdded) { ATL::CHeapPtr<BYTE> byFriendlyName; if (QueryDeviceDescription(hDevInfoSet, devInfo, byFriendlyName)) { friendlyNames.push_back(reinterpret_cast<LPCTSTR>(byFriendlyName.m_pData)); } else { friendlyNames.push_back(_T("")); } } } ++nIndex; } //Free up the "device information set" now that we are finished with it SetupDiDestroyDeviceInfoList(hDevInfoSet); //Return the success indicator return TRUE; }
/*static*/ std::string SuperCardProWin32::GetDevicePath () { std::string path; HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, nullptr, nullptr, DIGCF_PRESENT); if (hDevInfo != INVALID_HANDLE_VALUE) { for (int i = 0; ; ++i) { char szInstanceId[256]; SP_DEVINFO_DATA DevInfoData = { sizeof(DevInfoData) }; if (SetupDiEnumDeviceInfo(hDevInfo, i, &DevInfoData) && SetupDiGetDeviceInstanceId(hDevInfo, &DevInfoData, szInstanceId, sizeof(szInstanceId), nullptr)) { if (!strstr(szInstanceId, "SCP-JIM")) continue; HKEY hkey = SetupDiOpenDevRegKey(hDevInfo, &DevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if (hkey != INVALID_HANDLE_VALUE) { char szPort[256]; DWORD dwType = REG_SZ, dwSize = sizeof(szPort) / 2; if (SUCCEEDED(RegQueryValueEx(hkey, "PortName", nullptr, &dwType, (PBYTE)szPort, &dwSize))) path = std::string(R"(\\.\)") + szPort; RegCloseKey(hkey); break; } } else if (GetLastError() == ERROR_NO_MORE_ITEMS) break; } SetupDiDestroyDeviceInfoList(hDevInfo); } return path; } /*static*/ std::unique_ptr<SuperCardPro> SuperCardProWin32::Open () { std::string path = GetDevicePath(); if (!path.empty()) { HANDLE h = CreateFile(path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); if (h != INVALID_HANDLE_VALUE) { DCB dcb = { sizeof(dcb) }; if (BuildCommDCB("baud=9600 parity=N data=8 stop=1", &dcb) && SetCommState(h, &dcb)) return std::unique_ptr<SuperCardPro>(new SuperCardProWin32(h)); } } return std::unique_ptr<SuperCardPro>(); } SuperCardProWin32::SuperCardProWin32 (HANDLE hdev) : m_hdev(hdev), m_dwError(ERROR_SUCCESS) { } SuperCardProWin32::~SuperCardProWin32 () { CloseHandle(m_hdev); } bool SuperCardProWin32::Read (void *p, int len, int *bytes_read) { DWORD dwBytesRead = 0; if (!ReadFile(m_hdev, p, static_cast<DWORD>(len), &dwBytesRead, nullptr)) { m_dwError = GetLastError(); return false; } *bytes_read = static_cast<int>(dwBytesRead); return true; }
BOOL FindCurrentDriver(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo, _In_ PSP_DRVINFO_DATA DriverInfoData) /*++ Routine Description: Find the driver that is associated with the current device We can do this either the quick way (available in WinXP) or the long way that works in Win2k. Arguments: Devs )_ uniquely identify device DevInfo ) Return Value: TRUE if we managed to determine and select current driver --*/ { SP_DEVINSTALL_PARAMS deviceInstallParams; WCHAR SectionName[LINE_LEN]; WCHAR DrvDescription[LINE_LEN]; WCHAR MfgName[LINE_LEN]; WCHAR ProviderName[LINE_LEN]; HKEY hKey = NULL; DWORD RegDataLength; DWORD RegDataType; DWORD c; BOOL match = FALSE; long regerr; ZeroMemory(&deviceInstallParams, sizeof(deviceInstallParams)); deviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if(!SetupDiGetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams)) { return FALSE; } #ifdef DI_FLAGSEX_INSTALLEDDRIVER // // Set the flags that tell SetupDiBuildDriverInfoList to just put the // currently installed driver node in the list, and that it should allow // excluded drivers. This flag introduced in WinXP. // deviceInstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS); if(SetupDiSetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams)) { // // we were able to specify this flag, so proceed the easy way // we should get a list of no more than 1 driver // if(!SetupDiBuildDriverInfoList(Devs, DevInfo, SPDIT_CLASSDRIVER)) { return FALSE; } if (!SetupDiEnumDriverInfo(Devs, DevInfo, SPDIT_CLASSDRIVER, 0, DriverInfoData)) { return FALSE; } // // we've selected the current driver // return TRUE; } deviceInstallParams.FlagsEx &= ~(DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS); #endif // // The following method works in Win2k, but it's slow and painful. // // First, get driver key - if it doesn't exist, no driver // hKey = SetupDiOpenDevRegKey(Devs, DevInfo, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ ); if(hKey == INVALID_HANDLE_VALUE) { // // no such value exists, so there can't be an associated driver // RegCloseKey(hKey); return FALSE; } // // obtain path of INF - we'll do a search on this specific INF // RegDataLength = sizeof(deviceInstallParams.DriverPath); // bytes!!! regerr = RegQueryValueEx(hKey, REGSTR_VAL_INFPATH, NULL, &RegDataType, (PBYTE)deviceInstallParams.DriverPath, &RegDataLength ); if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) { // // no such value exists, so no associated driver // RegCloseKey(hKey); return FALSE; } // // obtain name of Provider to fill into DriverInfoData // RegDataLength = sizeof(ProviderName); // bytes!!! regerr = RegQueryValueEx(hKey, REGSTR_VAL_PROVIDER_NAME, NULL, &RegDataType, (PBYTE)ProviderName, &RegDataLength ); if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) { // // no such value exists, so we don't have a valid associated driver // RegCloseKey(hKey); return FALSE; } // // obtain name of section - for final verification // RegDataLength = sizeof(SectionName); // bytes!!! regerr = RegQueryValueEx(hKey, REGSTR_VAL_INFSECTION, NULL, &RegDataType, (PBYTE)SectionName, &RegDataLength ); if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) { // // no such value exists, so we don't have a valid associated driver // RegCloseKey(hKey); return FALSE; } // // driver description (need not be same as device description) // - for final verification // RegDataLength = sizeof(DrvDescription); // bytes!!! regerr = RegQueryValueEx(hKey, REGSTR_VAL_DRVDESC, NULL, &RegDataType, (PBYTE)DrvDescription, &RegDataLength ); RegCloseKey(hKey); if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) { // // no such value exists, so we don't have a valid associated driver // return FALSE; } // // Manufacturer (via SPDRP_MFG, don't access registry directly!) // if(!SetupDiGetDeviceRegistryProperty(Devs, DevInfo, SPDRP_MFG, NULL, // datatype is guaranteed to always be REG_SZ. (PBYTE)MfgName, sizeof(MfgName), // bytes!!! NULL)) { // // no such value exists, so we don't have a valid associated driver // return FALSE; } // // now search for drivers listed in the INF // // deviceInstallParams.Flags |= DI_ENUMSINGLEINF; deviceInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS; if(!SetupDiSetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams)) { return FALSE; } if(!SetupDiBuildDriverInfoList(Devs, DevInfo, SPDIT_CLASSDRIVER)) { return FALSE; } // // find the entry in the INF that was used to install the driver for // this device // for(c=0;SetupDiEnumDriverInfo(Devs,DevInfo,SPDIT_CLASSDRIVER,c,DriverInfoData);c++) { if((_tcscmp(DriverInfoData->MfgName,MfgName)==0) &&(_tcscmp(DriverInfoData->ProviderName,ProviderName)==0)) { // // these two fields match, try more detailed info // to ensure we have the exact driver entry used // SP_DRVINFO_DETAIL_DATA detail; detail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); if(!SetupDiGetDriverInfoDetail(Devs,DevInfo,DriverInfoData,&detail,sizeof(detail),NULL) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) { continue; } if((_tcscmp(detail.SectionName,SectionName)==0) && (_tcscmp(detail.DrvDescription,DrvDescription)==0)) { match = TRUE; break; } } } if(!match) { SetupDiDestroyDriverInfoList(Devs,DevInfo,SPDIT_CLASSDRIVER); } return match; }
/*++ Routine Description: LptFillPortSettings Gets the settings out of the registry ready for initializing the dialog box with. Arguments: LptPropPageData: the data to fill in ParentHwnd: address of the window Return Value: ULONG: returns error messages --*/ ULONG LptFillPortSettings( IN HWND ParentHwnd, IN PLPT_PROP_PARAMS LptPropPageData ) { HKEY hKey; DWORD dwPortNameSize, dwError; TCHAR szCharBuffer[81]; DWORD dwSize; UNREFERENCED_PARAMETER(ParentHwnd); // // Open the device key for the source device instance, and retrieve its // "PortName" value. // hKey = SetupDiOpenDevRegKey(LptPropPageData->DeviceInfoSet, LptPropPageData->DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ | KEY_WRITE); if (INVALID_HANDLE_VALUE == hKey) { return GetLastError(); } dwPortNameSize = sizeof(LptPropPageData->szLptName); dwError = RegQueryValueEx(hKey, m_szPortName, // "PortName" NULL, NULL, (PBYTE)LptPropPageData->szLptName, &dwPortNameSize); if(ERROR_SUCCESS != dwError) { RegCloseKey(hKey); return dwError; } // // create "lpt#:" // StringCchCopy(szCharBuffer, ARRAYSIZE(szCharBuffer), LptPropPageData->szLptName); StringCchCat(szCharBuffer, ARRAYSIZE(szCharBuffer), m_szColon); dwSize = sizeof(LptPropPageData->FilterResourceMethod); dwError = RegQueryValueEx(hKey, m_szFilterResourceMethod, NULL, NULL, (LPBYTE)(&LptPropPageData->FilterResourceMethod), &dwSize); if (dwError != ERROR_SUCCESS) { // // value does not exist. Create our own: // Get Filter Resource Method information // LptPropPageData->FilterResourceMethod = FilterResourceMethods[RESOURCE_METHOD_DEFAULT_IDX]; RegSetValueEx(hKey, m_szFilterResourceMethod, 0, REG_DWORD, (LPBYTE)(&LptPropPageData->FilterResourceMethod), sizeof(LptPropPageData->FilterResourceMethod)); } RegCloseKey(hKey); dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_szParEnableLegacyZipRegPath, 0, KEY_READ | KEY_WRITE, &hKey); if (dwError != ERROR_SUCCESS) { // // Don't have access maybe? // LptPropPageData->ParEnableLegacyZip = ENABLELEGACYZIPDEFAULT; return dwError; } dwSize = sizeof(LptPropPageData->ParEnableLegacyZip); dwError = RegQueryValueEx(hKey, TEXT("ParEnableLegacyZip"), NULL, NULL, (LPBYTE)(&LptPropPageData->ParEnableLegacyZip), &dwSize); if (dwError != ERROR_SUCCESS) { // // value does not exist. Create our own // LptPropPageData->ParEnableLegacyZip = ENABLELEGACYZIPDEFAULT; dwError = RegSetValueEx(hKey, m_szParEnableLegacyZip, 0, REG_DWORD, (LPBYTE)(&LptPropPageData->ParEnableLegacyZip), sizeof(LptPropPageData->ParEnableLegacyZip)); } RegCloseKey(hKey); return dwError; } // LptFillPortSettings
/*++ Routine Description: LptSavePortSettings saves the advanced box settings back to the registry, if any were changed Arguments: AdvancedData: holds the current settings and the location of of the device in the registry ParentHwnd: address of the window Return Value: ULONG: returns error messages --*/ ULONG LptSavePortSettings( IN HWND ParentHwnd, IN PLPT_PROP_PARAMS LptPropParams ) { HKEY hKey; DWORD dwSize, dwData; UINT curLptNum, newLptNum = (UINT)CB_ERR; DWORD curFilterResourceMethod; DWORD newFilterResourceMethod = 0; DWORD curParEnableLegacyZip, newParEnableLegacyZip; ULONG error = ERROR_SUCCESS; // // Grab all of the new settings // // Filter resource method curFilterResourceMethod = newFilterResourceMethod = LptPropParams->FilterResourceMethod; if (BST_CHECKED == IsDlgButtonChecked(ParentHwnd, IDC_FILTERMETHOD_TRYNOT)) newFilterResourceMethod = 0; else if (BST_CHECKED == IsDlgButtonChecked(ParentHwnd, IDC_FILTERMETHOD_NEVER)) newFilterResourceMethod = 1; else if (BST_CHECKED == IsDlgButtonChecked(ParentHwnd, IDC_FILTERMETHOD_ACCEPTANY)) newFilterResourceMethod = 2; // LPT port number curLptNum = myatoi(LptPropParams->szLptName + wcslen(m_szLPT)); newLptNum = ComboBox_GetCurSel(GetDlgItem(ParentHwnd, PP_LPT_PORT_NUMBER)); if (newLptNum == CB_ERR) { newLptNum = curLptNum; } else { newLptNum++; } // Legacy device detection curParEnableLegacyZip = LptPropParams->ParEnableLegacyZip; if (BST_CHECKED == IsDlgButtonChecked(ParentHwnd, IDC_LPT_ENABLE_LEGACY)) { newParEnableLegacyZip = 0x1; } else { newParEnableLegacyZip = 0x0; } // // See if they changed anything // if ((curLptNum == newLptNum) && (curFilterResourceMethod == newFilterResourceMethod) && (curParEnableLegacyZip == newParEnableLegacyZip)) { // // They didn't change anything. Just exit. // return ERROR_SUCCESS; } // // Open the device key for the source device instance // hKey = SetupDiOpenDevRegKey(LptPropParams->DeviceInfoSet, LptPropParams->DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ | KEY_WRITE); if (INVALID_HANDLE_VALUE == hKey) { // // Not much we can do, just exit gracefully // return ERROR_SUCCESS; } // Check the LPT port name for changes if (newLptNum != curLptNum) { LptEnactPortNameChanges(ParentHwnd, LptPropParams, hKey, newLptNum); } // Check the Filter resource method for changes if (curFilterResourceMethod != newFilterResourceMethod) { // // They changed the Filter Resource Method // dwData = newFilterResourceMethod; dwSize = sizeof(dwData); RegSetValueEx(hKey, m_szFilterResourceMethod, 0, REG_DWORD, (CONST BYTE *)(&dwData), dwSize); } RegCloseKey(hKey); if (curParEnableLegacyZip != newParEnableLegacyZip) { // // Open the services path and set the new value for Legacy Parallel device // detection. // DWORD disposition = 0; error = RegCreateKeyEx(HKEY_LOCAL_MACHINE, m_szParEnableLegacyZipRegPath, 0, (TCHAR *) NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, (LPSECURITY_ATTRIBUTES) NULL, &hKey, &disposition); if (error == ERROR_SUCCESS) { error = RegSetValueEx(hKey, m_szParEnableLegacyZip, 0, REG_DWORD, (LPBYTE)(&newParEnableLegacyZip), sizeof(newParEnableLegacyZip)); RegCloseKey(hKey); if (error != ERROR_SUCCESS) { goto ParEnableLegacyZipSetParamFailed; } if (newParEnableLegacyZip == 0) { // // We want a reboot when disabling this thing, because the parallel // enumerator won't get rid of legacy devices. // InformDriverOfChanges(TRUE, LptPropParams); } else { InformDriverOfChanges(FALSE, LptPropParams); } } else { ParEnableLegacyZipSetParamFailed: MyMessageBox(ParentHwnd, IDS_LPT_LEGACY_FAILED, IDS_LPT_PROPERTIES, MB_OK); // // Don't want to overload the user by telling them they have to // reboot. Since we were unable to set things correctly, just // rebuild the stack. // InformDriverOfChanges(FALSE, LptPropParams); } } else { InformDriverOfChanges(FALSE, LptPropParams); } return error; } // LptSaveAdvancedSettings
//static void QextSerialEnumerator::setupAPIScan(QList<QextPortInfo> & infoList) { HDEVINFO devInfo = INVALID_HANDLE_VALUE; GUID * guidDev = (GUID *) & GUID_CLASS_COMPORT; devInfo = SetupDiGetClassDevs(guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(devInfo == INVALID_HANDLE_VALUE) { qCritical("SetupDiGetClassDevs failed. Error code: %ld", GetLastError()); return; } //enumerate the devices bool ok = true; SP_DEVICE_INTERFACE_DATA ifcData; ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); SP_DEVICE_INTERFACE_DETAIL_DATA * detData = NULL; DWORD detDataSize = 0; DWORD oldDetDataSize = 0; for (DWORD i = 0; ok; i++) { ok = SetupDiEnumDeviceInterfaces(devInfo, NULL, guidDev, i, &ifcData); if (ok) { SP_DEVINFO_DATA devData = {sizeof(SP_DEVINFO_DATA)}; //check for required detData size SetupDiGetDeviceInterfaceDetail(devInfo, & ifcData, NULL, 0, & detDataSize, & devData); //if larger than old detData size then reallocate the buffer if (detDataSize > oldDetDataSize) { delete [] detData; detData = (SP_DEVICE_INTERFACE_DETAIL_DATA *) new char[detDataSize]; detData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); oldDetDataSize = detDataSize; } //check the details if (SetupDiGetDeviceInterfaceDetail(devInfo, & ifcData, detData, detDataSize, NULL, & devData)) { // Got a device. Get the details. QextPortInfo info; info.friendName = getDeviceProperty(devInfo, & devData, SPDRP_FRIENDLYNAME); info.physName = getDeviceProperty(devInfo, & devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME); info.enumName = getDeviceProperty(devInfo, & devData, SPDRP_ENUMERATOR_NAME); //anyway, to get the port name we must still open registry directly :( ??? //Eh... HKEY devKey = SetupDiOpenDevRegKey(devInfo, & devData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); info.portName = getRegKeyValue(devKey, TEXT("PortName")); RegCloseKey(devKey); infoList.append(info); } else { qCritical("SetupDiGetDeviceInterfaceDetail failed. Error code: %ld", GetLastError()); delete [] detData; return; } } else { if (GetLastError() != ERROR_NO_MORE_ITEMS) { delete [] detData; qCritical("SetupDiEnumDeviceInterfaces failed. Error code: %ld", GetLastError()); return; } } } delete [] detData; }
UINT LptEnactPortNameChanges( IN HWND ParentHwnd, IN PLPT_PROP_PARAMS LptPropParams, IN HKEY hDeviceKey, IN UINT NewLptNum) { HANDLE hLpt; DWORD dwError, dwNewLptNameLen; BYTE portUsage[MAX_LPT_PORT]; TCHAR charBuffer[LINE_LEN], friendlyNameFormat[LINE_LEN], deviceDesc[LINE_LEN], buffer[BUFFER_SIZE], szNewLptName[20]; // // Check if we're trying to rename the port to the same name. // StringCchPrintf(szNewLptName, ARRAYSIZE(szNewLptName), _T("\\DosDevices\\LPT%d"), NewLptNum); if (wcscmp(szNewLptName, LptPropParams->szLptName) == 0) { return ERROR_SUCCESS; } // // Check if a valid port number has been passed in // if (MAX_LPT_PORT < NewLptNum) { // // Get out of here - exceeding array bounds // This should never happen in the property page since it is a hardcoded // selection box. The user can't simply type a number. // MyMessageBox(ParentHwnd, IDS_LPT_NUM_ERROR, IDS_LPT_PROPERTIES, MB_OK | MB_ICONINFORMATION); return ERROR_SUCCESS; } // // Get an array of used ports // LptEnumerateUsedPorts(ParentHwnd, portUsage, MAX_LPT_PORT); if (portUsage[NewLptNum-1]) { // // Port name is taken by another port. Check if user wants system to // get into inconsistent state. // if (IDNO == MyMessageBox(ParentHwnd, IDS_LPT_PORT_INUSE, IDS_LPT_PROPERTIES, MB_YESNO | MB_ICONINFORMATION)) { return ERROR_SUCCESS; } } // // Make sure that the port has not been opened by another application // StringCchPrintf(buffer, ARRAYSIZE(buffer), L"\\\\.\\%ws", LptPropParams->szLptName); hLpt = CreateFile(buffer, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // // If the file handle is invalid, then the Lpt port is open, warn the user // if (hLpt == INVALID_HANDLE_VALUE && MyMessageBox(ParentHwnd, IDS_PORT_OPEN, IDS_LPT_PROPERTIES, MB_YESNO | MB_ICONINFORMATION) == IDNO) { return GetLastError(); } CloseHandle(hLpt); StringCchPrintf(szNewLptName, ARRAYSIZE(szNewLptName), _T("LPT%d"), NewLptNum); // // Open the device key for the source device instance, and write its // new "PortName" value. // hDeviceKey = SetupDiOpenDevRegKey(LptPropParams->DeviceInfoSet, LptPropParams->DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ | KEY_WRITE); if (INVALID_HANDLE_VALUE == hDeviceKey) { return GetLastError(); } dwNewLptNameLen = ByteCountOf((DWORD)wcslen(szNewLptName) + 1); dwError = RegSetValueEx(hDeviceKey, m_szPortName, 0, REG_SZ, (PBYTE) szNewLptName, dwNewLptNameLen); if (ERROR_SUCCESS == dwError) { StringCchCopy(LptPropParams->szLptName, ARRAYSIZE(LptPropParams->szLptName), szNewLptName); } else { return dwError; } // Now generate a string, to be used for the device's friendly name, that // incorporates both the INF-specified device description, and the port // name. For example, // // ECP Printer Port (LPT1) // // If we can load the device description and the localized friendly format, // then compose the two // If we can only load the device description, then use that as the friendly name // If we can't load either, put a non localized string in there charBuffer[0] = L'\0'; if( SetupDiGetDeviceRegistryProperty(LptPropParams->DeviceInfoSet, LptPropParams->DeviceInfoData, SPDRP_DEVICEDESC, NULL, (PBYTE)deviceDesc, sizeof(deviceDesc), NULL)) { if (LoadString(g_hInst, IDS_FRIENDLY_FORMAT, friendlyNameFormat, ARRAYSIZE(friendlyNameFormat))) { StringCchPrintf(charBuffer, ARRAYSIZE(charBuffer), friendlyNameFormat, deviceDesc, szNewLptName); } else { StringCchCopy(charBuffer, ARRAYSIZE(charBuffer), deviceDesc); } } else { // // Simply use LPT port name. // StringCchCopy(charBuffer, ARRAYSIZE(charBuffer), szNewLptName); } SetupDiSetDeviceRegistryProperty(LptPropParams->DeviceInfoSet, LptPropParams->DeviceInfoData, SPDRP_FRIENDLYNAME, (PBYTE)charBuffer, ByteCountOf(lstrlen(charBuffer) + 1) ); return ERROR_SUCCESS; } // LptEnactPortNameChanges
//static void QextSerialEnumerator::setupAPIScan(QList<QextPortInfo> & infoList) { HDEVINFO devInfo = INVALID_HANDLE_VALUE; DWORD dwGuids = 0; SetupDiClassGuidsFromName(TEXT("Ports"), NULL, 0, &dwGuids); if (dwGuids == 0) { qCritical("SetupDiClassGuidsFromName failed. Error code: %ld", GetLastError()); return; } GUID *pGuids = new GUID[dwGuids]; if (!SetupDiClassGuidsFromName(TEXT("Ports"), pGuids, dwGuids, &dwGuids)) { qCritical("SetupDiClassGuidsFromName second call failed. Error code: %ld", GetLastError()); return; } devInfo = SetupDiGetClassDevs(pGuids, NULL, NULL, DIGCF_PRESENT); if(devInfo == INVALID_HANDLE_VALUE) { qCritical("SetupDiGetClassDevs failed. Error code: %ld", GetLastError()); return; } //enumerate the devices bool ok = true; SP_DEVICE_INTERFACE_DATA ifcData; ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); SP_DEVICE_INTERFACE_DETAIL_DATA * detData = NULL; SP_DEVINFO_DATA devData = {sizeof(SP_DEVINFO_DATA)}; for (DWORD i = 0; ok; i++) { ok = SetupDiEnumDeviceInfo(devInfo, i, &devData); if (ok) { // Got a device. Get the details. QextPortInfo info; info.friendName = getDeviceProperty(devInfo, & devData, SPDRP_FRIENDLYNAME); info.physName = getDeviceProperty(devInfo, & devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME); info.enumName = getDeviceProperty(devInfo, & devData, SPDRP_ENUMERATOR_NAME); //anyway, to get the port name we must still open registry directly :( ??? //Eh... HKEY devKey = SetupDiOpenDevRegKey(devInfo, & devData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); info.portName = getRegKeyValue(devKey, TEXT("PortName")); RegCloseKey(devKey); if(info.portName.startsWith("COM")) { infoList.append(info); } } else { if (GetLastError() != ERROR_NO_MORE_ITEMS) { delete [] detData; qCritical("SetupDiEnumDeviceInfo failed. Error code: %ld", GetLastError()); return; } } } delete [] detData; delete[] pGuids; }
static DWORD InstallNetDevice( IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, LPCWSTR UuidString, DWORD Characteristics, LPCWSTR BusType) { LPWSTR InstanceId = NULL; LPWSTR DeviceName = NULL; LPWSTR ExportName = NULL; LONG rc; HKEY hKey = NULL; HKEY hNetworkKey = NULL; HKEY hLinkageKey = NULL; HKEY hConnectionKey = NULL; DWORD dwShowIcon, dwLength, dwValue; WCHAR szBuffer[300]; /* Get Instance ID */ if (SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, NULL, 0, &dwLength)) { DPRINT("SetupDiGetDeviceInstanceIdW() returned TRUE. FALSE expected\n"); rc = ERROR_GEN_FAILURE; goto cleanup; } InstanceId = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR)); if (!InstanceId) { DPRINT("HeapAlloc() failed\n"); rc = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } if (!SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, InstanceId, dwLength, NULL)) { rc = GetLastError(); DPRINT("SetupDiGetDeviceInstanceIdW() failed with error 0x%lx\n", rc); goto cleanup; } /* Create device name */ DeviceName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); if (!DeviceName) { DPRINT("HeapAlloc() failed\n"); rc = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } wcscpy(DeviceName, L"\\Device\\"); wcscat(DeviceName, UuidString); /* Create export name */ ExportName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\Tcpip_") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); if (!ExportName) { DPRINT("HeapAlloc() failed\n"); rc = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } wcscpy(ExportName, L"\\Device\\Tcpip_"); wcscat(ExportName, UuidString); /* Write Tcpip parameters in new service Key */ rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services", 0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegCreateKeyExW(hKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hNetworkKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } RegCloseKey(hKey); hKey = NULL; rc = RegCreateKeyExW(hNetworkKey, L"Parameters\\Tcpip", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } RegCloseKey(hNetworkKey); hNetworkKey = NULL; rc = RegSetValueExW(hKey, L"DefaultGateway", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hKey, L"IPAddress", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hKey, L"SubnetMask", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } dwValue = 1; rc = RegSetValueExW(hKey, L"EnableDHCP", 0, REG_DWORD, (const BYTE*)&dwValue, sizeof(DWORD)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } RegCloseKey(hKey); hKey = NULL; /* Write 'Linkage' key in hardware key */ #if _WIN32_WINNT >= 0x502 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE); #else hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS); #endif if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND) hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL); if (hKey == INVALID_HANDLE_VALUE) { hKey = NULL; rc = GetLastError(); DPRINT("SetupDiCreateDevRegKeyW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hKey, L"NetCfgInstanceId", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hKey, L"Characteristics", 0, REG_DWORD, (const BYTE*)&Characteristics, sizeof(DWORD)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } if (BusType) rc = RegSetValueExW(hKey, L"BusType", 0, REG_SZ, (const BYTE*)BusType, (wcslen(BusType) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegCreateKeyExW(hKey, L"Linkage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hLinkageKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hLinkageKey, L"Export", 0, REG_SZ, (const BYTE*)DeviceName, (wcslen(DeviceName) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hLinkageKey, L"RootDevice", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hLinkageKey, L"UpperBind", 0, REG_SZ, (const BYTE*)L"Tcpip", (wcslen(L"Tcpip") + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } RegCloseKey(hKey); hKey = NULL; /* Write connection information in network subkey */ rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hNetworkKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegCreateKeyExW(hNetworkKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegCreateKeyExW(hKey, L"Connection", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hConnectionKey, NULL); RegCloseKey(hKey); hKey = NULL; if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } if (!LoadStringW(netcfgx_hInstance, IDS_NET_CONNECT, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) { wcscpy(szBuffer,L"Network connection"); } rc = RegSetValueExW(hConnectionKey, L"Name", 0, REG_SZ, (const BYTE*)szBuffer, (wcslen(szBuffer) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hConnectionKey, L"PnpInstanceId", 0, REG_SZ, (const BYTE*)InstanceId, (wcslen(InstanceId) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } dwShowIcon = 1; rc = RegSetValueExW(hConnectionKey, L"ShowIcon", 0, REG_DWORD, (const BYTE*)&dwShowIcon, sizeof(dwShowIcon)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } /* Write linkage information in Tcpip service */ rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = AppendStringToMultiSZ(hKey, L"Bind", DeviceName); if (rc != ERROR_SUCCESS) { DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); goto cleanup; } rc = AppendStringToMultiSZ(hKey, L"Export", ExportName); if (rc != ERROR_SUCCESS) { DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); goto cleanup; } rc = AppendStringToMultiSZ(hKey, L"Route", UuidString); if (rc != ERROR_SUCCESS) { DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); goto cleanup; } /* Install additionnal services */ rc = InstallAdditionalServices(NULL); if (rc != ERROR_SUCCESS) { DPRINT("InstallAdditionalServices() failed with error 0x%lx\n", rc); goto cleanup; } rc = ERROR_SUCCESS; cleanup: HeapFree(GetProcessHeap(), 0, InstanceId); HeapFree(GetProcessHeap(), 0, DeviceName); HeapFree(GetProcessHeap(), 0, ExportName); if (hKey != NULL) RegCloseKey(hKey); if (hNetworkKey != NULL) RegCloseKey(hNetworkKey); if (hLinkageKey != NULL) RegCloseKey(hLinkageKey); if (hConnectionKey != NULL) RegCloseKey(hConnectionKey); return rc; }
void EnumSerialPortsWindows(std::vector<SerialPortInfo> &serialports) { // 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) { return; } // 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) { std::string strDevPath(pDetData->DevicePath); // Got a path to the device. Try to get some more info. TCHAR fname[256]; TCHAR desc[256]; BOOL bSuccess = SetupDiGetDeviceRegistryProperty( hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL, (PBYTE)fname, sizeof(fname), NULL); bSuccess = bSuccess && SetupDiGetDeviceRegistryProperty( hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL, (PBYTE)desc, sizeof(desc), NULL); BOOL bUsbDevice = FALSE; TCHAR locinfo[256]; if (SetupDiGetDeviceRegistryProperty( hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL, (PBYTE)locinfo, sizeof(locinfo), NULL)) { // Just check the first three characters to determine // if the port is connected to the USB bus. This isn't // an infallible method; it would be better to use the // BUS GUID. Currently, Windows doesn't let you query // that though (SPDRP_BUSTYPEGUID seems to exist in // documentation only). bUsbDevice = (strncmp(locinfo, "USB", 3) == 0); } // Open device parameters reg key - Added after fact from post on CodeGuru - credit to Peter Wurmsdobler HKEY hKey = SetupDiOpenDevRegKey (hDevInfo, &devdata, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); TCHAR szPortName[MAX_PATH]; if (hKey) { DWORD dwType = REG_SZ; DWORD dwReqSize = sizeof(szPortName); // Query for portname long lRet = RegQueryValueEx (hKey, "PortName", 0, &dwType, (LPBYTE)&szPortName, &dwReqSize); if (lRet == ERROR_SUCCESS) bSuccess &= TRUE; else bSuccess &= FALSE; } else bSuccess &= FALSE; if (bSuccess) { // Add an entry to the array SerialPortInfo si; si.szDevPath = strDevPath; si.szFriendlyName = fname; si.szPortName = szPortName; si.szPortDesc = desc; si.bUsbDevice = (bUsbDevice==TRUE); serialports.push_back(si); } } else { return; } } else { DWORD err = GetLastError(); if (err != ERROR_NO_MORE_ITEMS) { return; } } } } catch (...) { } if (pDetData != NULL) delete[](char*)pDetData; if (hDevInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hDevInfo); }
// enumerate serial ports void senum(void (*fp_enum)(char *name, char *device)) { // STG's 50-cents: // for the love of all things sacred... enumerate serial ports already! // not only does this require an utterly convoluted piece of code but it doesn't even work on all windows versions! // to support windows across the board, you'd have to implement at least three different enumeration routines... // god damn it... two f*****g hours of my life wasted on this crap! // microsoft, i usually like you, but for this you deserve to be bitchslapped into outer space. HDEVINFO h_devinfo; SP_DEVICE_INTERFACE_DATA ifdata; SP_DEVICE_INTERFACE_DETAIL_DATA *ifdetail; SP_DEVINFO_DATA ifinfo; int count=0; DWORD size=0; char friendlyname[MAX_PATH+1]; char name[MAX_PATH+1]; char *namecat; DWORD type; HKEY devkey; DWORD keysize; // initialize some stuff memset(&ifdata,0,sizeof(ifdata)); ifdata.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA); memset(&ifinfo,0,sizeof(ifinfo)); ifinfo.cbSize=sizeof(ifinfo); // set up a device information set h_devinfo=SetupDiGetClassDevs(&GUID_SERENUM_BUS_ENUMERATOR,NULL,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); if(h_devinfo) { while(1) { // enumerate devices if(!SetupDiEnumDeviceInterfaces(h_devinfo,NULL,&GUID_SERENUM_BUS_ENUMERATOR,count,&ifdata)) break; size=0; // fetch size required for "interface details" struct SetupDiGetDeviceInterfaceDetail(h_devinfo,&ifdata,NULL,0,&size,NULL); if(size) { // allocate and initialize "interface details" struct ifdetail=malloc(sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)+size); memset(ifdetail,0,sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)+size); ifdetail->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // get "device interface details" and "device info" if(SetupDiGetDeviceInterfaceDetail(h_devinfo,&ifdata,ifdetail,size,&size,&ifinfo)) { // retrieve "friendly name" from the registry if(!SetupDiGetDeviceRegistryProperty(h_devinfo,&ifinfo,SPDRP_FRIENDLYNAME,&type,friendlyname,sizeof(friendlyname),&size)) { friendlyname[0]=0; } // open the registry key containing device information devkey=SetupDiOpenDevRegKey(h_devinfo,&ifinfo,DICS_FLAG_GLOBAL,0,DIREG_DEV,KEY_READ); if(devkey!=INVALID_HANDLE_VALUE) { keysize=sizeof(name); // retrieve the actual *short* port name from the registry if(RegQueryValueEx(devkey,"PortName",NULL,NULL,name,&keysize)==ERROR_SUCCESS) { // whoop-dee-f*****g-doo, we finally have what we need! if(strlen(friendlyname)) { // build a display name (because "friendly name" may not contain port name early enough) namecat=malloc(strlen(name)+strlen(friendlyname)+2); strcpy(namecat,name); strcat(namecat," "); strcat(namecat,friendlyname); fp_enum(namecat,name); free(namecat); } else { // no "friendly name" available, just use device name fp_enum(name,name); } } // close the registry key RegCloseKey(devkey); } } free(ifdetail); } count++; } // DESTROY! DESTROY! SetupDiDestroyDeviceInfoList(h_devinfo); } }
bool cmtScanPorts(List<CmtPortInfo>& ports,uint32_t baudrate, uint32_t singleScanTimeout, uint32_t scanTries) { CmtPortInfo current = {0,0,0}; ports.clear(); // clear the list #ifdef _WIN32 HDEVINFO hDevInfo; SP_DEVINFO_DATA DeviceInfoData; DWORD i; // Create a HDEVINFO with all present devices. // GUID for Ports: 4D36E978-E325-11CE-BFC1-08002BE10318 GUID portGuid = {0x4D36E978,0xE325,0x11CE,{0xBF,0xC1,0x08,0x00,0x2B,0xE1,0x03,0x18}}; // "4D36E978-E325-11CE-BFC1-08002BE10318" hDevInfo = SetupDiGetClassDevs(&portGuid, 0, 0, DIGCF_PRESENT | DIGCF_PROFILE); if (hDevInfo == INVALID_HANDLE_VALUE) return false; // Enumerate through all devices in Set. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (i=0;!abortScan && SetupDiEnumDeviceInfo(hDevInfo,i,&DeviceInfoData);++i) { DWORD DataT; char buffer[256]; bool isBT = false; // // Call function with null to begin with, // then use the returned buffer size // to Alloc the buffer. Keep calling until // success or an unknown failure. // #if 1 if (SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_MFG, &DataT, (PBYTE)buffer, 256, NULL)) { // on failure, this is not an Xsens Device // on success, we need to check if the device is an Xsens Device //if (_strnicmp(buffer,"xsens",5)) // scan = true; //else if (!_strnicmp(buffer,"(Standard port types)",20)) continue; if (_strnicmp(buffer,"xsens",5)) // if this is NOT an xsens device, treat it as a BT device { isBT = true; if (_strnicmp(buffer,"WIDCOMM",7)) // if this is NOT a WIDCOMM (Ezureo / TDK stack), skip it continue; } } #endif // we found an Xsens Device, add its port nr to the list //Get the registry key which stores the ports settings HKEY hDeviceKey = SetupDiOpenDevRegKey(hDevInfo, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); if (hDeviceKey != INVALID_HANDLE_VALUE) { //Read in the name of the port char pszPortName[256]; DWORD dwSize = 256; DWORD dwType = 0; if ((RegQueryValueEx(hDeviceKey, "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 int32_t nLen = (int32_t) strlen(pszPortName); if (nLen > 3) { if (_strnicmp(pszPortName, "COM", 3)) continue; int32_t nPort = atoi(&pszPortName[3]); if (nPort) { current.m_portNr = (uint16_t) nPort; if (isBT) current.m_baudrate = CMT_BAUD_RATE_460K8; else current.m_baudrate = baudrate; ports.append(current); } } } } //Close the key now that we are finished with it RegCloseKey(hDeviceKey); } // Cleanup SetupDiDestroyDeviceInfoList(hDevInfo); // Now sort the list by ascending port nr ports.sortAscending(); // Add the standard com ports 1 and 2 unless they are already in the list bool add1 = true, add2 = true; if ((ports.length() > 0) && (ports[0].m_portNr == 1)) add1 = false; if (ports.length() > 0) { if (ports[0].m_portNr == 2) add2 = false; else if (ports.length() > 1) if (ports[1].m_portNr == 2) add2 = false; } if (add1) { current.m_portNr = 1; current.m_baudrate = baudrate; ports.append(current); } if (add2) { current.m_portNr = 2; current.m_baudrate = baudrate; ports.append(current); } #else DIR *dir; struct dirent *entry; if ((dir = opendir("/dev/")) == NULL) return false; while ((entry = readdir(dir))) if (strncmp("ttyS", entry->d_name, 4) == 0 || strncmp("ttyUSB", entry->d_name, 6) == 0) { sprintf(current.m_portName, "/dev/%s", entry->d_name); current.m_baudrate = baudrate; ports.append(current); } closedir(dir); ports.sortAscending(); #endif // try to connect so we can detect if there really is an MT / XM attached unsigned p = 0; while (!abortScan && p < ports.length()) { if (cmtScanPort(ports[p],ports[p].m_baudrate,singleScanTimeout,scanTries)) ++p; else ports.remove(p); } if (abortScan) return abortScan = false; // Now sort the final list by ascending port nr ports.sortAscending(); abortScan = false; return true; }
static DWORD RemovePort(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData) { PORT_TYPE PortType; HCOMDB hComDB = HCOMDB_INVALID_HANDLE_VALUE; HKEY hKey; LONG lError; DWORD dwPortNumber; DWORD dwPortNameSize; WCHAR szPortName[8]; /* If we are removing a serial port ... */ PortType = GetPortType(DeviceInfoSet, DeviceInfoData); if (PortType == SerialPort) { /* Open the port database */ if (ComDBOpen(&hComDB) == ERROR_SUCCESS) { /* Open the device key */ hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if (hKey != INVALID_HANDLE_VALUE) { /* Query the port name */ dwPortNameSize = sizeof(szPortName); lError = RegQueryValueEx(hKey, L"PortName", NULL, NULL, (PBYTE)szPortName, &dwPortNameSize); /* Close the device key */ RegCloseKey(hKey); /* If we got a valid port name ...*/ if (lError == ERROR_SUCCESS) { /* Get the port number */ dwPortNumber = _wtoi(szPortName + wcslen(pszCom)); /* Release the port */ ComDBReleasePort(hComDB, dwPortNumber); } } /* Close the port database */ ComDBClose(hComDB); } } /* Remove the device */ if (!SetupDiRemoveDevice(DeviceInfoSet, DeviceInfoData)) return GetLastError(); return ERROR_SUCCESS; }