Click here to Skip to main content
15,892,298 members
Articles / Desktop Programming / MFC

Remote Processes and Machine control of Windows NT based systems (2000/XP)

Rate me:
Please Sign up or sign in to vote.
4.80/5 (35 votes)
1 Apr 2012CPOL5 min read 157.1K   8.9K   103  
Control certain aspects of machines sitting remotely, without having to install and trigger an application on the remote machine.
#include "stdafx.h"
#include "AboutDlg.h"
#include <Tlhelp32.h>

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
    m_pszLoadedModules         = NULL;
    m_pszLoadedModulesFullPath = NULL;
    m_nNumberOfLoadedModules   = 0;
}


CAboutDlg::~CAboutDlg()
{
    // Delete individual strings
    for (int i = 0; i < m_nNumberOfLoadedModules; ++i)
    {
        if (m_pszLoadedModules[i] != NULL)
        {
            delete m_pszLoadedModules[i];
            delete m_pszLoadedModulesFullPath[i];

            m_pszLoadedModulesFullPath[i] = NULL;
            m_pszLoadedModules[i]         = NULL;
        }
    }

    // Delete the array of strings
    if (m_pszLoadedModules != NULL)
    {
        delete m_pszLoadedModules;
        delete m_pszLoadedModulesFullPath;

        m_pszLoadedModules         = NULL;
        m_pszLoadedModulesFullPath = NULL;
    }
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BOOL CAboutDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
    	
	CListCtrl* pListCtrl = static_cast<CListCtrl*>(GetDlgItem(IDC_LIST_LOADED_MODULES));
    CStatic* pStaticBuildInfo = static_cast<CStatic*>(GetDlgItem(IDC_STATIC_BUILD_INFO));

    // Get the build date and time
    CString strBuildDateTime = GetBuildDateTime();
    pStaticBuildInfo->SetWindowText(strBuildDateTime);

    // Get the number of loaded modules that will be shown
    GetLoadedModules(&m_pszLoadedModules, &m_pszLoadedModulesFullPath, &m_nNumberOfLoadedModules);

    pListCtrl->InsertColumn(0, _T("Name"), LVCFMT_LEFT, 100);
    pListCtrl->InsertColumn(1, _T("Path"), LVCFMT_LEFT, 245);
    

    // We start from 1 because the first name is always the path of the exe itself.
    // Hence, no point in showing it again.
    for (int i = 1; i < m_nNumberOfLoadedModules; ++i)
    {
        pListCtrl->InsertItem(i - 1, m_pszLoadedModules[i]);
        pListCtrl->SetItemText(i - 1, 1, m_pszLoadedModulesFullPath[i]);
    }
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}


void CAboutDlg::GetLoadedModules(TCHAR*** pszModuleList, TCHAR*** pszModuleListFullPath, int* pnNumberOfModules)
{
    *pnNumberOfModules = 0;

    DWORD dwCurrentProcessId = ::GetCurrentProcessId();
    
    // Take this process's snapshot
    HANDLE hModulesSnapShot = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwCurrentProcessId);
    
    MODULEENTRY32 me32;

    // << Start counting the number of modules loaded
    BOOL bSuccessInModuleFind = ::Module32First(hModulesSnapShot, &me32);
    
    if (bSuccessInModuleFind)
    {
        ++(*pnNumberOfModules);
        do 
        {
            bSuccessInModuleFind = ::Module32Next(hModulesSnapShot, &me32);
            if (bSuccessInModuleFind)
            {
                ++(*pnNumberOfModules);
            }
        }
        while (bSuccessInModuleFind);
    }
    else
    {
        // We didn't forget to clean up the snapshot object.
        ::CloseHandle(hModulesSnapShot);

        return; // no modules loaded
    }

    // Stop counting the number of modules loaded >>


    // Now do the same things to get the loaded module names and paths, as done above,
    // but allocate memory for the module name and path name strings.
    // Again, walk through the list of modules in this process

    *pszModuleList         = new TCHAR*[(*pnNumberOfModules)];
    *pszModuleListFullPath = new TCHAR*[(*pnNumberOfModules)];

    ::Module32First(hModulesSnapShot, &me32);
    
    // Allocate memory for the first module name and its path
    unsigned int nStrLenModuleName     = ::strlen(me32.szModule);
    unsigned int nStrLenModuleFullPath = ::strlen(me32.szExePath);

    (*pszModuleList)[0]         = new TCHAR[nStrLenModuleName + 1];
    (*pszModuleListFullPath)[0] = new TCHAR[nStrLenModuleFullPath + 1];

    // Copy the first module name and its path in the buffer
    ::strcpy((*pszModuleList)[0], me32.szModule);
    ::strcpy((*pszModuleListFullPath)[0], me32.szExePath);

    for (int i = 1; i < (*pnNumberOfModules); ++i)
    {
        ::Module32Next(hModulesSnapShot, &me32);

        // Allocate memory for modules name and their path
        nStrLenModuleName     = ::strlen(me32.szModule);
        nStrLenModuleFullPath = ::strlen(me32.szExePath);

        (*pszModuleList)[i]         = new TCHAR[nStrLenModuleName + 1];
        (*pszModuleListFullPath)[i] = new TCHAR[nStrLenModuleFullPath + 1];

        // Copy the module name and their path in the buffer
        ::strcpy((*pszModuleList)[i], me32.szModule);
        ::strcpy((*pszModuleListFullPath)[i], me32.szExePath);
    }

    // We didn't forget to clean up the snapshot object.
    ::CloseHandle(hModulesSnapShot);
}


CString CAboutDlg::GetBuildDateTime()
{
    CString strDateTime;
    
    strDateTime.Format("Built on %s at %s", __DATE__, __TIME__);

    return strDateTime;
}

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 Code Project Open License (CPOL)


Written By
Web Developer
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions