diff --git a/files/dos_fs.c b/files/dos_fs.c index d0d9e8f0d40..5b83fb0cfc3 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -747,18 +747,8 @@ static HANDLE DOSFS_CreateCommPort(LPCWSTR name, DWORD access, DWORD attributes, TRACE("opening %s as %s\n", devname, debugstr_w(name)); - SERVER_START_REQ( create_serial ) - { - req->access = access; - req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - req->attributes = attributes; - req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE; - wine_server_add_data( req, devname, strlen(devname) ); - SetLastError(0); - wine_server_call_err( req ); - ret = reply->handle; - } - SERVER_END_REQ; + ret = FILE_CreateFile( devname, access, FILE_SHARE_READ|FILE_SHARE_WRITE, + sa, OPEN_EXISTING, attributes, NULL, FALSE, DRIVE_FIXED ); if(!ret) ERR("Couldn't open device '%s' ! (check permissions)\n",devname); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 9ee99545f55..a4ace65e34e 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2299,23 +2299,6 @@ struct kill_win_timer_reply -struct create_serial_request -{ - struct request_header __header; - unsigned int access; - int inherit; - unsigned int attributes; - unsigned int sharing; - /* VARARG(name,string); */ -}; -struct create_serial_reply -{ - struct reply_header __header; - obj_handle_t handle; -}; - - - struct get_serial_info_request { struct request_header __header; @@ -3302,7 +3285,6 @@ enum request REQ_get_message_reply, REQ_set_win_timer, REQ_kill_win_timer, - REQ_create_serial, REQ_get_serial_info, REQ_set_serial_info, REQ_register_async, @@ -3490,7 +3472,6 @@ union generic_request struct get_message_reply_request get_message_reply_request; struct set_win_timer_request set_win_timer_request; struct kill_win_timer_request kill_win_timer_request; - struct create_serial_request create_serial_request; struct get_serial_info_request get_serial_info_request; struct set_serial_info_request set_serial_info_request; struct register_async_request register_async_request; @@ -3676,7 +3657,6 @@ union generic_reply struct get_message_reply_reply get_message_reply_reply; struct set_win_timer_reply set_win_timer_reply; struct kill_win_timer_reply kill_win_timer_reply; - struct create_serial_reply create_serial_reply; struct get_serial_info_reply get_serial_info_reply; struct set_serial_info_reply set_serial_info_reply; struct register_async_reply register_async_reply; @@ -3730,6 +3710,6 @@ union generic_reply struct set_global_windows_reply set_global_windows_reply; }; -#define SERVER_PROTOCOL_VERSION 134 +#define SERVER_PROTOCOL_VERSION 135 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/file.c b/server/file.c index a22d269f217..62bda2404fb 100644 --- a/server/file.c +++ b/server/file.c @@ -162,9 +162,9 @@ static struct file *create_file_for_fd( int fd, unsigned int access, unsigned in } -static struct file *create_file( const char *nameptr, size_t len, unsigned int access, - unsigned int sharing, int create, unsigned int options, - unsigned int attrs, int removable ) +static struct object *create_file( const char *nameptr, size_t len, unsigned int access, + unsigned int sharing, int create, unsigned int options, + unsigned int attrs, int removable ) { struct file *file; int hash, flags; @@ -231,7 +231,15 @@ static struct file *create_file( const char *nameptr, size_t len, unsigned int a release_object( file ); return NULL; } - return file; + /* check for serial port */ + if (S_ISCHR(mode) && is_serial_fd( file->fd )) + { + struct object *obj = create_serial( file->fd, file->options ); + release_object( file ); + return obj; + } + + return &file->obj; error: free( name ); @@ -599,7 +607,7 @@ static int set_file_time( obj_handle_t handle, time_t access_time, time_t write_ /* create a file */ DECL_HANDLER(create_file) { - struct file *file; + struct object *file; reply->handle = 0; if ((file = create_file( get_req_data(), get_req_data_size(), req->access, diff --git a/server/file.h b/server/file.h index 890cdb3d511..85b47ae9177 100644 --- a/server/file.h +++ b/server/file.h @@ -101,4 +101,9 @@ extern void file_set_error(void); extern void do_change_notify( int unix_fd ); extern void sigio_callback(void); +/* serial port functions */ + +extern int is_serial_fd( struct fd *fd ); +extern struct object *create_serial( struct fd *fd, unsigned int options ); + #endif /* __WINE_SERVER_FILE_H */ diff --git a/server/protocol.def b/server/protocol.def index 22535548725..0ee3fdfc981 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1623,18 +1623,6 @@ enum message_type @END -/* Open a serial port */ -@REQ(create_serial) - unsigned int access; /* wanted access rights */ - int inherit; /* inherit flag */ - unsigned int attributes; /* eg. FILE_FLAG_OVERLAPPED */ - unsigned int sharing; /* sharing flags */ - VARARG(name,string); /* file name */ -@REPLY - obj_handle_t handle; /* handle to the port */ -@END - - /* Retrieve info about a serial port */ @REQ(get_serial_info) obj_handle_t handle; /* handle to comm port */ diff --git a/server/request.h b/server/request.h index 624ac519605..46a3cee93d8 100644 --- a/server/request.h +++ b/server/request.h @@ -232,7 +232,6 @@ DECL_HANDLER(reply_message); DECL_HANDLER(get_message_reply); DECL_HANDLER(set_win_timer); DECL_HANDLER(kill_win_timer); -DECL_HANDLER(create_serial); DECL_HANDLER(get_serial_info); DECL_HANDLER(set_serial_info); DECL_HANDLER(register_async); @@ -419,7 +418,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_get_message_reply, (req_handler)req_set_win_timer, (req_handler)req_kill_win_timer, - (req_handler)req_create_serial, (req_handler)req_get_serial_info, (req_handler)req_set_serial_info, (req_handler)req_register_async, diff --git a/server/serial.c b/server/serial.c index 65dd087caff..ae82199796e 100644 --- a/server/serial.c +++ b/server/serial.c @@ -46,6 +46,8 @@ #include "winerror.h" #include "windef.h" #include "winbase.h" +#include "winreg.h" +#include "winternl.h" #include "file.h" #include "handle.h" @@ -67,8 +69,7 @@ struct serial { struct object obj; struct fd *fd; - unsigned int access; - unsigned int attrib; + unsigned int options; /* timeout values */ unsigned int readinterval; @@ -110,55 +111,32 @@ static const struct fd_ops serial_fd_ops = serial_queue_async /* queue_async */ }; -static struct serial *create_serial( const char *nameptr, size_t len, unsigned int access, int attributes ) +/* check if the given fd is a serial port */ +int is_serial_fd( struct fd *fd ) +{ + struct termios tios; + + return !tcgetattr( get_unix_fd(fd), &tios ); +} + +/* create a serial object for a given fd */ +struct object *create_serial( struct fd *fd, unsigned int options ) { struct serial *serial; - struct termios tios; - int fd, flags = 0; - char *name; + int unix_fd; - if (!(name = mem_alloc( len + 1 ))) return NULL; - memcpy( name, nameptr, len ); - name[len] = 0; - - switch(access & (GENERIC_READ | GENERIC_WRITE)) - { - case GENERIC_READ: flags |= O_RDONLY; break; - case GENERIC_WRITE: flags |= O_WRONLY; break; - case GENERIC_READ|GENERIC_WRITE: flags |= O_RDWR; break; - default: break; - } - - flags |= O_NONBLOCK; - - fd = open( name, flags ); - free( name ); - if (fd < 0) - { - file_set_error(); - return NULL; - } - - /* check its really a serial port */ - if (tcgetattr(fd,&tios)) - { - file_set_error(); - close( fd ); - return NULL; - } + if ((unix_fd = dup( get_unix_fd(fd) )) == -1) return NULL; /* set the fd back to blocking if necessary */ - if( ! (attributes & FILE_FLAG_OVERLAPPED) ) - if(0>fcntl(fd, F_SETFL, 0)) - perror("fcntl"); + if (options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)) + fcntl( unix_fd, F_SETFL, 0 ); if (!(serial = alloc_object( &serial_ops ))) { - close( fd ); + close( unix_fd ); return NULL; } - serial->attrib = attributes; - serial->access = access; + serial->options = options; serial->readinterval = 0; serial->readmult = 0; serial->readconst = 0; @@ -169,12 +147,12 @@ static struct serial *create_serial( const char *nameptr, size_t len, unsigned i init_async_queue(&serial->read_q); init_async_queue(&serial->write_q); init_async_queue(&serial->wait_q); - if (!(serial->fd = create_anonymous_fd( &serial_fd_ops, fd, &serial->obj ))) + if (!(serial->fd = create_anonymous_fd( &serial_fd_ops, unix_fd, &serial->obj ))) { release_object( serial ); return NULL; } - return serial; + return &serial->obj; } static struct fd *serial_get_fd( struct object *obj ) @@ -243,7 +221,7 @@ static int serial_get_info( struct fd *fd, struct get_file_info_reply *reply, in } *flags = 0; - if(serial->attrib & FILE_FLAG_OVERLAPPED) + if (!(serial->options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))) *flags |= FD_FLAG_OVERLAPPED; else if(!((serial->readinterval == MAXDWORD) && (serial->readmult == 0) && (serial->readconst == 0)) ) @@ -341,19 +319,6 @@ static int serial_flush( struct fd *fd, struct event **event ) return ret; } -/* create a serial */ -DECL_HANDLER(create_serial) -{ - struct serial *serial; - - reply->handle = 0; - if ((serial = create_serial( get_req_data(), get_req_data_size(), req->access, req->attributes ))) - { - reply->handle = alloc_handle( current->process, serial, req->access, req->inherit ); - release_object( serial ); - } -} - DECL_HANDLER(get_serial_info) { struct serial *serial; diff --git a/server/trace.c b/server/trace.c index 30f0f31b5fa..0294019540e 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1923,21 +1923,6 @@ static void dump_kill_win_timer_request( const struct kill_win_timer_request *re fprintf( stderr, " id=%08x", req->id ); } -static void dump_create_serial_request( const struct create_serial_request *req ) -{ - fprintf( stderr, " access=%08x,", req->access ); - fprintf( stderr, " inherit=%d,", req->inherit ); - fprintf( stderr, " attributes=%08x,", req->attributes ); - fprintf( stderr, " sharing=%08x,", req->sharing ); - fprintf( stderr, " name=" ); - dump_varargs_string( cur_size ); -} - -static void dump_create_serial_reply( const struct create_serial_reply *req ) -{ - fprintf( stderr, " handle=%p", req->handle ); -} - static void dump_get_serial_info_request( const struct get_serial_info_request *req ) { fprintf( stderr, " handle=%p", req->handle ); @@ -2711,7 +2696,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_message_reply_request, (dump_func)dump_set_win_timer_request, (dump_func)dump_kill_win_timer_request, - (dump_func)dump_create_serial_request, (dump_func)dump_get_serial_info_request, (dump_func)dump_set_serial_info_request, (dump_func)dump_register_async_request, @@ -2895,7 +2879,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_message_reply_reply, (dump_func)0, (dump_func)0, - (dump_func)dump_create_serial_reply, (dump_func)dump_get_serial_info_reply, (dump_func)0, (dump_func)0, @@ -3079,7 +3062,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "get_message_reply", "set_win_timer", "kill_win_timer", - "create_serial", "get_serial_info", "set_serial_info", "register_async",