summaryrefslogtreecommitdiffstats
path: root/private/unimodem/serialui
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/unimodem/serialui
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/unimodem/serialui')
-rw-r--r--private/unimodem/serialui/cstrings.c30
-rw-r--r--private/unimodem/serialui/cstrings.h23
-rw-r--r--private/unimodem/serialui/dlgids.h42
-rw-r--r--private/unimodem/serialui/dll.c291
-rw-r--r--private/unimodem/serialui/dll.h44
-rw-r--r--private/unimodem/serialui/makefile6
-rw-r--r--private/unimodem/serialui/port.c1085
-rw-r--r--private/unimodem/serialui/proj.h99
-rw-r--r--private/unimodem/serialui/rcids.h109
-rw-r--r--private/unimodem/serialui/serialui.c989
-rw-r--r--private/unimodem/serialui/serialui.def22
-rw-r--r--private/unimodem/serialui/serialui.dlg116
-rw-r--r--private/unimodem/serialui/serialui.h47
-rw-r--r--private/unimodem/serialui/serialui.rc77
-rw-r--r--private/unimodem/serialui/serialui.rcv19
-rw-r--r--private/unimodem/serialui/sources79
-rw-r--r--private/unimodem/serialui/util.c290
-rw-r--r--private/unimodem/serialui/util.h40
18 files changed, 3408 insertions, 0 deletions
diff --git a/private/unimodem/serialui/cstrings.c b/private/unimodem/serialui/cstrings.c
new file mode 100644
index 000000000..9b23635b5
--- /dev/null
+++ b/private/unimodem/serialui/cstrings.c
@@ -0,0 +1,30 @@
+//---------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation 1993-1996
+//
+// File: cstrings.c
+//
+// This file contains read-only string constants
+//
+// History:
+// 12-23-93 ScottH Created
+// 11-06-95 ScottH Ported to NT
+//
+//---------------------------------------------------------------------------
+
+#include "proj.h"
+
+#pragma data_seg(DATASEG_READONLY)
+
+TCHAR const FAR c_szWinHelpFile[] = TEXT("windows.hlp");
+
+// Registry key names
+
+TCHAR const FAR c_szPortClass[] = TEXT("ports");
+TCHAR const FAR c_szDeviceDesc[] = TEXT("DeviceDesc");
+TCHAR const FAR c_szPortName[] = TEXT("PortName");
+TCHAR const FAR c_szFriendlyName[] = REGSTR_VAL_FRIENDLYNAME;
+TCHAR const FAR c_szDCB[] = TEXT("DCB");
+
+#pragma data_seg()
+
diff --git a/private/unimodem/serialui/cstrings.h b/private/unimodem/serialui/cstrings.h
new file mode 100644
index 000000000..432253aef
--- /dev/null
+++ b/private/unimodem/serialui/cstrings.h
@@ -0,0 +1,23 @@
+//---------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation 1993-1996
+//
+// File: cstrings.h
+//
+//---------------------------------------------------------------------------
+
+#ifndef _CSTRINGS_H_
+#define _CSTRINGS_H_
+
+extern TCHAR const FAR c_szWinHelpFile[];
+
+// Registry key names
+
+extern TCHAR const FAR c_szPortClass[];
+extern TCHAR const FAR c_szDeviceDesc[];
+extern TCHAR const FAR c_szPortName[];
+extern TCHAR const FAR c_szFriendlyName[];
+extern TCHAR const FAR c_szDCB[];
+
+#endif // _CSTRINGS_H_
+
diff --git a/private/unimodem/serialui/dlgids.h b/private/unimodem/serialui/dlgids.h
new file mode 100644
index 000000000..c36d5f5e1
--- /dev/null
+++ b/private/unimodem/serialui/dlgids.h
@@ -0,0 +1,42 @@
+//{{NO_DEPENDENCIES}}
+// App Studio generated include file.
+// Used by TEMPLATE.RC
+//
+#define IDD_ADV_PORT 101
+#define IDD_PORTSETTINGS 119
+#define IDC_DEFAULTS 1000
+#define IDC_RXFIFO_USAGE 1003
+#define IDC_TXFIFO_USAGE 1004
+#define IDC_LBL_RXFIFO 1005
+#define IDC_LBL_RXFIFO_LO 1006
+#define IDC_LBL_RXFIFO_HI 1007
+#define IDC_FIFO_USAGE 1008
+#define IDC_LBL_TXFIFO 1009
+#define IDC_LBL_TXFIFO_LO 1010
+#define IDC_LBL_TXFIFO_HI 1011
+#define IDC_PS_PORT 1046
+#define IDC_PS_LBL_BAUDRATE 1047
+#define IDC_PS_BAUDRATE 1048
+#define IDC_PS_LBL_DATABITS 1049
+#define IDC_PS_DATABITS 1050
+#define IDC_PS_LBL_PARITY 1051
+#define IDC_PS_PARITY 1052
+#define IDC_PS_LBL_STOPBITS 1053
+#define IDC_PS_STOPBITS 1054
+#define IDC_PS_LBL_FLOWCTL 1055
+#define IDC_PS_FLOWCTL 1056
+#define IDC_PS_PB_RESTORE 1058
+#define IDC_PS_ADVANCED 1059
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NEXT_RESOURCE_VALUE 103
+#define _APS_NEXT_COMMAND_VALUE 101
+#define _APS_NEXT_CONTROL_VALUE 1061
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/private/unimodem/serialui/dll.c b/private/unimodem/serialui/dll.c
new file mode 100644
index 000000000..1df35f06d
--- /dev/null
+++ b/private/unimodem/serialui/dll.c
@@ -0,0 +1,291 @@
+//---------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation 1993-1995
+//
+// File: dll.c
+//
+// This file contains the library entry points
+//
+// History:
+// 12-23-93 ScottH Created
+// 9-22-95 ScottH Ported to NT
+//
+//---------------------------------------------------------------------------
+
+
+#include "proj.h"
+#include <rovdbg.h> // debug assertion code
+
+// Global data
+//
+int g_cProcesses = 0;
+BOOL g_bAdminUser;
+
+#ifdef WIN32
+
+CRITICAL_SECTION g_csDll = { 0 };
+
+#endif // WIN32
+
+
+/*----------------------------------------------------------
+Purpose: Initialize the DLL
+Returns:
+Cond: --
+*/
+BOOL PRIVATE Dll_Initialize(void)
+ {
+ BOOL bRet = TRUE;
+
+ InitCommonControls();
+
+ return bRet;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Register window classes per process
+Returns:
+Cond: --
+*/
+BOOL PRIVATE InitWindowClasses(
+ HINSTANCE hinst)
+ {
+ return TRUE;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Terminate DLL
+Returns: --
+Cond: --
+*/
+BOOL PRIVATE Dll_Terminate(
+ HINSTANCE hinst)
+ {
+ return TRUE;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Unregister window classes per process
+Returns:
+Cond: --
+*/
+void PRIVATE TermWindowClasses(
+ HINSTANCE hinst)
+ {
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Attach a process to this DLL
+Returns: --
+Cond: --
+*/
+BOOL PRIVATE Dll_ProcessAttach(HINSTANCE hDll)
+ {
+ BOOL bSuccess = TRUE;
+
+#ifdef WIN32
+
+ if (g_cProcesses == 0)
+ {
+ InitializeCriticalSection(&g_csDll);
+ }
+
+ g_bAdminUser = IsAdminUser();
+#endif // WIN32
+
+ if (bSuccess)
+ {
+ g_hinst = hDll;
+
+#ifdef DEBUG
+
+ // We do this simply to load the debug .ini flags
+ //
+ RovComm_ProcessIniFile();
+
+ TRACE_MSG(TF_GENERAL, "Process Attach [%d] (hDll = %lx)", g_cProcesses, hDll);
+ DEBUG_BREAK(BF_ONPROCESSATT);
+
+#endif
+
+ if (g_cProcesses++ == 0)
+ {
+ bSuccess = Dll_Initialize();
+ }
+
+ if (bSuccess)
+ {
+ // (Only do this if we succeeded above)
+ //
+ // Register the window classes again (they are per-process)
+ //
+ bSuccess = InitWindowClasses(hDll);
+ }
+ }
+
+ return bSuccess;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Detach a process from the DLL
+Returns: --
+Cond: --
+*/
+BOOL PRIVATE Dll_ProcessDetach(HINSTANCE hDll)
+ {
+ BOOL bSuccess = TRUE;
+
+ ASSERT(hDll == g_hinst);
+
+ DEBUG_CODE( TRACE_MSG(TF_GENERAL, "Process Detach [%d] (hDll = %lx)",
+ g_cProcesses-1, hDll); )
+
+ DEBUG_CODE( DEBUG_BREAK(BF_ONPROCESSDET); )
+
+ if (--g_cProcesses == 0)
+ {
+ bSuccess = Dll_Terminate(g_hinst);
+ }
+
+#ifdef WIN32
+
+ if (g_cProcesses == 0)
+ {
+ DeleteCriticalSection(&g_csDll);
+ }
+
+#endif // WIN32
+
+ TermWindowClasses(hDll);
+
+ return bSuccess;
+ }
+
+
+//
+// Per-instance data
+//
+#pragma data_seg(DATASEG_PERINSTANCE)
+
+HINSTANCE g_hinst = 0;
+
+#pragma data_seg()
+
+
+// **************************************************************************
+// WIN32 specific code
+// **************************************************************************
+
+#ifdef WIN32
+
+#ifdef DEBUG
+BOOL g_bExclusive=FALSE;
+#endif
+
+
+/*----------------------------------------------------------
+Purpose: Enter an exclusive section
+Returns: --
+Cond: --
+*/
+void PUBLIC Dll_EnterExclusive(void)
+ {
+ EnterCriticalSection(&g_csDll);
+
+#ifdef DEBUG
+ g_bExclusive = TRUE;
+#endif
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Leave an exclusive section
+Returns: --
+Cond: --
+*/
+void PUBLIC Dll_LeaveExclusive(void)
+ {
+#ifdef DEBUG
+ g_bExclusive = FALSE;
+#endif
+
+ LeaveCriticalSection(&g_csDll);
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Win32 Libmain
+Returns: --
+Cond: --
+*/
+BOOL APIENTRY LibMain(
+ HANDLE hDll,
+ DWORD dwReason,
+ LPVOID lpReserved)
+ {
+ switch(dwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ Dll_ProcessAttach(hDll);
+ break;
+
+ case DLL_PROCESS_DETACH:
+ Dll_ProcessDetach(hDll);
+ break;
+
+ case DLL_THREAD_ATTACH:
+
+#ifdef DEBUG
+
+ DEBUG_BREAK(BF_ONTHREADATT);
+
+#endif
+
+ break;
+
+ case DLL_THREAD_DETACH:
+
+#ifdef DEBUG
+
+ DEBUG_BREAK(BF_ONTHREADDET);
+
+#endif
+
+ break;
+
+ default:
+ break;
+ }
+
+ return TRUE;
+ }
+
+
+#else // WIN32
+
+
+// **************************************************************************
+// WIN16 specific code
+// **************************************************************************
+
+
+BOOL CALLBACK LibMain(HINSTANCE hinst, UINT wDS, DWORD unused)
+ {
+ return Dll_ProcessAttach(hinst);
+ }
+
+BOOL CALLBACK WEP(BOOL fSystemExit)
+ {
+ return Dll_ProcessDetach(g_hinst);
+ }
+
+#endif // WIN32
+
+
+
+
diff --git a/private/unimodem/serialui/dll.h b/private/unimodem/serialui/dll.h
new file mode 100644
index 000000000..2157968ef
--- /dev/null
+++ b/private/unimodem/serialui/dll.h
@@ -0,0 +1,44 @@
+//
+// dll.h
+//
+
+#ifndef __DLL_H__
+#define __DLL_H__
+
+extern HINSTANCE g_hinst;
+
+#ifdef WIN32
+
+// Notes:
+// 1. Never "return" from the critical section.
+// 2. Never "SendMessage" or "Yield" from the critical section.
+// 3. Never call USER API which may yield.
+// 4. Always make the critical section as small as possible.
+// 5. Critical sections in Win95 block across processes. In NT
+// they are per-process only, so use mutexes instead.
+//
+
+#define WIN32_CODE(x) x
+
+void PUBLIC Dll_EnterExclusive(void);
+void PUBLIC Dll_LeaveExclusive(void);
+extern BOOL g_bExclusive;
+extern BOOL g_bAdminUser;
+#define USER_IS_ADMIN() (g_bAdminUser)
+
+#define ENTER_X() Dll_EnterExclusive();
+#define LEAVE_X() Dll_LeaveExclusive();
+#define ASSERT_X() ASSERT(g_bExclusive)
+
+#else // WIN32
+
+#define WIN32_CODE(x)
+
+#define ENTER_X()
+#define LEAVE_X()
+#define ASSERT_X()
+
+#endif // WIN32
+
+#endif //!__DLL_H__
+
diff --git a/private/unimodem/serialui/makefile b/private/unimodem/serialui/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/unimodem/serialui/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/unimodem/serialui/port.c b/private/unimodem/serialui/port.c
new file mode 100644
index 000000000..5d0068b49
--- /dev/null
+++ b/private/unimodem/serialui/port.c
@@ -0,0 +1,1085 @@
+//---------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation 1993-1996
+//
+// File: port.c
+//
+// This files contains the dialog code for the Port Settings property page.
+//
+// History:
+// 2-09-94 ScottH Created
+// 11-06-95 ScottH Ported to NT
+//
+//---------------------------------------------------------------------------
+
+
+#include "proj.h"
+
+#ifdef CS_HELP // Context-sensitive help
+#include "..\..\..\..\win\core\inc\help.h"
+#endif
+
+// This is the structure that is used to fill the
+// max speed listbox
+typedef struct _Bauds
+ {
+ DWORD dwDTERate;
+ int ids;
+ } Bauds;
+
+static Bauds g_rgbauds[] = {
+ { 110L, IDS_BAUD_110 },
+ { 300L, IDS_BAUD_300 },
+ { 1200L, IDS_BAUD_1200 },
+ { 2400L, IDS_BAUD_2400 },
+ { 4800L, IDS_BAUD_4800 },
+ { 9600L, IDS_BAUD_9600 },
+ { 19200, IDS_BAUD_19200 },
+ { 38400, IDS_BAUD_38400 },
+ { 57600, IDS_BAUD_57600 },
+ { 115200, IDS_BAUD_115200 },
+ { 230400, IDS_BAUD_230400 },
+ { 460800, IDS_BAUD_460800 },
+ { 921600, IDS_BAUD_921600 },
+ };
+
+// Command IDs for the parity listbox
+#define CMD_PARITY_EVEN 1
+#define CMD_PARITY_ODD 2
+#define CMD_PARITY_NONE 3
+#define CMD_PARITY_MARK 4
+#define CMD_PARITY_SPACE 5
+
+// Command IDs for the flow control listbox
+#define CMD_FLOWCTL_XONXOFF 1
+#define CMD_FLOWCTL_HARDWARE 2
+#define CMD_FLOWCTL_NONE 3
+
+// This table is the generic port settings table
+// that is used to fill the various listboxes
+typedef struct _PortValues
+ {
+ union {
+ BYTE bytesize;
+ BYTE cmd;
+ BYTE stopbits;
+ };
+ int ids;
+ } PortValues, FAR * LPPORTVALUES;
+
+
+#pragma data_seg(DATASEG_READONLY)
+
+// This is the structure that is used to fill the data bits listbox
+static PortValues s_rgbytesize[] = {
+ { 4, IDS_BYTESIZE_4 },
+ { 5, IDS_BYTESIZE_5 },
+ { 6, IDS_BYTESIZE_6 },
+ { 7, IDS_BYTESIZE_7 },
+ { 8, IDS_BYTESIZE_8 },
+ };
+
+// This is the structure that is used to fill the parity listbox
+static PortValues s_rgparity[] = {
+ { CMD_PARITY_EVEN, IDS_PARITY_EVEN },
+ { CMD_PARITY_ODD, IDS_PARITY_ODD },
+ { CMD_PARITY_NONE, IDS_PARITY_NONE },
+ { CMD_PARITY_MARK, IDS_PARITY_MARK },
+ { CMD_PARITY_SPACE, IDS_PARITY_SPACE },
+ };
+
+// This is the structure that is used to fill the stopbits listbox
+static PortValues s_rgstopbits[] = {
+ { ONESTOPBIT, IDS_STOPBITS_1 },
+ { ONE5STOPBITS, IDS_STOPBITS_1_5 },
+ { TWOSTOPBITS, IDS_STOPBITS_2 },
+ };
+
+// This is the structure that is used to fill the flow control listbox
+static PortValues s_rgflowctl[] = {
+ { CMD_FLOWCTL_XONXOFF, IDS_FLOWCTL_XONXOFF },
+ { CMD_FLOWCTL_HARDWARE, IDS_FLOWCTL_HARDWARE },
+ { CMD_FLOWCTL_NONE, IDS_FLOWCTL_NONE },
+ };
+
+#pragma data_seg()
+
+
+typedef struct tagPORT
+ {
+ HWND hdlg; // dialog handle
+ HWND hwndBaudRate;
+ HWND hwndDataBits;
+ HWND hwndParity;
+ HWND hwndStopBits;
+ HWND hwndFlowCtl;
+
+ LPPORTINFO pportinfo; // pointer to shared working buffer
+
+ } PORT, FAR * PPORT;
+
+
+// This structure contains the default settings for the dialog
+static struct _DefPortSettings
+ {
+ int iSelBaud;
+ int iSelDataBits;
+ int iSelParity;
+ int iSelStopBits;
+ int iSelFlowCtl;
+ } s_defportsettings;
+
+// These are default settings
+#define DEFAULT_BAUDRATE 9600L
+#define DEFAULT_BYTESIZE 8
+#define DEFAULT_PARITY CMD_PARITY_NONE
+#define DEFAULT_STOPBITS ONESTOPBIT
+#define DEFAULT_FLOWCTL CMD_FLOWCTL_NONE
+
+
+#define Port_GetPtr(hwnd) (PPORT)GetWindowLong(hwnd, DWL_USER)
+#define Port_SetPtr(hwnd, lp) (PPORT)SetWindowLong(hwnd, DWL_USER, (LONG)(lp))
+
+UINT WINAPI FeFiFoFum(HWND hwndOwner, LPCTSTR pszPortName);
+
+
+/*----------------------------------------------------------
+Purpose: Fills the baud rate combobox with the possible baud
+ rates that Windows supports.
+Returns: --
+Cond: --
+*/
+void PRIVATE Port_FillBaud(
+ PPORT this)
+ {
+ HWND hwndCB = this->hwndBaudRate;
+ WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
+ int i;
+ int n;
+ int iMatch = -1;
+ int iDef = -1;
+ int iSel;
+ TCHAR sz[MAXMEDLEN];
+
+ // Fill the listbox
+ for (i = 0; i < ARRAYSIZE(g_rgbauds); i++)
+ {
+ n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, g_rgbauds[i].ids, sz, SIZECHARS(sz)));
+ ComboBox_SetItemData(hwndCB, n, g_rgbauds[i].dwDTERate);
+
+ // Keep our eyes peeled for important values
+ if (DEFAULT_BAUDRATE == g_rgbauds[i].dwDTERate)
+ {
+ iDef = n;
+ }
+ if (pdcb->BaudRate == g_rgbauds[i].dwDTERate)
+ {
+ iMatch = n;
+ }
+ }
+
+ ASSERT(-1 != iDef);
+ s_defportsettings.iSelBaud = iDef;
+
+ // Does the DCB baudrate exist in our list of baud rates?
+ if (-1 == iMatch)
+ {
+ // No; choose the default
+ iSel = iDef;
+ }
+ else
+ {
+ // Yes; choose the matched value
+ ASSERT(-1 != iMatch);
+ iSel = iMatch;
+ }
+ ComboBox_SetCurSel(hwndCB, iSel);
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Fills the bytesize combobox with the possible byte sizes.
+Returns: --
+Cond: --
+*/
+void PRIVATE Port_FillDataBits(
+ PPORT this)
+ {
+ HWND hwndCB = this->hwndDataBits;
+ WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
+ int i;
+ int iSel;
+ int n;
+ int iMatch = -1;
+ int iDef = -1;
+ TCHAR sz[MAXMEDLEN];
+
+ // Fill the listbox
+ for (i = 0; i < ARRAYSIZE(s_rgbytesize); i++)
+ {
+ n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgbytesize[i].ids, sz, SIZECHARS(sz)));
+ ComboBox_SetItemData(hwndCB, n, s_rgbytesize[i].bytesize);
+
+ // Keep our eyes peeled for important values
+ if (DEFAULT_BYTESIZE == s_rgbytesize[i].bytesize)
+ {
+ iDef = n;
+ }
+ if (pdcb->ByteSize == s_rgbytesize[i].bytesize)
+ {
+ iMatch = n;
+ }
+ }
+
+ ASSERT(-1 != iDef);
+ s_defportsettings.iSelDataBits = iDef;
+
+ // Does the DCB value exist in our list?
+ if (-1 == iMatch)
+ {
+ // No; choose the default
+ iSel = iDef;
+ }
+ else
+ {
+ // Yes; choose the matched value
+ ASSERT(-1 != iMatch);
+ iSel = iMatch;
+ }
+ ComboBox_SetCurSel(hwndCB, iSel);
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Fills the parity combobox with the possible settings.
+Returns: --
+Cond: --
+*/
+void PRIVATE Port_FillParity(
+ PPORT this)
+ {
+ HWND hwndCB = this->hwndParity;
+ WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
+ int i;
+ int iSel;
+ int n;
+ int iMatch = -1;
+ int iDef = -1;
+ TCHAR sz[MAXMEDLEN];
+
+ // Fill the listbox
+ for (i = 0; i < ARRAYSIZE(s_rgparity); i++)
+ {
+ n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgparity[i].ids, sz, SIZECHARS(sz)));
+ ComboBox_SetItemData(hwndCB, n, s_rgparity[i].cmd);
+
+ // Keep our eyes peeled for important values
+ if (DEFAULT_PARITY == s_rgparity[i].cmd)
+ {
+ iDef = n;
+ }
+ switch (s_rgparity[i].cmd)
+ {
+ case CMD_PARITY_EVEN:
+ if (TRUE == pdcb->fParity && EVENPARITY == pdcb->Parity)
+ iMatch = n;
+ break;
+
+ case CMD_PARITY_ODD:
+ if (TRUE == pdcb->fParity && ODDPARITY == pdcb->Parity)
+ iMatch = n;
+ break;
+
+ case CMD_PARITY_NONE:
+ if (FALSE == pdcb->fParity && NOPARITY == pdcb->Parity)
+ iMatch = n;
+ break;
+
+ case CMD_PARITY_MARK:
+ if (TRUE == pdcb->fParity && MARKPARITY == pdcb->Parity)
+ iMatch = n;
+ break;
+
+ case CMD_PARITY_SPACE:
+ if (TRUE == pdcb->fParity && SPACEPARITY == pdcb->Parity)
+ iMatch = n;
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+
+ ASSERT(-1 != iDef);
+ s_defportsettings.iSelParity = iDef;
+
+ // Does the DCB value exist in our list?
+ if (-1 == iMatch)
+ {
+ // No; choose the default
+ iSel = iDef;
+ }
+ else
+ {
+ // Yes; choose the matched value
+ ASSERT(-1 != iMatch);
+ iSel = iMatch;
+ }
+ ComboBox_SetCurSel(hwndCB, iSel);
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Fills the stopbits combobox with the possible settings.
+Returns: --
+Cond: --
+*/
+void PRIVATE Port_FillStopBits(
+ PPORT this)
+ {
+ HWND hwndCB = this->hwndStopBits;
+ WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
+ int i;
+ int iSel;
+ int n;
+ int iMatch = -1;
+ int iDef = -1;
+ TCHAR sz[MAXMEDLEN];
+
+ // Fill the listbox
+ for (i = 0; i < ARRAYSIZE(s_rgstopbits); i++)
+ {
+ n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgstopbits[i].ids, sz, SIZECHARS(sz)));
+ ComboBox_SetItemData(hwndCB, n, s_rgstopbits[i].stopbits);
+
+ // Keep our eyes peeled for important values
+ if (DEFAULT_STOPBITS == s_rgstopbits[i].stopbits)
+ {
+ iDef = n;
+ }
+ if (pdcb->StopBits == s_rgstopbits[i].stopbits)
+ {
+ iMatch = n;
+ }
+ }
+
+ ASSERT(-1 != iDef);
+ s_defportsettings.iSelStopBits = iDef;
+
+ // Does the DCB value exist in our list?
+ if (-1 == iMatch)
+ {
+ // No; choose the default
+ iSel = iDef;
+ }
+ else
+ {
+ // Yes; choose the matched value
+ ASSERT(-1 != iMatch);
+ iSel = iMatch;
+ }
+ ComboBox_SetCurSel(hwndCB, iSel);
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Fills the flow control combobox with the possible settings.
+Returns: --
+Cond: --
+*/
+void PRIVATE Port_FillFlowCtl(
+ PPORT this)
+ {
+ HWND hwndCB = this->hwndFlowCtl;
+ WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
+ int i;
+ int iSel;
+ int n;
+ int iMatch = -1;
+ int iDef = -1;
+ TCHAR sz[MAXMEDLEN];
+
+ // Fill the listbox
+ for (i = 0; i < ARRAYSIZE(s_rgflowctl); i++)
+ {
+ n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgflowctl[i].ids, sz, SIZECHARS(sz)));
+ ComboBox_SetItemData(hwndCB, n, s_rgflowctl[i].cmd);
+
+ // Keep our eyes peeled for important values
+ if (DEFAULT_FLOWCTL == s_rgflowctl[i].cmd)
+ {
+ iDef = n;
+ }
+ switch (s_rgflowctl[i].cmd)
+ {
+ case CMD_FLOWCTL_XONXOFF:
+ if (TRUE == pdcb->fOutX && FALSE == pdcb->fOutxCtsFlow)
+ iMatch = n;
+ break;
+
+ case CMD_FLOWCTL_HARDWARE:
+ if (FALSE == pdcb->fOutX && TRUE == pdcb->fOutxCtsFlow)
+ iMatch = n;
+ break;
+
+ case CMD_FLOWCTL_NONE:
+ if (FALSE == pdcb->fOutX && FALSE == pdcb->fOutxCtsFlow)
+ iMatch = n;
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+
+ ASSERT(-1 != iDef);
+ s_defportsettings.iSelFlowCtl = iDef;
+
+ // Does the DCB value exist in our list?
+ if (-1 == iMatch)
+ {
+ // No; choose the default
+ iSel = iDef;
+ }
+ else
+ {
+ // Yes; choose the matched value
+ ASSERT(-1 != iMatch);
+ iSel = iMatch;
+ }
+ ComboBox_SetCurSel(hwndCB, iSel);
+ }
+
+
+/*----------------------------------------------------------
+Purpose: WM_INITDIALOG Handler
+Returns: FALSE when we assign the control focus
+Cond: --
+*/
+BOOL PRIVATE Port_OnInitDialog(
+ PPORT this,
+ HWND hwndFocus,
+ LPARAM lParam) // expected to be PROPSHEETINFO
+ {
+ LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
+ HWND hwnd = this->hdlg;
+
+ ASSERT((LPTSTR)lppsp->lParam);
+
+ this->pportinfo = (LPPORTINFO)lppsp->lParam;
+
+ // Save away the window handles
+ this->hwndBaudRate = GetDlgItem(hwnd, IDC_PS_BAUDRATE);
+ this->hwndDataBits = GetDlgItem(hwnd, IDC_PS_DATABITS);
+ this->hwndParity = GetDlgItem(hwnd, IDC_PS_PARITY);
+ this->hwndStopBits = GetDlgItem(hwnd, IDC_PS_STOPBITS);
+ this->hwndFlowCtl = GetDlgItem(hwnd, IDC_PS_FLOWCTL);
+
+ Port_FillBaud(this);
+ Port_FillDataBits(this);
+ Port_FillParity(this);
+ Port_FillStopBits(this);
+ Port_FillFlowCtl(this);
+
+#if !defined(SUPPORT_FIFO)
+
+ // Hide and disable the Advanced button
+ ShowWindow(GetDlgItem(hwnd, IDC_PS_ADVANCED), FALSE);
+ EnableWindow(GetDlgItem(hwnd, IDC_PS_ADVANCED), FALSE);
+
+#endif
+
+ return TRUE; // allow USER to set the initial focus
+ }
+
+/*----------------------------------------------------------
+Purpose: WM_COMMAND Handler
+Returns: --
+Cond: --
+*/
+void PRIVATE Port_OnCommand(
+ PPORT this,
+ int id,
+ HWND hwndCtl,
+ UINT uNotifyCode)
+ {
+ HWND hwnd = this->hdlg;
+
+ switch (id)
+ {
+ case IDC_PS_PB_RESTORE:
+ // Set the values to the default settings
+ ComboBox_SetCurSel(this->hwndBaudRate, s_defportsettings.iSelBaud);
+ ComboBox_SetCurSel(this->hwndDataBits, s_defportsettings.iSelDataBits);
+ ComboBox_SetCurSel(this->hwndParity, s_defportsettings.iSelParity);
+ ComboBox_SetCurSel(this->hwndStopBits, s_defportsettings.iSelStopBits);
+ ComboBox_SetCurSel(this->hwndFlowCtl, s_defportsettings.iSelFlowCtl);
+ break;
+
+#ifdef SUPPORT_FIFO
+
+ case IDC_PS_ADVANCED:
+ FeFiFoFum(this->hdlg, this->pportinfo->szFriendlyName);
+ break;
+
+#endif
+
+ default:
+ break;
+ }
+ }
+
+
+/*----------------------------------------------------------
+Purpose: PSN_APPLY handler
+Returns: --
+Cond: --
+*/
+void PRIVATE Port_OnApply(
+ PPORT this)
+ {
+ int iSel;
+ BYTE cmd;
+ WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
+
+ // Determine new speed settings
+ iSel = ComboBox_GetCurSel(this->hwndBaudRate);
+ pdcb->BaudRate = ComboBox_GetItemData(this->hwndBaudRate, iSel);
+
+
+ // Determine new byte size
+ iSel = ComboBox_GetCurSel(this->hwndDataBits);
+ pdcb->ByteSize = (BYTE)ComboBox_GetItemData(this->hwndDataBits, iSel);
+
+
+ // Determine new parity settings
+ iSel = ComboBox_GetCurSel(this->hwndParity);
+ cmd = (BYTE)ComboBox_GetItemData(this->hwndParity, iSel);
+ switch (cmd)
+ {
+ case CMD_PARITY_EVEN:
+ pdcb->fParity = TRUE;
+ pdcb->Parity = EVENPARITY;
+ break;
+
+ case CMD_PARITY_ODD:
+ pdcb->fParity = TRUE;
+ pdcb->Parity = ODDPARITY;
+ break;
+
+ case CMD_PARITY_NONE:
+ pdcb->fParity = FALSE;
+ pdcb->Parity = NOPARITY;
+ break;
+
+ case CMD_PARITY_MARK:
+ pdcb->fParity = TRUE;
+ pdcb->Parity = MARKPARITY;
+ break;
+
+ case CMD_PARITY_SPACE:
+ pdcb->fParity = TRUE;
+ pdcb->Parity = SPACEPARITY;
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ // Determine new stopbits setting
+ iSel = ComboBox_GetCurSel(this->hwndStopBits);
+ pdcb->StopBits = (BYTE)ComboBox_GetItemData(this->hwndStopBits, iSel);
+
+
+ // Determine new flow control settings
+ iSel = ComboBox_GetCurSel(this->hwndFlowCtl);
+ cmd = (BYTE)ComboBox_GetItemData(this->hwndFlowCtl, iSel);
+ switch (cmd)
+ {
+ case CMD_FLOWCTL_XONXOFF:
+ pdcb->fOutX = TRUE;
+ pdcb->fInX = TRUE;
+ pdcb->fOutxCtsFlow = FALSE;
+ pdcb->fRtsControl = RTS_CONTROL_DISABLE;
+ break;
+
+ case CMD_FLOWCTL_HARDWARE:
+ pdcb->fOutX = FALSE;
+ pdcb->fInX = FALSE;
+ pdcb->fOutxCtsFlow = TRUE;
+ pdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
+ break;
+
+ case CMD_FLOWCTL_NONE:
+ pdcb->fOutX = FALSE;
+ pdcb->fInX = FALSE;
+ pdcb->fOutxCtsFlow = FALSE;
+ pdcb->fRtsControl = RTS_CONTROL_DISABLE;
+ break;
+
+ default:
+ ASSERT(0); // should never be here
+ break;
+ }
+
+ this->pportinfo->idRet = IDOK;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: WM_NOTIFY handler
+Returns: varies
+Cond: --
+*/
+LRESULT PRIVATE Port_OnNotify(
+ PPORT this,
+ int idFrom,
+ NMHDR FAR * lpnmhdr)
+ {
+ LRESULT lRet = 0;
+
+ switch (lpnmhdr->code)
+ {
+ case PSN_SETACTIVE:
+ break;
+
+ case PSN_KILLACTIVE:
+ // N.b. This message is not sent if user clicks Cancel!
+ // N.b. This message is sent prior to PSN_APPLY
+ //
+ break;
+
+ case PSN_APPLY:
+ Port_OnApply(this);
+ break;
+
+ default:
+ break;
+ }
+
+ return lRet;
+ }
+
+
+///////////////////////////////////////////////////// EXPORTED FUNCTIONS
+
+static BOOL s_bPortRecurse = FALSE;
+
+LRESULT INLINE Port_DefProc(
+ HWND hDlg,
+ UINT msg,
+ WPARAM wParam,
+ LPARAM lParam)
+ {
+ ENTER_X()
+ {
+ s_bPortRecurse = TRUE;
+ }
+ LEAVE_X()
+
+ return DefDlgProc(hDlg, msg, wParam, lParam);
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Real dialog proc
+Returns: varies
+Cond: --
+*/
+LRESULT Port_DlgProc(
+ PPORT this,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
+ {
+#ifdef CS_HELP
+#pragma data_seg(DATASEG_READONLY)
+ const static DWORD rgHelpIDs[] = {
+ IDC_PS_LBL_BAUDRATE, IDH_PORT_BAUD,
+ IDC_PS_BAUDRATE, IDH_PORT_BAUD,
+ IDC_PS_LBL_DATABITS, IDH_PORT_DATA,
+ IDC_PS_DATABITS, IDH_PORT_DATA,
+ IDC_PS_LBL_PARITY, IDH_PORT_PARITY,
+ IDC_PS_PARITY, IDH_PORT_PARITY,
+ IDC_PS_LBL_STOPBITS, IDH_PORT_STOPBITS,
+ IDC_PS_STOPBITS, IDH_PORT_STOPBITS,
+ IDC_PS_LBL_FLOWCTL, IDH_PORT_FLOW,
+ IDC_PS_FLOWCTL, IDH_PORT_FLOW,
+ IDC_PS_PB_RESTORE, IDH_PORT_RESTORE,
+ 0, 0 };
+#pragma data_seg()
+#endif
+
+ switch (message)
+ {
+ HANDLE_MSG(this, WM_INITDIALOG, Port_OnInitDialog);
+ HANDLE_MSG(this, WM_COMMAND, Port_OnCommand);
+ HANDLE_MSG(this, WM_NOTIFY, Port_OnNotify);
+
+#ifdef CS_HELP
+ case WM_HELP:
+ WinHelp(((LPHELPINFO)lParam)->hItemHandle, c_szWinHelpFile, HELP_WM_HELP, (DWORD)(LPVOID)rgHelpIDs);
+ return 0;
+
+ case WM_CONTEXTMENU:
+ WinHelp((HWND)wParam, c_szWinHelpFile, HELP_CONTEXTMENU, (DWORD)(LPVOID)rgHelpIDs);
+ return 0;
+#endif
+
+ default:
+ return Port_DefProc(this->hdlg, message, wParam, lParam);
+ }
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Dialog Wrapper
+Returns: varies
+Cond: --
+*/
+BOOL CALLBACK Port_WrapperProc(
+ HWND hDlg, // std params
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
+ {
+ PPORT this;
+
+ // Cool windowsx.h dialog technique. For full explanation, see
+ // WINDOWSX.TXT. This supports multiple-instancing of dialogs.
+ //
+ ENTER_X()
+ {
+ if (s_bPortRecurse)
+ {
+ s_bPortRecurse = FALSE;
+ LEAVE_X()
+ return FALSE;
+ }
+ }
+ LEAVE_X()
+
+ this = Port_GetPtr(hDlg);
+ if (this == NULL)
+ {
+ if (message == WM_INITDIALOG)
+ {
+ this = (PPORT)LocalAlloc(LPTR, sizeof(PORT));
+ if (!this)
+ {
+ MsgBox(g_hinst,
+ hDlg,
+ MAKEINTRESOURCE(IDS_OOM_PORT),
+ MAKEINTRESOURCE(IDS_CAP_PORT),
+ NULL,
+ MB_ERROR);
+ EndDialog(hDlg, IDCANCEL);
+ return (BOOL)Port_DefProc(hDlg, message, wParam, lParam);
+ }
+ this->hdlg = hDlg;
+ Port_SetPtr(hDlg, this);
+ }
+ else
+ {
+ return (BOOL)Port_DefProc(hDlg, message, wParam, lParam);
+ }
+ }
+
+ if (message == WM_DESTROY)
+ {
+ Port_DlgProc(this, message, wParam, lParam);
+ LocalFree((HLOCAL)OFFSETOF(this));
+ Port_SetPtr(hDlg, NULL);
+ return 0;
+ }
+
+ return SetDlgMsgResult(hDlg, message, Port_DlgProc(this, message, wParam, lParam));
+ }
+
+
+#ifdef SUPPORT_FIFO
+
+//
+// Advanced Port Settings
+//
+
+#pragma data_seg(DATASEG_READONLY)
+
+// Fifo related strings
+
+TCHAR const FAR c_szSettings[] = TEXT("Settings");
+TCHAR const FAR c_szComxFifo[] = TEXT("Fifo");
+TCHAR const FAR c_szEnh[] = TEXT("386Enh");
+TCHAR const FAR c_szSystem[] = TEXT("system.ini");
+
+#pragma data_seg()
+
+
+/*----------------------------------------------------------
+Purpose: Set the dialog controls
+
+Returns: --
+Cond: --
+*/
+void DisplayAdvSettings(
+ HWND hDlg,
+ BYTE RxTrigger,
+ BYTE TxTrigger,
+ BOOL bUseFifo)
+ {
+ SendDlgItemMessage(hDlg, IDC_RXFIFO_USAGE, TBM_SETRANGE, 0, 0x30000);
+ SendDlgItemMessage(hDlg, IDC_TXFIFO_USAGE, TBM_SETRANGE, 0, 0x30000);
+
+ // Use FIFO?
+ if ( !bUseFifo )
+ {
+ // No
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO), FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_LO), FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_HI), FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDC_RXFIFO_USAGE), FALSE);
+
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO), FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_LO), FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_HI), FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDC_TXFIFO_USAGE), FALSE);
+ CheckDlgButton(hDlg, IDC_FIFO_USAGE, FALSE);
+ }
+ else
+ {
+ CheckDlgButton(hDlg, IDC_FIFO_USAGE, TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_LO), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_HI), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_RXFIFO_USAGE), TRUE);
+
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_LO), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_HI), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_TXFIFO_USAGE), TRUE);
+ SendDlgItemMessage(hDlg, IDC_RXFIFO_USAGE, TBM_SETPOS,
+ TRUE, RxTrigger);
+ SendDlgItemMessage(hDlg, IDC_TXFIFO_USAGE, TBM_SETPOS,
+ TRUE, TxTrigger/4);
+ }
+ }
+
+
+typedef struct tagSETTINGS
+ {
+ BYTE fifoon;
+ BYTE txfifosize;
+ BYTE dsron;
+ BYTE rxtriggersize;
+ } SETTINGS;
+
+typedef enum
+ {
+ ACT_GET,
+ ACT_SET
+ } ACTION;
+
+BYTE RxTriggerValues[4]={0,0x40,0x80,0xC0};
+
+
+/*----------------------------------------------------------
+Purpose: Gets or sets the advanced settings of the port
+
+Returns: --
+Cond: --
+*/
+void GetSetAdvSettings(
+ LPCTSTR pszPortName,
+ BYTE FAR *RxTrigger,
+ BYTE FAR *TxTrigger,
+ BOOL FAR * pbUseFifo,
+ ACTION action)
+ {
+ LPFINDDEV pfd;
+ DWORD cbData;
+ SETTINGS settings;
+ TCHAR szFifo[256];
+ TCHAR OnStr[2] = TEXT("0");
+
+ ASSERT(pszPortName);
+
+ // In Win95, the FIFO settings were (wrongfully) stored in the
+ // device key. I've changed this to look in the driver key.
+ // (scotth)
+
+ if (FindDev_Create(&pfd, c_pguidPort, c_szFriendlyName, pszPortName) ||
+ FindDev_Create(&pfd, c_pguidPort, c_szPortName, pszPortName) ||
+ FindDev_Create(&pfd, c_pguidModem, c_szPortName, pszPortName))
+ {
+ switch (action)
+ {
+ case ACT_GET:
+ ASSERT(4 == sizeof(SETTINGS));
+
+ cbData = sizeof(SETTINGS);
+ if (ERROR_SUCCESS != RegQueryValueEx(pfd->hkeyDrv, c_szSettings, NULL,
+ NULL, (LPBYTE)&settings, &cbData))
+ {
+ // Default settings if not in registry
+ settings.fifoon = 0x02;
+ settings.dsron = 0;
+ settings.txfifosize = 16;
+ settings.rxtriggersize = 0x80;
+ }
+ if (!settings.fifoon)
+ *pbUseFifo = FALSE;
+ else
+ *pbUseFifo = TRUE;
+ settings.rxtriggersize = settings.rxtriggersize % 0xC1;
+ *RxTrigger = settings.rxtriggersize/0x40;
+ *TxTrigger = settings.txfifosize % 17;
+ break;
+
+ case ACT_SET:
+ if (FALSE == *pbUseFifo)
+ settings.fifoon = 0;
+ else
+ settings.fifoon = 2;
+
+ settings.rxtriggersize = RxTriggerValues[*RxTrigger];
+ settings.dsron = 0;
+ settings.txfifosize = (*TxTrigger)*5+1;
+ RegSetValueEx(pfd->hkeyDrv, c_szSettings, 0, REG_BINARY,
+ (LPBYTE)&settings, sizeof(SETTINGS));
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ cbData = sizeof(szFifo) - 6; // leave room for "fifo" on the end
+ RegQueryValueEx(pfd->hkeyDrv, c_szPortName, NULL, NULL, (LPBYTE)szFifo,
+ &cbData);
+
+ FindDev_Destroy(pfd);
+
+ lstrcat(szFifo, c_szComxFifo);
+ if (*pbUseFifo)
+ WritePrivateProfileString(c_szEnh, szFifo, NULL, c_szSystem);
+ else
+ WritePrivateProfileString(c_szEnh, szFifo, OnStr, c_szSystem);
+ }
+ }
+
+
+
+/*----------------------------------------------------------
+Purpose: Dialog proc for advanced port settings
+
+Returns: standard
+Cond: --
+*/
+BOOL CALLBACK AdvPort_DlgProc(
+ HWND hDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+ {
+ BOOL bRet = FALSE;
+ BYTE rxtrigger, txtrigger;
+ BOOL bUseFifo;
+ LPCTSTR pszPortName;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ pszPortName = (LPCTSTR)lParam;
+ SetWindowLong(hDlg, DWL_USER, (LONG)pszPortName);
+
+ GetSetAdvSettings(pszPortName, &rxtrigger, &txtrigger, &bUseFifo, ACT_GET);
+ DisplayAdvSettings(hDlg, rxtrigger, txtrigger, bUseFifo);
+ break;
+
+ case WM_COMMAND:
+ pszPortName = (LPCTSTR)GetWindowLong(hDlg, DWL_USER);
+ if (!pszPortName)
+ {
+ ASSERT(0);
+ break;
+ }
+
+ switch (wParam)
+ {
+ case IDOK:
+ if (IsDlgButtonChecked(hDlg, IDC_FIFO_USAGE))
+ bUseFifo = TRUE;
+ else
+ bUseFifo = FALSE;
+
+ rxtrigger = (BYTE)SendDlgItemMessage(hDlg,
+ IDC_RXFIFO_USAGE, TBM_GETPOS, 0, 0);
+ txtrigger = (BYTE)SendDlgItemMessage(hDlg,
+ IDC_TXFIFO_USAGE, TBM_GETPOS, 0, 0);
+
+ GetSetAdvSettings(pszPortName, &rxtrigger, &txtrigger, &bUseFifo, ACT_SET);
+
+ // Fall thru
+ // | |
+ // v v
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDOK == wParam);
+ break;
+
+ case IDC_FIFO_USAGE:
+ if (!IsDlgButtonChecked(hDlg, IDC_FIFO_USAGE))
+ DisplayAdvSettings(hDlg, 0, 0, FALSE);
+ else
+ {
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_LO), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_HI), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_RXFIFO_USAGE), TRUE);
+
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_LO), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_HI), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_TXFIFO_USAGE), TRUE);
+ }
+ break;
+
+ case IDC_DEFAULTS:
+ DisplayAdvSettings(hDlg, 2, 12, TRUE);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return bRet;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Private entry point to show the Advanced Fifo dialog
+
+Returns: IDOK or IDCANCEL
+
+Cond: --
+*/
+UINT WINAPI FeFiFoFum(
+ HWND hwndOwner,
+ LPCTSTR pszPortName)
+ {
+ UINT uRet = (UINT)-1;
+
+ // Invoke the advanced dialog
+ if (pszPortName)
+ {
+ uRet = DialogBoxParam(g_hinst, MAKEINTRESOURCE(IDD_ADV_PORT),
+ hwndOwner, AdvPort_DlgProc, (LPARAM)pszPortName);
+ }
+ return uRet;
+ }
+
+#endif // SUPPORT_FIFO
diff --git a/private/unimodem/serialui/proj.h b/private/unimodem/serialui/proj.h
new file mode 100644
index 000000000..5c9f3789a
--- /dev/null
+++ b/private/unimodem/serialui/proj.h
@@ -0,0 +1,99 @@
+//
+// proj.h: Includes all files that are to be part of the precompiled
+// header.
+//
+
+#ifndef __PROJ_H__
+#define __PROJ_H__
+
+//
+// Private Defines
+//
+
+//#define SUPPORT_FIFO // Win95 only: support Advanced FIFO dialog
+//#define DCB_IN_REGISTRY // Plug-and-play: The port driver info is stored in the registry
+
+
+#define STRICT
+
+#if DBG > 0 && !defined(DEBUG)
+#define DEBUG
+#endif
+#if DBG > 0 && !defined(FULL_DEBUG)
+#define FULL_DEBUG
+#endif
+
+#define UNICODE
+
+// Defines for rovcomm.h
+
+#define NODA
+#define NOSHAREDHEAP
+#define NOFILEINFO
+#define NOCOLORHELP
+#define NODRAWTEXT
+#define NOPATH
+#define NOSYNC
+#ifndef DEBUG
+#define NOPROFILE
+#endif
+
+#define SZ_MODULEA "SERIALUI"
+#define SZ_MODULEW TEXT("SERIALUI")
+
+#ifdef DEBUG
+#define SZ_DEBUGSECTION TEXT("SERIALUI")
+#define SZ_DEBUGINI TEXT("unimdm.ini")
+#endif // DEBUG
+
+// Includes
+
+#define USECOMM
+
+#include <windows.h>
+#include <windowsx.h>
+
+#include <winerror.h>
+#include <commctrl.h> // needed by shlobj.h and our progress bar
+#include <prsht.h> // Property sheet stuff
+#include <rovcomm.h>
+#include <modemp.h>
+#include <shellapi.h> // for registration functions
+#include <regstr.h>
+
+#ifdef WIN95
+#include <setupx.h> // PnP setup/installer services
+#else
+#include <setupapi.h> // PnP setup/installer services
+#endif
+
+#define MAXBUFLEN MAX_BUF
+#define MAXMSGLEN MAX_BUF_MSG
+#define MAXMEDLEN MAX_BUF_MED
+#define MAXSHORTLEN MAX_BUF_SHORT
+
+#ifndef LINE_LEN
+#define LINE_LEN MAXBUFLEN
+#endif
+
+// local includes
+//
+#include "dll.h"
+#include "cstrings.h" // Read-only string constants
+#include "util.h" // Utility functions
+#include "serialui.h"
+#include "rcids.h"
+#include "dlgids.h"
+
+//****************************************************************************
+//
+//****************************************************************************
+
+
+// Dump flags
+#define DF_DCB 0x00000001
+#define DF_MODEMSETTINGS 0x00000002
+#define DF_DEVCAPS 0x00000004
+
+#endif //!__PROJ_H__
+
diff --git a/private/unimodem/serialui/rcids.h b/private/unimodem/serialui/rcids.h
new file mode 100644
index 000000000..e165180ab
--- /dev/null
+++ b/private/unimodem/serialui/rcids.h
@@ -0,0 +1,109 @@
+//{{NO_DEPENDENCIES}}
+// App Studio generated include file.
+// Used by SYNCUI.RC
+//
+
+// Icon values
+//
+#define IDI_NULL_MODEM 700
+#define IDI_EXTERNAL_MODEM 701
+#define IDI_INTERNAL_MODEM 702
+#define IDI_PCMCIA_MODEM 703
+
+// Bitmap values
+//
+#define IDB_ACTIONS 108
+#define IDB_SMALLACTIONS_MASK 111
+#define IDB_CONTAIN 801
+#define IDB_CONTAIN_MASK 802
+#define IDB_ACTIONS_MASK 803
+#define IDB_SMALLACTIONS 804
+#define IDB_MENU_MASK 806
+#define IDB_MENU 806
+
+// Random stuff
+//
+#define IDS_NULL_MODEM 180
+#define IDS_EXTERNAL_MODEM 181
+#define IDS_INTERNAL_MODEM 182
+#define IDS_PCMCIA_MODEM 183
+#define IDS_PARALLEL_MODEM 184
+#define IDS_PARALLEL_PORT 185
+
+#define IDS_BAUD_110 200
+#define IDS_BAUD_1200 201
+#define IDS_BAUD_2400 202
+#define IDS_BAUD_4800 203
+#define IDS_BAUD_9600 204
+#define IDS_BAUD_14400 205
+#define IDS_BAUD_19200 206
+#define IDS_BAUD_38400 207
+#define IDS_BAUD_56K 208
+#define IDS_BAUD_128K 209
+#define IDS_BAUD_115200 210
+#define IDS_BAUD_57600 211
+#define IDS_BAUD_FASTEST 212
+#define IDS_BAUD_075 213
+#define IDS_BAUD_134_5 214
+#define IDS_BAUD_150 215
+#define IDS_BAUD_300 216
+#define IDS_BAUD_600 217
+#define IDS_BAUD_1800 218
+#define IDS_BAUD_7200 219
+#define IDS_BAUD_230400 220
+#define IDS_BAUD_460800 221
+#define IDS_BAUD_921600 222
+
+#define IDS_BYTESIZE_4 240
+#define IDS_BYTESIZE_5 241
+#define IDS_BYTESIZE_6 242
+#define IDS_BYTESIZE_7 243
+#define IDS_BYTESIZE_8 244
+
+#define IDS_PARITY_EVEN 250
+#define IDS_PARITY_ODD 251
+#define IDS_PARITY_NONE 252
+#define IDS_PARITY_MARK 253
+#define IDS_PARITY_SPACE 254
+#define IDS_STOPBITS_1 255
+#define IDS_STOPBITS_1_5 256
+#define IDS_STOPBITS_2 257
+
+#define IDS_FLOWCTL_XONXOFF 260
+#define IDS_FLOWCTL_HARDWARE 261
+#define IDS_FLOWCTL_NONE 262
+
+#define IDS_LOGFILE 270
+
+// Messages
+//
+
+// Captions
+//
+#define IDS_CAP_GENERAL 340
+#define IDS_CAP_SETTINGS 341
+#define IDS_CAP_PORT 342
+
+// Formatted strings
+//
+
+// Error strings
+//
+
+// Out-of-memory strings
+//
+#define IDS_OOM_GENERAL 460
+#define IDS_OOM_SETTINGS 461
+#define IDS_OOM_PORT 462
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NEXT_RESOURCE_VALUE 113
+#define _APS_NEXT_COMMAND_VALUE 105
+#define _APS_NEXT_CONTROL_VALUE 1006
+#define _APS_NEXT_SYMED_VALUE 105
+#endif
+#endif
diff --git a/private/unimodem/serialui/serialui.c b/private/unimodem/serialui/serialui.c
new file mode 100644
index 000000000..b1baad242
--- /dev/null
+++ b/private/unimodem/serialui/serialui.c
@@ -0,0 +1,989 @@
+//---------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation 1993-1996
+//
+// File: serialui.c
+//
+// This files contains the DLL entry-points.
+//
+// Much of this file contains the code that builds the default property dialog
+// for serial ports.
+//
+// History:
+// 1-12-94 ScottH Created
+// 8-15-94 ScottH Split from modemui.dll
+// 11-06-95 ScottH Ported to NT
+//
+//---------------------------------------------------------------------------
+
+
+#include "proj.h" // common headers
+
+#define INITGUID
+#include <initguid.h>
+#include <devguid.h>
+
+#pragma data_seg(DATASEG_READONLY)
+
+LPGUID c_pguidModem = (LPGUID)&GUID_DEVCLASS_MODEM;
+
+// BUGBUG (scotth): it looks like for the NT SUR release, that there
+// will be no Port class key or GUID. So we have to hack something
+// up.
+#ifdef DCB_IN_REGISTRY
+LPGUID c_pguidPort = (LPGUID)&GUID_DEVCLASS_PORT;
+#else
+LPGUID c_pguidPort = (LPGUID)NULL;
+#endif
+
+#pragma data_seg()
+
+
+#define MAX_PROP_PAGES 8 // Define a reasonable limit
+
+
+#ifdef DEBUG
+
+//-----------------------------------------------------------------------------------
+// Debug routines
+//-----------------------------------------------------------------------------------
+
+/*----------------------------------------------------------
+Purpose: Dumps the DCB struct
+Returns: --
+Cond: --
+*/
+void PRIVATE DumpDCB(
+ LPWIN32DCB pdcb)
+ {
+ ASSERT(pdcb);
+
+ if (IsFlagSet(g_dwDumpFlags, DF_DCB))
+ {
+ int i;
+ LPDWORD pdw = (LPDWORD)pdcb;
+
+ TRACE_MSG(TF_ALWAYS, "DCB %08lx %08lx %08lx %08lx", pdw[0], pdw[1], pdw[2], pdw[3]);
+ pdw += 4;
+ for (i = 0; i < sizeof(WIN32DCB)/sizeof(DWORD); i += 4, pdw += 4)
+ {
+ TRACE_MSG(TF_ALWAYS, " %08lx %08lx %08lx %08lx", pdw[0], pdw[1], pdw[2], pdw[3]);
+ }
+ }
+ }
+
+#endif //DEBUG
+
+
+//-----------------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------------
+
+
+/*----------------------------------------------------------
+Purpose: Composes a string of the format "baud,parity,data,stopbit"
+
+Returns: --
+Cond: --
+*/
+void PRIVATE ComposeModeComString(
+ LPCOMMCONFIG pcc,
+ LPTSTR pszBuffer)
+ {
+ WIN32DCB FAR * pdcb = &pcc->dcb;
+ TCHAR chParity;
+ LPCTSTR pszStop;
+ TCHAR chFlow;
+
+ static TCHAR rgchParity[] = {'n', 'o', 'e', 'm', 's'};
+ static LPCTSTR rgpszStop[] = {TEXT("1"), TEXT("1.5"), TEXT("2")};
+
+ // Parity
+ ASSERT(!pdcb->fParity && NOPARITY == pdcb->Parity || pdcb->fParity);
+ ASSERT(0 <= pdcb->Parity && ARRAYSIZE(rgchParity) > pdcb->Parity);
+
+ if (0 <= pdcb->Parity && ARRAYSIZE(rgchParity) > pdcb->Parity)
+ {
+ chParity = rgchParity[pdcb->Parity];
+ }
+ else
+ {
+ chParity = rgchParity[0]; // Safety net
+ }
+
+ // Stop bits
+ ASSERT(0 <= pdcb->StopBits && ARRAYSIZE(rgpszStop) > pdcb->StopBits);
+
+ if (0 <= pdcb->StopBits && ARRAYSIZE(rgpszStop) > pdcb->StopBits)
+ {
+ pszStop = rgpszStop[pdcb->StopBits];
+ }
+ else
+ {
+ pszStop = rgpszStop[0]; // Safety net
+ }
+
+ // Flow control
+ if (FALSE != pdcb->fOutX && FALSE == pdcb->fOutxCtsFlow)
+ {
+ chFlow = 'x'; // XON/XOFF flow control
+ }
+ else if (FALSE == pdcb->fOutX && FALSE != pdcb->fOutxCtsFlow)
+ {
+ chFlow = 'p'; // Hardware flow control
+ }
+ else
+ {
+ chFlow = ' '; // No flow control
+ }
+
+ wsprintf(pszBuffer, TEXT("%ld,%c,%d,%s,%c"), pdcb->BaudRate, chParity, pdcb->ByteSize,
+ pszStop, chFlow);
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Initialize the port info.
+
+Returns: --
+Cond: --
+*/
+void PRIVATE InitializePortInfo(
+ LPCTSTR pszFriendlyName,
+ LPPORTINFO pportinfo,
+ LPCOMMCONFIG pcc)
+ {
+ ASSERT(pportinfo);
+ ASSERT(pcc);
+
+ // Read-only fields
+ pportinfo->pcc = pcc;
+
+ BltByte(&pportinfo->dcb, &pcc->dcb, sizeof(pportinfo->dcb));
+
+ lstrcpyn(pportinfo->szFriendlyName, pszFriendlyName, SIZECHARS(pportinfo->szFriendlyName));
+ }
+
+
+
+/*----------------------------------------------------------
+Purpose: Gets a WIN32DCB from the registry.
+
+Returns: One of the ERROR_ values
+Cond: --
+*/
+DWORD
+PRIVATE
+RegQueryDCB(
+ IN LPFINDDEV pfd,
+ OUT WIN32DCB FAR * pdcb)
+ {
+ DWORD dwRet = ERROR_BADKEY;
+
+#ifdef DCB_IN_REGISTRY
+
+ DWORD cbData;
+
+ ASSERT(pdcb);
+
+ // Does the DCB key exist in the driver key?
+ if (ERROR_SUCCESS == RegQueryValueEx(pfd->hkeyDrv, c_szDCB, NULL, NULL, NULL, &cbData))
+ {
+ // Yes; is the size in the registry okay?
+ if (sizeof(*pdcb) < cbData)
+ {
+ // No; the registry has bogus data
+ dwRet = ERROR_BADDB;
+ }
+ else
+ {
+ // Yes; get the DCB from the registry
+ if (ERROR_SUCCESS == RegQueryValueEx(pfd->hkeyDrv, c_szDCB, NULL, NULL, (LPBYTE)pdcb, &cbData))
+ {
+ if (sizeof(*pdcb) == pdcb->DCBlength)
+ {
+ dwRet = NO_ERROR;
+ }
+ else
+ {
+ dwRet = ERROR_BADDB;
+ }
+ }
+ else
+ {
+ dwRet = ERROR_BADKEY;
+ }
+ }
+ }
+
+#else
+
+#pragma data_seg(DATASEG_READONLY)
+ static TCHAR const FAR c_szDefaultDCBString[] = TEXT("96,n,8,1");
+#pragma data_seg()
+
+ TCHAR sz[MAX_BUF_MED];
+ TCHAR szKey[MAX_BUF_SHORT];
+
+ lstrcpy(szKey, pfd->szPort);
+ lstrcat(szKey, TEXT(":"));
+
+ GetProfileString(c_szPortClass, szKey, c_szDefaultDCBString, sz, SIZECHARS(sz));
+
+ TRACE_MSG(TF_GENERAL, "DCB string is \"%s\"", sz);
+
+ // Convert the DCB string to a DCB structure
+ if ( !BuildCommDCB(sz, pdcb) )
+ {
+ dwRet = GetLastError();
+
+ ASSERT(NO_ERROR != dwRet);
+ }
+ else
+ {
+ dwRet = NO_ERROR;
+ }
+
+#endif
+
+ return dwRet;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Save the DCB to the permanent storage
+
+Returns: win32 error
+Cond: --
+*/
+DWORD
+PRIVATE
+RegSetDCB(
+ IN LPFINDDEV pfd,
+ IN WIN32DCB FAR * pdcb)
+ {
+ DWORD dwRet;
+
+#ifdef DCB_IN_REGISTRY
+
+ DWORD cbData;
+
+ // Write the DCB to the driver key
+ cbData = sizeof(WIN32DCB);
+ dwRet = RegSetValueEx(pfd->hkeyDrv, c_szDCB, 0, REG_BINARY, (LPBYTE)&pcc->dcb, cbData);
+
+#else
+
+ dwRet = NO_ERROR;
+
+#endif
+
+ return dwRet;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Frees the portinfo struct
+
+Returns: --
+Cond: --
+*/
+void PRIVATE FreePortInfo(
+ LPPORTINFO pportinfo)
+ {
+ if (pportinfo)
+ {
+ if (pportinfo->pcc)
+ LocalFree(LOCALOF(pportinfo->pcc));
+
+ LocalFree(LOCALOF(pportinfo));
+ }
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Release the data associated with the Port Settings page
+Returns: --
+Cond: --
+*/
+UINT CALLBACK PortSettingsCallback(
+ HWND hwnd,
+ UINT uMsg,
+ LPPROPSHEETPAGE ppsp)
+ {
+ DBG_ENTER("PortSettingsCallback");
+
+ if (PSPCB_RELEASE == uMsg)
+ {
+ LPPORTINFO pportinfo = (LPPORTINFO)ppsp->lParam;
+ LPCOMMCONFIG pcc;
+
+ ASSERT(pportinfo);
+
+ pcc = pportinfo->pcc;
+
+ if (IDOK == pportinfo->idRet)
+ {
+ // Save the changes back to the commconfig struct
+ TRACE_MSG(TF_GENERAL, "Saving DCB");
+
+ BltByte(&pcc->dcb, &pportinfo->dcb, sizeof(pcc->dcb));
+
+ DEBUG_CODE( DumpDCB(&pcc->dcb); )
+
+ // Are we releasing from the Device Mgr?
+ if (IsFlagSet(pportinfo->uFlags, SIF_FROM_DEVMGR))
+ {
+ // Yes; save the commconfig now as well
+ drvSetDefaultCommConfig(pportinfo->szFriendlyName, pcc, pcc->dwSize);
+
+ // Free the portinfo struct only when called from the Device Mgr
+ FreePortInfo(pportinfo);
+ }
+ }
+
+ TRACE_MSG(TF_GENERAL, "Releasing the Port Settings page");
+ }
+
+ DBG_EXIT("PortSettingsCallback");
+ return TRUE;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Add the port settings page.
+
+Returns: ERROR_ value
+
+Cond: --
+*/
+DWORD PRIVATE AddPortSettingsPage(
+ LPPORTINFO pportinfo,
+ LPFNADDPROPSHEETPAGE pfnAdd,
+ LPARAM lParam)
+ {
+ DWORD dwRet = ERROR_NOT_ENOUGH_MEMORY;
+ PROPSHEETPAGE psp;
+ HPROPSHEETPAGE hpage;
+
+ ASSERT(pportinfo);
+ ASSERT(pfnAdd);
+
+ // Add the Port Settings property page
+ //
+ psp.dwSize = sizeof(PROPSHEETPAGE);
+ psp.dwFlags = PSP_USECALLBACK;
+ psp.hInstance = g_hinst;
+ psp.pszTemplate = MAKEINTRESOURCE(IDD_PORTSETTINGS);
+ psp.pfnDlgProc = Port_WrapperProc;
+ psp.lParam = (LPARAM)pportinfo;
+ psp.pfnCallback = PortSettingsCallback;
+
+ hpage = CreatePropertySheetPage(&psp);
+ if (hpage)
+ {
+ if (!pfnAdd(hpage, lParam))
+ DestroyPropertySheetPage(hpage);
+ else
+ dwRet = NO_ERROR;
+ }
+
+ return dwRet;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Function that is called by EnumPropPages entry-point to
+ add property pages.
+
+Returns: TRUE on success
+ FALSE on failure
+
+Cond: --
+*/
+BOOL CALLBACK AddInstallerPropPage(
+ HPROPSHEETPAGE hPage,
+ LPARAM lParam)
+ {
+ PROPSHEETHEADER FAR * ppsh = (PROPSHEETHEADER FAR *)lParam;
+
+ if (ppsh->nPages < MAX_PROP_PAGES)
+ {
+ ppsh->phpage[ppsh->nPages] = hPage;
+ ++ppsh->nPages;
+ return(TRUE);
+ }
+ return(FALSE);
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Bring up property sheet for a serial port
+
+Returns: ERROR_ value
+Cond: --
+*/
+DWORD PRIVATE DoProperties(
+ LPCTSTR pszFriendlyName,
+ HWND hwndParent,
+ LPCOMMCONFIG pcc)
+ {
+ DWORD dwRet;
+ PROPSHEETHEADER psh;
+ HPROPSHEETPAGE hpsPages[MAX_PROP_PAGES];
+ LPPORTINFO pportinfo;
+
+ // Initialize the PropertySheet Header
+ psh.dwSize = sizeof(psh);
+ psh.dwFlags = PSH_PROPTITLE;
+ psh.hwndParent = hwndParent;
+ psh.hInstance = g_hinst;
+ psh.nPages = 0;
+ psh.nStartPage = 0;
+ psh.phpage = (HPROPSHEETPAGE FAR *)hpsPages;
+
+ // Allocate the working buffer
+ //
+ pportinfo = (LPPORTINFO)LocalAlloc(LPTR, sizeof(*pportinfo));
+ if (pportinfo)
+ {
+ InitializePortInfo(pszFriendlyName, pportinfo, pcc);
+ psh.pszCaption = pportinfo->szFriendlyName;
+
+ DEBUG_CODE( DumpDCB(&pcc->dcb); )
+
+ dwRet = AddPortSettingsPage(pportinfo, AddInstallerPropPage, (LPARAM)&psh);
+
+ if (NO_ERROR == dwRet)
+ {
+ // Show the property sheet
+ PropertySheet(&psh);
+
+ dwRet = (IDOK == pportinfo->idRet) ? NO_ERROR : ERROR_CANCELLED;
+ }
+
+ // Clear the pcc field so FreePortInfo does not prematurely free it,
+ // since we did not allocate it.
+ pportinfo->pcc = NULL;
+ FreePortInfo(pportinfo);
+ }
+ else
+ {
+ dwRet = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ return dwRet;
+ }
+
+
+#ifdef WIN95
+
+// The Device Manager allows DLLs to add pages to the properties
+// of a device. EnumPropPages is the entry-point that it would
+// call to add pages.
+//
+// This is not implemented in NT.
+
+
+/*----------------------------------------------------------
+Purpose: Derives a PORTINFO struct from a device info.
+
+Returns: TRUE on success
+
+Cond: --
+*/
+BOOL PRIVATE DeviceInfoToPortInfo(
+ LPDEVICE_INFO pdi,
+ LPPORTINFO pportinfo)
+ {
+ BOOL bRet = FALSE;
+ LPFINDDEV pfd;
+ COMMCONFIG ccDummy;
+ LPCOMMCONFIG pcommconfig;
+ DWORD cbSize;
+ DWORD cbData;
+ TCHAR szFriendly[MAXFRIENDLYNAME];
+
+ // Find the device by looking for the device description. (Note the
+ // device description is not always the same as the friendly name.)
+
+ if (FindDev_Create(&pfd, c_pguidPort, c_szDeviceDesc, pdi->szDescription))
+ {
+ cbData = sizeof(szFriendly);
+ if (ERROR_SUCCESS == RegQueryValueEx(pfd->hkeyDev, c_szFriendlyName, NULL, NULL,
+ (LPBYTE)szFriendly, &cbData))
+ {
+ ccDummy.dwProviderSubType = PST_RS232;
+ cbSize = sizeof(COMMCONFIG);
+ drvGetDefaultCommConfig(szFriendly, &ccDummy, &cbSize);
+
+ pcommconfig = (LPCOMMCONFIG)LocalAlloc(LPTR, (UINT)cbSize);
+ if (pcommconfig)
+ {
+ // Get the commconfig from the registry
+ pcommconfig->dwProviderSubType = PST_RS232;
+ if (NO_ERROR == drvGetDefaultCommConfig(szFriendly, pcommconfig,
+ &cbSize))
+ {
+ // Initialize the modem info from the commconfig
+ InitializePortInfo(szFriendly, pportinfo, pcommconfig);
+
+ SetFlag(pportinfo->uFlags, SIF_FROM_DEVMGR);
+ bRet = TRUE;
+ }
+ else
+ {
+ // Failure
+ LocalFree(LOCALOF(pcommconfig));
+ }
+
+ // pcommconfig is freed in ReleasePortSettingsPage
+ }
+ }
+ FindDev_Destroy(pfd);
+ }
+
+ return bRet;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: EnumDevicePropPages entry-point. This entry-point
+ gets called only when the Device Manager asks for
+ additional property pages.
+
+Returns: TRUE on success
+ FALSE if pages could not be added
+Cond: --
+*/
+BOOL WINAPI EnumPropPages(
+ LPDEVICE_INFO pdi,
+ LPFNADDPROPSHEETPAGE pfnAdd,
+ LPARAM lParam) // Don't touch the lParam value, just pass it on!
+ {
+ BOOL bRet = FALSE;
+ LPPORTINFO pportinfo;
+
+ DBG_ENTER("EnumPropPages");
+
+ ASSERT(pdi);
+ ASSERT(pfnAdd);
+
+ pportinfo = (LPPORTINFO)LocalAlloc(LPTR, sizeof(*pportinfo));
+ if (pportinfo)
+ {
+ // Convert the device info struct to a portinfo.
+ bRet = DeviceInfoToPortInfo(pdi, pportinfo);
+ if (bRet)
+ {
+ AddPortSettingsPage(pportinfo, pfnAdd, lParam);
+ }
+ else
+ {
+ // Failed
+ FreePortInfo(pportinfo);
+ }
+ // pportinfo is freed in ReleasePortSettingsPage
+ }
+
+ DBG_EXIT_BOOL("EnumPropPages", bRet);
+
+ return bRet;
+ }
+#endif
+
+
+/*----------------------------------------------------------
+Purpose: Invokes the serial port configuration dialog.
+
+Returns: One of the ERROR_ values
+Cond: --
+*/
+DWORD
+PRIVATE
+MyCommConfigDialog(
+ IN LPFINDDEV pfd,
+ IN LPCTSTR pszFriendlyName,
+ IN HWND hwndOwner,
+ IN OUT LPCOMMCONFIG pcc)
+ {
+ DWORD dwRet;
+
+ ASSERT(pfd);
+ // (Wrapper should have checked these first)
+ ASSERT(pszFriendlyName);
+ ASSERT(pcc);
+ ASSERT(sizeof(*pcc) <= pcc->dwSize);
+
+ dwRet = DoProperties(pszFriendlyName, hwndOwner, pcc);
+
+ return dwRet;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Gets the default COMMCONFIG for the specified device.
+ This API doesn't require a handle.
+
+ If the caller passed in a null device name or a null
+ commconfig pointer, this function will set *pdwSize to
+ the minimum COMMCONFIG size. Calling this function
+ a second time (after setting the dwSize and dwProviderSubType
+ fields) will verify if the size is correct.
+
+ So generally, when getting a commconfig for serial ports,
+ the process is:
+
+ COMMCONFIG ccDummy;
+ LPCOMMCONFIG pcc;
+ DWORD dwSize = sizeof(*pcc);
+
+ // Determine real size of COMMCONFIG for RS-232 subtype
+ ccDummy.dwProviderSubType = PST_RS232;
+ GetDefaultCommConfig(pszFriendlyName, &ccDummy, &dwSize);
+
+ // Allocate real commconfig struct and initialize
+ pcc = LocalAlloc(LPTR, dwSize);
+ if (pcc)
+ {
+ pcc->dwProviderSubType = PST_RS232;
+ GetDefaultCommConfig(pszFriendlyName, pcc, &dwSize);
+ ....
+ }
+
+Returns: One of the ERROR_ values in winerror.h
+
+Cond: --
+*/
+DWORD
+PRIVATE
+MyGetDefaultCommConfig(
+ IN LPFINDDEV pfd,
+ IN LPCTSTR pszFriendlyName,
+ OUT LPCOMMCONFIG pcc,
+ OUT LPDWORD pdwSize)
+ {
+ DWORD dwRet;
+
+ ASSERT(pfd);
+ // (Wrapper should have checked these first)
+ ASSERT(pszFriendlyName);
+ ASSERT(pcc);
+ ASSERT(pdwSize);
+ ASSERT(sizeof(*pcc) <= *pdwSize);
+
+ *pdwSize = sizeof(*pcc);
+
+ // Initialize the commconfig structure
+ pcc->dwSize = *pdwSize;
+ pcc->wVersion = COMMCONFIG_VERSION_1;
+ pcc->dwProviderSubType = PST_RS232;
+ pcc->dwProviderOffset = 0;
+ pcc->dwProviderSize = 0;
+
+ dwRet = RegQueryDCB(pfd, &pcc->dcb);
+
+ DEBUG_CODE( DumpDCB(&pcc->dcb); )
+
+ return dwRet;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Sets the default COMMCONFIG for the specified device.
+ This API doesn't require a handle. This function
+ strictly modifies the registry. Use SetCommConfig
+ to set the COMMCONFIG of an open device.
+
+ If the dwSize parameter or the dwSize field are invalid
+ sizes (given the dwProviderSubType field in COMMCONFIG),
+ then this function fails.
+
+Returns: One of the ERROR_ return values
+
+Cond: --
+*/
+DWORD
+PRIVATE
+MySetDefaultCommConfig(
+ IN LPFINDDEV pfd,
+ IN LPCTSTR pszFriendlyName,
+ IN LPCOMMCONFIG pcc)
+ {
+ DWORD dwRet;
+ TCHAR szValue[MAX_BUF_SHORT];
+ TCHAR szKey[MAX_BUF_SHORT];
+
+ ASSERT(pfd);
+ // (Wrapper should have checked these first)
+ ASSERT(pszFriendlyName);
+ ASSERT(pcc);
+ ASSERT(sizeof(*pcc) <= pcc->dwSize);
+
+ ASSERT(0 == pcc->dwProviderSize);
+ ASSERT(0 == pcc->dwProviderOffset);
+
+ dwRet = RegSetDCB(pfd, &pcc->dcb);
+
+ if (NO_ERROR == dwRet)
+ {
+ // For Win 3.1 compatibility, write some info to win.ini
+ lstrcpy(szKey, pfd->szPort);
+ lstrcat(szKey, TEXT(":"));
+
+ // Delete the old win.ini entry first
+ WriteProfileString(c_szPortClass, szKey, NULL);
+
+ ComposeModeComString(pcc, szValue);
+ WriteProfileString(c_szPortClass, szKey, szValue);
+
+#ifdef WIN95
+ {
+ DWORD dwRecipients;
+
+ // Send a broadcast proclaiming that the win.ini has changed
+ // (Use the internal BroadcastSystemMessage to avoid deadlocks.
+ // SendMessageTimeout would be more appropriate, but that is
+ // not exported for 16-bit dlls. PostMessage is not good because
+ // lParam is a pointer.)
+
+ dwRecipients = BSM_APPLICATIONS;
+ BroadcastSystemMessage(BSF_NOHANG, &dwRecipients, WM_WININICHANGE,
+ NULL, (LPARAM)c_szPortClass);
+ }
+#else
+ {
+ SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM)c_szPortClass);
+ }
+#endif
+ }
+
+
+ DEBUG_CODE( DumpDCB(&pcc->dcb); )
+
+ return dwRet;
+ }
+
+
+//-----------------------------------------------------------------------------------
+// Entry-points provided for KERNEL32 APIs
+//-----------------------------------------------------------------------------------
+
+
+DWORD
+APIENTRY
+#ifdef UNICODE
+drvCommConfigDialogA(
+ IN LPCSTR pszFriendlyName,
+ IN HWND hwndOwner,
+ IN OUT LPCOMMCONFIG pcc)
+#else
+drvCommConfigDialogW(
+ IN LPCWSTR pszFriendlyName,
+ IN HWND hwndOwner,
+ IN OUT LPCOMMCONFIG pcc)
+#endif
+ {
+ return ERROR_CALL_NOT_IMPLEMENTED;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Entry point for CommConfigDialog
+
+Returns: standard error value in winerror.h
+Cond: --
+*/
+DWORD
+APIENTRY
+drvCommConfigDialog(
+ IN LPCTSTR pszFriendlyName,
+ IN HWND hwndOwner,
+ IN OUT LPCOMMCONFIG pcc)
+ {
+ DWORD dwRet;
+ LPFINDDEV pfd;
+
+ DEBUG_CODE( TRACE_MSG(TF_FUNC, "drvCommConfigDialog(%s, ...) entered",
+ Dbg_SafeStr(pszFriendlyName)); )
+
+ // We support friendly names (eg, "Communications Port (COM1)") or
+ // portname values (eg, "COM1").
+
+ if (NULL == pszFriendlyName ||
+ NULL == pcc)
+ {
+ dwRet = ERROR_INVALID_PARAMETER;
+ }
+ // Is the size sufficient?
+ else if (sizeof(*pcc) > pcc->dwSize)
+ {
+ // No
+ dwRet = ERROR_INSUFFICIENT_BUFFER;
+ }
+ else if (FindDev_Create(&pfd, c_pguidPort, c_szFriendlyName, pszFriendlyName) ||
+ FindDev_Create(&pfd, c_pguidPort, c_szPortName, pszFriendlyName) ||
+ FindDev_Create(&pfd, c_pguidModem, c_szPortName, pszFriendlyName))
+ {
+ dwRet = MyCommConfigDialog(pfd, pszFriendlyName, hwndOwner, pcc);
+
+ FindDev_Destroy(pfd);
+ }
+ else
+ {
+ dwRet = ERROR_BADKEY;
+ }
+
+ DBG_EXIT_DWORD("drvCommConfigDialog", dwRet);
+
+ return dwRet;
+ }
+
+
+DWORD
+APIENTRY
+#ifdef UNICODE
+drvGetDefaultCommConfigA(
+ IN LPCSTR pszFriendlyName,
+ IN LPCOMMCONFIG pcc,
+ IN OUT LPDWORD pdwSize)
+#else
+drvGetDefaultCommConfigW(
+ IN LPCWSTR pszFriendlyName,
+ IN LPCOMMCONFIG pcc,
+ IN OUT LPDWORD pdwSize)
+#endif
+ {
+ return ERROR_CALL_NOT_IMPLEMENTED;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Entry point for GetDefaultCommConfig
+
+Returns: standard error value in winerror.h
+Cond: --
+*/
+DWORD
+APIENTRY
+drvGetDefaultCommConfig(
+ IN LPCTSTR pszFriendlyName,
+ IN LPCOMMCONFIG pcc,
+ IN OUT LPDWORD pdwSize)
+ {
+ DWORD dwRet;
+ LPFINDDEV pfd;
+
+ DEBUG_CODE( TRACE_MSG(TF_FUNC, "drvGetDefaultCommConfig(%s, ...) entered",
+ Dbg_SafeStr(pszFriendlyName)); )
+
+ // We support friendly names (eg, "Communications Port (COM1)") or
+ // portname values (eg, "COM1").
+
+ if (NULL == pszFriendlyName ||
+ NULL == pcc ||
+ NULL == pdwSize)
+ {
+ dwRet = ERROR_INVALID_PARAMETER;
+ }
+ // Is the size sufficient?
+ else if (sizeof(*pcc) > *pdwSize)
+ {
+ // No; return correct value
+ dwRet = ERROR_INSUFFICIENT_BUFFER;
+ *pdwSize = sizeof(*pcc);
+ }
+ else if (FindDev_Create(&pfd, c_pguidPort, c_szFriendlyName, pszFriendlyName) ||
+ FindDev_Create(&pfd, c_pguidPort, c_szPortName, pszFriendlyName) ||
+ FindDev_Create(&pfd, c_pguidModem, c_szPortName, pszFriendlyName))
+ {
+ dwRet = MyGetDefaultCommConfig(pfd, pszFriendlyName, pcc, pdwSize);
+
+ FindDev_Destroy(pfd);
+ }
+ else
+ {
+ dwRet = ERROR_BADKEY;
+ }
+
+ DBG_EXIT_DWORD("drvGetDefaultCommConfig", dwRet);
+
+ return dwRet;
+ }
+
+
+DWORD
+APIENTRY
+#ifdef UNICODE
+drvSetDefaultCommConfigA(
+ IN LPSTR pszFriendlyName,
+ IN LPCOMMCONFIG pcc,
+ IN DWORD dwSize)
+#else
+drvSetDefaultCommConfigW(
+ IN LPWSTR pszFriendlyName,
+ IN LPCOMMCONFIG pcc,
+ IN DWORD dwSize)
+#endif
+ {
+ return ERROR_CALL_NOT_IMPLEMENTED;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Entry point for SetDefaultCommConfig
+
+Returns: standard error value in winerror.h
+Cond: --
+*/
+DWORD
+APIENTRY
+drvSetDefaultCommConfig(
+ IN LPTSTR pszFriendlyName,
+ IN LPCOMMCONFIG pcc,
+ IN DWORD dwSize) // This is ignored
+ {
+ DWORD dwRet;
+ LPFINDDEV pfd;
+
+ // BUGBUG (scotth): it is not great that the dwSize parameter is
+ // ignored. It should have been used. I was young and foolish
+ // back when I originally implemented this. It should be reviewed
+ // whether to start looking at this parameter now.
+
+ DEBUG_CODE( TRACE_MSG(TF_FUNC, "drvSetDefaultCommConfig(%s, ...) entered",
+ Dbg_SafeStr(pszFriendlyName)); )
+
+ // We support friendly names (eg, "Communications Port (COM1)") or
+ // portname values (eg, "COM1").
+
+ if (NULL == pszFriendlyName ||
+ NULL == pcc)
+ {
+ dwRet = ERROR_INVALID_PARAMETER;
+ }
+ // Is the size sufficient?
+ else if (sizeof(*pcc) > pcc->dwSize)
+ {
+ // No
+ dwRet = ERROR_INSUFFICIENT_BUFFER;
+ }
+ else if (FindDev_Create(&pfd, c_pguidPort, c_szFriendlyName, pszFriendlyName) ||
+ FindDev_Create(&pfd, c_pguidPort, c_szPortName, pszFriendlyName) ||
+ FindDev_Create(&pfd, c_pguidModem, c_szPortName, pszFriendlyName))
+ {
+ dwRet = MySetDefaultCommConfig(pfd, pszFriendlyName, pcc);
+
+ FindDev_Destroy(pfd);
+ }
+ else
+ {
+ dwRet = ERROR_BADKEY;
+ }
+
+ DBG_EXIT_DWORD("drvSetDefaultCommConfig", dwRet);
+
+ return dwRet;
+ }
+
+
diff --git a/private/unimodem/serialui/serialui.def b/private/unimodem/serialui/serialui.def
new file mode 100644
index 000000000..aa2ee078f
--- /dev/null
+++ b/private/unimodem/serialui/serialui.def
@@ -0,0 +1,22 @@
+LIBRARY SERIALUI
+EXETYPE WINDOWS
+PROTMODE
+
+DESCRIPTION 'Windows Serial Port Properties'
+
+CODE MOVEABLE DISCARDABLE PRELOAD
+DATA MOVEABLE PRELOAD SINGLE
+
+HEAPSIZE 1024
+
+EXPORTS
+ ; Stubs to KERNEL32
+ drvCommConfigDialogW @2
+ drvCommConfigDialogA @3
+ drvSetDefaultCommConfigW @4
+ drvSetDefaultCommConfigA @5
+ drvGetDefaultCommConfigW @6
+ drvGetDefaultCommConfigA @7
+
+ ; Private entry point for FIFO
+ ;FeFiFoFum @8
diff --git a/private/unimodem/serialui/serialui.dlg b/private/unimodem/serialui/serialui.dlg
new file mode 100644
index 000000000..6887cab9d
--- /dev/null
+++ b/private/unimodem/serialui/serialui.dlg
@@ -0,0 +1,116 @@
+//{{NO_DEPENDENCIES}}
+//Microsoft App Studio generated resource script.
+//
+#include "dlgids.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+#include <commctrl.h>
+/////////////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_PORTSETTINGS DIALOG DISCARDABLE 0, 0, 212, 188
+STYLE DS_MODALFRAME | 4L | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Port Settings"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "",IDC_PS_PORT,11,8,190,150
+ RTEXT "&Bits per second:",IDC_PS_LBL_BAUDRATE,26,28,54,8
+ COMBOBOX IDC_PS_BAUDRATE,84,26,99,60,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ RTEXT "&Data bits:",IDC_PS_LBL_DATABITS,26,54,54,8
+ COMBOBOX IDC_PS_DATABITS,84,52,99,60,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ RTEXT "&Parity:",IDC_PS_LBL_PARITY,26,80,54,8
+ COMBOBOX IDC_PS_PARITY,84,78,99,60,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ RTEXT "&Stop bits:",IDC_PS_LBL_STOPBITS,26,106,54,8
+ COMBOBOX IDC_PS_STOPBITS,84,104,99,45,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ RTEXT "&Flow control:",IDC_PS_LBL_FLOWCTL,26,132,54,8
+ COMBOBOX IDC_PS_FLOWCTL,84,130,99,45,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ PUSHBUTTON "&Advanced...",IDC_PS_ADVANCED, 11, 164, 74, 14, WS_GROUP
+ PUSHBUTTON "&Restore Defaults",IDC_PS_PB_RESTORE,127,164,74,14,
+ WS_GROUP
+END
+
+IDD_ADV_PORT DIALOG DISCARDABLE 0, 0, 304, 114
+STYLE DS_MODALFRAME | 4L | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Advanced Port Settings"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "",IDC_STATIC,11,8,225,95
+ CONTROL "Use &FIFO buffers (requires 16550 compatible UART)",
+ IDC_FIFO_USAGE,"Button",BS_AUTOCHECKBOX | WS_GROUP |
+ WS_TABSTOP,16,8,180,10
+ LTEXT "Select lower settings to correct connection problems.",
+ IDC_STATIC,16,25,200,10
+ LTEXT "Select higher settings for faster performance.",
+ IDC_STATIC,16,36,200,10
+ LTEXT "&Receive Buffer:",IDC_LBL_RXFIFO,16,57,50,8
+ CONTROL "RxFifo",IDC_RXFIFO_USAGE,"msctls_trackbar",WS_TABSTOP |
+ 0x1,96,55,100,16
+ LTEXT "Low (1)",IDC_LBL_RXFIFO_LO,71,57,25,8
+ LTEXT "High (14)",IDC_LBL_RXFIFO_HI,201,57,32,8
+ LTEXT "&Transmit Buffer:",IDC_LBL_TXFIFO,16,82,50,8
+ CONTROL "TxFifo",IDC_TXFIFO_USAGE,"msctls_trackbar",WS_TABSTOP |
+ 0x1,96,80,100,16
+ LTEXT "Low (1)",IDC_LBL_TXFIFO_LO,71,82,25,8
+ LTEXT "High (16)",IDC_LBL_TXFIFO_HI,201,82,32,8
+ DEFPUSHBUTTON "OK",IDOK,245,12,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,245,31,50,14
+ PUSHBUTTON "&Defaults",IDC_DEFAULTS,245,50,50,14
+END
+
+
+#ifdef APSTUDIO_INVOKED
+//////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "dlgids.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""windows.h""\r\n"
+ "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include <commctrl.h>\r\n"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+/////////////////////////////////////////////////////////////////////////////////////
+#endif // APSTUDIO_INVOKED
+
+
+#ifndef APSTUDIO_INVOKED
+////////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
diff --git a/private/unimodem/serialui/serialui.h b/private/unimodem/serialui/serialui.h
new file mode 100644
index 000000000..755841f5a
--- /dev/null
+++ b/private/unimodem/serialui/serialui.h
@@ -0,0 +1,47 @@
+//---------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation 1993-1994
+//
+// File: serialui.h
+//
+// This files contains the shared prototypes and macros.
+//
+// History:
+// 02-03-94 ScottH Created
+//
+//---------------------------------------------------------------------------
+
+
+#ifndef __SERIALUI_H__
+#define __SERIALUI_H__
+
+#define MAXPORTNAME 13
+#define MAXFRIENDLYNAME LINE_LEN // LINE_LEN is defined in setupx.h
+
+// Internal structure shared between port property pages.
+//
+typedef struct _PORTINFO
+ {
+ UINT uFlags; // One of SIF_* values
+ WIN32DCB dcb;
+ LPCOMMCONFIG pcc; // Read-only
+ int idRet;
+
+ TCHAR szFriendlyName[MAXFRIENDLYNAME];
+ } PortInfo, FAR * LPPORTINFO;
+
+// PortInfo Flags
+#define SIF_FROM_DEVMGR 0x0001
+
+
+extern LPGUID c_pguidModem;
+extern LPGUID c_pguidPort;
+
+//-------------------------------------------------------------------------
+// PORT.C
+//-------------------------------------------------------------------------
+
+BOOL CALLBACK Port_WrapperProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+
+#endif // __SERIALUI_H__
+
diff --git a/private/unimodem/serialui/serialui.rc b/private/unimodem/serialui/serialui.rc
new file mode 100644
index 000000000..3fab18ca8
--- /dev/null
+++ b/private/unimodem/serialui/serialui.rc
@@ -0,0 +1,77 @@
+#include "rcids.h"
+#include "dlgids.h"
+
+#include <windows.h>
+
+/* Version stamping */
+#include "serialui.rcv"
+
+/* Dialog resource */
+#include "serialui.dlg"
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Icons
+//
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_OOM_PORT "There is not enough memory to view the Port Settings dialog.\nClose some files or programs, and then try again."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_CAP_PORT "Port Settings"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_BAUD_075 "75"
+ IDS_BAUD_134_5 "134.5"
+ IDS_BAUD_150 "150"
+ IDS_BAUD_300 "300"
+ IDS_BAUD_600 "600"
+ IDS_BAUD_1800 "1800"
+ IDS_BAUD_7200 "7200"
+ IDS_BAUD_110 "110"
+ IDS_BAUD_1200 "1200"
+ IDS_BAUD_2400 "2400"
+ IDS_BAUD_4800 "4800"
+ IDS_BAUD_9600 "9600"
+ IDS_BAUD_14400 "14400"
+ IDS_BAUD_19200 "19200"
+ IDS_BAUD_38400 "38400"
+ IDS_BAUD_56K "56000"
+ IDS_BAUD_57600 "57600"
+ IDS_BAUD_115200 "115200"
+ IDS_BAUD_128K "128000"
+ IDS_BAUD_230400 "230400"
+ IDS_BAUD_460800 "460800"
+ IDS_BAUD_921600, "921600"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_BYTESIZE_4 "4"
+ IDS_BYTESIZE_5 "5"
+ IDS_BYTESIZE_6 "6"
+ IDS_BYTESIZE_7 "7"
+ IDS_BYTESIZE_8 "8"
+ IDS_PARITY_EVEN "Even"
+ IDS_PARITY_ODD "Odd"
+ IDS_PARITY_NONE "None"
+ IDS_PARITY_MARK "Mark"
+ IDS_PARITY_SPACE "Space"
+ IDS_STOPBITS_1 "1"
+ IDS_STOPBITS_1_5 "1.5"
+ IDS_STOPBITS_2 "2"
+ IDS_FLOWCTL_XONXOFF "Xon / Xoff"
+ IDS_FLOWCTL_HARDWARE "Hardware"
+ IDS_FLOWCTL_NONE "None"
+END
diff --git a/private/unimodem/serialui/serialui.rcv b/private/unimodem/serialui/serialui.rcv
new file mode 100644
index 000000000..137aa9b7c
--- /dev/null
+++ b/private/unimodem/serialui/serialui.rcv
@@ -0,0 +1,19 @@
+/********************************************************************/
+/* SERIALUI.RCV */
+/********************************************************************/
+
+#define VER_FILETYPE VFT_DLL
+#define VER_FILESUBTYPE VFT_UNKNOWN
+#define VER_FILEDESCRIPTION_STR "Serial Port Property Pages"
+#define VER_INTERNALNAME_STR "SERIALUI"
+#define VER_LEGALCOPYRIGHT_YEARS "1993-1995"
+#define VER_ORIGINALFILENAME_STR "SERIALUI.DLL"
+
+#ifdef WIN32
+#include <ntverp.h>
+#else
+#include <version.h>
+#endif
+
+#include <common.ver>
+
diff --git a/private/unimodem/serialui/sources b/private/unimodem/serialui/sources
new file mode 100644
index 000000000..93946939d
--- /dev/null
+++ b/private/unimodem/serialui/sources
@@ -0,0 +1,79 @@
+!IF 0
+
+Copyright (c) 1994 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+ Steve Cathcart (stevecat) 15-Nov-1994
+
+NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl
+
+Use the following line when this is UNICODE ported
+
+NOT_UNICODE=1
+
+
+ $(BASEDIR)\public\sdk\lib\*\mpr.lib \
+
+!ENDIF
+
+MAJORCOMP=shell
+MINORCOMP=cpls
+
+TARGETNAME=serialui
+TARGETPATH=..\lib
+TARGETTYPE=DYNLINK
+TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \
+ $(BASEDIR)\public\sdk\lib\*\user32.lib \
+ $(BASEDIR)\public\sdk\lib\*\comctl32.lib \
+ $(BASEDIR)\public\sdk\lib\*\shell32.lib \
+ $(BASEDIR)\public\sdk\lib\*\gdi32.lib \
+ $(BASEDIR)\public\sdk\lib\*\libc.lib \
+ $(BASEDIR)\public\sdk\lib\*\uuid.lib \
+ $(BASEDIR)\public\sdk\lib\*\advapi32.lib \
+ $(BASEDIR)\public\sdk\lib\*\setupapi.lib \
+ ..\lib\*\rovcomm.lib
+
+DLLBASE=0x69000000
+
+DLLENTRY= LibMain
+
+NOT_LEAN_AND_MEAN=1
+
+INCLUDES=.;..\inc;..\..\inc;$(BASEDIR)\private\windows\inc
+
+C_DEFINES=-DWIN32 -DWINNT -D_WIN32 -DWINVER=0x0400
+
+!IF "$(SHELLDBG)"=="1"
+C_DEFINES=$(C_DEFINES) -DDEBUG -DFULL_DEBUG
+!ENDIF
+
+UMTYPE=windows
+EXPECTED_WINVER=4.0
+
+SOURCES= serialui.rc \
+ serialui.c \
+ dll.c \
+ util.c \
+ cstrings.c \
+ port.c
+
+PRECOMPILED_INCLUDE=proj.h
+PRECOMPILED_PCH=proj.pch
+PRECOMPILED_OBJ=proj.obj
+
+!IFNDEF 386_WARNING_LEVEL
+386_WARNING_LEVEL=/W3
+!ENDIF
diff --git a/private/unimodem/serialui/util.c b/private/unimodem/serialui/util.c
new file mode 100644
index 000000000..d8ac24627
--- /dev/null
+++ b/private/unimodem/serialui/util.c
@@ -0,0 +1,290 @@
+//---------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation 1993-1996
+//
+// File: util.c
+//
+// This files contains all common utility routines
+//
+// History:
+// 12-23-93 ScottH Created
+// 09-22-95 ScottH Ported to NT
+//
+//---------------------------------------------------------------------------
+
+#include "proj.h" // common headers
+
+
+//-----------------------------------------------------------------------------------
+// Wrapper that finds a device instance
+//-----------------------------------------------------------------------------------
+
+
+/*----------------------------------------------------------
+Purpose: Enumerates the HKEY_LOCAL_MACHINE branch and finds the
+ device matching the given class and value. If there
+ are duplicate devices that match both criteria, only the
+ first device is returned.
+
+ Returns TRUE if the device was found.
+
+Returns: see above
+Cond: --
+*/
+BOOL
+PRIVATE
+FindDev_Find(
+ IN LPFINDDEV pfinddev,
+ IN LPGUID pguidClass, OPTIONAL
+ IN LPCTSTR pszValueName,
+ IN LPCTSTR pszValue)
+ {
+ BOOL bRet = FALSE;
+ TCHAR szKey[MAX_BUF];
+ TCHAR szName[MAX_BUF];
+ HDEVINFO hdi;
+ DWORD dwRW = KEY_READ;
+
+ ASSERT(pfinddev);
+ ASSERT(pszValueName);
+ ASSERT(pszValue);
+
+ if (USER_IS_ADMIN()) dwRW |= KEY_WRITE;
+
+ // BUGBUG (scotth): hack to support no device instances because
+ // ports do not have a class GUID. This should be fixed after SUR.
+
+ // Is there a class GUID?
+ if (pguidClass)
+ {
+ // Yes; use it
+ hdi = CplDiGetClassDevs(pguidClass, NULL, NULL, 0);
+ if (INVALID_HANDLE_VALUE != hdi)
+ {
+ SP_DEVINFO_DATA devData;
+ DWORD iIndex = 0;
+ HKEY hkey;
+
+ // Look for the modem that has the matching value
+ devData.cbSize = sizeof(devData);
+ while (CplDiEnumDeviceInfo(hdi, iIndex, &devData))
+ {
+ hkey = CplDiOpenDevRegKey(hdi, &devData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, dwRW);
+ if (INVALID_HANDLE_VALUE != hkey)
+ {
+ // Does the value match?
+ DWORD cbData = sizeof(szName);
+ if (NO_ERROR == RegQueryValueEx(hkey, pszValueName, NULL, NULL,
+ (LPBYTE)szName, &cbData) &&
+ IsSzEqual(pszValue, szName))
+ {
+ // Yes
+ pfinddev->hkeyDrv = hkey;
+ pfinddev->hdi = hdi;
+ BltByte(&pfinddev->devData, &devData, sizeof(devData));
+
+ // Don't close the driver key or free the DeviceInfoSet,
+ // but exit
+ bRet = TRUE;
+ break;
+ }
+ RegCloseKey(hkey);
+ }
+
+ iIndex++;
+ }
+
+ // Free the DeviceInfoSet if nothing was found. Otherwise, we will
+ // retain these handles so the caller can make use of this.
+ if ( !bRet )
+ {
+ CplDiDestroyDeviceInfoList(hdi);
+ }
+ }
+ }
+ else
+ {
+ // No; HACK ALERT! Hmm, it must be a port class in SUR.
+#pragma data_seg(DATASEG_READONLY)
+ static TCHAR const FAR c_szSerialComm[] = TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM");
+#pragma data_seg()
+
+ HKEY hkeyEnum;
+ DWORD iSubKey;
+ TCHAR szName[MAX_BUF];
+ DWORD cbName;
+ DWORD cbData;
+ DWORD dwType;
+ DWORD dwRet;
+
+ dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, c_szSerialComm, &hkeyEnum);
+ if (NO_ERROR == dwRet)
+ {
+ ZeroInit(pfinddev);
+
+ iSubKey = 0;
+
+ cbName = sizeof(szName);
+ cbData = sizeof(pfinddev->szPort);
+
+ while (NO_ERROR == RegEnumValue(hkeyEnum, iSubKey++, szName,
+ &cbName, NULL, &dwType,
+ (LPBYTE)pfinddev->szPort, &cbData))
+ {
+ if (REG_SZ == dwType &&
+ 0 == lstrcmpi(pfinddev->szPort, pszValue))
+ {
+ bRet = TRUE;
+ break;
+ }
+
+ cbName = sizeof(szName);
+ cbData = sizeof(pfinddev->szPort);
+ }
+ RegCloseKey(hkeyEnum);
+ }
+ }
+
+ return bRet;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Creates a FINDDEV structure given the device class,
+ and a valuename and its value.
+
+Returns: TRUE if the device is found in the system
+
+Cond: --
+*/
+BOOL
+PUBLIC
+FindDev_Create(
+ OUT LPFINDDEV FAR * ppfinddev,
+ IN LPGUID pguidClass, OPTIONAL
+ IN LPCTSTR pszValueName,
+ IN LPCTSTR pszValue)
+ {
+ BOOL bRet;
+ LPFINDDEV pfinddev;
+
+ DEBUG_CODE( TRACE_MSG(TF_FUNC, " > FindDev_Create(....%s, %s, ...)",
+ Dbg_SafeStr(pszValueName), Dbg_SafeStr(pszValue)); )
+
+ ASSERT(ppfinddev);
+ ASSERT(pszValueName);
+ ASSERT(pszValue);
+
+ pfinddev = (LPFINDDEV)LocalAlloc(LPTR, sizeof(*pfinddev));
+ if (NULL == pfinddev)
+ {
+ bRet = FALSE;
+ }
+ else
+ {
+ bRet = FindDev_Find(pfinddev, pguidClass, pszValueName, pszValue);
+
+ if (FALSE == bRet)
+ {
+ // Didn't find anything
+ FindDev_Destroy(pfinddev);
+ pfinddev = NULL;
+ }
+ }
+
+ *ppfinddev = pfinddev;
+
+ DBG_EXIT_BOOL(FindDev_Create, bRet);
+
+ return bRet;
+ }
+
+
+/*----------------------------------------------------------
+Purpose: Destroys a FINDDEV structure
+
+Returns: TRUE on success
+Cond: --
+*/
+BOOL
+PUBLIC
+FindDev_Destroy(
+ IN LPFINDDEV this)
+ {
+ BOOL bRet;
+
+ if (NULL == this)
+ {
+ bRet = FALSE;
+ }
+ else
+ {
+ if (this->hkeyDrv)
+ RegCloseKey(this->hkeyDrv);
+
+ if (this->hdi && INVALID_HANDLE_VALUE != this->hdi)
+ CplDiDestroyDeviceInfoList(this->hdi);
+
+ LocalFreePtr(this);
+
+ bRet = TRUE;
+ }
+
+ return bRet;
+ }
+
+
+//-----------------------------------------------------------------------------------
+// Debug functions
+//-----------------------------------------------------------------------------------
+
+
+#ifdef DEBUG
+
+#pragma data_seg(DATASEG_READONLY)
+
+#ifdef WIN95
+struct _RETERRMAP
+ {
+ RETERR ret;
+ LPCTSTR psz;
+ } const c_rgreterrmap[] = {
+ { NO_ERROR, "NO_ERROR" },
+ { DI_ERROR, "DI_ERROR" },
+ { ERR_DI_INVALID_DEVICE_ID, "ERR_DI_INVALID_DEVICE_ID" },
+ { ERR_DI_INVALID_COMPATIBLE_DEVICE_LIST, "ERR_DI_INVALID_COMPATIBLE_DEVICE_LIST" },
+ { ERR_DI_REG_API, "ERR_DI_REG_API" },
+ { ERR_DI_LOW_MEM, "ERR_DI_LOW_MEM" },
+ { ERR_DI_BAD_DEV_INFO, "ERR_DI_BAD_DEV_INFO" },
+ { ERR_DI_INVALID_CLASS_INSTALLER, "ERR_DI_INVALID_CLASS_INSTALLER" },
+ { ERR_DI_DO_DEFAULT, "ERR_DI_DO_DEFAULT" },
+ { ERR_DI_USER_CANCEL, "ERR_DI_USER_CANCEL" },
+ { ERR_DI_NOFILECOPY, "ERR_DI_NOFILECOPY" },
+ { ERR_DI_BAD_CLASS_INFO, "ERR_DI_BAD_CLASS_INFO" },
+ };
+#endif
+
+#pragma data_seg()
+
+#ifdef WIN95
+/*----------------------------------------------------------
+Purpose: Returns the string form of a RETERR.
+
+Returns: String ptr
+Cond: --
+*/
+LPCTSTR PUBLIC Dbg_GetReterr(
+ RETERR ret)
+ {
+ int i;
+
+ for (i = 0; i < ARRAY_ELEMENTS(c_rgreterrmap); i++)
+ {
+ if (ret == c_rgreterrmap[i].ret)
+ return c_rgreterrmap[i].psz;
+ }
+ return "Unknown RETERR";
+ }
+#endif // WIN95
+
+#endif // DEBUG
diff --git a/private/unimodem/serialui/util.h b/private/unimodem/serialui/util.h
new file mode 100644
index 000000000..34eeb23fe
--- /dev/null
+++ b/private/unimodem/serialui/util.h
@@ -0,0 +1,40 @@
+//
+// util.h: Declares data, defines and struct types for common code
+// module.
+//
+//
+
+#ifndef __UTIL_H__
+#define __UTIL_H__
+
+#if defined(DEBUG) && defined(WIN95)
+LPCTSTR PUBLIC Dbg_GetReterr(RETERR ret);
+#endif
+
+//
+// FINDDEV structure
+//
+typedef struct tagFINDDEV
+ {
+ HDEVINFO hdi;
+ SP_DEVINFO_DATA devData;
+ HKEY hkeyDrv;
+ TCHAR szPort[MAX_BUF_SHORT];
+ } FINDEV, FAR * LPFINDDEV;
+
+BOOL
+PUBLIC
+FindDev_Create(
+ OUT LPFINDDEV FAR * ppfinddev,
+ IN LPGUID pguidClass,
+ IN LPCTSTR pszValueName,
+ IN LPCTSTR pszValue);
+
+BOOL
+PUBLIC
+FindDev_Destroy(
+ IN LPFINDDEV this);
+
+
+#endif // __UTIL_H__
+