高低權限進程通信(ChangeWindowMessageFilter, WM_COPYDATA)

低權限進程向高權限進程發送消息時會返回拒絕訪問, windows爲我們提供了ChangeWindowMessageFilter, 直接上代碼(client.cpp用非管理員啓動, server.cpp用管理員啓動, 通過SendMessage WM_COPYDATA進行通信)


// client.cpp

// ncLowProcessClient.cpp
#include 
#include 
#include 
using namespace std;

#define NC_TEST_SERVER_CLASS_NAME TEXT("ncTestServerClassName")
#define NC_TEST_CLASS_NAME TEXT("ncTestClientClassName")
#define NC_TEST_WINDOWS_NAME TEXT("ncTestClientWindowsName")

LRESULT CALLBACK WndPron(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

TCHAR ipp[256] = { 0 };

int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
	WNDCLASSEX wcex = { 0 };
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndPron;
	wcex.hInstance = hInstance;
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszClassName = NC_TEST_CLASS_NAME;
	if (!RegisterClassEx(&wcex)) { return -1; }

	HWND hwnd = CreateWindow(NC_TEST_CLASS_NAME, NC_TEST_WINDOWS_NAME
		, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
		, CW_USEDEFAULT, 0 , CW_USEDEFAULT, 0
		, NULL, NULL, hInstance, NULL);
	MoveWindow(hwnd, 300, 300, 300, 300, true);
	ShowWindow(hwnd, SW_SHOW);
	UpdateWindow(hwnd);

	MSG msg = { 0 };
	GetMessage(&msg, NULL, NULL, NULL);
	while (msg.message != WM_QUIT) {
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	UnregisterClass(NC_TEST_CLASS_NAME, wcex.hInstance);
	return 0;
}


LRESULT CALLBACK WndPron(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	switch(msg) 
	{
	case WM_LBUTTONDOWN:
		{
			wstring sender = _T("hello");
			if (HWND hwndExe = ::FindWindow (NC_TEST_SERVER_CLASS_NAME, NULL)) {
				COPYDATASTRUCT cds;
				cds.dwData = 1;
				cds.cbData = (DWORD)(sender.length() + 1) * sizeof(TCHAR);
				cds.lpData = (PVOID)sender.c_str();
				LRESULT res = SendMessage (hwndExe, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)&cds);
			}
			break;
		}
	case WM_COPYDATA:
		{
			COPYDATASTRUCT* pCds = (COPYDATASTRUCT*)lparam;
			if (pCds->dwData == 1) {
				int nArgNum;
				LPWSTR* szArgList = CommandLineToArgvW (CT2CW((TCHAR*)pCds->lpData), &nArgNum);
				LPWSTR ip = szArgList[0];
				wsprintf(ipp, ip);
				LocalFree(szArgList);
			}

			MoveWindow(hwnd, 300, 300, 400, 400, true);
			break;;
		}
	case WM_SIZE:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);
			TextOut (hdc, 0, 0, ipp, wcslen(ipp));
			EndPaint(hwnd, &ps);
			break;
		}
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			break;
		}
	default:
		{
			return DefWindowProc(hwnd, msg, wparam, lparam);
		}
	}
	return 0;
}

// server.cpp

// ncHighProcessServer.cpp
#include 
#include 
#include 
using namespace std;

#define NC_TEST_CLASS_NAME TEXT("ncTestServerClassName")
#define NC_TEST_WINDOWS_NAME TEXT("ncTestServerWindowsName")

LRESULT CALLBACK WndPron(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
	WNDCLASSEX wcex = { 0 };
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndPron;
	wcex.hInstance = hInstance;
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszClassName = NC_TEST_CLASS_NAME;
	if (!RegisterClassEx(&wcex)) { return -1; }

	HWND hwnd = CreateWindow(NC_TEST_CLASS_NAME, NC_TEST_WINDOWS_NAME
		, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
		, CW_USEDEFAULT, 0 , CW_USEDEFAULT, 0
		, NULL, NULL, hInstance, NULL);
	MoveWindow(hwnd, 300, 300, 300, 300, true);
	ShowWindow(hwnd, SW_SHOW);
	UpdateWindow(hwnd);

	MSG msg = { 0 };
	GetMessage(&msg, NULL, NULL, NULL);
	while (msg.message != WM_QUIT) {
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	UnregisterClass(NC_TEST_CLASS_NAME, wcex.hInstance);
	return 0;
}

LRESULT CALLBACK WndPron(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	static bool s_flag = true;
	if (s_flag) {
		ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD);
		s_flag = false;
	}

	switch(msg) 
	{
	case WM_COPYDATA:
		{
			COPYDATASTRUCT* pCdS = (COPYDATASTRUCT*)lparam;
			if (pCdS->dwData == 1) {
				if (pCdS->lpData) {
					int nArgNum;
					LPWSTR* szArgList = CommandLineToArgvW (CT2CW((TCHAR*)pCdS->lpData), &nArgNum);
					LPWSTR recver = szArgList[0];
					LocalFree(szArgList);
				}
			}

			wstring recver = _T("world");
			HWND hWnd = (HWND)wparam;
			COPYDATASTRUCT cds;
			cds.dwData = 1;
			cds.cbData = (DWORD)(recver.length() + 1) * sizeof(TCHAR);
			cds.lpData = (PVOID)recver.c_str();

			SendMessage(hWnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)&cds);
			break;;
		}
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			break;
		}
	default:
		{
			return DefWindowProc(hwnd, msg, wparam, lparam);
		}
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章