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"
69 #ifdef HAVE_SYS_FILIO_H
70 # include <sys/filio.h>
72 #ifdef HAVE_SYS_IOCTL_H
73 #include <sys/ioctl.h>
78 #ifdef HAVE_SYS_POLL_H
79 # include <sys/poll.h>
81 #ifdef HAVE_SYS_MODEM_H
82 # include <sys/modem.h>
84 #ifdef HAVE_SYS_STRTIO_H
85 # include <sys/strtio.h>
88 #define NONAMELESSUNION
89 #define NONAMELESSSTRUCT
95 #include "wine/server.h"
99 #include "wine/debug.h"
101 #ifdef HAVE_LINUX_SERIAL_H
102 #include <linux/serial.h>
105 WINE_DEFAULT_DEBUG_CHANNEL(comm);
107 /* retrieve the Unix handle corresponding to a comm handle */
108 static int get_comm_fd( HANDLE handle, DWORD access )
112 ret = wine_server_handle_to_fd( handle, access, &fd, NULL, NULL );
113 if (ret) SetLastError( RtlNtStatusToDosError(ret) );
117 /* release the Unix handle returned by get_comm_fd */
118 static inline void release_comm_fd( HANDLE handle, int fd )
120 wine_server_release_fd( handle, fd );
124 /***********************************************************************
125 * Asynchronous I/O for asynchronous wait requests *
128 static DWORD commio_get_async_count (const async_private *ovp);
129 static void commio_async_cleanup (async_private *ovp);
131 static async_ops commio_async_ops =
133 commio_get_async_count, /* get_count */
134 NULL, /* call_completion */
135 commio_async_cleanup /* cleanup */
138 typedef struct async_commio
140 struct async_private async;
144 static DWORD commio_get_async_count (const struct async_private *ovp)
149 static void commio_async_cleanup (async_private *ovp)
151 HeapFree(GetProcessHeap(), 0, ovp );
154 /***********************************************************************/
156 #if !defined(TIOCINQ) && defined(FIONREAD)
157 #define TIOCINQ FIONREAD
160 static int COMM_WhackModem(int fd, unsigned int andy, unsigned int orrie)
163 unsigned int mstat, okay;
164 okay = ioctl(fd, TIOCMGET, &mstat);
165 if (okay) return okay;
166 if (andy) mstat &= andy;
168 return ioctl(fd, TIOCMSET, &mstat);
174 /***********************************************************************
175 * COMM_Parse* (Internal)
177 * The following COMM_Parse* functions are used by the BuildCommDCB
178 * functions to help parse the various parts of the device control string.
180 static LPCSTR COMM_ParseStart(LPCSTR ptr)
182 /* The device control string may optionally start with "COMx" followed
183 by an optional ':' and spaces. */
184 if(!strncasecmp(ptr, "COM", 3))
188 /* Allow any com port above 0 as Win 9x does (NT only allows
189 values for com ports which are actually present) */
190 if(*ptr < '1' || *ptr > '9')
193 /* Advance pointer past port number */
194 while(*ptr >= '0' && *ptr <= '9') ptr++;
196 /* The com port number must be followed by a ':' or ' ' */
197 if(*ptr != ':' && *ptr != ' ')
200 /* Advance pointer to beginning of next parameter */
201 while(*ptr == ' ') ptr++;
205 while(*ptr == ' ') ptr++;
208 /* The device control string must not start with a space. */
215 static LPCSTR COMM_ParseNumber(LPCSTR ptr, LPDWORD lpnumber)
217 if(*ptr < '0' || *ptr > '9') return NULL;
218 if(!sscanf(ptr, "%lu", lpnumber)) return NULL;
219 while(*ptr >= '0' && *ptr <= '9') ptr++;
223 static LPCSTR COMM_ParseParity(LPCSTR ptr, LPBYTE lpparity)
225 /* Contrary to what you might expect, Windows only sets the Parity
226 member of DCB and not fParity even when parity is specified in the
227 device control string */
229 switch(toupper(*ptr++))
232 *lpparity = EVENPARITY;
235 *lpparity = MARKPARITY;
238 *lpparity = NOPARITY;
241 *lpparity = ODDPARITY;
244 *lpparity = SPACEPARITY;
253 static LPCSTR COMM_ParseByteSize(LPCSTR ptr, LPBYTE lpbytesize)
257 if(!(ptr = COMM_ParseNumber(ptr, &temp)))
260 if(temp >= 5 && temp <= 8)
269 static LPCSTR COMM_ParseStopBits(LPCSTR ptr, LPBYTE lpstopbits)
273 if(!strncmp("1.5", ptr, 3))
276 *lpstopbits = ONE5STOPBITS;
280 if(!(ptr = COMM_ParseNumber(ptr, &temp)))
284 *lpstopbits = ONESTOPBIT;
286 *lpstopbits = TWOSTOPBITS;
294 static LPCSTR COMM_ParseOnOff(LPCSTR ptr, LPDWORD lponoff)
296 if(!strncasecmp("on", ptr, 2))
301 else if(!strncasecmp("off", ptr, 3))
312 /***********************************************************************
313 * COMM_BuildOldCommDCB (Internal)
315 * Build a DCB using the old style settings string eg: "96,n,8,1"
317 static BOOL COMM_BuildOldCommDCB(LPCSTR device, LPDCB lpdcb)
321 if(!(device = COMM_ParseNumber(device, &lpdcb->BaudRate)))
324 switch(lpdcb->BaudRate)
329 lpdcb->BaudRate *= 10;
335 lpdcb->BaudRate *= 100;
338 lpdcb->BaudRate = 19200;
342 while(*device == ' ') device++;
343 if(*device++ != ',') return FALSE;
344 while(*device == ' ') device++;
346 if(!(device = COMM_ParseParity(device, &lpdcb->Parity)))
349 while(*device == ' ') device++;
350 if(*device++ != ',') return FALSE;
351 while(*device == ' ') device++;
353 if(!(device = COMM_ParseByteSize(device, &lpdcb->ByteSize)))
356 while(*device == ' ') device++;
357 if(*device++ != ',') return FALSE;
358 while(*device == ' ') device++;
360 if(!(device = COMM_ParseStopBits(device, &lpdcb->StopBits)))
363 /* The last parameter for flow control is optional. */
364 while(*device == ' ') device++;
368 while(*device == ' ') device++;
369 if(*device) last = toupper(*device++);
370 while(*device == ' ') device++;
373 /* Win NT sets the flow control members based on (or lack of) the last
374 parameter. Win 9x does not set these members. */
379 lpdcb->fOutX = FALSE;
380 lpdcb->fOutxCtsFlow = FALSE;
381 lpdcb->fOutxDsrFlow = FALSE;
382 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
383 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
388 lpdcb->fOutxCtsFlow = FALSE;
389 lpdcb->fOutxDsrFlow = FALSE;
390 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
391 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
395 lpdcb->fOutX = FALSE;
396 lpdcb->fOutxCtsFlow = TRUE;
397 lpdcb->fOutxDsrFlow = TRUE;
398 lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE;
399 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
405 /* This should be the end of the string. */
406 if(*device) return FALSE;
411 /***********************************************************************
412 * COMM_BuildNewCommDCB (Internal)
414 * Build a DCB using the new style settings string.
415 * eg: "baud=9600 parity=n data=8 stop=1 xon=on to=on"
417 static BOOL COMM_BuildNewCommDCB(LPCSTR device, LPDCB lpdcb, LPCOMMTIMEOUTS lptimeouts)
420 BOOL baud = FALSE, stop = FALSE;
424 while(*device == ' ') device++;
426 if(!strncasecmp("baud=", device, 5))
430 if(!(device = COMM_ParseNumber(device + 5, &lpdcb->BaudRate)))
433 else if(!strncasecmp("parity=", device, 7))
435 if(!(device = COMM_ParseParity(device + 7, &lpdcb->Parity)))
438 else if(!strncasecmp("data=", device, 5))
440 if(!(device = COMM_ParseByteSize(device + 5, &lpdcb->ByteSize)))
443 else if(!strncasecmp("stop=", device, 5))
447 if(!(device = COMM_ParseStopBits(device + 5, &lpdcb->StopBits)))
450 else if(!strncasecmp("to=", device, 3))
452 if(!(device = COMM_ParseOnOff(device + 3, &temp)))
455 lptimeouts->ReadIntervalTimeout = 0;
456 lptimeouts->ReadTotalTimeoutMultiplier = 0;
457 lptimeouts->ReadTotalTimeoutConstant = 0;
458 lptimeouts->WriteTotalTimeoutMultiplier = 0;
459 lptimeouts->WriteTotalTimeoutConstant = temp ? 60000 : 0;
461 else if(!strncasecmp("xon=", device, 4))
463 if(!(device = COMM_ParseOnOff(device + 4, &temp)))
469 else if(!strncasecmp("odsr=", device, 5))
471 if(!(device = COMM_ParseOnOff(device + 5, &temp)))
474 lpdcb->fOutxDsrFlow = temp;
476 else if(!strncasecmp("octs=", device, 5))
478 if(!(device = COMM_ParseOnOff(device + 5, &temp)))
481 lpdcb->fOutxCtsFlow = temp;
483 else if(!strncasecmp("dtr=", device, 4))
485 if(!(device = COMM_ParseOnOff(device + 4, &temp)))
488 lpdcb->fDtrControl = temp;
490 else if(!strncasecmp("rts=", device, 4))
492 if(!(device = COMM_ParseOnOff(device + 4, &temp)))
495 lpdcb->fRtsControl = temp;
497 else if(!strncasecmp("idsr=", device, 5))
499 if(!(device = COMM_ParseOnOff(device + 5, &temp)))
502 /* Win NT sets the fDsrSensitivity member based on the
503 idsr parameter. Win 9x sets fOutxDsrFlow instead. */
504 lpdcb->fDsrSensitivity = temp;
509 /* After the above parsing, the next character (if not the end of
510 the string) should be a space */
511 if(*device && *device != ' ')
515 /* If stop bits were not specified, a default is always supplied. */
518 if(baud && lpdcb->BaudRate == 110)
519 lpdcb->StopBits = TWOSTOPBITS;
521 lpdcb->StopBits = ONESTOPBIT;
527 /**************************************************************************
528 * BuildCommDCBA (KERNEL32.@)
530 * Updates a device control block data structure with values from an
531 * ascii device control string. The device control string has two forms
532 * normal and extended, it must be exclusively in one or the other form.
536 * True on success, false on a malformed control string.
538 BOOL WINAPI BuildCommDCBA(
539 LPCSTR device, /* [in] The ascii device control string used to update the DCB. */
540 LPDCB lpdcb) /* [out] The device control block to be updated. */
542 return BuildCommDCBAndTimeoutsA(device,lpdcb,NULL);
545 /**************************************************************************
546 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
548 * Updates a device control block data structure with values from an
549 * ascii device control string. Taking timeout values from a timeouts
550 * struct if desired by the control string.
554 * True on success, false bad handles etc
556 BOOL WINAPI BuildCommDCBAndTimeoutsA(
557 LPCSTR device, /* [in] The ascii device control string. */
558 LPDCB lpdcb, /* [out] The device control block to be updated. */
559 LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */
562 COMMTIMEOUTS timeouts;
566 TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts);
568 /* Set DCBlength. (Windows NT does not do this, but 9x does) */
569 lpdcb->DCBlength = sizeof(DCB);
571 /* Make a copy of the original data structures to work with since if
572 if there is an error in the device control string the originals
573 should not be modified (except possibly DCBlength) */
574 memcpy(&dcb, lpdcb, sizeof(DCB));
575 if(lptimeouts) memcpy(&timeouts, lptimeouts, sizeof(COMMTIMEOUTS));
577 ptr = COMM_ParseStart(ptr);
581 else if(strchr(ptr, ','))
582 result = COMM_BuildOldCommDCB(ptr, &dcb);
584 result = COMM_BuildNewCommDCB(ptr, &dcb, &timeouts);
588 memcpy(lpdcb, &dcb, sizeof(DCB));
589 if(lptimeouts) memcpy(lptimeouts, &timeouts, sizeof(COMMTIMEOUTS));
594 WARN("Invalid device control string: %s\n", device);
595 SetLastError(ERROR_INVALID_PARAMETER);
600 /**************************************************************************
601 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
603 * Updates a device control block data structure with values from an
604 * unicode device control string. Taking timeout values from a timeouts
605 * struct if desired by the control string.
609 * True on success, false bad handles etc.
611 BOOL WINAPI BuildCommDCBAndTimeoutsW(
612 LPCWSTR devid, /* [in] The unicode device control string. */
613 LPDCB lpdcb, /* [out] The device control block to be updated. */
614 LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */
619 TRACE("(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
620 devidA = HEAP_strdupWtoA( GetProcessHeap(), 0, devid );
623 ret=BuildCommDCBAndTimeoutsA(devidA,lpdcb,lptimeouts);
624 HeapFree( GetProcessHeap(), 0, devidA );
629 /**************************************************************************
630 * BuildCommDCBW (KERNEL32.@)
632 * Updates a device control block structure with values from an
633 * unicode device control string. The device control string has two forms
634 * normal and extended, it must be exclusively in one or the other form.
638 * True on success, false on an malformed control string.
640 BOOL WINAPI BuildCommDCBW(
641 LPCWSTR devid, /* [in] The unicode device control string. */
642 LPDCB lpdcb) /* [out] The device control block to be updated. */
644 return BuildCommDCBAndTimeoutsW(devid,lpdcb,NULL);
647 static BOOL COMM_SetCommError(HANDLE handle, DWORD error)
651 SERVER_START_REQ( set_serial_info )
653 req->handle = handle;
654 req->flags = SERIALINFO_SET_ERROR;
655 req->commerror = error;
656 ret = !wine_server_call_err( req );
662 static BOOL COMM_GetCommError(HANDLE handle, LPDWORD lperror)
669 SERVER_START_REQ( get_serial_info )
671 req->handle = handle;
672 ret = !wine_server_call_err( req );
673 *lperror = reply->commerror;
680 /*****************************************************************************
681 * SetCommBreak (KERNEL32.@)
683 * Halts the transmission of characters to a communications device.
687 * True on success, and false if the communications device could not be found,
688 * the control is not supported.
692 * Only TIOCSBRK and TIOCCBRK are supported.
694 BOOL WINAPI SetCommBreak(
695 HANDLE handle) /* [in] The communictions device to suspend. */
697 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
700 fd = get_comm_fd( handle, GENERIC_READ );
701 if(fd<0) return FALSE;
702 result = ioctl(fd,TIOCSBRK,0);
703 release_comm_fd( handle, fd );
706 TRACE("ioctl failed\n");
707 SetLastError(ERROR_NOT_SUPPORTED);
712 FIXME("ioctl not available\n");
713 SetLastError(ERROR_NOT_SUPPORTED);
718 /*****************************************************************************
719 * ClearCommBreak (KERNEL32.@)
721 * Resumes character transmission from a communication device.
725 * True on success and false if the communications device could not be found.
729 * Only TIOCSBRK and TIOCCBRK are supported.
731 BOOL WINAPI ClearCommBreak(
732 HANDLE handle) /* [in] The halted communication device whose character transmission is to be resumed. */
734 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
737 fd = get_comm_fd( handle, GENERIC_READ );
738 if(fd<0) return FALSE;
739 result = ioctl(fd,TIOCCBRK,0);
740 release_comm_fd( handle, fd );
743 TRACE("ioctl failed\n");
744 SetLastError(ERROR_NOT_SUPPORTED);
749 FIXME("ioctl not available\n");
750 SetLastError(ERROR_NOT_SUPPORTED);
755 /*****************************************************************************
756 * EscapeCommFunction (KERNEL32.@)
758 * Directs a communication device to perform an extended function.
762 * True or requested data on successful completion of the command,
763 * false if the device is not present cannot execute the command
764 * or the command failed.
766 BOOL WINAPI EscapeCommFunction(
767 HANDLE handle, /* [in] The communication device to perform the extended function. */
768 UINT nFunction) /* [in] The extended function to be performed. */
770 int fd,direct=FALSE,result=FALSE;
773 TRACE("handle %p, function=%d\n", handle, nFunction);
774 fd = get_comm_fd( handle, GENERIC_READ );
775 if(fd<0) return FALSE;
777 if (tcgetattr(fd,&port) == -1) {
778 COMM_SetCommError(handle,CE_IOE);
779 release_comm_fd( handle, fd );
792 result= COMM_WhackModem(fd, ~TIOCM_DTR, 0);
800 result= COMM_WhackModem(fd, ~TIOCM_RTS, 0);
808 result= COMM_WhackModem(fd, 0, TIOCM_DTR);
816 result= COMM_WhackModem(fd, 0, TIOCM_RTS);
822 port.c_iflag |= IXOFF;
827 port.c_iflag |= IXON;
833 result = ioctl(fd,TIOCSBRK,0);
840 result = ioctl(fd,TIOCCBRK,0);
844 WARN("(handle=%p,nFunction=%d): Unknown function\n",
850 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
851 release_comm_fd( handle, fd );
852 COMM_SetCommError(handle,CE_IOE);
861 COMM_SetCommError(handle,CE_IOE);
866 release_comm_fd( handle, fd );
870 /********************************************************************
871 * PurgeComm (KERNEL32.@)
873 * Terminates pending operations and/or discards buffers on a
874 * communication resource.
878 * True on success and false if the communications handle is bad.
880 BOOL WINAPI PurgeComm(
881 HANDLE handle, /* [in] The communication resource to be purged. */
882 DWORD flags) /* [in] Flags for clear pending/buffer on input/output. */
886 TRACE("handle %p, flags %lx\n", handle, flags);
888 fd = get_comm_fd( handle, GENERIC_READ );
889 if(fd<0) return FALSE;
892 ** not exactly sure how these are different
893 ** Perhaps if we had our own internal queues, one flushes them
894 ** and the other flushes the kernel's buffers.
896 if(flags&PURGE_TXABORT)
897 tcflush(fd,TCOFLUSH);
898 if(flags&PURGE_RXABORT)
899 tcflush(fd,TCIFLUSH);
900 if(flags&PURGE_TXCLEAR)
901 tcflush(fd,TCOFLUSH);
902 if(flags&PURGE_RXCLEAR)
903 tcflush(fd,TCIFLUSH);
904 release_comm_fd( handle, fd );
909 /*****************************************************************************
910 * ClearCommError (KERNEL32.@)
912 * Enables further I/O operations on a communications resource after
913 * supplying error and current status information.
917 * True on success, false if the communication resource handle is bad.
919 BOOL WINAPI ClearCommError(
920 HANDLE handle, /* [in] The communication resource with the error. */
921 LPDWORD errors, /* [out] Flags indicating error the resource experienced. */
922 LPCOMSTAT lpStat) /* [out] The status of the communication resource. */
926 fd=get_comm_fd( handle, GENERIC_READ );
927 if(0>fd) return FALSE;
931 lpStat->fCtsHold = 0;
932 lpStat->fDsrHold = 0;
933 lpStat->fRlsdHold = 0;
934 lpStat->fXoffHold = 0;
935 lpStat->fXoffSent = 0;
938 lpStat->fReserved = 0;
941 if(ioctl(fd, TIOCOUTQ, &lpStat->cbOutQue))
942 WARN("ioctl returned error\n");
944 lpStat->cbOutQue = 0; /* FIXME: find a different way to find out */
948 if(ioctl(fd, TIOCINQ, &lpStat->cbInQue))
949 WARN("ioctl returned error\n");
952 TRACE("handle %p cbInQue = %ld cbOutQue = %ld\n",
953 handle, lpStat->cbInQue, lpStat->cbOutQue);
956 release_comm_fd( handle, fd );
958 COMM_GetCommError(handle, errors);
959 COMM_SetCommError(handle, 0);
964 /*****************************************************************************
965 * SetupComm (KERNEL32.@)
967 * Called after CreateFile to hint to the communication resource to use
968 * specified sizes for input and output buffers rather than the default values.
972 * True if successful, false if the communications resource handle is bad.
978 BOOL WINAPI SetupComm(
979 HANDLE handle, /* [in] The just created communication resource handle. */
980 DWORD insize, /* [in] The suggested size of the communication resources input buffer in bytes. */
981 DWORD outsize) /* [in] The suggested size of the communication resources output buffer in bytes. */
985 FIXME("insize %ld outsize %ld unimplemented stub\n", insize, outsize);
986 fd=get_comm_fd( handle, GENERIC_READ );
987 if(0>fd) return FALSE;
988 release_comm_fd( handle, fd );
992 /*****************************************************************************
993 * GetCommMask (KERNEL32.@)
995 * Obtain the events associated with a communication device that will cause
996 * a call WaitCommEvent to return.
1000 * True on success, fail on bad device handle etc.
1002 BOOL WINAPI GetCommMask(
1003 HANDLE handle, /* [in] The communications device. */
1004 LPDWORD evtmask) /* [out] The events which cause WaitCommEvent to return. */
1008 TRACE("handle %p, mask %p\n", handle, evtmask);
1010 SERVER_START_REQ( get_serial_info )
1012 req->handle = handle;
1013 if ((ret = !wine_server_call_err( req )))
1015 if (evtmask) *evtmask = reply->eventmask;
1022 /*****************************************************************************
1023 * SetCommMask (KERNEL32.@)
1025 * There be some things we need to hear about yon there communications device.
1026 * (Set which events associated with a communication device should cause
1027 * a call WaitCommEvent to return.)
1031 * True on success, false on bad handle etc.
1033 BOOL WINAPI SetCommMask(
1034 HANDLE handle, /* [in] The communications device. */
1035 DWORD evtmask) /* [in] The events that are to be monitored. */
1039 TRACE("handle %p, mask %lx\n", handle, evtmask);
1041 SERVER_START_REQ( set_serial_info )
1043 req->handle = handle;
1044 req->flags = SERIALINFO_SET_MASK;
1045 req->eventmask = evtmask;
1046 ret = !wine_server_call_err( req );
1052 /*****************************************************************************
1053 * SetCommState (KERNEL32.@)
1055 * Re-initializes all hardware and control settings of a communications device,
1056 * with values from a device control block without effecting the input and output
1061 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
1063 BOOL WINAPI SetCommState(
1064 HANDLE handle, /* [in] The communications device. */
1065 LPDCB lpdcb) /* [out] The device control block. */
1067 struct termios port;
1068 int fd, bytesize, stopbits;
1070 TRACE("handle %p, ptr %p\n", handle, lpdcb);
1071 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1072 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
1073 (lpdcb->StopBits == ONESTOPBIT)?1:
1074 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
1075 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
1076 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
1078 fd = get_comm_fd( handle, GENERIC_READ );
1079 if (fd < 0) return FALSE;
1081 if ((tcgetattr(fd,&port)) == -1) {
1082 int save_error = errno;
1083 COMM_SetCommError(handle,CE_IOE);
1084 release_comm_fd( handle, fd );
1085 ERR("tcgetattr error '%s'\n", strerror(save_error));
1089 port.c_cc[VMIN] = 0;
1090 port.c_cc[VTIME] = 1;
1093 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
1095 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
1097 port.c_iflag |= (IGNBRK);
1099 port.c_oflag &= ~(OPOST);
1101 port.c_cflag &= ~(HUPCL);
1102 port.c_cflag |= CLOCAL | CREAD;
1104 port.c_lflag &= ~(ICANON|ECHO|ISIG);
1105 port.c_lflag |= NOFLSH;
1108 port.c_cflag &= ~CBAUD;
1109 switch (lpdcb->BaudRate) {
1112 port.c_cflag |= B110;
1116 port.c_cflag |= B300;
1120 port.c_cflag |= B600;
1124 port.c_cflag |= B1200;
1128 port.c_cflag |= B2400;
1132 port.c_cflag |= B4800;
1136 port.c_cflag |= B9600;
1140 port.c_cflag |= B19200;
1144 port.c_cflag |= B38400;
1148 port.c_cflag |= B57600;
1153 port.c_cflag |= B115200;
1158 port.c_cflag |= B230400;
1163 port.c_cflag |= B460800;
1167 #if defined (HAVE_LINUX_SERIAL_H) && defined (TIOCSSERIAL)
1168 { struct serial_struct nuts;
1170 ioctl(fd, TIOCGSERIAL, &nuts);
1171 nuts.custom_divisor = nuts.baud_base / lpdcb->BaudRate;
1172 if (!(nuts.custom_divisor)) nuts.custom_divisor = 1;
1173 arby = nuts.baud_base / nuts.custom_divisor;
1174 nuts.flags &= ~ASYNC_SPD_MASK;
1175 nuts.flags |= ASYNC_SPD_CUST;
1176 WARN("You (or a program acting at your behest) have specified\n"
1177 "a non-standard baud rate %ld. Wine will set the rate to %d,\n"
1178 "which is as close as we can get by our present understanding of your\n"
1179 "hardware. I hope you know what you are doing. Any disruption Wine\n"
1180 "has caused to your linux system can be undone with setserial \n"
1181 "(see man setserial). If you have incapacitated a Hayes type modem,\n"
1182 "reset it and it will probably recover.\n", lpdcb->BaudRate, arby);
1183 ioctl(fd, TIOCSSERIAL, &nuts);
1184 port.c_cflag |= B38400;
1187 #endif /* Don't have linux/serial.h or lack TIOCSSERIAL */
1190 COMM_SetCommError(handle,IE_BAUDRATE);
1191 release_comm_fd( handle, fd );
1192 ERR("baudrate %ld\n",lpdcb->BaudRate);
1195 #elif !defined(__EMX__)
1196 switch (lpdcb->BaudRate) {
1199 port.c_ospeed = B110;
1203 port.c_ospeed = B300;
1207 port.c_ospeed = B600;
1211 port.c_ospeed = B1200;
1215 port.c_ospeed = B2400;
1219 port.c_ospeed = B4800;
1223 port.c_ospeed = B9600;
1227 port.c_ospeed = B19200;
1231 port.c_ospeed = B38400;
1236 port.c_cflag |= B57600;
1242 port.c_cflag |= B115200;
1247 port.c_cflag |= B230400;
1252 port.c_cflag |= B460800;
1256 COMM_SetCommError(handle,IE_BAUDRATE);
1257 release_comm_fd( handle, fd );
1258 ERR("baudrate %ld\n",lpdcb->BaudRate);
1261 port.c_ispeed = port.c_ospeed;
1263 bytesize=lpdcb->ByteSize;
1264 stopbits=lpdcb->StopBits;
1267 port.c_cflag &= ~(PARENB | PARODD | CMSPAR);
1269 port.c_cflag &= ~(PARENB | PARODD);
1272 port.c_iflag |= INPCK;
1274 port.c_iflag &= ~INPCK;
1275 switch (lpdcb->Parity) {
1279 port.c_cflag |= (PARENB | PARODD);
1282 port.c_cflag |= PARENB;
1285 /* Linux defines mark/space (stick) parity */
1287 port.c_cflag |= (PARENB | CMSPAR);
1290 port.c_cflag |= (PARENB | PARODD | CMSPAR);
1293 /* try the POSIX way */
1295 if( stopbits == ONESTOPBIT) {
1296 stopbits = TWOSTOPBITS;
1297 port.c_iflag &= ~INPCK;
1299 COMM_SetCommError(handle,IE_BYTESIZE);
1300 release_comm_fd( handle, fd );
1301 ERR("Cannot set MARK Parity\n");
1308 port.c_iflag &= ~INPCK;
1310 COMM_SetCommError(handle,IE_BYTESIZE);
1311 release_comm_fd( handle, fd );
1312 ERR("Cannot set SPACE Parity\n");
1318 COMM_SetCommError(handle,IE_BYTESIZE);
1319 release_comm_fd( handle, fd );
1325 port.c_cflag &= ~CSIZE;
1328 port.c_cflag |= CS5;
1331 port.c_cflag |= CS6;
1334 port.c_cflag |= CS7;
1337 port.c_cflag |= CS8;
1340 COMM_SetCommError(handle,IE_BYTESIZE);
1341 release_comm_fd( handle, fd );
1348 port.c_cflag &= ~CSTOPB;
1350 case ONE5STOPBITS: /* wil be selected if bytesize is 5 */
1352 port.c_cflag |= CSTOPB;
1355 COMM_SetCommError(handle,IE_BYTESIZE);
1356 release_comm_fd( handle, fd );
1361 if ( lpdcb->fOutxCtsFlow ||
1362 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1365 port.c_cflag |= CRTSCTS;
1370 if (lpdcb->fDtrControl == DTR_CONTROL_HANDSHAKE)
1372 WARN("DSR/DTR flow control not supported\n");
1376 port.c_iflag |= IXON;
1378 port.c_iflag &= ~IXON;
1380 port.c_iflag |= IXOFF;
1382 port.c_iflag &= ~IXOFF;
1384 if (tcsetattr(fd,TCSANOW,&port)==-1) { /* otherwise it hangs with pending input*/
1385 int save_error=errno;
1386 COMM_SetCommError(handle,CE_IOE);
1387 release_comm_fd( handle, fd );
1388 ERR("tcsetattr error '%s'\n", strerror(save_error));
1391 COMM_SetCommError(handle,0);
1392 release_comm_fd( handle, fd );
1398 /*****************************************************************************
1399 * GetCommState (KERNEL32.@)
1401 * Fills in a device control block with information from a communications device.
1405 * True on success, false if the communication device handle is bad etc
1409 * XonChar and XoffChar are not set.
1411 BOOL WINAPI GetCommState(
1412 HANDLE handle, /* [in] The communications device. */
1413 LPDCB lpdcb) /* [out] The device control block. */
1415 struct termios port;
1418 TRACE("handle %p, ptr %p\n", handle, lpdcb);
1420 fd = get_comm_fd( handle, GENERIC_READ );
1421 if (fd < 0) return FALSE;
1422 if (tcgetattr(fd, &port) == -1) {
1423 int save_error=errno;
1424 ERR("tcgetattr error '%s'\n", strerror(save_error));
1425 COMM_SetCommError(handle,CE_IOE);
1426 release_comm_fd( handle, fd );
1429 release_comm_fd( handle, fd );
1432 speed= (port.c_cflag & CBAUD);
1434 speed= (cfgetospeed(&port));
1438 lpdcb->BaudRate = 110;
1441 lpdcb->BaudRate = 300;
1444 lpdcb->BaudRate = 600;
1447 lpdcb->BaudRate = 1200;
1450 lpdcb->BaudRate = 2400;
1453 lpdcb->BaudRate = 4800;
1456 lpdcb->BaudRate = 9600;
1459 lpdcb->BaudRate = 19200;
1462 lpdcb->BaudRate = 38400;
1466 lpdcb->BaudRate = 57600;
1471 lpdcb->BaudRate = 115200;
1476 lpdcb->BaudRate = 230400;
1481 lpdcb->BaudRate = 460800;
1485 ERR("unknown speed %x \n",speed);
1488 switch (port.c_cflag & CSIZE) {
1490 lpdcb->ByteSize = 5;
1493 lpdcb->ByteSize = 6;
1496 lpdcb->ByteSize = 7;
1499 lpdcb->ByteSize = 8;
1502 ERR("unknown size %x \n",port.c_cflag & CSIZE);
1505 if(port.c_iflag & INPCK)
1506 lpdcb->fParity = TRUE;
1508 lpdcb->fParity = FALSE;
1510 switch (port.c_cflag & (PARENB | PARODD | CMSPAR))
1512 switch (port.c_cflag & (PARENB | PARODD))
1516 lpdcb->Parity = NOPARITY;
1519 lpdcb->Parity = EVENPARITY;
1521 case (PARENB | PARODD):
1522 lpdcb->Parity = ODDPARITY;
1525 case (PARENB | CMSPAR):
1526 lpdcb->Parity = MARKPARITY;
1528 case (PARENB | PARODD | CMSPAR):
1529 lpdcb->Parity = SPACEPARITY;
1534 if (port.c_cflag & CSTOPB)
1535 if(lpdcb->ByteSize == 5)
1536 lpdcb->StopBits = ONE5STOPBITS;
1538 lpdcb->StopBits = TWOSTOPBITS;
1540 lpdcb->StopBits = ONESTOPBIT;
1545 /* termios does not support DTR/DSR flow control */
1546 lpdcb->fOutxDsrFlow = 0;
1547 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
1551 if (port.c_cflag & CRTSCTS) {
1552 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
1553 lpdcb->fOutxCtsFlow = 1;
1557 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
1558 lpdcb->fOutxCtsFlow = 0;
1560 if (port.c_iflag & IXON)
1565 if (port.c_iflag & IXOFF)
1574 lpdcb->XoffLim = 10;
1576 COMM_SetCommError(handle,0);
1580 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1581 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
1582 (lpdcb->StopBits == ONESTOPBIT)?1:
1583 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
1584 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
1585 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
1587 if ( lpdcb->fOutxCtsFlow ||
1588 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1593 TRACE("~CRTSCTS\n");
1599 /*****************************************************************************
1600 * TransmitCommChar (KERNEL32.@)
1602 * Transmits a single character in front of any pending characters in the
1603 * output buffer. Usually used to send an interrupt character to a host.
1607 * True if the call succeeded, false if the previous command character to the
1608 * same device has not been sent yet the handle is bad etc.
1614 BOOL WINAPI TransmitCommChar(
1615 HANDLE hComm, /* [in] The communication device in need of a command character. */
1616 CHAR chTransmit) /* [in] The character to transmit. */
1618 WARN("(%p,'%c') not perfect!\n",hComm,chTransmit);
1620 return WriteFile( hComm, &chTransmit, 1, NULL, NULL );
1624 /*****************************************************************************
1625 * GetCommTimeouts (KERNEL32.@)
1627 * Obtains the request timeout values for the communications device.
1631 * True on success, false if communications device handle is bad
1632 * or the target structure is null.
1634 BOOL WINAPI GetCommTimeouts(
1635 HANDLE hComm, /* [in] The communications device. */
1636 LPCOMMTIMEOUTS lptimeouts) /* [out] The struct of request timeouts. */
1640 TRACE("(%p,%p)\n",hComm,lptimeouts);
1644 SetLastError(ERROR_INVALID_PARAMETER);
1648 SERVER_START_REQ( get_serial_info )
1650 req->handle = hComm;
1651 if ((ret = !wine_server_call_err( req )))
1653 lptimeouts->ReadIntervalTimeout = reply->readinterval;
1654 lptimeouts->ReadTotalTimeoutMultiplier = reply->readmult;
1655 lptimeouts->ReadTotalTimeoutConstant = reply->readconst;
1656 lptimeouts->WriteTotalTimeoutMultiplier = reply->writemult;
1657 lptimeouts->WriteTotalTimeoutConstant = reply->writeconst;
1664 /*****************************************************************************
1665 * SetCommTimeouts (KERNEL32.@)
1667 * Sets the timeouts used when reading and writing data to/from COMM ports.
1669 * ReadIntervalTimeout
1670 * - converted and passes to linux kernel as c_cc[VTIME]
1671 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1672 * - used in ReadFile to calculate GetOverlappedResult's timeout
1673 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1674 * - used in WriteFile to calculate GetOverlappedResult's timeout
1678 * True if the timeouts were set, false otherwise.
1680 BOOL WINAPI SetCommTimeouts(
1681 HANDLE hComm, /* [in] handle of COMM device */
1682 LPCOMMTIMEOUTS lptimeouts) /* [in] pointer to COMMTIMEOUTS structure */
1686 struct termios tios;
1688 TRACE("(%p,%p)\n",hComm,lptimeouts);
1692 SetLastError(ERROR_INVALID_PARAMETER);
1696 SERVER_START_REQ( set_serial_info )
1698 req->handle = hComm;
1699 req->flags = SERIALINFO_SET_TIMEOUTS;
1700 req->readinterval = lptimeouts->ReadIntervalTimeout ;
1701 req->readmult = lptimeouts->ReadTotalTimeoutMultiplier ;
1702 req->readconst = lptimeouts->ReadTotalTimeoutConstant ;
1703 req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ;
1704 req->writeconst = lptimeouts->WriteTotalTimeoutConstant ;
1705 ret = !wine_server_call_err( req );
1708 if (!ret) return FALSE;
1710 /* FIXME: move this stuff to the server */
1711 fd = get_comm_fd( hComm, GENERIC_READ );
1712 if (fd < 0) return FALSE;
1714 if (-1==tcgetattr(fd,&tios)) {
1715 FIXME("tcgetattr on fd %d failed!\n",fd);
1716 release_comm_fd( hComm, fd );
1720 /* VTIME is in 1/10 seconds */
1722 unsigned int ux_timeout;
1724 if(lptimeouts->ReadIntervalTimeout == 0) /* 0 means no timeout */
1730 ux_timeout = (lptimeouts->ReadIntervalTimeout+99)/100;
1733 ux_timeout = 1; /* must be at least some timeout */
1736 tios.c_cc[VTIME] = ux_timeout;
1739 if (-1==tcsetattr(fd,0,&tios)) {
1740 FIXME("tcsetattr on fd %d failed!\n",fd);
1741 release_comm_fd( hComm, fd );
1744 release_comm_fd( hComm, fd );
1748 /***********************************************************************
1749 * GetCommModemStatus (KERNEL32.@)
1751 * Obtains the four control register bits if supported by the hardware.
1755 * True if the communications handle was good and for hardware that
1756 * control register access, false otherwise.
1758 BOOL WINAPI GetCommModemStatus(
1759 HANDLE hFile, /* [in] The communications device. */
1760 LPDWORD lpModemStat) /* [out] The control register bits. */
1762 int fd,mstat, result=FALSE;
1766 fd = get_comm_fd( hFile, GENERIC_READ );
1769 result = ioctl(fd, TIOCMGET, &mstat);
1770 release_comm_fd( hFile, fd );
1773 WARN("ioctl failed\n");
1777 if (mstat & TIOCM_CTS)
1778 *lpModemStat |= MS_CTS_ON;
1781 if (mstat & TIOCM_DSR)
1782 *lpModemStat |= MS_DSR_ON;
1785 if (mstat & TIOCM_RNG)
1786 *lpModemStat |= MS_RING_ON;
1789 /*FIXME: Not really sure about RLSD UB 990810*/
1790 if (mstat & TIOCM_CAR)
1791 *lpModemStat |= MS_RLSD_ON;
1793 TRACE("%04x -> %s%s%s%s\n", mstat,
1794 (*lpModemStat &MS_RLSD_ON)?"MS_RLSD_ON ":"",
1795 (*lpModemStat &MS_RING_ON)?"MS_RING_ON ":"",
1796 (*lpModemStat &MS_DSR_ON)?"MS_DSR_ON ":"",
1797 (*lpModemStat &MS_CTS_ON)?"MS_CTS_ON ":"");
1804 /***********************************************************************
1805 * COMM_WaitCommEventService (INTERNAL)
1807 * This function is called while the client is waiting on the
1808 * server, so we can't make any server calls here.
1810 static void COMM_WaitCommEventService(async_private *ovp)
1812 async_commio *commio = (async_commio*) ovp;
1813 IO_STATUS_BLOCK* iosb = commio->async.iosb;
1815 TRACE("iosb %p\n",iosb);
1817 /* FIXME: detect other events */
1818 *commio->buffer = EV_RXCHAR;
1820 iosb->u.Status = STATUS_SUCCESS;
1824 /***********************************************************************
1825 * COMM_WaitCommEvent (INTERNAL)
1827 * This function must have an lpOverlapped.
1829 static BOOL COMM_WaitCommEvent(
1830 HANDLE hFile, /* [in] handle of comm port to wait for */
1831 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1832 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1839 SetLastError(ERROR_INVALID_PARAMETER);
1843 if(NtResetEvent(lpOverlapped->hEvent,NULL))
1846 fd = get_comm_fd( hFile, GENERIC_WRITE );
1850 ovp = (async_commio*) HeapAlloc(GetProcessHeap(), 0, sizeof (async_commio));
1853 release_comm_fd( hFile, fd );
1857 ovp->async.ops = &commio_async_ops;
1858 ovp->async.handle = hFile;
1859 ovp->async.fd = fd; /* FIXME */
1860 ovp->async.type = ASYNC_TYPE_WAIT;
1861 ovp->async.func = COMM_WaitCommEventService;
1862 ovp->async.event = lpOverlapped->hEvent;
1863 ovp->async.iosb = (IO_STATUS_BLOCK*)lpOverlapped;
1864 ovp->buffer = (char *)lpdwEvents;
1866 lpOverlapped->InternalHigh = 0;
1867 lpOverlapped->Offset = 0;
1868 lpOverlapped->OffsetHigh = 0;
1870 if ( !register_new_async (&ovp->async) )
1871 SetLastError( ERROR_IO_PENDING );
1876 /***********************************************************************
1877 * WaitCommEvent (KERNEL32.@)
1879 * Wait until something interesting happens on a COMM port.
1880 * Interesting things (events) are set by calling SetCommMask before
1881 * this function is called.
1884 * TRUE if successful
1887 * The set of detected events will be written to *lpdwEventMask
1888 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1891 * Only supports EV_RXCHAR and EV_TXEMPTY
1893 BOOL WINAPI WaitCommEvent(
1894 HANDLE hFile, /* [in] handle of comm port to wait for */
1895 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1896 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1901 TRACE("(%p %p %p )\n",hFile, lpdwEvents,lpOverlapped);
1904 return COMM_WaitCommEvent(hFile, lpdwEvents, lpOverlapped);
1906 /* if there is no overlapped structure, create our own */
1907 ov.hEvent = CreateEventA(NULL,FALSE,FALSE,NULL);
1909 COMM_WaitCommEvent(hFile, lpdwEvents, &ov);
1911 /* wait for the overlapped to complete */
1912 ret = GetOverlappedResult(hFile, &ov, NULL, TRUE);
1913 CloseHandle(ov.hEvent);
1918 /***********************************************************************
1919 * GetCommProperties (KERNEL32.@)
1921 * This function fills in a structure with the capabilities of the
1922 * communications port driver.
1926 * TRUE on success, FALSE on failure
1927 * If successful, the lpCommProp structure be filled in with
1928 * properties of the comm port.
1930 BOOL WINAPI GetCommProperties(
1931 HANDLE hFile, /* [in] handle of the comm port */
1932 LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */
1934 FIXME("(%p %p )\n",hFile,lpCommProp);
1939 * These values should be valid for LINUX's serial driver
1940 * FIXME: Perhaps they deserve an #ifdef LINUX
1942 memset(lpCommProp,0,sizeof(COMMPROP));
1943 lpCommProp->wPacketLength = 1;
1944 lpCommProp->wPacketVersion = 1;
1945 lpCommProp->dwServiceMask = SP_SERIALCOMM;
1946 lpCommProp->dwReserved1 = 0;
1947 lpCommProp->dwMaxTxQueue = 4096;
1948 lpCommProp->dwMaxRxQueue = 4096;
1949 lpCommProp->dwMaxBaud = BAUD_115200;
1950 lpCommProp->dwProvSubType = PST_RS232;
1951 lpCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS | PCF_TOTALTIMEOUTS;
1952 lpCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING |
1953 SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ;
1954 lpCommProp->dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 |
1955 BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
1956 BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ;
1957 lpCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ;
1958 lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
1959 PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE;
1960 lpCommProp->dwCurrentTxQueue = lpCommProp->dwMaxTxQueue;
1961 lpCommProp->dwCurrentRxQueue = lpCommProp->dwMaxRxQueue;
1966 /***********************************************************************
1968 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1969 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1970 * This is dependent on the type of COMM port, but since it is doubtful
1971 * anybody will get around to implementing support for fancy serial
1972 * ports in WINE, this is hardcoded for the time being. The name of
1973 * this DLL should be stored in and read from the system registry in
1974 * the hive HKEY_LOCAL_MACHINE, key
1975 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1976 * where ???? is the port number... that is determined by PNP
1977 * The DLL should be loaded when the COMM port is opened, and closed
1978 * when the COMM port is closed. - MJM 20 June 2000
1979 ***********************************************************************/
1980 static CHAR lpszSerialUI[] = "serialui.dll";
1983 /***********************************************************************
1984 * CommConfigDialogA (KERNEL32.@)
1986 * Raises a dialog that allows the user to configure a comm port.
1987 * Fills the COMMCONFIG struct with information specified by the user.
1988 * This function should call a similar routine in the COMM driver...
1992 * TRUE on success, FALSE on failure
1993 * If successful, the lpCommConfig structure will contain a new
1994 * configuration for the comm port, as specified by the user.
1997 * The library with the CommConfigDialog code is never unloaded.
1998 * Perhaps this should be done when the comm port is closed?
2000 BOOL WINAPI CommConfigDialogA(
2001 LPCSTR lpszDevice, /* [in] name of communications device */
2002 HANDLE hWnd, /* [in] parent window for the dialog */
2003 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
2005 FARPROC lpfnCommDialog;
2006 HMODULE hConfigModule;
2009 TRACE("(%p %p %p)\n",lpszDevice, hWnd, lpCommConfig);
2011 hConfigModule = LoadLibraryA(lpszSerialUI);
2015 lpfnCommDialog = GetProcAddress(hConfigModule, (LPCSTR)3L);
2020 r = lpfnCommDialog(lpszDevice,hWnd,lpCommConfig);
2022 /* UnloadLibrary(hConfigModule); */
2027 /***********************************************************************
2028 * CommConfigDialogW (KERNEL32.@)
2030 * see CommConfigDialogA for more info
2032 BOOL WINAPI CommConfigDialogW(
2033 LPCWSTR lpszDevice, /* [in] name of communications device */
2034 HANDLE hWnd, /* [in] parent window for the dialog */
2035 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
2040 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
2043 r = CommConfigDialogA(lpDeviceA,hWnd,lpCommConfig);
2044 HeapFree( GetProcessHeap(), 0, lpDeviceA );
2048 /***********************************************************************
2049 * GetCommConfig (KERNEL32.@)
2051 * Fill in the COMMCONFIG structure for the comm port hFile
2055 * TRUE on success, FALSE on failure
2056 * If successful, lpCommConfig contains the comm port configuration.
2061 BOOL WINAPI GetCommConfig(
2062 HANDLE hFile, /* [in] The communications device. */
2063 LPCOMMCONFIG lpCommConfig, /* [out] The communications configuration of the device (if it fits). */
2064 LPDWORD lpdwSize) /* [in/out] Initially the size of the configuration buffer/structure,
2065 afterwards the number of bytes copied to the buffer or
2066 the needed size of the buffer. */
2070 TRACE("(%p %p)\n",hFile,lpCommConfig);
2072 if(lpCommConfig == NULL)
2074 r = *lpdwSize < sizeof(COMMCONFIG); /* TRUE if not enough space */
2075 *lpdwSize = sizeof(COMMCONFIG);
2079 lpCommConfig->dwSize = sizeof(COMMCONFIG);
2080 lpCommConfig->wVersion = 1;
2081 lpCommConfig->wReserved = 0;
2082 r = GetCommState(hFile,&lpCommConfig->dcb);
2083 lpCommConfig->dwProviderSubType = PST_RS232;
2084 lpCommConfig->dwProviderOffset = 0;
2085 lpCommConfig->dwProviderSize = 0;
2090 /***********************************************************************
2091 * SetCommConfig (KERNEL32.@)
2093 * Sets the configuration of the communications device.
2097 * True on success, false if the handle was bad is not a communications device.
2099 BOOL WINAPI SetCommConfig(
2100 HANDLE hFile, /* [in] The communications device. */
2101 LPCOMMCONFIG lpCommConfig, /* [in] The desired configuration. */
2102 DWORD dwSize) /* [in] size of the lpCommConfig struct */
2104 TRACE("(%p %p)\n",hFile,lpCommConfig);
2105 return SetCommState(hFile,&lpCommConfig->dcb);
2108 /***********************************************************************
2109 * SetDefaultCommConfigA (KERNEL32.@)
2111 * Initializes the default configuration for the specified communication
2116 * True if the device was found and the defaults set, false otherwise
2118 BOOL WINAPI SetDefaultCommConfigA(
2119 LPCSTR lpszDevice, /* [in] The ascii name of the device targeted for configuration. */
2120 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
2121 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
2123 FARPROC lpfnSetDefaultCommConfig;
2124 HMODULE hConfigModule;
2127 TRACE("(%p %p %lx)\n",lpszDevice, lpCommConfig, dwSize);
2129 hConfigModule = LoadLibraryA(lpszSerialUI);
2133 lpfnSetDefaultCommConfig = GetProcAddress(hConfigModule, (LPCSTR)4L);
2135 if(! lpfnSetDefaultCommConfig)
2138 r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize);
2140 /* UnloadLibrary(hConfigModule); */
2146 /***********************************************************************
2147 * SetDefaultCommConfigW (KERNEL32.@)
2149 * Initializes the default configuration for the specified
2150 * communication device. (unicode)
2155 BOOL WINAPI SetDefaultCommConfigW(
2156 LPCWSTR lpszDevice, /* [in] The unicode name of the device targeted for configuration. */
2157 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
2158 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
2163 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice),lpCommConfig,dwSize);
2165 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
2168 r = SetDefaultCommConfigA(lpDeviceA,lpCommConfig,dwSize);
2169 HeapFree( GetProcessHeap(), 0, lpDeviceA );
2174 /***********************************************************************
2175 * GetDefaultCommConfigA (KERNEL32.@)
2177 * Acquires the default configuration of the specified communication device. (unicode)
2181 * True on successful reading of the default configuration,
2182 * if the device is not found or the buffer is too small.
2184 BOOL WINAPI GetDefaultCommConfigA(
2185 LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */
2186 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
2187 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
2188 afterwards the number of bytes copied to the buffer or
2189 the needed size of the buffer. */
2191 LPDCB lpdcb = &(lpCC->dcb);
2194 if (strncasecmp(lpszName,"COM",3)) {
2195 ERR("not implemented for <%s>\n", lpszName);
2199 TRACE("(%s %p %ld)\n", lpszName, lpCC, *lpdwSize );
2200 if (*lpdwSize < sizeof(COMMCONFIG)) {
2201 *lpdwSize = sizeof(COMMCONFIG);
2205 *lpdwSize = sizeof(COMMCONFIG);
2207 lpCC->dwSize = sizeof(COMMCONFIG);
2209 lpCC->dwProviderSubType = PST_RS232;
2210 lpCC->dwProviderOffset = 0L;
2211 lpCC->dwProviderSize = 0L;
2213 sprintf( temp, "COM%c:38400,n,8,1", lpszName[3]);
2214 FIXME("setting %s as default\n", temp);
2216 return BuildCommDCBA( temp, lpdcb);
2219 /**************************************************************************
2220 * GetDefaultCommConfigW (KERNEL32.@)
2222 * Acquires the default configuration of the specified communication device. (unicode)
2226 * True on successful reading of the default configuration,
2227 * if the device is not found or the buffer is too small.
2229 BOOL WINAPI GetDefaultCommConfigW(
2230 LPCWSTR lpszName, /* [in] The unicode name of the device targeted for configuration. */
2231 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
2232 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
2233 afterwards the number of bytes copied to the buffer or
2234 the needed size of the buffer. */
2239 TRACE("(%p,%p,%ld)\n",lpszName,lpCC,*lpdwSize);
2240 lpszNameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName );
2243 ret=GetDefaultCommConfigA(lpszNameA,lpCC,lpdwSize);
2244 HeapFree( GetProcessHeap(), 0, lpszNameA );