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