Click here to Skip to main content
15,897,718 members
Articles / Desktop Programming / MFC

Task Manager Extension 2.0

Rate me:
Please Sign up or sign in to vote.
4.92/5 (149 votes)
22 Jan 2007CDDL11 min read 598.7K   18.7K   263  
Task Manager Extension. This is a Windows Task Manager (NT/2000/XP/2003) plug-in. It adds lots of useful features to the standard Task Manager. It can show process modules, memory map, used handles, open files, file properties and a lot of other info!
// TaskManagerEx.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "LoadDll.h"
#include <locale.h>
#include "SplashWnd.h"
#include "Resource.h"

#include "../TaskManagerExDll/Localization.h"
#include "../TaskManagerExDll/TaskManagerEx.h"
#include "../TaskManagerExDll/Taskmgr.h"
#include "../TaskManagerExDll/Options.h"

DWORD	dwWindowsNTMajorVersion = 0;
HWND	hwndTaskManager = NULL;

HANDLE hAnotherTaskManagerExEvent = NULL;
LPCTSTR szGlobalKernelName = _T("Local\\TaskManagerExIsAlreadyRunning");

static char g_szStamp_Mark[] = "\r\n\r\nTaskManagerEx.cpp Timestamp: " __DATE__ ", " __TIME__ "\r\n\r\n";

//////////////////////////////////////////////////////////////////////////

BOOL IsAnotherTaskManagerEx_Capture( BOOL bInitialState )
{
	if( hAnotherTaskManagerExEvent != NULL )
	{
		return TRUE;
	}
	hAnotherTaskManagerExEvent = CreateEvent( NULL, TRUE, bInitialState, szGlobalKernelName );	

	DWORD dwer = GetLastError();	

	return (dwer==ERROR_ALREADY_EXISTS);
}

//////////////////////////////////////////////////////////////////////////

void ReleaseAnotherTaskManagerEx()
{
	if( hAnotherTaskManagerExEvent != NULL )
	{
		CloseHandle( hAnotherTaskManagerExEvent );
		hAnotherTaskManagerExEvent = NULL;
	}
}

//////////////////////////////////////////////////////////////////////////

DWORD GetTaskManagerProcessID()
{
	DWORD pID = 0;

	GetWindowThreadProcessId( hwndTaskManager, &pID );

	return pID;
}

//////////////////////////////////////////////////////////////////////////

//void MySleep( DWORD dwMilliseconds ) // for simplier debug
//{
//	Sleep(dwMilliseconds);
//}

DWORD MyWaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ) // for simplier debug
{
	DWORD res = WaitForSingleObject( hHandle, dwMilliseconds );
	return res;
}

//////////////////////////////////////////////////////////////////////////

TCHAR szDllPath[_MAX_PATH] = _T(""); // TaskManagerEx.dll name

//////////////////////////////////////////////////////////////////////////

VOID CALLBACK ThreadTimerProc(
	HWND hwnd,
    UINT uMsg,
    UINT idEvent,
    DWORD dwTime
)
{
	hwnd = hwnd;
	uMsg = uMsg;
	idEvent = idEvent;
	dwTime = dwTime;

	hwndTaskManager = FindTaskManagerWindow();
	if( hwndTaskManager != NULL )
	{
		DWORD processId = GetTaskManagerProcessID();
		#ifdef _DEBUG
		TCHAR s[200] = _T("");
		wsprintf( s, _T("TaskManagerEx> LoadDllForRemoteThread for PID = %d\n"),
			processId );
		OutputDebugString( s );
		#endif

		DWORD dwRet = LoadDllForRemoteThread( 
				processId, 
				TRUE, 
				FALSE, 
				szDllPath,
				"Initialize",
				NULL,
				NULL,
				NULL,
				NULL,
				NULL,
				0,
				NULL
				);

		if( dwRet != 0 )
		{
			#ifdef _DEBUG
			TCHAR s[200] = _T("");
			wsprintf( s, _T("TaskManagerEx> LoadDllForRemoteThread for PID = %d returned %d (0x%X)\n"),
				processId, dwRet, dwRet );
			OutputDebugString( s );
			#endif
		}

		BOOL bRunOnceOnly = FALSE;

		{
			HKEY hKey = NULL;
			DWORD dwType = REG_DWORD;
			DWORD dwSize = sizeof(DWORD);
			LONG lRes;
			DWORD dwValue;

			::RegOpenKey( REG_ROOT, REG_KEY, &hKey );

			if( hKey != NULL )
			{
				dwType = REG_DWORD; dwSize = sizeof(DWORD);
				lRes = ::RegQueryValueEx( hKey, _T("LoaderStartOnceOnly"), NULL, &dwType, 
						(LPBYTE)&dwValue, &dwSize );

				if( lRes == ERROR_SUCCESS )
				{
					bRunOnceOnly = dwValue != 0;
				}

				::RegCloseKey( hKey );
			}
		}

		if( bRunOnceOnly )
		{
			ResetEvent( hAnotherTaskManagerExEvent ); // Stop process after one Dll load
		}
	}

	DWORD res = MyWaitForSingleObject( hAnotherTaskManagerExEvent, 0 );
	if( res != WAIT_OBJECT_0 )
	{
		PostQuitMessage( 0 );
	}
}

//////////////////////////////////////////////////////////////////////////

//LPCTSTR g_szLocale = NULL;

//////////////////////////////////////////////////////////////////////////

int MainFunction()
{
//	g_szLocale = _tsetlocale( LC_ALL, _T("") ); // it is commented because CRT was reduced from this project
												// so there is no need in localization of CRT library
	BOOL res;
	DWORD dwBufSize;

	TCHAR szCaption[200] = _T("");
	TCHAR szRequireNT[200] = _T("");
	TCHAR szGetModuleFilenameError[200] = _T("");
	TCHAR szCommandLineHelp[5000] = _T("");

	dwBufSize = SIZEOF_ARRAY(szCaption);
	LocLoadString(IDS_MESSAGEBOX_CAPTION, szCaption, &dwBufSize );
	dwBufSize = SIZEOF_ARRAY(szRequireNT);
	LocLoadString(IDS_REQUIRE_NT, szRequireNT, &dwBufSize );
	dwBufSize = SIZEOF_ARRAY(szGetModuleFilenameError);
	LocLoadString(IDS_GETMODULEFILNAME_ERROR, szGetModuleFilenameError, &dwBufSize );
	dwBufSize = SIZEOF_ARRAY(szCommandLineHelp);
	LocLoadString(IDS_COMMANDLINE_HELP, szCommandLineHelp, &dwBufSize );

	LPWSTR szCommandLineW = GetCommandLineW();
	if( szCommandLineW == NULL )
	{
		return -1;
	}
	int argc = 0;
	LPWSTR* argv = CommandLineToArgvW( szCommandLineW, &argc );
	if( argv == NULL )
	{
		MessageBox( NULL, szRequireNT, szCaption, MB_OK | MB_ICONERROR );
		return -1;
	}

	BOOL bAnother = FALSE;

	BOOL bUnload =	FALSE;
	BOOL bRestart =	FALSE;

	if( argc > 1 )
	{
		bUnload =	lstrcmpW( argv[1], L"/u" ) == 0 ||
					lstrcmpW( argv[1], L"/U" ) == 0;
		bRestart =	lstrcmpW( argv[1], L"/r" ) == 0 ||
					lstrcmpW( argv[1], L"/R" ) == 0;

		if( argc > 2 || ( !bUnload && !bRestart ) )
		{
			MessageBox( NULL, szCommandLineHelp, szCaption, MB_OK | MB_ICONINFORMATION );
			GlobalFree( argv );
			return 1;
		}

		if( bUnload )
		{
			bAnother = IsAnotherTaskManagerEx_Capture( TRUE );
			if( bAnother )
			{
				ResetEvent( hAnotherTaskManagerExEvent );
			}
			ReleaseAnotherTaskManagerEx();
			GlobalFree( argv );
			return 0;
		}
		else if( bRestart )
		{
			bAnother = IsAnotherTaskManagerEx_Capture( TRUE );
			if( bAnother )
			{
				ResetEvent( hAnotherTaskManagerExEvent );
				DWORD dwRet = MyWaitForSingleObject( hAnotherTaskManagerExEvent, 3000 );
				if( dwRet != WAIT_OBJECT_0 )
				{
					ASSERT( FALSE && "WaitForSingleObject error!" );
					GlobalFree( argv );
					return -1;
				}
			}
			bAnother = FALSE;
		}
		else
		{
			ASSERT(FALSE);
			// return -1; // warning C4702: unreachable code
		}
	}
	else
	{
		bAnother = IsAnotherTaskManagerEx_Capture( TRUE );
	}

	GlobalFree( argv );
	argv = NULL;

	if( bAnother != FALSE )
	{
		return 0;
	}

	if( hAnotherTaskManagerExEvent == NULL )
	{
		ASSERT(FALSE);
		return -1;
	}

	dwWindowsNTMajorVersion = IsWindowsNT();

	if ( dwWindowsNTMajorVersion < 4 )
	{
		MessageBox( NULL, szRequireNT, szCaption, MB_OK | MB_ICONERROR );
		return -1;
	}


	res = GetModuleFileName( NULL, szDllPath, _MAX_PATH );
	if ( !res )
	{
		MessageBox( NULL, szGetModuleFilenameError, szCaption, MB_OK | MB_ICONERROR );
		return -2;
	}

	LPTSTR p = NULL;

	for( int i = lstrlen(szDllPath)-1; i>=0; i-- )
	{
		if( szDllPath[i] == _T('\\') )
		{
			p = &szDllPath[i];
			break;
		}
	}

	if( p == NULL )
	{
	   p = szDllPath;
	}
	else
	{
	   p++;
	}

	lstrcpy( p, TMEX_INJECT_DLL );

	//////////////////////////////////////////////////////////////////////////
	//Let's work

	COptions options;
	BOOL bSplash = options.GetShowSplash();

	if( bSplash )
	{
		res = CreateSplashScreen();
	}

	SetTimer( NULL, 0, 400, ThreadTimerProc );

	MSG msg;

	while( (res = GetMessage( &msg, NULL, 0, 0 )) != 0)
	{ 
		if (res == -1)
		{
			// handle the error and possibly exit
			break;
		}
		else
		{
			TranslateMessage(&msg); 
			DispatchMessage(&msg); 
		}
	} 

	SetEvent( hAnotherTaskManagerExEvent );
	ReleaseAnotherTaskManagerEx();

	return 0;
}

///////////////////////////////////////////////////////////////////////////////////
///  CRT:

/*
#ifdef SUBSYSTEM_WINDOWS

int CALLBACK _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
{
	int res = MainFunction();
	return res;
}

#else

int _tmain( int, TCHAR ** ) //( int argc, TCHAR **argv )
{
	int res = MainFunction();
	return res;
}

#endif
//*/

//////////////////////////////////////////////////////////////////////////

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)


Written By
Software Developer (Senior)
Belarus Belarus
He is a young and forward-looking software developer. He also has lots of interesting hobbies like snowboarding, bicycle riding, carting racing and of course talking about himself in a third person. Smile | :)

github.com/kolomenkin

Curriculum Vitae

Comments and Discussions