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
23 typedef LARGE_INTEGER PHYSICAL_ADDRESS
, *PPHYSICAL_ADDRESS
;
24 #undef SERIAL_LSRMST_ESCAPE
25 #undef SERIAL_LSRMST_LSR_DATA
26 #undef SERIAL_LSRMST_LSR_NODATA
27 #undef SERIAL_LSRMST_MST
28 #undef SERIAL_IOC_FCR_FIFO_ENABLE
29 #undef SERIAL_IOC_FCR_RCVR_RESET
30 #undef SERIAL_IOC_FCR_XMIT_RESET
31 #undef SERIAL_IOC_FCR_DMA_MODE
32 #undef SERIAL_IOC_FCR_RES1
33 #undef SERIAL_IOC_FCR_RES2
34 #undef SERIAL_IOC_FCR_RCVR_TRIGGER_LSB
35 #undef SERIAL_IOC_FCR_RCVR_TRIGGER_MSB
36 #undef SERIAL_IOC_MCR_DTR
37 #undef SERIAL_IOC_MCR_RTS
38 #undef SERIAL_IOC_MCR_OUT1
39 #undef SERIAL_IOC_MCR_OUT2
40 #undef SERIAL_IOC_MCR_LOOP
41 #undef IOCTL_SERIAL_LSRMST_INSERT
48 /***********************************************************************
49 * COMM_Parse* (Internal)
51 * The following COMM_Parse* functions are used by the BuildCommDCB
52 * functions to help parse the various parts of the device control string.
54 static LPCWSTR
COMM_ParseStart(LPCWSTR ptr
)
56 static const WCHAR comW
[] = {'C','O','M',0};
58 /* The device control string may optionally start with "COMx" followed
59 by an optional ':' and spaces. */
60 if(!strncmpiW(ptr
, comW
, 3))
64 /* Allow any com port above 0 as Win 9x does (NT only allows
65 values for com ports which are actually present) */
66 if(*ptr
< '1' || *ptr
> '9')
69 /* Advance pointer past port number */
70 while(*ptr
>= '0' && *ptr
<= '9') ptr
++;
72 /* The com port number must be followed by a ':' or ' ' */
73 if(*ptr
!= ':' && *ptr
!= ' ')
76 /* Advance pointer to beginning of next parameter */
77 while(*ptr
== ' ') ptr
++;
81 while(*ptr
== ' ') ptr
++;
84 /* The device control string must not start with a space. */
91 static LPCWSTR
COMM_ParseNumber(LPCWSTR ptr
, LPDWORD lpnumber
)
93 if(*ptr
< '0' || *ptr
> '9') return NULL
;
94 *lpnumber
= strtoulW(ptr
, NULL
, 10);
95 while(*ptr
>= '0' && *ptr
<= '9') ptr
++;
99 static LPCWSTR
COMM_ParseParity(LPCWSTR ptr
, LPBYTE lpparity
)
101 /* Contrary to what you might expect, Windows only sets the Parity
102 member of DCB and not fParity even when parity is specified in the
103 device control string */
105 switch(toupperW(*ptr
++))
108 *lpparity
= EVENPARITY
;
111 *lpparity
= MARKPARITY
;
114 *lpparity
= NOPARITY
;
117 *lpparity
= ODDPARITY
;
120 *lpparity
= SPACEPARITY
;
129 static LPCWSTR
COMM_ParseByteSize(LPCWSTR ptr
, LPBYTE lpbytesize
)
133 if(!(ptr
= COMM_ParseNumber(ptr
, &temp
)))
136 if(temp
>= 5 && temp
<= 8)
145 static LPCWSTR
COMM_ParseStopBits(LPCWSTR ptr
, LPBYTE lpstopbits
)
148 static const WCHAR stopbits15W
[] = {'1','.','5',0};
150 if(!strncmpW(stopbits15W
, ptr
, 3))
153 *lpstopbits
= ONE5STOPBITS
;
157 if(!(ptr
= COMM_ParseNumber(ptr
, &temp
)))
161 *lpstopbits
= ONESTOPBIT
;
163 *lpstopbits
= TWOSTOPBITS
;
171 static LPCWSTR
COMM_ParseOnOff(LPCWSTR ptr
, LPDWORD lponoff
)
173 static const WCHAR onW
[] = {'o','n',0};
174 static const WCHAR offW
[] = {'o','f','f',0};
176 if(!strncmpiW(onW
, ptr
, 2))
181 else if(!strncmpiW(offW
, ptr
, 3))
192 /***********************************************************************
193 * COMM_BuildOldCommDCB (Internal)
195 * Build a DCB using the old style settings string eg: "96,n,8,1"
197 static BOOL
COMM_BuildOldCommDCB(LPCWSTR device
, LPDCB lpdcb
)
201 if(!(device
= COMM_ParseNumber(device
, &lpdcb
->BaudRate
)))
204 switch(lpdcb
->BaudRate
)
209 lpdcb
->BaudRate
*= 10;
215 lpdcb
->BaudRate
*= 100;
218 lpdcb
->BaudRate
= 19200;
222 while(*device
== ' ') device
++;
223 if(*device
++ != ',') return FALSE
;
224 while(*device
== ' ') device
++;
226 if(!(device
= COMM_ParseParity(device
, &lpdcb
->Parity
)))
229 while(*device
== ' ') device
++;
230 if(*device
++ != ',') return FALSE
;
231 while(*device
== ' ') device
++;
233 if(!(device
= COMM_ParseByteSize(device
, &lpdcb
->ByteSize
)))
236 while(*device
== ' ') device
++;
237 if(*device
++ != ',') return FALSE
;
238 while(*device
== ' ') device
++;
240 if(!(device
= COMM_ParseStopBits(device
, &lpdcb
->StopBits
)))
243 /* The last parameter for flow control is optional. */
244 while(*device
== ' ') device
++;
248 while(*device
== ' ') device
++;
249 if(*device
) last
= toupperW(*device
++);
250 while(*device
== ' ') device
++;
253 /* Win NT sets the flow control members based on (or lack of) the last
254 parameter. Win 9x does not set these members. */
259 lpdcb
->fOutX
= FALSE
;
260 lpdcb
->fOutxCtsFlow
= FALSE
;
261 lpdcb
->fOutxDsrFlow
= FALSE
;
262 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
263 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
268 lpdcb
->fOutxCtsFlow
= FALSE
;
269 lpdcb
->fOutxDsrFlow
= FALSE
;
270 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
271 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
275 lpdcb
->fOutX
= FALSE
;
276 lpdcb
->fOutxCtsFlow
= TRUE
;
277 lpdcb
->fOutxDsrFlow
= TRUE
;
278 lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
;
279 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
285 /* This should be the end of the string. */
286 if(*device
) return FALSE
;
291 /***********************************************************************
292 * COMM_BuildNewCommDCB (Internal)
294 * Build a DCB using the new style settings string.
295 * eg: "baud=9600 parity=n data=8 stop=1 xon=on to=on"
297 static BOOL
COMM_BuildNewCommDCB(LPCWSTR device
, LPDCB lpdcb
, LPCOMMTIMEOUTS lptimeouts
)
300 BOOL baud
= FALSE
, stop
= FALSE
;
301 static const WCHAR baudW
[] = {'b','a','u','d','=',0};
302 static const WCHAR parityW
[] = {'p','a','r','i','t','y','=',0};
303 static const WCHAR dataW
[] = {'d','a','t','a','=',0};
304 static const WCHAR stopW
[] = {'s','t','o','p','=',0};
305 static const WCHAR toW
[] = {'t','o','=',0};
306 static const WCHAR xonW
[] = {'x','o','n','=',0};
307 static const WCHAR odsrW
[] = {'o','d','s','r','=',0};
308 static const WCHAR octsW
[] = {'o','c','t','s','=',0};
309 static const WCHAR dtrW
[] = {'d','t','r','=',0};
310 static const WCHAR rtsW
[] = {'r','t','s','=',0};
311 static const WCHAR idsrW
[] = {'i','d','s','r','=',0};
315 while(*device
== ' ') device
++;
317 if(!strncmpiW(baudW
, device
, 5))
321 if(!(device
= COMM_ParseNumber(device
+ 5, &lpdcb
->BaudRate
)))
324 else if(!strncmpiW(parityW
, device
, 7))
326 if(!(device
= COMM_ParseParity(device
+ 7, &lpdcb
->Parity
)))
329 else if(!strncmpiW(dataW
, device
, 5))
331 if(!(device
= COMM_ParseByteSize(device
+ 5, &lpdcb
->ByteSize
)))
334 else if(!strncmpiW(stopW
, device
, 5))
338 if(!(device
= COMM_ParseStopBits(device
+ 5, &lpdcb
->StopBits
)))
341 else if(!strncmpiW(toW
, device
, 3))
343 if(!(device
= COMM_ParseOnOff(device
+ 3, &temp
)))
346 lptimeouts
->ReadIntervalTimeout
= 0;
347 lptimeouts
->ReadTotalTimeoutMultiplier
= 0;
348 lptimeouts
->ReadTotalTimeoutConstant
= 0;
349 lptimeouts
->WriteTotalTimeoutMultiplier
= 0;
350 lptimeouts
->WriteTotalTimeoutConstant
= temp
? 60000 : 0;
352 else if(!strncmpiW(xonW
, device
, 4))
354 if(!(device
= COMM_ParseOnOff(device
+ 4, &temp
)))
360 else if(!strncmpiW(odsrW
, device
, 5))
362 if(!(device
= COMM_ParseOnOff(device
+ 5, &temp
)))
365 lpdcb
->fOutxDsrFlow
= temp
;
367 else if(!strncmpiW(octsW
, device
, 5))
369 if(!(device
= COMM_ParseOnOff(device
+ 5, &temp
)))
372 lpdcb
->fOutxCtsFlow
= temp
;
374 else if(!strncmpiW(dtrW
, device
, 4))
376 if(!(device
= COMM_ParseOnOff(device
+ 4, &temp
)))
379 lpdcb
->fDtrControl
= temp
;
381 else if(!strncmpiW(rtsW
, device
, 4))
383 if(!(device
= COMM_ParseOnOff(device
+ 4, &temp
)))
386 lpdcb
->fRtsControl
= temp
;
388 else if(!strncmpiW(idsrW
, device
, 5))
390 if(!(device
= COMM_ParseOnOff(device
+ 5, &temp
)))
393 /* Win NT sets the fDsrSensitivity member based on the
394 idsr parameter. Win 9x sets fOutxDsrFlow instead. */
395 lpdcb
->fDsrSensitivity
= temp
;
400 /* After the above parsing, the next character (if not the end of
401 the string) should be a space */
402 if(*device
&& *device
!= ' ')
406 /* If stop bits were not specified, a default is always supplied. */
409 if(baud
&& lpdcb
->BaudRate
== 110)
410 lpdcb
->StopBits
= TWOSTOPBITS
;
412 lpdcb
->StopBits
= ONESTOPBIT
;
418 /**************************************************************************
419 * BuildCommDCBA (KERNEL32.@)
421 * Updates a device control block data structure with values from an
422 * ascii device control string. The device control string has two forms
423 * normal and extended, it must be exclusively in one or the other form.
427 * True on success, false on a malformed control string.
429 BOOL WINAPI
BuildCommDCBA(
430 LPCSTR device
, /* [in] The ascii device control string used to update the DCB. */
431 LPDCB lpdcb
) /* [out] The device control block to be updated. */
433 return BuildCommDCBAndTimeoutsA(device
,lpdcb
,NULL
);
436 /**************************************************************************
437 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
439 * Updates a device control block data structure with values from an
440 * ascii device control string. Taking timeout values from a timeouts
441 * struct if desired by the control string.
445 * True on success, false bad handles etc.
447 BOOL WINAPI
BuildCommDCBAndTimeoutsA(
448 LPCSTR device
, /* [in] The ascii device control string. */
449 LPDCB lpdcb
, /* [out] The device control block to be updated. */
450 LPCOMMTIMEOUTS lptimeouts
) /* [in] The COMMTIMEOUTS structure to be updated. */
453 UNICODE_STRING deviceW
;
455 TRACE("(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
456 if(device
) RtlCreateUnicodeStringFromAsciiz(&deviceW
,device
);
457 else deviceW
.Buffer
= NULL
;
459 if(deviceW
.Buffer
) ret
= BuildCommDCBAndTimeoutsW(deviceW
.Buffer
,lpdcb
,lptimeouts
);
461 RtlFreeUnicodeString(&deviceW
);
465 /**************************************************************************
466 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
468 * Updates a device control block data structure with values from a
469 * unicode device control string. Taking timeout values from a timeouts
470 * struct if desired by the control string.
474 * True on success, false bad handles etc
476 BOOL WINAPI
BuildCommDCBAndTimeoutsW(
477 LPCWSTR devid
, /* [in] The unicode device control string. */
478 LPDCB lpdcb
, /* [out] The device control block to be updated. */
479 LPCOMMTIMEOUTS lptimeouts
) /* [in] The COMMTIMEOUTS structure to be updated. */
482 COMMTIMEOUTS timeouts
;
486 TRACE("(%s,%p,%p)\n",debugstr_w(devid
),lpdcb
,lptimeouts
);
488 memset(&timeouts
, 0, sizeof timeouts
);
490 /* Set DCBlength. (Windows NT does not do this, but 9x does) */
491 lpdcb
->DCBlength
= sizeof(DCB
);
493 /* Make a copy of the original data structures to work with since if
494 if there is an error in the device control string the originals
495 should not be modified (except possibly DCBlength) */
497 if(lptimeouts
) timeouts
= *lptimeouts
;
499 ptr
= COMM_ParseStart(ptr
);
503 else if(strchrW(ptr
, ','))
504 result
= COMM_BuildOldCommDCB(ptr
, &dcb
);
506 result
= COMM_BuildNewCommDCB(ptr
, &dcb
, &timeouts
);
511 if(lptimeouts
) *lptimeouts
= timeouts
;
516 WARN("Invalid device control string: %s\n", debugstr_w(devid
));
517 SetLastError(ERROR_INVALID_PARAMETER
);
522 /**************************************************************************
523 * BuildCommDCBW (KERNEL32.@)
525 * Updates a device control block structure with values from an
526 * unicode device control string. The device control string has two forms
527 * normal and extended, it must be exclusively in one or the other form.
531 * True on success, false on a malformed control string.
533 BOOL WINAPI
BuildCommDCBW(
534 LPCWSTR devid
, /* [in] The unicode device control string. */
535 LPDCB lpdcb
) /* [out] The device control block to be updated. */
537 return BuildCommDCBAndTimeoutsW(devid
,lpdcb
,NULL
);
540 /*****************************************************************************
541 * SetCommBreak (KERNEL32.@)
543 * Halts the transmission of characters to a communications device.
546 * handle [in] The communications device to suspend
550 * True on success, and false if the communications device could not be found,
551 * the control is not supported.
555 * Only TIOCSBRK and TIOCCBRK are supported.
557 BOOL WINAPI
SetCommBreak(HANDLE handle
)
559 DWORD dwBytesReturned
;
560 return DeviceIoControl(handle
, IOCTL_SERIAL_SET_BREAK_ON
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
563 /*****************************************************************************
564 * ClearCommBreak (KERNEL32.@)
566 * Resumes character transmission from a communication device.
570 * handle [in] The halted communication device whose character transmission is to be resumed
574 * True on success and false if the communications device could not be found.
578 * Only TIOCSBRK and TIOCCBRK are supported.
580 BOOL WINAPI
ClearCommBreak(HANDLE handle
)
582 DWORD dwBytesReturned
;
583 return DeviceIoControl(handle
, IOCTL_SERIAL_SET_BREAK_OFF
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
586 /*****************************************************************************
587 * EscapeCommFunction (KERNEL32.@)
589 * Directs a communication device to perform an extended function.
593 * handle [in] The communication device to perform the extended function
594 * nFunction [in] The extended function to be performed
598 * True or requested data on successful completion of the command,
599 * false if the device is not present cannot execute the command
600 * or the command failed.
602 BOOL WINAPI
EscapeCommFunction(HANDLE handle
, DWORD func
)
605 DWORD dwBytesReturned
;
609 case CLRDTR
: ioc
= IOCTL_SERIAL_CLR_DTR
; break;
610 case CLRRTS
: ioc
= IOCTL_SERIAL_CLR_RTS
; break;
611 case SETDTR
: ioc
= IOCTL_SERIAL_SET_DTR
; break;
612 case SETRTS
: ioc
= IOCTL_SERIAL_SET_RTS
; break;
613 case SETXOFF
: ioc
= IOCTL_SERIAL_SET_XOFF
; break;
614 case SETXON
: ioc
= IOCTL_SERIAL_SET_XON
; break;
615 case SETBREAK
: ioc
= IOCTL_SERIAL_SET_BREAK_ON
; break;
616 case CLRBREAK
: ioc
= IOCTL_SERIAL_SET_BREAK_OFF
; break;
617 case RESETDEV
: ioc
= IOCTL_SERIAL_RESET_DEVICE
; break;
619 ERR("Unknown function code (%u)\n", func
);
620 SetLastError(ERROR_INVALID_PARAMETER
);
623 return DeviceIoControl(handle
, ioc
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
626 /********************************************************************
627 * PurgeComm (KERNEL32.@)
629 * Terminates pending operations and/or discards buffers on a
630 * communication resource.
634 * handle [in] The communication resource to be purged
635 * flags [in] Flags for clear pending/buffer on input/output
639 * True on success and false if the communications handle is bad.
641 BOOL WINAPI
PurgeComm(HANDLE handle
, DWORD flags
)
643 DWORD dwBytesReturned
;
644 return DeviceIoControl(handle
, IOCTL_SERIAL_PURGE
, &flags
, sizeof(flags
),
645 NULL
, 0, &dwBytesReturned
, NULL
);
648 /*****************************************************************************
649 * ClearCommError (KERNEL32.@)
651 * Enables further I/O operations on a communications resource after
652 * supplying error and current status information.
656 * handle [in] The communication resource with the error
657 * errors [out] Flags indicating error the resource experienced
658 * lpStat [out] The status of the communication resource
661 * True on success, false if the communication resource handle is bad.
663 BOOL WINAPI
ClearCommError(HANDLE handle
, LPDWORD errors
, LPCOMSTAT lpStat
)
666 DWORD dwBytesReturned
;
668 if (!DeviceIoControl(handle
, IOCTL_SERIAL_GET_COMMSTATUS
, NULL
, 0,
669 &ss
, sizeof(ss
), &dwBytesReturned
, NULL
))
675 if (ss
.Errors
& SERIAL_ERROR_BREAK
) *errors
|= CE_BREAK
;
676 if (ss
.Errors
& SERIAL_ERROR_FRAMING
) *errors
|= CE_FRAME
;
677 if (ss
.Errors
& SERIAL_ERROR_OVERRUN
) *errors
|= CE_OVERRUN
;
678 if (ss
.Errors
& SERIAL_ERROR_QUEUEOVERRUN
) *errors
|= CE_RXOVER
;
679 if (ss
.Errors
& SERIAL_ERROR_PARITY
) *errors
|= CE_RXPARITY
;
684 memset(lpStat
, 0, sizeof(*lpStat
));
686 if (ss
.HoldReasons
& SERIAL_TX_WAITING_FOR_CTS
) lpStat
->fCtsHold
= TRUE
;
687 if (ss
.HoldReasons
& SERIAL_TX_WAITING_FOR_DSR
) lpStat
->fDsrHold
= TRUE
;
688 if (ss
.HoldReasons
& SERIAL_TX_WAITING_FOR_DCD
) lpStat
->fRlsdHold
= TRUE
;
689 if (ss
.HoldReasons
& SERIAL_TX_WAITING_FOR_XON
) lpStat
->fXoffHold
= TRUE
;
690 if (ss
.HoldReasons
& SERIAL_TX_WAITING_XOFF_SENT
) lpStat
->fXoffSent
= TRUE
;
691 if (ss
.EofReceived
) lpStat
->fEof
= TRUE
;
692 if (ss
.WaitForImmediate
) lpStat
->fTxim
= TRUE
;
693 lpStat
->cbInQue
= ss
.AmountInInQueue
;
694 lpStat
->cbOutQue
= ss
.AmountInOutQueue
;
699 /*****************************************************************************
700 * SetupComm (KERNEL32.@)
702 * Called after CreateFile to hint to the communication resource to use
703 * specified sizes for input and output buffers rather than the default values.
706 * handle [in] The just created communication resource handle
707 * insize [in] The suggested size of the communication resources input buffer in bytes
708 * outsize [in] The suggested size of the communication resources output buffer in bytes
712 * True if successful, false if the communications resource handle is bad.
718 BOOL WINAPI
SetupComm(HANDLE handle
, DWORD insize
, DWORD outsize
)
720 SERIAL_QUEUE_SIZE sqs
;
721 DWORD dwBytesReturned
;
724 sqs
.OutSize
= outsize
;
725 return DeviceIoControl(handle
, IOCTL_SERIAL_SET_QUEUE_SIZE
,
726 &sqs
, sizeof(sqs
), NULL
, 0, &dwBytesReturned
, NULL
);
729 /*****************************************************************************
730 * GetCommMask (KERNEL32.@)
732 * Obtain the events associated with a communication device that will cause
733 * a call WaitCommEvent to return.
737 * handle [in] The communications device
738 * evtmask [out] The events which cause WaitCommEvent to return
742 * True on success, fail on bad device handle etc.
744 BOOL WINAPI
GetCommMask(HANDLE handle
, LPDWORD evtmask
)
746 DWORD dwBytesReturned
;
747 TRACE("handle %p, mask %p\n", handle
, evtmask
);
748 return DeviceIoControl(handle
, IOCTL_SERIAL_GET_WAIT_MASK
,
749 NULL
, 0, evtmask
, sizeof(*evtmask
), &dwBytesReturned
, NULL
);
752 /*****************************************************************************
753 * SetCommMask (KERNEL32.@)
755 * There be some things we need to hear about yon there communications device.
756 * (Set which events associated with a communication device should cause
757 * a call WaitCommEvent to return.)
761 * handle [in] The communications device
762 * evtmask [in] The events that are to be monitored
766 * True on success, false on bad handle etc.
768 BOOL WINAPI
SetCommMask(HANDLE handle
, DWORD evtmask
)
770 DWORD dwBytesReturned
;
771 TRACE("handle %p, mask %x\n", handle
, evtmask
);
772 return DeviceIoControl(handle
, IOCTL_SERIAL_SET_WAIT_MASK
,
773 &evtmask
, sizeof(evtmask
), NULL
, 0, &dwBytesReturned
, NULL
);
776 static void dump_dcb(const DCB
* lpdcb
)
778 TRACE("bytesize=%d baudrate=%d fParity=%d Parity=%d stopbits=%d\n",
779 lpdcb
->ByteSize
, lpdcb
->BaudRate
, lpdcb
->fParity
, lpdcb
->Parity
,
780 (lpdcb
->StopBits
== ONESTOPBIT
) ? 1 :
781 (lpdcb
->StopBits
== TWOSTOPBITS
) ? 2 : 0);
782 TRACE("%sIXON %sIXOFF\n", (lpdcb
->fOutX
) ? "" : "~", (lpdcb
->fInX
) ? "" : "~");
783 TRACE("fOutxCtsFlow=%d fRtsControl=%d\n", lpdcb
->fOutxCtsFlow
, lpdcb
->fRtsControl
);
784 TRACE("fOutxDsrFlow=%d fDtrControl=%d\n", lpdcb
->fOutxDsrFlow
, lpdcb
->fDtrControl
);
785 if (lpdcb
->fOutxCtsFlow
|| lpdcb
->fRtsControl
== RTS_CONTROL_HANDSHAKE
)
791 /*****************************************************************************
792 * SetCommState (KERNEL32.@)
794 * Re-initializes all hardware and control settings of a communications device,
795 * with values from a device control block without affecting the input and output
800 * handle [in] The communications device
801 * lpdcb [out] The device control block
805 * True on success, false on failure, e.g., if the XonChar is equal to the XoffChar.
807 BOOL WINAPI
SetCommState( HANDLE handle
, LPDCB lpdcb
)
809 SERIAL_BAUD_RATE sbr
;
810 SERIAL_LINE_CONTROL slc
;
813 DWORD dwBytesReturned
;
817 SetLastError(ERROR_INVALID_PARAMETER
);
822 sbr
.BaudRate
= lpdcb
->BaudRate
;
824 slc
.StopBits
= lpdcb
->StopBits
;
825 slc
.Parity
= lpdcb
->Parity
;
826 slc
.WordLength
= lpdcb
->ByteSize
;
828 shf
.ControlHandShake
= 0;
830 if (lpdcb
->fOutxCtsFlow
) shf
.ControlHandShake
|= SERIAL_CTS_HANDSHAKE
;
831 if (lpdcb
->fOutxDsrFlow
) shf
.ControlHandShake
|= SERIAL_DSR_HANDSHAKE
;
832 switch (lpdcb
->fDtrControl
)
834 case DTR_CONTROL_DISABLE
: break;
835 case DTR_CONTROL_ENABLE
: shf
.ControlHandShake
|= SERIAL_DTR_CONTROL
; break;
836 case DTR_CONTROL_HANDSHAKE
: shf
.ControlHandShake
|= SERIAL_DTR_HANDSHAKE
;break;
838 SetLastError(ERROR_INVALID_PARAMETER
);
841 switch (lpdcb
->fRtsControl
)
843 case RTS_CONTROL_DISABLE
: break;
844 case RTS_CONTROL_ENABLE
: shf
.FlowReplace
|= SERIAL_RTS_CONTROL
; break;
845 case RTS_CONTROL_HANDSHAKE
: shf
.FlowReplace
|= SERIAL_RTS_HANDSHAKE
; break;
846 case RTS_CONTROL_TOGGLE
: shf
.FlowReplace
|= SERIAL_RTS_CONTROL
|
847 SERIAL_RTS_HANDSHAKE
; break;
849 SetLastError(ERROR_INVALID_PARAMETER
);
852 if (lpdcb
->fDsrSensitivity
) shf
.ControlHandShake
|= SERIAL_DSR_SENSITIVITY
;
853 if (lpdcb
->fAbortOnError
) shf
.ControlHandShake
|= SERIAL_ERROR_ABORT
;
855 if (lpdcb
->fErrorChar
) shf
.FlowReplace
|= SERIAL_ERROR_CHAR
;
856 if (lpdcb
->fNull
) shf
.FlowReplace
|= SERIAL_NULL_STRIPPING
;
857 if (lpdcb
->fTXContinueOnXoff
) shf
.FlowReplace
|= SERIAL_XOFF_CONTINUE
;
858 if (lpdcb
->fOutX
) shf
.FlowReplace
|= SERIAL_AUTO_TRANSMIT
;
859 if (lpdcb
->fInX
) shf
.FlowReplace
|= SERIAL_AUTO_RECEIVE
;
861 shf
.XonLimit
= lpdcb
->XonLim
;
862 shf
.XoffLimit
= lpdcb
->XoffLim
;
864 sc
.EofChar
= lpdcb
->EofChar
;
865 sc
.ErrorChar
= lpdcb
->ErrorChar
;
867 sc
.EventChar
= lpdcb
->EvtChar
;
868 sc
.XonChar
= lpdcb
->XonChar
;
869 sc
.XoffChar
= lpdcb
->XoffChar
;
871 /* note: change DTR/RTS lines after setting the comm attributes,
872 * so flow control does not interfere.
874 return (DeviceIoControl(handle
, IOCTL_SERIAL_SET_BAUD_RATE
,
875 &sbr
, sizeof(sbr
), NULL
, 0, &dwBytesReturned
, NULL
) &&
876 DeviceIoControl(handle
, IOCTL_SERIAL_SET_LINE_CONTROL
,
877 &slc
, sizeof(slc
), NULL
, 0, &dwBytesReturned
, NULL
) &&
878 DeviceIoControl(handle
, IOCTL_SERIAL_SET_HANDFLOW
,
879 &shf
, sizeof(shf
), NULL
, 0, &dwBytesReturned
, NULL
) &&
880 DeviceIoControl(handle
, IOCTL_SERIAL_SET_CHARS
,
881 &sc
, sizeof(sc
), NULL
, 0, &dwBytesReturned
, NULL
));
885 /*****************************************************************************
886 * GetCommState (KERNEL32.@)
888 * Fills in a device control block with information from a communications device.
891 * handle [in] The communications device
892 * lpdcb [out] The device control block
896 * True on success, false if the communication device handle is bad etc
900 * XonChar and XoffChar are not set.
902 BOOL WINAPI
GetCommState(HANDLE handle
, LPDCB lpdcb
)
904 SERIAL_BAUD_RATE sbr
;
905 SERIAL_LINE_CONTROL slc
;
908 DWORD dwBytesReturned
;
910 TRACE("handle %p, ptr %p\n", handle
, lpdcb
);
914 SetLastError(ERROR_INVALID_PARAMETER
);
918 if (!DeviceIoControl(handle
, IOCTL_SERIAL_GET_BAUD_RATE
,
919 NULL
, 0, &sbr
, sizeof(sbr
), &dwBytesReturned
, NULL
) ||
920 !DeviceIoControl(handle
, IOCTL_SERIAL_GET_LINE_CONTROL
,
921 NULL
, 0, &slc
, sizeof(slc
), &dwBytesReturned
, NULL
) ||
922 !DeviceIoControl(handle
, IOCTL_SERIAL_GET_HANDFLOW
,
923 NULL
, 0, &shf
, sizeof(shf
), &dwBytesReturned
, NULL
) ||
924 !DeviceIoControl(handle
, IOCTL_SERIAL_GET_CHARS
,
925 NULL
, 0, &sc
, sizeof(sc
), &dwBytesReturned
, NULL
))
928 memset(lpdcb
, 0, sizeof(*lpdcb
));
929 lpdcb
->DCBlength
= sizeof(*lpdcb
);
931 /* yes, they seem no never be (re)set on NT */
935 lpdcb
->BaudRate
= sbr
.BaudRate
;
937 lpdcb
->StopBits
= slc
.StopBits
;
938 lpdcb
->Parity
= slc
.Parity
;
939 lpdcb
->ByteSize
= slc
.WordLength
;
941 if (shf
.ControlHandShake
& SERIAL_CTS_HANDSHAKE
) lpdcb
->fOutxCtsFlow
= 1;
942 if (shf
.ControlHandShake
& SERIAL_DSR_HANDSHAKE
) lpdcb
->fOutxDsrFlow
= 1;
943 switch (shf
.ControlHandShake
& (SERIAL_DTR_CONTROL
| SERIAL_DTR_HANDSHAKE
))
945 case 0: lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
; break;
946 case SERIAL_DTR_CONTROL
: lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
; break;
947 case SERIAL_DTR_HANDSHAKE
: lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
; break;
949 switch (shf
.FlowReplace
& (SERIAL_RTS_CONTROL
| SERIAL_RTS_HANDSHAKE
))
951 case 0: lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
; break;
952 case SERIAL_RTS_CONTROL
: lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
; break;
953 case SERIAL_RTS_HANDSHAKE
: lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
; break;
954 case SERIAL_RTS_CONTROL
| SERIAL_RTS_HANDSHAKE
:
955 lpdcb
->fRtsControl
= RTS_CONTROL_TOGGLE
; break;
957 if (shf
.ControlHandShake
& SERIAL_DSR_SENSITIVITY
) lpdcb
->fDsrSensitivity
= 1;
958 if (shf
.ControlHandShake
& SERIAL_ERROR_ABORT
) lpdcb
->fAbortOnError
= 1;
959 if (shf
.FlowReplace
& SERIAL_ERROR_CHAR
) lpdcb
->fErrorChar
= 1;
960 if (shf
.FlowReplace
& SERIAL_NULL_STRIPPING
) lpdcb
->fNull
= 1;
961 if (shf
.FlowReplace
& SERIAL_XOFF_CONTINUE
) lpdcb
->fTXContinueOnXoff
= 1;
962 lpdcb
->XonLim
= shf
.XonLimit
;
963 lpdcb
->XoffLim
= shf
.XoffLimit
;
965 if (shf
.FlowReplace
& SERIAL_AUTO_TRANSMIT
) lpdcb
->fOutX
= 1;
966 if (shf
.FlowReplace
& SERIAL_AUTO_RECEIVE
) lpdcb
->fInX
= 1;
968 lpdcb
->EofChar
= sc
.EofChar
;
969 lpdcb
->ErrorChar
= sc
.ErrorChar
;
970 lpdcb
->EvtChar
= sc
.EventChar
;
971 lpdcb
->XonChar
= sc
.XonChar
;
972 lpdcb
->XoffChar
= sc
.XoffChar
;
980 /*****************************************************************************
981 * TransmitCommChar (KERNEL32.@)
983 * Transmits a single character in front of any pending characters in the
984 * output buffer. Usually used to send an interrupt character to a host.
987 * hComm [in] The communication device in need of a command character
988 * chTransmit [in] The character to transmit
992 * True if the call succeeded, false if the previous command character to the
993 * same device has not been sent yet the handle is bad etc.
996 BOOL WINAPI
TransmitCommChar(HANDLE hComm
, CHAR chTransmit
)
998 DWORD dwBytesReturned
;
999 return DeviceIoControl(hComm
, IOCTL_SERIAL_IMMEDIATE_CHAR
,
1000 &chTransmit
, sizeof(chTransmit
), NULL
, 0, &dwBytesReturned
, NULL
);
1004 /*****************************************************************************
1005 * GetCommTimeouts (KERNEL32.@)
1007 * Obtains the request timeout values for the communications device.
1010 * hComm [in] The communications device
1011 * lptimeouts [out] The struct of request timeouts
1015 * True on success, false if communications device handle is bad
1016 * or the target structure is null.
1018 BOOL WINAPI
GetCommTimeouts(HANDLE hComm
, LPCOMMTIMEOUTS lptimeouts
)
1021 DWORD dwBytesReturned
;
1023 TRACE("(%p, %p)\n", hComm
, lptimeouts
);
1026 SetLastError(ERROR_INVALID_PARAMETER
);
1029 if (!DeviceIoControl(hComm
, IOCTL_SERIAL_GET_TIMEOUTS
,
1030 NULL
, 0, &st
, sizeof(st
), &dwBytesReturned
, NULL
))
1032 lptimeouts
->ReadIntervalTimeout
= st
.ReadIntervalTimeout
;
1033 lptimeouts
->ReadTotalTimeoutMultiplier
= st
.ReadTotalTimeoutMultiplier
;
1034 lptimeouts
->ReadTotalTimeoutConstant
= st
.ReadTotalTimeoutConstant
;
1035 lptimeouts
->WriteTotalTimeoutMultiplier
= st
.WriteTotalTimeoutMultiplier
;
1036 lptimeouts
->WriteTotalTimeoutConstant
= st
.WriteTotalTimeoutConstant
;
1040 /*****************************************************************************
1041 * SetCommTimeouts (KERNEL32.@)
1043 * Sets the timeouts used when reading and writing data to/from COMM ports.
1046 * hComm [in] handle of COMM device
1047 * lptimeouts [in] pointer to COMMTIMEOUTS structure
1049 * ReadIntervalTimeout
1050 * - converted and passes to linux kernel as c_cc[VTIME]
1051 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1052 * - used in ReadFile to calculate GetOverlappedResult's timeout
1053 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1054 * - used in WriteFile to calculate GetOverlappedResult's timeout
1058 * True if the timeouts were set, false otherwise.
1060 BOOL WINAPI
SetCommTimeouts(HANDLE hComm
, LPCOMMTIMEOUTS lptimeouts
)
1063 DWORD dwBytesReturned
;
1065 TRACE("(%p, %p)\n", hComm
, lptimeouts
);
1067 if (lptimeouts
== NULL
)
1069 SetLastError(ERROR_INVALID_PARAMETER
);
1072 st
.ReadIntervalTimeout
= lptimeouts
->ReadIntervalTimeout
;
1073 st
.ReadTotalTimeoutMultiplier
= lptimeouts
->ReadTotalTimeoutMultiplier
;
1074 st
.ReadTotalTimeoutConstant
= lptimeouts
->ReadTotalTimeoutConstant
;
1075 st
.WriteTotalTimeoutMultiplier
= lptimeouts
->WriteTotalTimeoutMultiplier
;
1076 st
.WriteTotalTimeoutConstant
= lptimeouts
->WriteTotalTimeoutConstant
;
1078 return DeviceIoControl(hComm
, IOCTL_SERIAL_SET_TIMEOUTS
,
1079 &st
, sizeof(st
), NULL
, 0, &dwBytesReturned
, NULL
);
1082 /***********************************************************************
1083 * GetCommModemStatus (KERNEL32.@)
1085 * Obtains the four control register bits if supported by the hardware.
1089 * hFile [in] The communications device
1090 * lpModemStat [out] The control register bits
1094 * True if the communications handle was good and for hardware that
1095 * control register access, false otherwise.
1097 BOOL WINAPI
GetCommModemStatus(HANDLE hFile
, LPDWORD lpModemStat
)
1099 DWORD dwBytesReturned
;
1100 return DeviceIoControl(hFile
, IOCTL_SERIAL_GET_MODEMSTATUS
,
1101 NULL
, 0, lpModemStat
, sizeof(DWORD
), &dwBytesReturned
, NULL
);
1104 /***********************************************************************
1105 * WaitCommEvent (KERNEL32.@)
1107 * Wait until something interesting happens on a COMM port.
1108 * Interesting things (events) are set by calling SetCommMask before
1109 * this function is called.
1112 * TRUE if successful
1115 * The set of detected events will be written to *lpdwEventMask
1116 * ERROR_IO_PENDING will be returned the overlapped structure was passed
1119 * Only supports EV_RXCHAR and EV_TXEMPTY
1121 BOOL WINAPI
WaitCommEvent(
1122 HANDLE hFile
, /* [in] handle of comm port to wait for */
1123 LPDWORD lpdwEvents
, /* [out] event(s) that were detected */
1124 LPOVERLAPPED lpOverlapped
) /* [in/out] for Asynchronous waiting */
1126 return DeviceIoControl(hFile
, IOCTL_SERIAL_WAIT_ON_MASK
, NULL
, 0,
1127 lpdwEvents
, sizeof(DWORD
), NULL
, lpOverlapped
);
1130 /***********************************************************************
1131 * GetCommProperties (KERNEL32.@)
1133 * This function fills in a structure with the capabilities of the
1134 * communications port driver.
1138 * TRUE on success, FALSE on failure
1139 * If successful, the lpCommProp structure be filled in with
1140 * properties of the comm port.
1142 BOOL WINAPI
GetCommProperties(
1143 HANDLE hFile
, /* [in] handle of the comm port */
1144 LPCOMMPROP lpCommProp
) /* [out] pointer to struct to be filled */
1146 TRACE("(%p %p)\n",hFile
,lpCommProp
);
1151 * These values should be valid for LINUX's serial driver
1152 * FIXME: Perhaps they deserve an #ifdef LINUX
1154 memset(lpCommProp
,0,sizeof(COMMPROP
));
1155 lpCommProp
->wPacketLength
= 1;
1156 lpCommProp
->wPacketVersion
= 1;
1157 lpCommProp
->dwServiceMask
= SP_SERIALCOMM
;
1158 lpCommProp
->dwMaxTxQueue
= 4096;
1159 lpCommProp
->dwMaxRxQueue
= 4096;
1160 lpCommProp
->dwMaxBaud
= BAUD_115200
;
1161 lpCommProp
->dwProvSubType
= PST_RS232
;
1162 lpCommProp
->dwProvCapabilities
= PCF_DTRDSR
| PCF_PARITY_CHECK
| PCF_RTSCTS
| PCF_TOTALTIMEOUTS
;
1163 lpCommProp
->dwSettableParams
= SP_BAUD
| SP_DATABITS
| SP_HANDSHAKING
|
1164 SP_PARITY
| SP_PARITY_CHECK
| SP_STOPBITS
;
1165 lpCommProp
->dwSettableBaud
= BAUD_075
| BAUD_110
| BAUD_134_5
| BAUD_150
|
1166 BAUD_300
| BAUD_600
| BAUD_1200
| BAUD_1800
| BAUD_2400
| BAUD_4800
|
1167 BAUD_9600
| BAUD_19200
| BAUD_38400
| BAUD_57600
| BAUD_115200
;
1168 lpCommProp
->wSettableData
= DATABITS_5
| DATABITS_6
| DATABITS_7
| DATABITS_8
;
1169 lpCommProp
->wSettableStopParity
= STOPBITS_10
| STOPBITS_15
| STOPBITS_20
|
1170 PARITY_NONE
| PARITY_ODD
|PARITY_EVEN
| PARITY_MARK
| PARITY_SPACE
;
1171 lpCommProp
->dwCurrentTxQueue
= lpCommProp
->dwMaxTxQueue
;
1172 lpCommProp
->dwCurrentRxQueue
= lpCommProp
->dwMaxRxQueue
;
1177 /***********************************************************************
1179 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1180 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1181 * This is dependent on the type of COMM port, but since it is doubtful
1182 * anybody will get around to implementing support for fancy serial
1183 * ports in WINE, this is hardcoded for the time being. The name of
1184 * this DLL should be stored in and read from the system registry in
1185 * the hive HKEY_LOCAL_MACHINE, key
1186 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1187 * where ???? is the port number... that is determined by PNP
1188 * The DLL should be loaded when the COMM port is opened, and closed
1189 * when the COMM port is closed. - MJM 20 June 2000
1190 ***********************************************************************/
1191 static const WCHAR lpszSerialUI
[] = {
1192 's','e','r','i','a','l','u','i','.','d','l','l',0 };
1195 /***********************************************************************
1196 * CommConfigDialogA (KERNEL32.@)
1198 * Raises a dialog that allows the user to configure a comm port.
1199 * Fills the COMMCONFIG struct with information specified by the user.
1200 * This function should call a similar routine in the COMM driver...
1204 * TRUE on success, FALSE on failure
1205 * If successful, the lpCommConfig structure will contain a new
1206 * configuration for the comm port, as specified by the user.
1209 * The library with the CommConfigDialog code is never unloaded.
1210 * Perhaps this should be done when the comm port is closed?
1212 BOOL WINAPI
CommConfigDialogA(
1213 LPCSTR lpszDevice
, /* [in] name of communications device */
1214 HWND hWnd
, /* [in] parent window for the dialog */
1215 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
1217 LPWSTR lpDeviceW
= NULL
;
1221 TRACE("(%s, %p, %p)\n", debugstr_a(lpszDevice
), hWnd
, lpCommConfig
);
1225 len
= MultiByteToWideChar( CP_ACP
, 0, lpszDevice
, -1, NULL
, 0 );
1226 lpDeviceW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
1227 MultiByteToWideChar( CP_ACP
, 0, lpszDevice
, -1, lpDeviceW
, len
);
1229 r
= CommConfigDialogW(lpDeviceW
, hWnd
, lpCommConfig
);
1230 HeapFree( GetProcessHeap(), 0, lpDeviceW
);
1234 /***********************************************************************
1235 * CommConfigDialogW (KERNEL32.@)
1237 * See CommConfigDialogA.
1239 BOOL WINAPI
CommConfigDialogW(
1240 LPCWSTR lpszDevice
, /* [in] name of communications device */
1241 HWND hWnd
, /* [in] parent window for the dialog */
1242 LPCOMMCONFIG lpCommConfig
) /* [out] pointer to struct to fill */
1244 DWORD (WINAPI
*pCommConfigDialog
)(LPCWSTR
, HWND
, LPCOMMCONFIG
);
1245 HMODULE hConfigModule
;
1246 DWORD res
= ERROR_INVALID_PARAMETER
;
1248 TRACE("(%s, %p, %p)\n", debugstr_w(lpszDevice
), hWnd
, lpCommConfig
);
1249 hConfigModule
= LoadLibraryW(lpszSerialUI
);
1251 if (hConfigModule
) {
1252 pCommConfigDialog
= (void *)GetProcAddress(hConfigModule
, "drvCommConfigDialogW");
1253 if (pCommConfigDialog
) {
1254 res
= pCommConfigDialog(lpszDevice
, hWnd
, lpCommConfig
);
1256 FreeLibrary(hConfigModule
);
1259 if (res
) SetLastError(res
);
1260 return (res
== ERROR_SUCCESS
);
1263 /***********************************************************************
1264 * GetCommConfig (KERNEL32.@)
1266 * Fill in the COMMCONFIG structure for the comm port hFile
1270 * TRUE on success, FALSE on failure
1271 * If successful, lpCommConfig contains the comm port configuration.
1276 BOOL WINAPI
GetCommConfig(
1277 HANDLE hFile
, /* [in] The communications device. */
1278 LPCOMMCONFIG lpCommConfig
, /* [out] The communications configuration of the device (if it fits). */
1279 LPDWORD lpdwSize
) /* [in/out] Initially the size of the configuration buffer/structure,
1280 afterwards the number of bytes copied to the buffer or
1281 the needed size of the buffer. */
1285 TRACE("(%p, %p, %p) *lpdwSize: %u\n", hFile
, lpCommConfig
, lpdwSize
, lpdwSize
? *lpdwSize
: 0 );
1287 if(lpCommConfig
== NULL
)
1289 r
= *lpdwSize
< sizeof(COMMCONFIG
); /* TRUE if not enough space */
1290 *lpdwSize
= sizeof(COMMCONFIG
);
1294 lpCommConfig
->dwSize
= sizeof(COMMCONFIG
);
1295 lpCommConfig
->wVersion
= 1;
1296 lpCommConfig
->wReserved
= 0;
1297 r
= GetCommState(hFile
,&lpCommConfig
->dcb
);
1298 lpCommConfig
->dwProviderSubType
= PST_RS232
;
1299 lpCommConfig
->dwProviderOffset
= 0;
1300 lpCommConfig
->dwProviderSize
= 0;
1305 /***********************************************************************
1306 * SetCommConfig (KERNEL32.@)
1308 * Sets the configuration of the communications device.
1312 * True on success, false if the handle was bad is not a communications device.
1314 BOOL WINAPI
SetCommConfig(
1315 HANDLE hFile
, /* [in] The communications device. */
1316 LPCOMMCONFIG lpCommConfig
, /* [in] The desired configuration. */
1317 DWORD dwSize
) /* [in] size of the lpCommConfig struct */
1319 TRACE("(%p, %p, %u)\n", hFile
, lpCommConfig
, dwSize
);
1320 return SetCommState(hFile
,&lpCommConfig
->dcb
);
1323 /***********************************************************************
1324 * SetDefaultCommConfigW (KERNEL32.@)
1326 * Initializes the default configuration for a communication device.
1329 * lpszDevice [I] Name of the device targeted for configuration
1330 * lpCommConfig [I] PTR to a buffer with the configuration for the device
1331 * dwSize [I] Number of bytes in the buffer
1335 * Success: TRUE, and default configuration saved
1338 BOOL WINAPI
SetDefaultCommConfigW(LPCWSTR lpszDevice
, LPCOMMCONFIG lpCommConfig
, DWORD dwSize
)
1340 BOOL (WINAPI
*lpfnSetDefaultCommConfig
)(LPCWSTR
, LPCOMMCONFIG
, DWORD
);
1341 HMODULE hConfigModule
;
1344 TRACE("(%s, %p, %u)\n", debugstr_w(lpszDevice
), lpCommConfig
, dwSize
);
1346 hConfigModule
= LoadLibraryW(lpszSerialUI
);
1350 lpfnSetDefaultCommConfig
= (void *)GetProcAddress(hConfigModule
, "drvSetDefaultCommConfigW");
1351 if (lpfnSetDefaultCommConfig
)
1352 r
= lpfnSetDefaultCommConfig(lpszDevice
, lpCommConfig
, dwSize
);
1354 FreeLibrary(hConfigModule
);
1360 /***********************************************************************
1361 * SetDefaultCommConfigA (KERNEL32.@)
1363 * Initializes the default configuration for a communication device.
1365 * See SetDefaultCommConfigW.
1368 BOOL WINAPI
SetDefaultCommConfigA(LPCSTR lpszDevice
, LPCOMMCONFIG lpCommConfig
, DWORD dwSize
)
1371 LPWSTR lpDeviceW
= NULL
;
1374 TRACE("(%s, %p, %u)\n", debugstr_a(lpszDevice
), lpCommConfig
, dwSize
);
1378 len
= MultiByteToWideChar( CP_ACP
, 0, lpszDevice
, -1, NULL
, 0 );
1379 lpDeviceW
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1380 MultiByteToWideChar( CP_ACP
, 0, lpszDevice
, -1, lpDeviceW
, len
);
1382 r
= SetDefaultCommConfigW(lpDeviceW
,lpCommConfig
,dwSize
);
1383 HeapFree( GetProcessHeap(), 0, lpDeviceW
);
1388 /***********************************************************************
1389 * GetDefaultCommConfigW (KERNEL32.@)
1391 * Acquires the default configuration of the specified communication device. (unicode)
1395 * True on successful reading of the default configuration,
1396 * if the device is not found or the buffer is too small.
1398 BOOL WINAPI
GetDefaultCommConfigW(
1399 LPCWSTR lpszName
, /* [in] The unicode name of the device targeted for configuration. */
1400 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
1401 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
1402 afterwards the number of bytes copied to the buffer or
1403 the needed size of the buffer. */
1405 DWORD (WINAPI
*pGetDefaultCommConfig
)(LPCWSTR
, LPCOMMCONFIG
, LPDWORD
);
1406 HMODULE hConfigModule
;
1407 DWORD res
= ERROR_INVALID_PARAMETER
;
1409 TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_w(lpszName
), lpCC
, lpdwSize
, lpdwSize
? *lpdwSize
: 0 );
1410 hConfigModule
= LoadLibraryW(lpszSerialUI
);
1412 if (hConfigModule
) {
1413 pGetDefaultCommConfig
= (void *)GetProcAddress(hConfigModule
, "drvGetDefaultCommConfigW");
1414 if (pGetDefaultCommConfig
) {
1415 res
= pGetDefaultCommConfig(lpszName
, lpCC
, lpdwSize
);
1417 FreeLibrary(hConfigModule
);
1420 if (res
) SetLastError(res
);
1421 return (res
== ERROR_SUCCESS
);
1424 /**************************************************************************
1425 * GetDefaultCommConfigA (KERNEL32.@)
1427 * Acquires the default configuration of the specified communication device. (ascii)
1431 * True on successful reading of the default configuration,
1432 * if the device is not found or the buffer is too small.
1434 BOOL WINAPI
GetDefaultCommConfigA(
1435 LPCSTR lpszName
, /* [in] The ascii name of the device targeted for configuration. */
1436 LPCOMMCONFIG lpCC
, /* [out] The default configuration for the device. */
1437 LPDWORD lpdwSize
) /* [in/out] Initially the size of the default configuration buffer,
1438 afterwards the number of bytes copied to the buffer or
1439 the needed size of the buffer. */
1442 UNICODE_STRING lpszNameW
;
1444 TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_a(lpszName
), lpCC
, lpdwSize
, lpdwSize
? *lpdwSize
: 0 );
1445 if(lpszName
) RtlCreateUnicodeStringFromAsciiz(&lpszNameW
,lpszName
);
1446 else lpszNameW
.Buffer
= NULL
;
1448 ret
= GetDefaultCommConfigW(lpszNameW
.Buffer
,lpCC
,lpdwSize
);
1450 RtlFreeUnicodeString(&lpszNameW
);