Hans Leidekker : wbemprox: Implement IWbemClassObject::GetMethod.

Alexandre Julliard julliard at winehq.org
Wed Jul 25 16:06:54 CDT 2012


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

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Wed Jul 25 13:13:17 2012 +0200

wbemprox: Implement IWbemClassObject::GetMethod.

---

 dlls/wbemprox/class.c            |  172 +++++++++++++++++++++++++++++++++++++-
 dlls/wbemprox/table.c            |   15 ++-
 dlls/wbemprox/wbemprox_private.h |   14 +++
 3 files changed, 194 insertions(+), 7 deletions(-)

diff --git a/dlls/wbemprox/class.c b/dlls/wbemprox/class.c
index af7d8f5..293c8c4 100644
--- a/dlls/wbemprox/class.c
+++ b/dlls/wbemprox/class.c
@@ -441,6 +441,163 @@ static HRESULT WINAPI class_object_InheritsFrom(
     return E_NOTIMPL;
 }
 
+static UINT count_instances( IEnumWbemClassObject *iter )
+{
+    UINT count = 0;
+    while (!IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 )) count++;
+    IEnumWbemClassObject_Reset( iter );
+    return count;
+}
+
+static void set_default_value( CIMTYPE type, UINT val, BYTE *ptr )
+{
+    switch (type)
+    {
+    case CIM_SINT16:
+        *(INT16 *)ptr = val;
+        break;
+    case CIM_UINT16:
+        *(UINT16 *)ptr = val;
+        break;
+    case CIM_SINT32:
+        *(INT32 *)ptr = val;
+        break;
+    case CIM_UINT32:
+        *(UINT32 *)ptr = val;
+        break;
+    default:
+        FIXME("unhandled type %u\n", type);
+        break;
+    }
+}
+
+HRESULT create_signature_columns_and_data( IEnumWbemClassObject *iter, UINT *num_cols,
+                                           struct column **cols, BYTE **data )
+{
+    static const WCHAR parameterW[] = {'P','a','r','a','m','e','t','e','r',0};
+    static const WCHAR typeW[] = {'T','y','p','e',0};
+    static const WCHAR defaultvalueW[] = {'D','e','f','a','u','l','t','V','a','l','u','e',0};
+    struct column *columns;
+    BYTE *row;
+    IWbemClassObject *param;
+    VARIANT val;
+    HRESULT hr = E_OUTOFMEMORY;
+    UINT offset = 0;
+    ULONG count;
+    int i = 0;
+
+    count = count_instances( iter );
+    if (!(columns = heap_alloc( count * sizeof(struct column) ))) return E_OUTOFMEMORY;
+    if (!(row = heap_alloc_zero( count * sizeof(LONGLONG) ))) goto error;
+
+    for (;;)
+    {
+        IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &param, &count );
+        if (!count) break;
+
+        hr = IWbemClassObject_Get( param, parameterW, 0, &val, NULL, NULL );
+        if (hr != S_OK) goto error;
+        columns[i].name = heap_strdupW( V_BSTR( &val ) );
+        VariantClear( &val );
+
+        hr = IWbemClassObject_Get( param, typeW, 0, &val, NULL, NULL );
+        if (hr != S_OK) goto error;
+        columns[i].type    = V_UI4( &val );
+        columns[i].vartype = 0;
+
+        hr = IWbemClassObject_Get( param, defaultvalueW, 0, &val, NULL, NULL );
+        if (hr != S_OK) goto error;
+        if (V_UI4( &val )) set_default_value( columns[i].type, V_UI4( &val ), row + offset );
+        offset += get_type_size( columns[i].type );
+
+        IWbemClassObject_Release( param );
+        i++;
+    }
+    *num_cols = i;
+    *cols = columns;
+    *data = row;
+    return S_OK;
+
+error:
+    for (; i >= 0; i--) heap_free( (WCHAR *)columns[i].name );
+    heap_free( columns );
+    heap_free( row );
+    return hr;
+}
+
+HRESULT create_signature_table( IEnumWbemClassObject *iter, WCHAR *name )
+{
+    HRESULT hr;
+    struct table *table;
+    struct column *columns;
+    UINT num_cols;
+    BYTE *row;
+
+    hr = create_signature_columns_and_data( iter, &num_cols, &columns, &row );
+    if (hr != S_OK) return hr;
+
+    if (!(table = create_table( name, num_cols, columns, 1, row, NULL )))
+    {
+        free_columns( columns, num_cols );
+        heap_free( row );
+        return E_OUTOFMEMORY;
+    }
+    if (!add_table( table )) free_table( table ); /* already exists */
+    return S_OK;
+}
+
+WCHAR *build_signature_table_name( const WCHAR *class, const WCHAR *method, enum param_direction dir )
+{
+    static const WCHAR fmtW[] = {'_','_','%','s','_','%','s','_','%','s',0};
+    static const WCHAR outW[] = {'O','U','T',0};
+    static const WCHAR inW[] = {'I','N',0};
+    UINT len = SIZEOF(fmtW) + SIZEOF(outW) + strlenW( class ) + strlenW( method );
+    WCHAR *ret;
+
+    if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
+    sprintfW( ret, fmtW, class, method, dir == PARAM_IN ? inW : outW );
+    return struprW( ret );
+}
+
+static HRESULT create_signature( const WCHAR *class, const WCHAR *method, enum param_direction dir,
+                                 IWbemClassObject **sig )
+{
+    static const WCHAR selectW[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         '_','_','P','A','R','A','M','E','T','E','R','S',' ','W','H','E','R','E',' ',
+         'C','l','a','s','s','=','\'','%','s','\'',' ','A','N','D',' ',
+         'M','e','t','h','o','d','=','\'','%','s','\'',' ','A','N','D',' ',
+         'D','i','r','e','c','t','i','o','n','%','s',0};
+    static const WCHAR geW[] = {'>','=','0',0};
+    static const WCHAR leW[] = {'<','=','0',0};
+    UINT len = SIZEOF(selectW) + SIZEOF(geW);
+    IEnumWbemClassObject *iter;
+    WCHAR *query, *name;
+    HRESULT hr;
+
+    len += strlenW( class ) + strlenW( method );
+    if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
+    sprintfW( query, selectW, class, method, dir >= 0 ? geW : leW );
+
+    hr = exec_query( query, &iter );
+    heap_free( query );
+    if (hr != S_OK) return hr;
+
+    if (!(name = build_signature_table_name( class, method, dir )))
+    {
+        IEnumWbemClassObject_Release( iter );
+        return E_OUTOFMEMORY;
+    }
+    hr = create_signature_table( iter, name );
+    IEnumWbemClassObject_Release( iter );
+    if (hr != S_OK)
+    {
+        heap_free( name );
+        return hr;
+    }
+    return get_object( name, sig );
+}
+
 static HRESULT WINAPI class_object_GetMethod(
     IWbemClassObject *iface,
     LPCWSTR wszName,
@@ -448,8 +605,19 @@ static HRESULT WINAPI class_object_GetMethod(
     IWbemClassObject **ppInSignature,
     IWbemClassObject **ppOutSignature )
 {
-    FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature);
-    return E_NOTIMPL;
+    struct class_object *co = impl_from_IWbemClassObject( iface );
+    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
+    struct view *view = ec->query->view;
+    HRESULT hr;
+
+    TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature);
+
+    hr = create_signature( view->table->name, wszName, PARAM_IN, ppInSignature );
+    if (hr != S_OK) return hr;
+
+    hr = create_signature( view->table->name, wszName, PARAM_OUT, ppOutSignature );
+    if (hr != S_OK) IWbemClassObject_Release( *ppInSignature );
+    return hr;
 }
 
 static HRESULT WINAPI class_object_PutMethod(
diff --git a/dlls/wbemprox/table.c b/dlls/wbemprox/table.c
index d3ad06d..d94a8e8 100644
--- a/dlls/wbemprox/table.c
+++ b/dlls/wbemprox/table.c
@@ -44,11 +44,11 @@ HRESULT get_column_index( const struct table *table, const WCHAR *name, UINT *co
     return WBEM_E_INVALID_QUERY;
 }
 
-static UINT get_column_size( const struct table *table, UINT column )
+UINT get_type_size( CIMTYPE type )
 {
-    if (table->columns[column].type & CIM_FLAG_ARRAY) return sizeof(void *);
+    if (type & CIM_FLAG_ARRAY) return sizeof(void *);
 
-    switch (table->columns[column].type & COL_TYPE_MASK)
+    switch (type)
     {
     case CIM_SINT16:
     case CIM_UINT16:
@@ -63,10 +63,15 @@ static UINT get_column_size( const struct table *table, UINT column )
     case CIM_STRING:
         return sizeof(WCHAR *);
     default:
-        ERR("unknown column type %u\n", table->columns[column].type & COL_TYPE_MASK);
+        ERR("unhandled type %u\n", type);
         break;
     }
-    return sizeof(INT32);
+    return sizeof(LONGLONG);
+}
+
+static UINT get_column_size( const struct table *table, UINT column )
+{
+    return get_type_size( table->columns[column].type & COL_TYPE_MASK );
 }
 
 static UINT get_column_offset( const struct table *table, UINT column )
diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h
index 725ea8c..a5f0a42 100644
--- a/dlls/wbemprox/wbemprox_private.h
+++ b/dlls/wbemprox/wbemprox_private.h
@@ -24,6 +24,13 @@ struct list *table_list;
 
 #define SIZEOF(array) (sizeof(array)/sizeof((array)[0]))
 
+enum param_direction
+{
+    PARAM_OUT   = -1,
+    PARAM_INOUT = 0,
+    PARAM_IN    = 1
+};
+
 #define COL_TYPE_MASK    0x0000ffff
 #define COL_FLAG_DYNAMIC 0x00010000
 #define COL_FLAG_KEY     0x00020000
@@ -134,6 +141,7 @@ struct table *create_table( const WCHAR *, UINT, const struct column *, UINT,
 BOOL add_table( struct table * ) DECLSPEC_HIDDEN;
 void free_columns( struct column *, UINT ) DECLSPEC_HIDDEN;
 void free_table( struct table * ) DECLSPEC_HIDDEN;
+UINT get_type_size( CIMTYPE ) 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;
@@ -161,6 +169,12 @@ static inline void *heap_realloc( void *mem, size_t len )
     return HeapReAlloc( GetProcessHeap(), 0, mem, len );
 }
 
+static void *heap_alloc_zero( size_t len ) __WINE_ALLOC_SIZE(1);
+static inline void *heap_alloc_zero( size_t len )
+{
+    return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
+}
+
 static inline BOOL heap_free( void *mem )
 {
     return HeapFree( GetProcessHeap(), 0, mem );




More information about the wine-cvs mailing list