ctm.c - main program file
Written by: Aleksey Bragin (aleksey@studiocerebral.com)
-
+
Most of the code dealing with getting system parameters is taken from
ReactOS Task Manager written by Brian Palmer (brianp@reactos.org)
-
- Localization features added by Hervé Poussineau (hpoussineau@fr.st)
+
+ Localization features added by Hervé Poussineau (hpoussin@reactos.org)
History:
- 24 October 2004 - added localization features
+ 24 October 2004 - added localization features
09 April 2003 - v0.1, fixed bugs, added features, ported to mingw
20 March 2003 - v0.03, works good under ReactOS, and allows process
killing
18 March 2003 - Initial version 0.01, doesn't work under RectOS
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows //headers
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows //headers
+#define WIN32_NO_STATUS
#include <windows.h>
+
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <process.h>
#include <stdio.h>
-#include <ddk/ntddk.h>
-#include <epsapi.h>
-#include <ntos/zwtypes.h>
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
+
+#include <epsapi/epsapi.h>
#include "ctm.h"
#include "resource.h"
-#define MAX_PROC 17
#define TIMES
HANDLE hStdin;
TCHAR lpSeparator[80];
TCHAR lpHeader[80];
TCHAR lpMemUnit[3];
-TCHAR lpIdleProcess[80];;
+TCHAR lpIdleProcess[80];
TCHAR lpTitle[80];
TCHAR lpHeader[80];
TCHAR lpMenu[80];
TCHAR KEY_QUIT, KEY_KILL;
TCHAR KEY_YES, KEY_NO;
-const int ProcPerScreen = 17; // 17 processess are displayed on one page
+int ProcPerScreen = 17; // 17 processess are displayed on one page
+int ScreenLines=25;
ULONG ProcessCountOld = 0;
ULONG ProcessCount = 0;
int first = 0; // first time in DisplayScreen
SYSTEM_BASIC_INFORMATION SystemBasicInfo;
+CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
#define NEW_CONSOLE
// Functions that are needed by epsapi
void DisplayScreen()
{
COORD pos;
+ COORD size;
TCHAR lpStr[80];
- int posStr;
DWORD numChars;
int lines;
- int idx, i;
-
+ int idx;
+ GetConsoleScreenBufferInfo(hStdout,&screenBufferInfo);
+ size=screenBufferInfo.dwSize;
+ ScreenLines=size.Y;
+ ProcPerScreen = ScreenLines-7;
if (first == 0)
{
// Header
- pos.X = 2; pos.Y = 2;
+ pos.X = 1; pos.Y = 1;
WriteConsoleOutputCharacter(hStdout, lpTitle, _tcslen(lpTitle), pos, &numChars);
- pos.X = 2; pos.Y = 3;
+ pos.X = 1; pos.Y = 2;
WriteConsoleOutputCharacter(hStdout, lpSeparator, _tcslen(lpSeparator), pos, &numChars);
- pos.X = 2; pos.Y = 4;
+ pos.X = 1; pos.Y = 3;
WriteConsoleOutputCharacter(hStdout, lpHeader, _tcslen(lpHeader), pos, &numChars);
- pos.X = 2; pos.Y = 5;
+ pos.X = 1; pos.Y = 4;
WriteConsoleOutputCharacter(hStdout, lpSeparator, _tcslen(lpSeparator), pos, &numChars);
// Footer
- pos.X = 2; pos.Y = ProcPerScreen+6;
+ pos.X = 1; pos.Y = ScreenLines-2;
WriteConsoleOutputCharacter(hStdout, lpSeparator, _tcslen(lpSeparator), pos, &numChars);
-
+
// Menu
- pos.X = 2; pos.Y = ProcPerScreen+7;
+ pos.X = 1; pos.Y = ScreenLines-1;
WriteConsoleOutputCharacter(hStdout, lpEmpty, _tcslen(lpEmpty), pos, &numChars);
WriteConsoleOutputCharacter(hStdout, lpMenu, _tcslen(lpMenu), pos, &numChars);
first = 1;
}
- // Processess
+ // Processess
lines = ProcessCount;
- if (lines > MAX_PROC)
- lines = MAX_PROC;
- for (idx=0; idx<MAX_PROC; idx++)
+ if (lines > ProcPerScreen)
+ lines = ProcPerScreen;
+ for (idx=0; idx<ProcPerScreen; idx++)
{
int len, i;
- TCHAR imgName[MAX_PATH];
+ TCHAR lpNumber[5];
TCHAR lpPid[8];
TCHAR lpCpu[6];
TCHAR lpMemUsg[12];
TCHAR lpPageFaults[15];
WORD wColor;
-
+
for (i = 0; i < 80; i++)
lpStr[i] = _T(' ');
// data
if (idx < lines && scrolled + idx < ProcessCount)
{
+
+ // number
+ _stprintf(lpNumber, _T("%3d"), idx+scrolled);
+ _tcsncpy(&lpStr[2], lpNumber, 3);
+
// image name
-#ifdef _UNICODE
- len = wcslen(pPerfData[scrolled+idx].ImageName);
+#ifdef _UNICODE
+ len = wcslen(pPerfData[scrolled+idx].ImageName);
#else
WideCharToMultiByte(CP_ACP, 0, pPerfData[scrolled+idx].ImageName, -1,
imgName, MAX_PATH, NULL, NULL);
len = strlen(imgName);
#endif
- if (len > columnRightPositions[0])
+ if (len > columnRightPositions[1])
{
- len = columnRightPositions[0];
+ len = columnRightPositions[1];
}
#ifdef _UNICODE
- wcsncpy(&lpStr[2], pPerfData[scrolled+idx].ImageName, len);
+ wcsncpy(&lpStr[columnRightPositions[0]+3], pPerfData[scrolled+idx].ImageName, len);
#else
- strncpy(&lpStr[2], imgName, len);
+ strncpy(&lpStr[columnRightPositions[0]+3], imgName, len);
#endif
// PID
- _stprintf(lpPid, _T("%6ld"), pPerfData[scrolled+idx].ProcessId);
- _tcsncpy(&lpStr[columnRightPositions[1] - 6], lpPid, 6);
+ _stprintf(lpPid, _T("%6ld"), pPerfData[scrolled+idx].ProcessId);
+ _tcsncpy(&lpStr[columnRightPositions[2] - 6], lpPid, 6);
#ifdef TIMES
// CPU
_stprintf(lpCpu, _T("%3d%%"), pPerfData[scrolled+idx].CPUUsage);
- _tcsncpy(&lpStr[columnRightPositions[2] - 4], lpCpu, 4);
+ _tcsncpy(&lpStr[columnRightPositions[3] - 4], lpCpu, 4);
#endif
// Mem usage
_stprintf(lpMemUsg, _T("%6ld %s"), pPerfData[scrolled+idx].WorkingSetSizeBytes / 1024, lpMemUnit);
- _tcsncpy(&lpStr[columnRightPositions[3] - 9], lpMemUsg, 9);
+ _tcsncpy(&lpStr[columnRightPositions[4] - 9], lpMemUsg, 9);
// Page Fault
_stprintf(lpPageFaults, _T("%12ld"), pPerfData[scrolled+idx].PageFaultCount);
- _tcsncpy(&lpStr[columnRightPositions[4] - 12], lpPageFaults, 12);
+ _tcsncpy(&lpStr[columnRightPositions[5] - 12], lpPageFaults, 12);
}
// columns
lpStr[0] = _T(' ');
lpStr[1] = _T('|');
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 6; i++)
lpStr[columnRightPositions[i] + 1] = _T('|');
- pos.X = 1; pos.Y = 6+idx;
- WriteConsoleOutputCharacter(hStdout, lpStr, 74, pos, &numChars);
+ pos.X = 0; pos.Y = 5+idx;
+ WriteConsoleOutputCharacter(hStdout, lpStr, 80, pos, &numChars);
// Attributes now...
- pos.X = 3; pos.Y = 6+idx;
+ pos.X = columnRightPositions[0] + 1; pos.Y = 5+idx;
if (selection == idx)
{
- wColor = BACKGROUND_GREEN |
- FOREGROUND_RED |
- FOREGROUND_GREEN |
+ wColor = BACKGROUND_GREEN |
+ FOREGROUND_RED |
+ FOREGROUND_GREEN |
FOREGROUND_BLUE;
}
else
{
wColor = BACKGROUND_BLUE |
- FOREGROUND_RED |
- FOREGROUND_GREEN |
+ FOREGROUND_RED |
+ FOREGROUND_GREEN |
FOREGROUND_BLUE;
}
- FillConsoleOutputAttribute(
- hStdout, // screen buffer handle
- wColor, // color to fill with
- columnRightPositions[0] - 1, // number of cells to fill
- pos, // first cell to write to
- &numChars); // actual number written
+ FillConsoleOutputAttribute(
+ hStdout, // screen buffer handle
+ wColor, // color to fill with
+ columnRightPositions[1] - 4, // number of cells to fill
+ pos, // first cell to write to
+ &numChars); // actual number written
}
return;
COORD pos;
TCHAR lpStr[100];
- pos.X = 2; pos.Y = 24;
+ pos.X = 1; pos.Y =ScreenLines-1;
if (LoadString(hInst, IDS_KILL_PROCESS, lpStr, 100))
WriteConsoleOutputCharacter(hStdout, lpStr, _tcslen(lpStr), pos, &numChars);
HANDLE hProcess;
pId = pPerfData[selection+scrolled].ProcessId;
hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pId);
-
+
if (hProcess)
{
if (!TerminateProcess(hProcess, 0))
Sleep(1000);
}
}
-
+
first = 0;
}
else if (key == VK_UP)
}
else if (key == VK_DOWN)
{
- if ((selection < MAX_PROC-1) && (selection < ProcessCount-1))
+ if ((selection < ProcPerScreen-1) && (selection < ProcessCount-1))
selection++;
- else if ((selection == MAX_PROC-1) && (selection+scrolled < ProcessCount-1))
+ else if ((selection == ProcPerScreen-1) && (selection+scrolled < ProcessCount-1))
scrolled++;
}
-
+ else if (key == VK_PRIOR)
+ {
+ if (scrolled>ProcPerScreen-1)
+ scrolled-=ProcPerScreen-1;
+ else
+ {
+ scrolled=0; //First
+ selection=0;
+ }
+ //selection=0;
+ }
+ else if (key == VK_NEXT)
+ {
+ scrolled+=ProcPerScreen-1;
+ if (scrolled>ProcessCount-ProcPerScreen)
+ {
+ scrolled=ProcessCount-ProcPerScreen; //End
+ selection=ProcPerScreen-1;
+ }
+
+ //selection=ProcPerScreen-1;
+ if (ProcessCount<=ProcPerScreen) //If there are less process than fits on the screen
+ {
+ scrolled=0;
+ selection=(ProcessCount%ProcPerScreen)-1;
+ }
+ }
+ else if (key == VK_HOME)
+ {
+ selection=0;
+ scrolled=0;
+ }
+ else if (key == VK_END)
+ {
+ selection=ProcPerScreen-1;
+ scrolled=ProcessCount-ProcPerScreen;
+ if (ProcessCount<=ProcPerScreen) //If there are less process than fits on the screen
+ {
+ scrolled=0;
+ selection=(ProcessCount%ProcPerScreen)-1;
+ }
+ }
return FALSE;
}
LONG status;
ULONG ulSize;
LPBYTE pBuffer;
- ULONG BufferSize;
ULONG Idx, Idx2;
- HANDLE hProcess;
- HANDLE hProcessToken;
PSYSTEM_PROCESS_INFORMATION pSPI;
PPERFDATA pPDOld;
+#ifdef EXTRA_INFO
+ HANDLE hProcess;
+ HANDLE hProcessToken;
TCHAR szTemp[MAX_PATH];
DWORD dwSize;
+#endif
#ifdef TIMES
LARGE_INTEGER liCurrentKernelTime;
LARGE_INTEGER liCurrentIdleTime;
if (status != NO_ERROR)
return;
#endif
- // Get processor information
- SysProcessorTimeInfo = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)malloc(sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberProcessors);
- status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberProcessors, &ulSize);
+ // Get processor information
+ SysProcessorTimeInfo = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)malloc(sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors);
+ status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors, &ulSize);
// Get process information
#ifdef TIMES
liCurrentKernelTime.QuadPart = 0;
liCurrentIdleTime.QuadPart = 0;
- for (Idx=0; Idx<SystemBasicInfo.NumberProcessors; Idx++) {
+ for (Idx=0; Idx<SystemBasicInfo.NumberOfProcessors; Idx++) {
liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].KernelTime.QuadPart;
liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].DpcTime.QuadPart;
liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].InterruptTime.QuadPart;
// CurrentCpuIdle = IdleTime / SystemTime
dbIdleTime = dbIdleTime / dbSystemTime;
dbKernelTime = dbKernelTime / dbSystemTime;
-
+
// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
- dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.NumberProcessors;// + 0.5;
- dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberProcessors;// + 0.5;
+ dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors;// + 0.5;
+ dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors;// + 0.5;
}
// Store new CPU's idle and system time
double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime);
double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime);
double CpuTime = (CurTime - OldTime) / dbSystemTime;
- CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.NumberProcessors; // + 0.5;
+ CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; // + 0.5;
pPerfData[Idx].CPUUsage = (ULONG)CpuTime;
#else
//pPerfData[Idx].SessionId = pSPI->SessionId;
#ifdef EXTRA_INFO
- hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pSPI->UniqueProcessId);
+ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)pSPI->UniqueProcessId);
if (hProcess) {
if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) {
ImpersonateLoggedOnUser(hProcessToken);
GetUserName(szTemp, &dwSize);
#ifndef UNICODE
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTemp, -1, pPerfData[Idx].UserName, MAX_PATH);
-/*
-int MultiByteToWideChar(
- UINT CodePage, // code page
- DWORD dwFlags, // character-type options
- LPCSTR lpMultiByteStr, // string to map
- int cbMultiByte, // number of bytes in string
- LPWSTR lpWideCharStr, // wide-character buffer
- int cchWideChar // size of buffer
-);
- */
#endif
RevertToSelf();
CloseHandle(hProcessToken);
// Code partly taken from slw32tty.c from mc/slang
unsigned int GetKeyPressed(int events)
{
- long key;
DWORD bytesRead;
INPUT_RECORD record;
int i;
}
-int main(int *argc, char **argv)
+int main(int argc, char **argv)
{
int i;
TCHAR lpStr[80];
-
+
for (i = 0; i < 80; i++)
lpEmpty[i] = lpHeader[i] = _T(' ');
lpEmpty[79] = _T('\0');
/* Initialize global variables */
hInst = 0 /* FIXME: which value? [used with LoadString(hInst, ..., ..., ...)] */;
- if (LoadString(hInst, IDS_COLUMN_IMAGENAME, lpStr, 80))
+
+ if (LoadString(hInst, IDS_COLUMN_NUMBER, lpStr, 80))
{
- columnRightPositions[0] = _tcslen(lpStr);
+ columnRightPositions[0] = _tcslen(lpStr) + 3;
_tcsncpy(&lpHeader[2], lpStr, _tcslen(lpStr));
}
- if (LoadString(hInst, IDS_COLUMN_PID, lpStr, 80))
+ if (LoadString(hInst, IDS_COLUMN_IMAGENAME, lpStr, 80))
{
columnRightPositions[1] = columnRightPositions[0] + _tcslen(lpStr) + 3;
_tcsncpy(&lpHeader[columnRightPositions[0] + 2], lpStr, _tcslen(lpStr));
}
- if (LoadString(hInst, IDS_COLUMN_CPU, lpStr, 80))
+ if (LoadString(hInst, IDS_COLUMN_PID, lpStr, 80))
{
columnRightPositions[2] = columnRightPositions[1] + _tcslen(lpStr) + 3;
_tcsncpy(&lpHeader[columnRightPositions[1] + 2], lpStr, _tcslen(lpStr));
}
- if (LoadString(hInst, IDS_COLUMN_MEM, lpStr, 80))
+ if (LoadString(hInst, IDS_COLUMN_CPU, lpStr, 80))
{
columnRightPositions[3] = columnRightPositions[2] + _tcslen(lpStr) + 3;
_tcsncpy(&lpHeader[columnRightPositions[2] + 2], lpStr, _tcslen(lpStr));
}
- if (LoadString(hInst, IDS_COLUMN_PF, lpStr, 80))
+ if (LoadString(hInst, IDS_COLUMN_MEM, lpStr, 80))
{
columnRightPositions[4] = columnRightPositions[3] + _tcslen(lpStr) + 3;
_tcsncpy(&lpHeader[columnRightPositions[3] + 2], lpStr, _tcslen(lpStr));
}
-
- for (i = 0; i < columnRightPositions[4]; i++)
+ if (LoadString(hInst, IDS_COLUMN_PF, lpStr, 80))
+ {
+ columnRightPositions[5] = columnRightPositions[4] + _tcslen(lpStr) + 3;
+ _tcsncpy(&lpHeader[columnRightPositions[4] + 2], lpStr, _tcslen(lpStr));
+ }
+
+ for (i = 0; i < columnRightPositions[5]; i++)
lpSeparator[i] = _T('-');
lpHeader[0] = _T('|');
lpSeparator[0] = _T('+');
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 6; i++)
{
lpHeader[columnRightPositions[i]] = _T('|');
lpSeparator[columnRightPositions[i]] = _T('+');
}
- lpSeparator[columnRightPositions[4] + 1] = _T('\0');
- lpHeader[columnRightPositions[4] + 1] = _T('\0');
+ lpSeparator[columnRightPositions[5] + 1] = _T('\0');
+ lpHeader[columnRightPositions[5] + 1] = _T('\0');
+
-
if (!LoadString(hInst, IDS_APP_TITLE, lpTitle, 80))
lpTitle[0] = _T('\0');
if (!LoadString(hInst, IDS_COLUMN_MEM_UNIT, lpMemUnit, 3))
lpMenu[0] = _T('\0');
if (!LoadString(hInst, IDS_IDLE_PROCESS, lpIdleProcess, 80))
lpIdleProcess[0] = _T('\0');
-
+
if (LoadString(hInst, IDS_MENU_QUIT, lpStr, 2))
KEY_QUIT = lpStr[0];
if (LoadString(hInst, IDS_MENU_KILL_PROCESS, lpStr, 2))