2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/misc/comm.c
5 * PURPOSE: Comm functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 * modified from WINE [ Onno Hovers, (onno@stack.urc.tue.nl) ]
8 * Robert Dickenson (robd@mok.lvcom.com)
9 * Saveliy Tretiakov (saveliyt@mail.ru)
10 * Dmitry Philippov (shedon@mail.ru)
13 * RDD (30/09/2002) implemented many function bodies to call serial driver.
14 * KJK (11/02/2003) implemented BuildCommDCB & BuildCommDCBAndTimeouts
15 * ST (21/03/2005) implemented GetCommProperties
16 * ST (24/03/2005) implemented ClearCommError. Corrected many functions.
17 * ST (05/04/2005) implemented CommConfigDialog
18 * DP (11/06/2005) implemented GetCommConfig
19 * DP (12/06/2005) implemented SetCommConfig
20 * KJK (26/12/2008) reimplemented BuildCommDCB & BuildCommDCBAndTimeouts elsewhere
25 #undef SERIAL_LSRMST_ESCAPE
26 #undef SERIAL_LSRMST_LSR_DATA
27 #undef SERIAL_LSRMST_LSR_NODATA
28 #undef SERIAL_LSRMST_MST
29 #undef SERIAL_IOC_FCR_FIFO_ENABLE
30 #undef SERIAL_IOC_FCR_RCVR_RESET
31 #undef SERIAL_IOC_FCR_XMIT_RESET
32 #undef SERIAL_IOC_FCR_DMA_MODE
33 #undef SERIAL_IOC_FCR_RES1
34 #undef SERIAL_IOC_FCR_RES2
35 #undef SERIAL_IOC_FCR_RCVR_TRIGGER_LSB
36 #undef SERIAL_IOC_FCR_RCVR_TRIGGER_MSB
37 #undef SERIAL_IOC_MCR_DTR
38 #undef SERIAL_IOC_MCR_RTS
39 #undef SERIAL_IOC_MCR_OUT1
40 #undef SERIAL_IOC_MCR_OUT2
41 #undef SERIAL_IOC_MCR_LOOP
42 #undef IOCTL_SERIAL_LSRMST_INSERT
48 static const WCHAR lpszSerialUI
[] = {
49 's','e','r','i','a','l','u','i','.','d','l','l',0 };
56 ClearCommBreak(HANDLE hFile
)
58 DWORD dwBytesReturned
;
59 return DeviceIoControl(hFile
, IOCTL_SERIAL_SET_BREAK_OFF
,
60 NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
69 ClearCommError(HANDLE hFile
, LPDWORD lpErrors
, LPCOMSTAT lpComStat
)
72 DWORD dwBytesReturned
;
73 SERIAL_STATUS SerialStatus
;
75 status
= DeviceIoControl(hFile
, IOCTL_SERIAL_GET_COMMSTATUS
, NULL
, 0,
76 &SerialStatus
, sizeof(SERIAL_STATUS
), &dwBytesReturned
, NULL
);
78 if(!NT_SUCCESS(status
))
86 if(SerialStatus
.Errors
& SERIAL_ERROR_BREAK
)
87 *lpErrors
|= CE_BREAK
;
88 if(SerialStatus
.Errors
& SERIAL_ERROR_FRAMING
)
89 *lpErrors
|= CE_FRAME
;
90 if(SerialStatus
.Errors
& SERIAL_ERROR_OVERRUN
)
91 *lpErrors
|= CE_OVERRUN
;
92 if(SerialStatus
.Errors
& SERIAL_ERROR_QUEUEOVERRUN
)
93 *lpErrors
|= CE_RXOVER
;
94 if(SerialStatus
.Errors
& SERIAL_ERROR_PARITY
)
95 *lpErrors
|= CE_RXPARITY
;
100 ZeroMemory(lpComStat
, sizeof(COMSTAT
));
102 if(SerialStatus
.HoldReasons
& SERIAL_TX_WAITING_FOR_CTS
)
103 lpComStat
->fCtsHold
= TRUE
;
104 if(SerialStatus
.HoldReasons
& SERIAL_TX_WAITING_FOR_DSR
)
105 lpComStat
->fDsrHold
= TRUE
;
106 if(SerialStatus
.HoldReasons
& SERIAL_TX_WAITING_FOR_DCD
)
107 lpComStat
->fRlsdHold
= TRUE
;
108 if(SerialStatus
.HoldReasons
& SERIAL_TX_WAITING_FOR_XON
)
109 lpComStat
->fXoffHold
= TRUE
;
110 if(SerialStatus
.HoldReasons
& SERIAL_TX_WAITING_XOFF_SENT
)
111 lpComStat
->fXoffSent
= TRUE
;
113 if(SerialStatus
.EofReceived
)
114 lpComStat
->fEof
= TRUE
;
116 if(SerialStatus
.WaitForImmediate
)
117 lpComStat
->fTxim
= TRUE
;
119 lpComStat
->cbInQue
= SerialStatus
.AmountInInQueue
;
120 lpComStat
->cbOutQue
= SerialStatus
.AmountInOutQueue
;
131 CommConfigDialogA(LPCSTR lpszName
, HWND hWnd
, LPCOMMCONFIG lpCC
)
136 /* don't use the static thread buffer so operations in serialui
137 don't overwrite the string */
138 if(!(NameW
= FilenameA2W(lpszName
, TRUE
)))
143 result
= CommConfigDialogW(NameW
, hWnd
, lpCC
);
145 RtlFreeHeap(RtlGetProcessHeap(), 0, NameW
);
156 CommConfigDialogW(LPCWSTR lpszName
, HWND hWnd
, LPCOMMCONFIG lpCC
)
158 DWORD (WINAPI
*drvCommDlgW
)(LPCWSTR
, HWND
, LPCOMMCONFIG
);
159 HMODULE hSerialuiDll
;
162 //FIXME: Get dll name from registry. (setupapi needed)
163 if(!(hSerialuiDll
= LoadLibraryW(L
"serialui.dll")))
165 DPRINT("CommConfigDialogW: serialui.dll not found.\n");
169 drvCommDlgW
= (DWORD (WINAPI
*)(LPCWSTR
, HWND
, LPCOMMCONFIG
))
170 GetProcAddress(hSerialuiDll
, "drvCommConfigDialogW");
174 DPRINT("CommConfigDialogW: serialui does not export drvCommConfigDialogW\n");
175 FreeLibrary(hSerialuiDll
);
179 result
= drvCommDlgW(lpszName
, hWnd
, lpCC
);
180 SetLastError(result
);
181 FreeLibrary(hSerialuiDll
);
183 return (result
== ERROR_SUCCESS
? TRUE
: FALSE
);
192 EscapeCommFunction(HANDLE hFile
, DWORD dwFunc
)
195 DWORD dwBytesReturned
;
198 case CLRDTR
: // Clears the DTR (data-terminal-ready) signal.
199 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_CLR_DTR
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
201 case CLRRTS
: // Clears the RTS (request-to-send) signal.
202 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_CLR_RTS
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
204 case SETDTR
: // Sends the DTR (data-terminal-ready) signal.
205 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_SET_DTR
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
207 case SETRTS
: // Sends the RTS (request-to-send) signal.
208 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_SET_RTS
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
210 case SETXOFF
: // Causes transmission to act as if an XOFF character has been received.
211 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_SET_XOFF
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
213 case SETXON
: // Causes transmission to act as if an XON character has been received.
214 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_SET_XON
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
216 case SETBREAK
: // Suspends character transmission and places the transmission line in a break state until the ClearCommBreak function is called (or EscapeCommFunction is called with the CLRBREAK extended function code). The SETBREAK extended function code is identical to the SetCommBreak function. Note that this extended function does not flush data that has not been transmitted.
217 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_SET_BREAK_ON
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
219 case CLRBREAK
: // Restores character transmission and places the transmission line in a nonbreak state. The CLRBREAK extended function code is identical to the ClearCommBreak function.
220 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_SET_BREAK_OFF
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
223 DPRINT("EscapeCommFunction() WARNING: unknown function code\n");
224 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
236 GetCommConfig(HANDLE hCommDev
, LPCOMMCONFIG lpCC
, LPDWORD lpdwSize
)
238 BOOL ReturnValue
= FALSE
;
239 LPCOMMPROP lpComPort
;
241 DPRINT("GetCommConfig(%d, %p, %p)\n", hCommDev
, lpCC
, lpdwSize
);
243 lpComPort
= RtlAllocateHeap( hProcessHeap
,
245 sizeof(COMMPROP
) + 0x100 );
247 if(NULL
== lpComPort
) {
248 DPRINT("GetCommConfig() - ERROR_NOT_ENOUGH_MEMORY\n");
249 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
253 if( (NULL
== lpdwSize
)
254 || (NULL
== lpCC
) ) {
255 DPRINT("GetCommConfig() - invalid parameter\n");
256 SetLastError(ERROR_INVALID_PARAMETER
);
261 lpComPort
->wPacketLength
= sizeof(COMMPROP
) + 0x100;
262 lpComPort
->dwProvSpec1
= COMMPROP_INITIALIZED
;
263 ReturnValue
= GetCommProperties(hCommDev
, lpComPort
);
266 lpCC
->dwSize
= sizeof(COMMCONFIG
);
269 lpCC
->dwProviderSubType
= lpComPort
->dwProvSubType
;
270 lpCC
->dwProviderSize
= lpComPort
->dwProvSpec2
;
271 if( 0 == lpComPort
->dwProvSpec2
) {
272 lpCC
->dwProviderOffset
= 0;
274 lpCC
->dwProviderOffset
= (ULONG_PTR
)&lpCC
->wcProviderData
[0] - (ULONG_PTR
)lpCC
;
276 if( (lpCC
->dwProviderSize
+lpCC
->dwSize
) > *lpdwSize
) {
277 DPRINT("GetCommConfig() - ERROR_INSUFFICIENT_BUFFER\n");
278 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
281 RtlCopyMemory(lpCC
->wcProviderData
, lpComPort
->wcProvChar
, lpCC
->dwProviderSize
);
282 ReturnValue
= GetCommState(hCommDev
, &lpCC
->dcb
);
284 *lpdwSize
= lpCC
->dwSize
+lpCC
->dwProviderSize
;
288 RtlFreeHeap(hProcessHeap
, 0, lpComPort
);
289 return (ReturnValue
);
298 GetCommMask(HANDLE hFile
, LPDWORD lpEvtMask
)
300 DWORD dwBytesReturned
;
301 return DeviceIoControl(hFile
, IOCTL_SERIAL_GET_WAIT_MASK
,
302 NULL
, 0, lpEvtMask
, sizeof(DWORD
), &dwBytesReturned
, NULL
);
311 GetCommModemStatus(HANDLE hFile
, LPDWORD lpModemStat
)
313 DWORD dwBytesReturned
;
315 return DeviceIoControl(hFile
, IOCTL_SERIAL_GET_MODEMSTATUS
,
316 NULL
, 0, lpModemStat
, sizeof(DWORD
), &dwBytesReturned
, NULL
);
325 GetCommProperties(HANDLE hFile
, LPCOMMPROP lpCommProp
)
327 DWORD dwBytesReturned
;
328 return DeviceIoControl(hFile
, IOCTL_SERIAL_GET_PROPERTIES
, 0, 0,
329 lpCommProp
, sizeof(COMMPROP
), &dwBytesReturned
, 0);
338 GetCommState(HANDLE hFile
, LPDCB lpDCB
)
341 DWORD dwBytesReturned
;
343 SERIAL_BAUD_RATE BaudRate
;
344 SERIAL_HANDFLOW HandFlow
;
345 SERIAL_CHARS SpecialChars
;
346 SERIAL_LINE_CONTROL LineControl
;
348 DPRINT("GetCommState(%d, %p)\n", hFile
, lpDCB
);
351 SetLastError(ERROR_INVALID_PARAMETER
);
352 DPRINT("ERROR: GetCommState() - NULL DCB pointer\n");
356 if (!DeviceIoControl(hFile
, IOCTL_SERIAL_GET_BAUD_RATE
,
357 NULL
, 0, &BaudRate
, sizeof(BaudRate
), &dwBytesReturned
, NULL
) ||
358 !DeviceIoControl(hFile
, IOCTL_SERIAL_GET_LINE_CONTROL
,
359 NULL
, 0, &LineControl
, sizeof(LineControl
), &dwBytesReturned
, NULL
) ||
360 !DeviceIoControl(hFile
, IOCTL_SERIAL_GET_HANDFLOW
,
361 NULL
, 0, &HandFlow
, sizeof(HandFlow
), &dwBytesReturned
, NULL
) ||
362 !DeviceIoControl(hFile
, IOCTL_SERIAL_GET_CHARS
,
363 NULL
, 0, &SpecialChars
, sizeof(SpecialChars
), &dwBytesReturned
, NULL
))
366 memset(lpDCB
, 0, sizeof(*lpDCB
));
367 lpDCB
->DCBlength
= sizeof(*lpDCB
);
371 lpDCB
->BaudRate
= BaudRate
.BaudRate
;
373 lpDCB
->StopBits
= LineControl
.StopBits
;
374 lpDCB
->Parity
= LineControl
.Parity
;
375 lpDCB
->ByteSize
= LineControl
.WordLength
;
377 if (HandFlow
.ControlHandShake
& SERIAL_CTS_HANDSHAKE
) {
378 lpDCB
->fOutxCtsFlow
= 1;
380 if (HandFlow
.ControlHandShake
& SERIAL_DSR_HANDSHAKE
) {
381 lpDCB
->fOutxDsrFlow
= 1;
383 if (HandFlow
.ControlHandShake
& SERIAL_DTR_CONTROL
) {
384 lpDCB
->fDtrControl
= 1;
386 if (HandFlow
.ControlHandShake
& SERIAL_DTR_HANDSHAKE
) {
387 lpDCB
->fDtrControl
= 2;
389 if (HandFlow
.ControlHandShake
& SERIAL_RTS_CONTROL
) {
390 lpDCB
->fRtsControl
= 1;
392 if (HandFlow
.ControlHandShake
& SERIAL_RTS_HANDSHAKE
) {
393 lpDCB
->fRtsControl
= 2;
395 if (HandFlow
.ControlHandShake
& SERIAL_DSR_SENSITIVITY
) {
396 lpDCB
->fDsrSensitivity
= 1;
398 if (HandFlow
.ControlHandShake
& SERIAL_ERROR_ABORT
) {
399 lpDCB
->fAbortOnError
= 1;
402 if (HandFlow
.FlowReplace
& SERIAL_ERROR_CHAR
) {
403 lpDCB
->fErrorChar
= 1;
405 if (HandFlow
.FlowReplace
& SERIAL_NULL_STRIPPING
) {
408 if (HandFlow
.FlowReplace
& SERIAL_XOFF_CONTINUE
) {
409 lpDCB
->fTXContinueOnXoff
= 1;
411 lpDCB
->XonLim
= (WORD
)HandFlow
.XonLimit
;
412 lpDCB
->XoffLim
= (WORD
)HandFlow
.XoffLimit
;
414 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_GET_CHARS
,
415 NULL
, 0, &SpecialChars
, sizeof(SpecialChars
), &dwBytesReturned
, NULL
);
416 if (!NT_SUCCESS(result
)) {
417 DPRINT("ERROR: GetCommState() - DeviceIoControl(IOCTL_SERIAL_GET_CHARS) Failed.\n");
421 lpDCB
->EofChar
= SpecialChars
.EofChar
;
422 lpDCB
->ErrorChar
= SpecialChars
.ErrorChar
;
423 // = SpecialChars.BreakChar;
424 lpDCB
->EvtChar
= SpecialChars
.EventChar
;
425 lpDCB
->XonChar
= SpecialChars
.XonChar
;
426 lpDCB
->XoffChar
= SpecialChars
.XoffChar
;
428 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_GET_LINE_CONTROL
,
429 NULL
, 0, &LineControl
, sizeof(LineControl
), &dwBytesReturned
, NULL
);
430 if (!NT_SUCCESS(result
)) {
431 DPRINT("ERROR: GetCommState() - DeviceIoControl(IOCTL_SERIAL_GET_LINE_CONTROL) Failed.\n");
434 lpDCB
->StopBits
= LineControl
.StopBits
;
435 lpDCB
->Parity
= LineControl
.Parity
;
436 lpDCB
->ByteSize
= LineControl
.WordLength
;
437 DPRINT("GetCommState() - COMPLETED SUCCESSFULLY\n");
447 GetCommTimeouts(HANDLE hFile
, LPCOMMTIMEOUTS lpCommTimeouts
)
449 DWORD dwBytesReturned
;
451 if (lpCommTimeouts
== NULL
) {
455 return DeviceIoControl(hFile
, IOCTL_SERIAL_GET_TIMEOUTS
,
457 lpCommTimeouts
, sizeof(COMMTIMEOUTS
),
458 &dwBytesReturned
, NULL
);
467 GetDefaultCommConfigW(LPCWSTR lpszName
, LPCOMMCONFIG lpCC
, LPDWORD lpdwSize
)
469 FARPROC pGetDefaultCommConfig
;
470 HMODULE hConfigModule
;
471 DWORD res
= ERROR_INVALID_PARAMETER
;
473 DPRINT("(%s, %p, %p) *lpdwSize: %u\n", lpszName
, lpCC
, lpdwSize
, lpdwSize
? *lpdwSize
: 0 );
474 hConfigModule
= LoadLibraryW(lpszSerialUI
);
477 pGetDefaultCommConfig
= GetProcAddress(hConfigModule
, "drvGetDefaultCommConfigW");
478 if (pGetDefaultCommConfig
) {
479 res
= pGetDefaultCommConfig(lpszName
, lpCC
, lpdwSize
);
481 FreeLibrary(hConfigModule
);
484 if (res
) SetLastError(res
);
485 return (res
== ERROR_SUCCESS
);
494 GetDefaultCommConfigA(LPCSTR lpszName
, LPCOMMCONFIG lpCC
, LPDWORD lpdwSize
)
497 UNICODE_STRING lpszNameW
;
499 DPRINT("(%s, %p, %p) *lpdwSize: %u\n", lpszName
, lpCC
, lpdwSize
, lpdwSize
? *lpdwSize
: 0 );
500 if(lpszName
) RtlCreateUnicodeStringFromAsciiz(&lpszNameW
,lpszName
);
501 else lpszNameW
.Buffer
= NULL
;
503 ret
= GetDefaultCommConfigW(lpszNameW
.Buffer
,lpCC
,lpdwSize
);
505 RtlFreeUnicodeString(&lpszNameW
);
515 PurgeComm(HANDLE hFile
, DWORD dwFlags
)
517 DWORD dwBytesReturned
;
519 return DeviceIoControl(hFile
, IOCTL_SERIAL_PURGE
,
520 &dwFlags
, sizeof(DWORD
), NULL
, 0, &dwBytesReturned
, NULL
);
529 SetCommBreak(HANDLE hFile
)
531 DWORD dwBytesReturned
;
533 return DeviceIoControl(hFile
, IOCTL_SERIAL_SET_BREAK_ON
, NULL
, 0, NULL
, 0, &dwBytesReturned
, NULL
);
542 SetCommConfig(HANDLE hCommDev
, LPCOMMCONFIG lpCC
, DWORD dwSize
)
544 BOOL ReturnValue
= FALSE
;
546 DPRINT("SetCommConfig(%d, %p, %d)\n", hCommDev
, lpCC
, dwSize
);
550 DPRINT("SetCommConfig() - invalid parameter\n");
551 SetLastError(ERROR_INVALID_PARAMETER
);
556 ReturnValue
= SetCommState(hCommDev
, &lpCC
->dcb
);
568 SetCommMask(HANDLE hFile
, DWORD dwEvtMask
)
570 DWORD dwBytesReturned
;
572 return DeviceIoControl(hFile
, IOCTL_SERIAL_SET_WAIT_MASK
,
573 &dwEvtMask
, sizeof(DWORD
), NULL
, 0, &dwBytesReturned
, NULL
);
582 SetCommState(HANDLE hFile
, LPDCB lpDCB
)
585 DWORD dwBytesReturned
;
587 SERIAL_BAUD_RATE BaudRate
;
588 SERIAL_HANDFLOW HandFlow
;
589 SERIAL_CHARS SpecialChars
;
590 SERIAL_LINE_CONTROL LineControl
;
592 DPRINT("SetCommState(%d, %p) - ENTERED\n", hFile
, lpDCB
);
595 DPRINT("SetCommState() - ERROR: NULL DCB pointer passed\n");
599 BaudRate
.BaudRate
= lpDCB
->BaudRate
;
600 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_SET_BAUD_RATE
,
601 &BaudRate
, sizeof(BaudRate
), NULL
, 0, &dwBytesReturned
, NULL
);
602 if (!NT_SUCCESS(result
)) {
603 DPRINT("ERROR: SetCommState() - DeviceIoControl(IOCTL_SERIAL_SET_BAUD_RATE) Failed.\n");
607 #define SERIAL_DTR_MASK ((ULONG)0x03)
608 #define SERIAL_DTR_CONTROL ((ULONG)0x01)
609 #define SERIAL_DTR_HANDSHAKE ((ULONG)0x02)
610 #define SERIAL_CTS_HANDSHAKE ((ULONG)0x08)
611 #define SERIAL_DSR_HANDSHAKE ((ULONG)0x10)
612 #define SERIAL_DCD_HANDSHAKE ((ULONG)0x20)
613 #define SERIAL_OUT_HANDSHAKEMASK ((ULONG)0x38)
614 #define SERIAL_DSR_SENSITIVITY ((ULONG)0x40)
615 #define SERIAL_ERROR_ABORT ((ULONG)0x80000000)
616 #define SERIAL_CONTROL_INVALID ((ULONG)0x7fffff84)
618 HandFlow
.ControlHandShake
= 0;
620 if (lpDCB
->fOutxCtsFlow
) {
621 HandFlow
.ControlHandShake
|= SERIAL_CTS_HANDSHAKE
;
623 if (lpDCB
->fOutxDsrFlow
) {
624 HandFlow
.ControlHandShake
|= SERIAL_DSR_HANDSHAKE
;
626 if (lpDCB
->fDtrControl
) {
627 HandFlow
.ControlHandShake
|= SERIAL_DTR_CONTROL
;
629 if (lpDCB
->fDtrControl
) {
630 HandFlow
.ControlHandShake
|= SERIAL_DTR_HANDSHAKE
;
632 if (lpDCB
->fRtsControl
) {
633 HandFlow
.ControlHandShake
|= SERIAL_RTS_CONTROL
;
635 if (lpDCB
->fRtsControl
) {
636 HandFlow
.ControlHandShake
|= SERIAL_RTS_HANDSHAKE
;
638 if (lpDCB
->fDsrSensitivity
) {
639 HandFlow
.ControlHandShake
|= SERIAL_DSR_SENSITIVITY
;
641 if (lpDCB
->fAbortOnError
) {
642 HandFlow
.ControlHandShake
|= SERIAL_ERROR_ABORT
;
645 #define SERIAL_AUTO_TRANSMIT ((ULONG)0x01)
646 #define SERIAL_AUTO_RECEIVE ((ULONG)0x02)
647 #define SERIAL_ERROR_CHAR ((ULONG)0x04)
648 #define SERIAL_NULL_STRIPPING ((ULONG)0x08)
649 #define SERIAL_BREAK_CHAR ((ULONG)0x10)
650 #define SERIAL_RTS_MASK ((ULONG)0xc0)
651 #define SERIAL_RTS_CONTROL ((ULONG)0x40)
652 #define SERIAL_RTS_HANDSHAKE ((ULONG)0x80)
653 #define SERIAL_TRANSMIT_TOGGLE ((ULONG)0xc0)
654 #define SERIAL_XOFF_CONTINUE ((ULONG)0x80000000)
655 #define SERIAL_FLOW_INVALID ((ULONG)0x7fffff20)
657 HandFlow
.FlowReplace
= 0;
658 if (lpDCB
->fErrorChar
) {
659 HandFlow
.FlowReplace
|= SERIAL_ERROR_CHAR
;
662 HandFlow
.FlowReplace
|= SERIAL_NULL_STRIPPING
;
664 if (lpDCB
->fTXContinueOnXoff
) {
665 HandFlow
.FlowReplace
|= SERIAL_XOFF_CONTINUE
;
667 HandFlow
.XonLimit
= lpDCB
->XonLim
;
668 HandFlow
.XoffLimit
= lpDCB
->XoffLim
;
669 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_SET_HANDFLOW
,
670 &HandFlow
, sizeof(HandFlow
), NULL
, 0, &dwBytesReturned
, NULL
);
671 if (!NT_SUCCESS(result
)) {
672 DPRINT("ERROR: SetCommState() - DeviceIoControl(IOCTL_SERIAL_SET_HANDFLOW) Failed.\n");
676 SpecialChars
.EofChar
= lpDCB
->EofChar
;
677 SpecialChars
.ErrorChar
= lpDCB
->ErrorChar
;
678 SpecialChars
.BreakChar
= 0;
679 SpecialChars
.EventChar
= lpDCB
->EvtChar
;
680 SpecialChars
.XonChar
= lpDCB
->XonChar
;
681 SpecialChars
.XoffChar
= lpDCB
->XoffChar
;
682 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_SET_CHARS
,
683 &SpecialChars
, sizeof(SpecialChars
), NULL
, 0, &dwBytesReturned
, NULL
);
684 if (!NT_SUCCESS(result
)) {
685 DPRINT("ERROR: SetCommState() - DeviceIoControl(IOCTL_SERIAL_SET_CHARS) Failed.\n");
689 LineControl
.StopBits
= lpDCB
->StopBits
;
690 LineControl
.Parity
= lpDCB
->Parity
;
691 LineControl
.WordLength
= lpDCB
->ByteSize
;
692 result
= DeviceIoControl(hFile
, IOCTL_SERIAL_SET_LINE_CONTROL
,
693 &LineControl
, sizeof(LineControl
), NULL
, 0, &dwBytesReturned
, NULL
);
694 if (!NT_SUCCESS(result
)) {
695 DPRINT("ERROR: SetCommState() - DeviceIoControl(IOCTL_SERIAL_SET_LINE_CONTROL) Failed.\n");
699 DPRINT("SetCommState() - COMPLETED SUCCESSFULLY\n");
709 SetCommTimeouts(HANDLE hFile
, LPCOMMTIMEOUTS lpCommTimeouts
)
711 DWORD dwBytesReturned
;
712 SERIAL_TIMEOUTS Timeouts
;
714 if (lpCommTimeouts
== NULL
) {
717 Timeouts
.ReadIntervalTimeout
= lpCommTimeouts
->ReadIntervalTimeout
;
718 Timeouts
.ReadTotalTimeoutMultiplier
= lpCommTimeouts
->ReadTotalTimeoutMultiplier
;
719 Timeouts
.ReadTotalTimeoutConstant
= lpCommTimeouts
->ReadTotalTimeoutConstant
;
720 Timeouts
.WriteTotalTimeoutMultiplier
= lpCommTimeouts
->WriteTotalTimeoutMultiplier
;
721 Timeouts
.WriteTotalTimeoutConstant
= lpCommTimeouts
->WriteTotalTimeoutConstant
;
723 return DeviceIoControl(hFile
, IOCTL_SERIAL_SET_TIMEOUTS
,
724 &Timeouts
, sizeof(Timeouts
), NULL
, 0, &dwBytesReturned
, NULL
);
733 SetDefaultCommConfigA(LPCSTR lpszName
, LPCOMMCONFIG lpCC
, DWORD dwSize
)
736 LPWSTR lpDeviceW
= NULL
;
739 DPRINT("(%s, %p, %u)\n", lpszName
, lpCC
, dwSize
);
743 len
= MultiByteToWideChar( CP_ACP
, 0, lpszName
, -1, NULL
, 0 );
745 lpDeviceW
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
748 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
752 MultiByteToWideChar( CP_ACP
, 0, lpszName
, -1, lpDeviceW
, len
);
754 r
= SetDefaultCommConfigW(lpDeviceW
,lpCC
,dwSize
);
755 HeapFree( GetProcessHeap(), 0, lpDeviceW
);
765 SetDefaultCommConfigW(LPCWSTR lpszName
, LPCOMMCONFIG lpCC
, DWORD dwSize
)
767 FARPROC pGetDefaultCommConfig
;
768 HMODULE hConfigModule
;
769 DWORD res
= ERROR_INVALID_PARAMETER
;
771 DPRINT("(%s, %p, %p) *dwSize: %u\n", lpszName
, lpCC
, dwSize
, dwSize
? dwSize
: 0 );
772 hConfigModule
= LoadLibraryW(lpszSerialUI
);
775 pGetDefaultCommConfig
= GetProcAddress(hConfigModule
, "drvGetDefaultCommConfigW");
776 if (pGetDefaultCommConfig
) {
777 res
= pGetDefaultCommConfig(lpszName
, lpCC
, &dwSize
);
779 FreeLibrary(hConfigModule
);
782 if (res
) SetLastError(res
);
783 return (res
== ERROR_SUCCESS
);
792 SetupComm(HANDLE hFile
, DWORD dwInQueue
, DWORD dwOutQueue
)
794 DWORD dwBytesReturned
;
795 SERIAL_QUEUE_SIZE QueueSize
;
797 QueueSize
.InSize
= dwInQueue
;
798 QueueSize
.OutSize
= dwOutQueue
;
799 return DeviceIoControl(hFile
, IOCTL_SERIAL_SET_QUEUE_SIZE
,
800 &QueueSize
, sizeof(QueueSize
), NULL
, 0, &dwBytesReturned
, NULL
);
809 TransmitCommChar(HANDLE hFile
, char cChar
)
811 DWORD dwBytesReturned
;
812 return DeviceIoControl(hFile
, IOCTL_SERIAL_IMMEDIATE_CHAR
,
813 &cChar
, sizeof(cChar
), NULL
, 0, &dwBytesReturned
, NULL
);
822 WaitCommEvent(HANDLE hFile
, LPDWORD lpEvtMask
, LPOVERLAPPED lpOverlapped
)
824 DWORD dwBytesReturned
;
826 if (lpEvtMask
== NULL
) {
830 return DeviceIoControl(hFile
, IOCTL_SERIAL_WAIT_ON_MASK
,
831 NULL
, 0, lpEvtMask
, sizeof(DWORD
), &dwBytesReturned
, lpOverlapped
);