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