Added serial port object to the server.
This commit is contained in:
parent
27a76c8473
commit
44b5bf5998
|
@ -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 */
|
||||
|
|
28
misc/comm.c
28
misc/comm.c
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
@ -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 ### */
|
||||
|
|
Loading…
Reference in New Issue