From 0199a94329c80208bab565c56d46cd12f604e951 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Wed, 2 Jan 2013 13:34:32 +0100 Subject: [PATCH] wmiutils: Support more flags in IWbemPath::GetText. --- dlls/wmiutils/path.c | 178 +++++++++++++++++++++++++++++-- dlls/wmiutils/wmiutils_private.h | 10 ++ 2 files changed, 179 insertions(+), 9 deletions(-) diff --git a/dlls/wmiutils/path.c b/dlls/wmiutils/path.c index 0cb7170e29..a26ade1ff7 100644 --- a/dlls/wmiutils/path.c +++ b/dlls/wmiutils/path.c @@ -28,7 +28,6 @@ #include "wmiutils.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "wmiutils_private.h" WINE_DEFAULT_DEBUG_CHANNEL(wmiutils); @@ -211,6 +210,163 @@ static HRESULT WINAPI path_SetText( return S_OK; } +static WCHAR *build_namespace( struct path *path, int *len ) +{ + WCHAR *ret, *p; + int i; + + *len = 0; + for (i = 0; i < path->num_namespaces; i++) + { + if (i > 0) *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) *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->server) *len += 2 + path->len_server; + else *len += 4; + if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL; + if (path->server) + { + p[0] = p[1] = '\\'; + strcpyW( p + 2, path->server ); + } + else + { + p[0] = p[1] = p[3] = '\\'; + p[2] = '.'; + } + return ret; +} + +static WCHAR *build_path( struct path *path, LONG flags, int *len ) +{ + switch (flags) + { + case 0: + { + int len_namespace; + WCHAR *ret, *namespace = build_namespace( path, &len_namespace ); + + if (!namespace) return NULL; + + *len = len_namespace; + if (path->class) *len += 1 + path->len_class; + if (!(ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) + { + heap_free( namespace ); + return NULL; + } + strcpyW( ret, namespace ); + if (path->class) + { + ret[len_namespace] = ':'; + strcpyW( ret + len_namespace + 1, path->class ); + } + heap_free( namespace ); + return ret; + + } + case WBEMPATH_GET_RELATIVE_ONLY: + if (!path->class) + { + *len = 0; + return NULL; + } + *len = path->len_class; + return strdupW( path->class ); + + case WBEMPATH_GET_SERVER_TOO: + { + int len_namespace, len_server; + WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace ); + WCHAR *server = build_server( path, &len_server ); + + if (!namespace || !server) + { + heap_free( namespace ); + heap_free( server ); + return NULL; + } + *len = len_namespace + len_server; + if (path->class) *len += 1 + path->len_class; + 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 ); + p += len_namespace; + if (path->class) + { + *p = ':'; + strcpyW( p + 1, path->class ); + } + heap_free( namespace ); + heap_free( server ); + return ret; + } + case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY: + { + int len_namespace, len_server; + WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace ); + 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 ); + + case WBEMPATH_GET_ORIGINAL: + if (!path->text) + { + *len = 0; + 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, @@ -218,23 +374,27 @@ static HRESULT WINAPI path_GetText( LPWSTR pszText) { struct path *path = impl_from_IWbemPath( iface ); + WCHAR *str; + int len; TRACE("%p, 0x%x, %p, %p\n", iface, lFlags, puBufferLength, pszText); if (!puBufferLength || !pszText) return WBEM_E_INVALID_PARAMETER; - if (lFlags != WBEMPATH_GET_ORIGINAL) + str = build_path( path, lFlags, &len ); + + if (*puBufferLength < len + 1) { - FIXME("flags 0x%x not supported\n", lFlags); - return WBEM_E_INVALID_PARAMETER; + *puBufferLength = len + 1; + return S_OK; } - if (*puBufferLength < path->len_text + 1) + if (pszText) { - *puBufferLength = path->len_text + 1; - return S_OK; + if (str) strcpyW( pszText, str ); + else pszText[0] = 0; } - if (pszText) strcpyW( pszText, path->text ); - *puBufferLength = path->len_text + 1; + *puBufferLength = len + 1; + heap_free( str ); return S_OK; } diff --git a/dlls/wmiutils/wmiutils_private.h b/dlls/wmiutils/wmiutils_private.h index fdfca13732..9837ce8b40 100644 --- a/dlls/wmiutils/wmiutils_private.h +++ b/dlls/wmiutils/wmiutils_private.h @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "wine/unicode.h" + HRESULT WbemPath_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN; HRESULT WbemStatusCodeText_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN; @@ -29,3 +31,11 @@ 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; +} -- 2.32.0.93.g670b81a890