diff --git a/dlls/kernel/tests/sync.c b/dlls/kernel/tests/sync.c index 5c7f92fc1b6..6d7bc88762d 100644 --- a/dlls/kernel/tests/sync.c +++ b/dlls/kernel/tests/sync.c @@ -109,9 +109,7 @@ static void test_signalandwait(void) FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL); r = pSignalObjectAndWait(file, file, 0, FALSE); ok( r == WAIT_FAILED, "should fail\n"); - todo_wine { ok( ERROR_INVALID_HANDLE == GetLastError(), "should return invalid handle error\n"); - } CloseHandle(file); } diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index 88c00156fa6..e2647cafdfe 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -484,6 +484,11 @@ int wine_server_handle_to_fd( obj_handle_t handle, unsigned int access, int *uni obj_handle_t fd_handle; int ret, removable = -1, fd = -1; + /* FIXME: callers should be fixed to pass the appropriate specific rights */ + if (access & GENERIC_READ) access |= FILE_READ_DATA; + if (access & GENERIC_WRITE) access |= FILE_WRITE_DATA; + access &= ~(GENERIC_READ|GENERIC_WRITE); + RtlEnterCriticalSection( &fd_cache_section ); *unix_fd = -1; diff --git a/server/directory.c b/server/directory.c index d4ec59b87fb..e00687a7e08 100644 --- a/server/directory.c +++ b/server/directory.c @@ -48,6 +48,7 @@ struct directory }; static void directory_dump( struct object *obj, int verbose ); +static unsigned int directory_map_access( struct object *obj, unsigned int access ); static struct object *directory_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); static void directory_destroy( struct object *obj ); @@ -62,7 +63,7 @@ static const struct object_ops directory_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ - no_map_access, /* map_access */ + directory_map_access, /* map_access */ directory_lookup_name, /* lookup_name */ no_close_handle, /* close_handle */ directory_destroy /* destroy */ @@ -121,6 +122,15 @@ static struct object *directory_lookup_name( struct object *obj, struct unicode_ return NULL; } +static unsigned int directory_map_access( struct object *obj, unsigned int access ) +{ + if (access & GENERIC_READ) access |= FILE_GENERIC_READ; + if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; + if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; + if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); +} + static void directory_destroy( struct object *obj ) { struct directory *dir = (struct directory *)obj; diff --git a/server/fd.c b/server/fd.c index 7ed113f382a..5c4efd4c8d2 100644 --- a/server/fd.c +++ b/server/fd.c @@ -142,7 +142,7 @@ struct fd struct closed_fd *closed; /* structure to store the unix fd at destroy time */ struct object *user; /* object using this file descriptor */ struct list locks; /* list of locks on this fd */ - unsigned int access; /* file access (GENERIC_READ/WRITE) */ + unsigned int access; /* file access (FILE_READ_DATA etc.) */ unsigned int sharing; /* file sharing mode */ int unix_fd; /* unix file descriptor */ int fs_locks :1; /* can we use filesystem locks for this fd? */ @@ -1302,10 +1302,10 @@ static int check_sharing( struct fd *fd, unsigned int access, unsigned int shari } } - if ((access & GENERIC_READ) && !(existing_sharing & FILE_SHARE_READ)) return 0; - if ((access & GENERIC_WRITE) && !(existing_sharing & FILE_SHARE_WRITE)) return 0; - if ((existing_access & GENERIC_READ) && !(sharing & FILE_SHARE_READ)) return 0; - if ((existing_access & GENERIC_WRITE) && !(sharing & FILE_SHARE_WRITE)) return 0; + if ((access & FILE_UNIX_READ_ACCESS) && !(existing_sharing & FILE_SHARE_READ)) return 0; + if ((access & FILE_UNIX_WRITE_ACCESS) && !(existing_sharing & FILE_SHARE_WRITE)) return 0; + if ((existing_access & FILE_UNIX_READ_ACCESS) && !(sharing & FILE_SHARE_READ)) return 0; + if ((existing_access & FILE_UNIX_WRITE_ACCESS) && !(sharing & FILE_SHARE_WRITE)) return 0; if (fd->closed->unlink[0] && !(existing_sharing & FILE_SHARE_DELETE)) return 0; if (unlink && !(sharing & FILE_SHARE_DELETE)) return 0; return 1; diff --git a/server/file.c b/server/file.c index 8e97f6d17fe..84215c53ef3 100644 --- a/server/file.c +++ b/server/file.c @@ -57,12 +57,13 @@ struct file { struct object obj; /* object header */ struct fd *fd; /* file descriptor for this file */ - unsigned int access; /* file access (GENERIC_READ/WRITE) */ + unsigned int access; /* file access (FILE_READ_DATA etc.) */ unsigned int options; /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */ }; static void file_dump( struct object *obj, int verbose ); static struct fd *file_get_fd( struct object *obj ); +static unsigned int file_map_access( struct object *obj, unsigned int access ); static void file_destroy( struct object *obj ); static int file_get_poll_events( struct fd *fd ); @@ -79,7 +80,7 @@ static const struct object_ops file_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ file_get_fd, /* get_fd */ - no_map_access, /* map_access */ + file_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_close_handle, /* close_handle */ file_destroy /* destroy */ @@ -108,7 +109,7 @@ static struct file *create_file_for_fd( int fd, unsigned int access, unsigned in if ((file = alloc_object( &file_ops ))) { - file->access = access; + file->access = file_map_access( &file->obj, access ); file->options = FILE_SYNCHRONOUS_IO_NONALERT; if (!(file->fd = create_anonymous_fd( &file_fd_ops, fd, &file->obj ))) { @@ -125,7 +126,7 @@ static struct object *create_file( const char *nameptr, size_t len, unsigned int unsigned int attrs ) { struct file *file; - int flags; + int flags, rw_mode; char *name; mode_t mode; @@ -144,13 +145,6 @@ static struct object *create_file( const char *nameptr, size_t len, unsigned int default: set_error( STATUS_INVALID_PARAMETER ); goto error; } - switch(access & (GENERIC_READ | GENERIC_WRITE)) - { - case 0: break; - case GENERIC_READ: flags |= O_RDONLY; break; - case GENERIC_WRITE: flags |= O_WRONLY; break; - case GENERIC_READ|GENERIC_WRITE: flags |= O_RDWR; break; - } mode = (attrs & FILE_ATTRIBUTE_READONLY) ? 0444 : 0666; if (len >= 4 && @@ -159,13 +153,24 @@ static struct object *create_file( const char *nameptr, size_t len, unsigned int if (!(file = alloc_object( &file_ops ))) goto error; - file->access = access; + file->access = file_map_access( &file->obj, access ); file->options = options; + rw_mode = 0; + if (file->access & FILE_UNIX_READ_ACCESS) rw_mode |= FILE_READ_DATA; + if (file->access & FILE_UNIX_WRITE_ACCESS) rw_mode |= FILE_WRITE_DATA; + switch(rw_mode) + { + case 0: break; + case FILE_READ_DATA: flags |= O_RDONLY; break; + case FILE_WRITE_DATA: flags |= O_WRONLY; break; + case FILE_READ_DATA|FILE_WRITE_DATA: flags |= O_RDWR; break; + } + /* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */ if (!(file->fd = alloc_fd( &file_fd_ops, &file->obj )) || !(file->fd = open_fd( file->fd, name, flags | O_NONBLOCK | O_LARGEFILE, - &mode, access, sharing, options ))) + &mode, file->access, sharing, options ))) { free( name ); release_object( file ); @@ -223,8 +228,8 @@ static int file_get_poll_events( struct fd *fd ) struct file *file = get_fd_user( fd ); int events = 0; assert( file->obj.ops == &file_ops ); - if (file->access & GENERIC_READ) events |= POLLIN; - if (file->access & GENERIC_WRITE) events |= POLLOUT; + if (file->access & FILE_UNIX_READ_ACCESS) events |= POLLIN; + if (file->access & FILE_UNIX_WRITE_ACCESS) events |= POLLOUT; return events; } @@ -255,6 +260,15 @@ static struct fd *file_get_fd( struct object *obj ) return (struct fd *)grab_object( file->fd ); } +static unsigned int file_map_access( struct object *obj, unsigned int access ) +{ + if (access & GENERIC_READ) access |= FILE_GENERIC_READ; + if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; + if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; + if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); +} + static void file_destroy( struct object *obj ) { struct file *file = (struct file *)obj; diff --git a/server/file.h b/server/file.h index 4419998eb6f..a4e8c7aaebd 100644 --- a/server/file.h +++ b/server/file.h @@ -125,4 +125,10 @@ static inline void async_terminate_queue( struct list *queue, int status ) while (!list_empty( queue )) async_terminate_head( queue, status ); } +/* access rights that require Unix read permission */ +#define FILE_UNIX_READ_ACCESS (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA) + +/* access rights that require Unix write permission */ +#define FILE_UNIX_WRITE_ACCESS (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA) + #endif /* __WINE_SERVER_FILE_H */ diff --git a/server/mailslot.c b/server/mailslot.c index 00cc8b1ee44..b6344d28b1b 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -62,16 +62,10 @@ struct mailslot struct list writers; }; -struct mailslot_device -{ - struct object obj; /* object header */ - struct fd *fd; /* pseudo-fd for ioctls */ - struct namespace *mailslots; /* mailslot namespace */ -}; - /* mailslot functions */ static void mailslot_dump( struct object*, int ); static struct fd *mailslot_get_fd( struct object * ); +static unsigned int mailslot_map_access( struct object *obj, unsigned int access ); static void mailslot_destroy( struct object * ); static const struct object_ops mailslot_ops = @@ -84,7 +78,7 @@ static const struct object_ops mailslot_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ mailslot_get_fd, /* get_fd */ - no_map_access, /* map_access */ + mailslot_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_close_handle, /* close_handle */ mailslot_destroy /* destroy */ @@ -103,17 +97,19 @@ static const struct fd_ops mailslot_fd_ops = default_fd_cancel_async /* cancel_async */ }; + struct mail_writer { struct object obj; struct mailslot *mailslot; struct list entry; - int access; - int sharing; + unsigned int access; + unsigned int sharing; }; static void mail_writer_dump( struct object *obj, int verbose ); static struct fd *mail_writer_get_fd( struct object *obj ); +static unsigned int mail_writer_map_access( struct object *obj, unsigned int access ); static void mail_writer_destroy( struct object *obj); static const struct object_ops mail_writer_ops = @@ -126,7 +122,7 @@ static const struct object_ops mail_writer_ops = NULL, /* satisfied */ no_signal, /* signal */ mail_writer_get_fd, /* get_fd */ - no_map_access, /* map_access */ + mail_writer_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_close_handle, /* close_handle */ mail_writer_destroy /* destroy */ @@ -144,6 +140,14 @@ static const struct fd_ops mail_writer_fd_ops = NULL /* cancel_async */ }; + +struct mailslot_device +{ + struct object obj; /* object header */ + struct fd *fd; /* pseudo-fd for ioctls */ + struct namespace *mailslots; /* mailslot namespace */ +}; + static void mailslot_device_dump( struct object *obj, int verbose ); static struct fd *mailslot_device_get_fd( struct object *obj ); static struct object *mailslot_device_lookup_name( struct object *obj, struct unicode_str *name, @@ -231,6 +235,15 @@ static struct fd *mailslot_get_fd( struct object *obj ) return (struct fd *)grab_object( mailslot->fd ); } +static unsigned int mailslot_map_access( struct object *obj, unsigned int access ) +{ + if (access & GENERIC_READ) access |= FILE_GENERIC_READ; + if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; + if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; + if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); +} + static void mailslot_queue_async( struct fd *fd, void *apc, void *user, void *iosb, int type, int count ) { @@ -396,6 +409,15 @@ static struct fd *mail_writer_get_fd( struct object *obj ) return (struct fd *)grab_object( writer->mailslot->write_fd ); } +static unsigned int mail_writer_map_access( struct object *obj, unsigned int access ) +{ + if (access & GENERIC_READ) access |= FILE_GENERIC_READ; + if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; + if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; + if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); +} + /* * Readers and writers cannot be mixed. * If there's more than one writer, all writers must open with FILE_SHARE_WRITE @@ -409,7 +431,7 @@ static struct mail_writer *create_mail_writer( struct mailslot *mailslot, unsign { writer = LIST_ENTRY( list_head(&mailslot->writers), struct mail_writer, entry ); - if (((access & GENERIC_WRITE) || (writer->access & GENERIC_WRITE)) && + if (((access & (GENERIC_WRITE|FILE_WRITE_DATA)) || (writer->access & FILE_WRITE_DATA)) && !((sharing & FILE_SHARE_WRITE) && (writer->sharing & FILE_SHARE_WRITE))) { set_error( STATUS_SHARING_VIOLATION ); @@ -423,8 +445,8 @@ static struct mail_writer *create_mail_writer( struct mailslot *mailslot, unsign grab_object( mailslot ); writer->mailslot = mailslot; - writer->access = access; - writer->sharing = sharing; + writer->access = mail_writer_map_access( &writer->obj, access ); + writer->sharing = sharing; list_add_head( &mailslot->writers, &writer->entry ); diff --git a/server/mapping.c b/server/mapping.c index 2c2daf111f3..6701e445271 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -53,6 +53,7 @@ struct mapping static void mapping_dump( struct object *obj, int verbose ); static struct fd *mapping_get_fd( struct object *obj ); +static unsigned int mapping_map_access( struct object *obj, unsigned int access ); static void mapping_destroy( struct object *obj ); static const struct object_ops mapping_ops = @@ -65,7 +66,7 @@ static const struct object_ops mapping_ops = NULL, /* satisfied */ no_signal, /* signal */ mapping_get_fd, /* get_fd */ - no_map_access, /* map_access */ + mapping_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_close_handle, /* close_handle */ mapping_destroy /* destroy */ @@ -164,7 +165,7 @@ static int build_shared_mapping( struct mapping *mapping, int fd, /* create a temp file for the mapping */ - if (!(mapping->shared_file = create_temp_file( GENERIC_READ|GENERIC_WRITE ))) return 0; + if (!(mapping->shared_file = create_temp_file( FILE_GENERIC_READ|FILE_GENERIC_WRITE ))) return 0; if (!grow_file( mapping->shared_file, total_size )) goto error; if ((shared_fd = get_file_unix_fd( mapping->shared_file )) == -1) goto error; @@ -293,8 +294,8 @@ static struct object *create_mapping( struct directory *root, const struct unico mapping->shared_file = NULL; mapping->shared_size = 0; - if (protect & VPROT_READ) access |= GENERIC_READ; - if (protect & VPROT_WRITE) access |= GENERIC_WRITE; + if (protect & VPROT_READ) access |= FILE_READ_DATA; + if (protect & VPROT_WRITE) access |= FILE_WRITE_DATA; if (handle) { @@ -357,6 +358,15 @@ static struct fd *mapping_get_fd( struct object *obj ) return get_obj_fd( (struct object *)mapping->file ); } +static unsigned int mapping_map_access( struct object *obj, unsigned int access ) +{ + if (access & GENERIC_READ) access |= STANDARD_RIGHTS_READ | SECTION_QUERY | SECTION_MAP_READ; + if (access & GENERIC_WRITE) access |= STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE; + if (access & GENERIC_EXECUTE) access |= STANDARD_RIGHTS_EXECUTE | SECTION_MAP_EXECUTE; + if (access & GENERIC_ALL) access |= SECTION_ALL_ACCESS; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); +} + static void mapping_destroy( struct object *obj ) { struct mapping *mapping = (struct mapping *)obj; diff --git a/server/named_pipe.c b/server/named_pipe.c index 07a7ceb28d0..e45115659c3 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -107,6 +107,7 @@ struct named_pipe_device }; static void named_pipe_dump( struct object *obj, int verbose ); +static unsigned int named_pipe_map_access( struct object *obj, unsigned int access ); static void named_pipe_destroy( struct object *obj ); static const struct object_ops named_pipe_ops = @@ -119,12 +120,15 @@ static const struct object_ops named_pipe_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ - no_map_access, /* map_access */ + named_pipe_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_close_handle, /* close_handle */ named_pipe_destroy /* destroy */ }; +/* functions common to server and client */ +static unsigned int pipe_map_access( struct object *obj, unsigned int access ); + /* server end functions */ static void pipe_server_dump( struct object *obj, int verbose ); static struct fd *pipe_server_get_fd( struct object *obj ); @@ -142,7 +146,7 @@ static const struct object_ops pipe_server_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ pipe_server_get_fd, /* get_fd */ - no_map_access, /* map_access */ + pipe_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_close_handle, /* close_handle */ pipe_server_destroy /* destroy */ @@ -175,7 +179,7 @@ static const struct object_ops pipe_client_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ pipe_client_get_fd, /* get_fd */ - no_map_access, /* map_access */ + pipe_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_close_handle, /* close_handle */ pipe_client_destroy /* destroy */ @@ -207,7 +211,7 @@ static const struct object_ops named_pipe_device_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ named_pipe_device_get_fd, /* get_fd */ - no_map_access, /* map_access */ + pipe_map_access, /* map_access */ named_pipe_device_lookup_name, /* lookup_name */ no_close_handle, /* close_handle */ named_pipe_device_destroy /* destroy */ @@ -232,6 +236,15 @@ static void named_pipe_dump( struct object *obj, int verbose ) fprintf( stderr, "\n" ); } +static unsigned int named_pipe_map_access( struct object *obj, unsigned int access ) +{ + if (access & GENERIC_READ) access |= STANDARD_RIGHTS_READ; + if (access & GENERIC_WRITE) access |= STANDARD_RIGHTS_WRITE | FILE_CREATE_PIPE_INSTANCE; + if (access & GENERIC_EXECUTE) access |= STANDARD_RIGHTS_EXECUTE; + if (access & GENERIC_ALL) access |= STANDARD_RIGHTS_ALL; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); +} + static void pipe_server_dump( struct object *obj, int verbose ) { struct pipe_server *server = (struct pipe_server *) obj; @@ -317,6 +330,15 @@ static void do_disconnect( struct pipe_server *server ) server->fd = NULL; } +static unsigned int pipe_map_access( struct object *obj, unsigned int access ) +{ + if (access & GENERIC_READ) access |= FILE_GENERIC_READ; + if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; + if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; + if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); +} + static void pipe_server_destroy( struct object *obj) { struct pipe_server *server = (struct pipe_server *)obj; diff --git a/server/object.c b/server/object.c index 94c8c53907f..e881a69d727 100644 --- a/server/object.c +++ b/server/object.c @@ -314,7 +314,11 @@ struct fd *no_get_fd( struct object *obj ) unsigned int no_map_access( struct object *obj, unsigned int access ) { - return access; + if (access & GENERIC_READ) access |= STANDARD_RIGHTS_READ; + if (access & GENERIC_WRITE) access |= STANDARD_RIGHTS_WRITE; + if (access & GENERIC_EXECUTE) access |= STANDARD_RIGHTS_EXECUTE; + if (access & GENERIC_ALL) access |= STANDARD_RIGHTS_ALL; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); } struct object *no_lookup_name( struct object *obj, struct unicode_str *name, diff --git a/server/process.c b/server/process.c index c1657e467dc..cdc04619663 100644 --- a/server/process.c +++ b/server/process.c @@ -900,7 +900,7 @@ DECL_HANDLER(new_process) info->data = NULL; if (req->exe_file && - !(info->exe_file = get_file_obj( current->process, req->exe_file, GENERIC_READ ))) + !(info->exe_file = get_file_obj( current->process, req->exe_file, FILE_READ_DATA ))) goto done; if (!(info->data = memdup( get_req_data(), info->data_size ))) goto done; @@ -999,7 +999,7 @@ DECL_HANDLER(init_process_done) process->exe.size = req->module_size; process->exe.name = req->name; - if (req->exe_file) file = get_file_obj( process, req->exe_file, GENERIC_READ ); + if (req->exe_file) file = get_file_obj( process, req->exe_file, FILE_READ_DATA ); if (process->exe.file) release_object( process->exe.file ); process->exe.file = file; @@ -1126,7 +1126,7 @@ DECL_HANDLER(load_dll) struct process_dll *dll; struct file *file = NULL; - if (req->handle && !(file = get_file_obj( current->process, req->handle, GENERIC_READ ))) + if (req->handle && !(file = get_file_obj( current->process, req->handle, FILE_READ_DATA ))) return; if ((dll = process_load_dll( current->process, file, req->base, diff --git a/server/registry.c b/server/registry.c index 09c7f5a3406..c57ef388384 100644 --- a/server/registry.c +++ b/server/registry.c @@ -1408,7 +1408,7 @@ static void load_registry( struct key *key, obj_handle_t handle ) struct file *file; int fd; - if (!(file = get_file_obj( current->process, handle, GENERIC_READ ))) return; + if (!(file = get_file_obj( current->process, handle, FILE_READ_DATA ))) return; fd = dup( get_file_unix_fd( file ) ); release_object( file ); if (fd != -1) @@ -1550,7 +1550,7 @@ static void save_registry( struct key *key, obj_handle_t handle ) set_error( STATUS_KEY_DELETED ); return; } - if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE ))) return; + if (!(file = get_file_obj( current->process, handle, FILE_WRITE_DATA ))) return; fd = dup( get_file_unix_fd( file ) ); release_object( file ); if (fd != -1) diff --git a/server/serial.c b/server/serial.c index a6f39034b39..08a64a04d6b 100644 --- a/server/serial.c +++ b/server/serial.c @@ -58,6 +58,7 @@ static void serial_dump( struct object *obj, int verbose ); static struct fd *serial_get_fd( struct object *obj ); +static unsigned int serial_map_access( struct object *obj, unsigned int access ); static void serial_destroy(struct object *obj); static int serial_get_poll_events( struct fd *fd ); @@ -102,7 +103,7 @@ static const struct object_ops serial_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ serial_get_fd, /* get_fd */ - no_map_access, /* map_access */ + serial_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_close_handle, /* close_handle */ serial_destroy /* destroy */ @@ -168,6 +169,15 @@ static struct fd *serial_get_fd( struct object *obj ) return (struct fd *)grab_object( serial->fd ); } +static unsigned int serial_map_access( struct object *obj, unsigned int access ) +{ + if (access & GENERIC_READ) access |= FILE_GENERIC_READ; + if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; + if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; + if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); +} + static void serial_destroy( struct object *obj) { struct serial *serial = (struct serial *)obj; diff --git a/server/sock.c b/server/sock.c index dd48e3d7960..6e145696ae5 100644 --- a/server/sock.c +++ b/server/sock.c @@ -90,6 +90,7 @@ struct sock static void sock_dump( struct object *obj, int verbose ); static int sock_signaled( struct object *obj, struct thread *thread ); static struct fd *sock_get_fd( struct object *obj ); +static unsigned int sock_map_access( struct object *obj, unsigned int access ); static void sock_destroy( struct object *obj ); static int sock_get_poll_events( struct fd *fd ); @@ -111,7 +112,7 @@ static const struct object_ops sock_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ sock_get_fd, /* get_fd */ - no_map_access, /* map_access */ + sock_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_close_handle, /* close_handle */ sock_destroy /* destroy */ @@ -457,6 +458,15 @@ static int sock_signaled( struct object *obj, struct thread *thread ) return check_fd_events( sock->fd, sock_get_poll_events( sock->fd ) ) != 0; } +static unsigned int sock_map_access( struct object *obj, unsigned int access ) +{ + if (access & GENERIC_READ) access |= FILE_GENERIC_READ; + if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; + if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; + if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); +} + static int sock_get_poll_events( struct fd *fd ) { struct sock *sock = get_fd_user( fd ); @@ -629,8 +639,7 @@ static struct sock *accept_socket( obj_handle_t handle ) int acceptfd; struct sockaddr saddr; - sock=(struct sock*)get_handle_obj(current->process,handle, - GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops); + sock = (struct sock *)get_handle_obj( current->process, handle, FILE_READ_DATA, &sock_ops ); if (!sock) return NULL; @@ -801,9 +810,8 @@ DECL_HANDLER(set_socket_event) struct event *old_event; int pollev; - if (!(sock = (struct sock*)get_handle_obj( current->process, req->handle, - GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE, &sock_ops))) - return; + if (!(sock = (struct sock *)get_handle_obj( current->process, req->handle, + FILE_WRITE_ATTRIBUTES, &sock_ops))) return; old_event = sock->event; sock->mask = req->mask; sock->event = NULL; @@ -835,7 +843,7 @@ DECL_HANDLER(get_socket_event) { struct sock *sock; - sock=(struct sock*)get_handle_obj(current->process,req->handle,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops); + sock = (struct sock *)get_handle_obj( current->process, req->handle, FILE_READ_ATTRIBUTES, &sock_ops ); if (!sock) { reply->mask = 0; @@ -874,7 +882,7 @@ DECL_HANDLER(enable_socket_event) int pollev; if (!(sock = (struct sock*)get_handle_obj( current->process, req->handle, - GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE, &sock_ops))) + FILE_WRITE_ATTRIBUTES, &sock_ops))) return; sock->pmask &= ~req->mask; /* is this safe? */ @@ -895,15 +903,13 @@ DECL_HANDLER(set_socket_deferred) { struct sock *sock, *acceptsock; - sock=(struct sock*)get_handle_obj( current->process,req->handle, - GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops ); + sock=(struct sock *)get_handle_obj( current->process, req->handle, FILE_WRITE_ATTRIBUTES, &sock_ops ); if ( !sock ) { set_error( WSAENOTSOCK ); return; } - acceptsock = (struct sock*)get_handle_obj( current->process,req->deferred, - GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops ); + acceptsock = (struct sock *)get_handle_obj( current->process, req->deferred, 0, &sock_ops ); if ( !acceptsock ) { release_object( sock );