Hans Leidekker : wbemprox: Allow string values in boolean comparisons.

Alexandre Julliard julliard at winehq.org
Tue Jan 28 13:33:26 CST 2014


Module: wine
Branch: master
Commit: 6a042307a56270e1bd5fe6ad6a53d6cc68942d57
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6a042307a56270e1bd5fe6ad6a53d6cc68942d57

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Tue Jan 28 13:26:16 2014 +0100

wbemprox: Allow string values in boolean comparisons.

---

 dlls/wbemprox/builtin.c          |    4 +-
 dlls/wbemprox/query.c            |  113 ++++++++++++++++++++++++++++++++++----
 dlls/wbemprox/wbemprox_private.h |    2 +-
 3 files changed, 107 insertions(+), 12 deletions(-)

diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 58054de..3086a4f 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -806,12 +806,14 @@ static const struct record_stdregprov data_stdregprov[] =
 static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status )
 {
     LONGLONG val;
+    UINT type;
+
     if (!cond)
     {
         *status = FILL_STATUS_UNFILTERED;
         return TRUE;
     }
-    if (eval_cond( table, row, cond, &val ) != S_OK)
+    if (eval_cond( table, row, cond, &val, &type ) != S_OK)
     {
         *status = FILL_STATUS_FAILED;
         return FALSE;
diff --git a/dlls/wbemprox/query.c b/dlls/wbemprox/query.c
index 5134d5b..bd68560 100644
--- a/dlls/wbemprox/query.c
+++ b/dlls/wbemprox/query.c
@@ -114,16 +114,93 @@ static inline BOOL is_strcmp( const struct complex_expr *expr )
             (expr->left->type == EXPR_SVAL && expr->right->type == EXPR_PROPVAL));
 }
 
+static inline BOOL is_boolcmp( const struct complex_expr *expr, UINT ltype, UINT rtype )
+{
+    if (ltype == CIM_BOOLEAN && expr->left->type == EXPR_PROPVAL &&
+        (expr->right->type == EXPR_SVAL || expr->right->type == EXPR_BVAL)) return TRUE;
+    else if (rtype == CIM_BOOLEAN && expr->right->type == EXPR_PROPVAL &&
+             (expr->left->type == EXPR_SVAL || expr->left->type == EXPR_BVAL)) return TRUE;
+    return FALSE;
+}
+
+static HRESULT eval_boolcmp( UINT op, LONGLONG lval, LONGLONG rval, UINT ltype, UINT rtype, LONGLONG *val )
+{
+    static const WCHAR trueW[] = {'T','r','u','e',0};
+
+    if (ltype == CIM_STRING) lval = !strcmpiW( (const WCHAR *)(INT_PTR)lval, trueW ) ? -1 : 0;
+    else if (rtype == CIM_STRING) rval = !strcmpiW( (const WCHAR *)(INT_PTR)rval, trueW ) ? -1 : 0;
+
+    switch (op)
+    {
+    case OP_EQ:
+        *val = (lval == rval);
+        break;
+    case OP_NE:
+        *val = (lval != rval);
+        break;
+    default:
+        ERR("unhandled operator %u\n", op);
+        return WBEM_E_INVALID_QUERY;
+    }
+    return S_OK;
+}
+
+static UINT resolve_type( UINT left, UINT right )
+{
+    switch (left)
+    {
+    case CIM_SINT8:
+    case CIM_SINT16:
+    case CIM_SINT32:
+    case CIM_SINT64:
+    case CIM_UINT8:
+    case CIM_UINT16:
+    case CIM_UINT32:
+    case CIM_UINT64:
+        switch (right)
+        {
+            case CIM_SINT8:
+            case CIM_SINT16:
+            case CIM_SINT32:
+            case CIM_SINT64:
+            case CIM_UINT8:
+            case CIM_UINT16:
+            case CIM_UINT32:
+            case CIM_UINT64:
+                return CIM_UINT64;
+            default: break;
+        }
+
+    case CIM_STRING:
+        if (right == CIM_STRING) return CIM_STRING;
+        break;
+
+    case CIM_BOOLEAN:
+        if (right == CIM_BOOLEAN) return CIM_BOOLEAN;
+        break;
+
+    default:
+        break;
+    }
+    return CIM_ILLEGAL;
+}
+
 static HRESULT eval_binary( const struct table *table, UINT row, const struct complex_expr *expr,
-                            LONGLONG *val )
+                            LONGLONG *val, UINT *type )
 {
     HRESULT lret, rret;
     LONGLONG lval, rval;
+    UINT ltype, rtype;
 
-    lret = eval_cond( table, row, expr->left, &lval );
-    rret = eval_cond( table, row, expr->right, &rval );
+    lret = eval_cond( table, row, expr->left, &lval, &ltype );
+    rret = eval_cond( table, row, expr->right, &rval, &rtype );
     if (lret != S_OK || rret != S_OK) return WBEM_E_INVALID_QUERY;
 
+    *type = resolve_type( ltype, rtype );
+
+    if (is_boolcmp( expr, ltype, rtype ))
+        return eval_boolcmp( expr->op, lval, rval, ltype, rtype, val );
+
     if (is_strcmp( expr ))
     {
         const WCHAR *lstr = (const WCHAR *)(INT_PTR)lval;
@@ -165,7 +242,7 @@ static HRESULT eval_binary( const struct table *table, UINT row, const struct co
 }
 
 static HRESULT eval_unary( const struct table *table, UINT row, const struct complex_expr *expr,
-                           LONGLONG *val )
+                           LONGLONG *val, UINT *type )
 
 {
     HRESULT hr;
@@ -192,11 +269,13 @@ static HRESULT eval_unary( const struct table *table, UINT row, const struct com
         ERR("unknown operator %u\n", expr->op);
         return WBEM_E_INVALID_QUERY;
     }
+
+    *type = table->columns[column].type & CIM_TYPE_MASK;
     return S_OK;
 }
 
 static HRESULT eval_propval( const struct table *table, UINT row, const struct property *propval,
-                             LONGLONG *val )
+                             LONGLONG *val, UINT *type )
 
 {
     HRESULT hr;
@@ -206,31 +285,44 @@ static HRESULT eval_propval( const struct table *table, UINT row, const struct p
     if (hr != S_OK)
         return hr;
 
+    *type = table->columns[column].type & CIM_TYPE_MASK;
     return get_value( table, row, column, val );
 }
 
-HRESULT eval_cond( const struct table *table, UINT row, const struct expr *cond, LONGLONG *val )
+HRESULT eval_cond( const struct table *table, UINT row, const struct expr *cond, LONGLONG *val, UINT *type )
 {
     if (!cond)
     {
         *val = 1;
+        *type = CIM_UINT64;
         return S_OK;
     }
     switch (cond->type)
     {
     case EXPR_COMPLEX:
-        return eval_binary( table, row, &cond->u.expr, val );
+        return eval_binary( table, row, &cond->u.expr, val, type );
+
     case EXPR_UNARY:
-        return eval_unary( table, row, &cond->u.expr, val );
+        return eval_unary( table, row, &cond->u.expr, val, type );
+
     case EXPR_PROPVAL:
-        return eval_propval( table, row, cond->u.propval, val );
+        return eval_propval( table, row, cond->u.propval, val, type );
+
     case EXPR_SVAL:
         *val = (INT_PTR)cond->u.sval;
+        *type = CIM_STRING;
         return S_OK;
+
     case EXPR_IVAL:
+        *val = cond->u.ival;
+        *type = CIM_UINT64;
+        return S_OK;
+
     case EXPR_BVAL:
         *val = cond->u.ival;
+        *type = CIM_BOOLEAN;
         return S_OK;
+
     default:
         ERR("invalid expression type\n");
         break;
@@ -257,6 +349,7 @@ HRESULT execute_view( struct view *view )
     {
         HRESULT hr;
         LONGLONG val = 0;
+        UINT type;
 
         if (j >= len)
         {
@@ -265,7 +358,7 @@ HRESULT execute_view( struct view *view )
             if (!(tmp = heap_realloc( view->result, len * sizeof(UINT) ))) return E_OUTOFMEMORY;
             view->result = tmp;
         }
-        if ((hr = eval_cond( view->table, i, view->cond, &val )) != S_OK) return hr;
+        if ((hr = eval_cond( view->table, i, view->cond, &val, &type )) != S_OK) return hr;
         if (val) view->result[j++] = i;
     }
     view->count = j;
diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h
index 81c0fcc..0e39d00 100644
--- a/dlls/wbemprox/wbemprox_private.h
+++ b/dlls/wbemprox/wbemprox_private.h
@@ -186,7 +186,7 @@ void free_row_values( const struct table *, UINT ) DECLSPEC_HIDDEN;
 void clear_table( struct table * ) DECLSPEC_HIDDEN;
 void free_table( struct table * ) DECLSPEC_HIDDEN;
 UINT get_type_size( CIMTYPE ) DECLSPEC_HIDDEN;
-HRESULT eval_cond( const struct table *, UINT, const struct expr *, LONGLONG * ) DECLSPEC_HIDDEN;
+HRESULT eval_cond( const struct table *, UINT, const struct expr *, LONGLONG *, UINT * ) DECLSPEC_HIDDEN;
 HRESULT get_column_index( const struct table *, const WCHAR *, UINT * ) DECLSPEC_HIDDEN;
 HRESULT get_value( const struct table *, UINT, UINT, LONGLONG * ) DECLSPEC_HIDDEN;
 BSTR get_value_bstr( const struct table *, UINT, UINT ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list