From b2a546c92dabee8ab1c3d5b9fecc84d99caf0e76 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek@codeweavers.com>
Date: Mon, 25 Mar 2019 14:37:09 +0100
Subject: [PATCH] server: Introduce kernel_object struct for generic
 association between server and kernel objects.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
---
 server/async.c      |  2 ++
 server/atom.c       |  1 +
 server/change.c     |  1 +
 server/clipboard.c  |  1 +
 server/completion.c |  1 +
 server/console.c    |  3 +++
 server/debugger.c   |  2 ++
 server/device.c     | 57 ++++++++++++++++++++++++++++++++++++++++++---
 server/directory.c  |  2 ++
 server/event.c      |  2 ++
 server/fd.c         |  4 ++++
 server/file.c       |  1 +
 server/handle.c     |  1 +
 server/hook.c       |  1 +
 server/mailslot.c   |  3 +++
 server/mapping.c    |  3 +++
 server/mutex.c      |  1 +
 server/named_pipe.c |  5 ++++
 server/object.c     |  1 +
 server/object.h     |  4 ++++
 server/process.c    |  3 +++
 server/queue.c      |  2 ++
 server/registry.c   |  1 +
 server/request.c    |  1 +
 server/semaphore.c  |  1 +
 server/serial.c     |  1 +
 server/signal.c     |  1 +
 server/snapshot.c   |  1 +
 server/sock.c       |  2 ++
 server/symlink.c    |  1 +
 server/thread.c     |  2 ++
 server/timer.c      |  1 +
 server/token.c      |  1 +
 server/winstation.c |  2 ++
 34 files changed, 113 insertions(+), 3 deletions(-)

diff --git a/server/async.c b/server/async.c
index cadeda3ffbd..b88dd168075 100644
--- a/server/async.c
+++ b/server/async.c
@@ -79,6 +79,7 @@ static const struct object_ops async_ops =
     no_link_name,              /* link_name */
     NULL,                      /* unlink_name */
     no_open_file,              /* open_file */
+    no_kernel_obj_list,        /* get_kernel_obj_list */
     no_close_handle,           /* close_handle */
     async_destroy              /* destroy */
 };
@@ -467,6 +468,7 @@ static const struct object_ops iosb_ops =
     no_link_name,             /* link_name */
     NULL,                     /* unlink_name */
     no_open_file,             /* open_file */
+    no_kernel_obj_list,       /* get_kernel_obj_list */
     no_close_handle,          /* close_handle */
     iosb_destroy              /* destroy */
 };
diff --git a/server/atom.c b/server/atom.c
index 3ff75407d9f..35db8e3e911 100644
--- a/server/atom.c
+++ b/server/atom.c
@@ -90,6 +90,7 @@ static const struct object_ops atom_table_ops =
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     no_close_handle,              /* close_handle */
     atom_table_destroy            /* destroy */
 };
diff --git a/server/change.c b/server/change.c
index 3dd52aa167d..eb27dae5988 100644
--- a/server/change.c
+++ b/server/change.c
@@ -172,6 +172,7 @@ static const struct object_ops dir_ops =
     no_link_name,             /* link_name */
     NULL,                     /* unlink_name */
     no_open_file,             /* open_file */
+    no_kernel_obj_list,       /* get_kernel_obj_list */
     dir_close_handle,         /* close_handle */
     dir_destroy               /* destroy */
 };
diff --git a/server/clipboard.c b/server/clipboard.c
index 162725b2eaf..e6884dd75fa 100644
--- a/server/clipboard.c
+++ b/server/clipboard.c
@@ -87,6 +87,7 @@ static const struct object_ops clipboard_ops =
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     no_close_handle,              /* close_handle */
     clipboard_destroy             /* destroy */
 };
diff --git a/server/completion.c b/server/completion.c
index 8b8983a157f..be5ffe585c3 100644
--- a/server/completion.c
+++ b/server/completion.c
@@ -75,6 +75,7 @@ static const struct object_ops completion_ops =
     directory_link_name,       /* link_name */
     default_unlink_name,       /* unlink_name */
     no_open_file,              /* open_file */
+    no_kernel_obj_list,        /* get_kernel_obj_list */
     no_close_handle,           /* close_handle */
     completion_destroy         /* destroy */
 };
diff --git a/server/console.c b/server/console.c
index e1ae086cb73..7d1fc5d2680 100644
--- a/server/console.c
+++ b/server/console.c
@@ -87,6 +87,7 @@ static const struct object_ops console_input_ops =
     no_link_name,                     /* link_name */
     NULL,                             /* unlink_name */
     no_open_file,                     /* open_file */
+    no_kernel_obj_list,               /* get_kernel_obj_list */
     no_close_handle,                  /* close_handle */
     console_input_destroy             /* destroy */
 };
@@ -121,6 +122,7 @@ static const struct object_ops console_input_events_ops =
     no_link_name,                     /* link_name */
     NULL,                             /* unlink_name */
     no_open_file,                     /* open_file */
+    no_kernel_obj_list,               /* get_kernel_obj_list */
     no_close_handle,                  /* close_handle */
     console_input_events_destroy      /* destroy */
 };
@@ -177,6 +179,7 @@ static const struct object_ops screen_buffer_ops =
     no_link_name,                     /* link_name */
     NULL,                             /* unlink_name */
     no_open_file,                     /* open_file */
+    no_kernel_obj_list,               /* get_kernel_obj_list */
     no_close_handle,                  /* close_handle */
     screen_buffer_destroy             /* destroy */
 };
diff --git a/server/debugger.c b/server/debugger.c
index 79b7e527f33..bff813a16d4 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -84,6 +84,7 @@ static const struct object_ops debug_event_ops =
     no_link_name,                  /* link_name */
     NULL,                          /* unlink_name */
     no_open_file,                  /* open_file */
+    no_kernel_obj_list,            /* get_kernel_obj_list */
     no_close_handle,               /* close_handle */
     debug_event_destroy            /* destroy */
 };
@@ -110,6 +111,7 @@ static const struct object_ops debug_ctx_ops =
     no_link_name,                  /* link_name */
     NULL,                          /* unlink_name */
     no_open_file,                  /* open_file */
+    no_kernel_obj_list,            /* get_kernel_obj_list */
     no_close_handle,               /* close_handle */
     debug_ctx_destroy              /* destroy */
 };
diff --git a/server/device.c b/server/device.c
index cae66d4f44a..3348cd56a6b 100644
--- a/server/device.c
+++ b/server/device.c
@@ -20,6 +20,7 @@
 
 #include "config.h"
 #include "wine/port.h"
+#include "wine/rbtree.h"
 
 #include <assert.h>
 #include <fcntl.h>
@@ -75,6 +76,7 @@ static const struct object_ops irp_call_ops =
     no_link_name,                     /* link_name */
     NULL,                             /* unlink_name */
     no_open_file,                     /* open_file */
+    no_kernel_obj_list,               /* get_kernel_obj_list */
     no_close_handle,                  /* close_handle */
     irp_call_destroy                  /* destroy */
 };
@@ -84,9 +86,10 @@ static const struct object_ops irp_call_ops =
 
 struct device_manager
 {
-    struct object          obj;           /* object header */
-    struct list            devices;       /* list of devices */
-    struct list            requests;      /* list of pending irps across all devices */
+    struct object          obj;            /* object header */
+    struct list            devices;        /* list of devices */
+    struct list            requests;       /* list of pending irps across all devices */
+    struct wine_rb_tree    kernel_objects; /* map of objects that have client side pointer associated */
 };
 
 static void device_manager_dump( struct object *obj, int verbose );
@@ -111,6 +114,7 @@ static const struct object_ops device_manager_ops =
     no_link_name,                     /* link_name */
     NULL,                             /* unlink_name */
     no_open_file,                     /* open_file */
+    no_kernel_obj_list,               /* get_kernel_obj_list */
     no_close_handle,                  /* close_handle */
     device_manager_destroy            /* destroy */
 };
@@ -152,6 +156,7 @@ static const struct object_ops device_ops =
     directory_link_name,              /* link_name */
     default_unlink_name,              /* unlink_name */
     device_open_file,                 /* open_file */
+    no_kernel_obj_list,               /* get_kernel_obj_list */
     no_close_handle,                  /* close_handle */
     device_destroy                    /* destroy */
 };
@@ -197,6 +202,7 @@ static const struct object_ops device_file_ops =
     no_link_name,                     /* link_name */
     NULL,                             /* unlink_name */
     no_open_file,                     /* open_file */
+    no_kernel_obj_list,               /* get_kernel_obj_list */
     device_file_close_handle,         /* close_handle */
     device_file_destroy               /* destroy */
 };
@@ -217,6 +223,26 @@ static const struct fd_ops device_file_fd_ops =
 };
 
 
+struct list *no_kernel_obj_list( struct object *obj )
+{
+    return NULL;
+}
+
+struct kernel_object
+{
+    struct device_manager  *manager;
+    client_ptr_t            user_ptr;
+    struct object          *object;
+    struct list             list_entry;
+    struct wine_rb_entry    rb_entry;
+};
+
+static int compare_kernel_object( const void *k, const struct wine_rb_entry *entry )
+{
+    struct kernel_object *ptr = WINE_RB_ENTRY_VALUE( entry, struct kernel_object, rb_entry );
+    return memcmp( k, &ptr->user_ptr, sizeof(client_ptr_t) );
+}
+
 static void irp_call_dump( struct object *obj, int verbose )
 {
     struct irp_call *irp = (struct irp_call *)obj;
@@ -608,8 +634,17 @@ static int device_manager_signaled( struct object *obj, struct wait_queue_entry
 static void device_manager_destroy( struct object *obj )
 {
     struct device_manager *manager = (struct device_manager *)obj;
+    struct kernel_object *kernel_object;
     struct list *ptr;
 
+    while (manager->kernel_objects.root)
+    {
+        kernel_object = WINE_RB_ENTRY_VALUE( manager->kernel_objects.root, struct kernel_object, rb_entry );
+        wine_rb_remove( &manager->kernel_objects, &kernel_object->rb_entry );
+        list_remove( &kernel_object->list_entry );
+        free( kernel_object );
+    }
+
     while ((ptr = list_head( &manager->devices )))
     {
         struct device *device = LIST_ENTRY( ptr, struct device, entry );
@@ -625,10 +660,26 @@ static struct device_manager *create_device_manager(void)
     {
         list_init( &manager->devices );
         list_init( &manager->requests );
+        wine_rb_init( &manager->kernel_objects, compare_kernel_object );
     }
     return manager;
 }
 
+void free_kernel_objects( struct object *obj )
+{
+    struct list *ptr, *list;
+
+    if (!(list = obj->ops->get_kernel_obj_list( obj ))) return;
+
+    while ((ptr = list_head( list )))
+    {
+        struct kernel_object *kernel_object = LIST_ENTRY( ptr, struct kernel_object, list_entry );
+        list_remove( &kernel_object->list_entry );
+        wine_rb_remove( &kernel_object->manager->kernel_objects, &kernel_object->rb_entry );
+        free( kernel_object );
+    }
+}
+
 
 /* create a device manager */
 DECL_HANDLER(create_device_manager)
diff --git a/server/directory.c b/server/directory.c
index 6aa3a55f35e..c995487f59e 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -67,6 +67,7 @@ static const struct object_ops object_type_ops =
     directory_link_name,          /* link_name */
     default_unlink_name,          /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     no_close_handle,              /* close_handle */
     no_destroy                    /* destroy */
 };
@@ -102,6 +103,7 @@ static const struct object_ops directory_ops =
     directory_link_name,          /* link_name */
     default_unlink_name,          /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     no_close_handle,              /* close_handle */
     directory_destroy             /* destroy */
 };
diff --git a/server/event.c b/server/event.c
index 750d20a6601..f5feca90e09 100644
--- a/server/event.c
+++ b/server/event.c
@@ -68,6 +68,7 @@ static const struct object_ops event_ops =
     directory_link_name,       /* link_name */
     default_unlink_name,       /* unlink_name */
     no_open_file,              /* open_file */
+    no_kernel_obj_list,        /* get_kernel_obj_list */
     no_close_handle,           /* close_handle */
     no_destroy                 /* destroy */
 };
@@ -101,6 +102,7 @@ static const struct object_ops keyed_event_ops =
     directory_link_name,         /* link_name */
     default_unlink_name,         /* unlink_name */
     no_open_file,                /* open_file */
+    no_kernel_obj_list,          /* get_kernel_obj_list */
     no_close_handle,             /* close_handle */
     no_destroy                   /* destroy */
 };
diff --git a/server/fd.c b/server/fd.c
index f2d83b4d583..5d80e218b97 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -218,6 +218,7 @@ static const struct object_ops fd_ops =
     no_link_name,             /* link_name */
     NULL,                     /* unlink_name */
     no_open_file,             /* open_file */
+    no_kernel_obj_list,       /* get_kernel_obj_list */
     no_close_handle,          /* close_handle */
     fd_destroy                /* destroy */
 };
@@ -257,6 +258,7 @@ static const struct object_ops device_ops =
     no_link_name,             /* link_name */
     NULL,                     /* unlink_name */
     no_open_file,             /* open_file */
+    no_kernel_obj_list,       /* get_kernel_obj_list */
     no_close_handle,          /* close_handle */
     device_destroy            /* destroy */
 };
@@ -295,6 +297,7 @@ static const struct object_ops inode_ops =
     no_link_name,             /* link_name */
     NULL,                     /* unlink_name */
     no_open_file,             /* open_file */
+    no_kernel_obj_list,       /* get_kernel_obj_list */
     no_close_handle,          /* close_handle */
     inode_destroy             /* destroy */
 };
@@ -335,6 +338,7 @@ static const struct object_ops file_lock_ops =
     no_link_name,               /* link_name */
     NULL,                       /* unlink_name */
     no_open_file,               /* open_file */
+    no_kernel_obj_list,         /* get_kernel_obj_list */
     no_close_handle,            /* close_handle */
     no_destroy                  /* destroy */
 };
diff --git a/server/file.c b/server/file.c
index 7ca650f9d3d..aae811e3d94 100644
--- a/server/file.c
+++ b/server/file.c
@@ -94,6 +94,7 @@ static const struct object_ops file_ops =
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
     file_open_file,               /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     fd_close_handle,              /* close_handle */
     file_destroy                  /* destroy */
 };
diff --git a/server/handle.c b/server/handle.c
index 35ab8607c85..a2a8bb5479c 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -133,6 +133,7 @@ static const struct object_ops handle_table_ops =
     no_link_name,                    /* link_name */
     NULL,                            /* unlink_name */
     no_open_file,                    /* open_file */
+    no_kernel_obj_list,              /* get_kernel_obj_list */
     no_close_handle,                 /* close_handle */
     handle_table_destroy             /* destroy */
 };
diff --git a/server/hook.c b/server/hook.c
index 3a0e4b4d1d3..ec6be582482 100644
--- a/server/hook.c
+++ b/server/hook.c
@@ -91,6 +91,7 @@ static const struct object_ops hook_table_ops =
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     no_close_handle,              /* close_handle */
     hook_table_destroy            /* destroy */
 };
diff --git a/server/mailslot.c b/server/mailslot.c
index 75a397dbabe..49e79e9acd1 100644
--- a/server/mailslot.c
+++ b/server/mailslot.c
@@ -89,6 +89,7 @@ static const struct object_ops mailslot_ops =
     mailslot_link_name,        /* link_name */
     default_unlink_name,       /* unlink_name */
     mailslot_open_file,        /* open_file */
+    no_kernel_obj_list,        /* get_kernel_obj_list */
     fd_close_handle,           /* close_handle */
     mailslot_destroy           /* destroy */
 };
@@ -145,6 +146,7 @@ static const struct object_ops mail_writer_ops =
     no_link_name,               /* link_name */
     NULL,                       /* unlink_name */
     no_open_file,               /* open_file */
+    no_kernel_obj_list,         /* get_kernel_obj_list */
     fd_close_handle,            /* close_handle */
     mail_writer_destroy         /* destroy */
 };
@@ -202,6 +204,7 @@ static const struct object_ops mailslot_device_ops =
     directory_link_name,            /* link_name */
     default_unlink_name,            /* unlink_name */
     mailslot_device_open_file,      /* open_file */
+    no_kernel_obj_list,             /* get_kernel_obj_list */
     fd_close_handle,                /* close_handle */
     mailslot_device_destroy         /* destroy */
 };
diff --git a/server/mapping.c b/server/mapping.c
index 085d7aaa304..ddc8be890f3 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -77,6 +77,7 @@ static const struct object_ops ranges_ops =
     no_link_name,              /* link_name */
     NULL,                      /* unlink_name */
     no_open_file,              /* open_file */
+    no_kernel_obj_list,        /* get_kernel_obj_list */
     no_close_handle,           /* close_handle */
     ranges_destroy             /* destroy */
 };
@@ -111,6 +112,7 @@ static const struct object_ops shared_map_ops =
     no_link_name,              /* link_name */
     NULL,                      /* unlink_name */
     no_open_file,              /* open_file */
+    no_kernel_obj_list,        /* get_kernel_obj_list */
     no_close_handle,           /* close_handle */
     shared_map_destroy         /* destroy */
 };
@@ -166,6 +168,7 @@ static const struct object_ops mapping_ops =
     directory_link_name,         /* link_name */
     default_unlink_name,         /* unlink_name */
     no_open_file,                /* open_file */
+    no_kernel_obj_list,          /* get_kernel_obj_list */
     fd_close_handle,             /* close_handle */
     mapping_destroy              /* destroy */
 };
diff --git a/server/mutex.c b/server/mutex.c
index d1887e4bc45..8a8f7248eae 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -71,6 +71,7 @@ static const struct object_ops mutex_ops =
     directory_link_name,       /* link_name */
     default_unlink_name,       /* unlink_name */
     no_open_file,              /* open_file */
+    no_kernel_obj_list,        /* get_kernel_obj_list */
     no_close_handle,           /* close_handle */
     mutex_destroy              /* destroy */
 };
diff --git a/server/named_pipe.c b/server/named_pipe.c
index a6ec8ae06a0..8e0380d060d 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -128,6 +128,7 @@ static const struct object_ops named_pipe_ops =
     named_pipe_link_name,         /* link_name */
     default_unlink_name,          /* unlink_name */
     named_pipe_open_file,         /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     no_close_handle,              /* close_handle */
     named_pipe_destroy            /* destroy */
 };
@@ -169,6 +170,7 @@ static const struct object_ops pipe_server_ops =
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     fd_close_handle,              /* close_handle */
     pipe_server_destroy           /* destroy */
 };
@@ -210,6 +212,7 @@ static const struct object_ops pipe_client_ops =
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     fd_close_handle,              /* close_handle */
     pipe_end_destroy              /* destroy */
 };
@@ -255,6 +258,7 @@ static const struct object_ops named_pipe_device_ops =
     directory_link_name,              /* link_name */
     default_unlink_name,              /* unlink_name */
     named_pipe_device_open_file,      /* open_file */
+    no_kernel_obj_list,               /* get_kernel_obj_list */
     no_close_handle,                  /* close_handle */
     named_pipe_device_destroy         /* destroy */
 };
@@ -283,6 +287,7 @@ static const struct object_ops named_pipe_device_file_ops =
     no_link_name,                            /* link_name */
     NULL,                                    /* unlink_name */
     no_open_file,                            /* open_file */
+    no_kernel_obj_list,                      /* get_kernel_obj_list */
     fd_close_handle,                         /* close_handle */
     named_pipe_device_file_destroy           /* destroy */
 };
diff --git a/server/object.c b/server/object.c
index 4455718aac3..048da504ad2 100644
--- a/server/object.c
+++ b/server/object.c
@@ -425,6 +425,7 @@ void release_object( void *ptr )
         assert( !obj->handle_count );
         /* if the refcount is 0, nobody can be in the wait queue */
         assert( list_empty( &obj->wait_queue ));
+        free_kernel_objects( obj );
         unlink_named_object( obj );
         obj->ops->destroy( obj );
         free_object( obj );
diff --git a/server/object.h b/server/object.h
index b5c50e1cee8..4a486e0d633 100644
--- a/server/object.h
+++ b/server/object.h
@@ -89,6 +89,8 @@ struct object_ops
     /* open a file object to access this object */
     struct object *(*open_file)(struct object *, unsigned int access, unsigned int sharing,
                                 unsigned int options);
+    /* return list of kernel objects */
+    struct list *(*get_kernel_obj_list)(struct object *);
     /* close a handle to this object */
     int (*close_handle)(struct object *,struct process *,obj_handle_t);
     /* destroy on refcount == 0 */
@@ -141,6 +143,7 @@ extern void *open_named_object( struct object *parent, const struct object_ops *
 extern void unlink_named_object( struct object *obj );
 extern void make_object_static( struct object *obj );
 extern struct namespace *create_namespace( unsigned int hash_size );
+extern void free_kernel_objects( struct object *obj );
 /* grab/release_object can take any pointer, but you better make sure */
 /* that the thing pointed to starts with a struct object... */
 extern struct object *grab_object( void *obj );
@@ -163,6 +166,7 @@ extern int no_link_name( struct object *obj, struct object_name *name, struct ob
 extern void default_unlink_name( struct object *obj, struct object_name *name );
 extern struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing,
                                     unsigned int options );
+extern struct list *no_kernel_obj_list( struct object *obj );
 extern int no_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
 extern void no_destroy( struct object *obj );
 #ifdef DEBUG_OBJECTS
diff --git a/server/process.c b/server/process.c
index 77bd1e74b50..473d3b1a27a 100644
--- a/server/process.c
+++ b/server/process.c
@@ -85,6 +85,7 @@ static const struct object_ops process_ops =
     no_link_name,                /* link_name */
     NULL,                        /* unlink_name */
     no_open_file,                /* open_file */
+    no_kernel_obj_list,          /* get_kernel_obj_list */
     no_close_handle,             /* close_handle */
     process_destroy              /* destroy */
 };
@@ -134,6 +135,7 @@ static const struct object_ops startup_info_ops =
     no_link_name,                  /* link_name */
     NULL,                          /* unlink_name */
     no_open_file,                  /* open_file */
+    no_kernel_obj_list,            /* get_kernel_obj_list */
     no_close_handle,               /* close_handle */
     startup_info_destroy           /* destroy */
 };
@@ -177,6 +179,7 @@ static const struct object_ops job_ops =
     directory_link_name,           /* link_name */
     default_unlink_name,           /* unlink_name */
     no_open_file,                  /* open_file */
+    no_kernel_obj_list,            /* get_kernel_obj_list */
     job_close_handle,              /* close_handle */
     job_destroy                    /* destroy */
 };
diff --git a/server/queue.c b/server/queue.c
index 2eec422c575..24239916af0 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -181,6 +181,7 @@ static const struct object_ops msg_queue_ops =
     no_link_name,              /* link_name */
     NULL,                      /* unlink_name */
     no_open_file,              /* open_file */
+    no_kernel_obj_list,        /* get_kernel_obj_list */
     no_close_handle,           /* close_handle */
     msg_queue_destroy          /* destroy */
 };
@@ -216,6 +217,7 @@ static const struct object_ops thread_input_ops =
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     no_close_handle,              /* close_handle */
     thread_input_destroy          /* destroy */
 };
diff --git a/server/registry.c b/server/registry.c
index dffa3acffd5..48a0f28c97e 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -170,6 +170,7 @@ static const struct object_ops key_ops =
     no_link_name,            /* link_name */
     NULL,                    /* unlink_name */
     no_open_file,            /* open_file */
+    no_kernel_obj_list,      /* get_kernel_obj_list */
     key_close_handle,        /* close_handle */
     key_destroy              /* destroy */
 };
diff --git a/server/request.c b/server/request.c
index c10c4e65268..d2adb08a183 100644
--- a/server/request.c
+++ b/server/request.c
@@ -107,6 +107,7 @@ static const struct object_ops master_socket_ops =
     no_link_name,                  /* link_name */
     NULL,                          /* unlink_name */
     no_open_file,                  /* open_file */
+    no_kernel_obj_list,            /* get_kernel_obj_list */
     no_close_handle,               /* close_handle */
     master_socket_destroy          /* destroy */
 };
diff --git a/server/semaphore.c b/server/semaphore.c
index 08ff1536cee..6e2415fd79a 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -68,6 +68,7 @@ static const struct object_ops semaphore_ops =
     directory_link_name,           /* link_name */
     default_unlink_name,           /* unlink_name */
     no_open_file,                  /* open_file */
+    no_kernel_obj_list,            /* get_kernel_obj_list */
     no_close_handle,               /* close_handle */
     no_destroy                     /* destroy */
 };
diff --git a/server/serial.c b/server/serial.c
index f0adf92f3a8..4292472613a 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -102,6 +102,7 @@ static const struct object_ops serial_ops =
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     fd_close_handle,              /* close_handle */
     serial_destroy                /* destroy */
 };
diff --git a/server/signal.c b/server/signal.c
index 74416fab7be..c81f6b8e989 100644
--- a/server/signal.c
+++ b/server/signal.c
@@ -77,6 +77,7 @@ static const struct object_ops handler_ops =
     no_link_name,             /* link_name */
     NULL,                     /* unlink_name */
     no_open_file,             /* open_file */
+    no_kernel_obj_list,       /* get_kernel_obj_list */
     no_close_handle,          /* close_handle */
     handler_destroy           /* destroy */
 };
diff --git a/server/snapshot.c b/server/snapshot.c
index e35588a136c..a0f2ea17a3e 100644
--- a/server/snapshot.c
+++ b/server/snapshot.c
@@ -71,6 +71,7 @@ static const struct object_ops snapshot_ops =
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     no_close_handle,              /* close_handle */
     snapshot_destroy              /* destroy */
 };
diff --git a/server/sock.c b/server/sock.c
index 284ab9ff78a..1a53ce4b091 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -154,6 +154,7 @@ static const struct object_ops sock_ops =
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     fd_close_handle,              /* close_handle */
     sock_destroy                  /* destroy */
 };
@@ -968,6 +969,7 @@ static const struct object_ops ifchange_ops =
     no_link_name,            /* link_name */
     NULL,                    /* unlink_name */
     no_open_file,            /* open_file */
+    no_kernel_obj_list,      /* get_kernel_obj_list */
     no_close_handle,         /* close_handle */
     ifchange_destroy         /* destroy */
 };
diff --git a/server/symlink.c b/server/symlink.c
index 9199bc559d7..bc75ee9a7eb 100644
--- a/server/symlink.c
+++ b/server/symlink.c
@@ -70,6 +70,7 @@ static const struct object_ops symlink_ops =
     directory_link_name,          /* link_name */
     default_unlink_name,          /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     no_close_handle,              /* close_handle */
     symlink_destroy               /* destroy */
 };
diff --git a/server/thread.c b/server/thread.c
index 4c3d9c3d165..f5f98ebef1b 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -120,6 +120,7 @@ static const struct object_ops thread_apc_ops =
     no_link_name,               /* link_name */
     NULL,                       /* unlink_name */
     no_open_file,               /* open_file */
+    no_kernel_obj_list,         /* get_kernel_obj_list */
     no_close_handle,            /* close_handle */
     thread_apc_destroy          /* destroy */
 };
@@ -152,6 +153,7 @@ static const struct object_ops thread_ops =
     no_link_name,               /* link_name */
     NULL,                       /* unlink_name */
     no_open_file,               /* open_file */
+    no_kernel_obj_list,         /* get_kernel_obj_list */
     no_close_handle,            /* close_handle */
     destroy_thread              /* destroy */
 };
diff --git a/server/timer.c b/server/timer.c
index 3a786fb4fca..9cca85569f4 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -75,6 +75,7 @@ static const struct object_ops timer_ops =
     directory_link_name,       /* link_name */
     default_unlink_name,       /* unlink_name */
     no_open_file,              /* open_file */
+    no_kernel_obj_list,        /* get_kernel_obj_list */
     no_close_handle,           /* close_handle */
     timer_destroy              /* destroy */
 };
diff --git a/server/token.c b/server/token.c
index e440d489f2d..e58e6a4fe77 100644
--- a/server/token.c
+++ b/server/token.c
@@ -156,6 +156,7 @@ static const struct object_ops token_ops =
     no_link_name,              /* link_name */
     NULL,                      /* unlink_name */
     no_open_file,              /* open_file */
+    no_kernel_obj_list,        /* get_kernel_obj_list */
     no_close_handle,           /* close_handle */
     token_destroy              /* destroy */
 };
diff --git a/server/winstation.c b/server/winstation.c
index a0be0586523..a09ca03e3b0 100644
--- a/server/winstation.c
+++ b/server/winstation.c
@@ -75,6 +75,7 @@ static const struct object_ops winstation_ops =
     directory_link_name,          /* link_name */
     default_unlink_name,          /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     winstation_close_handle,      /* close_handle */
     winstation_destroy            /* destroy */
 };
@@ -98,6 +99,7 @@ static const struct object_ops desktop_ops =
     desktop_link_name,            /* link_name */
     default_unlink_name,          /* unlink_name */
     no_open_file,                 /* open_file */
+    no_kernel_obj_list,           /* get_kernel_obj_list */
     desktop_close_handle,         /* close_handle */
     desktop_destroy               /* destroy */
 };
-- 
GitLab