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
)
95 static HRESULT WINAPI
client_security_SetBlanket(
96 IClientSecurity
*iface
,
100 OLECHAR
*pServerPrincName
,
106 const OLECHAR
*princname
= (pServerPrincName
== COLE_DEFAULT_PRINCIPAL
) ?
107 L
"<COLE_DEFAULT_PRINCIPAL>" : pServerPrincName
;
109 FIXME("%p, %p, %u, %u, %s, %u, %u, %p, 0x%08x\n", iface
, pProxy
, AuthnSvc
, AuthzSvc
,
110 debugstr_w(princname
), AuthnLevel
, ImpLevel
, pAuthInfo
, Capabilities
);
111 return WBEM_NO_ERROR
;
114 static HRESULT WINAPI
client_security_CopyProxy(
115 IClientSecurity
*iface
,
120 return WBEM_E_FAILED
;
123 static const IClientSecurityVtbl client_security_vtbl
=
125 client_security_QueryInterface
,
126 client_security_AddRef
,
127 client_security_Release
,
128 client_security_QueryBlanket
,
129 client_security_SetBlanket
,
130 client_security_CopyProxy
133 IClientSecurity client_security
= { &client_security_vtbl
};
137 IWbemObjectSink
*sink
;
138 void (*proc
)( struct async_header
* );
145 struct async_header hdr
;
149 static void free_async( struct async_header
*async
)
151 if (async
->sink
) IWbemObjectSink_Release( async
->sink
);
152 CloseHandle( async
->cancel
);
153 CloseHandle( async
->wait
);
157 static BOOL
init_async( struct async_header
*async
, IWbemObjectSink
*sink
,
158 void (*proc
)(struct async_header
*) )
160 if (!(async
->wait
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
))) return FALSE
;
161 if (!(async
->cancel
= CreateEventW( NULL
, FALSE
, FALSE
, NULL
)))
163 CloseHandle( async
->wait
);
168 IWbemObjectSink_AddRef( sink
);
172 static DWORD CALLBACK
async_proc( LPVOID param
)
174 struct async_header
*async
= param
;
175 HANDLE wait
= async
->wait
;
177 async
->proc( async
);
179 WaitForSingleObject( async
->cancel
, INFINITE
);
181 return ERROR_SUCCESS
;
184 static HRESULT
queue_async( struct async_header
*async
)
186 if (QueueUserWorkItem( async_proc
, async
, WT_EXECUTELONGFUNCTION
)) return S_OK
;
187 return HRESULT_FROM_WIN32( GetLastError() );
192 IWbemServices IWbemServices_iface
;
196 struct async_header
*async
;
199 static inline struct wbem_services
*impl_from_IWbemServices( IWbemServices
*iface
)
201 return CONTAINING_RECORD( iface
, struct wbem_services
, IWbemServices_iface
);
204 static ULONG WINAPI
wbem_services_AddRef(
205 IWbemServices
*iface
)
207 struct wbem_services
*ws
= impl_from_IWbemServices( iface
);
208 return InterlockedIncrement( &ws
->refs
);
211 static ULONG WINAPI
wbem_services_Release(
212 IWbemServices
*iface
)
214 struct wbem_services
*ws
= impl_from_IWbemServices( iface
);
215 LONG refs
= InterlockedDecrement( &ws
->refs
);
218 TRACE("destroying %p\n", ws
);
220 EnterCriticalSection( &ws
->cs
);
221 if (ws
->async
) SetEvent( ws
->async
->cancel
);
222 LeaveCriticalSection( &ws
->cs
);
225 WaitForSingleObject( ws
->async
->wait
, INFINITE
);
226 free_async( ws
->async
);
228 ws
->cs
.DebugInfo
->Spare
[0] = 0;
229 DeleteCriticalSection( &ws
->cs
);
230 heap_free( ws
->namespace );
236 static HRESULT WINAPI
wbem_services_QueryInterface(
237 IWbemServices
*iface
,
241 struct wbem_services
*ws
= impl_from_IWbemServices( iface
);
243 TRACE("%p %s %p\n", ws
, debugstr_guid( riid
), ppvObject
);
245 if ( IsEqualGUID( riid
, &IID_IWbemServices
) ||
246 IsEqualGUID( riid
, &IID_IUnknown
) )
250 else if ( IsEqualGUID( riid
, &IID_IClientSecurity
) )
252 *ppvObject
= &client_security
;
257 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
258 return E_NOINTERFACE
;
260 IWbemServices_AddRef( iface
);
264 static HRESULT WINAPI
wbem_services_OpenNamespace(
265 IWbemServices
*iface
,
266 const BSTR strNamespace
,
269 IWbemServices
**ppWorkingNamespace
,
270 IWbemCallResult
**ppResult
)
272 struct wbem_services
*ws
= impl_from_IWbemServices( iface
);
274 TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface
, debugstr_w(strNamespace
), lFlags
,
275 pCtx
, ppWorkingNamespace
, ppResult
);
277 if ((wcsicmp( strNamespace
, L
"cimv2" ) && wcsicmp( strNamespace
, L
"default" )) || ws
->namespace)
278 return WBEM_E_INVALID_NAMESPACE
;
280 return WbemServices_create( L
"cimv2", (void **)ppWorkingNamespace
);
283 static HRESULT WINAPI
wbem_services_CancelAsyncCall(
284 IWbemServices
*iface
,
285 IWbemObjectSink
*pSink
)
287 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
288 struct async_header
*async
;
290 TRACE("%p, %p\n", iface
, pSink
);
292 if (!pSink
) return WBEM_E_INVALID_PARAMETER
;
294 EnterCriticalSection( &services
->cs
);
296 if (!(async
= services
->async
))
298 LeaveCriticalSection( &services
->cs
);
299 return WBEM_E_INVALID_PARAMETER
;
301 services
->async
= NULL
;
302 SetEvent( async
->cancel
);
304 LeaveCriticalSection( &services
->cs
);
306 WaitForSingleObject( async
->wait
, INFINITE
);
311 static HRESULT WINAPI
wbem_services_QueryObjectSink(
312 IWbemServices
*iface
,
314 IWbemObjectSink
**ppResponseHandler
)
317 return WBEM_E_FAILED
;
320 HRESULT
parse_path( const WCHAR
*str
, struct path
**ret
)
323 const WCHAR
*p
= str
, *q
;
326 if (!(path
= heap_alloc_zero( sizeof(*path
) ))) return E_OUTOFMEMORY
;
330 static const WCHAR cimv2W
[] = L
"ROOT\\CIMV2";
331 WCHAR server
[MAX_COMPUTERNAME_LENGTH
+1];
332 DWORD server_len
= ARRAY_SIZE(server
);
338 return WBEM_E_INVALID_OBJECT_PATH
;
343 while (*p
&& *p
!= '\\') p
++;
347 return WBEM_E_INVALID_OBJECT_PATH
;
351 if (!GetComputerNameW( server
, &server_len
) || server_len
!= len
|| wcsnicmp( q
, server
, server_len
))
354 return WBEM_E_NOT_SUPPORTED
;
358 while (*p
&& *p
!= ':') p
++;
362 return WBEM_E_INVALID_OBJECT_PATH
;
366 if (len
!= ARRAY_SIZE(cimv2W
) - 1 || wcsnicmp( q
, cimv2W
, ARRAY_SIZE(cimv2W
) - 1 ))
369 return WBEM_E_INVALID_NAMESPACE
;
375 while (*p
&& *p
!= '.') p
++;
378 if (!(path
->class = heap_alloc( (len
+ 1) * sizeof(WCHAR
) )))
381 return E_OUTOFMEMORY
;
383 memcpy( path
->class, q
, len
* sizeof(WCHAR
) );
384 path
->class[len
] = 0;
385 path
->class_len
= len
;
387 if (p
[0] == '.' && p
[1])
393 if (!(path
->filter
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) )))
395 heap_free( path
->class );
397 return E_OUTOFMEMORY
;
399 memcpy( path
->filter
, p
, len
* sizeof(WCHAR
) );
400 path
->filter
[len
] = 0;
401 path
->filter_len
= len
;
407 void free_path( struct path
*path
)
410 heap_free( path
->class );
411 heap_free( path
->filter
);
415 WCHAR
*query_from_path( const struct path
*path
)
417 static const WCHAR selectW
[] = L
"SELECT * FROM %s WHERE %s";
418 static const WCHAR select_allW
[] = L
"SELECT * FROM ";
424 len
= path
->class_len
+ path
->filter_len
+ ARRAY_SIZE(selectW
);
425 if (!(query
= heap_alloc( len
* sizeof(WCHAR
) ))) return NULL
;
426 swprintf( query
, len
, selectW
, path
->class, path
->filter
);
430 len
= path
->class_len
+ ARRAY_SIZE(select_allW
);
431 if (!(query
= heap_alloc( len
* sizeof(WCHAR
) ))) return NULL
;
432 lstrcpyW( query
, select_allW
);
433 lstrcatW( query
, path
->class );
438 static HRESULT
create_instance_enum( const struct path
*path
, IEnumWbemClassObject
**iter
)
443 if (!(query
= query_from_path( path
))) return E_OUTOFMEMORY
;
444 hr
= exec_query( query
, iter
);
449 HRESULT
get_object( const WCHAR
*object_path
, IWbemClassObject
**obj
)
451 IEnumWbemClassObject
*iter
;
456 hr
= parse_path( object_path
, &path
);
457 if (hr
!= S_OK
) return hr
;
459 hr
= create_instance_enum( path
, &iter
);
465 hr
= IEnumWbemClassObject_Next( iter
, WBEM_INFINITE
, 1, obj
, &count
);
466 if (hr
== WBEM_S_FALSE
)
468 hr
= WBEM_E_NOT_FOUND
;
471 IEnumWbemClassObject_Release( iter
);
476 static HRESULT WINAPI
wbem_services_GetObject(
477 IWbemServices
*iface
,
478 const BSTR strObjectPath
,
481 IWbemClassObject
**ppObject
,
482 IWbemCallResult
**ppCallResult
)
484 TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface
, debugstr_w(strObjectPath
), lFlags
,
485 pCtx
, ppObject
, ppCallResult
);
487 if (lFlags
) FIXME("unsupported flags 0x%08x\n", lFlags
);
489 if (!strObjectPath
|| !strObjectPath
[0])
490 return create_class_object( NULL
, NULL
, 0, NULL
, ppObject
);
492 return get_object( strObjectPath
, ppObject
);
495 static HRESULT WINAPI
wbem_services_GetObjectAsync(
496 IWbemServices
*iface
,
497 const BSTR strObjectPath
,
500 IWbemObjectSink
*pResponseHandler
)
503 return WBEM_E_FAILED
;
506 static HRESULT WINAPI
wbem_services_PutClass(
507 IWbemServices
*iface
,
508 IWbemClassObject
*pObject
,
511 IWbemCallResult
**ppCallResult
)
514 return WBEM_E_FAILED
;
517 static HRESULT WINAPI
wbem_services_PutClassAsync(
518 IWbemServices
*iface
,
519 IWbemClassObject
*pObject
,
522 IWbemObjectSink
*pResponseHandler
)
525 return WBEM_E_FAILED
;
528 static HRESULT WINAPI
wbem_services_DeleteClass(
529 IWbemServices
*iface
,
533 IWbemCallResult
**ppCallResult
)
536 return WBEM_E_FAILED
;
539 static HRESULT WINAPI
wbem_services_DeleteClassAsync(
540 IWbemServices
*iface
,
544 IWbemObjectSink
*pResponseHandler
)
547 return WBEM_E_FAILED
;
550 static HRESULT WINAPI
wbem_services_CreateClassEnum(
551 IWbemServices
*iface
,
552 const BSTR strSuperclass
,
555 IEnumWbemClassObject
**ppEnum
)
558 return WBEM_E_FAILED
;
561 static HRESULT WINAPI
wbem_services_CreateClassEnumAsync(
562 IWbemServices
*iface
,
563 const BSTR strSuperclass
,
566 IWbemObjectSink
*pResponseHandler
)
569 return WBEM_E_FAILED
;
572 static HRESULT WINAPI
wbem_services_PutInstance(
573 IWbemServices
*iface
,
574 IWbemClassObject
*pInst
,
577 IWbemCallResult
**ppCallResult
)
580 return WBEM_E_FAILED
;
583 static HRESULT WINAPI
wbem_services_PutInstanceAsync(
584 IWbemServices
*iface
,
585 IWbemClassObject
*pInst
,
588 IWbemObjectSink
*pResponseHandler
)
591 return WBEM_E_FAILED
;
594 static HRESULT WINAPI
wbem_services_DeleteInstance(
595 IWbemServices
*iface
,
596 const BSTR strObjectPath
,
599 IWbemCallResult
**ppCallResult
)
602 return WBEM_E_FAILED
;
605 static HRESULT WINAPI
wbem_services_DeleteInstanceAsync(
606 IWbemServices
*iface
,
607 const BSTR strObjectPath
,
610 IWbemObjectSink
*pResponseHandler
)
613 return WBEM_E_FAILED
;
616 static HRESULT WINAPI
wbem_services_CreateInstanceEnum(
617 IWbemServices
*iface
,
621 IEnumWbemClassObject
**ppEnum
)
626 TRACE("%p, %s, 0%08x, %p, %p\n", iface
, debugstr_w(strClass
), lFlags
, pCtx
, ppEnum
);
628 if (lFlags
) FIXME("unsupported flags 0x%08x\n", lFlags
);
630 hr
= parse_path( strClass
, &path
);
631 if (hr
!= S_OK
) return hr
;
633 hr
= create_instance_enum( path
, ppEnum
);
638 static HRESULT WINAPI
wbem_services_CreateInstanceEnumAsync(
639 IWbemServices
*iface
,
640 const BSTR strFilter
,
643 IWbemObjectSink
*pResponseHandler
)
646 return WBEM_E_FAILED
;
649 static HRESULT WINAPI
wbem_services_ExecQuery(
650 IWbemServices
*iface
,
651 const BSTR strQueryLanguage
,
655 IEnumWbemClassObject
**ppEnum
)
657 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface
, debugstr_w(strQueryLanguage
),
658 debugstr_w(strQuery
), lFlags
, pCtx
, ppEnum
);
660 if (!strQueryLanguage
|| !strQuery
|| !strQuery
[0]) return WBEM_E_INVALID_PARAMETER
;
661 if (wcsicmp( strQueryLanguage
, L
"WQL" )) return WBEM_E_INVALID_QUERY_TYPE
;
662 return exec_query( strQuery
, ppEnum
);
665 static void async_exec_query( struct async_header
*hdr
)
667 struct async_query
*query
= (struct async_query
*)hdr
;
668 IEnumWbemClassObject
*result
;
669 IWbemClassObject
*obj
;
673 hr
= exec_query( query
->str
, &result
);
678 IEnumWbemClassObject_Next( result
, WBEM_INFINITE
, 1, &obj
, &count
);
680 IWbemObjectSink_Indicate( query
->hdr
.sink
, 1, &obj
);
681 IWbemClassObject_Release( obj
);
683 IEnumWbemClassObject_Release( result
);
685 IWbemObjectSink_SetStatus( query
->hdr
.sink
, WBEM_STATUS_COMPLETE
, hr
, NULL
, NULL
);
686 heap_free( query
->str
);
689 static HRESULT WINAPI
wbem_services_ExecQueryAsync(
690 IWbemServices
*iface
,
691 const BSTR strQueryLanguage
,
695 IWbemObjectSink
*pResponseHandler
)
697 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
698 IWbemObjectSink
*sink
;
699 HRESULT hr
= E_OUTOFMEMORY
;
700 struct async_header
*async
;
701 struct async_query
*query
;
703 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface
, debugstr_w(strQueryLanguage
), debugstr_w(strQuery
),
704 lFlags
, pCtx
, pResponseHandler
);
706 if (!pResponseHandler
) return WBEM_E_INVALID_PARAMETER
;
708 hr
= IWbemObjectSink_QueryInterface( pResponseHandler
, &IID_IWbemObjectSink
, (void **)&sink
);
709 if (FAILED(hr
)) return hr
;
711 EnterCriticalSection( &services
->cs
);
715 FIXME("handle more than one pending async\n");
719 if (!(query
= heap_alloc_zero( sizeof(*query
) ))) goto done
;
720 async
= (struct async_header
*)query
;
722 if (!(init_async( async
, sink
, async_exec_query
)))
727 if (!(query
->str
= heap_strdupW( strQuery
)))
732 hr
= queue_async( async
);
733 if (hr
== S_OK
) services
->async
= async
;
736 heap_free( query
->str
);
741 LeaveCriticalSection( &services
->cs
);
742 IWbemObjectSink_Release( sink
);
746 static HRESULT WINAPI
wbem_services_ExecNotificationQuery(
747 IWbemServices
*iface
,
748 const BSTR strQueryLanguage
,
752 IEnumWbemClassObject
**ppEnum
)
755 return WBEM_E_FAILED
;
758 static HRESULT WINAPI
wbem_services_ExecNotificationQueryAsync(
759 IWbemServices
*iface
,
760 const BSTR strQueryLanguage
,
764 IWbemObjectSink
*pResponseHandler
)
766 struct wbem_services
*services
= impl_from_IWbemServices( iface
);
767 IWbemObjectSink
*sink
;
768 HRESULT hr
= E_OUTOFMEMORY
;
769 struct async_header
*async
;
770 struct async_query
*query
;
772 TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface
, debugstr_w(strQueryLanguage
), debugstr_w(strQuery
),
773 lFlags
, pCtx
, pResponseHandler
);
775 if (!pResponseHandler
) return WBEM_E_INVALID_PARAMETER
;
777 hr
= IWbemObjectSink_QueryInterface( pResponseHandler
, &IID_IWbemObjectSink
, (void **)&sink
);
778 if (FAILED(hr
)) return hr
;
780 EnterCriticalSection( &services
->cs
);
784 FIXME("handle more than one pending async\n");
788 if (!(query
= heap_alloc_zero( sizeof(*query
) ))) goto done
;
789 async
= (struct async_header
*)query
;
791 if (!(init_async( async
, sink
, async_exec_query
)))
796 if (!(query
->str
= heap_strdupW( strQuery
)))
801 hr
= queue_async( async
);
802 if (hr
== S_OK
) services
->async
= async
;
805 heap_free( query
->str
);
810 LeaveCriticalSection( &services
->cs
);
811 IWbemObjectSink_Release( sink
);
815 static HRESULT WINAPI
wbem_services_ExecMethod(
816 IWbemServices
*iface
,
817 const BSTR strObjectPath
,
818 const BSTR strMethodName
,
821 IWbemClassObject
*pInParams
,
822 IWbemClassObject
**ppOutParams
,
823 IWbemCallResult
**ppCallResult
)
825 IEnumWbemClassObject
*result
= NULL
;
826 IWbemClassObject
*obj
= NULL
;
827 struct query
*query
= NULL
;
834 TRACE("%p, %s, %s, %08x, %p, %p, %p, %p\n", iface
, debugstr_w(strObjectPath
),
835 debugstr_w(strMethodName
), lFlags
, pCtx
, pInParams
, ppOutParams
, ppCallResult
);
837 if (lFlags
) FIXME("flags %08x not supported\n", lFlags
);
839 if ((hr
= parse_path( strObjectPath
, &path
)) != S_OK
) return hr
;
840 if (!(str
= query_from_path( path
)))
845 if (!(query
= create_query()))
850 hr
= parse_query( str
, &query
->view
, &query
->mem
);
851 if (hr
!= S_OK
) goto done
;
853 hr
= execute_view( query
->view
);
854 if (hr
!= S_OK
) goto done
;
856 hr
= EnumWbemClassObject_create( query
, (void **)&result
);
857 if (hr
!= S_OK
) goto done
;
859 table
= get_view_table( query
->view
, 0 );
860 hr
= create_class_object( table
->name
, result
, 0, NULL
, &obj
);
861 if (hr
!= S_OK
) goto done
;
863 hr
= get_method( table
, strMethodName
, &func
);
864 if (hr
!= S_OK
) goto done
;
866 hr
= func( obj
, pInParams
, ppOutParams
);
869 if (result
) IEnumWbemClassObject_Release( result
);
870 if (obj
) IWbemClassObject_Release( obj
);
877 static HRESULT WINAPI
wbem_services_ExecMethodAsync(
878 IWbemServices
*iface
,
879 const BSTR strObjectPath
,
880 const BSTR strMethodName
,
883 IWbemClassObject
*pInParams
,
884 IWbemObjectSink
*pResponseHandler
)
887 return WBEM_E_FAILED
;
890 static const IWbemServicesVtbl wbem_services_vtbl
=
892 wbem_services_QueryInterface
,
893 wbem_services_AddRef
,
894 wbem_services_Release
,
895 wbem_services_OpenNamespace
,
896 wbem_services_CancelAsyncCall
,
897 wbem_services_QueryObjectSink
,
898 wbem_services_GetObject
,
899 wbem_services_GetObjectAsync
,
900 wbem_services_PutClass
,
901 wbem_services_PutClassAsync
,
902 wbem_services_DeleteClass
,
903 wbem_services_DeleteClassAsync
,
904 wbem_services_CreateClassEnum
,
905 wbem_services_CreateClassEnumAsync
,
906 wbem_services_PutInstance
,
907 wbem_services_PutInstanceAsync
,
908 wbem_services_DeleteInstance
,
909 wbem_services_DeleteInstanceAsync
,
910 wbem_services_CreateInstanceEnum
,
911 wbem_services_CreateInstanceEnumAsync
,
912 wbem_services_ExecQuery
,
913 wbem_services_ExecQueryAsync
,
914 wbem_services_ExecNotificationQuery
,
915 wbem_services_ExecNotificationQueryAsync
,
916 wbem_services_ExecMethod
,
917 wbem_services_ExecMethodAsync
920 HRESULT
WbemServices_create( const WCHAR
*namespace, LPVOID
*ppObj
)
922 struct wbem_services
*ws
;
924 TRACE("(%p)\n", ppObj
);
926 ws
= heap_alloc( sizeof(*ws
) );
927 if (!ws
) return E_OUTOFMEMORY
;
929 ws
->IWbemServices_iface
.lpVtbl
= &wbem_services_vtbl
;
931 ws
->namespace = heap_strdupW( namespace );
933 InitializeCriticalSection( &ws
->cs
);
934 ws
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": wbemprox_services.cs");
936 *ppObj
= &ws
->IWbemServices_iface
;
938 TRACE("returning iface %p\n", *ppObj
);