mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Rebase against c6a3072051fb88edd3847c750c2ec852f11870f6.
This commit is contained in:
parent
d0873d2c72
commit
2a9a56c4d0
@ -1,137 +0,0 @@
|
||||
From d2e98b2054a5af671fd81ded32f2cf60a062312c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
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
|
||||
|
@ -1,46 +0,0 @@
|
||||
From 48f4c131f9e8ffc091dde12437ad0772ed1c5ca6 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
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
|
||||
|
@ -1,219 +0,0 @@
|
||||
From c47977a8bbd739483589d1f01cfece435be1c100 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
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
|
||||
|
@ -1,67 +0,0 @@
|
||||
From e34d019222909281390f83149be755a4145024c4 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
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
|
||||
|
@ -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 <pgofman@codeweavers.com>
|
||||
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
|
||||
|
||||
|
@ -51,7 +51,7 @@ usage()
|
||||
# Get the upstream commit sha
|
||||
upstream_commit()
|
||||
{
|
||||
echo "a55a37d1dae2231d8dec9f3191449f89be0b10dc"
|
||||
echo "c6a3072051fb88edd3847c750c2ec852f11870f6"
|
||||
}
|
||||
|
||||
# Show version information
|
||||
|
@ -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 <dmitry@baikal.ru>
|
||||
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
|
||||
|
||||
|
@ -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 <dmitry@baikal.ru>
|
||||
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
|
||||
|
||||
|
@ -1,529 +0,0 @@
|
||||
From 5ec925e389c8b5403173aaa81940dbc63cd4b7ed Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
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<Windows.Media.SpeechSynthesis.VoiceInformation*>;
|
||||
+ interface Windows.Foundation.Collections.IIterable<Windows.Media.SpeechSynthesis.VoiceInformation*>;
|
||||
+ interface Windows.Foundation.Collections.IVectorView<Windows.Media.SpeechSynthesis.VoiceInformation*>;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
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<VoiceInformation*>** 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 <typelib> library_start librarydef
|
||||
%type <statement> statement typedef pragma_warning
|
||||
%type <stmt_list> gbl_statements imp_statements int_statements
|
||||
+%type <stmt_list> decl_block decl_statements
|
||||
+%type <stmt_list> imp_decl_block imp_decl_statements
|
||||
%type <warning_list> warnings
|
||||
%type <num> allocate_option_list allocate_option
|
||||
%type <namespace> 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
|
||||
|
@ -1 +1 @@
|
||||
a55a37d1dae2231d8dec9f3191449f89be0b10dc
|
||||
c6a3072051fb88edd3847c750c2ec852f11870f6
|
||||
|
Loading…
Reference in New Issue
Block a user