Rebase against 0a49202109e29bd18daaf746cb9493e385511e13.

This commit is contained in:
Zebediah Figura 2020-09-23 18:52:01 -05:00
parent 5087d8a8d9
commit 831d2d8b52
8 changed files with 42 additions and 523 deletions

View File

@ -1,334 +0,0 @@
From 1b222275e7faf71ae1e5c94e297004055ec6f82f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 4 Aug 2017 02:33:14 +0200
Subject: [PATCH] ntdll: Implement NtFilterToken.
---
dlls/ntdll/ntdll.spec | 2 +-
dlls/ntdll/unix/security.c | 64 +++++++++++++++++++++++++++++
include/winnt.h | 5 +++
include/winternl.h | 1 +
server/named_pipe.c | 2 +-
server/process.c | 2 +-
server/protocol.def | 10 +++++
server/security.h | 4 +-
server/token.c | 84 +++++++++++++++++++++++++++++++++++++-
9 files changed, 168 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index a3bc57716da..f604c8a3c35 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -208,7 +208,7 @@
# @ stub NtEnumerateSystemEnvironmentValuesEx
@ stdcall -syscall NtEnumerateValueKey(long long long ptr long ptr)
@ stub NtExtendSection
-# @ stub NtFilterToken
+@ stdcall -syscall NtFilterToken(long long ptr ptr ptr ptr)
@ stdcall -syscall NtFindAtom(ptr long ptr)
@ stdcall -syscall NtFlushBuffersFile(long ptr)
@ stdcall -syscall NtFlushInstructionCache(long ptr long)
diff --git a/dlls/ntdll/unix/security.c b/dlls/ntdll/unix/security.c
index daecc5e0591..d063d43d6d4 100644
--- a/dlls/ntdll/unix/security.c
+++ b/dlls/ntdll/unix/security.c
@@ -604,6 +604,70 @@ NTSTATUS WINAPI NtAdjustPrivilegesToken( HANDLE token, BOOLEAN disable, TOKEN_PR
}
+/***********************************************************************
+ * NtFilterToken (NTDLL.@)
+ */
+NTSTATUS WINAPI NtFilterToken( HANDLE token, ULONG flags, TOKEN_GROUPS *disable_sids,
+ TOKEN_PRIVILEGES *privileges, TOKEN_GROUPS *restrict_sids,
+ HANDLE *new_token )
+{
+ data_size_t privileges_len = 0;
+ data_size_t sids_len = 0;
+ SID *sids = NULL;
+ NTSTATUS status;
+
+ TRACE( "(%p, 0x%08x, %p, %p, %p, %p)\n", token, flags, disable_sids, privileges,
+ restrict_sids, new_token );
+
+ if (flags)
+ FIXME( "flags %x unsupported\n", flags );
+
+ if (restrict_sids)
+ FIXME( "support for restricting sids not yet implemented\n" );
+
+ if (privileges)
+ privileges_len = privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
+
+ if (disable_sids)
+ {
+ DWORD len, i;
+ BYTE *tmp;
+
+ for (i = 0; i < disable_sids->GroupCount; i++)
+ {
+ SID *sid = disable_sids->Groups[i].Sid;
+ sids_len += offsetof( SID, SubAuthority[sid->SubAuthorityCount] );
+ }
+
+ sids = malloc( sids_len );
+ if (!sids) return STATUS_NO_MEMORY;
+
+ for (i = 0, tmp = (BYTE *)sids; i < disable_sids->GroupCount; i++, tmp += len)
+ {
+ SID *sid = disable_sids->Groups[i].Sid;
+ len = offsetof( SID, SubAuthority[sid->SubAuthorityCount] );
+ memcpy( tmp, disable_sids->Groups[i].Sid, len );
+ }
+ }
+
+ SERVER_START_REQ( filter_token )
+ {
+ req->handle = wine_server_obj_handle( token );
+ req->flags = flags;
+ req->privileges_size = privileges_len;
+ wine_server_add_data( req, privileges->Privileges, privileges_len );
+ wine_server_add_data( req, sids, sids_len );
+ status = wine_server_call( req );
+ if (!status) *new_token = wine_server_ptr_handle( reply->new_handle );
+ }
+ SERVER_END_REQ;
+
+ free( sids );
+ return status;
+}
+
+
+
/***********************************************************************
* NtPrivilegeCheck (NTDLL.@)
*/
diff --git a/include/winnt.h b/include/winnt.h
index e1cf78420a6..da17fe3e330 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -4221,6 +4221,11 @@ typedef enum _TOKEN_INFORMATION_CLASS {
TOKEN_ADJUST_SESSIONID | \
TOKEN_ADJUST_DEFAULT )
+#define DISABLE_MAX_PRIVILEGE 0x1
+#define SANDBOX_INERT 0x2
+#define LUA_TOKEN 0x4
+#define WRITE_RESTRICTED 0x8
+
#ifndef _SECURITY_DEFINED
#define _SECURITY_DEFINED
diff --git a/include/winternl.h b/include/winternl.h
index b3fbb90feff..4687a410ca4 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2749,6 +2749,7 @@ NTSYSAPI NTSTATUS WINAPI NtDuplicateToken(HANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES
NTSYSAPI NTSTATUS WINAPI NtEnumerateKey(HANDLE,ULONG,KEY_INFORMATION_CLASS,void *,DWORD,DWORD *);
NTSYSAPI NTSTATUS WINAPI NtEnumerateValueKey(HANDLE,ULONG,KEY_VALUE_INFORMATION_CLASS,PVOID,ULONG,PULONG);
NTSYSAPI NTSTATUS WINAPI NtExtendSection(HANDLE,PLARGE_INTEGER);
+NTSYSAPI NTSTATUS WINAPI NtFilterToken(HANDLE,ULONG,TOKEN_GROUPS*,TOKEN_PRIVILEGES*,TOKEN_GROUPS*,HANDLE*);
NTSYSAPI NTSTATUS WINAPI NtFindAtom(const WCHAR*,ULONG,RTL_ATOM*);
NTSYSAPI NTSTATUS WINAPI NtFlushBuffersFile(HANDLE,IO_STATUS_BLOCK*);
NTSYSAPI NTSTATUS WINAPI NtFlushInstructionCache(HANDLE,LPCVOID,SIZE_T);
diff --git a/server/named_pipe.c b/server/named_pipe.c
index b259abb8de4..4cd4d7dc4a8 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -1142,7 +1142,7 @@ static int pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *as
if (current->process->token) /* FIXME: use the client token */
{
struct token *token;
- if (!(token = token_duplicate( current->process->token, 0, SecurityImpersonation, NULL )))
+ if (!(token = token_duplicate( current->process->token, 0, SecurityImpersonation, NULL, NULL, 0, NULL, 0 )))
return 0;
if (current->token) release_object( current->token );
current->token = token;
diff --git a/server/process.c b/server/process.c
index 5e587b28cbe..406167e825b 100644
--- a/server/process.c
+++ b/server/process.c
@@ -577,7 +577,7 @@ struct process *create_process( int fd, struct process *parent, int inherit_all,
: alloc_handle_table( process, 0 );
/* Note: for security reasons, starting a new process does not attempt
* to use the current impersonation token for the new process */
- process->token = token_duplicate( parent->token, TRUE, 0, NULL );
+ process->token = token_duplicate( parent->token, TRUE, 0, NULL, NULL, 0, NULL, 0 );
process->affinity = parent->affinity;
}
if (!process->handles || !process->token) goto error;
diff --git a/server/protocol.def b/server/protocol.def
index a121c371c19..ee07b1eca14 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3263,6 +3263,16 @@ enum caret_state
obj_handle_t new_handle; /* duplicated handle */
@END
+@REQ(filter_token)
+ obj_handle_t handle; /* handle to the token to duplicate */
+ unsigned int flags; /* flags */
+ data_size_t privileges_size; /* size of privileges */
+ VARARG(privileges,LUID_AND_ATTRIBUTES,privileges_size); /* privileges to remove from new token */
+ VARARG(disable_sids,SID); /* array of groups to remove from new token */
+@REPLY
+ obj_handle_t new_handle; /* filtered handle */
+@END
+
@REQ(access_check)
obj_handle_t handle; /* handle to the token */
unsigned int desired_access; /* desired access to the object */
diff --git a/server/security.h b/server/security.h
index 606dbb2ab2c..6c337143c3d 100644
--- a/server/security.h
+++ b/server/security.h
@@ -56,7 +56,9 @@ extern const PSID security_high_label_sid;
extern struct token *token_create_admin(void);
extern int token_assign_label( struct token *token, PSID label );
extern struct token *token_duplicate( struct token *src_token, unsigned primary,
- int impersonation_level, const struct security_descriptor *sd );
+ int impersonation_level, const struct security_descriptor *sd,
+ const LUID_AND_ATTRIBUTES *filter_privileges, unsigned int priv_count,
+ const SID *filter_groups, unsigned int group_count );
extern int token_check_privileges( struct token *token, int all_required,
const LUID_AND_ATTRIBUTES *reqprivs,
unsigned int count, LUID_AND_ATTRIBUTES *usedprivs);
diff --git a/server/token.c b/server/token.c
index 2fa95e17aaf..38a4c203d54 100644
--- a/server/token.c
+++ b/server/token.c
@@ -285,6 +285,19 @@ static int acl_is_valid( const ACL *acl, data_size_t size )
return TRUE;
}
+static unsigned int get_sid_count( const SID *sid, data_size_t size )
+{
+ unsigned int count;
+
+ for (count = 0; size >= sizeof(SID) && security_sid_len( sid ) <= size; count++)
+ {
+ size -= security_sid_len( sid );
+ sid = (const SID *)((char *)sid + security_sid_len( sid ));
+ }
+
+ return count;
+}
+
/* checks whether all members of a security descriptor fit inside the size
* of memory specified */
int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
@@ -626,8 +639,36 @@ static struct token *create_token( unsigned primary, const SID *user,
return token;
}
+static int filter_group( struct group *group, const SID *filter, unsigned int count )
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (security_equal_sid( &group->sid, filter )) return 1;
+ filter = (const SID *)((char *)filter + security_sid_len( filter ));
+ }
+
+ return 0;
+}
+
+static int filter_privilege( struct privilege *privilege, const LUID_AND_ATTRIBUTES *filter, unsigned int count )
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (!memcmp( &privilege->luid, &filter[i].Luid, sizeof(LUID) ))
+ return 1;
+ }
+
+ return 0;
+}
+
struct token *token_duplicate( struct token *src_token, unsigned primary,
- int impersonation_level, const struct security_descriptor *sd )
+ int impersonation_level, const struct security_descriptor *sd,
+ const LUID_AND_ATTRIBUTES *filter_privileges, unsigned int priv_count,
+ const SID *filter_groups, unsigned int group_count)
{
const luid_t *modified_id =
primary || (impersonation_level == src_token->impersonation_level) ?
@@ -663,6 +704,12 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
return NULL;
}
memcpy( newgroup, group, size );
+ if (filter_group( group, filter_groups, group_count ))
+ {
+ newgroup->enabled = 0;
+ newgroup->def = 0;
+ newgroup->deny_only = 1;
+ }
list_add_tail( &token->groups, &newgroup->entry );
if (src_token->primary_group == &group->sid)
{
@@ -674,11 +721,14 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
/* copy privileges */
LIST_FOR_EACH_ENTRY( privilege, &src_token->privileges, struct privilege, entry )
+ {
+ if (filter_privilege( privilege, filter_privileges, priv_count )) continue;
if (!privilege_add( token, &privilege->luid, privilege->enabled ))
{
release_object( token );
return NULL;
}
+ }
if (sd) default_set_sd( &token->obj, sd, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION );
@@ -1311,7 +1361,7 @@ DECL_HANDLER(duplicate_token)
TOKEN_DUPLICATE,
&token_ops )))
{
- struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level, sd );
+ struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level, sd, NULL, 0, NULL, 0 );
if (token)
{
reply->new_handle = alloc_handle_no_access_check( current->process, token, req->access, objattr->attributes );
@@ -1321,6 +1371,36 @@ DECL_HANDLER(duplicate_token)
}
}
+/* creates a restricted version of a token */
+DECL_HANDLER(filter_token)
+{
+ struct token *src_token;
+
+ if ((src_token = (struct token *)get_handle_obj( current->process, req->handle,
+ TOKEN_DUPLICATE,
+ &token_ops )))
+ {
+ const LUID_AND_ATTRIBUTES *filter_privileges = get_req_data();
+ unsigned int priv_count, group_count;
+ const SID *filter_groups;
+ struct token *token;
+
+ priv_count = min( req->privileges_size, get_req_data_size() ) / sizeof(LUID_AND_ATTRIBUTES);
+ filter_groups = (const SID *)((char *)filter_privileges + priv_count * sizeof(LUID_AND_ATTRIBUTES));
+ group_count = get_sid_count( filter_groups, get_req_data_size() - priv_count * sizeof(LUID_AND_ATTRIBUTES) );
+
+ token = token_duplicate( src_token, src_token->primary, src_token->impersonation_level, NULL,
+ filter_privileges, priv_count, filter_groups, group_count );
+ if (token)
+ {
+ unsigned int access = get_handle_access( current->process, req->handle );
+ reply->new_handle = alloc_handle_no_access_check( current->process, token, access, 0 );
+ release_object( token );
+ }
+ release_object( src_token );
+ }
+}
+
/* checks the specified privileges are held by the token */
DECL_HANDLER(check_token_privileges)
{
--
2.27.0

View File

@ -1,132 +0,0 @@
From 3c1f5962482e7acf531f57f49d923d9c4e5278b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 4 Aug 2017 02:51:57 +0200
Subject: [PATCH] advapi32: Implement CreateRestrictedToken.
---
dlls/kernelbase/security.c | 103 ++++++++++++++++++++++++++++++-------
1 file changed, 84 insertions(+), 19 deletions(-)
diff --git a/dlls/kernelbase/security.c b/dlls/kernelbase/security.c
index 2e75e81ed77..97f6ee6a2fd 100644
--- a/dlls/kernelbase/security.c
+++ b/dlls/kernelbase/security.c
@@ -592,31 +592,96 @@ exit:
return ret;
}
+static BOOL allocate_groups(TOKEN_GROUPS **groups_ret, SID_AND_ATTRIBUTES *sids, DWORD count)
+{
+ TOKEN_GROUPS *groups;
+ DWORD i;
+
+ if (!count)
+ {
+ *groups_ret = NULL;
+ return TRUE;
+ }
+
+ groups = (TOKEN_GROUPS *)heap_alloc(FIELD_OFFSET(TOKEN_GROUPS, Groups) +
+ count * sizeof(SID_AND_ATTRIBUTES));
+ if (!groups)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ groups->GroupCount = count;
+ for (i = 0; i < count; i++)
+ groups->Groups[i] = sids[i];
+
+ *groups_ret = groups;
+ return TRUE;
+}
+
+static BOOL allocate_privileges(TOKEN_PRIVILEGES **privileges_ret, LUID_AND_ATTRIBUTES *privs, DWORD count)
+{
+ TOKEN_PRIVILEGES *privileges;
+ DWORD i;
+
+ if (!count)
+ {
+ *privileges_ret = NULL;
+ return TRUE;
+ }
+
+ privileges = (TOKEN_PRIVILEGES *)heap_alloc(FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges) +
+ count * sizeof(LUID_AND_ATTRIBUTES));
+ if (!privileges)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ privileges->PrivilegeCount = count;
+ for (i = 0; i < count; i++)
+ privileges->Privileges[i] = privs[i];
+
+ *privileges_ret = privileges;
+ return TRUE;
+}
+
/*************************************************************************
* CreateRestrictedToken (kernelbase.@)
*/
-BOOL WINAPI CreateRestrictedToken( HANDLE token, DWORD flags,
- DWORD disable_count, PSID_AND_ATTRIBUTES disable_sids,
- DWORD delete_count, PLUID_AND_ATTRIBUTES delete_privs,
- DWORD restrict_count, PSID_AND_ATTRIBUTES restrict_sids, PHANDLE ret )
+BOOL WINAPI CreateRestrictedToken( HANDLE baseToken, DWORD flags,
+ DWORD nDisableSids, PSID_AND_ATTRIBUTES disableSids,
+ DWORD nDeletePrivs, PLUID_AND_ATTRIBUTES deletePrivs,
+ DWORD nRestrictSids, PSID_AND_ATTRIBUTES restrictSids, PHANDLE newToken )
{
- TOKEN_TYPE type;
- SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous;
- DWORD size;
+ TOKEN_PRIVILEGES *delete_privs = NULL;
+ TOKEN_GROUPS *disable_groups = NULL;
+ TOKEN_GROUPS *restrict_sids = NULL;
+ BOOL ret = FALSE;
- FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
- token, flags, disable_count, disable_sids, delete_count, delete_privs,
- restrict_count, restrict_sids, ret );
+ TRACE("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p)\n",
+ baseToken, flags, nDisableSids, disableSids,
+ nDeletePrivs, deletePrivs,
+ nRestrictSids, restrictSids,
+ newToken);
+
+ if (!allocate_groups(&disable_groups, disableSids, nDisableSids))
+ goto done;
+
+ if (!allocate_privileges(&delete_privs, deletePrivs, nDeletePrivs))
+ goto done;
+
+ if (!allocate_groups(&restrict_sids, restrictSids, nRestrictSids))
+ goto done;
+
+ ret = set_ntstatus(NtFilterToken(baseToken, flags, disable_groups, delete_privs, restrict_sids, newToken));
+
+done:
+ heap_free(disable_groups);
+ heap_free(delete_privs);
+ heap_free(restrict_sids);
+ return ret;
- size = sizeof(type);
- if (!GetTokenInformation( token, TokenType, &type, size, &size )) return FALSE;
- if (type == TokenImpersonation)
- {
- size = sizeof(level);
- if (!GetTokenInformation( token, TokenImpersonationLevel, &level, size, &size ))
- return FALSE;
- }
- return DuplicateTokenEx( token, MAXIMUM_ALLOWED, NULL, level, type, ret );
}
/******************************************************************************
--
2.20.1

View File

@ -1 +0,0 @@
Fixes: [25834] Implement advapi32.CreateRestrictedToken

View File

@ -1,6 +1,5 @@
Fixes: [40613] Basic implementation for token integrity levels and UAC handling
Fixes: [39262] Run explorer.exe as unevaluated process
Depends: advapi32-CreateRestrictedToken
Depends: Staging
# Broken due to ntdll.so <- ntdll.dll imports. This isn't particularly difficult
# to fix, but it was already broken for some more obscure reason, and the whole

View File

@ -85,7 +85,6 @@ patch_enable_all ()
enable_Compiler_Warnings="$1"
enable_Pipelight="$1"
enable_Staging="$1"
enable_advapi32_CreateRestrictedToken="$1"
enable_advapi32_LsaLookupPrivilegeName="$1"
enable_api_ms_win_Stub_DLLs="$1"
enable_atl_AtlAxDialogBox="$1"
@ -347,9 +346,6 @@ patch_enable ()
Staging)
enable_Staging="$2"
;;
advapi32-CreateRestrictedToken)
enable_advapi32_CreateRestrictedToken="$2"
;;
advapi32-LsaLookupPrivilegeName)
enable_advapi32_LsaLookupPrivilegeName="$2"
;;
@ -1786,20 +1782,6 @@ if test "$enable_Staging" -eq 1; then
patch_apply Staging/0002-winelib-Append-Staging-at-the-end-of-the-version-s.patch
fi
# Patchset advapi32-CreateRestrictedToken
# |
# | This patchset fixes the following Wine bugs:
# | * [#25834] Implement advapi32.CreateRestrictedToken
# |
# | Modified files:
# | * dlls/kernelbase/security.c, dlls/ntdll/ntdll.spec, dlls/ntdll/unix/security.c, include/winnt.h, include/winternl.h,
# | server/named_pipe.c, server/process.c, server/protocol.def, server/security.h, server/token.c
# |
if test "$enable_advapi32_CreateRestrictedToken" -eq 1; then
patch_apply advapi32-CreateRestrictedToken/0001-ntdll-Implement-NtFilterToken.patch
patch_apply advapi32-CreateRestrictedToken/0002-advapi32-Implement-CreateRestrictedToken.patch
fi
# Patchset advapi32-LsaLookupPrivilegeName
# |
# | Modified files:

View File

@ -1,4 +1,4 @@
From 33767942e97c0c4a32c1e30dd347f1a69ec5707e Mon Sep 17 00:00:00 2001
From fb47d0b55447f5ec93fb5091fc318c92651f0b40 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 02:12:37 +0100
Subject: [PATCH] ntdll: Implement ObjectTypesInformation in NtQueryObject.
@ -7,12 +7,12 @@ Subject: [PATCH] ntdll: Implement ObjectTypesInformation in NtQueryObject.
dlls/ntdll/tests/om.c | 57 ++++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/unix/file.c | 53 +++++++++++++++++++++++++++++++++++++++
include/winternl.h | 30 ++++++++++++++++++++--
server/directory.c | 19 +++++++++++++-
server/directory.c | 23 +++++++++++++++++
server/protocol.def | 9 +++++++
5 files changed, 165 insertions(+), 3 deletions(-)
5 files changed, 170 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index fba64b8f0d6..e38e4d633b6 100644
index d3b932bec1d..e5a123447e2 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -78,6 +78,21 @@ static void (WINAPI *pRtlWakeAddressSingle)( const void * );
@ -37,7 +37,7 @@ index fba64b8f0d6..e38e4d633b6 100644
static void test_case_sensitive (void)
{
NTSTATUS status;
@@ -1495,6 +1510,47 @@ static void test_query_object(void)
@@ -1493,6 +1508,47 @@ static void test_query_object(void)
pNtClose(handle);
}
@ -85,7 +85,7 @@ index fba64b8f0d6..e38e4d633b6 100644
static void test_type_mismatch(void)
{
HANDLE h;
@@ -2092,6 +2148,7 @@ START_TEST(om)
@@ -2090,6 +2146,7 @@ START_TEST(om)
test_directory();
test_symboliclink();
test_query_object();
@ -94,10 +94,10 @@ index fba64b8f0d6..e38e4d633b6 100644
test_event();
test_mutant();
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 1800cc1f21d..a377ce7bd7b 100644
index afb552be098..e18daaea5ca 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -132,6 +132,8 @@
@@ -130,6 +130,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(file);
WINE_DECLARE_DEBUG_CHANNEL(winediag);
@ -106,7 +106,7 @@ index 1800cc1f21d..a377ce7bd7b 100644
#define MAX_DOS_DRIVES 26
#define FILE_WRITE_TO_END_OF_FILE ((LONGLONG)-1)
@@ -7438,6 +7440,57 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
@@ -6593,6 +6595,57 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
break;
}
@ -165,10 +165,10 @@ index 1800cc1f21d..a377ce7bd7b 100644
{
OBJECT_DATA_INFORMATION* p = ptr;
diff --git a/include/winternl.h b/include/winternl.h
index ac1e0880d59..8a3bdd2b95c 100644
index 9b628474655..2944e03afc0 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1116,7 +1116,7 @@ typedef enum _OBJECT_INFORMATION_CLASS {
@@ -1115,7 +1115,7 @@ typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
@ -177,7 +177,7 @@ index ac1e0880d59..8a3bdd2b95c 100644
ObjectDataInformation
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
@@ -1576,9 +1576,35 @@ typedef struct _OBJECT_NAME_INFORMATION {
@@ -1554,9 +1554,35 @@ typedef struct _OBJECT_NAME_INFORMATION {
typedef struct __OBJECT_TYPE_INFORMATION {
UNICODE_STRING TypeName;
@ -215,7 +215,7 @@ index ac1e0880d59..8a3bdd2b95c 100644
#ifdef __WINESRC__
DWORD_PTR ExitStatus;
diff --git a/server/directory.c b/server/directory.c
index b735602a805..d89da8b169b 100644
index 4d6978f61af..82f02ddeb2e 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -73,6 +73,8 @@ static const struct object_ops object_type_ops =
@ -227,17 +227,22 @@ index b735602a805..d89da8b169b 100644
struct directory
{
@@ -238,7 +240,8 @@ struct object_type *get_object_type( const struct unicode_str *name )
{
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
- grab_object( type );
+ assert( object_type_count < sizeof(object_type_list)/sizeof(object_type_list[0]) );
@@ -236,7 +238,14 @@ struct object_type *get_object_type( const struct unicode_str *name )
if ((type = create_named_object( &dir_objtype->obj, &object_type_ops, name,
OBJ_OPENIF | OBJ_PERMANENT, NULL )))
+ {
+ if (get_error() != STATUS_OBJECT_NAME_EXISTS)
+ {
+ assert( object_type_count < ARRAY_SIZE(object_type_list) );
+ object_type_list[ object_type_count++ ] = (struct object_type *)grab_object( type );
make_object_static( &type->obj );
}
+ }
clear_error();
@@ -553,3 +556,17 @@ DECL_HANDLER(get_object_type)
+ }
return type;
}
@@ -532,3 +541,17 @@ DECL_HANDLER(get_object_type)
}
release_object( obj );
}
@ -256,10 +261,10 @@ index b735602a805..d89da8b169b 100644
+ else set_error( STATUS_NO_MORE_ENTRIES );
+}
diff --git a/server/protocol.def b/server/protocol.def
index ab5efef36e4..ade5e85d10b 100644
index 85af5f0061c..9bc4ba12042 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3408,6 +3408,15 @@ struct handle_info
@@ -3339,6 +3339,15 @@ struct handle_info
@END
@ -276,5 +281,5 @@ index ab5efef36e4..ade5e85d10b 100644
@REQ(get_token_impersonation_level)
obj_handle_t handle; /* handle to the object */
--
2.27.0
2.28.0

View File

@ -1,4 +1,4 @@
From 574a79c56964a86181cb721b5e7e4f672455027e Mon Sep 17 00:00:00 2001
From 64928073fc2e463fa9f637a9a1bcddfaeb5a55c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 17:41:11 +0100
Subject: [PATCH] ntdll: Set TypeIndex for ObjectTypeInformation in
@ -11,10 +11,10 @@ Subject: [PATCH] ntdll: Set TypeIndex for ObjectTypeInformation in
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 708fe842020..4544df55d16 100644
index e18daaea5ca..ece09c12f77 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -6460,6 +6460,10 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
@@ -6589,6 +6589,10 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
p->TypeName.Buffer[res / sizeof(WCHAR)] = 0;
if (used_len) *used_len = sizeof(*p) + p->TypeName.MaximumLength;
}
@ -26,7 +26,7 @@ index 708fe842020..4544df55d16 100644
}
SERVER_END_REQ;
diff --git a/server/directory.c b/server/directory.c
index 0d5a320690e..1bc97fb2682 100644
index 65357e7f2e3..c752a652d49 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -44,6 +44,7 @@
@ -37,17 +37,17 @@ index 0d5a320690e..1bc97fb2682 100644
};
static void object_type_dump( struct object *obj, int verbose );
@@ -237,7 +238,8 @@ struct object_type *get_object_type( const struct unicode_str *name )
@@ -240,7 +241,8 @@ struct object_type *get_object_type( const struct unicode_str *name )
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
assert( object_type_count < sizeof(object_type_list)/sizeof(object_type_list[0]) );
assert( object_type_count < ARRAY_SIZE(object_type_list) );
- object_type_list[ object_type_count++ ] = (struct object_type *)grab_object( type );
+ type->index = object_type_count++;
+ object_type_list[ type->index ] = (struct object_type *)grab_object( type );
make_object_static( &type->obj );
}
clear_error();
@@ -560,6 +562,7 @@ DECL_HANDLER(get_object_type)
}
@@ -535,6 +537,7 @@ DECL_HANDLER(get_object_type)
{
if ((name = get_object_name( &type->obj, &reply->total )))
set_reply_data( name, min( reply->total, get_reply_max_size() ) );
@ -56,10 +56,10 @@ index 0d5a320690e..1bc97fb2682 100644
}
release_object( obj );
diff --git a/server/protocol.def b/server/protocol.def
index def84b35967..3406a056688 100644
index 9bc4ba12042..b52321ed519 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3528,6 +3528,7 @@ struct handle_info
@@ -3334,6 +3334,7 @@ struct handle_info
@REQ(get_object_type)
obj_handle_t handle; /* handle to the object */
@REPLY
@ -68,5 +68,5 @@ index def84b35967..3406a056688 100644
VARARG(type,unicode_str); /* type name */
@END
--
2.27.0
2.28.0

View File

@ -1 +1 @@
1a7b256f7c69c50c2a216317e03f9caeb268d0af
0a49202109e29bd18daaf746cb9493e385511e13