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
29 #include "wine/debug.h"
30 #include "wmiutils_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wmiutils
);
36 IWbemPathKeyList IWbemPathKeyList_iface
;
51 IWbemPath IWbemPath_iface
;
64 unsigned int num_keys
;
68 static inline struct keylist
*impl_from_IWbemPathKeyList( IWbemPathKeyList
*iface
)
70 return CONTAINING_RECORD(iface
, struct keylist
, IWbemPathKeyList_iface
);
73 static inline struct path
*impl_from_IWbemPath( IWbemPath
*iface
)
75 return CONTAINING_RECORD(iface
, struct path
, IWbemPath_iface
);
78 static ULONG WINAPI
keylist_AddRef(
79 IWbemPathKeyList
*iface
)
81 struct keylist
*keylist
= impl_from_IWbemPathKeyList( iface
);
82 return InterlockedIncrement( &keylist
->refs
);
85 static ULONG WINAPI
keylist_Release(
86 IWbemPathKeyList
*iface
)
88 struct keylist
*keylist
= impl_from_IWbemPathKeyList( iface
);
89 LONG refs
= InterlockedDecrement( &keylist
->refs
);
92 TRACE("destroying %p\n", keylist
);
93 IWbemPath_Release( keylist
->parent
);
99 static HRESULT WINAPI
keylist_QueryInterface(
100 IWbemPathKeyList
*iface
,
104 struct keylist
*keylist
= impl_from_IWbemPathKeyList( iface
);
106 TRACE("%p, %s, %p\n", keylist
, debugstr_guid(riid
), ppvObject
);
108 if (IsEqualGUID( riid
, &IID_IWbemPathKeyList
) ||
109 IsEqualGUID( riid
, &IID_IUnknown
))
115 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
116 return E_NOINTERFACE
;
118 IWbemPathKeyList_AddRef( iface
);
122 static HRESULT WINAPI
keylist_GetCount(
123 IWbemPathKeyList
*iface
,
126 struct keylist
*keylist
= impl_from_IWbemPathKeyList( iface
);
127 struct path
*parent
= impl_from_IWbemPath( keylist
->parent
);
129 TRACE("%p, %p\n", iface
, puKeyCount
);
131 if (!puKeyCount
) return WBEM_E_INVALID_PARAMETER
;
133 EnterCriticalSection( &parent
->cs
);
135 *puKeyCount
= parent
->num_keys
;
137 LeaveCriticalSection( &parent
->cs
);
141 static HRESULT WINAPI
keylist_SetKey(
142 IWbemPathKeyList
*iface
,
148 FIXME("%p, %s, 0x%x, %u, %p\n", iface
, debugstr_w(wszName
), uFlags
, uCimType
, pKeyVal
);
152 static HRESULT WINAPI
keylist_SetKey2(
153 IWbemPathKeyList
*iface
,
159 FIXME("%p, %s, 0x%x, %u, %p\n", iface
, debugstr_w(wszName
), uFlags
, uCimType
, pKeyVal
);
163 static HRESULT WINAPI
keylist_GetKey(
164 IWbemPathKeyList
*iface
,
167 ULONG
*puNameBufSize
,
169 ULONG
*puKeyValBufSize
,
171 ULONG
*puApparentCimType
)
173 FIXME("%p, %u, 0x%x, %p, %p, %p, %p, %p\n", iface
, uKeyIx
, uFlags
, puNameBufSize
,
174 pszKeyName
, puKeyValBufSize
, pKeyVal
, puApparentCimType
);
178 static HRESULT WINAPI
keylist_GetKey2(
179 IWbemPathKeyList
*iface
,
182 ULONG
*puNameBufSize
,
185 ULONG
*puApparentCimType
)
187 FIXME("%p, %u, 0x%x, %p, %p, %p, %p\n", iface
, uKeyIx
, uFlags
, puNameBufSize
,
188 pszKeyName
, pKeyValue
, puApparentCimType
);
192 static HRESULT WINAPI
keylist_RemoveKey(
193 IWbemPathKeyList
*iface
,
197 FIXME("%p, %s, 0x%x\n", iface
, debugstr_w(wszName
), uFlags
);
201 static void free_keys( struct key
*keys
, unsigned int count
)
205 for (i
= 0; i
< count
; i
++)
207 heap_free( keys
[i
].name
);
208 heap_free( keys
[i
].value
);
213 static HRESULT WINAPI
keylist_RemoveAllKeys(
214 IWbemPathKeyList
*iface
,
217 struct keylist
*keylist
= impl_from_IWbemPathKeyList( iface
);
218 struct path
*parent
= impl_from_IWbemPath( keylist
->parent
);
220 TRACE("%p, 0x%x\n", iface
, uFlags
);
222 if (uFlags
) return WBEM_E_INVALID_PARAMETER
;
224 EnterCriticalSection( &parent
->cs
);
226 free_keys( parent
->keys
, parent
->num_keys
);
227 parent
->num_keys
= 0;
230 LeaveCriticalSection( &parent
->cs
);
234 static HRESULT WINAPI
keylist_MakeSingleton(
235 IWbemPathKeyList
*iface
,
238 FIXME("%p, %d\n", iface
, bSet
);
242 static HRESULT WINAPI
keylist_GetInfo(
243 IWbemPathKeyList
*iface
,
244 ULONG uRequestedInfo
,
245 ULONGLONG
*puResponse
)
247 FIXME("%p, %u, %p\n", iface
, uRequestedInfo
, puResponse
);
251 static HRESULT WINAPI
keylist_GetText(
252 IWbemPathKeyList
*iface
,
257 FIXME("%p, 0x%x, %p, %p\n", iface
, lFlags
, puBuffLength
, pszText
);
261 static const struct IWbemPathKeyListVtbl keylist_vtbl
=
263 keylist_QueryInterface
,
272 keylist_RemoveAllKeys
,
273 keylist_MakeSingleton
,
278 static HRESULT
WbemPathKeyList_create( IWbemPath
*parent
, LPVOID
*ppObj
)
280 struct keylist
*keylist
;
282 TRACE("%p\n", ppObj
);
284 if (!(keylist
= heap_alloc( sizeof(*keylist
) ))) return E_OUTOFMEMORY
;
286 keylist
->IWbemPathKeyList_iface
.lpVtbl
= &keylist_vtbl
;
288 keylist
->parent
= parent
;
289 IWbemPath_AddRef( keylist
->parent
);
291 *ppObj
= &keylist
->IWbemPathKeyList_iface
;
293 TRACE("returning iface %p\n", *ppObj
);
297 static void init_path( struct path
*path
)
302 path
->len_server
= 0;
303 path
->namespaces
= NULL
;
304 path
->len_namespaces
= NULL
;
305 path
->num_namespaces
= 0;
313 static void clear_path( struct path
*path
)
317 heap_free( path
->text
);
318 heap_free( path
->server
);
319 for (i
= 0; i
< path
->num_namespaces
; i
++) heap_free( path
->namespaces
[i
] );
320 heap_free( path
->namespaces
);
321 heap_free( path
->len_namespaces
);
322 heap_free( path
->class );
323 free_keys( path
->keys
, path
->num_keys
);
327 static ULONG WINAPI
path_AddRef(
330 struct path
*path
= impl_from_IWbemPath( iface
);
331 return InterlockedIncrement( &path
->refs
);
334 static ULONG WINAPI
path_Release(
337 struct path
*path
= impl_from_IWbemPath( iface
);
338 LONG refs
= InterlockedDecrement( &path
->refs
);
341 TRACE("destroying %p\n", path
);
343 path
->cs
.DebugInfo
->Spare
[0] = 0;
344 DeleteCriticalSection( &path
->cs
);
350 static HRESULT WINAPI
path_QueryInterface(
355 struct path
*path
= impl_from_IWbemPath( iface
);
357 TRACE("%p, %s, %p\n", path
, debugstr_guid( riid
), ppvObject
);
359 if ( IsEqualGUID( riid
, &IID_IWbemPath
) ||
360 IsEqualGUID( riid
, &IID_IUnknown
) )
366 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
367 return E_NOINTERFACE
;
369 IWbemPath_AddRef( iface
);
373 static HRESULT
parse_key( struct key
*key
, const WCHAR
*str
, unsigned int *ret_len
)
379 while (*q
&& *q
!= '=')
381 if (*q
== ',' || iswspace( *q
)) return WBEM_E_INVALID_PARAMETER
;
385 if (!(key
->name
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) return E_OUTOFMEMORY
;
386 memcpy( key
->name
, p
, len
* sizeof(WCHAR
) );
391 if (!*p
|| *p
== ',' || iswspace( *p
)) return WBEM_E_INVALID_PARAMETER
;
393 while (*q
&& *q
!= ',') q
++;
395 if (!(key
->value
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) return E_OUTOFMEMORY
;
396 memcpy( key
->value
, p
, len
* sizeof(WCHAR
) );
398 key
->len_value
= len
;
401 if (*q
== ',') (*ret_len
)++;
405 static HRESULT
parse_text( struct path
*path
, ULONG mode
, const WCHAR
*text
)
407 HRESULT hr
= E_OUTOFMEMORY
;
412 if ((p
[0] == '\\' && p
[1] == '\\') || (p
[0] == '/' && p
[1] == '/'))
416 while (*q
&& *q
!= '\\' && *q
!= '/') q
++;
418 if (!(path
->server
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
419 memcpy( path
->server
, p
, len
* sizeof(WCHAR
) );
420 path
->server
[len
] = 0;
421 path
->len_server
= len
;
422 path
->flags
|= WBEMPATH_INFO_PATH_HAD_SERVER
;
425 if (wcschr( p
, '\\' ) || wcschr( p
, '/' ))
427 if (*q
!= '\\' && *q
!= '/' && *q
!= ':')
429 path
->num_namespaces
= 1;
432 while (*q
&& *q
!= ':')
434 if (*q
== '\\' || *q
== '/') path
->num_namespaces
++;
438 if (path
->num_namespaces
)
440 if (!(path
->namespaces
= heap_alloc( path
->num_namespaces
* sizeof(WCHAR
*) ))) goto done
;
441 if (!(path
->len_namespaces
= heap_alloc( path
->num_namespaces
* sizeof(int) ))) goto done
;
445 if (*q
&& *q
!= '\\' && *q
!= '/' && *q
!= ':')
448 while (*p
&& *p
!= '\\' && *p
!= '/' && *p
!= ':') p
++;
450 if (!(path
->namespaces
[i
] = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
451 memcpy( path
->namespaces
[i
], q
, len
* sizeof(WCHAR
) );
452 path
->namespaces
[i
][len
] = 0;
453 path
->len_namespaces
[i
] = len
;
457 while (*q
&& *q
!= ':')
459 if (*q
== '\\' || *q
== '/')
462 while (*p
&& *p
!= '\\' && *p
!= '/' && *p
!= ':') p
++;
464 if (!(path
->namespaces
[i
] = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
465 memcpy( path
->namespaces
[i
], q
+ 1, len
* sizeof(WCHAR
) );
466 path
->namespaces
[i
][len
] = 0;
467 path
->len_namespaces
[i
] = len
;
475 while (*q
&& *q
!= '.') q
++;
477 if (!(path
->class = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
478 memcpy( path
->class, p
, len
* sizeof(WCHAR
) );
479 path
->class[len
] = 0;
480 path
->len_class
= len
;
488 if (*q
== ',') path
->num_keys
++;
491 if (!(path
->keys
= heap_alloc_zero( path
->num_keys
* sizeof(struct key
) ))) goto done
;
496 if (i
>= path
->num_keys
) break;
497 hr
= parse_key( &path
->keys
[i
], q
, &len
);
498 if (hr
!= S_OK
) goto done
;
506 if (hr
!= S_OK
) clear_path( path
);
507 else path
->flags
|= WBEMPATH_INFO_CIM_COMPLIANT
| WBEMPATH_INFO_V2_COMPLIANT
;
511 static HRESULT WINAPI
path_SetText(
516 struct path
*path
= impl_from_IWbemPath( iface
);
520 TRACE("%p, %u, %s\n", iface
, uMode
, debugstr_w(pszPath
));
522 if (!uMode
|| !pszPath
) return WBEM_E_INVALID_PARAMETER
;
524 EnterCriticalSection( &path
->cs
);
527 if (!pszPath
[0]) goto done
;
528 if ((hr
= parse_text( path
, uMode
, pszPath
)) != S_OK
) goto done
;
530 len
= lstrlenW( pszPath
);
531 if (!(path
->text
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) )))
537 lstrcpyW( path
->text
, pszPath
);
538 path
->len_text
= len
;
541 LeaveCriticalSection( &path
->cs
);
545 static WCHAR
*build_namespace( struct path
*path
, int *len
, BOOL leading_slash
)
551 for (i
= 0; i
< path
->num_namespaces
; i
++)
553 if (i
> 0 || leading_slash
) *len
+= 1;
554 *len
+= path
->len_namespaces
[i
];
556 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
557 for (i
= 0; i
< path
->num_namespaces
; i
++)
559 if (i
> 0 || leading_slash
) *p
++ = '\\';
560 memcpy( p
, path
->namespaces
[i
], path
->len_namespaces
[i
] * sizeof(WCHAR
) );
561 p
+= path
->len_namespaces
[i
];
567 static WCHAR
*build_server( struct path
*path
, int *len
)
572 if (path
->len_server
) *len
+= 2 + path
->len_server
;
574 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
575 if (path
->len_server
)
578 lstrcpyW( p
+ 2, path
->server
);
589 static WCHAR
*build_keylist( struct path
*path
, int *len
)
595 for (i
= 0; i
< path
->num_keys
; i
++)
597 if (i
> 0) *len
+= 1;
598 *len
+= path
->keys
[i
].len_name
+ path
->keys
[i
].len_value
+ 1;
600 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
601 for (i
= 0; i
< path
->num_keys
; i
++)
603 if (i
> 0) *p
++ = ',';
604 memcpy( p
, path
->keys
[i
].name
, path
->keys
[i
].len_name
* sizeof(WCHAR
) );
605 p
+= path
->keys
[i
].len_name
;
607 memcpy( p
, path
->keys
[i
].value
, path
->keys
[i
].len_value
* sizeof(WCHAR
) );
608 p
+= path
->keys
[i
].len_value
;
614 static WCHAR
*build_path( struct path
*path
, LONG flags
, int *len
)
621 int len_namespace
, len_keylist
;
622 WCHAR
*ret
, *namespace = build_namespace( path
, &len_namespace
, FALSE
);
623 WCHAR
*keylist
= build_keylist( path
, &len_keylist
);
625 if (!namespace || !keylist
)
627 heap_free( namespace );
628 heap_free( keylist
);
631 *len
= len_namespace
;
634 *len
+= path
->len_class
+ 1;
635 if (path
->num_keys
) *len
+= len_keylist
+ 1;
637 if (!(ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
639 heap_free( namespace );
640 heap_free( keylist
);
643 lstrcpyW( ret
, namespace );
646 ret
[len_namespace
] = ':';
647 lstrcpyW( ret
+ len_namespace
+ 1, path
->class );
650 ret
[len_namespace
+ path
->len_class
+ 1] = '.';
651 lstrcpyW( ret
+ len_namespace
+ path
->len_class
+ 2, keylist
);
654 heap_free( namespace );
655 heap_free( keylist
);
659 case WBEMPATH_GET_RELATIVE_ONLY
:
662 WCHAR
*ret
, *keylist
;
664 if (!path
->len_class
) return NULL
;
665 if (!(keylist
= build_keylist( path
, &len_keylist
))) return NULL
;
667 *len
= path
->len_class
;
668 if (path
->num_keys
) *len
+= len_keylist
+ 1;
669 if (!(ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
671 heap_free( keylist
);
674 lstrcpyW( ret
, path
->class );
677 ret
[path
->len_class
] = '.';
678 lstrcpyW( ret
+ path
->len_class
+ 1, keylist
);
680 heap_free( keylist
);
683 case WBEMPATH_GET_SERVER_TOO
:
685 int len_namespace
, len_server
, len_keylist
;
686 WCHAR
*p
, *ret
, *namespace = build_namespace( path
, &len_namespace
, TRUE
);
687 WCHAR
*server
= build_server( path
, &len_server
);
688 WCHAR
*keylist
= build_keylist( path
, &len_keylist
);
690 if (!namespace || !server
|| !keylist
)
692 heap_free( namespace );
694 heap_free( keylist
);
697 *len
= len_namespace
+ len_server
;
700 *len
+= path
->len_class
+ 1;
701 if (path
->num_keys
) *len
+= len_keylist
+ 1;
703 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
705 heap_free( namespace );
707 heap_free( keylist
);
710 lstrcpyW( p
, server
);
712 lstrcpyW( p
, namespace );
717 lstrcpyW( p
, path
->class );
720 p
[path
->len_class
] = '.';
721 lstrcpyW( p
+ path
->len_class
+ 1, keylist
);
724 heap_free( namespace );
726 heap_free( keylist
);
729 case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY
:
731 int len_namespace
, len_server
;
732 WCHAR
*p
, *ret
, *namespace = build_namespace( path
, &len_namespace
, TRUE
);
733 WCHAR
*server
= build_server( path
, &len_server
);
735 if (!namespace || !server
)
737 heap_free( namespace );
741 *len
= len_namespace
+ len_server
;
742 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
744 heap_free( namespace );
748 lstrcpyW( p
, server
);
750 lstrcpyW( p
, namespace );
751 heap_free( namespace );
755 case WBEMPATH_GET_NAMESPACE_ONLY
:
756 return build_namespace( path
, len
, FALSE
);
758 case WBEMPATH_GET_ORIGINAL
:
759 if (!path
->len_text
) return NULL
;
760 *len
= path
->len_text
;
761 return strdupW( path
->text
);
764 ERR("unhandled flags 0x%x\n", flags
);
769 static HRESULT WINAPI
path_GetText(
772 ULONG
*puBufferLength
,
775 struct path
*path
= impl_from_IWbemPath( iface
);
780 TRACE("%p, 0x%x, %p, %p\n", iface
, lFlags
, puBufferLength
, pszText
);
782 if (!puBufferLength
) return WBEM_E_INVALID_PARAMETER
;
784 EnterCriticalSection( &path
->cs
);
786 str
= build_path( path
, lFlags
, &len
);
787 if (*puBufferLength
< len
+ 1)
789 *puBufferLength
= len
+ 1;
794 hr
= WBEM_E_INVALID_PARAMETER
;
797 if (str
) lstrcpyW( pszText
, str
);
799 *puBufferLength
= len
+ 1;
801 TRACE("returning %s\n", debugstr_w(pszText
));
805 LeaveCriticalSection( &path
->cs
);
809 static HRESULT WINAPI
path_GetInfo(
814 struct path
*path
= impl_from_IWbemPath( iface
);
816 TRACE("%p, %u, %p\n", iface
, info
, response
);
818 if (info
|| !response
) return WBEM_E_INVALID_PARAMETER
;
820 FIXME("some flags are not implemented\n");
822 EnterCriticalSection( &path
->cs
);
824 *response
= path
->flags
;
825 if (!path
->server
|| (path
->len_server
== 1 && path
->server
[0] == '.'))
826 *response
|= WBEMPATH_INFO_ANON_LOCAL_MACHINE
;
828 *response
|= WBEMPATH_INFO_HAS_MACHINE_NAME
;
831 *response
|= WBEMPATH_INFO_SERVER_NAMESPACE_ONLY
;
834 *response
|= WBEMPATH_INFO_HAS_SUBSCOPES
;
836 *response
|= WBEMPATH_INFO_IS_INST_REF
;
838 *response
|= WBEMPATH_INFO_IS_CLASS_REF
;
841 LeaveCriticalSection( &path
->cs
);
845 static HRESULT WINAPI
path_SetServer(
849 struct path
*path
= impl_from_IWbemPath( iface
);
850 static const ULONGLONG flags
=
851 WBEMPATH_INFO_PATH_HAD_SERVER
| WBEMPATH_INFO_V1_COMPLIANT
|
852 WBEMPATH_INFO_V2_COMPLIANT
| WBEMPATH_INFO_CIM_COMPLIANT
;
855 TRACE("%p, %s\n", iface
, debugstr_w(name
));
857 EnterCriticalSection( &path
->cs
);
861 if (!(server
= strdupW( name
)))
863 LeaveCriticalSection( &path
->cs
);
864 return WBEM_E_OUT_OF_MEMORY
;
866 heap_free( path
->server
);
867 path
->server
= server
;
868 path
->len_server
= lstrlenW( path
->server
);
869 path
->flags
|= flags
;
873 heap_free( path
->server
);
875 path
->len_server
= 0;
876 path
->flags
&= ~flags
;
879 LeaveCriticalSection( &path
->cs
);
883 static HRESULT WINAPI
path_GetServer(
888 struct path
*path
= impl_from_IWbemPath( iface
);
890 TRACE("%p, %p, %p\n", iface
, len
, name
);
892 if (!len
|| (*len
&& !name
)) return WBEM_E_INVALID_PARAMETER
;
894 EnterCriticalSection( &path
->cs
);
898 LeaveCriticalSection( &path
->cs
);
899 return WBEM_E_NOT_AVAILABLE
;
901 if (*len
> path
->len_server
) lstrcpyW( name
, path
->server
);
902 *len
= path
->len_server
+ 1;
904 LeaveCriticalSection( &path
->cs
);
908 static HRESULT WINAPI
path_GetNamespaceCount(
912 struct path
*path
= impl_from_IWbemPath( iface
);
914 TRACE("%p, %p\n", iface
, puCount
);
916 if (!puCount
) return WBEM_E_INVALID_PARAMETER
;
918 EnterCriticalSection( &path
->cs
);
919 *puCount
= path
->num_namespaces
;
920 LeaveCriticalSection( &path
->cs
);
924 static HRESULT WINAPI
path_SetNamespaceAt(
929 struct path
*path
= impl_from_IWbemPath( iface
);
930 static const ULONGLONG flags
=
931 WBEMPATH_INFO_V1_COMPLIANT
| WBEMPATH_INFO_V2_COMPLIANT
|
932 WBEMPATH_INFO_CIM_COMPLIANT
;
937 TRACE("%p, %u, %s\n", iface
, idx
, debugstr_w(name
));
939 EnterCriticalSection( &path
->cs
);
941 if (idx
> path
->num_namespaces
|| !name
)
943 LeaveCriticalSection( &path
->cs
);
944 return WBEM_E_INVALID_PARAMETER
;
946 if (!(new = strdupW( name
)))
948 LeaveCriticalSection( &path
->cs
);
949 return WBEM_E_OUT_OF_MEMORY
;
951 size
= (path
->num_namespaces
+ 1) * sizeof(WCHAR
*);
952 if (path
->namespaces
) tmp
= heap_realloc( path
->namespaces
, size
);
953 else tmp
= heap_alloc( size
);
957 LeaveCriticalSection( &path
->cs
);
958 return WBEM_E_OUT_OF_MEMORY
;
960 path
->namespaces
= tmp
;
961 size
= (path
->num_namespaces
+ 1) * sizeof(int);
962 if (path
->len_namespaces
) tmp_len
= heap_realloc( path
->len_namespaces
, size
);
963 else tmp_len
= heap_alloc( size
);
967 LeaveCriticalSection( &path
->cs
);
968 return WBEM_E_OUT_OF_MEMORY
;
970 path
->len_namespaces
= tmp_len
;
971 for (i
= idx
; i
< path
->num_namespaces
; i
++)
973 path
->namespaces
[i
+ 1] = path
->namespaces
[i
];
974 path
->len_namespaces
[i
+ 1] = path
->len_namespaces
[i
];
976 path
->namespaces
[idx
] = new;
977 path
->len_namespaces
[idx
] = lstrlenW( new );
978 path
->num_namespaces
++;
979 path
->flags
|= flags
;
981 LeaveCriticalSection( &path
->cs
);
985 static HRESULT WINAPI
path_GetNamespaceAt(
991 struct path
*path
= impl_from_IWbemPath( iface
);
993 TRACE("%p, %u, %p, %p\n", iface
, idx
, len
, name
);
995 EnterCriticalSection( &path
->cs
);
997 if (!len
|| (*len
&& !name
) || idx
>= path
->num_namespaces
)
999 LeaveCriticalSection( &path
->cs
);
1000 return WBEM_E_INVALID_PARAMETER
;
1002 if (*len
> path
->len_namespaces
[idx
]) lstrcpyW( name
, path
->namespaces
[idx
] );
1003 *len
= path
->len_namespaces
[idx
] + 1;
1005 LeaveCriticalSection( &path
->cs
);
1009 static HRESULT WINAPI
path_RemoveNamespaceAt(
1013 struct path
*path
= impl_from_IWbemPath( iface
);
1015 TRACE("%p, %u\n", iface
, idx
);
1017 EnterCriticalSection( &path
->cs
);
1019 if (idx
>= path
->num_namespaces
)
1021 LeaveCriticalSection( &path
->cs
);
1022 return WBEM_E_INVALID_PARAMETER
;
1024 heap_free( path
->namespaces
[idx
] );
1025 while (idx
< path
->num_namespaces
- 1)
1027 path
->namespaces
[idx
] = path
->namespaces
[idx
+ 1];
1028 path
->len_namespaces
[idx
] = path
->len_namespaces
[idx
+ 1];
1031 path
->num_namespaces
--;
1033 LeaveCriticalSection( &path
->cs
);
1037 static HRESULT WINAPI
path_RemoveAllNamespaces(
1040 struct path
*path
= impl_from_IWbemPath( iface
);
1043 TRACE("%p\n", iface
);
1045 EnterCriticalSection( &path
->cs
);
1047 for (i
= 0; i
< path
->num_namespaces
; i
++) heap_free( path
->namespaces
[i
] );
1048 path
->num_namespaces
= 0;
1049 heap_free( path
->namespaces
);
1050 path
->namespaces
= NULL
;
1051 heap_free( path
->len_namespaces
);
1052 path
->len_namespaces
= NULL
;
1054 LeaveCriticalSection( &path
->cs
);
1058 static HRESULT WINAPI
path_GetScopeCount(
1062 FIXME("%p, %p\n", iface
, puCount
);
1066 static HRESULT WINAPI
path_SetScope(
1071 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszClass
));
1075 static HRESULT WINAPI
path_SetScopeFromText(
1080 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszText
));
1084 static HRESULT WINAPI
path_GetScope(
1087 ULONG
*puClassNameBufSize
,
1089 IWbemPathKeyList
**pKeyList
)
1091 FIXME("%p, %u, %p, %p, %p\n", iface
, uIndex
, puClassNameBufSize
, pszClass
, pKeyList
);
1095 static HRESULT WINAPI
path_GetScopeAsText(
1098 ULONG
*puTextBufSize
,
1101 FIXME("%p, %u, %p, %p\n", iface
, uIndex
, puTextBufSize
, pszText
);
1105 static HRESULT WINAPI
path_RemoveScope(
1109 FIXME("%p, %u\n", iface
, uIndex
);
1113 static HRESULT WINAPI
path_RemoveAllScopes(
1116 FIXME("%p\n", iface
);
1120 static HRESULT WINAPI
path_SetClassName(
1124 struct path
*path
= impl_from_IWbemPath( iface
);
1127 TRACE("%p, %s\n", iface
, debugstr_w(name
));
1129 if (!name
) return WBEM_E_INVALID_PARAMETER
;
1130 if (!(class = strdupW( name
))) return WBEM_E_OUT_OF_MEMORY
;
1132 EnterCriticalSection( &path
->cs
);
1134 heap_free( path
->class );
1135 path
->class = class;
1136 path
->len_class
= lstrlenW( path
->class );
1137 path
->flags
|= WBEMPATH_INFO_V2_COMPLIANT
| WBEMPATH_INFO_CIM_COMPLIANT
;
1139 LeaveCriticalSection( &path
->cs
);
1143 static HRESULT WINAPI
path_GetClassName(
1148 struct path
*path
= impl_from_IWbemPath( iface
);
1150 TRACE("%p, %p, %p\n", iface
, len
, name
);
1152 if (!len
|| (*len
&& !name
)) return WBEM_E_INVALID_PARAMETER
;
1154 EnterCriticalSection( &path
->cs
);
1158 LeaveCriticalSection( &path
->cs
);
1159 return WBEM_E_INVALID_OBJECT_PATH
;
1161 if (*len
> path
->len_class
) lstrcpyW( name
, path
->class );
1162 *len
= path
->len_class
+ 1;
1164 LeaveCriticalSection( &path
->cs
);
1168 static HRESULT WINAPI
path_GetKeyList(
1170 IWbemPathKeyList
**pOut
)
1172 struct path
*path
= impl_from_IWbemPath( iface
);
1175 TRACE("%p, %p\n", iface
, pOut
);
1177 EnterCriticalSection( &path
->cs
);
1181 LeaveCriticalSection( &path
->cs
);
1182 return WBEM_E_INVALID_PARAMETER
;
1184 hr
= WbemPathKeyList_create( iface
, (void **)pOut
);
1186 LeaveCriticalSection( &path
->cs
);
1190 static HRESULT WINAPI
path_CreateClassPart(
1195 FIXME("%p, 0x%x, %s\n", iface
, lFlags
, debugstr_w(Name
));
1199 static HRESULT WINAPI
path_DeleteClassPart(
1203 FIXME("%p, 0x%x\n", iface
, lFlags
);
1207 static BOOL WINAPI
path_IsRelative(
1210 LPWSTR wszNamespace
)
1212 FIXME("%p, %s, %s\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
));
1216 static BOOL WINAPI
path_IsRelativeOrChild(
1219 LPWSTR wszNamespace
,
1222 FIXME("%p, %s, %s, 0x%x\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
), lFlags
);
1226 static BOOL WINAPI
path_IsLocal(
1230 FIXME("%p, %s\n", iface
, debugstr_w(wszMachine
));
1234 static BOOL WINAPI
path_IsSameClassName(
1238 FIXME("%p, %s\n", iface
, debugstr_w(wszClass
));
1242 static const struct IWbemPathVtbl path_vtbl
=
1244 path_QueryInterface
,
1252 path_GetNamespaceCount
,
1253 path_SetNamespaceAt
,
1254 path_GetNamespaceAt
,
1255 path_RemoveNamespaceAt
,
1256 path_RemoveAllNamespaces
,
1259 path_SetScopeFromText
,
1261 path_GetScopeAsText
,
1263 path_RemoveAllScopes
,
1267 path_CreateClassPart
,
1268 path_DeleteClassPart
,
1270 path_IsRelativeOrChild
,
1272 path_IsSameClassName
1275 HRESULT
WbemPath_create( LPVOID
*ppObj
)
1279 TRACE("%p\n", ppObj
);
1281 if (!(path
= heap_alloc( sizeof(*path
) ))) return E_OUTOFMEMORY
;
1283 path
->IWbemPath_iface
.lpVtbl
= &path_vtbl
;
1285 InitializeCriticalSection( &path
->cs
);
1286 path
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": wmiutils_path.cs");
1289 *ppObj
= &path
->IWbemPath_iface
;
1291 TRACE("returning iface %p\n", *ppObj
);