[PATCH] ole32: Call individual UserFree() functions in STGMEDIUM_UserFree().

Huw Davies huw at codeweavers.com
Wed Dec 12 05:00:32 CST 2018


On Tue, Dec 11, 2018 at 03:25:36PM -0600, Zebediah Figura wrote:
> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46270
> Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
> ---
>  dlls/ole32/usrmarshal.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 48 insertions(+), 3 deletions(-)
> 
> diff --git a/dlls/ole32/usrmarshal.c b/dlls/ole32/usrmarshal.c
> index 772bff5f5e..e2a786098c 100644
> --- a/dlls/ole32/usrmarshal.c
> +++ b/dlls/ole32/usrmarshal.c
> @@ -2036,11 +2036,56 @@ unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char
>   *  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)
> +void __RPC_USER STGMEDIUM_UserFree(ULONG *flags, STGMEDIUM *med)
>  {
> -    TRACE("(%s, %p\n", debugstr_user_flags(pFlags), pStgMedium);
> +    TRACE("(%s, %p)\n", debugstr_user_flags(flags), med);
>  
> -    ReleaseStgMedium(pStgMedium);
> +    switch(med->tymed)
> +    {
> +    case TYMED_NULL:
> +        break;
> +    case TYMED_HGLOBAL:
> +        if (!med->pUnkForRelease)
> +            HGLOBAL_UserFree(flags, &med->u.hGlobal);
> +        break;
> +    case TYMED_FILE:
> +        if (med->u.lpszFileName)
> +        {
> +            if (!med->pUnkForRelease)
> +                DeleteFileW(med->u.lpszFileName);
> +            CoTaskMemFree(med->u.lpszFileName);
> +        }
> +        break;
> +    case TYMED_ISTREAM:
> +        if (med->u.pstm)
> +            IStream_Release(med->u.pstm);
> +        break;
> +    case TYMED_ISTORAGE:
> +        if (med->u.pstg)
> +            IStorage_Release(med->u.pstg);
> +        break;
> +    case TYMED_GDI:
> +        if (!med->pUnkForRelease)
> +            HBITMAP_UserFree(flags, &med->u.hBitmap);
> +        break;
> +    case TYMED_MFPICT:
> +        if (!med->pUnkForRelease)
> +            HMETAFILEPICT_UserFree(flags, &med->u.hMetaFilePict);
> +        break;
> +    case TYMED_ENHMF:
> +        if (!med->pUnkForRelease)
> +            HENHMETAFILE_UserFree(flags, &med->u.hEnhMetaFile);
> +        break;
> +    default:
> +        RaiseException(DV_E_TYMED, 0, 0, NULL);
> +    }
> +    med->tymed = TYMED_NULL;
> +
> +    if (med->pUnkForRelease)
> +    {
> +        IUnknown_Release(med->pUnkForRelease);
> +        med->pUnkForRelease = NULL;
> +    }
>  }

Rather than re-coding ReleaseStgMedium() I think it would be neater to
reuse it when we can.  Something like:

switch (med->tymed)
{
case TYMED_NULL:
case TYMED_FILE:
case TYMED_ISTREAM:
case TYMED_ISTORAGE:
    ReleaseStgMedium(med);
    break;
case TYMED_HGLOBAL:
case TYMED_GDI:
case TYMED_MFPICT:
case TYMED_ENHMF:
    if (LOWORD(*flags) == MSHCTX_INPROC)
    {
        if (med->pUnkForRelease)
        {
            IUnknown_Release(med->pUnkForRelease);
            med->pUnkForRelease = NULL;
        }
        med->tymed = TYMED_NULL;
    }
    else
        ReleaseStgMedium(med);
    break;
default:
    RaiseExeception(blah);
}

Huw.



More information about the wine-devel mailing list