[WIN32SS][USER] fixing couple typos for WINVER >= 0x600
[reactos.git] / win32ss / user / ntuser / sysparams.c
index 635a93c..7eedc02 100644 (file)
@@ -2,7 +2,7 @@
  * COPYRIGHT:        GPL, see COPYING in the top level directory
  * PROJECT:          ReactOS win32 kernel mode subsystem server
  * PURPOSE:          System parameters functions
- * FILE:             subsystems/win32/win32k/ntuser/sysparams.c
+ * FILE:             win32ss/user/ntuser/sysparams.c
  * PROGRAMER:        Timo Kreuzer (timo.kreuzer@reactos.org)
  */
 
@@ -186,7 +186,7 @@ SpiLoadFont(PLOGFONTW plfOut, LPWSTR pwszValueName, PLOGFONTW plfDefault)
 
 static
 VOID
-SpiFixupValues()
+SpiFixupValues(VOID)
 {
     /* Fixup values */
     gspv.ncm.iCaptionWidth = max(gspv.ncm.iCaptionWidth, 8);
@@ -210,7 +210,7 @@ SpiFixupValues()
 
 static
 VOID
-SpiUpdatePerUserSystemParameters()
+SpiUpdatePerUserSystemParameters(VOID)
 {
     static LOGFONTW lf1 = {-11, 0, 0, 0, FW_NORMAL, FALSE, FALSE,
                            FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY,
@@ -222,7 +222,7 @@ SpiUpdatePerUserSystemParameters()
     TRACE("Enter SpiUpdatePerUserSystemParameters\n");
 
     /* Clear the structure */
-    memset(&gspv, 0, sizeof(gspv));
+    RtlZeroMemory(&gspv, sizeof(gspv));
 
     /* Load mouse settings */
     gspv.caiMouse.FirstThreshold = SpiLoadMouse(VAL_MOUSE1, 6);
@@ -282,19 +282,18 @@ SpiUpdatePerUserSystemParameters()
     gspv.bMouseClickLock = (gspv.dwUserPrefMask & UPM_CLICKLOCK) != 0;
     gspv.bMouseCursorShadow = (gspv.dwUserPrefMask & UPM_CURSORSHADOW) != 0;
 #if (_WIN32_WINNT >= 0x0600)
-    gspv.iWheelScrollChars = SpiLoadInt(KEY_DESKTOP, VAL_SCRLLCHARS, 3);
+    gspv.uiWheelScrollChars = SpiLoadInt(KEY_DESKTOP, VAL_SCRLLCHARS, 3);
 #endif
 
     /* Some hardcoded values for now */
 
     gspv.tmCaptionFont.tmAveCharWidth = 6;
     gspv.bBeep = TRUE;
-    gspv.bFlatMenu = FALSE;
     gspv.uiFocusBorderWidth = 1;
     gspv.uiFocusBorderHeight = 1;
     gspv.bMenuDropAlign = 1;
-    gspv.bDropShadow = 1;
     gspv.dwMenuShowDelay = 100;
+    gspv.dwForegroundFlashCount = 3;
 
     gspv.iScrSaverTimeout = SpiLoadTimeOut();
     gspv.bScrSaverActive = FALSE;
@@ -303,6 +302,16 @@ SpiUpdatePerUserSystemParameters()
     gspv.bScrSaverSecure = FALSE;
 #endif
 
+    gspv.accesstimeout.cbSize = sizeof(ACCESSTIMEOUT);
+    gspv.filterkeys.cbSize = sizeof(FILTERKEYS);
+    gspv.togglekeys.cbSize = sizeof(TOGGLEKEYS);
+    gspv.mousekeys.cbSize = sizeof(MOUSEKEYS);
+    gspv.stickykeys.cbSize = sizeof(STICKYKEYS);
+    gspv.serialkeys.cbSize = sizeof(SERIALKEYS);
+    gspv.soundsentry.cbSize = sizeof(SOUNDSENTRYW);
+    gspv.highcontrast.cbSize = sizeof(HIGHCONTRASTW);
+    gspv.animationinfo.cbSize = sizeof(ANIMATIONINFO);
+
     /* Make sure we don't use broken values */
     SpiFixupValues();
 
@@ -316,10 +325,11 @@ SpiUpdatePerUserSystemParameters()
        if (SPITESTPREF(UPM_COMBOBOXANIMATION)) gpsi->PUSIFlags |= PUSIF_COMBOBOXANIMATION;
        if (SPITESTPREF(UPM_LISTBOXSMOOTHSCROLLING)) gpsi->PUSIFlags |= PUSIF_LISTBOXSMOOTHSCROLLING;
     }
+    gdwLanguageToggleKey = UserGetLanguageToggle();
 }
 
 BOOL
-InitSysParams()
+InitSysParams(VOID)
 {
     SpiUpdatePerUserSystemParameters();
     gbSpiInitialized = TRUE;
@@ -372,8 +382,8 @@ SpiStoreSz(PCWSTR pwszKey, PCWSTR pwszValue, PCWSTR pwsz)
     RegWriteUserSetting(pwszKey,
                         pwszValue,
                         REG_SZ,
-                        (PWSTR)pwsz,
-                        wcslen(pwsz) * sizeof(WCHAR));
+                        pwsz,
+                        (wcslen(pwsz) + 1) * sizeof(WCHAR));
 }
 
 static
@@ -414,7 +424,7 @@ SpiStoreFont(PCWSTR pwszValue, LOGFONTW* plogfont)
 // FIXME: get rid of the flags and only use this from um. kernel can access data directly.
 static
 UINT_PTR
-SpiMemCopy(PVOID pvDst, PVOID pvSrc, ULONG cbSize, BOOL bProtect, BOOL bToUser)
+SpiMemCopy(PVOID pvDst, PVOID pvSrc, ULONG cbSize, BOOL bProtect)
 {
     NTSTATUS Status = STATUS_SUCCESS;
 
@@ -422,32 +432,25 @@ SpiMemCopy(PVOID pvDst, PVOID pvSrc, ULONG cbSize, BOOL bProtect, BOOL bToUser)
     {
         _SEH2_TRY
         {
-            if (bToUser)
-            {
-                ProbeForWrite(pvDst, cbSize, 1);
-            }
-            else
-            {
-                ProbeForRead(pvSrc, cbSize, 1);
-            }
-            memcpy(pvDst, pvSrc, cbSize);
+            RtlCopyMemory(pvDst, pvSrc, cbSize);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
             Status = _SEH2_GetExceptionCode();
         }
-        _SEH2_END
+        _SEH2_END;
     }
     else
     {
-        memcpy(pvDst, pvSrc, cbSize);
+        RtlCopyMemory(pvDst, pvSrc, cbSize);
     }
 
     if (!NT_SUCCESS(Status))
     {
         SetLastNtError(Status);
-        ERR("SpiMemCopy failed, pvDst=%p, pvSrc=%p, bProtect=%d, bToUser=%d\n", pvDst, pvSrc, bProtect, bToUser);
+        ERR("SpiMemCopy failed, pvDst=%p, pvSrc=%p, bProtect=%d\n", pvDst, pvSrc, bProtect);
     }
+
     return NT_SUCCESS(Status);
 }
 
@@ -456,7 +459,7 @@ UINT_PTR
 SpiGet(PVOID pvParam, PVOID pvData, ULONG cbSize, FLONG fl)
 {
     REQ_INTERACTIVE_WINSTA(ERROR_ACCESS_DENIED);
-    return SpiMemCopy(pvParam, pvData, cbSize, fl & SPIF_PROTECT, TRUE);
+    return SpiMemCopy(pvParam, pvData, cbSize, fl & SPIF_PROTECT);
 }
 
 static inline
@@ -464,7 +467,7 @@ UINT_PTR
 SpiSet(PVOID pvData, PVOID pvParam, ULONG cbSize, FLONG fl)
 {
     REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
-    return SpiMemCopy(pvData, pvParam, cbSize, fl & SPIF_PROTECT, FALSE);
+    return SpiMemCopy(pvData, pvParam, cbSize, fl & SPIF_PROTECT);
 }
 
 static inline
@@ -558,7 +561,7 @@ UINT_PTR
 SpiSetUserPref(DWORD dwMask, PVOID pvValue, FLONG fl)
 {
     DWORD dwRegMask;
-    BOOL bValue = (BOOL)pvValue;
+    BOOL bValue = PtrToUlong(pvValue);
 
     REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
 
@@ -569,14 +572,18 @@ SpiSetUserPref(DWORD dwMask, PVOID pvValue, FLONG fl)
     if (fl & SPIF_UPDATEINIFILE)
     {
         /* Read current value */
-        RegReadUserSetting(KEY_DESKTOP,
-                           VAL_USERPREFMASK,
-                           REG_BINARY,
-                           &dwRegMask,
-                           sizeof(DWORD));
+        if (!RegReadUserSetting(KEY_DESKTOP,
+                                VAL_USERPREFMASK,
+                                REG_BINARY,
+                                &dwRegMask,
+                                sizeof(DWORD)))
+        {
+            WARN("Failed to read UserPreferencesMask setting\n");
+            dwRegMask = 0;
+        }
 
         /* Set or clear bit according to bValue */
-        dwRegMask = bValue ? dwRegMask | dwMask : dwRegMask & ~dwMask;
+        dwRegMask = bValue ? (dwRegMask | dwMask) : (dwRegMask & ~dwMask);
 
         /* write back value */
         RegWriteUserSetting(KEY_DESKTOP,
@@ -617,14 +624,22 @@ SpiSetWallpaper(PVOID pvParam, FLONG fl)
     }
 
     /* Capture UNICODE_STRING */
-    bResult = SpiMemCopy(&ustr, pvParam, sizeof(ustr), fl & SPIF_PROTECT, 0);
-    if (!bResult) return 0;
+    bResult = SpiMemCopy(&ustr, pvParam, sizeof(ustr), fl & SPIF_PROTECT);
+    if (!bResult)
+    {
+        return 0;
+    }
     if (ustr.Length > MAX_PATH * sizeof(WCHAR))
+    {
         return 0;
+    }
 
     /* Copy the string buffer name */
-    bResult = SpiMemCopy(gspv.awcWallpaper, ustr.Buffer, ustr.Length, fl & SPIF_PROTECT, 0);
-    if (!bResult) return 0;
+    bResult = SpiMemCopy(gspv.awcWallpaper, ustr.Buffer, ustr.Length, fl & SPIF_PROTECT);
+    if (!bResult)
+    {
+        return 0;
+    }
 
     /* Update the UNICODE_STRING */
     gspv.ustrWallpaper.Buffer = gspv.awcWallpaper;
@@ -662,7 +677,7 @@ SpiSetWallpaper(PVOID pvParam, FLONG fl)
         }
 
         /* Try to get the size of the wallpaper */
-        if(!(psurfBmp = SURFACE_ShareLockSurface(hbmp)))
+        if (!(psurfBmp = SURFACE_ShareLockSurface(hbmp)))
         {
             GreDeleteObject(hbmp);
             return 0;
@@ -683,13 +698,24 @@ SpiSetWallpaper(PVOID pvParam, FLONG fl)
         TRACE("SpiSetWallpaper: ulTile=%lu, ulStyle=%lu\n", ulTile, ulStyle);
 
         /* Check the values we found in the registry */
-        if(ulTile && !ulStyle)
+        if (ulTile && !ulStyle)
         {
             gspv.WallpaperMode = wmTile;
         }
-        else if(!ulTile && ulStyle == 2)
+        else if (!ulTile && ulStyle)
         {
-            gspv.WallpaperMode = wmStretch;
+            if (ulStyle == 2)
+            {
+                gspv.WallpaperMode = wmStretch;
+            }
+            else if (ulStyle == 6)
+            {
+                gspv.WallpaperMode = wmFit;
+            }
+            else if (ulStyle == 10)
+            {
+                gspv.WallpaperMode = wmFill;
+            }
         }
     }
     else
@@ -719,7 +745,7 @@ SpiSetWallpaper(PVOID pvParam, FLONG fl)
 }
 
 static BOOL
-SpiNotifyNCMetricsChanged()
+SpiNotifyNCMetricsChanged(VOID)
 {
     PWND pwndDesktop, pwndCurrent;
     HWND *ahwnd;
@@ -874,7 +900,7 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
             if (fl & SPIF_UPDATEINIFILE)
             {
                 SpiStoreFont(L"IconFont", &gspv.im.lfFont);
-             }
+            }
             return (UINT_PTR)KEY_METRIC;
 
         case SPI_SETDOUBLECLICKTIME:
@@ -888,7 +914,7 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
 
         case SPI_SETFASTTASKSWITCH:
             /* According to Winetest this one is unimplemented */
-            return 0;
+            return 1;
 
         case SPI_GETDRAGFULLWINDOWS:
             return SpiGetInt(pvParam, &gspv.bDragFullWindows, fl);
@@ -897,11 +923,20 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
             return SpiSetInt(&gspv.bDragFullWindows, uiParam, KEY_DESKTOP, VAL_DRAG, fl);
 
         case SPI_GETNONCLIENTMETRICS:
+        {
             return SpiGet(pvParam, &gspv.ncm, sizeof(NONCLIENTMETRICSW), fl);
+        }
 
         case SPI_SETNONCLIENTMETRICS:
-            if (!SpiSet(&gspv.ncm, pvParam, sizeof(NONCLIENTMETRICSW), fl))
+        {
+            LPNONCLIENTMETRICSW metrics = (LPNONCLIENTMETRICSW)pvParam;
+
+            /* Fixup user's structure size */
+            metrics->cbSize = sizeof(NONCLIENTMETRICSW);
+            
+            if (!SpiSet(&gspv.ncm, metrics, sizeof(NONCLIENTMETRICSW), fl))
                 return 0;
+
             if (fl & SPIF_UPDATEINIFILE)
             {
                 SpiStoreMetric(VAL_BORDER, gspv.ncm.iBorderWidth);
@@ -922,20 +957,33 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
                 SpiStoreFont(L"StatusFont", &gspv.ncm.lfStatusFont);
                 SpiStoreFont(L"MessageFont", &gspv.ncm.lfMessageFont);
             }
+
             if(!SpiNotifyNCMetricsChanged())
                 return 0;
+
             return (UINT_PTR)KEY_METRIC;
+        }
 
         case SPI_GETMINIMIZEDMETRICS:
+        {
             return SpiGet(pvParam, &gspv.mm, sizeof(MINIMIZEDMETRICS), fl);
+        }
 
         case SPI_SETMINIMIZEDMETRICS:
-            if (!SpiSet(&gspv.mm, pvParam, sizeof(MINIMIZEDMETRICS), fl))
+        {
+            LPMINIMIZEDMETRICS metrics = (LPMINIMIZEDMETRICS)pvParam;
+
+            /* Fixup user's structure size */
+            metrics->cbSize = sizeof(MINIMIZEDMETRICS);
+
+            if (!SpiSet(&gspv.mm, metrics, sizeof(MINIMIZEDMETRICS), fl))
                 return 0;
+
             gspv.mm.iWidth = max(0, gspv.mm.iWidth);
             gspv.mm.iHorzGap = max(0, gspv.mm.iHorzGap);
             gspv.mm.iVertGap = max(0, gspv.mm.iVertGap);
             gspv.mm.iArrange = gspv.mm.iArrange & 0xf;
+
             if (fl & SPIF_UPDATEINIFILE)
             {
                 SpiStoreMetric(L"MinWidth", gspv.mm.iWidth);
@@ -943,14 +991,25 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
                 SpiStoreMetric(L"MinVertGap", gspv.mm.iVertGap);
                 SpiStoreMetric(L"MinArrange", gspv.mm.iArrange);
             }
+
             return (UINT_PTR)KEY_METRIC;
+        }
 
         case SPI_GETICONMETRICS:
-            return SpiGet(pvParam, &gspv.im, sizeof(ICONMETRICS), fl);
+        {
+            return SpiGet(pvParam, &gspv.im, sizeof(ICONMETRICSW), fl);
+        }
 
         case SPI_SETICONMETRICS:
-            if (!SpiSet(&gspv.im, pvParam, sizeof(ICONMETRICS), fl))
+        {
+            LPICONMETRICSW metrics = (LPICONMETRICSW)pvParam;
+
+            /* Fixup user's structure size */
+            metrics->cbSize = sizeof(ICONMETRICSW);
+
+            if (!SpiSet(&gspv.im, metrics, sizeof(ICONMETRICSW), fl))
                 return 0;
+
             if (fl & SPIF_UPDATEINIFILE)
             {
                 SpiStoreMetric(VAL_ICONSPC, gspv.im.iHorzSpacing);
@@ -959,6 +1018,7 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
                 SpiStoreFont(L"IconFont", &gspv.im.lfFont);
             }
             return (UINT_PTR)KEY_METRIC;
+        }
 
         case SPI_GETWORKAREA:
         {
@@ -1005,40 +1065,103 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
             break;
 
         case SPI_GETFILTERKEYS:
+        {
+            LPFILTERKEYS FilterKeys = (LPFILTERKEYS)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(FILTERKEYS))
+                return 0;
+
+            if (!FilterKeys || FilterKeys->cbSize != sizeof(FILTERKEYS))
+                return 0;
+
             return SpiGet(pvParam, &gspv.filterkeys, sizeof(FILTERKEYS), fl);
+        }
 
         case SPI_SETFILTERKEYS:
+        {
+            LPFILTERKEYS FilterKeys = (LPFILTERKEYS)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(FILTERKEYS))
+                return 0;
+
+            if (!FilterKeys || FilterKeys->cbSize != sizeof(FILTERKEYS))
+                return 0;
+
             if (!SpiSet(&gspv.filterkeys, pvParam, sizeof(FILTERKEYS), fl))
                 return 0;
+
             if (fl & SPIF_UPDATEINIFILE)
             {
                 // FIXME: What to do?
             }
             return (UINT_PTR)KEY_DESKTOP;
+        }
 
         case SPI_GETTOGGLEKEYS:
+        {
+            LPTOGGLEKEYS ToggleKeys = (LPTOGGLEKEYS)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(TOGGLEKEYS))
+                return 0;
+
+            if (!ToggleKeys || ToggleKeys->cbSize != sizeof(TOGGLEKEYS))
+                return 0;
+
             return SpiGet(pvParam, &gspv.togglekeys, sizeof(TOGGLEKEYS), fl);
+        }
 
         case SPI_SETTOGGLEKEYS:
+        {
+            LPTOGGLEKEYS ToggleKeys = (LPTOGGLEKEYS)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(TOGGLEKEYS))
+                return 0;
+
+            if (!ToggleKeys || ToggleKeys->cbSize != sizeof(TOGGLEKEYS))
+                return 0;
+
             if (!SpiSet(&gspv.togglekeys, pvParam, sizeof(TOGGLEKEYS), fl))
                 return 0;
+
             if (fl & SPIF_UPDATEINIFILE)
             {
                 // FIXME: What to do?
             }
             return (UINT_PTR)KEY_DESKTOP;
+        }
 
         case SPI_GETMOUSEKEYS:
+        {
+            LPMOUSEKEYS MouseKeys = (LPMOUSEKEYS)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(MOUSEKEYS))
+                return 0;
+
+            if (!MouseKeys || MouseKeys->cbSize != sizeof(MOUSEKEYS))
+                return 0;
+
             return SpiGet(pvParam, &gspv.mousekeys, sizeof(MOUSEKEYS), fl);
+        }
 
         case SPI_SETMOUSEKEYS:
+        {
+            LPMOUSEKEYS MouseKeys = (LPMOUSEKEYS)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(MOUSEKEYS))
+                return 0;
+
+            if (!MouseKeys || MouseKeys->cbSize != sizeof(MOUSEKEYS))
+                return 0;
+
             if (!SpiSet(&gspv.mousekeys, pvParam, sizeof(MOUSEKEYS), fl))
                 return 0;
+
             if (fl & SPIF_UPDATEINIFILE)
             {
                 // FIXME: What to do?
             }
             return (UINT_PTR)KEY_DESKTOP;
+        }
 
         case SPI_GETSHOWSOUNDS:
             return SpiGetInt(pvParam, &gspv.bShowSounds, fl);
@@ -1047,68 +1170,173 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
             return SpiSetBool(&gspv.bShowSounds, uiParam, KEY_SHOWSNDS, VAL_ON, fl);
 
         case SPI_GETSTICKYKEYS:
-            if (uiParam != sizeof(STICKYKEYS))
+        {
+            LPSTICKYKEYS StickyKeys = (LPSTICKYKEYS)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(STICKYKEYS))
+                return 0;
+
+            if (!StickyKeys || StickyKeys->cbSize != sizeof(STICKYKEYS))
                 return 0;
+
             return SpiGetEx(pvParam, &gspv.stickykeys, sizeof(STICKYKEYS), fl);
+        }
 
         case SPI_SETSTICKYKEYS:
+        {
+            LPSTICKYKEYS StickyKeys = (LPSTICKYKEYS)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(STICKYKEYS))
+                return 0;
+
+            if (!StickyKeys || StickyKeys->cbSize != sizeof(STICKYKEYS))
+                return 0;
+
             if (!SpiSet(&gspv.stickykeys, pvParam, sizeof(STICKYKEYS), fl))
                 return 0;
+
             if (fl & SPIF_UPDATEINIFILE)
             {
                 // FIXME: What to do?
             }
             return (UINT_PTR)KEY_DESKTOP;
+        }
 
         case SPI_GETACCESSTIMEOUT:
+        {
+            LPACCESSTIMEOUT AccessTimeout = (LPACCESSTIMEOUT)pvParam;
+
             if (uiParam != 0 && uiParam != sizeof(ACCESSTIMEOUT))
                 return 0;
+
+            if (!AccessTimeout || AccessTimeout->cbSize != sizeof(ACCESSTIMEOUT))
+                return 0;
+
             return SpiGetEx(pvParam, &gspv.accesstimeout, sizeof(ACCESSTIMEOUT), fl);
+        }
 
         case SPI_SETACCESSTIMEOUT:
+        {
+            LPACCESSTIMEOUT AccessTimeout = (LPACCESSTIMEOUT)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(ACCESSTIMEOUT))
+            {
+                return 0;
+            }
+
+            if (!AccessTimeout || AccessTimeout->cbSize != sizeof(ACCESSTIMEOUT))
+            {
+                return 0;
+            }
+
             if (!SpiSet(&gspv.accesstimeout, pvParam, sizeof(ACCESSTIMEOUT), fl))
                 return 0;
+
             if (fl & SPIF_UPDATEINIFILE)
             {
                 // FIXME: What to do?
             }
             return (UINT_PTR)KEY_DESKTOP;
+        }
 
         case SPI_GETSERIALKEYS:
+        {
+            LPSERIALKEYS SerialKeys = (LPSERIALKEYS)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(SERIALKEYS))
+                return 0;
+
+            if (!SerialKeys || SerialKeys->cbSize != sizeof(SERIALKEYS))
+                return 0;
+
             return SpiGet(pvParam, &gspv.serialkeys, sizeof(SERIALKEYS), fl);
+        }
 
         case SPI_SETSERIALKEYS:
+        {
+            LPSERIALKEYS SerialKeys = (LPSERIALKEYS)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(SERIALKEYS))
+                return 0;
+
+            if (!SerialKeys || SerialKeys->cbSize != sizeof(SERIALKEYS))
+                return 0;
+
             if (!SpiSet(&gspv.serialkeys, pvParam, sizeof(SERIALKEYS), fl))
                 return 0;
+
             if (fl & SPIF_UPDATEINIFILE)
             {
                 // FIXME: What to do?
             }
             return (UINT_PTR)KEY_DESKTOP;
+        }
 
         case SPI_GETSOUNDSENTRY:
-            return SpiGet(pvParam, &gspv.soundsentry, sizeof(SOUNDSENTRY), fl);
+        {
+            LPSOUNDSENTRYW SoundsEntry = (LPSOUNDSENTRYW)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(SOUNDSENTRYW))
+                return 0;
+
+            if (!SoundsEntry || SoundsEntry->cbSize != sizeof(SOUNDSENTRYW))
+                return 0;
+
+            return SpiGet(pvParam, &gspv.soundsentry, sizeof(SOUNDSENTRYW), fl);
+        }
 
         case SPI_SETSOUNDSENTRY:
-            if (!SpiSet(&gspv.soundsentry, pvParam, sizeof(SOUNDSENTRY), fl))
+        {
+            LPSOUNDSENTRYW SoundsEntry = (LPSOUNDSENTRYW)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(SOUNDSENTRYW))
+                return 0;
+
+            if (!SoundsEntry || SoundsEntry->cbSize != sizeof(SOUNDSENTRYW))
+                return 0;
+
+            if (!SpiSet(&gspv.soundsentry, pvParam, sizeof(SOUNDSENTRYW), fl))
                 return 0;
+
             if (fl & SPIF_UPDATEINIFILE)
             {
                 // FIXME: What to do?
             }
             return (UINT_PTR)KEY_DESKTOP;
+        }
 
         case SPI_GETHIGHCONTRAST:
-            return SpiGet(pvParam, &gspv.highcontrast, sizeof(HIGHCONTRAST), fl);
+        {
+            LPHIGHCONTRASTW highcontrast = (LPHIGHCONTRASTW)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(HIGHCONTRASTW))
+                return 0;
+
+            if (!highcontrast || highcontrast->cbSize != sizeof(HIGHCONTRASTW))
+                return 0;
+
+            return SpiGet(pvParam, &gspv.highcontrast, sizeof(HIGHCONTRASTW), fl);
+        }
 
         case SPI_SETHIGHCONTRAST:
-            if (!SpiSet(&gspv.highcontrast, pvParam, sizeof(HIGHCONTRAST), fl))
+        {
+            LPHIGHCONTRASTW highcontrast = (LPHIGHCONTRASTW)pvParam;
+
+            if (uiParam != 0 && uiParam != sizeof(HIGHCONTRASTW))
+                return 0;
+
+            if (!highcontrast || highcontrast->cbSize != sizeof(HIGHCONTRASTW))
+                return 0;
+
+            if (!SpiSet(&gspv.highcontrast, pvParam, sizeof(HIGHCONTRASTW), fl))
                 return 0;
+
             if (fl & SPIF_UPDATEINIFILE)
             {
                 // FIXME: What to do?
             }
             return (UINT_PTR)KEY_DESKTOP;
+        }
 
         case SPI_GETKEYBOARDPREF:
             return SpiGetInt(pvParam, &gspv.bKbdPref, fl);
@@ -1204,7 +1432,8 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
         }
 
         case SPI_SETLANGTOGGLE:
-            ERR("SPI_SETLANGTOGGLE is unimplemented\n");
+            gdwLanguageToggleKey = UserGetLanguageToggle();
+            return gdwLanguageToggleKey;
             break;
 
         case SPI_GETWINDOWSEXTENSION:
@@ -1294,7 +1523,7 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
 
 #if(WINVER >= 0x0600)
         case SPI_GETAUDIODESCRIPTION:
-            return SpiGet(pvParam, &gspv.audiodesription, sizeof(AUDIODESCRIPTION), fl);
+            return SpiGet(pvParam, &gspv.audiodescription, sizeof(AUDIODESCRIPTION), fl);
 
         case SPI_SETAUDIODESCRIPTION:
             ERR("SPI_SETAUDIODESCRIPTION is unimplemented\n");
@@ -1383,7 +1612,7 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
             return SpiGetUserPref(UPM_CURSORSHADOW, pvParam, fl);
 
         case SPI_SETCURSORSHADOW:
-            gspv.bMouseCursorShadow = (BOOL)pvParam;
+            gspv.bMouseCursorShadow = PtrToUlong(pvParam);
             return SpiSetUserPref(UPM_CURSORSHADOW, pvParam, fl);
 
         case SPI_GETUIEFFECTS:
@@ -1402,7 +1631,7 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
             return SpiGetUserPref(UPM_CLICKLOCK, pvParam, fl);
 
         case SPI_SETMOUSECLICKLOCK:
-            gspv.bMouseClickLock = (BOOL)pvParam;
+            gspv.bMouseClickLock = PtrToUlong(pvParam);
             return SpiSetUserPref(UPM_CLICKLOCK, pvParam, fl);
 
         case SPI_GETMOUSEVANISH:
@@ -1412,16 +1641,16 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
             return SpiSetBool(&gspv.bMouseVanish, uiParam, KEY_MOUSE, L"", fl);
 
         case SPI_GETFLATMENU:
-            return SpiGetInt(pvParam, &gspv.bFlatMenu, fl);
+            return SpiGetUserPref(UPM_FLATMENU, pvParam, fl);
 
         case SPI_SETFLATMENU:
-            return SpiSetBool(&gspv.bFlatMenu, uiParam, KEY_MOUSE, L"", fl);
+            return SpiSetUserPref(UPM_FLATMENU, pvParam, fl);
 
         case SPI_GETDROPSHADOW:
-            return SpiGetInt(pvParam, &gspv.bDropShadow, fl);
+            return SpiGetUserPref(UPM_DROPSHADOW, pvParam, fl);
 
         case SPI_SETDROPSHADOW:
-            return SpiSetBool(&gspv.bDropShadow, uiParam, KEY_MOUSE, L"", fl);
+            return SpiSetUserPref(UPM_DROPSHADOW, pvParam, fl);
 
         case SPI_GETBLOCKSENDINPUTRESETS:
             return SpiGetInt(pvParam, &gspv.bBlockSendInputResets, fl);
@@ -1437,10 +1666,10 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
             return SpiSetBool(&gspv.bDisableOverlappedContent, uiParam, KEY_MOUSE, L"", fl);
 
         case SPI_GETCLIENTAREAANIMATION:
-            return SpiGetInt(pvParam, &gspv.bClientAnimation, fl);
+            return SpiGetInt(pvParam, &gspv.bClientAreaAnimation, fl);
 
         case SPI_SETCLIENTAREAANIMATION:
-            return SpiSetBool(&gspv.bClientAnimation, uiParam, KEY_MOUSE, L"", fl);
+            return SpiSetBool(&gspv.bClientAreaAnimation, uiParam, KEY_MOUSE, L"", fl);
 
         case SPI_GETCLEARTYPE:
             return SpiGetInt(pvParam, &gspv.bClearType, fl);
@@ -1552,6 +1781,276 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl)
     return 0;
 }
 
+static BOOL
+SpiGetSetProbeBuffer(UINT uiAction, UINT uiParam, PVOID pvParam)
+{
+    BOOL bToUser = TRUE;
+    ULONG cbSize = 0;
+
+    switch (uiAction)
+    {
+        case SPI_GETBEEP:
+        case SPI_GETBORDER:
+        case SPI_GETKEYBOARDSPEED:
+        case SPI_GETSCREENSAVETIMEOUT:
+        case SPI_GETSCREENSAVEACTIVE:
+        case SPI_GETGRIDGRANULARITY:
+        case SPI_GETKEYBOARDDELAY:
+        case SPI_GETICONTITLEWRAP:
+        case SPI_GETMENUDROPALIGNMENT:
+        case SPI_GETFASTTASKSWITCH:
+        case SPI_GETDRAGFULLWINDOWS:
+        case SPI_GETSHOWSOUNDS:
+        case SPI_GETKEYBOARDPREF:
+        case SPI_GETSCREENREADER:
+        case SPI_GETFONTSMOOTHING:
+        case SPI_GETLOWPOWERTIMEOUT:
+        case SPI_GETPOWEROFFTIMEOUT:
+        case SPI_GETLOWPOWERACTIVE:
+        case SPI_GETPOWEROFFACTIVE:
+        case SPI_GETMOUSETRAILS:
+        case SPI_GETSNAPTODEFBUTTON:
+        case SPI_GETMOUSEHOVERWIDTH:
+        case SPI_GETMOUSEHOVERHEIGHT:
+        case SPI_GETMOUSEHOVERTIME:
+        case SPI_GETWHEELSCROLLLINES:
+        case SPI_GETMENUSHOWDELAY:
+#if (_WIN32_WINNT >= 0x0600)
+        case SPI_GETWHEELSCROLLCHARS:
+#endif
+        case SPI_GETSHOWIMEUI:
+        case SPI_GETMOUSESPEED:
+        case SPI_GETSCREENSAVERRUNNING:
+#if(WINVER >= 0x0600)
+        case SPI_GETSCREENSAVESECURE:
+#endif
+        case SPI_GETACTIVEWINDOWTRACKING:
+        case SPI_GETMENUANIMATION:
+        case SPI_GETCOMBOBOXANIMATION:
+        case SPI_GETLISTBOXSMOOTHSCROLLING:
+        case SPI_GETGRADIENTCAPTIONS:
+        case SPI_GETKEYBOARDCUES:
+        case SPI_GETACTIVEWNDTRKZORDER:
+        case SPI_GETHOTTRACKING:
+        case SPI_GETMENUFADE:
+        case SPI_GETSELECTIONFADE:
+        case SPI_GETTOOLTIPANIMATION:
+        case SPI_GETTOOLTIPFADE:
+        case SPI_GETCURSORSHADOW:
+        case SPI_GETUIEFFECTS:
+        case SPI_GETMOUSESONAR:
+        case SPI_GETMOUSECLICKLOCK:
+        case SPI_GETMOUSEVANISH:
+        case SPI_GETFLATMENU:
+        case SPI_GETDROPSHADOW:
+        case SPI_GETBLOCKSENDINPUTRESETS:
+#if(_WIN32_WINNT >= 0x0600)
+        case SPI_GETDISABLEOVERLAPPEDCONTENT:
+        case SPI_GETCLIENTAREAANIMATION:
+        case SPI_GETCLEARTYPE:
+        case SPI_GETSPEECHRECOGNITION:
+#endif
+        case SPI_GETFOREGROUNDLOCKTIMEOUT:
+        case SPI_GETACTIVEWNDTRKTIMEOUT:
+        case SPI_GETFOREGROUNDFLASHCOUNT:
+        case SPI_GETCARETWIDTH:
+        case SPI_GETMOUSECLICKLOCKTIME:
+        case SPI_GETFONTSMOOTHINGTYPE:
+        case SPI_GETFONTSMOOTHINGCONTRAST:
+        case SPI_GETFOCUSBORDERWIDTH:
+        case SPI_GETFOCUSBORDERHEIGHT:
+        case SPI_GETFONTSMOOTHINGORIENTATION:
+            cbSize = sizeof(INT);
+            break;
+
+        case SPI_ICONHORIZONTALSPACING:
+        case SPI_ICONVERTICALSPACING:
+            if (pvParam) cbSize = sizeof(INT);
+            break;
+
+        case SPI_GETMOUSE:
+            cbSize = 3 * sizeof(INT);
+            break;
+
+        case SPI_GETDESKWALLPAPER:
+            cbSize = min(uiParam, gspv.ustrWallpaper.Length + 1UL);
+            break;
+
+        case SPI_GETICONTITLELOGFONT:
+            cbSize = sizeof(LOGFONTW);
+            break;
+
+        case SPI_GETNONCLIENTMETRICS:
+            cbSize = sizeof(NONCLIENTMETRICSW);
+            break;
+
+        case SPI_GETMINIMIZEDMETRICS:
+            cbSize = sizeof(MINIMIZEDMETRICS);
+            break;
+
+        case SPI_GETICONMETRICS:
+            cbSize = sizeof(ICONMETRICSW);
+            break;
+
+        case SPI_GETWORKAREA:
+            cbSize = sizeof(RECTL);
+            break;
+
+        case SPI_GETFILTERKEYS:
+            cbSize = sizeof(FILTERKEYS);
+            break;
+
+        case SPI_GETTOGGLEKEYS:
+            cbSize = sizeof(TOGGLEKEYS);
+            break;
+
+        case SPI_GETMOUSEKEYS:
+            cbSize = sizeof(MOUSEKEYS);
+            break;
+
+        case SPI_GETSTICKYKEYS:
+            cbSize = sizeof(STICKYKEYS);
+            break;
+
+        case SPI_GETACCESSTIMEOUT:
+            cbSize = sizeof(ACCESSTIMEOUT);
+            break;
+
+        case SPI_GETSERIALKEYS:
+            cbSize = sizeof(SERIALKEYS);
+            break;
+
+        case SPI_GETSOUNDSENTRY:
+            cbSize = sizeof(SOUNDSENTRYW);
+            break;
+
+        case SPI_GETHIGHCONTRAST:
+            cbSize = sizeof(HIGHCONTRASTW);
+            break;
+
+        case SPI_GETANIMATION:
+            cbSize = sizeof(ANIMATIONINFO);
+            break;
+
+        case SPI_GETDEFAULTINPUTLANG:
+            cbSize = sizeof(HKL);
+            break;
+
+#if(WINVER >= 0x0600)
+        case SPI_GETAUDIODESCRIPTION:
+            cbSize = sizeof(AUDIODESCRIPTION);
+            break;
+#endif
+
+        case SPI_SETMOUSE:
+            cbSize = 3 * sizeof(INT);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETICONTITLELOGFONT:
+            cbSize = sizeof(LOGFONTW);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETNONCLIENTMETRICS:
+            cbSize = sizeof(NONCLIENTMETRICSW);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETMINIMIZEDMETRICS:
+            cbSize = sizeof(MINIMIZEDMETRICS);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETICONMETRICS:
+            cbSize = sizeof(ICONMETRICSW);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETWORKAREA:
+            cbSize = sizeof(RECTL);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETFILTERKEYS:
+            cbSize = sizeof(FILTERKEYS);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETTOGGLEKEYS:
+            cbSize = sizeof(TOGGLEKEYS);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETMOUSEKEYS:
+            cbSize = sizeof(MOUSEKEYS);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETSTICKYKEYS:
+            cbSize = sizeof(STICKYKEYS);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETACCESSTIMEOUT:
+            cbSize = sizeof(ACCESSTIMEOUT);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETSERIALKEYS:
+            cbSize = sizeof(SERIALKEYS);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETSOUNDSENTRY:
+            cbSize = sizeof(SOUNDSENTRYW);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETHIGHCONTRAST:
+            cbSize = sizeof(HIGHCONTRASTW);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETANIMATION:
+            cbSize = sizeof(ANIMATIONINFO);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETDEFAULTINPUTLANG:
+            cbSize = sizeof(HKL);
+            bToUser = FALSE;
+            break;
+
+        case SPI_SETMOUSESPEED:
+            cbSize = sizeof(INT);
+            bToUser = FALSE;
+            break;
+    }
+
+    if (cbSize)
+    {
+        _SEH2_TRY
+        {
+            if (bToUser)
+            {
+                ProbeForWrite(pvParam, cbSize, sizeof(UCHAR));
+            }
+            else
+            {
+                ProbeForRead(pvParam, cbSize, sizeof(UCHAR));
+            }
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            _SEH2_YIELD(return FALSE);
+        }
+        _SEH2_END;
+    }
+
+    return TRUE;
+}
+
 BOOL
 FASTCALL
 UserSystemParametersInfo(
@@ -1580,6 +2079,12 @@ UserSystemParametersInfo(
         //return FALSE;
     }
 
+    if ((fWinIni & SPIF_PROTECT) && !SpiGetSetProbeBuffer(uiAction, uiParam, pvParam))
+    {
+        EngSetLastError(ERROR_NOACCESS);
+        return FALSE;
+    }
+
     /* Do the actual operation */
     ulResult = SpiGetSet(uiAction, uiParam, pvParam, fWinIni);