IntChangeDisplaySettings: set last error before leaving the function
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / display.c
index e1985b9..158c30b 100644 (file)
@@ -21,7 +21,7 @@
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 NTSTATUS
-NTAPI
+APIENTRY
 NtUserEnumDisplaySettings(
    PUNICODE_STRING pusDeviceName,
    DWORD iModeNum,
@@ -35,18 +35,18 @@ NtUserEnumDisplaySettings(
     USHORT Size = 0, ExtraSize = 0;
 
     /* Copy the devmode */
-    _SEH_TRY
+    _SEH2_TRY
     {
         ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1);
         Size = lpDevMode->dmSize;
         ExtraSize = lpDevMode->dmDriverExtra;
     }
-    _SEH_HANDLE
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
         DPRINT("FIXME ? : Out of range of DEVMODEW size \n");
-        _SEH_YIELD(return _SEH_GetExceptionCode());
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
-    _SEH_END;
+    _SEH2_END;
 
     if (Size != sizeof(DEVMODEW))
     {
@@ -86,7 +86,7 @@ NtUserEnumDisplaySettings(
     }
 
     /* Copy some information back */
-    _SEH_TRY
+    _SEH2_TRY
     {
         ProbeForWrite(lpDevMode,Size + ExtraSize, 1);
         lpDevMode->dmPelsWidth = pSafeDevMode->dmPelsWidth;
@@ -101,11 +101,11 @@ NtUserEnumDisplaySettings(
             memcpy((PCHAR)lpDevMode + Size, (PCHAR)pSafeDevMode + Size, ExtraSize);
         }
     }
-    _SEH_HANDLE
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        Status = _SEH_GetExceptionCode();
+        Status = _SEH2_GetExceptionCode();
     }
-    _SEH_END;
+    _SEH2_END;
 
     ExFreePool(pSafeDevMode);
     return Status;
@@ -113,7 +113,7 @@ NtUserEnumDisplaySettings(
 
 
 LONG
-NTAPI
+APIENTRY
 NtUserChangeDisplaySettings(
    PUNICODE_STRING lpszDeviceName,
    LPDEVMODEW lpDevMode,
@@ -121,7 +121,8 @@ NtUserChangeDisplaySettings(
    DWORD dwflags,
    LPVOID lParam)
 {
-   NTSTATUS Status;
+   NTSTATUS Status = STATUS_SUCCESS;
+   LPDEVMODEW lpSafeDevMode = NULL;
    DEVMODEW DevMode;
    PUNICODE_STRING pSafeDeviceName = NULL;
    UNICODE_STRING SafeDeviceName;
@@ -147,23 +148,32 @@ NtUserChangeDisplaySettings(
    }
 
    /* Copy devmode */
-   Status = MmCopyFromCaller(&DevMode.dmSize, &lpDevMode->dmSize, sizeof (DevMode.dmSize));
-   if (!NT_SUCCESS(Status))
+   if (lpDevMode != NULL)
    {
-      SetLastNtError(Status);
-      return DISP_CHANGE_BADPARAM;
-   }
-   DevMode.dmSize = min(sizeof (DevMode), DevMode.dmSize);
-   Status = MmCopyFromCaller(&DevMode, lpDevMode, DevMode.dmSize);
-   if (!NT_SUCCESS(Status))
-   {
-      SetLastNtError(Status);
-      return DISP_CHANGE_BADPARAM;
-   }
-   if (DevMode.dmDriverExtra > 0)
-   {
-      DbgPrint("(%s:%i) WIN32K: %s lpDevMode->dmDriverExtra is IGNORED!\n", __FILE__, __LINE__, __FUNCTION__);
-      DevMode.dmDriverExtra = 0;
+      _SEH2_TRY
+      {
+          ProbeForRead(lpDevMode, sizeof(DevMode.dmSize), 1);
+          DevMode.dmSize = lpDevMode->dmSize;
+          DevMode.dmSize = min(sizeof(DevMode), DevMode.dmSize);
+          ProbeForRead(lpDevMode, DevMode.dmSize, 1);
+          RtlCopyMemory(&DevMode, lpDevMode, DevMode.dmSize);
+      }
+      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+      {
+          Status = _SEH2_GetExceptionCode();
+      }
+      _SEH2_END
+      if (!NT_SUCCESS(Status))
+      {
+         SetLastNtError(Status);
+         return DISP_CHANGE_BADPARAM;
+      }
+      if (DevMode.dmDriverExtra > 0)
+      {
+         DPRINT1("lpDevMode->dmDriverExtra is IGNORED!\n");
+         DevMode.dmDriverExtra = 0;
+      }
+      lpSafeDevMode = &DevMode;
    }
 
    /* Copy the device name */
@@ -179,7 +189,7 @@ NtUserChangeDisplaySettings(
    }
 
    /* Call internal function */
-   Ret = IntChangeDisplaySettings(pSafeDeviceName, &DevMode, dwflags, lParam);
+   Ret = IntChangeDisplaySettings(pSafeDeviceName, lpSafeDevMode, dwflags, lParam);
 
    if (pSafeDeviceName != NULL)
       RtlFreeUnicodeString(pSafeDeviceName);