|
|
/****************************************************************************
Copyright (c) Microsoft Corporation 1997 All rights reserved ***************************************************************************/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <winsock2.h>
#include <ntexapi.h>
#include <devioctl.h>
#include <stdlib.h>
#include <rccxport.h>
#include "rcclib.h"
#include "error.h"
ULONG GlobalBufferCurrentSize; char *GlobalBuffer = NULL;
ULONG GlobalCommandLineSize; char *GlobalCommandLine = NULL; ULONG GlobalReadIndex;
BOOL GlobalPagingNeeded = TRUE; BOOL GlobalDoThreads = TRUE;
UCHAR *StateTable[] = { "Initialized", "Ready", "Running", "Standby", "Terminated", "Wait:", "Transition", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown" };
UCHAR *WaitTable[] = { "Executive", "FreePage", "PageIn", "PoolAllocation", "DelayExecution", "Suspended", "UserRequest", "Executive", "FreePage", "PageIn", "PoolAllocation", "DelayExecution", "Suspended", "UserRequest", "EventPairHigh", "EventPairLow", "LpcReceive", "LpcReply", "VirtualMemory", "PageOut", "Spare1", "Spare2", "Spare3", "Spare4", "Spare5", "Spare6", "Spare7", "Unknown", "Unknown", "Unknown" };
UCHAR *Empty = " ";
DWORD RCCSrvReportEventA( DWORD EventID, DWORD EventType, DWORD NumStrings, DWORD DataLength, LPSTR *Strings, LPVOID Data );
DWORD RCCSrvGetCommandLine( IN HANDLE ComPortHandle, OUT PBOOL ControlC );
DWORD RCCSrvPrintMsg( IN HANDLE ComPortHandle, IN DWORD MessageId, IN DWORD SystemErrorCode ); DWORD RCCSrvPrint( IN HANDLE ComPortHandle, IN PUCHAR Buffer, IN DWORD BufferSize ); VOID RCCSrvPrintTListInfo( IN HANDLE ComPortHandle, IN PRCC_RSP_TLIST Buffer );
VOID RCCSrvPutMore( IN HANDLE ComPortHandle, OUT PBOOL ControlC );
BOOL AreYouSure( IN HANDLE ComPortHandle );
//
//
// Main routine
//
//
int __cdecl main( int argc, char *argv[] ) { NTSTATUS Status; HANDLE ComPortHandle; HANDLE RCCHandle = NULL; DWORD Error; DWORD BytesReturned; DWORD ProcessId; DWORD PrintMessage = 0; char *NewBuffer; DWORD ThisProcessId; DWORD MemoryLimit; DWORD DataLength; PUCHAR ComPort; DCB Dcb; char *pch; char *pTemp; char Command; BOOL Abort; STRING String1, String2;
//
// Init the library
//
Error = RCCLibInit(&GlobalBuffer, &GlobalBufferCurrentSize); if (Error != ERROR_SUCCESS) { PrintMessage = ERROR_RCCSRV_LIB_INIT_FAILED; goto Exit; }
//
// Check for arguments
//
if ((argc > 3) || ((argc > 1) && ((argv[1][0] == '-') || (argv[1][0] == '/')))) { PrintMessage = MSG_RCCSRV_USAGE; goto Exit; }
//
// Allocate memory for the command line
//
GlobalCommandLine = VirtualAlloc(NULL, 80 * sizeof(char), MEM_COMMIT, PAGE_READWRITE | PAGE_NOCACHE );
if (GlobalCommandLine == NULL) { //
// Log an error!
//
RCCSrvReportEventA(ERROR_RCCSRV_INITIAL_ALLOC_FAILED, EVENTLOG_ERROR_TYPE, 0, 0, NULL, NULL ); PrintMessage = MSG_RCCSRV_GENERAL_FAILURE; goto Exit; }
GlobalCommandLineSize = 80 * sizeof(char);
//
// Remember our process ID, so people cannot kill us.
//
ThisProcessId = GetCurrentProcessId();
//
// Open the Remote Command Console driver
//
RCCHandle = CreateFile("\\\\.\\RCC", GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, // create disposition.
0, 0 );
if (RCCHandle == INVALID_HANDLE_VALUE) { RCCHandle = NULL; Error = GetLastError(); RCCSrvReportEventA(ERROR_RCCSRV_OPEN_RCCDRIVER_FAILED, EVENTLOG_ERROR_TYPE, 0, 0, NULL, NULL ); }
//
// Open the serial port
//
if (argc > 1) { ComPort = argv[1]; } else { ComPort = "COM1"; } ComPortHandle = CreateFile(ComPort, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 0, NULL, OPEN_EXISTING, // create disposition.
0, 0 );
if (ComPortHandle == INVALID_HANDLE_VALUE) { //
// Log an error!
//
Error = GetLastError(); RCCSrvReportEventA(ERROR_RCCSRV_OPEN_COMPORT_FAILED, EVENTLOG_ERROR_TYPE, 0, 0, NULL, NULL ); PrintMessage = MSG_RCCSRV_GENERAL_FAILURE; goto Exit; }
//
// Set the serial port line characteristics
//
Dcb.DCBlength = sizeof(DCB);
if (!GetCommState(ComPortHandle, &Dcb)) { //
// Log an error!
//
Error = GetLastError(); RCCSrvReportEventA(ERROR_RCCSRV_OPEN_COMPORT_FAILED, EVENTLOG_ERROR_TYPE, 0, 0, NULL, NULL ); PrintMessage = MSG_RCCSRV_GENERAL_FAILURE; goto Exit; }
if (argc > 2) { Dcb.BaudRate = atoi(argv[2]); } else { Dcb.BaudRate = 9600; } Dcb.ByteSize = 8; Dcb.Parity = NOPARITY; Dcb.StopBits = ONESTOPBIT;
if (!SetCommState(ComPortHandle, &Dcb)) { //
// Log an error!
//
Error = GetLastError(); RCCSrvReportEventA(ERROR_RCCSRV_OPEN_COMPORT_FAILED, EVENTLOG_ERROR_TYPE, 0, 0, NULL, NULL ); PrintMessage = MSG_RCCSRV_GENERAL_FAILURE; goto Exit; }
while (1) {
//
// Write the prompt
//
Error = RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_PROMPT, 0);
if (Error != ERROR_SUCCESS) { RCCSrvReportEventA(ERROR_RCCSRV_SEND_FAILED, EVENTLOG_ERROR_TYPE, 0, sizeof(DWORD), NULL, &Error ); goto Exit; }
//
// Get any response.
//
Error = RCCSrvGetCommandLine(ComPortHandle, &Abort);
if (Error != ERROR_SUCCESS) { RCCSrvReportEventA(ERROR_RCCSRV_RCV_FAILED, EVENTLOG_ERROR_TYPE, 0, sizeof(DWORD), NULL, &Error ); goto Exit; }
if (Abort) { continue; }
//
// It completed, so we have data in the buffer - verify it and process the message.
//
pch = GlobalCommandLine; while (((*pch == ' ') || (*pch == '\t')) && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; }
Command = *pch;
switch (Command) { case 'c': case 'C': //
// Compare the command
//
pTemp = pch; while ((*pch != '\0') && (*pch != ' ') && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; } *pch = '\0'; RtlInitString(&String1, "crashdump"); RtlInitString(&String2, pTemp);
if (!RtlEqualString(&String1, &String2, TRUE)) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_HELP, 0); continue;
} if (RCCHandle == NULL) { RCCSrvPrintMsg(ComPortHandle, ERROR_RCCSRV_OPEN_RCCDRIVER_FAILED, 0); } else { //
// Send back an acknowledgement that we got the command before starting the crash.
//
if (AreYouSure(ComPortHandle)) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_CRASHING, 0);
if (!DeviceIoControl(RCCHandle, CTL_CODE(FILE_DEVICE_NETWORK, 0x3, METHOD_NEITHER, FILE_ANY_ACCESS), NULL, 0, NULL, 0, &BytesReturned, NULL )) { RCCSrvPrintMsg(ComPortHandle, ERROR_RCCSRV_CRASH_FAILED, 0); } } } break;
case 'f': case 'F': //
// Toggle paging
//
GlobalDoThreads = !GlobalDoThreads; if (GlobalDoThreads) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_THREADS_ENABLED, 0); } else { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_THREADS_DISABLED, 0); } break;
case 'k': case 'K': //
// Skip to next argument (process id)
//
while ((*pch != ' ') && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; } while ((*pch == ' ') && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; } ProcessId = atoi(pch); if (ProcessId != ThisProcessId) { Error = RCCLibKillProcess(ProcessId); } else { Error = ERROR_INVALID_PARAMETER; }
if (Error == ERROR_SUCCESS) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_RESULT_SUCCESS, 0); } else { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_RESULT_FAILURE, Error); } break;
case 'l': case 'L': //
// Skip to next argument (process id)
//
while ((*pch != ' ') && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; } while ((*pch == ' ') && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; } ProcessId = atoi(pch);
if (ProcessId != ThisProcessId) { Error = RCCLibLowerProcessPriority(ProcessId); } else { Error = ERROR_INVALID_PARAMETER; }
if (Error == ERROR_SUCCESS) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_RESULT_SUCCESS, 0); } else { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_RESULT_FAILURE, Error); } break;
case 'm': case 'M': //
// Skip to next argument (process id)
//
while ((*pch != ' ') && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; } while ((*pch == ' ') && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; } ProcessId = atoi(pch); //
// Skip to next argument (kb-allowed)
//
while ((*pch != ' ') && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; } while ((*pch == ' ') && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; } MemoryLimit = atoi(pch);
if (ProcessId != ThisProcessId) { Error = RCCLibLimitProcessMemory(ProcessId, MemoryLimit); } else { Error = ERROR_INVALID_PARAMETER; }
if (Error == ERROR_SUCCESS) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_RESULT_SUCCESS, 0); } else { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_RESULT_FAILURE, Error); } break;
case 'p': case 'P': //
// Toggle paging
//
GlobalPagingNeeded = !GlobalPagingNeeded; if (GlobalPagingNeeded) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_PAGING_ENABLED, 0); } else { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_PAGING_DISABLED, 0); } break;
case 'r': case 'R':
//
// Compare the command
//
pTemp = pch; while ((*pch != '\0') && (*pch != ' ') && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; } *pch = '\0'; RtlInitString(&String1, "reboot"); RtlInitString(&String2, pTemp);
if (!RtlEqualString(&String1, &String2, TRUE)) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_HELP, 0); continue;
} //
// Send back an acknowledgement that we got the command before starting the reboot.
//
if (AreYouSure(ComPortHandle)) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_SHUTTING_DOWN, 0); NtShutdownSystem(ShutdownReboot); } break;
case 's': case 'S':
//
// Compare the command
//
RtlInitString(&String1, "shutdown"); pTemp = pch; while ((*pch != '\0') && (*pch != ' ') && (pch < (GlobalCommandLine + GlobalCommandLineSize))) { pch++; } if (pch >= (GlobalCommandLine + GlobalCommandLineSize)) { continue; } *pch = '\0'; RtlInitString(&String2, pTemp);
if (!RtlEqualString(&String1, &String2, TRUE)) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_HELP, 0); continue;
} //
// Send back an acknowledgement that we got the command before starting the reboot.
//
if (AreYouSure(ComPortHandle)) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_SHUTTING_DOWN, 0); NtShutdownSystem(ShutdownNoReboot); } break;
case 't': case 'T':
RetryTList: Error = RCCLibGetTListInfo((PRCC_RSP_TLIST)GlobalBuffer, (LONG)GlobalBufferCurrentSize, &DataLength );
//
// Try to get more memory, if not available, then just fail without out of memory error.
//
if (Error == ERROR_OUTOFMEMORY) {
Error = RCCLibIncreaseMemory(&GlobalBuffer, &GlobalBufferCurrentSize); if (Error == ERROR_SUCCESS) { goto RetryTList; } RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_OUT_OF_MEMORY, 0); break; }
RCCSrvPrintTListInfo(ComPortHandle, (PRCC_RSP_TLIST)GlobalBuffer); break;
//
// Help
//
case '?': RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_HELP, 0); break;
default: RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_INVALID_COMMAND, 0); break; } }
Exit:
if (PrintMessage != 0) { BytesReturned = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, PrintMessage, 0, (LPTSTR)&NewBuffer, 0, (va_list *)&Error );
if (BytesReturned != 0) { printf(NewBuffer); LocalFree(NewBuffer); } }
RCCLibExit(GlobalBuffer, GlobalBufferCurrentSize); if (GlobalCommandLine != NULL) { VirtualFree(GlobalCommandLine, GlobalCommandLineSize, MEM_DECOMMIT); } if (RCCHandle != NULL) { NtClose(RCCHandle); } return 0; }
DWORD RCCSrvReportEventA( DWORD EventID, DWORD EventType, DWORD NumStrings, DWORD DataLength, LPSTR *Strings, LPVOID Data ) /*++
Routine Description:
This function writes the specified (EventID) log at the end of the eventlog.
Arguments:
EventID - The specific event identifier. This identifies the message that goes with this event.
EventType - Specifies the type of event being logged. This parameter can have one of the following
values:
Value Meaning
EVENTLOG_ERROR_TYPE Error event EVENTLOG_WARNING_TYPE Warning event EVENTLOG_INFORMATION_TYPE Information event
NumStrings - Specifies the number of strings that are in the array at 'Strings'. A value of zero indicates no strings are present.
DataLength - Specifies the number of bytes of event-specific raw (binary) data to write to the log. If cbData is zero, no event-specific data is present.
Strings - Points to a buffer containing an array of null-terminated strings that are merged into the message before displaying to the user. This parameter must be a valid pointer (or NULL), even if cStrings is zero.
Data - Buffer containing the raw data. This parameter must be a valid pointer (or NULL), even if cbData is zero.
Return Value:
Returns the WIN32 extended error obtained by GetLastError().
NOTE : This function works slow since it calls the open and close eventlog source everytime.
--*/ { HANDLE EventlogHandle; DWORD ReturnCode;
//
// open eventlog section.
//
EventlogHandle = RegisterEventSourceW(NULL, L"RCCSer");
if (EventlogHandle == NULL) { ReturnCode = GetLastError(); goto Cleanup; }
//
// Log the error code specified
//
if(!ReportEventA(EventlogHandle, (WORD)EventType, 0, // event category
EventID, NULL, (WORD)NumStrings, DataLength, Strings, Data )) {
ReturnCode = GetLastError(); goto Cleanup; }
ReturnCode = ERROR_SUCCESS;
Cleanup:
if (EventlogHandle != NULL) { DeregisterEventSource(EventlogHandle); }
return ReturnCode; }
DWORD RCCSrvGetCommandLine( IN HANDLE ComPortHandle, OUT PBOOL ControlC ) { DWORD Bytes; DWORD i; GlobalReadIndex = 0;
*ControlC = FALSE;
do {
if (GlobalReadIndex == GlobalCommandLineSize) { GlobalReadIndex--; }
//
// Read a (possibly) partial command line.
//
if (!ReadFile(ComPortHandle, &(GlobalCommandLine[GlobalReadIndex]), 1, &Bytes, NULL )) {
return GetLastError();
}
if (GlobalCommandLine[GlobalReadIndex] == 0x3) { *ControlC = TRUE; return ERROR_SUCCESS; }
if ((GlobalCommandLine[GlobalReadIndex] == 0x8) || // backspace (^h)
(GlobalCommandLine[GlobalReadIndex] == 0x7F)) { // delete
if (GlobalReadIndex > 0) { WriteFile(ComPortHandle, &(GlobalCommandLine[GlobalReadIndex]), 1, &Bytes, NULL ); GlobalReadIndex--; } } else { WriteFile(ComPortHandle, &(GlobalCommandLine[GlobalReadIndex]), 1, &Bytes, NULL ); GlobalReadIndex++; } } while ((GlobalReadIndex == 0) || (GlobalCommandLine[GlobalReadIndex - 1] != '\r'));
GlobalCommandLine[GlobalReadIndex - 1] = '\0'; RCCSrvPrint(ComPortHandle, "\n", sizeof("\n") - 1); return ERROR_SUCCESS; }
DWORD RCCSrvPrintMsg( IN HANDLE ComPortHandle, IN DWORD MessageId, IN DWORD SystemErrorCode ) { DWORD Bytes; UCHAR OutBuffer[512];
Bytes = FormatMessageA(FORMAT_MESSAGE_FROM_HMODULE, NULL, MessageId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), OutBuffer, ARRAYSIZE(OutBuffer)), NULL );
ASSERT(Bytes != 0);
if (MessageId == MSG_RCCSRV_PROMPT) { Bytes -= 2; // remove the \r\n that get added in .mc files
}
RCCSrvPrint(ComPortHandle, OutBuffer, Bytes);
if (SystemErrorCode != 0) {
Bytes = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, SystemErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), OutBuffer, ARRAYSIZE(OutBuffer), NULL );
if (Bytes == 0) { Bytes = FormatMessageA(FORMAT_MESSAGE_FROM_HMODULE, NULL, MSG_RCCSRV_ERROR_NOT_DEFINED, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), OutBuffer, ARRAYSIZE(OutBuffer), (LPVOID)&SystemErrorCode );
ASSERT(Bytes != 0); }
RCCSrvPrint(ComPortHandle, OutBuffer, Bytes); RCCSrvPrint(ComPortHandle, "\r\n\r\n", sizeof("\r\n\r\n") - 1); }
return ERROR_SUCCESS; } DWORD RCCSrvPrint( IN HANDLE ComPortHandle, IN PUCHAR Buffer, IN DWORD BufferSize ) { DWORD BytesWritten;
if (!WriteFile(ComPortHandle, Buffer, BufferSize, &BytesWritten, NULL)) { return GetLastError(); }
return ERROR_SUCCESS; }
VOID RCCSrvPrintTListInfo( IN HANDLE ComPortHandle, IN PRCC_RSP_TLIST Buffer ) { LARGE_INTEGER Time; TIME_FIELDS UserTime; TIME_FIELDS KernelTime; TIME_FIELDS UpTime; ULONG TotalOffset; SIZE_T SumCommit; SIZE_T SumWorkingSet;
PSYSTEM_PROCESS_INFORMATION ProcessInfo; PSYSTEM_THREAD_INFORMATION ThreadInfo; PSYSTEM_PAGEFILE_INFORMATION PageFileInfo;
ULONG i;
PUCHAR ProcessInfoStart; PUCHAR BufferStart = (PUCHAR)Buffer;
ANSI_STRING pname;
ULONG LineNumber = 0;
UCHAR OutputBuffer[200]; // should never be more than 80, but just to be safe....
BOOL Stop; Time.QuadPart = Buffer->TimeOfDayInfo.CurrentTime.QuadPart - Buffer->TimeOfDayInfo.BootTime.QuadPart;
RtlTimeToElapsedTimeFields(&Time, &UpTime);
sprintf(OutputBuffer, "memory: %4ld kb uptime:%3ld %2ld:%02ld:%02ld.%03ld \r\n\r\n", Buffer->BasicInfo.NumberOfPhysicalPages * (Buffer->BasicInfo.PageSize / 1024), UpTime.Day, UpTime.Hour, UpTime.Minute, UpTime.Second, UpTime.Milliseconds );
RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer));
LineNumber += 2;
PageFileInfo = (PSYSTEM_PAGEFILE_INFORMATION)(BufferStart + Buffer->PagefileInfoOffset); //
// Print out the page file information.
//
if (Buffer->PagefileInfoOffset == 0) { sprintf(OutputBuffer, "no page files in use\r\n"); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++; } else { for (; ; ) {
PageFileInfo->PageFileName.Buffer = (PWCHAR)(((PUCHAR)BufferStart) + (ULONG_PTR)(PageFileInfo->PageFileName.Buffer));
sprintf(OutputBuffer, "PageFile: %wZ\r\n", &PageFileInfo->PageFileName); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++; sprintf(OutputBuffer, "\tCurrent Size: %6ld kb Total Used: %6ld kb Peak Used %6ld kb\r\n", PageFileInfo->TotalSize * (Buffer->BasicInfo.PageSize/1024), PageFileInfo->TotalInUse * (Buffer->BasicInfo.PageSize/1024), PageFileInfo->PeakUsage * (Buffer->BasicInfo.PageSize/1024) ); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++; if (PageFileInfo->NextEntryOffset == 0) { break; }
PageFileInfo = (PSYSTEM_PAGEFILE_INFORMATION)((PCHAR)PageFileInfo + PageFileInfo->NextEntryOffset);
}
}
//
// display pmon style process output, then detailed output that includes
// per thread stuff
//
if (Buffer->ProcessInfoOffset == 0) { return; }
TotalOffset = 0; SumCommit = 0; SumWorkingSet = 0; ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)(BufferStart + Buffer->ProcessInfoOffset); ProcessInfoStart = (PUCHAR)ProcessInfo; while (TRUE) { SumCommit += ProcessInfo->PrivatePageCount / 1024; SumWorkingSet += ProcessInfo->WorkingSetSize / 1024; if (ProcessInfo->NextEntryOffset == 0) { break; } TotalOffset += ProcessInfo->NextEntryOffset; ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)(ProcessInfoStart +TotalOffset); }
SumWorkingSet += Buffer->FileCache.CurrentSize/1024;
if (LineNumber > 17) { RCCSrvPutMore(ComPortHandle, &Stop);
if (Stop) { return; }
LineNumber = 0; }
sprintf(OutputBuffer, "\r\n Memory:%7ldK Avail:%7ldK TotalWs:%7ldK InRam Kernel:%5ldK P:%5ldK\r\n", Buffer->BasicInfo.NumberOfPhysicalPages * (Buffer->BasicInfo.PageSize/1024), Buffer->PerfInfo.AvailablePages * (Buffer->BasicInfo.PageSize/1024), SumWorkingSet, (Buffer->PerfInfo.ResidentSystemCodePage + Buffer->PerfInfo.ResidentSystemDriverPage) * (Buffer->BasicInfo.PageSize/1024), (Buffer->PerfInfo.ResidentPagedPoolPage) * (Buffer->BasicInfo.PageSize/1024) ); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber += 2; if (LineNumber > 18) { RCCSrvPutMore(ComPortHandle, &Stop);
if (Stop) { return; }
LineNumber = 0; }
sprintf(OutputBuffer, " Commit:%7ldK/%7ldK Limit:%7ldK Peak:%7ldK Pool N:%5ldK P:%5ldK\r\n", Buffer->PerfInfo.CommittedPages * (Buffer->BasicInfo.PageSize/1024), SumCommit, Buffer->PerfInfo.CommitLimit * (Buffer->BasicInfo.PageSize/1024), Buffer->PerfInfo.PeakCommitment * (Buffer->BasicInfo.PageSize/1024), Buffer->PerfInfo.NonPagedPoolPages * (Buffer->BasicInfo.PageSize/1024), Buffer->PerfInfo.PagedPoolPages * (Buffer->BasicInfo.PageSize/1024) );
RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++; if (LineNumber > 18) { RCCSrvPutMore(ComPortHandle, &Stop);
if (Stop) { return; }
LineNumber = 0; }
sprintf(OutputBuffer, "\r\n"); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); RCCSrvPutMore(ComPortHandle, &Stop);
if (Stop) { return; }
LineNumber = 0;
sprintf(OutputBuffer, " User Time Kernel Time Ws Faults Commit Pri Hnd Thd Pid Name\r\n");
RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++;
sprintf(OutputBuffer, " %6ld %8ld %s\r\n", Buffer->FileCache.CurrentSize/1024, Buffer->FileCache.PageFaultCount, "File Cache" );
RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++; TotalOffset = 0; ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)(BufferStart + Buffer->ProcessInfoOffset);
while (TRUE) {
pname.Buffer = NULL; if (ProcessInfo->ImageName.Buffer) { ProcessInfo->ImageName.Buffer = (PWCHAR)(BufferStart + (ULONG_PTR)(ProcessInfo->ImageName.Buffer)); RtlUnicodeStringToAnsiString(&pname,(PUNICODE_STRING)&ProcessInfo->ImageName,TRUE); }
RtlTimeToElapsedTimeFields(&ProcessInfo->UserTime, &UserTime); RtlTimeToElapsedTimeFields(&ProcessInfo->KernelTime, &KernelTime);
sprintf(OutputBuffer, "%3ld:%02ld:%02ld.%03ld %3ld:%02ld:%02ld.%03ld", UserTime.Hour, UserTime.Minute, UserTime.Second, UserTime.Milliseconds, KernelTime.Hour, KernelTime.Minute, KernelTime.Second, KernelTime.Milliseconds ); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer));
sprintf(OutputBuffer, "%6ld %8ld %7ld", ProcessInfo->WorkingSetSize / 1024, ProcessInfo->PageFaultCount, ProcessInfo->PrivatePageCount / 1024 ); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer));
sprintf(OutputBuffer, " %2ld %4ld %3ld %3ld %s\r\n", ProcessInfo->BasePriority, ProcessInfo->HandleCount, ProcessInfo->NumberOfThreads, HandleToUlong(ProcessInfo->UniqueProcessId), ProcessInfo->UniqueProcessId == 0 ? "Idle Process" : (ProcessInfo->ImageName.Buffer ? pname.Buffer : "System") );
RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++; if (LineNumber > 18) { RCCSrvPutMore(ComPortHandle, &Stop);
if (Stop) { return; }
LineNumber = 0; if (GlobalPagingNeeded) { sprintf(OutputBuffer, " User Time Kernel Time Ws Faults Commit Pri Hnd Thd Pid Name\r\n");
RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); }
LineNumber++; }
if (pname.Buffer) { RtlFreeAnsiString(&pname); }
if (ProcessInfo->NextEntryOffset == 0) { break; }
TotalOffset += ProcessInfo->NextEntryOffset; ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)(ProcessInfoStart + TotalOffset); }
if (!GlobalDoThreads) { return; }
//
// Beginning of normal old style pstat output
//
TotalOffset = 0; ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)(BufferStart + Buffer->ProcessInfoOffset);
RCCSrvPutMore(ComPortHandle, &Stop);
if (Stop) { return; }
LineNumber = 0;
sprintf(OutputBuffer, "\r\n"); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++;
while (TRUE) {
pname.Buffer = NULL;
if (ProcessInfo->ImageName.Buffer) { RtlUnicodeStringToAnsiString(&pname,(PUNICODE_STRING)&ProcessInfo->ImageName,TRUE); }
sprintf(OutputBuffer, "pid:%3lx pri:%2ld Hnd:%5ld Pf:%7ld Ws:%7ldK %s\r\n", HandleToUlong(ProcessInfo->UniqueProcessId), ProcessInfo->BasePriority, ProcessInfo->HandleCount, ProcessInfo->PageFaultCount, ProcessInfo->WorkingSetSize / 1024, ProcessInfo->UniqueProcessId == 0 ? "Idle Process" : ( ProcessInfo->ImageName.Buffer ? pname.Buffer : "System") );
RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++; if (LineNumber > 18) { RCCSrvPutMore(ComPortHandle, &Stop);
if (Stop) { return; }
LineNumber = 0; }
if (pname.Buffer) { RtlFreeAnsiString(&pname); }
i = 0; ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(ProcessInfo + 1); if (ProcessInfo->NumberOfThreads) {
if ((LineNumber < 18) || !GlobalPagingNeeded) { sprintf(OutputBuffer, " tid pri Ctx Swtch StrtAddr User Time Kernel Time State\r\n"); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++; } else { RCCSrvPutMore(ComPortHandle, &Stop);
if (Stop) { return; }
LineNumber = 0; }
}
while (i < ProcessInfo->NumberOfThreads) { RtlTimeToElapsedTimeFields ( &ThreadInfo->UserTime, &UserTime);
RtlTimeToElapsedTimeFields ( &ThreadInfo->KernelTime, &KernelTime); sprintf(OutputBuffer, " %3lx %2ld %9ld %p", ProcessInfo->UniqueProcessId == 0 ? 0 : HandleToUlong(ThreadInfo->ClientId.UniqueThread), ProcessInfo->UniqueProcessId == 0 ? 0 : ThreadInfo->Priority, ThreadInfo->ContextSwitches, ProcessInfo->UniqueProcessId == 0 ? 0 : ThreadInfo->StartAddress ); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer));
sprintf(OutputBuffer, " %2ld:%02ld:%02ld.%03ld %2ld:%02ld:%02ld.%03ld", UserTime.Hour, UserTime.Minute, UserTime.Second, UserTime.Milliseconds, KernelTime.Hour, KernelTime.Minute, KernelTime.Second, KernelTime.Milliseconds ); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer));
sprintf(OutputBuffer, " %s%s\r\n", StateTable[ThreadInfo->ThreadState], (ThreadInfo->ThreadState == 5) ? WaitTable[ThreadInfo->WaitReason] : Empty ); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++; if (LineNumber > 18) { RCCSrvPutMore(ComPortHandle, &Stop);
if (Stop) { return; }
LineNumber = 0;
if (GlobalPagingNeeded) { sprintf(OutputBuffer, " tid pri Ctx Swtch StrtAddr User Time Kernel Time State\r\n"); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); }
LineNumber++; }
ThreadInfo += 1; i += 1;
}
if (ProcessInfo->NextEntryOffset == 0) { break; }
TotalOffset += ProcessInfo->NextEntryOffset; ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)(ProcessInfoStart + TotalOffset);
sprintf(OutputBuffer, "\r\n"); RCCSrvPrint(ComPortHandle, OutputBuffer, strlen(OutputBuffer)); LineNumber++;
if (LineNumber > 18) { RCCSrvPutMore(ComPortHandle, &Stop);
if (Stop) { return; }
LineNumber = 0; }
}
}
VOID RCCSrvPutMore( IN HANDLE ComPortHandle, OUT PBOOL Stop ) {
if (GlobalPagingNeeded) { RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_MORE, 0); RCCSrvGetCommandLine(ComPortHandle, Stop); } else { *Stop = FALSE; }
}
BOOL AreYouSure( IN HANDLE ComPortHandle ) { BOOL Stop;
RCCSrvPrintMsg(ComPortHandle, MSG_RCCSRV_ARE_YOU_SURE, 0); RCCSrvGetCommandLine(ComPortHandle, &Stop);
if (!Stop && ((GlobalCommandLine[0] == 'y') || (GlobalCommandLine[0] == 'Y'))) { return TRUE; }
return FALSE; }
|