Release 1.6-rc2.
[wine/testsucceed.git] / dlls / wmiutils / path.c
blob046f424fe5499043810015c0dcb492c409d5a9f0
1 /*
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
19 #define COBJMACROS
21 #include "config.h"
22 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "ole2.h"
27 #include "wbemcli.h"
28 #include "wmiutils.h"
30 #include "wine/debug.h"
31 #include "wmiutils_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(wmiutils);
35 struct keylist
37 IWbemPathKeyList IWbemPathKeyList_iface;
38 IWbemPath *parent;
39 LONG refs;
42 struct key
44 WCHAR *name;
45 int len_name;
46 WCHAR *value;
47 int len_value;
50 struct path
52 IWbemPath IWbemPath_iface;
53 LONG refs;
54 CRITICAL_SECTION cs;
55 WCHAR *text;
56 int len_text;
57 WCHAR *server;
58 int len_server;
59 WCHAR **namespaces;
60 int *len_namespaces;
61 int num_namespaces;
62 WCHAR *class;
63 int len_class;
64 struct key *keys;
65 unsigned int num_keys;
66 ULONGLONG flags;
69 static inline struct keylist *impl_from_IWbemPathKeyList( IWbemPathKeyList *iface )
71 return CONTAINING_RECORD(iface, struct keylist, IWbemPathKeyList_iface);
74 static inline struct path *impl_from_IWbemPath( IWbemPath *iface )
76 return CONTAINING_RECORD(iface, struct path, IWbemPath_iface);
79 static ULONG WINAPI keylist_AddRef(
80 IWbemPathKeyList *iface )
82 struct keylist *keylist = impl_from_IWbemPathKeyList( iface );
83 return InterlockedIncrement( &keylist->refs );
86 static ULONG WINAPI keylist_Release(
87 IWbemPathKeyList *iface )
89 struct keylist *keylist = impl_from_IWbemPathKeyList( iface );
90 LONG refs = InterlockedDecrement( &keylist->refs );
91 if (!refs)
93 TRACE("destroying %p\n", keylist);
94 IWbemPath_Release( keylist->parent );
95 heap_free( keylist );
97 return refs;
100 static HRESULT WINAPI keylist_QueryInterface(
101 IWbemPathKeyList *iface,
102 REFIID riid,
103 void **ppvObject )
105 struct keylist *keylist = impl_from_IWbemPathKeyList( iface );
107 TRACE("%p, %s, %p\n", keylist, debugstr_guid(riid), ppvObject);
109 if (IsEqualGUID( riid, &IID_IWbemPathKeyList ) ||
110 IsEqualGUID( riid, &IID_IUnknown ))
112 *ppvObject = iface;
114 else
116 FIXME("interface %s not implemented\n", debugstr_guid(riid));
117 return E_NOINTERFACE;
119 IWbemPathKeyList_AddRef( iface );
120 return S_OK;
123 static HRESULT WINAPI keylist_GetCount(
124 IWbemPathKeyList *iface,
125 ULONG *puKeyCount )
127 struct keylist *keylist = impl_from_IWbemPathKeyList( iface );
128 struct path *parent = impl_from_IWbemPath( keylist->parent );
130 TRACE("%p, %p\n", iface, puKeyCount);
132 if (!puKeyCount) return WBEM_E_INVALID_PARAMETER;
134 EnterCriticalSection( &parent->cs );
136 *puKeyCount = parent->num_keys;
138 LeaveCriticalSection( &parent->cs );
139 return S_OK;
142 static HRESULT WINAPI keylist_SetKey(
143 IWbemPathKeyList *iface,
144 LPCWSTR wszName,
145 ULONG uFlags,
146 ULONG uCimType,
147 LPVOID pKeyVal )
149 FIXME("%p, %s, 0x%x, %u, %p\n", iface, debugstr_w(wszName), uFlags, uCimType, pKeyVal);
150 return E_NOTIMPL;
153 static HRESULT WINAPI keylist_SetKey2(
154 IWbemPathKeyList *iface,
155 LPCWSTR wszName,
156 ULONG uFlags,
157 ULONG uCimType,
158 VARIANT *pKeyVal )
160 FIXME("%p, %s, 0x%x, %u, %p\n", iface, debugstr_w(wszName), uFlags, uCimType, pKeyVal);
161 return E_NOTIMPL;
164 static HRESULT WINAPI keylist_GetKey(
165 IWbemPathKeyList *iface,
166 ULONG uKeyIx,
167 ULONG uFlags,
168 ULONG *puNameBufSize,
169 LPWSTR pszKeyName,
170 ULONG *puKeyValBufSize,
171 LPVOID pKeyVal,
172 ULONG *puApparentCimType )
174 FIXME("%p, %u, 0x%x, %p, %p, %p, %p, %p\n", iface, uKeyIx, uFlags, puNameBufSize,
175 pszKeyName, puKeyValBufSize, pKeyVal, puApparentCimType);
176 return E_NOTIMPL;
179 static HRESULT WINAPI keylist_GetKey2(
180 IWbemPathKeyList *iface,
181 ULONG uKeyIx,
182 ULONG uFlags,
183 ULONG *puNameBufSize,
184 LPWSTR pszKeyName,
185 VARIANT *pKeyValue,
186 ULONG *puApparentCimType )
188 FIXME("%p, %u, 0x%x, %p, %p, %p, %p\n", iface, uKeyIx, uFlags, puNameBufSize,
189 pszKeyName, pKeyValue, puApparentCimType);
190 return E_NOTIMPL;
193 static HRESULT WINAPI keylist_RemoveKey(
194 IWbemPathKeyList *iface,
195 LPCWSTR wszName,
196 ULONG uFlags )
198 FIXME("%p, %s, 0x%x\n", iface, debugstr_w(wszName), uFlags);
199 return E_NOTIMPL;
202 static void free_keys( struct key *keys, unsigned int count )
204 unsigned int i;
206 for (i = 0; i < count; i++)
208 heap_free( keys[i].name );
209 heap_free( keys[i].value );
211 heap_free( keys );
214 static HRESULT WINAPI keylist_RemoveAllKeys(
215 IWbemPathKeyList *iface,
216 ULONG uFlags )
218 struct keylist *keylist = impl_from_IWbemPathKeyList( iface );
219 struct path *parent = impl_from_IWbemPath( keylist->parent );
221 TRACE("%p, 0x%x\n", iface, uFlags);
223 if (uFlags) return WBEM_E_INVALID_PARAMETER;
225 EnterCriticalSection( &parent->cs );
227 free_keys( parent->keys, parent->num_keys );
228 parent->num_keys = 0;
229 parent->keys = NULL;
231 LeaveCriticalSection( &parent->cs );
232 return S_OK;
235 static HRESULT WINAPI keylist_MakeSingleton(
236 IWbemPathKeyList *iface,
237 boolean bSet )
239 FIXME("%p, %d\n", iface, bSet);
240 return E_NOTIMPL;
243 static HRESULT WINAPI keylist_GetInfo(
244 IWbemPathKeyList *iface,
245 ULONG uRequestedInfo,
246 ULONGLONG *puResponse )
248 FIXME("%p, %u, %p\n", iface, uRequestedInfo, puResponse);
249 return E_NOTIMPL;
252 static HRESULT WINAPI keylist_GetText(
253 IWbemPathKeyList *iface,
254 LONG lFlags,
255 ULONG *puBuffLength,
256 LPWSTR pszText )
258 FIXME("%p, 0x%x, %p, %p\n", iface, lFlags, puBuffLength, pszText);
259 return E_NOTIMPL;
262 static const struct IWbemPathKeyListVtbl keylist_vtbl =
264 keylist_QueryInterface,
265 keylist_AddRef,
266 keylist_Release,
267 keylist_GetCount,
268 keylist_SetKey,
269 keylist_SetKey2,
270 keylist_GetKey,
271 keylist_GetKey2,
272 keylist_RemoveKey,
273 keylist_RemoveAllKeys,
274 keylist_MakeSingleton,
275 keylist_GetInfo,
276 keylist_GetText
279 static HRESULT WbemPathKeyList_create( IUnknown *pUnkOuter, IWbemPath *parent, LPVOID *ppObj )
281 struct keylist *keylist;
283 TRACE("%p, %p\n", pUnkOuter, ppObj);
285 if (!(keylist = heap_alloc( sizeof(*keylist) ))) return E_OUTOFMEMORY;
287 keylist->IWbemPathKeyList_iface.lpVtbl = &keylist_vtbl;
288 keylist->refs = 1;
289 keylist->parent = parent;
290 IWbemPath_AddRef( keylist->parent );
292 *ppObj = &keylist->IWbemPathKeyList_iface;
294 TRACE("returning iface %p\n", *ppObj);
295 return S_OK;
298 static void init_path( struct path *path )
300 path->text = NULL;
301 path->len_text = 0;
302 path->server = NULL;
303 path->len_server = 0;
304 path->namespaces = NULL;
305 path->len_namespaces = NULL;
306 path->num_namespaces = 0;
307 path->class = NULL;
308 path->len_class = 0;
309 path->keys = NULL;
310 path->num_keys = 0;
311 path->flags = 0;
314 static void clear_path( struct path *path )
316 heap_free( path->text );
317 heap_free( path->server );
318 heap_free( path->namespaces );
319 heap_free( path->len_namespaces );
320 heap_free( path->class );
321 free_keys( path->keys, path->num_keys );
322 init_path( path );
325 static ULONG WINAPI path_AddRef(
326 IWbemPath *iface )
328 struct path *path = impl_from_IWbemPath( iface );
329 return InterlockedIncrement( &path->refs );
332 static ULONG WINAPI path_Release(
333 IWbemPath *iface )
335 struct path *path = impl_from_IWbemPath( iface );
336 LONG refs = InterlockedDecrement( &path->refs );
337 if (!refs)
339 TRACE("destroying %p\n", path);
340 clear_path( path );
341 path->cs.DebugInfo->Spare[0] = 0;
342 DeleteCriticalSection( &path->cs );
343 heap_free( path );
345 return refs;
348 static HRESULT WINAPI path_QueryInterface(
349 IWbemPath *iface,
350 REFIID riid,
351 void **ppvObject )
353 struct path *path = impl_from_IWbemPath( iface );
355 TRACE("%p, %s, %p\n", path, debugstr_guid( riid ), ppvObject );
357 if ( IsEqualGUID( riid, &IID_IWbemPath ) ||
358 IsEqualGUID( riid, &IID_IUnknown ) )
360 *ppvObject = iface;
362 else
364 FIXME("interface %s not implemented\n", debugstr_guid(riid));
365 return E_NOINTERFACE;
367 IWbemPath_AddRef( iface );
368 return S_OK;
371 static HRESULT parse_key( struct key *key, const WCHAR *str, unsigned int *ret_len )
373 const WCHAR *p, *q;
374 unsigned int len;
376 p = q = str;
377 while (*q && *q != '=')
379 if (*q == ',' || isspaceW( *q )) return WBEM_E_INVALID_PARAMETER;
380 q++;
382 len = q - p;
383 if (!(key->name = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
384 memcpy( key->name, p, len * sizeof(WCHAR) );
385 key->name[len] = 0;
386 key->len_name = len;
388 p = ++q;
389 if (!*p || *p == ',' || isspaceW( *p )) return WBEM_E_INVALID_PARAMETER;
391 while (*q && *q != ',') q++;
392 len = q - p;
393 if (!(key->value = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
394 memcpy( key->value, p, len * sizeof(WCHAR) );
395 key->value[len] = 0;
396 key->len_value = len;
398 *ret_len = q - str;
399 if (*q == ',') (*ret_len)++;
400 return S_OK;
403 static HRESULT parse_text( struct path *path, ULONG mode, const WCHAR *text )
405 HRESULT hr = E_OUTOFMEMORY;
406 const WCHAR *p, *q;
407 unsigned int i, len;
409 p = q = text;
410 if ((p[0] == '\\' && p[1] == '\\') || (p[0] == '/' && p[1] == '/'))
412 p += 2;
413 q = p;
414 while (*q && *q != '\\' && *q != '/') q++;
415 len = q - p;
416 if (!(path->server = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
417 memcpy( path->server, p, len * sizeof(WCHAR) );
418 path->server[len] = 0;
419 path->len_server = len;
420 path->flags |= WBEMPATH_INFO_PATH_HAD_SERVER;
422 p = q;
423 if (strchrW( p, '\\' ) || strchrW( p, '/' ))
425 if (*q != '\\' && *q != '/' && *q != ':')
427 path->num_namespaces = 1;
428 q++;
430 while (*q && *q != ':')
432 if (*q == '\\' || *q == '/') path->num_namespaces++;
433 q++;
436 if (path->num_namespaces)
438 if (!(path->namespaces = heap_alloc( path->num_namespaces * sizeof(WCHAR *) ))) goto done;
439 if (!(path->len_namespaces = heap_alloc( path->num_namespaces * sizeof(int) ))) goto done;
441 i = 0;
442 q = p;
443 if (*q && *q != '\\' && *q != '/' && *q != ':')
445 p = q;
446 while (*p && *p != '\\' && *p != '/' && *p != ':') p++;
447 len = p - q;
448 if (!(path->namespaces[i] = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
449 memcpy( path->namespaces[i], q, len * sizeof(WCHAR) );
450 path->namespaces[i][len] = 0;
451 path->len_namespaces[i] = len;
452 q = p;
453 i++;
455 while (*q && *q != ':')
457 if (*q == '\\' || *q == '/')
459 p = q + 1;
460 while (*p && *p != '\\' && *p != '/' && *p != ':') p++;
461 len = p - q - 1;
462 if (!(path->namespaces[i] = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
463 memcpy( path->namespaces[i], q + 1, len * sizeof(WCHAR) );
464 path->namespaces[i][len] = 0;
465 path->len_namespaces[i] = len;
466 i++;
468 q++;
471 if (*q == ':') q++;
472 p = q;
473 while (*q && *q != '.') q++;
474 len = q - p;
475 if (!(path->class = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done;
476 memcpy( path->class, p, len * sizeof(WCHAR) );
477 path->class[len] = 0;
478 path->len_class = len;
480 if (*q == '.')
482 p = ++q;
483 path->num_keys++;
484 while (*q)
486 if (*q == ',') path->num_keys++;
487 q++;
489 if (!(path->keys = heap_alloc_zero( path->num_keys * sizeof(struct key) ))) goto done;
490 i = 0;
491 q = p;
492 while (*q)
494 if (i >= path->num_keys) break;
495 hr = parse_key( &path->keys[i], q, &len );
496 if (hr != S_OK) goto done;
497 q += len;
498 i++;
501 hr = S_OK;
503 done:
504 if (hr != S_OK) clear_path( path );
505 else path->flags |= WBEMPATH_INFO_CIM_COMPLIANT | WBEMPATH_INFO_V2_COMPLIANT;
506 return hr;
509 static HRESULT WINAPI path_SetText(
510 IWbemPath *iface,
511 ULONG uMode,
512 LPCWSTR pszPath)
514 struct path *path = impl_from_IWbemPath( iface );
515 HRESULT hr = S_OK;
516 int len;
518 TRACE("%p, %u, %s\n", iface, uMode, debugstr_w(pszPath));
520 if (!uMode || !pszPath) return WBEM_E_INVALID_PARAMETER;
522 EnterCriticalSection( &path->cs );
524 clear_path( path );
525 if (!pszPath[0]) goto done;
526 if ((hr = parse_text( path, uMode, pszPath )) != S_OK) goto done;
528 len = strlenW( pszPath );
529 if (!(path->text = heap_alloc( (len + 1) * sizeof(WCHAR) )))
531 clear_path( path );
532 hr = E_OUTOFMEMORY;
533 goto done;
535 strcpyW( path->text, pszPath );
536 path->len_text = len;
538 done:
539 LeaveCriticalSection( &path->cs );
540 return hr;
543 static WCHAR *build_namespace( struct path *path, int *len, BOOL leading_slash )
545 WCHAR *ret, *p;
546 int i;
548 *len = 0;
549 for (i = 0; i < path->num_namespaces; i++)
551 if (i > 0 || leading_slash) *len += 1;
552 *len += path->len_namespaces[i];
554 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL;
555 for (i = 0; i < path->num_namespaces; i++)
557 if (i > 0 || leading_slash) *p++ = '\\';
558 memcpy( p, path->namespaces[i], path->len_namespaces[i] * sizeof(WCHAR) );
559 p += path->len_namespaces[i];
561 *p = 0;
562 return ret;
565 static WCHAR *build_server( struct path *path, int *len )
567 WCHAR *ret, *p;
569 *len = 0;
570 if (path->len_server) *len += 2 + path->len_server;
571 else *len += 3;
572 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL;
573 if (path->len_server)
575 p[0] = p[1] = '\\';
576 strcpyW( p + 2, path->server );
578 else
580 p[0] = p[1] = '\\';
581 p[2] = '.';
583 return ret;
586 static WCHAR *build_keylist( struct path *path, int *len )
588 WCHAR *ret, *p;
589 unsigned int i;
591 *len = 0;
592 for (i = 0; i < path->num_keys; i++)
594 if (i > 0) *len += 1;
595 *len += path->keys[i].len_name + path->keys[i].len_value + 1;
597 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL;
598 for (i = 0; i < path->num_keys; i++)
600 if (i > 0) *p++ = ',';
601 memcpy( p, path->keys[i].name, path->keys[i].len_name * sizeof(WCHAR) );
602 p += path->keys[i].len_name;
603 *p++ = '=';
604 memcpy( p, path->keys[i].value, path->keys[i].len_value * sizeof(WCHAR) );
605 p += path->keys[i].len_value;
607 *p = 0;
608 return ret;
611 static WCHAR *build_path( struct path *path, LONG flags, int *len )
613 *len = 0;
614 switch (flags)
616 case 0:
618 int len_namespace, len_keylist;
619 WCHAR *ret, *namespace = build_namespace( path, &len_namespace, FALSE );
620 WCHAR *keylist = build_keylist( path, &len_keylist );
622 if (!namespace || !keylist)
624 heap_free( namespace );
625 heap_free( keylist );
626 return NULL;
628 *len = len_namespace;
629 if (path->len_class)
631 *len += path->len_class + 1;
632 if (path->num_keys) *len += len_keylist + 1;
634 if (!(ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
636 heap_free( namespace );
637 heap_free( keylist );
638 return NULL;
640 strcpyW( ret, namespace );
641 if (path->len_class)
643 ret[len_namespace] = ':';
644 strcpyW( ret + len_namespace + 1, path->class );
645 if (path->num_keys)
647 ret[len_namespace + path->len_class + 1] = '.';
648 strcpyW( ret + len_namespace + path->len_class + 2, keylist );
651 heap_free( namespace );
652 heap_free( keylist );
653 return ret;
656 case WBEMPATH_GET_RELATIVE_ONLY:
658 int len_keylist;
659 WCHAR *ret, *keylist;
661 if (!path->len_class) return NULL;
662 if (!(keylist = build_keylist( path, &len_keylist ))) return NULL;
664 *len = path->len_class;
665 if (path->num_keys) *len += len_keylist + 1;
666 if (!(ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
668 heap_free( keylist );
669 return NULL;
671 strcpyW( ret, path->class );
672 if (path->num_keys)
674 ret[path->len_class] = '.';
675 strcpyW( ret + path->len_class + 1, keylist );
677 heap_free( keylist );
678 return ret;
680 case WBEMPATH_GET_SERVER_TOO:
682 int len_namespace, len_server, len_keylist;
683 WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace, TRUE );
684 WCHAR *server = build_server( path, &len_server );
685 WCHAR *keylist = build_keylist( path, &len_keylist );
687 if (!namespace || !server || !keylist)
689 heap_free( namespace );
690 heap_free( server );
691 heap_free( keylist );
692 return NULL;
694 *len = len_namespace + len_server;
695 if (path->len_class)
697 *len += path->len_class + 1;
698 if (path->num_keys) *len += len_keylist + 1;
700 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
702 heap_free( namespace );
703 heap_free( server );
704 heap_free( keylist );
705 return NULL;
707 strcpyW( p, server );
708 p += len_server;
709 strcpyW( p, namespace );
710 p += len_namespace;
711 if (path->len_class)
713 *p++ = ':';
714 strcpyW( p, path->class );
715 if (path->num_keys)
717 p[path->len_class] = '.';
718 strcpyW( p + path->len_class + 1, keylist );
721 heap_free( namespace );
722 heap_free( server );
723 heap_free( keylist );
724 return ret;
726 case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY:
728 int len_namespace, len_server;
729 WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace, TRUE );
730 WCHAR *server = build_server( path, &len_server );
732 if (!namespace || !server)
734 heap_free( namespace );
735 heap_free( server );
736 return NULL;
738 *len = len_namespace + len_server;
739 if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) )))
741 heap_free( namespace );
742 heap_free( server );
743 return NULL;
745 strcpyW( p, server );
746 p += len_server;
747 strcpyW( p, namespace );
748 heap_free( namespace );
749 heap_free( server );
750 return ret;
752 case WBEMPATH_GET_NAMESPACE_ONLY:
753 return build_namespace( path, len, FALSE );
755 case WBEMPATH_GET_ORIGINAL:
756 if (!path->len_text) return NULL;
757 *len = path->len_text;
758 return strdupW( path->text );
760 default:
761 ERR("unhandled flags 0x%x\n", flags);
762 return NULL;
766 static HRESULT WINAPI path_GetText(
767 IWbemPath *iface,
768 LONG lFlags,
769 ULONG *puBufferLength,
770 LPWSTR pszText)
772 struct path *path = impl_from_IWbemPath( iface );
773 HRESULT hr = S_OK;
774 WCHAR *str;
775 int len;
777 TRACE("%p, 0x%x, %p, %p\n", iface, lFlags, puBufferLength, pszText);
779 if (!puBufferLength) return WBEM_E_INVALID_PARAMETER;
781 EnterCriticalSection( &path->cs );
783 str = build_path( path, lFlags, &len );
784 if (*puBufferLength < len + 1)
786 *puBufferLength = len + 1;
787 goto done;
789 if (!pszText)
791 hr = WBEM_E_INVALID_PARAMETER;
792 goto done;
794 if (str) strcpyW( pszText, str );
795 else pszText[0] = 0;
796 *puBufferLength = len + 1;
798 TRACE("returning %s\n", debugstr_w(pszText));
800 done:
801 heap_free( str );
802 LeaveCriticalSection( &path->cs );
803 return hr;
806 static HRESULT WINAPI path_GetInfo(
807 IWbemPath *iface,
808 ULONG info,
809 ULONGLONG *response)
811 struct path *path = impl_from_IWbemPath( iface );
813 TRACE("%p, %u, %p\n", iface, info, response);
815 if (info || !response) return WBEM_E_INVALID_PARAMETER;
817 FIXME("some flags are not implemented\n");
819 EnterCriticalSection( &path->cs );
821 *response = path->flags;
822 if (!path->server || (path->len_server == 1 && path->server[0] == '.'))
823 *response |= WBEMPATH_INFO_ANON_LOCAL_MACHINE;
824 else
825 *response |= WBEMPATH_INFO_HAS_MACHINE_NAME;
827 if (!path->class)
828 *response |= WBEMPATH_INFO_SERVER_NAMESPACE_ONLY;
829 else
831 *response |= WBEMPATH_INFO_HAS_SUBSCOPES;
832 if (path->num_keys)
833 *response |= WBEMPATH_INFO_IS_INST_REF;
834 else
835 *response |= WBEMPATH_INFO_IS_CLASS_REF;
838 LeaveCriticalSection( &path->cs );
839 return S_OK;
842 static HRESULT WINAPI path_SetServer(
843 IWbemPath *iface,
844 LPCWSTR name)
846 struct path *path = impl_from_IWbemPath( iface );
847 static const ULONGLONG flags =
848 WBEMPATH_INFO_PATH_HAD_SERVER | WBEMPATH_INFO_V1_COMPLIANT |
849 WBEMPATH_INFO_V2_COMPLIANT | WBEMPATH_INFO_CIM_COMPLIANT;
850 WCHAR *server;
852 TRACE("%p, %s\n", iface, debugstr_w(name));
854 EnterCriticalSection( &path->cs );
856 if (name)
858 if (!(server = strdupW( name )))
860 LeaveCriticalSection( &path->cs );
861 return WBEM_E_OUT_OF_MEMORY;
863 heap_free( path->server );
864 path->server = server;
865 path->len_server = strlenW( path->server );
866 path->flags |= flags;
868 else
870 heap_free( path->server );
871 path->server = NULL;
872 path->len_server = 0;
873 path->flags &= ~flags;
876 LeaveCriticalSection( &path->cs );
877 return S_OK;
880 static HRESULT WINAPI path_GetServer(
881 IWbemPath *iface,
882 ULONG *len,
883 LPWSTR name)
885 struct path *path = impl_from_IWbemPath( iface );
887 TRACE("%p, %p, %p\n", iface, len, name);
889 if (!len || (*len && !name)) return WBEM_E_INVALID_PARAMETER;
891 EnterCriticalSection( &path->cs );
893 if (!path->server)
895 LeaveCriticalSection( &path->cs );
896 return WBEM_E_NOT_AVAILABLE;
898 if (*len > path->len_server) strcpyW( name, path->server );
899 *len = path->len_server + 1;
901 LeaveCriticalSection( &path->cs );
902 return S_OK;
905 static HRESULT WINAPI path_GetNamespaceCount(
906 IWbemPath *iface,
907 ULONG *puCount)
909 struct path *path = impl_from_IWbemPath( iface );
911 TRACE("%p, %p\n", iface, puCount);
913 if (!puCount) return WBEM_E_INVALID_PARAMETER;
915 EnterCriticalSection( &path->cs );
916 *puCount = path->num_namespaces;
917 LeaveCriticalSection( &path->cs );
918 return S_OK;
921 static HRESULT WINAPI path_SetNamespaceAt(
922 IWbemPath *iface,
923 ULONG idx,
924 LPCWSTR name)
926 struct path *path = impl_from_IWbemPath( iface );
927 static const ULONGLONG flags =
928 WBEMPATH_INFO_V1_COMPLIANT | WBEMPATH_INFO_V2_COMPLIANT |
929 WBEMPATH_INFO_CIM_COMPLIANT;
930 int i, *tmp_len;
931 WCHAR **tmp, *new;
932 DWORD size;
934 TRACE("%p, %u, %s\n", iface, idx, debugstr_w(name));
936 EnterCriticalSection( &path->cs );
938 if (idx > path->num_namespaces || !name)
940 LeaveCriticalSection( &path->cs );
941 return WBEM_E_INVALID_PARAMETER;
943 if (!(new = strdupW( name )))
945 LeaveCriticalSection( &path->cs );
946 return WBEM_E_OUT_OF_MEMORY;
948 size = (path->num_namespaces + 1) * sizeof(WCHAR *);
949 if (path->namespaces) tmp = heap_realloc( path->namespaces, size );
950 else tmp = heap_alloc( size );
951 if (!tmp)
953 heap_free( new );
954 LeaveCriticalSection( &path->cs );
955 return WBEM_E_OUT_OF_MEMORY;
957 path->namespaces = tmp;
958 size = (path->num_namespaces + 1) * sizeof(int);
959 if (path->len_namespaces) tmp_len = heap_realloc( path->len_namespaces, size );
960 else tmp_len = heap_alloc( size );
961 if (!tmp_len)
963 heap_free( new );
964 LeaveCriticalSection( &path->cs );
965 return WBEM_E_OUT_OF_MEMORY;
967 path->len_namespaces = tmp_len;
968 for (i = idx; i < path->num_namespaces; i++)
970 path->namespaces[i + 1] = path->namespaces[i];
971 path->len_namespaces[i + 1] = path->len_namespaces[i];
973 path->namespaces[idx] = new;
974 path->len_namespaces[idx] = strlenW( new );
975 path->num_namespaces++;
976 path->flags |= flags;
978 LeaveCriticalSection( &path->cs );
979 return S_OK;
982 static HRESULT WINAPI path_GetNamespaceAt(
983 IWbemPath *iface,
984 ULONG idx,
985 ULONG *len,
986 LPWSTR name)
988 struct path *path = impl_from_IWbemPath( iface );
990 TRACE("%p, %u, %p, %p\n", iface, idx, len, name);
992 EnterCriticalSection( &path->cs );
994 if (!len || (*len && !name) || idx >= path->num_namespaces)
996 LeaveCriticalSection( &path->cs );
997 return WBEM_E_INVALID_PARAMETER;
999 if (*len > path->len_namespaces[idx]) strcpyW( name, path->namespaces[idx] );
1000 *len = path->len_namespaces[idx] + 1;
1002 LeaveCriticalSection( &path->cs );
1003 return S_OK;
1006 static HRESULT WINAPI path_RemoveNamespaceAt(
1007 IWbemPath *iface,
1008 ULONG idx)
1010 struct path *path = impl_from_IWbemPath( iface );
1012 TRACE("%p, %u\n", iface, idx);
1014 EnterCriticalSection( &path->cs );
1016 if (idx >= path->num_namespaces)
1018 LeaveCriticalSection( &path->cs );
1019 return WBEM_E_INVALID_PARAMETER;
1021 heap_free( path->namespaces[idx] );
1022 while (idx < path->num_namespaces - 1)
1024 path->namespaces[idx] = path->namespaces[idx + 1];
1025 path->len_namespaces[idx] = path->len_namespaces[idx + 1];
1026 idx++;
1028 path->num_namespaces--;
1030 LeaveCriticalSection( &path->cs );
1031 return S_OK;
1034 static HRESULT WINAPI path_RemoveAllNamespaces(
1035 IWbemPath *iface)
1037 struct path *path = impl_from_IWbemPath( iface );
1038 int i;
1040 TRACE("%p\n", iface);
1042 EnterCriticalSection( &path->cs );
1044 for (i = 0; i < path->num_namespaces; i++) heap_free( path->namespaces[i] );
1045 path->num_namespaces = 0;
1046 heap_free( path->namespaces );
1047 path->namespaces = NULL;
1048 heap_free( path->len_namespaces );
1049 path->len_namespaces = NULL;
1051 LeaveCriticalSection( &path->cs );
1052 return S_OK;
1055 static HRESULT WINAPI path_GetScopeCount(
1056 IWbemPath *iface,
1057 ULONG *puCount)
1059 FIXME("%p, %p\n", iface, puCount);
1060 return E_NOTIMPL;
1063 static HRESULT WINAPI path_SetScope(
1064 IWbemPath *iface,
1065 ULONG uIndex,
1066 LPWSTR pszClass)
1068 FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszClass));
1069 return E_NOTIMPL;
1072 static HRESULT WINAPI path_SetScopeFromText(
1073 IWbemPath *iface,
1074 ULONG uIndex,
1075 LPWSTR pszText)
1077 FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszText));
1078 return E_NOTIMPL;
1081 static HRESULT WINAPI path_GetScope(
1082 IWbemPath *iface,
1083 ULONG uIndex,
1084 ULONG *puClassNameBufSize,
1085 LPWSTR pszClass,
1086 IWbemPathKeyList **pKeyList)
1088 FIXME("%p, %u, %p, %p, %p\n", iface, uIndex, puClassNameBufSize, pszClass, pKeyList);
1089 return E_NOTIMPL;
1092 static HRESULT WINAPI path_GetScopeAsText(
1093 IWbemPath *iface,
1094 ULONG uIndex,
1095 ULONG *puTextBufSize,
1096 LPWSTR pszText)
1098 FIXME("%p, %u, %p, %p\n", iface, uIndex, puTextBufSize, pszText);
1099 return E_NOTIMPL;
1102 static HRESULT WINAPI path_RemoveScope(
1103 IWbemPath *iface,
1104 ULONG uIndex)
1106 FIXME("%p, %u\n", iface, uIndex);
1107 return E_NOTIMPL;
1110 static HRESULT WINAPI path_RemoveAllScopes(
1111 IWbemPath *iface)
1113 FIXME("%p\n", iface);
1114 return E_NOTIMPL;
1117 static HRESULT WINAPI path_SetClassName(
1118 IWbemPath *iface,
1119 LPCWSTR name)
1121 struct path *path = impl_from_IWbemPath( iface );
1122 WCHAR *class;
1124 TRACE("%p, %s\n", iface, debugstr_w(name));
1126 if (!name) return WBEM_E_INVALID_PARAMETER;
1127 if (!(class = strdupW( name ))) return WBEM_E_OUT_OF_MEMORY;
1129 EnterCriticalSection( &path->cs );
1131 heap_free( path->class );
1132 path->class = class;
1133 path->len_class = strlenW( path->class );
1134 path->flags |= WBEMPATH_INFO_V2_COMPLIANT | WBEMPATH_INFO_CIM_COMPLIANT;
1136 LeaveCriticalSection( &path->cs );
1137 return S_OK;
1140 static HRESULT WINAPI path_GetClassName(
1141 IWbemPath *iface,
1142 ULONG *len,
1143 LPWSTR name)
1145 struct path *path = impl_from_IWbemPath( iface );
1147 TRACE("%p, %p, %p\n", iface, len, name);
1149 if (!len || (*len && !name)) return WBEM_E_INVALID_PARAMETER;
1151 EnterCriticalSection( &path->cs );
1153 if (!path->class)
1155 LeaveCriticalSection( &path->cs );
1156 return WBEM_E_INVALID_OBJECT_PATH;
1158 if (*len > path->len_class) strcpyW( name, path->class );
1159 *len = path->len_class + 1;
1161 LeaveCriticalSection( &path->cs );
1162 return S_OK;
1165 static HRESULT WINAPI path_GetKeyList(
1166 IWbemPath *iface,
1167 IWbemPathKeyList **pOut)
1169 struct path *path = impl_from_IWbemPath( iface );
1170 HRESULT hr;
1172 TRACE("%p, %p\n", iface, pOut);
1174 EnterCriticalSection( &path->cs );
1176 if (!path->class)
1178 LeaveCriticalSection( &path->cs );
1179 return WBEM_E_INVALID_PARAMETER;
1181 hr = WbemPathKeyList_create( NULL, iface, (void **)pOut );
1183 LeaveCriticalSection( &path->cs );
1184 return hr;
1187 static HRESULT WINAPI path_CreateClassPart(
1188 IWbemPath *iface,
1189 LONG lFlags,
1190 LPCWSTR Name)
1192 FIXME("%p, 0x%x, %s\n", iface, lFlags, debugstr_w(Name));
1193 return E_NOTIMPL;
1196 static HRESULT WINAPI path_DeleteClassPart(
1197 IWbemPath *iface,
1198 LONG lFlags)
1200 FIXME("%p, 0x%x\n", iface, lFlags);
1201 return E_NOTIMPL;
1204 static BOOL WINAPI path_IsRelative(
1205 IWbemPath *iface,
1206 LPWSTR wszMachine,
1207 LPWSTR wszNamespace)
1209 FIXME("%p, %s, %s\n", iface, debugstr_w(wszMachine), debugstr_w(wszNamespace));
1210 return E_NOTIMPL;
1213 static BOOL WINAPI path_IsRelativeOrChild(
1214 IWbemPath *iface,
1215 LPWSTR wszMachine,
1216 LPWSTR wszNamespace,
1217 LONG lFlags)
1219 FIXME("%p, %s, %s, 0x%x\n", iface, debugstr_w(wszMachine), debugstr_w(wszNamespace), lFlags);
1220 return E_NOTIMPL;
1223 static BOOL WINAPI path_IsLocal(
1224 IWbemPath *iface,
1225 LPCWSTR wszMachine)
1227 FIXME("%p, %s\n", iface, debugstr_w(wszMachine));
1228 return E_NOTIMPL;
1231 static BOOL WINAPI path_IsSameClassName(
1232 IWbemPath *iface,
1233 LPCWSTR wszClass)
1235 FIXME("%p, %s\n", iface, debugstr_w(wszClass));
1236 return E_NOTIMPL;
1239 static const struct IWbemPathVtbl path_vtbl =
1241 path_QueryInterface,
1242 path_AddRef,
1243 path_Release,
1244 path_SetText,
1245 path_GetText,
1246 path_GetInfo,
1247 path_SetServer,
1248 path_GetServer,
1249 path_GetNamespaceCount,
1250 path_SetNamespaceAt,
1251 path_GetNamespaceAt,
1252 path_RemoveNamespaceAt,
1253 path_RemoveAllNamespaces,
1254 path_GetScopeCount,
1255 path_SetScope,
1256 path_SetScopeFromText,
1257 path_GetScope,
1258 path_GetScopeAsText,
1259 path_RemoveScope,
1260 path_RemoveAllScopes,
1261 path_SetClassName,
1262 path_GetClassName,
1263 path_GetKeyList,
1264 path_CreateClassPart,
1265 path_DeleteClassPart,
1266 path_IsRelative,
1267 path_IsRelativeOrChild,
1268 path_IsLocal,
1269 path_IsSameClassName
1272 HRESULT WbemPath_create( IUnknown *pUnkOuter, LPVOID *ppObj )
1274 struct path *path;
1276 TRACE("%p, %p\n", pUnkOuter, ppObj);
1278 if (!(path = heap_alloc( sizeof(*path) ))) return E_OUTOFMEMORY;
1280 path->IWbemPath_iface.lpVtbl = &path_vtbl;
1281 path->refs = 1;
1282 InitializeCriticalSection( &path->cs );
1283 path->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wmiutils_path.cs");
1284 init_path( path );
1286 *ppObj = &path->IWbemPath_iface;
1288 TRACE("returning iface %p\n", *ppObj);
1289 return S_OK;