mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 17:10:22 +00:00
[SACDRV]: Implement DoCrashCommand.
[SACDRV]: Cleanups and fixes. You can now use "Shutdown", "crashdump" and "restart" in the !SAC and the commands work as expected. [SACDRV]: Implement GetTListInfo and DoTlistCommand. PrintTListInfo is next to actually show the output. svn path=/trunk/; revision=59838
This commit is contained in:
parent
12796b070e
commit
08c5f648ed
5 changed files with 408 additions and 74 deletions
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
PWCHAR GlobalBuffer;
|
PVOID GlobalBuffer;
|
||||||
ULONG GlobalBufferSize;
|
ULONG GlobalBufferSize;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
@ -57,30 +57,269 @@ DoChannelSwitchByIndexCommand(
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _SAC_SYSTEM_INFORMATION
|
||||||
|
{
|
||||||
|
SYSTEM_BASIC_INFORMATION BasicInfo;
|
||||||
|
SYSTEM_TIMEOFDAY_INFORMATION TimeInfo;
|
||||||
|
SYSTEM_FILECACHE_INFORMATION CacheInfo;
|
||||||
|
SYSTEM_PERFORMANCE_INFORMATION PerfInfo;
|
||||||
|
ULONG RemainingSize;
|
||||||
|
ULONG ProcessDataOffset;
|
||||||
|
// SYSTEM_PAGEFILE_INFORMATION PageFileInfo;
|
||||||
|
// SYSTEM_PROCESS_INFORMATINO ProcessInfo;
|
||||||
|
} SAC_SYSTEM_INFORMATION, *PSAC_SYSTEM_INFORMATION;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
GetTListInfo(
|
NTAPI
|
||||||
IN PVOID TListData,
|
GetTListInfo(IN PSAC_SYSTEM_INFORMATION SacInfo,
|
||||||
IN ULONG InputSize,
|
IN ULONG InputSize,
|
||||||
IN ULONG TotalSize
|
OUT PULONG TotalSize)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
NTSTATUS Status;
|
||||||
|
ULONG BufferLength, ReturnLength, RemainingSize;
|
||||||
|
PSYSTEM_PAGEFILE_INFORMATION PageFileInfo;
|
||||||
|
PSYSTEM_PROCESS_INFORMATION ProcessInfo;
|
||||||
|
ULONG_PTR P;
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n");
|
||||||
|
|
||||||
|
/* Assume failure */
|
||||||
|
*TotalSize = 0;
|
||||||
|
|
||||||
|
/* Bail out if the buffer is way too small */
|
||||||
|
if (InputSize < 4)
|
||||||
|
{
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, no memory.\n");
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure it's at least big enough to hold the static structure */
|
||||||
|
BufferLength = InputSize - sizeof(SAC_SYSTEM_INFORMATION);
|
||||||
|
if ((INT)InputSize - sizeof(SAC_SYSTEM_INFORMATION) < 0)
|
||||||
|
{
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, no memory (2).\n");
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Query the time */
|
||||||
|
Status = ZwQuerySystemInformation(SystemTimeOfDayInformation,
|
||||||
|
&SacInfo->TimeInfo,
|
||||||
|
sizeof(SacInfo->TimeInfo),
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, error.\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Query basic information */
|
||||||
|
Status = ZwQuerySystemInformation(SystemBasicInformation,
|
||||||
|
&SacInfo->BasicInfo,
|
||||||
|
sizeof(SacInfo->BasicInfo),
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, error (2).\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now query the pagefile information, which comes right after */
|
||||||
|
P = (ULONG_PTR)(SacInfo + 1);
|
||||||
|
PageFileInfo = (PSYSTEM_PAGEFILE_INFORMATION)P;
|
||||||
|
Status = ZwQuerySystemInformation(SystemPageFileInformation,
|
||||||
|
PageFileInfo,
|
||||||
|
BufferLength,
|
||||||
|
&ReturnLength);
|
||||||
|
if (!NT_SUCCESS(Status) || !(ReturnLength))
|
||||||
|
{
|
||||||
|
/* We failed -- is it because our buffer was too small? */
|
||||||
|
if (BufferLength < ReturnLength)
|
||||||
|
{
|
||||||
|
/* Bail out */
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, no memory(5).\n");
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some other reason, assume the buffer is now full */
|
||||||
|
SacInfo->RemainingSize = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is the leftover data */
|
||||||
|
SacInfo->RemainingSize = InputSize - BufferLength;
|
||||||
|
|
||||||
|
/* This much has now been consumed, and where we are now */
|
||||||
|
BufferLength -= ReturnLength;
|
||||||
|
P += ReturnLength;
|
||||||
|
|
||||||
|
/* Are we out of memory? */
|
||||||
|
if ((LONG)BufferLength < 0)
|
||||||
|
{
|
||||||
|
/* Bail out */
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, no memory(3).\n");
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All good, loop the pagefile data now */
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
/* Is the pagefile name too big to fit? */
|
||||||
|
if (PageFileInfo->PageFileName.Length > (LONG)BufferLength)
|
||||||
|
{
|
||||||
|
/* Bail out */
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, error(3).\n");
|
||||||
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the name into our own buffer */
|
||||||
|
RtlCopyMemory((PVOID)P,
|
||||||
|
PageFileInfo->PageFileName.Buffer,
|
||||||
|
PageFileInfo->PageFileName.Length);
|
||||||
|
PageFileInfo->PageFileName.Buffer = (PWCHAR)P;
|
||||||
|
|
||||||
|
/* Update buffer lengths and offset */
|
||||||
|
BufferLength -= PageFileInfo->PageFileName.Length;
|
||||||
|
P += PageFileInfo->PageFileName.Length;
|
||||||
|
|
||||||
|
/* Are we out of memory? */
|
||||||
|
if ((LONG)BufferLength < 0)
|
||||||
|
{
|
||||||
|
/* Bail out */
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, no memory(4).\n");
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this was the only pagefile, break out */
|
||||||
|
if (!PageFileInfo->NextEntryOffset) break;
|
||||||
|
|
||||||
|
/* Otherwise, move to the next one */
|
||||||
|
PageFileInfo = (PVOID)((ULONG_PTR)PageFileInfo +
|
||||||
|
PageFileInfo->NextEntryOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next, query the file cache information */
|
||||||
|
Status = ZwQuerySystemInformation(SystemFileCacheInformation,
|
||||||
|
&SacInfo->CacheInfo,
|
||||||
|
sizeof(SacInfo->CacheInfo),
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, error (4).\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And then the performance information */
|
||||||
|
Status = ZwQuerySystemInformation(SystemPerformanceInformation,
|
||||||
|
&SacInfo->PerfInfo,
|
||||||
|
sizeof(SacInfo->PerfInfo),
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, error(5).\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally, align the buffer to query process and thread information */
|
||||||
|
P = ALIGN_UP(P, SYSTEM_PROCESS_INFORMATION);
|
||||||
|
RemainingSize = (ULONG_PTR)SacInfo + InputSize - P;
|
||||||
|
|
||||||
|
/* Are we out of memory? */
|
||||||
|
if ((LONG)RemainingSize < 0)
|
||||||
|
{
|
||||||
|
/* Bail out */
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, no memory (6).\n");
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now query the processes and threads */
|
||||||
|
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)P;
|
||||||
|
Status = ZwQuerySystemInformation(SystemProcessInformation,
|
||||||
|
ProcessInfo,
|
||||||
|
RemainingSize,
|
||||||
|
&ReturnLength);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, error(6).\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The first process name will be right after this buffer */
|
||||||
|
P += ReturnLength;
|
||||||
|
|
||||||
|
/* The caller should look for process info over here */
|
||||||
|
SacInfo->ProcessDataOffset = InputSize - RemainingSize;
|
||||||
|
|
||||||
|
/* This is how much buffer data we have left -- are we out? */
|
||||||
|
BufferLength = RemainingSize - ReturnLength;
|
||||||
|
if ((LONG)BufferLength < 0)
|
||||||
|
{
|
||||||
|
/* Bail out */
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, no memory(7).\n");
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All good and ready to parse the process and thread list */
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
/* Does the process have a name? */
|
||||||
|
if (ProcessInfo->ImageName.Buffer)
|
||||||
|
{
|
||||||
|
/* Is the process name too big to fit? */
|
||||||
|
if ((LONG)BufferLength < ProcessInfo->ImageName.Length)
|
||||||
|
{
|
||||||
|
/* Bail out */
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, error(7).\n");
|
||||||
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the name into our own buffer */
|
||||||
|
RtlCopyMemory((PVOID)P,
|
||||||
|
ProcessInfo->ImageName.Buffer,
|
||||||
|
ProcessInfo->ImageName.Length);
|
||||||
|
ProcessInfo->ImageName.Buffer = (PWCHAR)P;
|
||||||
|
|
||||||
|
/* Update buffer lengths and offset */
|
||||||
|
BufferLength -= ProcessInfo->ImageName.Length;
|
||||||
|
P += ProcessInfo->ImageName.Length;
|
||||||
|
|
||||||
|
/* Are we out of memory? */
|
||||||
|
if ((LONG)BufferLength < 0)
|
||||||
|
{
|
||||||
|
/* Bail out */
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting, no memory(8).\n");
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this was the only process, break out */
|
||||||
|
if (!ProcessInfo->NextEntryOffset) break;
|
||||||
|
|
||||||
|
/* Otherwise, move to the next one */
|
||||||
|
ProcessInfo = (PVOID)((ULONG_PTR)ProcessInfo +
|
||||||
|
ProcessInfo->NextEntryOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All done! */
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting.\n");
|
||||||
|
*TotalSize = InputSize - BufferLength;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
PrintTListInfo(
|
NTAPI
|
||||||
IN PVOID TListData
|
PrintTListInfo(IN PSAC_SYSTEM_INFORMATION SacInfo)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Testing: %d %d %I64d\n",
|
||||||
|
SacInfo->BasicInfo.NumberOfPhysicalPages,
|
||||||
|
SacInfo->PerfInfo.AvailablePages,
|
||||||
|
SacInfo->TimeInfo.BootTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
PutMore(
|
NTAPI
|
||||||
OUT PBOOLEAN ScreenFull
|
PutMore(OUT PBOOLEAN ScreenFull)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
*ScreenFull = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
|
@ -167,144 +406,234 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoFullInfoCommand(VOID)
|
DoFullInfoCommand(VOID)
|
||||||
{
|
{
|
||||||
|
/* Flip the flag */
|
||||||
|
GlobalDoThreads = !GlobalDoThreads;
|
||||||
|
|
||||||
|
/* Print out the new state */
|
||||||
|
SacPutSimpleMessage(GlobalDoThreads ? 8 : 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoPagingCommand(VOID)
|
DoPagingCommand(VOID)
|
||||||
{
|
{
|
||||||
|
/* Flip the flag */
|
||||||
|
GlobalPagingNeeded = !GlobalPagingNeeded;
|
||||||
|
|
||||||
|
/* Print out the new state */
|
||||||
|
SacPutSimpleMessage(GlobalPagingNeeded ? 10 : 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoSetTimeCommand(IN PCHAR InputTime)
|
DoSetTimeCommand(IN PCHAR InputTime)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Entering\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoKillCommand(IN PCHAR KillString)
|
DoKillCommand(IN PCHAR KillString)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Entering\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoLowerPriorityCommand(IN PCHAR PrioString)
|
DoLowerPriorityCommand(IN PCHAR PrioString)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Entering\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoRaisePriorityCommand(IN PCHAR PrioString)
|
DoRaisePriorityCommand(IN PCHAR PrioString)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Entering\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoLimitMemoryCommand(IN PCHAR LimitString)
|
DoLimitMemoryCommand(IN PCHAR LimitString)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Entering\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoCrashCommand(VOID)
|
DoCrashCommand(VOID)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "SAC DoCrashCommand: Entering.\n");
|
||||||
|
|
||||||
|
/* Crash the machine */
|
||||||
|
KeBugCheckEx(MANUALLY_INITIATED_CRASH, 0, 0, 0, 0);
|
||||||
|
__debugbreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoMachineInformationCommand(VOID)
|
DoMachineInformationCommand(VOID)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Entering\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoChannelCommand(IN PCHAR ChannelString)
|
DoChannelCommand(IN PCHAR ChannelString)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Entering\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoCmdCommand(IN PCHAR InputString)
|
DoCmdCommand(IN PCHAR InputString)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Entering\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoLockCommand(VOID)
|
DoLockCommand(VOID)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Entering\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PRINT_HELP_MESSAGE(x) \
|
FORCEINLINE
|
||||||
{ \
|
BOOLEAN
|
||||||
Count += NewCount; \
|
PrintHelpMessage(IN ULONG MessageId,
|
||||||
NewCount = GetMessageLineCount(x); \
|
IN OUT PULONG Count)
|
||||||
if ( (NewCount + Count) > SAC_VTUTF8_COL_HEIGHT) \
|
{
|
||||||
{ \
|
BOOLEAN ScreenFull;
|
||||||
PutMore(&ScreenFull); \
|
ULONG NewCount;
|
||||||
if (ScreenFull) return; \
|
|
||||||
Count = 0; \
|
/* Get the amount of lines this message will take */
|
||||||
} \
|
NewCount = GetMessageLineCount(MessageId);
|
||||||
SacPutSimpleMessage(x); \
|
if ((NewCount + *Count) > SAC_VTUTF8_ROW_HEIGHT)
|
||||||
|
{
|
||||||
|
/* We are going to overflow the screen, wait for input */
|
||||||
|
PutMore(&ScreenFull);
|
||||||
|
if (ScreenFull) return FALSE;
|
||||||
|
*Count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print out the message and update the amount of lines printed */
|
||||||
|
SacPutSimpleMessage(MessageId);
|
||||||
|
*Count += NewCount;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoHelpCommand(VOID)
|
DoHelpCommand(VOID)
|
||||||
{
|
{
|
||||||
ULONG NewCount = 0, Count = 0;
|
ULONG Count = 0;
|
||||||
BOOLEAN ScreenFull = FALSE;
|
|
||||||
|
|
||||||
PRINT_HELP_MESSAGE(112);
|
/* Print out all the help messages */
|
||||||
PRINT_HELP_MESSAGE(12);
|
if (!PrintHelpMessage(112, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(13);
|
if (!PrintHelpMessage(12, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(14);
|
if (!PrintHelpMessage(13, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(15);
|
if (!PrintHelpMessage(14, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(16);
|
if (!PrintHelpMessage(15, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(31);
|
if (!PrintHelpMessage(16, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(18);
|
if (!PrintHelpMessage(31, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(19);
|
if (!PrintHelpMessage(18, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(32);
|
if (!PrintHelpMessage(19, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(20);
|
if (!PrintHelpMessage(32, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(21);
|
if (!PrintHelpMessage(20, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(22);
|
if (!PrintHelpMessage(21, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(23);
|
if (!PrintHelpMessage(22, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(24);
|
if (!PrintHelpMessage(23, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(25);
|
if (!PrintHelpMessage(24, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(27);
|
if (!PrintHelpMessage(25, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(28);
|
if (!PrintHelpMessage(27, &Count)) return;
|
||||||
PRINT_HELP_MESSAGE(29);
|
if (!PrintHelpMessage(28, &Count)) return;
|
||||||
|
if (!PrintHelpMessage(29, &Count)) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoGetNetInfo(IN BOOLEAN DoPrint)
|
DoGetNetInfo(IN BOOLEAN DoPrint)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Entering\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoSetIpAddressCommand(IN PCHAR IpString)
|
DoSetIpAddressCommand(IN PCHAR IpString)
|
||||||
{
|
{
|
||||||
|
SAC_DBG(1, "Entering\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DoTlistCommand(VOID)
|
DoTlistCommand(VOID)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PVOID NewGlobalBuffer;
|
||||||
|
ULONG Size;
|
||||||
|
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoTlistCommand: Entering.\n");
|
||||||
|
|
||||||
|
/* Check if a global buffer already exists */
|
||||||
|
if (!GlobalBuffer)
|
||||||
|
{
|
||||||
|
/* It doesn't, allocate one */
|
||||||
|
GlobalBuffer = SacAllocatePool(4096, GLOBAL_BLOCK_TAG);
|
||||||
|
if (GlobalBuffer)
|
||||||
|
{
|
||||||
|
/* Remember its current size */
|
||||||
|
GlobalBufferSize = 4096;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Out of memory, bail out */
|
||||||
|
SacPutSimpleMessage(11);
|
||||||
|
SAC_DBG(1, "SAC DoTlistCommand: Exiting.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop as long as the buffer is too small */
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
/* Get the process list */
|
||||||
|
Status = GetTListInfo(GlobalBuffer, GlobalBufferSize, &Size);
|
||||||
|
if ((Status != STATUS_NO_MEMORY) &&
|
||||||
|
(Status != STATUS_INFO_LENGTH_MISMATCH))
|
||||||
|
{
|
||||||
|
/* It fits! Bail out */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We need a new bigger buffer */
|
||||||
|
NewGlobalBuffer = SacAllocatePool(GlobalBufferSize + 4096,
|
||||||
|
GLOBAL_BLOCK_TAG);
|
||||||
|
if (!NewGlobalBuffer)
|
||||||
|
{
|
||||||
|
/* Out of memory, bail out */
|
||||||
|
SacPutSimpleMessage(11);
|
||||||
|
SAC_DBG(1, "SAC DoTlistCommand: Exiting.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the old one, update state */
|
||||||
|
SacFreePool(GlobalBuffer);
|
||||||
|
GlobalBufferSize += 4096;
|
||||||
|
GlobalBuffer = NewGlobalBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did we get here because we have the whole list? */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Nope, print out a failure message */
|
||||||
|
SacPutSimpleMessage(68);
|
||||||
|
swprintf(GlobalBuffer, GetMessage(48), Status);
|
||||||
|
SacPutString(GlobalBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Yep, print out the list */
|
||||||
|
PrintTListInfo(GlobalBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
SAC_DBG(1, "SAC DoTlistCommand: Exiting.\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ PSAC_CHANNEL ExecutePostConsumerCommandData;
|
||||||
BOOLEAN InputInEscape, InputInEscTab, ConMgrLastCharWasCR;
|
BOOLEAN InputInEscape, InputInEscTab, ConMgrLastCharWasCR;
|
||||||
CHAR InputBuffer[80];
|
CHAR InputBuffer[80];
|
||||||
|
|
||||||
|
BOOLEAN GlobalPagingNeeded, GlobalDoThreads;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -447,11 +449,6 @@ ConMgrChannelOWrite(IN PSAC_CHANNEL Channel,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Shutdown 1
|
|
||||||
#define Restart 3
|
|
||||||
#define Nothing 0
|
|
||||||
BOOLEAN GlobalPagingNeeded;
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ConMgrProcessInputLine(VOID)
|
ConMgrProcessInputLine(VOID)
|
||||||
|
@ -566,7 +563,7 @@ ConMgrProcessInputLine(VOID)
|
||||||
}
|
}
|
||||||
else if ((InputBuffer[0] != '\n') && (InputBuffer[0] != ANSI_NULL))
|
else if ((InputBuffer[0] != '\n') && (InputBuffer[0] != ANSI_NULL))
|
||||||
{
|
{
|
||||||
SacPutSimpleMessage(105);
|
SacPutSimpleMessage(SAC_UNKNOWN_COMMAND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,25 +848,25 @@ ConMgrWorkerProcessEvents(IN PSAC_DEVICE_EXTENSION DeviceExtension)
|
||||||
ConMgrSerialPortConsumer();
|
ConMgrSerialPortConsumer();
|
||||||
switch (ExecutePostConsumerCommand)
|
switch (ExecutePostConsumerCommand)
|
||||||
{
|
{
|
||||||
case 1:
|
case Restart:
|
||||||
/* A reboot was sent, do it */
|
/* A reboot was sent, do it */
|
||||||
DoRebootCommand(FALSE);
|
DoRebootCommand(FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case Close:
|
||||||
/* A close was sent, do it */
|
/* A close was sent, do it */
|
||||||
ChanMgrCloseChannel(ExecutePostConsumerCommandData);
|
ChanMgrCloseChannel(ExecutePostConsumerCommandData);
|
||||||
ChanMgrReleaseChannel(ExecutePostConsumerCommandData);
|
ChanMgrReleaseChannel(ExecutePostConsumerCommandData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case Shutdown:
|
||||||
/* A shutdown was sent, do it */
|
/* A shutdown was sent, do it */
|
||||||
DoRebootCommand(TRUE);
|
DoRebootCommand(TRUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the serial port consumer state */
|
/* Clear the serial port consumer state */
|
||||||
ExecutePostConsumerCommand = 0;
|
ExecutePostConsumerCommand = Nothing;
|
||||||
ExecutePostConsumerCommandData = NULL;
|
ExecutePostConsumerCommandData = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,6 +261,17 @@ typedef enum _SAC_ANSI_DISPATCH
|
||||||
SacAnsiClearBoldAttribute
|
SacAnsiClearBoldAttribute
|
||||||
} SAC_ANSI_DISPATCH;
|
} SAC_ANSI_DISPATCH;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Commands that the consumer and producer share
|
||||||
|
//
|
||||||
|
typedef enum _SAC_POST_COMMANDS
|
||||||
|
{
|
||||||
|
Nothing,
|
||||||
|
Shutdown,
|
||||||
|
Close,
|
||||||
|
Restart
|
||||||
|
} SAC_POST_COMMANDS;
|
||||||
|
|
||||||
//
|
//
|
||||||
// SAC supports 3 different channel output types
|
// SAC supports 3 different channel output types
|
||||||
//
|
//
|
||||||
|
@ -1232,7 +1243,7 @@ extern LONG CurrentChannelRefCount;
|
||||||
extern PCHAR SerialPortBuffer;
|
extern PCHAR SerialPortBuffer;
|
||||||
extern LONG SerialPortConsumerIndex, SerialPortProducerIndex;
|
extern LONG SerialPortConsumerIndex, SerialPortProducerIndex;
|
||||||
extern PCHAR Utf8ConversionBuffer;
|
extern PCHAR Utf8ConversionBuffer;
|
||||||
extern BOOLEAN GlobalPagingNeeded;
|
extern BOOLEAN GlobalPagingNeeded, GlobalDoThreads;
|
||||||
extern ULONG Utf8ConversionBufferSize;
|
extern ULONG Utf8ConversionBufferSize;
|
||||||
extern BOOLEAN CommandConsoleLaunchingEnabled;
|
extern BOOLEAN CommandConsoleLaunchingEnabled;
|
||||||
|
|
||||||
|
|
|
@ -881,7 +881,6 @@ VTUTF8ChannelOFlush(IN PSAC_CHANNEL Channel)
|
||||||
if (Utf8Count)
|
if (Utf8Count)
|
||||||
{
|
{
|
||||||
/* Write it out on the wire */
|
/* Write it out on the wire */
|
||||||
SAC_DBG(1, "Row: %d\tCol : %d\t\tValue : (%c) -> (%c)\n", R, C, *TmpBuffer, *Utf8ConversionBuffer);
|
|
||||||
Status = ConMgrWriteData(Channel, Utf8ConversionBuffer, Utf8Count);
|
Status = ConMgrWriteData(Channel, Utf8ConversionBuffer, Utf8Count);
|
||||||
if (!NT_SUCCESS(Status)) goto Quickie;
|
if (!NT_SUCCESS(Status)) goto Quickie;
|
||||||
}
|
}
|
||||||
|
@ -949,7 +948,6 @@ VTUTF8ChannelOWrite2(IN PSAC_CHANNEL Channel,
|
||||||
{
|
{
|
||||||
/* Check what the character is */
|
/* Check what the character is */
|
||||||
pwch = &String[i];
|
pwch = &String[i];
|
||||||
SAC_DBG(1, "Writing on VT-UTF8: (%lx)\n", *pwch);
|
|
||||||
switch (*pwch)
|
switch (*pwch)
|
||||||
{
|
{
|
||||||
/* It's an escape sequence... */
|
/* It's an escape sequence... */
|
||||||
|
@ -1003,7 +1001,7 @@ VTUTF8ChannelOWrite2(IN PSAC_CHANNEL Channel,
|
||||||
|
|
||||||
/* Now we're left with the before-last row, zero it out */
|
/* Now we're left with the before-last row, zero it out */
|
||||||
ASSERT(R == (SAC_VTUTF8_ROW_HEIGHT - 1));
|
ASSERT(R == (SAC_VTUTF8_ROW_HEIGHT - 1));
|
||||||
RtlZeroMemory(&Cursor[R], sizeof(Cursor[R]));
|
RtlZeroMemory(&Cursor->Cell[R], sizeof(Cursor->Cell[R]));
|
||||||
|
|
||||||
/* Reset the row back by one */
|
/* Reset the row back by one */
|
||||||
Channel->CursorRow--;
|
Channel->CursorRow--;
|
||||||
|
@ -1178,7 +1176,6 @@ VTUTF8ChannelOWrite(IN PSAC_CHANNEL Channel,
|
||||||
CHECK_PARAMETER2(String);
|
CHECK_PARAMETER2(String);
|
||||||
|
|
||||||
/* Call the lower level function */
|
/* Call the lower level function */
|
||||||
SAC_DBG(1, "Writing on VT-UTF8: %S\n", String);
|
|
||||||
Status = VTUTF8ChannelOWrite2(Channel, (PWCHAR)String, Length / sizeof(WCHAR));
|
Status = VTUTF8ChannelOWrite2(Channel, (PWCHAR)String, Length / sizeof(WCHAR));
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
|
@ -513,7 +513,7 @@ Computer identification information is unavailable.
|
||||||
.
|
.
|
||||||
|
|
||||||
MessageId=105
|
MessageId=105
|
||||||
SymbolicName=SACDRV_105
|
SymbolicName=SAC_UNKNOWN_COMMAND
|
||||||
Language=English
|
Language=English
|
||||||
Unrecognized command. Try the 'help' command for more details.
|
Unrecognized command. Try the 'help' command for more details.
|
||||||
.
|
.
|
||||||
|
|
Loading…
Reference in a new issue