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"
86 #include "wine/debug.h"
88 #ifdef HAVE_LINUX_SERIAL_H
89 #include <linux/serial.h>
92 WINE_DEFAULT_DEBUG_CHANNEL(comm);
94 #if !defined(TIOCINQ) && defined(FIONREAD)
95 #define TIOCINQ FIONREAD
98 static int COMM_WhackModem(int fd, unsigned int andy, unsigned int orrie)
100 unsigned int mstat, okay;
101 okay = ioctl(fd, TIOCMGET, &mstat);
102 if (okay) return okay;
103 if (andy) mstat &= andy;
105 return ioctl(fd, TIOCMSET, &mstat);
108 /***********************************************************************
109 * COMM_BuildOldCommDCB (Internal)
111 * Build a DCB using the old style settings string eg: "COMx:96,n,8,1"
112 * We ignore the COM port index, since we can support more than 4 ports.
114 BOOL WINAPI COMM_BuildOldCommDCB(LPCSTR device, LPDCB lpdcb)
116 /* "COM1:96,n,8,1" */
118 char *ptr, temp[256], last;
121 TRACE("(%s), ptr %p\n", device, lpdcb);
123 if (strncasecmp(device,"COM",3))
129 if ((*(device+4) != ':') && (*(device+4) != ' '))
132 strcpy(temp,device+5);
133 last=temp[strlen(temp)-1];
134 ptr = strtok(temp, ", ");
136 /* DOS/Windows only compares the first two numbers
137 * and assigns an appropriate baud rate.
138 * You can supply 961324245, it still returns 9600 ! */
141 WARN("Unknown baudrate string '%s' !\n", ptr);
142 return FALSE; /* error: less than 2 chars */
163 WARN("Unknown baudrate indicator %d !\n", rate);
167 lpdcb->BaudRate = rate;
168 TRACE("baudrate (%ld)\n", lpdcb->BaudRate);
170 ptr = strtok(NULL, ", ");
172 *ptr = toupper(*ptr);
174 TRACE("parity (%c)\n", *ptr);
175 lpdcb->fParity = TRUE;
178 lpdcb->Parity = NOPARITY;
179 lpdcb->fParity = FALSE;
182 lpdcb->Parity = EVENPARITY;
185 lpdcb->Parity = MARKPARITY;
188 lpdcb->Parity = ODDPARITY;
191 lpdcb->Parity = SPACEPARITY;
194 WARN("Unknown parity `%c'!\n", *ptr);
198 ptr = strtok(NULL, ", ");
199 TRACE("charsize (%c)\n", *ptr);
200 lpdcb->ByteSize = *ptr - '0';
202 ptr = strtok(NULL, ", ");
203 TRACE("stopbits (%c)\n", *ptr);
206 lpdcb->StopBits = ONESTOPBIT;
209 lpdcb->StopBits = TWOSTOPBITS;
212 WARN("Unknown # of stopbits `%c'!\n", *ptr);
219 lpdcb->fOutxCtsFlow = FALSE;
220 lpdcb->fOutxDsrFlow = FALSE;
221 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
222 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
223 } else if (last=='p') {
225 lpdcb->fOutX = FALSE;
226 lpdcb->fOutxCtsFlow = TRUE;
227 lpdcb->fOutxDsrFlow = FALSE;
228 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
229 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
232 lpdcb->fOutX = FALSE;
233 lpdcb->fOutxCtsFlow = FALSE;
234 lpdcb->fOutxDsrFlow = FALSE;
235 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
236 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
242 /**************************************************************************
243 * BuildCommDCBA (KERNEL32.@)
245 * Updates a device control block data structure with values from an
246 * ascii device control string. The device control string has two forms
247 * normal and extended, it must be exclusively in one or the other form.
251 * True on success, false on a malformed control string.
253 BOOL WINAPI BuildCommDCBA(
254 LPCSTR device, /* [in] The ascii device control string used to update the DCB. */
255 LPDCB lpdcb) /* [out] The device control block to be updated. */
257 return BuildCommDCBAndTimeoutsA(device,lpdcb,NULL);
260 /**************************************************************************
261 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
263 * Updates a device control block data structure with values from an
264 * ascii device control string. Taking timeout values from a timeouts
265 * struct if desired by the control string.
269 * True on success, false bad handles etc
271 BOOL WINAPI BuildCommDCBAndTimeoutsA(
272 LPCSTR device, /* [in] The ascii device control string. */
273 LPDCB lpdcb, /* [out] The device control block to be updated. */
274 LPCOMMTIMEOUTS lptimeouts) /* [in] The timeouts to use if asked to set them by the control string. */
279 TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts);
281 if (!strncasecmp(device,"COM",3)) {
284 ERR("BUG! COM0 can't exist!\n");
287 if ((*(device+4)!=':') && (*(device+4)!=' '))
289 temp=(LPSTR)(device+5);
293 memset(lpdcb,0,sizeof (DCB));
294 lpdcb->DCBlength = sizeof(DCB);
295 if (strchr(temp,',')) { /* old style */
297 return COMM_BuildOldCommDCB(device,lpdcb);
299 ptr=strtok(temp," ");
304 if (!strncmp("baud=",ptr,5)) {
305 if (!sscanf(ptr+5,"%ld",&x))
306 WARN("Couldn't parse %s\n",ptr);
310 if (!strncmp("stop=",ptr,5)) {
311 if (!sscanf(ptr+5,"%ld",&x))
312 WARN("Couldn't parse %s\n",ptr);
316 if (!strncmp("data=",ptr,5)) {
317 if (!sscanf(ptr+5,"%ld",&x))
318 WARN("Couldn't parse %s\n",ptr);
322 if (!strncmp("parity=",ptr,7)) {
323 lpdcb->fParity = TRUE;
326 lpdcb->fParity = FALSE;
327 lpdcb->Parity = NOPARITY;
330 lpdcb->Parity = EVENPARITY;
333 lpdcb->Parity = ODDPARITY;
336 lpdcb->Parity = MARKPARITY;
339 lpdcb->Parity = SPACEPARITY;
345 ERR("Unhandled specifier '%s', please report.\n",ptr);
346 ptr=strtok(NULL," ");
348 if (lpdcb->BaudRate==110)
353 /**************************************************************************
354 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
356 * Updates a device control block data structure with values from an
357 * unicode device control string. Taking timeout values from a timeouts
358 * struct if desired by the control string.
362 * True on success, false bad handles etc.
364 BOOL WINAPI BuildCommDCBAndTimeoutsW(
365 LPCWSTR devid, /* [in] The unicode device control string. */
366 LPDCB lpdcb, /* [out] The device control block to be updated. */
367 LPCOMMTIMEOUTS lptimeouts) /* [in] The timeouts to use if asked to set them by the control string. */
372 TRACE("(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
373 devidA = HEAP_strdupWtoA( GetProcessHeap(), 0, devid );
376 ret=BuildCommDCBAndTimeoutsA(devidA,lpdcb,lptimeouts);
377 HeapFree( GetProcessHeap(), 0, devidA );
382 /**************************************************************************
383 * BuildCommDCBW (KERNEL32.@)
385 * Updates a device control block structure with values from an
386 * unicode device control string. The device control string has two forms
387 * normal and extended, it must be exclusively in one or the other form.
391 * True on success, false on an malformed control string.
393 BOOL WINAPI BuildCommDCBW(
394 LPCWSTR devid, /* [in] The unicode device control string. */
395 LPDCB lpdcb) /* [out] The device control block to be updated. */
397 return BuildCommDCBAndTimeoutsW(devid,lpdcb,NULL);
400 static BOOL COMM_SetCommError(HANDLE handle, DWORD error)
404 SERVER_START_REQ( set_serial_info )
406 req->handle = handle;
407 req->flags = SERIALINFO_SET_ERROR;
408 req->commerror = error;
409 ret = !wine_server_call_err( req );
415 static BOOL COMM_GetCommError(HANDLE handle, LPDWORD lperror)
422 SERVER_START_REQ( get_serial_info )
424 req->handle = handle;
425 ret = !wine_server_call_err( req );
426 *lperror = reply->commerror;
433 /*****************************************************************************
434 * SetCommBreak (KERNEL32.@)
436 * Halts the transmission of characters to a communications device.
440 * True on success, and false if the communications device could not be found,
441 * the control is not supported.
445 * Only TIOCSBRK and TIOCCBRK are supported.
447 BOOL WINAPI SetCommBreak(
448 HANDLE handle) /* [in] The communictions device to suspend. */
450 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
453 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
455 TRACE("FILE_GetUnixHandle failed\n");
458 result = ioctl(fd,TIOCSBRK,0);
462 TRACE("ioctl failed\n");
463 SetLastError(ERROR_NOT_SUPPORTED);
468 FIXME("ioctl not available\n");
469 SetLastError(ERROR_NOT_SUPPORTED);
474 /*****************************************************************************
475 * ClearCommBreak (KERNEL32.@)
477 * Resumes character transmission from a communication device.
481 * True on success and false if the communications device could not be found.
485 * Only TIOCSBRK and TIOCCBRK are supported.
487 BOOL WINAPI ClearCommBreak(
488 HANDLE handle) /* [in] The halted communication device whose character transmission is to be resumed. */
490 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
493 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
495 TRACE("FILE_GetUnixHandle failed\n");
498 result = ioctl(fd,TIOCCBRK,0);
502 TRACE("ioctl failed\n");
503 SetLastError(ERROR_NOT_SUPPORTED);
508 FIXME("ioctl not available\n");
509 SetLastError(ERROR_NOT_SUPPORTED);
514 /*****************************************************************************
515 * EscapeCommFunction (KERNEL32.@)
517 * Directs a communication device to perform an extended function.
521 * True or requested data on successful completion of the command,
522 * false if the device is not present cannot execute the command
523 * or the command failed.
525 BOOL WINAPI EscapeCommFunction(
526 HANDLE handle, /* [in] The communication device to perform the extended function. */
527 UINT nFunction) /* [in] The extended function to be performed. */
529 int fd,direct=FALSE,result=FALSE;
532 TRACE("handle %d, function=%d\n", handle, nFunction);
533 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
535 FIXME("handle %d not found.\n",handle);
539 if (tcgetattr(fd,&port) == -1) {
540 COMM_SetCommError(handle,CE_IOE);
554 result= COMM_WhackModem(fd, ~TIOCM_DTR, 0);
562 result= COMM_WhackModem(fd, ~TIOCM_RTS, 0);
570 result= COMM_WhackModem(fd, 0, TIOCM_DTR);
578 result= COMM_WhackModem(fd, 0, TIOCM_RTS);
584 port.c_iflag |= IXOFF;
589 port.c_iflag |= IXON;
595 result = ioctl(fd,TIOCSBRK,0);
602 result = ioctl(fd,TIOCCBRK,0);
606 WARN("(handle=%d,nFunction=%d): Unknown function\n",
612 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
614 COMM_SetCommError(handle,CE_IOE);
623 COMM_SetCommError(handle,CE_IOE);
632 /********************************************************************
633 * PurgeComm (KERNEL32.@)
635 * Terminates pending operations and/or discards buffers on a
636 * communication resource.
640 * True on success and false if the communications handle is bad.
642 BOOL WINAPI PurgeComm(
643 HANDLE handle, /* [in] The communication resource to be purged. */
644 DWORD flags) /* [in] Flags for clear pending/buffer on input/output. */
648 TRACE("handle %d, flags %lx\n", handle, flags);
650 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
652 FIXME("no handle %d found\n",handle);
657 ** not exactly sure how these are different
658 ** Perhaps if we had our own internal queues, one flushes them
659 ** and the other flushes the kernel's buffers.
661 if(flags&PURGE_TXABORT)
662 tcflush(fd,TCOFLUSH);
663 if(flags&PURGE_RXABORT)
664 tcflush(fd,TCIFLUSH);
665 if(flags&PURGE_TXCLEAR)
666 tcflush(fd,TCOFLUSH);
667 if(flags&PURGE_RXCLEAR)
668 tcflush(fd,TCIFLUSH);
674 /*****************************************************************************
675 * ClearCommError (KERNEL32.@)
677 * Enables further I/O operations on a communications resource after
678 * supplying error and current status information.
682 * True on success, false if the communication resource handle is bad.
684 BOOL WINAPI ClearCommError(
685 HANDLE handle, /* [in] The communication resource with the error. */
686 LPDWORD errors, /* [out] Flags indicating error the resource experienced. */
687 LPCOMSTAT lpStat) /* [out] The status of the communication resource. */
691 fd=FILE_GetUnixHandle( handle, GENERIC_READ );
694 FIXME("no handle %d found\n",handle);
703 if(ioctl(fd, TIOCOUTQ, &lpStat->cbOutQue))
704 WARN("ioctl returned error\n");
706 lpStat->cbOutQue = 0; /* FIXME: find a different way to find out */
710 if(ioctl(fd, TIOCINQ, &lpStat->cbInQue))
711 WARN("ioctl returned error\n");
714 TRACE("handle %d cbInQue = %ld cbOutQue = %ld\n",
715 handle, lpStat->cbInQue, lpStat->cbOutQue);
720 COMM_GetCommError(handle, errors);
721 COMM_SetCommError(handle, 0);
726 /*****************************************************************************
727 * SetupComm (KERNEL32.@)
729 * Called after CreateFile to hint to the communication resource to use
730 * specified sizes for input and output buffers rather than the default values.
734 * True if successful, false if the communications resource handle is bad.
740 BOOL WINAPI SetupComm(
741 HANDLE handle, /* [in] The just created communication resource handle. */
742 DWORD insize, /* [in] The suggested size of the communication resources input buffer in bytes. */
743 DWORD outsize) /* [in] The suggested size of the communication resources output buffer in bytes. */
747 FIXME("insize %ld outsize %ld unimplemented stub\n", insize, outsize);
748 fd=FILE_GetUnixHandle( handle, GENERIC_READ );
750 FIXME("handle %d not found?\n",handle);
757 /*****************************************************************************
758 * GetCommMask (KERNEL32.@)
760 * Obtain the events associated with a communication device that will cause
761 * a call WaitCommEvent to return.
765 * True on success, fail on bad device handle etc.
767 BOOL WINAPI GetCommMask(
768 HANDLE handle, /* [in] The communications device. */
769 LPDWORD evtmask) /* [out] The events which cause WaitCommEvent to return. */
773 TRACE("handle %d, mask %p\n", handle, evtmask);
775 SERVER_START_REQ( get_serial_info )
777 req->handle = handle;
778 if ((ret = !wine_server_call_err( req )))
780 if (evtmask) *evtmask = reply->eventmask;
787 /*****************************************************************************
788 * SetCommMask (KERNEL32.@)
790 * There be some things we need to hear about yon there communications device.
791 * (Set which events associated with a communication device should cause
792 * a call WaitCommEvent to return.)
796 * True on success, false on bad handle etc.
798 BOOL WINAPI SetCommMask(
799 HANDLE handle, /* [in] The communications device. */
800 DWORD evtmask) /* [in] The events that are to be monitored. */
804 TRACE("handle %d, mask %lx\n", handle, evtmask);
806 SERVER_START_REQ( set_serial_info )
808 req->handle = handle;
809 req->flags = SERIALINFO_SET_MASK;
810 req->eventmask = evtmask;
811 ret = !wine_server_call_err( req );
817 /*****************************************************************************
818 * SetCommState (KERNEL32.@)
820 * Re-initializes all hardware and control settings of a communications device,
821 * with values from a device control block without effecting the input and output
826 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
828 BOOL WINAPI SetCommState(
829 HANDLE handle, /* [in] The communications device. */
830 LPDCB lpdcb) /* [out] The device control block. */
833 int fd, bytesize, stopbits;
835 TRACE("handle %d, ptr %p\n", handle, lpdcb);
836 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
837 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
838 (lpdcb->StopBits == ONESTOPBIT)?1:
839 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
840 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
841 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
843 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
845 FIXME("no handle %d found\n",handle);
849 if ((tcgetattr(fd,&port)) == -1) {
850 int save_error = errno;
851 COMM_SetCommError(handle,CE_IOE);
853 ERR("tcgetattr error '%s'\n", strerror(save_error));
858 port.c_cc[VTIME] = 1;
861 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
863 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
865 port.c_iflag |= (IGNBRK);
867 port.c_oflag &= ~(OPOST);
869 port.c_cflag &= ~(HUPCL);
870 port.c_cflag |= CLOCAL | CREAD;
872 port.c_lflag &= ~(ICANON|ECHO|ISIG);
873 port.c_lflag |= NOFLSH;
876 port.c_cflag &= ~CBAUD;
877 switch (lpdcb->BaudRate) {
880 port.c_cflag |= B110;
884 port.c_cflag |= B300;
888 port.c_cflag |= B600;
892 port.c_cflag |= B1200;
896 port.c_cflag |= B2400;
900 port.c_cflag |= B4800;
904 port.c_cflag |= B9600;
908 port.c_cflag |= B19200;
912 port.c_cflag |= B38400;
916 port.c_cflag |= B57600;
921 port.c_cflag |= B115200;
926 port.c_cflag |= B230400;
931 port.c_cflag |= B460800;
935 #if defined (HAVE_LINUX_SERIAL_H) && defined (TIOCSSERIAL)
936 { struct serial_struct nuts;
938 ioctl(fd, TIOCGSERIAL, &nuts);
939 nuts.custom_divisor = nuts.baud_base / lpdcb->BaudRate;
940 if (!(nuts.custom_divisor)) nuts.custom_divisor = 1;
941 arby = nuts.baud_base / nuts.custom_divisor;
942 nuts.flags &= ~ASYNC_SPD_MASK;
943 nuts.flags |= ASYNC_SPD_CUST;
944 WARN("You (or a program acting at your behest) have specified\n"
945 "a non-standard baud rate %ld. Wine will set the rate to %d,\n"
946 "which is as close as we can get by our present understanding of your\n"
947 "hardware. I hope you know what you are doing. Any disruption Wine\n"
948 "has caused to your linux system can be undone with setserial \n"
949 "(see man setserial). If you have incapacitated a Hayes type modem,\n"
950 "reset it and it will probably recover.\n", lpdcb->BaudRate, arby);
951 ioctl(fd, TIOCSSERIAL, &nuts);
952 port.c_cflag |= B38400;
955 #endif /* Don't have linux/serial.h or lack TIOCSSERIAL */
958 COMM_SetCommError(handle,IE_BAUDRATE);
960 ERR("baudrate %ld\n",lpdcb->BaudRate);
963 #elif !defined(__EMX__)
964 switch (lpdcb->BaudRate) {
967 port.c_ospeed = B110;
971 port.c_ospeed = B300;
975 port.c_ospeed = B600;
979 port.c_ospeed = B1200;
983 port.c_ospeed = B2400;
987 port.c_ospeed = B4800;
991 port.c_ospeed = B9600;
995 port.c_ospeed = B19200;
999 port.c_ospeed = B38400;
1002 COMM_SetCommError(handle,IE_BAUDRATE);
1004 ERR("baudrate %ld\n",lpdcb->BaudRate);
1007 port.c_ispeed = port.c_ospeed;
1009 bytesize=lpdcb->ByteSize;
1010 stopbits=lpdcb->StopBits;
1013 port.c_cflag &= ~(PARENB | PARODD | CMSPAR);
1015 port.c_cflag &= ~(PARENB | PARODD);
1018 port.c_iflag |= INPCK;
1020 port.c_iflag &= ~INPCK;
1021 switch (lpdcb->Parity) {
1025 port.c_cflag |= (PARENB | PARODD);
1028 port.c_cflag |= PARENB;
1031 /* Linux defines mark/space (stick) parity */
1033 port.c_cflag |= (PARENB | CMSPAR);
1036 port.c_cflag |= (PARENB | PARODD | CMSPAR);
1039 /* try the POSIX way */
1041 if( stopbits == ONESTOPBIT) {
1042 stopbits = TWOSTOPBITS;
1043 port.c_iflag &= ~INPCK;
1045 COMM_SetCommError(handle,IE_BYTESIZE);
1047 ERR("Cannot set MARK Parity\n");
1054 port.c_iflag &= ~INPCK;
1056 COMM_SetCommError(handle,IE_BYTESIZE);
1058 ERR("Cannot set SPACE Parity\n");
1064 COMM_SetCommError(handle,IE_BYTESIZE);
1071 port.c_cflag &= ~CSIZE;
1074 port.c_cflag |= CS5;
1077 port.c_cflag |= CS6;
1080 port.c_cflag |= CS7;
1083 port.c_cflag |= CS8;
1086 COMM_SetCommError(handle,IE_BYTESIZE);
1094 port.c_cflag &= ~CSTOPB;
1096 case ONE5STOPBITS: /* wil be selected if bytesize is 5 */
1098 port.c_cflag |= CSTOPB;
1101 COMM_SetCommError(handle,IE_BYTESIZE);
1107 if ( lpdcb->fOutxCtsFlow ||
1108 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1111 port.c_cflag |= CRTSCTS;
1116 if (lpdcb->fDtrControl == DTR_CONTROL_HANDSHAKE)
1118 WARN("DSR/DTR flow control not supported\n");
1122 port.c_iflag |= IXON;
1124 port.c_iflag &= ~IXON;
1126 port.c_iflag |= IXOFF;
1128 port.c_iflag &= ~IXOFF;
1130 if (tcsetattr(fd,TCSANOW,&port)==-1) { /* otherwise it hangs with pending input*/
1131 int save_error=errno;
1132 COMM_SetCommError(handle,CE_IOE);
1134 ERR("tcsetattr error '%s'\n", strerror(save_error));
1137 COMM_SetCommError(handle,0);
1144 /*****************************************************************************
1145 * GetCommState (KERNEL32.@)
1147 * Fills in a device control block with information from a communications device.
1151 * True on success, false if the communication device handle is bad etc
1155 * XonChar and XoffChar are not set.
1157 BOOL WINAPI GetCommState(
1158 HANDLE handle, /* [in] The communications device. */
1159 LPDCB lpdcb) /* [out] The device control block. */
1161 struct termios port;
1164 TRACE("handle %d, ptr %p\n", handle, lpdcb);
1166 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
1169 ERR("FILE_GetUnixHandle failed\n");
1172 if (tcgetattr(fd, &port) == -1) {
1173 int save_error=errno;
1174 ERR("tcgetattr error '%s'\n", strerror(save_error));
1175 COMM_SetCommError(handle,CE_IOE);
1182 speed= (port.c_cflag & CBAUD);
1184 speed= (cfgetospeed(&port));
1188 lpdcb->BaudRate = 110;
1191 lpdcb->BaudRate = 300;
1194 lpdcb->BaudRate = 600;
1197 lpdcb->BaudRate = 1200;
1200 lpdcb->BaudRate = 2400;
1203 lpdcb->BaudRate = 4800;
1206 lpdcb->BaudRate = 9600;
1209 lpdcb->BaudRate = 19200;
1212 lpdcb->BaudRate = 38400;
1216 lpdcb->BaudRate = 57600;
1221 lpdcb->BaudRate = 115200;
1226 lpdcb->BaudRate = 230400;
1231 lpdcb->BaudRate = 460800;
1235 ERR("unknown speed %x \n",speed);
1238 switch (port.c_cflag & CSIZE) {
1240 lpdcb->ByteSize = 5;
1243 lpdcb->ByteSize = 6;
1246 lpdcb->ByteSize = 7;
1249 lpdcb->ByteSize = 8;
1252 ERR("unknown size %x \n",port.c_cflag & CSIZE);
1255 if(port.c_iflag & INPCK)
1256 lpdcb->fParity = TRUE;
1258 lpdcb->fParity = FALSE;
1260 switch (port.c_cflag & (PARENB | PARODD | CMSPAR))
1262 switch (port.c_cflag & (PARENB | PARODD))
1266 lpdcb->Parity = NOPARITY;
1269 lpdcb->Parity = EVENPARITY;
1271 case (PARENB | PARODD):
1272 lpdcb->Parity = ODDPARITY;
1275 case (PARENB | CMSPAR):
1276 lpdcb->Parity = MARKPARITY;
1278 case (PARENB | PARODD | CMSPAR):
1279 lpdcb->Parity = SPACEPARITY;
1284 if (port.c_cflag & CSTOPB)
1285 if(lpdcb->ByteSize == 5)
1286 lpdcb->StopBits = ONE5STOPBITS;
1288 lpdcb->StopBits = TWOSTOPBITS;
1290 lpdcb->StopBits = ONESTOPBIT;
1295 /* termios does not support DTR/DSR flow control */
1296 lpdcb->fOutxDsrFlow = 0;
1297 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
1301 if (port.c_cflag & CRTSCTS) {
1302 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
1303 lpdcb->fOutxCtsFlow = 1;
1307 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
1308 lpdcb->fOutxCtsFlow = 0;
1310 if (port.c_iflag & IXON)
1315 if (port.c_iflag & IXOFF)
1324 lpdcb->XoffLim = 10;
1326 COMM_SetCommError(handle,0);
1330 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1331 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
1332 (lpdcb->StopBits == ONESTOPBIT)?1:
1333 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
1334 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
1335 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
1337 if ( lpdcb->fOutxCtsFlow ||
1338 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1343 TRACE("~CRTSCTS\n");
1349 /*****************************************************************************
1350 * TransmitCommChar (KERNEL32.@)
1352 * Transmits a single character in front of any pending characters in the
1353 * output buffer. Usually used to send an interrupt character to a host.
1357 * True if the call succeeded, false if the previous command character to the
1358 * same device has not been sent yet the handle is bad etc.
1364 BOOL WINAPI TransmitCommChar(
1365 HANDLE hComm, /* [in] The communication device in need of a command character. */
1366 CHAR chTransmit) /* [in] The character to transmit. */
1368 FIXME("(%x,'%c'), stub ! Use win32 handle!\n",hComm,chTransmit);
1372 /*****************************************************************************
1373 * GetCommTimeouts (KERNEL32.@)
1375 * Obtains the request timeout values for the communications device.
1379 * True on success, false if communications device handle is bad
1380 * or the target structure is null.
1382 BOOL WINAPI GetCommTimeouts(
1383 HANDLE hComm, /* [in] The communications device. */
1384 LPCOMMTIMEOUTS lptimeouts) /* [out] The struct of request timeouts. */
1388 TRACE("(%x,%p)\n",hComm,lptimeouts);
1392 SetLastError(ERROR_INVALID_PARAMETER);
1396 SERVER_START_REQ( get_serial_info )
1398 req->handle = hComm;
1399 if ((ret = !wine_server_call_err( req )))
1401 lptimeouts->ReadIntervalTimeout = reply->readinterval;
1402 lptimeouts->ReadTotalTimeoutMultiplier = reply->readmult;
1403 lptimeouts->ReadTotalTimeoutConstant = reply->readconst;
1404 lptimeouts->WriteTotalTimeoutMultiplier = reply->writemult;
1405 lptimeouts->WriteTotalTimeoutConstant = reply->writeconst;
1412 /*****************************************************************************
1413 * SetCommTimeouts (KERNEL32.@)
1415 * Sets the timeouts used when reading and writing data to/from COMM ports.
1417 * ReadIntervalTimeout
1418 * - converted and passes to linux kernel as c_cc[VTIME]
1419 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1420 * - used in ReadFile to calculate GetOverlappedResult's timeout
1421 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1422 * - used in WriteFile to calculate GetOverlappedResult's timeout
1426 * True if the timeouts were set, false otherwise.
1428 BOOL WINAPI SetCommTimeouts(
1429 HANDLE hComm, /* [in] handle of COMM device */
1430 LPCOMMTIMEOUTS lptimeouts) /* [in] pointer to COMMTIMEOUTS structure */
1434 struct termios tios;
1436 TRACE("(%x,%p)\n",hComm,lptimeouts);
1440 SetLastError(ERROR_INVALID_PARAMETER);
1444 SERVER_START_REQ( set_serial_info )
1446 req->handle = hComm;
1447 req->flags = SERIALINFO_SET_TIMEOUTS;
1448 req->readinterval = lptimeouts->ReadIntervalTimeout ;
1449 req->readmult = lptimeouts->ReadTotalTimeoutMultiplier ;
1450 req->readconst = lptimeouts->ReadTotalTimeoutConstant ;
1451 req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ;
1452 req->writeconst = lptimeouts->WriteTotalTimeoutConstant ;
1453 ret = !wine_server_call_err( req );
1456 if (!ret) return FALSE;
1458 /* FIXME: move this stuff to the server */
1459 fd = FILE_GetUnixHandle( hComm, GENERIC_READ );
1461 FIXME("no fd for handle = %0x!.\n",hComm);
1465 if (-1==tcgetattr(fd,&tios)) {
1466 FIXME("tcgetattr on fd %d failed!\n",fd);
1470 /* VTIME is in 1/10 seconds */
1472 unsigned int ux_timeout;
1474 if(lptimeouts->ReadIntervalTimeout == 0) /* 0 means no timeout */
1480 ux_timeout = (lptimeouts->ReadIntervalTimeout+99)/100;
1483 ux_timeout = 1; /* must be at least some timeout */
1486 tios.c_cc[VTIME] = ux_timeout;
1489 if (-1==tcsetattr(fd,0,&tios)) {
1490 FIXME("tcsetattr on fd %d failed!\n",fd);
1497 /***********************************************************************
1498 * GetCommModemStatus (KERNEL32.@)
1500 * Obtains the four control register bits if supported by the hardware.
1504 * True if the communications handle was good and for hardware that
1505 * control register access, false otherwise.
1507 BOOL WINAPI GetCommModemStatus(
1508 HANDLE hFile, /* [in] The communications device. */
1509 LPDWORD lpModemStat) /* [out] The control register bits. */
1511 int fd,mstat, result=FALSE;
1515 fd = FILE_GetUnixHandle( hFile, GENERIC_READ );
1518 result = ioctl(fd, TIOCMGET, &mstat);
1522 WARN("ioctl failed\n");
1526 if (mstat & TIOCM_CTS)
1527 *lpModemStat |= MS_CTS_ON;
1530 if (mstat & TIOCM_DSR)
1531 *lpModemStat |= MS_DSR_ON;
1534 if (mstat & TIOCM_RNG)
1535 *lpModemStat |= MS_RING_ON;
1538 /*FIXME: Not really sure about RLSD UB 990810*/
1539 if (mstat & TIOCM_CAR)
1540 *lpModemStat |= MS_RLSD_ON;
1542 TRACE("%04x -> %s%s%s%s\n", mstat,
1543 (*lpModemStat &MS_RLSD_ON)?"MS_RLSD_ON ":"",
1544 (*lpModemStat &MS_RING_ON)?"MS_RING_ON ":"",
1545 (*lpModemStat &MS_DSR_ON)?"MS_DSR_ON ":"",
1546 (*lpModemStat &MS_CTS_ON)?"MS_CTS_ON ":"");
1553 /***********************************************************************
1554 * COMM_WaitCommEventService (INTERNAL)
1556 * This function is called while the client is waiting on the
1557 * server, so we can't make any server calls here.
1559 static void COMM_WaitCommEventService(async_private *ovp)
1561 LPOVERLAPPED lpOverlapped = ovp->lpOverlapped;
1563 TRACE("overlapped %p\n",lpOverlapped);
1565 /* FIXME: detect other events */
1566 *ovp->buffer = EV_RXCHAR;
1568 lpOverlapped->Internal = STATUS_SUCCESS;
1572 /***********************************************************************
1573 * COMM_WaitCommEvent (INTERNAL)
1575 * This function must have an lpOverlapped.
1577 static BOOL COMM_WaitCommEvent(
1578 HANDLE hFile, /* [in] handle of comm port to wait for */
1579 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1580 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1587 SetLastError(ERROR_INVALID_PARAMETER);
1591 if(NtResetEvent(lpOverlapped->hEvent,NULL))
1594 lpOverlapped->Internal = STATUS_PENDING;
1595 lpOverlapped->InternalHigh = 0;
1596 lpOverlapped->Offset = 0;
1597 lpOverlapped->OffsetHigh = 0;
1599 fd = FILE_GetUnixHandle( hFile, GENERIC_WRITE );
1603 ovp = (async_private *) HeapAlloc(GetProcessHeap(), 0, sizeof (async_private));
1609 ovp->event = lpOverlapped->hEvent;
1610 ovp->lpOverlapped = lpOverlapped;
1611 ovp->func = COMM_WaitCommEventService;
1612 ovp->buffer = (char *)lpdwEvents;
1615 ovp->completion_func = 0;
1616 ovp->type = ASYNC_TYPE_WAIT;
1617 ovp->handle = hFile;
1619 ovp->next = NtCurrentTeb()->pending_list;
1622 ovp->next->prev=ovp;
1623 NtCurrentTeb()->pending_list = ovp;
1625 /* start an ASYNCHRONOUS WaitCommEvent */
1626 SERVER_START_REQ( register_async )
1628 req->handle = hFile;
1629 req->overlapped = lpOverlapped;
1630 req->type = ASYNC_TYPE_WAIT;
1632 req->func = check_async_list;
1633 req->status = STATUS_PENDING;
1635 ret=wine_server_call_err(req);
1640 SetLastError(ERROR_IO_PENDING);
1645 /***********************************************************************
1646 * WaitCommEvent (KERNEL32.@)
1648 * Wait until something interesting happens on a COMM port.
1649 * Interesting things (events) are set by calling SetCommMask before
1650 * this function is called.
1653 * TRUE if successful
1656 * The set of detected events will be written to *lpdwEventMask
1657 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1660 * Only supports EV_RXCHAR and EV_TXEMPTY
1662 BOOL WINAPI 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 */
1670 TRACE("(%x %p %p )\n",hFile, lpdwEvents,lpOverlapped);
1673 return COMM_WaitCommEvent(hFile, lpdwEvents, lpOverlapped);
1675 /* if there is no overlapped structure, create our own */
1676 ov.hEvent = CreateEventA(NULL,FALSE,FALSE,NULL);
1678 COMM_WaitCommEvent(hFile, lpdwEvents, &ov);
1680 if(GetLastError()!=STATUS_PENDING)
1682 CloseHandle(ov.hEvent);
1686 /* wait for the overlapped to complete */
1687 ret = GetOverlappedResult(hFile, &ov, NULL, TRUE);
1688 CloseHandle(ov.hEvent);
1693 /***********************************************************************
1694 * GetCommProperties (KERNEL32.@)
1696 * This function fills in a structure with the capabilities of the
1697 * communications port driver.
1701 * TRUE on success, FALSE on failure
1702 * If successful, the lpCommProp structure be filled in with
1703 * properties of the comm port.
1705 BOOL WINAPI GetCommProperties(
1706 HANDLE hFile, /* [in] handle of the comm port */
1707 LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */
1709 FIXME("(%d %p )\n",hFile,lpCommProp);
1714 * These values should be valid for LINUX's serial driver
1715 * FIXME: Perhaps they deserve an #ifdef LINUX
1717 memset(lpCommProp,0,sizeof(COMMPROP));
1718 lpCommProp->wPacketLength = 1;
1719 lpCommProp->wPacketVersion = 1;
1720 lpCommProp->dwServiceMask = SP_SERIALCOMM;
1721 lpCommProp->dwReserved1 = 0;
1722 lpCommProp->dwMaxTxQueue = 4096;
1723 lpCommProp->dwMaxRxQueue = 4096;
1724 lpCommProp->dwMaxBaud = BAUD_115200;
1725 lpCommProp->dwProvSubType = PST_RS232;
1726 lpCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS ;
1727 lpCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING |
1728 SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ;
1729 lpCommProp->dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 |
1730 BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
1731 BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ;
1732 lpCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ;
1733 lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
1734 PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE;
1735 lpCommProp->dwCurrentTxQueue = lpCommProp->dwMaxTxQueue;
1736 lpCommProp->dwCurrentRxQueue = lpCommProp->dwMaxRxQueue;
1741 /***********************************************************************
1743 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1744 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1745 * This is dependent on the type of COMM port, but since it is doubtful
1746 * anybody will get around to implementing support for fancy serial
1747 * ports in WINE, this is hardcoded for the time being. The name of
1748 * this DLL should be stored in and read from the system registry in
1749 * the hive HKEY_LOCAL_MACHINE, key
1750 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1751 * where ???? is the port number... that is determined by PNP
1752 * The DLL should be loaded when the COMM port is opened, and closed
1753 * when the COMM port is closed. - MJM 20 June 2000
1754 ***********************************************************************/
1755 static CHAR lpszSerialUI[] = "serialui.dll";
1758 /***********************************************************************
1759 * CommConfigDialogA (KERNEL32.@)
1761 * Raises a dialog that allows the user to configure a comm port.
1762 * Fills the COMMCONFIG struct with information specified by the user.
1763 * This function should call a similar routine in the COMM driver...
1767 * TRUE on success, FALSE on failure
1768 * If successful, the lpCommConfig structure will contain a new
1769 * configuration for the comm port, as specified by the user.
1772 * The library with the CommConfigDialog code is never unloaded.
1773 * Perhaps this should be done when the comm port is closed?
1775 BOOL WINAPI CommConfigDialogA(
1776 LPCSTR lpszDevice, /* [in] name of communications device */
1777 HANDLE hWnd, /* [in] parent window for the dialog */
1778 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1780 FARPROC lpfnCommDialog;
1781 HMODULE hConfigModule;
1784 TRACE("(%p %x %p)\n",lpszDevice, hWnd, lpCommConfig);
1786 hConfigModule = LoadLibraryA(lpszSerialUI);
1790 lpfnCommDialog = GetProcAddress(hConfigModule, (LPCSTR)3L);
1795 r = lpfnCommDialog(lpszDevice,hWnd,lpCommConfig);
1797 /* UnloadLibrary(hConfigModule); */
1802 /***********************************************************************
1803 * CommConfigDialogW (KERNEL32.@)
1805 * see CommConfigDialogA for more info
1807 BOOL WINAPI CommConfigDialogW(
1808 LPCWSTR lpszDevice, /* [in] name of communications device */
1809 HANDLE hWnd, /* [in] parent window for the dialog */
1810 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1815 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
1818 r = CommConfigDialogA(lpDeviceA,hWnd,lpCommConfig);
1819 HeapFree( GetProcessHeap(), 0, lpDeviceA );
1823 /***********************************************************************
1824 * GetCommConfig (KERNEL32.@)
1826 * Fill in the COMMCONFIG structure for the comm port hFile
1830 * TRUE on success, FALSE on failure
1831 * If successful, lpCommConfig contains the comm port configuration.
1836 BOOL WINAPI GetCommConfig(
1837 HANDLE hFile, /* [in] The communications device. */
1838 LPCOMMCONFIG lpCommConfig, /* [out] The communications configuration of the device (if it fits). */
1839 LPDWORD lpdwSize) /* [in/out] Initially the size of the configuration buffer/structure,
1840 afterwards the number of bytes copied to the buffer or
1841 the needed size of the buffer. */
1845 TRACE("(%x %p)\n",hFile,lpCommConfig);
1847 if(lpCommConfig == NULL)
1850 r = *lpdwSize < sizeof(COMMCONFIG);
1851 *lpdwSize = sizeof(COMMCONFIG);
1855 lpCommConfig->dwSize = sizeof(COMMCONFIG);
1856 lpCommConfig->wVersion = 1;
1857 lpCommConfig->wReserved = 0;
1858 r = GetCommState(hFile,&lpCommConfig->dcb);
1859 lpCommConfig->dwProviderSubType = PST_RS232;
1860 lpCommConfig->dwProviderOffset = 0;
1861 lpCommConfig->dwProviderSize = 0;
1866 /***********************************************************************
1867 * SetCommConfig (KERNEL32.@)
1869 * Sets the configuration of the communications device.
1873 * True on success, false if the handle was bad is not a communications device.
1875 BOOL WINAPI SetCommConfig(
1876 HANDLE hFile, /* [in] The communications device. */
1877 LPCOMMCONFIG lpCommConfig, /* [in] The desired configuration. */
1878 DWORD dwSize) /* [in] size of the lpCommConfig struct */
1880 TRACE("(%x %p)\n",hFile,lpCommConfig);
1881 return SetCommState(hFile,&lpCommConfig->dcb);
1884 /***********************************************************************
1885 * SetDefaultCommConfigA (KERNEL32.@)
1887 * Initializes the default configuration for the specified communication
1892 * True if the device was found and the defaults set, false otherwise
1894 BOOL WINAPI SetDefaultCommConfigA(
1895 LPCSTR lpszDevice, /* [in] The ascii name of the device targeted for configuration. */
1896 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1897 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
1899 FARPROC lpfnSetDefaultCommConfig;
1900 HMODULE hConfigModule;
1903 TRACE("(%p %p %lx)\n",lpszDevice, lpCommConfig, dwSize);
1905 hConfigModule = LoadLibraryA(lpszSerialUI);
1909 lpfnSetDefaultCommConfig = GetProcAddress(hConfigModule, (LPCSTR)4L);
1911 if(! lpfnSetDefaultCommConfig)
1914 r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize);
1916 /* UnloadLibrary(hConfigModule); */
1922 /***********************************************************************
1923 * SetDefaultCommConfigW (KERNEL32.@)
1925 * Initializes the default configuration for the specified
1926 * communication device. (unicode)
1931 BOOL WINAPI SetDefaultCommConfigW(
1932 LPCWSTR lpszDevice, /* [in] The unicode name of the device targeted for configuration. */
1933 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1934 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
1939 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice),lpCommConfig,dwSize);
1941 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
1944 r = SetDefaultCommConfigA(lpDeviceA,lpCommConfig,dwSize);
1945 HeapFree( GetProcessHeap(), 0, lpDeviceA );
1950 /***********************************************************************
1951 * GetDefaultCommConfigA (KERNEL32.@)
1953 * Acquires the default configuration of the specified communication device. (unicode)
1957 * True on successful reading of the default configuration,
1958 * if the device is not found or the buffer is too small.
1960 BOOL WINAPI GetDefaultCommConfigA(
1961 LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */
1962 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
1963 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
1964 afterwards the number of bytes copied to the buffer or
1965 the needed size of the buffer. */
1967 LPDCB lpdcb = &(lpCC->dcb);
1970 if (strncasecmp(lpszName,"COM",3)) {
1971 ERR("not implemented for <%s>\n", lpszName);
1975 TRACE("(%s %p %ld)\n", lpszName, lpCC, *lpdwSize );
1976 if (*lpdwSize < sizeof(COMMCONFIG)) {
1977 *lpdwSize = sizeof(COMMCONFIG);
1981 *lpdwSize = sizeof(COMMCONFIG);
1983 lpCC->dwSize = sizeof(COMMCONFIG);
1985 lpCC->dwProviderSubType = PST_RS232;
1986 lpCC->dwProviderOffset = 0L;
1987 lpCC->dwProviderSize = 0L;
1989 sprintf( temp, "COM%c:38400,n,8,1", lpszName[3]);
1990 FIXME("setting %s as default\n", temp);
1992 return BuildCommDCBA( temp, lpdcb);
1995 /**************************************************************************
1996 * GetDefaultCommConfigW (KERNEL32.@)
1998 * Acquires the default configuration of the specified communication device. (unicode)
2002 * True on successful reading of the default configuration,
2003 * if the device is not found or the buffer is too small.
2005 BOOL WINAPI GetDefaultCommConfigW(
2006 LPCWSTR lpszName, /* [in] The unicode name of the device targeted for configuration. */
2007 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
2008 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
2009 afterwards the number of bytes copied to the buffer or
2010 the needed size of the buffer. */
2015 TRACE("(%p,%p,%ld)\n",lpszName,lpCC,*lpdwSize);
2016 lpszNameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName );
2019 ret=GetDefaultCommConfigA(lpszNameA,lpCC,lpdwSize);
2020 HeapFree( GetProcessHeap(), 0, lpszNameA );