⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compositemoniker.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:

/***********************************************************************
 *        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 + -