diff --git a/files/dos_fs.c b/files/dos_fs.c index 707ff6b26c8..fce3ff8ddbc 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -832,14 +832,14 @@ const DOS_DEVICE *DOSFS_GetDevice( LPCWSTR name ) const DOS_DEVICE *DOSFS_GetDeviceByHandle( HANDLE hFile ) { const DOS_DEVICE *ret = NULL; - SERVER_START_REQ( get_file_info ) + SERVER_START_REQ( get_device_id ) { req->handle = hFile; - if (!wine_server_call( req ) && (reply->type == FILE_TYPE_UNKNOWN)) + if (!wine_server_call( req )) { - if ((reply->attr >= 0) && - (reply->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0]))) - ret = &DOSFS_Devices[reply->attr]; + if ((reply->id >= 0) && + (reply->id < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0]))) + ret = &DOSFS_Devices[reply->id]; } } SERVER_END_REQ; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 07ef51a37e3..260361e571a 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -1512,6 +1512,19 @@ struct create_device_reply }; + +struct get_device_id_request +{ + struct request_header __header; + obj_handle_t handle; +}; +struct get_device_id_reply +{ + struct reply_header __header; + int id; +}; + + #define SNAP_HEAPLIST 0x00000001 #define SNAP_PROCESS 0x00000002 #define SNAP_THREAD 0x00000004 @@ -3080,6 +3093,7 @@ enum request REQ_open_mapping, REQ_get_mapping_info, REQ_create_device, + REQ_get_device_id, REQ_create_snapshot, REQ_next_process, REQ_next_thread, @@ -3260,6 +3274,7 @@ union generic_request struct open_mapping_request open_mapping_request; struct get_mapping_info_request get_mapping_info_request; struct create_device_request create_device_request; + struct get_device_id_request get_device_id_request; struct create_snapshot_request create_snapshot_request; struct next_process_request next_process_request; struct next_thread_request next_thread_request; @@ -3438,6 +3453,7 @@ union generic_reply struct open_mapping_reply open_mapping_reply; struct get_mapping_info_reply get_mapping_info_reply; struct create_device_reply create_device_reply; + struct get_device_id_reply get_device_id_reply; struct create_snapshot_reply create_snapshot_reply; struct next_process_reply next_process_reply; struct next_thread_reply next_thread_reply; @@ -3535,6 +3551,6 @@ union generic_reply struct get_next_hook_reply get_next_hook_reply; }; -#define SERVER_PROTOCOL_VERSION 96 +#define SERVER_PROTOCOL_VERSION 97 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/atom.c b/server/atom.c index 40b07f4cf94..78378cf5c76 100644 --- a/server/atom.c +++ b/server/atom.c @@ -72,7 +72,6 @@ static const struct object_ops atom_table_ops = NULL, /* signaled */ NULL, /* satified */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ atom_table_destroy /* destroy */ }; diff --git a/server/change.c b/server/change.c index e110eadfeeb..0edb34bbc17 100644 --- a/server/change.c +++ b/server/change.c @@ -47,7 +47,6 @@ static const struct object_ops change_ops = change_signaled, /* signaled */ no_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ no_destroy /* destroy */ }; diff --git a/server/console.c b/server/console.c index 6288a1a02eb..4dbdc37500c 100644 --- a/server/console.c +++ b/server/console.c @@ -40,9 +40,6 @@ static void console_input_dump( struct object *obj, int verbose ); static void console_input_destroy( struct object *obj ); static int console_input_signaled( struct object *obj, struct thread *thread ); -/* common routine */ -static int console_get_file_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); - static const struct object_ops console_input_ops = { sizeof(struct console_input), /* size */ @@ -52,7 +49,6 @@ static const struct object_ops console_input_ops = console_input_signaled, /* signaled */ no_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - console_get_file_info, /* get_file_info */ console_input_destroy /* destroy */ }; @@ -77,7 +73,6 @@ static const struct object_ops console_input_events_ops = console_input_events_signaled, /* signaled */ no_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ console_input_events_destroy /* destroy */ }; @@ -114,7 +109,6 @@ static const struct object_ops screen_buffer_ops = NULL, /* signaled */ NULL, /* satisfied */ no_get_fd, /* get_fd */ - console_get_file_info, /* get_file_info */ screen_buffer_destroy /* destroy */ }; @@ -374,6 +368,11 @@ void inherit_console(struct thread *parent_thread, struct process *process, obj_ } } +int is_console_object( struct object *obj ) +{ + return (obj->ops == &console_input_ops || obj->ops == &screen_buffer_ops); +} + static struct console_input* console_input_get( obj_handle_t handle, unsigned access ) { struct console_input* console = 0; @@ -938,25 +937,6 @@ static void console_input_dump( struct object *obj, int verbose ) console->active, console->evt ); } -static int console_get_file_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) -{ - if (reply) - { - reply->type = FILE_TYPE_CHAR; - reply->attr = 0; - reply->access_time = 0; - reply->write_time = 0; - reply->size_high = 0; - reply->size_low = 0; - reply->links = 0; - reply->index_high = 0; - reply->index_low = 0; - reply->serial = 0; - } - *flags = 0; - return FD_TYPE_CONSOLE; -} - static void console_input_destroy( struct object *obj ) { struct console_input* console_in = (struct console_input *)obj; diff --git a/server/console.h b/server/console.h index 9371d7ad2f7..c3b4aae50c6 100644 --- a/server/console.h +++ b/server/console.h @@ -48,5 +48,6 @@ struct console_input extern void inherit_console(struct thread *parent_thread, struct process *process, obj_handle_t hconin); extern int free_console( struct process *process ); +extern int is_console_object( struct object *obj ); #endif /* __WINE_SERVER_CONSOLE_H */ diff --git a/server/context_i386.c b/server/context_i386.c index b27b5f7fdea..b7a7bb03751 100644 --- a/server/context_i386.c +++ b/server/context_i386.c @@ -36,6 +36,8 @@ #endif #include "winbase.h" + +#include "file.h" #include "thread.h" #include "request.h" diff --git a/server/context_powerpc.c b/server/context_powerpc.c index 3dca87429f4..b1dde4ff792 100644 --- a/server/context_powerpc.c +++ b/server/context_powerpc.c @@ -35,6 +35,7 @@ #include "winbase.h" +#include "file.h" #include "thread.h" #include "request.h" diff --git a/server/context_sparc.c b/server/context_sparc.c index 15ef4cf7f9a..bc1b3afbf23 100644 --- a/server/context_sparc.c +++ b/server/context_sparc.c @@ -35,6 +35,7 @@ #include "winbase.h" +#include "file.h" #include "thread.h" #include "request.h" diff --git a/server/debugger.c b/server/debugger.c index 04276464e7e..200c6923657 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -73,7 +73,6 @@ static const struct object_ops debug_event_ops = debug_event_signaled, /* signaled */ no_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ debug_event_destroy /* destroy */ }; @@ -90,7 +89,6 @@ static const struct object_ops debug_ctx_ops = debug_ctx_signaled, /* signaled */ no_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ debug_ctx_destroy /* destroy */ }; diff --git a/server/device.c b/server/device.c index 939e6c8651c..7e06b994286 100644 --- a/server/device.c +++ b/server/device.c @@ -43,7 +43,6 @@ struct device }; static void device_dump( struct object *obj, int verbose ); -static int device_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static const struct object_ops device_ops = { @@ -54,7 +53,6 @@ static const struct object_ops device_ops = NULL, /* signaled */ NULL, /* satisfied */ no_get_fd, /* get_fd */ - device_get_info, /* get_file_info */ no_destroy /* destroy */ }; @@ -75,28 +73,6 @@ static void device_dump( struct object *obj, int verbose ) fprintf( stderr, "Device id=%08x\n", dev->id ); } -static int device_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) -{ - struct device *dev = (struct device *)obj; - assert( obj->ops == &device_ops ); - - if (reply) - { - reply->type = FILE_TYPE_UNKNOWN; - reply->attr = dev->id; /* hack! */ - reply->access_time = 0; - reply->write_time = 0; - reply->size_high = 0; - reply->size_low = 0; - reply->links = 0; - reply->index_high = 0; - reply->index_low = 0; - reply->serial = 0; - } - *flags = 0; - return FD_TYPE_DEFAULT; -} - /* create a device */ DECL_HANDLER(create_device) { @@ -109,3 +85,16 @@ DECL_HANDLER(create_device) release_object( dev ); } } + + +/* Retrieve the client private id for a device */ +DECL_HANDLER(get_device_id) +{ + struct device *dev; + + if ((dev = (struct device *)get_handle_obj( current->process, req->handle, 0, &device_ops ))) + { + reply->id = dev->id; + release_object( dev ); + } +} diff --git a/server/event.c b/server/event.c index 927e2c77ed7..bc1b5a4c6bf 100644 --- a/server/event.c +++ b/server/event.c @@ -51,7 +51,6 @@ static const struct object_ops event_ops = event_signaled, /* signaled */ event_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ no_destroy /* destroy */ }; diff --git a/server/fd.c b/server/fd.c index 1dff6efe80c..6c2a49ac485 100644 --- a/server/fd.c +++ b/server/fd.c @@ -32,6 +32,7 @@ #include "handle.h" #include "process.h" #include "request.h" +#include "console.h" struct fd { @@ -54,7 +55,6 @@ static const struct object_ops fd_ops = NULL, /* signaled */ NULL, /* satisfied */ default_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ fd_destroy /* destroy */ }; @@ -95,18 +95,17 @@ void *alloc_fd_object( const struct object_ops *ops, return user; } -/* retrieve the unix fd for an object */ -int get_unix_fd( struct object *obj ) +/* retrieve the object that is using an fd */ +void *get_fd_user( struct fd *fd ) { - struct fd *fd = obj->ops->get_fd( obj ); - int unix_fd = -1; + return fd->user; +} - if (fd) - { - unix_fd = fd->unix_fd; - release_object( fd ); - } - return unix_fd; +/* retrieve the unix fd for an object */ +int get_unix_fd( struct fd *fd ) +{ + if (fd) return fd->unix_fd; + return -1; } /* set the unix fd for an object; can only be done once */ @@ -121,17 +120,22 @@ void set_unix_fd( struct object *obj, int unix_fd ) obj->fd = unix_fd; } -/* close a file descriptor */ -void close_fd( struct fd *fd ) -{ - release_object( fd ); -} - /* callback for event happening in the main poll() loop */ void fd_poll_event( struct object *obj, int event ) { struct fd *fd = obj->fd_obj; - return fd->fd_ops->poll_event( fd->user, event ); + return fd->fd_ops->poll_event( fd, event ); +} + +/* check if events are pending and if yes return which one(s) */ +int check_fd_events( struct fd *fd, int events ) +{ + struct pollfd pfd; + + pfd.fd = fd->unix_fd; + pfd.events = events; + if (poll( &pfd, 1, 0 ) <= 0) return 0; + return pfd.revents; } /* default add_queue() routine for objects that poll() on an fd */ @@ -140,7 +144,7 @@ int default_fd_add_queue( struct object *obj, struct wait_queue_entry *entry ) struct fd *fd = obj->fd_obj; if (!obj->head) /* first on the queue */ - set_select_events( obj, fd->fd_ops->get_poll_events( fd->user ) ); + set_select_events( obj, fd->fd_ops->get_poll_events( fd ) ); add_queue( obj, entry ); return 1; } @@ -159,9 +163,9 @@ void default_fd_remove_queue( struct object *obj, struct wait_queue_entry *entry int default_fd_signaled( struct object *obj, struct thread *thread ) { struct fd *fd = obj->fd_obj; - int events = fd->fd_ops->get_poll_events( obj ); + int events = fd->fd_ops->get_poll_events( fd ); - if (check_select_events( fd->unix_fd, events )) + if (check_fd_events( fd, events )) { /* stop waiting on select() if we are signaled */ set_select_events( obj, 0 ); @@ -172,15 +176,31 @@ int default_fd_signaled( struct object *obj, struct thread *thread ) return 0; } +/* default handler for poll() events */ +void default_poll_event( struct fd *fd, int event ) +{ + /* an error occurred, stop polling this fd to avoid busy-looping */ + if (event & (POLLERR | POLLHUP)) set_select_events( fd->user, -1 ); + wake_up( fd->user, 0 ); +} + /* default flush() routine */ -int no_flush( struct object *obj ) +int no_flush( struct fd *fd ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); return 0; } +/* default get_file_info() routine */ +int no_get_file_info( struct fd *fd, struct get_file_info_reply *info, int *flags ) +{ + set_error( STATUS_OBJECT_TYPE_MISMATCH ); + *flags = 0; + return FD_TYPE_INVALID; +} + /* default queue_async() routine */ -void no_queue_async( struct object *obj, void* ptr, unsigned int status, int type, int count ) +void no_queue_async( struct fd *fd, void* ptr, unsigned int status, int type, int count ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); } @@ -192,7 +212,7 @@ static struct fd *get_handle_fd_obj( struct process *process, obj_handle_t handl struct fd *fd = NULL; struct object *obj; - if ((obj = get_handle_obj( process, handle, 0, NULL ))) + if ((obj = get_handle_obj( process, handle, access, NULL ))) { if (obj->fd_obj) fd = (struct fd *)grab_object( obj->fd_obj ); else set_error( STATUS_OBJECT_TYPE_MISMATCH ); @@ -201,7 +221,6 @@ static struct fd *get_handle_fd_obj( struct process *process, obj_handle_t handl return fd; } - /* flush a file buffers */ DECL_HANDLER(flush_file) { @@ -209,7 +228,52 @@ DECL_HANDLER(flush_file) if (fd) { - fd->fd_ops->flush( fd->user ); + fd->fd_ops->flush( fd ); + release_object( fd ); + } +} + +/* get a Unix fd to access a file */ +DECL_HANDLER(get_handle_fd) +{ + struct fd *fd; + + reply->fd = -1; + reply->type = FD_TYPE_INVALID; + + if ((fd = get_handle_fd_obj( current->process, req->handle, req->access ))) + { + int unix_fd = get_handle_unix_fd( current->process, req->handle, req->access ); + if (unix_fd != -1) reply->fd = unix_fd; + else if (!get_error()) + { + unix_fd = fd->unix_fd; + if (unix_fd != -1) send_client_fd( current->process, unix_fd, req->handle ); + } + reply->type = fd->fd_ops->get_file_info( fd, NULL, &reply->flags ); + release_object( fd ); + } + else /* check for console handle (FIXME: should be done in the client) */ + { + struct object *obj; + + if ((obj = get_handle_obj( current->process, req->handle, req->access, NULL ))) + { + if (is_console_object( obj )) reply->type = FD_TYPE_CONSOLE; + release_object( obj ); + } + } +} + +/* get a file information */ +DECL_HANDLER(get_file_info) +{ + struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 ); + + if (fd) + { + int flags; + fd->fd_ops->get_file_info( fd, reply, &flags ); release_object( fd ); } } @@ -238,7 +302,7 @@ DECL_HANDLER(register_async) if (fd) { - fd->fd_ops->queue_async( fd->user, req->overlapped, req->status, req->type, req->count ); + fd->fd_ops->queue_async( fd, req->overlapped, req->status, req->type, req->count ); release_object( fd ); } } diff --git a/server/file.c b/server/file.c index 60b72a66d58..7518a09a8c1 100644 --- a/server/file.c +++ b/server/file.c @@ -66,12 +66,13 @@ struct file static struct file *file_hash[NAME_HASH_SIZE]; static void file_dump( struct object *obj, int verbose ); -static int file_get_poll_events( struct object *obj ); -static void file_poll_event( struct object *obj, int event ); -static int file_flush( struct object *obj ); -static int file_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static void file_destroy( struct object *obj ); -static void file_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count); + +static int file_get_poll_events( struct fd *fd ); +static void file_poll_event( struct fd *fd, int event ); +static int file_flush( struct fd *fd ); +static int file_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ); +static void file_queue_async( struct fd *fd, void *ptr, unsigned int status, int type, int count ); static const struct object_ops file_ops = { @@ -82,7 +83,6 @@ static const struct object_ops file_ops = default_fd_signaled, /* signaled */ no_satisfied, /* satisfied */ default_get_fd, /* get_fd */ - file_get_info, /* get_file_info */ file_destroy /* destroy */ }; @@ -264,23 +264,23 @@ static void file_dump( struct object *obj, int verbose ) { struct file *file = (struct file *)obj; assert( obj->ops == &file_ops ); - fprintf( stderr, "File fd=%d flags=%08x name='%s'\n", file->obj.fd, file->flags, file->name ); + fprintf( stderr, "File fd=%p flags=%08x name='%s'\n", file->obj.fd_obj, file->flags, file->name ); } -static int file_get_poll_events( struct object *obj ) +static int file_get_poll_events( struct fd *fd ) { - struct file *file = (struct file *)obj; + struct file *file = get_fd_user( fd ); int events = 0; - assert( obj->ops == &file_ops ); + assert( file->obj.ops == &file_ops ); if (file->access & GENERIC_READ) events |= POLLIN; if (file->access & GENERIC_WRITE) events |= POLLOUT; return events; } -static void file_poll_event( struct object *obj, int event ) +static void file_poll_event( struct fd *fd, int event ) { - struct file *file = (struct file *)obj; - assert( obj->ops == &file_ops ); + struct file *file = get_fd_user( fd ); + assert( file->obj.ops == &file_ops ); if ( file->flags & FILE_FLAG_OVERLAPPED ) { if( IS_READY(file->read_q) && (POLLIN & event) ) @@ -294,22 +294,22 @@ static void file_poll_event( struct object *obj, int event ) return; } } - default_poll_event( obj, event ); + default_poll_event( fd, event ); } -static int file_flush( struct object *obj ) +static int file_flush( struct fd *fd ) { - int ret = (fsync( get_unix_fd(obj) ) != -1); + int ret = (fsync( get_unix_fd(fd) ) != -1); if (!ret) file_set_error(); return ret; } -static int file_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) +static int file_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ) { struct stat st; - struct file *file = (struct file *)obj; - int unix_fd = get_unix_fd( obj ); + struct file *file = get_fd_user( fd ); + int unix_fd = get_unix_fd( fd ); if (reply) { @@ -346,13 +346,13 @@ static int file_get_info( struct object *obj, struct get_file_info_reply *reply, return FD_TYPE_DEFAULT; } -static void file_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count) +static void file_queue_async(struct fd *fd, void *ptr, unsigned int status, int type, int count) { - struct file *file = (struct file *)obj; + struct file *file = get_fd_user( fd ); struct async *async; struct async_queue *q; - assert( obj->ops == &file_ops ); + assert( file->obj.ops == &file_ops ); if ( !(file->flags & FILE_FLAG_OVERLAPPED) ) { @@ -377,10 +377,10 @@ static void file_queue_async(struct object *obj, void *ptr, unsigned int status, if ( status == STATUS_PENDING ) { - struct pollfd pfd; + int events; if ( !async ) - async = create_async ( obj, current, ptr ); + async = create_async ( &file->obj, current, ptr ); if ( !async ) return; @@ -389,18 +389,13 @@ static void file_queue_async(struct object *obj, void *ptr, unsigned int status, async_insert( q, async ); /* Check if the new pending request can be served immediately */ - pfd.fd = get_unix_fd( obj ); - pfd.events = file_get_poll_events ( obj ); - pfd.revents = 0; - poll ( &pfd, 1, 0 ); - - if ( pfd.revents ) - file_poll_event ( obj, pfd.revents ); + events = check_fd_events( fd, file_get_poll_events( fd ) ); + if (events) file_poll_event ( fd, events ); } else if ( async ) destroy_async ( async ); else set_error ( STATUS_INVALID_PARAMETER ); - set_select_events ( obj, file_get_poll_events ( obj )); + set_select_events( &file->obj, file_get_poll_events( fd )); } static void file_destroy( struct object *obj ) @@ -456,6 +451,11 @@ struct file *get_file_obj( struct process *process, obj_handle_t handle, unsigne return (struct file *)get_handle_obj( process, handle, access, &file_ops ); } +int get_file_unix_fd( struct file *file ) +{ + return get_unix_fd( file->obj.fd_obj ); +} + static int set_file_pointer( obj_handle_t handle, unsigned int *low, int *high, int whence ) { struct file *file; @@ -464,7 +464,7 @@ static int set_file_pointer( obj_handle_t handle, unsigned int *low, int *high, xto = *low+((off_t)*high<<32); if (!(file = get_file_obj( current->process, handle, 0 ))) return 0; - if ((result = lseek( get_unix_fd(&file->obj), xto, whence))==-1) + if ((result = lseek( get_file_unix_fd(file), xto, whence))==-1) { /* Check for seek before start of file */ @@ -487,7 +487,7 @@ static int set_file_pointer( obj_handle_t handle, unsigned int *low, int *high, static int extend_file( struct file *file, off_t size ) { static const char zero; - int unix_fd = get_unix_fd( &file->obj ); + int unix_fd = get_file_unix_fd( file ); /* extend the file one byte beyond the requested size and then truncate it */ /* this should work around ftruncate implementations that can't extend files */ @@ -505,7 +505,7 @@ static int extend_file( struct file *file, off_t size ) static int truncate_file( struct file *file ) { int ret = 0; - int unix_fd = get_unix_fd( &file->obj ); + int unix_fd = get_file_unix_fd( file ); off_t pos = lseek( unix_fd, 0, SEEK_CUR ); off_t eof = lseek( unix_fd, 0, SEEK_END ); @@ -524,7 +524,7 @@ int grow_file( struct file *file, int size_high, int size_low ) { int ret = 0; struct stat st; - int unix_fd = get_unix_fd( &file->obj ); + int unix_fd = get_file_unix_fd( file ); off_t old_pos, size = size_low + (((off_t)size_high)<<32); if (fstat( unix_fd, &st ) == -1) @@ -618,27 +618,6 @@ DECL_HANDLER(alloc_file_handle) } } -/* get a Unix fd to access a file */ -DECL_HANDLER(get_handle_fd) -{ - struct object *obj; - - reply->fd = -1; - reply->type = FD_TYPE_INVALID; - if ((obj = get_handle_obj( current->process, req->handle, req->access, NULL ))) - { - int fd = get_handle_fd( current->process, req->handle, req->access ); - if (fd != -1) reply->fd = fd; - else if (!get_error()) - { - int unix_fd = get_unix_fd( obj ); - if (unix_fd != -1) send_client_fd( current->process, unix_fd, req->handle ); - } - reply->type = obj->ops->get_file_info( obj, NULL, &reply->flags ); - release_object( obj ); - } -} - /* set a file current position */ DECL_HANDLER(set_file_pointer) { @@ -667,19 +646,6 @@ DECL_HANDLER(set_file_time) set_file_time( req->handle, req->access_time, req->write_time ); } -/* get a file information */ -DECL_HANDLER(get_file_info) -{ - struct object *obj; - - if ((obj = get_handle_obj( current->process, req->handle, 0, NULL ))) - { - int flags; - obj->ops->get_file_info( obj, reply, &flags ); - release_object( obj ); - } -} - /* lock a region of a file */ DECL_HANDLER(lock_file) { diff --git a/server/file.h b/server/file.h index f5c9a32c308..351c62e0c6d 100644 --- a/server/file.h +++ b/server/file.h @@ -29,28 +29,47 @@ struct fd; struct fd_ops { /* get the events we want to poll() for on this object */ - int (*get_poll_events)(struct object *); + int (*get_poll_events)(struct fd *); /* a poll() event occured */ - void (*poll_event)(struct object *,int event); + void (*poll_event)(struct fd *,int event); /* flush the object buffers */ - int (*flush)(struct object *); + int (*flush)(struct fd *); /* get file information */ - int (*get_file_info)(struct object *,struct get_file_info_reply *, int *flags); + int (*get_file_info)(struct fd *,struct get_file_info_reply *, int *flags); /* queue an async operation - see register_async handler in async.c*/ - void (*queue_async)(struct object *, void* ptr, unsigned int status, int type, int count); + void (*queue_async)(struct fd *, void* ptr, unsigned int status, int type, int count); }; +/* file descriptor functions */ + extern void *alloc_fd_object( const struct object_ops *ops, const struct fd_ops *fd_user_ops, int unix_fd ); -extern int get_unix_fd( struct object *obj ); +extern void *get_fd_user( struct fd *fd ); +extern int get_unix_fd( struct fd *fd ); extern void set_unix_fd( struct object *obj, int unix_fd ); -extern void close_fd( struct fd *fd ); extern void fd_poll_event( struct object *obj, int event ); +extern int check_fd_events( struct fd *fd, int events ); extern int default_fd_add_queue( struct object *obj, struct wait_queue_entry *entry ); extern void default_fd_remove_queue( struct object *obj, struct wait_queue_entry *entry ); extern int default_fd_signaled( struct object *obj, struct thread *thread ); -extern int no_flush( struct object *obj ); -extern void no_queue_async(struct object *obj, void* ptr, unsigned int status, int type, int count); +extern void default_poll_event( struct fd *fd, int event ); +extern int no_flush( struct fd *fd ); +extern int no_get_file_info( struct fd *fd, struct get_file_info_reply *info, int *flags ); +extern void no_queue_async( struct fd *fd, void* ptr, unsigned int status, int type, int count ); + +inline static struct fd *get_obj_fd( struct object *obj ) { return obj->ops->get_fd( obj ); } + +/* file functions */ + +extern struct file *get_file_obj( struct process *process, obj_handle_t handle, + unsigned int access ); +extern int get_file_unix_fd( struct file *file ); +extern int is_same_file( struct file *file1, struct file *file2 ); +extern int get_file_drive_type( struct file *file ); +extern int grow_file( struct file *file, int size_high, int size_low ); +extern int create_anonymous_file(void); +extern struct file *create_temp_file( int access ); +extern void file_set_error(void); #endif /* __WINE_SERVER_FILE_H */ diff --git a/server/handle.c b/server/handle.c index 471d5a7edee..6fa8f713da5 100644 --- a/server/handle.c +++ b/server/handle.c @@ -105,7 +105,6 @@ static const struct object_ops handle_table_ops = NULL, /* signaled */ NULL, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ handle_table_destroy /* destroy */ }; @@ -385,7 +384,7 @@ struct object *get_handle_obj( struct process *process, obj_handle_t handle, } /* retrieve the cached fd for a given handle */ -int get_handle_fd( struct process *process, obj_handle_t handle, unsigned int access ) +int get_handle_unix_fd( struct process *process, obj_handle_t handle, unsigned int access ) { struct handle_entry *entry; diff --git a/server/handle.h b/server/handle.h index 994ce48a6c7..212a0ae8a4e 100644 --- a/server/handle.h +++ b/server/handle.h @@ -38,7 +38,7 @@ extern obj_handle_t alloc_handle( struct process *process, void *obj, extern int close_handle( struct process *process, obj_handle_t handle, int *fd ); extern struct object *get_handle_obj( struct process *process, obj_handle_t handle, unsigned int access, const struct object_ops *ops ); -extern int get_handle_fd( struct process *process, obj_handle_t handle, unsigned int access ); +extern int get_handle_unix_fd( struct process *process, obj_handle_t handle, unsigned int access ); extern int set_handle_info( struct process *process, obj_handle_t handle, int mask, int flags, int *fd ); extern obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, struct process *dst, unsigned int access, int inherit, int options ); diff --git a/server/hook.c b/server/hook.c index d10318dca0f..b69b1ccdcf0 100644 --- a/server/hook.c +++ b/server/hook.c @@ -67,7 +67,6 @@ static const struct object_ops hook_table_ops = NULL, /* signaled */ NULL, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ hook_table_destroy /* destroy */ }; diff --git a/server/mapping.c b/server/mapping.c index 4881bc734d2..f91edcbf691 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "winbase.h" @@ -48,8 +49,6 @@ struct mapping struct mapping *shared_prev; /* prev in shared PE mapping list */ }; -static struct fd *mapping_get_fd( struct object *obj ); -static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static void mapping_dump( struct object *obj, int verbose ); static void mapping_destroy( struct object *obj ); @@ -61,8 +60,7 @@ static const struct object_ops mapping_ops = NULL, /* remove_queue */ NULL, /* signaled */ NULL, /* satisfied */ - mapping_get_fd, /* get_fd */ - mapping_get_info, /* get_file_info */ + default_get_fd, /* get_fd */ mapping_destroy /* destroy */ }; @@ -105,11 +103,6 @@ static void init_page_size(void) #define ROUND_SIZE(addr,size) \ (((int)(size) + ((int)(addr) & page_mask) + page_mask) & ~page_mask) -/* get the fd to use for mmaping a file */ -inline static int get_mmap_fd( struct file *file ) -{ - return get_unix_fd( (struct object *)file ); -} /* find the shared PE mapping for a given mapping */ static struct file *get_shared_file( struct mapping *mapping ) @@ -152,7 +145,7 @@ static int build_shared_mapping( struct mapping *mapping, int fd, if (!(mapping->shared_file = create_temp_file( GENERIC_READ|GENERIC_WRITE ))) return 0; if (!grow_file( mapping->shared_file, 0, total_size )) goto error; - if ((shared_fd = get_mmap_fd( mapping->shared_file )) == -1) goto error; + if ((shared_fd = get_file_unix_fd( mapping->shared_file )) == -1) goto error; if (!(buffer = malloc( max_size ))) goto error; @@ -192,30 +185,33 @@ static int get_image_params( struct mapping *mapping ) IMAGE_DOS_HEADER dos; IMAGE_NT_HEADERS nt; IMAGE_SECTION_HEADER *sec = NULL; - int fd, filepos, size; + struct fd *fd; + int unix_fd, filepos, size; /* load the headers */ - if ((fd = get_mmap_fd( mapping->file )) == -1) return 0; - filepos = lseek( fd, 0, SEEK_SET ); - if (read( fd, &dos, sizeof(dos) ) != sizeof(dos)) goto error; + if (!(fd = get_obj_fd( (struct object *)mapping->file ))) return 0; + mapping->obj.fd_obj = fd; + unix_fd = get_unix_fd( fd ); + filepos = lseek( unix_fd, 0, SEEK_SET ); + if (read( unix_fd, &dos, sizeof(dos) ) != sizeof(dos)) goto error; if (dos.e_magic != IMAGE_DOS_SIGNATURE) goto error; - if (lseek( fd, dos.e_lfanew, SEEK_SET ) == -1) goto error; + if (lseek( unix_fd, dos.e_lfanew, SEEK_SET ) == -1) goto error; - if (read( fd, &nt.Signature, sizeof(nt.Signature) ) != sizeof(nt.Signature)) goto error; + if (read( unix_fd, &nt.Signature, sizeof(nt.Signature) ) != sizeof(nt.Signature)) goto error; if (nt.Signature != IMAGE_NT_SIGNATURE) goto error; - if (read( fd, &nt.FileHeader, sizeof(nt.FileHeader) ) != sizeof(nt.FileHeader)) goto error; + if (read( unix_fd, &nt.FileHeader, sizeof(nt.FileHeader) ) != sizeof(nt.FileHeader)) goto error; /* zero out Optional header in the case it's not present or partial */ memset(&nt.OptionalHeader, 0, sizeof(nt.OptionalHeader)); - if (read( fd, &nt.OptionalHeader, nt.FileHeader.SizeOfOptionalHeader) != nt.FileHeader.SizeOfOptionalHeader) goto error; + if (read( unix_fd, &nt.OptionalHeader, nt.FileHeader.SizeOfOptionalHeader) != nt.FileHeader.SizeOfOptionalHeader) goto error; /* load the section headers */ size = sizeof(*sec) * nt.FileHeader.NumberOfSections; if (!(sec = malloc( size ))) goto error; - if (read( fd, sec, size ) != size) goto error; + if (read( unix_fd, sec, size ) != size) goto error; - if (!build_shared_mapping( mapping, fd, sec, nt.FileHeader.NumberOfSections )) goto error; + if (!build_shared_mapping( mapping, unix_fd, sec, nt.FileHeader.NumberOfSections )) goto error; if (mapping->shared_file) /* link it in the list */ { @@ -233,17 +229,28 @@ static int get_image_params( struct mapping *mapping ) /* sanity check */ if (mapping->header_size > mapping->size_low) goto error; - lseek( fd, filepos, SEEK_SET ); + lseek( unix_fd, filepos, SEEK_SET ); free( sec ); return 1; error: - lseek( fd, filepos, SEEK_SET ); + lseek( unix_fd, filepos, SEEK_SET ); if (sec) free( sec ); set_error( STATUS_INVALID_FILE_FOR_SECTION ); return 0; } +/* get the size of the unix file associated with the mapping */ +inline static int get_file_size( struct mapping *mapping, int *size_high, int *size_low ) +{ + struct stat st; + int unix_fd = get_unix_fd( mapping->obj.fd_obj ); + + if (fstat( unix_fd, &st ) == -1) return 0; + *size_high = st.st_size >> 32; + *size_low = st.st_size & 0xffffffff; + return 1; +} static struct object *create_mapping( int size_high, int size_low, int protect, obj_handle_t handle, const WCHAR *name, size_t len ) @@ -276,14 +283,12 @@ static struct object *create_mapping( int size_high, int size_low, int protect, } if (!size_high && !size_low) { - int flags; - struct get_file_info_reply reply; - struct object *obj = (struct object *)mapping->file; - obj->ops->get_file_info( obj, &reply, &flags ); - size_high = reply.size_high; - size_low = ROUND_SIZE( 0, reply.size_low ); + if (!get_file_size( mapping, &size_high, &size_low )) goto error; + } + else + { + if (!grow_file( mapping->file, size_high, size_low )) goto error; } - else if (!grow_file( mapping->file, size_high, size_low )) goto error; } else /* Anonymous mapping (no associated file) */ { @@ -296,6 +301,7 @@ static struct object *create_mapping( int size_high, int size_low, int protect, if (!(mapping->file = create_temp_file( access ))) goto error; if (!grow_file( mapping->file, size_high, size_low )) goto error; } + mapping->obj.fd_obj = get_obj_fd( (struct object *)mapping->file ); mapping->size_high = size_high; mapping->size_low = ROUND_SIZE( 0, size_low ); mapping->protect = protect; @@ -318,24 +324,6 @@ static void mapping_dump( struct object *obj, int verbose ) fputc( '\n', stderr ); } -static struct fd *mapping_get_fd( struct object *obj ) -{ - struct mapping *mapping = (struct mapping *)obj; - assert( obj->ops == &mapping_ops ); - - return default_get_fd( (struct object *)mapping->file ); -} - -static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) -{ - struct mapping *mapping = (struct mapping *)obj; - struct object *file = (struct object *)mapping->file; - - assert( obj->ops == &mapping_ops ); - assert( file ); - return file->ops->get_file_info( file, reply, flags ); -} - static void mapping_destroy( struct object *obj ) { struct mapping *mapping = (struct mapping *)obj; diff --git a/server/mutex.c b/server/mutex.c index 9ca844e3c8e..1bb07eb0cdd 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -55,7 +55,6 @@ static const struct object_ops mutex_ops = mutex_signaled, /* signaled */ mutex_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ mutex_destroy /* destroy */ }; diff --git a/server/named_pipe.c b/server/named_pipe.c index 5eed612cd2e..29c76143771 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -94,13 +94,12 @@ static const struct object_ops named_pipe_ops = NULL, /* signaled */ NULL, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ named_pipe_destroy /* destroy */ }; static void pipe_user_dump( struct object *obj, int verbose ); static void pipe_user_destroy( struct object *obj); -static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); +static int pipe_user_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ); static const struct object_ops pipe_user_ops = { @@ -111,7 +110,6 @@ static const struct object_ops pipe_user_ops = default_fd_signaled, /* signaled */ no_satisfied, /* satisfied */ default_get_fd, /* get_fd */ - pipe_user_get_info, /* get_file_info */ pipe_user_destroy /* destroy */ }; @@ -169,7 +167,7 @@ static void pipe_user_destroy( struct object *obj) if(user->other) { - close_fd( user->other->obj.fd_obj ); + release_object( user->other->obj.fd_obj ); user->other->obj.fd_obj = NULL; switch(user->other->state) { @@ -195,7 +193,7 @@ static void pipe_user_destroy( struct object *obj) release_object(user->pipe); } -static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) +static int pipe_user_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ) { if (reply) { @@ -443,12 +441,12 @@ DECL_HANDLER(disconnect_named_pipe) if( (user->state == ps_connected_server) && (user->other->state == ps_connected_client) ) { - close_fd( user->other->obj.fd_obj ); + release_object( user->other->obj.fd_obj ); user->other->obj.fd_obj = NULL; user->other->state = ps_disconnected; user->other->other = NULL; - close_fd( user->obj.fd_obj ); + release_object( user->obj.fd_obj ); user->obj.fd_obj = NULL; user->state = ps_idle_server; user->other = NULL; diff --git a/server/object.c b/server/object.c index 77e116243ae..20fa2324219 100644 --- a/server/object.c +++ b/server/object.c @@ -220,7 +220,7 @@ void release_object( void *ptr ) assert( !obj->head ); assert( !obj->tail ); obj->ops->destroy( obj ); - if (obj->fd_obj) close_fd( obj->fd_obj ); + if (obj->fd_obj) release_object( obj->fd_obj ); if (obj->name) free_name( obj ); if (obj->select != -1) remove_select_user( obj ); if (obj->fd != -1) close( obj->fd ); @@ -303,21 +303,6 @@ struct fd *default_get_fd( struct object *obj ) return NULL; } -int no_get_file_info( struct object *obj, struct get_file_info_reply *info, int *flags ) -{ - set_error( STATUS_OBJECT_TYPE_MISMATCH ); - *flags = 0; - return FD_TYPE_INVALID; -} - void no_destroy( struct object *obj ) { } - -/* default handler for poll() events */ -void default_poll_event( struct object *obj, int event ) -{ - /* an error occurred, stop polling this fd to avoid busy-looping */ - if (event & (POLLERR | POLLHUP)) set_select_events( obj, -1 ); - wake_up( obj, 0 ); -} diff --git a/server/object.h b/server/object.h index 234c9720ffb..54d082f564a 100644 --- a/server/object.h +++ b/server/object.h @@ -60,8 +60,6 @@ struct object_ops int (*satisfied)(struct object *,struct thread *); /* return an fd object that can be used to read/write from the object */ struct fd *(*get_fd)(struct object *); - /* get file information */ - int (*get_file_info)(struct object *,struct get_file_info_reply *, int *flags); /* destroy on refcount == 0 */ void (*destroy)(struct object *); }; @@ -105,9 +103,7 @@ extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry ); extern int no_satisfied( struct object *obj, struct thread *thread ); extern struct fd *no_get_fd( struct object *obj ); extern struct fd *default_get_fd( struct object *obj ); -extern int no_get_file_info( struct object *obj, struct get_file_info_reply *info, int *flags ); extern void no_destroy( struct object *obj ); -extern void default_poll_event( struct object *obj, int event ); #ifdef DEBUG_OBJECTS extern void dump_objects(void); #endif @@ -118,7 +114,6 @@ extern int add_select_user( struct object *obj ); extern void remove_select_user( struct object *obj ); extern void change_select_fd( struct object *obj, int fd, int events ); extern void set_select_events( struct object *obj, int events ); -extern int check_select_events( int fd, int events ); extern void select_loop(void); /* timeout functions */ @@ -153,17 +148,6 @@ extern void reset_event( struct event *event ); extern void abandon_mutexes( struct thread *thread ); -/* file functions */ - -extern struct file *get_file_obj( struct process *process, obj_handle_t handle, - unsigned int access ); -extern int is_same_file( struct file *file1, struct file *file2 ); -extern int get_file_drive_type( struct file *file ); -extern int grow_file( struct file *file, int size_high, int size_low ); -extern int create_anonymous_file(void); -extern struct file *create_temp_file( int access ); -extern void file_set_error(void); - /* serial functions */ int get_serial_async_timeout(struct object *obj, int type, int count); diff --git a/server/pipe.c b/server/pipe.c index 4f57a2fdc8b..79074e57886 100644 --- a/server/pipe.c +++ b/server/pipe.c @@ -47,11 +47,12 @@ struct pipe }; static void pipe_dump( struct object *obj, int verbose ); -static int pipe_get_poll_events( struct object *obj ); static struct fd *pipe_get_fd( struct object *obj ); -static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static void pipe_destroy( struct object *obj ); +static int pipe_get_poll_events( struct fd *fd ); +static int pipe_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ); + static const struct object_ops pipe_ops = { sizeof(struct pipe), /* size */ @@ -61,7 +62,6 @@ static const struct object_ops pipe_ops = default_fd_signaled, /* signaled */ no_satisfied, /* satisfied */ pipe_get_fd, /* get_fd */ - pipe_get_info, /* get_file_info */ pipe_destroy /* destroy */ }; @@ -118,14 +118,14 @@ static void pipe_dump( struct object *obj, int verbose ) { struct pipe *pipe = (struct pipe *)obj; assert( obj->ops == &pipe_ops ); - fprintf( stderr, "Pipe %s-side fd=%d\n", - (pipe->side == READ_SIDE) ? "read" : "write", pipe->obj.fd ); + fprintf( stderr, "Pipe %s-side fd=%p\n", + (pipe->side == READ_SIDE) ? "read" : "write", pipe->obj.fd_obj ); } -static int pipe_get_poll_events( struct object *obj ) +static int pipe_get_poll_events( struct fd *fd ) { - struct pipe *pipe = (struct pipe *)obj; - assert( obj->ops == &pipe_ops ); + struct pipe *pipe = get_fd_user( fd ); + assert( pipe->obj.ops == &pipe_ops ); return (pipe->side == READ_SIDE) ? POLLIN : POLLOUT; } @@ -142,7 +142,7 @@ static struct fd *pipe_get_fd( struct object *obj ) return (struct fd *)grab_object( pipe->obj.fd_obj ); } -static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) +static int pipe_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ) { if (reply) { diff --git a/server/process.c b/server/process.c index ba0e19ab2c3..5d808dcb807 100644 --- a/server/process.c +++ b/server/process.c @@ -52,7 +52,7 @@ static int running_processes; static void process_dump( struct object *obj, int verbose ); static int process_signaled( struct object *obj, struct thread *thread ); -static void process_poll_event( struct object *obj, int event ); +static void process_poll_event( struct fd *fd, int event ); static void process_destroy( struct object *obj ); static const struct object_ops process_ops = @@ -64,7 +64,6 @@ static const struct object_ops process_ops = process_signaled, /* signaled */ no_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ process_destroy /* destroy */ }; @@ -109,7 +108,6 @@ static const struct object_ops startup_info_ops = startup_info_signaled, /* signaled */ no_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ startup_info_destroy /* destroy */ }; @@ -434,12 +432,12 @@ static int process_signaled( struct object *obj, struct thread *thread ) } -static void process_poll_event( struct object *obj, int event ) +static void process_poll_event( struct fd *fd, int event ) { - struct process *process = (struct process *)obj; - assert( obj->ops == &process_ops ); + struct process *process = get_fd_user( fd ); + assert( process->obj.ops == &process_ops ); - if (event & (POLLERR | POLLHUP)) set_select_events( obj, -1 ); + if (event & (POLLERR | POLLHUP)) set_select_events( &process->obj, -1 ); else if (event & POLLIN) receive_fd( process ); } diff --git a/server/protocol.def b/server/protocol.def index 7a17949bf0c..bab120ea3f5 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1114,6 +1114,14 @@ enum char_info_mode @END +/* Retrieve the client private id for a device */ +@REQ(get_device_id) + obj_handle_t handle; /* handle to the device */ +@REPLY + int id; /* client private id */ +@END + + #define SNAP_HEAPLIST 0x00000001 #define SNAP_PROCESS 0x00000002 #define SNAP_THREAD 0x00000004 diff --git a/server/ptrace.c b/server/ptrace.c index a74dad1987d..2c0c12bf203 100644 --- a/server/ptrace.c +++ b/server/ptrace.c @@ -33,10 +33,10 @@ #endif #include +#include "file.h" #include "process.h" #include "thread.h" - #ifndef PTRACE_CONT #define PTRACE_CONT PT_CONTINUE #endif diff --git a/server/queue.c b/server/queue.c index 39c0d0ec956..32caefec244 100644 --- a/server/queue.c +++ b/server/queue.c @@ -144,7 +144,6 @@ static const struct object_ops msg_queue_ops = msg_queue_signaled, /* signaled */ msg_queue_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ msg_queue_destroy /* destroy */ }; @@ -158,7 +157,6 @@ static const struct object_ops thread_input_ops = NULL, /* signaled */ NULL, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ thread_input_destroy /* destroy */ }; diff --git a/server/registry.c b/server/registry.c index 5b75b50ebb1..2262f5925ef 100644 --- a/server/registry.c +++ b/server/registry.c @@ -169,7 +169,6 @@ static const struct object_ops key_ops = NULL, /* signaled */ NULL, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ key_destroy /* destroy */ }; @@ -1446,12 +1445,12 @@ static void load_keys( struct key *key, FILE *f ) /* load a part of the registry from a file */ static void load_registry( struct key *key, obj_handle_t handle ) { - struct object *obj; + struct file *file; int fd; - if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL ))) return; - fd = dup( get_unix_fd( obj ) ); - release_object( obj ); + if (!(file = get_file_obj( current->process, handle, GENERIC_READ ))) return; + fd = dup( get_file_unix_fd( file ) ); + release_object( file ); if (fd != -1) { FILE *f = fdopen( fd, "r" ); @@ -1536,7 +1535,7 @@ static void save_all_subkeys( struct key *key, FILE *f ) /* save a registry branch to a file handle */ static void save_registry( struct key *key, obj_handle_t handle ) { - struct object *obj; + struct file *file; int fd; if (key->flags & KEY_DELETED) @@ -1544,9 +1543,9 @@ static void save_registry( struct key *key, obj_handle_t handle ) set_error( STATUS_KEY_DELETED ); return; } - if (!(obj = get_handle_obj( current->process, handle, GENERIC_WRITE, NULL ))) return; - fd = dup( get_unix_fd( obj ) ); - release_object( obj ); + if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE ))) return; + fd = dup( get_file_unix_fd( file ) ); + release_object( file ); if (fd != -1) { FILE *f = fdopen( fd, "w" ); diff --git a/server/request.c b/server/request.c index 5411313fcf7..d13c761b7b6 100644 --- a/server/request.c +++ b/server/request.c @@ -78,7 +78,7 @@ struct master_socket }; static void master_socket_dump( struct object *obj, int verbose ); -static void master_socket_poll_event( struct object *obj, int event ); +static void master_socket_poll_event( struct fd *fd, int event ); static const struct object_ops master_socket_ops = { @@ -89,7 +89,6 @@ static const struct object_ops master_socket_ops = NULL, /* signaled */ NULL, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ no_destroy /* destroy */ }; @@ -446,14 +445,14 @@ static void master_socket_dump( struct object *obj, int verbose ) { struct master_socket *sock = (struct master_socket *)obj; assert( obj->ops == &master_socket_ops ); - fprintf( stderr, "Master socket fd=%d\n", sock->obj.fd ); + fprintf( stderr, "Master socket fd=%p\n", sock->obj.fd_obj ); } /* handle a socket event */ -static void master_socket_poll_event( struct object *obj, int event ) +static void master_socket_poll_event( struct fd *fd, int event ) { - struct master_socket *sock = (struct master_socket *)obj; - assert( obj->ops == &master_socket_ops ); + struct master_socket *sock = get_fd_user( fd ); + assert( master_socket->obj.ops == &master_socket_ops ); assert( sock == master_socket ); /* there is only one master socket */ @@ -461,7 +460,7 @@ static void master_socket_poll_event( struct object *obj, int event ) { /* this is not supposed to happen */ fprintf( stderr, "wineserver: Error on master socket\n" ); - release_object( obj ); + release_object( sock ); } else if (event & POLLIN) { @@ -749,7 +748,7 @@ static void close_socket_timeout( void *arg ) flush_registry(); /* if a new client is waiting, we keep on running */ - if (check_select_events( master_socket->obj.fd, POLLIN )) return; + if (check_fd_events( master_socket->obj.fd_obj, POLLIN )) return; if (debug_level) fprintf( stderr, "wineserver: exiting (pid=%ld)\n", (long) getpid() ); diff --git a/server/request.h b/server/request.h index 01bb2301ee1..c0983faaaa3 100644 --- a/server/request.h +++ b/server/request.h @@ -181,6 +181,7 @@ DECL_HANDLER(create_mapping); DECL_HANDLER(open_mapping); DECL_HANDLER(get_mapping_info); DECL_HANDLER(create_device); +DECL_HANDLER(get_device_id); DECL_HANDLER(create_snapshot); DECL_HANDLER(next_process); DECL_HANDLER(next_thread); @@ -360,6 +361,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_open_mapping, (req_handler)req_get_mapping_info, (req_handler)req_create_device, + (req_handler)req_get_device_id, (req_handler)req_create_snapshot, (req_handler)req_next_process, (req_handler)req_next_thread, diff --git a/server/select.c b/server/select.c index 324ec20842f..f02e917fed3 100644 --- a/server/select.c +++ b/server/select.c @@ -138,15 +138,6 @@ void set_select_events( struct object *obj, int events ) else if (pollfd[user].fd != -1) pollfd[user].events = events; } -/* check if events are pending */ -int check_select_events( int fd, int events ) -{ - struct pollfd pfd; - pfd.fd = fd; - pfd.events = events; - return poll( &pfd, 1, 0 ) > 0; -} - /* add a timeout user */ struct timeout_user *add_timeout_user( struct timeval *when, timeout_callback func, void *private ) { diff --git a/server/semaphore.c b/server/semaphore.c index 3f5e9534d55..99f41f33dce 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -51,7 +51,6 @@ static const struct object_ops semaphore_ops = semaphore_signaled, /* signaled */ semaphore_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ no_destroy /* destroy */ }; diff --git a/server/serial.c b/server/serial.c index 998d9b61e7b..06b07cb032d 100644 --- a/server/serial.c +++ b/server/serial.c @@ -52,12 +52,13 @@ #include "async.h" static void serial_dump( struct object *obj, int verbose ); -static int serial_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); -static int serial_get_poll_events( struct object *obj ); -static void serial_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count); -static void destroy_serial(struct object *obj); -static void serial_poll_event( struct object *obj, int event ); -static int serial_flush( struct object *obj ); +static void serial_destroy(struct object *obj); + +static int serial_get_poll_events( struct fd *fd ); +static void serial_poll_event( struct fd *fd, int event ); +static int serial_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ); +static int serial_flush( struct fd *fd ); +static void serial_queue_async(struct fd *fd, void *ptr, unsigned int status, int type, int count); struct serial { @@ -93,8 +94,7 @@ static const struct object_ops serial_ops = default_fd_signaled, /* signaled */ no_satisfied, /* satisfied */ default_get_fd, /* get_fd */ - serial_get_info, /* get_file_info */ - destroy_serial /* destroy */ + serial_destroy /* destroy */ }; static const struct fd_ops serial_fd_ops = @@ -166,7 +166,7 @@ static struct serial *create_serial( const char *nameptr, size_t len, unsigned i return serial; } -static void destroy_serial( struct object *obj) +static void serial_destroy( struct object *obj) { struct serial *serial = (struct serial *)obj; @@ -179,7 +179,7 @@ static void serial_dump( struct object *obj, int verbose ) { struct serial *serial = (struct serial *)obj; assert( obj->ops == &serial_ops ); - fprintf( stderr, "Port fd=%d mask=%x\n", serial->obj.fd, serial->eventmask ); + fprintf( stderr, "Port fd=%p mask=%x\n", serial->obj.fd_obj, serial->eventmask ); } struct serial *get_serial_obj( struct process *process, obj_handle_t handle, unsigned int access ) @@ -187,11 +187,11 @@ struct serial *get_serial_obj( struct process *process, obj_handle_t handle, uns return (struct serial *)get_handle_obj( process, handle, access, &serial_ops ); } -static int serial_get_poll_events( struct object *obj ) +static int serial_get_poll_events( struct fd *fd ) { - struct serial *serial = (struct serial *)obj; + struct serial *serial = get_fd_user( fd ); int events = 0; - assert( obj->ops == &serial_ops ); + assert( serial->obj.ops == &serial_ops ); if(IS_READY(serial->read_q)) events |= POLLIN; @@ -205,10 +205,10 @@ static int serial_get_poll_events( struct object *obj ) return events; } -static int serial_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) +static int serial_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ) { - struct serial *serial = (struct serial *) obj; - assert( obj->ops == &serial_ops ); + struct serial *serial = get_fd_user( fd ); + assert( serial->obj.ops == &serial_ops ); if (reply) { @@ -234,9 +234,9 @@ static int serial_get_info( struct object *obj, struct get_file_info_reply *repl return FD_TYPE_DEFAULT; } -static void serial_poll_event(struct object *obj, int event) +static void serial_poll_event(struct fd *fd, int event) { - struct serial *serial = (struct serial *)obj; + struct serial *serial = get_fd_user( fd ); /* fprintf(stderr,"Poll event %02x\n",event); */ @@ -249,17 +249,17 @@ static void serial_poll_event(struct object *obj, int event) if(IS_READY(serial->wait_q) && (POLLIN & event) ) async_notify(serial->wait_q.head,STATUS_ALERTED); - set_select_events( obj, serial_get_poll_events(obj) ); + set_select_events( &serial->obj, serial_get_poll_events(fd) ); } -static void serial_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count) +static void serial_queue_async(struct fd *fd, void *ptr, unsigned int status, int type, int count) { - struct serial *serial = (struct serial *)obj; + struct serial *serial = get_fd_user( fd ); struct async_queue *q; struct async *async; int timeout; - assert(obj->ops == &serial_ops); + assert(serial->obj.ops == &serial_ops); switch(type) { @@ -284,10 +284,10 @@ static void serial_queue_async(struct object *obj, void *ptr, unsigned int statu if ( status == STATUS_PENDING ) { - struct pollfd pfd; + int events; if ( !async ) - async = create_async ( obj, current, ptr ); + async = create_async ( &serial->obj, current, ptr ); if ( !async ) return; @@ -299,30 +299,26 @@ static void serial_queue_async(struct object *obj, void *ptr, unsigned int statu } /* Check if the new pending request can be served immediately */ - pfd.fd = get_unix_fd( obj ); - pfd.events = serial_get_poll_events ( obj ); - pfd.revents = 0; - poll ( &pfd, 1, 0 ); - - if ( pfd.revents ) + events = check_fd_events( fd, serial_get_poll_events( fd ) ); + if (events) + { /* serial_poll_event() calls set_select_events() */ - serial_poll_event ( obj, pfd.revents ); - else - set_select_events ( obj, pfd.events ); - return; + serial_poll_event( fd, events ); + return; + } } else if ( async ) destroy_async ( async ); else set_error ( STATUS_INVALID_PARAMETER ); - set_select_events ( obj, serial_get_poll_events ( obj )); + set_select_events ( &serial->obj, serial_get_poll_events( fd )); } -static int serial_flush( struct object *obj ) +static int serial_flush( struct fd *fd ) { /* MSDN says: If hFile is a handle to a communications device, * the function only flushes the transmit buffer. */ - int ret = (tcflush( get_unix_fd(obj), TCOFLUSH ) != -1); + int ret = (tcflush( get_unix_fd(fd), TCOFLUSH ) != -1); if (!ret) file_set_error(); return ret; } diff --git a/server/smb.c b/server/smb.c index c3ab30b1e49..4bb777478cf 100644 --- a/server/smb.c +++ b/server/smb.c @@ -52,9 +52,10 @@ #include "request.h" static void smb_dump( struct object *obj, int verbose ); -static int smb_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); -static int smb_get_poll_events( struct object *obj ); -static void destroy_smb(struct object *obj); +static void smb_destroy(struct object *obj); + +static int smb_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ); +static int smb_get_poll_events( struct fd *fd ); struct smb { @@ -75,8 +76,7 @@ static const struct object_ops smb_ops = default_fd_signaled, /* signaled */ no_satisfied, /* satisfied */ default_get_fd, /* get_fd */ - smb_get_info, /* get_file_info */ - destroy_smb /* destroy */ + smb_destroy /* destroy */ }; static const struct fd_ops smb_fd_ops = @@ -88,7 +88,7 @@ static const struct fd_ops smb_fd_ops = no_queue_async /* queue_async */ }; -static void destroy_smb( struct object *obj) +static void smb_destroy( struct object *obj) { /* struct smb *smb = (struct smb *)obj; */ assert( obj->ops == &smb_ops ); @@ -98,7 +98,7 @@ static void smb_dump( struct object *obj, int verbose ) { struct smb *smb = (struct smb *)obj; assert( obj->ops == &smb_ops ); - fprintf( stderr, "smb file with socket fd=%d \n", smb->obj.fd ); + fprintf( stderr, "Smb file fd=%p\n", smb->obj.fd_obj ); } struct smb *get_smb_obj( struct process *process, obj_handle_t handle, unsigned int access ) @@ -106,11 +106,11 @@ struct smb *get_smb_obj( struct process *process, obj_handle_t handle, unsigned return (struct smb *)get_handle_obj( process, handle, access, &smb_ops ); } -static int smb_get_poll_events( struct object *obj ) +static int smb_get_poll_events( struct fd *fd ) { - /* struct smb *smb = (struct smb *)obj; */ + struct smb *smb = get_fd_user( fd ); int events = 0; - assert( obj->ops == &smb_ops ); + assert( smb->obj.ops == &smb_ops ); events |= POLLIN; @@ -119,10 +119,10 @@ static int smb_get_poll_events( struct object *obj ) return events; } -static int smb_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) +static int smb_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ) { - /* struct smb *smb = (struct smb *) obj; */ - assert( obj->ops == &smb_ops ); +/* struct smb *smb = get_fd_user( fd ); */ +/* assert( smb->obj.ops == &smb_ops ); */ if (reply) { diff --git a/server/snapshot.c b/server/snapshot.c index 90a8bf4ed0b..c1284a0d828 100644 --- a/server/snapshot.c +++ b/server/snapshot.c @@ -62,7 +62,6 @@ static const struct object_ops snapshot_ops = NULL, /* signaled */ NULL, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ snapshot_destroy /* destroy */ }; diff --git a/server/sock.c b/server/sock.c index 3a4e514af35..44e0088b04c 100644 --- a/server/sock.c +++ b/server/sock.c @@ -84,13 +84,15 @@ struct sock static void sock_dump( struct object *obj, int verbose ); static int sock_signaled( struct object *obj, struct thread *thread ); -static int sock_get_poll_events( struct object *obj ); -static void sock_poll_event( struct object *obj, int event ); -static int sock_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static void sock_destroy( struct object *obj ); + +static int sock_get_poll_events( struct fd *fd ); +static void sock_poll_event( struct fd *fd, int event ); +static int sock_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ); +static void sock_queue_async( struct fd *fd, void *ptr, unsigned int status, int type, int count ); + static int sock_get_error( int err ); static void sock_set_error(void); -static void sock_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count); static const struct object_ops sock_ops = { @@ -101,7 +103,6 @@ static const struct object_ops sock_ops = sock_signaled, /* signaled */ no_satisfied, /* satisfied */ default_get_fd, /* get_fd */ - sock_get_info, /* get_file_info */ sock_destroy /* destroy */ }; @@ -192,10 +193,10 @@ void sock_init(void) static int sock_reselect( struct sock *sock ) { - int ev = sock_get_poll_events( &sock->obj ); + int ev = sock_get_poll_events( sock->obj.fd_obj ); if (debug_level) - fprintf(stderr,"sock_reselect(%d): new mask %x\n", sock->obj.fd, ev); + fprintf(stderr,"sock_reselect(%p): new mask %x\n", sock, ev); if (sock->obj.select == -1) { /* previously unconnected socket, is this reselect supposed to connect it? */ @@ -212,17 +213,11 @@ static int sock_reselect( struct sock *sock ) This function is used to signal pending events nevertheless */ static void sock_try_event ( struct sock *sock, int event ) { - struct pollfd pfd; - - pfd.fd = sock->obj.fd; - pfd.events = event; - pfd.revents = 0; - poll (&pfd, 1, 0); - - if ( pfd.revents ) + event = check_fd_events( sock->obj.fd_obj, event ); + if (event) { - if ( debug_level ) fprintf ( stderr, "sock_try_event: %x\n", pfd.revents ); - sock_poll_event ( &sock->obj, pfd.revents ); + if ( debug_level ) fprintf ( stderr, "sock_try_event: %x\n", event ); + sock_poll_event ( sock->obj.fd_obj, event ); } } @@ -275,23 +270,23 @@ static void sock_wake_up( struct sock *sock, int pollev ) } } -inline static int sock_error(int s) +inline static int sock_error( struct fd *fd ) { unsigned int optval = 0, optlen; optlen = sizeof(optval); - getsockopt(s, SOL_SOCKET, SO_ERROR, (void *) &optval, &optlen); + getsockopt( get_unix_fd(fd), SOL_SOCKET, SO_ERROR, (void *) &optval, &optlen); return optval ? sock_get_error(optval) : 0; } -static void sock_poll_event( struct object *obj, int event ) +static void sock_poll_event( struct fd *fd, int event ) { - struct sock *sock = (struct sock *)obj; + struct sock *sock = get_fd_user( fd ); int hangup_seen = 0; assert( sock->obj.ops == &sock_ops ); if (debug_level) - fprintf(stderr, "socket %d select event: %x\n", sock->obj.fd, event); + fprintf(stderr, "socket %p select event: %x\n", sock, event); if (sock->state & FD_CONNECT) { /* connecting */ @@ -303,16 +298,16 @@ static void sock_poll_event( struct object *obj, int event ) sock->pmask |= FD_CONNECT; sock->errors[FD_CONNECT_BIT] = 0; if (debug_level) - fprintf(stderr, "socket %d connection success\n", sock->obj.fd); + fprintf(stderr, "socket %p connection success\n", sock); } else if (event & (POLLERR|POLLHUP)) { /* we didn't get connected? */ sock->state &= ~FD_CONNECT; sock->pmask |= FD_CONNECT; - sock->errors[FD_CONNECT_BIT] = sock_error( sock->obj.fd ); + sock->errors[FD_CONNECT_BIT] = sock_error( fd ); if (debug_level) - fprintf(stderr, "socket %d connection failure\n", sock->obj.fd); + fprintf(stderr, "socket %p connection failure\n", sock); } } else if (sock->state & FD_WINE_LISTENING) @@ -329,7 +324,7 @@ static void sock_poll_event( struct object *obj, int event ) { /* failed incoming connection? */ sock->pmask |= FD_ACCEPT; - sock->errors[FD_ACCEPT_BIT] = sock_error( sock->obj.fd ); + sock->errors[FD_ACCEPT_BIT] = sock_error( fd ); sock->hmask |= FD_ACCEPT; } } else @@ -342,7 +337,7 @@ static void sock_poll_event( struct object *obj, int event ) /* Linux 2.4 doesn't report POLLHUP if only one side of the socket * has been closed, so we need to check for it explicitly here */ - nr = recv( sock->obj.fd, &dummy, 1, MSG_PEEK ); + nr = recv( get_unix_fd( fd ), &dummy, 1, MSG_PEEK ); if ( nr > 0 ) { /* incoming data */ @@ -350,7 +345,7 @@ static void sock_poll_event( struct object *obj, int event ) sock->hmask |= (FD_READ|FD_CLOSE); sock->errors[FD_READ_BIT] = 0; if (debug_level) - fprintf(stderr, "socket %d is readable\n", sock->obj.fd ); + fprintf(stderr, "socket %p is readable\n", sock ); } else if ( nr == 0 ) hangup_seen = 1; @@ -363,7 +358,7 @@ static void sock_poll_event( struct object *obj, int event ) else { if ( debug_level ) - fprintf ( stderr, "recv error on socket %d: %d\n", sock->obj.fd, errno ); + fprintf ( stderr, "recv error on socket %p: %d\n", sock, errno ); event = POLLERR; } } @@ -379,7 +374,7 @@ static void sock_poll_event( struct object *obj, int event ) sock->hmask |= (FD_READ|FD_CLOSE); sock->errors[FD_READ_BIT] = 0; if (debug_level) - fprintf(stderr, "socket %d is readable\n", sock->obj.fd ); + fprintf(stderr, "socket %p is readable\n", sock ); } @@ -389,7 +384,7 @@ static void sock_poll_event( struct object *obj, int event ) sock->hmask |= FD_WRITE; sock->errors[FD_WRITE_BIT] = 0; if (debug_level) - fprintf(stderr, "socket %d is writable\n", sock->obj.fd); + fprintf(stderr, "socket %p is writable\n", sock); } if (event & POLLPRI) { @@ -397,27 +392,27 @@ static void sock_poll_event( struct object *obj, int event ) sock->hmask |= FD_OOB; sock->errors[FD_OOB_BIT] = 0; if (debug_level) - fprintf(stderr, "socket %d got OOB data\n", sock->obj.fd); + fprintf(stderr, "socket %p got OOB data\n", sock); } /* According to WS2 specs, FD_CLOSE is only delivered when there is no more data to be read (i.e. hangup_seen = 1) */ else if ( hangup_seen && (sock->state & (FD_READ|FD_WRITE) )) { - sock->errors[FD_CLOSE_BIT] = sock_error( sock->obj.fd ); + sock->errors[FD_CLOSE_BIT] = sock_error( fd ); if ( (event & POLLERR) || ( sock_shutdown_type == SOCK_SHUTDOWN_EOF && (event & POLLHUP) )) sock->state &= ~FD_WRITE; sock->pmask |= FD_CLOSE; sock->hmask |= FD_CLOSE; if (debug_level) - fprintf(stderr, "socket %d aborted by error %d, event: %x - removing from select loop\n", - sock->obj.fd, sock->errors[FD_CLOSE_BIT], event); + fprintf(stderr, "socket %p aborted by error %d, event: %x - removing from select loop\n", + sock, sock->errors[FD_CLOSE_BIT], event); } } if ( sock->pmask & FD_CLOSE || event & (POLLERR|POLLHUP) ) { if ( debug_level ) - fprintf ( stderr, "removing socket %d from select loop\n", sock->obj.fd ); + fprintf ( stderr, "removing socket %p from select loop\n", sock ); set_select_events( &sock->obj, -1 ); } else @@ -435,8 +430,8 @@ static void sock_dump( struct object *obj, int verbose ) { struct sock *sock = (struct sock *)obj; assert( obj->ops == &sock_ops ); - printf( "Socket fd=%d, state=%x, mask=%x, pending=%x, held=%x\n", - sock->obj.fd, sock->state, + printf( "Socket fd=%p, state=%x, mask=%x, pending=%x, held=%x\n", + sock->obj.fd_obj, sock->state, sock->mask, sock->pmask, sock->hmask ); } @@ -445,16 +440,16 @@ static int sock_signaled( struct object *obj, struct thread *thread ) struct sock *sock = (struct sock *)obj; assert( obj->ops == &sock_ops ); - return check_select_events( get_unix_fd(obj), sock_get_poll_events( &sock->obj ) ); + return check_fd_events( sock->obj.fd_obj, sock_get_poll_events( sock->obj.fd_obj ) ) != 0; } -static int sock_get_poll_events( struct object *obj ) +static int sock_get_poll_events( struct fd *fd ) { - struct sock *sock = (struct sock *)obj; + struct sock *sock = get_fd_user( fd ); unsigned int mask = sock->mask & sock->state & ~sock->hmask; int ev = 0; - assert( obj->ops == &sock_ops ); + assert( sock->obj.ops == &sock_ops ); if (sock->state & FD_CONNECT) /* connecting, wait for writable */ @@ -474,10 +469,10 @@ static int sock_get_poll_events( struct object *obj ) return ev; } -static int sock_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) +static int sock_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags ) { - struct sock *sock = (struct sock*) obj; - assert ( obj->ops == &sock_ops ); + struct sock *sock = get_fd_user( fd ); + assert ( sock->obj.ops == &sock_ops ); if (reply) { @@ -502,14 +497,14 @@ static int sock_get_info( struct object *obj, struct get_file_info_reply *reply, return FD_TYPE_SOCKET; } -static void sock_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count) +static void sock_queue_async(struct fd *fd, void *ptr, unsigned int status, int type, int count) { - struct sock *sock = (struct sock *)obj; + struct sock *sock = get_fd_user( fd ); struct async_queue *q; struct async *async; int pollev; - assert( obj->ops == &sock_ops ); + assert( sock->obj.ops == &sock_ops ); if ( !(sock->flags & WSA_FLAG_OVERLAPPED) ) { @@ -544,7 +539,7 @@ static void sock_queue_async(struct object *obj, void *ptr, unsigned int status, else { if ( !async ) - async = create_async ( obj, current, ptr ); + async = create_async ( &sock->obj, current, ptr ); if ( !async ) return; @@ -640,7 +635,7 @@ static struct sock *accept_socket( obj_handle_t handle ) * return. */ slen = sizeof(saddr); - acceptfd = accept( get_unix_fd(&sock->obj), &saddr, &slen); + acceptfd = accept( get_unix_fd(sock->obj.fd_obj), &saddr, &slen); if (acceptfd==-1) { sock_set_error(); release_object( sock ); diff --git a/server/thread.c b/server/thread.c index a649da3fbea..8b3ca12a868 100644 --- a/server/thread.c +++ b/server/thread.c @@ -75,7 +75,7 @@ struct thread_apc static void dump_thread( struct object *obj, int verbose ); static int thread_signaled( struct object *obj, struct thread *thread ); -static void thread_poll_event( struct object *obj, int event ); +static void thread_poll_event( struct fd *fd, int event ); static void destroy_thread( struct object *obj ); static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system_only ); @@ -88,7 +88,6 @@ static const struct object_ops thread_ops = thread_signaled, /* signaled */ no_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ destroy_thread /* destroy */ }; @@ -179,10 +178,10 @@ struct thread *create_thread( int fd, struct process *process ) } /* handle a client event */ -static void thread_poll_event( struct object *obj, int event ) +static void thread_poll_event( struct fd *fd, int event ) { - struct thread *thread = (struct thread *)obj; - assert( obj->ops == &thread_ops ); + struct thread *thread = get_fd_user( fd ); + assert( thread->obj.ops == &thread_ops ); if (event & (POLLERR | POLLHUP)) kill_thread( thread, 0 ); else if (event & POLLIN) read_request( thread ); diff --git a/server/timer.c b/server/timer.c index 2d48fc6be65..22e4e7906bc 100644 --- a/server/timer.c +++ b/server/timer.c @@ -58,7 +58,6 @@ static const struct object_ops timer_ops = timer_signaled, /* signaled */ timer_satisfied, /* satisfied */ no_get_fd, /* get_fd */ - no_get_file_info, /* get_file_info */ timer_destroy /* destroy */ }; diff --git a/server/trace.c b/server/trace.c index 50695344719..7611f7e9f5b 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1289,6 +1289,16 @@ static void dump_create_device_reply( const struct create_device_reply *req ) fprintf( stderr, " handle=%p", req->handle ); } +static void dump_get_device_id_request( const struct get_device_id_request *req ) +{ + fprintf( stderr, " handle=%p", req->handle ); +} + +static void dump_get_device_id_reply( const struct get_device_id_reply *req ) +{ + fprintf( stderr, " id=%d", req->id ); +} + static void dump_create_snapshot_request( const struct create_snapshot_request *req ) { fprintf( stderr, " inherit=%d,", req->inherit ); @@ -2468,6 +2478,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_open_mapping_request, (dump_func)dump_get_mapping_info_request, (dump_func)dump_create_device_request, + (dump_func)dump_get_device_id_request, (dump_func)dump_create_snapshot_request, (dump_func)dump_next_process_request, (dump_func)dump_next_thread_request, @@ -2644,6 +2655,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_open_mapping_reply, (dump_func)dump_get_mapping_info_reply, (dump_func)dump_create_device_reply, + (dump_func)dump_get_device_id_reply, (dump_func)dump_create_snapshot_reply, (dump_func)dump_next_process_reply, (dump_func)dump_next_thread_reply, @@ -2820,6 +2832,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "open_mapping", "get_mapping_info", "create_device", + "get_device_id", "create_snapshot", "next_process", "next_thread", diff --git a/win32/device.c b/win32/device.c index 2886dc3e3ff..860a87fd238 100644 --- a/win32/device.c +++ b/win32/device.c @@ -359,11 +359,10 @@ HANDLE DEVICE_Open( LPCWSTR filenameW, DWORD access, LPSECURITY_ATTRIBUTES sa ) static DWORD DEVICE_GetClientID( HANDLE handle ) { DWORD ret = 0; - SERVER_START_REQ( get_file_info ) + SERVER_START_REQ( get_device_id ) { req->handle = handle; - if (!wine_server_call( req ) && (reply->type == FILE_TYPE_UNKNOWN)) - ret = reply->attr; + if (!wine_server_call( req )) ret = reply->id; } SERVER_END_REQ; return ret;