From eb2fe39d63dfd6fe0ad7a11f55657f42cabff070 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 18 Apr 2011 13:41:54 +0200 Subject: [PATCH] server: Add support for opening a new file handle from a mapping object. --- server/file.c | 25 +++++++++++++++++++++++++ server/file.h | 9 +++++++++ server/mapping.c | 25 +++++++++++++++++++++---- server/object.h | 4 ---- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/server/file.c b/server/file.c index 8cf474bd79..ce95576e2e 100644 --- a/server/file.c +++ b/server/file.c @@ -141,6 +141,31 @@ struct file *create_file_for_fd( int fd, unsigned int access, unsigned int shari return file; } +/* create a file by duplicating an fd object */ +struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigned int sharing ) +{ + struct file *file; + struct stat st; + + if (fstat( get_unix_fd(fd), &st ) == -1) + { + file_set_error(); + return NULL; + } + + if ((file = alloc_object( &file_ops ))) + { + file->mode = st.st_mode; + file->access = default_fd_map_access( &file->obj, access ); + if (!(file->fd = dup_fd_object( fd, access, sharing, FILE_SYNCHRONOUS_IO_NONALERT ))) + { + release_object( file ); + return NULL; + } + } + return file; +} + static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_t mode ) { struct file *file = alloc_object( &file_ops ); diff --git a/server/file.h b/server/file.h index 26290a3896..772c9b8493 100644 --- a/server/file.h +++ b/server/file.h @@ -116,11 +116,20 @@ extern struct file *get_file_obj( struct process *process, obj_handle_t handle, extern int get_file_unix_fd( struct file *file ); extern int is_same_file( struct file *file1, struct file *file2 ); extern struct file *create_file_for_fd( int fd, unsigned int access, unsigned int sharing ); +extern struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigned int sharing ); extern struct file *grab_file_unless_removable( struct file *file ); extern void file_set_error(void); extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group ); extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ); +/* file mapping functions */ + +extern struct mapping *get_mapping_obj( struct process *process, obj_handle_t handle, + unsigned int access ); +extern obj_handle_t open_mapping_file( struct process *process, struct mapping *mapping, + unsigned int access, unsigned int sharing ); +extern int get_page_size(void); + /* change notification functions */ extern void do_change_notify( int unix_fd ); diff --git a/server/mapping.c b/server/mapping.c index 5c77989128..01622e8bab 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -565,6 +565,24 @@ static struct object *create_mapping( struct directory *root, const struct unico return NULL; } +struct mapping *get_mapping_obj( struct process *process, obj_handle_t handle, unsigned int access ) +{ + return (struct mapping *)get_handle_obj( process, handle, access, &mapping_ops ); +} + +/* open a new file handle to the file backing the mapping */ +obj_handle_t open_mapping_file( struct process *process, struct mapping *mapping, + unsigned int access, unsigned int sharing ) +{ + obj_handle_t handle; + struct file *file = create_file_for_fd_obj( mapping->fd, access, sharing ); + + if (!file) return 0; + handle = alloc_handle( process, file, access, 0 ); + release_object( file ); + return handle; +} + static void mapping_dump( struct object *obj, int verbose ) { struct mapping *mapping = (struct mapping *)obj; @@ -682,8 +700,7 @@ DECL_HANDLER(get_mapping_info) struct mapping *mapping; struct fd *fd; - if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle, - req->access, &mapping_ops ))) + if ((mapping = get_mapping_obj( current->process, req->handle, req->access ))) { reply->size = mapping->size; reply->protect = mapping->protect; @@ -713,7 +730,7 @@ DECL_HANDLER(get_mapping_committed_range) { struct mapping *mapping; - if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle, 0, &mapping_ops ))) + if ((mapping = get_mapping_obj( current->process, req->handle, 0 ))) { if (!(req->offset & page_mask) && req->offset < mapping->size) reply->committed = find_committed_range( mapping, req->offset, &reply->size ); @@ -729,7 +746,7 @@ DECL_HANDLER(add_mapping_committed_range) { struct mapping *mapping; - if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle, 0, &mapping_ops ))) + if ((mapping = get_mapping_obj( current->process, req->handle, 0 ))) { if (!(req->size & page_mask) && !(req->offset & page_mask) && diff --git a/server/object.h b/server/object.h index 172c3f763a..a8cb3276fd 100644 --- a/server/object.h +++ b/server/object.h @@ -180,10 +180,6 @@ extern void generate_debug_event( struct thread *thread, int code, const void *a extern void generate_startup_debug_events( struct process *process, client_ptr_t entry ); extern void debug_exit_thread( struct thread *thread ); -/* mapping functions */ - -extern int get_page_size(void); - /* registry functions */ extern unsigned int get_prefix_cpu_mask(void); -- 2.32.0.93.g670b81a890