+
+typedef struct _PORT_DATA
+{
+ HDEVINFO DeviceInfoSet;
+ PSP_DEVINFO_DATA DeviceInfoData;
+
+ WCHAR szPortName[16];
+ INT nBaudRateIndex;
+ INT nParityIndex;
+ INT nDataBitsIndex;
+ INT nStopBitsIndex;
+ INT nFlowControlIndex;
+
+ BOOL bChanged;
+} PORT_DATA, *PPORT_DATA;
+
+#define DEFAULT_BAUD_RATE_INDEX 11
+#define DEFAULT_DATA_BITS_INDEX 4
+#define DEFAULT_PARITY_INDEX 2
+#define DEFAULT_STOP_BITS_INDEX 0
+#define DEFAULT_FLOW_CONTROL_INDEX 2
+
+DWORD BaudRates[] = {75, 110, 134, 150, 300, 600, 1200, 1800, 2400, 4800,
+ 7200, 9600, 14400, 19200, 38400, 57600, 115200, 128000};
+PWSTR Paritys[] = {L"e", L"o", L"n", L"m", L"s"};
+PWSTR DataBits[] = {L"4", L"5", L"6", L"7", L"8"};
+PWSTR StopBits[] = {L"1", L"1.5", L"2"};
+PWSTR FlowControls[] = {L"x", L"p"};
+
+
+static
+VOID
+FillComboBox(
+ HWND hwnd,
+ PWSTR szBuffer)
+{
+ PWSTR pStart, pEnd;
+
+ pStart = szBuffer;
+ for (;;)
+ {
+ pEnd = wcschr(pStart, L',');
+ if (pEnd != NULL)
+ *pEnd = UNICODE_NULL;
+
+ ComboBox_AddString(hwnd, pStart);
+
+ if (pEnd == NULL)
+ break;
+
+ pStart = pEnd + 1;
+ }
+}
+
+
+static
+VOID
+ReadPortSettings(
+ PPORT_DATA pPortData)
+{
+ WCHAR szPortData[32];
+ WCHAR szParity[4];
+ WCHAR szDataBits[4];
+ WCHAR szStopBits[4];
+ WCHAR szFlowControl[4];
+ DWORD dwType, dwSize;
+ DWORD dwBaudRate = 0;
+ HKEY hKey;
+ INT n, i;
+ LONG lError;
+
+ TRACE("ReadPortSettings(%p)\n", pPortData);
+
+ pPortData->nBaudRateIndex = DEFAULT_BAUD_RATE_INDEX; /* 9600 */
+ pPortData->nParityIndex = DEFAULT_PARITY_INDEX; /* None */
+ pPortData->nDataBitsIndex = DEFAULT_DATA_BITS_INDEX; /* 8 Data Bits */
+ pPortData->nStopBitsIndex = DEFAULT_STOP_BITS_INDEX; /* 1 Stop Bit */
+ pPortData->nFlowControlIndex = DEFAULT_FLOW_CONTROL_INDEX; /* None */
+ pPortData->bChanged = FALSE;
+
+ hKey = SetupDiOpenDevRegKey(pPortData->DeviceInfoSet,
+ pPortData->DeviceInfoData,
+ DICS_FLAG_GLOBAL,
+ 0,
+ DIREG_DEV,
+ KEY_READ);
+ if (hKey == INVALID_HANDLE_VALUE)
+ {
+ ERR("SetupDiOpenDevRegKey() failed\n");
+ return;
+ }
+
+ dwSize = sizeof(pPortData->szPortName);
+ lError = RegQueryValueExW(hKey,
+ L"PortName",
+ NULL,
+ NULL,
+ (PBYTE)pPortData->szPortName,
+ &dwSize);
+ RegCloseKey(hKey);
+
+ if (lError != ERROR_SUCCESS)
+ {
+ ERR("RegQueryValueExW failed (Error %lu)\n", lError);
+ return;
+ }
+
+ wcscat(pPortData->szPortName, L":");
+ TRACE("PortName: '%S'\n", pPortData->szPortName);
+
+ lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Ports",
+ 0,
+ KEY_READ,
+ &hKey);
+ if (lError != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKeyExW failed (Error %lu)\n", lError);
+ return;
+ }
+
+ dwSize = sizeof(szPortData);
+ lError = RegQueryValueExW(hKey,
+ pPortData->szPortName,
+ NULL,
+ &dwType,
+ (LPBYTE)szPortData,
+ &dwSize);
+ RegCloseKey(hKey);
+
+ if (lError != ERROR_SUCCESS)
+ {
+ ERR("RegQueryValueExW failed (Error %lu)\n", lError);
+ return;
+ }
+
+ if ((dwType != REG_SZ) || (dwSize > sizeof(szPortData)))
+ {
+ ERR("Wrong type or size\n");
+ return;
+ }
+
+ TRACE("szPortData: '%S'\n", szPortData);
+
+ /* Replace commas by spaces */
+ for (i = 0; i < wcslen(szPortData); i++)
+ {
+ if (szPortData[i] == L',')
+ szPortData[i] = L' ';
+ }
+
+ TRACE("szPortData: '%S'\n", szPortData);
+
+ /* Parse the port settings */
+ n = swscanf(szPortData,
+ L"%lu %3s %3s %3s %3s",
+ &dwBaudRate,
+ &szParity,
+ &szDataBits,
+ &szStopBits,
+ &szFlowControl);
+
+ TRACE("dwBaudRate: %lu\n", dwBaudRate);
+ TRACE("szParity: '%S'\n", szParity);
+ TRACE("szDataBits: '%S'\n", szDataBits);
+ TRACE("szStopBits: '%S'\n", szStopBits);
+ TRACE("szFlowControl: '%S'\n", szFlowControl);
+
+ if (n > 0)
+ {
+ for (i = 0; i < ARRAYSIZE(BaudRates); i++)
+ {
+ if (dwBaudRate == BaudRates[i])
+ pPortData->nBaudRateIndex = i;
+ }
+ }
+
+ if (n > 1)
+ {
+ for (i = 0; i < ARRAYSIZE(Paritys); i++)
+ {
+ if (_wcsicmp(szParity, Paritys[i]) == 0)
+ pPortData->nParityIndex = i;
+ }
+ }
+
+ if (n > 2)
+ {
+ for (i = 0; i < ARRAYSIZE(DataBits); i++)
+ {
+ if (_wcsicmp(szDataBits, DataBits[i]) == 0)
+ pPortData->nDataBitsIndex = i;
+ }
+ }
+
+ if (n > 3)
+ {
+ for (i = 0; i < ARRAYSIZE(StopBits); i++)
+ {
+ if (_wcsicmp(szStopBits, StopBits[i]) == 0)
+ pPortData->nStopBitsIndex = i;
+ }
+ }
+
+ if (n > 4)
+ {
+ for (i = 0; i < ARRAYSIZE(FlowControls); i++)
+ {
+ if (_wcsicmp(szFlowControl, FlowControls[i]) == 0)
+ pPortData->nFlowControlIndex = i;
+ }
+ }
+}
+
+
+static
+VOID
+WritePortSettings(
+ HWND hwnd,
+ PPORT_DATA pPortData)
+{
+ WCHAR szPortData[32];
+ HWND hwndControl;
+ INT nBaudRateIndex;
+ INT nDataBitsIndex;
+ INT nParityIndex;
+ INT nStopBitsIndex;
+ INT nFlowControlIndex;
+ HKEY hKey;
+ LONG lError;
+
+ TRACE("WritePortSettings(%p)\n", pPortData);
+
+ if (pPortData->bChanged == FALSE)
+ {
+ TRACE("Nothing changed. Done!\n");
+ return;
+ }
+
+ nBaudRateIndex = pPortData->nBaudRateIndex;
+ nDataBitsIndex = pPortData->nDataBitsIndex;
+ nParityIndex = pPortData->nParityIndex;
+ nStopBitsIndex = pPortData->nStopBitsIndex;
+ nFlowControlIndex = pPortData->nFlowControlIndex;
+
+ hwndControl = GetDlgItem(hwnd, IDC_SERIAL_BITSPERSECOND);
+ if (hwndControl)
+ {
+ nBaudRateIndex = ComboBox_GetCurSel(hwndControl);
+ }
+
+ hwndControl = GetDlgItem(hwnd, IDC_SERIAL_DATABITS);
+ if (hwndControl)
+ {
+ nDataBitsIndex = ComboBox_GetCurSel(hwndControl);
+ }
+
+ hwndControl = GetDlgItem(hwnd, IDC_SERIAL_PARITY);
+ if (hwndControl)
+ {
+ nParityIndex = ComboBox_GetCurSel(hwndControl);
+ }
+
+ hwndControl = GetDlgItem(hwnd, IDC_SERIAL_STOPBITS);
+ if (hwndControl)
+ {
+ nStopBitsIndex = ComboBox_GetCurSel(hwndControl);
+ }
+
+ hwndControl = GetDlgItem(hwnd, IDC_SERIAL_FLOWCONTROL);
+ if (hwndControl)
+ {
+ nFlowControlIndex = ComboBox_GetCurSel(hwndControl);
+ }
+
+ swprintf(szPortData,
+ L"%lu,%s,%s,%s",
+ BaudRates[nBaudRateIndex],
+ Paritys[nParityIndex],
+ DataBits[nDataBitsIndex],
+ StopBits[nStopBitsIndex]);
+ if (nFlowControlIndex < 2)
+ {
+ wcscat(szPortData, L",");
+ wcscat(szPortData, FlowControls[nFlowControlIndex]);
+ }
+
+ TRACE("szPortData: '%S'\n", szPortData);
+
+ lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Ports",
+ 0,
+ KEY_WRITE,
+ &hKey);
+ if (lError != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKeyExW failed (Error %lu)\n", lError);
+ return;
+ }
+
+ lError = RegSetValueExW(hKey,
+ pPortData->szPortName,
+ 0,
+ REG_SZ,
+ (LPBYTE)szPortData,
+ (wcslen(szPortData) + 1) * sizeof(WCHAR));
+
+ RegCloseKey(hKey);
+
+ if (lError != ERROR_SUCCESS)
+ {
+ ERR("RegSetValueExW failed (Error %lu)\n", lError);
+ return;
+ }
+
+ TRACE("Done!\n");
+}
+
+