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

📄 usrmarshal.c

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

/******************************************************************************
 *           HMETAFILEPICT_UserFree [OLE32.@]
 *
 * Frees an unmarshaled metafile pict.
 *
 * PARAMS
 *  pFlags   [I] Flags. See notes.
 *  phMfp    [I] Metafile pict to free.
 *
 * RETURNS
 *  The end of the marshaled data in the buffer.
 *
 * NOTES
 *  Even though the function is documented to take a pointer to a ULONG in
 *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
 *  which the first parameter is a ULONG.
 *  This function is only intended to be called by the RPC runtime.
 */
void __RPC_USER HMETAFILEPICT_UserFree(ULONG *pFlags, HMETAFILEPICT *phMfp)
{
    TRACE("(%s, &%p)\n", debugstr_user_flags(pFlags), *phMfp);

    if ((LOWORD(*pFlags) == MSHCTX_INPROC) && *phMfp)
    {
        METAFILEPICT *mfpict;

        mfpict = GlobalLock(*phMfp);
        /* FIXME: raise an exception if mfpict is NULL? */

        GlobalUnlock(*phMfp);
    }
}

/******************************************************************************
*           STGMEDIUM_UserSize [OLE32.@]
*
* Calculates the buffer size required to marshal an STGMEDIUM.
*
* PARAMS
*  pFlags       [I] Flags. See notes.
*  StartingSize [I] Starting size of the buffer. This value is added on to
*                   the buffer size required for the clip format.
*  pStgMedium   [I] STGMEDIUM to size.
*
* RETURNS
*  The buffer size required to marshal an STGMEDIUM plus the starting size.
*
* NOTES
*  Even though the function is documented to take a pointer to a ULONG in
*  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
*  the first parameter is a ULONG.
*  This function is only intended to be called by the RPC runtime.
*/
ULONG __RPC_USER STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, STGMEDIUM *pStgMedium)
{
    ULONG size = StartingSize;

    TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, pStgMedium);

    ALIGN_LENGTH(size, 3);

    size += 2 * sizeof(DWORD);
    if (pStgMedium->tymed != TYMED_NULL)
        size += sizeof(DWORD);

    switch (pStgMedium->tymed)
    {
    case TYMED_NULL:
        TRACE("TYMED_NULL\n");
        break;
    case TYMED_HGLOBAL:
        TRACE("TYMED_HGLOBAL\n");
        if (pStgMedium->u.hGlobal)
            size = HGLOBAL_UserSize(pFlags, size, &pStgMedium->u.hGlobal);
        break;
    case TYMED_FILE:
        TRACE("TYMED_FILE\n");
        if (pStgMedium->u.lpszFileName)
        {
            TRACE("file name is %s\n", debugstr_w(pStgMedium->u.lpszFileName));
            size += 3 * sizeof(DWORD) +
                (strlenW(pStgMedium->u.lpszFileName) + 1) * sizeof(WCHAR);
        }
        break;
    case TYMED_ISTREAM:
        TRACE("TYMED_ISTREAM\n");
        if (pStgMedium->u.pstm)
        {
            FIXME("not implemented for IStream %p\n", pStgMedium->u.pstm);
        }
        break;
    case TYMED_ISTORAGE:
        TRACE("TYMED_ISTORAGE\n");
        if (pStgMedium->u.pstg)
        {
            FIXME("not implemented for IStorage %p\n", pStgMedium->u.pstg);
        }
        break;
    case TYMED_GDI:
        TRACE("TYMED_GDI\n");
        if (pStgMedium->u.hBitmap)
        {
            FIXME("not implemented for GDI object %p\n", pStgMedium->u.hBitmap);
        }
        break;
    case TYMED_MFPICT:
        TRACE("TYMED_MFPICT\n");
        if (pStgMedium->u.hMetaFilePict)
            size = HMETAFILEPICT_UserSize(pFlags, size, &pStgMedium->u.hMetaFilePict);
        break;
    case TYMED_ENHMF:
        TRACE("TYMED_ENHMF\n");
        if (pStgMedium->u.hEnhMetaFile)
            size = HENHMETAFILE_UserSize(pFlags, size, &pStgMedium->u.hEnhMetaFile);
        break;
    default:
        RaiseException(DV_E_TYMED, 0, 0, NULL);
    }

    if (pStgMedium->pUnkForRelease)
        FIXME("buffer size pUnkForRelease\n");

    return size;
}

/******************************************************************************
 *           STGMEDIUM_UserMarshal [OLE32.@]
 *
 * Marshals a STGMEDIUM into a buffer.
 *
 * PARAMS
 *  pFlags  [I] Flags. See notes.
 *  pBuffer [I] Buffer to marshal the clip format into.
 *  pCF     [I] STGMEDIUM to marshal.
 *
 * RETURNS
 *  The end of the marshaled data in the buffer.
 *
 * NOTES
 *  Even though the function is documented to take a pointer to a ULONG in
 *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
 *  the first parameter is a ULONG.
 *  This function is only intended to be called by the RPC runtime.
 */
unsigned char * __RPC_USER STGMEDIUM_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
{
    TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, pStgMedium);

    ALIGN_POINTER(pBuffer, 3);

    *(DWORD *)pBuffer = pStgMedium->tymed;
    pBuffer += sizeof(DWORD);
    if (pStgMedium->tymed != TYMED_NULL)
    {
        *(DWORD *)pBuffer = (DWORD)(DWORD_PTR)pStgMedium->u.pstg;
        pBuffer += sizeof(DWORD);
    }
    *(DWORD *)pBuffer = (DWORD)(DWORD_PTR)pStgMedium->pUnkForRelease;
    pBuffer += sizeof(DWORD);

    switch (pStgMedium->tymed)
    {
    case TYMED_NULL:
        TRACE("TYMED_NULL\n");
        break;
    case TYMED_HGLOBAL:
        TRACE("TYMED_HGLOBAL\n");
        if (pStgMedium->u.hGlobal)
            pBuffer = HGLOBAL_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hGlobal);
        break;
    case TYMED_FILE:
        TRACE("TYMED_FILE\n");
        if (pStgMedium->u.lpszFileName)
        {
            DWORD len;
            len = strlenW(pStgMedium->u.lpszFileName);
            /* conformance */
            *(DWORD *)pBuffer = len + 1;
            pBuffer += sizeof(DWORD);
            /* offset */
            *(DWORD *)pBuffer = 0;
            pBuffer += sizeof(DWORD);
            /* variance */
            *(DWORD *)pBuffer = len + 1;
            pBuffer += sizeof(DWORD);

            TRACE("file name is %s\n", debugstr_w(pStgMedium->u.lpszFileName));
            memcpy(pBuffer, pStgMedium->u.lpszFileName, (len + 1) * sizeof(WCHAR));
        }
        break;
    case TYMED_ISTREAM:
        TRACE("TYMED_ISTREAM\n");
        if (pStgMedium->u.pstm)
        {
            FIXME("not implemented for IStream %p\n", pStgMedium->u.pstm);
        }
        break;
    case TYMED_ISTORAGE:
        TRACE("TYMED_ISTORAGE\n");
        if (pStgMedium->u.pstg)
        {
            FIXME("not implemented for IStorage %p\n", pStgMedium->u.pstg);
        }
        break;
    case TYMED_GDI:
        TRACE("TYMED_GDI\n");
        if (pStgMedium->u.hBitmap)
        {
            FIXME("not implemented for GDI object %p\n", pStgMedium->u.hBitmap);
        }
        break;
    case TYMED_MFPICT:
        TRACE("TYMED_MFPICT\n");
        if (pStgMedium->u.hMetaFilePict)
            pBuffer = HMETAFILEPICT_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hMetaFilePict);
        break;
    case TYMED_ENHMF:
        TRACE("TYMED_ENHMF\n");
        if (pStgMedium->u.hEnhMetaFile)
            pBuffer = HENHMETAFILE_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hEnhMetaFile);
        break;
    default:
        RaiseException(DV_E_TYMED, 0, 0, NULL);
    }

    if (pStgMedium->pUnkForRelease)
        FIXME("marshal pUnkForRelease\n");

    return pBuffer;
}

/******************************************************************************
 *           STGMEDIUM_UserUnmarshal [OLE32.@]
 *
 * Unmarshals a STGMEDIUM from a buffer.
 *
 * PARAMS
 *  pFlags     [I] Flags. See notes.
 *  pBuffer    [I] Buffer to marshal the clip format from.
 *  pStgMedium [O] Address that receive the unmarshaled STGMEDIUM.
 *
 * RETURNS
 *  The end of the marshaled data in the buffer.
 *
 * NOTES
 *  Even though the function is documented to take a pointer to an ULONG in
 *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
 *  the first parameter is an ULONG.
 *  This function is only intended to be called by the RPC runtime.
 */
unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
{
    DWORD content = 0;
    DWORD releaseunk;

    ALIGN_POINTER(pBuffer, 3);

    TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, pStgMedium);

    pStgMedium->tymed = *(DWORD *)pBuffer;
    pBuffer += sizeof(DWORD);
    if (pStgMedium->tymed != TYMED_NULL)
    {
        content = *(DWORD *)pBuffer;
        pBuffer += sizeof(DWORD);
    }
    releaseunk = *(DWORD *)pBuffer;
    pBuffer += sizeof(DWORD);

    switch (pStgMedium->tymed)
    {
    case TYMED_NULL:
        TRACE("TYMED_NULL\n");
        break;
    case TYMED_HGLOBAL:
        TRACE("TYMED_HGLOBAL\n");
        if (content)
            pBuffer = HGLOBAL_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hGlobal);
        break;
    case TYMED_FILE:
        TRACE("TYMED_FILE\n");
        if (content)
        {
            DWORD conformance;
            DWORD variance;
            conformance = *(DWORD *)pBuffer;
            pBuffer += sizeof(DWORD);
            if (*(DWORD *)pBuffer != 0)
            {
                ERR("invalid offset %d\n", *(DWORD *)pBuffer);
                RpcRaiseException(RPC_S_INVALID_BOUND);
                return NULL;
            }
            pBuffer += sizeof(DWORD);
            variance = *(DWORD *)pBuffer;
            pBuffer += sizeof(DWORD);
            if (conformance != variance)
            {
                ERR("conformance (%d) and variance (%d) should be equal\n",
                    conformance, variance);
                RpcRaiseException(RPC_S_INVALID_BOUND);
                return NULL;
            }
            if (conformance > 0x7fffffff)
            {
                ERR("conformance 0x%x too large\n", conformance);
                RpcRaiseException(RPC_S_INVALID_BOUND);
                return NULL;
            }
            pStgMedium->u.lpszFileName = CoTaskMemAlloc(conformance * sizeof(WCHAR));
            if (!pStgMedium->u.lpszFileName) RpcRaiseException(ERROR_OUTOFMEMORY);
            TRACE("unmarshalled file name is %s\n", debugstr_wn((const WCHAR *)pBuffer, variance));
            memcpy(pStgMedium->u.lpszFileName, pBuffer, variance * sizeof(WCHAR));
            pBuffer += variance * sizeof(WCHAR);
        }
        else
            pStgMedium->u.lpszFileName = NULL;
        break;
    case TYMED_ISTREAM:
        TRACE("TYMED_ISTREAM\n");
        if (content)
        {
            FIXME("not implemented for IStream\n");
        }
        else
            pStgMedium->u.pstm = NULL;
        break;
    case TYMED_ISTORAGE:
        TRACE("TYMED_ISTORAGE\n");
        if (content)
        {
            FIXME("not implemented for IStorage\n");
        }
        else
            pStgMedium->u.pstg = NULL;
        break;
    case TYMED_GDI:
        TRACE("TYMED_GDI\n");
        if (content)
        {
            FIXME("not implemented for GDI object\n");
        }
        else
            pStgMedium->u.hBitmap = NULL;
        break;
    case TYMED_MFPICT:
        TRACE("TYMED_MFPICT\n");
        if (content)
            pBuffer = HMETAFILEPICT_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hMetaFilePict);
        else
            pStgMedium->u.hMetaFilePict = NULL;
        break;
    case TYMED_ENHMF:
        TRACE("TYMED_ENHMF\n");
        if (content)
            pBuffer = HENHMETAFILE_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hEnhMetaFile);
        else
            pStgMedium->u.hEnhMetaFile = NULL;
        break;
    default:
        RaiseException(DV_E_TYMED, 0, 0, NULL);
    }

    pStgMedium->pUnkForRelease = NULL;
    if (releaseunk)
        FIXME("unmarshal pUnkForRelease\n");

    return pBuffer;
}

/******************************************************************************
 *           STGMEDIUM_UserFree [OLE32.@]
 *
 * Frees an unmarshaled STGMEDIUM.
 *
 * PARAMS
 *  pFlags     [I] Flags. See notes.
 *  pStgmedium [I] STGMEDIUM to free.
 *
 * RETURNS
 *  The end of the marshaled data in the buffer.
 *
 * NOTES
 *  Even though the function is documented to take a pointer to a ULONG in
 *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
 *  which the first parameter is a ULONG.
 *  This function is only intended to be called by the RPC runtime.
 */
void __RPC_USER STGMEDIUM_UserFree(ULONG *pFlags, STGMEDIUM *pStgMedium)
{
    TRACE("(%s, %p\n", debugstr_user_flags(pFlags), pStgMedium);

    ReleaseStgMedium(pStgMedium);
}

ULONG __RPC_USER ASYNC_STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, ASYNC_STGMEDIUM *pStgMedium)
{
    FIXME(":stub\n");
    return StartingSize;
}

unsigned char * __RPC_USER ASYNC_STGMEDIUM_UserMarshal(  ULONG *pFlags, unsigned char *pBuffer, ASYNC_STGMEDIUM *pStgMedium)
{
    FIXME(":stub\n");
    return pBuffer;
}

unsigned char * __RPC_USER ASYNC_STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, ASYNC_STGMEDIUM *pStgMedium)
{
    FIXME(":stub\n");
    return pBuffer;
}

void __RPC_USER ASYNC_STGMEDIUM_UserFree(ULONG *pFlags, ASYNC_STGMEDIUM *pStgMedium)
{
    FIXME(":stub\n");
}

ULONG __RPC_USER FLAG_STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, FLAG_STGMEDIUM *pStgMedium)
{
    FIXME(":stub\n");
    return StartingSize;
}

unsigned char * __RPC_USER FLAG_STGMEDIUM_UserMarshal(  ULONG *pFlags, unsigned char *pBuffer, FLAG_STGMEDIUM *pStgMedium)
{
    FIXME(":stub\n");
    return pBuffer;
}

unsigned char * __RPC_USER FLAG_STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, FLAG_STGMEDIUM *pStgMedium)
{
    FIXME(":stub\n");
    return pBuffer;
}

void __RPC_USER FLAG_STGMEDIUM_UserFree(ULONG *pFlags, FLAG_STGMEDIUM *pStgMedium)
{
    FIXME(":stub\n");
}

ULONG __RPC_USER SNB_UserSize(ULONG *pFlags, ULONG StartingSize, SNB *pSnb)
{
    FIXME(":stub\n");
    return StartingSize;
}

unsigned char * __RPC_USER SNB_UserMarshal(  ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
{
    FIXME(":stub\n");
    return pBuffer;
}

unsigned char * __RPC_USER SNB_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
{
    FIXME(":stub\n");
    return pBuffer;
}

void __RPC_USER SNB_UserFree(ULONG *pFlags, SNB *pSnb)
{
    FIXME(":stub\n");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -