Click here to Skip to main content
15,886,199 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 156.9K   8.9K   103  
Control certain aspects of machines sitting remotely, without having to install and trigger an application on the remote machine.
// RemoteAdminView.cpp : implementation of the CRemoteAdminView class
//

#include "stdafx.h"
#include "RemoteAdmin.h"
#include "MachineView.h"
#include "GlobalHelperFunc.h"
#include "GlobalMFCHelperFunc.h"
#include "RemoteAdminDoc.h"
#include "RemoteAdminView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern CRITICAL_SECTION g_CriticalSection;

/////////////////////////////////////////////////////////////////////////////
// CRemoteAdminView

IMPLEMENT_DYNCREATE(CRemoteAdminView, CListView)

BEGIN_MESSAGE_MAP(CRemoteAdminView, CListView)
	//{{AFX_MSG_MAP(CRemoteAdminView)
	ON_WM_RBUTTONDOWN()
	ON_COMMAND(ID_PROCESSOPTIONS_ENDPROCESS, OnEndProcess)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRemoteAdminView construction/destruction

CRemoteAdminView::CRemoteAdminView()
{
	// TODO: add construction code here

}

CRemoteAdminView::~CRemoteAdminView()
{
}

BOOL CRemoteAdminView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CListView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CRemoteAdminView drawing

void CRemoteAdminView::OnDraw(CDC* pDC)
{
	CRemoteAdminDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	CListCtrl& refCtrl = GetListCtrl();
	refCtrl.InsertItem(0, "Item!");
	// TODO: add draw code for native data here
}

void CRemoteAdminView::OnInitialUpdate()
{
	CListView::OnInitialUpdate();

    CHeaderCtrl* pHeaderCtrl = GetListCtrl().GetHeaderCtrl();

    // Avoids repeation of headers when a new file is opened.
    if (pHeaderCtrl == NULL)
    {
        // Show the detail view
        GetListCtrl().ModifyStyle(LVS_TYPEMASK, LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS );
        GetListCtrl().SetExtendedStyle(GetListCtrl().GetExtendedStyle() | LVS_EX_FULLROWSELECT);
    
        // Insert the relevant columns
        GetListCtrl().InsertColumn(0, "Executable File",            LVCFMT_LEFT, 175);
        GetListCtrl().InsertColumn(1, "Process ID",                 LVCFMT_LEFT, 100);
        GetListCtrl().InsertColumn(2, "No. of Threads",             LVCFMT_LEFT, 100);
        GetListCtrl().InsertColumn(3, "Physical Memory Usage (KB)", LVCFMT_LEFT,150);
        //GetListCtrl().InsertColumn(3, "Parent Process ID", LVCFMT_LEFT, 100);
    }
}

/////////////////////////////////////////////////////////////////////////////
// CRemoteAdminView diagnostics

#ifdef _DEBUG
void CRemoteAdminView::AssertValid() const
{
	CListView::AssertValid();
}

void CRemoteAdminView::Dump(CDumpContext& dc) const
{
	CListView::Dump(dc);
}

CRemoteAdminDoc* CRemoteAdminView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CRemoteAdminDoc)));
	return (CRemoteAdminDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CRemoteAdminView message handlers
void CRemoteAdminView::OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct)
{
	//TODO: add code to react to the user changing the view style of your window
}

void CRemoteAdminView::RefreshProcesses(CString strRemoteMachineIP)
{
    CProcessInfoList* pProcessInfoList = NULL;
    //PROCESSENTRY32* pPe                = NULL;
    SProcessInfo* pPe                  = NULL;
    POSITION pos                       = NULL;
    TCHAR szProcessID[10]              = _T("");
    TCHAR szThreadCount[10]            = _T(""); 
    TCHAR szMemoryUsage[30]            = _T("");

    pProcessInfoList  = GetDocument()->GetProcessInfoList(strRemoteMachineIP);
    int iProcessCount = pProcessInfoList->GetCount();
    
    // Clear the list control
    GetListCtrl().DeleteAllItems();
	
	::EnterCriticalSection(&g_CriticalSection);

    for(int i = 0; i < iProcessCount; ++i)
    {
        pos = pProcessInfoList->FindIndex(i);
        pPe = pProcessInfoList->GetAt(pos);

        //::sprintf(szProcessID,       "%d", pPe->th32ProcessID);
        //::sprintf(szThreadCount,     "%d", pPe->cntThreads);
        //::sprintf(szParentProcessID, "%d", pPe->th32ParentProcessID);
        ::sprintf(szProcessID,       "%d", pPe->peProcessEntry.th32ProcessID);
        ::sprintf(szThreadCount,     "%d", pPe->peProcessEntry.cntThreads);
        ::sprintf(szMemoryUsage,     "%d", (pPe->stMemUsage)/1000);

        // Insert the processes in the list control
        GetListCtrl().InsertItem(i, pPe->peProcessEntry.szExeFile, 0);
        GetListCtrl().SetItemText(i, 1, szProcessID);
        GetListCtrl().SetItemText(i, 2, szThreadCount);
        GetListCtrl().SetItemText(i, 3, szMemoryUsage);
    }
    
    // Free the contents of the CProcessInfoList it had a opy of the internal 
    // PROCESSENTRY32's maintained
    pos = pProcessInfoList->GetHeadPosition();
    while (pos != (POSITION)0xcdcdcdcd && pos != NULL)
    {
        pPe = pProcessInfoList->GetNext(pos);

		if (pPe)
		{
			delete pPe;
		}
    }

	pProcessInfoList->RemoveAll();

    // Now delete the list itself, after deleteing it's contents (done just above)
    delete pProcessInfoList;
    pProcessInfoList = NULL;

	::LeaveCriticalSection(&g_CriticalSection);
}

void CRemoteAdminView::OnRButtonDown(UINT nFlags, CPoint point) 
{
    CListView::OnRButtonDown(nFlags, point);
    
    LVHITTESTINFO lvHitTestInfo = {0};
    lvHitTestInfo.pt = point;

    GetListCtrl().HitTest(&lvHitTestInfo);
    int iItemClicked = lvHitTestInfo.iItem;

    if (iItemClicked >= 0)
    {
        GetListCtrl().SetItemState(iItemClicked, LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
        m_strLastClickedProcessID = GetListCtrl().GetItemText(iItemClicked, 1);

        CMenu menuProcess;
        menuProcess.LoadMenu(IDR_PROCESS_OPTIONS);
    
        CMenu* pMenu = menuProcess.GetSubMenu(0);
        CPoint pt = point;

        ClientToScreen(&pt);
        pMenu->TrackPopupMenu(TPM_LEFTALIGN, pt.x, pt.y, this);
    }
}

void CRemoteAdminView::OnEndProcess() 
{
    // Send a command to continue the thread that will execute the remote process
    SCommand cmd;
    cmd.m_bThreadExit = FALSE;
     
    TCHAR szProcessID[10] = _T("");
    ::strcpy(szProcessID, m_strLastClickedProcessID.GetBuffer(0));
    
    /*
    // Get the currently selected machine IP, from the tree
    TCHAR szTextIP[_MAX_PATH] = _T("");
    HTREEITEM hSelectedItem = ::GetMachineView()->GetTreeCtrl().GetSelectedItem();
    TVITEM tvItem = {0};
    
    tvItem.hItem   = hSelectedItem;
    tvItem.pszText = szTextIP;
    tvItem.mask    = TVIF_TEXT | TVIF_HANDLE ;

    ::GetMachineView()->GetTreeCtrl().GetItem(&tvItem);
    //CString strMachineIP = tvItem.pszText;
    CString strMachineIP = ::GetMachineView()->GetTreeCtrl().GetItemText(hSelectedItem);*/
    CString strMachineIP = MFC_DocView::GetMachineView()->GetSelectedItemTextInTreeView();

    BOOL bOk = FALSE;
    DWORD dwWritten = 0;
    
    
    HANDLE hRemoteAdminProcessKillPipe = GetDocument()->GetRemoteAdminProcessKillPipe(strMachineIP);

    if (hRemoteAdminProcessKillPipe != NULL)
    {
        bOk = ::WriteFile(hRemoteAdminProcessKillPipe, &cmd,        sizeof(SCommand), &dwWritten, NULL);
        bOk = ::WriteFile(hRemoteAdminProcessKillPipe, szProcessID, 10,               &dwWritten, NULL);

        TCHAR szMessage[_MAX_PATH] = _T("");
        DWORD dwRead = 0;

        bOk = ::ReadFile(hRemoteAdminProcessKillPipe, szMessage, sizeof(szMessage), &dwRead, NULL);

        // There is some message that the process triggering was not sucessful
        // If it had been the string would be ""
        if (::strcmp(szMessage, _T("")) != 0)
        {
            CString strFormattedErrorMsg = ErrorHandling::ConvertStringTableIDToErrorMsg(strMachineIP, IDS_NOT_END_REMOTE_PROCESS);
            ::AfxMessageBox(strFormattedErrorMsg);
        }
    }
}

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