Commit a5c2f043 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

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: 's avatarJacek Caban <jacek@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 4db58797
......@@ -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 */
......
......@@ -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;
......
......@@ -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 );
......
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment