From 0ba86d81fec715f9a8bc7dcf7585372afcf5cc4e Mon Sep 17 00:00:00 2001
From: Jason Edmeades <us@the-edmeades.demon.co.uk>
Date: Mon, 25 Nov 2002 02:42:33 +0000
Subject: [PATCH] Add support for VarAnd between integers.

---
 dlls/oleaut32/variant.c | 52 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 50 insertions(+), 2 deletions(-)

diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c
index 71d82aa0884..d1d766804f8 100644
--- a/dlls/oleaut32/variant.c
+++ b/dlls/oleaut32/variant.c
@@ -5076,7 +5076,6 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 {
     HRESULT rc = E_FAIL;
 
-
     TRACE("Left Var:\n");
     dump_Variant(left);
     TRACE("Right Var:\n");
@@ -5094,7 +5093,56 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
         rc = S_OK;
 
     } else {
-        FIXME("VarAnd stub\n");
+        /* Integers */
+        BOOL         lOk        = TRUE;
+        BOOL         rOk        = TRUE;
+        LONGLONG     lVal = -1;
+        LONGLONG     rVal = -1;
+        LONGLONG     res  = -1;
+        int          resT = 0; /* Testing has shown I2 & I2 == I2, all else 
+                                  becomes I4, even unsigned ints (incl. UI2) */
+
+        lOk = TRUE;
+        switch (V_VT(left)&VT_TYPEMASK) {
+        case VT_I1   : lVal = V_UNION(left,cVal);  resT=VT_I4; break;
+        case VT_I2   : lVal = V_UNION(left,iVal);  resT=VT_I2; break;
+        case VT_I4   : lVal = V_UNION(left,lVal);  resT=VT_I4; break;
+        case VT_INT  : lVal = V_UNION(left,lVal);  resT=VT_I4; break;
+        case VT_UI1  : lVal = V_UNION(left,bVal);  resT=VT_I4; break;
+        case VT_UI2  : lVal = V_UNION(left,uiVal); resT=VT_I4; break;
+        case VT_UI4  : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
+        case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
+        default: lOk = FALSE;
+        }
+
+        rOk = TRUE;
+        switch (V_VT(right)&VT_TYPEMASK) {
+        case VT_I1   : rVal = V_UNION(right,cVal);  resT=VT_I4; break;
+        case VT_I2   : rVal = V_UNION(right,iVal);  resT=max(VT_I2, resT); break;
+        case VT_I4   : rVal = V_UNION(right,lVal);  resT=VT_I4; break;
+        case VT_INT  : rVal = V_UNION(right,lVal);  resT=VT_I4; break;
+        case VT_UI1  : rVal = V_UNION(right,bVal);  resT=VT_I4; break;
+        case VT_UI2  : rVal = V_UNION(right,uiVal); resT=VT_I4; break;
+        case VT_UI4  : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
+        case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
+        default: rOk = FALSE;
+        }
+
+        if (lOk && rOk) {
+            res = (lVal & rVal);
+            V_VT(result) = resT;
+            switch (resT) {
+            case VT_I2   : V_UNION(result,iVal)  = res; break;
+            case VT_I4   : V_UNION(result,lVal)  = res; break;
+            default:
+                FIXME("Unexpected result variant type %x\n", resT);
+                V_UNION(result,lVal)  = res;
+            }
+            rc = S_OK;
+
+        } else {
+            FIXME("VarAnd stub\n");
+        }
     }
 
     TRACE("rc=%d, Result:\n", (int) rc);
-- 
GitLab