From: Alexandre Julliard julliard@winehq.org
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/rpcrt4/Makefile.in | 8 +++-- dlls/rpcrt4/ndr_typelib.c | 75 +++++++++++++++++++++++++++++++++++++-- dlls/rpcrt4/ndr_types.idl | 30 ++++++++++++++++ 3 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 dlls/rpcrt4/ndr_types.idl
diff --git a/dlls/rpcrt4/Makefile.in b/dlls/rpcrt4/Makefile.in index ad67edf92e..2aa2a5376a 100644 --- a/dlls/rpcrt4/Makefile.in +++ b/dlls/rpcrt4/Makefile.in @@ -2,7 +2,9 @@ EXTRADEFS = -D_RPCRT4_ -DMSWMSG MODULE = rpcrt4.dll IMPORTLIB = rpcrt4 IMPORTS = uuid advapi32 -DELAYIMPORTS = iphlpapi wininet secur32 user32 ws2_32 +DELAYIMPORTS = iphlpapi wininet secur32 user32 ws2_32 oleaut32 + +ndr_types_EXTRAIDLFLAGS = -Oicf
C_SRCS = \ cproxy.c \ @@ -27,4 +29,6 @@ C_SRCS = \
RC_SRCS = version.rc
-IDL_SRCS = epm.idl +IDL_SRCS = \ + epm.idl \ + ndr_types.idl diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c index 37926dfb99..f81902623c 100644 --- a/dlls/rpcrt4/ndr_typelib.c +++ b/dlls/rpcrt4/ndr_typelib.c @@ -29,6 +29,9 @@ #include "wine/heap.h"
#include "cpsf.h" +#include "initguid.h" +#include "ndr_types.h" +#include "ndr_stubless.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -42,6 +45,67 @@ static size_t write_type_tfs(ITypeInfo *typeinfo, unsigned char *str, #define WRITE_INT(str, len, val) \ do { if ((str)) *((int *)((str) + (len))) = (val); (len) += 4; } while (0)
+extern const ExtendedProxyFileInfo ndr_types_ProxyFileInfo; + +static const MIDL_STUBLESS_PROXY_INFO *get_ndr_types_proxy_info(void) +{ + return ndr_types_ProxyFileInfo.pProxyVtblList[0]->header.pStublessProxyInfo; +} + +static const NDR_PARAM_OIF *get_ndr_types_params( unsigned int *nb_params ) +{ + const MIDL_STUBLESS_PROXY_INFO *proxy = get_ndr_types_proxy_info(); + const unsigned char *format = proxy->ProcFormatString + proxy->FormatStringOffset[3]; + const NDR_PROC_HEADER *proc = (const NDR_PROC_HEADER *)format; + const NDR_PROC_PARTIAL_OIF_HEADER *header; + + if (proc->Oi_flags & Oi_HAS_RPCFLAGS) + format += sizeof(NDR_PROC_HEADER_RPC); + else + format += sizeof(NDR_PROC_HEADER); + + header = (const NDR_PROC_PARTIAL_OIF_HEADER *)format; + format += sizeof(*header); + if (header->Oi2Flags.HasExtensions) + { + const NDR_PROC_HEADER_EXTS *ext = (const NDR_PROC_HEADER_EXTS *)format; + format += ext->Size; + } + *nb_params = header->number_of_params; + return (const NDR_PARAM_OIF *)format; +} + +static unsigned short get_tfs_offset( int param ) +{ + unsigned int nb_params; + const NDR_PARAM_OIF *params = get_ndr_types_params( &nb_params ); + + assert( param < nb_params ); + return params[param].u.type_offset; +} + +static const unsigned char *get_type_format_string( size_t *size ) +{ + unsigned int nb_params; + const NDR_PARAM_OIF *params = get_ndr_types_params( &nb_params ); + + *size = params[nb_params - 1].u.type_offset; + return get_ndr_types_proxy_info()->pStubDesc->pFormatTypes; +} + +static unsigned short write_oleaut_tfs(VARTYPE vt) +{ + switch (vt) + { + case VT_BSTR: return get_tfs_offset( 0 ); + case VT_UNKNOWN: return get_tfs_offset( 1 ); + case VT_DISPATCH: return get_tfs_offset( 2 ); + case VT_VARIANT: return get_tfs_offset( 3 ); + case VT_SAFEARRAY: return get_tfs_offset( 4 ); + } + return 0; +} + static unsigned char get_base_type(VARTYPE vt) { switch (vt) @@ -341,6 +405,9 @@ static size_t write_type_tfs(ITypeInfo *typeinfo, unsigned char *str,
TRACE("vt %d%s\n", desc->vt, toplevel ? " (toplevel)" : "");
+ if ((off = write_oleaut_tfs(desc->vt))) + return off; + switch (desc->vt) { case VT_PTR: @@ -684,7 +751,9 @@ static HRESULT build_format_strings(ITypeInfo *typeinfo, WORD funcs, const unsigned char **type_ret, const unsigned char **proc_ret, unsigned short **offset_ret) { - size_t typelen = 0, proclen = 0; + size_t tfs_size; + const unsigned char *tfs = get_type_format_string( &tfs_size ); + size_t typelen = tfs_size, proclen = 0; unsigned char *type, *proc; unsigned short *offset; HRESULT hr; @@ -702,7 +771,8 @@ static HRESULT build_format_strings(ITypeInfo *typeinfo, WORD funcs, goto err; }
- typelen = 0; + memcpy(type, tfs, tfs_size); + typelen = tfs_size; proclen = 0;
hr = write_iface_fs(typeinfo, funcs, type, &typelen, proc, &proclen, offset); @@ -759,6 +829,7 @@ static void init_stub_desc(MIDL_STUB_DESC *desc) desc->pfnAllocate = NdrOleAllocate; desc->pfnFree = NdrOleFree; desc->Version = 0x50002; + desc->aUserMarshalQuadruple = get_ndr_types_proxy_info()->pStubDesc->aUserMarshalQuadruple; /* type format string is initialized with proc format string and offset table */ }
diff --git a/dlls/rpcrt4/ndr_types.idl b/dlls/rpcrt4/ndr_types.idl new file mode 100644 index 0000000000..ff34ae47fb --- /dev/null +++ b/dlls/rpcrt4/ndr_types.idl @@ -0,0 +1,30 @@ +/* + * Copyright 2018 Alexandre Julliard + * + * 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 + */ + +#pragma makedep proxy + +import "oaidl.idl"; + +[ + object, + uuid(bfc61495-76bb-4855-8c2f-3764fd42523a) +] +interface dummy : IUnknown +{ + void dummy( BSTR a, IUnknown *b, IDispatch *c, VARIANT d, LPSAFEARRAY e, BSTR *last ); +}