From ddaa7175588942f217ae91a4553120f1882c9a7e Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Tue, 17 Feb 2015 15:07:56 +0000 Subject: [PATCH] [WMIUTILS] - Import from Wine 1.7.27 (or your choice of any later version) CORE-9212 #resolve svn path=/trunk/; revision=66335 --- reactos/dll/win32/CMakeLists.txt | 1 + reactos/dll/win32/wmiutils/CMakeLists.txt | 17 + reactos/dll/win32/wmiutils/main.c | 171 +++ reactos/dll/win32/wmiutils/path.c | 1294 +++++++++++++++++ reactos/dll/win32/wmiutils/statuscode.c | 150 ++ reactos/dll/win32/wmiutils/wmiutils.rc | 2 + reactos/dll/win32/wmiutils/wmiutils.spec | 4 + .../dll/win32/wmiutils/wmiutils_classes.idl | 33 + .../dll/win32/wmiutils/wmiutils_classes.rgs | 17 + reactos/dll/win32/wmiutils/wmiutils_private.h | 53 + reactos/include/psdk/CMakeLists.txt | 1 + reactos/include/psdk/wmiutils.idl | 236 +++ reactos/media/doc/README.WINE | 1 + reactos/media/inf/syssetup.inf | 1 + rostests/winetests/CMakeLists.txt | 1 + rostests/winetests/wmiutils/CMakeLists.txt | 9 + rostests/winetests/wmiutils/path.c | 882 +++++++++++ rostests/winetests/wmiutils/testlist.c | 15 + 18 files changed, 2888 insertions(+) create mode 100644 reactos/dll/win32/wmiutils/CMakeLists.txt create mode 100644 reactos/dll/win32/wmiutils/main.c create mode 100644 reactos/dll/win32/wmiutils/path.c create mode 100644 reactos/dll/win32/wmiutils/statuscode.c create mode 100644 reactos/dll/win32/wmiutils/wmiutils.rc create mode 100644 reactos/dll/win32/wmiutils/wmiutils.spec create mode 100644 reactos/dll/win32/wmiutils/wmiutils_classes.idl create mode 100644 reactos/dll/win32/wmiutils/wmiutils_classes.rgs create mode 100644 reactos/dll/win32/wmiutils/wmiutils_private.h create mode 100644 reactos/include/psdk/wmiutils.idl create mode 100644 rostests/winetests/wmiutils/CMakeLists.txt create mode 100644 rostests/winetests/wmiutils/path.c create mode 100644 rostests/winetests/wmiutils/testlist.c diff --git a/reactos/dll/win32/CMakeLists.txt b/reactos/dll/win32/CMakeLists.txt index 88445839523..4434f44549f 100644 --- a/reactos/dll/win32/CMakeLists.txt +++ b/reactos/dll/win32/CMakeLists.txt @@ -237,6 +237,7 @@ add_subdirectory(wintrust) add_subdirectory(wlanapi) add_subdirectory(wldap32) add_subdirectory(wmi) +add_subdirectory(wmiutils) add_subdirectory(ws2_32) add_subdirectory(ws2_32_new) add_subdirectory(ws2help) diff --git a/reactos/dll/win32/wmiutils/CMakeLists.txt b/reactos/dll/win32/wmiutils/CMakeLists.txt new file mode 100644 index 00000000000..14c84a302fa --- /dev/null +++ b/reactos/dll/win32/wmiutils/CMakeLists.txt @@ -0,0 +1,17 @@ + +add_definitions(-D__WINESRC__) + +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) +spec2def(wmiutils.dll wmiutils.spec) + +list(APPEND SOURCE + main.c + path.c + statuscode.c + ${CMAKE_CURRENT_BINARY_DIR}/wmiutils.def) + +add_library(wmiutils SHARED ${SOURCE} wmiutils.rc) +set_module_type(wmiutils win32dll) +target_link_libraries(wmiutils wine) +add_importlibs(wmiutils oleaut32 msvcrt kernel32 ntdll) +add_cd_file(TARGET wmiutils DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/win32/wmiutils/main.c b/reactos/dll/win32/wmiutils/main.c new file mode 100644 index 00000000000..89fd26b248d --- /dev/null +++ b/reactos/dll/win32/wmiutils/main.c @@ -0,0 +1,171 @@ +/* + * Copyright 2009 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 + */ + +#include "config.h" +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "initguid.h" +#include "objbase.h" +#include "wbemcli.h" +#include "wmiutils.h" +#include "rpcproxy.h" + +#include "wine/debug.h" +#include "wmiutils_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wmiutils); + +static HINSTANCE instance; + +typedef HRESULT (*fnCreateInstance)( LPVOID *ppObj ); + +typedef struct +{ + IClassFactory IClassFactory_iface; + fnCreateInstance pfnCreateInstance; +} wmiutils_cf; + +static inline wmiutils_cf *impl_from_IClassFactory( IClassFactory *iface ) +{ + return CONTAINING_RECORD(iface, wmiutils_cf, IClassFactory_iface); +} + +static HRESULT WINAPI wmiutils_cf_QueryInterface( IClassFactory *iface, REFIID riid, LPVOID *ppobj ) +{ + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IClassFactory)) + { + IClassFactory_AddRef( iface ); + *ppobj = iface; + return S_OK; + } + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI wmiutils_cf_AddRef( IClassFactory *iface ) +{ + return 2; +} + +static ULONG WINAPI wmiutils_cf_Release( IClassFactory *iface ) +{ + return 1; +} + +static HRESULT WINAPI wmiutils_cf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOuter, + REFIID riid, LPVOID *ppobj ) +{ + wmiutils_cf *This = impl_from_IClassFactory( iface ); + HRESULT r; + IUnknown *punk; + + TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj); + + *ppobj = NULL; + + if (pOuter) + return CLASS_E_NOAGGREGATION; + + r = This->pfnCreateInstance( (LPVOID *)&punk ); + if (FAILED(r)) + return r; + + r = IUnknown_QueryInterface( punk, riid, ppobj ); + IUnknown_Release( punk ); + return r; +} + +static HRESULT WINAPI wmiutils_cf_LockServer( IClassFactory *iface, BOOL dolock ) +{ + FIXME("(%p)->(%d)\n", iface, dolock); + return S_OK; +} + +static const struct IClassFactoryVtbl wmiutils_cf_vtbl = +{ + wmiutils_cf_QueryInterface, + wmiutils_cf_AddRef, + wmiutils_cf_Release, + wmiutils_cf_CreateInstance, + wmiutils_cf_LockServer +}; + +static wmiutils_cf status_code_cf = { { &wmiutils_cf_vtbl }, WbemStatusCodeText_create }; +static wmiutils_cf path_cf = { { &wmiutils_cf_vtbl }, WbemPath_create }; + +BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID lpv ) +{ + switch(reason) + { + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + instance = hinst; + DisableThreadLibraryCalls( hinst ); + break; + } + return TRUE; +} + +HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) +{ + IClassFactory *cf = NULL; + + TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); + + if (IsEqualGUID( rclsid, &CLSID_WbemStatusCode )) + { + cf = &status_code_cf.IClassFactory_iface; + } + else if (IsEqualGUID( rclsid, &CLSID_WbemDefPath )) + { + cf = &path_cf.IClassFactory_iface; + } + if (!cf) return CLASS_E_CLASSNOTAVAILABLE; + return IClassFactory_QueryInterface( cf, iid, ppv ); +} + +/*********************************************************************** + * DllCanUnloadNow (WMIUTILS.@) + */ +HRESULT WINAPI DllCanUnloadNow( void ) +{ + return S_FALSE; +} + +/*********************************************************************** + * DllRegisterServer (WMIUTILS.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + return __wine_register_resources( instance ); +} + +/*********************************************************************** + * DllUnregisterServer (WMIUTILS.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + return __wine_unregister_resources( instance ); +} diff --git a/reactos/dll/win32/wmiutils/path.c b/reactos/dll/win32/wmiutils/path.c new file mode 100644 index 00000000000..79774160d34 --- /dev/null +++ b/reactos/dll/win32/wmiutils/path.c @@ -0,0 +1,1294 @@ +/* + * 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 + +#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 E_NOTIMPL; +} + +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 E_NOTIMPL; +} + +static BOOL WINAPI path_IsLocal( + IWbemPath *iface, + LPCWSTR wszMachine) +{ + FIXME("%p, %s\n", iface, debugstr_w(wszMachine)); + return E_NOTIMPL; +} + +static BOOL WINAPI path_IsSameClassName( + IWbemPath *iface, + LPCWSTR wszClass) +{ + FIXME("%p, %s\n", iface, debugstr_w(wszClass)); + return E_NOTIMPL; +} + +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; +} diff --git a/reactos/dll/win32/wmiutils/statuscode.c b/reactos/dll/win32/wmiutils/statuscode.c new file mode 100644 index 00000000000..719f3af8b5d --- /dev/null +++ b/reactos/dll/win32/wmiutils/statuscode.c @@ -0,0 +1,150 @@ +/* + * Copyright 2009 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 +#include + +#include "windef.h" +#include "winbase.h" +#include "ole2.h" +#include "wbemcli.h" + +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wmiutils_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wmiutils); + +typedef struct status_code +{ + IWbemStatusCodeText IWbemStatusCodeText_iface; + LONG refs; +} status_code; + +static inline status_code *impl_from_IWbemStatusCodeText( IWbemStatusCodeText *iface ) +{ + return CONTAINING_RECORD(iface, status_code, IWbemStatusCodeText_iface); +} + +static ULONG WINAPI status_code_AddRef( + IWbemStatusCodeText *iface ) +{ + status_code *status_code = impl_from_IWbemStatusCodeText( iface ); + return InterlockedIncrement( &status_code->refs ); +} + +static ULONG WINAPI status_code_Release( + IWbemStatusCodeText *iface ) +{ + status_code *status_code = impl_from_IWbemStatusCodeText( iface ); + LONG refs = InterlockedDecrement( &status_code->refs ); + if (!refs) + { + TRACE("destroying %p\n", status_code); + heap_free( status_code ); + } + return refs; +} + +static HRESULT WINAPI status_code_QueryInterface( + IWbemStatusCodeText *iface, + REFIID riid, + void **ppvObject ) +{ + status_code *This = impl_from_IWbemStatusCodeText( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IWbemStatusCodeText ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemStatusCodeText_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI status_code_GetErrorCodeText( + IWbemStatusCodeText *iface, + HRESULT res, + LCID lcid, + LONG flags, + BSTR *text ) +{ + static const WCHAR fmt[] = + {'E','r','r','o','r',' ','c','o','d','e',':',' ','0','x','%','0','8','x',0}; + WCHAR msg[32]; + + FIXME("%p, 0x%08x, 0x%04x, 0x%08x, %p\n", iface, res, lcid, flags, text); + + sprintfW(msg, fmt, res); + *text = SysAllocString(msg); + return WBEM_S_NO_ERROR; +} + +static HRESULT WINAPI status_code_GetFacilityCodeText( + IWbemStatusCodeText *iface, + HRESULT res, + LCID lcid, + LONG flags, + BSTR *text ) +{ + static const WCHAR fmt[] = + {'F','a','c','i','l','i','t','y',' ','c','o','d','e',':',' ','0','x','%','0','8','x',0}; + WCHAR msg[32]; + + FIXME("%p, 0x%08x, 0x%04x, 0x%08x, %p\n", iface, res, lcid, flags, text); + + sprintfW(msg, fmt, res); + *text = SysAllocString(msg); + return WBEM_S_NO_ERROR; +} + +static const struct IWbemStatusCodeTextVtbl status_code_vtbl = +{ + status_code_QueryInterface, + status_code_AddRef, + status_code_Release, + status_code_GetErrorCodeText, + status_code_GetFacilityCodeText +}; + +HRESULT WbemStatusCodeText_create( LPVOID *ppObj ) +{ + status_code *sc; + + TRACE("(%p)\n", ppObj); + + if (!(sc = heap_alloc( sizeof(*sc) ))) return E_OUTOFMEMORY; + + sc->IWbemStatusCodeText_iface.lpVtbl = &status_code_vtbl; + sc->refs = 1; + + *ppObj = &sc->IWbemStatusCodeText_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} diff --git a/reactos/dll/win32/wmiutils/wmiutils.rc b/reactos/dll/win32/wmiutils/wmiutils.rc new file mode 100644 index 00000000000..46ae13bcaa2 --- /dev/null +++ b/reactos/dll/win32/wmiutils/wmiutils.rc @@ -0,0 +1,2 @@ +/* @makedep: wmiutils_classes.rgs */ +1 WINE_REGISTRY wmiutils_classes.rgs diff --git a/reactos/dll/win32/wmiutils/wmiutils.spec b/reactos/dll/win32/wmiutils/wmiutils.spec new file mode 100644 index 00000000000..b16365d0c9f --- /dev/null +++ b/reactos/dll/win32/wmiutils/wmiutils.spec @@ -0,0 +1,4 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/reactos/dll/win32/wmiutils/wmiutils_classes.idl b/reactos/dll/win32/wmiutils/wmiutils_classes.idl new file mode 100644 index 00000000000..80b46d5952f --- /dev/null +++ b/reactos/dll/win32/wmiutils/wmiutils_classes.idl @@ -0,0 +1,33 @@ +/* + * COM Classes for wmiutils + * + * Copyright 2010 Alexandre Julliard + * + * 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 + */ + +#pragma makedep register + +[ + threading(both), + uuid(cf4cc405-e2c5-4ddd-b3ce-5e7582d8c9fa) +] +coclass WbemDefPath { interface IWbemPath; } + +[ + threading(both), + uuid(eb87e1bd-3233-11d2-aec9-00c04fb68820) +] +coclass WbemStatusCode { interface IWbemStatusCodeText; } diff --git a/reactos/dll/win32/wmiutils/wmiutils_classes.rgs b/reactos/dll/win32/wmiutils/wmiutils_classes.rgs new file mode 100644 index 00000000000..0f06db380fa --- /dev/null +++ b/reactos/dll/win32/wmiutils/wmiutils_classes.rgs @@ -0,0 +1,17 @@ +HKCR +{ + NoRemove Interface + { + } + NoRemove CLSID + { + '{CF4CC405-E2C5-4DDD-B3CE-5E7582D8C9FA}' = s 'WbemDefPath' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{EB87E1BD-3233-11D2-AEC9-00C04FB68820}' = s 'WbemStatusCode' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + } +} \ No newline at end of file diff --git a/reactos/dll/win32/wmiutils/wmiutils_private.h b/reactos/dll/win32/wmiutils/wmiutils_private.h new file mode 100644 index 00000000000..2b76f712e71 --- /dev/null +++ b/reactos/dll/win32/wmiutils/wmiutils_private.h @@ -0,0 +1,53 @@ +/* + * Copyright 2009 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 + */ + +#include "wine/unicode.h" + +HRESULT WbemPath_create(LPVOID *) DECLSPEC_HIDDEN; +HRESULT WbemStatusCodeText_create(LPVOID *) DECLSPEC_HIDDEN; + +static void *heap_alloc( size_t len ) __WINE_ALLOC_SIZE(1); +static inline void *heap_alloc( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), 0, len ); +} + +static void *heap_alloc_zero( size_t len ) __WINE_ALLOC_SIZE(1); +static inline void *heap_alloc_zero( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ); +} + +static void *heap_realloc( void *mem, size_t len ) __WINE_ALLOC_SIZE(2); +static inline void *heap_realloc( void *mem, size_t len ) +{ + return HeapReAlloc( GetProcessHeap(), 0, mem, len ); +} + +static inline BOOL heap_free( void *mem ) +{ + return HeapFree( GetProcessHeap(), 0, mem ); +} + +static inline WCHAR *strdupW( const WCHAR *src ) +{ + WCHAR *dst; + if (!src) return NULL; + if ((dst = heap_alloc( (strlenW( src ) + 1) * sizeof(WCHAR) ))) strcpyW( dst, src ); + return dst; +} diff --git a/reactos/include/psdk/CMakeLists.txt b/reactos/include/psdk/CMakeLists.txt index 6c915b08f72..d9c88dd9a8e 100644 --- a/reactos/include/psdk/CMakeLists.txt +++ b/reactos/include/psdk/CMakeLists.txt @@ -121,6 +121,7 @@ list(APPEND SOURCE wincodec.idl wincodecsdk.idl winsxs.idl + wmiutils.idl wtypes.idl wuapi.idl xmldom.idl diff --git a/reactos/include/psdk/wmiutils.idl b/reactos/include/psdk/wmiutils.idl new file mode 100644 index 00000000000..fa790c83460 --- /dev/null +++ b/reactos/include/psdk/wmiutils.idl @@ -0,0 +1,236 @@ +/* + * 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 + */ + +import "oaidl.idl"; + +interface IWbemPath; +interface IWbemPathKeyList; + +typedef [v1_enum] enum tag_WBEM_PATH_STATUS_FLAG +{ + WBEMPATH_INFO_ANON_LOCAL_MACHINE = 0x1, + WBEMPATH_INFO_HAS_MACHINE_NAME = 0x2, + WBEMPATH_INFO_IS_CLASS_REF = 0x4, + WBEMPATH_INFO_IS_INST_REF = 0x8, + WBEMPATH_INFO_HAS_SUBSCOPES = 0x10, + WBEMPATH_INFO_IS_COMPOUND = 0x20, + WBEMPATH_INFO_HAS_V2_REF_PATHS = 0x40, + WBEMPATH_INFO_HAS_IMPLIED_KEY = 0x80, + WBEMPATH_INFO_CONTAINS_SINGLETON = 0x100, + WBEMPATH_INFO_V1_COMPLIANT = 0x200, + WBEMPATH_INFO_V2_COMPLIANT = 0x400, + WBEMPATH_INFO_CIM_COMPLIANT = 0x800, + WBEMPATH_INFO_IS_SINGLETON = 0x1000, + WBEMPATH_INFO_IS_PARENT = 0x2000, + WBEMPATH_INFO_SERVER_NAMESPACE_ONLY = 0x4000, + WBEMPATH_INFO_NATIVE_PATH = 0x8000, + WBEMPATH_INFO_WMI_PATH = 0x10000, + WBEMPATH_INFO_PATH_HAD_SERVER = 0x20000 +} tag_WBEM_PATH_STATUS_FLAG; + +typedef [v1_enum] enum tag_WBEM_PATH_CREATE_FLAG +{ + WBEMPATH_CREATE_ACCEPT_RELATIVE = 0x1, + WBEMPATH_CREATE_ACCEPT_ABSOLUTE = 0x2, + WBEMPATH_CREATE_ACCEPT_ALL = 0x4, + WBEMPATH_TREAT_SINGLE_IDENT_AS_NS = 0x8 +} tag_WBEM_PATH_CREATE_FLAG; + +typedef [v1_enum] enum tag_WBEM_GET_TEXT_FLAGS +{ + WBEMPATH_COMPRESSED = 0x1, + WBEMPATH_GET_RELATIVE_ONLY = 0x2, + WBEMPATH_GET_SERVER_TOO = 0x4, + WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY = 0x8, + WBEMPATH_GET_NAMESPACE_ONLY = 0x10, + WBEMPATH_GET_ORIGINAL = 0x20 +} tag_WBEM_GET_TEXT_FLAGS; + +[ + local, + object, + uuid(9ae62877-7544-4bb0-aa26-a13824659ed6) +] +interface IWbemPathKeyList : IUnknown +{ + HRESULT GetCount( + [out] ULONG *puKeyCount); + + HRESULT SetKey( + [in,string] LPCWSTR wszName, + [in] ULONG uFlags, + [in] ULONG uCimType, + [in] LPVOID pKeyVal); + + HRESULT SetKey2( + [in,string] LPCWSTR wszName, + [in] ULONG uFlags, + [in] ULONG uCimType, + [in] VARIANT *pKeyVal); + + HRESULT GetKey( + [in] ULONG uKeyIx, + [in] ULONG uFlags, + [in,out] ULONG *puNameBufSize, + [in,out] LPWSTR pszKeyName, + [in,out] ULONG *puKeyValBufSize, + [in,out] LPVOID pKeyVal, + [out] ULONG *puApparentCimType); + + HRESULT GetKey2( + [in] ULONG uKeyIx, + [in] ULONG uFlags, + [in,out] ULONG *puNameBufSize, + [in,out] LPWSTR pszKeyName, + [in,out] VARIANT *pKeyValue, + [out] ULONG *puApparentCimType); + + HRESULT RemoveKey( + [in,string] LPCWSTR wszName, + [in] ULONG uFlags); + + HRESULT RemoveAllKeys( + [in] ULONG uFlags); + + HRESULT MakeSingleton([in] boolean bSet); + + HRESULT GetInfo( + [in] ULONG uRequestedInfo, + [out] ULONGLONG *puResponse); + + HRESULT GetText( + [in] long lFlags, + [in,out] ULONG *puBuffLength, + [in,out,string] LPWSTR pszText); +}; + +cpp_quote("#ifdef WINE_NO_UNICODE_MACROS") +cpp_quote("#undef GetClassName") +cpp_quote("#endif") + +[ + local, + object, + uuid(3bc15af2-736c-477e-9e51-238af8667dcc) +] +interface IWbemPath : IUnknown +{ + HRESULT SetText( + [in] ULONG uMode, + [in] LPCWSTR pszPath); + + HRESULT GetText( + [in] long lFlags, + [in,out] ULONG *puBuffLength, + [in,out,string] LPWSTR pszText); + + HRESULT GetInfo( + [in] ULONG uRequestedInfo, + [out] ULONGLONG *puResponse); + + HRESULT SetServer( + [in,string] LPCWSTR Name); + + HRESULT GetServer( + [in,out] ULONG *puNameBufLength, + [in,out,string] LPWSTR pName); + + HRESULT GetNamespaceCount( + [out] ULONG *puCount); + + HRESULT SetNamespaceAt( + [in] ULONG uIndex, + [in,string] LPCWSTR pszName); + + HRESULT GetNamespaceAt( + [in] ULONG uIndex, + [in,out] ULONG *puNameBufLength, + [in,out,string] LPWSTR pName); + + HRESULT RemoveNamespaceAt( + [in] ULONG uIndex); + + HRESULT RemoveAllNamespaces(); + + HRESULT GetScopeCount( + [out] ULONG *puCount); + + HRESULT SetScope( + [in] ULONG uIndex, + [in] LPWSTR pszClass); + + HRESULT SetScopeFromText( + [in] ULONG uIndex, + [in] LPWSTR pszText); + + HRESULT GetScope( + [in] ULONG uIndex, + [in,out] ULONG *puClassNameBufSize, + [in,out] LPWSTR pszClass, + [out] IWbemPathKeyList **pKeyList); + + HRESULT GetScopeAsText( + [in] ULONG uIndex, + [in,out] ULONG *puTextBufSize, + [in,out] LPWSTR pszText); + + HRESULT RemoveScope( + [in] ULONG uIndex); + + HRESULT RemoveAllScopes(); + + HRESULT SetClassName( + [in,string] LPCWSTR Name); + + HRESULT GetClassName( + [in,out] ULONG *puBuffLength, + [in,out,string] LPWSTR pszName); + + HRESULT GetKeyList( + [out] IWbemPathKeyList **pOut); + + HRESULT CreateClassPart( + [in] long lFlags, + [in,string] LPCWSTR Name); + + HRESULT DeleteClassPart( + [in] long lFlags); + + BOOL IsRelative( + [in,string] LPWSTR wszMachine, + [in,string] LPWSTR wszNamespace); + + BOOL IsRelativeOrChild( + [in,string] LPWSTR wszMachine, + [in,string] LPWSTR wszNamespace, + [in] long lFlags); + + BOOL IsLocal( + [in,string] LPCWSTR wszMachine); + + BOOL IsSameClassName( + [in,string] LPCWSTR wszClass); +}; + +[ + uuid(cf4cc405-e2c5-4ddd-b3ce-5e7582d8c9fa) +] +coclass WbemDefPath +{ + interface IWbemPath; +}; diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 0e221f766ab..66e42f5e7e1 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -222,6 +222,7 @@ reactos/dll/win32/winscard # Synced to Wine-1.7.27 reactos/dll/win32/wintrust # Synced to Wine-1.7.27 reactos/dll/win32/wldap32 # Synced to Wine-1.7.27 reactos/dll/win32/wmi # Synced to Wine-1.7.27 +reactos/dll/win32/wmiutils # Synced to Wine-1.7.27 reactos/dll/win32/wshom.ocx # Synced to Wine-1.7.27 reactos/dll/win32/wtsapi32 # Synced to Wine-1.7.27 reactos/dll/win32/wuapi # Synced to Wine-1.7.27 diff --git a/reactos/media/inf/syssetup.inf b/reactos/media/inf/syssetup.inf index 85349fc299d..d53ce494652 100644 --- a/reactos/media/inf/syssetup.inf +++ b/reactos/media/inf/syssetup.inf @@ -102,6 +102,7 @@ AddReg=Classes 11,,winhttp.dll,1 11,,wininet.dll,2 11,,wintrust.dll,1 +11,,wmiutils.dll,1 11,,wshom.ocx,1 11,,wuapi.dll,1 11,wbem,wbemdisp.dll,1 diff --git a/rostests/winetests/CMakeLists.txt b/rostests/winetests/CMakeLists.txt index deaf1095dc8..312f39361d5 100644 --- a/rostests/winetests/CMakeLists.txt +++ b/rostests/winetests/CMakeLists.txt @@ -113,6 +113,7 @@ add_subdirectory(winmm) add_subdirectory(wintrust) add_subdirectory(wlanapi) add_subdirectory(wldap32) +add_subdirectory(wmiutils) add_subdirectory(ws2_32) add_subdirectory(wscript) add_subdirectory(wshom) diff --git a/rostests/winetests/wmiutils/CMakeLists.txt b/rostests/winetests/wmiutils/CMakeLists.txt new file mode 100644 index 00000000000..38b67c73c28 --- /dev/null +++ b/rostests/winetests/wmiutils/CMakeLists.txt @@ -0,0 +1,9 @@ + +add_definitions( + -DUSE_WINE_TODOS + -D__WINESRC__) + +add_executable(wmiutils_winetest path.c testlist.c) +set_module_type(wmiutils_winetest win32cui) +add_importlibs(wmiutils_winetest ole32 msvcrt kernel32 ntdll) +add_cd_file(TARGET wmiutils_winetest DESTINATION reactos/bin FOR all) diff --git a/rostests/winetests/wmiutils/path.c b/rostests/winetests/wmiutils/path.c new file mode 100644 index 00000000000..56bebb3aed5 --- /dev/null +++ b/rostests/winetests/wmiutils/path.c @@ -0,0 +1,882 @@ +/* + * 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 +#include "windows.h" +#include "initguid.h" +#include "wmiutils.h" +#include "wbemcli.h" +#include "wine/test.h" + +static const WCHAR path1[] = {0}; +static const WCHAR path2[] = {'\\',0}; +static const WCHAR path3[] = {'\\','\\','s','e','r','v','e','r',0}; +static const WCHAR path4[] = {'\\','\\','s','e','r','v','e','r','\\',0}; +static const WCHAR path5[] = {'\\','\\','.','\\',0}; +static const WCHAR path6[] = {'/','/','.','/','r','o','o','t','/','c','i','m','v','2',0}; +static const WCHAR path7[] = + {'/','/','.','/','r','o','o','t','/','c','i','m','v','2',':','W','i','n','3','2','_', + 'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; +static const WCHAR path8[] = + {'/','r','o','o','t','/','c','i','m','v','2',':','W','i','n','3','2','_', + 'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; +static const WCHAR path9[] = + {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_', + 'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; +static const WCHAR path10[] = + {'/','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_', + 'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; +static const WCHAR path11[] = + {'/','/','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_', + 'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; +static const WCHAR path12[] = + {'r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_', + 'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; +static const WCHAR path13[] = + {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',0}; +static const WCHAR path14[] = + {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; +static const WCHAR path15[] = + {'r','o','o','t','\\','c','i','m','v','2',0}; +static const WCHAR path16[] = + {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',0}; +static const WCHAR path17[] = + {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_', + 'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=', + '"','C',':','"',0}; +static const WCHAR path18[] = + {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_', + 'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=', + '"','C',':','"',',','D','r','i','v','e','T','y','p','e','=','3',0}; +static const WCHAR path19[] = + {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_', + 'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=',0}; +static const WCHAR path20[] = + {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_', + 'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d',' ','=',' ', + '"','C',':','"',0}; + +static IWbemPath *create_path(void) +{ + HRESULT hr; + IWbemPath *path; + + hr = CoCreateInstance( &CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemPath, (void **)&path ); + if (hr != S_OK) + { + win_skip( "can't create WbemDefPath instance, skipping tests\n" ); + return NULL; + } + return path; +} + +static void test_IWbemPath_SetText(void) +{ + static const struct + { + const WCHAR *path; + ULONG mode; + HRESULT ret; + BOOL todo; + } test[] = + { + { path1, 0, WBEM_E_INVALID_PARAMETER }, + { path1, WBEMPATH_CREATE_ACCEPT_ALL, S_OK }, + { path2, 0, WBEM_E_INVALID_PARAMETER }, + { path2, WBEMPATH_CREATE_ACCEPT_ALL, S_OK }, + { path3, 0, WBEM_E_INVALID_PARAMETER }, + { path3, WBEMPATH_CREATE_ACCEPT_ALL, S_OK }, + { path4, 0, WBEM_E_INVALID_PARAMETER }, + { path4, WBEMPATH_CREATE_ACCEPT_ALL, S_OK }, + { path5, 0, WBEM_E_INVALID_PARAMETER }, + { path5, WBEMPATH_CREATE_ACCEPT_ALL, S_OK }, + { path6, 0, WBEM_E_INVALID_PARAMETER }, + { path6, WBEMPATH_CREATE_ACCEPT_ALL, S_OK }, + { path7, 0, WBEM_E_INVALID_PARAMETER }, + { path7, WBEMPATH_CREATE_ACCEPT_RELATIVE, S_OK }, + { path7, WBEMPATH_CREATE_ACCEPT_ABSOLUTE, S_OK }, + { path7, WBEMPATH_CREATE_ACCEPT_ALL, S_OK }, + { path7, WBEMPATH_TREAT_SINGLE_IDENT_AS_NS, WBEM_E_INVALID_PARAMETER, TRUE }, + { path7, WBEMPATH_TREAT_SINGLE_IDENT_AS_NS + 1, S_OK }, + { path8, WBEMPATH_CREATE_ACCEPT_RELATIVE, S_OK }, + { path8, WBEMPATH_CREATE_ACCEPT_ABSOLUTE, WBEM_E_INVALID_PARAMETER, TRUE }, + { path8, WBEMPATH_CREATE_ACCEPT_ALL, S_OK }, + { path8, WBEMPATH_TREAT_SINGLE_IDENT_AS_NS, WBEM_E_INVALID_PARAMETER, TRUE }, + { path8, WBEMPATH_TREAT_SINGLE_IDENT_AS_NS + 1, S_OK }, + { path9, WBEMPATH_CREATE_ACCEPT_ABSOLUTE, S_OK }, + { path10, WBEMPATH_CREATE_ACCEPT_ABSOLUTE, WBEM_E_INVALID_PARAMETER, TRUE }, + { path11, WBEMPATH_CREATE_ACCEPT_ABSOLUTE, S_OK }, + { path15, WBEMPATH_CREATE_ACCEPT_ALL, S_OK } + }; + IWbemPath *path; + HRESULT hr; + UINT i; + + if (!(path = create_path())) return; + + hr = IWbemPath_SetText( path, 0, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + for (i = 0; i < sizeof(test)/sizeof(test[0]); i++) + { + hr = IWbemPath_SetText( path, test[i].mode, test[i].path ); + if (test[i].todo) todo_wine ok( hr == test[i].ret, "%u got %08x\n", i, hr ); + else ok( hr == test[i].ret, "%u got %08x\n", i, hr ); + + if (test[i].ret == S_OK) + { + WCHAR buf[128]; + ULONG len; + + memset( buf, 0x55, sizeof(buf) ); + len = sizeof(buf)/sizeof(buf[0]); + hr = IWbemPath_GetText( path, WBEMPATH_GET_ORIGINAL, &len, buf ); + ok( hr == S_OK, "%u got %08x\n", i, hr ); + ok( !lstrcmpW( buf, test[i].path ), "%u unexpected path %s\n", i, wine_dbgstr_w(buf) ); + ok( len == lstrlenW( test[i].path ) + 1, "%u unexpected length %u\n", i, len ); + } + } + IWbemPath_Release( path ); +} + +static void test_IWbemPath_GetText(void) +{ + static const WCHAR serviceW[] = + {'W','i','n','3','2','_','S','e','r','v','i','c','e','.','N','a','m','e','=', + '\"','S','e','r','v','i','c','e','\"',0}; + static const WCHAR classW[] = + {'W','i','n','3','2','_','C','l','a','s','s',0}; + static const WCHAR expected1W[] = + {'r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_', + 'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=', + '"','C',':','"',0}; + static const WCHAR expected2W[] = + {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k','.', + 'D','e','v','i','c','e','I','d','=','"','C',':','"',0}; + static const WCHAR expected3W[] = + {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',0}; + WCHAR buf[128]; + ULONG len, count; + IWbemPath *path; + HRESULT hr; + + if (!(path = create_path())) return; + + hr = IWbemPath_GetText( path, 0, NULL, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + len = sizeof(buf)/sizeof(buf[0]); + hr = IWbemPath_GetText( path, 0, &len, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + ok( len == sizeof(buf)/sizeof(buf[0]), "unexpected length %u\n", len ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, 0, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !buf[0], "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == 1, "unexpected length %u\n", len ); + + hr = IWbemPath_GetText( path, WBEMPATH_GET_ORIGINAL, NULL, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + len = sizeof(buf)/sizeof(buf[0]); + hr = IWbemPath_GetText( path, WBEMPATH_GET_ORIGINAL, &len, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + ok( len == sizeof(buf)/sizeof(buf[0]), "unexpected length %u\n", len ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_ORIGINAL, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !buf[0], "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == 1, "unexpected length %u\n", len ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + todo_wine ok( !buf[0], "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + todo_wine ok( len == 1, "unexpected length %u\n", len ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path8 ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = IWbemPath_GetNamespaceCount( path, &count ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, path9 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( path9 ) + 1, "unexpected length %u\n", len ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, path13 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( path13 ) + 1, "unexpected length %u\n", len ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, path14 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( path14 ) + 1, "unexpected length %u\n", len ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_NAMESPACE_ONLY, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, path15 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( path15 ) + 1, "unexpected length %u\n", len ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, 0, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, path12 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( path12 ) + 1, "unexpected length %u\n", len ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = IWbemPath_GetNamespaceCount( path, &count ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path6 ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = IWbemPath_GetNamespaceCount( path, &count ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + + len = 0; + hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( len == lstrlenW( path16 ) + 1, "unexpected length %u\n", len ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, path16 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( path16 ) + 1, "unexpected length %u\n", len ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 ); + ok( hr == S_OK, "got %08x\n", hr ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, path17 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( path17 ) + 1, "unexpected length %u\n", len ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, 0, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, expected1W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( expected1W ) + 1, "unexpected length %u\n", len ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, expected2W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( expected2W ) + 1, "unexpected length %u\n", len ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path15 ); + ok( hr == S_OK, "got %08x\n", hr ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, expected3W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( expected3W ) + 1, "unexpected length %u\n", len ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path18 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path19 ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path20 ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + IWbemPath_Release( path ); + if (!(path = create_path())) return; + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, serviceW ); + ok( hr == S_OK, "got %08x\n", hr ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, serviceW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( serviceW ) + 1, "unexpected length %u\n", len ); + + IWbemPath_Release( path ); + if (!(path = create_path())) return; + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, classW ); + ok( hr == S_OK, "got %08x\n", hr ); + + len = sizeof(buf)/sizeof(buf[0]); + memset( buf, 0x55, sizeof(buf) ); + hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, classW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( classW ) + 1, "unexpected length %u\n", len ); + + IWbemPath_Release( path ); +} + +static void test_IWbemPath_GetClassName(void) +{ + static const WCHAR classW[] = {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k',0}; + IWbemPath *path; + HRESULT hr; + WCHAR buf[32]; + ULONG len; + + if (!(path = create_path())) return; + + hr = IWbemPath_GetClassName( path, NULL, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + len = 0; + hr = IWbemPath_GetClassName( path, &len, NULL ); + ok( hr == WBEM_E_INVALID_OBJECT_PATH, "got %08x\n", hr ); + + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetClassName( path, &len, buf ); + ok( hr == WBEM_E_INVALID_OBJECT_PATH, "got %08x\n", hr ); + + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetClassName( path, &len, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 ); + ok( hr == S_OK, "got %08x\n", hr ); + + len = 0; + hr = IWbemPath_GetClassName( path, &len, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetClassName( path, &len, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetClassName( path, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, classW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( classW ) + 1, "unexpected length %u\n", len ); + + IWbemPath_Release( path ); +} + +static void test_IWbemPath_SetClassName(void) +{ + static const WCHAR classW[] = {'c','l','a','s','s',0}; + static const WCHAR emptyW[] = {0}; + IWbemPath *path; + WCHAR buf[16]; + ULONG len; + ULONGLONG flags; + HRESULT hr; + + if (!(path = create_path())) return; + + hr = IWbemPath_SetClassName( path, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + hr = IWbemPath_SetClassName( path, emptyW ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = IWbemPath_SetClassName( path, classW ); + ok( hr == S_OK, "got %08x\n", hr ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetClassName( path, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, classW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + + flags = 0; + hr = IWbemPath_GetInfo( path, 0, &flags ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flags == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_IS_CLASS_REF | + WBEMPATH_INFO_HAS_SUBSCOPES | WBEMPATH_INFO_V2_COMPLIANT | + WBEMPATH_INFO_CIM_COMPLIANT), + "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags ); + + IWbemPath_Release( path ); +} + +static void test_IWbemPath_GetServer(void) +{ + static const WCHAR dotW[] = {'.',0}; + IWbemPath *path; + HRESULT hr; + WCHAR buf[32]; + ULONG len; + + if (!(path = create_path())) return; + + hr = IWbemPath_GetServer( path, NULL, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + len = 0; + hr = IWbemPath_GetServer( path, &len, NULL ); + ok( hr == WBEM_E_NOT_AVAILABLE, "got %08x\n", hr ); + + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetServer( path, &len, buf ); + ok( hr == WBEM_E_NOT_AVAILABLE, "got %08x\n", hr ); + + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetServer( path, &len, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 ); + ok( hr == S_OK, "got %08x\n", hr ); + + len = 0; + hr = IWbemPath_GetServer( path, &len, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetServer( path, &len, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetServer( path, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, dotW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( dotW ) + 1, "unexpected length %u\n", len ); + + IWbemPath_Release( path ); +} + +static void test_IWbemPath_GetInfo(void) +{ + IWbemPath *path; + HRESULT hr; + ULONGLONG resp; + + if (!(path = create_path())) return; + + hr = IWbemPath_GetInfo( path, 0, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + hr = IWbemPath_GetInfo( path, 1, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + resp = 0xdeadbeef; + hr = IWbemPath_GetInfo( path, 0, &resp ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( resp == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_SERVER_NAMESPACE_ONLY), + "got %lx%08lx\n", (unsigned long)(resp >> 32), (unsigned long)resp ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = IWbemPath_GetInfo( path, 0, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + hr = IWbemPath_GetInfo( path, 1, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + resp = 0xdeadbeef; + hr = IWbemPath_GetInfo( path, 0, &resp ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( resp == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_IS_INST_REF | + WBEMPATH_INFO_HAS_SUBSCOPES | WBEMPATH_INFO_V2_COMPLIANT | + WBEMPATH_INFO_CIM_COMPLIANT | WBEMPATH_INFO_PATH_HAD_SERVER), + "got %lx%08lx\n", (unsigned long)(resp >> 32), (unsigned long)resp ); + + IWbemPath_Release( path ); + if (!(path = create_path())) return; + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path12 ); + ok( hr == S_OK, "got %08x\n", hr ); + + resp = 0xdeadbeef; + hr = IWbemPath_GetInfo( path, 0, &resp ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( resp == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_IS_CLASS_REF | + WBEMPATH_INFO_HAS_SUBSCOPES | WBEMPATH_INFO_V2_COMPLIANT | + WBEMPATH_INFO_CIM_COMPLIANT), + "got %lx%08lx\n", (unsigned long)(resp >> 32), (unsigned long)resp ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + resp = 0xdeadbeef; + hr = IWbemPath_GetInfo( path, 0, &resp ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( resp == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_SERVER_NAMESPACE_ONLY), + "got %lx%08lx\n", (unsigned long)(resp >> 32), (unsigned long)resp ); + + IWbemPath_Release( path ); +} + +static void test_IWbemPath_SetServer(void) +{ + static const WCHAR serverW[] = {'s','e','r','v','e','r',0}; + static const WCHAR emptyW[] = {0}; + IWbemPath *path; + WCHAR buf[16]; + ULONG len; + ULONGLONG flags; + HRESULT hr; + + if (!(path = create_path())) return; + + hr = IWbemPath_SetServer( path, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetServer( path, &len, buf ); + ok( hr == WBEM_E_NOT_AVAILABLE, "got %08x\n", hr ); + + hr = IWbemPath_SetServer( path, emptyW ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = IWbemPath_SetServer( path, serverW ); + ok( hr == S_OK, "got %08x\n", hr ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetServer( path, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, serverW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + + flags = 0; + hr = IWbemPath_GetInfo( path, 0, &flags ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flags == (WBEMPATH_INFO_HAS_MACHINE_NAME | WBEMPATH_INFO_V1_COMPLIANT | + WBEMPATH_INFO_V2_COMPLIANT | WBEMPATH_INFO_CIM_COMPLIANT | + WBEMPATH_INFO_SERVER_NAMESPACE_ONLY | WBEMPATH_INFO_PATH_HAD_SERVER), + "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags ); + + hr = IWbemPath_SetServer( path, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetServer( path, &len, buf ); + ok( hr == WBEM_E_NOT_AVAILABLE, "got %08x\n", hr ); + + flags = 0; + hr = IWbemPath_GetInfo( path, 0, &flags ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flags == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_SERVER_NAMESPACE_ONLY), + "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags ); + + IWbemPath_Release( path ); +} + +static void test_IWbemPath_GetNamespaceAt(void) +{ + static const WCHAR rootW[] = {'r','o','o','t',0}; + static const WCHAR cimv2W[] = {'c','i','m','v','2',0}; + IWbemPath *path; + HRESULT hr; + WCHAR buf[32]; + ULONG len; + + if (!(path = create_path())) return; + + hr = IWbemPath_GetNamespaceAt( path, 0, NULL, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + len = 0; + hr = IWbemPath_GetNamespaceAt( path, 0, &len, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetNamespaceAt( path, 0, &len, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 ); + ok( hr == S_OK, "got %08x\n", hr ); + + len = 0; + hr = IWbemPath_GetNamespaceAt( path, 2, &len, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetNamespaceAt( path, 0, &len, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, rootW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( rootW ) + 1, "unexpected length %u\n", len ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetNamespaceAt( path, 1, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, cimv2W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( cimv2W ) + 1, "unexpected length %u\n", len ); + + IWbemPath_Release( path ); +} + +static void test_IWbemPath_RemoveAllNamespaces(void) +{ + static const ULONGLONG expected_flags = + WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_IS_INST_REF | + WBEMPATH_INFO_HAS_SUBSCOPES | WBEMPATH_INFO_V2_COMPLIANT | + WBEMPATH_INFO_CIM_COMPLIANT | WBEMPATH_INFO_PATH_HAD_SERVER; + IWbemPath *path; + WCHAR buf[16]; + ULONG len; + ULONGLONG flags; + HRESULT hr; + + if (!(path = create_path())) return; + + hr = IWbemPath_RemoveAllNamespaces( path ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 ); + ok( hr == S_OK, "got %08x\n", hr ); + + flags = 0; + hr = IWbemPath_GetInfo( path, 0, &flags ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flags == expected_flags, + "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags ); + + hr = IWbemPath_RemoveAllNamespaces( path ); + ok( hr == S_OK, "got %08x\n", hr ); + + flags = 0; + hr = IWbemPath_GetInfo( path, 0, &flags ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flags == expected_flags, + "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + IWbemPath_Release( path ); +} + +static void test_IWbemPath_RemoveNamespaceAt(void) +{ + static const ULONGLONG expected_flags = + WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_IS_INST_REF | + WBEMPATH_INFO_HAS_SUBSCOPES | WBEMPATH_INFO_V2_COMPLIANT | + WBEMPATH_INFO_CIM_COMPLIANT | WBEMPATH_INFO_PATH_HAD_SERVER; + static const WCHAR cimv2W[] = {'c','i','m','v','2',0}; + IWbemPath *path; + WCHAR buf[16]; + ULONG len, count; + ULONGLONG flags; + HRESULT hr; + + if (!(path = create_path())) return; + + hr = IWbemPath_RemoveNamespaceAt( path, 0 ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 ); + ok( hr == S_OK, "got %08x\n", hr ); + + flags = 0; + hr = IWbemPath_GetInfo( path, 0, &flags ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flags == expected_flags, + "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags ); + + count = 0xdeadbeef; + hr = IWbemPath_GetNamespaceCount( path, &count ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + + hr = IWbemPath_RemoveNamespaceAt( path, 0 ); + ok( hr == S_OK, "got %08x\n", hr ); + + flags = 0; + hr = IWbemPath_GetInfo( path, 0, &flags ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flags == expected_flags, + "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags ); + + count = 0xdeadbeef; + hr = IWbemPath_GetNamespaceCount( path, &count ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 1, "got %u\n", count ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, cimv2W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( cimv2W ) + 1, "unexpected length %u\n", len ); + + hr = IWbemPath_RemoveNamespaceAt( path, 0 ); + ok( hr == S_OK, "got %08x\n", hr ); + + flags = 0; + hr = IWbemPath_GetInfo( path, 0, &flags ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flags == expected_flags, + "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags ); + + count = 0xdeadbeef; + hr = IWbemPath_GetNamespaceCount( path, &count ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %u\n", count ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + IWbemPath_Release( path ); +} + +static void test_IWbemPath_SetNamespaceAt(void) +{ + static const ULONGLONG expected_flags = + WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_V1_COMPLIANT | + WBEMPATH_INFO_V2_COMPLIANT | WBEMPATH_INFO_CIM_COMPLIANT | + WBEMPATH_INFO_SERVER_NAMESPACE_ONLY; + static const WCHAR rootW[] = {'r','o','o','t',0}; + static const WCHAR cimv2W[] = {'c','i','m','v','2',0}; + IWbemPath *path; + WCHAR buf[16]; + ULONG len, count; + ULONGLONG flags; + HRESULT hr; + + if (!(path = create_path())) return; + + hr = IWbemPath_SetNamespaceAt( path, 0, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + hr = IWbemPath_SetNamespaceAt( path, 1, cimv2W ); + ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr ); + + hr = IWbemPath_SetNamespaceAt( path, 0, cimv2W ); + ok( hr == S_OK, "got %08x\n", hr ); + + count = 0xdeadbeef; + hr = IWbemPath_GetNamespaceCount( path, &count ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 1, "got %u\n", count ); + + flags = 0; + hr = IWbemPath_GetInfo( path, 0, &flags ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flags == expected_flags, + "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, cimv2W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( cimv2W ) + 1, "unexpected length %u\n", len ); + + hr = IWbemPath_SetNamespaceAt( path, 0, rootW ); + ok( hr == S_OK, "got %08x\n", hr ); + + flags = 0; + hr = IWbemPath_GetInfo( path, 0, &flags ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( flags == expected_flags, + "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags ); + + count = 0xdeadbeef; + hr = IWbemPath_GetNamespaceCount( path, &count ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( count == 2, "got %u\n", count ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, rootW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( rootW ) + 1, "unexpected length %u\n", len ); + + buf[0] = 0; + len = sizeof(buf) / sizeof(buf[0]); + hr = IWbemPath_GetNamespaceAt( path, 1, &len, buf ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !lstrcmpW( buf, cimv2W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) ); + ok( len == lstrlenW( cimv2W ) + 1, "unexpected length %u\n", len ); + + IWbemPath_Release( path ); +} + +START_TEST (path) +{ + CoInitialize( NULL ); + + test_IWbemPath_SetText(); + test_IWbemPath_GetText(); + test_IWbemPath_GetClassName(); + test_IWbemPath_SetClassName(); + test_IWbemPath_GetServer(); + test_IWbemPath_GetInfo(); + test_IWbemPath_SetServer(); + test_IWbemPath_GetNamespaceAt(); + test_IWbemPath_RemoveAllNamespaces(); + test_IWbemPath_RemoveNamespaceAt(); + test_IWbemPath_SetNamespaceAt(); + + CoUninitialize(); +} diff --git a/rostests/winetests/wmiutils/testlist.c b/rostests/winetests/wmiutils/testlist.c new file mode 100644 index 00000000000..fd8244b97ca --- /dev/null +++ b/rostests/winetests/wmiutils/testlist.c @@ -0,0 +1,15 @@ +/* Automatically generated by make depend; DO NOT EDIT!! */ + +#define WIN32_LEAN_AND_MEAN +#include + +#define STANDALONE +#include "wine/test.h" + +extern void func_path(void); + +const struct test winetest_testlist[] = +{ + { "path", func_path }, + { 0, 0 } +};