diff --git a/ntop.c b/ntop.c index 51c31c5..6a95358 100644 --- a/ntop.c +++ b/ntop.c @@ -54,6 +54,7 @@ static DWORD VisibleProcessCount; static WORD SavedAttributes; HANDLE ConsoleHandle; static HANDLE OldConsoleHandle; +static BOOL InteractiveMode = TRUE; static CRITICAL_SECTION SyncLock; static int ConPrintf(TCHAR *Fmt, ...) @@ -66,7 +67,7 @@ static int ConPrintf(TCHAR *Fmt, ...) va_end(VaList); DWORD Dummy; - WriteConsole(ConsoleHandle, Buffer, CharsWritten, &Dummy, 0); + WriteFile(ConsoleHandle, Buffer, CharsWritten, &Dummy, 0); return CharsWritten; } @@ -74,7 +75,7 @@ static int ConPrintf(TCHAR *Fmt, ...) static void ConPutc(TCHAR c) { DWORD Dummy; - WriteConsole(ConsoleHandle, &c, 1, &Dummy, 0); + WriteFile(ConsoleHandle, &c, 1, &Dummy, 0); } #define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE) @@ -169,34 +170,47 @@ static void ParseConfigLine(char *Line) static void ReadConfigFile(void) { - FILE *File; - errno_t Error; - - Error = fopen_s(&File, "ntop.conf", "r"); - if(Error != 0) - return; - - size_t BufferSize = BUF_INCREASE; - size_t Offset = 0; - char *Buffer = xmalloc(BUF_INCREASE); - - while(1) { - if(!fgets(Offset + Buffer, (int)(BufferSize - Offset), File)) { - break; - } - - if(!feof(File) && !strchr(Buffer, '\n')) { - Offset = BufferSize - 1; - BufferSize += BUF_INCREASE; - Buffer = xrealloc(Buffer, BufferSize); - } else { - Offset = 0; - ParseConfigLine(Buffer); - } + FILE *File; + errno_t Error; + char exePath[MAX_PATH]; + char configPath[MAX_PATH]; + + // Get executable path + if(GetModuleFileNameA(NULL, exePath, MAX_PATH) == 0) + return; + + // Remove executable name to get directory + char *lastSlash = strrchr(exePath, '\\'); + if(lastSlash != NULL) + *lastSlash = '\0'; + + // Construct config file path + snprintf(configPath, MAX_PATH, "%s\\ntop.conf", exePath); + + Error = fopen_s(&File, configPath, "r"); + if(Error != 0) { + OutputDebugStringA("Did not open config file!\n"); + return; } - - free(Buffer); - fclose(File); + + size_t BufferSize = BUF_INCREASE; + size_t Offset = 0; + char *Buffer = xmalloc(BUF_INCREASE); + while(1) { + if(!fgets(Offset + Buffer, (int)(BufferSize - Offset), File)) { + break; + } + if(!feof(File) && !strchr(Buffer, '\n')) { + Offset = BufferSize - 1; + BufferSize += BUF_INCREASE; + Buffer = xrealloc(Buffer, BufferSize); + } else { + Offset = 0; + ParseConfigLine(Buffer); + } + } + free(Buffer); + fclose(File); } static WORD CurrentColor; @@ -1159,8 +1173,9 @@ static void WriteProcessInfo(const process *Process, BOOL Highlighted) ); } - - ConPrintf(_T("%*c"), Width-CharsWritten+1, _T(' ')); + if (InteractiveMode) { + ConPrintf(_T("%*c"), Width-CharsWritten+1, _T(' ')); + } } static ULONGLONG KeyPressStart = 0; @@ -1307,6 +1322,7 @@ static void PrintHelp(const TCHAR *argv0) { _T("-n NamePart,NamePart...\n"), _T("\tShow only processes containing at least one of the name parts.") }, { _T("-s COLUMN\n"), _T("\tSort by this column.") }, { _T("-u USERNAME\n"), _T("\tDisplay only processes of this user.") }, + { _T("-d"), _T("Do not run in interactive mode.") }, { _T("-v"), _T("Print version.") }, }; PrintHelpEntries(_T("OPTIONS"), _countof(Options), Options); @@ -1657,6 +1673,9 @@ int _tmain(int argc, TCHAR *argv[]) _tcscpy_s(FilterUserName, UNLEN, argv[i]); } break; + case _T('d'): + InteractiveMode = FALSE; + break; case _T('v'): PrintVersion(); return EXIT_SUCCESS; @@ -1700,26 +1719,28 @@ int _tmain(int argc, TCHAR *argv[]) InitializeCriticalSection(&SyncLock); SetConsoleCtrlHandler(CtrlHandler, TRUE); - OldConsoleHandle = ConsoleHandle; + + if (InteractiveMode) { + OldConsoleHandle = ConsoleHandle; + ConsoleHandle = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + 0, + CONSOLE_TEXTMODE_BUFFER, + 0); + + if(ConsoleHandle == INVALID_HANDLE_VALUE) { + Die(_T("Could not create console screen buffer: %ld\n"), GetLastError()); + } - ConsoleHandle = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, - 0, - CONSOLE_TEXTMODE_BUFFER, - 0); + if(!SetConsoleActiveScreenBuffer(ConsoleHandle)) { + Die(_T("Could not set active console screen buffer: %ld\n"), GetLastError()); + } - if(ConsoleHandle == INVALID_HANDLE_VALUE) { - Die(_T("Could not create console screen buffer: %ld\n"), GetLastError()); - } + SetConsoleMode(ConsoleHandle, ENABLE_PROCESSED_INPUT|ENABLE_WRAP_AT_EOL_OUTPUT); - if(!SetConsoleActiveScreenBuffer(ConsoleHandle)) { - Die(_T("Could not set active console screen buffer: %ld\n"), GetLastError()); + atexit(RestoreConsole); } - SetConsoleMode(ConsoleHandle, ENABLE_PROCESSED_INPUT|ENABLE_WRAP_AT_EOL_OUTPUT); - - atexit(RestoreConsole); - if(Monochrome) { Config = MonochromeConfig; } else { @@ -1750,152 +1771,163 @@ int _tmain(int argc, TCHAR *argv[]) #if _DEBUG ULONGLONG T1 = GetTickCount64(); #endif + if (InteractiveMode) { + SetConCursorPos(0, 0); + SetColor(Config.FGColor | Config.MenuBarColor); - SetConCursorPos(0, 0); - SetColor(Config.FGColor | Config.MenuBarColor); + int MenuBarOffsetX = Width / 2 - (int)_tcslen(MenuBar) / 2; + for(int i = 0; i < MenuBarOffsetX; i++) { + ConPutc(_T(' ')); + } - int MenuBarOffsetX = Width / 2 - (int)_tcslen(MenuBar) / 2; - for(int i = 0; i < MenuBarOffsetX; i++) { - ConPutc(_T(' ')); - } + ConPrintf(_T("%s"), MenuBar); - ConPrintf(_T("%s"), MenuBar); + for(int i = 0; i < Width - MenuBarOffsetX - (int)_tcslen(MenuBar); i++) { + ConPutc(_T(' ')); + } - for(int i = 0; i < Width - MenuBarOffsetX - (int)_tcslen(MenuBar); i++) { - ConPutc(_T(' ')); - } + SetColor(Config.FGColor); + WriteBlankLine(); - SetColor(Config.FGColor); - WriteBlankLine(); + /* CPU */ + int CharsWritten = 0; - /* CPU */ - int CharsWritten = 0; + CharsWritten += DrawPercentageBar(_T("CPU"), CPUUsage, Config.CPUBarColor); - CharsWritten += DrawPercentageBar(_T("CPU"), CPUUsage, Config.CPUBarColor); + int CPUInfoChars = 0; - int CPUInfoChars = 0; + TCHAR CPUNameBuf[] = _T(" Name: "); - TCHAR CPUNameBuf[] = _T(" Name: "); + CPUInfoChars += (int)_tcslen(CPUNameBuf); + TCHAR CPUInfoBuf[256]; + CPUInfoChars += wsprintf(CPUInfoBuf, _T("%s (%u Cores)"), CPUName, CPUCoreCount); - CPUInfoChars += (int)_tcslen(CPUNameBuf); - TCHAR CPUInfoBuf[256]; - CPUInfoChars += wsprintf(CPUInfoBuf, _T("%s (%u Cores)"), CPUName, CPUCoreCount); + int TaskInfoChars = 0; - int TaskInfoChars = 0; + TCHAR TasksNameBuf[] = _T(" Tasks: "); - TCHAR TasksNameBuf[] = _T(" Tasks: "); + TaskInfoChars += (int)_tcsclen(TasksNameBuf); + TCHAR TasksInfoBuf[256]; + TaskInfoChars += wsprintf(TasksInfoBuf, _T("%u total, %u running"), ProcessCount, RunningProcessCount); - TaskInfoChars += (int)_tcsclen(TasksNameBuf); - TCHAR TasksInfoBuf[256]; - TaskInfoChars += wsprintf(TasksInfoBuf, _T("%u total, %u running"), ProcessCount, RunningProcessCount); + if(CharsWritten + CPUInfoChars + TaskInfoChars < Width) { + SetColor(Config.FGHighlightColor); + ConPrintf(_T("%s"), CPUNameBuf); + SetColor(Config.FGColor); + ConPrintf(_T("%s"), CPUInfoBuf); + CharsWritten += CPUInfoChars; + } - if(CharsWritten + CPUInfoChars + TaskInfoChars < Width) { SetColor(Config.FGHighlightColor); - ConPrintf(_T("%s"), CPUNameBuf); + ConPrintf(_T("%s"), TasksNameBuf); SetColor(Config.FGColor); - ConPrintf(_T("%s"), CPUInfoBuf); - CharsWritten += CPUInfoChars; - } - - SetColor(Config.FGHighlightColor); - ConPrintf(_T("%s"), TasksNameBuf); - SetColor(Config.FGColor); - ConPrintf(_T("%s"), TasksInfoBuf); - CharsWritten += TaskInfoChars; + ConPrintf(_T("%s"), TasksInfoBuf); + CharsWritten += TaskInfoChars; - for(; CharsWritten < Width; CharsWritten++) { - ConPutc(_T(' ')); - } - - /* Memory */ - CharsWritten = DrawPercentageBar(_T("Mem"), UsedMemoryPerc, Config.MemoryBarColor); - - SetColor(Config.FGHighlightColor); - CharsWritten += ConPrintf(_T(" Size: ")); - SetColor(Config.FGColor); - CharsWritten += ConPrintf(_T("%d GB"), (int)TotalMemory/1000); + for(; CharsWritten < Width; CharsWritten++) { + ConPutc(_T(' ')); + } - for(; CharsWritten < Width; CharsWritten++) { - ConPutc(_T(' ')); - } + /* Memory */ + CharsWritten = DrawPercentageBar(_T("Mem"), UsedMemoryPerc, Config.MemoryBarColor); - CharsWritten = DrawPercentageBar(_T("Pge"), UsedPageMemoryPerc, Config.PageMemoryBarColor); + SetColor(Config.FGHighlightColor); + CharsWritten += ConPrintf(_T(" Size: ")); + SetColor(Config.FGColor); + CharsWritten += ConPrintf(_T("%d GB"), (int)TotalMemory/1000); - SetColor(Config.FGHighlightColor); - CharsWritten += ConPrintf(_T(" Uptime: ")); + for(; CharsWritten < Width; CharsWritten++) { + ConPutc(_T(' ')); + } - TCHAR Buffer[TIME_STR_SIZE]; - FormatTimeString(Buffer, TIME_STR_SIZE, UpTime); - SetColor(Config.FGColor); - CharsWritten += ConPrintf(_T("%s"), Buffer); - SetColor(Config.FGColor); + CharsWritten = DrawPercentageBar(_T("Pge"), UsedPageMemoryPerc, Config.PageMemoryBarColor); - for(; CharsWritten < Width; CharsWritten++) { - ConPutc(_T(' ')); - } + SetColor(Config.FGHighlightColor); + CharsWritten += ConPrintf(_T(" Uptime: ")); - WriteBlankLine(); + TCHAR Buffer[TIME_STR_SIZE]; + FormatTimeString(Buffer, TIME_STR_SIZE, UpTime); + SetColor(Config.FGColor); + CharsWritten += ConPrintf(_T("%s"), Buffer); + SetColor(Config.FGColor); - ProcessWindowHeight = Height - ProcessWindowPosY; - VisibleProcessCount = ProcessWindowHeight - 2; - - const process_list_column ProcessListColumns[] = { - { _T("ID"), 7 }, - { _T("USER"), 9 }, - { _T("PRI"), 3 }, - { _T("CPU%"), 5 }, - { _T("MEM"), 11 }, - { _T("THRD"), 4 }, - { _T("DISK"), 9 }, - { _T("TIME"), TIME_STR_SIZE - 1 }, - { _T("PROCESS"), -1 }, - }; - - DrawProcessListHeader(ProcessListColumns, _countof(ProcessListColumns)); - - CharsWritten = 0; - - EnterCriticalSection(&SyncLock); - DWORD Count = 0; - for(DWORD i = 0; i < VisibleProcessCount; i++) { - DWORD PID = i+ProcessIndex; - if(PID < ProcessCount) { - const process *Process = &ProcessList[PID]; - SetConCursorPos(0, (SHORT)(i + ProcessWindowPosY)); - WriteProcessInfo(Process, PID == SelectedProcessIndex); - Count++; + for(; CharsWritten < Width; CharsWritten++) { + ConPutc(_T(' ')); } - } - LeaveCriticalSection(&SyncLock); - SetColor(0); - for(DWORD i = Count; i < VisibleProcessCount - 1; i++) { WriteBlankLine(); - } - SetConCursorPos(0, (SHORT)Height-2); - - SetColor(FOREGROUND_WHITE); - - /* Disable auto newline here. This allows us to fill the last row entirely - * without scrolling the screen buffer accidentally which is really annoying. */ - SetConsoleMode(ConsoleHandle, ENABLE_PROCESSED_INPUT|DISABLE_NEWLINE_AUTO_RETURN); - if (InInputMode) { - CharsWritten = ConPrintf(_T("\n%s"), CurrentInputStr); - if (CaretState) { - ConPutc(_T('_')); - ++CharsWritten; + ProcessWindowHeight = Height - ProcessWindowPosY; + VisibleProcessCount = ProcessWindowHeight - 2; + + const process_list_column ProcessListColumns[] = { + { _T("ID"), 7 }, + { _T("USER"), 9 }, + { _T("PRI"), 3 }, + { _T("CPU%"), 5 }, + { _T("MEM"), 11 }, + { _T("THRD"), 4 }, + { _T("DISK"), 9 }, + { _T("TIME"), TIME_STR_SIZE - 1 }, + { _T("PROCESS"), -1 }, + }; + + DrawProcessListHeader(ProcessListColumns, _countof(ProcessListColumns)); + + CharsWritten = 0; + + EnterCriticalSection(&SyncLock); + DWORD Count = 0; + for(DWORD i = 0; i < VisibleProcessCount; i++) { + DWORD PID = i+ProcessIndex; + if(PID < ProcessCount) { + const process *Process = &ProcessList[PID]; + SetConCursorPos(0, (SHORT)(i + ProcessWindowPosY)); + WriteProcessInfo(Process, PID == SelectedProcessIndex); + Count++; + } + } + LeaveCriticalSection(&SyncLock); + + SetColor(0); + for(DWORD i = Count; i < VisibleProcessCount - 1; i++) { + WriteBlankLine(); } + + SetConCursorPos(0, (SHORT)Height-2); + SetColor(FOREGROUND_WHITE); + + /* Disable auto newline here. This allows us to fill the last row entirely + * without scrolling the screen buffer accidentally which is really annoying. */ + SetConsoleMode(ConsoleHandle, ENABLE_PROCESSED_INPUT|DISABLE_NEWLINE_AUTO_RETURN); + if (InInputMode) { + CharsWritten = ConPrintf(_T("\n%s"), CurrentInputStr); + if (CaretState) { + ConPutc(_T('_')); + ++CharsWritten; + } - for(; CharsWritten < Width; CharsWritten++) { - ConPutc(_T(' ')); + for(; CharsWritten < Width; CharsWritten++) { + ConPutc(_T(' ')); + } + } else if(ViMessageActive()) { + WriteVi(); + } else { + ConPrintf(_T("\n%*c"), Width - 1, _T(' ')); } - } else if(ViMessageActive()) { - WriteVi(); - } else { - ConPrintf(_T("\n%*c"), Width - 1, _T(' ')); + SetConsoleMode(ConsoleHandle, ENABLE_PROCESSED_INPUT|ENABLE_WRAP_AT_EOL_OUTPUT); + } + else { + ConPrintf(_T(" ID USER PRI CPU%% MEM THRD DISK TIME PROCESS")); + EnterCriticalSection(&SyncLock); + for(DWORD i = 0; i < ProcessCount; i++) { + const process *Process = &ProcessList[i]; + WriteProcessInfo(Process, FALSE); + } + ConPrintf(_T("\n")); + LeaveCriticalSection(&SyncLock); + exit(EXIT_SUCCESS); } - SetConsoleMode(ConsoleHandle, ENABLE_PROCESSED_INPUT|ENABLE_WRAP_AT_EOL_OUTPUT); #ifdef _DEBUG ULONGLONG T2 = GetTickCount64();