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