server: Notify kernel when IRP is terminated by server.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
dc5421f950
commit
b724024d5a
|
@ -838,6 +838,15 @@ static NTSTATUS dispatch_free( struct dispatch_context *context )
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS dispatch_cancel( struct dispatch_context *context )
|
||||||
|
{
|
||||||
|
IRP *irp = wine_server_get_ptr( context->params.cancel.irp );
|
||||||
|
|
||||||
|
FIXME( "%p\n", irp );
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
typedef NTSTATUS (*dispatch_func)( struct dispatch_context *context );
|
typedef NTSTATUS (*dispatch_func)( struct dispatch_context *context );
|
||||||
|
|
||||||
static const dispatch_func dispatch_funcs[] =
|
static const dispatch_func dispatch_funcs[] =
|
||||||
|
@ -849,7 +858,8 @@ static const dispatch_func dispatch_funcs[] =
|
||||||
dispatch_write, /* IRP_CALL_WRITE */
|
dispatch_write, /* IRP_CALL_WRITE */
|
||||||
dispatch_flush, /* IRP_CALL_FLUSH */
|
dispatch_flush, /* IRP_CALL_FLUSH */
|
||||||
dispatch_ioctl, /* IRP_CALL_IOCTL */
|
dispatch_ioctl, /* IRP_CALL_IOCTL */
|
||||||
dispatch_free /* IRP_CALL_FREE */
|
dispatch_free, /* IRP_CALL_FREE */
|
||||||
|
dispatch_cancel /* IRP_CALL_CANCEL */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* helper function to update service status */
|
/* helper function to update service status */
|
||||||
|
|
|
@ -649,7 +649,8 @@ enum irp_type
|
||||||
IRP_CALL_WRITE,
|
IRP_CALL_WRITE,
|
||||||
IRP_CALL_FLUSH,
|
IRP_CALL_FLUSH,
|
||||||
IRP_CALL_IOCTL,
|
IRP_CALL_IOCTL,
|
||||||
IRP_CALL_FREE
|
IRP_CALL_FREE,
|
||||||
|
IRP_CALL_CANCEL
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
@ -706,6 +707,12 @@ typedef union
|
||||||
int __pad;
|
int __pad;
|
||||||
client_ptr_t obj;
|
client_ptr_t obj;
|
||||||
} free;
|
} free;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
enum irp_type type;
|
||||||
|
int __pad;
|
||||||
|
client_ptr_t irp;
|
||||||
|
} cancel;
|
||||||
} irp_params_t;
|
} irp_params_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -6695,6 +6702,6 @@ union generic_reply
|
||||||
struct resume_process_reply resume_process_reply;
|
struct resume_process_reply resume_process_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 584
|
#define SERVER_PROTOCOL_VERSION 585
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -52,6 +52,7 @@ struct irp_call
|
||||||
struct async *async; /* pending async op */
|
struct async *async; /* pending async op */
|
||||||
irp_params_t params; /* irp parameters */
|
irp_params_t params; /* irp parameters */
|
||||||
struct iosb *iosb; /* I/O status block */
|
struct iosb *iosb; /* I/O status block */
|
||||||
|
int canceled; /* the call was canceled */
|
||||||
client_ptr_t user_ptr; /* client side pointer */
|
client_ptr_t user_ptr; /* client side pointer */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -188,6 +189,7 @@ static int device_file_read( struct fd *fd, struct async *async, file_pos_t pos
|
||||||
static int device_file_write( struct fd *fd, struct async *async, file_pos_t pos );
|
static int device_file_write( struct fd *fd, struct async *async, file_pos_t pos );
|
||||||
static int device_file_flush( struct fd *fd, struct async *async );
|
static int device_file_flush( struct fd *fd, struct async *async );
|
||||||
static int device_file_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
|
static int device_file_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
|
||||||
|
static void device_file_reselect_async( struct fd *fd, struct async_queue *queue );
|
||||||
|
|
||||||
static const struct object_ops device_file_ops =
|
static const struct object_ops device_file_ops =
|
||||||
{
|
{
|
||||||
|
@ -224,7 +226,7 @@ static const struct fd_ops device_file_fd_ops =
|
||||||
no_fd_get_volume_info, /* get_volume_info */
|
no_fd_get_volume_info, /* get_volume_info */
|
||||||
device_file_ioctl, /* ioctl */
|
device_file_ioctl, /* ioctl */
|
||||||
default_fd_queue_async, /* queue_async */
|
default_fd_queue_async, /* queue_async */
|
||||||
default_fd_reselect_async /* reselect_async */
|
device_file_reselect_async /* reselect_async */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -352,6 +354,7 @@ static struct irp_call *create_irp( struct device_file *file, const irp_params_t
|
||||||
irp->async = NULL;
|
irp->async = NULL;
|
||||||
irp->params = *params;
|
irp->params = *params;
|
||||||
irp->iosb = NULL;
|
irp->iosb = NULL;
|
||||||
|
irp->canceled = 0;
|
||||||
irp->user_ptr = 0;
|
irp->user_ptr = 0;
|
||||||
|
|
||||||
if (async) irp->iosb = async_get_iosb( async );
|
if (async) irp->iosb = async_get_iosb( async );
|
||||||
|
@ -548,6 +551,7 @@ static int fill_irp_params( struct device_manager *manager, struct irp_call *irp
|
||||||
{
|
{
|
||||||
case IRP_CALL_NONE:
|
case IRP_CALL_NONE:
|
||||||
case IRP_CALL_FREE:
|
case IRP_CALL_FREE:
|
||||||
|
case IRP_CALL_CANCEL:
|
||||||
break;
|
break;
|
||||||
case IRP_CALL_CREATE:
|
case IRP_CALL_CREATE:
|
||||||
irp->params.create.file = alloc_handle( current->process, irp->file,
|
irp->params.create.file = alloc_handle( current->process, irp->file,
|
||||||
|
@ -653,6 +657,40 @@ static int device_file_ioctl( struct fd *fd, ioctl_code_t code, struct async *as
|
||||||
return queue_irp( file, ¶ms, async );
|
return queue_irp( file, ¶ms, async );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cancel_irp_call( struct irp_call *irp )
|
||||||
|
{
|
||||||
|
struct irp_call *cancel_irp;
|
||||||
|
irp_params_t params;
|
||||||
|
|
||||||
|
irp->canceled = 1;
|
||||||
|
if (!irp->user_ptr || !irp->file || !irp->file->device->manager) return;
|
||||||
|
|
||||||
|
memset( ¶ms, 0, sizeof(params) );
|
||||||
|
params.cancel.type = IRP_CALL_CANCEL;
|
||||||
|
params.cancel.irp = irp->user_ptr;
|
||||||
|
|
||||||
|
if ((cancel_irp = create_irp( NULL, ¶ms, NULL )))
|
||||||
|
{
|
||||||
|
add_irp_to_queue( irp->file->device->manager, cancel_irp, NULL );
|
||||||
|
release_object( cancel_irp );
|
||||||
|
}
|
||||||
|
|
||||||
|
set_irp_result( irp, STATUS_CANCELLED, NULL, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void device_file_reselect_async( struct fd *fd, struct async_queue *queue )
|
||||||
|
{
|
||||||
|
struct device_file *file = get_fd_user( fd );
|
||||||
|
struct irp_call *irp;
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY( irp, &file->requests, struct irp_call, dev_entry )
|
||||||
|
if (irp->iosb->status != STATUS_PENDING)
|
||||||
|
{
|
||||||
|
cancel_irp_call( irp );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct device *create_device( struct object *root, const struct unicode_str *name,
|
static struct device *create_device( struct object *root, const struct unicode_str *name,
|
||||||
struct device_manager *manager )
|
struct device_manager *manager )
|
||||||
{
|
{
|
||||||
|
@ -897,6 +935,10 @@ DECL_HANDLER(get_next_device_request)
|
||||||
|
|
||||||
if (req->status)
|
if (req->status)
|
||||||
set_irp_result( irp, req->status, NULL, 0, 0 );
|
set_irp_result( irp, req->status, NULL, 0, 0 );
|
||||||
|
if (irp->canceled)
|
||||||
|
/* if it was canceled during dispatch, we couldn't queue cancel call without client pointer,
|
||||||
|
* so we need to do it now */
|
||||||
|
cancel_irp_call( irp );
|
||||||
else if (irp->async)
|
else if (irp->async)
|
||||||
set_async_pending( irp->async, irp->file && is_fd_overlapped( irp->file->fd ) );
|
set_async_pending( irp->async, irp->file && is_fd_overlapped( irp->file->fd ) );
|
||||||
|
|
||||||
|
@ -947,7 +989,12 @@ DECL_HANDLER(set_irp_result)
|
||||||
|
|
||||||
if ((irp = (struct irp_call *)get_handle_obj( current->process, req->handle, 0, &irp_call_ops )))
|
if ((irp = (struct irp_call *)get_handle_obj( current->process, req->handle, 0, &irp_call_ops )))
|
||||||
{
|
{
|
||||||
|
if (!irp->canceled)
|
||||||
set_irp_result( irp, req->status, get_req_data(), get_req_data_size(), req->size );
|
set_irp_result( irp, req->status, get_req_data(), get_req_data_size(), req->size );
|
||||||
|
else if(irp->user_ptr) /* cancel already queued */
|
||||||
|
set_error( STATUS_MORE_PROCESSING_REQUIRED );
|
||||||
|
else /* we may be still dispatching the IRP. don't bother queuing cancel if it's already complete */
|
||||||
|
irp->canceled = 0;
|
||||||
close_handle( current->process, req->handle ); /* avoid an extra round-trip for close */
|
close_handle( current->process, req->handle ); /* avoid an extra round-trip for close */
|
||||||
release_object( irp );
|
release_object( irp );
|
||||||
}
|
}
|
||||||
|
|
|
@ -665,7 +665,8 @@ enum irp_type
|
||||||
IRP_CALL_WRITE,
|
IRP_CALL_WRITE,
|
||||||
IRP_CALL_FLUSH,
|
IRP_CALL_FLUSH,
|
||||||
IRP_CALL_IOCTL,
|
IRP_CALL_IOCTL,
|
||||||
IRP_CALL_FREE
|
IRP_CALL_FREE,
|
||||||
|
IRP_CALL_CANCEL
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
@ -722,6 +723,12 @@ typedef union
|
||||||
int __pad;
|
int __pad;
|
||||||
client_ptr_t obj; /* opaque ptr for the freed object */
|
client_ptr_t obj; /* opaque ptr for the freed object */
|
||||||
} free;
|
} free;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
enum irp_type type; /* IRP_CALL_CANCEL */
|
||||||
|
int __pad;
|
||||||
|
client_ptr_t irp; /* opaque ptr for canceled irp */
|
||||||
|
} cancel;
|
||||||
} irp_params_t;
|
} irp_params_t;
|
||||||
|
|
||||||
/* information about a PE image mapping, roughly equivalent to SECTION_IMAGE_INFORMATION */
|
/* information about a PE image mapping, roughly equivalent to SECTION_IMAGE_INFORMATION */
|
||||||
|
|
|
@ -363,6 +363,11 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data )
|
||||||
dump_uint64( ",obj=", &data->free.obj );
|
dump_uint64( ",obj=", &data->free.obj );
|
||||||
fputc( '}', stderr );
|
fputc( '}', stderr );
|
||||||
break;
|
break;
|
||||||
|
case IRP_CALL_CANCEL:
|
||||||
|
fprintf( stderr, "%s{CANCEL", prefix );
|
||||||
|
dump_uint64( ",irp=", &data->cancel.irp );
|
||||||
|
fputc( '}', stderr );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue