2 * DEC 93 Erik Bos <erik@xs4all.nl>
4 * Copyright 1996 Marcus Meissner
6 * Apr 3, 1999. Lawson Whitney <lawson_whitney@juno.com>
7 * - Fixed the modem control part of EscapeCommFunction16.
9 * Mar 31, 1999. Ove Kåven <ovek@arcticnet.no>
10 * - Implemented buffers and EnableCommNotification.
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 * Oktober 98, Rein Klazes [RHK]
18 * A program that wants to monitor the modem status line (RLSD/DCD) may
19 * poll the modem status register in the commMask structure. I update the bit
20 * in GetCommError, waiting for an implementation of communication events.
22 * July 6, 1998. Fixes and comments by Valentijn Sessink
23 * <vsessink@ic.uva.nl> [V]
25 * August 12, 1997. Take a bash at SetCommEventMask - Lawson Whitney
26 * <lawson_whitney@juno.com>
28 * May 26, 1997. Fixes and comments by Rick Richardson <rick@dgii.com> [RER]
29 * - ptr->fd wasn't getting cleared on close.
30 * - GetCommEventMask() and GetCommError() didn't do much of anything.
31 * IMHO, they are still wrong, but they at least implement the RXCHAR
32 * event and return I/O queue sizes, which makes the app I'm interested
33 * in (analog devices EZKIT DSP development system) work.
37 #include "wine/port.h"
50 #ifdef HAVE_SYS_FILIO_H
51 # include <sys/filio.h>
53 #include <sys/ioctl.h>
56 #ifdef HAVE_SYS_MODEM_H
57 # include <sys/modem.h>
59 #ifdef HAVE_SYS_STRTIO_H
60 # include <sys/strtio.h>
66 #include "wine/server.h"
70 #include "debugtools.h"
72 #ifdef HAVE_LINUX_SERIAL_H
73 #include <linux/serial.h>
76 DEFAULT_DEBUG_CHANNEL(comm);
78 #if !defined(TIOCINQ) && defined(FIONREAD)
79 #define TIOCINQ FIONREAD
82 static int COMM_WhackModem(int fd, unsigned int andy, unsigned int orrie)
84 unsigned int mstat, okay;
85 okay = ioctl(fd, TIOCMGET, &mstat);
86 if (okay) return okay;
87 if (andy) mstat &= andy;
89 return ioctl(fd, TIOCMSET, &mstat);
92 /***********************************************************************
93 * COMM_BuildOldCommDCB (Internal)
95 * Build a DCB using the old style settings string eg: "COMx:96,n,8,1"
96 * We ignore the COM port index, since we can support more than 4 ports.
98 BOOL WINAPI COMM_BuildOldCommDCB(LPCSTR device, LPDCB lpdcb)
100 /* "COM1:96,n,8,1" */
102 char *ptr, temp[256], last;
105 TRACE("(%s), ptr %p\n", device, lpdcb);
107 if (strncasecmp(device,"COM",3))
113 if ((*(device+4) != ':') && (*(device+4) != ' '))
116 strcpy(temp,device+5);
117 last=temp[strlen(temp)-1];
118 ptr = strtok(temp, ", ");
120 /* DOS/Windows only compares the first two numbers
121 * and assigns an appropriate baud rate.
122 * You can supply 961324245, it still returns 9600 ! */
125 WARN("Unknown baudrate string '%s' !\n", ptr);
126 return FALSE; /* error: less than 2 chars */
147 WARN("Unknown baudrate indicator %d !\n", rate);
151 lpdcb->BaudRate = rate;
152 TRACE("baudrate (%ld)\n", lpdcb->BaudRate);
154 ptr = strtok(NULL, ", ");
156 *ptr = toupper(*ptr);
158 TRACE("parity (%c)\n", *ptr);
159 lpdcb->fParity = TRUE;
162 lpdcb->Parity = NOPARITY;
163 lpdcb->fParity = FALSE;
166 lpdcb->Parity = EVENPARITY;
169 lpdcb->Parity = MARKPARITY;
172 lpdcb->Parity = ODDPARITY;
175 lpdcb->Parity = SPACEPARITY;
178 WARN("Unknown parity `%c'!\n", *ptr);
182 ptr = strtok(NULL, ", ");
183 TRACE("charsize (%c)\n", *ptr);
184 lpdcb->ByteSize = *ptr - '0';
186 ptr = strtok(NULL, ", ");
187 TRACE("stopbits (%c)\n", *ptr);
190 lpdcb->StopBits = ONESTOPBIT;
193 lpdcb->StopBits = TWOSTOPBITS;
196 WARN("Unknown # of stopbits `%c'!\n", *ptr);
203 lpdcb->fOutxCtsFlow = FALSE;
204 lpdcb->fOutxDsrFlow = FALSE;
205 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
206 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
207 } else if (last=='p') {
209 lpdcb->fOutX = FALSE;
210 lpdcb->fOutxCtsFlow = TRUE;
211 lpdcb->fOutxDsrFlow = FALSE;
212 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
213 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
216 lpdcb->fOutX = FALSE;
217 lpdcb->fOutxCtsFlow = FALSE;
218 lpdcb->fOutxDsrFlow = FALSE;
219 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
220 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
226 /**************************************************************************
227 * BuildCommDCBA (KERNEL32.@)
229 * Updates a device control block data structure with values from an
230 * ascii device control string. The device control string has two forms
231 * normal and extended, it must be exclusively in one or the other form.
235 * True on success, false on a malformed control string.
237 BOOL WINAPI BuildCommDCBA(
238 LPCSTR device, /* [in] The ascii device control string used to update the DCB. */
239 LPDCB lpdcb) /* [out] The device control block to be updated. */
241 return BuildCommDCBAndTimeoutsA(device,lpdcb,NULL);
244 /**************************************************************************
245 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
247 * Updates a device control block data structure with values from an
248 * ascii device control string. Taking timeout values from a timeouts
249 * struct if desired by the control string.
253 * True on success, false bad handles etc
255 BOOL WINAPI BuildCommDCBAndTimeoutsA(
256 LPCSTR device, /* [in] The ascii device control string. */
257 LPDCB lpdcb, /* [out] The device control block to be updated. */
258 LPCOMMTIMEOUTS lptimeouts) /* [in] The timeouts to use if asked to set them by the control string. */
263 TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts);
265 if (!strncasecmp(device,"COM",3)) {
268 ERR("BUG! COM0 can't exist!\n");
271 if ((*(device+4)!=':') && (*(device+4)!=' '))
273 temp=(LPSTR)(device+5);
277 memset(lpdcb,0,sizeof (DCB));
278 lpdcb->DCBlength = sizeof(DCB);
279 if (strchr(temp,',')) { /* old style */
281 return COMM_BuildOldCommDCB(device,lpdcb);
283 ptr=strtok(temp," ");
288 if (!strncmp("baud=",ptr,5)) {
289 if (!sscanf(ptr+5,"%ld",&x))
290 WARN("Couldn't parse %s\n",ptr);
294 if (!strncmp("stop=",ptr,5)) {
295 if (!sscanf(ptr+5,"%ld",&x))
296 WARN("Couldn't parse %s\n",ptr);
300 if (!strncmp("data=",ptr,5)) {
301 if (!sscanf(ptr+5,"%ld",&x))
302 WARN("Couldn't parse %s\n",ptr);
306 if (!strncmp("parity=",ptr,7)) {
307 lpdcb->fParity = TRUE;
310 lpdcb->fParity = FALSE;
311 lpdcb->Parity = NOPARITY;
314 lpdcb->Parity = EVENPARITY;
317 lpdcb->Parity = ODDPARITY;
320 lpdcb->Parity = MARKPARITY;
323 lpdcb->Parity = SPACEPARITY;
329 ERR("Unhandled specifier '%s', please report.\n",ptr);
330 ptr=strtok(NULL," ");
332 if (lpdcb->BaudRate==110)
337 /**************************************************************************
338 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
340 * Updates a device control block data structure with values from an
341 * unicode device control string. Taking timeout values from a timeouts
342 * struct if desired by the control string.
346 * True on success, false bad handles etc.
348 BOOL WINAPI BuildCommDCBAndTimeoutsW(
349 LPCWSTR devid, /* [in] The unicode device control string. */
350 LPDCB lpdcb, /* [out] The device control block to be updated. */
351 LPCOMMTIMEOUTS lptimeouts) /* [in] The timeouts to use if asked to set them by the control string. */
356 TRACE("(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
357 devidA = HEAP_strdupWtoA( GetProcessHeap(), 0, devid );
360 ret=BuildCommDCBAndTimeoutsA(devidA,lpdcb,lptimeouts);
361 HeapFree( GetProcessHeap(), 0, devidA );
366 /**************************************************************************
367 * BuildCommDCBW (KERNEL32.@)
369 * Updates a device control block structure with values from an
370 * unicode device control string. The device control string has two forms
371 * normal and extended, it must be exclusively in one or the other form.
375 * True on success, false on an malformed control string.
377 BOOL WINAPI BuildCommDCBW(
378 LPCWSTR devid, /* [in] The unicode device control string. */
379 LPDCB lpdcb) /* [out] The device control block to be updated. */
381 return BuildCommDCBAndTimeoutsW(devid,lpdcb,NULL);
384 static BOOL COMM_SetCommError(HANDLE handle, DWORD error)
388 SERVER_START_REQ( set_serial_info )
390 req->handle = handle;
391 req->flags = SERIALINFO_SET_ERROR;
392 req->commerror = error;
393 ret = !wine_server_call_err( req );
399 static BOOL COMM_GetCommError(HANDLE handle, LPDWORD lperror)
406 SERVER_START_REQ( get_serial_info )
408 req->handle = handle;
409 ret = !wine_server_call_err( req );
410 *lperror = reply->commerror;
417 /*****************************************************************************
418 * SetCommBreak (KERNEL32.@)
420 * Halts the transmission of characters to a communications device.
424 * True on success, and false if the communications device could not be found,
425 * the control is not supported.
429 * Only TIOCSBRK and TIOCCBRK are supported.
431 BOOL WINAPI SetCommBreak(
432 HANDLE handle) /* [in] The communictions device to suspend. */
434 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
437 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
439 TRACE("FILE_GetUnixHandle failed\n");
442 result = ioctl(fd,TIOCSBRK,0);
446 TRACE("ioctl failed\n");
447 SetLastError(ERROR_NOT_SUPPORTED);
452 FIXME("ioctl not available\n");
453 SetLastError(ERROR_NOT_SUPPORTED);
458 /*****************************************************************************
459 * ClearCommBreak (KERNEL32.@)
461 * Resumes character transmission from a communication device.
465 * True on success and false if the communications device could not be found.
469 * Only TIOCSBRK and TIOCCBRK are supported.
471 BOOL WINAPI ClearCommBreak(
472 HANDLE handle) /* [in] The halted communication device whose character transmission is to be resumed. */
474 #if defined(TIOCSBRK) && defined(TIOCCBRK) /* check if available for compilation */
477 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
479 TRACE("FILE_GetUnixHandle failed\n");
482 result = ioctl(fd,TIOCCBRK,0);
486 TRACE("ioctl failed\n");
487 SetLastError(ERROR_NOT_SUPPORTED);
492 FIXME("ioctl not available\n");
493 SetLastError(ERROR_NOT_SUPPORTED);
498 /*****************************************************************************
499 * EscapeCommFunction (KERNEL32.@)
501 * Directs a communication device to perform an extended function.
505 * True or requested data on successful completion of the command,
506 * false if the device is not present cannot execute the command
507 * or the command failed.
509 BOOL WINAPI EscapeCommFunction(
510 HANDLE handle, /* [in] The communication device to perform the extended function. */
511 UINT nFunction) /* [in] The extended function to be performed. */
513 int fd,direct=FALSE,result=FALSE;
516 TRACE("handle %d, function=%d\n", handle, nFunction);
517 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
519 FIXME("handle %d not found.\n",handle);
523 if (tcgetattr(fd,&port) == -1) {
524 COMM_SetCommError(handle,CE_IOE);
538 result= COMM_WhackModem(fd, ~TIOCM_DTR, 0);
546 result= COMM_WhackModem(fd, ~TIOCM_RTS, 0);
554 result= COMM_WhackModem(fd, 0, TIOCM_DTR);
562 result= COMM_WhackModem(fd, 0, TIOCM_RTS);
568 port.c_iflag |= IXOFF;
573 port.c_iflag |= IXON;
579 result = ioctl(fd,TIOCSBRK,0);
586 result = ioctl(fd,TIOCCBRK,0);
590 WARN("(handle=%d,nFunction=%d): Unknown function\n",
596 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
598 COMM_SetCommError(handle,CE_IOE);
607 COMM_SetCommError(handle,CE_IOE);
616 /********************************************************************
617 * PurgeComm (KERNEL32.@)
619 * Terminates pending operations and/or discards buffers on a
620 * communication resource.
624 * True on success and false if the communications handle is bad.
626 BOOL WINAPI PurgeComm(
627 HANDLE handle, /* [in] The communication resource to be purged. */
628 DWORD flags) /* [in] Flags for clear pending/buffer on input/output. */
632 TRACE("handle %d, flags %lx\n", handle, flags);
634 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
636 FIXME("no handle %d found\n",handle);
641 ** not exactly sure how these are different
642 ** Perhaps if we had our own internal queues, one flushes them
643 ** and the other flushes the kernel's buffers.
645 if(flags&PURGE_TXABORT)
646 tcflush(fd,TCOFLUSH);
647 if(flags&PURGE_RXABORT)
648 tcflush(fd,TCIFLUSH);
649 if(flags&PURGE_TXCLEAR)
650 tcflush(fd,TCOFLUSH);
651 if(flags&PURGE_RXCLEAR)
652 tcflush(fd,TCIFLUSH);
658 /*****************************************************************************
659 * ClearCommError (KERNEL32.@)
661 * Enables further I/O operations on a communications resource after
662 * supplying error and current status information.
666 * True on success, false if the communication resource handle is bad.
668 BOOL WINAPI ClearCommError(
669 HANDLE handle, /* [in] The communication resource with the error. */
670 LPDWORD errors, /* [out] Flags indicating error the resource experienced. */
671 LPCOMSTAT lpStat) /* [out] The status of the communication resource. */
675 fd=FILE_GetUnixHandle( handle, GENERIC_READ );
678 FIXME("no handle %d found\n",handle);
687 if(ioctl(fd, TIOCOUTQ, &lpStat->cbOutQue))
688 WARN("ioctl returned error\n");
690 lpStat->cbOutQue = 0; /* FIXME: find a different way to find out */
694 if(ioctl(fd, TIOCINQ, &lpStat->cbInQue))
695 WARN("ioctl returned error\n");
698 TRACE("handle %d cbInQue = %ld cbOutQue = %ld\n",
699 handle, lpStat->cbInQue, lpStat->cbOutQue);
704 COMM_GetCommError(handle, errors);
705 COMM_SetCommError(handle, 0);
710 /*****************************************************************************
711 * SetupComm (KERNEL32.@)
713 * Called after CreateFile to hint to the communication resource to use
714 * specified sizes for input and output buffers rather than the default values.
718 * True if successful, false if the communications resource handle is bad.
724 BOOL WINAPI SetupComm(
725 HANDLE handle, /* [in] The just created communication resource handle. */
726 DWORD insize, /* [in] The suggested size of the communication resources input buffer in bytes. */
727 DWORD outsize) /* [in] The suggested size of the communication resources output buffer in bytes. */
731 FIXME("insize %ld outsize %ld unimplemented stub\n", insize, outsize);
732 fd=FILE_GetUnixHandle( handle, GENERIC_READ );
734 FIXME("handle %d not found?\n",handle);
741 /*****************************************************************************
742 * GetCommMask (KERNEL32.@)
744 * Obtain the events associated with a communication device that will cause
745 * a call WaitCommEvent to return.
749 * True on success, fail on bad device handle etc.
751 BOOL WINAPI GetCommMask(
752 HANDLE handle, /* [in] The communications device. */
753 LPDWORD evtmask) /* [out] The events which cause WaitCommEvent to return. */
757 TRACE("handle %d, mask %p\n", handle, evtmask);
759 SERVER_START_REQ( get_serial_info )
761 req->handle = handle;
762 if ((ret = !wine_server_call_err( req )))
764 if (evtmask) *evtmask = reply->eventmask;
771 /*****************************************************************************
772 * SetCommMask (KERNEL32.@)
774 * There be some things we need to hear about yon there communications device.
775 * (Set which events associated with a communication device should cause
776 * a call WaitCommEvent to return.)
780 * True on success, false on bad handle etc.
782 BOOL WINAPI SetCommMask(
783 HANDLE handle, /* [in] The communications device. */
784 DWORD evtmask) /* [in] The events that are to be monitored. */
788 TRACE("handle %d, mask %lx\n", handle, evtmask);
790 SERVER_START_REQ( set_serial_info )
792 req->handle = handle;
793 req->flags = SERIALINFO_SET_MASK;
794 req->eventmask = evtmask;
795 ret = !wine_server_call_err( req );
801 /*****************************************************************************
802 * SetCommState (KERNEL32.@)
804 * Re-initializes all hardware and control settings of a communications device,
805 * with values from a device control block without effecting the input and output
810 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
812 BOOL WINAPI SetCommState(
813 HANDLE handle, /* [in] The communications device. */
814 LPDCB lpdcb) /* [out] The device control block. */
817 int fd, bytesize, stopbits;
819 TRACE("handle %d, ptr %p\n", handle, lpdcb);
820 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
821 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
822 (lpdcb->StopBits == ONESTOPBIT)?1:
823 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
824 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
825 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
827 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
829 FIXME("no handle %d found\n",handle);
833 if ((tcgetattr(fd,&port)) == -1) {
834 int save_error = errno;
835 COMM_SetCommError(handle,CE_IOE);
837 ERR("tcgetattr error '%s'\n", strerror(save_error));
842 port.c_cc[VTIME] = 1;
845 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
847 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
849 port.c_iflag |= (IGNBRK);
851 port.c_oflag &= ~(OPOST);
853 port.c_cflag &= ~(HUPCL);
854 port.c_cflag |= CLOCAL | CREAD;
856 port.c_lflag &= ~(ICANON|ECHO|ISIG);
857 port.c_lflag |= NOFLSH;
860 port.c_cflag &= ~CBAUD;
861 switch (lpdcb->BaudRate) {
864 port.c_cflag |= B110;
868 port.c_cflag |= B300;
872 port.c_cflag |= B600;
876 port.c_cflag |= B1200;
880 port.c_cflag |= B2400;
884 port.c_cflag |= B4800;
888 port.c_cflag |= B9600;
892 port.c_cflag |= B19200;
896 port.c_cflag |= B38400;
900 port.c_cflag |= B57600;
905 port.c_cflag |= B115200;
910 port.c_cflag |= B230400;
915 port.c_cflag |= B460800;
919 #if defined (HAVE_LINUX_SERIAL_H) && defined (TIOCSSERIAL)
920 { struct serial_struct nuts;
922 ioctl(fd, TIOCGSERIAL, &nuts);
923 nuts.custom_divisor = nuts.baud_base / lpdcb->BaudRate;
924 if (!(nuts.custom_divisor)) nuts.custom_divisor = 1;
925 arby = nuts.baud_base / nuts.custom_divisor;
926 nuts.flags &= ~ASYNC_SPD_MASK;
927 nuts.flags |= ASYNC_SPD_CUST;
928 WARN("You (or a program acting at your behest) have specified\n"
929 "a non-standard baud rate %ld. Wine will set the rate to %d,\n"
930 "which is as close as we can get by our present understanding of your\n"
931 "hardware. I hope you know what you are doing. Any disruption Wine\n"
932 "has caused to your linux system can be undone with setserial \n"
933 "(see man setserial). If you have incapacitated a Hayes type modem,\n"
934 "reset it and it will probably recover.\n", lpdcb->BaudRate, arby);
935 ioctl(fd, TIOCSSERIAL, &nuts);
936 port.c_cflag |= B38400;
939 #endif /* Don't have linux/serial.h or lack TIOCSSERIAL */
942 COMM_SetCommError(handle,IE_BAUDRATE);
944 ERR("baudrate %ld\n",lpdcb->BaudRate);
947 #elif !defined(__EMX__)
948 switch (lpdcb->BaudRate) {
951 port.c_ospeed = B110;
955 port.c_ospeed = B300;
959 port.c_ospeed = B600;
963 port.c_ospeed = B1200;
967 port.c_ospeed = B2400;
971 port.c_ospeed = B4800;
975 port.c_ospeed = B9600;
979 port.c_ospeed = B19200;
983 port.c_ospeed = B38400;
986 COMM_SetCommError(handle,IE_BAUDRATE);
988 ERR("baudrate %ld\n",lpdcb->BaudRate);
991 port.c_ispeed = port.c_ospeed;
993 bytesize=lpdcb->ByteSize;
994 stopbits=lpdcb->StopBits;
997 port.c_cflag &= ~(PARENB | PARODD | CMSPAR);
999 port.c_cflag &= ~(PARENB | PARODD);
1002 port.c_iflag |= INPCK;
1004 port.c_iflag &= ~INPCK;
1005 switch (lpdcb->Parity) {
1009 port.c_cflag |= (PARENB | PARODD);
1012 port.c_cflag |= PARENB;
1015 /* Linux defines mark/space (stick) parity */
1017 port.c_cflag |= (PARENB | CMSPAR);
1020 port.c_cflag |= (PARENB | PARODD | CMSPAR);
1023 /* try the POSIX way */
1025 if( stopbits == ONESTOPBIT) {
1026 stopbits = TWOSTOPBITS;
1027 port.c_iflag &= ~INPCK;
1029 COMM_SetCommError(handle,IE_BYTESIZE);
1031 ERR("Cannot set MARK Parity\n");
1038 port.c_iflag &= ~INPCK;
1040 COMM_SetCommError(handle,IE_BYTESIZE);
1042 ERR("Cannot set SPACE Parity\n");
1048 COMM_SetCommError(handle,IE_BYTESIZE);
1055 port.c_cflag &= ~CSIZE;
1058 port.c_cflag |= CS5;
1061 port.c_cflag |= CS6;
1064 port.c_cflag |= CS7;
1067 port.c_cflag |= CS8;
1070 COMM_SetCommError(handle,IE_BYTESIZE);
1078 port.c_cflag &= ~CSTOPB;
1080 case ONE5STOPBITS: /* wil be selected if bytesize is 5 */
1082 port.c_cflag |= CSTOPB;
1085 COMM_SetCommError(handle,IE_BYTESIZE);
1091 if ( lpdcb->fOutxCtsFlow ||
1092 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1095 port.c_cflag |= CRTSCTS;
1100 if (lpdcb->fDtrControl == DTR_CONTROL_HANDSHAKE)
1102 WARN("DSR/DTR flow control not supported\n");
1106 port.c_iflag |= IXON;
1108 port.c_iflag &= ~IXON;
1110 port.c_iflag |= IXOFF;
1112 port.c_iflag &= ~IXOFF;
1114 if (tcsetattr(fd,TCSANOW,&port)==-1) { /* otherwise it hangs with pending input*/
1115 int save_error=errno;
1116 COMM_SetCommError(handle,CE_IOE);
1118 ERR("tcsetattr error '%s'\n", strerror(save_error));
1121 COMM_SetCommError(handle,0);
1128 /*****************************************************************************
1129 * GetCommState (KERNEL32.@)
1131 * Fills in a device control block with information from a communications device.
1135 * True on success, false if the communication device handle is bad etc
1139 * XonChar and XoffChar are not set.
1141 BOOL WINAPI GetCommState(
1142 HANDLE handle, /* [in] The communications device. */
1143 LPDCB lpdcb) /* [out] The device control block. */
1145 struct termios port;
1148 TRACE("handle %d, ptr %p\n", handle, lpdcb);
1150 fd = FILE_GetUnixHandle( handle, GENERIC_READ );
1153 ERR("FILE_GetUnixHandle failed\n");
1156 if (tcgetattr(fd, &port) == -1) {
1157 int save_error=errno;
1158 ERR("tcgetattr error '%s'\n", strerror(save_error));
1159 COMM_SetCommError(handle,CE_IOE);
1166 speed= (port.c_cflag & CBAUD);
1168 speed= (cfgetospeed(&port));
1172 lpdcb->BaudRate = 110;
1175 lpdcb->BaudRate = 300;
1178 lpdcb->BaudRate = 600;
1181 lpdcb->BaudRate = 1200;
1184 lpdcb->BaudRate = 2400;
1187 lpdcb->BaudRate = 4800;
1190 lpdcb->BaudRate = 9600;
1193 lpdcb->BaudRate = 19200;
1196 lpdcb->BaudRate = 38400;
1200 lpdcb->BaudRate = 57600;
1205 lpdcb->BaudRate = 115200;
1210 lpdcb->BaudRate = 230400;
1215 lpdcb->BaudRate = 460800;
1219 ERR("unknown speed %x \n",speed);
1222 switch (port.c_cflag & CSIZE) {
1224 lpdcb->ByteSize = 5;
1227 lpdcb->ByteSize = 6;
1230 lpdcb->ByteSize = 7;
1233 lpdcb->ByteSize = 8;
1236 ERR("unknown size %x \n",port.c_cflag & CSIZE);
1239 if(port.c_iflag & INPCK)
1240 lpdcb->fParity = TRUE;
1242 lpdcb->fParity = FALSE;
1244 switch (port.c_cflag & (PARENB | PARODD | CMSPAR))
1246 switch (port.c_cflag & (PARENB | PARODD))
1250 lpdcb->Parity = NOPARITY;
1253 lpdcb->Parity = EVENPARITY;
1255 case (PARENB | PARODD):
1256 lpdcb->Parity = ODDPARITY;
1259 case (PARENB | CMSPAR):
1260 lpdcb->Parity = MARKPARITY;
1262 case (PARENB | PARODD | CMSPAR):
1263 lpdcb->Parity = SPACEPARITY;
1268 if (port.c_cflag & CSTOPB)
1269 if(lpdcb->ByteSize == 5)
1270 lpdcb->StopBits = ONE5STOPBITS;
1272 lpdcb->StopBits = TWOSTOPBITS;
1274 lpdcb->StopBits = ONESTOPBIT;
1279 /* termios does not support DTR/DSR flow control */
1280 lpdcb->fOutxDsrFlow = 0;
1281 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
1285 if (port.c_cflag & CRTSCTS) {
1286 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
1287 lpdcb->fOutxCtsFlow = 1;
1291 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
1292 lpdcb->fOutxCtsFlow = 0;
1294 if (port.c_iflag & IXON)
1299 if (port.c_iflag & IXOFF)
1308 lpdcb->XoffLim = 10;
1310 COMM_SetCommError(handle,0);
1314 TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
1315 lpdcb->ByteSize,lpdcb->BaudRate,lpdcb->fParity, lpdcb->Parity,
1316 (lpdcb->StopBits == ONESTOPBIT)?1:
1317 (lpdcb->StopBits == TWOSTOPBITS)?2:0);
1318 TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
1319 (lpdcb->fOutX)?"IXOFF":"~IXOFF");
1321 if ( lpdcb->fOutxCtsFlow ||
1322 lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
1327 TRACE("~CRTSCTS\n");
1333 /*****************************************************************************
1334 * TransmitCommChar (KERNEL32.@)
1336 * Transmits a single character in front of any pending characters in the
1337 * output buffer. Usually used to send an interrupt character to a host.
1341 * True if the call succeeded, false if the previous command character to the
1342 * same device has not been sent yet the handle is bad etc.
1348 BOOL WINAPI TransmitCommChar(
1349 HANDLE hComm, /* [in] The communication device in need of a command character. */
1350 CHAR chTransmit) /* [in] The character to transmit. */
1352 FIXME("(%x,'%c'), stub ! Use win32 handle!\n",hComm,chTransmit);
1356 /*****************************************************************************
1357 * GetCommTimeouts (KERNEL32.@)
1359 * Obtains the request timeout values for the communications device.
1363 * True on success, false if communications device handle is bad
1364 * or the target structure is null.
1366 BOOL WINAPI GetCommTimeouts(
1367 HANDLE hComm, /* [in] The communications device. */
1368 LPCOMMTIMEOUTS lptimeouts) /* [out] The struct of request timeouts. */
1372 TRACE("(%x,%p)\n",hComm,lptimeouts);
1376 SetLastError(ERROR_INVALID_PARAMETER);
1380 SERVER_START_REQ( get_serial_info )
1382 req->handle = hComm;
1383 if ((ret = !wine_server_call_err( req )))
1385 lptimeouts->ReadIntervalTimeout = reply->readinterval;
1386 lptimeouts->ReadTotalTimeoutMultiplier = reply->readmult;
1387 lptimeouts->ReadTotalTimeoutConstant = reply->readconst;
1388 lptimeouts->WriteTotalTimeoutMultiplier = reply->writemult;
1389 lptimeouts->WriteTotalTimeoutConstant = reply->writeconst;
1396 /*****************************************************************************
1397 * SetCommTimeouts (KERNEL32.@)
1399 * Sets the timeouts used when reading and writing data to/from COMM ports.
1401 * ReadIntervalTimeout
1402 * - converted and passes to linux kernel as c_cc[VTIME]
1403 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1404 * - used in ReadFile to calculate GetOverlappedResult's timeout
1405 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1406 * - used in WriteFile to calculate GetOverlappedResult's timeout
1410 * True if the timeouts were set, false otherwise.
1412 BOOL WINAPI SetCommTimeouts(
1413 HANDLE hComm, /* [in] handle of COMM device */
1414 LPCOMMTIMEOUTS lptimeouts) /* [in] pointer to COMMTIMEOUTS structure */
1418 struct termios tios;
1420 TRACE("(%x,%p)\n",hComm,lptimeouts);
1424 SetLastError(ERROR_INVALID_PARAMETER);
1428 SERVER_START_REQ( set_serial_info )
1430 req->handle = hComm;
1431 req->flags = SERIALINFO_SET_TIMEOUTS;
1432 req->readinterval = lptimeouts->ReadIntervalTimeout ;
1433 req->readmult = lptimeouts->ReadTotalTimeoutMultiplier ;
1434 req->readconst = lptimeouts->ReadTotalTimeoutConstant ;
1435 req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ;
1436 req->writeconst = lptimeouts->WriteTotalTimeoutConstant ;
1437 ret = !wine_server_call_err( req );
1440 if (!ret) return FALSE;
1442 /* FIXME: move this stuff to the server */
1443 fd = FILE_GetUnixHandle( hComm, GENERIC_READ );
1445 FIXME("no fd for handle = %0x!.\n",hComm);
1449 if (-1==tcgetattr(fd,&tios)) {
1450 FIXME("tcgetattr on fd %d failed!\n",fd);
1454 /* VTIME is in 1/10 seconds */
1456 unsigned int ux_timeout;
1458 if(lptimeouts->ReadIntervalTimeout == 0) /* 0 means no timeout */
1464 ux_timeout = (lptimeouts->ReadIntervalTimeout+99)/100;
1467 ux_timeout = 1; /* must be at least some timeout */
1470 tios.c_cc[VTIME] = ux_timeout;
1473 if (-1==tcsetattr(fd,0,&tios)) {
1474 FIXME("tcsetattr on fd %d failed!\n",fd);
1481 /***********************************************************************
1482 * GetCommModemStatus (KERNEL32.@)
1484 * Obtains the four control register bits if supported by the hardware.
1488 * True if the communications handle was good and for hardware that
1489 * control register access, false otherwise.
1491 BOOL WINAPI GetCommModemStatus(
1492 HANDLE hFile, /* [in] The communications device. */
1493 LPDWORD lpModemStat) /* [out] The control register bits. */
1495 int fd,mstat, result=FALSE;
1499 fd = FILE_GetUnixHandle( hFile, GENERIC_READ );
1502 result = ioctl(fd, TIOCMGET, &mstat);
1506 WARN("ioctl failed\n");
1510 if (mstat & TIOCM_CTS)
1511 *lpModemStat |= MS_CTS_ON;
1514 if (mstat & TIOCM_DSR)
1515 *lpModemStat |= MS_DSR_ON;
1518 if (mstat & TIOCM_RNG)
1519 *lpModemStat |= MS_RING_ON;
1522 /*FIXME: Not really sure about RLSD UB 990810*/
1523 if (mstat & TIOCM_CAR)
1524 *lpModemStat |= MS_RLSD_ON;
1526 TRACE("%04x -> %s%s%s%s\n", mstat,
1527 (*lpModemStat &MS_RLSD_ON)?"MS_RLSD_ON ":"",
1528 (*lpModemStat &MS_RING_ON)?"MS_RING_ON ":"",
1529 (*lpModemStat &MS_DSR_ON)?"MS_DSR_ON ":"",
1530 (*lpModemStat &MS_CTS_ON)?"MS_CTS_ON ":"");
1537 /***********************************************************************
1538 * COMM_WaitCommEventService (INTERNAL)
1540 * This function is called while the client is waiting on the
1541 * server, so we can't make any server calls here.
1543 static void COMM_WaitCommEventService(async_private *ovp)
1545 LPOVERLAPPED lpOverlapped = ovp->lpOverlapped;
1547 TRACE("overlapped %p\n",lpOverlapped);
1549 /* FIXME: detect other events */
1550 *ovp->buffer = EV_RXCHAR;
1552 lpOverlapped->Internal = STATUS_SUCCESS;
1556 /***********************************************************************
1557 * COMM_WaitCommEvent (INTERNAL)
1559 * This function must have an lpOverlapped.
1561 static BOOL COMM_WaitCommEvent(
1562 HANDLE hFile, /* [in] handle of comm port to wait for */
1563 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1564 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1571 SetLastError(ERROR_INVALID_PARAMETER);
1575 if(NtResetEvent(lpOverlapped->hEvent,NULL))
1578 lpOverlapped->Internal = STATUS_PENDING;
1579 lpOverlapped->InternalHigh = 0;
1580 lpOverlapped->Offset = 0;
1581 lpOverlapped->OffsetHigh = 0;
1583 fd = FILE_GetUnixHandle( hFile, GENERIC_WRITE );
1587 ovp = (async_private *) HeapAlloc(GetProcessHeap(), 0, sizeof (async_private));
1593 ovp->lpOverlapped = lpOverlapped;
1594 ovp->func = COMM_WaitCommEventService;
1595 ovp->buffer = (char *)lpdwEvents;
1598 ovp->completion_func = 0;
1599 ovp->type = ASYNC_TYPE_WAIT;
1600 ovp->handle = hFile;
1602 ovp->next = NtCurrentTeb()->pending_list;
1605 ovp->next->prev=ovp;
1606 NtCurrentTeb()->pending_list = ovp;
1608 /* start an ASYNCHRONOUS WaitCommEvent */
1609 SERVER_START_REQ( register_async )
1611 req->handle = hFile;
1612 req->overlapped = lpOverlapped;
1613 req->type = ASYNC_TYPE_WAIT;
1615 req->func = check_async_list;
1616 req->status = STATUS_PENDING;
1618 ret=wine_server_call_err(req);
1623 SetLastError(ERROR_IO_PENDING);
1628 /***********************************************************************
1629 * WaitCommEvent (KERNEL32.@)
1631 * Wait until something interesting happens on a COMM port.
1632 * Interesting things (events) are set by calling SetCommMask before
1633 * this function is called.
1636 * TRUE if successful
1639 * The set of detected events will be written to *lpdwEventMask
1640 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1643 * Only supports EV_RXCHAR and EV_TXEMPTY
1645 BOOL WINAPI WaitCommEvent(
1646 HANDLE hFile, /* [in] handle of comm port to wait for */
1647 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1648 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1653 TRACE("(%x %p %p )\n",hFile, lpdwEvents,lpOverlapped);
1656 return COMM_WaitCommEvent(hFile, lpdwEvents, lpOverlapped);
1658 /* if there is no overlapped structure, create our own */
1659 ov.hEvent = CreateEventA(NULL,FALSE,FALSE,NULL);
1661 COMM_WaitCommEvent(hFile, lpdwEvents, &ov);
1663 if(GetLastError()!=STATUS_PENDING)
1665 CloseHandle(ov.hEvent);
1669 /* wait for the overlapped to complete */
1670 ret = GetOverlappedResult(hFile, &ov, NULL, TRUE);
1671 CloseHandle(ov.hEvent);
1676 /***********************************************************************
1677 * GetCommProperties (KERNEL32.@)
1679 * This function fills in a structure with the capabilities of the
1680 * communications port driver.
1684 * TRUE on success, FALSE on failure
1685 * If successful, the lpCommProp structure be filled in with
1686 * properties of the comm port.
1688 BOOL WINAPI GetCommProperties(
1689 HANDLE hFile, /* [in] handle of the comm port */
1690 LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */
1692 FIXME("(%d %p )\n",hFile,lpCommProp);
1697 * These values should be valid for LINUX's serial driver
1698 * FIXME: Perhaps they deserve an #ifdef LINUX
1700 memset(lpCommProp,0,sizeof(COMMPROP));
1701 lpCommProp->wPacketLength = 1;
1702 lpCommProp->wPacketVersion = 1;
1703 lpCommProp->dwServiceMask = SP_SERIALCOMM;
1704 lpCommProp->dwReserved1 = 0;
1705 lpCommProp->dwMaxTxQueue = 4096;
1706 lpCommProp->dwMaxRxQueue = 4096;
1707 lpCommProp->dwMaxBaud = BAUD_115200;
1708 lpCommProp->dwProvSubType = PST_RS232;
1709 lpCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS ;
1710 lpCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING |
1711 SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ;
1712 lpCommProp->dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 |
1713 BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
1714 BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ;
1715 lpCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ;
1716 lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
1717 PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE;
1718 lpCommProp->dwCurrentTxQueue = lpCommProp->dwMaxTxQueue;
1719 lpCommProp->dwCurrentRxQueue = lpCommProp->dwMaxRxQueue;
1724 /***********************************************************************
1726 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1727 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1728 * This is dependent on the type of COMM port, but since it is doubtful
1729 * anybody will get around to implementing support for fancy serial
1730 * ports in WINE, this is hardcoded for the time being. The name of
1731 * this DLL should be stored in and read from the system registry in
1732 * the hive HKEY_LOCAL_MACHINE, key
1733 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1734 * where ???? is the port number... that is determined by PNP
1735 * The DLL should be loaded when the COMM port is opened, and closed
1736 * when the COMM port is closed. - MJM 20 June 2000
1737 ***********************************************************************/
1738 static CHAR lpszSerialUI[] = "serialui.dll";
1741 /***********************************************************************
1742 * CommConfigDialogA (KERNEL32.@)
1744 * Raises a dialog that allows the user to configure a comm port.
1745 * Fills the COMMCONFIG struct with information specified by the user.
1746 * This function should call a similar routine in the COMM driver...
1750 * TRUE on success, FALSE on failure
1751 * If successful, the lpCommConfig structure will contain a new
1752 * configuration for the comm port, as specified by the user.
1755 * The library with the CommConfigDialog code is never unloaded.
1756 * Perhaps this should be done when the comm port is closed?
1758 BOOL WINAPI CommConfigDialogA(
1759 LPCSTR lpszDevice, /* [in] name of communications device */
1760 HANDLE hWnd, /* [in] parent window for the dialog */
1761 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1763 FARPROC lpfnCommDialog;
1764 HMODULE hConfigModule;
1767 TRACE("(%p %x %p)\n",lpszDevice, hWnd, lpCommConfig);
1769 hConfigModule = LoadLibraryA(lpszSerialUI);
1773 lpfnCommDialog = GetProcAddress(hConfigModule, (LPCSTR)3L);
1778 r = lpfnCommDialog(lpszDevice,hWnd,lpCommConfig);
1780 /* UnloadLibrary(hConfigModule); */
1785 /***********************************************************************
1786 * CommConfigDialogW (KERNEL32.@)
1788 * see CommConfigDialogA for more info
1790 BOOL WINAPI CommConfigDialogW(
1791 LPCWSTR lpszDevice, /* [in] name of communications device */
1792 HANDLE hWnd, /* [in] parent window for the dialog */
1793 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1798 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
1801 r = CommConfigDialogA(lpDeviceA,hWnd,lpCommConfig);
1802 HeapFree( GetProcessHeap(), 0, lpDeviceA );
1806 /***********************************************************************
1807 * GetCommConfig (KERNEL32.@)
1809 * Fill in the COMMCONFIG structure for the comm port hFile
1813 * TRUE on success, FALSE on failure
1814 * If successful, lpCommConfig contains the comm port configuration.
1819 BOOL WINAPI GetCommConfig(
1820 HANDLE hFile, /* [in] The communications device. */
1821 LPCOMMCONFIG lpCommConfig, /* [out] The communications configuration of the device (if it fits). */
1822 LPDWORD lpdwSize) /* [in/out] Initially the size of the configuration buffer/structure,
1823 afterwards the number of bytes copied to the buffer or
1824 the needed size of the buffer. */
1828 TRACE("(%x %p)\n",hFile,lpCommConfig);
1830 if(lpCommConfig == NULL)
1833 r = *lpdwSize < sizeof(COMMCONFIG);
1834 *lpdwSize = sizeof(COMMCONFIG);
1838 lpCommConfig->dwSize = sizeof(COMMCONFIG);
1839 lpCommConfig->wVersion = 1;
1840 lpCommConfig->wReserved = 0;
1841 r = GetCommState(hFile,&lpCommConfig->dcb);
1842 lpCommConfig->dwProviderSubType = PST_RS232;
1843 lpCommConfig->dwProviderOffset = 0;
1844 lpCommConfig->dwProviderSize = 0;
1849 /***********************************************************************
1850 * SetCommConfig (KERNEL32.@)
1852 * Sets the configuration of the communications device.
1856 * True on success, false if the handle was bad is not a communications device.
1858 BOOL WINAPI SetCommConfig(
1859 HANDLE hFile, /* [in] The communications device. */
1860 LPCOMMCONFIG lpCommConfig, /* [in] The desired configuration. */
1861 DWORD dwSize) /* [in] size of the lpCommConfig struct */
1863 TRACE("(%x %p)\n",hFile,lpCommConfig);
1864 return SetCommState(hFile,&lpCommConfig->dcb);
1867 /***********************************************************************
1868 * SetDefaultCommConfigA (KERNEL32.@)
1870 * Initializes the default configuration for the specified communication
1875 * True if the device was found and the defaults set, false otherwise
1877 BOOL WINAPI SetDefaultCommConfigA(
1878 LPCSTR lpszDevice, /* [in] The ascii name of the device targeted for configuration. */
1879 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1880 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
1882 FARPROC lpfnSetDefaultCommConfig;
1883 HMODULE hConfigModule;
1886 TRACE("(%p %p %lx)\n",lpszDevice, lpCommConfig, dwSize);
1888 hConfigModule = LoadLibraryA(lpszSerialUI);
1892 lpfnSetDefaultCommConfig = GetProcAddress(hConfigModule, (LPCSTR)4L);
1894 if(! lpfnSetDefaultCommConfig)
1897 r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize);
1899 /* UnloadLibrary(hConfigModule); */
1905 /***********************************************************************
1906 * SetDefaultCommConfigW (KERNEL32.@)
1908 * Initializes the default configuration for the specified
1909 * communication device. (unicode)
1914 BOOL WINAPI SetDefaultCommConfigW(
1915 LPCWSTR lpszDevice, /* [in] The unicode name of the device targeted for configuration. */
1916 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1917 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
1922 TRACE("(%s %p %lx)\n",debugstr_w(lpszDevice),lpCommConfig,dwSize);
1924 lpDeviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszDevice );
1927 r = SetDefaultCommConfigA(lpDeviceA,lpCommConfig,dwSize);
1928 HeapFree( GetProcessHeap(), 0, lpDeviceA );
1933 /***********************************************************************
1934 * GetDefaultCommConfigA (KERNEL32.@)
1936 * Acquires the default configuration of the specified communication device. (unicode)
1940 * True on successful reading of the default configuration,
1941 * if the device is not found or the buffer is too small.
1943 BOOL WINAPI GetDefaultCommConfigA(
1944 LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */
1945 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
1946 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
1947 afterwards the number of bytes copied to the buffer or
1948 the needed size of the buffer. */
1950 LPDCB lpdcb = &(lpCC->dcb);
1953 if (strncasecmp(lpszName,"COM",3)) {
1954 ERR("not implemented for <%s>\n", lpszName);
1958 TRACE("(%s %p %ld)\n", lpszName, lpCC, *lpdwSize );
1959 if (*lpdwSize < sizeof(COMMCONFIG)) {
1960 *lpdwSize = sizeof(COMMCONFIG);
1964 *lpdwSize = sizeof(COMMCONFIG);
1966 lpCC->dwSize = sizeof(COMMCONFIG);
1968 lpCC->dwProviderSubType = PST_RS232;
1969 lpCC->dwProviderOffset = 0L;
1970 lpCC->dwProviderSize = 0L;
1972 sprintf( temp, "COM%c:38400,n,8,1", lpszName[3]);
1973 FIXME("setting %s as default\n", temp);
1975 return BuildCommDCBA( temp, lpdcb);
1978 /**************************************************************************
1979 * GetDefaultCommConfigW (KERNEL32.@)
1981 * Acquires the default configuration of the specified communication device. (unicode)
1985 * True on successful reading of the default configuration,
1986 * if the device is not found or the buffer is too small.
1988 BOOL WINAPI GetDefaultCommConfigW(
1989 LPCWSTR lpszName, /* [in] The unicode name of the device targeted for configuration. */
1990 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
1991 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
1992 afterwards the number of bytes copied to the buffer or
1993 the needed size of the buffer. */
1998 TRACE("(%p,%p,%ld)\n",lpszName,lpCC,*lpdwSize);
1999 lpszNameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszName );
2002 ret=GetDefaultCommConfigA(lpszNameA,lpCC,lpdwSize);
2003 HeapFree( GetProcessHeap(), 0, lpszNameA );