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
22 #include "wine/port.h"
32 #include "ddk/ntddser.h"
34 #include "wine/server.h"
35 #include "wine/unicode.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(comm
);
41 /***********************************************************************
42 * COMM_Parse* (Internal)
44 * The following COMM_Parse* functions are used by the BuildCommDCB
45 * functions to help parse the various parts of the device control string.
47 static LPCWSTR
COMM_ParseStart(LPCWSTR ptr
)
49 static const WCHAR comW
[] = {'C','O','M',0};
51 /* The device control string may optionally start with "COMx" followed
52 by an optional ':' and spaces. */
53 if(!strncmpiW(ptr
, comW
, 3))
57 /* Allow any com port above 0 as Win 9x does (NT only allows
58 values for com ports which are actually present) */
59 if(*ptr
< '1' || *ptr
> '9')
62 /* Advance pointer past port number */
63 while(*ptr
>= '0' && *ptr
<= '9') ptr
++;
65 /* The com port number must be followed by a ':' or ' ' */
66 if(*ptr
!= ':' && *ptr
!= ' ')
69 /* Advance pointer to beginning of next parameter */
70 while(*ptr
== ' ') ptr
++;
74 while(*ptr
== ' ') ptr
++;
77 /* The device control string must not start with a space. */
84 static LPCWSTR
COMM_ParseNumber(LPCWSTR ptr
, LPDWORD lpnumber
)
86 if(*ptr
< '0' || *ptr
> '9') return NULL
;
87 *lpnumber
= strtoulW(ptr
, NULL
, 10);
88 while(*ptr
>= '0' && *ptr
<= '9') ptr
++;
92 static LPCWSTR
COMM_ParseParity(LPCWSTR ptr
, LPBYTE lpparity
)
94 /* Contrary to what you might expect, Windows only sets the Parity
95 member of DCB and not fParity even when parity is specified in the
96 device control string */
98 switch(toupperW(*ptr
++))
101 *lpparity
= EVENPARITY
;
104 *lpparity
= MARKPARITY
;
107 *lpparity
= NOPARITY
;
110 *lpparity
= ODDPARITY
;
113 *lpparity
= SPACEPARITY
;
122 static LPCWSTR
COMM_ParseByteSize(LPCWSTR ptr
, LPBYTE lpbytesize
)
126 if(!(ptr
= COMM_ParseNumber(ptr
, &temp
)))
129 if(temp
>= 5 && temp
<= 8)
138 static LPCWSTR
COMM_ParseStopBits(LPCWSTR ptr
, LPBYTE lpstopbits
)
141 static const WCHAR stopbits15W
[] = {'1','.','5',0};
143 if(!strncmpW(stopbits15W
, ptr
, 3))
146 *lpstopbits
= ONE5STOPBITS
;
150 if(!(ptr
= COMM_ParseNumber(ptr
, &temp
)))
154 *lpstopbits
= ONESTOPBIT
;
156 *lpstopbits
= TWOSTOPBITS
;
164 static LPCWSTR
COMM_ParseOnOff(LPCWSTR ptr
, LPDWORD lponoff
)
166 static const WCHAR onW
[] = {'o','n',0};
167 static const WCHAR offW
[] = {'o','f','f',0};
169 if(!strncmpiW(onW
, ptr
, 2))
174 else if(!strncmpiW(offW
, ptr
, 3))
185 /***********************************************************************
186 * COMM_BuildOldCommDCB (Internal)
188 * Build a DCB using the old style settings string eg: "96,n,8,1"
190 static BOOL
COMM_BuildOldCommDCB(LPCWSTR device
, LPDCB lpdcb
)
194 if(!(device
= COMM_ParseNumber(device
, &lpdcb
->BaudRate
)))
197 switch(lpdcb
->BaudRate
)
202 lpdcb
->BaudRate
*= 10;
208 lpdcb
->BaudRate
*= 100;
211 lpdcb
->BaudRate
= 19200;
215 while(*device
== ' ') device
++;
216 if(*device
++ != ',') return FALSE
;
217 while(*device
== ' ') device
++;
219 if(!(device
= COMM_ParseParity(device
, &lpdcb
->Parity
)))
222 while(*device
== ' ') device
++;
223 if(*device
++ != ',') return FALSE
;
224 while(*device
== ' ') device
++;
226 if(!(device
= COMM_ParseByteSize(device
, &lpdcb
->ByteSize
)))
229 while(*device
== ' ') device
++;
230 if(*device
++ != ',') return FALSE
;
231 while(*device
== ' ') device
++;
233 if(!(device
= COMM_ParseStopBits(device
, &lpdcb
->StopBits
)))
236 /* The last parameter for flow control is optional. */
237 while(*device
== ' ') device
++;
241 while(*device
== ' ') device
++;
242 if(*device
) last
= toupperW(*device
++);
243 while(*device
== ' ') device
++;
246 /* Win NT sets the flow control members based on (or lack of) the last
247 parameter. Win 9x does not set these members. */
252 lpdcb
->fOutX
= FALSE
;
253 lpdcb
->fOutxCtsFlow
= FALSE
;
254 lpdcb
->fOutxDsrFlow
= FALSE
;
255 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
256 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
261 lpdcb
->fOutxCtsFlow
= FALSE
;
262 lpdcb
->fOutxDsrFlow
= FALSE
;
263 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
264 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
268 lpdcb
->fOutX
= FALSE
;
269 lpdcb
->fOutxCtsFlow
= TRUE
;
270 lpdcb
->fOutxDsrFlow
= TRUE
;
271 lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
;
272 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
278 /* This should be the end of the string. */
279 if(*device
) return FALSE
;
284 /***********************************************************************
285 * COMM_BuildNewCommDCB (Internal)
287 * Build a DCB using the new style settings string.
288 * eg: "baud=9600 parity=n data=8 stop=1 xon=on to=on"
290 static BOOL
COMM_BuildNewCommDCB(LPCWSTR device
, LPDCB lpdcb
, LPCOMMTIMEOUTS lptimeouts
)
293 BOOL baud
= FALSE
, stop
= FALSE
;
294 static const WCHAR baudW
[] = {'b','a','u','d','=',0};
295 static const WCHAR parityW
[] = {'p','a','r','i','t','y','=',0};
296 static const WCHAR dataW
[] = {'d','a','t','a','=',0};
297 static const WCHAR stopW
[] = {'s','t','o','p','=',0};
298 static const WCHAR toW
[] = {'t','o','=',0};
299 static const WCHAR xonW
[] = {'x','o','n','=',0};
300 static const WCHAR odsrW
[] = {'o','d','s','r','=',0};
301 static const WCHAR octsW
[] = {'o','c','t','s','=',0};
302 static const WCHAR dtrW
[] = {'d','t','r','=',0};
303 static const WCHAR rtsW
[] = {'r','t','s','=',0};
304 static const WCHAR idsrW
[] = {'i','d','s','r','=',0};
308 while(*device
== ' ') device
++;
310 if(!strncmpiW(baudW
, device
, 5))
314 if(!(device
= COMM_ParseNumber(device
+ 5, &lpdcb
->BaudRate
)))
317 else if(!strncmpiW(parityW
, device
, 7))
319 if(!(device
= COMM_ParseParity(device
+ 7, &lpdcb
->Parity
)))
322 else if(!strncmpiW(dataW
, device
, 5))
324 if(!(device
= COMM_ParseByteSize(device
+ 5, &lpdcb
->ByteSize
)))
327 else if(!strncmpiW(stopW
, device
, 5))
331 if(!(device
= COMM_ParseStopBits(device
+ 5, &lpdcb
->StopBits
)))
334 else if(!strncmpiW(toW
, device
, 3))
336 if(!(device
= COMM_ParseOnOff(device
+ 3, &temp
)))
339 lptimeouts
->ReadIntervalTimeout
= 0;
340 lptimeouts
->ReadTotalTimeoutMultiplier
= 0;
341 lptimeouts
->ReadTotalTimeoutConstant
= 0;
342 lptimeouts
->WriteTotalTimeoutMultiplier
= 0;
343 lptimeouts
->WriteTotalTimeoutConstant
= temp
? 60000 : 0;
345 else if(!strncmpiW(xonW
, device
, 4))
347 if(!(device
= COMM_ParseOnOff(device
+ 4, &temp
)))
353 else if(!strncmpiW(odsrW
, device
, 5))
355 if(!(device
= COMM_ParseOnOff(device
+ 5, &temp
)))
358 lpdcb
->fOutxDsrFlow
= temp
;
360 else if(!strncmpiW(octsW
, device
, 5))
362 if(!(device
= COMM_ParseOnOff(device
+ 5, &temp
)))
365 lpdcb
->fOutxCtsFlow
= temp
;
367 else if(!strncmpiW(dtrW
, device
, 4))
369 if(!(device
= COMM_ParseOnOff(device
+ 4, &temp
)))
372 lpdcb
->fDtrControl
= temp
;
374 else if(!strncmpiW(rtsW
, device
, 4))
376 if(!(device
= COMM_ParseOnOff(device
+ 4, &temp
)))
379 lpdcb
->fRtsControl
= temp
;
381 else if(!strncmpiW(idsrW
, device
, 5))
383 if(!(device
= COMM_ParseOnOff(device
+ 5, &temp
)))
386 /* Win NT sets the fDsrSensitivity member based on the
387 idsr parameter. Win 9x sets fOutxDsrFlow instead. */
388 lpdcb
->fDsrSensitivity
= temp
;
393 /* After the above parsing, the next character (if not the end of
394 the string) should be a space */
395 if(*device
&& *device
!= ' ')
399 /* If stop bits were not specified, a default is always supplied. */
402 if(baud
&& lpdcb
->BaudRate
== 110)
403 lpdcb
->StopBits
= TWOSTOPBITS
;
405 lpdcb
->StopBits
= ONESTOPBIT
;
411 /**************************************************************************
412 * BuildCommDCBA (KERNEL32.@)
414 * Updates a device control block data structure with values from an
415 * ascii device control string. The device control string has two forms
416 * normal and extended, it must be exclusively in one or the other form.
420 * True on success, false on a malformed control string.
422 BOOL WINAPI
BuildCommDCBA(
423 LPCSTR device
, /* [in] The ascii device control string used to update the DCB. */
424 LPDCB lpdcb
) /* [out] The device control block to be updated. */
426 return BuildCommDCBAndTimeoutsA(device
,lpdcb
,NULL
);
429 /**************************************************************************
430 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
432 * Updates a device control block data structure with values from an
433 * ascii device control string. Taking timeout values from a timeouts
434 * struct if desired by the control string.
438 * True on success, false bad handles etc.
440 BOOL WINAPI
BuildCommDCBAndTimeoutsA(
441 LPCSTR device
, /* [in] The ascii device control string. */
442 LPDCB lpdcb
, /* [out] The device control block to be updated. */
443 LPCOMMTIMEOUTS lptimeouts
) /* [in] The COMMTIMEOUTS structure to be updated. */
446 UNICODE_STRING deviceW
;
448 TRACE("(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
449 if(device
) RtlCreateUnicodeStringFromAsciiz(&deviceW
,device
);
450 else deviceW
.Buffer
= NULL
;
452 if(deviceW
.Buffer
) ret
= BuildCommDCBAndTimeoutsW(deviceW
.Buffer
,lpdcb
,lptimeouts
);
454 RtlFreeUnicodeString(&deviceW
);
458 /**************************************************************************
459 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
461 * Updates a device control block data structure with values from a
462 * unicode device control string. Taking timeout values from a timeouts
463 * struct if desired by the control string.
467 * True on success, false bad handles etc
469 BOOL WINAPI
BuildCommDCBAndTimeoutsW(
470 LPCWSTR devid
, /* [in] The unicode device control string. */
471 LPDCB lpdcb
, /* [out] The device control block to be updated. */
472 LPCOMMTIMEOUTS lptimeouts
) /* [in] The COMMTIMEOUTS structure to be updated. */
475 COMMTIMEOUTS timeouts
;
479 TRACE("(%s,%p,%p)\n",debugstr_w(devid
),lpdcb
,lptimeouts
);
481 memset(&timeouts
, 0, sizeof timeouts
);
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) */
490 if(lptimeouts
) timeouts
= *lptimeouts
;
492 ptr
= COMM_ParseStart(ptr
);
496 else if(strchrW(ptr
, ','))
497 result
= COMM_BuildOldCommDCB(ptr
, &dcb
);
499 result
= COMM_BuildNewCommDCB(ptr
, &dcb
, &timeouts
);
504 if(lptimeouts
) *lptimeouts
= timeouts
;
509 WARN("Invalid device control string: %s\n", debugstr_w(devid
));
510 SetLastError(ERROR_INVALID_PARAMETER
);
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.
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.
539 * handle [in] The communications device to suspend
543 * True on success, and false if the communications device could not be found,
544 * the control is not supported.
548 * Only TIOCSBRK and TIOCCBRK are supported.
550 BOOL WINAPI
SetCommBreak(HANDLE handle
)
552 DWORD dwBytesReturned
;
553 return DeviceIoControl(handle
, IOCTL_SERIAL_SET_BREAK_ON
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
556 /*****************************************************************************
557 * ClearCommBreak (KERNEL32.@)
559 * Resumes character transmission from a communication device.
563 * handle [in] The halted communication device whose character transmission is to be resumed
567 * True on success and false if the communications device could not be found.
571 * Only TIOCSBRK and TIOCCBRK are supported.
573 BOOL WINAPI
ClearCommBreak(HANDLE handle
)
575 DWORD dwBytesReturned
;
576 return DeviceIoControl(handle
, IOCTL_SERIAL_SET_BREAK_OFF
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
579 /*****************************************************************************
580 * EscapeCommFunction (KERNEL32.@)
582 * Directs a communication device to perform an extended function.
586 * handle [in] The communication device to perform the extended function
587 * nFunction [in] The extended function to be performed
591 * True or requested data on successful completion of the command,
592 * false if the device is not present cannot execute the command
593 * or the command failed.
595 BOOL WINAPI
EscapeCommFunction(HANDLE handle
, DWORD func
)
598 DWORD dwBytesReturned
;
602 case CLRDTR
: ioc
= IOCTL_SERIAL_CLR_DTR
; break;
603 case CLRRTS
: ioc
= IOCTL_SERIAL_CLR_RTS
; break;
604 case SETDTR
: ioc
= IOCTL_SERIAL_SET_DTR
; break;
605 case SETRTS
: ioc
= IOCTL_SERIAL_SET_RTS
; break;
606 case SETXOFF
: ioc
= IOCTL_SERIAL_SET_XOFF
; break;
607 case SETXON
: ioc
= IOCTL_SERIAL_SET_XON
; break;
608 case SETBREAK
: ioc
= IOCTL_SERIAL_SET_BREAK_ON
; break;
609 case CLRBREAK
: ioc
= IOCTL_SERIAL_SET_BREAK_OFF
; break;
610 case RESETDEV
: ioc
= IOCTL_SERIAL_RESET_DEVICE
; break;
612 ERR("Unknown function code (%u)\n", func
);
613 SetLastError(ERROR_INVALID_PARAMETER
);
616 return DeviceIoControl(handle
, ioc
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
619 /********************************************************************
620 * PurgeComm (KERNEL32.@)
622 * Terminates pending operations and/or discards buffers on a
623 * communication resource.
627 * handle [in] The communication resource to be purged
628 * flags [in] Flags for clear pending/buffer on input/output
632 * True on success and false if the communications handle is bad.
634 BOOL WINAPI
PurgeComm(HANDLE handle
, DWORD flags
)
636 DWORD dwBytesReturned
;
637 return DeviceIoControl(handle
, IOCTL_SERIAL_PURGE
, &flags
, sizeof(flags
),
638 NULL
, 0, &dwBytesReturned
, NULL
);
641 /*****************************************************************************
642 * ClearCommError (KERNEL32.@)
644 * Enables further I/O operations on a communications resource after
645 * supplying error and current status information.
649 * handle [in] The communication resource with the error
650 * errors [out] Flags indicating error the resource experienced
651 * lpStat [out] The status of the communication resource
654 * True on success, false if the communication resource handle is bad.
656 BOOL WINAPI
ClearCommError(HANDLE handle
, LPDWORD errors
, LPCOMSTAT lpStat
)
659 DWORD dwBytesReturned
;
661 if (!DeviceIoControl(handle
, IOCTL_SERIAL_GET_COMMSTATUS
, NULL
, 0,
662 &ss
, sizeof(ss
), &dwBytesReturned
, NULL
))
665 TRACE("=> status %#x,%#x, in %u, out %u, eof %d, wait %d\n", ss
.Errors
, ss
.HoldReasons
,
666 ss
.AmountInInQueue
, ss
.AmountInOutQueue
, ss
.EofReceived
, ss
.WaitForImmediate
);
671 if (ss
.Errors
& SERIAL_ERROR_BREAK
) *errors
|= CE_BREAK
;
672 if (ss
.Errors
& SERIAL_ERROR_FRAMING
) *errors
|= CE_FRAME
;
673 if (ss
.Errors
& SERIAL_ERROR_OVERRUN
) *errors
|= CE_OVERRUN
;
674 if (ss
.Errors
& SERIAL_ERROR_QUEUEOVERRUN
) *errors
|= CE_RXOVER
;
675 if (ss
.Errors
& SERIAL_ERROR_PARITY
) *errors
|= CE_RXPARITY
;
680 memset(lpStat
, 0, sizeof(*lpStat
));
682 if (ss
.HoldReasons
& SERIAL_TX_WAITING_FOR_CTS
) lpStat
->fCtsHold
= TRUE
;
683 if (ss
.HoldReasons
& SERIAL_TX_WAITING_FOR_DSR
) lpStat
->fDsrHold
= TRUE
;
684 if (ss
.HoldReasons
& SERIAL_TX_WAITING_FOR_DCD
) lpStat
->fRlsdHold
= TRUE
;
685 if (ss
.HoldReasons
& SERIAL_TX_WAITING_FOR_XON
) lpStat
->fXoffHold
= TRUE
;
686 if (ss
.HoldReasons
& SERIAL_TX_WAITING_XOFF_SENT
) lpStat
->fXoffSent
= TRUE
;
687 if (ss
.EofReceived
) lpStat
->fEof
= TRUE
;
688 if (ss
.WaitForImmediate
) lpStat
->fTxim
= TRUE
;
689 lpStat
->cbInQue
= ss
.AmountInInQueue
;
690 lpStat
->cbOutQue
= ss
.AmountInOutQueue
;
695 /*****************************************************************************
696 * SetupComm (KERNEL32.@)
698 * Called after CreateFile to hint to the communication resource to use
699 * specified sizes for input and output buffers rather than the default values.
702 * handle [in] The just created communication resource handle
703 * insize [in] The suggested size of the communication resources input buffer in bytes
704 * outsize [in] The suggested size of the communication resources output buffer in bytes
708 * True if successful, false if the communications resource handle is bad.
714 BOOL WINAPI
SetupComm(HANDLE handle
, DWORD insize
, DWORD outsize
)
716 SERIAL_QUEUE_SIZE sqs
;
717 DWORD dwBytesReturned
;
720 sqs
.OutSize
= outsize
;
721 return DeviceIoControl(handle
, IOCTL_SERIAL_SET_QUEUE_SIZE
,
722 &sqs
, sizeof(sqs
), NULL
, 0, &dwBytesReturned
, NULL
);
725 /*****************************************************************************
726 * GetCommMask (KERNEL32.@)
728 * Obtain the events associated with a communication device that will cause
729 * a call WaitCommEvent to return.
733 * handle [in] The communications device
734 * evtmask [out] The events which cause WaitCommEvent to return
738 * True on success, fail on bad device handle etc.
740 BOOL WINAPI
GetCommMask(HANDLE handle
, LPDWORD evtmask
)
742 DWORD dwBytesReturned
;
743 TRACE("handle %p, mask %p\n", handle
, evtmask
);
744 return DeviceIoControl(handle
, IOCTL_SERIAL_GET_WAIT_MASK
,
745 NULL
, 0, evtmask
, sizeof(*evtmask
), &dwBytesReturned
, NULL
);
748 /*****************************************************************************
749 * SetCommMask (KERNEL32.@)
751 * There be some things we need to hear about yon there communications device.
752 * (Set which events associated with a communication device should cause
753 * a call WaitCommEvent to return.)
757 * handle [in] The communications device
758 * evtmask [in] The events that are to be monitored
762 * True on success, false on bad handle etc.
764 BOOL WINAPI
SetCommMask(HANDLE handle
, DWORD evtmask
)
766 DWORD dwBytesReturned
;
767 TRACE("handle %p, mask %x\n", handle
, evtmask
);
768 return DeviceIoControl(handle
, IOCTL_SERIAL_SET_WAIT_MASK
,
769 &evtmask
, sizeof(evtmask
), NULL
, 0, &dwBytesReturned
, NULL
);
772 static void dump_dcb(const DCB
* lpdcb
)
774 TRACE("bytesize=%d baudrate=%d fParity=%d Parity=%d stopbits=%d\n",
775 lpdcb
->ByteSize
, lpdcb
->BaudRate
, lpdcb
->fParity
, lpdcb
->Parity
,
776 (lpdcb
->StopBits
== ONESTOPBIT
) ? 1 :
777 (lpdcb
->StopBits
== TWOSTOPBITS
) ? 2 : 0);
778 TRACE("%sIXON %sIXOFF\n", (lpdcb
->fOutX
) ? "" : "~", (lpdcb
->fInX
) ? "" : "~");
779 TRACE("fOutxCtsFlow=%d fRtsControl=%d\n", lpdcb
->fOutxCtsFlow
, lpdcb
->fRtsControl
);
780 TRACE("fOutxDsrFlow=%d fDtrControl=%d\n", lpdcb
->fOutxDsrFlow
, lpdcb
->fDtrControl
);
781 if (lpdcb
->fOutxCtsFlow
|| lpdcb
->fRtsControl
== RTS_CONTROL_HANDSHAKE
)
787 /*****************************************************************************
788 * SetCommState (KERNEL32.@)
790 * Re-initializes all hardware and control settings of a communications device,
791 * with values from a device control block without affecting the input and output
796 * handle [in] The communications device
797 * lpdcb [out] The device control block
801 * True on success, false on failure, e.g., if the XonChar is equal to the XoffChar.
803 BOOL WINAPI
SetCommState( HANDLE handle
, LPDCB lpdcb
)
805 SERIAL_BAUD_RATE sbr
;
806 SERIAL_LINE_CONTROL slc
;
809 DWORD dwBytesReturned
;
811 TRACE("handle %p, ptr %p\n", handle
, lpdcb
);
815 SetLastError(ERROR_INVALID_PARAMETER
);
820 sbr
.BaudRate
= lpdcb
->BaudRate
;
822 slc
.StopBits
= lpdcb
->StopBits
;
823 slc
.Parity
= lpdcb
->Parity
;
824 slc
.WordLength
= lpdcb
->ByteSize
;
826 shf
.ControlHandShake
= 0;
828 if (lpdcb
->fOutxCtsFlow
) shf
.ControlHandShake
|= SERIAL_CTS_HANDSHAKE
;
829 if (lpdcb
->fOutxDsrFlow
) shf
.ControlHandShake
|= SERIAL_DSR_HANDSHAKE
;
830 switch (lpdcb
->fDtrControl
)
832 case DTR_CONTROL_DISABLE
: break;
833 case DTR_CONTROL_ENABLE
: shf
.ControlHandShake
|= SERIAL_DTR_CONTROL
; break;
834 case DTR_CONTROL_HANDSHAKE
: shf
.ControlHandShake
|= SERIAL_DTR_HANDSHAKE
;break;
836 SetLastError(ERROR_INVALID_PARAMETER
);
839 switch (lpdcb
->fRtsControl
)
841 case RTS_CONTROL_DISABLE
: break;
842 case RTS_CONTROL_ENABLE
: shf
.FlowReplace
|= SERIAL_RTS_CONTROL
; break;
843 case RTS_CONTROL_HANDSHAKE
: shf
.FlowReplace
|= SERIAL_RTS_HANDSHAKE
; break;
844 case RTS_CONTROL_TOGGLE
: shf
.FlowReplace
|= SERIAL_RTS_CONTROL
|
845 SERIAL_RTS_HANDSHAKE
; break;
847 SetLastError(ERROR_INVALID_PARAMETER
);
850 if (lpdcb
->fDsrSensitivity
) shf
.ControlHandShake
|= SERIAL_DSR_SENSITIVITY
;
851 if (lpdcb
->fAbortOnError
) shf
.ControlHandShake
|= SERIAL_ERROR_ABORT
;
853 if (lpdcb
->fErrorChar
) shf
.FlowReplace
|= SERIAL_ERROR_CHAR
;
854 if (lpdcb
->fNull
) shf
.FlowReplace
|= SERIAL_NULL_STRIPPING
;
855 if (lpdcb
->fTXContinueOnXoff
) shf
.FlowReplace
|= SERIAL_XOFF_CONTINUE
;
856 if (lpdcb
->fOutX
) shf
.FlowReplace
|= SERIAL_AUTO_TRANSMIT
;
857 if (lpdcb
->fInX
) shf
.FlowReplace
|= SERIAL_AUTO_RECEIVE
;
859 shf
.XonLimit
= lpdcb
->XonLim
;
860 shf
.XoffLimit
= lpdcb
->XoffLim
;
862 sc
.EofChar
= lpdcb
->EofChar
;
863 sc
.ErrorChar
= lpdcb
->ErrorChar
;
865 sc
.EventChar
= lpdcb
->EvtChar
;
866 sc
.XonChar
= lpdcb
->XonChar
;
867 sc
.XoffChar
= lpdcb
->XoffChar
;
869 /* note: change DTR/RTS lines after setting the comm attributes,
870 * so flow control does not interfere.
872 return (DeviceIoControl(handle
, IOCTL_SERIAL_SET_BAUD_RATE
,
873 &sbr
, sizeof(sbr
), NULL
, 0, &dwBytesReturned
, NULL
) &&
874 DeviceIoControl(handle
, IOCTL_SERIAL_SET_LINE_CONTROL
,
875 &slc
, sizeof(slc
), NULL
, 0, &dwBytesReturned
, NULL
) &&
876 DeviceIoControl(handle
, IOCTL_SERIAL_SET_HANDFLOW
,
877 &shf
, sizeof(shf
), NULL
, 0, &dwBytesReturned
, NULL
) &&
878 DeviceIoControl(handle
, IOCTL_SERIAL_SET_CHARS
,
879 &sc
, sizeof(sc
), NULL
, 0, &dwBytesReturned
, NULL
));
883 /*****************************************************************************
884 * GetCommState (KERNEL32.@)
886 * Fills in a device control block with information from a communications device.
889 * handle [in] The communications device
890 * lpdcb [out] The device control block
894 * True on success, false if the communication device handle is bad etc
898 * XonChar and XoffChar are not set.
900 BOOL WINAPI
GetCommState(HANDLE handle
, LPDCB lpdcb
)
902 SERIAL_BAUD_RATE sbr
;
903 SERIAL_LINE_CONTROL slc
;
906 DWORD dwBytesReturned
;
908 TRACE("handle %p, ptr %p\n", handle
, lpdcb
);
912 SetLastError(ERROR_INVALID_PARAMETER
);
916 if (!DeviceIoControl(handle
, IOCTL_SERIAL_GET_BAUD_RATE
,
917 NULL
, 0, &sbr
, sizeof(sbr
), &dwBytesReturned
, NULL
) ||
918 !DeviceIoControl(handle
, IOCTL_SERIAL_GET_LINE_CONTROL
,
919 NULL
, 0, &slc
, sizeof(slc
), &dwBytesReturned
, NULL
) ||
920 !DeviceIoControl(handle
, IOCTL_SERIAL_GET_HANDFLOW
,
921 NULL
, 0, &shf
, sizeof(shf
), &dwBytesReturned
, NULL
) ||
922 !DeviceIoControl(handle
, IOCTL_SERIAL_GET_CHARS
,
923 NULL
, 0, &sc
, sizeof(sc
), &dwBytesReturned
, NULL
))
926 memset(lpdcb
, 0, sizeof(*lpdcb
));
927 lpdcb
->DCBlength
= sizeof(*lpdcb
);
929 /* yes, they seem no never be (re)set on NT */
933 lpdcb
->BaudRate
= sbr
.BaudRate
;
935 lpdcb
->StopBits
= slc
.StopBits
;
936 lpdcb
->Parity
= slc
.Parity
;
937 lpdcb
->ByteSize
= slc
.WordLength
;
939 if (shf
.ControlHandShake
& SERIAL_CTS_HANDSHAKE
) lpdcb
->fOutxCtsFlow
= 1;
940 if (shf
.ControlHandShake
& SERIAL_DSR_HANDSHAKE
) lpdcb
->fOutxDsrFlow
= 1;
941 switch (shf
.ControlHandShake
& (SERIAL_DTR_CONTROL
| SERIAL_DTR_HANDSHAKE
))
943 case 0: lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
; break;
944 case SERIAL_DTR_CONTROL
: lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
; break;
945 case SERIAL_DTR_HANDSHAKE
: lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
; break;
947 switch (shf
.FlowReplace
& (SERIAL_RTS_CONTROL
| SERIAL_RTS_HANDSHAKE
))
949 case 0: lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
; break;
950 case SERIAL_RTS_CONTROL
: lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
; break;
951 case SERIAL_RTS_HANDSHAKE
: lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
; break;
952 case SERIAL_RTS_CONTROL
| SERIAL_RTS_HANDSHAKE
:
953 lpdcb
->fRtsControl
= RTS_CONTROL_TOGGLE
; break;
955 if (shf
.ControlHandShake
& SERIAL_DSR_SENSITIVITY
) lpdcb
->fDsrSensitivity
= 1;
956 if (shf
.ControlHandShake
& SERIAL_ERROR_ABORT
) lpdcb
->fAbortOnError
= 1;
957 if (shf
.FlowReplace
& SERIAL_ERROR_CHAR
) lpdcb
->fErrorChar
= 1;
958 if (shf
.FlowReplace
& SERIAL_NULL_STRIPPING
) lpdcb
->fNull
= 1;
959 if (shf
.FlowReplace
& SERIAL_XOFF_CONTINUE
) lpdcb
->fTXContinueOnXoff
= 1;
960 lpdcb
->XonLim
= shf
.XonLimit
;
961 lpdcb
->XoffLim
= shf
.XoffLimit
;
963 if (shf
.FlowReplace
& SERIAL_AUTO_TRANSMIT
) lpdcb
->fOutX
= 1;
964 if (shf
.FlowReplace
& SERIAL_AUTO_RECEIVE
) lpdcb
->fInX
= 1;
966 lpdcb
->EofChar
= sc
.EofChar
;
967 lpdcb
->ErrorChar
= sc
.ErrorChar
;
968 lpdcb
->EvtChar
= sc
.EventChar
;
969 lpdcb
->XonChar
= sc
.XonChar
;
970 lpdcb
->XoffChar
= sc
.XoffChar
;
978 /*****************************************************************************
979 * TransmitCommChar (KERNEL32.@)
981 * Transmits a single character in front of any pending characters in the
982 * output buffer. Usually used to send an interrupt character to a host.
985 * hComm [in] The communication device in need of a command character
986 * chTransmit [in] The character to transmit
990 * True if the call succeeded, false if the previous command character to the
991 * same device has not been sent yet the handle is bad etc.
994 BOOL WINAPI
TransmitCommChar(HANDLE hComm
, CHAR chTransmit
)
996 DWORD dwBytesReturned
;
997 return DeviceIoControl(hComm
, IOCTL_SERIAL_IMMEDIATE_CHAR
,
998 &chTransmit
, sizeof(chTransmit
), NULL
, 0, &dwBytesReturned
, NULL
);
1002 /*****************************************************************************
1003 * GetCommTimeouts (KERNEL32.@)
1005 * Obtains the request timeout values for the communications device.
1008 * hComm [in] The communications device
1009 * lptimeouts [out] The struct of request timeouts
1013 * True on success, false if communications device handle is bad
1014 * or the target structure is null.
1016 BOOL WINAPI
GetCommTimeouts(HANDLE hComm
, LPCOMMTIMEOUTS lptimeouts
)
1019 DWORD dwBytesReturned
;
1021 TRACE("(%p, %p)\n", hComm
, lptimeouts
);
1024 SetLastError(ERROR_INVALID_PARAMETER
);
1027 if (!DeviceIoControl(hComm
, IOCTL_SERIAL_GET_TIMEOUTS
,
1028 NULL
, 0, &st
, sizeof(st
), &dwBytesReturned
, NULL
))
1030 lptimeouts
->ReadIntervalTimeout
= st
.ReadIntervalTimeout
;
1031 lptimeouts
->ReadTotalTimeoutMultiplier
= st
.ReadTotalTimeoutMultiplier
;
1032 lptimeouts
->ReadTotalTimeoutConstant
= st
.ReadTotalTimeoutConstant
;
1033 lptimeouts
->WriteTotalTimeoutMultiplier
= st
.WriteTotalTimeoutMultiplier
;
1034 lptimeouts
->WriteTotalTimeoutConstant
= st
.WriteTotalTimeoutConstant
;
1038 /*****************************************************************************
1039 * SetCommTimeouts (KERNEL32.@)
1041 * Sets the timeouts used when reading and writing data to/from COMM ports.
1044 * hComm [in] handle of COMM device
1045 * lptimeouts [in] pointer to COMMTIMEOUTS structure
1047 * ReadIntervalTimeout
1048 * - converted and passes to linux kernel as c_cc[VTIME]
1049 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1050 * - used in ReadFile to calculate GetOverlappedResult's timeout
1051 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1052 * - used in WriteFile to calculate GetOverlappedResult's timeout
1056 * True if the timeouts were set, false otherwise.
1058 BOOL WINAPI
SetCommTimeouts(HANDLE hComm
, LPCOMMTIMEOUTS lptimeouts
)
1061 DWORD dwBytesReturned
;
1063 TRACE("(%p, %p)\n", hComm
, lptimeouts
);
1065 if (lptimeouts
== NULL
)
1067 SetLastError(ERROR_INVALID_PARAMETER
);
1070 st
.ReadIntervalTimeout
= lptimeouts
->ReadIntervalTimeout
;
1071 st
.ReadTotalTimeoutMultiplier
= lptimeouts
->ReadTotalTimeoutMultiplier
;
1072 st
.ReadTotalTimeoutConstant
= lptimeouts
->ReadTotalTimeoutConstant
;
1073 st
.WriteTotalTimeoutMultiplier
= lptimeouts
->WriteTotalTimeoutMultiplier
;
1074 st
.WriteTotalTimeoutConstant
= lptimeouts
->WriteTotalTimeoutConstant
;
1076 return DeviceIoControl(hComm
, IOCTL_SERIAL_SET_TIMEOUTS
,
1077 &st
, sizeof(st
), NULL
, 0, &dwBytesReturned
, NULL
);
1080 /***********************************************************************
1081 * GetCommModemStatus (KERNEL32.@)
1083 * Obtains the four control register bits if supported by the hardware.
1087 * hFile [in] The communications device
1088 * lpModemStat [out] The control register bits
1092 * True if the communications handle was good and for hardware that
1093 * control register access, false otherwise.
1095 BOOL WINAPI
GetCommModemStatus(HANDLE hFile
, LPDWORD lpModemStat
)
1097 DWORD dwBytesReturned
;
1098 return DeviceIoControl(hFile
, IOCTL_SERIAL_GET_MODEMSTATUS
,
1099 NULL
, 0, lpModemStat
, sizeof(DWORD
), &dwBytesReturned
, NULL
);
1102 /***********************************************************************
1103 * WaitCommEvent (KERNEL32.@)
1105 * Wait until something interesting happens on a COMM port.
1106 * Interesting things (events) are set by calling SetCommMask before
1107 * this function is called.
1110 * TRUE if successful
1113 * The set of detected events will be written to *lpdwEventMask
1114 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1117 * Only supports EV_RXCHAR and EV_TXEMPTY
1119 BOOL WINAPI
WaitCommEvent(
1120 HANDLE hFile
, /* [in] handle of comm port to wait for */
1121 LPDWORD lpdwEvents
, /* [out] event(s) that were detected */
1122 LPOVERLAPPED lpOverlapped
) /* [in/out] for Asynchronous waiting */
1124 return DeviceIoControl(hFile
, IOCTL_SERIAL_WAIT_ON_MASK
, NULL
, 0,
1125 lpdwEvents
, sizeof(DWORD
), NULL
, lpOverlapped
);
1128 /***********************************************************************
1129 * GetCommProperties (KERNEL32.@)
1131 * This function fills in a structure with the capabilities of the
1132 * communications port driver.
1136 * TRUE on success, FALSE on failure
1137 * If successful, the lpCommProp structure be filled in with
1138 * properties of the comm port.
1140 BOOL WINAPI
GetCommProperties(
1141 HANDLE hFile
, /* [in] handle of the comm port */
1142 LPCOMMPROP lpCommProp
) /* [out] pointer to struct to be filled */
1144 TRACE("(%p %p)\n",hFile
,lpCommProp
);
1149 * These values should be valid for LINUX's serial driver
1150 * FIXME: Perhaps they deserve an #ifdef LINUX
1152 memset(lpCommProp
,0,sizeof(COMMPROP
));
1153 lpCommProp
->wPacketLength
= 1;
1154 lpCommProp
->wPacketVersion
= 1;
1155 lpCommProp
->dwServiceMask
= SP_SERIALCOMM
;
1156 lpCommProp
->dwMaxTxQueue
= 4096;
1157 lpCommProp
->dwMaxRxQueue
= 4096;
1158 lpCommProp
->dwMaxBaud
= BAUD_115200
;
1159 lpCommProp
->dwProvSubType
= PST_RS232
;
1160 lpCommProp
->dwProvCapabilities
= PCF_DTRDSR
| PCF_PARITY_CHECK
| PCF_RTSCTS
| PCF_TOTALTIMEOUTS
| PCF_INTTIMEOUTS
;
1161 lpCommProp
->dwSettableParams
= SP_BAUD
| SP_DATABITS
| SP_HANDSHAKING
|
1162 SP_PARITY
| SP_PARITY_CHECK
| SP_STOPBITS
;
1163 lpCommProp
->dwSettableBaud
= BAUD_075
| BAUD_110
| BAUD_134_5
| BAUD_150
|
1164 BAUD_300
| BAUD_600
| BAUD_1200
| BAUD_1800
| BAUD_2400
| BAUD_4800
|
1165 BAUD_9600
| BAUD_19200
| BAUD_38400
| BAUD_57600
| BAUD_115200
;
1166 lpCommProp
->wSettableData
= DATABITS_5
| DATABITS_6
| DATABITS_7
| DATABITS_8
;
1167 lpCommProp
->wSettableStopParity
= STOPBITS_10
| STOPBITS_15
| STOPBITS_20
|
1168 PARITY_NONE
| PARITY_ODD
|PARITY_EVEN
| PARITY_MARK
| PARITY_SPACE
;
1169 lpCommProp
->dwCurrentTxQueue
= lpCommProp
->dwMaxTxQueue
;
1170 lpCommProp
->dwCurrentRxQueue
= lpCommProp
->dwMaxRxQueue
;
1175 /***********************************************************************
1177 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1178 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1179 * This is dependent on the type of COMM port, but since it is doubtful
1180 * anybody will get around to implementing support for fancy serial
1181 * ports in WINE, this is hardcoded for the time being. The name of
1182 * this DLL should be stored in and read from the system registry in
1183 * the hive HKEY_LOCAL_MACHINE, key
1184 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1185 * where ???? is the port number... that is determined by PNP
1186 * The DLL should be loaded when the COMM port is opened, and closed
1187 * when the COMM port is closed. - MJM 20 June 2000
1188 ***********************************************************************/
1189 static const WCHAR lpszSerialUI
[] = {
1190 's','e','r','i','a','l','u','i','.','d','l','l',0 };
1193 /***********************************************************************
1194 * CommConfigDialogA (KERNEL32.@)
1196 * Raises a dialog that allows the user to configure a comm port.
1197 * Fills the COMMCONFIG struct with information specified by the user.
1198 * This function should call a similar routine in the COMM driver...
1202 * TRUE on success, FALSE on failure
1203 * If successful, the lpCommConfig structure will contain a new
1204 * configuration for the comm port, as specified by the user.
1207 * The library with the CommConfigDialog code is never unloaded.
1208 * Perhaps this should be done when the comm port is closed?
1210 BOOL WINAPI
CommConfigDialogA(
1211 LPCSTR lpszDevice
, /* [in] name of communications device */
1212 HWND hWnd
, /* [in] parent window for the dialog */
1213 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
1215 LPWSTR lpDeviceW
= NULL
;
1219 TRACE("(%s, %p, %p)\n", debugstr_a(lpszDevice
), hWnd
, lpCommConfig
);
1223 len
= MultiByteToWideChar( CP_ACP
, 0, lpszDevice
, -1, NULL
, 0 );
1224 lpDeviceW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
1225 MultiByteToWideChar( CP_ACP
, 0, lpszDevice
, -1, lpDeviceW
, len
);
1227 r
= CommConfigDialogW(lpDeviceW
, hWnd
, lpCommConfig
);
1228 HeapFree( GetProcessHeap(), 0, lpDeviceW
);
1232 /***********************************************************************
1233 * CommConfigDialogW (KERNEL32.@)
1235 * See CommConfigDialogA.
1237 BOOL WINAPI
CommConfigDialogW(
1238 LPCWSTR lpszDevice
, /* [in] name of communications device */
1239 HWND hWnd
, /* [in] parent window for the dialog */
1240 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
1242 DWORD (WINAPI
*pCommConfigDialog
)(LPCWSTR
, HWND
, LPCOMMCONFIG
);
1243 HMODULE hConfigModule
;
1244 DWORD res
= ERROR_INVALID_PARAMETER
;
1246 TRACE("(%s, %p, %p)\n", debugstr_w(lpszDevice
), hWnd
, lpCommConfig
);
1247 hConfigModule
= LoadLibraryW(lpszSerialUI
);
1249 if (hConfigModule
) {
1250 pCommConfigDialog
= (void *)GetProcAddress(hConfigModule
, "drvCommConfigDialogW");
1251 if (pCommConfigDialog
) {
1252 res
= pCommConfigDialog(lpszDevice
, hWnd
, lpCommConfig
);
1254 FreeLibrary(hConfigModule
);
1257 if (res
) SetLastError(res
);
1258 return (res
== ERROR_SUCCESS
);
1261 /***********************************************************************
1262 * GetCommConfig (KERNEL32.@)
1264 * Fill in the COMMCONFIG structure for the comm port hFile
1268 * TRUE on success, FALSE on failure
1269 * If successful, lpCommConfig contains the comm port configuration.
1274 BOOL WINAPI
GetCommConfig(
1275 HANDLE hFile
, /* [in] The communications device. */
1276 LPCOMMCONFIG lpCommConfig
, /* [out] The communications configuration of the device (if it fits). */
1277 LPDWORD lpdwSize
) /* [in/out] Initially the size of the configuration buffer/structure,
1278 afterwards the number of bytes copied to the buffer or
1279 the needed size of the buffer. */
1283 TRACE("(%p, %p, %p) *lpdwSize: %u\n", hFile
, lpCommConfig
, lpdwSize
, lpdwSize
? *lpdwSize
: 0 );
1285 if(lpCommConfig
== NULL
)
1287 r
= *lpdwSize
< sizeof(COMMCONFIG
); /* TRUE if not enough space */
1288 *lpdwSize
= sizeof(COMMCONFIG
);
1292 lpCommConfig
->dwSize
= sizeof(COMMCONFIG
);
1293 lpCommConfig
->wVersion
= 1;
1294 lpCommConfig
->wReserved
= 0;
1295 r
= GetCommState(hFile
,&lpCommConfig
->dcb
);
1296 lpCommConfig
->dwProviderSubType
= PST_RS232
;
1297 lpCommConfig
->dwProviderOffset
= 0;
1298 lpCommConfig
->dwProviderSize
= 0;
1303 /***********************************************************************
1304 * SetCommConfig (KERNEL32.@)
1306 * Sets the configuration of the communications device.
1310 * True on success, false if the handle was bad is not a communications device.
1312 BOOL WINAPI
SetCommConfig(
1313 HANDLE hFile
, /* [in] The communications device. */
1314 LPCOMMCONFIG lpCommConfig
, /* [in] The desired configuration. */
1315 DWORD dwSize
) /* [in] size of the lpCommConfig struct */
1317 TRACE("(%p, %p, %u)\n", hFile
, lpCommConfig
, dwSize
);
1318 return SetCommState(hFile
,&lpCommConfig
->dcb
);
1321 /***********************************************************************
1322 * SetDefaultCommConfigW (KERNEL32.@)
1324 * Initializes the default configuration for a communication device.
1327 * lpszDevice [I] Name of the device targeted for configuration
1328 * lpCommConfig [I] PTR to a buffer with the configuration for the device
1329 * dwSize [I] Number of bytes in the buffer
1333 * Success: TRUE, and default configuration saved
1336 BOOL WINAPI
SetDefaultCommConfigW(LPCWSTR lpszDevice
, LPCOMMCONFIG lpCommConfig
, DWORD dwSize
)
1338 BOOL (WINAPI
*lpfnSetDefaultCommConfig
)(LPCWSTR
, LPCOMMCONFIG
, DWORD
);
1339 HMODULE hConfigModule
;
1342 TRACE("(%s, %p, %u)\n", debugstr_w(lpszDevice
), lpCommConfig
, dwSize
);
1344 hConfigModule
= LoadLibraryW(lpszSerialUI
);
1348 lpfnSetDefaultCommConfig
= (void *)GetProcAddress(hConfigModule
, "drvSetDefaultCommConfigW");
1349 if (lpfnSetDefaultCommConfig
)
1350 r
= lpfnSetDefaultCommConfig(lpszDevice
, lpCommConfig
, dwSize
);
1352 FreeLibrary(hConfigModule
);
1358 /***********************************************************************
1359 * SetDefaultCommConfigA (KERNEL32.@)
1361 * Initializes the default configuration for a communication device.
1363 * See SetDefaultCommConfigW.
1366 BOOL WINAPI
SetDefaultCommConfigA(LPCSTR lpszDevice
, LPCOMMCONFIG lpCommConfig
, DWORD dwSize
)
1369 LPWSTR lpDeviceW
= NULL
;
1372 TRACE("(%s, %p, %u)\n", debugstr_a(lpszDevice
), lpCommConfig
, dwSize
);
1376 len
= MultiByteToWideChar( CP_ACP
, 0, lpszDevice
, -1, NULL
, 0 );
1377 lpDeviceW
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1378 MultiByteToWideChar( CP_ACP
, 0, lpszDevice
, -1, lpDeviceW
, len
);
1380 r
= SetDefaultCommConfigW(lpDeviceW
,lpCommConfig
,dwSize
);
1381 HeapFree( GetProcessHeap(), 0, lpDeviceW
);
1386 /***********************************************************************
1387 * GetDefaultCommConfigW (KERNEL32.@)
1389 * Acquires the default configuration of the specified communication device. (unicode)
1393 * True on successful reading of the default configuration,
1394 * if the device is not found or the buffer is too small.
1396 BOOL WINAPI
GetDefaultCommConfigW(
1397 LPCWSTR lpszName
, /* [in] The unicode name of the device targeted for configuration. */
1398 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
1399 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
1400 afterwards the number of bytes copied to the buffer or
1401 the needed size of the buffer. */
1403 DWORD (WINAPI
*pGetDefaultCommConfig
)(LPCWSTR
, LPCOMMCONFIG
, LPDWORD
);
1404 HMODULE hConfigModule
;
1405 DWORD res
= ERROR_INVALID_PARAMETER
;
1407 TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_w(lpszName
), lpCC
, lpdwSize
, lpdwSize
? *lpdwSize
: 0 );
1408 hConfigModule
= LoadLibraryW(lpszSerialUI
);
1410 if (hConfigModule
) {
1411 pGetDefaultCommConfig
= (void *)GetProcAddress(hConfigModule
, "drvGetDefaultCommConfigW");
1412 if (pGetDefaultCommConfig
) {
1413 res
= pGetDefaultCommConfig(lpszName
, lpCC
, lpdwSize
);
1415 FreeLibrary(hConfigModule
);
1418 if (res
) SetLastError(res
);
1419 return (res
== ERROR_SUCCESS
);
1422 /**************************************************************************
1423 * GetDefaultCommConfigA (KERNEL32.@)
1425 * Acquires the default configuration of the specified communication device. (ascii)
1429 * True on successful reading of the default configuration,
1430 * if the device is not found or the buffer is too small.
1432 BOOL WINAPI
GetDefaultCommConfigA(
1433 LPCSTR lpszName
, /* [in] The ascii name of the device targeted for configuration. */
1434 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
1435 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
1436 afterwards the number of bytes copied to the buffer or
1437 the needed size of the buffer. */
1440 UNICODE_STRING lpszNameW
;
1442 TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_a(lpszName
), lpCC
, lpdwSize
, lpdwSize
? *lpdwSize
: 0 );
1443 if(lpszName
) RtlCreateUnicodeStringFromAsciiz(&lpszNameW
,lpszName
);
1444 else lpszNameW
.Buffer
= NULL
;
1446 ret
= GetDefaultCommConfigW(lpszNameW
.Buffer
,lpCC
,lpdwSize
);
1448 RtlFreeUnicodeString(&lpszNameW
);