<转>CProcessData : A template class to ease up SendMessage calls across processes

Overview

CProcessData is a template class that makes it easy to use data allocated in a different process, and is useful when making inter-process SendMessage/PostMessage calls.

Example Scenario - 1

Imagine that you are sending a DTM_SETSYSTEMTIME message to a Date/Time picker control in a different process.

Without CProcessData

Collapse | Copy Code

SYSTEMTIME systim;
//Populate systim

HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
LPVOID lpData = VirtualAllocEx(hProc, NULL,
    sizeof SYSTEMTIME, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, lpData, (LPCVOID)&systim,
    sizeof SYSTEMTIME, NULL);            

DWORD dwResult = (DWORD)::SendMessage(hwnd,
    DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&lpData);

if(dwResult == 0)
{
    DWORD err = GetLastError();
    //...
}

VirtualFreeEx(hProc, lpData, NULL, MEM_RELEASE);
CloseHandle(hProc);

Using CProcessData

Collapse | Copy Code

SYSTEMTIME systim;
//Populate systim

CProcessData<SYSTEMTIME> data(pid);
data.WriteData(systim);

DWORD dwResult = (DWORD)::SendMessage(hwnd,
    DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)data.GetData());

if(dwResult == 0)
{
    DWORD err = GetLastError();
    //...
}

Note only have you saved on lines of code, but you don't run the risk of forgetting to free the allocated memory or closing the process handle.

Example Scenario - 2

Imagine that you are retrieving toolbar info from a toolbar control in a different process.

Without CProcessData

Collapse | Copy Code

HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
LPVOID lpData = VirtualAllocEx(hProc, NULL,
    sizeof TBBUTTON, MEM_COMMIT, PAGE_READWRITE);      

::SendMessage(hwnd, TB_GETBUTTON, index, (LPARAM)lpData);

TBBUTTON tb;
ReadProcessMemory(hProc, lpData,(LPVOID)&tb,
    sizeof TBBUTTON, NULL)

CUSTOMDATA cus;
ReadProcessMemory(hProc, (LPCVOID)tb.dwData, (LPVOID)&cus,
    sizeof CUSTOMDATA, NULL)

VirtualFreeEx(hProc,lpData,NULL,MEM_RELEASE);
CloseHandle(hProc);

Using CProcessData

Collapse | Copy Code

CProcessData<TBBUTTON> data(pid);

::SendMessage(hwnd, TB_GETBUTTON, index,
    (LPARAM)data.GetData());

TBBUTTON tb;
data.ReadData(&tb);    

CUSTOMDATA cus;
data.ReadData<CUSTOMDATA>(&cus,(LPCVOID)tb.dwData);

Pretty neat, huh?

Class Reference

Constructor

CProcessData(DWORD dwProcessId = 0, DWORD dwDesiredAccess = PROCESS_ALL_ACCESS, DWORD flAllocationType = MEM_COMMIT, DWORD flProtect = PAGE_READWRITE)

If you pass in a dwProcessId of 0, the current process Id is used. For the other arguments, see MSDN documentation for OpenProcess and VirtualAllocEx.

WriteData

BOOL WriteData(const T& data)

WriteData copies data to memory in the foreign process

ReadData

BOOL ReadData(T* data)

ReadData reads back from the memory in the foreign process into data.

ReadData (template version)

template<typename TSUBTYPE> BOOL ReadData(TSUBTYPE* data, LPCVOID lpData)

Templated ReadData that's used to read a specific data type from a memory address located in the foreign process.

Full source listing

[Listing has been formatted to fit within 600 pixels. Actual source code (included as a download) is formatted for wider screens]

Collapse | Copy Code

/*
    Author  :    Nishant Sivakumar
    Date    :    June 9, 2005
    Info    :    Template class that makes it easy to use data allocated
                 in a different process. Useful when making inter-process
                 SendMessage/PostMessage calls.
    Contact :    nish#voidnish.com
*/

//ProcessData.h

#pragma once

template<typename T> class CProcessData
{
public:
    /*
        If you pass in a dwProcessId of 0, the current process Id is used.
        For the other arguments, see MSDN documentation for OpenProcess and
        VirtualAllocEx.
    */
    CProcessData(DWORD dwProcessId = 0,
        DWORD dwDesiredAccess = PROCESS_ALL_ACCESS,
        DWORD flAllocationType = MEM_COMMIT, DWORD flProtect = PAGE_READWRITE)
    {
        m_hProcess = OpenProcess(dwDesiredAccess, FALSE,
            dwProcessId ? dwProcessId : GetCurrentProcessId());
        ASSERT(m_hProcess);
        if(m_hProcess)
        {
            m_lpData = VirtualAllocEx(m_hProcess, NULL, sizeof T,
                flAllocationType, flProtect);
            ASSERT(m_lpData);
        }
    }

    ~CProcessData()
    {
        if(m_hProcess)
        {
            if(m_lpData)
            {
                VirtualFreeEx(m_hProcess, m_lpData, NULL, MEM_RELEASE);
            }
            CloseHandle(m_hProcess);
        }
    }

    //WriteData is used to copy data to memory in the foreign process
    BOOL WriteData(const T& data)
    {
        return (m_hProcess && m_lpData) ? WriteProcessMemory(
            m_hProcess, m_lpData,
            (LPCVOID)&data, sizeof T, NULL) : FALSE;
    }

    //ReadData reads back data from memory in the foreign process
    BOOL ReadData(T* data)
    {
        return (m_hProcess && m_lpData) ? ReadProcessMemory(
            m_hProcess, m_lpData,
            (LPVOID)data, sizeof T, NULL) : FALSE;
    }

    //Templated ReadData that's used to read a specific data type from
    //a memory address located in the foreign process
    template<typename TSUBTYPE> BOOL ReadData(
        TSUBTYPE* data, LPCVOID lpData)
    {
        return m_hProcess ? ReadProcessMemory(m_hProcess, lpData,
            (LPVOID)data, sizeof TSUBTYPE, NULL) : FALSE;
    }

    //Gets the address of the allocated memory in the foreign process
    const T* GetData()
    {
        return (m_hProcess && m_lpData) ? (T*)m_lpData : NULL;
    }
private:
    T m_Data;
    HANDLE m_hProcess;
    LPVOID m_lpData;
};

History

  • June 16, 2005 : Small bug fix in destructor. (VirtualFreeEx and CloseHandle were in the wrong order)
  • June 10, 2005 : Article first published.
  • June 9, 2005 : Class written.

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

时间: 2024-09-20 09:01:38

<转>CProcessData : A template class to ease up SendMessage calls across processes的相关文章

Velocity A template engine OR A Rule engine OR Both

March 2005 Discussion Velocity: A template engine OR A Rule engine OR Both? Most of the developers must be familiar with Velocity as a great open source template engine and I don't think I need to say much about its uses and features as a template en

C++ template学习总结6

对于基本类型来说,并没有一个default模式来讲他们初始化为有意义的值,没有初始化的变量,其指都是未定义的,但是在模板这一块呢?我们可以采用下面的形式: template <typename T> void foo() { T x = T(); // x is zero (or false)ifT is a built-in type } 对于class template我们可以采用下面例子的方式: template <typename T> class MyClass { pr

创建3层的服务模板(4)--- 创建一个App Server的VM Template

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://beanxyz.blog.51cto.com/5570417/1361508 我们已经创建了Guest OS Profile, Application Profile,Hardware Profile,现在把他们组织在一起就可以创建一个App Server的VM Template了. 过程很简单 登陆SCVMM -> Library, Create VM Template 我选择

ES6 Features系列:Template Strings &amp; Tagged Template Strings

1. Brief   ES6(ECMAScript 6th edition)于2015年7月份发布,虽然各大浏览器仍未全面支持ES6,但我们可以在后端通过Node.js 0.12和io.js,而前端则通过Traceur或Babel这类Transpiler将ES6语法预转译为ES5语法,来提前兴奋一把.而仅需适配 IE9+的朋友们现在更是可以开始撸ES6了,而不必为学哪门JavaScript超集语言而烦恼.(ES6又名为ECMAScript 2015或JavaScript.next,ES4的部分较

在PHP世界中选择最合适的模板--比较PHPLIB Template和FastTemplate

比较|模板 PHP工程中的模板应用,是进行中型乃至大型项目中建议采用的处理表现层的好办法.但是具体到模板的实施,采用何种现有的模板技术却需要进行一番比较.PHP世界中比较受关注的模板处理有PHPLIB Template和FastTemplate两种,我们对技术的易用性和速度进行了评测--想知道结果吗? 事情的起因:你用过FastTemplate吗?对于PHP工程中的模板应用,其实我和我的同事们已经在许多的项目中接触过--关于它的好处,我想无论是在实际开发阶段还是上升到设计模式的角度都已经有很多"

用Groovy Template 生成代码

这是我的同事在文档极度贫乏的情况下,摸着石头过河搞出来的东西,向他致敬. 1.Groovy目前的开发状态  Groovy已经如期发布了最后一个是用Classic语法分析器的版本-beta10 ,以后的版本将基于JSR标准的parser,预计发三个jsr版本,每月一个, 到年中就可能有正式版出来了.    Eclipse和IDEA的插件也在开发中,不够都很挑版本,比如IDEA的就只能跑在IEDA5.0的EAP版本上. 2.Groovy Template与 内置xml语法Groovy官方网站上的链接

Template和JSP技术

js (本文发于java emag第一期)一.起源与现状:关于Template和JSP的起源还要追述到Web开发的远古年代,那个时候的人们用CGI来开发web应用,在一个CGI程序中写HTML标签.在这之后世界开始朝不同的方向发展:sun公司提供了类似于CGI的servlet解决方案,但是无论是CGI还是servlet都面对同一个问题:在程序里写html标签,无论如何都不是一个明智的解决方案.于是sun公司于1999年推出了JSP技术.而在另一个世界里,以PHP和ASP为代表的scriptlet

使用phplib7.2中的Template处理BLOCK多重嵌套

现在大部分模板类中都提供block功能,block用来处理不确定个数的HTML 元素,当出现多层不可定的元素,就会用到block的嵌套,对于block嵌套的用法,经过多次测试还是有需要注意的地方,下面用一个例子说明block嵌套的一种处理方法. 1.我们先来看一下例子要达到的效果(图一): 2.模板文件test.htm 模板文件就是静态的页,可以用你喜欢的网页编辑器编制他的外观 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitiona

aspTemplate : 类似 phpLib::Template 的分离层实现

MVC 模式在网站架构中十分常见.它允许我们建立一个三层结构的应用程式,从代码中分离出有用的层,帮助设计师和开发者协同工作以及提高我们维护和扩展既有程式的能力. PHP 中有一个很著名的类库 phpLib,其中有 Template 模板类.能够很方便地实现代码分离在 ASP 中是否也可以这样做呢?当然可以,这就是 aspTemplate 的初衷.它完全实现了 phpLib Template 的全部功能,你可以象使用 phpLib Template 一样使用它,连习惯也基本不用改.:) <% '#