ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

sysparams.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:        GPL, see COPYING in the top level directory
00003  * PROJECT:          ReactOS win32 kernel mode subsystem server
00004  * PURPOSE:          System parameters functions
00005  * FILE:             subsystems/win32/win32k/ntuser/sysparams.c
00006  * PROGRAMER:        Timo Kreuzer (timo.kreuzer@reactos.org)
00007  */
00008 
00009 // TODO:
00010 // - Check all values that are in Winsta in ROS.
00011 // - Does setting invalid fonts work?
00012 // - Save appropriate text metrics.
00013 
00014 #include <win32k.h>
00015 DBG_DEFAULT_CHANNEL(UserSysparams);
00016 
00017 SPIVALUES gspv;
00018 BOOL gbSpiInitialized = FALSE;
00019 BOOL g_PaintDesktopVersion = FALSE;
00020 
00021 // HACK! We initialize SPI before we have a proper surface to get this from.
00022 #define dpi 96
00023 //(pPrimarySurface->GDIInfo.ulLogPixelsY)
00024 #define REG2METRIC(reg) (reg > 0 ? reg : ((-(reg) * dpi + 720) / 1440))
00025 #define METRIC2REG(met) (-((((met) * 1440)- 0) / dpi))
00026 
00027 #define REQ_INTERACTIVE_WINSTA(err) \
00028     if ( GetW32ProcessInfo()->prpwinsta != InputWindowStation) \
00029     { \
00030         ERR("NtUserSystemParametersInfo requires interactive window station (current is %wZ)\n", &GetW32ProcessInfo()->prpwinsta->Name); \
00031         EngSetLastError(err); \
00032         return 0; \
00033     }
00034 
00035 static const WCHAR* KEY_MOUSE = L"Control Panel\\Mouse";
00036 static const WCHAR* VAL_MOUSE1 = L"MouseThreshold1";
00037 static const WCHAR* VAL_MOUSE2 = L"MouseThreshold2";
00038 static const WCHAR* VAL_MOUSE3 = L"MouseSpeed";
00039 static const WCHAR* VAL_MOUSETRAILS = L"MouseTrails";
00040 static const WCHAR* VAL_DBLCLKWIDTH = L"DoubleClickWidth";
00041 static const WCHAR* VAL_DBLCLKHEIGHT = L"DoubleClickHeight";
00042 static const WCHAR* VAL_DBLCLKTIME = L"DoubleClickSpeed";
00043 static const WCHAR* VAL_SNAPDEFBTN = L"SnapToDefaultButton";
00044 static const WCHAR* VAL_SWAP = L"SwapMouseButtons";
00045 static const WCHAR* VAL_HOVERTIME = L"MouseHoverTime";
00046 static const WCHAR* VAL_HOVERWIDTH = L"MouseHoverWidth";
00047 static const WCHAR* VAL_HOVERHEIGHT = L"MouseHoverHeight";
00048 static const WCHAR* VAL_SENSITIVITY = L"MouseSensitivity";
00049 
00050 static const WCHAR* KEY_DESKTOP = L"Control Panel\\Desktop";
00051 static const WCHAR* VAL_SCRTO = L"ScreenSaveTimeOut";
00052 static const WCHAR* VAL_SCRNSV = L"SCRNSAVE.EXE";
00053 static const WCHAR* VAL_SCRACT = L"ScreenSaveActive";
00054 static const WCHAR* VAL_GRID = L"GridGranularity";
00055 static const WCHAR* VAL_DRAG = L"DragFullWindows";
00056 static const WCHAR* VAL_DRAGHEIGHT = L"DragHeight";
00057 static const WCHAR* VAL_DRAGWIDTH = L"DragWidth";
00058 static const WCHAR* VAL_FNTSMOOTH = L"FontSmoothing";
00059 static const WCHAR* VAL_SCRLLLINES = L"WheelScrollLines";
00060 static const WCHAR* VAL_CLICKLOCKTIME = L"ClickLockTime";
00061 static const WCHAR* VAL_PAINTDESKVER = L"PaintDesktopVersion";
00062 static const WCHAR* VAL_CARETRATE = L"CursorBlinkRate";
00063 #if (_WIN32_WINNT >= 0x0600)
00064 static const WCHAR* VAL_SCRLLCHARS = L"WheelScrollChars";
00065 #endif
00066 static const WCHAR* VAL_USERPREFMASK = L"UserPreferencesMask";
00067 
00068 static const WCHAR* KEY_MDALIGN = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows";
00069 static const WCHAR* VAL_MDALIGN = L"MenuDropAlignment";
00070 
00071 static const WCHAR* KEY_METRIC = L"Control Panel\\Desktop\\WindowMetrics";
00072 static const WCHAR* VAL_BORDER = L"BorderWidth";
00073 static const WCHAR* VAL_ICONSPC = L"IconSpacing";
00074 static const WCHAR* VAL_ICONVSPC = L"IconVerticalspacing";
00075 static const WCHAR* VAL_ITWRAP = L"IconTitleWrap";
00076 
00077 static const WCHAR* KEY_SOUND = L"Control Panel\\Sound";
00078 static const WCHAR* VAL_BEEP = L"Beep";
00079 
00080 static const WCHAR* KEY_KBD = L"Control Panel\\Keyboard";
00081 static const WCHAR* VAL_KBDSPD = L"KeyboardSpeed";
00082 static const WCHAR* VAL_KBDDELAY = L"KeyboardDelay";
00083 
00084 static const WCHAR* KEY_SHOWSNDS = L"Control Panel\\Accessibility\\ShowSounds";
00085 static const WCHAR* KEY_KDBPREF = L"Control Panel\\Accessibility\\Keyboard Preference";
00086 static const WCHAR* KEY_SCRREAD = L"Control Panel\\Accessibility\\Blind Access";
00087 static const WCHAR* VAL_ON = L"On";
00088 
00089 
00090 
00093 static
00094 INT
00095 SpiLoadDWord(PCWSTR pwszKey, PCWSTR pwszValue, INT iValue)
00096 {
00097     DWORD Result;
00098     if (!RegReadUserSetting(pwszKey, pwszValue, REG_DWORD, &Result, sizeof(Result)))
00099     {
00100         return iValue;
00101     }
00102     return Result;
00103 }
00104 
00105 static
00106 INT
00107 SpiLoadInt(PCWSTR pwszKey, PCWSTR pwszValue, INT iValue)
00108 {
00109     WCHAR awcBuffer[12];
00110     ULONG cbSize;
00111 
00112     cbSize = sizeof(awcBuffer);
00113     if (!RegReadUserSetting(pwszKey, pwszValue, REG_SZ, awcBuffer, cbSize))
00114     {
00115         return iValue;
00116     }
00117     return _wtoi(awcBuffer);
00118 }
00119 
00120 static
00121 DWORD
00122 SpiLoadUserPrefMask(DWORD dValue)
00123 {
00124     DWORD Result;
00125     if (!RegReadUserSetting(KEY_DESKTOP, VAL_USERPREFMASK, REG_BINARY, &Result, sizeof(Result)))
00126     {
00127         return dValue;
00128     }
00129     return Result;
00130 }
00131 
00132 static
00133 DWORD
00134 SpiLoadTimeOut(VOID)
00135 {   // Must have the string!
00136     WCHAR szApplicationName[MAX_PATH];
00137     RtlZeroMemory(&szApplicationName, sizeof(szApplicationName));
00138     if (!RegReadUserSetting(KEY_DESKTOP, VAL_SCRNSV, REG_SZ, &szApplicationName, sizeof(szApplicationName)))
00139     {
00140         return 0;
00141     }
00142     if (wcslen(szApplicationName) == 0) return 0;
00143     return SpiLoadInt(KEY_DESKTOP, VAL_SCRTO, 0);
00144 }
00145 
00146 static
00147 INT
00148 SpiLoadMouse(PCWSTR pwszValue, INT iValue)
00149 {
00150     return SpiLoadInt(KEY_MOUSE, pwszValue, iValue);
00151 }
00152 
00153 static
00154 INT
00155 SpiLoadMetric(PCWSTR pwszValue, INT iValue)
00156 {
00157     INT iRegVal;
00158 
00159     iRegVal = SpiLoadInt(KEY_METRIC, pwszValue, METRIC2REG(iValue));
00160     TRACE("Loaded metric setting '%S', iValue=%d(reg:%d), ret=%d(reg:%d)\n",
00161            pwszValue, iValue, METRIC2REG(iValue), REG2METRIC(iRegVal), iRegVal);
00162     return REG2METRIC(iRegVal);
00163 }
00164 
00165 static
00166 VOID
00167 SpiLoadFont(PLOGFONTW plfOut, LPWSTR pwszValueName, PLOGFONTW plfDefault)
00168 {
00169     BOOL bResult;
00170 
00171     bResult = RegReadUserSetting(KEY_METRIC,
00172                                  pwszValueName,
00173                                  REG_BINARY,
00174                                  plfOut,
00175                                  sizeof(LOGFONTW));
00176     if (!bResult)
00177         *plfOut = *plfDefault;
00178 }
00179 
00180 static
00181 VOID
00182 SpiFixupValues()
00183 {
00184     /* Fixup values */
00185     gspv.ncm.iCaptionWidth = max(gspv.ncm.iCaptionWidth, 8);
00186     gspv.ncm.iBorderWidth = max(gspv.ncm.iBorderWidth, 1);
00187     gspv.ncm.iScrollWidth = max(gspv.ncm.iScrollWidth, 8);
00188     gspv.ncm.iScrollHeight = max(gspv.ncm.iScrollHeight, 8);
00189 //    gspv.ncm.iMenuHeight = max(gspv.ncm.iMenuHeight, gspv.tmMenuFont.tmHeight);
00190 //    gspv.ncm.iMenuHeight = max(gspv.ncm.iMenuHeight,
00191 //                               2 + gspv.tmMenuFont.tmHeight +
00192 //                               gspv.tmMenuFont.tmExternalLeading);
00193     if (gspv.iDblClickTime == 0) gspv.iDblClickTime = 500;
00194 
00195     // FIXME: Hack!!!
00196     gspv.tmMenuFont.tmHeight = 11;
00197     gspv.tmMenuFont.tmExternalLeading = 2;
00198 
00199     gspv.tmCaptionFont.tmHeight = 11;
00200     gspv.tmCaptionFont.tmExternalLeading = 2;
00201 
00202 }
00203 
00204 static
00205 VOID
00206 SpiUpdatePerUserSystemParameters()
00207 {
00208     static LOGFONTW lf1 = {-11, 0, 0, 0, FW_NORMAL, FALSE, FALSE,
00209                            FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY,
00210                            VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif"};
00211     static LOGFONTW lf2 = {-11, 0, 0, 0, FW_BOLD, FALSE, FALSE,
00212                            FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY,
00213                            VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif"};
00214 
00215     TRACE("Enter SpiUpdatePerUserSystemParameters\n");
00216 
00217     /* Clear the structure */
00218     memset(&gspv, 0, sizeof(gspv));
00219 
00220     /* Load mouse settings */
00221     gspv.caiMouse.FirstThreshold = SpiLoadMouse(VAL_MOUSE1, 6);
00222     gspv.caiMouse.SecondThreshold = SpiLoadMouse(VAL_MOUSE2, 10);
00223     gspv.caiMouse.Acceleration = SpiLoadMouse(VAL_MOUSE3, 1);
00224     gspv.iMouseSpeed = SpiLoadMouse(VAL_SENSITIVITY, 10);
00225     gspv.bMouseBtnSwap = SpiLoadMouse(VAL_SWAP, 0);
00226     gspv.bSnapToDefBtn = SpiLoadMouse(VAL_SNAPDEFBTN, 0);
00227     gspv.iMouseTrails = SpiLoadMouse(VAL_MOUSETRAILS, 0);
00228     gspv.iDblClickTime = SpiLoadMouse(VAL_DBLCLKTIME, 500);
00229     gspv.iDblClickWidth = SpiLoadMouse(VAL_DBLCLKWIDTH, 4);
00230     gspv.iDblClickHeight = SpiLoadMouse(VAL_DBLCLKHEIGHT, 4);
00231     gspv.iMouseHoverTime = SpiLoadMouse(VAL_HOVERTIME, 400);
00232     gspv.iMouseHoverWidth = SpiLoadMouse(VAL_HOVERWIDTH, 4);
00233     gspv.iMouseHoverHeight = SpiLoadMouse(VAL_HOVERHEIGHT, 4);
00234 
00235     /* Load NONCLIENTMETRICS */
00236     gspv.ncm.cbSize = sizeof(NONCLIENTMETRICSW);
00237     gspv.ncm.iBorderWidth = SpiLoadMetric(VAL_BORDER, 1);
00238     gspv.ncm.iScrollWidth = SpiLoadMetric(L"ScrollWidth", 16);
00239     gspv.ncm.iScrollHeight = SpiLoadMetric(L"ScrollHeight", 16);
00240     gspv.ncm.iCaptionWidth = SpiLoadMetric(L"CaptionWidth", 19);
00241     gspv.ncm.iCaptionHeight = SpiLoadMetric(L"CaptionHeight", 19);
00242     gspv.ncm.iSmCaptionWidth = SpiLoadMetric(L"SmCaptionWidth", 12);
00243     gspv.ncm.iSmCaptionHeight =  SpiLoadMetric(L"SmCaptionHeight", 14);
00244     gspv.ncm.iMenuWidth = SpiLoadMetric(L"MenuWidth", 18);
00245     gspv.ncm.iMenuHeight = SpiLoadMetric(L"MenuHeight", 18);
00246 #if (WINVER >= 0x0600)
00247     gspv.ncm.iPaddedBorderWidth = SpiLoadMetric(L"PaddedBorderWidth", 18);
00248 #endif
00249     SpiLoadFont(&gspv.ncm.lfCaptionFont, L"CaptionFont", &lf2);
00250     SpiLoadFont(&gspv.ncm.lfSmCaptionFont, L"SmCaptionFont", &lf1);
00251     SpiLoadFont(&gspv.ncm.lfMenuFont, L"MenuFont", &lf1);
00252     SpiLoadFont(&gspv.ncm.lfStatusFont, L"StatusFont", &lf1);
00253     SpiLoadFont(&gspv.ncm.lfMessageFont, L"MessageFont", &lf1);
00254 
00255     /* Load MINIMIZEDMETRICS */
00256     gspv.mm.cbSize = sizeof(MINIMIZEDMETRICS);
00257     gspv.mm.iWidth = SpiLoadMetric(L"MinWidth", 160);
00258     gspv.mm.iHorzGap = SpiLoadMetric(L"MinHorzGap", 160);
00259     gspv.mm.iVertGap = SpiLoadMetric(L"MinVertGap", 24);
00260     gspv.mm.iArrange = SpiLoadInt(KEY_METRIC, L"MinArrange", ARW_HIDE);
00261 
00262     /* Load ICONMETRICS */
00263     gspv.im.cbSize = sizeof(ICONMETRICSW);
00264     gspv.im.iHorzSpacing = SpiLoadMetric(VAL_ICONSPC, 64);
00265     gspv.im.iVertSpacing = SpiLoadMetric(VAL_ICONVSPC, 64);
00266     gspv.im.iTitleWrap = SpiLoadMetric(VAL_ITWRAP, 0);
00267     SpiLoadFont(&gspv.im.lfFont, L"IconFont", &lf1);
00268 
00269     /* Load desktop settings */
00270     gspv.bDragFullWindows = SpiLoadInt(KEY_DESKTOP, VAL_DRAG, 0);
00271     gspv.iWheelScrollLines = SpiLoadInt(KEY_DESKTOP, VAL_SCRLLLINES, 3);
00272     gspv.dwMouseClickLockTime = SpiLoadDWord(KEY_DESKTOP, VAL_CLICKLOCKTIME, 1200);
00273     gpsi->dtCaretBlink = SpiLoadInt(KEY_DESKTOP, VAL_CARETRATE, 530);
00274     gspv.dwUserPrefMask = SpiLoadUserPrefMask(UPM_DEFAULT);
00275     gspv.bMouseClickLock = (gspv.dwUserPrefMask & UPM_CLICKLOCK) != 0;
00276     gspv.bMouseCursorShadow = (gspv.dwUserPrefMask & UPM_CURSORSHADOW) != 0;
00277 #if (_WIN32_WINNT >= 0x0600)
00278     gspv.iWheelScrollChars = SpiLoadInt(KEY_DESKTOP, VAL_SCRLLCHARS, 3);
00279 #endif
00280 
00281     /* Some hardcoded values for now */
00282 
00283     gspv.tmCaptionFont.tmAveCharWidth = 6;
00284     gspv.bBeep = TRUE;
00285     gspv.bFlatMenu = FALSE;
00286     gspv.uiFocusBorderWidth = 1;
00287     gspv.uiFocusBorderHeight = 1;
00288     gspv.bMenuDropAlign = 1;
00289     gspv.bDropShadow = 1;
00290     gspv.dwMenuShowDelay = 100;
00291 
00292     gspv.iScrSaverTimeout = SpiLoadTimeOut();
00293     gspv.bScrSaverActive = FALSE;
00294     gspv.bScrSaverRunning = FALSE;
00295 #if(WINVER >= 0x0600)
00296     gspv.bScrSaverSecure = FALSE;
00297 #endif
00298 
00299     /* Make sure we don't use broken values */
00300     SpiFixupValues();
00301 
00302     /* Update SystemMetrics */
00303     InitMetrics();
00304 }
00305 
00306 BOOL
00307 InitSysParams()
00308 {
00309     SpiUpdatePerUserSystemParameters();
00310     gbSpiInitialized = TRUE;
00311     return TRUE;
00312 }
00313 
00314 
00315 BOOL
00316 APIENTRY
00317 NtUserUpdatePerUserSystemParameters(
00318     DWORD dwReserved,
00319     BOOL bEnable)
00320 {
00321     BOOL bResult;
00322 
00323     TRACE("Enter NtUserUpdatePerUserSystemParameters\n");
00324     UserEnterExclusive();
00325 
00326     SpiUpdatePerUserSystemParameters();
00327     if(bEnable)
00328         g_PaintDesktopVersion = SpiLoadDWord(KEY_DESKTOP, VAL_PAINTDESKVER, 0);
00329     else
00330         g_PaintDesktopVersion = FALSE;
00331     bResult = TRUE;
00332 
00333     TRACE("Leave NtUserUpdatePerUserSystemParameters, returning %d\n", bResult);
00334     UserLeave();
00335 
00336     return bResult;
00337 }
00338 
00339 
00342 static
00343 VOID
00344 SpiStoreDWord(PCWSTR pwszKey, PCWSTR pwszValue, DWORD Value)
00345 {
00346     RegWriteUserSetting(pwszKey,
00347                         pwszValue,
00348                         REG_DWORD,
00349                         &Value,
00350                         sizeof(Value));
00351 }
00352 
00353 static
00354 VOID
00355 SpiStoreSz(PCWSTR pwszKey, PCWSTR pwszValue, PCWSTR pwsz)
00356 {
00357     RegWriteUserSetting(pwszKey,
00358                         pwszValue,
00359                         REG_SZ,
00360                         (PWSTR)pwsz,
00361                         wcslen(pwsz) * sizeof(WCHAR));
00362 }
00363 
00364 static
00365 VOID
00366 SpiStoreSzInt(PCWSTR pwszKey, PCWSTR pwszValue, INT iValue)
00367 {
00368     WCHAR awcBuffer[15];
00369 
00370     _itow(iValue, awcBuffer, 10);
00371     RegWriteUserSetting(pwszKey,
00372                         pwszValue,
00373                         REG_SZ,
00374                         awcBuffer,
00375                         (wcslen(awcBuffer) + 1) * sizeof(WCHAR));
00376 }
00377 
00378 static
00379 VOID
00380 SpiStoreMetric(LPCWSTR pwszValue, INT iValue)
00381 {
00382     SpiStoreSzInt(KEY_METRIC, pwszValue, METRIC2REG(iValue));
00383 }
00384 
00385 static
00386 VOID
00387 SpiStoreFont(PCWSTR pwszValue, LOGFONTW* plogfont)
00388 {
00389     RegWriteUserSetting(KEY_METRIC,
00390                         pwszValue,
00391                         REG_BINARY,
00392                         plogfont,
00393                         sizeof(LOGFONTW));
00394 }
00395 
00396 
00399 // FIXME: get rid of the flags and only use this from um. kernel can access data directly.
00400 static
00401 UINT_PTR
00402 SpiMemCopy(PVOID pvDst, PVOID pvSrc, ULONG cbSize, BOOL bProtect, BOOL bToUser)
00403 {
00404     NTSTATUS Status = STATUS_SUCCESS;
00405 
00406     if (bProtect)
00407     {
00408         _SEH2_TRY
00409         {
00410             if (bToUser)
00411             {
00412                 ProbeForWrite(pvDst, cbSize, 1);
00413             }
00414             else
00415             {
00416                 ProbeForRead(pvSrc, cbSize, 1);
00417             }
00418             memcpy(pvDst, pvSrc, cbSize);
00419         }
00420         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00421         {
00422             Status = _SEH2_GetExceptionCode();
00423         }
00424         _SEH2_END
00425     }
00426     else
00427     {
00428         memcpy(pvDst, pvSrc, cbSize);
00429     }
00430 
00431     if (!NT_SUCCESS(Status))
00432     {
00433         SetLastNtError(Status);
00434         ERR("SpiMemCopy failed, pvDst=%p, pvSrc=%p, bProtect=%d, bToUser=%d\n", pvDst, pvSrc, bProtect, bToUser);
00435     }
00436     return NT_SUCCESS(Status);
00437 }
00438 
00439 static inline
00440 UINT_PTR
00441 SpiGet(PVOID pvParam, PVOID pvData, ULONG cbSize, FLONG fl)
00442 {
00443     REQ_INTERACTIVE_WINSTA(ERROR_ACCESS_DENIED);
00444     return SpiMemCopy(pvParam, pvData, cbSize, fl & SPIF_PROTECT, TRUE);
00445 }
00446 
00447 static inline
00448 UINT_PTR
00449 SpiSet(PVOID pvData, PVOID pvParam, ULONG cbSize, FLONG fl)
00450 {
00451     REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
00452     return SpiMemCopy(pvData, pvParam, cbSize, fl & SPIF_PROTECT, FALSE);
00453 }
00454 
00455 static inline
00456 UINT_PTR
00457 SpiGetEx(PVOID pvParam, PVOID pvData, ULONG cbSize, FLONG fl)
00458 {
00459     ULONG cbBufSize;
00460     /* Get the cbSite member from UM memory */
00461     if (!SpiSet(&cbBufSize, pvParam, sizeof(ULONG), fl))
00462         return 0;
00463     /* Verify the correct size */
00464     if (cbBufSize != cbSize)
00465         return 0;
00466     return SpiGet(pvParam, pvData, cbSize, fl);
00467 }
00468 
00469 static inline
00470 UINT_PTR
00471 SpiGetInt(PVOID pvParam, PVOID piValue, FLONG fl)
00472 {
00473     return SpiGet(pvParam, piValue, sizeof(INT), fl);
00474 }
00475 
00476 static inline
00477 UINT_PTR
00478 SpiSetYesNo(BOOL *pbData, BOOL bValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl)
00479 {
00480     REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
00481     *pbData = bValue ? TRUE : FALSE;
00482     if (fl & SPIF_UPDATEINIFILE)
00483     {
00484         SpiStoreSz(pwszKey, pwszValue, bValue ? L"Yes" : L"No");
00485     }
00486     return (UINT_PTR)pwszKey;
00487 }
00488 
00489 static inline
00490 UINT_PTR
00491 SpiSetBool(BOOL *pbData, INT iValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl)
00492 {
00493     REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
00494     *pbData = iValue ? TRUE : FALSE;
00495     if (fl & SPIF_UPDATEINIFILE)
00496     {
00497         SpiStoreSzInt(pwszKey, pwszValue, iValue);
00498     }
00499     return (UINT_PTR)pwszKey;
00500 }
00501 
00502 static inline
00503 UINT_PTR
00504 SpiSetDWord(PVOID pvData, INT iValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl)
00505 {
00506     REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
00507     *(INT*)pvData = iValue;
00508     if (fl & SPIF_UPDATEINIFILE)
00509     {
00510         SpiStoreDWord(pwszKey, pwszValue, iValue);
00511     }
00512     return (UINT_PTR)pwszKey;
00513 }
00514 
00515 static inline
00516 UINT_PTR
00517 SpiSetInt(PVOID pvData, INT iValue, PCWSTR pwszKey, PCWSTR pwszValue, FLONG fl)
00518 {
00519     REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
00520     *(INT*)pvData = iValue;
00521     if (fl & SPIF_UPDATEINIFILE)
00522     {
00523         SpiStoreSzInt(pwszKey, pwszValue, iValue);
00524     }
00525     return (UINT_PTR)pwszKey;
00526 }
00527 
00528 static inline
00529 UINT_PTR
00530 SpiSetMetric(PVOID pvData, INT iValue, PCWSTR pwszValue, FLONG fl)
00531 {
00532     REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
00533     *(INT*)pvData = iValue;
00534     if (fl & SPIF_UPDATEINIFILE)
00535     {
00536         SpiStoreMetric(pwszValue, iValue);
00537     }
00538     return (UINT_PTR)KEY_METRIC;
00539 }
00540 
00541 static inline
00542 UINT_PTR
00543 SpiSetUserPref(DWORD dwMask, PVOID pvValue, FLONG fl)
00544 {
00545     DWORD dwRegMask;
00546     BOOL bValue = (BOOL)pvValue;
00547 
00548     REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
00549 
00550     /* Set or clear bit according to bValue */
00551     gspv.dwUserPrefMask = bValue ? gspv.dwUserPrefMask | dwMask :
00552                                    gspv.dwUserPrefMask & ~dwMask;
00553 
00554     if (fl & SPIF_UPDATEINIFILE)
00555     {
00556         /* Read current value */
00557         RegReadUserSetting(KEY_DESKTOP,
00558                            VAL_USERPREFMASK,
00559                            REG_BINARY,
00560                            &dwRegMask,
00561                            sizeof(DWORD));
00562 
00563         /* Set or clear bit according to bValue */
00564         dwRegMask = bValue ? dwRegMask | dwMask : dwRegMask & ~dwMask;
00565 
00566         /* write back value */
00567         RegWriteUserSetting(KEY_DESKTOP,
00568                             VAL_USERPREFMASK,
00569                             REG_BINARY,
00570                             &dwRegMask,
00571                             sizeof(DWORD));
00572     }
00573 
00574     return (UINT_PTR)KEY_DESKTOP;
00575 }
00576 
00577 static inline
00578 UINT_PTR
00579 SpiGetUserPref(DWORD dwMask, PVOID pvParam, FLONG fl)
00580 {
00581     INT iValue = gspv.dwUserPrefMask & dwMask ? 1 : 0;
00582     return SpiGetInt(pvParam, &iValue, fl);
00583 }
00584 
00585 static
00586 UINT_PTR
00587 SpiSetWallpaper(PVOID pvParam, FLONG fl)
00588 {
00589     UNICODE_STRING ustr;
00590     WCHAR awc[MAX_PATH];
00591     BOOL bResult;
00592     HBITMAP hbmp, hOldBitmap;
00593     SURFACE *psurfBmp;
00594     ULONG ulTile, ulStyle;
00595 
00596     REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
00597 
00598     if (!pvParam)
00599     {
00600         /* FIXME: Reset Wallpaper to registry value */
00601         return (UINT_PTR)KEY_DESKTOP;
00602     }
00603 
00604     /* Capture UNICODE_STRING */
00605     bResult = SpiMemCopy(&ustr, pvParam, sizeof(UNICODE_STRING), fl & SPIF_PROTECT, 0);
00606     if (!bResult) return 0;
00607     if (ustr.Length > MAX_PATH * sizeof(WCHAR))
00608         return 0;
00609 
00610     /* Copy the string buffer name */
00611     bResult = SpiMemCopy(gspv.awcWallpaper, ustr.Buffer, ustr.Length, fl & SPIF_PROTECT, 0);
00612     if (!bResult) return 0;
00613 
00614     /* Update the UNICODE_STRING */
00615     gspv.ustrWallpaper.Buffer = gspv.awcWallpaper;
00616     gspv.ustrWallpaper.MaximumLength = MAX_PATH * sizeof(WCHAR);
00617     gspv.ustrWallpaper.Length = ustr.Length;
00618     gspv.awcWallpaper[ustr.Length / sizeof(WCHAR)] = 0;
00619 
00620     TRACE("SpiSetWallpaper, name=%S\n", gspv.awcWallpaper);
00621 
00622     /* Update registry */
00623     if (fl & SPIF_UPDATEINIFILE)
00624     {
00625         SpiStoreSz(KEY_DESKTOP, L"Wallpaper", gspv.awcWallpaper);
00626     }
00627 
00628     /* Got a filename? */
00629     if (gspv.awcWallpaper[0] != 0)
00630     {
00631         /* Convert file name to nt file name */
00632         ustr.Buffer = awc;
00633         ustr.MaximumLength = MAX_PATH * sizeof(WCHAR);
00634         ustr.Length = 0;
00635         if (!W32kDosPathNameToNtPathName(gspv.awcWallpaper, &ustr))
00636         {
00637             ERR("RtlDosPathNameToNtPathName_U failed\n");
00638             return 0;
00639         }
00640 
00641         /* Load the Bitmap */
00642         hbmp = UserLoadImage(ustr.Buffer);
00643         if (!hbmp)
00644         {
00645             ERR("UserLoadImage failed\n");
00646             return 0;
00647         }
00648 
00649         /* Try to get the size of the wallpaper */
00650         if(!(psurfBmp = SURFACE_ShareLockSurface(hbmp)))
00651         {
00652             GreDeleteObject(hbmp);
00653             return 0;
00654         }
00655 
00656         gspv.cxWallpaper = psurfBmp->SurfObj.sizlBitmap.cx;
00657         gspv.cyWallpaper = psurfBmp->SurfObj.sizlBitmap.cy;
00658         gspv.WallpaperMode = wmCenter;
00659 
00660         SURFACE_ShareUnlockSurface(psurfBmp);
00661 
00662         /* Change the bitmap's ownership */
00663         GreSetObjectOwner(hbmp, GDI_OBJ_HMGR_PUBLIC);
00664 
00665         /* Yes, Windows really loads the current setting from the registry. */
00666         ulTile = SpiLoadInt(KEY_DESKTOP, L"TileWallpaper", 0);
00667         ulStyle = SpiLoadInt(KEY_DESKTOP, L"WallpaperStyle", 0);
00668         TRACE("SpiSetWallpaper: ulTile=%ld, ulStyle=%d\n", ulTile, ulStyle);
00669 
00670         /* Check the values we found in the registry */
00671         if(ulTile && !ulStyle)
00672         {
00673             gspv.WallpaperMode = wmTile;
00674         }
00675         else if(!ulTile && ulStyle == 2)
00676         {
00677             gspv.WallpaperMode = wmStretch;
00678         }
00679     }
00680     else
00681     {
00682         /* Remove wallpaper */
00683         gspv.cxWallpaper = 0;
00684         gspv.cyWallpaper = 0;
00685         hbmp = 0;
00686     }
00687 
00688     /* Take care of the old wallpaper, if any */
00689     hOldBitmap = gspv.hbmWallpaper;
00690     if(hOldBitmap != NULL)
00691     {
00692         /* Delete the old wallpaper */
00693         GreSetObjectOwner(hOldBitmap, GDI_OBJ_HMGR_POWNED);
00694         GreDeleteObject(hOldBitmap);
00695     }
00696 
00697     /* Set the new wallpaper */
00698     gspv.hbmWallpaper = hbmp;
00699 
00700     NtUserRedrawWindow(UserGetShellWindow(), NULL, NULL, RDW_INVALIDATE | RDW_ERASE);
00701 
00702 
00703     return (UINT_PTR)KEY_DESKTOP;
00704 }
00705 
00706 static BOOL
00707 SpiNotifyNCMetricsChanged()
00708 {
00709     PWND pwndDesktop, pwndCurrent;
00710     HWND *ahwnd;
00711     USER_REFERENCE_ENTRY Ref;
00712     int i;
00713 
00714     pwndDesktop = UserGetDesktopWindow();
00715     ASSERT(pwndDesktop);
00716 
00717     ahwnd = IntWinListChildren(pwndDesktop);
00718     if(!ahwnd)
00719         return FALSE;
00720 
00721     for (i = 0; ahwnd[i]; i++)
00722     {
00723         pwndCurrent = UserGetWindowObject(ahwnd[i]);
00724         if(!pwndCurrent)
00725             continue;
00726 
00727         UserRefObjectCo(pwndCurrent, &Ref);
00728         co_WinPosSetWindowPos(pwndCurrent, 0, pwndCurrent->rcWindow.left,pwndCurrent->rcWindow.top,
00729                                               pwndCurrent->rcWindow.right-pwndCurrent->rcWindow.left
00730                                               ,pwndCurrent->rcWindow.bottom - pwndCurrent->rcWindow.top,
00731                               SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOCOPYBITS|
00732                               SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW);
00733         UserDerefObjectCo(pwndCurrent);
00734     }
00735 
00736     ExFreePool(ahwnd);
00737 
00738     return TRUE;
00739 }
00740 
00741 static
00742 UINT_PTR
00743 SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
00744 {
00745     switch (uiAction)
00746     {
00747         case SPI_GETBEEP:
00748             return SpiGetInt(pvParam, &gspv.bBeep, fl);
00749 
00750         case SPI_SETBEEP:
00751             return SpiSetYesNo(&gspv.bBeep, uiParam, KEY_SOUND, VAL_BEEP, fl);
00752 
00753         case SPI_GETMOUSE:
00754             return SpiGet(pvParam, &gspv.caiMouse, 3 * sizeof(INT), fl);
00755 
00756         case SPI_SETMOUSE:
00757             if (!SpiSet(&gspv.caiMouse, pvParam, 3 * sizeof(INT), fl))
00758                 return 0;
00759             if (fl & SPIF_UPDATEINIFILE)
00760             {
00761                 SpiStoreSzInt(KEY_MOUSE, VAL_MOUSE1, gspv.caiMouse.FirstThreshold);
00762                 SpiStoreSzInt(KEY_MOUSE, VAL_MOUSE2, gspv.caiMouse.SecondThreshold);
00763                 SpiStoreSzInt(KEY_MOUSE, VAL_MOUSE3, gspv.caiMouse.Acceleration);
00764             }
00765             return (UINT_PTR)KEY_MOUSE;
00766 
00767         case SPI_GETBORDER:
00768             return SpiGetInt(pvParam, &gspv.ncm.iBorderWidth, fl);
00769 
00770         case SPI_SETBORDER:
00771             uiParam = max(uiParam, 1);
00772             return SpiSetInt(&gspv.ncm.iBorderWidth, uiParam, KEY_METRIC, VAL_BORDER, fl);
00773 
00774         case SPI_GETKEYBOARDSPEED:
00775             return SpiGetInt(pvParam, &gspv.dwKbdSpeed, fl);
00776 
00777         case SPI_SETKEYBOARDSPEED:
00778             return SpiSetInt(&gspv.dwKbdSpeed, uiParam, KEY_KBD, VAL_KBDSPD, fl);
00779 
00780         case SPI_LANGDRIVER:
00781             ERR("SPI_LANGDRIVER is unimplemented\n");
00782             break;
00783 
00784         case SPI_GETSCREENSAVETIMEOUT:
00785             return SpiGetInt(pvParam, &gspv.iScrSaverTimeout, fl);
00786 
00787         case SPI_SETSCREENSAVETIMEOUT:
00788             return SpiSetInt(&gspv.iScrSaverTimeout, uiParam, KEY_DESKTOP, VAL_SCRTO, fl);
00789 
00790         case SPI_GETSCREENSAVEACTIVE:
00791             return SpiGetInt(pvParam, &gspv.bScrSaverActive, fl);
00792 
00793         case SPI_SETSCREENSAVEACTIVE:
00794             return SpiSetInt(&gspv.bScrSaverActive, uiParam, KEY_DESKTOP, VAL_SCRACT, fl);
00795 
00796         case SPI_GETGRIDGRANULARITY:
00797             return SpiGetInt(pvParam, &gspv.uiGridGranularity, fl);
00798 
00799         case SPI_SETGRIDGRANULARITY:
00800             return SpiSetInt(&gspv.uiGridGranularity, uiParam, KEY_DESKTOP, VAL_GRID, fl);
00801 
00802         case SPI_GETDESKWALLPAPER:
00803             uiParam = min(uiParam, gspv.ustrWallpaper.Length + 1UL);
00804             return SpiGet(pvParam, gspv.awcWallpaper, uiParam, fl);
00805 
00806         case SPI_SETDESKWALLPAPER:
00807             return SpiSetWallpaper(pvParam, fl);
00808 
00809         case SPI_SETDESKPATTERN:
00810             ERR("SPI_SETDESKPATTERN is unimplemented\n");
00811             break;
00812 
00813         case SPI_GETKEYBOARDDELAY:
00814             return SpiGetInt(pvParam, &gspv.iKbdDelay, fl);
00815 
00816         case SPI_SETKEYBOARDDELAY:
00817             return SpiSetInt(&gspv.iKbdDelay, uiParam, KEY_KBD, VAL_KBDDELAY, fl);
00818 
00819         case SPI_ICONHORIZONTALSPACING:
00820             if (pvParam)
00821             {
00822                 return SpiGetInt(pvParam, &gspv.im.iHorzSpacing, fl);
00823             }
00824             uiParam = max(uiParam, 32);
00825             return SpiSetMetric(&gspv.im.iHorzSpacing, uiParam, VAL_ICONSPC, fl);
00826 
00827         case SPI_ICONVERTICALSPACING:
00828             if (pvParam)
00829             {
00830                 return SpiGetInt(pvParam, &gspv.im.iVertSpacing, fl);
00831             }
00832             uiParam = max(uiParam, 32);
00833             return SpiSetMetric(&gspv.im.iVertSpacing, uiParam, VAL_ICONVSPC, fl);
00834 
00835         case SPI_GETICONTITLEWRAP:
00836             return SpiGetInt(pvParam, &gspv.im.iTitleWrap, fl);
00837 
00838         case SPI_SETICONTITLEWRAP:
00839             return SpiSetInt(&gspv.im.iTitleWrap, uiParam, KEY_METRIC, VAL_ITWRAP, fl);
00840 
00841         case SPI_GETMENUDROPALIGNMENT:
00842             return SpiGetInt(pvParam, &gspv.bMenuDropAlign, fl);
00843 
00844         case SPI_SETMENUDROPALIGNMENT:
00845             return SpiSetBool(&gspv.bMenuDropAlign, uiParam, KEY_MDALIGN, VAL_MDALIGN, fl);
00846 
00847         case SPI_SETDOUBLECLKWIDTH:
00848             return SpiSetInt(&gspv.iDblClickWidth, uiParam, KEY_MOUSE, VAL_DBLCLKWIDTH, fl);
00849 
00850         case SPI_SETDOUBLECLKHEIGHT:
00851             return SpiSetInt(&gspv.iDblClickHeight, uiParam, KEY_MOUSE, VAL_DBLCLKHEIGHT, fl);
00852 
00853         case SPI_GETICONTITLELOGFONT:
00854             return SpiGet(pvParam, &gspv.im.lfFont, sizeof(LOGFONTW), fl);
00855 
00856         case SPI_SETICONTITLELOGFONT:
00857             if (!SpiSet(&gspv.im.lfFont, pvParam, sizeof(LOGFONTW), fl))
00858                 return 0;
00859             if (fl & SPIF_UPDATEINIFILE)
00860             {
00861                 SpiStoreFont(L"IconFont", &gspv.im.lfFont);
00862              }
00863             return (UINT_PTR)KEY_METRIC;
00864 
00865         case SPI_SETDOUBLECLICKTIME:
00866             return SpiSetInt(&gspv.iDblClickTime, uiParam, KEY_MOUSE, VAL_DBLCLKTIME, fl);
00867 
00868         case SPI_SETMOUSEBUTTONSWAP:
00869             return SpiSetInt(&gspv.bMouseBtnSwap, uiParam, KEY_MOUSE, VAL_SWAP, fl);
00870 
00871         case SPI_GETFASTTASKSWITCH:
00872             return SpiGetInt(pvParam, &gspv.bFastTaskSwitch, fl);
00873 
00874         case SPI_SETFASTTASKSWITCH:
00875             /* According to Winetest this one is unimplemented */
00876             return 0;
00877 
00878         case SPI_GETDRAGFULLWINDOWS:
00879             return SpiGetInt(pvParam, &gspv.bDragFullWindows, fl);
00880 
00881         case SPI_SETDRAGFULLWINDOWS:
00882             return SpiSetInt(&gspv.bDragFullWindows, uiParam, KEY_DESKTOP, VAL_DRAG, fl);
00883 
00884         case SPI_GETNONCLIENTMETRICS:
00885             return SpiGet(pvParam, &gspv.ncm, sizeof(NONCLIENTMETRICSW), fl);
00886 
00887         case SPI_SETNONCLIENTMETRICS:
00888             if (!SpiSet(&gspv.ncm, pvParam, sizeof(NONCLIENTMETRICSW), fl))
00889                 return 0;
00890             if (fl & SPIF_UPDATEINIFILE)
00891             {
00892                 SpiStoreMetric(VAL_BORDER, gspv.ncm.iBorderWidth);
00893                 SpiStoreMetric(L"ScrollWidth", gspv.ncm.iScrollWidth);
00894                 SpiStoreMetric(L"ScrollHeight", gspv.ncm.iScrollHeight);
00895                 SpiStoreMetric(L"CaptionWidth", gspv.ncm.iCaptionWidth);
00896                 SpiStoreMetric(L"CaptionHeight", gspv.ncm.iCaptionHeight);
00897                 SpiStoreMetric(L"SmCaptionWidth", gspv.ncm.iSmCaptionWidth);
00898                 SpiStoreMetric(L"SmCaptionHeight", gspv.ncm.iSmCaptionHeight);
00899                 SpiStoreMetric(L"MenuWidth", gspv.ncm.iMenuWidth);
00900                 SpiStoreMetric(L"MenuHeight", gspv.ncm.iMenuHeight);
00901 #if (WINVER >= 0x0600)
00902                 SpiStoreMetric(L"PaddedBorderWidth", gspv.ncm.iPaddedBorderWidth);
00903 #endif
00904                 SpiStoreFont(L"CaptionFont", &gspv.ncm.lfCaptionFont);
00905                 SpiStoreFont(L"SmCaptionFont", &gspv.ncm.lfSmCaptionFont);
00906                 SpiStoreFont(L"MenuFont", &gspv.ncm.lfMenuFont);
00907                 SpiStoreFont(L"StatusFont", &gspv.ncm.lfStatusFont);
00908                 SpiStoreFont(L"MessageFont", &gspv.ncm.lfMessageFont);
00909             }
00910             if(!SpiNotifyNCMetricsChanged())
00911                 return 0;
00912             return (UINT_PTR)KEY_METRIC;
00913 
00914         case SPI_GETMINIMIZEDMETRICS:
00915             return SpiGet(pvParam, &gspv.mm, sizeof(MINIMIZEDMETRICS), fl);
00916 
00917         case SPI_SETMINIMIZEDMETRICS:
00918             if (!SpiSet(&gspv.mm, pvParam, sizeof(MINIMIZEDMETRICS), fl))
00919                 return 0;
00920             gspv.mm.iWidth = max(0, gspv.mm.iWidth);
00921             gspv.mm.iHorzGap = max(0, gspv.mm.iHorzGap);
00922             gspv.mm.iVertGap = max(0, gspv.mm.iVertGap);
00923             gspv.mm.iArrange = gspv.mm.iArrange & 0xf;
00924             if (fl & SPIF_UPDATEINIFILE)
00925             {
00926                 SpiStoreMetric(L"MinWidth", gspv.mm.iWidth);
00927                 SpiStoreMetric(L"MinHorzGap", gspv.mm.iHorzGap);
00928                 SpiStoreMetric(L"MinVertGap", gspv.mm.iVertGap);
00929                 SpiStoreMetric(L"MinArrange", gspv.mm.iArrange);
00930             }
00931             return (UINT_PTR)KEY_METRIC;
00932 
00933         case SPI_GETICONMETRICS:
00934             return SpiGet(pvParam, &gspv.im, sizeof(ICONMETRICS), fl);
00935 
00936         case SPI_SETICONMETRICS:
00937             if (!SpiSet(&gspv.im, pvParam, sizeof(ICONMETRICS), fl))
00938                 return 0;
00939             if (fl & SPIF_UPDATEINIFILE)
00940             {
00941                 SpiStoreMetric(VAL_ICONSPC, gspv.im.iHorzSpacing);
00942                 SpiStoreMetric(VAL_ICONVSPC, gspv.im.iVertSpacing);
00943                 SpiStoreMetric(VAL_ITWRAP, gspv.im.iTitleWrap);
00944                 SpiStoreFont(L"IconFont", &gspv.im.lfFont);
00945             }
00946             return (UINT_PTR)KEY_METRIC;
00947 
00948         case SPI_GETWORKAREA:
00949         {
00950             PMONITOR pmonitor = UserGetPrimaryMonitor();
00951 
00952             if(!pmonitor)
00953                 return 0;
00954 
00955             return SpiGet(pvParam, &pmonitor->rcWork, sizeof(RECTL), fl);
00956         }
00957 
00958         case SPI_SETWORKAREA:
00959         {
00960             /* FIXME: We should set the work area of the monitor
00961                       that contains the specified rectangle */
00962             PMONITOR pmonitor = UserGetPrimaryMonitor();
00963             RECT rcWorkArea;
00964 
00965             if(!pmonitor)
00966                 return 0;
00967 
00968             if (!SpiSet(&rcWorkArea, pvParam, sizeof(RECTL), fl))
00969                 return 0;
00970 
00971             /* Verify the new values */
00972             if (rcWorkArea.left < 0 ||
00973                 rcWorkArea.top < 0 ||
00974                 rcWorkArea.right > gpsi->aiSysMet[SM_CXSCREEN] ||
00975                 rcWorkArea.bottom > gpsi->aiSysMet[SM_CYSCREEN] ||
00976                 rcWorkArea.right <= rcWorkArea.left ||
00977                 rcWorkArea.bottom <= rcWorkArea.top)
00978                 return 0;
00979 
00980             pmonitor->rcWork = rcWorkArea;
00981             if (fl & SPIF_UPDATEINIFILE)
00982             {
00983                 // FIXME: What to do?
00984             }
00985             return (UINT_PTR)KEY_DESKTOP;
00986         }
00987 
00988         case SPI_SETPENWINDOWS:
00989             ERR("SPI_SETPENWINDOWS is unimplemented\n");
00990             break;
00991 
00992         case SPI_GETFILTERKEYS:
00993             return SpiGet(pvParam, &gspv.filterkeys, sizeof(FILTERKEYS), fl);
00994 
00995         case SPI_SETFILTERKEYS:
00996             if (!SpiSet(&gspv.filterkeys, pvParam, sizeof(FILTERKEYS), fl))
00997                 return 0;
00998             if (fl & SPIF_UPDATEINIFILE)
00999             {
01000                 // FIXME: What to do?
01001             }
01002             return (UINT_PTR)KEY_DESKTOP;
01003 
01004         case SPI_GETTOGGLEKEYS:
01005             return SpiGet(pvParam, &gspv.togglekeys, sizeof(TOGGLEKEYS), fl);
01006 
01007         case SPI_SETTOGGLEKEYS:
01008             if (!SpiSet(&gspv.togglekeys, pvParam, sizeof(TOGGLEKEYS), fl))
01009                 return 0;
01010             if (fl & SPIF_UPDATEINIFILE)
01011             {
01012                 // FIXME: What to do?
01013             }
01014             return (UINT_PTR)KEY_DESKTOP;
01015 
01016         case SPI_GETMOUSEKEYS:
01017             return SpiGet(pvParam, &gspv.mousekeys, sizeof(MOUSEKEYS), fl);
01018 
01019         case SPI_SETMOUSEKEYS:
01020             if (!SpiSet(&gspv.mousekeys, pvParam, sizeof(MOUSEKEYS), fl))
01021                 return 0;
01022             if (fl & SPIF_UPDATEINIFILE)
01023             {
01024                 // FIXME: What to do?
01025             }
01026             return (UINT_PTR)KEY_DESKTOP;
01027 
01028         case SPI_GETSHOWSOUNDS:
01029             return SpiGetInt(pvParam, &gspv.bShowSounds, fl);
01030 
01031         case SPI_SETSHOWSOUNDS:
01032             return SpiSetBool(&gspv.bShowSounds, uiParam, KEY_SHOWSNDS, VAL_ON, fl);
01033 
01034         case SPI_GETSTICKYKEYS:
01035             if (uiParam != sizeof(STICKYKEYS))
01036                 return 0;
01037             return SpiGetEx(pvParam, &gspv.stickykeys, sizeof(STICKYKEYS), fl);
01038 
01039         case SPI_SETSTICKYKEYS:
01040             if (!SpiSet(&gspv.stickykeys, pvParam, sizeof(STICKYKEYS), fl))
01041                 return 0;
01042             if (fl & SPIF_UPDATEINIFILE)
01043             {
01044                 // FIXME: What to do?
01045             }
01046             return (UINT_PTR)KEY_DESKTOP;
01047 
01048         case SPI_GETACCESSTIMEOUT:
01049             if (uiParam != 0 && uiParam != sizeof(ACCESSTIMEOUT))
01050                 return 0;
01051             return SpiGetEx(pvParam, &gspv.accesstimeout, sizeof(ACCESSTIMEOUT), fl);
01052 
01053         case SPI_SETACCESSTIMEOUT:
01054             if (!SpiSet(&gspv.accesstimeout, pvParam, sizeof(ACCESSTIMEOUT), fl))
01055                 return 0;
01056             if (fl & SPIF_UPDATEINIFILE)
01057             {
01058                 // FIXME: What to do?
01059             }
01060             return (UINT_PTR)KEY_DESKTOP;
01061 
01062         case SPI_GETSERIALKEYS:
01063             return SpiGet(pvParam, &gspv.serialkeys, sizeof(SERIALKEYS), fl);
01064 
01065         case SPI_SETSERIALKEYS:
01066             if (!SpiSet(&gspv.serialkeys, pvParam, sizeof(SERIALKEYS), fl))
01067                 return 0;
01068             if (fl & SPIF_UPDATEINIFILE)
01069             {
01070                 // FIXME: What to do?
01071             }
01072             return (UINT_PTR)KEY_DESKTOP;
01073 
01074         case SPI_GETSOUNDSENTRY:
01075             return SpiGet(pvParam, &gspv.soundsentry, sizeof(SOUNDSENTRY), fl);
01076 
01077         case SPI_SETSOUNDSENTRY:
01078             if (!SpiSet(&gspv.soundsentry, pvParam, sizeof(SOUNDSENTRY), fl))
01079                 return 0;
01080             if (fl & SPIF_UPDATEINIFILE)
01081             {
01082                 // FIXME: What to do?
01083             }
01084             return (UINT_PTR)KEY_DESKTOP;
01085 
01086         case SPI_GETHIGHCONTRAST:
01087             return SpiGet(pvParam, &gspv.highcontrast, sizeof(HIGHCONTRAST), fl);
01088 
01089         case SPI_SETHIGHCONTRAST:
01090             if (!SpiSet(&gspv.highcontrast, pvParam, sizeof(HIGHCONTRAST), fl))
01091                 return 0;
01092             if (fl & SPIF_UPDATEINIFILE)
01093             {
01094                 // FIXME: What to do?
01095             }
01096             return (UINT_PTR)KEY_DESKTOP;
01097 
01098         case SPI_GETKEYBOARDPREF:
01099             return SpiGetInt(pvParam, &gspv.bKbdPref, fl);
01100 
01101         case SPI_SETKEYBOARDPREF:
01102             return SpiSetBool(&gspv.bKbdPref, uiParam, KEY_KDBPREF, VAL_ON, fl);
01103 
01104         case SPI_GETSCREENREADER:
01105             return SpiGetInt(pvParam, &gspv.bScreenReader, fl);
01106 
01107         case SPI_SETSCREENREADER:
01108             return SpiSetBool(&gspv.bScreenReader, uiParam, KEY_SCRREAD, VAL_ON, fl);
01109 
01110         case SPI_GETANIMATION:
01111             return SpiGet(pvParam, &gspv.animationinfo, sizeof(ANIMATIONINFO), fl);
01112 
01113         case SPI_SETANIMATION:
01114             if (!SpiSet(&gspv.animationinfo, pvParam, sizeof(ANIMATIONINFO), fl))
01115                 return 0;
01116             if (fl & SPIF_UPDATEINIFILE)
01117             {
01118                 // FIXME: What to do?
01119             }
01120             return (UINT_PTR)KEY_DESKTOP;
01121 
01122         case SPI_GETFONTSMOOTHING:
01123             return SpiGetInt(pvParam, &gspv.bFontSmoothing, fl);
01124 
01125         case SPI_SETFONTSMOOTHING:
01126             gspv.bFontSmoothing = uiParam ? TRUE : FALSE;
01127             if (fl & SPIF_UPDATEINIFILE)
01128             {
01129                 SpiStoreSzInt(KEY_DESKTOP, VAL_FNTSMOOTH, uiParam ? 2 : 0);
01130             }
01131             return (UINT_PTR)KEY_DESKTOP;
01132 
01133         case SPI_SETDRAGWIDTH:
01134             return SpiSetInt(&gspv.iDragWidth, uiParam, KEY_DESKTOP, VAL_DRAGWIDTH, fl);
01135 
01136         case SPI_SETDRAGHEIGHT:
01137             return SpiSetInt(&gspv.iDragHeight, uiParam, KEY_DESKTOP, VAL_DRAGHEIGHT, fl);
01138 
01139         case SPI_SETHANDHELD:
01140             return SpiSetBool(&gspv.bHandHeld, uiParam, KEY_DESKTOP, L"HandHeld", fl);
01141 
01142         case SPI_GETLOWPOWERTIMEOUT:
01143             return SpiGetInt(pvParam, &gspv.iLowPwrTimeout, fl);
01144 
01145         case SPI_GETPOWEROFFTIMEOUT:
01146             return SpiGetInt(pvParam, &gspv.iPwrOffTimeout, fl);
01147 
01148         case SPI_SETLOWPOWERTIMEOUT:
01149             return SpiSetInt(&gspv.iLowPwrTimeout, uiParam, KEY_DESKTOP, L"LowPowerTimeOut", fl);
01150 
01151         case SPI_SETPOWEROFFTIMEOUT:
01152             return SpiSetInt(&gspv.iPwrOffTimeout, uiParam, KEY_DESKTOP, L"PowerOffTimeOut", fl);
01153 
01154         case SPI_GETLOWPOWERACTIVE:
01155             return SpiGetInt(pvParam, &gspv.iPwrOffTimeout, fl);
01156 
01157         case SPI_GETPOWEROFFACTIVE:
01158             return SpiGetInt(pvParam, &gspv.bPwrOffActive, fl);
01159 
01160         case SPI_SETLOWPOWERACTIVE:
01161             return SpiSetBool(&gspv.bLowPwrActive, uiParam, KEY_DESKTOP, L"LowPowerActive", fl);
01162 
01163         case SPI_SETPOWEROFFACTIVE:
01164             return SpiSetBool(&gspv.bPwrOffActive, uiParam, KEY_DESKTOP, L"PowerOffActive", fl);
01165 
01166         case SPI_SETCURSORS:
01167             ERR("SPI_SETCURSORS is unimplemented\n");
01168             break;
01169 
01170         case SPI_SETICONS:
01171             ERR("SPI_SETICONS is unimplemented\n");
01172             break;
01173 
01174         case SPI_GETDEFAULTINPUTLANG:
01175             if (!gspklBaseLayout)
01176                 return FALSE;
01177 
01178             return SpiGet(pvParam, &gspklBaseLayout->hkl, sizeof(HKL), fl);
01179 
01180         case SPI_SETDEFAULTINPUTLANG:
01181         {
01182             HKL hkl;
01183 
01184             /* Note: SPIF_UPDATEINIFILE is not supported */
01185             if ((fl & SPIF_UPDATEINIFILE) || !SpiSet(&hkl, pvParam, sizeof(hkl), fl))
01186                 return FALSE;
01187 
01188             return UserSetDefaultInputLang(hkl);
01189         }
01190 
01191         case SPI_SETLANGTOGGLE:
01192             ERR("SPI_SETLANGTOGGLE is unimplemented\n");
01193             break;
01194 
01195         case SPI_GETWINDOWSEXTENSION:
01196             ERR("SPI_GETWINDOWSEXTENSION is unimplemented\n");
01197             break;
01198 
01199         case SPI_GETMOUSETRAILS:
01200             return SpiGetInt(pvParam, &gspv.iMouseTrails, fl);
01201 
01202         case SPI_SETMOUSETRAILS:
01203             return SpiSetInt(&gspv.iMouseTrails, uiParam, KEY_MOUSE, VAL_MOUSETRAILS, fl);
01204 
01205         case SPI_GETSNAPTODEFBUTTON:
01206             return SpiGetInt(pvParam, &gspv.bSnapToDefBtn, fl);
01207 
01208         case SPI_SETSNAPTODEFBUTTON:
01209             return SpiSetBool(&gspv.bSnapToDefBtn, uiParam, KEY_MOUSE, VAL_SNAPDEFBTN, fl);
01210 
01211         case SPI_GETMOUSEHOVERWIDTH:
01212             return SpiGetInt(pvParam, &gspv.iMouseHoverWidth, fl);
01213 
01214         case SPI_SETMOUSEHOVERWIDTH:
01215             return SpiSetInt(&gspv.iMouseHoverWidth, uiParam, KEY_MOUSE, VAL_HOVERWIDTH, fl);
01216 
01217         case SPI_GETMOUSEHOVERHEIGHT:
01218             return SpiGetInt(pvParam, &gspv.iMouseHoverHeight, fl);
01219 
01220         case SPI_SETMOUSEHOVERHEIGHT:
01221             return SpiSetInt(&gspv.iMouseHoverHeight, uiParam, KEY_MOUSE, VAL_HOVERHEIGHT, fl);
01222 
01223         case SPI_GETMOUSEHOVERTIME:
01224             return SpiGetInt(pvParam, &gspv.iMouseHoverTime, fl);
01225 
01226         case SPI_SETMOUSEHOVERTIME:
01227            /* See http://msdn2.microsoft.com/en-us/library/ms724947.aspx
01228             * copy text from it, if some agument why xp and 2003 behovir diffent
01229             * only if they do not have SP install
01230             * " Windows Server 2003 and Windows XP: The operating system does not
01231             *   enforce the use of USER_TIMER_MAXIMUM and USER_TIMER_MINIMUM until
01232             *   Windows Server 2003 SP1 and Windows XP SP2 "
01233             */
01234             return SpiSetInt(&gspv.iMouseHoverTime, uiParam, KEY_MOUSE, VAL_HOVERTIME, fl);
01235 
01236         case SPI_GETWHEELSCROLLLINES:
01237             return SpiGetInt(pvParam, &gspv.iWheelScrollLines, fl);
01238 
01239         case SPI_SETWHEELSCROLLLINES:
01240             return SpiSetInt(&gspv.iWheelScrollLines, uiParam, KEY_DESKTOP, VAL_SCRLLLINES, fl);
01241 
01242         case SPI_GETMENUSHOWDELAY:
01243             return SpiGetInt(pvParam, &gspv.dwMenuShowDelay, fl);
01244 
01245         case SPI_SETMENUSHOWDELAY:
01246             return SpiSetInt(&gspv.dwMenuShowDelay, uiParam, KEY_DESKTOP, L"MenuShowDelay", fl);
01247 
01248 #if (_WIN32_WINNT >= 0x0600)
01249         case SPI_GETWHEELSCROLLCHARS:
01250             return SpiGetInt(pvParam, &gspv.uiWheelScrollChars, fl);
01251 
01252         case SPI_SETWHEELSCROLLCHARS:
01253             return SpiSetInt(&gspv.uiWheelScrollChars, uiParam, KEY_DESKTOP, VAL_SCRLLCHARS, fl);
01254 #endif
01255         case SPI_GETSHOWIMEUI:
01256             return SpiGetInt(pvParam, &gspv.bShowImeUi, fl);
01257 
01258         case SPI_SETSHOWIMEUI:
01259             return SpiSetBool(&gspv.bShowImeUi, uiParam, KEY_DESKTOP, L"", fl);
01260 
01261         case SPI_GETMOUSESPEED:
01262             return SpiGetInt(pvParam, &gspv.iMouseSpeed, fl);
01263 
01264         case SPI_SETMOUSESPEED:
01265         {
01266             /* Allowed range is [1:20] */
01267             if ((INT_PTR)pvParam < 1 || (INT_PTR)pvParam > 20)
01268                 return 0;
01269             else
01270                 return SpiSetInt(&gspv.iMouseSpeed, (INT_PTR)pvParam, KEY_MOUSE, VAL_SENSITIVITY, fl);
01271         }
01272 
01273         case SPI_GETSCREENSAVERRUNNING:
01274             return SpiGetInt(pvParam, &gspv.bScrSaverRunning, fl);
01275 
01276         case SPI_SETSCREENSAVERRUNNING:
01277             // FIXME: also return value?
01278             return SpiSetBool(&gspv.bScrSaverRunning, uiParam, KEY_MOUSE, L"", fl);
01279 
01280 #if(WINVER >= 0x0600)
01281         case SPI_GETAUDIODESCRIPTION:
01282             return SpiGet(pvParam, &gspv.audiodesription, sizeof(AUDIODESCRIPTION), fl);
01283 
01284         case SPI_SETAUDIODESCRIPTION:
01285             ERR("SPI_SETAUDIODESCRIPTION is unimplemented\n");
01286             break;
01287 
01288         case SPI_GETSCREENSAVESECURE:
01289             return SpiGetInt(pvParam, &gspv.bScrSaverSecure, fl);
01290 
01291         case SPI_SETSCREENSAVESECURE:
01292             return SpiSetBool(&gspv.bScrSaverSecure, uiParam, KEY_DESKTOP, L"ScreenSaverIsSecure", fl);
01293 #endif
01294 
01295         case SPI_GETACTIVEWINDOWTRACKING:
01296             return SpiGetUserPref(UPM_ACTIVEWINDOWTRACKING, pvParam, fl);
01297 
01298         case SPI_SETACTIVEWINDOWTRACKING:
01299             return SpiSetUserPref(UPM_ACTIVEWINDOWTRACKING, pvParam, fl);
01300 
01301         case SPI_GETMENUANIMATION:
01302             return SpiGetUserPref(UPM_MENUANIMATION, pvParam, fl);
01303 
01304         case SPI_SETMENUANIMATION:
01305             return SpiSetUserPref(UPM_MENUANIMATION, pvParam, fl);
01306 
01307         case SPI_GETCOMBOBOXANIMATION:
01308             return SpiGetUserPref(UPM_COMBOBOXANIMATION, pvParam, fl);
01309 
01310         case SPI_SETCOMBOBOXANIMATION:
01311             return SpiSetUserPref(UPM_COMBOBOXANIMATION, pvParam, fl);
01312 
01313         case SPI_GETLISTBOXSMOOTHSCROLLING:
01314             return SpiGetUserPref(UPM_LISTBOXSMOOTHSCROLLING, pvParam, fl);
01315 
01316         case SPI_SETLISTBOXSMOOTHSCROLLING:
01317             return SpiSetUserPref(UPM_LISTBOXSMOOTHSCROLLING, pvParam, fl);
01318 
01319         case SPI_GETGRADIENTCAPTIONS:
01320             return SpiGetUserPref(UPM_GRADIENTCAPTIONS, pvParam, fl);
01321 
01322         case SPI_SETGRADIENTCAPTIONS:
01323             return SpiSetUserPref(UPM_GRADIENTCAPTIONS, pvParam, fl);
01324 
01325         case SPI_GETKEYBOARDCUES:
01326             return SpiGetUserPref(UPM_KEYBOARDCUES, pvParam, fl);
01327 
01328         case SPI_SETKEYBOARDCUES:
01329             return SpiSetUserPref(UPM_KEYBOARDCUES, pvParam, fl);
01330 
01331         case SPI_GETACTIVEWNDTRKZORDER:
01332             return SpiGetUserPref(UPM_ACTIVEWNDTRKZORDER, pvParam, fl);
01333 
01334         case SPI_SETACTIVEWNDTRKZORDER:
01335             return SpiSetUserPref(UPM_ACTIVEWNDTRKZORDER, pvParam, fl);
01336 
01337         case SPI_GETHOTTRACKING:
01338             return SpiGetUserPref(UPM_HOTTRACKING, pvParam, fl);
01339 
01340         case SPI_SETHOTTRACKING:
01341             return SpiSetUserPref(UPM_HOTTRACKING, pvParam, fl);
01342 
01343         case SPI_GETMENUFADE:
01344             return SpiGetUserPref(UPM_MENUFADE, pvParam, fl);
01345 
01346         case SPI_SETMENUFADE:
01347             return SpiSetUserPref(UPM_MENUFADE, pvParam, fl);
01348 
01349         case SPI_GETSELECTIONFADE:
01350             return SpiGetUserPref(UPM_SELECTIONFADE, pvParam, fl);
01351 
01352         case SPI_SETSELECTIONFADE:
01353             return SpiSetUserPref(UPM_SELECTIONFADE, pvParam, fl);
01354 
01355         case SPI_GETTOOLTIPANIMATION:
01356             return SpiGetUserPref(UPM_TOOLTIPANIMATION, pvParam, fl);
01357 
01358         case SPI_SETTOOLTIPANIMATION:
01359             return SpiSetUserPref(UPM_TOOLTIPANIMATION, pvParam, fl);
01360 
01361         case SPI_GETTOOLTIPFADE:
01362             return SpiGetUserPref(UPM_TOOLTIPFADE, pvParam, fl);
01363 
01364         case SPI_SETTOOLTIPFADE:
01365             return SpiSetUserPref(UPM_TOOLTIPFADE, pvParam, fl);
01366 
01367         case SPI_GETCURSORSHADOW:
01368             return SpiGetUserPref(UPM_CURSORSHADOW, pvParam, fl);
01369 
01370         case SPI_SETCURSORSHADOW:
01371             gspv.bMouseCursorShadow = (BOOL)pvParam;
01372             return SpiSetUserPref(UPM_CURSORSHADOW, pvParam, fl);
01373 
01374         case SPI_GETUIEFFECTS:
01375             return SpiGetUserPref(UPM_UIEFFECTS, pvParam, fl);
01376 
01377         case SPI_SETUIEFFECTS:
01378             return SpiSetUserPref(UPM_UIEFFECTS, pvParam, fl);
01379 
01380         case SPI_GETMOUSESONAR:
01381             return SpiGetInt(pvParam, &gspv.bMouseSonar, fl);
01382 
01383         case SPI_SETMOUSESONAR:
01384             return SpiSetBool(&gspv.bMouseSonar, uiParam, KEY_MOUSE, L"", fl);
01385 
01386         case SPI_GETMOUSECLICKLOCK:
01387             return SpiGetUserPref(UPM_CLICKLOCK, pvParam, fl);
01388 
01389         case SPI_SETMOUSECLICKLOCK:
01390             gspv.bMouseClickLock = (BOOL)pvParam;
01391             return SpiSetUserPref(UPM_CLICKLOCK, pvParam, fl);
01392 
01393         case SPI_GETMOUSEVANISH:
01394             return SpiGetInt(pvParam, &gspv.bMouseVanish, fl);
01395 
01396         case SPI_SETMOUSEVANISH:
01397             return SpiSetBool(&gspv.bMouseVanish, uiParam, KEY_MOUSE, L"", fl);
01398 
01399         case SPI_GETFLATMENU:
01400             return SpiGetInt(pvParam, &gspv.bFlatMenu, fl);
01401 
01402         case SPI_SETFLATMENU:
01403             return SpiSetBool(&gspv.bFlatMenu, uiParam, KEY_MOUSE, L"", fl);
01404 
01405         case SPI_GETDROPSHADOW:
01406             return SpiGetInt(pvParam, &gspv.bDropShadow, fl);
01407 
01408         case SPI_SETDROPSHADOW:
01409             return SpiSetBool(&gspv.bDropShadow, uiParam, KEY_MOUSE, L"", fl);
01410 
01411         case SPI_GETBLOCKSENDINPUTRESETS:
01412             return SpiGetInt(pvParam, &gspv.bBlockSendInputResets, fl);
01413 
01414         case SPI_SETBLOCKSENDINPUTRESETS:
01415             return SpiSetBool(&gspv.bBlockSendInputResets, uiParam, KEY_MOUSE, L"", fl);
01416 
01417 #if(_WIN32_WINNT >= 0x0600)
01418         case SPI_GETDISABLEOVERLAPPEDCONTENT:
01419             return SpiGetInt(pvParam, &gspv.bDisableOverlappedContent, fl);
01420 
01421         case SPI_SETDISABLEOVERLAPPEDCONTENT:
01422             return SpiSetBool(&gspv.bDisableOverlappedContent, uiParam, KEY_MOUSE, L"", fl);
01423 
01424         case SPI_GETCLIENTAREAANIMATION:
01425             return SpiGetInt(pvParam, &gspv.bClientAnimation, fl);
01426 
01427         case SPI_SETCLIENTAREAANIMATION:
01428             return SpiSetBool(&gspv.bClientAnimation, uiParam, KEY_MOUSE, L"", fl);
01429 
01430         case SPI_GETCLEARTYPE:
01431             return SpiGetInt(pvParam, &gspv.bClearType, fl);
01432 
01433         case SPI_SETCLEARTYPE:
01434             return SpiSetBool(&gspv.bClearType, uiParam, KEY_MOUSE, L"", fl);
01435 
01436         case SPI_GETSPEECHRECOGNITION:
01437             return SpiGetInt(pvParam, &gspv.bSpeechRecognition, fl);
01438 
01439         case SPI_SETSPEECHRECOGNITION:
01440             return SpiSetBool(&gspv.bSpeechRecognition, uiParam, KEY_MOUSE, L"", fl);
01441 #endif
01442 
01443         case SPI_GETFOREGROUNDLOCKTIMEOUT:
01444             return SpiGetInt(pvParam, &gspv.dwForegroundLockTimeout, fl);
01445 
01446         case SPI_SETFOREGROUNDLOCKTIMEOUT:
01447             return SpiSetInt(&gspv.dwForegroundLockTimeout, uiParam, KEY_MOUSE, L"", fl);
01448 
01449         case SPI_GETACTIVEWNDTRKTIMEOUT:
01450             return SpiGetInt(pvParam, &gspv.dwActiveTrackingTimeout, fl);
01451 
01452         case SPI_SETACTIVEWNDTRKTIMEOUT:
01453             return SpiSetInt(&gspv.dwActiveTrackingTimeout, uiParam, KEY_MOUSE, L"", fl);
01454 
01455         case SPI_GETFOREGROUNDFLASHCOUNT:
01456             return SpiGetInt(pvParam, &gspv.dwForegroundFlashCount, fl);
01457 
01458         case SPI_SETFOREGROUNDFLASHCOUNT:
01459             return SpiSetInt(&gspv.dwForegroundFlashCount, uiParam, KEY_MOUSE, L"", fl);
01460 
01461         case SPI_GETCARETWIDTH:
01462             return SpiGetInt(pvParam, &gspv.dwCaretWidth, fl);
01463 
01464         case SPI_SETCARETWIDTH:
01465             return SpiSetInt(&gspv.dwCaretWidth, uiParam, KEY_MOUSE, L"", fl);
01466 
01467         case SPI_GETMOUSECLICKLOCKTIME:
01468             return SpiGetInt(pvParam, &gspv.dwMouseClickLockTime, fl);
01469 
01470         case SPI_SETMOUSECLICKLOCKTIME:
01471             return SpiSetDWord(&gspv.dwMouseClickLockTime, uiParam, KEY_DESKTOP, VAL_CLICKLOCKTIME, fl);
01472 
01473         case SPI_GETFONTSMOOTHINGTYPE:
01474             return SpiGetInt(pvParam, &gspv.uiFontSmoothingType, fl);
01475 
01476         case SPI_SETFONTSMOOTHINGTYPE:
01477             return SpiSetInt(&gspv.uiFontSmoothingType, uiParam, KEY_MOUSE, L"", fl);
01478 
01479         case SPI_GETFONTSMOOTHINGCONTRAST:
01480             return SpiGetInt(pvParam, &gspv.uiFontSmoothingContrast, fl);
01481 
01482         case SPI_SETFONTSMOOTHINGCONTRAST:
01483             return SpiSetInt(&gspv.uiFontSmoothingContrast, uiParam, KEY_MOUSE, L"", fl);
01484 
01485         case SPI_GETFOCUSBORDERWIDTH:
01486             return SpiGetInt(pvParam, &gspv.uiFocusBorderWidth, fl);
01487 
01488         case SPI_SETFOCUSBORDERWIDTH:
01489             return SpiSetInt(&gspv.uiFocusBorderWidth, uiParam, KEY_MOUSE, L"", fl);
01490 
01491         case SPI_GETFOCUSBORDERHEIGHT:
01492             return SpiGetInt(pvParam, &gspv.uiFocusBorderHeight, fl);
01493 
01494         case SPI_SETFOCUSBORDERHEIGHT:
01495             return SpiSetInt(&gspv.uiFocusBorderHeight, uiParam, KEY_MOUSE, L"", fl);
01496 
01497         case SPI_GETFONTSMOOTHINGORIENTATION:
01498             return SpiGetInt(pvParam, &gspv.uiFontSmoothingOrientation, fl);
01499 
01500         case SPI_SETFONTSMOOTHINGORIENTATION:
01501             return SpiSetInt(&gspv.uiFontSmoothingOrientation, uiParam, KEY_MOUSE, L"", fl);
01502 
01503         /* The following are undocumented, but valid SPI values */
01504         case 0x1010:
01505         case 0x1011:
01506         case 0x1028:
01507         case 0x1029:
01508         case 0x102A:
01509         case 0x102B:
01510         case 0x102C:
01511         case 0x102D:
01512         case 0x102E:
01513         case 0x102F:
01514         case 0x1030:
01515         case 0x1031:
01516         case 0x1032:
01517         case 0x1033:
01518         case 0x1034:
01519         case 0x1035:
01520         case 0x1036:
01521         case 0x1037:
01522         case 0x1038:
01523         case 0x1039:
01524         case 0x103A:
01525         case 0x103B:
01526         case 0x103C:
01527         case 0x103D:
01528             ERR("Undocumented SPI value %x is unimplemented\n", uiAction);
01529             break;
01530 
01531         default:
01532             ERR("Invalid SPI value: %d\n", uiAction);
01533             EngSetLastError(ERROR_INVALID_PARAMETER);
01534             return 0;
01535     }
01536 
01537     return 0;
01538 }
01539 
01540 BOOL
01541 FASTCALL
01542 UserSystemParametersInfo(
01543     UINT uiAction,
01544     UINT uiParam,
01545     PVOID pvParam,
01546     UINT fWinIni)
01547 {
01548     ULONG_PTR ulResult;
01549     PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
01550 
01551     ASSERT(ppi);
01552 
01553     if (!gbSpiInitialized)
01554     {
01555         KeRosDumpStackFrames(NULL, 20);
01556         //ASSERT(FALSE);
01557         return FALSE;
01558     }
01559 
01560     /* Get a pointer to the current Windowstation */
01561     if (!ppi->prpwinsta)
01562     {
01563         ERR("UserSystemParametersInfo called without active windowstation.\n");
01564         //ASSERT(FALSE);
01565         //return FALSE;
01566     }
01567 
01568     /* Do the actual operation */
01569     ulResult = SpiGetSet(uiAction, uiParam, pvParam, fWinIni);
01570 
01571     /* Did we change something? */
01572     if (ulResult > 1)
01573     {
01574         SpiFixupValues();
01575 
01576         /* Update system metrics */
01577         InitMetrics();
01578 
01579         /* Send notification to toplevel windows, if requested */
01580         if (fWinIni & (SPIF_SENDCHANGE | SPIF_SENDWININICHANGE))
01581         {
01582             /* Send WM_SETTINGCHANGE to all toplevel windows */
01583             co_IntSendMessageTimeout(HWND_BROADCAST,
01584                                      WM_SETTINGCHANGE,
01585                                      (WPARAM)uiAction,
01586                                      (LPARAM)ulResult,
01587                                      SMTO_NORMAL,
01588                                      100,
01589                                      &ulResult);
01590         }
01591         ulResult = 1;
01592     }
01593 
01594     return ulResult;
01595 }
01596 
01597 BOOL
01598 APIENTRY
01599 NtUserSystemParametersInfo(
01600     UINT uiAction,
01601     UINT uiParam,
01602     PVOID pvParam,
01603     UINT fWinIni)
01604 {
01605     BOOL bResult;
01606 
01607     TRACE("Enter NtUserSystemParametersInfo(%d)\n", uiAction);
01608     UserEnterExclusive();
01609 
01610     // FIXME: Get rid of the flags and only use this from um. kernel can access data directly.
01611     /* Set UM memory protection flag */
01612     fWinIni |= SPIF_PROTECT;
01613 
01614     /* Call internal function */
01615     bResult = UserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
01616 
01617     TRACE("Leave NtUserSystemParametersInfo, returning %d\n", bResult);
01618     UserLeave();
01619 
01620     return bResult;
01621 }
01622 
01623 /* EOF */

Generated on Sat May 26 2012 04:37:26 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.