summaryrefslogtreecommitdiffstats
path: root/private/windbg/newdm/com.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/windbg/newdm/com.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/windbg/newdm/com.c')
-rw-r--r--private/windbg/newdm/com.c473
1 files changed, 473 insertions, 0 deletions
diff --git a/private/windbg/newdm/com.c b/private/windbg/newdm/com.c
new file mode 100644
index 000000000..d908a1a30
--- /dev/null
+++ b/private/windbg/newdm/com.c
@@ -0,0 +1,473 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ api.c
+
+Abstract:
+
+ This module implements the all apis that simulate their
+ WIN32 counterparts.
+
+Author:
+
+ Wesley Witt (wesw) 8-Mar-1992
+
+Environment:
+
+ NT 3.1
+
+Revision History:
+
+--*/
+#include "precomp.h"
+#pragma hdrstop
+
+#ifdef min
+#undef min
+#undef max
+#endif
+
+#define COM_PORT_NAME "_NT_DEBUG_PORT"
+#define COM_PORT_BAUD "_NT_DEBUG_BAUD_RATE"
+#define OUT_NORMAL 0
+#define OUT_TERMINAL 1
+
+ULONG KdPollThreadMode = 0;
+
+//
+// Global Data
+//
+HANDLE DmKdComPort;
+
+//
+// This overlapped structure will be used for all serial read
+// operations. We only need one structure since the code is
+// designed so that no more than one serial read operation is
+// outstanding at any one time.
+//
+OVERLAPPED ReadOverlapped;
+
+//
+// This overlapped structure will be used for all serial write
+// operations. We only need one structure since the code is
+// designed so that no more than one serial write operation is
+// outstanding at any one time.
+//
+OVERLAPPED WriteOverlapped;
+
+//
+// This overlapped structure will be used for all event operations.
+// We only need one structure since the code is designed so that no more
+// than one serial event operation is outstanding at any one time.
+//
+OVERLAPPED EventOverlapped;
+
+
+//
+// Global to watch changes in event status. (used for carrier detection)
+//
+DWORD DmKdComEvent;
+
+
+CRITICAL_SECTION csComPort;
+CRITICAL_SECTION csPacket;
+
+
+BOOLEAN
+DmKdInitComPort(
+ BOOLEAN KdModemControl
+ )
+{
+ char ComPortName[16];
+ ULONG Baud;
+ DCB LocalDcb;
+ COMMTIMEOUTS To;
+ DWORD mask;
+
+
+ Baud = KdOptions[KDO_BAUDRATE].value;
+ sprintf( ComPortName, "\\\\.\\com%d", KdOptions[KDO_PORT].value );
+
+ //
+ // Open the device
+ //
+ DmKdComPort = CreateFile(
+ (PSZ)ComPortName,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+ NULL
+ );
+
+ if ( DmKdComPort == (HANDLE)-1 ) {
+ return FALSE;
+ }
+
+ SetupComm(DmKdComPort,(DWORD)4096,(DWORD)4096);
+
+ //
+ // Create the events used by the overlapped structures for the
+ // read and write.
+ //
+
+ ReadOverlapped.hEvent = CreateEvent(
+ NULL,
+ TRUE,
+ FALSE,NULL
+ );
+
+ if (!ReadOverlapped.hEvent) {
+ return FALSE;
+ }
+
+ WriteOverlapped.hEvent = CreateEvent(
+ NULL,
+ TRUE,
+ FALSE,NULL
+ );
+
+ if (!WriteOverlapped.hEvent) {
+ return FALSE;
+ }
+
+ ReadOverlapped.Offset = 0;
+ ReadOverlapped.OffsetHigh = 0;
+
+ WriteOverlapped.Offset = 0;
+ WriteOverlapped.OffsetHigh = 0;
+
+ //
+ // Set up the Comm port....
+ //
+
+ if (!GetCommState(
+ DmKdComPort,
+ &LocalDcb
+ )) {
+
+ return FALSE;
+ }
+
+ LocalDcb.BaudRate = Baud;
+ LocalDcb.ByteSize = 8;
+ LocalDcb.Parity = NOPARITY;
+ LocalDcb.StopBits = ONESTOPBIT;
+ LocalDcb.fDtrControl = DTR_CONTROL_ENABLE;
+ LocalDcb.fRtsControl = RTS_CONTROL_ENABLE;
+ LocalDcb.fBinary = TRUE;
+ LocalDcb.fOutxCtsFlow = FALSE;
+ LocalDcb.fOutxDsrFlow = FALSE;
+ LocalDcb.fOutX = FALSE;
+ LocalDcb.fInX = FALSE;
+
+ if (!SetCommState(
+ DmKdComPort,
+ &LocalDcb
+ )) {
+
+ return FALSE;
+ }
+
+ //
+ // Set the normal read and write timeout time.
+ // The symbols are 10 millisecond intervals.
+ //
+
+ To.ReadIntervalTimeout = 0;
+ To.ReadTotalTimeoutMultiplier = 0;
+ To.ReadTotalTimeoutConstant = 4 * 1000;
+ To.WriteTotalTimeoutMultiplier = 0;
+ To.WriteTotalTimeoutConstant = 4 * 1000;
+
+ if (!SetCommTimeouts(
+ DmKdComPort,
+ &To
+ )) {
+
+ return FALSE;
+ }
+
+ DmKdComEvent = 0;
+ if (KdModemControl) {
+
+ //
+ // Debugger is being run over a modem. Set event to watch
+ // carrier detect.
+ //
+
+ GetCommMask (DmKdComPort, &mask);
+ mask = mask | EV_ERR; // | EV_RLSD;
+ if (!SetCommMask (DmKdComPort, mask)) {
+ return FALSE;
+ }
+
+ EventOverlapped.hEvent = CreateEvent(
+ NULL,
+ TRUE,
+ FALSE,NULL
+ );
+
+ if (!EventOverlapped.hEvent) {
+ return FALSE;
+ }
+
+ EventOverlapped.Offset = 0;
+ EventOverlapped.OffsetHigh = 0;
+
+ DmKdComEvent = 1; // Fake an event, so modem status will be checked
+ }
+
+ InitializeCriticalSection(&csComPort);
+ InitializeCriticalSection(&csPacket);
+
+ return TRUE;
+}
+
+BOOLEAN
+DmKdWriteComPort(
+ IN PUCHAR Buffer,
+ IN ULONG SizeOfBuffer,
+ IN PULONG BytesWritten
+ )
+/*++
+
+Routine Description:
+
+ Writes the supplied bytes to the COM port. Handles overlapped
+ IO requirements and other common com port maintanance.
+
+--*/
+{
+ BOOLEAN rc;
+ DWORD TrashErr;
+ COMSTAT TrashStat;
+
+
+ EnterCriticalSection(&csComPort);
+
+// if (DmKdComEvent) {
+// DmKdCheckComStatus ( );
+// }
+
+ rc = WriteFile(
+ DmKdComPort,
+ Buffer,
+ SizeOfBuffer,
+ BytesWritten,
+ &WriteOverlapped
+ );
+
+ if (!rc) {
+
+ if (GetLastError() == ERROR_IO_PENDING) {
+
+ rc = GetOverlappedResult(
+ DmKdComPort,
+ &WriteOverlapped,
+ BytesWritten,
+ TRUE
+ );
+
+ } else {
+
+ //
+ // Device could be locked up. Clear it just in case.
+ //
+ ClearCommError( DmKdComPort, &TrashErr, &TrashStat );
+
+ }
+ }
+
+ //
+ // this is here for digiboards
+ //
+ FlushFileBuffers( DmKdComPort );
+
+ LeaveCriticalSection(&csComPort);
+
+ return rc;
+}
+
+BOOLEAN
+DmKdReadComPort(
+ IN PUCHAR Buffer,
+ IN ULONG SizeOfBuffer,
+ IN PULONG BytesRead
+ )
+/*++
+
+Routine Description:
+
+ Reads bytes from the COM port. Handles overlapped
+ IO requirements and other common com port maintanance.
+
+--*/
+{
+ BOOLEAN rc;
+ DWORD TrashErr;
+ COMSTAT TrashStat;
+
+
+ EnterCriticalSection(&csComPort);
+
+// if (DmKdComEvent) {
+// DmKdCheckComStatus ( );
+// }
+
+ rc = ReadFile(
+ DmKdComPort,
+ Buffer,
+ SizeOfBuffer,
+ BytesRead,
+ &ReadOverlapped
+ );
+
+ if (!rc) {
+
+ if (GetLastError() == ERROR_IO_PENDING) {
+
+ rc = GetOverlappedResult(
+ DmKdComPort,
+ &ReadOverlapped,
+ BytesRead,
+ TRUE
+ );
+
+ } else {
+
+ //
+ // Device could be locked up. Clear it just in case.
+ //
+ ClearCommError( DmKdComPort, &TrashErr, &TrashStat );
+
+ }
+ }
+
+ LeaveCriticalSection(&csComPort);
+
+ return rc;
+}
+
+VOID
+DmKdCheckComStatus (
+ )
+/*++
+
+Routine Description:
+
+ Called when the com port status trigger signals a change.
+ This function handles the change in status.
+
+ Note: status is only monitored when being used over the modem.
+
+--*/
+{
+ DWORD status;
+ DWORD CommErr;
+ COMSTAT CommStat;
+#if 0
+ BOOLEAN rc;
+ ULONG br;
+ UCHAR buf[20];
+#endif
+
+ if (!DmKdComEvent) {
+ //
+ // Not triggered, just return
+ //
+
+ return ;
+ }
+ DmKdComEvent = 0;
+
+ GetCommModemStatus (DmKdComPort, &status);
+#if 0
+ if (!(status & MS_RLSD_ON)) {
+ DEBUG_PRINT ("KD: No carrier detect - in terminal mode\n");
+
+ //
+ // Send any keystrokes to the ComPort
+ //
+
+ KdPollThreadMode = OUT_TERMINAL;
+
+ //
+ // Loop and read any com input
+ //
+
+ while (!(status & 0x80)) {
+ GetCommModemStatus (DmKdComPort, &status);
+ rc = DmKdReadComPort(buf, sizeof buf, &br);
+ if (rc != TRUE || br == 0)
+ continue;
+
+ DMPrintShellMsg( "%s", buf );
+
+ }
+
+ KdPollThreadMode = OUT_NORMAL;
+ DEBUG_PRINT ("KD: Carrier detect - returning to debugger\n");
+
+ ClearCommError (
+ DmKdComPort,
+ &CommErr,
+ &CommStat
+ );
+
+ } else {
+#endif
+
+ CommErr = 0;
+ ClearCommError (
+ DmKdComPort,
+ &CommErr,
+ &CommStat
+ );
+
+ if (CommErr) {
+ DEBUG_PRINT( "Comm Error: " );
+ }
+
+ if (CommErr & CE_OVERRUN) {
+ DEBUG_PRINT (" [overrun err] ");
+ }
+
+ if (CommErr & CE_RXOVER) {
+ DEBUG_PRINT (" [overflow err] ");
+ }
+
+ if (CommErr & CE_RXPARITY) {
+ DEBUG_PRINT (" [parify err] ");
+ }
+
+ if (CommErr & CE_BREAK) {
+ DEBUG_PRINT (" [break err] ");
+ }
+
+ if (CommErr & CE_FRAME) {
+ DEBUG_PRINT (" [frame err] ");
+ }
+
+ if (CommErr & CE_TXFULL) {
+ DEBUG_PRINT (" [txfull err] ");
+ }
+
+ if (CommErr) {
+ DEBUG_PRINT( "\n" );
+ }
+#if 0
+ }
+#endif
+
+
+ //
+ // Reset trigger
+ //
+
+ WaitCommEvent (DmKdComPort, &DmKdComEvent, &EventOverlapped);
+}