From 2a9a56c4d0ae482d73f76c21b223ac2827a7a21b Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Wed, 17 Feb 2021 20:40:31 -0600 Subject: [PATCH] Rebase against c6a3072051fb88edd3847c750c2ec852f11870f6. --- ...mplement-token-elevation-information.patch | 137 ----- ...all-group-attributes-in-create_token.patch | 46 -- ...on-to-create-new-tokens-for-elevatio.patch | 219 -------- ...stub-for-TokenLinkedToken-info-class.patch | 67 --- ...dll-Support-x86_64-syscall-emulation.patch | 26 +- patches/patchinstall.sh | 2 +- ...-implementation-of-SLTG-typelib-gene.patch | 36 +- ...-for-recursive-type-references-to-SL.patch | 20 +- ...t-WinRT-parameterized-interface-type.patch | 529 ------------------ staging/upstream-commit | 2 +- 10 files changed, 45 insertions(+), 1039 deletions(-) delete mode 100644 patches/advapi32-Token_Integrity_Level/0002-server-Implement-token-elevation-information.patch delete mode 100644 patches/advapi32-Token_Integrity_Level/0005-server-Use-all-group-attributes-in-create_token.patch delete mode 100644 patches/advapi32-Token_Integrity_Level/0006-ntdll-Add-function-to-create-new-tokens-for-elevatio.patch delete mode 100644 patches/advapi32-Token_Integrity_Level/0015-ntdll-Add-semi-stub-for-TokenLinkedToken-info-class.patch delete mode 100644 patches/widl-winrt-support/0018-widl-Support-WinRT-parameterized-interface-type.patch diff --git a/patches/advapi32-Token_Integrity_Level/0002-server-Implement-token-elevation-information.patch b/patches/advapi32-Token_Integrity_Level/0002-server-Implement-token-elevation-information.patch deleted file mode 100644 index c06b36f2..00000000 --- a/patches/advapi32-Token_Integrity_Level/0002-server-Implement-token-elevation-information.patch +++ /dev/null @@ -1,137 +0,0 @@ -From d2e98b2054a5af671fd81ded32f2cf60a062312c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Sat, 5 Aug 2017 00:26:03 +0200 -Subject: [PATCH] server: Implement token elevation information. - ---- - dlls/ntdll/unix/security.c | 16 ++++++++++++---- - server/protocol.def | 8 ++++++++ - server/token.c | 22 +++++++++++++++++++--- - 3 files changed, 39 insertions(+), 7 deletions(-) - -diff --git a/dlls/ntdll/unix/security.c b/dlls/ntdll/unix/security.c -index d063d43d6d4..03a81afa46e 100644 ---- a/dlls/ntdll/unix/security.c -+++ b/dlls/ntdll/unix/security.c -@@ -390,19 +390,27 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c - break; - - case TokenElevationType: -+ SERVER_START_REQ( get_token_elevation_type ) - { - TOKEN_ELEVATION_TYPE *type = info; -- FIXME("QueryInformationToken( ..., TokenElevationType, ...) semi-stub\n"); -- *type = TokenElevationTypeFull; -+ req->handle = wine_server_obj_handle( token ); -+ status = wine_server_call( req ); -+ if (status == STATUS_SUCCESS) -+ *type = reply->elevation; - } -+ SERVER_END_REQ; - break; - - case TokenElevation: -+ SERVER_START_REQ( get_token_elevation_type ) - { - TOKEN_ELEVATION *elevation = info; -- FIXME("QueryInformationToken( ..., TokenElevation, ...) semi-stub\n"); -- elevation->TokenIsElevated = TRUE; -+ req->handle = wine_server_obj_handle( token ); -+ status = wine_server_call( req ); -+ if (status == STATUS_SUCCESS) -+ elevation->TokenIsElevated = (reply->elevation == TokenElevationTypeFull); - } -+ SERVER_END_REQ; - break; - - case TokenSessionId: -diff --git a/server/protocol.def b/server/protocol.def -index ee07b1eca14..84f0b577d72 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -3566,6 +3566,14 @@ struct handle_info - @END - - -+/* Get elevation level of token */ -+@REQ(get_token_elevation_type) -+ obj_handle_t handle; /* handle to the object */ -+@REPLY -+ unsigned int elevation; /* elevation level */ -+@END -+ -+ - /* Create I/O completion port */ - @REQ(create_completion) - unsigned int access; /* desired access to a port */ -diff --git a/server/token.c b/server/token.c -index 38a4c203d54..14343637af5 100644 ---- a/server/token.c -+++ b/server/token.c -@@ -110,6 +110,7 @@ struct token - ACL *default_dacl; /* the default DACL to assign to objects created by this user */ - TOKEN_SOURCE source; /* source of the token */ - int impersonation_level; /* impersonation level this token is capable of if non-primary token */ -+ TOKEN_ELEVATION_TYPE elevation; /* elevation level */ - }; - - struct privilege -@@ -552,7 +553,7 @@ static struct token *create_token( unsigned primary, const SID *user, - const LUID_AND_ATTRIBUTES *privs, unsigned int priv_count, - const ACL *default_dacl, TOKEN_SOURCE source, - const luid_t *modified_id, -- int impersonation_level ) -+ int impersonation_level, TOKEN_ELEVATION_TYPE elevation ) - { - struct token *token = alloc_object( &token_ops ); - if (token) -@@ -574,6 +575,7 @@ static struct token *create_token( unsigned primary, const SID *user, - token->impersonation_level = impersonation_level; - token->default_dacl = NULL; - token->primary_group = NULL; -+ token->elevation = elevation; - - /* copy user */ - token->user = memdup( user, security_sid_len( user )); -@@ -689,7 +691,8 @@ struct token *token_duplicate( struct token *src_token, unsigned primary, - token = create_token( primary, src_token->user, NULL, 0, - NULL, 0, src_token->default_dacl, - src_token->source, modified_id, -- impersonation_level ); -+ impersonation_level, -+ src_token->elevation ); - if (!token) return token; - - /* copy groups */ -@@ -895,7 +898,7 @@ struct token *token_create_admin( void ) - static const TOKEN_SOURCE admin_source = {"SeMgr", {0, 0}}; - token = create_token( TRUE, user_sid, admin_groups, ARRAY_SIZE( admin_groups ), - admin_privs, ARRAY_SIZE( admin_privs ), default_dacl, -- admin_source, NULL, -1 ); -+ admin_source, NULL, -1, TokenElevationTypeFull ); - /* we really need a primary group */ - assert( token->primary_group ); - } -@@ -1634,6 +1637,19 @@ DECL_HANDLER(get_token_statistics) - } - } - -+DECL_HANDLER(get_token_elevation_type) -+{ -+ struct token *token; -+ -+ if ((token = (struct token *)get_handle_obj( current->process, req->handle, -+ TOKEN_QUERY, -+ &token_ops ))) -+ { -+ reply->elevation = token->elevation; -+ release_object( token ); -+ } -+} -+ - DECL_HANDLER(get_token_default_dacl) - { - struct token *token; --- -2.27.0 - diff --git a/patches/advapi32-Token_Integrity_Level/0005-server-Use-all-group-attributes-in-create_token.patch b/patches/advapi32-Token_Integrity_Level/0005-server-Use-all-group-attributes-in-create_token.patch deleted file mode 100644 index e2eaf981..00000000 --- a/patches/advapi32-Token_Integrity_Level/0005-server-Use-all-group-attributes-in-create_token.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 48f4c131f9e8ffc091dde12437ad0772ed1c5ca6 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sun, 6 Aug 2017 15:16:33 +0200 -Subject: server: Use all group attributes in create_token. - ---- - server/token.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/server/token.c b/server/token.c -index 0019b3a..2a56664 100644 ---- a/server/token.c -+++ b/server/token.c -@@ -592,13 +592,13 @@ static struct token *create_token( unsigned primary, const SID *user, - return NULL; - } - memcpy( &group->sid, groups[i].Sid, security_sid_len( groups[i].Sid )); -- group->enabled = TRUE; -- group->def = TRUE; -- group->logon = (groups[i].Attributes & SE_GROUP_LOGON_ID) != 0; - group->mandatory = (groups[i].Attributes & SE_GROUP_MANDATORY) != 0; -- group->owner = (groups[i].Attributes & SE_GROUP_OWNER) != 0; -- group->resource = FALSE; -- group->deny_only = FALSE; -+ group->def = (groups[i].Attributes & SE_GROUP_ENABLED_BY_DEFAULT) != 0; -+ group->enabled = (groups[i].Attributes & SE_GROUP_ENABLED) != 0; -+ group->owner = (groups[i].Attributes & SE_GROUP_OWNER) != 0; -+ group->deny_only = (groups[i].Attributes & SE_GROUP_USE_FOR_DENY_ONLY) != 0; -+ group->logon = (groups[i].Attributes & SE_GROUP_LOGON_ID) != 0; -+ group->resource = (groups[i].Attributes & SE_GROUP_RESOURCE) != 0; - list_add_tail( &token->groups, &group->entry ); - /* Use first owner capable group as owner and primary group */ - if (!token->primary_group && group->owner) -@@ -1603,8 +1603,8 @@ DECL_HANDLER(get_token_groups) - if (group->enabled) *attr_ptr |= SE_GROUP_ENABLED; - if (group->owner) *attr_ptr |= SE_GROUP_OWNER; - if (group->deny_only) *attr_ptr |= SE_GROUP_USE_FOR_DENY_ONLY; -- if (group->resource) *attr_ptr |= SE_GROUP_RESOURCE; - if (group->logon) *attr_ptr |= SE_GROUP_LOGON_ID; -+ if (group->resource) *attr_ptr |= SE_GROUP_RESOURCE; - - memcpy(sid_ptr, &group->sid, security_sid_len( &group->sid )); - --- -2.7.4 - diff --git a/patches/advapi32-Token_Integrity_Level/0006-ntdll-Add-function-to-create-new-tokens-for-elevatio.patch b/patches/advapi32-Token_Integrity_Level/0006-ntdll-Add-function-to-create-new-tokens-for-elevatio.patch deleted file mode 100644 index cfd451ab..00000000 --- a/patches/advapi32-Token_Integrity_Level/0006-ntdll-Add-function-to-create-new-tokens-for-elevatio.patch +++ /dev/null @@ -1,219 +0,0 @@ -From c47977a8bbd739483589d1f01cfece435be1c100 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Sat, 5 Aug 2017 01:45:29 +0200 -Subject: [PATCH] ntdll: Add function to create new tokens for elevation - purposes. - ---- - dlls/ntdll/ntdll.spec | 3 ++ - dlls/ntdll/ntdll_misc.h | 3 ++ - dlls/ntdll/process.c | 18 +++++++++ - server/protocol.def | 8 ++++ - server/security.h | 1 + - server/token.c | 84 +++++++++++++++++++++++++++++++++++++++++ - 6 files changed, 117 insertions(+) - -diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 0997c310110..8e3786e1972 100644 ---- a/dlls/ntdll/ntdll.spec -+++ b/dlls/ntdll/ntdll.spec -@@ -1600,6 +1600,9 @@ - # Virtual memory - @ cdecl __wine_locked_recvmsg(long ptr long) - -+# Token -+@ cdecl __wine_create_default_token(long) -+ - # Version - @ cdecl wine_get_version() - @ cdecl wine_get_build_id() -diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h -index 63ceac42e94..5a98501381b 100644 ---- a/dlls/ntdll/ntdll_misc.h -+++ b/dlls/ntdll/ntdll_misc.h -@@ -67,6 +67,9 @@ extern void init_user_process_params(void) DECLSPEC_HIDDEN; - extern NTSTATUS restart_process( RTL_USER_PROCESS_PARAMETERS *params, NTSTATUS status ) DECLSPEC_HIDDEN; - extern void CDECL DECLSPEC_NORETURN signal_start_thread( CONTEXT *ctx ) DECLSPEC_HIDDEN; - -+/* token */ -+extern HANDLE CDECL __wine_create_default_token(BOOL admin); -+ - /* server support */ - extern BOOL is_wow64 DECLSPEC_HIDDEN; - -diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c -index 77ba5b371e2..3e91a1fa9c4 100644 ---- a/dlls/ntdll/process.c -+++ b/dlls/ntdll/process.c -@@ -72,6 +72,24 @@ HANDLE CDECL __wine_make_process_system(void) - return ret; - } - -+/*********************************************************************** -+ * __wine_create_default_token (NTDLL.@) -+ * -+ * Creates a default limited or admin token. -+ */ -+HANDLE CDECL __wine_create_default_token( BOOL admin ) -+{ -+ HANDLE ret = NULL; -+ SERVER_START_REQ( create_token ) -+ { -+ req->admin = admin; -+ if (!wine_server_call( req )) -+ ret = wine_server_ptr_handle( reply->token ); -+ } -+ SERVER_END_REQ; -+ return ret; -+} -+ - /*********************************************************************** - * restart_process - */ -diff --git a/server/protocol.def b/server/protocol.def -index 30a102d7b82..a9308904afc 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -3481,6 +3481,14 @@ struct handle_info - @END - - -+/* Create a new token */ -+@REQ(create_token) -+ unsigned int admin; /* admin or limited token */ -+@REPLY -+ obj_handle_t token; /* handle for new token */ -+@END -+ -+ - /* Create I/O completion port */ - @REQ(create_completion) - unsigned int access; /* desired access to a port */ -diff --git a/server/security.h b/server/security.h -index 6c337143c3d..21e90ccf23f 100644 ---- a/server/security.h -+++ b/server/security.h -@@ -49,6 +49,7 @@ extern const PSID security_builtin_users_sid; - extern const PSID security_builtin_admins_sid; - extern const PSID security_domain_users_sid; - extern const PSID security_high_label_sid; -+extern const PSID security_medium_label_sid; - - - /* token functions */ -diff --git a/server/token.c b/server/token.c -index c4f1cd943c2..970ed1838da 100644 ---- a/server/token.c -+++ b/server/token.c -@@ -77,6 +77,7 @@ static const SID anonymous_logon_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORIT - static const SID authenticated_user_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } }; - static const SID local_system_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } }; - static const SID high_label_sid = { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY }, { SECURITY_MANDATORY_HIGH_RID } }; -+static const SID medium_label_sid = { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY }, { SECURITY_MANDATORY_MEDIUM_RID } }; - static const SID_N(5) local_user_sid = { SID_REVISION, 5, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0, 1000 } }; - static const SID_N(2) builtin_admins_sid = { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } }; - static const SID_N(2) builtin_users_sid = { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } }; -@@ -93,6 +94,7 @@ const PSID security_builtin_admins_sid = (PSID)&builtin_admins_sid; - const PSID security_builtin_users_sid = (PSID)&builtin_users_sid; - const PSID security_domain_users_sid = (PSID)&domain_users_sid; - const PSID security_high_label_sid = (PSID)&high_label_sid; -+const PSID security_medium_label_sid = (PSID)&medium_label_sid; - - static luid_t prev_luid_value = { 1000, 0 }; - -@@ -915,6 +917,64 @@ struct token *token_create_admin( void ) - return token; - } - -+static struct token *token_create_limited( void ) -+{ -+ struct token *token = NULL; -+ static const SID_IDENTIFIER_AUTHORITY nt_authority = { SECURITY_NT_AUTHORITY }; -+ static const unsigned int alias_admins_subauth[] = { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS }; -+ static const unsigned int alias_users_subauth[] = { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS }; -+ /* on Windows, this value changes every time the user logs on */ -+ static const unsigned int logon_subauth[] = { SECURITY_LOGON_IDS_RID, 0, 1 /* FIXME: should be randomly generated when tokens are inherited by new processes */ }; -+ PSID alias_admins_sid; -+ PSID alias_users_sid; -+ PSID logon_sid; -+ const SID *user_sid = security_unix_uid_to_sid( getuid() ); -+ ACL *default_dacl = create_default_dacl( user_sid ); -+ -+ alias_admins_sid = security_sid_alloc( &nt_authority, sizeof(alias_admins_subauth)/sizeof(alias_admins_subauth[0]), -+ alias_admins_subauth ); -+ alias_users_sid = security_sid_alloc( &nt_authority, sizeof(alias_users_subauth)/sizeof(alias_users_subauth[0]), -+ alias_users_subauth ); -+ logon_sid = security_sid_alloc( &nt_authority, sizeof(logon_subauth)/sizeof(logon_subauth[0]), -+ logon_subauth ); -+ -+ if (alias_admins_sid && alias_users_sid && logon_sid && default_dacl) -+ { -+ const LUID_AND_ATTRIBUTES user_privs[] = -+ { -+ { SeChangeNotifyPrivilege , SE_PRIVILEGE_ENABLED }, -+ { SeShutdownPrivilege , 0 }, -+ { SeUndockPrivilege , 0 }, -+ }; -+ /* note: we don't include non-builtin groups here for the user - -+ * telling us these is the job of a client-side program */ -+ const SID_AND_ATTRIBUTES user_groups[] = -+ { -+ { security_world_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, -+ { security_local_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, -+ { security_interactive_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, -+ { security_authenticated_user_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, -+ { security_domain_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_OWNER }, -+ { alias_admins_sid, SE_GROUP_USE_FOR_DENY_ONLY }, -+ { alias_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, -+ { logon_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_LOGON_ID }, -+ }; -+ static const TOKEN_SOURCE admin_source = {"SeMgr", {0, 0}}; -+ token = create_token( TRUE, user_sid, user_groups, sizeof(user_groups)/sizeof(user_groups[0]), -+ user_privs, sizeof(user_privs)/sizeof(user_privs[0]), default_dacl, -+ admin_source, NULL, -1, TokenElevationTypeLimited, &medium_label_sid ); -+ /* we really need a primary group */ -+ assert( token->primary_group ); -+ } -+ -+ free( logon_sid ); -+ free( alias_admins_sid ); -+ free( alias_users_sid ); -+ free( default_dacl ); -+ -+ return token; -+} -+ - static struct privilege *token_find_privilege( struct token *token, const LUID *luid, int enabled_only ) - { - struct privilege *privilege; -@@ -1720,3 +1780,27 @@ DECL_HANDLER(set_token_default_dacl) - release_object( token ); - } - } -+ -+DECL_HANDLER(create_token) -+{ -+ struct token *token; -+ PSID label; -+ -+ if (req->admin) -+ { -+ token = token_create_admin(); -+ label = security_high_label_sid; -+ } -+ else -+ { -+ token = token_create_limited(); -+ label = security_medium_label_sid; -+ } -+ -+ if (token) -+ { -+ if (token_assign_label( token, label )) -+ reply->token = alloc_handle( current->process, token, TOKEN_ALL_ACCESS, 0 ); -+ release_object( token ); -+ } -+} --- -2.28.0 - diff --git a/patches/advapi32-Token_Integrity_Level/0015-ntdll-Add-semi-stub-for-TokenLinkedToken-info-class.patch b/patches/advapi32-Token_Integrity_Level/0015-ntdll-Add-semi-stub-for-TokenLinkedToken-info-class.patch deleted file mode 100644 index 57fc1aef..00000000 --- a/patches/advapi32-Token_Integrity_Level/0015-ntdll-Add-semi-stub-for-TokenLinkedToken-info-class.patch +++ /dev/null @@ -1,67 +0,0 @@ -From e34d019222909281390f83149be755a4145024c4 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 7 Aug 2017 15:28:33 +0200 -Subject: [PATCH] ntdll: Add semi-stub for TokenLinkedToken info class. - ---- - dlls/ntdll/unix/security.c | 30 +++++++++++++++++++++++++++++- - 1 file changed, 29 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/unix/security.c b/dlls/ntdll/unix/security.c -index f0057116dee..2769e5f6a7b 100644 ---- a/dlls/ntdll/unix/security.c -+++ b/dlls/ntdll/unix/security.c -@@ -138,6 +138,7 @@ NTSTATUS WINAPI NtDuplicateToken( HANDLE token, ACCESS_MASK access, OBJECT_ATTRI - return status; - } - -+extern HANDLE CDECL __wine_create_default_token(BOOL admin); - - /*********************************************************************** - * NtQueryInformationToken (NTDLL.@) -@@ -166,7 +167,7 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c - 0, /* TokenAuditPolicy */ - 0, /* TokenOrigin */ - sizeof(TOKEN_ELEVATION_TYPE), /* TokenElevationType */ -- 0, /* TokenLinkedToken */ -+ sizeof(TOKEN_LINKED_TOKEN), /* TokenLinkedToken */ - sizeof(TOKEN_ELEVATION), /* TokenElevation */ - 0, /* TokenHasRestrictions */ - 0, /* TokenAccessInformation */ -@@ -401,6 +402,33 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c - SERVER_END_REQ; - break; - -+ case TokenLinkedToken: -+ SERVER_START_REQ( get_token_elevation_type ) -+ { -+ TOKEN_LINKED_TOKEN *linked_token = info; -+ req->handle = wine_server_obj_handle( token ); -+ status = wine_server_call( req ); -+ if (status == STATUS_SUCCESS) -+ { -+ HANDLE token; -+ /* FIXME: On Wine we do not have real linked tokens yet. Typically, a -+ * program running with admin privileges is linked to a limited token, -+ * and vice versa. We just create a new token instead of storing links -+ * on the wineserver side. Using TokenLinkedToken twice should return -+ * back the original token. */ -+ if ((reply->elevation == TokenElevationTypeFull || reply->elevation == TokenElevationTypeLimited) && -+ (token = __wine_create_default_token( reply->elevation != TokenElevationTypeFull ))) -+ { -+ status = NtDuplicateToken( token, 0, NULL, SecurityIdentification, TokenImpersonation, &linked_token->LinkedToken ); -+ NtClose( token ); -+ } -+ else -+ status = STATUS_NO_TOKEN; -+ } -+ } -+ SERVER_END_REQ; -+ break; -+ - case TokenElevation: - SERVER_START_REQ( get_token_elevation_type ) - { --- -2.27.0 - diff --git a/patches/ntdll-Syscall_Emulation/0001-ntdll-Support-x86_64-syscall-emulation.patch b/patches/ntdll-Syscall_Emulation/0001-ntdll-Support-x86_64-syscall-emulation.patch index 30a6a9d4..97408196 100644 --- a/patches/ntdll-Syscall_Emulation/0001-ntdll-Support-x86_64-syscall-emulation.patch +++ b/patches/ntdll-Syscall_Emulation/0001-ntdll-Support-x86_64-syscall-emulation.patch @@ -1,4 +1,4 @@ -From 375a86a401828569803cde23143b024c72eb9383 Mon Sep 17 00:00:00 2001 +From 32242051c19fcd4f4f0ada534ad5a1621df96b45 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Tue, 14 Jul 2020 15:00:34 +0300 Subject: [PATCH] ntdll: Support x86_64 syscall emulation. @@ -10,10 +10,10 @@ Subject: [PATCH] ntdll: Support x86_64 syscall emulation. 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac -index 553b4c3df98e..d3b04ae90a04 100644 +index 5e392ff5ed6..d814b6f85d7 100644 --- a/configure.ac +++ b/configure.ac -@@ -465,6 +465,7 @@ AC_CHECK_HEADERS(\ +@@ -466,6 +466,7 @@ AC_CHECK_HEADERS(\ linux/joystick.h \ linux/major.h \ linux/param.h \ @@ -22,7 +22,7 @@ index 553b4c3df98e..d3b04ae90a04 100644 linux/types.h \ linux/ucdrom.h \ diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c -index 925de00545f7..6502a15592b6 100644 +index 892d208e43a..bb820eee6e5 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -28,6 +28,7 @@ @@ -47,7 +47,7 @@ index 925de00545f7..6502a15592b6 100644 #define NONAMELESSUNION #define NONAMELESSSTRUCT #include "ntstatus.h" -@@ -2238,6 +2246,114 @@ static inline DWORD is_privileged_instr( CONTEXT *context ) +@@ -2320,6 +2328,114 @@ static inline DWORD is_privileged_instr( CONTEXT *context ) return 0; } @@ -162,7 +162,7 @@ index 925de00545f7..6502a15592b6 100644 /*********************************************************************** * handle_interrupt -@@ -2725,6 +2841,7 @@ void signal_init_process(void) +@@ -2779,6 +2895,7 @@ void signal_init_process(void) if (sigaction( SIGSEGV, &sig_act, NULL ) == -1) goto error; if (sigaction( SIGILL, &sig_act, NULL ) == -1) goto error; if (sigaction( SIGBUS, &sig_act, NULL ) == -1) goto error; @@ -171,18 +171,18 @@ index 925de00545f7..6502a15592b6 100644 error: diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c -index fb5c26da07f9..2c2606b21e56 100644 +index 5645d3aa9af..441a3800726 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c -@@ -1524,6 +1524,7 @@ void output_syscalls( DLLSPEC *spec ) +@@ -1526,6 +1526,7 @@ void output_syscalls( DLLSPEC *spec ) /* Legends of Runeterra hooks the first system call return instruction, and * depends on us returning to it. Adjust the return address accordingly. */ output( "\tsubq $0xb,0x8(%%rbp)\n" ); + output( "\tsubq $0xf000,%%rax\n" ); - output( "\tmovq %%rsp,0x328(%%rcx)\n" ); /* amd64_thread_data()->syscall_frame */ - output( "\tcmpq $%u,%%rax\n", count ); - output( "\tjae 4f\n" ); -@@ -1717,7 +1718,7 @@ void output_syscalls( DLLSPEC *spec ) + output( "\tmovq 0x8(%%rbp),%%rbx\n" ); + output( "\tmovq %%rbx,-0x28(%%rbp)\n" ); + output( "\tleaq 0x10(%%rbp),%%rbx\n" ); +@@ -1746,7 +1747,7 @@ void output_syscalls( DLLSPEC *spec ) * validate that instruction, we can just put a jmp there instead. */ output( "\t.byte 0x4c,0x8b,0xd1\n" ); /* movq %rcx,%r10 */ output( "\t.byte 0xb8\n" ); /* movl $i,%eax */ @@ -192,5 +192,5 @@ index fb5c26da07f9..2c2606b21e56 100644 output( "\t.byte 0x75,0x03\n" ); /* jne 1f */ output( "\t.byte 0x0f,0x05\n" ); /* syscall */ -- -2.29.2 +2.20.1 diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 0c4b3cac..e7b4e2a5 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -51,7 +51,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "a55a37d1dae2231d8dec9f3191449f89be0b10dc" + echo "c6a3072051fb88edd3847c750c2ec852f11870f6" } # Show version information diff --git a/patches/widl-SLTG_Typelib_Support/0001-widl-Add-initial-implementation-of-SLTG-typelib-gene.patch b/patches/widl-SLTG_Typelib_Support/0001-widl-Add-initial-implementation-of-SLTG-typelib-gene.patch index d2b196f7..de4649b0 100644 --- a/patches/widl-SLTG_Typelib_Support/0001-widl-Add-initial-implementation-of-SLTG-typelib-gene.patch +++ b/patches/widl-SLTG_Typelib_Support/0001-widl-Add-initial-implementation-of-SLTG-typelib-gene.patch @@ -1,4 +1,4 @@ -From 922bbc203c309dde57dc836fea516a364822d2c6 Mon Sep 17 00:00:00 2001 +From cf653804e70bc54a027bd679cf27468125c46520 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Wed, 23 Dec 2015 19:37:37 +0800 Subject: [PATCH] widl: Add initial implementation of SLTG typelib generator. @@ -7,12 +7,12 @@ Subject: [PATCH] widl: Add initial implementation of SLTG typelib generator. tools/widl/Makefile.in | 3 +- tools/widl/typelib.h | 1 + tools/widl/widl.c | 6 + - tools/widl/write_sltg.c | 557 ++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 566 insertions(+), 1 deletion(-) + tools/widl/write_sltg.c | 561 ++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 570 insertions(+), 1 deletion(-) create mode 100644 tools/widl/write_sltg.c diff --git a/tools/widl/Makefile.in b/tools/widl/Makefile.in -index 80a12601de9..2736cd7874e 100644 +index a231087f37c..77992cba337 100644 --- a/tools/widl/Makefile.in +++ b/tools/widl/Makefile.in @@ -14,7 +14,8 @@ C_SRCS = \ @@ -36,10 +36,10 @@ index 7df7d290825..5d9f45a7c38 100644 +extern int create_sltg_typelib(typelib_t *typelib); #endif diff --git a/tools/widl/widl.c b/tools/widl/widl.c -index aa6697135be..a361d862337 100644 +index 8da887ea636..22f8f2602a6 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c -@@ -167,6 +167,7 @@ enum { +@@ -170,6 +170,7 @@ enum { DLLDATA_ONLY_OPTION, LOCAL_STUBS_OPTION, NOSTDINC_OPTION, @@ -47,7 +47,7 @@ index aa6697135be..a361d862337 100644 PREFIX_ALL_OPTION, PREFIX_CLIENT_OPTION, PREFIX_SERVER_OPTION, -@@ -193,6 +194,7 @@ static const struct option long_options[] = { +@@ -196,6 +197,7 @@ static const struct option long_options[] = { { "nostdinc", 0, NULL, NOSTDINC_OPTION }, { "ns_prefix", 0, NULL, RT_NS_PREFIX }, { "oldnames", 0, NULL, OLDNAMES_OPTION }, @@ -55,7 +55,7 @@ index aa6697135be..a361d862337 100644 { "output", 0, NULL, 'o' }, { "prefix-all", 1, NULL, PREFIX_ALL_OPTION }, { "prefix-client", 1, NULL, PREFIX_CLIENT_OPTION }, -@@ -725,6 +727,10 @@ int main(int argc,char *argv[]) +@@ -747,6 +749,10 @@ int main(int argc,char *argv[]) do_everything = 0; do_typelib = 1; break; @@ -68,10 +68,10 @@ index aa6697135be..a361d862337 100644 break; diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c new file mode 100644 -index 00000000000..3c478ca667d +index 00000000000..80e3b5f06a3 --- /dev/null +++ b/tools/widl/write_sltg.c -@@ -0,0 +1,557 @@ +@@ -0,0 +1,561 @@ +/* + * Typelib (SLTG) generation + * @@ -415,15 +415,19 @@ index 00000000000..3c478ca667d + + case STMT_TYPEDEF: + { -+ const type_list_t *type_entry = stmt->u.type_list; -+ for (; type_entry; type_entry = type_entry->next) ++ typeref_t *ref; ++ ++ if (!stmt->u.type_list) ++ break; ++ ++ LIST_FOR_EACH_ENTRY(ref, stmt->u.type_list, typeref_t, entry) + { + /* if the type is public then add the typedef, otherwise attempt + * to add the aliased type */ -+ if (is_attr(type_entry->type->attrs, ATTR_PUBLIC)) -+ add_typedef_typeinfo(typelib, type_entry->type); ++ if (is_attr(ref->type->attrs, ATTR_PUBLIC)) ++ add_typedef_typeinfo(typelib, ref->type); + else -+ add_type_typeinfo(typelib, type_alias_get_aliasee_type(type_entry->type)); ++ add_type_typeinfo(typelib, type_alias_get_aliasee_type(ref->type)); + } + break; + } @@ -630,5 +634,5 @@ index 00000000000..3c478ca667d + return 1; +} -- -2.24.0.rc1 +2.20.1 diff --git a/patches/widl-SLTG_Typelib_Support/0012-widl-Add-support-for-recursive-type-references-to-SL.patch b/patches/widl-SLTG_Typelib_Support/0012-widl-Add-support-for-recursive-type-references-to-SL.patch index 10f76487..f927be3f 100644 --- a/patches/widl-SLTG_Typelib_Support/0012-widl-Add-support-for-recursive-type-references-to-SL.patch +++ b/patches/widl-SLTG_Typelib_Support/0012-widl-Add-support-for-recursive-type-references-to-SL.patch @@ -1,4 +1,4 @@ -From 5d75156efed85e3f124f3b48511f0fb41fac6387 Mon Sep 17 00:00:00 2001 +From 8438b605a8c08605a05e60114a549f6e72cda435 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 14 Jan 2016 15:16:37 +0800 Subject: [PATCH] widl: Add support for recursive type references to SLTG @@ -9,7 +9,7 @@ Subject: [PATCH] widl: Add support for recursive type references to SLTG 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c -index 7a6967c7f39..2ba5a3c25b0 100644 +index bb3a6c003d0..b4fd8f38006 100644 --- a/tools/widl/write_sltg.c +++ b/tools/widl/write_sltg.c @@ -203,6 +203,12 @@ struct sltg_hrefinfo @@ -139,21 +139,21 @@ index 7a6967c7f39..2ba5a3c25b0 100644 init_typeinfo(&ti, type, TKIND_RECORD, &hrefmap); append_data(&data, &ti, sizeof(ti)); -@@ -1060,12 +1090,8 @@ static void add_statement(struct sltg_typelib *typelib, const statement_t *stmt) - const type_list_t *type_entry = stmt->u.type_list; - for (; type_entry; type_entry = type_entry->next) +@@ -1064,12 +1094,8 @@ static void add_statement(struct sltg_typelib *typelib, const statement_t *stmt) + + LIST_FOR_EACH_ENTRY(ref, stmt->u.type_list, typeref_t, entry) { - /* if the type is public then add the typedef, otherwise attempt - * to add the aliased type */ -- if (is_attr(type_entry->type->attrs, ATTR_PUBLIC)) -- add_typedef_typeinfo(typelib, type_entry->type); +- if (is_attr(ref->type->attrs, ATTR_PUBLIC)) +- add_typedef_typeinfo(typelib, ref->type); - else -- add_type_typeinfo(typelib, type_alias_get_aliasee_type(type_entry->type)); +- add_type_typeinfo(typelib, type_alias_get_aliasee_type(ref->type)); + /* in old style typelibs all types are public */ -+ add_type_typeinfo(typelib, type_entry->type); ++ add_type_typeinfo(typelib, ref->type); } break; } -- -2.17.1 +2.20.1 diff --git a/patches/widl-winrt-support/0018-widl-Support-WinRT-parameterized-interface-type.patch b/patches/widl-winrt-support/0018-widl-Support-WinRT-parameterized-interface-type.patch deleted file mode 100644 index d603821b..00000000 --- a/patches/widl-winrt-support/0018-widl-Support-WinRT-parameterized-interface-type.patch +++ /dev/null @@ -1,529 +0,0 @@ -From 5ec925e389c8b5403173aaa81940dbc63cd4b7ed Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 4 Feb 2021 17:10:15 +0100 -Subject: [PATCH] widl: Support WinRT parameterized interface type. - -This allows parameterized interfaces to be instanciated in declare -blocks, in the same way MIDL does, generating a new interface to the -header from the parameterized type template, replacing its parameters -with the given types. ---- - include/windows.media.speechsynthesis.idl | 24 +++ - tools/widl/header.c | 7 +- - tools/widl/parser.l | 1 + - tools/widl/parser.y | 63 +++++- - tools/widl/typetree.c | 238 ++++++++++++++++++++++ - tools/widl/typetree.h | 2 + - 6 files changed, 330 insertions(+), 5 deletions(-) - -diff --git a/include/windows.media.speechsynthesis.idl b/include/windows.media.speechsynthesis.idl -index 87497678f30..af4466681dc 100644 ---- a/include/windows.media.speechsynthesis.idl -+++ b/include/windows.media.speechsynthesis.idl -@@ -35,11 +35,24 @@ namespace Windows { - interface ISpeechSynthesizer; - interface ISpeechSynthesizer2; - interface IVoiceInformation; -+ runtimeclass SpeechSynthesizer; - runtimeclass VoiceInformation; - } - } - } - -+namespace Windows { -+ namespace Media { -+ namespace SpeechSynthesis { -+ declare { -+ interface Windows.Foundation.Collections.IIterator; -+ interface Windows.Foundation.Collections.IIterable; -+ interface Windows.Foundation.Collections.IVectorView; -+ } -+ } -+ } -+} -+ - namespace Windows { - namespace Media { - namespace SpeechSynthesis { -@@ -64,6 +77,17 @@ namespace Windows { - [propget] HRESULT Gender([out] [retval] VoiceGender* value); - } - -+ [ -+ contract(Windows.Foundation.UniversalApiContract, 1.0), -+ exclusiveto(Windows.Media.SpeechSynthesis.SpeechSynthesizer), -+ uuid(7d526ecc-7533-4c3f-85be-888c2baeebdc) -+ ] -+ interface IInstalledVoicesStatic : IInspectable -+ { -+ [propget] HRESULT AllVoices([out, retval] Windows.Foundation.Collections.IVectorView** value); -+ [propget] HRESULT DefaultVoice([out, retval] VoiceInformation** value); -+ } -+ - [ - contract(Windows.Foundation.UniversalApiContract, 1.0), - marshaling_behavior(agile) -diff --git a/tools/widl/header.c b/tools/widl/header.c -index 8423756e060..a4f1db56a01 100644 ---- a/tools/widl/header.c -+++ b/tools/widl/header.c -@@ -1479,7 +1479,8 @@ static void write_forward(FILE *header, type_t *iface) - fprintf(header, "typedef interface %s %s;\n", iface->c_name, iface->c_name); - fprintf(header, "#ifdef __cplusplus\n"); - write_namespace_start(header, iface->namespace); -- write_line(header, 0, "interface %s;", iface->name); -+ if (strchr(iface->name, '<')) write_line(header, 0, "template<> struct %s;", iface->name); -+ else write_line(header, 0, "interface %s;", iface->name); - write_namespace_end(header, iface->namespace); - fprintf(header, "#endif /* __cplusplus */\n"); - fprintf(header, "#endif\n\n" ); -@@ -1548,11 +1549,13 @@ static void write_com_interface_end(FILE *header, type_t *iface) - write_namespace_start(header, iface->namespace); - } - if (uuid) { -+ if (strchr(iface->name, '<')) write_line(header, 0, "template<>"); - write_line(header, 0, "MIDL_INTERFACE(\"%s\")", uuid_string(uuid)); - indent(header, 0); - }else { - indent(header, 0); -- fprintf(header, "interface "); -+ if (strchr(iface->name, '<')) fprintf(header, "template<> struct "); -+ else fprintf(header, "interface "); - } - if (type_iface_get_inherit(iface)) - { -diff --git a/tools/widl/parser.l b/tools/widl/parser.l -index 946dba84cd6..d319954edd3 100644 ---- a/tools/widl/parser.l -+++ b/tools/widl/parser.l -@@ -276,6 +276,7 @@ static const struct keyword keywords[] = { - {"coclass", tCOCLASS, 0}, - {"const", tCONST, 0}, - {"cpp_quote", tCPPQUOTE, 0}, -+ {"declare", tDECLARE, 1}, - {"default", tDEFAULT, 0}, - {"dispinterface", tDISPINTERFACE, 0}, - {"double", tDOUBLE, 0}, -diff --git a/tools/widl/parser.y b/tools/widl/parser.y -index 92f6345e2dc..7ab825b612b 100644 ---- a/tools/widl/parser.y -+++ b/tools/widl/parser.y -@@ -81,6 +81,7 @@ static void pop_namespace(const char *name); - static void push_parameters_namespace(const char *name); - static void pop_parameters_namespace(const char *name); - -+static statement_list_t *append_parameterized_type_stmts(statement_list_t *stmts); - static void check_arg_attrs(const var_t *arg); - static void check_statements(const statement_list_t *stmts, int is_inside_library); - static void check_all_user_types(const statement_list_t *stmts); -@@ -108,6 +109,7 @@ 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, int declonly); - static statement_t *make_statement_import(const char *str); -+static statement_t *make_statement_parameterized_type(type_t *type, type_list_t *params); - 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 *); -@@ -118,6 +120,7 @@ static struct namespace global_namespace = { - - static struct namespace *current_namespace = &global_namespace; - static struct namespace *parameters_namespace = NULL; -+static statement_list_t *parameterized_type_stmts = NULL; - - static typelib_t *current_typelib; - -@@ -180,6 +183,7 @@ static typelib_t *current_typelib; - %token tCONTRACTVERSION - %token tCONTROL tCPPQUOTE - %token tCUSTOM -+%token tDECLARE - %token tDECODE tDEFAULT tDEFAULTBIND - %token tDEFAULTCOLLELEM - %token tDEFAULTVALUE -@@ -320,6 +324,8 @@ static typelib_t *current_typelib; - %type library_start librarydef - %type statement typedef pragma_warning - %type gbl_statements imp_statements int_statements -+%type decl_block decl_statements -+%type imp_decl_block imp_decl_statements - %type warnings - %type allocate_option_list allocate_option - %type namespace_pfx -@@ -343,7 +349,8 @@ static typelib_t *current_typelib; - - %% - --input: gbl_statements m_acf { check_statements($1, FALSE); -+input: gbl_statements m_acf { $1 = append_parameterized_type_stmts($1); -+ check_statements($1, FALSE); - check_all_user_types($1); - write_header($1); - write_id_data($1); -@@ -359,6 +366,22 @@ input: gbl_statements m_acf { check_statements($1, FALSE); - - m_acf: /* empty */ | aACF acf_statements - -+decl_statements: { $$ = NULL; } -+ | decl_statements tINTERFACE qualified_type '<' parameterized_types '>' ';' -+ { parameterized_type_stmts = append_statement(parameterized_type_stmts, make_statement_parameterized_type($3, $5)); -+ $$ = append_statement($1, make_statement_reference(type_parameterized_type_specialize_declare($3, $5))); -+ } -+ ; -+ -+decl_block: tDECLARE '{' decl_statements '}' { $$ = $3; } -+ -+imp_decl_statements: { $$ = NULL; } -+ | imp_decl_statements tINTERFACE qualified_type '<' parameterized_types '>' ';' -+ { $$ = append_statement($1, make_statement_reference(type_parameterized_type_specialize_declare($3, $5))); } -+ ; -+ -+imp_decl_block: tDECLARE '{' imp_decl_statements '}' { $$ = $3; } -+ - gbl_statements: { $$ = NULL; } - | gbl_statements namespacedef '{' { push_namespace($2); } gbl_statements '}' - { pop_namespace($2); $$ = append_statements($1, $5); } -@@ -380,6 +403,7 @@ gbl_statements: { $$ = NULL; } - | gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); } - | gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); } - | gbl_statements statement { $$ = append_statement($1, $2); } -+ | gbl_statements decl_block { $$ = append_statements($1, $2); } - ; - - imp_statements: { $$ = NULL; } -@@ -402,6 +426,7 @@ imp_statements: { $$ = NULL; } - | imp_statements statement { $$ = append_statement($1, $2); } - | imp_statements importlib { $$ = append_statement($1, make_statement_importlib($2)); } - | imp_statements librarydef { $$ = append_statement($1, make_statement_library($2)); } -+ | imp_statements imp_decl_block { $$ = append_statements($1, $2); } - ; - - int_statements: { $$ = NULL; } -@@ -3083,6 +3108,27 @@ static void check_async_uuid(type_t *iface) - iface->details.iface->async_iface = async_iface->details.iface->async_iface = async_iface; - } - -+static statement_list_t *append_parameterized_type_stmts(statement_list_t *stmts) -+{ -+ statement_t *stmt, *next; -+ if (stmts && parameterized_type_stmts) LIST_FOR_EACH_ENTRY_SAFE(stmt, next, parameterized_type_stmts, statement_t, entry) -+ { -+ switch(stmt->type) { -+ case STMT_TYPE: -+ stmt->u.type = type_parameterized_type_specialize_define(stmt->u.type_list->type, stmt->u.type_list->next); -+ stmt->declonly = FALSE; -+ list_remove(&stmt->entry); -+ stmts = append_statement(stmts, stmt); -+ break; -+ default: -+ assert(0); /* should not be there */ -+ break; -+ } -+ } -+ -+ return stmts; -+} -+ - static void check_statements(const statement_list_t *stmts, int is_inside_library) - { - const statement_t *stmt; -@@ -3264,6 +3310,15 @@ static statement_t *make_statement_typedef(declarator_list_t *decls, int declonl - return stmt; - } - -+static statement_t *make_statement_parameterized_type(type_t *type, type_list_t *params) -+{ -+ statement_t *stmt = make_statement(STMT_TYPE); -+ stmt->u.type_list = xmalloc(sizeof(type_list_t)); -+ stmt->u.type_list->type = type; -+ stmt->u.type_list->next = params; -+ return stmt; -+} -+ - static statement_list_t *append_statements(statement_list_t *l1, statement_list_t *l2) - { - if (!l2) return l1; -@@ -3308,8 +3363,10 @@ type_t *find_parameterized_type(type_t *type, type_list_t *params) - assert(type->type_type == TYPE_PARAMETERIZED_TYPE); - type = type_parameterized_type_specialize_partial(type, params); - } -- /* FIXME: If not in another parameterized type, we'll have to look for the declared specialization. */ -- else error_loc("parameterized type '%s' not declared\n", name); -+ else if ((type = find_type(name, type->namespace, 0))) -+ assert(type->type_type != TYPE_PARAMETERIZED_TYPE); -+ else -+ error_loc("parameterized type '%s' not declared\n", name); - - free(name); - return type; -diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c -index 1a5b13add96..77148de8d0f 100644 ---- a/tools/widl/typetree.c -+++ b/tools/widl/typetree.c -@@ -137,6 +137,41 @@ char *format_parameterized_type_name(type_t *type, type_list_t *params) - return buf; - } - -+static char const *parameterized_type_shorthands[][2] = { -+ {"Windows_CFoundation_CCollections_C", "__F"}, -+ {"Windows_CFoundation_C", "__F"}, -+}; -+ -+static char *format_parameterized_type_c_name(type_t *type, type_list_t *params) -+{ -+ size_t len = 0, pos = 0; -+ char *buf = NULL, *tmp; -+ type_list_t *entry; -+ int i, count = 0; -+ -+ pos += append_namespaces(&buf, &len, pos, type->namespace, "__x_", "_C", type->name, use_abi_namespace ? "ABI" : NULL); -+ for (entry = params; entry; entry = entry->next) count++; -+ pos += strappend(&buf, &len, pos, "_%d", count); -+ for (entry = params; entry; entry = entry->next) -+ { -+ for (type = entry->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {} -+ pos += append_namespaces(&buf, &len, pos, type->namespace, "_", "__C", type->name, NULL); -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(parameterized_type_shorthands); ++i) -+ { -+ if ((tmp = strstr(buf, parameterized_type_shorthands[i][0])) && -+ (tmp - buf) == strlen(use_abi_namespace ? "__x_ABI_C" : "__x_C")) -+ { -+ tmp += strlen(parameterized_type_shorthands[i][0]); -+ strcpy(buf, parameterized_type_shorthands[i][1]); -+ memmove(buf + 3, tmp, len - (tmp - buf) + 1); -+ } -+ } -+ -+ return buf; -+} -+ - type_t *type_new_function(var_list_t *args) - { - var_t *arg; -@@ -652,6 +687,209 @@ type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *pa - return new_type; - } - -+static type_t *replace_type_parameters_in_type(type_t *type, type_list_t *orig, type_list_t *repl); -+ -+static type_list_t *replace_type_parameters_in_type_list(type_list_t *type_list, type_list_t *orig, type_list_t *repl) -+{ -+ type_list_t *entry, *new_entry, **next, *first = NULL; -+ -+ if (!type_list) return type_list; -+ -+ next = &first; -+ for (entry = type_list; entry; entry = entry->next) -+ { -+ new_entry = xmalloc(sizeof(*new_entry)); -+ new_entry->type = replace_type_parameters_in_type(entry->type, orig, repl); -+ new_entry->next = NULL; -+ *next = new_entry; -+ next = &new_entry->next; -+ } -+ -+ return first; -+} -+ -+static var_t *replace_type_parameters_in_var(var_t *var, type_list_t *orig, type_list_t *repl) -+{ -+ var_t *new_var = xmalloc(sizeof(*new_var)); -+ *new_var = *var; -+ list_init(&new_var->entry); -+ new_var->declspec.type = replace_type_parameters_in_type(var->declspec.type, orig, repl); -+ return new_var; -+} -+ -+static var_list_t *replace_type_parameters_in_var_list(var_list_t *var_list, type_list_t *orig, type_list_t *repl) -+{ -+ var_list_t *new_var_list; -+ var_t *var, *new_var; -+ -+ if (!var_list) return var_list; -+ -+ new_var_list = xmalloc(sizeof(*new_var_list)); -+ list_init(new_var_list); -+ -+ LIST_FOR_EACH_ENTRY(var, var_list, var_t, entry) -+ { -+ new_var = replace_type_parameters_in_var(var, orig, repl); -+ list_add_tail(new_var_list, &new_var->entry); -+ } -+ -+ return new_var_list; -+} -+ -+static statement_t *replace_type_parameters_in_statement(statement_t *stmt, type_list_t *orig, type_list_t *repl) -+{ -+ statement_t *new_stmt = xmalloc(sizeof(*new_stmt)); -+ *new_stmt = *stmt; -+ list_init(&new_stmt->entry); -+ -+ switch (stmt->type) -+ { -+ case STMT_DECLARATION: -+ new_stmt->u.var = replace_type_parameters_in_var(stmt->u.var, orig, repl); -+ break; -+ case STMT_LIBRARY: -+ case STMT_TYPE: -+ case STMT_TYPEREF: -+ case STMT_MODULE: -+ case STMT_TYPEDEF: -+ new_stmt->u.type_list = replace_type_parameters_in_type_list(stmt->u.type_list, orig, repl); -+ break; -+ case STMT_IMPORT: -+ case STMT_IMPORTLIB: -+ case STMT_PRAGMA: -+ case STMT_CPPQUOTE: -+ fprintf(stderr, "%d\n", stmt->type); -+ assert(0); -+ break; -+ } -+ -+ return new_stmt; -+} -+ -+static statement_list_t *replace_type_parameters_in_statement_list(statement_list_t *stmt_list, type_list_t *orig, type_list_t *repl) -+{ -+ statement_list_t *new_stmt_list; -+ statement_t *stmt, *new_stmt; -+ -+ if (!stmt_list) return stmt_list; -+ -+ new_stmt_list = xmalloc(sizeof(*new_stmt_list)); -+ list_init(new_stmt_list); -+ -+ LIST_FOR_EACH_ENTRY(stmt, stmt_list, statement_t, entry) -+ { -+ new_stmt = replace_type_parameters_in_statement(stmt, orig, repl); -+ list_add_tail(new_stmt_list, &new_stmt->entry); -+ } -+ -+ return new_stmt_list; -+} -+ -+static type_t *replace_type_parameters_in_type(type_t *type, type_list_t *orig, type_list_t *repl) -+{ -+ type_list_t *o, *r; -+ type_t *t; -+ -+ if (!type) return type; -+ switch (type->type_type) -+ { -+ case TYPE_VOID: -+ case TYPE_BASIC: -+ case TYPE_ENUM: -+ case TYPE_BITFIELD: -+ case TYPE_INTERFACE: -+ case TYPE_RUNTIMECLASS: -+ return type; -+ case TYPE_PARAMETER: -+ for (o = orig, r = repl; o && r; o = o->next, r = r->next) -+ if (type == o->type) return r->type; -+ return type; -+ case TYPE_POINTER: -+ t = replace_type_parameters_in_type(type->details.pointer.ref.type, orig, repl); -+ if (t == type->details.pointer.ref.type) return type; -+ type = duptype(type, 0); -+ type->details.pointer.ref.type = t; -+ return type; -+ case TYPE_ALIAS: -+ t = replace_type_parameters_in_type(type->details.alias.aliasee.type, orig, repl); -+ if (t == type->details.alias.aliasee.type) return type; -+ type = duptype(type, 0); -+ type->details.alias.aliasee.type = t; -+ return type; -+ case TYPE_ARRAY: -+ t = replace_type_parameters_in_type(type->details.array.elem.type, orig, repl); -+ if (t == t->details.array.elem.type) return type; -+ type = duptype(type, 0); -+ t->details.array.elem.type = t; -+ return type; -+ case TYPE_FUNCTION: -+ t = duptype(type, 0); -+ t->details.function = xmalloc(sizeof(*t->details.function)); -+ t->details.function->args = replace_type_parameters_in_var_list(type->details.function->args, orig, repl); -+ t->details.function->retval = replace_type_parameters_in_var(type->details.function->retval, orig, repl); -+ return t; -+ case TYPE_PARAMETERIZED_TYPE: -+ t = type->details.parameterized.type; -+ if (t->type_type != TYPE_PARAMETERIZED_TYPE) return find_parameterized_type(type, repl); -+ repl = replace_type_parameters_in_type_list(type->details.parameterized.params, orig, repl); -+ return replace_type_parameters_in_type(t, t->details.parameterized.params, repl); -+ case TYPE_STRUCT: -+ case TYPE_ENCAPSULATED_UNION: -+ case TYPE_UNION: -+ case TYPE_MODULE: -+ case TYPE_COCLASS: -+ case TYPE_APICONTRACT: -+ assert(0); /* FIXME: implement when needed */ -+ break; -+ } -+ -+ return type; -+} -+ -+static void type_parameterized_interface_specialize(type_t *tmpl, type_t *iface, type_list_t *orig, type_list_t *repl) -+{ -+ iface->details.iface = xmalloc(sizeof(*iface->details.iface)); -+ iface->details.iface->disp_methods = NULL; -+ iface->details.iface->disp_props = NULL; -+ iface->details.iface->stmts = replace_type_parameters_in_statement_list(tmpl->details.iface->stmts, orig, repl); -+ iface->details.iface->inherit = replace_type_parameters_in_type(tmpl->details.iface->inherit, orig, repl); -+ iface->details.iface->disp_inherit = NULL; -+ iface->details.iface->async_iface = NULL; -+ iface->details.iface->requires = NULL; -+} -+ -+type_t *type_parameterized_type_specialize_declare(type_t *type, type_list_t *params) -+{ -+ type_t *tmpl = type->details.parameterized.type; -+ type_t *new_type = duptype(tmpl, 0); -+ -+ new_type->namespace = type->namespace; -+ new_type->name = format_parameterized_type_name(type, params); -+ reg_type(new_type, new_type->name, new_type->namespace, 0); -+ new_type->c_name = format_parameterized_type_c_name(type, params); -+ -+ return new_type; -+} -+ -+type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *params) -+{ -+ type_list_t *orig = type->details.parameterized.params; -+ type_t *tmpl = type->details.parameterized.type; -+ type_t *iface = find_parameterized_type(type, params); -+ -+ if (tmpl->type_type == TYPE_INTERFACE) -+ type_parameterized_interface_specialize(tmpl, iface, orig, params); -+ else -+ { -+ error_loc("Unsupported parameterized type template %d\n", tmpl->type_type); -+ return NULL; -+ } -+ -+ iface->defined = TRUE; -+ compute_method_indexes(iface); -+ return iface; -+} -+ - int type_is_equal(const type_t *type1, const type_t *type2) - { - if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2)) -diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h -index 538134871a2..b3812649f59 100644 ---- a/tools/widl/typetree.h -+++ b/tools/widl/typetree.h -@@ -67,6 +67,8 @@ type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs); - type_t *type_parameterized_interface_declare(char *name, struct namespace *namespace, type_list_t *params); - type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, type_list_t *requires); - type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params); -+type_t *type_parameterized_type_specialize_declare(type_t *type, type_list_t *params); -+type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *params); - int type_is_equal(const type_t *type1, const type_t *type2); - const char *type_get_name(const type_t *type, enum name_type name_type); - char *gen_name(void); --- -2.20.1 - diff --git a/staging/upstream-commit b/staging/upstream-commit index f431e26e..d8c21343 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -a55a37d1dae2231d8dec9f3191449f89be0b10dc +c6a3072051fb88edd3847c750c2ec852f11870f6