2 * Copyright 2013 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
31 #include "wine/debug.h"
32 #include "wine/heap.h"
33 #include "wine/unicode.h"
34 #include "wbemdisp_private.h"
35 #include "wbemdisp_classes.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wbemdisp
);
39 static HINSTANCE instance
;
43 IMoniker IMoniker_iface
;
48 static inline struct moniker
*impl_from_IMoniker(
51 return CONTAINING_RECORD( iface
, struct moniker
, IMoniker_iface
);
54 static ULONG WINAPI
moniker_AddRef(
57 struct moniker
*moniker
= impl_from_IMoniker( iface
);
58 return InterlockedIncrement( &moniker
->refs
);
61 static ULONG WINAPI
moniker_Release(
64 struct moniker
*moniker
= impl_from_IMoniker( iface
);
65 LONG refs
= InterlockedDecrement( &moniker
->refs
);
68 TRACE( "destroying %p\n", moniker
);
69 IUnknown_Release( moniker
->obj
);
75 static HRESULT WINAPI
moniker_QueryInterface(
76 IMoniker
*iface
, REFIID riid
, void **ppvObject
)
78 struct moniker
*moniker
= impl_from_IMoniker( iface
);
80 TRACE( "%p, %s, %p\n", moniker
, debugstr_guid( riid
), ppvObject
);
82 if (IsEqualGUID( riid
, &IID_IMoniker
) ||
83 IsEqualGUID( riid
, &IID_IUnknown
))
89 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
92 IMoniker_AddRef( iface
);
96 static HRESULT WINAPI
moniker_GetClassID(
97 IMoniker
*iface
, CLSID
*pClassID
)
103 static HRESULT WINAPI
moniker_IsDirty(
110 static HRESULT WINAPI
moniker_Load(
111 IMoniker
*iface
, IStream
*pStm
)
117 static HRESULT WINAPI
moniker_Save(
118 IMoniker
*iface
, IStream
*pStm
, BOOL fClearDirty
)
124 static HRESULT WINAPI
moniker_GetSizeMax(
125 IMoniker
*iface
, ULARGE_INTEGER
*pcbSize
)
131 static HRESULT WINAPI
moniker_BindToObject(
132 IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, REFIID riidResult
, void **ppvResult
)
134 struct moniker
*moniker
= impl_from_IMoniker( iface
);
136 TRACE( "%p, %p, %p, %s, %p\n", iface
, pbc
, pmkToLeft
, debugstr_guid(riidResult
), ppvResult
);
137 return IUnknown_QueryInterface( moniker
->obj
, riidResult
, ppvResult
);
140 static HRESULT WINAPI
moniker_BindToStorage(
141 IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, REFIID riid
, void **ppvObj
)
147 static HRESULT WINAPI
moniker_Reduce(
148 IMoniker
*iface
, IBindCtx
*pbc
, DWORD dwReduceHowFar
, IMoniker
**ppmkToLeft
, IMoniker
**ppmkReduced
)
154 static HRESULT WINAPI
moniker_ComposeWith(
155 IMoniker
*iface
, IMoniker
*pmkRight
, BOOL fOnlyIfNotGeneric
, IMoniker
**ppmkComposite
)
161 static HRESULT WINAPI
moniker_Enum(
162 IMoniker
*iface
, BOOL fForward
, IEnumMoniker
**ppenumMoniker
)
168 static HRESULT WINAPI
moniker_IsEqual(
169 IMoniker
*iface
, IMoniker
*pmkOtherMoniker
)
175 static HRESULT WINAPI
moniker_Hash(
176 IMoniker
*iface
, DWORD
*pdwHash
)
182 static HRESULT WINAPI
moniker_IsRunning(
183 IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, IMoniker
*pmkNewlyRunning
)
189 static HRESULT WINAPI
moniker_GetTimeOfLastChange(
190 IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, FILETIME
*pFileTime
)
196 static HRESULT WINAPI
moniker_Inverse(
197 IMoniker
*iface
, IMoniker
**ppmk
)
203 static HRESULT WINAPI
moniker_CommonPrefixWith(
204 IMoniker
*iface
, IMoniker
*pmkOther
, IMoniker
**ppmkPrefix
)
210 static HRESULT WINAPI
moniker_RelativePathTo(
211 IMoniker
*iface
, IMoniker
*pmkOther
, IMoniker
**ppmkRelPath
)
217 static HRESULT WINAPI
moniker_GetDisplayName(
218 IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, LPOLESTR
*ppszDisplayName
)
224 static HRESULT WINAPI
moniker_ParseDisplayName(
225 IMoniker
*iface
, IBindCtx
*pbc
, IMoniker
*pmkToLeft
, LPOLESTR pszDisplayName
, ULONG
*pchEaten
,
232 static HRESULT WINAPI
moniker_IsSystemMoniker(
233 IMoniker
*iface
, DWORD
*pdwMksys
)
239 static const IMonikerVtbl moniker_vtbl
=
241 moniker_QueryInterface
,
249 moniker_BindToObject
,
250 moniker_BindToStorage
,
257 moniker_GetTimeOfLastChange
,
259 moniker_CommonPrefixWith
,
260 moniker_RelativePathTo
,
261 moniker_GetDisplayName
,
262 moniker_ParseDisplayName
,
263 moniker_IsSystemMoniker
266 static HRESULT
Moniker_create( IUnknown
*unk
, IMoniker
**obj
)
268 struct moniker
*moniker
;
270 TRACE( "%p, %p\n", unk
, obj
);
272 if (!(moniker
= heap_alloc( sizeof(*moniker
) ))) return E_OUTOFMEMORY
;
273 moniker
->IMoniker_iface
.lpVtbl
= &moniker_vtbl
;
276 IUnknown_AddRef( moniker
->obj
);
278 *obj
= &moniker
->IMoniker_iface
;
279 TRACE( "returning iface %p\n", *obj
);
283 static HRESULT WINAPI
WinMGMTS_QueryInterface(IParseDisplayName
*iface
, REFIID riid
, void **ppv
)
285 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
286 TRACE("(IID_IUnknown %p)\n", ppv
);
288 }else if(IsEqualGUID(riid
, &IID_IParseDisplayName
)) {
289 TRACE("(IID_IParseDisplayName %p)\n", ppv
);
292 WARN("Unsupported riid %s\n", debugstr_guid(riid
));
294 return E_NOINTERFACE
;
297 IUnknown_AddRef((IUnknown
*)*ppv
);
301 static ULONG WINAPI
WinMGMTS_AddRef(IParseDisplayName
*iface
)
306 static ULONG WINAPI
WinMGMTS_Release(IParseDisplayName
*iface
)
311 static HRESULT
parse_path( const WCHAR
*str
, BSTR
*server
, BSTR
*namespace, BSTR
*relative
)
317 *server
= *namespace = *relative
= NULL
;
319 hr
= CoCreateInstance( &CLSID_WbemDefPath
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWbemPath
, (void **)&path
);
320 if (hr
!= S_OK
) return hr
;
322 hr
= IWbemPath_SetText( path
, WBEMPATH_CREATE_ACCEPT_ALL
, str
);
323 if (hr
!= S_OK
) goto done
;
326 hr
= IWbemPath_GetServer( path
, &len
, NULL
);
329 if (!(*server
= SysAllocStringLen( NULL
, len
)))
334 hr
= IWbemPath_GetServer( path
, &len
, *server
);
335 if (hr
!= S_OK
) goto done
;
339 hr
= IWbemPath_GetText( path
, WBEMPATH_GET_NAMESPACE_ONLY
, &len
, NULL
);
342 if (!(*namespace = SysAllocStringLen( NULL
, len
)))
347 hr
= IWbemPath_GetText( path
, WBEMPATH_GET_NAMESPACE_ONLY
, &len
, *namespace );
348 if (hr
!= S_OK
) goto done
;
351 hr
= IWbemPath_GetText( path
, WBEMPATH_GET_RELATIVE_ONLY
, &len
, NULL
);
354 if (!(*relative
= SysAllocStringLen( NULL
, len
)))
359 hr
= IWbemPath_GetText( path
, WBEMPATH_GET_RELATIVE_ONLY
, &len
, *relative
);
363 IWbemPath_Release( path
);
366 SysFreeString( *server
);
367 SysFreeString( *namespace );
368 SysFreeString( *relative
);
373 static HRESULT WINAPI
WinMGMTS_ParseDisplayName(IParseDisplayName
*iface
, IBindCtx
*pbc
, LPOLESTR pszDisplayName
,
374 ULONG
*pchEaten
, IMoniker
**ppmkOut
)
376 static const WCHAR prefixW
[] = {'w','i','n','m','g','m','t','s',':',0};
377 const DWORD prefix_len
= sizeof(prefixW
) / sizeof(prefixW
[0]) - 1;
378 ISWbemLocator
*locator
= NULL
;
379 ISWbemServices
*services
= NULL
;
380 ISWbemObject
*obj
= NULL
;
381 BSTR server
, namespace, relative
;
385 TRACE( "%p, %p, %s, %p, %p\n", iface
, pbc
, debugstr_w(pszDisplayName
), pchEaten
, ppmkOut
);
387 if (strncmpiW( pszDisplayName
, prefixW
, prefix_len
)) return MK_E_SYNTAX
;
389 p
= pszDisplayName
+ prefix_len
;
392 FIXME( "ignoring security settings\n" );
393 while (*p
&& *p
!= '}') p
++;
397 hr
= parse_path( p
, &server
, &namespace, &relative
);
398 if (hr
!= S_OK
) return hr
;
400 hr
= SWbemLocator_create( (void **)&locator
);
401 if (hr
!= S_OK
) goto done
;
403 hr
= ISWbemLocator_ConnectServer( locator
, server
, namespace, NULL
, NULL
, NULL
, NULL
, 0, NULL
, &services
);
404 if (hr
!= S_OK
) goto done
;
406 if (!relative
|| !*relative
) Moniker_create( (IUnknown
*)services
, ppmkOut
);
409 hr
= ISWbemServices_Get( services
, relative
, 0, NULL
, &obj
);
410 if (hr
!= S_OK
) goto done
;
411 hr
= Moniker_create( (IUnknown
*)obj
, ppmkOut
);
415 if (obj
) ISWbemObject_Release( obj
);
416 if (services
) ISWbemServices_Release( services
);
417 if (locator
) ISWbemLocator_Release( locator
);
418 SysFreeString( server
);
419 SysFreeString( namespace );
420 SysFreeString( relative
);
421 if (hr
== S_OK
) *pchEaten
= strlenW( pszDisplayName
);
425 static const IParseDisplayNameVtbl WinMGMTSVtbl
= {
426 WinMGMTS_QueryInterface
,
429 WinMGMTS_ParseDisplayName
432 static IParseDisplayName winmgmts
= { &WinMGMTSVtbl
};
434 static HRESULT
WinMGMTS_create(void **ppv
)
442 IClassFactory IClassFactory_iface
;
443 HRESULT (*fnCreateInstance
)( LPVOID
* );
446 static inline struct factory
*impl_from_IClassFactory( IClassFactory
*iface
)
448 return CONTAINING_RECORD( iface
, struct factory
, IClassFactory_iface
);
451 static HRESULT WINAPI
factory_QueryInterface( IClassFactory
*iface
, REFIID riid
, LPVOID
*obj
)
453 if (IsEqualGUID( riid
, &IID_IUnknown
) || IsEqualGUID( riid
, &IID_IClassFactory
))
455 IClassFactory_AddRef( iface
);
459 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
460 return E_NOINTERFACE
;
463 static ULONG WINAPI
factory_AddRef( IClassFactory
*iface
)
468 static ULONG WINAPI
factory_Release( IClassFactory
*iface
)
473 static HRESULT WINAPI
factory_CreateInstance( IClassFactory
*iface
, LPUNKNOWN outer
, REFIID riid
,
476 struct factory
*factory
= impl_from_IClassFactory( iface
);
480 TRACE( "%p, %s, %p\n", outer
, debugstr_guid(riid
), obj
);
483 if (outer
) return CLASS_E_NOAGGREGATION
;
485 hr
= factory
->fnCreateInstance( (LPVOID
*)&unk
);
489 hr
= IUnknown_QueryInterface( unk
, riid
, obj
);
490 IUnknown_Release( unk
);
494 static HRESULT WINAPI
factory_LockServer( IClassFactory
*iface
, BOOL lock
)
496 FIXME( "%p, %d\n", iface
, lock
);
500 static const struct IClassFactoryVtbl factory_vtbl
=
502 factory_QueryInterface
,
505 factory_CreateInstance
,
509 static struct factory swbem_locator_cf
= { { &factory_vtbl
}, SWbemLocator_create
};
510 static struct factory winmgmts_cf
= { { &factory_vtbl
}, WinMGMTS_create
};
512 BOOL WINAPI
DllMain( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
517 case DLL_WINE_PREATTACH
:
518 return FALSE
; /* prefer native version */
519 case DLL_PROCESS_ATTACH
:
521 DisableThreadLibraryCalls( hinst
);
527 HRESULT WINAPI
DllGetClassObject( REFCLSID rclsid
, REFIID iid
, LPVOID
*obj
)
529 IClassFactory
*cf
= NULL
;
531 TRACE( "%s, %s, %p\n", debugstr_guid(rclsid
), debugstr_guid(iid
), obj
);
533 if (IsEqualGUID( rclsid
, &CLSID_SWbemLocator
))
534 cf
= &swbem_locator_cf
.IClassFactory_iface
;
535 else if (IsEqualGUID( rclsid
, &CLSID_WinMGMTS
))
536 cf
= &winmgmts_cf
.IClassFactory_iface
;
538 return CLASS_E_CLASSNOTAVAILABLE
;
540 return IClassFactory_QueryInterface( cf
, iid
, obj
);
543 /***********************************************************************
544 * DllCanUnloadNow (WBEMDISP.@)
546 HRESULT WINAPI
DllCanUnloadNow(void)
551 /***********************************************************************
552 * DllRegisterServer (WBEMDISP.@)
554 HRESULT WINAPI
DllRegisterServer(void)
556 return __wine_register_resources( instance
);
559 /***********************************************************************
560 * DllUnregisterServer (WBEMDISP.@)
562 HRESULT WINAPI
DllUnregisterServer(void)
564 return __wine_unregister_resources( instance
);