2 * DEC 93 Erik Bos <erik@xs4all.nl>
4 * Copyright 1996 Marcus Meissner
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Apr 3, 1999. Lawson Whitney <lawson_whitney@juno.com>
23 * - Fixed the modem control part of EscapeCommFunction16.
25 * Mar 31, 1999. Ove Kåven <ovek@arcticnet.no>
26 * - Implemented buffers and EnableCommNotification.
28 * Mar 3, 1999. Ove Kåven <ovek@arcticnet.no>
29 * - Use port indices instead of unixfds for win16
30 * - Moved things around (separated win16 and win32 routines)
31 * - Added some hints on how to implement buffers and EnableCommNotification.
33 * Oktober 98, Rein Klazes [RHK]
34 * A program that wants to monitor the modem status line (RLSD/DCD) may
35 * poll the modem status register in the commMask structure. I update the bit
36 * in GetCommError, waiting for an implementation of communication events.
38 * July 6, 1998. Fixes and comments by Valentijn Sessink
39 * <vsessink@ic.uva.nl> [V]
41 * August 12, 1997. Take a bash at SetCommEventMask - Lawson Whitney
42 * <lawson_whitney@juno.com>
44 * May 26, 1997. Fixes and comments by Rick Richardson <rick@dgii.com> [RER]
45 * - ptr->fd wasn't getting cleared on close.
46 * - GetCommEventMask() and GetCommError() didn't do much of anything.
47 * IMHO, they are still wrong, but they at least implement the RXCHAR
48 * event and return I/O queue sizes, which makes the app I'm interested
49 * in (analog devices EZKIT DSP development system) work.
53 #include "wine/port.h"
69 #ifdef HAVE_SYS_FILIO_H
70 # include <sys/filio.h>
72 #ifdef HAVE_SYS_IOCTL_H
73 #include <sys/ioctl.h>
78 #ifdef HAVE_SYS_POLL_H
79 # include <sys/poll.h>
81 #ifdef HAVE_SYS_MODEM_H
82 # include <sys/modem.h>
84 #ifdef HAVE_SYS_STRTIO_H
85 # include <sys/strtio.h>
88 #define NONAMELESSUNION
89 #define NONAMELESSSTRUCT
95 #include "wine/server.h"
100 #include "wine/debug.h"
102 #ifdef HAVE_LINUX_SERIAL_H
103 #include <linux/serial.h>
106 WINE_DEFAULT_DEBUG_CHANNEL(comm
);
108 /***********************************************************************
109 * Asynchronous I/O for asynchronous wait requests *
112 static DWORD
commio_get_async_count (const async_private
*ovp
);
113 static void commio_async_cleanup (async_private
*ovp
);
115 static async_ops commio_async_ops
=
117 commio_get_async_count
, /* get_count */
118 NULL
, /* call_completion */
119 commio_async_cleanup
/* cleanup */
122 typedef struct async_commio
124 struct async_private async
;
128 static DWORD
commio_get_async_count (const struct async_private
*ovp
)
133 static void commio_async_cleanup (async_private
*ovp
)
135 HeapFree(GetProcessHeap(), 0, ovp
);
138 /***********************************************************************/
140 #if !defined(TIOCINQ) && defined(FIONREAD)
141 #define TIOCINQ FIONREAD
144 static int COMM_WhackModem(int fd
, unsigned int andy
, unsigned int orrie
)
147 unsigned int mstat
, okay
;
148 okay
= ioctl(fd
, TIOCMGET
, &mstat
);
149 if (okay
) return okay
;
150 if (andy
) mstat
&= andy
;
152 return ioctl(fd
, TIOCMSET
, &mstat
);
158 /***********************************************************************
159 * COMM_Parse* (Internal)
161 * The following COMM_Parse* functions are used by the BuildCommDCB
162 * functions to help parse the various parts of the device control string.
164 static LPCSTR
COMM_ParseStart(LPCSTR ptr
)
166 /* The device control string may optionally start with "COMx" followed
167 by an optional ':' and spaces. */
168 if(!strncasecmp(ptr
, "COM", 3))
172 /* Allow any com port above 0 as Win 9x does (NT only allows
173 values for com ports which are actually present) */
174 if(*ptr
< '1' || *ptr
> '9')
177 /* Advance pointer past port number */
178 while(*ptr
>= '0' && *ptr
<= '9') ptr
++;
180 /* The com port number must be followed by a ':' or ' ' */
181 if(*ptr
!= ':' && *ptr
!= ' ')
184 /* Advance pointer to beginning of next parameter */
185 while(*ptr
== ' ') ptr
++;
189 while(*ptr
== ' ') ptr
++;
192 /* The device control string must not start with a space. */
199 static LPCSTR
COMM_ParseNumber(LPCSTR ptr
, LPDWORD lpnumber
)
201 if(*ptr
< '0' || *ptr
> '9') return NULL
;
202 if(!sscanf(ptr
, "%lu", lpnumber
)) return NULL
;
203 while(*ptr
>= '0' && *ptr
<= '9') ptr
++;
207 static LPCSTR
COMM_ParseParity(LPCSTR ptr
, LPBYTE lpparity
)
209 /* Contrary to what you might expect, Windows only sets the Parity
210 member of DCB and not fParity even when parity is specified in the
211 device control string */
213 switch(toupper(*ptr
++))
216 *lpparity
= EVENPARITY
;
219 *lpparity
= MARKPARITY
;
222 *lpparity
= NOPARITY
;
225 *lpparity
= ODDPARITY
;
228 *lpparity
= SPACEPARITY
;
237 static LPCSTR
COMM_ParseByteSize(LPCSTR ptr
, LPBYTE lpbytesize
)
241 if(!(ptr
= COMM_ParseNumber(ptr
, &temp
)))
244 if(temp
>= 5 && temp
<= 8)
253 static LPCSTR
COMM_ParseStopBits(LPCSTR ptr
, LPBYTE lpstopbits
)
257 if(!strncmp("1.5", ptr
, 3))
260 *lpstopbits
= ONE5STOPBITS
;
264 if(!(ptr
= COMM_ParseNumber(ptr
, &temp
)))
268 *lpstopbits
= ONESTOPBIT
;
270 *lpstopbits
= TWOSTOPBITS
;
278 static LPCSTR
COMM_ParseOnOff(LPCSTR ptr
, LPDWORD lponoff
)
280 if(!strncasecmp("on", ptr
, 2))
285 else if(!strncasecmp("off", ptr
, 3))
296 /***********************************************************************
297 * COMM_BuildOldCommDCB (Internal)
299 * Build a DCB using the old style settings string eg: "96,n,8,1"
301 static BOOL
COMM_BuildOldCommDCB(LPCSTR device
, LPDCB lpdcb
)
305 if(!(device
= COMM_ParseNumber(device
, &lpdcb
->BaudRate
)))
308 switch(lpdcb
->BaudRate
)
313 lpdcb
->BaudRate
*= 10;
319 lpdcb
->BaudRate
*= 100;
322 lpdcb
->BaudRate
= 19200;
326 while(*device
== ' ') device
++;
327 if(*device
++ != ',') return FALSE
;
328 while(*device
== ' ') device
++;
330 if(!(device
= COMM_ParseParity(device
, &lpdcb
->Parity
)))
333 while(*device
== ' ') device
++;
334 if(*device
++ != ',') return FALSE
;
335 while(*device
== ' ') device
++;
337 if(!(device
= COMM_ParseByteSize(device
, &lpdcb
->ByteSize
)))
340 while(*device
== ' ') device
++;
341 if(*device
++ != ',') return FALSE
;
342 while(*device
== ' ') device
++;
344 if(!(device
= COMM_ParseStopBits(device
, &lpdcb
->StopBits
)))
347 /* The last parameter for flow control is optional. */
348 while(*device
== ' ') device
++;
352 while(*device
== ' ') device
++;
353 if(*device
) last
= toupper(*device
++);
354 while(*device
== ' ') device
++;
357 /* Win NT sets the flow control members based on (or lack of) the last
358 parameter. Win 9x does not set these members. */
363 lpdcb
->fOutX
= FALSE
;
364 lpdcb
->fOutxCtsFlow
= FALSE
;
365 lpdcb
->fOutxDsrFlow
= FALSE
;
366 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
367 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
372 lpdcb
->fOutxCtsFlow
= FALSE
;
373 lpdcb
->fOutxDsrFlow
= FALSE
;
374 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
375 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
379 lpdcb
->fOutX
= FALSE
;
380 lpdcb
->fOutxCtsFlow
= TRUE
;
381 lpdcb
->fOutxDsrFlow
= TRUE
;
382 lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
;
383 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
389 /* This should be the end of the string. */
390 if(*device
) return FALSE
;
395 /***********************************************************************
396 * COMM_BuildNewCommDCB (Internal)
398 * Build a DCB using the new style settings string.
399 * eg: "baud=9600 parity=n data=8 stop=1 xon=on to=on"
401 static BOOL
COMM_BuildNewCommDCB(LPCSTR device
, LPDCB lpdcb
, LPCOMMTIMEOUTS lptimeouts
)
404 BOOL baud
= FALSE
, stop
= FALSE
;
408 while(*device
== ' ') device
++;
410 if(!strncasecmp("baud=", device
, 5))
414 if(!(device
= COMM_ParseNumber(device
+ 5, &lpdcb
->BaudRate
)))
417 else if(!strncasecmp("parity=", device
, 7))
419 if(!(device
= COMM_ParseParity(device
+ 7, &lpdcb
->Parity
)))
422 else if(!strncasecmp("data=", device
, 5))
424 if(!(device
= COMM_ParseByteSize(device
+ 5, &lpdcb
->ByteSize
)))
427 else if(!strncasecmp("stop=", device
, 5))
431 if(!(device
= COMM_ParseStopBits(device
+ 5, &lpdcb
->StopBits
)))
434 else if(!strncasecmp("to=", device
, 3))
436 if(!(device
= COMM_ParseOnOff(device
+ 3, &temp
)))
439 lptimeouts
->ReadIntervalTimeout
= 0;
440 lptimeouts
->ReadTotalTimeoutMultiplier
= 0;
441 lptimeouts
->ReadTotalTimeoutConstant
= 0;
442 lptimeouts
->WriteTotalTimeoutMultiplier
= 0;
443 lptimeouts
->WriteTotalTimeoutConstant
= temp
? 60000 : 0;
445 else if(!strncasecmp("xon=", device
, 4))
447 if(!(device
= COMM_ParseOnOff(device
+ 4, &temp
)))
453 else if(!strncasecmp("odsr=", device
, 5))
455 if(!(device
= COMM_ParseOnOff(device
+ 5, &temp
)))
458 lpdcb
->fOutxDsrFlow
= temp
;
460 else if(!strncasecmp("octs=", device
, 5))
462 if(!(device
= COMM_ParseOnOff(device
+ 5, &temp
)))
465 lpdcb
->fOutxCtsFlow
= temp
;
467 else if(!strncasecmp("dtr=", device
, 4))
469 if(!(device
= COMM_ParseOnOff(device
+ 4, &temp
)))
472 lpdcb
->fDtrControl
= temp
;
474 else if(!strncasecmp("rts=", device
, 4))
476 if(!(device
= COMM_ParseOnOff(device
+ 4, &temp
)))
479 lpdcb
->fRtsControl
= temp
;
481 else if(!strncasecmp("idsr=", device
, 5))
483 if(!(device
= COMM_ParseOnOff(device
+ 5, &temp
)))
486 /* Win NT sets the fDsrSensitivity member based on the
487 idsr parameter. Win 9x sets fOutxDsrFlow instead. */
488 lpdcb
->fDsrSensitivity
= temp
;
493 /* After the above parsing, the next character (if not the end of
494 the string) should be a space */
495 if(*device
&& *device
!= ' ')
499 /* If stop bits were not specified, a default is always supplied. */
502 if(baud
&& lpdcb
->BaudRate
== 110)
503 lpdcb
->StopBits
= TWOSTOPBITS
;
505 lpdcb
->StopBits
= ONESTOPBIT
;
511 /**************************************************************************
512 * BuildCommDCBA (KERNEL32.@)
514 * Updates a device control block data structure with values from an
515 * ascii device control string. The device control string has two forms
516 * normal and extended, it must be exclusively in one or the other form.
520 * True on success, false on a malformed control string.
522 BOOL WINAPI
BuildCommDCBA(
523 LPCSTR device
, /* [in] The ascii device control string used to update the DCB. */
524 LPDCB lpdcb
) /* [out] The device control block to be updated. */
526 return BuildCommDCBAndTimeoutsA(device
,lpdcb
,NULL
);
529 /**************************************************************************
530 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
532 * Updates a device control block data structure with values from an
533 * ascii device control string. Taking timeout values from a timeouts
534 * struct if desired by the control string.
538 * True on success, false bad handles etc
540 BOOL WINAPI
BuildCommDCBAndTimeoutsA(
541 LPCSTR device
, /* [in] The ascii device control string. */
542 LPDCB lpdcb
, /* [out] The device control block to be updated. */
543 LPCOMMTIMEOUTS lptimeouts
) /* [in] The COMMTIMEOUTS structure to be updated. */
546 COMMTIMEOUTS timeouts
;
550 TRACE("(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
552 /* Set DCBlength. (Windows NT does not do this, but 9x does) */
553 lpdcb
->DCBlength
= sizeof(DCB
);
555 /* Make a copy of the original data structures to work with since if
556 if there is an error in the device control string the originals
557 should not be modified (except possibly DCBlength) */
558 memcpy(&dcb
, lpdcb
, sizeof(DCB
));
559 if(lptimeouts
) memcpy(&timeouts
, lptimeouts
, sizeof(COMMTIMEOUTS
));
561 ptr
= COMM_ParseStart(ptr
);
565 else if(strchr(ptr
, ','))
566 result
= COMM_BuildOldCommDCB(ptr
, &dcb
);
568 result
= COMM_BuildNewCommDCB(ptr
, &dcb
, &timeouts
);
572 memcpy(lpdcb
, &dcb
, sizeof(DCB
));
573 if(lptimeouts
) memcpy(lptimeouts
, &timeouts
, sizeof(COMMTIMEOUTS
));
578 WARN("Invalid device control string: %s\n", device
);
579 SetLastError(ERROR_INVALID_PARAMETER
);
584 /**************************************************************************
585 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
587 * Updates a device control block data structure with values from an
588 * unicode device control string. Taking timeout values from a timeouts
589 * struct if desired by the control string.
593 * True on success, false bad handles etc.
595 BOOL WINAPI
BuildCommDCBAndTimeoutsW(
596 LPCWSTR devid
, /* [in] The unicode device control string. */
597 LPDCB lpdcb
, /* [out] The device control block to be updated. */
598 LPCOMMTIMEOUTS lptimeouts
) /* [in] The COMMTIMEOUTS structure to be updated. */
603 TRACE("(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
604 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
607 ret
=BuildCommDCBAndTimeoutsA(devidA
,lpdcb
,lptimeouts
);
608 HeapFree( GetProcessHeap(), 0, devidA
);
613 /**************************************************************************
614 * BuildCommDCBW (KERNEL32.@)
616 * Updates a device control block structure with values from an
617 * unicode device control string. The device control string has two forms
618 * normal and extended, it must be exclusively in one or the other form.
622 * True on success, false on an malformed control string.
624 BOOL WINAPI
BuildCommDCBW(
625 LPCWSTR devid
, /* [in] The unicode device control string. */
626 LPDCB lpdcb
) /* [out] The device control block to be updated. */
628 return BuildCommDCBAndTimeoutsW(devid
,lpdcb
,NULL
);
631 static BOOL
COMM_SetCommError(HANDLE handle
, DWORD error
)
635 SERVER_START_REQ( set_serial_info
)
637 req
->handle
= handle
;
638 req
->flags
= SERIALINFO_SET_ERROR
;
639 req
->commerror
= error
;
640 ret
= !wine_server_call_err( req
);
646 static BOOL
COMM_GetCommError(HANDLE handle
, LPDWORD lperror
)
653 SERVER_START_REQ( get_serial_info
)
655 req
->handle
= handle
;
656 ret
= !wine_server_call_err( req
);
657 *lperror
= reply
->commerror
;
664 /*****************************************************************************
665 * SetCommBreak (KERNEL32.@)
667 * Halts the transmission of characters to a communications device.
671 * True on success, and false if the communications device could not be found,
672 * the control is not supported.
676 * Only TIOCSBRK and TIOCCBRK are supported.
678 BOOL WINAPI
SetCommBreak(
679 HANDLE handle
) /* [in] The communictions device to suspend. */
681 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
684 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
686 TRACE("FILE_GetUnixHandle failed\n");
689 result
= ioctl(fd
,TIOCSBRK
,0);
693 TRACE("ioctl failed\n");
694 SetLastError(ERROR_NOT_SUPPORTED
);
699 FIXME("ioctl not available\n");
700 SetLastError(ERROR_NOT_SUPPORTED
);
705 /*****************************************************************************
706 * ClearCommBreak (KERNEL32.@)
708 * Resumes character transmission from a communication device.
712 * True on success and false if the communications device could not be found.
716 * Only TIOCSBRK and TIOCCBRK are supported.
718 BOOL WINAPI
ClearCommBreak(
719 HANDLE handle
) /* [in] The halted communication device whose character transmission is to be resumed. */
721 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
724 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
726 TRACE("FILE_GetUnixHandle failed\n");
729 result
= ioctl(fd
,TIOCCBRK
,0);
733 TRACE("ioctl failed\n");
734 SetLastError(ERROR_NOT_SUPPORTED
);
739 FIXME("ioctl not available\n");
740 SetLastError(ERROR_NOT_SUPPORTED
);
745 /*****************************************************************************
746 * EscapeCommFunction (KERNEL32.@)
748 * Directs a communication device to perform an extended function.
752 * True or requested data on successful completion of the command,
753 * false if the device is not present cannot execute the command
754 * or the command failed.
756 BOOL WINAPI
EscapeCommFunction(
757 HANDLE handle
, /* [in] The communication device to perform the extended function. */
758 UINT nFunction
) /* [in] The extended function to be performed. */
760 int fd
,direct
=FALSE
,result
=FALSE
;
763 TRACE("handle %p, function=%d\n", handle
, nFunction
);
764 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
766 FIXME("handle %p not found.\n",handle
);
770 if (tcgetattr(fd
,&port
) == -1) {
771 COMM_SetCommError(handle
,CE_IOE
);
785 result
= COMM_WhackModem(fd
, ~TIOCM_DTR
, 0);
793 result
= COMM_WhackModem(fd
, ~TIOCM_RTS
, 0);
801 result
= COMM_WhackModem(fd
, 0, TIOCM_DTR
);
809 result
= COMM_WhackModem(fd
, 0, TIOCM_RTS
);
815 port
.c_iflag
|= IXOFF
;
820 port
.c_iflag
|= IXON
;
826 result
= ioctl(fd
,TIOCSBRK
,0);
833 result
= ioctl(fd
,TIOCCBRK
,0);
837 WARN("(handle=%p,nFunction=%d): Unknown function\n",
843 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
845 COMM_SetCommError(handle
,CE_IOE
);
854 COMM_SetCommError(handle
,CE_IOE
);
863 /********************************************************************
864 * PurgeComm (KERNEL32.@)
866 * Terminates pending operations and/or discards buffers on a
867 * communication resource.
871 * True on success and false if the communications handle is bad.
873 BOOL WINAPI
PurgeComm(
874 HANDLE handle
, /* [in] The communication resource to be purged. */
875 DWORD flags
) /* [in] Flags for clear pending/buffer on input/output. */
879 TRACE("handle %p, flags %lx\n", handle
, flags
);
881 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
883 FIXME("no handle %p found\n",handle
);
888 ** not exactly sure how these are different
889 ** Perhaps if we had our own internal queues, one flushes them
890 ** and the other flushes the kernel's buffers.
892 if(flags
&PURGE_TXABORT
)
893 tcflush(fd
,TCOFLUSH
);
894 if(flags
&PURGE_RXABORT
)
895 tcflush(fd
,TCIFLUSH
);
896 if(flags
&PURGE_TXCLEAR
)
897 tcflush(fd
,TCOFLUSH
);
898 if(flags
&PURGE_RXCLEAR
)
899 tcflush(fd
,TCIFLUSH
);
905 /*****************************************************************************
906 * ClearCommError (KERNEL32.@)
908 * Enables further I/O operations on a communications resource after
909 * supplying error and current status information.
913 * True on success, false if the communication resource handle is bad.
915 BOOL WINAPI
ClearCommError(
916 HANDLE handle
, /* [in] The communication resource with the error. */
917 LPDWORD errors
, /* [out] Flags indicating error the resource experienced. */
918 LPCOMSTAT lpStat
) /* [out] The status of the communication resource. */
922 fd
=FILE_GetUnixHandle( handle
, GENERIC_READ
);
925 FIXME("no handle %p found\n",handle
);
931 lpStat
->fCtsHold
= 0;
932 lpStat
->fDsrHold
= 0;
933 lpStat
->fRlsdHold
= 0;
934 lpStat
->fXoffHold
= 0;
935 lpStat
->fXoffSent
= 0;
938 lpStat
->fReserved
= 0;
941 if(ioctl(fd
, TIOCOUTQ
, &lpStat
->cbOutQue
))
942 WARN("ioctl returned error\n");
944 lpStat
->cbOutQue
= 0; /* FIXME: find a different way to find out */
948 if(ioctl(fd
, TIOCINQ
, &lpStat
->cbInQue
))
949 WARN("ioctl returned error\n");
952 TRACE("handle %p cbInQue = %ld cbOutQue = %ld\n",
953 handle
, lpStat
->cbInQue
, lpStat
->cbOutQue
);
958 COMM_GetCommError(handle
, errors
);
959 COMM_SetCommError(handle
, 0);
964 /*****************************************************************************
965 * SetupComm (KERNEL32.@)
967 * Called after CreateFile to hint to the communication resource to use
968 * specified sizes for input and output buffers rather than the default values.
972 * True if successful, false if the communications resource handle is bad.
978 BOOL WINAPI
SetupComm(
979 HANDLE handle
, /* [in] The just created communication resource handle. */
980 DWORD insize
, /* [in] The suggested size of the communication resources input buffer in bytes. */
981 DWORD outsize
) /* [in] The suggested size of the communication resources output buffer in bytes. */
985 FIXME("insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
986 fd
=FILE_GetUnixHandle( handle
, GENERIC_READ
);
988 FIXME("handle %p not found?\n",handle
);
995 /*****************************************************************************
996 * GetCommMask (KERNEL32.@)
998 * Obtain the events associated with a communication device that will cause
999 * a call WaitCommEvent to return.
1003 * True on success, fail on bad device handle etc.
1005 BOOL WINAPI
GetCommMask(
1006 HANDLE handle
, /* [in] The communications device. */
1007 LPDWORD evtmask
) /* [out] The events which cause WaitCommEvent to return. */
1011 TRACE("handle %p, mask %p\n", handle
, evtmask
);
1013 SERVER_START_REQ( get_serial_info
)
1015 req
->handle
= handle
;
1016 if ((ret
= !wine_server_call_err( req
)))
1018 if (evtmask
) *evtmask
= reply
->eventmask
;
1025 /*****************************************************************************
1026 * SetCommMask (KERNEL32.@)
1028 * There be some things we need to hear about yon there communications device.
1029 * (Set which events associated with a communication device should cause
1030 * a call WaitCommEvent to return.)
1034 * True on success, false on bad handle etc.
1036 BOOL WINAPI
SetCommMask(
1037 HANDLE handle
, /* [in] The communications device. */
1038 DWORD evtmask
) /* [in] The events that are to be monitored. */
1042 TRACE("handle %p, mask %lx\n", handle
, evtmask
);
1044 SERVER_START_REQ( set_serial_info
)
1046 req
->handle
= handle
;
1047 req
->flags
= SERIALINFO_SET_MASK
;
1048 req
->eventmask
= evtmask
;
1049 ret
= !wine_server_call_err( req
);
1055 /*****************************************************************************
1056 * SetCommState (KERNEL32.@)
1058 * Re-initializes all hardware and control settings of a communications device,
1059 * with values from a device control block without effecting the input and output
1064 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
1066 BOOL WINAPI
SetCommState(
1067 HANDLE handle
, /* [in] The communications device. */
1068 LPDCB lpdcb
) /* [out] The device control block. */
1070 struct termios port
;
1071 int fd
, bytesize
, stopbits
;
1073 TRACE("handle %p, ptr %p\n", handle
, lpdcb
);
1074 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1075 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
1076 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
1077 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
1078 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
1079 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
1081 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
1083 FIXME("no handle %p found\n",handle
);
1087 if ((tcgetattr(fd
,&port
)) == -1) {
1088 int save_error
= errno
;
1089 COMM_SetCommError(handle
,CE_IOE
);
1091 ERR("tcgetattr error '%s'\n", strerror(save_error
));
1095 port
.c_cc
[VMIN
] = 0;
1096 port
.c_cc
[VTIME
] = 1;
1099 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
1101 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
1103 port
.c_iflag
|= (IGNBRK
);
1105 port
.c_oflag
&= ~(OPOST
);
1107 port
.c_cflag
&= ~(HUPCL
);
1108 port
.c_cflag
|= CLOCAL
| CREAD
;
1110 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
1111 port
.c_lflag
|= NOFLSH
;
1114 port
.c_cflag
&= ~CBAUD
;
1115 switch (lpdcb
->BaudRate
) {
1118 port
.c_cflag
|= B110
;
1122 port
.c_cflag
|= B300
;
1126 port
.c_cflag
|= B600
;
1130 port
.c_cflag
|= B1200
;
1134 port
.c_cflag
|= B2400
;
1138 port
.c_cflag
|= B4800
;
1142 port
.c_cflag
|= B9600
;
1146 port
.c_cflag
|= B19200
;
1150 port
.c_cflag
|= B38400
;
1154 port
.c_cflag
|= B57600
;
1159 port
.c_cflag
|= B115200
;
1164 port
.c_cflag
|= B230400
;
1169 port
.c_cflag
|= B460800
;
1173 #if defined (HAVE_LINUX_SERIAL_H) && defined (TIOCSSERIAL)
1174 { struct serial_struct nuts
;
1176 ioctl(fd
, TIOCGSERIAL
, &nuts
);
1177 nuts
.custom_divisor
= nuts
.baud_base
/ lpdcb
->BaudRate
;
1178 if (!(nuts
.custom_divisor
)) nuts
.custom_divisor
= 1;
1179 arby
= nuts
.baud_base
/ nuts
.custom_divisor
;
1180 nuts
.flags
&= ~ASYNC_SPD_MASK
;
1181 nuts
.flags
|= ASYNC_SPD_CUST
;
1182 WARN("You (or a program acting at your behest) have specified\n"
1183 "a non-standard baud rate %ld. Wine will set the rate to %d,\n"
1184 "which is as close as we can get by our present understanding of your\n"
1185 "hardware. I hope you know what you are doing. Any disruption Wine\n"
1186 "has caused to your linux system can be undone with setserial \n"
1187 "(see man setserial). If you have incapacitated a Hayes type modem,\n"
1188 "reset it and it will probably recover.\n", lpdcb
->BaudRate
, arby
);
1189 ioctl(fd
, TIOCSSERIAL
, &nuts
);
1190 port
.c_cflag
|= B38400
;
1193 #endif /* Don't have linux/serial.h or lack TIOCSSERIAL */
1196 COMM_SetCommError(handle
,IE_BAUDRATE
);
1198 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
1201 #elif !defined(__EMX__)
1202 switch (lpdcb
->BaudRate
) {
1205 port
.c_ospeed
= B110
;
1209 port
.c_ospeed
= B300
;
1213 port
.c_ospeed
= B600
;
1217 port
.c_ospeed
= B1200
;
1221 port
.c_ospeed
= B2400
;
1225 port
.c_ospeed
= B4800
;
1229 port
.c_ospeed
= B9600
;
1233 port
.c_ospeed
= B19200
;
1237 port
.c_ospeed
= B38400
;
1242 port
.c_cflag
|= B57600
;
1248 port
.c_cflag
|= B115200
;
1253 port
.c_cflag
|= B230400
;
1258 port
.c_cflag
|= B460800
;
1262 COMM_SetCommError(handle
,IE_BAUDRATE
);
1264 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
1267 port
.c_ispeed
= port
.c_ospeed
;
1269 bytesize
=lpdcb
->ByteSize
;
1270 stopbits
=lpdcb
->StopBits
;
1273 port
.c_cflag
&= ~(PARENB
| PARODD
| CMSPAR
);
1275 port
.c_cflag
&= ~(PARENB
| PARODD
);
1278 port
.c_iflag
|= INPCK
;
1280 port
.c_iflag
&= ~INPCK
;
1281 switch (lpdcb
->Parity
) {
1285 port
.c_cflag
|= (PARENB
| PARODD
);
1288 port
.c_cflag
|= PARENB
;
1291 /* Linux defines mark/space (stick) parity */
1293 port
.c_cflag
|= (PARENB
| CMSPAR
);
1296 port
.c_cflag
|= (PARENB
| PARODD
| CMSPAR
);
1299 /* try the POSIX way */
1301 if( stopbits
== ONESTOPBIT
) {
1302 stopbits
= TWOSTOPBITS
;
1303 port
.c_iflag
&= ~INPCK
;
1305 COMM_SetCommError(handle
,IE_BYTESIZE
);
1307 ERR("Cannot set MARK Parity\n");
1314 port
.c_iflag
&= ~INPCK
;
1316 COMM_SetCommError(handle
,IE_BYTESIZE
);
1318 ERR("Cannot set SPACE Parity\n");
1324 COMM_SetCommError(handle
,IE_BYTESIZE
);
1331 port
.c_cflag
&= ~CSIZE
;
1334 port
.c_cflag
|= CS5
;
1337 port
.c_cflag
|= CS6
;
1340 port
.c_cflag
|= CS7
;
1343 port
.c_cflag
|= CS8
;
1346 COMM_SetCommError(handle
,IE_BYTESIZE
);
1354 port
.c_cflag
&= ~CSTOPB
;
1356 case ONE5STOPBITS
: /* wil be selected if bytesize is 5 */
1358 port
.c_cflag
|= CSTOPB
;
1361 COMM_SetCommError(handle
,IE_BYTESIZE
);
1367 if ( lpdcb
->fOutxCtsFlow
||
1368 lpdcb
->fRtsControl
== RTS_CONTROL_HANDSHAKE
1371 port
.c_cflag
|= CRTSCTS
;
1376 if (lpdcb
->fDtrControl
== DTR_CONTROL_HANDSHAKE
)
1378 WARN("DSR/DTR flow control not supported\n");
1382 port
.c_iflag
|= IXON
;
1384 port
.c_iflag
&= ~IXON
;
1386 port
.c_iflag
|= IXOFF
;
1388 port
.c_iflag
&= ~IXOFF
;
1390 if (tcsetattr(fd
,TCSANOW
,&port
)==-1) { /* otherwise it hangs with pending input*/
1391 int save_error
=errno
;
1392 COMM_SetCommError(handle
,CE_IOE
);
1394 ERR("tcsetattr error '%s'\n", strerror(save_error
));
1397 COMM_SetCommError(handle
,0);
1404 /*****************************************************************************
1405 * GetCommState (KERNEL32.@)
1407 * Fills in a device control block with information from a communications device.
1411 * True on success, false if the communication device handle is bad etc
1415 * XonChar and XoffChar are not set.
1417 BOOL WINAPI
GetCommState(
1418 HANDLE handle
, /* [in] The communications device. */
1419 LPDCB lpdcb
) /* [out] The device control block. */
1421 struct termios port
;
1424 TRACE("handle %p, ptr %p\n", handle
, lpdcb
);
1426 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
1429 ERR("FILE_GetUnixHandle failed\n");
1432 if (tcgetattr(fd
, &port
) == -1) {
1433 int save_error
=errno
;
1434 ERR("tcgetattr error '%s'\n", strerror(save_error
));
1435 COMM_SetCommError(handle
,CE_IOE
);
1442 speed
= (port
.c_cflag
& CBAUD
);
1444 speed
= (cfgetospeed(&port
));
1448 lpdcb
->BaudRate
= 110;
1451 lpdcb
->BaudRate
= 300;
1454 lpdcb
->BaudRate
= 600;
1457 lpdcb
->BaudRate
= 1200;
1460 lpdcb
->BaudRate
= 2400;
1463 lpdcb
->BaudRate
= 4800;
1466 lpdcb
->BaudRate
= 9600;
1469 lpdcb
->BaudRate
= 19200;
1472 lpdcb
->BaudRate
= 38400;
1476 lpdcb
->BaudRate
= 57600;
1481 lpdcb
->BaudRate
= 115200;
1486 lpdcb
->BaudRate
= 230400;
1491 lpdcb
->BaudRate
= 460800;
1495 ERR("unknown speed %x \n",speed
);
1498 switch (port
.c_cflag
& CSIZE
) {
1500 lpdcb
->ByteSize
= 5;
1503 lpdcb
->ByteSize
= 6;
1506 lpdcb
->ByteSize
= 7;
1509 lpdcb
->ByteSize
= 8;
1512 ERR("unknown size %x \n",port
.c_cflag
& CSIZE
);
1515 if(port
.c_iflag
& INPCK
)
1516 lpdcb
->fParity
= TRUE
;
1518 lpdcb
->fParity
= FALSE
;
1520 switch (port
.c_cflag
& (PARENB
| PARODD
| CMSPAR
))
1522 switch (port
.c_cflag
& (PARENB
| PARODD
))
1526 lpdcb
->Parity
= NOPARITY
;
1529 lpdcb
->Parity
= EVENPARITY
;
1531 case (PARENB
| PARODD
):
1532 lpdcb
->Parity
= ODDPARITY
;
1535 case (PARENB
| CMSPAR
):
1536 lpdcb
->Parity
= MARKPARITY
;
1538 case (PARENB
| PARODD
| CMSPAR
):
1539 lpdcb
->Parity
= SPACEPARITY
;
1544 if (port
.c_cflag
& CSTOPB
)
1545 if(lpdcb
->ByteSize
== 5)
1546 lpdcb
->StopBits
= ONE5STOPBITS
;
1548 lpdcb
->StopBits
= TWOSTOPBITS
;
1550 lpdcb
->StopBits
= ONESTOPBIT
;
1555 /* termios does not support DTR/DSR flow control */
1556 lpdcb
->fOutxDsrFlow
= 0;
1557 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1561 if (port
.c_cflag
& CRTSCTS
) {
1562 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
1563 lpdcb
->fOutxCtsFlow
= 1;
1567 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1568 lpdcb
->fOutxCtsFlow
= 0;
1570 if (port
.c_iflag
& IXON
)
1575 if (port
.c_iflag
& IXOFF
)
1584 lpdcb
->XoffLim
= 10;
1586 COMM_SetCommError(handle
,0);
1590 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1591 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
1592 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
1593 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
1594 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
1595 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
1597 if ( lpdcb
->fOutxCtsFlow
||
1598 lpdcb
->fRtsControl
== RTS_CONTROL_HANDSHAKE
1603 TRACE("~CRTSCTS\n");
1609 /*****************************************************************************
1610 * TransmitCommChar (KERNEL32.@)
1612 * Transmits a single character in front of any pending characters in the
1613 * output buffer. Usually used to send an interrupt character to a host.
1617 * True if the call succeeded, false if the previous command character to the
1618 * same device has not been sent yet the handle is bad etc.
1624 BOOL WINAPI
TransmitCommChar(
1625 HANDLE hComm
, /* [in] The communication device in need of a command character. */
1626 CHAR chTransmit
) /* [in] The character to transmit. */
1631 WARN("(%p,'%c') not perfect!\n",hComm
,chTransmit
);
1633 fd
= FILE_GetUnixHandle( hComm
, GENERIC_READ
);
1635 SetLastError ( ERROR_INVALID_PARAMETER
);
1638 r
= (1 == write(fd
, &chTransmit
, 1));
1646 /*****************************************************************************
1647 * GetCommTimeouts (KERNEL32.@)
1649 * Obtains the request timeout values for the communications device.
1653 * True on success, false if communications device handle is bad
1654 * or the target structure is null.
1656 BOOL WINAPI
GetCommTimeouts(
1657 HANDLE hComm
, /* [in] The communications device. */
1658 LPCOMMTIMEOUTS lptimeouts
) /* [out] The struct of request timeouts. */
1662 TRACE("(%p,%p)\n",hComm
,lptimeouts
);
1666 SetLastError(ERROR_INVALID_PARAMETER
);
1670 SERVER_START_REQ( get_serial_info
)
1672 req
->handle
= hComm
;
1673 if ((ret
= !wine_server_call_err( req
)))
1675 lptimeouts
->ReadIntervalTimeout
= reply
->readinterval
;
1676 lptimeouts
->ReadTotalTimeoutMultiplier
= reply
->readmult
;
1677 lptimeouts
->ReadTotalTimeoutConstant
= reply
->readconst
;
1678 lptimeouts
->WriteTotalTimeoutMultiplier
= reply
->writemult
;
1679 lptimeouts
->WriteTotalTimeoutConstant
= reply
->writeconst
;
1686 /*****************************************************************************
1687 * SetCommTimeouts (KERNEL32.@)
1689 * Sets the timeouts used when reading and writing data to/from COMM ports.
1691 * ReadIntervalTimeout
1692 * - converted and passes to linux kernel as c_cc[VTIME]
1693 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1694 * - used in ReadFile to calculate GetOverlappedResult's timeout
1695 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1696 * - used in WriteFile to calculate GetOverlappedResult's timeout
1700 * True if the timeouts were set, false otherwise.
1702 BOOL WINAPI
SetCommTimeouts(
1703 HANDLE hComm
, /* [in] handle of COMM device */
1704 LPCOMMTIMEOUTS lptimeouts
) /* [in] pointer to COMMTIMEOUTS structure */
1708 struct termios tios
;
1710 TRACE("(%p,%p)\n",hComm
,lptimeouts
);
1714 SetLastError(ERROR_INVALID_PARAMETER
);
1718 SERVER_START_REQ( set_serial_info
)
1720 req
->handle
= hComm
;
1721 req
->flags
= SERIALINFO_SET_TIMEOUTS
;
1722 req
->readinterval
= lptimeouts
->ReadIntervalTimeout
;
1723 req
->readmult
= lptimeouts
->ReadTotalTimeoutMultiplier
;
1724 req
->readconst
= lptimeouts
->ReadTotalTimeoutConstant
;
1725 req
->writemult
= lptimeouts
->WriteTotalTimeoutMultiplier
;
1726 req
->writeconst
= lptimeouts
->WriteTotalTimeoutConstant
;
1727 ret
= !wine_server_call_err( req
);
1730 if (!ret
) return FALSE
;
1732 /* FIXME: move this stuff to the server */
1733 fd
= FILE_GetUnixHandle( hComm
, GENERIC_READ
);
1735 FIXME("no fd for handle = %p!.\n",hComm
);
1739 if (-1==tcgetattr(fd
,&tios
)) {
1740 FIXME("tcgetattr on fd %d failed!\n",fd
);
1745 /* VTIME is in 1/10 seconds */
1747 unsigned int ux_timeout
;
1749 if(lptimeouts
->ReadIntervalTimeout
== 0) /* 0 means no timeout */
1755 ux_timeout
= (lptimeouts
->ReadIntervalTimeout
+99)/100;
1758 ux_timeout
= 1; /* must be at least some timeout */
1761 tios
.c_cc
[VTIME
] = ux_timeout
;
1764 if (-1==tcsetattr(fd
,0,&tios
)) {
1765 FIXME("tcsetattr on fd %d failed!\n",fd
);
1773 /***********************************************************************
1774 * GetCommModemStatus (KERNEL32.@)
1776 * Obtains the four control register bits if supported by the hardware.
1780 * True if the communications handle was good and for hardware that
1781 * control register access, false otherwise.
1783 BOOL WINAPI
GetCommModemStatus(
1784 HANDLE hFile
, /* [in] The communications device. */
1785 LPDWORD lpModemStat
) /* [out] The control register bits. */
1787 int fd
,mstat
, result
=FALSE
;
1791 fd
= FILE_GetUnixHandle( hFile
, GENERIC_READ
);
1794 result
= ioctl(fd
, TIOCMGET
, &mstat
);
1798 WARN("ioctl failed\n");
1802 if (mstat
& TIOCM_CTS
)
1803 *lpModemStat
|= MS_CTS_ON
;
1806 if (mstat
& TIOCM_DSR
)
1807 *lpModemStat
|= MS_DSR_ON
;
1810 if (mstat
& TIOCM_RNG
)
1811 *lpModemStat
|= MS_RING_ON
;
1814 /*FIXME: Not really sure about RLSD UB 990810*/
1815 if (mstat
& TIOCM_CAR
)
1816 *lpModemStat
|= MS_RLSD_ON
;
1818 TRACE("%04x -> %s%s%s%s\n", mstat
,
1819 (*lpModemStat
&MS_RLSD_ON
)?"MS_RLSD_ON ":"",
1820 (*lpModemStat
&MS_RING_ON
)?"MS_RING_ON ":"",
1821 (*lpModemStat
&MS_DSR_ON
)?"MS_DSR_ON ":"",
1822 (*lpModemStat
&MS_CTS_ON
)?"MS_CTS_ON ":"");
1829 /***********************************************************************
1830 * COMM_WaitCommEventService (INTERNAL)
1832 * This function is called while the client is waiting on the
1833 * server, so we can't make any server calls here.
1835 static void COMM_WaitCommEventService(async_private
*ovp
)
1837 async_commio
*commio
= (async_commio
*) ovp
;
1838 IO_STATUS_BLOCK
* iosb
= commio
->async
.iosb
;
1840 TRACE("iosb %p\n",iosb
);
1842 /* FIXME: detect other events */
1843 *commio
->buffer
= EV_RXCHAR
;
1845 iosb
->u
.Status
= STATUS_SUCCESS
;
1849 /***********************************************************************
1850 * COMM_WaitCommEvent (INTERNAL)
1852 * This function must have an lpOverlapped.
1854 static BOOL
COMM_WaitCommEvent(
1855 HANDLE hFile
, /* [in] handle of comm port to wait for */
1856 LPDWORD lpdwEvents
, /* [out] event(s) that were detected */
1857 LPOVERLAPPED lpOverlapped
) /* [in/out] for Asynchronous waiting */
1864 SetLastError(ERROR_INVALID_PARAMETER
);
1868 if(NtResetEvent(lpOverlapped
->hEvent
,NULL
))
1871 fd
= FILE_GetUnixHandle( hFile
, GENERIC_WRITE
);
1875 ovp
= (async_commio
*) HeapAlloc(GetProcessHeap(), 0, sizeof (async_commio
));
1882 ovp
->async
.ops
= &commio_async_ops
;
1883 ovp
->async
.handle
= hFile
;
1885 ovp
->async
.type
= ASYNC_TYPE_WAIT
;
1886 ovp
->async
.func
= COMM_WaitCommEventService
;
1887 ovp
->async
.event
= lpOverlapped
->hEvent
;
1888 ovp
->async
.iosb
= (IO_STATUS_BLOCK
*)lpOverlapped
;
1889 ovp
->buffer
= (char *)lpdwEvents
;
1891 lpOverlapped
->InternalHigh
= 0;
1892 lpOverlapped
->Offset
= 0;
1893 lpOverlapped
->OffsetHigh
= 0;
1895 if ( !register_new_async (&ovp
->async
) )
1896 SetLastError( ERROR_IO_PENDING
);
1901 /***********************************************************************
1902 * WaitCommEvent (KERNEL32.@)
1904 * Wait until something interesting happens on a COMM port.
1905 * Interesting things (events) are set by calling SetCommMask before
1906 * this function is called.
1909 * TRUE if successful
1912 * The set of detected events will be written to *lpdwEventMask
1913 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1916 * Only supports EV_RXCHAR and EV_TXEMPTY
1918 BOOL WINAPI
WaitCommEvent(
1919 HANDLE hFile
, /* [in] handle of comm port to wait for */
1920 LPDWORD lpdwEvents
, /* [out] event(s) that were detected */
1921 LPOVERLAPPED lpOverlapped
) /* [in/out] for Asynchronous waiting */
1926 TRACE("(%p %p %p )\n",hFile
, lpdwEvents
,lpOverlapped
);
1929 return COMM_WaitCommEvent(hFile
, lpdwEvents
, lpOverlapped
);
1931 /* if there is no overlapped structure, create our own */
1932 ov
.hEvent
= CreateEventA(NULL
,FALSE
,FALSE
,NULL
);
1934 COMM_WaitCommEvent(hFile
, lpdwEvents
, &ov
);
1936 /* wait for the overlapped to complete */
1937 ret
= GetOverlappedResult(hFile
, &ov
, NULL
, TRUE
);
1938 CloseHandle(ov
.hEvent
);
1943 /***********************************************************************
1944 * GetCommProperties (KERNEL32.@)
1946 * This function fills in a structure with the capabilities of the
1947 * communications port driver.
1951 * TRUE on success, FALSE on failure
1952 * If successful, the lpCommProp structure be filled in with
1953 * properties of the comm port.
1955 BOOL WINAPI
GetCommProperties(
1956 HANDLE hFile
, /* [in] handle of the comm port */
1957 LPCOMMPROP lpCommProp
) /* [out] pointer to struct to be filled */
1959 FIXME("(%p %p )\n",hFile
,lpCommProp
);
1964 * These values should be valid for LINUX's serial driver
1965 * FIXME: Perhaps they deserve an #ifdef LINUX
1967 memset(lpCommProp
,0,sizeof(COMMPROP
));
1968 lpCommProp
->wPacketLength
= 1;
1969 lpCommProp
->wPacketVersion
= 1;
1970 lpCommProp
->dwServiceMask
= SP_SERIALCOMM
;
1971 lpCommProp
->dwReserved1
= 0;
1972 lpCommProp
->dwMaxTxQueue
= 4096;
1973 lpCommProp
->dwMaxRxQueue
= 4096;
1974 lpCommProp
->dwMaxBaud
= BAUD_115200
;
1975 lpCommProp
->dwProvSubType
= PST_RS232
;
1976 lpCommProp
->dwProvCapabilities
= PCF_DTRDSR
| PCF_PARITY_CHECK
| PCF_RTSCTS
| PCF_TOTALTIMEOUTS
;
1977 lpCommProp
->dwSettableParams
= SP_BAUD
| SP_DATABITS
| SP_HANDSHAKING
|
1978 SP_PARITY
| SP_PARITY_CHECK
| SP_STOPBITS
;
1979 lpCommProp
->dwSettableBaud
= BAUD_075
| BAUD_110
| BAUD_134_5
| BAUD_150
|
1980 BAUD_300
| BAUD_600
| BAUD_1200
| BAUD_1800
| BAUD_2400
| BAUD_4800
|
1981 BAUD_9600
| BAUD_19200
| BAUD_38400
| BAUD_57600
| BAUD_115200
;
1982 lpCommProp
->wSettableData
= DATABITS_5
| DATABITS_6
| DATABITS_7
| DATABITS_8
;
1983 lpCommProp
->wSettableStopParity
= STOPBITS_10
| STOPBITS_15
| STOPBITS_20
|
1984 PARITY_NONE
| PARITY_ODD
|PARITY_EVEN
| PARITY_MARK
| PARITY_SPACE
;
1985 lpCommProp
->dwCurrentTxQueue
= lpCommProp
->dwMaxTxQueue
;
1986 lpCommProp
->dwCurrentRxQueue
= lpCommProp
->dwMaxRxQueue
;
1991 /***********************************************************************
1993 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1994 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1995 * This is dependent on the type of COMM port, but since it is doubtful
1996 * anybody will get around to implementing support for fancy serial
1997 * ports in WINE, this is hardcoded for the time being. The name of
1998 * this DLL should be stored in and read from the system registry in
1999 * the hive HKEY_LOCAL_MACHINE, key
2000 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
2001 * where ???? is the port number... that is determined by PNP
2002 * The DLL should be loaded when the COMM port is opened, and closed
2003 * when the COMM port is closed. - MJM 20 June 2000
2004 ***********************************************************************/
2005 static CHAR lpszSerialUI
[] = "serialui.dll";
2008 /***********************************************************************
2009 * CommConfigDialogA (KERNEL32.@)
2011 * Raises a dialog that allows the user to configure a comm port.
2012 * Fills the COMMCONFIG struct with information specified by the user.
2013 * This function should call a similar routine in the COMM driver...
2017 * TRUE on success, FALSE on failure
2018 * If successful, the lpCommConfig structure will contain a new
2019 * configuration for the comm port, as specified by the user.
2022 * The library with the CommConfigDialog code is never unloaded.
2023 * Perhaps this should be done when the comm port is closed?
2025 BOOL WINAPI
CommConfigDialogA(
2026 LPCSTR lpszDevice
, /* [in] name of communications device */
2027 HANDLE hWnd
, /* [in] parent window for the dialog */
2028 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
2030 FARPROC lpfnCommDialog
;
2031 HMODULE hConfigModule
;
2034 TRACE("(%p %p %p)\n",lpszDevice
, hWnd
, lpCommConfig
);
2036 hConfigModule
= LoadLibraryA(lpszSerialUI
);
2040 lpfnCommDialog
= GetProcAddress(hConfigModule
, (LPCSTR
)3L);
2045 r
= lpfnCommDialog(lpszDevice
,hWnd
,lpCommConfig
);
2047 /* UnloadLibrary(hConfigModule); */
2052 /***********************************************************************
2053 * CommConfigDialogW (KERNEL32.@)
2055 * see CommConfigDialogA for more info
2057 BOOL WINAPI
CommConfigDialogW(
2058 LPCWSTR lpszDevice
, /* [in] name of communications device */
2059 HANDLE hWnd
, /* [in] parent window for the dialog */
2060 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
2065 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
2068 r
= CommConfigDialogA(lpDeviceA
,hWnd
,lpCommConfig
);
2069 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
2073 /***********************************************************************
2074 * GetCommConfig (KERNEL32.@)
2076 * Fill in the COMMCONFIG structure for the comm port hFile
2080 * TRUE on success, FALSE on failure
2081 * If successful, lpCommConfig contains the comm port configuration.
2086 BOOL WINAPI
GetCommConfig(
2087 HANDLE hFile
, /* [in] The communications device. */
2088 LPCOMMCONFIG lpCommConfig
, /* [out] The communications configuration of the device (if it fits). */
2089 LPDWORD lpdwSize
) /* [in/out] Initially the size of the configuration buffer/structure,
2090 afterwards the number of bytes copied to the buffer or
2091 the needed size of the buffer. */
2095 TRACE("(%p %p)\n",hFile
,lpCommConfig
);
2097 if(lpCommConfig
== NULL
)
2100 r
= *lpdwSize
< sizeof(COMMCONFIG
);
2101 *lpdwSize
= sizeof(COMMCONFIG
);
2105 lpCommConfig
->dwSize
= sizeof(COMMCONFIG
);
2106 lpCommConfig
->wVersion
= 1;
2107 lpCommConfig
->wReserved
= 0;
2108 r
= GetCommState(hFile
,&lpCommConfig
->dcb
);
2109 lpCommConfig
->dwProviderSubType
= PST_RS232
;
2110 lpCommConfig
->dwProviderOffset
= 0;
2111 lpCommConfig
->dwProviderSize
= 0;
2116 /***********************************************************************
2117 * SetCommConfig (KERNEL32.@)
2119 * Sets the configuration of the communications device.
2123 * True on success, false if the handle was bad is not a communications device.
2125 BOOL WINAPI
SetCommConfig(
2126 HANDLE hFile
, /* [in] The communications device. */
2127 LPCOMMCONFIG lpCommConfig
, /* [in] The desired configuration. */
2128 DWORD dwSize
) /* [in] size of the lpCommConfig struct */
2130 TRACE("(%p %p)\n",hFile
,lpCommConfig
);
2131 return SetCommState(hFile
,&lpCommConfig
->dcb
);
2134 /***********************************************************************
2135 * SetDefaultCommConfigA (KERNEL32.@)
2137 * Initializes the default configuration for the specified communication
2142 * True if the device was found and the defaults set, false otherwise
2144 BOOL WINAPI
SetDefaultCommConfigA(
2145 LPCSTR lpszDevice
, /* [in] The ascii name of the device targeted for configuration. */
2146 LPCOMMCONFIG lpCommConfig
, /* [in] The default configuration for the device. */
2147 DWORD dwSize
) /* [in] The number of bytes in the configuration structure. */
2149 FARPROC lpfnSetDefaultCommConfig
;
2150 HMODULE hConfigModule
;
2153 TRACE("(%p %p %lx)\n",lpszDevice
, lpCommConfig
, dwSize
);
2155 hConfigModule
= LoadLibraryA(lpszSerialUI
);
2159 lpfnSetDefaultCommConfig
= GetProcAddress(hConfigModule
, (LPCSTR
)4L);
2161 if(! lpfnSetDefaultCommConfig
)
2164 r
= lpfnSetDefaultCommConfig(lpszDevice
, lpCommConfig
, dwSize
);
2166 /* UnloadLibrary(hConfigModule); */
2172 /***********************************************************************
2173 * SetDefaultCommConfigW (KERNEL32.@)
2175 * Initializes the default configuration for the specified
2176 * communication device. (unicode)
2181 BOOL WINAPI
SetDefaultCommConfigW(
2182 LPCWSTR lpszDevice
, /* [in] The unicode name of the device targeted for configuration. */
2183 LPCOMMCONFIG lpCommConfig
, /* [in] The default configuration for the device. */
2184 DWORD dwSize
) /* [in] The number of bytes in the configuration structure. */
2189 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice
),lpCommConfig
,dwSize
);
2191 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
2194 r
= SetDefaultCommConfigA(lpDeviceA
,lpCommConfig
,dwSize
);
2195 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
2200 /***********************************************************************
2201 * GetDefaultCommConfigA (KERNEL32.@)
2203 * Acquires the default configuration of the specified communication device. (unicode)
2207 * True on successful reading of the default configuration,
2208 * if the device is not found or the buffer is too small.
2210 BOOL WINAPI
GetDefaultCommConfigA(
2211 LPCSTR lpszName
, /* [in] The ascii name of the device targeted for configuration. */
2212 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
2213 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
2214 afterwards the number of bytes copied to the buffer or
2215 the needed size of the buffer. */
2217 LPDCB lpdcb
= &(lpCC
->dcb
);
2220 if (strncasecmp(lpszName
,"COM",3)) {
2221 ERR("not implemented for <%s>\n", lpszName
);
2225 TRACE("(%s %p %ld)\n", lpszName
, lpCC
, *lpdwSize
);
2226 if (*lpdwSize
< sizeof(COMMCONFIG
)) {
2227 *lpdwSize
= sizeof(COMMCONFIG
);
2231 *lpdwSize
= sizeof(COMMCONFIG
);
2233 lpCC
->dwSize
= sizeof(COMMCONFIG
);
2235 lpCC
->dwProviderSubType
= PST_RS232
;
2236 lpCC
->dwProviderOffset
= 0L;
2237 lpCC
->dwProviderSize
= 0L;
2239 sprintf( temp
, "COM%c:38400,n,8,1", lpszName
[3]);
2240 FIXME("setting %s as default\n", temp
);
2242 return BuildCommDCBA( temp
, lpdcb
);
2245 /**************************************************************************
2246 * GetDefaultCommConfigW (KERNEL32.@)
2248 * Acquires the default configuration of the specified communication device. (unicode)
2252 * True on successful reading of the default configuration,
2253 * if the device is not found or the buffer is too small.
2255 BOOL WINAPI
GetDefaultCommConfigW(
2256 LPCWSTR lpszName
, /* [in] The unicode name of the device targeted for configuration. */
2257 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
2258 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
2259 afterwards the number of bytes copied to the buffer or
2260 the needed size of the buffer. */
2265 TRACE("(%p,%p,%ld)\n",lpszName
,lpCC
,*lpdwSize
);
2266 lpszNameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName
);
2269 ret
=GetDefaultCommConfigA(lpszNameA
,lpCC
,lpdwSize
);
2270 HeapFree( GetProcessHeap(), 0, lpszNameA
);