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 /* Some applications call this function with "9600,n,8,1"
172 * not sending the "COM1:" parameter at left of string */
173 if (!strncasecmp(device,"COM",3))
175 if (!device[3]) return FALSE;
176 if (device[4] != ':' && device[4] != ' ') return FALSE;
177 strcpy(temp,device+5);
179 else strcpy(temp,device);
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;
1052 port.c_cflag |= B57600;
1058 port.c_cflag |= B115200;
1063 port.c_cflag |= B230400;
1068 port.c_cflag |= B460800;
1072 COMM_SetCommError(handle,IE_BAUDRATE);
1074 ERR("baudrate %ld\n",lpdcb->BaudRate);
1077 port.c_ispeed = port.c_ospeed;
1079 bytesize=lpdcb->ByteSize;
1080 stopbits=lpdcb->StopBits;
1083 port.c_cflag &= ~(PARENB | PARODD | CMSPAR);
1085 port.c_cflag &= ~(PARENB | PARODD);
1088 port.c_iflag |= INPCK;
1090 port.c_iflag &= ~INPCK;
1091 switch (lpdcb->Parity) {
1095 port.c_cflag |= (PARENB | PARODD);
1098 port.c_cflag |= PARENB;
1101 /* Linux defines mark/space (stick) parity */
1103 port.c_cflag |= (PARENB | CMSPAR);
1106 port.c_cflag |= (PARENB | PARODD | CMSPAR);
1109 /* try the POSIX way */
1111 if( stopbits == ONESTOPBIT) {
1112 stopbits = TWOSTOPBITS;
1113 port.c_iflag &= ~INPCK;
1115 COMM_SetCommError(handle,IE_BYTESIZE);
1117 ERR("Cannot set MARK Parity\n");
1124 port.c_iflag &= ~INPCK;
1126 COMM_SetCommError(handle,IE_BYTESIZE);
1128 ERR("Cannot set SPACE Parity\n");
1134 COMM_SetCommError(handle,IE_BYTESIZE);
1141 port.c_cflag &= ~CSIZE;
1144 port.c_cflag |= CS5;
1147 port.c_cflag |= CS6;
1150 port.c_cflag |= CS7;
1153 port.c_cflag |= CS8;
1156 COMM_SetCommError(handle,IE_BYTESIZE);
1164 port.c_cflag &= ~CSTOPB;
1166 case ONE5STOPBITS: /* wil be selected if bytesize is 5 */
1168 port.c_cflag |= CSTOPB;
1171 COMM_SetCommError(handle,IE_BYTESIZE);
1177 if ( lpdcb->fOutxCtsFlow ||
1178 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1181 port.c_cflag |= CRTSCTS;
1186 if (lpdcb->fDtrControl == DTR_CONTROL_HANDSHAKE)
1188 WARN("DSR/DTR flow control not supported\n");
1192 port.c_iflag |= IXON;
1194 port.c_iflag &= ~IXON;
1196 port.c_iflag |= IXOFF;
1198 port.c_iflag &= ~IXOFF;
1200 if (tcsetattr(fd,TCSANOW,&port)==-1) { /* otherwise it hangs with pending input*/
1201 int save_error=errno;
1202 COMM_SetCommError(handle,CE_IOE);
1204 ERR("tcsetattr error '%s'\n", strerror(save_error));
1207 COMM_SetCommError(handle,0);
1214 /*****************************************************************************
1215 * GetCommState (KERNEL32.@)
1217 * Fills in a device control block with information from a communications device.
1221 * True on success, false if the communication device handle is bad etc
1225 * XonChar and XoffChar are not set.
1227 BOOL WINAPI GetCommState(
1228 HANDLE handle, /* [in] The communications device. */
1229 LPDCB lpdcb) /* [out] The device control block. */
1231 struct termios port;
1234 TRACE("handle %d, ptr %p\n", handle, lpdcb);
1236 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
1239 ERR("FILE_GetUnixHandle failed\n");
1242 if (tcgetattr(fd, &port) == -1) {
1243 int save_error=errno;
1244 ERR("tcgetattr error '%s'\n", strerror(save_error));
1245 COMM_SetCommError(handle,CE_IOE);
1252 speed= (port.c_cflag & CBAUD);
1254 speed= (cfgetospeed(&port));
1258 lpdcb->BaudRate = 110;
1261 lpdcb->BaudRate = 300;
1264 lpdcb->BaudRate = 600;
1267 lpdcb->BaudRate = 1200;
1270 lpdcb->BaudRate = 2400;
1273 lpdcb->BaudRate = 4800;
1276 lpdcb->BaudRate = 9600;
1279 lpdcb->BaudRate = 19200;
1282 lpdcb->BaudRate = 38400;
1286 lpdcb->BaudRate = 57600;
1291 lpdcb->BaudRate = 115200;
1296 lpdcb->BaudRate = 230400;
1301 lpdcb->BaudRate = 460800;
1305 ERR("unknown speed %x \n",speed);
1308 switch (port.c_cflag & CSIZE) {
1310 lpdcb->ByteSize = 5;
1313 lpdcb->ByteSize = 6;
1316 lpdcb->ByteSize = 7;
1319 lpdcb->ByteSize = 8;
1322 ERR("unknown size %x \n",port.c_cflag & CSIZE);
1325 if(port.c_iflag & INPCK)
1326 lpdcb->fParity = TRUE;
1328 lpdcb->fParity = FALSE;
1330 switch (port.c_cflag & (PARENB | PARODD | CMSPAR))
1332 switch (port.c_cflag & (PARENB | PARODD))
1336 lpdcb->Parity = NOPARITY;
1339 lpdcb->Parity = EVENPARITY;
1341 case (PARENB | PARODD):
1342 lpdcb->Parity = ODDPARITY;
1345 case (PARENB | CMSPAR):
1346 lpdcb->Parity = MARKPARITY;
1348 case (PARENB | PARODD | CMSPAR):
1349 lpdcb->Parity = SPACEPARITY;
1354 if (port.c_cflag & CSTOPB)
1355 if(lpdcb->ByteSize == 5)
1356 lpdcb->StopBits = ONE5STOPBITS;
1358 lpdcb->StopBits = TWOSTOPBITS;
1360 lpdcb->StopBits = ONESTOPBIT;
1365 /* termios does not support DTR/DSR flow control */
1366 lpdcb->fOutxDsrFlow = 0;
1367 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
1371 if (port.c_cflag & CRTSCTS) {
1372 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
1373 lpdcb->fOutxCtsFlow = 1;
1377 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
1378 lpdcb->fOutxCtsFlow = 0;
1380 if (port.c_iflag & IXON)
1385 if (port.c_iflag & IXOFF)
1394 lpdcb->XoffLim = 10;
1396 COMM_SetCommError(handle,0);
1400 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1401 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
1402 (lpdcb->StopBits == ONESTOPBIT)?1:
1403 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
1404 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
1405 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
1407 if ( lpdcb->fOutxCtsFlow ||
1408 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1413 TRACE("~CRTSCTS\n");
1419 /*****************************************************************************
1420 * TransmitCommChar (KERNEL32.@)
1422 * Transmits a single character in front of any pending characters in the
1423 * output buffer. Usually used to send an interrupt character to a host.
1427 * True if the call succeeded, false if the previous command character to the
1428 * same device has not been sent yet the handle is bad etc.
1434 BOOL WINAPI TransmitCommChar(
1435 HANDLE hComm, /* [in] The communication device in need of a command character. */
1436 CHAR chTransmit) /* [in] The character to transmit. */
1441 WARN("(%x,'%c') not perfect!\n",hComm,chTransmit);
1443 fd = FILE_GetUnixHandle( hComm, GENERIC_READ );
1445 SetLastError ( ERROR_INVALID_PARAMETER );
1448 r = (1 == write(fd, &chTransmit, 1));
1456 /*****************************************************************************
1457 * GetCommTimeouts (KERNEL32.@)
1459 * Obtains the request timeout values for the communications device.
1463 * True on success, false if communications device handle is bad
1464 * or the target structure is null.
1466 BOOL WINAPI GetCommTimeouts(
1467 HANDLE hComm, /* [in] The communications device. */
1468 LPCOMMTIMEOUTS lptimeouts) /* [out] The struct of request timeouts. */
1472 TRACE("(%x,%p)\n",hComm,lptimeouts);
1476 SetLastError(ERROR_INVALID_PARAMETER);
1480 SERVER_START_REQ( get_serial_info )
1482 req->handle = hComm;
1483 if ((ret = !wine_server_call_err( req )))
1485 lptimeouts->ReadIntervalTimeout = reply->readinterval;
1486 lptimeouts->ReadTotalTimeoutMultiplier = reply->readmult;
1487 lptimeouts->ReadTotalTimeoutConstant = reply->readconst;
1488 lptimeouts->WriteTotalTimeoutMultiplier = reply->writemult;
1489 lptimeouts->WriteTotalTimeoutConstant = reply->writeconst;
1496 /*****************************************************************************
1497 * SetCommTimeouts (KERNEL32.@)
1499 * Sets the timeouts used when reading and writing data to/from COMM ports.
1501 * ReadIntervalTimeout
1502 * - converted and passes to linux kernel as c_cc[VTIME]
1503 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1504 * - used in ReadFile to calculate GetOverlappedResult's timeout
1505 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1506 * - used in WriteFile to calculate GetOverlappedResult's timeout
1510 * True if the timeouts were set, false otherwise.
1512 BOOL WINAPI SetCommTimeouts(
1513 HANDLE hComm, /* [in] handle of COMM device */
1514 LPCOMMTIMEOUTS lptimeouts) /* [in] pointer to COMMTIMEOUTS structure */
1518 struct termios tios;
1520 TRACE("(%x,%p)\n",hComm,lptimeouts);
1524 SetLastError(ERROR_INVALID_PARAMETER);
1528 SERVER_START_REQ( set_serial_info )
1530 req->handle = hComm;
1531 req->flags = SERIALINFO_SET_TIMEOUTS;
1532 req->readinterval = lptimeouts->ReadIntervalTimeout ;
1533 req->readmult = lptimeouts->ReadTotalTimeoutMultiplier ;
1534 req->readconst = lptimeouts->ReadTotalTimeoutConstant ;
1535 req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ;
1536 req->writeconst = lptimeouts->WriteTotalTimeoutConstant ;
1537 ret = !wine_server_call_err( req );
1540 if (!ret) return FALSE;
1542 /* FIXME: move this stuff to the server */
1543 fd = FILE_GetUnixHandle( hComm, GENERIC_READ );
1545 FIXME("no fd for handle = %0x!.\n",hComm);
1549 if (-1==tcgetattr(fd,&tios)) {
1550 FIXME("tcgetattr on fd %d failed!\n",fd);
1554 /* VTIME is in 1/10 seconds */
1556 unsigned int ux_timeout;
1558 if(lptimeouts->ReadIntervalTimeout == 0) /* 0 means no timeout */
1564 ux_timeout = (lptimeouts->ReadIntervalTimeout+99)/100;
1567 ux_timeout = 1; /* must be at least some timeout */
1570 tios.c_cc[VTIME] = ux_timeout;
1573 if (-1==tcsetattr(fd,0,&tios)) {
1574 FIXME("tcsetattr on fd %d failed!\n",fd);
1581 /***********************************************************************
1582 * GetCommModemStatus (KERNEL32.@)
1584 * Obtains the four control register bits if supported by the hardware.
1588 * True if the communications handle was good and for hardware that
1589 * control register access, false otherwise.
1591 BOOL WINAPI GetCommModemStatus(
1592 HANDLE hFile, /* [in] The communications device. */
1593 LPDWORD lpModemStat) /* [out] The control register bits. */
1595 int fd,mstat, result=FALSE;
1599 fd = FILE_GetUnixHandle( hFile, GENERIC_READ );
1602 result = ioctl(fd, TIOCMGET, &mstat);
1606 WARN("ioctl failed\n");
1610 if (mstat & TIOCM_CTS)
1611 *lpModemStat |= MS_CTS_ON;
1614 if (mstat & TIOCM_DSR)
1615 *lpModemStat |= MS_DSR_ON;
1618 if (mstat & TIOCM_RNG)
1619 *lpModemStat |= MS_RING_ON;
1622 /*FIXME: Not really sure about RLSD UB 990810*/
1623 if (mstat & TIOCM_CAR)
1624 *lpModemStat |= MS_RLSD_ON;
1626 TRACE("%04x -> %s%s%s%s\n", mstat,
1627 (*lpModemStat &MS_RLSD_ON)?"MS_RLSD_ON ":"",
1628 (*lpModemStat &MS_RING_ON)?"MS_RING_ON ":"",
1629 (*lpModemStat &MS_DSR_ON)?"MS_DSR_ON ":"",
1630 (*lpModemStat &MS_CTS_ON)?"MS_CTS_ON ":"");
1637 /***********************************************************************
1638 * COMM_WaitCommEventService (INTERNAL)
1640 * This function is called while the client is waiting on the
1641 * server, so we can't make any server calls here.
1643 static void COMM_WaitCommEventService(async_private *ovp)
1645 async_commio *commio = (async_commio*) ovp;
1646 LPOVERLAPPED lpOverlapped = commio->lpOverlapped;
1648 TRACE("overlapped %p\n",lpOverlapped);
1650 /* FIXME: detect other events */
1651 *commio->buffer = EV_RXCHAR;
1653 lpOverlapped->Internal = STATUS_SUCCESS;
1657 /***********************************************************************
1658 * COMM_WaitCommEvent (INTERNAL)
1660 * This function must have an lpOverlapped.
1662 static BOOL COMM_WaitCommEvent(
1663 HANDLE hFile, /* [in] handle of comm port to wait for */
1664 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1665 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1672 SetLastError(ERROR_INVALID_PARAMETER);
1676 if(NtResetEvent(lpOverlapped->hEvent,NULL))
1679 fd = FILE_GetUnixHandle( hFile, GENERIC_WRITE );
1683 ovp = (async_commio*) HeapAlloc(GetProcessHeap(), 0, sizeof (async_commio));
1690 ovp->async.ops = &commio_async_ops;
1691 ovp->async.handle = hFile;
1693 ovp->async.type = ASYNC_TYPE_WAIT;
1694 ovp->async.func = COMM_WaitCommEventService;
1695 ovp->async.event = lpOverlapped->hEvent;
1696 ovp->lpOverlapped = lpOverlapped;
1697 ovp->buffer = (char *)lpdwEvents;
1699 lpOverlapped->InternalHigh = 0;
1700 lpOverlapped->Offset = 0;
1701 lpOverlapped->OffsetHigh = 0;
1703 if ( !register_new_async (&ovp->async) )
1704 SetLastError( ERROR_IO_PENDING );
1709 /***********************************************************************
1710 * WaitCommEvent (KERNEL32.@)
1712 * Wait until something interesting happens on a COMM port.
1713 * Interesting things (events) are set by calling SetCommMask before
1714 * this function is called.
1717 * TRUE if successful
1720 * The set of detected events will be written to *lpdwEventMask
1721 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1724 * Only supports EV_RXCHAR and EV_TXEMPTY
1726 BOOL WINAPI WaitCommEvent(
1727 HANDLE hFile, /* [in] handle of comm port to wait for */
1728 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1729 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1734 TRACE("(%x %p %p )\n",hFile, lpdwEvents,lpOverlapped);
1737 return COMM_WaitCommEvent(hFile, lpdwEvents, lpOverlapped);
1739 /* if there is no overlapped structure, create our own */
1740 ov.hEvent = CreateEventA(NULL,FALSE,FALSE,NULL);
1742 COMM_WaitCommEvent(hFile, lpdwEvents, &ov);
1744 if(GetLastError()!=STATUS_PENDING)
1746 CloseHandle(ov.hEvent);
1750 /* wait for the overlapped to complete */
1751 ret = GetOverlappedResult(hFile, &ov, NULL, TRUE);
1752 CloseHandle(ov.hEvent);
1757 /***********************************************************************
1758 * GetCommProperties (KERNEL32.@)
1760 * This function fills in a structure with the capabilities of the
1761 * communications port driver.
1765 * TRUE on success, FALSE on failure
1766 * If successful, the lpCommProp structure be filled in with
1767 * properties of the comm port.
1769 BOOL WINAPI GetCommProperties(
1770 HANDLE hFile, /* [in] handle of the comm port */
1771 LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */
1773 FIXME("(%d %p )\n",hFile,lpCommProp);
1778 * These values should be valid for LINUX's serial driver
1779 * FIXME: Perhaps they deserve an #ifdef LINUX
1781 memset(lpCommProp,0,sizeof(COMMPROP));
1782 lpCommProp->wPacketLength = 1;
1783 lpCommProp->wPacketVersion = 1;
1784 lpCommProp->dwServiceMask = SP_SERIALCOMM;
1785 lpCommProp->dwReserved1 = 0;
1786 lpCommProp->dwMaxTxQueue = 4096;
1787 lpCommProp->dwMaxRxQueue = 4096;
1788 lpCommProp->dwMaxBaud = BAUD_115200;
1789 lpCommProp->dwProvSubType = PST_RS232;
1790 lpCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS ;
1791 lpCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING |
1792 SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ;
1793 lpCommProp->dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 |
1794 BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
1795 BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ;
1796 lpCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ;
1797 lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
1798 PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE;
1799 lpCommProp->dwCurrentTxQueue = lpCommProp->dwMaxTxQueue;
1800 lpCommProp->dwCurrentRxQueue = lpCommProp->dwMaxRxQueue;
1805 /***********************************************************************
1807 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1808 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1809 * This is dependent on the type of COMM port, but since it is doubtful
1810 * anybody will get around to implementing support for fancy serial
1811 * ports in WINE, this is hardcoded for the time being. The name of
1812 * this DLL should be stored in and read from the system registry in
1813 * the hive HKEY_LOCAL_MACHINE, key
1814 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1815 * where ???? is the port number... that is determined by PNP
1816 * The DLL should be loaded when the COMM port is opened, and closed
1817 * when the COMM port is closed. - MJM 20 June 2000
1818 ***********************************************************************/
1819 static CHAR lpszSerialUI[] = "serialui.dll";
1822 /***********************************************************************
1823 * CommConfigDialogA (KERNEL32.@)
1825 * Raises a dialog that allows the user to configure a comm port.
1826 * Fills the COMMCONFIG struct with information specified by the user.
1827 * This function should call a similar routine in the COMM driver...
1831 * TRUE on success, FALSE on failure
1832 * If successful, the lpCommConfig structure will contain a new
1833 * configuration for the comm port, as specified by the user.
1836 * The library with the CommConfigDialog code is never unloaded.
1837 * Perhaps this should be done when the comm port is closed?
1839 BOOL WINAPI CommConfigDialogA(
1840 LPCSTR lpszDevice, /* [in] name of communications device */
1841 HANDLE hWnd, /* [in] parent window for the dialog */
1842 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1844 FARPROC lpfnCommDialog;
1845 HMODULE hConfigModule;
1848 TRACE("(%p %x %p)\n",lpszDevice, hWnd, lpCommConfig);
1850 hConfigModule = LoadLibraryA(lpszSerialUI);
1854 lpfnCommDialog = GetProcAddress(hConfigModule, (LPCSTR)3L);
1859 r = lpfnCommDialog(lpszDevice,hWnd,lpCommConfig);
1861 /* UnloadLibrary(hConfigModule); */
1866 /***********************************************************************
1867 * CommConfigDialogW (KERNEL32.@)
1869 * see CommConfigDialogA for more info
1871 BOOL WINAPI CommConfigDialogW(
1872 LPCWSTR lpszDevice, /* [in] name of communications device */
1873 HANDLE hWnd, /* [in] parent window for the dialog */
1874 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1879 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
1882 r = CommConfigDialogA(lpDeviceA,hWnd,lpCommConfig);
1883 HeapFree( GetProcessHeap(), 0, lpDeviceA );
1887 /***********************************************************************
1888 * GetCommConfig (KERNEL32.@)
1890 * Fill in the COMMCONFIG structure for the comm port hFile
1894 * TRUE on success, FALSE on failure
1895 * If successful, lpCommConfig contains the comm port configuration.
1900 BOOL WINAPI GetCommConfig(
1901 HANDLE hFile, /* [in] The communications device. */
1902 LPCOMMCONFIG lpCommConfig, /* [out] The communications configuration of the device (if it fits). */
1903 LPDWORD lpdwSize) /* [in/out] Initially the size of the configuration buffer/structure,
1904 afterwards the number of bytes copied to the buffer or
1905 the needed size of the buffer. */
1909 TRACE("(%x %p)\n",hFile,lpCommConfig);
1911 if(lpCommConfig == NULL)
1914 r = *lpdwSize < sizeof(COMMCONFIG);
1915 *lpdwSize = sizeof(COMMCONFIG);
1919 lpCommConfig->dwSize = sizeof(COMMCONFIG);
1920 lpCommConfig->wVersion = 1;
1921 lpCommConfig->wReserved = 0;
1922 r = GetCommState(hFile,&lpCommConfig->dcb);
1923 lpCommConfig->dwProviderSubType = PST_RS232;
1924 lpCommConfig->dwProviderOffset = 0;
1925 lpCommConfig->dwProviderSize = 0;
1930 /***********************************************************************
1931 * SetCommConfig (KERNEL32.@)
1933 * Sets the configuration of the communications device.
1937 * True on success, false if the handle was bad is not a communications device.
1939 BOOL WINAPI SetCommConfig(
1940 HANDLE hFile, /* [in] The communications device. */
1941 LPCOMMCONFIG lpCommConfig, /* [in] The desired configuration. */
1942 DWORD dwSize) /* [in] size of the lpCommConfig struct */
1944 TRACE("(%x %p)\n",hFile,lpCommConfig);
1945 return SetCommState(hFile,&lpCommConfig->dcb);
1948 /***********************************************************************
1949 * SetDefaultCommConfigA (KERNEL32.@)
1951 * Initializes the default configuration for the specified communication
1956 * True if the device was found and the defaults set, false otherwise
1958 BOOL WINAPI SetDefaultCommConfigA(
1959 LPCSTR lpszDevice, /* [in] The ascii name of the device targeted for configuration. */
1960 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1961 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
1963 FARPROC lpfnSetDefaultCommConfig;
1964 HMODULE hConfigModule;
1967 TRACE("(%p %p %lx)\n",lpszDevice, lpCommConfig, dwSize);
1969 hConfigModule = LoadLibraryA(lpszSerialUI);
1973 lpfnSetDefaultCommConfig = GetProcAddress(hConfigModule, (LPCSTR)4L);
1975 if(! lpfnSetDefaultCommConfig)
1978 r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize);
1980 /* UnloadLibrary(hConfigModule); */
1986 /***********************************************************************
1987 * SetDefaultCommConfigW (KERNEL32.@)
1989 * Initializes the default configuration for the specified
1990 * communication device. (unicode)
1995 BOOL WINAPI SetDefaultCommConfigW(
1996 LPCWSTR lpszDevice, /* [in] The unicode name of the device targeted for configuration. */
1997 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1998 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
2003 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice),lpCommConfig,dwSize);
2005 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
2008 r = SetDefaultCommConfigA(lpDeviceA,lpCommConfig,dwSize);
2009 HeapFree( GetProcessHeap(), 0, lpDeviceA );
2014 /***********************************************************************
2015 * GetDefaultCommConfigA (KERNEL32.@)
2017 * Acquires the default configuration of the specified communication device. (unicode)
2021 * True on successful reading of the default configuration,
2022 * if the device is not found or the buffer is too small.
2024 BOOL WINAPI GetDefaultCommConfigA(
2025 LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */
2026 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
2027 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
2028 afterwards the number of bytes copied to the buffer or
2029 the needed size of the buffer. */
2031 LPDCB lpdcb = &(lpCC->dcb);
2034 if (strncasecmp(lpszName,"COM",3)) {
2035 ERR("not implemented for <%s>\n", lpszName);
2039 TRACE("(%s %p %ld)\n", lpszName, lpCC, *lpdwSize );
2040 if (*lpdwSize < sizeof(COMMCONFIG)) {
2041 *lpdwSize = sizeof(COMMCONFIG);
2045 *lpdwSize = sizeof(COMMCONFIG);
2047 lpCC->dwSize = sizeof(COMMCONFIG);
2049 lpCC->dwProviderSubType = PST_RS232;
2050 lpCC->dwProviderOffset = 0L;
2051 lpCC->dwProviderSize = 0L;
2053 sprintf( temp, "COM%c:38400,n,8,1", lpszName[3]);
2054 FIXME("setting %s as default\n", temp);
2056 return BuildCommDCBA( temp, lpdcb);
2059 /**************************************************************************
2060 * GetDefaultCommConfigW (KERNEL32.@)
2062 * Acquires the default configuration of the specified communication device. (unicode)
2066 * True on successful reading of the default configuration,
2067 * if the device is not found or the buffer is too small.
2069 BOOL WINAPI GetDefaultCommConfigW(
2070 LPCWSTR lpszName, /* [in] The unicode name of the device targeted for configuration. */
2071 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
2072 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
2073 afterwards the number of bytes copied to the buffer or
2074 the needed size of the buffer. */
2079 TRACE("(%p,%p,%ld)\n",lpszName,lpCC,*lpdwSize);
2080 lpszNameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName );
2083 ret=GetDefaultCommConfigA(lpszNameA,lpCC,lpdwSize);
2084 HeapFree( GetProcessHeap(), 0, lpszNameA );