[COMCTL32] Pt.rc: Place accelerator FIXMEs
[reactos.git] / 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 <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 }