diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/unimodem/serialui | |
download | NT4.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.c | 30 | ||||
-rw-r--r-- | private/unimodem/serialui/cstrings.h | 23 | ||||
-rw-r--r-- | private/unimodem/serialui/dlgids.h | 42 | ||||
-rw-r--r-- | private/unimodem/serialui/dll.c | 291 | ||||
-rw-r--r-- | private/unimodem/serialui/dll.h | 44 | ||||
-rw-r--r-- | private/unimodem/serialui/makefile | 6 | ||||
-rw-r--r-- | private/unimodem/serialui/port.c | 1085 | ||||
-rw-r--r-- | private/unimodem/serialui/proj.h | 99 | ||||
-rw-r--r-- | private/unimodem/serialui/rcids.h | 109 | ||||
-rw-r--r-- | private/unimodem/serialui/serialui.c | 989 | ||||
-rw-r--r-- | private/unimodem/serialui/serialui.def | 22 | ||||
-rw-r--r-- | private/unimodem/serialui/serialui.dlg | 116 | ||||
-rw-r--r-- | private/unimodem/serialui/serialui.h | 47 | ||||
-rw-r--r-- | private/unimodem/serialui/serialui.rc | 77 | ||||
-rw-r--r-- | private/unimodem/serialui/serialui.rcv | 19 | ||||
-rw-r--r-- | private/unimodem/serialui/sources | 79 | ||||
-rw-r--r-- | private/unimodem/serialui/util.c | 290 | ||||
-rw-r--r-- | private/unimodem/serialui/util.h | 40 |
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__ + |