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>
70 #include "debugtools.h"
72 DEFAULT_DEBUG_CHANNEL(comm
);
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/cua1 */
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
)
125 if(mstat
& TIOCM_CTS
) tmpmsr
|= MSR_CTS
;
126 if(mstat
& TIOCM_DSR
) tmpmsr
|= MSR_DSR
;
127 if(mstat
& TIOCM_RI
) tmpmsr
|= MSR_RI
;
128 if(mstat
& TIOCM_CAR
) tmpmsr
|= MSR_RLSD
;
129 *pMsr
= (*pMsr
& ~MSR_MASK
) | tmpmsr
;
135 char option
[10], temp
[256], *btemp
;
138 for (x
=0; x
!=MAX_PORTS
; x
++) {
139 strcpy(option
,"COMx");
143 PROFILE_GetWineIniString( "serialports", option
, "*",
144 temp
, sizeof(temp
) );
145 if (!strcmp(temp
, "*") || *temp
== '\0')
146 COM
[x
].devicename
= NULL
;
148 btemp
= strchr(temp
,',');
151 COM
[x
].baudrate
= atoi(btemp
);
153 COM
[x
].baudrate
= -1;
156 if (!S_ISCHR(st
.st_mode
))
157 WARN("Can't use `%s' as %s !\n", temp
, option
);
159 if ((COM
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
160 WARN("Can't malloc for device info!\n");
163 strcpy(COM
[x
].devicename
, temp
);
165 TRACE("%s = %s\n", option
, COM
[x
].devicename
);
168 strcpy(option
, "LPTx");
172 PROFILE_GetWineIniString( "parallelports", option
, "*",
173 temp
, sizeof(temp
) );
174 if (!strcmp(temp
, "*") || *temp
== '\0')
175 LPT
[x
].devicename
= NULL
;
178 if (!S_ISCHR(st
.st_mode
))
179 WARN("Can't use `%s' as %s !\n", temp
, option
);
181 if ((LPT
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
182 WARN("Can't malloc for device info!\n");
185 strcpy(LPT
[x
].devicename
, temp
);
187 TRACE("%s = %s\n", option
, LPT
[x
].devicename
);
194 static struct DosDeviceStruct
*GetDeviceStruct(int fd
)
196 if ((fd
&0x7F)<=MAX_PORTS
) {
197 if (!(fd
&FLAG_LPT
)) {
210 static int GetCommPort_fd(int fd
)
214 for (x
=0; x
<MAX_PORTS
; x
++) {
222 static int ValidCOMPort(int x
)
224 return(x
< MAX_PORTS
? (int) COM
[x
].devicename
: 0);
227 static int ValidLPTPort(int x
)
229 return(x
< MAX_PORTS
? (int) LPT
[x
].devicename
: 0);
232 static int WinError(void)
234 TRACE("errno = %d\n", errno
);
241 static unsigned comm_inbuf(struct DosDeviceStruct
*ptr
)
243 return ((ptr
->ibuf_tail
> ptr
->ibuf_head
) ? ptr
->ibuf_size
: 0)
244 + ptr
->ibuf_head
- ptr
->ibuf_tail
;
247 static unsigned comm_outbuf(struct DosDeviceStruct
*ptr
)
249 return ((ptr
->obuf_tail
> ptr
->obuf_head
) ? ptr
->obuf_size
: 0)
250 + ptr
->obuf_head
- ptr
->obuf_tail
;
253 static int COMM_WhackModem(int fd
, unsigned int andy
, unsigned int orrie
)
255 unsigned int mstat
, okay
;
256 okay
= ioctl(fd
, TIOCMGET
, &mstat
);
257 if (okay
) return okay
;
258 if (andy
) mstat
&= andy
;
260 return ioctl(fd
, TIOCMSET
, &mstat
);
263 static void CALLBACK
comm_notification( ULONG_PTR
private )
265 struct DosDeviceStruct
*ptr
= (struct DosDeviceStruct
*)private;
266 int prev
, bleft
, len
;
268 int cid
= GetCommPort_fd(ptr
->fd
);
270 TRACE("async notification\n");
271 /* read data from comm port */
272 prev
= comm_inbuf(ptr
);
274 bleft
= ((ptr
->ibuf_tail
> ptr
->ibuf_head
) ? (ptr
->ibuf_tail
-1) : ptr
->ibuf_size
)
276 len
= read(ptr
->fd
, ptr
->inbuf
+ ptr
->ibuf_head
, bleft
?bleft
:1);
279 ptr
->commerror
= CE_RXOVER
;
281 /* check for events */
282 if ((ptr
->eventmask
& EV_RXFLAG
) &&
283 memchr(ptr
->inbuf
+ ptr
->ibuf_head
, ptr
->evtchar
, len
)) {
284 *(WORD
*)(unknown
[cid
]) |= EV_RXFLAG
;
287 if (ptr
->eventmask
& EV_RXCHAR
) {
288 *(WORD
*)(unknown
[cid
]) |= EV_RXCHAR
;
291 /* advance buffer position */
292 ptr
->ibuf_head
+= len
;
293 if (ptr
->ibuf_head
>= ptr
->ibuf_size
)
298 /* check for notification */
299 if (ptr
->wnd
&& (ptr
->n_read
>0) && (prev
<ptr
->n_read
) &&
300 (comm_inbuf(ptr
)>=ptr
->n_read
)) {
301 /* passed the receive notification threshold */
305 /* write any TransmitCommChar character */
307 len
= write(ptr
->fd
, &(ptr
->xmit
), 1);
308 if (len
> 0) ptr
->xmit
= -1;
310 /* write from output queue */
311 prev
= comm_outbuf(ptr
);
313 bleft
= ((ptr
->obuf_tail
<= ptr
->obuf_head
) ? ptr
->obuf_head
: ptr
->obuf_size
)
315 len
= bleft
? write(ptr
->fd
, ptr
->outbuf
+ ptr
->obuf_tail
, bleft
) : 0;
317 ptr
->obuf_tail
+= len
;
318 if (ptr
->obuf_tail
>= ptr
->obuf_size
)
321 if (ptr
->obuf_tail
== ptr
->obuf_head
) {
323 SERVICE_Delete( ptr
->s_write
);
324 ptr
->s_write
= INVALID_HANDLE_VALUE
;
326 if (ptr
->eventmask
& EV_TXEMPTY
) {
327 *(WORD
*)(unknown
[cid
]) |= EV_TXEMPTY
;
333 /* check for notification */
334 if (ptr
->wnd
&& (ptr
->n_write
>0) && (prev
>=ptr
->n_write
) &&
335 (comm_outbuf(ptr
)<ptr
->n_write
)) {
336 /* passed the transmit notification threshold */
340 /* send notifications, if any */
341 if (ptr
->wnd
&& mask
) {
342 TRACE("notifying %04x: cid=%d, mask=%02x\n", ptr
->wnd
, cid
, mask
);
343 if (Callout
.PostMessageA
) Callout
.PostMessageA(ptr
->wnd
, WM_COMMNOTIFY
, cid
, mask
);
347 static void comm_waitread(struct DosDeviceStruct
*ptr
)
349 if (ptr
->s_read
!= INVALID_HANDLE_VALUE
) return;
350 ptr
->s_read
= SERVICE_AddObject( FILE_DupUnixHandle( ptr
->fd
,
351 GENERIC_READ
| SYNCHRONIZE
),
356 static void comm_waitwrite(struct DosDeviceStruct
*ptr
)
358 if (ptr
->s_write
!= INVALID_HANDLE_VALUE
) return;
359 ptr
->s_write
= SERVICE_AddObject( FILE_DupUnixHandle( ptr
->fd
,
360 GENERIC_WRITE
| SYNCHRONIZE
),
365 /**************************************************************************
366 * BuildCommDCB16 (USER.213)
368 * According to the ECMA-234 (368.3) the function will return FALSE on
369 * success, otherwise it will return -1.
370 * IF THIS IS NOT CORRECT THE RETURNVALUE CHECK IN BuildCommDCBAndTimeoutsA
373 BOOL16 WINAPI
BuildCommDCB16(LPCSTR device
, LPDCB16 lpdcb
)
375 /* "COM1:9600,n,8,1" */
378 char *ptr
, temp
[256];
380 TRACE("(%s), ptr %p\n", device
, lpdcb
);
382 if (!strncasecmp(device
,"COM",3)) {
383 port
= device
[3] - '0';
387 ERR("BUG ! COM0 can't exist!.\n");
391 if (!ValidCOMPort(port
)) {
392 FIXME("invalid COM port %d?\n",port
);
396 memset(lpdcb
, 0, sizeof(DCB16
)); /* initialize */
403 if (*(device
+4) != ':')
406 strcpy(temp
,device
+5);
407 ptr
= strtok(temp
, ", ");
409 if (COM
[port
].baudrate
> 0)
410 lpdcb
->BaudRate
= COM
[port
].baudrate
;
412 lpdcb
->BaudRate
= atoi(ptr
);
413 TRACE("baudrate (%d)\n", lpdcb
->BaudRate
);
415 ptr
= strtok(NULL
, ", ");
417 *ptr
= toupper(*ptr
);
419 TRACE("parity (%c)\n", *ptr
);
420 lpdcb
->fParity
= TRUE
;
423 lpdcb
->Parity
= NOPARITY
;
424 lpdcb
->fParity
= FALSE
;
427 lpdcb
->Parity
= EVENPARITY
;
430 lpdcb
->Parity
= MARKPARITY
;
433 lpdcb
->Parity
= ODDPARITY
;
436 WARN("Unknown parity `%c'!\n", *ptr
);
440 ptr
= strtok(NULL
, ", ");
441 TRACE("charsize (%c)\n", *ptr
);
442 lpdcb
->ByteSize
= *ptr
- '0';
444 ptr
= strtok(NULL
, ", ");
445 TRACE("stopbits (%c)\n", *ptr
);
448 lpdcb
->StopBits
= ONESTOPBIT
;
451 lpdcb
->StopBits
= TWOSTOPBITS
;
454 WARN("Unknown # of stopbits `%c'!\n", *ptr
);
462 /*****************************************************************************
463 * OpenComm16 (USER.200)
465 INT16 WINAPI
OpenComm16(LPCSTR device
,UINT16 cbInQueue
,UINT16 cbOutQueue
)
469 TRACE("%s, %d, %d\n", device
, cbInQueue
, cbOutQueue
);
471 if (strlen(device
) < 4)
474 port
= device
[3] - '0';
477 ERR("BUG ! COM0 or LPT0 don't exist !\n");
479 if (!strncasecmp(device
,"COM",3)) {
481 TRACE("%s = %s\n", device
, COM
[port
].devicename
);
483 if (!ValidCOMPort(port
))
489 fd
= open(COM
[port
].devicename
, O_RDWR
| O_NONBLOCK
);
491 ERR("Couldn't open %s ! (%s)\n", COM
[port
].devicename
, strerror(errno
));
494 unknown
[port
] = SEGPTR_ALLOC(40);
495 bzero(unknown
[port
],40);
497 COM
[port
].commerror
= 0;
498 COM
[port
].eventmask
= 0;
499 COM
[port
].evtchar
= 0; /* FIXME: default? */
500 /* save terminal state */
501 tcgetattr(fd
,&m_stat
[port
]);
502 /* set default parameters */
503 if(COM
[port
].baudrate
>-1){
505 GetCommState16(port
, &dcb
);
506 dcb
.BaudRate
=COM
[port
].baudrate
;
508 * databits, parity, stopbits
510 SetCommState16( &dcb
);
512 /* init priority characters */
513 COM
[port
].unget
= -1;
515 /* allocate buffers */
516 COM
[port
].ibuf_size
= cbInQueue
;
517 COM
[port
].ibuf_head
= COM
[port
].ibuf_tail
= 0;
518 COM
[port
].obuf_size
= cbOutQueue
;
519 COM
[port
].obuf_head
= COM
[port
].obuf_tail
= 0;
521 COM
[port
].inbuf
= malloc(cbInQueue
);
522 if (COM
[port
].inbuf
) {
523 COM
[port
].outbuf
= malloc(cbOutQueue
);
524 if (!COM
[port
].outbuf
)
525 free(COM
[port
].inbuf
);
526 } else COM
[port
].outbuf
= NULL
;
527 if (!COM
[port
].outbuf
) {
528 /* not enough memory */
529 tcsetattr(COM
[port
].fd
,TCSANOW
,&m_stat
[port
]);
531 ERR("out of memory\n");
535 COM
[port
].s_read
= INVALID_HANDLE_VALUE
;
536 COM
[port
].s_write
= INVALID_HANDLE_VALUE
;
537 comm_waitread( &COM
[port
] );
542 if (!strncasecmp(device
,"LPT",3)) {
544 if (!ValidLPTPort(port
))
550 fd
= open(LPT
[port
].devicename
, O_RDWR
| O_NONBLOCK
, 0);
555 LPT
[port
].commerror
= 0;
556 LPT
[port
].eventmask
= 0;
557 return port
|FLAG_LPT
;
563 /*****************************************************************************
564 * CloseComm16 (USER.207)
566 INT16 WINAPI
CloseComm16(INT16 cid
)
568 struct DosDeviceStruct
*ptr
;
570 TRACE("cid=%d\n", cid
);
571 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
572 FIXME("no cid=%d found!\n", cid
);
575 if (!(cid
&FLAG_LPT
)) {
577 SEGPTR_FREE(unknown
[cid
]); /* [LW] */
579 SERVICE_Delete( COM
[cid
].s_write
);
580 SERVICE_Delete( COM
[cid
].s_read
);
585 /* reset modem lines */
586 tcsetattr(ptr
->fd
,TCSANOW
,&m_stat
[cid
]);
589 if (close(ptr
->fd
) == -1) {
590 ptr
->commerror
= WinError();
591 /* FIXME: should we clear ptr->fd here? */
600 /*****************************************************************************
601 * SetCommBreak16 (USER.210)
603 INT16 WINAPI
SetCommBreak16(INT16 cid
)
605 struct DosDeviceStruct
*ptr
;
607 TRACE("cid=%d\n", cid
);
608 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
609 FIXME("no cid=%d found!\n", cid
);
618 /*****************************************************************************
619 * ClearCommBreak16 (USER.211)
621 INT16 WINAPI
ClearCommBreak16(INT16 cid
)
623 struct DosDeviceStruct
*ptr
;
625 TRACE("cid=%d\n", cid
);
626 if (!(ptr
= GetDeviceStruct(cid
))) {
627 FIXME("no cid=%d found!\n", cid
);
635 /*****************************************************************************
636 * EscapeCommFunction16 (USER.214)
638 LONG WINAPI
EscapeCommFunction16(UINT16 cid
,UINT16 nFunction
)
641 struct DosDeviceStruct
*ptr
;
644 TRACE("cid=%d, function=%d\n", cid
, nFunction
);
645 if ((nFunction
!= GETMAXCOM
) && (nFunction
!= GETMAXLPT
)) {
646 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
647 FIXME("no cid=%d found!\n", cid
);
650 if (tcgetattr(ptr
->fd
,&port
) == -1) {
651 TRACE("tcgetattr failed\n");
652 ptr
->commerror
=WinError();
663 TRACE("GETMAXCOM\n");
664 for (max
= MAX_PORTS
;!COM
[max
].devicename
;max
--)
670 TRACE("GETMAXLPT\n");
671 for (max
= MAX_PORTS
;!LPT
[max
].devicename
;max
--)
673 return FLAG_LPT
+ max
;
677 TRACE("GETBASEIRQ\n");
678 /* FIXME: use tables */
679 /* just fake something for now */
680 if (cid
& FLAG_LPT
) {
681 /* LPT1: irq 7, LPT2: irq 5 */
682 return (cid
& 0x7f) ? 5 : 7;
684 /* COM1: irq 4, COM2: irq 3,
685 COM3: irq 4, COM4: irq 3 */
686 return 4 - (cid
& 1);
693 return COMM_WhackModem(ptr
->fd
, ~TIOCM_DTR
, 0);
698 return COMM_WhackModem(ptr
->fd
, ~TIOCM_RTS
, 0);
704 return COMM_WhackModem(ptr
->fd
, 0, TIOCM_DTR
);
710 return COMM_WhackModem(ptr
->fd
, 0, TIOCM_RTS
);
715 port
.c_iflag
|= IXOFF
;
720 port
.c_iflag
|= IXON
;
724 WARN("(cid=%d,nFunction=%d): Unknown function\n",
729 if (tcsetattr(ptr
->fd
, TCSADRAIN
, &port
) == -1) {
730 ptr
->commerror
= WinError();
738 /*****************************************************************************
739 * FlushComm16 (USER.215)
741 INT16 WINAPI
FlushComm16(INT16 cid
,INT16 fnQueue
)
744 struct DosDeviceStruct
*ptr
;
746 TRACE("cid=%d, queue=%d\n", cid
, fnQueue
);
747 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
748 FIXME("no cid=%d found!\n", cid
);
754 ptr
->obuf_tail
= ptr
->obuf_head
;
758 ptr
->ibuf_head
= ptr
->ibuf_tail
;
761 WARN("(cid=%d,fnQueue=%d):Unknown queue\n",
765 if (tcflush(ptr
->fd
, queue
)) {
766 ptr
->commerror
= WinError();
774 /********************************************************************
775 * GetCommError16 (USER.203)
777 INT16 WINAPI
GetCommError16(INT16 cid
,LPCOMSTAT16 lpStat
)
780 struct DosDeviceStruct
*ptr
;
784 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
785 FIXME("no handle for cid = %0x!.\n",cid
);
789 WARN(" cid %d not comm port\n",cid
);
792 stol
= (unsigned char *)unknown
[cid
] + COMM_MSR_OFFSET
;
793 ioctl(ptr
->fd
,TIOCMGET
,&mstat
);
794 COMM_MSRUpdate( stol
, mstat
);
799 lpStat
->cbOutQue
= comm_outbuf(ptr
);
800 lpStat
->cbInQue
= comm_inbuf(ptr
);
802 TRACE("cid %d, error %d, lpStat %d %d %d stol %x\n",
803 cid
, ptr
->commerror
, lpStat
->status
, lpStat
->cbInQue
,
804 lpStat
->cbOutQue
, *stol
);
807 TRACE("cid %d, error %d, lpStat NULL stol %x\n",
808 cid
, ptr
->commerror
, *stol
);
810 /* Return any errors and clear it */
811 temperror
= ptr
->commerror
;
816 /*****************************************************************************
817 * SetCommEventMask16 (USER.208)
819 SEGPTR WINAPI
SetCommEventMask16(INT16 cid
,UINT16 fuEvtMask
)
821 struct DosDeviceStruct
*ptr
;
826 TRACE("cid %d,mask %d\n",cid
,fuEvtMask
);
827 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
828 FIXME("no handle for cid = %0x!.\n",cid
);
832 ptr
->eventmask
= fuEvtMask
;
834 if ((cid
&FLAG_LPT
) || !ValidCOMPort(cid
)) {
835 WARN(" cid %d not comm port\n",cid
);
838 /* it's a COM port ? -> modify flags */
839 stol
= (unsigned char *)unknown
[cid
] + COMM_MSR_OFFSET
;
840 repid
= ioctl(ptr
->fd
,TIOCMGET
,&mstat
);
841 TRACE(" ioctl %d, msr %x at %p %p\n",repid
,mstat
,stol
,unknown
[cid
]);
842 COMM_MSRUpdate( stol
, mstat
);
844 TRACE(" modem dcd construct %x\n",*stol
);
845 return SEGPTR_GET(unknown
[cid
]);
848 /*****************************************************************************
849 * GetCommEventMask16 (USER.209)
851 UINT16 WINAPI
GetCommEventMask16(INT16 cid
,UINT16 fnEvtClear
)
853 struct DosDeviceStruct
*ptr
;
856 TRACE("cid %d, mask %d\n", cid
, fnEvtClear
);
857 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
858 FIXME("no handle for cid = %0x!.\n",cid
);
862 if ((cid
&FLAG_LPT
) || !ValidCOMPort(cid
)) {
863 WARN(" cid %d not comm port\n",cid
);
867 events
= *(WORD
*)(unknown
[cid
]) & fnEvtClear
;
868 *(WORD
*)(unknown
[cid
]) &= ~fnEvtClear
;
872 /*****************************************************************************
873 * SetCommState16 (USER.201)
875 INT16 WINAPI
SetCommState16(LPDCB16 lpdcb
)
878 struct DosDeviceStruct
*ptr
;
879 int bytesize
, stopbits
;
882 TRACE("cid %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
883 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
884 FIXME("no handle for cid = %0x!.\n",lpdcb
->Id
);
887 if (tcgetattr(ptr
->fd
, &port
) == -1) {
888 ptr
->commerror
= WinError();
893 port
.c_cc
[VTIME
] = 1;
896 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
898 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
900 port
.c_iflag
|= (IGNBRK
);
902 port
.c_oflag
&= ~(OPOST
);
904 port
.c_cflag
&= ~(HUPCL
);
905 port
.c_cflag
|= CLOCAL
| CREAD
;
907 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
908 port
.c_lflag
|= NOFLSH
;
910 TRACE("baudrate %d\n",lpdcb
->BaudRate
);
912 port
.c_cflag
&= ~CBAUD
;
913 switch (lpdcb
->BaudRate
) {
916 port
.c_cflag
|= B110
;
920 port
.c_cflag
|= B300
;
924 port
.c_cflag
|= B600
;
928 port
.c_cflag
|= B1200
;
932 port
.c_cflag
|= B2400
;
936 port
.c_cflag
|= B4800
;
940 port
.c_cflag
|= B9600
;
944 port
.c_cflag
|= B19200
;
948 port
.c_cflag
|= B38400
;
952 port
.c_cflag
|= B57600
;
957 port
.c_cflag
|= B115200
;
961 ptr
->commerror
= IE_BAUDRATE
;
964 #elif !defined(__EMX__)
965 switch (lpdcb
->BaudRate
) {
968 port
.c_ospeed
= B110
;
972 port
.c_ospeed
= B300
;
976 port
.c_ospeed
= B600
;
980 port
.c_ospeed
= B1200
;
984 port
.c_ospeed
= B2400
;
988 port
.c_ospeed
= B4800
;
992 port
.c_ospeed
= B9600
;
996 port
.c_ospeed
= B19200
;
1000 port
.c_ospeed
= B38400
;
1003 ptr
->commerror
= IE_BAUDRATE
;
1006 port
.c_ispeed
= port
.c_ospeed
;
1008 bytesize
=lpdcb
->ByteSize
;
1009 stopbits
=lpdcb
->StopBits
;
1011 TRACE("fParity %d Parity %d\n",lpdcb
->fParity
, lpdcb
->Parity
);
1013 port
.c_cflag
&= ~(PARENB
| PARODD
| CMSPAR
);
1015 port
.c_cflag
&= ~(PARENB
| PARODD
);
1018 port
.c_iflag
|= INPCK
;
1020 port
.c_iflag
&= ~INPCK
;
1021 switch (lpdcb
->Parity
) {
1025 port
.c_cflag
|= (PARENB
| PARODD
);
1028 port
.c_cflag
|= PARENB
;
1031 /* Linux defines mark/space (stick) parity */
1033 port
.c_cflag
|= (PARENB
| CMSPAR
);
1036 port
.c_cflag
|= (PARENB
| PARODD
| CMSPAR
);
1039 /* try the POSIX way */
1041 if( stopbits
== ONESTOPBIT
) {
1042 stopbits
= TWOSTOPBITS
;
1043 port
.c_iflag
&= ~INPCK
;
1045 ptr
->commerror
= IE_BYTESIZE
;
1052 port
.c_iflag
&= ~INPCK
;
1054 ptr
->commerror
= IE_BYTESIZE
;
1060 ptr
->commerror
= IE_BYTESIZE
;
1064 TRACE("bytesize %d\n",bytesize
);
1065 port
.c_cflag
&= ~CSIZE
;
1068 port
.c_cflag
|= CS5
;
1071 port
.c_cflag
|= CS6
;
1074 port
.c_cflag
|= CS7
;
1077 port
.c_cflag
|= CS8
;
1080 ptr
->commerror
= IE_BYTESIZE
;
1084 TRACE("stopbits %d\n",stopbits
);
1088 port
.c_cflag
&= ~CSTOPB
;
1090 case ONE5STOPBITS
: /* wil be selected if bytesize is 5 */
1092 port
.c_cflag
|= CSTOPB
;
1095 ptr
->commerror
= IE_BYTESIZE
;
1100 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
1101 port
.c_cflag
|= CRTSCTS
;
1103 if (lpdcb
->fDtrDisable
)
1104 port
.c_cflag
&= ~CRTSCTS
;
1107 port
.c_iflag
|= IXON
;
1109 port
.c_iflag
&= ~IXON
;
1111 port
.c_iflag
|= IXOFF
;
1113 port
.c_iflag
&= ~IXOFF
;
1115 ptr
->evtchar
= lpdcb
->EvtChar
;
1120 if (tcsetattr(ptr
->fd
, TCSADRAIN
, &port
) == -1) {
1121 ptr
->commerror
= WinError();
1129 /*****************************************************************************
1130 * GetCommState16 (USER.202)
1132 INT16 WINAPI
GetCommState16(INT16 cid
, LPDCB16 lpdcb
)
1135 struct DosDeviceStruct
*ptr
;
1136 struct termios port
;
1138 TRACE("cid %d, ptr %p\n", cid
, lpdcb
);
1139 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1140 FIXME("no handle for cid = %0x!.\n",cid
);
1143 if (tcgetattr(ptr
->fd
, &port
) == -1) {
1144 ptr
->commerror
= WinError();
1150 speed
= port
.c_cflag
& CBAUD
;
1152 speed
= port
.c_ospeed
;
1156 lpdcb
->BaudRate
= 110;
1159 lpdcb
->BaudRate
= 300;
1162 lpdcb
->BaudRate
= 600;
1165 lpdcb
->BaudRate
= 1200;
1168 lpdcb
->BaudRate
= 2400;
1171 lpdcb
->BaudRate
= 4800;
1174 lpdcb
->BaudRate
= 9600;
1177 lpdcb
->BaudRate
= 19200;
1180 lpdcb
->BaudRate
= 38400;
1184 lpdcb
->BaudRate
= 57600;
1189 lpdcb
->BaudRate
= 57601;
1194 switch (port
.c_cflag
& CSIZE
) {
1196 lpdcb
->ByteSize
= 5;
1199 lpdcb
->ByteSize
= 6;
1202 lpdcb
->ByteSize
= 7;
1205 lpdcb
->ByteSize
= 8;
1209 if(port
.c_iflag
& INPCK
)
1210 lpdcb
->fParity
= TRUE
;
1212 lpdcb
->fParity
= FALSE
;
1214 switch (port
.c_cflag
& (PARENB
| PARODD
| CMSPAR
))
1216 switch (port
.c_cflag
& (PARENB
| PARODD
))
1220 lpdcb
->Parity
= NOPARITY
;
1223 lpdcb
->Parity
= EVENPARITY
;
1225 case (PARENB
| PARODD
):
1226 lpdcb
->Parity
= ODDPARITY
;
1229 case (PARENB
| CMSPAR
):
1230 lpdcb
->Parity
= MARKPARITY
;
1232 case (PARENB
| PARODD
| CMSPAR
):
1233 lpdcb
->Parity
= SPACEPARITY
;
1238 if (port
.c_cflag
& CSTOPB
)
1239 if(lpdcb
->ByteSize
== 5)
1240 lpdcb
->StopBits
= ONE5STOPBITS
;
1242 lpdcb
->StopBits
= TWOSTOPBITS
;
1244 lpdcb
->StopBits
= ONESTOPBIT
;
1246 lpdcb
->RlsTimeout
= 50;
1247 lpdcb
->CtsTimeout
= 50;
1248 lpdcb
->DsrTimeout
= 50;
1252 lpdcb
->fDtrDisable
= 0;
1256 if (port
.c_cflag
& CRTSCTS
) {
1257 lpdcb
->fDtrflow
= 1;
1258 lpdcb
->fRtsflow
= 1;
1259 lpdcb
->fOutxCtsFlow
= 1;
1260 lpdcb
->fOutxDsrFlow
= 1;
1263 lpdcb
->fDtrDisable
= 1;
1265 if (port
.c_iflag
& IXON
)
1270 if (port
.c_iflag
& IXOFF
)
1279 lpdcb
->XoffLim
= 10;
1281 lpdcb
->EvtChar
= ptr
->evtchar
;
1287 /*****************************************************************************
1288 * TransmitCommChar16 (USER.206)
1290 INT16 WINAPI
TransmitCommChar16(INT16 cid
,CHAR chTransmit
)
1292 struct DosDeviceStruct
*ptr
;
1294 TRACE("cid %d, data %d \n", cid
, chTransmit
);
1295 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1296 FIXME("no handle for cid = %0x!.\n",cid
);
1300 if (ptr
->suspended
) {
1301 ptr
->commerror
= IE_HARDWARE
;
1305 if (ptr
->xmit
>= 0) {
1306 /* character already queued */
1307 /* FIXME: which error would Windows return? */
1308 ptr
->commerror
= CE_TXFULL
;
1312 if (ptr
->obuf_head
== ptr
->obuf_tail
) {
1313 /* transmit queue empty, try to transmit directly */
1314 if (write(ptr
->fd
, &chTransmit
, 1) == -1) {
1315 /* didn't work, queue it */
1316 ptr
->xmit
= chTransmit
;
1317 comm_waitwrite(ptr
);
1320 /* data in queue, let this char be transmitted next */
1321 ptr
->xmit
= chTransmit
;
1322 comm_waitwrite(ptr
);
1329 /*****************************************************************************
1330 * UngetCommChar16 (USER.212)
1332 INT16 WINAPI
UngetCommChar16(INT16 cid
,CHAR chUnget
)
1334 struct DosDeviceStruct
*ptr
;
1336 TRACE("cid %d (char %d)\n", cid
, chUnget
);
1337 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1338 FIXME("no handle for cid = %0x!.\n",cid
);
1342 if (ptr
->suspended
) {
1343 ptr
->commerror
= IE_HARDWARE
;
1347 if (ptr
->unget
>=0) {
1348 /* character already queued */
1349 /* FIXME: which error would Windows return? */
1350 ptr
->commerror
= CE_RXOVER
;
1354 ptr
->unget
= chUnget
;
1360 /*****************************************************************************
1361 * ReadComm16 (USER.204)
1363 INT16 WINAPI
ReadComm16(INT16 cid
,LPSTR lpvBuf
,INT16 cbRead
)
1366 struct DosDeviceStruct
*ptr
;
1367 LPSTR orgBuf
= lpvBuf
;
1369 TRACE("cid %d, ptr %p, length %d\n", cid
, lpvBuf
, cbRead
);
1370 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1371 FIXME("no handle for cid = %0x!.\n",cid
);
1375 if (ptr
->suspended
) {
1376 ptr
->commerror
= IE_HARDWARE
;
1380 /* read unget character */
1381 if (ptr
->unget
>=0) {
1382 *lpvBuf
++ = ptr
->unget
;
1389 /* read from receive buffer */
1390 while (length
< cbRead
) {
1391 status
= ((ptr
->ibuf_head
< ptr
->ibuf_tail
) ?
1392 ptr
->ibuf_size
: ptr
->ibuf_head
) - ptr
->ibuf_tail
;
1394 if ((cbRead
- length
) < status
)
1395 status
= cbRead
- length
;
1397 memcpy(lpvBuf
, ptr
->inbuf
+ ptr
->ibuf_tail
, status
);
1398 ptr
->ibuf_tail
+= status
;
1399 if (ptr
->ibuf_tail
>= ptr
->ibuf_size
)
1405 TRACE("%.*s\n", length
, orgBuf
);
1410 /*****************************************************************************
1411 * WriteComm16 (USER.205)
1413 INT16 WINAPI
WriteComm16(INT16 cid
, LPSTR lpvBuf
, INT16 cbWrite
)
1416 struct DosDeviceStruct
*ptr
;
1418 TRACE("cid %d, ptr %p, length %d\n",
1419 cid
, lpvBuf
, cbWrite
);
1420 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1421 FIXME("no handle for cid = %0x!.\n",cid
);
1425 if (ptr
->suspended
) {
1426 ptr
->commerror
= IE_HARDWARE
;
1430 TRACE("%.*s\n", cbWrite
, lpvBuf
);
1433 while (length
< cbWrite
) {
1434 if ((ptr
->obuf_head
== ptr
->obuf_tail
) && (ptr
->xmit
< 0)) {
1435 /* no data queued, try to write directly */
1436 status
= write(ptr
->fd
, lpvBuf
, cbWrite
- length
);
1443 /* can't write directly, put into transmit buffer */
1444 status
= ((ptr
->obuf_tail
> ptr
->obuf_head
) ?
1445 (ptr
->obuf_tail
-1) : ptr
->obuf_size
) - ptr
->obuf_head
;
1447 if ((cbWrite
- length
) < status
)
1448 status
= cbWrite
- length
;
1449 memcpy(lpvBuf
, ptr
->outbuf
+ ptr
->obuf_head
, status
);
1450 ptr
->obuf_head
+= status
;
1451 if (ptr
->obuf_head
>= ptr
->obuf_size
)
1455 comm_waitwrite(ptr
);
1462 /***********************************************************************
1463 * EnableCommNotification16 (USER.246)
1465 BOOL16 WINAPI
EnableCommNotification16( INT16 cid
, HWND16 hwnd
,
1466 INT16 cbWriteNotify
, INT16 cbOutQueue
)
1468 struct DosDeviceStruct
*ptr
;
1470 TRACE("(%d, %x, %d, %d)\n", cid
, hwnd
, cbWriteNotify
, cbOutQueue
);
1471 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1472 FIXME("no handle for cid = %0x!.\n",cid
);
1476 ptr
->n_read
= cbWriteNotify
;
1477 ptr
->n_write
= cbOutQueue
;
1482 /**************************************************************************
1483 * BuildCommDCBA (KERNEL32.14)
1485 BOOL WINAPI
BuildCommDCBA(LPCSTR device
,LPDCB lpdcb
)
1487 return BuildCommDCBAndTimeoutsA(device
,lpdcb
,NULL
);
1490 /**************************************************************************
1491 * BuildCommDCBAndTimeoutsA (KERNEL32.15)
1493 BOOL WINAPI
BuildCommDCBAndTimeoutsA(LPCSTR device
, LPDCB lpdcb
,
1494 LPCOMMTIMEOUTS lptimeouts
)
1499 TRACE("(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
1501 if (!strncasecmp(device
,"COM",3)) {
1504 ERR("BUG! COM0 can't exists!.\n");
1507 if (!ValidCOMPort(port
))
1509 if (*(device
+4)!=':')
1511 temp
=(LPSTR
)(device
+5);
1515 lpdcb
->DCBlength
= sizeof(DCB
);
1516 if (strchr(temp
,',')) { /* old style */
1519 char last
=temp
[strlen(temp
)-1];
1521 ret
=BuildCommDCB16(device
,&dcb16
);
1524 lpdcb
->BaudRate
= dcb16
.BaudRate
;
1525 lpdcb
->ByteSize
= dcb16
.ByteSize
;
1526 lpdcb
->fBinary
= dcb16
.fBinary
;
1527 lpdcb
->Parity
= dcb16
.Parity
;
1528 lpdcb
->fParity
= dcb16
.fParity
;
1529 lpdcb
->fNull
= dcb16
.fNull
;
1530 lpdcb
->StopBits
= dcb16
.StopBits
;
1533 lpdcb
->fOutX
= TRUE
;
1534 lpdcb
->fOutxCtsFlow
= FALSE
;
1535 lpdcb
->fOutxDsrFlow
= FALSE
;
1536 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1537 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1538 } else if (last
=='p') {
1539 lpdcb
->fInX
= FALSE
;
1540 lpdcb
->fOutX
= FALSE
;
1541 lpdcb
->fOutxCtsFlow
= TRUE
;
1542 lpdcb
->fOutxDsrFlow
= TRUE
;
1543 lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
;
1544 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
1546 lpdcb
->fInX
= FALSE
;
1547 lpdcb
->fOutX
= FALSE
;
1548 lpdcb
->fOutxCtsFlow
= FALSE
;
1549 lpdcb
->fOutxDsrFlow
= FALSE
;
1550 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1551 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1553 lpdcb
->XonChar
= dcb16
.XonChar
;
1554 lpdcb
->XoffChar
= dcb16
.XoffChar
;
1555 lpdcb
->ErrorChar
= dcb16
.PeChar
;
1556 lpdcb
->fErrorChar
= dcb16
.fPeChar
;
1557 lpdcb
->EofChar
= dcb16
.EofChar
;
1558 lpdcb
->EvtChar
= dcb16
.EvtChar
;
1559 lpdcb
->XonLim
= dcb16
.XonLim
;
1560 lpdcb
->XoffLim
= dcb16
.XoffLim
;
1563 ptr
=strtok(temp
," ");
1568 if (!strncmp("baud=",ptr
,5)) {
1569 if (!sscanf(ptr
+5,"%ld",&x
))
1570 WARN("Couldn't parse %s\n",ptr
);
1571 lpdcb
->BaudRate
= x
;
1574 if (!strncmp("stop=",ptr
,5)) {
1575 if (!sscanf(ptr
+5,"%ld",&x
))
1576 WARN("Couldn't parse %s\n",ptr
);
1577 lpdcb
->StopBits
= x
;
1580 if (!strncmp("data=",ptr
,5)) {
1581 if (!sscanf(ptr
+5,"%ld",&x
))
1582 WARN("Couldn't parse %s\n",ptr
);
1583 lpdcb
->ByteSize
= x
;
1586 if (!strncmp("parity=",ptr
,7)) {
1587 lpdcb
->fParity
= TRUE
;
1590 lpdcb
->fParity
= FALSE
;
1591 lpdcb
->Parity
= NOPARITY
;
1594 lpdcb
->Parity
= EVENPARITY
;
1597 lpdcb
->Parity
= ODDPARITY
;
1600 lpdcb
->Parity
= MARKPARITY
;
1606 ERR("Unhandled specifier '%s', please report.\n",ptr
);
1607 ptr
=strtok(NULL
," ");
1609 if (lpdcb
->BaudRate
==110)
1610 lpdcb
->StopBits
= 2;
1614 /**************************************************************************
1615 * BuildCommDCBAndTimeoutsW (KERNEL32.16)
1617 BOOL WINAPI
BuildCommDCBAndTimeoutsW( LPCWSTR devid
, LPDCB lpdcb
,
1618 LPCOMMTIMEOUTS lptimeouts
)
1623 TRACE("(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
1624 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
1625 ret
=BuildCommDCBAndTimeoutsA(devidA
,lpdcb
,lptimeouts
);
1626 HeapFree( GetProcessHeap(), 0, devidA
);
1630 /**************************************************************************
1631 * BuildCommDCBW (KERNEL32.17)
1633 BOOL WINAPI
BuildCommDCBW(LPCWSTR devid
,LPDCB lpdcb
)
1635 return BuildCommDCBAndTimeoutsW(devid
,lpdcb
,NULL
);
1638 /* FIXME: having these global for win32 for now */
1641 /*****************************************************************************
1642 * SetCommBreak (KERNEL32.449)
1644 BOOL WINAPI
SetCommBreak(HANDLE handle
)
1646 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
1649 fd
= FILE_GetUnixHandle( handle
, GENERIC_WRITE
);
1651 TRACE("FILE_GetUnixHandle failed\n");
1654 result
= ioctl(fd
,TIOCSBRK
,0);
1658 TRACE("ioctl failed\n");
1659 SetLastError(ERROR_NOT_SUPPORTED
);
1664 FIXME("ioctl not available\n");
1665 SetLastError(ERROR_NOT_SUPPORTED
);
1670 /*****************************************************************************
1671 * ClearCommBreak (KERNEL32.20)
1673 BOOL WINAPI
ClearCommBreak(HANDLE handle
)
1675 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
1678 fd
= FILE_GetUnixHandle( handle
, GENERIC_WRITE
);
1680 TRACE("FILE_GetUnixHandle failed\n");
1683 result
= ioctl(fd
,TIOCCBRK
,0);
1687 TRACE("ioctl failed\n");
1688 SetLastError(ERROR_NOT_SUPPORTED
);
1693 FIXME("ioctl not available\n");
1694 SetLastError(ERROR_NOT_SUPPORTED
);
1699 /*****************************************************************************
1700 * EscapeCommFunction (KERNEL32.214)
1702 BOOL WINAPI
EscapeCommFunction(HANDLE handle
,UINT nFunction
)
1704 int fd
,direct
=FALSE
,result
=FALSE
;
1705 struct termios port
;
1707 TRACE("handle %d, function=%d\n", handle
, nFunction
);
1708 fd
= FILE_GetUnixHandle( handle
, GENERIC_WRITE
);
1710 FIXME("handle %d not found.\n",handle
);
1714 if (tcgetattr(fd
,&port
) == -1) {
1715 commerror
=WinError();
1720 switch (nFunction
) {
1729 result
= COMM_WhackModem(fd
, ~TIOCM_DTR
, 0);
1737 result
= COMM_WhackModem(fd
, ~TIOCM_RTS
, 0);
1745 result
= COMM_WhackModem(fd
, 0, TIOCM_DTR
);
1753 result
= COMM_WhackModem(fd
, 0, TIOCM_RTS
);
1759 port
.c_iflag
|= IXOFF
;
1764 port
.c_iflag
|= IXON
;
1767 TRACE("setbreak\n");
1770 result
= ioctl(fd
,TIOCSBRK
,0);
1774 TRACE("clrbreak\n");
1777 result
= ioctl(fd
,TIOCCBRK
,0);
1781 WARN("(handle=%d,nFunction=%d): Unknown function\n",
1787 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
1788 commerror
= WinError();
1798 commerror
=WinError();
1807 /********************************************************************
1808 * PurgeComm (KERNEL32.557)
1810 BOOL WINAPI
PurgeComm( HANDLE handle
, DWORD flags
)
1814 TRACE("handle %d, flags %lx\n", handle
, flags
);
1816 fd
= FILE_GetUnixHandle( handle
, GENERIC_WRITE
);
1818 FIXME("no handle %d found\n",handle
);
1823 ** not exactly sure how these are different
1824 ** Perhaps if we had our own internal queues, one flushes them
1825 ** and the other flushes the kernel's buffers.
1827 if(flags
&PURGE_TXABORT
)
1828 tcflush(fd
,TCOFLUSH
);
1829 if(flags
&PURGE_RXABORT
)
1830 tcflush(fd
,TCIFLUSH
);
1831 if(flags
&PURGE_TXCLEAR
)
1832 tcflush(fd
,TCOFLUSH
);
1833 if(flags
&PURGE_RXCLEAR
)
1834 tcflush(fd
,TCIFLUSH
);
1840 /*****************************************************************************
1841 * ClearCommError (KERNEL32.21)
1843 BOOL WINAPI
ClearCommError(HANDLE handle
,LPDWORD errors
,LPCOMSTAT lpStat
)
1847 fd
=FILE_GetUnixHandle( handle
, GENERIC_READ
);
1850 FIXME("no handle %d found\n",handle
);
1859 if(ioctl(fd
, TIOCOUTQ
, &lpStat
->cbOutQue
))
1860 WARN("ioctl returned error\n");
1862 lpStat
->cbOutQue
= 0; /* FIXME: find a different way to find out */
1865 if(ioctl(fd
, TIOCINQ
, &lpStat
->cbInQue
))
1866 WARN("ioctl returned error\n");
1868 TRACE("handle %d cbInQue = %ld cbOutQue = %ld\n",
1869 handle
, lpStat
->cbInQue
, lpStat
->cbOutQue
);
1878 ** After an asynchronous write opperation, the
1879 ** app will call ClearCommError to see if the
1880 ** results are ready yet. It waits for ERROR_IO_PENDING
1882 commerror
= ERROR_IO_PENDING
;
1887 /*****************************************************************************
1888 * SetupComm (KERNEL32.676)
1890 BOOL WINAPI
SetupComm( HANDLE handle
, DWORD insize
, DWORD outsize
)
1894 FIXME("insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
1895 fd
=FILE_GetUnixHandle( handle
, GENERIC_WRITE
);
1897 FIXME("handle %d not found?\n",handle
);
1904 /*****************************************************************************
1905 * GetCommMask (KERNEL32.156)
1907 BOOL WINAPI
GetCommMask(HANDLE handle
,LPDWORD evtmask
)
1911 TRACE("handle %d, mask %p\n", handle
, evtmask
);
1915 struct get_serial_info_request
*req
= server_alloc_req( sizeof(*req
), 0 );
1916 req
->handle
= handle
;
1917 if ((ret
= !server_call( REQ_GET_SERIAL_INFO
)))
1919 if (evtmask
) *evtmask
= req
->eventmask
;
1926 /*****************************************************************************
1927 * SetCommMask (KERNEL32.451)
1929 BOOL WINAPI
SetCommMask(HANDLE handle
,DWORD evtmask
)
1933 TRACE("handle %d, mask %lx\n", handle
, evtmask
);
1937 struct set_serial_info_request
*req
= server_alloc_req( sizeof(*req
), 0 );
1938 req
->handle
= handle
;
1939 req
->flags
= SERIALINFO_SET_MASK
;
1940 req
->eventmask
= evtmask
;
1941 ret
= !server_call( REQ_SET_SERIAL_INFO
);
1947 /*****************************************************************************
1948 * SetCommState (KERNEL32.452)
1950 BOOL WINAPI
SetCommState(HANDLE handle
,LPDCB lpdcb
)
1952 struct termios port
;
1954 int bytesize
, stopbits
;
1956 TRACE("handle %d, ptr %p\n", handle
, lpdcb
);
1957 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1958 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
1959 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
1960 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
1961 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
1962 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
1964 fd
= FILE_GetUnixHandle( handle
, GENERIC_WRITE
);
1966 FIXME("no handle %d found\n",handle
);
1970 if ((tcgetattr(fd
,&port
)) == -1) {
1971 int save_error
= errno
;
1972 commerror
= WinError();
1974 ERR("tcgetattr error '%s'\n", strerror(save_error
));
1978 port
.c_cc
[VMIN
] = 0;
1979 port
.c_cc
[VTIME
] = 1;
1982 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
1984 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
1986 port
.c_iflag
|= (IGNBRK
);
1988 port
.c_oflag
&= ~(OPOST
);
1990 port
.c_cflag
&= ~(HUPCL
);
1991 port
.c_cflag
|= CLOCAL
| CREAD
;
1993 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
1994 port
.c_lflag
|= NOFLSH
;
1997 ** MJM - removed default baudrate settings
1998 ** TRACE(comm,"baudrate %ld\n",lpdcb->BaudRate);
2001 port
.c_cflag
&= ~CBAUD
;
2002 switch (lpdcb
->BaudRate
) {
2005 port
.c_cflag
|= B110
;
2009 port
.c_cflag
|= B300
;
2013 port
.c_cflag
|= B600
;
2017 port
.c_cflag
|= B1200
;
2021 port
.c_cflag
|= B2400
;
2025 port
.c_cflag
|= B4800
;
2029 port
.c_cflag
|= B9600
;
2033 port
.c_cflag
|= B19200
;
2037 port
.c_cflag
|= B38400
;
2041 port
.c_cflag
|= B57600
;
2046 port
.c_cflag
|= B115200
;
2051 port
.c_cflag
|= B230400
;
2056 port
.c_cflag
|= B460800
;
2060 commerror
= IE_BAUDRATE
;
2062 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
2065 #elif !defined(__EMX__)
2066 switch (lpdcb
->BaudRate
) {
2069 port
.c_ospeed
= B110
;
2073 port
.c_ospeed
= B300
;
2077 port
.c_ospeed
= B600
;
2081 port
.c_ospeed
= B1200
;
2085 port
.c_ospeed
= B2400
;
2089 port
.c_ospeed
= B4800
;
2093 port
.c_ospeed
= B9600
;
2097 port
.c_ospeed
= B19200
;
2101 port
.c_ospeed
= B38400
;
2104 commerror
= IE_BAUDRATE
;
2106 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
2109 port
.c_ispeed
= port
.c_ospeed
;
2111 bytesize
=lpdcb
->ByteSize
;
2112 stopbits
=lpdcb
->StopBits
;
2115 port
.c_cflag
&= ~(PARENB
| PARODD
| CMSPAR
);
2117 port
.c_cflag
&= ~(PARENB
| PARODD
);
2120 port
.c_iflag
|= INPCK
;
2122 port
.c_iflag
&= ~INPCK
;
2123 switch (lpdcb
->Parity
) {
2127 port
.c_cflag
|= (PARENB
| PARODD
);
2130 port
.c_cflag
|= PARENB
;
2133 /* Linux defines mark/space (stick) parity */
2135 port
.c_cflag
|= (PARENB
| CMSPAR
);
2138 port
.c_cflag
|= (PARENB
| PARODD
| CMSPAR
);
2141 /* try the POSIX way */
2143 if( stopbits
== ONESTOPBIT
) {
2144 stopbits
= TWOSTOPBITS
;
2145 port
.c_iflag
&= ~INPCK
;
2147 commerror
= IE_BYTESIZE
;
2149 ERR("Cannot set MARK Parity\n");
2156 port
.c_iflag
&= ~INPCK
;
2158 commerror
= IE_BYTESIZE
;
2160 ERR("Cannot set SPACE Parity\n");
2166 commerror
= IE_BYTESIZE
;
2173 port
.c_cflag
&= ~CSIZE
;
2176 port
.c_cflag
|= CS5
;
2179 port
.c_cflag
|= CS6
;
2182 port
.c_cflag
|= CS7
;
2185 port
.c_cflag
|= CS8
;
2188 commerror
= IE_BYTESIZE
;
2196 port
.c_cflag
&= ~CSTOPB
;
2198 case ONE5STOPBITS
: /* wil be selected if bytesize is 5 */
2200 port
.c_cflag
|= CSTOPB
;
2203 commerror
= IE_BYTESIZE
;
2209 if ( lpdcb
->fOutxCtsFlow
||
2210 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
2211 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
2214 port
.c_cflag
|= CRTSCTS
;
2218 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
2220 port
.c_cflag
&= ~CRTSCTS
;
2221 TRACE("~CRTSCTS\n");
2226 port
.c_iflag
|= IXON
;
2228 port
.c_iflag
&= ~IXON
;
2230 port
.c_iflag
|= IXOFF
;
2232 port
.c_iflag
&= ~IXOFF
;
2234 if (tcsetattr(fd
,TCSANOW
,&port
)==-1) { /* otherwise it hangs with pending input*/
2235 int save_error
=errno
;
2236 commerror
= WinError();
2238 ERR("tcgetattr error '%s'\n", strerror(save_error
));
2248 /*****************************************************************************
2249 * GetCommState (KERNEL32.159)
2251 BOOL WINAPI
GetCommState(HANDLE handle
, LPDCB lpdcb
)
2253 struct termios port
;
2256 TRACE("handle %d, ptr %p\n", handle
, lpdcb
);
2258 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
2261 ERR("FILE_GetUnixHandle failed\n");
2264 if (tcgetattr(fd
, &port
) == -1) {
2265 int save_error
=errno
;
2266 ERR("tcgetattr error '%s'\n", strerror(save_error
));
2267 commerror
= WinError();
2274 speed
= (port
.c_cflag
& CBAUD
);
2276 speed
= (cfgetospeed(&port
));
2280 lpdcb
->BaudRate
= 110;
2283 lpdcb
->BaudRate
= 300;
2286 lpdcb
->BaudRate
= 600;
2289 lpdcb
->BaudRate
= 1200;
2292 lpdcb
->BaudRate
= 2400;
2295 lpdcb
->BaudRate
= 4800;
2298 lpdcb
->BaudRate
= 9600;
2301 lpdcb
->BaudRate
= 19200;
2304 lpdcb
->BaudRate
= 38400;
2308 lpdcb
->BaudRate
= 57600;
2313 lpdcb
->BaudRate
= 115200;
2318 lpdcb
->BaudRate
= 230400;
2323 lpdcb
->BaudRate
= 460800;
2327 ERR("unknown speed %x \n",speed
);
2330 switch (port
.c_cflag
& CSIZE
) {
2332 lpdcb
->ByteSize
= 5;
2335 lpdcb
->ByteSize
= 6;
2338 lpdcb
->ByteSize
= 7;
2341 lpdcb
->ByteSize
= 8;
2344 ERR("unknown size %x \n",port
.c_cflag
& CSIZE
);
2347 if(port
.c_iflag
& INPCK
)
2348 lpdcb
->fParity
= TRUE
;
2350 lpdcb
->fParity
= FALSE
;
2352 switch (port
.c_cflag
& (PARENB
| PARODD
| CMSPAR
))
2354 switch (port
.c_cflag
& (PARENB
| PARODD
))
2358 lpdcb
->Parity
= NOPARITY
;
2361 lpdcb
->Parity
= EVENPARITY
;
2363 case (PARENB
| PARODD
):
2364 lpdcb
->Parity
= ODDPARITY
;
2367 case (PARENB
| CMSPAR
):
2368 lpdcb
->Parity
= MARKPARITY
;
2370 case (PARENB
| PARODD
| CMSPAR
):
2371 lpdcb
->Parity
= SPACEPARITY
;
2376 if (port
.c_cflag
& CSTOPB
)
2377 if(lpdcb
->ByteSize
== 5)
2378 lpdcb
->StopBits
= ONE5STOPBITS
;
2380 lpdcb
->StopBits
= TWOSTOPBITS
;
2382 lpdcb
->StopBits
= ONESTOPBIT
;
2389 if (port
.c_cflag
& CRTSCTS
) {
2390 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
2391 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
2392 lpdcb
->fOutxCtsFlow
= 1;
2393 lpdcb
->fOutxDsrFlow
= 1;
2397 lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
;
2398 lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
;
2400 if (port
.c_iflag
& IXON
)
2405 if (port
.c_iflag
& IXOFF
)
2414 lpdcb
->XoffLim
= 10;
2420 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
2421 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
2422 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
2423 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
2424 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
2425 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
2427 if ( lpdcb
->fOutxCtsFlow
||
2428 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
2429 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
2433 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
2434 TRACE("~CRTSCTS\n");
2440 /*****************************************************************************
2441 * TransmitCommChar (KERNEL32.535)
2443 BOOL WINAPI
TransmitCommChar(HANDLE hComm
,CHAR chTransmit
)
2445 FIXME("(%x,'%c'), use win32 handle!\n",hComm
,chTransmit
);
2449 /*****************************************************************************
2450 * GetCommTimeouts (KERNEL32.160)
2452 BOOL WINAPI
GetCommTimeouts(HANDLE hComm
,LPCOMMTIMEOUTS lptimeouts
)
2456 TRACE("(%x,%p)\n",hComm
,lptimeouts
);
2460 SetLastError(ERROR_INVALID_PARAMETER
);
2466 struct get_serial_info_request
*req
= server_alloc_req( sizeof(*req
), 0 );
2467 req
->handle
= hComm
;
2468 if ((ret
= !server_call( REQ_GET_SERIAL_INFO
)))
2470 lptimeouts
->ReadIntervalTimeout
= req
->readinterval
;
2471 lptimeouts
->ReadTotalTimeoutMultiplier
= req
->readmult
;
2472 lptimeouts
->ReadTotalTimeoutConstant
= req
->readconst
;
2473 lptimeouts
->WriteTotalTimeoutMultiplier
= req
->writemult
;
2474 lptimeouts
->WriteTotalTimeoutConstant
= req
->writeconst
;
2481 /*****************************************************************************
2482 * SetCommTimeouts (KERNEL32.453)
2484 * Sets the timeouts used when reading and writing data to/from COMM ports.
2486 * ReadIntervalTimeout
2487 * - converted and passes to linux kernel as c_cc[VTIME]
2488 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
2489 * - used in ReadFile to calculate GetOverlappedResult's timeout
2490 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
2491 * - used in WriteFile to calculate GetOverlappedResult's timeout
2493 BOOL WINAPI
SetCommTimeouts(
2494 HANDLE hComm
, /* [I] handle of COMM device */
2495 LPCOMMTIMEOUTS lptimeouts
/* [I] pointer to COMMTIMEOUTS structure */
2499 struct termios tios
;
2501 TRACE("(%x,%p)\n",hComm
,lptimeouts
);
2505 SetLastError(ERROR_INVALID_PARAMETER
);
2511 struct set_serial_info_request
*req
= server_alloc_req( sizeof(*req
), 0 );
2512 req
->handle
= hComm
;
2513 req
->flags
= SERIALINFO_SET_TIMEOUTS
;
2514 req
->readinterval
= lptimeouts
->ReadIntervalTimeout
;
2515 req
->readmult
= lptimeouts
->ReadTotalTimeoutMultiplier
;
2516 req
->readconst
= lptimeouts
->ReadTotalTimeoutConstant
;
2517 req
->writemult
= lptimeouts
->WriteTotalTimeoutMultiplier
;
2518 req
->writeconst
= lptimeouts
->WriteTotalTimeoutConstant
;
2519 ret
= !server_call( REQ_SET_SERIAL_INFO
);
2522 if (!ret
) return FALSE
;
2524 /* FIXME: move this stuff to the server */
2525 fd
= FILE_GetUnixHandle( hComm
, GENERIC_WRITE
);
2527 FIXME("no fd for handle = %0x!.\n",hComm
);
2531 if (-1==tcgetattr(fd
,&tios
)) {
2532 FIXME("tcgetattr on fd %d failed!\n",fd
);
2535 /* VTIME is in 1/10 seconds */
2536 tios
.c_cc
[VTIME
]= (lptimeouts
->ReadIntervalTimeout
+99)/100;
2537 if (-1==tcsetattr(fd
,0,&tios
)) {
2538 FIXME("tcsetattr on fd %d failed!\n",fd
);
2545 /***********************************************************************
2546 * GetCommModemStatus (KERNEL32.285)
2548 BOOL WINAPI
GetCommModemStatus(HANDLE hFile
,LPDWORD lpModemStat
)
2550 int fd
,mstat
, result
=FALSE
;
2554 fd
= FILE_GetUnixHandle( hFile
, GENERIC_WRITE
);
2557 result
= ioctl(fd
, TIOCMGET
, &mstat
);
2561 TRACE("ioctl failed\n");
2564 if (mstat
& TIOCM_CTS
)
2565 *lpModemStat
|= MS_CTS_ON
;
2566 if (mstat
& TIOCM_DSR
)
2567 *lpModemStat
|= MS_DSR_ON
;
2568 if (mstat
& TIOCM_RNG
)
2569 *lpModemStat
|= MS_RING_ON
;
2570 /*FIXME: Not really sure about RLSD UB 990810*/
2571 if (mstat
& TIOCM_CAR
)
2572 *lpModemStat
|= MS_RLSD_ON
;
2574 (*lpModemStat
&MS_RLSD_ON
)?"MS_RLSD_ON ":"",
2575 (*lpModemStat
&MS_RING_ON
)?"MS_RING_ON ":"",
2576 (*lpModemStat
&MS_DSR_ON
)?"MS_DSR_ON ":"",
2577 (*lpModemStat
&MS_CTS_ON
)?"MS_CTS_ON ":"");
2584 VOID
COMM_WaitCommEventService(void **args
)
2586 LPOVERLAPPED lpOverlapped
= (LPOVERLAPPED
)args
[0];
2587 LPDWORD buffer
= (LPDWORD
)args
[1];
2588 DWORD events
= (DWORD
)args
[2];
2590 TRACE("overlapped %p wait complete %p <- %lx\n",lpOverlapped
,buffer
,events
);
2594 SetEvent( lpOverlapped
->hEvent
);
2597 /***********************************************************************
2598 * WaitCommEvent (KERNEL32.719)
2600 * Wait until something interesting happens on a COMM port.
2601 * Interesting things (events) are set by calling SetCommMask before
2602 * this function is called.
2605 * TRUE if successful
2608 * The set of detected events will be written to *lpdwEventMask
2609 * ERROR_IO_PENDING will be returned the overlapped structure was passed
2612 * Only supports EV_RXCHAR and EV_TXEMPTY
2614 BOOL WINAPI
WaitCommEvent(
2615 HANDLE hFile
, /* [I] handle of comm port to wait for */
2616 LPDWORD lpdwEvents
, /* [O] event(s) that were detected */
2617 LPOVERLAPPED lpOverlapped
/* [I/O] for Asynchronous waiting */
2623 TRACE("(%x %p %p )\n",hFile
, lpdwEvents
,lpOverlapped
);
2625 /* if there is no overlapped structure, create our own */
2628 ov
.hEvent
= CreateEventA(NULL
,FALSE
,FALSE
,NULL
);
2632 lpov
= lpOverlapped
;
2634 /* check that the overlapped structure has a valid event flag */
2635 if ( (lpov
->hEvent
==0) || (lpov
->hEvent
== INVALID_HANDLE_VALUE
) )
2637 ERR("Couldn't create Event flag for Overlapped structure\n");
2638 SetLastError(ERROR_INVALID_PARAMETER
);
2643 lpov
->InternalHigh
= hFile
;
2645 lpov
->OffsetHigh
= 0;
2647 /* start an ASYNCHRONOUS WaitCommEvent */
2650 struct create_async_request
*req
= server_alloc_req( sizeof(*req
), 0 );
2652 req
->file_handle
= hFile
;
2653 req
->overlapped
= lpov
;
2654 req
->buffer
= lpdwEvents
;
2656 req
->func
= COMM_WaitCommEventService
;
2657 req
->type
= ASYNC_TYPE_WAIT
;
2659 ret
=server_call( REQ_CREATE_ASYNC
);
2661 lpov
->Internal
= req
->ov_handle
;
2668 CloseHandle(lpov
->hEvent
);
2669 TRACE("server call failed.\n");
2673 /* wait ourselves if the caller didn't give us an overlapped struct */
2676 GetOverlappedResult(hFile
, lpov
, NULL
, TRUE
);
2677 CloseHandle(lpov
->hEvent
);
2682 /* caller wants overlapped I/O using GetOverlapped result */
2683 SetLastError(ERROR_IO_PENDING
);
2690 /***********************************************************************
2691 * GetCommProperties (KERNEL32.286)
2693 * This function fills in a structure with the capabilities of the
2694 * communications port driver.
2698 * TRUE on success, FALSE on failure
2699 * If successful, the lpCommProp structure be filled in with
2700 * properties of the comm port.
2702 BOOL WINAPI
GetCommProperties(
2703 HANDLE hFile
, /* handle of the comm port */
2704 LPCOMMPROP lpCommProp
/* pointer to struct to be filled */
2706 FIXME("(%d %p )\n",hFile
,lpCommProp
);
2711 * These values should be valid for LINUX's serial driver
2712 * FIXME: Perhaps they deserve an #ifdef LINUX
2714 memset(lpCommProp
,0,sizeof(COMMPROP
));
2715 lpCommProp
->wPacketLength
= 1;
2716 lpCommProp
->wPacketVersion
= 1;
2717 lpCommProp
->dwServiceMask
= SP_SERIALCOMM
;
2718 lpCommProp
->dwReserved1
= 0;
2719 lpCommProp
->dwMaxTxQueue
= 4096;
2720 lpCommProp
->dwMaxRxQueue
= 4096;
2721 lpCommProp
->dwMaxBaud
= BAUD_115200
;
2722 lpCommProp
->dwProvSubType
= PST_RS232
;
2723 lpCommProp
->dwProvCapabilities
= PCF_DTRDSR
| PCF_PARITY_CHECK
| PCF_RTSCTS
;
2724 lpCommProp
->dwSettableParams
= SP_BAUD
| SP_DATABITS
| SP_HANDSHAKING
|
2725 SP_PARITY
| SP_PARITY_CHECK
| SP_STOPBITS
;
2726 lpCommProp
->dwSettableBaud
= BAUD_075
| BAUD_110
| BAUD_134_5
| BAUD_150
|
2727 BAUD_300
| BAUD_600
| BAUD_1200
| BAUD_1800
| BAUD_2400
| BAUD_4800
|
2728 BAUD_9600
| BAUD_19200
| BAUD_38400
| BAUD_57600
| BAUD_115200
;
2729 lpCommProp
->wSettableData
= DATABITS_5
| DATABITS_6
| DATABITS_7
| DATABITS_8
;
2730 lpCommProp
->wSettableStopParity
= STOPBITS_10
| STOPBITS_15
| STOPBITS_20
|
2731 PARITY_NONE
| PARITY_ODD
|PARITY_EVEN
| PARITY_MARK
| PARITY_SPACE
;
2732 lpCommProp
->dwCurrentTxQueue
= lpCommProp
->dwMaxTxQueue
;
2733 lpCommProp
->dwCurrentRxQueue
= lpCommProp
->dwMaxRxQueue
;
2738 /***********************************************************************
2740 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
2741 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
2742 * This is dependent on the type of COMM port, but since it is doubtful
2743 * anybody will get around to implementing support for fancy serial
2744 * ports in WINE, this is hardcoded for the time being. The name of
2745 * this DLL should be stored in and read from the system registry in
2746 * the hive HKEY_LOCAL_MACHINE, key
2747 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
2748 * where ???? is the port number... that is determined by PNP
2749 * The DLL should be loaded when the COMM port is opened, and closed
2750 * when the COMM port is closed. - MJM 20 June 2000
2751 ***********************************************************************/
2752 static CHAR lpszSerialUI
[] = "serialui.dll";
2755 /***********************************************************************
2756 * CommConfigDialogA (KERNEL32.140)
2758 * Raises a dialog that allows the user to configure a comm port.
2759 * Fills the COMMCONFIG struct with information specified by the user.
2760 * This function should call a similar routine in the COMM driver...
2764 * TRUE on success, FALSE on failure
2765 * If successful, the lpCommConfig structure will contain a new
2766 * configuration for the comm port, as specified by the user.
2769 * The library with the CommConfigDialog code is never unloaded.
2770 * Perhaps this should be done when the comm port is closed?
2772 BOOL WINAPI
CommConfigDialogA(
2773 LPCSTR lpszDevice
, /* name of communications device */
2774 HANDLE hWnd
, /* parent window for the dialog */
2775 LPCOMMCONFIG lpCommConfig
/* pointer to struct to fill */
2777 FARPROC lpfnCommDialog
;
2778 HMODULE hConfigModule
;
2781 TRACE("(%p %x %p)\n",lpszDevice
, hWnd
, lpCommConfig
);
2783 hConfigModule
= LoadLibraryA(lpszSerialUI
);
2787 lpfnCommDialog
= GetProcAddress(hConfigModule
, (LPCSTR
)3L);
2792 r
= lpfnCommDialog(lpszDevice
,hWnd
,lpCommConfig
);
2794 /* UnloadLibrary(hConfigModule); */
2799 /***********************************************************************
2800 * CommConfigDialogW (KERNEL32.141)
2802 * see CommConfigDialogA for more info
2804 BOOL WINAPI
CommConfigDialogW(
2805 LPCWSTR lpszDevice
, /* name of communications device */
2806 HANDLE hWnd
, /* parent window for the dialog */
2807 LPCOMMCONFIG lpCommConfig
/* pointer to struct to fill */
2812 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
2815 r
= CommConfigDialogA(lpDeviceA
,hWnd
,lpCommConfig
);
2816 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
2820 /***********************************************************************
2821 * GetCommConfig (KERNEL32.283)
2823 * Fill in the COMMCONFIG structure for the comm port hFile
2827 * TRUE on success, FALSE on failure
2828 * If successful, lpCommConfig contains the comm port configuration.
2830 BOOL WINAPI
GetCommConfig(
2832 LPCOMMCONFIG lpCommConfig
2836 TRACE("(%x %p)\n",hFile
,lpCommConfig
);
2838 if(lpCommConfig
== NULL
)
2841 lpCommConfig
->dwSize
= sizeof(COMMCONFIG
);
2842 lpCommConfig
->wVersion
= 1;
2843 lpCommConfig
->wReserved
= 0;
2844 r
= GetCommState(hFile
,&lpCommConfig
->dcb
);
2845 lpCommConfig
->dwProviderSubType
= PST_RS232
;
2846 lpCommConfig
->dwProviderOffset
= 0;
2847 lpCommConfig
->dwProviderSize
= 0;
2852 /***********************************************************************
2853 * SetCommConfig (KERNEL32.617)
2856 BOOL WINAPI
SetCommConfig(
2858 LPCOMMCONFIG lpCommConfig
2862 TRACE("(%x %p)\n",hFile
,lpCommConfig
);
2864 r
= SetCommState(hFile
,&lpCommConfig
->dcb
);
2868 /***********************************************************************
2869 * SetDefaultCommConfigA (KERNEL32.638)
2871 BOOL WINAPI
SetDefaultCommConfigA(
2873 LPCOMMCONFIG lpCommConfig
,
2876 FARPROC lpfnSetDefaultCommConfig
;
2877 HMODULE hConfigModule
;
2880 TRACE("(%p %p %lx)\n",lpszDevice
, lpCommConfig
, dwSize
);
2882 hConfigModule
= LoadLibraryA(lpszSerialUI
);
2886 lpfnSetDefaultCommConfig
= GetProcAddress(hConfigModule
, (LPCSTR
)4L);
2888 if(! lpfnSetDefaultCommConfig
)
2891 r
= lpfnSetDefaultCommConfig(lpszDevice
, lpCommConfig
, dwSize
);
2893 /* UnloadLibrary(hConfigModule); */
2899 /***********************************************************************
2900 * SetDefaultCommConfigW (KERNEL32.639)
2903 BOOL WINAPI
SetDefaultCommConfigW(
2905 LPCOMMCONFIG lpCommConfig
,
2911 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice
),lpCommConfig
,dwSize
);
2913 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
2916 r
= SetDefaultCommConfigA(lpDeviceA
,lpCommConfig
,dwSize
);
2917 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
2922 /***********************************************************************
2923 * GetDefaultCommConfigA (KERNEL32.313)
2925 BOOL WINAPI
GetDefaultCommConfigA(LPCSTR lpszName
,LPCOMMCONFIG lpCC
,
2928 LPDCB lpdcb
= &(lpCC
->dcb
);
2931 if (strncasecmp(lpszName
,"COM",3)) {
2932 ERR("not implemented for <%s>\n", lpszName
);
2936 if (!ValidCOMPort(lpszName
[3]-'1'))
2939 TRACE("(%s %p %ld)\n", lpszName
, lpCC
, *lpdwSize
);
2940 if (*lpdwSize
< sizeof(COMMCONFIG
)) {
2941 *lpdwSize
= sizeof(COMMCONFIG
);
2945 *lpdwSize
= sizeof(COMMCONFIG
);
2947 lpCC
->dwSize
= sizeof(COMMCONFIG
);
2949 lpCC
->dwProviderSubType
= PST_RS232
;
2950 lpCC
->dwProviderOffset
= 0L;
2951 lpCC
->dwProviderSize
= 0L;
2953 (void) sprintf( temp
, "COM%c:38400,n,8,1", lpszName
[3]);
2954 FIXME("setting %s as default\n", temp
);
2956 return BuildCommDCBA( temp
, lpdcb
);
2959 /**************************************************************************
2960 * GetDefaultCommConfigW (KERNEL32.314)
2962 BOOL WINAPI
GetDefaultCommConfigW( LPCWSTR lpszName
,LPCOMMCONFIG lpCC
,
2968 TRACE("(%p,%p,%ld)\n",lpszName
,lpCC
,*lpdwSize
);
2969 lpszNameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName
);
2970 ret
=GetDefaultCommConfigA(lpszNameA
,lpCC
,lpdwSize
);
2971 HeapFree( GetProcessHeap(), 0, lpszNameA
);