windows进程间内核对象的共享方式(c++实现)

一.内核对象句柄的继承

以这种方式共享,父子进程中使用的句柄(对于某个内核对象)的值当然是相等的。

process_A:

int main(int argc, char* argv[])
{
	/*
	*   A进程创建一个信号量, 并将其句柄声明是可继承的。
	*/
	SECURITY_ATTRIBUTES security_attr;
	security_attr.nLength = sizeof(security_attr);
	security_attr.bInheritHandle = true;
	security_attr.lpSecurityDescriptor = NULL;
	HANDLE sem = ::CreateSemaphore(&security_attr, 0, 1, NULL); //创建一个未命名的信号量  
	cout << "sem = " << hex << sem << endl;

	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = true;
	ZeroMemory(&pi, sizeof(si));
	size_t trans_sem = reinterpret_cast<size_t>(sem);
	char commandLine[32] = { 0 };
	sprintf_s(commandLine, "%u", trans_sem);
	/*
	*   A进程创建子进程B,并声明B可以继承父进程中可继承的句柄,
	*   B进程被创建的同时,会将A进程中可继承的句柄复制到B进程的句柄表中,
	*   A通过命令行传递可继承句柄值给B
	*/
	bool rlt = ::CreateProcess("E:\\MYVC\\test\\Debug\\process_B.exe",
		commandLine, NULL, NULL, true,
		CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
	if (rlt)
	{
		cout << "create process success." << endl;
		::CloseHandle(pi.hProcess);
		::CloseHandle(pi.hThread);
	}
	size_t cnt = 5;
	while (cnt)
	{
		cout << cnt-- << endl;
		Sleep(1000);
	}
	cout << "release sem." << endl;
	::ReleaseSemaphore(sem, 1, NULL);
	::CloseHandle(sem);
	getchar();
	return 0;
}

process_B:

int main(int argc, char* argv[])
{
	cout << "commandLine :" << endl;
	cout << "\targc = " << argc << endl;
	cout << "\targv[0] = " << argv[0] << endl;
	size_t tmp = atoi(argv[0]);
	HANDLE sem = reinterpret_cast<HANDLE>(tmp);
	cout << "sem = " << hex << sem << endl;
	::WaitForSingleObject(sem, INFINITE);
	::CloseHandle(sem);
	cout << "get sem response" << endl;
	getchar();
	return 1;
}

二. 打开命名内核对象

以这种方式共享,如果子进程继承了父进程的句柄,那么在子进程中打开命名内核对象返回的句柄值,与父进程中该命名内核对象的句柄值是不相等的;如果子进程没有继承父进程的句柄,则相等。

process_A:

同上, 只是当创建子进程B的时候,可以不继承A进程的句柄, 或者不将A进程中的句柄声明是可继承的。

process_B:

int main(int argc, char* argv[])
{
	char *pName = "TEST";
	WCHAR wcName[32];
	memset(wcName, 0, sizeof(wcName));
	MultiByteToWideChar(CP_ACP, 0, pName, strlen(pName) + 1, wcName,
							sizeof(wcName) / sizeof(wcName[0]));
	HANDLE sem = ::OpenSemaphore(SEMAPHORE_ALL_ACCESS, false, wcName);	//打开"TEST"命名内核对象
	cout << "sem = " << hex << sem << endl;
	::WaitForSingleObject(sem, INFINITE);
	::CloseHandle(sem);
	printf("get sem response.\n");
	getchar();
}

三. 复制内核对象句柄

以这种方式共享,复制出来的句柄值与原句柄值相等。

process_A:

HANDLE getProcessHandle(const char* pProcessName)
{
	::PROCESSENTRY32 pe32;
	pe32.dwSize = sizeof(pe32);

	//给系统所有进程拍一个快照
	HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE)
	{
		printf("CreateToolhelp32Snapshot error.\n");
		return NULL;
	}

	BOOL bFind = false;
	//遍历所有快照,查找指定名字的线程
	BOOL bMore = ::Process32First(hProcessSnap, &pe32);
	while (bMore)
	{
		//printf("进程名称:%s\n", pe32.szExeFile);
		//printf("进程ID号: %u\n\n", pe32.th32ProcessID);
		if (0 == strcmp(pe32.szExeFile, pProcessName))
		{
			bFind = true;
			break;
		}
		else
		{
			bMore = ::Process32Next(hProcessSnap, &pe32);
		}
	}
	::CloseHandle(hProcessSnap);//释放进程快照

	if (!bFind)
	{
		return NULL;
	}
	HANDLE hDstProcessHandle = ::OpenProcess(PROCESS_ALL_ACCESS, false, pe32.th32ProcessID);
	return hDstProcessHandle;
}

int main(int argc, char* argv[])
{
	HANDLE sem = ::CreateSemaphore(NULL, 0, 1, NULL);
	cout << "sem = " << hex << sem << endl;

	//主动将本进程的内核对象句柄sem复制到目标进程
	HANDLE hDstProcessHandle;
	HANDLE hNewHandle;
	hDstProcessHandle = getProcessHandle("process_B.exe");	//process_B首先得运行
	BOOL bRet = ::DuplicateHandle(GetCurrentProcess(), sem, hDstProcessHandle, &hNewHandle,
						0, false, DUPLICATE_SAME_ACCESS);
	/*
	* 注意!!!在这里,必须想办法通知子进程process_B该新句柄的值,这里为了测试方便,故直接
	* 打印该句柄的值,在process_B中输入该值,从而直接使用
	*/
	cout << "newHandle : " << hNewHandle << endl;

	size_t cnt = 10;
	while (cnt)
	{
		cout << cnt-- << endl;
		Sleep(1000);
	}
	cout << "release sem." << endl;
	::ReleaseSemaphore(sem, 1, NULL);
	::CloseHandle(sem);
	getchar();
	return 0;
}

process_B:

int main(int argc, char* argv[])
{
	HANDLE sem;
	cout << "input newHandle: " << endl;
	cin >> sem;	//注意这里输入为16进制整数
	::WaitForSingleObject(sem, INFINITE);
	::CloseHandle(sem);
	printf("get sem response.\n");
	getchar();
	getchar();
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值