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@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4db5879742
commit
a5c2f043e6
|
@ -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( ¶ms, 0, sizeof(params) );
|
||||
params.cleanup.major = IRP_MJ_CLEANUP;
|
||||
params.cleanup.obj = kernel_object->user_ptr;
|
||||
|
||||
if ((irp = create_irp( NULL, ¶ms, 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 */
|
||||
|
|
Loading…
Reference in New Issue