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