From 9ad85e9d6fe75013cf7bfc4f5adbbc644fea8f41 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 31 Oct 2015 17:47:59 +0100 Subject: [PATCH] Added patch to fix multiple issues in widl typelib generation. --- README.md | 3 +- debian/changelog | 1 + patches/patchinstall.sh | 27 + ...-an-interface-typedef-do-check-wheth.patch | 37 ++ ...signment-of-a-duplicate-uuid.-Resend.patch | 58 +++ ...uid-takes-precedence-over-hidden-.-R.patch | 61 +++ ...of-the-alias-are-supposed-to-replace.patch | 68 +++ ...ating-duplicate-typelib-entries-for-.patch | 38 ++ ...dd-a-bunch-of-new-tests-for-typelib-.patch | 491 ++++++++++++++++++ patches/widl-Typelib_Generator/definition | 1 + 10 files changed, 784 insertions(+), 1 deletion(-) create mode 100644 patches/widl-Typelib_Generator/0001-widl-When-adding-an-interface-typedef-do-check-wheth.patch create mode 100644 patches/widl-Typelib_Generator/0002-widl-Ignore-assignment-of-a-duplicate-uuid.-Resend.patch create mode 100644 patches/widl-Typelib_Generator/0003-widl-Attribute-uuid-takes-precedence-over-hidden-.-R.patch create mode 100644 patches/widl-Typelib_Generator/0004-widl-Attributes-of-the-alias-are-supposed-to-replace.patch create mode 100644 patches/widl-Typelib_Generator/0005-widl-Avoid-generating-duplicate-typelib-entries-for-.patch create mode 100644 patches/widl-Typelib_Generator/0006-oleaut32-tests-Add-a-bunch-of-new-tests-for-typelib-.patch create mode 100644 patches/widl-Typelib_Generator/definition diff --git a/README.md b/README.md index 100945d4..ac5d6592 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,12 @@ Wine. All those differences are also documented on the Included bug fixes and improvements ----------------------------------- -**Bug fixes and features included in the next upcoming release [8]:** +**Bug fixes and features included in the next upcoming release [9]:** * Add stub for SetCoalescableTimer ([Wine Bug #39509](https://bugs.winehq.org/show_bug.cgi?id=39509)) * Add stub for SfcGetNextProtectedFile ([Wine Bug #38097](https://bugs.winehq.org/show_bug.cgi?id=38097)) * Do not allow interruption of system APC in server_select ([Wine Bug #14697](https://bugs.winehq.org/show_bug.cgi?id=14697)) +* Fix multiple issues in widl typelib generation * IEnumSTATSTG::Next should zero out returned stats when enumeration ends * Implement FileNamesInformation class support for NtQueryDirectoryFile * Implement hal.KeQueryPerformanceCounter ([Wine Bug #39500](https://bugs.winehq.org/show_bug.cgi?id=39500)) diff --git a/debian/changelog b/debian/changelog index d7f53d75..f7766924 100644 --- a/debian/changelog +++ b/debian/changelog @@ -20,6 +20,7 @@ wine-staging (1.7.54) UNRELEASED; urgency=low * Added patch for SfcGetNextProtectedFile stub function. * Added patch to zero out returned stats when IEnumSTATSTG::Next reaches end of enumeration. + * Added patch to fix multiple issues in widl typelib generation. * Removed patch to implement kernel32.GetPhysicallyInstalledSystemMemory (accepted upstream). * Partially removed patches for ws2_32 TransmitFile (accepted upstream). diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 82c25013..86734600 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -285,6 +285,7 @@ patch_enable_all () enable_uxtheme_GTK_Theming="$1" enable_version_VerQueryValue="$1" enable_wbemdisp_ISWbemSecurity="$1" + enable_widl_Typelib_Generator="$1" enable_wine_inf_Performance="$1" enable_wine_inf_ProfileList_UserSID="$1" enable_wineboot_DriveSerial="$1" @@ -954,6 +955,9 @@ patch_enable () wbemdisp-ISWbemSecurity) enable_wbemdisp_ISWbemSecurity="$2" ;; + widl-Typelib_Generator) + enable_widl_Typelib_Generator="$2" + ;; wine.inf-Performance) enable_wine_inf_Performance="$2" ;; @@ -5530,6 +5534,29 @@ if test "$enable_wbemdisp_ISWbemSecurity" -eq 1; then ) >> "$patchlist" fi +# Patchset widl-Typelib_Generator +# | +# | Modified files: +# | * dlls/oleaut32/tests/test_tlb.idl, dlls/oleaut32/tests/typelib.c, tools/widl/parser.y, tools/widl/typetree.c, +# | tools/widl/write_msft.c +# | +if test "$enable_widl_Typelib_Generator" -eq 1; then + patch_apply widl-Typelib_Generator/0001-widl-When-adding-an-interface-typedef-do-check-wheth.patch + patch_apply widl-Typelib_Generator/0002-widl-Ignore-assignment-of-a-duplicate-uuid.-Resend.patch + patch_apply widl-Typelib_Generator/0003-widl-Attribute-uuid-takes-precedence-over-hidden-.-R.patch + patch_apply widl-Typelib_Generator/0004-widl-Attributes-of-the-alias-are-supposed-to-replace.patch + patch_apply widl-Typelib_Generator/0005-widl-Avoid-generating-duplicate-typelib-entries-for-.patch + patch_apply widl-Typelib_Generator/0006-oleaut32-tests-Add-a-bunch-of-new-tests-for-typelib-.patch + ( + echo '+ { "Sebastian Lackner", "widl: When adding an interface typedef do check whether it has been already added while resolving the parent interface.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Ignore assignment of a duplicate uuid. Resend.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Attribute uuid() takes precedence over '\''hidden'\''. Resend.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Attributes of the alias are supposed to replace attributes of a tag in the typelib. Resend.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Avoid generating duplicate typelib entries for structure tag names. Resend.", 1 },'; + echo '+ { "Dmitry Timoshkov", "oleaut32/tests: Add a bunch of new tests for typelib generation.", 1 },'; + ) >> "$patchlist" +fi + # Patchset wine.inf-Performance # | # | This patchset fixes the following Wine bugs: diff --git a/patches/widl-Typelib_Generator/0001-widl-When-adding-an-interface-typedef-do-check-wheth.patch b/patches/widl-Typelib_Generator/0001-widl-When-adding-an-interface-typedef-do-check-wheth.patch new file mode 100644 index 00000000..622b016a --- /dev/null +++ b/patches/widl-Typelib_Generator/0001-widl-When-adding-an-interface-typedef-do-check-wheth.patch @@ -0,0 +1,37 @@ +From c87d5df626e5ea91bbdc167707715b43d4424d24 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 31 Oct 2015 14:31:26 +0800 +Subject: widl: When adding an interface typedef do check whether it has been + already added while resolving the parent interface. + +This patch fixes a long standing bug that when an inherited interface gets +referenced by a parent interface definition then multiple definitions of an +inherited interface get added to a typelib. + +This bug has been discovered by the patch that emits a warning for a duplicate +uuid. A test case for this problem is added in the last patch of the series. + +Signed-off-by: Sebastian Lackner +Signed-off-by: Dmitry Timoshkov +--- + tools/widl/write_msft.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c +index fc0eae7..98081f2 100644 +--- a/tools/widl/write_msft.c ++++ b/tools/widl/write_msft.c +@@ -2078,6 +2078,10 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface) + add_interface_typeinfo(typelib, inherit); + } + ++ /* check typelib_idx again, it could have been added while resolving the parent interface */ ++ if (-1 < interface->typelib_idx) ++ return; ++ + interface->typelib_idx = typelib->typelib_header.nrtypeinfos; + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs); + msft_typeinfo->typeinfo->size = pointer_size; +-- +2.6.1 + diff --git a/patches/widl-Typelib_Generator/0002-widl-Ignore-assignment-of-a-duplicate-uuid.-Resend.patch b/patches/widl-Typelib_Generator/0002-widl-Ignore-assignment-of-a-duplicate-uuid.-Resend.patch new file mode 100644 index 00000000..5fad4baa --- /dev/null +++ b/patches/widl-Typelib_Generator/0002-widl-Ignore-assignment-of-a-duplicate-uuid.-Resend.patch @@ -0,0 +1,58 @@ +From d2819273e30e3f5c89cd2f704ddb4593e3cbb540 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sat, 31 Oct 2015 14:31:38 +0800 +Subject: widl: Ignore assignment of a duplicate uuid. Resend. + +MSDN KB285146 article describes this behaviour, and the tests in the last +patch confirm that. + +Technically this means that in the construct like + +typedef [uuid(016fe2ec-b2c8-45f8-b23b-39e53a75396d)] +enum _d { d1, d2 } d; + +only 'd' gets assigned the specified uuid, '_d' will get uuid offset set +to -1 (undefined) which leads to '_d' having NULL_GUID. This matches widl +behaviour, in this case widl emits a warning (mentioned in the KB article). + +I decided to leave emitting a warning about a duplicate uuid for enums same +way as for structures and unions, this may help recognizing real bugs instead +of hiding them (although apparently midl doesn't generate a warning for enums +while still ignoring the uuid assignment). + +Signed-off-by: Dmitry Timoshkov +--- + tools/widl/write_msft.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c +index 98081f2..0992cf3 100644 +--- a/tools/widl/write_msft.c ++++ b/tools/widl/write_msft.c +@@ -494,10 +494,22 @@ static int ctl2_alloc_guid( + MSFT_GuidEntry *guid_space; + int hash_key; + ++ chat("adding uuid {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", ++ guid->guid.Data1, guid->guid.Data2, guid->guid.Data3, ++ guid->guid.Data4[0], guid->guid.Data4[1], guid->guid.Data4[2], guid->guid.Data4[3], ++ guid->guid.Data4[4], guid->guid.Data4[5], guid->guid.Data4[6], guid->guid.Data4[7]); ++ + hash_key = ctl2_hash_guid(&guid->guid); + + offset = ctl2_find_guid(typelib, hash_key, &guid->guid); +- if (offset != -1) return offset; ++ if (offset != -1) ++ { ++ warning("duplicate uuid {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", ++ guid->guid.Data1, guid->guid.Data2, guid->guid.Data3, ++ guid->guid.Data4[0], guid->guid.Data4[1], guid->guid.Data4[2], guid->guid.Data4[3], ++ guid->guid.Data4[4], guid->guid.Data4[5], guid->guid.Data4[6], guid->guid.Data4[7]); ++ return -1; ++ } + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0); + +-- +2.6.1 + diff --git a/patches/widl-Typelib_Generator/0003-widl-Attribute-uuid-takes-precedence-over-hidden-.-R.patch b/patches/widl-Typelib_Generator/0003-widl-Attribute-uuid-takes-precedence-over-hidden-.-R.patch new file mode 100644 index 00000000..9a7e85e6 --- /dev/null +++ b/patches/widl-Typelib_Generator/0003-widl-Attribute-uuid-takes-precedence-over-hidden-.-R.patch @@ -0,0 +1,61 @@ +From a9e4b8375ccef3198df93f9021a7262bb5578033 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sat, 31 Oct 2015 14:31:42 +0800 +Subject: widl: Attribute uuid() takes precedence over 'hidden'. Resend. + +This means that definition like + +[uuid(016fe2ec-b2c8-45f8-b23b-39e53a753900),hidden] +typedef struct _m { int m1; } m; + +makes both '_m' and 'm' appear in the typelib, and the tests confirm that. + +Signed-off-by: Dmitry Timoshkov +--- + tools/widl/parser.y | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/tools/widl/parser.y b/tools/widl/parser.y +index b42b4a2..db5897e 100644 +--- a/tools/widl/parser.y ++++ b/tools/widl/parser.y +@@ -123,7 +123,6 @@ static statement_t *make_statement_importlib(const char *str); + static statement_t *make_statement_module(type_t *type); + static statement_t *make_statement_typedef(var_list_t *names); + static statement_t *make_statement_import(const char *str); +-static statement_t *make_statement_typedef(var_list_t *names); + static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt); + static statement_list_t *append_statements(statement_list_t *, statement_list_t *); + static attr_list_t *append_attribs(attr_list_t *, attr_list_t *); +@@ -1881,22 +1880,20 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at + const declarator_t *decl; + type_t *type = decl_spec->type; + ++ if (is_attr(attrs, ATTR_UUID) && !is_attr(attrs, ATTR_PUBLIC)) ++ attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) ); ++ + /* We must generate names for tagless enum, struct or union. + Typedef-ing a tagless enum, struct or union means we want the typedef + to be included in a library hence the public attribute. */ + if ((type_get_type_detect_alias(type) == TYPE_ENUM || + type_get_type_detect_alias(type) == TYPE_STRUCT || + type_get_type_detect_alias(type) == TYPE_UNION || +- type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION) && +- !type->name) ++ type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)) + { +- if (! is_attr(attrs, ATTR_PUBLIC) && ! is_attr (attrs, ATTR_HIDDEN)) +- attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) ); +- type->name = gen_name(); ++ if (!type->name) ++ type->name = gen_name(); + } +- else if (is_attr(attrs, ATTR_UUID) && !is_attr(attrs, ATTR_PUBLIC) +- && !is_attr(attrs, ATTR_HIDDEN)) +- attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) ); + + LIST_FOR_EACH_ENTRY( decl, decls, const declarator_t, entry ) + { +-- +2.6.1 + diff --git a/patches/widl-Typelib_Generator/0004-widl-Attributes-of-the-alias-are-supposed-to-replace.patch b/patches/widl-Typelib_Generator/0004-widl-Attributes-of-the-alias-are-supposed-to-replace.patch new file mode 100644 index 00000000..42cb1db3 --- /dev/null +++ b/patches/widl-Typelib_Generator/0004-widl-Attributes-of-the-alias-are-supposed-to-replace.patch @@ -0,0 +1,68 @@ +From 6efefd95152a5dd8f05c95558c783e42562d4bf1 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sat, 31 Oct 2015 14:31:47 +0800 +Subject: widl: Attributes of the alias are supposed to replace attributes of a + tag in the typelib. Resend. + +I have limited this functionality only to typedefs for structures, unions +and enums since I have the tests only for this types. + +I've added the tests for version() and helpcontext() attributes suggested +by Huw to the last patch with tests to make this change more convincing. + +In practice this means that the difinitions in an .idl like + +[uuid(016fe2ec-b2c8-45f8-b23b-39e53a753901),restricted] +struct _n { int n1; }; +[uuid(016fe2ec-b2c8-45f8-b23b-39e53a753902),hidden] +typedef struct _n n; +[uuid(016fe2ec-b2c8-45f8-b23b-39e53a753903)] +typedef struct _n nn; + +lead to the following typelib records: + +{ + "_n", + "{016fe2ec-b2c8-45f8-b23b-39e53a753903}", + /*kind*/ TKIND_RECORD, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(struct _n), + /*#vtbl*/ 0, /*#func*/ 0 +}, +{ + "n", + "{016fe2ec-b2c8-45f8-b23b-39e53a753902}", + /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4, + /*#vtbl*/ 0, /*#func*/ 0 +}, +{ + "nn", + "{00000000-0000-0000-0000-000000000000}", + /*kind*/ TKIND_ALIAS, /*flags*/ 0, /*align*/ 4, /*size*/ 4, + /*#vtbl*/ 0, /*#func*/ 0 +} + +and the tests confirm that. But this change is very specific to typelibs +and breaks header generation, thus it's limited only to the typelib mode. + +Signed-off-by: Dmitry Timoshkov +--- + tools/widl/parser.y | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/widl/parser.y b/tools/widl/parser.y +index db5897e..4309833 100644 +--- a/tools/widl/parser.y ++++ b/tools/widl/parser.y +@@ -1893,6 +1893,10 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at + { + if (!type->name) + type->name = gen_name(); ++ ++ /* replace existing attributes when generating a typelib */ ++ if (do_typelib) ++ type->attrs = attrs; + } + + LIST_FOR_EACH_ENTRY( decl, decls, const declarator_t, entry ) +-- +2.6.1 + diff --git a/patches/widl-Typelib_Generator/0005-widl-Avoid-generating-duplicate-typelib-entries-for-.patch b/patches/widl-Typelib_Generator/0005-widl-Avoid-generating-duplicate-typelib-entries-for-.patch new file mode 100644 index 00000000..30f3c402 --- /dev/null +++ b/patches/widl-Typelib_Generator/0005-widl-Avoid-generating-duplicate-typelib-entries-for-.patch @@ -0,0 +1,38 @@ +From a0a2310c05b8205b67a9e4aeaa6bb98d68746b52 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sat, 31 Oct 2015 14:31:51 +0800 +Subject: widl: Avoid generating duplicate typelib entries for structure tag + names. Resend. + +I've added the tests to show how it's supposed to behave. Without this +patch a generated typelib has numerous duplicate '_n' entries. + +This is merely an optimization for the typelib generator, but this change +breaks header generation, thus it's limited only to the typelib mode. + +Signed-off-by: Dmitry Timoshkov +--- + tools/widl/typetree.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c +index 5925d40..e316614 100644 +--- a/tools/widl/typetree.c ++++ b/tools/widl/typetree.c +@@ -300,7 +300,12 @@ type_t *type_new_enum(const char *name, struct namespace *namespace, int defined + type_t *type_new_struct(char *name, struct namespace *namespace, int defined, var_list_t *fields) + { + type_t *tag_type = name ? find_type(name, namespace, tsSTRUCT) : NULL; +- type_t *t = make_type(TYPE_STRUCT); ++ type_t *t; ++ ++ /* avoid creating duplicate typelib type entries */ ++ if (tag_type && do_typelib) return tag_type; ++ ++ t = make_type(TYPE_STRUCT); + t->name = name; + t->namespace = namespace; + +-- +2.6.1 + diff --git a/patches/widl-Typelib_Generator/0006-oleaut32-tests-Add-a-bunch-of-new-tests-for-typelib-.patch b/patches/widl-Typelib_Generator/0006-oleaut32-tests-Add-a-bunch-of-new-tests-for-typelib-.patch new file mode 100644 index 00000000..d136929e --- /dev/null +++ b/patches/widl-Typelib_Generator/0006-oleaut32-tests-Add-a-bunch-of-new-tests-for-typelib-.patch @@ -0,0 +1,491 @@ +From e8c77ae1630f628cf2d43049399ca99b24514548 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sat, 31 Oct 2015 14:31:55 +0800 +Subject: oleaut32/tests: Add a bunch of new tests for typelib generation. + +Signed-off-by: Dmitry Timoshkov +--- + dlls/oleaut32/tests/test_tlb.idl | 50 +++++++++ + dlls/oleaut32/tests/typelib.c | 237 +++++++++++++++++++++++++++++++++++---- + 2 files changed, 265 insertions(+), 22 deletions(-) + +diff --git a/dlls/oleaut32/tests/test_tlb.idl b/dlls/oleaut32/tests/test_tlb.idl +index 8275c37..7ae5565 100644 +--- a/dlls/oleaut32/tests/test_tlb.idl ++++ b/dlls/oleaut32/tests/test_tlb.idl +@@ -2,6 +2,7 @@ + * ITypeLib test IDL - we dump it and compare results in typelib.c + * + * Copyright 2007 Google (Mikolaj Zalewski) ++ * Copyright 2015 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -28,6 +29,34 @@ library Test + { + importlib("stdole2.tlb"); + ++ interface child_iface; ++ interface parent_iface; ++ ++ [uuid(b14b6bb5-904e-4ff9-b247-bd361f7aa001)] ++ interface parent_iface : IUnknown ++ { ++ HRESULT test1([out,retval] child_iface **); ++ } ++ [uuid(b14b6bb5-904e-4ff9-b247-bd361f7aa002)] ++ interface child_iface: parent_iface ++ { ++ HRESULT test2(void); ++ } ++ ++ [uuid(016fe2ec-b2c8-45f8-b23b-39e53a753901),restricted] ++ struct _n { int n1; }; ++ [uuid(016fe2ec-b2c8-45f8-b23b-39e53a753902),hidden] ++ typedef struct _n n; ++ [uuid(016fe2ec-b2c8-45f8-b23b-39e53a753903),version(1.2),helpcontext(3)] ++ typedef struct _n nn; ++ ++ [uuid(016fe2ec-b2c8-45f8-b23b-39e53a753904),restricted] ++ struct _m { int m1; }; ++ [uuid(016fe2ec-b2c8-45f8-b23b-39e53a753905),hidden,version(1.2)] ++ typedef struct _m m; ++ [uuid(016fe2ec-b2c8-45f8-b23b-39e53a753906),helpcontext(3)] ++ typedef struct _m mm; ++ + [dual,uuid(b14b6bb5-904e-4ff9-b247-bd361f7aaedd)] + interface IDualIface : IDispatch + { +@@ -59,6 +88,9 @@ library Test + BSTR bstr; + }; + ++ typedef [uuid(016fe2ec-b2c8-45f8-b23b-39e53a75396a),restricted] ++ int t_INT; ++ + typedef [public] enum _a { a1, a2 } a; + typedef [public] enum aa { aa1, aa2 } aa; + typedef enum _b { b1, b2 } b; +@@ -66,11 +98,29 @@ library Test + typedef [uuid(016fe2ec-b2c8-45f8-b23b-39e53a75396b)] enum _c { c1, c2 } c; + typedef [uuid(016fe2ec-b2c8-45f8-b23b-39e53a75396c)] enum cc { cc1, cc2 } cc; + ++ typedef [uuid(016fe2ec-b2c8-45f8-b23b-39e53a75396d),restricted,hidden] ++ enum _d { d1, d2 } d; ++ typedef [uuid(016fe2ec-b2c8-45f8-b23b-39e53a75396e),restricted,hidden] ++ enum dd { dd1, dd2 } dd; ++ ++ typedef [uuid(016fe2ec-b2c8-45f8-b23b-39e53a753970),restricted,hidden] ++ struct _e { int e1; } e; ++ typedef [uuid(016fe2ec-b2c8-45f8-b23b-39e53a753971),restricted,hidden] ++ struct ee { int ee1; } ee; ++ ++ typedef [uuid(016fe2ec-b2c8-45f8-b23b-39e53a753972),restricted,hidden] ++ union _f { int f1; BSTR *f2; } f; ++ typedef [uuid(016fe2ec-b2c8-45f8-b23b-39e53a753973),restricted,hidden] ++ union ff { int ff1; BSTR *ff2; } ff; ++ + [uuid(ec5dfcd6-eeb0-4cd6-b51e-8030e1dac00a)] + interface ITestIface : IDispatch + { + HRESULT test1(a value); + HRESULT test2(b value); + HRESULT test3(c value); ++ HRESULT test4(d value); ++ HRESULT test5(e value); ++ HRESULT test6(f value); + } + } +diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c +index 1d13b89..977d7a8 100644 +--- a/dlls/oleaut32/tests/typelib.c ++++ b/dlls/oleaut32/tests/typelib.c +@@ -2,7 +2,7 @@ + * ITypeLib and ITypeInfo test + * + * Copyright 2004 Jacek Caban +- * Copyright 2006 Dmitry Timoshkov ++ * Copyright 2006,2015 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -3862,6 +3862,10 @@ static char *print_size(BSTR name, TYPEATTR *attr) + sprintf(buf, "sizeof(struct %s)", dump_string(name)); + break; + ++ case TKIND_UNION: ++ sprintf(buf, "sizeof(union %s)", dump_string(name)); ++ break; ++ + case TKIND_ENUM: + case TKIND_ALIAS: + sprintf(buf, "4"); +@@ -3971,9 +3975,10 @@ static void test_dump_typelib(const char *name) + { + TYPEATTR *attr; + BSTR name; ++ DWORD help_ctx; + int f = 0; + +- OLE_CHECK(ITypeLib_GetDocumentation(lib, i, &name, NULL, NULL, NULL)); ++ OLE_CHECK(ITypeLib_GetDocumentation(lib, i, &name, NULL, &help_ctx, NULL)); + printf("{\n" + " \"%s\",\n", dump_string(name)); + +@@ -3983,10 +3988,11 @@ static void test_dump_typelib(const char *name) + printf(" \"%s\",\n", wine_dbgstr_guid(&attr->guid)); + + printf(" /*kind*/ %s, /*flags*/ %s, /*align*/ %d, /*size*/ %s,\n" +- " /*#vtbl*/ %d, /*#func*/ %d", ++ " /*helpctx*/ 0x%04x, /*version*/ 0x%08x, /*#vtbl*/ %d, /*#func*/ %d", + map_value(attr->typekind, tkind_map), dump_type_flags(attr->wTypeFlags), +- attr->cbAlignment, print_size(name, attr), attr->cbSizeVft/sizeof(void*), +- attr->cFuncs); ++ attr->cbAlignment, print_size(name, attr), ++ help_ctx, MAKELONG(attr->wMinorVerNum, attr->wMajorVerNum), ++ attr->cbSizeVft/sizeof(void*), attr->cFuncs); + + if (attr->cFuncs) printf(",\n {\n"); + else printf("\n"); +@@ -4072,6 +4078,8 @@ typedef struct _type_info + WORD wTypeFlags; + USHORT cbAlignment; + USHORT cbSizeInstance; ++ USHORT help_ctx; ++ DWORD version; + USHORT cbSizeVft; + USHORT cFuncs; + function_info funcs[20]; +@@ -4080,10 +4088,88 @@ typedef struct _type_info + static const type_info info[] = { + /*** Autogenerated data. Do not edit, change the generator above instead. ***/ + { ++ "parent_iface", ++ "{b14b6bb5-904e-4ff9-b247-bd361f7aa001}", ++ /*kind*/ TKIND_INTERFACE, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(parent_iface*), ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 4, /*#func*/ 1, ++ { ++ { ++ /*id*/ 0x60010000, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, ++ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 3, /*#scodes*/ 0, /*flags*/ 0, ++ {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ ++ { /* params */ ++ {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL}, ++ {-1, 0, 0} ++ }, ++ { /* names */ ++ "test1", ++ "__MIDL__parent_iface0000", ++ NULL, ++ }, ++ }, ++ } ++}, ++{ ++ "child_iface", ++ "{b14b6bb5-904e-4ff9-b247-bd361f7aa002}", ++ /*kind*/ TKIND_INTERFACE, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(child_iface*), ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 5, /*#func*/ 1, ++ { ++ { ++ /*id*/ 0x60020000, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, ++ /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 4, /*#scodes*/ 0, /*flags*/ 0, ++ {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ ++ { /* params */ ++ {-1, 0, 0} ++ }, ++ { /* names */ ++ "test2", ++ NULL, ++ }, ++ }, ++ } ++}, ++{ ++ "_n", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a753903}", ++ /*kind*/ TKIND_RECORD, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(struct _n), ++ /*helpctx*/ 0x0003, /*version*/ 0x00010002, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "n", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a753902}", ++ /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4, ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "nn", ++ "{00000000-0000-0000-0000-000000000000}", ++ /*kind*/ TKIND_ALIAS, /*flags*/ 0, /*align*/ 4, /*size*/ 4, ++ /*helpctx*/ 0x0003, /*version*/ 0x00010002, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "_m", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a753906}", ++ /*kind*/ TKIND_RECORD, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(struct _m), ++ /*helpctx*/ 0x0003, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "m", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a753905}", ++ /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4, ++ /*helpctx*/ 0x0000, /*version*/ 0x00010002, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "mm", ++ "{00000000-0000-0000-0000-000000000000}", ++ /*kind*/ TKIND_ALIAS, /*flags*/ 0, /*align*/ 4, /*size*/ 4, ++ /*helpctx*/ 0x0003, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ + "IDualIface", + "{b14b6bb5-904e-4ff9-b247-bd361f7aaedd}", + /*kind*/ TKIND_DISPATCH, /*flags*/ TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL, /*align*/ 4, /*size*/ sizeof(IDualIface*), +- /*#vtbl*/ 7, /*#func*/ 8, ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 7, /*#func*/ 8, + { + { + /*id*/ 0x60000000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, +@@ -4225,7 +4311,7 @@ static const type_info info[] = { + "ISimpleIface", + "{ec5dfcd6-eeb0-4cd6-b51e-8030e1dac009}", + /*kind*/ TKIND_INTERFACE, /*flags*/ TYPEFLAG_FDISPATCHABLE, /*align*/ 4, /*size*/ sizeof(ISimpleIface*), +- /*#vtbl*/ 8, /*#func*/ 1, ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 8, /*#func*/ 1, + { + { + /*id*/ 0x60020000, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, +@@ -4245,67 +4331,127 @@ static const type_info info[] = { + "test_struct", + "{4029f190-ca4a-4611-aeb9-673983cb96dd}", + /*kind*/ TKIND_RECORD, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(struct test_struct), +- /*#vtbl*/ 0, /*#func*/ 0 ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 + }, + { + "test_struct2", + "{4029f190-ca4a-4611-aeb9-673983cb96de}", + /*kind*/ TKIND_RECORD, /*flags*/ 0, /*align*/ 4, /*size*/ sizeof(struct test_struct2), +- /*#vtbl*/ 0, /*#func*/ 0 ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "t_INT", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a75396a}", ++ /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FRESTRICTED, /*align*/ 4, /*size*/ 4, ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 + }, + { + "a", + "{00000000-0000-0000-0000-000000000000}", + /*kind*/ TKIND_ALIAS, /*flags*/ 0, /*align*/ 4, /*size*/ 4, +- /*#vtbl*/ 0, /*#func*/ 0 ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 + }, + { + "_a", + "{00000000-0000-0000-0000-000000000000}", + /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4, +- /*#vtbl*/ 0, /*#func*/ 0 ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 + }, + { + "aa", + "{00000000-0000-0000-0000-000000000000}", + /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4, +- /*#vtbl*/ 0, /*#func*/ 0 ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 + }, + { + "_b", + "{00000000-0000-0000-0000-000000000000}", + /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4, +- /*#vtbl*/ 0, /*#func*/ 0 ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 + }, + { + "bb", + "{00000000-0000-0000-0000-000000000000}", + /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4, +- /*#vtbl*/ 0, /*#func*/ 0 ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 + }, + { + "c", + "{016fe2ec-b2c8-45f8-b23b-39e53a75396b}", + /*kind*/ TKIND_ALIAS, /*flags*/ 0, /*align*/ 4, /*size*/ 4, +- /*#vtbl*/ 0, /*#func*/ 0 ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 + }, + { + "_c", + "{00000000-0000-0000-0000-000000000000}", + /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4, +- /*#vtbl*/ 0, /*#func*/ 0 ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 + }, + { + "cc", +- "{00000000-0000-0000-0000-000000000000}", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a75396c}", + /*kind*/ TKIND_ENUM, /*flags*/ 0, /*align*/ 4, /*size*/ 4, +- /*#vtbl*/ 0, /*#func*/ 0 ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "d", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a75396d}", ++ /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4, ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "_d", ++ "{00000000-0000-0000-0000-000000000000}", ++ /*kind*/ TKIND_ENUM, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4, ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "dd", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a75396e}", ++ /*kind*/ TKIND_ENUM, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4, ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "e", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a753970}", ++ /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4, ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "_e", ++ "{00000000-0000-0000-0000-000000000000}", ++ /*kind*/ TKIND_RECORD, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ sizeof(struct _e), ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "ee", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a753971}", ++ /*kind*/ TKIND_RECORD, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ sizeof(struct ee), ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "f", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a753972}", ++ /*kind*/ TKIND_ALIAS, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ 4, ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "_f", ++ "{00000000-0000-0000-0000-000000000000}", ++ /*kind*/ TKIND_UNION, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ sizeof(union _f), ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 ++}, ++{ ++ "ff", ++ "{016fe2ec-b2c8-45f8-b23b-39e53a753973}", ++ /*kind*/ TKIND_UNION, /*flags*/ TYPEFLAG_FRESTRICTED|TYPEFLAG_FHIDDEN, /*align*/ 4, /*size*/ sizeof(union ff), ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 0, /*#func*/ 0 + }, + { + "ITestIface", + "{ec5dfcd6-eeb0-4cd6-b51e-8030e1dac00a}", + /*kind*/ TKIND_INTERFACE, /*flags*/ TYPEFLAG_FDISPATCHABLE, /*align*/ 4, /*size*/ sizeof(ITestIface*), +- /*#vtbl*/ 10, /*#func*/ 3, ++ /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 13, /*#func*/ 6, + { + { + /*id*/ 0x60020000, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, +@@ -4349,6 +4495,48 @@ static const type_info info[] = { + NULL, + }, + }, ++ { ++ /*id*/ 0x60020003, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, ++ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 10, /*#scodes*/ 0, /*flags*/ 0, ++ {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ ++ { /* params */ ++ {VT_USERDEFINED, TKIND_ALIAS, PARAMFLAG_NONE}, ++ {-1, 0, 0} ++ }, ++ { /* names */ ++ "test4", ++ "value", ++ NULL, ++ }, ++ }, ++ { ++ /*id*/ 0x60020004, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, ++ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 11, /*#scodes*/ 0, /*flags*/ 0, ++ {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ ++ { /* params */ ++ {VT_USERDEFINED, TKIND_ALIAS, PARAMFLAG_NONE}, ++ {-1, 0, 0} ++ }, ++ { /* names */ ++ "test5", ++ "value", ++ NULL, ++ }, ++ }, ++ { ++ /*id*/ 0x60020005, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, ++ /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 12, /*#scodes*/ 0, /*flags*/ 0, ++ {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ ++ { /* params */ ++ {VT_USERDEFINED, TKIND_ALIAS, PARAMFLAG_NONE}, ++ {-1, 0, 0} ++ }, ++ { /* names */ ++ "test6", ++ "value", ++ NULL, ++ }, ++ }, + } + } + }; +@@ -4374,10 +4562,11 @@ static void test_dump_typelib(const char *name) + ITypeInfo *typeinfo; + TYPEATTR *typeattr; + BSTR bstrIfName; ++ DWORD help_ctx; + + trace("Interface %s\n", ti->name); + ole_check(ITypeLib_GetTypeInfo(typelib, iface, &typeinfo)); +- ole_check(ITypeLib_GetDocumentation(typelib, iface, &bstrIfName, NULL, NULL, NULL)); ++ ole_check(ITypeLib_GetDocumentation(typelib, iface, &bstrIfName, NULL, &help_ctx, NULL)); + expect_wstr_acpval(bstrIfName, ti->name); + SysFreeString(bstrIfName); + +@@ -4385,7 +4574,7 @@ static void test_dump_typelib(const char *name) + expect_int(typeattr->typekind, ti->type); + expect_hex(typeattr->wTypeFlags, ti->wTypeFlags); + /* FIXME: remove once widl is fixed */ +- if (typeattr->typekind == TKIND_ALIAS) ++ if (typeattr->typekind == TKIND_ALIAS && typeattr->cbAlignment != ti->cbAlignment) + { + todo_wine /* widl generates broken typelib and typeattr just reflects that */ + ok(typeattr->cbAlignment == ti->cbAlignment || broken(typeattr->cbAlignment == 1), +@@ -4399,6 +4588,8 @@ todo_wine /* widl generates broken typelib and typeattr just reflects that */ + expect_int(typeattr->cbAlignment, ti->cbAlignment); + expect_int(typeattr->cbSizeInstance, ti->cbSizeInstance); + } ++ expect_int(help_ctx, ti->help_ctx); ++ expect_int(MAKELONG(typeattr->wMinorVerNum, typeattr->wMajorVerNum), ti->version); + expect_int(typeattr->cbSizeVft, ti->cbSizeVft * sizeof(void*)); + expect_int(typeattr->cFuncs, ti->cFuncs); + +@@ -4445,7 +4636,9 @@ todo_wine /* widl generates broken typelib and typeattr just reflects that */ + ole_check(ITypeInfo_GetNames(typeinfo, desc->memid, namesTab, 256, &cNames)); + for (i = 0; i < cNames; i++) + { +- expect_wstr_acpval(namesTab[i], fn_info->names[i]); ++ /* automatically generated names differ between midl and widl */ ++ if (strncmp(fn_info->names[i], "__MIDL__", 8) != 0) ++ expect_wstr_acpval(namesTab[i], fn_info->names[i]); + SysFreeString(namesTab[i]); + } + expect_null(fn_info->names[cNames]); +-- +2.6.1 + diff --git a/patches/widl-Typelib_Generator/definition b/patches/widl-Typelib_Generator/definition new file mode 100644 index 00000000..9d6c81d4 --- /dev/null +++ b/patches/widl-Typelib_Generator/definition @@ -0,0 +1 @@ +Fixes: Fix multiple issues in widl typelib generation