server: Use generic kernel object list to store client device pointer.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
abca25b30f
commit
b4f78d6896
|
@ -1474,8 +1474,6 @@ static const WCHAR device_type_name[] = {'D','e','v','i','c','e',0};
|
|||
static struct _OBJECT_TYPE device_type =
|
||||
{
|
||||
device_type_name,
|
||||
NULL,
|
||||
free_kernel_object
|
||||
};
|
||||
|
||||
POBJECT_TYPE IoDeviceObjectType = &device_type;
|
||||
|
@ -1491,7 +1489,6 @@ NTSTATUS WINAPI IoCreateDevice( DRIVER_OBJECT *driver, ULONG ext_size,
|
|||
{
|
||||
NTSTATUS status;
|
||||
DEVICE_OBJECT *device;
|
||||
HANDLE handle = 0;
|
||||
HANDLE manager = get_device_manager();
|
||||
|
||||
TRACE( "(%p, %u, %s, %u, %x, %u, %p)\n",
|
||||
|
@ -1500,34 +1497,32 @@ NTSTATUS WINAPI IoCreateDevice( DRIVER_OBJECT *driver, ULONG ext_size,
|
|||
if (!(device = alloc_kernel_object( IoDeviceObjectType, NULL, sizeof(DEVICE_OBJECT) + ext_size, 1 )))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
device->DriverObject = driver;
|
||||
device->DeviceExtension = device + 1;
|
||||
device->DeviceType = type;
|
||||
device->StackSize = 1;
|
||||
|
||||
device->NextDevice = driver->DeviceObject;
|
||||
driver->DeviceObject = device;
|
||||
|
||||
SERVER_START_REQ( create_device )
|
||||
{
|
||||
req->access = 0;
|
||||
req->attributes = 0;
|
||||
req->rootdir = 0;
|
||||
req->manager = wine_server_obj_handle( manager );
|
||||
req->user_ptr = wine_server_client_ptr( device );
|
||||
if (name) wine_server_add_data( req, name->Buffer, name->Length );
|
||||
if (!(status = wine_server_call( req ))) handle = wine_server_ptr_handle( reply->handle );
|
||||
status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (status == STATUS_SUCCESS)
|
||||
if (status)
|
||||
{
|
||||
device->DriverObject = driver;
|
||||
device->DeviceExtension = device + 1;
|
||||
device->DeviceType = type;
|
||||
device->StackSize = 1;
|
||||
device->Reserved = handle;
|
||||
|
||||
device->NextDevice = driver->DeviceObject;
|
||||
driver->DeviceObject = device;
|
||||
|
||||
*ret_device = device;
|
||||
free_kernel_object( device );
|
||||
return status;
|
||||
}
|
||||
else free_kernel_object( device );
|
||||
|
||||
return status;
|
||||
*ret_device = device;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1542,7 +1537,8 @@ void WINAPI IoDeleteDevice( DEVICE_OBJECT *device )
|
|||
|
||||
SERVER_START_REQ( delete_device )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( device->Reserved );
|
||||
req->manager = wine_server_obj_handle( get_device_manager() );
|
||||
req->device = wine_server_client_ptr( device );
|
||||
status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
@ -1552,7 +1548,6 @@ void WINAPI IoDeleteDevice( DEVICE_OBJECT *device )
|
|||
DEVICE_OBJECT **prev = &device->DriverObject->DeviceObject;
|
||||
while (*prev && *prev != device) prev = &(*prev)->NextDevice;
|
||||
if (*prev) *prev = (*prev)->NextDevice;
|
||||
NtClose( device->Reserved );
|
||||
ObDereferenceObject( device );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5202,19 +5202,15 @@ struct create_device_manager_reply
|
|||
struct create_device_request
|
||||
{
|
||||
struct request_header __header;
|
||||
unsigned int access;
|
||||
unsigned int attributes;
|
||||
obj_handle_t rootdir;
|
||||
client_ptr_t user_ptr;
|
||||
obj_handle_t manager;
|
||||
/* VARARG(name,unicode_str); */
|
||||
char __pad_36[4];
|
||||
char __pad_28[4];
|
||||
};
|
||||
struct create_device_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
obj_handle_t handle;
|
||||
char __pad_12[4];
|
||||
};
|
||||
|
||||
|
||||
|
@ -5222,7 +5218,8 @@ struct create_device_reply
|
|||
struct delete_device_request
|
||||
{
|
||||
struct request_header __header;
|
||||
obj_handle_t handle;
|
||||
obj_handle_t manager;
|
||||
client_ptr_t device;
|
||||
};
|
||||
struct delete_device_reply
|
||||
{
|
||||
|
@ -6650,6 +6647,6 @@ union generic_reply
|
|||
struct terminate_job_reply terminate_job_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 576
|
||||
#define SERVER_PROTOCOL_VERSION 577
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -127,7 +127,7 @@ struct device
|
|||
struct object obj; /* object header */
|
||||
struct device_manager *manager; /* manager for this device (or NULL if deleted) */
|
||||
char *unix_path; /* path to unix device if any */
|
||||
client_ptr_t user_ptr; /* opaque ptr for client side */
|
||||
struct list kernel_object; /* list of kernel object pointers */
|
||||
struct list entry; /* entry in device manager list */
|
||||
struct list files; /* list of open files */
|
||||
};
|
||||
|
@ -137,6 +137,7 @@ static struct object_type *device_get_type( struct object *obj );
|
|||
static void device_destroy( struct object *obj );
|
||||
static struct object *device_open_file( struct object *obj, unsigned int access,
|
||||
unsigned int sharing, unsigned int options );
|
||||
static struct list *device_get_kernel_obj_list( struct object *obj );
|
||||
|
||||
static const struct object_ops device_ops =
|
||||
{
|
||||
|
@ -156,7 +157,7 @@ static const struct object_ops device_ops =
|
|||
directory_link_name, /* link_name */
|
||||
default_unlink_name, /* unlink_name */
|
||||
device_open_file, /* open_file */
|
||||
no_kernel_obj_list, /* get_kernel_obj_list */
|
||||
device_get_kernel_obj_list, /* get_kernel_obj_list */
|
||||
no_close_handle, /* close_handle */
|
||||
device_destroy /* destroy */
|
||||
};
|
||||
|
@ -460,7 +461,7 @@ static struct object *device_open_file( struct object *obj, unsigned int access,
|
|||
params.create.access = access;
|
||||
params.create.sharing = sharing;
|
||||
params.create.options = options;
|
||||
params.create.device = file->device->user_ptr;
|
||||
params.create.device = get_kernel_object_ptr( device->manager, &device->obj );
|
||||
|
||||
if ((irp = create_irp( file, ¶ms, NULL )))
|
||||
{
|
||||
|
@ -471,6 +472,12 @@ static struct object *device_open_file( struct object *obj, unsigned int access,
|
|||
return &file->obj;
|
||||
}
|
||||
|
||||
static struct list *device_get_kernel_obj_list( struct object *obj )
|
||||
{
|
||||
struct device *device = (struct device *)obj;
|
||||
return &device->kernel_object;
|
||||
}
|
||||
|
||||
static void device_file_dump( struct object *obj, int verbose )
|
||||
{
|
||||
struct device_file *file = (struct device_file *)obj;
|
||||
|
@ -614,20 +621,17 @@ static int device_file_ioctl( struct fd *fd, ioctl_code_t code, struct async *as
|
|||
}
|
||||
|
||||
static struct device *create_device( struct object *root, const struct unicode_str *name,
|
||||
struct device_manager *manager, unsigned int attr )
|
||||
struct device_manager *manager )
|
||||
{
|
||||
struct device *device;
|
||||
|
||||
if ((device = create_named_object( root, &device_ops, name, attr, NULL )))
|
||||
if ((device = create_named_object( root, &device_ops, name, 0, NULL )))
|
||||
{
|
||||
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
|
||||
{
|
||||
/* initialize it if it didn't already exist */
|
||||
device->unix_path = NULL;
|
||||
device->manager = manager;
|
||||
list_add_tail( &manager->devices, &device->entry );
|
||||
list_init( &device->files );
|
||||
}
|
||||
device->unix_path = NULL;
|
||||
device->manager = manager;
|
||||
list_add_tail( &manager->devices, &device->entry );
|
||||
list_init( &device->kernel_object );
|
||||
list_init( &device->files );
|
||||
}
|
||||
return device;
|
||||
}
|
||||
|
@ -641,6 +645,7 @@ struct object *create_unix_device( struct object *root, const struct unicode_str
|
|||
{
|
||||
device->unix_path = strdup( unix_path );
|
||||
device->manager = NULL; /* no manager, requests go straight to the Unix device */
|
||||
list_init( &device->kernel_object );
|
||||
list_init( &device->files );
|
||||
}
|
||||
return &device->obj;
|
||||
|
@ -793,10 +798,13 @@ DECL_HANDLER(create_device)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((device = create_device( root, &name, manager, req->attributes )))
|
||||
if ((device = create_device( root, &name, manager )))
|
||||
{
|
||||
device->user_ptr = req->user_ptr;
|
||||
reply->handle = alloc_handle( current->process, device, req->access, req->attributes );
|
||||
struct kernel_object *ptr = set_kernel_object( manager, &device->obj, req->user_ptr );
|
||||
if (ptr)
|
||||
grab_kernel_object( ptr );
|
||||
else
|
||||
set_error( STATUS_NO_MEMORY );
|
||||
release_object( device );
|
||||
}
|
||||
|
||||
|
@ -808,13 +816,23 @@ DECL_HANDLER(create_device)
|
|||
/* delete a device */
|
||||
DECL_HANDLER(delete_device)
|
||||
{
|
||||
struct device_manager *manager;
|
||||
struct kernel_object *ref;
|
||||
struct device *device;
|
||||
|
||||
if ((device = (struct device *)get_handle_obj( current->process, req->handle, 0, &device_ops )))
|
||||
if (!(manager = (struct device_manager *)get_handle_obj( current->process, req->manager,
|
||||
0, &device_manager_ops )))
|
||||
return;
|
||||
|
||||
if ((ref = kernel_object_from_ptr( manager, req->device )) && ref->object->ops == &device_ops)
|
||||
{
|
||||
device = (struct device *)grab_object( ref->object );
|
||||
delete_device( device );
|
||||
release_object( device );
|
||||
}
|
||||
else set_error( STATUS_INVALID_HANDLE );
|
||||
|
||||
release_object( manager );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3596,20 +3596,17 @@ struct handle_info
|
|||
|
||||
/* Create a device */
|
||||
@REQ(create_device)
|
||||
unsigned int access; /* wanted access rights */
|
||||
unsigned int attributes; /* object attributes */
|
||||
obj_handle_t rootdir; /* root directory */
|
||||
client_ptr_t user_ptr; /* opaque ptr for use by client */
|
||||
obj_handle_t manager; /* device manager */
|
||||
VARARG(name,unicode_str); /* object name */
|
||||
@REPLY
|
||||
obj_handle_t handle; /* handle to the device */
|
||||
@END
|
||||
|
||||
|
||||
/* Delete a device */
|
||||
@REQ(delete_device)
|
||||
obj_handle_t handle; /* handle to the device */
|
||||
obj_handle_t manager; /* handle to the device manager */
|
||||
client_ptr_t device; /* pointer to the device */
|
||||
@END
|
||||
|
||||
|
||||
|
|
|
@ -2274,16 +2274,13 @@ C_ASSERT( FIELD_OFFSET(struct create_device_manager_request, attributes) == 16 )
|
|||
C_ASSERT( sizeof(struct create_device_manager_request) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_device_manager_reply, handle) == 8 );
|
||||
C_ASSERT( sizeof(struct create_device_manager_reply) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_device_request, access) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_device_request, attributes) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_device_request, rootdir) == 20 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_device_request, user_ptr) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_device_request, manager) == 32 );
|
||||
C_ASSERT( sizeof(struct create_device_request) == 40 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_device_reply, handle) == 8 );
|
||||
C_ASSERT( sizeof(struct create_device_reply) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct delete_device_request, handle) == 12 );
|
||||
C_ASSERT( sizeof(struct delete_device_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_device_request, rootdir) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_device_request, user_ptr) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_device_request, manager) == 24 );
|
||||
C_ASSERT( sizeof(struct create_device_request) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct delete_device_request, manager) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct delete_device_request, device) == 16 );
|
||||
C_ASSERT( sizeof(struct delete_device_request) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_request, manager) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_request, prev) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_next_device_request_request, status) == 20 );
|
||||
|
|
|
@ -4262,22 +4262,16 @@ static void dump_create_device_manager_reply( const struct create_device_manager
|
|||
|
||||
static void dump_create_device_request( const struct create_device_request *req )
|
||||
{
|
||||
fprintf( stderr, " access=%08x", req->access );
|
||||
fprintf( stderr, ", attributes=%08x", req->attributes );
|
||||
fprintf( stderr, ", rootdir=%04x", req->rootdir );
|
||||
fprintf( stderr, " rootdir=%04x", req->rootdir );
|
||||
dump_uint64( ", user_ptr=", &req->user_ptr );
|
||||
fprintf( stderr, ", manager=%04x", req->manager );
|
||||
dump_varargs_unicode_str( ", name=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_create_device_reply( const struct create_device_reply *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%04x", req->handle );
|
||||
}
|
||||
|
||||
static void dump_delete_device_request( const struct delete_device_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%04x", req->handle );
|
||||
fprintf( stderr, " manager=%04x", req->manager );
|
||||
dump_uint64( ", device=", &req->device );
|
||||
}
|
||||
|
||||
static void dump_get_next_device_request_request( const struct get_next_device_request_request *req )
|
||||
|
@ -5149,7 +5143,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_get_token_impersonation_level_reply,
|
||||
(dump_func)dump_allocate_locally_unique_id_reply,
|
||||
(dump_func)dump_create_device_manager_reply,
|
||||
(dump_func)dump_create_device_reply,
|
||||
NULL,
|
||||
NULL,
|
||||
(dump_func)dump_get_next_device_request_reply,
|
||||
(dump_func)dump_get_kernel_object_ptr_reply,
|
||||
|
|
Loading…
Reference in New Issue