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