Added serial port object to the server.
This commit is contained in:
parent
27a76c8473
commit
44b5bf5998
|
@ -28,6 +28,7 @@
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
#include "comm.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "msdos.h"
|
#include "msdos.h"
|
||||||
#include "syslevel.h"
|
#include "syslevel.h"
|
||||||
|
@ -648,6 +649,7 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
HFILE handle;
|
||||||
|
|
||||||
if (!name) return (HFILE)NULL; /* if FILE_DupUnixHandle was used */
|
if (!name) return (HFILE)NULL; /* if FILE_DupUnixHandle was used */
|
||||||
if (name[0] && (name[1] == ':')) name += 2;
|
if (name[0] && (name[1] == ':')) name += 2;
|
||||||
|
@ -667,7 +669,6 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access )
|
||||||
OPEN_EXISTING, 0, -1, TRUE );
|
OPEN_EXISTING, 0, -1, TRUE );
|
||||||
if (!strcmp(DOSFS_Devices[i].name,"CON")) {
|
if (!strcmp(DOSFS_Devices[i].name,"CON")) {
|
||||||
HFILE to_dup;
|
HFILE to_dup;
|
||||||
HFILE handle;
|
|
||||||
switch (access & (GENERIC_READ|GENERIC_WRITE)) {
|
switch (access & (GENERIC_READ|GENERIC_WRITE)) {
|
||||||
case GENERIC_READ:
|
case GENERIC_READ:
|
||||||
to_dup = GetStdHandle( STD_INPUT_HANDLE );
|
to_dup = GetStdHandle( STD_INPUT_HANDLE );
|
||||||
|
@ -690,22 +691,9 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access )
|
||||||
{
|
{
|
||||||
return FILE_CreateDevice( i, access, NULL );
|
return FILE_CreateDevice( i, access, NULL );
|
||||||
}
|
}
|
||||||
{
|
|
||||||
HFILE r;
|
|
||||||
char devname[40];
|
|
||||||
PROFILE_GetWineIniString("serialports",name,"",devname,sizeof devname);
|
|
||||||
|
|
||||||
if(devname[0])
|
if( (handle=COMM_CreatePort(name,access)) )
|
||||||
{
|
return handle;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FIXME("device open %s not supported (yet)\n",DOSFS_Devices[i].name);
|
FIXME("device open %s not supported (yet)\n",DOSFS_Devices[i].name);
|
||||||
return HFILE_ERROR;
|
return HFILE_ERROR;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __WINE_COMM_H
|
#define __WINE_COMM_H
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
|
||||||
#define MAX_PORTS 9
|
#define MAX_PORTS 9
|
||||||
|
|
||||||
|
@ -24,5 +25,6 @@ struct DosDeviceStruct {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void COMM_Init(void);
|
extern void COMM_Init(void);
|
||||||
|
extern HANDLE COMM_CreatePort(LPCSTR name, DWORD access);
|
||||||
|
|
||||||
#endif /* __WINE_COMM_H */
|
#endif /* __WINE_COMM_H */
|
||||||
|
|
|
@ -1312,6 +1312,15 @@ struct wait_input_idle_request
|
||||||
OUT int event; /* handle to idle event */
|
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 */
|
/* Everything below this line is generated automatically by tools/make_requests */
|
||||||
/* ### make_requests begin ### */
|
/* ### make_requests begin ### */
|
||||||
|
@ -1425,6 +1434,7 @@ enum request
|
||||||
REQ_GET_MSG_QUEUE,
|
REQ_GET_MSG_QUEUE,
|
||||||
REQ_WAKE_QUEUE,
|
REQ_WAKE_QUEUE,
|
||||||
REQ_WAIT_INPUT_IDLE,
|
REQ_WAIT_INPUT_IDLE,
|
||||||
|
REQ_CREATE_SERIAL,
|
||||||
REQ_NB_REQUESTS
|
REQ_NB_REQUESTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1539,9 +1549,10 @@ union generic_request
|
||||||
struct get_msg_queue_request get_msg_queue;
|
struct get_msg_queue_request get_msg_queue;
|
||||||
struct wake_queue_request wake_queue;
|
struct wake_queue_request wake_queue;
|
||||||
struct wait_input_idle_request wait_input_idle;
|
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 ### */
|
/* ### make_requests end ### */
|
||||||
/* Everything above this line is generated automatically by tools/make_requests */
|
/* 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 );
|
HeapFree( GetProcessHeap(), 0, lpszNameA );
|
||||||
return ret;
|
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 \
|
request.c \
|
||||||
select.c \
|
select.c \
|
||||||
semaphore.c \
|
semaphore.c \
|
||||||
|
serial.c \
|
||||||
snapshot.c \
|
snapshot.c \
|
||||||
sock.c \
|
sock.c \
|
||||||
thread.c \
|
thread.c \
|
||||||
|
|
|
@ -201,6 +201,7 @@ DECL_HANDLER(init_atom_table);
|
||||||
DECL_HANDLER(get_msg_queue);
|
DECL_HANDLER(get_msg_queue);
|
||||||
DECL_HANDLER(wake_queue);
|
DECL_HANDLER(wake_queue);
|
||||||
DECL_HANDLER(wait_input_idle);
|
DECL_HANDLER(wait_input_idle);
|
||||||
|
DECL_HANDLER(create_serial);
|
||||||
|
|
||||||
#ifdef WANT_REQUEST_HANDLERS
|
#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_get_msg_queue,
|
||||||
(req_handler)req_wake_queue,
|
(req_handler)req_wake_queue,
|
||||||
(req_handler)req_wait_input_idle,
|
(req_handler)req_wait_input_idle,
|
||||||
|
(req_handler)req_create_serial,
|
||||||
};
|
};
|
||||||
#endif /* WANT_REQUEST_HANDLERS */
|
#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 );
|
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] = {
|
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||||
(dump_func)dump_new_process_request,
|
(dump_func)dump_new_process_request,
|
||||||
(dump_func)dump_wait_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_get_msg_queue_request,
|
||||||
(dump_func)dump_wake_queue_request,
|
(dump_func)dump_wake_queue_request,
|
||||||
(dump_func)dump_wait_input_idle_request,
|
(dump_func)dump_wait_input_idle_request,
|
||||||
|
(dump_func)dump_create_serial_request,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
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)dump_get_msg_queue_reply,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)dump_wait_input_idle_reply,
|
(dump_func)dump_wait_input_idle_reply,
|
||||||
|
(dump_func)dump_create_serial_reply,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const req_names[REQ_NB_REQUESTS] = {
|
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",
|
"get_msg_queue",
|
||||||
"wake_queue",
|
"wake_queue",
|
||||||
"wait_input_idle",
|
"wait_input_idle",
|
||||||
|
"create_serial",
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ### make_requests end ### */
|
/* ### make_requests end ### */
|
||||||
|
|
Loading…
Reference in New Issue