📄 compositemoniker.c
字号:
/***********************************************************************
* CompositeMonikerIROTData_Release
*/
static ULONG WINAPI CompositeMonikerROTDataImpl_Release(IROTData* iface)
{
IMoniker *This = impl_from_IROTData(iface);
TRACE("(%p)\n",iface);
return IMoniker_Release(This);
}
/******************************************************************************
* CompositeMonikerIROTData_GetComparisonData
******************************************************************************/
static HRESULT WINAPI
CompositeMonikerROTDataImpl_GetComparisonData(IROTData* iface,
BYTE* pbData, ULONG cbMax, ULONG* pcbData)
{
IMoniker *This = impl_from_IROTData(iface);
IEnumMoniker *pEnumMk;
IMoniker *pmk;
HRESULT hr;
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
*pcbData = sizeof(CLSID);
hr = IMoniker_Enum(This, TRUE, &pEnumMk);
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)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppv);
return CompositeMonikerImpl_QueryInterface(This, riid, ppv);
}
static ULONG WINAPI CompositeMonikerMarshalImpl_AddRef(IMarshal *iface)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%p)\n",iface);
return CompositeMonikerImpl_AddRef(This);
}
static ULONG WINAPI CompositeMonikerMarshalImpl_Release(IMarshal *iface)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%p)\n",iface);
return CompositeMonikerImpl_Release(This);
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_GetUnmarshalClass(
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, CLSID* pCid)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pCid);
return IMoniker_GetClassID(This, pCid);
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_GetMarshalSizeMax(
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, DWORD* pSize)
{
IMoniker *This = impl_from_IMarshal(iface);
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 */
hr = IMoniker_Enum(This, TRUE, &pEnumMk);
if (FAILED(hr)) return hr;
hr = IMoniker_GetSizeMax(This, &size);
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;
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_MarshalInterface(LPMARSHAL iface, IStream *pStm,
REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags)
{
IMoniker *This = impl_from_IMarshal(iface);
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);
hr = IMoniker_Enum(This, TRUE, &pEnumMk);
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;
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
{
CompositeMonikerImpl *This = (CompositeMonikerImpl *)impl_from_IMarshal(iface);
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);
This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
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++;
return IMoniker_QueryInterface((IMoniker *)&This->lpvtbl1, riid, ppv);
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
{
TRACE("(%p)\n", pStm);
/* can't release a state-based marshal as nothing on server side to
* release */
return S_OK;
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved)
{
TRACE("(0x%x)\n", dwReserved);
/* can't disconnect a state-based marshal as nothing on server side to
* disconnect from */
return S_OK;
}
/******************************************************************************
* EnumMonikerImpl_QueryInterface
******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_QueryInterface(IEnumMoniker* iface,REFIID riid,void** ppvObject)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
/* Perform a sanity check on the parameters.*/
if ( (This==0) || (ppvObject==0) )
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)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
TRACE("(%p)\n",This);
return InterlockedIncrement(&This->ref);
}
/******************************************************************************
* EnumMonikerImpl_Release
******************************************************************************/
static ULONG WINAPI
EnumMonikerImpl_Release(IEnumMoniker* iface)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
ULONG i;
ULONG ref;
TRACE("(%p)\n",This);
ref = InterlockedDecrement(&This->ref);
/* destroy the object if there's no more reference on it */
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)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
ULONG i;
/* retrieve the requested number of moniker from the current position */
for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++)
{
rgelt[i]=This->tabMoniker[This->currentPos++];
IMoniker_AddRef(rgelt[i]);
}
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)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
if ((This->currentPos+celt) >= This->tabSize)
return S_FALSE;
This->currentPos+=celt;
return S_OK;
}
/******************************************************************************
* EnumMonikerImpl_Reset
******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_Reset(IEnumMoniker* iface)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
This->currentPos=0;
return S_OK;
}
/******************************************************************************
* EnumMonikerImpl_Clone
******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -