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: win32ss/user/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 BOOL g_bWindowSnapEnabled = TRUE; 21 22 // HACK! We initialize SPI before we have a proper surface to get this from. 23 #define dpi 96 24 //(pPrimarySurface->GDIInfo.ulLogPixelsY) 25 #define REG2METRIC(reg) (reg > 0 ? reg : ((-(reg) * dpi + 720) / 1440)) 26 #define METRIC2REG(met) (-((((met) * 1440)- 0) / dpi)) 27 28 #define REQ_INTERACTIVE_WINSTA(err) \ 29 do { \ 30 if (GetW32ProcessInfo()->prpwinsta != InputWindowStation) \ 31 { \ 32 if (GetW32ProcessInfo()->prpwinsta == NULL) \ 33 { \ 34 ERR("NtUserSystemParametersInfo called without active window station, and it requires an interactive one\n"); \ 35 } \ 36 else \ 37 { \ 38 ERR("NtUserSystemParametersInfo requires interactive window station (current is '%wZ')\n", \ 39 &(OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(GetW32ProcessInfo()->prpwinsta))->Name)); \ 40 } \ 41 EngSetLastError(err); \ 42 return 0; \ 43 } \ 44 } while (0) 45 46 static const WCHAR* KEY_MOUSE = L"Control Panel\\Mouse"; 47 static const WCHAR* VAL_MOUSE1 = L"MouseThreshold1"; 48 static const WCHAR* VAL_MOUSE2 = L"MouseThreshold2"; 49 static const WCHAR* VAL_MOUSE3 = L"MouseSpeed"; 50 static const WCHAR* VAL_MOUSETRAILS = L"MouseTrails"; 51 static const WCHAR* VAL_DBLCLKWIDTH = L"DoubleClickWidth"; 52 static const WCHAR* VAL_DBLCLKHEIGHT = L"DoubleClickHeight"; 53 static const WCHAR* VAL_DBLCLKTIME = L"DoubleClickSpeed"; 54 static const WCHAR* VAL_SNAPDEFBTN = L"SnapToDefaultButton"; 55 static const WCHAR* VAL_SWAP = L"SwapMouseButtons"; 56 static const WCHAR* VAL_HOVERTIME = L"MouseHoverTime"; 57 static const WCHAR* VAL_HOVERWIDTH = L"MouseHoverWidth"; 58 static const WCHAR* VAL_HOVERHEIGHT = L"MouseHoverHeight"; 59 static const WCHAR* VAL_SENSITIVITY = L"MouseSensitivity"; 60 61 static const WCHAR* KEY_DESKTOP = L"Control Panel\\Desktop"; 62 static const WCHAR* VAL_SCRTO = L"ScreenSaveTimeOut"; 63 static const WCHAR* VAL_SCRNSV = L"SCRNSAVE.EXE"; 64 static const WCHAR* VAL_SCRACT = L"ScreenSaveActive"; 65 static const WCHAR* VAL_GRID = L"GridGranularity"; 66 static const WCHAR* VAL_DRAG = L"DragFullWindows"; 67 static const WCHAR* VAL_DRAGHEIGHT = L"DragHeight"; 68 static const WCHAR* VAL_DRAGWIDTH = L"DragWidth"; 69 static const WCHAR* VAL_FONTSMOOTHING = L"FontSmoothing"; 70 static const WCHAR* VAL_FONTSMOOTHINGTYPE = L"FontSmoothingType"; 71 static const WCHAR* VAL_FONTSMOOTHINGCONTRAST = L"FontSmoothingGamma"; 72 static const WCHAR* VAL_FONTSMOOTHINGORIENTATION = L"FontSmoothingOrientation"; 73 static const WCHAR* VAL_SCRLLLINES = L"WheelScrollLines"; 74 static const WCHAR* VAL_CLICKLOCKTIME = L"ClickLockTime"; 75 static const WCHAR* VAL_PAINTDESKVER = L"PaintDesktopVersion"; 76 static const WCHAR* VAL_CARETRATE = L"CursorBlinkRate"; 77 static const WCHAR* VAL_CARETWIDTH = L"CaretWidth"; 78 #if (_WIN32_WINNT >= 0x0600) 79 static const WCHAR* VAL_SCRLLCHARS = L"WheelScrollChars"; 80 #endif 81 static const WCHAR* VAL_USERPREFMASK = L"UserPreferencesMask"; 82 83 static const WCHAR* KEY_MDALIGN = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"; 84 static const WCHAR* VAL_MDALIGN = L"MenuDropAlignment"; 85 86 static const WCHAR* KEY_METRIC = L"Control Panel\\Desktop\\WindowMetrics"; 87 static const WCHAR* VAL_BORDER = L"BorderWidth"; 88 static const WCHAR* VAL_ICONSPC = L"IconSpacing"; 89 static const WCHAR* VAL_ICONVSPC = L"IconVerticalspacing"; 90 static const WCHAR* VAL_ITWRAP = L"IconTitleWrap"; 91 92 static const WCHAR* KEY_SOUND = L"Control Panel\\Sound"; 93 static const WCHAR* VAL_BEEP = L"Beep"; 94 95 static const WCHAR* KEY_KBD = L"Control Panel\\Keyboard"; 96 static const WCHAR* VAL_KBDSPD = L"KeyboardSpeed"; 97 static const WCHAR* VAL_KBDDELAY = L"KeyboardDelay"; 98 99 static const WCHAR* KEY_SHOWSNDS = L"Control Panel\\Accessibility\\ShowSounds"; 100 static const WCHAR* KEY_KDBPREF = L"Control Panel\\Accessibility\\Keyboard Preference"; 101 static const WCHAR* KEY_SCRREAD = L"Control Panel\\Accessibility\\Blind Access"; 102 static const WCHAR* VAL_ON = L"On"; 103 104 /** Loading the settings ******************************************************/ 105 106 static 107 INT 108 SpiLoadDWord(PCWSTR pwszKey, PCWSTR pwszValue, INT iValue) 109 { 110 DWORD Result; 111 if (!RegReadUserSetting(pwszKey, pwszValue, REG_DWORD, &Result, sizeof(Result))) 112 { 113 return iValue; 114 } 115 return Result; 116 } 117 118 static 119 INT 120 SpiLoadInt(PCWSTR pwszKey, PCWSTR pwszValue, INT iValue) 121 { 122 WCHAR awcBuffer[12]; 123 ULONG cbSize; 124 125 cbSize = sizeof(awcBuffer); 126 if (!RegReadUserSetting(pwszKey, pwszValue, REG_SZ, awcBuffer, cbSize)) 127 { 128 return iValue; 129 } 130 return _wtoi(awcBuffer); 131 } 132 133 static 134 DWORD 135 SpiLoadUserPrefMask(DWORD dValue) 136 { 137 DWORD Result; 138 if (!RegReadUserSetting(KEY_DESKTOP, VAL_USERPREFMASK, REG_BINARY, &Result, sizeof(Result))) 139 { 140 return dValue; 141 } 142 return Result; 143 } 144 145 static 146 DWORD 147 SpiLoadTimeOut(VOID) 148 { // Must have the string! 149 WCHAR szApplicationName[MAX_PATH]; 150 RtlZeroMemory(&szApplicationName, sizeof(szApplicationName)); 151 if (!RegReadUserSetting(KEY_DESKTOP, VAL_SCRNSV, REG_SZ, &szApplicationName, sizeof(szApplicationName))) 152 { 153 return 0; 154 } 155 if (szApplicationName[0] == 0) return 0; 156 return SpiLoadInt(KEY_DESKTOP, VAL_SCRTO, 600); 157 } 158 159 static 160 INT 161 SpiLoadMouse(PCWSTR pwszValue, INT iValue) 162 { 163 return SpiLoadInt(KEY_MOUSE, pwszValue, iValue); 164 } 165 166 static 167 INT 168 SpiLoadMetric(PCWSTR pwszValue, INT iValue) 169 { 170 INT iRegVal; 171 172 iRegVal = SpiLoadInt(KEY_METRIC, pwszValue, METRIC2REG(iValue)); 173 TRACE("Loaded metric setting '%S', iValue=%d(reg:%d), ret=%d(reg:%d)\n", 174 pwszValue, iValue, METRIC2REG(iValue), REG2METRIC(iRegVal), iRegVal); 175 return REG2METRIC(iRegVal); 176 } 177 178 static 179 VOID 180 SpiLoadFont(PLOGFONTW plfOut, LPWSTR pwszValueName, PLOGFONTW plfDefault) 181 { 182 BOOL bResult; 183 184 bResult = RegReadUserSetting(KEY_METRIC, 185 pwszValueName, 186 REG_BINARY, 187 plfOut, 188 sizeof(LOGFONTW)); 189 if (!bResult) 190 *plfOut = *plfDefault; 191 } 192 193 static 194 VOID 195 SpiFixupValues(VOID) 196 { 197 /* Fixup values */ 198 gspv.ncm.iCaptionWidth = max(gspv.ncm.iCaptionWidth, 8); 199 gspv.ncm.iBorderWidth = max(gspv.ncm.iBorderWidth, 1); 200 gspv.ncm.iScrollWidth = max(gspv.ncm.iScrollWidth, 8); 201 gspv.ncm.iScrollHeight = max(gspv.ncm.iScrollHeight, 8); 202 // gspv.ncm.iMenuHeight = max(gspv.ncm.iMenuHeight, gspv.tmMenuFont.tmHeight); 203 // gspv.ncm.iMenuHeight = max(gspv.ncm.iMenuHeight, 204 // 2 + gspv.tmMenuFont.tmHeight + 205 // gspv.tmMenuFont.tmExternalLeading); 206 if (gspv.iDblClickTime == 0) gspv.iDblClickTime = 500; 207 208 // FIXME: Hack!!! 209 gspv.tmMenuFont.tmHeight = 11; 210 gspv.tmMenuFont.tmExternalLeading = 2; 211 212 gspv.tmCaptionFont.tmHeight = 11; 213 gspv.tmCaptionFont.tmExternalLeading = 2; 214 215 } 216 217 /* Is Window Snap enabled? */ 218 static BOOL IntIsWindowSnapEnabled(VOID) 219 { 220 WCHAR szValue[2]; 221 if (RegReadUserSetting(L"Control Panel\\Desktop", L"WindowArrangementActive", 222 REG_SZ, szValue, sizeof(szValue))) 223 { 224 szValue[RTL_NUMBER_OF(szValue) - 1] = UNICODE_NULL; /* Avoid buffer overrun */ 225 return (_wtoi(szValue) != 0); 226 } 227 return TRUE; 228 } 229 230 static 231 VOID 232 SpiUpdatePerUserSystemParameters(VOID) 233 { 234 static LOGFONTW lf1 = {-11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 235 FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY, 236 VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif"}; 237 static LOGFONTW lf2 = {-11, 0, 0, 0, FW_BOLD, FALSE, FALSE, 238 FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY, 239 VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif"}; 240 241 TRACE("Enter SpiUpdatePerUserSystemParameters\n"); 242 243 /* Clear the structure */ 244 RtlZeroMemory(&gspv, sizeof(gspv)); 245 246 /* Load mouse settings */ 247 gspv.caiMouse.FirstThreshold = SpiLoadMouse(VAL_MOUSE1, 6); 248 gspv.caiMouse.SecondThreshold = SpiLoadMouse(VAL_MOUSE2, 10); 249 gspv.caiMouse.Acceleration = SpiLoadMouse(VAL_MOUSE3, 1); 250 gspv.iMouseSpeed = SpiLoadMouse(VAL_SENSITIVITY, 10); 251 gspv.bMouseBtnSwap = SpiLoadMouse(VAL_SWAP, 0); 252 gspv.bSnapToDefBtn = SpiLoadMouse(VAL_SNAPDEFBTN, 0); 253 gspv.iMouseTrails = SpiLoadMouse(VAL_MOUSETRAILS, 0); 254 gspv.iDblClickTime = SpiLoadMouse(VAL_DBLCLKTIME, 500); 255 gspv.iDblClickWidth = SpiLoadMouse(VAL_DBLCLKWIDTH, 4); 256 gspv.iDblClickHeight = SpiLoadMouse(VAL_DBLCLKHEIGHT, 4); 257 gspv.iMouseHoverTime = SpiLoadMouse(VAL_HOVERTIME, 400); 258 gspv.iMouseHoverWidth = SpiLoadMouse(VAL_HOVERWIDTH, 4); 259 gspv.iMouseHoverHeight = SpiLoadMouse(VAL_HOVERHEIGHT, 4); 260 261 /* Load keyboard settings */ 262 gspv.dwKbdSpeed = SpiLoadInt(KEY_KBD, VAL_KBDSPD, 31); 263 gspv.iKbdDelay = SpiLoadInt(KEY_KBD, VAL_KBDDELAY, 1); 264 265 /* Load NONCLIENTMETRICS */ 266 gspv.ncm.cbSize = sizeof(NONCLIENTMETRICSW); 267 gspv.ncm.iBorderWidth = SpiLoadMetric(VAL_BORDER, 1); 268 gspv.ncm.iScrollWidth = SpiLoadMetric(L"ScrollWidth", 16); 269 gspv.ncm.iScrollHeight = SpiLoadMetric(L"ScrollHeight", 16); 270 gspv.ncm.iCaptionWidth = SpiLoadMetric(L"CaptionWidth", 19); 271 gspv.ncm.iCaptionHeight = SpiLoadMetric(L"CaptionHeight", 19); 272 gspv.ncm.iSmCaptionWidth = SpiLoadMetric(L"SmCaptionWidth", 12); 273 gspv.ncm.iSmCaptionHeight = SpiLoadMetric(L"SmCaptionHeight", 15); 274 gspv.ncm.iMenuWidth = SpiLoadMetric(L"MenuWidth", 18); 275 gspv.ncm.iMenuHeight = SpiLoadMetric(L"MenuHeight", 18); 276 #if (WINVER >= 0x0600) 277 gspv.ncm.iPaddedBorderWidth = SpiLoadMetric(L"PaddedBorderWidth", 18); 278 #endif 279 SpiLoadFont(&gspv.ncm.lfCaptionFont, L"CaptionFont", &lf2); 280 SpiLoadFont(&gspv.ncm.lfSmCaptionFont, L"SmCaptionFont", &lf1); 281 SpiLoadFont(&gspv.ncm.lfMenuFont, L"MenuFont", &lf1); 282 SpiLoadFont(&gspv.ncm.lfStatusFont, L"StatusFont", &lf1); 283 SpiLoadFont(&gspv.ncm.lfMessageFont, L"MessageFont", &lf1); 284 285 /* Load MINIMIZEDMETRICS */ 286 gspv.mm.cbSize = sizeof(MINIMIZEDMETRICS); 287 gspv.mm.iWidth = SpiLoadMetric(L"MinWidth", 160); 288 gspv.mm.iHorzGap = SpiLoadMetric(L"MinHorzGap", 160); 289 gspv.mm.iVertGap = SpiLoadMetric(L"MinVertGap", 24); 290 gspv.mm.iArrange = SpiLoadInt(KEY_METRIC, L"MinArrange", ARW_HIDE); 291 292 /* Load ICONMETRICS */ 293 gspv.im.cbSize = sizeof(ICONMETRICSW); 294 gspv.im.iHorzSpacing = SpiLoadMetric(VAL_ICONSPC, 64); 295 gspv.im.iVertSpacing = SpiLoadMetric(VAL_ICONVSPC, 64); 296 gspv.im.iTitleWrap = SpiLoadMetric(VAL_ITWRAP, 1); 297 SpiLoadFont(&gspv.im.lfFont, L"IconFont", &lf1); 298 299 /* Load desktop settings */ 300 gspv.bDragFullWindows = SpiLoadInt(KEY_DESKTOP, VAL_DRAG, 0); 301 gspv.iWheelScrollLines = SpiLoadInt(KEY_DESKTOP, VAL_SCRLLLINES, 3); 302 gspv.dwMouseClickLockTime = SpiLoadDWord(KEY_DESKTOP, VAL_CLICKLOCKTIME, 1200); 303 gpsi->dtCaretBlink = SpiLoadInt(KEY_DESKTOP, VAL_CARETRATE, 530); 304 gspv.dwCaretWidth = SpiLoadDWord(KEY_DESKTOP, VAL_CARETWIDTH, 1); 305 gspv.dwUserPrefMask = SpiLoadUserPrefMask(UPM_DEFAULT); 306 gspv.bMouseClickLock = (gspv.dwUserPrefMask & UPM_CLICKLOCK) != 0; 307 gspv.bMouseCursorShadow = (gspv.dwUserPrefMask & UPM_CURSORSHADOW) != 0; 308 gspv.bFontSmoothing = SpiLoadInt(KEY_DESKTOP, VAL_FONTSMOOTHING, 0) == 2; 309 gspv.uiFontSmoothingType = SpiLoadDWord(KEY_DESKTOP, VAL_FONTSMOOTHINGTYPE, 1); 310 gspv.uiFontSmoothingContrast = SpiLoadDWord(KEY_DESKTOP, VAL_FONTSMOOTHINGCONTRAST, 1400); 311 gspv.uiFontSmoothingOrientation = SpiLoadDWord(KEY_DESKTOP, VAL_FONTSMOOTHINGORIENTATION, 1); 312 #if (_WIN32_WINNT >= 0x0600) 313 gspv.uiWheelScrollChars = SpiLoadInt(KEY_DESKTOP, VAL_SCRLLCHARS, 3); 314 #endif 315 316 /* Some hardcoded values for now */ 317 318 gspv.tmCaptionFont.tmAveCharWidth = 6; 319 gspv.bBeep = TRUE; 320 gspv.uiFocusBorderWidth = 1; 321 gspv.uiFocusBorderHeight = 1; 322 gspv.bMenuDropAlign = 0; 323 gspv.dwMenuShowDelay = SpiLoadInt(KEY_DESKTOP, L"MenuShowDelay", 400); 324 gspv.dwForegroundFlashCount = 3; 325 326 gspv.iScrSaverTimeout = SpiLoadTimeOut(); 327 gspv.bScrSaverActive = FALSE; 328 gspv.bScrSaverRunning = FALSE; 329 #if(WINVER >= 0x0600) 330 gspv.bScrSaverSecure = FALSE; 331 #endif 332 333 gspv.bFastTaskSwitch = TRUE; 334 335 gspv.accesstimeout.cbSize = sizeof(ACCESSTIMEOUT); 336 gspv.filterkeys.cbSize = sizeof(FILTERKEYS); 337 gspv.togglekeys.cbSize = sizeof(TOGGLEKEYS); 338 gspv.mousekeys.cbSize = sizeof(MOUSEKEYS); 339 gspv.stickykeys.cbSize = sizeof(STICKYKEYS); 340 gspv.serialkeys.cbSize = sizeof(SERIALKEYS); 341 gspv.soundsentry.cbSize = sizeof(SOUNDSENTRYW); 342 gspv.highcontrast.cbSize = sizeof(HIGHCONTRASTW); 343 gspv.animationinfo.cbSize = sizeof(ANIMATIONINFO); 344 345 /* Make sure we don't use broken values */ 346 SpiFixupValues(); 347 348 /* Update SystemMetrics */ 349 InitMetrics(); 350 351 if (gbSpiInitialized && gpsi) 352 { 353 if (gspv.bKbdPref) gpsi->dwSRVIFlags |= SRVINFO_KBDPREF; 354 if (SPITESTPREF(UPM_KEYBOARDCUES)) gpsi->PUSIFlags |= PUSIF_KEYBOARDCUES; 355 if (SPITESTPREF(UPM_COMBOBOXANIMATION)) gpsi->PUSIFlags |= PUSIF_COMBOBOXANIMATION; 356 if (SPITESTPREF(UPM_LISTBOXSMOOTHSCROLLING)) gpsi->PUSIFlags |= PUSIF_LISTBOXSMOOTHSCROLLING; 357 } 358 gdwLanguageToggleKey = UserGetLanguageToggle(L"Language Hotkey", 1); 359 gdwLayoutToggleKey = UserGetLanguageToggle(L"Layout Hotkey", 2); 360 361 g_bWindowSnapEnabled = IntIsWindowSnapEnabled(); 362 } 363 364 BOOL 365 InitSysParams(VOID) 366 { 367 SpiUpdatePerUserSystemParameters(); 368 gbSpiInitialized = TRUE; 369 return TRUE; 370 } 371 372 373 BOOL 374 APIENTRY 375 NtUserUpdatePerUserSystemParameters( 376 DWORD dwReserved, 377 BOOL bEnable) 378 { 379 BOOL bResult; 380 381 TRACE("Enter NtUserUpdatePerUserSystemParameters\n"); 382 UserEnterExclusive(); 383 384 SpiUpdatePerUserSystemParameters(); 385 if(bEnable) 386 g_PaintDesktopVersion = SpiLoadDWord(KEY_DESKTOP, VAL_PAINTDESKVER, 0); 387 else 388 g_PaintDesktopVersion = FALSE; 389 bResult = TRUE; 390 391 TRACE("Leave NtUserUpdatePerUserSystemParameters, returning %d\n", bResult); 392 UserLeave(); 393 394 return bResult; 395 } 396 397 398 /** Storing the settings ******************************************************/ 399 400 static 401 VOID 402 SpiStoreDWord(PCWSTR pwszKey, PCWSTR pwszValue, DWORD Value) 403 { 404 RegWriteUserSetting(pwszKey, 405 pwszValue, 406 REG_DWORD, 407 &Value, 408 sizeof(Value)); 409 } 410 411 static 412 VOID 413 SpiStoreSz(PCWSTR pwszKey, PCWSTR pwszValue, PCWSTR pwsz) 414 { 415 RegWriteUserSetting(pwszKey, 416 pwszValue, 417 REG_SZ, 418 pwsz, 419 (wcslen(pwsz) + 1) * sizeof(WCHAR)); 420 } 421 422 static 423 VOID 424 SpiStoreSzInt(PCWSTR pwszKey, PCWSTR pwszValue, INT iValue) 425 { 426 WCHAR awcBuffer[15]; 427 428 _itow(iValue, awcBuffer, 10); 429 RegWriteUserSetting(pwszKey, 430 pwszValue, 431 REG_SZ, 432 awcBuffer, 433 (wcslen(awcBuffer) + 1) * sizeof(WCHAR)); 434 } 435 436 static 437 VOID 438 SpiStoreMetric(LPCWSTR pwszValue, INT iValue) 439 { 440 SpiStoreSzInt(KEY_METRIC, pwszValue, METRIC2REG(iValue)); 441 } 442 443 static 444 VOID 445 SpiStoreFont(PCWSTR pwszValue, LOGFONTW* plogfont) 446 { 447 RegWriteUserSetting(KEY_METRIC, 448 pwszValue, 449 REG_BINARY, 450 plogfont, 451 sizeof(LOGFONTW)); 452 } 453 454 455 /** Get/Set value *************************************************************/ 456 457 // FIXME: get rid of the flags and only use this from um. kernel can access data directly. 458 static 459 UINT_PTR 460 SpiMemCopy(PVOID pvDst, PVOID pvSrc, ULONG cbSize, BOOL bProtect) 461 { 462 NTSTATUS Status = STATUS_SUCCESS; 463 464 if (bProtect) 465 { 466 _SEH2_TRY 467 { 468 RtlCopyMemory(pvDst, pvSrc, cbSize); 469 } 470 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 471 { 472 Status = _SEH2_GetExceptionCode(); 473 } 474 _SEH2_END; 475 } 476 else 477 { 478 RtlCopyMemory(pvDst, pvSrc, cbSize); 479 } 480 481 if (!NT_SUCCESS(Status)) 482 { 483 SetLastNtError(Status); 484 ERR("SpiMemCopy failed, pvDst=%p, pvSrc=%p, bProtect=%d\n", pvDst, pvSrc, bProtect); 485 } 486 487 return NT_SUCCESS(Status); 488 } 489 490 static inline 491 UINT_PTR 492 SpiGet(PVOID pvParam, PVOID pvData, ULONG cbSize, FLONG fl) 493 { 494 REQ_INTERACTIVE_WINSTA(ERROR_ACCESS_DENIED); 495 return SpiMemCopy(pvParam, pvData, cbSize, fl & SPIF_PROTECT); 496 } 497 498 static inline 499 UINT_PTR 500 SpiSet(PVOID pvData, PVOID pvParam, ULONG cbSize, FLONG fl) 501 { 502 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); 503 return SpiMemCopy(pvData, pvParam, cbSize, fl & SPIF_PROTECT); 504 } 505 506 static inline 507 UINT_PTR 508 SpiGetEx(PVOID pvParam, PVOID pvData, ULONG cbSize, FLONG fl) 509 { 510 ULONG cbBufSize; 511 /* Get the cbSite member from UM memory */ 512 if (!SpiSet(&cbBufSize, pvParam, sizeof(ULONG), fl)) 513 return 0; 514 /* Verify the correct size */ 515 if (cbBufSize != cbSize) 516 return 0; 517 return SpiGet(pvParam, pvData, cbSize, fl); 518 } 519 520 static inline 521 UINT_PTR 522 SpiGetInt(PVOID pvParam, PVOID piValue, FLONG fl) 523 { 524 return SpiGet(pvParam, piValue, sizeof(INT), fl); 525 } 526 527 static inline 528 UINT_PTR 529 SpiSetYesNo(BOOL *pbData, BOOL bValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl) 530 { 531 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); 532 *pbData = bValue ? TRUE : FALSE; 533 if (fl & SPIF_UPDATEINIFILE) 534 { 535 SpiStoreSz(pwszKey, pwszValue, bValue ? L"Yes" : L"No"); 536 } 537 return (UINT_PTR)pwszKey; 538 } 539 540 static inline 541 UINT_PTR 542 SpiSetBool(BOOL *pbData, INT iValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl) 543 { 544 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); 545 *pbData = iValue ? TRUE : FALSE; 546 if (fl & SPIF_UPDATEINIFILE) 547 { 548 SpiStoreSzInt(pwszKey, pwszValue, iValue); 549 } 550 return (UINT_PTR)pwszKey; 551 } 552 553 static inline 554 UINT_PTR 555 SpiSetDWord(PVOID pvData, INT iValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl) 556 { 557 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); 558 *(INT*)pvData = iValue; 559 if (fl & SPIF_UPDATEINIFILE) 560 { 561 SpiStoreDWord(pwszKey, pwszValue, iValue); 562 } 563 return (UINT_PTR)pwszKey; 564 } 565 566 static inline 567 UINT_PTR 568 SpiSetInt(PVOID pvData, INT iValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl) 569 { 570 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); 571 *(INT*)pvData = iValue; 572 if (fl & SPIF_UPDATEINIFILE) 573 { 574 SpiStoreSzInt(pwszKey, pwszValue, iValue); 575 } 576 return (UINT_PTR)pwszKey; 577 } 578 579 static inline 580 UINT_PTR 581 SpiSetMetric(PVOID pvData, INT iValue, PCWSTR pwszValue, FLONG fl) 582 { 583 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); 584 *(INT*)pvData = iValue; 585 if (fl & SPIF_UPDATEINIFILE) 586 { 587 SpiStoreMetric(pwszValue, iValue); 588 } 589 return (UINT_PTR)KEY_METRIC; 590 } 591 592 static inline 593 UINT_PTR 594 SpiSetUserPref(DWORD dwMask, PVOID pvValue, FLONG fl) 595 { 596 DWORD dwRegMask; 597 BOOL bValue = PtrToUlong(pvValue); 598 599 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); 600 601 /* Set or clear bit according to bValue */ 602 gspv.dwUserPrefMask = bValue ? gspv.dwUserPrefMask | dwMask : 603 gspv.dwUserPrefMask & ~dwMask; 604 605 if (fl & SPIF_UPDATEINIFILE) 606 { 607 /* Read current value */ 608 if (!RegReadUserSetting(KEY_DESKTOP, 609 VAL_USERPREFMASK, 610 REG_BINARY, 611 &dwRegMask, 612 sizeof(DWORD))) 613 { 614 WARN("Failed to read UserPreferencesMask setting\n"); 615 dwRegMask = 0; 616 } 617 618 /* Set or clear bit according to bValue */ 619 dwRegMask = bValue ? (dwRegMask | dwMask) : (dwRegMask & ~dwMask); 620 621 /* write back value */ 622 RegWriteUserSetting(KEY_DESKTOP, 623 VAL_USERPREFMASK, 624 REG_BINARY, 625 &dwRegMask, 626 sizeof(DWORD)); 627 } 628 629 return (UINT_PTR)KEY_DESKTOP; 630 } 631 632 static inline 633 UINT_PTR 634 SpiGetUserPref(DWORD dwMask, PVOID pvParam, FLONG fl) 635 { 636 INT iValue = gspv.dwUserPrefMask & dwMask ? 1 : 0; 637 return SpiGetInt(pvParam, &iValue, fl); 638 } 639 640 static 641 UINT_PTR 642 SpiSetWallpaper(PVOID pvParam, FLONG fl) 643 { 644 UNICODE_STRING ustr; 645 WCHAR awc[MAX_PATH]; 646 BOOL bResult; 647 HBITMAP hbmp, hOldBitmap; 648 SURFACE *psurfBmp; 649 ULONG ulTile, ulStyle; 650 651 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); 652 653 if (!pvParam) 654 { 655 /* FIXME: Reset Wallpaper to registry value */ 656 return (UINT_PTR)KEY_DESKTOP; 657 } 658 659 /* Capture UNICODE_STRING */ 660 bResult = SpiMemCopy(&ustr, pvParam, sizeof(ustr), fl & SPIF_PROTECT); 661 if (!bResult) 662 { 663 return 0; 664 } 665 if (ustr.Length > MAX_PATH * sizeof(WCHAR)) 666 { 667 return 0; 668 } 669 670 /* Copy the string buffer name */ 671 bResult = SpiMemCopy(gspv.awcWallpaper, ustr.Buffer, ustr.Length, fl & SPIF_PROTECT); 672 if (!bResult) 673 { 674 return 0; 675 } 676 677 /* Update the UNICODE_STRING */ 678 gspv.ustrWallpaper.Buffer = gspv.awcWallpaper; 679 gspv.ustrWallpaper.MaximumLength = MAX_PATH * sizeof(WCHAR); 680 gspv.ustrWallpaper.Length = ustr.Length; 681 gspv.awcWallpaper[ustr.Length / sizeof(WCHAR)] = 0; 682 683 TRACE("SpiSetWallpaper, name=%S\n", gspv.awcWallpaper); 684 685 /* Update registry */ 686 if (fl & SPIF_UPDATEINIFILE) 687 { 688 SpiStoreSz(KEY_DESKTOP, L"Wallpaper", gspv.awcWallpaper); 689 } 690 691 /* Got a filename? */ 692 if (gspv.awcWallpaper[0] != 0) 693 { 694 /* Convert file name to nt file name */ 695 ustr.Buffer = awc; 696 ustr.MaximumLength = MAX_PATH * sizeof(WCHAR); 697 ustr.Length = 0; 698 if (!W32kDosPathNameToNtPathName(gspv.awcWallpaper, &ustr)) 699 { 700 ERR("RtlDosPathNameToNtPathName_U failed\n"); 701 return 0; 702 } 703 704 /* Load the Bitmap */ 705 hbmp = UserLoadImage(ustr.Buffer); 706 if (!hbmp) 707 { 708 ERR("UserLoadImage failed\n"); 709 return 0; 710 } 711 712 /* Try to get the size of the wallpaper */ 713 if (!(psurfBmp = SURFACE_ShareLockSurface(hbmp))) 714 { 715 GreDeleteObject(hbmp); 716 return 0; 717 } 718 719 gspv.cxWallpaper = psurfBmp->SurfObj.sizlBitmap.cx; 720 gspv.cyWallpaper = psurfBmp->SurfObj.sizlBitmap.cy; 721 gspv.WallpaperMode = wmCenter; 722 723 SURFACE_ShareUnlockSurface(psurfBmp); 724 725 /* Change the bitmap's ownership */ 726 GreSetObjectOwner(hbmp, GDI_OBJ_HMGR_PUBLIC); 727 728 /* Yes, Windows really loads the current setting from the registry. */ 729 ulTile = SpiLoadInt(KEY_DESKTOP, L"TileWallpaper", 0); 730 ulStyle = SpiLoadInt(KEY_DESKTOP, L"WallpaperStyle", 0); 731 TRACE("SpiSetWallpaper: ulTile=%lu, ulStyle=%lu\n", ulTile, ulStyle); 732 733 /* Check the values we found in the registry */ 734 if (ulTile && !ulStyle) 735 { 736 gspv.WallpaperMode = wmTile; 737 } 738 else if (!ulTile && ulStyle) 739 { 740 if (ulStyle == 2) 741 { 742 gspv.WallpaperMode = wmStretch; 743 } 744 else if (ulStyle == 6) 745 { 746 gspv.WallpaperMode = wmFit; 747 } 748 else if (ulStyle == 10) 749 { 750 gspv.WallpaperMode = wmFill; 751 } 752 } 753 } 754 else 755 { 756 /* Remove wallpaper */ 757 gspv.cxWallpaper = 0; 758 gspv.cyWallpaper = 0; 759 hbmp = 0; 760 } 761 762 /* Take care of the old wallpaper, if any */ 763 hOldBitmap = gspv.hbmWallpaper; 764 if(hOldBitmap != NULL) 765 { 766 /* Delete the old wallpaper */ 767 GreSetObjectOwner(hOldBitmap, GDI_OBJ_HMGR_POWNED); 768 GreDeleteObject(hOldBitmap); 769 } 770 771 /* Set the new wallpaper */ 772 gspv.hbmWallpaper = hbmp; 773 774 NtUserRedrawWindow(UserGetShellWindow(), NULL, NULL, RDW_INVALIDATE | RDW_ERASE); 775 776 777 return (UINT_PTR)KEY_DESKTOP; 778 } 779 780 static BOOL 781 SpiNotifyNCMetricsChanged(VOID) 782 { 783 PWND pwndDesktop, pwndCurrent; 784 HWND *ahwnd; 785 USER_REFERENCE_ENTRY Ref; 786 int i; 787 788 pwndDesktop = UserGetDesktopWindow(); 789 ASSERT(pwndDesktop); 790 791 ahwnd = IntWinListChildren(pwndDesktop); 792 if(!ahwnd) 793 return FALSE; 794 795 for (i = 0; ahwnd[i]; i++) 796 { 797 pwndCurrent = UserGetWindowObject(ahwnd[i]); 798 if(!pwndCurrent) 799 continue; 800 801 UserRefObjectCo(pwndCurrent, &Ref); 802 co_WinPosSetWindowPos(pwndCurrent, 0, pwndCurrent->rcWindow.left,pwndCurrent->rcWindow.top, 803 pwndCurrent->rcWindow.right-pwndCurrent->rcWindow.left 804 ,pwndCurrent->rcWindow.bottom - pwndCurrent->rcWindow.top, 805 SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOCOPYBITS| 806 SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW); 807 UserDerefObjectCo(pwndCurrent); 808 } 809 810 ExFreePoolWithTag(ahwnd, USERTAG_WINDOWLIST); 811 812 return TRUE; 813 } 814 815 static 816 UINT_PTR 817 SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl) 818 { 819 switch (uiAction) 820 { 821 case SPI_GETBEEP: 822 return SpiGetInt(pvParam, &gspv.bBeep, fl); 823 824 case SPI_SETBEEP: 825 return SpiSetYesNo(&gspv.bBeep, uiParam, KEY_SOUND, VAL_BEEP, fl); 826 827 case SPI_GETMOUSE: 828 return SpiGet(pvParam, &gspv.caiMouse, 3 * sizeof(INT), fl); 829 830 case SPI_SETMOUSE: 831 if (!SpiSet(&gspv.caiMouse, pvParam, 3 * sizeof(INT), fl)) 832 return 0; 833 if (fl & SPIF_UPDATEINIFILE) 834 { 835 SpiStoreSzInt(KEY_MOUSE, VAL_MOUSE1, gspv.caiMouse.FirstThreshold); 836 SpiStoreSzInt(KEY_MOUSE, VAL_MOUSE2, gspv.caiMouse.SecondThreshold); 837 SpiStoreSzInt(KEY_MOUSE, VAL_MOUSE3, gspv.caiMouse.Acceleration); 838 } 839 return (UINT_PTR)KEY_MOUSE; 840 841 case SPI_GETBORDER: 842 return SpiGetInt(pvParam, &gspv.ncm.iBorderWidth, fl); 843 844 case SPI_SETBORDER: 845 uiParam = max(uiParam, 1); 846 return SpiSetInt(&gspv.ncm.iBorderWidth, uiParam, KEY_METRIC, VAL_BORDER, fl); 847 848 case SPI_GETKEYBOARDSPEED: 849 return SpiGetInt(pvParam, &gspv.dwKbdSpeed, fl); 850 851 case SPI_SETKEYBOARDSPEED: 852 return SpiSetInt(&gspv.dwKbdSpeed, uiParam, KEY_KBD, VAL_KBDSPD, fl); 853 854 case SPI_LANGDRIVER: 855 ERR("SPI_LANGDRIVER is unimplemented\n"); 856 break; 857 858 case SPI_GETSCREENSAVETIMEOUT: 859 return SpiGetInt(pvParam, &gspv.iScrSaverTimeout, fl); 860 861 case SPI_SETSCREENSAVETIMEOUT: 862 return SpiSetInt(&gspv.iScrSaverTimeout, uiParam, KEY_DESKTOP, VAL_SCRTO, fl); 863 864 case SPI_GETSCREENSAVEACTIVE: 865 return SpiGetInt(pvParam, &gspv.bScrSaverActive, fl); 866 867 case SPI_SETSCREENSAVEACTIVE: 868 return SpiSetInt(&gspv.bScrSaverActive, uiParam, KEY_DESKTOP, VAL_SCRACT, fl); 869 870 case SPI_GETGRIDGRANULARITY: 871 return SpiGetInt(pvParam, &gspv.uiGridGranularity, fl); 872 873 case SPI_SETGRIDGRANULARITY: 874 return SpiSetInt(&gspv.uiGridGranularity, uiParam, KEY_DESKTOP, VAL_GRID, fl); 875 876 case SPI_GETDESKWALLPAPER: 877 uiParam = min(uiParam, gspv.ustrWallpaper.Length + 1UL); 878 return SpiGet(pvParam, gspv.awcWallpaper, uiParam, fl); 879 880 case SPI_SETDESKWALLPAPER: 881 return SpiSetWallpaper(pvParam, fl); 882 883 case SPI_SETDESKPATTERN: 884 ERR("SPI_SETDESKPATTERN is unimplemented\n"); 885 break; 886 887 case SPI_GETKEYBOARDDELAY: 888 return SpiGetInt(pvParam, &gspv.iKbdDelay, fl); 889 890 case SPI_SETKEYBOARDDELAY: 891 return SpiSetInt(&gspv.iKbdDelay, uiParam, KEY_KBD, VAL_KBDDELAY, fl); 892 893 case SPI_ICONHORIZONTALSPACING: 894 if (pvParam) 895 { 896 return SpiGetInt(pvParam, &gspv.im.iHorzSpacing, fl); 897 } 898 uiParam = max(uiParam, 32); 899 return SpiSetMetric(&gspv.im.iHorzSpacing, uiParam, VAL_ICONSPC, fl); 900 901 case SPI_ICONVERTICALSPACING: 902 if (pvParam) 903 { 904 return SpiGetInt(pvParam, &gspv.im.iVertSpacing, fl); 905 } 906 uiParam = max(uiParam, 32); 907 return SpiSetMetric(&gspv.im.iVertSpacing, uiParam, VAL_ICONVSPC, fl); 908 909 case SPI_GETICONTITLEWRAP: 910 return SpiGetInt(pvParam, &gspv.im.iTitleWrap, fl); 911 912 case SPI_SETICONTITLEWRAP: 913 return SpiSetInt(&gspv.im.iTitleWrap, uiParam, KEY_METRIC, VAL_ITWRAP, fl); 914 915 case SPI_GETMENUDROPALIGNMENT: 916 return SpiGetInt(pvParam, &gspv.bMenuDropAlign, fl); 917 918 case SPI_SETMENUDROPALIGNMENT: 919 return SpiSetBool(&gspv.bMenuDropAlign, uiParam, KEY_MDALIGN, VAL_MDALIGN, fl); 920 921 case SPI_SETDOUBLECLKWIDTH: 922 return SpiSetInt(&gspv.iDblClickWidth, uiParam, KEY_MOUSE, VAL_DBLCLKWIDTH, fl); 923 924 case SPI_SETDOUBLECLKHEIGHT: 925 return SpiSetInt(&gspv.iDblClickHeight, uiParam, KEY_MOUSE, VAL_DBLCLKHEIGHT, fl); 926 927 case SPI_GETICONTITLELOGFONT: 928 return SpiGet(pvParam, &gspv.im.lfFont, sizeof(LOGFONTW), fl); 929 930 case SPI_SETICONTITLELOGFONT: 931 if (!SpiSet(&gspv.im.lfFont, pvParam, sizeof(LOGFONTW), fl)) 932 return 0; 933 if (fl & SPIF_UPDATEINIFILE) 934 { 935 SpiStoreFont(L"IconFont", &gspv.im.lfFont); 936 } 937 return (UINT_PTR)KEY_METRIC; 938 939 case SPI_SETDOUBLECLICKTIME: 940 return SpiSetInt(&gspv.iDblClickTime, uiParam, KEY_MOUSE, VAL_DBLCLKTIME, fl); 941 942 case SPI_SETMOUSEBUTTONSWAP: 943 return SpiSetInt(&gspv.bMouseBtnSwap, uiParam, KEY_MOUSE, VAL_SWAP, fl); 944 945 case SPI_GETFASTTASKSWITCH: 946 return SpiGetInt(pvParam, &gspv.bFastTaskSwitch, fl); 947 948 case SPI_SETFASTTASKSWITCH: 949 /* According to Winetest this one is unimplemented */ 950 return 1; 951 952 case SPI_GETDRAGFULLWINDOWS: 953 return SpiGetInt(pvParam, &gspv.bDragFullWindows, fl); 954 955 case SPI_SETDRAGFULLWINDOWS: 956 return SpiSetInt(&gspv.bDragFullWindows, uiParam, KEY_DESKTOP, VAL_DRAG, fl); 957 958 case SPI_GETNONCLIENTMETRICS: 959 { 960 return SpiGet(pvParam, &gspv.ncm, sizeof(NONCLIENTMETRICSW), fl); 961 } 962 963 case SPI_SETNONCLIENTMETRICS: 964 { 965 LPNONCLIENTMETRICSW metrics = (LPNONCLIENTMETRICSW)pvParam; 966 967 /* Fixup user's structure size */ 968 metrics->cbSize = sizeof(NONCLIENTMETRICSW); 969 970 if (!SpiSet(&gspv.ncm, metrics, sizeof(NONCLIENTMETRICSW), fl)) 971 return 0; 972 973 if (fl & SPIF_UPDATEINIFILE) 974 { 975 SpiStoreMetric(VAL_BORDER, gspv.ncm.iBorderWidth); 976 SpiStoreMetric(L"ScrollWidth", gspv.ncm.iScrollWidth); 977 SpiStoreMetric(L"ScrollHeight", gspv.ncm.iScrollHeight); 978 SpiStoreMetric(L"CaptionWidth", gspv.ncm.iCaptionWidth); 979 SpiStoreMetric(L"CaptionHeight", gspv.ncm.iCaptionHeight); 980 SpiStoreMetric(L"SmCaptionWidth", gspv.ncm.iSmCaptionWidth); 981 SpiStoreMetric(L"SmCaptionHeight", gspv.ncm.iSmCaptionHeight); 982 SpiStoreMetric(L"MenuWidth", gspv.ncm.iMenuWidth); 983 SpiStoreMetric(L"MenuHeight", gspv.ncm.iMenuHeight); 984 #if (WINVER >= 0x0600) 985 SpiStoreMetric(L"PaddedBorderWidth", gspv.ncm.iPaddedBorderWidth); 986 #endif 987 SpiStoreFont(L"CaptionFont", &gspv.ncm.lfCaptionFont); 988 SpiStoreFont(L"SmCaptionFont", &gspv.ncm.lfSmCaptionFont); 989 SpiStoreFont(L"MenuFont", &gspv.ncm.lfMenuFont); 990 SpiStoreFont(L"StatusFont", &gspv.ncm.lfStatusFont); 991 SpiStoreFont(L"MessageFont", &gspv.ncm.lfMessageFont); 992 } 993 994 if(!SpiNotifyNCMetricsChanged()) 995 return 0; 996 997 return (UINT_PTR)KEY_METRIC; 998 } 999 1000 case SPI_GETMINIMIZEDMETRICS: 1001 { 1002 return SpiGet(pvParam, &gspv.mm, sizeof(MINIMIZEDMETRICS), fl); 1003 } 1004 1005 case SPI_SETMINIMIZEDMETRICS: 1006 { 1007 LPMINIMIZEDMETRICS metrics = (LPMINIMIZEDMETRICS)pvParam; 1008 1009 /* Fixup user's structure size */ 1010 metrics->cbSize = sizeof(MINIMIZEDMETRICS); 1011 1012 if (!SpiSet(&gspv.mm, metrics, sizeof(MINIMIZEDMETRICS), fl)) 1013 return 0; 1014 1015 gspv.mm.iWidth = max(0, gspv.mm.iWidth); 1016 gspv.mm.iHorzGap = max(0, gspv.mm.iHorzGap); 1017 gspv.mm.iVertGap = max(0, gspv.mm.iVertGap); 1018 gspv.mm.iArrange = gspv.mm.iArrange & 0xf; 1019 1020 if (fl & SPIF_UPDATEINIFILE) 1021 { 1022 SpiStoreMetric(L"MinWidth", gspv.mm.iWidth); 1023 SpiStoreMetric(L"MinHorzGap", gspv.mm.iHorzGap); 1024 SpiStoreMetric(L"MinVertGap", gspv.mm.iVertGap); 1025 SpiStoreMetric(L"MinArrange", gspv.mm.iArrange); 1026 } 1027 1028 return (UINT_PTR)KEY_METRIC; 1029 } 1030 1031 case SPI_GETICONMETRICS: 1032 { 1033 return SpiGet(pvParam, &gspv.im, sizeof(ICONMETRICSW), fl); 1034 } 1035 1036 case SPI_SETICONMETRICS: 1037 { 1038 LPICONMETRICSW metrics = (LPICONMETRICSW)pvParam; 1039 1040 /* Fixup user's structure size */ 1041 metrics->cbSize = sizeof(ICONMETRICSW); 1042 1043 if (!SpiSet(&gspv.im, metrics, sizeof(ICONMETRICSW), fl)) 1044 return 0; 1045 1046 if (fl & SPIF_UPDATEINIFILE) 1047 { 1048 SpiStoreMetric(VAL_ICONSPC, gspv.im.iHorzSpacing); 1049 SpiStoreMetric(VAL_ICONVSPC, gspv.im.iVertSpacing); 1050 SpiStoreMetric(VAL_ITWRAP, gspv.im.iTitleWrap); 1051 SpiStoreFont(L"IconFont", &gspv.im.lfFont); 1052 } 1053 return (UINT_PTR)KEY_METRIC; 1054 } 1055 1056 case SPI_GETWORKAREA: 1057 { 1058 PMONITOR pmonitor = UserGetPrimaryMonitor(); 1059 1060 if(!pmonitor) 1061 return 0; 1062 1063 return SpiGet(pvParam, &pmonitor->rcWork, sizeof(RECTL), fl); 1064 } 1065 1066 case SPI_SETWORKAREA: 1067 { 1068 PMONITOR pmonitor; 1069 RECTL rcWorkArea, rcIntersect; 1070 1071 if (!pvParam) 1072 return 0; 1073 1074 RtlCopyMemory(&rcWorkArea, pvParam, sizeof(rcWorkArea)); 1075 1076 /* fail if empty */ 1077 if (RECTL_bIsEmptyRect(&rcWorkArea)) 1078 return 0; 1079 1080 /* get the nearest monitor */ 1081 pmonitor = UserMonitorFromRect(&rcWorkArea, MONITOR_DEFAULTTONEAREST); 1082 if (!pmonitor) 1083 return 0; 1084 1085 /* fail unless work area is completely in monitor */ 1086 if (!RECTL_bIntersectRect(&rcIntersect, &pmonitor->rcMonitor, &rcWorkArea) || 1087 !RtlEqualMemory(&rcIntersect, &rcWorkArea, sizeof(rcIntersect))) 1088 { 1089 return 0; 1090 } 1091 1092 if (!SpiSet(&pmonitor->rcWork, pvParam, sizeof(RECTL), fl)) 1093 return 0; 1094 1095 if (fl & SPIF_UPDATEINIFILE) 1096 { 1097 // FIXME: What to do? 1098 } 1099 return (UINT_PTR)KEY_DESKTOP; 1100 } 1101 1102 case SPI_SETPENWINDOWS: 1103 ERR("SPI_SETPENWINDOWS is unimplemented\n"); 1104 break; 1105 1106 case SPI_GETFILTERKEYS: 1107 { 1108 LPFILTERKEYS FilterKeys = (LPFILTERKEYS)pvParam; 1109 1110 if (uiParam != 0 && uiParam != sizeof(FILTERKEYS)) 1111 return 0; 1112 1113 if (!FilterKeys || FilterKeys->cbSize != sizeof(FILTERKEYS)) 1114 return 0; 1115 1116 return SpiGet(pvParam, &gspv.filterkeys, sizeof(FILTERKEYS), fl); 1117 } 1118 1119 case SPI_SETFILTERKEYS: 1120 { 1121 LPFILTERKEYS FilterKeys = (LPFILTERKEYS)pvParam; 1122 1123 if (uiParam != 0 && uiParam != sizeof(FILTERKEYS)) 1124 return 0; 1125 1126 if (!FilterKeys || FilterKeys->cbSize != sizeof(FILTERKEYS)) 1127 return 0; 1128 1129 if (!SpiSet(&gspv.filterkeys, pvParam, sizeof(FILTERKEYS), fl)) 1130 return 0; 1131 1132 if (fl & SPIF_UPDATEINIFILE) 1133 { 1134 // FIXME: What to do? 1135 } 1136 return (UINT_PTR)KEY_DESKTOP; 1137 } 1138 1139 case SPI_GETTOGGLEKEYS: 1140 { 1141 LPTOGGLEKEYS ToggleKeys = (LPTOGGLEKEYS)pvParam; 1142 1143 if (uiParam != 0 && uiParam != sizeof(TOGGLEKEYS)) 1144 return 0; 1145 1146 if (!ToggleKeys || ToggleKeys->cbSize != sizeof(TOGGLEKEYS)) 1147 return 0; 1148 1149 return SpiGet(pvParam, &gspv.togglekeys, sizeof(TOGGLEKEYS), fl); 1150 } 1151 1152 case SPI_SETTOGGLEKEYS: 1153 { 1154 LPTOGGLEKEYS ToggleKeys = (LPTOGGLEKEYS)pvParam; 1155 1156 if (uiParam != 0 && uiParam != sizeof(TOGGLEKEYS)) 1157 return 0; 1158 1159 if (!ToggleKeys || ToggleKeys->cbSize != sizeof(TOGGLEKEYS)) 1160 return 0; 1161 1162 if (!SpiSet(&gspv.togglekeys, pvParam, sizeof(TOGGLEKEYS), fl)) 1163 return 0; 1164 1165 if (fl & SPIF_UPDATEINIFILE) 1166 { 1167 // FIXME: What to do? 1168 } 1169 return (UINT_PTR)KEY_DESKTOP; 1170 } 1171 1172 case SPI_GETMOUSEKEYS: 1173 { 1174 LPMOUSEKEYS MouseKeys = (LPMOUSEKEYS)pvParam; 1175 1176 if (uiParam != 0 && uiParam != sizeof(MOUSEKEYS)) 1177 return 0; 1178 1179 if (!MouseKeys || MouseKeys->cbSize != sizeof(MOUSEKEYS)) 1180 return 0; 1181 1182 return SpiGet(pvParam, &gspv.mousekeys, sizeof(MOUSEKEYS), fl); 1183 } 1184 1185 case SPI_SETMOUSEKEYS: 1186 { 1187 LPMOUSEKEYS MouseKeys = (LPMOUSEKEYS)pvParam; 1188 1189 if (uiParam != 0 && uiParam != sizeof(MOUSEKEYS)) 1190 return 0; 1191 1192 if (!MouseKeys || MouseKeys->cbSize != sizeof(MOUSEKEYS)) 1193 return 0; 1194 1195 if (!SpiSet(&gspv.mousekeys, pvParam, sizeof(MOUSEKEYS), fl)) 1196 return 0; 1197 1198 if (fl & SPIF_UPDATEINIFILE) 1199 { 1200 // FIXME: What to do? 1201 } 1202 return (UINT_PTR)KEY_DESKTOP; 1203 } 1204 1205 case SPI_GETSHOWSOUNDS: 1206 return SpiGetInt(pvParam, &gspv.bShowSounds, fl); 1207 1208 case SPI_SETSHOWSOUNDS: 1209 return SpiSetBool(&gspv.bShowSounds, uiParam, KEY_SHOWSNDS, VAL_ON, fl); 1210 1211 case SPI_GETSTICKYKEYS: 1212 { 1213 LPSTICKYKEYS StickyKeys = (LPSTICKYKEYS)pvParam; 1214 1215 if (uiParam != 0 && uiParam != sizeof(STICKYKEYS)) 1216 return 0; 1217 1218 if (!StickyKeys || StickyKeys->cbSize != sizeof(STICKYKEYS)) 1219 return 0; 1220 1221 return SpiGetEx(pvParam, &gspv.stickykeys, sizeof(STICKYKEYS), fl); 1222 } 1223 1224 case SPI_SETSTICKYKEYS: 1225 { 1226 LPSTICKYKEYS StickyKeys = (LPSTICKYKEYS)pvParam; 1227 1228 if (uiParam != 0 && uiParam != sizeof(STICKYKEYS)) 1229 return 0; 1230 1231 if (!StickyKeys || StickyKeys->cbSize != sizeof(STICKYKEYS)) 1232 return 0; 1233 1234 if (!SpiSet(&gspv.stickykeys, pvParam, sizeof(STICKYKEYS), fl)) 1235 return 0; 1236 1237 if (fl & SPIF_UPDATEINIFILE) 1238 { 1239 // FIXME: What to do? 1240 } 1241 return (UINT_PTR)KEY_DESKTOP; 1242 } 1243 1244 case SPI_GETACCESSTIMEOUT: 1245 { 1246 LPACCESSTIMEOUT AccessTimeout = (LPACCESSTIMEOUT)pvParam; 1247 1248 if (uiParam != 0 && uiParam != sizeof(ACCESSTIMEOUT)) 1249 return 0; 1250 1251 if (!AccessTimeout || AccessTimeout->cbSize != sizeof(ACCESSTIMEOUT)) 1252 return 0; 1253 1254 return SpiGetEx(pvParam, &gspv.accesstimeout, sizeof(ACCESSTIMEOUT), fl); 1255 } 1256 1257 case SPI_SETACCESSTIMEOUT: 1258 { 1259 LPACCESSTIMEOUT AccessTimeout = (LPACCESSTIMEOUT)pvParam; 1260 1261 if (uiParam != 0 && uiParam != sizeof(ACCESSTIMEOUT)) 1262 { 1263 return 0; 1264 } 1265 1266 if (!AccessTimeout || AccessTimeout->cbSize != sizeof(ACCESSTIMEOUT)) 1267 { 1268 return 0; 1269 } 1270 1271 if (!SpiSet(&gspv.accesstimeout, pvParam, sizeof(ACCESSTIMEOUT), fl)) 1272 return 0; 1273 1274 if (fl & SPIF_UPDATEINIFILE) 1275 { 1276 // FIXME: What to do? 1277 } 1278 return (UINT_PTR)KEY_DESKTOP; 1279 } 1280 1281 case SPI_GETSERIALKEYS: 1282 { 1283 LPSERIALKEYS SerialKeys = (LPSERIALKEYS)pvParam; 1284 1285 if (uiParam != 0 && uiParam != sizeof(SERIALKEYS)) 1286 return 0; 1287 1288 if (!SerialKeys || SerialKeys->cbSize != sizeof(SERIALKEYS)) 1289 return 0; 1290 1291 return SpiGet(pvParam, &gspv.serialkeys, sizeof(SERIALKEYS), fl); 1292 } 1293 1294 case SPI_SETSERIALKEYS: 1295 { 1296 LPSERIALKEYS SerialKeys = (LPSERIALKEYS)pvParam; 1297 1298 if (uiParam != 0 && uiParam != sizeof(SERIALKEYS)) 1299 return 0; 1300 1301 if (!SerialKeys || SerialKeys->cbSize != sizeof(SERIALKEYS)) 1302 return 0; 1303 1304 if (!SpiSet(&gspv.serialkeys, pvParam, sizeof(SERIALKEYS), fl)) 1305 return 0; 1306 1307 if (fl & SPIF_UPDATEINIFILE) 1308 { 1309 // FIXME: What to do? 1310 } 1311 return (UINT_PTR)KEY_DESKTOP; 1312 } 1313 1314 case SPI_GETSOUNDSENTRY: 1315 { 1316 LPSOUNDSENTRYW SoundsEntry = (LPSOUNDSENTRYW)pvParam; 1317 1318 if (uiParam != 0 && uiParam != sizeof(SOUNDSENTRYW)) 1319 return 0; 1320 1321 if (!SoundsEntry || SoundsEntry->cbSize != sizeof(SOUNDSENTRYW)) 1322 return 0; 1323 1324 return SpiGet(pvParam, &gspv.soundsentry, sizeof(SOUNDSENTRYW), fl); 1325 } 1326 1327 case SPI_SETSOUNDSENTRY: 1328 { 1329 LPSOUNDSENTRYW SoundsEntry = (LPSOUNDSENTRYW)pvParam; 1330 1331 if (uiParam != 0 && uiParam != sizeof(SOUNDSENTRYW)) 1332 return 0; 1333 1334 if (!SoundsEntry || SoundsEntry->cbSize != sizeof(SOUNDSENTRYW)) 1335 return 0; 1336 1337 if (!SpiSet(&gspv.soundsentry, pvParam, sizeof(SOUNDSENTRYW), fl)) 1338 return 0; 1339 1340 if (fl & SPIF_UPDATEINIFILE) 1341 { 1342 // FIXME: What to do? 1343 } 1344 return (UINT_PTR)KEY_DESKTOP; 1345 } 1346 1347 case SPI_GETHIGHCONTRAST: 1348 { 1349 LPHIGHCONTRASTW highcontrast = (LPHIGHCONTRASTW)pvParam; 1350 1351 if (uiParam != 0 && uiParam != sizeof(HIGHCONTRASTW)) 1352 return 0; 1353 1354 if (!highcontrast || highcontrast->cbSize != sizeof(HIGHCONTRASTW)) 1355 return 0; 1356 1357 return SpiGet(pvParam, &gspv.highcontrast, sizeof(HIGHCONTRASTW), fl); 1358 } 1359 1360 case SPI_SETHIGHCONTRAST: 1361 { 1362 LPHIGHCONTRASTW highcontrast = (LPHIGHCONTRASTW)pvParam; 1363 1364 if (uiParam != 0 && uiParam != sizeof(HIGHCONTRASTW)) 1365 return 0; 1366 1367 if (!highcontrast || highcontrast->cbSize != sizeof(HIGHCONTRASTW)) 1368 return 0; 1369 1370 if (!SpiSet(&gspv.highcontrast, pvParam, sizeof(HIGHCONTRASTW), fl)) 1371 return 0; 1372 1373 if (fl & SPIF_UPDATEINIFILE) 1374 { 1375 // FIXME: What to do? 1376 } 1377 return (UINT_PTR)KEY_DESKTOP; 1378 } 1379 1380 case SPI_GETKEYBOARDPREF: 1381 return SpiGetInt(pvParam, &gspv.bKbdPref, fl); 1382 1383 case SPI_SETKEYBOARDPREF: 1384 return SpiSetBool(&gspv.bKbdPref, uiParam, KEY_KDBPREF, VAL_ON, fl); 1385 1386 case SPI_GETSCREENREADER: 1387 return SpiGetInt(pvParam, &gspv.bScreenReader, fl); 1388 1389 case SPI_SETSCREENREADER: 1390 return SpiSetBool(&gspv.bScreenReader, uiParam, KEY_SCRREAD, VAL_ON, fl); 1391 1392 case SPI_GETANIMATION: 1393 return SpiGet(pvParam, &gspv.animationinfo, sizeof(ANIMATIONINFO), fl); 1394 1395 case SPI_SETANIMATION: 1396 if (!SpiSet(&gspv.animationinfo, pvParam, sizeof(ANIMATIONINFO), fl)) 1397 return 0; 1398 if (fl & SPIF_UPDATEINIFILE) 1399 { 1400 // FIXME: What to do? 1401 } 1402 return (UINT_PTR)KEY_DESKTOP; 1403 1404 case SPI_GETFONTSMOOTHING: 1405 return SpiGetInt(pvParam, &gspv.bFontSmoothing, fl); 1406 1407 case SPI_SETFONTSMOOTHING: 1408 gspv.bFontSmoothing = !!uiParam; 1409 if (fl & SPIF_UPDATEINIFILE) 1410 { 1411 SpiStoreSzInt(KEY_DESKTOP, VAL_FONTSMOOTHING, gspv.bFontSmoothing ? 2 : 0); 1412 } 1413 return (UINT_PTR)KEY_DESKTOP; 1414 1415 case SPI_SETDRAGWIDTH: 1416 return SpiSetInt(&gspv.iDragWidth, uiParam, KEY_DESKTOP, VAL_DRAGWIDTH, fl); 1417 1418 case SPI_SETDRAGHEIGHT: 1419 return SpiSetInt(&gspv.iDragHeight, uiParam, KEY_DESKTOP, VAL_DRAGHEIGHT, fl); 1420 1421 case SPI_SETHANDHELD: 1422 return SpiSetBool(&gspv.bHandHeld, uiParam, KEY_DESKTOP, L"HandHeld", fl); 1423 1424 case SPI_GETLOWPOWERTIMEOUT: 1425 return SpiGetInt(pvParam, &gspv.iLowPwrTimeout, fl); 1426 1427 case SPI_GETPOWEROFFTIMEOUT: 1428 return SpiGetInt(pvParam, &gspv.iPwrOffTimeout, fl); 1429 1430 case SPI_SETLOWPOWERTIMEOUT: 1431 return SpiSetInt(&gspv.iLowPwrTimeout, uiParam, KEY_DESKTOP, L"LowPowerTimeOut", fl); 1432 1433 case SPI_SETPOWEROFFTIMEOUT: 1434 return SpiSetInt(&gspv.iPwrOffTimeout, uiParam, KEY_DESKTOP, L"PowerOffTimeOut", fl); 1435 1436 case SPI_GETLOWPOWERACTIVE: 1437 return SpiGetInt(pvParam, &gspv.iPwrOffTimeout, fl); 1438 1439 case SPI_GETPOWEROFFACTIVE: 1440 return SpiGetInt(pvParam, &gspv.bPwrOffActive, fl); 1441 1442 case SPI_SETLOWPOWERACTIVE: 1443 return SpiSetBool(&gspv.bLowPwrActive, uiParam, KEY_DESKTOP, L"LowPowerActive", fl); 1444 1445 case SPI_SETPOWEROFFACTIVE: 1446 return SpiSetBool(&gspv.bPwrOffActive, uiParam, KEY_DESKTOP, L"PowerOffActive", fl); 1447 1448 case SPI_SETCURSORS: 1449 ERR("SPI_SETCURSORS is unimplemented\n"); 1450 break; 1451 1452 case SPI_SETICONS: 1453 ERR("SPI_SETICONS is unimplemented\n"); 1454 break; 1455 1456 case SPI_GETDEFAULTINPUTLANG: 1457 if (!gspklBaseLayout) 1458 return FALSE; 1459 1460 return SpiGet(pvParam, &gspklBaseLayout->hkl, sizeof(HKL), fl); 1461 1462 case SPI_SETDEFAULTINPUTLANG: 1463 { 1464 HKL hkl; 1465 1466 /* Note: SPIF_UPDATEINIFILE is not supported */ 1467 if ((fl & SPIF_UPDATEINIFILE) || !SpiSet(&hkl, pvParam, sizeof(hkl), fl)) 1468 return FALSE; 1469 1470 return UserSetDefaultInputLang(hkl); 1471 } 1472 1473 case SPI_SETLANGTOGGLE: 1474 gdwLayoutToggleKey = UserGetLanguageToggle(L"Layout Hotkey", 2); 1475 gdwLanguageToggleKey = UserGetLanguageToggle(L"Language Hotkey", 1); 1476 return gdwLanguageToggleKey; 1477 1478 case SPI_GETWINDOWSEXTENSION: 1479 ERR("SPI_GETWINDOWSEXTENSION is unimplemented\n"); 1480 break; 1481 1482 case SPI_GETMOUSETRAILS: 1483 return SpiGetInt(pvParam, &gspv.iMouseTrails, fl); 1484 1485 case SPI_SETMOUSETRAILS: 1486 return SpiSetInt(&gspv.iMouseTrails, uiParam, KEY_MOUSE, VAL_MOUSETRAILS, fl); 1487 1488 case SPI_GETSNAPTODEFBUTTON: 1489 return SpiGetInt(pvParam, &gspv.bSnapToDefBtn, fl); 1490 1491 case SPI_SETSNAPTODEFBUTTON: 1492 return SpiSetBool(&gspv.bSnapToDefBtn, uiParam, KEY_MOUSE, VAL_SNAPDEFBTN, fl); 1493 1494 case SPI_GETMOUSEHOVERWIDTH: 1495 return SpiGetInt(pvParam, &gspv.iMouseHoverWidth, fl); 1496 1497 case SPI_SETMOUSEHOVERWIDTH: 1498 return SpiSetInt(&gspv.iMouseHoverWidth, uiParam, KEY_MOUSE, VAL_HOVERWIDTH, fl); 1499 1500 case SPI_GETMOUSEHOVERHEIGHT: 1501 return SpiGetInt(pvParam, &gspv.iMouseHoverHeight, fl); 1502 1503 case SPI_SETMOUSEHOVERHEIGHT: 1504 return SpiSetInt(&gspv.iMouseHoverHeight, uiParam, KEY_MOUSE, VAL_HOVERHEIGHT, fl); 1505 1506 case SPI_GETMOUSEHOVERTIME: 1507 return SpiGetInt(pvParam, &gspv.iMouseHoverTime, fl); 1508 1509 case SPI_SETMOUSEHOVERTIME: 1510 /* See http://msdn2.microsoft.com/en-us/library/ms724947.aspx 1511 * copy text from it, if some agument why xp and 2003 behovir diffent 1512 * only if they do not have SP install 1513 * " Windows Server 2003 and Windows XP: The operating system does not 1514 * enforce the use of USER_TIMER_MAXIMUM and USER_TIMER_MINIMUM until 1515 * Windows Server 2003 SP1 and Windows XP SP2 " 1516 */ 1517 return SpiSetInt(&gspv.iMouseHoverTime, uiParam, KEY_MOUSE, VAL_HOVERTIME, fl); 1518 1519 case SPI_GETWHEELSCROLLLINES: 1520 return SpiGetInt(pvParam, &gspv.iWheelScrollLines, fl); 1521 1522 case SPI_SETWHEELSCROLLLINES: 1523 return SpiSetInt(&gspv.iWheelScrollLines, uiParam, KEY_DESKTOP, VAL_SCRLLLINES, fl); 1524 1525 case SPI_GETMENUSHOWDELAY: 1526 return SpiGetInt(pvParam, &gspv.dwMenuShowDelay, fl); 1527 1528 case SPI_SETMENUSHOWDELAY: 1529 return SpiSetInt(&gspv.dwMenuShowDelay, uiParam, KEY_DESKTOP, L"MenuShowDelay", fl); 1530 1531 #if (_WIN32_WINNT >= 0x0600) 1532 case SPI_GETWHEELSCROLLCHARS: 1533 return SpiGetInt(pvParam, &gspv.uiWheelScrollChars, fl); 1534 1535 case SPI_SETWHEELSCROLLCHARS: 1536 return SpiSetInt(&gspv.uiWheelScrollChars, uiParam, KEY_DESKTOP, VAL_SCRLLCHARS, fl); 1537 #endif 1538 case SPI_GETSHOWIMEUI: 1539 return SpiGetInt(pvParam, &gspv.bShowImeUi, fl); 1540 1541 case SPI_SETSHOWIMEUI: 1542 return SpiSetBool(&gspv.bShowImeUi, uiParam, KEY_DESKTOP, L"", fl); 1543 1544 case SPI_GETMOUSESPEED: 1545 return SpiGetInt(pvParam, &gspv.iMouseSpeed, fl); 1546 1547 case SPI_SETMOUSESPEED: 1548 { 1549 /* Allowed range is [1:20] */ 1550 if ((INT_PTR)pvParam < 1 || (INT_PTR)pvParam > 20) 1551 return 0; 1552 else 1553 return SpiSetInt(&gspv.iMouseSpeed, (INT_PTR)pvParam, KEY_MOUSE, VAL_SENSITIVITY, fl); 1554 } 1555 1556 case SPI_GETSCREENSAVERRUNNING: 1557 return SpiGetInt(pvParam, &gspv.bScrSaverRunning, fl); 1558 1559 case SPI_SETSCREENSAVERRUNNING: 1560 // FIXME: also return value? 1561 return SpiSetBool(&gspv.bScrSaverRunning, uiParam, KEY_MOUSE, L"", fl); 1562 1563 #if(WINVER >= 0x0600) 1564 case SPI_GETAUDIODESCRIPTION: 1565 return SpiGet(pvParam, &gspv.audiodescription, sizeof(AUDIODESCRIPTION), fl); 1566 1567 case SPI_SETAUDIODESCRIPTION: 1568 ERR("SPI_SETAUDIODESCRIPTION is unimplemented\n"); 1569 break; 1570 1571 case SPI_GETSCREENSAVESECURE: 1572 return SpiGetInt(pvParam, &gspv.bScrSaverSecure, fl); 1573 1574 case SPI_SETSCREENSAVESECURE: 1575 return SpiSetBool(&gspv.bScrSaverSecure, uiParam, KEY_DESKTOP, L"ScreenSaverIsSecure", fl); 1576 #endif 1577 1578 case SPI_GETACTIVEWINDOWTRACKING: 1579 return SpiGetUserPref(UPM_ACTIVEWINDOWTRACKING, pvParam, fl); 1580 1581 case SPI_SETACTIVEWINDOWTRACKING: 1582 return SpiSetUserPref(UPM_ACTIVEWINDOWTRACKING, pvParam, fl); 1583 1584 case SPI_GETMENUANIMATION: 1585 return SpiGetUserPref(UPM_MENUANIMATION, pvParam, fl); 1586 1587 case SPI_SETMENUANIMATION: 1588 return SpiSetUserPref(UPM_MENUANIMATION, pvParam, fl); 1589 1590 case SPI_GETCOMBOBOXANIMATION: 1591 return SpiGetUserPref(UPM_COMBOBOXANIMATION, pvParam, fl); 1592 1593 case SPI_SETCOMBOBOXANIMATION: 1594 return SpiSetUserPref(UPM_COMBOBOXANIMATION, pvParam, fl); 1595 1596 case SPI_GETLISTBOXSMOOTHSCROLLING: 1597 return SpiGetUserPref(UPM_LISTBOXSMOOTHSCROLLING, pvParam, fl); 1598 1599 case SPI_SETLISTBOXSMOOTHSCROLLING: 1600 return SpiSetUserPref(UPM_LISTBOXSMOOTHSCROLLING, pvParam, fl); 1601 1602 case SPI_GETGRADIENTCAPTIONS: 1603 { 1604 if (NtGdiGetDeviceCaps(ScreenDeviceContext, BITSPIXEL) <= 8) 1605 { 1606 INT iValue = 0; 1607 return SpiGetInt(pvParam, &iValue, fl); 1608 } 1609 else 1610 { 1611 return SpiGetUserPref(UPM_GRADIENTCAPTIONS, pvParam, fl); 1612 } 1613 } 1614 1615 case SPI_SETGRADIENTCAPTIONS: 1616 return SpiSetUserPref(UPM_GRADIENTCAPTIONS, pvParam, fl); 1617 1618 case SPI_GETKEYBOARDCUES: 1619 return SpiGetUserPref(UPM_KEYBOARDCUES, pvParam, fl); 1620 1621 case SPI_SETKEYBOARDCUES: 1622 return SpiSetUserPref(UPM_KEYBOARDCUES, pvParam, fl); 1623 1624 case SPI_GETACTIVEWNDTRKZORDER: 1625 return SpiGetUserPref(UPM_ACTIVEWNDTRKZORDER, pvParam, fl); 1626 1627 case SPI_SETACTIVEWNDTRKZORDER: 1628 return SpiSetUserPref(UPM_ACTIVEWNDTRKZORDER, pvParam, fl); 1629 1630 case SPI_GETHOTTRACKING: 1631 return SpiGetUserPref(UPM_HOTTRACKING, pvParam, fl); 1632 1633 case SPI_SETHOTTRACKING: 1634 return SpiSetUserPref(UPM_HOTTRACKING, pvParam, fl); 1635 1636 case SPI_GETMENUFADE: 1637 return SpiGetUserPref(UPM_MENUFADE, pvParam, fl); 1638 1639 case SPI_SETMENUFADE: 1640 return SpiSetUserPref(UPM_MENUFADE, pvParam, fl); 1641 1642 case SPI_GETSELECTIONFADE: 1643 return SpiGetUserPref(UPM_SELECTIONFADE, pvParam, fl); 1644 1645 case SPI_SETSELECTIONFADE: 1646 return SpiSetUserPref(UPM_SELECTIONFADE, pvParam, fl); 1647 1648 case SPI_GETTOOLTIPANIMATION: 1649 return SpiGetUserPref(UPM_TOOLTIPANIMATION, pvParam, fl); 1650 1651 case SPI_SETTOOLTIPANIMATION: 1652 return SpiSetUserPref(UPM_TOOLTIPANIMATION, pvParam, fl); 1653 1654 case SPI_GETTOOLTIPFADE: 1655 return SpiGetUserPref(UPM_TOOLTIPFADE, pvParam, fl); 1656 1657 case SPI_SETTOOLTIPFADE: 1658 return SpiSetUserPref(UPM_TOOLTIPFADE, pvParam, fl); 1659 1660 case SPI_GETCURSORSHADOW: 1661 return SpiGetUserPref(UPM_CURSORSHADOW, pvParam, fl); 1662 1663 case SPI_SETCURSORSHADOW: 1664 gspv.bMouseCursorShadow = PtrToUlong(pvParam); 1665 return SpiSetUserPref(UPM_CURSORSHADOW, pvParam, fl); 1666 1667 case SPI_GETUIEFFECTS: 1668 return SpiGetUserPref(UPM_UIEFFECTS, pvParam, fl); 1669 1670 case SPI_SETUIEFFECTS: 1671 return SpiSetUserPref(UPM_UIEFFECTS, pvParam, fl); 1672 1673 case SPI_GETMOUSESONAR: 1674 return SpiGetInt(pvParam, &gspv.bMouseSonar, fl); 1675 1676 case SPI_SETMOUSESONAR: 1677 return SpiSetBool(&gspv.bMouseSonar, uiParam, KEY_MOUSE, L"", fl); 1678 1679 case SPI_GETMOUSECLICKLOCK: 1680 return SpiGetUserPref(UPM_CLICKLOCK, pvParam, fl); 1681 1682 case SPI_SETMOUSECLICKLOCK: 1683 gspv.bMouseClickLock = PtrToUlong(pvParam); 1684 return SpiSetUserPref(UPM_CLICKLOCK, pvParam, fl); 1685 1686 case SPI_GETMOUSEVANISH: 1687 return SpiGetInt(pvParam, &gspv.bMouseVanish, fl); 1688 1689 case SPI_SETMOUSEVANISH: 1690 return SpiSetBool(&gspv.bMouseVanish, uiParam, KEY_MOUSE, L"", fl); 1691 1692 case SPI_GETFLATMENU: 1693 return SpiGetUserPref(UPM_FLATMENU, pvParam, fl); 1694 1695 case SPI_SETFLATMENU: 1696 return SpiSetUserPref(UPM_FLATMENU, pvParam, fl); 1697 1698 case SPI_GETDROPSHADOW: 1699 return SpiGetUserPref(UPM_DROPSHADOW, pvParam, fl); 1700 1701 case SPI_SETDROPSHADOW: 1702 return SpiSetUserPref(UPM_DROPSHADOW, pvParam, fl); 1703 1704 case SPI_GETBLOCKSENDINPUTRESETS: 1705 return SpiGetInt(pvParam, &gspv.bBlockSendInputResets, fl); 1706 1707 case SPI_SETBLOCKSENDINPUTRESETS: 1708 return SpiSetBool(&gspv.bBlockSendInputResets, uiParam, KEY_MOUSE, L"", fl); 1709 1710 #if(_WIN32_WINNT >= 0x0600) 1711 case SPI_GETDISABLEOVERLAPPEDCONTENT: 1712 return SpiGetInt(pvParam, &gspv.bDisableOverlappedContent, fl); 1713 1714 case SPI_SETDISABLEOVERLAPPEDCONTENT: 1715 return SpiSetBool(&gspv.bDisableOverlappedContent, uiParam, KEY_MOUSE, L"", fl); 1716 1717 case SPI_GETCLIENTAREAANIMATION: 1718 return SpiGetInt(pvParam, &gspv.bClientAreaAnimation, fl); 1719 1720 case SPI_SETCLIENTAREAANIMATION: 1721 return SpiSetBool(&gspv.bClientAreaAnimation, uiParam, KEY_MOUSE, L"", fl); 1722 1723 case SPI_GETCLEARTYPE: 1724 return SpiGetInt(pvParam, &gspv.bClearType, fl); 1725 1726 case SPI_SETCLEARTYPE: 1727 return SpiSetBool(&gspv.bClearType, uiParam, KEY_MOUSE, L"", fl); 1728 1729 case SPI_GETSPEECHRECOGNITION: 1730 return SpiGetInt(pvParam, &gspv.bSpeechRecognition, fl); 1731 1732 case SPI_SETSPEECHRECOGNITION: 1733 return SpiSetBool(&gspv.bSpeechRecognition, uiParam, KEY_MOUSE, L"", fl); 1734 #endif 1735 1736 case SPI_GETFOREGROUNDLOCKTIMEOUT: 1737 return SpiGetInt(pvParam, &gspv.dwForegroundLockTimeout, fl); 1738 1739 case SPI_SETFOREGROUNDLOCKTIMEOUT: 1740 return SpiSetInt(&gspv.dwForegroundLockTimeout, uiParam, KEY_MOUSE, L"", fl); 1741 1742 case SPI_GETACTIVEWNDTRKTIMEOUT: 1743 return SpiGetInt(pvParam, &gspv.dwActiveTrackingTimeout, fl); 1744 1745 case SPI_SETACTIVEWNDTRKTIMEOUT: 1746 return SpiSetInt(&gspv.dwActiveTrackingTimeout, uiParam, KEY_MOUSE, L"", fl); 1747 1748 case SPI_GETFOREGROUNDFLASHCOUNT: 1749 return SpiGetInt(pvParam, &gspv.dwForegroundFlashCount, fl); 1750 1751 case SPI_SETFOREGROUNDFLASHCOUNT: 1752 return SpiSetInt(&gspv.dwForegroundFlashCount, uiParam, KEY_MOUSE, L"", fl); 1753 1754 case SPI_GETCARETWIDTH: 1755 return SpiGetInt(pvParam, &gspv.dwCaretWidth, fl); 1756 1757 case SPI_SETCARETWIDTH: 1758 return SpiSetDWord(&gspv.dwCaretWidth, PtrToUlong(pvParam), KEY_DESKTOP, VAL_CARETWIDTH, fl); 1759 1760 case SPI_GETMOUSECLICKLOCKTIME: 1761 return SpiGetInt(pvParam, &gspv.dwMouseClickLockTime, fl); 1762 1763 case SPI_SETMOUSECLICKLOCKTIME: 1764 return SpiSetDWord(&gspv.dwMouseClickLockTime, uiParam, KEY_DESKTOP, VAL_CLICKLOCKTIME, fl); 1765 1766 case SPI_GETFONTSMOOTHINGTYPE: 1767 return SpiGetInt(pvParam, &gspv.uiFontSmoothingType, fl); 1768 1769 case SPI_SETFONTSMOOTHINGTYPE: 1770 return SpiSetDWord(&gspv.uiFontSmoothingType, PtrToUlong(pvParam), KEY_DESKTOP, VAL_FONTSMOOTHINGTYPE, fl); 1771 1772 case SPI_GETFONTSMOOTHINGCONTRAST: 1773 return SpiGetInt(pvParam, &gspv.uiFontSmoothingContrast, fl); 1774 1775 case SPI_SETFONTSMOOTHINGCONTRAST: 1776 return SpiSetDWord(&gspv.uiFontSmoothingContrast, PtrToUlong(pvParam), KEY_DESKTOP, VAL_FONTSMOOTHINGCONTRAST, fl); 1777 1778 case SPI_GETFOCUSBORDERWIDTH: 1779 return SpiGetInt(pvParam, &gspv.uiFocusBorderWidth, fl); 1780 1781 case SPI_SETFOCUSBORDERWIDTH: 1782 return SpiSetInt(&gspv.uiFocusBorderWidth, uiParam, KEY_MOUSE, L"", fl); 1783 1784 case SPI_GETFOCUSBORDERHEIGHT: 1785 return SpiGetInt(pvParam, &gspv.uiFocusBorderHeight, fl); 1786 1787 case SPI_SETFOCUSBORDERHEIGHT: 1788 return SpiSetInt(&gspv.uiFocusBorderHeight, uiParam, KEY_MOUSE, L"", fl); 1789 1790 case SPI_GETFONTSMOOTHINGORIENTATION: 1791 return SpiGetInt(pvParam, &gspv.uiFontSmoothingOrientation, fl); 1792 1793 case SPI_SETFONTSMOOTHINGORIENTATION: 1794 return SpiSetDWord(&gspv.uiFontSmoothingOrientation, PtrToUlong(pvParam), KEY_DESKTOP, VAL_FONTSMOOTHINGORIENTATION, fl); 1795 1796 /* The following are undocumented, but valid SPI values */ 1797 case 0x1010: 1798 case 0x1011: 1799 case 0x1028: 1800 case 0x1029: 1801 case 0x102A: 1802 case 0x102B: 1803 case 0x102C: 1804 case 0x102D: 1805 case 0x102E: 1806 case 0x102F: 1807 case 0x1030: 1808 case 0x1031: 1809 case 0x1032: 1810 case 0x1033: 1811 case 0x1034: 1812 case 0x1035: 1813 case 0x1036: 1814 case 0x1037: 1815 case 0x1038: 1816 case 0x1039: 1817 case 0x103A: 1818 case 0x103B: 1819 case 0x103C: 1820 case 0x103D: 1821 ERR("Undocumented SPI value %x is unimplemented\n", uiAction); 1822 break; 1823 1824 default: 1825 ERR("Invalid SPI value: %u\n", uiAction); 1826 EngSetLastError(ERROR_INVALID_PARAMETER); 1827 return 0; 1828 } 1829 1830 return 0; 1831 } 1832 1833 static BOOL 1834 SpiGetSetProbeBuffer(UINT uiAction, UINT uiParam, PVOID pvParam) 1835 { 1836 BOOL bToUser = TRUE; 1837 ULONG cbSize = 0; 1838 1839 switch (uiAction) 1840 { 1841 case SPI_GETBEEP: 1842 case SPI_GETBORDER: 1843 case SPI_GETKEYBOARDSPEED: 1844 case SPI_GETSCREENSAVETIMEOUT: 1845 case SPI_GETSCREENSAVEACTIVE: 1846 case SPI_GETGRIDGRANULARITY: 1847 case SPI_GETKEYBOARDDELAY: 1848 case SPI_GETICONTITLEWRAP: 1849 case SPI_GETMENUDROPALIGNMENT: 1850 case SPI_GETFASTTASKSWITCH: 1851 case SPI_GETDRAGFULLWINDOWS: 1852 case SPI_GETSHOWSOUNDS: 1853 case SPI_GETKEYBOARDPREF: 1854 case SPI_GETSCREENREADER: 1855 case SPI_GETFONTSMOOTHING: 1856 case SPI_GETLOWPOWERTIMEOUT: 1857 case SPI_GETPOWEROFFTIMEOUT: 1858 case SPI_GETLOWPOWERACTIVE: 1859 case SPI_GETPOWEROFFACTIVE: 1860 case SPI_GETMOUSETRAILS: 1861 case SPI_GETSNAPTODEFBUTTON: 1862 case SPI_GETMOUSEHOVERWIDTH: 1863 case SPI_GETMOUSEHOVERHEIGHT: 1864 case SPI_GETMOUSEHOVERTIME: 1865 case SPI_GETWHEELSCROLLLINES: 1866 case SPI_GETMENUSHOWDELAY: 1867 #if (_WIN32_WINNT >= 0x0600) 1868 case SPI_GETWHEELSCROLLCHARS: 1869 #endif 1870 case SPI_GETSHOWIMEUI: 1871 case SPI_GETMOUSESPEED: 1872 case SPI_GETSCREENSAVERRUNNING: 1873 #if(WINVER >= 0x0600) 1874 case SPI_GETSCREENSAVESECURE: 1875 #endif 1876 case SPI_GETACTIVEWINDOWTRACKING: 1877 case SPI_GETMENUANIMATION: 1878 case SPI_GETCOMBOBOXANIMATION: 1879 case SPI_GETLISTBOXSMOOTHSCROLLING: 1880 case SPI_GETGRADIENTCAPTIONS: 1881 case SPI_GETKEYBOARDCUES: 1882 case SPI_GETACTIVEWNDTRKZORDER: 1883 case SPI_GETHOTTRACKING: 1884 case SPI_GETMENUFADE: 1885 case SPI_GETSELECTIONFADE: 1886 case SPI_GETTOOLTIPANIMATION: 1887 case SPI_GETTOOLTIPFADE: 1888 case SPI_GETCURSORSHADOW: 1889 case SPI_GETUIEFFECTS: 1890 case SPI_GETMOUSESONAR: 1891 case SPI_GETMOUSECLICKLOCK: 1892 case SPI_GETMOUSEVANISH: 1893 case SPI_GETFLATMENU: 1894 case SPI_GETDROPSHADOW: 1895 case SPI_GETBLOCKSENDINPUTRESETS: 1896 #if(_WIN32_WINNT >= 0x0600) 1897 case SPI_GETDISABLEOVERLAPPEDCONTENT: 1898 case SPI_GETCLIENTAREAANIMATION: 1899 case SPI_GETCLEARTYPE: 1900 case SPI_GETSPEECHRECOGNITION: 1901 #endif 1902 case SPI_GETFOREGROUNDLOCKTIMEOUT: 1903 case SPI_GETACTIVEWNDTRKTIMEOUT: 1904 case SPI_GETFOREGROUNDFLASHCOUNT: 1905 case SPI_GETCARETWIDTH: 1906 case SPI_GETMOUSECLICKLOCKTIME: 1907 case SPI_GETFONTSMOOTHINGTYPE: 1908 case SPI_GETFONTSMOOTHINGCONTRAST: 1909 case SPI_GETFOCUSBORDERWIDTH: 1910 case SPI_GETFOCUSBORDERHEIGHT: 1911 case SPI_GETFONTSMOOTHINGORIENTATION: 1912 cbSize = sizeof(INT); 1913 break; 1914 1915 case SPI_ICONHORIZONTALSPACING: 1916 case SPI_ICONVERTICALSPACING: 1917 if (pvParam) cbSize = sizeof(INT); 1918 break; 1919 1920 case SPI_GETMOUSE: 1921 cbSize = 3 * sizeof(INT); 1922 break; 1923 1924 case SPI_GETDESKWALLPAPER: 1925 cbSize = min(uiParam, gspv.ustrWallpaper.Length + 1UL); 1926 break; 1927 1928 case SPI_GETICONTITLELOGFONT: 1929 cbSize = sizeof(LOGFONTW); 1930 break; 1931 1932 case SPI_GETNONCLIENTMETRICS: 1933 cbSize = sizeof(NONCLIENTMETRICSW); 1934 break; 1935 1936 case SPI_GETMINIMIZEDMETRICS: 1937 cbSize = sizeof(MINIMIZEDMETRICS); 1938 break; 1939 1940 case SPI_GETICONMETRICS: 1941 cbSize = sizeof(ICONMETRICSW); 1942 break; 1943 1944 case SPI_GETWORKAREA: 1945 cbSize = sizeof(RECTL); 1946 break; 1947 1948 case SPI_GETFILTERKEYS: 1949 cbSize = sizeof(FILTERKEYS); 1950 break; 1951 1952 case SPI_GETTOGGLEKEYS: 1953 cbSize = sizeof(TOGGLEKEYS); 1954 break; 1955 1956 case SPI_GETMOUSEKEYS: 1957 cbSize = sizeof(MOUSEKEYS); 1958 break; 1959 1960 case SPI_GETSTICKYKEYS: 1961 cbSize = sizeof(STICKYKEYS); 1962 break; 1963 1964 case SPI_GETACCESSTIMEOUT: 1965 cbSize = sizeof(ACCESSTIMEOUT); 1966 break; 1967 1968 case SPI_GETSERIALKEYS: 1969 cbSize = sizeof(SERIALKEYS); 1970 break; 1971 1972 case SPI_GETSOUNDSENTRY: 1973 cbSize = sizeof(SOUNDSENTRYW); 1974 break; 1975 1976 case SPI_GETHIGHCONTRAST: 1977 cbSize = sizeof(HIGHCONTRASTW); 1978 break; 1979 1980 case SPI_GETANIMATION: 1981 cbSize = sizeof(ANIMATIONINFO); 1982 break; 1983 1984 case SPI_GETDEFAULTINPUTLANG: 1985 cbSize = sizeof(HKL); 1986 break; 1987 1988 #if(WINVER >= 0x0600) 1989 case SPI_GETAUDIODESCRIPTION: 1990 cbSize = sizeof(AUDIODESCRIPTION); 1991 break; 1992 #endif 1993 1994 case SPI_SETMOUSE: 1995 cbSize = 3 * sizeof(INT); 1996 bToUser = FALSE; 1997 break; 1998 1999 case SPI_SETICONTITLELOGFONT: 2000 cbSize = sizeof(LOGFONTW); 2001 bToUser = FALSE; 2002 break; 2003 2004 case SPI_SETNONCLIENTMETRICS: 2005 cbSize = sizeof(NONCLIENTMETRICSW); 2006 bToUser = FALSE; 2007 break; 2008 2009 case SPI_SETMINIMIZEDMETRICS: 2010 cbSize = sizeof(MINIMIZEDMETRICS); 2011 bToUser = FALSE; 2012 break; 2013 2014 case SPI_SETICONMETRICS: 2015 cbSize = sizeof(ICONMETRICSW); 2016 bToUser = FALSE; 2017 break; 2018 2019 case SPI_SETWORKAREA: 2020 cbSize = sizeof(RECTL); 2021 bToUser = FALSE; 2022 break; 2023 2024 case SPI_SETFILTERKEYS: 2025 cbSize = sizeof(FILTERKEYS); 2026 bToUser = FALSE; 2027 break; 2028 2029 case SPI_SETTOGGLEKEYS: 2030 cbSize = sizeof(TOGGLEKEYS); 2031 bToUser = FALSE; 2032 break; 2033 2034 case SPI_SETMOUSEKEYS: 2035 cbSize = sizeof(MOUSEKEYS); 2036 bToUser = FALSE; 2037 break; 2038 2039 case SPI_SETSTICKYKEYS: 2040 cbSize = sizeof(STICKYKEYS); 2041 bToUser = FALSE; 2042 break; 2043 2044 case SPI_SETACCESSTIMEOUT: 2045 cbSize = sizeof(ACCESSTIMEOUT); 2046 bToUser = FALSE; 2047 break; 2048 2049 case SPI_SETSERIALKEYS: 2050 cbSize = sizeof(SERIALKEYS); 2051 bToUser = FALSE; 2052 break; 2053 2054 case SPI_SETSOUNDSENTRY: 2055 cbSize = sizeof(SOUNDSENTRYW); 2056 bToUser = FALSE; 2057 break; 2058 2059 case SPI_SETHIGHCONTRAST: 2060 cbSize = sizeof(HIGHCONTRASTW); 2061 bToUser = FALSE; 2062 break; 2063 2064 case SPI_SETANIMATION: 2065 cbSize = sizeof(ANIMATIONINFO); 2066 bToUser = FALSE; 2067 break; 2068 2069 case SPI_SETDEFAULTINPUTLANG: 2070 cbSize = sizeof(HKL); 2071 bToUser = FALSE; 2072 break; 2073 2074 case SPI_SETMOUSESPEED: 2075 cbSize = sizeof(INT); 2076 bToUser = FALSE; 2077 break; 2078 } 2079 2080 if (cbSize) 2081 { 2082 _SEH2_TRY 2083 { 2084 if (bToUser) 2085 { 2086 ProbeForWrite(pvParam, cbSize, sizeof(UCHAR)); 2087 } 2088 else 2089 { 2090 ProbeForRead(pvParam, cbSize, sizeof(UCHAR)); 2091 } 2092 } 2093 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2094 { 2095 _SEH2_YIELD(return FALSE); 2096 } 2097 _SEH2_END; 2098 } 2099 2100 return TRUE; 2101 } 2102 2103 BOOL 2104 FASTCALL 2105 UserSystemParametersInfo( 2106 UINT uiAction, 2107 UINT uiParam, 2108 PVOID pvParam, 2109 UINT fWinIni) 2110 { 2111 ULONG_PTR ulResult; 2112 PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); 2113 2114 ASSERT(ppi); 2115 2116 if (!gbSpiInitialized) 2117 { 2118 KeRosDumpStackFrames(NULL, 20); 2119 //ASSERT(FALSE); 2120 return FALSE; 2121 } 2122 2123 /* Get a pointer to the current Windowstation */ 2124 if (!ppi->prpwinsta) 2125 { 2126 ERR("UserSystemParametersInfo called without active window station.\n"); 2127 //ASSERT(FALSE); 2128 //return FALSE; 2129 } 2130 2131 if ((fWinIni & SPIF_PROTECT) && !SpiGetSetProbeBuffer(uiAction, uiParam, pvParam)) 2132 { 2133 EngSetLastError(ERROR_NOACCESS); 2134 return FALSE; 2135 } 2136 2137 /* Do the actual operation */ 2138 ulResult = SpiGetSet(uiAction, uiParam, pvParam, fWinIni); 2139 2140 /* Did we change something? */ 2141 if (ulResult > 1) 2142 { 2143 SpiFixupValues(); 2144 2145 /* Update system metrics */ 2146 InitMetrics(); 2147 2148 /* Send notification to toplevel windows, if requested */ 2149 if (fWinIni & SPIF_SENDCHANGE) 2150 { 2151 /* Send WM_SETTINGCHANGE to all toplevel windows */ 2152 co_IntSendMessageTimeout(HWND_BROADCAST, 2153 WM_SETTINGCHANGE, 2154 (WPARAM)uiAction, 2155 (LPARAM)ulResult, 2156 SMTO_NORMAL, 2157 100, 2158 &ulResult); 2159 } 2160 ulResult = 1; 2161 } 2162 2163 return ulResult; 2164 } 2165 2166 BOOL 2167 APIENTRY 2168 NtUserSystemParametersInfo( 2169 UINT uiAction, 2170 UINT uiParam, 2171 PVOID pvParam, 2172 UINT fWinIni) 2173 { 2174 BOOL bResult; 2175 2176 TRACE("Enter NtUserSystemParametersInfo(%u)\n", uiAction); 2177 UserEnterExclusive(); 2178 2179 // FIXME: Get rid of the flags and only use this from um. kernel can access data directly. 2180 /* Set UM memory protection flag */ 2181 fWinIni |= SPIF_PROTECT; 2182 2183 /* Call internal function */ 2184 bResult = UserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni); 2185 2186 TRACE("Leave NtUserSystemParametersInfo, returning %d\n", bResult); 2187 UserLeave(); 2188 2189 return bResult; 2190 } 2191 2192 /* EOF */ 2193