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( IWbemPath
*parent
, LPVOID
*ppObj
)
281 struct keylist
*keylist
;
283 TRACE("%p\n", 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
)
318 heap_free( path
->text
);
319 heap_free( path
->server
);
320 for (i
= 0; i
< path
->num_namespaces
; i
++) heap_free( path
->namespaces
[i
] );
321 heap_free( path
->namespaces
);
322 heap_free( path
->len_namespaces
);
323 heap_free( path
->class );
324 free_keys( path
->keys
, path
->num_keys
);
328 static ULONG WINAPI
path_AddRef(
331 struct path
*path
= impl_from_IWbemPath( iface
);
332 return InterlockedIncrement( &path
->refs
);
335 static ULONG WINAPI
path_Release(
338 struct path
*path
= impl_from_IWbemPath( iface
);
339 LONG refs
= InterlockedDecrement( &path
->refs
);
342 TRACE("destroying %p\n", path
);
344 path
->cs
.DebugInfo
->Spare
[0] = 0;
345 DeleteCriticalSection( &path
->cs
);
351 static HRESULT WINAPI
path_QueryInterface(
356 struct path
*path
= impl_from_IWbemPath( iface
);
358 TRACE("%p, %s, %p\n", path
, debugstr_guid( riid
), ppvObject
);
360 if ( IsEqualGUID( riid
, &IID_IWbemPath
) ||
361 IsEqualGUID( riid
, &IID_IUnknown
) )
367 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
368 return E_NOINTERFACE
;
370 IWbemPath_AddRef( iface
);
374 static HRESULT
parse_key( struct key
*key
, const WCHAR
*str
, unsigned int *ret_len
)
380 while (*q
&& *q
!= '=')
382 if (*q
== ',' || isspaceW( *q
)) return WBEM_E_INVALID_PARAMETER
;
386 if (!(key
->name
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) return E_OUTOFMEMORY
;
387 memcpy( key
->name
, p
, len
* sizeof(WCHAR
) );
392 if (!*p
|| *p
== ',' || isspaceW( *p
)) return WBEM_E_INVALID_PARAMETER
;
394 while (*q
&& *q
!= ',') q
++;
396 if (!(key
->value
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) return E_OUTOFMEMORY
;
397 memcpy( key
->value
, p
, len
* sizeof(WCHAR
) );
399 key
->len_value
= len
;
402 if (*q
== ',') (*ret_len
)++;
406 static HRESULT
parse_text( struct path
*path
, ULONG mode
, const WCHAR
*text
)
408 HRESULT hr
= E_OUTOFMEMORY
;
413 if ((p
[0] == '\\' && p
[1] == '\\') || (p
[0] == '/' && p
[1] == '/'))
417 while (*q
&& *q
!= '\\' && *q
!= '/') q
++;
419 if (!(path
->server
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
420 memcpy( path
->server
, p
, len
* sizeof(WCHAR
) );
421 path
->server
[len
] = 0;
422 path
->len_server
= len
;
423 path
->flags
|= WBEMPATH_INFO_PATH_HAD_SERVER
;
426 if (strchrW( p
, '\\' ) || strchrW( p
, '/' ))
428 if (*q
!= '\\' && *q
!= '/' && *q
!= ':')
430 path
->num_namespaces
= 1;
433 while (*q
&& *q
!= ':')
435 if (*q
== '\\' || *q
== '/') path
->num_namespaces
++;
439 if (path
->num_namespaces
)
441 if (!(path
->namespaces
= heap_alloc( path
->num_namespaces
* sizeof(WCHAR
*) ))) goto done
;
442 if (!(path
->len_namespaces
= heap_alloc( path
->num_namespaces
* sizeof(int) ))) goto done
;
446 if (*q
&& *q
!= '\\' && *q
!= '/' && *q
!= ':')
449 while (*p
&& *p
!= '\\' && *p
!= '/' && *p
!= ':') p
++;
451 if (!(path
->namespaces
[i
] = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
452 memcpy( path
->namespaces
[i
], q
, len
* sizeof(WCHAR
) );
453 path
->namespaces
[i
][len
] = 0;
454 path
->len_namespaces
[i
] = len
;
458 while (*q
&& *q
!= ':')
460 if (*q
== '\\' || *q
== '/')
463 while (*p
&& *p
!= '\\' && *p
!= '/' && *p
!= ':') p
++;
465 if (!(path
->namespaces
[i
] = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
466 memcpy( path
->namespaces
[i
], q
+ 1, len
* sizeof(WCHAR
) );
467 path
->namespaces
[i
][len
] = 0;
468 path
->len_namespaces
[i
] = len
;
476 while (*q
&& *q
!= '.') q
++;
478 if (!(path
->class = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
479 memcpy( path
->class, p
, len
* sizeof(WCHAR
) );
480 path
->class[len
] = 0;
481 path
->len_class
= len
;
489 if (*q
== ',') path
->num_keys
++;
492 if (!(path
->keys
= heap_alloc_zero( path
->num_keys
* sizeof(struct key
) ))) goto done
;
497 if (i
>= path
->num_keys
) break;
498 hr
= parse_key( &path
->keys
[i
], q
, &len
);
499 if (hr
!= S_OK
) goto done
;
507 if (hr
!= S_OK
) clear_path( path
);
508 else path
->flags
|= WBEMPATH_INFO_CIM_COMPLIANT
| WBEMPATH_INFO_V2_COMPLIANT
;
512 static HRESULT WINAPI
path_SetText(
517 struct path
*path
= impl_from_IWbemPath( iface
);
521 TRACE("%p, %u, %s\n", iface
, uMode
, debugstr_w(pszPath
));
523 if (!uMode
|| !pszPath
) return WBEM_E_INVALID_PARAMETER
;
525 EnterCriticalSection( &path
->cs
);
528 if (!pszPath
[0]) goto done
;
529 if ((hr
= parse_text( path
, uMode
, pszPath
)) != S_OK
) goto done
;
531 len
= strlenW( pszPath
);
532 if (!(path
->text
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) )))
538 strcpyW( path
->text
, pszPath
);
539 path
->len_text
= len
;
542 LeaveCriticalSection( &path
->cs
);
546 static WCHAR
*build_namespace( struct path
*path
, int *len
, BOOL leading_slash
)
552 for (i
= 0; i
< path
->num_namespaces
; i
++)
554 if (i
> 0 || leading_slash
) *len
+= 1;
555 *len
+= path
->len_namespaces
[i
];
557 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
558 for (i
= 0; i
< path
->num_namespaces
; i
++)
560 if (i
> 0 || leading_slash
) *p
++ = '\\';
561 memcpy( p
, path
->namespaces
[i
], path
->len_namespaces
[i
] * sizeof(WCHAR
) );
562 p
+= path
->len_namespaces
[i
];
568 static WCHAR
*build_server( struct path
*path
, int *len
)
573 if (path
->len_server
) *len
+= 2 + path
->len_server
;
575 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
576 if (path
->len_server
)
579 strcpyW( p
+ 2, path
->server
);
590 static WCHAR
*build_keylist( struct path
*path
, int *len
)
596 for (i
= 0; i
< path
->num_keys
; i
++)
598 if (i
> 0) *len
+= 1;
599 *len
+= path
->keys
[i
].len_name
+ path
->keys
[i
].len_value
+ 1;
601 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
602 for (i
= 0; i
< path
->num_keys
; i
++)
604 if (i
> 0) *p
++ = ',';
605 memcpy( p
, path
->keys
[i
].name
, path
->keys
[i
].len_name
* sizeof(WCHAR
) );
606 p
+= path
->keys
[i
].len_name
;
608 memcpy( p
, path
->keys
[i
].value
, path
->keys
[i
].len_value
* sizeof(WCHAR
) );
609 p
+= path
->keys
[i
].len_value
;
615 static WCHAR
*build_path( struct path
*path
, LONG flags
, int *len
)
622 int len_namespace
, len_keylist
;
623 WCHAR
*ret
, *namespace = build_namespace( path
, &len_namespace
, FALSE
);
624 WCHAR
*keylist
= build_keylist( path
, &len_keylist
);
626 if (!namespace || !keylist
)
628 heap_free( namespace );
629 heap_free( keylist
);
632 *len
= len_namespace
;
635 *len
+= path
->len_class
+ 1;
636 if (path
->num_keys
) *len
+= len_keylist
+ 1;
638 if (!(ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
640 heap_free( namespace );
641 heap_free( keylist
);
644 strcpyW( ret
, namespace );
647 ret
[len_namespace
] = ':';
648 strcpyW( ret
+ len_namespace
+ 1, path
->class );
651 ret
[len_namespace
+ path
->len_class
+ 1] = '.';
652 strcpyW( ret
+ len_namespace
+ path
->len_class
+ 2, keylist
);
655 heap_free( namespace );
656 heap_free( keylist
);
660 case WBEMPATH_GET_RELATIVE_ONLY
:
663 WCHAR
*ret
, *keylist
;
665 if (!path
->len_class
) return NULL
;
666 if (!(keylist
= build_keylist( path
, &len_keylist
))) return NULL
;
668 *len
= path
->len_class
;
669 if (path
->num_keys
) *len
+= len_keylist
+ 1;
670 if (!(ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
672 heap_free( keylist
);
675 strcpyW( ret
, path
->class );
678 ret
[path
->len_class
] = '.';
679 strcpyW( ret
+ path
->len_class
+ 1, keylist
);
681 heap_free( keylist
);
684 case WBEMPATH_GET_SERVER_TOO
:
686 int len_namespace
, len_server
, len_keylist
;
687 WCHAR
*p
, *ret
, *namespace = build_namespace( path
, &len_namespace
, TRUE
);
688 WCHAR
*server
= build_server( path
, &len_server
);
689 WCHAR
*keylist
= build_keylist( path
, &len_keylist
);
691 if (!namespace || !server
|| !keylist
)
693 heap_free( namespace );
695 heap_free( keylist
);
698 *len
= len_namespace
+ len_server
;
701 *len
+= path
->len_class
+ 1;
702 if (path
->num_keys
) *len
+= len_keylist
+ 1;
704 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
706 heap_free( namespace );
708 heap_free( keylist
);
711 strcpyW( p
, server
);
713 strcpyW( p
, namespace );
718 strcpyW( p
, path
->class );
721 p
[path
->len_class
] = '.';
722 strcpyW( p
+ path
->len_class
+ 1, keylist
);
725 heap_free( namespace );
727 heap_free( keylist
);
730 case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY
:
732 int len_namespace
, len_server
;
733 WCHAR
*p
, *ret
, *namespace = build_namespace( path
, &len_namespace
, TRUE
);
734 WCHAR
*server
= build_server( path
, &len_server
);
736 if (!namespace || !server
)
738 heap_free( namespace );
742 *len
= len_namespace
+ len_server
;
743 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
745 heap_free( namespace );
749 strcpyW( p
, server
);
751 strcpyW( p
, namespace );
752 heap_free( namespace );
756 case WBEMPATH_GET_NAMESPACE_ONLY
:
757 return build_namespace( path
, len
, FALSE
);
759 case WBEMPATH_GET_ORIGINAL
:
760 if (!path
->len_text
) return NULL
;
761 *len
= path
->len_text
;
762 return strdupW( path
->text
);
765 ERR("unhandled flags 0x%x\n", flags
);
770 static HRESULT WINAPI
path_GetText(
773 ULONG
*puBufferLength
,
776 struct path
*path
= impl_from_IWbemPath( iface
);
781 TRACE("%p, 0x%x, %p, %p\n", iface
, lFlags
, puBufferLength
, pszText
);
783 if (!puBufferLength
) return WBEM_E_INVALID_PARAMETER
;
785 EnterCriticalSection( &path
->cs
);
787 str
= build_path( path
, lFlags
, &len
);
788 if (*puBufferLength
< len
+ 1)
790 *puBufferLength
= len
+ 1;
795 hr
= WBEM_E_INVALID_PARAMETER
;
798 if (str
) strcpyW( pszText
, str
);
800 *puBufferLength
= len
+ 1;
802 TRACE("returning %s\n", debugstr_w(pszText
));
806 LeaveCriticalSection( &path
->cs
);
810 static HRESULT WINAPI
path_GetInfo(
815 struct path
*path
= impl_from_IWbemPath( iface
);
817 TRACE("%p, %u, %p\n", iface
, info
, response
);
819 if (info
|| !response
) return WBEM_E_INVALID_PARAMETER
;
821 FIXME("some flags are not implemented\n");
823 EnterCriticalSection( &path
->cs
);
825 *response
= path
->flags
;
826 if (!path
->server
|| (path
->len_server
== 1 && path
->server
[0] == '.'))
827 *response
|= WBEMPATH_INFO_ANON_LOCAL_MACHINE
;
829 *response
|= WBEMPATH_INFO_HAS_MACHINE_NAME
;
832 *response
|= WBEMPATH_INFO_SERVER_NAMESPACE_ONLY
;
835 *response
|= WBEMPATH_INFO_HAS_SUBSCOPES
;
837 *response
|= WBEMPATH_INFO_IS_INST_REF
;
839 *response
|= WBEMPATH_INFO_IS_CLASS_REF
;
842 LeaveCriticalSection( &path
->cs
);
846 static HRESULT WINAPI
path_SetServer(
850 struct path
*path
= impl_from_IWbemPath( iface
);
851 static const ULONGLONG flags
=
852 WBEMPATH_INFO_PATH_HAD_SERVER
| WBEMPATH_INFO_V1_COMPLIANT
|
853 WBEMPATH_INFO_V2_COMPLIANT
| WBEMPATH_INFO_CIM_COMPLIANT
;
856 TRACE("%p, %s\n", iface
, debugstr_w(name
));
858 EnterCriticalSection( &path
->cs
);
862 if (!(server
= strdupW( name
)))
864 LeaveCriticalSection( &path
->cs
);
865 return WBEM_E_OUT_OF_MEMORY
;
867 heap_free( path
->server
);
868 path
->server
= server
;
869 path
->len_server
= strlenW( path
->server
);
870 path
->flags
|= flags
;
874 heap_free( path
->server
);
876 path
->len_server
= 0;
877 path
->flags
&= ~flags
;
880 LeaveCriticalSection( &path
->cs
);
884 static HRESULT WINAPI
path_GetServer(
889 struct path
*path
= impl_from_IWbemPath( iface
);
891 TRACE("%p, %p, %p\n", iface
, len
, name
);
893 if (!len
|| (*len
&& !name
)) return WBEM_E_INVALID_PARAMETER
;
895 EnterCriticalSection( &path
->cs
);
899 LeaveCriticalSection( &path
->cs
);
900 return WBEM_E_NOT_AVAILABLE
;
902 if (*len
> path
->len_server
) strcpyW( name
, path
->server
);
903 *len
= path
->len_server
+ 1;
905 LeaveCriticalSection( &path
->cs
);
909 static HRESULT WINAPI
path_GetNamespaceCount(
913 struct path
*path
= impl_from_IWbemPath( iface
);
915 TRACE("%p, %p\n", iface
, puCount
);
917 if (!puCount
) return WBEM_E_INVALID_PARAMETER
;
919 EnterCriticalSection( &path
->cs
);
920 *puCount
= path
->num_namespaces
;
921 LeaveCriticalSection( &path
->cs
);
925 static HRESULT WINAPI
path_SetNamespaceAt(
930 struct path
*path
= impl_from_IWbemPath( iface
);
931 static const ULONGLONG flags
=
932 WBEMPATH_INFO_V1_COMPLIANT
| WBEMPATH_INFO_V2_COMPLIANT
|
933 WBEMPATH_INFO_CIM_COMPLIANT
;
938 TRACE("%p, %u, %s\n", iface
, idx
, debugstr_w(name
));
940 EnterCriticalSection( &path
->cs
);
942 if (idx
> path
->num_namespaces
|| !name
)
944 LeaveCriticalSection( &path
->cs
);
945 return WBEM_E_INVALID_PARAMETER
;
947 if (!(new = strdupW( name
)))
949 LeaveCriticalSection( &path
->cs
);
950 return WBEM_E_OUT_OF_MEMORY
;
952 size
= (path
->num_namespaces
+ 1) * sizeof(WCHAR
*);
953 if (path
->namespaces
) tmp
= heap_realloc( path
->namespaces
, size
);
954 else tmp
= heap_alloc( size
);
958 LeaveCriticalSection( &path
->cs
);
959 return WBEM_E_OUT_OF_MEMORY
;
961 path
->namespaces
= tmp
;
962 size
= (path
->num_namespaces
+ 1) * sizeof(int);
963 if (path
->len_namespaces
) tmp_len
= heap_realloc( path
->len_namespaces
, size
);
964 else tmp_len
= heap_alloc( size
);
968 LeaveCriticalSection( &path
->cs
);
969 return WBEM_E_OUT_OF_MEMORY
;
971 path
->len_namespaces
= tmp_len
;
972 for (i
= idx
; i
< path
->num_namespaces
; i
++)
974 path
->namespaces
[i
+ 1] = path
->namespaces
[i
];
975 path
->len_namespaces
[i
+ 1] = path
->len_namespaces
[i
];
977 path
->namespaces
[idx
] = new;
978 path
->len_namespaces
[idx
] = strlenW( new );
979 path
->num_namespaces
++;
980 path
->flags
|= flags
;
982 LeaveCriticalSection( &path
->cs
);
986 static HRESULT WINAPI
path_GetNamespaceAt(
992 struct path
*path
= impl_from_IWbemPath( iface
);
994 TRACE("%p, %u, %p, %p\n", iface
, idx
, len
, name
);
996 EnterCriticalSection( &path
->cs
);
998 if (!len
|| (*len
&& !name
) || idx
>= path
->num_namespaces
)
1000 LeaveCriticalSection( &path
->cs
);
1001 return WBEM_E_INVALID_PARAMETER
;
1003 if (*len
> path
->len_namespaces
[idx
]) strcpyW( name
, path
->namespaces
[idx
] );
1004 *len
= path
->len_namespaces
[idx
] + 1;
1006 LeaveCriticalSection( &path
->cs
);
1010 static HRESULT WINAPI
path_RemoveNamespaceAt(
1014 struct path
*path
= impl_from_IWbemPath( iface
);
1016 TRACE("%p, %u\n", iface
, idx
);
1018 EnterCriticalSection( &path
->cs
);
1020 if (idx
>= path
->num_namespaces
)
1022 LeaveCriticalSection( &path
->cs
);
1023 return WBEM_E_INVALID_PARAMETER
;
1025 heap_free( path
->namespaces
[idx
] );
1026 while (idx
< path
->num_namespaces
- 1)
1028 path
->namespaces
[idx
] = path
->namespaces
[idx
+ 1];
1029 path
->len_namespaces
[idx
] = path
->len_namespaces
[idx
+ 1];
1032 path
->num_namespaces
--;
1034 LeaveCriticalSection( &path
->cs
);
1038 static HRESULT WINAPI
path_RemoveAllNamespaces(
1041 struct path
*path
= impl_from_IWbemPath( iface
);
1044 TRACE("%p\n", iface
);
1046 EnterCriticalSection( &path
->cs
);
1048 for (i
= 0; i
< path
->num_namespaces
; i
++) heap_free( path
->namespaces
[i
] );
1049 path
->num_namespaces
= 0;
1050 heap_free( path
->namespaces
);
1051 path
->namespaces
= NULL
;
1052 heap_free( path
->len_namespaces
);
1053 path
->len_namespaces
= NULL
;
1055 LeaveCriticalSection( &path
->cs
);
1059 static HRESULT WINAPI
path_GetScopeCount(
1063 FIXME("%p, %p\n", iface
, puCount
);
1067 static HRESULT WINAPI
path_SetScope(
1072 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszClass
));
1076 static HRESULT WINAPI
path_SetScopeFromText(
1081 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszText
));
1085 static HRESULT WINAPI
path_GetScope(
1088 ULONG
*puClassNameBufSize
,
1090 IWbemPathKeyList
**pKeyList
)
1092 FIXME("%p, %u, %p, %p, %p\n", iface
, uIndex
, puClassNameBufSize
, pszClass
, pKeyList
);
1096 static HRESULT WINAPI
path_GetScopeAsText(
1099 ULONG
*puTextBufSize
,
1102 FIXME("%p, %u, %p, %p\n", iface
, uIndex
, puTextBufSize
, pszText
);
1106 static HRESULT WINAPI
path_RemoveScope(
1110 FIXME("%p, %u\n", iface
, uIndex
);
1114 static HRESULT WINAPI
path_RemoveAllScopes(
1117 FIXME("%p\n", iface
);
1121 static HRESULT WINAPI
path_SetClassName(
1125 struct path
*path
= impl_from_IWbemPath( iface
);
1128 TRACE("%p, %s\n", iface
, debugstr_w(name
));
1130 if (!name
) return WBEM_E_INVALID_PARAMETER
;
1131 if (!(class = strdupW( name
))) return WBEM_E_OUT_OF_MEMORY
;
1133 EnterCriticalSection( &path
->cs
);
1135 heap_free( path
->class );
1136 path
->class = class;
1137 path
->len_class
= strlenW( path
->class );
1138 path
->flags
|= WBEMPATH_INFO_V2_COMPLIANT
| WBEMPATH_INFO_CIM_COMPLIANT
;
1140 LeaveCriticalSection( &path
->cs
);
1144 static HRESULT WINAPI
path_GetClassName(
1149 struct path
*path
= impl_from_IWbemPath( iface
);
1151 TRACE("%p, %p, %p\n", iface
, len
, name
);
1153 if (!len
|| (*len
&& !name
)) return WBEM_E_INVALID_PARAMETER
;
1155 EnterCriticalSection( &path
->cs
);
1159 LeaveCriticalSection( &path
->cs
);
1160 return WBEM_E_INVALID_OBJECT_PATH
;
1162 if (*len
> path
->len_class
) strcpyW( name
, path
->class );
1163 *len
= path
->len_class
+ 1;
1165 LeaveCriticalSection( &path
->cs
);
1169 static HRESULT WINAPI
path_GetKeyList(
1171 IWbemPathKeyList
**pOut
)
1173 struct path
*path
= impl_from_IWbemPath( iface
);
1176 TRACE("%p, %p\n", iface
, pOut
);
1178 EnterCriticalSection( &path
->cs
);
1182 LeaveCriticalSection( &path
->cs
);
1183 return WBEM_E_INVALID_PARAMETER
;
1185 hr
= WbemPathKeyList_create( iface
, (void **)pOut
);
1187 LeaveCriticalSection( &path
->cs
);
1191 static HRESULT WINAPI
path_CreateClassPart(
1196 FIXME("%p, 0x%x, %s\n", iface
, lFlags
, debugstr_w(Name
));
1200 static HRESULT WINAPI
path_DeleteClassPart(
1204 FIXME("%p, 0x%x\n", iface
, lFlags
);
1208 static BOOL WINAPI
path_IsRelative(
1211 LPWSTR wszNamespace
)
1213 FIXME("%p, %s, %s\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
));
1217 static BOOL WINAPI
path_IsRelativeOrChild(
1220 LPWSTR wszNamespace
,
1223 FIXME("%p, %s, %s, 0x%x\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
), lFlags
);
1227 static BOOL WINAPI
path_IsLocal(
1231 FIXME("%p, %s\n", iface
, debugstr_w(wszMachine
));
1235 static BOOL WINAPI
path_IsSameClassName(
1239 FIXME("%p, %s\n", iface
, debugstr_w(wszClass
));
1243 static const struct IWbemPathVtbl path_vtbl
=
1245 path_QueryInterface
,
1253 path_GetNamespaceCount
,
1254 path_SetNamespaceAt
,
1255 path_GetNamespaceAt
,
1256 path_RemoveNamespaceAt
,
1257 path_RemoveAllNamespaces
,
1260 path_SetScopeFromText
,
1262 path_GetScopeAsText
,
1264 path_RemoveAllScopes
,
1268 path_CreateClassPart
,
1269 path_DeleteClassPart
,
1271 path_IsRelativeOrChild
,
1273 path_IsSameClassName
1276 HRESULT
WbemPath_create( LPVOID
*ppObj
)
1280 TRACE("%p\n", ppObj
);
1282 if (!(path
= heap_alloc( sizeof(*path
) ))) return E_OUTOFMEMORY
;
1284 path
->IWbemPath_iface
.lpVtbl
= &path_vtbl
;
1286 InitializeCriticalSection( &path
->cs
);
1287 path
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": wmiutils_path.cs");
1290 *ppObj
= &path
->IWbemPath_iface
;
1292 TRACE("returning iface %p\n", *ppObj
);