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