From a84860785a1859d9f2ddff7e2cbb7d152eda5201 Mon Sep 17 00:00:00 2001 From: Michael McCormack Date: Sun, 14 Mar 1999 12:25:36 +0000 Subject: [PATCH] Basic support for WIN32 serial communications API. Modify DOSFS_OpenDevice to allow opening of COM ports. Change Win32 comm functions to accept file handle. Add declaration of COMSTAT32 structure. --- files/dos_fs.c | 17 +++ include/winbase.h | 9 +- include/wine/winuser16.h | 2 +- misc/comm.c | 241 ++++++++++++++++++++++++++++++++------- 4 files changed, 223 insertions(+), 46 deletions(-) diff --git a/files/dos_fs.c b/files/dos_fs.c index b88b2cbb279..9572a485483 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -673,6 +673,23 @@ 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 ); + TRACE(file,"Create_File return %08X\n",r); + return r; + } + } + FIXME(dosfs,"device open %s not supported (yet)\n",DOSFS_Devices[i].name); return HFILE_ERROR; } diff --git a/include/winbase.h b/include/winbase.h index a9fb92ef326..5bdb71f47d6 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1175,11 +1175,18 @@ DECL_WINELIB_TYPE_AW(OSVERSIONINFO) #define VER_PLATFORM_WIN32_WINDOWS 1 #define VER_PLATFORM_WIN32_NT 2 -typedef struct tagCOMSTAT +typedef struct tagCOMSTAT16 { BYTE status; UINT16 cbInQue WINE_PACKED; UINT16 cbOutQue WINE_PACKED; +} COMSTAT16,*LPCOMSTAT16; + +typedef struct tagCOMSTAT +{ + DWORD status; + DWORD cbInQue; + DWORD cbOutQue; } COMSTAT,*LPCOMSTAT; typedef struct tagDCB16 diff --git a/include/wine/winuser16.h b/include/wine/winuser16.h index f10e12e1ddf..c2008cb80ba 100644 --- a/include/wine/winuser16.h +++ b/include/wine/winuser16.h @@ -847,7 +847,7 @@ UINT16 WINAPI WNetAddConnection16(LPCSTR,LPCSTR,LPCSTR); INT16 WINAPI wvsprintf16(LPSTR,LPCSTR,LPCVOID); BOOL16 WINAPI DrawState16A(HDC16,HBRUSH16,DRAWSTATEPROC16,LPARAM,WPARAM16,INT16,INT16,INT16,INT16,UINT16); BOOL16 WINAPI IsDialogMessage16(HWND16,LPMSG16); -INT16 WINAPI GetCommError16(INT16,LPCOMSTAT); +INT16 WINAPI GetCommError16(INT16,LPCOMSTAT16); BOOL16 WINAPI BuildCommDCB16(LPCSTR,LPDCB16); INT16 WINAPI GetCommState16(INT16,LPDCB16); INT16 WINAPI SetCommState16(LPDCB16); diff --git a/misc/comm.c b/misc/comm.c index 72477bf2fdc..886d9e43a41 100644 --- a/misc/comm.c +++ b/misc/comm.c @@ -69,6 +69,11 @@ #include "options.h" #include "debug.h" +#include "server/request.h" +#include "server.h" +#include "process.h" +#include "winerror.h" + #ifndef TIOCINQ #define TIOCINQ FIONREAD #endif @@ -803,17 +808,49 @@ INT16 WINAPI FlushComm16(INT16 fd,INT16 fnQueue) /******************************************************************** * PurgeComm (KERNEL32.557) */ -BOOL WINAPI PurgeComm( HANDLE hFile, DWORD flags) +BOOL WINAPI PurgeComm( HANDLE handle, DWORD flags) { - FIXME(comm, "(%08x %08lx) unimplemented stub\n", - hFile, flags); - return 0; + int fd; + struct get_write_fd_request req; + + TRACE(comm,"handle %d, flags %lx\n", handle, flags); + + req.handle = handle; + CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &req, sizeof(req) ); + CLIENT_WaitReply( NULL, &fd, 0 ); + + if(fd<0) + return FALSE; + + /* + ** not exactly sure how these are different + ** Perhaps if we had our own internal queues, one flushes them + ** and the other flushes the kernel's buffers. + */ + if(flags&PURGE_TXABORT) + { + tcflush(fd,TCOFLUSH); + } + if(flags&PURGE_RXABORT) + { + tcflush(fd,TCIFLUSH); + } + if(flags&PURGE_TXCLEAR) + { + tcflush(fd,TCOFLUSH); + } + if(flags&PURGE_RXCLEAR) + { + tcflush(fd,TCIFLUSH); + } + + return 1; } /******************************************************************** * GetCommError (USER.203) */ -INT16 WINAPI GetCommError16(INT16 fd,LPCOMSTAT lpStat) +INT16 WINAPI GetCommError16(INT16 fd,LPCOMSTAT16 lpStat) { int temperror; unsigned long cnt; @@ -861,18 +898,77 @@ INT16 WINAPI GetCommError16(INT16 fd,LPCOMSTAT lpStat) return(temperror); } +/***************************************************************************** + * COMM_Handle2fd + * returns a file descriptor for reading from or writing to + * mode is GENERIC_READ or GENERIC_WRITE. Make sure to close + * the handle afterwards! + */ +int COMM_Handle2fd(HANDLE handle, int mode) { + struct get_read_fd_request r_req; + struct get_write_fd_request w_req; + int fd; + + w_req.handle = r_req.handle = handle; + + switch(mode) { + case GENERIC_WRITE: + CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &w_req, sizeof(w_req) ); + break; + case GENERIC_READ: + CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &r_req, sizeof(r_req) ); + break; + default: + ERR(comm,"COMM_Handle2fd: Don't know what type of fd is required.\n"); + return -1; + } + CLIENT_WaitReply( NULL, &fd, 0 ); + + return fd; +} + /***************************************************************************** * ClearCommError (KERNEL32.21) */ -BOOL WINAPI ClearCommError(INT fd,LPDWORD errors,LPCOMSTAT lpStat) +BOOL WINAPI ClearCommError(INT handle,LPDWORD errors,LPCOMSTAT lpStat) { - int temperror; + int fd; - TRACE(comm, "fd %d (current error %d)\n", - fd, commerror); - temperror = commerror; - commerror = 0; - return TRUE; + fd=COMM_Handle2fd(handle,GENERIC_READ); + if(0>fd) + { + return FALSE; + } + + if (lpStat) + { + lpStat->status = 0; + + if(ioctl(fd, TIOCOUTQ, &lpStat->cbOutQue)) + WARN(comm, "ioctl returned error\n"); + + if(ioctl(fd, TIOCINQ, &lpStat->cbInQue)) + WARN(comm, "ioctl returned error\n"); + } + + close(fd); + + TRACE(comm,"handle %d cbInQue = %ld cbOutQue = %ld\n", + handle, + lpStat->cbInQue, + lpStat->cbOutQue); + + if(errors) + *errors = 0; + + /* + ** After an asynchronous write opperation, the + ** app will call ClearCommError to see if the + ** results are ready yet. It waits for ERROR_IO_PENDING + */ + commerror = ERROR_IO_PENDING; + + return TRUE; } /***************************************************************************** @@ -944,30 +1040,51 @@ UINT16 WINAPI GetCommEventMask16(INT16 fd,UINT16 fnEvtClear) /***************************************************************************** * SetupComm (KERNEL32.676) */ -BOOL WINAPI SetupComm( HANDLE hFile, DWORD insize, DWORD outsize) +BOOL WINAPI SetupComm( HANDLE handle, DWORD insize, DWORD outsize) { - FIXME(comm, "insize %ld outsize %ld unimplemented stub\n", insize, outsize); - return FALSE; + int fd; + + FIXME(comm, "insize %ld outsize %ld unimplemented stub\n", insize, outsize); + fd=COMM_Handle2fd(handle,GENERIC_WRITE); + if(0>fd) + { + return FALSE; + } + close(fd); + return TRUE; } /***************************************************************************** * GetCommMask (KERNEL32.156) */ -BOOL WINAPI GetCommMask(HANDLE fd,LPDWORD evtmask) +BOOL WINAPI GetCommMask(HANDLE handle,LPDWORD evtmask) { - TRACE(comm, "fd %d, mask %p\n", fd, evtmask); - *evtmask = eventmask; - return TRUE; + int fd; + + TRACE(comm, "handle %d, mask %p\n", handle, evtmask); + if(0>(fd=COMM_Handle2fd(handle,GENERIC_READ))) + { + return FALSE; + } + close(fd); + *evtmask = eventmask; + return TRUE; } /***************************************************************************** * SetCommMask (KERNEL32.451) */ -BOOL WINAPI SetCommMask(INT fd,DWORD evtmask) +BOOL WINAPI SetCommMask(INT handle,DWORD evtmask) { - TRACE(comm, "fd %d, mask %lx\n", fd, evtmask); - eventmask = evtmask; - return TRUE; + int fd; + + TRACE(comm, "handle %d, mask %lx\n", handle, evtmask); + if(0>(fd=COMM_Handle2fd(handle,GENERIC_WRITE))) { + return FALSE; + } + close(fd); + eventmask = evtmask; + return TRUE; } /***************************************************************************** @@ -1187,18 +1304,27 @@ INT16 WINAPI SetCommState16(LPDCB16 lpdcb) } /***************************************************************************** - * SetCommState32 (KERNEL32.452) + * SetCommState (KERNEL32.452) */ -BOOL WINAPI SetCommState(INT fd,LPDCB lpdcb) +BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb) { - struct termios port; - struct DosDeviceStruct *ptr; + struct termios port; + int fd; + struct get_write_fd_request req; - TRACE(comm,"fd %d, ptr %p\n",fd,lpdcb); - if (tcgetattr(fd,&port) == -1) { - commerror = WinError(); - return FALSE; - } + TRACE(comm,"handle %d, ptr %p\n", handle, lpdcb); + + req.handle = handle; + CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &req, sizeof(req) ); + CLIENT_WaitReply( NULL, &fd, 0 ); + + if(fd<0) + return FALSE; + + if (tcgetattr(fd,&port) == -1) { + commerror = WinError(); + return FALSE; + } port.c_cc[VMIN] = 0; port.c_cc[VTIME] = 1; @@ -1218,13 +1344,10 @@ BOOL WINAPI SetCommState(INT fd,LPDCB lpdcb) port.c_lflag &= ~(ICANON|ECHO|ISIG); port.c_lflag |= NOFLSH; - if ((ptr = GetDeviceStruct(fd)) == NULL) { - commerror = IE_BADID; - return FALSE; - } - if (ptr->baudrate > 0) - lpdcb->BaudRate = ptr->baudrate; - TRACE(comm,"baudrate %ld\n",lpdcb->BaudRate); + /* + ** MJM - removed default baudrate settings + ** TRACE(comm,"baudrate %ld\n",lpdcb->BaudRate); + */ #ifdef CBAUD port.c_cflag &= ~CBAUD; switch (lpdcb->BaudRate) { @@ -1529,13 +1652,22 @@ INT16 WINAPI GetCommState16(INT16 fd, LPDCB16 lpdcb) /***************************************************************************** * GetCommState (KERNEL32.159) */ -BOOL WINAPI GetCommState(INT fd, LPDCB lpdcb) +BOOL WINAPI GetCommState(INT handle, LPDCB lpdcb) { - struct termios port; + struct termios port; + int fd; + struct get_read_fd_request req; - TRACE(comm,"fd %d, ptr %p\n", fd, lpdcb); - if (GetDeviceStruct(fd) == NULL) return FALSE; - if (tcgetattr(fd, &port) == -1) { + TRACE(comm,"handle %d, ptr %p\n", handle, lpdcb); + req.handle = handle; + CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &req, sizeof(req) ); + CLIENT_WaitReply( NULL, &fd, 0 ); + + if(fd<0) + return FALSE; + + if (tcgetattr(fd, &port) == -1) { + TRACE(comm,"tcgetattr(%d, ...) returned -1",fd); commerror = WinError(); return FALSE; } @@ -1642,6 +1774,9 @@ BOOL WINAPI GetCommState(INT fd, LPDCB lpdcb) lpdcb->XoffLim = 10; commerror = 0; + + TRACE(comm,"OK\n"); + return TRUE; } @@ -1844,3 +1979,21 @@ BOOL WINAPI WaitCommEvent(HANDLE hFile,LPDWORD eventmask ,LPOVERLAPPED overlappe return TRUE; } +/*********************************************************************** + * GetCommProperties (KERNEL32.???) + */ +BOOL WINAPI GetCommProperties(HANDLE hFile, LPDCB *dcb) +{ + FIXME(comm, "(%d %p )\n",hFile,dcb); + return TRUE; +} + +/*********************************************************************** + * SetCommProperties (KERNEL32.???) + */ +BOOL WINAPI SetCommProperties(HANDLE hFile, LPDCB dcb) +{ + FIXME(comm, "(%d %p )\n",hFile,dcb); + return TRUE; +} +