oleaut32: Rip out the old typelib marshaller.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Marcus Meissner <marcus@jet.franken.de>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2018-11-09 18:02:00 -06:00 committed by Alexandre Julliard
parent 0c642cc043
commit 077b4391d4
6 changed files with 255 additions and 2445 deletions

View File

@ -14,7 +14,6 @@ C_SRCS = \
olepropframe.c \
recinfo.c \
safearray.c \
tmarshal.c \
typelib.c \
usrmarshal.c \
varformat.c \

View File

@ -21,6 +21,7 @@
#include "config.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
@ -766,6 +767,230 @@ extern BOOL WINAPI OLEAUTPS_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
extern HRESULT WINAPI OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN;
extern HRESULT WINAPI OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN;
extern HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo,
IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **obj);
extern HRESULT WINAPI CreateStubFromTypeInfo(ITypeInfo *typeinfo, REFIID iid,
IUnknown *server, IRpcStubBuffer **stub);
struct ifacepsredirect_data
{
ULONG size;
DWORD mask;
GUID iid;
ULONG nummethods;
GUID tlbid;
GUID base;
ULONG name_len;
ULONG name_offset;
};
struct tlibredirect_data
{
ULONG size;
DWORD res;
ULONG name_len;
ULONG name_offset;
LANGID langid;
WORD flags;
ULONG help_len;
ULONG help_offset;
WORD major_version;
WORD minor_version;
};
static BOOL actctx_get_typelib_module(REFIID iid, WCHAR *module, DWORD len)
{
struct ifacepsredirect_data *iface;
struct tlibredirect_data *tlib;
ACTCTX_SECTION_KEYED_DATA data;
WCHAR *ptrW;
data.cbSize = sizeof(data);
if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
iid, &data))
return FALSE;
iface = (struct ifacepsredirect_data *)data.lpData;
if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION,
&iface->tlbid, &data))
return FALSE;
tlib = (struct tlibredirect_data *)data.lpData;
ptrW = (WCHAR *)((BYTE *)data.lpSectionBase + tlib->name_offset);
if (tlib->name_len/sizeof(WCHAR) >= len)
{
ERR("need larger module buffer, %u\n", tlib->name_len);
return FALSE;
}
memcpy(module, ptrW, tlib->name_len);
module[tlib->name_len/sizeof(WCHAR)] = 0;
return TRUE;
}
static HRESULT reg_get_typelib_module(REFIID iid, WCHAR *module, DWORD len)
{
REGSAM opposite = (sizeof(void*) == 8) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
char tlguid[200], typelibkey[300], interfacekey[300], ver[100], tlfn[260];
DWORD tlguidlen, verlen, type;
LONG tlfnlen, err;
BOOL is_wow64;
HKEY ikey;
sprintf( interfacekey, "Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
iid->Data1, iid->Data2, iid->Data3,
iid->Data4[0], iid->Data4[1], iid->Data4[2], iid->Data4[3],
iid->Data4[4], iid->Data4[5], iid->Data4[6], iid->Data4[7]
);
err = RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ,&ikey);
if (err && (opposite == KEY_WOW64_32KEY || (IsWow64Process(GetCurrentProcess(), &is_wow64)
&& is_wow64)))
err = RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ|opposite,&ikey);
if (err)
{
ERR("No %s key found.\n", interfacekey);
return E_FAIL;
}
tlguidlen = sizeof(tlguid);
if (RegQueryValueExA(ikey, NULL, NULL, &type, (BYTE *)tlguid, &tlguidlen))
{
ERR("Getting typelib guid failed.\n");
RegCloseKey(ikey);
return E_FAIL;
}
verlen = sizeof(ver);
if (RegQueryValueExA(ikey, "Version", NULL, &type, (BYTE *)ver, &verlen))
{
ERR("Could not get version value?\n");
RegCloseKey(ikey);
return E_FAIL;
}
RegCloseKey(ikey);
sprintf(typelibkey, "Typelib\\%s\\%s\\0\\win%u", tlguid, ver, sizeof(void *) == 8 ? 64 : 32);
tlfnlen = sizeof(tlfn);
if (RegQueryValueA(HKEY_CLASSES_ROOT, typelibkey, tlfn, &tlfnlen))
{
#ifdef _WIN64
sprintf(typelibkey, "Typelib\\%s\\%s\\0\\win32", tlguid, ver);
tlfnlen = sizeof(tlfn);
if (RegQueryValueA(HKEY_CLASSES_ROOT, typelibkey, tlfn, &tlfnlen))
{
#endif
ERR("Could not get typelib fn?\n");
return E_FAIL;
#ifdef _WIN64
}
#endif
}
MultiByteToWideChar(CP_ACP, 0, tlfn, -1, module, len);
return S_OK;
}
static HRESULT get_typeinfo_for_iid(REFIID iid, ITypeInfo **typeinfo)
{
WCHAR module[MAX_PATH];
ITypeLib *typelib;
HRESULT hr;
*typeinfo = NULL;
module[0] = 0;
if (!actctx_get_typelib_module(iid, module, ARRAY_SIZE(module)))
{
hr = reg_get_typelib_module(iid, module, ARRAY_SIZE(module));
if (FAILED(hr))
return hr;
}
hr = LoadTypeLib(module, &typelib);
if (hr != S_OK) {
ERR("Failed to load typelib for %s, but it should be there.\n", debugstr_guid(iid));
return hr;
}
hr = ITypeLib_GetTypeInfoOfGuid(typelib, iid, typeinfo);
ITypeLib_Release(typelib);
if (hr != S_OK)
ERR("typelib does not contain info for %s\n", debugstr_guid(iid));
return hr;
}
static HRESULT WINAPI typelib_ps_QueryInterface(IPSFactoryBuffer *iface, REFIID iid, void **out)
{
if (IsEqualIID(iid, &IID_IPSFactoryBuffer) || IsEqualIID(iid, &IID_IUnknown))
{
*out = iface;
return S_OK;
}
FIXME("No interface for %s.\n", debugstr_guid(iid));
*out = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI typelib_ps_AddRef(IPSFactoryBuffer *iface)
{
return 2;
}
static ULONG WINAPI typelib_ps_Release(IPSFactoryBuffer *iface)
{
return 1;
}
static HRESULT WINAPI typelib_ps_CreateProxy(IPSFactoryBuffer *iface,
IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **out)
{
ITypeInfo *typeinfo;
HRESULT hr;
hr = get_typeinfo_for_iid(iid, &typeinfo);
if (FAILED(hr)) return hr;
hr = CreateProxyFromTypeInfo(typeinfo, outer, iid, proxy, out);
if (FAILED(hr))
ERR("Failed to create proxy, hr %#x.\n", hr);
ITypeInfo_Release(typeinfo);
return hr;
}
static HRESULT WINAPI typelib_ps_CreateStub(IPSFactoryBuffer *iface, REFIID iid,
IUnknown *server, IRpcStubBuffer **stub)
{
ITypeInfo *typeinfo;
HRESULT hr;
hr = get_typeinfo_for_iid(iid, &typeinfo);
if (FAILED(hr)) return hr;
hr = CreateStubFromTypeInfo(typeinfo, iid, server, stub);
if (FAILED(hr))
ERR("Failed to create stub, hr %#x.\n", hr);
ITypeInfo_Release(typeinfo);
return hr;
}
static const IPSFactoryBufferVtbl typelib_ps_vtbl =
{
typelib_ps_QueryInterface,
typelib_ps_AddRef,
typelib_ps_Release,
typelib_ps_CreateProxy,
typelib_ps_CreateStub,
};
static IPSFactoryBuffer typelib_ps = { &typelib_ps_vtbl };
extern void _get_STDFONT_CF(LPVOID *);
extern void _get_STDPIC_CF(LPVOID *);
@ -791,40 +1016,42 @@ static ULONG WINAPI PSDispatchFacBuf_Release(IPSFactoryBuffer *iface)
return 1;
}
static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface, IUnknown *pUnkOuter, REFIID riid, IRpcProxyBuffer **ppProxy, void **ppv)
static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface,
IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **obj)
{
IPSFactoryBuffer *pPSFB;
IPSFactoryBuffer *factory;
HRESULT hr;
if (IsEqualIID(riid, &IID_IDispatch))
hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB);
if (IsEqualIID(iid, &IID_IDispatch))
{
hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
if (FAILED(hr)) return hr;
hr = IPSFactoryBuffer_CreateProxy(factory, outer, iid, proxy, obj);
IPSFactoryBuffer_Release(factory);
return hr;
}
else
hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB);
if (FAILED(hr)) return hr;
hr = IPSFactoryBuffer_CreateProxy(pPSFB, pUnkOuter, riid, ppProxy, ppv);
IPSFactoryBuffer_Release(pPSFB);
return hr;
return IPSFactoryBuffer_CreateProxy(&typelib_ps, outer, iid, proxy, obj);
}
static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface, REFIID riid, IUnknown *pUnkOuter, IRpcStubBuffer **ppStub)
static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface,
REFIID iid, IUnknown *server, IRpcStubBuffer **stub)
{
IPSFactoryBuffer *pPSFB;
IPSFactoryBuffer *factory;
HRESULT hr;
if (IsEqualIID(riid, &IID_IDispatch))
hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB);
if (IsEqualIID(iid, &IID_IDispatch))
{
hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory);
if (FAILED(hr)) return hr;
hr = IPSFactoryBuffer_CreateStub(factory, iid, server, stub);
IPSFactoryBuffer_Release(factory);
return hr;
}
else
hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB);
if (FAILED(hr)) return hr;
hr = IPSFactoryBuffer_CreateStub(pPSFB, riid, pUnkOuter, ppStub);
IPSFactoryBuffer_Release(pPSFB);
return hr;
return IPSFactoryBuffer_CreateStub(&typelib_ps, iid, server, stub);
}
static const IPSFactoryBufferVtbl PSDispatchFacBuf_Vtbl =
@ -864,11 +1091,10 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
IPSFactoryBuffer_AddRef((IPSFactoryBuffer *)*ppv);
return S_OK;
}
if (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) {
if (S_OK==TMARSHAL_DllGetClassObject(rclsid,iid,ppv))
return S_OK;
/*FALLTHROUGH*/
}
if (IsEqualGUID(rclsid, &CLSID_PSOAInterface))
return IPSFactoryBuffer_QueryInterface(&typelib_ps, iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_PSTypeComp) ||
IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
IsEqualCLSID(rclsid, &CLSID_PSTypeLib) ||

View File

@ -1010,7 +1010,6 @@ static HRESULT WINAPI Widget_int_ptr(IWidget *iface, int *in, int *out, int *in_
static HRESULT WINAPI Widget_int_ptr_ptr(IWidget *iface, int **in, int **out, int **in_out)
{
todo_wine_if(testmode == 2)
ok(!*out, "Got [out] %p.\n", *out);
if (testmode == 0)
{
@ -1078,7 +1077,6 @@ static HRESULT WINAPI Widget_iface_in(IWidget *iface, IUnknown *unk, IDispatch *
static HRESULT WINAPI Widget_iface_out(IWidget *iface, IUnknown **unk, IDispatch **disp, ISomethingFromDispatch **sfd)
{
todo_wine
ok(!*unk, "Got iface %p.\n", *unk);
ok(!*disp, "Got iface %p.\n", *disp);
ok(!*sfd, "Got iface %p.\n", *sfd);
@ -1138,7 +1136,6 @@ static HRESULT WINAPI Widget_bstr(IWidget *iface, BSTR in, BSTR *out, BSTR *in_p
len = SysStringByteLen(in);
ok(len == sizeof(test_bstr1), "Got wrong length %u.\n", len);
ok(!memcmp(in, test_bstr1, len), "Got string %s.\n", wine_dbgstr_wn(in, len / sizeof(WCHAR)));
todo_wine_if(*out)
ok(!*out, "Got unexpected output %p.\n", *out);
len = SysStringLen(*in_ptr);
ok(len == lstrlenW(test_bstr2), "Got wrong length %u.\n", len);
@ -1284,7 +1281,6 @@ static HRESULT WINAPI Widget_array(IWidget *iface, array_t in, array_t out, arra
{
static const array_t empty = {0};
ok(!memcmp(in, test_array1, sizeof(array_t)), "Arrays didn't match.\n");
todo_wine
ok(!memcmp(out, empty, sizeof(array_t)), "Arrays didn't match.\n");
ok(!memcmp(in_out, test_array3, sizeof(array_t)), "Arrays didn't match.\n");
@ -1832,7 +1828,6 @@ static void test_marshal_pointer(IWidget *widget, IDispatch *disp)
ok(out == 654, "Got [out] %d.\n", out);
ok(in_out == 321, "Got [in, out] %d.\n", in_out);
if (0) {
out = in_out = -1;
hr = IWidget_int_ptr(widget, NULL, &out, &in_out);
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
@ -1850,7 +1845,6 @@ if (0) {
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "Got hr %#x.\n", hr);
ok(in == -1, "[in] parameter should not have been cleared.\n");
ok(!out, "[out] parameter should have been cleared.\n");
}
/* We can't test Invoke() with double pointers, as it is not possible to fit
* more than one level of indirection into a VARIANTARG. */
@ -1863,7 +1857,6 @@ if (0) {
ok(!out_ptr, "Got [out] %p.\n", out_ptr);
ok(!in_out_ptr, "Got [in, out] %p.\n", in_out_ptr);
if (0) {
testmode = 1;
hr = IWidget_int_ptr_ptr(widget, &in_ptr, &out_ptr, &in_out_ptr);
ok(hr == S_OK, "Got hr %#x\n", hr);
@ -1885,7 +1878,6 @@ if (0) {
ok(in_out_ptr == &in_out, "[in, out] ptr should not have changed.\n");
ok(*out_ptr == 654, "Got [out] %d.\n", *out_ptr);
ok(*in_out_ptr == 321, "Got [in, out] %d.\n", *in_out_ptr);
}
testmode = 3;
in_ptr = out_ptr = NULL;
@ -1895,7 +1887,6 @@ if (0) {
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(!in_out_ptr, "Got [in, out] %p.\n", in_out_ptr);
if (0) {
out_ptr = &out;
in_out_ptr = &in_out;
hr = IWidget_int_ptr_ptr(widget, NULL, &out_ptr, &in_out_ptr);
@ -1917,7 +1908,6 @@ if (0) {
ok(in_ptr == &in, "[in] parameter should not have been cleared.\n");
ok(!out_ptr, "[out] parameter should have been cleared.\n");
}
}
static void test_marshal_iface(IWidget *widget, IDispatch *disp)
{
@ -1954,14 +1944,12 @@ static void test_marshal_iface(IWidget *widget, IDispatch *disp)
release_iface(proxy_disp);
release_iface(proxy_sfd);
if (0) {
testmode = 1;
hr = IWidget_iface_out(widget, &proxy_unk, &proxy_disp, &proxy_sfd);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(!proxy_unk, "Got unexpected proxy %p.\n", proxy_unk);
ok(!proxy_disp, "Got unexpected proxy %p.\n", proxy_disp);
ok(!proxy_sfd, "Got unexpected proxy %p.\n", proxy_sfd);
}
testmode = 0;
sfd_in = sfd1 = create_disp_obj();
@ -1974,7 +1962,6 @@ if (0) {
ok(sfd_in_out == sfd3, "[in, out] parameter should not have changed.\n");
release_iface(sfd1);
release_iface(sfd2);
todo_wine
release_iface(sfd3);
testmode = 1;
@ -1991,7 +1978,6 @@ todo_wine
release_iface(sfd_out);
release_iface(sfd_in_out);
release_iface(sfd1);
todo_wine
release_iface(sfd3);
testmode = 2;
@ -2010,7 +1996,6 @@ todo_wine
hr = IWidget_iface_ptr(widget, &sfd_in, &sfd_out, &sfd_in_out);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(!sfd_in_out, "Got [in, out] %p.\n", sfd_in_out);
todo_wine
release_iface(sfd3);
/* Test with Invoke(). Note that since we pass VT_UNKNOWN, we don't get our
@ -2331,17 +2316,14 @@ static void test_marshal_array(IWidget *widget, IDispatch *disp)
MYSTRUCT struct_in[2];
HRESULT hr;
if (0) {
memcpy(in, test_array1, sizeof(array_t));
memcpy(out, test_array2, sizeof(array_t));
memcpy(in_out, test_array3, sizeof(array_t));
hr = IWidget_array(widget, in, out, in_out);
ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine
ok(!memcmp(&in, &test_array1, sizeof(array_t)), "Arrays didn't match.\n");
ok(!memcmp(&out, &test_array5, sizeof(array_t)), "Arrays didn't match.\n");
ok(!memcmp(&in_out, &test_array6, sizeof(array_t)), "Arrays didn't match.\n");
}
V_VT(&var_in[0]) = VT_I4; V_I4(&var_in[0]) = 1;
V_VT(&var_in[1]) = VT_I4; V_I4(&var_in[1]) = 2;
@ -2355,7 +2337,6 @@ todo_wine
ok(V_I4(&var_in[0]) == 1, "Got wrong value %d.\n", V_I4(&var_in[0]));
ok(V_VT(&var_in[1]) == VT_I4, "Got wrong type %u.\n", V_VT(&var_in[1]));
ok(V_I4(&var_in[1]) == 2, "Got wrong value %d.\n", V_I4(&var_in[1]));
todo_wine {
ok(V_VT(&var_out[0]) == VT_I1, "Got wrong type %u.\n", V_VT(&var_out[0]));
ok(V_I1(&var_out[0]) == 9, "Got wrong value %u.\n", V_VT(&var_out[0]));
ok(V_VT(&var_out[1]) == VT_I1, "Got wrong type %u.\n", V_VT(&var_out[1]));
@ -2364,7 +2345,6 @@ todo_wine {
ok(V_I1(&var_in_out[0]) == 11, "Got wrong value %u.\n", V_VT(&var_in_out[0]));
ok(V_VT(&var_in_out[1]) == VT_I1, "Got wrong type %u.\n", V_VT(&var_in_out[1]));
ok(V_I1(&var_in_out[1]) == 12, "Got wrong value %u.\n", V_VT(&var_in_out[1]));
}
memcpy(&struct_in[0], &test_mystruct1, sizeof(MYSTRUCT));
memcpy(&struct_in[1], &test_mystruct2, sizeof(MYSTRUCT));
@ -2404,9 +2384,6 @@ static void test_typelibmarshal(void)
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IKindaEnumWidget, (void **)&pKEW);
#ifndef __i386__
todo_wine
#endif
ok_ole_success(hr, CoUnmarshalInterface);
IStream_Release(pStream);
if (FAILED(hr))
@ -3080,9 +3057,6 @@ static void test_external_connection(void)
IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
hres = CoUnmarshalInterface(stream, &IID_ItestDual, (void**)&iface);
#ifndef __i386__
todo_wine
#endif
ok(hres == S_OK, "CoUnmarshalInterface failed: %08x\n", hres);
if (FAILED(hres))
{

File diff suppressed because it is too large Load Diff

View File

@ -6345,38 +6345,6 @@ __ASM_GLOBAL_FUNC( call_method,
__ASM_GLOBAL_FUNC( call_double_method,
"jmp " __ASM_NAME("call_method") )
/* ITypeInfo::Invoke
*
* Invokes a method, or accesses a property of an object, that implements the
* interface described by the type description.
*/
DWORD
_invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) {
DWORD res;
int stack_offset;
if (TRACE_ON(ole)) {
int i;
TRACE("Calling %p(",func);
for (i=0;i<min(nrargs,30);i++) TRACE("%08x,",args[i]);
if (nrargs > 30) TRACE("...");
TRACE(")\n");
}
switch (callconv) {
case CC_STDCALL:
case CC_CDECL:
res = call_method( func, nrargs, args, &stack_offset );
break;
default:
FIXME("unsupported calling convention %d\n",callconv);
res = -1;
break;
}
TRACE("returns %08x\n",res);
return res;
}
#elif defined(__x86_64__)
extern DWORD_PTR CDECL call_method( void *func, int nb_args, const DWORD_PTR *args );

View File

@ -595,12 +595,6 @@ WORD typeofarray
#include "poppack.h"
HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc ) DECLSPEC_HIDDEN;
extern DWORD _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) DECLSPEC_HIDDEN;
HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN;
/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
DEFINE_OLEGUID( CLSID_PSDispatch, 0x00020420, 0x0000, 0x0000 );
DEFINE_OLEGUID( CLSID_PSEnumVariant, 0x00020421, 0x0000, 0x0000 );