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