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

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

, 1 Apr 2012
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)

About the Author

Prateek Kaul
Web Developer
India India
No Biography provided

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 1 Apr 2012
Article Copyright 2003 by Prateek Kaul
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid