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"
68 #ifdef HAVE_SYS_FILIO_H
69 # include <sys/filio.h>
71 #ifdef HAVE_SYS_IOCTL_H
72 #include <sys/ioctl.h>
77 #ifdef HAVE_SYS_POLL_H
78 # include <sys/poll.h>
80 #ifdef HAVE_SYS_MODEM_H
81 # include <sys/modem.h>
83 #ifdef HAVE_SYS_STRTIO_H
84 # include <sys/strtio.h>
90 #include "wine/server.h"
95 #include "wine/debug.h"
97 #ifdef HAVE_LINUX_SERIAL_H
98 #include <linux/serial.h>
101 WINE_DEFAULT_DEBUG_CHANNEL(comm
);
103 /***********************************************************************
104 * Asynchronous I/O for asynchronous wait requests *
107 static DWORD
commio_get_async_status (const async_private
*ovp
);
108 static DWORD
commio_get_async_count (const async_private
*ovp
);
109 static void commio_set_async_status (async_private
*ovp
, const DWORD status
);
110 static void commio_async_cleanup (async_private
*ovp
);
112 static async_ops commio_async_ops
=
114 commio_get_async_status
, /* get_status */
115 commio_set_async_status
, /* set_status */
116 commio_get_async_count
, /* get_count */
117 NULL
, /* call_completion */
118 commio_async_cleanup
/* cleanup */
121 typedef struct async_commio
123 struct async_private async
;
124 LPOVERLAPPED lpOverlapped
;
128 static DWORD
commio_get_async_status (const struct async_private
*ovp
)
130 return ((async_commio
*) ovp
)->lpOverlapped
->Internal
;
133 static void commio_set_async_status (async_private
*ovp
, const DWORD status
)
135 ((async_commio
*) ovp
)->lpOverlapped
->Internal
= status
;
138 static DWORD
commio_get_async_count (const struct async_private
*ovp
)
143 static void commio_async_cleanup (async_private
*ovp
)
145 HeapFree(GetProcessHeap(), 0, ovp
);
148 /***********************************************************************/
150 #if !defined(TIOCINQ) && defined(FIONREAD)
151 #define TIOCINQ FIONREAD
154 static int COMM_WhackModem(int fd
, unsigned int andy
, unsigned int orrie
)
157 unsigned int mstat
, okay
;
158 okay
= ioctl(fd
, TIOCMGET
, &mstat
);
159 if (okay
) return okay
;
160 if (andy
) mstat
&= andy
;
162 return ioctl(fd
, TIOCMSET
, &mstat
);
168 /***********************************************************************
169 * COMM_BuildOldCommDCB (Internal)
171 * Build a DCB using the old style settings string eg: "COMx:96,n,8,1"
172 * We ignore the COM port index, since we can support more than 4 ports.
174 BOOL WINAPI
COMM_BuildOldCommDCB(LPCSTR device
, LPDCB lpdcb
)
176 /* "COM1:96,n,8,1" */
178 char *ptr
, temp
[256], last
;
181 TRACE("(%s), ptr %p\n", device
, lpdcb
);
183 /* Some applications call this function with "9600,n,8,1"
184 * not sending the "COM1:" parameter at left of string */
185 if (!strncasecmp(device
,"COM",3))
187 if (!device
[3]) return FALSE
;
188 if (device
[4] != ':' && device
[4] != ' ') return FALSE
;
189 strcpy(temp
,device
+5);
191 else strcpy(temp
,device
);
193 last
=temp
[strlen(temp
)-1];
194 ptr
= strtok(temp
, ", ");
196 /* DOS/Windows only compares the first two numbers
197 * and assigns an appropriate baud rate.
198 * You can supply 961324245, it still returns 9600 ! */
201 WARN("Unknown baudrate string '%s' !\n", ptr
);
202 return FALSE
; /* error: less than 2 chars */
223 WARN("Unknown baudrate indicator %d !\n", rate
);
227 lpdcb
->BaudRate
= rate
;
228 TRACE("baudrate (%ld)\n", lpdcb
->BaudRate
);
230 ptr
= strtok(NULL
, ", ");
232 *ptr
= toupper(*ptr
);
234 TRACE("parity (%c)\n", *ptr
);
235 lpdcb
->fParity
= TRUE
;
238 lpdcb
->Parity
= NOPARITY
;
239 lpdcb
->fParity
= FALSE
;
242 lpdcb
->Parity
= EVENPARITY
;
245 lpdcb
->Parity
= MARKPARITY
;
248 lpdcb
->Parity
= ODDPARITY
;
251 lpdcb
->Parity
= SPACEPARITY
;
254 WARN("Unknown parity `%c'!\n", *ptr
);
258 ptr
= strtok(NULL
, ", ");
259 TRACE("charsize (%c)\n", *ptr
);
260 lpdcb
->ByteSize
= *ptr
- '0';
262 ptr
= strtok(NULL
, ", ");
263 TRACE("stopbits (%c)\n", *ptr
);
266 lpdcb
->StopBits
= ONESTOPBIT
;
269 lpdcb
->StopBits
= TWOSTOPBITS
;
272 WARN("Unknown # of stopbits `%c'!\n", *ptr
);
279 lpdcb
->fOutxCtsFlow
= FALSE
;
280 lpdcb
->fOutxDsrFlow
= FALSE
;
281 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
282 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
283 } else if (last
=='p') {
285 lpdcb
->fOutX
= FALSE
;
286 lpdcb
->fOutxCtsFlow
= TRUE
;
287 lpdcb
->fOutxDsrFlow
= FALSE
;
288 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
289 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
292 lpdcb
->fOutX
= FALSE
;
293 lpdcb
->fOutxCtsFlow
= FALSE
;
294 lpdcb
->fOutxDsrFlow
= FALSE
;
295 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
296 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
302 /**************************************************************************
303 * BuildCommDCBA (KERNEL32.@)
305 * Updates a device control block data structure with values from an
306 * ascii device control string. The device control string has two forms
307 * normal and extended, it must be exclusively in one or the other form.
311 * True on success, false on a malformed control string.
313 BOOL WINAPI
BuildCommDCBA(
314 LPCSTR device
, /* [in] The ascii device control string used to update the DCB. */
315 LPDCB lpdcb
) /* [out] The device control block to be updated. */
317 return BuildCommDCBAndTimeoutsA(device
,lpdcb
,NULL
);
320 /**************************************************************************
321 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
323 * Updates a device control block data structure with values from an
324 * ascii device control string. Taking timeout values from a timeouts
325 * struct if desired by the control string.
329 * True on success, false bad handles etc
331 BOOL WINAPI
BuildCommDCBAndTimeoutsA(
332 LPCSTR device
, /* [in] The ascii device control string. */
333 LPDCB lpdcb
, /* [out] The device control block to be updated. */
334 LPCOMMTIMEOUTS lptimeouts
) /* [in] The timeouts to use if asked to set them by the control string. */
339 TRACE("(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
341 if (!strncasecmp(device
,"COM",3)) {
344 ERR("BUG! COM0 can't exist!\n");
347 if ((*(device
+4)!=':') && (*(device
+4)!=' '))
349 temp
=(LPSTR
)(device
+5);
353 memset(lpdcb
,0,sizeof (DCB
));
354 lpdcb
->DCBlength
= sizeof(DCB
);
355 if (strchr(temp
,',')) { /* old style */
357 return COMM_BuildOldCommDCB(device
,lpdcb
);
359 ptr
=strtok(temp
," ");
364 if (!strncasecmp("baud=",ptr
,5)) {
365 if (!sscanf(ptr
+5,"%ld",&x
))
366 WARN("Couldn't parse %s\n",ptr
);
370 if (!strncasecmp("stop=",ptr
,5)) {
371 if (!sscanf(ptr
+5,"%ld",&x
))
372 WARN("Couldn't parse %s\n",ptr
);
376 if (!strncasecmp("data=",ptr
,5)) {
377 if (!sscanf(ptr
+5,"%ld",&x
))
378 WARN("Couldn't parse %s\n",ptr
);
382 if (!strncasecmp("parity=",ptr
,7)) {
383 lpdcb
->fParity
= TRUE
;
386 lpdcb
->fParity
= FALSE
;
387 lpdcb
->Parity
= NOPARITY
;
390 lpdcb
->Parity
= EVENPARITY
;
393 lpdcb
->Parity
= ODDPARITY
;
396 lpdcb
->Parity
= MARKPARITY
;
399 lpdcb
->Parity
= SPACEPARITY
;
405 ERR("Unhandled specifier '%s', please report.\n",ptr
);
406 ptr
=strtok(NULL
," ");
408 if (lpdcb
->BaudRate
==110)
413 /**************************************************************************
414 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
416 * Updates a device control block data structure with values from an
417 * unicode device control string. Taking timeout values from a timeouts
418 * struct if desired by the control string.
422 * True on success, false bad handles etc.
424 BOOL WINAPI
BuildCommDCBAndTimeoutsW(
425 LPCWSTR devid
, /* [in] The unicode device control string. */
426 LPDCB lpdcb
, /* [out] The device control block to be updated. */
427 LPCOMMTIMEOUTS lptimeouts
) /* [in] The timeouts to use if asked to set them by the control string. */
432 TRACE("(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
433 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
436 ret
=BuildCommDCBAndTimeoutsA(devidA
,lpdcb
,lptimeouts
);
437 HeapFree( GetProcessHeap(), 0, devidA
);
442 /**************************************************************************
443 * BuildCommDCBW (KERNEL32.@)
445 * Updates a device control block structure with values from an
446 * unicode device control string. The device control string has two forms
447 * normal and extended, it must be exclusively in one or the other form.
451 * True on success, false on an malformed control string.
453 BOOL WINAPI
BuildCommDCBW(
454 LPCWSTR devid
, /* [in] The unicode device control string. */
455 LPDCB lpdcb
) /* [out] The device control block to be updated. */
457 return BuildCommDCBAndTimeoutsW(devid
,lpdcb
,NULL
);
460 static BOOL
COMM_SetCommError(HANDLE handle
, DWORD error
)
464 SERVER_START_REQ( set_serial_info
)
466 req
->handle
= handle
;
467 req
->flags
= SERIALINFO_SET_ERROR
;
468 req
->commerror
= error
;
469 ret
= !wine_server_call_err( req
);
475 static BOOL
COMM_GetCommError(HANDLE handle
, LPDWORD lperror
)
482 SERVER_START_REQ( get_serial_info
)
484 req
->handle
= handle
;
485 ret
= !wine_server_call_err( req
);
486 *lperror
= reply
->commerror
;
493 /*****************************************************************************
494 * SetCommBreak (KERNEL32.@)
496 * Halts the transmission of characters to a communications device.
500 * True on success, and false if the communications device could not be found,
501 * the control is not supported.
505 * Only TIOCSBRK and TIOCCBRK are supported.
507 BOOL WINAPI
SetCommBreak(
508 HANDLE handle
) /* [in] The communictions device to suspend. */
510 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
513 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
515 TRACE("FILE_GetUnixHandle failed\n");
518 result
= ioctl(fd
,TIOCSBRK
,0);
522 TRACE("ioctl failed\n");
523 SetLastError(ERROR_NOT_SUPPORTED
);
528 FIXME("ioctl not available\n");
529 SetLastError(ERROR_NOT_SUPPORTED
);
534 /*****************************************************************************
535 * ClearCommBreak (KERNEL32.@)
537 * Resumes character transmission from a communication device.
541 * True on success and false if the communications device could not be found.
545 * Only TIOCSBRK and TIOCCBRK are supported.
547 BOOL WINAPI
ClearCommBreak(
548 HANDLE handle
) /* [in] The halted communication device whose character transmission is to be resumed. */
550 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
553 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
555 TRACE("FILE_GetUnixHandle failed\n");
558 result
= ioctl(fd
,TIOCCBRK
,0);
562 TRACE("ioctl failed\n");
563 SetLastError(ERROR_NOT_SUPPORTED
);
568 FIXME("ioctl not available\n");
569 SetLastError(ERROR_NOT_SUPPORTED
);
574 /*****************************************************************************
575 * EscapeCommFunction (KERNEL32.@)
577 * Directs a communication device to perform an extended function.
581 * True or requested data on successful completion of the command,
582 * false if the device is not present cannot execute the command
583 * or the command failed.
585 BOOL WINAPI
EscapeCommFunction(
586 HANDLE handle
, /* [in] The communication device to perform the extended function. */
587 UINT nFunction
) /* [in] The extended function to be performed. */
589 int fd
,direct
=FALSE
,result
=FALSE
;
592 TRACE("handle %p, function=%d\n", handle
, nFunction
);
593 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
595 FIXME("handle %p not found.\n",handle
);
599 if (tcgetattr(fd
,&port
) == -1) {
600 COMM_SetCommError(handle
,CE_IOE
);
614 result
= COMM_WhackModem(fd
, ~TIOCM_DTR
, 0);
622 result
= COMM_WhackModem(fd
, ~TIOCM_RTS
, 0);
630 result
= COMM_WhackModem(fd
, 0, TIOCM_DTR
);
638 result
= COMM_WhackModem(fd
, 0, TIOCM_RTS
);
644 port
.c_iflag
|= IXOFF
;
649 port
.c_iflag
|= IXON
;
655 result
= ioctl(fd
,TIOCSBRK
,0);
662 result
= ioctl(fd
,TIOCCBRK
,0);
666 WARN("(handle=%p,nFunction=%d): Unknown function\n",
672 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
674 COMM_SetCommError(handle
,CE_IOE
);
683 COMM_SetCommError(handle
,CE_IOE
);
692 /********************************************************************
693 * PurgeComm (KERNEL32.@)
695 * Terminates pending operations and/or discards buffers on a
696 * communication resource.
700 * True on success and false if the communications handle is bad.
702 BOOL WINAPI
PurgeComm(
703 HANDLE handle
, /* [in] The communication resource to be purged. */
704 DWORD flags
) /* [in] Flags for clear pending/buffer on input/output. */
708 TRACE("handle %p, flags %lx\n", handle
, flags
);
710 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
712 FIXME("no handle %p found\n",handle
);
717 ** not exactly sure how these are different
718 ** Perhaps if we had our own internal queues, one flushes them
719 ** and the other flushes the kernel's buffers.
721 if(flags
&PURGE_TXABORT
)
722 tcflush(fd
,TCOFLUSH
);
723 if(flags
&PURGE_RXABORT
)
724 tcflush(fd
,TCIFLUSH
);
725 if(flags
&PURGE_TXCLEAR
)
726 tcflush(fd
,TCOFLUSH
);
727 if(flags
&PURGE_RXCLEAR
)
728 tcflush(fd
,TCIFLUSH
);
734 /*****************************************************************************
735 * ClearCommError (KERNEL32.@)
737 * Enables further I/O operations on a communications resource after
738 * supplying error and current status information.
742 * True on success, false if the communication resource handle is bad.
744 BOOL WINAPI
ClearCommError(
745 HANDLE handle
, /* [in] The communication resource with the error. */
746 LPDWORD errors
, /* [out] Flags indicating error the resource experienced. */
747 LPCOMSTAT lpStat
) /* [out] The status of the communication resource. */
751 fd
=FILE_GetUnixHandle( handle
, GENERIC_READ
);
754 FIXME("no handle %p found\n",handle
);
760 lpStat
->fCtsHold
= 0;
761 lpStat
->fDsrHold
= 0;
762 lpStat
->fRlsdHold
= 0;
763 lpStat
->fXoffHold
= 0;
764 lpStat
->fXoffSent
= 0;
767 lpStat
->fReserved
= 0;
770 if(ioctl(fd
, TIOCOUTQ
, &lpStat
->cbOutQue
))
771 WARN("ioctl returned error\n");
773 lpStat
->cbOutQue
= 0; /* FIXME: find a different way to find out */
777 if(ioctl(fd
, TIOCINQ
, &lpStat
->cbInQue
))
778 WARN("ioctl returned error\n");
781 TRACE("handle %p cbInQue = %ld cbOutQue = %ld\n",
782 handle
, lpStat
->cbInQue
, lpStat
->cbOutQue
);
787 COMM_GetCommError(handle
, errors
);
788 COMM_SetCommError(handle
, 0);
793 /*****************************************************************************
794 * SetupComm (KERNEL32.@)
796 * Called after CreateFile to hint to the communication resource to use
797 * specified sizes for input and output buffers rather than the default values.
801 * True if successful, false if the communications resource handle is bad.
807 BOOL WINAPI
SetupComm(
808 HANDLE handle
, /* [in] The just created communication resource handle. */
809 DWORD insize
, /* [in] The suggested size of the communication resources input buffer in bytes. */
810 DWORD outsize
) /* [in] The suggested size of the communication resources output buffer in bytes. */
814 FIXME("insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
815 fd
=FILE_GetUnixHandle( handle
, GENERIC_READ
);
817 FIXME("handle %p not found?\n",handle
);
824 /*****************************************************************************
825 * GetCommMask (KERNEL32.@)
827 * Obtain the events associated with a communication device that will cause
828 * a call WaitCommEvent to return.
832 * True on success, fail on bad device handle etc.
834 BOOL WINAPI
GetCommMask(
835 HANDLE handle
, /* [in] The communications device. */
836 LPDWORD evtmask
) /* [out] The events which cause WaitCommEvent to return. */
840 TRACE("handle %p, mask %p\n", handle
, evtmask
);
842 SERVER_START_REQ( get_serial_info
)
844 req
->handle
= handle
;
845 if ((ret
= !wine_server_call_err( req
)))
847 if (evtmask
) *evtmask
= reply
->eventmask
;
854 /*****************************************************************************
855 * SetCommMask (KERNEL32.@)
857 * There be some things we need to hear about yon there communications device.
858 * (Set which events associated with a communication device should cause
859 * a call WaitCommEvent to return.)
863 * True on success, false on bad handle etc.
865 BOOL WINAPI
SetCommMask(
866 HANDLE handle
, /* [in] The communications device. */
867 DWORD evtmask
) /* [in] The events that are to be monitored. */
871 TRACE("handle %p, mask %lx\n", handle
, evtmask
);
873 SERVER_START_REQ( set_serial_info
)
875 req
->handle
= handle
;
876 req
->flags
= SERIALINFO_SET_MASK
;
877 req
->eventmask
= evtmask
;
878 ret
= !wine_server_call_err( req
);
884 /*****************************************************************************
885 * SetCommState (KERNEL32.@)
887 * Re-initializes all hardware and control settings of a communications device,
888 * with values from a device control block without effecting the input and output
893 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
895 BOOL WINAPI
SetCommState(
896 HANDLE handle
, /* [in] The communications device. */
897 LPDCB lpdcb
) /* [out] The device control block. */
900 int fd
, bytesize
, stopbits
;
902 TRACE("handle %p, ptr %p\n", handle
, lpdcb
);
903 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
904 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
905 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
906 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
907 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
908 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
910 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
912 FIXME("no handle %p found\n",handle
);
916 if ((tcgetattr(fd
,&port
)) == -1) {
917 int save_error
= errno
;
918 COMM_SetCommError(handle
,CE_IOE
);
920 ERR("tcgetattr error '%s'\n", strerror(save_error
));
925 port
.c_cc
[VTIME
] = 1;
928 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
930 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
932 port
.c_iflag
|= (IGNBRK
);
934 port
.c_oflag
&= ~(OPOST
);
936 port
.c_cflag
&= ~(HUPCL
);
937 port
.c_cflag
|= CLOCAL
| CREAD
;
939 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
940 port
.c_lflag
|= NOFLSH
;
943 port
.c_cflag
&= ~CBAUD
;
944 switch (lpdcb
->BaudRate
) {
947 port
.c_cflag
|= B110
;
951 port
.c_cflag
|= B300
;
955 port
.c_cflag
|= B600
;
959 port
.c_cflag
|= B1200
;
963 port
.c_cflag
|= B2400
;
967 port
.c_cflag
|= B4800
;
971 port
.c_cflag
|= B9600
;
975 port
.c_cflag
|= B19200
;
979 port
.c_cflag
|= B38400
;
983 port
.c_cflag
|= B57600
;
988 port
.c_cflag
|= B115200
;
993 port
.c_cflag
|= B230400
;
998 port
.c_cflag
|= B460800
;
1002 #if defined (HAVE_LINUX_SERIAL_H) && defined (TIOCSSERIAL)
1003 { struct serial_struct nuts
;
1005 ioctl(fd
, TIOCGSERIAL
, &nuts
);
1006 nuts
.custom_divisor
= nuts
.baud_base
/ lpdcb
->BaudRate
;
1007 if (!(nuts
.custom_divisor
)) nuts
.custom_divisor
= 1;
1008 arby
= nuts
.baud_base
/ nuts
.custom_divisor
;
1009 nuts
.flags
&= ~ASYNC_SPD_MASK
;
1010 nuts
.flags
|= ASYNC_SPD_CUST
;
1011 WARN("You (or a program acting at your behest) have specified\n"
1012 "a non-standard baud rate %ld. Wine will set the rate to %d,\n"
1013 "which is as close as we can get by our present understanding of your\n"
1014 "hardware. I hope you know what you are doing. Any disruption Wine\n"
1015 "has caused to your linux system can be undone with setserial \n"
1016 "(see man setserial). If you have incapacitated a Hayes type modem,\n"
1017 "reset it and it will probably recover.\n", lpdcb
->BaudRate
, arby
);
1018 ioctl(fd
, TIOCSSERIAL
, &nuts
);
1019 port
.c_cflag
|= B38400
;
1022 #endif /* Don't have linux/serial.h or lack TIOCSSERIAL */
1025 COMM_SetCommError(handle
,IE_BAUDRATE
);
1027 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
1030 #elif !defined(__EMX__)
1031 switch (lpdcb
->BaudRate
) {
1034 port
.c_ospeed
= B110
;
1038 port
.c_ospeed
= B300
;
1042 port
.c_ospeed
= B600
;
1046 port
.c_ospeed
= B1200
;
1050 port
.c_ospeed
= B2400
;
1054 port
.c_ospeed
= B4800
;
1058 port
.c_ospeed
= B9600
;
1062 port
.c_ospeed
= B19200
;
1066 port
.c_ospeed
= B38400
;
1071 port
.c_cflag
|= B57600
;
1077 port
.c_cflag
|= B115200
;
1082 port
.c_cflag
|= B230400
;
1087 port
.c_cflag
|= B460800
;
1091 COMM_SetCommError(handle
,IE_BAUDRATE
);
1093 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
1096 port
.c_ispeed
= port
.c_ospeed
;
1098 bytesize
=lpdcb
->ByteSize
;
1099 stopbits
=lpdcb
->StopBits
;
1102 port
.c_cflag
&= ~(PARENB
| PARODD
| CMSPAR
);
1104 port
.c_cflag
&= ~(PARENB
| PARODD
);
1107 port
.c_iflag
|= INPCK
;
1109 port
.c_iflag
&= ~INPCK
;
1110 switch (lpdcb
->Parity
) {
1114 port
.c_cflag
|= (PARENB
| PARODD
);
1117 port
.c_cflag
|= PARENB
;
1120 /* Linux defines mark/space (stick) parity */
1122 port
.c_cflag
|= (PARENB
| CMSPAR
);
1125 port
.c_cflag
|= (PARENB
| PARODD
| CMSPAR
);
1128 /* try the POSIX way */
1130 if( stopbits
== ONESTOPBIT
) {
1131 stopbits
= TWOSTOPBITS
;
1132 port
.c_iflag
&= ~INPCK
;
1134 COMM_SetCommError(handle
,IE_BYTESIZE
);
1136 ERR("Cannot set MARK Parity\n");
1143 port
.c_iflag
&= ~INPCK
;
1145 COMM_SetCommError(handle
,IE_BYTESIZE
);
1147 ERR("Cannot set SPACE Parity\n");
1153 COMM_SetCommError(handle
,IE_BYTESIZE
);
1160 port
.c_cflag
&= ~CSIZE
;
1163 port
.c_cflag
|= CS5
;
1166 port
.c_cflag
|= CS6
;
1169 port
.c_cflag
|= CS7
;
1172 port
.c_cflag
|= CS8
;
1175 COMM_SetCommError(handle
,IE_BYTESIZE
);
1183 port
.c_cflag
&= ~CSTOPB
;
1185 case ONE5STOPBITS
: /* wil be selected if bytesize is 5 */
1187 port
.c_cflag
|= CSTOPB
;
1190 COMM_SetCommError(handle
,IE_BYTESIZE
);
1196 if ( lpdcb
->fOutxCtsFlow
||
1197 lpdcb
->fRtsControl
== RTS_CONTROL_HANDSHAKE
1200 port
.c_cflag
|= CRTSCTS
;
1205 if (lpdcb
->fDtrControl
== DTR_CONTROL_HANDSHAKE
)
1207 WARN("DSR/DTR flow control not supported\n");
1211 port
.c_iflag
|= IXON
;
1213 port
.c_iflag
&= ~IXON
;
1215 port
.c_iflag
|= IXOFF
;
1217 port
.c_iflag
&= ~IXOFF
;
1219 if (tcsetattr(fd
,TCSANOW
,&port
)==-1) { /* otherwise it hangs with pending input*/
1220 int save_error
=errno
;
1221 COMM_SetCommError(handle
,CE_IOE
);
1223 ERR("tcsetattr error '%s'\n", strerror(save_error
));
1226 COMM_SetCommError(handle
,0);
1233 /*****************************************************************************
1234 * GetCommState (KERNEL32.@)
1236 * Fills in a device control block with information from a communications device.
1240 * True on success, false if the communication device handle is bad etc
1244 * XonChar and XoffChar are not set.
1246 BOOL WINAPI
GetCommState(
1247 HANDLE handle
, /* [in] The communications device. */
1248 LPDCB lpdcb
) /* [out] The device control block. */
1250 struct termios port
;
1253 TRACE("handle %p, ptr %p\n", handle
, lpdcb
);
1255 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
1258 ERR("FILE_GetUnixHandle failed\n");
1261 if (tcgetattr(fd
, &port
) == -1) {
1262 int save_error
=errno
;
1263 ERR("tcgetattr error '%s'\n", strerror(save_error
));
1264 COMM_SetCommError(handle
,CE_IOE
);
1271 speed
= (port
.c_cflag
& CBAUD
);
1273 speed
= (cfgetospeed(&port
));
1277 lpdcb
->BaudRate
= 110;
1280 lpdcb
->BaudRate
= 300;
1283 lpdcb
->BaudRate
= 600;
1286 lpdcb
->BaudRate
= 1200;
1289 lpdcb
->BaudRate
= 2400;
1292 lpdcb
->BaudRate
= 4800;
1295 lpdcb
->BaudRate
= 9600;
1298 lpdcb
->BaudRate
= 19200;
1301 lpdcb
->BaudRate
= 38400;
1305 lpdcb
->BaudRate
= 57600;
1310 lpdcb
->BaudRate
= 115200;
1315 lpdcb
->BaudRate
= 230400;
1320 lpdcb
->BaudRate
= 460800;
1324 ERR("unknown speed %x \n",speed
);
1327 switch (port
.c_cflag
& CSIZE
) {
1329 lpdcb
->ByteSize
= 5;
1332 lpdcb
->ByteSize
= 6;
1335 lpdcb
->ByteSize
= 7;
1338 lpdcb
->ByteSize
= 8;
1341 ERR("unknown size %x \n",port
.c_cflag
& CSIZE
);
1344 if(port
.c_iflag
& INPCK
)
1345 lpdcb
->fParity
= TRUE
;
1347 lpdcb
->fParity
= FALSE
;
1349 switch (port
.c_cflag
& (PARENB
| PARODD
| CMSPAR
))
1351 switch (port
.c_cflag
& (PARENB
| PARODD
))
1355 lpdcb
->Parity
= NOPARITY
;
1358 lpdcb
->Parity
= EVENPARITY
;
1360 case (PARENB
| PARODD
):
1361 lpdcb
->Parity
= ODDPARITY
;
1364 case (PARENB
| CMSPAR
):
1365 lpdcb
->Parity
= MARKPARITY
;
1367 case (PARENB
| PARODD
| CMSPAR
):
1368 lpdcb
->Parity
= SPACEPARITY
;
1373 if (port
.c_cflag
& CSTOPB
)
1374 if(lpdcb
->ByteSize
== 5)
1375 lpdcb
->StopBits
= ONE5STOPBITS
;
1377 lpdcb
->StopBits
= TWOSTOPBITS
;
1379 lpdcb
->StopBits
= ONESTOPBIT
;
1384 /* termios does not support DTR/DSR flow control */
1385 lpdcb
->fOutxDsrFlow
= 0;
1386 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1390 if (port
.c_cflag
& CRTSCTS
) {
1391 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
1392 lpdcb
->fOutxCtsFlow
= 1;
1396 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1397 lpdcb
->fOutxCtsFlow
= 0;
1399 if (port
.c_iflag
& IXON
)
1404 if (port
.c_iflag
& IXOFF
)
1413 lpdcb
->XoffLim
= 10;
1415 COMM_SetCommError(handle
,0);
1419 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1420 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
1421 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
1422 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
1423 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
1424 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
1426 if ( lpdcb
->fOutxCtsFlow
||
1427 lpdcb
->fRtsControl
== RTS_CONTROL_HANDSHAKE
1432 TRACE("~CRTSCTS\n");
1438 /*****************************************************************************
1439 * TransmitCommChar (KERNEL32.@)
1441 * Transmits a single character in front of any pending characters in the
1442 * output buffer. Usually used to send an interrupt character to a host.
1446 * True if the call succeeded, false if the previous command character to the
1447 * same device has not been sent yet the handle is bad etc.
1453 BOOL WINAPI
TransmitCommChar(
1454 HANDLE hComm
, /* [in] The communication device in need of a command character. */
1455 CHAR chTransmit
) /* [in] The character to transmit. */
1460 WARN("(%p,'%c') not perfect!\n",hComm
,chTransmit
);
1462 fd
= FILE_GetUnixHandle( hComm
, GENERIC_READ
);
1464 SetLastError ( ERROR_INVALID_PARAMETER
);
1467 r
= (1 == write(fd
, &chTransmit
, 1));
1475 /*****************************************************************************
1476 * GetCommTimeouts (KERNEL32.@)
1478 * Obtains the request timeout values for the communications device.
1482 * True on success, false if communications device handle is bad
1483 * or the target structure is null.
1485 BOOL WINAPI
GetCommTimeouts(
1486 HANDLE hComm
, /* [in] The communications device. */
1487 LPCOMMTIMEOUTS lptimeouts
) /* [out] The struct of request timeouts. */
1491 TRACE("(%p,%p)\n",hComm
,lptimeouts
);
1495 SetLastError(ERROR_INVALID_PARAMETER
);
1499 SERVER_START_REQ( get_serial_info
)
1501 req
->handle
= hComm
;
1502 if ((ret
= !wine_server_call_err( req
)))
1504 lptimeouts
->ReadIntervalTimeout
= reply
->readinterval
;
1505 lptimeouts
->ReadTotalTimeoutMultiplier
= reply
->readmult
;
1506 lptimeouts
->ReadTotalTimeoutConstant
= reply
->readconst
;
1507 lptimeouts
->WriteTotalTimeoutMultiplier
= reply
->writemult
;
1508 lptimeouts
->WriteTotalTimeoutConstant
= reply
->writeconst
;
1515 /*****************************************************************************
1516 * SetCommTimeouts (KERNEL32.@)
1518 * Sets the timeouts used when reading and writing data to/from COMM ports.
1520 * ReadIntervalTimeout
1521 * - converted and passes to linux kernel as c_cc[VTIME]
1522 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1523 * - used in ReadFile to calculate GetOverlappedResult's timeout
1524 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1525 * - used in WriteFile to calculate GetOverlappedResult's timeout
1529 * True if the timeouts were set, false otherwise.
1531 BOOL WINAPI
SetCommTimeouts(
1532 HANDLE hComm
, /* [in] handle of COMM device */
1533 LPCOMMTIMEOUTS lptimeouts
) /* [in] pointer to COMMTIMEOUTS structure */
1537 struct termios tios
;
1539 TRACE("(%p,%p)\n",hComm
,lptimeouts
);
1543 SetLastError(ERROR_INVALID_PARAMETER
);
1547 SERVER_START_REQ( set_serial_info
)
1549 req
->handle
= hComm
;
1550 req
->flags
= SERIALINFO_SET_TIMEOUTS
;
1551 req
->readinterval
= lptimeouts
->ReadIntervalTimeout
;
1552 req
->readmult
= lptimeouts
->ReadTotalTimeoutMultiplier
;
1553 req
->readconst
= lptimeouts
->ReadTotalTimeoutConstant
;
1554 req
->writemult
= lptimeouts
->WriteTotalTimeoutMultiplier
;
1555 req
->writeconst
= lptimeouts
->WriteTotalTimeoutConstant
;
1556 ret
= !wine_server_call_err( req
);
1559 if (!ret
) return FALSE
;
1561 /* FIXME: move this stuff to the server */
1562 fd
= FILE_GetUnixHandle( hComm
, GENERIC_READ
);
1564 FIXME("no fd for handle = %p!.\n",hComm
);
1568 if (-1==tcgetattr(fd
,&tios
)) {
1569 FIXME("tcgetattr on fd %d failed!\n",fd
);
1574 /* VTIME is in 1/10 seconds */
1576 unsigned int ux_timeout
;
1578 if(lptimeouts
->ReadIntervalTimeout
== 0) /* 0 means no timeout */
1584 ux_timeout
= (lptimeouts
->ReadIntervalTimeout
+99)/100;
1587 ux_timeout
= 1; /* must be at least some timeout */
1590 tios
.c_cc
[VTIME
] = ux_timeout
;
1593 if (-1==tcsetattr(fd
,0,&tios
)) {
1594 FIXME("tcsetattr on fd %d failed!\n",fd
);
1602 /***********************************************************************
1603 * GetCommModemStatus (KERNEL32.@)
1605 * Obtains the four control register bits if supported by the hardware.
1609 * True if the communications handle was good and for hardware that
1610 * control register access, false otherwise.
1612 BOOL WINAPI
GetCommModemStatus(
1613 HANDLE hFile
, /* [in] The communications device. */
1614 LPDWORD lpModemStat
) /* [out] The control register bits. */
1616 int fd
,mstat
, result
=FALSE
;
1620 fd
= FILE_GetUnixHandle( hFile
, GENERIC_READ
);
1623 result
= ioctl(fd
, TIOCMGET
, &mstat
);
1627 WARN("ioctl failed\n");
1631 if (mstat
& TIOCM_CTS
)
1632 *lpModemStat
|= MS_CTS_ON
;
1635 if (mstat
& TIOCM_DSR
)
1636 *lpModemStat
|= MS_DSR_ON
;
1639 if (mstat
& TIOCM_RNG
)
1640 *lpModemStat
|= MS_RING_ON
;
1643 /*FIXME: Not really sure about RLSD UB 990810*/
1644 if (mstat
& TIOCM_CAR
)
1645 *lpModemStat
|= MS_RLSD_ON
;
1647 TRACE("%04x -> %s%s%s%s\n", mstat
,
1648 (*lpModemStat
&MS_RLSD_ON
)?"MS_RLSD_ON ":"",
1649 (*lpModemStat
&MS_RING_ON
)?"MS_RING_ON ":"",
1650 (*lpModemStat
&MS_DSR_ON
)?"MS_DSR_ON ":"",
1651 (*lpModemStat
&MS_CTS_ON
)?"MS_CTS_ON ":"");
1658 /***********************************************************************
1659 * COMM_WaitCommEventService (INTERNAL)
1661 * This function is called while the client is waiting on the
1662 * server, so we can't make any server calls here.
1664 static void COMM_WaitCommEventService(async_private
*ovp
)
1666 async_commio
*commio
= (async_commio
*) ovp
;
1667 LPOVERLAPPED lpOverlapped
= commio
->lpOverlapped
;
1669 TRACE("overlapped %p\n",lpOverlapped
);
1671 /* FIXME: detect other events */
1672 *commio
->buffer
= EV_RXCHAR
;
1674 lpOverlapped
->Internal
= STATUS_SUCCESS
;
1678 /***********************************************************************
1679 * COMM_WaitCommEvent (INTERNAL)
1681 * This function must have an lpOverlapped.
1683 static BOOL
COMM_WaitCommEvent(
1684 HANDLE hFile
, /* [in] handle of comm port to wait for */
1685 LPDWORD lpdwEvents
, /* [out] event(s) that were detected */
1686 LPOVERLAPPED lpOverlapped
) /* [in/out] for Asynchronous waiting */
1693 SetLastError(ERROR_INVALID_PARAMETER
);
1697 if(NtResetEvent(lpOverlapped
->hEvent
,NULL
))
1700 fd
= FILE_GetUnixHandle( hFile
, GENERIC_WRITE
);
1704 ovp
= (async_commio
*) HeapAlloc(GetProcessHeap(), 0, sizeof (async_commio
));
1711 ovp
->async
.ops
= &commio_async_ops
;
1712 ovp
->async
.handle
= hFile
;
1714 ovp
->async
.type
= ASYNC_TYPE_WAIT
;
1715 ovp
->async
.func
= COMM_WaitCommEventService
;
1716 ovp
->async
.event
= lpOverlapped
->hEvent
;
1717 ovp
->lpOverlapped
= lpOverlapped
;
1718 ovp
->buffer
= (char *)lpdwEvents
;
1720 lpOverlapped
->InternalHigh
= 0;
1721 lpOverlapped
->Offset
= 0;
1722 lpOverlapped
->OffsetHigh
= 0;
1724 if ( !register_new_async (&ovp
->async
) )
1725 SetLastError( ERROR_IO_PENDING
);
1730 /***********************************************************************
1731 * WaitCommEvent (KERNEL32.@)
1733 * Wait until something interesting happens on a COMM port.
1734 * Interesting things (events) are set by calling SetCommMask before
1735 * this function is called.
1738 * TRUE if successful
1741 * The set of detected events will be written to *lpdwEventMask
1742 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1745 * Only supports EV_RXCHAR and EV_TXEMPTY
1747 BOOL WINAPI
WaitCommEvent(
1748 HANDLE hFile
, /* [in] handle of comm port to wait for */
1749 LPDWORD lpdwEvents
, /* [out] event(s) that were detected */
1750 LPOVERLAPPED lpOverlapped
) /* [in/out] for Asynchronous waiting */
1755 TRACE("(%p %p %p )\n",hFile
, lpdwEvents
,lpOverlapped
);
1758 return COMM_WaitCommEvent(hFile
, lpdwEvents
, lpOverlapped
);
1760 /* if there is no overlapped structure, create our own */
1761 ov
.hEvent
= CreateEventA(NULL
,FALSE
,FALSE
,NULL
);
1763 COMM_WaitCommEvent(hFile
, lpdwEvents
, &ov
);
1765 /* wait for the overlapped to complete */
1766 ret
= GetOverlappedResult(hFile
, &ov
, NULL
, TRUE
);
1767 CloseHandle(ov
.hEvent
);
1772 /***********************************************************************
1773 * GetCommProperties (KERNEL32.@)
1775 * This function fills in a structure with the capabilities of the
1776 * communications port driver.
1780 * TRUE on success, FALSE on failure
1781 * If successful, the lpCommProp structure be filled in with
1782 * properties of the comm port.
1784 BOOL WINAPI
GetCommProperties(
1785 HANDLE hFile
, /* [in] handle of the comm port */
1786 LPCOMMPROP lpCommProp
) /* [out] pointer to struct to be filled */
1788 FIXME("(%p %p )\n",hFile
,lpCommProp
);
1793 * These values should be valid for LINUX's serial driver
1794 * FIXME: Perhaps they deserve an #ifdef LINUX
1796 memset(lpCommProp
,0,sizeof(COMMPROP
));
1797 lpCommProp
->wPacketLength
= 1;
1798 lpCommProp
->wPacketVersion
= 1;
1799 lpCommProp
->dwServiceMask
= SP_SERIALCOMM
;
1800 lpCommProp
->dwReserved1
= 0;
1801 lpCommProp
->dwMaxTxQueue
= 4096;
1802 lpCommProp
->dwMaxRxQueue
= 4096;
1803 lpCommProp
->dwMaxBaud
= BAUD_115200
;
1804 lpCommProp
->dwProvSubType
= PST_RS232
;
1805 lpCommProp
->dwProvCapabilities
= PCF_DTRDSR
| PCF_PARITY_CHECK
| PCF_RTSCTS
| PCF_TOTALTIMEOUTS
;
1806 lpCommProp
->dwSettableParams
= SP_BAUD
| SP_DATABITS
| SP_HANDSHAKING
|
1807 SP_PARITY
| SP_PARITY_CHECK
| SP_STOPBITS
;
1808 lpCommProp
->dwSettableBaud
= BAUD_075
| BAUD_110
| BAUD_134_5
| BAUD_150
|
1809 BAUD_300
| BAUD_600
| BAUD_1200
| BAUD_1800
| BAUD_2400
| BAUD_4800
|
1810 BAUD_9600
| BAUD_19200
| BAUD_38400
| BAUD_57600
| BAUD_115200
;
1811 lpCommProp
->wSettableData
= DATABITS_5
| DATABITS_6
| DATABITS_7
| DATABITS_8
;
1812 lpCommProp
->wSettableStopParity
= STOPBITS_10
| STOPBITS_15
| STOPBITS_20
|
1813 PARITY_NONE
| PARITY_ODD
|PARITY_EVEN
| PARITY_MARK
| PARITY_SPACE
;
1814 lpCommProp
->dwCurrentTxQueue
= lpCommProp
->dwMaxTxQueue
;
1815 lpCommProp
->dwCurrentRxQueue
= lpCommProp
->dwMaxRxQueue
;
1820 /***********************************************************************
1822 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1823 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1824 * This is dependent on the type of COMM port, but since it is doubtful
1825 * anybody will get around to implementing support for fancy serial
1826 * ports in WINE, this is hardcoded for the time being. The name of
1827 * this DLL should be stored in and read from the system registry in
1828 * the hive HKEY_LOCAL_MACHINE, key
1829 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1830 * where ???? is the port number... that is determined by PNP
1831 * The DLL should be loaded when the COMM port is opened, and closed
1832 * when the COMM port is closed. - MJM 20 June 2000
1833 ***********************************************************************/
1834 static CHAR lpszSerialUI
[] = "serialui.dll";
1837 /***********************************************************************
1838 * CommConfigDialogA (KERNEL32.@)
1840 * Raises a dialog that allows the user to configure a comm port.
1841 * Fills the COMMCONFIG struct with information specified by the user.
1842 * This function should call a similar routine in the COMM driver...
1846 * TRUE on success, FALSE on failure
1847 * If successful, the lpCommConfig structure will contain a new
1848 * configuration for the comm port, as specified by the user.
1851 * The library with the CommConfigDialog code is never unloaded.
1852 * Perhaps this should be done when the comm port is closed?
1854 BOOL WINAPI
CommConfigDialogA(
1855 LPCSTR lpszDevice
, /* [in] name of communications device */
1856 HANDLE hWnd
, /* [in] parent window for the dialog */
1857 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
1859 FARPROC lpfnCommDialog
;
1860 HMODULE hConfigModule
;
1863 TRACE("(%p %p %p)\n",lpszDevice
, hWnd
, lpCommConfig
);
1865 hConfigModule
= LoadLibraryA(lpszSerialUI
);
1869 lpfnCommDialog
= GetProcAddress(hConfigModule
, (LPCSTR
)3L);
1874 r
= lpfnCommDialog(lpszDevice
,hWnd
,lpCommConfig
);
1876 /* UnloadLibrary(hConfigModule); */
1881 /***********************************************************************
1882 * CommConfigDialogW (KERNEL32.@)
1884 * see CommConfigDialogA for more info
1886 BOOL WINAPI
CommConfigDialogW(
1887 LPCWSTR lpszDevice
, /* [in] name of communications device */
1888 HANDLE hWnd
, /* [in] parent window for the dialog */
1889 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
1894 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
1897 r
= CommConfigDialogA(lpDeviceA
,hWnd
,lpCommConfig
);
1898 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
1902 /***********************************************************************
1903 * GetCommConfig (KERNEL32.@)
1905 * Fill in the COMMCONFIG structure for the comm port hFile
1909 * TRUE on success, FALSE on failure
1910 * If successful, lpCommConfig contains the comm port configuration.
1915 BOOL WINAPI
GetCommConfig(
1916 HANDLE hFile
, /* [in] The communications device. */
1917 LPCOMMCONFIG lpCommConfig
, /* [out] The communications configuration of the device (if it fits). */
1918 LPDWORD lpdwSize
) /* [in/out] Initially the size of the configuration buffer/structure,
1919 afterwards the number of bytes copied to the buffer or
1920 the needed size of the buffer. */
1924 TRACE("(%p %p)\n",hFile
,lpCommConfig
);
1926 if(lpCommConfig
== NULL
)
1929 r
= *lpdwSize
< sizeof(COMMCONFIG
);
1930 *lpdwSize
= sizeof(COMMCONFIG
);
1934 lpCommConfig
->dwSize
= sizeof(COMMCONFIG
);
1935 lpCommConfig
->wVersion
= 1;
1936 lpCommConfig
->wReserved
= 0;
1937 r
= GetCommState(hFile
,&lpCommConfig
->dcb
);
1938 lpCommConfig
->dwProviderSubType
= PST_RS232
;
1939 lpCommConfig
->dwProviderOffset
= 0;
1940 lpCommConfig
->dwProviderSize
= 0;
1945 /***********************************************************************
1946 * SetCommConfig (KERNEL32.@)
1948 * Sets the configuration of the communications device.
1952 * True on success, false if the handle was bad is not a communications device.
1954 BOOL WINAPI
SetCommConfig(
1955 HANDLE hFile
, /* [in] The communications device. */
1956 LPCOMMCONFIG lpCommConfig
, /* [in] The desired configuration. */
1957 DWORD dwSize
) /* [in] size of the lpCommConfig struct */
1959 TRACE("(%p %p)\n",hFile
,lpCommConfig
);
1960 return SetCommState(hFile
,&lpCommConfig
->dcb
);
1963 /***********************************************************************
1964 * SetDefaultCommConfigA (KERNEL32.@)
1966 * Initializes the default configuration for the specified communication
1971 * True if the device was found and the defaults set, false otherwise
1973 BOOL WINAPI
SetDefaultCommConfigA(
1974 LPCSTR lpszDevice
, /* [in] The ascii name of the device targeted for configuration. */
1975 LPCOMMCONFIG lpCommConfig
, /* [in] The default configuration for the device. */
1976 DWORD dwSize
) /* [in] The number of bytes in the configuration structure. */
1978 FARPROC lpfnSetDefaultCommConfig
;
1979 HMODULE hConfigModule
;
1982 TRACE("(%p %p %lx)\n",lpszDevice
, lpCommConfig
, dwSize
);
1984 hConfigModule
= LoadLibraryA(lpszSerialUI
);
1988 lpfnSetDefaultCommConfig
= GetProcAddress(hConfigModule
, (LPCSTR
)4L);
1990 if(! lpfnSetDefaultCommConfig
)
1993 r
= lpfnSetDefaultCommConfig(lpszDevice
, lpCommConfig
, dwSize
);
1995 /* UnloadLibrary(hConfigModule); */
2001 /***********************************************************************
2002 * SetDefaultCommConfigW (KERNEL32.@)
2004 * Initializes the default configuration for the specified
2005 * communication device. (unicode)
2010 BOOL WINAPI
SetDefaultCommConfigW(
2011 LPCWSTR lpszDevice
, /* [in] The unicode name of the device targeted for configuration. */
2012 LPCOMMCONFIG lpCommConfig
, /* [in] The default configuration for the device. */
2013 DWORD dwSize
) /* [in] The number of bytes in the configuration structure. */
2018 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice
),lpCommConfig
,dwSize
);
2020 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
2023 r
= SetDefaultCommConfigA(lpDeviceA
,lpCommConfig
,dwSize
);
2024 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
2029 /***********************************************************************
2030 * GetDefaultCommConfigA (KERNEL32.@)
2032 * Acquires the default configuration of the specified communication device. (unicode)
2036 * True on successful reading of the default configuration,
2037 * if the device is not found or the buffer is too small.
2039 BOOL WINAPI
GetDefaultCommConfigA(
2040 LPCSTR lpszName
, /* [in] The ascii name of the device targeted for configuration. */
2041 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
2042 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
2043 afterwards the number of bytes copied to the buffer or
2044 the needed size of the buffer. */
2046 LPDCB lpdcb
= &(lpCC
->dcb
);
2049 if (strncasecmp(lpszName
,"COM",3)) {
2050 ERR("not implemented for <%s>\n", lpszName
);
2054 TRACE("(%s %p %ld)\n", lpszName
, lpCC
, *lpdwSize
);
2055 if (*lpdwSize
< sizeof(COMMCONFIG
)) {
2056 *lpdwSize
= sizeof(COMMCONFIG
);
2060 *lpdwSize
= sizeof(COMMCONFIG
);
2062 lpCC
->dwSize
= sizeof(COMMCONFIG
);
2064 lpCC
->dwProviderSubType
= PST_RS232
;
2065 lpCC
->dwProviderOffset
= 0L;
2066 lpCC
->dwProviderSize
= 0L;
2068 sprintf( temp
, "COM%c:38400,n,8,1", lpszName
[3]);
2069 FIXME("setting %s as default\n", temp
);
2071 return BuildCommDCBA( temp
, lpdcb
);
2074 /**************************************************************************
2075 * GetDefaultCommConfigW (KERNEL32.@)
2077 * Acquires the default configuration of the specified communication device. (unicode)
2081 * True on successful reading of the default configuration,
2082 * if the device is not found or the buffer is too small.
2084 BOOL WINAPI
GetDefaultCommConfigW(
2085 LPCWSTR lpszName
, /* [in] The unicode name of the device targeted for configuration. */
2086 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
2087 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
2088 afterwards the number of bytes copied to the buffer or
2089 the needed size of the buffer. */
2094 TRACE("(%p,%p,%ld)\n",lpszName
,lpCC
,*lpdwSize
);
2095 lpszNameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName
);
2098 ret
=GetDefaultCommConfigA(lpszNameA
,lpCC
,lpdwSize
);
2099 HeapFree( GetProcessHeap(), 0, lpszNameA
);