server: Store the NT name in the fd object.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9e255ba4e0
commit
bb00942671
|
@ -446,6 +446,7 @@ static struct object *device_open_file( struct object *obj, unsigned int access,
|
|||
{
|
||||
struct device *device = (struct device *)obj;
|
||||
struct device_file *file;
|
||||
struct unicode_str nt_name;
|
||||
|
||||
if (!(file = alloc_object( &device_file_ops ))) return NULL;
|
||||
|
||||
|
@ -458,7 +459,8 @@ static struct object *device_open_file( struct object *obj, unsigned int access,
|
|||
{
|
||||
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,
|
||||
nt_name.str = device->obj.ops->get_full_name( &device->obj, &nt_name.len );
|
||||
file->fd = open_fd( NULL, device->unix_path, nt_name, O_NONBLOCK | O_LARGEFILE,
|
||||
&mode, access, sharing, options );
|
||||
if (file->fd) set_fd_user( file->fd, &device_file_fd_ops, &file->obj );
|
||||
}
|
||||
|
|
68
server/fd.c
68
server/fd.c
|
@ -185,6 +185,8 @@ struct fd
|
|||
unsigned int options; /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
|
||||
unsigned int sharing; /* file sharing mode */
|
||||
char *unix_name; /* unix file name */
|
||||
WCHAR *nt_name; /* NT file name */
|
||||
data_size_t nt_namelen; /* length of NT file name */
|
||||
int unix_fd; /* unix file descriptor */
|
||||
unsigned int no_fd_status;/* status to return when unix_fd is -1 */
|
||||
unsigned int cacheable :1;/* can the fd be cached on the client side? */
|
||||
|
@ -1570,6 +1572,7 @@ static void fd_destroy( struct object *obj )
|
|||
remove_fd_locks( fd );
|
||||
list_remove( &fd->inode_entry );
|
||||
if (fd->poll_index != -1) remove_poll_user( fd, fd->poll_index );
|
||||
free( fd->nt_name );
|
||||
if (fd->inode)
|
||||
{
|
||||
inode_add_closed_fd( fd->inode, fd->closed );
|
||||
|
@ -1688,6 +1691,8 @@ static struct fd *alloc_fd_object(void)
|
|||
fd->sharing = 0;
|
||||
fd->unix_fd = -1;
|
||||
fd->unix_name = NULL;
|
||||
fd->nt_name = NULL;
|
||||
fd->nt_namelen = 0;
|
||||
fd->cacheable = 0;
|
||||
fd->signaled = 1;
|
||||
fd->fs_locks = 1;
|
||||
|
@ -1723,6 +1728,8 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
|
|||
fd->options = options;
|
||||
fd->sharing = 0;
|
||||
fd->unix_name = NULL;
|
||||
fd->nt_name = NULL;
|
||||
fd->nt_namelen = 0;
|
||||
fd->unix_fd = -1;
|
||||
fd->cacheable = 0;
|
||||
fd->signaled = 0;
|
||||
|
@ -1755,6 +1762,11 @@ struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sha
|
|||
if (!(fd->unix_name = mem_alloc( strlen(orig->unix_name) + 1 ))) goto failed;
|
||||
strcpy( fd->unix_name, orig->unix_name );
|
||||
}
|
||||
if (orig->nt_namelen)
|
||||
{
|
||||
if (!(fd->nt_name = memdup( orig->nt_name, orig->nt_namelen ))) goto failed;
|
||||
fd->nt_namelen = orig->nt_namelen;
|
||||
}
|
||||
|
||||
if (orig->inode)
|
||||
{
|
||||
|
@ -1831,8 +1843,50 @@ char *dup_fd_name( struct fd *root, const char *name )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *dup_nt_name( struct fd *root, struct unicode_str name, data_size_t *len )
|
||||
{
|
||||
WCHAR *ret;
|
||||
data_size_t retlen;
|
||||
|
||||
if (!root)
|
||||
{
|
||||
*len = name.len;
|
||||
if (!name.len) return NULL;
|
||||
return memdup( name.str, name.len );
|
||||
}
|
||||
if (!root->nt_namelen) return NULL;
|
||||
retlen = root->nt_namelen;
|
||||
|
||||
/* skip . prefix */
|
||||
if (name.len && name.str[0] == '.' && (name.len == sizeof(WCHAR) || name.str[1] == '\\'))
|
||||
{
|
||||
name.str++;
|
||||
name.len -= sizeof(WCHAR);
|
||||
}
|
||||
if ((ret = malloc( retlen + name.len + 1 )))
|
||||
{
|
||||
memcpy( ret, root->nt_name, root->nt_namelen );
|
||||
if (name.len && name.str[0] != '\\' &&
|
||||
root->nt_namelen && root->nt_name[root->nt_namelen / sizeof(WCHAR) - 1] != '\\')
|
||||
{
|
||||
ret[retlen / sizeof(WCHAR)] = '\\';
|
||||
retlen += sizeof(WCHAR);
|
||||
}
|
||||
memcpy( ret + retlen / sizeof(WCHAR), name.str, name.len );
|
||||
*len = retlen + name.len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void get_nt_name( struct fd *fd, struct unicode_str *name )
|
||||
{
|
||||
name->str = fd->nt_name;
|
||||
name->len = fd->nt_namelen;
|
||||
}
|
||||
|
||||
/* open() wrapper that returns a struct fd with no fd user set */
|
||||
struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode, unsigned int access,
|
||||
struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_name,
|
||||
int flags, mode_t *mode, unsigned int access,
|
||||
unsigned int sharing, unsigned int options )
|
||||
{
|
||||
struct stat st;
|
||||
|
@ -1906,6 +1960,7 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
|
|||
}
|
||||
}
|
||||
|
||||
fd->nt_name = dup_nt_name( root, nt_name, &fd->nt_namelen );
|
||||
fd->unix_name = NULL;
|
||||
if ((path = dup_fd_name( root, name )))
|
||||
{
|
||||
|
@ -2437,8 +2492,8 @@ static void set_fd_disposition( struct fd *fd, int unlink )
|
|||
}
|
||||
|
||||
/* set new name for the fd */
|
||||
static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr,
|
||||
data_size_t len, int create_link, int replace )
|
||||
static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, data_size_t len,
|
||||
struct unicode_str nt_name, int create_link, int replace )
|
||||
{
|
||||
struct inode *inode;
|
||||
struct stat st, st2;
|
||||
|
@ -2553,6 +2608,8 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr,
|
|||
fchmod( fd->unix_fd, st.st_mode );
|
||||
}
|
||||
|
||||
free( fd->nt_name );
|
||||
fd->nt_name = dup_nt_name( root, nt_name, &fd->nt_namelen );
|
||||
free( fd->unix_name );
|
||||
fd->closed->unix_name = fd->unix_name = realpath( name, NULL );
|
||||
free( name );
|
||||
|
@ -2824,12 +2881,15 @@ DECL_HANDLER(set_fd_disp_info)
|
|||
DECL_HANDLER(set_fd_name_info)
|
||||
{
|
||||
struct fd *fd, *root_fd = NULL;
|
||||
struct unicode_str nt_name;
|
||||
|
||||
if (req->namelen > get_req_data_size())
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
nt_name.str = get_req_data();
|
||||
nt_name.len = (req->namelen / sizeof(WCHAR)) * sizeof(WCHAR);
|
||||
|
||||
if (req->rootdir)
|
||||
{
|
||||
|
@ -2844,7 +2904,7 @@ DECL_HANDLER(set_fd_name_info)
|
|||
if ((fd = get_handle_fd_obj( current->process, req->handle, 0 )))
|
||||
{
|
||||
set_fd_name( fd, root_fd, (const char *)get_req_data() + req->namelen,
|
||||
get_req_data_size() - req->namelen, req->link, req->replace );
|
||||
get_req_data_size() - req->namelen, nt_name, req->link, req->replace );
|
||||
release_object( fd );
|
||||
}
|
||||
if (root_fd) release_object( root_fd );
|
||||
|
|
|
@ -210,6 +210,7 @@ int is_file_executable( const char *name )
|
|||
}
|
||||
|
||||
static struct object *create_file( struct fd *root, const char *nameptr, data_size_t len,
|
||||
struct unicode_str nt_name,
|
||||
unsigned int access, unsigned int sharing, int create,
|
||||
unsigned int options, unsigned int attrs,
|
||||
const struct security_descriptor *sd )
|
||||
|
@ -220,7 +221,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
|||
char *name;
|
||||
mode_t mode;
|
||||
|
||||
if (!len || ((nameptr[0] == '/') ^ !root))
|
||||
if (!len || ((nameptr[0] == '/') ^ !root) || (nt_name.len && ((nt_name.str[0] == '\\') ^ !root)))
|
||||
{
|
||||
set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
|
||||
return NULL;
|
||||
|
@ -267,7 +268,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
|||
access = map_access( access, &file_type.mapping );
|
||||
|
||||
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
|
||||
fd = open_fd( root, name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
|
||||
fd = open_fd( root, name, nt_name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
|
||||
if (!fd) goto done;
|
||||
|
||||
if (S_ISDIR(mode))
|
||||
|
@ -603,13 +604,15 @@ static struct object *file_open_file( struct object *obj, unsigned int access,
|
|||
{
|
||||
struct file *file = (struct file *)obj;
|
||||
struct object *new_file = NULL;
|
||||
struct unicode_str nt_name;
|
||||
char *unix_name;
|
||||
|
||||
assert( obj->ops == &file_ops );
|
||||
|
||||
if ((unix_name = dup_fd_name( file->fd, "" )))
|
||||
{
|
||||
new_file = create_file( NULL, unix_name, strlen(unix_name), access,
|
||||
get_nt_name( file->fd, &nt_name );
|
||||
new_file = create_file( NULL, unix_name, strlen(unix_name), nt_name, access,
|
||||
sharing, FILE_OPEN, options, 0, NULL );
|
||||
free( unix_name );
|
||||
}
|
||||
|
@ -706,7 +709,7 @@ DECL_HANDLER(create_file)
|
|||
name = get_req_data_after_objattr( objattr, &name_len );
|
||||
|
||||
reply->handle = 0;
|
||||
if ((file = create_file( root_fd, name, name_len, req->access, req->sharing,
|
||||
if ((file = create_file( root_fd, name, name_len, nt_name, req->access, req->sharing,
|
||||
req->create, req->options, req->attrs, sd )))
|
||||
{
|
||||
reply->handle = alloc_handle( current->process, file, req->access, objattr->attributes );
|
||||
|
|
|
@ -78,8 +78,9 @@ struct fd_ops
|
|||
|
||||
extern struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *user,
|
||||
unsigned int options );
|
||||
extern struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
|
||||
unsigned int access, unsigned int sharing, unsigned int options );
|
||||
extern struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_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,
|
||||
int unix_fd, struct object *user, unsigned int options );
|
||||
extern struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sharing,
|
||||
|
@ -100,6 +101,7 @@ extern void unlock_fd( struct fd *fd, file_pos_t offset, file_pos_t count );
|
|||
extern void allow_fd_caching( struct fd *fd );
|
||||
extern void set_fd_signaled( struct fd *fd, int signaled );
|
||||
extern char *dup_fd_name( struct fd *root, const char *name );
|
||||
extern void get_nt_name( struct fd *fd, struct unicode_str *name );
|
||||
|
||||
extern int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||
extern int default_fd_get_poll_events( struct fd *fd );
|
||||
|
|
|
@ -264,6 +264,9 @@ static char *get_nls_dir(void)
|
|||
struct fd *load_intl_file(void)
|
||||
{
|
||||
static const char *nls_dirs[] = { NULL, NLSDIR, "/usr/local/share/wine/nls", "/usr/share/wine/nls" };
|
||||
static const WCHAR nt_pathW[] = {'C',':','\\','w','i','n','d','o','w','s','\\',
|
||||
's','y','s','t','e','m','3','2','\\','l','_','i','n','t','l','.','n','l','s',0};
|
||||
static const struct unicode_str nt_name = { nt_pathW, sizeof(nt_pathW) };
|
||||
unsigned int i, offset, size;
|
||||
unsigned short data;
|
||||
char *path;
|
||||
|
@ -278,7 +281,7 @@ struct fd *load_intl_file(void)
|
|||
if (!(path = malloc( strlen(nls_dirs[i]) + sizeof("/l_intl.nls" )))) continue;
|
||||
strcpy( path, nls_dirs[i] );
|
||||
strcat( path, "/l_intl.nls" );
|
||||
if ((fd = open_fd( NULL, path, O_RDONLY, &mode, FILE_READ_DATA,
|
||||
if ((fd = open_fd( NULL, path, nt_name, O_RDONLY, &mode, FILE_READ_DATA,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) break;
|
||||
free( path );
|
||||
|
|
Loading…
Reference in New Issue