window核心编程 22.3 DIPS.exe的踩坑逻辑梳理

先上源代码

DIPSLib.DLL编译篇

这个是公共头文件CmnHdr.h

#pragma once
//#define _WIN32_WINNT	_WIN32_WINNT_LONGHORN
//#define WINVER			_WIN32_WINNT_LONGHORN

#ifndef UNICODE
	#define UNICODE
#endif // UNICODE

#ifdef UNICODE
	#ifndef _UNICODE
		#define _UNICODE
	#endif // !_UNICODE
#endif // UNICODE

#pragma warning(push,3)
#include<Windows.h>
#pragma warning(pop)
#pragma warning(push,4)
#include<CommCtrl.h>
#include<process.h>

#ifndef FILE_SKIP_COMPLETION_PORT_ON_SUCESS
#pragma message("You are not using the latest Platform SDK header /library")
#pragma message("files. This may prevent the project form building correctly.")
#endif // !FILE_SKIP_COMPLETION_PORT_ON_SUCESS

#define chSTR2(x)	#x
#define chSTR(x)	chSTR2(x)
#define chMSG(desc) message(__FILE__ "(" chSTR(__LINE__) "):" #desc)
inline void chMB(PCSTR szMsg)
{
	char szTitle[MAX_PATH];
	GetModuleFileNameA(NULL, szTitle, _countof(szTitle));
	MessageBoxA(GetActiveWindow(), szMsg, szTitle, MB_OK);
}
inline void chFAIL(PSTR szMsg)
{
	chMB(szMsg);
	DebugBreak();
}
inline void chASSERTFAIL(LPCSTR file, int line, PCSTR expr)
{
	char sz[2 * MAX_PATH];
	wsprintfA(sz, "File %s , Linr %d : %s", file, line, expr);
	chFAIL(sz);
}

#ifdef  _DEBUG
#define chASSERT(x) if(!(x)) chASSERTFAIL(__FILE__,__LINE__,#x)
#else
#define chASSERT(x)
#endif //  _DEBUG

#ifdef  _DEBUG
#define chVERIFY(x) chASSERT(x)
#else
#define chVERIFY(x) (x)
#endif //  _DEBUG

inline void chSETDLGICONS(HWND hWnd, int idi)
{
	SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)
		LoadIcon((HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
			MAKEINTRESOURCE(idi)));
	SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)
		LoadIcon((HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
			MAKEINTRESOURCE(idi)));
}

#define chHANDLE_DLGMSG(hWnd,message,fn)	\
	case(message): return (SetDlgMsgResult(hWnd,message,HANDLE_##message((hWnd),(wParam),(lParam),(fn))))

创建个dialog资源用mfc  改名字Wintellect DIPS 改id  IDD_DIPS

下面附上DIPSLib代码  .H文件

#pragma once
#if !defined(DIPSLIBAPI)
#define DIPSLIBAPI __declspec(dllimport)
#endif


DIPSLIBAPI BOOL __stdcall SetDIPSHook(DWORD dwThreadId);

.cpp文件

#include"CmnHdr.h"
#include<WindowsX.h>
#include<CommCtrl.h>
#define DIPSLIBAPI __declspec(dllexport)
#include"DIPSLib.h"
#include"resource.h"

#ifdef _DEBUG
void ForceDebugBreak()
{
	__try {
		DebugBreak();
	}
	__except (UnhandledExceptionFilter(GetExceptionInformation()))
	{
	}
}
#else
#define ForceDebugBreak()
#endif // _DEBUG

//Instruct the compiler to put the g_hHook data variable in its own
//data section called shared. we then instruct the linker that we want to 
//share the data in this section with all instances of this application
#pragma data_seg("Shared")
HHOOK g_hHook = NULL;
DWORD g_dwThreadIdDIPS = 0;
#pragma data_seg()

//Instruct the linker to make the shared section
//readable writeable and shared
#pragma comment(linker,"/section:Shared,rws")

//Nonshared variables
HINSTANCE g_hInstDll = NULL;
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK Dlg_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID fImpLoad)
{
	switch (fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		g_hInstDll = hInstance;
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_PROCESS_DETACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	default:
		break;
	}
	return TRUE;
}
BOOL WINAPI SetDIPSHook(DWORD dwThreadId)
{
	BOOL bok = FALSE;
	if (dwThreadId != 0)
	{
		//make sure that the hook is not already installed
		chASSERT(g_hHook == NULL);

		//Save our thread ID in a shared variable so that our GetMsgProc
		//function can post a message back to the thread when the server window
		//has been created
		g_dwThreadIdDIPS = GetCurrentThreadId();
		//install the hook on the spacified thread
		g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstDll, dwThreadId);

		bok = (g_hHook != NULL);
		if (bok)
		{
			//The Hook was installed sucessfully; force a benign message to 
			//the thread's queue so that the hook funtion gets called
			bok = PostThreadMessage(dwThreadId, WM_NULL, 0, 0);
		}
		else
		{

		}
	}
	else
	{
		//make sure that a hook has been installed
		chASSERT(g_hHook != NULL);
		bok = UnhookWindowsHookEx(g_hHook);
		g_hHook = NULL;
	}
	return bok;
}

LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	static BOOL bFirstTime = TRUE;
	if (bFirstTime)
	{
		//the dll just got injected
		bFirstTime = FALSE;
		chMB("wo jinlaile wokaixin");
		//create the dips server window to handle the client request
		CreateDialog(g_hInstDll, MAKEINTRESOURCE(IDD_DIPS), NULL, Dlg_Proc);

		//Tell the Dips application that the server is up 
		//and ready to handle requests
		PostThreadMessage(g_dwThreadIdDIPS, WM_NULL, 0, 0);
	}
	return (CallNextHookEx(g_hHook, nCode, wParam, lParam));
}
void Dlg_OnClose(HWND hWnd)
{
	DestroyWindow(hWnd);
}
static const TCHAR g_szRegSubKey[] = TEXT("Software\\Wintellect\\Desktop Item Position Saver");

void SaveListViewItemPositions(HWND hWndLV)
{
	int nMaxItems = ListView_GetItemCount(hWndLV);

	//when saving new positions, delete the old position
	//information that is currently in the registry.
	LONG l = RegDeleteKey(HKEY_CURRENT_USER, g_szRegSubKey);

	//Create the registry key to hold the info
	HKEY hKey;
	l = RegCreateKeyEx(HKEY_CURRENT_USER, g_szRegSubKey, 0, NULL,
		REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,NULL);
	chASSERT(l == ERROR_SUCCESS);
	for (int nItem = 0; nItem < nMaxItems; nItem++)
	{
		//Get the name and positon of a ListView item.
		TCHAR szName[MAX_PATH];
		ListView_GetItemText(hWndLV, nItem, 0, szName, _countof(szName));

		POINT pt;
		ListView_GetItemPosition(hWndLV, nItem, &pt);
		//Save the name and Position in the registry
		l = RegSetValueEx(hKey, szName, 0, REG_BINARY, (PBYTE)&pt, sizeof(pt));
		chASSERT(l == ERROR_SUCCESS);
	}
	RegCloseKey(hKey);
}
void RestoreListViewItemPositions(HWND hWndLV)
{
	HKEY hkey;
	LONG l = RegOpenKeyEx(HKEY_CURRENT_USER, g_szRegSubKey,
		0, KEY_QUERY_VALUE, &hkey);
	if (l == ERROR_SUCCESS)
	{
		//if the listview has autoarrange on temporarity turn it of
		DWORD dwStyle = GetWindowStyle(hWndLV);
		if (dwStyle & LVS_AUTOARRANGE)
		{
			SetWindowLong(hWndLV, GWL_STYLE, dwStyle&LVS_AUTOARRANGE);
		}
		l = NO_ERROR;
		for (int nIndex = 0; l != ERROR_NO_MORE_ITEMS; nIndex++)
		{
			TCHAR szName[MAX_PATH];
			DWORD cbValueName = _countof(szName);

			POINT pt;
			DWORD cbData = sizeof(pt);
			DWORD nItem;

			//read a value  name and position from the registry.
			DWORD dwType;
			l = RegEnumValue(hkey, nIndex, szName, &cbValueName,
				NULL, &dwType, (PBYTE)&pt, &cbData);
			if (l == ERROR_NO_MORE_ITEMS)
			{
				continue;
			}
			if ((dwType == REG_BINARY) && (cbData == sizeof(pt)))
			{
				//the value is something we recognize; try to find an
				//item in the listview control that matches the name 
				LV_FINDINFO lvfi;
				lvfi.flags = LVFI_STRING;
				lvfi.psz = szName;
				nItem = ListView_FindItem(hWndLV, -1, &lvfi);
				if (nItem != -1)
				{
					// we found a match ;change the item's position
					ListView_SetItemPosition(hWndLV, nItem, pt.x, pt.y);
				}
			}
		}
		//turn auto arrange back on if it was originally on
		SetWindowLong(hWndLV, GWL_STYLE, dwStyle);
		RegCloseKey(hkey);
	}
}


INT_PTR WINAPI Dlg_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {

	switch (uMsg) {
		chHANDLE_DLGMSG(hWnd, WM_CLOSE, Dlg_OnClose);

	case WM_APP:
		// Uncomment the line below to invoke the debugger
		// on the process that just got the injected DLL.
		//ForceDebugBreak();

		if (lParam)
			SaveListViewItemPositions((HWND)wParam);
		else
			RestoreListViewItemPositions((HWND)wParam);
		break;
	}

	return FALSE;
}

注意你hook的是explorer 你得确定它的窗口位置用spy++来获取,不再是原先作者提示的一个窗口的唯一子窗口了

第二explorer程序是系统程序如果你是64位系统恭喜你你的整个环境都得换成64位来编译了

命令预处理得加入WIN32(64);_DEBUG;_WINDOWS;_USRDLL;

下面贴exe代码  .cpp

//#include"..\CommonFiles\CmnHdr.h"
#include<WindowsX.h>
#include<Windows.h>
#include<tchar.h>
#include"resource.h"
#pragma comment(lib,"E:\\VS2017WSpce\\Proxxxxxx\\x64\\Debug\\DIPSLib.lib")
#include"../DIPSLib/DIPSLib.h"
#include"CmnHdr.h"



BOOL Dlg_OnInitDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam)
{
	chSETDLGICONS(hWnd, IDI_DIPS);
	return TRUE;
}

void Dlg_OnCommand(HWND hWnd, int id, HWND hWndCt1, UINT codeNotify)
{
	switch (id)
	{
	case IDC_SAVE:
	case IDC_RESTORE:
	case IDCANCEL:
		EndDialog(hWnd, id);
		break;
	default:
		break;
	}
}
BOOL WINAPI Dlg_Proc2(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	//case(WM_INITDIALOG): return (SetDlgMsgResult(hWnd, message, HANDLE_##message((hWnd), (wParam), (lParam), (Dlg_OnInitDialog))))
	//case(WM_COMMAND): return (SetDlgMsgResult(hWnd, message, HANDLE_##message((hWnd), (wParam), (lParam), (Dlg_OnInitDialog))))
		chHANDLE_DLGMSG(hWnd, WM_INITDIALOG,Dlg_OnInitDialog);
		chHANDLE_DLGMSG(hWnd, WM_COMMAND, Dlg_OnCommand);
	}
	return FALSE;
}

int WINAPI _tWinMain(HINSTANCE hInstExe, HINSTANCE, PTSTR pszCmdLine, int)
{
	//Conver Command-Line character to uppercase
	CharUpperBuff(pszCmdLine, 1);
	TCHAR cWhatToDo = pszCmdLine[0];
	if ((cWhatToDo != TEXT('S')) && (cWhatToDo != TEXT('R')))
	{
		//An incalid command-line argument;prompt the user
		cWhatToDo = 0;
	}
	if (cWhatToDo == 0)
	{
		//NO Command-line argument was used to tell us what to
		//do; show usage dialog box and prompt the user
		switch (DialogBox(hInstExe,MAKEINTRESOURCE(IDD_DIPS),NULL,(DLGPROC)Dlg_Proc2))
		{
		case IDC_SAVE:
			cWhatToDo = TEXT('S');
			break;
		case IDC_RESTORE:
			cWhatToDo = TEXT('R');
			break;
		default:
			break;
		}
	}
	if (cWhatToDo == 0)
	{
		//The user doesn't want to do anything
		return (0);
	}
	//The Desktop ListView window is the grandchild of the ProMan window.
	HWND hWndLV2 = FindWindow(TEXT("Progman"), NULL);
	HWND hwnd3 = GetFirstChild(hWndLV2);
	HWND hwnd4 = GetNextSibling(hwnd3);
	HWND hWndLV = GetFirstChild(hwnd4);
	//HWND hWndLV = GetFirstChild(GetFirstChild(
	//	FindWindow(TEXT("Progman"), NULL)));
	chASSERT(IsWindow(hWndLV));

	//Set hook that injects out DLL into the Exporer's address space. After
	//setting the hook, the DIPS hidden modeless dialog box is created. we
	//send messages to this window to tell it what we want it to do.
	DWORD threadId = GetWindowThreadProcessId(hWndLV, NULL);

	chVERIFY(SetDIPSHook(threadId));
	//wait for the DIPS server window to be created.
	MSG msg;
	GetMessage(&msg, NULL, 0, 0);

	//find the handle of the hidden dialog box window.
	HWND hWndDIPS = FindWindow(NULL, TEXT("Wintellect DIPS"));

	//make sure that the window was created.
	chASSERT(IsWindow(hWndDIPS));

	//Tell the DIPS window which ListView window to manipulate
	//and wherther the item should be saved or restored
	BOOL bSave = (cWhatToDo == TEXT('S'));

	SendMessage(hWndDIPS, WM_APP, (WPARAM)hWndLV, bSave);

	//Tell the DIPS window to destory itself .Use sendMessage
	//instead of PostMessage so that we know the window is 
	//destoryed befor the hook is removed.
	SendMessage(hWndDIPS, WM_CLOSE, 0, 0);

	//Make sure that the window was destoryed.
	chASSERT(!IsWindow(hWndDIPS));

	//Unhook the DLL, removing the DIPS dialog box provedure
	//form the Exporer's address space.
	SetDIPSHook(0);
	return 0;
}

这个不要.h

需要包含那个dll的头文件,生成的dll  lib 都得移动到工程下面来,附加依赖也得把lib加上去

编译平台得移植,Unicode编码一致,字符集得一致,多线程调试得一致

然后你就可以愉快的踩坑了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值