|
|
///////////////////////////////////////////////////////////////////////////
// Advanced Dialog Functions
///////////////////////////////////////////////////////////////////////////
#include "ports.h"
#include "pp.h"
#include <windowsx.h>
#define COBJMACROS 1
#include <ole2.h>
#include <initguid.h>
#include <oleacc.h>
#include <winable.h>
//
// write out values in tenths of a sec
//
#define SECONDS_CONVERSION_FACTOR (10)
#define NUM_POLLING_PERIODS 7
DWORD PollingPeriods[NUM_POLLING_PERIODS] = { -1, 0, 1 * SECONDS_CONVERSION_FACTOR, 5 * SECONDS_CONVERSION_FACTOR, 10 * SECONDS_CONVERSION_FACTOR, 30 * SECONDS_CONVERSION_FACTOR, 60 * SECONDS_CONVERSION_FACTOR };
TCHAR PeriodDescription[NUM_POLLING_PERIODS+1][40] = { { _T("Disabled") }, { _T("Manually") }, { _T("Every second") }, { _T("Every 5 seconds") }, { _T("Every 10 seconds") }, { _T("Every 30 seconds") }, { _T("Every minute") }, { _T("Other (every %d sec)") } };
ULONG RxValues[4] = { 1, 4, 8, 14};
WCHAR RxValuesStringMap[] = L"A:0:1:1:2:4:3:8:4:14:"; WCHAR TxValuesStringMap[] = L"use_raw";
TCHAR m_szRxFIFO[] = _T("RxFIFO"); TCHAR m_szTxFIFO[] = _T("TxFIFO"); TCHAR m_szFifoRxMax[] = _T("FifoRxMax"); TCHAR m_szFifoTxMax[] = _T("FifoTxMax");
const DWORD AdvanHelpIDs[] = { IDC_DESC_1, IDH_NOHELP, IDC_DESC_2, IDH_NOHELP,
IDC_FIFO, IDH_DEVMGR_PORTSET_ADV_USEFIFO, // "Use FIFO buffers (requires 16550 compatible UART)" (Button)
IDC_RECEIVE_TEXT, IDH_NOHELP, // "&Receive Buffer:" (Static)
IDC_RECEIVE_SLIDER, IDH_DEVMGR_PORTSET_ADV_RECV, // "" (msctls_trackbar32)
IDC_RECEIVE_LOW, IDH_NOHELP, // "Low (%d)" (Static)
IDC_RECEIVE_HIGH, IDH_NOHELP, // "High (%d)" (Static)
IDC_RXVALUE, IDH_NOHELP,
IDC_TRANSMIT_TEXT, IDH_NOHELP, // "&Transmit Buffer:" (Static)
IDC_TRANSMIT_SLIDER, IDH_DEVMGR_PORTSET_ADV_TRANS, // "" (msctls_trackbar32)
IDC_TRANSMIT_LOW, IDH_NOHELP, // "Low (%d)" (Static)
IDC_TRANSMIT_HIGH, IDH_NOHELP, // "High (%d)" (Static)
IDC_TXVALUE, IDH_NOHELP,
IDC_POLL_DESC, IDH_NOHELP, IDC_POLL_PERIOD, IDH_DEVMGR_PORTSET_ADV_DEVICES, // "" (ComboBox)
PP_PORT_NUMBER, IDH_DEVMGR_PORTSET_ADV_NUMBER, // "" (ComboBox)
IDC_COMNUMTEXT, IDH_NOHELP, // "COM &Port Number:" (Static)
IDC_RESTORE, IDH_DEVMGR_PORTSET_ADV_DEFAULTS,// "&Restore Defaults" (Button)
0, 0 };
#define Trackbar_SetPos(hwndTb, Redraw, Position)\
(VOID) SendMessage(hwndTb, TBM_SETPOS, (WPARAM) Redraw, (LPARAM) Position)
#define Trackbar_SetRange(hwndTb, Redraw, MinVal, MaxVal)\
(VOID) SendMessage(hwndTb, TBM_SETRANGE, (WPARAM) Redraw, (LPARAM) MAKELONG(MinVal, MaxVal))
#define Trackbar_SetTic(hwndTb, Tic)\
(VOID) SendMessage(hwndTb, TBM_SETTIC, (WPARAM) 0, (LPARAM) Tic)
#define Trackbar_GetPos(hwndTb)\
(DWORD) SendMessage(hwndTb, TBM_GETPOS, (WPARAM) 0, (LPARAM) 0)
BOOL Advanced_OnCommand( HWND ParentHwnd, int ControlId, HWND ControlHwnd, UINT NotifyCode );
BOOL Advanced_OnContextMenu( HWND HwndControl, WORD Xpos, WORD Ypos );
void Advanced_OnHelp( HWND ParentHwnd, LPHELPINFO HelpInfo );
BOOL Advanced_OnInitDialog( HWND ParentHwnd, HWND FocusHwnd, LPARAM Lparam );
/*++
Routine Description: AdvancedPortsDlgProc
The windows proc for the Advanced properties window
Arguments:
hDlg, uMessage, wParam, lParam: standard windows DlgProc parameters
Return Value:
BOOL: FALSE if the page could not be created
--*/ INT_PTR APIENTRY AdvancedPortsDlgProc( IN HWND hDlg, IN UINT uMessage, IN WPARAM wParam, IN LPARAM lParam ) { switch(uMessage) { case WM_COMMAND: return Advanced_OnCommand(hDlg, (int) LOWORD(wParam), (HWND)lParam, (UINT) HIWORD(wParam));
case WM_CONTEXTMENU: return Advanced_OnContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
case WM_HELP: Advanced_OnHelp(hDlg, (LPHELPINFO) lParam); break;
case WM_HSCROLL: HandleTrackbarChange(hDlg, (HWND) lParam); return TRUE;
case WM_INITDIALOG: return Advanced_OnInitDialog(hDlg, (HWND) wParam, lParam); }
return FALSE; } /* AdvancedPortsDlgProc */
BOOL Advanced_OnCommand( HWND ParentHwnd, int ControlId, HWND ControlHwnd, UINT NotifyCode ) { PADVANCED_DATA advancedData = (PADVANCED_DATA) GetWindowLongPtr(ParentHwnd, DWLP_USER);
switch(ControlId) {
case IDC_FIFO: //
// Disable or enable the sliders
//
EnableFifoControls(ParentHwnd, IsDlgButtonChecked(ParentHwnd, IDC_FIFO)); return TRUE;
case IDOK: SaveAdvancedSettings(ParentHwnd, advancedData); // fall through
case IDCANCEL: EndDialog(ParentHwnd, ControlId); return TRUE;
case IDC_RESTORE: RestoreAdvancedDefaultState(ParentHwnd, advancedData); return TRUE; }
return FALSE; }
BOOL Advanced_OnContextMenu( HWND HwndControl, WORD Xpos, WORD Ypos ) { WinHelp(HwndControl, m_szDevMgrHelp, HELP_CONTEXTMENU, (ULONG_PTR) AdvanHelpIDs);
return FALSE; }
void Advanced_OnHelp( HWND ParentHwnd, LPHELPINFO HelpInfo ) { if (HelpInfo->iContextType == HELPINFO_WINDOW) { WinHelp((HWND) HelpInfo->hItemHandle, m_szDevMgrHelp, HELP_WM_HELP, (ULONG_PTR) AdvanHelpIDs); } }
BOOL Advanced_OnInitDialog( HWND ParentHwnd, HWND FocusHwnd, LPARAM Lparam ) { PADVANCED_DATA advancedData; TCHAR szFormat[200]; TCHAR szBuffer[200];
advancedData = (PADVANCED_DATA) Lparam;
//
// Initialize the dialog box parameters
//
FillAdvancedDlg(ParentHwnd, advancedData); SetWindowLongPtr(ParentHwnd, DWLP_USER, (ULONG_PTR) advancedData);
//
// Set up the dialog box with these initialized parameters
//
InitializeControls(ParentHwnd, advancedData);
LoadString(g_hInst, IDS_ADVANCED_SETTINGS_FOR, szFormat, CharSizeOf(szFormat)); wsprintf(szBuffer, szFormat, advancedData->szComName); SetWindowText(ParentHwnd, szBuffer);
return TRUE; }
// @@BEGIN_DDKSPLIT
LONG SerialDisplayAdvancedSettings( IN HWND ParentHwnd, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData ) { ADVANCED_DATA advancedData; HKEY hDeviceKey; DWORD dwPortNameSize;
if (!DeviceInfoSet) { return ERROR_INVALID_PARAMETER; }
advancedData.HidePolling = TRUE; advancedData.DeviceInfoSet = DeviceInfoSet; advancedData.DeviceInfoData = DeviceInfoData;
//
// Open the device key for the source device instance, and retrieve its
// "PortName" value.
//
hDeviceKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
if (INVALID_HANDLE_VALUE == hDeviceKey) return ERROR_ACCESS_DENIED;
dwPortNameSize = sizeof(advancedData.szComName); if (RegQueryValueEx(hDeviceKey, m_szPortName, NULL, NULL, (PBYTE) advancedData.szComName, &dwPortNameSize) != ERROR_SUCCESS) { RegCloseKey(hDeviceKey); return ERROR_INVALID_DATA; } RegCloseKey(hDeviceKey);
return DisplayAdvancedDialog(ParentHwnd, &advancedData) ? ERROR_SUCCESS : ERROR_ACCESS_DENIED; } // @@END_DDKSPLIT
BOOL InternalAdvancedDialog( IN HWND ParentHwnd, IN OUT PADVANCED_DATA AdvancedData ) { AdvancedData->hComDB = HCOMDB_INVALID_HANDLE_VALUE; ComDBOpen(&AdvancedData->hComDB);
DialogBoxParam(g_hInst, MAKEINTRESOURCE(DLG_PP_ADVPORTS), ParentHwnd, AdvancedPortsDlgProc, (DWORD_PTR) AdvancedData);
ComDBClose(AdvancedData->hComDB); AdvancedData->hComDB = HCOMDB_INVALID_HANDLE_VALUE;
return TRUE; }
// @@BEGIN_DDKSPLIT
BOOL FindAdvancedDialogOverride( IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, IN PTCHAR Value ) /*++
Routine Description:
Checks the driver key in the devnode for the override value.
Arguments:
DeviceInfoSet - Supplies a handle to the device information
DeviceInfoData - Supplies the address of the device information element
Value - Value read in from the registry
Return Value:
If found TRUE, otherwise FALSE
--*/ { HKEY hKey; TCHAR szLine[LINE_LEN]; DWORD dwDataType, dwSize; TCHAR szOverrideName[] = _T("EnumAdvancedDialog");
//
// Open up the driver key for this device so we can run our INF registry mods
// against it.
//
hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ);
dwSize = sizeof(szLine); if (RegQueryValueEx(hKey, szOverrideName, NULL, &dwDataType, (PBYTE) &szLine, &dwSize) != ERROR_SUCCESS || dwDataType != REG_SZ) { RegCloseKey(hKey); return FALSE; }
lstrcpy(Value, szLine); RegCloseKey(hKey); return TRUE; }
BOOL CallAdvancedDialogOverride( IN HWND ParentHwnd, IN PADVANCED_DATA AdvancedData, PTCHAR Override, PBOOL Success ) { PTCHAR szProc = NULL; HINSTANCE hInst = NULL; PPORT_ADVANCED_DIALOG pfnAdvanced = NULL; TCHAR szNewComName[50]; HKEY hDeviceKey; DWORD dwSize; TCHAR szMfg[LINE_LEN];
#ifdef UNICODE
CHAR szFunction[LINE_LEN]; #endif
szProc = _tcschr(Override, _T(',')); if (!szProc) { return FALSE; }
*szProc = _T('\0'); szProc++;
hInst = LoadLibrary(Override); if (!hInst) { return FALSE; }
#ifdef UNICODE
WideCharToMultiByte(CP_ACP, 0, szProc, lstrlen(szProc) + 1, szFunction, sizeof(szFunction), NULL, NULL);
pfnAdvanced = (PPORT_ADVANCED_DIALOG) GetProcAddress(hInst, szFunction); #else
pfnAdvanced = (PPORT_ADVANCED_DIALOG) GetProcAddress(hInst, szProc); #endif
if (!pfnAdvanced) { FreeLibrary(hInst); return FALSE; }
_try { *Success = (*pfnAdvanced) (ParentHwnd, AdvancedData->HidePolling, AdvancedData->DeviceInfoSet, AdvancedData->DeviceInfoData, NULL);
} _except(UnhandledExceptionFilter(GetExceptionInformation())) { *Success = FALSE; }
//
// Make sure the new com name is zero terminated in case of error
//
AdvancedData->szComName[0] = TEXT('\0');
//
// Open the device key for the source device instance, and retrieve its
// "PortName" value in case the override dialog changed it.
//
hDeviceKey = SetupDiOpenDevRegKey(AdvancedData->DeviceInfoSet, AdvancedData->DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
if (INVALID_HANDLE_VALUE != hDeviceKey) { dwSize = sizeof(szNewComName); if (RegQueryValueEx(hDeviceKey, m_szPortName, NULL, NULL, (PBYTE) szNewComName, &dwSize) == ERROR_SUCCESS) { lstrcpy(AdvancedData->szComName, szNewComName); } RegCloseKey(hDeviceKey); }
FreeLibrary(hInst); return TRUE; } // @@END_DDKSPLIT
/*++
Routine Description: DisplayAdvancedDialog
Opens the devices instance and checks to see if it is valid. If so, then the advanced dialog is displayed. Otherwise a message is displayed to the user stating that the user does not have write access to this particular key.
Arguments:
ParentHwnd - Handle to the parent dialog (Port Settings Property Sheet) AdvancedData - hDeviceKey will be set with the device's key in the registry upon success, INVALID_HANDLE_VALUE upon error
Return Value:
None
--*/ BOOL DisplayAdvancedDialog( IN HWND ParentHwnd, IN OUT PADVANCED_DATA AdvancedData ) { AdvancedData->hDeviceKey = SetupDiOpenDevRegKey(AdvancedData->DeviceInfoSet, AdvancedData->DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_ALL_ACCESS);
if (AdvancedData->hDeviceKey == INVALID_HANDLE_VALUE) { MyMessageBox(ParentHwnd, IDS_NO_WRITE_PRVILEGE, IDS_NAME_PROPERTIES, MB_OK | MB_ICONINFORMATION); return FALSE; } else { // @@BEGIN_DDKSPLIT
TCHAR szOverride[LINE_LEN]; BOOL success = FALSE;
if (FindAdvancedDialogOverride(AdvancedData->DeviceInfoSet, AdvancedData->DeviceInfoData, szOverride) && CallAdvancedDialogOverride(ParentHwnd, AdvancedData, szOverride, &success)) { RegCloseKey(AdvancedData->hDeviceKey); return success; } else { // @@END_DDKSPLIT
return InternalAdvancedDialog(ParentHwnd, AdvancedData); // @@BEGIN_DDKSPLIT
} // @@END_DDKSPLIT
} }
/*++
Routine Description: EnableFifoControls
Enables/Disables all of the controls bounded by the rectangle with the Use Fifo checkbox.
Arguments:
hDlg - Handle to the dialog enabled - flag to either enable/disable the controls
Return Value:
None
--*/ void EnableFifoControls(IN HWND hDlg, IN BOOL enabled) { // The actual trackbar/slider
EnableWindow(GetDlgItem(hDlg, IDC_RECEIVE_SLIDER), enabled);
// "Low (xxx)" (Receive)
EnableWindow(GetDlgItem(hDlg, IDC_RECEIVE_LOW), enabled);
// "High (xxx)" (Receive)
EnableWindow(GetDlgItem(hDlg, IDC_RECEIVE_HIGH), enabled);
// "Receive Buffer: "
EnableWindow(GetDlgItem(hDlg, IDC_RECEIVE_TEXT), enabled);
// "(xxx)" (Actual value of trackbar, Receive)
EnableWindow(GetDlgItem(hDlg, IDC_RXVALUE), enabled);
// The actual trackbar/slider
EnableWindow(GetDlgItem(hDlg, IDC_TRANSMIT_SLIDER), enabled);
// "Low (xxx)" (Transmit)
EnableWindow(GetDlgItem(hDlg, IDC_TRANSMIT_LOW), enabled);
// "High (xxx)" (Transmit)
EnableWindow(GetDlgItem(hDlg, IDC_TRANSMIT_HIGH), enabled);
// "Transmit Buffer" (Transmit)
EnableWindow(GetDlgItem(hDlg, IDC_TRANSMIT_TEXT), enabled);
// "(xxx)" (Actual value of trackbar, Trasmist)
EnableWindow(GetDlgItem(hDlg, IDC_TXVALUE), enabled); }
/*++
Routine Description: HandleTrackbarChange
Whenever the user changes the trackbar thumb position, update the control to its right which displays its actual numeric value
Arguments:
hDlg - Handle to the parent dialog hTrackbar - Handle to the trackbar whose thumb has changed
Return Value:
None
--*/ void HandleTrackbarChange(IN HWND hDlg, IN HWND hTrackbar ) { DWORD ctrlID; TCHAR szCurrentValue[10]; ULONG position;
position = Trackbar_GetPos(hTrackbar);
if (GetDlgCtrlID(hTrackbar) == IDC_RECEIVE_SLIDER) { //
// Rx we need to translate the tick position from index to value
//
wsprintf(szCurrentValue, TEXT("(%d)"), RxValues[position-1]); ctrlID = IDC_RXVALUE; } else { //
// Tx is just a straight translation between value and index
//
wsprintf(szCurrentValue, TEXT("(%d)"), position); ctrlID = IDC_TXVALUE; } SetDlgItemText(hDlg, ctrlID, szCurrentValue); }
DWORD RxValueToTrackbarPosition(IN OUT PDWORD RxValue ) { switch (*RxValue) { case 1: return 1; case 4: return 2; case 8: return 3; case 14: return 4; }
//
// busted value
//
*RxValue = 14; return 4; }
/*++
Routine Description: SetTxTrackbarTicks
Creates a tick at 1/4, half, and 3/4 across the span of the trackbar
Arguments:
hTrackbar - handle to the trackbar that will receive the ticks minVal, maxVal - Range on the trackbar
Return Value:
None
--*/ void SetTxTrackbarTics( IN HWND TrackbarHwnd ) { Trackbar_SetTic(TrackbarHwnd, 6); Trackbar_SetTic(TrackbarHwnd, 11); }
/*++
Routine Description: SetLabelText
Sets the label's to the string identified by resID concated with the passed in value and closing paren.
The final string is [resID string][value])
Arguments:
hLabel - handle to the control whose text is going to change resID - resource ID for the beginning of the string that will become the label's text value - number to be concated into the string
Return Value:
None
--*/ void SetLabelText( IN HWND LabelHwnd, IN DWORD ResId, IN ULONG Value ) { TCHAR szTemp[258], txt[258];
if (LoadString(g_hInst, ResId, szTemp, CharSizeOf(szTemp))) { lstrcpy(txt, szTemp); wsprintf(szTemp, _T("%d)"), Value); lstrcat(txt, szTemp); } else { lstrcpy(txt, _T("Low")); } SetWindowText(LabelHwnd, txt); }
/*++
Routine Description: InitializeControls
Initializes all of the controls that represent Fifo
Arguments:
ParentHwnd - handle to the dialog AdvancedData - Contains all of the initial values
Return Value:
None
--*/ void InitializeControls( IN HWND ParentHwnd, IN PADVANCED_DATA AdvancedData ) { TCHAR szCurrentValue[40]; HWND hwnd; int i, periodIdx;
//
// Set up the Fifo buffers checkbox
//
if (!AdvancedData->UseFifoBuffersControl) { //
// Something went wrong with the Fifo buffers control. Disable
// the checkbox
//
CheckDlgButton(ParentHwnd, IDC_FIFO, BST_UNCHECKED); EnableWindow(GetDlgItem(ParentHwnd, IDC_FIFO), FALSE); EnableFifoControls(ParentHwnd, FALSE); } else { EnableWindow(GetDlgItem(ParentHwnd, IDC_FIFO), TRUE);
if (!AdvancedData->UseFifoBuffers) { EnableFifoControls(ParentHwnd, FALSE); CheckDlgButton(ParentHwnd, IDC_FIFO, BST_UNCHECKED); } else { EnableFifoControls(ParentHwnd, TRUE); CheckDlgButton(ParentHwnd, IDC_FIFO, BST_CHECKED); } }
//
// Set up the sliders
//
if (!AdvancedData->UseRxFIFOControl || !AdvancedData->UseTxFIFOControl) { //
// Something went wrong with the sliders.
// Disable them
//
CheckDlgButton(ParentHwnd, IDC_FIFO, BST_UNCHECKED); EnableWindow(GetDlgItem(ParentHwnd, IDC_FIFO), FALSE); EnableFifoControls(ParentHwnd, FALSE); } else { IAccPropServices * pAccPropServices = NULL; HRESULT hr; //
// Set up Rx Slider
//
hwnd = GetDlgItem(ParentHwnd, IDC_RECEIVE_SLIDER);
Trackbar_SetRange(hwnd, TRUE, RX_MIN, 4); Trackbar_SetPos(hwnd, TRUE, RxValueToTrackbarPosition(&AdvancedData->RxFIFO));
SetLabelText(GetDlgItem(ParentHwnd, IDC_RECEIVE_LOW), IDS_LOW, RX_MIN); SetLabelText(GetDlgItem(ParentHwnd, IDC_RECEIVE_HIGH), IDS_HIGH, AdvancedData->FifoRxMax);
wsprintf(szCurrentValue, TEXT("(%d)"), AdvancedData->RxFIFO); SetDlgItemText(ParentHwnd, IDC_RXVALUE, szCurrentValue);
//
// Create the mapping for this slider for accessibility
//
hr = CoCreateInstance(&CLSID_AccPropServices, NULL, CLSCTX_INPROC_SERVER, &IID_IAccPropServices, (PVOID *) &pAccPropServices);
if (SUCCEEDED(hr) && pAccPropServices != NULL) { IAccPropServices_SetHwndPropStr(pAccPropServices, hwnd, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_VALUEMAP, RxValuesStringMap);
IAccPropServices_Release(pAccPropServices); }
//
// Set up the Tx slider
//
hwnd = GetDlgItem(ParentHwnd, IDC_TRANSMIT_SLIDER); Trackbar_SetRange(hwnd, TRUE, TX_MIN, AdvancedData->FifoTxMax); Trackbar_SetPos(hwnd, TRUE, AdvancedData->TxFIFO);
SetTxTrackbarTics(hwnd);
SetLabelText(GetDlgItem(ParentHwnd, IDC_TRANSMIT_LOW), IDS_LOW, TX_MIN); SetLabelText(GetDlgItem(ParentHwnd, IDC_TRANSMIT_HIGH), IDS_HIGH, AdvancedData->FifoTxMax);
wsprintf(szCurrentValue, TEXT("(%d)"), AdvancedData->TxFIFO); SetDlgItemText(ParentHwnd, IDC_TXVALUE, szCurrentValue); //
// Create the mapping for this slider for accessibility
//
hr = CoCreateInstance(&CLSID_AccPropServices, NULL, CLSCTX_INPROC_SERVER, &IID_IAccPropServices, (PVOID *) &pAccPropServices);
if (SUCCEEDED(hr) && pAccPropServices != NULL) { IAccPropServices_SetHwndPropStr(pAccPropServices, hwnd, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_VALUEMAP, TxValuesStringMap);
IAccPropServices_Release(pAccPropServices); } }
FillPortNameCb(ParentHwnd, AdvancedData);
if (!AdvancedData->HidePolling) {
//
// Add the descriptions for each polling period and select the current
// setting
//
hwnd = GetDlgItem(ParentHwnd, IDC_POLL_PERIOD); periodIdx = NUM_POLLING_PERIODS; for (i = 0; i < NUM_POLLING_PERIODS; i++) { ComboBox_AddString(hwnd, PeriodDescription[i]); if (PollingPeriods[i] == AdvancedData->PollingPeriod) { periodIdx = i; } }
if (periodIdx == NUM_POLLING_PERIODS) { wsprintf(szCurrentValue, PeriodDescription[NUM_POLLING_PERIODS], AdvancedData->PollingPeriod / SECONDS_CONVERSION_FACTOR); ComboBox_AddString(hwnd, szCurrentValue); }
ComboBox_SetCurSel(hwnd, periodIdx); } else { ShowWindow(GetDlgItem(ParentHwnd, IDC_POLL_PERIOD), SW_HIDE); ShowWindow(GetDlgItem(ParentHwnd, IDC_POLL_DESC), SW_HIDE); } } /* InitializeControls */
/*++
Routine Description: RestoreAdvancedDefaultState
Restores all values and UI to their default state, specifically: o All Fifo related child controls are enabled o The Rx trackbar is set to its max value o The Tx trackbar is set to its max value o The number of the comport is reset to its original value
Return Value:
None
--*/ void RestoreAdvancedDefaultState( IN HWND ParentHwnd, IN PADVANCED_DATA AdvancedData ) { USHORT ushIndex; TCHAR szCurrentValue[10]; int i;
//
// Set up the Fifo buffers checkbox
//
EnableWindow(GetDlgItem(ParentHwnd, IDC_FIFO), TRUE);
EnableFifoControls(ParentHwnd, TRUE); CheckDlgButton(ParentHwnd, IDC_FIFO, BST_CHECKED);
//
// Set up the sliders and the static control that show their numberic value
//
Trackbar_SetPos(GetDlgItem(ParentHwnd, IDC_RECEIVE_SLIDER), TRUE, RxValueToTrackbarPosition(&AdvancedData->FifoRxMax)); wsprintf(szCurrentValue, TEXT("(%d)"), AdvancedData->FifoRxMax); SetDlgItemText(ParentHwnd, IDC_RXVALUE, szCurrentValue);
Trackbar_SetPos(GetDlgItem(ParentHwnd, IDC_TRANSMIT_SLIDER), TRUE, AdvancedData->FifoTxMax); wsprintf(szCurrentValue, TEXT("(%d)"), AdvancedData->FifoTxMax); SetDlgItemText(ParentHwnd, IDC_TXVALUE, szCurrentValue);
//
// Set the COM name to whatever it is currently set to in the registry
//
ushIndex = (USHORT) ComboBox_FindString(GetDlgItem(ParentHwnd, PP_PORT_NUMBER), -1, AdvancedData->szComName);
ushIndex = (ushIndex == CB_ERR) ? 0 : ushIndex;
ComboBox_SetCurSel(GetDlgItem(ParentHwnd, PP_PORT_NUMBER), ushIndex); ComboBox_SetCurSel(GetDlgItem(ParentHwnd, IDC_POLL_PERIOD), POLL_PERIOD_DEFAULT_IDX); } /* RestoreAdvancedDefaultStates */
/*++
Routine Description: FillPortNameCb
fill in the Port Name combo box selection with a list of possible un-used portnames
Arguments:
poppOurPropParams: where to save the data to hDlg: address of the window
Return Value:
ULONG: returns error messages
--*/ ULONG FillPortNameCb( HWND ParentHwnd, PADVANCED_DATA AdvancedData ) { BYTE portUsage[MAX_COM_PORT/8]; DWORD tmp, portsReported; int i, j, nEntries; int nCurPortNum; TCHAR szCom[40]; TCHAR szInUse[40]; char mask, *current; HWND portHwnd;
portHwnd = GetDlgItem(ParentHwnd, PP_PORT_NUMBER);
//
// Check if our ComName is blank. If it is, disable the com port selector
//
if (_tcscmp(AdvancedData->szComName, TEXT("")) == 0) { EnableWindow(portHwnd, FALSE); EnableWindow(GetDlgItem(ParentHwnd, IDC_COMNUMTEXT), FALSE); return 0; }
//
// assumes szComPort filled in...
//
nCurPortNum = myatoi(&AdvancedData->szComName[3]);
if (!LoadString(g_hInst, IDS_IN_USE, szInUse, CharSizeOf(szInUse))) { wcscpy(szInUse, _T(" (in use)")); }
//
// first tally up which ports NOT to offer in list box
//
ZeroMemory(portUsage, MAX_COM_PORT/8);
if (AdvancedData->hComDB != HCOMDB_INVALID_HANDLE_VALUE) { ComDBGetCurrentPortUsage(AdvancedData->hComDB, portUsage, MAX_COM_PORT / 8, CDB_REPORT_BITS, &portsReported); }
//
// tag the current port as not in use so it shows up in the CB
//
current = portUsage + (nCurPortNum-1) / 8; if ((i = nCurPortNum % 8)) *current &= ~(1 << (i-1)); else *current &= ~(0x80);
current = portUsage; mask = 0x1; for(nEntries = j = 0, i = MIN_COM-1; i < MAX_COM_PORT; i++) {
wsprintf(szCom, TEXT("COM%d"), i+1); if (*current & mask) { wcscat(szCom, szInUse); }
if (mask == (char) 0x80) { mask = 0x01; current++; } else { mask <<= 1; }
ComboBox_AddString(portHwnd, szCom); }
ComboBox_SetCurSel(portHwnd, nCurPortNum-1); return 0; } /* FillPortNamesCb */
/*++
Routine Description: FillAdvancedDlg
fill in the advanced dialog window
Arguments:
poppOurPropParams: the data to fill in ParentHwnd: address of the window
Return Value:
ULONG: returns error messages
--*/ ULONG FillAdvancedDlg( IN HWND ParentHwnd, IN PADVANCED_DATA AdvancedData ) { PSP_DEVINFO_DATA DeviceInfoData = AdvancedData->DeviceInfoData; HKEY hDeviceKey; DWORD dwSize, dwData, dwFifo, dwError = ERROR_SUCCESS;
//
// Open the device key for the source device instance
//
hDeviceKey = AdvancedData->hDeviceKey;
//
// Get COM Name
//
dwSize = sizeof(AdvancedData->szComName); dwError = RegQueryValueEx(hDeviceKey, m_szPortName, NULL, NULL, (PBYTE)AdvancedData->szComName, &dwSize);
if (dwError != ERROR_SUCCESS) { wsprintf(AdvancedData->szComName, TEXT("COMX")); }
//
// Get ForceFifoEnable information
//
AdvancedData->UseFifoBuffersControl = TRUE;
dwSize = sizeof(dwFifo); dwError = RegQueryValueEx(hDeviceKey, m_szFIFO, NULL, NULL, (LPBYTE)(&dwFifo), &dwSize);
if (dwError == ERROR_SUCCESS) { //
// Save this initial value
//
AdvancedData->UseFifoBuffersControl = TRUE; if (dwFifo == 0) { AdvancedData->UseFifoBuffers = FALSE; } else { AdvancedData->UseFifoBuffers = TRUE; } } else { //
// value does not exist. Create our own
//
dwData = 1; dwSize = sizeof(dwSize); dwError = RegSetValueEx(hDeviceKey, m_szFIFO, 0, REG_DWORD, (CONST BYTE *)(&dwData), dwSize);
if (dwError == ERROR_SUCCESS) { AdvancedData->UseFifoBuffers = TRUE; } else { AdvancedData->UseFifoBuffers = FALSE; AdvancedData->UseFifoBuffersControl = FALSE; } }
//
// Get FifoRxMax information
//
dwSize = sizeof(dwFifo); dwError = RegQueryValueEx(hDeviceKey, m_szFifoRxMax, NULL, NULL, (LPBYTE)(&dwFifo), &dwFifo);
if (dwError == ERROR_SUCCESS) { //
// Save this initial value
//
AdvancedData->FifoRxMax = dwFifo; if (AdvancedData->FifoRxMax > RX_MAX) { AdvancedData->FifoRxMax = RX_MAX; } } else { //
// value does not exist. Create our own
//
AdvancedData->FifoRxMax = RX_MAX; }
//
// Get RxFIFO information
//
dwSize = sizeof(dwFifo); dwError = RegQueryValueEx(hDeviceKey, m_szFifoTxMax, NULL, NULL, (LPBYTE)(&dwFifo), &dwSize);
if (dwError == ERROR_SUCCESS) { //
// Save this initial value
//
AdvancedData->FifoTxMax = dwFifo; if (AdvancedData->FifoTxMax > TX_MAX) { AdvancedData->FifoTxMax = TX_MAX; } } else { //
// value does not exist. Create our own
//
AdvancedData->FifoTxMax = TX_MAX; }
//
// Get RxFIFO information
//
AdvancedData->UseRxFIFOControl = TRUE;
dwSize = sizeof(dwFifo); dwError = RegQueryValueEx(hDeviceKey, m_szRxFIFO, NULL, NULL, (LPBYTE)(&dwFifo), &dwSize);
if (dwError == ERROR_SUCCESS) { //
// Save this initial value
//
AdvancedData->RxFIFO = dwFifo; if (AdvancedData->RxFIFO > RX_MAX) { goto SetRxFIFO; } } else { SetRxFIFO: //
// value does not exist. Create our own
//
dwData = AdvancedData->FifoRxMax; dwSize = sizeof(dwData); dwError = RegSetValueEx(hDeviceKey, m_szRxFIFO, 0, REG_DWORD, (CONST BYTE *)(&dwData), dwSize);
if (dwError == ERROR_SUCCESS) { AdvancedData->RxFIFO = AdvancedData->FifoRxMax; } else { AdvancedData->RxFIFO = 0; AdvancedData->UseRxFIFOControl = FALSE; } }
//
// Get TxFIFO information
//
AdvancedData->UseTxFIFOControl = TRUE;
dwSize = sizeof(dwFifo); dwError = RegQueryValueEx(hDeviceKey, m_szTxFIFO, NULL, NULL, (LPBYTE)(&dwFifo), &dwSize);
if (dwError == ERROR_SUCCESS) { //
// Save this initial value
//
AdvancedData->TxFIFO = dwFifo; if (AdvancedData->TxFIFO > TX_MAX) { goto SetTxFIFO; } } else { SetTxFIFO: //
// value does not exist. Create our own
//
dwData = AdvancedData->FifoTxMax; dwSize = sizeof(dwData); dwError = RegSetValueEx(hDeviceKey, m_szTxFIFO, 0, REG_DWORD, (LPBYTE)(&dwData), dwSize);
if (dwError == ERROR_SUCCESS) { AdvancedData->TxFIFO = AdvancedData->FifoTxMax; } else { AdvancedData->TxFIFO = 0; AdvancedData->UseTxFIFOControl = FALSE; } }
//
// Get Polling Period information
//
AdvancedData->PollingPeriod = PollingPeriods[POLL_PERIOD_DEFAULT_IDX];
dwSize = sizeof(dwFifo); dwError = RegQueryValueEx(hDeviceKey, m_szPollingPeriod, NULL, NULL, (LPBYTE)(&dwFifo), &dwSize);
if (dwError == ERROR_SUCCESS) { //
// Save this initial value
//
AdvancedData->PollingPeriod = dwFifo; } else { //
// value does not exist. Create our own
//
dwData = AdvancedData->PollingPeriod; dwSize = sizeof(dwData); dwError = RegSetValueEx(hDeviceKey, m_szPollingPeriod, 0, REG_DWORD, (LPBYTE)(&dwData), dwSize); }
RegCloseKey(hDeviceKey);
if (ERROR_SUCCESS != dwError) { return dwError; } else { return ERROR_SUCCESS; } } /* FillAdvancedDlg*/
void ChangeParentTitle( IN HWND Hwnd, IN LPCTSTR OldComName, IN LPCTSTR NewComName ) { INT textLength, offset, newNameLen, oldNameLen; PTCHAR oldTitle = NULL, newTitle = NULL; PTCHAR oldLocation;
textLength = GetWindowTextLength(Hwnd); if (textLength == 0) { return; }
//
// Account for null char and unicode
//
textLength++; oldTitle = (PTCHAR) LocalAlloc(LPTR, textLength * sizeof(TCHAR)); if (!oldTitle) { return; }
if (!GetWindowText(Hwnd, oldTitle, textLength)) { goto exit; }
oldLocation = wcsstr(oldTitle, OldComName); if (!oldLocation) { goto exit; }
newNameLen = lstrlen(NewComName); oldNameLen = lstrlen(OldComName); offset = newNameLen - oldNameLen; if (offset > 0) { textLength += offset; } newTitle = (PTCHAR) LocalAlloc(LPTR, textLength * sizeof(TCHAR)); if (!newTitle) { goto exit; }
//
// Find the OldComName in the title and do the following
// 1) up to that location in the string
// 2) copy the new name
// 3) copy the remainder of the string after OldComName
//
offset = (INT)(oldLocation - oldTitle); CopyMemory(newTitle, oldTitle, offset * sizeof(TCHAR)); // 1
CopyMemory(newTitle + offset, NewComName, newNameLen * sizeof(TCHAR)); // 2
lstrcpy(newTitle + offset + newNameLen, oldLocation + oldNameLen); // 3
SetWindowText(Hwnd, newTitle);
exit: if (oldTitle) { LocalFree(oldTitle); } if (newTitle) { LocalFree(newTitle); } }
void MigratePortSettings( LPCTSTR OldComName, LPCTSTR NewComName ) { TCHAR settings[BUFFER_SIZE]; TCHAR szNew[20], szOld[20];
lstrcpy(szOld, OldComName); wcscat(szOld, m_szColon);
lstrcpy(szNew, NewComName); wcscat(szNew, m_szColon);
settings[0] = TEXT('\0'); GetProfileString(m_szPorts, szOld, TEXT(""), settings, sizeof(settings) / sizeof(TCHAR) );
//
// Insert the new key based on the old one
//
if (settings[0] == TEXT('\0')) { WriteProfileString(m_szPorts, szNew, m_szDefParams); } else { WriteProfileString(m_szPorts, szNew, settings); }
//
// Notify everybody of the changes and blow away the old key
//
SendWinIniChange((LPTSTR)m_szPorts); WriteProfileString(m_szPorts, szOld, NULL); }
void EnactComNameChanges( IN HWND ParentHwnd, IN PADVANCED_DATA AdvancedData, IN HKEY hDeviceKey, IN UINT NewComNum) { DWORD dwNewComNameLen; TCHAR buffer[BUFFER_SIZE]; TCHAR szFriendlyNameFormat[LINE_LEN]; TCHAR szDeviceDesc[LINE_LEN]; PTCHAR szNewComName; UINT i; UINT curComNum; BOOLEAN updateMapping = TRUE;
SP_DEVINSTALL_PARAMS spDevInstall;
curComNum = myatoi(AdvancedData->szComName + wcslen(m_szCOM));
if (AdvancedData->hComDB != HCOMDB_INVALID_HANDLE_VALUE) { BYTE portUsage[MAX_COM_PORT/8]; DWORD portsReported; char mask;
//
// Check to see if the desired new COM number has been claimed in the
// com name database. If so, ask the user if they are *really* sure
//
ComDBGetCurrentPortUsage(AdvancedData->hComDB, portUsage, MAX_COM_PORT / 8, CDB_REPORT_BITS, &portsReported);
if ((i = NewComNum % 8)) mask = 1 << (i-1); else mask = (char) 0x80; if ((portUsage[(NewComNum-1)/8] & mask) && MyMessageBox(ParentHwnd, IDS_PORT_IN_USE, IDS_NAME_PROPERTIES, MB_YESNO | MB_ICONINFORMATION) == IDNO) { //
// Port has been previously claimed and user doesn't want to override
//
return; } }
if (!QueryDosDevice(AdvancedData->szComName, buffer, BUFFER_SIZE-1)) { //
// The old com name does not exist in the mapping. Basically, the symbolic
// link from COMX => \Device\SerialY has been broken. Just change the
// value in the registry and the friendly name for the device; don't
// change the dos symbolic name b/c one does not exist
//
updateMapping = FALSE; } else { TCHAR szComFileName[20]; // more than enough for "\\.\COMXxxx"
HANDLE hCom;
lstrcpy(szComFileName, L"\\\\.\\"); lstrcat(szComFileName, AdvancedData->szComName);
//
// Make sure that the port has not been opened by another application
//
hCom = CreateFile(szComFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
//
// If the file handle is invalid, then the com port is open, warn the user
//
if (hCom == INVALID_HANDLE_VALUE && MyMessageBox(ParentHwnd, IDS_PORT_OPEN, IDS_NAME_PROPERTIES, MB_YESNO | MB_ICONERROR) == IDNO) { return; }
if (hCom != INVALID_HANDLE_VALUE) { CloseHandle(hCom); } }
szNewComName = AdvancedData->szNewComName; wsprintf(szNewComName, _T("COM%d"), NewComNum); dwNewComNameLen = ByteCountOf(wcslen(szNewComName) + 1);
//
// Change the name in the symbolic namespace.
// First try to get what device the old com name mapped to
// (ie something like \Device\Serial0). Then remove the mapping. If
// the user isn't an admin, then this will fail and the dialog will popup.
// Finally, map the new name to the old device retrieved from the
// QueryDosDevice
//
if (updateMapping) { BOOL removed; HKEY hSerialMap;
if (!QueryDosDevice(AdvancedData->szComName, buffer, BUFFER_SIZE-1)) { //
// This shouldn't happen because the previous QueryDosDevice call
// succeeded
//
MyMessageBox(ParentHwnd, IDS_PORT_RENAME_ERROR, IDS_NAME_PROPERTIES, MB_ICONERROR); return; }
//
// If this fails, then the following define will just replace the current
// mapping.
//
removed = DefineDosDevice(DDD_REMOVE_DEFINITION, AdvancedData->szComName, NULL);
if (!DefineDosDevice(DDD_RAW_TARGET_PATH, szNewComName, buffer)) { //
// error, first fix up the remove definition and restore the old
// mapping
//
if (removed) { DefineDosDevice(DDD_RAW_TARGET_PATH, AdvancedData->szComName, buffer); }
MyMessageBox(ParentHwnd, IDS_PORT_RENAME_ERROR, IDS_NAME_PROPERTIES, MB_ICONERROR);
return; }
//
// Set the \\HARDWARE\DEVICEMAP\SERIALCOMM field
//
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_szRegSerialMap, 0, KEY_ALL_ACCESS, &hSerialMap) == ERROR_SUCCESS) {
TCHAR szSerial[BUFFER_SIZE]; DWORD dwSerialSize, dwEnum, dwType, dwComSize; TCHAR szCom[BUFFER_SIZE];
i = 0; do { dwSerialSize = CharSizeOf(szSerial); dwComSize = sizeof(szCom); dwEnum = RegEnumValue(hSerialMap, i++, szSerial, &dwSerialSize, NULL, &dwType, (LPBYTE)szCom, &dwComSize);
if (dwEnum == ERROR_SUCCESS) { if(dwType != REG_SZ) continue;
if (wcscmp(szCom, AdvancedData->szComName) == 0) { RegSetValueEx(hSerialMap, szSerial, 0, REG_SZ, (PBYTE) szNewComName, dwNewComNameLen); break; } } } while (dwEnum == ERROR_SUCCESS); }
RegCloseKey(hSerialMap); }
//
// Update the com db
//
if (AdvancedData->hComDB != HCOMDB_INVALID_HANDLE_VALUE) { ComDBReleasePort(AdvancedData->hComDB, (DWORD) curComNum);
ComDBClaimPort(AdvancedData->hComDB, (DWORD) NewComNum, TRUE, NULL); }
//
// Set the friendly name in the form of DeviceDesc (COM#)
//
if (LoadString(g_hInst, IDS_FRIENDLY_FORMAT, szFriendlyNameFormat, CharSizeOf(szFriendlyNameFormat)) && SetupDiGetDeviceRegistryProperty(AdvancedData->DeviceInfoSet, AdvancedData->DeviceInfoData, SPDRP_DEVICEDESC, NULL, (PBYTE) szDeviceDesc, sizeof(szDeviceDesc), NULL)) { wsprintf(buffer, szFriendlyNameFormat, szDeviceDesc, szNewComName); } else { //
// Use the COM port name straight out
//
lstrcpy(buffer, szNewComName); }
SetupDiSetDeviceRegistryProperty(AdvancedData->DeviceInfoSet, AdvancedData->DeviceInfoData, SPDRP_FRIENDLYNAME, (PBYTE) buffer, ByteCountOf(wcslen(buffer)+1));
//
// Set the parent dialog's title to reflect the change in the com port's name
//
ChangeParentTitle(GetParent(ParentHwnd), AdvancedData->szComName, szNewComName); MigratePortSettings(AdvancedData->szComName, szNewComName);
//
// Update the PortName value in the devnode
//
RegSetValueEx(hDeviceKey, m_szPortName, 0, REG_SZ, (PBYTE)szNewComName, dwNewComNameLen);
//
// Now broadcast this change to the device manager
//
ZeroMemory(&spDevInstall, sizeof(SP_DEVINSTALL_PARAMS)); spDevInstall.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
if (SetupDiGetDeviceInstallParams(AdvancedData->DeviceInfoSet, AdvancedData->DeviceInfoData, &spDevInstall)) { spDevInstall.Flags |= DI_PROPERTIES_CHANGE; SetupDiSetDeviceInstallParams(AdvancedData->DeviceInfoSet, AdvancedData->DeviceInfoData, &spDevInstall); } }
/*++
Routine Description: SaveAdvancedSettings
saves the advanced box settings back to the registry, if any were changed
Arguments:
AdvancedData: holds the current settings and the location of of the device in the registry ParentHwnd: address of the window
Return Value:
ULONG: returns error messages
--*/ ULONG SaveAdvancedSettings( IN HWND ParentHwnd, IN PADVANCED_DATA AdvancedData ) { HKEY hDeviceKey; DWORD dwSize, dwData;
UINT i = CB_ERR, curComNum, newComNum = CB_ERR; UINT uiDlgButtonChecked; DWORD dwRxPosition, dwTxPosition, dwPollingPeriod;
SP_DEVINSTALL_PARAMS spDevInstall;
//
// Grab all of the new settings
//
uiDlgButtonChecked = IsDlgButtonChecked(ParentHwnd, IDC_FIFO);
dwTxPosition = Trackbar_GetPos(GetDlgItem(ParentHwnd, IDC_TRANSMIT_SLIDER)); dwRxPosition = Trackbar_GetPos(GetDlgItem(ParentHwnd, IDC_RECEIVE_SLIDER));
//
// Index is actually into the array of values
//
dwRxPosition = RxValues[dwRxPosition-1];
curComNum = myatoi(AdvancedData->szComName + wcslen(m_szCOM)); newComNum = ComboBox_GetCurSel(GetDlgItem(ParentHwnd, PP_PORT_NUMBER));
if (newComNum == CB_ERR) { newComNum = curComNum; } else { newComNum++; }
i = ComboBox_GetCurSel(GetDlgItem(ParentHwnd, IDC_POLL_PERIOD));
if (i == CB_ERR || i >= NUM_POLLING_PERIODS) { dwPollingPeriod = AdvancedData->PollingPeriod; } else { dwPollingPeriod = PollingPeriods[i]; }
//
// See if they changed anything
//
if (((AdvancedData->UseFifoBuffers && uiDlgButtonChecked == BST_CHECKED) || (!AdvancedData->UseFifoBuffers && uiDlgButtonChecked == BST_UNCHECKED)) && AdvancedData->RxFIFO == dwRxPosition && AdvancedData->TxFIFO == dwTxPosition && AdvancedData->PollingPeriod == dwPollingPeriod && newComNum == curComNum) { //
// They didn't change anything. Just exit.
//
return ERROR_SUCCESS; }
//
// Open the device key for the source device instance
//
hDeviceKey = SetupDiOpenDevRegKey(AdvancedData->DeviceInfoSet, AdvancedData->DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_ALL_ACCESS);
if (INVALID_HANDLE_VALUE == hDeviceKey) { //
// Not much we can do without a valid key, exit gracefully
//
return ERROR_SUCCESS; }
//
// Check to see if the user changed the COM port name
//
if (newComNum != curComNum) { EnactComNameChanges(ParentHwnd, AdvancedData, hDeviceKey, newComNum); }
if ((AdvancedData->UseFifoBuffers && uiDlgButtonChecked == BST_UNCHECKED) || (!AdvancedData->UseFifoBuffers && uiDlgButtonChecked == BST_CHECKED)) { //
// They changed the Use Fifo checkbox.
//
dwData = (uiDlgButtonChecked == BST_CHECKED) ? 1 : 0; dwSize = sizeof(dwData); RegSetValueEx(hDeviceKey, m_szFIFO, 0, REG_DWORD, (CONST BYTE *)(&dwData), dwSize); }
if (AdvancedData->RxFIFO != dwRxPosition) { //
// They changed the RxFIFO setting
//
dwData = dwRxPosition; dwSize = sizeof(dwData); RegSetValueEx(hDeviceKey, m_szRxFIFO, 0, REG_DWORD, (CONST BYTE *)(&dwData), dwSize); }
if (AdvancedData->TxFIFO != dwTxPosition) { //
// They changed the TxFIFO setting
//
dwData = dwTxPosition; dwSize = sizeof(dwData); RegSetValueEx(hDeviceKey, m_szTxFIFO, 0, REG_DWORD, (CONST BYTE *)(&dwData), dwSize); }
if (AdvancedData->PollingPeriod != dwPollingPeriod) { //
// They changed the polling period
//
dwData = dwPollingPeriod; dwSize = sizeof(dwData); RegSetValueEx(hDeviceKey, m_szPollingPeriod, 0, REG_DWORD, (CONST BYTE *)(&dwData), dwSize);
//
// Don't really care if this fails, nothing else we can do
//
CM_Reenumerate_DevNode(AdvancedData->DeviceInfoData->DevInst, CM_REENUMERATE_NORMAL); }
RegCloseKey(hDeviceKey);
SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, AdvancedData->DeviceInfoSet, AdvancedData->DeviceInfoData);
return ERROR_SUCCESS; } /* SaveAdvancedSettings*/
|