[Win32k]
[reactos.git] / reactos / win32ss / user / ntuser / sysparams.c
1 /*
2 * COPYRIGHT: GPL, see COPYING in the top level directory
3 * PROJECT: ReactOS win32 kernel mode subsystem server
4 * PURPOSE: System parameters functions
5 * FILE: subsystems/win32/win32k/ntuser/sysparams.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9 // TODO:
10 // - Check all values that are in Winsta in ROS.
11 // - Does setting invalid fonts work?
12 // - Save appropriate text metrics.
13
14 #include <win32k.h>
15 DBG_DEFAULT_CHANNEL(UserSysparams);
16
17 SPIVALUES gspv;
18 BOOL gbSpiInitialized = FALSE;
19 BOOL g_PaintDesktopVersion = FALSE;
20
21 // HACK! We initialize SPI before we have a proper surface to get this from.
22 #define dpi 96
23 //(pPrimarySurface->GDIInfo.ulLogPixelsY)
24 #define REG2METRIC(reg) (reg > 0 ? reg : ((-(reg) * dpi + 720) / 1440))
25 #define METRIC2REG(met) (-((((met) * 1440)- 0) / dpi))
26
27 #define REQ_INTERACTIVE_WINSTA(err) \
28 if ( GetW32ProcessInfo()->prpwinsta != InputWindowStation) \
29 { \
30 ERR("NtUserSystemParametersInfo requires interactive window station (current is %wZ)\n", &GetW32ProcessInfo()->prpwinsta->Name); \
31 EngSetLastError(err); \
32 return 0; \
33 }
34
35 static const WCHAR* KEY_MOUSE = L"Control Panel\\Mouse";
36 static const WCHAR* VAL_MOUSE1 = L"MouseThreshold1";
37 static const WCHAR* VAL_MOUSE2 = L"MouseThreshold2";
38 static const WCHAR* VAL_MOUSE3 = L"MouseSpeed";
39 static const WCHAR* VAL_MOUSETRAILS = L"MouseTrails";
40 static const WCHAR* VAL_DBLCLKWIDTH = L"DoubleClickWidth";
41 static const WCHAR* VAL_DBLCLKHEIGHT = L"DoubleClickHeight";
42 static const WCHAR* VAL_DBLCLKTIME = L"DoubleClickSpeed";
43 static const WCHAR* VAL_SNAPDEFBTN = L"SnapToDefaultButton";
44 static const WCHAR* VAL_SWAP = L"SwapMouseButtons";
45 static const WCHAR* VAL_HOVERTIME = L"MouseHoverTime";
46 static const WCHAR* VAL_HOVERWIDTH = L"MouseHoverWidth";
47 static const WCHAR* VAL_HOVERHEIGHT = L"MouseHoverHeight";
48 static const WCHAR* VAL_SENSITIVITY = L"MouseSensitivity";
49
50 static const WCHAR* KEY_DESKTOP = L"Control Panel\\Desktop";
51 static const WCHAR* VAL_SCRTO = L"ScreenSaveTimeOut";
52 static const WCHAR* VAL_SCRNSV = L"SCRNSAVE.EXE";
53 static const WCHAR* VAL_SCRACT = L"ScreenSaveActive";
54 static const WCHAR* VAL_GRID = L"GridGranularity";
55 static const WCHAR* VAL_DRAG = L"DragFullWindows";
56 static const WCHAR* VAL_DRAGHEIGHT = L"DragHeight";
57 static const WCHAR* VAL_DRAGWIDTH = L"DragWidth";
58 static const WCHAR* VAL_FNTSMOOTH = L"FontSmoothing";
59 static const WCHAR* VAL_SCRLLLINES = L"WheelScrollLines";
60 static const WCHAR* VAL_CLICKLOCKTIME = L"ClickLockTime";
61 static const WCHAR* VAL_PAINTDESKVER = L"PaintDesktopVersion";
62 static const WCHAR* VAL_CARETRATE = L"CursorBlinkRate";
63 #if (_WIN32_WINNT >= 0x0600)
64 static const WCHAR* VAL_SCRLLCHARS = L"WheelScrollChars";
65 #endif
66 static const WCHAR* VAL_USERPREFMASK = L"UserPreferencesMask";
67
68 static const WCHAR* KEY_MDALIGN = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows";
69 static const WCHAR* VAL_MDALIGN = L"MenuDropAlignment";
70
71 static const WCHAR* KEY_METRIC = L"Control Panel\\Desktop\\WindowMetrics";
72 static const WCHAR* VAL_BORDER = L"BorderWidth";
73 static const WCHAR* VAL_ICONSPC = L"IconSpacing";
74 static const WCHAR* VAL_ICONVSPC = L"IconVerticalspacing";
75 static const WCHAR* VAL_ITWRAP = L"IconTitleWrap";
76
77 static const WCHAR* KEY_SOUND = L"Control Panel\\Sound";
78 static const WCHAR* VAL_BEEP = L"Beep";
79
80 static const WCHAR* KEY_KBD = L"Control Panel\\Keyboard";
81 static const WCHAR* VAL_KBDSPD = L"KeyboardSpeed";
82 static const WCHAR* VAL_KBDDELAY = L"KeyboardDelay";
83
84 static const WCHAR* KEY_SHOWSNDS = L"Control Panel\\Accessibility\\ShowSounds";
85 static const WCHAR* KEY_KDBPREF = L"Control Panel\\Accessibility\\Keyboard Preference";
86 static const WCHAR* KEY_SCRREAD = L"Control Panel\\Accessibility\\Blind Access";
87 static const WCHAR* VAL_ON = L"On";
88
89
90
91 /** Loading the settings ******************************************************/
92
93 static
94 INT
95 SpiLoadDWord(PCWSTR pwszKey, PCWSTR pwszValue, INT iValue)
96 {
97 DWORD Result;
98 if (!RegReadUserSetting(pwszKey, pwszValue, REG_DWORD, &Result, sizeof(Result)))
99 {
100 return iValue;
101 }
102 return Result;
103 }
104
105 static
106 INT
107 SpiLoadInt(PCWSTR pwszKey, PCWSTR pwszValue, INT iValue)
108 {
109 WCHAR awcBuffer[12];
110 ULONG cbSize;
111
112 cbSize = sizeof(awcBuffer);
113 if (!RegReadUserSetting(pwszKey, pwszValue, REG_SZ, awcBuffer, cbSize))
114 {
115 return iValue;
116 }
117 return _wtoi(awcBuffer);
118 }
119
120 static
121 DWORD
122 SpiLoadUserPrefMask(DWORD dValue)
123 {
124 DWORD Result;
125 if (!RegReadUserSetting(KEY_DESKTOP, VAL_USERPREFMASK, REG_BINARY, &Result, sizeof(Result)))
126 {
127 return dValue;
128 }
129 return Result;
130 }
131
132 static
133 DWORD
134 SpiLoadTimeOut(VOID)
135 { // Must have the string!
136 WCHAR szApplicationName[MAX_PATH];
137 RtlZeroMemory(&szApplicationName, sizeof(szApplicationName));
138 if (!RegReadUserSetting(KEY_DESKTOP, VAL_SCRNSV, REG_SZ, &szApplicationName, sizeof(szApplicationName)))
139 {
140 return 0;
141 }
142 if (wcslen(szApplicationName) == 0) return 0;
143 return SpiLoadInt(KEY_DESKTOP, VAL_SCRTO, 0);
144 }
145
146 static
147 INT
148 SpiLoadMouse(PCWSTR pwszValue, INT iValue)
149 {
150 return SpiLoadInt(KEY_MOUSE, pwszValue, iValue);
151 }
152
153 static
154 INT
155 SpiLoadMetric(PCWSTR pwszValue, INT iValue)
156 {
157 INT iRegVal;
158
159 iRegVal = SpiLoadInt(KEY_METRIC, pwszValue, METRIC2REG(iValue));
160 TRACE("Loaded metric setting '%S', iValue=%d(reg:%d), ret=%d(reg:%d)\n",
161 pwszValue, iValue, METRIC2REG(iValue), REG2METRIC(iRegVal), iRegVal);
162 return REG2METRIC(iRegVal);
163 }
164
165 static
166 VOID
167 SpiLoadFont(PLOGFONTW plfOut, LPWSTR pwszValueName, PLOGFONTW plfDefault)
168 {
169 BOOL bResult;
170
171 bResult = RegReadUserSetting(KEY_METRIC,
172 pwszValueName,
173 REG_BINARY,
174 plfOut,
175 sizeof(LOGFONTW));
176 if (!bResult)
177 *plfOut = *plfDefault;
178 }
179
180 static
181 VOID
182 SpiFixupValues()
183 {
184 /* Fixup values */
185 gspv.ncm.iCaptionWidth = max(gspv.ncm.iCaptionWidth, 8);
186 gspv.ncm.iBorderWidth = max(gspv.ncm.iBorderWidth, 1);
187 gspv.ncm.iScrollWidth = max(gspv.ncm.iScrollWidth, 8);
188 gspv.ncm.iScrollHeight = max(gspv.ncm.iScrollHeight, 8);
189 // gspv.ncm.iMenuHeight = max(gspv.ncm.iMenuHeight, gspv.tmMenuFont.tmHeight);
190 // gspv.ncm.iMenuHeight = max(gspv.ncm.iMenuHeight,
191 // 2 + gspv.tmMenuFont.tmHeight +
192 // gspv.tmMenuFont.tmExternalLeading);
193 if (gspv.iDblClickTime == 0) gspv.iDblClickTime = 500;
194
195 // FIXME: Hack!!!
196 gspv.tmMenuFont.tmHeight = 11;
197 gspv.tmMenuFont.tmExternalLeading = 2;
198
199 gspv.tmCaptionFont.tmHeight = 11;
200 gspv.tmCaptionFont.tmExternalLeading = 2;
201
202 }
203
204 static
205 VOID
206 SpiUpdatePerUserSystemParameters()
207 {
208 static LOGFONTW lf1 = {-11, 0, 0, 0, FW_NORMAL, FALSE, FALSE,
209 FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY,
210 VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif"};
211 static LOGFONTW lf2 = {-11, 0, 0, 0, FW_BOLD, FALSE, FALSE,
212 FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY,
213 VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif"};
214
215 TRACE("Enter SpiUpdatePerUserSystemParameters\n");
216
217 /* Clear the structure */
218 memset(&gspv, 0, sizeof(gspv));
219
220 /* Load mouse settings */
221 gspv.caiMouse.FirstThreshold = SpiLoadMouse(VAL_MOUSE1, 6);
222 gspv.caiMouse.SecondThreshold = SpiLoadMouse(VAL_MOUSE2, 10);
223 gspv.caiMouse.Acceleration = SpiLoadMouse(VAL_MOUSE3, 1);
224 gspv.iMouseSpeed = SpiLoadMouse(VAL_SENSITIVITY, 10);
225 gspv.bMouseBtnSwap = SpiLoadMouse(VAL_SWAP, 0);
226 gspv.bSnapToDefBtn = SpiLoadMouse(VAL_SNAPDEFBTN, 0);
227 gspv.iMouseTrails = SpiLoadMouse(VAL_MOUSETRAILS, 0);
228 gspv.iDblClickTime = SpiLoadMouse(VAL_DBLCLKTIME, 500);
229 gspv.iDblClickWidth = SpiLoadMouse(VAL_DBLCLKWIDTH, 4);
230 gspv.iDblClickHeight = SpiLoadMouse(VAL_DBLCLKHEIGHT, 4);
231 gspv.iMouseHoverTime = SpiLoadMouse(VAL_HOVERTIME, 400);
232 gspv.iMouseHoverWidth = SpiLoadMouse(VAL_HOVERWIDTH, 4);
233 gspv.iMouseHoverHeight = SpiLoadMouse(VAL_HOVERHEIGHT, 4);
234
235 /* Load NONCLIENTMETRICS */
236 gspv.ncm.cbSize = sizeof(NONCLIENTMETRICSW);
237 gspv.ncm.iBorderWidth = SpiLoadMetric(VAL_BORDER, 1);
238 gspv.ncm.iScrollWidth = SpiLoadMetric(L"ScrollWidth", 16);
239 gspv.ncm.iScrollHeight = SpiLoadMetric(L"ScrollHeight", 16);
240 gspv.ncm.iCaptionWidth = SpiLoadMetric(L"CaptionWidth", 19);
241 gspv.ncm.iCaptionHeight = SpiLoadMetric(L"CaptionHeight", 19);
242 gspv.ncm.iSmCaptionWidth = SpiLoadMetric(L"SmCaptionWidth", 12);
243 gspv.ncm.iSmCaptionHeight = SpiLoadMetric(L"SmCaptionHeight", 14);
244 gspv.ncm.iMenuWidth = SpiLoadMetric(L"MenuWidth", 18);
245 gspv.ncm.iMenuHeight = SpiLoadMetric(L"MenuHeight", 18);
246 #if (WINVER >= 0x0600)
247 gspv.ncm.iPaddedBorderWidth = SpiLoadMetric(L"PaddedBorderWidth", 18);
248 #endif
249 SpiLoadFont(&gspv.ncm.lfCaptionFont, L"CaptionFont", &lf2);
250 SpiLoadFont(&gspv.ncm.lfSmCaptionFont, L"SmCaptionFont", &lf1);
251 SpiLoadFont(&gspv.ncm.lfMenuFont, L"MenuFont", &lf1);
252 SpiLoadFont(&gspv.ncm.lfStatusFont, L"StatusFont", &lf1);
253 SpiLoadFont(&gspv.ncm.lfMessageFont, L"MessageFont", &lf1);
254
255 /* Load MINIMIZEDMETRICS */
256 gspv.mm.cbSize = sizeof(MINIMIZEDMETRICS);
257 gspv.mm.iWidth = SpiLoadMetric(L"MinWidth", 160);
258 gspv.mm.iHorzGap = SpiLoadMetric(L"MinHorzGap", 160);
259 gspv.mm.iVertGap = SpiLoadMetric(L"MinVertGap", 24);
260 gspv.mm.iArrange = SpiLoadInt(KEY_METRIC, L"MinArrange", ARW_HIDE);
261
262 /* Load ICONMETRICS */
263 gspv.im.cbSize = sizeof(ICONMETRICSW);
264 gspv.im.iHorzSpacing = SpiLoadMetric(VAL_ICONSPC, 64);
265 gspv.im.iVertSpacing = SpiLoadMetric(VAL_ICONVSPC, 64);
266 gspv.im.iTitleWrap = SpiLoadMetric(VAL_ITWRAP, 0);
267 SpiLoadFont(&gspv.im.lfFont, L"IconFont", &lf1);
268
269 /* Load desktop settings */
270 gspv.bDragFullWindows = SpiLoadInt(KEY_DESKTOP, VAL_DRAG, 0);
271 gspv.iWheelScrollLines = SpiLoadInt(KEY_DESKTOP, VAL_SCRLLLINES, 3);
272 gspv.dwMouseClickLockTime = SpiLoadDWord(KEY_DESKTOP, VAL_CLICKLOCKTIME, 1200);
273 gpsi->dtCaretBlink = SpiLoadInt(KEY_DESKTOP, VAL_CARETRATE, 530);
274 gspv.dwUserPrefMask = SpiLoadUserPrefMask(UPM_DEFAULT);
275 gspv.bMouseClickLock = (gspv.dwUserPrefMask & UPM_CLICKLOCK) != 0;
276 gspv.bMouseCursorShadow = (gspv.dwUserPrefMask & UPM_CURSORSHADOW) != 0;
277 #if (_WIN32_WINNT >= 0x0600)
278 gspv.iWheelScrollChars = SpiLoadInt(KEY_DESKTOP, VAL_SCRLLCHARS, 3);
279 #endif
280
281 /* Some hardcoded values for now */
282
283 gspv.tmCaptionFont.tmAveCharWidth = 6;
284 gspv.bBeep = TRUE;
285 gspv.bFlatMenu = FALSE;
286 gspv.uiFocusBorderWidth = 1;
287 gspv.uiFocusBorderHeight = 1;
288 gspv.bMenuDropAlign = 1;
289 gspv.bDropShadow = 1;
290 gspv.dwMenuShowDelay = 100;
291
292 gspv.iScrSaverTimeout = SpiLoadTimeOut();
293 gspv.bScrSaverActive = FALSE;
294 gspv.bScrSaverRunning = FALSE;
295 #if(WINVER >= 0x0600)
296 gspv.bScrSaverSecure = FALSE;
297 #endif
298
299 /* Make sure we don't use broken values */
300 SpiFixupValues();
301
302 /* Update SystemMetrics */
303 InitMetrics();
304 }
305
306 BOOL
307 InitSysParams()
308 {
309 SpiUpdatePerUserSystemParameters();
310 gbSpiInitialized = TRUE;
311 return TRUE;
312 }
313
314
315 BOOL
316 APIENTRY
317 NtUserUpdatePerUserSystemParameters(
318 DWORD dwReserved,
319 BOOL bEnable)
320 {
321 BOOL bResult;
322
323 TRACE("Enter NtUserUpdatePerUserSystemParameters\n");
324 UserEnterExclusive();
325
326 SpiUpdatePerUserSystemParameters();
327 if(bEnable)
328 g_PaintDesktopVersion = SpiLoadDWord(KEY_DESKTOP, VAL_PAINTDESKVER, 0);
329 else
330 g_PaintDesktopVersion = FALSE;
331 bResult = TRUE;
332
333 TRACE("Leave NtUserUpdatePerUserSystemParameters, returning %d\n", bResult);
334 UserLeave();
335
336 return bResult;
337 }
338
339
340 /** Storing the settings ******************************************************/
341
342 static
343 VOID
344 SpiStoreDWord(PCWSTR pwszKey, PCWSTR pwszValue, DWORD Value)
345 {
346 RegWriteUserSetting(pwszKey,
347 pwszValue,
348 REG_DWORD,
349 &Value,
350 sizeof(Value));
351 }
352
353 static
354 VOID
355 SpiStoreSz(PCWSTR pwszKey, PCWSTR pwszValue, PCWSTR pwsz)
356 {
357 RegWriteUserSetting(pwszKey,
358 pwszValue,
359 REG_SZ,
360 (PWSTR)pwsz,
361 wcslen(pwsz) * sizeof(WCHAR));
362 }
363
364 static
365 VOID
366 SpiStoreSzInt(PCWSTR pwszKey, PCWSTR pwszValue, INT iValue)
367 {
368 WCHAR awcBuffer[15];
369
370 _itow(iValue, awcBuffer, 10);
371 RegWriteUserSetting(pwszKey,
372 pwszValue,
373 REG_SZ,
374 awcBuffer,
375 (wcslen(awcBuffer) + 1) * sizeof(WCHAR));
376 }
377
378 static
379 VOID
380 SpiStoreMetric(LPCWSTR pwszValue, INT iValue)
381 {
382 SpiStoreSzInt(KEY_METRIC, pwszValue, METRIC2REG(iValue));
383 }
384
385 static
386 VOID
387 SpiStoreFont(PCWSTR pwszValue, LOGFONTW* plogfont)
388 {
389 RegWriteUserSetting(KEY_METRIC,
390 pwszValue,
391 REG_BINARY,
392 plogfont,
393 sizeof(LOGFONTW));
394 }
395
396
397 /** Get/Set value *************************************************************/
398
399 // FIXME: get rid of the flags and only use this from um. kernel can access data directly.
400 static
401 UINT_PTR
402 SpiMemCopy(PVOID pvDst, PVOID pvSrc, ULONG cbSize, BOOL bProtect, BOOL bToUser)
403 {
404 NTSTATUS Status = STATUS_SUCCESS;
405
406 if (bProtect)
407 {
408 _SEH2_TRY
409 {
410 if (bToUser)
411 {
412 ProbeForWrite(pvDst, cbSize, 1);
413 }
414 else
415 {
416 ProbeForRead(pvSrc, cbSize, 1);
417 }
418 memcpy(pvDst, pvSrc, cbSize);
419 }
420 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
421 {
422 Status = _SEH2_GetExceptionCode();
423 }
424 _SEH2_END
425 }
426 else
427 {
428 memcpy(pvDst, pvSrc, cbSize);
429 }
430
431 if (!NT_SUCCESS(Status))
432 {
433 SetLastNtError(Status);
434 ERR("SpiMemCopy failed, pvDst=%p, pvSrc=%p, bProtect=%d, bToUser=%d\n", pvDst, pvSrc, bProtect, bToUser);
435 }
436 return NT_SUCCESS(Status);
437 }
438
439 static inline
440 UINT_PTR
441 SpiGet(PVOID pvParam, PVOID pvData, ULONG cbSize, FLONG fl)
442 {
443 REQ_INTERACTIVE_WINSTA(ERROR_ACCESS_DENIED);
444 return SpiMemCopy(pvParam, pvData, cbSize, fl & SPIF_PROTECT, TRUE);
445 }
446
447 static inline
448 UINT_PTR
449 SpiSet(PVOID pvData, PVOID pvParam, ULONG cbSize, FLONG fl)
450 {
451 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
452 return SpiMemCopy(pvData, pvParam, cbSize, fl & SPIF_PROTECT, FALSE);
453 }
454
455 static inline
456 UINT_PTR
457 SpiGetEx(PVOID pvParam, PVOID pvData, ULONG cbSize, FLONG fl)
458 {
459 ULONG cbBufSize;
460 /* Get the cbSite member from UM memory */
461 if (!SpiSet(&cbBufSize, pvParam, sizeof(ULONG), fl))
462 return 0;
463 /* Verify the correct size */
464 if (cbBufSize != cbSize)
465 return 0;
466 return SpiGet(pvParam, pvData, cbSize, fl);
467 }
468
469 static inline
470 UINT_PTR
471 SpiGetInt(PVOID pvParam, PVOID piValue, FLONG fl)
472 {
473 return SpiGet(pvParam, piValue, sizeof(INT), fl);
474 }
475
476 static inline
477 UINT_PTR
478 SpiSetYesNo(BOOL *pbData, BOOL bValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl)
479 {
480 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
481 *pbData = bValue ? TRUE : FALSE;
482 if (fl & SPIF_UPDATEINIFILE)
483 {
484 SpiStoreSz(pwszKey, pwszValue, bValue ? L"Yes" : L"No");
485 }
486 return (UINT_PTR)pwszKey;
487 }
488
489 static inline
490 UINT_PTR
491 SpiSetBool(BOOL *pbData, INT iValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl)
492 {
493 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
494 *pbData = iValue ? TRUE : FALSE;
495 if (fl & SPIF_UPDATEINIFILE)
496 {
497 SpiStoreSzInt(pwszKey, pwszValue, iValue);
498 }
499 return (UINT_PTR)pwszKey;
500 }
501
502 static inline
503 UINT_PTR
504 SpiSetDWord(PVOID pvData, INT iValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl)
505 {
506 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
507 *(INT*)pvData = iValue;
508 if (fl & SPIF_UPDATEINIFILE)
509 {
510 SpiStoreDWord(pwszKey, pwszValue, iValue);
511 }
512 return (UINT_PTR)pwszKey;
513 }
514
515 static inline
516 UINT_PTR
517 SpiSetInt(PVOID pvData, INT iValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl)
518 {
519 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
520 *(INT*)pvData = iValue;
521 if (fl & SPIF_UPDATEINIFILE)
522 {
523 SpiStoreSzInt(pwszKey, pwszValue, iValue);
524 }
525 return (UINT_PTR)pwszKey;
526 }
527
528 static inline
529 UINT_PTR
530 SpiSetMetric(PVOID pvData, INT iValue, PCWSTR pwszValue, FLONG fl)
531 {
532 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
533 *(INT*)pvData = iValue;
534 if (fl & SPIF_UPDATEINIFILE)
535 {
536 SpiStoreMetric(pwszValue, iValue);
537 }
538 return (UINT_PTR)KEY_METRIC;
539 }
540
541 static inline
542 UINT_PTR
543 SpiSetUserPref(DWORD dwMask, PVOID pvValue, FLONG fl)
544 {
545 DWORD dwRegMask;
546 BOOL bValue = (BOOL)pvValue;
547
548 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
549
550 /* Set or clear bit according to bValue */
551 gspv.dwUserPrefMask = bValue ? gspv.dwUserPrefMask | dwMask :
552 gspv.dwUserPrefMask & ~dwMask;
553
554 if (fl & SPIF_UPDATEINIFILE)
555 {
556 /* Read current value */
557 RegReadUserSetting(KEY_DESKTOP,
558 VAL_USERPREFMASK,
559 REG_BINARY,
560 &dwRegMask,
561 sizeof(DWORD));
562
563 /* Set or clear bit according to bValue */
564 dwRegMask = bValue ? dwRegMask | dwMask : dwRegMask & ~dwMask;
565
566 /* write back value */
567 RegWriteUserSetting(KEY_DESKTOP,
568 VAL_USERPREFMASK,
569 REG_BINARY,
570 &dwRegMask,
571 sizeof(DWORD));
572 }
573
574 return (UINT_PTR)KEY_DESKTOP;
575 }
576
577 static inline
578 UINT_PTR
579 SpiGetUserPref(DWORD dwMask, PVOID pvParam, FLONG fl)
580 {
581 INT iValue = gspv.dwUserPrefMask & dwMask ? 1 : 0;
582 return SpiGetInt(pvParam, &iValue, fl);
583 }
584
585 static
586 UINT_PTR
587 SpiSetWallpaper(PVOID pvParam, FLONG fl)
588 {
589 UNICODE_STRING ustr;
590 WCHAR awc[MAX_PATH];
591 BOOL bResult;
592 HBITMAP hbmp, hOldBitmap;
593 SURFACE *psurfBmp;
594 ULONG ulTile, ulStyle;
595
596 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
597
598 if (!pvParam)
599 {
600 /* FIXME: Reset Wallpaper to registry value */
601 return (UINT_PTR)KEY_DESKTOP;
602 }
603
604 /* Capture UNICODE_STRING */
605 bResult = SpiMemCopy(&ustr, pvParam, sizeof(UNICODE_STRING), fl & SPIF_PROTECT, 0);
606 if (!bResult) return 0;
607 if (ustr.Length > MAX_PATH * sizeof(WCHAR))
608 return 0;
609
610 /* Copy the string buffer name */
611 bResult = SpiMemCopy(gspv.awcWallpaper, ustr.Buffer, ustr.Length, fl & SPIF_PROTECT, 0);
612 if (!bResult) return 0;
613
614 /* Update the UNICODE_STRING */
615 gspv.ustrWallpaper.Buffer = gspv.awcWallpaper;
616 gspv.ustrWallpaper.MaximumLength = MAX_PATH * sizeof(WCHAR);
617 gspv.ustrWallpaper.Length = ustr.Length;
618 gspv.awcWallpaper[ustr.Length / sizeof(WCHAR)] = 0;
619
620 TRACE("SpiSetWallpaper, name=%S\n", gspv.awcWallpaper);
621
622 /* Update registry */
623 if (fl & SPIF_UPDATEINIFILE)
624 {
625 SpiStoreSz(KEY_DESKTOP, L"Wallpaper", gspv.awcWallpaper);
626 }
627
628 /* Got a filename? */
629 if (gspv.awcWallpaper[0] != 0)
630 {
631 /* Convert file name to nt file name */
632 ustr.Buffer = awc;
633 ustr.MaximumLength = MAX_PATH * sizeof(WCHAR);
634 ustr.Length = 0;
635 if (!W32kDosPathNameToNtPathName(gspv.awcWallpaper, &ustr))
636 {
637 ERR("RtlDosPathNameToNtPathName_U failed\n");
638 return 0;
639 }
640
641 /* Load the Bitmap */
642 hbmp = UserLoadImage(ustr.Buffer);
643 if (!hbmp)
644 {
645 ERR("UserLoadImage failed\n");
646 return 0;
647 }
648
649 /* Try to get the size of the wallpaper */
650 if(!(psurfBmp = SURFACE_ShareLockSurface(hbmp)))
651 {
652 GreDeleteObject(hbmp);
653 return 0;
654 }
655
656 gspv.cxWallpaper = psurfBmp->SurfObj.sizlBitmap.cx;
657 gspv.cyWallpaper = psurfBmp->SurfObj.sizlBitmap.cy;
658 gspv.WallpaperMode = wmCenter;
659
660 SURFACE_ShareUnlockSurface(psurfBmp);
661
662 /* Change the bitmap's ownership */
663 GreSetObjectOwner(hbmp, GDI_OBJ_HMGR_PUBLIC);
664
665 /* Yes, Windows really loads the current setting from the registry. */
666 ulTile = SpiLoadInt(KEY_DESKTOP, L"TileWallpaper", 0);
667 ulStyle = SpiLoadInt(KEY_DESKTOP, L"WallpaperStyle", 0);
668 TRACE("SpiSetWallpaper: ulTile=%ld, ulStyle=%d\n", ulTile, ulStyle);
669
670 /* Check the values we found in the registry */
671 if(ulTile && !ulStyle)
672 {
673 gspv.WallpaperMode = wmTile;
674 }
675 else if(!ulTile && ulStyle == 2)
676 {
677 gspv.WallpaperMode = wmStretch;
678 }
679 }
680 else
681 {
682 /* Remove wallpaper */
683 gspv.cxWallpaper = 0;
684 gspv.cyWallpaper = 0;
685 hbmp = 0;
686 }
687
688 /* Take care of the old wallpaper, if any */
689 hOldBitmap = gspv.hbmWallpaper;
690 if(hOldBitmap != NULL)
691 {
692 /* Delete the old wallpaper */
693 GreSetObjectOwner(hOldBitmap, GDI_OBJ_HMGR_POWNED);
694 GreDeleteObject(hOldBitmap);
695 }
696
697 /* Set the new wallpaper */
698 gspv.hbmWallpaper = hbmp;
699
700 NtUserRedrawWindow(UserGetShellWindow(), NULL, NULL, RDW_INVALIDATE | RDW_ERASE);
701
702
703 return (UINT_PTR)KEY_DESKTOP;
704 }
705
706 static BOOL
707 SpiNotifyNCMetricsChanged()
708 {
709 PWND pwndDesktop, pwndCurrent;
710 HWND *ahwnd;
711 USER_REFERENCE_ENTRY Ref;
712 int i;
713
714 pwndDesktop = UserGetDesktopWindow();
715 ASSERT(pwndDesktop);
716
717 ahwnd = IntWinListChildren(pwndDesktop);
718 if(!ahwnd)
719 return FALSE;
720
721 for (i = 0; ahwnd[i]; i++)
722 {
723 pwndCurrent = UserGetWindowObject(ahwnd[i]);
724 if(!pwndCurrent)
725 continue;
726
727 UserRefObjectCo(pwndCurrent, &Ref);
728 co_WinPosSetWindowPos(pwndCurrent, 0, pwndCurrent->rcWindow.left,pwndCurrent->rcWindow.top,
729 pwndCurrent->rcWindow.right-pwndCurrent->rcWindow.left
730 ,pwndCurrent->rcWindow.bottom - pwndCurrent->rcWindow.top,
731 SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOCOPYBITS|
732 SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW);
733 UserDerefObjectCo(pwndCurrent);
734 }
735
736 ExFreePool(ahwnd);
737
738 return TRUE;
739 }
740
741 static
742 UINT_PTR
743 SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
744 {
745 switch (uiAction)
746 {
747 case SPI_GETBEEP:
748 return SpiGetInt(pvParam, &gspv.bBeep, fl);
749
750 case SPI_SETBEEP:
751 return SpiSetYesNo(&gspv.bBeep, uiParam, KEY_SOUND, VAL_BEEP, fl);
752
753 case SPI_GETMOUSE:
754 return SpiGet(pvParam, &gspv.caiMouse, 3 * sizeof(INT), fl);
755
756 case SPI_SETMOUSE:
757 if (!SpiSet(&gspv.caiMouse, pvParam, 3 * sizeof(INT), fl))
758 return 0;
759 if (fl & SPIF_UPDATEINIFILE)
760 {
761 SpiStoreSzInt(KEY_MOUSE, VAL_MOUSE1, gspv.caiMouse.FirstThreshold);
762 SpiStoreSzInt(KEY_MOUSE, VAL_MOUSE2, gspv.caiMouse.SecondThreshold);
763 SpiStoreSzInt(KEY_MOUSE, VAL_MOUSE3, gspv.caiMouse.Acceleration);
764 }
765 return (UINT_PTR)KEY_MOUSE;
766
767 case SPI_GETBORDER:
768 return SpiGetInt(pvParam, &gspv.ncm.iBorderWidth, fl);
769
770 case SPI_SETBORDER:
771 uiParam = max(uiParam, 1);
772 return SpiSetInt(&gspv.ncm.iBorderWidth, uiParam, KEY_METRIC, VAL_BORDER, fl);
773
774 case SPI_GETKEYBOARDSPEED:
775 return SpiGetInt(pvParam, &gspv.dwKbdSpeed, fl);
776
777 case SPI_SETKEYBOARDSPEED:
778 return SpiSetInt(&gspv.dwKbdSpeed, uiParam, KEY_KBD, VAL_KBDSPD, fl);
779
780 case SPI_LANGDRIVER:
781 ERR("SPI_LANGDRIVER is unimplemented\n");
782 break;
783
784 case SPI_GETSCREENSAVETIMEOUT:
785 return SpiGetInt(pvParam, &gspv.iScrSaverTimeout, fl);
786
787 case SPI_SETSCREENSAVETIMEOUT:
788 return SpiSetInt(&gspv.iScrSaverTimeout, uiParam, KEY_DESKTOP, VAL_SCRTO, fl);
789
790 case SPI_GETSCREENSAVEACTIVE:
791 return SpiGetInt(pvParam, &gspv.bScrSaverActive, fl);
792
793 case SPI_SETSCREENSAVEACTIVE:
794 return SpiSetInt(&gspv.bScrSaverActive, uiParam, KEY_DESKTOP, VAL_SCRACT, fl);
795
796 case SPI_GETGRIDGRANULARITY:
797 return SpiGetInt(pvParam, &gspv.uiGridGranularity, fl);
798
799 case SPI_SETGRIDGRANULARITY:
800 return SpiSetInt(&gspv.uiGridGranularity, uiParam, KEY_DESKTOP, VAL_GRID, fl);
801
802 case SPI_GETDESKWALLPAPER:
803 uiParam = min(uiParam, gspv.ustrWallpaper.Length + 1UL);
804 return SpiGet(pvParam, gspv.awcWallpaper, uiParam, fl);
805
806 case SPI_SETDESKWALLPAPER:
807 return SpiSetWallpaper(pvParam, fl);
808
809 case SPI_SETDESKPATTERN:
810 ERR("SPI_SETDESKPATTERN is unimplemented\n");
811 break;
812
813 case SPI_GETKEYBOARDDELAY:
814 return SpiGetInt(pvParam, &gspv.iKbdDelay, fl);
815
816 case SPI_SETKEYBOARDDELAY:
817 return SpiSetInt(&gspv.iKbdDelay, uiParam, KEY_KBD, VAL_KBDDELAY, fl);
818
819 case SPI_ICONHORIZONTALSPACING:
820 if (pvParam)
821 {
822 return SpiGetInt(pvParam, &gspv.im.iHorzSpacing, fl);
823 }
824 uiParam = max(uiParam, 32);
825 return SpiSetMetric(&gspv.im.iHorzSpacing, uiParam, VAL_ICONSPC, fl);
826
827 case SPI_ICONVERTICALSPACING:
828 if (pvParam)
829 {
830 return SpiGetInt(pvParam, &gspv.im.iVertSpacing, fl);
831 }
832 uiParam = max(uiParam, 32);
833 return SpiSetMetric(&gspv.im.iVertSpacing, uiParam, VAL_ICONVSPC, fl);
834
835 case SPI_GETICONTITLEWRAP:
836 return SpiGetInt(pvParam, &gspv.im.iTitleWrap, fl);
837
838 case SPI_SETICONTITLEWRAP:
839 return SpiSetInt(&gspv.im.iTitleWrap, uiParam, KEY_METRIC, VAL_ITWRAP, fl);
840
841 case SPI_GETMENUDROPALIGNMENT:
842 return SpiGetInt(pvParam, &gspv.bMenuDropAlign, fl);
843
844 case SPI_SETMENUDROPALIGNMENT:
845 return SpiSetBool(&gspv.bMenuDropAlign, uiParam, KEY_MDALIGN, VAL_MDALIGN, fl);
846
847 case SPI_SETDOUBLECLKWIDTH:
848 return SpiSetInt(&gspv.iDblClickWidth, uiParam, KEY_MOUSE, VAL_DBLCLKWIDTH, fl);
849
850 case SPI_SETDOUBLECLKHEIGHT:
851 return SpiSetInt(&gspv.iDblClickHeight, uiParam, KEY_MOUSE, VAL_DBLCLKHEIGHT, fl);
852
853 case SPI_GETICONTITLELOGFONT:
854 return SpiGet(pvParam, &gspv.im.lfFont, sizeof(LOGFONTW), fl);
855
856 case SPI_SETICONTITLELOGFONT:
857 if (!SpiSet(&gspv.im.lfFont, pvParam, sizeof(LOGFONTW), fl))
858 return 0;
859 if (fl & SPIF_UPDATEINIFILE)
860 {
861 SpiStoreFont(L"IconFont", &gspv.im.lfFont);
862 }
863 return (UINT_PTR)KEY_METRIC;
864
865 case SPI_SETDOUBLECLICKTIME:
866 return SpiSetInt(&gspv.iDblClickTime, uiParam, KEY_MOUSE, VAL_DBLCLKTIME, fl);
867
868 case SPI_SETMOUSEBUTTONSWAP:
869 return SpiSetInt(&gspv.bMouseBtnSwap, uiParam, KEY_MOUSE, VAL_SWAP, fl);
870
871 case SPI_GETFASTTASKSWITCH:
872 return SpiGetInt(pvParam, &gspv.bFastTaskSwitch, fl);
873
874 case SPI_SETFASTTASKSWITCH:
875 /* According to Winetest this one is unimplemented */
876 return 0;
877
878 case SPI_GETDRAGFULLWINDOWS:
879 return SpiGetInt(pvParam, &gspv.bDragFullWindows, fl);
880
881 case SPI_SETDRAGFULLWINDOWS:
882 return SpiSetInt(&gspv.bDragFullWindows, uiParam, KEY_DESKTOP, VAL_DRAG, fl);
883
884 case SPI_GETNONCLIENTMETRICS:
885 return SpiGet(pvParam, &gspv.ncm, sizeof(NONCLIENTMETRICSW), fl);
886
887 case SPI_SETNONCLIENTMETRICS:
888 if (!SpiSet(&gspv.ncm, pvParam, sizeof(NONCLIENTMETRICSW), fl))
889 return 0;
890 if (fl & SPIF_UPDATEINIFILE)
891 {
892 SpiStoreMetric(VAL_BORDER, gspv.ncm.iBorderWidth);
893 SpiStoreMetric(L"ScrollWidth", gspv.ncm.iScrollWidth);
894 SpiStoreMetric(L"ScrollHeight", gspv.ncm.iScrollHeight);
895 SpiStoreMetric(L"CaptionWidth", gspv.ncm.iCaptionWidth);
896 SpiStoreMetric(L"CaptionHeight", gspv.ncm.iCaptionHeight);
897 SpiStoreMetric(L"SmCaptionWidth", gspv.ncm.iSmCaptionWidth);
898 SpiStoreMetric(L"SmCaptionHeight", gspv.ncm.iSmCaptionHeight);
899 SpiStoreMetric(L"MenuWidth", gspv.ncm.iMenuWidth);
900 SpiStoreMetric(L"MenuHeight", gspv.ncm.iMenuHeight);
901 #if (WINVER >= 0x0600)
902 SpiStoreMetric(L"PaddedBorderWidth", gspv.ncm.iPaddedBorderWidth);
903 #endif
904 SpiStoreFont(L"CaptionFont", &gspv.ncm.lfCaptionFont);
905 SpiStoreFont(L"SmCaptionFont", &gspv.ncm.lfSmCaptionFont);
906 SpiStoreFont(L"MenuFont", &gspv.ncm.lfMenuFont);
907 SpiStoreFont(L"StatusFont", &gspv.ncm.lfStatusFont);
908 SpiStoreFont(L"MessageFont", &gspv.ncm.lfMessageFont);
909 }
910 if(!SpiNotifyNCMetricsChanged())
911 return 0;
912 return (UINT_PTR)KEY_METRIC;
913
914 case SPI_GETMINIMIZEDMETRICS:
915 return SpiGet(pvParam, &gspv.mm, sizeof(MINIMIZEDMETRICS), fl);
916
917 case SPI_SETMINIMIZEDMETRICS:
918 if (!SpiSet(&gspv.mm, pvParam, sizeof(MINIMIZEDMETRICS), fl))
919 return 0;
920 gspv.mm.iWidth = max(0, gspv.mm.iWidth);
921 gspv.mm.iHorzGap = max(0, gspv.mm.iHorzGap);
922 gspv.mm.iVertGap = max(0, gspv.mm.iVertGap);
923 gspv.mm.iArrange = gspv.mm.iArrange & 0xf;
924 if (fl & SPIF_UPDATEINIFILE)
925 {
926 SpiStoreMetric(L"MinWidth", gspv.mm.iWidth);
927 SpiStoreMetric(L"MinHorzGap", gspv.mm.iHorzGap);
928 SpiStoreMetric(L"MinVertGap", gspv.mm.iVertGap);
929 SpiStoreMetric(L"MinArrange", gspv.mm.iArrange);
930 }
931 return (UINT_PTR)KEY_METRIC;
932
933 case SPI_GETICONMETRICS:
934 return SpiGet(pvParam, &gspv.im, sizeof(ICONMETRICS), fl);
935
936 case SPI_SETICONMETRICS:
937 if (!SpiSet(&gspv.im, pvParam, sizeof(ICONMETRICS), fl))
938 return 0;
939 if (fl & SPIF_UPDATEINIFILE)
940 {
941 SpiStoreMetric(VAL_ICONSPC, gspv.im.iHorzSpacing);
942 SpiStoreMetric(VAL_ICONVSPC, gspv.im.iVertSpacing);
943 SpiStoreMetric(VAL_ITWRAP, gspv.im.iTitleWrap);
944 SpiStoreFont(L"IconFont", &gspv.im.lfFont);
945 }
946 return (UINT_PTR)KEY_METRIC;
947
948 case SPI_GETWORKAREA:
949 {
950 PMONITOR pmonitor = UserGetPrimaryMonitor();
951
952 if(!pmonitor)
953 return 0;
954
955 return SpiGet(pvParam, &pmonitor->rcWork, sizeof(RECTL), fl);
956 }
957
958 case SPI_SETWORKAREA:
959 {
960 /* FIXME: We should set the work area of the monitor
961 that contains the specified rectangle */
962 PMONITOR pmonitor = UserGetPrimaryMonitor();
963 RECT rcWorkArea;
964
965 if(!pmonitor)
966 return 0;
967
968 if (!SpiSet(&rcWorkArea, pvParam, sizeof(RECTL), fl))
969 return 0;
970
971 /* Verify the new values */
972 if (rcWorkArea.left < 0 ||
973 rcWorkArea.top < 0 ||
974 rcWorkArea.right > gpsi->aiSysMet[SM_CXSCREEN] ||
975 rcWorkArea.bottom > gpsi->aiSysMet[SM_CYSCREEN] ||
976 rcWorkArea.right <= rcWorkArea.left ||
977 rcWorkArea.bottom <= rcWorkArea.top)
978 return 0;
979
980 pmonitor->rcWork = rcWorkArea;
981 if (fl & SPIF_UPDATEINIFILE)
982 {
983 // FIXME: What to do?
984 }
985 return (UINT_PTR)KEY_DESKTOP;
986 }
987
988 case SPI_SETPENWINDOWS:
989 ERR("SPI_SETPENWINDOWS is unimplemented\n");
990 break;
991
992 case SPI_GETFILTERKEYS:
993 return SpiGet(pvParam, &gspv.filterkeys, sizeof(FILTERKEYS), fl);
994
995 case SPI_SETFILTERKEYS:
996 if (!SpiSet(&gspv.filterkeys, pvParam, sizeof(FILTERKEYS), fl))
997 return 0;
998 if (fl & SPIF_UPDATEINIFILE)
999 {
1000 // FIXME: What to do?
1001 }
1002 return (UINT_PTR)KEY_DESKTOP;
1003
1004 case SPI_GETTOGGLEKEYS:
1005 return SpiGet(pvParam, &gspv.togglekeys, sizeof(TOGGLEKEYS), fl);
1006
1007 case SPI_SETTOGGLEKEYS:
1008 if (!SpiSet(&gspv.togglekeys, pvParam, sizeof(TOGGLEKEYS), fl))
1009 return 0;
1010 if (fl & SPIF_UPDATEINIFILE)
1011 {
1012 // FIXME: What to do?
1013 }
1014 return (UINT_PTR)KEY_DESKTOP;
1015
1016 case SPI_GETMOUSEKEYS:
1017 return SpiGet(pvParam, &gspv.mousekeys, sizeof(MOUSEKEYS), fl);
1018
1019 case SPI_SETMOUSEKEYS:
1020 if (!SpiSet(&gspv.mousekeys, pvParam, sizeof(MOUSEKEYS), fl))
1021 return 0;
1022 if (fl & SPIF_UPDATEINIFILE)
1023 {
1024 // FIXME: What to do?
1025 }
1026 return (UINT_PTR)KEY_DESKTOP;
1027
1028 case SPI_GETSHOWSOUNDS:
1029 return SpiGetInt(pvParam, &gspv.bShowSounds, fl);
1030
1031 case SPI_SETSHOWSOUNDS:
1032 return SpiSetBool(&gspv.bShowSounds, uiParam, KEY_SHOWSNDS, VAL_ON, fl);
1033
1034 case SPI_GETSTICKYKEYS:
1035 if (uiParam != sizeof(STICKYKEYS))
1036 return 0;
1037 return SpiGetEx(pvParam, &gspv.stickykeys, sizeof(STICKYKEYS), fl);
1038
1039 case SPI_SETSTICKYKEYS:
1040 if (!SpiSet(&gspv.stickykeys, pvParam, sizeof(STICKYKEYS), fl))
1041 return 0;
1042 if (fl & SPIF_UPDATEINIFILE)
1043 {
1044 // FIXME: What to do?
1045 }
1046 return (UINT_PTR)KEY_DESKTOP;
1047
1048 case SPI_GETACCESSTIMEOUT:
1049 if (uiParam != 0 && uiParam != sizeof(ACCESSTIMEOUT))
1050 return 0;
1051 return SpiGetEx(pvParam, &gspv.accesstimeout, sizeof(ACCESSTIMEOUT), fl);
1052
1053 case SPI_SETACCESSTIMEOUT:
1054 if (!SpiSet(&gspv.accesstimeout, pvParam, sizeof(ACCESSTIMEOUT), fl))
1055 return 0;
1056 if (fl & SPIF_UPDATEINIFILE)
1057 {
1058 // FIXME: What to do?
1059 }
1060 return (UINT_PTR)KEY_DESKTOP;
1061
1062 case SPI_GETSERIALKEYS:
1063 return SpiGet(pvParam, &gspv.serialkeys, sizeof(SERIALKEYS), fl);
1064
1065 case SPI_SETSERIALKEYS:
1066 if (!SpiSet(&gspv.serialkeys, pvParam, sizeof(SERIALKEYS), fl))
1067 return 0;
1068 if (fl & SPIF_UPDATEINIFILE)
1069 {
1070 // FIXME: What to do?
1071 }
1072 return (UINT_PTR)KEY_DESKTOP;
1073
1074 case SPI_GETSOUNDSENTRY:
1075 return SpiGet(pvParam, &gspv.soundsentry, sizeof(SOUNDSENTRY), fl);
1076
1077 case SPI_SETSOUNDSENTRY:
1078 if (!SpiSet(&gspv.soundsentry, pvParam, sizeof(SOUNDSENTRY), fl))
1079 return 0;
1080 if (fl & SPIF_UPDATEINIFILE)
1081 {
1082 // FIXME: What to do?
1083 }
1084 return (UINT_PTR)KEY_DESKTOP;
1085
1086 case SPI_GETHIGHCONTRAST:
1087 return SpiGet(pvParam, &gspv.highcontrast, sizeof(HIGHCONTRAST), fl);
1088
1089 case SPI_SETHIGHCONTRAST:
1090 if (!SpiSet(&gspv.highcontrast, pvParam, sizeof(HIGHCONTRAST), fl))
1091 return 0;
1092 if (fl & SPIF_UPDATEINIFILE)
1093 {
1094 // FIXME: What to do?
1095 }
1096 return (UINT_PTR)KEY_DESKTOP;
1097
1098 case SPI_GETKEYBOARDPREF:
1099 return SpiGetInt(pvParam, &gspv.bKbdPref, fl);
1100
1101 case SPI_SETKEYBOARDPREF:
1102 return SpiSetBool(&gspv.bKbdPref, uiParam, KEY_KDBPREF, VAL_ON, fl);
1103
1104 case SPI_GETSCREENREADER:
1105 return SpiGetInt(pvParam, &gspv.bScreenReader, fl);
1106
1107 case SPI_SETSCREENREADER:
1108 return SpiSetBool(&gspv.bScreenReader, uiParam, KEY_SCRREAD, VAL_ON, fl);
1109
1110 case SPI_GETANIMATION:
1111 return SpiGet(pvParam, &gspv.animationinfo, sizeof(ANIMATIONINFO), fl);
1112
1113 case SPI_SETANIMATION:
1114 if (!SpiSet(&gspv.animationinfo, pvParam, sizeof(ANIMATIONINFO), fl))
1115 return 0;
1116 if (fl & SPIF_UPDATEINIFILE)
1117 {
1118 // FIXME: What to do?
1119 }
1120 return (UINT_PTR)KEY_DESKTOP;
1121
1122 case SPI_GETFONTSMOOTHING:
1123 return SpiGetInt(pvParam, &gspv.bFontSmoothing, fl);
1124
1125 case SPI_SETFONTSMOOTHING:
1126 gspv.bFontSmoothing = uiParam ? TRUE : FALSE;
1127 if (fl & SPIF_UPDATEINIFILE)
1128 {
1129 SpiStoreSzInt(KEY_DESKTOP, VAL_FNTSMOOTH, uiParam ? 2 : 0);
1130 }
1131 return (UINT_PTR)KEY_DESKTOP;
1132
1133 case SPI_SETDRAGWIDTH:
1134 return SpiSetInt(&gspv.iDragWidth, uiParam, KEY_DESKTOP, VAL_DRAGWIDTH, fl);
1135
1136 case SPI_SETDRAGHEIGHT:
1137 return SpiSetInt(&gspv.iDragHeight, uiParam, KEY_DESKTOP, VAL_DRAGHEIGHT, fl);
1138
1139 case SPI_SETHANDHELD:
1140 return SpiSetBool(&gspv.bHandHeld, uiParam, KEY_DESKTOP, L"HandHeld", fl);
1141
1142 case SPI_GETLOWPOWERTIMEOUT:
1143 return SpiGetInt(pvParam, &gspv.iLowPwrTimeout, fl);
1144
1145 case SPI_GETPOWEROFFTIMEOUT:
1146 return SpiGetInt(pvParam, &gspv.iPwrOffTimeout, fl);
1147
1148 case SPI_SETLOWPOWERTIMEOUT:
1149 return SpiSetInt(&gspv.iLowPwrTimeout, uiParam, KEY_DESKTOP, L"LowPowerTimeOut", fl);
1150
1151 case SPI_SETPOWEROFFTIMEOUT:
1152 return SpiSetInt(&gspv.iPwrOffTimeout, uiParam, KEY_DESKTOP, L"PowerOffTimeOut", fl);
1153
1154 case SPI_GETLOWPOWERACTIVE:
1155 return SpiGetInt(pvParam, &gspv.iPwrOffTimeout, fl);
1156
1157 case SPI_GETPOWEROFFACTIVE:
1158 return SpiGetInt(pvParam, &gspv.bPwrOffActive, fl);
1159
1160 case SPI_SETLOWPOWERACTIVE:
1161 return SpiSetBool(&gspv.bLowPwrActive, uiParam, KEY_DESKTOP, L"LowPowerActive", fl);
1162
1163 case SPI_SETPOWEROFFACTIVE:
1164 return SpiSetBool(&gspv.bPwrOffActive, uiParam, KEY_DESKTOP, L"PowerOffActive", fl);
1165
1166 case SPI_SETCURSORS:
1167 ERR("SPI_SETCURSORS is unimplemented\n");
1168 break;
1169
1170 case SPI_SETICONS:
1171 ERR("SPI_SETICONS is unimplemented\n");
1172 break;
1173
1174 case SPI_GETDEFAULTINPUTLANG:
1175 if (!gspklBaseLayout)
1176 return FALSE;
1177
1178 return SpiGet(pvParam, &gspklBaseLayout->hkl, sizeof(HKL), fl);
1179
1180 case SPI_SETDEFAULTINPUTLANG:
1181 {
1182 HKL hkl;
1183
1184 /* Note: SPIF_UPDATEINIFILE is not supported */
1185 if ((fl & SPIF_UPDATEINIFILE) || !SpiSet(&hkl, pvParam, sizeof(hkl), fl))
1186 return FALSE;
1187
1188 return UserSetDefaultInputLang(hkl);
1189 }
1190
1191 case SPI_SETLANGTOGGLE:
1192 ERR("SPI_SETLANGTOGGLE is unimplemented\n");
1193 break;
1194
1195 case SPI_GETWINDOWSEXTENSION:
1196 ERR("SPI_GETWINDOWSEXTENSION is unimplemented\n");
1197 break;
1198
1199 case SPI_GETMOUSETRAILS:
1200 return SpiGetInt(pvParam, &gspv.iMouseTrails, fl);
1201
1202 case SPI_SETMOUSETRAILS:
1203 return SpiSetInt(&gspv.iMouseTrails, uiParam, KEY_MOUSE, VAL_MOUSETRAILS, fl);
1204
1205 case SPI_GETSNAPTODEFBUTTON:
1206 return SpiGetInt(pvParam, &gspv.bSnapToDefBtn, fl);
1207
1208 case SPI_SETSNAPTODEFBUTTON:
1209 return SpiSetBool(&gspv.bSnapToDefBtn, uiParam, KEY_MOUSE, VAL_SNAPDEFBTN, fl);
1210
1211 case SPI_GETMOUSEHOVERWIDTH:
1212 return SpiGetInt(pvParam, &gspv.iMouseHoverWidth, fl);
1213
1214 case SPI_SETMOUSEHOVERWIDTH:
1215 return SpiSetInt(&gspv.iMouseHoverWidth, uiParam, KEY_MOUSE, VAL_HOVERWIDTH, fl);
1216
1217 case SPI_GETMOUSEHOVERHEIGHT:
1218 return SpiGetInt(pvParam, &gspv.iMouseHoverHeight, fl);
1219
1220 case SPI_SETMOUSEHOVERHEIGHT:
1221 return SpiSetInt(&gspv.iMouseHoverHeight, uiParam, KEY_MOUSE, VAL_HOVERHEIGHT, fl);
1222
1223 case SPI_GETMOUSEHOVERTIME:
1224 return SpiGetInt(pvParam, &gspv.iMouseHoverTime, fl);
1225
1226 case SPI_SETMOUSEHOVERTIME:
1227 /* See http://msdn2.microsoft.com/en-us/library/ms724947.aspx
1228 * copy text from it, if some agument why xp and 2003 behovir diffent
1229 * only if they do not have SP install
1230 * " Windows Server 2003 and Windows XP: The operating system does not
1231 * enforce the use of USER_TIMER_MAXIMUM and USER_TIMER_MINIMUM until
1232 * Windows Server 2003 SP1 and Windows XP SP2 "
1233 */
1234 return SpiSetInt(&gspv.iMouseHoverTime, uiParam, KEY_MOUSE, VAL_HOVERTIME, fl);
1235
1236 case SPI_GETWHEELSCROLLLINES:
1237 return SpiGetInt(pvParam, &gspv.iWheelScrollLines, fl);
1238
1239 case SPI_SETWHEELSCROLLLINES:
1240 return SpiSetInt(&gspv.iWheelScrollLines, uiParam, KEY_DESKTOP, VAL_SCRLLLINES, fl);
1241
1242 case SPI_GETMENUSHOWDELAY:
1243 return SpiGetInt(pvParam, &gspv.dwMenuShowDelay, fl);
1244
1245 case SPI_SETMENUSHOWDELAY:
1246 return SpiSetInt(&gspv.dwMenuShowDelay, uiParam, KEY_DESKTOP, L"MenuShowDelay", fl);
1247
1248 #if (_WIN32_WINNT >= 0x0600)
1249 case SPI_GETWHEELSCROLLCHARS:
1250 return SpiGetInt(pvParam, &gspv.uiWheelScrollChars, fl);
1251
1252 case SPI_SETWHEELSCROLLCHARS:
1253 return SpiSetInt(&gspv.uiWheelScrollChars, uiParam, KEY_DESKTOP, VAL_SCRLLCHARS, fl);
1254 #endif
1255 case SPI_GETSHOWIMEUI:
1256 return SpiGetInt(pvParam, &gspv.bShowImeUi, fl);
1257
1258 case SPI_SETSHOWIMEUI:
1259 return SpiSetBool(&gspv.bShowImeUi, uiParam, KEY_DESKTOP, L"", fl);
1260
1261 case SPI_GETMOUSESPEED:
1262 return SpiGetInt(pvParam, &gspv.iMouseSpeed, fl);
1263
1264 case SPI_SETMOUSESPEED:
1265 {
1266 /* Allowed range is [1:20] */
1267 if ((INT_PTR)pvParam < 1 || (INT_PTR)pvParam > 20)
1268 return 0;
1269 else
1270 return SpiSetInt(&gspv.iMouseSpeed, (INT_PTR)pvParam, KEY_MOUSE, VAL_SENSITIVITY, fl);
1271 }
1272
1273 case SPI_GETSCREENSAVERRUNNING:
1274 return SpiGetInt(pvParam, &gspv.bScrSaverRunning, fl);
1275
1276 case SPI_SETSCREENSAVERRUNNING:
1277 // FIXME: also return value?
1278 return SpiSetBool(&gspv.bScrSaverRunning, uiParam, KEY_MOUSE, L"", fl);
1279
1280 #if(WINVER >= 0x0600)
1281 case SPI_GETAUDIODESCRIPTION:
1282 return SpiGet(pvParam, &gspv.audiodesription, sizeof(AUDIODESCRIPTION), fl);
1283
1284 case SPI_SETAUDIODESCRIPTION:
1285 ERR("SPI_SETAUDIODESCRIPTION is unimplemented\n");
1286 break;
1287
1288 case SPI_GETSCREENSAVESECURE:
1289 return SpiGetInt(pvParam, &gspv.bScrSaverSecure, fl);
1290
1291 case SPI_SETSCREENSAVESECURE:
1292 return SpiSetBool(&gspv.bScrSaverSecure, uiParam, KEY_DESKTOP, L"ScreenSaverIsSecure", fl);
1293 #endif
1294
1295 case SPI_GETACTIVEWINDOWTRACKING:
1296 return SpiGetUserPref(UPM_ACTIVEWINDOWTRACKING, pvParam, fl);
1297
1298 case SPI_SETACTIVEWINDOWTRACKING:
1299 return SpiSetUserPref(UPM_ACTIVEWINDOWTRACKING, pvParam, fl);
1300
1301 case SPI_GETMENUANIMATION:
1302 return SpiGetUserPref(UPM_MENUANIMATION, pvParam, fl);
1303
1304 case SPI_SETMENUANIMATION:
1305 return SpiSetUserPref(UPM_MENUANIMATION, pvParam, fl);
1306
1307 case SPI_GETCOMBOBOXANIMATION:
1308 return SpiGetUserPref(UPM_COMBOBOXANIMATION, pvParam, fl);
1309
1310 case SPI_SETCOMBOBOXANIMATION:
1311 return SpiSetUserPref(UPM_COMBOBOXANIMATION, pvParam, fl);
1312
1313 case SPI_GETLISTBOXSMOOTHSCROLLING:
1314 return SpiGetUserPref(UPM_LISTBOXSMOOTHSCROLLING, pvParam, fl);
1315
1316 case SPI_SETLISTBOXSMOOTHSCROLLING:
1317 return SpiSetUserPref(UPM_LISTBOXSMOOTHSCROLLING, pvParam, fl);
1318
1319 case SPI_GETGRADIENTCAPTIONS:
1320 return SpiGetUserPref(UPM_GRADIENTCAPTIONS, pvParam, fl);
1321
1322 case SPI_SETGRADIENTCAPTIONS:
1323 return SpiSetUserPref(UPM_GRADIENTCAPTIONS, pvParam, fl);
1324
1325 case SPI_GETKEYBOARDCUES:
1326 return SpiGetUserPref(UPM_KEYBOARDCUES, pvParam, fl);
1327
1328 case SPI_SETKEYBOARDCUES:
1329 return SpiSetUserPref(UPM_KEYBOARDCUES, pvParam, fl);
1330
1331 case SPI_GETACTIVEWNDTRKZORDER:
1332 return SpiGetUserPref(UPM_ACTIVEWNDTRKZORDER, pvParam, fl);
1333
1334 case SPI_SETACTIVEWNDTRKZORDER:
1335 return SpiSetUserPref(UPM_ACTIVEWNDTRKZORDER, pvParam, fl);
1336
1337 case SPI_GETHOTTRACKING:
1338 return SpiGetUserPref(UPM_HOTTRACKING, pvParam, fl);
1339
1340 case SPI_SETHOTTRACKING:
1341 return SpiSetUserPref(UPM_HOTTRACKING, pvParam, fl);
1342
1343 case SPI_GETMENUFADE:
1344 return SpiGetUserPref(UPM_MENUFADE, pvParam, fl);
1345
1346 case SPI_SETMENUFADE:
1347 return SpiSetUserPref(UPM_MENUFADE, pvParam, fl);
1348
1349 case SPI_GETSELECTIONFADE:
1350 return SpiGetUserPref(UPM_SELECTIONFADE, pvParam, fl);
1351
1352 case SPI_SETSELECTIONFADE:
1353 return SpiSetUserPref(UPM_SELECTIONFADE, pvParam, fl);
1354
1355 case SPI_GETTOOLTIPANIMATION:
1356 return SpiGetUserPref(UPM_TOOLTIPANIMATION, pvParam, fl);
1357
1358 case SPI_SETTOOLTIPANIMATION:
1359 return SpiSetUserPref(UPM_TOOLTIPANIMATION, pvParam, fl);
1360
1361 case SPI_GETTOOLTIPFADE:
1362 return SpiGetUserPref(UPM_TOOLTIPFADE, pvParam, fl);
1363
1364 case SPI_SETTOOLTIPFADE:
1365 return SpiSetUserPref(UPM_TOOLTIPFADE, pvParam, fl);
1366
1367 case SPI_GETCURSORSHADOW:
1368 return SpiGetUserPref(UPM_CURSORSHADOW, pvParam, fl);
1369
1370 case SPI_SETCURSORSHADOW:
1371 gspv.bMouseCursorShadow = (BOOL)pvParam;
1372 return SpiSetUserPref(UPM_CURSORSHADOW, pvParam, fl);
1373
1374 case SPI_GETUIEFFECTS:
1375 return SpiGetUserPref(UPM_UIEFFECTS, pvParam, fl);
1376
1377 case SPI_SETUIEFFECTS:
1378 return SpiSetUserPref(UPM_UIEFFECTS, pvParam, fl);
1379
1380 case SPI_GETMOUSESONAR:
1381 return SpiGetInt(pvParam, &gspv.bMouseSonar, fl);
1382
1383 case SPI_SETMOUSESONAR:
1384 return SpiSetBool(&gspv.bMouseSonar, uiParam, KEY_MOUSE, L"", fl);
1385
1386 case SPI_GETMOUSECLICKLOCK:
1387 return SpiGetUserPref(UPM_CLICKLOCK, pvParam, fl);
1388
1389 case SPI_SETMOUSECLICKLOCK:
1390 gspv.bMouseClickLock = (BOOL)pvParam;
1391 return SpiSetUserPref(UPM_CLICKLOCK, pvParam, fl);
1392
1393 case SPI_GETMOUSEVANISH:
1394 return SpiGetInt(pvParam, &gspv.bMouseVanish, fl);
1395
1396 case SPI_SETMOUSEVANISH:
1397 return SpiSetBool(&gspv.bMouseVanish, uiParam, KEY_MOUSE, L"", fl);
1398
1399 case SPI_GETFLATMENU:
1400 return SpiGetInt(pvParam, &gspv.bFlatMenu, fl);
1401
1402 case SPI_SETFLATMENU:
1403 return SpiSetBool(&gspv.bFlatMenu, uiParam, KEY_MOUSE, L"", fl);
1404
1405 case SPI_GETDROPSHADOW:
1406 return SpiGetInt(pvParam, &gspv.bDropShadow, fl);
1407
1408 case SPI_SETDROPSHADOW:
1409 return SpiSetBool(&gspv.bDropShadow, uiParam, KEY_MOUSE, L"", fl);
1410
1411 case SPI_GETBLOCKSENDINPUTRESETS:
1412 return SpiGetInt(pvParam, &gspv.bBlockSendInputResets, fl);
1413
1414 case SPI_SETBLOCKSENDINPUTRESETS:
1415 return SpiSetBool(&gspv.bBlockSendInputResets, uiParam, KEY_MOUSE, L"", fl);
1416
1417 #if(_WIN32_WINNT >= 0x0600)
1418 case SPI_GETDISABLEOVERLAPPEDCONTENT:
1419 return SpiGetInt(pvParam, &gspv.bDisableOverlappedContent, fl);
1420
1421 case SPI_SETDISABLEOVERLAPPEDCONTENT:
1422 return SpiSetBool(&gspv.bDisableOverlappedContent, uiParam, KEY_MOUSE, L"", fl);
1423
1424 case SPI_GETCLIENTAREAANIMATION:
1425 return SpiGetInt(pvParam, &gspv.bClientAnimation, fl);
1426
1427 case SPI_SETCLIENTAREAANIMATION:
1428 return SpiSetBool(&gspv.bClientAnimation, uiParam, KEY_MOUSE, L"", fl);
1429
1430 case SPI_GETCLEARTYPE:
1431 return SpiGetInt(pvParam, &gspv.bClearType, fl);
1432
1433 case SPI_SETCLEARTYPE:
1434 return SpiSetBool(&gspv.bClearType, uiParam, KEY_MOUSE, L"", fl);
1435
1436 case SPI_GETSPEECHRECOGNITION:
1437 return SpiGetInt(pvParam, &gspv.bSpeechRecognition, fl);
1438
1439 case SPI_SETSPEECHRECOGNITION:
1440 return SpiSetBool(&gspv.bSpeechRecognition, uiParam, KEY_MOUSE, L"", fl);
1441 #endif
1442
1443 case SPI_GETFOREGROUNDLOCKTIMEOUT:
1444 return SpiGetInt(pvParam, &gspv.dwForegroundLockTimeout, fl);
1445
1446 case SPI_SETFOREGROUNDLOCKTIMEOUT:
1447 return SpiSetInt(&gspv.dwForegroundLockTimeout, uiParam, KEY_MOUSE, L"", fl);
1448
1449 case SPI_GETACTIVEWNDTRKTIMEOUT:
1450 return SpiGetInt(pvParam, &gspv.dwActiveTrackingTimeout, fl);
1451
1452 case SPI_SETACTIVEWNDTRKTIMEOUT:
1453 return SpiSetInt(&gspv.dwActiveTrackingTimeout, uiParam, KEY_MOUSE, L"", fl);
1454
1455 case SPI_GETFOREGROUNDFLASHCOUNT:
1456 return SpiGetInt(pvParam, &gspv.dwForegroundFlashCount, fl);
1457
1458 case SPI_SETFOREGROUNDFLASHCOUNT:
1459 return SpiSetInt(&gspv.dwForegroundFlashCount, uiParam, KEY_MOUSE, L"", fl);
1460
1461 case SPI_GETCARETWIDTH:
1462 return SpiGetInt(pvParam, &gspv.dwCaretWidth, fl);
1463
1464 case SPI_SETCARETWIDTH:
1465 return SpiSetInt(&gspv.dwCaretWidth, uiParam, KEY_MOUSE, L"", fl);
1466
1467 case SPI_GETMOUSECLICKLOCKTIME:
1468 return SpiGetInt(pvParam, &gspv.dwMouseClickLockTime, fl);
1469
1470 case SPI_SETMOUSECLICKLOCKTIME:
1471 return SpiSetDWord(&gspv.dwMouseClickLockTime, uiParam, KEY_DESKTOP, VAL_CLICKLOCKTIME, fl);
1472
1473 case SPI_GETFONTSMOOTHINGTYPE:
1474 return SpiGetInt(pvParam, &gspv.uiFontSmoothingType, fl);
1475
1476 case SPI_SETFONTSMOOTHINGTYPE:
1477 return SpiSetInt(&gspv.uiFontSmoothingType, uiParam, KEY_MOUSE, L"", fl);
1478
1479 case SPI_GETFONTSMOOTHINGCONTRAST:
1480 return SpiGetInt(pvParam, &gspv.uiFontSmoothingContrast, fl);
1481
1482 case SPI_SETFONTSMOOTHINGCONTRAST:
1483 return SpiSetInt(&gspv.uiFontSmoothingContrast, uiParam, KEY_MOUSE, L"", fl);
1484
1485 case SPI_GETFOCUSBORDERWIDTH:
1486 return SpiGetInt(pvParam, &gspv.uiFocusBorderWidth, fl);
1487
1488 case SPI_SETFOCUSBORDERWIDTH:
1489 return SpiSetInt(&gspv.uiFocusBorderWidth, uiParam, KEY_MOUSE, L"", fl);
1490
1491 case SPI_GETFOCUSBORDERHEIGHT:
1492 return SpiGetInt(pvParam, &gspv.uiFocusBorderHeight, fl);
1493
1494 case SPI_SETFOCUSBORDERHEIGHT:
1495 return SpiSetInt(&gspv.uiFocusBorderHeight, uiParam, KEY_MOUSE, L"", fl);
1496
1497 case SPI_GETFONTSMOOTHINGORIENTATION:
1498 return SpiGetInt(pvParam, &gspv.uiFontSmoothingOrientation, fl);
1499
1500 case SPI_SETFONTSMOOTHINGORIENTATION:
1501 return SpiSetInt(&gspv.uiFontSmoothingOrientation, uiParam, KEY_MOUSE, L"", fl);
1502
1503 /* The following are undocumented, but valid SPI values */
1504 case 0x1010:
1505 case 0x1011:
1506 case 0x1028:
1507 case 0x1029:
1508 case 0x102A:
1509 case 0x102B:
1510 case 0x102C:
1511 case 0x102D:
1512 case 0x102E:
1513 case 0x102F:
1514 case 0x1030:
1515 case 0x1031:
1516 case 0x1032:
1517 case 0x1033:
1518 case 0x1034:
1519 case 0x1035:
1520 case 0x1036:
1521 case 0x1037:
1522 case 0x1038:
1523 case 0x1039:
1524 case 0x103A:
1525 case 0x103B:
1526 case 0x103C:
1527 case 0x103D:
1528 ERR("Undocumented SPI value %x is unimplemented\n", uiAction);
1529 break;
1530
1531 default:
1532 ERR("Invalid SPI value: %d\n", uiAction);
1533 EngSetLastError(ERROR_INVALID_PARAMETER);
1534 return 0;
1535 }
1536
1537 return 0;
1538 }
1539
1540 BOOL
1541 FASTCALL
1542 UserSystemParametersInfo(
1543 UINT uiAction,
1544 UINT uiParam,
1545 PVOID pvParam,
1546 UINT fWinIni)
1547 {
1548 ULONG_PTR ulResult;
1549 PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
1550
1551 ASSERT(ppi);
1552
1553 if (!gbSpiInitialized)
1554 {
1555 KeRosDumpStackFrames(NULL, 20);
1556 //ASSERT(FALSE);
1557 return FALSE;
1558 }
1559
1560 /* Get a pointer to the current Windowstation */
1561 if (!ppi->prpwinsta)
1562 {
1563 ERR("UserSystemParametersInfo called without active windowstation.\n");
1564 //ASSERT(FALSE);
1565 //return FALSE;
1566 }
1567
1568 /* Do the actual operation */
1569 ulResult = SpiGetSet(uiAction, uiParam, pvParam, fWinIni);
1570
1571 /* Did we change something? */
1572 if (ulResult > 1)
1573 {
1574 SpiFixupValues();
1575
1576 /* Update system metrics */
1577 InitMetrics();
1578
1579 /* Send notification to toplevel windows, if requested */
1580 if (fWinIni & (SPIF_SENDCHANGE | SPIF_SENDWININICHANGE))
1581 {
1582 /* Send WM_SETTINGCHANGE to all toplevel windows */
1583 co_IntSendMessageTimeout(HWND_BROADCAST,
1584 WM_SETTINGCHANGE,
1585 (WPARAM)uiAction,
1586 (LPARAM)ulResult,
1587 SMTO_NORMAL,
1588 100,
1589 &ulResult);
1590 }
1591 ulResult = 1;
1592 }
1593
1594 return ulResult;
1595 }
1596
1597 BOOL
1598 APIENTRY
1599 NtUserSystemParametersInfo(
1600 UINT uiAction,
1601 UINT uiParam,
1602 PVOID pvParam,
1603 UINT fWinIni)
1604 {
1605 BOOL bResult;
1606
1607 TRACE("Enter NtUserSystemParametersInfo(%d)\n", uiAction);
1608 UserEnterExclusive();
1609
1610 // FIXME: Get rid of the flags and only use this from um. kernel can access data directly.
1611 /* Set UM memory protection flag */
1612 fWinIni |= SPIF_PROTECT;
1613
1614 /* Call internal function */
1615 bResult = UserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
1616
1617 TRACE("Leave NtUserSystemParametersInfo, returning %d\n", bResult);
1618 UserLeave();
1619
1620 return bResult;
1621 }
1622
1623 /* EOF */