Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642/* * PROJECT: ReactOS Drivers * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: drivers/sac/driver/concmd.c * PURPOSE: Driver for the Server Administration Console (SAC) for EMS * PROGRAMMERS: ReactOS Portable Systems Group */
/* INCLUDES *******************************************************************/
#include "sacdrv.h"
#include <ndk/exfuncs.h>
/* GLOBALS ********************************************************************/
PVOID GlobalBuffer;ULONG GlobalBufferSize;
/* FUNCTIONS ******************************************************************/
NTSTATUSDoChannelListCommand( VOID ){ return STATUS_NOT_IMPLEMENTED;}
NTSTATUSDoChannelCloseByNameCommand( IN PCHAR Count ){ return STATUS_NOT_IMPLEMENTED;}
NTSTATUSDoChannelCloseByIndexCommand( IN ULONG ChannelIndex ){ return STATUS_NOT_IMPLEMENTED;}
NTSTATUSDoChannelSwitchByNameCommand( IN PCHAR Count ){ return STATUS_NOT_IMPLEMENTED;}
NTSTATUSDoChannelSwitchByIndexCommand( IN ULONG ChannelIndex ){ 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_INFORMATION ProcessInfo;} SAC_SYSTEM_INFORMATION, *PSAC_SYSTEM_INFORMATION;
NTSTATUSNTAPIGetTListInfo(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 (InputSize < sizeof(SAC_SYSTEM_INFORMATION)) { 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;}
VOIDNTAPIPrintTListInfo(IN PSAC_SYSTEM_INFORMATION SacInfo){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Testing: %d %d %I64d\n", SacInfo->BasicInfo.NumberOfPhysicalPages, SacInfo->PerfInfo.AvailablePages, SacInfo->TimeInfo.BootTime);}
VOIDNTAPIPutMore(OUT PBOOLEAN ScreenFull){ *ScreenFull = FALSE;}
BOOLEANRetrieveIpAddressFromString( IN PWCHAR IpString, OUT PULONG IpAddress ){ return FALSE;}
NTSTATUSCallQueryIPIOCTL( IN HANDLE DriverHandle, IN PVOID DriverObject, IN HANDLE WaitEvent, IN PIO_STATUS_BLOCK IoStatusBlock, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN PrintMessage, OUT PBOOLEAN MessagePrinted ){ return STATUS_NOT_IMPLEMENTED;}
VOIDNTAPIDoRebootCommand(IN BOOLEAN Reboot){ LARGE_INTEGER Timeout, TickCount; NTSTATUS Status; KEVENT Event; SAC_DBG(SAC_DBG_ENTRY_EXIT, "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");}
VOIDNTAPIDoFullInfoCommand(VOID){ /* Flip the flag */ GlobalDoThreads = !GlobalDoThreads;
/* Print out the new state */ SacPutSimpleMessage(GlobalDoThreads ? 8 : 7);}
VOIDNTAPIDoPagingCommand(VOID){ /* Flip the flag */ GlobalPagingNeeded = !GlobalPagingNeeded;
/* Print out the new state */ SacPutSimpleMessage(GlobalPagingNeeded ? 10 : 9);}
VOIDNTAPIDoSetTimeCommand(IN PCHAR InputTime){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");}
VOIDNTAPIDoKillCommand(IN PCHAR KillString){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");}
VOIDNTAPIDoLowerPriorityCommand(IN PCHAR PrioString){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");}
VOIDNTAPIDoRaisePriorityCommand(IN PCHAR PrioString){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");}
VOIDNTAPIDoLimitMemoryCommand(IN PCHAR LimitString){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");}
VOIDNTAPIDoCrashCommand(VOID){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoCrashCommand: Entering.\n");
/* Crash the machine */ KeBugCheckEx(MANUALLY_INITIATED_CRASH, 0, 0, 0, 0); __debugbreak();}
VOIDNTAPIDoMachineInformationCommand(VOID){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");}
VOIDNTAPIDoChannelCommand(IN PCHAR ChannelString){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");}
VOIDNTAPIDoCmdCommand(IN PCHAR InputString){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");}
VOIDNTAPIDoLockCommand(VOID){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");}
FORCEINLINEBOOLEANPrintHelpMessage(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;}
VOIDNTAPIDoHelpCommand(VOID){ 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;}
VOIDNTAPIDoGetNetInfo(IN BOOLEAN DoPrint){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");}
VOIDNTAPIDoSetIpAddressCommand(IN PCHAR IpString){ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");}
VOIDNTAPIDoTlistCommand(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(SAC_DBG_ENTRY_EXIT, "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(SAC_DBG_ENTRY_EXIT, "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(SAC_DBG_ENTRY_EXIT, "SAC DoTlistCommand: Exiting.\n");}