kernel32: Remove duplicate code (use serialui instead).
[wine/wine64.git] / dlls / kernel32 / comm.c
blob8fc10330016020eaa2e411c5cc4cebd2a9343894
1 /*
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <stdio.h>
28 #define NONAMELESSUNION
29 #define NONAMELESSSTRUCT
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winerror.h"
33 #include "winioctl.h"
34 #include "ddk/ntddser.h"
36 #include "wine/server.h"
37 #include "wine/unicode.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(comm);
43 /***********************************************************************
44 * COMM_Parse* (Internal)
46 * The following COMM_Parse* functions are used by the BuildCommDCB
47 * functions to help parse the various parts of the device control string.
49 static LPCWSTR COMM_ParseStart(LPCWSTR ptr)
51 static const WCHAR comW[] = {'C','O','M',0};
53 /* The device control string may optionally start with "COMx" followed
54 by an optional ':' and spaces. */
55 if(!strncmpiW(ptr, comW, 3))
57 ptr += 3;
59 /* Allow any com port above 0 as Win 9x does (NT only allows
60 values for com ports which are actually present) */
61 if(*ptr < '1' || *ptr > '9')
62 return NULL;
64 /* Advance pointer past port number */
65 while(*ptr >= '0' && *ptr <= '9') ptr++;
67 /* The com port number must be followed by a ':' or ' ' */
68 if(*ptr != ':' && *ptr != ' ')
69 return NULL;
71 /* Advance pointer to beginning of next parameter */
72 while(*ptr == ' ') ptr++;
73 if(*ptr == ':')
75 ptr++;
76 while(*ptr == ' ') ptr++;
79 /* The device control string must not start with a space. */
80 else if(*ptr == ' ')
81 return NULL;
83 return ptr;
86 static LPCWSTR COMM_ParseNumber(LPCWSTR ptr, LPDWORD lpnumber)
88 if(*ptr < '0' || *ptr > '9') return NULL;
89 *lpnumber = strtoulW(ptr, NULL, 10);
90 while(*ptr >= '0' && *ptr <= '9') ptr++;
91 return ptr;
94 static LPCWSTR COMM_ParseParity(LPCWSTR ptr, LPBYTE lpparity)
96 /* Contrary to what you might expect, Windows only sets the Parity
97 member of DCB and not fParity even when parity is specified in the
98 device control string */
100 switch(toupperW(*ptr++))
102 case 'E':
103 *lpparity = EVENPARITY;
104 break;
105 case 'M':
106 *lpparity = MARKPARITY;
107 break;
108 case 'N':
109 *lpparity = NOPARITY;
110 break;
111 case 'O':
112 *lpparity = ODDPARITY;
113 break;
114 case 'S':
115 *lpparity = SPACEPARITY;
116 break;
117 default:
118 return NULL;
121 return ptr;
124 static LPCWSTR COMM_ParseByteSize(LPCWSTR ptr, LPBYTE lpbytesize)
126 DWORD temp;
128 if(!(ptr = COMM_ParseNumber(ptr, &temp)))
129 return NULL;
131 if(temp >= 5 && temp <= 8)
133 *lpbytesize = temp;
134 return ptr;
136 else
137 return NULL;
140 static LPCWSTR COMM_ParseStopBits(LPCWSTR ptr, LPBYTE lpstopbits)
142 DWORD temp;
143 static const WCHAR stopbits15W[] = {'1','.','5',0};
145 if(!strncmpW(stopbits15W, ptr, 3))
147 ptr += 3;
148 *lpstopbits = ONE5STOPBITS;
150 else
152 if(!(ptr = COMM_ParseNumber(ptr, &temp)))
153 return NULL;
155 if(temp == 1)
156 *lpstopbits = ONESTOPBIT;
157 else if(temp == 2)
158 *lpstopbits = TWOSTOPBITS;
159 else
160 return NULL;
163 return ptr;
166 static LPCWSTR COMM_ParseOnOff(LPCWSTR ptr, LPDWORD lponoff)
168 static const WCHAR onW[] = {'o','n',0};
169 static const WCHAR offW[] = {'o','f','f',0};
171 if(!strncmpiW(onW, ptr, 2))
173 ptr += 2;
174 *lponoff = 1;
176 else if(!strncmpiW(offW, ptr, 3))
178 ptr += 3;
179 *lponoff = 0;
181 else
182 return NULL;
184 return ptr;
187 /***********************************************************************
188 * COMM_BuildOldCommDCB (Internal)
190 * Build a DCB using the old style settings string eg: "96,n,8,1"
192 static BOOL COMM_BuildOldCommDCB(LPCWSTR device, LPDCB lpdcb)
194 WCHAR last = 0;
196 if(!(device = COMM_ParseNumber(device, &lpdcb->BaudRate)))
197 return FALSE;
199 switch(lpdcb->BaudRate)
201 case 11:
202 case 30:
203 case 60:
204 lpdcb->BaudRate *= 10;
205 break;
206 case 12:
207 case 24:
208 case 48:
209 case 96:
210 lpdcb->BaudRate *= 100;
211 break;
212 case 19:
213 lpdcb->BaudRate = 19200;
214 break;
217 while(*device == ' ') device++;
218 if(*device++ != ',') return FALSE;
219 while(*device == ' ') device++;
221 if(!(device = COMM_ParseParity(device, &lpdcb->Parity)))
222 return FALSE;
224 while(*device == ' ') device++;
225 if(*device++ != ',') return FALSE;
226 while(*device == ' ') device++;
228 if(!(device = COMM_ParseByteSize(device, &lpdcb->ByteSize)))
229 return FALSE;
231 while(*device == ' ') device++;
232 if(*device++ != ',') return FALSE;
233 while(*device == ' ') device++;
235 if(!(device = COMM_ParseStopBits(device, &lpdcb->StopBits)))
236 return FALSE;
238 /* The last parameter for flow control is optional. */
239 while(*device == ' ') device++;
240 if(*device == ',')
242 device++;
243 while(*device == ' ') device++;
244 if(*device) last = toupperW(*device++);
245 while(*device == ' ') device++;
248 /* Win NT sets the flow control members based on (or lack of) the last
249 parameter. Win 9x does not set these members. */
250 switch(last)
252 case 0:
253 lpdcb->fInX = FALSE;
254 lpdcb->fOutX = FALSE;
255 lpdcb->fOutxCtsFlow = FALSE;
256 lpdcb->fOutxDsrFlow = FALSE;
257 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
258 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
259 break;
260 case 'X':
261 lpdcb->fInX = TRUE;
262 lpdcb->fOutX = TRUE;
263 lpdcb->fOutxCtsFlow = FALSE;
264 lpdcb->fOutxDsrFlow = FALSE;
265 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
266 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
267 break;
268 case 'P':
269 lpdcb->fInX = FALSE;
270 lpdcb->fOutX = FALSE;
271 lpdcb->fOutxCtsFlow = TRUE;
272 lpdcb->fOutxDsrFlow = TRUE;
273 lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE;
274 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
275 break;
276 default:
277 return FALSE;
280 /* This should be the end of the string. */
281 if(*device) return FALSE;
283 return TRUE;
286 /***********************************************************************
287 * COMM_BuildNewCommDCB (Internal)
289 * Build a DCB using the new style settings string.
290 * eg: "baud=9600 parity=n data=8 stop=1 xon=on to=on"
292 static BOOL COMM_BuildNewCommDCB(LPCWSTR device, LPDCB lpdcb, LPCOMMTIMEOUTS lptimeouts)
294 DWORD temp;
295 BOOL baud = FALSE, stop = FALSE;
296 static const WCHAR baudW[] = {'b','a','u','d','=',0};
297 static const WCHAR parityW[] = {'p','a','r','i','t','y','=',0};
298 static const WCHAR dataW[] = {'d','a','t','a','=',0};
299 static const WCHAR stopW[] = {'s','t','o','p','=',0};
300 static const WCHAR toW[] = {'t','o','=',0};
301 static const WCHAR xonW[] = {'x','o','n','=',0};
302 static const WCHAR odsrW[] = {'o','d','s','r','=',0};
303 static const WCHAR octsW[] = {'o','c','t','s','=',0};
304 static const WCHAR dtrW[] = {'d','t','r','=',0};
305 static const WCHAR rtsW[] = {'r','t','s','=',0};
306 static const WCHAR idsrW[] = {'i','d','s','r','=',0};
308 while(*device)
310 while(*device == ' ') device++;
312 if(!strncmpiW(baudW, device, 5))
314 baud = TRUE;
316 if(!(device = COMM_ParseNumber(device + 5, &lpdcb->BaudRate)))
317 return FALSE;
319 else if(!strncmpiW(parityW, device, 7))
321 if(!(device = COMM_ParseParity(device + 7, &lpdcb->Parity)))
322 return FALSE;
324 else if(!strncmpiW(dataW, device, 5))
326 if(!(device = COMM_ParseByteSize(device + 5, &lpdcb->ByteSize)))
327 return FALSE;
329 else if(!strncmpiW(stopW, device, 5))
331 stop = TRUE;
333 if(!(device = COMM_ParseStopBits(device + 5, &lpdcb->StopBits)))
334 return FALSE;
336 else if(!strncmpiW(toW, device, 3))
338 if(!(device = COMM_ParseOnOff(device + 3, &temp)))
339 return FALSE;
341 lptimeouts->ReadIntervalTimeout = 0;
342 lptimeouts->ReadTotalTimeoutMultiplier = 0;
343 lptimeouts->ReadTotalTimeoutConstant = 0;
344 lptimeouts->WriteTotalTimeoutMultiplier = 0;
345 lptimeouts->WriteTotalTimeoutConstant = temp ? 60000 : 0;
347 else if(!strncmpiW(xonW, device, 4))
349 if(!(device = COMM_ParseOnOff(device + 4, &temp)))
350 return FALSE;
352 lpdcb->fOutX = temp;
353 lpdcb->fInX = temp;
355 else if(!strncmpiW(odsrW, device, 5))
357 if(!(device = COMM_ParseOnOff(device + 5, &temp)))
358 return FALSE;
360 lpdcb->fOutxDsrFlow = temp;
362 else if(!strncmpiW(octsW, device, 5))
364 if(!(device = COMM_ParseOnOff(device + 5, &temp)))
365 return FALSE;
367 lpdcb->fOutxCtsFlow = temp;
369 else if(!strncmpiW(dtrW, device, 4))
371 if(!(device = COMM_ParseOnOff(device + 4, &temp)))
372 return FALSE;
374 lpdcb->fDtrControl = temp;
376 else if(!strncmpiW(rtsW, device, 4))
378 if(!(device = COMM_ParseOnOff(device + 4, &temp)))
379 return FALSE;
381 lpdcb->fRtsControl = temp;
383 else if(!strncmpiW(idsrW, device, 5))
385 if(!(device = COMM_ParseOnOff(device + 5, &temp)))
386 return FALSE;
388 /* Win NT sets the fDsrSensitivity member based on the
389 idsr parameter. Win 9x sets fOutxDsrFlow instead. */
390 lpdcb->fDsrSensitivity = temp;
392 else
393 return FALSE;
395 /* After the above parsing, the next character (if not the end of
396 the string) should be a space */
397 if(*device && *device != ' ')
398 return FALSE;
401 /* If stop bits were not specified, a default is always supplied. */
402 if(!stop)
404 if(baud && lpdcb->BaudRate == 110)
405 lpdcb->StopBits = TWOSTOPBITS;
406 else
407 lpdcb->StopBits = ONESTOPBIT;
410 return TRUE;
413 /**************************************************************************
414 * BuildCommDCBA (KERNEL32.@)
416 * Updates a device control block data structure with values from an
417 * ascii device control string. The device control string has two forms
418 * normal and extended, it must be exclusively in one or the other form.
420 * RETURNS
422 * True on success, false on a malformed control string.
424 BOOL WINAPI BuildCommDCBA(
425 LPCSTR device, /* [in] The ascii device control string used to update the DCB. */
426 LPDCB lpdcb) /* [out] The device control block to be updated. */
428 return BuildCommDCBAndTimeoutsA(device,lpdcb,NULL);
431 /**************************************************************************
432 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
434 * Updates a device control block data structure with values from an
435 * ascii device control string. Taking timeout values from a timeouts
436 * struct if desired by the control string.
438 * RETURNS
440 * True on success, false bad handles etc.
442 BOOL WINAPI BuildCommDCBAndTimeoutsA(
443 LPCSTR device, /* [in] The ascii device control string. */
444 LPDCB lpdcb, /* [out] The device control block to be updated. */
445 LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */
447 BOOL ret = FALSE;
448 UNICODE_STRING deviceW;
450 TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts);
451 if(device) RtlCreateUnicodeStringFromAsciiz(&deviceW,device);
452 else deviceW.Buffer = NULL;
454 if(deviceW.Buffer) ret = BuildCommDCBAndTimeoutsW(deviceW.Buffer,lpdcb,lptimeouts);
456 RtlFreeUnicodeString(&deviceW);
457 return ret;
460 /**************************************************************************
461 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
463 * Updates a device control block data structure with values from a
464 * unicode device control string. Taking timeout values from a timeouts
465 * struct if desired by the control string.
467 * RETURNS
469 * True on success, false bad handles etc
471 BOOL WINAPI BuildCommDCBAndTimeoutsW(
472 LPCWSTR devid, /* [in] The unicode device control string. */
473 LPDCB lpdcb, /* [out] The device control block to be updated. */
474 LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */
476 DCB dcb;
477 COMMTIMEOUTS timeouts;
478 BOOL result;
479 LPCWSTR ptr = devid;
481 TRACE("(%s,%p,%p)\n",debugstr_w(devid),lpdcb,lptimeouts);
483 /* Set DCBlength. (Windows NT does not do this, but 9x does) */
484 lpdcb->DCBlength = sizeof(DCB);
486 /* Make a copy of the original data structures to work with since if
487 if there is an error in the device control string the originals
488 should not be modified (except possibly DCBlength) */
489 memcpy(&dcb, lpdcb, sizeof(DCB));
490 if(lptimeouts) memcpy(&timeouts, lptimeouts, sizeof(COMMTIMEOUTS));
492 ptr = COMM_ParseStart(ptr);
494 if(ptr == NULL)
495 result = FALSE;
496 else if(strchrW(ptr, ','))
497 result = COMM_BuildOldCommDCB(ptr, &dcb);
498 else
499 result = COMM_BuildNewCommDCB(ptr, &dcb, &timeouts);
501 if(result)
503 memcpy(lpdcb, &dcb, sizeof(DCB));
504 if(lptimeouts) memcpy(lptimeouts, &timeouts, sizeof(COMMTIMEOUTS));
505 return TRUE;
507 else
509 WARN("Invalid device control string: %s\n", debugstr_w(devid));
510 SetLastError(ERROR_INVALID_PARAMETER);
511 return FALSE;
515 /**************************************************************************
516 * BuildCommDCBW (KERNEL32.@)
518 * Updates a device control block structure with values from an
519 * unicode device control string. The device control string has two forms
520 * normal and extended, it must be exclusively in one or the other form.
522 * RETURNS
524 * True on success, false on a malformed control string.
526 BOOL WINAPI BuildCommDCBW(
527 LPCWSTR devid, /* [in] The unicode device control string. */
528 LPDCB lpdcb) /* [out] The device control block to be updated. */
530 return BuildCommDCBAndTimeoutsW(devid,lpdcb,NULL);
533 /*****************************************************************************
534 * SetCommBreak (KERNEL32.@)
536 * Halts the transmission of characters to a communications device.
538 * PARAMS
539 * handle [in] The communications device to suspend
541 * RETURNS
543 * True on success, and false if the communications device could not be found,
544 * the control is not supported.
546 * BUGS
548 * Only TIOCSBRK and TIOCCBRK are supported.
550 BOOL WINAPI SetCommBreak(HANDLE handle)
552 return DeviceIoControl(handle, IOCTL_SERIAL_SET_BREAK_ON, NULL, 0, NULL, 0, NULL, NULL);
555 /*****************************************************************************
556 * ClearCommBreak (KERNEL32.@)
558 * Resumes character transmission from a communication device.
560 * PARAMS
562 * handle [in] The halted communication device whose character transmission is to be resumed
564 * RETURNS
566 * True on success and false if the communications device could not be found.
568 * BUGS
570 * Only TIOCSBRK and TIOCCBRK are supported.
572 BOOL WINAPI ClearCommBreak(HANDLE handle)
574 return DeviceIoControl(handle, IOCTL_SERIAL_SET_BREAK_OFF, NULL, 0, NULL, 0, NULL, NULL);
577 /*****************************************************************************
578 * EscapeCommFunction (KERNEL32.@)
580 * Directs a communication device to perform an extended function.
582 * PARAMS
584 * handle [in] The communication device to perform the extended function
585 * nFunction [in] The extended function to be performed
587 * RETURNS
589 * True or requested data on successful completion of the command,
590 * false if the device is not present cannot execute the command
591 * or the command failed.
593 BOOL WINAPI EscapeCommFunction(HANDLE handle, UINT func)
595 DWORD ioc;
597 switch (func)
599 case CLRDTR: ioc = IOCTL_SERIAL_CLR_DTR; break;
600 case CLRRTS: ioc = IOCTL_SERIAL_CLR_RTS; break;
601 case SETDTR: ioc = IOCTL_SERIAL_SET_DTR; break;
602 case SETRTS: ioc = IOCTL_SERIAL_SET_RTS; break;
603 case SETXOFF: ioc = IOCTL_SERIAL_SET_XOFF; break;
604 case SETXON: ioc = IOCTL_SERIAL_SET_XON; break;
605 case SETBREAK: ioc = IOCTL_SERIAL_SET_BREAK_ON; break;
606 case CLRBREAK: ioc = IOCTL_SERIAL_SET_BREAK_OFF; break;
607 case RESETDEV: ioc = IOCTL_SERIAL_RESET_DEVICE; break;
608 default:
609 ERR("Unknown function code (%u)\n", func);
610 SetLastError(ERROR_INVALID_PARAMETER);
611 return FALSE;
613 return DeviceIoControl(handle, ioc, NULL, 0, NULL, 0, NULL, NULL);
616 /********************************************************************
617 * PurgeComm (KERNEL32.@)
619 * Terminates pending operations and/or discards buffers on a
620 * communication resource.
622 * PARAMS
624 * handle [in] The communication resource to be purged
625 * flags [in] Flags for clear pending/buffer on input/output
627 * RETURNS
629 * True on success and false if the communications handle is bad.
631 BOOL WINAPI PurgeComm(HANDLE handle, DWORD flags)
633 return DeviceIoControl(handle, IOCTL_SERIAL_PURGE, &flags, sizeof(flags),
634 NULL, 0, NULL, NULL);
637 /*****************************************************************************
638 * ClearCommError (KERNEL32.@)
640 * Enables further I/O operations on a communications resource after
641 * supplying error and current status information.
643 * PARAMS
645 * handle [in] The communication resource with the error
646 * errors [out] Flags indicating error the resource experienced
647 * lpStat [out] The status of the communication resource
648 * RETURNS
650 * True on success, false if the communication resource handle is bad.
652 BOOL WINAPI ClearCommError(HANDLE handle, LPDWORD errors, LPCOMSTAT lpStat)
654 SERIAL_STATUS ss;
656 if (!DeviceIoControl(handle, IOCTL_SERIAL_GET_COMMSTATUS, NULL, 0,
657 &ss, sizeof(ss), NULL, NULL))
658 return FALSE;
660 if (errors)
662 *errors = 0;
663 if (ss.Errors & SERIAL_ERROR_BREAK) *errors |= CE_BREAK;
664 if (ss.Errors & SERIAL_ERROR_FRAMING) *errors |= CE_FRAME;
665 if (ss.Errors & SERIAL_ERROR_OVERRUN) *errors |= CE_OVERRUN;
666 if (ss.Errors & SERIAL_ERROR_QUEUEOVERRUN) *errors |= CE_RXOVER;
667 if (ss.Errors & SERIAL_ERROR_PARITY) *errors |= CE_RXPARITY;
670 if (lpStat)
672 memset(lpStat, 0, sizeof(*lpStat));
674 if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_CTS) lpStat->fCtsHold = TRUE;
675 if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_DSR) lpStat->fDsrHold = TRUE;
676 if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_DCD) lpStat->fRlsdHold = TRUE;
677 if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_XON) lpStat->fXoffHold = TRUE;
678 if (ss.HoldReasons & SERIAL_TX_WAITING_XOFF_SENT) lpStat->fXoffSent = TRUE;
679 if (ss.EofReceived) lpStat->fEof = TRUE;
680 if (ss.WaitForImmediate) lpStat->fTxim = TRUE;
681 lpStat->cbInQue = ss.AmountInInQueue;
682 lpStat->cbOutQue = ss.AmountInOutQueue;
684 return TRUE;
687 /*****************************************************************************
688 * SetupComm (KERNEL32.@)
690 * Called after CreateFile to hint to the communication resource to use
691 * specified sizes for input and output buffers rather than the default values.
693 * PARAMS
694 * handle [in] The just created communication resource handle
695 * insize [in] The suggested size of the communication resources input buffer in bytes
696 * outsize [in] The suggested size of the communication resources output buffer in bytes
698 * RETURNS
700 * True if successful, false if the communications resource handle is bad.
702 * BUGS
704 * Stub.
706 BOOL WINAPI SetupComm(HANDLE handle, DWORD insize, DWORD outsize)
708 SERIAL_QUEUE_SIZE sqs;
710 sqs.InSize = insize;
711 sqs.OutSize = outsize;
712 return DeviceIoControl(handle, IOCTL_SERIAL_SET_QUEUE_SIZE,
713 &sqs, sizeof(sqs), NULL, 0, NULL, NULL);
716 /*****************************************************************************
717 * GetCommMask (KERNEL32.@)
719 * Obtain the events associated with a communication device that will cause
720 * a call WaitCommEvent to return.
722 * PARAMS
724 * handle [in] The communications device
725 * evtmask [out] The events which cause WaitCommEvent to return
727 * RETURNS
729 * True on success, fail on bad device handle etc.
731 BOOL WINAPI GetCommMask(HANDLE handle, LPDWORD evtmask)
733 TRACE("handle %p, mask %p\n", handle, evtmask);
734 return DeviceIoControl(handle, IOCTL_SERIAL_GET_WAIT_MASK,
735 NULL, 0, evtmask, sizeof(*evtmask), NULL, NULL);
738 /*****************************************************************************
739 * SetCommMask (KERNEL32.@)
741 * There be some things we need to hear about yon there communications device.
742 * (Set which events associated with a communication device should cause
743 * a call WaitCommEvent to return.)
745 * PARAMS
747 * handle [in] The communications device
748 * evtmask [in] The events that are to be monitored
750 * RETURNS
752 * True on success, false on bad handle etc.
754 BOOL WINAPI SetCommMask(HANDLE handle, DWORD evtmask)
756 TRACE("handle %p, mask %x\n", handle, evtmask);
757 return DeviceIoControl(handle, IOCTL_SERIAL_SET_WAIT_MASK,
758 &evtmask, sizeof(evtmask), NULL, 0, NULL, NULL);
761 static void dump_dcb(const DCB* lpdcb)
763 TRACE("bytesize=%d baudrate=%d fParity=%d Parity=%d stopbits=%d\n",
764 lpdcb->ByteSize, lpdcb->BaudRate, lpdcb->fParity, lpdcb->Parity,
765 (lpdcb->StopBits == ONESTOPBIT) ? 1 :
766 (lpdcb->StopBits == TWOSTOPBITS) ? 2 : 0);
767 TRACE("%sIXON %sIXOFF\n", (lpdcb->fInX) ? "" : "~", (lpdcb->fOutX) ? "" : "~");
768 TRACE("fOutxCtsFlow=%d fRtsControl=%d\n", lpdcb->fOutxCtsFlow, lpdcb->fRtsControl);
769 TRACE("fOutxDsrFlow=%d fDtrControl=%d\n", lpdcb->fOutxDsrFlow, lpdcb->fDtrControl);
770 if (lpdcb->fOutxCtsFlow || lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE)
771 TRACE("CRTSCTS\n");
772 else
773 TRACE("~CRTSCTS\n");
776 /*****************************************************************************
777 * SetCommState (KERNEL32.@)
779 * Re-initializes all hardware and control settings of a communications device,
780 * with values from a device control block without effecting the input and output
781 * queues.
783 * PARAMS
785 * handle [in] The communications device
786 * lpdcb [out] The device control block
788 * RETURNS
790 * True on success, false on failure eg if the XonChar is equal to the XoffChar.
792 BOOL WINAPI SetCommState( HANDLE handle, LPDCB lpdcb)
794 SERIAL_BAUD_RATE sbr;
795 SERIAL_LINE_CONTROL slc;
796 SERIAL_HANDFLOW shf;
797 SERIAL_CHARS sc;
799 if (lpdcb == NULL)
801 SetLastError(ERROR_INVALID_PARAMETER);
802 return FALSE;
804 dump_dcb(lpdcb);
806 sbr.BaudRate = lpdcb->BaudRate;
808 slc.StopBits = lpdcb->StopBits;
809 slc.Parity = lpdcb->Parity;
810 slc.WordLength = lpdcb->ByteSize;
812 shf.ControlHandShake = 0;
813 shf.FlowReplace = 0;
814 if (lpdcb->fOutxCtsFlow) shf.ControlHandShake |= SERIAL_CTS_HANDSHAKE;
815 if (lpdcb->fOutxDsrFlow) shf.ControlHandShake |= SERIAL_DSR_HANDSHAKE;
816 switch (lpdcb->fDtrControl)
818 case DTR_CONTROL_DISABLE: break;
819 case DTR_CONTROL_ENABLE: shf.ControlHandShake |= SERIAL_DTR_CONTROL; break;
820 case DTR_CONTROL_HANDSHAKE: shf.ControlHandShake |= SERIAL_DTR_HANDSHAKE;break;
821 default:
822 SetLastError(ERROR_INVALID_PARAMETER);
823 return FALSE;
825 switch (lpdcb->fDtrControl)
827 case RTS_CONTROL_DISABLE: break;
828 case RTS_CONTROL_ENABLE: shf.FlowReplace |= SERIAL_RTS_CONTROL; break;
829 case RTS_CONTROL_HANDSHAKE: shf.FlowReplace |= SERIAL_RTS_HANDSHAKE; break;
830 case RTS_CONTROL_TOGGLE: shf.FlowReplace |= SERIAL_RTS_CONTROL |
831 SERIAL_RTS_HANDSHAKE; break;
832 default:
833 SetLastError(ERROR_INVALID_PARAMETER);
834 return FALSE;
836 if (lpdcb->fDsrSensitivity) shf.ControlHandShake |= SERIAL_DSR_SENSITIVITY;
837 if (lpdcb->fAbortOnError) shf.ControlHandShake |= SERIAL_ERROR_ABORT;
839 if (lpdcb->fErrorChar) shf.FlowReplace |= SERIAL_ERROR_CHAR;
840 if (lpdcb->fNull) shf.FlowReplace |= SERIAL_NULL_STRIPPING;
841 if (lpdcb->fTXContinueOnXoff) shf.FlowReplace |= SERIAL_XOFF_CONTINUE;
842 if (lpdcb->fOutX) shf.FlowReplace |= SERIAL_AUTO_TRANSMIT;
843 if (lpdcb->fInX) shf.FlowReplace |= SERIAL_AUTO_RECEIVE;
845 shf.XonLimit = lpdcb->XonLim;
846 shf.XoffLimit = lpdcb->XoffLim;
848 sc.EofChar = lpdcb->EofChar;
849 sc.ErrorChar = lpdcb->ErrorChar;
850 sc.BreakChar = 0;
851 sc.EventChar = lpdcb->EvtChar;
852 sc.XonChar = lpdcb->XonChar;
853 sc.XoffChar = lpdcb->XoffChar;
855 /* note: change DTR/RTS lines after setting the comm attributes,
856 * so flow control does not interfere.
858 return (DeviceIoControl(handle, IOCTL_SERIAL_SET_BAUD_RATE,
859 &sbr, sizeof(sbr), NULL, 0, NULL, NULL) &&
860 DeviceIoControl(handle, IOCTL_SERIAL_SET_LINE_CONTROL,
861 &slc, sizeof(slc), NULL, 0, NULL, NULL) &&
862 DeviceIoControl(handle, IOCTL_SERIAL_SET_HANDFLOW,
863 &shf, sizeof(shf), NULL, 0, NULL, NULL) &&
864 DeviceIoControl(handle, IOCTL_SERIAL_SET_CHARS,
865 &sc, sizeof(sc), NULL, 0, NULL, NULL));
869 /*****************************************************************************
870 * GetCommState (KERNEL32.@)
872 * Fills in a device control block with information from a communications device.
874 * PARAMS
875 * handle [in] The communications device
876 * lpdcb [out] The device control block
878 * RETURNS
880 * True on success, false if the communication device handle is bad etc
882 * BUGS
884 * XonChar and XoffChar are not set.
886 BOOL WINAPI GetCommState(HANDLE handle, LPDCB lpdcb)
888 SERIAL_BAUD_RATE sbr;
889 SERIAL_LINE_CONTROL slc;
890 SERIAL_HANDFLOW shf;
891 SERIAL_CHARS sc;
893 TRACE("handle %p, ptr %p\n", handle, lpdcb);
895 if (!lpdcb)
897 SetLastError(ERROR_INVALID_PARAMETER);
898 return FALSE;
901 if (!DeviceIoControl(handle, IOCTL_SERIAL_GET_BAUD_RATE,
902 NULL, 0, &sbr, sizeof(sbr), NULL, NULL) ||
903 !DeviceIoControl(handle, IOCTL_SERIAL_GET_LINE_CONTROL,
904 NULL, 0, &slc, sizeof(slc), NULL, NULL) ||
905 !DeviceIoControl(handle, IOCTL_SERIAL_GET_HANDFLOW,
906 NULL, 0, &shf, sizeof(shf), NULL, NULL) ||
907 !DeviceIoControl(handle, IOCTL_SERIAL_GET_CHARS,
908 NULL, 0, &sc, sizeof(sc), NULL, NULL))
909 return FALSE;
911 memset(lpdcb, 0, sizeof(*lpdcb));
912 lpdcb->DCBlength = sizeof(*lpdcb);
914 /* yes, they seem no never be (re)set on NT */
915 lpdcb->fBinary = 1;
916 lpdcb->fParity = 0;
918 lpdcb->BaudRate = sbr.BaudRate;
920 lpdcb->StopBits = slc.StopBits;
921 lpdcb->Parity = slc.Parity;
922 lpdcb->ByteSize = slc.WordLength;
924 if (shf.ControlHandShake & SERIAL_CTS_HANDSHAKE) lpdcb->fOutxCtsFlow = 1;
925 if (shf.ControlHandShake & SERIAL_DSR_HANDSHAKE) lpdcb->fOutxDsrFlow = 1;
926 switch (shf.ControlHandShake & (SERIAL_DTR_CONTROL | SERIAL_DTR_HANDSHAKE))
928 case 0: lpdcb->fDtrControl = DTR_CONTROL_DISABLE; break;
929 case SERIAL_DTR_CONTROL: lpdcb->fDtrControl = DTR_CONTROL_ENABLE; break;
930 case SERIAL_DTR_HANDSHAKE: lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE; break;
932 switch (shf.FlowReplace & (SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE))
934 case 0: lpdcb->fRtsControl = RTS_CONTROL_DISABLE; break;
935 case SERIAL_RTS_CONTROL: lpdcb->fRtsControl = RTS_CONTROL_ENABLE; break;
936 case SERIAL_RTS_HANDSHAKE: lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE; break;
937 case SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE:
938 lpdcb->fRtsControl = RTS_CONTROL_TOGGLE; break;
940 if (shf.ControlHandShake & SERIAL_DSR_SENSITIVITY) lpdcb->fDsrSensitivity = 1;
941 if (shf.ControlHandShake & SERIAL_ERROR_ABORT) lpdcb->fAbortOnError = 1;
942 if (shf.FlowReplace & SERIAL_ERROR_CHAR) lpdcb->fErrorChar = 1;
943 if (shf.FlowReplace & SERIAL_NULL_STRIPPING) lpdcb->fNull = 1;
944 if (shf.FlowReplace & SERIAL_XOFF_CONTINUE) lpdcb->fTXContinueOnXoff = 1;
945 lpdcb->XonLim = shf.XonLimit;
946 lpdcb->XoffLim = shf.XoffLimit;
948 if (shf.FlowReplace & SERIAL_AUTO_TRANSMIT) lpdcb->fOutX = 1;
949 if (shf.FlowReplace & SERIAL_AUTO_RECEIVE) lpdcb->fInX = 1;
951 lpdcb->EofChar = sc.EofChar;
952 lpdcb->ErrorChar = sc.ErrorChar;
953 lpdcb->EvtChar = sc.EventChar;
954 lpdcb->XonChar = sc.XonChar;
955 lpdcb->XoffChar = sc.XoffChar;
957 TRACE("OK\n");
958 dump_dcb(lpdcb);
960 return TRUE;
963 /*****************************************************************************
964 * TransmitCommChar (KERNEL32.@)
966 * Transmits a single character in front of any pending characters in the
967 * output buffer. Usually used to send an interrupt character to a host.
969 * PARAMS
970 * hComm [in] The communication device in need of a command character
971 * chTransmit [in] The character to transmit
973 * RETURNS
975 * True if the call succeeded, false if the previous command character to the
976 * same device has not been sent yet the handle is bad etc.
979 BOOL WINAPI TransmitCommChar(HANDLE hComm, CHAR chTransmit)
981 return DeviceIoControl(hComm, IOCTL_SERIAL_IMMEDIATE_CHAR,
982 &chTransmit, sizeof(chTransmit), NULL, 0, NULL, NULL);
986 /*****************************************************************************
987 * GetCommTimeouts (KERNEL32.@)
989 * Obtains the request timeout values for the communications device.
991 * PARAMS
992 * hComm [in] The communications device
993 * lptimeouts [out] The struct of request timeouts
995 * RETURNS
997 * True on success, false if communications device handle is bad
998 * or the target structure is null.
1000 BOOL WINAPI GetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts)
1002 SERIAL_TIMEOUTS st;
1004 TRACE("(%p, %p)\n", hComm, lptimeouts);
1005 if (!lptimeouts)
1007 SetLastError(ERROR_INVALID_PARAMETER);
1008 return FALSE;
1010 if (!DeviceIoControl(hComm, IOCTL_SERIAL_GET_TIMEOUTS,
1011 NULL, 0, &st, sizeof(st), NULL, NULL))
1012 return FALSE;
1013 lptimeouts->ReadIntervalTimeout = st.ReadIntervalTimeout;
1014 lptimeouts->ReadTotalTimeoutMultiplier = st.ReadTotalTimeoutMultiplier;
1015 lptimeouts->ReadTotalTimeoutConstant = st.ReadTotalTimeoutConstant;
1016 lptimeouts->WriteTotalTimeoutMultiplier = st.WriteTotalTimeoutMultiplier;
1017 lptimeouts->WriteTotalTimeoutConstant = st.WriteTotalTimeoutConstant;
1018 return TRUE;
1021 /*****************************************************************************
1022 * SetCommTimeouts (KERNEL32.@)
1024 * Sets the timeouts used when reading and writing data to/from COMM ports.
1026 * PARAMS
1027 * hComm [in] handle of COMM device
1028 * lptimeouts [in] pointer to COMMTIMEOUTS structure
1030 * ReadIntervalTimeout
1031 * - converted and passes to linux kernel as c_cc[VTIME]
1032 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1033 * - used in ReadFile to calculate GetOverlappedResult's timeout
1034 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1035 * - used in WriteFile to calculate GetOverlappedResult's timeout
1037 * RETURNS
1039 * True if the timeouts were set, false otherwise.
1041 BOOL WINAPI SetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts)
1043 SERIAL_TIMEOUTS st;
1045 TRACE("(%p, %p)\n", hComm, lptimeouts);
1047 if (lptimeouts == NULL)
1049 SetLastError(ERROR_INVALID_PARAMETER);
1050 return FALSE;
1052 st.ReadIntervalTimeout = lptimeouts->ReadIntervalTimeout;
1053 st.ReadTotalTimeoutMultiplier = lptimeouts->ReadTotalTimeoutMultiplier;
1054 st.ReadTotalTimeoutConstant = lptimeouts->ReadTotalTimeoutConstant;
1055 st.WriteTotalTimeoutMultiplier = lptimeouts->WriteTotalTimeoutMultiplier;
1056 st.WriteTotalTimeoutConstant = lptimeouts->WriteTotalTimeoutConstant;
1058 return DeviceIoControl(hComm, IOCTL_SERIAL_SET_TIMEOUTS,
1059 &st, sizeof(st), NULL, 0, NULL, NULL);
1062 /***********************************************************************
1063 * GetCommModemStatus (KERNEL32.@)
1065 * Obtains the four control register bits if supported by the hardware.
1067 * PARAMS
1069 * hFile [in] The communications device
1070 * lpModemStat [out] The control register bits
1072 * RETURNS
1074 * True if the communications handle was good and for hardware that
1075 * control register access, false otherwise.
1077 BOOL WINAPI GetCommModemStatus(HANDLE hFile, LPDWORD lpModemStat)
1079 return DeviceIoControl(hFile, IOCTL_SERIAL_GET_MODEMSTATUS,
1080 NULL, 0, lpModemStat, sizeof(DWORD), NULL, NULL);
1083 /***********************************************************************
1084 * WaitCommEvent (KERNEL32.@)
1086 * Wait until something interesting happens on a COMM port.
1087 * Interesting things (events) are set by calling SetCommMask before
1088 * this function is called.
1090 * RETURNS
1091 * TRUE if successful
1092 * FALSE if failure
1094 * The set of detected events will be written to *lpdwEventMask
1095 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1097 * BUGS:
1098 * Only supports EV_RXCHAR and EV_TXEMPTY
1100 BOOL WINAPI WaitCommEvent(
1101 HANDLE hFile, /* [in] handle of comm port to wait for */
1102 LPDWORD lpdwEvents, /* [out] event(s) that were detected */
1103 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1105 return DeviceIoControl(hFile, IOCTL_SERIAL_WAIT_ON_MASK, NULL, 0,
1106 lpdwEvents, sizeof(DWORD), NULL, lpOverlapped);
1109 /***********************************************************************
1110 * GetCommProperties (KERNEL32.@)
1112 * This function fills in a structure with the capabilities of the
1113 * communications port driver.
1115 * RETURNS
1117 * TRUE on success, FALSE on failure
1118 * If successful, the lpCommProp structure be filled in with
1119 * properties of the comm port.
1121 BOOL WINAPI GetCommProperties(
1122 HANDLE hFile, /* [in] handle of the comm port */
1123 LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */
1125 FIXME("(%p %p )\n",hFile,lpCommProp);
1126 if(!lpCommProp)
1127 return FALSE;
1130 * These values should be valid for LINUX's serial driver
1131 * FIXME: Perhaps they deserve an #ifdef LINUX
1133 memset(lpCommProp,0,sizeof(COMMPROP));
1134 lpCommProp->wPacketLength = 1;
1135 lpCommProp->wPacketVersion = 1;
1136 lpCommProp->dwServiceMask = SP_SERIALCOMM;
1137 lpCommProp->dwReserved1 = 0;
1138 lpCommProp->dwMaxTxQueue = 4096;
1139 lpCommProp->dwMaxRxQueue = 4096;
1140 lpCommProp->dwMaxBaud = BAUD_115200;
1141 lpCommProp->dwProvSubType = PST_RS232;
1142 lpCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS | PCF_TOTALTIMEOUTS;
1143 lpCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING |
1144 SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ;
1145 lpCommProp->dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 |
1146 BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
1147 BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ;
1148 lpCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ;
1149 lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
1150 PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE;
1151 lpCommProp->dwCurrentTxQueue = lpCommProp->dwMaxTxQueue;
1152 lpCommProp->dwCurrentRxQueue = lpCommProp->dwMaxRxQueue;
1154 return TRUE;
1157 /***********************************************************************
1158 * FIXME:
1159 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1160 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1161 * This is dependent on the type of COMM port, but since it is doubtful
1162 * anybody will get around to implementing support for fancy serial
1163 * ports in WINE, this is hardcoded for the time being. The name of
1164 * this DLL should be stored in and read from the system registry in
1165 * the hive HKEY_LOCAL_MACHINE, key
1166 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1167 * where ???? is the port number... that is determined by PNP
1168 * The DLL should be loaded when the COMM port is opened, and closed
1169 * when the COMM port is closed. - MJM 20 June 2000
1170 ***********************************************************************/
1171 static const WCHAR lpszSerialUI[] = {
1172 's','e','r','i','a','l','u','i','.','d','l','l',0 };
1175 /***********************************************************************
1176 * CommConfigDialogA (KERNEL32.@)
1178 * Raises a dialog that allows the user to configure a comm port.
1179 * Fills the COMMCONFIG struct with information specified by the user.
1180 * This function should call a similar routine in the COMM driver...
1182 * RETURNS
1184 * TRUE on success, FALSE on failure
1185 * If successful, the lpCommConfig structure will contain a new
1186 * configuration for the comm port, as specified by the user.
1188 * BUGS
1189 * The library with the CommConfigDialog code is never unloaded.
1190 * Perhaps this should be done when the comm port is closed?
1192 BOOL WINAPI CommConfigDialogA(
1193 LPCSTR lpszDevice, /* [in] name of communications device */
1194 HWND hWnd, /* [in] parent window for the dialog */
1195 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1197 FARPROC lpfnCommDialog;
1198 HMODULE hConfigModule;
1199 BOOL r = FALSE;
1201 TRACE("(%s, %p, %p)\n", debugstr_a(lpszDevice), hWnd, lpCommConfig);
1203 hConfigModule = LoadLibraryW(lpszSerialUI);
1204 if(!hConfigModule)
1205 return FALSE;
1207 lpfnCommDialog = GetProcAddress(hConfigModule, "drvCommConfigDialogA");
1209 if(lpfnCommDialog)
1210 r = lpfnCommDialog(lpszDevice,hWnd,lpCommConfig);
1212 FreeLibrary(hConfigModule);
1214 return r;
1217 /***********************************************************************
1218 * CommConfigDialogW (KERNEL32.@)
1220 * See CommConfigDialogA.
1222 BOOL WINAPI CommConfigDialogW(
1223 LPCWSTR lpszDevice, /* [in] name of communications device */
1224 HWND hWnd, /* [in] parent window for the dialog */
1225 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1227 FARPROC lpfnCommDialog;
1228 HMODULE hConfigModule;
1229 BOOL r = FALSE;
1231 TRACE("(%s, %p, %p)\n", debugstr_w(lpszDevice), hWnd, lpCommConfig);
1233 hConfigModule = LoadLibraryW(lpszSerialUI);
1234 if(!hConfigModule)
1235 return FALSE;
1237 lpfnCommDialog = GetProcAddress(hConfigModule, "drvCommConfigDialogW");
1239 if(lpfnCommDialog)
1240 r = lpfnCommDialog(lpszDevice,hWnd,lpCommConfig);
1242 FreeLibrary(hConfigModule);
1244 return r;
1247 /***********************************************************************
1248 * GetCommConfig (KERNEL32.@)
1250 * Fill in the COMMCONFIG structure for the comm port hFile
1252 * RETURNS
1254 * TRUE on success, FALSE on failure
1255 * If successful, lpCommConfig contains the comm port configuration.
1257 * BUGS
1260 BOOL WINAPI GetCommConfig(
1261 HANDLE hFile, /* [in] The communications device. */
1262 LPCOMMCONFIG lpCommConfig, /* [out] The communications configuration of the device (if it fits). */
1263 LPDWORD lpdwSize) /* [in/out] Initially the size of the configuration buffer/structure,
1264 afterwards the number of bytes copied to the buffer or
1265 the needed size of the buffer. */
1267 BOOL r;
1269 TRACE("(%p, %p, %p) *lpdwSize: %u\n", hFile, lpCommConfig, lpdwSize, lpdwSize ? *lpdwSize : 0 );
1271 if(lpCommConfig == NULL)
1272 return FALSE;
1273 r = *lpdwSize < sizeof(COMMCONFIG); /* TRUE if not enough space */
1274 *lpdwSize = sizeof(COMMCONFIG);
1275 if(r)
1276 return FALSE;
1278 lpCommConfig->dwSize = sizeof(COMMCONFIG);
1279 lpCommConfig->wVersion = 1;
1280 lpCommConfig->wReserved = 0;
1281 r = GetCommState(hFile,&lpCommConfig->dcb);
1282 lpCommConfig->dwProviderSubType = PST_RS232;
1283 lpCommConfig->dwProviderOffset = 0;
1284 lpCommConfig->dwProviderSize = 0;
1286 return r;
1289 /***********************************************************************
1290 * SetCommConfig (KERNEL32.@)
1292 * Sets the configuration of the communications device.
1294 * RETURNS
1296 * True on success, false if the handle was bad is not a communications device.
1298 BOOL WINAPI SetCommConfig(
1299 HANDLE hFile, /* [in] The communications device. */
1300 LPCOMMCONFIG lpCommConfig, /* [in] The desired configuration. */
1301 DWORD dwSize) /* [in] size of the lpCommConfig struct */
1303 TRACE("(%p, %p, %u)\n", hFile, lpCommConfig, dwSize);
1304 return SetCommState(hFile,&lpCommConfig->dcb);
1307 /***********************************************************************
1308 * SetDefaultCommConfigA (KERNEL32.@)
1310 * Initializes the default configuration for the specified communication
1311 * device. (ascii)
1313 * RETURNS
1315 * True if the device was found and the defaults set, false otherwise
1317 BOOL WINAPI SetDefaultCommConfigW(
1318 LPCWSTR lpszDevice, /* [in] The ascii name of the device targeted for configuration. */
1319 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1320 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
1322 FARPROC lpfnSetDefaultCommConfig;
1323 HMODULE hConfigModule;
1324 BOOL r = FALSE;
1326 TRACE("(%s, %p, %u)\n", debugstr_w(lpszDevice), lpCommConfig, dwSize);
1328 hConfigModule = LoadLibraryW(lpszSerialUI);
1329 if(!hConfigModule)
1330 return r;
1332 lpfnSetDefaultCommConfig = GetProcAddress(hConfigModule, "drvSetDefaultCommConfigW");
1333 if (lpfnSetDefaultCommConfig)
1334 r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize);
1336 FreeLibrary(hConfigModule);
1338 return r;
1342 /***********************************************************************
1343 * SetDefaultCommConfigW (KERNEL32.@)
1345 * Initializes the default configuration for the specified
1346 * communication device. (unicode)
1348 * RETURNS
1351 BOOL WINAPI SetDefaultCommConfigA(
1352 LPCSTR lpszDevice, /* [in] The unicode name of the device targeted for configuration. */
1353 LPCOMMCONFIG lpCommConfig, /* [in] The default configuration for the device. */
1354 DWORD dwSize) /* [in] The number of bytes in the configuration structure. */
1356 BOOL r;
1357 LPWSTR lpDeviceW = NULL;
1358 DWORD len;
1360 TRACE("(%s, %p, %u)\n", debugstr_a(lpszDevice), lpCommConfig, dwSize);
1362 if (lpszDevice)
1364 len = MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, NULL, 0 );
1365 lpDeviceW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1366 MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, lpDeviceW, len );
1368 r = SetDefaultCommConfigW(lpDeviceW,lpCommConfig,dwSize);
1369 HeapFree( GetProcessHeap(), 0, lpDeviceW );
1370 return r;
1374 /***********************************************************************
1375 * GetDefaultCommConfigW (KERNEL32.@)
1377 * Acquires the default configuration of the specified communication device. (unicode)
1379 * RETURNS
1381 * True on successful reading of the default configuration,
1382 * if the device is not found or the buffer is too small.
1384 BOOL WINAPI GetDefaultCommConfigW(
1385 LPCWSTR lpszName, /* [in] The unicode name of the device targeted for configuration. */
1386 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
1387 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
1388 afterwards the number of bytes copied to the buffer or
1389 the needed size of the buffer. */
1391 FARPROC pGetDefaultCommConfig;
1392 HMODULE hConfigModule;
1393 DWORD res = ERROR_INVALID_PARAMETER;
1395 TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_w(lpszName), lpCC, lpdwSize, lpdwSize ? *lpdwSize : 0 );
1396 hConfigModule = LoadLibraryW(lpszSerialUI);
1398 if (hConfigModule) {
1399 pGetDefaultCommConfig = GetProcAddress(hConfigModule, "drvGetDefaultCommConfigW");
1400 if (pGetDefaultCommConfig) {
1401 res = pGetDefaultCommConfig(lpszName, lpCC, lpdwSize);
1403 FreeLibrary(hConfigModule);
1406 if (res) SetLastError(res);
1407 return (res == ERROR_SUCCESS);
1410 /**************************************************************************
1411 * GetDefaultCommConfigA (KERNEL32.@)
1413 * Acquires the default configuration of the specified communication device. (ascii)
1415 * RETURNS
1417 * True on successful reading of the default configuration,
1418 * if the device is not found or the buffer is too small.
1420 BOOL WINAPI GetDefaultCommConfigA(
1421 LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */
1422 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
1423 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
1424 afterwards the number of bytes copied to the buffer or
1425 the needed size of the buffer. */
1427 BOOL ret = FALSE;
1428 UNICODE_STRING lpszNameW;
1430 TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_a(lpszName), lpCC, lpdwSize, lpdwSize ? *lpdwSize : 0 );
1431 if(lpszName) RtlCreateUnicodeStringFromAsciiz(&lpszNameW,lpszName);
1432 else lpszNameW.Buffer = NULL;
1434 ret = GetDefaultCommConfigW(lpszNameW.Buffer,lpCC,lpdwSize);
1436 RtlFreeUnicodeString(&lpszNameW);
1437 return ret;