Jacek Caban : server: Notify client about freed object so that it may free associated kernel object.

Alexandre Julliard julliard at winehq.org
Tue Mar 26 16:43:14 CDT 2019


Module: wine
Branch: master
Commit: a5c2f043e688ca1dde9c272f92e0b0d993879570
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a5c2f043e688ca1dde9c272f92e0b0d993879570

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Mar 25 14:38:30 2019 +0100

server: Notify client about freed object so that it may free associated kernel object.

Long term, we may consider making interface between server and device
manager more generic so that it could be used for messages other than IRPs.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntoskrnl.exe/ntoskrnl.c   | 14 +++++++++++++-
 include/wine/server_protocol.h |  6 ++++++
 server/device.c                | 15 +++++++++++++++
 server/protocol.def            |  6 ++++++
 4 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 14e85e6..1a4cc74 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -833,6 +833,18 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG
     return STATUS_SUCCESS;
 }
 
+/* This is not a real IRP_MJ_CLEANUP dispatcher. We use it to notify client that server
+ * object associated with kernel object is freed so that we may free it on client side
+ * as well. */
+static NTSTATUS dispatch_cleanup( const irp_params_t *params, void *in_buff, ULONG in_size,
+                                  ULONG out_size, HANDLE irp_handle )
+{
+    void *obj = wine_server_get_ptr( params->cleanup.obj );
+    TRACE( "freeing %p object\n", obj );
+    free_kernel_object( obj );
+    return STATUS_SUCCESS;
+}
+
 typedef NTSTATUS (*dispatch_func)( const irp_params_t *params, void *in_buff, ULONG in_size,
                                    ULONG out_size, HANDLE irp_handle );
 
@@ -856,7 +868,7 @@ static const dispatch_func dispatch_funcs[IRP_MJ_MAXIMUM_FUNCTION + 1] =
     NULL,              /* IRP_MJ_INTERNAL_DEVICE_CONTROL */
     NULL,              /* IRP_MJ_SHUTDOWN */
     NULL,              /* IRP_MJ_LOCK_CONTROL */
-    NULL,              /* IRP_MJ_CLEANUP */
+    dispatch_cleanup,  /* IRP_MJ_CLEANUP */
     NULL,              /* IRP_MJ_CREATE_MAILSLOT */
     NULL,              /* IRP_MJ_QUERY_SECURITY */
     NULL,              /* IRP_MJ_SET_SECURITY */
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 54a5791..cd50894 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -683,6 +683,12 @@ typedef union
         ioctl_code_t     code;
         client_ptr_t     file;
     } ioctl;
+    struct
+    {
+        unsigned int     major;
+        int              __pad;
+        client_ptr_t     obj;
+    } cleanup;
 } irp_params_t;
 
 
diff --git a/server/device.c b/server/device.c
index 9eec374..e9cf43f 100644
--- a/server/device.c
+++ b/server/device.c
@@ -739,7 +739,22 @@ void free_kernel_objects( struct object *obj )
     while ((ptr = list_head( list )))
     {
         struct kernel_object *kernel_object = LIST_ENTRY( ptr, struct kernel_object, list_entry );
+        struct irp_call *irp;
+        irp_params_t params;
+
         assert( !kernel_object->owned );
+
+        /* abuse IRP_MJ_CLEANUP to request client to free no longer valid kernel object */
+        memset( &params, 0, sizeof(params) );
+        params.cleanup.major = IRP_MJ_CLEANUP;
+        params.cleanup.obj   = kernel_object->user_ptr;
+
+        if ((irp = create_irp( NULL, &params, NULL )))
+        {
+            add_irp_to_queue( kernel_object->manager, irp, NULL );
+            release_object( irp );
+        }
+
         list_remove( &kernel_object->list_entry );
         wine_rb_remove( &kernel_object->manager->kernel_objects, &kernel_object->rb_entry );
         free( kernel_object );
diff --git a/server/protocol.def b/server/protocol.def
index 3993ddd..f889e3b 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -699,6 +699,12 @@ typedef union
         ioctl_code_t     code;      /* ioctl code */
         client_ptr_t     file;      /* opaque ptr for the file object */
     } ioctl;
+    struct
+    {
+        unsigned int     major;     /* IRP_MJ_DEVICE_CLEANUP */
+        int              __pad;
+        client_ptr_t     obj;       /* opaque ptr for the freed object */
+    } cleanup;
 } irp_params_t;
 
 /* information about a PE image mapping, roughly equivalent to SECTION_IMAGE_INFORMATION */




More information about the wine-cvs mailing list