2 * DEC 93 Erik Bos <erik@xs4all.nl>
4 * Copyright 1996 Marcus Meissner
6 * Mar 31, 1999. Ove Kåven <ovek@arcticnet.no>
7 * - Implemented buffers and EnableCommNotification.
9 * Apr 3, 1999. Lawson Whitney <lawson_whitney@juno.com>
10 * - Fixed the modem control part of EscapeCommFunction16.
12 * Mar 3, 1999. Ove Kåven <ovek@arcticnet.no>
13 * - Use port indices instead of unixfds for win16
14 * - Moved things around (separated win16 and win32 routines)
15 * - Added some hints on how to implement buffers and EnableCommNotification.
17 * May 26, 1997. Fixes and comments by Rick Richardson <rick@dgii.com> [RER]
18 * - ptr->fd wasn't getting cleared on close.
19 * - GetCommEventMask() and GetCommError() didn't do much of anything.
20 * IMHO, they are still wrong, but they at least implement the RXCHAR
21 * event and return I/O queue sizes, which makes the app I'm interested
22 * in (analog devices EZKIT DSP development system) work.
24 * August 12, 1997. Take a bash at SetCommEventMask - Lawson Whitney
25 * <lawson_whitney@juno.com>
26 * July 6, 1998. Fixes and comments by Valentijn Sessink
27 * <vsessink@ic.uva.nl> [V]
28 * Oktober 98, Rein Klazes [RHK]
29 * A program that wants to monitor the modem status line (RLSD/DCD) may
30 * poll the modem status register in the commMask structure. I update the bit
31 * in GetCommError, waiting for an implementation of communication events.
36 #include "wine/port.h"
49 #ifdef HAVE_SYS_FILIO_H
50 # include <sys/filio.h>
52 #include <sys/ioctl.h>
55 #ifdef HAVE_SYS_MODEM_H
56 # include <sys/modem.h>
58 #ifdef HAVE_SYS_STRTIO_H
59 # include <sys/strtio.h>
65 #include "wine/server.h"
69 #include "debugtools.h"
71 DEFAULT_DEBUG_CHANNEL(comm
);
73 #if !defined(TIOCINQ) && defined(FIONREAD)
74 #define TIOCINQ FIONREAD
77 static int COMM_WhackModem(int fd
, unsigned int andy
, unsigned int orrie
)
79 unsigned int mstat
, okay
;
80 okay
= ioctl(fd
, TIOCMGET
, &mstat
);
81 if (okay
) return okay
;
82 if (andy
) mstat
&= andy
;
84 return ioctl(fd
, TIOCMSET
, &mstat
);
87 /***********************************************************************
88 * COMM_BuildOldCommDCB (Internal)
90 * Build a DCB using the old style settings string eg: "COMx:96,n,8,1"
91 * We ignore the COM port index, since we can support more than 4 ports.
93 BOOL WINAPI
COMM_BuildOldCommDCB(LPCSTR device
, LPDCB lpdcb
)
97 char *ptr
, temp
[256], last
;
100 TRACE("(%s), ptr %p\n", device
, lpdcb
);
102 if (strncasecmp(device
,"COM",3))
108 if ((*(device
+4) != ':') && (*(device
+4) != ' '))
111 strcpy(temp
,device
+5);
112 last
=temp
[strlen(temp
)-1];
113 ptr
= strtok(temp
, ", ");
115 /* DOS/Windows only compares the first two numbers
116 * and assigns an appropriate baud rate.
117 * You can supply 961324245, it still returns 9600 ! */
120 WARN("Unknown baudrate string '%s' !\n", ptr
);
121 return FALSE
; /* error: less than 2 chars */
142 WARN("Unknown baudrate indicator %d !\n", rate
);
146 lpdcb
->BaudRate
= rate
;
147 TRACE("baudrate (%ld)\n", lpdcb
->BaudRate
);
149 ptr
= strtok(NULL
, ", ");
151 *ptr
= toupper(*ptr
);
153 TRACE("parity (%c)\n", *ptr
);
154 lpdcb
->fParity
= TRUE
;
157 lpdcb
->Parity
= NOPARITY
;
158 lpdcb
->fParity
= FALSE
;
161 lpdcb
->Parity
= EVENPARITY
;
164 lpdcb
->Parity
= MARKPARITY
;
167 lpdcb
->Parity
= ODDPARITY
;
170 lpdcb
->Parity
= SPACEPARITY
;
173 WARN("Unknown parity `%c'!\n", *ptr
);
177 ptr
= strtok(NULL
, ", ");
178 TRACE("charsize (%c)\n", *ptr
);
179 lpdcb
->ByteSize
= *ptr
- '0';
181 ptr
= strtok(NULL
, ", ");
182 TRACE("stopbits (%c)\n", *ptr
);
185 lpdcb
->StopBits
= ONESTOPBIT
;
188 lpdcb
->StopBits
= TWOSTOPBITS
;
191 WARN("Unknown # of stopbits `%c'!\n", *ptr
);
198 lpdcb
->fOutxCtsFlow
= FALSE
;
199 lpdcb
->fOutxDsrFlow
= FALSE
;
200 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
201 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
202 } else if (last
=='p') {
204 lpdcb
->fOutX
= FALSE
;
205 lpdcb
->fOutxCtsFlow
= TRUE
;
206 lpdcb
->fOutxDsrFlow
= FALSE
;
207 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
208 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
211 lpdcb
->fOutX
= FALSE
;
212 lpdcb
->fOutxCtsFlow
= FALSE
;
213 lpdcb
->fOutxDsrFlow
= FALSE
;
214 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
215 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
221 /**************************************************************************
222 * BuildCommDCBA (KERNEL32.@)
224 * Updates a device control block data structure with values from an
225 * ascii device control string. The device control string has two forms
226 * normal and extended, it must be exclusively in one or the other form.
230 * True on success, false on an malformed control string.
232 BOOL WINAPI
BuildCommDCBA(
233 LPCSTR device
, /* [in] The ascii device control string used to update the DCB. */
234 LPDCB lpdcb
) /* [out] The device control block to be updated. */
236 return BuildCommDCBAndTimeoutsA(device
,lpdcb
,NULL
);
239 /**************************************************************************
240 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
242 * Updates a device control block data structure with values from an
243 * ascii device control string. Taking time out values from a time outs
244 * struct if desired by the control string.
248 * True on success, false bad handles etc
250 BOOL WINAPI
BuildCommDCBAndTimeoutsA(
251 LPCSTR device
, /* [in] The ascii device control string. */
252 LPDCB lpdcb
, /* [out] The device control block to be updated. */
253 LPCOMMTIMEOUTS lptimeouts
) /* [in] The time outs to use if asked to set them by the control string. */
258 TRACE("(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
260 if (!strncasecmp(device
,"COM",3)) {
263 ERR("BUG! COM0 can't exist!\n");
266 if ((*(device
+4)!=':') && (*(device
+4)!=' '))
268 temp
=(LPSTR
)(device
+5);
272 memset(lpdcb
,0,sizeof (DCB
));
273 lpdcb
->DCBlength
= sizeof(DCB
);
274 if (strchr(temp
,',')) { /* old style */
276 return COMM_BuildOldCommDCB(device
,lpdcb
);
278 ptr
=strtok(temp
," ");
283 if (!strncmp("baud=",ptr
,5)) {
284 if (!sscanf(ptr
+5,"%ld",&x
))
285 WARN("Couldn't parse %s\n",ptr
);
289 if (!strncmp("stop=",ptr
,5)) {
290 if (!sscanf(ptr
+5,"%ld",&x
))
291 WARN("Couldn't parse %s\n",ptr
);
295 if (!strncmp("data=",ptr
,5)) {
296 if (!sscanf(ptr
+5,"%ld",&x
))
297 WARN("Couldn't parse %s\n",ptr
);
301 if (!strncmp("parity=",ptr
,7)) {
302 lpdcb
->fParity
= TRUE
;
305 lpdcb
->fParity
= FALSE
;
306 lpdcb
->Parity
= NOPARITY
;
309 lpdcb
->Parity
= EVENPARITY
;
312 lpdcb
->Parity
= ODDPARITY
;
315 lpdcb
->Parity
= MARKPARITY
;
318 lpdcb
->Parity
= SPACEPARITY
;
324 ERR("Unhandled specifier '%s', please report.\n",ptr
);
325 ptr
=strtok(NULL
," ");
327 if (lpdcb
->BaudRate
==110)
332 /**************************************************************************
333 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
335 * Updates a device control block data structure with values from an
336 * unicode device control string. Taking time out values from a time outs
337 * struct if desired by the control string.
341 * True on success, false bad handles etc.
343 BOOL WINAPI
BuildCommDCBAndTimeoutsW(
344 LPCWSTR devid
, /* [in] The unicode device control string. */
345 LPDCB lpdcb
, /* [out] The device control block to be updated. */
346 LPCOMMTIMEOUTS lptimeouts
) /* [in] The time outs to use if asked to set them by the control string. */
351 TRACE("(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
352 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
355 ret
=BuildCommDCBAndTimeoutsA(devidA
,lpdcb
,lptimeouts
);
356 HeapFree( GetProcessHeap(), 0, devidA
);
361 /**************************************************************************
362 * BuildCommDCBW (KERNEL32.@)
364 * Updates a device control block structure with values from an
365 * unicode device control string. The device control string has two forms
366 * normal and extended, it must be exclusively in one or the other form.
370 * True on success, false on an malformed control string.
372 BOOL WINAPI
BuildCommDCBW(
373 LPCWSTR devid
, /* [in] The unicode device control string. */
374 LPDCB lpdcb
) /* [out] The device control block to be updated. */
376 return BuildCommDCBAndTimeoutsW(devid
,lpdcb
,NULL
);
379 static BOOL
COMM_SetCommError(HANDLE handle
, DWORD error
)
383 SERVER_START_REQ( set_serial_info
)
385 req
->handle
= handle
;
386 req
->flags
= SERIALINFO_SET_ERROR
;
387 req
->commerror
= error
;
388 ret
= !wine_server_call_err( req
);
394 static BOOL
COMM_GetCommError(HANDLE handle
, LPDWORD lperror
)
401 SERVER_START_REQ( get_serial_info
)
403 req
->handle
= handle
;
404 ret
= !wine_server_call_err( req
);
405 *lperror
= reply
->commerror
;
412 /*****************************************************************************
413 * SetCommBreak (KERNEL32.@)
415 * Halts the transmission of characters to a communications device.
419 * True on success, and false if the communications device could not be found,
420 * the control is not supported.
424 * Only TIOCSBRK and TIOCCBRK are supported.
426 BOOL WINAPI
SetCommBreak(
427 HANDLE handle
) /* [in] The communictions device to suspend. */
429 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
432 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
434 TRACE("FILE_GetUnixHandle failed\n");
437 result
= ioctl(fd
,TIOCSBRK
,0);
441 TRACE("ioctl failed\n");
442 SetLastError(ERROR_NOT_SUPPORTED
);
447 FIXME("ioctl not available\n");
448 SetLastError(ERROR_NOT_SUPPORTED
);
453 /*****************************************************************************
454 * ClearCommBreak (KERNEL32.@)
456 * Resumes character transmission from a communication device.
460 * True on success and false if the communications device could not be found.
464 * Only TIOCSBRK and TIOCCBRK are supported.
466 BOOL WINAPI
ClearCommBreak(
467 HANDLE handle
) /* [in] The halted communication device whose character transmission is to be resumed. */
469 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
472 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
474 TRACE("FILE_GetUnixHandle failed\n");
477 result
= ioctl(fd
,TIOCCBRK
,0);
481 TRACE("ioctl failed\n");
482 SetLastError(ERROR_NOT_SUPPORTED
);
487 FIXME("ioctl not available\n");
488 SetLastError(ERROR_NOT_SUPPORTED
);
493 /*****************************************************************************
494 * EscapeCommFunction (KERNEL32.@)
496 * Directs a communication device to perform an extended function.
500 * True or requested data on successful completion of the command,
501 * false if the device is not present cannot execute the command
502 * or the command failed.
504 BOOL WINAPI
EscapeCommFunction(
505 HANDLE handle
, /* [in] The communication device to perform the extended function. */
506 UINT nFunction
) /* [in] The extended function to be performed. */
508 int fd
,direct
=FALSE
,result
=FALSE
;
511 TRACE("handle %d, function=%d\n", handle
, nFunction
);
512 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
514 FIXME("handle %d not found.\n",handle
);
518 if (tcgetattr(fd
,&port
) == -1) {
519 COMM_SetCommError(handle
,CE_IOE
);
533 result
= COMM_WhackModem(fd
, ~TIOCM_DTR
, 0);
541 result
= COMM_WhackModem(fd
, ~TIOCM_RTS
, 0);
549 result
= COMM_WhackModem(fd
, 0, TIOCM_DTR
);
557 result
= COMM_WhackModem(fd
, 0, TIOCM_RTS
);
563 port
.c_iflag
|= IXOFF
;
568 port
.c_iflag
|= IXON
;
574 result
= ioctl(fd
,TIOCSBRK
,0);
581 result
= ioctl(fd
,TIOCCBRK
,0);
585 WARN("(handle=%d,nFunction=%d): Unknown function\n",
591 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
593 COMM_SetCommError(handle
,CE_IOE
);
602 COMM_SetCommError(handle
,CE_IOE
);
611 /********************************************************************
612 * PurgeComm (KERNEL32.@)
614 * Terminates pending operations and/or discards buffers on a
615 * communication resource.
619 * True on success and false if the communications handle is bad.
621 BOOL WINAPI
PurgeComm(
622 HANDLE handle
, /* [in] The communication resource to be purged. */
623 DWORD flags
) /* [in] Flags for clear pending/buffer on input/output. */
627 TRACE("handle %d, flags %lx\n", handle
, flags
);
629 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
631 FIXME("no handle %d found\n",handle
);
636 ** not exactly sure how these are different
637 ** Perhaps if we had our own internal queues, one flushes them
638 ** and the other flushes the kernel's buffers.
640 if(flags
&PURGE_TXABORT
)
641 tcflush(fd
,TCOFLUSH
);
642 if(flags
&PURGE_RXABORT
)
643 tcflush(fd
,TCIFLUSH
);
644 if(flags
&PURGE_TXCLEAR
)
645 tcflush(fd
,TCOFLUSH
);
646 if(flags
&PURGE_RXCLEAR
)
647 tcflush(fd
,TCIFLUSH
);
653 /*****************************************************************************
654 * ClearCommError (KERNEL32.@)
656 * Enables further I/O operations on a communications resource after
657 * supplying error and current status information.
661 * True on success, false if the communication resource handle is bad.
663 BOOL WINAPI
ClearCommError(
664 HANDLE handle
, /* [in] The communication resource with the error. */
665 LPDWORD errors
, /* [out] Flags indicating error the resource experienced. */
666 LPCOMSTAT lpStat
) /* [out] The status of the communication resource. */
670 fd
=FILE_GetUnixHandle( handle
, GENERIC_READ
);
673 FIXME("no handle %d found\n",handle
);
682 if(ioctl(fd
, TIOCOUTQ
, &lpStat
->cbOutQue
))
683 WARN("ioctl returned error\n");
685 lpStat
->cbOutQue
= 0; /* FIXME: find a different way to find out */
689 if(ioctl(fd
, TIOCINQ
, &lpStat
->cbInQue
))
690 WARN("ioctl returned error\n");
693 TRACE("handle %d cbInQue = %ld cbOutQue = %ld\n",
694 handle
, lpStat
->cbInQue
, lpStat
->cbOutQue
);
699 COMM_GetCommError(handle
, errors
);
700 COMM_SetCommError(handle
, 0);
705 /*****************************************************************************
706 * SetupComm (KERNEL32.@)
708 * Called after CreateFile to hint to the communication resource to use
709 * specified sizes for input and output buffers rather than the default values.
713 * True if successful, false if the communications resource handle is bad.
719 BOOL WINAPI
SetupComm(
720 HANDLE handle
, /* [in] The just created communication resource handle. */
721 DWORD insize
, /* [in] The suggested size of the communication resources input buffer in bytes. */
722 DWORD outsize
) /* [in] The suggested size of the communication resources output buffer in bytes. */
726 FIXME("insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
727 fd
=FILE_GetUnixHandle( handle
, GENERIC_READ
);
729 FIXME("handle %d not found?\n",handle
);
736 /*****************************************************************************
737 * GetCommMask (KERNEL32.@)
739 * Obtain the events associated with a communication device that will cause a call
740 * WaitCommEvent to return.
744 * True on success, fail on bad device handle etc.
746 BOOL WINAPI
GetCommMask(
747 HANDLE handle
, /* [in] The communications device. */
748 LPDWORD evtmask
) /* [out] The events which cause WaitCommEvent to return. */
752 TRACE("handle %d, mask %p\n", handle
, evtmask
);
754 SERVER_START_REQ( get_serial_info
)
756 req
->handle
= handle
;
757 if ((ret
= !wine_server_call_err( req
)))
759 if (evtmask
) *evtmask
= reply
->eventmask
;
766 /*****************************************************************************
767 * SetCommMask (KERNEL32.@)
769 * There be some things we need to hear about yon there communications device.
770 * (Set which events associated with a communication device should cause
771 * a call WaitCommEvent to return.)
775 * True on success, false on bad handle etc.
777 BOOL WINAPI
SetCommMask(
778 HANDLE handle
, /* [in] The communications device. */
779 DWORD evtmask
) /* [in] The events that to be monitored. */
783 TRACE("handle %d, mask %lx\n", handle
, evtmask
);
785 SERVER_START_REQ( set_serial_info
)
787 req
->handle
= handle
;
788 req
->flags
= SERIALINFO_SET_MASK
;
789 req
->eventmask
= evtmask
;
790 ret
= !wine_server_call_err( req
);
796 /*****************************************************************************
797 * SetCommState (KERNEL32.@)
799 * Re-initializes all hardware and control settings of a communications device,
800 * with values from a device control block without effecting the input and output
805 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
807 BOOL WINAPI
SetCommState(
808 HANDLE handle
, /* [in] The communications device. */
809 LPDCB lpdcb
) /* [out] The device control block. */
812 int fd
, bytesize
, stopbits
;
814 TRACE("handle %d, ptr %p\n", handle
, lpdcb
);
815 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
816 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
817 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
818 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
819 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
820 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
822 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
824 FIXME("no handle %d found\n",handle
);
828 if ((tcgetattr(fd
,&port
)) == -1) {
829 int save_error
= errno
;
830 COMM_SetCommError(handle
,CE_IOE
);
832 ERR("tcgetattr error '%s'\n", strerror(save_error
));
837 port
.c_cc
[VTIME
] = 1;
840 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
842 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
844 port
.c_iflag
|= (IGNBRK
);
846 port
.c_oflag
&= ~(OPOST
);
848 port
.c_cflag
&= ~(HUPCL
);
849 port
.c_cflag
|= CLOCAL
| CREAD
;
851 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
852 port
.c_lflag
|= NOFLSH
;
855 port
.c_cflag
&= ~CBAUD
;
856 switch (lpdcb
->BaudRate
) {
859 port
.c_cflag
|= B110
;
863 port
.c_cflag
|= B300
;
867 port
.c_cflag
|= B600
;
871 port
.c_cflag
|= B1200
;
875 port
.c_cflag
|= B2400
;
879 port
.c_cflag
|= B4800
;
883 port
.c_cflag
|= B9600
;
887 port
.c_cflag
|= B19200
;
891 port
.c_cflag
|= B38400
;
895 port
.c_cflag
|= B57600
;
900 port
.c_cflag
|= B115200
;
905 port
.c_cflag
|= B230400
;
910 port
.c_cflag
|= B460800
;
914 COMM_SetCommError(handle
,IE_BAUDRATE
);
916 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
919 #elif !defined(__EMX__)
920 switch (lpdcb
->BaudRate
) {
923 port
.c_ospeed
= B110
;
927 port
.c_ospeed
= B300
;
931 port
.c_ospeed
= B600
;
935 port
.c_ospeed
= B1200
;
939 port
.c_ospeed
= B2400
;
943 port
.c_ospeed
= B4800
;
947 port
.c_ospeed
= B9600
;
951 port
.c_ospeed
= B19200
;
955 port
.c_ospeed
= B38400
;
958 COMM_SetCommError(handle
,IE_BAUDRATE
);
960 ERR("baudrate %ld\n",lpdcb
->BaudRate
);
963 port
.c_ispeed
= port
.c_ospeed
;
965 bytesize
=lpdcb
->ByteSize
;
966 stopbits
=lpdcb
->StopBits
;
969 port
.c_cflag
&= ~(PARENB
| PARODD
| CMSPAR
);
971 port
.c_cflag
&= ~(PARENB
| PARODD
);
974 port
.c_iflag
|= INPCK
;
976 port
.c_iflag
&= ~INPCK
;
977 switch (lpdcb
->Parity
) {
981 port
.c_cflag
|= (PARENB
| PARODD
);
984 port
.c_cflag
|= PARENB
;
987 /* Linux defines mark/space (stick) parity */
989 port
.c_cflag
|= (PARENB
| CMSPAR
);
992 port
.c_cflag
|= (PARENB
| PARODD
| CMSPAR
);
995 /* try the POSIX way */
997 if( stopbits
== ONESTOPBIT
) {
998 stopbits
= TWOSTOPBITS
;
999 port
.c_iflag
&= ~INPCK
;
1001 COMM_SetCommError(handle
,IE_BYTESIZE
);
1003 ERR("Cannot set MARK Parity\n");
1010 port
.c_iflag
&= ~INPCK
;
1012 COMM_SetCommError(handle
,IE_BYTESIZE
);
1014 ERR("Cannot set SPACE Parity\n");
1020 COMM_SetCommError(handle
,IE_BYTESIZE
);
1027 port
.c_cflag
&= ~CSIZE
;
1030 port
.c_cflag
|= CS5
;
1033 port
.c_cflag
|= CS6
;
1036 port
.c_cflag
|= CS7
;
1039 port
.c_cflag
|= CS8
;
1042 COMM_SetCommError(handle
,IE_BYTESIZE
);
1050 port
.c_cflag
&= ~CSTOPB
;
1052 case ONE5STOPBITS
: /* wil be selected if bytesize is 5 */
1054 port
.c_cflag
|= CSTOPB
;
1057 COMM_SetCommError(handle
,IE_BYTESIZE
);
1063 if ( lpdcb
->fOutxCtsFlow
||
1064 lpdcb
->fRtsControl
== RTS_CONTROL_HANDSHAKE
1067 port
.c_cflag
|= CRTSCTS
;
1072 if (lpdcb
->fDtrControl
== DTR_CONTROL_HANDSHAKE
)
1074 WARN("DSR/DTR flow control not supported\n");
1078 port
.c_iflag
|= IXON
;
1080 port
.c_iflag
&= ~IXON
;
1082 port
.c_iflag
|= IXOFF
;
1084 port
.c_iflag
&= ~IXOFF
;
1086 if (tcsetattr(fd
,TCSANOW
,&port
)==-1) { /* otherwise it hangs with pending input*/
1087 int save_error
=errno
;
1088 COMM_SetCommError(handle
,CE_IOE
);
1090 ERR("tcsetattr error '%s'\n", strerror(save_error
));
1093 COMM_SetCommError(handle
,0);
1100 /*****************************************************************************
1101 * GetCommState (KERNEL32.@)
1103 * Fills in a device control block with information from a communications device.
1107 * True on success, false if the communication device handle is bad etc
1111 * XonChar and XoffChar are not set.
1113 BOOL WINAPI
GetCommState(
1114 HANDLE handle
, /* [in] The communications device. */
1115 LPDCB lpdcb
) /* [out] The device control block. */
1117 struct termios port
;
1120 TRACE("handle %d, ptr %p\n", handle
, lpdcb
);
1122 fd
= FILE_GetUnixHandle( handle
, GENERIC_READ
);
1125 ERR("FILE_GetUnixHandle failed\n");
1128 if (tcgetattr(fd
, &port
) == -1) {
1129 int save_error
=errno
;
1130 ERR("tcgetattr error '%s'\n", strerror(save_error
));
1131 COMM_SetCommError(handle
,CE_IOE
);
1138 speed
= (port
.c_cflag
& CBAUD
);
1140 speed
= (cfgetospeed(&port
));
1144 lpdcb
->BaudRate
= 110;
1147 lpdcb
->BaudRate
= 300;
1150 lpdcb
->BaudRate
= 600;
1153 lpdcb
->BaudRate
= 1200;
1156 lpdcb
->BaudRate
= 2400;
1159 lpdcb
->BaudRate
= 4800;
1162 lpdcb
->BaudRate
= 9600;
1165 lpdcb
->BaudRate
= 19200;
1168 lpdcb
->BaudRate
= 38400;
1172 lpdcb
->BaudRate
= 57600;
1177 lpdcb
->BaudRate
= 115200;
1182 lpdcb
->BaudRate
= 230400;
1187 lpdcb
->BaudRate
= 460800;
1191 ERR("unknown speed %x \n",speed
);
1194 switch (port
.c_cflag
& CSIZE
) {
1196 lpdcb
->ByteSize
= 5;
1199 lpdcb
->ByteSize
= 6;
1202 lpdcb
->ByteSize
= 7;
1205 lpdcb
->ByteSize
= 8;
1208 ERR("unknown size %x \n",port
.c_cflag
& CSIZE
);
1211 if(port
.c_iflag
& INPCK
)
1212 lpdcb
->fParity
= TRUE
;
1214 lpdcb
->fParity
= FALSE
;
1216 switch (port
.c_cflag
& (PARENB
| PARODD
| CMSPAR
))
1218 switch (port
.c_cflag
& (PARENB
| PARODD
))
1222 lpdcb
->Parity
= NOPARITY
;
1225 lpdcb
->Parity
= EVENPARITY
;
1227 case (PARENB
| PARODD
):
1228 lpdcb
->Parity
= ODDPARITY
;
1231 case (PARENB
| CMSPAR
):
1232 lpdcb
->Parity
= MARKPARITY
;
1234 case (PARENB
| PARODD
| CMSPAR
):
1235 lpdcb
->Parity
= SPACEPARITY
;
1240 if (port
.c_cflag
& CSTOPB
)
1241 if(lpdcb
->ByteSize
== 5)
1242 lpdcb
->StopBits
= ONE5STOPBITS
;
1244 lpdcb
->StopBits
= TWOSTOPBITS
;
1246 lpdcb
->StopBits
= ONESTOPBIT
;
1251 /* termios does not support DTR/DSR flow control */
1252 lpdcb
->fOutxDsrFlow
= 0;
1253 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1257 if (port
.c_cflag
& CRTSCTS
) {
1258 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
1259 lpdcb
->fOutxCtsFlow
= 1;
1263 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1264 lpdcb
->fOutxCtsFlow
= 0;
1266 if (port
.c_iflag
& IXON
)
1271 if (port
.c_iflag
& IXOFF
)
1280 lpdcb
->XoffLim
= 10;
1282 COMM_SetCommError(handle
,0);
1286 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1287 lpdcb
->ByteSize
,lpdcb
->BaudRate
,lpdcb
->fParity
, lpdcb
->Parity
,
1288 (lpdcb
->StopBits
== ONESTOPBIT
)?1:
1289 (lpdcb
->StopBits
== TWOSTOPBITS
)?2:0);
1290 TRACE("%s %s\n",(lpdcb
->fInX
)?"IXON":"~IXON",
1291 (lpdcb
->fOutX
)?"IXOFF":"~IXOFF");
1293 if ( lpdcb
->fOutxCtsFlow
||
1294 lpdcb
->fRtsControl
== RTS_CONTROL_HANDSHAKE
1299 TRACE("~CRTSCTS\n");
1305 /*****************************************************************************
1306 * TransmitCommChar (KERNEL32.@)
1308 * Transmits a single character in front of any pending characters in the
1309 * output buffer. Usually used to send an interrupt character to a host.
1313 * True if the call succeeded, false if the previous command character to the
1314 * same device has not been sent yet the handle is bad etc.
1320 BOOL WINAPI
TransmitCommChar(
1321 HANDLE hComm
, /* [in] The communication device in need of a command character. */
1322 CHAR chTransmit
) /* [in] The character to transmit. */
1324 FIXME("(%x,'%c'), use win32 handle!\n",hComm
,chTransmit
);
1328 /*****************************************************************************
1329 * GetCommTimeouts (KERNEL32.@)
1331 * Obtains the request time out values for the communications device.
1335 * True on success, false if communications device handle is bad
1336 * or the target structure is null.
1338 BOOL WINAPI
GetCommTimeouts(
1339 HANDLE hComm
, /* [in] The communications device. */
1340 LPCOMMTIMEOUTS lptimeouts
) /* [out] The struct of request time outs. */
1344 TRACE("(%x,%p)\n",hComm
,lptimeouts
);
1348 SetLastError(ERROR_INVALID_PARAMETER
);
1352 SERVER_START_REQ( get_serial_info
)
1354 req
->handle
= hComm
;
1355 if ((ret
= !wine_server_call_err( req
)))
1357 lptimeouts
->ReadIntervalTimeout
= reply
->readinterval
;
1358 lptimeouts
->ReadTotalTimeoutMultiplier
= reply
->readmult
;
1359 lptimeouts
->ReadTotalTimeoutConstant
= reply
->readconst
;
1360 lptimeouts
->WriteTotalTimeoutMultiplier
= reply
->writemult
;
1361 lptimeouts
->WriteTotalTimeoutConstant
= reply
->writeconst
;
1368 /*****************************************************************************
1369 * SetCommTimeouts (KERNEL32.@)
1371 * Sets the timeouts used when reading and writing data to/from COMM ports.
1373 * ReadIntervalTimeout
1374 * - converted and passes to linux kernel as c_cc[VTIME]
1375 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1376 * - used in ReadFile to calculate GetOverlappedResult's timeout
1377 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1378 * - used in WriteFile to calculate GetOverlappedResult's timeout
1382 * True if the time outs were set, false otherwise.
1384 BOOL WINAPI
SetCommTimeouts(
1385 HANDLE hComm
, /* [in] handle of COMM device */
1386 LPCOMMTIMEOUTS lptimeouts
) /* [in] pointer to COMMTIMEOUTS structure */
1390 struct termios tios
;
1392 TRACE("(%x,%p)\n",hComm
,lptimeouts
);
1396 SetLastError(ERROR_INVALID_PARAMETER
);
1400 SERVER_START_REQ( set_serial_info
)
1402 req
->handle
= hComm
;
1403 req
->flags
= SERIALINFO_SET_TIMEOUTS
;
1404 req
->readinterval
= lptimeouts
->ReadIntervalTimeout
;
1405 req
->readmult
= lptimeouts
->ReadTotalTimeoutMultiplier
;
1406 req
->readconst
= lptimeouts
->ReadTotalTimeoutConstant
;
1407 req
->writemult
= lptimeouts
->WriteTotalTimeoutMultiplier
;
1408 req
->writeconst
= lptimeouts
->WriteTotalTimeoutConstant
;
1409 ret
= !wine_server_call_err( req
);
1412 if (!ret
) return FALSE
;
1414 /* FIXME: move this stuff to the server */
1415 fd
= FILE_GetUnixHandle( hComm
, GENERIC_READ
);
1417 FIXME("no fd for handle = %0x!.\n",hComm
);
1421 if (-1==tcgetattr(fd
,&tios
)) {
1422 FIXME("tcgetattr on fd %d failed!\n",fd
);
1426 /* VTIME is in 1/10 seconds */
1428 unsigned int ux_timeout
;
1430 if(lptimeouts
->ReadIntervalTimeout
== 0) /* 0 means no timeout */
1436 ux_timeout
= (lptimeouts
->ReadIntervalTimeout
+99)/100;
1439 ux_timeout
= 1; /* must be at least some timeout */
1442 tios
.c_cc
[VTIME
] = ux_timeout
;
1445 if (-1==tcsetattr(fd
,0,&tios
)) {
1446 FIXME("tcsetattr on fd %d failed!\n",fd
);
1453 /***********************************************************************
1454 * GetCommModemStatus (KERNEL32.@)
1456 * Obtains the four control register bits if supported by the hardware.
1460 * True if the communications handle was good and for hardware that
1461 * control register access, false otherwise.
1463 BOOL WINAPI
GetCommModemStatus(
1464 HANDLE hFile
, /* [in] The communications device. */
1465 LPDWORD lpModemStat
) /* [out] The control register bits. */
1467 int fd
,mstat
, result
=FALSE
;
1471 fd
= FILE_GetUnixHandle( hFile
, GENERIC_READ
);
1474 result
= ioctl(fd
, TIOCMGET
, &mstat
);
1478 WARN("ioctl failed\n");
1482 if (mstat
& TIOCM_CTS
)
1483 *lpModemStat
|= MS_CTS_ON
;
1486 if (mstat
& TIOCM_DSR
)
1487 *lpModemStat
|= MS_DSR_ON
;
1490 if (mstat
& TIOCM_RNG
)
1491 *lpModemStat
|= MS_RING_ON
;
1494 /*FIXME: Not really sure about RLSD UB 990810*/
1495 if (mstat
& TIOCM_CAR
)
1496 *lpModemStat
|= MS_RLSD_ON
;
1498 TRACE("%04x -> %s%s%s%s\n", mstat
,
1499 (*lpModemStat
&MS_RLSD_ON
)?"MS_RLSD_ON ":"",
1500 (*lpModemStat
&MS_RING_ON
)?"MS_RING_ON ":"",
1501 (*lpModemStat
&MS_DSR_ON
)?"MS_DSR_ON ":"",
1502 (*lpModemStat
&MS_CTS_ON
)?"MS_CTS_ON ":"");
1509 /***********************************************************************
1510 * COMM_WaitCommEventService (INTERNAL)
1512 * This function is called while the client is waiting on the
1513 * server, so we can't make any server calls here.
1515 static void COMM_WaitCommEventService(async_private
*ovp
)
1517 LPOVERLAPPED lpOverlapped
= ovp
->lpOverlapped
;
1519 TRACE("overlapped %p\n",lpOverlapped
);
1521 /* FIXME: detect other events */
1522 *ovp
->buffer
= EV_RXCHAR
;
1524 lpOverlapped
->Internal
= STATUS_SUCCESS
;
1528 /***********************************************************************
1529 * COMM_WaitCommEvent (INTERNAL)
1531 * This function must have an lpOverlapped.
1533 static BOOL
COMM_WaitCommEvent(
1534 HANDLE hFile
, /* [in] handle of comm port to wait for */
1535 LPDWORD lpdwEvents
, /* [out] event(s) that were detected */
1536 LPOVERLAPPED lpOverlapped
) /* [in/out] for Asynchronous waiting */
1543 SetLastError(ERROR_INVALID_PARAMETER
);
1547 if(NtResetEvent(lpOverlapped
->hEvent
,NULL
))
1550 lpOverlapped
->Internal
= STATUS_PENDING
;
1551 lpOverlapped
->InternalHigh
= 0;
1552 lpOverlapped
->Offset
= 0;
1553 lpOverlapped
->OffsetHigh
= 0;
1555 fd
= FILE_GetUnixHandle( hFile
, GENERIC_WRITE
);
1559 ovp
= (async_private
*) HeapAlloc(GetProcessHeap(), 0, sizeof (async_private
));
1565 ovp
->lpOverlapped
= lpOverlapped
;
1566 ovp
->func
= COMM_WaitCommEventService
;
1567 ovp
->buffer
= (char *)lpdwEvents
;
1570 ovp
->completion_func
= 0;
1571 ovp
->type
= ASYNC_TYPE_WAIT
;
1572 ovp
->handle
= hFile
;
1574 ovp
->next
= NtCurrentTeb()->pending_list
;
1577 ovp
->next
->prev
=ovp
;
1578 NtCurrentTeb()->pending_list
= ovp
;
1580 /* start an ASYNCHRONOUS WaitCommEvent */
1581 SERVER_START_REQ( register_async
)
1583 req
->handle
= hFile
;
1584 req
->overlapped
= lpOverlapped
;
1585 req
->type
= ASYNC_TYPE_WAIT
;
1587 req
->func
= check_async_list
;
1588 req
->status
= STATUS_PENDING
;
1590 ret
=wine_server_call_err(req
);
1595 SetLastError(ERROR_IO_PENDING
);
1600 /***********************************************************************
1601 * WaitCommEvent (KERNEL32.@)
1603 * Wait until something interesting happens on a COMM port.
1604 * Interesting things (events) are set by calling SetCommMask before
1605 * this function is called.
1608 * TRUE if successful
1611 * The set of detected events will be written to *lpdwEventMask
1612 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1615 * Only supports EV_RXCHAR and EV_TXEMPTY
1617 BOOL WINAPI
WaitCommEvent(
1618 HANDLE hFile
, /* [in] handle of comm port to wait for */
1619 LPDWORD lpdwEvents
, /* [out] event(s) that were detected */
1620 LPOVERLAPPED lpOverlapped
) /* [in/out] for Asynchronous waiting */
1625 TRACE("(%x %p %p )\n",hFile
, lpdwEvents
,lpOverlapped
);
1628 return COMM_WaitCommEvent(hFile
, lpdwEvents
, lpOverlapped
);
1630 /* if there is no overlapped structure, create our own */
1631 ov
.hEvent
= CreateEventA(NULL
,FALSE
,FALSE
,NULL
);
1633 COMM_WaitCommEvent(hFile
, lpdwEvents
, &ov
);
1635 if(GetLastError()!=STATUS_PENDING
)
1637 CloseHandle(ov
.hEvent
);
1641 /* wait for the overlapped to complete */
1642 ret
= GetOverlappedResult(hFile
, &ov
, NULL
, TRUE
);
1643 CloseHandle(ov
.hEvent
);
1648 /***********************************************************************
1649 * GetCommProperties (KERNEL32.@)
1651 * This function fills in a structure with the capabilities of the
1652 * communications port driver.
1656 * TRUE on success, FALSE on failure
1657 * If successful, the lpCommProp structure be filled in with
1658 * properties of the comm port.
1660 BOOL WINAPI
GetCommProperties(
1661 HANDLE hFile
, /* [in] handle of the comm port */
1662 LPCOMMPROP lpCommProp
) /* [out] pointer to struct to be filled */
1664 FIXME("(%d %p )\n",hFile
,lpCommProp
);
1669 * These values should be valid for LINUX's serial driver
1670 * FIXME: Perhaps they deserve an #ifdef LINUX
1672 memset(lpCommProp
,0,sizeof(COMMPROP
));
1673 lpCommProp
->wPacketLength
= 1;
1674 lpCommProp
->wPacketVersion
= 1;
1675 lpCommProp
->dwServiceMask
= SP_SERIALCOMM
;
1676 lpCommProp
->dwReserved1
= 0;
1677 lpCommProp
->dwMaxTxQueue
= 4096;
1678 lpCommProp
->dwMaxRxQueue
= 4096;
1679 lpCommProp
->dwMaxBaud
= BAUD_115200
;
1680 lpCommProp
->dwProvSubType
= PST_RS232
;
1681 lpCommProp
->dwProvCapabilities
= PCF_DTRDSR
| PCF_PARITY_CHECK
| PCF_RTSCTS
;
1682 lpCommProp
->dwSettableParams
= SP_BAUD
| SP_DATABITS
| SP_HANDSHAKING
|
1683 SP_PARITY
| SP_PARITY_CHECK
| SP_STOPBITS
;
1684 lpCommProp
->dwSettableBaud
= BAUD_075
| BAUD_110
| BAUD_134_5
| BAUD_150
|
1685 BAUD_300
| BAUD_600
| BAUD_1200
| BAUD_1800
| BAUD_2400
| BAUD_4800
|
1686 BAUD_9600
| BAUD_19200
| BAUD_38400
| BAUD_57600
| BAUD_115200
;
1687 lpCommProp
->wSettableData
= DATABITS_5
| DATABITS_6
| DATABITS_7
| DATABITS_8
;
1688 lpCommProp
->wSettableStopParity
= STOPBITS_10
| STOPBITS_15
| STOPBITS_20
|
1689 PARITY_NONE
| PARITY_ODD
|PARITY_EVEN
| PARITY_MARK
| PARITY_SPACE
;
1690 lpCommProp
->dwCurrentTxQueue
= lpCommProp
->dwMaxTxQueue
;
1691 lpCommProp
->dwCurrentRxQueue
= lpCommProp
->dwMaxRxQueue
;
1696 /***********************************************************************
1698 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1699 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1700 * This is dependent on the type of COMM port, but since it is doubtful
1701 * anybody will get around to implementing support for fancy serial
1702 * ports in WINE, this is hardcoded for the time being. The name of
1703 * this DLL should be stored in and read from the system registry in
1704 * the hive HKEY_LOCAL_MACHINE, key
1705 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1706 * where ???? is the port number... that is determined by PNP
1707 * The DLL should be loaded when the COMM port is opened, and closed
1708 * when the COMM port is closed. - MJM 20 June 2000
1709 ***********************************************************************/
1710 static CHAR lpszSerialUI
[] = "serialui.dll";
1713 /***********************************************************************
1714 * CommConfigDialogA (KERNEL32.@)
1716 * Raises a dialog that allows the user to configure a comm port.
1717 * Fills the COMMCONFIG struct with information specified by the user.
1718 * This function should call a similar routine in the COMM driver...
1722 * TRUE on success, FALSE on failure
1723 * If successful, the lpCommConfig structure will contain a new
1724 * configuration for the comm port, as specified by the user.
1727 * The library with the CommConfigDialog code is never unloaded.
1728 * Perhaps this should be done when the comm port is closed?
1730 BOOL WINAPI
CommConfigDialogA(
1731 LPCSTR lpszDevice
, /* [in] name of communications device */
1732 HANDLE hWnd
, /* [in] parent window for the dialog */
1733 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
1735 FARPROC lpfnCommDialog
;
1736 HMODULE hConfigModule
;
1739 TRACE("(%p %x %p)\n",lpszDevice
, hWnd
, lpCommConfig
);
1741 hConfigModule
= LoadLibraryA(lpszSerialUI
);
1745 lpfnCommDialog
= GetProcAddress(hConfigModule
, (LPCSTR
)3L);
1750 r
= lpfnCommDialog(lpszDevice
,hWnd
,lpCommConfig
);
1752 /* UnloadLibrary(hConfigModule); */
1757 /***********************************************************************
1758 * CommConfigDialogW (KERNEL32.@)
1760 * see CommConfigDialogA for more info
1762 BOOL WINAPI
CommConfigDialogW(
1763 LPCWSTR lpszDevice
, /* [in] name of communications device */
1764 HANDLE hWnd
, /* [in] parent window for the dialog */
1765 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
1770 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
1773 r
= CommConfigDialogA(lpDeviceA
,hWnd
,lpCommConfig
);
1774 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
1778 /***********************************************************************
1779 * GetCommConfig (KERNEL32.@)
1781 * Fill in the COMMCONFIG structure for the comm port hFile
1785 * TRUE on success, FALSE on failure
1786 * If successful, lpCommConfig contains the comm port configuration.
1790 * The signature is missing a the parameter for the size of the COMMCONFIG
1791 * structure/buffer it should be
1792 * BOOL WINAPI GetCommConfig(HANDLE hFile,LPCOMMCONFIG lpCommConfig,LPDWORD lpdwSize)
1794 BOOL WINAPI
GetCommConfig(
1795 HANDLE hFile
, /* [in] The communications device. */
1796 LPCOMMCONFIG lpCommConfig
, /* [out] The communications configuration of the device (if it fits). */
1797 LPDWORD lpdwSize
) /* [in/out] Initially the size of the configuration buffer/structure,
1798 afterwards the number of bytes copied to the buffer or
1799 the needed size of the buffer. */
1803 TRACE("(%x %p)\n",hFile
,lpCommConfig
);
1805 if(lpCommConfig
== NULL
)
1808 r
= *lpdwSize
< sizeof(COMMCONFIG
);
1809 *lpdwSize
= sizeof(COMMCONFIG
);
1813 lpCommConfig
->dwSize
= sizeof(COMMCONFIG
);
1814 lpCommConfig
->wVersion
= 1;
1815 lpCommConfig
->wReserved
= 0;
1816 r
= GetCommState(hFile
,&lpCommConfig
->dcb
);
1817 lpCommConfig
->dwProviderSubType
= PST_RS232
;
1818 lpCommConfig
->dwProviderOffset
= 0;
1819 lpCommConfig
->dwProviderSize
= 0;
1824 /***********************************************************************
1825 * SetCommConfig (KERNEL32.@)
1827 * Sets the configuration of the commications device.
1831 * True on success, false if the handle was bad is not a communications device.
1833 BOOL WINAPI
SetCommConfig(
1834 HANDLE hFile
, /* [in] The communications device. */
1835 LPCOMMCONFIG lpCommConfig
, /* [in] The desired configuration. */
1836 DWORD dwSize
) /* [in] size of the lpCommConfig struct */
1838 TRACE("(%x %p)\n",hFile
,lpCommConfig
);
1839 return SetCommState(hFile
,&lpCommConfig
->dcb
);
1842 /***********************************************************************
1843 * SetDefaultCommConfigA (KERNEL32.@)
1845 * Initializes the default configuration for the specified communication
1850 * True if the device was found and the defaults set, false otherwise
1852 BOOL WINAPI
SetDefaultCommConfigA(
1853 LPCSTR lpszDevice
, /* [in] The ascii name of the device targeted for configuration. */
1854 LPCOMMCONFIG lpCommConfig
, /* [in] The default configuration for the device. */
1855 DWORD dwSize
) /* [in] The number of bytes in the configuration structure. */
1857 FARPROC lpfnSetDefaultCommConfig
;
1858 HMODULE hConfigModule
;
1861 TRACE("(%p %p %lx)\n",lpszDevice
, lpCommConfig
, dwSize
);
1863 hConfigModule
= LoadLibraryA(lpszSerialUI
);
1867 lpfnSetDefaultCommConfig
= GetProcAddress(hConfigModule
, (LPCSTR
)4L);
1869 if(! lpfnSetDefaultCommConfig
)
1872 r
= lpfnSetDefaultCommConfig(lpszDevice
, lpCommConfig
, dwSize
);
1874 /* UnloadLibrary(hConfigModule); */
1880 /***********************************************************************
1881 * SetDefaultCommConfigW (KERNEL32.@)
1883 * Initializes the default configuration for the specified
1884 * communication device. (unicode)
1889 BOOL WINAPI
SetDefaultCommConfigW(
1890 LPCWSTR lpszDevice
, /* [in] The unicode name of the device targeted for configuration. */
1891 LPCOMMCONFIG lpCommConfig
, /* [in] The default configuration for the device. */
1892 DWORD dwSize
) /* [in] The number of bytes in the configuration structure. */
1897 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice
),lpCommConfig
,dwSize
);
1899 lpDeviceA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice
);
1902 r
= SetDefaultCommConfigA(lpDeviceA
,lpCommConfig
,dwSize
);
1903 HeapFree( GetProcessHeap(), 0, lpDeviceA
);
1908 /***********************************************************************
1909 * GetDefaultCommConfigA (KERNEL32.@)
1911 * Acquires the default configuration of the specified communication device. (unicode)
1915 * True on successful reading of the default configuration,
1916 * if the device is not found or the buffer is too small.
1918 BOOL WINAPI
GetDefaultCommConfigA(
1919 LPCSTR lpszName
, /* [in] The ascii name of the device targeted for configuration. */
1920 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
1921 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
1922 afterwards the number of bytes copied to the buffer or
1923 the needed size of the buffer. */
1925 LPDCB lpdcb
= &(lpCC
->dcb
);
1928 if (strncasecmp(lpszName
,"COM",3)) {
1929 ERR("not implemented for <%s>\n", lpszName
);
1933 TRACE("(%s %p %ld)\n", lpszName
, lpCC
, *lpdwSize
);
1934 if (*lpdwSize
< sizeof(COMMCONFIG
)) {
1935 *lpdwSize
= sizeof(COMMCONFIG
);
1939 *lpdwSize
= sizeof(COMMCONFIG
);
1941 lpCC
->dwSize
= sizeof(COMMCONFIG
);
1943 lpCC
->dwProviderSubType
= PST_RS232
;
1944 lpCC
->dwProviderOffset
= 0L;
1945 lpCC
->dwProviderSize
= 0L;
1947 (void) sprintf( temp
, "COM%c:38400,n,8,1", lpszName
[3]);
1948 FIXME("setting %s as default\n", temp
);
1950 return BuildCommDCBA( temp
, lpdcb
);
1953 /**************************************************************************
1954 * GetDefaultCommConfigW (KERNEL32.@)
1956 * Acquires the default configuration of the specified communication device. (unicode)
1960 * True on successful reading of the default configuration,
1961 * if the device is not found or the buffer is too small.
1963 BOOL WINAPI
GetDefaultCommConfigW(
1964 LPCWSTR lpszName
, /* [in] The unicode name of the device targeted for configuration. */
1965 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
1966 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
1967 afterwards the number of bytes copied to the buffer or
1968 the needed size of the buffer. */
1973 TRACE("(%p,%p,%ld)\n",lpszName
,lpCC
,*lpdwSize
);
1974 lpszNameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName
);
1977 ret
=GetDefaultCommConfigA(lpszNameA
,lpCC
,lpdwSize
);
1978 HeapFree( GetProcessHeap(), 0, lpszNameA
);