Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Extending Task Manager with DLL Injection

, 19 May 2005
How to extend the features of Windows Task Manager using DLL injection.
#include "stdafx.h"
#include "TaskExApp.h"
#include "TaskExDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define WM_TRAY_ICON_NOTIFY_MESSAGE (WM_USER + 777)

TaskExDlg::TaskExDlg(CWnd* pParent)
	: CDialog(TaskExDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void TaskExDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(TaskExDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_MESSAGE(WM_TRAY_ICON_NOTIFY_MESSAGE, OnTrayNotify)
	ON_BN_CLICKED(IDOK, OnBnClickedOk)
END_MESSAGE_MAP()

BOOL TaskExDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	m_nidIconData.cbSize			= sizeof(NOTIFYICONDATA);
	m_nidIconData.hWnd				= 0;
	m_nidIconData.uID				= 1;
	m_nidIconData.uCallbackMessage	= WM_TRAY_ICON_NOTIFY_MESSAGE;
	m_nidIconData.hIcon				= 0;
	m_nidIconData.szTip[0]			= 0;	
	m_nidIconData.uFlags			= NIF_MESSAGE | NIF_ICON;
	m_nidIconData.hIcon = m_hIcon;

	m_nidIconData.hWnd = this->m_hWnd;
	m_nidIconData.uID = 1;

	Shell_NotifyIcon(NIM_ADD,&m_nidIconData);

	SetIcon(m_hIcon, TRUE);
	SetIcon(m_hIcon, FALSE);

	DWORD tid;
	CreateThread(NULL, 0, GetTaskManagerThread, this, 0, &tid);
	
	return TRUE;
}

void TaskExDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this);

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR TaskExDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void TaskExDlg::OnBnClickedOk()
{
	if(m_nidIconData.hWnd && m_nidIconData.uID>0)
	{
		Shell_NotifyIcon(NIM_DELETE,&m_nidIconData);
	}

	OnOK();
}

void TaskExDlg::Install(HWND hWnd, DWORD pid)
{
	m_taskManagers.insert(pid);

	HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
									FALSE, pid);	

	if (hProcess != NULL)
	{
		HANDLE hThread;
		char   szLibPath [_MAX_PATH];
		void*  pLibRemote = 0;
		DWORD  hLibModule = 0;

		HMODULE hKernel32 = ::GetModuleHandle("Kernel32");

		if( !::GetSystemDirectory(szLibPath, _MAX_PATH))
			return;

		strcat(szLibPath, "\\InstallTaskHook.dll");

		pLibRemote = ::VirtualAllocEx( hProcess, NULL, sizeof(szLibPath), MEM_COMMIT, PAGE_READWRITE );
		
		if( pLibRemote == NULL )
			return;

		::WriteProcessMemory(hProcess, pLibRemote, (void*)szLibPath,sizeof(szLibPath),NULL);

		hThread = ::CreateRemoteThread( hProcess, NULL, 0,	
						(LPTHREAD_START_ROUTINE) ::GetProcAddress(hKernel32,"LoadLibraryA"), 
						pLibRemote, 0, NULL );

		if( hThread != NULL )
		{
			::WaitForSingleObject( hThread, INFINITE );
			::GetExitCodeThread( hThread, &hLibModule );
			::CloseHandle( hThread );
			
		}


	}
}

BOOL CALLBACK TaskExDlg::EnumProc(HWND hWnd, LPARAM p)
{
	char szTitle[24];

	::GetWindowText(hWnd, szTitle, sizeof(szTitle));

	if (strcmp(szTitle, "Windows Task Manager") == 0)
	{
		TaskExDlg *This = (TaskExDlg *)p;
		DWORD pid;
		GetWindowThreadProcessId(hWnd, &pid);

		if (This->m_taskManagers.find(pid) == This->m_taskManagers.end())
		{
			This->Install(hWnd, pid);
		}
	}

	return TRUE;
}

DWORD WINAPI TaskExDlg::GetTaskManagerThread(LPVOID p)
{
	while(true)
	{
		EnumWindows(EnumProc, (LPARAM)p);

		Sleep(1000);
	}

	return 0;
}

BOOL isVisible = TRUE;

LRESULT TaskExDlg::OnTrayNotify(WPARAM wParam, LPARAM lParam) 
{ 
    UINT uID; 
    UINT uMsg; 
 
    uID = (UINT) wParam; 
    uMsg = (UINT) lParam; 
 
	if (uID != 1)
		return 0;
	
	CPoint pt;	

    switch (uMsg ) 
	{ 
	case WM_LBUTTONDBLCLK:
		ShowWindow(!isVisible);
		isVisible = !isVisible;
		break;
    } 
     return 0; 
 } 

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

rocky_pulley
Web Developer
United States United States
I live in the Nothern Virginia/Washington D.C. area. I have been working in the software industry since 1995. My skills are primarily in C++ and Java on Windows and Unix platforms but I also work with C# and some other programming languages (even PL/I and COBOL when necessary!).
 
Check out my software web site: http://www.dreamsyssoft.com
 

| Advertise | Privacy | Mobile
Web02 | 2.8.141029.1 | Last Updated 19 May 2005
Article Copyright 2005 by rocky_pulley
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid