From 251bab8ac9909c2dcf4447918dfcd58349f95ded Mon Sep 17 00:00:00 2001 From: Rob Shearman Date: Mon, 19 Mar 2007 14:55:59 +0000 Subject: [PATCH] ole32: Implement TYMED_FILE for STGMEDIUM marshaling and unmarshaling. --- dlls/ole32/usrmarshal.c | 69 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/dlls/ole32/usrmarshal.c b/dlls/ole32/usrmarshal.c index 785d2681df8..550b2012ecc 100644 --- a/dlls/ole32/usrmarshal.c +++ b/dlls/ole32/usrmarshal.c @@ -35,6 +35,8 @@ #include "ole2.h" #include "oleauto.h" #include "rpcproxy.h" + +#include "wine/unicode.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -1471,7 +1473,13 @@ ULONG __RPC_USER STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, STGMEDIUM size = HGLOBAL_UserSize(pFlags, size, &pStgMedium->u.hGlobal); break; case TYMED_FILE: - FIXME("TYMED_FILE\n"); + 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: FIXME("TYMED_ISTREAM\n"); @@ -1545,7 +1553,24 @@ unsigned char * __RPC_USER STGMEDIUM_UserMarshal(ULONG *pFlags, unsigned char *p pBuffer = HGLOBAL_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hGlobal); break; case TYMED_FILE: - FIXME("TYMED_FILE\n"); + 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: FIXME("TYMED_ISTREAM\n"); @@ -1595,7 +1620,7 @@ unsigned char * __RPC_USER STGMEDIUM_UserMarshal(ULONG *pFlags, unsigned char *p */ unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium) { - DWORD content; + DWORD content = 0; DWORD releaseunk; ALIGN_POINTER(pBuffer, 3); @@ -1622,7 +1647,43 @@ unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char pBuffer = HGLOBAL_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hGlobal); break; case TYMED_FILE: - FIXME("TYMED_FILE\n"); + 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: FIXME("TYMED_ISTREAM\n");