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
) )
55 *ppvObject
= &cs
->IClientSecurity_iface
;
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, %lu, %lu, %s, %lu, %lu, %p, %#lx\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
;
162 enum wbm_namespace ns
;
166 static void free_async( struct async_header
*async
)
168 if (async
->sink
) IWbemObjectSink_Release( async
->sink
);
169 CloseHandle( async
->cancel
);
170 CloseHandle( async
->wait
);
174 static BOOL
init_async( struct async_header
*async
, IWbemObjectSink
*sink
,
175 void (*proc
)(struct async_header
*) )
177 if (!(async
->wait
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
))) return FALSE
;
178 if (!(async
->cancel
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
)))
180 CloseHandle( async
->wait
);
185 IWbemObjectSink_AddRef( sink
);
189 static DWORD CALLBACK
async_proc( LPVOID param
)
191 struct async_header
*async
= param
;
192 HANDLE wait
= async
->wait
;
194 async
->proc( async
);
196 WaitForSingleObject( async
->cancel
, INFINITE
);
198 return ERROR_SUCCESS
;
201 static HRESULT
queue_async( struct async_header
*async
)
203 if (QueueUserWorkItem( async_proc
, async
, WT_EXECUTELONGFUNCTION
)) return S_OK
;
204 return HRESULT_FROM_WIN32( GetLastError() );
209 IWbemServices IWbemServices_iface
;
212 enum wbm_namespace ns
;
213 struct async_header
*async
;
214 IWbemContext
*context
;
217 static inline struct wbem_services
*impl_from_IWbemServices( IWbemServices
*iface
)
219 return CONTAINING_RECORD( iface
, struct wbem_services
, IWbemServices_iface
);
222 static ULONG WINAPI
wbem_services_AddRef(
223 IWbemServices
*iface
)
225 struct wbem_services
*ws
= impl_from_IWbemServices( iface
);
226 return InterlockedIncrement( &ws
->refs
);
229 static ULONG WINAPI
wbem_services_Release(
230 IWbemServices
*iface
)
232 struct wbem_services
*ws
= impl_from_IWbemServices( iface
);
233 LONG refs
= InterlockedDecrement( &ws
->refs
);
236 TRACE("destroying %p\n", ws
);
238 EnterCriticalSection( &ws
->cs
);
239 if (ws
->async
) SetEvent( ws
->async
->cancel
);
240 LeaveCriticalSection( &ws
->cs
);
243 WaitForSingleObject( ws
->async
->wait
, INFINITE
);
244 free_async( ws
->async
);
246 ws
->cs
.DebugInfo
->Spare
[0] = 0;
247 DeleteCriticalSection( &ws
->cs
);
249 IWbemContext_Release( ws
->context
);
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
) )
267 *ppvObject
= &ws
->IWbemServices_iface
;
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, %#lx, %p, %p, %p\n", iface
, debugstr_w(strNamespace
), lFlags
,
294 pCtx
, ppWorkingNamespace
, ppResult
);
296 if (ws
->ns
!= WBEMPROX_NAMESPACE_LAST
|| !strNamespace
)
297 return WBEM_E_INVALID_NAMESPACE
;
299 return WbemServices_create( strNamespace
, 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 void free_path( struct path
*path
)
343 free( path
->filter
);
347 HRESULT
parse_path( const WCHAR
*str
, struct path
**ret
)
350 const WCHAR
*p
= str
, *q
;
353 if (!(path
= calloc( 1, sizeof(*path
) ))) return E_OUTOFMEMORY
;
357 static const WCHAR cimv2W
[] = L
"ROOT\\CIMV2";
358 WCHAR server
[MAX_COMPUTERNAME_LENGTH
+1];
359 DWORD server_len
= ARRAY_SIZE(server
);
365 return WBEM_E_INVALID_OBJECT_PATH
;
370 while (*p
&& *p
!= '\\') p
++;
374 return WBEM_E_INVALID_OBJECT_PATH
;
378 if (!GetComputerNameW( server
, &server_len
) || server_len
!= len
|| wcsnicmp( q
, server
, server_len
))
381 return WBEM_E_NOT_SUPPORTED
;
385 while (*p
&& *p
!= ':') p
++;
389 return WBEM_E_INVALID_OBJECT_PATH
;
393 if (len
!= ARRAY_SIZE(cimv2W
) - 1 || wcsnicmp( q
, cimv2W
, ARRAY_SIZE(cimv2W
) - 1 ))
396 return WBEM_E_INVALID_NAMESPACE
;
402 while (*p
&& *p
!= '.' && *p
!= '=') p
++;
405 if (!(path
->class = malloc( (len
+ 1) * sizeof(WCHAR
) )))
408 return E_OUTOFMEMORY
;
410 memcpy( path
->class, q
, len
* sizeof(WCHAR
) );
411 path
->class[len
] = 0;
412 path
->class_len
= len
;
414 if (p
[0] == '.' && p
[1])
420 if (!(path
->filter
= malloc( (len
+ 1) * sizeof(WCHAR
) )))
423 return E_OUTOFMEMORY
;
425 memcpy( path
->filter
, p
, len
* sizeof(WCHAR
) );
426 path
->filter
[len
] = 0;
427 path
->filter_len
= len
;
429 else if (p
[0] == '=' && p
[1])
437 if (!(key
= get_first_key_property( WBEMPROX_NAMESPACE_CIMV2
, path
->class )))
440 return WBEM_E_INVALID_OBJECT_PATH
;
442 len_key
= wcslen( key
);
444 if (!(path
->filter
= malloc( (len
+ len_key
+ 1) * sizeof(WCHAR
) )))
448 return E_OUTOFMEMORY
;
450 wcscpy( path
->filter
, key
);
451 memcpy( path
->filter
+ len_key
, p
, len
* sizeof(WCHAR
) );
452 path
->filter_len
= len
+ len_key
;
453 path
->filter
[path
->filter_len
] = 0;
459 return WBEM_E_INVALID_OBJECT_PATH
;
466 WCHAR
*query_from_path( const struct path
*path
)
468 static const WCHAR selectW
[] = L
"SELECT * FROM %s WHERE %s";
469 static const WCHAR select_allW
[] = L
"SELECT * FROM ";
475 len
= path
->class_len
+ path
->filter_len
+ ARRAY_SIZE(selectW
);
476 if (!(query
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
477 swprintf( query
, len
, selectW
, path
->class, path
->filter
);
481 len
= path
->class_len
+ ARRAY_SIZE(select_allW
);
482 if (!(query
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
483 lstrcpyW( query
, select_allW
);
484 lstrcatW( query
, path
->class );
489 static HRESULT
create_instance_enum( enum wbm_namespace ns
, const struct path
*path
, IEnumWbemClassObject
**iter
)
494 if (!(query
= query_from_path( path
))) return E_OUTOFMEMORY
;
495 hr
= exec_query( ns
, query
, iter
);
500 HRESULT
get_object( enum wbm_namespace ns
, const WCHAR
*object_path
, IWbemClassObject
**obj
)
502 IEnumWbemClassObject
*iter
;
507 hr
= parse_path( object_path
, &path
);
508 if (hr
!= S_OK
) return hr
;
510 hr
= create_instance_enum( ns
, path
, &iter
);
516 hr
= IEnumWbemClassObject_Next( iter
, WBEM_INFINITE
, 1, obj
, &count
);
517 if (hr
== WBEM_S_FALSE
)
519 hr
= WBEM_E_NOT_FOUND
;
522 IEnumWbemClassObject_Release( iter
);
527 static HRESULT WINAPI
wbem_services_GetObject(
528 IWbemServices
*iface
,
529 const BSTR strObjectPath
,
532 IWbemClassObject
**ppObject
,
533 IWbemCallResult
**ppCallResult
)
535 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
537 TRACE( "%p, %s, %#lx, %p, %p, %p\n", iface
, debugstr_w(strObjectPath
), lFlags
,
538 pCtx
, ppObject
, ppCallResult
);
540 if (lFlags
) FIXME( "unsupported flags %#lx\n", lFlags
);
542 if (!strObjectPath
|| !strObjectPath
[0])
543 return create_class_object( services
->ns
, NULL
, NULL
, 0, NULL
, ppObject
);
545 return get_object( services
->ns
, strObjectPath
, ppObject
);
548 static HRESULT WINAPI
wbem_services_GetObjectAsync(
549 IWbemServices
*iface
,
550 const BSTR strObjectPath
,
553 IWbemObjectSink
*pResponseHandler
)
556 return WBEM_E_FAILED
;
559 static HRESULT WINAPI
wbem_services_PutClass(
560 IWbemServices
*iface
,
561 IWbemClassObject
*pObject
,
564 IWbemCallResult
**ppCallResult
)
567 return WBEM_E_FAILED
;
570 static HRESULT WINAPI
wbem_services_PutClassAsync(
571 IWbemServices
*iface
,
572 IWbemClassObject
*pObject
,
575 IWbemObjectSink
*pResponseHandler
)
578 return WBEM_E_FAILED
;
581 static HRESULT WINAPI
wbem_services_DeleteClass(
582 IWbemServices
*iface
,
586 IWbemCallResult
**ppCallResult
)
589 return WBEM_E_FAILED
;
592 static HRESULT WINAPI
wbem_services_DeleteClassAsync(
593 IWbemServices
*iface
,
597 IWbemObjectSink
*pResponseHandler
)
600 return WBEM_E_FAILED
;
603 static HRESULT WINAPI
wbem_services_CreateClassEnum(
604 IWbemServices
*iface
,
605 const BSTR strSuperclass
,
608 IEnumWbemClassObject
**ppEnum
)
611 return WBEM_E_FAILED
;
614 static HRESULT WINAPI
wbem_services_CreateClassEnumAsync(
615 IWbemServices
*iface
,
616 const BSTR strSuperclass
,
619 IWbemObjectSink
*pResponseHandler
)
622 return WBEM_E_FAILED
;
625 static HRESULT WINAPI
wbem_services_PutInstance(
626 IWbemServices
*iface
,
627 IWbemClassObject
*pInst
,
630 IWbemCallResult
**ppCallResult
)
633 return WBEM_E_FAILED
;
636 static HRESULT WINAPI
wbem_services_PutInstanceAsync(
637 IWbemServices
*iface
,
638 IWbemClassObject
*pInst
,
641 IWbemObjectSink
*pResponseHandler
)
644 return WBEM_E_FAILED
;
647 static HRESULT WINAPI
wbem_services_DeleteInstance(
648 IWbemServices
*iface
,
649 const BSTR strObjectPath
,
652 IWbemCallResult
**ppCallResult
)
655 return WBEM_E_FAILED
;
658 static HRESULT WINAPI
wbem_services_DeleteInstanceAsync(
659 IWbemServices
*iface
,
660 const BSTR strObjectPath
,
663 IWbemObjectSink
*pResponseHandler
)
666 return WBEM_E_FAILED
;
669 static HRESULT WINAPI
wbem_services_CreateInstanceEnum(
670 IWbemServices
*iface
,
674 IEnumWbemClassObject
**ppEnum
)
676 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
680 TRACE( "%p, %s, %#lx, %p, %p\n", iface
, debugstr_w(strClass
), lFlags
, pCtx
, ppEnum
);
682 if (lFlags
) FIXME( "unsupported flags %#lx\n", lFlags
);
684 hr
= parse_path( strClass
, &path
);
685 if (hr
!= S_OK
) return hr
;
687 hr
= create_instance_enum( services
->ns
, path
, ppEnum
);
692 static HRESULT WINAPI
wbem_services_CreateInstanceEnumAsync(
693 IWbemServices
*iface
,
694 const BSTR strFilter
,
697 IWbemObjectSink
*pResponseHandler
)
700 return WBEM_E_FAILED
;
703 static HRESULT WINAPI
wbem_services_ExecQuery(
704 IWbemServices
*iface
,
705 const BSTR strQueryLanguage
,
709 IEnumWbemClassObject
**ppEnum
)
711 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
713 TRACE( "%p, %s, %s, %#lx, %p, %p\n", iface
, debugstr_w(strQueryLanguage
),
714 debugstr_w(strQuery
), lFlags
, pCtx
, ppEnum
);
716 if (!strQueryLanguage
|| !strQuery
|| !strQuery
[0]) return WBEM_E_INVALID_PARAMETER
;
717 if (wcsicmp( strQueryLanguage
, L
"WQL" )) return WBEM_E_INVALID_QUERY_TYPE
;
718 return exec_query( services
->ns
, strQuery
, ppEnum
);
721 static void async_exec_query( struct async_header
*hdr
)
723 struct async_query
*query
= (struct async_query
*)hdr
;
724 IEnumWbemClassObject
*result
;
725 IWbemClassObject
*obj
;
729 hr
= exec_query( query
->ns
, query
->str
, &result
);
734 IEnumWbemClassObject_Next( result
, WBEM_INFINITE
, 1, &obj
, &count
);
736 IWbemObjectSink_Indicate( query
->hdr
.sink
, 1, &obj
);
737 IWbemClassObject_Release( obj
);
739 IEnumWbemClassObject_Release( result
);
741 IWbemObjectSink_SetStatus( query
->hdr
.sink
, WBEM_STATUS_COMPLETE
, hr
, NULL
, NULL
);
745 static HRESULT WINAPI
wbem_services_ExecQueryAsync(
746 IWbemServices
*iface
,
747 const BSTR strQueryLanguage
,
751 IWbemObjectSink
*pResponseHandler
)
753 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
754 IWbemObjectSink
*sink
;
755 HRESULT hr
= E_OUTOFMEMORY
;
756 struct async_header
*async
;
757 struct async_query
*query
;
759 TRACE( "%p, %s, %s, %#lx, %p, %p\n", iface
, debugstr_w(strQueryLanguage
), debugstr_w(strQuery
),
760 lFlags
, pCtx
, pResponseHandler
);
762 if (!pResponseHandler
) return WBEM_E_INVALID_PARAMETER
;
764 hr
= IWbemObjectSink_QueryInterface( pResponseHandler
, &IID_IWbemObjectSink
, (void **)&sink
);
765 if (FAILED(hr
)) return hr
;
767 EnterCriticalSection( &services
->cs
);
771 FIXME("handle more than one pending async\n");
775 if (!(query
= calloc( 1, sizeof(*query
) ))) goto done
;
776 query
->ns
= services
->ns
;
777 async
= (struct async_header
*)query
;
779 if (!(init_async( async
, sink
, async_exec_query
)))
784 if (!(query
->str
= wcsdup( strQuery
)))
789 hr
= queue_async( async
);
790 if (hr
== S_OK
) services
->async
= async
;
798 LeaveCriticalSection( &services
->cs
);
799 IWbemObjectSink_Release( sink
);
803 static HRESULT WINAPI
wbem_services_ExecNotificationQuery(
804 IWbemServices
*iface
,
805 const BSTR strQueryLanguage
,
809 IEnumWbemClassObject
**ppEnum
)
812 return WBEM_E_FAILED
;
815 static HRESULT WINAPI
wbem_services_ExecNotificationQueryAsync(
816 IWbemServices
*iface
,
817 const BSTR strQueryLanguage
,
821 IWbemObjectSink
*pResponseHandler
)
823 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
824 IWbemObjectSink
*sink
;
825 HRESULT hr
= E_OUTOFMEMORY
;
826 struct async_header
*async
;
827 struct async_query
*query
;
829 TRACE( "%p, %s, %s, %#lx, %p, %p\n", iface
, debugstr_w(strQueryLanguage
), debugstr_w(strQuery
),
830 lFlags
, pCtx
, pResponseHandler
);
832 if (!pResponseHandler
) return WBEM_E_INVALID_PARAMETER
;
834 hr
= IWbemObjectSink_QueryInterface( pResponseHandler
, &IID_IWbemObjectSink
, (void **)&sink
);
835 if (FAILED(hr
)) return hr
;
837 EnterCriticalSection( &services
->cs
);
841 FIXME("handle more than one pending async\n");
845 if (!(query
= calloc( 1, sizeof(*query
) ))) goto done
;
846 async
= (struct async_header
*)query
;
848 if (!(init_async( async
, sink
, async_exec_query
)))
853 if (!(query
->str
= wcsdup( strQuery
)))
858 hr
= queue_async( async
);
859 if (hr
== S_OK
) services
->async
= async
;
867 LeaveCriticalSection( &services
->cs
);
868 IWbemObjectSink_Release( sink
);
872 static HRESULT WINAPI
wbem_services_ExecMethod(
873 IWbemServices
*iface
,
874 const BSTR strObjectPath
,
875 const BSTR strMethodName
,
877 IWbemContext
*context
,
878 IWbemClassObject
*pInParams
,
879 IWbemClassObject
**ppOutParams
,
880 IWbemCallResult
**ppCallResult
)
882 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
883 IEnumWbemClassObject
*result
= NULL
;
884 IWbemClassObject
*obj
= NULL
;
885 struct query
*query
= NULL
;
892 TRACE( "%p, %s, %s, %#lx, %p, %p, %p, %p\n", iface
, debugstr_w(strObjectPath
),
893 debugstr_w(strMethodName
), lFlags
, context
, pInParams
, ppOutParams
, ppCallResult
);
895 if (lFlags
) FIXME( "flags %#lx not supported\n", lFlags
);
897 if ((hr
= parse_path( strObjectPath
, &path
)) != S_OK
) return hr
;
898 if (!(str
= query_from_path( path
)))
903 if (!(query
= create_query( services
->ns
)))
908 hr
= parse_query( services
->ns
, str
, &query
->view
, &query
->mem
);
909 if (hr
!= S_OK
) goto done
;
911 hr
= execute_view( query
->view
);
912 if (hr
!= S_OK
) goto done
;
914 hr
= EnumWbemClassObject_create( query
, (void **)&result
);
915 if (hr
!= S_OK
) goto done
;
917 table
= get_view_table( query
->view
, 0 );
918 hr
= create_class_object( services
->ns
, table
->name
, result
, 0, NULL
, &obj
);
919 if (hr
!= S_OK
) goto done
;
921 hr
= get_method( table
, strMethodName
, &func
);
922 if (hr
!= S_OK
) goto done
;
924 hr
= func( obj
, context
? context
: services
->context
, pInParams
, ppOutParams
);
927 if (result
) IEnumWbemClassObject_Release( result
);
928 if (obj
) IWbemClassObject_Release( obj
);
935 static HRESULT WINAPI
wbem_services_ExecMethodAsync(
936 IWbemServices
*iface
,
937 const BSTR strObjectPath
,
938 const BSTR strMethodName
,
941 IWbemClassObject
*pInParams
,
942 IWbemObjectSink
*pResponseHandler
)
945 return WBEM_E_FAILED
;
948 static const IWbemServicesVtbl wbem_services_vtbl
=
950 wbem_services_QueryInterface
,
951 wbem_services_AddRef
,
952 wbem_services_Release
,
953 wbem_services_OpenNamespace
,
954 wbem_services_CancelAsyncCall
,
955 wbem_services_QueryObjectSink
,
956 wbem_services_GetObject
,
957 wbem_services_GetObjectAsync
,
958 wbem_services_PutClass
,
959 wbem_services_PutClassAsync
,
960 wbem_services_DeleteClass
,
961 wbem_services_DeleteClassAsync
,
962 wbem_services_CreateClassEnum
,
963 wbem_services_CreateClassEnumAsync
,
964 wbem_services_PutInstance
,
965 wbem_services_PutInstanceAsync
,
966 wbem_services_DeleteInstance
,
967 wbem_services_DeleteInstanceAsync
,
968 wbem_services_CreateInstanceEnum
,
969 wbem_services_CreateInstanceEnumAsync
,
970 wbem_services_ExecQuery
,
971 wbem_services_ExecQueryAsync
,
972 wbem_services_ExecNotificationQuery
,
973 wbem_services_ExecNotificationQueryAsync
,
974 wbem_services_ExecMethod
,
975 wbem_services_ExecMethodAsync
978 HRESULT
WbemServices_create( const WCHAR
*namespace, IWbemContext
*context
, LPVOID
*ppObj
)
980 struct wbem_services
*ws
;
981 enum wbm_namespace ns
;
983 TRACE("namespace %s, context %p, ppObj %p.\n", debugstr_w(namespace), context
, ppObj
);
986 ns
= WBEMPROX_NAMESPACE_LAST
;
987 else if ((ns
= get_namespace_from_string( namespace )) == WBEMPROX_NAMESPACE_LAST
)
988 return WBEM_E_INVALID_NAMESPACE
;
990 if (!(ws
= calloc( 1, sizeof(*ws
) ))) return E_OUTOFMEMORY
;
992 ws
->IWbemServices_iface
.lpVtbl
= &wbem_services_vtbl
;
995 InitializeCriticalSectionEx( &ws
->cs
, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
);
996 ws
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": wbemprox_services.cs");
998 IWbemContext_Clone( context
, &ws
->context
);
1000 *ppObj
= &ws
->IWbemServices_iface
;
1002 TRACE("returning iface %p\n", *ppObj
);
1006 struct wbem_context_value
1015 IWbemContext IWbemContext_iface
;
1020 static void wbem_context_delete_values(struct wbem_context
*context
)
1022 struct wbem_context_value
*value
, *next
;
1024 LIST_FOR_EACH_ENTRY_SAFE(value
, next
, &context
->values
, struct wbem_context_value
, entry
)
1026 list_remove( &value
->entry
);
1027 VariantClear( &value
->value
);
1028 free( value
->name
);
1033 static struct wbem_context
*impl_from_IWbemContext( IWbemContext
*iface
)
1035 return CONTAINING_RECORD( iface
, struct wbem_context
, IWbemContext_iface
);
1038 static HRESULT WINAPI
wbem_context_QueryInterface(
1039 IWbemContext
*iface
,
1043 TRACE("%p, %s, %p\n", iface
, debugstr_guid( riid
), obj
);
1045 if ( IsEqualGUID( riid
, &IID_IWbemContext
) ||
1046 IsEqualGUID( riid
, &IID_IUnknown
) )
1052 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
1053 return E_NOINTERFACE
;
1056 IWbemContext_AddRef( iface
);
1060 static ULONG WINAPI
wbem_context_AddRef(
1061 IWbemContext
*iface
)
1063 struct wbem_context
*context
= impl_from_IWbemContext( iface
);
1064 return InterlockedIncrement( &context
->refs
);
1067 static ULONG WINAPI
wbem_context_Release(
1068 IWbemContext
*iface
)
1070 struct wbem_context
*context
= impl_from_IWbemContext( iface
);
1071 LONG refs
= InterlockedDecrement( &context
->refs
);
1075 TRACE("destroying %p\n", context
);
1076 wbem_context_delete_values( context
);
1082 static HRESULT WINAPI
wbem_context_Clone(
1083 IWbemContext
*iface
,
1084 IWbemContext
**newcopy
)
1086 struct wbem_context
*context
= impl_from_IWbemContext( iface
);
1087 struct wbem_context_value
*value
;
1088 IWbemContext
*cloned_context
;
1091 TRACE("%p, %p\n", iface
, newcopy
);
1093 if (SUCCEEDED(hr
= WbemContext_create( (void **)&cloned_context
, &IID_IWbemContext
)))
1095 LIST_FOR_EACH_ENTRY( value
, &context
->values
, struct wbem_context_value
, entry
)
1097 if (FAILED(hr
= IWbemContext_SetValue( cloned_context
, value
->name
, 0, &value
->value
))) break;
1103 *newcopy
= cloned_context
;
1108 IWbemContext_Release( cloned_context
);
1114 static HRESULT WINAPI
wbem_context_GetNames(
1115 IWbemContext
*iface
,
1119 FIXME( "%p, %#lx, %p\n", iface
, flags
, names
);
1124 static HRESULT WINAPI
wbem_context_BeginEnumeration(
1125 IWbemContext
*iface
,
1128 FIXME( "%p, %#lx\n", iface
, flags
);
1133 static HRESULT WINAPI
wbem_context_Next(
1134 IWbemContext
*iface
,
1139 FIXME( "%p, %#lx, %p, %p\n", iface
, flags
, name
, value
);
1144 static HRESULT WINAPI
wbem_context_EndEnumeration(
1145 IWbemContext
*iface
)
1147 FIXME("%p\n", iface
);
1152 static struct wbem_context_value
*wbem_context_get_value( struct wbem_context
*context
, const WCHAR
*name
)
1154 struct wbem_context_value
*value
;
1156 LIST_FOR_EACH_ENTRY( value
, &context
->values
, struct wbem_context_value
, entry
)
1158 if (!lstrcmpiW( value
->name
, name
)) return value
;
1164 static HRESULT WINAPI
wbem_context_SetValue(
1165 IWbemContext
*iface
,
1170 struct wbem_context
*context
= impl_from_IWbemContext( iface
);
1171 struct wbem_context_value
*value
;
1174 TRACE( "%p, %s, %#lx, %s\n", iface
, debugstr_w(name
), flags
, debugstr_variant(var
) );
1177 return WBEM_E_INVALID_PARAMETER
;
1179 if ((value
= wbem_context_get_value( context
, name
)))
1181 VariantClear( &value
->value
);
1182 hr
= VariantCopy( &value
->value
, var
);
1186 if (!(value
= calloc( 1, sizeof(*value
) ))) return E_OUTOFMEMORY
;
1187 if (!(value
->name
= wcsdup( name
)))
1190 return E_OUTOFMEMORY
;
1192 if (FAILED(hr
= VariantCopy( &value
->value
, var
)))
1194 free( value
->name
);
1199 list_add_tail( &context
->values
, &value
->entry
);
1205 static HRESULT WINAPI
wbem_context_GetValue(
1206 IWbemContext
*iface
,
1211 struct wbem_context
*context
= impl_from_IWbemContext( iface
);
1212 struct wbem_context_value
*value
;
1214 TRACE( "%p, %s, %#lx, %p\n", iface
, debugstr_w(name
), flags
, var
);
1217 return WBEM_E_INVALID_PARAMETER
;
1219 if (!(value
= wbem_context_get_value( context
, name
)))
1220 return WBEM_E_NOT_FOUND
;
1222 V_VT(var
) = VT_EMPTY
;
1223 return VariantCopy( var
, &value
->value
);
1226 static HRESULT WINAPI
wbem_context_DeleteValue(
1227 IWbemContext
*iface
,
1231 FIXME( "%p, %s, %#lx\n", iface
, debugstr_w(name
), flags
);
1236 static HRESULT WINAPI
wbem_context_DeleteAll(
1237 IWbemContext
*iface
)
1239 FIXME("%p\n", iface
);
1244 static const IWbemContextVtbl wbem_context_vtbl
=
1246 wbem_context_QueryInterface
,
1247 wbem_context_AddRef
,
1248 wbem_context_Release
,
1250 wbem_context_GetNames
,
1251 wbem_context_BeginEnumeration
,
1253 wbem_context_EndEnumeration
,
1254 wbem_context_SetValue
,
1255 wbem_context_GetValue
,
1256 wbem_context_DeleteValue
,
1257 wbem_context_DeleteAll
,
1260 HRESULT
WbemContext_create( void **obj
, REFIID riid
)
1262 struct wbem_context
*context
;
1264 TRACE("(%p)\n", obj
);
1266 if ( !IsEqualGUID( riid
, &IID_IWbemContext
) &&
1267 !IsEqualGUID( riid
, &IID_IUnknown
) )
1268 return E_NOINTERFACE
;
1270 if (!(context
= malloc( sizeof(*context
) ))) return E_OUTOFMEMORY
;
1272 context
->IWbemContext_iface
.lpVtbl
= &wbem_context_vtbl
;
1274 list_init(&context
->values
);
1276 *obj
= &context
->IWbemContext_iface
;
1278 TRACE("returning iface %p\n", *obj
);