2 * Copyright 2012 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wine/debug.h"
31 #include "wmiutils_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(wmiutils);
37 IWbemPath IWbemPath_iface;
50 static void init_path( struct path *path )
56 path->namespaces = NULL;
57 path->len_namespaces = NULL;
58 path->num_namespaces = 0;
63 static void clear_path( struct path *path )
65 heap_free( path->text );
66 heap_free( path->server );
67 heap_free( path->namespaces );
68 heap_free( path->len_namespaces );
69 heap_free( path->class );
73 static inline struct path *impl_from_IWbemPath( IWbemPath *iface )
75 return CONTAINING_RECORD(iface, struct path, IWbemPath_iface);
78 static ULONG WINAPI path_AddRef(
81 struct path *path = impl_from_IWbemPath( iface );
82 return InterlockedIncrement( &path->refs );
85 static ULONG WINAPI path_Release(
88 struct path *path = impl_from_IWbemPath( iface );
89 LONG refs = InterlockedDecrement( &path->refs );
92 TRACE("destroying %p\n", path);
99 static HRESULT WINAPI path_QueryInterface(
104 struct path *path = impl_from_IWbemPath( iface );
106 TRACE("%p, %s, %p\n", path, debugstr_guid( riid ), ppvObject );
108 if ( IsEqualGUID( riid, &IID_IWbemPath ) ||
109 IsEqualGUID( riid, &IID_IUnknown ) )
115 FIXME("interface %s not implemented\n", debugstr_guid(riid));
116 return E_NOINTERFACE;
118 IWbemPath_AddRef( iface );
122 static HRESULT parse_text( struct path *path, ULONG mode, const WCHAR *text )
124 HRESULT hr = E_OUTOFMEMORY;
129 if ((p[0] == '\\' && p[1] == '\\') || (p[0] == '/' && p[1] == '/'))
133 while (*q && *q != '\\' && *q != '/') q++;
135 if (!(path->server = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
136 memcpy( path->server, p, len * sizeof(WCHAR) );
137 path->server[len] = 0;
138 path->len_server = len;
141 while (*q && *q != ':')
143 if (*q == '\\' || *q == '/') path->num_namespaces++;
146 if (path->num_namespaces)
148 if (!(path->namespaces = heap_alloc( path->num_namespaces * sizeof(WCHAR *) ))) goto done;
149 if (!(path->len_namespaces = heap_alloc( path->num_namespaces * sizeof(int) ))) goto done;
153 while (*q && *q != ':')
155 if (*q == '\\' || *q == '/')
158 while (*p && *p != '\\' && *p != '/' && *p != ':') p++;
160 if (!(path->namespaces[i] = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
161 memcpy( path->namespaces[i], q + 1, len * sizeof(WCHAR) );
162 path->namespaces[i][len] = 0;
163 path->len_namespaces[i] = len;
171 while (*q && *q != '.') q++;
173 if (!(path->class = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
174 memcpy( path->class, p, len * sizeof(WCHAR) );
175 path->class[len] = 0;
176 path->len_class = len;
178 if (*q == '.') FIXME("handle key list\n");
182 if (hr != S_OK) clear_path( path );
186 static HRESULT WINAPI path_SetText(
191 struct path *path = impl_from_IWbemPath( iface );
195 TRACE("%p, %u, %s\n", iface, uMode, debugstr_w(pszPath));
197 if (!uMode || !pszPath) return WBEM_E_INVALID_PARAMETER;
200 if ((hr = parse_text( path, uMode, pszPath )) != S_OK) return hr;
202 len = strlenW( pszPath );
203 if (!(path->text = heap_alloc( (len + 1) * sizeof(WCHAR) )))
206 return E_OUTOFMEMORY;
208 strcpyW( path->text, pszPath );
209 path->len_text = len;
213 static WCHAR *build_namespace( struct path *path, int *len, BOOL leading_slash )
219 for (i = 0; i < path->num_namespaces; i++)
221 if (i > 0 || leading_slash) *len += 1;
222 *len += path->len_namespaces[i];
224 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL;
225 for (i = 0; i < path->num_namespaces; i++)
227 if (i > 0 || leading_slash) *p++ = '\\';
228 memcpy( p, path->namespaces[i], path->len_namespaces[i] * sizeof(WCHAR) );
229 p += path->len_namespaces[i];
235 static WCHAR *build_server( struct path *path, int *len )
240 if (path->len_server) *len += 2 + path->len_server;
242 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL;
243 if (path->len_server)
246 strcpyW( p + 2, path->server );
256 static WCHAR *build_path( struct path *path, LONG flags, int *len )
263 WCHAR *ret, *namespace = build_namespace( path, &len_namespace, FALSE );
265 if (!namespace) return NULL;
267 *len = len_namespace;
268 if (path->len_class) *len += 1 + path->len_class;
269 if (!(ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
271 heap_free( namespace );
274 strcpyW( ret, namespace );
277 ret[len_namespace] = ':';
278 strcpyW( ret + len_namespace + 1, path->class );
280 heap_free( namespace );
284 case WBEMPATH_GET_RELATIVE_ONLY:
285 if (!path->len_class)
290 *len = path->len_class;
291 return strdupW( path->class );
293 case WBEMPATH_GET_SERVER_TOO:
295 int len_namespace, len_server;
296 WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace, TRUE );
297 WCHAR *server = build_server( path, &len_server );
299 if (!namespace || !server)
301 heap_free( namespace );
305 *len = len_namespace + len_server;
306 if (path->len_class) *len += 1 + path->len_class;
307 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
309 heap_free( namespace );
313 strcpyW( p, server );
315 strcpyW( p, namespace );
320 strcpyW( p + 1, path->class );
322 heap_free( namespace );
326 case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY:
328 int len_namespace, len_server;
329 WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace, TRUE );
330 WCHAR *server = build_server( path, &len_server );
332 if (!namespace || !server)
334 heap_free( namespace );
338 *len = len_namespace + len_server;
339 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
341 heap_free( namespace );
345 strcpyW( p, server );
347 strcpyW( p, namespace );
348 heap_free( namespace );
352 case WBEMPATH_GET_NAMESPACE_ONLY:
353 return build_namespace( path, len, FALSE );
355 case WBEMPATH_GET_ORIGINAL:
361 *len = path->len_text;
362 return strdupW( path->text );
365 ERR("unhandled flags 0x%x\n", flags);
370 static HRESULT WINAPI path_GetText(
373 ULONG *puBufferLength,
376 struct path *path = impl_from_IWbemPath( iface );
380 TRACE("%p, 0x%x, %p, %p\n", iface, lFlags, puBufferLength, pszText);
382 if (!puBufferLength) return WBEM_E_INVALID_PARAMETER;
384 str = build_path( path, lFlags, &len );
386 if (*puBufferLength < len + 1)
388 *puBufferLength = len + 1;
394 return WBEM_E_INVALID_PARAMETER;
396 if (str) strcpyW( pszText, str );
398 *puBufferLength = len + 1;
400 TRACE("<-- %s\n", debugstr_w(pszText));
405 static HRESULT WINAPI path_GetInfo(
407 ULONG uRequestedInfo,
408 ULONGLONG *puResponse)
410 FIXME("%p, %d, %p\n", iface, uRequestedInfo, puResponse);
414 static HRESULT WINAPI path_SetServer(
418 FIXME("%p, %s\n", iface, debugstr_w(Name));
422 static HRESULT WINAPI path_GetServer(
424 ULONG *puNameBufLength,
427 FIXME("%p, %p, %p\n", iface, puNameBufLength, pName);
431 static HRESULT WINAPI path_GetNamespaceCount(
435 struct path *path = impl_from_IWbemPath( iface );
437 TRACE("%p, %p\n", iface, puCount);
439 if (!puCount) return WBEM_E_INVALID_PARAMETER;
440 *puCount = path->num_namespaces;
444 static HRESULT WINAPI path_SetNamespaceAt(
449 FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszName));
453 static HRESULT WINAPI path_GetNamespaceAt(
456 ULONG *puNameBufLength,
459 FIXME("%p, %u, %p, %p\n", iface, uIndex, puNameBufLength, pName);
463 static HRESULT WINAPI path_RemoveNamespaceAt(
467 FIXME("%p, %u\n", iface, uIndex);
471 static HRESULT WINAPI path_RemoveAllNamespaces(
474 FIXME("%p\n", iface);
478 static HRESULT WINAPI path_GetScopeCount(
482 FIXME("%p, %p\n", iface, puCount);
486 static HRESULT WINAPI path_SetScope(
491 FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszClass));
495 static HRESULT WINAPI path_SetScopeFromText(
500 FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszText));
504 static HRESULT WINAPI path_GetScope(
507 ULONG *puClassNameBufSize,
509 IWbemPathKeyList **pKeyList)
511 FIXME("%p, %u, %p, %p, %p\n", iface, uIndex, puClassNameBufSize, pszClass, pKeyList);
515 static HRESULT WINAPI path_GetScopeAsText(
518 ULONG *puTextBufSize,
521 FIXME("%p, %u, %p, %p\n", iface, uIndex, puTextBufSize, pszText);
525 static HRESULT WINAPI path_RemoveScope(
529 FIXME("%p, %u\n", iface, uIndex);
533 static HRESULT WINAPI path_RemoveAllScopes(
536 FIXME("%p\n", iface);
540 static HRESULT WINAPI path_SetClassName(
544 FIXME("%p, %s\n", iface, debugstr_w(Name));
548 static HRESULT WINAPI path_GetClassName(
553 struct path *path = impl_from_IWbemPath( iface );
555 TRACE("%p, %p, %p\n", iface, len, name);
557 if (!len || (*len && !name)) return WBEM_E_INVALID_PARAMETER;
558 if (!path->class) return WBEM_E_INVALID_OBJECT_PATH;
559 if (*len > path->len_class) strcpyW( name, path->class );
560 *len = path->len_class + 1;
564 static HRESULT WINAPI path_GetKeyList(
566 IWbemPathKeyList **pOut)
568 FIXME("%p, %p\n", iface, pOut);
572 static HRESULT WINAPI path_CreateClassPart(
577 FIXME("%p, 0x%x, %s\n", iface, lFlags, debugstr_w(Name));
581 static HRESULT WINAPI path_DeleteClassPart(
585 FIXME("%p, 0x%x\n", iface, lFlags);
589 static BOOL WINAPI path_IsRelative(
594 FIXME("%p, %s, %s\n", iface, debugstr_w(wszMachine), debugstr_w(wszNamespace));
598 static BOOL WINAPI path_IsRelativeOrChild(
604 FIXME("%p, %s, %s, 0x%x\n", iface, debugstr_w(wszMachine), debugstr_w(wszNamespace), lFlags);
608 static BOOL WINAPI path_IsLocal(
612 FIXME("%p, %s\n", iface, debugstr_w(wszMachine));
616 static BOOL WINAPI path_IsSameClassName(
620 FIXME("%p, %s\n", iface, debugstr_w(wszClass));
624 static const struct IWbemPathVtbl path_vtbl =
634 path_GetNamespaceCount,
637 path_RemoveNamespaceAt,
638 path_RemoveAllNamespaces,
641 path_SetScopeFromText,
645 path_RemoveAllScopes,
649 path_CreateClassPart,
650 path_DeleteClassPart,
652 path_IsRelativeOrChild,
657 HRESULT WbemPath_create( IUnknown *pUnkOuter, LPVOID *ppObj )
661 TRACE("%p, %p\n", pUnkOuter, ppObj);
663 if (!(path = heap_alloc( sizeof(*path) ))) return E_OUTOFMEMORY;
665 path->IWbemPath_iface.lpVtbl = &path_vtbl;
669 *ppObj = &path->IWbemPath_iface;
671 TRACE("returning iface %p\n", *ppObj);