/*
 * 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 "ole2.h"
#include "wbemcli.h"
#include "wmiutils.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(wmiutils);

struct keylist
{
    IWbemPathKeyList IWbemPathKeyList_iface;
    IWbemPath       *parent;
    LONG             refs;
};

struct key
{
    WCHAR *name;
    int    len_name;
    WCHAR *value;
    int    len_value;
};

struct path
{
    IWbemPath        IWbemPath_iface;
    LONG             refs;
    CRITICAL_SECTION cs;
    WCHAR           *text;
    int              len_text;
    WCHAR           *server;
    int              len_server;
    WCHAR          **namespaces;
    int             *len_namespaces;
    int              num_namespaces;
    WCHAR           *class;
    int              len_class;
    struct key      *keys;
    unsigned int     num_keys;
    ULONGLONG        flags;
};

static inline struct keylist *impl_from_IWbemPathKeyList( IWbemPathKeyList *iface )
{
    return CONTAINING_RECORD(iface, struct keylist, IWbemPathKeyList_iface);
}

static inline struct path *impl_from_IWbemPath( IWbemPath *iface )
{
    return CONTAINING_RECORD(iface, struct path, IWbemPath_iface);
}

static ULONG WINAPI keylist_AddRef(
    IWbemPathKeyList *iface )
{
    struct keylist *keylist = impl_from_IWbemPathKeyList( iface );
    return InterlockedIncrement( &keylist->refs );
}

static ULONG WINAPI keylist_Release(
    IWbemPathKeyList *iface )
{
    struct keylist *keylist = impl_from_IWbemPathKeyList( iface );
    LONG refs = InterlockedDecrement( &keylist->refs );
    if (!refs)
    {
        TRACE("destroying %p\n", keylist);
        IWbemPath_Release( keylist->parent );
        heap_free( keylist );
    }
    return refs;
}

static HRESULT WINAPI keylist_QueryInterface(
    IWbemPathKeyList *iface,
    REFIID riid,
    void **ppvObject )
{
    struct keylist *keylist = impl_from_IWbemPathKeyList( iface );

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

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

static HRESULT WINAPI keylist_GetCount(
    IWbemPathKeyList *iface,
    ULONG *puKeyCount )
{
    struct keylist *keylist = impl_from_IWbemPathKeyList( iface );
    struct path *parent = impl_from_IWbemPath( keylist->parent );

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

    if (!puKeyCount) return WBEM_E_INVALID_PARAMETER;

    EnterCriticalSection( &parent->cs );

    *puKeyCount = parent->num_keys;

    LeaveCriticalSection( &parent->cs );
    return S_OK;
}

static HRESULT WINAPI keylist_SetKey(
    IWbemPathKeyList *iface,
    LPCWSTR wszName,
    ULONG uFlags,
    ULONG uCimType,
    LPVOID pKeyVal )
{
    FIXME("%p, %s, 0x%x, %u, %p\n", iface, debugstr_w(wszName), uFlags, uCimType, pKeyVal);
    return E_NOTIMPL;
}

static HRESULT WINAPI keylist_SetKey2(
    IWbemPathKeyList *iface,
    LPCWSTR wszName,
    ULONG uFlags,
    ULONG uCimType,
    VARIANT *pKeyVal )
{
    FIXME("%p, %s, 0x%x, %u, %p\n", iface, debugstr_w(wszName), uFlags, uCimType, pKeyVal);
    return E_NOTIMPL;
}

static HRESULT WINAPI keylist_GetKey(
    IWbemPathKeyList *iface,
    ULONG uKeyIx,
    ULONG uFlags,
    ULONG *puNameBufSize,
    LPWSTR pszKeyName,
    ULONG *puKeyValBufSize,
    LPVOID pKeyVal,
    ULONG *puApparentCimType )
{
    FIXME("%p, %u, 0x%x, %p, %p, %p, %p, %p\n", iface, uKeyIx, uFlags, puNameBufSize,
          pszKeyName, puKeyValBufSize, pKeyVal, puApparentCimType);
    return E_NOTIMPL;
}

static HRESULT WINAPI keylist_GetKey2(
    IWbemPathKeyList *iface,
    ULONG uKeyIx,
    ULONG uFlags,
    ULONG *puNameBufSize,
    LPWSTR pszKeyName,
    VARIANT *pKeyValue,
    ULONG *puApparentCimType )
{
    FIXME("%p, %u, 0x%x, %p, %p, %p, %p\n", iface, uKeyIx, uFlags, puNameBufSize,
          pszKeyName, pKeyValue, puApparentCimType);
    return E_NOTIMPL;
}

static HRESULT WINAPI keylist_RemoveKey(
    IWbemPathKeyList *iface,
    LPCWSTR wszName,
    ULONG uFlags )
{
    FIXME("%p, %s, 0x%x\n", iface, debugstr_w(wszName), uFlags);
    return E_NOTIMPL;
}

static void free_keys( struct key *keys, unsigned int count )
{
    unsigned int i;

    for (i = 0; i < count; i++)
    {
        heap_free( keys[i].name );
        heap_free( keys[i].value );
    }
    heap_free( keys );
}

static HRESULT WINAPI keylist_RemoveAllKeys(
    IWbemPathKeyList *iface,
    ULONG uFlags )
{
    struct keylist *keylist = impl_from_IWbemPathKeyList( iface );
    struct path *parent = impl_from_IWbemPath( keylist->parent );

    TRACE("%p, 0x%x\n", iface, uFlags);

    if (uFlags) return WBEM_E_INVALID_PARAMETER;

    EnterCriticalSection( &parent->cs );

    free_keys( parent->keys, parent->num_keys );
    parent->num_keys = 0;
    parent->keys = NULL;

    LeaveCriticalSection( &parent->cs );
    return S_OK;
}

static HRESULT WINAPI keylist_MakeSingleton(
    IWbemPathKeyList *iface,
    boolean bSet )
{
    FIXME("%p, %d\n", iface, bSet);
    return E_NOTIMPL;
}

static HRESULT WINAPI keylist_GetInfo(
    IWbemPathKeyList *iface,
    ULONG uRequestedInfo,
    ULONGLONG *puResponse )
{
    FIXME("%p, %u, %p\n", iface, uRequestedInfo, puResponse);
    return E_NOTIMPL;
}

static HRESULT WINAPI keylist_GetText(
    IWbemPathKeyList *iface,
    LONG lFlags,
    ULONG *puBuffLength,
    LPWSTR pszText )
{
    FIXME("%p, 0x%x, %p, %p\n", iface, lFlags, puBuffLength, pszText);
    return E_NOTIMPL;
}

static const struct IWbemPathKeyListVtbl keylist_vtbl =
{
    keylist_QueryInterface,
    keylist_AddRef,
    keylist_Release,
    keylist_GetCount,
    keylist_SetKey,
    keylist_SetKey2,
    keylist_GetKey,
    keylist_GetKey2,
    keylist_RemoveKey,
    keylist_RemoveAllKeys,
    keylist_MakeSingleton,
    keylist_GetInfo,
    keylist_GetText
};

static HRESULT WbemPathKeyList_create( IWbemPath *parent, LPVOID *ppObj )
{
    struct keylist *keylist;

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

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

    keylist->IWbemPathKeyList_iface.lpVtbl = &keylist_vtbl;
    keylist->refs = 1;
    keylist->parent = parent;
    IWbemPath_AddRef( keylist->parent );

    *ppObj = &keylist->IWbemPathKeyList_iface;

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

static void init_path( struct path *path )
{
    path->text           = NULL;
    path->len_text       = 0;
    path->server         = NULL;
    path->len_server     = 0;
    path->namespaces     = NULL;
    path->len_namespaces = NULL;
    path->num_namespaces = 0;
    path->class          = NULL;
    path->len_class      = 0;
    path->keys           = NULL;
    path->num_keys       = 0;
    path->flags          = 0;
}

static void clear_path( struct path *path )
{
    unsigned int i;

    heap_free( path->text );
    heap_free( path->server );
    for (i = 0; i < path->num_namespaces; i++) heap_free( path->namespaces[i] );
    heap_free( path->namespaces );
    heap_free( path->len_namespaces );
    heap_free( path->class );
    free_keys( path->keys, path->num_keys );
    init_path( path );
}

static ULONG WINAPI path_AddRef(
    IWbemPath *iface )
{
    struct path *path = impl_from_IWbemPath( iface );
    return InterlockedIncrement( &path->refs );
}

static ULONG WINAPI path_Release(
    IWbemPath *iface )
{
    struct path *path = impl_from_IWbemPath( iface );
    LONG refs = InterlockedDecrement( &path->refs );
    if (!refs)
    {
        TRACE("destroying %p\n", path);
        clear_path( path );
        path->cs.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection( &path->cs );
        heap_free( path );
    }
    return refs;
}

static HRESULT WINAPI path_QueryInterface(
    IWbemPath *iface,
    REFIID riid,
    void **ppvObject )
{
    struct path *path = impl_from_IWbemPath( iface );

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

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

static HRESULT parse_key( struct key *key, const WCHAR *str, unsigned int *ret_len )
{
    const WCHAR *p, *q;
    unsigned int len;

    p = q = str;
    while (*q && *q != '=')
    {
        if (*q == ',' || isspaceW( *q )) return WBEM_E_INVALID_PARAMETER;
        q++;
    }
    len = q - p;
    if (!(key->name = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
    memcpy( key->name, p, len * sizeof(WCHAR) );
    key->name[len] = 0;
    key->len_name = len;

    p = ++q;
    if (!*p || *p == ',' || isspaceW( *p )) return WBEM_E_INVALID_PARAMETER;

    while (*q && *q != ',') q++;
    len = q - p;
    if (!(key->value = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
    memcpy( key->value, p, len * sizeof(WCHAR) );
    key->value[len] = 0;
    key->len_value = len;

    *ret_len = q - str;
    if (*q == ',') (*ret_len)++;
    return S_OK;
}

static HRESULT parse_text( struct path *path, ULONG mode, const WCHAR *text )
{
    HRESULT hr = E_OUTOFMEMORY;
    const WCHAR *p, *q;
    unsigned int i, len;

    p = q = text;
    if ((p[0] == '\\' && p[1] == '\\') || (p[0] == '/' && p[1] == '/'))
    {
        p += 2;
        q = p;
        while (*q && *q != '\\' && *q != '/') q++;
        len = q - p;
        if (!(path->server = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
        memcpy( path->server, p, len * sizeof(WCHAR) );
        path->server[len] = 0;
        path->len_server = len;
        path->flags |= WBEMPATH_INFO_PATH_HAD_SERVER;
    }
    p = q;
    if (strchrW( p, '\\' ) || strchrW( p, '/' ))
    {
        if (*q != '\\' && *q != '/' && *q != ':')
        {
            path->num_namespaces = 1;
            q++;
        }
        while (*q && *q != ':')
        {
            if (*q == '\\' || *q == '/') path->num_namespaces++;
            q++;
        }
    }
    if (path->num_namespaces)
    {
        if (!(path->namespaces = heap_alloc( path->num_namespaces * sizeof(WCHAR *) ))) goto done;
        if (!(path->len_namespaces = heap_alloc( path->num_namespaces * sizeof(int) ))) goto done;

        i = 0;
        q = p;
        if (*q && *q != '\\' && *q != '/' && *q != ':')
        {
            p = q;
            while (*p && *p != '\\' && *p != '/' && *p != ':') p++;
            len = p - q;
            if (!(path->namespaces[i] = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
            memcpy( path->namespaces[i], q, len * sizeof(WCHAR) );
            path->namespaces[i][len] = 0;
            path->len_namespaces[i] = len;
            q = p;
            i++;
        }
        while (*q && *q != ':')
        {
            if (*q == '\\' || *q == '/')
            {
                p = q + 1;
                while (*p && *p != '\\' && *p != '/' && *p != ':') p++;
                len = p - q - 1;
                if (!(path->namespaces[i] = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
                memcpy( path->namespaces[i], q + 1, len * sizeof(WCHAR) );
                path->namespaces[i][len] = 0;
                path->len_namespaces[i] = len;
                i++;
            }
            q++;
        }
    }
    if (*q == ':') q++;
    p = q;
    while (*q && *q != '.') q++;
    len = q - p;
    if (!(path->class = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
    memcpy( path->class, p, len * sizeof(WCHAR) );
    path->class[len] = 0;
    path->len_class = len;

    if (*q == '.')
    {
        p = ++q;
        path->num_keys++;
        while (*q)
        {
            if (*q == ',') path->num_keys++;
            q++;
        }
        if (!(path->keys = heap_alloc_zero( path->num_keys * sizeof(struct key) ))) goto done;
        i = 0;
        q = p;
        while (*q)
        {
            if (i >= path->num_keys) break;
            hr = parse_key( &path->keys[i], q, &len );
            if (hr != S_OK) goto done;
            q += len;
            i++;
        }
    }
    hr = S_OK;

done:
    if (hr != S_OK) clear_path( path );
    else path->flags |= WBEMPATH_INFO_CIM_COMPLIANT | WBEMPATH_INFO_V2_COMPLIANT;
    return hr;
}

static HRESULT WINAPI path_SetText(
    IWbemPath *iface,
    ULONG uMode,
    LPCWSTR pszPath)
{
    struct path *path = impl_from_IWbemPath( iface );
    HRESULT hr = S_OK;
    int len;

    TRACE("%p, %u, %s\n", iface, uMode, debugstr_w(pszPath));

    if (!uMode || !pszPath) return WBEM_E_INVALID_PARAMETER;

    EnterCriticalSection( &path->cs );

    clear_path( path );
    if (!pszPath[0]) goto done;
    if ((hr = parse_text( path, uMode, pszPath )) != S_OK) goto done;

    len = strlenW( pszPath );
    if (!(path->text = heap_alloc( (len + 1) * sizeof(WCHAR) )))
    {
        clear_path( path );
        hr = E_OUTOFMEMORY;
        goto done;
    }
    strcpyW( path->text, pszPath );
    path->len_text = len;

done:
    LeaveCriticalSection( &path->cs );
    return hr;
}

static WCHAR *build_namespace( struct path *path, int *len, BOOL leading_slash )
{
    WCHAR *ret, *p;
    int i;

    *len = 0;
    for (i = 0; i < path->num_namespaces; i++)
    {
        if (i > 0 || leading_slash) *len += 1;
        *len += path->len_namespaces[i];
    }
    if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL;
    for (i = 0; i < path->num_namespaces; i++)
    {
        if (i > 0 || leading_slash) *p++ = '\\';
        memcpy( p, path->namespaces[i], path->len_namespaces[i] * sizeof(WCHAR) );
        p += path->len_namespaces[i];
    }
    *p = 0;
    return ret;
}

static WCHAR *build_server( struct path *path, int *len )
{
    WCHAR *ret, *p;

    *len = 0;
    if (path->len_server) *len += 2 + path->len_server;
    else *len += 3;
    if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL;
    if (path->len_server)
    {
        p[0] = p[1] = '\\';
        strcpyW( p + 2, path->server );
    }
    else
    {
        p[0] = p[1] = '\\';
        p[2] = '.';
        p[3] = 0;
    }
    return ret;
}

static WCHAR *build_keylist( struct path *path, int *len )
{
    WCHAR *ret, *p;
    unsigned int i;

    *len = 0;
    for (i = 0; i < path->num_keys; i++)
    {
        if (i > 0) *len += 1;
        *len += path->keys[i].len_name + path->keys[i].len_value + 1;
    }
    if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL;
    for (i = 0; i < path->num_keys; i++)
    {
        if (i > 0) *p++ = ',';
        memcpy( p, path->keys[i].name, path->keys[i].len_name * sizeof(WCHAR) );
        p += path->keys[i].len_name;
        *p++ = '=';
        memcpy( p, path->keys[i].value, path->keys[i].len_value * sizeof(WCHAR) );
        p += path->keys[i].len_value;
    }
    *p = 0;
    return ret;
}

static WCHAR *build_path( struct path *path, LONG flags, int *len )
{
    *len = 0;
    switch (flags)
    {
    case 0:
    {
        int len_namespace, len_keylist;
        WCHAR *ret, *namespace = build_namespace( path, &len_namespace, FALSE );
        WCHAR *keylist = build_keylist( path, &len_keylist );

        if (!namespace || !keylist)
        {
            heap_free( namespace );
            heap_free( keylist );
            return NULL;
        }
        *len = len_namespace;
        if (path->len_class)
        {
            *len += path->len_class + 1;
            if (path->num_keys) *len += len_keylist + 1;
        }
        if (!(ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
        {
            heap_free( namespace );
            heap_free( keylist );
            return NULL;
        }
        strcpyW( ret, namespace );
        if (path->len_class)
        {
            ret[len_namespace] = ':';
            strcpyW( ret + len_namespace + 1, path->class );
            if (path->num_keys)
            {
                ret[len_namespace + path->len_class + 1] = '.';
                strcpyW( ret + len_namespace + path->len_class + 2, keylist );
            }
        }
        heap_free( namespace );
        heap_free( keylist );
        return ret;

    }
    case WBEMPATH_GET_RELATIVE_ONLY:
    {
        int len_keylist;
        WCHAR *ret, *keylist;

        if (!path->len_class) return NULL;
        if (!(keylist = build_keylist( path, &len_keylist ))) return NULL;

        *len = path->len_class;
        if (path->num_keys) *len += len_keylist + 1;
        if (!(ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
        {
            heap_free( keylist );
            return NULL;
        }
        strcpyW( ret, path->class );
        if (path->num_keys)
        {
            ret[path->len_class] = '.';
            strcpyW( ret + path->len_class + 1, keylist );
        }
        heap_free( keylist );
        return ret;
    }
    case WBEMPATH_GET_SERVER_TOO:
    {
        int len_namespace, len_server, len_keylist;
        WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace, TRUE );
        WCHAR *server = build_server( path, &len_server );
        WCHAR *keylist = build_keylist( path, &len_keylist );

        if (!namespace || !server || !keylist)
        {
            heap_free( namespace );
            heap_free( server );
            heap_free( keylist );
            return NULL;
        }
        *len = len_namespace + len_server;
        if (path->len_class)
        {
            *len += path->len_class + 1;
            if (path->num_keys) *len += len_keylist + 1;
        }
        if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
        {
            heap_free( namespace );
            heap_free( server );
            heap_free( keylist );
            return NULL;
        }
        strcpyW( p, server );
        p += len_server;
        strcpyW( p, namespace );
        p += len_namespace;
        if (path->len_class)
        {
            *p++ = ':';
            strcpyW( p, path->class );
            if (path->num_keys)
            {
                p[path->len_class] = '.';
                strcpyW( p + path->len_class + 1, keylist );
            }
        }
        heap_free( namespace );
        heap_free( server );
        heap_free( keylist );
        return ret;
    }
    case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY:
    {
        int len_namespace, len_server;
        WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace, TRUE );
        WCHAR *server = build_server( path, &len_server );

        if (!namespace || !server)
        {
            heap_free( namespace );
            heap_free( server );
            return NULL;
        }
        *len = len_namespace + len_server;
        if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
        {
            heap_free( namespace );
            heap_free( server );
            return NULL;
        }
        strcpyW( p, server );
        p += len_server;
        strcpyW( p, namespace );
        heap_free( namespace );
        heap_free( server );
        return ret;
    }
    case WBEMPATH_GET_NAMESPACE_ONLY:
        return build_namespace( path, len, FALSE );

    case WBEMPATH_GET_ORIGINAL:
        if (!path->len_text) return NULL;
        *len = path->len_text;
        return strdupW( path->text );

    default:
        ERR("unhandled flags 0x%x\n", flags);
        return NULL;
    }
}

static HRESULT WINAPI path_GetText(
    IWbemPath *iface,
    LONG lFlags,
    ULONG *puBufferLength,
    LPWSTR pszText)
{
    struct path *path = impl_from_IWbemPath( iface );
    HRESULT hr = S_OK;
    WCHAR *str;
    int len;

    TRACE("%p, 0x%x, %p, %p\n", iface, lFlags, puBufferLength, pszText);

    if (!puBufferLength) return WBEM_E_INVALID_PARAMETER;

    EnterCriticalSection( &path->cs );

    str = build_path( path, lFlags, &len );
    if (*puBufferLength < len + 1)
    {
        *puBufferLength = len + 1;
        goto done;
    }
    if (!pszText)
    {
        hr = WBEM_E_INVALID_PARAMETER;
        goto done;
    }
    if (str) strcpyW( pszText, str );
    else pszText[0] = 0;
    *puBufferLength = len + 1;

    TRACE("returning %s\n", debugstr_w(pszText));

done:
    heap_free( str );
    LeaveCriticalSection( &path->cs );
    return hr;
}

static HRESULT WINAPI path_GetInfo(
    IWbemPath *iface,
    ULONG info,
    ULONGLONG *response)
{
    struct path *path = impl_from_IWbemPath( iface );

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

    if (info || !response) return WBEM_E_INVALID_PARAMETER;

    FIXME("some flags are not implemented\n");

    EnterCriticalSection( &path->cs );

    *response = path->flags;
    if (!path->server || (path->len_server == 1 && path->server[0] == '.'))
        *response |= WBEMPATH_INFO_ANON_LOCAL_MACHINE;
    else
        *response |= WBEMPATH_INFO_HAS_MACHINE_NAME;

    if (!path->class)
        *response |= WBEMPATH_INFO_SERVER_NAMESPACE_ONLY;
    else
    {
        *response |= WBEMPATH_INFO_HAS_SUBSCOPES;
        if (path->num_keys)
            *response |= WBEMPATH_INFO_IS_INST_REF;
        else
            *response |= WBEMPATH_INFO_IS_CLASS_REF;
    }

    LeaveCriticalSection( &path->cs );
    return S_OK;
}

static HRESULT WINAPI path_SetServer(
    IWbemPath *iface,
    LPCWSTR name)
{
    struct path *path = impl_from_IWbemPath( iface );
    static const ULONGLONG flags =
        WBEMPATH_INFO_PATH_HAD_SERVER | WBEMPATH_INFO_V1_COMPLIANT |
        WBEMPATH_INFO_V2_COMPLIANT | WBEMPATH_INFO_CIM_COMPLIANT;
    WCHAR *server;

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

    EnterCriticalSection( &path->cs );

    if (name)
    {
        if (!(server = strdupW( name )))
        {
            LeaveCriticalSection( &path->cs );
            return WBEM_E_OUT_OF_MEMORY;
        }
        heap_free( path->server );
        path->server = server;
        path->len_server = strlenW( path->server );
        path->flags |= flags;
    }
    else
    {
        heap_free( path->server );
        path->server = NULL;
        path->len_server = 0;
        path->flags &= ~flags;
    }

    LeaveCriticalSection( &path->cs );
    return S_OK;
}

static HRESULT WINAPI path_GetServer(
    IWbemPath *iface,
    ULONG *len,
    LPWSTR name)
{
    struct path *path = impl_from_IWbemPath( iface );

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

    if (!len || (*len && !name)) return WBEM_E_INVALID_PARAMETER;

    EnterCriticalSection( &path->cs );

    if (!path->server)
    {
        LeaveCriticalSection( &path->cs );
        return WBEM_E_NOT_AVAILABLE;
    }
    if (*len > path->len_server) strcpyW( name, path->server );
    *len = path->len_server + 1;

    LeaveCriticalSection( &path->cs );
    return S_OK;
}

static HRESULT WINAPI path_GetNamespaceCount(
    IWbemPath *iface,
    ULONG *puCount)
{
    struct path *path = impl_from_IWbemPath( iface );

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

    if (!puCount) return WBEM_E_INVALID_PARAMETER;

    EnterCriticalSection( &path->cs );
    *puCount = path->num_namespaces;
    LeaveCriticalSection( &path->cs );
    return S_OK;
}

static HRESULT WINAPI path_SetNamespaceAt(
    IWbemPath *iface,
    ULONG idx,
    LPCWSTR name)
{
    struct path *path = impl_from_IWbemPath( iface );
    static const ULONGLONG flags =
        WBEMPATH_INFO_V1_COMPLIANT | WBEMPATH_INFO_V2_COMPLIANT |
        WBEMPATH_INFO_CIM_COMPLIANT;
    int i, *tmp_len;
    WCHAR **tmp, *new;
    DWORD size;

    TRACE("%p, %u, %s\n", iface, idx, debugstr_w(name));

    EnterCriticalSection( &path->cs );

    if (idx > path->num_namespaces || !name)
    {
        LeaveCriticalSection( &path->cs );
        return WBEM_E_INVALID_PARAMETER;
    }
    if (!(new = strdupW( name )))
    {
        LeaveCriticalSection( &path->cs );
        return WBEM_E_OUT_OF_MEMORY;
    }
    size = (path->num_namespaces + 1) * sizeof(WCHAR *);
    if (path->namespaces) tmp = heap_realloc( path->namespaces, size );
    else tmp = heap_alloc( size );
    if (!tmp)
    {
        heap_free( new );
        LeaveCriticalSection( &path->cs );
        return WBEM_E_OUT_OF_MEMORY;
    }
    path->namespaces = tmp;
    size = (path->num_namespaces + 1) * sizeof(int);
    if (path->len_namespaces) tmp_len = heap_realloc( path->len_namespaces, size );
    else tmp_len = heap_alloc( size );
    if (!tmp_len)
    {
        heap_free( new );
        LeaveCriticalSection( &path->cs );
        return WBEM_E_OUT_OF_MEMORY;
    }
    path->len_namespaces = tmp_len;
    for (i = idx; i < path->num_namespaces; i++)
    {
        path->namespaces[i + 1] = path->namespaces[i];
        path->len_namespaces[i + 1] = path->len_namespaces[i];
    }
    path->namespaces[idx] = new;
    path->len_namespaces[idx] = strlenW( new );
    path->num_namespaces++;
    path->flags |= flags;

    LeaveCriticalSection( &path->cs );
    return S_OK;
}

static HRESULT WINAPI path_GetNamespaceAt(
    IWbemPath *iface,
    ULONG idx,
    ULONG *len,
    LPWSTR name)
{
    struct path *path = impl_from_IWbemPath( iface );

    TRACE("%p, %u, %p, %p\n", iface, idx, len, name);

    EnterCriticalSection( &path->cs );

    if (!len || (*len && !name) || idx >= path->num_namespaces)
    {
        LeaveCriticalSection( &path->cs );
        return WBEM_E_INVALID_PARAMETER;
    }
    if (*len > path->len_namespaces[idx]) strcpyW( name, path->namespaces[idx] );
    *len = path->len_namespaces[idx] + 1;

    LeaveCriticalSection( &path->cs );
    return S_OK;
}

static HRESULT WINAPI path_RemoveNamespaceAt(
    IWbemPath *iface,
    ULONG idx)
{
    struct path *path = impl_from_IWbemPath( iface );

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

    EnterCriticalSection( &path->cs );

    if (idx >= path->num_namespaces)
    {
        LeaveCriticalSection( &path->cs );
        return WBEM_E_INVALID_PARAMETER;
    }
    heap_free( path->namespaces[idx] );
    while (idx < path->num_namespaces - 1)
    {
        path->namespaces[idx] = path->namespaces[idx + 1];
        path->len_namespaces[idx] = path->len_namespaces[idx + 1];
        idx++;
    }
    path->num_namespaces--;

    LeaveCriticalSection( &path->cs );
    return S_OK;
}

static HRESULT WINAPI path_RemoveAllNamespaces(
    IWbemPath *iface)
{
    struct path *path = impl_from_IWbemPath( iface );
    int i;

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

    EnterCriticalSection( &path->cs );

    for (i = 0; i < path->num_namespaces; i++) heap_free( path->namespaces[i] );
    path->num_namespaces = 0;
    heap_free( path->namespaces );
    path->namespaces = NULL;
    heap_free( path->len_namespaces );
    path->len_namespaces = NULL;

    LeaveCriticalSection( &path->cs );
    return S_OK;
}

static HRESULT WINAPI path_GetScopeCount(
    IWbemPath *iface,
    ULONG *puCount)
{
    FIXME("%p, %p\n", iface, puCount);
    return E_NOTIMPL;
}

static HRESULT WINAPI path_SetScope(
    IWbemPath *iface,
    ULONG uIndex,
    LPWSTR pszClass)
{
    FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszClass));
    return E_NOTIMPL;
}

static HRESULT WINAPI path_SetScopeFromText(
    IWbemPath *iface,
    ULONG uIndex,
    LPWSTR pszText)
{
    FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszText));
    return E_NOTIMPL;
}

static HRESULT WINAPI path_GetScope(
    IWbemPath *iface,
    ULONG uIndex,
    ULONG *puClassNameBufSize,
    LPWSTR pszClass,
    IWbemPathKeyList **pKeyList)
{
    FIXME("%p, %u, %p, %p, %p\n", iface, uIndex, puClassNameBufSize, pszClass, pKeyList);
    return E_NOTIMPL;
}

static HRESULT WINAPI path_GetScopeAsText(
    IWbemPath *iface,
    ULONG uIndex,
    ULONG *puTextBufSize,
    LPWSTR pszText)
{
    FIXME("%p, %u, %p, %p\n", iface, uIndex, puTextBufSize, pszText);
    return E_NOTIMPL;
}

static HRESULT WINAPI path_RemoveScope(
    IWbemPath *iface,
    ULONG uIndex)
{
    FIXME("%p, %u\n", iface, uIndex);
    return E_NOTIMPL;
}

static HRESULT WINAPI path_RemoveAllScopes(
    IWbemPath *iface)
{
    FIXME("%p\n", iface);
    return E_NOTIMPL;
}

static HRESULT WINAPI path_SetClassName(
    IWbemPath *iface,
    LPCWSTR name)
{
    struct path *path = impl_from_IWbemPath( iface );
    WCHAR *class;

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

    if (!name) return WBEM_E_INVALID_PARAMETER;
    if (!(class = strdupW( name ))) return WBEM_E_OUT_OF_MEMORY;

    EnterCriticalSection( &path->cs );

    heap_free( path->class );
    path->class = class;
    path->len_class = strlenW( path->class );
    path->flags |= WBEMPATH_INFO_V2_COMPLIANT | WBEMPATH_INFO_CIM_COMPLIANT;

    LeaveCriticalSection( &path->cs );
    return S_OK;
}

static HRESULT WINAPI path_GetClassName(
    IWbemPath *iface,
    ULONG *len,
    LPWSTR name)
{
    struct path *path = impl_from_IWbemPath( iface );

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

    if (!len || (*len && !name)) return WBEM_E_INVALID_PARAMETER;

    EnterCriticalSection( &path->cs );

    if (!path->class)
    {
        LeaveCriticalSection( &path->cs );
        return WBEM_E_INVALID_OBJECT_PATH;
    }
    if (*len > path->len_class) strcpyW( name, path->class );
    *len = path->len_class + 1;

    LeaveCriticalSection( &path->cs );
    return S_OK;
}

static HRESULT WINAPI path_GetKeyList(
    IWbemPath *iface,
    IWbemPathKeyList **pOut)
{
    struct path *path = impl_from_IWbemPath( iface );
    HRESULT hr;

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

    EnterCriticalSection( &path->cs );

    if (!path->class)
    {
        LeaveCriticalSection( &path->cs );
        return WBEM_E_INVALID_PARAMETER;
    }
    hr = WbemPathKeyList_create( iface, (void **)pOut );

    LeaveCriticalSection( &path->cs );
    return hr;
}

static HRESULT WINAPI path_CreateClassPart(
    IWbemPath *iface,
    LONG lFlags,
    LPCWSTR Name)
{
    FIXME("%p, 0x%x, %s\n", iface, lFlags, debugstr_w(Name));
    return E_NOTIMPL;
}

static HRESULT WINAPI path_DeleteClassPart(
    IWbemPath *iface,
    LONG lFlags)
{
    FIXME("%p, 0x%x\n", iface, lFlags);
    return E_NOTIMPL;
}

static BOOL WINAPI path_IsRelative(
    IWbemPath *iface,
    LPWSTR wszMachine,
    LPWSTR wszNamespace)
{
    FIXME("%p, %s, %s\n", iface, debugstr_w(wszMachine), debugstr_w(wszNamespace));
    return FALSE;
}

static BOOL WINAPI path_IsRelativeOrChild(
    IWbemPath *iface,
    LPWSTR wszMachine,
    LPWSTR wszNamespace,
    LONG lFlags)
{
    FIXME("%p, %s, %s, 0x%x\n", iface, debugstr_w(wszMachine), debugstr_w(wszNamespace), lFlags);
    return FALSE;
}

static BOOL WINAPI path_IsLocal(
    IWbemPath *iface,
    LPCWSTR wszMachine)
{
    FIXME("%p, %s\n", iface, debugstr_w(wszMachine));
    return FALSE;
}

static BOOL WINAPI path_IsSameClassName(
    IWbemPath *iface,
    LPCWSTR wszClass)
{
    FIXME("%p, %s\n", iface, debugstr_w(wszClass));
    return FALSE;
}

static const struct IWbemPathVtbl path_vtbl =
{
    path_QueryInterface,
    path_AddRef,
    path_Release,
    path_SetText,
    path_GetText,
    path_GetInfo,
    path_SetServer,
    path_GetServer,
    path_GetNamespaceCount,
    path_SetNamespaceAt,
    path_GetNamespaceAt,
    path_RemoveNamespaceAt,
    path_RemoveAllNamespaces,
    path_GetScopeCount,
    path_SetScope,
    path_SetScopeFromText,
    path_GetScope,
    path_GetScopeAsText,
    path_RemoveScope,
    path_RemoveAllScopes,
    path_SetClassName,
    path_GetClassName,
    path_GetKeyList,
    path_CreateClassPart,
    path_DeleteClassPart,
    path_IsRelative,
    path_IsRelativeOrChild,
    path_IsLocal,
    path_IsSameClassName
};

HRESULT WbemPath_create( LPVOID *ppObj )
{
    struct path *path;

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

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

    path->IWbemPath_iface.lpVtbl = &path_vtbl;
    path->refs = 1;
    InitializeCriticalSection( &path->cs );
    path->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wmiutils_path.cs");
    init_path( path );

    *ppObj = &path->IWbemPath_iface;

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