* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
-
-#define COBJMACROS
-
-#include "config.h"
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "objbase.h"
-#include "oleauto.h"
-#include "wbemcli.h"
-
-#include "wine/debug.h"
#include "wbemprox_private.h"
-WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
+#include <winuser.h>
HRESULT create_view( const struct property *proplist, const WCHAR *class,
const struct expr *cond, struct view **ret )
{
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;
}
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 )
+{
+ 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;
+ }
+ 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_cond( const struct table *, UINT, const struct expr *, LONGLONG * );
+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 )
+ 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;
- if (is_strcmp( expr ))
+ *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, 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 );
}
}
static HRESULT eval_unary( const struct table *table, UINT row, const struct complex_expr *expr,
- LONGLONG *val )
+ LONGLONG *val, UINT *type )
{
HRESULT hr;
UINT column;
LONGLONG lval;
+ if (expr->op == OP_NOT)
+ {
+ hr = eval_cond( table, row, expr->left, &lval, type );
+ if (hr != S_OK)
+ return hr;
+ *val = !lval;
+ return S_OK;
+ }
+
hr = get_column_index( table, expr->left->u.propval->name, &column );
if (hr != S_OK)
return hr;
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;
if (hr != S_OK)
return hr;
+ *type = table->columns[column].type & CIM_TYPE_MASK;
return get_value( table, row, column, val );
}
-static 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;
return WBEM_E_INVALID_QUERY;
}
-static HRESULT execute_view( struct view *view )
+HRESULT execute_view( struct view *view )
{
UINT i, j = 0, len;
- if (!view->table || !view->table->num_rows) return S_OK;
+ if (!view->table) return S_OK;
+ if (view->table->fill)
+ {
+ clear_table( view->table );
+ view->table->fill( view->table, view->cond );
+ }
+ if (!view->table->num_rows) return S_OK;
len = min( view->table->num_rows, 16 );
if (!(view->result = heap_alloc( len * sizeof(UINT) ))) return E_OUTOFMEMORY;
{
HRESULT hr;
LONGLONG val = 0;
+ UINT type;
if (j >= len)
{
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;
return S_OK;
}
-static struct query *create_query(void)
+struct query *create_query(void)
{
struct query *query;
return query;
}
-static void free_query( struct query *query )
+void free_query( struct query *query )
{
struct list *mem, *next;
+ if (!query) return;
destroy_view( query->view );
- LIST_FOR_EACH_SAFE( mem, next, &query->mem )
- {
- heap_free( mem );
- }
+ LIST_FOR_EACH_SAFE( mem, next, &query->mem ) { heap_free( mem ); }
heap_free( query );
}
if (hr != S_OK) goto done;
hr = execute_view( query->view );
if (hr != S_OK) goto done;
- hr = EnumWbemClassObject_create( NULL, query, (void **)result );
+ hr = EnumWbemClassObject_create( query, (void **)result );
done:
release_query( query );
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;
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;
}
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;
VARTYPE vartype = to_vartype( type );
LONG i;
- if (!(ret = SafeArrayCreateVector( vartype, 0, array->count ))) return NULL;
+ if (!array || !(ret = SafeArrayCreateVector( vartype, 0, array->count ))) return NULL;
for (i = 0; i < array->count; i++)
{
SafeArrayDestroy( ret );
return NULL;
}
+ SysFreeString( str );
}
else if (SafeArrayPutElement( ret, &i, ptr ) != S_OK)
{
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;
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)
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;
{
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;
return set_value( view->table, row, column, val, type );
}
-HRESULT get_properties( const struct view *view, SAFEARRAY **props )
+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;