mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 21:01:54 +00:00
[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. svn path=/trunk/; revision=59778
This commit is contained in:
parent
ed35b983f9
commit
519595d9c4
9 changed files with 1112 additions and 359 deletions
|
@ -404,7 +404,6 @@ ChanMgrCreateChannel(OUT PSAC_CHANNEL *Channel,
|
|||
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 @@ ChanMgrCreateChannel(OUT PSAC_CHANNEL *Channel,
|
|||
else
|
||||
{
|
||||
/* We couldn't create it, free the buffer */
|
||||
SAC_DBG(SAC_DBG_INIT, "failing here: %d %lx\n", __LINE__, Status);
|
||||
SacFreePool(NewChannel);
|
||||
}
|
||||
|
||||
|
|
|
@ -147,11 +147,11 @@ ChannelIRead(IN PSAC_CHANNEL Channel,
|
|||
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 @@ ChannelInitializeVTable(IN PSAC_CHANNEL Channel)
|
|||
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 */
|
||||
|
|
|
@ -17,58 +17,44 @@ ULONG GlobalBufferSize;
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DoRebootCommand(IN BOOLEAN Reboot)
|
||||
NTSTATUS
|
||||
DoChannelListCommand(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
LARGE_INTEGER Timeout, TickCount;
|
||||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
SAC_DBG(1, "SAC DoRebootCommand: Entering.\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* Get the current time now, and setup a timeout in 1 second */
|
||||
KeQueryTickCount(&TickCount);
|
||||
Timeout.QuadPart = TickCount.QuadPart / (10000000 / KeQueryTimeIncrement());
|
||||
NTSTATUS
|
||||
DoChannelCloseByNameCommand(
|
||||
IN PCHAR Count
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* Check if the timeout is small enough */
|
||||
if (Timeout.QuadPart < 60 )
|
||||
{
|
||||
/* Show the prompt */
|
||||
ConMgrSimpleEventMessage(Reboot ?
|
||||
SAC_RESTART_PROMPT : SAC_SHUTDOWN_PROMPT,
|
||||
TRUE);
|
||||
NTSTATUS
|
||||
DoChannelCloseByIndexCommand(
|
||||
IN ULONG ChannelIndex
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* Do the wait */
|
||||
KeInitializeEvent(&Event, SynchronizationEvent, 0);
|
||||
Timeout.QuadPart = -10000000 * (60 - Timeout.LowPart);
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &Timeout);
|
||||
}
|
||||
NTSTATUS
|
||||
DoChannelSwitchByNameCommand(
|
||||
IN PCHAR Count
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* Do a shutdown or a reboot, based on the request */
|
||||
Status = NtShutdownSystem(Reboot ? ShutdownReboot : ShutdownPowerOff);
|
||||
|
||||
/* Check if anyone in the command channel already allocated this */
|
||||
if (!GlobalBuffer)
|
||||
{
|
||||
/* Allocate it */
|
||||
GlobalBuffer = SacAllocatePool(PAGE_SIZE, GLOBAL_BLOCK_TAG);
|
||||
if (!GlobalBuffer)
|
||||
{
|
||||
/* We need the global buffer, bail out without it*/
|
||||
SacPutSimpleMessage(SAC_OUT_OF_MEMORY_PROMPT);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoRebootCommand: Exiting (1).\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the size of the buffer */
|
||||
GlobalBufferSize = PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* We came back from a reboot, this doesn't make sense, tell the user */
|
||||
SacPutSimpleMessage(Reboot ? SAC_RESTART_FAIL_PROMPT : SAC_SHUTDOWN_FAIL_PROMPT);
|
||||
swprintf(GlobalBuffer, GetMessage(SAC_FAIL_PROMPT), Status);
|
||||
SacPutString(GlobalBuffer);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoRebootCommand: Exiting.\n");
|
||||
NTSTATUS
|
||||
DoChannelSwitchByIndexCommand(
|
||||
IN ULONG ChannelIndex
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -124,169 +110,201 @@ CallQueryIPIOCTL(
|
|||
}
|
||||
|
||||
VOID
|
||||
DoFullInfoCommand(
|
||||
VOID
|
||||
)
|
||||
NTAPI
|
||||
DoRebootCommand(IN BOOLEAN Reboot)
|
||||
{
|
||||
LARGE_INTEGER Timeout, TickCount;
|
||||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
SAC_DBG(1, "SAC DoRebootCommand: Entering.\n");
|
||||
|
||||
/* Get the current time now, and setup a timeout in 1 second */
|
||||
KeQueryTickCount(&TickCount);
|
||||
Timeout.QuadPart = TickCount.QuadPart / (10000000 / KeQueryTimeIncrement());
|
||||
|
||||
/* Check if the timeout is small enough */
|
||||
if (Timeout.QuadPart < 60 )
|
||||
{
|
||||
/* Show the prompt */
|
||||
ConMgrSimpleEventMessage(Reboot ?
|
||||
SAC_RESTART_PROMPT : SAC_SHUTDOWN_PROMPT,
|
||||
TRUE);
|
||||
|
||||
/* Do the wait */
|
||||
KeInitializeEvent(&Event, SynchronizationEvent, 0);
|
||||
Timeout.QuadPart = -10000000 * (60 - Timeout.LowPart);
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &Timeout);
|
||||
}
|
||||
|
||||
/* Do a shutdown or a reboot, based on the request */
|
||||
Status = NtShutdownSystem(Reboot ? ShutdownReboot : ShutdownPowerOff);
|
||||
|
||||
/* Check if anyone in the command channel already allocated this */
|
||||
if (!GlobalBuffer)
|
||||
{
|
||||
/* Allocate it */
|
||||
GlobalBuffer = SacAllocatePool(PAGE_SIZE, GLOBAL_BLOCK_TAG);
|
||||
if (!GlobalBuffer)
|
||||
{
|
||||
/* We need the global buffer, bail out without it*/
|
||||
SacPutSimpleMessage(SAC_OUT_OF_MEMORY_PROMPT);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoRebootCommand: Exiting (1).\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the size of the buffer */
|
||||
GlobalBufferSize = PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* We came back from a reboot, this doesn't make sense, tell the user */
|
||||
SacPutSimpleMessage(Reboot ? SAC_RESTART_FAIL_PROMPT : SAC_SHUTDOWN_FAIL_PROMPT);
|
||||
swprintf(GlobalBuffer, GetMessage(SAC_FAIL_PROMPT), Status);
|
||||
SacPutString(GlobalBuffer);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoRebootCommand: Exiting.\n");
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DoFullInfoCommand(VOID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoPagingCommand(
|
||||
VOID
|
||||
)
|
||||
NTAPI
|
||||
DoPagingCommand(VOID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoSetTimeCommand(
|
||||
IN PCHAR InputTime
|
||||
)
|
||||
NTAPI
|
||||
DoSetTimeCommand(IN PCHAR InputTime)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoKillCommand(
|
||||
IN PCHAR KillString
|
||||
)
|
||||
NTAPI
|
||||
DoKillCommand(IN PCHAR KillString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoLowerPriorityCommand(
|
||||
IN PCHAR PrioString
|
||||
)
|
||||
NTAPI
|
||||
DoLowerPriorityCommand(IN PCHAR PrioString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoRaisePriorityCommand(
|
||||
IN PCHAR PrioString
|
||||
)
|
||||
NTAPI
|
||||
DoRaisePriorityCommand(IN PCHAR PrioString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoLimitMemoryCommand(
|
||||
IN PCHAR LimitString
|
||||
)
|
||||
NTAPI
|
||||
DoLimitMemoryCommand(IN PCHAR LimitString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoCrashCommand(
|
||||
VOID
|
||||
)
|
||||
NTAPI
|
||||
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
|
||||
)
|
||||
NTAPI
|
||||
DoMachineInformationCommand(VOID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoCmdCommand(
|
||||
VOID
|
||||
)
|
||||
NTAPI
|
||||
DoChannelCommand(IN PCHAR ChannelString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoLockCommand(
|
||||
VOID
|
||||
)
|
||||
NTAPI
|
||||
DoCmdCommand(IN PCHAR InputString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoHelpCommand(
|
||||
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
|
||||
DoGetNetInfo(
|
||||
IN BOOLEAN DoPrint
|
||||
)
|
||||
NTAPI
|
||||
DoSetIpAddressCommand(IN PCHAR IpString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoSetIpAddressCommand(
|
||||
IN PCHAR IpString
|
||||
)
|
||||
NTAPI
|
||||
DoTlistCommand(VOID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoTlistCommand(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,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);
|
||||
|
@ -438,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();
|
||||
|
||||
|
@ -446,22 +447,137 @@ ConMgrChannelOWrite(IN PSAC_CHANNEL Channel,
|
|||
return Status;
|
||||
}
|
||||
|
||||
#define Shutdown 1
|
||||
#define Restart 3
|
||||
#define Nothing 0
|
||||
BOOLEAN GlobalPagingNeeded;
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ConMgrProcessInputLine(VOID)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
BOOLEAN EnablePaging;
|
||||
NTSTATUS Status;
|
||||
|
||||
#define Nothing 0
|
||||
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 @@ ConMgrSerialPortConsumer(VOID)
|
|||
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 @@ DoLineParsing:
|
|||
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 @@ DoLineParsing:
|
|||
/* 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 @@ DoLineParsing:
|
|||
/* 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 @@ DoLineParsing:
|
|||
/* 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 @@ DoLineParsing:
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,17 +23,19 @@ RawChannelCreate(IN PSAC_CHANNEL Channel)
|
|||
{
|
||||
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 @@ RawChannelDestroy(IN PSAC_CHANNEL Channel)
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -63,13 +58,6 @@ ChannelHasNewOBufferData(IN PSAC_CHANNEL Channel)
|
|||
return Channel->ChannelHasNewOBufferData;
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
BOOLEAN
|
||||
ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return Channel->ChannelHasNewIBufferData;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RawChannelORead(IN PSAC_CHANNEL Channel,
|
||||
|
@ -207,38 +195,6 @@ RawChannelOFlush(IN PSAC_CHANNEL Channel)
|
|||
return ConMgrFlushData(Channel);
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
RawChannelGetIBufferIndex(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
ASSERT(Channel);
|
||||
ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE);
|
||||
|
||||
return Channel->IBufferIndex;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RawChannelSetIBufferIndex(IN PSAC_CHANNEL Channel,
|
||||
IN ULONG BufferIndex)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ASSERT(Channel);
|
||||
ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE);
|
||||
|
||||
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,
|
||||
|
@ -256,6 +212,40 @@ RawChannelOWrite(IN PSAC_CHANNEL Channel,
|
|||
return RawChannelOWrite2(Channel, String, Length);
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
RawChannelGetIBufferIndex(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
ASSERT(Channel);
|
||||
ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE);
|
||||
|
||||
/* Return the current buffer index */
|
||||
return Channel->IBufferIndex;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RawChannelSetIBufferIndex(IN PSAC_CHANNEL Channel,
|
||||
IN ULONG BufferIndex)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
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;
|
||||
_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
|
||||
RawChannelIRead(IN PSAC_CHANNEL Channel,
|
||||
|
@ -264,38 +254,46 @@ RawChannelIRead(IN PSAC_CHANNEL Channel,
|
|||
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 @@ RawChannelIBufferIsFull(IN PSAC_CHANNEL Channel,
|
|||
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 @@ NTAPI
|
|||
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 @@ RawChannelIWrite(IN PSAC_CHANNEL Channel,
|
|||
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);
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -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 @@ ULONG
|
|||
);
|
||||
|
||||
typedef
|
||||
CHAR
|
||||
WCHAR
|
||||
(NTAPI *PSAC_CHANNEL_IREAD_LAST)(
|
||||
IN struct _SAC_CHANNEL* Channel
|
||||
);
|
||||
|
@ -775,7 +776,7 @@ ChannelIWrite(
|
|||
IN ULONG BufferSize
|
||||
);
|
||||
|
||||
UCHAR
|
||||
WCHAR
|
||||
NTAPI
|
||||
ChannelIReadLast(
|
||||
IN PSAC_CHANNEL Channel
|
||||
|
@ -864,7 +865,7 @@ RawChannelIBufferLength(
|
|||
IN PSAC_CHANNEL Channel
|
||||
);
|
||||
|
||||
CHAR
|
||||
WCHAR
|
||||
NTAPI
|
||||
RawChannelIReadLast(
|
||||
IN PSAC_CHANNEL Channel
|
||||
|
@ -878,9 +879,106 @@ RawChannelIWrite(
|
|||
IN ULONG BufferSize
|
||||
);
|
||||
|
||||
//
|
||||
// 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(
|
||||
|
@ -923,6 +1021,102 @@ 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
|
||||
);
|
||||
|
||||
//
|
||||
// External data
|
||||
//
|
||||
|
@ -933,7 +1127,9 @@ extern LONG CurrentChannelRefCount;
|
|||
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 @@ ChannelGetIndex(IN PSAC_CHANNEL Channel)
|
|||
/* 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;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,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
|
||||
SacTranslateUnicodeToUtf8(IN PWCHAR SourceBuffer,
|
||||
|
@ -151,8 +201,76 @@ SacFormatMessage(IN PWCHAR FormattedString,
|
|||
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
|
||||
|
@ -1105,6 +1223,25 @@ SerialBufferGetChar(OUT PCHAR Char)
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -1131,16 +1268,6 @@ InvokeUserModeService(
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
SacTranslateUtf8ToUnicode(
|
||||
IN CHAR Utf8Char,
|
||||
IN PCHAR UnicodeBuffer,
|
||||
OUT PCHAR Utf8Value
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
TranslateMachineInformationText(
|
||||
IN PWCHAR Buffer)
|
||||
|
@ -1159,14 +1286,6 @@ CopyAndInsertStringAtInterval(
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ULONG
|
||||
GetMessageLineCount(
|
||||
IN ULONG MessageIndex
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
RegisterSacCmdEvent(
|
||||
IN PVOID Object,
|
||||
|
|
|
@ -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 ********************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
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
|
||||
VTUTF8ChannelCreate(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
VTUTF8ChannelOInit(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
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
|
||||
VTUTF8ChannelDestroy(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
VTUTF8ChannelCreate(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
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 @@ VTUTF8ChannelORead(
|
|||
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 @@ VTUTF8ChannelScanForNumber(
|
|||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
VTUTF8ChannelAnsiDispatch(
|
||||
IN NTSTATUS Status,
|
||||
IN ULONG AnsiCode,
|
||||
|
@ -72,6 +137,7 @@ VTUTF8ChannelAnsiDispatch(
|
|||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
VTUTF8ChannelProcessAttributes(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN UCHAR Attribute
|
||||
|
@ -80,24 +146,8 @@ VTUTF8ChannelProcessAttributes(
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ULONG
|
||||
VTUTF8ChannelGetIBufferIndex(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID
|
||||
VTUTF8ChannelSetIBufferIndex(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN ULONG BufferIndex
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
VTUTF8ChannelConsumeEscapeSequence(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR String
|
||||
|
@ -107,6 +157,7 @@ VTUTF8ChannelConsumeEscapeSequence(
|
|||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
VTUTF8ChannelOFlush(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
|
@ -115,67 +166,240 @@ VTUTF8ChannelOFlush(
|
|||
}
|
||||
|
||||
NTSTATUS
|
||||
VTUTF8ChannelIRead(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
IN PULONG ReturnBufferSize
|
||||
)
|
||||
NTAPI
|
||||
VTUTF8ChannelOWrite2(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR String,
|
||||
IN ULONG Size)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
VTUTF8ChannelIBufferIsFull(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
OUT PBOOLEAN BufferStatus
|
||||
)
|
||||
NTAPI
|
||||
VTUTF8ChannelOEcho(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR String,
|
||||
IN ULONG Size)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
WCHAR
|
||||
VTUTF8ChannelIReadLast(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
VTUTF8ChannelOWrite(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR String,
|
||||
IN ULONG Length)
|
||||
{
|
||||
return 0;
|
||||
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
|
||||
VTUTF8ChannelIBufferLength(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
VTUTF8ChannelGetIBufferIndex(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return 0;
|
||||
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
|
||||
VTUTF8ChannelOWrite2(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR String,
|
||||
IN ULONG Size
|
||||
)
|
||||
NTAPI
|
||||
VTUTF8ChannelIRead(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
IN PULONG ReturnBufferSize)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
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
|
||||
VTUTF8ChannelIWrite(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize
|
||||
)
|
||||
NTAPI
|
||||
VTUTF8ChannelIBufferIsFull(IN PSAC_CHANNEL Channel,
|
||||
OUT PBOOLEAN BufferStatus)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
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
|
||||
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
|
||||
VTUTF8ChannelOWrite(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR String,
|
||||
IN ULONG Length
|
||||
)
|
||||
NTAPI
|
||||
VTUTF8ChannelIWrite(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 @@ The SAC is unavailable, it was directly unloaded.
|
|||
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 @@ SAC failed to retrieve the task list.
|
|||
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 @@ Language=English
|
|||
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 @@ That process has been killed and is being cleaned up by the system.
|
|||
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 @@ Error: Could not find a channel with that name.
|
|||
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 @@ SAC preparing to shutdown the system.
|
|||
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 @@ cmd Create a Command Prompt channel.
|
|||
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 @@ Error: The SAC Command Console session failed to be created.
|
|||
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 @@ EVENT: The CMD command is unavailable.
|
|||
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 @@ not yet initialized%0
|
|||
MessageId=154
|
||||
SymbolicName=SACDRV_154
|
||||
Language=English
|
||||
The maximum number of channels has been reached.
|
||||
The maximum number of channels has been reached.
|
||||
.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue