Revert "[SHELL32] SHChangeNotify: Use tree for CDirectoryList (#6784)" (#6800)
[reactos.git] / dll / win32 / syssetup / proppage.c
1 /*
2 * PROJECT: ReactOS system libraries
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/syssetup/proppage.c
5 * PURPOSE: Property page providers
6 * PROGRAMMERS: Copyright 2018 Eric Kohl <eric.kohl@reactos.org>
7 */
8
9 #include "precomp.h"
10
11 #define NDEBUG
12 #include <debug.h>
13
14 typedef struct _MOUSE_INFO
15 {
16 HKEY hDeviceKey;
17 DWORD dwSampleRateIndex;
18 DWORD dwWheelDetection;
19 DWORD dwInputBufferLength;
20 DWORD dwInitPolled;
21 } MOUSE_INFO, *PMOUSE_INFO;
22
23 DWORD MouseSampleRates[] = {20, 40, 60, 80, 100, 200};
24
25 #define DEFAULT_SAMPLERATEINDEX 4
26 #define DEFAULT_WHEELDETECTION 2
27 #define DEFAULT_INPUTBUFFERSIZE 100
28 #define DEFAULT_MINBUFFERSIZE 100
29 #define DEFAULT_MAXBUFFERSIZE 300
30
31 /*
32 * @implemented
33 */
34 BOOL
35 WINAPI
36 CdromPropPageProvider(
37 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
38 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
39 _In_ LPARAM lParam)
40 {
41 DPRINT("CdromPropPageProvider(%p %p %lx)\n",
42 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
43 return FALSE;
44 }
45
46
47 /*
48 * @implemented
49 */
50 BOOL
51 WINAPI
52 DiskPropPageProvider(
53 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
54 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
55 _In_ LPARAM lParam)
56 {
57 DPRINT("DiskPropPageProvider(%p %p %lx)\n",
58 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
59 return FALSE;
60 }
61
62
63 /*
64 * @implemented
65 */
66 BOOL
67 WINAPI
68 EisaUpHalPropPageProvider(
69 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
70 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
71 _In_ LPARAM lParam)
72 {
73 DPRINT("EisaUpHalPropPageProvider(%p %p %lx)\n",
74 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
75 return FALSE;
76 }
77
78
79 /*
80 * @unimplemented
81 */
82 BOOL
83 WINAPI
84 LegacyDriverPropPageProvider(
85 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
86 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
87 _In_ LPARAM lParam)
88 {
89 DPRINT1("LegacyDriverPropPageProvider(%p %p %lx)\n",
90 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
91 UNIMPLEMENTED;
92 return FALSE;
93 }
94
95
96 static
97 DWORD
98 MouseGetSampleRateIndex(
99 DWORD dwSampleRate)
100 {
101 DWORD i;
102
103 for (i = 0; i < ARRAYSIZE(MouseSampleRates); i++)
104 {
105 if (MouseSampleRates[i] == dwSampleRate)
106 return i;
107 }
108
109 return DEFAULT_SAMPLERATEINDEX;
110 }
111
112
113 static
114 BOOL
115 MouseOnDialogInit(
116 HWND hwndDlg,
117 LPARAM lParam)
118 {
119 PMOUSE_INFO pMouseInfo;
120 WCHAR szBuffer[64];
121 UINT i;
122 DWORD dwType, dwSize;
123 DWORD dwSampleRate;
124 LONG lError;
125
126 /* Get the pointer to the mouse info struct */
127 pMouseInfo = (PMOUSE_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
128 if (pMouseInfo == NULL)
129 return FALSE;
130
131 /* Keep the pointer to the mouse info struct */
132 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pMouseInfo);
133
134 /* Add the sample rates */
135 for (i = 0; i < ARRAYSIZE(MouseSampleRates); i++)
136 {
137 wsprintf(szBuffer, L"%lu", MouseSampleRates[i]);
138 SendDlgItemMessageW(hwndDlg,
139 IDC_PS2MOUSESAMPLERATE,
140 CB_ADDSTRING,
141 0,
142 (LPARAM)szBuffer);
143 }
144
145 /* Read the SampleRate parameter */
146 dwSize = sizeof(DWORD);
147 lError = RegQueryValueExW(pMouseInfo->hDeviceKey,
148 L"SampleRate",
149 NULL,
150 &dwType,
151 (LPBYTE)&dwSampleRate,
152 &dwSize);
153 if (lError == ERROR_SUCCESS && dwType == REG_DWORD && dwSize == sizeof(DWORD))
154 {
155 pMouseInfo->dwSampleRateIndex = MouseGetSampleRateIndex(dwSampleRate);
156 }
157 else
158 {
159 /* Set the default sample rate (100 samples per second) */
160 pMouseInfo->dwSampleRateIndex = DEFAULT_SAMPLERATEINDEX;
161 }
162
163 /* Set the sample rate */
164 SendDlgItemMessageW(hwndDlg,
165 IDC_PS2MOUSESAMPLERATE,
166 CB_SETCURSEL,
167 pMouseInfo->dwSampleRateIndex,
168 0);
169
170 /* Add the detection options */
171 for (i = IDS_DETECTIONDISABLED; i <= IDS_ASSUMEPRESENT; i++)
172 {
173 LoadStringW(hDllInstance, i, szBuffer, ARRAYSIZE(szBuffer));
174 SendDlgItemMessageW(hwndDlg,
175 IDC_PS2MOUSEWHEEL,
176 CB_ADDSTRING,
177 0,
178 (LPARAM)szBuffer);
179 }
180
181 /* Read the EnableWheelDetection parameter */
182 dwSize = sizeof(DWORD);
183 lError = RegQueryValueExW(pMouseInfo->hDeviceKey,
184 L"EnableWheelDetection",
185 NULL,
186 &dwType,
187 (LPBYTE)&pMouseInfo->dwWheelDetection,
188 &dwSize);
189 if (lError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD))
190 {
191 /* Set the default wheel detection parameter */
192 pMouseInfo->dwWheelDetection = DEFAULT_WHEELDETECTION;
193 }
194
195 /* Set the wheel detection parameter */
196 SendDlgItemMessageW(hwndDlg,
197 IDC_PS2MOUSEWHEEL,
198 CB_SETCURSEL,
199 pMouseInfo->dwWheelDetection,
200 0);
201
202 /* Set the input buffer length range: 100-300 */
203 SendDlgItemMessageW(hwndDlg,
204 IDC_PS2MOUSEINPUTUPDN,
205 UDM_SETRANGE32,
206 DEFAULT_MINBUFFERSIZE,
207 DEFAULT_MAXBUFFERSIZE);
208
209 /* Read the MouseDataQueueSize parameter */
210 dwSize = sizeof(DWORD);
211 lError = RegQueryValueExW(pMouseInfo->hDeviceKey,
212 L"MouseDataQueueSize",
213 NULL,
214 &dwType,
215 (LPBYTE)&pMouseInfo->dwInputBufferLength,
216 &dwSize);
217 if (lError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD))
218 {
219 /* Set the default input buffer length (100 packets) */
220 pMouseInfo->dwInputBufferLength = DEFAULT_INPUTBUFFERSIZE;
221 }
222
223 /* Set the input buffer length */
224 SendDlgItemMessageW(hwndDlg,
225 IDC_PS2MOUSEINPUTUPDN,
226 UDM_SETPOS32,
227 0,
228 pMouseInfo->dwInputBufferLength);
229
230 /* Read the MouseInitializePolled parameter */
231 dwSize = sizeof(DWORD);
232 lError = RegQueryValueExW(pMouseInfo->hDeviceKey,
233 L"MouseInitializePolled",
234 NULL,
235 &dwType,
236 (LPBYTE)&pMouseInfo->dwInitPolled,
237 &dwSize);
238 if (lError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD))
239 {
240 /* Set the default init polled value (FALSE) */
241 pMouseInfo->dwInitPolled = 0;
242 }
243
244 /* Set the fast initialization option */
245 SendDlgItemMessage(hwndDlg,
246 IDC_PS2MOUSEFASTINIT,
247 BM_SETCHECK,
248 (pMouseInfo->dwInitPolled == 0) ? BST_CHECKED : 0,
249 0);
250
251 return TRUE;
252 }
253
254
255 static
256 VOID
257 MouseOnCommand(
258 HWND hwndDlg,
259 WPARAM wParam,
260 LPARAM lParam)
261 {
262 switch (LOWORD(wParam))
263 {
264 case IDC_PS2MOUSESAMPLERATE:
265 case IDC_PS2MOUSEWHEEL:
266 case IDC_PS2MOUSEINPUTLEN:
267 case IDC_PS2MOUSEFASTINIT:
268 if (HIWORD(wParam) == CBN_SELCHANGE ||
269 HIWORD(wParam) == CBN_EDITCHANGE)
270 {
271 /* Enable the Apply button */
272 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
273 }
274 break;
275
276 case IDC_PS2MOUSEDEFAULTS:
277 if (HIWORD(wParam) == BN_CLICKED)
278 {
279 /* Sample rate: 100 */
280 SendDlgItemMessageW(hwndDlg,
281 IDC_PS2MOUSESAMPLERATE,
282 CB_SETCURSEL,
283 DEFAULT_SAMPLERATEINDEX,
284 0);
285
286 /* Wheel detection: Assume wheel present */
287 SendDlgItemMessageW(hwndDlg,
288 IDC_PS2MOUSEWHEEL,
289 CB_SETCURSEL,
290 DEFAULT_WHEELDETECTION,
291 0);
292
293 /* Input buffer length: 100 packets */
294 SendDlgItemMessageW(hwndDlg,
295 IDC_PS2MOUSEINPUTUPDN,
296 UDM_SETPOS32,
297 0,
298 DEFAULT_INPUTBUFFERSIZE);
299
300 /* Fast Initialization: Checked */
301 SendDlgItemMessage(hwndDlg,
302 IDC_PS2MOUSEFASTINIT,
303 BM_SETCHECK,
304 (WPARAM)BST_CHECKED,
305 (LPARAM)0);
306
307 /* Enable the Apply button */
308 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
309 }
310 break;
311
312 default:
313 break;
314 }
315 }
316
317
318 static
319 VOID
320 MouseOnApply(
321 HWND hwndDlg)
322 {
323 PMOUSE_INFO pMouseInfo;
324 DWORD dwSampleRateIndex = 0;
325 DWORD dwSampleRate, dwWheelDetection;
326 DWORD dwInputBufferLength;
327 DWORD dwInitPolled;
328 UINT uValue;
329 BOOL bFailed;
330 INT nIndex;
331
332 pMouseInfo = (PMOUSE_INFO)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
333
334 /* Get the sample rate setting and store it if it was changed */
335 nIndex = SendDlgItemMessageW(hwndDlg, IDC_PS2MOUSESAMPLERATE,
336 CB_GETCURSEL, 0, 0);
337 if (nIndex == CB_ERR)
338 dwSampleRateIndex = DEFAULT_SAMPLERATEINDEX;
339 else
340 dwSampleRateIndex = (DWORD)nIndex;
341
342 if (dwSampleRateIndex != pMouseInfo->dwSampleRateIndex)
343 {
344 dwSampleRate = MouseSampleRates[dwSampleRateIndex];
345 RegSetValueExW(pMouseInfo->hDeviceKey,
346 L"SampleRate",
347 0,
348 REG_DWORD,
349 (LPBYTE)&dwSampleRate,
350 sizeof(dwSampleRate));
351 }
352
353 /* Get the wheel detection setting and store it if it was changed */
354 nIndex = SendDlgItemMessageW(hwndDlg, IDC_PS2MOUSEWHEEL,
355 CB_GETCURSEL, 0, 0);
356 if (nIndex == CB_ERR)
357 dwWheelDetection = DEFAULT_WHEELDETECTION;
358 else
359 dwWheelDetection = (DWORD)nIndex;
360
361 if (dwWheelDetection != pMouseInfo->dwWheelDetection)
362 {
363 RegSetValueExW(pMouseInfo->hDeviceKey,
364 L"EnableWheelDetection",
365 0,
366 REG_DWORD,
367 (LPBYTE)&dwWheelDetection,
368 sizeof(dwWheelDetection));
369 }
370
371 /* Get the input buffer length setting and store it if it was changed */
372 uValue = SendDlgItemMessageW(hwndDlg,
373 IDC_PS2MOUSEINPUTUPDN,
374 UDM_GETPOS32,
375 0,
376 (LPARAM)&bFailed);
377 if (bFailed)
378 dwInputBufferLength = DEFAULT_INPUTBUFFERSIZE;
379 else
380 dwInputBufferLength = (DWORD)uValue;
381
382 if (dwInputBufferLength != pMouseInfo->dwInputBufferLength)
383 {
384 RegSetValueExW(pMouseInfo->hDeviceKey,
385 L"MouseDataQueueSize",
386 0,
387 REG_DWORD,
388 (LPBYTE)&dwInputBufferLength,
389 sizeof(dwInputBufferLength));
390 }
391
392 /* Get the fast initialization setting and store it if it was changed */
393 uValue = SendDlgItemMessage(hwndDlg,
394 IDC_PS2MOUSEFASTINIT,
395 BM_GETCHECK,
396 0,
397 0);
398 dwInitPolled = (uValue == BST_CHECKED) ? 0 : 1;
399
400 if (dwInitPolled != pMouseInfo->dwInitPolled)
401 {
402 RegSetValueExW(pMouseInfo->hDeviceKey,
403 L"MouseInitializePolled",
404 0,
405 REG_DWORD,
406 (LPBYTE)&dwInitPolled,
407 sizeof(dwInitPolled));
408 }
409 }
410
411
412 static
413 BOOL
414 MouseOnNotify(
415 HWND hwndDlg,
416 WPARAM wParam,
417 LPARAM lParam)
418 {
419 switch (((LPNMHDR)lParam)->code)
420 {
421 case UDN_DELTAPOS:
422 if (((LPNMHDR)lParam)->idFrom == IDC_PS2MOUSEINPUTUPDN)
423 {
424 ((LPNMUPDOWN)lParam)->iDelta *= 10;
425 return FALSE;
426 }
427 break;
428
429 case PSN_APPLY:
430 MouseOnApply(hwndDlg);
431 return TRUE;
432 }
433
434 return FALSE;
435 }
436
437
438 static
439 INT_PTR
440 MouseOnCtrlColorStatic(
441 HWND hwndDlg,
442 WPARAM wParam,
443 LPARAM lParam)
444 {
445 if ((HWND)lParam != GetDlgItem(hwndDlg, IDC_PS2MOUSEINPUTLEN))
446 return 0;
447
448 SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
449 SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
450 return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
451 }
452
453
454 static
455 INT_PTR
456 CALLBACK
457 MouseDlgProc(
458 HWND hwndDlg,
459 UINT uMsg,
460 WPARAM wParam,
461 LPARAM lParam)
462 {
463 DPRINT("MouseDlgProc\n");
464
465 switch (uMsg)
466 {
467 case WM_INITDIALOG:
468 return MouseOnDialogInit(hwndDlg, lParam);
469
470 case WM_COMMAND:
471 MouseOnCommand(hwndDlg, wParam, lParam);
472 break;
473
474 case WM_NOTIFY:
475 return MouseOnNotify(hwndDlg, wParam, lParam);
476
477 case WM_CTLCOLORSTATIC:
478 return MouseOnCtrlColorStatic(hwndDlg, wParam, lParam);
479 }
480
481 return FALSE;
482 }
483
484
485 static
486 UINT
487 CALLBACK
488 MouseCallback(
489 HWND hWnd,
490 UINT uMsg,
491 LPPROPSHEETPAGE ppsp)
492 {
493 PMOUSE_INFO pMouseInfo;
494
495 pMouseInfo = (PMOUSE_INFO)ppsp->lParam;
496
497 if (uMsg == PSPCB_RELEASE)
498 {
499 if (pMouseInfo->hDeviceKey != NULL)
500 RegCloseKey(pMouseInfo->hDeviceKey);
501 HeapFree(GetProcessHeap(), 0, pMouseInfo);
502 }
503
504 return 1;
505 }
506
507
508 /*
509 * @implemented
510 */
511 BOOL
512 WINAPI
513 PS2MousePropPageProvider(
514 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
515 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
516 _In_ LPARAM lParam)
517 {
518 PROPSHEETPAGEW PropSheetPage;
519 HPROPSHEETPAGE hPropSheetPage;
520 PMOUSE_INFO pMouseInfo;
521
522 DPRINT("PS2MousePropPageProvider(%p %p %lx)\n",
523 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
524
525 if (lpPropSheetPageRequest->PageRequested != SPPSR_ENUM_ADV_DEVICE_PROPERTIES)
526 return FALSE;
527
528 pMouseInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MOUSE_INFO));
529 if (pMouseInfo == NULL)
530 return FALSE;
531
532 pMouseInfo->hDeviceKey = SetupDiOpenDevRegKey(lpPropSheetPageRequest->DeviceInfoSet,
533 lpPropSheetPageRequest->DeviceInfoData,
534 DICS_FLAG_GLOBAL,
535 0,
536 DIREG_DEV,
537 KEY_ALL_ACCESS);
538 if (pMouseInfo->hDeviceKey == INVALID_HANDLE_VALUE)
539 {
540 DPRINT1("SetupDiOpenDevRegKey() failed (Error %lu)\n", GetLastError());
541 HeapFree(GetProcessHeap(), 0, pMouseInfo);
542 return FALSE;
543 }
544
545 PropSheetPage.dwSize = sizeof(PROPSHEETPAGEW);
546 PropSheetPage.dwFlags = 0;
547 PropSheetPage.hInstance = hDllInstance;
548 PropSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_PS2MOUSEPROPERTIES);
549 PropSheetPage.pfnDlgProc = MouseDlgProc;
550 PropSheetPage.lParam = (LPARAM)pMouseInfo;
551 PropSheetPage.pfnCallback = MouseCallback;
552
553 hPropSheetPage = CreatePropertySheetPageW(&PropSheetPage);
554 if (hPropSheetPage == NULL)
555 {
556 DPRINT1("CreatePropertySheetPageW() failed!\n");
557 HeapFree(GetProcessHeap(), 0, pMouseInfo);
558 return FALSE;
559 }
560
561 if (!(*lpfnAddPropSheetPageProc)(hPropSheetPage, lParam))
562 {
563 DPRINT1("lpfnAddPropSheetPageProc() failed!\n");
564 DestroyPropertySheetPage(hPropSheetPage);
565 HeapFree(GetProcessHeap(), 0, pMouseInfo);
566 return FALSE;
567 }
568
569 return TRUE;
570 }
571
572
573 /*
574 * @implemented
575 */
576 BOOL
577 WINAPI
578 TapePropPageProvider(
579 _In_ PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
580 _In_ LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
581 _In_ LPARAM lParam)
582 {
583 DPRINT("TapePropPageProvider(%p %p %lx)\n",
584 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
585 return FALSE;
586 }
587
588 /* EOF */