xref: /reactos/dll/win32/wbemprox/services.c (revision 628f4c99)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Copyright 2012 Hans Leidekker for CodeWeavers
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck  * License as published by the Free Software Foundation; either
7c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck  *
9c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12c2c66affSColin Finck  * Lesser General Public License for more details.
13c2c66affSColin Finck  *
14c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17c2c66affSColin Finck  */
18c2c66affSColin Finck 
19edccad14SAmine Khaldi #define COBJMACROS
20edccad14SAmine Khaldi 
21edccad14SAmine Khaldi #include <stdarg.h>
22*628f4c99SAmine Khaldi #ifdef __REACTOS__
23*628f4c99SAmine Khaldi #include <wchar.h>
24*628f4c99SAmine Khaldi #endif
25edccad14SAmine Khaldi 
26edccad14SAmine Khaldi #include "windef.h"
27edccad14SAmine Khaldi #include "winbase.h"
28edccad14SAmine Khaldi #include "objbase.h"
29edccad14SAmine Khaldi #include "wbemcli.h"
30edccad14SAmine Khaldi 
31edccad14SAmine Khaldi #include "wine/debug.h"
32c2c66affSColin Finck #include "wbemprox_private.h"
33c2c66affSColin Finck 
34edccad14SAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
35edccad14SAmine Khaldi 
36c2c66affSColin Finck struct client_security
37c2c66affSColin Finck {
38c2c66affSColin Finck     IClientSecurity IClientSecurity_iface;
39c2c66affSColin Finck };
40c2c66affSColin Finck 
impl_from_IClientSecurity(IClientSecurity * iface)41c2c66affSColin Finck static inline struct client_security *impl_from_IClientSecurity( IClientSecurity *iface )
42c2c66affSColin Finck {
43c2c66affSColin Finck     return CONTAINING_RECORD( iface, struct client_security, IClientSecurity_iface );
44c2c66affSColin Finck }
45c2c66affSColin Finck 
client_security_QueryInterface(IClientSecurity * iface,REFIID riid,void ** ppvObject)46c2c66affSColin Finck static HRESULT WINAPI client_security_QueryInterface(
47c2c66affSColin Finck     IClientSecurity *iface,
48c2c66affSColin Finck     REFIID riid,
49c2c66affSColin Finck     void **ppvObject )
50c2c66affSColin Finck {
51c2c66affSColin Finck     struct client_security *cs = impl_from_IClientSecurity( iface );
52c2c66affSColin Finck 
53c2c66affSColin Finck     TRACE("%p %s %p\n", cs, debugstr_guid( riid ), ppvObject );
54c2c66affSColin Finck 
55c2c66affSColin Finck     if ( IsEqualGUID( riid, &IID_IClientSecurity ) ||
56c2c66affSColin Finck          IsEqualGUID( riid, &IID_IUnknown ) )
57c2c66affSColin Finck     {
58c2c66affSColin Finck         *ppvObject = cs;
59c2c66affSColin Finck     }
60c2c66affSColin Finck     else
61c2c66affSColin Finck     {
62c2c66affSColin Finck         FIXME("interface %s not implemented\n", debugstr_guid(riid));
63c2c66affSColin Finck         return E_NOINTERFACE;
64c2c66affSColin Finck     }
65c2c66affSColin Finck     IClientSecurity_AddRef( iface );
66c2c66affSColin Finck     return S_OK;
67c2c66affSColin Finck }
68c2c66affSColin Finck 
client_security_AddRef(IClientSecurity * iface)69c2c66affSColin Finck static ULONG WINAPI client_security_AddRef(
70c2c66affSColin Finck     IClientSecurity *iface )
71c2c66affSColin Finck {
72c2c66affSColin Finck     FIXME("%p\n", iface);
73c2c66affSColin Finck     return 2;
74c2c66affSColin Finck }
75c2c66affSColin Finck 
client_security_Release(IClientSecurity * iface)76c2c66affSColin Finck static ULONG WINAPI client_security_Release(
77c2c66affSColin Finck     IClientSecurity *iface )
78c2c66affSColin Finck {
79c2c66affSColin Finck     FIXME("%p\n", iface);
80c2c66affSColin Finck     return 1;
81c2c66affSColin Finck }
82c2c66affSColin Finck 
client_security_QueryBlanket(IClientSecurity * iface,IUnknown * pProxy,DWORD * pAuthnSvc,DWORD * pAuthzSvc,OLECHAR ** pServerPrincName,DWORD * pAuthnLevel,DWORD * pImpLevel,void ** pAuthInfo,DWORD * pCapabilities)83c2c66affSColin Finck static HRESULT WINAPI client_security_QueryBlanket(
84c2c66affSColin Finck     IClientSecurity *iface,
85c2c66affSColin Finck     IUnknown *pProxy,
86c2c66affSColin Finck     DWORD *pAuthnSvc,
87c2c66affSColin Finck     DWORD *pAuthzSvc,
88c2c66affSColin Finck     OLECHAR **pServerPrincName,
89c2c66affSColin Finck     DWORD *pAuthnLevel,
90c2c66affSColin Finck     DWORD *pImpLevel,
91c2c66affSColin Finck     void **pAuthInfo,
92c2c66affSColin Finck     DWORD *pCapabilities )
93c2c66affSColin Finck {
94c2c66affSColin Finck     FIXME("\n");
95c2c66affSColin Finck     return WBEM_E_FAILED;
96c2c66affSColin Finck }
97c2c66affSColin Finck 
client_security_SetBlanket(IClientSecurity * iface,IUnknown * pProxy,DWORD AuthnSvc,DWORD AuthzSvc,OLECHAR * pServerPrincName,DWORD AuthnLevel,DWORD ImpLevel,void * pAuthInfo,DWORD Capabilities)98c2c66affSColin Finck static HRESULT WINAPI client_security_SetBlanket(
99c2c66affSColin Finck     IClientSecurity *iface,
100c2c66affSColin Finck     IUnknown *pProxy,
101c2c66affSColin Finck     DWORD AuthnSvc,
102c2c66affSColin Finck     DWORD AuthzSvc,
103c2c66affSColin Finck     OLECHAR *pServerPrincName,
104c2c66affSColin Finck     DWORD AuthnLevel,
105c2c66affSColin Finck     DWORD ImpLevel,
106c2c66affSColin Finck     void *pAuthInfo,
107c2c66affSColin Finck     DWORD Capabilities )
108c2c66affSColin Finck {
109c2c66affSColin Finck     static const OLECHAR defaultW[] =
110c2c66affSColin Finck         {'<','C','O','L','E','_','D','E','F','A','U','L','T','_','P','R','I','N','C','I','P','A','L','>',0};
111c2c66affSColin Finck     const OLECHAR *princname = (pServerPrincName == COLE_DEFAULT_PRINCIPAL) ? defaultW : pServerPrincName;
112c2c66affSColin Finck 
113c2c66affSColin Finck     FIXME("%p, %p, %u, %u, %s, %u, %u, %p, 0x%08x\n", iface, pProxy, AuthnSvc, AuthzSvc,
114c2c66affSColin Finck           debugstr_w(princname), AuthnLevel, ImpLevel, pAuthInfo, Capabilities);
115c2c66affSColin Finck     return WBEM_NO_ERROR;
116c2c66affSColin Finck }
117c2c66affSColin Finck 
client_security_CopyProxy(IClientSecurity * iface,IUnknown * pProxy,IUnknown ** ppCopy)118c2c66affSColin Finck static HRESULT WINAPI client_security_CopyProxy(
119c2c66affSColin Finck     IClientSecurity *iface,
120c2c66affSColin Finck     IUnknown *pProxy,
121c2c66affSColin Finck     IUnknown **ppCopy )
122c2c66affSColin Finck {
123c2c66affSColin Finck     FIXME("\n");
124c2c66affSColin Finck     return WBEM_E_FAILED;
125c2c66affSColin Finck }
126c2c66affSColin Finck 
127c2c66affSColin Finck static const IClientSecurityVtbl client_security_vtbl =
128c2c66affSColin Finck {
129c2c66affSColin Finck     client_security_QueryInterface,
130c2c66affSColin Finck     client_security_AddRef,
131c2c66affSColin Finck     client_security_Release,
132c2c66affSColin Finck     client_security_QueryBlanket,
133c2c66affSColin Finck     client_security_SetBlanket,
134c2c66affSColin Finck     client_security_CopyProxy
135c2c66affSColin Finck };
136c2c66affSColin Finck 
137c2c66affSColin Finck IClientSecurity client_security = { &client_security_vtbl };
138c2c66affSColin Finck 
139c2c66affSColin Finck struct async_header
140c2c66affSColin Finck {
141c2c66affSColin Finck     IWbemObjectSink *sink;
142c2c66affSColin Finck     void (*proc)( struct async_header * );
143c2c66affSColin Finck     HANDLE cancel;
144c2c66affSColin Finck     HANDLE wait;
145c2c66affSColin Finck };
146c2c66affSColin Finck 
147c2c66affSColin Finck struct async_query
148c2c66affSColin Finck {
149c2c66affSColin Finck     struct async_header hdr;
150c2c66affSColin Finck     WCHAR *str;
151c2c66affSColin Finck };
152c2c66affSColin Finck 
free_async(struct async_header * async)153c2c66affSColin Finck static void free_async( struct async_header *async )
154c2c66affSColin Finck {
155c2c66affSColin Finck     if (async->sink) IWbemObjectSink_Release( async->sink );
156c2c66affSColin Finck     CloseHandle( async->cancel );
157c2c66affSColin Finck     CloseHandle( async->wait );
158c2c66affSColin Finck     heap_free( async );
159c2c66affSColin Finck }
160c2c66affSColin Finck 
init_async(struct async_header * async,IWbemObjectSink * sink,void (* proc)(struct async_header *))161c2c66affSColin Finck static BOOL init_async( struct async_header *async, IWbemObjectSink *sink,
162c2c66affSColin Finck                         void (*proc)(struct async_header *) )
163c2c66affSColin Finck {
164c2c66affSColin Finck     if (!(async->wait = CreateEventW( NULL, FALSE, FALSE, NULL ))) return FALSE;
165c2c66affSColin Finck     if (!(async->cancel = CreateEventW( NULL, FALSE, FALSE, NULL )))
166c2c66affSColin Finck     {
167c2c66affSColin Finck         CloseHandle( async->wait );
168c2c66affSColin Finck         return FALSE;
169c2c66affSColin Finck     }
170c2c66affSColin Finck     async->proc = proc;
171c2c66affSColin Finck     async->sink = sink;
172c2c66affSColin Finck     IWbemObjectSink_AddRef( sink );
173c2c66affSColin Finck     return TRUE;
174c2c66affSColin Finck }
175c2c66affSColin Finck 
async_proc(LPVOID param)176c2c66affSColin Finck static DWORD CALLBACK async_proc( LPVOID param )
177c2c66affSColin Finck {
178c2c66affSColin Finck     struct async_header *async = param;
179c2c66affSColin Finck     HANDLE wait = async->wait;
180c2c66affSColin Finck 
181c2c66affSColin Finck     async->proc( async );
182c2c66affSColin Finck 
183c2c66affSColin Finck     WaitForSingleObject( async->cancel, INFINITE );
184c2c66affSColin Finck     SetEvent( wait );
185c2c66affSColin Finck     return ERROR_SUCCESS;
186c2c66affSColin Finck }
187c2c66affSColin Finck 
queue_async(struct async_header * async)188c2c66affSColin Finck static HRESULT queue_async( struct async_header *async )
189c2c66affSColin Finck {
190c2c66affSColin Finck     if (QueueUserWorkItem( async_proc, async, WT_EXECUTELONGFUNCTION )) return S_OK;
191c2c66affSColin Finck     return HRESULT_FROM_WIN32( GetLastError() );
192c2c66affSColin Finck }
193c2c66affSColin Finck 
194c2c66affSColin Finck struct wbem_services
195c2c66affSColin Finck {
196c2c66affSColin Finck     IWbemServices IWbemServices_iface;
197c2c66affSColin Finck     LONG refs;
198c2c66affSColin Finck     CRITICAL_SECTION cs;
199c2c66affSColin Finck     WCHAR *namespace;
200c2c66affSColin Finck     struct async_header *async;
201c2c66affSColin Finck };
202c2c66affSColin Finck 
impl_from_IWbemServices(IWbemServices * iface)203c2c66affSColin Finck static inline struct wbem_services *impl_from_IWbemServices( IWbemServices *iface )
204c2c66affSColin Finck {
205c2c66affSColin Finck     return CONTAINING_RECORD( iface, struct wbem_services, IWbemServices_iface );
206c2c66affSColin Finck }
207c2c66affSColin Finck 
wbem_services_AddRef(IWbemServices * iface)208c2c66affSColin Finck static ULONG WINAPI wbem_services_AddRef(
209c2c66affSColin Finck     IWbemServices *iface )
210c2c66affSColin Finck {
211c2c66affSColin Finck     struct wbem_services *ws = impl_from_IWbemServices( iface );
212c2c66affSColin Finck     return InterlockedIncrement( &ws->refs );
213c2c66affSColin Finck }
214c2c66affSColin Finck 
wbem_services_Release(IWbemServices * iface)215c2c66affSColin Finck static ULONG WINAPI wbem_services_Release(
216c2c66affSColin Finck     IWbemServices *iface )
217c2c66affSColin Finck {
218c2c66affSColin Finck     struct wbem_services *ws = impl_from_IWbemServices( iface );
219c2c66affSColin Finck     LONG refs = InterlockedDecrement( &ws->refs );
220c2c66affSColin Finck     if (!refs)
221c2c66affSColin Finck     {
222c2c66affSColin Finck         TRACE("destroying %p\n", ws);
223c2c66affSColin Finck 
224c2c66affSColin Finck         EnterCriticalSection( &ws->cs );
225c2c66affSColin Finck         if (ws->async) SetEvent( ws->async->cancel );
226c2c66affSColin Finck         LeaveCriticalSection( &ws->cs );
227c2c66affSColin Finck         if (ws->async)
228c2c66affSColin Finck         {
229c2c66affSColin Finck             WaitForSingleObject( ws->async->wait, INFINITE );
230c2c66affSColin Finck             free_async( ws->async );
231c2c66affSColin Finck         }
232c2c66affSColin Finck         ws->cs.DebugInfo->Spare[0] = 0;
233c2c66affSColin Finck         DeleteCriticalSection( &ws->cs );
234c2c66affSColin Finck         heap_free( ws->namespace );
235c2c66affSColin Finck         heap_free( ws );
236c2c66affSColin Finck     }
237c2c66affSColin Finck     return refs;
238c2c66affSColin Finck }
239c2c66affSColin Finck 
wbem_services_QueryInterface(IWbemServices * iface,REFIID riid,void ** ppvObject)240c2c66affSColin Finck static HRESULT WINAPI wbem_services_QueryInterface(
241c2c66affSColin Finck     IWbemServices *iface,
242c2c66affSColin Finck     REFIID riid,
243c2c66affSColin Finck     void **ppvObject )
244c2c66affSColin Finck {
245c2c66affSColin Finck     struct wbem_services *ws = impl_from_IWbemServices( iface );
246c2c66affSColin Finck 
247c2c66affSColin Finck     TRACE("%p %s %p\n", ws, debugstr_guid( riid ), ppvObject );
248c2c66affSColin Finck 
249c2c66affSColin Finck     if ( IsEqualGUID( riid, &IID_IWbemServices ) ||
250c2c66affSColin Finck          IsEqualGUID( riid, &IID_IUnknown ) )
251c2c66affSColin Finck     {
252c2c66affSColin Finck         *ppvObject = ws;
253c2c66affSColin Finck     }
254c2c66affSColin Finck     else if ( IsEqualGUID( riid, &IID_IClientSecurity ) )
255c2c66affSColin Finck     {
256c2c66affSColin Finck         *ppvObject = &client_security;
257c2c66affSColin Finck         return S_OK;
258c2c66affSColin Finck     }
259c2c66affSColin Finck     else
260c2c66affSColin Finck     {
261c2c66affSColin Finck         FIXME("interface %s not implemented\n", debugstr_guid(riid));
262c2c66affSColin Finck         return E_NOINTERFACE;
263c2c66affSColin Finck     }
264c2c66affSColin Finck     IWbemServices_AddRef( iface );
265c2c66affSColin Finck     return S_OK;
266c2c66affSColin Finck }
267c2c66affSColin Finck 
wbem_services_OpenNamespace(IWbemServices * iface,const BSTR strNamespace,LONG lFlags,IWbemContext * pCtx,IWbemServices ** ppWorkingNamespace,IWbemCallResult ** ppResult)268c2c66affSColin Finck static HRESULT WINAPI wbem_services_OpenNamespace(
269c2c66affSColin Finck     IWbemServices *iface,
270c2c66affSColin Finck     const BSTR strNamespace,
271c2c66affSColin Finck     LONG lFlags,
272c2c66affSColin Finck     IWbemContext *pCtx,
273c2c66affSColin Finck     IWbemServices **ppWorkingNamespace,
274c2c66affSColin Finck     IWbemCallResult **ppResult )
275c2c66affSColin Finck {
276c2c66affSColin Finck     static const WCHAR cimv2W[] = {'c','i','m','v','2',0};
277c2c66affSColin Finck     static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
278c2c66affSColin Finck     struct wbem_services *ws = impl_from_IWbemServices( iface );
279c2c66affSColin Finck 
280c2c66affSColin Finck     TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strNamespace), lFlags,
281c2c66affSColin Finck           pCtx, ppWorkingNamespace, ppResult);
282c2c66affSColin Finck 
283*628f4c99SAmine Khaldi     if ((wcsicmp( strNamespace, cimv2W ) && wcsicmp( strNamespace, defaultW )) || ws->namespace)
284c2c66affSColin Finck         return WBEM_E_INVALID_NAMESPACE;
285c2c66affSColin Finck 
286c2c66affSColin Finck     return WbemServices_create( cimv2W, (void **)ppWorkingNamespace );
287c2c66affSColin Finck }
288c2c66affSColin Finck 
wbem_services_CancelAsyncCall(IWbemServices * iface,IWbemObjectSink * pSink)289c2c66affSColin Finck static HRESULT WINAPI wbem_services_CancelAsyncCall(
290c2c66affSColin Finck     IWbemServices *iface,
291c2c66affSColin Finck     IWbemObjectSink *pSink )
292c2c66affSColin Finck {
293c2c66affSColin Finck     struct wbem_services *services = impl_from_IWbemServices( iface );
294c2c66affSColin Finck     struct async_header *async;
295c2c66affSColin Finck 
296c2c66affSColin Finck     TRACE("%p, %p\n", iface, pSink);
297c2c66affSColin Finck 
298c2c66affSColin Finck     if (!pSink) return WBEM_E_INVALID_PARAMETER;
299c2c66affSColin Finck 
300c2c66affSColin Finck     EnterCriticalSection( &services->cs );
301c2c66affSColin Finck 
302c2c66affSColin Finck     if (!(async = services->async))
303c2c66affSColin Finck     {
304c2c66affSColin Finck         LeaveCriticalSection( &services->cs );
305c2c66affSColin Finck         return WBEM_E_INVALID_PARAMETER;
306c2c66affSColin Finck     }
307c2c66affSColin Finck     services->async = NULL;
308c2c66affSColin Finck     SetEvent( async->cancel );
309c2c66affSColin Finck 
310c2c66affSColin Finck     LeaveCriticalSection( &services->cs );
311c2c66affSColin Finck 
312c2c66affSColin Finck     WaitForSingleObject( async->wait, INFINITE );
313c2c66affSColin Finck     free_async( async );
314c2c66affSColin Finck     return S_OK;
315c2c66affSColin Finck }
316c2c66affSColin Finck 
wbem_services_QueryObjectSink(IWbemServices * iface,LONG lFlags,IWbemObjectSink ** ppResponseHandler)317c2c66affSColin Finck static HRESULT WINAPI wbem_services_QueryObjectSink(
318c2c66affSColin Finck     IWbemServices *iface,
319c2c66affSColin Finck     LONG lFlags,
320c2c66affSColin Finck     IWbemObjectSink **ppResponseHandler )
321c2c66affSColin Finck {
322c2c66affSColin Finck     FIXME("\n");
323c2c66affSColin Finck     return WBEM_E_FAILED;
324c2c66affSColin Finck }
325c2c66affSColin Finck 
parse_path(const WCHAR * str,struct path ** ret)326*628f4c99SAmine Khaldi HRESULT parse_path( const WCHAR *str, struct path **ret )
327c2c66affSColin Finck {
328c2c66affSColin Finck     struct path *path;
329c2c66affSColin Finck     const WCHAR *p = str, *q;
330c2c66affSColin Finck     UINT len;
331c2c66affSColin Finck 
332c2c66affSColin Finck     if (!(path = heap_alloc_zero( sizeof(*path) ))) return E_OUTOFMEMORY;
333c2c66affSColin Finck 
33446add00dSAmine Khaldi     if (*p == '\\')
33546add00dSAmine Khaldi     {
336*628f4c99SAmine Khaldi         static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
33746add00dSAmine Khaldi         WCHAR server[MAX_COMPUTERNAME_LENGTH+1];
33846add00dSAmine Khaldi         DWORD server_len = ARRAY_SIZE(server);
33946add00dSAmine Khaldi 
34046add00dSAmine Khaldi         p++;
341*628f4c99SAmine Khaldi         if (*p != '\\')
342*628f4c99SAmine Khaldi         {
343*628f4c99SAmine Khaldi             heap_free( path );
344*628f4c99SAmine Khaldi             return WBEM_E_INVALID_OBJECT_PATH;
345*628f4c99SAmine Khaldi         }
34646add00dSAmine Khaldi         p++;
34746add00dSAmine Khaldi 
34846add00dSAmine Khaldi         q = p;
34946add00dSAmine Khaldi         while (*p && *p != '\\') p++;
350*628f4c99SAmine Khaldi         if (!*p)
351*628f4c99SAmine Khaldi         {
352*628f4c99SAmine Khaldi             heap_free( path );
353*628f4c99SAmine Khaldi             return WBEM_E_INVALID_OBJECT_PATH;
354*628f4c99SAmine Khaldi         }
35546add00dSAmine Khaldi 
35646add00dSAmine Khaldi         len = p - q;
357*628f4c99SAmine Khaldi         if (!GetComputerNameW( server, &server_len ) || server_len != len || _wcsnicmp( q, server, server_len ))
358*628f4c99SAmine Khaldi         {
359*628f4c99SAmine Khaldi             heap_free( path );
36046add00dSAmine Khaldi             return WBEM_E_NOT_SUPPORTED;
361*628f4c99SAmine Khaldi         }
36246add00dSAmine Khaldi 
36346add00dSAmine Khaldi         q = ++p;
36446add00dSAmine Khaldi         while (*p && *p != ':') p++;
365*628f4c99SAmine Khaldi         if (!*p)
366*628f4c99SAmine Khaldi         {
367*628f4c99SAmine Khaldi             heap_free( path );
368*628f4c99SAmine Khaldi             return WBEM_E_INVALID_OBJECT_PATH;
369*628f4c99SAmine Khaldi         }
37046add00dSAmine Khaldi 
37146add00dSAmine Khaldi         len = p - q;
372*628f4c99SAmine Khaldi         if (len != ARRAY_SIZE(cimv2W) - 1 || _wcsnicmp( q, cimv2W, ARRAY_SIZE(cimv2W) - 1 ))
373*628f4c99SAmine Khaldi         {
374*628f4c99SAmine Khaldi             heap_free( path );
37546add00dSAmine Khaldi             return WBEM_E_INVALID_NAMESPACE;
376*628f4c99SAmine Khaldi         }
37746add00dSAmine Khaldi         p++;
37846add00dSAmine Khaldi     }
37946add00dSAmine Khaldi 
38046add00dSAmine Khaldi     q = p;
381c2c66affSColin Finck     while (*p && *p != '.') p++;
382c2c66affSColin Finck 
38346add00dSAmine Khaldi     len = p - q;
384c2c66affSColin Finck     if (!(path->class = heap_alloc( (len + 1) * sizeof(WCHAR) )))
385c2c66affSColin Finck     {
386c2c66affSColin Finck         heap_free( path );
387c2c66affSColin Finck         return E_OUTOFMEMORY;
388c2c66affSColin Finck     }
38946add00dSAmine Khaldi     memcpy( path->class, q, len * sizeof(WCHAR) );
390c2c66affSColin Finck     path->class[len] = 0;
391c2c66affSColin Finck     path->class_len = len;
392c2c66affSColin Finck 
393c2c66affSColin Finck     if (p[0] == '.' && p[1])
394c2c66affSColin Finck     {
395c2c66affSColin Finck         q = ++p;
396c2c66affSColin Finck         while (*q) q++;
397c2c66affSColin Finck 
398c2c66affSColin Finck         len = q - p;
399c2c66affSColin Finck         if (!(path->filter = heap_alloc( (len + 1) * sizeof(WCHAR) )))
400c2c66affSColin Finck         {
401c2c66affSColin Finck             heap_free( path->class );
402c2c66affSColin Finck             heap_free( path );
403c2c66affSColin Finck             return E_OUTOFMEMORY;
404c2c66affSColin Finck         }
405c2c66affSColin Finck         memcpy( path->filter, p, len * sizeof(WCHAR) );
406c2c66affSColin Finck         path->filter[len] = 0;
407c2c66affSColin Finck         path->filter_len = len;
408c2c66affSColin Finck     }
409c2c66affSColin Finck     *ret = path;
410c2c66affSColin Finck     return S_OK;
411c2c66affSColin Finck }
412c2c66affSColin Finck 
free_path(struct path * path)413*628f4c99SAmine Khaldi void free_path( struct path *path )
414c2c66affSColin Finck {
415*628f4c99SAmine Khaldi     if (!path) return;
416c2c66affSColin Finck     heap_free( path->class );
417c2c66affSColin Finck     heap_free( path->filter );
418c2c66affSColin Finck     heap_free( path );
419c2c66affSColin Finck }
420c2c66affSColin Finck 
query_from_path(const struct path * path)421*628f4c99SAmine Khaldi WCHAR *query_from_path( const struct path *path )
422c2c66affSColin Finck {
423c2c66affSColin Finck     static const WCHAR selectW[] =
424c2c66affSColin Finck         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','%','s',' ',
425c2c66affSColin Finck          'W','H','E','R','E',' ','%','s',0};
426c2c66affSColin Finck     static const WCHAR select_allW[] =
427c2c66affSColin Finck         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0};
428c2c66affSColin Finck     WCHAR *query;
429c2c66affSColin Finck     UINT len;
430c2c66affSColin Finck 
431c2c66affSColin Finck     if (path->filter)
432c2c66affSColin Finck     {
43346add00dSAmine Khaldi         len = path->class_len + path->filter_len + ARRAY_SIZE(selectW);
434c2c66affSColin Finck         if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
435*628f4c99SAmine Khaldi         swprintf( query, selectW, path->class, path->filter );
436c2c66affSColin Finck     }
437c2c66affSColin Finck     else
438c2c66affSColin Finck     {
43946add00dSAmine Khaldi         len = path->class_len + ARRAY_SIZE(select_allW);
440c2c66affSColin Finck         if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
441*628f4c99SAmine Khaldi         lstrcpyW( query, select_allW );
442*628f4c99SAmine Khaldi         lstrcatW( query, path->class );
443c2c66affSColin Finck     }
444c2c66affSColin Finck     return query;
445c2c66affSColin Finck }
446c2c66affSColin Finck 
create_instance_enum(const struct path * path,IEnumWbemClassObject ** iter)447c2c66affSColin Finck static HRESULT create_instance_enum( const struct path *path, IEnumWbemClassObject **iter )
448c2c66affSColin Finck {
449c2c66affSColin Finck     WCHAR *query;
450c2c66affSColin Finck     HRESULT hr;
451c2c66affSColin Finck 
452c2c66affSColin Finck     if (!(query = query_from_path( path ))) return E_OUTOFMEMORY;
453c2c66affSColin Finck     hr = exec_query( query, iter );
454c2c66affSColin Finck     heap_free( query );
455c2c66affSColin Finck     return hr;
456c2c66affSColin Finck }
457c2c66affSColin Finck 
get_object(const WCHAR * object_path,IWbemClassObject ** obj)458c2c66affSColin Finck HRESULT get_object( const WCHAR *object_path, IWbemClassObject **obj )
459c2c66affSColin Finck {
460c2c66affSColin Finck     IEnumWbemClassObject *iter;
461c2c66affSColin Finck     struct path *path;
462c2c66affSColin Finck     HRESULT hr;
463c2c66affSColin Finck 
464c2c66affSColin Finck     hr = parse_path( object_path, &path );
465c2c66affSColin Finck     if (hr != S_OK) return hr;
466c2c66affSColin Finck 
467c2c66affSColin Finck     hr = create_instance_enum( path, &iter );
468c2c66affSColin Finck     if (hr != S_OK)
469c2c66affSColin Finck     {
470c2c66affSColin Finck         free_path( path );
471c2c66affSColin Finck         return hr;
472c2c66affSColin Finck     }
473c2c66affSColin Finck     hr = create_class_object( path->class, iter, 0, NULL, obj );
474c2c66affSColin Finck     IEnumWbemClassObject_Release( iter );
475c2c66affSColin Finck     free_path( path );
476c2c66affSColin Finck     return hr;
477c2c66affSColin Finck }
478c2c66affSColin Finck 
wbem_services_GetObject(IWbemServices * iface,const BSTR strObjectPath,LONG lFlags,IWbemContext * pCtx,IWbemClassObject ** ppObject,IWbemCallResult ** ppCallResult)479c2c66affSColin Finck static HRESULT WINAPI wbem_services_GetObject(
480c2c66affSColin Finck     IWbemServices *iface,
481c2c66affSColin Finck     const BSTR strObjectPath,
482c2c66affSColin Finck     LONG lFlags,
483c2c66affSColin Finck     IWbemContext *pCtx,
484c2c66affSColin Finck     IWbemClassObject **ppObject,
485c2c66affSColin Finck     IWbemCallResult **ppCallResult )
486c2c66affSColin Finck {
487c2c66affSColin Finck     TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strObjectPath), lFlags,
488c2c66affSColin Finck           pCtx, ppObject, ppCallResult);
489c2c66affSColin Finck 
490c2c66affSColin Finck     if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
491c2c66affSColin Finck 
492c2c66affSColin Finck     if (!strObjectPath || !strObjectPath[0])
493c2c66affSColin Finck         return create_class_object( NULL, NULL, 0, NULL, ppObject );
494c2c66affSColin Finck 
495c2c66affSColin Finck     return get_object( strObjectPath, ppObject );
496c2c66affSColin Finck }
497c2c66affSColin Finck 
wbem_services_GetObjectAsync(IWbemServices * iface,const BSTR strObjectPath,LONG lFlags,IWbemContext * pCtx,IWbemObjectSink * pResponseHandler)498c2c66affSColin Finck static HRESULT WINAPI wbem_services_GetObjectAsync(
499c2c66affSColin Finck     IWbemServices *iface,
500c2c66affSColin Finck     const BSTR strObjectPath,
501c2c66affSColin Finck     LONG lFlags,
502c2c66affSColin Finck     IWbemContext *pCtx,
503c2c66affSColin Finck     IWbemObjectSink *pResponseHandler )
504c2c66affSColin Finck {
505c2c66affSColin Finck     FIXME("\n");
506c2c66affSColin Finck     return WBEM_E_FAILED;
507c2c66affSColin Finck }
508c2c66affSColin Finck 
wbem_services_PutClass(IWbemServices * iface,IWbemClassObject * pObject,LONG lFlags,IWbemContext * pCtx,IWbemCallResult ** ppCallResult)509c2c66affSColin Finck static HRESULT WINAPI wbem_services_PutClass(
510c2c66affSColin Finck     IWbemServices *iface,
511c2c66affSColin Finck     IWbemClassObject *pObject,
512c2c66affSColin Finck     LONG lFlags,
513c2c66affSColin Finck     IWbemContext *pCtx,
514c2c66affSColin Finck     IWbemCallResult **ppCallResult )
515c2c66affSColin Finck {
516c2c66affSColin Finck     FIXME("\n");
517c2c66affSColin Finck     return WBEM_E_FAILED;
518c2c66affSColin Finck }
519c2c66affSColin Finck 
wbem_services_PutClassAsync(IWbemServices * iface,IWbemClassObject * pObject,LONG lFlags,IWbemContext * pCtx,IWbemObjectSink * pResponseHandler)520c2c66affSColin Finck static HRESULT WINAPI wbem_services_PutClassAsync(
521c2c66affSColin Finck     IWbemServices *iface,
522c2c66affSColin Finck     IWbemClassObject *pObject,
523c2c66affSColin Finck     LONG lFlags,
524c2c66affSColin Finck     IWbemContext *pCtx,
525c2c66affSColin Finck     IWbemObjectSink *pResponseHandler )
526c2c66affSColin Finck {
527c2c66affSColin Finck     FIXME("\n");
528c2c66affSColin Finck     return WBEM_E_FAILED;
529c2c66affSColin Finck }
530c2c66affSColin Finck 
wbem_services_DeleteClass(IWbemServices * iface,const BSTR strClass,LONG lFlags,IWbemContext * pCtx,IWbemCallResult ** ppCallResult)531c2c66affSColin Finck static HRESULT WINAPI wbem_services_DeleteClass(
532c2c66affSColin Finck     IWbemServices *iface,
533c2c66affSColin Finck     const BSTR strClass,
534c2c66affSColin Finck     LONG lFlags,
535c2c66affSColin Finck     IWbemContext *pCtx,
536c2c66affSColin Finck     IWbemCallResult **ppCallResult )
537c2c66affSColin Finck {
538c2c66affSColin Finck     FIXME("\n");
539c2c66affSColin Finck     return WBEM_E_FAILED;
540c2c66affSColin Finck }
541c2c66affSColin Finck 
wbem_services_DeleteClassAsync(IWbemServices * iface,const BSTR strClass,LONG lFlags,IWbemContext * pCtx,IWbemObjectSink * pResponseHandler)542c2c66affSColin Finck static HRESULT WINAPI wbem_services_DeleteClassAsync(
543c2c66affSColin Finck     IWbemServices *iface,
544c2c66affSColin Finck     const BSTR strClass,
545c2c66affSColin Finck     LONG lFlags,
546c2c66affSColin Finck     IWbemContext *pCtx,
547c2c66affSColin Finck     IWbemObjectSink *pResponseHandler )
548c2c66affSColin Finck {
549c2c66affSColin Finck     FIXME("\n");
550c2c66affSColin Finck     return WBEM_E_FAILED;
551c2c66affSColin Finck }
552c2c66affSColin Finck 
wbem_services_CreateClassEnum(IWbemServices * iface,const BSTR strSuperclass,LONG lFlags,IWbemContext * pCtx,IEnumWbemClassObject ** ppEnum)553c2c66affSColin Finck static HRESULT WINAPI wbem_services_CreateClassEnum(
554c2c66affSColin Finck     IWbemServices *iface,
555c2c66affSColin Finck     const BSTR strSuperclass,
556c2c66affSColin Finck     LONG lFlags,
557c2c66affSColin Finck     IWbemContext *pCtx,
558c2c66affSColin Finck     IEnumWbemClassObject **ppEnum )
559c2c66affSColin Finck {
560c2c66affSColin Finck     FIXME("\n");
561c2c66affSColin Finck     return WBEM_E_FAILED;
562c2c66affSColin Finck }
563c2c66affSColin Finck 
wbem_services_CreateClassEnumAsync(IWbemServices * iface,const BSTR strSuperclass,LONG lFlags,IWbemContext * pCtx,IWbemObjectSink * pResponseHandler)564c2c66affSColin Finck static HRESULT WINAPI wbem_services_CreateClassEnumAsync(
565c2c66affSColin Finck     IWbemServices *iface,
566c2c66affSColin Finck     const BSTR strSuperclass,
567c2c66affSColin Finck     LONG lFlags,
568c2c66affSColin Finck     IWbemContext *pCtx,
569c2c66affSColin Finck     IWbemObjectSink *pResponseHandler )
570c2c66affSColin Finck {
571c2c66affSColin Finck     FIXME("\n");
572c2c66affSColin Finck     return WBEM_E_FAILED;
573c2c66affSColin Finck }
574c2c66affSColin Finck 
wbem_services_PutInstance(IWbemServices * iface,IWbemClassObject * pInst,LONG lFlags,IWbemContext * pCtx,IWbemCallResult ** ppCallResult)575c2c66affSColin Finck static HRESULT WINAPI wbem_services_PutInstance(
576c2c66affSColin Finck     IWbemServices *iface,
577c2c66affSColin Finck     IWbemClassObject *pInst,
578c2c66affSColin Finck     LONG lFlags,
579c2c66affSColin Finck     IWbemContext *pCtx,
580c2c66affSColin Finck     IWbemCallResult **ppCallResult )
581c2c66affSColin Finck {
582c2c66affSColin Finck     FIXME("\n");
583c2c66affSColin Finck     return WBEM_E_FAILED;
584c2c66affSColin Finck }
585c2c66affSColin Finck 
wbem_services_PutInstanceAsync(IWbemServices * iface,IWbemClassObject * pInst,LONG lFlags,IWbemContext * pCtx,IWbemObjectSink * pResponseHandler)586c2c66affSColin Finck static HRESULT WINAPI wbem_services_PutInstanceAsync(
587c2c66affSColin Finck     IWbemServices *iface,
588c2c66affSColin Finck     IWbemClassObject *pInst,
589c2c66affSColin Finck     LONG lFlags,
590c2c66affSColin Finck     IWbemContext *pCtx,
591c2c66affSColin Finck     IWbemObjectSink *pResponseHandler )
592c2c66affSColin Finck {
593c2c66affSColin Finck     FIXME("\n");
594c2c66affSColin Finck     return WBEM_E_FAILED;
595c2c66affSColin Finck }
596c2c66affSColin Finck 
wbem_services_DeleteInstance(IWbemServices * iface,const BSTR strObjectPath,LONG lFlags,IWbemContext * pCtx,IWbemCallResult ** ppCallResult)597c2c66affSColin Finck static HRESULT WINAPI wbem_services_DeleteInstance(
598c2c66affSColin Finck     IWbemServices *iface,
599c2c66affSColin Finck     const BSTR strObjectPath,
600c2c66affSColin Finck     LONG lFlags,
601c2c66affSColin Finck     IWbemContext *pCtx,
602c2c66affSColin Finck     IWbemCallResult **ppCallResult )
603c2c66affSColin Finck {
604c2c66affSColin Finck     FIXME("\n");
605c2c66affSColin Finck     return WBEM_E_FAILED;
606c2c66affSColin Finck }
607c2c66affSColin Finck 
wbem_services_DeleteInstanceAsync(IWbemServices * iface,const BSTR strObjectPath,LONG lFlags,IWbemContext * pCtx,IWbemObjectSink * pResponseHandler)608c2c66affSColin Finck static HRESULT WINAPI wbem_services_DeleteInstanceAsync(
609c2c66affSColin Finck     IWbemServices *iface,
610c2c66affSColin Finck     const BSTR strObjectPath,
611c2c66affSColin Finck     LONG lFlags,
612c2c66affSColin Finck     IWbemContext *pCtx,
613c2c66affSColin Finck     IWbemObjectSink *pResponseHandler )
614c2c66affSColin Finck {
615c2c66affSColin Finck     FIXME("\n");
616c2c66affSColin Finck     return WBEM_E_FAILED;
617c2c66affSColin Finck }
618c2c66affSColin Finck 
wbem_services_CreateInstanceEnum(IWbemServices * iface,const BSTR strClass,LONG lFlags,IWbemContext * pCtx,IEnumWbemClassObject ** ppEnum)619c2c66affSColin Finck static HRESULT WINAPI wbem_services_CreateInstanceEnum(
620c2c66affSColin Finck     IWbemServices *iface,
621c2c66affSColin Finck     const BSTR strClass,
622c2c66affSColin Finck     LONG lFlags,
623c2c66affSColin Finck     IWbemContext *pCtx,
624c2c66affSColin Finck     IEnumWbemClassObject **ppEnum )
625c2c66affSColin Finck {
626c2c66affSColin Finck     struct path *path;
627c2c66affSColin Finck     HRESULT hr;
628c2c66affSColin Finck 
629c2c66affSColin Finck     TRACE("%p, %s, 0%08x, %p, %p\n", iface, debugstr_w(strClass), lFlags, pCtx, ppEnum);
630c2c66affSColin Finck 
631c2c66affSColin Finck     if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags);
632c2c66affSColin Finck 
633c2c66affSColin Finck     hr = parse_path( strClass, &path );
634c2c66affSColin Finck     if (hr != S_OK) return hr;
635c2c66affSColin Finck 
636c2c66affSColin Finck     hr = create_instance_enum( path, ppEnum );
637c2c66affSColin Finck     free_path( path );
638c2c66affSColin Finck     return hr;
639c2c66affSColin Finck }
640c2c66affSColin Finck 
wbem_services_CreateInstanceEnumAsync(IWbemServices * iface,const BSTR strFilter,LONG lFlags,IWbemContext * pCtx,IWbemObjectSink * pResponseHandler)641c2c66affSColin Finck static HRESULT WINAPI wbem_services_CreateInstanceEnumAsync(
642c2c66affSColin Finck     IWbemServices *iface,
643c2c66affSColin Finck     const BSTR strFilter,
644c2c66affSColin Finck     LONG lFlags,
645c2c66affSColin Finck     IWbemContext *pCtx,
646c2c66affSColin Finck     IWbemObjectSink *pResponseHandler )
647c2c66affSColin Finck {
648c2c66affSColin Finck     FIXME("\n");
649c2c66affSColin Finck     return WBEM_E_FAILED;
650c2c66affSColin Finck }
651c2c66affSColin Finck 
wbem_services_ExecQuery(IWbemServices * iface,const BSTR strQueryLanguage,const BSTR strQuery,LONG lFlags,IWbemContext * pCtx,IEnumWbemClassObject ** ppEnum)652c2c66affSColin Finck static HRESULT WINAPI wbem_services_ExecQuery(
653c2c66affSColin Finck     IWbemServices *iface,
654c2c66affSColin Finck     const BSTR strQueryLanguage,
655c2c66affSColin Finck     const BSTR strQuery,
656c2c66affSColin Finck     LONG lFlags,
657c2c66affSColin Finck     IWbemContext *pCtx,
658c2c66affSColin Finck     IEnumWbemClassObject **ppEnum )
659c2c66affSColin Finck {
660c2c66affSColin Finck     static const WCHAR wqlW[] = {'W','Q','L',0};
661c2c66affSColin Finck 
662c2c66affSColin Finck     TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage),
663c2c66affSColin Finck           debugstr_w(strQuery), lFlags, pCtx, ppEnum);
664c2c66affSColin Finck 
665c2c66affSColin Finck     if (!strQueryLanguage || !strQuery || !strQuery[0]) return WBEM_E_INVALID_PARAMETER;
666*628f4c99SAmine Khaldi     if (wcsicmp( strQueryLanguage, wqlW )) return WBEM_E_INVALID_QUERY_TYPE;
667c2c66affSColin Finck     return exec_query( strQuery, ppEnum );
668c2c66affSColin Finck }
669c2c66affSColin Finck 
async_exec_query(struct async_header * hdr)670c2c66affSColin Finck static void async_exec_query( struct async_header *hdr )
671c2c66affSColin Finck {
672c2c66affSColin Finck     struct async_query *query = (struct async_query *)hdr;
673c2c66affSColin Finck     IEnumWbemClassObject *result;
674c2c66affSColin Finck     IWbemClassObject *obj;
675c2c66affSColin Finck     ULONG count;
676c2c66affSColin Finck     HRESULT hr;
677c2c66affSColin Finck 
678c2c66affSColin Finck     hr = exec_query( query->str, &result );
679c2c66affSColin Finck     if (hr == S_OK)
680c2c66affSColin Finck     {
681c2c66affSColin Finck         for (;;)
682c2c66affSColin Finck         {
683c2c66affSColin Finck             IEnumWbemClassObject_Next( result, WBEM_INFINITE, 1, &obj, &count );
684c2c66affSColin Finck             if (!count) break;
685c2c66affSColin Finck             IWbemObjectSink_Indicate( query->hdr.sink, 1, &obj );
686c2c66affSColin Finck             IWbemClassObject_Release( obj );
687c2c66affSColin Finck         }
688c2c66affSColin Finck         IEnumWbemClassObject_Release( result );
689c2c66affSColin Finck     }
690c2c66affSColin Finck     IWbemObjectSink_SetStatus( query->hdr.sink, WBEM_STATUS_COMPLETE, hr, NULL, NULL );
691c2c66affSColin Finck     heap_free( query->str );
692c2c66affSColin Finck }
693c2c66affSColin Finck 
wbem_services_ExecQueryAsync(IWbemServices * iface,const BSTR strQueryLanguage,const BSTR strQuery,LONG lFlags,IWbemContext * pCtx,IWbemObjectSink * pResponseHandler)694c2c66affSColin Finck static HRESULT WINAPI wbem_services_ExecQueryAsync(
695c2c66affSColin Finck     IWbemServices *iface,
696c2c66affSColin Finck     const BSTR strQueryLanguage,
697c2c66affSColin Finck     const BSTR strQuery,
698c2c66affSColin Finck     LONG lFlags,
699c2c66affSColin Finck     IWbemContext *pCtx,
700c2c66affSColin Finck     IWbemObjectSink *pResponseHandler )
701c2c66affSColin Finck {
702c2c66affSColin Finck     struct wbem_services *services = impl_from_IWbemServices( iface );
703c2c66affSColin Finck     IWbemObjectSink *sink;
704c2c66affSColin Finck     HRESULT hr = E_OUTOFMEMORY;
705c2c66affSColin Finck     struct async_header *async;
706c2c66affSColin Finck     struct async_query *query;
707c2c66affSColin Finck 
708c2c66affSColin Finck     TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage), debugstr_w(strQuery),
709c2c66affSColin Finck           lFlags, pCtx, pResponseHandler);
710c2c66affSColin Finck 
711c2c66affSColin Finck     if (!pResponseHandler) return WBEM_E_INVALID_PARAMETER;
712c2c66affSColin Finck 
713c2c66affSColin Finck     hr = IWbemObjectSink_QueryInterface( pResponseHandler, &IID_IWbemObjectSink, (void **)&sink );
714c2c66affSColin Finck     if (FAILED(hr)) return hr;
715c2c66affSColin Finck 
716c2c66affSColin Finck     EnterCriticalSection( &services->cs );
717c2c66affSColin Finck 
718c2c66affSColin Finck     if (services->async)
719c2c66affSColin Finck     {
720c2c66affSColin Finck         FIXME("handle more than one pending async\n");
721c2c66affSColin Finck         hr = WBEM_E_FAILED;
722c2c66affSColin Finck         goto done;
723c2c66affSColin Finck     }
724c2c66affSColin Finck     if (!(query = heap_alloc_zero( sizeof(*query) ))) goto done;
725c2c66affSColin Finck     async = (struct async_header *)query;
726c2c66affSColin Finck 
727c2c66affSColin Finck     if (!(init_async( async, sink, async_exec_query )))
728c2c66affSColin Finck     {
729c2c66affSColin Finck         free_async( async );
730c2c66affSColin Finck         goto done;
731c2c66affSColin Finck     }
732c2c66affSColin Finck     if (!(query->str = heap_strdupW( strQuery )))
733c2c66affSColin Finck     {
734c2c66affSColin Finck         free_async( async );
735c2c66affSColin Finck         goto done;
736c2c66affSColin Finck     }
737c2c66affSColin Finck     hr = queue_async( async );
738c2c66affSColin Finck     if (hr == S_OK) services->async = async;
739c2c66affSColin Finck     else
740c2c66affSColin Finck     {
741c2c66affSColin Finck         heap_free( query->str );
742c2c66affSColin Finck         free_async( async );
743c2c66affSColin Finck     }
744c2c66affSColin Finck 
745c2c66affSColin Finck done:
746c2c66affSColin Finck     LeaveCriticalSection( &services->cs );
747c2c66affSColin Finck     IWbemObjectSink_Release( sink );
748c2c66affSColin Finck     return hr;
749c2c66affSColin Finck }
750c2c66affSColin Finck 
wbem_services_ExecNotificationQuery(IWbemServices * iface,const BSTR strQueryLanguage,const BSTR strQuery,LONG lFlags,IWbemContext * pCtx,IEnumWbemClassObject ** ppEnum)751c2c66affSColin Finck static HRESULT WINAPI wbem_services_ExecNotificationQuery(
752c2c66affSColin Finck     IWbemServices *iface,
753c2c66affSColin Finck     const BSTR strQueryLanguage,
754c2c66affSColin Finck     const BSTR strQuery,
755c2c66affSColin Finck     LONG lFlags,
756c2c66affSColin Finck     IWbemContext *pCtx,
757c2c66affSColin Finck     IEnumWbemClassObject **ppEnum )
758c2c66affSColin Finck {
759c2c66affSColin Finck     FIXME("\n");
760c2c66affSColin Finck     return WBEM_E_FAILED;
761c2c66affSColin Finck }
762c2c66affSColin Finck 
wbem_services_ExecNotificationQueryAsync(IWbemServices * iface,const BSTR strQueryLanguage,const BSTR strQuery,LONG lFlags,IWbemContext * pCtx,IWbemObjectSink * pResponseHandler)763c2c66affSColin Finck static HRESULT WINAPI wbem_services_ExecNotificationQueryAsync(
764c2c66affSColin Finck     IWbemServices *iface,
765c2c66affSColin Finck     const BSTR strQueryLanguage,
766c2c66affSColin Finck     const BSTR strQuery,
767c2c66affSColin Finck     LONG lFlags,
768c2c66affSColin Finck     IWbemContext *pCtx,
769c2c66affSColin Finck     IWbemObjectSink *pResponseHandler )
770c2c66affSColin Finck {
771c2c66affSColin Finck     struct wbem_services *services = impl_from_IWbemServices( iface );
772c2c66affSColin Finck     IWbemObjectSink *sink;
773c2c66affSColin Finck     HRESULT hr = E_OUTOFMEMORY;
774c2c66affSColin Finck     struct async_header *async;
775c2c66affSColin Finck     struct async_query *query;
776c2c66affSColin Finck 
777c2c66affSColin Finck     TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage), debugstr_w(strQuery),
778c2c66affSColin Finck           lFlags, pCtx, pResponseHandler);
779c2c66affSColin Finck 
780c2c66affSColin Finck     if (!pResponseHandler) return WBEM_E_INVALID_PARAMETER;
781c2c66affSColin Finck 
782c2c66affSColin Finck     hr = IWbemObjectSink_QueryInterface( pResponseHandler, &IID_IWbemObjectSink, (void **)&sink );
783c2c66affSColin Finck     if (FAILED(hr)) return hr;
784c2c66affSColin Finck 
785c2c66affSColin Finck     EnterCriticalSection( &services->cs );
786c2c66affSColin Finck 
787c2c66affSColin Finck     if (services->async)
788c2c66affSColin Finck     {
789c2c66affSColin Finck         FIXME("handle more than one pending async\n");
790c2c66affSColin Finck         hr = WBEM_E_FAILED;
791c2c66affSColin Finck         goto done;
792c2c66affSColin Finck     }
793c2c66affSColin Finck     if (!(query = heap_alloc_zero( sizeof(*query) ))) goto done;
794c2c66affSColin Finck     async = (struct async_header *)query;
795c2c66affSColin Finck 
796c2c66affSColin Finck     if (!(init_async( async, sink, async_exec_query )))
797c2c66affSColin Finck     {
798c2c66affSColin Finck         free_async( async );
799c2c66affSColin Finck         goto done;
800c2c66affSColin Finck     }
801c2c66affSColin Finck     if (!(query->str = heap_strdupW( strQuery )))
802c2c66affSColin Finck     {
803c2c66affSColin Finck         free_async( async );
804c2c66affSColin Finck         goto done;
805c2c66affSColin Finck     }
806c2c66affSColin Finck     hr = queue_async( async );
807c2c66affSColin Finck     if (hr == S_OK) services->async = async;
808c2c66affSColin Finck     else
809c2c66affSColin Finck     {
810c2c66affSColin Finck         heap_free( query->str );
811c2c66affSColin Finck         free_async( async );
812c2c66affSColin Finck     }
813c2c66affSColin Finck 
814c2c66affSColin Finck done:
815c2c66affSColin Finck     LeaveCriticalSection( &services->cs );
816c2c66affSColin Finck     IWbemObjectSink_Release( sink );
817c2c66affSColin Finck     return hr;
818c2c66affSColin Finck }
819c2c66affSColin Finck 
wbem_services_ExecMethod(IWbemServices * iface,const BSTR strObjectPath,const BSTR strMethodName,LONG lFlags,IWbemContext * pCtx,IWbemClassObject * pInParams,IWbemClassObject ** ppOutParams,IWbemCallResult ** ppCallResult)820c2c66affSColin Finck static HRESULT WINAPI wbem_services_ExecMethod(
821c2c66affSColin Finck     IWbemServices *iface,
822c2c66affSColin Finck     const BSTR strObjectPath,
823c2c66affSColin Finck     const BSTR strMethodName,
824c2c66affSColin Finck     LONG lFlags,
825c2c66affSColin Finck     IWbemContext *pCtx,
826c2c66affSColin Finck     IWbemClassObject *pInParams,
827c2c66affSColin Finck     IWbemClassObject **ppOutParams,
828c2c66affSColin Finck     IWbemCallResult **ppCallResult )
829c2c66affSColin Finck {
830c2c66affSColin Finck     IEnumWbemClassObject *result = NULL;
831c2c66affSColin Finck     IWbemClassObject *obj = NULL;
832c2c66affSColin Finck     struct query *query = NULL;
833c2c66affSColin Finck     struct path *path;
834c2c66affSColin Finck     WCHAR *str;
835c2c66affSColin Finck     class_method *func;
836*628f4c99SAmine Khaldi     struct table *table;
837c2c66affSColin Finck     HRESULT hr;
838c2c66affSColin Finck 
839c2c66affSColin Finck     TRACE("%p, %s, %s, %08x, %p, %p, %p, %p\n", iface, debugstr_w(strObjectPath),
840c2c66affSColin Finck           debugstr_w(strMethodName), lFlags, pCtx, pInParams, ppOutParams, ppCallResult);
841c2c66affSColin Finck 
842c2c66affSColin Finck     if (lFlags) FIXME("flags %08x not supported\n", lFlags);
843c2c66affSColin Finck 
844c2c66affSColin Finck     if ((hr = parse_path( strObjectPath, &path )) != S_OK) return hr;
845c2c66affSColin Finck     if (!(str = query_from_path( path )))
846c2c66affSColin Finck     {
847c2c66affSColin Finck         hr = E_OUTOFMEMORY;
848c2c66affSColin Finck         goto done;
849c2c66affSColin Finck     }
850c2c66affSColin Finck     if (!(query = create_query()))
851c2c66affSColin Finck     {
852c2c66affSColin Finck         hr = E_OUTOFMEMORY;
853c2c66affSColin Finck         goto done;
854c2c66affSColin Finck     }
855c2c66affSColin Finck     hr = parse_query( str, &query->view, &query->mem );
856c2c66affSColin Finck     if (hr != S_OK) goto done;
857c2c66affSColin Finck 
858c2c66affSColin Finck     hr = execute_view( query->view );
859c2c66affSColin Finck     if (hr != S_OK) goto done;
860c2c66affSColin Finck 
861c2c66affSColin Finck     hr = EnumWbemClassObject_create( query, (void **)&result );
862c2c66affSColin Finck     if (hr != S_OK) goto done;
863c2c66affSColin Finck 
864*628f4c99SAmine Khaldi     table = get_view_table( query->view, 0 );
865*628f4c99SAmine Khaldi     hr = create_class_object( table->name, result, 0, NULL, &obj );
866c2c66affSColin Finck     if (hr != S_OK) goto done;
867c2c66affSColin Finck 
868*628f4c99SAmine Khaldi     hr = get_method( table, strMethodName, &func );
869c2c66affSColin Finck     if (hr != S_OK) goto done;
870c2c66affSColin Finck 
871c2c66affSColin Finck     hr = func( obj, pInParams, ppOutParams );
872c2c66affSColin Finck 
873c2c66affSColin Finck done:
874c2c66affSColin Finck     if (result) IEnumWbemClassObject_Release( result );
875c2c66affSColin Finck     if (obj) IWbemClassObject_Release( obj );
876c2c66affSColin Finck     free_query( query );
877c2c66affSColin Finck     free_path( path );
878c2c66affSColin Finck     heap_free( str );
879c2c66affSColin Finck     return hr;
880c2c66affSColin Finck }
881c2c66affSColin Finck 
wbem_services_ExecMethodAsync(IWbemServices * iface,const BSTR strObjectPath,const BSTR strMethodName,LONG lFlags,IWbemContext * pCtx,IWbemClassObject * pInParams,IWbemObjectSink * pResponseHandler)882c2c66affSColin Finck static HRESULT WINAPI wbem_services_ExecMethodAsync(
883c2c66affSColin Finck     IWbemServices *iface,
884c2c66affSColin Finck     const BSTR strObjectPath,
885c2c66affSColin Finck     const BSTR strMethodName,
886c2c66affSColin Finck     LONG lFlags,
887c2c66affSColin Finck     IWbemContext *pCtx,
888c2c66affSColin Finck     IWbemClassObject *pInParams,
889c2c66affSColin Finck     IWbemObjectSink *pResponseHandler )
890c2c66affSColin Finck {
891c2c66affSColin Finck     FIXME("\n");
892c2c66affSColin Finck     return WBEM_E_FAILED;
893c2c66affSColin Finck }
894c2c66affSColin Finck 
895c2c66affSColin Finck static const IWbemServicesVtbl wbem_services_vtbl =
896c2c66affSColin Finck {
897c2c66affSColin Finck     wbem_services_QueryInterface,
898c2c66affSColin Finck     wbem_services_AddRef,
899c2c66affSColin Finck     wbem_services_Release,
900c2c66affSColin Finck     wbem_services_OpenNamespace,
901c2c66affSColin Finck     wbem_services_CancelAsyncCall,
902c2c66affSColin Finck     wbem_services_QueryObjectSink,
903c2c66affSColin Finck     wbem_services_GetObject,
904c2c66affSColin Finck     wbem_services_GetObjectAsync,
905c2c66affSColin Finck     wbem_services_PutClass,
906c2c66affSColin Finck     wbem_services_PutClassAsync,
907c2c66affSColin Finck     wbem_services_DeleteClass,
908c2c66affSColin Finck     wbem_services_DeleteClassAsync,
909c2c66affSColin Finck     wbem_services_CreateClassEnum,
910c2c66affSColin Finck     wbem_services_CreateClassEnumAsync,
911c2c66affSColin Finck     wbem_services_PutInstance,
912c2c66affSColin Finck     wbem_services_PutInstanceAsync,
913c2c66affSColin Finck     wbem_services_DeleteInstance,
914c2c66affSColin Finck     wbem_services_DeleteInstanceAsync,
915c2c66affSColin Finck     wbem_services_CreateInstanceEnum,
916c2c66affSColin Finck     wbem_services_CreateInstanceEnumAsync,
917c2c66affSColin Finck     wbem_services_ExecQuery,
918c2c66affSColin Finck     wbem_services_ExecQueryAsync,
919c2c66affSColin Finck     wbem_services_ExecNotificationQuery,
920c2c66affSColin Finck     wbem_services_ExecNotificationQueryAsync,
921c2c66affSColin Finck     wbem_services_ExecMethod,
922c2c66affSColin Finck     wbem_services_ExecMethodAsync
923c2c66affSColin Finck };
924c2c66affSColin Finck 
WbemServices_create(const WCHAR * namespace,LPVOID * ppObj)925c2c66affSColin Finck HRESULT WbemServices_create( const WCHAR *namespace, LPVOID *ppObj )
926c2c66affSColin Finck {
927c2c66affSColin Finck     struct wbem_services *ws;
928c2c66affSColin Finck 
929c2c66affSColin Finck     TRACE("(%p)\n", ppObj);
930c2c66affSColin Finck 
931c2c66affSColin Finck     ws = heap_alloc( sizeof(*ws) );
932c2c66affSColin Finck     if (!ws) return E_OUTOFMEMORY;
933c2c66affSColin Finck 
934c2c66affSColin Finck     ws->IWbemServices_iface.lpVtbl = &wbem_services_vtbl;
935c2c66affSColin Finck     ws->refs      = 1;
936c2c66affSColin Finck     ws->namespace = heap_strdupW( namespace );
937c2c66affSColin Finck     ws->async     = NULL;
938c2c66affSColin Finck     InitializeCriticalSection( &ws->cs );
939c2c66affSColin Finck     ws->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wbemprox_services.cs");
940c2c66affSColin Finck 
941c2c66affSColin Finck     *ppObj = &ws->IWbemServices_iface;
942c2c66affSColin Finck 
943c2c66affSColin Finck     TRACE("returning iface %p\n", *ppObj);
944c2c66affSColin Finck     return S_OK;
945c2c66affSColin Finck }
946