Author: ion Date: Mon Aug 19 03:32:39 2013 New Revision: 59778
URL: http://svn.reactos.org/svn/reactos?rev=59778&view=rev Log: [SACDRV]: IReadLast returns WCHAR, not CHAR. [SACDRV]: Implement VtUtf8 case in ChannelInitializeVTable. [SACDRV]: Implement DoHelpCommand, reformat concmd.c to standards. [SACDRV]: ConMgrInitialize shoudl setup the SAC channel as VtUtf8, not Raw. I guess it was set to Raw since VtUtf8 wasn't yet implemented, however this breaks the command parsing since it expects WCHAR's. Make a note of this, and temporarily hack ConMgrSerialPortConsumer to work with CHAR's from a Raw channel. [SACDRV]: Implement ConMgrProcessInputLine, which calls out the appopriate helpers. [SACDRV]: Fixes to parsing in ConMgrSerialPortConsumer [SACDRV]: Document, reformat, and fix some of the bugs in the RawChannelI* commands. [SACDRV]: Implement simple (ANSI) case of SacTranslateUtf8ToUnicode. [SACDRV]: Implement SacFormatMessage and GetMessageLineCount. [SACDRV]: Start implementing VT-UTF8 support. Input routines are done, output routines are still WIP. [SACMSG]: Fix the messages in the .MC file. Stuff is now being output correctly. If using Putty, make sure to turn on "Implicit CR in every LF" in Settings->Terminal.
Modified: trunk/reactos/drivers/sac/driver/chanmgr.c trunk/reactos/drivers/sac/driver/channel.c trunk/reactos/drivers/sac/driver/concmd.c trunk/reactos/drivers/sac/driver/conmgr.c trunk/reactos/drivers/sac/driver/rawchan.c trunk/reactos/drivers/sac/driver/sacdrv.h trunk/reactos/drivers/sac/driver/util.c trunk/reactos/drivers/sac/driver/vtutf8chan.c trunk/reactos/include/reactos/mc/sacmsg.mc
Modified: trunk/reactos/drivers/sac/driver/chanmgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/chanmgr.... ============================================================================== --- trunk/reactos/drivers/sac/driver/chanmgr.c [iso-8859-1] (original) +++ trunk/reactos/drivers/sac/driver/chanmgr.c [iso-8859-1] Mon Aug 19 03:32:39 2013 @@ -404,7 +404,6 @@ if (i == SAC_MAX_CHANNELS) { /* Bail out */ - SAC_DBG(SAC_DBG_INIT, "failing here: %d %lx\n", __LINE__, Status); goto ReturnStatus; }
@@ -438,7 +437,6 @@ else { /* We couldn't create it, free the buffer */ - SAC_DBG(SAC_DBG_INIT, "failing here: %d %lx\n", __LINE__, Status); SacFreePool(NewChannel); }
Modified: trunk/reactos/drivers/sac/driver/channel.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/channel.... ============================================================================== --- trunk/reactos/drivers/sac/driver/channel.c [iso-8859-1] (original) +++ trunk/reactos/drivers/sac/driver/channel.c [iso-8859-1] Mon Aug 19 03:32:39 2013 @@ -147,11 +147,11 @@ return Status; }
-UCHAR +WCHAR NTAPI ChannelIReadLast(IN PSAC_CHANNEL Channel) { - UCHAR LastChar; + WCHAR LastChar;
/* Read the last character while holding the lock */ ChannelLockIBuffer(Channel); @@ -410,9 +410,19 @@ switch (Channel->ChannelType) { case VtUtf8: - /* FIXME: TODO */ - ASSERT(FALSE); - return STATUS_NOT_IMPLEMENTED; + /* Setup the calls for a VT-UTF8 channel */ + Channel->ChannelCreate = VTUTF8ChannelCreate; + Channel->ChannelDestroy = VTUTF8ChannelDestroy; + Channel->ChannelOutputFlush = VTUTF8ChannelOFlush; + Channel->ChannelOutputEcho = VTUTF8ChannelOEcho; + Channel->ChannelOutputWrite = VTUTF8ChannelOWrite; + Channel->ChannelOutputRead = VTUTF8ChannelORead; + Channel->ChannelInputWrite = VTUTF8ChannelIWrite; + Channel->ChannelInputRead = VTUTF8ChannelIRead; + Channel->ChannelInputReadLast = VTUTF8ChannelIReadLast; + Channel->ChannelInputBufferIsFull = VTUTF8ChannelIBufferIsFull; + Channel->ChannelInputBufferLength = VTUTF8ChannelIBufferLength; + break;
case Cmd: /* FIXME: TODO */
Modified: trunk/reactos/drivers/sac/driver/concmd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/concmd.c... ============================================================================== --- trunk/reactos/drivers/sac/driver/concmd.c [iso-8859-1] (original) +++ trunk/reactos/drivers/sac/driver/concmd.c [iso-8859-1] Mon Aug 19 03:32:39 2013 @@ -16,6 +16,98 @@ ULONG GlobalBufferSize;
/* FUNCTIONS *****************************************************************/ + +NTSTATUS +DoChannelListCommand( + VOID + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +DoChannelCloseByNameCommand( + IN PCHAR Count + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +DoChannelCloseByIndexCommand( + IN ULONG ChannelIndex + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +DoChannelSwitchByNameCommand( + IN PCHAR Count + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +DoChannelSwitchByIndexCommand( + IN ULONG ChannelIndex + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +GetTListInfo( + IN PVOID TListData, + IN ULONG InputSize, + IN ULONG TotalSize + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +VOID +PrintTListInfo( + IN PVOID TListData + ) +{ + +} + +VOID +PutMore( + OUT PBOOLEAN ScreenFull + ) +{ + +} + +BOOLEAN +RetrieveIpAddressFromString( + IN PWCHAR IpString, + OUT PULONG IpAddress + ) +{ + return FALSE; +} + +NTSTATUS +CallQueryIPIOCTL( + IN HANDLE DriverHandle, + IN PVOID DriverObject, + IN HANDLE WaitEvent, + IN PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID InputBuffer, + IN ULONG InputBufferLength, + IN PVOID OutputBuffer, + IN ULONG OutputBufferLength, + IN BOOLEAN PrintMessage, + OUT PBOOLEAN MessagePrinted + ) +{ + return STATUS_NOT_IMPLEMENTED; +}
VOID NTAPI @@ -71,222 +163,148 @@ SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoRebootCommand: Exiting.\n"); }
-NTSTATUS -GetTListInfo( - IN PVOID TListData, - IN ULONG InputSize, - IN ULONG TotalSize - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -VOID -PrintTListInfo( - IN PVOID TListData - ) -{ - -} - -VOID -PutMore( - OUT PBOOLEAN ScreenFull - ) -{ - -} - -BOOLEAN -RetrieveIpAddressFromString( - IN PWCHAR IpString, - OUT PULONG IpAddress - ) -{ - return FALSE; -} - -NTSTATUS -CallQueryIPIOCTL( - IN HANDLE DriverHandle, - IN PVOID DriverObject, - IN HANDLE WaitEvent, - IN PIO_STATUS_BLOCK IoStatusBlock, - IN PVOID InputBuffer, - IN ULONG InputBufferLength, - IN PVOID OutputBuffer, - IN ULONG OutputBufferLength, - IN BOOLEAN PrintMessage, - OUT PBOOLEAN MessagePrinted - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -VOID -DoFullInfoCommand( - VOID - ) -{ - -} - -VOID -DoPagingCommand( - VOID - ) -{ - -} - -VOID -DoSetTimeCommand( - IN PCHAR InputTime - ) -{ - -} - -VOID -DoKillCommand( - IN PCHAR KillString - ) -{ - -} - -VOID -DoLowerPriorityCommand( - IN PCHAR PrioString - ) -{ - -} - -VOID -DoRaisePriorityCommand( - IN PCHAR PrioString - ) -{ - -} - -VOID -DoLimitMemoryCommand( - IN PCHAR LimitString - ) -{ - -} - -VOID -DoCrashCommand( - VOID - ) -{ - -} - -VOID -DoMachineInformationCommand( - VOID - ) -{ - -} - -NTSTATUS -DoChannelListCommand( - VOID - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -DoChannelCloseByNameCommand( - IN PCHAR Count - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -DoChannelCloseByIndexCommand( - IN ULONG ChannelIndex - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -DoChannelSwitchByNameCommand( - IN PCHAR Count - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -DoChannelSwitchByIndexCommand( - IN ULONG ChannelIndex - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -VOID -DoChannelCommand( - IN PCHAR ChannelString - ) -{ - -} - -VOID -DoCmdCommand( - VOID - ) -{ - -} - -VOID -DoLockCommand( - VOID - ) -{ - -} - -VOID -DoHelpCommand( - VOID - ) -{ - -} - -VOID -DoGetNetInfo( - IN BOOLEAN DoPrint - ) -{ - -} - -VOID -DoSetIpAddressCommand( - IN PCHAR IpString - ) -{ - -} - -VOID -DoTlistCommand( - VOID - ) -{ - -} +VOID +NTAPI +DoFullInfoCommand(VOID) +{ + +} + +VOID +NTAPI +DoPagingCommand(VOID) +{ + +} + +VOID +NTAPI +DoSetTimeCommand(IN PCHAR InputTime) +{ + +} + +VOID +NTAPI +DoKillCommand(IN PCHAR KillString) +{ + +} + +VOID +NTAPI +DoLowerPriorityCommand(IN PCHAR PrioString) +{ + +} + +VOID +NTAPI +DoRaisePriorityCommand(IN PCHAR PrioString) +{ + +} + +VOID +NTAPI +DoLimitMemoryCommand(IN PCHAR LimitString) +{ + +} + +VOID +NTAPI +DoCrashCommand(VOID) +{ + +} + +VOID +NTAPI +DoMachineInformationCommand(VOID) +{ + +} + +VOID +NTAPI +DoChannelCommand(IN PCHAR ChannelString) +{ + +} + +VOID +NTAPI +DoCmdCommand(IN PCHAR InputString) +{ + +} + +VOID +NTAPI +DoLockCommand(VOID) +{ + +} + +#define PRINT_HELP_MESSAGE(x) \ +{ \ + Count += NewCount; \ + NewCount = GetMessageLineCount(x); \ + if ( (NewCount + Count) > SAC_VTUTF8_COL_HEIGHT) \ + { \ + PutMore(&ScreenFull); \ + if (ScreenFull) return; \ + Count = 0; \ + } \ + SacPutSimpleMessage(x); \ +} + +VOID +NTAPI +DoHelpCommand(VOID) +{ + ULONG NewCount = 0, Count = 0; + BOOLEAN ScreenFull = FALSE; + + PRINT_HELP_MESSAGE(112); + PRINT_HELP_MESSAGE(12); + PRINT_HELP_MESSAGE(13); + PRINT_HELP_MESSAGE(14); + PRINT_HELP_MESSAGE(15); + PRINT_HELP_MESSAGE(16); + PRINT_HELP_MESSAGE(31); + PRINT_HELP_MESSAGE(18); + PRINT_HELP_MESSAGE(19); + PRINT_HELP_MESSAGE(32); + PRINT_HELP_MESSAGE(20); + PRINT_HELP_MESSAGE(21); + PRINT_HELP_MESSAGE(22); + PRINT_HELP_MESSAGE(23); + PRINT_HELP_MESSAGE(24); + PRINT_HELP_MESSAGE(25); + PRINT_HELP_MESSAGE(27); + PRINT_HELP_MESSAGE(28); + PRINT_HELP_MESSAGE(29); +} + +VOID +NTAPI +DoGetNetInfo(IN BOOLEAN DoPrint) +{ + +} + +VOID +NTAPI +DoSetIpAddressCommand(IN PCHAR IpString) +{ + +} + +VOID +NTAPI +DoTlistCommand(VOID) +{ + +}
Modified: trunk/reactos/drivers/sac/driver/conmgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/conmgr.c... ============================================================================== --- trunk/reactos/drivers/sac/driver/conmgr.c [iso-8859-1] (original) +++ trunk/reactos/drivers/sac/driver/conmgr.c [iso-8859-1] Mon Aug 19 03:32:39 2013 @@ -169,7 +169,7 @@
/* 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); @@ -438,6 +438,7 @@
/* Do the write with the lock held */ SacAcquireMutexLock(); + ASSERT(FALSE); Status = STATUS_NOT_IMPLEMENTED;// ChannelOWrite(Channel, WriteBuffer + 24, *(WriteBuffer + 20)); SacReleaseMutexLock();
@@ -446,22 +447,137 @@ return Status; }
+#define Shutdown 1 +#define Restart 3 +#define Nothing 0 +BOOLEAN GlobalPagingNeeded; + VOID NTAPI ConMgrProcessInputLine(VOID) { - ASSERT(FALSE); -} - -#define Nothing 0 + 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 ConMgrSerialPortConsumer(VOID) { NTSTATUS Status; - CHAR Char, LastChar; - CHAR WriteBuffer[2], ReadBuffer[2]; + CHAR Char; + WCHAR LastChar; + CHAR ReadBuffer[2]; ULONG ReadBufferSize, i; WCHAR StringBuffer[2]; SAC_DBG(SAC_DBG_MACHINE, "SAC TimerDpcRoutine: Entering.\n"); //bug @@ -546,8 +662,8 @@ if ((InputInEscape) && (CurrentChannel != SacChannel)) { /* Store the ESC in the current channel buffer */ - WriteBuffer[0] = '\x1B'; - ChannelIWrite(CurrentChannel, WriteBuffer, sizeof(CHAR)); + ReadBuffer[0] = '\x1B'; + ChannelIWrite(CurrentChannel, ReadBuffer, sizeof(CHAR)); }
/* Check if we are no longer pressing ESC and exit the mode if so */ @@ -582,26 +698,26 @@ ChannelIReadLast(CurrentChannel);
/* NULL-terminate the channel's input buffer */ - WriteBuffer[0] = ANSI_NULL; - ChannelIWrite(CurrentChannel, WriteBuffer, sizeof(CHAR)); + 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); - WriteBuffer[0] = LastChar; + ReadBuffer[0] = (CHAR) LastChar; } while ((!(LastChar) || - (LastChar == ' ') || - (LastChar == '\t')) && + (LastChar == L' ') || + (LastChar == L'\t')) && (ChannelIBufferLength(CurrentChannel)));
/* Write back into the channel the last character */ - ChannelIWrite(CurrentChannel, WriteBuffer, sizeof(CHAR)); + ChannelIWrite(CurrentChannel, ReadBuffer, sizeof(CHAR));
/* NULL-terminate the input buffer */ - WriteBuffer[0] = ANSI_NULL; - ChannelIWrite(CurrentChannel, WriteBuffer, sizeof(WCHAR)); + ReadBuffer[0] = ANSI_NULL; + ChannelIWrite(CurrentChannel, ReadBuffer, sizeof(CHAR));
/* Now loop over every first character */ do @@ -609,11 +725,10 @@ /* Read every character in the channel, and strip whitespace */ ChannelIRead(CurrentChannel, ReadBuffer, - sizeof(ReadBuffer), + sizeof(CHAR), /* FIXME: Should be sizeof(ReadBuffer) */ &ReadBufferSize); - WriteBuffer[0] = ReadBuffer[0]; } while ((ReadBufferSize) && - ((ReadBuffer[0] != ' ') || (ReadBuffer[0] != '\t'))); + ((ReadBuffer[0] == ' ') || (ReadBuffer[0] == '\t')));
/* We read one more than we should, so treat that as our first one */ InputBuffer[0] = ReadBuffer[0]; @@ -625,7 +740,7 @@ /* Read each character -- there should be max 80 */ ChannelIRead(CurrentChannel, ReadBuffer, - sizeof(ReadBuffer), + sizeof(CHAR), /* FIXME: Should be sizeof(ReadBuffer) */ &ReadBufferSize); ASSERT(i < SAC_VTUTF8_COL_WIDTH); InputBuffer[i++] = ReadBuffer[0]; @@ -637,7 +752,7 @@ /* Again it should be less than 80 characters */ ASSERT(i < SAC_VTUTF8_COL_WIDTH);
- /* And upcase each character */ + /* And downbase each character */ Char = InputBuffer[i]; if ((Char >= 'A') && (Char <= 'Z')) InputBuffer[i] = Char + ' '; } @@ -700,9 +815,9 @@ ChannelIReadLast(CurrentChannel); ChannelIReadLast(CurrentChannel);
- /* NULL-terminate it */ - WriteBuffer[0] = Char; - ChannelIWrite(CurrentChannel, WriteBuffer, sizeof(CHAR)); + /* Write the last character that was just typed in */ + ReadBuffer[0] = Char; + ChannelIWrite(CurrentChannel, ReadBuffer, sizeof(CHAR)); continue; }
Modified: trunk/reactos/drivers/sac/driver/rawchan.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/rawchan.... ============================================================================== --- trunk/reactos/drivers/sac/driver/rawchan.c [iso-8859-1] (original) +++ trunk/reactos/drivers/sac/driver/rawchan.c [iso-8859-1] Mon Aug 19 03:32:39 2013 @@ -23,17 +23,19 @@ { CHECK_PARAMETER(Channel);
+ /* Allocate the output buffer */ Channel->OBuffer = SacAllocatePool(SAC_RAW_OBUFFER_SIZE, GLOBAL_BLOCK_TAG); CHECK_ALLOCATION(Channel->OBuffer);
+ /* Allocate the input buffer */ Channel->IBuffer = SacAllocatePool(SAC_RAW_IBUFFER_SIZE, GLOBAL_BLOCK_TAG); CHECK_ALLOCATION(Channel->IBuffer);
+ /* Reset all flags and return success */ Channel->OBufferIndex = 0; Channel->OBufferFirstGoodIndex = 0; Channel->ChannelHasNewIBufferData = FALSE; Channel->ChannelHasNewOBufferData = FALSE; - return STATUS_SUCCESS; }
@@ -43,16 +45,9 @@ { CHECK_PARAMETER(Channel);
- if (Channel->OBuffer) - { - SacFreePool(Channel->OBuffer); - } - - if (Channel->IBuffer) - { - SacFreePool(Channel->IBuffer); - } - + /* Free the buffer and then destroy the channel */ + if (Channel->OBuffer) SacFreePool(Channel->OBuffer); + if (Channel->IBuffer) SacFreePool(Channel->IBuffer); return ChannelDestroy(Channel); }
@@ -61,13 +56,6 @@ ChannelHasNewOBufferData(IN PSAC_CHANNEL Channel) { return Channel->ChannelHasNewOBufferData; -} - -FORCEINLINE -BOOLEAN -ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel) -{ - return Channel->ChannelHasNewIBufferData; }
NTSTATUS @@ -207,6 +195,23 @@ return ConMgrFlushData(Channel); }
+NTSTATUS +NTAPI +RawChannelOWrite(IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length) +{ + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(String); + + if ((ConMgrIsWriteEnabled(Channel)) && (Channel->WriteEnabled)) + { + return RawChannelOEcho(Channel, String, Length); + } + + return RawChannelOWrite2(Channel, String, Length); +} + ULONG NTAPI RawChannelGetIBufferIndex(IN PSAC_CHANNEL Channel) @@ -214,6 +219,7 @@ ASSERT(Channel); ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE);
+ /* Return the current buffer index */ return Channel->IBufferIndex; }
@@ -226,34 +232,18 @@ ASSERT(Channel); ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE);
+ /* Set the new index, and if it's not zero, it means we have data */ Channel->IBufferIndex = BufferIndex; - Channel->ChannelHasNewIBufferData = BufferIndex != 0; - - if (!Channel->IBufferIndex) - { - if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) - { - ChannelClearEvent(Channel, HasNewDataEvent); - UNREFERENCED_PARAMETER(Status); - } - } -} - -NTSTATUS -NTAPI -RawChannelOWrite(IN PSAC_CHANNEL Channel, - IN PCHAR String, - IN ULONG Length) -{ - CHECK_PARAMETER1(Channel); - CHECK_PARAMETER2(String); - - if ((ConMgrIsWriteEnabled(Channel)) && (Channel->WriteEnabled)) - { - return RawChannelOEcho(Channel, String, Length); - } - - return RawChannelOWrite2(Channel, String, Length); + _InterlockedExchange(&Channel->ChannelHasNewIBufferData, BufferIndex != 0); + + /* If we have new data, and an event has been registered... */ + if (!(Channel->IBufferIndex) && + (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)) + { + /* Go ahead and signal it */ + ChannelClearEvent(Channel, HasNewDataEvent); + UNREFERENCED_PARAMETER(Status); + } }
NTSTATUS @@ -264,38 +254,46 @@ IN PULONG ReturnBufferSize) { ULONG CopyChars; - CHECK_PARAMETER1(Channel); CHECK_PARAMETER2(Buffer); CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE);
+ /* Assume failure */ *ReturnBufferSize = 0;
+ /* Check how many bytes are in the buffer */ if (Channel->ChannelInputBufferLength(Channel) == 0) { + /* Apparently nothing. Make sure the flag indicates so too */ ASSERT(ChannelHasNewIBufferData(Channel) == FALSE); } else { - CopyChars = Channel->ChannelInputBufferLength(Channel); - if (CopyChars > BufferSize) CopyChars = BufferSize; + /* Use the smallest number of bytes either in the buffer or requested */ + CopyChars = min(Channel->ChannelInputBufferLength(Channel), BufferSize); ASSERT(CopyChars <= Channel->ChannelInputBufferLength(Channel));
+ /* Copy them into the caller's buffer */ RtlCopyMemory(Buffer, Channel->IBuffer, CopyChars);
+ /* Update the channel's index past the copied (read) bytes */ RawChannelSetIBufferIndex(Channel, RawChannelGetIBufferIndex(Channel) - CopyChars);
+ /* Are there still bytes that haven't been read yet? */ if (Channel->ChannelInputBufferLength(Channel)) { + /* Shift them up in the buffer */ RtlMoveMemory(Channel->IBuffer, &Channel->IBuffer[CopyChars], Channel->ChannelInputBufferLength(Channel)); }
+ /* Return the number of bytes we actually copied */ *ReturnBufferSize = CopyChars; }
+ /* Return success */ return STATUS_SUCCESS; }
@@ -307,6 +305,7 @@ CHECK_PARAMETER1(Channel); CHECK_PARAMETER2(BufferStatus);
+ /* If the index is beyond the length, the buffer must be full */ *BufferStatus = RawChannelGetIBufferIndex(Channel) > SAC_RAW_IBUFFER_SIZE; return STATUS_SUCCESS; } @@ -316,25 +315,31 @@ RawChannelIBufferLength(IN PSAC_CHANNEL Channel) { ASSERT(Channel); + + /* The index is the current length (since we're 0-based) */ return RawChannelGetIBufferIndex(Channel); }
-CHAR +WCHAR NTAPI RawChannelIReadLast(IN PSAC_CHANNEL Channel) { UCHAR LastChar = 0; - ASSERT(Channel);
+ /* Check if there's anything to read in the buffer */ if (Channel->ChannelInputBufferLength(Channel)) { - RawChannelSetIBufferIndex(Channel, RawChannelGetIBufferIndex(Channel) - 1); - + /* Go back one character */ + RawChannelSetIBufferIndex(Channel, + RawChannelGetIBufferIndex(Channel) - 1); + + /* Read it, and clear its current value */ LastChar = Channel->IBuffer[RawChannelGetIBufferIndex(Channel)]; - Channel->IBuffer[RawChannelGetIBufferIndex(Channel)] = 0; - } - + Channel->IBuffer[RawChannelGetIBufferIndex(Channel)] = ANSI_NULL; + } + + /* Return the last character */ return LastChar; }
@@ -347,27 +352,34 @@ NTSTATUS Status; BOOLEAN IsFull; ULONG Index; - CHECK_PARAMETER1(Channel); CHECK_PARAMETER2(Buffer); CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE);
+ /* First, check if the input buffer still has space */ Status = RawChannelIBufferIsFull(Channel, &IsFull); if (!NT_SUCCESS(Status)) return Status; - if (IsFull) return STATUS_UNSUCCESSFUL;
+ /* Get the current buffer index */ Index = RawChannelGetIBufferIndex(Channel); - if ((SAC_RAW_IBUFFER_SIZE - Index) >= BufferSize) return STATUS_INSUFFICIENT_RESOURCES; - + if ((SAC_RAW_IBUFFER_SIZE - Index) < BufferSize) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Copy the new data */ RtlCopyMemory(&Channel->IBuffer[Index], Buffer, BufferSize);
+ /* Update the index */ RawChannelSetIBufferIndex(Channel, BufferSize + Index);
+ /* Signal the event, if one was set */ if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) { ChannelSetEvent(Channel, HasNewDataEvent); }
- return STATUS_SUCCESS; -} + /* All done */ + return STATUS_SUCCESS; +}
Modified: trunk/reactos/drivers/sac/driver/sacdrv.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/sacdrv.h... ============================================================================== --- trunk/reactos/drivers/sac/driver/sacdrv.h [iso-8859-1] (original) +++ trunk/reactos/drivers/sac/driver/sacdrv.h [iso-8859-1] Mon Aug 19 03:32:39 2013 @@ -157,6 +157,7 @@ #define SAC_SERIAL_PORT_BUFFER_SIZE 1024 // 1KB #define SAC_MAX_MESSAGES 200 #define SAC_VTUTF8_COL_WIDTH 80 +#define SAC_VTUTF8_COL_HEIGHT 25
// // Channel flags @@ -302,7 +303,7 @@ );
typedef -CHAR +WCHAR (NTAPI *PSAC_CHANNEL_IREAD_LAST)( IN struct _SAC_CHANNEL* Channel ); @@ -775,7 +776,7 @@ IN ULONG BufferSize );
-UCHAR +WCHAR NTAPI ChannelIReadLast( IN PSAC_CHANNEL Channel @@ -864,7 +865,7 @@ IN PSAC_CHANNEL Channel );
-CHAR +WCHAR NTAPI RawChannelIReadLast( IN PSAC_CHANNEL Channel @@ -879,8 +880,105 @@ );
// +// VT-UTF8 Channel Table +// +NTSTATUS +NTAPI +VTUTF8ChannelCreate( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +VTUTF8ChannelDestroy( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +VTUTF8ChannelORead( + IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + OUT PULONG ByteCount +); + +NTSTATUS +NTAPI +VTUTF8ChannelOEcho( + IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length +); + +NTSTATUS +NTAPI +VTUTF8ChannelOFlush( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +VTUTF8ChannelOWrite( + IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length +); + +NTSTATUS +NTAPI +VTUTF8ChannelIRead( + IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + IN PULONG ReturnBufferSize +); + +NTSTATUS +NTAPI +VTUTF8ChannelIBufferIsFull( + IN PSAC_CHANNEL Channel, + OUT PBOOLEAN BufferStatus +); + +ULONG +NTAPI +VTUTF8ChannelIBufferLength( + IN PSAC_CHANNEL Channel +); + +WCHAR +NTAPI +VTUTF8ChannelIReadLast( + IN PSAC_CHANNEL Channel +); + +NTSTATUS +NTAPI +VTUTF8ChannelIWrite( + IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize +); + + +// // Helper Routines // +BOOLEAN +NTAPI +SacTranslateUtf8ToUnicode( + IN CHAR Utf8Char, + IN PCHAR Utf8Buffer, + OUT PWCHAR Utf8Value +); + +ULONG +NTAPI +GetMessageLineCount( + IN ULONG MessageIndex +); + NTSTATUS NTAPI SerialBufferGetChar( @@ -921,6 +1019,102 @@ NTAPI DoRebootCommand( IN BOOLEAN Reboot +); + +VOID +NTAPI +DoFullInfoCommand( + VOID +); + +VOID +NTAPI +DoPagingCommand( + VOID +); + +VOID +NTAPI +DoSetTimeCommand( + IN PCHAR InputTime +); + +VOID +NTAPI +DoKillCommand( + IN PCHAR KillString +); + +VOID +NTAPI +DoLowerPriorityCommand( + IN PCHAR PrioString +); + +VOID +NTAPI +DoRaisePriorityCommand( + IN PCHAR PrioString +); + +VOID +NTAPI +DoLimitMemoryCommand( + IN PCHAR LimitString +); + +VOID +NTAPI +DoCrashCommand( + VOID +); + +VOID +NTAPI +DoMachineInformationCommand( + VOID +); + +VOID +NTAPI +DoChannelCommand( + IN PCHAR ChannelString +); + +VOID +NTAPI +DoCmdCommand( + IN PCHAR InputString +); + +VOID +NTAPI +DoLockCommand( + VOID +); + +VOID +NTAPI +DoHelpCommand( + VOID +); + +VOID +NTAPI +DoGetNetInfo( + IN BOOLEAN DoPrint +); + +VOID +NTAPI +DoSetIpAddressCommand( + IN PCHAR IpString +); + +VOID +NTAPI +DoTlistCommand( + VOID );
// @@ -933,7 +1127,9 @@ extern PCHAR SerialPortBuffer; extern LONG SerialPortConsumerIndex, SerialPortProducerIndex; extern PCHAR Utf8ConversionBuffer; +extern BOOLEAN GlobalPagingNeeded; extern ULONG Utf8ConversionBufferSize; +extern BOOLEAN CommandConsoleLaunchingEnabled;
// // Function to initailize a SAC Semaphore Lock @@ -1046,3 +1242,11 @@ /* Return the index of the channel */ return Channel->Index; } + +FORCEINLINE +BOOLEAN +ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel) +{ + /* Return if there's any new data in the input buffer */ + return Channel->ChannelHasNewIBufferData; +}
Modified: trunk/reactos/drivers/sac/driver/util.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/util.c?r... ============================================================================== --- trunk/reactos/drivers/sac/driver/util.c [iso-8859-1] (original) +++ trunk/reactos/drivers/sac/driver/util.c [iso-8859-1] Mon Aug 19 03:32:39 2013 @@ -33,6 +33,56 @@ PCHAR SerialPortBuffer;
/* FUNCTIONS *****************************************************************/ + +BOOLEAN +NTAPI +SacTranslateUtf8ToUnicode(IN CHAR Utf8Char, + IN PCHAR Utf8Buffer, + OUT PWCHAR Utf8Value) +{ + ULONG i; + + /* Find out how many valid characters we have in the buffer */ + i = 0; + while (Utf8Buffer[i++] && (i < 3)); + + /* If we have at least 3, shift everything by a byte */ + if (i >= 3) + { + /* The last input character goes at the end */ + Utf8Buffer[0] = Utf8Buffer[1]; + Utf8Buffer[1] = Utf8Buffer[2]; + Utf8Buffer[2] = Utf8Char; + } + else + { + /* We don't have more than 3 characters, place the input at the index */ + Utf8Buffer[i] = Utf8Char; + } + + /* Print to debugger */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SacTranslateUtf8ToUnicode - About to decode the UTF8 buffer.\n"); + SAC_DBG(SAC_DBG_ENTRY_EXIT, " UTF8[0]: 0x%02lx UTF8[1]: 0x%02lx UTF8[2]: 0x%02lx\n", + Utf8Buffer[0], + Utf8Buffer[1], + Utf8Buffer[2]); + + /* Is this a simple ANSI character? */ + if (!(Utf8Char & 0x80)) + { + /* Return it as Unicode, nothing left to do */ + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SACDRV: SacTranslateUTf8ToUnicode - Case1\n"); + *Utf8Value = (WCHAR)Utf8Char; + Utf8Buffer[0] = Utf8Buffer[1]; + Utf8Buffer[1] = Utf8Buffer[2]; + Utf8Buffer[2] = UNICODE_NULL; + return TRUE; + } + + /* Anything else is not yet supported */ + ASSERT(FALSE); + return FALSE; +}
BOOLEAN NTAPI @@ -151,8 +201,76 @@ IN PWCHAR MessageString, IN ULONG MessageSize) { - /* FIXME: For now don't format anything */ - wcsncpy(FormattedString, MessageString, MessageSize / sizeof(WCHAR)); + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SacFormatMessage: Entering.\n"); + + /* Check if any of the parameters are NULL or zero */ + if (!(MessageString) || !(FormattedString) || !(MessageSize)) + { + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SacFormatMessage: Exiting with invalid parameters.\n"); + return; + } + + /* Keep going as long as there's still characters */ + while ((MessageString[0]) && (MessageSize)) + { + /* Is it a non-formatting character? */ + if (MessageString[0] != L'%') + { + /* Just write it back into the buffer and keep going */ + *FormattedString++ = MessageString[0]; + MessageString++; + } + else + { + /* Go over the format characters we recognize */ + switch (MessageString[1]) + { + case L'0': + *FormattedString = UNICODE_NULL; + return; + + case L'%': + *FormattedString++ = L'%'; + break; + + case L'\': + *FormattedString++ = L'\r'; + *FormattedString++ = L'\n'; + break; + + case L'r': + *FormattedString++ = L'\r'; + break; + + case L'b': + *FormattedString++ = L' '; + break; + + case L'.': + *FormattedString++ = L'.'; + break; + + case L'!': + *FormattedString++ = L'!'; + break; + + default: + /* Only move forward one character */ + MessageString--; + break; + } + + /* Move forward two characters */ + MessageString += 2; + } + + /* Move to the next character*/ + MessageSize--; + } + + /* All done */ + *FormattedString = UNICODE_NULL; + SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SacFormatMessage: Exiting.\n"); }
NTSTATUS @@ -1106,6 +1224,25 @@ }
ULONG +NTAPI +GetMessageLineCount(IN ULONG MessageIndex) +{ + ULONG LineCount = 0; + PWCHAR Buffer; + + /* Get the message buffer */ + Buffer = GetMessage(MessageIndex); + if (Buffer) + { + /* Scan it looking for new lines, and increment the conut each time */ + while (*Buffer) if (*Buffer++ == L'\n') ++LineCount; + } + + /* Return the line count */ + return LineCount; +} + +ULONG ConvertAnsiToUnicode( IN PWCHAR pwch, IN PCHAR pch, @@ -1129,16 +1266,6 @@ ) { return STATUS_NOT_IMPLEMENTED; -} - -BOOLEAN -SacTranslateUtf8ToUnicode( - IN CHAR Utf8Char, - IN PCHAR UnicodeBuffer, - OUT PCHAR Utf8Value - ) -{ - return FALSE; }
NTSTATUS @@ -1159,14 +1286,6 @@ return STATUS_NOT_IMPLEMENTED; }
-ULONG -GetMessageLineCount( - IN ULONG MessageIndex - ) -{ - return 0; -} - NTSTATUS RegisterSacCmdEvent( IN PVOID Object,
Modified: trunk/reactos/drivers/sac/driver/vtutf8chan.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/vtutf8ch... ============================================================================== --- trunk/reactos/drivers/sac/driver/vtutf8chan.c [iso-8859-1] (original) +++ trunk/reactos/drivers/sac/driver/vtutf8chan.c [iso-8859-1] Mon Aug 19 03:32:39 2013 @@ -1,36 +1,109 @@ /* - * PROJECT: ReactOS Boot Loader - * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: drivers/sac/driver/vtutf8chan.c - * PURPOSE: Driver for the Server Administration Console (SAC) for EMS - * PROGRAMMERS: ReactOS Portable Systems Group + * PROJECT: ReactOS Drivers + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: drivers/sac/driver/vtutf8chan.c + * PURPOSE: Driver for the Server Administration Console (SAC) for EMS + * PROGRAMMERS: ReactOS Portable Systems Group */
-/* INCLUDES *******************************************************************/ +/* INCLUDES ******************************************************************/
#include "sacdrv.h"
-/* GLOBALS ********************************************************************/ - -/* FUNCTIONS ******************************************************************/ - -NTSTATUS -VTUTF8ChannelCreate( - IN PSAC_CHANNEL Channel - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -VTUTF8ChannelDestroy( - IN PSAC_CHANNEL Channel - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS +/* GLOBALS *******************************************************************/ + +CHAR IncomingUtf8ConversionBuffer[4]; +WCHAR IncomingUnicodeValue; + +/* FUNCTIONS *****************************************************************/ + +typedef struct _SAC_CURSOR_DATA +{ + UCHAR CursorX; + UCHAR CursorY; + UCHAR CursorVisible; + WCHAR CursorValue; +} SAC_CURSOR_DATA, *PSAC_CURSOR_DATA; + +C_ASSERT(sizeof(SAC_CURSOR_DATA) == 6); + +#define SAC_VTUTF8_OBUFFER_SIZE 0x2D00 +#define SAC_VTUTF8_IBUFFER_SIZE 0x2000 + +NTSTATUS +NTAPI +VTUTF8ChannelOInit(IN PSAC_CHANNEL Channel) +{ + PSAC_CURSOR_DATA Cursor; + ULONG x, y; + CHECK_PARAMETER(Channel); + + /* Set the current channel cursor parameters */ + Channel->CursorVisible = 0; + Channel->CursorX = 40; + Channel->CursorY = 37; + + /* Loop the output buffer height by width */ + Cursor = (PSAC_CURSOR_DATA)Channel->OBuffer; + y = SAC_VTUTF8_COL_HEIGHT - 1; + do + { + x = SAC_VTUTF8_COL_WIDTH; + do + { + /* For every character, set the defaults */ + Cursor->CursorValue = ' '; + Cursor->CursorX = 40; + Cursor->CursorY = 38; + + /* Move to the next character */ + Cursor++; + } while (--x); + } while (--y); + + /* All done */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +VTUTF8ChannelCreate(IN PSAC_CHANNEL Channel) +{ + NTSTATUS Status; + CHECK_PARAMETER(Channel); + + /* Allocate the output buffer */ + Channel->OBuffer = SacAllocatePool(SAC_VTUTF8_OBUFFER_SIZE, GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(Channel->OBuffer); + + /* Allocate the input buffer */ + Channel->IBuffer = SacAllocatePool(SAC_VTUTF8_IBUFFER_SIZE, GLOBAL_BLOCK_TAG); + CHECK_ALLOCATION(Channel->IBuffer); + + /* Initialize the output stream */ + Status = VTUTF8ChannelOInit(Channel); + if (NT_SUCCESS(Status)) return Status; + + /* Reset all flags and return success */ + _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 0); + _InterlockedExchange(&Channel->ChannelHasNewIBufferData, 0); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +VTUTF8ChannelDestroy(IN PSAC_CHANNEL Channel) +{ + CHECK_PARAMETER(Channel); + + /* Free the buffer and then destroy the channel */ + if (Channel->OBuffer) SacFreePool(Channel->OBuffer); + if (Channel->IBuffer) SacFreePool(Channel->IBuffer); + return ChannelDestroy(Channel); +} + +NTSTATUS +NTAPI VTUTF8ChannelORead( IN PSAC_CHANNEL Channel, IN PCHAR Buffer, @@ -41,17 +114,8 @@ return STATUS_NOT_IMPLEMENTED; }
-NTSTATUS -VTUTF8ChannelOEcho( - IN PSAC_CHANNEL Channel, - IN PWCHAR String, - IN ULONG Size - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - BOOLEAN +NTAPI VTUTF8ChannelScanForNumber( IN PWCHAR String, OUT PULONG Number @@ -61,6 +125,7 @@ }
NTSTATUS +NTAPI VTUTF8ChannelAnsiDispatch( IN NTSTATUS Status, IN ULONG AnsiCode, @@ -72,6 +137,7 @@ }
NTSTATUS +NTAPI VTUTF8ChannelProcessAttributes( IN PSAC_CHANNEL Channel, IN UCHAR Attribute @@ -80,24 +146,8 @@ return STATUS_NOT_IMPLEMENTED; }
-ULONG -VTUTF8ChannelGetIBufferIndex( - IN PSAC_CHANNEL Channel - ) -{ - return 0; -} - -VOID -VTUTF8ChannelSetIBufferIndex( - IN PSAC_CHANNEL Channel, - IN ULONG BufferIndex - ) -{ - -} - -NTSTATUS +NTSTATUS +NTAPI VTUTF8ChannelConsumeEscapeSequence( IN PSAC_CHANNEL Channel, IN PWCHAR String @@ -107,6 +157,7 @@ }
NTSTATUS +NTAPI VTUTF8ChannelOFlush( IN PSAC_CHANNEL Channel ) @@ -115,67 +166,240 @@ }
NTSTATUS -VTUTF8ChannelIRead( - IN PSAC_CHANNEL Channel, - IN PCHAR Buffer, - IN ULONG BufferSize, - IN PULONG ReturnBufferSize - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -VTUTF8ChannelIBufferIsFull( - IN PSAC_CHANNEL Channel, - OUT PBOOLEAN BufferStatus - ) -{ - return STATUS_NOT_IMPLEMENTED; +NTAPI +VTUTF8ChannelOWrite2(IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Size) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +VTUTF8ChannelOEcho(IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Size) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +VTUTF8ChannelOWrite(IN PSAC_CHANNEL Channel, + IN PCHAR String, + IN ULONG Length) +{ + NTSTATUS Status; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(String); + + /* Call the lower level function */ + Status = VTUTF8ChannelOWrite2(Channel, String, Length / sizeof(WCHAR)); + if (NT_SUCCESS(Status)) + { + /* Is the channel enabled for output? */ + if ((ConMgrIsWriteEnabled(Channel)) && (Channel->WriteEnabled)) + { + /* Go ahead and output it */ + Status = VTUTF8ChannelOEcho(Channel, String, Length); + } + else + { + /* Otherwise, just remember that we have new data */ + _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 1); + } + } + + /* We're done */ + return Status; +} + +ULONG +NTAPI +VTUTF8ChannelGetIBufferIndex(IN PSAC_CHANNEL Channel) +{ + ASSERT(Channel); + ASSERT((Channel->IBufferIndex % sizeof(WCHAR)) == 0); + ASSERT(Channel->IBufferIndex < SAC_VTUTF8_IBUFFER_SIZE); + + /* Return the current buffer index */ + return Channel->IBufferIndex; +} + +VOID +NTAPI +VTUTF8ChannelSetIBufferIndex(IN PSAC_CHANNEL Channel, + IN ULONG BufferIndex) +{ + NTSTATUS Status; + ASSERT(Channel); + ASSERT((Channel->IBufferIndex % sizeof(WCHAR)) == 0); + ASSERT(Channel->IBufferIndex < SAC_VTUTF8_IBUFFER_SIZE); + + /* Set the new index, and if it's not zero, it means we have data */ + Channel->IBufferIndex = BufferIndex; + _InterlockedExchange(&Channel->ChannelHasNewIBufferData, BufferIndex != 0); + + /* If we have new data, and an event has been registered... */ + if (!(Channel->IBufferIndex) && + (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)) + { + /* Go ahead and signal it */ + ChannelClearEvent(Channel, HasNewDataEvent); + UNREFERENCED_PARAMETER(Status); + } +} + +NTSTATUS +NTAPI +VTUTF8ChannelIRead(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize, + IN PULONG ReturnBufferSize) +{ + ULONG CopyChars; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Buffer); + CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE); + + /* Assume failure */ + *ReturnBufferSize = 0; + + /* Check how many bytes are in the buffer */ + if (Channel->ChannelInputBufferLength(Channel) == 0) + { + /* Apparently nothing. Make sure the flag indicates so too */ + ASSERT(ChannelHasNewIBufferData(Channel) == FALSE); + } + else + { + /* Use the smallest number of bytes either in the buffer or requested */ + CopyChars = min(Channel->ChannelInputBufferLength(Channel) * sizeof(WCHAR), + BufferSize); + ASSERT(CopyChars <= Channel->ChannelInputBufferLength(Channel)); + + /* Copy them into the caller's buffer */ + RtlCopyMemory(Buffer, Channel->IBuffer, CopyChars); + + /* Update the channel's index past the copied (read) bytes */ + VTUTF8ChannelSetIBufferIndex(Channel, + VTUTF8ChannelGetIBufferIndex(Channel) - CopyChars); + + /* Are there still bytes that haven't been read yet? */ + if (Channel->ChannelInputBufferLength(Channel)) + { + /* Shift them up in the buffer */ + RtlMoveMemory(Channel->IBuffer, + &Channel->IBuffer[CopyChars], + Channel->ChannelInputBufferLength(Channel) * + sizeof(WCHAR)); + } + + /* Return the number of bytes we actually copied */ + *ReturnBufferSize = CopyChars; + } + + /* Return success */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +VTUTF8ChannelIBufferIsFull(IN PSAC_CHANNEL Channel, + OUT PBOOLEAN BufferStatus) +{ + CHECK_PARAMETER1(Channel); + + /* If the index is beyond the length, the buffer must be full */ + *BufferStatus = VTUTF8ChannelGetIBufferIndex(Channel) > SAC_VTUTF8_IBUFFER_SIZE; + return STATUS_SUCCESS; +} + +ULONG +NTAPI +VTUTF8ChannelIBufferLength(IN PSAC_CHANNEL Channel) +{ + ASSERT(Channel); + + /* The index is the length, so divide by two to get character count */ + return VTUTF8ChannelGetIBufferIndex(Channel) / sizeof(WCHAR); }
WCHAR -VTUTF8ChannelIReadLast( - IN PSAC_CHANNEL Channel - ) -{ - return 0; -} - -ULONG -VTUTF8ChannelIBufferLength( - IN PSAC_CHANNEL Channel - ) -{ - return 0; -} - -NTSTATUS -VTUTF8ChannelOWrite2( - IN PSAC_CHANNEL Channel, - IN PWCHAR String, - IN ULONG Size - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -VTUTF8ChannelIWrite( - IN PSAC_CHANNEL Channel, - IN PCHAR Buffer, - IN ULONG BufferSize - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -VTUTF8ChannelOWrite( - IN PSAC_CHANNEL Channel, - IN PWCHAR String, - IN ULONG Length - ) -{ - return STATUS_NOT_IMPLEMENTED; -} +NTAPI +VTUTF8ChannelIReadLast(IN PSAC_CHANNEL Channel) +{ + PWCHAR LastCharLocation; + WCHAR LastChar = 0; + ASSERT(Channel); + + /* Check if there's anything to read in the buffer */ + if (Channel->ChannelInputBufferLength(Channel)) + { + /* Go back one character */ + VTUTF8ChannelSetIBufferIndex(Channel, + VTUTF8ChannelGetIBufferIndex(Channel) - + sizeof(WCHAR)); + + /* Read it, and clear its current value */ + LastCharLocation = (PWCHAR)&Channel->IBuffer[VTUTF8ChannelGetIBufferIndex(Channel)]; + LastChar = *LastCharLocation; + *LastCharLocation = UNICODE_NULL; + } + + /* Return the last character */ + return LastChar; +} + +NTSTATUS +NTAPI +VTUTF8ChannelIWrite(IN PSAC_CHANNEL Channel, + IN PCHAR Buffer, + IN ULONG BufferSize) +{ + NTSTATUS Status; + BOOLEAN IsFull; + ULONG Index, i; + CHECK_PARAMETER1(Channel); + CHECK_PARAMETER2(Buffer); + CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE); + + /* First, check if the input buffer still has space */ + Status = VTUTF8ChannelIBufferIsFull(Channel, &IsFull); + if (!NT_SUCCESS(Status)) return Status; + if (IsFull) return STATUS_UNSUCCESSFUL; + + /* Get the current buffer index */ + Index = VTUTF8ChannelGetIBufferIndex(Channel); + if ((SAC_VTUTF8_IBUFFER_SIZE - Index) < BufferSize) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Copy the new data */ + for (i = 0; i < BufferSize; i++) + { + /* Convert the character */ + if (SacTranslateUtf8ToUnicode(Buffer[i], + IncomingUtf8ConversionBuffer, + &IncomingUnicodeValue)) + { + /* Write it into the buffer */ + *(PWCHAR)&Channel->IBuffer[VTUTF8ChannelGetIBufferIndex(Channel)] = + IncomingUnicodeValue; + + /* Update the index */ + Index = VTUTF8ChannelGetIBufferIndex(Channel); + VTUTF8ChannelSetIBufferIndex(Channel, Index + sizeof(WCHAR)); + } + } + + /* Signal the event, if one was set */ + if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) + { + ChannelSetEvent(Channel, HasNewDataEvent); + } + + /* All done */ + return STATUS_SUCCESS; +}
Modified: trunk/reactos/include/reactos/mc/sacmsg.mc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/mc/sacmsg.m... ============================================================================== --- trunk/reactos/include/reactos/mc/sacmsg.mc [iso-8859-1] (original) +++ trunk/reactos/include/reactos/mc/sacmsg.mc [iso-8859-1] Mon Aug 19 03:32:39 2013 @@ -1,7 +1,12 @@ MessageId=1 SymbolicName=SAC_INIT_STATUS Language=English -Computer is booting, SAC started and initialized.\n\nUse the "ch -?" command for information about using channels.\nUse the "?" command for general help. + +Computer is booting, SAC started and initialized. + +Use the "ch -?" command for information about using channels. +Use the "?" command for general help. + .
MessageId=2 @@ -25,7 +30,8 @@ MessageId=5 SymbolicName=SACDRV_5 Language=English -The SAC will become unavailable soon. The computer is shutting down.\n +The SAC will become unavailable soon. The computer is shutting down. + .
MessageId=6 @@ -295,7 +301,9 @@ MessageId=69 SymbolicName=SACDRV_69 Language=English -memory: %%4ld kb uptime:%%3ld %%2ld:%%02ld:%%02ld.%%03ld\n\n +memory: %%4ld kb uptime:%%3ld %%2ld:%%02ld:%%02ld.%%03ld + + .
MessageId=70 @@ -319,7 +327,8 @@ MessageId=73 SymbolicName=SACDRV_73 Language=English -\n Memory:%%7ldK Avail:%%7ldK TotalWs:%%7ldK InRam Kernel:%%5ldK P:%%5ldK + + Memory:%%7ldK Avail:%%7ldK TotalWs:%%7ldK InRam Kernel:%%5ldK P:%%5ldK .
MessageId=74 @@ -421,7 +430,8 @@ MessageId=90 SymbolicName=SACDRV_90 Language=English -A duplicate process id is being cleaned up by the system. Try the \ncommand again in a few seconds. +A duplicate process id is being cleaned up by the system. Try the +command again in a few seconds. .
MessageId=92 @@ -523,31 +533,46 @@ MessageId=108 SymbolicName=SACDRV_108 Language=English -Channel List\n \n(Use "ch -?" for information on using channels)\n\n# Status Channel Name +Channel List + +(Use "ch -?" for information on using channels) + +# Status Channel Name .
MessageId=109 SymbolicName=SACDRV_109 Language=English -EVENT: A new channel has been created. Use "ch -?" for channel help.\nChannel: %%s +EVENT: A new channel has been created. Use "ch -?" for channel help. +Channel: %%s .
MessageId=110 SymbolicName=SACDRV_110 Language=English -EVENT: A channel has been closed.\nChannel: %%s +EVENT: A channel has been closed. +Channel: %%s .
MessageId=111 SymbolicName=SACDRV_111 Language=English -Name: %%s\nDescription: %%s\nType: %%s\nChannel GUID: %%08lx-%%04x-%%04x-%%02x%%02x-%%02x%%02x%%02x%%02x%%02x%%02x\nApplication Type GUID: %%08lx-%%04x-%%04x-%%02x%%02x-%%02x%%02x%%02x%%02x%%02x%%02x\n\nPress <esc><tab> for next channel.\nPress <esc><tab>0 to return to the SAC channel.\nUse any other key to view this channel.\n +Name: %%s +Description: %%s +Type: %%s +Channel GUID: %%08lx-%%04x-%%04x-%%02x%%02x-%%02x%%02x%%02x%%02x%%02x%%02x +Application Type GUID: %%08lx-%%04x-%%04x-%%02x%%02x-%%02x%%02x%%02x%%02x%%02x%%02x + +Press <esc><tab> for next channel. +Press <esc><tab>0 to return to the SAC channel. +Use any other key to view this channel. + .
MessageId=112 SymbolicName=SACDRV_112 Language=English -ch Channel management commands. Use ch -? for more help. +ch Channel management commands. Use ch -? for more help. .
MessageId=113 @@ -571,7 +596,10 @@ MessageId=116 SymbolicName=SACDRV_116 Language=English -Error! Failed to remove channel! \n\nPlease contact your system administrator.\n +Error! Failed to remove channel! + +Please contact your system administrator. + .
MessageId=119 @@ -583,7 +611,9 @@ MessageId=120 SymbolicName=SACDRV_120 Language=English -Timeout: Unable to launch a Command Prompt. The service responsible for \n launching Command Prompt channels has timed out. This may be \n because the service is malfunctioning or is unresponsive. +Timeout: Unable to launch a Command Prompt. The service responsible for + launching Command Prompt channels has timed out. This may be + because the service is malfunctioning or is unresponsive. .
MessageId=121 @@ -601,7 +631,10 @@ MessageId=131 SymbolicName=SACDRV_131 Language=English -Error: Unable to launch a Command Prompt. The service responsible for launching\n Command Prompt channels has not yet registered. This may be because the\n service is not yet started, is disabled by the administrator, is\n malfunctioning or is unresponsive. +Error: Unable to launch a Command Prompt. The service responsible for launching + Command Prompt channels has not yet registered. This may be because the + service is not yet started, is disabled by the administrator, is + malfunctioning or is unresponsive. .
MessageId=132 @@ -619,19 +652,39 @@ MessageId=134 SymbolicName=SACDRV_134 Language=English -EVENT: An attempt was made to close a channel but failed.\nChannel: %%s +EVENT: An attempt was made to close a channel but failed. +Channel: %%s .
MessageId=135 SymbolicName=SACDRV_135 Language=English -EVENT: An attempt to close a channel failed because it is already closed.\nChannel: %%s +EVENT: An attempt to close a channel failed because it is already closed. +Channel: %%s .
MessageId=136 SymbolicName=SACDRV_136 Language=English -Channel management commands:\n\nch List all channels.\n\nStatus Legend: (AB)\nA: Channel operational status\n 'A' = Channel is active.\n 'I' = Channel is inactive.\nB: Channel Type\n 'V' = VT-UTF8 emulation.\n 'R' = Raw - no emulation.\n\nch -si <#> Switch to a channel by its number.\nch -sn <name> Switch to a channel by its name.\nch -ci <#> Close a channel by its number.\nch -cn <name> Close a channel by its name.\n\nPress <esc><tab> to select a channel.\nPress <esc><tab>0 to return to the SAC channel. +Channel management commands: + +ch List all channels. + +Status Legend: (AB) +A: Channel operational status + 'A' = Channel is active. + 'I' = Channel is inactive. +B: Channel Type + 'V' = VT-UTF8 emulation. + 'R' = Raw - no emulation. + +ch -si <#> Switch to a channel by its number. +ch -sn <name> Switch to a channel by its name. +ch -ci <#> Close a channel by its number. +ch -cn <name> Close a channel by its name. + +Press <esc><tab> to select a channel. +Press <esc><tab>0 to return to the SAC channel. .
MessageId=137 @@ -703,5 +756,5 @@ MessageId=154 SymbolicName=SACDRV_154 Language=English -The maximum number of channels has been reached. -. +The maximum number of channels has been reached. +.