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 (*q
&& *q
!= '\\' && *q
!= '/' && *q
!= ':')
425 path
->num_namespaces
= 1;
428 while (*q
&& *q
!= ':')
430 if (*q
== '\\' || *q
== '/') path
->num_namespaces
++;
433 if (path
->num_namespaces
)
435 if (!(path
->namespaces
= heap_alloc( path
->num_namespaces
* sizeof(WCHAR
*) ))) goto done
;
436 if (!(path
->len_namespaces
= heap_alloc( path
->num_namespaces
* sizeof(int) ))) goto done
;
440 if (*q
&& *q
!= '\\' && *q
!= '/' && *q
!= ':')
443 while (*p
&& *p
!= '\\' && *p
!= '/' && *p
!= ':') p
++;
445 if (!(path
->namespaces
[i
] = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
446 memcpy( path
->namespaces
[i
], q
, len
* sizeof(WCHAR
) );
447 path
->namespaces
[i
][len
] = 0;
448 path
->len_namespaces
[i
] = len
;
452 while (*q
&& *q
!= ':')
454 if (*q
== '\\' || *q
== '/')
457 while (*p
&& *p
!= '\\' && *p
!= '/' && *p
!= ':') p
++;
459 if (!(path
->namespaces
[i
] = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
460 memcpy( path
->namespaces
[i
], q
+ 1, len
* sizeof(WCHAR
) );
461 path
->namespaces
[i
][len
] = 0;
462 path
->len_namespaces
[i
] = len
;
470 while (*q
&& *q
!= '.') q
++;
472 if (!(path
->class = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
473 memcpy( path
->class, p
, len
* sizeof(WCHAR
) );
474 path
->class[len
] = 0;
475 path
->len_class
= len
;
483 if (*q
== ',') path
->num_keys
++;
486 if (!(path
->keys
= heap_alloc_zero( path
->num_keys
* sizeof(struct key
) ))) goto done
;
491 if (i
>= path
->num_keys
) break;
492 hr
= parse_key( &path
->keys
[i
], q
, &len
);
493 if (hr
!= S_OK
) goto done
;
501 if (hr
!= S_OK
) clear_path( path
);
502 else path
->flags
|= WBEMPATH_INFO_CIM_COMPLIANT
| WBEMPATH_INFO_V2_COMPLIANT
;
506 static HRESULT WINAPI
path_SetText(
511 struct path
*path
= impl_from_IWbemPath( iface
);
515 TRACE("%p, %u, %s\n", iface
, uMode
, debugstr_w(pszPath
));
517 if (!uMode
|| !pszPath
) return WBEM_E_INVALID_PARAMETER
;
519 EnterCriticalSection( &path
->cs
);
522 if (!pszPath
[0]) goto done
;
523 if ((hr
= parse_text( path
, uMode
, pszPath
)) != S_OK
) goto done
;
525 len
= strlenW( pszPath
);
526 if (!(path
->text
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) )))
532 strcpyW( path
->text
, pszPath
);
533 path
->len_text
= len
;
536 LeaveCriticalSection( &path
->cs
);
540 static WCHAR
*build_namespace( struct path
*path
, int *len
, BOOL leading_slash
)
546 for (i
= 0; i
< path
->num_namespaces
; i
++)
548 if (i
> 0 || leading_slash
) *len
+= 1;
549 *len
+= path
->len_namespaces
[i
];
551 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
552 for (i
= 0; i
< path
->num_namespaces
; i
++)
554 if (i
> 0 || leading_slash
) *p
++ = '\\';
555 memcpy( p
, path
->namespaces
[i
], path
->len_namespaces
[i
] * sizeof(WCHAR
) );
556 p
+= path
->len_namespaces
[i
];
562 static WCHAR
*build_server( struct path
*path
, int *len
)
567 if (path
->len_server
) *len
+= 2 + path
->len_server
;
569 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
570 if (path
->len_server
)
573 strcpyW( p
+ 2, path
->server
);
583 static WCHAR
*build_keylist( struct path
*path
, int *len
)
589 for (i
= 0; i
< path
->num_keys
; i
++)
591 if (i
> 0) *len
+= 1;
592 *len
+= path
->keys
[i
].len_name
+ path
->keys
[i
].len_value
+ 1;
594 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
595 for (i
= 0; i
< path
->num_keys
; i
++)
597 if (i
> 0) *p
++ = ',';
598 memcpy( p
, path
->keys
[i
].name
, path
->keys
[i
].len_name
* sizeof(WCHAR
) );
599 p
+= path
->keys
[i
].len_name
;
601 memcpy( p
, path
->keys
[i
].value
, path
->keys
[i
].len_value
* sizeof(WCHAR
) );
602 p
+= path
->keys
[i
].len_value
;
608 static WCHAR
*build_path( struct path
*path
, LONG flags
, int *len
)
615 int len_namespace
, len_keylist
;
616 WCHAR
*ret
, *namespace = build_namespace( path
, &len_namespace
, FALSE
);
617 WCHAR
*keylist
= build_keylist( path
, &len_keylist
);
619 if (!namespace || !keylist
)
621 heap_free( namespace );
622 heap_free( keylist
);
625 *len
= len_namespace
;
628 *len
+= path
->len_class
+ 1;
629 if (path
->num_keys
) *len
+= len_keylist
+ 1;
631 if (!(ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
633 heap_free( namespace );
634 heap_free( keylist
);
637 strcpyW( ret
, namespace );
640 ret
[len_namespace
] = ':';
641 strcpyW( ret
+ len_namespace
+ 1, path
->class );
644 ret
[len_namespace
+ path
->len_class
+ 1] = '.';
645 strcpyW( ret
+ len_namespace
+ path
->len_class
+ 2, keylist
);
648 heap_free( namespace );
649 heap_free( keylist
);
653 case WBEMPATH_GET_RELATIVE_ONLY
:
656 WCHAR
*ret
, *keylist
;
658 if (!path
->len_class
) return NULL
;
659 if (!(keylist
= build_keylist( path
, &len_keylist
))) return NULL
;
661 *len
= path
->len_class
;
662 if (path
->num_keys
) *len
+= len_keylist
+ 1;
663 if (!(ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
665 heap_free( keylist
);
668 strcpyW( ret
, path
->class );
671 ret
[path
->len_class
] = '.';
672 strcpyW( ret
+ path
->len_class
+ 1, keylist
);
674 heap_free( keylist
);
677 case WBEMPATH_GET_SERVER_TOO
:
679 int len_namespace
, len_server
, len_keylist
;
680 WCHAR
*p
, *ret
, *namespace = build_namespace( path
, &len_namespace
, TRUE
);
681 WCHAR
*server
= build_server( path
, &len_server
);
682 WCHAR
*keylist
= build_keylist( path
, &len_keylist
);
684 if (!namespace || !server
|| !keylist
)
686 heap_free( namespace );
688 heap_free( keylist
);
691 *len
= len_namespace
+ len_server
;
694 *len
+= path
->len_class
+ 1;
695 if (path
->num_keys
) *len
+= len_keylist
+ 1;
697 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
699 heap_free( namespace );
701 heap_free( keylist
);
704 strcpyW( p
, server
);
706 strcpyW( p
, namespace );
711 strcpyW( p
, path
->class );
714 p
[path
->len_class
] = '.';
715 strcpyW( p
+ path
->len_class
+ 1, keylist
);
718 heap_free( namespace );
720 heap_free( keylist
);
723 case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY
:
725 int len_namespace
, len_server
;
726 WCHAR
*p
, *ret
, *namespace = build_namespace( path
, &len_namespace
, TRUE
);
727 WCHAR
*server
= build_server( path
, &len_server
);
729 if (!namespace || !server
)
731 heap_free( namespace );
735 *len
= len_namespace
+ len_server
;
736 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
738 heap_free( namespace );
742 strcpyW( p
, server
);
744 strcpyW( p
, namespace );
745 heap_free( namespace );
749 case WBEMPATH_GET_NAMESPACE_ONLY
:
750 return build_namespace( path
, len
, FALSE
);
752 case WBEMPATH_GET_ORIGINAL
:
753 if (!path
->len_text
) return NULL
;
754 *len
= path
->len_text
;
755 return strdupW( path
->text
);
758 ERR("unhandled flags 0x%x\n", flags
);
763 static HRESULT WINAPI
path_GetText(
766 ULONG
*puBufferLength
,
769 struct path
*path
= impl_from_IWbemPath( iface
);
774 TRACE("%p, 0x%x, %p, %p\n", iface
, lFlags
, puBufferLength
, pszText
);
776 if (!puBufferLength
) return WBEM_E_INVALID_PARAMETER
;
778 EnterCriticalSection( &path
->cs
);
780 str
= build_path( path
, lFlags
, &len
);
781 if (*puBufferLength
< len
+ 1)
783 *puBufferLength
= len
+ 1;
788 hr
= WBEM_E_INVALID_PARAMETER
;
791 if (str
) strcpyW( pszText
, str
);
793 *puBufferLength
= len
+ 1;
795 TRACE("returning %s\n", debugstr_w(pszText
));
799 LeaveCriticalSection( &path
->cs
);
803 static HRESULT WINAPI
path_GetInfo(
808 struct path
*path
= impl_from_IWbemPath( iface
);
810 TRACE("%p, %u, %p\n", iface
, info
, response
);
812 if (info
|| !response
) return WBEM_E_INVALID_PARAMETER
;
814 FIXME("some flags are not implemented\n");
816 EnterCriticalSection( &path
->cs
);
818 *response
= path
->flags
;
819 if (!path
->server
|| (path
->len_server
== 1 && path
->server
[0] == '.'))
820 *response
|= WBEMPATH_INFO_ANON_LOCAL_MACHINE
;
822 *response
|= WBEMPATH_INFO_HAS_MACHINE_NAME
;
825 *response
|= WBEMPATH_INFO_SERVER_NAMESPACE_ONLY
;
828 *response
|= WBEMPATH_INFO_HAS_SUBSCOPES
;
830 *response
|= WBEMPATH_INFO_IS_INST_REF
;
832 *response
|= WBEMPATH_INFO_IS_CLASS_REF
;
835 LeaveCriticalSection( &path
->cs
);
839 static HRESULT WINAPI
path_SetServer(
843 struct path
*path
= impl_from_IWbemPath( iface
);
844 static const ULONGLONG flags
=
845 WBEMPATH_INFO_PATH_HAD_SERVER
| WBEMPATH_INFO_V1_COMPLIANT
|
846 WBEMPATH_INFO_V2_COMPLIANT
| WBEMPATH_INFO_CIM_COMPLIANT
;
849 TRACE("%p, %s\n", iface
, debugstr_w(name
));
851 EnterCriticalSection( &path
->cs
);
855 if (!(server
= strdupW( name
)))
857 LeaveCriticalSection( &path
->cs
);
858 return WBEM_E_OUT_OF_MEMORY
;
860 heap_free( path
->server
);
861 path
->server
= server
;
862 path
->len_server
= strlenW( path
->server
);
863 path
->flags
|= flags
;
867 heap_free( path
->server
);
869 path
->len_server
= 0;
870 path
->flags
&= ~flags
;
873 LeaveCriticalSection( &path
->cs
);
877 static HRESULT WINAPI
path_GetServer(
882 struct path
*path
= impl_from_IWbemPath( iface
);
884 TRACE("%p, %p, %p\n", iface
, len
, name
);
886 if (!len
|| (*len
&& !name
)) return WBEM_E_INVALID_PARAMETER
;
888 EnterCriticalSection( &path
->cs
);
892 LeaveCriticalSection( &path
->cs
);
893 return WBEM_E_NOT_AVAILABLE
;
895 if (*len
> path
->len_server
) strcpyW( name
, path
->server
);
896 *len
= path
->len_server
+ 1;
898 LeaveCriticalSection( &path
->cs
);
902 static HRESULT WINAPI
path_GetNamespaceCount(
906 struct path
*path
= impl_from_IWbemPath( iface
);
908 TRACE("%p, %p\n", iface
, puCount
);
910 if (!puCount
) return WBEM_E_INVALID_PARAMETER
;
912 EnterCriticalSection( &path
->cs
);
913 *puCount
= path
->num_namespaces
;
914 LeaveCriticalSection( &path
->cs
);
918 static HRESULT WINAPI
path_SetNamespaceAt(
923 struct path
*path
= impl_from_IWbemPath( iface
);
924 static const ULONGLONG flags
=
925 WBEMPATH_INFO_V1_COMPLIANT
| WBEMPATH_INFO_V2_COMPLIANT
|
926 WBEMPATH_INFO_CIM_COMPLIANT
;
931 TRACE("%p, %u, %s\n", iface
, idx
, debugstr_w(name
));
933 EnterCriticalSection( &path
->cs
);
935 if (idx
> path
->num_namespaces
|| !name
)
937 LeaveCriticalSection( &path
->cs
);
938 return WBEM_E_INVALID_PARAMETER
;
940 if (!(new = strdupW( name
)))
942 LeaveCriticalSection( &path
->cs
);
943 return WBEM_E_OUT_OF_MEMORY
;
945 size
= (path
->num_namespaces
+ 1) * sizeof(WCHAR
*);
946 if (path
->namespaces
) tmp
= heap_realloc( path
->namespaces
, size
);
947 else tmp
= heap_alloc( size
);
951 LeaveCriticalSection( &path
->cs
);
952 return WBEM_E_OUT_OF_MEMORY
;
954 path
->namespaces
= tmp
;
955 size
= (path
->num_namespaces
+ 1) * sizeof(int);
956 if (path
->len_namespaces
) tmp_len
= heap_realloc( path
->len_namespaces
, size
);
957 else tmp_len
= heap_alloc( size
);
961 LeaveCriticalSection( &path
->cs
);
962 return WBEM_E_OUT_OF_MEMORY
;
964 path
->len_namespaces
= tmp_len
;
965 for (i
= idx
; i
< path
->num_namespaces
; i
++)
967 path
->namespaces
[i
+ 1] = path
->namespaces
[i
];
968 path
->len_namespaces
[i
+ 1] = path
->len_namespaces
[i
];
970 path
->namespaces
[idx
] = new;
971 path
->len_namespaces
[idx
] = strlenW( new );
972 path
->num_namespaces
++;
973 path
->flags
|= flags
;
975 LeaveCriticalSection( &path
->cs
);
979 static HRESULT WINAPI
path_GetNamespaceAt(
985 struct path
*path
= impl_from_IWbemPath( iface
);
987 TRACE("%p, %u, %p, %p\n", iface
, idx
, len
, name
);
989 EnterCriticalSection( &path
->cs
);
991 if (!len
|| (*len
&& !name
) || idx
>= path
->num_namespaces
)
993 LeaveCriticalSection( &path
->cs
);
994 return WBEM_E_INVALID_PARAMETER
;
996 if (*len
> path
->len_namespaces
[idx
]) strcpyW( name
, path
->namespaces
[idx
] );
997 *len
= path
->len_namespaces
[idx
] + 1;
999 LeaveCriticalSection( &path
->cs
);
1003 static HRESULT WINAPI
path_RemoveNamespaceAt(
1007 struct path
*path
= impl_from_IWbemPath( iface
);
1009 TRACE("%p, %u\n", iface
, idx
);
1011 EnterCriticalSection( &path
->cs
);
1013 if (idx
>= path
->num_namespaces
)
1015 LeaveCriticalSection( &path
->cs
);
1016 return WBEM_E_INVALID_PARAMETER
;
1018 heap_free( path
->namespaces
[idx
] );
1019 while (idx
< path
->num_namespaces
- 1)
1021 path
->namespaces
[idx
] = path
->namespaces
[idx
+ 1];
1022 path
->len_namespaces
[idx
] = path
->len_namespaces
[idx
+ 1];
1025 path
->num_namespaces
--;
1027 LeaveCriticalSection( &path
->cs
);
1031 static HRESULT WINAPI
path_RemoveAllNamespaces(
1034 struct path
*path
= impl_from_IWbemPath( iface
);
1037 TRACE("%p\n", iface
);
1039 EnterCriticalSection( &path
->cs
);
1041 for (i
= 0; i
< path
->num_namespaces
; i
++) heap_free( path
->namespaces
[i
] );
1042 path
->num_namespaces
= 0;
1043 heap_free( path
->namespaces
);
1044 path
->namespaces
= NULL
;
1045 heap_free( path
->len_namespaces
);
1046 path
->len_namespaces
= NULL
;
1048 LeaveCriticalSection( &path
->cs
);
1052 static HRESULT WINAPI
path_GetScopeCount(
1056 FIXME("%p, %p\n", iface
, puCount
);
1060 static HRESULT WINAPI
path_SetScope(
1065 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszClass
));
1069 static HRESULT WINAPI
path_SetScopeFromText(
1074 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszText
));
1078 static HRESULT WINAPI
path_GetScope(
1081 ULONG
*puClassNameBufSize
,
1083 IWbemPathKeyList
**pKeyList
)
1085 FIXME("%p, %u, %p, %p, %p\n", iface
, uIndex
, puClassNameBufSize
, pszClass
, pKeyList
);
1089 static HRESULT WINAPI
path_GetScopeAsText(
1092 ULONG
*puTextBufSize
,
1095 FIXME("%p, %u, %p, %p\n", iface
, uIndex
, puTextBufSize
, pszText
);
1099 static HRESULT WINAPI
path_RemoveScope(
1103 FIXME("%p, %u\n", iface
, uIndex
);
1107 static HRESULT WINAPI
path_RemoveAllScopes(
1110 FIXME("%p\n", iface
);
1114 static HRESULT WINAPI
path_SetClassName(
1118 struct path
*path
= impl_from_IWbemPath( iface
);
1121 TRACE("%p, %s\n", iface
, debugstr_w(name
));
1123 if (!name
) return WBEM_E_INVALID_PARAMETER
;
1124 if (!(class = strdupW( name
))) return WBEM_E_OUT_OF_MEMORY
;
1126 EnterCriticalSection( &path
->cs
);
1128 heap_free( path
->class );
1129 path
->class = class;
1130 path
->len_class
= strlenW( path
->class );
1131 path
->flags
|= WBEMPATH_INFO_V2_COMPLIANT
| WBEMPATH_INFO_CIM_COMPLIANT
;
1133 LeaveCriticalSection( &path
->cs
);
1137 static HRESULT WINAPI
path_GetClassName(
1142 struct path
*path
= impl_from_IWbemPath( iface
);
1144 TRACE("%p, %p, %p\n", iface
, len
, name
);
1146 if (!len
|| (*len
&& !name
)) return WBEM_E_INVALID_PARAMETER
;
1148 EnterCriticalSection( &path
->cs
);
1152 LeaveCriticalSection( &path
->cs
);
1153 return WBEM_E_INVALID_OBJECT_PATH
;
1155 if (*len
> path
->len_class
) strcpyW( name
, path
->class );
1156 *len
= path
->len_class
+ 1;
1158 LeaveCriticalSection( &path
->cs
);
1162 static HRESULT WINAPI
path_GetKeyList(
1164 IWbemPathKeyList
**pOut
)
1166 struct path
*path
= impl_from_IWbemPath( iface
);
1169 TRACE("%p, %p\n", iface
, pOut
);
1171 EnterCriticalSection( &path
->cs
);
1175 LeaveCriticalSection( &path
->cs
);
1176 return WBEM_E_INVALID_PARAMETER
;
1178 hr
= WbemPathKeyList_create( NULL
, iface
, (void **)pOut
);
1180 LeaveCriticalSection( &path
->cs
);
1184 static HRESULT WINAPI
path_CreateClassPart(
1189 FIXME("%p, 0x%x, %s\n", iface
, lFlags
, debugstr_w(Name
));
1193 static HRESULT WINAPI
path_DeleteClassPart(
1197 FIXME("%p, 0x%x\n", iface
, lFlags
);
1201 static BOOL WINAPI
path_IsRelative(
1204 LPWSTR wszNamespace
)
1206 FIXME("%p, %s, %s\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
));
1210 static BOOL WINAPI
path_IsRelativeOrChild(
1213 LPWSTR wszNamespace
,
1216 FIXME("%p, %s, %s, 0x%x\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
), lFlags
);
1220 static BOOL WINAPI
path_IsLocal(
1224 FIXME("%p, %s\n", iface
, debugstr_w(wszMachine
));
1228 static BOOL WINAPI
path_IsSameClassName(
1232 FIXME("%p, %s\n", iface
, debugstr_w(wszClass
));
1236 static const struct IWbemPathVtbl path_vtbl
=
1238 path_QueryInterface
,
1246 path_GetNamespaceCount
,
1247 path_SetNamespaceAt
,
1248 path_GetNamespaceAt
,
1249 path_RemoveNamespaceAt
,
1250 path_RemoveAllNamespaces
,
1253 path_SetScopeFromText
,
1255 path_GetScopeAsText
,
1257 path_RemoveAllScopes
,
1261 path_CreateClassPart
,
1262 path_DeleteClassPart
,
1264 path_IsRelativeOrChild
,
1266 path_IsSameClassName
1269 HRESULT
WbemPath_create( IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
1273 TRACE("%p, %p\n", pUnkOuter
, ppObj
);
1275 if (!(path
= heap_alloc( sizeof(*path
) ))) return E_OUTOFMEMORY
;
1277 path
->IWbemPath_iface
.lpVtbl
= &path_vtbl
;
1279 InitializeCriticalSection( &path
->cs
);
1280 path
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": wmiutils_path.cs");
1283 *ppObj
= &path
->IWbemPath_iface
;
1285 TRACE("returning iface %p\n", *ppObj
);