2 * DEC 93 Erik Bos <erik@xs4all.nl>
4 * Copyright 1996 Marcus Meissner
6 * Mar 31, 1999. Ove Kåven <ovek@arcticnet.no>
7 * - Implemented buffers and EnableCommNotification.
9 * Apr 3, 1999. Lawson Whitney <lawson_whitney@juno.com>
10 * - Fixed the modem control part of EscapeCommFunction16.
12 * Mar 3, 1999. Ove Kåven <ovek@arcticnet.no>
13 * - Use port indices instead of unixfds for win16
14 * - Moved things around (separated win16 and win32 routines)
15 * - Added some hints on how to implement buffers and EnableCommNotification.
17 * May 26, 1997. Fixes and comments by Rick Richardson <rick@dgii.com> [RER]
18 * - ptr->fd wasn't getting cleared on close.
19 * - GetCommEventMask() and GetCommError() didn't do much of anything.
20 * IMHO, they are still wrong, but they at least implement the RXCHAR
21 * event and return I/O queue sizes, which makes the app I'm interested
22 * in (analog devices EZKIT DSP development system) work.
24 * August 12, 1997. Take a bash at SetCommEventMask - Lawson Whitney
25 * <lawson_whitney@juno.com>
26 * July 6, 1998. Fixes and comments by Valentijn Sessink
27 * <vsessink@ic.uva.nl> [V]
28 * Oktober 98, Rein Klazes [RHK]
29 * A program that wants to monitor the modem status line (RLSD/DCD) may
30 * poll the modem status register in the commMask structure. I update the bit
31 * in GetCommError, waiting for an implementation of communication events.
48 #ifdef HAVE_SYS_FILIO_H
49 # include <sys/filio.h>
51 #include <sys/ioctl.h>
55 #ifdef HAVE_SYS_MODEM_H
56 # include <sys/modem.h>
58 #ifdef HAVE_SYS_STRTIO_H
59 # include <sys/strtio.h>
63 #include "wine/port.h"
70 #include "debugtools.h"
72 DEFAULT_DEBUG_CHANNEL(comm);
74 #if !defined(TIOCINQ) && defined(FIONREAD)
75 #define TIOCINQ FIONREAD
78 /* window's semi documented modem status register */
79 #define COMM_MSR_OFFSET 35
84 #define MSR_MASK (MSR_CTS|MSR_DSR|MSR_RI|MSR_RLSD)
89 #define CMSPAR 0x40000000 /* stick parity */
94 struct DosDeviceStruct {
95 char *devicename; /* /dev/ttyS0 */
102 int commerror, eventmask;
105 unsigned ibuf_size,ibuf_head,ibuf_tail;
106 unsigned obuf_size,obuf_head,obuf_tail;
108 int wnd, n_read, n_write;
109 HANDLE s_read, s_write;
113 static struct DosDeviceStruct COM[MAX_PORTS];
114 static struct DosDeviceStruct LPT[MAX_PORTS];
115 /* pointers to unknown(==undocumented) comm structure */
116 static LPCVOID *unknown[MAX_PORTS];
117 /* save terminal states */
118 static struct termios m_stat[MAX_PORTS];
120 /* update window's semi documented modem status register */
121 /* see knowledge base Q101417 */
122 static void COMM_MSRUpdate( UCHAR * pMsr, unsigned int mstat)
126 if(mstat & TIOCM_CTS) tmpmsr |= MSR_CTS;
129 if(mstat & TIOCM_DSR) tmpmsr |= MSR_DSR;
132 if(mstat & TIOCM_RI) tmpmsr |= MSR_RI;
135 if(mstat & TIOCM_CAR) tmpmsr |= MSR_RLSD;
137 *pMsr = (*pMsr & ~MSR_MASK) | tmpmsr;
143 char option[10], temp[256], *btemp;
146 for (x=0; x!=MAX_PORTS; x++) {
147 strcpy(option,"COMx");
151 PROFILE_GetWineIniString( "serialports", option, "*",
152 temp, sizeof(temp) );
153 if (!strcmp(temp, "*") || *temp == '\0')
154 COM[x].devicename = NULL;
156 btemp = strchr(temp,',');
159 COM[x].baudrate = atoi(btemp);
161 COM[x].baudrate = -1;
164 if (!S_ISCHR(st.st_mode))
165 WARN("Can't use `%s' as %s !\n", temp, option);
167 if ((COM[x].devicename = malloc(strlen(temp)+1)) == NULL)
168 WARN("Can't malloc for device info!\n");
171 strcpy(COM[x].devicename, temp);
173 TRACE("%s = %s\n", option, COM[x].devicename);
176 strcpy(option, "LPTx");
180 PROFILE_GetWineIniString( "parallelports", option, "*",
181 temp, sizeof(temp) );
182 if (!strcmp(temp, "*") || *temp == '\0')
183 LPT[x].devicename = NULL;
186 if (!S_ISCHR(st.st_mode))
187 WARN("Can't use `%s' as %s !\n", temp, option);
189 if ((LPT[x].devicename = malloc(strlen(temp)+1)) == NULL)
190 WARN("Can't malloc for device info!\n");
193 strcpy(LPT[x].devicename, temp);
195 TRACE("%s = %s\n", option, LPT[x].devicename);
202 static struct DosDeviceStruct *GetDeviceStruct(int fd)
204 if ((fd&0x7F)<=MAX_PORTS) {
205 if (!(fd&FLAG_LPT)) {
218 static int GetCommPort_fd(int fd)
222 for (x=0; x<MAX_PORTS; x++) {
230 static int ValidCOMPort(int x)
232 return(x < MAX_PORTS ? (int) COM[x].devicename : 0);
235 static int ValidLPTPort(int x)
237 return(x < MAX_PORTS ? (int) LPT[x].devicename : 0);
240 static int WinError(void)
242 TRACE("errno = %d\n", errno);
249 static unsigned comm_inbuf(struct DosDeviceStruct *ptr)
251 return ((ptr->ibuf_tail > ptr->ibuf_head) ? ptr->ibuf_size : 0)
252 + ptr->ibuf_head - ptr->ibuf_tail;
255 static unsigned comm_outbuf(struct DosDeviceStruct *ptr)
257 return ((ptr->obuf_tail > ptr->obuf_head) ? ptr->obuf_size : 0)
258 + ptr->obuf_head - ptr->obuf_tail;
261 static int COMM_WhackModem(int fd, unsigned int andy, unsigned int orrie)
263 unsigned int mstat, okay;
264 okay = ioctl(fd, TIOCMGET, &mstat);
265 if (okay) return okay;
266 if (andy) mstat &= andy;
268 return ioctl(fd, TIOCMSET, &mstat);
271 static void CALLBACK comm_notification( ULONG_PTR private )
273 struct DosDeviceStruct *ptr = (struct DosDeviceStruct *)private;
274 int prev, bleft, len;
276 int cid = GetCommPort_fd(ptr->fd);
278 TRACE("async notification\n");
279 /* read data from comm port */
280 prev = comm_inbuf(ptr);
282 bleft = ((ptr->ibuf_tail > ptr->ibuf_head) ? (ptr->ibuf_tail-1) : ptr->ibuf_size)
284 len = read(ptr->fd, ptr->inbuf + ptr->ibuf_head, bleft?bleft:1);
287 ptr->commerror = CE_RXOVER;
289 /* check for events */
290 if ((ptr->eventmask & EV_RXFLAG) &&
291 memchr(ptr->inbuf + ptr->ibuf_head, ptr->evtchar, len)) {
292 *(WORD*)(unknown[cid]) |= EV_RXFLAG;
295 if (ptr->eventmask & EV_RXCHAR) {
296 *(WORD*)(unknown[cid]) |= EV_RXCHAR;
299 /* advance buffer position */
300 ptr->ibuf_head += len;
301 if (ptr->ibuf_head >= ptr->ibuf_size)
306 /* check for notification */
307 if (ptr->wnd && (ptr->n_read>0) && (prev<ptr->n_read) &&
308 (comm_inbuf(ptr)>=ptr->n_read)) {
309 /* passed the receive notification threshold */
313 /* write any TransmitCommChar character */
315 len = write(ptr->fd, &(ptr->xmit), 1);
316 if (len > 0) ptr->xmit = -1;
318 /* write from output queue */
319 prev = comm_outbuf(ptr);
321 bleft = ((ptr->obuf_tail <= ptr->obuf_head) ? ptr->obuf_head : ptr->obuf_size)
323 len = bleft ? write(ptr->fd, ptr->outbuf + ptr->obuf_tail, bleft) : 0;
325 ptr->obuf_tail += len;
326 if (ptr->obuf_tail >= ptr->obuf_size)
329 if (ptr->obuf_tail == ptr->obuf_head) {
331 SERVICE_Delete( ptr->s_write );
332 ptr->s_write = INVALID_HANDLE_VALUE;
334 if (ptr->eventmask & EV_TXEMPTY) {
335 *(WORD*)(unknown[cid]) |= EV_TXEMPTY;
341 /* check for notification */
342 if (ptr->wnd && (ptr->n_write>0) && (prev>=ptr->n_write) &&
343 (comm_outbuf(ptr)<ptr->n_write)) {
344 /* passed the transmit notification threshold */
348 /* send notifications, if any */
349 if (ptr->wnd && mask) {
350 TRACE("notifying %04x: cid=%d, mask=%02x\n", ptr->wnd, cid, mask);
351 if (Callout.PostMessageA) Callout.PostMessageA(ptr->wnd, WM_COMMNOTIFY, cid, mask);
355 static void comm_waitread(struct DosDeviceStruct *ptr)
357 if (ptr->s_read != INVALID_HANDLE_VALUE) return;
358 ptr->s_read = SERVICE_AddObject( FILE_DupUnixHandle( ptr->fd,
359 GENERIC_READ | SYNCHRONIZE ),
364 static void comm_waitwrite(struct DosDeviceStruct *ptr)
366 if (ptr->s_write != INVALID_HANDLE_VALUE) return;
367 ptr->s_write = SERVICE_AddObject( FILE_DupUnixHandle( ptr->fd,
368 GENERIC_WRITE | SYNCHRONIZE ),
373 /**************************************************************************
374 * BuildCommDCB16 (USER.213)
376 * According to the ECMA-234 (368.3) the function will return FALSE on
377 * success, otherwise it will return -1.
378 * IF THIS IS NOT CORRECT THE RETURNVALUE CHECK IN BuildCommDCBAndTimeoutsA
381 BOOL16 WINAPI BuildCommDCB16(LPCSTR device, LPDCB16 lpdcb)
383 /* "COM1:9600,n,8,1" */
386 char *ptr, temp[256];
388 TRACE("(%s), ptr %p\n", device, lpdcb);
390 if (!strncasecmp(device,"COM",3)) {
391 port = device[3] - '0';
395 ERR("BUG ! COM0 can't exist!\n");
399 if (!ValidCOMPort(port)) {
400 FIXME("invalid COM port %d?\n",port);
404 memset(lpdcb, 0, sizeof(DCB16)); /* initialize */
411 if (*(device+4) != ':')
414 strcpy(temp,device+5);
415 ptr = strtok(temp, ", ");
417 if (COM[port].baudrate > 0)
418 lpdcb->BaudRate = COM[port].baudrate;
420 lpdcb->BaudRate = atoi(ptr);
421 TRACE("baudrate (%d)\n", lpdcb->BaudRate);
423 ptr = strtok(NULL, ", ");
425 *ptr = toupper(*ptr);
427 TRACE("parity (%c)\n", *ptr);
428 lpdcb->fParity = TRUE;
431 lpdcb->Parity = NOPARITY;
432 lpdcb->fParity = FALSE;
435 lpdcb->Parity = EVENPARITY;
438 lpdcb->Parity = MARKPARITY;
441 lpdcb->Parity = ODDPARITY;
444 WARN("Unknown parity `%c'!\n", *ptr);
448 ptr = strtok(NULL, ", ");
449 TRACE("charsize (%c)\n", *ptr);
450 lpdcb->ByteSize = *ptr - '0';
452 ptr = strtok(NULL, ", ");
453 TRACE("stopbits (%c)\n", *ptr);
456 lpdcb->StopBits = ONESTOPBIT;
459 lpdcb->StopBits = TWOSTOPBITS;
462 WARN("Unknown # of stopbits `%c'!\n", *ptr);
470 /*****************************************************************************
471 * OpenComm16 (USER.200)
473 INT16 WINAPI OpenComm16(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue)
477 TRACE("%s, %d, %d\n", device, cbInQueue, cbOutQueue);
479 if (strlen(device) < 4)
482 port = device[3] - '0';
485 ERR("BUG ! COM0 or LPT0 don't exist !\n");
487 if (!strncasecmp(device,"COM",3)) {
489 TRACE("%s = %s\n", device, COM[port].devicename);
491 if (!ValidCOMPort(port))
497 fd = open(COM[port].devicename, O_RDWR | O_NONBLOCK);
499 ERR("Couldn't open %s ! (%s)\n", COM[port].devicename, strerror(errno));
502 unknown[port] = SEGPTR_ALLOC(40);
503 bzero(unknown[port],40);
505 COM[port].commerror = 0;
506 COM[port].eventmask = 0;
507 COM[port].evtchar = 0; /* FIXME: default? */
508 /* save terminal state */
509 tcgetattr(fd,&m_stat[port]);
510 /* set default parameters */
511 if(COM[port].baudrate>-1){
513 GetCommState16(port, &dcb);
514 dcb.BaudRate=COM[port].baudrate;
516 * databits, parity, stopbits
518 SetCommState16( &dcb);
520 /* init priority characters */
521 COM[port].unget = -1;
523 /* allocate buffers */
524 COM[port].ibuf_size = cbInQueue;
525 COM[port].ibuf_head = COM[port].ibuf_tail = 0;
526 COM[port].obuf_size = cbOutQueue;
527 COM[port].obuf_head = COM[port].obuf_tail = 0;
529 COM[port].inbuf = malloc(cbInQueue);
530 if (COM[port].inbuf) {
531 COM[port].outbuf = malloc(cbOutQueue);
532 if (!COM[port].outbuf)
533 free(COM[port].inbuf);
534 } else COM[port].outbuf = NULL;
535 if (!COM[port].outbuf) {
536 /* not enough memory */
537 tcsetattr(COM[port].fd,TCSANOW,&m_stat[port]);
539 ERR("out of memory\n");
543 COM[port].s_read = INVALID_HANDLE_VALUE;
544 COM[port].s_write = INVALID_HANDLE_VALUE;
545 comm_waitread( &COM[port] );
550 if (!strncasecmp(device,"LPT",3)) {
552 if (!ValidLPTPort(port))
558 fd = open(LPT[port].devicename, O_RDWR | O_NONBLOCK, 0);
563 LPT[port].commerror = 0;
564 LPT[port].eventmask = 0;
565 return port|FLAG_LPT;
571 /*****************************************************************************
572 * CloseComm16 (USER.207)
574 INT16 WINAPI CloseComm16(INT16 cid)
576 struct DosDeviceStruct *ptr;
578 TRACE("cid=%d\n", cid);
579 if ((ptr = GetDeviceStruct(cid)) == NULL) {
580 FIXME("no cid=%d found!\n", cid);
583 if (!(cid&FLAG_LPT)) {
585 SEGPTR_FREE(unknown[cid]); /* [LW] */
587 SERVICE_Delete( COM[cid].s_write );
588 SERVICE_Delete( COM[cid].s_read );
593 /* reset modem lines */
594 tcsetattr(ptr->fd,TCSANOW,&m_stat[cid]);
597 if (close(ptr->fd) == -1) {
598 ptr->commerror = WinError();
599 /* FIXME: should we clear ptr->fd here? */
608 /*****************************************************************************
609 * SetCommBreak16 (USER.210)
611 INT16 WINAPI SetCommBreak16(INT16 cid)
613 struct DosDeviceStruct *ptr;
615 TRACE("cid=%d\n", cid);
616 if ((ptr = GetDeviceStruct(cid)) == NULL) {
617 FIXME("no cid=%d found!\n", cid);
626 /*****************************************************************************
627 * ClearCommBreak16 (USER.211)
629 INT16 WINAPI ClearCommBreak16(INT16 cid)
631 struct DosDeviceStruct *ptr;
633 TRACE("cid=%d\n", cid);
634 if (!(ptr = GetDeviceStruct(cid))) {
635 FIXME("no cid=%d found!\n", cid);
643 /*****************************************************************************
644 * EscapeCommFunction16 (USER.214)
646 LONG WINAPI EscapeCommFunction16(UINT16 cid,UINT16 nFunction)
649 struct DosDeviceStruct *ptr;
652 TRACE("cid=%d, function=%d\n", cid, nFunction);
653 if ((nFunction != GETMAXCOM) && (nFunction != GETMAXLPT)) {
654 if ((ptr = GetDeviceStruct(cid)) == NULL) {
655 FIXME("no cid=%d found!\n", cid);
658 if (tcgetattr(ptr->fd,&port) == -1) {
659 TRACE("tcgetattr failed\n");
660 ptr->commerror=WinError();
671 TRACE("GETMAXCOM\n");
672 for (max = MAX_PORTS;!COM[max].devicename;max--)
678 TRACE("GETMAXLPT\n");
679 for (max = MAX_PORTS;!LPT[max].devicename;max--)
681 return FLAG_LPT + max;
685 TRACE("GETBASEIRQ\n");
686 /* FIXME: use tables */
687 /* just fake something for now */
688 if (cid & FLAG_LPT) {
689 /* LPT1: irq 7, LPT2: irq 5 */
690 return (cid & 0x7f) ? 5 : 7;
692 /* COM1: irq 4, COM2: irq 3,
693 COM3: irq 4, COM4: irq 3 */
694 return 4 - (cid & 1);
701 return COMM_WhackModem(ptr->fd, ~TIOCM_DTR, 0);
706 return COMM_WhackModem(ptr->fd, ~TIOCM_RTS, 0);
712 return COMM_WhackModem(ptr->fd, 0, TIOCM_DTR);
718 return COMM_WhackModem(ptr->fd, 0, TIOCM_RTS);
723 port.c_iflag |= IXOFF;
728 port.c_iflag |= IXON;
732 WARN("(cid=%d,nFunction=%d): Unknown function\n",
737 if (tcsetattr(ptr->fd, TCSADRAIN, &port) == -1) {
738 ptr->commerror = WinError();
746 /*****************************************************************************
747 * FlushComm16 (USER.215)
749 INT16 WINAPI FlushComm16(INT16 cid,INT16 fnQueue)
752 struct DosDeviceStruct *ptr;
754 TRACE("cid=%d, queue=%d\n", cid, fnQueue);
755 if ((ptr = GetDeviceStruct(cid)) == NULL) {
756 FIXME("no cid=%d found!\n", cid);
762 ptr->obuf_tail = ptr->obuf_head;
766 ptr->ibuf_head = ptr->ibuf_tail;
769 WARN("(cid=%d,fnQueue=%d):Unknown queue\n",
773 if (tcflush(ptr->fd, queue)) {
774 ptr->commerror = WinError();
782 /********************************************************************
783 * GetCommError16 (USER.203)
785 INT16 WINAPI GetCommError16(INT16 cid,LPCOMSTAT16 lpStat)
788 struct DosDeviceStruct *ptr;
792 if ((ptr = GetDeviceStruct(cid)) == NULL) {
793 FIXME("no handle for cid = %0x!\n",cid);
797 WARN(" cid %d not comm port\n",cid);
800 stol = (unsigned char *)unknown[cid] + COMM_MSR_OFFSET;
801 ioctl(ptr->fd,TIOCMGET,&mstat);
802 COMM_MSRUpdate( stol, mstat);
807 lpStat->cbOutQue = comm_outbuf(ptr);
808 lpStat->cbInQue = comm_inbuf(ptr);
810 TRACE("cid %d, error %d, stat %d in %d out %d, stol %x\n",
811 cid, ptr->commerror, lpStat->status, lpStat->cbInQue,
812 lpStat->cbOutQue, *stol);
815 TRACE("cid %d, error %d, lpStat NULL stol %x\n",
816 cid, ptr->commerror, *stol);
818 /* Return any errors and clear it */
819 temperror = ptr->commerror;
824 /*****************************************************************************
825 * SetCommEventMask16 (USER.208)
827 SEGPTR WINAPI SetCommEventMask16(INT16 cid,UINT16 fuEvtMask)
829 struct DosDeviceStruct *ptr;
834 TRACE("cid %d,mask %d\n",cid,fuEvtMask);
835 if ((ptr = GetDeviceStruct(cid)) == NULL) {
836 FIXME("no handle for cid = %0x!\n",cid);
840 ptr->eventmask = fuEvtMask;
842 if ((cid&FLAG_LPT) || !ValidCOMPort(cid)) {
843 WARN(" cid %d not comm port\n",cid);
846 /* it's a COM port ? -> modify flags */
847 stol = (unsigned char *)unknown[cid] + COMM_MSR_OFFSET;
848 repid = ioctl(ptr->fd,TIOCMGET,&mstat);
849 TRACE(" ioctl %d, msr %x at %p %p\n",repid,mstat,stol,unknown[cid]);
850 COMM_MSRUpdate( stol, mstat);
852 TRACE(" modem dcd construct %x\n",*stol);
853 return SEGPTR_GET(unknown[cid]);
856 /*****************************************************************************
857 * GetCommEventMask16 (USER.209)
859 UINT16 WINAPI GetCommEventMask16(INT16 cid,UINT16 fnEvtClear)
861 struct DosDeviceStruct *ptr;
864 TRACE("cid %d, mask %d\n", cid, fnEvtClear);
865 if ((ptr = GetDeviceStruct(cid)) == NULL) {
866 FIXME("no handle for cid = %0x!\n",cid);
870 if ((cid&FLAG_LPT) || !ValidCOMPort(cid)) {
871 WARN(" cid %d not comm port\n",cid);
875 events = *(WORD*)(unknown[cid]) & fnEvtClear;
876 *(WORD*)(unknown[cid]) &= ~fnEvtClear;
880 /*****************************************************************************
881 * SetCommState16 (USER.201)
883 INT16 WINAPI SetCommState16(LPDCB16 lpdcb)
886 struct DosDeviceStruct *ptr;
887 int bytesize, stopbits;
890 TRACE("cid %d, ptr %p\n", lpdcb->Id, lpdcb);
891 if ((ptr = GetDeviceStruct(lpdcb->Id)) == NULL) {
892 FIXME("no handle for cid = %0x!\n",lpdcb->Id);
895 if (tcgetattr(ptr->fd, &port) == -1) {
896 ptr->commerror = WinError();
901 port.c_cc[VTIME] = 1;
904 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
906 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
908 port.c_iflag |= (IGNBRK);
910 port.c_oflag &= ~(OPOST);
912 port.c_cflag &= ~(HUPCL);
913 port.c_cflag |= CLOCAL | CREAD;
915 port.c_lflag &= ~(ICANON|ECHO|ISIG);
916 port.c_lflag |= NOFLSH;
918 TRACE("baudrate %d\n",lpdcb->BaudRate);
920 port.c_cflag &= ~CBAUD;
921 switch (lpdcb->BaudRate) {
924 port.c_cflag |= B110;
928 port.c_cflag |= B300;
932 port.c_cflag |= B600;
936 port.c_cflag |= B1200;
940 port.c_cflag |= B2400;
944 port.c_cflag |= B4800;
948 port.c_cflag |= B9600;
952 port.c_cflag |= B19200;
956 port.c_cflag |= B38400;
960 port.c_cflag |= B57600;
965 port.c_cflag |= B115200;
969 ptr->commerror = IE_BAUDRATE;
972 #elif !defined(__EMX__)
973 switch (lpdcb->BaudRate) {
976 port.c_ospeed = B110;
980 port.c_ospeed = B300;
984 port.c_ospeed = B600;
988 port.c_ospeed = B1200;
992 port.c_ospeed = B2400;
996 port.c_ospeed = B4800;
1000 port.c_ospeed = B9600;
1004 port.c_ospeed = B19200;
1008 port.c_ospeed = B38400;
1011 ptr->commerror = IE_BAUDRATE;
1014 port.c_ispeed = port.c_ospeed;
1016 bytesize=lpdcb->ByteSize;
1017 stopbits=lpdcb->StopBits;
1019 TRACE("fParity %d Parity %d\n",lpdcb->fParity, lpdcb->Parity);
1021 port.c_cflag &= ~(PARENB | PARODD | CMSPAR);
1023 port.c_cflag &= ~(PARENB | PARODD);
1026 port.c_iflag |= INPCK;
1028 port.c_iflag &= ~INPCK;
1029 switch (lpdcb->Parity) {
1033 port.c_cflag |= (PARENB | PARODD);
1036 port.c_cflag |= PARENB;
1039 /* Linux defines mark/space (stick) parity */
1041 port.c_cflag |= (PARENB | CMSPAR);
1044 port.c_cflag |= (PARENB | PARODD | CMSPAR);
1047 /* try the POSIX way */
1049 if( stopbits == ONESTOPBIT) {
1050 stopbits = TWOSTOPBITS;
1051 port.c_iflag &= ~INPCK;
1053 ptr->commerror = IE_BYTESIZE;
1060 port.c_iflag &= ~INPCK;
1062 ptr->commerror = IE_BYTESIZE;
1068 ptr->commerror = IE_BYTESIZE;
1072 TRACE("bytesize %d\n",bytesize);
1073 port.c_cflag &= ~CSIZE;
1076 port.c_cflag |= CS5;
1079 port.c_cflag |= CS6;
1082 port.c_cflag |= CS7;
1085 port.c_cflag |= CS8;
1088 ptr->commerror = IE_BYTESIZE;
1092 TRACE("stopbits %d\n",stopbits);
1096 port.c_cflag &= ~CSTOPB;
1098 case ONE5STOPBITS: /* wil be selected if bytesize is 5 */
1100 port.c_cflag |= CSTOPB;
1103 ptr->commerror = IE_BYTESIZE;
1108 if (lpdcb->fDtrflow || lpdcb->fRtsflow || lpdcb->fOutxCtsFlow)
1109 port.c_cflag |= CRTSCTS;
1111 if (lpdcb->fDtrDisable)
1112 port.c_cflag &= ~CRTSCTS;
1115 port.c_iflag |= IXON;
1117 port.c_iflag &= ~IXON;
1119 port.c_iflag |= IXOFF;
1121 port.c_iflag &= ~IXOFF;
1123 ptr->evtchar = lpdcb->EvtChar;
1128 if (tcsetattr(ptr->fd, TCSADRAIN, &port) == -1) {
1129 ptr->commerror = WinError();
1137 /*****************************************************************************
1138 * GetCommState16 (USER.202)
1140 INT16 WINAPI GetCommState16(INT16 cid, LPDCB16 lpdcb)
1143 struct DosDeviceStruct *ptr;
1144 struct termios port;
1146 TRACE("cid %d, ptr %p\n", cid, lpdcb);
1147 if ((ptr = GetDeviceStruct(cid)) == NULL) {
1148 FIXME("no handle for cid = %0x!\n",cid);
1151 if (tcgetattr(ptr->fd, &port) == -1) {
1152 ptr->commerror = WinError();
1158 speed = port.c_cflag & CBAUD;
1160 speed = port.c_ospeed;
1164 lpdcb->BaudRate = 110;
1167 lpdcb->BaudRate = 300;
1170 lpdcb->BaudRate = 600;
1173 lpdcb->BaudRate = 1200;
1176 lpdcb->BaudRate = 2400;
1179 lpdcb->BaudRate = 4800;
1182 lpdcb->BaudRate = 9600;
1185 lpdcb->BaudRate = 19200;
1188 lpdcb->BaudRate = 38400;
1192 lpdcb->BaudRate = 57600;
1197 lpdcb->BaudRate = 57601;
1202 switch (port.c_cflag & CSIZE) {
1204 lpdcb->ByteSize = 5;
1207 lpdcb->ByteSize = 6;
1210 lpdcb->ByteSize = 7;
1213 lpdcb->ByteSize = 8;
1217 if(port.c_iflag & INPCK)
1218 lpdcb->fParity = TRUE;
1220 lpdcb->fParity = FALSE;
1222 switch (port.c_cflag & (PARENB | PARODD | CMSPAR))
1224 switch (port.c_cflag & (PARENB | PARODD))
1228 lpdcb->Parity = NOPARITY;
1231 lpdcb->Parity = EVENPARITY;
1233 case (PARENB | PARODD):
1234 lpdcb->Parity = ODDPARITY;
1237 case (PARENB | CMSPAR):
1238 lpdcb->Parity = MARKPARITY;
1240 case (PARENB | PARODD | CMSPAR):
1241 lpdcb->Parity = SPACEPARITY;
1246 if (port.c_cflag & CSTOPB)
1247 if(lpdcb->ByteSize == 5)
1248 lpdcb->StopBits = ONE5STOPBITS;
1250 lpdcb->StopBits = TWOSTOPBITS;
1252 lpdcb->StopBits = ONESTOPBIT;
1254 lpdcb->RlsTimeout = 50;
1255 lpdcb->CtsTimeout = 50;
1256 lpdcb->DsrTimeout = 50;
1260 lpdcb->fDtrDisable = 0;
1264 if (port.c_cflag & CRTSCTS) {
1265 lpdcb->fDtrflow = 1;
1266 lpdcb->fRtsflow = 1;
1267 lpdcb->fOutxCtsFlow = 1;
1268 lpdcb->fOutxDsrFlow = 1;
1271 lpdcb->fDtrDisable = 1;
1273 if (port.c_iflag & IXON)
1278 if (port.c_iflag & IXOFF)
1287 lpdcb->XoffLim = 10;
1289 lpdcb->EvtChar = ptr->evtchar;
1295 /*****************************************************************************
1296 * TransmitCommChar16 (USER.206)
1298 INT16 WINAPI TransmitCommChar16(INT16 cid,CHAR chTransmit)
1300 struct DosDeviceStruct *ptr;
1302 TRACE("cid %d, data %d \n", cid, chTransmit);
1303 if ((ptr = GetDeviceStruct(cid)) == NULL) {
1304 FIXME("no handle for cid = %0x!\n",cid);
1308 if (ptr->suspended) {
1309 ptr->commerror = IE_HARDWARE;
1313 if (ptr->xmit >= 0) {
1314 /* character already queued */
1315 /* FIXME: which error would Windows return? */
1316 ptr->commerror = CE_TXFULL;
1320 if (ptr->obuf_head == ptr->obuf_tail) {
1321 /* transmit queue empty, try to transmit directly */
1322 if (write(ptr->fd, &chTransmit, 1) == -1) {
1323 /* didn't work, queue it */
1324 ptr->xmit = chTransmit;
1325 comm_waitwrite(ptr);
1328 /* data in queue, let this char be transmitted next */
1329 ptr->xmit = chTransmit;
1330 comm_waitwrite(ptr);
1337 /*****************************************************************************
1338 * UngetCommChar16 (USER.212)
1340 INT16 WINAPI UngetCommChar16(INT16 cid,CHAR chUnget)
1342 struct DosDeviceStruct *ptr;
1344 TRACE("cid %d (char %d)\n", cid, chUnget);
1345 if ((ptr = GetDeviceStruct(cid)) == NULL) {
1346 FIXME("no handle for cid = %0x!\n",cid);
1350 if (ptr->suspended) {
1351 ptr->commerror = IE_HARDWARE;
1355 if (ptr->unget>=0) {
1356 /* character already queued */
1357 /* FIXME: which error would Windows return? */
1358 ptr->commerror = CE_RXOVER;
1362 ptr->unget = chUnget;
1368 /*****************************************************************************
1369 * ReadComm16 (USER.204)
1371 INT16 WINAPI ReadComm16(INT16 cid,LPSTR lpvBuf,INT16 cbRead)
1374 struct DosDeviceStruct *ptr;
1375 LPSTR orgBuf = lpvBuf;
1377 TRACE("cid %d, ptr %p, length %d\n", cid, lpvBuf, cbRead);
1378 if ((ptr = GetDeviceStruct(cid)) == NULL) {
1379 FIXME("no handle for cid = %0x!\n",cid);
1383 if (ptr->suspended) {
1384 ptr->commerror = IE_HARDWARE;
1388 /* read unget character */
1389 if (ptr->unget>=0) {
1390 *lpvBuf++ = ptr->unget;
1397 /* read from receive buffer */
1398 while (length < cbRead) {
1399 status = ((ptr->ibuf_head < ptr->ibuf_tail) ?
1400 ptr->ibuf_size : ptr->ibuf_head) - ptr->ibuf_tail;
1402 if ((cbRead - length) < status)
1403 status = cbRead - length;
1405 memcpy(lpvBuf, ptr->inbuf + ptr->ibuf_tail, status);
1406 ptr->ibuf_tail += status;
1407 if (ptr->ibuf_tail >= ptr->ibuf_size)
1413 TRACE("%.*s\n", length, orgBuf);
1418 /*****************************************************************************
1419 * WriteComm16 (USER.205)
1421 INT16 WINAPI WriteComm16(INT16 cid, LPSTR lpvBuf, INT16 cbWrite)
1424 struct DosDeviceStruct *ptr;
1426 TRACE("cid %d, ptr %p, length %d\n",
1427 cid, lpvBuf, cbWrite);
1428 if ((ptr = GetDeviceStruct(cid)) == NULL) {
1429 FIXME("no handle for cid = %0x!\n",cid);
1433 if (ptr->suspended) {
1434 ptr->commerror = IE_HARDWARE;
1438 TRACE("%.*s\n", cbWrite, lpvBuf );
1441 while (length < cbWrite) {
1442 if ((ptr->obuf_head == ptr->obuf_tail) && (ptr->xmit < 0)) {
1443 /* no data queued, try to write directly */
1444 status = write(ptr->fd, lpvBuf, cbWrite - length);
1451 /* can't write directly, put into transmit buffer */
1452 status = ((ptr->obuf_tail > ptr->obuf_head) ?
1453 (ptr->obuf_tail-1) : ptr->obuf_size) - ptr->obuf_head;
1455 if ((cbWrite - length) < status)
1456 status = cbWrite - length;
1457 memcpy(lpvBuf, ptr->outbuf + ptr->obuf_head, status);
1458 ptr->obuf_head += status;
1459 if (ptr->obuf_head >= ptr->obuf_size)
1463 comm_waitwrite(ptr);
1470 /***********************************************************************
1471 * EnableCommNotification (USER.245)
1473 BOOL16 WINAPI EnableCommNotification16( INT16 cid, HWND16 hwnd,
1474 INT16 cbWriteNotify, INT16 cbOutQueue )
1476 struct DosDeviceStruct *ptr;
1478 TRACE("(%d, %x, %d, %d)\n", cid, hwnd, cbWriteNotify, cbOutQueue);
1479 if ((ptr = GetDeviceStruct(cid)) == NULL) {
1480 FIXME("no handle for cid = %0x!\n",cid);
1484 ptr->n_read = cbWriteNotify;
1485 ptr->n_write = cbOutQueue;
1490 /**************************************************************************
1491 * BuildCommDCBA (KERNEL32.113)
1493 * Updates a device control block data structure with values from an
1494 * ascii device control string. The device control string has two forms
1495 * normal and extended, it must be exclusively in one or the other form.
1499 * True on success, false on an malformed control string.
1501 BOOL WINAPI BuildCommDCBA(
1502 LPCSTR device, /* [in] The ascii device control string used to update the DCB. */
1503 LPDCB lpdcb) /* [out] The device control block to be updated. */
1505 return BuildCommDCBAndTimeoutsA(device,lpdcb,NULL);
1508 /**************************************************************************
1509 * BuildCommDCBAndTimeoutsA (KERNEL32.114)
1511 * Updates a device control block data structure with values from an
1512 * ascii device control string. Taking time out values from a time outs
1513 * struct if desired by the control string.
1517 * True on success, false bad handles etc
1519 BOOL WINAPI BuildCommDCBAndTimeoutsA(
1520 LPCSTR device, /* [in] The ascii device control string. */
1521 LPDCB lpdcb, /* [out] The device control block to be updated. */
1522 LPCOMMTIMEOUTS lptimeouts) /* [in] The time outs to use if asked to set them by the control string. */
1527 TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts);
1529 if (!strncasecmp(device,"COM",3)) {
1532 ERR("BUG! COM0 can't exist!\n");
1535 if (!ValidCOMPort(port))
1537 if (*(device+4)!=':')
1539 temp=(LPSTR)(device+5);
1543 lpdcb->DCBlength = sizeof(DCB);
1544 if (strchr(temp,',')) { /* old style */
1547 char last=temp[strlen(temp)-1];
1549 ret=BuildCommDCB16(device,&dcb16);
1552 lpdcb->BaudRate = dcb16.BaudRate;
1553 lpdcb->ByteSize = dcb16.ByteSize;
1554 lpdcb->fBinary = dcb16.fBinary;
1555 lpdcb->Parity = dcb16.Parity;
1556 lpdcb->fParity = dcb16.fParity;
1557 lpdcb->fNull = dcb16.fNull;
1558 lpdcb->StopBits = dcb16.StopBits;
1561 lpdcb->fOutX = TRUE;
1562 lpdcb->fOutxCtsFlow = FALSE;
1563 lpdcb->fOutxDsrFlow = FALSE;
1564 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
1565 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
1566 } else if (last=='p') {
1567 lpdcb->fInX = FALSE;
1568 lpdcb->fOutX = FALSE;
1569 lpdcb->fOutxCtsFlow = TRUE;
1570 lpdcb->fOutxDsrFlow = TRUE;
1571 lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE;
1572 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
1574 lpdcb->fInX = FALSE;
1575 lpdcb->fOutX = FALSE;
1576 lpdcb->fOutxCtsFlow = FALSE;
1577 lpdcb->fOutxDsrFlow = FALSE;
1578 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
1579 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
1581 lpdcb->XonChar = dcb16.XonChar;
1582 lpdcb->XoffChar = dcb16.XoffChar;
1583 lpdcb->ErrorChar= dcb16.PeChar;
1584 lpdcb->fErrorChar= dcb16.fPeChar;
1585 lpdcb->EofChar = dcb16.EofChar;
1586 lpdcb->EvtChar = dcb16.EvtChar;
1587 lpdcb->XonLim = dcb16.XonLim;
1588 lpdcb->XoffLim = dcb16.XoffLim;
1591 ptr=strtok(temp," ");
1596 if (!strncmp("baud=",ptr,5)) {
1597 if (!sscanf(ptr+5,"%ld",&x))
1598 WARN("Couldn't parse %s\n",ptr);
1599 lpdcb->BaudRate = x;
1602 if (!strncmp("stop=",ptr,5)) {
1603 if (!sscanf(ptr+5,"%ld",&x))
1604 WARN("Couldn't parse %s\n",ptr);
1605 lpdcb->StopBits = x;
1608 if (!strncmp("data=",ptr,5)) {
1609 if (!sscanf(ptr+5,"%ld",&x))
1610 WARN("Couldn't parse %s\n",ptr);
1611 lpdcb->ByteSize = x;
1614 if (!strncmp("parity=",ptr,7)) {
1615 lpdcb->fParity = TRUE;
1618 lpdcb->fParity = FALSE;
1619 lpdcb->Parity = NOPARITY;
1622 lpdcb->Parity = EVENPARITY;
1625 lpdcb->Parity = ODDPARITY;
1628 lpdcb->Parity = MARKPARITY;
1634 ERR("Unhandled specifier '%s', please report.\n",ptr);
1635 ptr=strtok(NULL," ");
1637 if (lpdcb->BaudRate==110)
1638 lpdcb->StopBits = 2;
1642 /**************************************************************************
1643 * BuildCommDCBAndTimeoutsW (KERNEL32.115)
1645 * Updates a device control block data structure with values from an
1646 * unicode device control string. Taking time out values from a time outs
1647 * struct if desired by the control string.
1651 * True on success, false bad handles etc.
1653 BOOL WINAPI BuildCommDCBAndTimeoutsW(
1654 LPCWSTR devid, /* [in] The unicode device control string. */
1655 LPDCB lpdcb, /* [out] The device control block to be updated. */
1656 LPCOMMTIMEOUTS lptimeouts) /* [in] The time outs to use if asked to set them by the control string. */
1661 TRACE("(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
1662 devidA = HEAP_strdupWtoA( GetProcessHeap(), 0, devid );
1665 ret=BuildCommDCBAndTimeoutsA(devidA,lpdcb,lptimeouts);
1666 HeapFree( GetProcessHeap(), 0, devidA );
1671 /**************************************************************************
1672 * BuildCommDCBW (KERNEL32.116)
1674 * Updates a device control block structure with values from an
1675 * unicode device control string. The device control string has two forms
1676 * normal and extended, it must be exclusively in one or the other form.
1680 * True on success, false on an malformed control string.
1682 BOOL WINAPI BuildCommDCBW(
1683 LPCWSTR devid, /* [in] The unicode device control string. */
1684 LPDCB lpdcb) /* [out] The device control block to be updated. */
1686 return BuildCommDCBAndTimeoutsW(devid,lpdcb,NULL);
1689 /* FIXME: having these global for win32 for now */
1692 /*****************************************************************************
1693 * SetCommBreak (KERNEL32.616)
1695 * Halts the transmission of characters to a communications device.
1699 * True on success, and false if the communications device could not be found,
1700 * the control is not supported.
1704 * Only TIOCSBRK and TIOCCBRK are supported.
1706 BOOL WINAPI SetCommBreak(
1707 HANDLE handle) /* [in] The communictions device to suspend. */
1709 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
1712 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
1714 TRACE("FILE_GetUnixHandle failed\n");
1717 result = ioctl(fd,TIOCSBRK,0);
1721 TRACE("ioctl failed\n");
1722 SetLastError(ERROR_NOT_SUPPORTED);
1727 FIXME("ioctl not available\n");
1728 SetLastError(ERROR_NOT_SUPPORTED);
1733 /*****************************************************************************
1734 * ClearCommBreak (KERNEL32.135)
1736 * Resumes character transmission from a communication device.
1740 * True on success and false if the communications device could not be found.
1744 * Only TIOCSBRK and TIOCCBRK are supported.
1746 BOOL WINAPI ClearCommBreak(
1747 HANDLE handle) /* [in] The halted communication device whose character transmission is to be resumed. */
1749 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
1752 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
1754 TRACE("FILE_GetUnixHandle failed\n");
1757 result = ioctl(fd,TIOCCBRK,0);
1761 TRACE("ioctl failed\n");
1762 SetLastError(ERROR_NOT_SUPPORTED);
1767 FIXME("ioctl not available\n");
1768 SetLastError(ERROR_NOT_SUPPORTED);
1773 /*****************************************************************************
1774 * EscapeCommFunction (KERNEL32.213)
1776 * Directs a communication device to perform an extended function.
1780 * True or requested data on successful completion of the command,
1781 * false if the device is not present cannot execute the command
1782 * or the command failed.
1784 BOOL WINAPI EscapeCommFunction(
1785 HANDLE handle, /* [in] The communication device to perform the extended function. */
1786 UINT nFunction) /* [in] The extended function to be performed. */
1788 int fd,direct=FALSE,result=FALSE;
1789 struct termios port;
1791 TRACE("handle %d, function=%d\n", handle, nFunction);
1792 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
1794 FIXME("handle %d not found.\n",handle);
1798 if (tcgetattr(fd,&port) == -1) {
1799 commerror=WinError();
1804 switch (nFunction) {
1813 result= COMM_WhackModem(fd, ~TIOCM_DTR, 0);
1821 result= COMM_WhackModem(fd, ~TIOCM_RTS, 0);
1829 result= COMM_WhackModem(fd, 0, TIOCM_DTR);
1837 result= COMM_WhackModem(fd, 0, TIOCM_RTS);
1843 port.c_iflag |= IXOFF;
1848 port.c_iflag |= IXON;
1851 TRACE("setbreak\n");
1854 result = ioctl(fd,TIOCSBRK,0);
1858 TRACE("clrbreak\n");
1861 result = ioctl(fd,TIOCCBRK,0);
1865 WARN("(handle=%d,nFunction=%d): Unknown function\n",
1871 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
1872 commerror = WinError();
1882 commerror=WinError();
1891 /********************************************************************
1892 * PurgeComm (KERNEL32.558)
1894 * Terminates pending operations and/or discards buffers on a
1895 * communication resource.
1899 * True on success and false if the communications handle is bad.
1901 BOOL WINAPI PurgeComm(
1902 HANDLE handle, /* [in] The communication resource to be purged. */
1903 DWORD flags) /* [in] Flags for clear pending/buffer on input/output. */
1907 TRACE("handle %d, flags %lx\n", handle, flags);
1909 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
1911 FIXME("no handle %d found\n",handle);
1916 ** not exactly sure how these are different
1917 ** Perhaps if we had our own internal queues, one flushes them
1918 ** and the other flushes the kernel's buffers.
1920 if(flags&PURGE_TXABORT)
1921 tcflush(fd,TCOFLUSH);
1922 if(flags&PURGE_RXABORT)
1923 tcflush(fd,TCIFLUSH);
1924 if(flags&PURGE_TXCLEAR)
1925 tcflush(fd,TCOFLUSH);
1926 if(flags&PURGE_RXCLEAR)
1927 tcflush(fd,TCIFLUSH);
1933 /*****************************************************************************
1934 * ClearCommError (KERNEL32.136)
1936 * Enables further I/O operations on a communications resource after
1937 * supplying error and current status information.
1941 * True on success, false if the communication resource handle is bad.
1943 BOOL WINAPI ClearCommError(
1944 HANDLE handle, /* [in] The communication resource with the error. */
1945 LPDWORD errors, /* [out] Flags indicating error the resource experienced. */
1946 LPCOMSTAT lpStat) /* [out] The status of the communication resource. */
1950 fd=FILE_GetUnixHandle( handle, GENERIC_READ );
1953 FIXME("no handle %d found\n",handle);
1962 if(ioctl(fd, TIOCOUTQ, &lpStat->cbOutQue))
1963 WARN("ioctl returned error\n");
1965 lpStat->cbOutQue = 0; /* FIXME: find a different way to find out */
1969 if(ioctl(fd, TIOCINQ, &lpStat->cbInQue))
1970 WARN("ioctl returned error\n");
1973 TRACE("handle %d cbInQue = %ld cbOutQue = %ld\n",
1974 handle, lpStat->cbInQue, lpStat->cbOutQue);
1983 ** After an asynchronous write opperation, the
1984 ** app will call ClearCommError to see if the
1985 ** results are ready yet. It waits for ERROR_IO_PENDING
1987 commerror = ERROR_IO_PENDING;
1992 /*****************************************************************************
1993 * SetupComm (KERNEL32.677)
1995 * Called after CreateFile to hint to the communication resource to use
1996 * specified sizes for input and output buffers rather than the default values.
2000 * True if successful, false if the communications resource handle is bad.
2006 BOOL WINAPI SetupComm(
2007 HANDLE handle, /* [in] The just created communication resource handle. */
2008 DWORD insize, /* [in] The suggested size of the communication resources input buffer in bytes. */
2009 DWORD outsize) /* [in] The suggested size of the communication resources output buffer in bytes. */
2013 FIXME("insize %ld outsize %ld unimplemented stub\n", insize, outsize);
2014 fd=FILE_GetUnixHandle( handle, GENERIC_READ );
2016 FIXME("handle %d not found?\n",handle);
2023 /*****************************************************************************
2024 * GetCommMask (KERNEL32.284)
2026 * Obtain the events associated with a communication device that will cause a call
2027 * WaitCommEvent to return.
2031 * True on success, fail on bad device handle etc.
2033 BOOL WINAPI GetCommMask(
2034 HANDLE handle, /* [in] The communications device. */
2035 LPDWORD evtmask) /* [out] The events which cause WaitCommEvent to return. */
2039 TRACE("handle %d, mask %p\n", handle, evtmask);
2043 struct get_serial_info_request *req = server_alloc_req( sizeof(*req), 0 );
2044 req->handle = handle;
2045 if ((ret = !server_call( REQ_GET_SERIAL_INFO )))
2047 if (evtmask) *evtmask = req->eventmask;
2054 /*****************************************************************************
2055 * SetCommMask (KERNEL32.618)
2057 * There be some things we need to hear about yon there communications device.
2058 * (Set which events associated with a communication device should cause
2059 * a call WaitCommEvent to return.)
2063 * True on success, false on bad handle etc.
2065 BOOL WINAPI SetCommMask(
2066 HANDLE handle, /* [in] The communications device. */
2067 DWORD evtmask) /* [in] The events that to be monitored. */
2071 TRACE("handle %d, mask %lx\n", handle, evtmask);
2075 struct set_serial_info_request *req = server_alloc_req( sizeof(*req), 0 );
2076 req->handle = handle;
2077 req->flags = SERIALINFO_SET_MASK;
2078 req->eventmask = evtmask;
2079 ret = !server_call( REQ_SET_SERIAL_INFO );
2085 /*****************************************************************************
2086 * SetCommState (KERNEL32.619)
2088 * Re-initializes all hardware and control settings of a communications device,
2089 * with values from a device control block without effecting the input and output
2094 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
2096 BOOL WINAPI SetCommState(
2097 HANDLE handle, /* [in] The communications device. */
2098 LPDCB lpdcb) /* [out] The device control block. */
2100 struct termios port;
2101 int fd, bytesize, stopbits;
2103 TRACE("handle %d, ptr %p\n", handle, lpdcb);
2104 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
2105 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
2106 (lpdcb->StopBits == ONESTOPBIT)?1:
2107 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
2108 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
2109 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
2111 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
2113 FIXME("no handle %d found\n",handle);
2117 if ((tcgetattr(fd,&port)) == -1) {
2118 int save_error = errno;
2119 commerror = WinError();
2121 ERR("tcgetattr error '%s'\n", strerror(save_error));
2125 port.c_cc[VMIN] = 0;
2126 port.c_cc[VTIME] = 1;
2129 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
2131 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
2133 port.c_iflag |= (IGNBRK);
2135 port.c_oflag &= ~(OPOST);
2137 port.c_cflag &= ~(HUPCL);
2138 port.c_cflag |= CLOCAL | CREAD;
2140 port.c_lflag &= ~(ICANON|ECHO|ISIG);
2141 port.c_lflag |= NOFLSH;
2144 ** MJM - removed default baudrate settings
2145 ** TRACE(comm,"baudrate %ld\n",lpdcb->BaudRate);
2148 port.c_cflag &= ~CBAUD;
2149 switch (lpdcb->BaudRate) {
2152 port.c_cflag |= B110;
2156 port.c_cflag |= B300;
2160 port.c_cflag |= B600;
2164 port.c_cflag |= B1200;
2168 port.c_cflag |= B2400;
2172 port.c_cflag |= B4800;
2176 port.c_cflag |= B9600;
2180 port.c_cflag |= B19200;
2184 port.c_cflag |= B38400;
2188 port.c_cflag |= B57600;
2193 port.c_cflag |= B115200;
2198 port.c_cflag |= B230400;
2203 port.c_cflag |= B460800;
2207 commerror = IE_BAUDRATE;
2209 ERR("baudrate %ld\n",lpdcb->BaudRate);
2212 #elif !defined(__EMX__)
2213 switch (lpdcb->BaudRate) {
2216 port.c_ospeed = B110;
2220 port.c_ospeed = B300;
2224 port.c_ospeed = B600;
2228 port.c_ospeed = B1200;
2232 port.c_ospeed = B2400;
2236 port.c_ospeed = B4800;
2240 port.c_ospeed = B9600;
2244 port.c_ospeed = B19200;
2248 port.c_ospeed = B38400;
2251 commerror = IE_BAUDRATE;
2253 ERR("baudrate %ld\n",lpdcb->BaudRate);
2256 port.c_ispeed = port.c_ospeed;
2258 bytesize=lpdcb->ByteSize;
2259 stopbits=lpdcb->StopBits;
2262 port.c_cflag &= ~(PARENB | PARODD | CMSPAR);
2264 port.c_cflag &= ~(PARENB | PARODD);
2267 port.c_iflag |= INPCK;
2269 port.c_iflag &= ~INPCK;
2270 switch (lpdcb->Parity) {
2274 port.c_cflag |= (PARENB | PARODD);
2277 port.c_cflag |= PARENB;
2280 /* Linux defines mark/space (stick) parity */
2282 port.c_cflag |= (PARENB | CMSPAR);
2285 port.c_cflag |= (PARENB | PARODD | CMSPAR);
2288 /* try the POSIX way */
2290 if( stopbits == ONESTOPBIT) {
2291 stopbits = TWOSTOPBITS;
2292 port.c_iflag &= ~INPCK;
2294 commerror = IE_BYTESIZE;
2296 ERR("Cannot set MARK Parity\n");
2303 port.c_iflag &= ~INPCK;
2305 commerror = IE_BYTESIZE;
2307 ERR("Cannot set SPACE Parity\n");
2313 commerror = IE_BYTESIZE;
2320 port.c_cflag &= ~CSIZE;
2323 port.c_cflag |= CS5;
2326 port.c_cflag |= CS6;
2329 port.c_cflag |= CS7;
2332 port.c_cflag |= CS8;
2335 commerror = IE_BYTESIZE;
2343 port.c_cflag &= ~CSTOPB;
2345 case ONE5STOPBITS: /* wil be selected if bytesize is 5 */
2347 port.c_cflag |= CSTOPB;
2350 commerror = IE_BYTESIZE;
2356 if ( lpdcb->fOutxCtsFlow ||
2357 lpdcb->fDtrControl == DTR_CONTROL_ENABLE||
2358 lpdcb->fRtsControl == RTS_CONTROL_ENABLE
2361 port.c_cflag |= CRTSCTS;
2365 if (lpdcb->fDtrControl == DTR_CONTROL_DISABLE)
2367 port.c_cflag &= ~CRTSCTS;
2368 TRACE("~CRTSCTS\n");
2373 port.c_iflag |= IXON;
2375 port.c_iflag &= ~IXON;
2377 port.c_iflag |= IXOFF;
2379 port.c_iflag &= ~IXOFF;
2381 if (tcsetattr(fd,TCSANOW,&port)==-1) { /* otherwise it hangs with pending input*/
2382 int save_error=errno;
2383 commerror = WinError();
2385 ERR("tcsetattr error '%s'\n", strerror(save_error));
2395 /*****************************************************************************
2396 * GetCommState (KERNEL32.287)
2398 * Fills in a device control block with information from a communications device.
2402 * True on success, false if the communication device handle is bad etc
2406 * XonChar and XoffChar are not set.
2408 BOOL WINAPI GetCommState(
2409 HANDLE handle, /* [in] The communications device. */
2410 LPDCB lpdcb) /* [out] The device control block. */
2412 struct termios port;
2415 TRACE("handle %d, ptr %p\n", handle, lpdcb);
2417 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
2420 ERR("FILE_GetUnixHandle failed\n");
2423 if (tcgetattr(fd, &port) == -1) {
2424 int save_error=errno;
2425 ERR("tcgetattr error '%s'\n", strerror(save_error));
2426 commerror = WinError();
2433 speed= (port.c_cflag & CBAUD);
2435 speed= (cfgetospeed(&port));
2439 lpdcb->BaudRate = 110;
2442 lpdcb->BaudRate = 300;
2445 lpdcb->BaudRate = 600;
2448 lpdcb->BaudRate = 1200;
2451 lpdcb->BaudRate = 2400;
2454 lpdcb->BaudRate = 4800;
2457 lpdcb->BaudRate = 9600;
2460 lpdcb->BaudRate = 19200;
2463 lpdcb->BaudRate = 38400;
2467 lpdcb->BaudRate = 57600;
2472 lpdcb->BaudRate = 115200;
2477 lpdcb->BaudRate = 230400;
2482 lpdcb->BaudRate = 460800;
2486 ERR("unknown speed %x \n",speed);
2489 switch (port.c_cflag & CSIZE) {
2491 lpdcb->ByteSize = 5;
2494 lpdcb->ByteSize = 6;
2497 lpdcb->ByteSize = 7;
2500 lpdcb->ByteSize = 8;
2503 ERR("unknown size %x \n",port.c_cflag & CSIZE);
2506 if(port.c_iflag & INPCK)
2507 lpdcb->fParity = TRUE;
2509 lpdcb->fParity = FALSE;
2511 switch (port.c_cflag & (PARENB | PARODD | CMSPAR))
2513 switch (port.c_cflag & (PARENB | PARODD))
2517 lpdcb->Parity = NOPARITY;
2520 lpdcb->Parity = EVENPARITY;
2522 case (PARENB | PARODD):
2523 lpdcb->Parity = ODDPARITY;
2526 case (PARENB | CMSPAR):
2527 lpdcb->Parity = MARKPARITY;
2529 case (PARENB | PARODD | CMSPAR):
2530 lpdcb->Parity = SPACEPARITY;
2535 if (port.c_cflag & CSTOPB)
2536 if(lpdcb->ByteSize == 5)
2537 lpdcb->StopBits = ONE5STOPBITS;
2539 lpdcb->StopBits = TWOSTOPBITS;
2541 lpdcb->StopBits = ONESTOPBIT;
2548 if (port.c_cflag & CRTSCTS) {
2549 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
2550 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
2551 lpdcb->fOutxCtsFlow = 1;
2552 lpdcb->fOutxDsrFlow = 1;
2556 lpdcb->fDtrControl = DTR_CONTROL_DISABLE;
2557 lpdcb->fRtsControl = RTS_CONTROL_DISABLE;
2559 if (port.c_iflag & IXON)
2564 if (port.c_iflag & IXOFF)
2573 lpdcb->XoffLim = 10;
2579 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
2580 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
2581 (lpdcb->StopBits == ONESTOPBIT)?1:
2582 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
2583 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
2584 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
2586 if ( lpdcb->fOutxCtsFlow ||
2587 lpdcb->fDtrControl == DTR_CONTROL_ENABLE||
2588 lpdcb->fRtsControl == RTS_CONTROL_ENABLE
2592 if (lpdcb->fDtrControl == DTR_CONTROL_DISABLE)
2593 TRACE("~CRTSCTS\n");
2599 /*****************************************************************************
2600 * TransmitCommChar (KERNEL32.697)
2602 * Transmits a single character in front of any pending characters in the
2603 * output buffer. Usually used to send an interrupt character to a host.
2607 * True if the call succeeded, false if the previous command character to the
2608 * same device has not been sent yet the handle is bad etc.
2614 BOOL WINAPI TransmitCommChar(
2615 HANDLE hComm, /* [in] The communication device in need of a command character. */
2616 CHAR chTransmit) /* [in] The character to transmit. */
2618 FIXME("(%x,'%c'), use win32 handle!\n",hComm,chTransmit);
2622 /*****************************************************************************
2623 * GetCommTimeouts (KERNEL32.288)
2625 * Obtains the request time out values for the communications device.
2629 * True on success, false if communications device handle is bad
2630 * or the target structure is null.
2632 BOOL WINAPI GetCommTimeouts(
2633 HANDLE hComm, /* [in] The communications device. */
2634 LPCOMMTIMEOUTS lptimeouts) /* [out] The struct of request time outs. */
2638 TRACE("(%x,%p)\n",hComm,lptimeouts);
2642 SetLastError(ERROR_INVALID_PARAMETER);
2648 struct get_serial_info_request *req = server_alloc_req( sizeof(*req), 0 );
2649 req->handle = hComm;
2650 if ((ret = !server_call( REQ_GET_SERIAL_INFO )))
2652 lptimeouts->ReadIntervalTimeout = req->readinterval;
2653 lptimeouts->ReadTotalTimeoutMultiplier = req->readmult;
2654 lptimeouts->ReadTotalTimeoutConstant = req->readconst;
2655 lptimeouts->WriteTotalTimeoutMultiplier = req->writemult;
2656 lptimeouts->WriteTotalTimeoutConstant = req->writeconst;
2663 /*****************************************************************************
2664 * SetCommTimeouts (KERNEL32.620)
2666 * Sets the timeouts used when reading and writing data to/from COMM ports.
2668 * ReadIntervalTimeout
2669 * - converted and passes to linux kernel as c_cc[VTIME]
2670 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
2671 * - used in ReadFile to calculate GetOverlappedResult's timeout
2672 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
2673 * - used in WriteFile to calculate GetOverlappedResult's timeout
2677 * True if the time outs were set, false otherwise.
2679 BOOL WINAPI SetCommTimeouts(
2680 HANDLE hComm, /* [in] handle of COMM device */
2681 LPCOMMTIMEOUTS lptimeouts) /* [in] pointer to COMMTIMEOUTS structure */
2685 struct termios tios;
2687 TRACE("(%x,%p)\n",hComm,lptimeouts);
2691 SetLastError(ERROR_INVALID_PARAMETER);
2697 struct set_serial_info_request *req = server_alloc_req( sizeof(*req), 0 );
2698 req->handle = hComm;
2699 req->flags = SERIALINFO_SET_TIMEOUTS;
2700 req->readinterval = lptimeouts->ReadIntervalTimeout ;
2701 req->readmult = lptimeouts->ReadTotalTimeoutMultiplier ;
2702 req->readconst = lptimeouts->ReadTotalTimeoutConstant ;
2703 req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ;
2704 req->writeconst = lptimeouts->WriteTotalTimeoutConstant ;
2705 ret = !server_call( REQ_SET_SERIAL_INFO );
2708 if (!ret) return FALSE;
2710 /* FIXME: move this stuff to the server */
2711 fd = FILE_GetUnixHandle( hComm, GENERIC_READ );
2713 FIXME("no fd for handle = %0x!.\n",hComm);
2717 if (-1==tcgetattr(fd,&tios)) {
2718 FIXME("tcgetattr on fd %d failed!\n",fd);
2721 /* VTIME is in 1/10 seconds */
2722 tios.c_cc[VTIME]= (lptimeouts->ReadIntervalTimeout+99)/100;
2723 if (-1==tcsetattr(fd,0,&tios)) {
2724 FIXME("tcsetattr on fd %d failed!\n",fd);
2731 /***********************************************************************
2732 * GetCommModemStatus (KERNEL32.285)
2734 * Obtains the four control register bits if supported by the hardware.
2738 * True if the communications handle was good and for hardware that
2739 * control register access, false otherwise.
2741 BOOL WINAPI GetCommModemStatus(
2742 HANDLE hFile, /* [in] The communications device. */
2743 LPDWORD lpModemStat) /* [out] The control register bits. */
2745 int fd,mstat, result=FALSE;
2749 fd = FILE_GetUnixHandle( hFile, GENERIC_READ );
2752 result = ioctl(fd, TIOCMGET, &mstat);
2756 WARN("ioctl failed\n");
2760 if (mstat & TIOCM_CTS)
2761 *lpModemStat |= MS_CTS_ON;
2764 if (mstat & TIOCM_DSR)
2765 *lpModemStat |= MS_DSR_ON;
2768 if (mstat & TIOCM_RNG)
2769 *lpModemStat |= MS_RING_ON;
2772 /*FIXME: Not really sure about RLSD UB 990810*/
2773 if (mstat & TIOCM_CAR)
2774 *lpModemStat |= MS_RLSD_ON;
2776 TRACE("%04x -> %s%s%s%s\n", mstat,
2777 (*lpModemStat &MS_RLSD_ON)?"MS_RLSD_ON ":"",
2778 (*lpModemStat &MS_RING_ON)?"MS_RING_ON ":"",
2779 (*lpModemStat &MS_DSR_ON)?"MS_DSR_ON ":"",
2780 (*lpModemStat &MS_CTS_ON)?"MS_CTS_ON ":"");
2787 VOID COMM_WaitCommEventService(void **args)
2789 LPOVERLAPPED lpOverlapped = (LPOVERLAPPED)args[0];
2790 LPDWORD buffer = (LPDWORD)args[1];
2791 DWORD events = (DWORD)args[2];
2793 TRACE("overlapped %p wait complete %p <- %lx\n",lpOverlapped,buffer,events);
2797 lpOverlapped->Internal = STATUS_SUCCESS;
2798 SetEvent( lpOverlapped->hEvent);
2799 CloseHandle(lpOverlapped->InternalHigh);
2802 /***********************************************************************
2803 * WaitCommEvent (KERNEL32.719)
2805 * Wait until something interesting happens on a COMM port.
2806 * Interesting things (events) are set by calling SetCommMask before
2807 * this function is called.
2810 * TRUE if successful
2813 * The set of detected events will be written to *lpdwEventMask
2814 * ERROR_IO_PENDING will be returned the overlapped structure was passed
2817 * Only supports EV_RXCHAR and EV_TXEMPTY
2819 BOOL WINAPI WaitCommEvent(
2820 HANDLE hFile, /* [in] handle of comm port to wait for */
2821 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
2822 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
2828 TRACE("(%x %p %p )\n",hFile, lpdwEvents,lpOverlapped);
2830 /* if there is no overlapped structure, create our own */
2833 ov.hEvent = CreateEventA(NULL,FALSE,FALSE,NULL);
2837 lpov = lpOverlapped;
2839 /* check that the overlapped structure has a valid event flag */
2840 if ( (lpov->hEvent==0) || (lpov->hEvent == INVALID_HANDLE_VALUE) )
2842 ERR("Couldn't create Event flag for Overlapped structure\n");
2843 SetLastError(ERROR_INVALID_PARAMETER);
2847 ResetEvent(lpov->hEvent);
2849 lpov->Internal = STATUS_PENDING;
2850 lpov->InternalHigh = 0;
2852 lpov->OffsetHigh = 0;
2854 /* start an ASYNCHRONOUS WaitCommEvent */
2857 struct create_async_request *req = server_alloc_req( sizeof(*req), 0 );
2859 req->file_handle = hFile;
2860 req->overlapped = lpov;
2861 req->buffer = lpdwEvents;
2863 req->func = COMM_WaitCommEventService;
2864 req->type = ASYNC_TYPE_WAIT;
2866 ret=server_call( REQ_CREATE_ASYNC );
2868 lpov->InternalHigh = req->ov_handle;
2875 CloseHandle(lpov->hEvent);
2876 TRACE("server call failed.\n");
2880 /* activate the overlapped operation */
2881 lpov->Internal = STATUS_PENDING;
2883 /* wait ourselves if the caller didn't give us an overlapped struct */
2886 GetOverlappedResult(hFile, lpov, NULL, TRUE);
2887 CloseHandle(lpov->hEvent);
2892 /* caller wants overlapped I/O using GetOverlapped result */
2893 SetLastError(ERROR_IO_PENDING);
2900 /***********************************************************************
2901 * GetCommProperties (KERNEL32.286)
2903 * This function fills in a structure with the capabilities of the
2904 * communications port driver.
2908 * TRUE on success, FALSE on failure
2909 * If successful, the lpCommProp structure be filled in with
2910 * properties of the comm port.
2912 BOOL WINAPI GetCommProperties(
2913 HANDLE hFile, /* [in] handle of the comm port */
2914 LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */
2916 FIXME("(%d %p )\n",hFile,lpCommProp);
2921 * These values should be valid for LINUX's serial driver
2922 * FIXME: Perhaps they deserve an #ifdef LINUX
2924 memset(lpCommProp,0,sizeof(COMMPROP));
2925 lpCommProp->wPacketLength = 1;
2926 lpCommProp->wPacketVersion = 1;
2927 lpCommProp->dwServiceMask = SP_SERIALCOMM;
2928 lpCommProp->dwReserved1 = 0;
2929 lpCommProp->dwMaxTxQueue = 4096;
2930 lpCommProp->dwMaxRxQueue = 4096;
2931 lpCommProp->dwMaxBaud = BAUD_115200;
2932 lpCommProp->dwProvSubType = PST_RS232;
2933 lpCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS ;
2934 lpCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING |
2935 SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ;
2936 lpCommProp->dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 |
2937 BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
2938 BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ;
2939 lpCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ;
2940 lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
2941 PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE;
2942 lpCommProp->dwCurrentTxQueue = lpCommProp->dwMaxTxQueue;
2943 lpCommProp->dwCurrentRxQueue = lpCommProp->dwMaxRxQueue;
2948 /***********************************************************************
2950 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
2951 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
2952 * This is dependent on the type of COMM port, but since it is doubtful
2953 * anybody will get around to implementing support for fancy serial
2954 * ports in WINE, this is hardcoded for the time being. The name of
2955 * this DLL should be stored in and read from the system registry in
2956 * the hive HKEY_LOCAL_MACHINE, key
2957 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
2958 * where ???? is the port number... that is determined by PNP
2959 * The DLL should be loaded when the COMM port is opened, and closed
2960 * when the COMM port is closed. - MJM 20 June 2000
2961 ***********************************************************************/
2962 static CHAR lpszSerialUI[] = "serialui.dll";
2965 /***********************************************************************
2966 * CommConfigDialogA (KERNEL32.140)
2968 * Raises a dialog that allows the user to configure a comm port.
2969 * Fills the COMMCONFIG struct with information specified by the user.
2970 * This function should call a similar routine in the COMM driver...
2974 * TRUE on success, FALSE on failure
2975 * If successful, the lpCommConfig structure will contain a new
2976 * configuration for the comm port, as specified by the user.
2979 * The library with the CommConfigDialog code is never unloaded.
2980 * Perhaps this should be done when the comm port is closed?
2982 BOOL WINAPI CommConfigDialogA(
2983 LPCSTR lpszDevice, /* [in] name of communications device */
2984 HANDLE hWnd, /* [in] parent window for the dialog */
2985 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
2987 FARPROC lpfnCommDialog;
2988 HMODULE hConfigModule;
2991 TRACE("(%p %x %p)\n",lpszDevice, hWnd, lpCommConfig);
2993 hConfigModule = LoadLibraryA(lpszSerialUI);
2997 lpfnCommDialog = GetProcAddress(hConfigModule, (LPCSTR)3L);
3002 r = lpfnCommDialog(lpszDevice,hWnd,lpCommConfig);
3004 /* UnloadLibrary(hConfigModule); */
3009 /***********************************************************************
3010 * CommConfigDialogW (KERNEL32.141)
3012 * see CommConfigDialogA for more info
3014 BOOL WINAPI CommConfigDialogW(
3015 LPCWSTR lpszDevice, /* [in] name of communications device */
3016 HANDLE hWnd, /* [in] parent window for the dialog */
3017 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
3022 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
3025 r = CommConfigDialogA(lpDeviceA,hWnd,lpCommConfig);
3026 HeapFree( GetProcessHeap(), 0, lpDeviceA );
3030 /***********************************************************************
3031 * GetCommConfig (KERNEL32.283)
3033 * Fill in the COMMCONFIG structure for the comm port hFile
3037 * TRUE on success, FALSE on failure
3038 * If successful, lpCommConfig contains the comm port configuration.
3042 * The signature is missing a the parameter for the size of the COMMCONFIG
3043 * structure/buffer it should be
3044 * BOOL WINAPI GetCommConfig(HANDLE hFile,LPCOMMCONFIG lpCommConfig,LPDWORD lpdwSize)
3046 BOOL WINAPI GetCommConfig(
3047 HANDLE hFile, /* [in] The communications device. */
3048 LPCOMMCONFIG lpCommConfig) /* [out] The communications configuration of the device (if it fits). */
3049 #if 0 /* FIXME: Why is this "commented" out? */
3050 LPDWORD lpdwSize) /* [in/out] Initially the size of the configuration buffer/structure,
3051 afterwards the number of bytes copied to the buffer or
3052 the needed size of the buffer. */
3057 TRACE("(%x %p)\n",hFile,lpCommConfig);
3059 if(lpCommConfig == NULL)
3062 lpCommConfig->dwSize = sizeof(COMMCONFIG);
3063 lpCommConfig->wVersion = 1;
3064 lpCommConfig->wReserved = 0;
3065 r = GetCommState(hFile,&lpCommConfig->dcb);
3066 lpCommConfig->dwProviderSubType = PST_RS232;
3067 lpCommConfig->dwProviderOffset = 0;
3068 lpCommConfig->dwProviderSize = 0;
3073 /***********************************************************************
3074 * SetCommConfig (KERNEL32.617)
3076 * Sets the configuration of the commications device.
3080 * True on success, false if the handle was bad is not a communications device.
3082 BOOL WINAPI SetCommConfig(
3083 HANDLE hFile, /* [in] The communications device. */
3084 LPCOMMCONFIG lpCommConfig) /* [in] The desired configuration. */
3086 TRACE("(%x %p)\n",hFile,lpCommConfig);
3087 return SetCommState(hFile,&lpCommConfig->dcb);
3090 /***********************************************************************
3091 * SetDefaultCommConfigA (KERNEL32.638)
3093 * Initializes the default configuration for the specified communication
3098 * True if the device was found and the defaults set, false otherwise
3100 BOOL WINAPI SetDefaultCommConfigA(
3101 LPCSTR lpszDevice, /* [in] The ascii name of the device targeted for configuration. */
3102 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
3103 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
3105 FARPROC lpfnSetDefaultCommConfig;
3106 HMODULE hConfigModule;
3109 TRACE("(%p %p %lx)\n",lpszDevice, lpCommConfig, dwSize);
3111 hConfigModule = LoadLibraryA(lpszSerialUI);
3115 lpfnSetDefaultCommConfig = GetProcAddress(hConfigModule, (LPCSTR)4L);
3117 if(! lpfnSetDefaultCommConfig)
3120 r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize);
3122 /* UnloadLibrary(hConfigModule); */
3128 /***********************************************************************
3129 * SetDefaultCommConfigW (KERNEL32.639)
3131 * Initializes the default configuration for the specified
3132 * communication device. (unicode)
3137 BOOL WINAPI SetDefaultCommConfigW(
3138 LPCWSTR lpszDevice, /* [in] The unicode name of the device targeted for configuration. */
3139 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
3140 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
3145 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice),lpCommConfig,dwSize);
3147 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
3150 r = SetDefaultCommConfigA(lpDeviceA,lpCommConfig,dwSize);
3151 HeapFree( GetProcessHeap(), 0, lpDeviceA );
3156 /***********************************************************************
3157 * GetDefaultCommConfigA (KERNEL32.313)
3159 * Acquires the default configuration of the specified communication device. (unicode)
3163 * True on successful reading of the default configuration,
3164 * if the device is not found or the buffer is too small.
3166 BOOL WINAPI GetDefaultCommConfigA(
3167 LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */
3168 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
3169 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
3170 afterwards the number of bytes copied to the buffer or
3171 the needed size of the buffer. */
3173 LPDCB lpdcb = &(lpCC->dcb);
3176 if (strncasecmp(lpszName,"COM",3)) {
3177 ERR("not implemented for <%s>\n", lpszName);
3181 if (!ValidCOMPort(lpszName[3]-'1'))
3184 TRACE("(%s %p %ld)\n", lpszName, lpCC, *lpdwSize );
3185 if (*lpdwSize < sizeof(COMMCONFIG)) {
3186 *lpdwSize = sizeof(COMMCONFIG);
3190 *lpdwSize = sizeof(COMMCONFIG);
3192 lpCC->dwSize = sizeof(COMMCONFIG);
3194 lpCC->dwProviderSubType = PST_RS232;
3195 lpCC->dwProviderOffset = 0L;
3196 lpCC->dwProviderSize = 0L;
3198 (void) sprintf( temp, "COM%c:38400,n,8,1", lpszName[3]);
3199 FIXME("setting %s as default\n", temp);
3201 return BuildCommDCBA( temp, lpdcb);
3204 /**************************************************************************
3205 * GetDefaultCommConfigW (KERNEL32.314)
3207 * Acquires the default configuration of the specified communication device. (unicode)
3211 * True on successful reading of the default configuration,
3212 * if the device is not found or the buffer is too small.
3214 BOOL WINAPI GetDefaultCommConfigW(
3215 LPCWSTR lpszName, /* [in] The unicode name of the device targeted for configuration. */
3216 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
3217 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
3218 afterwards the number of bytes copied to the buffer or
3219 the needed size of the buffer. */
3224 TRACE("(%p,%p,%ld)\n",lpszName,lpCC,*lpdwSize);
3225 lpszNameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName );
3228 ret=GetDefaultCommConfigA(lpszNameA,lpCC,lpdwSize);
3229 HeapFree( GetProcessHeap(), 0, lpszNameA );