iphlpapi: Move the ICMP reply retrieval to a helper function.
[wine.git] / dlls / wbemprox / services.c
blobab7146db2d8e192460e196319ad70ac717d2db3e
1 /*
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
19 #define COBJMACROS
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "objbase.h"
26 #include "wbemcli.h"
28 #include "wine/debug.h"
29 #include "wbemprox_private.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
33 struct client_security
35 IClientSecurity IClientSecurity_iface;
38 static inline struct client_security *impl_from_IClientSecurity( IClientSecurity *iface )
40 return CONTAINING_RECORD( iface, struct client_security, IClientSecurity_iface );
43 static HRESULT WINAPI client_security_QueryInterface(
44 IClientSecurity *iface,
45 REFIID riid,
46 void **ppvObject )
48 struct client_security *cs = impl_from_IClientSecurity( iface );
50 TRACE("%p %s %p\n", cs, debugstr_guid( riid ), ppvObject );
52 if ( IsEqualGUID( riid, &IID_IClientSecurity ) ||
53 IsEqualGUID( riid, &IID_IUnknown ) )
55 *ppvObject = cs;
57 else
59 FIXME("interface %s not implemented\n", debugstr_guid(riid));
60 return E_NOINTERFACE;
62 IClientSecurity_AddRef( iface );
63 return S_OK;
66 static ULONG WINAPI client_security_AddRef(
67 IClientSecurity *iface )
69 FIXME("%p\n", iface);
70 return 2;
73 static ULONG WINAPI client_security_Release(
74 IClientSecurity *iface )
76 FIXME("%p\n", iface);
77 return 1;
80 static HRESULT WINAPI client_security_QueryBlanket(
81 IClientSecurity *iface,
82 IUnknown *pProxy,
83 DWORD *pAuthnSvc,
84 DWORD *pAuthzSvc,
85 OLECHAR **pServerPrincName,
86 DWORD *pAuthnLevel,
87 DWORD *pImpLevel,
88 void **pAuthInfo,
89 DWORD *pCapabilities )
91 FIXME("semi-stub.\n");
93 if (pAuthnSvc)
94 *pAuthnSvc = RPC_C_AUTHN_NONE;
95 if (pAuthzSvc)
96 *pAuthzSvc = RPC_C_AUTHZ_NONE;
97 if (pServerPrincName)
98 *pServerPrincName = NULL;
99 if (pAuthnLevel)
100 *pAuthnLevel = RPC_C_AUTHN_LEVEL_NONE;
101 if (pImpLevel)
102 *pImpLevel = RPC_C_IMP_LEVEL_DEFAULT;
103 if (pAuthInfo)
104 *pAuthInfo = NULL;
105 if (pCapabilities)
106 *pCapabilities = 0;
108 return WBEM_NO_ERROR;
111 static HRESULT WINAPI client_security_SetBlanket(
112 IClientSecurity *iface,
113 IUnknown *pProxy,
114 DWORD AuthnSvc,
115 DWORD AuthzSvc,
116 OLECHAR *pServerPrincName,
117 DWORD AuthnLevel,
118 DWORD ImpLevel,
119 void *pAuthInfo,
120 DWORD Capabilities )
122 const OLECHAR *princname = (pServerPrincName == COLE_DEFAULT_PRINCIPAL) ?
123 L"<COLE_DEFAULT_PRINCIPAL>" : pServerPrincName;
125 FIXME("%p, %p, %u, %u, %s, %u, %u, %p, 0x%08x\n", iface, pProxy, AuthnSvc, AuthzSvc,
126 debugstr_w(princname), AuthnLevel, ImpLevel, pAuthInfo, Capabilities);
127 return WBEM_NO_ERROR;
130 static HRESULT WINAPI client_security_CopyProxy(
131 IClientSecurity *iface,
132 IUnknown *pProxy,
133 IUnknown **ppCopy )
135 FIXME("\n");
136 return WBEM_E_FAILED;
139 static const IClientSecurityVtbl client_security_vtbl =
141 client_security_QueryInterface,
142 client_security_AddRef,
143 client_security_Release,
144 client_security_QueryBlanket,
145 client_security_SetBlanket,
146 client_security_CopyProxy
149 IClientSecurity client_security = { &client_security_vtbl };
151 struct async_header
153 IWbemObjectSink *sink;
154 void (*proc)( struct async_header * );
155 HANDLE cancel;
156 HANDLE wait;
159 struct async_query
161 struct async_header hdr;
162 WCHAR *str;
165 static void free_async( struct async_header *async )
167 if (async->sink) IWbemObjectSink_Release( async->sink );
168 CloseHandle( async->cancel );
169 CloseHandle( async->wait );
170 heap_free( async );
173 static BOOL init_async( struct async_header *async, IWbemObjectSink *sink,
174 void (*proc)(struct async_header *) )
176 if (!(async->wait = CreateEventW( NULL, FALSE, FALSE, NULL ))) return FALSE;
177 if (!(async->cancel = CreateEventW( NULL, FALSE, FALSE, NULL )))
179 CloseHandle( async->wait );
180 return FALSE;
182 async->proc = proc;
183 async->sink = sink;
184 IWbemObjectSink_AddRef( sink );
185 return TRUE;
188 static DWORD CALLBACK async_proc( LPVOID param )
190 struct async_header *async = param;
191 HANDLE wait = async->wait;
193 async->proc( async );
195 WaitForSingleObject( async->cancel, INFINITE );
196 SetEvent( wait );
197 return ERROR_SUCCESS;
200 static HRESULT queue_async( struct async_header *async )
202 if (QueueUserWorkItem( async_proc, async, WT_EXECUTELONGFUNCTION )) return S_OK;
203 return HRESULT_FROM_WIN32( GetLastError() );
206 struct wbem_services
208 IWbemServices IWbemServices_iface;
209 LONG refs;
210 CRITICAL_SECTION cs;
211 WCHAR *namespace;
212 struct async_header *async;
215 static inline struct wbem_services *impl_from_IWbemServices( IWbemServices *iface )
217 return CONTAINING_RECORD( iface, struct wbem_services, IWbemServices_iface );
220 static ULONG WINAPI wbem_services_AddRef(
221 IWbemServices *iface )
223 struct wbem_services *ws = impl_from_IWbemServices( iface );
224 return InterlockedIncrement( &ws->refs );
227 static ULONG WINAPI wbem_services_Release(
228 IWbemServices *iface )
230 struct wbem_services *ws = impl_from_IWbemServices( iface );
231 LONG refs = InterlockedDecrement( &ws->refs );
232 if (!refs)
234 TRACE("destroying %p\n", ws);
236 EnterCriticalSection( &ws->cs );
237 if (ws->async) SetEvent( ws->async->cancel );
238 LeaveCriticalSection( &ws->cs );
239 if (ws->async)
241 WaitForSingleObject( ws->async->wait, INFINITE );
242 free_async( ws->async );
244 ws->cs.DebugInfo->Spare[0] = 0;
245 DeleteCriticalSection( &ws->cs );
246 heap_free( ws->namespace );
247 heap_free( ws );
249 return refs;
252 static HRESULT WINAPI wbem_services_QueryInterface(
253 IWbemServices *iface,
254 REFIID riid,
255 void **ppvObject )
257 struct wbem_services *ws = impl_from_IWbemServices( iface );
259 TRACE("%p %s %p\n", ws, debugstr_guid( riid ), ppvObject );
261 if ( IsEqualGUID( riid, &IID_IWbemServices ) ||
262 IsEqualGUID( riid, &IID_IUnknown ) )
264 *ppvObject = ws;
266 else if ( IsEqualGUID( riid, &IID_IClientSecurity ) )
268 *ppvObject = &client_security;
269 return S_OK;
271 else
273 FIXME("interface %s not implemented\n", debugstr_guid(riid));
274 return E_NOINTERFACE;
276 IWbemServices_AddRef( iface );
277 return S_OK;
280 static HRESULT WINAPI wbem_services_OpenNamespace(
281 IWbemServices *iface,
282 const BSTR strNamespace,
283 LONG lFlags,
284 IWbemContext *pCtx,
285 IWbemServices **ppWorkingNamespace,
286 IWbemCallResult **ppResult )
288 struct wbem_services *ws = impl_from_IWbemServices( iface );
290 TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strNamespace), lFlags,
291 pCtx, ppWorkingNamespace, ppResult);
293 if ((wcsicmp( strNamespace, L"cimv2" ) && wcsicmp( strNamespace, L"default" )) || ws->namespace)
294 return WBEM_E_INVALID_NAMESPACE;
296 return WbemServices_create( L"cimv2", (void **)ppWorkingNamespace );
299 static HRESULT WINAPI wbem_services_CancelAsyncCall(
300 IWbemServices *iface,
301 IWbemObjectSink *pSink )
303 struct wbem_services *services = impl_from_IWbemServices( iface );
304 struct async_header *async;
306 TRACE("%p, %p\n", iface, pSink);
308 if (!pSink) return WBEM_E_INVALID_PARAMETER;
310 EnterCriticalSection( &services->cs );
312 if (!(async = services->async))
314 LeaveCriticalSection( &services->cs );
315 return WBEM_E_INVALID_PARAMETER;
317 services->async = NULL;
318 SetEvent( async->cancel );
320 LeaveCriticalSection( &services->cs );
322 WaitForSingleObject( async->wait, INFINITE );
323 free_async( async );
324 return S_OK;
327 static HRESULT WINAPI wbem_services_QueryObjectSink(
328 IWbemServices *iface,
329 LONG lFlags,
330 IWbemObjectSink **ppResponseHandler )
332 FIXME("\n");
333 return WBEM_E_FAILED;
336 HRESULT parse_path( const WCHAR *str, struct path **ret )
338 struct path *path;
339 const WCHAR *p = str, *q;
340 UINT len;
342 if (!(path = heap_alloc_zero( sizeof(*path) ))) return E_OUTOFMEMORY;
344 if (*p == '\\')
346 static const WCHAR cimv2W[] = L"ROOT\\CIMV2";
347 WCHAR server[MAX_COMPUTERNAME_LENGTH+1];
348 DWORD server_len = ARRAY_SIZE(server);
350 p++;
351 if (*p != '\\')
353 heap_free( path );
354 return WBEM_E_INVALID_OBJECT_PATH;
356 p++;
358 q = p;
359 while (*p && *p != '\\') p++;
360 if (!*p)
362 heap_free( path );
363 return WBEM_E_INVALID_OBJECT_PATH;
366 len = p - q;
367 if (!GetComputerNameW( server, &server_len ) || server_len != len || wcsnicmp( q, server, server_len ))
369 heap_free( path );
370 return WBEM_E_NOT_SUPPORTED;
373 q = ++p;
374 while (*p && *p != ':') p++;
375 if (!*p)
377 heap_free( path );
378 return WBEM_E_INVALID_OBJECT_PATH;
381 len = p - q;
382 if (len != ARRAY_SIZE(cimv2W) - 1 || wcsnicmp( q, cimv2W, ARRAY_SIZE(cimv2W) - 1 ))
384 heap_free( path );
385 return WBEM_E_INVALID_NAMESPACE;
387 p++;
390 q = p;
391 while (*p && *p != '.') p++;
393 len = p - q;
394 if (!(path->class = heap_alloc( (len + 1) * sizeof(WCHAR) )))
396 heap_free( path );
397 return E_OUTOFMEMORY;
399 memcpy( path->class, q, len * sizeof(WCHAR) );
400 path->class[len] = 0;
401 path->class_len = len;
403 if (p[0] == '.' && p[1])
405 q = ++p;
406 while (*q) q++;
408 len = q - p;
409 if (!(path->filter = heap_alloc( (len + 1) * sizeof(WCHAR) )))
411 heap_free( path->class );
412 heap_free( path );
413 return E_OUTOFMEMORY;
415 memcpy( path->filter, p, len * sizeof(WCHAR) );
416 path->filter[len] = 0;
417 path->filter_len = len;
419 *ret = path;
420 return S_OK;
423 void free_path( struct path *path )
425 if (!path) return;
426 heap_free( path->class );
427 heap_free( path->filter );
428 heap_free( path );
431 WCHAR *query_from_path( const struct path *path )
433 static const WCHAR selectW[] = L"SELECT * FROM %s WHERE %s";
434 static const WCHAR select_allW[] = L"SELECT * FROM ";
435 WCHAR *query;
436 UINT len;
438 if (path->filter)
440 len = path->class_len + path->filter_len + ARRAY_SIZE(selectW);
441 if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
442 swprintf( query, len, selectW, path->class, path->filter );
444 else
446 len = path->class_len + ARRAY_SIZE(select_allW);
447 if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
448 lstrcpyW( query, select_allW );
449 lstrcatW( query, path->class );
451 return query;
454 static HRESULT create_instance_enum( const struct path *path, IEnumWbemClassObject **iter )
456 WCHAR *query;
457 HRESULT hr;
459 if (!(query = query_from_path( path ))) return E_OUTOFMEMORY;
460 hr = exec_query( query, iter );
461 heap_free( query );
462 return hr;
465 HRESULT get_object( const WCHAR *object_path, IWbemClassObject **obj )
467 IEnumWbemClassObject *iter;
468 struct path *path;
469 ULONG count;
470 HRESULT hr;
472 hr = parse_path( object_path, &path );
473 if (hr != S_OK) return hr;
475 hr = create_instance_enum( path, &iter );
476 if (hr != S_OK)
478 free_path( path );
479 return hr;
481 hr = IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, obj, &count );
482 if (hr == WBEM_S_FALSE)
484 hr = WBEM_E_NOT_FOUND;
485 *obj = NULL;
487 IEnumWbemClassObject_Release( iter );
488 free_path( path );
489 return hr;
492 static HRESULT WINAPI wbem_services_GetObject(
493 IWbemServices *iface,
494 const BSTR strObjectPath,
495 LONG lFlags,
496 IWbemContext *pCtx,
497 IWbemClassObject **ppObject,
498 IWbemCallResult **ppCallResult )
500 TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strObjectPath), lFlags,
501 pCtx, ppObject, ppCallResult);
503 if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
505 if (!strObjectPath || !strObjectPath[0])
506 return create_class_object( NULL, NULL, 0, NULL, ppObject );
508 return get_object( strObjectPath, ppObject );
511 static HRESULT WINAPI wbem_services_GetObjectAsync(
512 IWbemServices *iface,
513 const BSTR strObjectPath,
514 LONG lFlags,
515 IWbemContext *pCtx,
516 IWbemObjectSink *pResponseHandler )
518 FIXME("\n");
519 return WBEM_E_FAILED;
522 static HRESULT WINAPI wbem_services_PutClass(
523 IWbemServices *iface,
524 IWbemClassObject *pObject,
525 LONG lFlags,
526 IWbemContext *pCtx,
527 IWbemCallResult **ppCallResult )
529 FIXME("\n");
530 return WBEM_E_FAILED;
533 static HRESULT WINAPI wbem_services_PutClassAsync(
534 IWbemServices *iface,
535 IWbemClassObject *pObject,
536 LONG lFlags,
537 IWbemContext *pCtx,
538 IWbemObjectSink *pResponseHandler )
540 FIXME("\n");
541 return WBEM_E_FAILED;
544 static HRESULT WINAPI wbem_services_DeleteClass(
545 IWbemServices *iface,
546 const BSTR strClass,
547 LONG lFlags,
548 IWbemContext *pCtx,
549 IWbemCallResult **ppCallResult )
551 FIXME("\n");
552 return WBEM_E_FAILED;
555 static HRESULT WINAPI wbem_services_DeleteClassAsync(
556 IWbemServices *iface,
557 const BSTR strClass,
558 LONG lFlags,
559 IWbemContext *pCtx,
560 IWbemObjectSink *pResponseHandler )
562 FIXME("\n");
563 return WBEM_E_FAILED;
566 static HRESULT WINAPI wbem_services_CreateClassEnum(
567 IWbemServices *iface,
568 const BSTR strSuperclass,
569 LONG lFlags,
570 IWbemContext *pCtx,
571 IEnumWbemClassObject **ppEnum )
573 FIXME("\n");
574 return WBEM_E_FAILED;
577 static HRESULT WINAPI wbem_services_CreateClassEnumAsync(
578 IWbemServices *iface,
579 const BSTR strSuperclass,
580 LONG lFlags,
581 IWbemContext *pCtx,
582 IWbemObjectSink *pResponseHandler )
584 FIXME("\n");
585 return WBEM_E_FAILED;
588 static HRESULT WINAPI wbem_services_PutInstance(
589 IWbemServices *iface,
590 IWbemClassObject *pInst,
591 LONG lFlags,
592 IWbemContext *pCtx,
593 IWbemCallResult **ppCallResult )
595 FIXME("\n");
596 return WBEM_E_FAILED;
599 static HRESULT WINAPI wbem_services_PutInstanceAsync(
600 IWbemServices *iface,
601 IWbemClassObject *pInst,
602 LONG lFlags,
603 IWbemContext *pCtx,
604 IWbemObjectSink *pResponseHandler )
606 FIXME("\n");
607 return WBEM_E_FAILED;
610 static HRESULT WINAPI wbem_services_DeleteInstance(
611 IWbemServices *iface,
612 const BSTR strObjectPath,
613 LONG lFlags,
614 IWbemContext *pCtx,
615 IWbemCallResult **ppCallResult )
617 FIXME("\n");
618 return WBEM_E_FAILED;
621 static HRESULT WINAPI wbem_services_DeleteInstanceAsync(
622 IWbemServices *iface,
623 const BSTR strObjectPath,
624 LONG lFlags,
625 IWbemContext *pCtx,
626 IWbemObjectSink *pResponseHandler )
628 FIXME("\n");
629 return WBEM_E_FAILED;
632 static HRESULT WINAPI wbem_services_CreateInstanceEnum(
633 IWbemServices *iface,
634 const BSTR strClass,
635 LONG lFlags,
636 IWbemContext *pCtx,
637 IEnumWbemClassObject **ppEnum )
639 struct path *path;
640 HRESULT hr;
642 TRACE("%p, %s, 0%08x, %p, %p\n", iface, debugstr_w(strClass), lFlags, pCtx, ppEnum);
644 if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
646 hr = parse_path( strClass, &path );
647 if (hr != S_OK) return hr;
649 hr = create_instance_enum( path, ppEnum );
650 free_path( path );
651 return hr;
654 static HRESULT WINAPI wbem_services_CreateInstanceEnumAsync(
655 IWbemServices *iface,
656 const BSTR strFilter,
657 LONG lFlags,
658 IWbemContext *pCtx,
659 IWbemObjectSink *pResponseHandler )
661 FIXME("\n");
662 return WBEM_E_FAILED;
665 static HRESULT WINAPI wbem_services_ExecQuery(
666 IWbemServices *iface,
667 const BSTR strQueryLanguage,
668 const BSTR strQuery,
669 LONG lFlags,
670 IWbemContext *pCtx,
671 IEnumWbemClassObject **ppEnum )
673 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage),
674 debugstr_w(strQuery), lFlags, pCtx, ppEnum);
676 if (!strQueryLanguage || !strQuery || !strQuery[0]) return WBEM_E_INVALID_PARAMETER;
677 if (wcsicmp( strQueryLanguage, L"WQL" )) return WBEM_E_INVALID_QUERY_TYPE;
678 return exec_query( strQuery, ppEnum );
681 static void async_exec_query( struct async_header *hdr )
683 struct async_query *query = (struct async_query *)hdr;
684 IEnumWbemClassObject *result;
685 IWbemClassObject *obj;
686 ULONG count;
687 HRESULT hr;
689 hr = exec_query( query->str, &result );
690 if (hr == S_OK)
692 for (;;)
694 IEnumWbemClassObject_Next( result, WBEM_INFINITE, 1, &obj, &count );
695 if (!count) break;
696 IWbemObjectSink_Indicate( query->hdr.sink, 1, &obj );
697 IWbemClassObject_Release( obj );
699 IEnumWbemClassObject_Release( result );
701 IWbemObjectSink_SetStatus( query->hdr.sink, WBEM_STATUS_COMPLETE, hr, NULL, NULL );
702 heap_free( query->str );
705 static HRESULT WINAPI wbem_services_ExecQueryAsync(
706 IWbemServices *iface,
707 const BSTR strQueryLanguage,
708 const BSTR strQuery,
709 LONG lFlags,
710 IWbemContext *pCtx,
711 IWbemObjectSink *pResponseHandler )
713 struct wbem_services *services = impl_from_IWbemServices( iface );
714 IWbemObjectSink *sink;
715 HRESULT hr = E_OUTOFMEMORY;
716 struct async_header *async;
717 struct async_query *query;
719 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage), debugstr_w(strQuery),
720 lFlags, pCtx, pResponseHandler);
722 if (!pResponseHandler) return WBEM_E_INVALID_PARAMETER;
724 hr = IWbemObjectSink_QueryInterface( pResponseHandler, &IID_IWbemObjectSink, (void **)&sink );
725 if (FAILED(hr)) return hr;
727 EnterCriticalSection( &services->cs );
729 if (services->async)
731 FIXME("handle more than one pending async\n");
732 hr = WBEM_E_FAILED;
733 goto done;
735 if (!(query = heap_alloc_zero( sizeof(*query) ))) goto done;
736 async = (struct async_header *)query;
738 if (!(init_async( async, sink, async_exec_query )))
740 free_async( async );
741 goto done;
743 if (!(query->str = heap_strdupW( strQuery )))
745 free_async( async );
746 goto done;
748 hr = queue_async( async );
749 if (hr == S_OK) services->async = async;
750 else
752 heap_free( query->str );
753 free_async( async );
756 done:
757 LeaveCriticalSection( &services->cs );
758 IWbemObjectSink_Release( sink );
759 return hr;
762 static HRESULT WINAPI wbem_services_ExecNotificationQuery(
763 IWbemServices *iface,
764 const BSTR strQueryLanguage,
765 const BSTR strQuery,
766 LONG lFlags,
767 IWbemContext *pCtx,
768 IEnumWbemClassObject **ppEnum )
770 FIXME("\n");
771 return WBEM_E_FAILED;
774 static HRESULT WINAPI wbem_services_ExecNotificationQueryAsync(
775 IWbemServices *iface,
776 const BSTR strQueryLanguage,
777 const BSTR strQuery,
778 LONG lFlags,
779 IWbemContext *pCtx,
780 IWbemObjectSink *pResponseHandler )
782 struct wbem_services *services = impl_from_IWbemServices( iface );
783 IWbemObjectSink *sink;
784 HRESULT hr = E_OUTOFMEMORY;
785 struct async_header *async;
786 struct async_query *query;
788 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage), debugstr_w(strQuery),
789 lFlags, pCtx, pResponseHandler);
791 if (!pResponseHandler) return WBEM_E_INVALID_PARAMETER;
793 hr = IWbemObjectSink_QueryInterface( pResponseHandler, &IID_IWbemObjectSink, (void **)&sink );
794 if (FAILED(hr)) return hr;
796 EnterCriticalSection( &services->cs );
798 if (services->async)
800 FIXME("handle more than one pending async\n");
801 hr = WBEM_E_FAILED;
802 goto done;
804 if (!(query = heap_alloc_zero( sizeof(*query) ))) goto done;
805 async = (struct async_header *)query;
807 if (!(init_async( async, sink, async_exec_query )))
809 free_async( async );
810 goto done;
812 if (!(query->str = heap_strdupW( strQuery )))
814 free_async( async );
815 goto done;
817 hr = queue_async( async );
818 if (hr == S_OK) services->async = async;
819 else
821 heap_free( query->str );
822 free_async( async );
825 done:
826 LeaveCriticalSection( &services->cs );
827 IWbemObjectSink_Release( sink );
828 return hr;
831 static HRESULT WINAPI wbem_services_ExecMethod(
832 IWbemServices *iface,
833 const BSTR strObjectPath,
834 const BSTR strMethodName,
835 LONG lFlags,
836 IWbemContext *pCtx,
837 IWbemClassObject *pInParams,
838 IWbemClassObject **ppOutParams,
839 IWbemCallResult **ppCallResult )
841 IEnumWbemClassObject *result = NULL;
842 IWbemClassObject *obj = NULL;
843 struct query *query = NULL;
844 struct path *path;
845 WCHAR *str;
846 class_method *func;
847 struct table *table;
848 HRESULT hr;
850 TRACE("%p, %s, %s, %08x, %p, %p, %p, %p\n", iface, debugstr_w(strObjectPath),
851 debugstr_w(strMethodName), lFlags, pCtx, pInParams, ppOutParams, ppCallResult);
853 if (lFlags) FIXME("flags %08x not supported\n", lFlags);
855 if ((hr = parse_path( strObjectPath, &path )) != S_OK) return hr;
856 if (!(str = query_from_path( path )))
858 hr = E_OUTOFMEMORY;
859 goto done;
861 if (!(query = create_query()))
863 hr = E_OUTOFMEMORY;
864 goto done;
866 hr = parse_query( str, &query->view, &query->mem );
867 if (hr != S_OK) goto done;
869 hr = execute_view( query->view );
870 if (hr != S_OK) goto done;
872 hr = EnumWbemClassObject_create( query, (void **)&result );
873 if (hr != S_OK) goto done;
875 table = get_view_table( query->view, 0 );
876 hr = create_class_object( table->name, result, 0, NULL, &obj );
877 if (hr != S_OK) goto done;
879 hr = get_method( table, strMethodName, &func );
880 if (hr != S_OK) goto done;
882 hr = func( obj, pInParams, ppOutParams );
884 done:
885 if (result) IEnumWbemClassObject_Release( result );
886 if (obj) IWbemClassObject_Release( obj );
887 free_query( query );
888 free_path( path );
889 heap_free( str );
890 return hr;
893 static HRESULT WINAPI wbem_services_ExecMethodAsync(
894 IWbemServices *iface,
895 const BSTR strObjectPath,
896 const BSTR strMethodName,
897 LONG lFlags,
898 IWbemContext *pCtx,
899 IWbemClassObject *pInParams,
900 IWbemObjectSink *pResponseHandler )
902 FIXME("\n");
903 return WBEM_E_FAILED;
906 static const IWbemServicesVtbl wbem_services_vtbl =
908 wbem_services_QueryInterface,
909 wbem_services_AddRef,
910 wbem_services_Release,
911 wbem_services_OpenNamespace,
912 wbem_services_CancelAsyncCall,
913 wbem_services_QueryObjectSink,
914 wbem_services_GetObject,
915 wbem_services_GetObjectAsync,
916 wbem_services_PutClass,
917 wbem_services_PutClassAsync,
918 wbem_services_DeleteClass,
919 wbem_services_DeleteClassAsync,
920 wbem_services_CreateClassEnum,
921 wbem_services_CreateClassEnumAsync,
922 wbem_services_PutInstance,
923 wbem_services_PutInstanceAsync,
924 wbem_services_DeleteInstance,
925 wbem_services_DeleteInstanceAsync,
926 wbem_services_CreateInstanceEnum,
927 wbem_services_CreateInstanceEnumAsync,
928 wbem_services_ExecQuery,
929 wbem_services_ExecQueryAsync,
930 wbem_services_ExecNotificationQuery,
931 wbem_services_ExecNotificationQueryAsync,
932 wbem_services_ExecMethod,
933 wbem_services_ExecMethodAsync
936 HRESULT WbemServices_create( const WCHAR *namespace, LPVOID *ppObj )
938 struct wbem_services *ws;
940 TRACE("(%p)\n", ppObj);
942 ws = heap_alloc( sizeof(*ws) );
943 if (!ws) return E_OUTOFMEMORY;
945 ws->IWbemServices_iface.lpVtbl = &wbem_services_vtbl;
946 ws->refs = 1;
947 ws->namespace = heap_strdupW( namespace );
948 ws->async = NULL;
949 InitializeCriticalSection( &ws->cs );
950 ws->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wbemprox_services.cs");
952 *ppObj = &ws->IWbemServices_iface;
954 TRACE("returning iface %p\n", *ppObj);
955 return S_OK;