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>
87 #define NONAMELESSUNION
88 #define NONAMELESSSTRUCT
92 #include "wine/server.h"
97 #include "wine/debug.h"
99 #ifdef HAVE_LINUX_SERIAL_H
100 #include <linux/serial.h>
103 WINE_DEFAULT_DEBUG_CHANNEL(comm);
105 /***********************************************************************
106 * Asynchronous I/O for asynchronous wait requests *
109 static DWORD commio_get_async_count (const async_private *ovp);
110 static void commio_async_cleanup (async_private *ovp);
112 static async_ops commio_async_ops =
114 commio_get_async_count, /* get_count */
115 NULL, /* call_completion */
116 commio_async_cleanup /* cleanup */
119 typedef struct async_commio
121 struct async_private async;
125 static DWORD commio_get_async_count (const struct async_private *ovp)
130 static void commio_async_cleanup (async_private *ovp)
132 HeapFree(GetProcessHeap(), 0, ovp );
135 /***********************************************************************/
137 #if !defined(TIOCINQ) && defined(FIONREAD)
138 #define TIOCINQ FIONREAD
141 static int COMM_WhackModem(int fd, unsigned int andy, unsigned int orrie)
144 unsigned int mstat, okay;
145 okay = ioctl(fd, TIOCMGET, &mstat);
146 if (okay) return okay;
147 if (andy) mstat &= andy;
149 return ioctl(fd, TIOCMSET, &mstat);
155 /***********************************************************************
156 * COMM_BuildOldCommDCB (Internal)
158 * Build a DCB using the old style settings string eg: "COMx:96,n,8,1"
159 * We ignore the COM port index, since we can support more than 4 ports.
161 BOOL WINAPI COMM_BuildOldCommDCB(LPCSTR device, LPDCB lpdcb)
163 /* "COM1:96,n,8,1" */
165 char *ptr, temp[256], last;
168 TRACE("(%s), ptr %p\n", device, lpdcb);
170 /* Some applications call this function with "9600,n,8,1"
171 * not sending the "COM1:" parameter at left of string */
172 if (!strncasecmp(device,"COM",3))
174 if (!device[3]) return FALSE;
175 if (device[4] != ':' && device[4] != ' ') return FALSE;
176 strcpy(temp,device+5);
178 else strcpy(temp,device);
180 last=temp[strlen(temp)-1];
181 ptr = strtok(temp, ", ");
183 /* DOS/Windows only compares the first two numbers
184 * and assigns an appropriate baud rate.
185 * You can supply 961324245, it still returns 9600 ! */
188 WARN("Unknown baudrate string '%s' !\n", ptr);
189 return FALSE; /* error: less than 2 chars */
210 WARN("Unknown baudrate indicator %d !\n", rate);
214 lpdcb->BaudRate = rate;
215 TRACE("baudrate (%ld)\n", lpdcb->BaudRate);
217 ptr = strtok(NULL, ", ");
219 *ptr = toupper(*ptr);
221 TRACE("parity (%c)\n", *ptr);
222 lpdcb->fParity = TRUE;
225 lpdcb->Parity = NOPARITY;
226 lpdcb->fParity = FALSE;
229 lpdcb->Parity = EVENPARITY;
232 lpdcb->Parity = MARKPARITY;
235 lpdcb->Parity = ODDPARITY;
238 lpdcb->Parity = SPACEPARITY;
241 WARN("Unknown parity `%c'!\n", *ptr);
245 ptr = strtok(NULL, ", ");
246 TRACE("charsize (%c)\n", *ptr);
247 lpdcb->ByteSize = *ptr - '0';
249 ptr = strtok(NULL, ", ");
250 TRACE("stopbits (%c)\n", *ptr);
253 lpdcb->StopBits = ONESTOPBIT;
256 lpdcb->StopBits = TWOSTOPBITS;
259 WARN("Unknown # of stopbits `%c'!\n", *ptr);
266 lpdcb->fOutxCtsFlow = FALSE;
267 lpdcb->fOutxDsrFlow = FALSE;
268 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
269 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
270 } else if (last=='p') {
272 lpdcb->fOutX = FALSE;
273 lpdcb->fOutxCtsFlow = TRUE;
274 lpdcb->fOutxDsrFlow = FALSE;
275 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
276 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
279 lpdcb->fOutX = FALSE;
280 lpdcb->fOutxCtsFlow = FALSE;
281 lpdcb->fOutxDsrFlow = FALSE;
282 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
283 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
289 /**************************************************************************
290 * BuildCommDCBA (KERNEL32.@)
292 * Updates a device control block data structure with values from an
293 * ascii device control string. The device control string has two forms
294 * normal and extended, it must be exclusively in one or the other form.
298 * True on success, false on a malformed control string.
300 BOOL WINAPI BuildCommDCBA(
301 LPCSTR device, /* [in] The ascii device control string used to update the DCB. */
302 LPDCB lpdcb) /* [out] The device control block to be updated. */
304 return BuildCommDCBAndTimeoutsA(device,lpdcb,NULL);
307 /**************************************************************************
308 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
310 * Updates a device control block data structure with values from an
311 * ascii device control string. Taking timeout values from a timeouts
312 * struct if desired by the control string.
316 * True on success, false bad handles etc
318 BOOL WINAPI BuildCommDCBAndTimeoutsA(
319 LPCSTR device, /* [in] The ascii device control string. */
320 LPDCB lpdcb, /* [out] The device control block to be updated. */
321 LPCOMMTIMEOUTS lptimeouts) /* [in] The timeouts to use if asked to set them by the control string. */
326 TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts);
328 if (!strncasecmp(device,"COM",3)) {
331 ERR("BUG! COM0 can't exist!\n");
334 if ((*(device+4)!=':') && (*(device+4)!=' '))
336 temp=(LPSTR)(device+5);
340 memset(lpdcb,0,sizeof (DCB));
341 lpdcb->DCBlength = sizeof(DCB);
342 if (strchr(temp,',')) { /* old style */
344 return COMM_BuildOldCommDCB(device,lpdcb);
346 ptr=strtok(temp," ");
351 if (!strncasecmp("baud=",ptr,5)) {
352 if (!sscanf(ptr+5,"%ld",&x))
353 WARN("Couldn't parse %s\n",ptr);
357 if (!strncasecmp("stop=",ptr,5)) {
358 if (!sscanf(ptr+5,"%ld",&x))
359 WARN("Couldn't parse %s\n",ptr);
363 if (!strncasecmp("data=",ptr,5)) {
364 if (!sscanf(ptr+5,"%ld",&x))
365 WARN("Couldn't parse %s\n",ptr);
369 if (!strncasecmp("parity=",ptr,7)) {
370 lpdcb->fParity = TRUE;
373 lpdcb->fParity = FALSE;
374 lpdcb->Parity = NOPARITY;
377 lpdcb->Parity = EVENPARITY;
380 lpdcb->Parity = ODDPARITY;
383 lpdcb->Parity = MARKPARITY;
386 lpdcb->Parity = SPACEPARITY;
392 ERR("Unhandled specifier '%s', please report.\n",ptr);
393 ptr=strtok(NULL," ");
395 if (lpdcb->BaudRate==110)
400 /**************************************************************************
401 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
403 * Updates a device control block data structure with values from an
404 * unicode device control string. Taking timeout values from a timeouts
405 * struct if desired by the control string.
409 * True on success, false bad handles etc.
411 BOOL WINAPI BuildCommDCBAndTimeoutsW(
412 LPCWSTR devid, /* [in] The unicode device control string. */
413 LPDCB lpdcb, /* [out] The device control block to be updated. */
414 LPCOMMTIMEOUTS lptimeouts) /* [in] The timeouts to use if asked to set them by the control string. */
419 TRACE("(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
420 devidA = HEAP_strdupWtoA( GetProcessHeap(), 0, devid );
423 ret=BuildCommDCBAndTimeoutsA(devidA,lpdcb,lptimeouts);
424 HeapFree( GetProcessHeap(), 0, devidA );
429 /**************************************************************************
430 * BuildCommDCBW (KERNEL32.@)
432 * Updates a device control block structure with values from an
433 * unicode device control string. The device control string has two forms
434 * normal and extended, it must be exclusively in one or the other form.
438 * True on success, false on an malformed control string.
440 BOOL WINAPI BuildCommDCBW(
441 LPCWSTR devid, /* [in] The unicode device control string. */
442 LPDCB lpdcb) /* [out] The device control block to be updated. */
444 return BuildCommDCBAndTimeoutsW(devid,lpdcb,NULL);
447 static BOOL COMM_SetCommError(HANDLE handle, DWORD error)
451 SERVER_START_REQ( set_serial_info )
453 req->handle = handle;
454 req->flags = SERIALINFO_SET_ERROR;
455 req->commerror = error;
456 ret = !wine_server_call_err( req );
462 static BOOL COMM_GetCommError(HANDLE handle, LPDWORD lperror)
469 SERVER_START_REQ( get_serial_info )
471 req->handle = handle;
472 ret = !wine_server_call_err( req );
473 *lperror = reply->commerror;
480 /*****************************************************************************
481 * SetCommBreak (KERNEL32.@)
483 * Halts the transmission of characters to a communications device.
487 * True on success, and false if the communications device could not be found,
488 * the control is not supported.
492 * Only TIOCSBRK and TIOCCBRK are supported.
494 BOOL WINAPI SetCommBreak(
495 HANDLE handle) /* [in] The communictions device to suspend. */
497 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
500 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
502 TRACE("FILE_GetUnixHandle failed\n");
505 result = ioctl(fd,TIOCSBRK,0);
509 TRACE("ioctl failed\n");
510 SetLastError(ERROR_NOT_SUPPORTED);
515 FIXME("ioctl not available\n");
516 SetLastError(ERROR_NOT_SUPPORTED);
521 /*****************************************************************************
522 * ClearCommBreak (KERNEL32.@)
524 * Resumes character transmission from a communication device.
528 * True on success and false if the communications device could not be found.
532 * Only TIOCSBRK and TIOCCBRK are supported.
534 BOOL WINAPI ClearCommBreak(
535 HANDLE handle) /* [in] The halted communication device whose character transmission is to be resumed. */
537 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
540 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
542 TRACE("FILE_GetUnixHandle failed\n");
545 result = ioctl(fd,TIOCCBRK,0);
549 TRACE("ioctl failed\n");
550 SetLastError(ERROR_NOT_SUPPORTED);
555 FIXME("ioctl not available\n");
556 SetLastError(ERROR_NOT_SUPPORTED);
561 /*****************************************************************************
562 * EscapeCommFunction (KERNEL32.@)
564 * Directs a communication device to perform an extended function.
568 * True or requested data on successful completion of the command,
569 * false if the device is not present cannot execute the command
570 * or the command failed.
572 BOOL WINAPI EscapeCommFunction(
573 HANDLE handle, /* [in] The communication device to perform the extended function. */
574 UINT nFunction) /* [in] The extended function to be performed. */
576 int fd,direct=FALSE,result=FALSE;
579 TRACE("handle %p, function=%d\n", handle, nFunction);
580 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
582 FIXME("handle %p not found.\n",handle);
586 if (tcgetattr(fd,&port) == -1) {
587 COMM_SetCommError(handle,CE_IOE);
601 result= COMM_WhackModem(fd, ~TIOCM_DTR, 0);
609 result= COMM_WhackModem(fd, ~TIOCM_RTS, 0);
617 result= COMM_WhackModem(fd, 0, TIOCM_DTR);
625 result= COMM_WhackModem(fd, 0, TIOCM_RTS);
631 port.c_iflag |= IXOFF;
636 port.c_iflag |= IXON;
642 result = ioctl(fd,TIOCSBRK,0);
649 result = ioctl(fd,TIOCCBRK,0);
653 WARN("(handle=%p,nFunction=%d): Unknown function\n",
659 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
661 COMM_SetCommError(handle,CE_IOE);
670 COMM_SetCommError(handle,CE_IOE);
679 /********************************************************************
680 * PurgeComm (KERNEL32.@)
682 * Terminates pending operations and/or discards buffers on a
683 * communication resource.
687 * True on success and false if the communications handle is bad.
689 BOOL WINAPI PurgeComm(
690 HANDLE handle, /* [in] The communication resource to be purged. */
691 DWORD flags) /* [in] Flags for clear pending/buffer on input/output. */
695 TRACE("handle %p, flags %lx\n", handle, flags);
697 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
699 FIXME("no handle %p found\n",handle);
704 ** not exactly sure how these are different
705 ** Perhaps if we had our own internal queues, one flushes them
706 ** and the other flushes the kernel's buffers.
708 if(flags&PURGE_TXABORT)
709 tcflush(fd,TCOFLUSH);
710 if(flags&PURGE_RXABORT)
711 tcflush(fd,TCIFLUSH);
712 if(flags&PURGE_TXCLEAR)
713 tcflush(fd,TCOFLUSH);
714 if(flags&PURGE_RXCLEAR)
715 tcflush(fd,TCIFLUSH);
721 /*****************************************************************************
722 * ClearCommError (KERNEL32.@)
724 * Enables further I/O operations on a communications resource after
725 * supplying error and current status information.
729 * True on success, false if the communication resource handle is bad.
731 BOOL WINAPI ClearCommError(
732 HANDLE handle, /* [in] The communication resource with the error. */
733 LPDWORD errors, /* [out] Flags indicating error the resource experienced. */
734 LPCOMSTAT lpStat) /* [out] The status of the communication resource. */
738 fd=FILE_GetUnixHandle( handle, GENERIC_READ );
741 FIXME("no handle %p found\n",handle);
747 lpStat->fCtsHold = 0;
748 lpStat->fDsrHold = 0;
749 lpStat->fRlsdHold = 0;
750 lpStat->fXoffHold = 0;
751 lpStat->fXoffSent = 0;
754 lpStat->fReserved = 0;
757 if(ioctl(fd, TIOCOUTQ, &lpStat->cbOutQue))
758 WARN("ioctl returned error\n");
760 lpStat->cbOutQue = 0; /* FIXME: find a different way to find out */
764 if(ioctl(fd, TIOCINQ, &lpStat->cbInQue))
765 WARN("ioctl returned error\n");
768 TRACE("handle %p cbInQue = %ld cbOutQue = %ld\n",
769 handle, lpStat->cbInQue, lpStat->cbOutQue);
774 COMM_GetCommError(handle, errors);
775 COMM_SetCommError(handle, 0);
780 /*****************************************************************************
781 * SetupComm (KERNEL32.@)
783 * Called after CreateFile to hint to the communication resource to use
784 * specified sizes for input and output buffers rather than the default values.
788 * True if successful, false if the communications resource handle is bad.
794 BOOL WINAPI SetupComm(
795 HANDLE handle, /* [in] The just created communication resource handle. */
796 DWORD insize, /* [in] The suggested size of the communication resources input buffer in bytes. */
797 DWORD outsize) /* [in] The suggested size of the communication resources output buffer in bytes. */
801 FIXME("insize %ld outsize %ld unimplemented stub\n", insize, outsize);
802 fd=FILE_GetUnixHandle( handle, GENERIC_READ );
804 FIXME("handle %p not found?\n",handle);
811 /*****************************************************************************
812 * GetCommMask (KERNEL32.@)
814 * Obtain the events associated with a communication device that will cause
815 * a call WaitCommEvent to return.
819 * True on success, fail on bad device handle etc.
821 BOOL WINAPI GetCommMask(
822 HANDLE handle, /* [in] The communications device. */
823 LPDWORD evtmask) /* [out] The events which cause WaitCommEvent to return. */
827 TRACE("handle %p, mask %p\n", handle, evtmask);
829 SERVER_START_REQ( get_serial_info )
831 req->handle = handle;
832 if ((ret = !wine_server_call_err( req )))
834 if (evtmask) *evtmask = reply->eventmask;
841 /*****************************************************************************
842 * SetCommMask (KERNEL32.@)
844 * There be some things we need to hear about yon there communications device.
845 * (Set which events associated with a communication device should cause
846 * a call WaitCommEvent to return.)
850 * True on success, false on bad handle etc.
852 BOOL WINAPI SetCommMask(
853 HANDLE handle, /* [in] The communications device. */
854 DWORD evtmask) /* [in] The events that are to be monitored. */
858 TRACE("handle %p, mask %lx\n", handle, evtmask);
860 SERVER_START_REQ( set_serial_info )
862 req->handle = handle;
863 req->flags = SERIALINFO_SET_MASK;
864 req->eventmask = evtmask;
865 ret = !wine_server_call_err( req );
871 /*****************************************************************************
872 * SetCommState (KERNEL32.@)
874 * Re-initializes all hardware and control settings of a communications device,
875 * with values from a device control block without effecting the input and output
880 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
882 BOOL WINAPI SetCommState(
883 HANDLE handle, /* [in] The communications device. */
884 LPDCB lpdcb) /* [out] The device control block. */
887 int fd, bytesize, stopbits;
889 TRACE("handle %p, ptr %p\n", handle, lpdcb);
890 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
891 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
892 (lpdcb->StopBits == ONESTOPBIT)?1:
893 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
894 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
895 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
897 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
899 FIXME("no handle %p found\n",handle);
903 if ((tcgetattr(fd,&port)) == -1) {
904 int save_error = errno;
905 COMM_SetCommError(handle,CE_IOE);
907 ERR("tcgetattr error '%s'\n", strerror(save_error));
912 port.c_cc[VTIME] = 1;
915 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
917 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
919 port.c_iflag |= (IGNBRK);
921 port.c_oflag &= ~(OPOST);
923 port.c_cflag &= ~(HUPCL);
924 port.c_cflag |= CLOCAL | CREAD;
926 port.c_lflag &= ~(ICANON|ECHO|ISIG);
927 port.c_lflag |= NOFLSH;
930 port.c_cflag &= ~CBAUD;
931 switch (lpdcb->BaudRate) {
934 port.c_cflag |= B110;
938 port.c_cflag |= B300;
942 port.c_cflag |= B600;
946 port.c_cflag |= B1200;
950 port.c_cflag |= B2400;
954 port.c_cflag |= B4800;
958 port.c_cflag |= B9600;
962 port.c_cflag |= B19200;
966 port.c_cflag |= B38400;
970 port.c_cflag |= B57600;
975 port.c_cflag |= B115200;
980 port.c_cflag |= B230400;
985 port.c_cflag |= B460800;
989 #if defined (HAVE_LINUX_SERIAL_H) && defined (TIOCSSERIAL)
990 { struct serial_struct nuts;
992 ioctl(fd, TIOCGSERIAL, &nuts);
993 nuts.custom_divisor = nuts.baud_base / lpdcb->BaudRate;
994 if (!(nuts.custom_divisor)) nuts.custom_divisor = 1;
995 arby = nuts.baud_base / nuts.custom_divisor;
996 nuts.flags &= ~ASYNC_SPD_MASK;
997 nuts.flags |= ASYNC_SPD_CUST;
998 WARN("You (or a program acting at your behest) have specified\n"
999 "a non-standard baud rate %ld. Wine will set the rate to %d,\n"
1000 "which is as close as we can get by our present understanding of your\n"
1001 "hardware. I hope you know what you are doing. Any disruption Wine\n"
1002 "has caused to your linux system can be undone with setserial \n"
1003 "(see man setserial). If you have incapacitated a Hayes type modem,\n"
1004 "reset it and it will probably recover.\n", lpdcb->BaudRate, arby);
1005 ioctl(fd, TIOCSSERIAL, &nuts);
1006 port.c_cflag |= B38400;
1009 #endif /* Don't have linux/serial.h or lack TIOCSSERIAL */
1012 COMM_SetCommError(handle,IE_BAUDRATE);
1014 ERR("baudrate %ld\n",lpdcb->BaudRate);
1017 #elif !defined(__EMX__)
1018 switch (lpdcb->BaudRate) {
1021 port.c_ospeed = B110;
1025 port.c_ospeed = B300;
1029 port.c_ospeed = B600;
1033 port.c_ospeed = B1200;
1037 port.c_ospeed = B2400;
1041 port.c_ospeed = B4800;
1045 port.c_ospeed = B9600;
1049 port.c_ospeed = B19200;
1053 port.c_ospeed = B38400;
1058 port.c_cflag |= B57600;
1064 port.c_cflag |= B115200;
1069 port.c_cflag |= B230400;
1074 port.c_cflag |= B460800;
1078 COMM_SetCommError(handle,IE_BAUDRATE);
1080 ERR("baudrate %ld\n",lpdcb->BaudRate);
1083 port.c_ispeed = port.c_ospeed;
1085 bytesize=lpdcb->ByteSize;
1086 stopbits=lpdcb->StopBits;
1089 port.c_cflag &= ~(PARENB | PARODD | CMSPAR);
1091 port.c_cflag &= ~(PARENB | PARODD);
1094 port.c_iflag |= INPCK;
1096 port.c_iflag &= ~INPCK;
1097 switch (lpdcb->Parity) {
1101 port.c_cflag |= (PARENB | PARODD);
1104 port.c_cflag |= PARENB;
1107 /* Linux defines mark/space (stick) parity */
1109 port.c_cflag |= (PARENB | CMSPAR);
1112 port.c_cflag |= (PARENB | PARODD | CMSPAR);
1115 /* try the POSIX way */
1117 if( stopbits == ONESTOPBIT) {
1118 stopbits = TWOSTOPBITS;
1119 port.c_iflag &= ~INPCK;
1121 COMM_SetCommError(handle,IE_BYTESIZE);
1123 ERR("Cannot set MARK Parity\n");
1130 port.c_iflag &= ~INPCK;
1132 COMM_SetCommError(handle,IE_BYTESIZE);
1134 ERR("Cannot set SPACE Parity\n");
1140 COMM_SetCommError(handle,IE_BYTESIZE);
1147 port.c_cflag &= ~CSIZE;
1150 port.c_cflag |= CS5;
1153 port.c_cflag |= CS6;
1156 port.c_cflag |= CS7;
1159 port.c_cflag |= CS8;
1162 COMM_SetCommError(handle,IE_BYTESIZE);
1170 port.c_cflag &= ~CSTOPB;
1172 case ONE5STOPBITS: /* wil be selected if bytesize is 5 */
1174 port.c_cflag |= CSTOPB;
1177 COMM_SetCommError(handle,IE_BYTESIZE);
1183 if ( lpdcb->fOutxCtsFlow ||
1184 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1187 port.c_cflag |= CRTSCTS;
1192 if (lpdcb->fDtrControl == DTR_CONTROL_HANDSHAKE)
1194 WARN("DSR/DTR flow control not supported\n");
1198 port.c_iflag |= IXON;
1200 port.c_iflag &= ~IXON;
1202 port.c_iflag |= IXOFF;
1204 port.c_iflag &= ~IXOFF;
1206 if (tcsetattr(fd,TCSANOW,&port)==-1) { /* otherwise it hangs with pending input*/
1207 int save_error=errno;
1208 COMM_SetCommError(handle,CE_IOE);
1210 ERR("tcsetattr error '%s'\n", strerror(save_error));
1213 COMM_SetCommError(handle,0);
1220 /*****************************************************************************
1221 * GetCommState (KERNEL32.@)
1223 * Fills in a device control block with information from a communications device.
1227 * True on success, false if the communication device handle is bad etc
1231 * XonChar and XoffChar are not set.
1233 BOOL WINAPI GetCommState(
1234 HANDLE handle, /* [in] The communications device. */
1235 LPDCB lpdcb) /* [out] The device control block. */
1237 struct termios port;
1240 TRACE("handle %p, ptr %p\n", handle, lpdcb);
1242 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
1245 ERR("FILE_GetUnixHandle failed\n");
1248 if (tcgetattr(fd, &port) == -1) {
1249 int save_error=errno;
1250 ERR("tcgetattr error '%s'\n", strerror(save_error));
1251 COMM_SetCommError(handle,CE_IOE);
1258 speed= (port.c_cflag & CBAUD);
1260 speed= (cfgetospeed(&port));
1264 lpdcb->BaudRate = 110;
1267 lpdcb->BaudRate = 300;
1270 lpdcb->BaudRate = 600;
1273 lpdcb->BaudRate = 1200;
1276 lpdcb->BaudRate = 2400;
1279 lpdcb->BaudRate = 4800;
1282 lpdcb->BaudRate = 9600;
1285 lpdcb->BaudRate = 19200;
1288 lpdcb->BaudRate = 38400;
1292 lpdcb->BaudRate = 57600;
1297 lpdcb->BaudRate = 115200;
1302 lpdcb->BaudRate = 230400;
1307 lpdcb->BaudRate = 460800;
1311 ERR("unknown speed %x \n",speed);
1314 switch (port.c_cflag & CSIZE) {
1316 lpdcb->ByteSize = 5;
1319 lpdcb->ByteSize = 6;
1322 lpdcb->ByteSize = 7;
1325 lpdcb->ByteSize = 8;
1328 ERR("unknown size %x \n",port.c_cflag & CSIZE);
1331 if(port.c_iflag & INPCK)
1332 lpdcb->fParity = TRUE;
1334 lpdcb->fParity = FALSE;
1336 switch (port.c_cflag & (PARENB | PARODD | CMSPAR))
1338 switch (port.c_cflag & (PARENB | PARODD))
1342 lpdcb->Parity = NOPARITY;
1345 lpdcb->Parity = EVENPARITY;
1347 case (PARENB | PARODD):
1348 lpdcb->Parity = ODDPARITY;
1351 case (PARENB | CMSPAR):
1352 lpdcb->Parity = MARKPARITY;
1354 case (PARENB | PARODD | CMSPAR):
1355 lpdcb->Parity = SPACEPARITY;
1360 if (port.c_cflag & CSTOPB)
1361 if(lpdcb->ByteSize == 5)
1362 lpdcb->StopBits = ONE5STOPBITS;
1364 lpdcb->StopBits = TWOSTOPBITS;
1366 lpdcb->StopBits = ONESTOPBIT;
1371 /* termios does not support DTR/DSR flow control */
1372 lpdcb->fOutxDsrFlow = 0;
1373 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
1377 if (port.c_cflag & CRTSCTS) {
1378 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
1379 lpdcb->fOutxCtsFlow = 1;
1383 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
1384 lpdcb->fOutxCtsFlow = 0;
1386 if (port.c_iflag & IXON)
1391 if (port.c_iflag & IXOFF)
1400 lpdcb->XoffLim = 10;
1402 COMM_SetCommError(handle,0);
1406 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1407 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
1408 (lpdcb->StopBits == ONESTOPBIT)?1:
1409 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
1410 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
1411 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
1413 if ( lpdcb->fOutxCtsFlow ||
1414 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1419 TRACE("~CRTSCTS\n");
1425 /*****************************************************************************
1426 * TransmitCommChar (KERNEL32.@)
1428 * Transmits a single character in front of any pending characters in the
1429 * output buffer. Usually used to send an interrupt character to a host.
1433 * True if the call succeeded, false if the previous command character to the
1434 * same device has not been sent yet the handle is bad etc.
1440 BOOL WINAPI TransmitCommChar(
1441 HANDLE hComm, /* [in] The communication device in need of a command character. */
1442 CHAR chTransmit) /* [in] The character to transmit. */
1447 WARN("(%p,'%c') not perfect!\n",hComm,chTransmit);
1449 fd = FILE_GetUnixHandle( hComm, GENERIC_READ );
1451 SetLastError ( ERROR_INVALID_PARAMETER );
1454 r = (1 == write(fd, &chTransmit, 1));
1462 /*****************************************************************************
1463 * GetCommTimeouts (KERNEL32.@)
1465 * Obtains the request timeout values for the communications device.
1469 * True on success, false if communications device handle is bad
1470 * or the target structure is null.
1472 BOOL WINAPI GetCommTimeouts(
1473 HANDLE hComm, /* [in] The communications device. */
1474 LPCOMMTIMEOUTS lptimeouts) /* [out] The struct of request timeouts. */
1478 TRACE("(%p,%p)\n",hComm,lptimeouts);
1482 SetLastError(ERROR_INVALID_PARAMETER);
1486 SERVER_START_REQ( get_serial_info )
1488 req->handle = hComm;
1489 if ((ret = !wine_server_call_err( req )))
1491 lptimeouts->ReadIntervalTimeout = reply->readinterval;
1492 lptimeouts->ReadTotalTimeoutMultiplier = reply->readmult;
1493 lptimeouts->ReadTotalTimeoutConstant = reply->readconst;
1494 lptimeouts->WriteTotalTimeoutMultiplier = reply->writemult;
1495 lptimeouts->WriteTotalTimeoutConstant = reply->writeconst;
1502 /*****************************************************************************
1503 * SetCommTimeouts (KERNEL32.@)
1505 * Sets the timeouts used when reading and writing data to/from COMM ports.
1507 * ReadIntervalTimeout
1508 * - converted and passes to linux kernel as c_cc[VTIME]
1509 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1510 * - used in ReadFile to calculate GetOverlappedResult's timeout
1511 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1512 * - used in WriteFile to calculate GetOverlappedResult's timeout
1516 * True if the timeouts were set, false otherwise.
1518 BOOL WINAPI SetCommTimeouts(
1519 HANDLE hComm, /* [in] handle of COMM device */
1520 LPCOMMTIMEOUTS lptimeouts) /* [in] pointer to COMMTIMEOUTS structure */
1524 struct termios tios;
1526 TRACE("(%p,%p)\n",hComm,lptimeouts);
1530 SetLastError(ERROR_INVALID_PARAMETER);
1534 SERVER_START_REQ( set_serial_info )
1536 req->handle = hComm;
1537 req->flags = SERIALINFO_SET_TIMEOUTS;
1538 req->readinterval = lptimeouts->ReadIntervalTimeout ;
1539 req->readmult = lptimeouts->ReadTotalTimeoutMultiplier ;
1540 req->readconst = lptimeouts->ReadTotalTimeoutConstant ;
1541 req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ;
1542 req->writeconst = lptimeouts->WriteTotalTimeoutConstant ;
1543 ret = !wine_server_call_err( req );
1546 if (!ret) return FALSE;
1548 /* FIXME: move this stuff to the server */
1549 fd = FILE_GetUnixHandle( hComm, GENERIC_READ );
1551 FIXME("no fd for handle = %p!.\n",hComm);
1555 if (-1==tcgetattr(fd,&tios)) {
1556 FIXME("tcgetattr on fd %d failed!\n",fd);
1561 /* VTIME is in 1/10 seconds */
1563 unsigned int ux_timeout;
1565 if(lptimeouts->ReadIntervalTimeout == 0) /* 0 means no timeout */
1571 ux_timeout = (lptimeouts->ReadIntervalTimeout+99)/100;
1574 ux_timeout = 1; /* must be at least some timeout */
1577 tios.c_cc[VTIME] = ux_timeout;
1580 if (-1==tcsetattr(fd,0,&tios)) {
1581 FIXME("tcsetattr on fd %d failed!\n",fd);
1589 /***********************************************************************
1590 * GetCommModemStatus (KERNEL32.@)
1592 * Obtains the four control register bits if supported by the hardware.
1596 * True if the communications handle was good and for hardware that
1597 * control register access, false otherwise.
1599 BOOL WINAPI GetCommModemStatus(
1600 HANDLE hFile, /* [in] The communications device. */
1601 LPDWORD lpModemStat) /* [out] The control register bits. */
1603 int fd,mstat, result=FALSE;
1607 fd = FILE_GetUnixHandle( hFile, GENERIC_READ );
1610 result = ioctl(fd, TIOCMGET, &mstat);
1614 WARN("ioctl failed\n");
1618 if (mstat & TIOCM_CTS)
1619 *lpModemStat |= MS_CTS_ON;
1622 if (mstat & TIOCM_DSR)
1623 *lpModemStat |= MS_DSR_ON;
1626 if (mstat & TIOCM_RNG)
1627 *lpModemStat |= MS_RING_ON;
1630 /*FIXME: Not really sure about RLSD UB 990810*/
1631 if (mstat & TIOCM_CAR)
1632 *lpModemStat |= MS_RLSD_ON;
1634 TRACE("%04x -> %s%s%s%s\n", mstat,
1635 (*lpModemStat &MS_RLSD_ON)?"MS_RLSD_ON ":"",
1636 (*lpModemStat &MS_RING_ON)?"MS_RING_ON ":"",
1637 (*lpModemStat &MS_DSR_ON)?"MS_DSR_ON ":"",
1638 (*lpModemStat &MS_CTS_ON)?"MS_CTS_ON ":"");
1645 /***********************************************************************
1646 * COMM_WaitCommEventService (INTERNAL)
1648 * This function is called while the client is waiting on the
1649 * server, so we can't make any server calls here.
1651 static void COMM_WaitCommEventService(async_private *ovp)
1653 async_commio *commio = (async_commio*) ovp;
1654 IO_STATUS_BLOCK* iosb = commio->async.iosb;
1656 TRACE("iosb %p\n",iosb);
1658 /* FIXME: detect other events */
1659 *commio->buffer = EV_RXCHAR;
1661 iosb->u.Status = STATUS_SUCCESS;
1665 /***********************************************************************
1666 * COMM_WaitCommEvent (INTERNAL)
1668 * This function must have an lpOverlapped.
1670 static BOOL COMM_WaitCommEvent(
1671 HANDLE hFile, /* [in] handle of comm port to wait for */
1672 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1673 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1680 SetLastError(ERROR_INVALID_PARAMETER);
1684 if(NtResetEvent(lpOverlapped->hEvent,NULL))
1687 fd = FILE_GetUnixHandle( hFile, GENERIC_WRITE );
1691 ovp = (async_commio*) HeapAlloc(GetProcessHeap(), 0, sizeof (async_commio));
1698 ovp->async.ops = &commio_async_ops;
1699 ovp->async.handle = hFile;
1701 ovp->async.type = ASYNC_TYPE_WAIT;
1702 ovp->async.func = COMM_WaitCommEventService;
1703 ovp->async.event = lpOverlapped->hEvent;
1704 ovp->async.iosb = (IO_STATUS_BLOCK*)lpOverlapped;
1705 ovp->buffer = (char *)lpdwEvents;
1707 lpOverlapped->InternalHigh = 0;
1708 lpOverlapped->Offset = 0;
1709 lpOverlapped->OffsetHigh = 0;
1711 if ( !register_new_async (&ovp->async) )
1712 SetLastError( ERROR_IO_PENDING );
1717 /***********************************************************************
1718 * WaitCommEvent (KERNEL32.@)
1720 * Wait until something interesting happens on a COMM port.
1721 * Interesting things (events) are set by calling SetCommMask before
1722 * this function is called.
1725 * TRUE if successful
1728 * The set of detected events will be written to *lpdwEventMask
1729 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1732 * Only supports EV_RXCHAR and EV_TXEMPTY
1734 BOOL WINAPI WaitCommEvent(
1735 HANDLE hFile, /* [in] handle of comm port to wait for */
1736 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1737 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1742 TRACE("(%p %p %p )\n",hFile, lpdwEvents,lpOverlapped);
1745 return COMM_WaitCommEvent(hFile, lpdwEvents, lpOverlapped);
1747 /* if there is no overlapped structure, create our own */
1748 ov.hEvent = CreateEventA(NULL,FALSE,FALSE,NULL);
1750 COMM_WaitCommEvent(hFile, lpdwEvents, &ov);
1752 /* wait for the overlapped to complete */
1753 ret = GetOverlappedResult(hFile, &ov, NULL, TRUE);
1754 CloseHandle(ov.hEvent);
1759 /***********************************************************************
1760 * GetCommProperties (KERNEL32.@)
1762 * This function fills in a structure with the capabilities of the
1763 * communications port driver.
1767 * TRUE on success, FALSE on failure
1768 * If successful, the lpCommProp structure be filled in with
1769 * properties of the comm port.
1771 BOOL WINAPI GetCommProperties(
1772 HANDLE hFile, /* [in] handle of the comm port */
1773 LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */
1775 FIXME("(%p %p )\n",hFile,lpCommProp);
1780 * These values should be valid for LINUX's serial driver
1781 * FIXME: Perhaps they deserve an #ifdef LINUX
1783 memset(lpCommProp,0,sizeof(COMMPROP));
1784 lpCommProp->wPacketLength = 1;
1785 lpCommProp->wPacketVersion = 1;
1786 lpCommProp->dwServiceMask = SP_SERIALCOMM;
1787 lpCommProp->dwReserved1 = 0;
1788 lpCommProp->dwMaxTxQueue = 4096;
1789 lpCommProp->dwMaxRxQueue = 4096;
1790 lpCommProp->dwMaxBaud = BAUD_115200;
1791 lpCommProp->dwProvSubType = PST_RS232;
1792 lpCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS | PCF_TOTALTIMEOUTS;
1793 lpCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING |
1794 SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ;
1795 lpCommProp->dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 |
1796 BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
1797 BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ;
1798 lpCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ;
1799 lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
1800 PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE;
1801 lpCommProp->dwCurrentTxQueue = lpCommProp->dwMaxTxQueue;
1802 lpCommProp->dwCurrentRxQueue = lpCommProp->dwMaxRxQueue;
1807 /***********************************************************************
1809 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1810 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1811 * This is dependent on the type of COMM port, but since it is doubtful
1812 * anybody will get around to implementing support for fancy serial
1813 * ports in WINE, this is hardcoded for the time being. The name of
1814 * this DLL should be stored in and read from the system registry in
1815 * the hive HKEY_LOCAL_MACHINE, key
1816 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1817 * where ???? is the port number... that is determined by PNP
1818 * The DLL should be loaded when the COMM port is opened, and closed
1819 * when the COMM port is closed. - MJM 20 June 2000
1820 ***********************************************************************/
1821 static CHAR lpszSerialUI[] = "serialui.dll";
1824 /***********************************************************************
1825 * CommConfigDialogA (KERNEL32.@)
1827 * Raises a dialog that allows the user to configure a comm port.
1828 * Fills the COMMCONFIG struct with information specified by the user.
1829 * This function should call a similar routine in the COMM driver...
1833 * TRUE on success, FALSE on failure
1834 * If successful, the lpCommConfig structure will contain a new
1835 * configuration for the comm port, as specified by the user.
1838 * The library with the CommConfigDialog code is never unloaded.
1839 * Perhaps this should be done when the comm port is closed?
1841 BOOL WINAPI CommConfigDialogA(
1842 LPCSTR lpszDevice, /* [in] name of communications device */
1843 HANDLE hWnd, /* [in] parent window for the dialog */
1844 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1846 FARPROC lpfnCommDialog;
1847 HMODULE hConfigModule;
1850 TRACE("(%p %p %p)\n",lpszDevice, hWnd, lpCommConfig);
1852 hConfigModule = LoadLibraryA(lpszSerialUI);
1856 lpfnCommDialog = GetProcAddress(hConfigModule, (LPCSTR)3L);
1861 r = lpfnCommDialog(lpszDevice,hWnd,lpCommConfig);
1863 /* UnloadLibrary(hConfigModule); */
1868 /***********************************************************************
1869 * CommConfigDialogW (KERNEL32.@)
1871 * see CommConfigDialogA for more info
1873 BOOL WINAPI CommConfigDialogW(
1874 LPCWSTR lpszDevice, /* [in] name of communications device */
1875 HANDLE hWnd, /* [in] parent window for the dialog */
1876 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1881 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
1884 r = CommConfigDialogA(lpDeviceA,hWnd,lpCommConfig);
1885 HeapFree( GetProcessHeap(), 0, lpDeviceA );
1889 /***********************************************************************
1890 * GetCommConfig (KERNEL32.@)
1892 * Fill in the COMMCONFIG structure for the comm port hFile
1896 * TRUE on success, FALSE on failure
1897 * If successful, lpCommConfig contains the comm port configuration.
1902 BOOL WINAPI GetCommConfig(
1903 HANDLE hFile, /* [in] The communications device. */
1904 LPCOMMCONFIG lpCommConfig, /* [out] The communications configuration of the device (if it fits). */
1905 LPDWORD lpdwSize) /* [in/out] Initially the size of the configuration buffer/structure,
1906 afterwards the number of bytes copied to the buffer or
1907 the needed size of the buffer. */
1911 TRACE("(%p %p)\n",hFile,lpCommConfig);
1913 if(lpCommConfig == NULL)
1916 r = *lpdwSize < sizeof(COMMCONFIG);
1917 *lpdwSize = sizeof(COMMCONFIG);
1921 lpCommConfig->dwSize = sizeof(COMMCONFIG);
1922 lpCommConfig->wVersion = 1;
1923 lpCommConfig->wReserved = 0;
1924 r = GetCommState(hFile,&lpCommConfig->dcb);
1925 lpCommConfig->dwProviderSubType = PST_RS232;
1926 lpCommConfig->dwProviderOffset = 0;
1927 lpCommConfig->dwProviderSize = 0;
1932 /***********************************************************************
1933 * SetCommConfig (KERNEL32.@)
1935 * Sets the configuration of the communications device.
1939 * True on success, false if the handle was bad is not a communications device.
1941 BOOL WINAPI SetCommConfig(
1942 HANDLE hFile, /* [in] The communications device. */
1943 LPCOMMCONFIG lpCommConfig, /* [in] The desired configuration. */
1944 DWORD dwSize) /* [in] size of the lpCommConfig struct */
1946 TRACE("(%p %p)\n",hFile,lpCommConfig);
1947 return SetCommState(hFile,&lpCommConfig->dcb);
1950 /***********************************************************************
1951 * SetDefaultCommConfigA (KERNEL32.@)
1953 * Initializes the default configuration for the specified communication
1958 * True if the device was found and the defaults set, false otherwise
1960 BOOL WINAPI SetDefaultCommConfigA(
1961 LPCSTR lpszDevice, /* [in] The ascii name of the device targeted for configuration. */
1962 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1963 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
1965 FARPROC lpfnSetDefaultCommConfig;
1966 HMODULE hConfigModule;
1969 TRACE("(%p %p %lx)\n",lpszDevice, lpCommConfig, dwSize);
1971 hConfigModule = LoadLibraryA(lpszSerialUI);
1975 lpfnSetDefaultCommConfig = GetProcAddress(hConfigModule, (LPCSTR)4L);
1977 if(! lpfnSetDefaultCommConfig)
1980 r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize);
1982 /* UnloadLibrary(hConfigModule); */
1988 /***********************************************************************
1989 * SetDefaultCommConfigW (KERNEL32.@)
1991 * Initializes the default configuration for the specified
1992 * communication device. (unicode)
1997 BOOL WINAPI SetDefaultCommConfigW(
1998 LPCWSTR lpszDevice, /* [in] The unicode name of the device targeted for configuration. */
1999 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
2000 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
2005 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice),lpCommConfig,dwSize);
2007 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
2010 r = SetDefaultCommConfigA(lpDeviceA,lpCommConfig,dwSize);
2011 HeapFree( GetProcessHeap(), 0, lpDeviceA );
2016 /***********************************************************************
2017 * GetDefaultCommConfigA (KERNEL32.@)
2019 * Acquires the default configuration of the specified communication device. (unicode)
2023 * True on successful reading of the default configuration,
2024 * if the device is not found or the buffer is too small.
2026 BOOL WINAPI GetDefaultCommConfigA(
2027 LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */
2028 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
2029 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
2030 afterwards the number of bytes copied to the buffer or
2031 the needed size of the buffer. */
2033 LPDCB lpdcb = &(lpCC->dcb);
2036 if (strncasecmp(lpszName,"COM",3)) {
2037 ERR("not implemented for <%s>\n", lpszName);
2041 TRACE("(%s %p %ld)\n", lpszName, lpCC, *lpdwSize );
2042 if (*lpdwSize < sizeof(COMMCONFIG)) {
2043 *lpdwSize = sizeof(COMMCONFIG);
2047 *lpdwSize = sizeof(COMMCONFIG);
2049 lpCC->dwSize = sizeof(COMMCONFIG);
2051 lpCC->dwProviderSubType = PST_RS232;
2052 lpCC->dwProviderOffset = 0L;
2053 lpCC->dwProviderSize = 0L;
2055 sprintf( temp, "COM%c:38400,n,8,1", lpszName[3]);
2056 FIXME("setting %s as default\n", temp);
2058 return BuildCommDCBA( temp, lpdcb);
2061 /**************************************************************************
2062 * GetDefaultCommConfigW (KERNEL32.@)
2064 * Acquires the default configuration of the specified communication device. (unicode)
2068 * True on successful reading of the default configuration,
2069 * if the device is not found or the buffer is too small.
2071 BOOL WINAPI GetDefaultCommConfigW(
2072 LPCWSTR lpszName, /* [in] The unicode name of the device targeted for configuration. */
2073 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
2074 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
2075 afterwards the number of bytes copied to the buffer or
2076 the needed size of the buffer. */
2081 TRACE("(%p,%p,%ld)\n",lpszName,lpCC,*lpdwSize);
2082 lpszNameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName );
2085 ret=GetDefaultCommConfigA(lpszNameA,lpCC,lpdwSize);
2086 HeapFree( GetProcessHeap(), 0, lpszNameA );