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 IWbemPath IWbemPath_iface
;
50 static void init_path( struct path
*path
)
56 path
->namespaces
= NULL
;
57 path
->len_namespaces
= NULL
;
58 path
->num_namespaces
= 0;
63 static void clear_path( struct path
*path
)
65 heap_free( path
->text
);
66 heap_free( path
->server
);
67 heap_free( path
->namespaces
);
68 heap_free( path
->len_namespaces
);
69 heap_free( path
->class );
73 static inline struct path
*impl_from_IWbemPath( IWbemPath
*iface
)
75 return CONTAINING_RECORD(iface
, struct path
, IWbemPath_iface
);
78 static ULONG WINAPI
path_AddRef(
81 struct path
*path
= impl_from_IWbemPath( iface
);
82 return InterlockedIncrement( &path
->refs
);
85 static ULONG WINAPI
path_Release(
88 struct path
*path
= impl_from_IWbemPath( iface
);
89 LONG refs
= InterlockedDecrement( &path
->refs
);
92 TRACE("destroying %p\n", path
);
99 static HRESULT WINAPI
path_QueryInterface(
104 struct path
*path
= impl_from_IWbemPath( iface
);
106 TRACE("%p, %s, %p\n", path
, debugstr_guid( riid
), ppvObject
);
108 if ( IsEqualGUID( riid
, &IID_IWbemPath
) ||
109 IsEqualGUID( riid
, &IID_IUnknown
) )
115 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
116 return E_NOINTERFACE
;
118 IWbemPath_AddRef( iface
);
122 static HRESULT
parse_text( struct path
*path
, ULONG mode
, const WCHAR
*text
)
124 HRESULT hr
= E_OUTOFMEMORY
;
129 if ((p
[0] == '\\' && p
[1] == '\\') || (p
[0] == '/' && p
[1] == '/'))
133 while (*q
&& *q
!= '\\' && *q
!= '/') q
++;
135 if (!(path
->server
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
136 memcpy( path
->server
, p
, len
* sizeof(WCHAR
) );
137 path
->server
[len
] = 0;
138 path
->len_server
= len
;
141 while (*q
&& *q
!= ':')
143 if (*q
== '\\' || *q
== '/') path
->num_namespaces
++;
146 if (path
->num_namespaces
)
148 if (!(path
->namespaces
= heap_alloc( path
->num_namespaces
* sizeof(WCHAR
*) ))) goto done
;
149 if (!(path
->len_namespaces
= heap_alloc( path
->num_namespaces
* sizeof(int) ))) goto done
;
153 while (*q
&& *q
!= ':')
155 if (*q
== '\\' || *q
== '/')
158 while (*p
&& *p
!= '\\' && *p
!= '/' && *p
!= ':') p
++;
160 if (!(path
->namespaces
[i
] = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
161 memcpy( path
->namespaces
[i
], q
+ 1, len
* sizeof(WCHAR
) );
162 path
->namespaces
[i
][len
] = 0;
163 path
->len_namespaces
[i
] = len
;
171 while (*q
&& *q
!= '.') q
++;
173 if (!(path
->class = heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) goto done
;
174 memcpy( path
->class, p
, len
* sizeof(WCHAR
) );
175 path
->class[len
] = 0;
176 path
->len_class
= len
;
178 if (*q
== '.') FIXME("handle key list\n");
182 if (hr
!= S_OK
) clear_path( path
);
186 static HRESULT WINAPI
path_SetText(
191 struct path
*path
= impl_from_IWbemPath( iface
);
195 TRACE("%p, %u, %s\n", iface
, uMode
, debugstr_w(pszPath
));
197 if (!uMode
|| !pszPath
) return WBEM_E_INVALID_PARAMETER
;
200 if ((hr
= parse_text( path
, uMode
, pszPath
)) != S_OK
) return hr
;
202 len
= strlenW( pszPath
);
203 if (!(path
->text
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) )))
206 return E_OUTOFMEMORY
;
208 strcpyW( path
->text
, pszPath
);
209 path
->len_text
= len
;
213 static WCHAR
*build_namespace( struct path
*path
, int *len
, BOOL leading_slash
)
219 for (i
= 0; i
< path
->num_namespaces
; i
++)
221 if (i
> 0 || leading_slash
) *len
+= 1;
222 *len
+= path
->len_namespaces
[i
];
224 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
225 for (i
= 0; i
< path
->num_namespaces
; i
++)
227 if (i
> 0 || leading_slash
) *p
++ = '\\';
228 memcpy( p
, path
->namespaces
[i
], path
->len_namespaces
[i
] * sizeof(WCHAR
) );
229 p
+= path
->len_namespaces
[i
];
235 static WCHAR
*build_server( struct path
*path
, int *len
)
240 if (path
->len_server
) *len
+= 2 + path
->len_server
;
242 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
243 if (path
->len_server
)
246 strcpyW( p
+ 2, path
->server
);
256 static WCHAR
*build_path( struct path
*path
, LONG flags
, int *len
)
263 WCHAR
*ret
, *namespace = build_namespace( path
, &len_namespace
, FALSE
);
265 if (!namespace) return NULL
;
267 *len
= len_namespace
;
268 if (path
->len_class
) *len
+= 1 + path
->len_class
;
269 if (!(ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
271 heap_free( namespace );
274 strcpyW( ret
, namespace );
277 ret
[len_namespace
] = ':';
278 strcpyW( ret
+ len_namespace
+ 1, path
->class );
280 heap_free( namespace );
284 case WBEMPATH_GET_RELATIVE_ONLY
:
285 if (!path
->len_class
)
290 *len
= path
->len_class
;
291 return strdupW( path
->class );
293 case WBEMPATH_GET_SERVER_TOO
:
295 int len_namespace
, len_server
;
296 WCHAR
*p
, *ret
, *namespace = build_namespace( path
, &len_namespace
, TRUE
);
297 WCHAR
*server
= build_server( path
, &len_server
);
299 if (!namespace || !server
)
301 heap_free( namespace );
305 *len
= len_namespace
+ len_server
;
306 if (path
->len_class
) *len
+= 1 + path
->len_class
;
307 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
309 heap_free( namespace );
313 strcpyW( p
, server
);
315 strcpyW( p
, namespace );
320 strcpyW( p
+ 1, path
->class );
322 heap_free( namespace );
326 case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY
:
328 int len_namespace
, len_server
;
329 WCHAR
*p
, *ret
, *namespace = build_namespace( path
, &len_namespace
, TRUE
);
330 WCHAR
*server
= build_server( path
, &len_server
);
332 if (!namespace || !server
)
334 heap_free( namespace );
338 *len
= len_namespace
+ len_server
;
339 if (!(p
= ret
= heap_alloc( (*len
+ 1) * sizeof(WCHAR
) )))
341 heap_free( namespace );
345 strcpyW( p
, server
);
347 strcpyW( p
, namespace );
348 heap_free( namespace );
352 case WBEMPATH_GET_NAMESPACE_ONLY
:
353 return build_namespace( path
, len
, FALSE
);
355 case WBEMPATH_GET_ORIGINAL
:
361 *len
= path
->len_text
;
362 return strdupW( path
->text
);
365 ERR("unhandled flags 0x%x\n", flags
);
370 static HRESULT WINAPI
path_GetText(
373 ULONG
*puBufferLength
,
376 struct path
*path
= impl_from_IWbemPath( iface
);
380 TRACE("%p, 0x%x, %p, %p\n", iface
, lFlags
, puBufferLength
, pszText
);
382 if (!puBufferLength
) return WBEM_E_INVALID_PARAMETER
;
384 str
= build_path( path
, lFlags
, &len
);
386 if (*puBufferLength
< len
+ 1)
388 *puBufferLength
= len
+ 1;
394 return WBEM_E_INVALID_PARAMETER
;
396 if (str
) strcpyW( pszText
, str
);
398 *puBufferLength
= len
+ 1;
400 TRACE("<-- %s\n", debugstr_w(pszText
));
405 static HRESULT WINAPI
path_GetInfo(
407 ULONG uRequestedInfo
,
408 ULONGLONG
*puResponse
)
410 FIXME("%p, %d, %p\n", iface
, uRequestedInfo
, puResponse
);
414 static HRESULT WINAPI
path_SetServer(
418 FIXME("%p, %s\n", iface
, debugstr_w(Name
));
422 static HRESULT WINAPI
path_GetServer(
424 ULONG
*puNameBufLength
,
427 FIXME("%p, %p, %p\n", iface
, puNameBufLength
, pName
);
431 static HRESULT WINAPI
path_GetNamespaceCount(
435 struct path
*path
= impl_from_IWbemPath( iface
);
437 TRACE("%p, %p\n", iface
, puCount
);
439 if (!puCount
) return WBEM_E_INVALID_PARAMETER
;
440 *puCount
= path
->num_namespaces
;
444 static HRESULT WINAPI
path_SetNamespaceAt(
449 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszName
));
453 static HRESULT WINAPI
path_GetNamespaceAt(
456 ULONG
*puNameBufLength
,
459 FIXME("%p, %u, %p, %p\n", iface
, uIndex
, puNameBufLength
, pName
);
463 static HRESULT WINAPI
path_RemoveNamespaceAt(
467 FIXME("%p, %u\n", iface
, uIndex
);
471 static HRESULT WINAPI
path_RemoveAllNamespaces(
474 FIXME("%p\n", iface
);
478 static HRESULT WINAPI
path_GetScopeCount(
482 FIXME("%p, %p\n", iface
, puCount
);
486 static HRESULT WINAPI
path_SetScope(
491 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszClass
));
495 static HRESULT WINAPI
path_SetScopeFromText(
500 FIXME("%p, %u, %s\n", iface
, uIndex
, debugstr_w(pszText
));
504 static HRESULT WINAPI
path_GetScope(
507 ULONG
*puClassNameBufSize
,
509 IWbemPathKeyList
**pKeyList
)
511 FIXME("%p, %u, %p, %p, %p\n", iface
, uIndex
, puClassNameBufSize
, pszClass
, pKeyList
);
515 static HRESULT WINAPI
path_GetScopeAsText(
518 ULONG
*puTextBufSize
,
521 FIXME("%p, %u, %p, %p\n", iface
, uIndex
, puTextBufSize
, pszText
);
525 static HRESULT WINAPI
path_RemoveScope(
529 FIXME("%p, %u\n", iface
, uIndex
);
533 static HRESULT WINAPI
path_RemoveAllScopes(
536 FIXME("%p\n", iface
);
540 static HRESULT WINAPI
path_SetClassName(
544 FIXME("%p, %s\n", iface
, debugstr_w(Name
));
548 static HRESULT WINAPI
path_GetClassName(
550 ULONG
*puBufferLength
,
553 FIXME("%p,%p, %p\n", iface
, puBufferLength
, pszName
);
557 static HRESULT WINAPI
path_GetKeyList(
559 IWbemPathKeyList
**pOut
)
561 FIXME("%p, %p\n", iface
, pOut
);
565 static HRESULT WINAPI
path_CreateClassPart(
570 FIXME("%p, 0x%x, %s\n", iface
, lFlags
, debugstr_w(Name
));
574 static HRESULT WINAPI
path_DeleteClassPart(
578 FIXME("%p, 0x%x\n", iface
, lFlags
);
582 static BOOL WINAPI
path_IsRelative(
587 FIXME("%p, %s, %s\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
));
591 static BOOL WINAPI
path_IsRelativeOrChild(
597 FIXME("%p, %s, %s, 0x%x\n", iface
, debugstr_w(wszMachine
), debugstr_w(wszNamespace
), lFlags
);
601 static BOOL WINAPI
path_IsLocal(
605 FIXME("%p, %s\n", iface
, debugstr_w(wszMachine
));
609 static BOOL WINAPI
path_IsSameClassName(
613 FIXME("%p, %s\n", iface
, debugstr_w(wszClass
));
617 static const struct IWbemPathVtbl path_vtbl
=
627 path_GetNamespaceCount
,
630 path_RemoveNamespaceAt
,
631 path_RemoveAllNamespaces
,
634 path_SetScopeFromText
,
638 path_RemoveAllScopes
,
642 path_CreateClassPart
,
643 path_DeleteClassPart
,
645 path_IsRelativeOrChild
,
650 HRESULT
WbemPath_create( IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
654 TRACE("%p, %p\n", pUnkOuter
, ppObj
);
656 if (!(path
= heap_alloc( sizeof(*path
) ))) return E_OUTOFMEMORY
;
658 path
->IWbemPath_iface
.lpVtbl
= &path_vtbl
;
662 *ppObj
= &path
->IWbemPath_iface
;
664 TRACE("returning iface %p\n", *ppObj
);