server: Queue an IRP_MJ_CREATE request on file creation.
This commit is contained in:
parent
d087ea6798
commit
b1fd5955c9
|
@ -635,6 +635,14 @@ typedef union
|
||||||
{
|
{
|
||||||
unsigned int major;
|
unsigned int major;
|
||||||
struct
|
struct
|
||||||
|
{
|
||||||
|
unsigned int major;
|
||||||
|
unsigned int access;
|
||||||
|
unsigned int sharing;
|
||||||
|
unsigned int options;
|
||||||
|
client_ptr_t device;
|
||||||
|
} create;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
unsigned int major;
|
unsigned int major;
|
||||||
unsigned int key;
|
unsigned int key;
|
||||||
|
@ -6081,6 +6089,6 @@ union generic_reply
|
||||||
struct terminate_job_reply terminate_job_reply;
|
struct terminate_job_reply terminate_job_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 477
|
#define SERVER_PROTOCOL_VERSION 478
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -335,31 +335,61 @@ static void device_destroy( struct object *obj )
|
||||||
if (device->manager) list_remove( &device->entry );
|
if (device->manager) list_remove( &device->entry );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_irp_to_queue( struct device_file *file, struct irp_call *irp )
|
||||||
|
{
|
||||||
|
struct device_manager *manager = file->device->manager;
|
||||||
|
|
||||||
|
assert( manager );
|
||||||
|
|
||||||
|
grab_object( irp ); /* grab reference for queued irp */
|
||||||
|
irp->thread = (struct thread *)grab_object( current );
|
||||||
|
list_add_tail( &file->requests, &irp->dev_entry );
|
||||||
|
list_add_tail( &manager->requests, &irp->mgr_entry );
|
||||||
|
if (list_head( &manager->requests ) == &irp->mgr_entry) wake_up( &manager->obj, 0 ); /* first one */
|
||||||
|
}
|
||||||
|
|
||||||
static struct object *device_open_file( struct object *obj, unsigned int access,
|
static struct object *device_open_file( struct object *obj, unsigned int access,
|
||||||
unsigned int sharing, unsigned int options )
|
unsigned int sharing, unsigned int options )
|
||||||
{
|
{
|
||||||
struct device *device = (struct device *)obj;
|
struct device *device = (struct device *)obj;
|
||||||
struct device_file *file;
|
struct device_file *file;
|
||||||
|
|
||||||
if ((file = alloc_object( &device_file_ops )))
|
if (!(file = alloc_object( &device_file_ops ))) return NULL;
|
||||||
{
|
|
||||||
file->device = (struct device *)grab_object( device );
|
|
||||||
list_init( &file->requests );
|
|
||||||
list_add_tail( &device->files, &file->entry );
|
|
||||||
if (device->unix_path)
|
|
||||||
{
|
|
||||||
mode_t mode = 0666;
|
|
||||||
access = file->obj.ops->map_access( &file->obj, access );
|
|
||||||
file->fd = open_fd( NULL, device->unix_path, O_NONBLOCK | O_LARGEFILE,
|
|
||||||
&mode, access, sharing, options );
|
|
||||||
if (file->fd) set_fd_user( file->fd, &device_file_fd_ops, &file->obj );
|
|
||||||
}
|
|
||||||
else file->fd = alloc_pseudo_fd( &device_file_fd_ops, &file->obj, 0 );
|
|
||||||
|
|
||||||
if (!file->fd)
|
file->device = (struct device *)grab_object( device );
|
||||||
|
list_init( &file->requests );
|
||||||
|
list_add_tail( &device->files, &file->entry );
|
||||||
|
if (device->unix_path)
|
||||||
|
{
|
||||||
|
mode_t mode = 0666;
|
||||||
|
access = file->obj.ops->map_access( &file->obj, access );
|
||||||
|
file->fd = open_fd( NULL, device->unix_path, O_NONBLOCK | O_LARGEFILE,
|
||||||
|
&mode, access, sharing, options );
|
||||||
|
if (file->fd) set_fd_user( file->fd, &device_file_fd_ops, &file->obj );
|
||||||
|
}
|
||||||
|
else file->fd = alloc_pseudo_fd( &device_file_fd_ops, &file->obj, 0 );
|
||||||
|
|
||||||
|
if (!file->fd)
|
||||||
|
{
|
||||||
|
release_object( file );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->manager)
|
||||||
|
{
|
||||||
|
struct irp_call *irp;
|
||||||
|
irp_params_t params;
|
||||||
|
|
||||||
|
params.create.major = IRP_MJ_CREATE;
|
||||||
|
params.create.access = access;
|
||||||
|
params.create.sharing = sharing;
|
||||||
|
params.create.options = options;
|
||||||
|
params.create.device = file->device->user_ptr;
|
||||||
|
|
||||||
|
if ((irp = create_irp( file, ¶ms, NULL, 0, 0 )))
|
||||||
{
|
{
|
||||||
release_object( file );
|
add_irp_to_queue( file, irp );
|
||||||
file = NULL;
|
release_object( irp );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &file->obj;
|
return &file->obj;
|
||||||
|
@ -411,9 +441,6 @@ static obj_handle_t queue_irp( struct device_file *file, struct irp_call *irp,
|
||||||
const async_data_t *async_data, int blocking )
|
const async_data_t *async_data, int blocking )
|
||||||
{
|
{
|
||||||
obj_handle_t handle = 0;
|
obj_handle_t handle = 0;
|
||||||
struct device_manager *manager = file->device->manager;
|
|
||||||
|
|
||||||
assert( manager );
|
|
||||||
|
|
||||||
if (blocking && !(handle = alloc_handle( current->process, irp, SYNCHRONIZE, 0 ))) return 0;
|
if (blocking && !(handle = alloc_handle( current->process, irp, SYNCHRONIZE, 0 ))) return 0;
|
||||||
|
|
||||||
|
@ -422,13 +449,8 @@ static obj_handle_t queue_irp( struct device_file *file, struct irp_call *irp,
|
||||||
if (handle) close_handle( current->process, handle );
|
if (handle) close_handle( current->process, handle );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
irp->thread = (struct thread *)grab_object( current );
|
|
||||||
irp->user_arg = async_data->arg;
|
irp->user_arg = async_data->arg;
|
||||||
grab_object( irp ); /* grab reference for queued irp */
|
add_irp_to_queue( file, irp );
|
||||||
|
|
||||||
list_add_tail( &file->requests, &irp->dev_entry );
|
|
||||||
list_add_tail( &manager->requests, &irp->mgr_entry );
|
|
||||||
if (list_head( &manager->requests ) == &irp->mgr_entry) wake_up( &manager->obj, 0 ); /* first one */
|
|
||||||
set_error( STATUS_PENDING );
|
set_error( STATUS_PENDING );
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
@ -683,6 +705,8 @@ DECL_HANDLER(get_next_device_request)
|
||||||
struct device_manager *manager;
|
struct device_manager *manager;
|
||||||
struct list *ptr;
|
struct list *ptr;
|
||||||
|
|
||||||
|
reply->params.major = IRP_MJ_MAXIMUM_FUNCTION + 1;
|
||||||
|
|
||||||
if (!(manager = (struct device_manager *)get_handle_obj( current->process, req->manager,
|
if (!(manager = (struct device_manager *)get_handle_obj( current->process, req->manager,
|
||||||
0, &device_manager_ops )))
|
0, &device_manager_ops )))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -651,6 +651,14 @@ typedef union
|
||||||
{
|
{
|
||||||
unsigned int major; /* irp major function */
|
unsigned int major; /* irp major function */
|
||||||
struct
|
struct
|
||||||
|
{
|
||||||
|
unsigned int major; /* IRP_MJ_CREATE */
|
||||||
|
unsigned int access; /* access rights */
|
||||||
|
unsigned int sharing; /* sharing flags */
|
||||||
|
unsigned int options; /* file options */
|
||||||
|
client_ptr_t device; /* opaque ptr for the device */
|
||||||
|
} create;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
unsigned int major; /* IRP_MJ_READ */
|
unsigned int major; /* IRP_MJ_READ */
|
||||||
unsigned int key; /* driver key */
|
unsigned int key; /* driver key */
|
||||||
|
|
|
@ -316,6 +316,12 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data )
|
||||||
{
|
{
|
||||||
switch (data->major)
|
switch (data->major)
|
||||||
{
|
{
|
||||||
|
case IRP_MJ_CREATE:
|
||||||
|
fprintf( stderr, "%s{major=CREATE,access=%08x,sharing=%08x,options=%08x",
|
||||||
|
prefix, data->create.access, data->create.sharing, data->create.options );
|
||||||
|
dump_uint64( ",device=", &data->create.device );
|
||||||
|
fputc( '}', stderr );
|
||||||
|
break;
|
||||||
case IRP_MJ_READ:
|
case IRP_MJ_READ:
|
||||||
fprintf( stderr, "%s{major=READ,key=%08x", prefix, data->read.key );
|
fprintf( stderr, "%s{major=READ,key=%08x", prefix, data->read.key );
|
||||||
dump_uint64( ",pos=", &data->read.pos );
|
dump_uint64( ",pos=", &data->read.pos );
|
||||||
|
@ -339,6 +345,9 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data )
|
||||||
dump_uint64( ",device=", &data->ioctl.device );
|
dump_uint64( ",device=", &data->ioctl.device );
|
||||||
fputc( '}', stderr );
|
fputc( '}', stderr );
|
||||||
break;
|
break;
|
||||||
|
case IRP_MJ_MAXIMUM_FUNCTION + 1: /* invalid */
|
||||||
|
fprintf( stderr, "%s{}", prefix );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf( stderr, "%s{major=%u}", prefix, data->major );
|
fprintf( stderr, "%s{major=%u}", prefix, data->major );
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue