+++ /dev/null
-/*
- * PROJECT: ReactOS Drivers
- * LICENSE: BSD - See COPYING.ARM in the top level directory
- * FILE: drivers/sac/driver/conmgr.c
- * PURPOSE: Driver for the Server Administration Console (SAC) for EMS
- * PROGRAMMERS: ReactOS Portable Systems Group
- */
-
-/* INCLUDES *******************************************************************/
-
-#include "sacdrv.h"
-
-#include <initguid.h>
-
-/* GLOBALS ********************************************************************/
-
-DEFINE_GUID(PRIMARY_SAC_CHANNEL_APPLICATION_GUID,
- 0x63D02270,
- 0x8AA4,
- 0x11D5,
- 0xBC, 0xCF, 0x80, 0x6D, 0x61, 0x72, 0x69, 0x6F);
-
-LONG CurrentChannelRefCount;
-KMUTEX CurrentChannelLock;
-
-PSAC_CHANNEL CurrentChannel;
-PSAC_CHANNEL SacChannel;
-
-ULONG ExecutePostConsumerCommand;
-PSAC_CHANNEL ExecutePostConsumerCommandData;
-
-BOOLEAN InputInEscape, InputInEscTab, ConMgrLastCharWasCR;
-CHAR InputBuffer[80];
-
-BOOLEAN GlobalPagingNeeded, GlobalDoThreads;
-
-/* FUNCTIONS ******************************************************************/
-
-VOID
-NTAPI
-SacPutString(IN PWCHAR String)
-{
- NTSTATUS Status;
-
- /* Write the string on the main SAC channel */
- Status = ChannelOWrite(SacChannel,
- (PCHAR)String,
- wcslen(String) * sizeof(WCHAR));
- if (!NT_SUCCESS(Status))
- {
- SAC_DBG(SAC_DBG_INIT, "SAC XmlMgrSacPutString: OWrite failed\n");
- }
-}
-
-BOOLEAN
-NTAPI
-SacPutSimpleMessage(IN ULONG MessageIndex)
-{
- PWCHAR MessageBuffer;
- BOOLEAN Result;
-
- /* Get the message */
- MessageBuffer = GetMessage(MessageIndex);
- if (MessageBuffer)
- {
- /* Output it */
- SacPutString(MessageBuffer);
- Result = TRUE;
- }
- else
- {
- Result = FALSE;
- }
-
- /* All done */
- return Result;
-}
-
-NTSTATUS
-NTAPI
-ConMgrDisplayCurrentChannel(VOID)
-{
- NTSTATUS Status;
- BOOLEAN HasRedraw;
-
- /* Make sure the lock is held */
- SacAssertMutexLockHeld();
-
- /* Check if we can redraw */
- Status = ChannelHasRedrawEvent(CurrentChannel, &HasRedraw);
- if (NT_SUCCESS(Status))
- {
- /* Enable writes */
- _InterlockedExchange(&CurrentChannel->WriteEnabled, 1);
- if (HasRedraw)
- {
- /* If we can redraw, set the event */
- ChannelSetRedrawEvent(CurrentChannel);
- }
-
- /* Flush the output */
- Status = ChannelOFlush(CurrentChannel);
- }
-
- /* All done, return the status */
- return Status;
-}
-
-NTSTATUS
-NTAPI
-ConMgrWriteData(IN PSAC_CHANNEL Channel,
- IN PVOID Buffer,
- IN ULONG BufferLength)
-{
- ULONG i;
- NTSTATUS Status;
- LARGE_INTEGER Interval;
-
- /* Loop up to 32 times */
- for (i = 0; i < 32; i++)
- {
- /* Attempt sending the data */
- Status = HeadlessDispatch(HeadlessCmdPutData, Buffer, BufferLength, NULL, NULL);
- if (Status != STATUS_UNSUCCESSFUL) break;
-
- /* Sending the data on the port failed, wait a second... */
- Interval.HighPart = -1;
- Interval.LowPart = -100000;
- KeDelayExecutionThread(KernelMode, FALSE, &Interval);
- }
-
- /* After 32 attempts it should really have worked... */
- ASSERT(NT_SUCCESS(Status));
- return Status;
-}
-
-NTSTATUS
-NTAPI
-ConMgrFlushData(IN PSAC_CHANNEL Channel)
-{
- /* Nothing to do */
- return STATUS_SUCCESS;
-}
-
-BOOLEAN
-NTAPI
-ConMgrIsSacChannel(IN PSAC_CHANNEL Channel)
-{
- /* Check which channel is active */
- return Channel == SacChannel;
-}
-
-BOOLEAN
-NTAPI
-ConMgrIsWriteEnabled(IN PSAC_CHANNEL Channel)
-{
- /* If the current channel is active, allow writes */
- return ChannelIsEqual(Channel, &CurrentChannel->ChannelId);
-}
-
-NTSTATUS
-NTAPI
-ConMgrInitialize(VOID)
-{
- PWCHAR pcwch;
- PSAC_CHANNEL FoundChannel;
- SAC_CHANNEL_ATTRIBUTES SacChannelAttributes;
- NTSTATUS Status;
-
- /* Initialize the connection manager lock */
- SacInitializeMutexLock();
- SacAcquireMutexLock();
-
- /* Setup the attributes for the raw SAC channel */
- RtlZeroMemory(&SacChannelAttributes, sizeof(SacChannelAttributes));
- SacChannelAttributes.ChannelType = VtUtf8;
-
- /* Get the right name for it */
- pcwch = GetMessage(SAC_CHANNEL_NAME);
- ASSERT(pcwch);
- wcsncpy(SacChannelAttributes.NameBuffer, pcwch, SAC_CHANNEL_NAME_SIZE);
- SacChannelAttributes.NameBuffer[SAC_CHANNEL_NAME_SIZE] = ANSI_NULL;
-
- /* Get the right description for it */
- pcwch = GetMessage(SAC_CHANNEL_DESCRIPTION);
- ASSERT(pcwch);
- wcsncpy(SacChannelAttributes.DescriptionBuffer, pcwch, SAC_CHANNEL_DESCRIPTION_SIZE);
- SacChannelAttributes.DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE] = ANSI_NULL;
-
- /* Set all the right flags */
- SacChannelAttributes.Flag = SAC_CHANNEL_FLAG_APPLICATION | SAC_CHANNEL_FLAG_INTERNAL;
- SacChannelAttributes.CloseEvent = NULL;
- SacChannelAttributes.HasNewDataEvent = NULL;
- SacChannelAttributes.LockEvent = NULL;
- SacChannelAttributes.RedrawEvent = NULL;
- SacChannelAttributes.ChannelId = PRIMARY_SAC_CHANNEL_APPLICATION_GUID;
-
- /* Now create it */
- Status = ChanMgrCreateChannel(&SacChannel, &SacChannelAttributes);
- if (NT_SUCCESS(Status))
- {
- /* Try to get it back */
- Status = ChanMgrGetByHandle(SacChannel->ChannelId, &FoundChannel);
- if (NT_SUCCESS(Status))
- {
- /* Set it as the current and SAC channel */
- SacChannel = CurrentChannel = FoundChannel;
-
- /* Disable writes for now and clear the display */
- _InterlockedExchange(&FoundChannel->WriteEnabled, FALSE);
- Status = HeadlessDispatch(HeadlessCmdClearDisplay, NULL, 0, NULL, NULL);
- if (!NT_SUCCESS(Status))
- {
- SAC_DBG(SAC_DBG_INIT, "SAC ConMgrInitialize: Failed dispatch\n");
- }
-
- /* Display the initial prompt */
- SacPutSimpleMessage(SAC_NEWLINE);
- SacPutSimpleMessage(SAC_INIT_STATUS);
- SacPutSimpleMessage(SAC_NEWLINE);
- SacPutSimpleMessage(SAC_PROMPT);
-
- /* Display the current channel */
- ConMgrDisplayCurrentChannel();
- }
- }
-
- /* Release the channel lock */
- SacReleaseMutexLock();
- return STATUS_SUCCESS;
-}
-
-VOID
-NTAPI
-ConMgrEventMessage(IN PWCHAR EventMessage,
- IN BOOLEAN LockHeld)
-{
- /* Acquire the current channel lock if needed */
- if (!LockHeld) SacAcquireMutexLock();
-
- /* Send out the event message */
- SacPutSimpleMessage(2);
- SacPutString(EventMessage);
- SacPutSimpleMessage(3);
-
- /* Release the current channel lock if needed */
- if (!LockHeld) SacReleaseMutexLock();
-}
-
-BOOLEAN
-NTAPI
-ConMgrSimpleEventMessage(IN ULONG MessageIndex,
- IN BOOLEAN LockHeld)
-{
- PWCHAR MessageBuffer;
- BOOLEAN Result;
-
- /* Get the message to send out */
- MessageBuffer = GetMessage(MessageIndex);
- if (MessageBuffer)
- {
- /* Send it */
- ConMgrEventMessage(MessageBuffer, LockHeld);
- Result = TRUE;
- }
- else
- {
- /* It doesn't exist, fail */
- Result = FALSE;
- }
-
- /* Return if the message was sent or not */
- return Result;
-}
-
-NTSTATUS
-NTAPI
-ConMgrDisplayFastChannelSwitchingInterface(IN PSAC_CHANNEL Channel)
-{
- /* FIXME: TODO */
- ASSERT(FALSE);
- return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTAPI
-ConMgrSetCurrentChannel(IN PSAC_CHANNEL Channel)
-{
- NTSTATUS Status;
- BOOLEAN HasRedrawEvent;
-
- /* Make sure the lock is held */
- SacAssertMutexLockHeld();
-
- /* Check if we have a redraw event */
- Status = ChannelHasRedrawEvent(CurrentChannel, &HasRedrawEvent);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Clear it */
- if (HasRedrawEvent) ChannelClearRedrawEvent(CurrentChannel);
-
- /* Disable writes on the current channel */
- _InterlockedExchange(&CurrentChannel->WriteEnabled, 0);
-
- /* Release the current channel */
- Status = ChanMgrReleaseChannel(CurrentChannel);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Set the new channel and also disable writes on it */
- CurrentChannel = Channel;
- _InterlockedExchange(&Channel->WriteEnabled, 0);
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-ConMgrResetCurrentChannel(IN BOOLEAN KeepChannel)
-{
- NTSTATUS Status;
- PSAC_CHANNEL Channel;
-
- /* Make sure the lock is held */
- SacAssertMutexLockHeld();
-
- /* Get the current SAC channel */
- Status = ChanMgrGetByHandle(SacChannel->ChannelId, &Channel);
- if (NT_SUCCESS(Status))
- {
- /* Set this as the current SAC channel*/
- SacChannel = Channel;
- Status = ConMgrSetCurrentChannel(Channel);
- if (NT_SUCCESS(Status))
- {
- /* Check if the caller wants to switch or not */
- if (KeepChannel)
- {
- /* Nope, keep the same channel */
- Status = ConMgrDisplayCurrentChannel();
- }
- else
- {
- /* Yep, show the switching interface */
- Status = ConMgrDisplayFastChannelSwitchingInterface(CurrentChannel);
- }
- }
- }
-
- /* All done */
- return Status;
-}
-
-NTSTATUS
-NTAPI
-ConMgrChannelClose(IN PSAC_CHANNEL Channel)
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- /* Check if we're in the right channel */
- if (ConMgrIsWriteEnabled(Channel))
- {
- /* Yep, reset it */
- Status = ConMgrResetCurrentChannel(FALSE);
- ASSERT(NT_SUCCESS(Status));
- }
-
- /* All done */
- return Status;
-}
-
-NTSTATUS
-NTAPI
-ConMgrShutdown(VOID)
-{
- NTSTATUS Status;
-
- /* Check if we have a SAC channel */
- if (SacChannel)
- {
- /* Close it */
- Status = ChannelClose(SacChannel);
- if (!NT_SUCCESS(Status))
- {
- SAC_DBG(SAC_DBG_INIT, "SAC ConMgrShutdown: failed closing SAC channel.\n");
- }
-
- /* No longer have one */
- SacChannel = NULL;
- }
-
- /* Check if we have a current channel */
- if (CurrentChannel)
- {
- /* Release it */
- Status = ChanMgrReleaseChannel(CurrentChannel);
- if (!NT_SUCCESS(Status))
- {
- SAC_DBG(SAC_DBG_INIT, "SAC ConMgrShutdown: failed releasing current channel\n");
- }
-
- /* No longer have one */
- CurrentChannel = NULL;
- }
-
- /* All done */
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-ConMgrAdvanceCurrentChannel(VOID)
-{
- NTSTATUS Status;
- ULONG Index;
- PSAC_CHANNEL Channel;
-
- /* Should always be called with the lock held */
- SacAssertMutexLockHeld();
-
- /* Get the next active channel */
- Status = ChanMgrGetNextActiveChannel(CurrentChannel, &Index, &Channel);
- if (NT_SUCCESS(Status))
- {
- /* Set it as the new channel */
- Status = ConMgrSetCurrentChannel(Channel);
- if (NT_SUCCESS(Status))
- {
- /* Let the user switch to it */
- Status = ConMgrDisplayFastChannelSwitchingInterface(Channel);
- }
- }
-
- /* All done */
- return Status;
-}
-
-NTSTATUS
-NTAPI
-ConMgrChannelOWrite(IN PSAC_CHANNEL Channel,
- IN PVOID WriteBuffer)
-{
- NTSTATUS Status;
-
- /* Do the write with the lock held */
- SacAcquireMutexLock();
- ASSERT(FALSE);
- Status = STATUS_NOT_IMPLEMENTED;// ChannelOWrite(Channel, WriteBuffer + 24, *(WriteBuffer + 20));
- SacReleaseMutexLock();
-
- /* Return back to the caller */
- ASSERT(NT_SUCCESS(Status) || Status == STATUS_NOT_FOUND);
- return Status;
-}
-
-VOID
-NTAPI
-ConMgrProcessInputLine(VOID)
-{
- BOOLEAN EnablePaging;
- NTSTATUS Status;
-
- SAC_DBG(SAC_DBG_INIT, "SAC Input Test: %s\n", InputBuffer);
-
- if (!strncmp(InputBuffer, "t", 1))
- {
- DoTlistCommand();
- }
- else if (!strncmp(InputBuffer, "?", 1))
- {
- DoHelpCommand();
- }
- else if (!strncmp(InputBuffer, "help", 4))
- {
- DoHelpCommand();
- }
- else if (!strncmp(InputBuffer, "f", 1))
- {
- DoFullInfoCommand();
- }
- else if (!strncmp(InputBuffer, "p", 1))
- {
- DoPagingCommand();
- }
- else if (!strncmp(InputBuffer, "id", 2))
- {
- DoMachineInformationCommand();
- }
- else if (!strncmp(InputBuffer, "crashdump", 9))
- {
- DoCrashCommand();
- }
- else if (!strncmp(InputBuffer, "lock", 4))
- {
- DoLockCommand();
- }
- else if (!strncmp(InputBuffer, "shutdown", 8))
- {
- ExecutePostConsumerCommand = Shutdown;
- }
- else if (!strncmp(InputBuffer, "restart", 7))
- {
- ExecutePostConsumerCommand = Restart;
- }
- else if (!strncmp(InputBuffer, "d", 1))
- {
- EnablePaging = GlobalPagingNeeded;
- Status = HeadlessDispatch(HeadlessCmdDisplayLog,
- &EnablePaging,
- sizeof(EnablePaging),
- NULL,
- 0);
- if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "SAC Display Log failed.\n");
- }
- else if (!strncmp(InputBuffer, "cmd", 3))
- {
- if (CommandConsoleLaunchingEnabled)
- {
- DoCmdCommand(InputBuffer);
- }
- else
- {
- SacPutSimpleMessage(148);
- }
- }
- else if (!(strncmp(InputBuffer, "ch", 2)) &&
- (((strlen(InputBuffer) > 1) && (InputBuffer[2] == ' ')) ||
- (strlen(InputBuffer) == 2)))
- {
- DoChannelCommand(InputBuffer);
- }
- else if (!(strncmp(InputBuffer, "k", 1)) &&
- (((strlen(InputBuffer) > 1) && (InputBuffer[1] == ' ')) ||
- (strlen(InputBuffer) == 1)))
- {
- DoKillCommand(InputBuffer);
- }
- else if (!(strncmp(InputBuffer, "l", 1)) &&
- (((strlen(InputBuffer) > 1) && (InputBuffer[1] == ' ')) ||
- (strlen(InputBuffer) == 1)))
- {
- DoLowerPriorityCommand(InputBuffer);
- }
- else if (!(strncmp(InputBuffer, "r", 1)) &&
- (((strlen(InputBuffer) > 1) && (InputBuffer[1] == ' ')) ||
- (strlen(InputBuffer) == 1)))
- {
- DoRaisePriorityCommand(InputBuffer);
- }
- else if (!(strncmp(InputBuffer, "m", 1)) &&
- (((strlen(InputBuffer) > 1) && (InputBuffer[1] == ' ')) ||
- (strlen(InputBuffer) == 1)))
- {
- DoLimitMemoryCommand(InputBuffer);
- }
- else if (!(strncmp(InputBuffer, "s", 1)) &&
- (((strlen(InputBuffer) > 1) && (InputBuffer[1] == ' ')) ||
- (strlen(InputBuffer) == 1)))
- {
- DoSetTimeCommand(InputBuffer);
- }
- else if (!(strncmp(InputBuffer, "i", 1)) &&
- (((strlen(InputBuffer) > 1) && (InputBuffer[1] == ' ')) ||
- (strlen(InputBuffer) == 1)))
- {
- DoSetIpAddressCommand(InputBuffer);
- }
- else if ((InputBuffer[0] != '\n') && (InputBuffer[0] != ANSI_NULL))
- {
- SacPutSimpleMessage(SAC_UNKNOWN_COMMAND);
- }
-}
-
-VOID
-NTAPI
-ConMgrSerialPortConsumer(VOID)
-{
- NTSTATUS Status;
- CHAR Char;
- WCHAR LastChar;
- CHAR ReadBuffer[2];
- ULONG ReadBufferSize, i;
- WCHAR StringBuffer[2];
- SAC_DBG(SAC_DBG_MACHINE, "SAC TimerDpcRoutine: Entering.\n"); //bug
-
- /* Acquire the manager lock and make sure a channel is selected */
- SacAcquireMutexLock();
- ASSERT(CurrentChannel);
-
- /* Read whatever came off the serial port */
- for (Status = SerialBufferGetChar(&Char);
- NT_SUCCESS(Status);
- Status = SerialBufferGetChar(&Char))
- {
- /* If nothing came through, bail out */
- if (Status == STATUS_NO_DATA_DETECTED) break;
-
- /* Check if ESC was pressed */
- if (Char == '\x1B')
- {
- /* Was it already pressed? */
- if (!InputInEscape)
- {
- /* First time ESC is pressed! Remember and reset TAB state */
- InputInEscTab = FALSE;
- InputInEscape = TRUE;
- continue;
- }
- }
- else if (Char == '\t')
- {
- /* TAB was pressed, is it following ESC (VT-100 sequence)? */
- if (InputInEscape)
- {
- /* Yes! This must be the only ESC-TAB we see in once moment */
- ASSERT(InputInEscTab == FALSE);
-
- /* No longer treat us as being in ESC */
- InputInEscape = FALSE;
-
- /* ESC-TAB is the sequence for changing channels */
- Status = ConMgrAdvanceCurrentChannel();
- if (!NT_SUCCESS(Status)) break;
-
- /* Remember ESC-TAB was pressed */
- InputInEscTab = TRUE;
- continue;
- }
- }
- else if ((Char == '0') && (InputInEscTab))
- {
- /* It this ESC-TAB-0? */
- ASSERT(InputInEscape == FALSE);
- InputInEscTab = FALSE;
-
- /* If writes are already enabled, don't do this */
- if (!CurrentChannel->WriteEnabled)
- {
- /* Reset the channel, this is our special sequence */
- Status = ConMgrResetCurrentChannel(FALSE);
- if (!NT_SUCCESS(Status)) break;
- }
-
- continue;
- }
- else
- {
- /* This is ESC-TAB-something else */
- InputInEscTab = FALSE;
-
- /* If writes are already enabled, don't do this */
- if (!CurrentChannel->WriteEnabled)
- {
- /* Display the current channel */
- InputInEscape = FALSE;
- Status = ConMgrDisplayCurrentChannel();
- if (!NT_SUCCESS(Status)) break;
- continue;
- }
- }
-
- /* Check if an ESC-sequence was being typed into a command channel */
- if ((InputInEscape) && (CurrentChannel != SacChannel))
- {
- /* Store the ESC in the current channel buffer */
- ReadBuffer[0] = '\x1B';
- ChannelIWrite(CurrentChannel, ReadBuffer, sizeof(CHAR));
- }
-
- /* Check if we are no longer pressing ESC and exit the mode if so */
- if (Char != '\x1B') InputInEscape = FALSE;
-
- /* Whatever was typed in, save it int eh current channel */
- ChannelIWrite(CurrentChannel, &Char, sizeof(Char));
-
- /* If this is a command channel, we're done, nothing to process */
- if (CurrentChannel != SacChannel) continue;
-
- /* Check for line feed right after a carriage return */
- if ((ConMgrLastCharWasCR) && (Char == '\n'))
- {
- /* Ignore the line feed, but clear the carriage return */
- ChannelIReadLast(CurrentChannel);
- ConMgrLastCharWasCR = 0;
- continue;
- }
-
- /* Check if the user did a carriage return */
- ConMgrLastCharWasCR = (Char == '\n');
-
- /* If the user did an "ENTER", we need to run the command */
- if ((Char == '\n') || (Char == '\r'))
- {
- /* Echo back to the terminal */
- SacPutString(L"\r\n");
-
-DoLineParsing:
- /* Inhibit the character (either CR or LF) */
- ChannelIReadLast(CurrentChannel);
-
- /* NULL-terminate the channel's input buffer */
- ReadBuffer[0] = ANSI_NULL;
- ChannelIWrite(CurrentChannel, ReadBuffer, sizeof(CHAR));
-
- /* Loop over every last character */
- do
- {
- /* Read every character in the channel, and strip whitespace */
- LastChar = ChannelIReadLast(CurrentChannel);
- ReadBuffer[0] = (CHAR) LastChar;
- } while ((!(LastChar) ||
- (LastChar == L' ') ||
- (LastChar == L'\t')) &&
- (ChannelIBufferLength(CurrentChannel)));
-
- /* Write back into the channel the last character */
- ChannelIWrite(CurrentChannel, ReadBuffer, sizeof(CHAR));
-
- /* NULL-terminate the input buffer */
- ReadBuffer[0] = ANSI_NULL;
- ChannelIWrite(CurrentChannel, ReadBuffer, sizeof(CHAR));
-
- /* Now loop over every first character */
- do
- {
- /* Read every character in the channel, and strip whitespace */
- ChannelIRead(CurrentChannel,
- ReadBuffer,
- sizeof(ReadBuffer),
- &ReadBufferSize);
- } while ((ReadBufferSize) &&
- ((ReadBuffer[0] == ' ') || (ReadBuffer[0] == '\t')));
-
- /* We read one more than we should, so treat that as our first one */
- InputBuffer[0] = ReadBuffer[0];
- i = 1;
-
- /* And now loop reading all the others */
- do
- {
- /* Read each character -- there should be max 80 */
- ChannelIRead(CurrentChannel,
- ReadBuffer,
- sizeof(ReadBuffer),
- &ReadBufferSize);
- ASSERT(i < SAC_VTUTF8_COL_WIDTH);
- InputBuffer[i++] = ReadBuffer[0];
- } while (ReadBufferSize);
-
- /* Now go over the entire input stream */
- for (i = 0; InputBuffer[i]; i++)
- {
- /* Again it should be less than 80 characters */
- ASSERT(i < SAC_VTUTF8_COL_WIDTH);
-
- /* And downbase each character */
- Char = InputBuffer[i];
- if ((Char >= 'A') && (Char <= 'Z')) InputBuffer[i] = Char + ' ';
- }
-
- /* Ok, at this point, no pending command should exist */
- ASSERT(ExecutePostConsumerCommand == Nothing);
-
- /* Go and process the input, then show the prompt again */
- ConMgrProcessInputLine();
- SacPutSimpleMessage(SAC_PROMPT);
-
- /* If the user typed a valid command, get out of here */
- if (ExecutePostConsumerCommand != Nothing) break;
-
- /* Keep going */
- continue;
- }
-
- /* Check if the user typed backspace or delete */
- if ((Char == '\b') || (Char == '\x7F'))
- {
- /* Omit the last character, which should be the DEL/BS itself */
- if (ChannelIBufferLength(CurrentChannel))
- {
- ChannelIReadLast(CurrentChannel);
- }
-
- /* Omit the before-last character, which is the one to delete */
- if (ChannelIBufferLength(CurrentChannel))
- {
- /* Also send two backspaces back to the console */
- SacPutString(L"\b \b");
- ChannelIReadLast(CurrentChannel);
- }
-
- /* Keep going */
- continue;
- }
-
- /* If the user pressed CTRL-C at this point, treat it like ENTER */
- if (Char == '\x03') goto DoLineParsing;
-
- /* Check if the user pressed TAB */
- if (Char == '\t')
- {
- /* Omit it, send a BELL, and keep going. We ignore TABs */
- ChannelIReadLast(CurrentChannel);
- SacPutString(L"\a");
- continue;
- }
-
- /* Check if the user is getting close to the end of the screen */
- if (ChannelIBufferLength(CurrentChannel) == (SAC_VTUTF8_COL_WIDTH - 2))
- {
- /* Delete the last character, replacing it with this one instead */
- swprintf(StringBuffer, L"\b%c", Char);
- SacPutString(StringBuffer);
-
- /* Omit the last two characters from the buffer */
- ChannelIReadLast(CurrentChannel);
- ChannelIReadLast(CurrentChannel);
-
- /* Write the last character that was just typed in */
- ReadBuffer[0] = Char;
- ChannelIWrite(CurrentChannel, ReadBuffer, sizeof(CHAR));
- continue;
- }
-
- /* Nothing of interest happened, just write the character back */
- swprintf(StringBuffer, L"%c", Char);
- SacPutString(StringBuffer);
- }
-
- /* We're done, release the lock */
- SacReleaseMutexLock();
- SAC_DBG(SAC_DBG_MACHINE, "SAC TimerDpcRoutine: Exiting.\n"); //bug
-}
-
-VOID
-NTAPI
-ConMgrWorkerProcessEvents(IN PSAC_DEVICE_EXTENSION DeviceExtension)
-{
- SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC WorkerProcessEvents: Entering.\n");
-
- /* Enter the main loop */
- while (TRUE)
- {
- /* Wait for something to do */
- KeWaitForSingleObject(&DeviceExtension->Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- /* Consume data off the serial port */
- ConMgrSerialPortConsumer();
- switch (ExecutePostConsumerCommand)
- {
- case Restart:
- /* A reboot was sent, do it */
- DoRebootCommand(FALSE);
- break;
-
- case Close:
- /* A close was sent, do it */
- ChanMgrCloseChannel(ExecutePostConsumerCommandData);
- ChanMgrReleaseChannel(ExecutePostConsumerCommandData);
- break;
-
- case Shutdown:
- /* A shutdown was sent, do it */
- DoRebootCommand(TRUE);
- break;
- }
-
- /* Clear the serial port consumer state */
- ExecutePostConsumerCommand = Nothing;
- ExecutePostConsumerCommandData = NULL;
- }
-}
-
-NTSTATUS
-NTAPI
-ConMgrGetChannelCloseMessage(IN PSAC_CHANNEL Channel,
- IN NTSTATUS CloseStatus,
- OUT PWCHAR OutputBuffer)
-{
- ASSERT(FALSE);
- return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTAPI
-ConMgrHandleEvent(IN ULONG EventCode,
- IN PSAC_CHANNEL Channel,
- OUT PVOID Data)
-{
- ASSERT(FALSE);
- return STATUS_NOT_IMPLEMENTED;
-}