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, <ype );
+ 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