2007-04-20 12:23:52 +00:00
|
|
|
/*
|
|
|
|
* Class Monikers
|
|
|
|
*
|
|
|
|
* Copyright 1999 Noomen Hamza
|
|
|
|
* Copyright 2005-2007 Robert Shearman
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#define COBJMACROS
|
|
|
|
#define NONAMELESSUNION
|
|
|
|
#define NONAMELESSSTRUCT
|
|
|
|
|
|
|
|
#include "winerror.h"
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "winuser.h"
|
|
|
|
#include "wine/debug.h"
|
|
|
|
#include "ole2.h"
|
|
|
|
#include "wine/unicode.h"
|
|
|
|
#include "moniker.h"
|
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|
|
|
|
|
|
|
#define CHARS_IN_GUID 39
|
|
|
|
|
|
|
|
/* ClassMoniker data structure */
|
|
|
|
typedef struct ClassMoniker
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
IMoniker IMoniker_iface;
|
|
|
|
IROTData IROTData_iface;
|
|
|
|
LONG ref;
|
2007-04-20 12:23:52 +00:00
|
|
|
CLSID clsid; /* clsid identified by this moniker */
|
|
|
|
IUnknown *pMarshal; /* custom marshaler */
|
|
|
|
} ClassMoniker;
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static inline ClassMoniker *impl_from_IMoniker(IMoniker *iface)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
return CONTAINING_RECORD(iface, ClassMoniker, IMoniker_iface);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline ClassMoniker *impl_from_IROTData(IROTData *iface)
|
|
|
|
{
|
|
|
|
return CONTAINING_RECORD(iface, ClassMoniker, IROTData_iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* ClassMoniker_QueryInterface
|
|
|
|
*******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IMoniker(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
|
|
|
|
|
|
|
|
/* Perform a sanity check on the parameters.*/
|
|
|
|
if (!ppvObject)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
/* Initialize the return parameter */
|
|
|
|
*ppvObject = 0;
|
|
|
|
|
|
|
|
/* Compare the riid with the interface IDs implemented by this object.*/
|
|
|
|
if (IsEqualIID(&IID_IUnknown, riid) ||
|
|
|
|
IsEqualIID(&IID_IPersist, riid) ||
|
|
|
|
IsEqualIID(&IID_IPersistStream, riid) ||
|
|
|
|
IsEqualIID(&IID_IMoniker, riid))
|
|
|
|
{
|
|
|
|
*ppvObject = iface;
|
|
|
|
}
|
|
|
|
else if (IsEqualIID(&IID_IROTData, riid))
|
2012-05-17 15:16:51 +00:00
|
|
|
*ppvObject = &This->IROTData_iface;
|
2007-04-20 12:23:52 +00:00
|
|
|
else if (IsEqualIID(&IID_IMarshal, riid))
|
|
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (!This->pMarshal)
|
|
|
|
hr = MonikerMarshal_Create(iface, &This->pMarshal);
|
|
|
|
if (hr != S_OK)
|
|
|
|
return hr;
|
|
|
|
return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check that we obtained an interface.*/
|
|
|
|
if (!*ppvObject)
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
|
|
|
|
/* Query Interface always increases the reference count by one when it is successful */
|
|
|
|
IMoniker_AddRef(iface);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_AddRef
|
|
|
|
******************************************************************************/
|
|
|
|
static ULONG WINAPI ClassMoniker_AddRef(IMoniker* iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IMoniker(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n",This);
|
|
|
|
|
|
|
|
return InterlockedIncrement(&This->ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_Destroy (local function)
|
|
|
|
*******************************************************************************/
|
2009-01-15 17:52:35 +00:00
|
|
|
static HRESULT ClassMoniker_Destroy(ClassMoniker* This)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
TRACE("(%p)\n",This);
|
|
|
|
|
|
|
|
if (This->pMarshal) IUnknown_Release(This->pMarshal);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(),0,This);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_Release
|
|
|
|
******************************************************************************/
|
|
|
|
static ULONG WINAPI ClassMoniker_Release(IMoniker* iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IMoniker(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
ULONG ref;
|
|
|
|
|
|
|
|
TRACE("(%p)\n",This);
|
|
|
|
|
|
|
|
ref = InterlockedDecrement(&This->ref);
|
|
|
|
|
|
|
|
/* destroy the object if there's no more reference on it */
|
|
|
|
if (ref == 0) ClassMoniker_Destroy(This);
|
|
|
|
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_GetClassID
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_GetClassID(IMoniker* iface,CLSID *pClassID)
|
|
|
|
{
|
|
|
|
TRACE("(%p,%p),stub!\n",iface,pClassID);
|
|
|
|
|
|
|
|
if (pClassID==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*pClassID = CLSID_ClassMoniker;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_IsDirty
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_IsDirty(IMoniker* iface)
|
|
|
|
{
|
|
|
|
/* Note that the OLE-provided implementations of the IPersistStream::IsDirty
|
|
|
|
method in the OLE-provided moniker interfaces always return S_FALSE because
|
|
|
|
their internal state never changes. */
|
|
|
|
|
|
|
|
TRACE("(%p)\n",iface);
|
|
|
|
|
|
|
|
return S_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_Load
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_Load(IMoniker* iface,IStream* pStm)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IMoniker(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
HRESULT hr;
|
|
|
|
DWORD zero;
|
|
|
|
|
|
|
|
TRACE("(%p)\n", pStm);
|
|
|
|
|
|
|
|
hr = IStream_Read(pStm, &This->clsid, sizeof(This->clsid), NULL);
|
|
|
|
if (hr != S_OK) return STG_E_READFAULT;
|
|
|
|
|
|
|
|
hr = IStream_Read(pStm, &zero, sizeof(zero), NULL);
|
|
|
|
if ((hr != S_OK) || (zero != 0)) return STG_E_READFAULT;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_Save
|
|
|
|
******************************************************************************/
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI ClassMoniker_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IMoniker(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
HRESULT hr;
|
|
|
|
DWORD zero = 0;
|
|
|
|
|
|
|
|
TRACE("(%p, %s)\n", pStm, fClearDirty ? "TRUE" : "FALSE");
|
|
|
|
|
|
|
|
hr = IStream_Write(pStm, &This->clsid, sizeof(This->clsid), NULL);
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
return IStream_Write(pStm, &zero, sizeof(zero), NULL);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_GetSizeMax
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_GetSizeMax(IMoniker* iface,
|
|
|
|
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
|
|
|
|
{
|
|
|
|
TRACE("(%p)\n", pcbSize);
|
|
|
|
|
|
|
|
pcbSize->QuadPart = sizeof(CLSID) + sizeof(DWORD);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_BindToObject
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_BindToObject(IMoniker* iface,
|
|
|
|
IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft,
|
|
|
|
REFIID riid,
|
|
|
|
VOID** ppvResult)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IMoniker(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
BIND_OPTS2 bindopts;
|
|
|
|
IClassActivator *pActivator;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
TRACE("(%p,%p,%p,%p)\n", pbc, pmkToLeft, riid, ppvResult);
|
|
|
|
|
|
|
|
bindopts.cbStruct = sizeof(bindopts);
|
|
|
|
IBindCtx_GetBindOptions(pbc, (BIND_OPTS *)&bindopts);
|
|
|
|
|
|
|
|
if (!pmkToLeft)
|
|
|
|
return CoGetClassObject(&This->clsid, bindopts.dwClassContext, NULL,
|
|
|
|
riid, ppvResult);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassActivator,
|
|
|
|
(void **)&pActivator);
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
|
|
|
|
hr = IClassActivator_GetClassObject(pActivator, &This->clsid,
|
|
|
|
bindopts.dwClassContext,
|
|
|
|
bindopts.locale, riid, ppvResult);
|
|
|
|
|
|
|
|
IClassActivator_Release(pActivator);
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_BindToStorage
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_BindToStorage(IMoniker* iface,
|
|
|
|
IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft,
|
|
|
|
REFIID riid,
|
|
|
|
VOID** ppvResult)
|
|
|
|
{
|
|
|
|
TRACE("(%p,%p,%p,%p)\n",pbc, pmkToLeft, riid, ppvResult);
|
|
|
|
return ClassMoniker_BindToObject(iface, pbc, pmkToLeft, riid, ppvResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_Reduce
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_Reduce(IMoniker* iface,
|
|
|
|
IBindCtx* pbc,
|
|
|
|
DWORD dwReduceHowFar,
|
|
|
|
IMoniker** ppmkToLeft,
|
|
|
|
IMoniker** ppmkReduced)
|
|
|
|
{
|
|
|
|
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
|
|
|
|
|
|
|
|
if (!ppmkReduced)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
ClassMoniker_AddRef(iface);
|
|
|
|
|
|
|
|
*ppmkReduced = iface;
|
|
|
|
|
|
|
|
return MK_S_REDUCED_TO_SELF;
|
|
|
|
}
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_ComposeWith
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_ComposeWith(IMoniker* iface,
|
|
|
|
IMoniker* pmkRight,
|
|
|
|
BOOL fOnlyIfNotGeneric,
|
|
|
|
IMoniker** ppmkComposite)
|
|
|
|
{
|
|
|
|
HRESULT res=S_OK;
|
|
|
|
DWORD mkSys,mkSys2;
|
|
|
|
IEnumMoniker* penumMk=0;
|
|
|
|
IMoniker *pmostLeftMk=0;
|
|
|
|
IMoniker* tempMkComposite=0;
|
|
|
|
|
|
|
|
TRACE("(%p,%d,%p)\n", pmkRight, fOnlyIfNotGeneric, ppmkComposite);
|
|
|
|
|
|
|
|
if ((ppmkComposite==NULL)||(pmkRight==NULL))
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppmkComposite=0;
|
|
|
|
|
|
|
|
IMoniker_IsSystemMoniker(pmkRight,&mkSys);
|
|
|
|
|
|
|
|
/* If pmkRight is an anti-moniker, the returned moniker is NULL */
|
|
|
|
if(mkSys==MKSYS_ANTIMONIKER)
|
|
|
|
return res;
|
|
|
|
|
|
|
|
else
|
|
|
|
/* if pmkRight is a composite whose leftmost component is an anti-moniker, */
|
|
|
|
/* the returned moniker is the composite after the leftmost anti-moniker is removed. */
|
|
|
|
|
|
|
|
if(mkSys==MKSYS_GENERICCOMPOSITE){
|
|
|
|
|
|
|
|
res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
|
|
|
|
|
|
|
|
if (FAILED(res))
|
|
|
|
return res;
|
|
|
|
|
|
|
|
res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
|
|
|
|
|
|
|
|
IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
|
|
|
|
|
|
|
|
if(mkSys2==MKSYS_ANTIMONIKER){
|
|
|
|
|
|
|
|
IMoniker_Release(pmostLeftMk);
|
|
|
|
|
|
|
|
tempMkComposite=iface;
|
|
|
|
IMoniker_AddRef(iface);
|
|
|
|
|
|
|
|
while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
|
|
|
|
|
|
|
|
res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
|
|
|
|
|
|
|
|
IMoniker_Release(tempMkComposite);
|
|
|
|
IMoniker_Release(pmostLeftMk);
|
|
|
|
|
|
|
|
tempMkComposite=*ppmkComposite;
|
|
|
|
IMoniker_AddRef(tempMkComposite);
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
|
|
|
|
}
|
|
|
|
/* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
|
|
|
|
composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
|
|
|
|
a NULL moniker and a return value of MK_E_NEEDGENERIC */
|
|
|
|
else
|
|
|
|
if (!fOnlyIfNotGeneric)
|
|
|
|
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
|
|
|
|
|
|
|
|
else
|
|
|
|
return MK_E_NEEDGENERIC;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_Enum
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
|
|
|
|
{
|
|
|
|
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
|
|
|
|
|
|
|
|
if (ppenumMoniker == NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppenumMoniker = NULL;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_IsEqual
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
|
|
|
|
{
|
|
|
|
|
|
|
|
CLSID clsid;
|
|
|
|
LPOLESTR dispName1,dispName2;
|
|
|
|
IBindCtx* bind;
|
|
|
|
HRESULT res = S_FALSE;
|
|
|
|
|
|
|
|
TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
|
|
|
|
|
|
|
|
if (!pmkOtherMoniker) return S_FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
/* check if both are ClassMoniker */
|
|
|
|
if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE;
|
|
|
|
if(!IsEqualCLSID(&clsid,&CLSID_ClassMoniker)) return S_FALSE;
|
|
|
|
|
|
|
|
/* check if both displaynames are the same */
|
|
|
|
if(SUCCEEDED ((res = CreateBindCtx(0,&bind)))) {
|
|
|
|
if(SUCCEEDED (IMoniker_GetDisplayName(iface,bind,NULL,&dispName1))) {
|
|
|
|
if(SUCCEEDED (IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2))) {
|
|
|
|
if(lstrcmpW(dispName1,dispName2)==0) res = S_OK;
|
|
|
|
CoTaskMemFree(dispName2);
|
|
|
|
}
|
|
|
|
CoTaskMemFree(dispName1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_Hash
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_Hash(IMoniker* iface,DWORD* pdwHash)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IMoniker(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n", pdwHash);
|
|
|
|
|
|
|
|
*pdwHash = This->clsid.Data1;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_IsRunning
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_IsRunning(IMoniker* iface,
|
|
|
|
IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft,
|
|
|
|
IMoniker* pmkNewlyRunning)
|
|
|
|
{
|
|
|
|
TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, pmkNewlyRunning);
|
|
|
|
|
|
|
|
/* as in native */
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_GetTimeOfLastChange
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_GetTimeOfLastChange(IMoniker* iface,
|
|
|
|
IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft,
|
|
|
|
FILETIME* pItemTime)
|
|
|
|
{
|
|
|
|
TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, pItemTime);
|
|
|
|
|
|
|
|
return MK_E_UNAVAILABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_Inverse
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_Inverse(IMoniker* iface,IMoniker** ppmk)
|
|
|
|
{
|
|
|
|
TRACE("(%p)\n",ppmk);
|
|
|
|
|
|
|
|
if (!ppmk)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
return CreateAntiMoniker(ppmk);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_CommonPrefixWith
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
|
|
|
|
{
|
|
|
|
DWORD mkSys;
|
2008-01-14 15:45:45 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %p)\n", pmkOther, ppmkPrefix);
|
|
|
|
|
|
|
|
*ppmkPrefix = NULL;
|
|
|
|
|
|
|
|
IMoniker_IsSystemMoniker(pmkOther, &mkSys);
|
|
|
|
|
|
|
|
/* If the other moniker is an class moniker that is equal to this moniker, this method sets *ppmkPrefix */
|
|
|
|
/* to this moniker and returns MK_S_US */
|
|
|
|
|
|
|
|
if (mkSys == MKSYS_CLASSMONIKER)
|
|
|
|
{
|
|
|
|
if (IMoniker_IsEqual(iface, pmkOther) == S_OK)
|
|
|
|
{
|
|
|
|
*ppmkPrefix = iface;
|
|
|
|
|
|
|
|
IMoniker_AddRef(iface);
|
|
|
|
|
|
|
|
return MK_S_US;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return MK_E_NOPREFIX;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
/* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
|
|
|
|
/* the case where the other moniker is a generic composite. */
|
|
|
|
return MonikerCommonPrefixWith(iface, pmkOther, ppmkPrefix);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_RelativePathTo
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
|
|
|
|
{
|
|
|
|
TRACE("(%p, %p)\n",pmOther,ppmkRelPath);
|
|
|
|
|
|
|
|
if (!ppmkRelPath)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppmkRelPath = NULL;
|
|
|
|
|
|
|
|
return MK_E_NOTBINDABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_GetDisplayName
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_GetDisplayName(IMoniker* iface,
|
|
|
|
IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft,
|
|
|
|
LPOLESTR *ppszDisplayName)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IMoniker(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
static const WCHAR wszClsidPrefix[] = {'c','l','s','i','d',':',0};
|
|
|
|
|
|
|
|
TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, ppszDisplayName);
|
|
|
|
|
|
|
|
if (!ppszDisplayName)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
if (pmkToLeft)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
*ppszDisplayName = CoTaskMemAlloc(sizeof(wszClsidPrefix) + (CHARS_IN_GUID-2) * sizeof(WCHAR));
|
|
|
|
|
|
|
|
StringFromGUID2(&This->clsid, *ppszDisplayName+sizeof(wszClsidPrefix)/sizeof(WCHAR)-2, CHARS_IN_GUID);
|
|
|
|
|
|
|
|
/* note: this overwrites the opening curly bracket of the CLSID string generated above */
|
|
|
|
memcpy(*ppszDisplayName, wszClsidPrefix, sizeof(wszClsidPrefix)-sizeof(WCHAR));
|
|
|
|
|
|
|
|
/* note: this overwrites the closing curly bracket of the CLSID string generated above */
|
|
|
|
(*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-2] = ':';
|
|
|
|
(*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-1] = '\0';
|
|
|
|
|
|
|
|
TRACE("string is %s\n", debugstr_w(*ppszDisplayName));
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_ParseDisplayName
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_ParseDisplayName(IMoniker* iface,
|
|
|
|
IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft,
|
|
|
|
LPOLESTR pszDisplayName,
|
|
|
|
ULONG* pchEaten,
|
|
|
|
IMoniker** ppmkOut)
|
|
|
|
{
|
|
|
|
FIXME("(%p, %p, %s, %p, %p)\n", pbc, pmkToLeft, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_IsSystemMoniker
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMoniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
|
|
|
|
{
|
|
|
|
TRACE("(%p,%p)\n",iface,pwdMksys);
|
|
|
|
|
|
|
|
if (!pwdMksys)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*pwdMksys = MKSYS_CLASSMONIKER;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* ClassMonikerIROTData_QueryInterface
|
|
|
|
*******************************************************************************/
|
|
|
|
static HRESULT WINAPI ClassMonikerROTData_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
|
|
|
|
{
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IROTData(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return ClassMoniker_QueryInterface(&This->IMoniker_iface, riid, ppvObject);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ClassMonikerIROTData_AddRef
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI ClassMonikerROTData_AddRef(IROTData *iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IROTData(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n",iface);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return ClassMoniker_AddRef(&This->IMoniker_iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ClassMonikerIROTData_Release
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI ClassMonikerROTData_Release(IROTData* iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IROTData(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n",iface);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return ClassMoniker_Release(&This->IMoniker_iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
2008-07-10 09:14:19 +00:00
|
|
|
* ClassMonikerIROTData_GetComparisonData
|
2007-04-20 12:23:52 +00:00
|
|
|
******************************************************************************/
|
2008-07-10 09:14:19 +00:00
|
|
|
static HRESULT WINAPI ClassMonikerROTData_GetComparisonData(IROTData* iface,
|
2007-04-20 12:23:52 +00:00
|
|
|
BYTE* pbData,
|
|
|
|
ULONG cbMax,
|
|
|
|
ULONG* pcbData)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
ClassMoniker *This = impl_from_IROTData(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
|
|
|
|
|
|
|
|
*pcbData = 2*sizeof(CLSID);
|
|
|
|
if (cbMax < *pcbData)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
/* write CLSID of the moniker */
|
|
|
|
memcpy(pbData, &CLSID_ClassMoniker, sizeof(CLSID));
|
|
|
|
/* write CLSID the moniker represents */
|
|
|
|
memcpy(pbData+sizeof(CLSID), &This->clsid, sizeof(CLSID));
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
/* Virtual function table for the ClassMoniker class which include IPersist,*/
|
|
|
|
/* IPersistStream and IMoniker functions. */
|
|
|
|
static const IMonikerVtbl ClassMonikerVtbl =
|
|
|
|
{
|
|
|
|
ClassMoniker_QueryInterface,
|
|
|
|
ClassMoniker_AddRef,
|
|
|
|
ClassMoniker_Release,
|
|
|
|
ClassMoniker_GetClassID,
|
|
|
|
ClassMoniker_IsDirty,
|
|
|
|
ClassMoniker_Load,
|
|
|
|
ClassMoniker_Save,
|
|
|
|
ClassMoniker_GetSizeMax,
|
|
|
|
ClassMoniker_BindToObject,
|
|
|
|
ClassMoniker_BindToStorage,
|
|
|
|
ClassMoniker_Reduce,
|
|
|
|
ClassMoniker_ComposeWith,
|
|
|
|
ClassMoniker_Enum,
|
|
|
|
ClassMoniker_IsEqual,
|
|
|
|
ClassMoniker_Hash,
|
|
|
|
ClassMoniker_IsRunning,
|
|
|
|
ClassMoniker_GetTimeOfLastChange,
|
|
|
|
ClassMoniker_Inverse,
|
|
|
|
ClassMoniker_CommonPrefixWith,
|
|
|
|
ClassMoniker_RelativePathTo,
|
|
|
|
ClassMoniker_GetDisplayName,
|
|
|
|
ClassMoniker_ParseDisplayName,
|
|
|
|
ClassMoniker_IsSystemMoniker
|
|
|
|
};
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
/* Virtual function table for the IROTData class. */
|
|
|
|
static const IROTDataVtbl ROTDataVtbl =
|
|
|
|
{
|
|
|
|
ClassMonikerROTData_QueryInterface,
|
|
|
|
ClassMonikerROTData_AddRef,
|
|
|
|
ClassMonikerROTData_Release,
|
2008-07-10 09:14:19 +00:00
|
|
|
ClassMonikerROTData_GetComparisonData
|
2007-04-20 12:23:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* ClassMoniker_Construct (local function)
|
|
|
|
*******************************************************************************/
|
2009-01-15 17:52:35 +00:00
|
|
|
static HRESULT ClassMoniker_Construct(ClassMoniker* This, REFCLSID rclsid)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
TRACE("(%p,%s)\n",This,debugstr_guid(rclsid));
|
|
|
|
|
|
|
|
/* Initialize the virtual function table. */
|
2012-05-17 15:16:51 +00:00
|
|
|
This->IMoniker_iface.lpVtbl = &ClassMonikerVtbl;
|
|
|
|
This->IROTData_iface.lpVtbl = &ROTDataVtbl;
|
2007-04-20 12:23:52 +00:00
|
|
|
This->ref = 0;
|
|
|
|
This->clsid = *rclsid;
|
|
|
|
This->pMarshal = NULL;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CreateClassMoniker [OLE32.@]
|
|
|
|
******************************************************************************/
|
|
|
|
HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, IMoniker **ppmk)
|
|
|
|
{
|
|
|
|
ClassMoniker* newClassMoniker;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
TRACE("(%s,%p)\n", debugstr_guid(rclsid), ppmk);
|
|
|
|
|
|
|
|
newClassMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassMoniker));
|
|
|
|
|
|
|
|
if (!newClassMoniker)
|
|
|
|
return STG_E_INSUFFICIENTMEMORY;
|
|
|
|
|
|
|
|
hr = ClassMoniker_Construct(newClassMoniker, rclsid);
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
HeapFree(GetProcessHeap(), 0, newClassMoniker);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return ClassMoniker_QueryInterface(&newClassMoniker->IMoniker_iface, &IID_IMoniker,
|
|
|
|
(void**)ppmk);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
HRESULT ClassMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName, LPDWORD pchEaten,
|
|
|
|
IMoniker **ppmk)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
LPCWSTR s = strchrW(szDisplayName, ':');
|
|
|
|
LPCWSTR end;
|
|
|
|
CLSID clsid;
|
|
|
|
BYTE table[256];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!s)
|
|
|
|
return MK_E_SYNTAX;
|
|
|
|
|
|
|
|
s++;
|
|
|
|
|
|
|
|
for (end = s; *end && (*end != ':'); end++)
|
|
|
|
;
|
|
|
|
|
|
|
|
TRACE("parsing %s\n", debugstr_wn(s, end - s));
|
|
|
|
|
|
|
|
/* validate the CLSID string */
|
|
|
|
if (s[0] == '{')
|
|
|
|
{
|
|
|
|
if ((end - s != 38) || (s[37] != '}'))
|
|
|
|
return MK_E_SYNTAX;
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (end - s != 36)
|
|
|
|
return MK_E_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=0; i<36; i++)
|
|
|
|
{
|
|
|
|
if ((i == 8)||(i == 13)||(i == 18)||(i == 23))
|
|
|
|
{
|
|
|
|
if (s[i] != '-')
|
|
|
|
return MK_E_SYNTAX;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!(((s[i] >= '0') && (s[i] <= '9')) ||
|
|
|
|
((s[i] >= 'a') && (s[i] <= 'f')) ||
|
|
|
|
((s[i] >= 'A') && (s[i] <= 'F'))))
|
|
|
|
return MK_E_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* quick lookup table */
|
|
|
|
memset(table, 0, 256);
|
|
|
|
|
|
|
|
for (i = 0; i < 10; i++)
|
|
|
|
table['0' + i] = i;
|
|
|
|
for (i = 0; i < 6; i++)
|
|
|
|
{
|
|
|
|
table['A' + i] = i+10;
|
|
|
|
table['a' + i] = i+10;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */
|
|
|
|
|
|
|
|
clsid.Data1 = (table[s[0]] << 28 | table[s[1]] << 24 | table[s[2]] << 20 | table[s[3]] << 16 |
|
|
|
|
table[s[4]] << 12 | table[s[5]] << 8 | table[s[6]] << 4 | table[s[7]]);
|
|
|
|
clsid.Data2 = table[s[9]] << 12 | table[s[10]] << 8 | table[s[11]] << 4 | table[s[12]];
|
|
|
|
clsid.Data3 = table[s[14]] << 12 | table[s[15]] << 8 | table[s[16]] << 4 | table[s[17]];
|
|
|
|
|
|
|
|
/* these are just sequential bytes */
|
|
|
|
clsid.Data4[0] = table[s[19]] << 4 | table[s[20]];
|
|
|
|
clsid.Data4[1] = table[s[21]] << 4 | table[s[22]];
|
|
|
|
clsid.Data4[2] = table[s[24]] << 4 | table[s[25]];
|
|
|
|
clsid.Data4[3] = table[s[26]] << 4 | table[s[27]];
|
|
|
|
clsid.Data4[4] = table[s[28]] << 4 | table[s[29]];
|
|
|
|
clsid.Data4[5] = table[s[30]] << 4 | table[s[31]];
|
|
|
|
clsid.Data4[6] = table[s[32]] << 4 | table[s[33]];
|
|
|
|
clsid.Data4[7] = table[s[34]] << 4 | table[s[35]];
|
|
|
|
|
|
|
|
hr = CreateClassMoniker(&clsid, ppmk);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
*pchEaten = (*end == ':' ? end + 1 : end) - szDisplayName;
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI ClassMonikerCF_QueryInterface(LPCLASSFACTORY iface,
|
|
|
|
REFIID riid, LPVOID *ppv)
|
|
|
|
{
|
|
|
|
*ppv = NULL;
|
|
|
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
|
|
|
|
{
|
|
|
|
*ppv = iface;
|
|
|
|
IUnknown_AddRef(iface);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI ClassMonikerCF_AddRef(LPCLASSFACTORY iface)
|
|
|
|
{
|
|
|
|
return 2; /* non-heap based object */
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI ClassMonikerCF_Release(LPCLASSFACTORY iface)
|
|
|
|
{
|
|
|
|
return 1; /* non-heap based object */
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI ClassMonikerCF_CreateInstance(LPCLASSFACTORY iface,
|
|
|
|
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
|
|
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
IMoniker *pmk;
|
|
|
|
|
|
|
|
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
|
|
|
|
|
|
|
|
*ppv = NULL;
|
|
|
|
|
|
|
|
if (pUnk)
|
|
|
|
return CLASS_E_NOAGGREGATION;
|
|
|
|
|
|
|
|
hr = CreateClassMoniker(&CLSID_NULL, &pmk);
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
|
|
|
|
hr = IMoniker_QueryInterface(pmk, riid, ppv);
|
|
|
|
IMoniker_Release(pmk);
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI ClassMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
|
|
|
|
{
|
|
|
|
FIXME("(%d), stub!\n",fLock);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const IClassFactoryVtbl ClassMonikerCFVtbl =
|
|
|
|
{
|
|
|
|
ClassMonikerCF_QueryInterface,
|
|
|
|
ClassMonikerCF_AddRef,
|
|
|
|
ClassMonikerCF_Release,
|
|
|
|
ClassMonikerCF_CreateInstance,
|
|
|
|
ClassMonikerCF_LockServer
|
|
|
|
};
|
|
|
|
static const IClassFactoryVtbl *ClassMonikerCF = &ClassMonikerCFVtbl;
|
|
|
|
|
|
|
|
HRESULT ClassMonikerCF_Create(REFIID riid, LPVOID *ppv)
|
|
|
|
{
|
|
|
|
return IClassFactory_QueryInterface((IClassFactory *)&ClassMonikerCF, riid, ppv);
|
|
|
|
}
|