combase: Move Wdtp* marshalling functions.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-07-28 13:42:22 +03:00 committed by Alexandre Julliard
parent ed83583934
commit 7d67c412ea
6 changed files with 249 additions and 185 deletions

View File

@ -1,8 +1,10 @@
MODULE = combase.dll MODULE = combase.dll
IMPORTLIB = combase
IMPORTS = advapi32 ole32 uuid IMPORTS = advapi32 ole32 uuid
EXTRADLLFLAGS = -mno-cygwin EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ C_SRCS = \
roapi.c \ roapi.c \
string.c string.c \
usrmarshal.c

View File

@ -281,11 +281,13 @@
@ stdcall StringFromGUID2(ptr ptr long) ole32.StringFromGUID2 @ stdcall StringFromGUID2(ptr ptr long) ole32.StringFromGUID2
@ stdcall StringFromIID(ptr ptr) ole32.StringFromIID @ stdcall StringFromIID(ptr ptr) ole32.StringFromIID
@ stub UpdateDCOMSettings @ stub UpdateDCOMSettings
@ stdcall WdtpInterfacePointer_UserMarshal(ptr long ptr ptr ptr) ole32.WdtpInterfacePointer_UserMarshal @ stdcall WdtpInterfacePointer_UserFree(ptr)
@ stub WdtpInterfacePointer_UserFree64
@ stdcall WdtpInterfacePointer_UserMarshal(ptr long ptr ptr ptr)
@ stub WdtpInterfacePointer_UserMarshal64 @ stub WdtpInterfacePointer_UserMarshal64
@ stdcall WdtpInterfacePointer_UserSize(ptr long long ptr ptr) ole32.WdtpInterfacePointer_UserSize @ stdcall WdtpInterfacePointer_UserSize(ptr long long ptr ptr)
@ stub WdtpInterfacePointer_UserSize64 @ stub WdtpInterfacePointer_UserSize64
@ stdcall WdtpInterfacePointer_UserUnmarshal(ptr ptr ptr ptr) ole32.WdtpInterfacePointer_UserUnmarshal @ stdcall WdtpInterfacePointer_UserUnmarshal(ptr ptr ptr ptr)
@ stub WdtpInterfacePointer_UserUnmarshal64 @ stub WdtpInterfacePointer_UserUnmarshal64
@ stdcall WindowsCompareStringOrdinal(ptr ptr ptr) @ stdcall WindowsCompareStringOrdinal(ptr ptr ptr)
@ stdcall WindowsConcatString(ptr ptr ptr) @ stdcall WindowsConcatString(ptr ptr ptr)

231
dlls/combase/usrmarshal.c Normal file
View File

@ -0,0 +1,231 @@
/*
* Marshaling Routines
*
* Copyright 2005 Robert Shearman
* Copyright 2009 Huw Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#define NONAMELESSUNION
#include "ole2.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
#define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
#define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
#define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
#define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
static const char* debugstr_user_flags(ULONG *pFlags)
{
char buf[12];
const char* loword;
switch (LOWORD(*pFlags))
{
case MSHCTX_LOCAL:
loword = "MSHCTX_LOCAL";
break;
case MSHCTX_NOSHAREDMEM:
loword = "MSHCTX_NOSHAREDMEM";
break;
case MSHCTX_DIFFERENTMACHINE:
loword = "MSHCTX_DIFFERENTMACHINE";
break;
case MSHCTX_INPROC:
loword = "MSHCTX_INPROC";
break;
default:
sprintf(buf, "%d", LOWORD(*pFlags));
loword=buf;
}
if (HIWORD(*pFlags) == NDR_LOCAL_DATA_REPRESENTATION)
return wine_dbg_sprintf("MAKELONG(%s, NDR_LOCAL_DATA_REPRESENTATION)", loword);
else
return wine_dbg_sprintf("MAKELONG(%s, 0x%04x)", loword, HIWORD(*pFlags));
}
/******************************************************************************
* WdtpInterfacePointer_UserSize (combase.@)
*
* Calculates the buffer size required to marshal an interface pointer.
*
* PARAMS
* pFlags [I] Flags. See notes.
* RealFlags [I] The MSHCTX to use when marshaling the interface.
* punk [I] Interface pointer to size.
* StartingSize [I] Starting size of the buffer. This value is added on to
* the buffer size required for the clip format.
* riid [I] ID of interface to size.
*
* RETURNS
* The buffer size required to marshal an interface pointer 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.
*/
ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *pFlags, ULONG RealFlags, ULONG StartingSize, IUnknown *punk, REFIID riid)
{
DWORD marshal_size = 0;
HRESULT hr;
TRACE("%s, %#x, %u, %p, %s.\n", debugstr_user_flags(pFlags), RealFlags, StartingSize, punk, debugstr_guid(riid));
hr = CoGetMarshalSizeMax(&marshal_size, riid, punk, LOWORD(RealFlags), NULL, MSHLFLAGS_NORMAL);
if (FAILED(hr)) return StartingSize;
ALIGN_LENGTH(StartingSize, 3);
StartingSize += 2 * sizeof(DWORD);
return StartingSize + marshal_size;
}
/******************************************************************************
* WdtpInterfacePointer_UserMarshal (combase.@)
*
* Marshals an interface pointer into a buffer.
*
* PARAMS
* pFlags [I] Flags. See notes.
* RealFlags [I] The MSHCTX to use when marshaling the interface.
* pBuffer [I] Buffer to marshal the clip format into.
* punk [I] Interface pointer to marshal.
* riid [I] ID of interface 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.
*/
unsigned char * WINAPI WdtpInterfacePointer_UserMarshal(ULONG *pFlags, ULONG RealFlags, unsigned char *pBuffer, IUnknown *punk, REFIID riid)
{
HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, 0);
IStream *stm;
DWORD size;
void *ptr;
TRACE("%s, %#x, %p, &%p, %s.\n", debugstr_user_flags(pFlags), RealFlags, pBuffer, punk, debugstr_guid(riid));
if (!h) return NULL;
if (CreateStreamOnHGlobal(h, TRUE, &stm) != S_OK)
{
GlobalFree(h);
return NULL;
}
if (CoMarshalInterface(stm, riid, punk, LOWORD(RealFlags), NULL, MSHLFLAGS_NORMAL) != S_OK)
{
IStream_Release(stm);
return pBuffer;
}
ALIGN_POINTER(pBuffer, 3);
size = GlobalSize(h);
*(DWORD *)pBuffer = size;
pBuffer += sizeof(DWORD);
*(DWORD *)pBuffer = size;
pBuffer += sizeof(DWORD);
ptr = GlobalLock(h);
memcpy(pBuffer, ptr, size);
GlobalUnlock(h);
IStream_Release(stm);
return pBuffer + size;
}
/******************************************************************************
* WdtpInterfacePointer_UserUnmarshal (combase.@)
*
* Unmarshals an interface pointer from a buffer.
*
* PARAMS
* pFlags [I] Flags. See notes.
* pBuffer [I] Buffer to marshal the clip format from.
* ppunk [I/O] Address that receives the unmarshaled interface pointer.
* riid [I] ID of interface to unmarshal.
*
* 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.
*/
unsigned char * WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, IUnknown **ppunk, REFIID riid)
{
HRESULT hr;
HGLOBAL h;
IStream *stm;
DWORD size;
void *ptr;
IUnknown *orig;
TRACE("%s, %p, %p, %s.\n", debugstr_user_flags(pFlags), pBuffer, ppunk, debugstr_guid(riid));
ALIGN_POINTER(pBuffer, 3);
size = *(DWORD *)pBuffer;
pBuffer += sizeof(DWORD);
if (size != *(DWORD *)pBuffer)
RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
pBuffer += sizeof(DWORD);
/* FIXME: sanity check on size */
h = GlobalAlloc(GMEM_MOVEABLE, size);
if (!h) RaiseException(RPC_X_NO_MEMORY, 0, 0, NULL);
if (CreateStreamOnHGlobal(h, TRUE, &stm) != S_OK)
{
GlobalFree(h);
RaiseException(RPC_X_NO_MEMORY, 0, 0, NULL);
}
ptr = GlobalLock(h);
memcpy(ptr, pBuffer, size);
GlobalUnlock(h);
orig = *ppunk;
hr = CoUnmarshalInterface(stm, riid, (void**)ppunk);
IStream_Release(stm);
if (hr != S_OK) RaiseException(hr, 0, 0, NULL);
if (orig) IUnknown_Release(orig);
return pBuffer + size;
}
/******************************************************************************
* WdtpInterfacePointer_UserFree (combase.@)
*/
void WINAPI WdtpInterfacePointer_UserFree(IUnknown *punk)
{
TRACE("%p.\n", punk);
if (punk) IUnknown_Release(punk);
}

View File

@ -1,6 +1,6 @@
MODULE = ole32.dll MODULE = ole32.dll
IMPORTLIB = ole32 IMPORTLIB = ole32
IMPORTS = uuid advapi32 user32 gdi32 rpcrt4 IMPORTS = uuid advapi32 user32 gdi32 combase rpcrt4
DELAYIMPORTS = oleaut32 DELAYIMPORTS = oleaut32
EXTRADEFS = -D_OLE32_ EXTRADEFS = -D_OLE32_

View File

@ -287,10 +287,10 @@
@ stub UtConvertDvtd32toDvtd16 @ stub UtConvertDvtd32toDvtd16
@ stub UtGetDvtd16Info @ stub UtGetDvtd16Info
@ stub UtGetDvtd32Info @ stub UtGetDvtd32Info
@ stdcall WdtpInterfacePointer_UserFree(ptr) @ stdcall WdtpInterfacePointer_UserFree(ptr) combase.WdtpInterfacePointer_UserFree
@ stdcall WdtpInterfacePointer_UserMarshal(ptr long ptr ptr ptr) @ stdcall WdtpInterfacePointer_UserMarshal(ptr long ptr ptr ptr) combase.WdtpInterfacePointer_UserMarshal
@ stdcall WdtpInterfacePointer_UserSize(ptr long long ptr ptr) @ stdcall WdtpInterfacePointer_UserSize(ptr long long ptr ptr) combase.WdtpInterfacePointer_UserSize
@ stdcall WdtpInterfacePointer_UserUnmarshal(ptr ptr ptr ptr) @ stdcall WdtpInterfacePointer_UserUnmarshal(ptr ptr ptr ptr) combase.WdtpInterfacePointer_UserUnmarshal
@ stdcall WriteClassStg(ptr ptr) @ stdcall WriteClassStg(ptr ptr)
@ stdcall WriteClassStm(ptr ptr) @ stdcall WriteClassStm(ptr ptr)
@ stdcall WriteFmtUserTypeStg(ptr long ptr) @ stdcall WriteFmtUserTypeStg(ptr long ptr)

View File

@ -48,6 +48,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \ ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) ) ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *pFlags, ULONG RealFlags, ULONG StartingSize, IUnknown *punk, REFIID riid);
unsigned char * WINAPI WdtpInterfacePointer_UserMarshal(ULONG *pFlags, ULONG RealFlags, unsigned char *pBuffer,
IUnknown *punk, REFIID riid);
unsigned char * WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, IUnknown **ppunk, REFIID riid);
static const char* debugstr_user_flags(ULONG *pFlags) static const char* debugstr_user_flags(ULONG *pFlags)
{ {
char buf[12]; char buf[12];
@ -1491,182 +1496,6 @@ void __RPC_USER HMETAFILEPICT_UserFree(ULONG *pFlags, HMETAFILEPICT *phMfp)
} }
} }
/******************************************************************************
* WdtpInterfacePointer_UserSize [OLE32.@]
*
* Calculates the buffer size required to marshal an interface pointer.
*
* PARAMS
* pFlags [I] Flags. See notes.
* RealFlags [I] The MSHCTX to use when marshaling the interface.
* punk [I] Interface pointer to size.
* StartingSize [I] Starting size of the buffer. This value is added on to
* the buffer size required for the clip format.
* riid [I] ID of interface to size.
*
* RETURNS
* The buffer size required to marshal an interface pointer 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.
*/
ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *pFlags, ULONG RealFlags, ULONG StartingSize, IUnknown *punk, REFIID riid)
{
DWORD marshal_size = 0;
HRESULT hr;
TRACE("(%s, 0%x, %d, %p, %s)\n", debugstr_user_flags(pFlags), RealFlags, StartingSize, punk, debugstr_guid(riid));
hr = CoGetMarshalSizeMax(&marshal_size, riid, punk, LOWORD(RealFlags), NULL, MSHLFLAGS_NORMAL);
if(FAILED(hr)) return StartingSize;
ALIGN_LENGTH(StartingSize, 3);
StartingSize += 2 * sizeof(DWORD);
return StartingSize + marshal_size;
}
/******************************************************************************
* WdtpInterfacePointer_UserMarshal [OLE32.@]
*
* Marshals an interface pointer into a buffer.
*
* PARAMS
* pFlags [I] Flags. See notes.
* RealFlags [I] The MSHCTX to use when marshaling the interface.
* pBuffer [I] Buffer to marshal the clip format into.
* punk [I] Interface pointer to marshal.
* riid [I] ID of interface 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.
*/
unsigned char * WINAPI WdtpInterfacePointer_UserMarshal(ULONG *pFlags, ULONG RealFlags, unsigned char *pBuffer, IUnknown *punk, REFIID riid)
{
HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, 0);
IStream *stm;
DWORD size;
void *ptr;
TRACE("(%s, 0x%x, %p, &%p, %s)\n", debugstr_user_flags(pFlags), RealFlags, pBuffer, punk, debugstr_guid(riid));
if(!h) return NULL;
if(CreateStreamOnHGlobal(h, TRUE, &stm) != S_OK)
{
GlobalFree(h);
return NULL;
}
if(CoMarshalInterface(stm, riid, punk, LOWORD(RealFlags), NULL, MSHLFLAGS_NORMAL) != S_OK)
{
IStream_Release(stm);
return pBuffer;
}
ALIGN_POINTER(pBuffer, 3);
size = GlobalSize(h);
*(DWORD *)pBuffer = size;
pBuffer += sizeof(DWORD);
*(DWORD *)pBuffer = size;
pBuffer += sizeof(DWORD);
ptr = GlobalLock(h);
memcpy(pBuffer, ptr, size);
GlobalUnlock(h);
IStream_Release(stm);
return pBuffer + size;
}
/******************************************************************************
* WdtpInterfacePointer_UserUnmarshal [OLE32.@]
*
* Unmarshals an interface pointer from a buffer.
*
* PARAMS
* pFlags [I] Flags. See notes.
* pBuffer [I] Buffer to marshal the clip format from.
* ppunk [I/O] Address that receives the unmarshaled interface pointer.
* riid [I] ID of interface to unmarshal.
*
* 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.
*/
unsigned char * WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, IUnknown **ppunk, REFIID riid)
{
HRESULT hr;
HGLOBAL h;
IStream *stm;
DWORD size;
void *ptr;
IUnknown *orig;
TRACE("(%s, %p, %p, %s)\n", debugstr_user_flags(pFlags), pBuffer, ppunk, debugstr_guid(riid));
ALIGN_POINTER(pBuffer, 3);
size = *(DWORD *)pBuffer;
pBuffer += sizeof(DWORD);
if(size != *(DWORD *)pBuffer)
RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
pBuffer += sizeof(DWORD);
/* FIXME: sanity check on size */
h = GlobalAlloc(GMEM_MOVEABLE, size);
if(!h) RaiseException(RPC_X_NO_MEMORY, 0, 0, NULL);
if(CreateStreamOnHGlobal(h, TRUE, &stm) != S_OK)
{
GlobalFree(h);
RaiseException(RPC_X_NO_MEMORY, 0, 0, NULL);
}
ptr = GlobalLock(h);
memcpy(ptr, pBuffer, size);
GlobalUnlock(h);
orig = *ppunk;
hr = CoUnmarshalInterface(stm, riid, (void**)ppunk);
IStream_Release(stm);
if(hr != S_OK) RaiseException(hr, 0, 0, NULL);
if(orig) IUnknown_Release(orig);
return pBuffer + size;
}
/******************************************************************************
* WdtpInterfacePointer_UserFree [OLE32.@]
*
* Releases an unmarshaled interface pointer.
*
* PARAMS
* punk [I] Interface pointer to release.
*
* RETURNS
* Nothing.
*/
void WINAPI WdtpInterfacePointer_UserFree(IUnknown *punk)
{
TRACE("(%p)\n", punk);
if(punk) IUnknown_Release(punk);
}
/****************************************************************************** /******************************************************************************
* STGMEDIUM_UserSize [OLE32.@] * STGMEDIUM_UserSize [OLE32.@]
* *