server: Implement open_file_object for rootdir pointing to file object.
This commit is contained in:
parent
84d2610aaf
commit
ec851647e2
@ -466,8 +466,8 @@ static void open_file_test(void)
|
|||||||
attr.ObjectName = &nameW;
|
attr.ObjectName = &nameW;
|
||||||
status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
|
status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
|
||||||
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT );
|
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT );
|
||||||
todo_wine ok( status == STATUS_OBJECT_PATH_NOT_FOUND,
|
ok( status == STATUS_OBJECT_PATH_NOT_FOUND,
|
||||||
"expected STATUS_OBJECT_PATH_NOT_FOUND, got %08x\n", status );
|
"expected STATUS_OBJECT_PATH_NOT_FOUND, got %08x\n", status );
|
||||||
|
|
||||||
nameW.Length = 0;
|
nameW.Length = 0;
|
||||||
nameW.Buffer = NULL;
|
nameW.Buffer = NULL;
|
||||||
@ -475,24 +475,24 @@ static void open_file_test(void)
|
|||||||
attr.ObjectName = &nameW;
|
attr.ObjectName = &nameW;
|
||||||
status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
|
status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
|
||||||
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT );
|
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT );
|
||||||
todo_wine ok( !status, "open %s failed %x\n", wine_dbgstr_w(tmpfile), status );
|
ok( !status, "open %s failed %x\n", wine_dbgstr_w(tmpfile), status );
|
||||||
|
|
||||||
numbytes = SetFilePointer( file, 0, 0, FILE_CURRENT );
|
numbytes = SetFilePointer( file, 0, 0, FILE_CURRENT );
|
||||||
ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes );
|
ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes );
|
||||||
numbytes = SetFilePointer( root, 0, 0, FILE_CURRENT );
|
numbytes = SetFilePointer( root, 0, 0, FILE_CURRENT );
|
||||||
todo_wine ok( numbytes == 0, "SetFilePointer returned %u\n", numbytes );
|
ok( numbytes == 0, "SetFilePointer returned %u\n", numbytes );
|
||||||
|
|
||||||
numbytes = 0xdeadbeef;
|
numbytes = 0xdeadbeef;
|
||||||
memset( data, 0, sizeof(data) );
|
memset( data, 0, sizeof(data) );
|
||||||
ret = ReadFile( root, data, sizeof(data), &numbytes, NULL );
|
ret = ReadFile( root, data, sizeof(data), &numbytes, NULL );
|
||||||
todo_wine ok( ret, "ReadFile failed with error %u\n", GetLastError() );
|
ok( ret, "ReadFile failed with error %u\n", GetLastError() );
|
||||||
todo_wine ok( numbytes == sizeof(testdata) - 1, "failed to read all data\n" );
|
ok( numbytes == sizeof(testdata) - 1, "failed to read all data\n" );
|
||||||
todo_wine ok( !memcmp( data, testdata, sizeof(testdata) - 1 ), "testdata doesn't match\n" );
|
ok( !memcmp( data, testdata, sizeof(testdata) - 1 ), "testdata doesn't match\n" );
|
||||||
|
|
||||||
numbytes = SetFilePointer( file, 0, 0, FILE_CURRENT );
|
numbytes = SetFilePointer( file, 0, 0, FILE_CURRENT );
|
||||||
ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes );
|
ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes );
|
||||||
numbytes = SetFilePointer( root, 0, 0, FILE_CURRENT );
|
numbytes = SetFilePointer( root, 0, 0, FILE_CURRENT );
|
||||||
todo_wine ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes );
|
ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes );
|
||||||
|
|
||||||
CloseHandle( file );
|
CloseHandle( file );
|
||||||
CloseHandle( root );
|
CloseHandle( root );
|
||||||
|
29
server/fd.c
29
server/fd.c
@ -1717,7 +1717,7 @@ void set_fd_user( struct fd *fd, const struct fd_ops *user_ops, struct object *u
|
|||||||
fd->user = user;
|
fd->user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *dup_fd_name( struct fd *root, const char *name )
|
char *dup_fd_name( struct fd *root, const char *name )
|
||||||
{
|
{
|
||||||
char *ret;
|
char *ret;
|
||||||
|
|
||||||
@ -2386,19 +2386,30 @@ DECL_HANDLER(open_file_object)
|
|||||||
|
|
||||||
get_req_unicode_str( &name );
|
get_req_unicode_str( &name );
|
||||||
if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
|
if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
|
||||||
return;
|
|
||||||
|
|
||||||
if ((obj = open_object_dir( root, &name, req->attributes, NULL )))
|
|
||||||
{
|
{
|
||||||
if ((result = obj->ops->open_file( obj, req->access, req->sharing, req->options )))
|
if (get_error() != STATUS_OBJECT_TYPE_MISMATCH) return;
|
||||||
|
if (!(obj = (struct object *)get_file_obj( current->process, req->rootdir, 0 ))) return;
|
||||||
|
if (name.len)
|
||||||
{
|
{
|
||||||
reply->handle = alloc_handle( current->process, result, req->access, req->attributes );
|
release_object( obj );
|
||||||
release_object( result );
|
set_error( STATUS_OBJECT_PATH_NOT_FOUND );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
release_object( obj );
|
clear_error();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj = open_object_dir( root, &name, req->attributes, NULL );
|
||||||
|
if (root) release_object( root );
|
||||||
|
if (!obj) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root) release_object( root );
|
if ((result = obj->ops->open_file( obj, req->access, req->sharing, req->options )))
|
||||||
|
{
|
||||||
|
reply->handle = alloc_handle( current->process, result, req->access, req->attributes );
|
||||||
|
release_object( result );
|
||||||
|
}
|
||||||
|
release_object( obj );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the Unix name from a file handle */
|
/* get the Unix name from a file handle */
|
||||||
|
@ -68,6 +68,8 @@ static struct object_type *file_get_type( struct object *obj );
|
|||||||
static struct fd *file_get_fd( struct object *obj );
|
static struct fd *file_get_fd( struct object *obj );
|
||||||
static struct security_descriptor *file_get_sd( struct object *obj );
|
static struct security_descriptor *file_get_sd( struct object *obj );
|
||||||
static int file_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info );
|
static int file_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info );
|
||||||
|
static struct object *file_open_file( struct object *obj, unsigned int access,
|
||||||
|
unsigned int sharing, unsigned int options );
|
||||||
static void file_destroy( struct object *obj );
|
static void file_destroy( struct object *obj );
|
||||||
|
|
||||||
static int file_get_poll_events( struct fd *fd );
|
static int file_get_poll_events( struct fd *fd );
|
||||||
@ -89,7 +91,7 @@ static const struct object_ops file_ops =
|
|||||||
file_get_sd, /* get_sd */
|
file_get_sd, /* get_sd */
|
||||||
file_set_sd, /* set_sd */
|
file_set_sd, /* set_sd */
|
||||||
no_lookup_name, /* lookup_name */
|
no_lookup_name, /* lookup_name */
|
||||||
no_open_file, /* open_file */
|
file_open_file, /* open_file */
|
||||||
fd_close_handle, /* close_handle */
|
fd_close_handle, /* close_handle */
|
||||||
file_destroy /* destroy */
|
file_destroy /* destroy */
|
||||||
};
|
};
|
||||||
@ -605,6 +607,25 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct object *file_open_file( struct object *obj, unsigned int access,
|
||||||
|
unsigned int sharing, unsigned int options )
|
||||||
|
{
|
||||||
|
struct file *file = (struct file *)obj;
|
||||||
|
struct object *new_file = NULL;
|
||||||
|
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,
|
||||||
|
sharing, FILE_OPEN, options, 0, NULL );
|
||||||
|
free( unix_name );
|
||||||
|
}
|
||||||
|
else set_error( STATUS_OBJECT_TYPE_MISMATCH );
|
||||||
|
return new_file;
|
||||||
|
}
|
||||||
|
|
||||||
static void file_destroy( struct object *obj )
|
static void file_destroy( struct object *obj )
|
||||||
{
|
{
|
||||||
struct file *file = (struct file *)obj;
|
struct file *file = (struct file *)obj;
|
||||||
|
@ -81,6 +81,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 int is_fd_signaled( struct fd *fd );
|
extern int is_fd_signaled( struct fd *fd );
|
||||||
|
extern char *dup_fd_name( struct fd *root, const char *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 unsigned int default_fd_map_access( struct object *obj, unsigned int access );
|
extern unsigned int default_fd_map_access( struct object *obj, unsigned int access );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user