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 if (strchrW( p
, '\\' ) || strchrW( p
, '/' ))
425 if (*q
!= '\\' && *q
!= '/' && *q
!= ':')
427 path
->num_namespaces
= 1;
430 while (*q
&& *q
!= ':')
432 if (*q
== '\\' || *q
== '/') path
->num_namespaces
++;
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
;
443 if (*q
&& *q
!= '\\' && *q
!= '/' && *q
!= ':')
446 while (*p
&& *p
!= '\\' && *p
!= '/' && *p
!= ':') p
++;
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
;
455 while (*q
&& *q
!= ':')
457 if (*q
== '\\' || *q
== '/')
460 while (*p
&& *p
!= '\\' && *p
!= '/' && *p
!= ':') p
++;
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
;
473 while (*q
&& *q
!= '.') q
++;
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
;
486 if (*q
== ',') path
->num_keys
++;
489 if (!(path
->keys
= heap_alloc_zero( path
->num_keys
* sizeof(struct key
) ))) goto done
;
494 if (i
>= path
->num_keys
) break;
495 hr
= parse_key( &path
->keys
[i
], q
, &len
);
496 if (hr
!= S_OK
) goto done
;
504 if (hr
!= S_OK
) clear_path( path
);
505 else path
->flags
|= WBEMPATH_INFO_CIM_COMPLIANT
| WBEMPATH_INFO_V2_COMPLIANT
;
509 static HRESULT WINAPI
path_SetText(
514 struct path
*path
= impl_from_IWbemPath( iface
);
518 TRACE("%p, %u, %s\n", iface
, uMode
, debugstr_w(pszPath
));
520 if (!uMode
|| !pszPath
) return WBEM_E_INVALID_PARAMETER
;
522 EnterCriticalSection( &path
->cs
);
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
) )))
535 strcpyW( path
->text
, pszPath
);
536 path
->len_text
= len
;
539 LeaveCriticalSection( &path
->cs
);
543 static WCHAR
*build_namespace( struct path
*path
, int *len
, BOOL leading_slash
)
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
];
565 static WCHAR
*build_server( struct path
*path
, int *len
)
570 if (path
->len_server
) *len
+= 2 + path
->len_server
;
572 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
573 if (path
->len_server
)
576 strcpyW( p
+ 2, path
->server
);
586 static WCHAR
*build_keylist( struct path
*path
, int *len
)
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
;
604 memcpy( p
, path
->keys
[i
].value
, path
->keys
[i
].len_value
* sizeof(WCHAR
) );
605 p
+= path
->keys
[i
].len_value
;
611 static WCHAR
*build_path( struct path
*path
, LONG flags
, int *len
)
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
);
628 *len
= len_namespace
;
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
);
640 strcpyW( ret
, namespace );
643 ret
[len_namespace
] = ':';
644 strcpyW( ret
+ len_namespace
+ 1, path
->class );
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
);
656 case WBEMPATH_GET_RELATIVE_ONLY
:
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
);
671 strcpyW( ret
, path
->class );
674 ret
[path
->len_class
] = '.';
675 strcpyW( ret
+ path
->len_class
+ 1, keylist
);
677 heap_free( keylist
);
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 );
691 heap_free( keylist
);
694 *len
= len_namespace
+ len_server
;
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 );
704 heap_free( keylist
);
707 strcpyW( p
, server
);
709 strcpyW( p
, namespace );
714 strcpyW( p
, path
->class );
717 p
[path
->len_class
] = '.';
718 strcpyW( p
+ path
->len_class
+ 1, keylist
);
721 heap_free( namespace );
723 heap_free( keylist
);
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 );
738 *len
= len_namespace
+ len_server
;
739 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
741 heap_free( namespace );
745 strcpyW( p
, server
);
747 strcpyW( p
, namespace );
748 heap_free( namespace );
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
);
761 ERR("unhandled flags 0x%x\n", flags
);
766 static HRESULT WINAPI
path_GetText(
769 ULONG
*puBufferLength
,
772 struct path
*path
= impl_from_IWbemPath( iface
);
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;
791 hr
= WBEM_E_INVALID_PARAMETER
;
794 if (str
) strcpyW( pszText
, str
);
796 *puBufferLength
= len
+ 1;
798 TRACE("returning %s\n", debugstr_w(pszText
));
802 LeaveCriticalSection( &path
->cs
);
806 static HRESULT WINAPI
path_GetInfo(
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
;
825 *response
|= WBEMPATH_INFO_HAS_MACHINE_NAME
;
828 *response
|= WBEMPATH_INFO_SERVER_NAMESPACE_ONLY
;
831 *response
|= WBEMPATH_INFO_HAS_SUBSCOPES
;
833 *response
|= WBEMPATH_INFO_IS_INST_REF
;
835 *response
|= WBEMPATH_INFO_IS_CLASS_REF
;
838 LeaveCriticalSection( &path
->cs
);
842 static HRESULT WINAPI
path_SetServer(
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
;
852 TRACE("%p, %s\n", iface
, debugstr_w(name
));
854 EnterCriticalSection( &path
->cs
);
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
;
870 heap_free( path
->server
);
872 path
->len_server
= 0;
873 path
->flags
&= ~flags
;
876 LeaveCriticalSection( &path
->cs
);
880 static HRESULT WINAPI
path_GetServer(
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
);
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
);
905 static HRESULT WINAPI
path_GetNamespaceCount(
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
);
921 static HRESULT WINAPI
path_SetNamespaceAt(
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
;
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
);
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
);
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
);
982 static HRESULT WINAPI
path_GetNamespaceAt(
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
);
1006 static HRESULT WINAPI
path_RemoveNamespaceAt(
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];
1028 path
->num_namespaces
--;
1030 LeaveCriticalSection( &path
->cs
);
1034 static HRESULT WINAPI
path_RemoveAllNamespaces(
1037 struct path
*path
= impl_from_IWbemPath( iface
);
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
);
1055 static HRESULT WINAPI
path_GetScopeCount(
1059 FIXME("%p, %p\n", iface
, puCount
);
1063 static HRESULT WINAPI
path_SetScope(
1068 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszClass
));
1072 static HRESULT WINAPI
path_SetScopeFromText(
1077 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszText
));
1081 static HRESULT WINAPI
path_GetScope(
1084 ULONG
*puClassNameBufSize
,
1086 IWbemPathKeyList
**pKeyList
)
1088 FIXME("%p, %u, %p, %p, %p\n", iface
, uIndex
, puClassNameBufSize
, pszClass
, pKeyList
);
1092 static HRESULT WINAPI
path_GetScopeAsText(
1095 ULONG
*puTextBufSize
,
1098 FIXME("%p, %u, %p, %p\n", iface
, uIndex
, puTextBufSize
, pszText
);
1102 static HRESULT WINAPI
path_RemoveScope(
1106 FIXME("%p, %u\n", iface
, uIndex
);
1110 static HRESULT WINAPI
path_RemoveAllScopes(
1113 FIXME("%p\n", iface
);
1117 static HRESULT WINAPI
path_SetClassName(
1121 struct path
*path
= impl_from_IWbemPath( iface
);
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
);
1140 static HRESULT WINAPI
path_GetClassName(
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
);
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
);
1165 static HRESULT WINAPI
path_GetKeyList(
1167 IWbemPathKeyList
**pOut
)
1169 struct path
*path
= impl_from_IWbemPath( iface
);
1172 TRACE("%p, %p\n", iface
, pOut
);
1174 EnterCriticalSection( &path
->cs
);
1178 LeaveCriticalSection( &path
->cs
);
1179 return WBEM_E_INVALID_PARAMETER
;
1181 hr
= WbemPathKeyList_create( NULL
, iface
, (void **)pOut
);
1183 LeaveCriticalSection( &path
->cs
);
1187 static HRESULT WINAPI
path_CreateClassPart(
1192 FIXME("%p, 0x%x, %s\n", iface
, lFlags
, debugstr_w(Name
));
1196 static HRESULT WINAPI
path_DeleteClassPart(
1200 FIXME("%p, 0x%x\n", iface
, lFlags
);
1204 static BOOL WINAPI
path_IsRelative(
1207 LPWSTR wszNamespace
)
1209 FIXME("%p, %s, %s\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
));
1213 static BOOL WINAPI
path_IsRelativeOrChild(
1216 LPWSTR wszNamespace
,
1219 FIXME("%p, %s, %s, 0x%x\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
), lFlags
);
1223 static BOOL WINAPI
path_IsLocal(
1227 FIXME("%p, %s\n", iface
, debugstr_w(wszMachine
));
1231 static BOOL WINAPI
path_IsSameClassName(
1235 FIXME("%p, %s\n", iface
, debugstr_w(wszClass
));
1239 static const struct IWbemPathVtbl path_vtbl
=
1241 path_QueryInterface
,
1249 path_GetNamespaceCount
,
1250 path_SetNamespaceAt
,
1251 path_GetNamespaceAt
,
1252 path_RemoveNamespaceAt
,
1253 path_RemoveAllNamespaces
,
1256 path_SetScopeFromText
,
1258 path_GetScopeAsText
,
1260 path_RemoveAllScopes
,
1264 path_CreateClassPart
,
1265 path_DeleteClassPart
,
1267 path_IsRelativeOrChild
,
1269 path_IsSameClassName
1272 HRESULT
WbemPath_create( IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
1276 TRACE("%p, %p\n", pUnkOuter
, ppObj
);
1278 if (!(path
= heap_alloc( sizeof(*path
) ))) return E_OUTOFMEMORY
;
1280 path
->IWbemPath_iface
.lpVtbl
= &path_vtbl
;
1282 InitializeCriticalSection( &path
->cs
);
1283 path
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": wmiutils_path.cs");
1286 *ppObj
= &path
->IWbemPath_iface
;
1288 TRACE("returning iface %p\n", *ppObj
);