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>
56 #ifdef HAVE_SYS_MODEM_H
57 # include <sys/modem.h>
59 #ifdef HAVE_SYS_STRTIO_H
60 # include <sys/strtio.h>
71 #include "debugtools.h"
73 DEFAULT_DEBUG_CHANNEL(comm
);
76 #define TIOCINQ FIONREAD
79 /* window's semi documented modem status register */
80 #define COMM_MSR_OFFSET 35
85 #define MSR_MASK (MSR_CTS|MSR_DSR|MSR_RI|MSR_RLSD)
90 #define CMSPAR 0x40000000 /* stick parity */
93 struct DosDeviceStruct COM
[MAX_PORTS
];
94 struct DosDeviceStruct LPT
[MAX_PORTS
];
95 /* pointers to unknown(==undocumented) comm structure */
96 LPCVOID
*unknown
[MAX_PORTS
];
97 /* save terminal states */
98 static struct termios m_stat
[MAX_PORTS
];
100 /* update window's semi documented modem status register */
101 /* see knowledge base Q101417 */
102 static void COMM_MSRUpdate( UCHAR
* pMsr
, unsigned int mstat
)
105 if(mstat
& TIOCM_CTS
) tmpmsr
|= MSR_CTS
;
106 if(mstat
& TIOCM_DSR
) tmpmsr
|= MSR_DSR
;
107 if(mstat
& TIOCM_RI
) tmpmsr
|= MSR_RI
;
108 if(mstat
& TIOCM_CAR
) tmpmsr
|= MSR_RLSD
;
109 *pMsr
= (*pMsr
& ~MSR_MASK
) | tmpmsr
;
115 char option
[10], temp
[256], *btemp
;
118 for (x
=0; x
!=MAX_PORTS
; x
++) {
119 strcpy(option
,"COMx");
123 PROFILE_GetWineIniString( "serialports", option
, "*",
124 temp
, sizeof(temp
) );
125 if (!strcmp(temp
, "*") || *temp
== '\0')
126 COM
[x
].devicename
= NULL
;
128 btemp
= strchr(temp
,',');
131 COM
[x
].baudrate
= atoi(btemp
);
133 COM
[x
].baudrate
= -1;
136 if (!S_ISCHR(st
.st_mode
))
137 WARN("Can't use `%s' as %s !\n", temp
, option
);
139 if ((COM
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
140 WARN("Can't malloc for device info!\n");
143 strcpy(COM
[x
].devicename
, temp
);
145 TRACE("%s = %s\n", option
, COM
[x
].devicename
);
148 strcpy(option
, "LPTx");
152 PROFILE_GetWineIniString( "parallelports", option
, "*",
153 temp
, sizeof(temp
) );
154 if (!strcmp(temp
, "*") || *temp
== '\0')
155 LPT
[x
].devicename
= NULL
;
158 if (!S_ISCHR(st
.st_mode
))
159 WARN("Can't use `%s' as %s !\n", temp
, option
);
161 if ((LPT
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
162 WARN("Can't malloc for device info!\n");
165 strcpy(LPT
[x
].devicename
, temp
);
167 TRACE("%s = %s\n", option
, LPT
[x
].devicename
);
174 static struct DosDeviceStruct
*GetDeviceStruct(int fd
)
176 if ((fd
&0x7F)<=MAX_PORTS
) {
177 if (!(fd
&FLAG_LPT
)) {
190 static int GetCommPort_fd(int fd
)
194 for (x
=0; x
<MAX_PORTS
; x
++) {
202 static int ValidCOMPort(int x
)
204 return(x
< MAX_PORTS
? (int) COM
[x
].devicename
: 0);
207 static int ValidLPTPort(int x
)
209 return(x
< MAX_PORTS
? (int) LPT
[x
].devicename
: 0);
212 static int WinError(void)
214 TRACE("errno = %d\n", errno
);
221 static unsigned comm_inbuf(struct DosDeviceStruct
*ptr
)
223 return ((ptr
->ibuf_tail
> ptr
->ibuf_head
) ? ptr
->ibuf_size
: 0)
224 + ptr
->ibuf_head
- ptr
->ibuf_tail
;
227 static unsigned comm_outbuf(struct DosDeviceStruct
*ptr
)
229 return ((ptr
->obuf_tail
> ptr
->obuf_head
) ? ptr
->obuf_size
: 0)
230 + ptr
->obuf_head
- ptr
->obuf_tail
;
233 static int COMM_WhackModem(int fd
, unsigned int andy
, unsigned int orrie
)
235 unsigned int mstat
, okay
;
236 okay
= ioctl(fd
, TIOCMGET
, &mstat
);
237 if (okay
) return okay
;
238 if (andy
) mstat
&= andy
;
240 return ioctl(fd
, TIOCMSET
, &mstat
);
243 static void CALLBACK
comm_notification( ULONG_PTR
private )
245 struct DosDeviceStruct
*ptr
= (struct DosDeviceStruct
*)private;
246 int prev
, bleft
, len
;
248 int cid
= GetCommPort_fd(ptr
->fd
);
250 TRACE("async notification\n");
251 /* read data from comm port */
252 prev
= comm_inbuf(ptr
);
254 bleft
= ((ptr
->ibuf_tail
> ptr
->ibuf_head
) ? (ptr
->ibuf_tail
-1) : ptr
->ibuf_size
)
256 len
= read(ptr
->fd
, ptr
->inbuf
+ ptr
->ibuf_head
, bleft
?bleft
:1);
259 ptr
->commerror
= CE_RXOVER
;
261 /* check for events */
262 if ((ptr
->eventmask
& EV_RXFLAG
) &&
263 memchr(ptr
->inbuf
+ ptr
->ibuf_head
, ptr
->evtchar
, len
)) {
264 *(WORD
*)(unknown
[cid
]) |= EV_RXFLAG
;
267 if (ptr
->eventmask
& EV_RXCHAR
) {
268 *(WORD
*)(unknown
[cid
]) |= EV_RXCHAR
;
271 /* advance buffer position */
272 ptr
->ibuf_head
+= len
;
273 if (ptr
->ibuf_head
>= ptr
->ibuf_size
)
278 /* check for notification */
279 if (ptr
->wnd
&& (ptr
->n_read
>0) && (prev
<ptr
->n_read
) &&
280 (comm_inbuf(ptr
)>=ptr
->n_read
)) {
281 /* passed the receive notification threshold */
285 /* write any TransmitCommChar character */
287 len
= write(ptr
->fd
, &(ptr
->xmit
), 1);
288 if (len
> 0) ptr
->xmit
= -1;
290 /* write from output queue */
291 prev
= comm_outbuf(ptr
);
293 bleft
= ((ptr
->obuf_tail
<= ptr
->obuf_head
) ? ptr
->obuf_head
: ptr
->obuf_size
)
295 len
= bleft
? write(ptr
->fd
, ptr
->outbuf
+ ptr
->obuf_tail
, bleft
) : 0;
297 ptr
->obuf_tail
+= len
;
298 if (ptr
->obuf_tail
>= ptr
->obuf_size
)
301 if (ptr
->obuf_tail
== ptr
->obuf_head
) {
303 SERVICE_Delete( ptr
->s_write
);
304 ptr
->s_write
= INVALID_HANDLE_VALUE
;
306 if (ptr
->eventmask
& EV_TXEMPTY
) {
307 *(WORD
*)(unknown
[cid
]) |= EV_TXEMPTY
;
313 /* check for notification */
314 if (ptr
->wnd
&& (ptr
->n_write
>0) && (prev
>=ptr
->n_write
) &&
315 (comm_outbuf(ptr
)<ptr
->n_write
)) {
316 /* passed the transmit notification threshold */
320 /* send notifications, if any */
321 if (ptr
->wnd
&& mask
) {
322 TRACE("notifying %04x: cid=%d, mask=%02x\n", ptr
->wnd
, cid
, mask
);
323 Callout
.PostMessageA(ptr
->wnd
, WM_COMMNOTIFY
, cid
, mask
);
327 static void comm_waitread(struct DosDeviceStruct
*ptr
)
329 if (ptr
->s_read
!= INVALID_HANDLE_VALUE
) return;
330 ptr
->s_read
= SERVICE_AddObject( FILE_DupUnixHandle( ptr
->fd
,
331 GENERIC_READ
| SYNCHRONIZE
),
336 static void comm_waitwrite(struct DosDeviceStruct
*ptr
)
338 if (ptr
->s_write
!= INVALID_HANDLE_VALUE
) return;
339 ptr
->s_write
= SERVICE_AddObject( FILE_DupUnixHandle( ptr
->fd
,
340 GENERIC_WRITE
| SYNCHRONIZE
),
345 /**************************************************************************
346 * BuildCommDCB (USER.213)
348 * According to the ECMA-234 (368.3) the function will return FALSE on
349 * success, otherwise it will return -1.
350 * IF THIS IS NOT CORRECT THE RETURNVALUE CHECK IN BuildCommDCBAndTimeoutsA
353 BOOL16 WINAPI
BuildCommDCB16(LPCSTR device
, LPDCB16 lpdcb
)
355 /* "COM1:9600,n,8,1" */
358 char *ptr
, temp
[256];
360 TRACE("(%s), ptr %p\n", device
, lpdcb
);
362 if (!lstrncmpiA(device
,"COM",3)) {
363 port
= device
[3] - '0';
367 ERR("BUG ! COM0 can't exist!.\n");
371 if (!ValidCOMPort(port
)) {
372 FIXME("invalid COM port %d?\n",port
);
376 memset(lpdcb
, 0, sizeof(DCB16
)); /* initialize */
383 if (*(device
+4) != ':')
386 strcpy(temp
,device
+5);
387 ptr
= strtok(temp
, ", ");
389 if (COM
[port
].baudrate
> 0)
390 lpdcb
->BaudRate
= COM
[port
].baudrate
;
392 lpdcb
->BaudRate
= atoi(ptr
);
393 TRACE("baudrate (%d)\n", lpdcb
->BaudRate
);
395 ptr
= strtok(NULL
, ", ");
397 *ptr
= toupper(*ptr
);
399 TRACE("parity (%c)\n", *ptr
);
400 lpdcb
->fParity
= TRUE
;
403 lpdcb
->Parity
= NOPARITY
;
404 lpdcb
->fParity
= FALSE
;
407 lpdcb
->Parity
= EVENPARITY
;
410 lpdcb
->Parity
= MARKPARITY
;
413 lpdcb
->Parity
= ODDPARITY
;
416 WARN("Unknown parity `%c'!\n", *ptr
);
420 ptr
= strtok(NULL
, ", ");
421 TRACE("charsize (%c)\n", *ptr
);
422 lpdcb
->ByteSize
= *ptr
- '0';
424 ptr
= strtok(NULL
, ", ");
425 TRACE("stopbits (%c)\n", *ptr
);
428 lpdcb
->StopBits
= ONESTOPBIT
;
431 lpdcb
->StopBits
= TWOSTOPBITS
;
434 WARN("Unknown # of stopbits `%c'!\n", *ptr
);
442 /*****************************************************************************
443 * OpenComm (USER.200)
445 INT16 WINAPI
OpenComm16(LPCSTR device
,UINT16 cbInQueue
,UINT16 cbOutQueue
)
449 TRACE("%s, %d, %d\n", device
, cbInQueue
, cbOutQueue
);
451 if (strlen(device
) < 4)
454 port
= device
[3] - '0';
457 ERR("BUG ! COM0 or LPT0 don't exist !\n");
459 if (!lstrncmpiA(device
,"COM",3)) {
461 TRACE("%s = %s\n", device
, COM
[port
].devicename
);
463 if (!ValidCOMPort(port
))
469 fd
= open(COM
[port
].devicename
, O_RDWR
| O_NONBLOCK
);
471 ERR("error=%d\n", errno
);
474 unknown
[port
] = SEGPTR_ALLOC(40);
475 bzero(unknown
[port
],40);
477 COM
[port
].commerror
= 0;
478 COM
[port
].eventmask
= 0;
479 COM
[port
].evtchar
= 0; /* FIXME: default? */
480 /* save terminal state */
481 tcgetattr(fd
,&m_stat
[port
]);
482 /* set default parameters */
483 if(COM
[port
].baudrate
>-1){
485 GetCommState16(port
, &dcb
);
486 dcb
.BaudRate
=COM
[port
].baudrate
;
488 * databits, parity, stopbits
490 SetCommState16( &dcb
);
492 /* init priority characters */
493 COM
[port
].unget
= -1;
495 /* allocate buffers */
496 COM
[port
].ibuf_size
= cbInQueue
;
497 COM
[port
].ibuf_head
= COM
[port
].ibuf_tail
= 0;
498 COM
[port
].obuf_size
= cbOutQueue
;
499 COM
[port
].obuf_head
= COM
[port
].obuf_tail
= 0;
501 COM
[port
].inbuf
= malloc(cbInQueue
);
502 if (COM
[port
].inbuf
) {
503 COM
[port
].outbuf
= malloc(cbOutQueue
);
504 if (!COM
[port
].outbuf
)
505 free(COM
[port
].inbuf
);
506 } else COM
[port
].outbuf
= NULL
;
507 if (!COM
[port
].outbuf
) {
508 /* not enough memory */
509 tcsetattr(COM
[port
].fd
,TCSANOW
,&m_stat
[port
]);
511 ERR("out of memory");
515 COM
[port
].s_read
= INVALID_HANDLE_VALUE
;
516 COM
[port
].s_write
= INVALID_HANDLE_VALUE
;
517 comm_waitread( &COM
[port
] );
522 if (!lstrncmpiA(device
,"LPT",3)) {
524 if (!ValidLPTPort(port
))
530 fd
= open(LPT
[port
].devicename
, O_RDWR
| O_NONBLOCK
, 0);
535 LPT
[port
].commerror
= 0;
536 LPT
[port
].eventmask
= 0;
537 return port
|FLAG_LPT
;
543 /*****************************************************************************
544 * CloseComm (USER.207)
546 INT16 WINAPI
CloseComm16(INT16 cid
)
548 struct DosDeviceStruct
*ptr
;
550 TRACE("cid=%d\n", cid
);
551 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
552 FIXME("no cid=%d found!\n", cid
);
555 if (!(cid
&FLAG_LPT
)) {
557 SEGPTR_FREE(unknown
[cid
]); /* [LW] */
559 SERVICE_Delete( COM
[cid
].s_write
);
560 SERVICE_Delete( COM
[cid
].s_read
);
565 /* reset modem lines */
566 tcsetattr(ptr
->fd
,TCSANOW
,&m_stat
[cid
]);
569 if (close(ptr
->fd
) == -1) {
570 ptr
->commerror
= WinError();
571 /* FIXME: should we clear ptr->fd here? */
580 /*****************************************************************************
581 * SetCommBreak (USER.210)
583 INT16 WINAPI
SetCommBreak16(INT16 cid
)
585 struct DosDeviceStruct
*ptr
;
587 TRACE("cid=%d\n", cid
);
588 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
589 FIXME("no cid=%d found!\n", cid
);
598 /*****************************************************************************
599 * ClearCommBreak (USER.211)
601 INT16 WINAPI
ClearCommBreak16(INT16 cid
)
603 struct DosDeviceStruct
*ptr
;
605 TRACE("cid=%d\n", cid
);
606 if (!(ptr
= GetDeviceStruct(cid
))) {
607 FIXME("no cid=%d found!\n", cid
);
615 /*****************************************************************************
616 * EscapeCommFunction (USER.214)
618 LONG WINAPI
EscapeCommFunction16(UINT16 cid
,UINT16 nFunction
)
621 struct DosDeviceStruct
*ptr
;
624 TRACE("cid=%d, function=%d\n", cid
, nFunction
);
625 if ((nFunction
!= GETMAXCOM
) && (nFunction
!= GETMAXLPT
)) {
626 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
627 FIXME("no cid=%d found!\n", cid
);
630 if (tcgetattr(ptr
->fd
,&port
) == -1) {
631 TRACE("tcgetattr failed\n");
632 ptr
->commerror
=WinError();
643 TRACE("GETMAXCOM\n");
644 for (max
= MAX_PORTS
;!COM
[max
].devicename
;max
--)
650 TRACE("GETMAXLPT\n");
651 for (max
= MAX_PORTS
;!LPT
[max
].devicename
;max
--)
653 return FLAG_LPT
+ max
;
657 TRACE("GETBASEIRQ\n");
658 /* FIXME: use tables */
659 /* just fake something for now */
660 if (cid
& FLAG_LPT
) {
661 /* LPT1: irq 7, LPT2: irq 5 */
662 return (cid
& 0x7f) ? 5 : 7;
664 /* COM1: irq 4, COM2: irq 3,
665 COM3: irq 4, COM4: irq 3 */
666 return 4 - (cid
& 1);
673 return COMM_WhackModem(ptr
->fd
, ~TIOCM_DTR
, 0);
678 return COMM_WhackModem(ptr
->fd
, ~TIOCM_RTS
, 0);
684 return COMM_WhackModem(ptr
->fd
, 0, TIOCM_DTR
);
690 return COMM_WhackModem(ptr
->fd
, 0, TIOCM_RTS
);
695 port
.c_iflag
|= IXOFF
;
700 port
.c_iflag
|= IXON
;
704 WARN("(cid=%d,nFunction=%d): Unknown function\n",
709 if (tcsetattr(ptr
->fd
, TCSADRAIN
, &port
) == -1) {
710 ptr
->commerror
= WinError();
718 /*****************************************************************************
719 * FlushComm (USER.215)
721 INT16 WINAPI
FlushComm16(INT16 cid
,INT16 fnQueue
)
724 struct DosDeviceStruct
*ptr
;
726 TRACE("cid=%d, queue=%d\n", cid
, fnQueue
);
727 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
728 FIXME("no cid=%d found!\n", cid
);
734 ptr
->obuf_tail
= ptr
->obuf_head
;
738 ptr
->ibuf_head
= ptr
->ibuf_tail
;
741 WARN("(cid=%d,fnQueue=%d):Unknown queue\n",
745 if (tcflush(ptr
->fd
, queue
)) {
746 ptr
->commerror
= WinError();
754 /********************************************************************
755 * GetCommError (USER.203)
757 INT16 WINAPI
GetCommError16(INT16 cid
,LPCOMSTAT16 lpStat
)
760 struct DosDeviceStruct
*ptr
;
764 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
765 FIXME("no handle for cid = %0x!.\n",cid
);
769 WARN(" cid %d not comm port\n",cid
);
772 stol
= (unsigned char *)unknown
[cid
] + COMM_MSR_OFFSET
;
773 ioctl(ptr
->fd
,TIOCMGET
,&mstat
);
774 COMM_MSRUpdate( stol
, mstat
);
779 lpStat
->cbOutQue
= comm_outbuf(ptr
);
780 lpStat
->cbInQue
= comm_inbuf(ptr
);
782 TRACE("cid %d, error %d, lpStat %d %d %d stol %x\n",
783 cid
, ptr
->commerror
, lpStat
->status
, lpStat
->cbInQue
,
784 lpStat
->cbOutQue
, *stol
);
787 TRACE("cid %d, error %d, lpStat NULL stol %x\n",
788 cid
, ptr
->commerror
, *stol
);
790 /* Return any errors and clear it */
791 temperror
= ptr
->commerror
;
796 /*****************************************************************************
797 * SetCommEventMask (USER.208)
799 SEGPTR WINAPI
SetCommEventMask16(INT16 cid
,UINT16 fuEvtMask
)
801 struct DosDeviceStruct
*ptr
;
806 TRACE("cid %d,mask %d\n",cid
,fuEvtMask
);
807 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
808 FIXME("no handle for cid = %0x!.\n",cid
);
812 ptr
->eventmask
= fuEvtMask
;
814 if ((cid
&FLAG_LPT
) || !ValidCOMPort(cid
)) {
815 WARN(" cid %d not comm port\n",cid
);
818 /* it's a COM port ? -> modify flags */
819 stol
= (unsigned char *)unknown
[cid
] + COMM_MSR_OFFSET
;
820 repid
= ioctl(ptr
->fd
,TIOCMGET
,&mstat
);
821 TRACE(" ioctl %d, msr %x at %p %p\n",repid
,mstat
,stol
,unknown
[cid
]);
822 COMM_MSRUpdate( stol
, mstat
);
824 TRACE(" modem dcd construct %x\n",*stol
);
825 return SEGPTR_GET(unknown
[cid
]);
828 /*****************************************************************************
829 * GetCommEventMask (USER.209)
831 UINT16 WINAPI
GetCommEventMask16(INT16 cid
,UINT16 fnEvtClear
)
833 struct DosDeviceStruct
*ptr
;
836 TRACE("cid %d, mask %d\n", cid
, fnEvtClear
);
837 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
838 FIXME("no handle for cid = %0x!.\n",cid
);
842 if ((cid
&FLAG_LPT
) || !ValidCOMPort(cid
)) {
843 WARN(" cid %d not comm port\n",cid
);
847 events
= *(WORD
*)(unknown
[cid
]) & fnEvtClear
;
848 *(WORD
*)(unknown
[cid
]) &= ~fnEvtClear
;
852 /*****************************************************************************
853 * SetCommState16 (USER.201)
855 INT16 WINAPI
SetCommState16(LPDCB16 lpdcb
)
858 struct DosDeviceStruct
*ptr
;
859 int bytesize
, stopbits
;
862 TRACE("cid %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
863 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
864 FIXME("no handle for cid = %0x!.\n",lpdcb
->Id
);
867 if (tcgetattr(ptr
->fd
, &port
) == -1) {
868 ptr
->commerror
= WinError();
873 port
.c_cc
[VTIME
] = 1;
876 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
878 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
880 port
.c_iflag
|= (IGNBRK
);
882 port
.c_oflag
&= ~(OPOST
);
884 port
.c_cflag
&= ~(HUPCL
);
885 port
.c_cflag
|= CLOCAL
| CREAD
;
887 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
888 port
.c_lflag
|= NOFLSH
;
890 TRACE("baudrate %d\n",lpdcb
->BaudRate
);
892 port
.c_cflag
&= ~CBAUD
;
893 switch (lpdcb
->BaudRate
) {
896 port
.c_cflag
|= B110
;
900 port
.c_cflag
|= B300
;
904 port
.c_cflag
|= B600
;
908 port
.c_cflag
|= B1200
;
912 port
.c_cflag
|= B2400
;
916 port
.c_cflag
|= B4800
;
920 port
.c_cflag
|= B9600
;
924 port
.c_cflag
|= B19200
;
928 port
.c_cflag
|= B38400
;
932 port
.c_cflag
|= B57600
;
937 port
.c_cflag
|= B115200
;
941 ptr
->commerror
= IE_BAUDRATE
;
944 #elif !defined(__EMX__)
945 switch (lpdcb
->BaudRate
) {
948 port
.c_ospeed
= B110
;
952 port
.c_ospeed
= B300
;
956 port
.c_ospeed
= B600
;
960 port
.c_ospeed
= B1200
;
964 port
.c_ospeed
= B2400
;
968 port
.c_ospeed
= B4800
;
972 port
.c_ospeed
= B9600
;
976 port
.c_ospeed
= B19200
;
980 port
.c_ospeed
= B38400
;
983 ptr
->commerror
= IE_BAUDRATE
;
986 port
.c_ispeed
= port
.c_ospeed
;
988 bytesize
=lpdcb
->ByteSize
;
989 stopbits
=lpdcb
->StopBits
;
991 TRACE("fParity %d Parity %d\n",lpdcb
->fParity
, lpdcb
->Parity
);
993 port
.c_cflag
&= ~(PARENB
| PARODD
| CMSPAR
);
995 port
.c_cflag
&= ~(PARENB
| PARODD
);
998 port
.c_iflag
|= INPCK
;
1000 port
.c_iflag
&= ~INPCK
;
1001 switch (lpdcb
->Parity
) {
1005 port
.c_cflag
|= (PARENB
| PARODD
);
1008 port
.c_cflag
|= PARENB
;
1011 /* Linux defines mark/space (stick) parity */
1013 port
.c_cflag
|= (PARENB
| CMSPAR
);
1016 port
.c_cflag
|= (PARENB
| PARODD
| CMSPAR
);
1019 /* try the POSIX way */
1021 if( stopbits
== ONESTOPBIT
) {
1022 stopbits
= TWOSTOPBITS
;
1023 port
.c_iflag
&= ~INPCK
;
1025 ptr
->commerror
= IE_BYTESIZE
;
1032 port
.c_iflag
&= ~INPCK
;
1034 ptr
->commerror
= IE_BYTESIZE
;
1040 ptr
->commerror
= IE_BYTESIZE
;
1044 TRACE("bytesize %d\n",bytesize
);
1045 port
.c_cflag
&= ~CSIZE
;
1048 port
.c_cflag
|= CS5
;
1051 port
.c_cflag
|= CS6
;
1054 port
.c_cflag
|= CS7
;
1057 port
.c_cflag
|= CS8
;
1060 ptr
->commerror
= IE_BYTESIZE
;
1064 TRACE("stopbits %d\n",stopbits
);
1068 port
.c_cflag
&= ~CSTOPB
;
1070 case ONE5STOPBITS
: /* wil be selected if bytesize is 5 */
1072 port
.c_cflag
|= CSTOPB
;
1075 ptr
->commerror
= IE_BYTESIZE
;
1080 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
1081 port
.c_cflag
|= CRTSCTS
;
1083 if (lpdcb
->fDtrDisable
)
1084 port
.c_cflag
&= ~CRTSCTS
;
1087 port
.c_iflag
|= IXON
;
1089 port
.c_iflag
&= ~IXON
;
1091 port
.c_iflag
|= IXOFF
;
1093 port
.c_iflag
&= ~IXOFF
;
1095 ptr
->evtchar
= lpdcb
->EvtChar
;
1100 if (tcsetattr(ptr
->fd
, TCSADRAIN
, &port
) == -1) {
1101 ptr
->commerror
= WinError();
1109 /*****************************************************************************
1110 * GetCommState (USER.202)
1112 INT16 WINAPI
GetCommState16(INT16 cid
, LPDCB16 lpdcb
)
1115 struct DosDeviceStruct
*ptr
;
1116 struct termios port
;
1118 TRACE("cid %d, ptr %p\n", cid
, lpdcb
);
1119 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1120 FIXME("no handle for cid = %0x!.\n",cid
);
1123 if (tcgetattr(ptr
->fd
, &port
) == -1) {
1124 ptr
->commerror
= WinError();
1130 speed
= port
.c_cflag
& CBAUD
;
1132 speed
= port
.c_ospeed
;
1136 lpdcb
->BaudRate
= 110;
1139 lpdcb
->BaudRate
= 300;
1142 lpdcb
->BaudRate
= 600;
1145 lpdcb
->BaudRate
= 1200;
1148 lpdcb
->BaudRate
= 2400;
1151 lpdcb
->BaudRate
= 4800;
1154 lpdcb
->BaudRate
= 9600;
1157 lpdcb
->BaudRate
= 19200;
1160 lpdcb
->BaudRate
= 38400;
1164 lpdcb
->BaudRate
= 57600;
1169 lpdcb
->BaudRate
= 57601;
1174 switch (port
.c_cflag
& CSIZE
) {
1176 lpdcb
->ByteSize
= 5;
1179 lpdcb
->ByteSize
= 6;
1182 lpdcb
->ByteSize
= 7;
1185 lpdcb
->ByteSize
= 8;
1189 if(port
.c_iflag
& INPCK
)
1190 lpdcb
->fParity
= TRUE
;
1192 lpdcb
->fParity
= FALSE
;
1194 switch (port
.c_cflag
& (PARENB
| PARODD
| CMSPAR
))
1196 switch (port
.c_cflag
& (PARENB
| PARODD
))
1200 lpdcb
->Parity
= NOPARITY
;
1203 lpdcb
->Parity
= EVENPARITY
;
1205 case (PARENB
| PARODD
):
1206 lpdcb
->Parity
= ODDPARITY
;
1209 case (PARENB
| CMSPAR
):
1210 lpdcb
->Parity
= MARKPARITY
;
1212 case (PARENB
| PARODD
| CMSPAR
):
1213 lpdcb
->Parity
= SPACEPARITY
;
1218 if (port
.c_cflag
& CSTOPB
)
1219 if(lpdcb
->ByteSize
== 5)
1220 lpdcb
->StopBits
= ONE5STOPBITS
;
1222 lpdcb
->StopBits
= TWOSTOPBITS
;
1224 lpdcb
->StopBits
= ONESTOPBIT
;
1226 lpdcb
->RlsTimeout
= 50;
1227 lpdcb
->CtsTimeout
= 50;
1228 lpdcb
->DsrTimeout
= 50;
1232 lpdcb
->fDtrDisable
= 0;
1236 if (port
.c_cflag
& CRTSCTS
) {
1237 lpdcb
->fDtrflow
= 1;
1238 lpdcb
->fRtsflow
= 1;
1239 lpdcb
->fOutxCtsFlow
= 1;
1240 lpdcb
->fOutxDsrFlow
= 1;
1243 lpdcb
->fDtrDisable
= 1;
1245 if (port
.c_iflag
& IXON
)
1250 if (port
.c_iflag
& IXOFF
)
1259 lpdcb
->XoffLim
= 10;
1261 lpdcb
->EvtChar
= ptr
->evtchar
;
1267 /*****************************************************************************
1268 * TransmitCommChar (USER.206)
1270 INT16 WINAPI
TransmitCommChar16(INT16 cid
,CHAR chTransmit
)
1272 struct DosDeviceStruct
*ptr
;
1274 TRACE("cid %d, data %d \n", cid
, chTransmit
);
1275 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1276 FIXME("no handle for cid = %0x!.\n",cid
);
1280 if (ptr
->suspended
) {
1281 ptr
->commerror
= IE_HARDWARE
;
1285 if (ptr
->xmit
>= 0) {
1286 /* character already queued */
1287 /* FIXME: which error would Windows return? */
1288 ptr
->commerror
= CE_TXFULL
;
1292 if (ptr
->obuf_head
== ptr
->obuf_tail
) {
1293 /* transmit queue empty, try to transmit directly */
1294 if (write(ptr
->fd
, &chTransmit
, 1) == -1) {
1295 /* didn't work, queue it */
1296 ptr
->xmit
= chTransmit
;
1297 comm_waitwrite(ptr
);
1300 /* data in queue, let this char be transmitted next */
1301 ptr
->xmit
= chTransmit
;
1302 comm_waitwrite(ptr
);
1309 /*****************************************************************************
1310 * UngetCommChar (USER.212)
1312 INT16 WINAPI
UngetCommChar16(INT16 cid
,CHAR chUnget
)
1314 struct DosDeviceStruct
*ptr
;
1316 TRACE("cid %d (char %d)\n", cid
, chUnget
);
1317 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1318 FIXME("no handle for cid = %0x!.\n",cid
);
1322 if (ptr
->suspended
) {
1323 ptr
->commerror
= IE_HARDWARE
;
1327 if (ptr
->unget
>=0) {
1328 /* character already queued */
1329 /* FIXME: which error would Windows return? */
1330 ptr
->commerror
= CE_RXOVER
;
1334 ptr
->unget
= chUnget
;
1340 /*****************************************************************************
1341 * ReadComm (USER.204)
1343 INT16 WINAPI
ReadComm16(INT16 cid
,LPSTR lpvBuf
,INT16 cbRead
)
1346 struct DosDeviceStruct
*ptr
;
1347 LPSTR orgBuf
= lpvBuf
;
1349 TRACE("cid %d, ptr %p, length %d\n", cid
, lpvBuf
, cbRead
);
1350 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1351 FIXME("no handle for cid = %0x!.\n",cid
);
1355 if (ptr
->suspended
) {
1356 ptr
->commerror
= IE_HARDWARE
;
1360 /* read unget character */
1361 if (ptr
->unget
>=0) {
1362 *lpvBuf
++ = ptr
->unget
;
1369 /* read from receive buffer */
1370 while (length
< cbRead
) {
1371 status
= ((ptr
->ibuf_head
< ptr
->ibuf_tail
) ?
1372 ptr
->ibuf_size
: ptr
->ibuf_head
) - ptr
->ibuf_tail
;
1374 if ((cbRead
- length
) < status
)
1375 status
= cbRead
- length
;
1377 memcpy(lpvBuf
, ptr
->inbuf
+ ptr
->ibuf_tail
, status
);
1378 ptr
->ibuf_tail
+= status
;
1379 if (ptr
->ibuf_tail
>= ptr
->ibuf_size
)
1385 TRACE("%.*s\n", length
, orgBuf
);
1390 /*****************************************************************************
1391 * WriteComm (USER.205)
1393 INT16 WINAPI
WriteComm16(INT16 cid
, LPSTR lpvBuf
, INT16 cbWrite
)
1396 struct DosDeviceStruct
*ptr
;
1398 TRACE("cid %d, ptr %p, length %d\n",
1399 cid
, lpvBuf
, cbWrite
);
1400 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1401 FIXME("no handle for cid = %0x!.\n",cid
);
1405 if (ptr
->suspended
) {
1406 ptr
->commerror
= IE_HARDWARE
;
1410 TRACE("%.*s\n", cbWrite
, lpvBuf
);
1413 while (length
< cbWrite
) {
1414 if ((ptr
->obuf_head
== ptr
->obuf_tail
) && (ptr
->xmit
< 0)) {
1415 /* no data queued, try to write directly */
1416 status
= write(ptr
->fd
, lpvBuf
, cbWrite
- length
);
1423 /* can't write directly, put into transmit buffer */
1424 status
= ((ptr
->obuf_tail
> ptr
->obuf_head
) ?
1425 (ptr
->obuf_tail
-1) : ptr
->obuf_size
) - ptr
->obuf_head
;
1427 if ((cbWrite
- length
) < status
)
1428 status
= cbWrite
- length
;
1429 memcpy(lpvBuf
, ptr
->outbuf
+ ptr
->obuf_head
, status
);
1430 ptr
->obuf_head
+= status
;
1431 if (ptr
->obuf_head
>= ptr
->obuf_size
)
1435 comm_waitwrite(ptr
);
1442 /***********************************************************************
1443 * EnableCommNotification (USER.246)
1445 BOOL16 WINAPI
EnableCommNotification16( INT16 cid
, HWND16 hwnd
,
1446 INT16 cbWriteNotify
, INT16 cbOutQueue
)
1448 struct DosDeviceStruct
*ptr
;
1450 TRACE("(%d, %x, %d, %d)\n", cid
, hwnd
, cbWriteNotify
, cbOutQueue
);
1451 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1452 FIXME("no handle for cid = %0x!.\n",cid
);
1456 ptr
->n_read
= cbWriteNotify
;
1457 ptr
->n_write
= cbOutQueue
;
1462 /**************************************************************************
1463 * BuildCommDCBA (KERNEL32.14)
1465 BOOL WINAPI
BuildCommDCBA(LPCSTR device
,LPDCB lpdcb
)
1467 return BuildCommDCBAndTimeoutsA(device
,lpdcb
,NULL
);
1470 /**************************************************************************
1471 * BuildCommDCBAndTimeoutsA (KERNEL32.15)
1473 BOOL WINAPI
BuildCommDCBAndTimeoutsA(LPCSTR device
, LPDCB lpdcb
,
1474 LPCOMMTIMEOUTS lptimeouts
)
1479 TRACE("(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
1481 if (!lstrncmpiA(device
,"COM",3)) {
1484 ERR("BUG! COM0 can't exists!.\n");
1487 if (!ValidCOMPort(port
))
1489 if (*(device
+4)!=':')
1491 temp
=(LPSTR
)(device
+5);
1495 lpdcb
->DCBlength
= sizeof(DCB
);
1496 if (strchr(temp
,',')) { /* old style */
1499 char last
=temp
[strlen(temp
)-1];
1501 ret
=BuildCommDCB16(device
,&dcb16
);
1504 lpdcb
->BaudRate
= dcb16
.BaudRate
;
1505 lpdcb
->ByteSize
= dcb16
.ByteSize
;
1506 lpdcb
->fBinary
= dcb16
.fBinary
;
1507 lpdcb
->Parity
= dcb16
.Parity
;
1508 lpdcb
->fParity
= dcb16
.fParity
;
1509 lpdcb
->fNull
= dcb16
.fNull
;
1510 lpdcb
->StopBits
= dcb16
.StopBits
;
1513 lpdcb
->fOutX
= TRUE
;
1514 lpdcb
->fOutxCtsFlow
= FALSE
;
1515 lpdcb
->fOutxDsrFlow
= FALSE
;
1516 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1517 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1518 } else if (last
=='p') {
1519 lpdcb
->fInX
= FALSE
;
1520 lpdcb
->fOutX
= FALSE
;
1521 lpdcb
->fOutxCtsFlow
= TRUE
;
1522 lpdcb
->fOutxDsrFlow
= TRUE
;
1523 lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
;
1524 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
1526 lpdcb
->fInX
= FALSE
;
1527 lpdcb
->fOutX
= FALSE
;
1528 lpdcb
->fOutxCtsFlow
= FALSE
;
1529 lpdcb
->fOutxDsrFlow
= FALSE
;
1530 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1531 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1533 lpdcb
->XonChar
= dcb16
.XonChar
;
1534 lpdcb
->XoffChar
= dcb16
.XoffChar
;
1535 lpdcb
->ErrorChar
= dcb16
.PeChar
;
1536 lpdcb
->fErrorChar
= dcb16
.fPeChar
;
1537 lpdcb
->EofChar
= dcb16
.EofChar
;
1538 lpdcb
->EvtChar
= dcb16
.EvtChar
;
1539 lpdcb
->XonLim
= dcb16
.XonLim
;
1540 lpdcb
->XoffLim
= dcb16
.XoffLim
;
1543 ptr
=strtok(temp
," ");
1548 if (!strncmp("baud=",ptr
,5)) {
1549 if (!sscanf(ptr
+5,"%ld",&x
))
1550 WARN("Couldn't parse %s\n",ptr
);
1551 lpdcb
->BaudRate
= x
;
1554 if (!strncmp("stop=",ptr
,5)) {
1555 if (!sscanf(ptr
+5,"%ld",&x
))
1556 WARN("Couldn't parse %s\n",ptr
);
1557 lpdcb
->StopBits
= x
;
1560 if (!strncmp("data=",ptr
,5)) {
1561 if (!sscanf(ptr
+5,"%ld",&x
))
1562 WARN("Couldn't parse %s\n",ptr
);
1563 lpdcb
->ByteSize
= x
;
1566 if (!strncmp("parity=",ptr
,7)) {
1567 lpdcb
->fParity
= TRUE
;
1570 lpdcb
->fParity
= FALSE
;
1571 lpdcb
->Parity
= NOPARITY
;
1574 lpdcb
->Parity
= EVENPARITY
;
1577 lpdcb
->Parity
= ODDPARITY
;
1580 lpdcb
->Parity
= MARKPARITY
;
1586 ERR("Unhandled specifier '%s', please report.\n",ptr
);
1587 ptr
=strtok(NULL
," ");
1589 if (lpdcb
->BaudRate
==110)
1590 lpdcb
->StopBits
= 2;
1594 /**************************************************************************
1595 * BuildCommDCBAndTimeoutsW (KERNEL32.16)
1597 BOOL WINAPI
BuildCommDCBAndTimeoutsW( LPCWSTR devid
, LPDCB lpdcb
,
1598 LPCOMMTIMEOUTS lptimeouts
)
1603 TRACE("(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
1604 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
1605 ret
=BuildCommDCBAndTimeoutsA(devidA
,lpdcb
,lptimeouts
);
1606 HeapFree( GetProcessHeap(), 0, devidA
);
1610 /**************************************************************************
1611 * BuildCommDCBW (KERNEL32.17)
1613 BOOL WINAPI
BuildCommDCBW(LPCWSTR devid
,LPDCB lpdcb
)
1615 return BuildCommDCBAndTimeoutsW(devid
,lpdcb
,NULL
);
1618 /*****************************************************************************
1620 * Returns a file descriptor for reading.
1621 * Make sure to close the handle afterwards!
1623 static int COMM_GetReadFd( HANDLE handle
)
1626 struct get_read_fd_request
*req
= get_req_buffer();
1627 req
->handle
= handle
;
1628 server_call_fd( REQ_GET_READ_FD
, -1, &fd
);
1632 /*****************************************************************************
1634 * Returns a file descriptor for writing.
1635 * Make sure to close the handle afterwards!
1637 static int COMM_GetWriteFd( HANDLE handle
)
1640 struct get_write_fd_request
*req
= get_req_buffer();
1641 req
->handle
= handle
;
1642 server_call_fd( REQ_GET_WRITE_FD
, -1, &fd
);
1646 /* FIXME: having these global for win32 for now */
1647 int commerror
=0,eventmask
=0;
1649 /*****************************************************************************
1650 * SetCommBreak (KERNEL32.449)
1652 BOOL WINAPI
SetCommBreak(HANDLE handle
)
1654 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
1657 fd
= COMM_GetWriteFd(handle
);
1659 TRACE("COMM_GetWriteFd failed\n");
1662 result
= ioctl(fd
,TIOCSBRK
,0);
1666 TRACE("ioctl failed\n");
1667 SetLastError(ERROR_NOT_SUPPORTED
);
1672 FIXME("ioctl not available\n");
1673 SetLastError(ERROR_NOT_SUPPORTED
);
1678 /*****************************************************************************
1679 * ClearCommBreak (KERNEL32.20)
1681 BOOL WINAPI
ClearCommBreak(HANDLE handle
)
1683 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
1686 fd
= COMM_GetWriteFd(handle
);
1688 TRACE("COMM_GetWriteFd failed\n");
1691 result
= ioctl(fd
,TIOCCBRK
,0);
1695 TRACE("ioctl failed\n");
1696 SetLastError(ERROR_NOT_SUPPORTED
);
1701 FIXME("ioctl not available\n");
1702 SetLastError(ERROR_NOT_SUPPORTED
);
1707 /*****************************************************************************
1708 * EscapeCommFunction (KERNEL32.214)
1710 BOOL WINAPI
EscapeCommFunction(HANDLE handle
,UINT nFunction
)
1712 int fd
,direct
=FALSE
,result
=FALSE
;
1713 struct termios port
;
1715 TRACE("handle %d, function=%d\n", handle
, nFunction
);
1716 fd
= COMM_GetWriteFd(handle
);
1718 FIXME("handle %d not found.\n",handle
);
1722 if (tcgetattr(fd
,&port
) == -1) {
1723 commerror
=WinError();
1728 switch (nFunction
) {
1737 result
= COMM_WhackModem(fd
, ~TIOCM_DTR
, 0);
1745 result
= COMM_WhackModem(fd
, ~TIOCM_RTS
, 0);
1753 result
= COMM_WhackModem(fd
, 0, TIOCM_DTR
);
1761 result
= COMM_WhackModem(fd
, 0, TIOCM_RTS
);
1767 port
.c_iflag
|= IXOFF
;
1772 port
.c_iflag
|= IXON
;
1775 TRACE("setbreak\n");
1778 result
= ioctl(fd
,TIOCSBRK
,0);
1782 TRACE("clrbreak\n");
1785 result
= ioctl(fd
,TIOCCBRK
,0);
1789 WARN("(handle=%d,nFunction=%d): Unknown function\n",
1795 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
1796 commerror
= WinError();
1806 commerror
=WinError();
1815 /********************************************************************
1816 * PurgeComm (KERNEL32.557)
1818 BOOL WINAPI
PurgeComm( HANDLE handle
, DWORD flags
)
1822 TRACE("handle %d, flags %lx\n", handle
, flags
);
1824 fd
= COMM_GetWriteFd(handle
);
1826 FIXME("no handle %d found\n",handle
);
1831 ** not exactly sure how these are different
1832 ** Perhaps if we had our own internal queues, one flushes them
1833 ** and the other flushes the kernel's buffers.
1835 if(flags
&PURGE_TXABORT
)
1836 tcflush(fd
,TCOFLUSH
);
1837 if(flags
&PURGE_RXABORT
)
1838 tcflush(fd
,TCIFLUSH
);
1839 if(flags
&PURGE_TXCLEAR
)
1840 tcflush(fd
,TCOFLUSH
);
1841 if(flags
&PURGE_RXCLEAR
)
1842 tcflush(fd
,TCIFLUSH
);
1848 /*****************************************************************************
1849 * ClearCommError (KERNEL32.21)
1851 BOOL WINAPI
ClearCommError(HANDLE handle
,LPDWORD errors
,LPCOMSTAT lpStat
)
1855 fd
=COMM_GetReadFd(handle
);
1858 FIXME("no handle %d found\n",handle
);
1867 if(ioctl(fd
, TIOCOUTQ
, &lpStat
->cbOutQue
))
1868 WARN("ioctl returned error\n");
1870 lpStat
->cbOutQue
= 0; /* FIXME: find a different way to find out */
1873 if(ioctl(fd
, TIOCINQ
, &lpStat
->cbInQue
))
1874 WARN("ioctl returned error\n");
1876 TRACE("handle %d cbInQue = %ld cbOutQue = %ld\n",
1877 handle
, lpStat
->cbInQue
, lpStat
->cbOutQue
);
1886 ** After an asynchronous write opperation, the
1887 ** app will call ClearCommError to see if the
1888 ** results are ready yet. It waits for ERROR_IO_PENDING
1890 commerror
= ERROR_IO_PENDING
;
1895 /*****************************************************************************
1896 * SetupComm (KERNEL32.676)
1898 BOOL WINAPI
SetupComm( HANDLE handle
, DWORD insize
, DWORD outsize
)
1902 FIXME("insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
1903 fd
=COMM_GetWriteFd(handle
);
1905 FIXME("handle %d not found?\n",handle
);
1912 /*****************************************************************************
1913 * GetCommMask (KERNEL32.156)
1915 BOOL WINAPI
GetCommMask(HANDLE handle
,LPDWORD evtmask
)
1919 TRACE("handle %d, mask %p\n", handle
, evtmask
);
1920 if(0>(fd
=COMM_GetReadFd(handle
)))
1922 FIXME("no handle %d found\n",handle
);
1926 *evtmask
= eventmask
;
1927 TRACE("%s%s%s%s%s%s%s%s%s\n",
1928 (eventmask
&EV_BREAK
)?"EV_BREAK":"",
1929 (eventmask
&EV_CTS
)?"EV_CTS":"",
1930 (eventmask
&EV_DSR
)?"EV_DSR":"",
1931 (eventmask
&EV_ERR
)?"EV_ERR":"",
1932 (eventmask
&EV_RING
)?"EV_RING":"",
1933 (eventmask
&EV_RLSD
)?"EV_RLSD":"",
1934 (eventmask
&EV_RXCHAR
)?"EV_RXCHAR":"",
1935 (eventmask
&EV_RXFLAG
)?"EV_RXFLAG":"",
1936 (eventmask
&EV_TXEMPTY
)?"EV_TXEMPTY":"");
1941 /*****************************************************************************
1942 * SetCommMask (KERNEL32.451)
1944 BOOL WINAPI
SetCommMask(HANDLE handle
,DWORD evtmask
)
1948 TRACE("handle %d, mask %lx\n", handle
, evtmask
);
1949 TRACE("%s%s%s%s%s%s%s%s%s\n",
1950 (evtmask
&EV_BREAK
)?"EV_BREAK":"",
1951 (evtmask
&EV_CTS
)?"EV_CTS":"",
1952 (evtmask
&EV_DSR
)?"EV_DSR":"",
1953 (evtmask
&EV_ERR
)?"EV_ERR":"",
1954 (evtmask
&EV_RING
)?"EV_RING":"",
1955 (evtmask
&EV_RLSD
)?"EV_RLSD":"",
1956 (evtmask
&EV_RXCHAR
)?"EV_RXCHAR":"",
1957 (evtmask
&EV_RXFLAG
)?"EV_RXFLAG":"",
1958 (evtmask
&EV_TXEMPTY
)?"EV_TXEMPTY":"");
1960 if(0>(fd
=COMM_GetWriteFd(handle
))) {
1961 FIXME("no handle %d found\n",handle
);
1965 eventmask
= evtmask
;
1969 /*****************************************************************************
1970 * SetCommState (KERNEL32.452)
1972 BOOL WINAPI
SetCommState(HANDLE handle
,LPDCB lpdcb
)
1974 struct termios port
;
1976 int bytesize
, stopbits
;
1978 TRACE("handle %d, ptr %p\n", handle
, lpdcb
);
1979 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1980 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
1981 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
1982 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
1983 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
1984 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
1986 if ((fd
= COMM_GetWriteFd(handle
)) < 0) {
1987 FIXME("no handle %d found\n",handle
);
1991 if ((tcgetattr(fd
,&port
)) == -1) {
1992 int save_error
= errno
;
1993 commerror
= WinError();
1995 #ifdef HAVE_STRERROR
1996 ERR("tcgetattr error '%s'\n", strerror(save_error
));
1998 ERR("tcgetattr error %d\n", save_error
);
2003 port
.c_cc
[VMIN
] = 0;
2004 port
.c_cc
[VTIME
] = 1;
2007 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
2009 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
2011 port
.c_iflag
|= (IGNBRK
);
2013 port
.c_oflag
&= ~(OPOST
);
2015 port
.c_cflag
&= ~(HUPCL
);
2016 port
.c_cflag
|= CLOCAL
| CREAD
;
2018 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
2019 port
.c_lflag
|= NOFLSH
;
2022 ** MJM - removed default baudrate settings
2023 ** TRACE(comm,"baudrate %ld\n",lpdcb->BaudRate);
2026 port
.c_cflag
&= ~CBAUD
;
2027 switch (lpdcb
->BaudRate
) {
2030 port
.c_cflag
|= B110
;
2034 port
.c_cflag
|= B300
;
2038 port
.c_cflag
|= B600
;
2042 port
.c_cflag
|= B1200
;
2046 port
.c_cflag
|= B2400
;
2050 port
.c_cflag
|= B4800
;
2054 port
.c_cflag
|= B9600
;
2058 port
.c_cflag
|= B19200
;
2062 port
.c_cflag
|= B38400
;
2066 port
.c_cflag
|= B57600
;
2071 port
.c_cflag
|= B115200
;
2076 port
.c_cflag
|= B230400
;
2081 port
.c_cflag
|= B460800
;
2085 commerror
= IE_BAUDRATE
;
2087 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
2090 #elif !defined(__EMX__)
2091 switch (lpdcb
->BaudRate
) {
2094 port
.c_ospeed
= B110
;
2098 port
.c_ospeed
= B300
;
2102 port
.c_ospeed
= B600
;
2106 port
.c_ospeed
= B1200
;
2110 port
.c_ospeed
= B2400
;
2114 port
.c_ospeed
= B4800
;
2118 port
.c_ospeed
= B9600
;
2122 port
.c_ospeed
= B19200
;
2126 port
.c_ospeed
= B38400
;
2129 commerror
= IE_BAUDRATE
;
2131 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
2134 port
.c_ispeed
= port
.c_ospeed
;
2136 bytesize
=lpdcb
->ByteSize
;
2137 stopbits
=lpdcb
->StopBits
;
2140 port
.c_cflag
&= ~(PARENB
| PARODD
| CMSPAR
);
2142 port
.c_cflag
&= ~(PARENB
| PARODD
);
2145 port
.c_iflag
|= INPCK
;
2147 port
.c_iflag
&= ~INPCK
;
2148 switch (lpdcb
->Parity
) {
2152 port
.c_cflag
|= (PARENB
| PARODD
);
2155 port
.c_cflag
|= PARENB
;
2158 /* Linux defines mark/space (stick) parity */
2160 port
.c_cflag
|= (PARENB
| CMSPAR
);
2163 port
.c_cflag
|= (PARENB
| PARODD
| CMSPAR
);
2166 /* try the POSIX way */
2168 if( stopbits
== ONESTOPBIT
) {
2169 stopbits
= TWOSTOPBITS
;
2170 port
.c_iflag
&= ~INPCK
;
2172 commerror
= IE_BYTESIZE
;
2174 ERR("Cannot set MARK Parity\n");
2181 port
.c_iflag
&= ~INPCK
;
2183 commerror
= IE_BYTESIZE
;
2185 ERR("Cannot set SPACE Parity\n");
2191 commerror
= IE_BYTESIZE
;
2198 port
.c_cflag
&= ~CSIZE
;
2201 port
.c_cflag
|= CS5
;
2204 port
.c_cflag
|= CS6
;
2207 port
.c_cflag
|= CS7
;
2210 port
.c_cflag
|= CS8
;
2213 commerror
= IE_BYTESIZE
;
2221 port
.c_cflag
&= ~CSTOPB
;
2223 case ONE5STOPBITS
: /* wil be selected if bytesize is 5 */
2225 port
.c_cflag
|= CSTOPB
;
2228 commerror
= IE_BYTESIZE
;
2234 if ( lpdcb
->fOutxCtsFlow
||
2235 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
2236 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
2239 port
.c_cflag
|= CRTSCTS
;
2243 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
2245 port
.c_cflag
&= ~CRTSCTS
;
2246 TRACE("~CRTSCTS\n");
2251 port
.c_iflag
|= IXON
;
2253 port
.c_iflag
&= ~IXON
;
2255 port
.c_iflag
|= IXOFF
;
2257 port
.c_iflag
&= ~IXOFF
;
2259 if (tcsetattr(fd
,TCSANOW
,&port
)==-1) { /* otherwise it hangs with pending input*/
2260 int save_error
=errno
;
2261 commerror
= WinError();
2263 #ifdef HAVE_STRERROR
2264 ERR("tcgetattr error '%s'\n", strerror(save_error
));
2266 ERR("tcgetattr error %d\n", save_error
);
2277 /*****************************************************************************
2278 * GetCommState (KERNEL32.159)
2280 BOOL WINAPI
GetCommState(HANDLE handle
, LPDCB lpdcb
)
2282 struct termios port
;
2285 TRACE("handle %d, ptr %p\n", handle
, lpdcb
);
2287 if ((fd
= COMM_GetReadFd(handle
)) < 0)
2289 ERR("can't get COMM_GetReadFd\n");
2292 if (tcgetattr(fd
, &port
) == -1) {
2293 int save_error
=errno
;
2294 #ifdef HAVE_STRERROR
2295 ERR("tcgetattr error '%s'\n", strerror(save_error
));
2297 ERR("tcgetattr error %d\n", save_error
);
2299 commerror
= WinError();
2306 speed
= (port
.c_cflag
& CBAUD
);
2308 speed
= (cfgetospeed(&port
));
2312 lpdcb
->BaudRate
= 110;
2315 lpdcb
->BaudRate
= 300;
2318 lpdcb
->BaudRate
= 600;
2321 lpdcb
->BaudRate
= 1200;
2324 lpdcb
->BaudRate
= 2400;
2327 lpdcb
->BaudRate
= 4800;
2330 lpdcb
->BaudRate
= 9600;
2333 lpdcb
->BaudRate
= 19200;
2336 lpdcb
->BaudRate
= 38400;
2340 lpdcb
->BaudRate
= 57600;
2345 lpdcb
->BaudRate
= 115200;
2350 lpdcb
->BaudRate
= 230400;
2355 lpdcb
->BaudRate
= 460800;
2359 ERR("unknown speed %x \n",speed
);
2362 switch (port
.c_cflag
& CSIZE
) {
2364 lpdcb
->ByteSize
= 5;
2367 lpdcb
->ByteSize
= 6;
2370 lpdcb
->ByteSize
= 7;
2373 lpdcb
->ByteSize
= 8;
2376 ERR("unknown size %x \n",port
.c_cflag
& CSIZE
);
2379 if(port
.c_iflag
& INPCK
)
2380 lpdcb
->fParity
= TRUE
;
2382 lpdcb
->fParity
= FALSE
;
2384 switch (port
.c_cflag
& (PARENB
| PARODD
| CMSPAR
))
2386 switch (port
.c_cflag
& (PARENB
| PARODD
))
2390 lpdcb
->Parity
= NOPARITY
;
2393 lpdcb
->Parity
= EVENPARITY
;
2395 case (PARENB
| PARODD
):
2396 lpdcb
->Parity
= ODDPARITY
;
2399 case (PARENB
| CMSPAR
):
2400 lpdcb
->Parity
= MARKPARITY
;
2402 case (PARENB
| PARODD
| CMSPAR
):
2403 lpdcb
->Parity
= SPACEPARITY
;
2408 if (port
.c_cflag
& CSTOPB
)
2409 if(lpdcb
->ByteSize
== 5)
2410 lpdcb
->StopBits
= ONE5STOPBITS
;
2412 lpdcb
->StopBits
= TWOSTOPBITS
;
2414 lpdcb
->StopBits
= ONESTOPBIT
;
2421 if (port
.c_cflag
& CRTSCTS
) {
2422 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
2423 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
2424 lpdcb
->fOutxCtsFlow
= 1;
2425 lpdcb
->fOutxDsrFlow
= 1;
2429 lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
;
2430 lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
;
2432 if (port
.c_iflag
& IXON
)
2437 if (port
.c_iflag
& IXOFF
)
2446 lpdcb
->XoffLim
= 10;
2452 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
2453 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
2454 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
2455 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
2456 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
2457 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
2459 if ( lpdcb
->fOutxCtsFlow
||
2460 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
2461 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
2465 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
2466 TRACE("~CRTSCTS\n");
2472 /*****************************************************************************
2473 * TransmitCommChar (KERNEL32.535)
2475 BOOL WINAPI
TransmitCommChar(HANDLE hComm
,CHAR chTransmit
)
2477 FIXME("(%x,'%c'), use win32 handle!\n",hComm
,chTransmit
);
2481 /*****************************************************************************
2482 * GetCommTimeouts (KERNEL32.160)
2484 BOOL WINAPI
GetCommTimeouts(HANDLE hcom
,LPCOMMTIMEOUTS lptimeouts
)
2486 FIXME("(%x,%p):stub.\n",hcom
,lptimeouts
);
2490 /*****************************************************************************
2491 * SetCommTimeouts (KERNEL32.453)
2493 BOOL WINAPI
SetCommTimeouts(HANDLE hcom
,LPCOMMTIMEOUTS lptimeouts
) {
2494 /* struct DosDeviceStruct *ptr; */
2495 struct termios tios
;
2498 FIXME("(%x,%p):stub.\n",hcom
,lptimeouts
);
2500 if ((ptr = GetDeviceStruct(hcom)) == NULL) {
2501 FIXME("no handle for cid = %0x!.\n",hcom);
2506 fd
= COMM_GetWriteFd(hcom
);
2508 FIXME("no fd for cid = %0x!.\n",hcom
);
2513 FIXME("ReadIntervalTimeout %ld\n",lptimeouts
->ReadIntervalTimeout
);
2514 FIXME("ReadTotalTimeoutMultiplier %ld\n",lptimeouts
->ReadTotalTimeoutMultiplier
);
2515 FIXME("ReadTotalTimeoutConstant %ld\n",lptimeouts
->ReadTotalTimeoutConstant
);
2516 FIXME("WriteTotalTimeoutMultiplier %ld\n",lptimeouts
->WriteTotalTimeoutMultiplier
);
2517 FIXME("WriteTotalTimeoutConstant %ld\n",lptimeouts
->WriteTotalTimeoutConstant
);
2520 if (-1==tcgetattr(fd
,&tios
)) {
2521 FIXME("tcgetattr on fd %d failed!\n",fd
);
2524 /* VTIME is in 1/10 seconds */
2525 tios
.c_cc
[VTIME
]= (lptimeouts
->ReadIntervalTimeout
+99)/100;
2526 if (-1==tcsetattr(fd
,0,&tios
)) {
2527 FIXME("tcsetattr on fd %d failed!\n",fd
);
2533 /***********************************************************************
2534 * GetCommModemStatus (KERNEL32.285)
2536 BOOL WINAPI
GetCommModemStatus(HANDLE hFile
,LPDWORD lpModemStat
)
2538 int fd
,mstat
, result
=FALSE
;
2542 fd
= COMM_GetWriteFd(hFile
);
2545 result
= ioctl(fd
, TIOCMGET
, &mstat
);
2549 TRACE("ioctl failed\n");
2552 if (mstat
& TIOCM_CTS
)
2553 *lpModemStat
|= MS_CTS_ON
;
2554 if (mstat
& TIOCM_DSR
)
2555 *lpModemStat
|= MS_DSR_ON
;
2556 if (mstat
& TIOCM_RNG
)
2557 *lpModemStat
|= MS_RING_ON
;
2558 /*FIXME: Not really sure about RLSD UB 990810*/
2559 if (mstat
& TIOCM_CAR
)
2560 *lpModemStat
|= MS_RLSD_ON
;
2562 (*lpModemStat
&MS_RLSD_ON
)?"MS_RLSD_ON ":"",
2563 (*lpModemStat
&MS_RING_ON
)?"MS_RING_ON ":"",
2564 (*lpModemStat
&MS_DSR_ON
)?"MS_DSR_ON ":"",
2565 (*lpModemStat
&MS_CTS_ON
)?"MS_CTS_ON ":"");
2571 /***********************************************************************
2572 * WaitCommEvent (KERNEL32.719)
2574 BOOL WINAPI
WaitCommEvent(HANDLE hFile
,LPDWORD eventmask
,LPOVERLAPPED overlapped
)
2576 FIXME("(%d %p %p )\n",hFile
, eventmask
,overlapped
);
2580 /***********************************************************************
2581 * GetCommProperties (KERNEL32.286)
2583 * This function fills in a structure with the capabilities of the
2584 * communications port driver.
2588 * TRUE on success, FALSE on failure
2589 * If successful, the lpCommProp structure be filled in with
2590 * properties of the comm port.
2592 BOOL WINAPI
GetCommProperties(
2593 HANDLE hFile
, /* handle of the comm port */
2594 LPCOMMPROP lpCommProp
/* pointer to struct to be filled */
2596 FIXME("(%d %p )\n",hFile
,lpCommProp
);
2601 * These values should be valid for LINUX's serial driver
2602 * FIXME: Perhaps they deserve an #ifdef LINUX
2604 memset(lpCommProp
,0,sizeof(COMMPROP
));
2605 lpCommProp
->wPacketLength
= 1;
2606 lpCommProp
->wPacketVersion
= 1;
2607 lpCommProp
->dwServiceMask
= SP_SERIALCOMM
;
2608 lpCommProp
->dwReserved1
= 0;
2609 lpCommProp
->dwMaxTxQueue
= 4096;
2610 lpCommProp
->dwMaxRxQueue
= 4096;
2611 lpCommProp
->dwMaxBaud
= BAUD_115200
;
2612 lpCommProp
->dwProvSubType
= PST_RS232
;
2613 lpCommProp
->dwProvCapabilities
= PCF_DTRDSR
| PCF_PARITY_CHECK
| PCF_RTSCTS
;
2614 lpCommProp
->dwSettableParams
= SP_BAUD
| SP_DATABITS
| SP_HANDSHAKING
|
2615 SP_PARITY
| SP_PARITY_CHECK
| SP_STOPBITS
;
2616 lpCommProp
->dwSettableBaud
= BAUD_075
| BAUD_110
| BAUD_134_5
| BAUD_150
|
2617 BAUD_300
| BAUD_600
| BAUD_1200
| BAUD_1800
| BAUD_2400
| BAUD_4800
|
2618 BAUD_9600
| BAUD_19200
| BAUD_38400
| BAUD_57600
| BAUD_115200
;
2619 lpCommProp
->wSettableData
= DATABITS_5
| DATABITS_6
| DATABITS_7
| DATABITS_8
;
2620 lpCommProp
->wSettableStopParity
= STOPBITS_10
| STOPBITS_15
| STOPBITS_20
|
2621 PARITY_NONE
| PARITY_ODD
|PARITY_EVEN
| PARITY_MARK
| PARITY_SPACE
;
2622 lpCommProp
->dwCurrentTxQueue
= lpCommProp
->dwMaxTxQueue
;
2623 lpCommProp
->dwCurrentRxQueue
= lpCommProp
->dwMaxRxQueue
;
2628 /***********************************************************************
2630 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
2631 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
2632 * This is dependent on the type of COMM port, but since it is doubtful
2633 * anybody will get around to implementing support for fancy serial
2634 * ports in WINE, this is hardcoded for the time being. The name of
2635 * this DLL should be stored in and read from the system registry in
2636 * the hive HKEY_LOCAL_MACHINE, key
2637 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
2638 * where ???? is the port number... that is determined by PNP
2639 * The DLL should be loaded when the COMM port is opened, and closed
2640 * when the COMM port is closed. - MJM 20 June 2000
2641 ***********************************************************************/
2642 static CHAR lpszSerialUI
[] = "serialui.dll";
2645 /***********************************************************************
2646 * CommConfigDialogA (KERNEL32.140)
2648 * Raises a dialog that allows the user to configure a comm port.
2649 * Fills the COMMCONFIG struct with information specified by the user.
2650 * This function should call a similar routine in the COMM driver...
2654 * TRUE on success, FALSE on failure
2655 * If successful, the lpCommConfig structure will contain a new
2656 * configuration for the comm port, as specified by the user.
2659 * The library with the CommConfigDialog code is never unloaded.
2660 * Perhaps this should be done when the comm port is closed?
2662 BOOL WINAPI
CommConfigDialogA(
2663 LPCSTR lpszDevice
, /* name of communications device */
2664 HANDLE hWnd
, /* parent window for the dialog */
2665 LPCOMMCONFIG lpCommConfig
/* pointer to struct to fill */
2667 FARPROC lpfnCommDialog
;
2668 HMODULE hConfigModule
;
2671 TRACE("(%p %x %p)\n",lpszDevice
, hWnd
, lpCommConfig
);
2673 hConfigModule
= LoadLibraryA(lpszSerialUI
);
2677 lpfnCommDialog
= GetProcAddress(hConfigModule
, (LPCSTR
)3L);
2682 r
= lpfnCommDialog(lpszDevice
,hWnd
,lpCommConfig
);
2684 /* UnloadLibrary(hConfigModule); */
2689 /***********************************************************************
2690 * CommConfigDialogW (KERNEL32.141)
2692 * see CommConfigDialogA for more info
2694 BOOL WINAPI
CommConfigDialogW(
2695 LPCWSTR lpszDevice
, /* name of communications device */
2696 HANDLE hWnd
, /* parent window for the dialog */
2697 LPCOMMCONFIG lpCommConfig
/* pointer to struct to fill */
2702 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
2705 r
= CommConfigDialogA(lpDeviceA
,hWnd
,lpCommConfig
);
2706 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
2710 /***********************************************************************
2711 * GetCommConfig (KERNEL32.283)
2713 * Fill in the COMMCONFIG structure for the comm port hFile
2717 * TRUE on success, FALSE on failure
2718 * If successful, lpCommConfig contains the comm port configuration.
2720 BOOL WINAPI
GetCommConfig(
2722 LPCOMMCONFIG lpCommConfig
2726 TRACE("(%x %p)\n",hFile
,lpCommConfig
);
2728 if(lpCommConfig
== NULL
)
2731 lpCommConfig
->dwSize
= sizeof(COMMCONFIG
);
2732 lpCommConfig
->wVersion
= 1;
2733 lpCommConfig
->wReserved
= 0;
2734 r
= GetCommState(hFile
,&lpCommConfig
->dcb
);
2735 lpCommConfig
->dwProviderSubType
= PST_RS232
;
2736 lpCommConfig
->dwProviderOffset
= 0;
2737 lpCommConfig
->dwProviderSize
= 0;
2742 /***********************************************************************
2743 * SetCommConfig (KERNEL32.617)
2746 BOOL WINAPI
SetCommConfig(
2748 LPCOMMCONFIG lpCommConfig
2752 TRACE("(%x %p)\n",hFile
,lpCommConfig
);
2754 r
= SetCommState(hFile
,&lpCommConfig
->dcb
);
2758 /***********************************************************************
2759 * SetDefaultCommConfigA (KERNEL32.@)
2761 BOOL WINAPI
SetDefaultCommConfigA(
2763 LPCOMMCONFIG lpCommConfig
,
2766 FARPROC lpfnSetDefaultCommConfig
;
2767 HMODULE hConfigModule
;
2770 TRACE("(%p %p %lx)\n",lpszDevice
, lpCommConfig
, dwSize
);
2772 hConfigModule
= LoadLibraryA(lpszSerialUI
);
2776 lpfnSetDefaultCommConfig
= GetProcAddress(hConfigModule
, (LPCSTR
)4L);
2778 if(! lpfnSetDefaultCommConfig
)
2781 r
= lpfnSetDefaultCommConfig(lpszDevice
, lpCommConfig
, dwSize
);
2783 /* UnloadLibrary(hConfigModule); */
2789 /***********************************************************************
2790 * SetDefaultCommConfigW (KERNEL32.639)
2793 BOOL WINAPI
SetDefaultCommConfigW(
2795 LPCOMMCONFIG lpCommConfig
,
2801 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice
),lpCommConfig
,dwSize
);
2803 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
2806 r
= SetDefaultCommConfigA(lpDeviceA
,lpCommConfig
,dwSize
);
2807 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
2812 /***********************************************************************
2813 * GetDefaultCommConfigA (KERNEL32.313)
2815 BOOL WINAPI
GetDefaultCommConfigA(LPCSTR lpszName
,LPCOMMCONFIG lpCC
,
2818 LPDCB lpdcb
= &(lpCC
->dcb
);
2821 if (strncasecmp(lpszName
,"COM",3)) {
2822 ERR("not implemented for <%s>\n", lpszName
);
2826 if (!ValidCOMPort(lpszName
[3]-'1'))
2829 TRACE("(%s %p %ld)\n", lpszName
, lpCC
, *lpdwSize
);
2830 if (*lpdwSize
< sizeof(COMMCONFIG
)) {
2831 *lpdwSize
= sizeof(COMMCONFIG
);
2835 *lpdwSize
= sizeof(COMMCONFIG
);
2837 lpCC
->dwSize
= sizeof(COMMCONFIG
);
2839 lpCC
->dwProviderSubType
= PST_RS232
;
2840 lpCC
->dwProviderOffset
= 0L;
2841 lpCC
->dwProviderSize
= 0L;
2843 (void) sprintf( temp
, "COM%c:38400,n,8,1", lpszName
[3]);
2844 FIXME("setting %s as default\n", temp
);
2846 return BuildCommDCBA( temp
, lpdcb
);
2849 /**************************************************************************
2850 * GetDefaultCommConfigW (KERNEL32.314)
2852 BOOL WINAPI
GetDefaultCommConfigW( LPCWSTR lpszName
,LPCOMMCONFIG lpCC
,
2858 TRACE("(%p,%p,%ld)\n",lpszName
,lpCC
,*lpdwSize
);
2859 lpszNameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName
);
2860 ret
=GetDefaultCommConfigA(lpszNameA
,lpCC
,lpdwSize
);
2861 HeapFree( GetProcessHeap(), 0, lpszNameA
);