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