2005-07-31 12:11:56 +00:00
|
|
|
/*
|
|
|
|
* CompositeMonikers implementation
|
|
|
|
*
|
|
|
|
* Copyright 1999 Noomen Hamza
|
|
|
|
*
|
|
|
|
* 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
|
2007-04-20 12:23:52 +00:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2005-07-31 12:11:56 +00:00
|
|
|
*/
|
|
|
|
|
2018-03-20 11:38:17 +00:00
|
|
|
#include <assert.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#define COBJMACROS
|
|
|
|
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "winuser.h"
|
|
|
|
#include "winerror.h"
|
|
|
|
#include "wine/debug.h"
|
|
|
|
#include "wine/unicode.h"
|
|
|
|
#include "ole2.h"
|
|
|
|
#include "moniker.h"
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|
|
|
|
2014-04-24 12:14:13 +00:00
|
|
|
#define BLOCK_TAB_SIZE 5 /* represent the first size table and its increment block size */
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/* CompositeMoniker data structure */
|
|
|
|
typedef struct CompositeMonikerImpl{
|
2012-05-17 15:16:51 +00:00
|
|
|
IMoniker IMoniker_iface;
|
|
|
|
IROTData IROTData_iface;
|
|
|
|
IMarshal IMarshal_iface;
|
|
|
|
LONG ref;
|
2008-07-10 09:14:19 +00:00
|
|
|
IMoniker** tabMoniker; /* dynamic table containing all components (monikers) of this composite moniker */
|
2005-07-31 12:11:56 +00:00
|
|
|
ULONG tabSize; /* size of tabMoniker */
|
2012-05-17 15:16:51 +00:00
|
|
|
ULONG tabLastIndex; /* first free index in tabMoniker */
|
|
|
|
} CompositeMonikerImpl;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static inline CompositeMonikerImpl *impl_from_IMoniker(IMoniker *iface)
|
|
|
|
{
|
|
|
|
return CONTAINING_RECORD(iface, CompositeMonikerImpl, IMoniker_iface);
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static inline CompositeMonikerImpl *impl_from_IROTData(IROTData *iface)
|
|
|
|
{
|
|
|
|
return CONTAINING_RECORD(iface, CompositeMonikerImpl, IROTData_iface);
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static inline CompositeMonikerImpl *impl_from_IMarshal(IMarshal *iface)
|
|
|
|
{
|
|
|
|
return CONTAINING_RECORD(iface, CompositeMonikerImpl, IMarshal_iface);
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/* EnumMoniker data structure */
|
|
|
|
typedef struct EnumMonikerImpl{
|
2012-05-17 15:16:51 +00:00
|
|
|
IEnumMoniker IEnumMoniker_iface;
|
|
|
|
LONG ref;
|
2005-07-31 12:11:56 +00:00
|
|
|
IMoniker** tabMoniker; /* dynamic table containing the enumerated monikers */
|
|
|
|
ULONG tabSize; /* size of tabMoniker */
|
|
|
|
ULONG currentPos; /* index pointer on the current moniker */
|
|
|
|
} EnumMonikerImpl;
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface)
|
2005-09-05 21:56:14 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
return CONTAINING_RECORD(iface, EnumMonikerImpl, IEnumMoniker_iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
2016-06-07 10:47:21 +00:00
|
|
|
static HRESULT EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRight,IEnumMoniker ** ppmk);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* CompositeMoniker_QueryInterface
|
|
|
|
*******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2016-11-22 12:30:48 +00:00
|
|
|
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/* Perform a sanity check on the parameters.*/
|
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
|
|
|
if ( ppvObject==0 )
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
/* 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))
|
2012-05-17 15:16:51 +00:00
|
|
|
*ppvObject = &This->IMarshal_iface;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/* Check that we obtained an interface.*/
|
|
|
|
if ((*ppvObject)==0)
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
|
|
|
|
/* Query Interface always increases the reference count by one when it is successful */
|
|
|
|
IMoniker_AddRef(iface);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_AddRef
|
|
|
|
******************************************************************************/
|
|
|
|
static ULONG WINAPI
|
|
|
|
CompositeMonikerImpl_AddRef(IMoniker* iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n",This);
|
|
|
|
|
|
|
|
return InterlockedIncrement(&This->ref);
|
|
|
|
}
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
static void CompositeMonikerImpl_ReleaseMonikersInTable(CompositeMonikerImpl *This)
|
|
|
|
{
|
|
|
|
ULONG i;
|
|
|
|
|
|
|
|
for (i = 0; i < This->tabLastIndex; i++)
|
|
|
|
IMoniker_Release(This->tabMoniker[i]);
|
|
|
|
|
|
|
|
This->tabLastIndex = 0;
|
|
|
|
}
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_Release
|
|
|
|
******************************************************************************/
|
|
|
|
static ULONG WINAPI
|
|
|
|
CompositeMonikerImpl_Release(IMoniker* iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
ULONG ref;
|
|
|
|
|
|
|
|
TRACE("(%p)\n",This);
|
|
|
|
|
|
|
|
ref = InterlockedDecrement(&This->ref);
|
|
|
|
|
2014-04-24 12:14:13 +00:00
|
|
|
/* destroy the object if there are no more references to it */
|
2005-07-31 12:11:56 +00:00
|
|
|
if (ref == 0){
|
|
|
|
|
|
|
|
/* release all the components before destroying this object */
|
2007-04-20 12:23:52 +00:00
|
|
|
CompositeMonikerImpl_ReleaseMonikersInTable(This);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(),0,This->tabMoniker);
|
|
|
|
HeapFree(GetProcessHeap(),0,This);
|
|
|
|
}
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_GetClassID
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
|
|
|
|
{
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p,%p)\n",iface,pClassID);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (pClassID==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*pClassID = CLSID_CompositeMoniker;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_IsDirty
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_Load
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_Load(IMoniker* iface,IStream* pStm)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
HRESULT res;
|
2007-04-20 12:23:52 +00:00
|
|
|
DWORD moniker_count;
|
|
|
|
DWORD i;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p,%p)\n",iface,pStm);
|
|
|
|
|
|
|
|
/* this function call OleLoadFromStream function for each moniker within this object */
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
res=IStream_Read(pStm,&moniker_count,sizeof(DWORD),NULL);
|
|
|
|
if (res != S_OK)
|
|
|
|
{
|
|
|
|
ERR("couldn't reading moniker count from stream\n");
|
2007-04-20 10:28:01 +00:00
|
|
|
return E_FAIL;
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
2007-04-20 02:30:53 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
CompositeMonikerImpl_ReleaseMonikersInTable(This);
|
|
|
|
|
|
|
|
for (i = 0; i < moniker_count; i++)
|
|
|
|
{
|
2005-07-31 12:11:56 +00:00
|
|
|
res=OleLoadFromStream(pStm,&IID_IMoniker,(void**)&This->tabMoniker[This->tabLastIndex]);
|
|
|
|
if (FAILED(res))
|
|
|
|
{
|
2007-04-20 12:23:52 +00:00
|
|
|
ERR("couldn't load moniker from stream, res = 0x%08x\n", res);
|
2005-07-31 12:11:56 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* resize the table if needed */
|
|
|
|
if (++This->tabLastIndex==This->tabSize){
|
|
|
|
|
|
|
|
This->tabSize+=BLOCK_TAB_SIZE;
|
2013-09-26 13:58:03 +00:00
|
|
|
This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(This->tabMoniker[0]));
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (This->tabMoniker==NULL)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_Save
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
HRESULT res;
|
|
|
|
IEnumMoniker *enumMk;
|
|
|
|
IMoniker *pmk;
|
2007-04-20 12:23:52 +00:00
|
|
|
DWORD moniker_count = This->tabLastIndex;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p,%p,%d)\n",iface,pStm,fClearDirty);
|
|
|
|
|
|
|
|
/* This function calls OleSaveToStream function for each moniker within
|
|
|
|
* this object.
|
|
|
|
* When I tested this function in windows, I usually found this constant
|
|
|
|
* at the beginning of the stream. I don't known why (there's no
|
|
|
|
* indication in the specification) !
|
|
|
|
*/
|
2007-04-20 12:23:52 +00:00
|
|
|
res=IStream_Write(pStm,&moniker_count,sizeof(moniker_count),NULL);
|
|
|
|
if (FAILED(res)) return res;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
IMoniker_Enum(iface,TRUE,&enumMk);
|
|
|
|
|
|
|
|
while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==S_OK){
|
|
|
|
|
|
|
|
res=OleSaveToStream((IPersistStream*)pmk,pStm);
|
|
|
|
|
|
|
|
IMoniker_Release(pmk);
|
|
|
|
|
|
|
|
if (FAILED(res)){
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
IEnumMoniker_Release(enumMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IEnumMoniker_Release(enumMk);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_GetSizeMax
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_GetSizeMax(IMoniker* iface,ULARGE_INTEGER* pcbSize)
|
|
|
|
{
|
|
|
|
IEnumMoniker *enumMk;
|
|
|
|
IMoniker *pmk;
|
|
|
|
ULARGE_INTEGER ptmpSize;
|
|
|
|
|
|
|
|
/* The sizeMax of this object is calculated by calling GetSizeMax on
|
|
|
|
* each moniker within this object then summing all returned values
|
|
|
|
*/
|
|
|
|
|
|
|
|
TRACE("(%p,%p)\n",iface,pcbSize);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (!pcbSize)
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_POINTER;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
pcbSize->QuadPart = sizeof(DWORD);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
IMoniker_Enum(iface,TRUE,&enumMk);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==S_OK){
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
IMoniker_GetSizeMax(pmk,&ptmpSize);
|
|
|
|
|
|
|
|
IMoniker_Release(pmk);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
pcbSize->QuadPart = ptmpSize.QuadPart + sizeof(CLSID);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
IEnumMoniker_Release(enumMk);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_BindToObject
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
|
|
|
|
{
|
|
|
|
HRESULT res;
|
|
|
|
IRunningObjectTable *prot;
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker *tempMk,*antiMk,*rightMostMk;
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker *enumMoniker;
|
|
|
|
|
2016-11-22 12:30:48 +00:00
|
|
|
TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (ppvResult==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppvResult=0;
|
|
|
|
/* If pmkToLeft is NULL, this method looks for the moniker in the ROT, and if found, queries the retrieved */
|
|
|
|
/* object for the requested interface pointer. */
|
|
|
|
if(pmkToLeft==NULL){
|
|
|
|
|
|
|
|
res=IBindCtx_GetRunningObjectTable(pbc,&prot);
|
|
|
|
|
|
|
|
if (SUCCEEDED(res)){
|
|
|
|
|
|
|
|
/* if the requested class was loaded before ! we don't need to reload it */
|
|
|
|
res = IRunningObjectTable_GetObject(prot,iface,(IUnknown**)ppvResult);
|
|
|
|
|
|
|
|
if (res==S_OK)
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
/* If pmkToLeft is not NULL, the method recursively calls IMoniker::BindToObject on the rightmost */
|
|
|
|
/* component of the composite, passing the rest of the composite as the pmkToLeft parameter for that call */
|
|
|
|
|
|
|
|
IMoniker_Enum(iface,FALSE,&enumMoniker);
|
2016-06-07 10:47:21 +00:00
|
|
|
IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker_Release(enumMoniker);
|
|
|
|
|
|
|
|
res=CreateAntiMoniker(&antiMk);
|
|
|
|
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
|
|
|
|
IMoniker_Release(antiMk);
|
|
|
|
|
2016-06-07 10:47:21 +00:00
|
|
|
res=IMoniker_BindToObject(rightMostMk,pbc,tempMk,riid,ppvResult);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
IMoniker_Release(tempMk);
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker_Release(rightMostMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_BindToStorage
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
|
|
|
|
{
|
|
|
|
HRESULT res;
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker *tempMk,*antiMk,*rightMostMk,*leftMk;
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker *enumMoniker;
|
|
|
|
|
2016-11-22 12:30:48 +00:00
|
|
|
TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
*ppvResult=0;
|
|
|
|
|
|
|
|
/* This method recursively calls BindToStorage on the rightmost component of the composite, */
|
|
|
|
/* passing the rest of the composite as the pmkToLeft parameter for that call. */
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (pmkToLeft)
|
|
|
|
{
|
|
|
|
res = IMoniker_ComposeWith(pmkToLeft, iface, FALSE, &leftMk);
|
|
|
|
if (FAILED(res)) return res;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
leftMk = iface;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
IMoniker_Enum(iface, FALSE, &enumMoniker);
|
2016-06-07 10:47:21 +00:00
|
|
|
IEnumMoniker_Next(enumMoniker, 1, &rightMostMk, NULL);
|
2007-04-20 12:23:52 +00:00
|
|
|
IEnumMoniker_Release(enumMoniker);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
res = CreateAntiMoniker(&antiMk);
|
|
|
|
if (FAILED(res)) return res;
|
|
|
|
res = IMoniker_ComposeWith(leftMk, antiMk, 0, &tempMk);
|
|
|
|
if (FAILED(res)) return res;
|
|
|
|
IMoniker_Release(antiMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2016-06-07 10:47:21 +00:00
|
|
|
res = IMoniker_BindToStorage(rightMostMk, pbc, tempMk, riid, ppvResult);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
IMoniker_Release(tempMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker_Release(rightMostMk);
|
2007-04-20 02:30:53 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (pmkToLeft)
|
|
|
|
IMoniker_Release(leftMk);
|
|
|
|
|
|
|
|
return res;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_Reduce
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
|
|
|
|
IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
|
|
|
|
{
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker *tempMk,*antiMk,*rightMostMk,*leftReducedComposedMk,*rightMostReducedMk;
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker *enumMoniker;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (ppmkReduced==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
/* This method recursively calls Reduce for each of its component monikers. */
|
|
|
|
|
|
|
|
if (ppmkToLeft==NULL){
|
|
|
|
|
|
|
|
IMoniker_Enum(iface,FALSE,&enumMoniker);
|
2016-06-07 10:47:21 +00:00
|
|
|
IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker_Release(enumMoniker);
|
|
|
|
|
2010-05-29 11:34:57 +00:00
|
|
|
CreateAntiMoniker(&antiMk);
|
|
|
|
IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
IMoniker_Release(antiMk);
|
|
|
|
|
2016-06-07 10:47:21 +00:00
|
|
|
return IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
else if (*ppmkToLeft==NULL)
|
|
|
|
|
|
|
|
return IMoniker_Reduce(iface,pbc,dwReduceHowFar,NULL,ppmkReduced);
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
/* separate the composite moniker in to left and right moniker */
|
|
|
|
IMoniker_Enum(iface,FALSE,&enumMoniker);
|
2016-06-07 10:47:21 +00:00
|
|
|
IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker_Release(enumMoniker);
|
|
|
|
|
2010-05-29 11:34:57 +00:00
|
|
|
CreateAntiMoniker(&antiMk);
|
|
|
|
IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
IMoniker_Release(antiMk);
|
|
|
|
|
|
|
|
/* If any of the components reduces itself, the method returns S_OK and passes back a composite */
|
|
|
|
/* of the reduced components */
|
2016-06-07 10:47:21 +00:00
|
|
|
if (IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,NULL,&rightMostReducedMk) &&
|
|
|
|
IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk)
|
2005-07-31 12:11:56 +00:00
|
|
|
)
|
|
|
|
|
2016-06-07 10:47:21 +00:00
|
|
|
return CreateGenericComposite(leftReducedComposedMk,rightMostReducedMk,ppmkReduced);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
else{
|
|
|
|
/* If no reduction occurred, the method passes back the same moniker and returns MK_S_REDUCED_TO_SELF.*/
|
|
|
|
|
|
|
|
IMoniker_AddRef(iface);
|
|
|
|
|
|
|
|
*ppmkReduced=iface;
|
|
|
|
|
|
|
|
return MK_S_REDUCED_TO_SELF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_ComposeWith
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
|
|
|
|
BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
|
|
|
|
{
|
|
|
|
TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
|
|
|
|
|
|
|
|
if ((ppmkComposite==NULL)||(pmkRight==NULL))
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppmkComposite=0;
|
|
|
|
|
|
|
|
/* If fOnlyIfNotGeneric is TRUE, this method sets *pmkComposite to NULL and returns MK_E_NEEDGENERIC; */
|
|
|
|
/* otherwise, the method returns the result of combining the two monikers by calling the */
|
|
|
|
/* CreateGenericComposite function */
|
|
|
|
|
|
|
|
if (fOnlyIfNotGeneric)
|
|
|
|
return MK_E_NEEDGENERIC;
|
|
|
|
|
|
|
|
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_Enum
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
|
|
|
|
|
|
|
|
if (ppenumMoniker == NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabLastIndex,0,fForward,ppenumMoniker);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_IsEqual
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
|
|
|
|
{
|
|
|
|
IEnumMoniker *enumMoniker1,*enumMoniker2;
|
|
|
|
IMoniker *tempMk1,*tempMk2;
|
|
|
|
HRESULT res1,res2,res;
|
2009-09-05 15:03:37 +00:00
|
|
|
BOOL done;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
|
|
|
|
|
|
|
|
if (pmkOtherMoniker==NULL)
|
|
|
|
return S_FALSE;
|
|
|
|
|
|
|
|
/* This method returns S_OK if the components of both monikers are equal when compared in the */
|
|
|
|
/* left-to-right order.*/
|
|
|
|
IMoniker_Enum(pmkOtherMoniker,TRUE,&enumMoniker1);
|
|
|
|
|
|
|
|
if (enumMoniker1==NULL)
|
|
|
|
return S_FALSE;
|
|
|
|
|
|
|
|
IMoniker_Enum(iface,TRUE,&enumMoniker2);
|
|
|
|
|
2009-09-05 15:03:37 +00:00
|
|
|
do {
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
|
|
|
|
res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL);
|
|
|
|
|
|
|
|
if((res1==S_OK)&&(res2==S_OK)){
|
2009-09-05 15:03:37 +00:00
|
|
|
done = (res = IMoniker_IsEqual(tempMk1,tempMk2)) == S_FALSE;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
2009-09-05 15:03:37 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
res = (res1==S_FALSE) && (res2==S_FALSE);
|
|
|
|
done = TRUE;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (res1==S_OK)
|
|
|
|
IMoniker_Release(tempMk1);
|
|
|
|
|
|
|
|
if (res2==S_OK)
|
|
|
|
IMoniker_Release(tempMk2);
|
2009-09-05 15:03:37 +00:00
|
|
|
} while (!done);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
IEnumMoniker_Release(enumMoniker1);
|
|
|
|
IEnumMoniker_Release(enumMoniker2);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_Hash
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
|
|
|
|
{
|
|
|
|
IEnumMoniker *enumMoniker;
|
|
|
|
IMoniker *tempMk;
|
|
|
|
HRESULT res;
|
|
|
|
DWORD tempHash;
|
|
|
|
|
|
|
|
TRACE("(%p,%p)\n",iface,pdwHash);
|
|
|
|
|
|
|
|
if (pdwHash==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
res = IMoniker_Enum(iface,TRUE,&enumMoniker);
|
|
|
|
if(FAILED(res))
|
|
|
|
return res;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
*pdwHash = 0;
|
|
|
|
|
|
|
|
while(IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL)==S_OK){
|
2005-07-31 12:11:56 +00:00
|
|
|
res = IMoniker_Hash(tempMk, &tempHash);
|
|
|
|
if(FAILED(res))
|
|
|
|
break;
|
2007-04-20 12:23:52 +00:00
|
|
|
*pdwHash = *pdwHash ^ tempHash;
|
2008-01-14 15:45:45 +00:00
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
IMoniker_Release(tempMk);
|
|
|
|
}
|
|
|
|
|
|
|
|
IEnumMoniker_Release(enumMoniker);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_IsRunning
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning)
|
|
|
|
{
|
|
|
|
IRunningObjectTable* rot;
|
|
|
|
HRESULT res;
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker *tempMk,*antiMk,*rightMostMk;
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker *enumMoniker;
|
|
|
|
|
|
|
|
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
|
|
|
|
|
|
|
|
/* If pmkToLeft is non-NULL, this method composes pmkToLeft with this moniker and calls IsRunning on the result.*/
|
|
|
|
if (pmkToLeft!=NULL){
|
|
|
|
|
|
|
|
CreateGenericComposite(pmkToLeft,iface,&tempMk);
|
|
|
|
|
|
|
|
res = IMoniker_IsRunning(tempMk,pbc,NULL,pmkNewlyRunning);
|
|
|
|
|
|
|
|
IMoniker_Release(tempMk);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
/* If pmkToLeft is NULL, this method returns S_OK if pmkNewlyRunning is non-NULL and is equal */
|
|
|
|
/* to this moniker */
|
|
|
|
|
|
|
|
if (pmkNewlyRunning!=NULL)
|
|
|
|
|
|
|
|
if (IMoniker_IsEqual(iface,pmkNewlyRunning)==S_OK)
|
|
|
|
return S_OK;
|
|
|
|
|
|
|
|
else
|
|
|
|
return S_FALSE;
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
if (pbc==NULL)
|
2010-03-10 14:28:56 +00:00
|
|
|
return E_INVALIDARG;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/* If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether */
|
|
|
|
/* the moniker is running. If so, the method returns S_OK; otherwise, it recursively calls */
|
|
|
|
/* IMoniker::IsRunning on the rightmost component of the composite, passing the remainder of */
|
|
|
|
/* the composite as the pmkToLeft parameter for that call. */
|
|
|
|
|
|
|
|
res=IBindCtx_GetRunningObjectTable(pbc,&rot);
|
|
|
|
|
|
|
|
if (FAILED(res))
|
|
|
|
return res;
|
|
|
|
|
|
|
|
res = IRunningObjectTable_IsRunning(rot,iface);
|
|
|
|
IRunningObjectTable_Release(rot);
|
|
|
|
|
|
|
|
if(res==S_OK)
|
|
|
|
return S_OK;
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
IMoniker_Enum(iface,FALSE,&enumMoniker);
|
2016-06-07 10:47:21 +00:00
|
|
|
IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker_Release(enumMoniker);
|
|
|
|
|
|
|
|
res=CreateAntiMoniker(&antiMk);
|
|
|
|
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
|
|
|
|
IMoniker_Release(antiMk);
|
|
|
|
|
2016-06-07 10:47:21 +00:00
|
|
|
res=IMoniker_IsRunning(rightMostMk,pbc,tempMk,pmkNewlyRunning);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
IMoniker_Release(tempMk);
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker_Release(rightMostMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_GetTimeOfLastChange
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft, FILETIME* pCompositeTime)
|
|
|
|
{
|
|
|
|
HRESULT res;
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker *tempMk,*antiMk,*rightMostMk,*leftMk;
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker *enumMoniker;
|
|
|
|
|
|
|
|
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pCompositeTime);
|
|
|
|
|
|
|
|
if (pCompositeTime==NULL)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
/* This method creates a composite of pmkToLeft (if non-NULL) and this moniker and uses the ROT to */
|
|
|
|
/* retrieve the time of last change. If the object is not in the ROT, the method recursively calls */
|
|
|
|
/* IMoniker::GetTimeOfLastChange on the rightmost component of the composite, passing the remainder */
|
|
|
|
/* of the composite as the pmkToLeft parameter for that call. */
|
2007-04-20 12:23:52 +00:00
|
|
|
if (pmkToLeft)
|
|
|
|
{
|
|
|
|
IRunningObjectTable* rot;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
res = IMoniker_ComposeWith(pmkToLeft, iface, FALSE, &leftMk);
|
2015-07-19 23:10:53 +00:00
|
|
|
if (FAILED(res))
|
|
|
|
return res;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
res = IBindCtx_GetRunningObjectTable(pbc,&rot);
|
2005-07-31 12:11:56 +00:00
|
|
|
if (FAILED(res))
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
IMoniker_Release(leftMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
return res;
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (IRunningObjectTable_GetTimeOfLastChange(rot,leftMk,pCompositeTime)==S_OK)
|
|
|
|
{
|
|
|
|
IMoniker_Release(leftMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
return res;
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
leftMk = iface;
|
|
|
|
|
|
|
|
IMoniker_Enum(iface, FALSE, &enumMoniker);
|
2016-06-07 10:47:21 +00:00
|
|
|
IEnumMoniker_Next(enumMoniker, 1, &rightMostMk, NULL);
|
2007-04-20 12:23:52 +00:00
|
|
|
IEnumMoniker_Release(enumMoniker);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
res = CreateAntiMoniker(&antiMk);
|
|
|
|
res = IMoniker_ComposeWith(leftMk, antiMk, 0, &tempMk);
|
|
|
|
IMoniker_Release(antiMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2016-06-07 10:47:21 +00:00
|
|
|
res = IMoniker_GetTimeOfLastChange(rightMostMk, pbc, tempMk, pCompositeTime);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
IMoniker_Release(tempMk);
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker_Release(rightMostMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (pmkToLeft)
|
|
|
|
IMoniker_Release(leftMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
return res;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_Inverse
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
|
|
|
|
{
|
|
|
|
HRESULT res;
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker *tempMk,*antiMk,*rightMostMk,*tempInvMk,*rightMostInvMk;
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker *enumMoniker;
|
|
|
|
|
|
|
|
TRACE("(%p,%p)\n",iface,ppmk);
|
|
|
|
|
|
|
|
if (ppmk==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
/* This method returns a composite moniker that consists of the inverses of each of the components */
|
|
|
|
/* of the original composite, stored in reverse order */
|
|
|
|
|
2015-07-19 23:10:53 +00:00
|
|
|
*ppmk = NULL;
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
res=CreateAntiMoniker(&antiMk);
|
2015-07-19 23:10:53 +00:00
|
|
|
if (FAILED(res))
|
|
|
|
return res;
|
|
|
|
|
|
|
|
res=IMoniker_ComposeWith(iface,antiMk,FALSE,&tempMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
IMoniker_Release(antiMk);
|
2015-07-19 23:10:53 +00:00
|
|
|
if (FAILED(res))
|
|
|
|
return res;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (tempMk==NULL)
|
|
|
|
|
|
|
|
return IMoniker_Inverse(iface,ppmk);
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
IMoniker_Enum(iface,FALSE,&enumMoniker);
|
2016-06-07 10:47:21 +00:00
|
|
|
IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker_Release(enumMoniker);
|
|
|
|
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker_Inverse(rightMostMk,&rightMostInvMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
CompositeMonikerImpl_Inverse(tempMk,&tempInvMk);
|
|
|
|
|
2016-06-07 10:47:21 +00:00
|
|
|
res=CreateGenericComposite(rightMostInvMk,tempInvMk,ppmk);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
IMoniker_Release(tempMk);
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker_Release(rightMostMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
IMoniker_Release(tempInvMk);
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker_Release(rightMostInvMk);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_CommonPrefixWith
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_CommonPrefixWith(IMoniker* iface, IMoniker* pmkOther,
|
|
|
|
IMoniker** ppmkPrefix)
|
|
|
|
{
|
|
|
|
DWORD mkSys;
|
|
|
|
HRESULT res1,res2;
|
|
|
|
IMoniker *tempMk1,*tempMk2,*mostLeftMk1,*mostLeftMk2;
|
|
|
|
IEnumMoniker *enumMoniker1,*enumMoniker2;
|
|
|
|
ULONG i,nbCommonMk=0;
|
|
|
|
|
|
|
|
/* If the other moniker is a composite, this method compares the components of each composite from left */
|
|
|
|
/* to right. The returned common prefix moniker might also be a composite moniker, depending on how many */
|
|
|
|
/* of the leftmost components were common to both monikers. */
|
|
|
|
|
|
|
|
if (ppmkPrefix==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppmkPrefix=0;
|
|
|
|
|
|
|
|
if (pmkOther==NULL)
|
|
|
|
return MK_E_NOPREFIX;
|
|
|
|
|
|
|
|
IMoniker_IsSystemMoniker(pmkOther,&mkSys);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
if(mkSys==MKSYS_GENERICCOMPOSITE){
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
IMoniker_Enum(iface,TRUE,&enumMoniker1);
|
|
|
|
IMoniker_Enum(pmkOther,TRUE,&enumMoniker2);
|
|
|
|
|
|
|
|
while(1){
|
|
|
|
|
|
|
|
res1=IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL);
|
|
|
|
res2=IEnumMoniker_Next(enumMoniker2,1,&mostLeftMk2,NULL);
|
|
|
|
|
|
|
|
if ((res1==S_FALSE) && (res2==S_FALSE)){
|
|
|
|
|
|
|
|
/* If the monikers are equal, the method returns MK_S_US and sets ppmkPrefix to this moniker.*/
|
|
|
|
*ppmkPrefix=iface;
|
|
|
|
IMoniker_AddRef(iface);
|
|
|
|
return MK_S_US;
|
|
|
|
}
|
|
|
|
else if ((res1==S_OK) && (res2==S_OK)){
|
|
|
|
|
|
|
|
if (IMoniker_IsEqual(mostLeftMk1,mostLeftMk2)==S_OK)
|
|
|
|
|
|
|
|
nbCommonMk++;
|
|
|
|
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
else if (res1==S_OK){
|
|
|
|
|
|
|
|
/* If the other moniker is a prefix of this moniker, the method returns MK_S_HIM and sets */
|
|
|
|
/* ppmkPrefix to the other moniker. */
|
|
|
|
*ppmkPrefix=pmkOther;
|
|
|
|
return MK_S_HIM;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
/* If this moniker is a prefix of the other, this method returns MK_S_ME and sets ppmkPrefix */
|
|
|
|
/* to this moniker. */
|
|
|
|
*ppmkPrefix=iface;
|
|
|
|
return MK_S_ME;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IEnumMoniker_Release(enumMoniker1);
|
|
|
|
IEnumMoniker_Release(enumMoniker2);
|
|
|
|
|
|
|
|
/* If there is no common prefix, this method returns MK_E_NOPREFIX and sets ppmkPrefix to NULL. */
|
|
|
|
if (nbCommonMk==0)
|
|
|
|
return MK_E_NOPREFIX;
|
|
|
|
|
|
|
|
IEnumMoniker_Reset(enumMoniker1);
|
|
|
|
|
|
|
|
IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
|
|
|
|
|
2008-07-10 09:14:19 +00:00
|
|
|
/* if we have more than one common moniker the result will be a composite moniker */
|
2005-07-31 12:11:56 +00:00
|
|
|
if (nbCommonMk>1){
|
|
|
|
|
|
|
|
/* initialize the common prefix moniker with the composite of two first moniker (from the left)*/
|
|
|
|
IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL);
|
|
|
|
CreateGenericComposite(tempMk1,tempMk2,ppmkPrefix);
|
|
|
|
IMoniker_Release(tempMk1);
|
|
|
|
IMoniker_Release(tempMk2);
|
|
|
|
|
|
|
|
/* compose all common monikers in a composite moniker */
|
|
|
|
for(i=0;i<nbCommonMk;i++){
|
|
|
|
|
|
|
|
IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
|
|
|
|
|
|
|
|
CreateGenericComposite(*ppmkPrefix,tempMk1,&tempMk2);
|
|
|
|
|
|
|
|
IMoniker_Release(*ppmkPrefix);
|
|
|
|
|
|
|
|
IMoniker_Release(tempMk1);
|
|
|
|
|
|
|
|
*ppmkPrefix=tempMk2;
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
else{
|
2008-07-10 09:14:19 +00:00
|
|
|
/* if we have only one common moniker the result will be a simple moniker which is the most-left one*/
|
2005-07-31 12:11:56 +00:00
|
|
|
*ppmkPrefix=tempMk1;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
/* If the other moniker is not a composite, the method simply compares it to the leftmost component
|
|
|
|
of this moniker.*/
|
|
|
|
|
|
|
|
IMoniker_Enum(iface,TRUE,&enumMoniker1);
|
|
|
|
|
|
|
|
IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL);
|
|
|
|
|
|
|
|
if (IMoniker_IsEqual(pmkOther,mostLeftMk1)==S_OK){
|
|
|
|
|
|
|
|
*ppmkPrefix=pmkOther;
|
|
|
|
|
|
|
|
return MK_S_HIM;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return MK_E_NOPREFIX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************************************
|
|
|
|
* GetAfterCommonPrefix (local function)
|
|
|
|
* This function returns a moniker that consist of the remainder when the common prefix is removed
|
|
|
|
***************************************************************************************************/
|
|
|
|
static VOID GetAfterCommonPrefix(IMoniker* pGenMk,IMoniker* commonMk,IMoniker** restMk)
|
|
|
|
{
|
|
|
|
IMoniker *tempMk,*tempMk1,*tempMk2;
|
|
|
|
IEnumMoniker *enumMoniker1,*enumMoniker2,*enumMoniker3;
|
|
|
|
ULONG nbRestMk=0;
|
|
|
|
DWORD mkSys;
|
|
|
|
HRESULT res1,res2;
|
|
|
|
|
|
|
|
*restMk=0;
|
|
|
|
|
|
|
|
/* to create an enumerator for pGenMk with current position pointed on the first element after common */
|
|
|
|
/* prefix: enum the two monikers (left-right) then compare these enumerations (left-right) and stop */
|
|
|
|
/* on the first difference. */
|
|
|
|
IMoniker_Enum(pGenMk,TRUE,&enumMoniker1);
|
|
|
|
|
|
|
|
IMoniker_IsSystemMoniker(commonMk,&mkSys);
|
|
|
|
|
|
|
|
if (mkSys==MKSYS_GENERICCOMPOSITE){
|
|
|
|
|
|
|
|
IMoniker_Enum(commonMk,TRUE,&enumMoniker2);
|
|
|
|
while(1){
|
|
|
|
|
|
|
|
res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
|
|
|
|
res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL);
|
|
|
|
|
|
|
|
if ((res1==S_FALSE)||(res2==S_FALSE)){
|
|
|
|
|
|
|
|
if (res1==S_OK)
|
|
|
|
|
|
|
|
nbRestMk++;
|
|
|
|
|
|
|
|
IMoniker_Release(tempMk1);
|
2009-09-05 15:03:37 +00:00
|
|
|
IMoniker_Release(tempMk2);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
IMoniker_Release(tempMk1);
|
2009-09-05 15:03:37 +00:00
|
|
|
IMoniker_Release(tempMk2);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
|
|
|
|
IMoniker_Release(tempMk1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* count the number of elements in the enumerator after the common prefix */
|
|
|
|
IEnumMoniker_Clone(enumMoniker1,&enumMoniker3);
|
|
|
|
|
|
|
|
for(;IEnumMoniker_Next(enumMoniker3,1,&tempMk,NULL)==S_OK;nbRestMk++)
|
|
|
|
|
|
|
|
IMoniker_Release(tempMk);
|
|
|
|
|
|
|
|
if (nbRestMk==0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* create a generic composite moniker with monikers located after the common prefix */
|
|
|
|
IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
|
|
|
|
|
|
|
|
if (nbRestMk==1){
|
|
|
|
|
|
|
|
*restMk= tempMk1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL);
|
|
|
|
|
|
|
|
CreateGenericComposite(tempMk1,tempMk2,restMk);
|
|
|
|
|
|
|
|
IMoniker_Release(tempMk1);
|
|
|
|
|
|
|
|
IMoniker_Release(tempMk2);
|
|
|
|
|
|
|
|
while(IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL)==S_OK){
|
|
|
|
|
|
|
|
CreateGenericComposite(*restMk,tempMk1,&tempMk2);
|
|
|
|
|
|
|
|
IMoniker_Release(tempMk1);
|
|
|
|
|
|
|
|
IMoniker_Release(*restMk);
|
|
|
|
|
|
|
|
*restMk=tempMk2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_RelativePathTo
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmkOther,
|
|
|
|
IMoniker** ppmkRelPath)
|
|
|
|
{
|
|
|
|
HRESULT res;
|
|
|
|
IMoniker *restOtherMk=0,*restThisMk=0,*invRestThisMk=0,*commonMk=0;
|
|
|
|
|
|
|
|
TRACE("(%p,%p,%p)\n",iface,pmkOther,ppmkRelPath);
|
|
|
|
|
|
|
|
if (ppmkRelPath==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppmkRelPath=0;
|
|
|
|
|
|
|
|
/* This method finds the common prefix of the two monikers and creates two monikers that consist */
|
|
|
|
/* of the remainder when the common prefix is removed. Then it creates the inverse for the remainder */
|
|
|
|
/* of this moniker and composes the remainder of the other moniker on the right of it. */
|
|
|
|
|
|
|
|
/* finds the common prefix of the two monikers */
|
|
|
|
res=IMoniker_CommonPrefixWith(iface,pmkOther,&commonMk);
|
|
|
|
|
|
|
|
/* if there's no common prefix or the two moniker are equal the relative is the other moniker */
|
|
|
|
if ((res== MK_E_NOPREFIX)||(res==MK_S_US)){
|
|
|
|
|
|
|
|
*ppmkRelPath=pmkOther;
|
|
|
|
IMoniker_AddRef(pmkOther);
|
|
|
|
return MK_S_HIM;
|
|
|
|
}
|
|
|
|
|
|
|
|
GetAfterCommonPrefix(iface,commonMk,&restThisMk);
|
|
|
|
GetAfterCommonPrefix(pmkOther,commonMk,&restOtherMk);
|
|
|
|
|
|
|
|
/* if other is a prefix of this moniker the relative path is the inverse of the remainder path of this */
|
|
|
|
/* moniker when the common prefix is removed */
|
|
|
|
if (res==MK_S_HIM){
|
|
|
|
|
|
|
|
IMoniker_Inverse(restThisMk,ppmkRelPath);
|
|
|
|
IMoniker_Release(restThisMk);
|
|
|
|
}
|
|
|
|
/* if this moniker is a prefix of other moniker the relative path is the remainder path of other moniker */
|
|
|
|
/* when the common prefix is removed */
|
|
|
|
else if (res==MK_S_ME){
|
|
|
|
|
|
|
|
*ppmkRelPath=restOtherMk;
|
|
|
|
IMoniker_AddRef(restOtherMk);
|
|
|
|
}
|
|
|
|
/* the relative path is the inverse for the remainder of this moniker and the remainder of the other */
|
|
|
|
/* moniker on the right of it. */
|
|
|
|
else if (res==S_OK){
|
|
|
|
|
|
|
|
IMoniker_Inverse(restThisMk,&invRestThisMk);
|
|
|
|
IMoniker_Release(restThisMk);
|
|
|
|
CreateGenericComposite(invRestThisMk,restOtherMk,ppmkRelPath);
|
|
|
|
IMoniker_Release(invRestThisMk);
|
|
|
|
IMoniker_Release(restOtherMk);
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_GetDisplayName
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
|
|
|
|
{
|
|
|
|
ULONG lengthStr=1;
|
|
|
|
IEnumMoniker *enumMoniker;
|
|
|
|
IMoniker* tempMk;
|
|
|
|
LPOLESTR tempStr;
|
|
|
|
|
|
|
|
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
|
|
|
|
|
|
|
|
if (ppszDisplayName==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR));
|
|
|
|
|
|
|
|
if (*ppszDisplayName==NULL)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
/* This method returns the concatenation of the display names returned by each component moniker of */
|
|
|
|
/* the composite */
|
|
|
|
|
|
|
|
**ppszDisplayName=0;
|
|
|
|
|
|
|
|
IMoniker_Enum(iface,TRUE,&enumMoniker);
|
|
|
|
|
|
|
|
while(IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL)==S_OK){
|
|
|
|
|
|
|
|
IMoniker_GetDisplayName(tempMk,pbc,NULL,&tempStr);
|
|
|
|
|
|
|
|
lengthStr+=lstrlenW(tempStr);
|
|
|
|
|
|
|
|
*ppszDisplayName=CoTaskMemRealloc(*ppszDisplayName,lengthStr * sizeof(WCHAR));
|
|
|
|
|
|
|
|
if (*ppszDisplayName==NULL)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
strcatW(*ppszDisplayName,tempStr);
|
|
|
|
|
|
|
|
CoTaskMemFree(tempStr);
|
|
|
|
IMoniker_Release(tempMk);
|
|
|
|
}
|
|
|
|
|
|
|
|
IEnumMoniker_Release(enumMoniker);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_ParseDisplayName
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc,
|
|
|
|
IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten,
|
|
|
|
IMoniker** ppmkOut)
|
|
|
|
{
|
|
|
|
IEnumMoniker *enumMoniker;
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker *tempMk,*rightMostMk,*antiMk;
|
2005-07-31 12:11:56 +00:00
|
|
|
/* This method recursively calls IMoniker::ParseDisplayName on the rightmost component of the composite,*/
|
|
|
|
/* passing everything else as the pmkToLeft parameter for that call. */
|
|
|
|
|
|
|
|
/* get the most right moniker */
|
|
|
|
IMoniker_Enum(iface,FALSE,&enumMoniker);
|
2016-06-07 10:47:21 +00:00
|
|
|
IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
|
2005-07-31 12:11:56 +00:00
|
|
|
IEnumMoniker_Release(enumMoniker);
|
|
|
|
|
|
|
|
/* get the left moniker */
|
|
|
|
CreateAntiMoniker(&antiMk);
|
|
|
|
IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
|
|
|
|
IMoniker_Release(antiMk);
|
|
|
|
|
2016-06-07 10:47:21 +00:00
|
|
|
return IMoniker_ParseDisplayName(rightMostMk,pbc,tempMk,pszDisplayName,pchEaten,ppmkOut);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CompositeMoniker_IsSystemMoniker
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
|
|
|
|
{
|
|
|
|
TRACE("(%p,%p)\n",iface,pwdMksys);
|
|
|
|
|
|
|
|
if (!pwdMksys)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
(*pwdMksys)=MKSYS_GENERICCOMPOSITE;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* CompositeMonikerIROTData_QueryInterface
|
|
|
|
*******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
CompositeMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,
|
|
|
|
VOID** ppvObject)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IROTData(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2016-11-22 12:30:48 +00:00
|
|
|
TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppvObject);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return CompositeMonikerImpl_QueryInterface(&This->IMoniker_iface, riid, ppvObject);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* CompositeMonikerIROTData_AddRef
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI
|
|
|
|
CompositeMonikerROTDataImpl_AddRef(IROTData *iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IROTData(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n",iface);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return IMoniker_AddRef(&This->IMoniker_iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* CompositeMonikerIROTData_Release
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI CompositeMonikerROTDataImpl_Release(IROTData* iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IROTData(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n",iface);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return IMoniker_Release(&This->IMoniker_iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
2007-04-20 12:23:52 +00:00
|
|
|
* CompositeMonikerIROTData_GetComparisonData
|
2005-07-31 12:11:56 +00:00
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
2007-04-20 12:23:52 +00:00
|
|
|
CompositeMonikerROTDataImpl_GetComparisonData(IROTData* iface,
|
2005-07-31 12:11:56 +00:00
|
|
|
BYTE* pbData, ULONG cbMax, ULONG* pcbData)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IROTData(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
IEnumMoniker *pEnumMk;
|
|
|
|
IMoniker *pmk;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
|
|
|
|
|
|
|
|
*pcbData = sizeof(CLSID);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
hr = IMoniker_Enum(&This->IMoniker_iface, TRUE, &pEnumMk);
|
2007-04-20 12:23:52 +00:00
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
|
|
|
|
while(IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
|
|
|
|
{
|
|
|
|
IROTData *pROTData;
|
|
|
|
hr = IMoniker_QueryInterface(pmk, &IID_IROTData, (void **)&pROTData);
|
|
|
|
if (FAILED(hr))
|
|
|
|
ERR("moniker doesn't support IROTData interface\n");
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
ULONG cbData;
|
|
|
|
hr = IROTData_GetComparisonData(pROTData, NULL, 0, &cbData);
|
|
|
|
IROTData_Release(pROTData);
|
|
|
|
if (SUCCEEDED(hr) || (hr == E_OUTOFMEMORY))
|
|
|
|
{
|
|
|
|
*pcbData += cbData;
|
|
|
|
hr = S_OK;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("IROTData_GetComparisonData failed with error 0x%08x\n", hr);
|
|
|
|
}
|
|
|
|
|
|
|
|
IMoniker_Release(pmk);
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
IEnumMoniker_Release(pEnumMk);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (cbMax < *pcbData)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
IEnumMoniker_Reset(pEnumMk);
|
|
|
|
|
|
|
|
memcpy(pbData, &CLSID_CompositeMoniker, sizeof(CLSID));
|
|
|
|
pbData += sizeof(CLSID);
|
|
|
|
cbMax -= sizeof(CLSID);
|
|
|
|
|
|
|
|
while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
|
|
|
|
{
|
|
|
|
IROTData *pROTData;
|
|
|
|
hr = IMoniker_QueryInterface(pmk, &IID_IROTData, (void **)&pROTData);
|
|
|
|
if (FAILED(hr))
|
|
|
|
ERR("moniker doesn't support IROTData interface\n");
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
ULONG cbData;
|
|
|
|
hr = IROTData_GetComparisonData(pROTData, pbData, cbMax, &cbData);
|
|
|
|
IROTData_Release(pROTData);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
pbData += cbData;
|
|
|
|
cbMax -= cbData;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("IROTData_GetComparisonData failed with error 0x%08x\n", hr);
|
|
|
|
}
|
|
|
|
|
|
|
|
IMoniker_Release(pmk);
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
IEnumMoniker_Release(pEnumMk);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IEnumMoniker_Release(pEnumMk);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI CompositeMonikerMarshalImpl_QueryInterface(IMarshal *iface, REFIID riid, LPVOID *ppv)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMarshal(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppv);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return CompositeMonikerImpl_QueryInterface(&This->IMoniker_iface, riid, ppv);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI CompositeMonikerMarshalImpl_AddRef(IMarshal *iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMarshal(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n",iface);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return CompositeMonikerImpl_AddRef(&This->IMoniker_iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI CompositeMonikerMarshalImpl_Release(IMarshal *iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMarshal(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n",iface);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return CompositeMonikerImpl_Release(&This->IMoniker_iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI CompositeMonikerMarshalImpl_GetUnmarshalClass(
|
2012-05-17 15:16:51 +00:00
|
|
|
IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext,
|
2007-04-20 12:23:52 +00:00
|
|
|
void* pvDestContext, DWORD mshlflags, CLSID* pCid)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMarshal(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
|
|
|
|
dwDestContext, pvDestContext, mshlflags, pCid);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return IMoniker_GetClassID(&This->IMoniker_iface, pCid);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI CompositeMonikerMarshalImpl_GetMarshalSizeMax(
|
2012-05-17 15:16:51 +00:00
|
|
|
IMarshal *iface, REFIID riid, void *pv, DWORD dwDestContext,
|
2007-04-20 12:23:52 +00:00
|
|
|
void* pvDestContext, DWORD mshlflags, DWORD* pSize)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMarshal(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
IEnumMoniker *pEnumMk;
|
|
|
|
IMoniker *pmk;
|
|
|
|
HRESULT hr;
|
|
|
|
ULARGE_INTEGER size;
|
|
|
|
|
|
|
|
TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
|
|
|
|
dwDestContext, pvDestContext, mshlflags, pSize);
|
|
|
|
|
|
|
|
*pSize = 0x10; /* to match native */
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
hr = IMoniker_Enum(&This->IMoniker_iface, TRUE, &pEnumMk);
|
2007-04-20 12:23:52 +00:00
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
hr = IMoniker_GetSizeMax(&This->IMoniker_iface, &size);
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
|
|
|
|
{
|
|
|
|
ULONG size;
|
|
|
|
|
|
|
|
hr = CoGetMarshalSizeMax(&size, &IID_IMoniker, (IUnknown *)pmk, dwDestContext, pvDestContext, mshlflags);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
*pSize += size;
|
|
|
|
|
|
|
|
IMoniker_Release(pmk);
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
IEnumMoniker_Release(pEnumMk);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IEnumMoniker_Release(pEnumMk);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI CompositeMonikerMarshalImpl_MarshalInterface(IMarshal *iface, IStream *pStm,
|
2007-04-20 12:23:52 +00:00
|
|
|
REFIID riid, void* pv, DWORD dwDestContext,
|
|
|
|
void* pvDestContext, DWORD mshlflags)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMarshal(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
IEnumMoniker *pEnumMk;
|
|
|
|
IMoniker *pmk;
|
|
|
|
HRESULT hr;
|
|
|
|
ULONG i = 0;
|
|
|
|
|
|
|
|
TRACE("(%p, %s, %p, %x, %p, %x)\n", pStm, debugstr_guid(riid), pv,
|
|
|
|
dwDestContext, pvDestContext, mshlflags);
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
hr = IMoniker_Enum(&This->IMoniker_iface, TRUE, &pEnumMk);
|
2007-04-20 12:23:52 +00:00
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
|
|
|
|
while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
|
|
|
|
{
|
|
|
|
hr = CoMarshalInterface(pStm, &IID_IMoniker, (IUnknown *)pmk, dwDestContext, pvDestContext, mshlflags);
|
|
|
|
|
|
|
|
IMoniker_Release(pmk);
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
IEnumMoniker_Release(pEnumMk);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i != 2)
|
|
|
|
FIXME("moniker count of %d not supported\n", i);
|
|
|
|
|
|
|
|
IEnumMoniker_Release(pEnumMk);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI CompositeMonikerMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm,
|
|
|
|
REFIID riid, void **ppv)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl *This = impl_from_IMarshal(iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
TRACE("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
|
|
|
|
|
|
|
|
CompositeMonikerImpl_ReleaseMonikersInTable(This);
|
|
|
|
|
|
|
|
/* resize the table if needed */
|
|
|
|
if (This->tabLastIndex + 2 > This->tabSize)
|
|
|
|
{
|
|
|
|
This->tabSize += max(BLOCK_TAB_SIZE, 2);
|
2013-09-26 13:58:03 +00:00
|
|
|
This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(This->tabMoniker[0]));
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
if (This->tabMoniker==NULL)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
hr = CoUnmarshalInterface(pStm, &IID_IMoniker, (void**)&This->tabMoniker[This->tabLastIndex]);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
ERR("couldn't unmarshal moniker, hr = 0x%08x\n", hr);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
This->tabLastIndex++;
|
|
|
|
hr = CoUnmarshalInterface(pStm, &IID_IMoniker, (void**)&This->tabMoniker[This->tabLastIndex]);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
ERR("couldn't unmarshal moniker, hr = 0x%08x\n", hr);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
This->tabLastIndex++;
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
return IMoniker_QueryInterface(&This->IMoniker_iface, riid, ppv);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI CompositeMonikerMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
TRACE("(%p)\n", pStm);
|
|
|
|
/* can't release a state-based marshal as nothing on server side to
|
|
|
|
* release */
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
static HRESULT WINAPI CompositeMonikerMarshalImpl_DisconnectObject(IMarshal *iface,
|
|
|
|
DWORD dwReserved)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
TRACE("(0x%x)\n", dwReserved);
|
|
|
|
/* can't disconnect a state-based marshal as nothing on server side to
|
|
|
|
* disconnect from */
|
|
|
|
return S_OK;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* EnumMonikerImpl_QueryInterface
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
EnumMonikerImpl_QueryInterface(IEnumMoniker* iface,REFIID riid,void** ppvObject)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2016-11-22 12:30:48 +00:00
|
|
|
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/* Perform a sanity check on the parameters.*/
|
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
|
|
|
if ( ppvObject==0 )
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
/* Initialize the return parameter */
|
|
|
|
*ppvObject = 0;
|
|
|
|
|
|
|
|
/* Compare the riid with the interface IDs implemented by this object.*/
|
|
|
|
if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IEnumMoniker, riid))
|
|
|
|
*ppvObject = iface;
|
|
|
|
|
|
|
|
/* Check that we obtained an interface.*/
|
|
|
|
if ((*ppvObject)==0)
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
|
|
|
|
/* Query Interface always increases the reference count by one when it is successful */
|
|
|
|
IEnumMoniker_AddRef(iface);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* EnumMonikerImpl_AddRef
|
|
|
|
******************************************************************************/
|
|
|
|
static ULONG WINAPI
|
|
|
|
EnumMonikerImpl_AddRef(IEnumMoniker* iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n",This);
|
|
|
|
|
|
|
|
return InterlockedIncrement(&This->ref);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* EnumMonikerImpl_Release
|
|
|
|
******************************************************************************/
|
|
|
|
static ULONG WINAPI
|
|
|
|
EnumMonikerImpl_Release(IEnumMoniker* iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
ULONG i;
|
|
|
|
ULONG ref;
|
|
|
|
TRACE("(%p)\n",This);
|
|
|
|
|
|
|
|
ref = InterlockedDecrement(&This->ref);
|
|
|
|
|
2014-04-24 12:14:13 +00:00
|
|
|
/* destroy the object if there are no more references to it */
|
2005-07-31 12:11:56 +00:00
|
|
|
if (ref == 0) {
|
|
|
|
|
|
|
|
for(i=0;i<This->tabSize;i++)
|
|
|
|
IMoniker_Release(This->tabMoniker[i]);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(),0,This->tabMoniker);
|
|
|
|
HeapFree(GetProcessHeap(),0,This);
|
|
|
|
}
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* EnumMonikerImpl_Next
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt, IMoniker** rgelt,
|
|
|
|
ULONG* pceltFethed)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
ULONG i;
|
|
|
|
|
|
|
|
/* retrieve the requested number of moniker from the current position */
|
|
|
|
for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2005-07-31 12:11:56 +00:00
|
|
|
rgelt[i]=This->tabMoniker[This->currentPos++];
|
2007-04-20 12:23:52 +00:00
|
|
|
IMoniker_AddRef(rgelt[i]);
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (pceltFethed!=NULL)
|
|
|
|
*pceltFethed= i;
|
|
|
|
|
|
|
|
if (i==celt)
|
|
|
|
return S_OK;
|
|
|
|
else
|
|
|
|
return S_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* EnumMonikerImpl_Skip
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
EnumMonikerImpl_Skip(IEnumMoniker* iface,ULONG celt)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if ((This->currentPos+celt) >= This->tabSize)
|
|
|
|
return S_FALSE;
|
|
|
|
|
|
|
|
This->currentPos+=celt;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* EnumMonikerImpl_Reset
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
EnumMonikerImpl_Reset(IEnumMoniker* iface)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
This->currentPos=0;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* EnumMonikerImpl_Clone
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT WINAPI
|
|
|
|
EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
EnumMonikerImpl *This = impl_from_IEnumMoniker(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ppenum);
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
/* Virtual function table for the IROTData class */
|
2005-08-03 22:31:39 +00:00
|
|
|
static const IEnumMonikerVtbl VT_EnumMonikerImpl =
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
EnumMonikerImpl_QueryInterface,
|
|
|
|
EnumMonikerImpl_AddRef,
|
|
|
|
EnumMonikerImpl_Release,
|
|
|
|
EnumMonikerImpl_Next,
|
|
|
|
EnumMonikerImpl_Skip,
|
|
|
|
EnumMonikerImpl_Reset,
|
|
|
|
EnumMonikerImpl_Clone
|
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* EnumMonikerImpl_CreateEnumMoniker
|
|
|
|
******************************************************************************/
|
|
|
|
static HRESULT
|
|
|
|
EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker, ULONG tabSize,
|
2013-03-23 10:35:27 +00:00
|
|
|
ULONG currentPos, BOOL leftToRight, IEnumMoniker ** ppmk)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
EnumMonikerImpl* newEnumMoniker;
|
2013-03-23 10:35:27 +00:00
|
|
|
ULONG i;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (currentPos > tabSize)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
newEnumMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl));
|
|
|
|
|
|
|
|
if (newEnumMoniker == 0)
|
|
|
|
return STG_E_INSUFFICIENTMEMORY;
|
|
|
|
|
|
|
|
/* Initialize the virtual function table. */
|
2012-05-17 15:16:51 +00:00
|
|
|
newEnumMoniker->IEnumMoniker_iface.lpVtbl = &VT_EnumMonikerImpl;
|
2007-04-20 12:23:52 +00:00
|
|
|
newEnumMoniker->ref = 1;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
newEnumMoniker->tabSize=tabSize;
|
|
|
|
newEnumMoniker->currentPos=currentPos;
|
|
|
|
|
2013-09-26 13:58:03 +00:00
|
|
|
newEnumMoniker->tabMoniker=HeapAlloc(GetProcessHeap(),0,tabSize*sizeof(newEnumMoniker->tabMoniker[0]));
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (newEnumMoniker->tabMoniker==NULL) {
|
|
|
|
HeapFree(GetProcessHeap(), 0, newEnumMoniker);
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
2013-03-23 10:35:27 +00:00
|
|
|
if (leftToRight)
|
2005-07-31 12:11:56 +00:00
|
|
|
for (i=0;i<tabSize;i++){
|
|
|
|
|
|
|
|
newEnumMoniker->tabMoniker[i]=tabMoniker[i];
|
|
|
|
IMoniker_AddRef(tabMoniker[i]);
|
|
|
|
}
|
|
|
|
else
|
2013-03-23 10:35:27 +00:00
|
|
|
for (i = tabSize; i > 0; i--){
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2013-03-23 10:35:27 +00:00
|
|
|
newEnumMoniker->tabMoniker[tabSize-i]=tabMoniker[i - 1];
|
|
|
|
IMoniker_AddRef(tabMoniker[i - 1]);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
2012-05-17 15:16:51 +00:00
|
|
|
*ppmk=&newEnumMoniker->IEnumMoniker_iface;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
/* Virtual function table for the CompositeMonikerImpl class which includes */
|
|
|
|
/* IPersist, IPersistStream and IMoniker functions. */
|
|
|
|
|
2005-08-03 22:31:39 +00:00
|
|
|
static const IMonikerVtbl VT_CompositeMonikerImpl =
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
CompositeMonikerImpl_QueryInterface,
|
|
|
|
CompositeMonikerImpl_AddRef,
|
|
|
|
CompositeMonikerImpl_Release,
|
|
|
|
CompositeMonikerImpl_GetClassID,
|
|
|
|
CompositeMonikerImpl_IsDirty,
|
|
|
|
CompositeMonikerImpl_Load,
|
|
|
|
CompositeMonikerImpl_Save,
|
|
|
|
CompositeMonikerImpl_GetSizeMax,
|
|
|
|
CompositeMonikerImpl_BindToObject,
|
|
|
|
CompositeMonikerImpl_BindToStorage,
|
|
|
|
CompositeMonikerImpl_Reduce,
|
|
|
|
CompositeMonikerImpl_ComposeWith,
|
|
|
|
CompositeMonikerImpl_Enum,
|
|
|
|
CompositeMonikerImpl_IsEqual,
|
|
|
|
CompositeMonikerImpl_Hash,
|
|
|
|
CompositeMonikerImpl_IsRunning,
|
|
|
|
CompositeMonikerImpl_GetTimeOfLastChange,
|
|
|
|
CompositeMonikerImpl_Inverse,
|
|
|
|
CompositeMonikerImpl_CommonPrefixWith,
|
|
|
|
CompositeMonikerImpl_RelativePathTo,
|
|
|
|
CompositeMonikerImpl_GetDisplayName,
|
|
|
|
CompositeMonikerImpl_ParseDisplayName,
|
|
|
|
CompositeMonikerImpl_IsSystemMoniker
|
|
|
|
};
|
|
|
|
|
|
|
|
/********************************************************************************/
|
|
|
|
/* Virtual function table for the IROTData class. */
|
2005-08-03 22:31:39 +00:00
|
|
|
static const IROTDataVtbl VT_ROTDataImpl =
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
CompositeMonikerROTDataImpl_QueryInterface,
|
|
|
|
CompositeMonikerROTDataImpl_AddRef,
|
|
|
|
CompositeMonikerROTDataImpl_Release,
|
2007-04-20 12:23:52 +00:00
|
|
|
CompositeMonikerROTDataImpl_GetComparisonData
|
|
|
|
};
|
|
|
|
|
|
|
|
static const IMarshalVtbl VT_MarshalImpl =
|
|
|
|
{
|
|
|
|
CompositeMonikerMarshalImpl_QueryInterface,
|
|
|
|
CompositeMonikerMarshalImpl_AddRef,
|
|
|
|
CompositeMonikerMarshalImpl_Release,
|
|
|
|
CompositeMonikerMarshalImpl_GetUnmarshalClass,
|
|
|
|
CompositeMonikerMarshalImpl_GetMarshalSizeMax,
|
|
|
|
CompositeMonikerMarshalImpl_MarshalInterface,
|
|
|
|
CompositeMonikerMarshalImpl_UnmarshalInterface,
|
|
|
|
CompositeMonikerMarshalImpl_ReleaseMarshalData,
|
|
|
|
CompositeMonikerMarshalImpl_DisconnectObject
|
2005-07-31 12:11:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* Composite-Moniker_Construct (local function)
|
|
|
|
*******************************************************************************/
|
|
|
|
static HRESULT
|
2012-05-17 15:16:51 +00:00
|
|
|
CompositeMonikerImpl_Construct(IMoniker **ppMoniker, IMoniker *pmkFirst, IMoniker *pmkRest)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
DWORD mkSys;
|
|
|
|
IEnumMoniker *enumMoniker;
|
|
|
|
IMoniker *tempMk;
|
|
|
|
HRESULT res;
|
2007-04-20 12:23:52 +00:00
|
|
|
CompositeMonikerImpl *This;
|
2016-06-07 10:47:21 +00:00
|
|
|
int i;
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
|
|
|
|
|
|
|
|
if (!This)
|
|
|
|
return E_OUTOFMEMORY;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p,%p,%p)\n",This,pmkFirst,pmkRest);
|
|
|
|
|
|
|
|
/* Initialize the virtual function table. */
|
2012-05-17 15:16:51 +00:00
|
|
|
This->IMoniker_iface.lpVtbl = &VT_CompositeMonikerImpl;
|
|
|
|
This->IROTData_iface.lpVtbl = &VT_ROTDataImpl;
|
|
|
|
This->IMarshal_iface.lpVtbl = &VT_MarshalImpl;
|
2007-04-20 12:23:52 +00:00
|
|
|
This->ref = 1;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
This->tabSize=BLOCK_TAB_SIZE;
|
|
|
|
This->tabLastIndex=0;
|
|
|
|
|
2013-09-26 13:58:03 +00:00
|
|
|
This->tabMoniker=HeapAlloc(GetProcessHeap(),0,This->tabSize*sizeof(This->tabMoniker[0]));
|
2008-01-14 15:45:45 +00:00
|
|
|
if (This->tabMoniker==NULL) {
|
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_OUTOFMEMORY;
|
2008-01-14 15:45:45 +00:00
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (!pmkFirst && !pmkRest)
|
|
|
|
{
|
2012-05-17 15:16:51 +00:00
|
|
|
*ppMoniker = &This->IMoniker_iface;
|
2007-04-20 12:23:52 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
IMoniker_IsSystemMoniker(pmkFirst,&mkSys);
|
|
|
|
|
|
|
|
/* put the first moniker contents in the beginning of the table */
|
|
|
|
if (mkSys!=MKSYS_GENERICCOMPOSITE){
|
|
|
|
|
|
|
|
This->tabMoniker[(This->tabLastIndex)++]=pmkFirst;
|
|
|
|
IMoniker_AddRef(pmkFirst);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
|
|
|
|
IMoniker_Enum(pmkFirst,TRUE,&enumMoniker);
|
|
|
|
|
|
|
|
while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){
|
|
|
|
|
|
|
|
|
|
|
|
if (++This->tabLastIndex==This->tabSize){
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker **tab_moniker = This->tabMoniker;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
This->tabSize+=BLOCK_TAB_SIZE;
|
2016-06-07 10:47:21 +00:00
|
|
|
This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(This->tabMoniker[0]));
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (This->tabMoniker==NULL){
|
2016-06-07 10:47:21 +00:00
|
|
|
for (i = 0; i < This->tabLastIndex; i++)
|
|
|
|
IMoniker_Release(tab_moniker[i]);
|
2008-01-14 15:45:45 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, tab_moniker);
|
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_OUTOFMEMORY;
|
2008-01-14 15:45:45 +00:00
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IEnumMoniker_Release(enumMoniker);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* put the rest moniker contents after the first one and make simplification if needed */
|
|
|
|
|
|
|
|
IMoniker_IsSystemMoniker(pmkRest,&mkSys);
|
|
|
|
|
|
|
|
if (mkSys!=MKSYS_GENERICCOMPOSITE){
|
|
|
|
|
|
|
|
/* add a simple moniker to the moniker table */
|
|
|
|
|
|
|
|
res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],pmkRest,TRUE,&tempMk);
|
|
|
|
|
|
|
|
if (res==MK_E_NEEDGENERIC){
|
|
|
|
|
|
|
|
/* there's no simplification in this case */
|
|
|
|
This->tabMoniker[This->tabLastIndex]=pmkRest;
|
|
|
|
|
|
|
|
This->tabLastIndex++;
|
|
|
|
|
|
|
|
IMoniker_AddRef(pmkRest);
|
|
|
|
}
|
|
|
|
else if (tempMk==NULL){
|
|
|
|
|
|
|
|
/* we have an antimoniker after a simple moniker so we can make a simplification in this case */
|
|
|
|
IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
|
|
|
|
|
|
|
|
This->tabLastIndex--;
|
|
|
|
}
|
|
|
|
else if (SUCCEEDED(res)){
|
|
|
|
|
|
|
|
/* the non-generic composition was successful so we can make a simplification in this case */
|
|
|
|
IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
|
|
|
|
|
|
|
|
This->tabMoniker[This->tabLastIndex-1]=tempMk;
|
2016-06-07 10:47:21 +00:00
|
|
|
} else{
|
|
|
|
for (i = 0; i < This->tabLastIndex; i++)
|
|
|
|
IMoniker_Release(This->tabMoniker[i]);
|
|
|
|
HeapFree(GetProcessHeap(), 0, This->tabMoniker);
|
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
2005-07-31 12:11:56 +00:00
|
|
|
return res;
|
2016-06-07 10:47:21 +00:00
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/* resize tabMoniker if needed */
|
|
|
|
if (This->tabLastIndex==This->tabSize){
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker **tab_moniker = This->tabMoniker;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
This->tabSize+=BLOCK_TAB_SIZE;
|
|
|
|
|
|
|
|
This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (This->tabMoniker==NULL){
|
2016-06-07 10:47:21 +00:00
|
|
|
for (i = 0; i < This->tabLastIndex; i++)
|
|
|
|
IMoniker_Release(tab_moniker[i]);
|
2008-01-14 15:45:45 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, tab_moniker);
|
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
|
|
|
|
/* add a composite moniker to the moniker table (do the same thing
|
|
|
|
* for each moniker within the composite moniker as a simple moniker
|
|
|
|
* (see above for how to add a simple moniker case) )
|
|
|
|
*/
|
|
|
|
IMoniker_Enum(pmkRest,TRUE,&enumMoniker);
|
|
|
|
|
|
|
|
while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){
|
|
|
|
|
|
|
|
res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],This->tabMoniker[This->tabLastIndex],TRUE,&tempMk);
|
|
|
|
|
|
|
|
if (res==MK_E_NEEDGENERIC){
|
|
|
|
|
|
|
|
This->tabLastIndex++;
|
|
|
|
}
|
|
|
|
else if (tempMk==NULL){
|
|
|
|
|
|
|
|
IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
|
|
|
|
IMoniker_Release(This->tabMoniker[This->tabLastIndex]);
|
|
|
|
This->tabLastIndex--;
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
|
|
|
|
IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
|
|
|
|
|
|
|
|
This->tabMoniker[This->tabLastIndex-1]=tempMk;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (This->tabLastIndex==This->tabSize){
|
2016-06-07 10:47:21 +00:00
|
|
|
IMoniker **tab_moniker = This->tabMoniker;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
This->tabSize+=BLOCK_TAB_SIZE;
|
|
|
|
|
2013-09-26 13:58:03 +00:00
|
|
|
This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(This->tabMoniker[0]));
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (This->tabMoniker==NULL){
|
2016-06-07 10:47:21 +00:00
|
|
|
for (i = 0; i < This->tabLastIndex; i++)
|
|
|
|
IMoniker_Release(tab_moniker[i]);
|
2008-01-14 15:45:45 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, tab_moniker);
|
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_OUTOFMEMORY;
|
2008-01-14 15:45:45 +00:00
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IEnumMoniker_Release(enumMoniker);
|
|
|
|
}
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
/* only one moniker, then just return it */
|
|
|
|
if (This->tabLastIndex == 1)
|
|
|
|
{
|
|
|
|
*ppMoniker = This->tabMoniker[0];
|
|
|
|
IMoniker_AddRef(*ppMoniker);
|
2012-05-17 15:16:51 +00:00
|
|
|
IMoniker_Release(&This->IMoniker_iface);
|
2007-04-20 12:23:52 +00:00
|
|
|
}
|
|
|
|
else
|
2012-05-17 15:16:51 +00:00
|
|
|
*ppMoniker = &This->IMoniker_iface;
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* CreateGenericComposite [OLE32.@]
|
|
|
|
******************************************************************************/
|
|
|
|
HRESULT WINAPI
|
2012-05-17 15:16:51 +00:00
|
|
|
CreateGenericComposite(IMoniker *pmkFirst, IMoniker *pmkRest, IMoniker **ppmkComposite)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2007-04-20 12:23:52 +00:00
|
|
|
IMoniker* moniker = 0;
|
2005-07-31 12:11:56 +00:00
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
|
|
TRACE("(%p,%p,%p)\n",pmkFirst,pmkRest,ppmkComposite);
|
|
|
|
|
|
|
|
if (ppmkComposite==NULL)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppmkComposite=0;
|
|
|
|
|
|
|
|
if (pmkFirst==NULL && pmkRest!=NULL){
|
|
|
|
|
|
|
|
*ppmkComposite=pmkRest;
|
2014-04-24 12:14:13 +00:00
|
|
|
IMoniker_AddRef(pmkRest);
|
2005-07-31 12:11:56 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
else if (pmkFirst!=NULL && pmkRest==NULL){
|
|
|
|
*ppmkComposite=pmkFirst;
|
2014-04-24 12:14:13 +00:00
|
|
|
IMoniker_AddRef(pmkFirst);
|
2005-07-31 12:11:56 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
else if (pmkFirst==NULL && pmkRest==NULL)
|
|
|
|
return S_OK;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
hr = CompositeMonikerImpl_Construct(&moniker,pmkFirst,pmkRest);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (FAILED(hr))
|
2005-07-31 12:11:56 +00:00
|
|
|
return hr;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
hr = IMoniker_QueryInterface(moniker,&IID_IMoniker,(void**)ppmkComposite);
|
|
|
|
IMoniker_Release(moniker);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* MonikerCommonPrefixWith [OLE32.@]
|
|
|
|
******************************************************************************/
|
|
|
|
HRESULT WINAPI
|
|
|
|
MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkCommon)
|
|
|
|
{
|
|
|
|
FIXME("(),stub!\n");
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
2007-04-20 12:23:52 +00:00
|
|
|
|
2017-06-03 22:33:33 +00:00
|
|
|
HRESULT WINAPI CompositeMoniker_CreateInstance(IClassFactory *iface,
|
|
|
|
IUnknown *pUnk, REFIID riid, void **ppv)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
IMoniker* pMoniker;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
|
|
|
|
|
|
|
|
*ppv = NULL;
|
|
|
|
|
|
|
|
if (pUnk)
|
|
|
|
return CLASS_E_NOAGGREGATION;
|
|
|
|
|
|
|
|
hr = CompositeMonikerImpl_Construct(&pMoniker, NULL, NULL);
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = IMoniker_QueryInterface(pMoniker, riid, ppv);
|
|
|
|
IMoniker_Release(pMoniker);
|
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
}
|