|
|
/*----------------------------------------------------------------------
file: pp.c - property page
@@BEGIN_DDKSPLIT
* History: 7-29-97 - Add this module for NT5.0, kpb
@@END_DDKSPLIT ----------------------------------------------------------------------*/ #include "ports.h"
#include "pp.h"
// @@BEGIN_DDKSPLIT
BOOL IsUserAdmin( VOID )
/*++
Routine Description:
This routine returns TRUE if the caller's process is a member of the Administrators local group.
Caller is NOT expected to be impersonating anyone and IS expected to be able to open their own process and process token.
Arguments:
None.
Return Value:
TRUE - Caller has Administrators local group.
FALSE - Caller does not have Administrators local group.
--*/
{ HANDLE Token; DWORD BytesRequired; PTOKEN_GROUPS Groups; BOOL b; DWORD i; SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; PSID AdministratorsGroup;
//
// Open the process token.
//
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&Token)) { return(FALSE); }
b = FALSE; Groups = NULL;
//
// Get group information.
//
if(!GetTokenInformation(Token,TokenGroups,NULL,0,&BytesRequired) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) && (Groups = (PTOKEN_GROUPS)LocalAlloc(LMEM_FIXED,BytesRequired)) && GetTokenInformation(Token,TokenGroups,Groups,BytesRequired,&BytesRequired)) {
b = AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup );
if(b) {
//
// See if the user has the administrator group.
//
b = FALSE; for(i=0; i<Groups->GroupCount; i++) { if(EqualSid(Groups->Groups[i].Sid,AdministratorsGroup)) { b = TRUE; break; } }
FreeSid(AdministratorsGroup); } }
//
// Clean up and return.
//
if(Groups) { LocalFree(Groups); }
CloseHandle(Token);
return(b); } // @@END_DDKSPLIT
TCHAR m_szDevMgrHelp[] = _T("devmgr.hlp");
const DWORD HelpIDs[]= { IDC_STATIC, IDH_NOHELP, IDC_ADVANCED, IDH_DEVMGR_PORTSET_ADVANCED, // "&Advanced" (Button)
PP_PORT_BAUDRATE, IDH_DEVMGR_PORTSET_BPS, // "" (ComboBox)
PP_PORT_DATABITS, IDH_DEVMGR_PORTSET_DATABITS, // "" (ComboBox)
PP_PORT_PARITY, IDH_DEVMGR_PORTSET_PARITY, // "" (ComboBox)
PP_PORT_STOPBITS, IDH_DEVMGR_PORTSET_STOPBITS, // "" (ComboBox)
PP_PORT_FLOWCTL, IDH_DEVMGR_PORTSET_FLOW, // "" (ComboBox)
IDC_RESTORE_PORT, IDH_DEVMGR_PORTSET_DEFAULTS, // "&Restore Defaults" (Button)
0, 0 };
void InitPortParams( IN OUT PPORT_PARAMS Params, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData ) { BOOL showAdvanced = TRUE; SP_DEVINFO_LIST_DETAIL_DATA detailData;
ZeroMemory(Params, sizeof(PORT_PARAMS));
Params->DeviceInfoSet = DeviceInfoSet; Params->DeviceInfoData = DeviceInfoData; Params->ChangesEnabled = TRUE;
//
// Now we know how big our structure is, so we can allocate memory
//
Params->pAdvancedData = (PADVANCED_DATA) LocalAlloc(LPTR, sizeof(ADVANCED_DATA));
if (Params->pAdvancedData == NULL) { //
// Not enough memory
//
SetLastError(ERROR_NOT_ENOUGH_MEMORY); showAdvanced = FALSE; } else { Params->pAdvancedData->HidePolling = FALSE; } //
// See if we are being invoked locally or over the network. If over the net,
// then disable all possible changes.
//
detailData.cbSize = sizeof(SP_DEVINFO_LIST_DETAIL_DATA); if (SetupDiGetDeviceInfoListDetail(DeviceInfoSet, &detailData) && detailData.RemoteMachineHandle != NULL) { showAdvanced = FALSE; Params->ChangesEnabled = FALSE; }
// @@BEGIN_DDKSPLIT
//
// The user can still change the buadrate etc b/c it is written to some
// magic place in the registry, not into the devnode
//
if (!IsUserAdmin()) { showAdvanced = FALSE; } // @@END_DDKSPLIT
if (Params->pAdvancedData) { Params->pAdvancedData->DeviceInfoSet = DeviceInfoSet; Params->pAdvancedData->DeviceInfoData = DeviceInfoData; } Params->ShowAdvanced = showAdvanced; }
HPROPSHEETPAGE InitSettingsPage(PROPSHEETPAGE * psp, OUT PPORT_PARAMS Params) { //
// Add the Port Settings property page
//
psp->dwSize = sizeof(PROPSHEETPAGE); psp->dwFlags = PSP_USECALLBACK; // | PSP_HASHELP;
psp->hInstance = g_hInst; psp->pszTemplate = MAKEINTRESOURCE(DLG_PP_PORTSETTINGS);
//
// following points to the dlg window proc
//
psp->pfnDlgProc = PortSettingsDlgProc; psp->lParam = (LPARAM) Params;
//
// following points to some control callback of the dlg window proc
//
psp->pfnCallback = PortSettingsDlgCallback;
//
// allocate our "Ports Setting" sheet
//
return CreatePropertySheetPage(psp); }
/*++
Routine Description: SerialPortPropPageProvider
Entry-point for adding additional device manager property sheet pages. Registry specifies this routine under Control\Class\PortNode::EnumPropPage32="msports.dll,thisproc" entry. This entry-point gets called only when the Device Manager asks for additional property pages.
Arguments:
Info - points to PROPSHEETPAGE_REQUEST, see setupapi.h AddFunc - function ptr to call to add sheet. Lparam - add sheet functions private data handle.
Return Value:
BOOL: FALSE if pages could not be added, TRUE on success
--*/ BOOL APIENTRY SerialPortPropPageProvider(LPVOID Info, LPFNADDPROPSHEETPAGE AddFunc, LPARAM Lparam ) { PSP_PROPSHEETPAGE_REQUEST pprPropPageRequest; PROPSHEETPAGE psp; HPROPSHEETPAGE hpsp; PPORT_PARAMS params = NULL;
pprPropPageRequest = (PSP_PROPSHEETPAGE_REQUEST) Info;
if (PortTypeSerial != GetPortType(pprPropPageRequest->DeviceInfoSet, pprPropPageRequest->DeviceInfoData, FALSE)) { return FALSE; }
//
// Allocate and zero out memory for the struct that will contain
// page specific data
//
params = (PPORT_PARAMS) LocalAlloc(LPTR, sizeof(PORT_PARAMS));
if (!params) { ErrMemDlg(GetFocus()); return FALSE; }
if (pprPropPageRequest->PageRequested == SPPSR_ENUM_ADV_DEVICE_PROPERTIES) { InitPortParams(params, pprPropPageRequest->DeviceInfoSet, pprPropPageRequest->DeviceInfoData);
hpsp = InitSettingsPage(&psp, params);
if (!hpsp) { return FALSE; }
if (!(*AddFunc)(hpsp, Lparam)) { DestroyPropertySheetPage(hpsp); return FALSE; } }
return TRUE; } /* SerialPortPropPageProvider */
UINT CALLBACK PortSettingsDlgCallback(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp) { PPORT_PARAMS params;
switch (uMsg) { case PSPCB_CREATE: return TRUE; // return TRUE to continue with creation of page
case PSPCB_RELEASE: params = (PPORT_PARAMS) ppsp->lParam; if (params->pAdvancedData) { LocalFree(params->pAdvancedData); } LocalFree(params);
return 0; // return value ignored
default: break; }
return TRUE; }
void Port_OnCommand( HWND DialogHwnd, int ControlId, HWND ControlHwnd, UINT NotifyCode );
BOOL Port_OnContextMenu( HWND HwndControl, WORD Xpos, WORD Ypos );
void Port_OnHelp( HWND DialogHwnd, LPHELPINFO HelpInfo );
BOOL Port_OnInitDialog( HWND DialogHwnd, HWND FocusHwnd, LPARAM Lparam );
BOOL Port_OnNotify( HWND DialogHwnd, LPNMHDR NmHdr );
/*++
Routine Description: PortSettingsDlgProc
The windows control function for the Port Settings properties window
Arguments:
hDlg, uMessage, wParam, lParam: standard windows DlgProc parameters
Return Value:
BOOL: FALSE if function fails, TRUE if function passes
--*/ INT_PTR APIENTRY PortSettingsDlgProc(IN HWND hDlg, IN UINT uMessage, IN WPARAM wParam, IN LPARAM lParam) { switch(uMessage) { case WM_COMMAND: Port_OnCommand(hDlg, (int) LOWORD(wParam), (HWND)lParam, (UINT)HIWORD(wParam)); break;
case WM_CONTEXTMENU: return Port_OnContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
case WM_HELP: Port_OnHelp(hDlg, (LPHELPINFO) lParam); break;
case WM_INITDIALOG: return Port_OnInitDialog(hDlg, (HWND)wParam, lParam);
case WM_NOTIFY: return Port_OnNotify(hDlg, (NMHDR *)lParam); }
return FALSE; } /* PortSettingsDialogProc */
void Port_OnAdvancedClicked( HWND DialogHwnd, PPORT_PARAMS Params ) { //
// Initialize the new COM name with the current COM name
//
lstrcpy(Params->pAdvancedData->szNewComName, Params->PortSettings.szComName);
if (DisplayAdvancedDialog(DialogHwnd, Params->pAdvancedData)) { //
// Only update if there is a change
//
if (_tcscmp(Params->pAdvancedData->szNewComName, Params->PortSettings.szComName) != 0) { lstrcpy(Params->PortSettings.szComName, Params->pAdvancedData->szNewComName); } } }
void Port_OnRestorePortClicked( HWND DialogHwnd, PPORT_PARAMS Params ) { RestorePortSettings(DialogHwnd, Params); PropSheet_Changed(GetParent(DialogHwnd), DialogHwnd); }
void Port_OnCommand( HWND DialogHwnd, int ControlId, HWND ControlHwnd, UINT NotifyCode ) { PPORT_PARAMS params = (PPORT_PARAMS)GetWindowLongPtr(DialogHwnd, DWLP_USER);
if (NotifyCode == CBN_SELCHANGE) { PropSheet_Changed(GetParent(DialogHwnd), DialogHwnd); } else { switch (ControlId) { case IDC_ADVANCED: Port_OnAdvancedClicked(DialogHwnd, params); break;
case IDC_RESTORE_PORT: Port_OnRestorePortClicked(DialogHwnd, params); break;
//
// Because this is a prop sheet, we should never get this.
// All notifications for ctrols outside of the sheet come through
// WM_NOTIFY
//
case IDCANCEL: EndDialog(DialogHwnd, 0); return; } } }
BOOL Port_OnContextMenu( HWND HwndControl, WORD Xpos, WORD Ypos ) { WinHelp(HwndControl, m_szDevMgrHelp, HELP_CONTEXTMENU, (ULONG_PTR) HelpIDs);
return FALSE; }
void Port_OnHelp( HWND DialogHwnd, LPHELPINFO HelpInfo ) { if (HelpInfo->iContextType == HELPINFO_WINDOW) { WinHelp((HWND) HelpInfo->hItemHandle, m_szDevMgrHelp, HELP_WM_HELP, (ULONG_PTR) HelpIDs); } }
BOOL Port_OnInitDialog( HWND DialogHwnd, HWND FocusHwnd, LPARAM Lparam ) { PPORT_PARAMS params;
//
// on WM_INITDIALOG call, lParam points to the property
// sheet page.
//
// The lParam field in the property sheet page struct is set by the
// caller. When I created the property sheet, I passed in a pointer
// to a struct containing information about the device. Save this in
// the user window long so I can access it on later messages.
//
params = (PPORT_PARAMS) ((LPPROPSHEETPAGE)Lparam)->lParam; SetWindowLongPtr(DialogHwnd, DWLP_USER, (ULONG_PTR) params);
//
// Set up the combo boxes with choices
//
FillCommDlg(DialogHwnd);
//
// Read current settings
//
FillPortSettingsDlg(DialogHwnd, params);
EnableWindow(GetDlgItem(DialogHwnd, IDC_ADVANCED), params->ShowAdvanced); EnableWindow(GetDlgItem(DialogHwnd, IDC_RESTORE_PORT), params->ChangesEnabled);
return TRUE; // No need for us to set the focus.
}
BOOL Port_OnNotify( HWND DialogHwnd, LPNMHDR NmHdr ) { PPORT_PARAMS params = (PPORT_PARAMS)GetWindowLongPtr(DialogHwnd, DWLP_USER);
switch (NmHdr->code) { //
// Sent when the user clicks on Apply OR OK !!
//
case PSN_APPLY: //
// Write out the com port options to the registry
//
SavePortSettingsDlg(DialogHwnd, params); SetWindowLongPtr(DialogHwnd, DWLP_MSGRESULT, PSNRET_NOERROR); return TRUE;
default: return FALSE; } }
VOID SetCBFromRes( HWND HwndCB, DWORD ResId, DWORD Default, BOOL CheckDecimal) { TCHAR szTemp[258], szDecSep[2], cSep; LPTSTR pThis, pThat, pDecSep; int iRV;
if (CheckDecimal) { iRV = GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SDECIMAL,szDecSep,2);
if (iRV == 0) { //
// following code can take only one char for decimal separator,
// better leave the point as separator
//
CheckDecimal = FALSE; } }
if (!LoadString(g_hInst, ResId, szTemp, CharSizeOf(szTemp))) return;
for (pThis = szTemp, cSep = *pThis++; pThis; pThis = pThat) { if (pThat = _tcschr( pThis, cSep)) *pThat++ = TEXT('\0');
if(CheckDecimal) { //
// Assume dec separator in resource is '.', comment was put to this
// effect
//
pDecSep = _tcschr(pThis,TEXT('.')); if (pDecSep) { //
// assume decimal sep width == 1
//
*pDecSep = *szDecSep; } } SendMessage(HwndCB, CB_ADDSTRING, 0, (LPARAM) pThis); }
SendMessage(HwndCB, CB_SETCURSEL, Default, 0L); }
/*++
Routine Description: FillCommDlg
Fill in baud rate, parity, etc in port dialog box
Arguments:
hDlg: the window address
Return Value:
BOOL: FALSE if function fails, TRUE if function passes
--*/ BOOL FillCommDlg( HWND DialogHwnd ) { SHORT shIndex; TCHAR szTemp[81];
//
// just list all of the baud rates
//
for(shIndex = 0; m_nBaudRates[shIndex]; shIndex++) { MyItoa(m_nBaudRates[shIndex], szTemp, 10);
SendDlgItemMessage(DialogHwnd, PP_PORT_BAUDRATE, CB_ADDSTRING, 0, (LPARAM)szTemp); }
//
// Set 9600 as default baud selection
//
shIndex = (USHORT) SendDlgItemMessage(DialogHwnd, PP_PORT_BAUDRATE, CB_FINDSTRING, (WPARAM)-1, (LPARAM)m_sz9600);
shIndex = (shIndex == CB_ERR) ? 0 : shIndex;
SendDlgItemMessage(DialogHwnd, PP_PORT_BAUDRATE, CB_SETCURSEL, shIndex, 0L);
for(shIndex = 0; m_nDataBits[shIndex]; shIndex++) { MyItoa(m_nDataBits[shIndex], szTemp, 10);
SendDlgItemMessage(DialogHwnd, PP_PORT_DATABITS, CB_ADDSTRING, 0, (LPARAM)szTemp); }
SendDlgItemMessage(DialogHwnd, PP_PORT_DATABITS, CB_SETCURSEL, DEF_WORD, 0L);
SetCBFromRes(GetDlgItem(DialogHwnd, PP_PORT_PARITY), IDS_PARITY, DEF_PARITY, FALSE);
SetCBFromRes(GetDlgItem(DialogHwnd, PP_PORT_STOPBITS), IDS_BITS, DEF_STOP, TRUE);
SetCBFromRes(GetDlgItem(DialogHwnd, PP_PORT_FLOWCTL), IDS_FLOWCONTROL, DEF_SHAKE, FALSE);
return 0;
} /* FillCommDlg */
/*++
Routine Description: FillPortSettingsDlg
fill in the port settings dlg sheet
Arguments:
params: the data to fill in hDlg: address of the window
Return Value:
ULONG: returns error messages
--*/ ULONG FillPortSettingsDlg( IN HWND DialogHwnd, IN PPORT_PARAMS Params ) { HKEY hDeviceKey; DWORD dwPortNameSize, dwError; TCHAR szCharBuffer[81];
//
// Open the device key for the source device instance, and retrieve its
// "PortName" value.
//
hDeviceKey = SetupDiOpenDevRegKey(Params->DeviceInfoSet, Params->DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
if (INVALID_HANDLE_VALUE == hDeviceKey) { goto RetGetLastError; }
dwPortNameSize = sizeof(Params->PortSettings.szComName); dwError = RegQueryValueEx(hDeviceKey, m_szPortName, // "PortName"
NULL, NULL, (PBYTE)Params->PortSettings.szComName, &dwPortNameSize);
RegCloseKey(hDeviceKey);
if(ERROR_SUCCESS != dwError) { goto RetERROR; }
//
// create "com#:"
//
lstrcpy(szCharBuffer, Params->PortSettings.szComName); lstrcat(szCharBuffer, m_szColon);
//
// get values from system, fills in baudrate, parity, etc.
//
GetPortSettings(DialogHwnd, szCharBuffer, Params);
if (!Params->ChangesEnabled) { EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_BAUDRATE), FALSE); EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_PARITY), FALSE); EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_DATABITS), FALSE); EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_STOPBITS), FALSE); EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_FLOWCTL), FALSE); }
return 0;
RetERROR: return dwError;
RetGetLastError: return GetLastError(); } /* FillPortSettingsDlg */
/*++
Routine Description: GetPortSettings
Read in port settings from the system
Arguments:
DialogHwnd: address of the window ComName: the port we're dealing with Params: where to put the information we're getting
Return Value:
ULONG: returns error messages
--*/ void GetPortSettings( IN HWND DialogHwnd, IN PTCHAR ComName, IN PPORT_PARAMS Params ) { TCHAR szParms[81]; PTCHAR szCur, szNext; int nIndex; int nBaud;
//
// read settings in from system
//
GetProfileString(m_szPorts, ComName, g_szNull, szParms, 81);
StripBlanks(szParms); if (lstrlen(szParms) == 0) { lstrcpy(szParms, m_szDefParams); WriteProfileString(m_szPorts, ComName, szParms); }
szCur = szParms;
//
// baud rate
//
szNext = strscan(szCur, m_szComma); if (*szNext) { //
// If we found a comma, terminate
//
*szNext++ = 0; }
//
// current Baud Rate selection
//
if (*szCur) { Params->PortSettings.BaudRate = myatoi(szCur); } else { //
// must not have been written, use default
//
Params->PortSettings.BaudRate = m_nBaudRates[DEF_BAUD]; }
//
// set the current value in the dialog sheet
//
nIndex = (int)SendDlgItemMessage(DialogHwnd, PP_PORT_BAUDRATE, CB_FINDSTRING, (WPARAM)-1, (LPARAM)szCur);
nIndex = (nIndex == CB_ERR) ? 0 : nIndex;
SendDlgItemMessage(DialogHwnd, PP_PORT_BAUDRATE, CB_SETCURSEL, nIndex, 0L);
szCur = szNext;
//
// parity
//
szNext = strscan(szCur, m_szComma);
if (*szNext) { *szNext++ = 0; } StripBlanks(szCur);
switch(*szCur) { case TEXT('o'): nIndex = PAR_ODD; break;
case TEXT('e'): nIndex = PAR_EVEN; break;
case TEXT('n'): nIndex = PAR_NONE; break;
case TEXT('m'): nIndex = PAR_MARK; break;
case TEXT('s'): nIndex = PAR_SPACE; break;
default: nIndex = DEF_PARITY; break; }
Params->PortSettings.Parity = nIndex; SendDlgItemMessage(DialogHwnd, PP_PORT_PARITY, CB_SETCURSEL, nIndex, 0L); szCur = szNext;
//
// word length: 4 - 8
//
szNext = strscan(szCur, m_szComma);
if (*szNext) { *szNext++ = 0; }
StripBlanks(szCur); nIndex = *szCur - TEXT('4');
if (nIndex < 0 || nIndex > 4) { nIndex = DEF_WORD; }
Params->PortSettings.DataBits = nIndex; SendDlgItemMessage(DialogHwnd, PP_PORT_DATABITS, CB_SETCURSEL, nIndex, 0L);
szCur = szNext;
//
// stop bits
//
szNext = strscan(szCur, m_szComma);
if (*szNext) { *szNext++ = 0; }
StripBlanks(szCur);
if (!lstrcmp(szCur, TEXT("1"))) { nIndex = STOP_1; } else if(!lstrcmp(szCur, TEXT("1.5"))) { nIndex = STOP_15; } else if(!lstrcmp(szCur, TEXT("2"))) { nIndex = STOP_2; } else { nIndex = DEF_STOP; }
SendDlgItemMessage(DialogHwnd, PP_PORT_STOPBITS, CB_SETCURSEL, nIndex, 0L);
Params->PortSettings.StopBits = nIndex; szCur = szNext;
//
// handshaking: Hardware, xon/xoff, or none
//
szNext = strscan(szCur, m_szComma);
if (*szNext) { *szNext++ = 0; }
StripBlanks(szCur);
if (*szCur == TEXT('p')) { nIndex = FLOW_HARD; } else if (*szCur == TEXT('x')) { nIndex = FLOW_XON; } else { nIndex = FLOW_NONE; }
SendDlgItemMessage(DialogHwnd, PP_PORT_FLOWCTL, CB_SETCURSEL, nIndex, 0L);
Params->PortSettings.FlowControl = nIndex; } /* GetPortSettings */
void RestorePortSettings( HWND DialogHwnd, PPORT_PARAMS Params ) { UINT nIndex;
//
// baud rate
//
nIndex = (UINT)SendDlgItemMessage(DialogHwnd, PP_PORT_BAUDRATE, CB_FINDSTRING, (WPARAM)-1, (LPARAM)TEXT("9600"));
nIndex = (nIndex == CB_ERR) ? 0 : nIndex; SendDlgItemMessage(DialogHwnd, PP_PORT_BAUDRATE, CB_SETCURSEL, nIndex, 0L);
//
// parity
//
SendDlgItemMessage(DialogHwnd, PP_PORT_PARITY, CB_SETCURSEL, PAR_NONE, 0L);
//
// word length: 4 - 8
//
SendDlgItemMessage(DialogHwnd, PP_PORT_DATABITS, CB_SETCURSEL, 4, // the 4th index is 8, what we want
0L);
//
// stop bits
//
SendDlgItemMessage(DialogHwnd, PP_PORT_STOPBITS, CB_SETCURSEL, STOP_1, 0L);
//
// handshaking: Hardware, xon/xoff, or none
//
SendDlgItemMessage(DialogHwnd, PP_PORT_FLOWCTL, CB_SETCURSEL, FLOW_NONE, 0L);
// nIndex = FLOW_HARD;
// nIndex = FLOW_XON;
// nIndex = FLOW_NONE;
}
/*++
Routine Description: SavePortSettingsDlg
save changes in the Ports Settings dlg sheet
Arguments:
Params: where to save the data to ParentHwnd: address of the window
Return Value:
ULONG: returns error messages
--*/ ULONG SavePortSettingsDlg( IN HWND DialogHwnd, IN PPORT_PARAMS Params ) { TCHAR szCharBuffer[81]; DWORD dwPortnum, dwOldPortnum; DWORD dwPortNameSize, dwError; TCHAR szNewComName[21]; TCHAR szSerialKey[41]; TCHAR szTitle[81]; TCHAR szTitleFormat[81]; HKEY hDeviceKey, hKey;
//
// create "com#:"
//
// lstrcpy(szCharBuffer, Params->pAdvancedData->szNewComName);
lstrcpy(szCharBuffer, Params->PortSettings.szComName); lstrcat(szCharBuffer, m_szColon);
//
// store changes to win.ini; broadcast changes to apps
//
SavePortSettings(DialogHwnd, szCharBuffer, Params);
return 0; } /* SavePortSettingsDlg */
/*++
Routine Description: SavePortSettings
Read the dlg screen selections for baudrate, parity, etc. If changed from what we started with, then save them
Arguments:
hDlg: address of the window szComName: which comport we're dealing with Params: contains, baudrate, parity, etc
Return Value:
ULONG: returns error messages
--*/ void SavePortSettings( IN HWND DialogHwnd, IN PTCHAR ComName, IN PPORT_PARAMS Params ) { TCHAR szBuild[PATHMAX]; ULONG i; PP_PORTSETTINGS pppNewPortSettings;
//
// Get the baud rate
//
i = (ULONG)SendDlgItemMessage(DialogHwnd, PP_PORT_BAUDRATE, WM_GETTEXT, 18, (LPARAM)szBuild); if (!i) { goto Return; }
pppNewPortSettings.BaudRate = myatoi(szBuild);
//
// Get the parity setting
//
i = (ULONG)SendDlgItemMessage(DialogHwnd, PP_PORT_PARITY, CB_GETCURSEL, 0, 0L);
if (i == CB_ERR || i == CB_ERRSPACE) { goto Return; }
pppNewPortSettings.Parity = i; lstrcat(szBuild, m_pszParitySuf[i]);
//
// Get the word length
//
i = (ULONG)SendDlgItemMessage(DialogHwnd, PP_PORT_DATABITS, CB_GETCURSEL, 0, 0L);
if (i == CB_ERR || i == CB_ERRSPACE) { goto Return; }
pppNewPortSettings.DataBits = i; lstrcat(szBuild, m_pszLenSuf[i]);
//
// Get the stop bits
//
i = (ULONG)SendDlgItemMessage(DialogHwnd, PP_PORT_STOPBITS, CB_GETCURSEL, 0, 0L);
if (i == CB_ERR || i == CB_ERRSPACE) { goto Return; }
pppNewPortSettings.StopBits = i; lstrcat(szBuild, m_pszStopSuf[i]);
//
// Get the flow control
//
i = (ULONG)SendDlgItemMessage(DialogHwnd, PP_PORT_FLOWCTL, CB_GETCURSEL, 0, 0L);
if (i == CB_ERR || i == CB_ERRSPACE) { goto Return; }
pppNewPortSettings.FlowControl = i; lstrcat(szBuild, m_pszFlowSuf[i]);
//
// if any of the values changed, then save it off
//
if (Params->PortSettings.BaudRate != pppNewPortSettings.BaudRate || Params->PortSettings.Parity != pppNewPortSettings.Parity || Params->PortSettings.DataBits != pppNewPortSettings.DataBits || Params->PortSettings.StopBits != pppNewPortSettings.StopBits || Params->PortSettings.FlowControl != pppNewPortSettings.FlowControl) {
//
// Write settings string to [ports] section in win.ini
// NT translates this if a translate key is set in registry
// and it winds up getting written to
// HKLM\Software\Microsoft\Windows NT\CurrentVersion\Ports
//
WriteProfileString(m_szPorts, ComName, szBuild);
//
// Send global notification message to all windows
//
SendWinIniChange((LPTSTR)m_szPorts);
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, Params->DeviceInfoSet, Params->DeviceInfoData)) { //
// Possibly do something here
//
} }
Return: return;
} /* SavePortSettings */
|