PROCESS_VM_OPERATION,//访问权限
FALSE,//继承关系
dwProcessID);//进程ID
为保证OpenProcess函数调用成功,用户所影响的进程必须由上述标志创建。
一旦用户获得一个进程的有效句柄,就可以调用ReadProcessMemory函数读取该
进程的内存:
BOOL ReadProcessMemory(
HANDLE hProcess, // 进程指针
LPCVOID lpBaseAddress, // 数据块的首地址
LPVOID lpBuffer, // 读取数据所需缓冲区
DWORD cbRead, // 要读取的字节数
LPDWORD lpNumberOfBytesRead
);
使用同样的句柄也可以写入该进程的内存:
BOOL WriteProcessMemory(
HANDLE hProcess, // 进程指针
LPVOID lpBaseAddress, // 要写入的首地址
LPVOID lpBuffer, // 缓冲区地址
DWORD cbWrite, // 要写的字节数
LPDWORD lpNumberOfBytesWritten
);
如下所示是读写另一进程的共享内存中的数据:
ReadProcessMemory((HANDLE)hTargetProcess,(LPSTR)lpsz,m_strGlobal.GetBuffer(_MAX_FIELD),
_MAX_FIELD,&cb);
WriteProcessMemory((HANDLE)hTargetProcess,(LPSTR)lpsz,(LPSTR)STARS,
m_strGlobal.GetLength(),&cb);
4、进程之间的消息发送与接收
在实际应用中进程之间需要发送和接收Windows消息来通知进程间相互通讯,
发送方发送通讯的消息以通知接收方,接收方在收到发送方的消息后就可以对内
存进行读写操作。
我们在程序设计中采用Windows注册消息进行消息传递,首先在发送进程初始
化过程中进行消息注册:
m_nMsgMapped=::RegisterWindowsMessage(“Mapped”);
m_nMsgHandle=::RegisterWindowsMessage(“Handle”);
m_nMsgShared=::RegisterWindowsMessage(“Shared”);
在程序运行中向接收进程发送消息:
CWnd* pWndRecv=FindWindow(lpClassName,“Receive”);
pWndRecv→SendMessage(m_MsgMapped,0,0);
pWndRecv→SendMessage(m_nMsgHandle,(UINT)GetCurrentProcessID(),(LONG)pApp→m_hGlobalHandle);
pWndRecv→SendMessage(m_nMsgShared,0,0);
可以按如下方式发送WM_COPYDATA消息:
static COPYDATASTRUCT cds;//用户存放数据pWnd→SendMessage(WM_COPYDATA,NULL,(LONG)&cds);
接收方进程初始化也必须进行消息注册:
UNIT CRecvApp:: m_nMsgMapped=::RegisterWindowsMessage(“Mapped”);
UNIT CRecvApp::m_nMsgHandle=::RegisterWindowsMessage(“Handle”);
UNIT CRecvApp::m_nMsgShared=::RegisterWindowsMessage(“Shared”);
同时映射消息函数如下:
ON_REGISTERED_MASSAGE(CRecvApp::m_nMsgMapped,OnRegMsgMapped)
ON_REGISTERED_MASSAGE(CRecvApp::m_nMsgHandle,OnRegMsgHandle)
ON_REGISTERED_MASSAGE(CRecvApp::m_nMsgShared,OnRegMsgShared)
有这些消息函数我们就可以采用上述技术实现接收进程中数据的读写操作了。
5、结束语
从以上分析中我们可以看出Windows9X的内存管理对进程之间的通讯有较为严
格的限制。这就确保了任何故障程序无法意外地写入用户的地址空间,而用户则可
根据实际情况灵活地进行进程间的数据通讯,从这一点上来讲Windows95增强了应用
程序的强壮性。
关键词:如何完成win9X进程间数据通讯技术