X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=drivers%2Fsac%2Fdriver%2Fconmgr.c;h=fda85472bc5f0993c94e4c2a8b04e50ba58648a9;hp=b012cad03f70316bd8e8e98d4eda14bb6654189c;hb=8e37700e5c527418228fa2269adc06c7ebcebcb9;hpb=23fbc3204c2fea26c52b8116bf0fe4842feba0dd diff --git a/drivers/sac/driver/conmgr.c b/drivers/sac/driver/conmgr.c index b012cad03f7..fda85472bc5 100644 --- a/drivers/sac/driver/conmgr.c +++ b/drivers/sac/driver/conmgr.c @@ -27,76 +27,10 @@ PSAC_CHANNEL SacChannel; ULONG ExecutePostConsumerCommand; PSAC_CHANNEL ExecutePostConsumerCommandData; -/* FUNCTIONS *****************************************************************/ - -VOID -NTAPI -ConMgrSerialPortConsumer(VOID) -{ - NTSTATUS Status; - CHAR Char; - SAC_DBG(0x2000, "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; - } +BOOLEAN InputInEscape, InputInEscTab, ConMgrLastCharWasCR; +CHAR InputBuffer[80]; - /* We're done, release the lock */ - SacReleaseMutexLock(); - SAC_DBG(0x2000, "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 1: - /* A reboot was sent, do it */ - DoRebootCommand(FALSE); - break; - - case 2: - /* A close was sent, do it */ - ChanMgrCloseChannel(ExecutePostConsumerCommandData); - ChanMgrReleaseChannel(ExecutePostConsumerCommandData); - break; - - case 3: - /* A shutdown was sent, do it */ - DoRebootCommand(TRUE); - break; - } - - /* Clear the serial port consumer state */ - ExecutePostConsumerCommand = 0; - ExecutePostConsumerCommandData = NULL; - } -} +/* FUNCTIONS *****************************************************************/ VOID NTAPI @@ -235,7 +169,7 @@ ConMgrInitialize(VOID) /* Setup the attributes for the raw SAC channel */ RtlZeroMemory(&SacChannelAttributes, sizeof(SacChannelAttributes)); - SacChannelAttributes.ChannelType = Raw; + SacChannelAttributes.ChannelType = Raw; /* FIXME: Should be VtUtf8 */ /* Get the right name for it */ pcwch = GetMessage(SAC_CHANNEL_NAME); @@ -504,6 +438,7 @@ ConMgrChannelOWrite(IN PSAC_CHANNEL Channel, /* Do the write with the lock held */ SacAcquireMutexLock(); + ASSERT(FALSE); Status = STATUS_NOT_IMPLEMENTED;// ChannelOWrite(Channel, WriteBuffer + 24, *(WriteBuffer + 20)); SacReleaseMutexLock(); @@ -512,21 +447,441 @@ ConMgrChannelOWrite(IN PSAC_CHANNEL Channel, return Status; } -NTSTATUS +#define Shutdown 1 +#define Restart 3 +#define Nothing 0 +BOOLEAN GlobalPagingNeeded; + +VOID NTAPI -ConMgrGetChannelCloseMessage(IN PSAC_CHANNEL Channel, - IN NTSTATUS CloseStatus, - OUT PWCHAR OutputBuffer) +ConMgrProcessInputLine(VOID) { - ASSERT(FALSE); - return STATUS_NOT_IMPLEMENTED; + BOOLEAN EnablePaging; + NTSTATUS Status; + + SAC_DBG(4, "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(4, "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(105); + } } VOID NTAPI -ConMgrProcessInputLine(VOID) +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(CHAR), /* FIXME: Should be 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(CHAR), /* FIXME: Should be 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 1: + /* A reboot was sent, do it */ + DoRebootCommand(FALSE); + break; + + case 2: + /* A close was sent, do it */ + ChanMgrCloseChannel(ExecutePostConsumerCommandData); + ChanMgrReleaseChannel(ExecutePostConsumerCommandData); + break; + + case 3: + /* A shutdown was sent, do it */ + DoRebootCommand(TRUE); + break; + } + + /* Clear the serial port consumer state */ + ExecutePostConsumerCommand = 0; + ExecutePostConsumerCommandData = NULL; + } +} + +NTSTATUS +NTAPI +ConMgrGetChannelCloseMessage(IN PSAC_CHANNEL Channel, + IN NTSTATUS CloseStatus, + OUT PWCHAR OutputBuffer) { ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; } NTSTATUS