2 * DEC 93 Erik Bos <erik@xs4all.nl>
4 * Copyright 1996 Marcus Meissner
6 * Mar 31, 1999. Ove Kåven <ovek@arcticnet.no>
7 * - Implemented buffers and EnableCommNotification.
9 * Apr 3, 1999. Lawson Whitney <lawson_whitney@juno.com>
10 * - Fixed the modem control part of EscapeCommFunction16.
12 * Mar 3, 1999. Ove Kåven <ovek@arcticnet.no>
13 * - Use port indices instead of unixfds for win16
14 * - Moved things around (separated win16 and win32 routines)
15 * - Added some hints on how to implement buffers and EnableCommNotification.
17 * May 26, 1997. Fixes and comments by Rick Richardson <rick@dgii.com> [RER]
18 * - ptr->fd wasn't getting cleared on close.
19 * - GetCommEventMask() and GetCommError() didn't do much of anything.
20 * IMHO, they are still wrong, but they at least implement the RXCHAR
21 * event and return I/O queue sizes, which makes the app I'm interested
22 * in (analog devices EZKIT DSP development system) work.
24 * August 12, 1997. Take a bash at SetCommEventMask - Lawson Whitney
25 * <lawson_whitney@juno.com>
26 * July 6, 1998. Fixes and comments by Valentijn Sessink
27 * <vsessink@ic.uva.nl> [V]
28 * Oktober 98, Rein Klazes [RHK]
29 * A program that wants to monitor the modem status line (RLSD/DCD) may
30 * poll the modem status register in the commMask structure. I update the bit
31 * in GetCommError, waiting for an implementation of communication events.
36 #include "wine/port.h"
49 #ifdef HAVE_SYS_FILIO_H
50 # include <sys/filio.h>
52 #include <sys/ioctl.h>
55 #ifdef HAVE_SYS_MODEM_H
56 # include <sys/modem.h>
58 #ifdef HAVE_SYS_STRTIO_H
59 # include <sys/strtio.h>
65 #include "wine/server.h"
69 #include "debugtools.h"
71 #ifdef HAVE_LINUX_SERIAL_H
72 #include <linux/serial.h>
75 DEFAULT_DEBUG_CHANNEL(comm);
77 #if !defined(TIOCINQ) && defined(FIONREAD)
78 #define TIOCINQ FIONREAD
81 static int COMM_WhackModem(int fd, unsigned int andy, unsigned int orrie)
83 unsigned int mstat, okay;
84 okay = ioctl(fd, TIOCMGET, &mstat);
85 if (okay) return okay;
86 if (andy) mstat &= andy;
88 return ioctl(fd, TIOCMSET, &mstat);
91 /***********************************************************************
92 * COMM_BuildOldCommDCB (Internal)
94 * Build a DCB using the old style settings string eg: "COMx:96,n,8,1"
95 * We ignore the COM port index, since we can support more than 4 ports.
97 BOOL WINAPI COMM_BuildOldCommDCB(LPCSTR device, LPDCB lpdcb)
101 char *ptr, temp[256], last;
104 TRACE("(%s), ptr %p\n", device, lpdcb);
106 if (strncasecmp(device,"COM",3))
112 if ((*(device+4) != ':') && (*(device+4) != ' '))
115 strcpy(temp,device+5);
116 last=temp[strlen(temp)-1];
117 ptr = strtok(temp, ", ");
119 /* DOS/Windows only compares the first two numbers
120 * and assigns an appropriate baud rate.
121 * You can supply 961324245, it still returns 9600 ! */
124 WARN("Unknown baudrate string '%s' !\n", ptr);
125 return FALSE; /* error: less than 2 chars */
146 WARN("Unknown baudrate indicator %d !\n", rate);
150 lpdcb->BaudRate = rate;
151 TRACE("baudrate (%ld)\n", lpdcb->BaudRate);
153 ptr = strtok(NULL, ", ");
155 *ptr = toupper(*ptr);
157 TRACE("parity (%c)\n", *ptr);
158 lpdcb->fParity = TRUE;
161 lpdcb->Parity = NOPARITY;
162 lpdcb->fParity = FALSE;
165 lpdcb->Parity = EVENPARITY;
168 lpdcb->Parity = MARKPARITY;
171 lpdcb->Parity = ODDPARITY;
174 lpdcb->Parity = SPACEPARITY;
177 WARN("Unknown parity `%c'!\n", *ptr);
181 ptr = strtok(NULL, ", ");
182 TRACE("charsize (%c)\n", *ptr);
183 lpdcb->ByteSize = *ptr - '0';
185 ptr = strtok(NULL, ", ");
186 TRACE("stopbits (%c)\n", *ptr);
189 lpdcb->StopBits = ONESTOPBIT;
192 lpdcb->StopBits = TWOSTOPBITS;
195 WARN("Unknown # of stopbits `%c'!\n", *ptr);
202 lpdcb->fOutxCtsFlow = FALSE;
203 lpdcb->fOutxDsrFlow = FALSE;
204 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
205 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
206 } else if (last=='p') {
208 lpdcb->fOutX = FALSE;
209 lpdcb->fOutxCtsFlow = TRUE;
210 lpdcb->fOutxDsrFlow = FALSE;
211 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
212 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
215 lpdcb->fOutX = FALSE;
216 lpdcb->fOutxCtsFlow = FALSE;
217 lpdcb->fOutxDsrFlow = FALSE;
218 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
219 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
225 /**************************************************************************
226 * BuildCommDCBA (KERNEL32.@)
228 * Updates a device control block data structure with values from an
229 * ascii device control string. The device control string has two forms
230 * normal and extended, it must be exclusively in one or the other form.
234 * True on success, false on an malformed control string.
236 BOOL WINAPI BuildCommDCBA(
237 LPCSTR device, /* [in] The ascii device control string used to update the DCB. */
238 LPDCB lpdcb) /* [out] The device control block to be updated. */
240 return BuildCommDCBAndTimeoutsA(device,lpdcb,NULL);
243 /**************************************************************************
244 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
246 * Updates a device control block data structure with values from an
247 * ascii device control string. Taking time out values from a time outs
248 * struct if desired by the control string.
252 * True on success, false bad handles etc
254 BOOL WINAPI BuildCommDCBAndTimeoutsA(
255 LPCSTR device, /* [in] The ascii device control string. */
256 LPDCB lpdcb, /* [out] The device control block to be updated. */
257 LPCOMMTIMEOUTS lptimeouts) /* [in] The time outs to use if asked to set them by the control string. */
262 TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts);
264 if (!strncasecmp(device,"COM",3)) {
267 ERR("BUG! COM0 can't exist!\n");
270 if ((*(device+4)!=':') && (*(device+4)!=' '))
272 temp=(LPSTR)(device+5);
276 memset(lpdcb,0,sizeof (DCB));
277 lpdcb->DCBlength = sizeof(DCB);
278 if (strchr(temp,',')) { /* old style */
280 return COMM_BuildOldCommDCB(device,lpdcb);
282 ptr=strtok(temp," ");
287 if (!strncmp("baud=",ptr,5)) {
288 if (!sscanf(ptr+5,"%ld",&x))
289 WARN("Couldn't parse %s\n",ptr);
293 if (!strncmp("stop=",ptr,5)) {
294 if (!sscanf(ptr+5,"%ld",&x))
295 WARN("Couldn't parse %s\n",ptr);
299 if (!strncmp("data=",ptr,5)) {
300 if (!sscanf(ptr+5,"%ld",&x))
301 WARN("Couldn't parse %s\n",ptr);
305 if (!strncmp("parity=",ptr,7)) {
306 lpdcb->fParity = TRUE;
309 lpdcb->fParity = FALSE;
310 lpdcb->Parity = NOPARITY;
313 lpdcb->Parity = EVENPARITY;
316 lpdcb->Parity = ODDPARITY;
319 lpdcb->Parity = MARKPARITY;
322 lpdcb->Parity = SPACEPARITY;
328 ERR("Unhandled specifier '%s', please report.\n",ptr);
329 ptr=strtok(NULL," ");
331 if (lpdcb->BaudRate==110)
336 /**************************************************************************
337 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
339 * Updates a device control block data structure with values from an
340 * unicode device control string. Taking time out values from a time outs
341 * struct if desired by the control string.
345 * True on success, false bad handles etc.
347 BOOL WINAPI BuildCommDCBAndTimeoutsW(
348 LPCWSTR devid, /* [in] The unicode device control string. */
349 LPDCB lpdcb, /* [out] The device control block to be updated. */
350 LPCOMMTIMEOUTS lptimeouts) /* [in] The time outs to use if asked to set them by the control string. */
355 TRACE("(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
356 devidA = HEAP_strdupWtoA( GetProcessHeap(), 0, devid );
359 ret=BuildCommDCBAndTimeoutsA(devidA,lpdcb,lptimeouts);
360 HeapFree( GetProcessHeap(), 0, devidA );
365 /**************************************************************************
366 * BuildCommDCBW (KERNEL32.@)
368 * Updates a device control block structure with values from an
369 * unicode device control string. The device control string has two forms
370 * normal and extended, it must be exclusively in one or the other form.
374 * True on success, false on an malformed control string.
376 BOOL WINAPI BuildCommDCBW(
377 LPCWSTR devid, /* [in] The unicode device control string. */
378 LPDCB lpdcb) /* [out] The device control block to be updated. */
380 return BuildCommDCBAndTimeoutsW(devid,lpdcb,NULL);
383 static BOOL COMM_SetCommError(HANDLE handle, DWORD error)
387 SERVER_START_REQ( set_serial_info )
389 req->handle = handle;
390 req->flags = SERIALINFO_SET_ERROR;
391 req->commerror = error;
392 ret = !wine_server_call_err( req );
398 static BOOL COMM_GetCommError(HANDLE handle, LPDWORD lperror)
405 SERVER_START_REQ( get_serial_info )
407 req->handle = handle;
408 ret = !wine_server_call_err( req );
409 *lperror = reply->commerror;
416 /*****************************************************************************
417 * SetCommBreak (KERNEL32.@)
419 * Halts the transmission of characters to a communications device.
423 * True on success, and false if the communications device could not be found,
424 * the control is not supported.
428 * Only TIOCSBRK and TIOCCBRK are supported.
430 BOOL WINAPI SetCommBreak(
431 HANDLE handle) /* [in] The communictions device to suspend. */
433 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
436 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
438 TRACE("FILE_GetUnixHandle failed\n");
441 result = ioctl(fd,TIOCSBRK,0);
445 TRACE("ioctl failed\n");
446 SetLastError(ERROR_NOT_SUPPORTED);
451 FIXME("ioctl not available\n");
452 SetLastError(ERROR_NOT_SUPPORTED);
457 /*****************************************************************************
458 * ClearCommBreak (KERNEL32.@)
460 * Resumes character transmission from a communication device.
464 * True on success and false if the communications device could not be found.
468 * Only TIOCSBRK and TIOCCBRK are supported.
470 BOOL WINAPI ClearCommBreak(
471 HANDLE handle) /* [in] The halted communication device whose character transmission is to be resumed. */
473 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
476 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
478 TRACE("FILE_GetUnixHandle failed\n");
481 result = ioctl(fd,TIOCCBRK,0);
485 TRACE("ioctl failed\n");
486 SetLastError(ERROR_NOT_SUPPORTED);
491 FIXME("ioctl not available\n");
492 SetLastError(ERROR_NOT_SUPPORTED);
497 /*****************************************************************************
498 * EscapeCommFunction (KERNEL32.@)
500 * Directs a communication device to perform an extended function.
504 * True or requested data on successful completion of the command,
505 * false if the device is not present cannot execute the command
506 * or the command failed.
508 BOOL WINAPI EscapeCommFunction(
509 HANDLE handle, /* [in] The communication device to perform the extended function. */
510 UINT nFunction) /* [in] The extended function to be performed. */
512 int fd,direct=FALSE,result=FALSE;
515 TRACE("handle %d, function=%d\n", handle, nFunction);
516 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
518 FIXME("handle %d not found.\n",handle);
522 if (tcgetattr(fd,&port) == -1) {
523 COMM_SetCommError(handle,CE_IOE);
537 result= COMM_WhackModem(fd, ~TIOCM_DTR, 0);
545 result= COMM_WhackModem(fd, ~TIOCM_RTS, 0);
553 result= COMM_WhackModem(fd, 0, TIOCM_DTR);
561 result= COMM_WhackModem(fd, 0, TIOCM_RTS);
567 port.c_iflag |= IXOFF;
572 port.c_iflag |= IXON;
578 result = ioctl(fd,TIOCSBRK,0);
585 result = ioctl(fd,TIOCCBRK,0);
589 WARN("(handle=%d,nFunction=%d): Unknown function\n",
595 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
597 COMM_SetCommError(handle,CE_IOE);
606 COMM_SetCommError(handle,CE_IOE);
615 /********************************************************************
616 * PurgeComm (KERNEL32.@)
618 * Terminates pending operations and/or discards buffers on a
619 * communication resource.
623 * True on success and false if the communications handle is bad.
625 BOOL WINAPI PurgeComm(
626 HANDLE handle, /* [in] The communication resource to be purged. */
627 DWORD flags) /* [in] Flags for clear pending/buffer on input/output. */
631 TRACE("handle %d, flags %lx\n", handle, flags);
633 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
635 FIXME("no handle %d found\n",handle);
640 ** not exactly sure how these are different
641 ** Perhaps if we had our own internal queues, one flushes them
642 ** and the other flushes the kernel's buffers.
644 if(flags&PURGE_TXABORT)
645 tcflush(fd,TCOFLUSH);
646 if(flags&PURGE_RXABORT)
647 tcflush(fd,TCIFLUSH);
648 if(flags&PURGE_TXCLEAR)
649 tcflush(fd,TCOFLUSH);
650 if(flags&PURGE_RXCLEAR)
651 tcflush(fd,TCIFLUSH);
657 /*****************************************************************************
658 * ClearCommError (KERNEL32.@)
660 * Enables further I/O operations on a communications resource after
661 * supplying error and current status information.
665 * True on success, false if the communication resource handle is bad.
667 BOOL WINAPI ClearCommError(
668 HANDLE handle, /* [in] The communication resource with the error. */
669 LPDWORD errors, /* [out] Flags indicating error the resource experienced. */
670 LPCOMSTAT lpStat) /* [out] The status of the communication resource. */
674 fd=FILE_GetUnixHandle( handle, GENERIC_READ );
677 FIXME("no handle %d found\n",handle);
686 if(ioctl(fd, TIOCOUTQ, &lpStat->cbOutQue))
687 WARN("ioctl returned error\n");
689 lpStat->cbOutQue = 0; /* FIXME: find a different way to find out */
693 if(ioctl(fd, TIOCINQ, &lpStat->cbInQue))
694 WARN("ioctl returned error\n");
697 TRACE("handle %d cbInQue = %ld cbOutQue = %ld\n",
698 handle, lpStat->cbInQue, lpStat->cbOutQue);
703 COMM_GetCommError(handle, errors);
704 COMM_SetCommError(handle, 0);
709 /*****************************************************************************
710 * SetupComm (KERNEL32.@)
712 * Called after CreateFile to hint to the communication resource to use
713 * specified sizes for input and output buffers rather than the default values.
717 * True if successful, false if the communications resource handle is bad.
723 BOOL WINAPI SetupComm(
724 HANDLE handle, /* [in] The just created communication resource handle. */
725 DWORD insize, /* [in] The suggested size of the communication resources input buffer in bytes. */
726 DWORD outsize) /* [in] The suggested size of the communication resources output buffer in bytes. */
730 FIXME("insize %ld outsize %ld unimplemented stub\n", insize, outsize);
731 fd=FILE_GetUnixHandle( handle, GENERIC_READ );
733 FIXME("handle %d not found?\n",handle);
740 /*****************************************************************************
741 * GetCommMask (KERNEL32.@)
743 * Obtain the events associated with a communication device that will cause a call
744 * WaitCommEvent to return.
748 * True on success, fail on bad device handle etc.
750 BOOL WINAPI GetCommMask(
751 HANDLE handle, /* [in] The communications device. */
752 LPDWORD evtmask) /* [out] The events which cause WaitCommEvent to return. */
756 TRACE("handle %d, mask %p\n", handle, evtmask);
758 SERVER_START_REQ( get_serial_info )
760 req->handle = handle;
761 if ((ret = !wine_server_call_err( req )))
763 if (evtmask) *evtmask = reply->eventmask;
770 /*****************************************************************************
771 * SetCommMask (KERNEL32.@)
773 * There be some things we need to hear about yon there communications device.
774 * (Set which events associated with a communication device should cause
775 * a call WaitCommEvent to return.)
779 * True on success, false on bad handle etc.
781 BOOL WINAPI SetCommMask(
782 HANDLE handle, /* [in] The communications device. */
783 DWORD evtmask) /* [in] The events that to be monitored. */
787 TRACE("handle %d, mask %lx\n", handle, evtmask);
789 SERVER_START_REQ( set_serial_info )
791 req->handle = handle;
792 req->flags = SERIALINFO_SET_MASK;
793 req->eventmask = evtmask;
794 ret = !wine_server_call_err( req );
800 /*****************************************************************************
801 * SetCommState (KERNEL32.@)
803 * Re-initializes all hardware and control settings of a communications device,
804 * with values from a device control block without effecting the input and output
809 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
811 BOOL WINAPI SetCommState(
812 HANDLE handle, /* [in] The communications device. */
813 LPDCB lpdcb) /* [out] The device control block. */
816 int fd, bytesize, stopbits;
818 TRACE("handle %d, ptr %p\n", handle, lpdcb);
819 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
820 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
821 (lpdcb->StopBits == ONESTOPBIT)?1:
822 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
823 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
824 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
826 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
828 FIXME("no handle %d found\n",handle);
832 if ((tcgetattr(fd,&port)) == -1) {
833 int save_error = errno;
834 COMM_SetCommError(handle,CE_IOE);
836 ERR("tcgetattr error '%s'\n", strerror(save_error));
841 port.c_cc[VTIME] = 1;
844 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
846 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
848 port.c_iflag |= (IGNBRK);
850 port.c_oflag &= ~(OPOST);
852 port.c_cflag &= ~(HUPCL);
853 port.c_cflag |= CLOCAL | CREAD;
855 port.c_lflag &= ~(ICANON|ECHO|ISIG);
856 port.c_lflag |= NOFLSH;
859 port.c_cflag &= ~CBAUD;
860 switch (lpdcb->BaudRate) {
863 port.c_cflag |= B110;
867 port.c_cflag |= B300;
871 port.c_cflag |= B600;
875 port.c_cflag |= B1200;
879 port.c_cflag |= B2400;
883 port.c_cflag |= B4800;
887 port.c_cflag |= B9600;
891 port.c_cflag |= B19200;
895 port.c_cflag |= B38400;
899 port.c_cflag |= B57600;
904 port.c_cflag |= B115200;
909 port.c_cflag |= B230400;
914 port.c_cflag |= B460800;
918 #if defined (HAVE_LINUX_SERIAL_H) && defined (TIOCSSERIAL)
919 { struct serial_struct nuts;
921 ioctl(fd, TIOCGSERIAL, &nuts);
922 nuts.custom_divisor = nuts.baud_base / lpdcb->BaudRate;
923 if (!(nuts.custom_divisor)) nuts.custom_divisor = 1;
924 arby = nuts.baud_base / nuts.custom_divisor;
925 nuts.flags &= ~ASYNC_SPD_MASK;
926 nuts.flags |= ASYNC_SPD_CUST;
927 WARN("You (or a program acting at your behest) have specified\n"
928 "a non-standard baud rate %ld. Wine will set the rate to %d,\n"
929 "which is as close as we can get by our present understanding of your\n"
930 "hardware. I hope you know what you are doing. Any disruption Wine\n"
931 "has caused to your linux system can be undone with setserial \n"
932 "(see man setserial). If you have incapacitated a Hayes type modem,\n"
933 "reset it and it will probably recover.\n", lpdcb->BaudRate, arby);
934 ioctl(fd, TIOCSSERIAL, &nuts);
935 port.c_cflag |= B38400;
938 #endif /* Don't have linux/serial.h or lack TIOCSSERIAL */
941 COMM_SetCommError(handle,IE_BAUDRATE);
943 ERR("baudrate %ld\n",lpdcb->BaudRate);
946 #elif !defined(__EMX__)
947 switch (lpdcb->BaudRate) {
950 port.c_ospeed = B110;
954 port.c_ospeed = B300;
958 port.c_ospeed = B600;
962 port.c_ospeed = B1200;
966 port.c_ospeed = B2400;
970 port.c_ospeed = B4800;
974 port.c_ospeed = B9600;
978 port.c_ospeed = B19200;
982 port.c_ospeed = B38400;
985 COMM_SetCommError(handle,IE_BAUDRATE);
987 ERR("baudrate %ld\n",lpdcb->BaudRate);
990 port.c_ispeed = port.c_ospeed;
992 bytesize=lpdcb->ByteSize;
993 stopbits=lpdcb->StopBits;
996 port.c_cflag &= ~(PARENB | PARODD | CMSPAR);
998 port.c_cflag &= ~(PARENB | PARODD);
1001 port.c_iflag |= INPCK;
1003 port.c_iflag &= ~INPCK;
1004 switch (lpdcb->Parity) {
1008 port.c_cflag |= (PARENB | PARODD);
1011 port.c_cflag |= PARENB;
1014 /* Linux defines mark/space (stick) parity */
1016 port.c_cflag |= (PARENB | CMSPAR);
1019 port.c_cflag |= (PARENB | PARODD | CMSPAR);
1022 /* try the POSIX way */
1024 if( stopbits == ONESTOPBIT) {
1025 stopbits = TWOSTOPBITS;
1026 port.c_iflag &= ~INPCK;
1028 COMM_SetCommError(handle,IE_BYTESIZE);
1030 ERR("Cannot set MARK Parity\n");
1037 port.c_iflag &= ~INPCK;
1039 COMM_SetCommError(handle,IE_BYTESIZE);
1041 ERR("Cannot set SPACE Parity\n");
1047 COMM_SetCommError(handle,IE_BYTESIZE);
1054 port.c_cflag &= ~CSIZE;
1057 port.c_cflag |= CS5;
1060 port.c_cflag |= CS6;
1063 port.c_cflag |= CS7;
1066 port.c_cflag |= CS8;
1069 COMM_SetCommError(handle,IE_BYTESIZE);
1077 port.c_cflag &= ~CSTOPB;
1079 case ONE5STOPBITS: /* wil be selected if bytesize is 5 */
1081 port.c_cflag |= CSTOPB;
1084 COMM_SetCommError(handle,IE_BYTESIZE);
1090 if ( lpdcb->fOutxCtsFlow ||
1091 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1094 port.c_cflag |= CRTSCTS;
1099 if (lpdcb->fDtrControl == DTR_CONTROL_HANDSHAKE)
1101 WARN("DSR/DTR flow control not supported\n");
1105 port.c_iflag |= IXON;
1107 port.c_iflag &= ~IXON;
1109 port.c_iflag |= IXOFF;
1111 port.c_iflag &= ~IXOFF;
1113 if (tcsetattr(fd,TCSANOW,&port)==-1) { /* otherwise it hangs with pending input*/
1114 int save_error=errno;
1115 COMM_SetCommError(handle,CE_IOE);
1117 ERR("tcsetattr error '%s'\n", strerror(save_error));
1120 COMM_SetCommError(handle,0);
1127 /*****************************************************************************
1128 * GetCommState (KERNEL32.@)
1130 * Fills in a device control block with information from a communications device.
1134 * True on success, false if the communication device handle is bad etc
1138 * XonChar and XoffChar are not set.
1140 BOOL WINAPI GetCommState(
1141 HANDLE handle, /* [in] The communications device. */
1142 LPDCB lpdcb) /* [out] The device control block. */
1144 struct termios port;
1147 TRACE("handle %d, ptr %p\n", handle, lpdcb);
1149 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
1152 ERR("FILE_GetUnixHandle failed\n");
1155 if (tcgetattr(fd, &port) == -1) {
1156 int save_error=errno;
1157 ERR("tcgetattr error '%s'\n", strerror(save_error));
1158 COMM_SetCommError(handle,CE_IOE);
1165 speed= (port.c_cflag & CBAUD);
1167 speed= (cfgetospeed(&port));
1171 lpdcb->BaudRate = 110;
1174 lpdcb->BaudRate = 300;
1177 lpdcb->BaudRate = 600;
1180 lpdcb->BaudRate = 1200;
1183 lpdcb->BaudRate = 2400;
1186 lpdcb->BaudRate = 4800;
1189 lpdcb->BaudRate = 9600;
1192 lpdcb->BaudRate = 19200;
1195 lpdcb->BaudRate = 38400;
1199 lpdcb->BaudRate = 57600;
1204 lpdcb->BaudRate = 115200;
1209 lpdcb->BaudRate = 230400;
1214 lpdcb->BaudRate = 460800;
1218 ERR("unknown speed %x \n",speed);
1221 switch (port.c_cflag & CSIZE) {
1223 lpdcb->ByteSize = 5;
1226 lpdcb->ByteSize = 6;
1229 lpdcb->ByteSize = 7;
1232 lpdcb->ByteSize = 8;
1235 ERR("unknown size %x \n",port.c_cflag & CSIZE);
1238 if(port.c_iflag & INPCK)
1239 lpdcb->fParity = TRUE;
1241 lpdcb->fParity = FALSE;
1243 switch (port.c_cflag & (PARENB | PARODD | CMSPAR))
1245 switch (port.c_cflag & (PARENB | PARODD))
1249 lpdcb->Parity = NOPARITY;
1252 lpdcb->Parity = EVENPARITY;
1254 case (PARENB | PARODD):
1255 lpdcb->Parity = ODDPARITY;
1258 case (PARENB | CMSPAR):
1259 lpdcb->Parity = MARKPARITY;
1261 case (PARENB | PARODD | CMSPAR):
1262 lpdcb->Parity = SPACEPARITY;
1267 if (port.c_cflag & CSTOPB)
1268 if(lpdcb->ByteSize == 5)
1269 lpdcb->StopBits = ONE5STOPBITS;
1271 lpdcb->StopBits = TWOSTOPBITS;
1273 lpdcb->StopBits = ONESTOPBIT;
1278 /* termios does not support DTR/DSR flow control */
1279 lpdcb->fOutxDsrFlow = 0;
1280 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
1284 if (port.c_cflag & CRTSCTS) {
1285 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
1286 lpdcb->fOutxCtsFlow = 1;
1290 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
1291 lpdcb->fOutxCtsFlow = 0;
1293 if (port.c_iflag & IXON)
1298 if (port.c_iflag & IXOFF)
1307 lpdcb->XoffLim = 10;
1309 COMM_SetCommError(handle,0);
1313 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1314 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
1315 (lpdcb->StopBits == ONESTOPBIT)?1:
1316 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
1317 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
1318 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
1320 if ( lpdcb->fOutxCtsFlow ||
1321 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1326 TRACE("~CRTSCTS\n");
1332 /*****************************************************************************
1333 * TransmitCommChar (KERNEL32.@)
1335 * Transmits a single character in front of any pending characters in the
1336 * output buffer. Usually used to send an interrupt character to a host.
1340 * True if the call succeeded, false if the previous command character to the
1341 * same device has not been sent yet the handle is bad etc.
1347 BOOL WINAPI TransmitCommChar(
1348 HANDLE hComm, /* [in] The communication device in need of a command character. */
1349 CHAR chTransmit) /* [in] The character to transmit. */
1351 FIXME("(%x,'%c'), use win32 handle!\n",hComm,chTransmit);
1355 /*****************************************************************************
1356 * GetCommTimeouts (KERNEL32.@)
1358 * Obtains the request time out values for the communications device.
1362 * True on success, false if communications device handle is bad
1363 * or the target structure is null.
1365 BOOL WINAPI GetCommTimeouts(
1366 HANDLE hComm, /* [in] The communications device. */
1367 LPCOMMTIMEOUTS lptimeouts) /* [out] The struct of request time outs. */
1371 TRACE("(%x,%p)\n",hComm,lptimeouts);
1375 SetLastError(ERROR_INVALID_PARAMETER);
1379 SERVER_START_REQ( get_serial_info )
1381 req->handle = hComm;
1382 if ((ret = !wine_server_call_err( req )))
1384 lptimeouts->ReadIntervalTimeout = reply->readinterval;
1385 lptimeouts->ReadTotalTimeoutMultiplier = reply->readmult;
1386 lptimeouts->ReadTotalTimeoutConstant = reply->readconst;
1387 lptimeouts->WriteTotalTimeoutMultiplier = reply->writemult;
1388 lptimeouts->WriteTotalTimeoutConstant = reply->writeconst;
1395 /*****************************************************************************
1396 * SetCommTimeouts (KERNEL32.@)
1398 * Sets the timeouts used when reading and writing data to/from COMM ports.
1400 * ReadIntervalTimeout
1401 * - converted and passes to linux kernel as c_cc[VTIME]
1402 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1403 * - used in ReadFile to calculate GetOverlappedResult's timeout
1404 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1405 * - used in WriteFile to calculate GetOverlappedResult's timeout
1409 * True if the time outs were set, false otherwise.
1411 BOOL WINAPI SetCommTimeouts(
1412 HANDLE hComm, /* [in] handle of COMM device */
1413 LPCOMMTIMEOUTS lptimeouts) /* [in] pointer to COMMTIMEOUTS structure */
1417 struct termios tios;
1419 TRACE("(%x,%p)\n",hComm,lptimeouts);
1423 SetLastError(ERROR_INVALID_PARAMETER);
1427 SERVER_START_REQ( set_serial_info )
1429 req->handle = hComm;
1430 req->flags = SERIALINFO_SET_TIMEOUTS;
1431 req->readinterval = lptimeouts->ReadIntervalTimeout ;
1432 req->readmult = lptimeouts->ReadTotalTimeoutMultiplier ;
1433 req->readconst = lptimeouts->ReadTotalTimeoutConstant ;
1434 req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ;
1435 req->writeconst = lptimeouts->WriteTotalTimeoutConstant ;
1436 ret = !wine_server_call_err( req );
1439 if (!ret) return FALSE;
1441 /* FIXME: move this stuff to the server */
1442 fd = FILE_GetUnixHandle( hComm, GENERIC_READ );
1444 FIXME("no fd for handle = %0x!.\n",hComm);
1448 if (-1==tcgetattr(fd,&tios)) {
1449 FIXME("tcgetattr on fd %d failed!\n",fd);
1453 /* VTIME is in 1/10 seconds */
1455 unsigned int ux_timeout;
1457 if(lptimeouts->ReadIntervalTimeout == 0) /* 0 means no timeout */
1463 ux_timeout = (lptimeouts->ReadIntervalTimeout+99)/100;
1466 ux_timeout = 1; /* must be at least some timeout */
1469 tios.c_cc[VTIME] = ux_timeout;
1472 if (-1==tcsetattr(fd,0,&tios)) {
1473 FIXME("tcsetattr on fd %d failed!\n",fd);
1480 /***********************************************************************
1481 * GetCommModemStatus (KERNEL32.@)
1483 * Obtains the four control register bits if supported by the hardware.
1487 * True if the communications handle was good and for hardware that
1488 * control register access, false otherwise.
1490 BOOL WINAPI GetCommModemStatus(
1491 HANDLE hFile, /* [in] The communications device. */
1492 LPDWORD lpModemStat) /* [out] The control register bits. */
1494 int fd,mstat, result=FALSE;
1498 fd = FILE_GetUnixHandle( hFile, GENERIC_READ );
1501 result = ioctl(fd, TIOCMGET, &mstat);
1505 WARN("ioctl failed\n");
1509 if (mstat & TIOCM_CTS)
1510 *lpModemStat |= MS_CTS_ON;
1513 if (mstat & TIOCM_DSR)
1514 *lpModemStat |= MS_DSR_ON;
1517 if (mstat & TIOCM_RNG)
1518 *lpModemStat |= MS_RING_ON;
1521 /*FIXME: Not really sure about RLSD UB 990810*/
1522 if (mstat & TIOCM_CAR)
1523 *lpModemStat |= MS_RLSD_ON;
1525 TRACE("%04x -> %s%s%s%s\n", mstat,
1526 (*lpModemStat &MS_RLSD_ON)?"MS_RLSD_ON ":"",
1527 (*lpModemStat &MS_RING_ON)?"MS_RING_ON ":"",
1528 (*lpModemStat &MS_DSR_ON)?"MS_DSR_ON ":"",
1529 (*lpModemStat &MS_CTS_ON)?"MS_CTS_ON ":"");
1536 /***********************************************************************
1537 * COMM_WaitCommEventService (INTERNAL)
1539 * This function is called while the client is waiting on the
1540 * server, so we can't make any server calls here.
1542 static void COMM_WaitCommEventService(async_private *ovp)
1544 LPOVERLAPPED lpOverlapped = ovp->lpOverlapped;
1546 TRACE("overlapped %p\n",lpOverlapped);
1548 /* FIXME: detect other events */
1549 *ovp->buffer = EV_RXCHAR;
1551 lpOverlapped->Internal = STATUS_SUCCESS;
1555 /***********************************************************************
1556 * COMM_WaitCommEvent (INTERNAL)
1558 * This function must have an lpOverlapped.
1560 static BOOL COMM_WaitCommEvent(
1561 HANDLE hFile, /* [in] handle of comm port to wait for */
1562 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1563 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1570 SetLastError(ERROR_INVALID_PARAMETER);
1574 if(NtResetEvent(lpOverlapped->hEvent,NULL))
1577 lpOverlapped->Internal = STATUS_PENDING;
1578 lpOverlapped->InternalHigh = 0;
1579 lpOverlapped->Offset = 0;
1580 lpOverlapped->OffsetHigh = 0;
1582 fd = FILE_GetUnixHandle( hFile, GENERIC_WRITE );
1586 ovp = (async_private *) HeapAlloc(GetProcessHeap(), 0, sizeof (async_private));
1592 ovp->lpOverlapped = lpOverlapped;
1593 ovp->func = COMM_WaitCommEventService;
1594 ovp->buffer = (char *)lpdwEvents;
1597 ovp->completion_func = 0;
1598 ovp->type = ASYNC_TYPE_WAIT;
1599 ovp->handle = hFile;
1601 ovp->next = NtCurrentTeb()->pending_list;
1604 ovp->next->prev=ovp;
1605 NtCurrentTeb()->pending_list = ovp;
1607 /* start an ASYNCHRONOUS WaitCommEvent */
1608 SERVER_START_REQ( register_async )
1610 req->handle = hFile;
1611 req->overlapped = lpOverlapped;
1612 req->type = ASYNC_TYPE_WAIT;
1614 req->func = check_async_list;
1615 req->status = STATUS_PENDING;
1617 ret=wine_server_call_err(req);
1622 SetLastError(ERROR_IO_PENDING);
1627 /***********************************************************************
1628 * WaitCommEvent (KERNEL32.@)
1630 * Wait until something interesting happens on a COMM port.
1631 * Interesting things (events) are set by calling SetCommMask before
1632 * this function is called.
1635 * TRUE if successful
1638 * The set of detected events will be written to *lpdwEventMask
1639 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1642 * Only supports EV_RXCHAR and EV_TXEMPTY
1644 BOOL WINAPI WaitCommEvent(
1645 HANDLE hFile, /* [in] handle of comm port to wait for */
1646 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1647 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1652 TRACE("(%x %p %p )\n",hFile, lpdwEvents,lpOverlapped);
1655 return COMM_WaitCommEvent(hFile, lpdwEvents, lpOverlapped);
1657 /* if there is no overlapped structure, create our own */
1658 ov.hEvent = CreateEventA(NULL,FALSE,FALSE,NULL);
1660 COMM_WaitCommEvent(hFile, lpdwEvents, &ov);
1662 if(GetLastError()!=STATUS_PENDING)
1664 CloseHandle(ov.hEvent);
1668 /* wait for the overlapped to complete */
1669 ret = GetOverlappedResult(hFile, &ov, NULL, TRUE);
1670 CloseHandle(ov.hEvent);
1675 /***********************************************************************
1676 * GetCommProperties (KERNEL32.@)
1678 * This function fills in a structure with the capabilities of the
1679 * communications port driver.
1683 * TRUE on success, FALSE on failure
1684 * If successful, the lpCommProp structure be filled in with
1685 * properties of the comm port.
1687 BOOL WINAPI GetCommProperties(
1688 HANDLE hFile, /* [in] handle of the comm port */
1689 LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */
1691 FIXME("(%d %p )\n",hFile,lpCommProp);
1696 * These values should be valid for LINUX's serial driver
1697 * FIXME: Perhaps they deserve an #ifdef LINUX
1699 memset(lpCommProp,0,sizeof(COMMPROP));
1700 lpCommProp->wPacketLength = 1;
1701 lpCommProp->wPacketVersion = 1;
1702 lpCommProp->dwServiceMask = SP_SERIALCOMM;
1703 lpCommProp->dwReserved1 = 0;
1704 lpCommProp->dwMaxTxQueue = 4096;
1705 lpCommProp->dwMaxRxQueue = 4096;
1706 lpCommProp->dwMaxBaud = BAUD_115200;
1707 lpCommProp->dwProvSubType = PST_RS232;
1708 lpCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS ;
1709 lpCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING |
1710 SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ;
1711 lpCommProp->dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 |
1712 BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
1713 BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ;
1714 lpCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ;
1715 lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
1716 PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE;
1717 lpCommProp->dwCurrentTxQueue = lpCommProp->dwMaxTxQueue;
1718 lpCommProp->dwCurrentRxQueue = lpCommProp->dwMaxRxQueue;
1723 /***********************************************************************
1725 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1726 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1727 * This is dependent on the type of COMM port, but since it is doubtful
1728 * anybody will get around to implementing support for fancy serial
1729 * ports in WINE, this is hardcoded for the time being. The name of
1730 * this DLL should be stored in and read from the system registry in
1731 * the hive HKEY_LOCAL_MACHINE, key
1732 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1733 * where ???? is the port number... that is determined by PNP
1734 * The DLL should be loaded when the COMM port is opened, and closed
1735 * when the COMM port is closed. - MJM 20 June 2000
1736 ***********************************************************************/
1737 static CHAR lpszSerialUI[] = "serialui.dll";
1740 /***********************************************************************
1741 * CommConfigDialogA (KERNEL32.@)
1743 * Raises a dialog that allows the user to configure a comm port.
1744 * Fills the COMMCONFIG struct with information specified by the user.
1745 * This function should call a similar routine in the COMM driver...
1749 * TRUE on success, FALSE on failure
1750 * If successful, the lpCommConfig structure will contain a new
1751 * configuration for the comm port, as specified by the user.
1754 * The library with the CommConfigDialog code is never unloaded.
1755 * Perhaps this should be done when the comm port is closed?
1757 BOOL WINAPI CommConfigDialogA(
1758 LPCSTR lpszDevice, /* [in] name of communications device */
1759 HANDLE hWnd, /* [in] parent window for the dialog */
1760 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1762 FARPROC lpfnCommDialog;
1763 HMODULE hConfigModule;
1766 TRACE("(%p %x %p)\n",lpszDevice, hWnd, lpCommConfig);
1768 hConfigModule = LoadLibraryA(lpszSerialUI);
1772 lpfnCommDialog = GetProcAddress(hConfigModule, (LPCSTR)3L);
1777 r = lpfnCommDialog(lpszDevice,hWnd,lpCommConfig);
1779 /* UnloadLibrary(hConfigModule); */
1784 /***********************************************************************
1785 * CommConfigDialogW (KERNEL32.@)
1787 * see CommConfigDialogA for more info
1789 BOOL WINAPI CommConfigDialogW(
1790 LPCWSTR lpszDevice, /* [in] name of communications device */
1791 HANDLE hWnd, /* [in] parent window for the dialog */
1792 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1797 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
1800 r = CommConfigDialogA(lpDeviceA,hWnd,lpCommConfig);
1801 HeapFree( GetProcessHeap(), 0, lpDeviceA );
1805 /***********************************************************************
1806 * GetCommConfig (KERNEL32.@)
1808 * Fill in the COMMCONFIG structure for the comm port hFile
1812 * TRUE on success, FALSE on failure
1813 * If successful, lpCommConfig contains the comm port configuration.
1817 * The signature is missing a the parameter for the size of the COMMCONFIG
1818 * structure/buffer it should be
1819 * BOOL WINAPI GetCommConfig(HANDLE hFile,LPCOMMCONFIG lpCommConfig,LPDWORD lpdwSize)
1821 BOOL WINAPI GetCommConfig(
1822 HANDLE hFile, /* [in] The communications device. */
1823 LPCOMMCONFIG lpCommConfig, /* [out] The communications configuration of the device (if it fits). */
1824 LPDWORD lpdwSize) /* [in/out] Initially the size of the configuration buffer/structure,
1825 afterwards the number of bytes copied to the buffer or
1826 the needed size of the buffer. */
1830 TRACE("(%x %p)\n",hFile,lpCommConfig);
1832 if(lpCommConfig == NULL)
1835 r = *lpdwSize < sizeof(COMMCONFIG);
1836 *lpdwSize = sizeof(COMMCONFIG);
1840 lpCommConfig->dwSize = sizeof(COMMCONFIG);
1841 lpCommConfig->wVersion = 1;
1842 lpCommConfig->wReserved = 0;
1843 r = GetCommState(hFile,&lpCommConfig->dcb);
1844 lpCommConfig->dwProviderSubType = PST_RS232;
1845 lpCommConfig->dwProviderOffset = 0;
1846 lpCommConfig->dwProviderSize = 0;
1851 /***********************************************************************
1852 * SetCommConfig (KERNEL32.@)
1854 * Sets the configuration of the commications device.
1858 * True on success, false if the handle was bad is not a communications device.
1860 BOOL WINAPI SetCommConfig(
1861 HANDLE hFile, /* [in] The communications device. */
1862 LPCOMMCONFIG lpCommConfig, /* [in] The desired configuration. */
1863 DWORD dwSize) /* [in] size of the lpCommConfig struct */
1865 TRACE("(%x %p)\n",hFile,lpCommConfig);
1866 return SetCommState(hFile,&lpCommConfig->dcb);
1869 /***********************************************************************
1870 * SetDefaultCommConfigA (KERNEL32.@)
1872 * Initializes the default configuration for the specified communication
1877 * True if the device was found and the defaults set, false otherwise
1879 BOOL WINAPI SetDefaultCommConfigA(
1880 LPCSTR lpszDevice, /* [in] The ascii name of the device targeted for configuration. */
1881 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1882 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
1884 FARPROC lpfnSetDefaultCommConfig;
1885 HMODULE hConfigModule;
1888 TRACE("(%p %p %lx)\n",lpszDevice, lpCommConfig, dwSize);
1890 hConfigModule = LoadLibraryA(lpszSerialUI);
1894 lpfnSetDefaultCommConfig = GetProcAddress(hConfigModule, (LPCSTR)4L);
1896 if(! lpfnSetDefaultCommConfig)
1899 r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize);
1901 /* UnloadLibrary(hConfigModule); */
1907 /***********************************************************************
1908 * SetDefaultCommConfigW (KERNEL32.@)
1910 * Initializes the default configuration for the specified
1911 * communication device. (unicode)
1916 BOOL WINAPI SetDefaultCommConfigW(
1917 LPCWSTR lpszDevice, /* [in] The unicode name of the device targeted for configuration. */
1918 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1919 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
1924 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice),lpCommConfig,dwSize);
1926 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
1929 r = SetDefaultCommConfigA(lpDeviceA,lpCommConfig,dwSize);
1930 HeapFree( GetProcessHeap(), 0, lpDeviceA );
1935 /***********************************************************************
1936 * GetDefaultCommConfigA (KERNEL32.@)
1938 * Acquires the default configuration of the specified communication device. (unicode)
1942 * True on successful reading of the default configuration,
1943 * if the device is not found or the buffer is too small.
1945 BOOL WINAPI GetDefaultCommConfigA(
1946 LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */
1947 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
1948 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
1949 afterwards the number of bytes copied to the buffer or
1950 the needed size of the buffer. */
1952 LPDCB lpdcb = &(lpCC->dcb);
1955 if (strncasecmp(lpszName,"COM",3)) {
1956 ERR("not implemented for <%s>\n", lpszName);
1960 TRACE("(%s %p %ld)\n", lpszName, lpCC, *lpdwSize );
1961 if (*lpdwSize < sizeof(COMMCONFIG)) {
1962 *lpdwSize = sizeof(COMMCONFIG);
1966 *lpdwSize = sizeof(COMMCONFIG);
1968 lpCC->dwSize = sizeof(COMMCONFIG);
1970 lpCC->dwProviderSubType = PST_RS232;
1971 lpCC->dwProviderOffset = 0L;
1972 lpCC->dwProviderSize = 0L;
1974 (void) sprintf( temp, "COM%c:38400,n,8,1", lpszName[3]);
1975 FIXME("setting %s as default\n", temp);
1977 return BuildCommDCBA( temp, lpdcb);
1980 /**************************************************************************
1981 * GetDefaultCommConfigW (KERNEL32.@)
1983 * Acquires the default configuration of the specified communication device. (unicode)
1987 * True on successful reading of the default configuration,
1988 * if the device is not found or the buffer is too small.
1990 BOOL WINAPI GetDefaultCommConfigW(
1991 LPCWSTR lpszName, /* [in] The unicode name of the device targeted for configuration. */
1992 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
1993 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
1994 afterwards the number of bytes copied to the buffer or
1995 the needed size of the buffer. */
2000 TRACE("(%p,%p,%ld)\n",lpszName,lpCC,*lpdwSize);
2001 lpszNameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName );
2004 ret=GetDefaultCommConfigA(lpszNameA,lpCC,lpdwSize);
2005 HeapFree( GetProcessHeap(), 0, lpszNameA );