From 1f1d4da5f66e00cd01a71b062ee2d1111609e971 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Wed, 17 Feb 2021 22:59:16 -0600 Subject: [PATCH] ntdll: Fill the handle attributes in System(Extended)HandleInformation. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/ntdll/tests/info.c | 24 +++++++++++++++++++----- dlls/ntdll/unix/system.c | 12 +++++++----- include/wine/server_protocol.h | 3 ++- server/handle.c | 9 ++++++--- server/protocol.def | 1 + server/trace.c | 4 ++-- 6 files changed, 37 insertions(+), 16 deletions(-) diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 419d8582dd3..85c523881ef 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -542,11 +542,14 @@ static void test_query_handle(void) ULONG SystemInformationLength = sizeof(SYSTEM_HANDLE_INFORMATION); SYSTEM_HANDLE_INFORMATION* shi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength); HANDLE EventHandle; - BOOL found; + BOOL found, ret; INT i; EventHandle = CreateEventA(NULL, FALSE, FALSE, NULL); ok( EventHandle != NULL, "CreateEventA failed %u\n", GetLastError() ); + ret = SetHandleInformation(EventHandle, HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE, + HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE); + ok(ret, "got error %u\n", GetLastError()); /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */ ReturnLength = 0xdeadbeef; @@ -581,11 +584,22 @@ static void test_query_handle(void) goto done; } - for (i = 0, found = FALSE; i < shi->Count && !found; i++) - found = (shi->Handle[i].OwnerPid == GetCurrentProcessId()) && - ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle); + found = FALSE; + for (i = 0; i < shi->Count; i++) + { + if (shi->Handle[i].OwnerPid == GetCurrentProcessId() && + (HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle) + { + ok(shi->Handle[i].HandleFlags == (OBJ_INHERIT | OBJ_PROTECT_CLOSE), + "got attributes %#x\n", shi->Handle[i].HandleFlags); + found = TRUE; + break; + } + } ok( found, "Expected to find event handle %p (pid %x) in handle list\n", EventHandle, GetCurrentProcessId() ); + ret = SetHandleInformation(EventHandle, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0); + ok(ret, "got error %u\n", GetLastError()); CloseHandle(EventHandle); ReturnLength = 0xdeadbeef; @@ -645,7 +659,7 @@ static void test_query_handle_ex(void) if (info->Handles[i].UniqueProcessId == GetCurrentProcessId() && (HANDLE)info->Handles[i].HandleValue == event) { - todo_wine ok(info->Handles[i].HandleAttributes == (OBJ_INHERIT | OBJ_PROTECT_CLOSE), + ok(info->Handles[i].HandleAttributes == (OBJ_INHERIT | OBJ_PROTECT_CLOSE), "got flags %#x\n", info->Handles[i].HandleAttributes); ok(info->Handles[i].GrantedAccess == EVENT_ALL_ACCESS, "got access %#x\n", info->Handles[i].GrantedAccess); found = TRUE; diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index e2482f91041..f4a879d8748 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -2446,7 +2446,8 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class, shi->Handle[i].OwnerPid = handle_info[i].owner; shi->Handle[i].HandleValue = handle_info[i].handle; shi->Handle[i].AccessMask = handle_info[i].access; - /* FIXME: Fill out ObjectType, HandleFlags, ObjectPointer */ + shi->Handle[i].HandleFlags = handle_info[i].attributes; + /* FIXME: Fill out ObjectType, ObjectPointer */ } } else if (ret == STATUS_BUFFER_TOO_SMALL) @@ -2493,10 +2494,11 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class, for (i = 0; i < shi->NumberOfHandles; i++) { memset( &shi->Handles[i], 0, sizeof(shi->Handles[i]) ); - shi->Handles[i].UniqueProcessId = handle_info[i].owner; - shi->Handles[i].HandleValue = handle_info[i].handle; - shi->Handles[i].GrantedAccess = handle_info[i].access; - /* FIXME: Fill out Object, HandleAttributes, ObjectTypeIndex */ + shi->Handles[i].UniqueProcessId = handle_info[i].owner; + shi->Handles[i].HandleValue = handle_info[i].handle; + shi->Handles[i].GrantedAccess = handle_info[i].access; + shi->Handles[i].HandleAttributes = handle_info[i].attributes; + /* FIXME: Fill out Object, ObjectTypeIndex */ } } else if (ret == STATUS_BUFFER_TOO_SMALL) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 277b1a1c33a..5e463fd5c9e 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4543,6 +4543,7 @@ struct handle_info process_id_t owner; obj_handle_t handle; unsigned int access; + unsigned int attributes; }; @@ -6226,7 +6227,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 682 +#define SERVER_PROTOCOL_VERSION 683 /* ### protocol_version end ### */ diff --git a/server/handle.c b/server/handle.c index ef0f595bf08..4291761ec6c 100644 --- a/server/handle.c +++ b/server/handle.c @@ -830,9 +830,12 @@ static int enum_handles( struct process *process, void *user ) } assert( info->count ); handle = info->handle++; - handle->owner = process->id; - handle->handle = index_to_handle(i); - handle->access = entry->access & ~RESERVED_ALL; + handle->owner = process->id; + handle->handle = index_to_handle(i); + handle->access = entry->access & ~RESERVED_ALL; + handle->attributes = 0; + if (entry->access & RESERVED_INHERIT) handle->attributes |= OBJ_INHERIT; + if (entry->access & RESERVED_CLOSE_PROTECT) handle->attributes |= OBJ_PROTECT_CLOSE; info->count--; } diff --git a/server/protocol.def b/server/protocol.def index fa19bb41bb4..5126a9e37e5 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3197,6 +3197,7 @@ struct handle_info process_id_t owner; obj_handle_t handle; unsigned int access; + unsigned int attributes; }; /* Return a list of all opened handles */ diff --git a/server/trace.c b/server/trace.c index 2737cb16499..9faa3d5a443 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1342,8 +1342,8 @@ static void dump_varargs_handle_infos( const char *prefix, data_size_t size ) while (size >= sizeof(*handle)) { handle = cur_data; - fprintf( stderr, "{owner=%04x,handle=%04x,access=%08x}", - handle->owner, handle->handle, handle->access ); + fprintf( stderr, "{owner=%04x,handle=%04x,access=%08x,attributes=%08x}", + handle->owner, handle->handle, handle->access, handle->attributes ); size -= sizeof(*handle); remove_data( sizeof(*handle) ); if (size) fputc( ',', stderr ); -- 2.11.4.GIT