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"
66 #ifdef HAVE_SYS_FILIO_H
67 # include <sys/filio.h>
69 #include <sys/ioctl.h>
72 #ifdef HAVE_SYS_MODEM_H
73 # include <sys/modem.h>
75 #ifdef HAVE_SYS_STRTIO_H
76 # include <sys/strtio.h>
82 #include "wine/server.h"
87 #include "wine/debug.h"
89 #ifdef HAVE_LINUX_SERIAL_H
90 #include <linux/serial.h>
93 WINE_DEFAULT_DEBUG_CHANNEL(comm
);
95 /***********************************************************************
96 * Asynchronous I/O for asynchronous wait requests *
99 static DWORD
commio_get_async_status (const async_private
*ovp
);
100 static DWORD
commio_get_async_count (const async_private
*ovp
);
101 static void commio_set_async_status (async_private
*ovp
, const DWORD status
);
102 static void commio_async_cleanup (async_private
*ovp
);
104 static async_ops commio_async_ops
=
106 commio_get_async_status
, /* get_status */
107 commio_set_async_status
, /* set_status */
108 commio_get_async_count
, /* get_count */
109 NULL
, /* call_completion */
110 commio_async_cleanup
/* cleanup */
113 typedef struct async_commio
115 struct async_private async
;
116 LPOVERLAPPED lpOverlapped
;
120 static DWORD
commio_get_async_status (const struct async_private
*ovp
)
122 return ((async_commio
*) ovp
)->lpOverlapped
->Internal
;
125 static void commio_set_async_status (async_private
*ovp
, const DWORD status
)
127 ((async_commio
*) ovp
)->lpOverlapped
->Internal
= status
;
130 static DWORD
commio_get_async_count (const struct async_private
*ovp
)
135 static void commio_async_cleanup (async_private
*ovp
)
137 HeapFree(GetProcessHeap(), 0, ovp
);
140 /***********************************************************************/
142 #if !defined(TIOCINQ) && defined(FIONREAD)
143 #define TIOCINQ FIONREAD
146 static int COMM_WhackModem(int fd
, unsigned int andy
, unsigned int orrie
)
148 unsigned int mstat
, okay
;
149 okay
= ioctl(fd
, TIOCMGET
, &mstat
);
150 if (okay
) return okay
;
151 if (andy
) mstat
&= andy
;
153 return ioctl(fd
, TIOCMSET
, &mstat
);
156 /***********************************************************************
157 * COMM_BuildOldCommDCB (Internal)
159 * Build a DCB using the old style settings string eg: "COMx:96,n,8,1"
160 * We ignore the COM port index, since we can support more than 4 ports.
162 BOOL WINAPI
COMM_BuildOldCommDCB(LPCSTR device
, LPDCB lpdcb
)
164 /* "COM1:96,n,8,1" */
166 char *ptr
, temp
[256], last
;
169 TRACE("(%s), ptr %p\n", device
, lpdcb
);
171 if (strncasecmp(device
,"COM",3))
177 if ((*(device
+4) != ':') && (*(device
+4) != ' '))
180 strcpy(temp
,device
+5);
181 last
=temp
[strlen(temp
)-1];
182 ptr
= strtok(temp
, ", ");
184 /* DOS/Windows only compares the first two numbers
185 * and assigns an appropriate baud rate.
186 * You can supply 961324245, it still returns 9600 ! */
189 WARN("Unknown baudrate string '%s' !\n", ptr
);
190 return FALSE
; /* error: less than 2 chars */
211 WARN("Unknown baudrate indicator %d !\n", rate
);
215 lpdcb
->BaudRate
= rate
;
216 TRACE("baudrate (%ld)\n", lpdcb
->BaudRate
);
218 ptr
= strtok(NULL
, ", ");
220 *ptr
= toupper(*ptr
);
222 TRACE("parity (%c)\n", *ptr
);
223 lpdcb
->fParity
= TRUE
;
226 lpdcb
->Parity
= NOPARITY
;
227 lpdcb
->fParity
= FALSE
;
230 lpdcb
->Parity
= EVENPARITY
;
233 lpdcb
->Parity
= MARKPARITY
;
236 lpdcb
->Parity
= ODDPARITY
;
239 lpdcb
->Parity
= SPACEPARITY
;
242 WARN("Unknown parity `%c'!\n", *ptr
);
246 ptr
= strtok(NULL
, ", ");
247 TRACE("charsize (%c)\n", *ptr
);
248 lpdcb
->ByteSize
= *ptr
- '0';
250 ptr
= strtok(NULL
, ", ");
251 TRACE("stopbits (%c)\n", *ptr
);
254 lpdcb
->StopBits
= ONESTOPBIT
;
257 lpdcb
->StopBits
= TWOSTOPBITS
;
260 WARN("Unknown # of stopbits `%c'!\n", *ptr
);
267 lpdcb
->fOutxCtsFlow
= FALSE
;
268 lpdcb
->fOutxDsrFlow
= FALSE
;
269 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
270 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
271 } else if (last
=='p') {
273 lpdcb
->fOutX
= FALSE
;
274 lpdcb
->fOutxCtsFlow
= TRUE
;
275 lpdcb
->fOutxDsrFlow
= FALSE
;
276 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
277 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
280 lpdcb
->fOutX
= FALSE
;
281 lpdcb
->fOutxCtsFlow
= FALSE
;
282 lpdcb
->fOutxDsrFlow
= FALSE
;
283 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
284 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
290 /**************************************************************************
291 * BuildCommDCBA (KERNEL32.@)
293 * Updates a device control block data structure with values from an
294 * ascii device control string. The device control string has two forms
295 * normal and extended, it must be exclusively in one or the other form.
299 * True on success, false on a malformed control string.
301 BOOL WINAPI
BuildCommDCBA(
302 LPCSTR device
, /* [in] The ascii device control string used to update the DCB. */
303 LPDCB lpdcb
) /* [out] The device control block to be updated. */
305 return BuildCommDCBAndTimeoutsA(device
,lpdcb
,NULL
);
308 /**************************************************************************
309 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
311 * Updates a device control block data structure with values from an
312 * ascii device control string. Taking timeout values from a timeouts
313 * struct if desired by the control string.
317 * True on success, false bad handles etc
319 BOOL WINAPI
BuildCommDCBAndTimeoutsA(
320 LPCSTR device
, /* [in] The ascii device control string. */
321 LPDCB lpdcb
, /* [out] The device control block to be updated. */
322 LPCOMMTIMEOUTS lptimeouts
) /* [in] The timeouts to use if asked to set them by the control string. */
327 TRACE("(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
329 if (!strncasecmp(device
,"COM",3)) {
332 ERR("BUG! COM0 can't exist!\n");
335 if ((*(device
+4)!=':') && (*(device
+4)!=' '))
337 temp
=(LPSTR
)(device
+5);
341 memset(lpdcb
,0,sizeof (DCB
));
342 lpdcb
->DCBlength
= sizeof(DCB
);
343 if (strchr(temp
,',')) { /* old style */
345 return COMM_BuildOldCommDCB(device
,lpdcb
);
347 ptr
=strtok(temp
," ");
352 if (!strncmp("baud=",ptr
,5)) {
353 if (!sscanf(ptr
+5,"%ld",&x
))
354 WARN("Couldn't parse %s\n",ptr
);
358 if (!strncmp("stop=",ptr
,5)) {
359 if (!sscanf(ptr
+5,"%ld",&x
))
360 WARN("Couldn't parse %s\n",ptr
);
364 if (!strncmp("data=",ptr
,5)) {
365 if (!sscanf(ptr
+5,"%ld",&x
))
366 WARN("Couldn't parse %s\n",ptr
);
370 if (!strncmp("parity=",ptr
,7)) {
371 lpdcb
->fParity
= TRUE
;
374 lpdcb
->fParity
= FALSE
;
375 lpdcb
->Parity
= NOPARITY
;
378 lpdcb
->Parity
= EVENPARITY
;
381 lpdcb
->Parity
= ODDPARITY
;
384 lpdcb
->Parity
= MARKPARITY
;
387 lpdcb
->Parity
= SPACEPARITY
;
393 ERR("Unhandled specifier '%s', please report.\n",ptr
);
394 ptr
=strtok(NULL
," ");
396 if (lpdcb
->BaudRate
==110)
401 /**************************************************************************
402 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
404 * Updates a device control block data structure with values from an
405 * unicode device control string. Taking timeout values from a timeouts
406 * struct if desired by the control string.
410 * True on success, false bad handles etc.
412 BOOL WINAPI
BuildCommDCBAndTimeoutsW(
413 LPCWSTR devid
, /* [in] The unicode device control string. */
414 LPDCB lpdcb
, /* [out] The device control block to be updated. */
415 LPCOMMTIMEOUTS lptimeouts
) /* [in] The timeouts to use if asked to set them by the control string. */
420 TRACE("(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
421 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
424 ret
=BuildCommDCBAndTimeoutsA(devidA
,lpdcb
,lptimeouts
);
425 HeapFree( GetProcessHeap(), 0, devidA
);
430 /**************************************************************************
431 * BuildCommDCBW (KERNEL32.@)
433 * Updates a device control block structure with values from an
434 * unicode device control string. The device control string has two forms
435 * normal and extended, it must be exclusively in one or the other form.
439 * True on success, false on an malformed control string.
441 BOOL WINAPI
BuildCommDCBW(
442 LPCWSTR devid
, /* [in] The unicode device control string. */
443 LPDCB lpdcb
) /* [out] The device control block to be updated. */
445 return BuildCommDCBAndTimeoutsW(devid
,lpdcb
,NULL
);
448 static BOOL
COMM_SetCommError(HANDLE handle
, DWORD error
)
452 SERVER_START_REQ( set_serial_info
)
454 req
->handle
= handle
;
455 req
->flags
= SERIALINFO_SET_ERROR
;
456 req
->commerror
= error
;
457 ret
= !wine_server_call_err( req
);
463 static BOOL
COMM_GetCommError(HANDLE handle
, LPDWORD lperror
)
470 SERVER_START_REQ( get_serial_info
)
472 req
->handle
= handle
;
473 ret
= !wine_server_call_err( req
);
474 *lperror
= reply
->commerror
;
481 /*****************************************************************************
482 * SetCommBreak (KERNEL32.@)
484 * Halts the transmission of characters to a communications device.
488 * True on success, and false if the communications device could not be found,
489 * the control is not supported.
493 * Only TIOCSBRK and TIOCCBRK are supported.
495 BOOL WINAPI
SetCommBreak(
496 HANDLE handle
) /* [in] The communictions device to suspend. */
498 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
501 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
503 TRACE("FILE_GetUnixHandle failed\n");
506 result
= ioctl(fd
,TIOCSBRK
,0);
510 TRACE("ioctl failed\n");
511 SetLastError(ERROR_NOT_SUPPORTED
);
516 FIXME("ioctl not available\n");
517 SetLastError(ERROR_NOT_SUPPORTED
);
522 /*****************************************************************************
523 * ClearCommBreak (KERNEL32.@)
525 * Resumes character transmission from a communication device.
529 * True on success and false if the communications device could not be found.
533 * Only TIOCSBRK and TIOCCBRK are supported.
535 BOOL WINAPI
ClearCommBreak(
536 HANDLE handle
) /* [in] The halted communication device whose character transmission is to be resumed. */
538 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
541 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
543 TRACE("FILE_GetUnixHandle failed\n");
546 result
= ioctl(fd
,TIOCCBRK
,0);
550 TRACE("ioctl failed\n");
551 SetLastError(ERROR_NOT_SUPPORTED
);
556 FIXME("ioctl not available\n");
557 SetLastError(ERROR_NOT_SUPPORTED
);
562 /*****************************************************************************
563 * EscapeCommFunction (KERNEL32.@)
565 * Directs a communication device to perform an extended function.
569 * True or requested data on successful completion of the command,
570 * false if the device is not present cannot execute the command
571 * or the command failed.
573 BOOL WINAPI
EscapeCommFunction(
574 HANDLE handle
, /* [in] The communication device to perform the extended function. */
575 UINT nFunction
) /* [in] The extended function to be performed. */
577 int fd
,direct
=FALSE
,result
=FALSE
;
580 TRACE("handle %d, function=%d\n", handle
, nFunction
);
581 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
583 FIXME("handle %d not found.\n",handle
);
587 if (tcgetattr(fd
,&port
) == -1) {
588 COMM_SetCommError(handle
,CE_IOE
);
602 result
= COMM_WhackModem(fd
, ~TIOCM_DTR
, 0);
610 result
= COMM_WhackModem(fd
, ~TIOCM_RTS
, 0);
618 result
= COMM_WhackModem(fd
, 0, TIOCM_DTR
);
626 result
= COMM_WhackModem(fd
, 0, TIOCM_RTS
);
632 port
.c_iflag
|= IXOFF
;
637 port
.c_iflag
|= IXON
;
643 result
= ioctl(fd
,TIOCSBRK
,0);
650 result
= ioctl(fd
,TIOCCBRK
,0);
654 WARN("(handle=%d,nFunction=%d): Unknown function\n",
660 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
662 COMM_SetCommError(handle
,CE_IOE
);
671 COMM_SetCommError(handle
,CE_IOE
);
680 /********************************************************************
681 * PurgeComm (KERNEL32.@)
683 * Terminates pending operations and/or discards buffers on a
684 * communication resource.
688 * True on success and false if the communications handle is bad.
690 BOOL WINAPI
PurgeComm(
691 HANDLE handle
, /* [in] The communication resource to be purged. */
692 DWORD flags
) /* [in] Flags for clear pending/buffer on input/output. */
696 TRACE("handle %d, flags %lx\n", handle
, flags
);
698 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
700 FIXME("no handle %d found\n",handle
);
705 ** not exactly sure how these are different
706 ** Perhaps if we had our own internal queues, one flushes them
707 ** and the other flushes the kernel's buffers.
709 if(flags
&PURGE_TXABORT
)
710 tcflush(fd
,TCOFLUSH
);
711 if(flags
&PURGE_RXABORT
)
712 tcflush(fd
,TCIFLUSH
);
713 if(flags
&PURGE_TXCLEAR
)
714 tcflush(fd
,TCOFLUSH
);
715 if(flags
&PURGE_RXCLEAR
)
716 tcflush(fd
,TCIFLUSH
);
722 /*****************************************************************************
723 * ClearCommError (KERNEL32.@)
725 * Enables further I/O operations on a communications resource after
726 * supplying error and current status information.
730 * True on success, false if the communication resource handle is bad.
732 BOOL WINAPI
ClearCommError(
733 HANDLE handle
, /* [in] The communication resource with the error. */
734 LPDWORD errors
, /* [out] Flags indicating error the resource experienced. */
735 LPCOMSTAT lpStat
) /* [out] The status of the communication resource. */
739 fd
=FILE_GetUnixHandle( handle
, GENERIC_READ
);
742 FIXME("no handle %d found\n",handle
);
751 if(ioctl(fd
, TIOCOUTQ
, &lpStat
->cbOutQue
))
752 WARN("ioctl returned error\n");
754 lpStat
->cbOutQue
= 0; /* FIXME: find a different way to find out */
758 if(ioctl(fd
, TIOCINQ
, &lpStat
->cbInQue
))
759 WARN("ioctl returned error\n");
762 TRACE("handle %d cbInQue = %ld cbOutQue = %ld\n",
763 handle
, lpStat
->cbInQue
, lpStat
->cbOutQue
);
768 COMM_GetCommError(handle
, errors
);
769 COMM_SetCommError(handle
, 0);
774 /*****************************************************************************
775 * SetupComm (KERNEL32.@)
777 * Called after CreateFile to hint to the communication resource to use
778 * specified sizes for input and output buffers rather than the default values.
782 * True if successful, false if the communications resource handle is bad.
788 BOOL WINAPI
SetupComm(
789 HANDLE handle
, /* [in] The just created communication resource handle. */
790 DWORD insize
, /* [in] The suggested size of the communication resources input buffer in bytes. */
791 DWORD outsize
) /* [in] The suggested size of the communication resources output buffer in bytes. */
795 FIXME("insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
796 fd
=FILE_GetUnixHandle( handle
, GENERIC_READ
);
798 FIXME("handle %d not found?\n",handle
);
805 /*****************************************************************************
806 * GetCommMask (KERNEL32.@)
808 * Obtain the events associated with a communication device that will cause
809 * a call WaitCommEvent to return.
813 * True on success, fail on bad device handle etc.
815 BOOL WINAPI
GetCommMask(
816 HANDLE handle
, /* [in] The communications device. */
817 LPDWORD evtmask
) /* [out] The events which cause WaitCommEvent to return. */
821 TRACE("handle %d, mask %p\n", handle
, evtmask
);
823 SERVER_START_REQ( get_serial_info
)
825 req
->handle
= handle
;
826 if ((ret
= !wine_server_call_err( req
)))
828 if (evtmask
) *evtmask
= reply
->eventmask
;
835 /*****************************************************************************
836 * SetCommMask (KERNEL32.@)
838 * There be some things we need to hear about yon there communications device.
839 * (Set which events associated with a communication device should cause
840 * a call WaitCommEvent to return.)
844 * True on success, false on bad handle etc.
846 BOOL WINAPI
SetCommMask(
847 HANDLE handle
, /* [in] The communications device. */
848 DWORD evtmask
) /* [in] The events that are to be monitored. */
852 TRACE("handle %d, mask %lx\n", handle
, evtmask
);
854 SERVER_START_REQ( set_serial_info
)
856 req
->handle
= handle
;
857 req
->flags
= SERIALINFO_SET_MASK
;
858 req
->eventmask
= evtmask
;
859 ret
= !wine_server_call_err( req
);
865 /*****************************************************************************
866 * SetCommState (KERNEL32.@)
868 * Re-initializes all hardware and control settings of a communications device,
869 * with values from a device control block without effecting the input and output
874 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
876 BOOL WINAPI
SetCommState(
877 HANDLE handle
, /* [in] The communications device. */
878 LPDCB lpdcb
) /* [out] The device control block. */
881 int fd
, bytesize
, stopbits
;
883 TRACE("handle %d, ptr %p\n", handle
, lpdcb
);
884 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
885 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
886 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
887 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
888 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
889 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
891 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
893 FIXME("no handle %d found\n",handle
);
897 if ((tcgetattr(fd
,&port
)) == -1) {
898 int save_error
= errno
;
899 COMM_SetCommError(handle
,CE_IOE
);
901 ERR("tcgetattr error '%s'\n", strerror(save_error
));
906 port
.c_cc
[VTIME
] = 1;
909 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
911 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
913 port
.c_iflag
|= (IGNBRK
);
915 port
.c_oflag
&= ~(OPOST
);
917 port
.c_cflag
&= ~(HUPCL
);
918 port
.c_cflag
|= CLOCAL
| CREAD
;
920 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
921 port
.c_lflag
|= NOFLSH
;
924 port
.c_cflag
&= ~CBAUD
;
925 switch (lpdcb
->BaudRate
) {
928 port
.c_cflag
|= B110
;
932 port
.c_cflag
|= B300
;
936 port
.c_cflag
|= B600
;
940 port
.c_cflag
|= B1200
;
944 port
.c_cflag
|= B2400
;
948 port
.c_cflag
|= B4800
;
952 port
.c_cflag
|= B9600
;
956 port
.c_cflag
|= B19200
;
960 port
.c_cflag
|= B38400
;
964 port
.c_cflag
|= B57600
;
969 port
.c_cflag
|= B115200
;
974 port
.c_cflag
|= B230400
;
979 port
.c_cflag
|= B460800
;
983 #if defined (HAVE_LINUX_SERIAL_H) && defined (TIOCSSERIAL)
984 { struct serial_struct nuts
;
986 ioctl(fd
, TIOCGSERIAL
, &nuts
);
987 nuts
.custom_divisor
= nuts
.baud_base
/ lpdcb
->BaudRate
;
988 if (!(nuts
.custom_divisor
)) nuts
.custom_divisor
= 1;
989 arby
= nuts
.baud_base
/ nuts
.custom_divisor
;
990 nuts
.flags
&= ~ASYNC_SPD_MASK
;
991 nuts
.flags
|= ASYNC_SPD_CUST
;
992 WARN("You (or a program acting at your behest) have specified\n"
993 "a non-standard baud rate %ld. Wine will set the rate to %d,\n"
994 "which is as close as we can get by our present understanding of your\n"
995 "hardware. I hope you know what you are doing. Any disruption Wine\n"
996 "has caused to your linux system can be undone with setserial \n"
997 "(see man setserial). If you have incapacitated a Hayes type modem,\n"
998 "reset it and it will probably recover.\n", lpdcb
->BaudRate
, arby
);
999 ioctl(fd
, TIOCSSERIAL
, &nuts
);
1000 port
.c_cflag
|= B38400
;
1003 #endif /* Don't have linux/serial.h or lack TIOCSSERIAL */
1006 COMM_SetCommError(handle
,IE_BAUDRATE
);
1008 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
1011 #elif !defined(__EMX__)
1012 switch (lpdcb
->BaudRate
) {
1015 port
.c_ospeed
= B110
;
1019 port
.c_ospeed
= B300
;
1023 port
.c_ospeed
= B600
;
1027 port
.c_ospeed
= B1200
;
1031 port
.c_ospeed
= B2400
;
1035 port
.c_ospeed
= B4800
;
1039 port
.c_ospeed
= B9600
;
1043 port
.c_ospeed
= B19200
;
1047 port
.c_ospeed
= B38400
;
1050 COMM_SetCommError(handle
,IE_BAUDRATE
);
1052 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
1055 port
.c_ispeed
= port
.c_ospeed
;
1057 bytesize
=lpdcb
->ByteSize
;
1058 stopbits
=lpdcb
->StopBits
;
1061 port
.c_cflag
&= ~(PARENB
| PARODD
| CMSPAR
);
1063 port
.c_cflag
&= ~(PARENB
| PARODD
);
1066 port
.c_iflag
|= INPCK
;
1068 port
.c_iflag
&= ~INPCK
;
1069 switch (lpdcb
->Parity
) {
1073 port
.c_cflag
|= (PARENB
| PARODD
);
1076 port
.c_cflag
|= PARENB
;
1079 /* Linux defines mark/space (stick) parity */
1081 port
.c_cflag
|= (PARENB
| CMSPAR
);
1084 port
.c_cflag
|= (PARENB
| PARODD
| CMSPAR
);
1087 /* try the POSIX way */
1089 if( stopbits
== ONESTOPBIT
) {
1090 stopbits
= TWOSTOPBITS
;
1091 port
.c_iflag
&= ~INPCK
;
1093 COMM_SetCommError(handle
,IE_BYTESIZE
);
1095 ERR("Cannot set MARK Parity\n");
1102 port
.c_iflag
&= ~INPCK
;
1104 COMM_SetCommError(handle
,IE_BYTESIZE
);
1106 ERR("Cannot set SPACE Parity\n");
1112 COMM_SetCommError(handle
,IE_BYTESIZE
);
1119 port
.c_cflag
&= ~CSIZE
;
1122 port
.c_cflag
|= CS5
;
1125 port
.c_cflag
|= CS6
;
1128 port
.c_cflag
|= CS7
;
1131 port
.c_cflag
|= CS8
;
1134 COMM_SetCommError(handle
,IE_BYTESIZE
);
1142 port
.c_cflag
&= ~CSTOPB
;
1144 case ONE5STOPBITS
: /* wil be selected if bytesize is 5 */
1146 port
.c_cflag
|= CSTOPB
;
1149 COMM_SetCommError(handle
,IE_BYTESIZE
);
1155 if ( lpdcb
->fOutxCtsFlow
||
1156 lpdcb
->fRtsControl
== RTS_CONTROL_HANDSHAKE
1159 port
.c_cflag
|= CRTSCTS
;
1164 if (lpdcb
->fDtrControl
== DTR_CONTROL_HANDSHAKE
)
1166 WARN("DSR/DTR flow control not supported\n");
1170 port
.c_iflag
|= IXON
;
1172 port
.c_iflag
&= ~IXON
;
1174 port
.c_iflag
|= IXOFF
;
1176 port
.c_iflag
&= ~IXOFF
;
1178 if (tcsetattr(fd
,TCSANOW
,&port
)==-1) { /* otherwise it hangs with pending input*/
1179 int save_error
=errno
;
1180 COMM_SetCommError(handle
,CE_IOE
);
1182 ERR("tcsetattr error '%s'\n", strerror(save_error
));
1185 COMM_SetCommError(handle
,0);
1192 /*****************************************************************************
1193 * GetCommState (KERNEL32.@)
1195 * Fills in a device control block with information from a communications device.
1199 * True on success, false if the communication device handle is bad etc
1203 * XonChar and XoffChar are not set.
1205 BOOL WINAPI
GetCommState(
1206 HANDLE handle
, /* [in] The communications device. */
1207 LPDCB lpdcb
) /* [out] The device control block. */
1209 struct termios port
;
1212 TRACE("handle %d, ptr %p\n", handle
, lpdcb
);
1214 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
1217 ERR("FILE_GetUnixHandle failed\n");
1220 if (tcgetattr(fd
, &port
) == -1) {
1221 int save_error
=errno
;
1222 ERR("tcgetattr error '%s'\n", strerror(save_error
));
1223 COMM_SetCommError(handle
,CE_IOE
);
1230 speed
= (port
.c_cflag
& CBAUD
);
1232 speed
= (cfgetospeed(&port
));
1236 lpdcb
->BaudRate
= 110;
1239 lpdcb
->BaudRate
= 300;
1242 lpdcb
->BaudRate
= 600;
1245 lpdcb
->BaudRate
= 1200;
1248 lpdcb
->BaudRate
= 2400;
1251 lpdcb
->BaudRate
= 4800;
1254 lpdcb
->BaudRate
= 9600;
1257 lpdcb
->BaudRate
= 19200;
1260 lpdcb
->BaudRate
= 38400;
1264 lpdcb
->BaudRate
= 57600;
1269 lpdcb
->BaudRate
= 115200;
1274 lpdcb
->BaudRate
= 230400;
1279 lpdcb
->BaudRate
= 460800;
1283 ERR("unknown speed %x \n",speed
);
1286 switch (port
.c_cflag
& CSIZE
) {
1288 lpdcb
->ByteSize
= 5;
1291 lpdcb
->ByteSize
= 6;
1294 lpdcb
->ByteSize
= 7;
1297 lpdcb
->ByteSize
= 8;
1300 ERR("unknown size %x \n",port
.c_cflag
& CSIZE
);
1303 if(port
.c_iflag
& INPCK
)
1304 lpdcb
->fParity
= TRUE
;
1306 lpdcb
->fParity
= FALSE
;
1308 switch (port
.c_cflag
& (PARENB
| PARODD
| CMSPAR
))
1310 switch (port
.c_cflag
& (PARENB
| PARODD
))
1314 lpdcb
->Parity
= NOPARITY
;
1317 lpdcb
->Parity
= EVENPARITY
;
1319 case (PARENB
| PARODD
):
1320 lpdcb
->Parity
= ODDPARITY
;
1323 case (PARENB
| CMSPAR
):
1324 lpdcb
->Parity
= MARKPARITY
;
1326 case (PARENB
| PARODD
| CMSPAR
):
1327 lpdcb
->Parity
= SPACEPARITY
;
1332 if (port
.c_cflag
& CSTOPB
)
1333 if(lpdcb
->ByteSize
== 5)
1334 lpdcb
->StopBits
= ONE5STOPBITS
;
1336 lpdcb
->StopBits
= TWOSTOPBITS
;
1338 lpdcb
->StopBits
= ONESTOPBIT
;
1343 /* termios does not support DTR/DSR flow control */
1344 lpdcb
->fOutxDsrFlow
= 0;
1345 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1349 if (port
.c_cflag
& CRTSCTS
) {
1350 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
1351 lpdcb
->fOutxCtsFlow
= 1;
1355 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1356 lpdcb
->fOutxCtsFlow
= 0;
1358 if (port
.c_iflag
& IXON
)
1363 if (port
.c_iflag
& IXOFF
)
1372 lpdcb
->XoffLim
= 10;
1374 COMM_SetCommError(handle
,0);
1378 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1379 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
1380 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
1381 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
1382 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
1383 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
1385 if ( lpdcb
->fOutxCtsFlow
||
1386 lpdcb
->fRtsControl
== RTS_CONTROL_HANDSHAKE
1391 TRACE("~CRTSCTS\n");
1397 /*****************************************************************************
1398 * TransmitCommChar (KERNEL32.@)
1400 * Transmits a single character in front of any pending characters in the
1401 * output buffer. Usually used to send an interrupt character to a host.
1405 * True if the call succeeded, false if the previous command character to the
1406 * same device has not been sent yet the handle is bad etc.
1412 BOOL WINAPI
TransmitCommChar(
1413 HANDLE hComm
, /* [in] The communication device in need of a command character. */
1414 CHAR chTransmit
) /* [in] The character to transmit. */
1416 FIXME("(%x,'%c'), stub ! Use win32 handle!\n",hComm
,chTransmit
);
1420 /*****************************************************************************
1421 * GetCommTimeouts (KERNEL32.@)
1423 * Obtains the request timeout values for the communications device.
1427 * True on success, false if communications device handle is bad
1428 * or the target structure is null.
1430 BOOL WINAPI
GetCommTimeouts(
1431 HANDLE hComm
, /* [in] The communications device. */
1432 LPCOMMTIMEOUTS lptimeouts
) /* [out] The struct of request timeouts. */
1436 TRACE("(%x,%p)\n",hComm
,lptimeouts
);
1440 SetLastError(ERROR_INVALID_PARAMETER
);
1444 SERVER_START_REQ( get_serial_info
)
1446 req
->handle
= hComm
;
1447 if ((ret
= !wine_server_call_err( req
)))
1449 lptimeouts
->ReadIntervalTimeout
= reply
->readinterval
;
1450 lptimeouts
->ReadTotalTimeoutMultiplier
= reply
->readmult
;
1451 lptimeouts
->ReadTotalTimeoutConstant
= reply
->readconst
;
1452 lptimeouts
->WriteTotalTimeoutMultiplier
= reply
->writemult
;
1453 lptimeouts
->WriteTotalTimeoutConstant
= reply
->writeconst
;
1460 /*****************************************************************************
1461 * SetCommTimeouts (KERNEL32.@)
1463 * Sets the timeouts used when reading and writing data to/from COMM ports.
1465 * ReadIntervalTimeout
1466 * - converted and passes to linux kernel as c_cc[VTIME]
1467 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1468 * - used in ReadFile to calculate GetOverlappedResult's timeout
1469 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1470 * - used in WriteFile to calculate GetOverlappedResult's timeout
1474 * True if the timeouts were set, false otherwise.
1476 BOOL WINAPI
SetCommTimeouts(
1477 HANDLE hComm
, /* [in] handle of COMM device */
1478 LPCOMMTIMEOUTS lptimeouts
) /* [in] pointer to COMMTIMEOUTS structure */
1482 struct termios tios
;
1484 TRACE("(%x,%p)\n",hComm
,lptimeouts
);
1488 SetLastError(ERROR_INVALID_PARAMETER
);
1492 SERVER_START_REQ( set_serial_info
)
1494 req
->handle
= hComm
;
1495 req
->flags
= SERIALINFO_SET_TIMEOUTS
;
1496 req
->readinterval
= lptimeouts
->ReadIntervalTimeout
;
1497 req
->readmult
= lptimeouts
->ReadTotalTimeoutMultiplier
;
1498 req
->readconst
= lptimeouts
->ReadTotalTimeoutConstant
;
1499 req
->writemult
= lptimeouts
->WriteTotalTimeoutMultiplier
;
1500 req
->writeconst
= lptimeouts
->WriteTotalTimeoutConstant
;
1501 ret
= !wine_server_call_err( req
);
1504 if (!ret
) return FALSE
;
1506 /* FIXME: move this stuff to the server */
1507 fd
= FILE_GetUnixHandle( hComm
, GENERIC_READ
);
1509 FIXME("no fd for handle = %0x!.\n",hComm
);
1513 if (-1==tcgetattr(fd
,&tios
)) {
1514 FIXME("tcgetattr on fd %d failed!\n",fd
);
1518 /* VTIME is in 1/10 seconds */
1520 unsigned int ux_timeout
;
1522 if(lptimeouts
->ReadIntervalTimeout
== 0) /* 0 means no timeout */
1528 ux_timeout
= (lptimeouts
->ReadIntervalTimeout
+99)/100;
1531 ux_timeout
= 1; /* must be at least some timeout */
1534 tios
.c_cc
[VTIME
] = ux_timeout
;
1537 if (-1==tcsetattr(fd
,0,&tios
)) {
1538 FIXME("tcsetattr on fd %d failed!\n",fd
);
1545 /***********************************************************************
1546 * GetCommModemStatus (KERNEL32.@)
1548 * Obtains the four control register bits if supported by the hardware.
1552 * True if the communications handle was good and for hardware that
1553 * control register access, false otherwise.
1555 BOOL WINAPI
GetCommModemStatus(
1556 HANDLE hFile
, /* [in] The communications device. */
1557 LPDWORD lpModemStat
) /* [out] The control register bits. */
1559 int fd
,mstat
, result
=FALSE
;
1563 fd
= FILE_GetUnixHandle( hFile
, GENERIC_READ
);
1566 result
= ioctl(fd
, TIOCMGET
, &mstat
);
1570 WARN("ioctl failed\n");
1574 if (mstat
& TIOCM_CTS
)
1575 *lpModemStat
|= MS_CTS_ON
;
1578 if (mstat
& TIOCM_DSR
)
1579 *lpModemStat
|= MS_DSR_ON
;
1582 if (mstat
& TIOCM_RNG
)
1583 *lpModemStat
|= MS_RING_ON
;
1586 /*FIXME: Not really sure about RLSD UB 990810*/
1587 if (mstat
& TIOCM_CAR
)
1588 *lpModemStat
|= MS_RLSD_ON
;
1590 TRACE("%04x -> %s%s%s%s\n", mstat
,
1591 (*lpModemStat
&MS_RLSD_ON
)?"MS_RLSD_ON ":"",
1592 (*lpModemStat
&MS_RING_ON
)?"MS_RING_ON ":"",
1593 (*lpModemStat
&MS_DSR_ON
)?"MS_DSR_ON ":"",
1594 (*lpModemStat
&MS_CTS_ON
)?"MS_CTS_ON ":"");
1601 /***********************************************************************
1602 * COMM_WaitCommEventService (INTERNAL)
1604 * This function is called while the client is waiting on the
1605 * server, so we can't make any server calls here.
1607 static void COMM_WaitCommEventService(async_private
*ovp
)
1609 async_commio
*commio
= (async_commio
*) ovp
;
1610 LPOVERLAPPED lpOverlapped
= commio
->lpOverlapped
;
1612 TRACE("overlapped %p\n",lpOverlapped
);
1614 /* FIXME: detect other events */
1615 *commio
->buffer
= EV_RXCHAR
;
1617 lpOverlapped
->Internal
= STATUS_SUCCESS
;
1621 /***********************************************************************
1622 * COMM_WaitCommEvent (INTERNAL)
1624 * This function must have an lpOverlapped.
1626 static BOOL
COMM_WaitCommEvent(
1627 HANDLE hFile
, /* [in] handle of comm port to wait for */
1628 LPDWORD lpdwEvents
, /* [out] event(s) that were detected */
1629 LPOVERLAPPED lpOverlapped
) /* [in/out] for Asynchronous waiting */
1636 SetLastError(ERROR_INVALID_PARAMETER
);
1640 if(NtResetEvent(lpOverlapped
->hEvent
,NULL
))
1643 fd
= FILE_GetUnixHandle( hFile
, GENERIC_WRITE
);
1647 ovp
= (async_commio
*) HeapAlloc(GetProcessHeap(), 0, sizeof (async_commio
));
1654 ovp
->async
.ops
= &commio_async_ops
;
1655 ovp
->async
.handle
= hFile
;
1657 ovp
->async
.type
= ASYNC_TYPE_WAIT
;
1658 ovp
->async
.func
= COMM_WaitCommEventService
;
1659 ovp
->async
.event
= lpOverlapped
->hEvent
;
1660 ovp
->lpOverlapped
= lpOverlapped
;
1661 ovp
->buffer
= (char *)lpdwEvents
;
1663 lpOverlapped
->InternalHigh
= 0;
1664 lpOverlapped
->Offset
= 0;
1665 lpOverlapped
->OffsetHigh
= 0;
1667 if ( !register_new_async (&ovp
->async
) )
1668 SetLastError( ERROR_IO_PENDING
);
1673 /***********************************************************************
1674 * WaitCommEvent (KERNEL32.@)
1676 * Wait until something interesting happens on a COMM port.
1677 * Interesting things (events) are set by calling SetCommMask before
1678 * this function is called.
1681 * TRUE if successful
1684 * The set of detected events will be written to *lpdwEventMask
1685 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1688 * Only supports EV_RXCHAR and EV_TXEMPTY
1690 BOOL WINAPI
WaitCommEvent(
1691 HANDLE hFile
, /* [in] handle of comm port to wait for */
1692 LPDWORD lpdwEvents
, /* [out] event(s) that were detected */
1693 LPOVERLAPPED lpOverlapped
) /* [in/out] for Asynchronous waiting */
1698 TRACE("(%x %p %p )\n",hFile
, lpdwEvents
,lpOverlapped
);
1701 return COMM_WaitCommEvent(hFile
, lpdwEvents
, lpOverlapped
);
1703 /* if there is no overlapped structure, create our own */
1704 ov
.hEvent
= CreateEventA(NULL
,FALSE
,FALSE
,NULL
);
1706 COMM_WaitCommEvent(hFile
, lpdwEvents
, &ov
);
1708 if(GetLastError()!=STATUS_PENDING
)
1710 CloseHandle(ov
.hEvent
);
1714 /* wait for the overlapped to complete */
1715 ret
= GetOverlappedResult(hFile
, &ov
, NULL
, TRUE
);
1716 CloseHandle(ov
.hEvent
);
1721 /***********************************************************************
1722 * GetCommProperties (KERNEL32.@)
1724 * This function fills in a structure with the capabilities of the
1725 * communications port driver.
1729 * TRUE on success, FALSE on failure
1730 * If successful, the lpCommProp structure be filled in with
1731 * properties of the comm port.
1733 BOOL WINAPI
GetCommProperties(
1734 HANDLE hFile
, /* [in] handle of the comm port */
1735 LPCOMMPROP lpCommProp
) /* [out] pointer to struct to be filled */
1737 FIXME("(%d %p )\n",hFile
,lpCommProp
);
1742 * These values should be valid for LINUX's serial driver
1743 * FIXME: Perhaps they deserve an #ifdef LINUX
1745 memset(lpCommProp
,0,sizeof(COMMPROP
));
1746 lpCommProp
->wPacketLength
= 1;
1747 lpCommProp
->wPacketVersion
= 1;
1748 lpCommProp
->dwServiceMask
= SP_SERIALCOMM
;
1749 lpCommProp
->dwReserved1
= 0;
1750 lpCommProp
->dwMaxTxQueue
= 4096;
1751 lpCommProp
->dwMaxRxQueue
= 4096;
1752 lpCommProp
->dwMaxBaud
= BAUD_115200
;
1753 lpCommProp
->dwProvSubType
= PST_RS232
;
1754 lpCommProp
->dwProvCapabilities
= PCF_DTRDSR
| PCF_PARITY_CHECK
| PCF_RTSCTS
;
1755 lpCommProp
->dwSettableParams
= SP_BAUD
| SP_DATABITS
| SP_HANDSHAKING
|
1756 SP_PARITY
| SP_PARITY_CHECK
| SP_STOPBITS
;
1757 lpCommProp
->dwSettableBaud
= BAUD_075
| BAUD_110
| BAUD_134_5
| BAUD_150
|
1758 BAUD_300
| BAUD_600
| BAUD_1200
| BAUD_1800
| BAUD_2400
| BAUD_4800
|
1759 BAUD_9600
| BAUD_19200
| BAUD_38400
| BAUD_57600
| BAUD_115200
;
1760 lpCommProp
->wSettableData
= DATABITS_5
| DATABITS_6
| DATABITS_7
| DATABITS_8
;
1761 lpCommProp
->wSettableStopParity
= STOPBITS_10
| STOPBITS_15
| STOPBITS_20
|
1762 PARITY_NONE
| PARITY_ODD
|PARITY_EVEN
| PARITY_MARK
| PARITY_SPACE
;
1763 lpCommProp
->dwCurrentTxQueue
= lpCommProp
->dwMaxTxQueue
;
1764 lpCommProp
->dwCurrentRxQueue
= lpCommProp
->dwMaxRxQueue
;
1769 /***********************************************************************
1771 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1772 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1773 * This is dependent on the type of COMM port, but since it is doubtful
1774 * anybody will get around to implementing support for fancy serial
1775 * ports in WINE, this is hardcoded for the time being. The name of
1776 * this DLL should be stored in and read from the system registry in
1777 * the hive HKEY_LOCAL_MACHINE, key
1778 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1779 * where ???? is the port number... that is determined by PNP
1780 * The DLL should be loaded when the COMM port is opened, and closed
1781 * when the COMM port is closed. - MJM 20 June 2000
1782 ***********************************************************************/
1783 static CHAR lpszSerialUI
[] = "serialui.dll";
1786 /***********************************************************************
1787 * CommConfigDialogA (KERNEL32.@)
1789 * Raises a dialog that allows the user to configure a comm port.
1790 * Fills the COMMCONFIG struct with information specified by the user.
1791 * This function should call a similar routine in the COMM driver...
1795 * TRUE on success, FALSE on failure
1796 * If successful, the lpCommConfig structure will contain a new
1797 * configuration for the comm port, as specified by the user.
1800 * The library with the CommConfigDialog code is never unloaded.
1801 * Perhaps this should be done when the comm port is closed?
1803 BOOL WINAPI
CommConfigDialogA(
1804 LPCSTR lpszDevice
, /* [in] name of communications device */
1805 HANDLE hWnd
, /* [in] parent window for the dialog */
1806 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
1808 FARPROC lpfnCommDialog
;
1809 HMODULE hConfigModule
;
1812 TRACE("(%p %x %p)\n",lpszDevice
, hWnd
, lpCommConfig
);
1814 hConfigModule
= LoadLibraryA(lpszSerialUI
);
1818 lpfnCommDialog
= GetProcAddress(hConfigModule
, (LPCSTR
)3L);
1823 r
= lpfnCommDialog(lpszDevice
,hWnd
,lpCommConfig
);
1825 /* UnloadLibrary(hConfigModule); */
1830 /***********************************************************************
1831 * CommConfigDialogW (KERNEL32.@)
1833 * see CommConfigDialogA for more info
1835 BOOL WINAPI
CommConfigDialogW(
1836 LPCWSTR lpszDevice
, /* [in] name of communications device */
1837 HANDLE hWnd
, /* [in] parent window for the dialog */
1838 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
1843 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
1846 r
= CommConfigDialogA(lpDeviceA
,hWnd
,lpCommConfig
);
1847 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
1851 /***********************************************************************
1852 * GetCommConfig (KERNEL32.@)
1854 * Fill in the COMMCONFIG structure for the comm port hFile
1858 * TRUE on success, FALSE on failure
1859 * If successful, lpCommConfig contains the comm port configuration.
1864 BOOL WINAPI
GetCommConfig(
1865 HANDLE hFile
, /* [in] The communications device. */
1866 LPCOMMCONFIG lpCommConfig
, /* [out] The communications configuration of the device (if it fits). */
1867 LPDWORD lpdwSize
) /* [in/out] Initially the size of the configuration buffer/structure,
1868 afterwards the number of bytes copied to the buffer or
1869 the needed size of the buffer. */
1873 TRACE("(%x %p)\n",hFile
,lpCommConfig
);
1875 if(lpCommConfig
== NULL
)
1878 r
= *lpdwSize
< sizeof(COMMCONFIG
);
1879 *lpdwSize
= sizeof(COMMCONFIG
);
1883 lpCommConfig
->dwSize
= sizeof(COMMCONFIG
);
1884 lpCommConfig
->wVersion
= 1;
1885 lpCommConfig
->wReserved
= 0;
1886 r
= GetCommState(hFile
,&lpCommConfig
->dcb
);
1887 lpCommConfig
->dwProviderSubType
= PST_RS232
;
1888 lpCommConfig
->dwProviderOffset
= 0;
1889 lpCommConfig
->dwProviderSize
= 0;
1894 /***********************************************************************
1895 * SetCommConfig (KERNEL32.@)
1897 * Sets the configuration of the communications device.
1901 * True on success, false if the handle was bad is not a communications device.
1903 BOOL WINAPI
SetCommConfig(
1904 HANDLE hFile
, /* [in] The communications device. */
1905 LPCOMMCONFIG lpCommConfig
, /* [in] The desired configuration. */
1906 DWORD dwSize
) /* [in] size of the lpCommConfig struct */
1908 TRACE("(%x %p)\n",hFile
,lpCommConfig
);
1909 return SetCommState(hFile
,&lpCommConfig
->dcb
);
1912 /***********************************************************************
1913 * SetDefaultCommConfigA (KERNEL32.@)
1915 * Initializes the default configuration for the specified communication
1920 * True if the device was found and the defaults set, false otherwise
1922 BOOL WINAPI
SetDefaultCommConfigA(
1923 LPCSTR lpszDevice
, /* [in] The ascii name of the device targeted for configuration. */
1924 LPCOMMCONFIG lpCommConfig
, /* [in] The default configuration for the device. */
1925 DWORD dwSize
) /* [in] The number of bytes in the configuration structure. */
1927 FARPROC lpfnSetDefaultCommConfig
;
1928 HMODULE hConfigModule
;
1931 TRACE("(%p %p %lx)\n",lpszDevice
, lpCommConfig
, dwSize
);
1933 hConfigModule
= LoadLibraryA(lpszSerialUI
);
1937 lpfnSetDefaultCommConfig
= GetProcAddress(hConfigModule
, (LPCSTR
)4L);
1939 if(! lpfnSetDefaultCommConfig
)
1942 r
= lpfnSetDefaultCommConfig(lpszDevice
, lpCommConfig
, dwSize
);
1944 /* UnloadLibrary(hConfigModule); */
1950 /***********************************************************************
1951 * SetDefaultCommConfigW (KERNEL32.@)
1953 * Initializes the default configuration for the specified
1954 * communication device. (unicode)
1959 BOOL WINAPI
SetDefaultCommConfigW(
1960 LPCWSTR lpszDevice
, /* [in] The unicode name of the device targeted for configuration. */
1961 LPCOMMCONFIG lpCommConfig
, /* [in] The default configuration for the device. */
1962 DWORD dwSize
) /* [in] The number of bytes in the configuration structure. */
1967 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice
),lpCommConfig
,dwSize
);
1969 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
1972 r
= SetDefaultCommConfigA(lpDeviceA
,lpCommConfig
,dwSize
);
1973 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
1978 /***********************************************************************
1979 * GetDefaultCommConfigA (KERNEL32.@)
1981 * Acquires the default configuration of the specified communication device. (unicode)
1985 * True on successful reading of the default configuration,
1986 * if the device is not found or the buffer is too small.
1988 BOOL WINAPI
GetDefaultCommConfigA(
1989 LPCSTR lpszName
, /* [in] The ascii name of the device targeted for configuration. */
1990 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
1991 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
1992 afterwards the number of bytes copied to the buffer or
1993 the needed size of the buffer. */
1995 LPDCB lpdcb
= &(lpCC
->dcb
);
1998 if (strncasecmp(lpszName
,"COM",3)) {
1999 ERR("not implemented for <%s>\n", lpszName
);
2003 TRACE("(%s %p %ld)\n", lpszName
, lpCC
, *lpdwSize
);
2004 if (*lpdwSize
< sizeof(COMMCONFIG
)) {
2005 *lpdwSize
= sizeof(COMMCONFIG
);
2009 *lpdwSize
= sizeof(COMMCONFIG
);
2011 lpCC
->dwSize
= sizeof(COMMCONFIG
);
2013 lpCC
->dwProviderSubType
= PST_RS232
;
2014 lpCC
->dwProviderOffset
= 0L;
2015 lpCC
->dwProviderSize
= 0L;
2017 sprintf( temp
, "COM%c:38400,n,8,1", lpszName
[3]);
2018 FIXME("setting %s as default\n", temp
);
2020 return BuildCommDCBA( temp
, lpdcb
);
2023 /**************************************************************************
2024 * GetDefaultCommConfigW (KERNEL32.@)
2026 * Acquires the default configuration of the specified communication device. (unicode)
2030 * True on successful reading of the default configuration,
2031 * if the device is not found or the buffer is too small.
2033 BOOL WINAPI
GetDefaultCommConfigW(
2034 LPCWSTR lpszName
, /* [in] The unicode name of the device targeted for configuration. */
2035 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
2036 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
2037 afterwards the number of bytes copied to the buffer or
2038 the needed size of the buffer. */
2043 TRACE("(%p,%p,%ld)\n",lpszName
,lpCC
,*lpdwSize
);
2044 lpszNameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName
);
2047 ret
=GetDefaultCommConfigA(lpszNameA
,lpCC
,lpdwSize
);
2048 HeapFree( GetProcessHeap(), 0, lpszNameA
);