Author: ion Date: Mon Aug 26 19:45:16 2013 New Revision: 59838
URL: http://svn.reactos.org/svn/reactos?rev=59838&view=rev Log: [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.
Modified: trunk/reactos/drivers/sac/driver/concmd.c trunk/reactos/drivers/sac/driver/conmgr.c trunk/reactos/drivers/sac/driver/sacdrv.h trunk/reactos/drivers/sac/driver/vtutf8chan.c trunk/reactos/include/reactos/mc/sacmsg.mc
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 26 19:45:16 2013 @@ -12,7 +12,7 @@
/* GLOBALS *******************************************************************/
-PWCHAR GlobalBuffer; +PVOID GlobalBuffer; ULONG GlobalBufferSize;
/* FUNCTIONS *****************************************************************/ @@ -57,30 +57,269 @@ 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 -GetTListInfo( - IN PVOID TListData, - IN ULONG InputSize, - IN ULONG TotalSize - ) -{ - return STATUS_NOT_IMPLEMENTED; -} - -VOID -PrintTListInfo( - IN PVOID TListData - ) -{ - -} - -VOID -PutMore( - OUT PBOOLEAN ScreenFull - ) -{ - +NTAPI +GetTListInfo(IN PSAC_SYSTEM_INFORMATION SacInfo, + IN ULONG InputSize, + OUT PULONG TotalSize) +{ + 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 +NTAPI +PrintTListInfo(IN PSAC_SYSTEM_INFORMATION SacInfo) +{ + SAC_DBG(1, "Testing: %d %d %I64d\n", + SacInfo->BasicInfo.NumberOfPhysicalPages, + SacInfo->PerfInfo.AvailablePages, + SacInfo->TimeInfo.BootTime); +} + +VOID +NTAPI +PutMore(OUT PBOOLEAN ScreenFull) +{ + *ScreenFull = FALSE; }
BOOLEAN @@ -167,144 +406,234 @@ NTAPI DoFullInfoCommand(VOID) { - + /* Flip the flag */ + GlobalDoThreads = !GlobalDoThreads; + + /* Print out the new state */ + SacPutSimpleMessage(GlobalDoThreads ? 8 : 7); }
VOID NTAPI DoPagingCommand(VOID) { - + /* Flip the flag */ + GlobalPagingNeeded = !GlobalPagingNeeded; + + /* Print out the new state */ + SacPutSimpleMessage(GlobalPagingNeeded ? 10 : 9); }
VOID NTAPI DoSetTimeCommand(IN PCHAR InputTime) { - + SAC_DBG(1, "Entering\n"); }
VOID NTAPI DoKillCommand(IN PCHAR KillString) { - + SAC_DBG(1, "Entering\n"); }
VOID NTAPI DoLowerPriorityCommand(IN PCHAR PrioString) { - + SAC_DBG(1, "Entering\n"); }
VOID NTAPI DoRaisePriorityCommand(IN PCHAR PrioString) { - + SAC_DBG(1, "Entering\n"); }
VOID NTAPI DoLimitMemoryCommand(IN PCHAR LimitString) { - + SAC_DBG(1, "Entering\n"); }
VOID NTAPI DoCrashCommand(VOID) { - + SAC_DBG(1, "SAC DoCrashCommand: Entering.\n"); + + /* Crash the machine */ + KeBugCheckEx(MANUALLY_INITIATED_CRASH, 0, 0, 0, 0); + __debugbreak(); }
VOID NTAPI DoMachineInformationCommand(VOID) { - + SAC_DBG(1, "Entering\n"); }
VOID NTAPI DoChannelCommand(IN PCHAR ChannelString) { - + SAC_DBG(1, "Entering\n"); }
VOID NTAPI DoCmdCommand(IN PCHAR InputString) { - + SAC_DBG(1, "Entering\n"); }
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); \ + SAC_DBG(1, "Entering\n"); +} + +FORCEINLINE +BOOLEAN +PrintHelpMessage(IN ULONG MessageId, + IN OUT PULONG Count) +{ + BOOLEAN ScreenFull; + ULONG NewCount; + + /* Get the amount of lines this message will take */ + NewCount = GetMessageLineCount(MessageId); + 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 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); + ULONG Count = 0; + + /* Print out all the help messages */ + if (!PrintHelpMessage(112, &Count)) return; + if (!PrintHelpMessage(12, &Count)) return; + if (!PrintHelpMessage(13, &Count)) return; + if (!PrintHelpMessage(14, &Count)) return; + if (!PrintHelpMessage(15, &Count)) return; + if (!PrintHelpMessage(16, &Count)) return; + if (!PrintHelpMessage(31, &Count)) return; + if (!PrintHelpMessage(18, &Count)) return; + if (!PrintHelpMessage(19, &Count)) return; + if (!PrintHelpMessage(32, &Count)) return; + if (!PrintHelpMessage(20, &Count)) return; + if (!PrintHelpMessage(21, &Count)) return; + if (!PrintHelpMessage(22, &Count)) return; + if (!PrintHelpMessage(23, &Count)) return; + if (!PrintHelpMessage(24, &Count)) return; + if (!PrintHelpMessage(25, &Count)) return; + if (!PrintHelpMessage(27, &Count)) return; + if (!PrintHelpMessage(28, &Count)) return; + if (!PrintHelpMessage(29, &Count)) return; }
VOID NTAPI DoGetNetInfo(IN BOOLEAN DoPrint) { - + SAC_DBG(1, "Entering\n"); }
VOID NTAPI DoSetIpAddressCommand(IN PCHAR IpString) { - + SAC_DBG(1, "Entering\n"); }
VOID NTAPI 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"); +}
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 26 19:45:16 2013 @@ -30,6 +30,8 @@ BOOLEAN InputInEscape, InputInEscTab, ConMgrLastCharWasCR; CHAR InputBuffer[80];
+BOOLEAN GlobalPagingNeeded, GlobalDoThreads; + /* FUNCTIONS *****************************************************************/
VOID @@ -447,11 +449,6 @@ return Status; }
-#define Shutdown 1 -#define Restart 3 -#define Nothing 0 -BOOLEAN GlobalPagingNeeded; - VOID NTAPI ConMgrProcessInputLine(VOID) @@ -566,7 +563,7 @@ } else if ((InputBuffer[0] != '\n') && (InputBuffer[0] != ANSI_NULL)) { - SacPutSimpleMessage(105); + SacPutSimpleMessage(SAC_UNKNOWN_COMMAND); } }
@@ -851,25 +848,25 @@ ConMgrSerialPortConsumer(); switch (ExecutePostConsumerCommand) { - case 1: + case Restart: /* A reboot was sent, do it */ DoRebootCommand(FALSE); break;
- case 2: + case Close: /* A close was sent, do it */ ChanMgrCloseChannel(ExecutePostConsumerCommandData); ChanMgrReleaseChannel(ExecutePostConsumerCommandData); break;
- case 3: + case Shutdown: /* A shutdown was sent, do it */ DoRebootCommand(TRUE); break; }
/* Clear the serial port consumer state */ - ExecutePostConsumerCommand = 0; + ExecutePostConsumerCommand = Nothing; ExecutePostConsumerCommandData = NULL; } }
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 26 19:45:16 2013 @@ -262,6 +262,17 @@ } 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 // typedef enum _SAC_CHANNEL_TYPE @@ -1232,7 +1243,7 @@ extern PCHAR SerialPortBuffer; extern LONG SerialPortConsumerIndex, SerialPortProducerIndex; extern PCHAR Utf8ConversionBuffer; -extern BOOLEAN GlobalPagingNeeded; +extern BOOLEAN GlobalPagingNeeded, GlobalDoThreads; extern ULONG Utf8ConversionBufferSize; extern BOOLEAN CommandConsoleLaunchingEnabled;
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 26 19:45:16 2013 @@ -881,7 +881,6 @@ if (Utf8Count) { /* 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); if (!NT_SUCCESS(Status)) goto Quickie; } @@ -949,7 +948,6 @@ { /* Check what the character is */ pwch = &String[i]; - SAC_DBG(1, "Writing on VT-UTF8: (%lx)\n", *pwch); switch (*pwch) { /* It's an escape sequence... */ @@ -1003,7 +1001,7 @@
/* Now we're left with the before-last row, zero it out */ 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 */ Channel->CursorRow--; @@ -1178,7 +1176,6 @@ CHECK_PARAMETER2(String);
/* Call the lower level function */ - SAC_DBG(1, "Writing on VT-UTF8: %S\n", String); Status = VTUTF8ChannelOWrite2(Channel, (PWCHAR)String, Length / sizeof(WCHAR)); if (NT_SUCCESS(Status)) {
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 26 19:45:16 2013 @@ -513,7 +513,7 @@ .
MessageId=105 -SymbolicName=SACDRV_105 +SymbolicName=SAC_UNKNOWN_COMMAND Language=English Unrecognized command. Try the 'help' command for more details. .