Added serial port object to the server.

This commit is contained in:
Mike McCormack 2000-09-07 18:39:51 +00:00 committed by Alexandre Julliard
parent 27a76c8473
commit 44b5bf5998
8 changed files with 264 additions and 17 deletions

View File

@ -28,6 +28,7 @@
#include "winerror.h"
#include "drive.h"
#include "file.h"
#include "comm.h"
#include "heap.h"
#include "msdos.h"
#include "syslevel.h"
@ -648,6 +649,7 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access )
{
int i;
const char *p;
HFILE handle;
if (!name) return (HFILE)NULL; /* if FILE_DupUnixHandle was used */
if (name[0] && (name[1] == ':')) name += 2;
@ -667,7 +669,6 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access )
OPEN_EXISTING, 0, -1, TRUE );
if (!strcmp(DOSFS_Devices[i].name,"CON")) {
HFILE to_dup;
HFILE handle;
switch (access & (GENERIC_READ|GENERIC_WRITE)) {
case GENERIC_READ:
to_dup = GetStdHandle( STD_INPUT_HANDLE );
@ -690,22 +691,9 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access )
{
return FILE_CreateDevice( i, access, NULL );
}
{
HFILE r;
char devname[40];
PROFILE_GetWineIniString("serialports",name,"",devname,sizeof devname);
if(devname[0])
{
TRACE_(file)("DOSFS_OpenDevice %s is %s\n",
DOSFS_Devices[i].name,devname);
r = FILE_CreateFile( devname, access,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, -1, TRUE );
TRACE_(file)("Create_File return %08X\n",r);
return r;
}
}
if( (handle=COMM_CreatePort(name,access)) )
return handle;
FIXME("device open %s not supported (yet)\n",DOSFS_Devices[i].name);
return HFILE_ERROR;

View File

@ -2,6 +2,7 @@
#define __WINE_COMM_H
#include "windef.h"
#include "winbase.h"
#define MAX_PORTS 9
@ -24,5 +25,6 @@ struct DosDeviceStruct {
};
extern void COMM_Init(void);
extern HANDLE COMM_CreatePort(LPCSTR name, DWORD access);
#endif /* __WINE_COMM_H */

View File

@ -1312,6 +1312,15 @@ struct wait_input_idle_request
OUT int event; /* handle to idle event */
};
struct create_serial_request
{
REQUEST_HEADER; /* request header */
IN unsigned int access; /* wanted access rights */
IN int inherit; /* inherit flag */
IN unsigned int sharing; /* sharing flags */
OUT int handle; /* handle to the port */
IN char name[1]; /* file name */
};
/* Everything below this line is generated automatically by tools/make_requests */
/* ### make_requests begin ### */
@ -1425,6 +1434,7 @@ enum request
REQ_GET_MSG_QUEUE,
REQ_WAKE_QUEUE,
REQ_WAIT_INPUT_IDLE,
REQ_CREATE_SERIAL,
REQ_NB_REQUESTS
};
@ -1539,9 +1549,10 @@ union generic_request
struct get_msg_queue_request get_msg_queue;
struct wake_queue_request wake_queue;
struct wait_input_idle_request wait_input_idle;
struct create_serial_request create_serial;
};
#define SERVER_PROTOCOL_VERSION 20
#define SERVER_PROTOCOL_VERSION 21
/* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */

View File

@ -2841,3 +2841,31 @@ BOOL WINAPI GetDefaultCommConfigW( LPCWSTR lpszName,LPCOMMCONFIG lpCC,
HeapFree( GetProcessHeap(), 0, lpszNameA );
return ret;
}
/**************************************************************************
* COMM_CreatePort INTERNAL
*/
HANDLE COMM_CreatePort(LPCSTR name, DWORD access)
{
struct create_serial_request *req = get_req_buffer();
DWORD r;
char devname[40];
TRACE("%s %lx\n", name, access);
PROFILE_GetWineIniString("serialports",name,"",devname,sizeof devname);
if(!devname[0])
return 0;
TRACE("opening %s as %s\n", devname, name);
req->handle = 0;
req->access = access;
req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE;
lstrcpynA( req->name, devname, server_remaining(req->name) );
SetLastError(0);
r = server_call( REQ_CREATE_SERIAL );
TRACE("create_port_request return %08lX handle = %08X\n",r,req->handle);
return req->handle;
}

View File

@ -28,6 +28,7 @@ C_SRCS = \
request.c \
select.c \
semaphore.c \
serial.c \
snapshot.c \
sock.c \
thread.c \

View File

@ -201,6 +201,7 @@ DECL_HANDLER(init_atom_table);
DECL_HANDLER(get_msg_queue);
DECL_HANDLER(wake_queue);
DECL_HANDLER(wait_input_idle);
DECL_HANDLER(create_serial);
#ifdef WANT_REQUEST_HANDLERS
@ -314,6 +315,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_msg_queue,
(req_handler)req_wake_queue,
(req_handler)req_wait_input_idle,
(req_handler)req_create_serial,
};
#endif /* WANT_REQUEST_HANDLERS */

198
server/serial.c Normal file
View File

@ -0,0 +1,198 @@
/*
* Server-side serial port communications management
*
* Copyright (C) 1998 Alexandre Julliard
* Copyright (C) 2000 Mike McCormack
*
* TODO:
* Add async read, write and WaitCommEvent handling.
*
*/
#include "config.h"
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include <termios.h>
#include <sys/ioctl.h>
#include "winerror.h"
#include "winbase.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
static void serial_dump( struct object *obj, int verbose );
static void serial_destroy( struct object *obj );
static int serial_get_read_fd( struct object *obj );
static int serial_get_write_fd( struct object *obj );
static int serial_get_info( struct object *obj, struct get_file_info_request *req );
static int serial_get_poll_events( struct object *obj );
struct serial
{
struct object obj;
char name[16]; /* eg. /dev/ttyS1 */
int access;
/* timeout values */
unsigned int readinterval;
unsigned int readconst;
unsigned int readmult;
unsigned int writeconst;
unsigned int writemult;
unsigned int eventmask;
unsigned int commerror;
struct termios original;
/* FIXME: add dcb, comm status, handler module, sharing */
};
static const struct object_ops serial_ops =
{
sizeof(struct serial), /* size */
serial_dump, /* dump */
default_poll_add_queue, /* add_queue */
default_poll_remove_queue, /* remove_queue */
default_poll_signaled, /* signaled */
no_satisfied, /* satisfied */
serial_get_poll_events, /* get_poll_events */
default_poll_event, /* poll_event */
serial_get_read_fd, /* get_read_fd */
serial_get_write_fd, /* get_write_fd */
no_flush, /* flush */
serial_get_info, /* get_file_info */
serial_destroy /* destroy */
};
/* SERIAL PORT functions */
static void serial_dump( struct object *obj, int verbose )
{
struct serial *serial = (struct serial *)obj;
assert( obj->ops == &serial_ops );
fprintf( stderr, "Port fd=%d name='%s' mask=%x\n",
serial->obj.fd, serial->name,serial->eventmask);
}
/* same as file_destroy, but don't delete comm ports */
static void serial_destroy( struct object *obj )
{
assert( obj->ops == &serial_ops );
}
struct serial *get_serial_obj( struct process *process, int handle, unsigned int access )
{
return (struct serial *)get_handle_obj( process, handle, access, &serial_ops );
}
static int serial_get_poll_events( struct object *obj )
{
struct serial *serial = (struct serial *)obj;
int events = 0;
assert( obj->ops == &serial_ops );
if (serial->access & GENERIC_READ) events |= POLLIN;
if (serial->access & GENERIC_WRITE) events |= POLLOUT;
return events;
}
static int serial_get_read_fd( struct object *obj )
{
struct serial *serial = (struct serial *)obj;
assert( obj->ops == &serial_ops );
return dup( serial->obj.fd );
}
static int serial_get_write_fd( struct object *obj )
{
struct serial *serial = (struct serial *)obj;
assert( obj->ops == &serial_ops );
return dup( serial->obj.fd );
}
static int serial_get_info( struct object *obj, struct get_file_info_request *req )
{
assert( obj->ops == &serial_ops );
req->type = FILE_TYPE_CHAR;
req->attr = 0;
req->access_time = 0;
req->write_time = 0;
req->size_high = 0;
req->size_low = 0;
req->links = 0;
req->index_high = 0;
req->index_low = 0;
req->serial = 0;
return 1;
}
/* create a serial */
DECL_HANDLER(create_serial)
{
struct serial *serial;
int fd,flags;
struct termios tios;
req->handle = -1;
flags = 0;
switch(req->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;
}
fd = open( req->name, flags );
if(fd < 0)
{
file_set_error();
return;
}
/* check its really a serial port */
if(0>tcgetattr(fd,&tios))
{
file_set_error();
close(fd);
return;
}
serial = alloc_object( &serial_ops, fd );
if (serial)
{
strncpy(serial->name,req->name,sizeof serial->name);
serial->name[sizeof(serial->name)-1] = 0;
serial->access = req->access;
serial->readinterval = 0;
serial->readmult = 0;
serial->readconst = 0;
serial->writemult = 0;
serial->writeconst = 0;
serial->eventmask = 0;
serial->commerror = 0;
req->handle = alloc_handle( current->process, serial, req->access, req->inherit );
release_object( serial );
}
}

View File

@ -1417,6 +1417,20 @@ static void dump_wait_input_idle_reply( const struct wait_input_idle_request *re
fprintf( stderr, " event=%d", req->event );
}
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, " sharing=%08x,", req->sharing );
fprintf( stderr, " name=" );
dump_string( req, req->name );
}
static void dump_create_serial_reply( const struct create_serial_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
}
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request,
(dump_func)dump_wait_process_request,
@ -1525,6 +1539,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_msg_queue_request,
(dump_func)dump_wake_queue_request,
(dump_func)dump_wait_input_idle_request,
(dump_func)dump_create_serial_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@ -1635,6 +1650,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_msg_queue_reply,
(dump_func)0,
(dump_func)dump_wait_input_idle_reply,
(dump_func)dump_create_serial_reply,
};
static const char * const req_names[REQ_NB_REQUESTS] = {
@ -1745,6 +1761,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_msg_queue",
"wake_queue",
"wait_input_idle",
"create_serial",
};
/* ### make_requests end ### */