From adeba6ee8058f4b21256c175ceff76c30af95257 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Thu, 1 Apr 2010 13:02:17 +0100 Subject: [PATCH] oleaut32: Only oleautomation interfaces as well as all dispinterfaces should be registered. --- .gitignore | 3 + dlls/oleaut32/tests/Makefile.in | 5 +- dlls/oleaut32/tests/test_reg.idl | 130 +++++++++++++++++++++++++++++++ dlls/oleaut32/tests/tmarshal.rc | 3 + dlls/oleaut32/tests/typelib.c | 115 ++++++++++++++++++++++++++- dlls/oleaut32/typelib.c | 5 +- 6 files changed, 256 insertions(+), 5 deletions(-) create mode 100644 dlls/oleaut32/tests/test_reg.idl diff --git a/.gitignore b/.gitignore index 3cf9b2c28dc..7dcf06c65f1 100644 --- a/.gitignore +++ b/.gitignore @@ -99,6 +99,9 @@ dlls/oleaut32/oleaut32_oaidl.h dlls/oleaut32/oleaut32_oaidl_p.c dlls/oleaut32/oleaut32_ocidl.h dlls/oleaut32/oleaut32_ocidl_p.c +dlls/oleaut32/tests/test_reg.h +dlls/oleaut32/tests/test_reg.tlb +dlls/oleaut32/tests/test_reg_i.c dlls/oleaut32/tests/test_tlb.tlb dlls/oleaut32/tests/tmarshal.h dlls/oleaut32/tests/tmarshal.tlb diff --git a/dlls/oleaut32/tests/Makefile.in b/dlls/oleaut32/tests/Makefile.in index 737e1c147a2..aba934ca418 100644 --- a/dlls/oleaut32/tests/Makefile.in +++ b/dlls/oleaut32/tests/Makefile.in @@ -19,9 +19,12 @@ C_SRCS = \ RC_SRCS = tmarshal.rc -IDL_I_SRCS = tmarshal.idl +IDL_I_SRCS = \ + test_reg.idl \ + tmarshal.idl IDL_TLB_SRCS = \ + test_reg.idl \ test_tlb.idl \ tmarshal.idl diff --git a/dlls/oleaut32/tests/test_reg.idl b/dlls/oleaut32/tests/test_reg.idl new file mode 100644 index 00000000000..4598efd5ce7 --- /dev/null +++ b/dlls/oleaut32/tests/test_reg.idl @@ -0,0 +1,130 @@ +/* + * A typelib to test registration. + * + * Copyright 2010 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 + */ + +import "oaidl.idl"; /* needed by widl */ + +[ + uuid(a2cfdbd3-2bbf-4b1c-a414-5a5904e634c9), + version(1.0) +] +library register_test +{ + importlib("stdole2.tlb"); + + [ + uuid(06c1f5f0-ea49-44f9-8e3b-4be00c7a0689) + ] + interface Inon_ole : IUnknown + { + HRESULT test(); + } + + [ + uuid(06c1f5f1-ea49-44f9-8e3b-4be00c7a0689) + ] + interface Inon_ole_from_disp : IDispatch + { + HRESULT test(); + } + + [ + uuid(06c1f5f2-ea49-44f9-8e3b-4be00c7a0689), + oleautomation + ] + interface Iole : IUnknown + { + HRESULT test(); + } + + [ + uuid(06c1f5f3-ea49-44f9-8e3b-4be00c7a0689), + oleautomation + ] + interface Iole_from_disp : IDispatch + { + HRESULT test(); + } + + [ + uuid(06c1f5f4-ea49-44f9-8e3b-4be00c7a0689), + dual + ] + interface Inon_ole_dual : IUnknown + { + HRESULT test(); + } + + [ + uuid(06c1f5f5-ea49-44f9-8e3b-4be00c7a0689), + oleautomation, + dual + ] + interface Iole_dual : IUnknown + { + HRESULT test(); + } + + [ + uuid(06c1f5f6-ea49-44f9-8e3b-4be00c7a0689), + dual + ] + interface Inon_ole_dual_from_disp : IDispatch + { + HRESULT test(); + } + + [ + uuid(06c1f5f7-ea49-44f9-8e3b-4be00c7a0689), + oleautomation, + dual + ] + interface Iole_dual_from_disp : IDispatch + { + HRESULT test(); + } + + /* oleautomation not allowed with dispinterfaces */ + [ + uuid(06c1f5f8-ea49-44f9-8e3b-4be00c7a0689) + ] + dispinterface Idisp + { + properties: + [id(0x0)] BSTR Name; + methods: + } + + [ + uuid(06c1f5f9-ea49-44f9-8e3b-4be00c7a0689) + ] + dispinterface Idisp_from_non_ole_iface + { + interface Inon_ole; + } + + [ + uuid(06c1f5fa-ea49-44f9-8e3b-4be00c7a0689) + ] + dispinterface Idisp_from_ole_from_disp_iface + { + interface Iole_from_disp; + } + +} diff --git a/dlls/oleaut32/tests/tmarshal.rc b/dlls/oleaut32/tests/tmarshal.rc index 707895f2bb5..ecc1f778d9a 100644 --- a/dlls/oleaut32/tests/tmarshal.rc +++ b/dlls/oleaut32/tests/tmarshal.rc @@ -32,3 +32,6 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* @makedep: test_tlb.tlb */ 2 TYPELIB LOADONCALL DISCARDABLE test_tlb.tlb + +/* @makedep: test_reg.tlb */ +3 TYPELIB LOADONCALL DISCARDABLE test_reg.tlb diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index a5d8e4a7310..6d476143ad6 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -32,6 +32,8 @@ #include "shlwapi.h" #include "tmarshal.h" +#include "test_reg.h" + #define expect_eq(expr, value, type, format) { type _ret = (expr); ok((value) == _ret, #expr " expected " format " got " format "\n", value, _ret); } #define expect_int(expr, value) expect_eq(expr, (int)(value), int, "%d") #define expect_hex(expr, value) expect_eq(expr, (int)(value), int, "0x%x") @@ -1883,7 +1885,7 @@ static void test_dump_typelib(const char *name) #endif -static const char *create_test_typelib(void) +static const char *create_test_typelib(int res_no) { static char filename[MAX_PATH]; HANDLE file; @@ -1895,7 +1897,7 @@ static const char *create_test_typelib(void) file = CreateFile( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); ok( file != INVALID_HANDLE_VALUE, "file creation failed\n" ); if (file == INVALID_HANDLE_VALUE) return NULL; - res = FindResource( GetModuleHandle(0), MAKEINTRESOURCE(2), "TYPELIB" ); + res = FindResource( GetModuleHandle(0), MAKEINTRESOURCE(res_no), "TYPELIB" ); ok( res != 0, "couldn't find resource\n" ); ptr = LockResource( LoadResource( GetModuleHandle(0), res )); WriteFile( file, ptr, SizeofResource( GetModuleHandle(0), res ), &written, NULL ); @@ -1956,6 +1958,112 @@ static void test_create_typelibs(void) test_create_typelib_lcid(0x407); } + +static void test_register_typelib(void) +{ + HRESULT hr; + WCHAR filename[MAX_PATH]; + const char *filenameA; + ITypeLib *typelib; + WCHAR key_name[MAX_PATH], uuid[40]; + static const WCHAR formatW[] = {'I','n','t','e','r','f','a','c','e','\\','%','s',0}; + LONG ret, expect_ret; + UINT count, i; + HKEY hkey; + struct + { + TYPEKIND kind; + WORD flags; + } attrs[11] = + { + { TKIND_INTERFACE, 0 }, + { TKIND_INTERFACE, TYPEFLAG_FDISPATCHABLE }, + { TKIND_INTERFACE, TYPEFLAG_FOLEAUTOMATION }, + { TKIND_INTERFACE, TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FOLEAUTOMATION }, + { TKIND_DISPATCH, 0 /* TYPEFLAG_FDUAL - widl clears this flag for non-IDispatch derived interfaces */ }, + { TKIND_DISPATCH, 0 /* TYPEFLAG_FDUAL - widl clears this flag for non-IDispatch derived interfaces */ }, + { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FDUAL }, + { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FDUAL }, + { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE }, + { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE }, + { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE } + }; + + filenameA = create_test_typelib(3); + MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH); + + hr = LoadTypeLibEx(filename, REGKIND_NONE, &typelib); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + hr = RegisterTypeLib(typelib, filename, NULL); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + count = ITypeLib_GetTypeInfoCount(typelib); + ok(count == 11, "got %d\n", count); + + for(i = 0; i < count; i++) + { + ITypeInfo *typeinfo; + TYPEATTR *attr; + + hr = ITypeLib_GetTypeInfo(typelib, i, &typeinfo); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + hr = ITypeInfo_GetTypeAttr(typeinfo, &attr); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + ok(attr->typekind == attrs[i].kind, "%d: got kind %d\n", i, attr->typekind); + ok(attr->wTypeFlags == attrs[i].flags, "%d: got flags %04x\n", i, attr->wTypeFlags); + + if(attr->typekind == TKIND_DISPATCH && (attr->wTypeFlags & TYPEFLAG_FDUAL)) + { + HREFTYPE reftype; + ITypeInfo *dual_info; + TYPEATTR *dual_attr; + + hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, -1, &reftype); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + hr = ITypeInfo_GetRefTypeInfo(typeinfo, reftype, &dual_info); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + hr = ITypeInfo_GetTypeAttr(dual_info, &dual_attr); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + ok(dual_attr->typekind == TKIND_INTERFACE, "%d: got kind %d\n", i, dual_attr->typekind); + ok(dual_attr->wTypeFlags == (TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FOLEAUTOMATION | TYPEFLAG_FDUAL), "%d: got flags %04x\n", i, dual_attr->wTypeFlags); + + ITypeInfo_ReleaseTypeAttr(dual_info, dual_attr); + ITypeInfo_Release(dual_info); + + } + + StringFromGUID2(&attr->guid, uuid, sizeof(uuid) / sizeof(uuid[0])); + wsprintfW(key_name, formatW, uuid); + + /* All dispinterfaces will be registered (this includes dual interfaces) as well + as oleautomation interfaces */ + if((attr->typekind == TKIND_INTERFACE && (attr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) || + attr->typekind == TKIND_DISPATCH) + expect_ret = ERROR_SUCCESS; + else + expect_ret = ERROR_FILE_NOT_FOUND; + + ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, key_name, 0, KEY_READ, &hkey); + ok(ret == expect_ret, "%d: got %d\n", i, ret); + if(ret == ERROR_SUCCESS) RegCloseKey(hkey); + + ITypeInfo_ReleaseTypeAttr(typeinfo, attr); + ITypeInfo_Release(typeinfo); + } + + hr = UnRegisterTypeLib(&LIBID_register_test, 1, 0, LOCALE_NEUTRAL, sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32); + ok(SUCCEEDED(hr), "got %08x\n", hr); + + ITypeLib_Release(typelib); + DeleteFileA( filenameA ); +} + START_TEST(typelib) { const char *filename; @@ -1968,12 +2076,13 @@ START_TEST(typelib) test_inheritance(); test_CreateTypeLib(); - if ((filename = create_test_typelib())) + if ((filename = create_test_typelib(2))) { test_dump_typelib( filename ); DeleteFile( filename ); } + test_register_typelib(); test_create_typelibs(); } diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index c1fa321b8a4..cbf68b5bc8e 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -691,7 +691,10 @@ HRESULT WINAPI RegisterTypeLib( MESSAGE("\n"); } - if (tattr->wTypeFlags & (TYPEFLAG_FOLEAUTOMATION|TYPEFLAG_FDUAL|TYPEFLAG_FDISPATCHABLE)) + /* Register all dispinterfaces (which includes dual interfaces) and + oleautomation interfaces */ + if ((kind == TKIND_INTERFACE && (tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) || + kind == TKIND_DISPATCH) { /* register interface<->typelib coupling */ get_interface_key( &tattr->guid, keyName );