Skip to content
Snippets Groups Projects
Commit 44b5bf59 authored by Michael McCormack's avatar Michael McCormack Committed by Alexandre Julliard
Browse files

Added serial port object to the server.

parent 27a76c84
No related merge requests found
......@@ -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;
......
......@@ -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 */
......@@ -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 */
......
......@@ -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;
}
......@@ -28,6 +28,7 @@ C_SRCS = \
request.c \
select.c \
semaphore.c \
serial.c \
snapshot.c \
sock.c \
thread.c \
......
......@@ -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 */
......
/*
* 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 );
}
}
......@@ -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 ### */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment