#include "wbemdisp_private.h"
#include <rpcproxy.h>
+#include <wmiutils.h>
#include <wbemdisp_classes.h>
static HINSTANCE instance;
+struct moniker
+{
+ IMoniker IMoniker_iface;
+ LONG refs;
+ IUnknown *obj;
+};
+
+static inline struct moniker *impl_from_IMoniker(
+ IMoniker *iface )
+{
+ return CONTAINING_RECORD( iface, struct moniker, IMoniker_iface );
+}
+
+static ULONG WINAPI moniker_AddRef(
+ IMoniker *iface )
+{
+ struct moniker *moniker = impl_from_IMoniker( iface );
+ return InterlockedIncrement( &moniker->refs );
+}
+
+static ULONG WINAPI moniker_Release(
+ IMoniker *iface )
+{
+ struct moniker *moniker = impl_from_IMoniker( iface );
+ LONG refs = InterlockedDecrement( &moniker->refs );
+ if (!refs)
+ {
+ TRACE( "destroying %p\n", moniker );
+ IUnknown_Release( moniker->obj );
+ heap_free( moniker );
+ }
+ return refs;
+}
+
+static HRESULT WINAPI moniker_QueryInterface(
+ IMoniker *iface, REFIID riid, void **ppvObject )
+{
+ struct moniker *moniker = impl_from_IMoniker( iface );
+
+ TRACE( "%p, %s, %p\n", moniker, debugstr_guid( riid ), ppvObject );
+
+ if (IsEqualGUID( riid, &IID_IMoniker ) ||
+ IsEqualGUID( riid, &IID_IUnknown ))
+ {
+ *ppvObject = iface;
+ }
+ else
+ {
+ FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
+ return E_NOINTERFACE;
+ }
+ IMoniker_AddRef( iface );
+ return S_OK;
+}
+
+static HRESULT WINAPI moniker_GetClassID(
+ IMoniker *iface, CLSID *pClassID )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_IsDirty(
+ IMoniker *iface )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_Load(
+ IMoniker *iface, IStream *pStm )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_Save(
+ IMoniker *iface, IStream *pStm, BOOL fClearDirty )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_GetSizeMax(
+ IMoniker *iface, ULARGE_INTEGER *pcbSize )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_BindToObject(
+ IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult )
+{
+ struct moniker *moniker = impl_from_IMoniker( iface );
+
+ TRACE( "%p, %p, %p, %s, %p\n", iface, pbc, pmkToLeft, debugstr_guid(riidResult), ppvResult );
+ return IUnknown_QueryInterface( moniker->obj, riidResult, ppvResult );
+}
+
+static HRESULT WINAPI moniker_BindToStorage(
+ IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ppvObj )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_Reduce(
+ IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_ComposeWith(
+ IMoniker *iface, IMoniker *pmkRight, BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_Enum(
+ IMoniker *iface, BOOL fForward, IEnumMoniker **ppenumMoniker )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_IsEqual(
+ IMoniker *iface, IMoniker *pmkOtherMoniker )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_Hash(
+ IMoniker *iface, DWORD *pdwHash )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_IsRunning(
+ IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_GetTimeOfLastChange(
+ IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pFileTime )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_Inverse(
+ IMoniker *iface, IMoniker **ppmk )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_CommonPrefixWith(
+ IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkPrefix )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_RelativePathTo(
+ IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkRelPath )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_GetDisplayName(
+ IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_ParseDisplayName(
+ IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten,
+ IMoniker **ppmkOut )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI moniker_IsSystemMoniker(
+ IMoniker *iface, DWORD *pdwMksys )
+{
+ FIXME( "\n" );
+ return E_NOTIMPL;
+}
+
+static const IMonikerVtbl moniker_vtbl =
+{
+ moniker_QueryInterface,
+ moniker_AddRef,
+ moniker_Release,
+ moniker_GetClassID,
+ moniker_IsDirty,
+ moniker_Load,
+ moniker_Save,
+ moniker_GetSizeMax,
+ moniker_BindToObject,
+ moniker_BindToStorage,
+ moniker_Reduce,
+ moniker_ComposeWith,
+ moniker_Enum,
+ moniker_IsEqual,
+ moniker_Hash,
+ moniker_IsRunning,
+ moniker_GetTimeOfLastChange,
+ moniker_Inverse,
+ moniker_CommonPrefixWith,
+ moniker_RelativePathTo,
+ moniker_GetDisplayName,
+ moniker_ParseDisplayName,
+ moniker_IsSystemMoniker
+};
+
+static HRESULT Moniker_create( IUnknown *unk, IMoniker **obj )
+{
+ struct moniker *moniker;
+
+ TRACE( "%p, %p\n", unk, obj );
+
+ if (!(moniker = heap_alloc( sizeof(*moniker) ))) return E_OUTOFMEMORY;
+ moniker->IMoniker_iface.lpVtbl = &moniker_vtbl;
+ moniker->refs = 1;
+ moniker->obj = unk;
+ IUnknown_AddRef( moniker->obj );
+
+ *obj = &moniker->IMoniker_iface;
+ TRACE( "returning iface %p\n", *obj );
+ return S_OK;
+}
+
static HRESULT WINAPI WinMGMTS_QueryInterface(IParseDisplayName *iface, REFIID riid, void **ppv)
{
if(IsEqualGUID(riid, &IID_IUnknown)) {
return 1;
}
+static HRESULT parse_path( const WCHAR *str, BSTR *server, BSTR *namespace, BSTR *relative )
+{
+ IWbemPath *path;
+ ULONG len;
+ HRESULT hr;
+
+ *server = *namespace = *relative = NULL;
+
+ hr = CoCreateInstance( &CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemPath, (void **)&path );
+ if (hr != S_OK) return hr;
+
+ hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, str );
+ if (hr != S_OK) goto done;
+
+ len = 0;
+ hr = IWbemPath_GetServer( path, &len, NULL );
+ if (hr == S_OK)
+ {
+ if (!(*server = SysAllocStringLen( NULL, len )))
+ {
+ hr = E_OUTOFMEMORY;
+ goto done;
+ }
+ hr = IWbemPath_GetServer( path, &len, *server );
+ if (hr != S_OK) goto done;
+ }
+
+ len = 0;
+ hr = IWbemPath_GetText( path, WBEMPATH_GET_NAMESPACE_ONLY, &len, NULL );
+ if (hr == S_OK)
+ {
+ if (!(*namespace = SysAllocStringLen( NULL, len )))
+ {
+ hr = E_OUTOFMEMORY;
+ goto done;
+ }
+ hr = IWbemPath_GetText( path, WBEMPATH_GET_NAMESPACE_ONLY, &len, *namespace );
+ if (hr != S_OK) goto done;
+ }
+ len = 0;
+ hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, NULL );
+ if (hr == S_OK)
+ {
+ if (!(*relative = SysAllocStringLen( NULL, len )))
+ {
+ hr = E_OUTOFMEMORY;
+ goto done;
+ }
+ hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, *relative );
+ }
+
+done:
+ IWbemPath_Release( path );
+ if (hr != S_OK)
+ {
+ SysFreeString( *server );
+ SysFreeString( *namespace );
+ SysFreeString( *relative );
+ }
+ return hr;
+}
+
static HRESULT WINAPI WinMGMTS_ParseDisplayName(IParseDisplayName *iface, IBindCtx *pbc, LPOLESTR pszDisplayName,
ULONG *pchEaten, IMoniker **ppmkOut)
{
- FIXME("(%p %s %p %p)\n", pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
- return E_NOTIMPL;
+ static const WCHAR prefixW[] = {'w','i','n','m','g','m','t','s',':',0};
+ const DWORD prefix_len = sizeof(prefixW) / sizeof(prefixW[0]) - 1;
+ ISWbemLocator *locator = NULL;
+ ISWbemServices *services = NULL;
+ ISWbemObject *obj = NULL;
+ BSTR server, namespace, relative;
+ WCHAR *p;
+ HRESULT hr;
+
+ TRACE( "%p, %p, %s, %p, %p\n", iface, pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut );
+
+ if (strncmpiW( pszDisplayName, prefixW, prefix_len )) return MK_E_SYNTAX;
+
+ p = pszDisplayName + prefix_len;
+ if (*p == '{')
+ {
+ FIXME( "ignoring security settings\n" );
+ while (*p && *p != '}') p++;
+ if (*p == '}') p++;
+ if (*p == '!') p++;
+ }
+ hr = parse_path( p, &server, &namespace, &relative );
+ if (hr != S_OK) return hr;
+
+ hr = SWbemLocator_create( (void **)&locator );
+ if (hr != S_OK) goto done;
+
+ hr = ISWbemLocator_ConnectServer( locator, server, namespace, NULL, NULL, NULL, NULL, 0, NULL, &services );
+ if (hr != S_OK) goto done;
+
+ if (!relative || !*relative) Moniker_create( (IUnknown *)services, ppmkOut );
+ else
+ {
+ hr = ISWbemServices_Get( services, relative, 0, NULL, &obj );
+ if (hr != S_OK) goto done;
+ hr = Moniker_create( (IUnknown *)obj, ppmkOut );
+ }
+
+done:
+ if (obj) ISWbemObject_Release( obj );
+ if (services) ISWbemServices_Release( services );
+ if (locator) ISWbemLocator_Release( locator );
+ SysFreeString( server );
+ SysFreeString( namespace );
+ SysFreeString( relative );
+ if (hr == S_OK) *pchEaten = strlenW( pszDisplayName );
+ return hr;
}
static const IParseDisplayNameVtbl WinMGMTSVtbl = {