/*
 * Copyright 2012 Hans Leidekker for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS

#include "config.h"
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wbemcli.h"

#include "wine/debug.h"
#include "wbemprox_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);

struct enum_class_object
{
    IEnumWbemClassObject IEnumWbemClassObject_iface;
    LONG refs;
    struct query *query;
    UINT index;
};

static inline struct enum_class_object *impl_from_IEnumWbemClassObject(
    IEnumWbemClassObject *iface )
{
    return CONTAINING_RECORD(iface, struct enum_class_object, IEnumWbemClassObject_iface);
}

static ULONG WINAPI enum_class_object_AddRef(
    IEnumWbemClassObject *iface )
{
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
    return InterlockedIncrement( &ec->refs );
}

static ULONG WINAPI enum_class_object_Release(
    IEnumWbemClassObject *iface )
{
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
    LONG refs = InterlockedDecrement( &ec->refs );
    if (!refs)
    {
        TRACE("destroying %p\n", ec);
        release_query( ec->query );
        heap_free( ec );
    }
    return refs;
}

static HRESULT WINAPI enum_class_object_QueryInterface(
    IEnumWbemClassObject *iface,
    REFIID riid,
    void **ppvObject )
{
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );

    TRACE("%p, %s, %p\n", ec, debugstr_guid( riid ), ppvObject );

    if ( IsEqualGUID( riid, &IID_IEnumWbemClassObject ) ||
         IsEqualGUID( riid, &IID_IUnknown ) )
    {
        *ppvObject = ec;
    }
    else if ( IsEqualGUID( riid, &IID_IClientSecurity ) )
    {
        *ppvObject = &client_security;
        return S_OK;
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }
    IEnumWbemClassObject_AddRef( iface );
    return S_OK;
}

static HRESULT WINAPI enum_class_object_Reset(
    IEnumWbemClassObject *iface )
{
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );

    TRACE("%p\n", iface);

    ec->index = 0;
    return WBEM_S_NO_ERROR;
}

static HRESULT WINAPI enum_class_object_Next(
    IEnumWbemClassObject *iface,
    LONG lTimeout,
    ULONG uCount,
    IWbemClassObject **apObjects,
    ULONG *puReturned )
{
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
    struct view *view = ec->query->view;
    HRESULT hr;

    TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned);

    if (!uCount) return WBEM_S_FALSE;
    if (!apObjects || !puReturned) return WBEM_E_INVALID_PARAMETER;
    if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n");

    *puReturned = 0;
    if (ec->index >= view->count) return WBEM_S_FALSE;

    hr = create_class_object( view->table->name, iface, ec->index, NULL, apObjects );
    if (hr != S_OK) return hr;

    ec->index++;
    *puReturned = 1;
    if (ec->index == view->count && uCount > 1) return WBEM_S_FALSE;
    if (uCount > 1) return WBEM_S_TIMEDOUT;
    return WBEM_S_NO_ERROR;
}

static HRESULT WINAPI enum_class_object_NextAsync(
    IEnumWbemClassObject *iface,
    ULONG uCount,
    IWbemObjectSink *pSink )
{
    FIXME("%p, %u, %p\n", iface, uCount, pSink);
    return E_NOTIMPL;
}

static HRESULT WINAPI enum_class_object_Clone(
    IEnumWbemClassObject *iface,
    IEnumWbemClassObject **ppEnum )
{
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );

    TRACE("%p, %p\n", iface, ppEnum);

    return EnumWbemClassObject_create( NULL, ec->query, (void **)ppEnum );
}

static HRESULT WINAPI enum_class_object_Skip(
    IEnumWbemClassObject *iface,
    LONG lTimeout,
    ULONG nCount )
{
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
    struct view *view = ec->query->view;

    TRACE("%p, %d, %u\n", iface, lTimeout, nCount);

    if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n");

    if (!view->count) return WBEM_S_FALSE;

    if (nCount > view->count - ec->index)
    {
        ec->index = view->count - 1;
        return WBEM_S_FALSE;
    }
    ec->index += nCount;
    return WBEM_S_NO_ERROR;
}

static const IEnumWbemClassObjectVtbl enum_class_object_vtbl =
{
    enum_class_object_QueryInterface,
    enum_class_object_AddRef,
    enum_class_object_Release,
    enum_class_object_Reset,
    enum_class_object_Next,
    enum_class_object_NextAsync,
    enum_class_object_Clone,
    enum_class_object_Skip
};

HRESULT EnumWbemClassObject_create(
    IUnknown *pUnkOuter, struct query *query, LPVOID *ppObj )
{
    struct enum_class_object *ec;

    TRACE("%p, %p\n", pUnkOuter, ppObj);

    ec = heap_alloc( sizeof(*ec) );
    if (!ec) return E_OUTOFMEMORY;

    ec->IEnumWbemClassObject_iface.lpVtbl = &enum_class_object_vtbl;
    ec->refs  = 1;
    ec->query = addref_query( query );
    ec->index = 0;

    *ppObj = &ec->IEnumWbemClassObject_iface;

    TRACE("returning iface %p\n", *ppObj);
    return S_OK;
}

static struct record *create_record( struct table *table )
{
    UINT i;
    struct record *record;

    if (!(record = heap_alloc( sizeof(struct record) ))) return NULL;
    if (!(record->fields = heap_alloc( table->num_cols * sizeof(struct field) )))
    {
        heap_free( record );
        return NULL;
    }
    for (i = 0; i < table->num_cols; i++)
    {
        record->fields[i].type    = table->columns[i].type;
        record->fields[i].vartype = table->columns[i].vartype;
        record->fields[i].u.ival  = 0;
    }
    record->count = table->num_cols;
    record->table = addref_table( table );
    return record;
}

void destroy_array( struct array *array, CIMTYPE type )
{
    UINT i, size;

    if (!array) return;
    if (type == CIM_STRING || type == CIM_DATETIME)
    {
        size = get_type_size( type );
        for (i = 0; i < array->count; i++) heap_free( *(WCHAR **)((char *)array->ptr + i * size) );
    }
    heap_free( array->ptr );
    heap_free( array );
}

static void destroy_record( struct record *record )
{
    UINT i;

    if (!record) return;
    release_table( record->table );
    for (i = 0; i < record->count; i++)
    {
        if (record->fields[i].type == CIM_STRING || record->fields[i].type == CIM_DATETIME)
            heap_free( record->fields[i].u.sval );
        else if (record->fields[i].type & CIM_FLAG_ARRAY)
            destroy_array( record->fields[i].u.aval, record->fields[i].type & CIM_TYPE_MASK );
    }
    heap_free( record->fields );
    heap_free( record );
}

struct class_object
{
    IWbemClassObject IWbemClassObject_iface;
    LONG refs;
    WCHAR *name;
    IEnumWbemClassObject *iter;
    UINT index;
    UINT index_method;
    UINT index_property;
    struct record *record; /* uncommitted instance */
};

static inline struct class_object *impl_from_IWbemClassObject(
    IWbemClassObject *iface )
{
    return CONTAINING_RECORD(iface, struct class_object, IWbemClassObject_iface);
}

static ULONG WINAPI class_object_AddRef(
    IWbemClassObject *iface )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );
    return InterlockedIncrement( &co->refs );
}

static ULONG WINAPI class_object_Release(
    IWbemClassObject *iface )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );
    LONG refs = InterlockedDecrement( &co->refs );
    if (!refs)
    {
        TRACE("destroying %p\n", co);
        if (co->iter) IEnumWbemClassObject_Release( co->iter );
        destroy_record( co->record );
        heap_free( co->name );
        heap_free( co );
    }
    return refs;
}

static HRESULT WINAPI class_object_QueryInterface(
    IWbemClassObject *iface,
    REFIID riid,
    void **ppvObject )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );

    TRACE("%p, %s, %p\n", co, debugstr_guid( riid ), ppvObject );

    if ( IsEqualGUID( riid, &IID_IWbemClassObject ) ||
         IsEqualGUID( riid, &IID_IUnknown ) )
    {
        *ppvObject = co;
    }
    else if (IsEqualGUID( riid, &IID_IClientSecurity ))
    {
        *ppvObject = &client_security;
        return S_OK;
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }
    IWbemClassObject_AddRef( iface );
    return S_OK;
}

static HRESULT WINAPI class_object_GetQualifierSet(
    IWbemClassObject *iface,
    IWbemQualifierSet **ppQualSet )
{
    FIXME("%p, %p\n", iface, ppQualSet);
    return E_NOTIMPL;
}

static HRESULT record_get_value( const struct record *record, UINT index, VARIANT *var, CIMTYPE *type )
{
    VARTYPE vartype = record->fields[index].vartype;

    if (type) *type = record->fields[index].type;

    if (record->fields[index].type & CIM_FLAG_ARRAY)
    {
        V_VT( var ) = vartype ? vartype : to_vartype( record->fields[index].type & CIM_TYPE_MASK ) | VT_ARRAY;
        V_ARRAY( var ) = to_safearray( record->fields[index].u.aval, record->fields[index].type & CIM_TYPE_MASK );
        return S_OK;
    }
    switch (record->fields[index].type)
    {
    case CIM_STRING:
    case CIM_DATETIME:
        if (!vartype) vartype = VT_BSTR;
        V_BSTR( var ) = SysAllocString( record->fields[index].u.sval );
        break;
    case CIM_SINT32:
        if (!vartype) vartype = VT_I4;
        V_I4( var ) = record->fields[index].u.ival;
        break;
    case CIM_UINT32:
        if (!vartype) vartype = VT_UI4;
        V_UI4( var ) = record->fields[index].u.ival;
        break;
    default:
        FIXME("unhandled type %u\n", record->fields[index].type);
        return WBEM_E_INVALID_PARAMETER;
    }
    V_VT( var ) = vartype;
    return S_OK;
}

static HRESULT WINAPI class_object_Get(
    IWbemClassObject *iface,
    LPCWSTR wszName,
    LONG lFlags,
    VARIANT *pVal,
    CIMTYPE *pType,
    LONG *plFlavor )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );

    TRACE("%p, %s, %08x, %p, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, pType, plFlavor);

    if (co->record)
    {
        UINT index;
        HRESULT hr;

        if ((hr = get_column_index( co->record->table, wszName, &index )) != S_OK) return hr;
        return record_get_value( co->record, index, pVal, pType );
    }
    return get_propval( ec->query->view, co->index, wszName, pVal, pType, plFlavor );
}

static HRESULT record_set_value( struct record *record, UINT index, VARIANT *var )
{
    LONGLONG val;
    CIMTYPE type;
    HRESULT hr;

    if ((hr = to_longlong( var, &val, &type )) != S_OK) return hr;
    if (type != record->fields[index].type) return WBEM_E_TYPE_MISMATCH;

    if (type & CIM_FLAG_ARRAY)
    {
        record->fields[index].u.aval = (struct array *)(INT_PTR)val;
        return S_OK;
    }
    switch (type)
    {
    case CIM_STRING:
    case CIM_DATETIME:
        record->fields[index].u.sval = (WCHAR *)(INT_PTR)val;
        return S_OK;
    case CIM_SINT16:
    case CIM_UINT16:
    case CIM_SINT32:
    case CIM_UINT32:
        record->fields[index].u.ival = val;
        return S_OK;
    default:
        FIXME("unhandled type %u\n", type);
        break;
    }
    return WBEM_E_INVALID_PARAMETER;
}

static HRESULT WINAPI class_object_Put(
    IWbemClassObject *iface,
    LPCWSTR wszName,
    LONG lFlags,
    VARIANT *pVal,
    CIMTYPE Type )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );

    TRACE("%p, %s, %08x, %p, %u\n", iface, debugstr_w(wszName), lFlags, pVal, Type);

    if (co->record)
    {
        UINT index;
        HRESULT hr;

        if ((hr = get_column_index( co->record->table, wszName, &index )) != S_OK) return hr;
        return record_set_value( co->record, index, pVal );
    }
    return put_propval( ec->query->view, co->index, wszName, pVal, Type );
}

static HRESULT WINAPI class_object_Delete(
    IWbemClassObject *iface,
    LPCWSTR wszName )
{
    FIXME("%p, %s\n", iface, debugstr_w(wszName));
    return E_NOTIMPL;
}

static HRESULT WINAPI class_object_GetNames(
    IWbemClassObject *iface,
    LPCWSTR wszQualifierName,
    LONG lFlags,
    VARIANT *pQualifierVal,
    SAFEARRAY **pNames )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );

    TRACE("%p, %s, %08x, %s, %p\n", iface, debugstr_w(wszQualifierName), lFlags,
          debugstr_variant(pQualifierVal), pNames);

    if (wszQualifierName || pQualifierVal)
    {
        FIXME("qualifier not supported\n");
        return E_NOTIMPL;
    }
    if (lFlags != WBEM_FLAG_ALWAYS)
    {
        FIXME("flags %08x not supported\n", lFlags);
        return E_NOTIMPL;
    }
    return get_properties( ec->query->view, pNames );
}

static HRESULT WINAPI class_object_BeginEnumeration(
    IWbemClassObject *iface,
    LONG lEnumFlags )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );

    TRACE("%p, %08x\n", iface, lEnumFlags);

    if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);

    co->index_property = 0;
    return S_OK;
}

static HRESULT WINAPI class_object_Next(
    IWbemClassObject *iface,
    LONG lFlags,
    BSTR *strName,
    VARIANT *pVal,
    CIMTYPE *pType,
    LONG *plFlavor )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
    struct view *view = ec->query->view;
    BSTR property;
    HRESULT hr;

    TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor);

    if (!(property = get_property_name( co->name, co->index_property ))) return WBEM_S_NO_MORE_DATA;
    if ((hr = get_propval( view, co->index, property, pVal, pType, plFlavor ) != S_OK))
    {
        SysFreeString( property );
        return hr;
    }
    *strName = property;
    co->index_property++;
    return S_OK;
}

static HRESULT WINAPI class_object_EndEnumeration(
    IWbemClassObject *iface )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );

    TRACE("%p\n", iface);

    co->index_property = 0;
    return S_OK;
}

static HRESULT WINAPI class_object_GetPropertyQualifierSet(
    IWbemClassObject *iface,
    LPCWSTR wszProperty,
    IWbemQualifierSet **ppQualSet )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );

    TRACE("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet);

    return WbemQualifierSet_create( NULL, co->name, wszProperty, (void **)ppQualSet );
}

static HRESULT WINAPI class_object_Clone(
    IWbemClassObject *iface,
    IWbemClassObject **ppCopy )
{
    FIXME("%p, %p\n", iface, ppCopy);
    return E_NOTIMPL;
}

static BSTR get_body_text( const struct table *table, UINT row, UINT *len )
{
    static const WCHAR fmtW[] = {'\n','\t','%','s',' ','=',' ','%','s',';',0};
    BSTR value, ret;
    WCHAR *p;
    UINT i;

    *len = 0;
    for (i = 0; i < table->num_cols; i++)
    {
        if ((value = get_value_bstr( table, row, i )))
        {
            *len += sizeof(fmtW) / sizeof(fmtW[0]);
            *len += strlenW( table->columns[i].name );
            *len += SysStringLen( value );
            SysFreeString( value );
        }
    }
    if (!(ret = SysAllocStringLen( NULL, *len ))) return NULL;
    p = ret;
    for (i = 0; i < table->num_cols; i++)
    {
        if ((value = get_value_bstr( table, row, i )))
        {
            p += sprintfW( p, fmtW, table->columns[i].name, value );
            SysFreeString( value );
        }
    }
    return ret;
}

static BSTR get_object_text( const struct view *view, UINT index )
{
    static const WCHAR fmtW[] =
        {'\n','i','n','s','t','a','n','c','e',' ','o','f',' ','%','s','\n','{','%','s','\n','}',';',0};
    UINT len, len_body, row = view->result[index];
    BSTR ret, body;

    len = sizeof(fmtW) / sizeof(fmtW[0]);
    len += strlenW( view->table->name );
    if (!(body = get_body_text( view->table, row, &len_body ))) return NULL;
    len += len_body;

    if (!(ret = SysAllocStringLen( NULL, len ))) return NULL;
    sprintfW( ret, fmtW, view->table->name, body );
    SysFreeString( body );
    return ret;
}

static HRESULT WINAPI class_object_GetObjectText(
    IWbemClassObject *iface,
    LONG lFlags,
    BSTR *pstrObjectText )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
    struct view *view = ec->query->view;
    BSTR text;

    TRACE("%p, %08x, %p\n", iface, lFlags, pstrObjectText);

    if (lFlags) FIXME("flags %08x not implemented\n", lFlags);

    if (!(text = get_object_text( view, co->index ))) return E_OUTOFMEMORY;
    *pstrObjectText = text;
    return S_OK;
}

static HRESULT WINAPI class_object_SpawnDerivedClass(
    IWbemClassObject *iface,
    LONG lFlags,
    IWbemClassObject **ppNewClass )
{
    FIXME("%p, %08x, %p\n", iface, lFlags, ppNewClass);
    return E_NOTIMPL;
}

static HRESULT WINAPI class_object_SpawnInstance(
    IWbemClassObject *iface,
    LONG lFlags,
    IWbemClassObject **ppNewInstance )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );
    struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
    struct view *view = ec->query->view;
    struct record *record;

    TRACE("%p, %08x, %p\n", iface, lFlags, ppNewInstance);

    if (!(record = create_record( view->table ))) return E_OUTOFMEMORY;

    return create_class_object( co->name, NULL, 0, record, ppNewInstance );
}

static HRESULT WINAPI class_object_CompareTo(
    IWbemClassObject *iface,
    LONG lFlags,
    IWbemClassObject *pCompareTo )
{
    FIXME("%p, %08x, %p\n", iface, lFlags, pCompareTo);
    return E_NOTIMPL;
}

static HRESULT WINAPI class_object_GetPropertyOrigin(
    IWbemClassObject *iface,
    LPCWSTR wszName,
    BSTR *pstrClassName )
{
    FIXME("%p, %s, %p\n", iface, debugstr_w(wszName), pstrClassName);
    return E_NOTIMPL;
}

static HRESULT WINAPI class_object_InheritsFrom(
    IWbemClassObject *iface,
    LPCWSTR strAncestor )
{
    FIXME("%p, %s\n", iface, debugstr_w(strAncestor));
    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;
    }
}

static 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 varianttypeW[] = {'V','a','r','i','a','n','t','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 );

        hr = IWbemClassObject_Get( param, varianttypeW, 0, &val, NULL, NULL );
        if (hr != S_OK) goto error;
        columns[i].vartype = V_UI4( &val );

        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;
}

static 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, 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;
}

static 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 );
}

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)
        hr = get_object( name, sig );

    heap_free( name );
    return hr;
}

static HRESULT WINAPI class_object_GetMethod(
    IWbemClassObject *iface,
    LPCWSTR wszName,
    LONG lFlags,
    IWbemClassObject **ppInSignature,
    IWbemClassObject **ppOutSignature )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );
    IWbemClassObject *in, *out;
    HRESULT hr;

    TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature);

    hr = create_signature( co->name, wszName, PARAM_IN, &in );
    if (hr != S_OK) return hr;

    hr = create_signature( co->name, wszName, PARAM_OUT, &out );
    if (hr == S_OK)
    {
        if (ppInSignature) *ppInSignature = in;
        else IWbemClassObject_Release( in );
        if (ppOutSignature) *ppOutSignature = out;
        else IWbemClassObject_Release( out );
    }
    else IWbemClassObject_Release( in );
    return hr;
}

static HRESULT WINAPI class_object_PutMethod(
    IWbemClassObject *iface,
    LPCWSTR wszName,
    LONG lFlags,
    IWbemClassObject *pInSignature,
    IWbemClassObject *pOutSignature )
{
    FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pInSignature, pOutSignature);
    return E_NOTIMPL;
}

static HRESULT WINAPI class_object_DeleteMethod(
    IWbemClassObject *iface,
    LPCWSTR wszName )
{
    FIXME("%p, %s\n", iface, debugstr_w(wszName));
    return E_NOTIMPL;
}

static HRESULT WINAPI class_object_BeginMethodEnumeration(
    IWbemClassObject *iface,
    LONG lEnumFlags)
{
    struct class_object *co = impl_from_IWbemClassObject( iface );

    TRACE("%p, %08x\n", iface, lEnumFlags);

    if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);

    if (co->iter)
    {
        WARN("not allowed on instance\n");
        return WBEM_E_ILLEGAL_OPERATION;
    }
    co->index_method = 0;
    return S_OK;
}

static HRESULT WINAPI class_object_NextMethod(
    IWbemClassObject *iface,
    LONG lFlags,
    BSTR *pstrName,
    IWbemClassObject **ppInSignature,
    IWbemClassObject **ppOutSignature)
{
    struct class_object *co = impl_from_IWbemClassObject( iface );
    BSTR method;
    HRESULT hr;

    TRACE("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature);

    if (!(method = get_method_name( co->name, co->index_method ))) return WBEM_S_NO_MORE_DATA;

    hr = create_signature( co->name, method, PARAM_IN, ppInSignature );
    if (hr != S_OK)
    {
        SysFreeString( method );
        return hr;
    }
    hr = create_signature( co->name, method, PARAM_OUT, ppOutSignature );
    if (hr != S_OK)
    {
        SysFreeString( method );
        IWbemClassObject_Release( *ppInSignature );
    }
    else
    {
        *pstrName = method;
        co->index_method++;
    }
    return hr;
}

static HRESULT WINAPI class_object_EndMethodEnumeration(
    IWbemClassObject *iface )
{
    struct class_object *co = impl_from_IWbemClassObject( iface );

    TRACE("%p\n", iface);

    co->index_method = 0;
    return S_OK;
}

static HRESULT WINAPI class_object_GetMethodQualifierSet(
    IWbemClassObject *iface,
    LPCWSTR wszMethod,
    IWbemQualifierSet **ppQualSet)
{
    FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethod), ppQualSet);
    return E_NOTIMPL;
}

static HRESULT WINAPI class_object_GetMethodOrigin(
    IWbemClassObject *iface,
    LPCWSTR wszMethodName,
    BSTR *pstrClassName)
{
    FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethodName), pstrClassName);
    return E_NOTIMPL;
}

static const IWbemClassObjectVtbl class_object_vtbl =
{
    class_object_QueryInterface,
    class_object_AddRef,
    class_object_Release,
    class_object_GetQualifierSet,
    class_object_Get,
    class_object_Put,
    class_object_Delete,
    class_object_GetNames,
    class_object_BeginEnumeration,
    class_object_Next,
    class_object_EndEnumeration,
    class_object_GetPropertyQualifierSet,
    class_object_Clone,
    class_object_GetObjectText,
    class_object_SpawnDerivedClass,
    class_object_SpawnInstance,
    class_object_CompareTo,
    class_object_GetPropertyOrigin,
    class_object_InheritsFrom,
    class_object_GetMethod,
    class_object_PutMethod,
    class_object_DeleteMethod,
    class_object_BeginMethodEnumeration,
    class_object_NextMethod,
    class_object_EndMethodEnumeration,
    class_object_GetMethodQualifierSet,
    class_object_GetMethodOrigin
};

HRESULT create_class_object( const WCHAR *name, IEnumWbemClassObject *iter, UINT index,
                             struct record *record, IWbemClassObject **obj )
{
    struct class_object *co;

    TRACE("%s, %p\n", debugstr_w(name), obj);

    co = heap_alloc( sizeof(*co) );
    if (!co) return E_OUTOFMEMORY;

    co->IWbemClassObject_iface.lpVtbl = &class_object_vtbl;
    co->refs  = 1;
    if (!name) co->name = NULL;
    else if (!(co->name = heap_strdupW( name )))
    {
        heap_free( co );
        return E_OUTOFMEMORY;
    }
    co->iter           = iter;
    co->index          = index;
    co->index_method   = 0;
    co->index_property = 0;
    co->record         = record;
    if (iter) IEnumWbemClassObject_AddRef( iter );

    *obj = &co->IWbemClassObject_iface;

    TRACE("returning iface %p\n", *obj);
    return S_OK;
}
