https://git.reactos.org/?p=reactos.git;a=commitdiff;h=12dfa8ce390917db814d0ace0c40ffc376fa6c04

commit 12dfa8ce390917db814d0ace0c40ffc376fa6c04
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Mon Mar 22 12:39:08 2021 +0100
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Wed Mar 31 18:35:31 2021 +0200

    [WIN32K] Fix getting long value from float object
    
    Most importantly, do not shift 32-bit integers by 32 or more.
---
 win32ss/CMakeLists.txt          |  1 +
 win32ss/gdi/eng/floatobj.h      | 23 ++++++++++-------------
 win32ss/gdi/eng/i386/floatobj.S | 34 +---------------------------------
 win32ss/gdi/eng/i386/floatobj.c | 22 ++++++++++++++++++++++
 4 files changed, 34 insertions(+), 46 deletions(-)

diff --git a/win32ss/CMakeLists.txt b/win32ss/CMakeLists.txt
index 44dc77cd381..727461031cd 100644
--- a/win32ss/CMakeLists.txt
+++ b/win32ss/CMakeLists.txt
@@ -213,6 +213,7 @@ list(APPEND ASM_SOURCE
     gdi/dib/i386/dib32bpp_hline.s
     gdi/dib/i386/dib32bpp_colorfill.s
     gdi/eng/i386/floatobj.S)
+list(APPEND SOURCE gdi/eng/i386/floatobj.c)
 else()
 list(APPEND SOURCE
     gdi/dib/dib24bppc.c
diff --git a/win32ss/gdi/eng/floatobj.h b/win32ss/gdi/eng/floatobj.h
index aa85a4e80b5..5cad6830af6 100644
--- a/win32ss/gdi/eng/floatobj.h
+++ b/win32ss/gdi/eng/floatobj.h
@@ -16,15 +16,6 @@ _FLOATOBJ_Equal(FLOATOBJ *pf1, FLOATOBJ *pf2)
 }
 #define FLOATOBJ_Equal _FLOATOBJ_Equal
 
-FORCEINLINE
-LONG
-_FLOATOBJ_GetLong(FLOATOBJ *pf)
-{
-    EFLOAT_S *pef = (EFLOAT_S*)pf;
-    return pef->lMant >> (32 - pef->lExp);
-}
-#define FLOATOBJ_GetLong _FLOATOBJ_GetLong
-
 /*!
  * \brief Converts a FLOATOBJ into a LONG by truncating the value to integer
  *
@@ -37,16 +28,22 @@ _FLOATOBJ_GetLong(FLOATOBJ *pf)
  */
 FORCEINLINE
 BOOL
-FASTCALL
 FLOATOBJ_bConvertToLong(FLOATOBJ *pf, PLONG pl)
 {
     EFLOAT_S *pef = (EFLOAT_S*)pf;
-    LONG lShift = 32 - pef->lExp;
-    if (lShift < 0)
+
+    if (pef->lExp > 32)
     {
         return FALSE;
     }
-    *pl = pef->lMant >> lShift;
+    
+    if (pef->lExp < 2)
+    {
+        *pl = 0;
+        return TRUE;
+    }
+    
+    *pl = EngMulDiv(pef->lMant, 1 << (pef->lExp - 2), 0x40000000);
     return TRUE;
 }
 
diff --git a/win32ss/gdi/eng/i386/floatobj.S b/win32ss/gdi/eng/i386/floatobj.S
index 7eb9f64cb76..0b36e1b4559 100644
--- a/win32ss/gdi/eng/i386/floatobj.S
+++ b/win32ss/gdi/eng/i386/floatobj.S
@@ -52,7 +52,7 @@
  * FLOATOBJ_SetFloat - implemented, tested
  * FLOATOBJ_SetLong - implemented, tested
  * FLOATOBJ_GetFloat - implemented, tested
- * FLOATOBJ_GetLong - implemented, tested
+ * FLOATOBJ_GetLong - implemented in C
  * FLOATOBJ_Equal - implemented, tested
  * FLOATOBJ_EqualLong - implemented
  * FLOATOBJ_GreaterThan - implemented
@@ -249,34 +249,6 @@ SetLong0:
        ret 8
 
 
-/*******************************************************************************
- * LONG
- * APIENTRY
- * FLOATOBJ_GetLong(IN PFLOATOBJ pf);
- *
- */
-_FLOATOBJ_GetLong@4:
-PUBLIC _FLOATOBJ_GetLong@4
-       push ebp
-       mov ebp, esp
-
-       mov edx, [ebp + PARAM1]         /* Load pf into edx */
-       mov ecx, 32                                     /* Load (32 - lExp) 
into ecx */
-       sub ecx, [edx + lExp]
-       jle short GetLong2                      /* Check for Overflow */
-
-       mov eax, [edx + lMant]          /* Load mantissa into eax */
-       sar eax, cl                                     /* Signed shift 
mantissa according to exponent */
-
-       pop ebp                                         /* Return */
-       ret 4
-
-GetLong2:
-       xor eax, eax                            /* Overflow, return 0 */
-       pop ebp
-       ret 4
-
-
 /******************************************************************************
  * BOOL
  * APIENTRY
@@ -842,7 +814,6 @@ PUBLIC _FLOATOBJ_DivLong@8
        pop ebp
        ret 8
 
-
 
/*******************************************************************************
  * VOID
  * APIENTRY
@@ -940,7 +911,6 @@ AddIs0:
        pop ebp
        ret 8
 
-
 /******************************************************************************
  * VOID
  * APIENTRY
@@ -998,7 +968,6 @@ PUBLIC _FLOATOBJ_AddLong@8
        pop ebp
        ret 8
 
-
 
/*******************************************************************************
  * VOID
  * APIENTRY
@@ -1095,7 +1064,6 @@ SubIs0:
        mov dword ptr [eax + lExp], 0
        pop ebp
        ret 8
-
 /******************************************************************************
  * VOID
  * APIENTRY
diff --git a/win32ss/gdi/eng/i386/floatobj.c b/win32ss/gdi/eng/i386/floatobj.c
new file mode 100644
index 00000000000..d5b623d164f
--- /dev/null
+++ b/win32ss/gdi/eng/i386/floatobj.c
@@ -0,0 +1,22 @@
+/*
+ * PROJECT:         ReactOS win32 kernel mode subsystem
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            win32ss/gdi/eng/i386/floatobj.c
+ * PURPOSE:         FLOATOBJ API
+ * PROGRAMMERS:     Jérôme Gardou
+ */
+
+/** Includes 
******************************************************************/
+
+#include <win32k.h>
+#define NDEBUG
+#include <debug.h>
+
+LONG
+APIENTRY
+FLOATOBJ_GetLong(FLOATOBJ* pf)
+{
+    LONG val = 0;
+    (void)FLOATOBJ_bConvertToLong(pf, &val);
+    return val;
+}

Reply via email to