/*
 * Copyright 2013 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 "initguid.h"
#include "objbase.h"
#include "wmiutils.h"
#include "wbemcli.h"
#include "wbemdisp.h"

#include "wine/debug.h"
#include "wine/unicode.h"
#include "wbemdisp_private.h"
#include "wbemdisp_classes.h"

WINE_DEFAULT_DEBUG_CHANNEL(wbemdisp);

static HRESULT EnumVARIANT_create( IEnumWbemClassObject *, IEnumVARIANT ** );

enum type_id
{
    ISWbemLocator_tid,
    ISWbemObject_tid,
    ISWbemObjectSet_tid,
    ISWbemProperty_tid,
    ISWbemPropertySet_tid,
    ISWbemServices_tid,
    last_tid
};

static ITypeLib *wbemdisp_typelib;
static ITypeInfo *wbemdisp_typeinfo[last_tid];

static REFIID wbemdisp_tid_id[] =
{
    &IID_ISWbemLocator,
    &IID_ISWbemObject,
    &IID_ISWbemObjectSet,
    &IID_ISWbemProperty,
    &IID_ISWbemPropertySet,
    &IID_ISWbemServices
};

static HRESULT get_typeinfo( enum type_id tid, ITypeInfo **ret )
{
    HRESULT hr;

    if (!wbemdisp_typelib)
    {
        ITypeLib *typelib;

        hr = LoadRegTypeLib( &LIBID_WbemScripting, 1, 2, LOCALE_SYSTEM_DEFAULT, &typelib );
        if (FAILED( hr ))
        {
            ERR( "LoadRegTypeLib failed: %08x\n", hr );
            return hr;
        }
        if (InterlockedCompareExchangePointer( (void **)&wbemdisp_typelib, typelib, NULL ))
            ITypeLib_Release( typelib );
    }
    if (!wbemdisp_typeinfo[tid])
    {
        ITypeInfo *typeinfo;

        hr = ITypeLib_GetTypeInfoOfGuid( wbemdisp_typelib, wbemdisp_tid_id[tid], &typeinfo );
        if (FAILED( hr ))
        {
            ERR( "GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(wbemdisp_tid_id[tid]), hr );
            return hr;
        }
        if (InterlockedCompareExchangePointer( (void **)(wbemdisp_typeinfo + tid), typeinfo, NULL ))
            ITypeInfo_Release( typeinfo );
    }
    *ret = wbemdisp_typeinfo[tid];
    ITypeInfo_AddRef( *ret );
    return S_OK;
}

struct property
{
    ISWbemProperty ISWbemProperty_iface;
    LONG refs;
    IWbemClassObject *object;
    BSTR name;
};

static inline struct property *impl_from_ISWbemProperty( ISWbemProperty *iface )
{
    return CONTAINING_RECORD( iface, struct property, ISWbemProperty_iface );
}

static ULONG WINAPI property_AddRef( ISWbemProperty *iface )
{
    struct property *property = impl_from_ISWbemProperty( iface );
    return InterlockedIncrement( &property->refs );
}

static ULONG WINAPI property_Release( ISWbemProperty *iface )
{
    struct property *property = impl_from_ISWbemProperty( iface );
    LONG refs = InterlockedDecrement( &property->refs );
    if (!refs)
    {
        TRACE( "destroying %p\n", property );
        IWbemClassObject_Release( property->object );
        SysFreeString( property->name );
        heap_free( property );
    }
    return refs;
}

static HRESULT WINAPI property_QueryInterface( ISWbemProperty *iface, REFIID riid, void **obj )
{
    struct property *property = impl_from_ISWbemProperty( iface );

    TRACE( "%p %s %p\n", property, debugstr_guid(riid), obj );

    if (IsEqualGUID( riid, &IID_ISWbemProperty ) ||
        IsEqualGUID( riid, &IID_IDispatch ) ||
        IsEqualGUID( riid, &IID_IUnknown ))
    {
        *obj = iface;
    }
    else
    {
        FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
        return E_NOINTERFACE;
    }
    ISWbemProperty_AddRef( iface );
    return S_OK;
}

static HRESULT WINAPI property_GetTypeInfoCount( ISWbemProperty *iface, UINT *count )
{
    struct property *property = impl_from_ISWbemProperty( iface );
    TRACE( "%p, %p\n", property, count );
    *count = 1;
    return S_OK;
}

static HRESULT WINAPI property_GetTypeInfo( ISWbemProperty *iface, UINT index,
                                            LCID lcid, ITypeInfo **info )
{
    struct property *property = impl_from_ISWbemProperty( iface );
    TRACE( "%p, %u, %u, %p\n", property, index, lcid, info );

    return get_typeinfo( ISWbemProperty_tid, info );
}

static HRESULT WINAPI property_GetIDsOfNames( ISWbemProperty *iface, REFIID riid, LPOLESTR *names,
                                              UINT count, LCID lcid, DISPID *dispid )
{
    struct property *property = impl_from_ISWbemProperty( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE( "%p, %s, %p, %u, %u, %p\n", property, debugstr_guid(riid), names, count, lcid, dispid );

    if (!names || !count || !dispid) return E_INVALIDARG;

    hr = get_typeinfo( ISWbemProperty_tid, &typeinfo );
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
        ITypeInfo_Release( typeinfo );
    }
    return hr;
}

static HRESULT WINAPI property_Invoke( ISWbemProperty *iface, DISPID member, REFIID riid,
                                       LCID lcid, WORD flags, DISPPARAMS *params,
                                       VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err )
{
    struct property *property = impl_from_ISWbemProperty( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", property, member, debugstr_guid(riid),
           lcid, flags, params, result, excep_info, arg_err );

    hr = get_typeinfo( ISWbemProperty_tid, &typeinfo );
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke( typeinfo, &property->ISWbemProperty_iface, member, flags,
                               params, result, excep_info, arg_err );
        ITypeInfo_Release( typeinfo );
    }
    return hr;
}

static HRESULT WINAPI property_get_Value( ISWbemProperty *iface, VARIANT *value )
{
    struct property *property = impl_from_ISWbemProperty( iface );

    TRACE( "%p %p\n", property, value );

    return IWbemClassObject_Get( property->object, property->name, 0, value, NULL, NULL );
}

static HRESULT WINAPI property_put_Value( ISWbemProperty *iface, VARIANT *varValue )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI property_get_Name( ISWbemProperty *iface, BSTR *strName )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI property_get_IsLocal( ISWbemProperty *iface, VARIANT_BOOL *bIsLocal )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI property_get_Origin( ISWbemProperty *iface, BSTR *strOrigin )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI property_get_CIMType( ISWbemProperty *iface, WbemCimtypeEnum *iCimType )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI property_get_Qualifiers_( ISWbemProperty *iface, ISWbemQualifierSet **objWbemQualifierSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI property_get_IsArray( ISWbemProperty *iface, VARIANT_BOOL *bIsArray )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static const ISWbemPropertyVtbl property_vtbl =
{
    property_QueryInterface,
    property_AddRef,
    property_Release,
    property_GetTypeInfoCount,
    property_GetTypeInfo,
    property_GetIDsOfNames,
    property_Invoke,
    property_get_Value,
    property_put_Value,
    property_get_Name,
    property_get_IsLocal,
    property_get_Origin,
    property_get_CIMType,
    property_get_Qualifiers_,
    property_get_IsArray
};

static HRESULT SWbemProperty_create( IWbemClassObject *wbem_object, BSTR name, ISWbemProperty **obj )
{
    struct property *property;

    TRACE( "%p, %p\n", obj, wbem_object );

    if (!(property = heap_alloc( sizeof(*property) ))) return E_OUTOFMEMORY;
    property->ISWbemProperty_iface.lpVtbl = &property_vtbl;
    property->refs = 1;
    property->object = wbem_object;
    IWbemClassObject_AddRef( property->object );
    property->name = SysAllocStringLen( name, SysStringLen( name ) );
    *obj = &property->ISWbemProperty_iface;
    TRACE( "returning iface %p\n", *obj );
    return S_OK;
}

struct propertyset
{
    ISWbemPropertySet ISWbemPropertySet_iface;
    LONG refs;
    IWbemClassObject *object;
};

static inline struct propertyset *impl_from_ISWbemPropertySet(
    ISWbemPropertySet *iface )
{
    return CONTAINING_RECORD( iface, struct propertyset, ISWbemPropertySet_iface );
}

static ULONG WINAPI propertyset_AddRef( ISWbemPropertySet *iface )
{
    struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface );
    return InterlockedIncrement( &propertyset->refs );
}

static ULONG WINAPI propertyset_Release( ISWbemPropertySet *iface )
{
    struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface );
    LONG refs = InterlockedDecrement( &propertyset->refs );
    if (!refs)
    {
        TRACE( "destroying %p\n", propertyset );
        IWbemClassObject_Release( propertyset->object );
        heap_free( propertyset );
    }
    return refs;
}

static HRESULT WINAPI propertyset_QueryInterface( ISWbemPropertySet *iface,
                                                  REFIID riid, void **obj )
{
    struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface );

    TRACE( "%p %s %p\n", propertyset, debugstr_guid(riid), obj );

    if (IsEqualGUID( riid, &IID_ISWbemPropertySet ) ||
        IsEqualGUID( riid, &IID_IDispatch ) ||
        IsEqualGUID( riid, &IID_IUnknown ))
    {
        *obj = iface;
    }
    else
    {
        FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
        return E_NOINTERFACE;
    }
    ISWbemPropertySet_AddRef( iface );
    return S_OK;
}

static HRESULT WINAPI propertyset_GetTypeInfoCount( ISWbemPropertySet *iface, UINT *count )
{
    struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface );
    TRACE( "%p, %p\n", propertyset, count );
    *count = 1;
    return S_OK;
}

static HRESULT WINAPI propertyset_GetTypeInfo( ISWbemPropertySet *iface,
                                               UINT index, LCID lcid, ITypeInfo **info )
{
    struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface );
    TRACE( "%p, %u, %u, %p\n", propertyset, index, lcid, info );

    return get_typeinfo( ISWbemPropertySet_tid, info );
}

static HRESULT WINAPI propertyset_GetIDsOfNames( ISWbemPropertySet *iface, REFIID riid, LPOLESTR *names,
                                                 UINT count, LCID lcid, DISPID *dispid )
{
    struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE( "%p, %s, %p, %u, %u, %p\n", propertyset, debugstr_guid(riid), names, count, lcid, dispid );

    if (!names || !count || !dispid) return E_INVALIDARG;

    hr = get_typeinfo( ISWbemPropertySet_tid, &typeinfo );
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
        ITypeInfo_Release( typeinfo );
    }
    return hr;
}

static HRESULT WINAPI propertyset_Invoke( ISWbemPropertySet *iface, DISPID member, REFIID riid,
                                          LCID lcid, WORD flags, DISPPARAMS *params,
                                          VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err )
{
    struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", propertyset, member, debugstr_guid(riid),
           lcid, flags, params, result, excep_info, arg_err );

    hr = get_typeinfo( ISWbemPropertySet_tid, &typeinfo );
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke( typeinfo, &propertyset->ISWbemPropertySet_iface, member, flags,
                               params, result, excep_info, arg_err );
        ITypeInfo_Release( typeinfo );
    }
    return hr;
}

static HRESULT WINAPI propertyset_get__NewEnum( ISWbemPropertySet *iface, IUnknown **unk )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI propertyset_Item( ISWbemPropertySet *iface, BSTR name,
                                        LONG flags, ISWbemProperty **prop )
{
    struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface );
    HRESULT hr;
    VARIANT var;

    TRACE( "%p, %s, %08x, %p\n", propertyset, debugstr_w(name), flags, prop );

    hr = IWbemClassObject_Get( propertyset->object, name, 0, &var, NULL, NULL );
    if (SUCCEEDED(hr))
    {
        hr = SWbemProperty_create( propertyset->object, name, prop );
        VariantClear( &var );
    }
    return hr;
}

static HRESULT WINAPI propertyset_get_Count( ISWbemPropertySet *iface, LONG *count )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI propertyset_Add( ISWbemPropertySet *iface, BSTR name, WbemCimtypeEnum type,
                                       VARIANT_BOOL is_array, LONG flags, ISWbemProperty **prop )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI propertyset_Remove( ISWbemPropertySet *iface, BSTR name, LONG flags )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static const ISWbemPropertySetVtbl propertyset_vtbl =
{
    propertyset_QueryInterface,
    propertyset_AddRef,
    propertyset_Release,
    propertyset_GetTypeInfoCount,
    propertyset_GetTypeInfo,
    propertyset_GetIDsOfNames,
    propertyset_Invoke,
    propertyset_get__NewEnum,
    propertyset_Item,
    propertyset_get_Count,
    propertyset_Add,
    propertyset_Remove
};

static HRESULT SWbemPropertySet_create( IWbemClassObject *wbem_object, ISWbemPropertySet **obj )
{
    struct propertyset *propertyset;

    TRACE( "%p, %p\n", obj, wbem_object );

    if (!(propertyset = heap_alloc( sizeof(*propertyset) ))) return E_OUTOFMEMORY;
    propertyset->ISWbemPropertySet_iface.lpVtbl = &propertyset_vtbl;
    propertyset->refs = 1;
    propertyset->object = wbem_object;
    IWbemClassObject_AddRef( propertyset->object );
    *obj = &propertyset->ISWbemPropertySet_iface;

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

#define DISPID_BASE 0x1800000

struct member
{
    BSTR name;
    DISPID dispid;
};

struct object
{
    ISWbemObject ISWbemObject_iface;
    LONG refs;
    IWbemClassObject *object;
    struct member *members;
    UINT nb_members;
    DISPID last_dispid;
};

static inline struct object *impl_from_ISWbemObject(
    ISWbemObject *iface )
{
    return CONTAINING_RECORD( iface, struct object, ISWbemObject_iface );
}

static ULONG WINAPI object_AddRef(
    ISWbemObject *iface )
{
    struct object *object = impl_from_ISWbemObject( iface );
    return InterlockedIncrement( &object->refs );
}

static ULONG WINAPI object_Release(
    ISWbemObject *iface )
{
    struct object *object = impl_from_ISWbemObject( iface );
    LONG refs = InterlockedDecrement( &object->refs );
    if (!refs)
    {
        UINT i;

        TRACE( "destroying %p\n", object );
        IWbemClassObject_Release( object->object );
        for (i = 0; i < object->nb_members; i++) SysFreeString( object->members[i].name );
        heap_free( object->members );
        heap_free( object );
    }
    return refs;
}

static HRESULT WINAPI object_QueryInterface(
    ISWbemObject *iface,
    REFIID riid,
    void **ppvObject )
{
    struct object *object = impl_from_ISWbemObject( iface );

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

    if (IsEqualGUID( riid, &IID_ISWbemObject ) ||
        IsEqualGUID( riid, &IID_IDispatch ) ||
        IsEqualGUID( riid, &IID_IUnknown ))
    {
        *ppvObject = iface;
    }
    else
    {
        FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
        return E_NOINTERFACE;
    }
    ISWbemObject_AddRef( iface );
    return S_OK;
}

static HRESULT WINAPI object_GetTypeInfoCount(
    ISWbemObject *iface,
    UINT *count )
{
    struct object *object = impl_from_ISWbemObject( iface );

    TRACE( "%p, %p\n", object, count );
    *count = 1;
    return S_OK;
}

static HRESULT WINAPI object_GetTypeInfo(
    ISWbemObject *iface,
    UINT index,
    LCID lcid,
    ITypeInfo **info )
{
    struct object *object = impl_from_ISWbemObject( iface );
    FIXME( "%p, %u, %u, %p\n", object, index, lcid, info );
    return E_NOTIMPL;
}

static HRESULT init_members( struct object *object )
{
    LONG bound, i;
    SAFEARRAY *sa;
    HRESULT hr;

    if (object->members) return S_OK;

    hr = IWbemClassObject_GetNames( object->object, NULL, 0, NULL, &sa );
    if (FAILED( hr )) return hr;
    hr = SafeArrayGetUBound( sa, 1, &bound );
    if (FAILED( hr ))
    {
        SafeArrayDestroy( sa );
        return hr;
    }
    if (!(object->members = heap_alloc( sizeof(struct member) * (bound + 1) )))
    {
        SafeArrayDestroy( sa );
        return E_OUTOFMEMORY;
    }
    for (i = 0; i <= bound; i++)
    {
        hr = SafeArrayGetElement( sa, &i, &object->members[i].name );
        if (FAILED( hr ))
        {
            for (i--; i >= 0; i--) SysFreeString( object->members[i].name );
            SafeArrayDestroy( sa );
            heap_free( object->members );
            object->members = NULL;
            return E_OUTOFMEMORY;
        }
        object->members[i].dispid = 0;
    }
    object->nb_members = bound + 1;
    SafeArrayDestroy( sa );
    return S_OK;
}

static DISPID get_member_dispid( struct object *object, const WCHAR *name )
{
    UINT i;
    for (i = 0; i < object->nb_members; i++)
    {
        if (!strcmpiW( object->members[i].name, name ))
        {
            if (!object->members[i].dispid) object->members[i].dispid = ++object->last_dispid;
            return object->members[i].dispid;
        }
    }
    return DISPID_UNKNOWN;
}

static HRESULT WINAPI object_GetIDsOfNames(
    ISWbemObject *iface,
    REFIID riid,
    LPOLESTR *names,
    UINT count,
    LCID lcid,
    DISPID *dispid )
{
    struct object *object = impl_from_ISWbemObject( iface );
    HRESULT hr;
    UINT i;
    ITypeInfo *typeinfo;

    TRACE( "%p, %s, %p, %u, %u, %p\n", object, debugstr_guid(riid), names, count, lcid, dispid );

    if (!names || !count || !dispid) return E_INVALIDARG;

    hr = init_members( object );
    if (FAILED( hr )) return hr;

    hr = get_typeinfo( ISWbemObject_tid, &typeinfo );
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
        ITypeInfo_Release( typeinfo );
    }
    if (SUCCEEDED(hr)) return hr;

    for (i = 0; i < count; i++)
    {
        if ((dispid[i] = get_member_dispid( object, names[i] )) == DISPID_UNKNOWN) break;
    }
    if (i != count) return DISP_E_UNKNOWNNAME;
    return S_OK;
}

static BSTR get_member_name( struct object *object, DISPID dispid )
{
    UINT i;
    for (i = 0; i < object->nb_members; i++)
    {
        if (object->members[i].dispid == dispid) return object->members[i].name;
    }
    return NULL;
}

static HRESULT WINAPI object_Invoke(
    ISWbemObject *iface,
    DISPID member,
    REFIID riid,
    LCID lcid,
    WORD flags,
    DISPPARAMS *params,
    VARIANT *result,
    EXCEPINFO *excep_info,
    UINT *arg_err )
{
    struct object *object = impl_from_ISWbemObject( iface );
    BSTR name;
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE( "%p, %x, %s, %u, %x, %p, %p, %p, %p\n", object, member, debugstr_guid(riid),
           lcid, flags, params, result, excep_info, arg_err );

    if (member <= DISPID_BASE)
    {
        hr = get_typeinfo( ISWbemObject_tid, &typeinfo );
        if (SUCCEEDED(hr))
        {
            hr = ITypeInfo_Invoke( typeinfo, &object->ISWbemObject_iface, member, flags,
                                   params, result, excep_info, arg_err );
            ITypeInfo_Release( typeinfo );
        }
        return hr;
    }

    if (flags != (DISPATCH_METHOD|DISPATCH_PROPERTYGET))
    {
        FIXME( "flags %x not supported\n", flags );
        return E_NOTIMPL;
    }
    if (!(name = get_member_name( object, member )))
        return DISP_E_MEMBERNOTFOUND;

    memset( params, 0, sizeof(*params) );
    return IWbemClassObject_Get( object->object, name, 0, result, NULL, NULL );
}

static HRESULT WINAPI object_Put_(
    ISWbemObject *iface,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObjectPath **objWbemObjectPath )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_PutAsync_(
    ISWbemObject *iface,
    IDispatch *objWbemSink,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_Delete_(
    ISWbemObject *iface,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_DeleteAsync_(
    ISWbemObject *iface,
    IDispatch *objWbemSink,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_Instances_(
    ISWbemObject *iface,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObjectSet **objWbemObjectSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_InstancesAsync_(
    ISWbemObject *iface,
    IDispatch *objWbemSink,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_Subclasses_(
    ISWbemObject *iface,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObjectSet **objWbemObjectSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_SubclassesAsync_(
    ISWbemObject *iface,
    IDispatch *objWbemSink,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_Associators_(
    ISWbemObject *iface,
    BSTR strAssocClass,
    BSTR strResultClass,
    BSTR strResultRole,
    BSTR strRole,
    VARIANT_BOOL bClassesOnly,
    VARIANT_BOOL bSchemaOnly,
    BSTR strRequiredAssocQualifier,
    BSTR strRequiredQualifier,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObjectSet **objWbemObjectSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_AssociatorsAsync_(
    ISWbemObject *iface,
    IDispatch *objWbemSink,
    BSTR strAssocClass,
    BSTR strResultClass,
    BSTR strResultRole,
    BSTR strRole,
    VARIANT_BOOL bClassesOnly,
    VARIANT_BOOL bSchemaOnly,
    BSTR strRequiredAssocQualifier,
    BSTR strRequiredQualifier,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_References_(
    ISWbemObject *iface,
    BSTR strResultClass,
    BSTR strRole,
    VARIANT_BOOL bClassesOnly,
    VARIANT_BOOL bSchemaOnly,
    BSTR strRequiredQualifier,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObjectSet **objWbemObjectSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_ReferencesAsync_(
    ISWbemObject *iface,
    IDispatch *objWbemSink,
    BSTR strResultClass,
    BSTR strRole,
    VARIANT_BOOL bClassesOnly,
    VARIANT_BOOL bSchemaOnly,
    BSTR strRequiredQualifier,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_ExecMethod_(
    ISWbemObject *iface,
    BSTR strMethodName,
    IDispatch *objWbemInParameters,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObject **objWbemOutParameters )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_ExecMethodAsync_(
    ISWbemObject *iface,
    IDispatch *objWbemSink,
    BSTR strMethodName,
    IDispatch *objWbemInParameters,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_Clone_(
    ISWbemObject *iface,
    ISWbemObject **objWbemObject )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_GetObjectText_(
    ISWbemObject *iface,
    LONG iFlags,
    BSTR *strObjectText )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_SpawnDerivedClass_(
    ISWbemObject *iface,
    LONG iFlags,
    ISWbemObject **objWbemObject )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_SpawnInstance_(
    ISWbemObject *iface,
    LONG iFlags,
    ISWbemObject **objWbemObject )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_CompareTo_(
    ISWbemObject *iface,
    IDispatch *objWbemObject,
    LONG iFlags,
    VARIANT_BOOL *bResult )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_get_Qualifiers_(
    ISWbemObject *iface,
    ISWbemQualifierSet **objWbemQualifierSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_get_Properties_( ISWbemObject *iface, ISWbemPropertySet **prop_set )
{
    struct object *object = impl_from_ISWbemObject( iface );

    TRACE( "%p, %p\n", object, prop_set );
    return SWbemPropertySet_create( object->object, prop_set );
}

static HRESULT WINAPI object_get_Methods_(
    ISWbemObject *iface,
    ISWbemMethodSet **objWbemMethodSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_get_Derivation_(
    ISWbemObject *iface,
    VARIANT *strClassNameArray )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_get_Path_(
    ISWbemObject *iface,
    ISWbemObjectPath **objWbemObjectPath )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI object_get_Security_(
    ISWbemObject *iface,
    ISWbemSecurity **objWbemSecurity )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static const ISWbemObjectVtbl object_vtbl =
{
    object_QueryInterface,
    object_AddRef,
    object_Release,
    object_GetTypeInfoCount,
    object_GetTypeInfo,
    object_GetIDsOfNames,
    object_Invoke,
    object_Put_,
    object_PutAsync_,
    object_Delete_,
    object_DeleteAsync_,
    object_Instances_,
    object_InstancesAsync_,
    object_Subclasses_,
    object_SubclassesAsync_,
    object_Associators_,
    object_AssociatorsAsync_,
    object_References_,
    object_ReferencesAsync_,
    object_ExecMethod_,
    object_ExecMethodAsync_,
    object_Clone_,
    object_GetObjectText_,
    object_SpawnDerivedClass_,
    object_SpawnInstance_,
    object_CompareTo_,
    object_get_Qualifiers_,
    object_get_Properties_,
    object_get_Methods_,
    object_get_Derivation_,
    object_get_Path_,
    object_get_Security_
};

static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject **obj )
{
    struct object *object;

    TRACE( "%p, %p\n", obj, wbem_object );

    if (!(object = heap_alloc( sizeof(*object) ))) return E_OUTOFMEMORY;
    object->ISWbemObject_iface.lpVtbl = &object_vtbl;
    object->refs = 1;
    object->object = wbem_object;
    IWbemClassObject_AddRef( object->object );
    object->members = NULL;
    object->nb_members = 0;
    object->last_dispid = DISPID_BASE;

    *obj = &object->ISWbemObject_iface;
    TRACE( "returning iface %p\n", *obj );
    return S_OK;
}

struct objectset
{
    ISWbemObjectSet ISWbemObjectSet_iface;
    LONG refs;
    IEnumWbemClassObject *objectenum;
    LONG count;
};

static inline struct objectset *impl_from_ISWbemObjectSet(
    ISWbemObjectSet *iface )
{
    return CONTAINING_RECORD( iface, struct objectset, ISWbemObjectSet_iface );
}

static ULONG WINAPI objectset_AddRef(
    ISWbemObjectSet *iface )
{
    struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
    return InterlockedIncrement( &objectset->refs );
}

static ULONG WINAPI objectset_Release(
    ISWbemObjectSet *iface )
{
    struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
    LONG refs = InterlockedDecrement( &objectset->refs );
    if (!refs)
    {
        TRACE( "destroying %p\n", objectset );
        IEnumWbemClassObject_Release( objectset->objectenum );
        heap_free( objectset );
    }
    return refs;
}

static HRESULT WINAPI objectset_QueryInterface(
    ISWbemObjectSet *iface,
    REFIID riid,
    void **ppvObject )
{
    struct objectset *objectset = impl_from_ISWbemObjectSet( iface );

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

    if (IsEqualGUID( riid, &IID_ISWbemObjectSet ) ||
        IsEqualGUID( riid, &IID_IDispatch ) ||
        IsEqualGUID( riid, &IID_IUnknown ))
    {
        *ppvObject = iface;
    }
    else
    {
        FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
        return E_NOINTERFACE;
    }
    ISWbemObjectSet_AddRef( iface );
    return S_OK;
}

static HRESULT WINAPI objectset_GetTypeInfoCount(
    ISWbemObjectSet *iface,
    UINT *count )
{
    struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
    TRACE( "%p, %p\n", objectset, count );
    *count = 1;
    return S_OK;
}

static HRESULT WINAPI objectset_GetTypeInfo(
    ISWbemObjectSet *iface,
    UINT index,
    LCID lcid,
    ITypeInfo **info )
{
    struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
    TRACE( "%p, %u, %u, %p\n", objectset, index, lcid, info );

    return get_typeinfo( ISWbemObjectSet_tid, info );
}

static HRESULT WINAPI objectset_GetIDsOfNames(
    ISWbemObjectSet *iface,
    REFIID riid,
    LPOLESTR *names,
    UINT count,
    LCID lcid,
    DISPID *dispid )
{
    struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE( "%p, %s, %p, %u, %u, %p\n", objectset, debugstr_guid(riid), names, count, lcid, dispid );

    if (!names || !count || !dispid) return E_INVALIDARG;

    hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo );
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
        ITypeInfo_Release( typeinfo );
    }
    return hr;
}

static HRESULT WINAPI objectset_Invoke(
    ISWbemObjectSet *iface,
    DISPID member,
    REFIID riid,
    LCID lcid,
    WORD flags,
    DISPPARAMS *params,
    VARIANT *result,
    EXCEPINFO *excep_info,
    UINT *arg_err )
{
    struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", objectset, member, debugstr_guid(riid),
           lcid, flags, params, result, excep_info, arg_err );

    hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo );
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke( typeinfo, &objectset->ISWbemObjectSet_iface, member, flags,
                               params, result, excep_info, arg_err );
        ITypeInfo_Release( typeinfo );
    }
    return hr;
}

static HRESULT WINAPI objectset_get__NewEnum(
    ISWbemObjectSet *iface,
    IUnknown **pUnk )
{
    struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
    IEnumWbemClassObject *objectenum;
    HRESULT hr;

    TRACE( "%p, %p\n", objectset, pUnk );

    hr = IEnumWbemClassObject_Clone( objectset->objectenum, &objectenum );
    if (FAILED( hr )) return hr;

    hr = EnumVARIANT_create( objectenum, (IEnumVARIANT **)pUnk );
    IEnumWbemClassObject_Release( objectenum );
    return hr;
}

static HRESULT WINAPI objectset_Item(
    ISWbemObjectSet *iface,
    BSTR strObjectPath,
    LONG iFlags,
    ISWbemObject **objWbemObject )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI objectset_get_Count(
    ISWbemObjectSet *iface,
    LONG *iCount )
{
    struct objectset *objectset = impl_from_ISWbemObjectSet( iface );

    TRACE( "%p, %p\n", objectset, iCount );

    *iCount = objectset->count;
    return S_OK;
}

static HRESULT WINAPI objectset_get_Security_(
    ISWbemObjectSet *iface,
    ISWbemSecurity **objWbemSecurity )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI objectset_ItemIndex(
    ISWbemObjectSet *iface,
    LONG lIndex,
    ISWbemObject **objWbemObject )
{
    struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
    LONG count;
    HRESULT hr;
    IEnumVARIANT *enum_var;
    VARIANT var;

    TRACE( "%p, %d, %p\n", objectset, lIndex, objWbemObject );

    *objWbemObject = NULL;
    hr = ISWbemObjectSet_get_Count( iface, &count );
    if (FAILED(hr)) return hr;

    if (lIndex >= count) return WBEM_E_NOT_FOUND;

    hr = ISWbemObjectSet_get__NewEnum( iface, (IUnknown **)&enum_var );
    if (FAILED(hr)) return hr;

    IEnumVARIANT_Reset( enum_var );
    hr = IEnumVARIANT_Skip( enum_var, lIndex );
    if (SUCCEEDED(hr))
        hr = IEnumVARIANT_Next( enum_var, 1, &var, NULL );
    IEnumVARIANT_Release( enum_var );

    if (SUCCEEDED(hr))
    {
        if (V_VT( &var ) == VT_DISPATCH)
            hr = IDispatch_QueryInterface( V_DISPATCH( &var ), &IID_ISWbemObject, (void **)objWbemObject );
        else
            hr = WBEM_E_NOT_FOUND;
        VariantClear( &var );
    }

    return hr;
}

static const ISWbemObjectSetVtbl objectset_vtbl =
{
    objectset_QueryInterface,
    objectset_AddRef,
    objectset_Release,
    objectset_GetTypeInfoCount,
    objectset_GetTypeInfo,
    objectset_GetIDsOfNames,
    objectset_Invoke,
    objectset_get__NewEnum,
    objectset_Item,
    objectset_get_Count,
    objectset_get_Security_,
    objectset_ItemIndex
};

static LONG get_object_count( IEnumWbemClassObject *iter )
{
    LONG count = 0;
    while (IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 ) == S_OK) count++;
    IEnumWbemClassObject_Reset( iter );
    return count;
}

static HRESULT SWbemObjectSet_create( IEnumWbemClassObject *wbem_objectenum, ISWbemObjectSet **obj )
{
    struct objectset *objectset;

    TRACE( "%p, %p\n", obj, wbem_objectenum );

    if (!(objectset = heap_alloc( sizeof(*objectset) ))) return E_OUTOFMEMORY;
    objectset->ISWbemObjectSet_iface.lpVtbl = &objectset_vtbl;
    objectset->refs = 1;
    objectset->objectenum = wbem_objectenum;
    IEnumWbemClassObject_AddRef( objectset->objectenum );
    objectset->count = get_object_count( objectset->objectenum );

    *obj = &objectset->ISWbemObjectSet_iface;
    TRACE( "returning iface %p\n", *obj );
    return S_OK;
}

struct enumvar
{
    IEnumVARIANT IEnumVARIANT_iface;
    LONG refs;
    IEnumWbemClassObject *objectenum;
};

static inline struct enumvar *impl_from_IEnumVARIANT(
    IEnumVARIANT *iface )
{
    return CONTAINING_RECORD( iface, struct enumvar, IEnumVARIANT_iface );
}

static ULONG WINAPI enumvar_AddRef(
    IEnumVARIANT *iface )
{
    struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
    return InterlockedIncrement( &enumvar->refs );
}

static ULONG WINAPI enumvar_Release(
    IEnumVARIANT *iface )
{
    struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
    LONG refs = InterlockedDecrement( &enumvar->refs );
    if (!refs)
    {
        TRACE( "destroying %p\n", enumvar );
        IEnumWbemClassObject_Release( enumvar->objectenum );
        heap_free( enumvar );
    }
    return refs;
}

static HRESULT WINAPI enumvar_QueryInterface(
    IEnumVARIANT *iface,
    REFIID riid,
    void **ppvObject )
{
    struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );

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

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

static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched )
{
    struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
    IWbemClassObject *obj;
    ULONG count = 0;

    TRACE( "%p, %u, %p, %p\n", iface, celt, var, fetched );

    if (celt) IEnumWbemClassObject_Next( enumvar->objectenum, WBEM_INFINITE, 1, &obj, &count );
    if (count)
    {
        ISWbemObject *sobj;
        HRESULT hr;

        hr = SWbemObject_create( obj, &sobj );
        IWbemClassObject_Release( obj );
        if (FAILED( hr )) return hr;

        V_VT( var ) = VT_DISPATCH;
        V_DISPATCH( var ) = (IDispatch *)sobj;
    }
    if (fetched) *fetched = count;
    return (count < celt) ? S_FALSE : S_OK;
}

static HRESULT WINAPI enumvar_Skip( IEnumVARIANT *iface, ULONG celt )
{
    struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );

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

    return IEnumWbemClassObject_Skip( enumvar->objectenum, WBEM_INFINITE, celt );
}

static HRESULT WINAPI enumvar_Reset( IEnumVARIANT *iface )
{
    struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );

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

    return IEnumWbemClassObject_Reset( enumvar->objectenum );
}

static HRESULT WINAPI enumvar_Clone( IEnumVARIANT *iface, IEnumVARIANT **penum )
{
    FIXME( "%p, %p\n", iface, penum );
    return E_NOTIMPL;
}

static const struct IEnumVARIANTVtbl enumvar_vtbl =
{
    enumvar_QueryInterface,
    enumvar_AddRef,
    enumvar_Release,
    enumvar_Next,
    enumvar_Skip,
    enumvar_Reset,
    enumvar_Clone
};

static HRESULT EnumVARIANT_create( IEnumWbemClassObject *objectenum, IEnumVARIANT **obj )
{
    struct enumvar *enumvar;

    if (!(enumvar = heap_alloc( sizeof(*enumvar) ))) return E_OUTOFMEMORY;
    enumvar->IEnumVARIANT_iface.lpVtbl = &enumvar_vtbl;
    enumvar->refs = 1;
    enumvar->objectenum = objectenum;
    IEnumWbemClassObject_AddRef( enumvar->objectenum );

    *obj = &enumvar->IEnumVARIANT_iface;
    TRACE( "returning iface %p\n", *obj );
    return S_OK;
}

struct services
{
    ISWbemServices ISWbemServices_iface;
    LONG refs;
    IWbemServices *services;
};

static inline struct services *impl_from_ISWbemServices(
    ISWbemServices *iface )
{
    return CONTAINING_RECORD( iface, struct services, ISWbemServices_iface );
}

static ULONG WINAPI services_AddRef(
    ISWbemServices *iface )
{
    struct services *services = impl_from_ISWbemServices( iface );
    return InterlockedIncrement( &services->refs );
}

static ULONG WINAPI services_Release(
    ISWbemServices *iface )
{
    struct services *services = impl_from_ISWbemServices( iface );
    LONG refs = InterlockedDecrement( &services->refs );
    if (!refs)
    {
        TRACE( "destroying %p\n", services );
        IWbemServices_Release( services->services );
        heap_free( services );
    }
    return refs;
}

static HRESULT WINAPI services_QueryInterface(
    ISWbemServices *iface,
    REFIID riid,
    void **ppvObject )
{
    struct services *services = impl_from_ISWbemServices( iface );

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

    if (IsEqualGUID( riid, &IID_ISWbemServices ) ||
        IsEqualGUID( riid, &IID_IDispatch ) ||
        IsEqualGUID( riid, &IID_IUnknown ))
    {
        *ppvObject = iface;
    }
    else
    {
        FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
        return E_NOINTERFACE;
    }
    ISWbemServices_AddRef( iface );
    return S_OK;
}

static HRESULT WINAPI services_GetTypeInfoCount(
    ISWbemServices *iface,
    UINT *count )
{
    struct services *services = impl_from_ISWbemServices( iface );
    TRACE( "%p, %p\n", services, count );

    *count = 1;
    return S_OK;
}

static HRESULT WINAPI services_GetTypeInfo(
    ISWbemServices *iface,
    UINT index,
    LCID lcid,
    ITypeInfo **info )
{
    struct services *services = impl_from_ISWbemServices( iface );
    TRACE( "%p, %u, %u, %p\n", services, index, lcid, info );

    return get_typeinfo( ISWbemServices_tid, info );
}

static HRESULT WINAPI services_GetIDsOfNames(
    ISWbemServices *iface,
    REFIID riid,
    LPOLESTR *names,
    UINT count,
    LCID lcid,
    DISPID *dispid )
{
    struct services *services = impl_from_ISWbemServices( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE( "%p, %s, %p, %u, %u, %p\n", services, debugstr_guid(riid), names, count, lcid, dispid );

    if (!names || !count || !dispid) return E_INVALIDARG;

    hr = get_typeinfo( ISWbemServices_tid, &typeinfo );
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
        ITypeInfo_Release( typeinfo );
    }
    return hr;
}

static HRESULT WINAPI services_Invoke(
    ISWbemServices *iface,
    DISPID member,
    REFIID riid,
    LCID lcid,
    WORD flags,
    DISPPARAMS *params,
    VARIANT *result,
    EXCEPINFO *excep_info,
    UINT *arg_err )
{
    struct services *services = impl_from_ISWbemServices( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", services, member, debugstr_guid(riid),
           lcid, flags, params, result, excep_info, arg_err );

    hr = get_typeinfo( ISWbemServices_tid, &typeinfo );
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke( typeinfo, &services->ISWbemServices_iface, member, flags,
                               params, result, excep_info, arg_err );
        ITypeInfo_Release( typeinfo );
    }
    return hr;
}

static HRESULT WINAPI services_Get(
    ISWbemServices *iface,
    BSTR strObjectPath,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObject **objWbemObject )
{
    struct services *services = impl_from_ISWbemServices( iface );
    IWbemClassObject *obj;
    HRESULT hr;

    TRACE( "%p, %s, %d, %p, %p\n", iface, debugstr_w(strObjectPath), iFlags, objWbemNamedValueSet,
           objWbemObject );

    if (objWbemNamedValueSet) FIXME( "ignoring context\n" );

    hr = IWbemServices_GetObject( services->services, strObjectPath, iFlags, NULL, &obj, NULL );
    if (hr != S_OK) return hr;

    hr = SWbemObject_create( obj, objWbemObject );
    IWbemClassObject_Release( obj );
    return hr;
}

static HRESULT WINAPI services_GetAsync(
    ISWbemServices *iface,
    IDispatch *objWbemSink,
    BSTR strObjectPath,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_Delete(
    ISWbemServices *iface,
    BSTR strObjectPath,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_DeleteAsync(
    ISWbemServices* This,
    IDispatch *objWbemSink,
    BSTR strObjectPath,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static BSTR build_query_string( const WCHAR *class )
{
    static const WCHAR selectW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0};
    UINT len = strlenW(class) + sizeof(selectW) / sizeof(selectW[0]);
    BSTR ret;

    if (!(ret = SysAllocStringLen( NULL, len ))) return NULL;
    strcpyW( ret, selectW );
    strcatW( ret, class );
    return ret;
}

static HRESULT WINAPI services_InstancesOf(
    ISWbemServices *iface,
    BSTR strClass,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObjectSet **objWbemObjectSet )
{
    static const WCHAR wqlW[] = {'W','Q','L',0};
    BSTR query, wql = SysAllocString( wqlW );
    HRESULT hr;

    TRACE( "%p, %s, %x, %p, %p\n", iface, debugstr_w(strClass), iFlags, objWbemNamedValueSet,
           objWbemObjectSet );

    if (!(query = build_query_string( strClass )))
    {
        SysFreeString( wql );
        return E_OUTOFMEMORY;
    }
    hr = ISWbemServices_ExecQuery( iface, query, wql, iFlags, objWbemNamedValueSet, objWbemObjectSet );
    SysFreeString( wql );
    SysFreeString( query );
    return hr;
}

static HRESULT WINAPI services_InstancesOfAsync(
    ISWbemServices *iface,
    IDispatch *objWbemSink,
    BSTR strClass,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_SubclassesOf(
    ISWbemServices *iface,
    BSTR strSuperclass,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObjectSet **objWbemObjectSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_SubclassesOfAsync(
    ISWbemServices *iface,
    IDispatch *objWbemSink,
    BSTR strSuperclass,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_ExecQuery(
    ISWbemServices *iface,
    BSTR strQuery,
    BSTR strQueryLanguage,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObjectSet **objWbemObjectSet )
{
    struct services *services = impl_from_ISWbemServices( iface );
    IEnumWbemClassObject *iter;
    HRESULT hr;

    TRACE( "%p, %s, %s, %x, %p, %p\n", iface, debugstr_w(strQuery), debugstr_w(strQueryLanguage),
           iFlags, objWbemNamedValueSet, objWbemObjectSet );

    if (objWbemNamedValueSet) FIXME( "ignoring context\n" );

    hr = IWbemServices_ExecQuery( services->services, strQueryLanguage, strQuery, iFlags, NULL, &iter );
    if (hr != S_OK) return hr;

    hr = SWbemObjectSet_create( iter, objWbemObjectSet );
    IEnumWbemClassObject_Release( iter );
    return hr;
}

static HRESULT WINAPI services_ExecQueryAsync(
    ISWbemServices *iface,
    IDispatch *objWbemSink,
    BSTR strQuery,
    BSTR strQueryLanguage,
    LONG lFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_AssociatorsOf(
    ISWbemServices *iface,
    BSTR strObjectPath,
    BSTR strAssocClass,
    BSTR strResultClass,
    BSTR strResultRole,
    BSTR strRole,
    VARIANT_BOOL bClassesOnly,
    VARIANT_BOOL bSchemaOnly,
    BSTR strRequiredAssocQualifier,
    BSTR strRequiredQualifier,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObjectSet **objWbemObjectSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_AssociatorsOfAsync(
    ISWbemServices *iface,
    IDispatch *objWbemSink,
    BSTR strObjectPath,
    BSTR strAssocClass,
    BSTR strResultClass,
    BSTR strResultRole,
    BSTR strRole,
    VARIANT_BOOL bClassesOnly,
    VARIANT_BOOL bSchemaOnly,
    BSTR strRequiredAssocQualifier,
    BSTR strRequiredQualifier,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_ReferencesTo(
    ISWbemServices *iface,
    BSTR strObjectPath,
    BSTR strResultClass,
    BSTR strRole,
    VARIANT_BOOL bClassesOnly,
    VARIANT_BOOL bSchemaOnly,
    BSTR strRequiredQualifier,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObjectSet **objWbemObjectSet )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_ReferencesToAsync(
    ISWbemServices *iface,
    IDispatch *objWbemSink,
    BSTR strObjectPath,
    BSTR strResultClass,
    BSTR strRole,
    VARIANT_BOOL bClassesOnly,
    VARIANT_BOOL bSchemaOnly,
    BSTR strRequiredQualifier,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_ExecNotificationQuery(
    ISWbemServices *iface,
    BSTR strQuery,
    BSTR strQueryLanguage,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemEventSource **objWbemEventSource )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_ExecNotificationQueryAsync(
    ISWbemServices *iface,
    IDispatch *objWbemSink,
    BSTR strQuery,
    BSTR strQueryLanguage,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_ExecMethod(
    ISWbemServices *iface,
    BSTR strObjectPath,
    BSTR strMethodName,
    IDispatch *objWbemInParameters,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemObject **objWbemOutParameters )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_ExecMethodAsync(
    ISWbemServices *iface,
    IDispatch *objWbemSink,
    BSTR strObjectPath,
    BSTR strMethodName,
    IDispatch *objWbemInParameters,
    LONG iFlags,
    IDispatch *objWbemNamedValueSet,
    IDispatch *objWbemAsyncContext )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static HRESULT WINAPI services_get_Security_(
        ISWbemServices *iface,
        ISWbemSecurity **objWbemSecurity )
{
    FIXME( "\n" );
    return E_NOTIMPL;
}

static const ISWbemServicesVtbl services_vtbl =
{
    services_QueryInterface,
    services_AddRef,
    services_Release,
    services_GetTypeInfoCount,
    services_GetTypeInfo,
    services_GetIDsOfNames,
    services_Invoke,
    services_Get,
    services_GetAsync,
    services_Delete,
    services_DeleteAsync,
    services_InstancesOf,
    services_InstancesOfAsync,
    services_SubclassesOf,
    services_SubclassesOfAsync,
    services_ExecQuery,
    services_ExecQueryAsync,
    services_AssociatorsOf,
    services_AssociatorsOfAsync,
    services_ReferencesTo,
    services_ReferencesToAsync,
    services_ExecNotificationQuery,
    services_ExecNotificationQueryAsync,
    services_ExecMethod,
    services_ExecMethodAsync,
    services_get_Security_
};

static HRESULT SWbemServices_create( IWbemServices *wbem_services, ISWbemServices **obj )
{
    struct services *services;

    TRACE( "%p, %p\n", obj, wbem_services );

    if (!(services = heap_alloc( sizeof(*services) ))) return E_OUTOFMEMORY;
    services->ISWbemServices_iface.lpVtbl = &services_vtbl;
    services->refs = 1;
    services->services = wbem_services;
    IWbemServices_AddRef( services->services );

    *obj = &services->ISWbemServices_iface;
    TRACE( "returning iface %p\n", *obj );
    return S_OK;
}

struct locator
{
    ISWbemLocator ISWbemLocator_iface;
    LONG refs;
    IWbemLocator *locator;
};

static inline struct locator *impl_from_ISWbemLocator( ISWbemLocator *iface )
{
    return CONTAINING_RECORD( iface, struct locator, ISWbemLocator_iface );
}

static ULONG WINAPI locator_AddRef(
    ISWbemLocator *iface )
{
    struct locator *locator = impl_from_ISWbemLocator( iface );
    return InterlockedIncrement( &locator->refs );
}

static ULONG WINAPI locator_Release(
    ISWbemLocator *iface )
{
    struct locator *locator = impl_from_ISWbemLocator( iface );
    LONG refs = InterlockedDecrement( &locator->refs );
    if (!refs)
    {
        TRACE( "destroying %p\n", locator );
        if (locator->locator)
            IWbemLocator_Release( locator->locator );
        heap_free( locator );
    }
    return refs;
}

static HRESULT WINAPI locator_QueryInterface(
    ISWbemLocator *iface,
    REFIID riid,
    void **ppvObject )
{
    struct locator *locator = impl_from_ISWbemLocator( iface );

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

    if (IsEqualGUID( riid, &IID_ISWbemLocator ) ||
        IsEqualGUID( riid, &IID_IDispatch ) ||
        IsEqualGUID( riid, &IID_IUnknown ))
    {
        *ppvObject = iface;
    }
    else
    {
        FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
        return E_NOINTERFACE;
    }
    ISWbemLocator_AddRef( iface );
    return S_OK;
}

static HRESULT WINAPI locator_GetTypeInfoCount(
    ISWbemLocator *iface,
    UINT *count )
{
    struct locator *locator = impl_from_ISWbemLocator( iface );

    TRACE( "%p, %p\n", locator, count );
    *count = 1;
    return S_OK;
}

static HRESULT WINAPI locator_GetTypeInfo(
    ISWbemLocator *iface,
    UINT index,
    LCID lcid,
    ITypeInfo **info )
{
    struct locator *locator = impl_from_ISWbemLocator( iface );
    TRACE( "%p, %u, %u, %p\n", locator, index, lcid, info );

    return get_typeinfo( ISWbemLocator_tid, info );
}

static HRESULT WINAPI locator_GetIDsOfNames(
    ISWbemLocator *iface,
    REFIID riid,
    LPOLESTR *names,
    UINT count,
    LCID lcid,
    DISPID *dispid )
{
    struct locator *locator = impl_from_ISWbemLocator( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE( "%p, %s, %p, %u, %u, %p\n", locator, debugstr_guid(riid), names, count, lcid, dispid );

    if (!names || !count || !dispid) return E_INVALIDARG;

    hr = get_typeinfo( ISWbemLocator_tid, &typeinfo );
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
        ITypeInfo_Release( typeinfo );
    }
    return hr;
}

static HRESULT WINAPI locator_Invoke(
    ISWbemLocator *iface,
    DISPID member,
    REFIID riid,
    LCID lcid,
    WORD flags,
    DISPPARAMS *params,
    VARIANT *result,
    EXCEPINFO *excep_info,
    UINT *arg_err )
{
    struct locator *locator = impl_from_ISWbemLocator( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", locator, member, debugstr_guid(riid),
           lcid, flags, params, result, excep_info, arg_err );

    hr = get_typeinfo( ISWbemLocator_tid, &typeinfo );
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke( typeinfo, &locator->ISWbemLocator_iface, member, flags,
                               params, result, excep_info, arg_err );
        ITypeInfo_Release( typeinfo );
    }
    return hr;
}

static BSTR build_resource_string( BSTR server, BSTR namespace )
{
    static const WCHAR defaultW[] = {'r','o','o','t','\\','d','e','f','a','u','l','t',0};
    ULONG len, len_server = 0, len_namespace = 0;
    BSTR ret;

    if (server && *server) len_server = strlenW( server );
    else len_server = 1;
    if (namespace && *namespace) len_namespace = strlenW( namespace );
    else len_namespace = sizeof(defaultW) / sizeof(defaultW[0]) - 1;

    if (!(ret = SysAllocStringLen( NULL, 2 + len_server + 1 + len_namespace ))) return NULL;

    ret[0] = ret[1] = '\\';
    if (server && *server) strcpyW( ret + 2, server );
    else ret[2] = '.';

    len = len_server + 2;
    ret[len++] = '\\';

    if (namespace && *namespace) strcpyW( ret + len, namespace );
    else strcpyW( ret + len, defaultW );
    return ret;
}

static HRESULT WINAPI locator_ConnectServer(
    ISWbemLocator *iface,
    BSTR strServer,
    BSTR strNamespace,
    BSTR strUser,
    BSTR strPassword,
    BSTR strLocale,
    BSTR strAuthority,
    LONG iSecurityFlags,
    IDispatch *objWbemNamedValueSet,
    ISWbemServices **objWbemServices )
{
    struct locator *locator = impl_from_ISWbemLocator( iface );
    IWbemServices *services;
    BSTR resource;
    HRESULT hr;

    TRACE( "%p, %s, %s, %s, %p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strServer),
           debugstr_w(strNamespace), debugstr_w(strUser), strPassword, debugstr_w(strLocale),
           debugstr_w(strAuthority), iSecurityFlags, objWbemNamedValueSet, objWbemServices );

    if (objWbemNamedValueSet) FIXME( "context not supported\n" );

    if (!locator->locator)
    {
        hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator,
                               (void **)&locator->locator );
        if (hr != S_OK) return hr;
    }

    if (!(resource = build_resource_string( strServer, strNamespace ))) return E_OUTOFMEMORY;
    hr = IWbemLocator_ConnectServer( locator->locator, resource, strUser, strPassword, strLocale,
                                     iSecurityFlags, strAuthority, NULL, &services );
    SysFreeString( resource );
    if (hr != S_OK) return hr;

    hr = SWbemServices_create( services, objWbemServices );
    IWbemServices_Release( services );
    return hr;
}

static HRESULT WINAPI locator_get_Security_(
    ISWbemLocator *iface,
    ISWbemSecurity **objWbemSecurity )
{
    FIXME( "%p, %p\n", iface, objWbemSecurity );
    return E_NOTIMPL;
}

static const ISWbemLocatorVtbl locator_vtbl =
{
    locator_QueryInterface,
    locator_AddRef,
    locator_Release,
    locator_GetTypeInfoCount,
    locator_GetTypeInfo,
    locator_GetIDsOfNames,
    locator_Invoke,
    locator_ConnectServer,
    locator_get_Security_
};

HRESULT SWbemLocator_create( void **obj )
{
    struct locator *locator;

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

    if (!(locator = heap_alloc( sizeof(*locator) ))) return E_OUTOFMEMORY;
    locator->ISWbemLocator_iface.lpVtbl = &locator_vtbl;
    locator->refs = 1;
    locator->locator = NULL;

    *obj = &locator->ISWbemLocator_iface;
    TRACE( "returning iface %p\n", *obj );
    return S_OK;
}
