xref: /reactos/dll/win32/wbemdisp/main.c (revision 177ae91b)
1 /*
2  * Copyright 2013 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 #include <stdarg.h>
20 
21 #define COBJMACROS
22 
23 #include "windef.h"
24 #include "winbase.h"
25 #include "objbase.h"
26 #include "wmiutils.h"
27 #include "wbemdisp.h"
28 #include "rpcproxy.h"
29 
30 #include "wine/debug.h"
31 #include "wine/heap.h"
32 #include "wbemdisp_private.h"
33 #include "wbemdisp_classes.h"
34 
35 WINE_DEFAULT_DEBUG_CHANNEL(wbemdisp);
36 
37 static HINSTANCE instance;
38 
39 struct moniker
40 {
41     IMoniker IMoniker_iface;
42     LONG refs;
43     IUnknown *obj;
44 };
45 
46 static inline struct moniker *impl_from_IMoniker(
47     IMoniker *iface )
48 {
49     return CONTAINING_RECORD( iface, struct moniker, IMoniker_iface );
50 }
51 
52 static ULONG WINAPI moniker_AddRef(
53     IMoniker *iface )
54 {
55     struct moniker *moniker = impl_from_IMoniker( iface );
56     return InterlockedIncrement( &moniker->refs );
57 }
58 
59 static ULONG WINAPI moniker_Release(
60     IMoniker *iface )
61 {
62     struct moniker *moniker = impl_from_IMoniker( iface );
63     LONG refs = InterlockedDecrement( &moniker->refs );
64     if (!refs)
65     {
66         TRACE( "destroying %p\n", moniker );
67         IUnknown_Release( moniker->obj );
68         heap_free( moniker );
69     }
70     return refs;
71 }
72 
73 static HRESULT WINAPI moniker_QueryInterface(
74     IMoniker *iface, REFIID riid, void **ppvObject )
75 {
76     struct moniker *moniker = impl_from_IMoniker( iface );
77 
78     TRACE( "%p, %s, %p\n", moniker, debugstr_guid( riid ), ppvObject );
79 
80     if (IsEqualGUID( riid, &IID_IMoniker ) ||
81         IsEqualGUID( riid, &IID_IUnknown ))
82     {
83         *ppvObject = iface;
84     }
85     else
86     {
87         FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
88         return E_NOINTERFACE;
89     }
90     IMoniker_AddRef( iface );
91     return S_OK;
92 }
93 
94 static HRESULT WINAPI moniker_GetClassID(
95     IMoniker *iface, CLSID *pClassID )
96 {
97     FIXME( "\n" );
98     return E_NOTIMPL;
99 }
100 
101 static HRESULT WINAPI moniker_IsDirty(
102     IMoniker *iface )
103 {
104     FIXME( "\n" );
105     return E_NOTIMPL;
106 }
107 
108 static HRESULT WINAPI moniker_Load(
109     IMoniker *iface, IStream *pStm )
110 {
111     FIXME( "\n" );
112     return E_NOTIMPL;
113 }
114 
115 static HRESULT WINAPI moniker_Save(
116     IMoniker *iface, IStream *pStm, BOOL fClearDirty )
117 {
118     FIXME( "\n" );
119     return E_NOTIMPL;
120 }
121 
122 static HRESULT WINAPI moniker_GetSizeMax(
123     IMoniker *iface, ULARGE_INTEGER *pcbSize )
124 {
125     FIXME( "\n" );
126     return E_NOTIMPL;
127 }
128 
129 static HRESULT WINAPI moniker_BindToObject(
130     IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult )
131 {
132     struct moniker *moniker = impl_from_IMoniker( iface );
133 
134     TRACE( "%p, %p, %p, %s, %p\n", iface, pbc, pmkToLeft, debugstr_guid(riidResult), ppvResult );
135     return IUnknown_QueryInterface( moniker->obj, riidResult, ppvResult );
136 }
137 
138 static HRESULT WINAPI moniker_BindToStorage(
139     IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ppvObj )
140 {
141     FIXME( "\n" );
142     return E_NOTIMPL;
143 }
144 
145 static HRESULT WINAPI moniker_Reduce(
146     IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced )
147 {
148     FIXME( "\n" );
149     return E_NOTIMPL;
150 }
151 
152 static HRESULT WINAPI moniker_ComposeWith(
153     IMoniker *iface, IMoniker *pmkRight, BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite )
154 {
155     FIXME( "\n" );
156     return E_NOTIMPL;
157 }
158 
159 static HRESULT WINAPI moniker_Enum(
160     IMoniker *iface, BOOL fForward, IEnumMoniker **ppenumMoniker )
161 {
162     FIXME( "\n" );
163     return E_NOTIMPL;
164 }
165 
166 static HRESULT WINAPI moniker_IsEqual(
167     IMoniker *iface, IMoniker *pmkOtherMoniker )
168 {
169     FIXME( "\n" );
170     return E_NOTIMPL;
171 }
172 
173 static HRESULT WINAPI moniker_Hash(
174     IMoniker *iface, DWORD *pdwHash )
175 {
176     FIXME( "\n" );
177     return E_NOTIMPL;
178 }
179 
180 static HRESULT WINAPI moniker_IsRunning(
181     IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning )
182 {
183     FIXME( "\n" );
184     return E_NOTIMPL;
185 }
186 
187 static HRESULT WINAPI moniker_GetTimeOfLastChange(
188     IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pFileTime )
189 {
190     FIXME( "\n" );
191     return E_NOTIMPL;
192 }
193 
194 static HRESULT WINAPI moniker_Inverse(
195     IMoniker *iface, IMoniker **ppmk )
196 {
197     FIXME( "\n" );
198     return E_NOTIMPL;
199 }
200 
201 static HRESULT WINAPI moniker_CommonPrefixWith(
202     IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkPrefix )
203 {
204     FIXME( "\n" );
205     return E_NOTIMPL;
206 }
207 
208 static HRESULT WINAPI moniker_RelativePathTo(
209     IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkRelPath )
210 {
211     FIXME( "\n" );
212     return E_NOTIMPL;
213 }
214 
215 static HRESULT WINAPI moniker_GetDisplayName(
216     IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName )
217 {
218     FIXME( "\n" );
219     return E_NOTIMPL;
220 }
221 
222 static HRESULT WINAPI moniker_ParseDisplayName(
223     IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten,
224     IMoniker **ppmkOut )
225 {
226     FIXME( "\n" );
227     return E_NOTIMPL;
228 }
229 
230 static HRESULT WINAPI moniker_IsSystemMoniker(
231     IMoniker *iface, DWORD *pdwMksys )
232 {
233     FIXME( "\n" );
234     return E_NOTIMPL;
235 }
236 
237 static const IMonikerVtbl moniker_vtbl =
238 {
239     moniker_QueryInterface,
240     moniker_AddRef,
241     moniker_Release,
242     moniker_GetClassID,
243     moniker_IsDirty,
244     moniker_Load,
245     moniker_Save,
246     moniker_GetSizeMax,
247     moniker_BindToObject,
248     moniker_BindToStorage,
249     moniker_Reduce,
250     moniker_ComposeWith,
251     moniker_Enum,
252     moniker_IsEqual,
253     moniker_Hash,
254     moniker_IsRunning,
255     moniker_GetTimeOfLastChange,
256     moniker_Inverse,
257     moniker_CommonPrefixWith,
258     moniker_RelativePathTo,
259     moniker_GetDisplayName,
260     moniker_ParseDisplayName,
261     moniker_IsSystemMoniker
262 };
263 
264 static HRESULT Moniker_create( IUnknown *unk, IMoniker **obj )
265 {
266     struct moniker *moniker;
267 
268     TRACE( "%p, %p\n", unk, obj );
269 
270     if (!(moniker = heap_alloc( sizeof(*moniker) ))) return E_OUTOFMEMORY;
271     moniker->IMoniker_iface.lpVtbl = &moniker_vtbl;
272     moniker->refs = 1;
273     moniker->obj = unk;
274     IUnknown_AddRef( moniker->obj );
275 
276     *obj = &moniker->IMoniker_iface;
277     TRACE( "returning iface %p\n", *obj );
278     return S_OK;
279 }
280 
281 static HRESULT WINAPI WinMGMTS_QueryInterface(IParseDisplayName *iface, REFIID riid, void **ppv)
282 {
283     if(IsEqualGUID(riid, &IID_IUnknown)) {
284         TRACE("(IID_IUnknown %p)\n", ppv);
285         *ppv = iface;
286     }else if(IsEqualGUID(riid, &IID_IParseDisplayName)) {
287         TRACE("(IID_IParseDisplayName %p)\n", ppv);
288         *ppv = iface;
289     }else {
290         WARN("Unsupported riid %s\n", debugstr_guid(riid));
291         *ppv = NULL;
292         return E_NOINTERFACE;
293     }
294 
295     IUnknown_AddRef((IUnknown*)*ppv);
296     return S_OK;
297 }
298 
299 static ULONG WINAPI WinMGMTS_AddRef(IParseDisplayName *iface)
300 {
301     return 2;
302 }
303 
304 static ULONG WINAPI WinMGMTS_Release(IParseDisplayName *iface)
305 {
306     return 1;
307 }
308 
309 static HRESULT parse_path( const WCHAR *str, BSTR *server, BSTR *namespace, BSTR *relative )
310 {
311     IWbemPath *path;
312     ULONG len;
313     HRESULT hr;
314 
315     *server = *namespace = *relative = NULL;
316 
317     hr = CoCreateInstance( &CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemPath, (void **)&path );
318     if (hr != S_OK) return hr;
319 
320     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, str );
321     if (hr != S_OK) goto done;
322 
323     len = 0;
324     hr = IWbemPath_GetServer( path, &len, NULL );
325     if (hr == S_OK)
326     {
327         if (!(*server = SysAllocStringLen( NULL, len )))
328         {
329             hr = E_OUTOFMEMORY;
330             goto done;
331         }
332         hr = IWbemPath_GetServer( path, &len, *server );
333         if (hr != S_OK) goto done;
334     }
335 
336     len = 0;
337     hr = IWbemPath_GetText( path, WBEMPATH_GET_NAMESPACE_ONLY, &len, NULL );
338     if (hr == S_OK)
339     {
340         if (!(*namespace = SysAllocStringLen( NULL, len )))
341         {
342             hr = E_OUTOFMEMORY;
343             goto done;
344         }
345         hr = IWbemPath_GetText( path, WBEMPATH_GET_NAMESPACE_ONLY, &len, *namespace );
346         if (hr != S_OK) goto done;
347     }
348     len = 0;
349     hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, NULL );
350     if (hr == S_OK)
351     {
352         if (!(*relative = SysAllocStringLen( NULL, len )))
353         {
354             hr = E_OUTOFMEMORY;
355             goto done;
356         }
357         hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, *relative );
358     }
359 
360 done:
361     IWbemPath_Release( path );
362     if (hr != S_OK)
363     {
364         SysFreeString( *server );
365         SysFreeString( *namespace );
366         SysFreeString( *relative );
367     }
368     return hr;
369 }
370 
371 static HRESULT WINAPI WinMGMTS_ParseDisplayName(IParseDisplayName *iface, IBindCtx *pbc, LPOLESTR pszDisplayName,
372         ULONG *pchEaten, IMoniker **ppmkOut)
373 {
374     static const WCHAR prefixW[] = {'w','i','n','m','g','m','t','s',':',0};
375     const DWORD prefix_len = ARRAY_SIZE(prefixW) - 1;
376     ISWbemLocator *locator = NULL;
377     ISWbemServices *services = NULL;
378     ISWbemObject *obj = NULL;
379     BSTR server, namespace, relative;
380     WCHAR *p;
381     HRESULT hr;
382 
383     TRACE( "%p, %p, %s, %p, %p\n", iface, pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut );
384 
385     if (_wcsnicmp( pszDisplayName, prefixW, prefix_len )) return MK_E_SYNTAX;
386 
387     p = pszDisplayName + prefix_len;
388     if (*p == '{')
389     {
390         FIXME( "ignoring security settings\n" );
391         while (*p && *p != '}') p++;
392         if (*p == '}') p++;
393         if (*p == '!') p++;
394     }
395     hr = parse_path( p, &server, &namespace, &relative );
396     if (hr != S_OK) return hr;
397 
398     hr = SWbemLocator_create( (void **)&locator );
399     if (hr != S_OK) goto done;
400 
401     hr = ISWbemLocator_ConnectServer( locator, server, namespace, NULL, NULL, NULL, NULL, 0, NULL, &services );
402     if (hr != S_OK) goto done;
403 
404     if (!relative || !*relative) Moniker_create( (IUnknown *)services, ppmkOut );
405     else
406     {
407         hr = ISWbemServices_Get( services, relative, 0, NULL, &obj );
408         if (hr != S_OK) goto done;
409         hr = Moniker_create( (IUnknown *)obj, ppmkOut );
410     }
411 
412 done:
413     if (obj) ISWbemObject_Release( obj );
414     if (services) ISWbemServices_Release( services );
415     if (locator) ISWbemLocator_Release( locator );
416     SysFreeString( server );
417     SysFreeString( namespace );
418     SysFreeString( relative );
419     if (hr == S_OK) *pchEaten = lstrlenW( pszDisplayName );
420     return hr;
421 }
422 
423 static const IParseDisplayNameVtbl WinMGMTSVtbl = {
424     WinMGMTS_QueryInterface,
425     WinMGMTS_AddRef,
426     WinMGMTS_Release,
427     WinMGMTS_ParseDisplayName
428 };
429 
430 static IParseDisplayName winmgmts = { &WinMGMTSVtbl };
431 
432 static HRESULT WinMGMTS_create(void **ppv)
433 {
434     *ppv = &winmgmts;
435     return S_OK;
436 }
437 
438 struct factory
439 {
440     IClassFactory IClassFactory_iface;
441     HRESULT (*fnCreateInstance)( LPVOID * );
442 };
443 
444 static inline struct factory *impl_from_IClassFactory( IClassFactory *iface )
445 {
446     return CONTAINING_RECORD( iface, struct factory, IClassFactory_iface );
447 }
448 
449 static HRESULT WINAPI factory_QueryInterface( IClassFactory *iface, REFIID riid, LPVOID *obj )
450 {
451     if (IsEqualGUID( riid, &IID_IUnknown ) || IsEqualGUID( riid, &IID_IClassFactory ))
452     {
453         IClassFactory_AddRef( iface );
454         *obj = iface;
455         return S_OK;
456     }
457     FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
458     return E_NOINTERFACE;
459 }
460 
461 static ULONG WINAPI factory_AddRef( IClassFactory *iface )
462 {
463     return 2;
464 }
465 
466 static ULONG WINAPI factory_Release( IClassFactory *iface )
467 {
468     return 1;
469 }
470 
471 static HRESULT WINAPI factory_CreateInstance( IClassFactory *iface, LPUNKNOWN outer, REFIID riid,
472                                               LPVOID *obj )
473 {
474     struct factory *factory = impl_from_IClassFactory( iface );
475     IUnknown *unk;
476     HRESULT hr;
477 
478     TRACE( "%p, %s, %p\n", outer, debugstr_guid(riid), obj );
479 
480     *obj = NULL;
481     if (outer) return CLASS_E_NOAGGREGATION;
482 
483     hr = factory->fnCreateInstance( (LPVOID *)&unk );
484     if (FAILED( hr ))
485         return hr;
486 
487     hr = IUnknown_QueryInterface( unk, riid, obj );
488     IUnknown_Release( unk );
489     return hr;
490 }
491 
492 static HRESULT WINAPI factory_LockServer( IClassFactory *iface, BOOL lock )
493 {
494     FIXME( "%p, %d\n", iface, lock );
495     return S_OK;
496 }
497 
498 static const struct IClassFactoryVtbl factory_vtbl =
499 {
500     factory_QueryInterface,
501     factory_AddRef,
502     factory_Release,
503     factory_CreateInstance,
504     factory_LockServer
505 };
506 
507 static struct factory swbem_locator_cf = { { &factory_vtbl }, SWbemLocator_create };
508 static struct factory winmgmts_cf = { { &factory_vtbl }, WinMGMTS_create };
509 
510 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
511 {
512 
513     switch (reason)
514     {
515         case DLL_WINE_PREATTACH:
516             return FALSE;    /* prefer native version */
517         case DLL_PROCESS_ATTACH:
518             instance = hinst;
519             DisableThreadLibraryCalls( hinst );
520             break;
521     }
522     return TRUE;
523 }
524 
525 HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *obj )
526 {
527     IClassFactory *cf = NULL;
528 
529     TRACE( "%s, %s, %p\n", debugstr_guid(rclsid), debugstr_guid(iid), obj );
530 
531     if (IsEqualGUID( rclsid, &CLSID_SWbemLocator ))
532         cf = &swbem_locator_cf.IClassFactory_iface;
533     else if (IsEqualGUID( rclsid, &CLSID_WinMGMTS ))
534         cf = &winmgmts_cf.IClassFactory_iface;
535     else
536         return CLASS_E_CLASSNOTAVAILABLE;
537 
538     return IClassFactory_QueryInterface( cf, iid, obj );
539 }
540 
541 /***********************************************************************
542  *      DllCanUnloadNow (WBEMDISP.@)
543  */
544 HRESULT WINAPI DllCanUnloadNow(void)
545 {
546     return S_FALSE;
547 }
548 
549 /***********************************************************************
550  *      DllRegisterServer (WBEMDISP.@)
551  */
552 HRESULT WINAPI DllRegisterServer(void)
553 {
554     return __wine_register_resources( instance );
555 }
556 
557 /***********************************************************************
558  *      DllUnregisterServer (WBEMDISP.@)
559  */
560 HRESULT WINAPI DllUnregisterServer(void)
561 {
562     return __wine_unregister_resources( instance );
563 }
564