[WBEMPROX] Sync with Wine Staging 1.9.4. CORE-10912
[reactos.git] / reactos / dll / win32 / wbemprox / query.c
index e7984a4..3e37f42 100644 (file)
@@ -18,6 +18,8 @@
 
 #include "wbemprox_private.h"
 
+#include <winuser.h>
+
 HRESULT create_view( const struct property *proplist, const WCHAR *class,
                      const struct expr *cond, struct view **ret )
 {
@@ -51,10 +53,10 @@ static BOOL eval_like( const WCHAR *lstr, const WCHAR *rstr )
         {
             while (*q == '%') q++;
             if (!*q) return TRUE;
-            while (*p && toupperW( p[1] ) != toupperW( q[1] )) p++;
-            if (!*p) return TRUE;
+            while (*p && *q && toupperW( *p ) == toupperW( *q )) { p++; q++; };
+            if (!*p && !*q) return TRUE;
         }
-        if (toupperW( *p++ ) != toupperW( *q++ )) return FALSE;
+        if (*q != '%' && toupperW( *p++ ) != toupperW( *q++ )) return FALSE;
     }
     return TRUE;
 }
@@ -96,10 +98,31 @@ static HRESULT eval_strcmp( UINT op, const WCHAR *lstr, const WCHAR *rstr, LONGL
     return S_OK;
 }
 
-static inline BOOL is_strcmp( const struct complex_expr *expr )
+static BOOL is_int( CIMTYPE type )
 {
-    return ((expr->left->type == EXPR_PROPVAL && expr->right->type == EXPR_SVAL) ||
-            (expr->left->type == EXPR_SVAL && expr->right->type == EXPR_PROPVAL));
+    switch (type)
+    {
+    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 TRUE;
+    default:
+        return FALSE;
+    }
+}
+
+static inline BOOL is_strcmp( const struct complex_expr *expr, UINT ltype, UINT rtype )
+{
+    if ((ltype == CIM_STRING || is_int( ltype )) && expr->left->type == EXPR_PROPVAL &&
+        expr->right->type == EXPR_SVAL) return TRUE;
+    else if ((rtype == CIM_STRING || is_int( rtype )) && expr->right->type == EXPR_PROPVAL &&
+             expr->left->type == EXPR_SVAL) return TRUE;
+    return FALSE;
 }
 
 static inline BOOL is_boolcmp( const struct complex_expr *expr, UINT ltype, UINT rtype )
@@ -174,6 +197,41 @@ static UINT resolve_type( UINT left, UINT right )
     return CIM_ILLEGAL;
 }
 
+static const WCHAR *format_int( WCHAR *buf, CIMTYPE type, LONGLONG val )
+{
+    static const WCHAR fmt_signedW[] = {'%','d',0};
+    static const WCHAR fmt_unsignedW[] = {'%','u',0};
+    static const WCHAR fmt_signed64W[] = {'%','I','6','4','d',0};
+    static const WCHAR fmt_unsigned64W[] = {'%','I','6','4','u',0};
+
+    switch (type)
+    {
+    case CIM_SINT8:
+    case CIM_SINT16:
+    case CIM_SINT32:
+        sprintfW( buf, fmt_signedW, val );
+        return buf;
+
+    case CIM_UINT8:
+    case CIM_UINT16:
+    case CIM_UINT32:
+        sprintfW( buf, fmt_unsignedW, val );
+        return buf;
+
+    case CIM_SINT64:
+        wsprintfW( buf, fmt_signed64W, val );
+        return buf;
+
+    case CIM_UINT64:
+        wsprintfW( buf, fmt_unsigned64W, val );
+        return buf;
+
+    default:
+        ERR( "unhandled type %u\n", type );
+        return NULL;
+    }
+}
+
 static HRESULT eval_binary( const struct table *table, UINT row, const struct complex_expr *expr,
                             LONGLONG *val, UINT *type )
 {
@@ -190,10 +248,16 @@ static HRESULT eval_binary( const struct table *table, UINT row, const struct co
     if (is_boolcmp( expr, ltype, rtype ))
         return eval_boolcmp( expr->op, lval, rval, ltype, rtype, val );
 
-    if (is_strcmp( expr ))
+    if (is_strcmp( expr, ltype, rtype ))
     {
-        const WCHAR *lstr = (const WCHAR *)(INT_PTR)lval;
-        const WCHAR *rstr = (const WCHAR *)(INT_PTR)rval;
+        const WCHAR *lstr, *rstr;
+        WCHAR lbuf[21], rbuf[21];
+
+        if (is_int( ltype )) lstr = format_int( lbuf, ltype, lval );
+        else lstr = (const WCHAR *)(INT_PTR)lval;
+
+        if (is_int( rtype )) rstr = format_int( rbuf, rtype, rval );
+        else rstr = (const WCHAR *)(INT_PTR)rval;
 
         return eval_strcmp( expr->op, lstr, rstr, val );
     }
@@ -412,7 +476,7 @@ done:
     return hr;
 }
 
-static BOOL is_selected_prop( const struct view *view, const WCHAR *name )
+BOOL is_selected_prop( const struct view *view, const WCHAR *name )
 {
     const struct property *prop = view->proplist;
 
@@ -551,7 +615,7 @@ done:
     return ret;
 }
 
-static inline BOOL is_method( const struct table *table, UINT column )
+BOOL is_method( const struct table *table, UINT column )
 {
     return table->columns[column].type & COL_FLAG_METHOD;
 }
@@ -652,6 +716,8 @@ VARTYPE to_vartype( CIMTYPE type )
     case CIM_BOOLEAN:  return VT_BOOL;
     case CIM_STRING:
     case CIM_DATETIME: return VT_BSTR;
+    case CIM_SINT8:    return VT_I1;
+    case CIM_UINT8:    return VT_UI1;
     case CIM_SINT16:   return VT_I2;
     case CIM_UINT16:   return VT_UI2;
     case CIM_SINT32:   return VT_I4;
@@ -686,6 +752,7 @@ SAFEARRAY *to_safearray( const struct array *array, CIMTYPE type )
                 SafeArrayDestroy( ret );
                 return NULL;
             }
+            SysFreeString( str );
         }
         else if (SafeArrayPutElement( ret, &i, ptr ) != S_OK)
         {
@@ -712,6 +779,12 @@ void set_variant( VARTYPE type, LONGLONG val, void *val_ptr, VARIANT *ret )
     case VT_BSTR:
         V_BSTR( ret ) = val_ptr;
         break;
+    case VT_I1:
+        V_I1( ret ) = val;
+        break;
+    case VT_UI1:
+        V_UI1( ret ) = val;
+        break;
     case VT_I2:
         V_I2( ret ) = val;
         break;
@@ -758,7 +831,8 @@ HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VAR
         CIMTYPE basetype = view->table->columns[column].type & CIM_TYPE_MASK;
 
         val_ptr = to_safearray( (const struct array *)(INT_PTR)val, basetype );
-        if (!vartype) vartype = to_vartype( basetype ) | VT_ARRAY;
+        if (!val_ptr) vartype = VT_NULL;
+        else if (!vartype) vartype = to_vartype( basetype ) | VT_ARRAY;
         goto done;
     }
     switch (view->table->columns[column].type & COL_TYPE_MASK)
@@ -776,6 +850,12 @@ HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VAR
         else
             vartype = VT_NULL;
         break;
+    case CIM_SINT8:
+        if (!vartype) vartype = VT_I1;
+        break;
+    case CIM_UINT8:
+        if (!vartype) vartype = VT_UI1;
+        break;
     case CIM_SINT16:
         if (!vartype) vartype = VT_I2;
         break;
@@ -814,6 +894,8 @@ static CIMTYPE to_cimtype( VARTYPE type )
     {
     case VT_BOOL:  return CIM_BOOLEAN;
     case VT_BSTR:  return CIM_STRING;
+    case VT_I1:    return CIM_SINT8;
+    case VT_UI1:   return CIM_UINT8;
     case VT_I2:    return CIM_SINT16;
     case VT_UI2:   return CIM_UINT16;
     case VT_I4:    return CIM_SINT32;
@@ -951,28 +1033,31 @@ HRESULT get_properties( const struct view *view, LONG flags, SAFEARRAY **props )
 {
     SAFEARRAY *sa;
     BSTR str;
-    LONG i;
-    UINT num_props = count_properties( view );
+    UINT i, num_props = count_selected_properties( view );
+    LONG j;
 
     if (!(sa = SafeArrayCreateVector( VT_BSTR, 0, num_props ))) return E_OUTOFMEMORY;
 
-    for (i = 0; i < view->table->num_cols; i++)
+    for (i = 0, j = 0; i < view->table->num_cols; i++)
     {
         BOOL is_system;
 
         if (is_method( view->table, i )) continue;
+        if (!is_selected_prop( view, view->table->columns[i].name )) continue;
 
         is_system = is_system_prop( view->table->columns[i].name );
         if ((flags & WBEM_FLAG_NONSYSTEM_ONLY) && is_system) continue;
         else if ((flags & WBEM_FLAG_SYSTEM_ONLY) && !is_system) continue;
 
         str = SysAllocString( view->table->columns[i].name );
-        if (!str || SafeArrayPutElement( sa, &i, str ) != S_OK)
+        if (!str || SafeArrayPutElement( sa, &j, str ) != S_OK)
         {
             SysFreeString( str );
             SafeArrayDestroy( sa );
             return E_OUTOFMEMORY;
         }
+        SysFreeString( str );
+        j++;
     }
     *props = sa;
     return S_OK;