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 IWbemPathKeyList IWbemPathKeyList_iface
;
52 IWbemPath IWbemPath_iface
;
65 unsigned int num_keys
;
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
);
93 TRACE("destroying %p\n", keylist
);
94 IWbemPath_Release( keylist
->parent
);
100 static HRESULT WINAPI
keylist_QueryInterface(
101 IWbemPathKeyList
*iface
,
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
))
116 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
117 return E_NOINTERFACE
;
119 IWbemPathKeyList_AddRef( iface
);
123 static HRESULT WINAPI
keylist_GetCount(
124 IWbemPathKeyList
*iface
,
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
);
142 static HRESULT WINAPI
keylist_SetKey(
143 IWbemPathKeyList
*iface
,
149 FIXME("%p, %s, 0x%x, %u, %p\n", iface
, debugstr_w(wszName
), uFlags
, uCimType
, pKeyVal
);
153 static HRESULT WINAPI
keylist_SetKey2(
154 IWbemPathKeyList
*iface
,
160 FIXME("%p, %s, 0x%x, %u, %p\n", iface
, debugstr_w(wszName
), uFlags
, uCimType
, pKeyVal
);
164 static HRESULT WINAPI
keylist_GetKey(
165 IWbemPathKeyList
*iface
,
168 ULONG
*puNameBufSize
,
170 ULONG
*puKeyValBufSize
,
172 ULONG
*puApparentCimType
)
174 FIXME("%p, %u, 0x%x, %p, %p, %p, %p, %p\n", iface
, uKeyIx
, uFlags
, puNameBufSize
,
175 pszKeyName
, puKeyValBufSize
, pKeyVal
, puApparentCimType
);
179 static HRESULT WINAPI
keylist_GetKey2(
180 IWbemPathKeyList
*iface
,
183 ULONG
*puNameBufSize
,
186 ULONG
*puApparentCimType
)
188 FIXME("%p, %u, 0x%x, %p, %p, %p, %p\n", iface
, uKeyIx
, uFlags
, puNameBufSize
,
189 pszKeyName
, pKeyValue
, puApparentCimType
);
193 static HRESULT WINAPI
keylist_RemoveKey(
194 IWbemPathKeyList
*iface
,
198 FIXME("%p, %s, 0x%x\n", iface
, debugstr_w(wszName
), uFlags
);
202 static void free_keys( struct key
*keys
, unsigned int count
)
206 for (i
= 0; i
< count
; i
++)
208 heap_free( keys
[i
].name
);
209 heap_free( keys
[i
].value
);
214 static HRESULT WINAPI
keylist_RemoveAllKeys(
215 IWbemPathKeyList
*iface
,
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;
231 LeaveCriticalSection( &parent
->cs
);
235 static HRESULT WINAPI
keylist_MakeSingleton(
236 IWbemPathKeyList
*iface
,
239 FIXME("%p, %d\n", iface
, bSet
);
243 static HRESULT WINAPI
keylist_GetInfo(
244 IWbemPathKeyList
*iface
,
245 ULONG uRequestedInfo
,
246 ULONGLONG
*puResponse
)
248 FIXME("%p, %u, %p\n", iface
, uRequestedInfo
, puResponse
);
252 static HRESULT WINAPI
keylist_GetText(
253 IWbemPathKeyList
*iface
,
258 FIXME("%p, 0x%x, %p, %p\n", iface
, lFlags
, puBuffLength
, pszText
);
262 static const struct IWbemPathKeyListVtbl keylist_vtbl
=
264 keylist_QueryInterface
,
273 keylist_RemoveAllKeys
,
274 keylist_MakeSingleton
,
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
;
289 keylist
->parent
= parent
;
290 IWbemPath_AddRef( keylist
->parent
);
292 *ppObj
= &keylist
->IWbemPathKeyList_iface
;
294 TRACE("returning iface %p\n", *ppObj
);
298 static void init_path( struct path
*path
)
303 path
->len_server
= 0;
304 path
->namespaces
= NULL
;
305 path
->len_namespaces
= NULL
;
306 path
->num_namespaces
= 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
);
325 static ULONG WINAPI
path_AddRef(
328 struct path
*path
= impl_from_IWbemPath( iface
);
329 return InterlockedIncrement( &path
->refs
);
332 static ULONG WINAPI
path_Release(
335 struct path
*path
= impl_from_IWbemPath( iface
);
336 LONG refs
= InterlockedDecrement( &path
->refs
);
339 TRACE("destroying %p\n", path
);
341 path
->cs
.DebugInfo
->Spare
[0] = 0;
342 DeleteCriticalSection( &path
->cs
);
348 static HRESULT WINAPI
path_QueryInterface(
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
) )
364 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
365 return E_NOINTERFACE
;
367 IWbemPath_AddRef( iface
);
371 static HRESULT
parse_key( struct key
*key
, const WCHAR
*str
, unsigned int *ret_len
)
377 while (*q
&& *q
!= '=')
379 if (*q
== ',' || isspaceW( *q
)) return WBEM_E_INVALID_PARAMETER
;
383 if (!(key
->name
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) return E_OUTOFMEMORY
;
384 memcpy( key
->name
, p
, len
* sizeof(WCHAR
) );
389 if (!*p
|| *p
== ',' || isspaceW( *p
)) return WBEM_E_INVALID_PARAMETER
;
391 while (*q
&& *q
!= ',') q
++;
393 if (!(key
->value
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) return E_OUTOFMEMORY
;
394 memcpy( key
->value
, p
, len
* sizeof(WCHAR
) );
396 key
->len_value
= len
;
399 if (*q
== ',') (*ret_len
)++;
403 static HRESULT
parse_text( struct path
*path
, ULONG mode
, const WCHAR
*text
)
405 HRESULT hr
= E_OUTOFMEMORY
;
410 if ((p
[0] == '\\' && p
[1] == '\\') || (p
[0] == '/' && p
[1] == '/'))
414 while (*q
&& *q
!= '\\' && *q
!= '/') q
++;
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
;
423 while (*q
&& *q
!= ':')
425 if (*q
== '\\' || *q
== '/') path
->num_namespaces
++;
428 if (path
->num_namespaces
)
430 if (!(path
->namespaces
= heap_alloc( path
->num_namespaces
* sizeof(WCHAR
*) ))) goto done
;
431 if (!(path
->len_namespaces
= heap_alloc( path
->num_namespaces
* sizeof(int) ))) goto done
;
435 while (*q
&& *q
!= ':')
437 if (*q
== '\\' || *q
== '/')
440 while (*p
&& *p
!= '\\' && *p
!= '/' && *p
!= ':') p
++;
442 if (!(path
->namespaces
[i
] = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
443 memcpy( path
->namespaces
[i
], q
+ 1, len
* sizeof(WCHAR
) );
444 path
->namespaces
[i
][len
] = 0;
445 path
->len_namespaces
[i
] = len
;
453 while (*q
&& *q
!= '.') q
++;
455 if (!(path
->class = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
456 memcpy( path
->class, p
, len
* sizeof(WCHAR
) );
457 path
->class[len
] = 0;
458 path
->len_class
= len
;
466 if (*q
== ',') path
->num_keys
++;
469 if (!(path
->keys
= heap_alloc_zero( path
->num_keys
* sizeof(struct key
) ))) goto done
;
474 if (i
>= path
->num_keys
) break;
475 hr
= parse_key( &path
->keys
[i
], q
, &len
);
476 if (hr
!= S_OK
) goto done
;
484 if (hr
!= S_OK
) clear_path( path
);
485 else path
->flags
|= WBEMPATH_INFO_CIM_COMPLIANT
| WBEMPATH_INFO_V2_COMPLIANT
;
489 static HRESULT WINAPI
path_SetText(
494 struct path
*path
= impl_from_IWbemPath( iface
);
498 TRACE("%p, %u, %s\n", iface
, uMode
, debugstr_w(pszPath
));
500 if (!uMode
|| !pszPath
) return WBEM_E_INVALID_PARAMETER
;
502 EnterCriticalSection( &path
->cs
);
505 if (!pszPath
[0]) goto done
;
506 if ((hr
= parse_text( path
, uMode
, pszPath
)) != S_OK
) goto done
;
508 len
= strlenW( pszPath
);
509 if (!(path
->text
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) )))
515 strcpyW( path
->text
, pszPath
);
516 path
->len_text
= len
;
519 LeaveCriticalSection( &path
->cs
);
523 static WCHAR
*build_namespace( struct path
*path
, int *len
, BOOL leading_slash
)
529 for (i
= 0; i
< path
->num_namespaces
; i
++)
531 if (i
> 0 || leading_slash
) *len
+= 1;
532 *len
+= path
->len_namespaces
[i
];
534 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
535 for (i
= 0; i
< path
->num_namespaces
; i
++)
537 if (i
> 0 || leading_slash
) *p
++ = '\\';
538 memcpy( p
, path
->namespaces
[i
], path
->len_namespaces
[i
] * sizeof(WCHAR
) );
539 p
+= path
->len_namespaces
[i
];
545 static WCHAR
*build_server( struct path
*path
, int *len
)
550 if (path
->len_server
) *len
+= 2 + path
->len_server
;
552 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
553 if (path
->len_server
)
556 strcpyW( p
+ 2, path
->server
);
566 static WCHAR
*build_keylist( struct path
*path
, int *len
)
572 for (i
= 0; i
< path
->num_keys
; i
++)
574 if (i
> 0) *len
+= 1;
575 *len
+= path
->keys
[i
].len_name
+ path
->keys
[i
].len_value
+ 1;
577 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
578 for (i
= 0; i
< path
->num_keys
; i
++)
580 if (i
> 0) *p
++ = ',';
581 memcpy( p
, path
->keys
[i
].name
, path
->keys
[i
].len_name
* sizeof(WCHAR
) );
582 p
+= path
->keys
[i
].len_name
;
584 memcpy( p
, path
->keys
[i
].value
, path
->keys
[i
].len_value
* sizeof(WCHAR
) );
585 p
+= path
->keys
[i
].len_value
;
591 static WCHAR
*build_path( struct path
*path
, LONG flags
, int *len
)
598 int len_namespace
, len_keylist
;
599 WCHAR
*ret
, *namespace = build_namespace( path
, &len_namespace
, FALSE
);
600 WCHAR
*keylist
= build_keylist( path
, &len_keylist
);
602 if (!namespace || !keylist
)
604 heap_free( namespace );
605 heap_free( keylist
);
608 *len
= len_namespace
;
611 *len
+= path
->len_class
+ 1;
612 if (path
->num_keys
) *len
+= len_keylist
+ 1;
614 if (!(ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
616 heap_free( namespace );
617 heap_free( keylist
);
620 strcpyW( ret
, namespace );
623 ret
[len_namespace
] = ':';
624 strcpyW( ret
+ len_namespace
+ 1, path
->class );
627 ret
[len_namespace
+ path
->len_class
+ 1] = '.';
628 strcpyW( ret
+ len_namespace
+ path
->len_class
+ 2, keylist
);
631 heap_free( namespace );
632 heap_free( keylist
);
636 case WBEMPATH_GET_RELATIVE_ONLY
:
639 WCHAR
*ret
, *keylist
;
641 if (!path
->len_class
) return NULL
;
642 if (!(keylist
= build_keylist( path
, &len_keylist
))) return NULL
;
644 *len
= path
->len_class
;
645 if (path
->num_keys
) *len
+= len_keylist
+ 1;
646 if (!(ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
648 heap_free( keylist
);
651 strcpyW( ret
, path
->class );
654 ret
[path
->len_class
] = '.';
655 strcpyW( ret
+ path
->len_class
+ 1, keylist
);
657 heap_free( keylist
);
660 case WBEMPATH_GET_SERVER_TOO
:
662 int len_namespace
, len_server
, len_keylist
;
663 WCHAR
*p
, *ret
, *namespace = build_namespace( path
, &len_namespace
, TRUE
);
664 WCHAR
*server
= build_server( path
, &len_server
);
665 WCHAR
*keylist
= build_keylist( path
, &len_keylist
);
667 if (!namespace || !server
|| !keylist
)
669 heap_free( namespace );
671 heap_free( keylist
);
674 *len
= len_namespace
+ len_server
;
677 *len
+= path
->len_class
+ 1;
678 if (path
->num_keys
) *len
+= len_keylist
+ 1;
680 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
682 heap_free( namespace );
684 heap_free( keylist
);
687 strcpyW( p
, server
);
689 strcpyW( p
, namespace );
694 strcpyW( p
, path
->class );
697 p
[path
->len_class
] = '.';
698 strcpyW( p
+ path
->len_class
+ 1, keylist
);
701 heap_free( namespace );
703 heap_free( keylist
);
706 case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY
:
708 int len_namespace
, len_server
;
709 WCHAR
*p
, *ret
, *namespace = build_namespace( path
, &len_namespace
, TRUE
);
710 WCHAR
*server
= build_server( path
, &len_server
);
712 if (!namespace || !server
)
714 heap_free( namespace );
718 *len
= len_namespace
+ len_server
;
719 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
721 heap_free( namespace );
725 strcpyW( p
, server
);
727 strcpyW( p
, namespace );
728 heap_free( namespace );
732 case WBEMPATH_GET_NAMESPACE_ONLY
:
733 return build_namespace( path
, len
, FALSE
);
735 case WBEMPATH_GET_ORIGINAL
:
736 if (!path
->len_text
) return NULL
;
737 *len
= path
->len_text
;
738 return strdupW( path
->text
);
741 ERR("unhandled flags 0x%x\n", flags
);
746 static HRESULT WINAPI
path_GetText(
749 ULONG
*puBufferLength
,
752 struct path
*path
= impl_from_IWbemPath( iface
);
757 TRACE("%p, 0x%x, %p, %p\n", iface
, lFlags
, puBufferLength
, pszText
);
759 if (!puBufferLength
) return WBEM_E_INVALID_PARAMETER
;
761 EnterCriticalSection( &path
->cs
);
763 str
= build_path( path
, lFlags
, &len
);
764 if (*puBufferLength
< len
+ 1)
766 *puBufferLength
= len
+ 1;
771 hr
= WBEM_E_INVALID_PARAMETER
;
774 if (str
) strcpyW( pszText
, str
);
776 *puBufferLength
= len
+ 1;
778 TRACE("returning %s\n", debugstr_w(pszText
));
782 LeaveCriticalSection( &path
->cs
);
786 static HRESULT WINAPI
path_GetInfo(
791 struct path
*path
= impl_from_IWbemPath( iface
);
793 TRACE("%p, %u, %p\n", iface
, info
, response
);
795 if (info
|| !response
) return WBEM_E_INVALID_PARAMETER
;
797 FIXME("some flags are not implemented\n");
799 EnterCriticalSection( &path
->cs
);
801 *response
= path
->flags
;
802 if (!path
->server
|| (path
->len_server
== 1 && path
->server
[0] == '.'))
803 *response
|= WBEMPATH_INFO_ANON_LOCAL_MACHINE
;
805 *response
|= WBEMPATH_INFO_HAS_MACHINE_NAME
;
808 *response
|= WBEMPATH_INFO_SERVER_NAMESPACE_ONLY
;
811 *response
|= WBEMPATH_INFO_HAS_SUBSCOPES
;
813 *response
|= WBEMPATH_INFO_IS_INST_REF
;
815 *response
|= WBEMPATH_INFO_IS_CLASS_REF
;
818 LeaveCriticalSection( &path
->cs
);
822 static HRESULT WINAPI
path_SetServer(
826 struct path
*path
= impl_from_IWbemPath( iface
);
827 static const ULONGLONG flags
=
828 WBEMPATH_INFO_PATH_HAD_SERVER
| WBEMPATH_INFO_V1_COMPLIANT
|
829 WBEMPATH_INFO_V2_COMPLIANT
| WBEMPATH_INFO_CIM_COMPLIANT
;
832 TRACE("%p, %s\n", iface
, debugstr_w(name
));
834 EnterCriticalSection( &path
->cs
);
838 if (!(server
= strdupW( name
)))
840 LeaveCriticalSection( &path
->cs
);
841 return WBEM_E_OUT_OF_MEMORY
;
843 heap_free( path
->server
);
844 path
->server
= server
;
845 path
->len_server
= strlenW( path
->server
);
846 path
->flags
|= flags
;
850 heap_free( path
->server
);
852 path
->len_server
= 0;
853 path
->flags
&= ~flags
;
856 LeaveCriticalSection( &path
->cs
);
860 static HRESULT WINAPI
path_GetServer(
865 struct path
*path
= impl_from_IWbemPath( iface
);
867 TRACE("%p, %p, %p\n", iface
, len
, name
);
869 if (!len
|| (*len
&& !name
)) return WBEM_E_INVALID_PARAMETER
;
871 EnterCriticalSection( &path
->cs
);
875 LeaveCriticalSection( &path
->cs
);
876 return WBEM_E_NOT_AVAILABLE
;
878 if (*len
> path
->len_server
) strcpyW( name
, path
->server
);
879 *len
= path
->len_server
+ 1;
881 LeaveCriticalSection( &path
->cs
);
885 static HRESULT WINAPI
path_GetNamespaceCount(
889 struct path
*path
= impl_from_IWbemPath( iface
);
891 TRACE("%p, %p\n", iface
, puCount
);
893 if (!puCount
) return WBEM_E_INVALID_PARAMETER
;
895 EnterCriticalSection( &path
->cs
);
896 *puCount
= path
->num_namespaces
;
897 LeaveCriticalSection( &path
->cs
);
901 static HRESULT WINAPI
path_SetNamespaceAt(
906 struct path
*path
= impl_from_IWbemPath( iface
);
907 static const ULONGLONG flags
=
908 WBEMPATH_INFO_V1_COMPLIANT
| WBEMPATH_INFO_V2_COMPLIANT
|
909 WBEMPATH_INFO_CIM_COMPLIANT
;
914 TRACE("%p, %u, %s\n", iface
, idx
, debugstr_w(name
));
916 EnterCriticalSection( &path
->cs
);
918 if (idx
> path
->num_namespaces
|| !name
)
920 LeaveCriticalSection( &path
->cs
);
921 return WBEM_E_INVALID_PARAMETER
;
923 if (!(new = strdupW( name
)))
925 LeaveCriticalSection( &path
->cs
);
926 return WBEM_E_OUT_OF_MEMORY
;
928 size
= (path
->num_namespaces
+ 1) * sizeof(WCHAR
*);
929 if (path
->namespaces
) tmp
= heap_realloc( path
->namespaces
, size
);
930 else tmp
= heap_alloc( size
);
934 LeaveCriticalSection( &path
->cs
);
935 return WBEM_E_OUT_OF_MEMORY
;
937 path
->namespaces
= tmp
;
938 size
= (path
->num_namespaces
+ 1) * sizeof(int);
939 if (path
->len_namespaces
) tmp_len
= heap_realloc( path
->len_namespaces
, size
);
940 else tmp_len
= heap_alloc( size
);
944 LeaveCriticalSection( &path
->cs
);
945 return WBEM_E_OUT_OF_MEMORY
;
947 path
->len_namespaces
= tmp_len
;
948 for (i
= idx
; i
< path
->num_namespaces
; i
++)
950 path
->namespaces
[i
+ 1] = path
->namespaces
[i
];
951 path
->len_namespaces
[i
+ 1] = path
->len_namespaces
[i
];
953 path
->namespaces
[idx
] = new;
954 path
->len_namespaces
[idx
] = strlenW( new );
955 path
->num_namespaces
++;
956 path
->flags
|= flags
;
958 LeaveCriticalSection( &path
->cs
);
962 static HRESULT WINAPI
path_GetNamespaceAt(
968 struct path
*path
= impl_from_IWbemPath( iface
);
970 TRACE("%p, %u, %p, %p\n", iface
, idx
, len
, name
);
972 EnterCriticalSection( &path
->cs
);
974 if (!len
|| (*len
&& !name
) || idx
>= path
->num_namespaces
)
976 LeaveCriticalSection( &path
->cs
);
977 return WBEM_E_INVALID_PARAMETER
;
979 if (*len
> path
->len_namespaces
[idx
]) strcpyW( name
, path
->namespaces
[idx
] );
980 *len
= path
->len_namespaces
[idx
] + 1;
982 LeaveCriticalSection( &path
->cs
);
986 static HRESULT WINAPI
path_RemoveNamespaceAt(
990 struct path
*path
= impl_from_IWbemPath( iface
);
992 TRACE("%p, %u\n", iface
, idx
);
994 EnterCriticalSection( &path
->cs
);
996 if (idx
>= path
->num_namespaces
)
998 LeaveCriticalSection( &path
->cs
);
999 return WBEM_E_INVALID_PARAMETER
;
1001 heap_free( path
->namespaces
[idx
] );
1002 while (idx
< path
->num_namespaces
- 1)
1004 path
->namespaces
[idx
] = path
->namespaces
[idx
+ 1];
1005 path
->len_namespaces
[idx
] = path
->len_namespaces
[idx
+ 1];
1008 path
->num_namespaces
--;
1010 LeaveCriticalSection( &path
->cs
);
1014 static HRESULT WINAPI
path_RemoveAllNamespaces(
1017 struct path
*path
= impl_from_IWbemPath( iface
);
1020 TRACE("%p\n", iface
);
1022 EnterCriticalSection( &path
->cs
);
1024 for (i
= 0; i
< path
->num_namespaces
; i
++) heap_free( path
->namespaces
[i
] );
1025 path
->num_namespaces
= 0;
1026 heap_free( path
->namespaces
);
1027 path
->namespaces
= NULL
;
1028 heap_free( path
->len_namespaces
);
1029 path
->len_namespaces
= NULL
;
1031 LeaveCriticalSection( &path
->cs
);
1035 static HRESULT WINAPI
path_GetScopeCount(
1039 FIXME("%p, %p\n", iface
, puCount
);
1043 static HRESULT WINAPI
path_SetScope(
1048 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszClass
));
1052 static HRESULT WINAPI
path_SetScopeFromText(
1057 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszText
));
1061 static HRESULT WINAPI
path_GetScope(
1064 ULONG
*puClassNameBufSize
,
1066 IWbemPathKeyList
**pKeyList
)
1068 FIXME("%p, %u, %p, %p, %p\n", iface
, uIndex
, puClassNameBufSize
, pszClass
, pKeyList
);
1072 static HRESULT WINAPI
path_GetScopeAsText(
1075 ULONG
*puTextBufSize
,
1078 FIXME("%p, %u, %p, %p\n", iface
, uIndex
, puTextBufSize
, pszText
);
1082 static HRESULT WINAPI
path_RemoveScope(
1086 FIXME("%p, %u\n", iface
, uIndex
);
1090 static HRESULT WINAPI
path_RemoveAllScopes(
1093 FIXME("%p\n", iface
);
1097 static HRESULT WINAPI
path_SetClassName(
1101 struct path
*path
= impl_from_IWbemPath( iface
);
1104 TRACE("%p, %s\n", iface
, debugstr_w(name
));
1106 if (!name
) return WBEM_E_INVALID_PARAMETER
;
1107 if (!(class = strdupW( name
))) return WBEM_E_OUT_OF_MEMORY
;
1109 EnterCriticalSection( &path
->cs
);
1111 heap_free( path
->class );
1112 path
->class = class;
1113 path
->len_class
= strlenW( path
->class );
1114 path
->flags
|= WBEMPATH_INFO_V2_COMPLIANT
| WBEMPATH_INFO_CIM_COMPLIANT
;
1116 LeaveCriticalSection( &path
->cs
);
1120 static HRESULT WINAPI
path_GetClassName(
1125 struct path
*path
= impl_from_IWbemPath( iface
);
1127 TRACE("%p, %p, %p\n", iface
, len
, name
);
1129 if (!len
|| (*len
&& !name
)) return WBEM_E_INVALID_PARAMETER
;
1131 EnterCriticalSection( &path
->cs
);
1135 LeaveCriticalSection( &path
->cs
);
1136 return WBEM_E_INVALID_OBJECT_PATH
;
1138 if (*len
> path
->len_class
) strcpyW( name
, path
->class );
1139 *len
= path
->len_class
+ 1;
1141 LeaveCriticalSection( &path
->cs
);
1145 static HRESULT WINAPI
path_GetKeyList(
1147 IWbemPathKeyList
**pOut
)
1149 struct path
*path
= impl_from_IWbemPath( iface
);
1152 TRACE("%p, %p\n", iface
, pOut
);
1154 EnterCriticalSection( &path
->cs
);
1158 LeaveCriticalSection( &path
->cs
);
1159 return WBEM_E_INVALID_PARAMETER
;
1161 hr
= WbemPathKeyList_create( NULL
, iface
, (void **)pOut
);
1163 LeaveCriticalSection( &path
->cs
);
1167 static HRESULT WINAPI
path_CreateClassPart(
1172 FIXME("%p, 0x%x, %s\n", iface
, lFlags
, debugstr_w(Name
));
1176 static HRESULT WINAPI
path_DeleteClassPart(
1180 FIXME("%p, 0x%x\n", iface
, lFlags
);
1184 static BOOL WINAPI
path_IsRelative(
1187 LPWSTR wszNamespace
)
1189 FIXME("%p, %s, %s\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
));
1193 static BOOL WINAPI
path_IsRelativeOrChild(
1196 LPWSTR wszNamespace
,
1199 FIXME("%p, %s, %s, 0x%x\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
), lFlags
);
1203 static BOOL WINAPI
path_IsLocal(
1207 FIXME("%p, %s\n", iface
, debugstr_w(wszMachine
));
1211 static BOOL WINAPI
path_IsSameClassName(
1215 FIXME("%p, %s\n", iface
, debugstr_w(wszClass
));
1219 static const struct IWbemPathVtbl path_vtbl
=
1221 path_QueryInterface
,
1229 path_GetNamespaceCount
,
1230 path_SetNamespaceAt
,
1231 path_GetNamespaceAt
,
1232 path_RemoveNamespaceAt
,
1233 path_RemoveAllNamespaces
,
1236 path_SetScopeFromText
,
1238 path_GetScopeAsText
,
1240 path_RemoveAllScopes
,
1244 path_CreateClassPart
,
1245 path_DeleteClassPart
,
1247 path_IsRelativeOrChild
,
1249 path_IsSameClassName
1252 HRESULT
WbemPath_create( IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
1256 TRACE("%p, %p\n", pUnkOuter
, ppObj
);
1258 if (!(path
= heap_alloc( sizeof(*path
) ))) return E_OUTOFMEMORY
;
1260 path
->IWbemPath_iface
.lpVtbl
= &path_vtbl
;
1262 InitializeCriticalSection( &path
->cs
);
1263 path
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": wmiutils_path.cs");
1266 *ppObj
= &path
->IWbemPath_iface
;
1268 TRACE("returning iface %p\n", *ppObj
);