Click here to Skip to main content
15,897,360 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!
//////////////////////////////////////////////////////////////
// File:		// main.cpp
// File time:	// 25.04.2005	12:14
// Version: 	// 1.0
/******************************************************************************
Module:  AccessMaster.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
Modified: Sergey Kolomenkin, 2005
******************************************************************************/
// Description: //////////////////////////////////////////////
//   Some useful routines...
//   

#include "stdafx.h"
//#include <windows.h>

#include "CmnHdr.h"              /* See Appendix A. */
#include <WindowsX.h>
#include <stdio.h>

#include "SecurityInformation.h"
#include "Resource.h"

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

typedef struct _ObjEntry
{
   OB_TYPE_ENUM   m_nSpecificType;
   PTSTR          m_pszComboText;
   PTSTR          m_pszUsageText;
   BOOL           m_fUseName;
   BOOL           m_fUseHandle;
   BOOL           m_fUsePID;
} ObjEntry;



ObjEntry g_objMap[] =
{
   {OB_TYPE_TOKEN, TEXT("Access Token"),
         TEXT("To view the access rights of an access token enter the ")
         TEXT("numerical value of its handle and process ID in the ")
         TEXT("\"Handle\" and \"PID/TID\" fields."),
         FALSE, TRUE, TRUE},
   {OB_TYPE_ANONPIPE, TEXT("Anonymous Pipe"),
         TEXT("To view the access rights of an Anonymous Pipe enter the ")
         TEXT("numerical value of its handle and process ID in the ")
         TEXT("\"Handle\" and \"PID/TID\" fields."),
         FALSE, TRUE, TRUE},
   {OB_TYPE_DESKTOP, TEXT("Desktop"), // XXXXXXXXX
         TEXT("To view the access rights of a Desktop object either enter ")
         TEXT("the Window Station and Desktop names in the \"Name\" field, ")
         TEXT("or the numerical value of its handle and process ID in the ")
         TEXT("\"Handle\" and \"PID/TID\" ")
         TEXT("fields.\r\nExample: \"Winsta0\\Default\""),
         TRUE, TRUE, TRUE},
   {OB_TYPE_DIRECTORY, TEXT("Directory"), // XXXXXXXXX
         TEXT("To view the access rights of a directory enter the fully ")
         TEXT("qualified path in the \"Name\" field."),
         TRUE, FALSE, FALSE}, // !!!!!!!!!!!!!!!!!!
   {OB_TYPE_EVENT, TEXT("Event"),
         TEXT("To view the access rights of an Event either enter the ")
         TEXT("object's name in the \"Name\" field, or the numerical value ")
         TEXT("of its handle and process ID in ")
         TEXT("the \"Handle\" and \"PID/TID\" fields."),
         TRUE, TRUE, TRUE},
   {OB_TYPE_FILE, TEXT("File"), // XXXXXXXXX
         TEXT("To view the access rights of a file either enter the fully ")
         TEXT("qualified path and filname in the \"Name\" field, or the ")
         TEXT("numerical value of the handle and process in the \"Handle\" ")
         TEXT("and \"PID/TID\" fields."),
         TRUE, TRUE, TRUE}, // !!!!!!!!!!!!!!!!!!
   {OB_TYPE_SECTION, TEXT("File Mapping"),
         TEXT("To view the access rights of a file mapping either enter ")
         TEXT("the object's name in the \"Name\" field, or the numerical ")
         TEXT("value of its handle and process ID in the \"Handle\" and ")
         TEXT("\"PID/TID\" fields."),
         TRUE, TRUE, TRUE},
   {OB_TYPE_JOB, TEXT("Job"),
         TEXT("Enter the numerical value of the Job's handle and process ")
         TEXT("ID's in the \"Handle\" and \"PID/TID\" fields."),
         FALSE, TRUE, TRUE},   
   {OB_TYPE_MUTANT, TEXT("Mutex"),
         TEXT("To view the access rights of a Mutex either enter the ")
         TEXT("object's name in the \"Name\" field, or the numerical value ")
         TEXT("of its handle and process ID in ")
         TEXT("the \"Handle\" and \"PID/TID\" fields."),
         TRUE, TRUE, TRUE},
   {OB_TYPE_NAMEDPIPE, TEXT("Named Pipe"),
         TEXT("To view the access rights of a Named Pipe enter the numerical ")
         TEXT("value of its handle and process ID in ")
         TEXT("the \"Handle\" and \"PID/TID\" fields."),
         FALSE, TRUE, TRUE},
   {OB_TYPE_PRINTER, TEXT("Printer"), // XXXXXXXXX
         TEXT("To view the access rights of a printer or print server enter ")
         TEXT("the object's fully qualified UNC name in the \"Name\" field."),
         TRUE, FALSE, FALSE},
   {OB_TYPE_PROCESS, TEXT("Process"),
         TEXT("Enter a Process' ID in the \"PID/TID\" field."),
         FALSE, FALSE, TRUE},
   {OB_TYPE_KEY, TEXT("Registry Key"), // XXXXXXXXX
         TEXT("To view the access rights of a registry key either enter the ")
         TEXT("fully qualified path and keyname in the \"Name\" field, or ")
         TEXT("the numerical value of the handle and process in the ")
         TEXT("\"Handle\" and \"PID/TID\" fields.  \r\nExample: \"\\\\machine")
         TEXT("name\\CLASSES_ROOT\\somepath\r\n\r\nThe following predefined ")
         TEXT("registry key values can be used:  \"CLASSES_ROOT\", \"CURRENT_")
         TEXT("USER\", \"MACHINE\", and \"USERS\"."),
         TRUE, TRUE, TRUE}, // !!!!!!!!!!!!!!!!!!
   {OB_TYPE_SEMAPHORE, TEXT("Semaphore"),
         TEXT("To view the access rights of a Semaphore either enter the ")
         TEXT("object's name in the \"Name\" field, or the numerical value ")
         TEXT("of its handle and process ID in the \"Handle\" ")
         TEXT("and \"PID/TID\" fields."),
         TRUE, TRUE, TRUE},
   {OB_TYPE_SERVICE, TEXT("Service"), // XXXXXXXXX
         TEXT("To view the access rights of a service enter the service's ")
         TEXT("programmatic name in the \"Name\" field."),
         TRUE, FALSE, FALSE},
   {OB_TYPE_SHARE, TEXT("Share"), // XXXXXXXXX
         TEXT("Enter a network share name in the \"Name\" field.  A share ")
         TEXT("object can be local, such as \"sharename\"; or ")
         TEXT("remote, such as \"\\\\machinename\\sharename\"."),
         TRUE, FALSE, FALSE},
   {OB_TYPE_THREAD, TEXT("Thread"),
         TEXT("Enter a Thread's Thread-ID or TID in the \"PID/TID\" field"),
         FALSE, FALSE, TRUE},
   {OB_TYPE_TIMER, TEXT("Waitable Timer"),
         TEXT("To view the access rights of a Waitable Timer either enter ")
         TEXT("the object's name in the \"Name\" field, or the numerical value ")
         TEXT("of its handle and process ID in ")
         TEXT("the \"Handle\" and \"PID/TID\" fields."),
         TRUE, TRUE, TRUE},
   {OB_TYPE_WINDOW_STATION, TEXT("Window Station"), // XXXXXXXXX
         TEXT("To view the access rights of a Window Station either enter ")
         TEXT("the object's name in the \"Name\" field, or the numerical ")
         TEXT("value of its handle and process ID in the \"Handle\" and ")
         TEXT("\"PID/TID\" fields.\r\nExample: \"Winsta0\""),
         TRUE, TRUE, TRUE}
};

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


void ReportError(PTSTR szFunction, ULONG lErr)
{
	TCHAR szBuf[200] = _T("");
	_stprintf( szBuf, _T("An error occurred calling function \"%s\": error %d"), szFunction, lErr );
	MessageBox(NULL, szBuf, TEXT("Security Notice"), MB_OK);
}

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


void UpdateObjDependentCtrls(HWND hwnd)
{
   // Setup controls for selected object type
   HWND hwndCtrl = GetDlgItem(hwnd, IDC_TYPE);
   int nIndex = ComboBox_GetCurSel(hwndCtrl);

   SetDlgItemText(hwnd, IDE_USAGE, g_objMap[nIndex].m_pszUsageText);

   hwndCtrl = GetDlgItem(hwnd, IDE_NAME);
   EnableWindow(hwndCtrl, g_objMap[nIndex].m_fUseName);

   hwndCtrl = GetDlgItem(hwnd, IDE_HANDLE);
   EnableWindow(hwndCtrl, g_objMap[nIndex].m_fUseHandle);

   hwndCtrl = GetDlgItem(hwnd, IDE_PID);
   EnableWindow(hwndCtrl, g_objMap[nIndex].m_fUsePID);

   if (g_objMap[nIndex].m_fUsePID || g_objMap[nIndex].m_fUseHandle) {
      hwndCtrl = GetDlgItem(hwnd, IDR_HANDLE);
      EnableWindow(hwndCtrl, TRUE);
   } else {
      hwndCtrl = GetDlgItem(hwnd, IDR_HANDLE);
      EnableWindow(hwndCtrl, FALSE);
      CheckRadioButton(hwnd, IDR_NAME, IDR_HANDLE, IDR_NAME);
   }

   if (g_objMap[nIndex].m_fUseName) {
      hwndCtrl = GetDlgItem(hwnd, IDR_NAME);
      EnableWindow(hwndCtrl, TRUE);
   } else {
      hwndCtrl = GetDlgItem(hwnd, IDR_NAME);
      EnableWindow(hwndCtrl, FALSE);
      CheckRadioButton(hwnd, IDR_NAME, IDR_HANDLE, IDR_HANDLE);
   }
}


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


BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
   chSETDLGICONS(hwnd, IDI_ACCESSMASTER);

   CheckDlgButton(hwnd, IDR_NAME, BST_CHECKED);

   TCHAR szTitle[1024];
   lstrcpy(szTitle, TEXT("AccessMaster is running as \""));
   ULONG lSize = chDIMOF(szTitle)-lstrlen(szTitle);
   GetUserName(szTitle+lstrlen(szTitle),&lSize);
   lstrcat(szTitle, TEXT("\""));
   SetWindowText(hwnd, szTitle);

   // Set-up the object type combo
   int nIndex = chDIMOF(g_objMap);
   HWND hwndCtrl = GetDlgItem(hwnd, IDC_TYPE);
   while (nIndex-- != 0) {
      ComboBox_InsertString(hwndCtrl, 0, g_objMap[nIndex].m_pszComboText);
   }

   ComboBox_SetCurSel(hwndCtrl, 0);
   UpdateObjDependentCtrls(hwnd);

   return(TRUE);
}


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


void HandleType(HWND hwnd, UINT codeNotify, HWND hwndCtl)
{
   if (codeNotify == CBN_SELCHANGE)
      UpdateObjDependentCtrls(hwnd);
}


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


void HandleRadio(HWND hwnd, UINT codeNotify, UINT nCtrl)
{
   if (codeNotify == EN_SETFOCUS)
      CheckRadioButton(hwnd, IDR_NAME, IDR_HANDLE, nCtrl);
}


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


BOOL FillInfo(HWND hwnd, ObjectInformation* pInfo, ObjEntry** pEntry)
{
   BOOL fReturn = FALSE;

   // Map object type to data block in the object map
   HWND hwndCtrl = GetDlgItem(hwnd, IDC_TYPE);
   int nIndex = ComboBox_GetCurSel(hwndCtrl);
//   pInfo->m_pEntry = g_objMap + nIndex;
   ObjEntry* m_pEntry = NULL;
/*
   for( int i=0; i<chDIMOF(g_objMap); i++ )
   {
	   if( g_objMap[i].m_objType == ??? )
	   {
		   m_pEntry = &g_objMap[i];
		   break;
	   }
   }
*/
   m_pEntry = g_objMap + nIndex;
   pInfo->m_objInternalType = m_pEntry->m_nSpecificType;
   *pEntry = m_pEntry;

//   USES_CONVERSION;

   // Copy the object's name into the info block for building the title text
//   lstrcpyW(pInfo->m_szObjectName, T2W(m_pEntry->m_pszComboText) );

   // Is it a named item?
   if (IsDlgButtonChecked(hwnd, IDR_NAME)) {
      switch (m_pEntry->m_nSpecificType) {
         
         case OB_TYPE_WINDOW_STATION:
            { // If windowstation, we must translate the name to a handle
               HWINSTA hwinsta = NULL;
               GetDlgItemText(hwnd, IDE_NAME, pInfo->m_szName, 
                     chDIMOF(pInfo->m_szName));
               // Get the maximum possible access
               hwinsta = OpenWindowStation(pInfo->m_szName, FALSE, 
                        MAXIMUM_ALLOWED);

               if (hwinsta == NULL) // Still failed?
                  ReportError(TEXT("OpenWindowStation"), GetLastError());
               else { // Otherwise finish title text
                  fReturn = TRUE;
                  pInfo->m_hHandle = (HANDLE) hwinsta;
//                  lstrcatW(pInfo->m_szObjectName, L" - " );
//                  lstrcatW(pInfo->m_szObjectName, T2W(pInfo->m_szName) ); 
//				  lstrcat(pInfo->m_szObjectName, _T(" - ") );
				  lstrcpy(pInfo->m_szObjectName, pInfo->m_szName ); 
                  pInfo->m_szName[0] = 0;
               }
            }
            break;

         case OB_TYPE_DESKTOP:
            { // If desktop, we must translate the name to a handle
               HWINSTA hwinstaOld;
               HWINSTA hwinstaTemp;
               HDESK hdesk=NULL;
               PTSTR pszWinSta;
               PTSTR pszDesktop;
               int nIndex;

               GetDlgItemText(hwnd, IDE_NAME, pInfo->m_szName, 
                     chDIMOF(pInfo->m_szName));
               pszWinSta = pInfo->m_szName;
               nIndex = lstrlen(pInfo->m_szName);
               
               // Parse the text for windowstation and desktop
               while (nIndex-- != 0) {

                  if (pInfo->m_szName[nIndex] == TEXT('\\') 
                        || pInfo->m_szName[nIndex] == TEXT('/')) {

                     pInfo->m_szName[nIndex] = 0;
                     break;
                  }
               }
            
               // Desktop string
               nIndex++;
               pszDesktop = pInfo->m_szName + nIndex;
               // Open the windowstation
               hwinstaTemp = OpenWindowStation(pszWinSta, FALSE, 
                     DESKTOP_ENUMERATE);
               if (hwinstaTemp != NULL) {
                  // Save the last one
                  hwinstaOld = GetProcessWindowStation();
                  SetProcessWindowStation(hwinstaTemp);
                  // Get maximum access to the desktop
                  hdesk = OpenDesktop(pszDesktop, 0, FALSE, 
                           MAXIMUM_ALLOWED);
                  if (hdesk == NULL)// failed?
                     ReportError(TEXT("OpenDesktop"), GetLastError());
                  else { // build title
                     fReturn = TRUE; 
                     pInfo->m_hHandle = (HANDLE) hdesk;
//					  lstrcatW(pInfo->m_szObjectName, L" - " );
//					  lstrcatW(pInfo->m_szObjectName, T2W(pszDesktop) ); 
//					  lstrcat(pInfo->m_szObjectName, _T(" - ") );
					  lstrcpy(pInfo->m_szObjectName, pszDesktop ); 
                     pInfo->m_szName[0] = 0;
                  }
                  
                  // Close and reset window stations for the process
                  CloseWindowStation(hwinstaTemp);
                  SetProcessWindowStation(hwinstaOld);
            
               } else // Failed open winsta
                  ReportError(TEXT("OpenWindowStation"), GetLastError());
            }
            break;

         default: // The rest of named objects work with GetNamedSecurity...
            GetDlgItemText(hwnd, IDE_NAME, pInfo->m_szName, 
                  chDIMOF(pInfo->m_szName));
//              lstrcatW(pInfo->m_szObjectName, L" - " );
//			  lstrcatW(pInfo->m_szObjectName, T2W(pInfo->m_szName) ); 
//              lstrcat(pInfo->m_szObjectName, _T(" - ") );
			  lstrcpy(pInfo->m_szObjectName, pInfo->m_szName ); 
            fReturn = TRUE;
            break;
      }
   
   } else { // Is it a handle and or process id we are dealing with?

      BOOL fTrans;
      // Get the actual numbers
      ULONG lPid = GetDlgItemInt(hwnd, IDE_PID, &fTrans, FALSE);
      HANDLE hHandle = (HANDLE) GetDlgItemInt(hwnd, IDE_HANDLE, &fTrans, 
            FALSE);
      HANDLE hObj = NULL;

      switch (m_pEntry->m_nSpecificType) {

         case OB_TYPE_THREAD: // Maximum access to the thread
            hObj = OpenThread(MAXIMUM_ALLOWED, FALSE, lPid);
            if (hObj == NULL) // None == failure
               ReportError(TEXT("OpenThread"), GetLastError());
            break;

         case OB_TYPE_PROCESS: // Get maximum access to the process
            hObj = OpenProcess(MAXIMUM_ALLOWED, FALSE, lPid);
            if (hObj == NULL) // None == failure
               ReportError(TEXT("OpenProcess"), GetLastError());
            break;

         default: // The rest work with duplicate handle
            {
               HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, lPid);
               if (hProcess != NULL) {
                  // Get as much access as possible
                  if (!DuplicateHandle(hProcess, hHandle, GetCurrentProcess(),
                     &hObj, MAXIMUM_ALLOWED, FALSE, 0))
                     ReportError(TEXT("DuplicateHandle"), GetLastError());
               } else
                  ReportError(TEXT("OpenProcess"), GetLastError());
            }
            break;
      }

      if (hObj != NULL) {
         pInfo->m_hHandle = hObj;
         fReturn = TRUE;
      }
   }

//   wsprintfW( pInfo->m_szObjectName, L"%hs-%hs", m_pEntry->m_pszComboText, pInfo->m_szName );

   return(fReturn);
}


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


void HandleEdit(HWND hwnd)
{
   // Maintains information about the object whose security we are editing
   ObjectInformation info = { 0 };

   // Fill the info structure with info from the UI
   ObjEntry* m_pEntry = NULL;
   if (FillInfo(hwnd, &info, &m_pEntry)) {

      // Create instance of class derived from interface ISecurityInformation 
	   CSecurityInformation* pSec = CSecurityInformation::CreateInstance( info, 
            IsDlgButtonChecked(hwnd, IDC_BINARY) == BST_CHECKED);

      // Common dialog box for ACL editing
      pSec->EditSecurity(hwnd);
      if (pSec != NULL)
            pSec->Release();

	  TRACE( _T("Cleanup if we had opened a handle before...\n") );

      // Cleanup if we had opened a handle before
      if (info.m_szName[0] == 0) {

         switch (m_pEntry->m_nSpecificType) {
            
            case OB_TYPE_KEY:
               RegCloseKey((HKEY) info.m_hHandle);
               break;
            
            case OB_TYPE_WINDOW_STATION:
               CloseWindowStation((HWINSTA) info.m_hHandle);
               break;
            
            case OB_TYPE_DESKTOP:
               CloseDesktop((HDESK) info.m_hHandle);
               break;

            case OB_TYPE_FILE:
            case OB_TYPE_PROCESS:
            case OB_TYPE_THREAD:
            case OB_TYPE_JOB:
            case OB_TYPE_SEMAPHORE:
            case OB_TYPE_EVENT:
            case OB_TYPE_MUTANT:
            case OB_TYPE_SECTION:
            case OB_TYPE_TIMER:
            case OB_TYPE_TOKEN:
            case OB_TYPE_NAMEDPIPE:
            case OB_TYPE_ANONPIPE:
			default:

               CloseHandle(info.m_hHandle);
               break;
         }
      }
   }
}


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


void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
   switch (id) {

      case IDCANCEL:
         EndDialog(hwnd, 0);
         break;

      case IDC_TYPE:
         HandleType(hwnd, codeNotify, hwndCtl);
         break;

      case IDE_PID:
      case IDE_HANDLE:
         HandleRadio(hwnd, codeNotify, IDR_HANDLE);
         break;
      
      case IDE_NAME:
         HandleRadio(hwnd, codeNotify, IDR_NAME);
         break;
      
      case IDB_EDIT:
         HandleEdit(hwnd);
         break;
   }
}


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


INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   switch (uMsg)
   {
      chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
      chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
   }
   return(FALSE);
}


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


int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {

//   HANDLE hPipe = CreateNamedPipe( _T("\\\\.\\pipe\\MyPipeName"), PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE,
	//				PIPE_UNLIMITED_INSTANCES, 8192, 8192, NMPWAIT_USE_DEFAULT_WAIT, NULL );
  // HANDLE hPipe1 = NULL;
//   HANDLE hPipe2 = NULL;
//	CreatePipe( &hPipe1, &hPipe2, NULL, 8192 );

   DialogBox(hinstExe, MAKEINTRESOURCE(IDD_DIALOG), NULL, Dlg_Proc);
   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, 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