WM_COPYDATA传回返回值的一个方案
  WtpFkP2ympcR 2023年11月02日 50 0


方案背景

适应场景,通过WM_COPYDATA进行进程间通信时,SendMessage不能返回自定义的数据,由此想到以下思路解决这个问题

  • A进程使用VirtualAlloc分配一块内存,通过某种方式将此地址以及A进程ID传给另一个进程B
  • B进程使用OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,FALSE, nRemoteProcessId)打开A进程的句柄,然后使用WriteProcessMemory向A进程指定地址写入数据
  • A进程即可从内存中读取值。

代码举例

进程A

{
	//分配一块8KB大小的区域给另外一个进程写入返回值
	const int nMaxBuffSize = 8192;
	LPVOID lpResultMem = ::VirtualAlloc(NULL, nMaxBuffSize, MEM_COMMIT, PAGE_READWRITE);


	Binary binData;
	binData.WriteUInt32(GetCurrentProcessId());//此进程ID
	binData.WriteUInt64(UINT64(lpResultMem));//此进程分配的一块共享内存块
	//通过SendMessage发送WM_COPYDATA消息给另外一个进程
	//代码略
	//...
	//LRESULT nResult = ::SendMessage(...);

	if (nResult)
	{
		//读取lpResultMem中的值
		int* pValue = (int*)lpResultMem;
		//pValue的值应该为另一个进程写入的8888

		//代码略
		//...
	}

	//释放
	::VirtualFree(lpResultMem, 0, MEM_RELEASE);
	lpResultMem = 0;
}

进程B

BOOL ProcessB::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
	//其他代码
	//略
	//....

	DWORD nRemoteProcessId = pBinData->ReadUInt32();//远程进程ID
	UINT64 nRemoteAddress = pBinData->ReadUInt64(); //远程可写入地址 最多8kb
	
	//打开远程进程
	HANDLE hRemoteProcess = ::OpenProcess(
		PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
		FALSE, nRemoteProcessId);

	//写入一个整数或其他的内容,但要小于对方进程分配的大小,此处为8kb
	int nValue = 8888;
	SIZE_T nWriteSize = 0;
	::WriteProcessMemory(hRemoteProcess, LPVOID(nRemoteAddress),
		&nValue, sizeof(int), &nWriteSize);
	::CloseHandle(hRemoteProcess);
	hRemoteProcess = NULL;
	if (nWriteSize == 0)
	{
		return FALSE;
	}
	return TRUE;

	//其他代码
	//略
	//....
}


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
WtpFkP2ympcR