From f4c44206896c0fdbcff7c465e631acff98bc920e 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:44:17 +0100
Subject: [PATCH] ntdll: Set object type for System(Extended)HandleInformation
 in NtQuerySystemInformation.

---
 dlls/ntdll/unix/system.c |  4 +++-
 server/directory.c       |  6 ++++++
 server/handle.c          | 10 ++++++++++
 server/object.h          |  1 +
 server/protocol.def      |  1 +
 5 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c
index 34cea04f852..7ae3f12753b 100644
--- a/dlls/ntdll/unix/system.c
+++ b/dlls/ntdll/unix/system.c
@@ -1970,7 +1970,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].ObjectType   = handle_info[i].type;
+                    /* FIXME: Fill out HandleFlags, ObjectPointer */
                 }
             }
             else if (ret == STATUS_BUFFER_TOO_SMALL)
@@ -2022,6 +2023,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
                     shi->Handle[i].UniqueProcessId = handle_info[i].owner;
                     shi->Handle[i].HandleValue     = handle_info[i].handle;
                     shi->Handle[i].GrantedAccess   = handle_info[i].access;
+                    shi->Handle[i].ObjectTypeIndex = handle_info[i].type;
                     /* FIXME: Fill out remaining fields */
                 }
             }
diff --git a/server/directory.c b/server/directory.c
index e6c1edc719a..021bc149c4d 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -247,6 +247,12 @@ struct object_type *get_object_type( const struct unicode_str *name )
     return type;
 }
 
+/* retrieve the object type index */
+unsigned int type_get_index( struct object_type *type )
+{
+    return type->index;
+}
+
 /* Global initialization */
 
 static void create_session( unsigned int id )
diff --git a/server/handle.c b/server/handle.c
index a2a8bb5479c..e40e9e95d8f 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -790,6 +790,7 @@ static int enum_handles( struct process *process, void *user )
     struct handle_table *table = process->handles;
     struct handle_entry *entry;
     struct handle_info *handle;
+    struct object_type *type;
     unsigned int i;
 
     if (!table)
@@ -808,6 +809,15 @@ static int enum_handles( struct process *process, void *user )
         handle->owner  = process->id;
         handle->handle = index_to_handle(i);
         handle->access = entry->access & ~RESERVED_ALL;
+
+        if ((type = entry->ptr->ops->get_type(entry->ptr)))
+        {
+            handle->type = type_get_index(type);
+            release_object(type);
+        }
+        else
+            handle->type = 0;
+
         info->count--;
     }
 
diff --git a/server/object.h b/server/object.h
index f3f7617394d..1517e8c98fb 100644
--- a/server/object.h
+++ b/server/object.h
@@ -262,6 +262,7 @@ static const WCHAR type_Type[] =          {'T','y','p','e'};
 static const WCHAR type_WindowStation[] = {'W','i','n','d','o','w','S','t','a','t','i','o','n'};
 
 extern void init_types(void);
+extern unsigned int type_get_index( struct object_type *type );
 
 /* symbolic link functions */
 
diff --git a/server/protocol.def b/server/protocol.def
index 2ec81bb6ad1..72f148b12e7 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3493,6 +3493,7 @@ struct handle_info
     process_id_t owner;
     obj_handle_t handle;
     unsigned int access;
+    unsigned int type;
 };
 
 /* Return a list of all opened handles */
-- 
2.27.0

