|
|
#include "setupp.h"
#pragma hdrstop
#include <windowsx.h>
//
// PAGE_INFO and related Prototypes
//
typedef struct _PAGE_INFO { HDEVINFO deviceInfoSet; PSP_DEVINFO_DATA deviceInfoData;
HKEY hKeyDev;
DWORD enableWheelDetect; DWORD sampleRate; DWORD bufferLength; DWORD mouseInitPolled; } PAGE_INFO, * PPAGE_INFO;
PPAGE_INFO PS2Mouse_CreatePageInfo( IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData );
void PS2Mouse_DestroyPageInfo( PPAGE_INFO PageInfo );
//
// Function Prototypes
//
HPROPSHEETPAGE PS2Mouse_CreatePropertyPage( PROPSHEETPAGE * PropSheetPage, PPAGE_INFO PageInfo );
UINT CALLBACK PS2Mouse_PropPageCallback( HWND Hwnd, UINT Message, LPPROPSHEETPAGE PropSheetPage );
INT_PTR APIENTRY PS2Mouse_DlgProc( IN HWND hDlg, IN UINT uMessage, IN WPARAM wParam, IN LPARAM lParam );
void PS2Mouse_InitializeControls( HWND ParentHwnd, PPAGE_INFO PageInfo );
void PS2Mouse_OnCommand( HWND ParentHwnd, int ControlId, HWND ControlHwnd, UINT NotifyCode );
BOOL PS2Mouse_OnContextMenu( HWND HwndControl, WORD Xpos, WORD Ypos );
INT_PTR PS2Mouse_OnCtlColorStatic( HDC DC, HWND Hwnd );
void PS2Mouse_OnHelp( HWND ParentHwnd, LPHELPINFO HelpInfo );
BOOL PS2Mouse_OnInitDialog( HWND ParentHwnd, HWND FocusHwnd, LPARAM Lparam );
BOOL PS2Mouse_OnNotify( HWND ParentHwnd, LPNMHDR NmHdr );
//
// Message macros for up down controls
//
#define UpDown_SetRange(hwndUD, nLower, nUpper) \
(VOID) SendMessage((hwndUD), UDM_SETRANGE, (WPARAM) 0, \ (LPARAM) MAKELONG((short) (nUpper), (short) (nLower)) )
#define UpDown_GetPos(hwndUD) \
(DWORD) SendMessage((hwndUD), UDM_GETPOS, (WPARAM) 0, (LPARAM) 0)
#define UpDown_SetPos(hwndUD, nPos) \
(short) SendMessage((hwndUD), UDM_SETPOS, (WPARAM) 0, \ (LPARAM) MAKELONG((short) (nPos), 0) )
#define UpDown_SetAccel(hwndUD, nCount, pAccels) \
(BOOL) SendMessage((hwndUD), UDM_SETACCEL, (WPARAM) nCount, \ (LPARAM) pAccels)
//
// Constants and strings
//
#define MOUSE_INIT_POLLED_DEFAULT 0
#define MAX_DETECTION_TYPES 3
#define WHEEL_DETECT_DEFAULT 2 // Default is now 2 for Beta3 /* 1 */
#define DATA_QUEUE_MIN 100
#define DATA_QUEUE_MAX 300
#define DATA_QUEUE_DEFAULT 100
#define SAMPLE_RATE_DEFAULT 100
const DWORD PS2Mouse_SampleRates[] = { 20, 40, 60, 80, 100, 200 };
#define MAX_SAMPLE_RATES (sizeof(PS2Mouse_SampleRates)/sizeof(PS2Mouse_SampleRates[0]))
#define IDH_DEVMGR_MOUSE_ADVANCED_RATE 2002100
#define IDH_DEVMGR_MOUSE_ADVANCED_DETECT 2002110
#define IDH_DEVMGR_MOUSE_ADVANCED_BUFFER 2002120
#define IDH_DEVMGR_MOUSE_ADVANCED_INIT 2002130
#define IDH_DEVMGR_MOUSE_ADVANCED_DEFAULT 2002140
const DWORD PS2Mouse_HelpIDs[] = { IDC_SAMPLE_RATE, IDH_DEVMGR_MOUSE_ADVANCED_RATE, IDC_WHEEL_DETECTION, IDH_DEVMGR_MOUSE_ADVANCED_DETECT, IDC_BUFFER, IDH_DEVMGR_MOUSE_ADVANCED_BUFFER, IDC_BUFFER_SPIN, IDH_DEVMGR_MOUSE_ADVANCED_BUFFER, IDC_FAST_INIT, IDH_DEVMGR_MOUSE_ADVANCED_INIT, IDC_DEFAULT, IDH_DEVMGR_MOUSE_ADVANCED_DEFAULT, 0, 0 };
TCHAR szDevMgrHelp[] = L"devmgr.hlp";
TCHAR szMouseDataQueueSize[] = L"MouseDataQueueSize"; TCHAR szSampleRate[] = L"SampleRate"; TCHAR szEnableWheelDetection[] = L"EnableWheelDetection"; TCHAR szMouseInitializePolled[] = L"MouseInitializePolled"; TCHAR szDisablePolledUI[] = L"DisableInitializePolledUI";
PPAGE_INFO PS2Mouse_CreatePageInfo( IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData) { PPAGE_INFO tmp = (PPAGE_INFO) MyMalloc(sizeof(PAGE_INFO));
if (!tmp) { return NULL; }
tmp->deviceInfoSet = DeviceInfoSet; tmp->deviceInfoData = DeviceInfoData;
tmp->hKeyDev = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_ALL_ACCESS);
return tmp; }
void PS2Mouse_DestroyPageInfo( PPAGE_INFO PageInfo ) { if (PageInfo->hKeyDev != (HKEY) INVALID_HANDLE_VALUE) { RegCloseKey(PageInfo->hKeyDev); }
MyFree(PageInfo); }
HPROPSHEETPAGE PS2Mouse_CreatePropertyPage( PROPSHEETPAGE * PropSheetPage, PPAGE_INFO PageInfo ) { //
// Add the Port Settings property page
//
PropSheetPage->dwSize = sizeof(PROPSHEETPAGE); PropSheetPage->dwFlags = PSP_USECALLBACK; // | PSP_HASHELP;
PropSheetPage->hInstance = MyModuleHandle; PropSheetPage->pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_PS2_MOUSE);
//
// following points to the dlg window proc
//
PropSheetPage->pfnDlgProc = PS2Mouse_DlgProc; PropSheetPage->lParam = (LPARAM) PageInfo;
//
// Following points to the control callback of the dlg window proc.
// The callback gets called before creation/after destruction of the page
//
PropSheetPage->pfnCallback = PS2Mouse_PropPageCallback;
//
// Allocate the actual page
//
return CreatePropertySheetPage(PropSheetPage); }
BOOL APIENTRY PS2MousePropPageProvider( LPVOID Info, LPFNADDPROPSHEETPAGE AddFunction, LPARAM Lparam) { PSP_PROPSHEETPAGE_REQUEST ppr; PROPSHEETPAGE psp; HPROPSHEETPAGE hpsp; PPAGE_INFO ppi = NULL; ULONG devStatus, devProblem; CONFIGRET cr;
ppr = (PSP_PROPSHEETPAGE_REQUEST) Info;
if (ppr->PageRequested == SPPSR_ENUM_ADV_DEVICE_PROPERTIES) { ppi = PS2Mouse_CreatePageInfo(ppr->DeviceInfoSet, ppr->DeviceInfoData);
if (!ppi) { return FALSE; }
//
// If this fails, it is most likely that the user does not have
// write access to the devices key/subkeys in the registry.
// If you only want to read the settings, then change KEY_ALL_ACCESS
// to KEY_READ in CreatePageInfo.
//
// Administrators usually have access to these reg keys....
//
if (ppi->hKeyDev == (HKEY) INVALID_HANDLE_VALUE) { PS2Mouse_DestroyPageInfo(ppi); return FALSE; }
//
// Retrieve the status of this device instance.
//
cr = CM_Get_DevNode_Status(&devStatus, &devProblem, ppr->DeviceInfoData->DevInst, 0); if ((cr == CR_SUCCESS) && (devStatus & DN_HAS_PROBLEM) && (devProblem & CM_PROB_DISABLED_SERVICE)) { //
// If the controlling service has been disabled, do not show any
// additional property pages.
//
return FALSE; }
hpsp = PS2Mouse_CreatePropertyPage(&psp, ppi);
if (!hpsp) { return FALSE; }
if (!AddFunction(hpsp, Lparam)) { DestroyPropertySheetPage(hpsp); return FALSE; } }
return TRUE; }
UINT CALLBACK PS2Mouse_PropPageCallback( HWND Hwnd, UINT Message, LPPROPSHEETPAGE PropSheetPage ) { PPAGE_INFO ppi;
switch (Message) { case PSPCB_CREATE: return TRUE; // return TRUE to continue with creation of page
case PSPCB_RELEASE: ppi = (PPAGE_INFO) PropSheetPage->lParam; PS2Mouse_DestroyPageInfo(ppi);
return 0; // return value ignored
default: break; }
return TRUE; }
INT_PTR APIENTRY PS2Mouse_DlgProc( IN HWND hDlg, IN UINT uMessage, IN WPARAM wParam, IN LPARAM lParam ) { switch(uMessage) { case WM_COMMAND: PS2Mouse_OnCommand(hDlg, (int) LOWORD(wParam), (HWND)lParam, (UINT)HIWORD(wParam)); break;
case WM_CONTEXTMENU: return PS2Mouse_OnContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
case WM_HELP: PS2Mouse_OnHelp(hDlg, (LPHELPINFO) lParam); break;
case WM_CTLCOLORSTATIC: return PS2Mouse_OnCtlColorStatic((HDC) wParam, (HWND) lParam);
case WM_INITDIALOG: return PS2Mouse_OnInitDialog(hDlg, (HWND)wParam, lParam);
case WM_NOTIFY: return PS2Mouse_OnNotify(hDlg, (NMHDR *)lParam); }
return FALSE; }
DWORD PS2Mouse_GetSampleRateIndex( DWORD SampleRate ) { ULONG i;
for (i = 0; i < MAX_SAMPLE_RATES; i++) { if (PS2Mouse_SampleRates[i] == SampleRate) { return i; } }
return 0; }
void PS2Mouse_OnDefault( HWND ParentHwnd, PPAGE_INFO PageInfo ) { UpDown_SetPos(GetDlgItem(ParentHwnd, IDC_BUFFER_SPIN), DATA_QUEUE_DEFAULT); ComboBox_SetCurSel(GetDlgItem(ParentHwnd, IDC_SAMPLE_RATE), PS2Mouse_GetSampleRateIndex(SAMPLE_RATE_DEFAULT)); ComboBox_SetCurSel(GetDlgItem(ParentHwnd, IDC_WHEEL_DETECTION), WHEEL_DETECT_DEFAULT); Button_SetCheck(GetDlgItem(ParentHwnd, IDC_FAST_INIT), !MOUSE_INIT_POLLED_DEFAULT);
PropSheet_Changed(GetParent(ParentHwnd), ParentHwnd); }
void PS2Mouse_OnCommand( HWND ParentHwnd, int ControlId, HWND ControlHwnd, UINT NotifyCode ) { PPAGE_INFO pageInfo = (PPAGE_INFO) GetWindowLongPtr(ParentHwnd, DWLP_USER);
if (NotifyCode == CBN_SELCHANGE) { PropSheet_Changed(GetParent(ParentHwnd), ParentHwnd); } else { switch (ControlId) { case IDC_DEFAULT: PS2Mouse_OnDefault(ParentHwnd, pageInfo); break;
case IDC_FAST_INIT: PropSheet_Changed(GetParent(ParentHwnd), ParentHwnd); break; } } }
BOOL PS2Mouse_OnContextMenu( HWND HwndControl, WORD Xpos, WORD Ypos ) { WinHelp(HwndControl, szDevMgrHelp, HELP_CONTEXTMENU, (ULONG_PTR) PS2Mouse_HelpIDs);
return FALSE; }
INT_PTR PS2Mouse_OnCtlColorStatic( HDC DC, HWND HStatic ) { UINT id = GetDlgCtrlID(HStatic);
//
// WM_CTLCOLORSTATIC is sent for the edit controls because they are read
// only
//
if (id == IDC_BUFFER) { SetBkColor(DC, GetSysColor(COLOR_WINDOW)); return (INT_PTR) GetSysColorBrush(COLOR_WINDOW); }
return FALSE; }
void PS2Mouse_OnHelp( HWND ParentHwnd, LPHELPINFO HelpInfo ) { if (HelpInfo->iContextType == HELPINFO_WINDOW) { WinHelp((HWND) HelpInfo->hItemHandle, szDevMgrHelp, HELP_WM_HELP, (ULONG_PTR) PS2Mouse_HelpIDs); } }
BOOL PS2Mouse_OnInitDialog( HWND ParentHwnd, HWND FocusHwnd, LPARAM Lparam ) { PPAGE_INFO pageInfo = (PPAGE_INFO) GetWindowLongPtr(ParentHwnd, DWLP_USER);
pageInfo = (PPAGE_INFO) ((LPPROPSHEETPAGE)Lparam)->lParam; SetWindowLongPtr(ParentHwnd, DWLP_USER, (ULONG_PTR) pageInfo);
PS2Mouse_InitializeControls(ParentHwnd, pageInfo);
return TRUE; }
void PS2Mouse_OnApply( HWND ParentHwnd, PPAGE_INFO PageInfo ) { DWORD uiEnableWheelDetect, uiSampleRate, uiBufferLength, uiMouseInitPolled; int iSel; BOOL reboot = FALSE;
uiEnableWheelDetect = ComboBox_GetCurSel(GetDlgItem(ParentHwnd, IDC_WHEEL_DETECTION)); uiBufferLength = UpDown_GetPos(GetDlgItem(ParentHwnd, IDC_BUFFER_SPIN)); uiMouseInitPolled = !Button_GetCheck(GetDlgItem(ParentHwnd, IDC_FAST_INIT));
//
// Must index the array as opposed to getting a real value
//
iSel = ComboBox_GetCurSel(GetDlgItem(ParentHwnd, IDC_SAMPLE_RATE)); if (iSel == CB_ERR) { uiSampleRate = PageInfo->sampleRate; } else { uiSampleRate = PS2Mouse_SampleRates[iSel]; }
//
// See if anything has changed
//
if (uiEnableWheelDetect != PageInfo->enableWheelDetect) { RegSetValueEx(PageInfo->hKeyDev, szEnableWheelDetection, 0, REG_DWORD, (PBYTE) &uiEnableWheelDetect, sizeof(DWORD)); reboot = TRUE; }
if (uiSampleRate != PageInfo->sampleRate) { RegSetValueEx(PageInfo->hKeyDev, szSampleRate, 0, REG_DWORD, (PBYTE) &uiSampleRate, sizeof(DWORD)); reboot = TRUE; }
if (uiBufferLength != PageInfo->bufferLength) { RegSetValueEx(PageInfo->hKeyDev, szMouseDataQueueSize, 0, REG_DWORD, (PBYTE) &uiBufferLength, sizeof(DWORD)); reboot = TRUE; }
if (uiMouseInitPolled) { //
// make sure if it is nonzero that it is 1
//
uiMouseInitPolled = 1; }
if (uiMouseInitPolled != PageInfo->mouseInitPolled) { RegSetValueEx(PageInfo->hKeyDev, szMouseInitializePolled, 0, REG_DWORD, (PBYTE) &uiMouseInitPolled, sizeof(DWORD)); reboot = TRUE; }
if (reboot) { SP_DEVINSTALL_PARAMS dip;
ZeroMemory(&dip, sizeof(dip)); dip.cbSize = sizeof(dip);
SetupDiGetDeviceInstallParams(PageInfo->deviceInfoSet, PageInfo->deviceInfoData, &dip);
dip.Flags |= DI_NEEDREBOOT;
SetupDiSetDeviceInstallParams(PageInfo->deviceInfoSet, PageInfo->deviceInfoData, &dip); } }
BOOL PS2Mouse_OnNotify( HWND ParentHwnd, LPNMHDR NmHdr ) { PPAGE_INFO pageInfo = (PPAGE_INFO) GetWindowLongPtr(ParentHwnd, DWLP_USER);
switch (NmHdr->code) {
//
// The user is about to change an up down control
//
case UDN_DELTAPOS: PropSheet_Changed(GetParent(ParentHwnd), ParentHwnd); return FALSE;
//
// Sent when the user clicks on Apply OR OK !!
//
case PSN_APPLY: //
// Write out the com port options to the registry
//
PS2Mouse_OnApply(ParentHwnd, pageInfo); SetWindowLongPtr(ParentHwnd, DWLP_MSGRESULT, PSNRET_NOERROR); return TRUE;
default: return FALSE; } }
DWORD PS2Mouse_SetupSpinner( HKEY Hkey, HWND SpinnerHwnd, TCHAR ValueName[], short MinVal, short MaxVal, short DefaultVal, short IncrementVal ) { DWORD dwValue, dwSize; UDACCEL accel;
UpDown_SetRange(SpinnerHwnd, MinVal, MaxVal); dwSize = sizeof(DWORD); if (RegQueryValueEx(Hkey, ValueName, 0, NULL, (PBYTE) &dwValue, &dwSize) != ERROR_SUCCESS) { dwValue = DefaultVal; } if (((short) dwValue) < MinVal || ((short) dwValue) > MaxVal) { dwValue = DefaultVal; }
if (dwValue % IncrementVal) { //
// Set the value to a good one and return the one we took out of the
// registry. When the user applies the changes the value in the control
// will be different and we will write the value out
//
UpDown_SetPos(SpinnerHwnd, dwValue - (dwValue % IncrementVal)); } else { UpDown_SetPos(SpinnerHwnd, dwValue); }
accel.nSec = 0; accel.nInc = IncrementVal; UpDown_SetAccel(SpinnerHwnd, 1, &accel);
return dwValue; }
DWORD PS2Mouse_SetupSampleRate( HWND ComboBoxHwnd, HKEY Hkey ) { int i; DWORD dwValue, dwSize; BOOL badValue = FALSE; TCHAR szValue[32];
//
// First setup the cb, then find the correct selection
//
for (i = 0; i < MAX_SAMPLE_RATES; i++) { wsprintf(szValue, TEXT("%d"), PS2Mouse_SampleRates[i]); ComboBox_AddString(ComboBoxHwnd, szValue); }
//
// Get the value out of the registry. If it not what we expect or it is not
// there, then make sure when the user clicks OK, the values are written out
//
dwSize = sizeof(DWORD); if (RegQueryValueEx(Hkey, szSampleRate, 0, NULL, (PBYTE) &dwValue, &dwSize) != ERROR_SUCCESS) { dwValue = SAMPLE_RATE_DEFAULT; badValue = TRUE; }
//
// Assume the value is wrong
//
badValue = TRUE; for (i = 0; i < MAX_SAMPLE_RATES; i++) { if (PS2Mouse_SampleRates[i] == dwValue) { badValue = FALSE; break; } }
if (badValue) { dwValue = SAMPLE_RATE_DEFAULT; }
ComboBox_SetCurSel(ComboBoxHwnd, PS2Mouse_GetSampleRateIndex(dwValue));
if (badValue) { return 0xffffffff; } else { return dwValue; } }
DWORD PS2Mouse_SetupWheelDetection( HWND ComboBoxHwnd, HKEY Hkey ) { int i; DWORD dwValue, dwSize; BOOL badValue = FALSE; TCHAR szDescription[80]; UINT stringIDs[MAX_DETECTION_TYPES] = { IDS_PS2_DETECTION_DISABLED, IDS_PS2_DETECTION_LOOK, IDS_PS2_DETECTION_ASSUME_PRESENT };
//
// First setup the cb, then find the correct selection
//
for (i = 0; i < MAX_DETECTION_TYPES; i++) { LoadString(MyModuleHandle, stringIDs[i], szDescription, sizeof(szDescription) / sizeof(TCHAR)); ComboBox_AddString(ComboBoxHwnd, szDescription); }
//
// Get the value out of the registry. If it not what we expect or it is not
// there, then make sure when the user clicks OK, the values are written out
//
dwSize = sizeof(DWORD); if (RegQueryValueEx(Hkey, szEnableWheelDetection, 0, NULL, (PBYTE) &dwValue, &dwSize) != ERROR_SUCCESS) { dwValue = WHEEL_DETECT_DEFAULT; badValue = TRUE; }
if (dwValue > 2) { dwValue = WHEEL_DETECT_DEFAULT; badValue = TRUE; }
ComboBox_SetCurSel(ComboBoxHwnd, dwValue);
if (badValue) { return 0xffffffff; } else { return dwValue; } }
ULONG PSMouse_SetupFastInit( HWND CheckBoxHwnd, HKEY Hkey ) { DWORD dwSize, dwValue, dwDisable = FALSE; BOOL badValue = FALSE;
//
// Get the value out of the registry. If it not what we expect or it is not
// there, then make sure when the user clicks OK, the values are written out
//
dwSize = sizeof(DWORD); if (RegQueryValueEx(Hkey, szMouseInitializePolled, 0, NULL, (PBYTE) &dwValue, &dwSize) != ERROR_SUCCESS) { dwValue = MOUSE_INIT_POLLED_DEFAULT; badValue = TRUE; }
//
// Make sure the value is 1 or 0. If it is nonzero and not 1, it is assumed
// to be 1
//
if (dwValue != 0 && dwValue != 1) { dwValue = 1; badValue = TRUE; }
//
// This is a bit confusing. The UI has fast initialization, but underneath
// it is represented as initialize polled which is fast when it is false,
// but we must show true to the user
//
Button_SetCheck(CheckBoxHwnd, !dwValue);
dwSize = sizeof(DWORD); if (RegQueryValueEx(Hkey, szDisablePolledUI, 0, NULL, (PBYTE) &dwDisable, &dwSize) == ERROR_SUCCESS && dwDisable != FALSE) { EnableWindow(CheckBoxHwnd, FALSE); }
if (badValue) { return -1; } else { return dwValue; } }
void PS2Mouse_InitializeControls( HWND ParentHwnd, PPAGE_INFO PageInfo ) { HKEY hKey; HWND hwnd; DWORD dwValue, dwSize; int i;
if (PageInfo->hKeyDev == (HKEY) INVALID_HANDLE_VALUE) { //
// Disable all of the controls
//
return; }
PageInfo->bufferLength = PS2Mouse_SetupSpinner(PageInfo->hKeyDev, GetDlgItem(ParentHwnd, IDC_BUFFER_SPIN), szMouseDataQueueSize, DATA_QUEUE_MIN, DATA_QUEUE_MAX, DATA_QUEUE_DEFAULT, 10);
PageInfo->sampleRate = PS2Mouse_SetupSampleRate(GetDlgItem(ParentHwnd, IDC_SAMPLE_RATE), PageInfo->hKeyDev);
PageInfo->enableWheelDetect = PS2Mouse_SetupWheelDetection(GetDlgItem(ParentHwnd, IDC_WHEEL_DETECTION), PageInfo->hKeyDev);
PageInfo->mouseInitPolled = PSMouse_SetupFastInit(GetDlgItem(ParentHwnd, IDC_FAST_INIT), PageInfo->hKeyDev); }
|