Skip to content

Commit d01612f

Browse files
committed
[KERNEL32] Rework SetCommState().
1 parent b001c6e commit d01612f

1 file changed

Lines changed: 199 additions & 0 deletions

File tree

dll/win32/kernel32/wine/comm.c

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,7 @@ static void dump_dcb(const DCB* lpdcb)
804804
*
805805
* True on success, false on failure, e.g., if the XonChar is equal to the XoffChar.
806806
*/
807+
#if 0
807808
BOOL WINAPI SetCommState( HANDLE handle, LPDCB lpdcb)
808809
{
809810
SERIAL_BAUD_RATE sbr;
@@ -880,7 +881,205 @@ BOOL WINAPI SetCommState( HANDLE handle, LPDCB lpdcb)
880881
DeviceIoControl(handle, IOCTL_SERIAL_SET_CHARS,
881882
&sc, sizeof(sc), NULL, 0, &dwBytesReturned, NULL));
882883
}
884+
#else
885+
BOOL WINAPI SetCommState(_In_ HANDLE hFile, _In_ LPDCB lpDCB)
886+
{
887+
IO_STATUS_BLOCK IoStatusBlock;
888+
SERIAL_LINE_CONTROL Slc;
889+
SERIAL_BAUD_RATE Sbr;
890+
SERIAL_HANDFLOW Sh;
891+
SERIAL_CHARS Sc;
892+
DCB SavedDCB;
893+
HANDLE Event;
894+
NTSTATUS Status;
895+
896+
if (!lpDCB)
897+
{
898+
ERR("GetCommState: lpDCB is NULL\n");
899+
SetLastError(ERROR_INVALID_PARAMETER);
900+
return FALSE;
901+
}
902+
903+
TRACE("SetCommState: hFile %IX\n", hFile);
904+
dump_dcb(lpDCB);
905+
906+
if (!GetCommState(hFile, &SavedDCB))
907+
{
908+
ERR("SetCommState: GetCommState() failed\n");
909+
return FALSE;
910+
}
911+
912+
Event = CreateEventA(NULL, TRUE, FALSE, NULL);
913+
if (!Event)
914+
{
915+
ERR("SetCommState: Event is NULL\n");
916+
return FALSE;
917+
}
918+
919+
Sbr.BaudRate = lpDCB->BaudRate;
920+
921+
Status = NtDeviceIoControlFile(hFile, Event, NULL, NULL, &IoStatusBlock,
922+
IOCTL_SERIAL_SET_BAUD_RATE, &Sbr, sizeof(Sbr), NULL, 0);
923+
if (Status == STATUS_PENDING)
924+
{
925+
Status = NtWaitForSingleObject(Event, FALSE, NULL);
926+
if (NT_SUCCESS(Status))
927+
Status = IoStatusBlock.Status;
928+
}
929+
if (NT_ERROR(Status))
930+
{
931+
ERR("SetCommState: Status %X\n", Status);
932+
CloseHandle(Event);
933+
BaseSetLastNTError(Status);
934+
return FALSE;
935+
}
936+
937+
Slc.StopBits = lpDCB->StopBits;
938+
Slc.Parity = lpDCB->Parity;
939+
Slc.WordLength = lpDCB->ByteSize;
940+
941+
Sc.XonChar = lpDCB->XonChar;
942+
Sc.XoffChar = lpDCB->XoffChar;
943+
Sc.ErrorChar = lpDCB->ErrorChar;
944+
Sc.BreakChar = lpDCB->ErrorChar;
945+
Sc.EofChar = lpDCB->EofChar;
946+
Sc.EventChar = lpDCB->EvtChar;
947+
948+
RtlZeroMemory(&Sh, sizeof(Sh));
949+
950+
switch (lpDCB->fRtsControl)
951+
{
952+
case 0:
953+
break;
954+
955+
case 1:
956+
Sh.FlowReplace |= 0x40;
957+
break;
958+
959+
case 2:
960+
Sh.FlowReplace |= 0x80;
961+
break;
962+
963+
case 3:
964+
Sh.FlowReplace |= 0xC0;
965+
break;
966+
967+
default:
968+
ERR("SetCommState: not valid RtsControl %X\n", lpDCB->fRtsControl);
969+
goto ErrorExit;
970+
}
971+
972+
switch (lpDCB->fDtrControl)
973+
{
974+
case 0:
975+
break;
976+
977+
case 1:
978+
Sh.ControlHandShake |= 1;
979+
break;
883980

981+
case 2:
982+
Sh.ControlHandShake |= 2;
983+
break;
984+
985+
default:
986+
ERR("SetCommState: not valid DtrControl %X\n", lpDCB->fDtrControl);
987+
goto ErrorExit;
988+
}
989+
990+
if (lpDCB->fDsrSensitivity)
991+
Sh.ControlHandShake |= 0x40;
992+
993+
if (lpDCB->fOutxCtsFlow)
994+
Sh.ControlHandShake |= 0x08;
995+
996+
if (lpDCB->fOutxDsrFlow)
997+
Sh.ControlHandShake |= 0x10;
998+
999+
if (lpDCB->fOutX)
1000+
Sh.FlowReplace |= 1;
1001+
1002+
if (lpDCB->fInX)
1003+
Sh.FlowReplace |= 2;
1004+
1005+
if (lpDCB->fNull)
1006+
Sh.FlowReplace |= 8;
1007+
1008+
if (lpDCB->fErrorChar)
1009+
Sh.FlowReplace |= 4;
1010+
1011+
if (lpDCB->fTXContinueOnXoff)
1012+
Sh.FlowReplace |= 0x80000000;
1013+
1014+
if (lpDCB->fAbortOnError)
1015+
Sh.ControlHandShake |= 0x80000000;
1016+
1017+
if (lpDCB->fRtsControl == 1)
1018+
EscapeCommFunction(hFile, 3);
1019+
else if (lpDCB->fRtsControl == 0)
1020+
EscapeCommFunction(hFile, 4);
1021+
1022+
if (lpDCB->fDtrControl == 1)
1023+
EscapeCommFunction(hFile, 5);
1024+
else if (lpDCB->fDtrControl == 0)
1025+
EscapeCommFunction(hFile, 6);
1026+
1027+
Sh.XonLimit = lpDCB->XonLim;
1028+
Sh.XoffLimit = lpDCB->XoffLim;
1029+
1030+
Status = NtDeviceIoControlFile(hFile, Event, NULL, NULL, &IoStatusBlock,
1031+
IOCTL_SERIAL_SET_LINE_CONTROL, &Slc, sizeof(Slc), NULL, 0);
1032+
if (Status == STATUS_PENDING)
1033+
{
1034+
Status = NtWaitForSingleObject(Event, FALSE, NULL);
1035+
if (NT_SUCCESS(Status))
1036+
Status = IoStatusBlock.Status;
1037+
}
1038+
if (NT_ERROR(Status))
1039+
{
1040+
ERR("SetCommState: Status %X\n", Status);
1041+
goto ErrorExit;
1042+
}
1043+
1044+
Status = NtDeviceIoControlFile(hFile, Event, NULL, NULL, &IoStatusBlock,
1045+
IOCTL_SERIAL_SET_CHARS, &Sc, sizeof(Sc), NULL, 0);
1046+
if (Status == STATUS_PENDING)
1047+
{
1048+
Status = NtWaitForSingleObject(Event, FALSE, NULL);
1049+
if (NT_SUCCESS(Status))
1050+
Status = IoStatusBlock.Status;
1051+
}
1052+
if (NT_ERROR(Status))
1053+
{
1054+
ERR("SetCommState: Status %X\n", Status);
1055+
goto ErrorExit;
1056+
}
1057+
1058+
Status = NtDeviceIoControlFile(hFile, Event, NULL, NULL, &IoStatusBlock,
1059+
IOCTL_SERIAL_SET_HANDFLOW, &Sh, sizeof(Sh), NULL, 0);
1060+
if (Status == STATUS_PENDING)
1061+
{
1062+
Status = NtWaitForSingleObject(Event, FALSE, NULL);
1063+
if (NT_SUCCESS(Status))
1064+
Status = IoStatusBlock.Status;
1065+
}
1066+
if (NT_ERROR(Status))
1067+
{
1068+
ERR("SetCommState: Status %X\n", Status);
1069+
goto ErrorExit;
1070+
}
1071+
1072+
CloseHandle(Event);
1073+
return TRUE;
1074+
1075+
ErrorExit:
1076+
1077+
CloseHandle(Event);
1078+
SetCommState(hFile, &SavedDCB);
1079+
BaseSetLastNTError(Status);
1080+
return FALSE;
1081+
}
1082+
#endif
8841083

8851084
/*****************************************************************************
8861085
* GetCommState (KERNEL32.@)

0 commit comments

Comments
 (0)