[4/7] wmiutils: Parse the path passed to IWbemPath::SetText.
Hans Leidekker
hans at codeweavers.com
Wed Jan 2 06:34:03 CST 2013
---
dlls/wmiutils/path.c | 124 +++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 112 insertions(+), 12 deletions(-)
diff --git a/dlls/wmiutils/path.c b/dlls/wmiutils/path.c
index e32c9b6..0d52544 100644
--- a/dlls/wmiutils/path.c
+++ b/dlls/wmiutils/path.c
@@ -36,11 +36,41 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmiutils);
struct path
{
IWbemPath IWbemPath_iface;
- LONG refs;
- WCHAR *text;
- int len;
+ LONG refs;
+ WCHAR *text;
+ int len_text;
+ WCHAR *server;
+ int len_server;
+ WCHAR **namespaces;
+ int *len_namespaces;
+ int num_namespaces;
+ WCHAR *class;
+ int len_class;
};
+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;
+}
+
+static void clear_path( struct path *path )
+{
+ heap_free( path->text );
+ heap_free( path->server );
+ heap_free( path->namespaces );
+ heap_free( path->len_namespaces );
+ heap_free( path->class );
+ init_path( path );
+}
+
static inline struct path *impl_from_IWbemPath( IWbemPath *iface )
{
return CONTAINING_RECORD(iface, struct path, IWbemPath_iface);
@@ -61,7 +91,7 @@ static ULONG WINAPI path_Release(
if (!refs)
{
TRACE("destroying %p\n", path);
- heap_free( path->text );
+ clear_path( path );
heap_free( path );
}
return refs;
@@ -90,25 +120,94 @@ static HRESULT WINAPI path_QueryInterface(
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;
+ }
+ p = 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;
+ 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 == '.') FIXME("handle key list\n");
+ hr = S_OK;
+
+done:
+ if (hr != S_OK) clear_path( path );
+ return hr;
+}
+
static HRESULT WINAPI path_SetText(
IWbemPath *iface,
ULONG uMode,
LPCWSTR pszPath)
{
struct path *path = impl_from_IWbemPath( iface );
+ HRESULT hr;
int len;
TRACE("%p, %u, %s\n", iface, uMode, debugstr_w(pszPath));
- if (!pszPath) return WBEM_E_INVALID_PARAMETER;
+ if (!uMode || !pszPath) return WBEM_E_INVALID_PARAMETER;
- if (uMode) FIXME("igoring mode %u\n", uMode);
+ clear_path( path );
+ if ((hr = parse_text( path, uMode, pszPath )) != S_OK) return hr;
len = strlenW( pszPath );
- if (!(path->text = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
-
+ if (!(path->text = heap_alloc( (len + 1) * sizeof(WCHAR) )))
+ {
+ clear_path( path );
+ return E_OUTOFMEMORY;
+ }
strcpyW( path->text, pszPath );
- path->len = len;
+ path->len_text = len;
return S_OK;
}
@@ -129,13 +228,13 @@ static HRESULT WINAPI path_GetText(
FIXME("flags 0x%x not supported\n", lFlags);
return WBEM_E_INVALID_PARAMETER;
}
- if (*puBufferLength < path->len + 1)
+ if (*puBufferLength < path->len_text + 1)
{
- *puBufferLength = path->len + 1;
+ *puBufferLength = path->len_text + 1;
return S_OK;
}
if (pszText) strcpyW( pszText, path->text );
- *puBufferLength = path->len + 1;
+ *puBufferLength = path->len_text + 1;
return S_OK;
}
@@ -389,6 +488,7 @@ HRESULT WbemPath_create( IUnknown *pUnkOuter, LPVOID *ppObj )
path->IWbemPath_iface.lpVtbl = &path_vtbl;
path->refs = 1;
+ init_path( path );
*ppObj = &path->IWbemPath_iface;
--
1.7.10.4
More information about the wine-patches
mailing list