Eric Pouech : ntdll/kernel32: GetCommState & SERIAL_GET_LINE_CONTROL
Alexandre Julliard
julliard at wine.codeweavers.com
Tue May 9 14:15:48 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: efb3244b0aeec890e16b210b1b25e424777b8147
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=efb3244b0aeec890e16b210b1b25e424777b8147
Author: Eric Pouech <eric.pouech at wanadoo.fr>
Date: Sun May 7 14:10:49 2006 +0200
ntdll/kernel32: GetCommState & SERIAL_GET_LINE_CONTROL
- implemented SERIAL_GET_LINE_CONTROL ioctl
- made use of it in kernel.GetCommState
---
dlls/kernel/comm.c | 60 +++++++++------------------------------------------
dlls/ntdll/serial.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+), 50 deletions(-)
diff --git a/dlls/kernel/comm.c b/dlls/kernel/comm.c
index 8fd765b..6fa5b89 100644
--- a/dlls/kernel/comm.c
+++ b/dlls/kernel/comm.c
@@ -1082,6 +1082,7 @@ BOOL WINAPI GetCommState(HANDLE handle,
int stat = DTR_CONTROL_ENABLE | RTS_CONTROL_ENABLE;
SERIAL_BAUD_RATE sbr;
+ SERIAL_LINE_CONTROL slc;
TRACE("handle %p, ptr %p\n", handle, lpdcb);
@@ -1093,13 +1094,21 @@ BOOL WINAPI GetCommState(HANDLE handle,
lpdcb->DCBlength = sizeof(*lpdcb);
if (!DeviceIoControl(handle, IOCTL_SERIAL_GET_BAUD_RATE,
- NULL, 0, &sbr, sizeof(sbr), NULL, NULL))
+ NULL, 0, &sbr, sizeof(sbr), NULL, NULL) ||
+ !DeviceIoControl(handle, IOCTL_SERIAL_GET_LINE_CONTROL,
+ NULL, 0, &slc, sizeof(slc), NULL, NULL))
return FALSE;
+
/* yes, they seem no never be (re)set on NT */
lpdcb->fBinary = 1;
lpdcb->fParity = 0;
lpdcb->BaudRate = sbr.BaudRate;
+
+ lpdcb->StopBits = slc.StopBits;
+ lpdcb->Parity = slc.Parity;
+ lpdcb->ByteSize = slc.WordLength;
+
fd = get_comm_fd( handle, FILE_READ_DATA );
if (fd < 0) return FALSE;
if (tcgetattr(fd, &port) == -1) {
@@ -1118,59 +1127,10 @@ #ifdef TIOCMGET
}
#endif
release_comm_fd( handle, fd );
- switch (port.c_cflag & CSIZE) {
- case CS5:
- lpdcb->ByteSize = 5;
- break;
- case CS6:
- lpdcb->ByteSize = 6;
- break;
- case CS7:
- lpdcb->ByteSize = 7;
- break;
- case CS8:
- lpdcb->ByteSize = 8;
- break;
- default:
- ERR("unknown size %x\n", port.c_cflag & CSIZE);
- }
-
if(port.c_iflag & INPCK)
lpdcb->fParity = TRUE;
else
lpdcb->fParity = FALSE;
-#ifdef CMSPAR
- switch (port.c_cflag & (PARENB | PARODD | CMSPAR))
-#else
- switch (port.c_cflag & (PARENB | PARODD))
-#endif
- {
- case 0:
- lpdcb->Parity = NOPARITY;
- break;
- case PARENB:
- lpdcb->Parity = EVENPARITY;
- break;
- case (PARENB | PARODD):
- lpdcb->Parity = ODDPARITY;
- break;
-#ifdef CMSPAR
- case (PARENB | CMSPAR):
- lpdcb->Parity = MARKPARITY;
- break;
- case (PARENB | PARODD | CMSPAR):
- lpdcb->Parity = SPACEPARITY;
- break;
-#endif
- }
-
- if (port.c_cflag & CSTOPB)
- if(lpdcb->ByteSize == 5)
- lpdcb->StopBits = ONE5STOPBITS;
- else
- lpdcb->StopBits = TWOSTOPBITS;
- else
- lpdcb->StopBits = ONESTOPBIT;
lpdcb->fNull = 0;
diff --git a/dlls/ntdll/serial.c b/dlls/ntdll/serial.c
index c86dc66..0a6d8f1 100644
--- a/dlls/ntdll/serial.c
+++ b/dlls/ntdll/serial.c
@@ -185,6 +185,53 @@ #endif
return STATUS_SUCCESS;
}
+static NTSTATUS get_line_control(int fd, SERIAL_LINE_CONTROL* slc)
+{
+ struct termios port;
+
+ if (tcgetattr(fd, &port) == -1)
+ {
+ ERR("tcgetattr error '%s'\n", strerror(errno));
+ return FILE_GetNtStatus();
+ }
+
+#ifdef CMSPAR
+ switch (port.c_cflag & (PARENB | PARODD | CMSPAR))
+#else
+ switch (port.c_cflag & (PARENB | PARODD))
+#endif
+ {
+ case 0: slc->Parity = NOPARITY; break;
+ case PARENB: slc->Parity = EVENPARITY; break;
+ case PARENB|PARODD: slc->Parity = ODDPARITY; break;
+#ifdef CMSPAR
+ case PARENB|CMSPAR: slc->Parity = MARKPARITY; break;
+ case PARENB|PARODD|CMSPAR: slc->Parity = SPACEPARITY; break;
+ break;
+#endif
+ }
+ switch (port.c_cflag & CSIZE)
+ {
+ case CS5: slc->WordLength = 5; break;
+ case CS6: slc->WordLength = 6; break;
+ case CS7: slc->WordLength = 7; break;
+ case CS8: slc->WordLength = 8; break;
+ default: ERR("unknown size %x\n", port.c_cflag & CSIZE);
+ }
+
+ if (port.c_cflag & CSTOPB)
+ {
+ if (slc->WordLength == 5)
+ slc->StopBits = ONE5STOPBITS;
+ else
+ slc->StopBits = TWOSTOPBITS;
+ }
+ else
+ slc->StopBits = ONESTOPBIT;
+
+ return STATUS_SUCCESS;
+}
+
static NTSTATUS get_modem_status(int fd, DWORD* lpModemStat)
{
NTSTATUS status = STATUS_SUCCESS;
@@ -692,6 +739,15 @@ NTSTATUS COMM_DeviceIoControl(HANDLE hDe
}
else status = STATUS_INVALID_PARAMETER;
break;
+ case IOCTL_SERIAL_GET_LINE_CONTROL:
+ if (lpOutBuffer && nOutBufferSize == sizeof(SERIAL_LINE_CONTROL))
+ {
+ if (!(status = get_line_control(fd, (SERIAL_LINE_CONTROL*)lpOutBuffer)))
+ sz = sizeof(SERIAL_LINE_CONTROL);
+ }
+ else
+ status = STATUS_INVALID_PARAMETER;
+ break;
case IOCTL_SERIAL_GET_MODEMSTATUS:
if (lpOutBuffer && nOutBufferSize == sizeof(DWORD))
{
More information about the wine-cvs
mailing list