Changed fd operations to take a struct fd instead of a struct object.
Removed get_file_info function from object operations. Added get_device_id request to avoid abusing get_file_info.
This commit is contained in:
parent
00ccf38987
commit
cf27a7fa3b
|
@ -832,14 +832,14 @@ const DOS_DEVICE *DOSFS_GetDevice( LPCWSTR name )
|
||||||
const DOS_DEVICE *DOSFS_GetDeviceByHandle( HANDLE hFile )
|
const DOS_DEVICE *DOSFS_GetDeviceByHandle( HANDLE hFile )
|
||||||
{
|
{
|
||||||
const DOS_DEVICE *ret = NULL;
|
const DOS_DEVICE *ret = NULL;
|
||||||
SERVER_START_REQ( get_file_info )
|
SERVER_START_REQ( get_device_id )
|
||||||
{
|
{
|
||||||
req->handle = hFile;
|
req->handle = hFile;
|
||||||
if (!wine_server_call( req ) && (reply->type == FILE_TYPE_UNKNOWN))
|
if (!wine_server_call( req ))
|
||||||
{
|
{
|
||||||
if ((reply->attr >= 0) &&
|
if ((reply->id >= 0) &&
|
||||||
(reply->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0])))
|
(reply->id < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0])))
|
||||||
ret = &DOSFS_Devices[reply->attr];
|
ret = &DOSFS_Devices[reply->id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
|
@ -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_HEAPLIST 0x00000001
|
||||||
#define SNAP_PROCESS 0x00000002
|
#define SNAP_PROCESS 0x00000002
|
||||||
#define SNAP_THREAD 0x00000004
|
#define SNAP_THREAD 0x00000004
|
||||||
|
@ -3080,6 +3093,7 @@ enum request
|
||||||
REQ_open_mapping,
|
REQ_open_mapping,
|
||||||
REQ_get_mapping_info,
|
REQ_get_mapping_info,
|
||||||
REQ_create_device,
|
REQ_create_device,
|
||||||
|
REQ_get_device_id,
|
||||||
REQ_create_snapshot,
|
REQ_create_snapshot,
|
||||||
REQ_next_process,
|
REQ_next_process,
|
||||||
REQ_next_thread,
|
REQ_next_thread,
|
||||||
|
@ -3260,6 +3274,7 @@ union generic_request
|
||||||
struct open_mapping_request open_mapping_request;
|
struct open_mapping_request open_mapping_request;
|
||||||
struct get_mapping_info_request get_mapping_info_request;
|
struct get_mapping_info_request get_mapping_info_request;
|
||||||
struct create_device_request create_device_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 create_snapshot_request create_snapshot_request;
|
||||||
struct next_process_request next_process_request;
|
struct next_process_request next_process_request;
|
||||||
struct next_thread_request next_thread_request;
|
struct next_thread_request next_thread_request;
|
||||||
|
@ -3438,6 +3453,7 @@ union generic_reply
|
||||||
struct open_mapping_reply open_mapping_reply;
|
struct open_mapping_reply open_mapping_reply;
|
||||||
struct get_mapping_info_reply get_mapping_info_reply;
|
struct get_mapping_info_reply get_mapping_info_reply;
|
||||||
struct create_device_reply create_device_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 create_snapshot_reply create_snapshot_reply;
|
||||||
struct next_process_reply next_process_reply;
|
struct next_process_reply next_process_reply;
|
||||||
struct next_thread_reply next_thread_reply;
|
struct next_thread_reply next_thread_reply;
|
||||||
|
@ -3535,6 +3551,6 @@ union generic_reply
|
||||||
struct get_next_hook_reply get_next_hook_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 */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -72,7 +72,6 @@ static const struct object_ops atom_table_ops =
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satified */
|
NULL, /* satified */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
atom_table_destroy /* destroy */
|
atom_table_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,6 @@ static const struct object_ops change_ops =
|
||||||
change_signaled, /* signaled */
|
change_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
no_destroy /* destroy */
|
no_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,6 @@ static void console_input_dump( struct object *obj, int verbose );
|
||||||
static void console_input_destroy( struct object *obj );
|
static void console_input_destroy( struct object *obj );
|
||||||
static int console_input_signaled( struct object *obj, struct thread *thread );
|
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 =
|
static const struct object_ops console_input_ops =
|
||||||
{
|
{
|
||||||
sizeof(struct console_input), /* size */
|
sizeof(struct console_input), /* size */
|
||||||
|
@ -52,7 +49,6 @@ static const struct object_ops console_input_ops =
|
||||||
console_input_signaled, /* signaled */
|
console_input_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
console_get_file_info, /* get_file_info */
|
|
||||||
console_input_destroy /* destroy */
|
console_input_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,7 +73,6 @@ static const struct object_ops console_input_events_ops =
|
||||||
console_input_events_signaled, /* signaled */
|
console_input_events_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
console_input_events_destroy /* destroy */
|
console_input_events_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,7 +109,6 @@ static const struct object_ops screen_buffer_ops =
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satisfied */
|
NULL, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
console_get_file_info, /* get_file_info */
|
|
||||||
screen_buffer_destroy /* destroy */
|
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 )
|
static struct console_input* console_input_get( obj_handle_t handle, unsigned access )
|
||||||
{
|
{
|
||||||
struct console_input* console = 0;
|
struct console_input* console = 0;
|
||||||
|
@ -938,25 +937,6 @@ static void console_input_dump( struct object *obj, int verbose )
|
||||||
console->active, console->evt );
|
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 )
|
static void console_input_destroy( struct object *obj )
|
||||||
{
|
{
|
||||||
struct console_input* console_in = (struct console_input *)obj;
|
struct console_input* console_in = (struct console_input *)obj;
|
||||||
|
|
|
@ -48,5 +48,6 @@ struct console_input
|
||||||
|
|
||||||
extern void inherit_console(struct thread *parent_thread, struct process *process, obj_handle_t hconin);
|
extern void inherit_console(struct thread *parent_thread, struct process *process, obj_handle_t hconin);
|
||||||
extern int free_console( struct process *process );
|
extern int free_console( struct process *process );
|
||||||
|
extern int is_console_object( struct object *obj );
|
||||||
|
|
||||||
#endif /* __WINE_SERVER_CONSOLE_H */
|
#endif /* __WINE_SERVER_CONSOLE_H */
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
|
||||||
|
#include "file.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
|
||||||
|
#include "file.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
|
||||||
|
#include "file.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,6 @@ static const struct object_ops debug_event_ops =
|
||||||
debug_event_signaled, /* signaled */
|
debug_event_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
debug_event_destroy /* destroy */
|
debug_event_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,7 +89,6 @@ static const struct object_ops debug_ctx_ops =
|
||||||
debug_ctx_signaled, /* signaled */
|
debug_ctx_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
debug_ctx_destroy /* destroy */
|
debug_ctx_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ struct device
|
||||||
};
|
};
|
||||||
|
|
||||||
static void device_dump( struct object *obj, int verbose );
|
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 =
|
static const struct object_ops device_ops =
|
||||||
{
|
{
|
||||||
|
@ -54,7 +53,6 @@ static const struct object_ops device_ops =
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satisfied */
|
NULL, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
device_get_info, /* get_file_info */
|
|
||||||
no_destroy /* destroy */
|
no_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,28 +73,6 @@ static void device_dump( struct object *obj, int verbose )
|
||||||
fprintf( stderr, "Device id=%08x\n", dev->id );
|
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 */
|
/* create a device */
|
||||||
DECL_HANDLER(create_device)
|
DECL_HANDLER(create_device)
|
||||||
{
|
{
|
||||||
|
@ -109,3 +85,16 @@ DECL_HANDLER(create_device)
|
||||||
release_object( dev );
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -51,7 +51,6 @@ static const struct object_ops event_ops =
|
||||||
event_signaled, /* signaled */
|
event_signaled, /* signaled */
|
||||||
event_satisfied, /* satisfied */
|
event_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
no_destroy /* destroy */
|
no_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
118
server/fd.c
118
server/fd.c
|
@ -32,6 +32,7 @@
|
||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
|
#include "console.h"
|
||||||
|
|
||||||
struct fd
|
struct fd
|
||||||
{
|
{
|
||||||
|
@ -54,7 +55,6 @@ static const struct object_ops fd_ops =
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satisfied */
|
NULL, /* satisfied */
|
||||||
default_get_fd, /* get_fd */
|
default_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
fd_destroy /* destroy */
|
fd_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,18 +95,17 @@ void *alloc_fd_object( const struct object_ops *ops,
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* retrieve the unix fd for an object */
|
/* retrieve the object that is using an fd */
|
||||||
int get_unix_fd( struct object *obj )
|
void *get_fd_user( struct fd *fd )
|
||||||
{
|
{
|
||||||
struct fd *fd = obj->ops->get_fd( obj );
|
return fd->user;
|
||||||
int unix_fd = -1;
|
}
|
||||||
|
|
||||||
if (fd)
|
/* retrieve the unix fd for an object */
|
||||||
{
|
int get_unix_fd( struct fd *fd )
|
||||||
unix_fd = fd->unix_fd;
|
{
|
||||||
release_object( fd );
|
if (fd) return fd->unix_fd;
|
||||||
}
|
return -1;
|
||||||
return unix_fd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the unix fd for an object; can only be done once */
|
/* 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;
|
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 */
|
/* callback for event happening in the main poll() loop */
|
||||||
void fd_poll_event( struct object *obj, int event )
|
void fd_poll_event( struct object *obj, int event )
|
||||||
{
|
{
|
||||||
struct fd *fd = obj->fd_obj;
|
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 */
|
/* 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;
|
struct fd *fd = obj->fd_obj;
|
||||||
|
|
||||||
if (!obj->head) /* first on the queue */
|
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 );
|
add_queue( obj, entry );
|
||||||
return 1;
|
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 )
|
int default_fd_signaled( struct object *obj, struct thread *thread )
|
||||||
{
|
{
|
||||||
struct fd *fd = obj->fd_obj;
|
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 */
|
/* stop waiting on select() if we are signaled */
|
||||||
set_select_events( obj, 0 );
|
set_select_events( obj, 0 );
|
||||||
|
@ -172,15 +176,31 @@ int default_fd_signaled( struct object *obj, struct thread *thread )
|
||||||
return 0;
|
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 */
|
/* default flush() routine */
|
||||||
int no_flush( struct object *obj )
|
int no_flush( struct fd *fd )
|
||||||
{
|
{
|
||||||
set_error( STATUS_OBJECT_TYPE_MISMATCH );
|
set_error( STATUS_OBJECT_TYPE_MISMATCH );
|
||||||
return 0;
|
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 */
|
/* 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 );
|
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 fd *fd = NULL;
|
||||||
struct object *obj;
|
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 );
|
if (obj->fd_obj) fd = (struct fd *)grab_object( obj->fd_obj );
|
||||||
else set_error( STATUS_OBJECT_TYPE_MISMATCH );
|
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;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* flush a file buffers */
|
/* flush a file buffers */
|
||||||
DECL_HANDLER(flush_file)
|
DECL_HANDLER(flush_file)
|
||||||
{
|
{
|
||||||
|
@ -209,7 +228,52 @@ DECL_HANDLER(flush_file)
|
||||||
|
|
||||||
if (fd)
|
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 );
|
release_object( fd );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +302,7 @@ DECL_HANDLER(register_async)
|
||||||
|
|
||||||
if (fd)
|
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 );
|
release_object( fd );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
106
server/file.c
106
server/file.c
|
@ -66,12 +66,13 @@ struct file
|
||||||
static struct file *file_hash[NAME_HASH_SIZE];
|
static struct file *file_hash[NAME_HASH_SIZE];
|
||||||
|
|
||||||
static void file_dump( struct object *obj, int verbose );
|
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_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 =
|
static const struct object_ops file_ops =
|
||||||
{
|
{
|
||||||
|
@ -82,7 +83,6 @@ static const struct object_ops file_ops =
|
||||||
default_fd_signaled, /* signaled */
|
default_fd_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
default_get_fd, /* get_fd */
|
default_get_fd, /* get_fd */
|
||||||
file_get_info, /* get_file_info */
|
|
||||||
file_destroy /* destroy */
|
file_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -264,23 +264,23 @@ static void file_dump( struct object *obj, int verbose )
|
||||||
{
|
{
|
||||||
struct file *file = (struct file *)obj;
|
struct file *file = (struct file *)obj;
|
||||||
assert( obj->ops == &file_ops );
|
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;
|
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_READ) events |= POLLIN;
|
||||||
if (file->access & GENERIC_WRITE) events |= POLLOUT;
|
if (file->access & GENERIC_WRITE) events |= POLLOUT;
|
||||||
return events;
|
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;
|
struct file *file = get_fd_user( fd );
|
||||||
assert( obj->ops == &file_ops );
|
assert( file->obj.ops == &file_ops );
|
||||||
if ( file->flags & FILE_FLAG_OVERLAPPED )
|
if ( file->flags & FILE_FLAG_OVERLAPPED )
|
||||||
{
|
{
|
||||||
if( IS_READY(file->read_q) && (POLLIN & event) )
|
if( IS_READY(file->read_q) && (POLLIN & event) )
|
||||||
|
@ -294,22 +294,22 @@ static void file_poll_event( struct object *obj, int event )
|
||||||
return;
|
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();
|
if (!ret) file_set_error();
|
||||||
return ret;
|
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 stat st;
|
||||||
struct file *file = (struct file *)obj;
|
struct file *file = get_fd_user( fd );
|
||||||
int unix_fd = get_unix_fd( obj );
|
int unix_fd = get_unix_fd( fd );
|
||||||
|
|
||||||
if (reply)
|
if (reply)
|
||||||
{
|
{
|
||||||
|
@ -346,13 +346,13 @@ static int file_get_info( struct object *obj, struct get_file_info_reply *reply,
|
||||||
return FD_TYPE_DEFAULT;
|
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 *async;
|
||||||
struct async_queue *q;
|
struct async_queue *q;
|
||||||
|
|
||||||
assert( obj->ops == &file_ops );
|
assert( file->obj.ops == &file_ops );
|
||||||
|
|
||||||
if ( !(file->flags & FILE_FLAG_OVERLAPPED) )
|
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 )
|
if ( status == STATUS_PENDING )
|
||||||
{
|
{
|
||||||
struct pollfd pfd;
|
int events;
|
||||||
|
|
||||||
if ( !async )
|
if ( !async )
|
||||||
async = create_async ( obj, current, ptr );
|
async = create_async ( &file->obj, current, ptr );
|
||||||
if ( !async )
|
if ( !async )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -389,18 +389,13 @@ static void file_queue_async(struct object *obj, void *ptr, unsigned int status,
|
||||||
async_insert( q, async );
|
async_insert( q, async );
|
||||||
|
|
||||||
/* Check if the new pending request can be served immediately */
|
/* Check if the new pending request can be served immediately */
|
||||||
pfd.fd = get_unix_fd( obj );
|
events = check_fd_events( fd, file_get_poll_events( fd ) );
|
||||||
pfd.events = file_get_poll_events ( obj );
|
if (events) file_poll_event ( fd, events );
|
||||||
pfd.revents = 0;
|
|
||||||
poll ( &pfd, 1, 0 );
|
|
||||||
|
|
||||||
if ( pfd.revents )
|
|
||||||
file_poll_event ( obj, pfd.revents );
|
|
||||||
}
|
}
|
||||||
else if ( async ) destroy_async ( async );
|
else if ( async ) destroy_async ( async );
|
||||||
else set_error ( STATUS_INVALID_PARAMETER );
|
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 )
|
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 );
|
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 )
|
static int set_file_pointer( obj_handle_t handle, unsigned int *low, int *high, int whence )
|
||||||
{
|
{
|
||||||
struct file *file;
|
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);
|
xto = *low+((off_t)*high<<32);
|
||||||
if (!(file = get_file_obj( current->process, handle, 0 )))
|
if (!(file = get_file_obj( current->process, handle, 0 )))
|
||||||
return 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 */
|
/* 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 int extend_file( struct file *file, off_t size )
|
||||||
{
|
{
|
||||||
static const char zero;
|
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 */
|
/* extend the file one byte beyond the requested size and then truncate it */
|
||||||
/* this should work around ftruncate implementations that can't extend files */
|
/* 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 )
|
static int truncate_file( struct file *file )
|
||||||
{
|
{
|
||||||
int ret = 0;
|
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 pos = lseek( unix_fd, 0, SEEK_CUR );
|
||||||
off_t eof = lseek( unix_fd, 0, SEEK_END );
|
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;
|
int ret = 0;
|
||||||
struct stat st;
|
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);
|
off_t old_pos, size = size_low + (((off_t)size_high)<<32);
|
||||||
|
|
||||||
if (fstat( unix_fd, &st ) == -1)
|
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 */
|
/* set a file current position */
|
||||||
DECL_HANDLER(set_file_pointer)
|
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 );
|
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 */
|
/* lock a region of a file */
|
||||||
DECL_HANDLER(lock_file)
|
DECL_HANDLER(lock_file)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,28 +29,47 @@ struct fd;
|
||||||
struct fd_ops
|
struct fd_ops
|
||||||
{
|
{
|
||||||
/* get the events we want to poll() for on this object */
|
/* 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 */
|
/* a poll() event occured */
|
||||||
void (*poll_event)(struct object *,int event);
|
void (*poll_event)(struct fd *,int event);
|
||||||
/* flush the object buffers */
|
/* flush the object buffers */
|
||||||
int (*flush)(struct object *);
|
int (*flush)(struct fd *);
|
||||||
/* get file information */
|
/* 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*/
|
/* 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,
|
extern void *alloc_fd_object( const struct object_ops *ops,
|
||||||
const struct fd_ops *fd_user_ops, int unix_fd );
|
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 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 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 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 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 default_fd_signaled( struct object *obj, struct thread *thread );
|
||||||
extern int no_flush( struct object *obj );
|
extern void default_poll_event( struct fd *fd, int event );
|
||||||
extern void no_queue_async(struct object *obj, void* ptr, unsigned int status, int type, int count);
|
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 */
|
#endif /* __WINE_SERVER_FILE_H */
|
||||||
|
|
|
@ -105,7 +105,6 @@ static const struct object_ops handle_table_ops =
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satisfied */
|
NULL, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
handle_table_destroy /* destroy */
|
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 */
|
/* 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;
|
struct handle_entry *entry;
|
||||||
|
|
||||||
|
|
|
@ -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 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,
|
extern struct object *get_handle_obj( struct process *process, obj_handle_t handle,
|
||||||
unsigned int access, const struct object_ops *ops );
|
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 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,
|
extern obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, struct process *dst,
|
||||||
unsigned int access, int inherit, int options );
|
unsigned int access, int inherit, int options );
|
||||||
|
|
|
@ -67,7 +67,6 @@ static const struct object_ops hook_table_ops =
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satisfied */
|
NULL, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
hook_table_destroy /* destroy */
|
hook_table_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
@ -48,8 +49,6 @@ struct mapping
|
||||||
struct mapping *shared_prev; /* prev in shared PE mapping list */
|
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_dump( struct object *obj, int verbose );
|
||||||
static void mapping_destroy( struct object *obj );
|
static void mapping_destroy( struct object *obj );
|
||||||
|
|
||||||
|
@ -61,8 +60,7 @@ static const struct object_ops mapping_ops =
|
||||||
NULL, /* remove_queue */
|
NULL, /* remove_queue */
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satisfied */
|
NULL, /* satisfied */
|
||||||
mapping_get_fd, /* get_fd */
|
default_get_fd, /* get_fd */
|
||||||
mapping_get_info, /* get_file_info */
|
|
||||||
mapping_destroy /* destroy */
|
mapping_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,11 +103,6 @@ static void init_page_size(void)
|
||||||
#define ROUND_SIZE(addr,size) \
|
#define ROUND_SIZE(addr,size) \
|
||||||
(((int)(size) + ((int)(addr) & page_mask) + page_mask) & ~page_mask)
|
(((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 */
|
/* find the shared PE mapping for a given mapping */
|
||||||
static struct file *get_shared_file( struct mapping *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 (!(mapping->shared_file = create_temp_file( GENERIC_READ|GENERIC_WRITE ))) return 0;
|
||||||
if (!grow_file( mapping->shared_file, 0, total_size )) goto error;
|
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;
|
if (!(buffer = malloc( max_size ))) goto error;
|
||||||
|
|
||||||
|
@ -192,30 +185,33 @@ static int get_image_params( struct mapping *mapping )
|
||||||
IMAGE_DOS_HEADER dos;
|
IMAGE_DOS_HEADER dos;
|
||||||
IMAGE_NT_HEADERS nt;
|
IMAGE_NT_HEADERS nt;
|
||||||
IMAGE_SECTION_HEADER *sec = NULL;
|
IMAGE_SECTION_HEADER *sec = NULL;
|
||||||
int fd, filepos, size;
|
struct fd *fd;
|
||||||
|
int unix_fd, filepos, size;
|
||||||
|
|
||||||
/* load the headers */
|
/* load the headers */
|
||||||
|
|
||||||
if ((fd = get_mmap_fd( mapping->file )) == -1) return 0;
|
if (!(fd = get_obj_fd( (struct object *)mapping->file ))) return 0;
|
||||||
filepos = lseek( fd, 0, SEEK_SET );
|
mapping->obj.fd_obj = fd;
|
||||||
if (read( fd, &dos, sizeof(dos) ) != sizeof(dos)) goto error;
|
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 (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 (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 */
|
/* zero out Optional header in the case it's not present or partial */
|
||||||
memset(&nt.OptionalHeader, 0, sizeof(nt.OptionalHeader));
|
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 */
|
/* load the section headers */
|
||||||
|
|
||||||
size = sizeof(*sec) * nt.FileHeader.NumberOfSections;
|
size = sizeof(*sec) * nt.FileHeader.NumberOfSections;
|
||||||
if (!(sec = malloc( size ))) goto error;
|
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 */
|
if (mapping->shared_file) /* link it in the list */
|
||||||
{
|
{
|
||||||
|
@ -233,17 +229,28 @@ static int get_image_params( struct mapping *mapping )
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (mapping->header_size > mapping->size_low) goto error;
|
if (mapping->header_size > mapping->size_low) goto error;
|
||||||
|
|
||||||
lseek( fd, filepos, SEEK_SET );
|
lseek( unix_fd, filepos, SEEK_SET );
|
||||||
free( sec );
|
free( sec );
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
lseek( fd, filepos, SEEK_SET );
|
lseek( unix_fd, filepos, SEEK_SET );
|
||||||
if (sec) free( sec );
|
if (sec) free( sec );
|
||||||
set_error( STATUS_INVALID_FILE_FOR_SECTION );
|
set_error( STATUS_INVALID_FILE_FOR_SECTION );
|
||||||
return 0;
|
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,
|
static struct object *create_mapping( int size_high, int size_low, int protect,
|
||||||
obj_handle_t handle, const WCHAR *name, size_t len )
|
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)
|
if (!size_high && !size_low)
|
||||||
{
|
{
|
||||||
int flags;
|
if (!get_file_size( mapping, &size_high, &size_low )) goto error;
|
||||||
struct get_file_info_reply reply;
|
}
|
||||||
struct object *obj = (struct object *)mapping->file;
|
else
|
||||||
obj->ops->get_file_info( obj, &reply, &flags );
|
{
|
||||||
size_high = reply.size_high;
|
if (!grow_file( mapping->file, size_high, size_low )) goto error;
|
||||||
size_low = ROUND_SIZE( 0, reply.size_low );
|
|
||||||
}
|
}
|
||||||
else if (!grow_file( mapping->file, size_high, size_low )) goto error;
|
|
||||||
}
|
}
|
||||||
else /* Anonymous mapping (no associated file) */
|
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 (!(mapping->file = create_temp_file( access ))) goto error;
|
||||||
if (!grow_file( mapping->file, size_high, size_low )) 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_high = size_high;
|
||||||
mapping->size_low = ROUND_SIZE( 0, size_low );
|
mapping->size_low = ROUND_SIZE( 0, size_low );
|
||||||
mapping->protect = protect;
|
mapping->protect = protect;
|
||||||
|
@ -318,24 +324,6 @@ static void mapping_dump( struct object *obj, int verbose )
|
||||||
fputc( '\n', stderr );
|
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 )
|
static void mapping_destroy( struct object *obj )
|
||||||
{
|
{
|
||||||
struct mapping *mapping = (struct mapping *)obj;
|
struct mapping *mapping = (struct mapping *)obj;
|
||||||
|
|
|
@ -55,7 +55,6 @@ static const struct object_ops mutex_ops =
|
||||||
mutex_signaled, /* signaled */
|
mutex_signaled, /* signaled */
|
||||||
mutex_satisfied, /* satisfied */
|
mutex_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
mutex_destroy /* destroy */
|
mutex_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -94,13 +94,12 @@ static const struct object_ops named_pipe_ops =
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satisfied */
|
NULL, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
named_pipe_destroy /* destroy */
|
named_pipe_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pipe_user_dump( struct object *obj, int verbose );
|
static void pipe_user_dump( struct object *obj, int verbose );
|
||||||
static void pipe_user_destroy( struct object *obj);
|
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 =
|
static const struct object_ops pipe_user_ops =
|
||||||
{
|
{
|
||||||
|
@ -111,7 +110,6 @@ static const struct object_ops pipe_user_ops =
|
||||||
default_fd_signaled, /* signaled */
|
default_fd_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
default_get_fd, /* get_fd */
|
default_get_fd, /* get_fd */
|
||||||
pipe_user_get_info, /* get_file_info */
|
|
||||||
pipe_user_destroy /* destroy */
|
pipe_user_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -169,7 +167,7 @@ static void pipe_user_destroy( struct object *obj)
|
||||||
|
|
||||||
if(user->other)
|
if(user->other)
|
||||||
{
|
{
|
||||||
close_fd( user->other->obj.fd_obj );
|
release_object( user->other->obj.fd_obj );
|
||||||
user->other->obj.fd_obj = NULL;
|
user->other->obj.fd_obj = NULL;
|
||||||
switch(user->other->state)
|
switch(user->other->state)
|
||||||
{
|
{
|
||||||
|
@ -195,7 +193,7 @@ static void pipe_user_destroy( struct object *obj)
|
||||||
release_object(user->pipe);
|
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)
|
if (reply)
|
||||||
{
|
{
|
||||||
|
@ -443,12 +441,12 @@ DECL_HANDLER(disconnect_named_pipe)
|
||||||
if( (user->state == ps_connected_server) &&
|
if( (user->state == ps_connected_server) &&
|
||||||
(user->other->state == ps_connected_client) )
|
(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->obj.fd_obj = NULL;
|
||||||
user->other->state = ps_disconnected;
|
user->other->state = ps_disconnected;
|
||||||
user->other->other = NULL;
|
user->other->other = NULL;
|
||||||
|
|
||||||
close_fd( user->obj.fd_obj );
|
release_object( user->obj.fd_obj );
|
||||||
user->obj.fd_obj = NULL;
|
user->obj.fd_obj = NULL;
|
||||||
user->state = ps_idle_server;
|
user->state = ps_idle_server;
|
||||||
user->other = NULL;
|
user->other = NULL;
|
||||||
|
|
|
@ -220,7 +220,7 @@ void release_object( void *ptr )
|
||||||
assert( !obj->head );
|
assert( !obj->head );
|
||||||
assert( !obj->tail );
|
assert( !obj->tail );
|
||||||
obj->ops->destroy( obj );
|
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->name) free_name( obj );
|
||||||
if (obj->select != -1) remove_select_user( obj );
|
if (obj->select != -1) remove_select_user( obj );
|
||||||
if (obj->fd != -1) close( obj->fd );
|
if (obj->fd != -1) close( obj->fd );
|
||||||
|
@ -303,21 +303,6 @@ struct fd *default_get_fd( struct object *obj )
|
||||||
return NULL;
|
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 )
|
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 );
|
|
||||||
}
|
|
||||||
|
|
|
@ -60,8 +60,6 @@ struct object_ops
|
||||||
int (*satisfied)(struct object *,struct thread *);
|
int (*satisfied)(struct object *,struct thread *);
|
||||||
/* return an fd object that can be used to read/write from the object */
|
/* return an fd object that can be used to read/write from the object */
|
||||||
struct fd *(*get_fd)(struct 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 */
|
/* destroy on refcount == 0 */
|
||||||
void (*destroy)(struct object *);
|
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 int no_satisfied( struct object *obj, struct thread *thread );
|
||||||
extern struct fd *no_get_fd( struct object *obj );
|
extern struct fd *no_get_fd( struct object *obj );
|
||||||
extern struct fd *default_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 no_destroy( struct object *obj );
|
||||||
extern void default_poll_event( struct object *obj, int event );
|
|
||||||
#ifdef DEBUG_OBJECTS
|
#ifdef DEBUG_OBJECTS
|
||||||
extern void dump_objects(void);
|
extern void dump_objects(void);
|
||||||
#endif
|
#endif
|
||||||
|
@ -118,7 +114,6 @@ extern int add_select_user( struct object *obj );
|
||||||
extern void remove_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 change_select_fd( struct object *obj, int fd, int events );
|
||||||
extern void set_select_events( struct object *obj, 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);
|
extern void select_loop(void);
|
||||||
|
|
||||||
/* timeout functions */
|
/* timeout functions */
|
||||||
|
@ -153,17 +148,6 @@ extern void reset_event( struct event *event );
|
||||||
|
|
||||||
extern void abandon_mutexes( struct thread *thread );
|
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 */
|
/* serial functions */
|
||||||
|
|
||||||
int get_serial_async_timeout(struct object *obj, int type, int count);
|
int get_serial_async_timeout(struct object *obj, int type, int count);
|
||||||
|
|
|
@ -47,11 +47,12 @@ struct pipe
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pipe_dump( struct object *obj, int verbose );
|
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 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 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 =
|
static const struct object_ops pipe_ops =
|
||||||
{
|
{
|
||||||
sizeof(struct pipe), /* size */
|
sizeof(struct pipe), /* size */
|
||||||
|
@ -61,7 +62,6 @@ static const struct object_ops pipe_ops =
|
||||||
default_fd_signaled, /* signaled */
|
default_fd_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
pipe_get_fd, /* get_fd */
|
pipe_get_fd, /* get_fd */
|
||||||
pipe_get_info, /* get_file_info */
|
|
||||||
pipe_destroy /* destroy */
|
pipe_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -118,14 +118,14 @@ static void pipe_dump( struct object *obj, int verbose )
|
||||||
{
|
{
|
||||||
struct pipe *pipe = (struct pipe *)obj;
|
struct pipe *pipe = (struct pipe *)obj;
|
||||||
assert( obj->ops == &pipe_ops );
|
assert( obj->ops == &pipe_ops );
|
||||||
fprintf( stderr, "Pipe %s-side fd=%d\n",
|
fprintf( stderr, "Pipe %s-side fd=%p\n",
|
||||||
(pipe->side == READ_SIDE) ? "read" : "write", pipe->obj.fd );
|
(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;
|
struct pipe *pipe = get_fd_user( fd );
|
||||||
assert( obj->ops == &pipe_ops );
|
assert( pipe->obj.ops == &pipe_ops );
|
||||||
return (pipe->side == READ_SIDE) ? POLLIN : POLLOUT;
|
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 );
|
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)
|
if (reply)
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,7 @@ static int running_processes;
|
||||||
|
|
||||||
static void process_dump( struct object *obj, int verbose );
|
static void process_dump( struct object *obj, int verbose );
|
||||||
static int process_signaled( struct object *obj, struct thread *thread );
|
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 void process_destroy( struct object *obj );
|
||||||
|
|
||||||
static const struct object_ops process_ops =
|
static const struct object_ops process_ops =
|
||||||
|
@ -64,7 +64,6 @@ static const struct object_ops process_ops =
|
||||||
process_signaled, /* signaled */
|
process_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
process_destroy /* destroy */
|
process_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,7 +108,6 @@ static const struct object_ops startup_info_ops =
|
||||||
startup_info_signaled, /* signaled */
|
startup_info_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
startup_info_destroy /* destroy */
|
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;
|
struct process *process = get_fd_user( fd );
|
||||||
assert( obj->ops == &process_ops );
|
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 );
|
else if (event & POLLIN) receive_fd( process );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1114,6 +1114,14 @@ enum char_info_mode
|
||||||
@END
|
@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_HEAPLIST 0x00000001
|
||||||
#define SNAP_PROCESS 0x00000002
|
#define SNAP_PROCESS 0x00000002
|
||||||
#define SNAP_THREAD 0x00000004
|
#define SNAP_THREAD 0x00000004
|
||||||
|
|
|
@ -33,10 +33,10 @@
|
||||||
#endif
|
#endif
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "file.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef PTRACE_CONT
|
#ifndef PTRACE_CONT
|
||||||
#define PTRACE_CONT PT_CONTINUE
|
#define PTRACE_CONT PT_CONTINUE
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -144,7 +144,6 @@ static const struct object_ops msg_queue_ops =
|
||||||
msg_queue_signaled, /* signaled */
|
msg_queue_signaled, /* signaled */
|
||||||
msg_queue_satisfied, /* satisfied */
|
msg_queue_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
msg_queue_destroy /* destroy */
|
msg_queue_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -158,7 +157,6 @@ static const struct object_ops thread_input_ops =
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satisfied */
|
NULL, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
thread_input_destroy /* destroy */
|
thread_input_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,6 @@ static const struct object_ops key_ops =
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satisfied */
|
NULL, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
key_destroy /* destroy */
|
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 */
|
/* load a part of the registry from a file */
|
||||||
static void load_registry( struct key *key, obj_handle_t handle )
|
static void load_registry( struct key *key, obj_handle_t handle )
|
||||||
{
|
{
|
||||||
struct object *obj;
|
struct file *file;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL ))) return;
|
if (!(file = get_file_obj( current->process, handle, GENERIC_READ ))) return;
|
||||||
fd = dup( get_unix_fd( obj ) );
|
fd = dup( get_file_unix_fd( file ) );
|
||||||
release_object( obj );
|
release_object( file );
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
FILE *f = fdopen( fd, "r" );
|
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 */
|
/* save a registry branch to a file handle */
|
||||||
static void save_registry( struct key *key, obj_handle_t handle )
|
static void save_registry( struct key *key, obj_handle_t handle )
|
||||||
{
|
{
|
||||||
struct object *obj;
|
struct file *file;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (key->flags & KEY_DELETED)
|
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 );
|
set_error( STATUS_KEY_DELETED );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(obj = get_handle_obj( current->process, handle, GENERIC_WRITE, NULL ))) return;
|
if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE ))) return;
|
||||||
fd = dup( get_unix_fd( obj ) );
|
fd = dup( get_file_unix_fd( file ) );
|
||||||
release_object( obj );
|
release_object( file );
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
FILE *f = fdopen( fd, "w" );
|
FILE *f = fdopen( fd, "w" );
|
||||||
|
|
|
@ -78,7 +78,7 @@ struct master_socket
|
||||||
};
|
};
|
||||||
|
|
||||||
static void master_socket_dump( struct object *obj, int verbose );
|
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 =
|
static const struct object_ops master_socket_ops =
|
||||||
{
|
{
|
||||||
|
@ -89,7 +89,6 @@ static const struct object_ops master_socket_ops =
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satisfied */
|
NULL, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
no_destroy /* destroy */
|
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;
|
struct master_socket *sock = (struct master_socket *)obj;
|
||||||
assert( obj->ops == &master_socket_ops );
|
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 */
|
/* 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;
|
struct master_socket *sock = get_fd_user( fd );
|
||||||
assert( obj->ops == &master_socket_ops );
|
assert( master_socket->obj.ops == &master_socket_ops );
|
||||||
|
|
||||||
assert( sock == master_socket ); /* there is only one master socket */
|
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 */
|
/* this is not supposed to happen */
|
||||||
fprintf( stderr, "wineserver: Error on master socket\n" );
|
fprintf( stderr, "wineserver: Error on master socket\n" );
|
||||||
release_object( obj );
|
release_object( sock );
|
||||||
}
|
}
|
||||||
else if (event & POLLIN)
|
else if (event & POLLIN)
|
||||||
{
|
{
|
||||||
|
@ -749,7 +748,7 @@ static void close_socket_timeout( void *arg )
|
||||||
flush_registry();
|
flush_registry();
|
||||||
|
|
||||||
/* if a new client is waiting, we keep on running */
|
/* 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() );
|
if (debug_level) fprintf( stderr, "wineserver: exiting (pid=%ld)\n", (long) getpid() );
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,7 @@ DECL_HANDLER(create_mapping);
|
||||||
DECL_HANDLER(open_mapping);
|
DECL_HANDLER(open_mapping);
|
||||||
DECL_HANDLER(get_mapping_info);
|
DECL_HANDLER(get_mapping_info);
|
||||||
DECL_HANDLER(create_device);
|
DECL_HANDLER(create_device);
|
||||||
|
DECL_HANDLER(get_device_id);
|
||||||
DECL_HANDLER(create_snapshot);
|
DECL_HANDLER(create_snapshot);
|
||||||
DECL_HANDLER(next_process);
|
DECL_HANDLER(next_process);
|
||||||
DECL_HANDLER(next_thread);
|
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_open_mapping,
|
||||||
(req_handler)req_get_mapping_info,
|
(req_handler)req_get_mapping_info,
|
||||||
(req_handler)req_create_device,
|
(req_handler)req_create_device,
|
||||||
|
(req_handler)req_get_device_id,
|
||||||
(req_handler)req_create_snapshot,
|
(req_handler)req_create_snapshot,
|
||||||
(req_handler)req_next_process,
|
(req_handler)req_next_process,
|
||||||
(req_handler)req_next_thread,
|
(req_handler)req_next_thread,
|
||||||
|
|
|
@ -138,15 +138,6 @@ void set_select_events( struct object *obj, int events )
|
||||||
else if (pollfd[user].fd != -1) pollfd[user].events = 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 */
|
/* add a timeout user */
|
||||||
struct timeout_user *add_timeout_user( struct timeval *when, timeout_callback func, void *private )
|
struct timeout_user *add_timeout_user( struct timeval *when, timeout_callback func, void *private )
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,6 @@ static const struct object_ops semaphore_ops =
|
||||||
semaphore_signaled, /* signaled */
|
semaphore_signaled, /* signaled */
|
||||||
semaphore_satisfied, /* satisfied */
|
semaphore_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
no_destroy /* destroy */
|
no_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -52,12 +52,13 @@
|
||||||
#include "async.h"
|
#include "async.h"
|
||||||
|
|
||||||
static void serial_dump( struct object *obj, int verbose );
|
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 void serial_destroy(struct object *obj);
|
||||||
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 int serial_get_poll_events( struct fd *fd );
|
||||||
static void destroy_serial(struct object *obj);
|
static void serial_poll_event( struct fd *fd, int event );
|
||||||
static void serial_poll_event( struct object *obj, int event );
|
static int serial_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags );
|
||||||
static int serial_flush( struct object *obj );
|
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
|
struct serial
|
||||||
{
|
{
|
||||||
|
@ -93,8 +94,7 @@ static const struct object_ops serial_ops =
|
||||||
default_fd_signaled, /* signaled */
|
default_fd_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
default_get_fd, /* get_fd */
|
default_get_fd, /* get_fd */
|
||||||
serial_get_info, /* get_file_info */
|
serial_destroy /* destroy */
|
||||||
destroy_serial /* destroy */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fd_ops serial_fd_ops =
|
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;
|
return serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_serial( struct object *obj)
|
static void serial_destroy( struct object *obj)
|
||||||
{
|
{
|
||||||
struct serial *serial = (struct serial *)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;
|
struct serial *serial = (struct serial *)obj;
|
||||||
assert( obj->ops == &serial_ops );
|
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 )
|
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 );
|
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;
|
int events = 0;
|
||||||
assert( obj->ops == &serial_ops );
|
assert( serial->obj.ops == &serial_ops );
|
||||||
|
|
||||||
if(IS_READY(serial->read_q))
|
if(IS_READY(serial->read_q))
|
||||||
events |= POLLIN;
|
events |= POLLIN;
|
||||||
|
@ -205,10 +205,10 @@ static int serial_get_poll_events( struct object *obj )
|
||||||
return events;
|
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;
|
struct serial *serial = get_fd_user( fd );
|
||||||
assert( obj->ops == &serial_ops );
|
assert( serial->obj.ops == &serial_ops );
|
||||||
|
|
||||||
if (reply)
|
if (reply)
|
||||||
{
|
{
|
||||||
|
@ -234,9 +234,9 @@ static int serial_get_info( struct object *obj, struct get_file_info_reply *repl
|
||||||
return FD_TYPE_DEFAULT;
|
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); */
|
/* 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) )
|
if(IS_READY(serial->wait_q) && (POLLIN & event) )
|
||||||
async_notify(serial->wait_q.head,STATUS_ALERTED);
|
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_queue *q;
|
||||||
struct async *async;
|
struct async *async;
|
||||||
int timeout;
|
int timeout;
|
||||||
|
|
||||||
assert(obj->ops == &serial_ops);
|
assert(serial->obj.ops == &serial_ops);
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
|
@ -284,10 +284,10 @@ static void serial_queue_async(struct object *obj, void *ptr, unsigned int statu
|
||||||
|
|
||||||
if ( status == STATUS_PENDING )
|
if ( status == STATUS_PENDING )
|
||||||
{
|
{
|
||||||
struct pollfd pfd;
|
int events;
|
||||||
|
|
||||||
if ( !async )
|
if ( !async )
|
||||||
async = create_async ( obj, current, ptr );
|
async = create_async ( &serial->obj, current, ptr );
|
||||||
if ( !async )
|
if ( !async )
|
||||||
return;
|
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 */
|
/* Check if the new pending request can be served immediately */
|
||||||
pfd.fd = get_unix_fd( obj );
|
events = check_fd_events( fd, serial_get_poll_events( fd ) );
|
||||||
pfd.events = serial_get_poll_events ( obj );
|
if (events)
|
||||||
pfd.revents = 0;
|
{
|
||||||
poll ( &pfd, 1, 0 );
|
|
||||||
|
|
||||||
if ( pfd.revents )
|
|
||||||
/* serial_poll_event() calls set_select_events() */
|
/* serial_poll_event() calls set_select_events() */
|
||||||
serial_poll_event ( obj, pfd.revents );
|
serial_poll_event( fd, events );
|
||||||
else
|
return;
|
||||||
set_select_events ( obj, pfd.events );
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else if ( async ) destroy_async ( async );
|
else if ( async ) destroy_async ( async );
|
||||||
else set_error ( STATUS_INVALID_PARAMETER );
|
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,
|
/* MSDN says: If hFile is a handle to a communications device,
|
||||||
* the function only flushes the transmit buffer.
|
* 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();
|
if (!ret) file_set_error();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
26
server/smb.c
26
server/smb.c
|
@ -52,9 +52,10 @@
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
|
|
||||||
static void smb_dump( struct object *obj, int verbose );
|
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 void smb_destroy(struct object *obj);
|
||||||
static int smb_get_poll_events( struct object *obj );
|
|
||||||
static void destroy_smb(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
|
struct smb
|
||||||
{
|
{
|
||||||
|
@ -75,8 +76,7 @@ static const struct object_ops smb_ops =
|
||||||
default_fd_signaled, /* signaled */
|
default_fd_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
default_get_fd, /* get_fd */
|
default_get_fd, /* get_fd */
|
||||||
smb_get_info, /* get_file_info */
|
smb_destroy /* destroy */
|
||||||
destroy_smb /* destroy */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fd_ops smb_fd_ops =
|
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 */
|
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; */
|
/* struct smb *smb = (struct smb *)obj; */
|
||||||
assert( obj->ops == &smb_ops );
|
assert( obj->ops == &smb_ops );
|
||||||
|
@ -98,7 +98,7 @@ static void smb_dump( struct object *obj, int verbose )
|
||||||
{
|
{
|
||||||
struct smb *smb = (struct smb *)obj;
|
struct smb *smb = (struct smb *)obj;
|
||||||
assert( obj->ops == &smb_ops );
|
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 )
|
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 );
|
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;
|
int events = 0;
|
||||||
assert( obj->ops == &smb_ops );
|
assert( smb->obj.ops == &smb_ops );
|
||||||
|
|
||||||
events |= POLLIN;
|
events |= POLLIN;
|
||||||
|
|
||||||
|
@ -119,10 +119,10 @@ static int smb_get_poll_events( struct object *obj )
|
||||||
return events;
|
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; */
|
/* struct smb *smb = get_fd_user( fd ); */
|
||||||
assert( obj->ops == &smb_ops );
|
/* assert( smb->obj.ops == &smb_ops ); */
|
||||||
|
|
||||||
if (reply)
|
if (reply)
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,7 +62,6 @@ static const struct object_ops snapshot_ops =
|
||||||
NULL, /* signaled */
|
NULL, /* signaled */
|
||||||
NULL, /* satisfied */
|
NULL, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
snapshot_destroy /* destroy */
|
snapshot_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -84,13 +84,15 @@ struct sock
|
||||||
|
|
||||||
static void sock_dump( struct object *obj, int verbose );
|
static void sock_dump( struct object *obj, int verbose );
|
||||||
static int sock_signaled( struct object *obj, struct thread *thread );
|
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 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 int sock_get_error( int err );
|
||||||
static void sock_set_error(void);
|
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 =
|
static const struct object_ops sock_ops =
|
||||||
{
|
{
|
||||||
|
@ -101,7 +103,6 @@ static const struct object_ops sock_ops =
|
||||||
sock_signaled, /* signaled */
|
sock_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
default_get_fd, /* get_fd */
|
default_get_fd, /* get_fd */
|
||||||
sock_get_info, /* get_file_info */
|
|
||||||
sock_destroy /* destroy */
|
sock_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -192,10 +193,10 @@ void sock_init(void)
|
||||||
|
|
||||||
static int sock_reselect( struct sock *sock )
|
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)
|
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) {
|
if (sock->obj.select == -1) {
|
||||||
/* previously unconnected socket, is this reselect supposed to connect it? */
|
/* 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 */
|
This function is used to signal pending events nevertheless */
|
||||||
static void sock_try_event ( struct sock *sock, int event )
|
static void sock_try_event ( struct sock *sock, int event )
|
||||||
{
|
{
|
||||||
struct pollfd pfd;
|
event = check_fd_events( sock->obj.fd_obj, event );
|
||||||
|
if (event)
|
||||||
pfd.fd = sock->obj.fd;
|
|
||||||
pfd.events = event;
|
|
||||||
pfd.revents = 0;
|
|
||||||
poll (&pfd, 1, 0);
|
|
||||||
|
|
||||||
if ( pfd.revents )
|
|
||||||
{
|
{
|
||||||
if ( debug_level ) fprintf ( stderr, "sock_try_event: %x\n", pfd.revents );
|
if ( debug_level ) fprintf ( stderr, "sock_try_event: %x\n", event );
|
||||||
sock_poll_event ( &sock->obj, pfd.revents );
|
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;
|
unsigned int optval = 0, optlen;
|
||||||
|
|
||||||
optlen = sizeof(optval);
|
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;
|
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;
|
int hangup_seen = 0;
|
||||||
|
|
||||||
assert( sock->obj.ops == &sock_ops );
|
assert( sock->obj.ops == &sock_ops );
|
||||||
if (debug_level)
|
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)
|
if (sock->state & FD_CONNECT)
|
||||||
{
|
{
|
||||||
/* connecting */
|
/* connecting */
|
||||||
|
@ -303,16 +298,16 @@ static void sock_poll_event( struct object *obj, int event )
|
||||||
sock->pmask |= FD_CONNECT;
|
sock->pmask |= FD_CONNECT;
|
||||||
sock->errors[FD_CONNECT_BIT] = 0;
|
sock->errors[FD_CONNECT_BIT] = 0;
|
||||||
if (debug_level)
|
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))
|
else if (event & (POLLERR|POLLHUP))
|
||||||
{
|
{
|
||||||
/* we didn't get connected? */
|
/* we didn't get connected? */
|
||||||
sock->state &= ~FD_CONNECT;
|
sock->state &= ~FD_CONNECT;
|
||||||
sock->pmask |= 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)
|
if (debug_level)
|
||||||
fprintf(stderr, "socket %d connection failure\n", sock->obj.fd);
|
fprintf(stderr, "socket %p connection failure\n", sock);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
if (sock->state & FD_WINE_LISTENING)
|
if (sock->state & FD_WINE_LISTENING)
|
||||||
|
@ -329,7 +324,7 @@ static void sock_poll_event( struct object *obj, int event )
|
||||||
{
|
{
|
||||||
/* failed incoming connection? */
|
/* failed incoming connection? */
|
||||||
sock->pmask |= FD_ACCEPT;
|
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;
|
sock->hmask |= FD_ACCEPT;
|
||||||
}
|
}
|
||||||
} else
|
} 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
|
/* 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 */
|
* 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 )
|
if ( nr > 0 )
|
||||||
{
|
{
|
||||||
/* incoming data */
|
/* incoming data */
|
||||||
|
@ -350,7 +345,7 @@ static void sock_poll_event( struct object *obj, int event )
|
||||||
sock->hmask |= (FD_READ|FD_CLOSE);
|
sock->hmask |= (FD_READ|FD_CLOSE);
|
||||||
sock->errors[FD_READ_BIT] = 0;
|
sock->errors[FD_READ_BIT] = 0;
|
||||||
if (debug_level)
|
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 )
|
else if ( nr == 0 )
|
||||||
hangup_seen = 1;
|
hangup_seen = 1;
|
||||||
|
@ -363,7 +358,7 @@ static void sock_poll_event( struct object *obj, int event )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( debug_level )
|
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;
|
event = POLLERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,7 +374,7 @@ static void sock_poll_event( struct object *obj, int event )
|
||||||
sock->hmask |= (FD_READ|FD_CLOSE);
|
sock->hmask |= (FD_READ|FD_CLOSE);
|
||||||
sock->errors[FD_READ_BIT] = 0;
|
sock->errors[FD_READ_BIT] = 0;
|
||||||
if (debug_level)
|
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->hmask |= FD_WRITE;
|
||||||
sock->errors[FD_WRITE_BIT] = 0;
|
sock->errors[FD_WRITE_BIT] = 0;
|
||||||
if (debug_level)
|
if (debug_level)
|
||||||
fprintf(stderr, "socket %d is writable\n", sock->obj.fd);
|
fprintf(stderr, "socket %p is writable\n", sock);
|
||||||
}
|
}
|
||||||
if (event & POLLPRI)
|
if (event & POLLPRI)
|
||||||
{
|
{
|
||||||
|
@ -397,27 +392,27 @@ static void sock_poll_event( struct object *obj, int event )
|
||||||
sock->hmask |= FD_OOB;
|
sock->hmask |= FD_OOB;
|
||||||
sock->errors[FD_OOB_BIT] = 0;
|
sock->errors[FD_OOB_BIT] = 0;
|
||||||
if (debug_level)
|
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
|
/* According to WS2 specs, FD_CLOSE is only delivered when there is
|
||||||
no more data to be read (i.e. hangup_seen = 1) */
|
no more data to be read (i.e. hangup_seen = 1) */
|
||||||
else if ( hangup_seen && (sock->state & (FD_READ|FD_WRITE) ))
|
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) ))
|
if ( (event & POLLERR) || ( sock_shutdown_type == SOCK_SHUTDOWN_EOF && (event & POLLHUP) ))
|
||||||
sock->state &= ~FD_WRITE;
|
sock->state &= ~FD_WRITE;
|
||||||
sock->pmask |= FD_CLOSE;
|
sock->pmask |= FD_CLOSE;
|
||||||
sock->hmask |= FD_CLOSE;
|
sock->hmask |= FD_CLOSE;
|
||||||
if (debug_level)
|
if (debug_level)
|
||||||
fprintf(stderr, "socket %d aborted by error %d, event: %x - removing from select loop\n",
|
fprintf(stderr, "socket %p aborted by error %d, event: %x - removing from select loop\n",
|
||||||
sock->obj.fd, sock->errors[FD_CLOSE_BIT], event);
|
sock, sock->errors[FD_CLOSE_BIT], event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( sock->pmask & FD_CLOSE || event & (POLLERR|POLLHUP) )
|
if ( sock->pmask & FD_CLOSE || event & (POLLERR|POLLHUP) )
|
||||||
{
|
{
|
||||||
if ( debug_level )
|
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 );
|
set_select_events( &sock->obj, -1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -435,8 +430,8 @@ static void sock_dump( struct object *obj, int verbose )
|
||||||
{
|
{
|
||||||
struct sock *sock = (struct sock *)obj;
|
struct sock *sock = (struct sock *)obj;
|
||||||
assert( obj->ops == &sock_ops );
|
assert( obj->ops == &sock_ops );
|
||||||
printf( "Socket fd=%d, state=%x, mask=%x, pending=%x, held=%x\n",
|
printf( "Socket fd=%p, state=%x, mask=%x, pending=%x, held=%x\n",
|
||||||
sock->obj.fd, sock->state,
|
sock->obj.fd_obj, sock->state,
|
||||||
sock->mask, sock->pmask, sock->hmask );
|
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;
|
struct sock *sock = (struct sock *)obj;
|
||||||
assert( obj->ops == &sock_ops );
|
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;
|
unsigned int mask = sock->mask & sock->state & ~sock->hmask;
|
||||||
int ev = 0;
|
int ev = 0;
|
||||||
|
|
||||||
assert( obj->ops == &sock_ops );
|
assert( sock->obj.ops == &sock_ops );
|
||||||
|
|
||||||
if (sock->state & FD_CONNECT)
|
if (sock->state & FD_CONNECT)
|
||||||
/* connecting, wait for writable */
|
/* connecting, wait for writable */
|
||||||
|
@ -474,10 +469,10 @@ static int sock_get_poll_events( struct object *obj )
|
||||||
return ev;
|
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;
|
struct sock *sock = get_fd_user( fd );
|
||||||
assert ( obj->ops == &sock_ops );
|
assert ( sock->obj.ops == &sock_ops );
|
||||||
|
|
||||||
if (reply)
|
if (reply)
|
||||||
{
|
{
|
||||||
|
@ -502,14 +497,14 @@ static int sock_get_info( struct object *obj, struct get_file_info_reply *reply,
|
||||||
return FD_TYPE_SOCKET;
|
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_queue *q;
|
||||||
struct async *async;
|
struct async *async;
|
||||||
int pollev;
|
int pollev;
|
||||||
|
|
||||||
assert( obj->ops == &sock_ops );
|
assert( sock->obj.ops == &sock_ops );
|
||||||
|
|
||||||
if ( !(sock->flags & WSA_FLAG_OVERLAPPED) )
|
if ( !(sock->flags & WSA_FLAG_OVERLAPPED) )
|
||||||
{
|
{
|
||||||
|
@ -544,7 +539,7 @@ static void sock_queue_async(struct object *obj, void *ptr, unsigned int status,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( !async )
|
if ( !async )
|
||||||
async = create_async ( obj, current, ptr );
|
async = create_async ( &sock->obj, current, ptr );
|
||||||
if ( !async )
|
if ( !async )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -640,7 +635,7 @@ static struct sock *accept_socket( obj_handle_t handle )
|
||||||
* return.
|
* return.
|
||||||
*/
|
*/
|
||||||
slen = sizeof(saddr);
|
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) {
|
if (acceptfd==-1) {
|
||||||
sock_set_error();
|
sock_set_error();
|
||||||
release_object( sock );
|
release_object( sock );
|
||||||
|
|
|
@ -75,7 +75,7 @@ struct thread_apc
|
||||||
|
|
||||||
static void dump_thread( struct object *obj, int verbose );
|
static void dump_thread( struct object *obj, int verbose );
|
||||||
static int thread_signaled( struct object *obj, struct thread *thread );
|
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 void destroy_thread( struct object *obj );
|
||||||
static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system_only );
|
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 */
|
thread_signaled, /* signaled */
|
||||||
no_satisfied, /* satisfied */
|
no_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
destroy_thread /* destroy */
|
destroy_thread /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,10 +178,10 @@ struct thread *create_thread( int fd, struct process *process )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle a client event */
|
/* 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;
|
struct thread *thread = get_fd_user( fd );
|
||||||
assert( obj->ops == &thread_ops );
|
assert( thread->obj.ops == &thread_ops );
|
||||||
|
|
||||||
if (event & (POLLERR | POLLHUP)) kill_thread( thread, 0 );
|
if (event & (POLLERR | POLLHUP)) kill_thread( thread, 0 );
|
||||||
else if (event & POLLIN) read_request( thread );
|
else if (event & POLLIN) read_request( thread );
|
||||||
|
|
|
@ -58,7 +58,6 @@ static const struct object_ops timer_ops =
|
||||||
timer_signaled, /* signaled */
|
timer_signaled, /* signaled */
|
||||||
timer_satisfied, /* satisfied */
|
timer_satisfied, /* satisfied */
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
no_get_file_info, /* get_file_info */
|
|
||||||
timer_destroy /* destroy */
|
timer_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1289,6 +1289,16 @@ static void dump_create_device_reply( const struct create_device_reply *req )
|
||||||
fprintf( stderr, " handle=%p", req->handle );
|
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 )
|
static void dump_create_snapshot_request( const struct create_snapshot_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " inherit=%d,", req->inherit );
|
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_open_mapping_request,
|
||||||
(dump_func)dump_get_mapping_info_request,
|
(dump_func)dump_get_mapping_info_request,
|
||||||
(dump_func)dump_create_device_request,
|
(dump_func)dump_create_device_request,
|
||||||
|
(dump_func)dump_get_device_id_request,
|
||||||
(dump_func)dump_create_snapshot_request,
|
(dump_func)dump_create_snapshot_request,
|
||||||
(dump_func)dump_next_process_request,
|
(dump_func)dump_next_process_request,
|
||||||
(dump_func)dump_next_thread_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_open_mapping_reply,
|
||||||
(dump_func)dump_get_mapping_info_reply,
|
(dump_func)dump_get_mapping_info_reply,
|
||||||
(dump_func)dump_create_device_reply,
|
(dump_func)dump_create_device_reply,
|
||||||
|
(dump_func)dump_get_device_id_reply,
|
||||||
(dump_func)dump_create_snapshot_reply,
|
(dump_func)dump_create_snapshot_reply,
|
||||||
(dump_func)dump_next_process_reply,
|
(dump_func)dump_next_process_reply,
|
||||||
(dump_func)dump_next_thread_reply,
|
(dump_func)dump_next_thread_reply,
|
||||||
|
@ -2820,6 +2832,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||||
"open_mapping",
|
"open_mapping",
|
||||||
"get_mapping_info",
|
"get_mapping_info",
|
||||||
"create_device",
|
"create_device",
|
||||||
|
"get_device_id",
|
||||||
"create_snapshot",
|
"create_snapshot",
|
||||||
"next_process",
|
"next_process",
|
||||||
"next_thread",
|
"next_thread",
|
||||||
|
|
|
@ -359,11 +359,10 @@ HANDLE DEVICE_Open( LPCWSTR filenameW, DWORD access, LPSECURITY_ATTRIBUTES sa )
|
||||||
static DWORD DEVICE_GetClientID( HANDLE handle )
|
static DWORD DEVICE_GetClientID( HANDLE handle )
|
||||||
{
|
{
|
||||||
DWORD ret = 0;
|
DWORD ret = 0;
|
||||||
SERVER_START_REQ( get_file_info )
|
SERVER_START_REQ( get_device_id )
|
||||||
{
|
{
|
||||||
req->handle = handle;
|
req->handle = handle;
|
||||||
if (!wine_server_call( req ) && (reply->type == FILE_TYPE_UNKNOWN))
|
if (!wine_server_call( req )) ret = reply->id;
|
||||||
ret = reply->attr;
|
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue