From db718970d3a6d40c520fad0c5bce8021de95e219 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 8 Jul 2001 20:28:55 +0000 Subject: [PATCH] Use HANDLEs instead of unix fds. --- dlls/kernel/comm.c | 266 ++++++++++++++++++++++++++++----------------- 1 file changed, 169 insertions(+), 97 deletions(-) diff --git a/dlls/kernel/comm.c b/dlls/kernel/comm.c index 7cfbb7921af..a32d7ee6454 100644 --- a/dlls/kernel/comm.c +++ b/dlls/kernel/comm.c @@ -94,7 +94,7 @@ DEFAULT_DEBUG_CHANNEL(comm); struct DosDeviceStruct { char *devicename; /* /dev/ttyS0 */ - int fd; + HANDLE handle; int suspended; int unget,xmit; int baudrate; @@ -168,7 +168,7 @@ void COMM_Init(void) if ((COM[x].devicename = malloc(strlen(temp)+1)) == NULL) WARN("Can't malloc for device info!\n"); else { - COM[x].fd = 0; + COM[x].handle = 0; strcpy(COM[x].devicename, temp); } TRACE("%s = %s\n", option, COM[x].devicename); @@ -190,7 +190,7 @@ void COMM_Init(void) if ((LPT[x].devicename = malloc(strlen(temp)+1)) == NULL) WARN("Can't malloc for device info!\n"); else { - LPT[x].fd = 0; + LPT[x].handle = 0; strcpy(LPT[x].devicename, temp); } TRACE("%s = %s\n", option, LPT[x].devicename); @@ -200,28 +200,28 @@ void COMM_Init(void) } -static struct DosDeviceStruct *GetDeviceStruct(int fd) +static struct DosDeviceStruct *GetDeviceStruct(int index) { - if ((fd&0x7F)<=MAX_PORTS) { - if (!(fd&FLAG_LPT)) { - if (COM[fd].fd) - return &COM[fd]; + if ((index&0x7F)<=MAX_PORTS) { + if (!(index&FLAG_LPT)) { + if (COM[index].handle) + return &COM[index]; } else { - fd &= 0x7f; - if (LPT[fd].fd) - return &LPT[fd]; + index &= 0x7f; + if (LPT[index].handle) + return &LPT[index]; } } return NULL; } -static int GetCommPort_fd(int fd) +static int GetCommPort_fd(HANDLE handle) { int x; for (x=0; xfd); + int cid = GetCommPort_fd(ptr->handle); TRACE("async notification\n"); /* read data from comm port */ @@ -282,7 +283,8 @@ static void CALLBACK comm_notification( ULONG_PTR private ) do { bleft = ((ptr->ibuf_tail > ptr->ibuf_head) ? (ptr->ibuf_tail-1) : ptr->ibuf_size) - ptr->ibuf_head; - len = read(ptr->fd, ptr->inbuf + ptr->ibuf_head, bleft?bleft:1); + if(!ReadFile(ptr->handle, ptr->inbuf + ptr->ibuf_head, bleft?bleft:1, &len, NULL)) + len = -1; if (len > 0) { if (!bleft) { ptr->commerror = CE_RXOVER; @@ -313,7 +315,8 @@ static void CALLBACK comm_notification( ULONG_PTR private ) /* write any TransmitCommChar character */ if (ptr->xmit>=0) { - len = write(ptr->fd, &(ptr->xmit), 1); + if(!WriteFile(ptr->handle, &(ptr->xmit), 1, &len, NULL)) + len = -1; if (len > 0) ptr->xmit = -1; } /* write from output queue */ @@ -321,7 +324,11 @@ static void CALLBACK comm_notification( ULONG_PTR private ) do { bleft = ((ptr->obuf_tail <= ptr->obuf_head) ? ptr->obuf_head : ptr->obuf_size) - ptr->obuf_tail; - len = bleft ? write(ptr->fd, ptr->outbuf + ptr->obuf_tail, bleft) : 0; + if(bleft) { + if(!WriteFile(ptr->handle, ptr->outbuf + ptr->obuf_tail, bleft, &len, NULL)) + len = -1; + } else + len = bleft; if (len > 0) { ptr->obuf_tail += len; if (ptr->obuf_tail >= ptr->obuf_size) @@ -355,20 +362,26 @@ static void CALLBACK comm_notification( ULONG_PTR private ) static void comm_waitread(struct DosDeviceStruct *ptr) { - if (ptr->s_read != INVALID_HANDLE_VALUE) return; - ptr->s_read = SERVICE_AddObject( FILE_DupUnixHandle( ptr->fd, - GENERIC_READ | SYNCHRONIZE ), - comm_notification, - (ULONG_PTR)ptr ); + HANDLE dup=INVALID_HANDLE_VALUE; + + if (ptr->s_read != INVALID_HANDLE_VALUE) + return; + if(!DuplicateHandle(GetCurrentProcess(), ptr->handle, + GetCurrentProcess(), &dup, GENERIC_READ|SYNCHRONIZE, FALSE, 0 )) + return; + ptr->s_read = SERVICE_AddObject( dup, comm_notification, (ULONG_PTR)ptr ); } static void comm_waitwrite(struct DosDeviceStruct *ptr) { - if (ptr->s_write != INVALID_HANDLE_VALUE) return; - ptr->s_write = SERVICE_AddObject( FILE_DupUnixHandle( ptr->fd, - GENERIC_WRITE | SYNCHRONIZE ), - comm_notification, - (ULONG_PTR)ptr ); + HANDLE dup=INVALID_HANDLE_VALUE; + + if (ptr->s_write != INVALID_HANDLE_VALUE) + return; + if(!DuplicateHandle(GetCurrentProcess(), ptr->handle, + GetCurrentProcess(), &dup, GENERIC_WRITE|SYNCHRONIZE, FALSE, 0 )) + return; + ptr->s_write = SERVICE_AddObject( dup, comm_notification, (ULONG_PTR)ptr ); } /************************************************************************** @@ -507,7 +520,8 @@ INT16 WINAPI BuildCommDCB16(LPCSTR device, LPDCB16 lpdcb) */ INT16 WINAPI OpenComm16(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue) { - int port,fd; + int port; + HANDLE handle; TRACE("%s, %d, %d\n", device, cbInQueue, cbOutQueue); @@ -526,22 +540,25 @@ INT16 WINAPI OpenComm16(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue) if (!ValidCOMPort(port)) return IE_BADID; - if (COM[port].fd) + if (COM[port].handle) return IE_OPEN; - fd = open(COM[port].devicename, O_RDWR | O_NONBLOCK); - if (fd == -1) { + handle = CreateFileA(device, GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0 ); + if (handle == INVALID_HANDLE_VALUE) { ERR("Couldn't open %s ! (%s)\n", COM[port].devicename, strerror(errno)); return IE_HARDWARE; } else { unknown[port] = SEGPTR_ALLOC(40); memset(unknown[port], 0, 40); - COM[port].fd = fd; + COM[port].handle = handle; COM[port].commerror = 0; COM[port].eventmask = 0; COM[port].evtchar = 0; /* FIXME: default? */ /* save terminal state */ + {int fd = FILE_GetUnixHandle(handle,GENERIC_READ); tcgetattr(fd,&m_stat[port]); + close(fd);} /* set default parameters */ if(COM[port].baudrate>-1){ DCB16 dcb; @@ -569,8 +586,10 @@ INT16 WINAPI OpenComm16(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue) } else COM[port].outbuf = NULL; if (!COM[port].outbuf) { /* not enough memory */ - tcsetattr(COM[port].fd,TCSANOW,&m_stat[port]); - close(COM[port].fd); + {int fd = FILE_GetUnixHandle(handle,GENERIC_READ); + tcsetattr(fd,TCSANOW,&m_stat[port]); + close(fd);} + CloseHandle(COM[port].handle); ERR("out of memory\n"); return IE_MEMORY; } @@ -587,14 +606,15 @@ INT16 WINAPI OpenComm16(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue) if (!ValidLPTPort(port)) return IE_BADID; - if (LPT[port].fd) + if (LPT[port].handle) return IE_OPEN; - fd = open(LPT[port].devicename, O_RDWR | O_NONBLOCK, 0); - if (fd == -1) { + handle = CreateFileA(device, GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0 ); + if (handle == INVALID_HANDLE_VALUE) { return IE_HARDWARE; } else { - LPT[port].fd = fd; + LPT[port].handle = handle; LPT[port].commerror = 0; LPT[port].eventmask = 0; return port|FLAG_LPT; @@ -626,16 +646,18 @@ INT16 WINAPI CloseComm16(INT16 cid) free(ptr->inbuf); /* reset modem lines */ - tcsetattr(ptr->fd,TCSANOW,&m_stat[cid]); + {int fd = FILE_GetUnixHandle(ptr->handle,GENERIC_READ); + tcsetattr(fd,TCSANOW,&m_stat[cid]); + close(fd);} } - if (close(ptr->fd) == -1) { + if (!CloseHandle(ptr->handle)) { ptr->commerror = WinError(); - /* FIXME: should we clear ptr->fd here? */ + /* FIXME: should we clear ptr->handle here? */ return -1; } else { ptr->commerror = 0; - ptr->fd = 0; + ptr->handle = 0; return 0; } } @@ -680,77 +702,93 @@ INT16 WINAPI ClearCommBreak16(INT16 cid) */ LONG WINAPI EscapeCommFunction16(UINT16 cid,UINT16 nFunction) { - int max; + int r,fd; struct DosDeviceStruct *ptr; struct termios port; TRACE("cid=%d, function=%d\n", cid, nFunction); - if ((nFunction != GETMAXCOM) && (nFunction != GETMAXLPT)) { - if ((ptr = GetDeviceStruct(cid)) == NULL) { - FIXME("no cid=%d found!\n", cid); - return -1; + + if (nFunction == GETMAXCOM) { + int max; + TRACE("GETMAXCOM\n"); + for (max = MAX_PORTS;!COM[max].devicename;max--) + ; + return max; + } + + if (nFunction == GETMAXLPT) { + int max; + TRACE("GETMAXLPT\n"); + for (max = MAX_PORTS;!LPT[max].devicename;max--) + ; + return FLAG_LPT + max; + } + + if (nFunction == GETBASEIRQ) { + TRACE("GETBASEIRQ\n"); + /* FIXME: use tables */ + /* just fake something for now */ + if (cid & FLAG_LPT) { + /* LPT1: irq 7, LPT2: irq 5 */ + return (cid & 0x7f) ? 5 : 7; + } else { + /* COM1: irq 4, COM2: irq 3, + COM3: irq 4, COM4: irq 3 */ + return 4 - (cid & 1); } - if (tcgetattr(ptr->fd,&port) == -1) { - TRACE("tcgetattr failed\n"); - ptr->commerror=WinError(); - return -1; - } - } else ptr = NULL; + } + + if ((ptr = GetDeviceStruct(cid)) == NULL) { + FIXME("no cid=%d found!\n", cid); + return -1; + } + + /* FIXME: replace with a call to EscapeCommFunction */ + + if ( (fd = FILE_GetUnixHandle(ptr->handle,GENERIC_READ)) == 0 ) + return -1; + + if (tcgetattr(fd,&port) == -1) { + TRACE("tcgetattr failed\n"); + close(fd); + ptr->commerror=WinError(); + return -1; + } switch (nFunction) { case RESETDEV: TRACE("RESETDEV\n"); break; - case GETMAXCOM: - TRACE("GETMAXCOM\n"); - for (max = MAX_PORTS;!COM[max].devicename;max--) - ; - return max; - break; - - case GETMAXLPT: - TRACE("GETMAXLPT\n"); - for (max = MAX_PORTS;!LPT[max].devicename;max--) - ; - return FLAG_LPT + max; - break; - - case GETBASEIRQ: - TRACE("GETBASEIRQ\n"); - /* FIXME: use tables */ - /* just fake something for now */ - if (cid & FLAG_LPT) { - /* LPT1: irq 7, LPT2: irq 5 */ - return (cid & 0x7f) ? 5 : 7; - } else { - /* COM1: irq 4, COM2: irq 3, - COM3: irq 4, COM4: irq 3 */ - return 4 - (cid & 1); - } - break; - case CLRDTR: TRACE("CLRDTR\n"); #ifdef TIOCM_DTR - return COMM_WhackModem(ptr->fd, ~TIOCM_DTR, 0); + r = COMM_WhackModem(fd, ~TIOCM_DTR, 0); + close(fd); + return r; #endif case CLRRTS: TRACE("CLRRTS\n"); #ifdef TIOCM_RTS - return COMM_WhackModem(ptr->fd, ~TIOCM_RTS, 0); + r = COMM_WhackModem(fd, ~TIOCM_RTS, 0); + close(fd); + return r; #endif case SETDTR: TRACE("SETDTR\n"); #ifdef TIOCM_DTR - return COMM_WhackModem(ptr->fd, 0, TIOCM_DTR); + r = COMM_WhackModem(fd, 0, TIOCM_DTR); + close(fd); + return r; #endif case SETRTS: TRACE("SETRTS\n"); #ifdef TIOCM_RTS - return COMM_WhackModem(ptr->fd, 0, TIOCM_RTS); + r = COMM_WhackModem(fd, 0, TIOCM_RTS); + close(fd); + return r; #endif case SETXOFF: @@ -769,7 +807,9 @@ LONG WINAPI EscapeCommFunction16(UINT16 cid,UINT16 nFunction) break; } - if (tcsetattr(ptr->fd, TCSADRAIN, &port) == -1) { + r = tcsetattr(fd, TCSADRAIN, &port); + close(fd); + if (r<0) { ptr->commerror = WinError(); return -1; } else { @@ -785,6 +825,7 @@ INT16 WINAPI FlushComm16(INT16 cid,INT16 fnQueue) { int queue; struct DosDeviceStruct *ptr; + int fd,r; TRACE("cid=%d, queue=%d\n", cid, fnQueue); if ((ptr = GetDeviceStruct(cid)) == NULL) { @@ -805,7 +846,13 @@ INT16 WINAPI FlushComm16(INT16 cid,INT16 fnQueue) cid, fnQueue); return -1; } - if (tcflush(ptr->fd, queue)) { + + /* FIXME: replace with a call to PurgeComm */ + if ( (fd = FILE_GetUnixHandle(ptr->handle,GENERIC_READ)) == 0 ) + return -1; + r = tcflush(fd, queue); + close(fd); + if (r) { ptr->commerror = WinError(); return -1; } else { @@ -823,6 +870,7 @@ INT16 WINAPI GetCommError16(INT16 cid,LPCOMSTAT16 lpStat) struct DosDeviceStruct *ptr; unsigned char *stol; unsigned int mstat; + int fd; if ((ptr = GetDeviceStruct(cid)) == NULL) { FIXME("no handle for cid = %0x!\n",cid); @@ -833,7 +881,10 @@ INT16 WINAPI GetCommError16(INT16 cid,LPCOMSTAT16 lpStat) return CE_MODE; } stol = (unsigned char *)unknown[cid] + COMM_MSR_OFFSET; - ioctl(ptr->fd,TIOCMGET,&mstat); + if ( (fd = FILE_GetUnixHandle(ptr->handle,GENERIC_READ)) == 0 ) + return -1; + ioctl(fd,TIOCMGET,&mstat); + close(fd); COMM_MSRUpdate( stol, mstat); if (lpStat) { @@ -865,6 +916,7 @@ SEGPTR WINAPI SetCommEventMask16(INT16 cid,UINT16 fuEvtMask) unsigned char *stol; int repid; unsigned int mstat; + int fd; TRACE("cid %d,mask %d\n",cid,fuEvtMask); if ((ptr = GetDeviceStruct(cid)) == NULL) { @@ -880,7 +932,10 @@ SEGPTR WINAPI SetCommEventMask16(INT16 cid,UINT16 fuEvtMask) } /* it's a COM port ? -> modify flags */ stol = (unsigned char *)unknown[cid] + COMM_MSR_OFFSET; - repid = ioctl(ptr->fd,TIOCMGET,&mstat); + if ( (fd = FILE_GetUnixHandle(ptr->handle,GENERIC_READ)) == 0 ) + return (SEGPTR)NULL; + repid = ioctl(fd,TIOCMGET,&mstat); + close(fd); TRACE(" ioctl %d, msr %x at %p %p\n",repid,mstat,stol,unknown[cid]); COMM_MSRUpdate( stol, mstat); @@ -921,13 +976,19 @@ INT16 WINAPI SetCommState16(LPDCB16 lpdcb) struct DosDeviceStruct *ptr; int bytesize, stopbits; int fail=0; + int fd,r=0; TRACE("cid %d, ptr %p\n", lpdcb->Id, lpdcb); if ((ptr = GetDeviceStruct(lpdcb->Id)) == NULL) { FIXME("no handle for cid = %0x!\n",lpdcb->Id); return -1; } - if (tcgetattr(ptr->fd, &port) == -1) { + + /* FIXME: replace with a call to SetCommState */ + if ( (fd = FILE_GetUnixHandle(ptr->handle,GENERIC_READ)) == 0 ) + return -1; + if (tcgetattr(fd, &port) == -1) { + close(fd); ptr->commerror = WinError(); return -1; } @@ -1157,10 +1218,14 @@ INT16 WINAPI SetCommState16(LPDCB16 lpdcb) ptr->evtchar = lpdcb->EvtChar; + if(!fail) + r = tcsetattr(fd, TCSADRAIN, &port); + close(fd); + if(fail) - return -1; + return -1; - if (tcsetattr(ptr->fd, TCSADRAIN, &port) == -1) { + if (r == -1) { ptr->commerror = WinError(); return -1; } else { @@ -1177,13 +1242,18 @@ INT16 WINAPI GetCommState16(INT16 cid, LPDCB16 lpdcb) int speed; struct DosDeviceStruct *ptr; struct termios port; + int fd,r; TRACE("cid %d, ptr %p\n", cid, lpdcb); if ((ptr = GetDeviceStruct(cid)) == NULL) { FIXME("no handle for cid = %0x!\n",cid); return -1; } - if (tcgetattr(ptr->fd, &port) == -1) { + if ( (fd = FILE_GetUnixHandle(ptr->handle,GENERIC_READ)) == 0 ) + return -1; + r = tcgetattr(fd, &port); + close(fd); + if (r == -1) { ptr->commerror = WinError(); return -1; } @@ -1354,7 +1424,8 @@ INT16 WINAPI TransmitCommChar16(INT16 cid,CHAR chTransmit) if (ptr->obuf_head == ptr->obuf_tail) { /* transmit queue empty, try to transmit directly */ - if (write(ptr->fd, &chTransmit, 1) == -1) { + DWORD len; + if(!WriteFile(ptr->handle, &chTransmit, 1, &len, NULL)) { /* didn't work, queue it */ ptr->xmit = chTransmit; comm_waitwrite(ptr); @@ -1476,7 +1547,8 @@ INT16 WINAPI WriteComm16(INT16 cid, LPSTR lpvBuf, INT16 cbWrite) while (length < cbWrite) { if ((ptr->obuf_head == ptr->obuf_tail) && (ptr->xmit < 0)) { /* no data queued, try to write directly */ - status = write(ptr->fd, lpvBuf, cbWrite - length); + if(!WriteFile(ptr->handle, lpvBuf, cbWrite - length, (LPDWORD)&status, NULL)) + status = -1; if (status > 0) { lpvBuf += status; length += status;