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