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;
51 static void init_path( struct path *path )
57 path->namespaces = NULL;
58 path->len_namespaces = NULL;
59 path->num_namespaces = 0;
65 static void clear_path( struct path *path )
67 heap_free( path->text );
68 heap_free( path->server );
69 heap_free( path->namespaces );
70 heap_free( path->len_namespaces );
71 heap_free( path->class );
75 static inline struct path *impl_from_IWbemPath( IWbemPath *iface )
77 return CONTAINING_RECORD(iface, struct path, IWbemPath_iface);
80 static ULONG WINAPI path_AddRef(
83 struct path *path = impl_from_IWbemPath( iface );
84 return InterlockedIncrement( &path->refs );
87 static ULONG WINAPI path_Release(
90 struct path *path = impl_from_IWbemPath( iface );
91 LONG refs = InterlockedDecrement( &path->refs );
94 TRACE("destroying %p\n", path);
101 static HRESULT WINAPI path_QueryInterface(
106 struct path *path = impl_from_IWbemPath( iface );
108 TRACE("%p, %s, %p\n", path, debugstr_guid( riid ), ppvObject );
110 if ( IsEqualGUID( riid, &IID_IWbemPath ) ||
111 IsEqualGUID( riid, &IID_IUnknown ) )
117 FIXME("interface %s not implemented\n", debugstr_guid(riid));
118 return E_NOINTERFACE;
120 IWbemPath_AddRef( iface );
124 static HRESULT parse_text( struct path *path, ULONG mode, const WCHAR *text )
126 HRESULT hr = E_OUTOFMEMORY;
131 if ((p[0] == '\\' && p[1] == '\\') || (p[0] == '/' && p[1] == '/'))
135 while (*q && *q != '\\' && *q != '/') q++;
137 if (!(path->server = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
138 memcpy( path->server, p, len * sizeof(WCHAR) );
139 path->server[len] = 0;
140 path->len_server = len;
141 path->flags |= WBEMPATH_INFO_PATH_HAD_SERVER;
144 while (*q && *q != ':')
146 if (*q == '\\' || *q == '/') path->num_namespaces++;
149 if (path->num_namespaces)
151 if (!(path->namespaces = heap_alloc( path->num_namespaces * sizeof(WCHAR *) ))) goto done;
152 if (!(path->len_namespaces = heap_alloc( path->num_namespaces * sizeof(int) ))) goto done;
156 while (*q && *q != ':')
158 if (*q == '\\' || *q == '/')
161 while (*p && *p != '\\' && *p != '/' && *p != ':') p++;
163 if (!(path->namespaces[i] = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
164 memcpy( path->namespaces[i], q + 1, len * sizeof(WCHAR) );
165 path->namespaces[i][len] = 0;
166 path->len_namespaces[i] = len;
174 while (*q && *q != '.') q++;
176 if (!(path->class = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
177 memcpy( path->class, p, len * sizeof(WCHAR) );
178 path->class[len] = 0;
179 path->len_class = len;
181 if (*q == '.') FIXME("handle key list\n");
185 if (hr != S_OK) clear_path( path );
186 else path->flags |= WBEMPATH_INFO_CIM_COMPLIANT | WBEMPATH_INFO_V2_COMPLIANT;
190 static HRESULT WINAPI path_SetText(
195 struct path *path = impl_from_IWbemPath( iface );
199 TRACE("%p, %u, %s\n", iface, uMode, debugstr_w(pszPath));
201 if (!uMode || !pszPath) return WBEM_E_INVALID_PARAMETER;
204 if (!pszPath[0]) return S_OK;
205 if ((hr = parse_text( path, uMode, pszPath )) != S_OK) return hr;
207 len = strlenW( pszPath );
208 if (!(path->text = heap_alloc( (len + 1) * sizeof(WCHAR) )))
211 return E_OUTOFMEMORY;
213 strcpyW( path->text, pszPath );
214 path->len_text = len;
218 static WCHAR *build_namespace( struct path *path, int *len, BOOL leading_slash )
224 for (i = 0; i < path->num_namespaces; i++)
226 if (i > 0 || leading_slash) *len += 1;
227 *len += path->len_namespaces[i];
229 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL;
230 for (i = 0; i < path->num_namespaces; i++)
232 if (i > 0 || leading_slash) *p++ = '\\';
233 memcpy( p, path->namespaces[i], path->len_namespaces[i] * sizeof(WCHAR) );
234 p += path->len_namespaces[i];
240 static WCHAR *build_server( struct path *path, int *len )
245 if (path->len_server) *len += 2 + path->len_server;
247 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL;
248 if (path->len_server)
251 strcpyW( p + 2, path->server );
261 static WCHAR *build_path( struct path *path, LONG flags, int *len )
268 WCHAR *ret, *namespace = build_namespace( path, &len_namespace, FALSE );
270 if (!namespace) return NULL;
272 *len = len_namespace;
273 if (path->len_class) *len += 1 + path->len_class;
274 if (!(ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
276 heap_free( namespace );
279 strcpyW( ret, namespace );
282 ret[len_namespace] = ':';
283 strcpyW( ret + len_namespace + 1, path->class );
285 heap_free( namespace );
289 case WBEMPATH_GET_RELATIVE_ONLY:
290 if (!path->len_class)
295 *len = path->len_class;
296 return strdupW( path->class );
298 case WBEMPATH_GET_SERVER_TOO:
300 int len_namespace, len_server;
301 WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace, TRUE );
302 WCHAR *server = build_server( path, &len_server );
304 if (!namespace || !server)
306 heap_free( namespace );
310 *len = len_namespace + len_server;
311 if (path->len_class) *len += 1 + path->len_class;
312 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
314 heap_free( namespace );
318 strcpyW( p, server );
320 strcpyW( p, namespace );
325 strcpyW( p + 1, path->class );
327 heap_free( namespace );
331 case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY:
333 int len_namespace, len_server;
334 WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace, TRUE );
335 WCHAR *server = build_server( path, &len_server );
337 if (!namespace || !server)
339 heap_free( namespace );
343 *len = len_namespace + len_server;
344 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
346 heap_free( namespace );
350 strcpyW( p, server );
352 strcpyW( p, namespace );
353 heap_free( namespace );
357 case WBEMPATH_GET_NAMESPACE_ONLY:
358 return build_namespace( path, len, FALSE );
360 case WBEMPATH_GET_ORIGINAL:
366 *len = path->len_text;
367 return strdupW( path->text );
370 ERR("unhandled flags 0x%x\n", flags);
375 static HRESULT WINAPI path_GetText(
378 ULONG *puBufferLength,
381 struct path *path = impl_from_IWbemPath( iface );
385 TRACE("%p, 0x%x, %p, %p\n", iface, lFlags, puBufferLength, pszText);
387 if (!puBufferLength) return WBEM_E_INVALID_PARAMETER;
389 str = build_path( path, lFlags, &len );
391 if (*puBufferLength < len + 1)
393 *puBufferLength = len + 1;
399 return WBEM_E_INVALID_PARAMETER;
401 if (str) strcpyW( pszText, str );
403 *puBufferLength = len + 1;
405 TRACE("<-- %s\n", debugstr_w(pszText));
410 static HRESULT WINAPI path_GetInfo(
415 struct path *path = impl_from_IWbemPath( iface );
417 TRACE("%p, %u, %p\n", iface, info, response);
419 if (info || !response) return WBEM_E_INVALID_PARAMETER;
421 FIXME("some flags are not implemented\n");
423 *response = path->flags;
424 if (!path->server || (path->len_server == 1 && path->server[0] == '.'))
425 *response |= WBEMPATH_INFO_ANON_LOCAL_MACHINE;
427 *response |= WBEMPATH_INFO_HAS_MACHINE_NAME;
430 *response |= WBEMPATH_INFO_SERVER_NAMESPACE_ONLY;
433 *response |= WBEMPATH_INFO_HAS_SUBSCOPES;
434 if (path->text && strchrW( path->text, '=' )) /* FIXME */
435 *response |= WBEMPATH_INFO_IS_INST_REF;
437 *response |= WBEMPATH_INFO_IS_CLASS_REF;
442 static HRESULT WINAPI path_SetServer(
446 FIXME("%p, %s\n", iface, debugstr_w(Name));
450 static HRESULT WINAPI path_GetServer(
455 struct path *path = impl_from_IWbemPath( iface );
457 TRACE("%p, %p, %p\n", iface, len, name);
459 if (!len || (*len && !name)) return WBEM_E_INVALID_PARAMETER;
460 if (!path->class) return WBEM_E_NOT_AVAILABLE;
461 if (*len > path->len_server) strcpyW( name, path->server );
462 *len = path->len_server + 1;
466 static HRESULT WINAPI path_GetNamespaceCount(
470 struct path *path = impl_from_IWbemPath( iface );
472 TRACE("%p, %p\n", iface, puCount);
474 if (!puCount) return WBEM_E_INVALID_PARAMETER;
475 *puCount = path->num_namespaces;
479 static HRESULT WINAPI path_SetNamespaceAt(
484 FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszName));
488 static HRESULT WINAPI path_GetNamespaceAt(
491 ULONG *puNameBufLength,
494 FIXME("%p, %u, %p, %p\n", iface, uIndex, puNameBufLength, pName);
498 static HRESULT WINAPI path_RemoveNamespaceAt(
502 FIXME("%p, %u\n", iface, uIndex);
506 static HRESULT WINAPI path_RemoveAllNamespaces(
509 FIXME("%p\n", iface);
513 static HRESULT WINAPI path_GetScopeCount(
517 FIXME("%p, %p\n", iface, puCount);
521 static HRESULT WINAPI path_SetScope(
526 FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszClass));
530 static HRESULT WINAPI path_SetScopeFromText(
535 FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszText));
539 static HRESULT WINAPI path_GetScope(
542 ULONG *puClassNameBufSize,
544 IWbemPathKeyList **pKeyList)
546 FIXME("%p, %u, %p, %p, %p\n", iface, uIndex, puClassNameBufSize, pszClass, pKeyList);
550 static HRESULT WINAPI path_GetScopeAsText(
553 ULONG *puTextBufSize,
556 FIXME("%p, %u, %p, %p\n", iface, uIndex, puTextBufSize, pszText);
560 static HRESULT WINAPI path_RemoveScope(
564 FIXME("%p, %u\n", iface, uIndex);
568 static HRESULT WINAPI path_RemoveAllScopes(
571 FIXME("%p\n", iface);
575 static HRESULT WINAPI path_SetClassName(
579 FIXME("%p, %s\n", iface, debugstr_w(Name));
583 static HRESULT WINAPI path_GetClassName(
588 struct path *path = impl_from_IWbemPath( iface );
590 TRACE("%p, %p, %p\n", iface, len, name);
592 if (!len || (*len && !name)) return WBEM_E_INVALID_PARAMETER;
593 if (!path->class) return WBEM_E_INVALID_OBJECT_PATH;
594 if (*len > path->len_class) strcpyW( name, path->class );
595 *len = path->len_class + 1;
599 static HRESULT WINAPI path_GetKeyList(
601 IWbemPathKeyList **pOut)
603 FIXME("%p, %p\n", iface, pOut);
607 static HRESULT WINAPI path_CreateClassPart(
612 FIXME("%p, 0x%x, %s\n", iface, lFlags, debugstr_w(Name));
616 static HRESULT WINAPI path_DeleteClassPart(
620 FIXME("%p, 0x%x\n", iface, lFlags);
624 static BOOL WINAPI path_IsRelative(
629 FIXME("%p, %s, %s\n", iface, debugstr_w(wszMachine), debugstr_w(wszNamespace));
633 static BOOL WINAPI path_IsRelativeOrChild(
639 FIXME("%p, %s, %s, 0x%x\n", iface, debugstr_w(wszMachine), debugstr_w(wszNamespace), lFlags);
643 static BOOL WINAPI path_IsLocal(
647 FIXME("%p, %s\n", iface, debugstr_w(wszMachine));
651 static BOOL WINAPI path_IsSameClassName(
655 FIXME("%p, %s\n", iface, debugstr_w(wszClass));
659 static const struct IWbemPathVtbl path_vtbl =
669 path_GetNamespaceCount,
672 path_RemoveNamespaceAt,
673 path_RemoveAllNamespaces,
676 path_SetScopeFromText,
680 path_RemoveAllScopes,
684 path_CreateClassPart,
685 path_DeleteClassPart,
687 path_IsRelativeOrChild,
692 HRESULT WbemPath_create( IUnknown *pUnkOuter, LPVOID *ppObj )
696 TRACE("%p, %p\n", pUnkOuter, ppObj);
698 if (!(path = heap_alloc( sizeof(*path) ))) return E_OUTOFMEMORY;
700 path->IWbemPath_iface.lpVtbl = &path_vtbl;
704 *ppObj = &path->IWbemPath_iface;
706 TRACE("returning iface %p\n", *ppObj);