Commit 67505c00 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Support for opening devices.

Added support for opening devices directly with the server when they don't correspond to a Unix file.
parent 2017555b
......@@ -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 */
......@@ -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 },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment