Make the standard create_file request handle serial ports too, and
remove the create_serial request.
diff --git a/server/file.c b/server/file.c
index a22d269..62bda24 100644
--- a/server/file.c
+++ b/server/file.c
@@ -162,9 +162,9 @@
}
-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 @@
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 @@
/* 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 890cdb3..85b47ae 100644
--- a/server/file.h
+++ b/server/file.h
@@ -101,4 +101,9 @@
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 2253554..0ee3fdf 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1623,18 +1623,6 @@
@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 624ac51..46a3cee 100644
--- a/server/request.h
+++ b/server/request.h
@@ -232,7 +232,6 @@
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 @@
(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 65dd087..ae82199 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 object obj;
struct fd *fd;
- unsigned int access;
- unsigned int attrib;
+ unsigned int options;
/* timeout values */
unsigned int readinterval;
@@ -110,55 +111,32 @@
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 @@
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 @@
}
*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 @@
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 30f0f31..0294019 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1923,21 +1923,6 @@
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 @@
(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 @@
(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 @@
"get_message_reply",
"set_win_timer",
"kill_win_timer",
- "create_serial",
"get_serial_info",
"set_serial_info",
"register_async",