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 CALLBACK commio_call_completion_func (ULONG_PTR data);
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 commio_call_completion_func /* call_completion */
112 typedef struct async_commio
114 struct async_private async;
115 LPOVERLAPPED lpOverlapped;
119 static DWORD commio_get_async_status (const struct async_private *ovp)
121 return ((async_commio*) ovp)->lpOverlapped->Internal;
124 static void commio_set_async_status (async_private *ovp, const DWORD status)
126 ((async_commio*) ovp)->lpOverlapped->Internal = status;
129 static DWORD commio_get_async_count (const struct async_private *ovp)
134 static void CALLBACK commio_call_completion_func (ULONG_PTR data)
136 HeapFree(GetProcessHeap(), 0, (void*) data);
139 /***********************************************************************/
141 #if !defined(TIOCINQ) && defined(FIONREAD)
142 #define TIOCINQ FIONREAD
145 static int COMM_WhackModem(int fd, unsigned int andy, unsigned int orrie)
147 unsigned int mstat, okay;
148 okay = ioctl(fd, TIOCMGET, &mstat);
149 if (okay) return okay;
150 if (andy) mstat &= andy;
152 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 if (strncasecmp(device,"COM",3))
176 if ((*(device+4) != ':') && (*(device+4) != ' '))
179 strcpy(temp,device+5);
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 (!strncmp("baud=",ptr,5)) {
352 if (!sscanf(ptr+5,"%ld",&x))
353 WARN("Couldn't parse %s\n",ptr);
357 if (!strncmp("stop=",ptr,5)) {
358 if (!sscanf(ptr+5,"%ld",&x))
359 WARN("Couldn't parse %s\n",ptr);
363 if (!strncmp("data=",ptr,5)) {
364 if (!sscanf(ptr+5,"%ld",&x))
365 WARN("Couldn't parse %s\n",ptr);
369 if (!strncmp("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 %d, function=%d\n", handle, nFunction);
580 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
582 FIXME("handle %d 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=%d,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 %d, flags %lx\n", handle, flags);
697 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
699 FIXME("no handle %d 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 %d found\n",handle);
750 if(ioctl(fd, TIOCOUTQ, &lpStat->cbOutQue))
751 WARN("ioctl returned error\n");
753 lpStat->cbOutQue = 0; /* FIXME: find a different way to find out */
757 if(ioctl(fd, TIOCINQ, &lpStat->cbInQue))
758 WARN("ioctl returned error\n");
761 TRACE("handle %d cbInQue = %ld cbOutQue = %ld\n",
762 handle, lpStat->cbInQue, lpStat->cbOutQue);
767 COMM_GetCommError(handle, errors);
768 COMM_SetCommError(handle, 0);
773 /*****************************************************************************
774 * SetupComm (KERNEL32.@)
776 * Called after CreateFile to hint to the communication resource to use
777 * specified sizes for input and output buffers rather than the default values.
781 * True if successful, false if the communications resource handle is bad.
787 BOOL WINAPI SetupComm(
788 HANDLE handle, /* [in] The just created communication resource handle. */
789 DWORD insize, /* [in] The suggested size of the communication resources input buffer in bytes. */
790 DWORD outsize) /* [in] The suggested size of the communication resources output buffer in bytes. */
794 FIXME("insize %ld outsize %ld unimplemented stub\n", insize, outsize);
795 fd=FILE_GetUnixHandle( handle, GENERIC_READ );
797 FIXME("handle %d not found?\n",handle);
804 /*****************************************************************************
805 * GetCommMask (KERNEL32.@)
807 * Obtain the events associated with a communication device that will cause
808 * a call WaitCommEvent to return.
812 * True on success, fail on bad device handle etc.
814 BOOL WINAPI GetCommMask(
815 HANDLE handle, /* [in] The communications device. */
816 LPDWORD evtmask) /* [out] The events which cause WaitCommEvent to return. */
820 TRACE("handle %d, mask %p\n", handle, evtmask);
822 SERVER_START_REQ( get_serial_info )
824 req->handle = handle;
825 if ((ret = !wine_server_call_err( req )))
827 if (evtmask) *evtmask = reply->eventmask;
834 /*****************************************************************************
835 * SetCommMask (KERNEL32.@)
837 * There be some things we need to hear about yon there communications device.
838 * (Set which events associated with a communication device should cause
839 * a call WaitCommEvent to return.)
843 * True on success, false on bad handle etc.
845 BOOL WINAPI SetCommMask(
846 HANDLE handle, /* [in] The communications device. */
847 DWORD evtmask) /* [in] The events that are to be monitored. */
851 TRACE("handle %d, mask %lx\n", handle, evtmask);
853 SERVER_START_REQ( set_serial_info )
855 req->handle = handle;
856 req->flags = SERIALINFO_SET_MASK;
857 req->eventmask = evtmask;
858 ret = !wine_server_call_err( req );
864 /*****************************************************************************
865 * SetCommState (KERNEL32.@)
867 * Re-initializes all hardware and control settings of a communications device,
868 * with values from a device control block without effecting the input and output
873 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
875 BOOL WINAPI SetCommState(
876 HANDLE handle, /* [in] The communications device. */
877 LPDCB lpdcb) /* [out] The device control block. */
880 int fd, bytesize, stopbits;
882 TRACE("handle %d, ptr %p\n", handle, lpdcb);
883 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
884 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
885 (lpdcb->StopBits == ONESTOPBIT)?1:
886 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
887 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
888 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
890 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
892 FIXME("no handle %d found\n",handle);
896 if ((tcgetattr(fd,&port)) == -1) {
897 int save_error = errno;
898 COMM_SetCommError(handle,CE_IOE);
900 ERR("tcgetattr error '%s'\n", strerror(save_error));
905 port.c_cc[VTIME] = 1;
908 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
910 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
912 port.c_iflag |= (IGNBRK);
914 port.c_oflag &= ~(OPOST);
916 port.c_cflag &= ~(HUPCL);
917 port.c_cflag |= CLOCAL | CREAD;
919 port.c_lflag &= ~(ICANON|ECHO|ISIG);
920 port.c_lflag |= NOFLSH;
923 port.c_cflag &= ~CBAUD;
924 switch (lpdcb->BaudRate) {
927 port.c_cflag |= B110;
931 port.c_cflag |= B300;
935 port.c_cflag |= B600;
939 port.c_cflag |= B1200;
943 port.c_cflag |= B2400;
947 port.c_cflag |= B4800;
951 port.c_cflag |= B9600;
955 port.c_cflag |= B19200;
959 port.c_cflag |= B38400;
963 port.c_cflag |= B57600;
968 port.c_cflag |= B115200;
973 port.c_cflag |= B230400;
978 port.c_cflag |= B460800;
982 #if defined (HAVE_LINUX_SERIAL_H) && defined (TIOCSSERIAL)
983 { struct serial_struct nuts;
985 ioctl(fd, TIOCGSERIAL, &nuts);
986 nuts.custom_divisor = nuts.baud_base / lpdcb->BaudRate;
987 if (!(nuts.custom_divisor)) nuts.custom_divisor = 1;
988 arby = nuts.baud_base / nuts.custom_divisor;
989 nuts.flags &= ~ASYNC_SPD_MASK;
990 nuts.flags |= ASYNC_SPD_CUST;
991 WARN("You (or a program acting at your behest) have specified\n"
992 "a non-standard baud rate %ld. Wine will set the rate to %d,\n"
993 "which is as close as we can get by our present understanding of your\n"
994 "hardware. I hope you know what you are doing. Any disruption Wine\n"
995 "has caused to your linux system can be undone with setserial \n"
996 "(see man setserial). If you have incapacitated a Hayes type modem,\n"
997 "reset it and it will probably recover.\n", lpdcb->BaudRate, arby);
998 ioctl(fd, TIOCSSERIAL, &nuts);
999 port.c_cflag |= B38400;
1002 #endif /* Don't have linux/serial.h or lack TIOCSSERIAL */
1005 COMM_SetCommError(handle,IE_BAUDRATE);
1007 ERR("baudrate %ld\n",lpdcb->BaudRate);
1010 #elif !defined(__EMX__)
1011 switch (lpdcb->BaudRate) {
1014 port.c_ospeed = B110;
1018 port.c_ospeed = B300;
1022 port.c_ospeed = B600;
1026 port.c_ospeed = B1200;
1030 port.c_ospeed = B2400;
1034 port.c_ospeed = B4800;
1038 port.c_ospeed = B9600;
1042 port.c_ospeed = B19200;
1046 port.c_ospeed = B38400;
1049 COMM_SetCommError(handle,IE_BAUDRATE);
1051 ERR("baudrate %ld\n",lpdcb->BaudRate);
1054 port.c_ispeed = port.c_ospeed;
1056 bytesize=lpdcb->ByteSize;
1057 stopbits=lpdcb->StopBits;
1060 port.c_cflag &= ~(PARENB | PARODD | CMSPAR);
1062 port.c_cflag &= ~(PARENB | PARODD);
1065 port.c_iflag |= INPCK;
1067 port.c_iflag &= ~INPCK;
1068 switch (lpdcb->Parity) {
1072 port.c_cflag |= (PARENB | PARODD);
1075 port.c_cflag |= PARENB;
1078 /* Linux defines mark/space (stick) parity */
1080 port.c_cflag |= (PARENB | CMSPAR);
1083 port.c_cflag |= (PARENB | PARODD | CMSPAR);
1086 /* try the POSIX way */
1088 if( stopbits == ONESTOPBIT) {
1089 stopbits = TWOSTOPBITS;
1090 port.c_iflag &= ~INPCK;
1092 COMM_SetCommError(handle,IE_BYTESIZE);
1094 ERR("Cannot set MARK Parity\n");
1101 port.c_iflag &= ~INPCK;
1103 COMM_SetCommError(handle,IE_BYTESIZE);
1105 ERR("Cannot set SPACE Parity\n");
1111 COMM_SetCommError(handle,IE_BYTESIZE);
1118 port.c_cflag &= ~CSIZE;
1121 port.c_cflag |= CS5;
1124 port.c_cflag |= CS6;
1127 port.c_cflag |= CS7;
1130 port.c_cflag |= CS8;
1133 COMM_SetCommError(handle,IE_BYTESIZE);
1141 port.c_cflag &= ~CSTOPB;
1143 case ONE5STOPBITS: /* wil be selected if bytesize is 5 */
1145 port.c_cflag |= CSTOPB;
1148 COMM_SetCommError(handle,IE_BYTESIZE);
1154 if ( lpdcb->fOutxCtsFlow ||
1155 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1158 port.c_cflag |= CRTSCTS;
1163 if (lpdcb->fDtrControl == DTR_CONTROL_HANDSHAKE)
1165 WARN("DSR/DTR flow control not supported\n");
1169 port.c_iflag |= IXON;
1171 port.c_iflag &= ~IXON;
1173 port.c_iflag |= IXOFF;
1175 port.c_iflag &= ~IXOFF;
1177 if (tcsetattr(fd,TCSANOW,&port)==-1) { /* otherwise it hangs with pending input*/
1178 int save_error=errno;
1179 COMM_SetCommError(handle,CE_IOE);
1181 ERR("tcsetattr error '%s'\n", strerror(save_error));
1184 COMM_SetCommError(handle,0);
1191 /*****************************************************************************
1192 * GetCommState (KERNEL32.@)
1194 * Fills in a device control block with information from a communications device.
1198 * True on success, false if the communication device handle is bad etc
1202 * XonChar and XoffChar are not set.
1204 BOOL WINAPI GetCommState(
1205 HANDLE handle, /* [in] The communications device. */
1206 LPDCB lpdcb) /* [out] The device control block. */
1208 struct termios port;
1211 TRACE("handle %d, ptr %p\n", handle, lpdcb);
1213 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
1216 ERR("FILE_GetUnixHandle failed\n");
1219 if (tcgetattr(fd, &port) == -1) {
1220 int save_error=errno;
1221 ERR("tcgetattr error '%s'\n", strerror(save_error));
1222 COMM_SetCommError(handle,CE_IOE);
1229 speed= (port.c_cflag & CBAUD);
1231 speed= (cfgetospeed(&port));
1235 lpdcb->BaudRate = 110;
1238 lpdcb->BaudRate = 300;
1241 lpdcb->BaudRate = 600;
1244 lpdcb->BaudRate = 1200;
1247 lpdcb->BaudRate = 2400;
1250 lpdcb->BaudRate = 4800;
1253 lpdcb->BaudRate = 9600;
1256 lpdcb->BaudRate = 19200;
1259 lpdcb->BaudRate = 38400;
1263 lpdcb->BaudRate = 57600;
1268 lpdcb->BaudRate = 115200;
1273 lpdcb->BaudRate = 230400;
1278 lpdcb->BaudRate = 460800;
1282 ERR("unknown speed %x \n",speed);
1285 switch (port.c_cflag & CSIZE) {
1287 lpdcb->ByteSize = 5;
1290 lpdcb->ByteSize = 6;
1293 lpdcb->ByteSize = 7;
1296 lpdcb->ByteSize = 8;
1299 ERR("unknown size %x \n",port.c_cflag & CSIZE);
1302 if(port.c_iflag & INPCK)
1303 lpdcb->fParity = TRUE;
1305 lpdcb->fParity = FALSE;
1307 switch (port.c_cflag & (PARENB | PARODD | CMSPAR))
1309 switch (port.c_cflag & (PARENB | PARODD))
1313 lpdcb->Parity = NOPARITY;
1316 lpdcb->Parity = EVENPARITY;
1318 case (PARENB | PARODD):
1319 lpdcb->Parity = ODDPARITY;
1322 case (PARENB | CMSPAR):
1323 lpdcb->Parity = MARKPARITY;
1325 case (PARENB | PARODD | CMSPAR):
1326 lpdcb->Parity = SPACEPARITY;
1331 if (port.c_cflag & CSTOPB)
1332 if(lpdcb->ByteSize == 5)
1333 lpdcb->StopBits = ONE5STOPBITS;
1335 lpdcb->StopBits = TWOSTOPBITS;
1337 lpdcb->StopBits = ONESTOPBIT;
1342 /* termios does not support DTR/DSR flow control */
1343 lpdcb->fOutxDsrFlow = 0;
1344 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
1348 if (port.c_cflag & CRTSCTS) {
1349 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
1350 lpdcb->fOutxCtsFlow = 1;
1354 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
1355 lpdcb->fOutxCtsFlow = 0;
1357 if (port.c_iflag & IXON)
1362 if (port.c_iflag & IXOFF)
1371 lpdcb->XoffLim = 10;
1373 COMM_SetCommError(handle,0);
1377 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1378 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
1379 (lpdcb->StopBits == ONESTOPBIT)?1:
1380 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
1381 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
1382 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
1384 if ( lpdcb->fOutxCtsFlow ||
1385 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1390 TRACE("~CRTSCTS\n");
1396 /*****************************************************************************
1397 * TransmitCommChar (KERNEL32.@)
1399 * Transmits a single character in front of any pending characters in the
1400 * output buffer. Usually used to send an interrupt character to a host.
1404 * True if the call succeeded, false if the previous command character to the
1405 * same device has not been sent yet the handle is bad etc.
1411 BOOL WINAPI TransmitCommChar(
1412 HANDLE hComm, /* [in] The communication device in need of a command character. */
1413 CHAR chTransmit) /* [in] The character to transmit. */
1415 FIXME("(%x,'%c'), stub ! Use win32 handle!\n",hComm,chTransmit);
1419 /*****************************************************************************
1420 * GetCommTimeouts (KERNEL32.@)
1422 * Obtains the request timeout values for the communications device.
1426 * True on success, false if communications device handle is bad
1427 * or the target structure is null.
1429 BOOL WINAPI GetCommTimeouts(
1430 HANDLE hComm, /* [in] The communications device. */
1431 LPCOMMTIMEOUTS lptimeouts) /* [out] The struct of request timeouts. */
1435 TRACE("(%x,%p)\n",hComm,lptimeouts);
1439 SetLastError(ERROR_INVALID_PARAMETER);
1443 SERVER_START_REQ( get_serial_info )
1445 req->handle = hComm;
1446 if ((ret = !wine_server_call_err( req )))
1448 lptimeouts->ReadIntervalTimeout = reply->readinterval;
1449 lptimeouts->ReadTotalTimeoutMultiplier = reply->readmult;
1450 lptimeouts->ReadTotalTimeoutConstant = reply->readconst;
1451 lptimeouts->WriteTotalTimeoutMultiplier = reply->writemult;
1452 lptimeouts->WriteTotalTimeoutConstant = reply->writeconst;
1459 /*****************************************************************************
1460 * SetCommTimeouts (KERNEL32.@)
1462 * Sets the timeouts used when reading and writing data to/from COMM ports.
1464 * ReadIntervalTimeout
1465 * - converted and passes to linux kernel as c_cc[VTIME]
1466 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1467 * - used in ReadFile to calculate GetOverlappedResult's timeout
1468 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1469 * - used in WriteFile to calculate GetOverlappedResult's timeout
1473 * True if the timeouts were set, false otherwise.
1475 BOOL WINAPI SetCommTimeouts(
1476 HANDLE hComm, /* [in] handle of COMM device */
1477 LPCOMMTIMEOUTS lptimeouts) /* [in] pointer to COMMTIMEOUTS structure */
1481 struct termios tios;
1483 TRACE("(%x,%p)\n",hComm,lptimeouts);
1487 SetLastError(ERROR_INVALID_PARAMETER);
1491 SERVER_START_REQ( set_serial_info )
1493 req->handle = hComm;
1494 req->flags = SERIALINFO_SET_TIMEOUTS;
1495 req->readinterval = lptimeouts->ReadIntervalTimeout ;
1496 req->readmult = lptimeouts->ReadTotalTimeoutMultiplier ;
1497 req->readconst = lptimeouts->ReadTotalTimeoutConstant ;
1498 req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ;
1499 req->writeconst = lptimeouts->WriteTotalTimeoutConstant ;
1500 ret = !wine_server_call_err( req );
1503 if (!ret) return FALSE;
1505 /* FIXME: move this stuff to the server */
1506 fd = FILE_GetUnixHandle( hComm, GENERIC_READ );
1508 FIXME("no fd for handle = %0x!.\n",hComm);
1512 if (-1==tcgetattr(fd,&tios)) {
1513 FIXME("tcgetattr on fd %d failed!\n",fd);
1517 /* VTIME is in 1/10 seconds */
1519 unsigned int ux_timeout;
1521 if(lptimeouts->ReadIntervalTimeout == 0) /* 0 means no timeout */
1527 ux_timeout = (lptimeouts->ReadIntervalTimeout+99)/100;
1530 ux_timeout = 1; /* must be at least some timeout */
1533 tios.c_cc[VTIME] = ux_timeout;
1536 if (-1==tcsetattr(fd,0,&tios)) {
1537 FIXME("tcsetattr on fd %d failed!\n",fd);
1544 /***********************************************************************
1545 * GetCommModemStatus (KERNEL32.@)
1547 * Obtains the four control register bits if supported by the hardware.
1551 * True if the communications handle was good and for hardware that
1552 * control register access, false otherwise.
1554 BOOL WINAPI GetCommModemStatus(
1555 HANDLE hFile, /* [in] The communications device. */
1556 LPDWORD lpModemStat) /* [out] The control register bits. */
1558 int fd,mstat, result=FALSE;
1562 fd = FILE_GetUnixHandle( hFile, GENERIC_READ );
1565 result = ioctl(fd, TIOCMGET, &mstat);
1569 WARN("ioctl failed\n");
1573 if (mstat & TIOCM_CTS)
1574 *lpModemStat |= MS_CTS_ON;
1577 if (mstat & TIOCM_DSR)
1578 *lpModemStat |= MS_DSR_ON;
1581 if (mstat & TIOCM_RNG)
1582 *lpModemStat |= MS_RING_ON;
1585 /*FIXME: Not really sure about RLSD UB 990810*/
1586 if (mstat & TIOCM_CAR)
1587 *lpModemStat |= MS_RLSD_ON;
1589 TRACE("%04x -> %s%s%s%s\n", mstat,
1590 (*lpModemStat &MS_RLSD_ON)?"MS_RLSD_ON ":"",
1591 (*lpModemStat &MS_RING_ON)?"MS_RING_ON ":"",
1592 (*lpModemStat &MS_DSR_ON)?"MS_DSR_ON ":"",
1593 (*lpModemStat &MS_CTS_ON)?"MS_CTS_ON ":"");
1600 /***********************************************************************
1601 * COMM_WaitCommEventService (INTERNAL)
1603 * This function is called while the client is waiting on the
1604 * server, so we can't make any server calls here.
1606 static void COMM_WaitCommEventService(async_private *ovp)
1608 async_commio *commio = (async_commio*) ovp;
1609 LPOVERLAPPED lpOverlapped = commio->lpOverlapped;
1611 TRACE("overlapped %p\n",lpOverlapped);
1613 /* FIXME: detect other events */
1614 *commio->buffer = EV_RXCHAR;
1616 lpOverlapped->Internal = STATUS_SUCCESS;
1620 /***********************************************************************
1621 * COMM_WaitCommEvent (INTERNAL)
1623 * This function must have an lpOverlapped.
1625 static BOOL COMM_WaitCommEvent(
1626 HANDLE hFile, /* [in] handle of comm port to wait for */
1627 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1628 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1635 SetLastError(ERROR_INVALID_PARAMETER);
1639 if(NtResetEvent(lpOverlapped->hEvent,NULL))
1642 fd = FILE_GetUnixHandle( hFile, GENERIC_WRITE );
1646 ovp = (async_commio*) HeapAlloc(GetProcessHeap(), 0, sizeof (async_commio));
1653 ovp->async.ops = &commio_async_ops;
1654 ovp->async.handle = hFile;
1656 ovp->async.type = ASYNC_TYPE_WAIT;
1657 ovp->async.func = COMM_WaitCommEventService;
1658 ovp->async.event = lpOverlapped->hEvent;
1659 ovp->lpOverlapped = lpOverlapped;
1660 ovp->buffer = (char *)lpdwEvents;
1662 lpOverlapped->InternalHigh = 0;
1663 lpOverlapped->Offset = 0;
1664 lpOverlapped->OffsetHigh = 0;
1666 if ( !register_new_async (&ovp->async) )
1667 SetLastError( ERROR_IO_PENDING );
1672 /***********************************************************************
1673 * WaitCommEvent (KERNEL32.@)
1675 * Wait until something interesting happens on a COMM port.
1676 * Interesting things (events) are set by calling SetCommMask before
1677 * this function is called.
1680 * TRUE if successful
1683 * The set of detected events will be written to *lpdwEventMask
1684 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1687 * Only supports EV_RXCHAR and EV_TXEMPTY
1689 BOOL WINAPI WaitCommEvent(
1690 HANDLE hFile, /* [in] handle of comm port to wait for */
1691 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1692 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1697 TRACE("(%x %p %p )\n",hFile, lpdwEvents,lpOverlapped);
1700 return COMM_WaitCommEvent(hFile, lpdwEvents, lpOverlapped);
1702 /* if there is no overlapped structure, create our own */
1703 ov.hEvent = CreateEventA(NULL,FALSE,FALSE,NULL);
1705 COMM_WaitCommEvent(hFile, lpdwEvents, &ov);
1707 if(GetLastError()!=STATUS_PENDING)
1709 CloseHandle(ov.hEvent);
1713 /* wait for the overlapped to complete */
1714 ret = GetOverlappedResult(hFile, &ov, NULL, TRUE);
1715 CloseHandle(ov.hEvent);
1720 /***********************************************************************
1721 * GetCommProperties (KERNEL32.@)
1723 * This function fills in a structure with the capabilities of the
1724 * communications port driver.
1728 * TRUE on success, FALSE on failure
1729 * If successful, the lpCommProp structure be filled in with
1730 * properties of the comm port.
1732 BOOL WINAPI GetCommProperties(
1733 HANDLE hFile, /* [in] handle of the comm port */
1734 LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */
1736 FIXME("(%d %p )\n",hFile,lpCommProp);
1741 * These values should be valid for LINUX's serial driver
1742 * FIXME: Perhaps they deserve an #ifdef LINUX
1744 memset(lpCommProp,0,sizeof(COMMPROP));
1745 lpCommProp->wPacketLength = 1;
1746 lpCommProp->wPacketVersion = 1;
1747 lpCommProp->dwServiceMask = SP_SERIALCOMM;
1748 lpCommProp->dwReserved1 = 0;
1749 lpCommProp->dwMaxTxQueue = 4096;
1750 lpCommProp->dwMaxRxQueue = 4096;
1751 lpCommProp->dwMaxBaud = BAUD_115200;
1752 lpCommProp->dwProvSubType = PST_RS232;
1753 lpCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS ;
1754 lpCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING |
1755 SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ;
1756 lpCommProp->dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 |
1757 BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
1758 BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ;
1759 lpCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ;
1760 lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
1761 PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE;
1762 lpCommProp->dwCurrentTxQueue = lpCommProp->dwMaxTxQueue;
1763 lpCommProp->dwCurrentRxQueue = lpCommProp->dwMaxRxQueue;
1768 /***********************************************************************
1770 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1771 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1772 * This is dependent on the type of COMM port, but since it is doubtful
1773 * anybody will get around to implementing support for fancy serial
1774 * ports in WINE, this is hardcoded for the time being. The name of
1775 * this DLL should be stored in and read from the system registry in
1776 * the hive HKEY_LOCAL_MACHINE, key
1777 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1778 * where ???? is the port number... that is determined by PNP
1779 * The DLL should be loaded when the COMM port is opened, and closed
1780 * when the COMM port is closed. - MJM 20 June 2000
1781 ***********************************************************************/
1782 static CHAR lpszSerialUI[] = "serialui.dll";
1785 /***********************************************************************
1786 * CommConfigDialogA (KERNEL32.@)
1788 * Raises a dialog that allows the user to configure a comm port.
1789 * Fills the COMMCONFIG struct with information specified by the user.
1790 * This function should call a similar routine in the COMM driver...
1794 * TRUE on success, FALSE on failure
1795 * If successful, the lpCommConfig structure will contain a new
1796 * configuration for the comm port, as specified by the user.
1799 * The library with the CommConfigDialog code is never unloaded.
1800 * Perhaps this should be done when the comm port is closed?
1802 BOOL WINAPI CommConfigDialogA(
1803 LPCSTR lpszDevice, /* [in] name of communications device */
1804 HANDLE hWnd, /* [in] parent window for the dialog */
1805 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1807 FARPROC lpfnCommDialog;
1808 HMODULE hConfigModule;
1811 TRACE("(%p %x %p)\n",lpszDevice, hWnd, lpCommConfig);
1813 hConfigModule = LoadLibraryA(lpszSerialUI);
1817 lpfnCommDialog = GetProcAddress(hConfigModule, (LPCSTR)3L);
1822 r = lpfnCommDialog(lpszDevice,hWnd,lpCommConfig);
1824 /* UnloadLibrary(hConfigModule); */
1829 /***********************************************************************
1830 * CommConfigDialogW (KERNEL32.@)
1832 * see CommConfigDialogA for more info
1834 BOOL WINAPI CommConfigDialogW(
1835 LPCWSTR lpszDevice, /* [in] name of communications device */
1836 HANDLE hWnd, /* [in] parent window for the dialog */
1837 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1842 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
1845 r = CommConfigDialogA(lpDeviceA,hWnd,lpCommConfig);
1846 HeapFree( GetProcessHeap(), 0, lpDeviceA );
1850 /***********************************************************************
1851 * GetCommConfig (KERNEL32.@)
1853 * Fill in the COMMCONFIG structure for the comm port hFile
1857 * TRUE on success, FALSE on failure
1858 * If successful, lpCommConfig contains the comm port configuration.
1863 BOOL WINAPI GetCommConfig(
1864 HANDLE hFile, /* [in] The communications device. */
1865 LPCOMMCONFIG lpCommConfig, /* [out] The communications configuration of the device (if it fits). */
1866 LPDWORD lpdwSize) /* [in/out] Initially the size of the configuration buffer/structure,
1867 afterwards the number of bytes copied to the buffer or
1868 the needed size of the buffer. */
1872 TRACE("(%x %p)\n",hFile,lpCommConfig);
1874 if(lpCommConfig == NULL)
1877 r = *lpdwSize < sizeof(COMMCONFIG);
1878 *lpdwSize = sizeof(COMMCONFIG);
1882 lpCommConfig->dwSize = sizeof(COMMCONFIG);
1883 lpCommConfig->wVersion = 1;
1884 lpCommConfig->wReserved = 0;
1885 r = GetCommState(hFile,&lpCommConfig->dcb);
1886 lpCommConfig->dwProviderSubType = PST_RS232;
1887 lpCommConfig->dwProviderOffset = 0;
1888 lpCommConfig->dwProviderSize = 0;
1893 /***********************************************************************
1894 * SetCommConfig (KERNEL32.@)
1896 * Sets the configuration of the communications device.
1900 * True on success, false if the handle was bad is not a communications device.
1902 BOOL WINAPI SetCommConfig(
1903 HANDLE hFile, /* [in] The communications device. */
1904 LPCOMMCONFIG lpCommConfig, /* [in] The desired configuration. */
1905 DWORD dwSize) /* [in] size of the lpCommConfig struct */
1907 TRACE("(%x %p)\n",hFile,lpCommConfig);
1908 return SetCommState(hFile,&lpCommConfig->dcb);
1911 /***********************************************************************
1912 * SetDefaultCommConfigA (KERNEL32.@)
1914 * Initializes the default configuration for the specified communication
1919 * True if the device was found and the defaults set, false otherwise
1921 BOOL WINAPI SetDefaultCommConfigA(
1922 LPCSTR lpszDevice, /* [in] The ascii name of the device targeted for configuration. */
1923 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1924 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
1926 FARPROC lpfnSetDefaultCommConfig;
1927 HMODULE hConfigModule;
1930 TRACE("(%p %p %lx)\n",lpszDevice, lpCommConfig, dwSize);
1932 hConfigModule = LoadLibraryA(lpszSerialUI);
1936 lpfnSetDefaultCommConfig = GetProcAddress(hConfigModule, (LPCSTR)4L);
1938 if(! lpfnSetDefaultCommConfig)
1941 r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize);
1943 /* UnloadLibrary(hConfigModule); */
1949 /***********************************************************************
1950 * SetDefaultCommConfigW (KERNEL32.@)
1952 * Initializes the default configuration for the specified
1953 * communication device. (unicode)
1958 BOOL WINAPI SetDefaultCommConfigW(
1959 LPCWSTR lpszDevice, /* [in] The unicode 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. */
1966 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice),lpCommConfig,dwSize);
1968 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
1971 r = SetDefaultCommConfigA(lpDeviceA,lpCommConfig,dwSize);
1972 HeapFree( GetProcessHeap(), 0, lpDeviceA );
1977 /***********************************************************************
1978 * GetDefaultCommConfigA (KERNEL32.@)
1980 * Acquires the default configuration of the specified communication device. (unicode)
1984 * True on successful reading of the default configuration,
1985 * if the device is not found or the buffer is too small.
1987 BOOL WINAPI GetDefaultCommConfigA(
1988 LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */
1989 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
1990 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
1991 afterwards the number of bytes copied to the buffer or
1992 the needed size of the buffer. */
1994 LPDCB lpdcb = &(lpCC->dcb);
1997 if (strncasecmp(lpszName,"COM",3)) {
1998 ERR("not implemented for <%s>\n", lpszName);
2002 TRACE("(%s %p %ld)\n", lpszName, lpCC, *lpdwSize );
2003 if (*lpdwSize < sizeof(COMMCONFIG)) {
2004 *lpdwSize = sizeof(COMMCONFIG);
2008 *lpdwSize = sizeof(COMMCONFIG);
2010 lpCC->dwSize = sizeof(COMMCONFIG);
2012 lpCC->dwProviderSubType = PST_RS232;
2013 lpCC->dwProviderOffset = 0L;
2014 lpCC->dwProviderSize = 0L;
2016 sprintf( temp, "COM%c:38400,n,8,1", lpszName[3]);
2017 FIXME("setting %s as default\n", temp);
2019 return BuildCommDCBA( temp, lpdcb);
2022 /**************************************************************************
2023 * GetDefaultCommConfigW (KERNEL32.@)
2025 * Acquires the default configuration of the specified communication device. (unicode)
2029 * True on successful reading of the default configuration,
2030 * if the device is not found or the buffer is too small.
2032 BOOL WINAPI GetDefaultCommConfigW(
2033 LPCWSTR lpszName, /* [in] The unicode name of the device targeted for configuration. */
2034 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
2035 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
2036 afterwards the number of bytes copied to the buffer or
2037 the needed size of the buffer. */
2042 TRACE("(%p,%p,%ld)\n",lpszName,lpCC,*lpdwSize);
2043 lpszNameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName );
2046 ret=GetDefaultCommConfigA(lpszNameA,lpCC,lpdwSize);
2047 HeapFree( GetProcessHeap(), 0, lpszNameA );