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
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
,
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
) )
59 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
62 IClientSecurity_AddRef( iface
);
66 static ULONG WINAPI
client_security_AddRef(
67 IClientSecurity
*iface
)
73 static ULONG WINAPI
client_security_Release(
74 IClientSecurity
*iface
)
80 static HRESULT WINAPI
client_security_QueryBlanket(
81 IClientSecurity
*iface
,
85 OLECHAR
**pServerPrincName
,
89 DWORD
*pCapabilities
)
91 FIXME("semi-stub.\n");
94 *pAuthnSvc
= RPC_C_AUTHN_NONE
;
96 *pAuthzSvc
= RPC_C_AUTHZ_NONE
;
98 *pServerPrincName
= NULL
;
100 *pAuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
102 *pImpLevel
= RPC_C_IMP_LEVEL_DEFAULT
;
108 return WBEM_NO_ERROR
;
111 static HRESULT WINAPI
client_security_SetBlanket(
112 IClientSecurity
*iface
,
116 OLECHAR
*pServerPrincName
,
122 const OLECHAR
*princname
= (pServerPrincName
== COLE_DEFAULT_PRINCIPAL
) ?
123 L
"<COLE_DEFAULT_PRINCIPAL>" : pServerPrincName
;
125 FIXME("%p, %p, %u, %u, %s, %u, %u, %p, 0x%08x\n", iface
, pProxy
, AuthnSvc
, AuthzSvc
,
126 debugstr_w(princname
), AuthnLevel
, ImpLevel
, pAuthInfo
, Capabilities
);
127 return WBEM_NO_ERROR
;
130 static HRESULT WINAPI
client_security_CopyProxy(
131 IClientSecurity
*iface
,
136 return WBEM_E_FAILED
;
139 static const IClientSecurityVtbl client_security_vtbl
=
141 client_security_QueryInterface
,
142 client_security_AddRef
,
143 client_security_Release
,
144 client_security_QueryBlanket
,
145 client_security_SetBlanket
,
146 client_security_CopyProxy
149 IClientSecurity client_security
= { &client_security_vtbl
};
153 IWbemObjectSink
*sink
;
154 void (*proc
)( struct async_header
* );
161 struct async_header hdr
;
165 static void free_async( struct async_header
*async
)
167 if (async
->sink
) IWbemObjectSink_Release( async
->sink
);
168 CloseHandle( async
->cancel
);
169 CloseHandle( async
->wait
);
173 static BOOL
init_async( struct async_header
*async
, IWbemObjectSink
*sink
,
174 void (*proc
)(struct async_header
*) )
176 if (!(async
->wait
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
))) return FALSE
;
177 if (!(async
->cancel
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
)))
179 CloseHandle( async
->wait
);
184 IWbemObjectSink_AddRef( sink
);
188 static DWORD CALLBACK
async_proc( LPVOID param
)
190 struct async_header
*async
= param
;
191 HANDLE wait
= async
->wait
;
193 async
->proc( async
);
195 WaitForSingleObject( async
->cancel
, INFINITE
);
197 return ERROR_SUCCESS
;
200 static HRESULT
queue_async( struct async_header
*async
)
202 if (QueueUserWorkItem( async_proc
, async
, WT_EXECUTELONGFUNCTION
)) return S_OK
;
203 return HRESULT_FROM_WIN32( GetLastError() );
208 IWbemServices IWbemServices_iface
;
212 struct async_header
*async
;
213 IWbemContext
*context
;
216 static inline struct wbem_services
*impl_from_IWbemServices( IWbemServices
*iface
)
218 return CONTAINING_RECORD( iface
, struct wbem_services
, IWbemServices_iface
);
221 static ULONG WINAPI
wbem_services_AddRef(
222 IWbemServices
*iface
)
224 struct wbem_services
*ws
= impl_from_IWbemServices( iface
);
225 return InterlockedIncrement( &ws
->refs
);
228 static ULONG WINAPI
wbem_services_Release(
229 IWbemServices
*iface
)
231 struct wbem_services
*ws
= impl_from_IWbemServices( iface
);
232 LONG refs
= InterlockedDecrement( &ws
->refs
);
235 TRACE("destroying %p\n", ws
);
237 EnterCriticalSection( &ws
->cs
);
238 if (ws
->async
) SetEvent( ws
->async
->cancel
);
239 LeaveCriticalSection( &ws
->cs
);
242 WaitForSingleObject( ws
->async
->wait
, INFINITE
);
243 free_async( ws
->async
);
245 ws
->cs
.DebugInfo
->Spare
[0] = 0;
246 DeleteCriticalSection( &ws
->cs
);
248 IWbemContext_Release( ws
->context
);
249 heap_free( ws
->namespace );
255 static HRESULT WINAPI
wbem_services_QueryInterface(
256 IWbemServices
*iface
,
260 struct wbem_services
*ws
= impl_from_IWbemServices( iface
);
262 TRACE("%p %s %p\n", ws
, debugstr_guid( riid
), ppvObject
);
264 if ( IsEqualGUID( riid
, &IID_IWbemServices
) ||
265 IsEqualGUID( riid
, &IID_IUnknown
) )
269 else if ( IsEqualGUID( riid
, &IID_IClientSecurity
) )
271 *ppvObject
= &client_security
;
276 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
277 return E_NOINTERFACE
;
279 IWbemServices_AddRef( iface
);
283 static HRESULT WINAPI
wbem_services_OpenNamespace(
284 IWbemServices
*iface
,
285 const BSTR strNamespace
,
288 IWbemServices
**ppWorkingNamespace
,
289 IWbemCallResult
**ppResult
)
291 struct wbem_services
*ws
= impl_from_IWbemServices( iface
);
293 TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface
, debugstr_w(strNamespace
), lFlags
,
294 pCtx
, ppWorkingNamespace
, ppResult
);
296 if ((wcsicmp( strNamespace
, L
"cimv2" ) && wcsicmp( strNamespace
, L
"default" )) || ws
->namespace)
297 return WBEM_E_INVALID_NAMESPACE
;
299 return WbemServices_create( L
"cimv2", NULL
, (void **)ppWorkingNamespace
);
302 static HRESULT WINAPI
wbem_services_CancelAsyncCall(
303 IWbemServices
*iface
,
304 IWbemObjectSink
*pSink
)
306 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
307 struct async_header
*async
;
309 TRACE("%p, %p\n", iface
, pSink
);
311 if (!pSink
) return WBEM_E_INVALID_PARAMETER
;
313 EnterCriticalSection( &services
->cs
);
315 if (!(async
= services
->async
))
317 LeaveCriticalSection( &services
->cs
);
318 return WBEM_E_INVALID_PARAMETER
;
320 services
->async
= NULL
;
321 SetEvent( async
->cancel
);
323 LeaveCriticalSection( &services
->cs
);
325 WaitForSingleObject( async
->wait
, INFINITE
);
330 static HRESULT WINAPI
wbem_services_QueryObjectSink(
331 IWbemServices
*iface
,
333 IWbemObjectSink
**ppResponseHandler
)
336 return WBEM_E_FAILED
;
339 HRESULT
parse_path( const WCHAR
*str
, struct path
**ret
)
342 const WCHAR
*p
= str
, *q
;
345 if (!(path
= heap_alloc_zero( sizeof(*path
) ))) return E_OUTOFMEMORY
;
349 static const WCHAR cimv2W
[] = L
"ROOT\\CIMV2";
350 WCHAR server
[MAX_COMPUTERNAME_LENGTH
+1];
351 DWORD server_len
= ARRAY_SIZE(server
);
357 return WBEM_E_INVALID_OBJECT_PATH
;
362 while (*p
&& *p
!= '\\') p
++;
366 return WBEM_E_INVALID_OBJECT_PATH
;
370 if (!GetComputerNameW( server
, &server_len
) || server_len
!= len
|| wcsnicmp( q
, server
, server_len
))
373 return WBEM_E_NOT_SUPPORTED
;
377 while (*p
&& *p
!= ':') p
++;
381 return WBEM_E_INVALID_OBJECT_PATH
;
385 if (len
!= ARRAY_SIZE(cimv2W
) - 1 || wcsnicmp( q
, cimv2W
, ARRAY_SIZE(cimv2W
) - 1 ))
388 return WBEM_E_INVALID_NAMESPACE
;
394 while (*p
&& *p
!= '.') p
++;
397 if (!(path
->class = heap_alloc( (len
+ 1) * sizeof(WCHAR
) )))
400 return E_OUTOFMEMORY
;
402 memcpy( path
->class, q
, len
* sizeof(WCHAR
) );
403 path
->class[len
] = 0;
404 path
->class_len
= len
;
406 if (p
[0] == '.' && p
[1])
412 if (!(path
->filter
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) )))
414 heap_free( path
->class );
416 return E_OUTOFMEMORY
;
418 memcpy( path
->filter
, p
, len
* sizeof(WCHAR
) );
419 path
->filter
[len
] = 0;
420 path
->filter_len
= len
;
426 void free_path( struct path
*path
)
429 heap_free( path
->class );
430 heap_free( path
->filter
);
434 WCHAR
*query_from_path( const struct path
*path
)
436 static const WCHAR selectW
[] = L
"SELECT * FROM %s WHERE %s";
437 static const WCHAR select_allW
[] = L
"SELECT * FROM ";
443 len
= path
->class_len
+ path
->filter_len
+ ARRAY_SIZE(selectW
);
444 if (!(query
= heap_alloc( len
* sizeof(WCHAR
) ))) return NULL
;
445 swprintf( query
, len
, selectW
, path
->class, path
->filter
);
449 len
= path
->class_len
+ ARRAY_SIZE(select_allW
);
450 if (!(query
= heap_alloc( len
* sizeof(WCHAR
) ))) return NULL
;
451 lstrcpyW( query
, select_allW
);
452 lstrcatW( query
, path
->class );
457 static HRESULT
create_instance_enum( const struct path
*path
, IEnumWbemClassObject
**iter
)
462 if (!(query
= query_from_path( path
))) return E_OUTOFMEMORY
;
463 hr
= exec_query( query
, iter
);
468 HRESULT
get_object( const WCHAR
*object_path
, IWbemClassObject
**obj
)
470 IEnumWbemClassObject
*iter
;
475 hr
= parse_path( object_path
, &path
);
476 if (hr
!= S_OK
) return hr
;
478 hr
= create_instance_enum( path
, &iter
);
484 hr
= IEnumWbemClassObject_Next( iter
, WBEM_INFINITE
, 1, obj
, &count
);
485 if (hr
== WBEM_S_FALSE
)
487 hr
= WBEM_E_NOT_FOUND
;
490 IEnumWbemClassObject_Release( iter
);
495 static HRESULT WINAPI
wbem_services_GetObject(
496 IWbemServices
*iface
,
497 const BSTR strObjectPath
,
500 IWbemClassObject
**ppObject
,
501 IWbemCallResult
**ppCallResult
)
503 TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface
, debugstr_w(strObjectPath
), lFlags
,
504 pCtx
, ppObject
, ppCallResult
);
506 if (lFlags
) FIXME("unsupported flags 0x%08x\n", lFlags
);
508 if (!strObjectPath
|| !strObjectPath
[0])
509 return create_class_object( NULL
, NULL
, 0, NULL
, ppObject
);
511 return get_object( strObjectPath
, ppObject
);
514 static HRESULT WINAPI
wbem_services_GetObjectAsync(
515 IWbemServices
*iface
,
516 const BSTR strObjectPath
,
519 IWbemObjectSink
*pResponseHandler
)
522 return WBEM_E_FAILED
;
525 static HRESULT WINAPI
wbem_services_PutClass(
526 IWbemServices
*iface
,
527 IWbemClassObject
*pObject
,
530 IWbemCallResult
**ppCallResult
)
533 return WBEM_E_FAILED
;
536 static HRESULT WINAPI
wbem_services_PutClassAsync(
537 IWbemServices
*iface
,
538 IWbemClassObject
*pObject
,
541 IWbemObjectSink
*pResponseHandler
)
544 return WBEM_E_FAILED
;
547 static HRESULT WINAPI
wbem_services_DeleteClass(
548 IWbemServices
*iface
,
552 IWbemCallResult
**ppCallResult
)
555 return WBEM_E_FAILED
;
558 static HRESULT WINAPI
wbem_services_DeleteClassAsync(
559 IWbemServices
*iface
,
563 IWbemObjectSink
*pResponseHandler
)
566 return WBEM_E_FAILED
;
569 static HRESULT WINAPI
wbem_services_CreateClassEnum(
570 IWbemServices
*iface
,
571 const BSTR strSuperclass
,
574 IEnumWbemClassObject
**ppEnum
)
577 return WBEM_E_FAILED
;
580 static HRESULT WINAPI
wbem_services_CreateClassEnumAsync(
581 IWbemServices
*iface
,
582 const BSTR strSuperclass
,
585 IWbemObjectSink
*pResponseHandler
)
588 return WBEM_E_FAILED
;
591 static HRESULT WINAPI
wbem_services_PutInstance(
592 IWbemServices
*iface
,
593 IWbemClassObject
*pInst
,
596 IWbemCallResult
**ppCallResult
)
599 return WBEM_E_FAILED
;
602 static HRESULT WINAPI
wbem_services_PutInstanceAsync(
603 IWbemServices
*iface
,
604 IWbemClassObject
*pInst
,
607 IWbemObjectSink
*pResponseHandler
)
610 return WBEM_E_FAILED
;
613 static HRESULT WINAPI
wbem_services_DeleteInstance(
614 IWbemServices
*iface
,
615 const BSTR strObjectPath
,
618 IWbemCallResult
**ppCallResult
)
621 return WBEM_E_FAILED
;
624 static HRESULT WINAPI
wbem_services_DeleteInstanceAsync(
625 IWbemServices
*iface
,
626 const BSTR strObjectPath
,
629 IWbemObjectSink
*pResponseHandler
)
632 return WBEM_E_FAILED
;
635 static HRESULT WINAPI
wbem_services_CreateInstanceEnum(
636 IWbemServices
*iface
,
640 IEnumWbemClassObject
**ppEnum
)
645 TRACE("%p, %s, 0%08x, %p, %p\n", iface
, debugstr_w(strClass
), lFlags
, pCtx
, ppEnum
);
647 if (lFlags
) FIXME("unsupported flags 0x%08x\n", lFlags
);
649 hr
= parse_path( strClass
, &path
);
650 if (hr
!= S_OK
) return hr
;
652 hr
= create_instance_enum( path
, ppEnum
);
657 static HRESULT WINAPI
wbem_services_CreateInstanceEnumAsync(
658 IWbemServices
*iface
,
659 const BSTR strFilter
,
662 IWbemObjectSink
*pResponseHandler
)
665 return WBEM_E_FAILED
;
668 static HRESULT WINAPI
wbem_services_ExecQuery(
669 IWbemServices
*iface
,
670 const BSTR strQueryLanguage
,
674 IEnumWbemClassObject
**ppEnum
)
676 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface
, debugstr_w(strQueryLanguage
),
677 debugstr_w(strQuery
), lFlags
, pCtx
, ppEnum
);
679 if (!strQueryLanguage
|| !strQuery
|| !strQuery
[0]) return WBEM_E_INVALID_PARAMETER
;
680 if (wcsicmp( strQueryLanguage
, L
"WQL" )) return WBEM_E_INVALID_QUERY_TYPE
;
681 return exec_query( strQuery
, ppEnum
);
684 static void async_exec_query( struct async_header
*hdr
)
686 struct async_query
*query
= (struct async_query
*)hdr
;
687 IEnumWbemClassObject
*result
;
688 IWbemClassObject
*obj
;
692 hr
= exec_query( query
->str
, &result
);
697 IEnumWbemClassObject_Next( result
, WBEM_INFINITE
, 1, &obj
, &count
);
699 IWbemObjectSink_Indicate( query
->hdr
.sink
, 1, &obj
);
700 IWbemClassObject_Release( obj
);
702 IEnumWbemClassObject_Release( result
);
704 IWbemObjectSink_SetStatus( query
->hdr
.sink
, WBEM_STATUS_COMPLETE
, hr
, NULL
, NULL
);
705 heap_free( query
->str
);
708 static HRESULT WINAPI
wbem_services_ExecQueryAsync(
709 IWbemServices
*iface
,
710 const BSTR strQueryLanguage
,
714 IWbemObjectSink
*pResponseHandler
)
716 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
717 IWbemObjectSink
*sink
;
718 HRESULT hr
= E_OUTOFMEMORY
;
719 struct async_header
*async
;
720 struct async_query
*query
;
722 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface
, debugstr_w(strQueryLanguage
), debugstr_w(strQuery
),
723 lFlags
, pCtx
, pResponseHandler
);
725 if (!pResponseHandler
) return WBEM_E_INVALID_PARAMETER
;
727 hr
= IWbemObjectSink_QueryInterface( pResponseHandler
, &IID_IWbemObjectSink
, (void **)&sink
);
728 if (FAILED(hr
)) return hr
;
730 EnterCriticalSection( &services
->cs
);
734 FIXME("handle more than one pending async\n");
738 if (!(query
= heap_alloc_zero( sizeof(*query
) ))) goto done
;
739 async
= (struct async_header
*)query
;
741 if (!(init_async( async
, sink
, async_exec_query
)))
746 if (!(query
->str
= heap_strdupW( strQuery
)))
751 hr
= queue_async( async
);
752 if (hr
== S_OK
) services
->async
= async
;
755 heap_free( query
->str
);
760 LeaveCriticalSection( &services
->cs
);
761 IWbemObjectSink_Release( sink
);
765 static HRESULT WINAPI
wbem_services_ExecNotificationQuery(
766 IWbemServices
*iface
,
767 const BSTR strQueryLanguage
,
771 IEnumWbemClassObject
**ppEnum
)
774 return WBEM_E_FAILED
;
777 static HRESULT WINAPI
wbem_services_ExecNotificationQueryAsync(
778 IWbemServices
*iface
,
779 const BSTR strQueryLanguage
,
783 IWbemObjectSink
*pResponseHandler
)
785 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
786 IWbemObjectSink
*sink
;
787 HRESULT hr
= E_OUTOFMEMORY
;
788 struct async_header
*async
;
789 struct async_query
*query
;
791 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface
, debugstr_w(strQueryLanguage
), debugstr_w(strQuery
),
792 lFlags
, pCtx
, pResponseHandler
);
794 if (!pResponseHandler
) return WBEM_E_INVALID_PARAMETER
;
796 hr
= IWbemObjectSink_QueryInterface( pResponseHandler
, &IID_IWbemObjectSink
, (void **)&sink
);
797 if (FAILED(hr
)) return hr
;
799 EnterCriticalSection( &services
->cs
);
803 FIXME("handle more than one pending async\n");
807 if (!(query
= heap_alloc_zero( sizeof(*query
) ))) goto done
;
808 async
= (struct async_header
*)query
;
810 if (!(init_async( async
, sink
, async_exec_query
)))
815 if (!(query
->str
= heap_strdupW( strQuery
)))
820 hr
= queue_async( async
);
821 if (hr
== S_OK
) services
->async
= async
;
824 heap_free( query
->str
);
829 LeaveCriticalSection( &services
->cs
);
830 IWbemObjectSink_Release( sink
);
834 static HRESULT WINAPI
wbem_services_ExecMethod(
835 IWbemServices
*iface
,
836 const BSTR strObjectPath
,
837 const BSTR strMethodName
,
839 IWbemContext
*context
,
840 IWbemClassObject
*pInParams
,
841 IWbemClassObject
**ppOutParams
,
842 IWbemCallResult
**ppCallResult
)
844 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
845 IEnumWbemClassObject
*result
= NULL
;
846 IWbemClassObject
*obj
= NULL
;
847 struct query
*query
= NULL
;
854 TRACE("%p, %s, %s, %08x, %p, %p, %p, %p\n", iface
, debugstr_w(strObjectPath
),
855 debugstr_w(strMethodName
), lFlags
, context
, pInParams
, ppOutParams
, ppCallResult
);
857 if (lFlags
) FIXME("flags %08x not supported\n", lFlags
);
859 if ((hr
= parse_path( strObjectPath
, &path
)) != S_OK
) return hr
;
860 if (!(str
= query_from_path( path
)))
865 if (!(query
= create_query()))
870 hr
= parse_query( str
, &query
->view
, &query
->mem
);
871 if (hr
!= S_OK
) goto done
;
873 hr
= execute_view( query
->view
);
874 if (hr
!= S_OK
) goto done
;
876 hr
= EnumWbemClassObject_create( query
, (void **)&result
);
877 if (hr
!= S_OK
) goto done
;
879 table
= get_view_table( query
->view
, 0 );
880 hr
= create_class_object( table
->name
, result
, 0, NULL
, &obj
);
881 if (hr
!= S_OK
) goto done
;
883 hr
= get_method( table
, strMethodName
, &func
);
884 if (hr
!= S_OK
) goto done
;
886 hr
= func( obj
, context
? context
: services
->context
, pInParams
, ppOutParams
);
889 if (result
) IEnumWbemClassObject_Release( result
);
890 if (obj
) IWbemClassObject_Release( obj
);
897 static HRESULT WINAPI
wbem_services_ExecMethodAsync(
898 IWbemServices
*iface
,
899 const BSTR strObjectPath
,
900 const BSTR strMethodName
,
903 IWbemClassObject
*pInParams
,
904 IWbemObjectSink
*pResponseHandler
)
907 return WBEM_E_FAILED
;
910 static const IWbemServicesVtbl wbem_services_vtbl
=
912 wbem_services_QueryInterface
,
913 wbem_services_AddRef
,
914 wbem_services_Release
,
915 wbem_services_OpenNamespace
,
916 wbem_services_CancelAsyncCall
,
917 wbem_services_QueryObjectSink
,
918 wbem_services_GetObject
,
919 wbem_services_GetObjectAsync
,
920 wbem_services_PutClass
,
921 wbem_services_PutClassAsync
,
922 wbem_services_DeleteClass
,
923 wbem_services_DeleteClassAsync
,
924 wbem_services_CreateClassEnum
,
925 wbem_services_CreateClassEnumAsync
,
926 wbem_services_PutInstance
,
927 wbem_services_PutInstanceAsync
,
928 wbem_services_DeleteInstance
,
929 wbem_services_DeleteInstanceAsync
,
930 wbem_services_CreateInstanceEnum
,
931 wbem_services_CreateInstanceEnumAsync
,
932 wbem_services_ExecQuery
,
933 wbem_services_ExecQueryAsync
,
934 wbem_services_ExecNotificationQuery
,
935 wbem_services_ExecNotificationQueryAsync
,
936 wbem_services_ExecMethod
,
937 wbem_services_ExecMethodAsync
940 HRESULT
WbemServices_create( const WCHAR
*namespace, IWbemContext
*context
, LPVOID
*ppObj
)
942 struct wbem_services
*ws
;
944 TRACE("(%p)\n", ppObj
);
946 ws
= heap_alloc_zero( sizeof(*ws
) );
947 if (!ws
) return E_OUTOFMEMORY
;
949 ws
->IWbemServices_iface
.lpVtbl
= &wbem_services_vtbl
;
951 ws
->namespace = heap_strdupW( namespace );
952 InitializeCriticalSection( &ws
->cs
);
953 ws
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": wbemprox_services.cs");
955 IWbemContext_Clone( context
, &ws
->context
);
957 *ppObj
= &ws
->IWbemServices_iface
;
959 TRACE("returning iface %p\n", *ppObj
);
963 struct wbem_context_value
972 IWbemContext IWbemContext_iface
;
977 static void wbem_context_delete_values(struct wbem_context
*context
)
979 struct wbem_context_value
*value
, *next
;
981 LIST_FOR_EACH_ENTRY_SAFE(value
, next
, &context
->values
, struct wbem_context_value
, entry
)
983 list_remove( &value
->entry
);
984 VariantClear( &value
->value
);
985 heap_free( value
->name
);
990 static struct wbem_context
*impl_from_IWbemContext( IWbemContext
*iface
)
992 return CONTAINING_RECORD( iface
, struct wbem_context
, IWbemContext_iface
);
995 static HRESULT WINAPI
wbem_context_QueryInterface(
1000 TRACE("%p, %s, %p\n", iface
, debugstr_guid( riid
), obj
);
1002 if ( IsEqualGUID( riid
, &IID_IWbemContext
) ||
1003 IsEqualGUID( riid
, &IID_IUnknown
) )
1009 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
1010 return E_NOINTERFACE
;
1013 IWbemContext_AddRef( iface
);
1017 static ULONG WINAPI
wbem_context_AddRef(
1018 IWbemContext
*iface
)
1020 struct wbem_context
*context
= impl_from_IWbemContext( iface
);
1021 return InterlockedIncrement( &context
->refs
);
1024 static ULONG WINAPI
wbem_context_Release(
1025 IWbemContext
*iface
)
1027 struct wbem_context
*context
= impl_from_IWbemContext( iface
);
1028 LONG refs
= InterlockedDecrement( &context
->refs
);
1032 TRACE("destroying %p\n", context
);
1033 wbem_context_delete_values( context
);
1034 heap_free( context
);
1039 static HRESULT WINAPI
wbem_context_Clone(
1040 IWbemContext
*iface
,
1041 IWbemContext
**newcopy
)
1043 struct wbem_context
*context
= impl_from_IWbemContext( iface
);
1044 struct wbem_context_value
*value
;
1045 IWbemContext
*cloned_context
;
1048 TRACE("%p, %p\n", iface
, newcopy
);
1050 if (SUCCEEDED(hr
= WbemContext_create( (void **)&cloned_context
)))
1052 LIST_FOR_EACH_ENTRY( value
, &context
->values
, struct wbem_context_value
, entry
)
1054 if (FAILED(hr
= IWbemContext_SetValue( cloned_context
, value
->name
, 0, &value
->value
))) break;
1060 *newcopy
= cloned_context
;
1065 IWbemContext_Release( cloned_context
);
1071 static HRESULT WINAPI
wbem_context_GetNames(
1072 IWbemContext
*iface
,
1076 FIXME("%p, %#x, %p\n", iface
, flags
, names
);
1081 static HRESULT WINAPI
wbem_context_BeginEnumeration(
1082 IWbemContext
*iface
,
1085 FIXME("%p, %#x\n", iface
, flags
);
1090 static HRESULT WINAPI
wbem_context_Next(
1091 IWbemContext
*iface
,
1096 FIXME("%p, %#x, %p, %p\n", iface
, flags
, name
, value
);
1101 static HRESULT WINAPI
wbem_context_EndEnumeration(
1102 IWbemContext
*iface
)
1104 FIXME("%p\n", iface
);
1109 static struct wbem_context_value
*wbem_context_get_value( struct wbem_context
*context
, const WCHAR
*name
)
1111 struct wbem_context_value
*value
;
1113 LIST_FOR_EACH_ENTRY( value
, &context
->values
, struct wbem_context_value
, entry
)
1115 if (!lstrcmpiW( value
->name
, name
)) return value
;
1121 static HRESULT WINAPI
wbem_context_SetValue(
1122 IWbemContext
*iface
,
1127 struct wbem_context
*context
= impl_from_IWbemContext( iface
);
1128 struct wbem_context_value
*value
;
1131 TRACE("%p, %s, %#x, %s\n", iface
, debugstr_w(name
), flags
, debugstr_variant(var
));
1134 return WBEM_E_INVALID_PARAMETER
;
1136 if ((value
= wbem_context_get_value( context
, name
)))
1138 VariantClear( &value
->value
);
1139 hr
= VariantCopy( &value
->value
, var
);
1143 if (!(value
= heap_alloc_zero( sizeof(*value
) ))) return E_OUTOFMEMORY
;
1144 if (!(value
->name
= heap_strdupW( name
)))
1147 return E_OUTOFMEMORY
;
1149 if (FAILED(hr
= VariantCopy( &value
->value
, var
)))
1151 heap_free( value
->name
);
1156 list_add_tail( &context
->values
, &value
->entry
);
1162 static HRESULT WINAPI
wbem_context_GetValue(
1163 IWbemContext
*iface
,
1168 struct wbem_context
*context
= impl_from_IWbemContext( iface
);
1169 struct wbem_context_value
*value
;
1171 TRACE("%p, %s, %#x, %p\n", iface
, debugstr_w(name
), flags
, var
);
1174 return WBEM_E_INVALID_PARAMETER
;
1176 if (!(value
= wbem_context_get_value( context
, name
)))
1177 return WBEM_E_NOT_FOUND
;
1179 V_VT(var
) = VT_EMPTY
;
1180 return VariantCopy( var
, &value
->value
);
1183 static HRESULT WINAPI
wbem_context_DeleteValue(
1184 IWbemContext
*iface
,
1188 FIXME("%p, %s, %#x\n", iface
, debugstr_w(name
), flags
);
1193 static HRESULT WINAPI
wbem_context_DeleteAll(
1194 IWbemContext
*iface
)
1196 FIXME("%p\n", iface
);
1201 static const IWbemContextVtbl wbem_context_vtbl
=
1203 wbem_context_QueryInterface
,
1204 wbem_context_AddRef
,
1205 wbem_context_Release
,
1207 wbem_context_GetNames
,
1208 wbem_context_BeginEnumeration
,
1210 wbem_context_EndEnumeration
,
1211 wbem_context_SetValue
,
1212 wbem_context_GetValue
,
1213 wbem_context_DeleteValue
,
1214 wbem_context_DeleteAll
,
1217 HRESULT
WbemContext_create( void **obj
)
1219 struct wbem_context
*context
;
1221 TRACE("(%p)\n", obj
);
1223 context
= heap_alloc( sizeof(*context
) );
1224 if (!context
) return E_OUTOFMEMORY
;
1226 context
->IWbemContext_iface
.lpVtbl
= &wbem_context_vtbl
;
1228 list_init(&context
->values
);
1230 *obj
= &context
->IWbemContext_iface
;
1232 TRACE("returning iface %p\n", *obj
);