ntdll: Stop resolving imports for the Unix library.
[wine.git] / dlls / wbemprox / services.c
blob3a0963e1f6c5d69077806a6e22d86ed1036e67b6
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("\n");
92 return WBEM_E_FAILED;
95 static HRESULT WINAPI client_security_SetBlanket(
96 IClientSecurity *iface,
97 IUnknown *pProxy,
98 DWORD AuthnSvc,
99 DWORD AuthzSvc,
100 OLECHAR *pServerPrincName,
101 DWORD AuthnLevel,
102 DWORD ImpLevel,
103 void *pAuthInfo,
104 DWORD Capabilities )
106 const OLECHAR *princname = (pServerPrincName == COLE_DEFAULT_PRINCIPAL) ?
107 L"<COLE_DEFAULT_PRINCIPAL>" : pServerPrincName;
109 FIXME("%p, %p, %u, %u, %s, %u, %u, %p, 0x%08x\n", iface, pProxy, AuthnSvc, AuthzSvc,
110 debugstr_w(princname), AuthnLevel, ImpLevel, pAuthInfo, Capabilities);
111 return WBEM_NO_ERROR;
114 static HRESULT WINAPI client_security_CopyProxy(
115 IClientSecurity *iface,
116 IUnknown *pProxy,
117 IUnknown **ppCopy )
119 FIXME("\n");
120 return WBEM_E_FAILED;
123 static const IClientSecurityVtbl client_security_vtbl =
125 client_security_QueryInterface,
126 client_security_AddRef,
127 client_security_Release,
128 client_security_QueryBlanket,
129 client_security_SetBlanket,
130 client_security_CopyProxy
133 IClientSecurity client_security = { &client_security_vtbl };
135 struct async_header
137 IWbemObjectSink *sink;
138 void (*proc)( struct async_header * );
139 HANDLE cancel;
140 HANDLE wait;
143 struct async_query
145 struct async_header hdr;
146 WCHAR *str;
149 static void free_async( struct async_header *async )
151 if (async->sink) IWbemObjectSink_Release( async->sink );
152 CloseHandle( async->cancel );
153 CloseHandle( async->wait );
154 heap_free( async );
157 static BOOL init_async( struct async_header *async, IWbemObjectSink *sink,
158 void (*proc)(struct async_header *) )
160 if (!(async->wait = CreateEventW( NULL, FALSE, FALSE, NULL ))) return FALSE;
161 if (!(async->cancel = CreateEventW( NULL, FALSE, FALSE, NULL )))
163 CloseHandle( async->wait );
164 return FALSE;
166 async->proc = proc;
167 async->sink = sink;
168 IWbemObjectSink_AddRef( sink );
169 return TRUE;
172 static DWORD CALLBACK async_proc( LPVOID param )
174 struct async_header *async = param;
175 HANDLE wait = async->wait;
177 async->proc( async );
179 WaitForSingleObject( async->cancel, INFINITE );
180 SetEvent( wait );
181 return ERROR_SUCCESS;
184 static HRESULT queue_async( struct async_header *async )
186 if (QueueUserWorkItem( async_proc, async, WT_EXECUTELONGFUNCTION )) return S_OK;
187 return HRESULT_FROM_WIN32( GetLastError() );
190 struct wbem_services
192 IWbemServices IWbemServices_iface;
193 LONG refs;
194 CRITICAL_SECTION cs;
195 WCHAR *namespace;
196 struct async_header *async;
199 static inline struct wbem_services *impl_from_IWbemServices( IWbemServices *iface )
201 return CONTAINING_RECORD( iface, struct wbem_services, IWbemServices_iface );
204 static ULONG WINAPI wbem_services_AddRef(
205 IWbemServices *iface )
207 struct wbem_services *ws = impl_from_IWbemServices( iface );
208 return InterlockedIncrement( &ws->refs );
211 static ULONG WINAPI wbem_services_Release(
212 IWbemServices *iface )
214 struct wbem_services *ws = impl_from_IWbemServices( iface );
215 LONG refs = InterlockedDecrement( &ws->refs );
216 if (!refs)
218 TRACE("destroying %p\n", ws);
220 EnterCriticalSection( &ws->cs );
221 if (ws->async) SetEvent( ws->async->cancel );
222 LeaveCriticalSection( &ws->cs );
223 if (ws->async)
225 WaitForSingleObject( ws->async->wait, INFINITE );
226 free_async( ws->async );
228 ws->cs.DebugInfo->Spare[0] = 0;
229 DeleteCriticalSection( &ws->cs );
230 heap_free( ws->namespace );
231 heap_free( ws );
233 return refs;
236 static HRESULT WINAPI wbem_services_QueryInterface(
237 IWbemServices *iface,
238 REFIID riid,
239 void **ppvObject )
241 struct wbem_services *ws = impl_from_IWbemServices( iface );
243 TRACE("%p %s %p\n", ws, debugstr_guid( riid ), ppvObject );
245 if ( IsEqualGUID( riid, &IID_IWbemServices ) ||
246 IsEqualGUID( riid, &IID_IUnknown ) )
248 *ppvObject = ws;
250 else if ( IsEqualGUID( riid, &IID_IClientSecurity ) )
252 *ppvObject = &client_security;
253 return S_OK;
255 else
257 FIXME("interface %s not implemented\n", debugstr_guid(riid));
258 return E_NOINTERFACE;
260 IWbemServices_AddRef( iface );
261 return S_OK;
264 static HRESULT WINAPI wbem_services_OpenNamespace(
265 IWbemServices *iface,
266 const BSTR strNamespace,
267 LONG lFlags,
268 IWbemContext *pCtx,
269 IWbemServices **ppWorkingNamespace,
270 IWbemCallResult **ppResult )
272 struct wbem_services *ws = impl_from_IWbemServices( iface );
274 TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strNamespace), lFlags,
275 pCtx, ppWorkingNamespace, ppResult);
277 if ((wcsicmp( strNamespace, L"cimv2" ) && wcsicmp( strNamespace, L"default" )) || ws->namespace)
278 return WBEM_E_INVALID_NAMESPACE;
280 return WbemServices_create( L"cimv2", (void **)ppWorkingNamespace );
283 static HRESULT WINAPI wbem_services_CancelAsyncCall(
284 IWbemServices *iface,
285 IWbemObjectSink *pSink )
287 struct wbem_services *services = impl_from_IWbemServices( iface );
288 struct async_header *async;
290 TRACE("%p, %p\n", iface, pSink);
292 if (!pSink) return WBEM_E_INVALID_PARAMETER;
294 EnterCriticalSection( &services->cs );
296 if (!(async = services->async))
298 LeaveCriticalSection( &services->cs );
299 return WBEM_E_INVALID_PARAMETER;
301 services->async = NULL;
302 SetEvent( async->cancel );
304 LeaveCriticalSection( &services->cs );
306 WaitForSingleObject( async->wait, INFINITE );
307 free_async( async );
308 return S_OK;
311 static HRESULT WINAPI wbem_services_QueryObjectSink(
312 IWbemServices *iface,
313 LONG lFlags,
314 IWbemObjectSink **ppResponseHandler )
316 FIXME("\n");
317 return WBEM_E_FAILED;
320 HRESULT parse_path( const WCHAR *str, struct path **ret )
322 struct path *path;
323 const WCHAR *p = str, *q;
324 UINT len;
326 if (!(path = heap_alloc_zero( sizeof(*path) ))) return E_OUTOFMEMORY;
328 if (*p == '\\')
330 static const WCHAR cimv2W[] = L"ROOT\\CIMV2";
331 WCHAR server[MAX_COMPUTERNAME_LENGTH+1];
332 DWORD server_len = ARRAY_SIZE(server);
334 p++;
335 if (*p != '\\')
337 heap_free( path );
338 return WBEM_E_INVALID_OBJECT_PATH;
340 p++;
342 q = p;
343 while (*p && *p != '\\') p++;
344 if (!*p)
346 heap_free( path );
347 return WBEM_E_INVALID_OBJECT_PATH;
350 len = p - q;
351 if (!GetComputerNameW( server, &server_len ) || server_len != len || wcsnicmp( q, server, server_len ))
353 heap_free( path );
354 return WBEM_E_NOT_SUPPORTED;
357 q = ++p;
358 while (*p && *p != ':') p++;
359 if (!*p)
361 heap_free( path );
362 return WBEM_E_INVALID_OBJECT_PATH;
365 len = p - q;
366 if (len != ARRAY_SIZE(cimv2W) - 1 || wcsnicmp( q, cimv2W, ARRAY_SIZE(cimv2W) - 1 ))
368 heap_free( path );
369 return WBEM_E_INVALID_NAMESPACE;
371 p++;
374 q = p;
375 while (*p && *p != '.') p++;
377 len = p - q;
378 if (!(path->class = heap_alloc( (len + 1) * sizeof(WCHAR) )))
380 heap_free( path );
381 return E_OUTOFMEMORY;
383 memcpy( path->class, q, len * sizeof(WCHAR) );
384 path->class[len] = 0;
385 path->class_len = len;
387 if (p[0] == '.' && p[1])
389 q = ++p;
390 while (*q) q++;
392 len = q - p;
393 if (!(path->filter = heap_alloc( (len + 1) * sizeof(WCHAR) )))
395 heap_free( path->class );
396 heap_free( path );
397 return E_OUTOFMEMORY;
399 memcpy( path->filter, p, len * sizeof(WCHAR) );
400 path->filter[len] = 0;
401 path->filter_len = len;
403 *ret = path;
404 return S_OK;
407 void free_path( struct path *path )
409 if (!path) return;
410 heap_free( path->class );
411 heap_free( path->filter );
412 heap_free( path );
415 WCHAR *query_from_path( const struct path *path )
417 static const WCHAR selectW[] = L"SELECT * FROM %s WHERE %s";
418 static const WCHAR select_allW[] = L"SELECT * FROM ";
419 WCHAR *query;
420 UINT len;
422 if (path->filter)
424 len = path->class_len + path->filter_len + ARRAY_SIZE(selectW);
425 if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
426 swprintf( query, len, selectW, path->class, path->filter );
428 else
430 len = path->class_len + ARRAY_SIZE(select_allW);
431 if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
432 lstrcpyW( query, select_allW );
433 lstrcatW( query, path->class );
435 return query;
438 static HRESULT create_instance_enum( const struct path *path, IEnumWbemClassObject **iter )
440 WCHAR *query;
441 HRESULT hr;
443 if (!(query = query_from_path( path ))) return E_OUTOFMEMORY;
444 hr = exec_query( query, iter );
445 heap_free( query );
446 return hr;
449 HRESULT get_object( const WCHAR *object_path, IWbemClassObject **obj )
451 IEnumWbemClassObject *iter;
452 struct path *path;
453 ULONG count;
454 HRESULT hr;
456 hr = parse_path( object_path, &path );
457 if (hr != S_OK) return hr;
459 hr = create_instance_enum( path, &iter );
460 if (hr != S_OK)
462 free_path( path );
463 return hr;
465 hr = IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, obj, &count );
466 if (hr == WBEM_S_FALSE)
468 hr = WBEM_E_NOT_FOUND;
469 *obj = NULL;
471 IEnumWbemClassObject_Release( iter );
472 free_path( path );
473 return hr;
476 static HRESULT WINAPI wbem_services_GetObject(
477 IWbemServices *iface,
478 const BSTR strObjectPath,
479 LONG lFlags,
480 IWbemContext *pCtx,
481 IWbemClassObject **ppObject,
482 IWbemCallResult **ppCallResult )
484 TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strObjectPath), lFlags,
485 pCtx, ppObject, ppCallResult);
487 if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
489 if (!strObjectPath || !strObjectPath[0])
490 return create_class_object( NULL, NULL, 0, NULL, ppObject );
492 return get_object( strObjectPath, ppObject );
495 static HRESULT WINAPI wbem_services_GetObjectAsync(
496 IWbemServices *iface,
497 const BSTR strObjectPath,
498 LONG lFlags,
499 IWbemContext *pCtx,
500 IWbemObjectSink *pResponseHandler )
502 FIXME("\n");
503 return WBEM_E_FAILED;
506 static HRESULT WINAPI wbem_services_PutClass(
507 IWbemServices *iface,
508 IWbemClassObject *pObject,
509 LONG lFlags,
510 IWbemContext *pCtx,
511 IWbemCallResult **ppCallResult )
513 FIXME("\n");
514 return WBEM_E_FAILED;
517 static HRESULT WINAPI wbem_services_PutClassAsync(
518 IWbemServices *iface,
519 IWbemClassObject *pObject,
520 LONG lFlags,
521 IWbemContext *pCtx,
522 IWbemObjectSink *pResponseHandler )
524 FIXME("\n");
525 return WBEM_E_FAILED;
528 static HRESULT WINAPI wbem_services_DeleteClass(
529 IWbemServices *iface,
530 const BSTR strClass,
531 LONG lFlags,
532 IWbemContext *pCtx,
533 IWbemCallResult **ppCallResult )
535 FIXME("\n");
536 return WBEM_E_FAILED;
539 static HRESULT WINAPI wbem_services_DeleteClassAsync(
540 IWbemServices *iface,
541 const BSTR strClass,
542 LONG lFlags,
543 IWbemContext *pCtx,
544 IWbemObjectSink *pResponseHandler )
546 FIXME("\n");
547 return WBEM_E_FAILED;
550 static HRESULT WINAPI wbem_services_CreateClassEnum(
551 IWbemServices *iface,
552 const BSTR strSuperclass,
553 LONG lFlags,
554 IWbemContext *pCtx,
555 IEnumWbemClassObject **ppEnum )
557 FIXME("\n");
558 return WBEM_E_FAILED;
561 static HRESULT WINAPI wbem_services_CreateClassEnumAsync(
562 IWbemServices *iface,
563 const BSTR strSuperclass,
564 LONG lFlags,
565 IWbemContext *pCtx,
566 IWbemObjectSink *pResponseHandler )
568 FIXME("\n");
569 return WBEM_E_FAILED;
572 static HRESULT WINAPI wbem_services_PutInstance(
573 IWbemServices *iface,
574 IWbemClassObject *pInst,
575 LONG lFlags,
576 IWbemContext *pCtx,
577 IWbemCallResult **ppCallResult )
579 FIXME("\n");
580 return WBEM_E_FAILED;
583 static HRESULT WINAPI wbem_services_PutInstanceAsync(
584 IWbemServices *iface,
585 IWbemClassObject *pInst,
586 LONG lFlags,
587 IWbemContext *pCtx,
588 IWbemObjectSink *pResponseHandler )
590 FIXME("\n");
591 return WBEM_E_FAILED;
594 static HRESULT WINAPI wbem_services_DeleteInstance(
595 IWbemServices *iface,
596 const BSTR strObjectPath,
597 LONG lFlags,
598 IWbemContext *pCtx,
599 IWbemCallResult **ppCallResult )
601 FIXME("\n");
602 return WBEM_E_FAILED;
605 static HRESULT WINAPI wbem_services_DeleteInstanceAsync(
606 IWbemServices *iface,
607 const BSTR strObjectPath,
608 LONG lFlags,
609 IWbemContext *pCtx,
610 IWbemObjectSink *pResponseHandler )
612 FIXME("\n");
613 return WBEM_E_FAILED;
616 static HRESULT WINAPI wbem_services_CreateInstanceEnum(
617 IWbemServices *iface,
618 const BSTR strClass,
619 LONG lFlags,
620 IWbemContext *pCtx,
621 IEnumWbemClassObject **ppEnum )
623 struct path *path;
624 HRESULT hr;
626 TRACE("%p, %s, 0%08x, %p, %p\n", iface, debugstr_w(strClass), lFlags, pCtx, ppEnum);
628 if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
630 hr = parse_path( strClass, &path );
631 if (hr != S_OK) return hr;
633 hr = create_instance_enum( path, ppEnum );
634 free_path( path );
635 return hr;
638 static HRESULT WINAPI wbem_services_CreateInstanceEnumAsync(
639 IWbemServices *iface,
640 const BSTR strFilter,
641 LONG lFlags,
642 IWbemContext *pCtx,
643 IWbemObjectSink *pResponseHandler )
645 FIXME("\n");
646 return WBEM_E_FAILED;
649 static HRESULT WINAPI wbem_services_ExecQuery(
650 IWbemServices *iface,
651 const BSTR strQueryLanguage,
652 const BSTR strQuery,
653 LONG lFlags,
654 IWbemContext *pCtx,
655 IEnumWbemClassObject **ppEnum )
657 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage),
658 debugstr_w(strQuery), lFlags, pCtx, ppEnum);
660 if (!strQueryLanguage || !strQuery || !strQuery[0]) return WBEM_E_INVALID_PARAMETER;
661 if (wcsicmp( strQueryLanguage, L"WQL" )) return WBEM_E_INVALID_QUERY_TYPE;
662 return exec_query( strQuery, ppEnum );
665 static void async_exec_query( struct async_header *hdr )
667 struct async_query *query = (struct async_query *)hdr;
668 IEnumWbemClassObject *result;
669 IWbemClassObject *obj;
670 ULONG count;
671 HRESULT hr;
673 hr = exec_query( query->str, &result );
674 if (hr == S_OK)
676 for (;;)
678 IEnumWbemClassObject_Next( result, WBEM_INFINITE, 1, &obj, &count );
679 if (!count) break;
680 IWbemObjectSink_Indicate( query->hdr.sink, 1, &obj );
681 IWbemClassObject_Release( obj );
683 IEnumWbemClassObject_Release( result );
685 IWbemObjectSink_SetStatus( query->hdr.sink, WBEM_STATUS_COMPLETE, hr, NULL, NULL );
686 heap_free( query->str );
689 static HRESULT WINAPI wbem_services_ExecQueryAsync(
690 IWbemServices *iface,
691 const BSTR strQueryLanguage,
692 const BSTR strQuery,
693 LONG lFlags,
694 IWbemContext *pCtx,
695 IWbemObjectSink *pResponseHandler )
697 struct wbem_services *services = impl_from_IWbemServices( iface );
698 IWbemObjectSink *sink;
699 HRESULT hr = E_OUTOFMEMORY;
700 struct async_header *async;
701 struct async_query *query;
703 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage), debugstr_w(strQuery),
704 lFlags, pCtx, pResponseHandler);
706 if (!pResponseHandler) return WBEM_E_INVALID_PARAMETER;
708 hr = IWbemObjectSink_QueryInterface( pResponseHandler, &IID_IWbemObjectSink, (void **)&sink );
709 if (FAILED(hr)) return hr;
711 EnterCriticalSection( &services->cs );
713 if (services->async)
715 FIXME("handle more than one pending async\n");
716 hr = WBEM_E_FAILED;
717 goto done;
719 if (!(query = heap_alloc_zero( sizeof(*query) ))) goto done;
720 async = (struct async_header *)query;
722 if (!(init_async( async, sink, async_exec_query )))
724 free_async( async );
725 goto done;
727 if (!(query->str = heap_strdupW( strQuery )))
729 free_async( async );
730 goto done;
732 hr = queue_async( async );
733 if (hr == S_OK) services->async = async;
734 else
736 heap_free( query->str );
737 free_async( async );
740 done:
741 LeaveCriticalSection( &services->cs );
742 IWbemObjectSink_Release( sink );
743 return hr;
746 static HRESULT WINAPI wbem_services_ExecNotificationQuery(
747 IWbemServices *iface,
748 const BSTR strQueryLanguage,
749 const BSTR strQuery,
750 LONG lFlags,
751 IWbemContext *pCtx,
752 IEnumWbemClassObject **ppEnum )
754 FIXME("\n");
755 return WBEM_E_FAILED;
758 static HRESULT WINAPI wbem_services_ExecNotificationQueryAsync(
759 IWbemServices *iface,
760 const BSTR strQueryLanguage,
761 const BSTR strQuery,
762 LONG lFlags,
763 IWbemContext *pCtx,
764 IWbemObjectSink *pResponseHandler )
766 struct wbem_services *services = impl_from_IWbemServices( iface );
767 IWbemObjectSink *sink;
768 HRESULT hr = E_OUTOFMEMORY;
769 struct async_header *async;
770 struct async_query *query;
772 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage), debugstr_w(strQuery),
773 lFlags, pCtx, pResponseHandler);
775 if (!pResponseHandler) return WBEM_E_INVALID_PARAMETER;
777 hr = IWbemObjectSink_QueryInterface( pResponseHandler, &IID_IWbemObjectSink, (void **)&sink );
778 if (FAILED(hr)) return hr;
780 EnterCriticalSection( &services->cs );
782 if (services->async)
784 FIXME("handle more than one pending async\n");
785 hr = WBEM_E_FAILED;
786 goto done;
788 if (!(query = heap_alloc_zero( sizeof(*query) ))) goto done;
789 async = (struct async_header *)query;
791 if (!(init_async( async, sink, async_exec_query )))
793 free_async( async );
794 goto done;
796 if (!(query->str = heap_strdupW( strQuery )))
798 free_async( async );
799 goto done;
801 hr = queue_async( async );
802 if (hr == S_OK) services->async = async;
803 else
805 heap_free( query->str );
806 free_async( async );
809 done:
810 LeaveCriticalSection( &services->cs );
811 IWbemObjectSink_Release( sink );
812 return hr;
815 static HRESULT WINAPI wbem_services_ExecMethod(
816 IWbemServices *iface,
817 const BSTR strObjectPath,
818 const BSTR strMethodName,
819 LONG lFlags,
820 IWbemContext *pCtx,
821 IWbemClassObject *pInParams,
822 IWbemClassObject **ppOutParams,
823 IWbemCallResult **ppCallResult )
825 IEnumWbemClassObject *result = NULL;
826 IWbemClassObject *obj = NULL;
827 struct query *query = NULL;
828 struct path *path;
829 WCHAR *str;
830 class_method *func;
831 struct table *table;
832 HRESULT hr;
834 TRACE("%p, %s, %s, %08x, %p, %p, %p, %p\n", iface, debugstr_w(strObjectPath),
835 debugstr_w(strMethodName), lFlags, pCtx, pInParams, ppOutParams, ppCallResult);
837 if (lFlags) FIXME("flags %08x not supported\n", lFlags);
839 if ((hr = parse_path( strObjectPath, &path )) != S_OK) return hr;
840 if (!(str = query_from_path( path )))
842 hr = E_OUTOFMEMORY;
843 goto done;
845 if (!(query = create_query()))
847 hr = E_OUTOFMEMORY;
848 goto done;
850 hr = parse_query( str, &query->view, &query->mem );
851 if (hr != S_OK) goto done;
853 hr = execute_view( query->view );
854 if (hr != S_OK) goto done;
856 hr = EnumWbemClassObject_create( query, (void **)&result );
857 if (hr != S_OK) goto done;
859 table = get_view_table( query->view, 0 );
860 hr = create_class_object( table->name, result, 0, NULL, &obj );
861 if (hr != S_OK) goto done;
863 hr = get_method( table, strMethodName, &func );
864 if (hr != S_OK) goto done;
866 hr = func( obj, pInParams, ppOutParams );
868 done:
869 if (result) IEnumWbemClassObject_Release( result );
870 if (obj) IWbemClassObject_Release( obj );
871 free_query( query );
872 free_path( path );
873 heap_free( str );
874 return hr;
877 static HRESULT WINAPI wbem_services_ExecMethodAsync(
878 IWbemServices *iface,
879 const BSTR strObjectPath,
880 const BSTR strMethodName,
881 LONG lFlags,
882 IWbemContext *pCtx,
883 IWbemClassObject *pInParams,
884 IWbemObjectSink *pResponseHandler )
886 FIXME("\n");
887 return WBEM_E_FAILED;
890 static const IWbemServicesVtbl wbem_services_vtbl =
892 wbem_services_QueryInterface,
893 wbem_services_AddRef,
894 wbem_services_Release,
895 wbem_services_OpenNamespace,
896 wbem_services_CancelAsyncCall,
897 wbem_services_QueryObjectSink,
898 wbem_services_GetObject,
899 wbem_services_GetObjectAsync,
900 wbem_services_PutClass,
901 wbem_services_PutClassAsync,
902 wbem_services_DeleteClass,
903 wbem_services_DeleteClassAsync,
904 wbem_services_CreateClassEnum,
905 wbem_services_CreateClassEnumAsync,
906 wbem_services_PutInstance,
907 wbem_services_PutInstanceAsync,
908 wbem_services_DeleteInstance,
909 wbem_services_DeleteInstanceAsync,
910 wbem_services_CreateInstanceEnum,
911 wbem_services_CreateInstanceEnumAsync,
912 wbem_services_ExecQuery,
913 wbem_services_ExecQueryAsync,
914 wbem_services_ExecNotificationQuery,
915 wbem_services_ExecNotificationQueryAsync,
916 wbem_services_ExecMethod,
917 wbem_services_ExecMethodAsync
920 HRESULT WbemServices_create( const WCHAR *namespace, LPVOID *ppObj )
922 struct wbem_services *ws;
924 TRACE("(%p)\n", ppObj);
926 ws = heap_alloc( sizeof(*ws) );
927 if (!ws) return E_OUTOFMEMORY;
929 ws->IWbemServices_iface.lpVtbl = &wbem_services_vtbl;
930 ws->refs = 1;
931 ws->namespace = heap_strdupW( namespace );
932 ws->async = NULL;
933 InitializeCriticalSection( &ws->cs );
934 ws->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wbemprox_services.cs");
936 *ppObj = &ws->IWbemServices_iface;
938 TRACE("returning iface %p\n", *ppObj);
939 return S_OK;