server: Support for opening devices.
Added support for opening devices directly with the server when they don't correspond to a Unix file.
This commit is contained in:
parent
2017555b06
commit
67505c00af
|
@ -1296,6 +1296,10 @@ HANDLE WINAPI CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing,
|
|||
{
|
||||
dosdev += MAKELONG( 0, 4*sizeof(WCHAR) ); /* adjust position to start of filename */
|
||||
}
|
||||
else if (!(GetVersion() & 0x80000000))
|
||||
{
|
||||
dosdev = 0;
|
||||
}
|
||||
else if (filename[4])
|
||||
{
|
||||
ret = VXD_Open( filename+4, access, sa );
|
||||
|
|
|
@ -1337,7 +1337,7 @@ static NTSTATUS get_dos_device( const WCHAR *name, UINT name_len, ANSI_STRING *u
|
|||
|
||||
/* make sure the device name is ASCII */
|
||||
for (i = 0; i < name_len; i++)
|
||||
if (name[i] <= 32 || name[i] >= 127) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
if (name[i] <= 32 || name[i] >= 127) return STATUS_BAD_DEVICE_TYPE;
|
||||
|
||||
unix_len = strlen(config_dir) + sizeof("/dosdevices/") + name_len + 1;
|
||||
|
||||
|
@ -1405,7 +1405,7 @@ static NTSTATUS get_dos_device( const WCHAR *name, UINT name_len, ANSI_STRING *u
|
|||
dev = NULL; /* last try */
|
||||
}
|
||||
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
return STATUS_BAD_DEVICE_TYPE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -202,6 +202,22 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
|
|||
io->u.Status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name, disposition,
|
||||
!(attr->Attributes & OBJ_CASE_INSENSITIVE) );
|
||||
|
||||
if (io->u.Status == STATUS_BAD_DEVICE_TYPE)
|
||||
{
|
||||
SERVER_START_REQ( open_file_object )
|
||||
{
|
||||
req->access = access;
|
||||
req->attributes = attr->Attributes;
|
||||
req->rootdir = attr->RootDirectory;
|
||||
req->sharing = sharing;
|
||||
wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length );
|
||||
io->u.Status = wine_server_call( req );
|
||||
*handle = reply->handle;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return io->u.Status;
|
||||
}
|
||||
|
||||
if (io->u.Status == STATUS_NO_SUCH_FILE &&
|
||||
disposition != FILE_OPEN && disposition != FILE_OVERWRITE)
|
||||
{
|
||||
|
|
|
@ -772,6 +772,23 @@ struct create_file_reply
|
|||
|
||||
|
||||
|
||||
struct open_file_object_request
|
||||
{
|
||||
struct request_header __header;
|
||||
unsigned int access;
|
||||
unsigned int attributes;
|
||||
obj_handle_t rootdir;
|
||||
unsigned int sharing;
|
||||
/* VARARG(filename,unicode_str); */
|
||||
};
|
||||
struct open_file_object_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
obj_handle_t handle;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct alloc_file_handle_request
|
||||
{
|
||||
struct request_header __header;
|
||||
|
@ -3716,6 +3733,7 @@ enum request
|
|||
REQ_release_semaphore,
|
||||
REQ_open_semaphore,
|
||||
REQ_create_file,
|
||||
REQ_open_file_object,
|
||||
REQ_alloc_file_handle,
|
||||
REQ_get_handle_fd,
|
||||
REQ_set_handle_fd,
|
||||
|
@ -3933,6 +3951,7 @@ union generic_request
|
|||
struct release_semaphore_request release_semaphore_request;
|
||||
struct open_semaphore_request open_semaphore_request;
|
||||
struct create_file_request create_file_request;
|
||||
struct open_file_object_request open_file_object_request;
|
||||
struct alloc_file_handle_request alloc_file_handle_request;
|
||||
struct get_handle_fd_request get_handle_fd_request;
|
||||
struct set_handle_fd_request set_handle_fd_request;
|
||||
|
@ -4148,6 +4167,7 @@ union generic_reply
|
|||
struct release_semaphore_reply release_semaphore_reply;
|
||||
struct open_semaphore_reply open_semaphore_reply;
|
||||
struct create_file_reply create_file_reply;
|
||||
struct open_file_object_reply open_file_object_reply;
|
||||
struct alloc_file_handle_reply alloc_file_handle_reply;
|
||||
struct get_handle_fd_reply get_handle_fd_reply;
|
||||
struct set_handle_fd_reply set_handle_fd_reply;
|
||||
|
@ -4325,6 +4345,6 @@ union generic_reply
|
|||
struct query_symlink_reply query_symlink_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 215
|
||||
#define SERVER_PROTOCOL_VERSION 216
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
66
server/fd.c
66
server/fd.c
|
@ -145,7 +145,8 @@ struct fd
|
|||
unsigned int access; /* file access (GENERIC_READ/WRITE) */
|
||||
unsigned int sharing; /* file sharing mode */
|
||||
int unix_fd; /* unix file descriptor */
|
||||
int fs_locks; /* can we use filesystem locks for this fd? */
|
||||
int fs_locks :1; /* can we use filesystem locks for this fd? */
|
||||
int unmounted :1;/* has the device been unmounted? */
|
||||
int poll_index; /* index of fd in poll array */
|
||||
struct list read_q; /* async readers of this fd */
|
||||
struct list write_q; /* async writers of this fd */
|
||||
|
@ -1210,6 +1211,7 @@ static inline void unmount_fd( struct fd *fd )
|
|||
if (fd->unix_fd != -1) close( fd->unix_fd );
|
||||
|
||||
fd->unix_fd = -1;
|
||||
fd->unmounted = 1;
|
||||
fd->closed->unix_fd = -1;
|
||||
fd->closed->unlink[0] = 0;
|
||||
|
||||
|
@ -1232,6 +1234,7 @@ struct fd *alloc_fd( const struct fd_ops *fd_user_ops, struct object *user )
|
|||
fd->sharing = 0;
|
||||
fd->unix_fd = -1;
|
||||
fd->fs_locks = 1;
|
||||
fd->unmounted = 0;
|
||||
fd->poll_index = -1;
|
||||
list_init( &fd->inode_entry );
|
||||
list_init( &fd->locks );
|
||||
|
@ -1246,6 +1249,30 @@ struct fd *alloc_fd( const struct fd_ops *fd_user_ops, struct object *user )
|
|||
return fd;
|
||||
}
|
||||
|
||||
/* allocate a pseudo fd object, for objects that need to behave like files but don't have a unix fd */
|
||||
struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *user )
|
||||
{
|
||||
struct fd *fd = alloc_object( &fd_ops );
|
||||
|
||||
if (!fd) return NULL;
|
||||
|
||||
fd->fd_ops = fd_user_ops;
|
||||
fd->user = user;
|
||||
fd->inode = NULL;
|
||||
fd->closed = NULL;
|
||||
fd->access = 0;
|
||||
fd->sharing = 0;
|
||||
fd->unix_fd = -1;
|
||||
fd->fs_locks = 0;
|
||||
fd->unmounted = 0;
|
||||
fd->poll_index = -1;
|
||||
list_init( &fd->inode_entry );
|
||||
list_init( &fd->locks );
|
||||
list_init( &fd->read_q );
|
||||
list_init( &fd->write_q );
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* check if the desired access is possible without violating */
|
||||
/* the sharing mode of other opens of the same file */
|
||||
static int check_sharing( struct fd *fd, unsigned int access, unsigned int sharing )
|
||||
|
@ -1409,7 +1436,11 @@ void *get_fd_user( struct fd *fd )
|
|||
/* retrieve the unix fd for an object */
|
||||
int get_unix_fd( struct fd *fd )
|
||||
{
|
||||
if (fd->unix_fd == -1) set_error( STATUS_VOLUME_DISMOUNTED );
|
||||
if (fd->unix_fd == -1)
|
||||
{
|
||||
if (fd->unmounted) set_error( STATUS_VOLUME_DISMOUNTED );
|
||||
else set_error( STATUS_BAD_DEVICE_TYPE );
|
||||
}
|
||||
return fd->unix_fd;
|
||||
}
|
||||
|
||||
|
@ -1595,8 +1626,11 @@ static void unmount_device( struct fd *device_fd )
|
|||
struct device *device;
|
||||
struct inode *inode;
|
||||
struct fd *fd;
|
||||
int unix_fd = get_unix_fd( device_fd );
|
||||
|
||||
if (device_fd->unix_fd == -1 || fstat( device_fd->unix_fd, &st ) == -1 || !S_ISBLK( st.st_mode ))
|
||||
if (unix_fd == -1) return;
|
||||
|
||||
if (fstat( unix_fd, &st ) == -1 || !S_ISBLK( st.st_mode ))
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
|
@ -1653,6 +1687,32 @@ DECL_HANDLER(flush_file)
|
|||
}
|
||||
}
|
||||
|
||||
/* open a file object */
|
||||
DECL_HANDLER(open_file_object)
|
||||
{
|
||||
struct unicode_str name;
|
||||
struct directory *root = NULL;
|
||||
struct object *obj;
|
||||
|
||||
get_req_unicode_str( &name );
|
||||
if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
|
||||
return;
|
||||
|
||||
if ((obj = open_object_dir( root, &name, req->attributes, NULL )))
|
||||
{
|
||||
/* make sure this is a valid file object */
|
||||
struct fd *fd = get_obj_fd( obj );
|
||||
if (fd)
|
||||
{
|
||||
reply->handle = alloc_handle( current->process, obj, req->access, req->attributes );
|
||||
release_object( fd );
|
||||
}
|
||||
release_object( obj );
|
||||
}
|
||||
|
||||
if (root) release_object( root );
|
||||
}
|
||||
|
||||
/* get a Unix fd to access a file */
|
||||
DECL_HANDLER(get_handle_fd)
|
||||
{
|
||||
|
|
|
@ -47,6 +47,7 @@ struct fd_ops
|
|||
/* file descriptor functions */
|
||||
|
||||
extern struct fd *alloc_fd( const struct fd_ops *fd_user_ops, struct object *user );
|
||||
extern struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *user );
|
||||
extern struct fd *open_fd( struct fd *fd, const char *name, int flags, mode_t *mode,
|
||||
unsigned int access, unsigned int sharing, unsigned int options );
|
||||
extern struct fd *create_anonymous_fd( const struct fd_ops *fd_user_ops,
|
||||
|
|
|
@ -604,6 +604,18 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
|
|||
@END
|
||||
|
||||
|
||||
/* Open a file object */
|
||||
@REQ(open_file_object)
|
||||
unsigned int access; /* wanted access rights */
|
||||
unsigned int attributes; /* open attributes */
|
||||
obj_handle_t rootdir; /* root directory */
|
||||
unsigned int sharing; /* sharing flags */
|
||||
VARARG(filename,unicode_str); /* file name */
|
||||
@REPLY
|
||||
obj_handle_t handle; /* handle to the file */
|
||||
@END
|
||||
|
||||
|
||||
/* Allocate a file handle for a Unix fd */
|
||||
@REQ(alloc_file_handle)
|
||||
unsigned int access; /* wanted access rights */
|
||||
|
|
|
@ -145,6 +145,7 @@ DECL_HANDLER(create_semaphore);
|
|||
DECL_HANDLER(release_semaphore);
|
||||
DECL_HANDLER(open_semaphore);
|
||||
DECL_HANDLER(create_file);
|
||||
DECL_HANDLER(open_file_object);
|
||||
DECL_HANDLER(alloc_file_handle);
|
||||
DECL_HANDLER(get_handle_fd);
|
||||
DECL_HANDLER(set_handle_fd);
|
||||
|
@ -361,6 +362,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_release_semaphore,
|
||||
(req_handler)req_open_semaphore,
|
||||
(req_handler)req_create_file,
|
||||
(req_handler)req_open_file_object,
|
||||
(req_handler)req_alloc_file_handle,
|
||||
(req_handler)req_get_handle_fd,
|
||||
(req_handler)req_set_handle_fd,
|
||||
|
|
|
@ -1025,6 +1025,21 @@ static void dump_create_file_reply( const struct create_file_reply *req )
|
|||
fprintf( stderr, " handle=%p", req->handle );
|
||||
}
|
||||
|
||||
static void dump_open_file_object_request( const struct open_file_object_request *req )
|
||||
{
|
||||
fprintf( stderr, " access=%08x,", req->access );
|
||||
fprintf( stderr, " attributes=%08x,", req->attributes );
|
||||
fprintf( stderr, " rootdir=%p,", req->rootdir );
|
||||
fprintf( stderr, " sharing=%08x,", req->sharing );
|
||||
fprintf( stderr, " filename=" );
|
||||
dump_varargs_unicode_str( cur_size );
|
||||
}
|
||||
|
||||
static void dump_open_file_object_reply( const struct open_file_object_reply *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%p", req->handle );
|
||||
}
|
||||
|
||||
static void dump_alloc_file_handle_request( const struct alloc_file_handle_request *req )
|
||||
{
|
||||
fprintf( stderr, " access=%08x,", req->access );
|
||||
|
@ -3223,6 +3238,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_release_semaphore_request,
|
||||
(dump_func)dump_open_semaphore_request,
|
||||
(dump_func)dump_create_file_request,
|
||||
(dump_func)dump_open_file_object_request,
|
||||
(dump_func)dump_alloc_file_handle_request,
|
||||
(dump_func)dump_get_handle_fd_request,
|
||||
(dump_func)dump_set_handle_fd_request,
|
||||
|
@ -3436,6 +3452,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_release_semaphore_reply,
|
||||
(dump_func)dump_open_semaphore_reply,
|
||||
(dump_func)dump_create_file_reply,
|
||||
(dump_func)dump_open_file_object_reply,
|
||||
(dump_func)dump_alloc_file_handle_reply,
|
||||
(dump_func)dump_get_handle_fd_reply,
|
||||
(dump_func)dump_set_handle_fd_reply,
|
||||
|
@ -3649,6 +3666,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"release_semaphore",
|
||||
"open_semaphore",
|
||||
"create_file",
|
||||
"open_file_object",
|
||||
"alloc_file_handle",
|
||||
"get_handle_fd",
|
||||
"set_handle_fd",
|
||||
|
@ -3835,6 +3853,7 @@ static const struct
|
|||
{ "ACCESS_DENIED", STATUS_ACCESS_DENIED },
|
||||
{ "ACCESS_VIOLATION", STATUS_ACCESS_VIOLATION },
|
||||
{ "ALIAS_EXISTS", STATUS_ALIAS_EXISTS },
|
||||
{ "BAD_DEVICE_TYPE", STATUS_BAD_DEVICE_TYPE },
|
||||
{ "BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW },
|
||||
{ "BUFFER_TOO_SMALL", STATUS_BUFFER_TOO_SMALL },
|
||||
{ "CHILD_MUST_BE_VOLATILE", STATUS_CHILD_MUST_BE_VOLATILE },
|
||||
|
|
Loading…
Reference in New Issue