Commit bb009426 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Store the NT name in the fd object.

parent 9e255ba4
...@@ -446,6 +446,7 @@ static struct object *device_open_file( struct object *obj, unsigned int access, ...@@ -446,6 +446,7 @@ static struct object *device_open_file( struct object *obj, unsigned int access,
{ {
struct device *device = (struct device *)obj; struct device *device = (struct device *)obj;
struct device_file *file; struct device_file *file;
struct unicode_str nt_name;
if (!(file = alloc_object( &device_file_ops ))) return NULL; 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, ...@@ -458,7 +459,8 @@ static struct object *device_open_file( struct object *obj, unsigned int access,
{ {
mode_t mode = 0666; mode_t mode = 0666;
access = file->obj.ops->map_access( &file->obj, access ); 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 ); &mode, access, sharing, options );
if (file->fd) set_fd_user( file->fd, &device_file_fd_ops, &file->obj ); if (file->fd) set_fd_user( file->fd, &device_file_fd_ops, &file->obj );
} }
......
...@@ -185,6 +185,8 @@ struct fd ...@@ -185,6 +185,8 @@ struct fd
unsigned int options; /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */ unsigned int options; /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
unsigned int sharing; /* file sharing mode */ unsigned int sharing; /* file sharing mode */
char *unix_name; /* unix file name */ 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 */ int unix_fd; /* unix file descriptor */
unsigned int no_fd_status;/* status to return when unix_fd is -1 */ 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? */ unsigned int cacheable :1;/* can the fd be cached on the client side? */
...@@ -1570,6 +1572,7 @@ static void fd_destroy( struct object *obj ) ...@@ -1570,6 +1572,7 @@ static void fd_destroy( struct object *obj )
remove_fd_locks( fd ); remove_fd_locks( fd );
list_remove( &fd->inode_entry ); list_remove( &fd->inode_entry );
if (fd->poll_index != -1) remove_poll_user( fd, fd->poll_index ); if (fd->poll_index != -1) remove_poll_user( fd, fd->poll_index );
free( fd->nt_name );
if (fd->inode) if (fd->inode)
{ {
inode_add_closed_fd( fd->inode, fd->closed ); inode_add_closed_fd( fd->inode, fd->closed );
...@@ -1688,6 +1691,8 @@ static struct fd *alloc_fd_object(void) ...@@ -1688,6 +1691,8 @@ static struct fd *alloc_fd_object(void)
fd->sharing = 0; fd->sharing = 0;
fd->unix_fd = -1; fd->unix_fd = -1;
fd->unix_name = NULL; fd->unix_name = NULL;
fd->nt_name = NULL;
fd->nt_namelen = 0;
fd->cacheable = 0; fd->cacheable = 0;
fd->signaled = 1; fd->signaled = 1;
fd->fs_locks = 1; fd->fs_locks = 1;
...@@ -1723,6 +1728,8 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use ...@@ -1723,6 +1728,8 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
fd->options = options; fd->options = options;
fd->sharing = 0; fd->sharing = 0;
fd->unix_name = NULL; fd->unix_name = NULL;
fd->nt_name = NULL;
fd->nt_namelen = 0;
fd->unix_fd = -1; fd->unix_fd = -1;
fd->cacheable = 0; fd->cacheable = 0;
fd->signaled = 0; fd->signaled = 0;
...@@ -1755,6 +1762,11 @@ struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sha ...@@ -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; if (!(fd->unix_name = mem_alloc( strlen(orig->unix_name) + 1 ))) goto failed;
strcpy( fd->unix_name, orig->unix_name ); 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) if (orig->inode)
{ {
...@@ -1831,8 +1843,50 @@ char *dup_fd_name( struct fd *root, const char *name ) ...@@ -1831,8 +1843,50 @@ char *dup_fd_name( struct fd *root, const char *name )
return ret; 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 */ /* 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 ) unsigned int sharing, unsigned int options )
{ {
struct stat st; struct stat st;
...@@ -1906,6 +1960,7 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode, ...@@ -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; fd->unix_name = NULL;
if ((path = dup_fd_name( root, name ))) if ((path = dup_fd_name( root, name )))
{ {
...@@ -2437,8 +2492,8 @@ static void set_fd_disposition( struct fd *fd, int unlink ) ...@@ -2437,8 +2492,8 @@ static void set_fd_disposition( struct fd *fd, int unlink )
} }
/* set new name for the fd */ /* set new name for the fd */
static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, data_size_t len,
data_size_t len, int create_link, int replace ) struct unicode_str nt_name, int create_link, int replace )
{ {
struct inode *inode; struct inode *inode;
struct stat st, st2; struct stat st, st2;
...@@ -2553,6 +2608,8 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, ...@@ -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 ); 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 ); free( fd->unix_name );
fd->closed->unix_name = fd->unix_name = realpath( name, NULL ); fd->closed->unix_name = fd->unix_name = realpath( name, NULL );
free( name ); free( name );
...@@ -2824,12 +2881,15 @@ DECL_HANDLER(set_fd_disp_info) ...@@ -2824,12 +2881,15 @@ DECL_HANDLER(set_fd_disp_info)
DECL_HANDLER(set_fd_name_info) DECL_HANDLER(set_fd_name_info)
{ {
struct fd *fd, *root_fd = NULL; struct fd *fd, *root_fd = NULL;
struct unicode_str nt_name;
if (req->namelen > get_req_data_size()) if (req->namelen > get_req_data_size())
{ {
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return; return;
} }
nt_name.str = get_req_data();
nt_name.len = (req->namelen / sizeof(WCHAR)) * sizeof(WCHAR);
if (req->rootdir) if (req->rootdir)
{ {
...@@ -2844,7 +2904,7 @@ DECL_HANDLER(set_fd_name_info) ...@@ -2844,7 +2904,7 @@ DECL_HANDLER(set_fd_name_info)
if ((fd = get_handle_fd_obj( current->process, req->handle, 0 ))) if ((fd = get_handle_fd_obj( current->process, req->handle, 0 )))
{ {
set_fd_name( fd, root_fd, (const char *)get_req_data() + req->namelen, 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 ); release_object( fd );
} }
if (root_fd) release_object( root_fd ); if (root_fd) release_object( root_fd );
......
...@@ -210,6 +210,7 @@ int is_file_executable( const char *name ) ...@@ -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, 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 access, unsigned int sharing, int create,
unsigned int options, unsigned int attrs, unsigned int options, unsigned int attrs,
const struct security_descriptor *sd ) const struct security_descriptor *sd )
...@@ -220,7 +221,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si ...@@ -220,7 +221,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
char *name; char *name;
mode_t mode; 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 ); set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
return NULL; return NULL;
...@@ -267,7 +268,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si ...@@ -267,7 +268,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
access = map_access( access, &file_type.mapping ); access = map_access( access, &file_type.mapping );
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */ /* 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 (!fd) goto done;
if (S_ISDIR(mode)) if (S_ISDIR(mode))
...@@ -603,13 +604,15 @@ static struct object *file_open_file( struct object *obj, unsigned int access, ...@@ -603,13 +604,15 @@ static struct object *file_open_file( struct object *obj, unsigned int access,
{ {
struct file *file = (struct file *)obj; struct file *file = (struct file *)obj;
struct object *new_file = NULL; struct object *new_file = NULL;
struct unicode_str nt_name;
char *unix_name; char *unix_name;
assert( obj->ops == &file_ops ); assert( obj->ops == &file_ops );
if ((unix_name = dup_fd_name( file->fd, "" ))) 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 ); sharing, FILE_OPEN, options, 0, NULL );
free( unix_name ); free( unix_name );
} }
...@@ -706,7 +709,7 @@ DECL_HANDLER(create_file) ...@@ -706,7 +709,7 @@ DECL_HANDLER(create_file)
name = get_req_data_after_objattr( objattr, &name_len ); name = get_req_data_after_objattr( objattr, &name_len );
reply->handle = 0; 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 ))) req->create, req->options, req->attrs, sd )))
{ {
reply->handle = alloc_handle( current->process, file, req->access, objattr->attributes ); reply->handle = alloc_handle( current->process, file, req->access, objattr->attributes );
......
...@@ -78,8 +78,9 @@ struct fd_ops ...@@ -78,8 +78,9 @@ struct fd_ops
extern struct fd *alloc_pseudo_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,
unsigned int options ); unsigned int options );
extern struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode, extern struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_name,
unsigned int access, unsigned int sharing, unsigned int options ); 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, extern struct fd *create_anonymous_fd( const struct fd_ops *fd_user_ops,
int unix_fd, struct object *user, unsigned int options ); int unix_fd, struct object *user, unsigned int options );
extern struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sharing, 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 ); ...@@ -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 allow_fd_caching( struct fd *fd );
extern void set_fd_signaled( struct fd *fd, int signaled ); extern void set_fd_signaled( struct fd *fd, int signaled );
extern char *dup_fd_name( struct fd *root, const char *name ); 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_signaled( struct object *obj, struct wait_queue_entry *entry );
extern int default_fd_get_poll_events( struct fd *fd ); extern int default_fd_get_poll_events( struct fd *fd );
......
...@@ -264,6 +264,9 @@ static char *get_nls_dir(void) ...@@ -264,6 +264,9 @@ static char *get_nls_dir(void)
struct fd *load_intl_file(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 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 int i, offset, size;
unsigned short data; unsigned short data;
char *path; char *path;
...@@ -278,7 +281,7 @@ struct fd *load_intl_file(void) ...@@ -278,7 +281,7 @@ struct fd *load_intl_file(void)
if (!(path = malloc( strlen(nls_dirs[i]) + sizeof("/l_intl.nls" )))) continue; if (!(path = malloc( strlen(nls_dirs[i]) + sizeof("/l_intl.nls" )))) continue;
strcpy( path, nls_dirs[i] ); strcpy( path, nls_dirs[i] );
strcat( path, "/l_intl.nls" ); 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_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) break; FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) break;
free( path ); free( path );
......
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