CProcessData:一个模板类,用于简化进程间的 SendMessage 调用





5.00/5 (39投票s)
2005年6月10日
1分钟阅读

136552

1355
CProcessData是一个模板类,可以轻松地使用在不同进程中分配的数据,并且在进行进程间SendMessage/PostMessage调用时非常有用。
概述
CProcessData
是一个模板类,可以轻松地使用在不同进程中分配的数据,并且在进行进程间SendMessage
/PostMessage
调用时非常有用。
示例场景 - 1
假设你要向另一个进程中的日期/时间选择器控件发送DTM_SETSYSTEMTIME
消息。
未使用CProcessData
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);
使用CProcessData
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(); //... }
请注意,你不仅节省了代码行数,而且避免了忘记释放分配的内存或关闭进程句柄的风险。
示例场景 - 2
假设你要从另一个进程中的工具栏控件中检索工具栏信息。
未使用CProcessData
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);
使用CProcessData
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);
很不错,对吧?
类参考
构造函数
CProcessData(DWORD dwProcessId = 0, DWORD dwDesiredAccess = PROCESS_ALL_ACCESS, DWORD flAllocationType = MEM_COMMIT, DWORD flProtect = PAGE_READWRITE)
如果你传入dwProcessId
为0,则使用当前进程Id。对于其他参数,请参阅MSDN文档中的OpenProcess
和VirtualAllocEx
。
WriteData
BOOL WriteData(const T& data)
WriteData
将data
复制到目标进程的内存中
ReadData
BOOL ReadData(T* data)
ReadData
从目标进程的内存中读取数据到data
中。
ReadData (模板版本)
template<typename TSUBTYPE> BOOL ReadData(TSUBTYPE* data, LPCVOID lpData)
模板化的ReadData
,用于从目标进程中位于特定内存地址读取特定数据类型。
完整源代码
[列表已格式化以适应600像素的宽度。实际源代码(作为下载提供)已格式化为更宽的屏幕]
/* 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; };
历史
- 2005年6月16日:修复了析构函数中的一个小错误。(
VirtualFreeEx
和CloseHandle
的顺序错误) - 2005年6月10日:文章首次发布。
- 2005年6月9日:类编写完成。