diff --git a/files/dos_fs.c b/files/dos_fs.c index 07163601ea8..39b270fe7dd 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -705,13 +705,13 @@ const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile ) /************************************************************************** * DOSFS_CreateCommPort */ -static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access) +static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access, DWORD attributes) { HANDLE ret; char devname[40]; size_t len; - TRACE("%s %lx\n", name, access); + TRACE_(file)("%s %lx %lx\n", name, access, attributes); PROFILE_GetWineIniString("serialports",name,"",devname,sizeof devname); if(!devname[0]) @@ -724,6 +724,7 @@ static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access) { req->access = access; req->inherit = 0; /*FIXME*/ + req->attributes = attributes; req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE; memcpy( server_data_ptr(req), devname, len ); SetLastError(0); @@ -745,7 +746,7 @@ static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access) * Open a DOS device. This might not map 1:1 into the UNIX device concept. * Returns 0 on failure. */ -HANDLE DOSFS_OpenDevice( const char *name, DWORD access ) +HANDLE DOSFS_OpenDevice( const char *name, DWORD access, DWORD attributes ) { int i; const char *p; @@ -790,7 +791,7 @@ HANDLE DOSFS_OpenDevice( const char *name, DWORD access ) return FILE_CreateDevice( i, access, NULL ); } - if( (handle=DOSFS_CreateCommPort(DOSFS_Devices[i].name,access)) ) + if( (handle=DOSFS_CreateCommPort(DOSFS_Devices[i].name,access,attributes)) ) return handle; FIXME("device open %s not supported (yet)\n",DOSFS_Devices[i].name); return 0; diff --git a/files/file.c b/files/file.c index ff3c4b533a5..4ec9a405ca5 100644 --- a/files/file.c +++ b/files/file.c @@ -488,7 +488,7 @@ HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing, { TRACE("opening device '%s'\n", filename ); - if (!(ret = DOSFS_OpenDevice( filename, access ))) + if (!(ret = DOSFS_OpenDevice( filename, access, attributes ))) { /* Do not silence this please. It is a critical error. -MM */ ERR("Couldn't open device '%s'!\n",filename); diff --git a/include/file.h b/include/file.h index ba67781b96c..9f668d11d48 100644 --- a/include/file.h +++ b/include/file.h @@ -98,7 +98,7 @@ extern time_t DOSFS_FileTimeToUnixTime( const FILETIME *ft, DWORD *remainder ); extern BOOL DOSFS_ToDosFCBFormat( LPCSTR name, LPSTR buffer ); extern const DOS_DEVICE *DOSFS_GetDevice( const char *name ); extern const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile ); -extern HANDLE DOSFS_OpenDevice( const char *name, DWORD access ); +extern HANDLE DOSFS_OpenDevice( const char *name, DWORD access, DWORD attributes ); extern BOOL DOSFS_FindUnixName( LPCSTR path, LPCSTR name, LPSTR long_buf, INT long_len, LPSTR short_buf, BOOL ignore_case ); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index bbac77afb2c..2df30022471 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -576,6 +576,7 @@ struct get_handle_fd_request #define FD_TYPE_DEFAULT 1 #define FD_TYPE_CONSOLE 2 #define FD_TYPE_OVERLAPPED 3 +#define FD_TYPE_TIMEOUT 4 @@ -1454,6 +1455,7 @@ struct create_serial_request struct request_header __header; unsigned int access; int inherit; + unsigned int attributes; unsigned int sharing; /* VARARG(name,string); */ handle_t handle; @@ -1917,6 +1919,6 @@ union generic_request struct get_window_tree_request get_window_tree; }; -#define SERVER_PROTOCOL_VERSION 54 +#define SERVER_PROTOCOL_VERSION 55 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index e519beb89bb..a7b7a2d3059 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -532,6 +532,7 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT }; #define FD_TYPE_DEFAULT 1 #define FD_TYPE_CONSOLE 2 #define FD_TYPE_OVERLAPPED 3 +#define FD_TYPE_TIMEOUT 4 /* Set a file current position */ @@ -1299,6 +1300,7 @@ enum message_type @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 diff --git a/server/serial.c b/server/serial.c index d6a1ea4f100..c16ccd78e9a 100644 --- a/server/serial.c +++ b/server/serial.c @@ -44,6 +44,7 @@ struct serial { struct object obj; unsigned int access; + unsigned int attrib; /* timeout values */ unsigned int readinterval; @@ -78,7 +79,7 @@ static const struct object_ops serial_ops = /* SERIAL PORT functions */ -static struct serial *create_serial( const char *nameptr, size_t len, unsigned int access ) +static struct serial *create_serial( const char *nameptr, size_t len, unsigned int access, int attributes ) { struct serial *serial; struct termios tios; @@ -115,8 +116,14 @@ static struct serial *create_serial( const char *nameptr, size_t len, unsigned i 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 ((serial = alloc_object( &serial_ops, fd ))) { + serial->attrib = attributes; serial->access = access; serial->readinterval = 0; serial->readmult = 0; @@ -160,6 +167,9 @@ static int serial_get_fd( struct object *obj ) static int serial_get_info( struct object *obj, struct get_file_info_request *req ) { + struct serial *serial = (struct serial *) obj; + assert( obj->ops == &serial_ops ); + if (req) { req->type = FILE_TYPE_CHAR; @@ -173,7 +183,11 @@ static int serial_get_info( struct object *obj, struct get_file_info_request *re req->index_low = 0; req->serial = 0; } - return FD_TYPE_DEFAULT; + + if(serial->attrib & FILE_FLAG_OVERLAPPED) + return FD_TYPE_OVERLAPPED; + + return FD_TYPE_TIMEOUT; } /* these function calculates the timeout for an async operation @@ -202,7 +216,7 @@ DECL_HANDLER(create_serial) struct serial *serial; req->handle = 0; - if ((serial = create_serial( get_req_data(req), get_req_data_size(req), req->access ))) + if ((serial = create_serial( get_req_data(req), get_req_data_size(req), req->access, req->attributes ))) { req->handle = alloc_handle( current->process, serial, req->access, req->inherit ); release_object( serial ); diff --git a/server/trace.c b/server/trace.c index eeb323c4267..9ce6400b367 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1556,6 +1556,7 @@ 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=" ); cur_pos += dump_varargs_string( req );