锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 銆銆鍦―LL_PROCESS_ATTACH鐨勬椂鍊欏垱寤轟簡涓涓嚎紼嬶紝榪欎釜綰跨▼涓垱寤轟簡涓涓殣钘忕殑紿楀彛錛屽茍鍒╃敤MCI瀹炵幇鎾斁闊充箰錛屽叿浣撳氨涓嶈創鍑轟簡銆傜劧鍚庡湪DLL_PROCESS_DETACH涓仠姝㈠拰鍏抽棴璁懼銆?/p>
銆銆浣嗘槸鍦ㄥ簲鐢ㄧ▼搴忎腑錛屽彂鐜版敞鍏ユ椂鏃犲紓甯革紝鍦ㄩ渶瑕佹挙閿DLL鏄犲皠鏃跺嚭鐜頒簡闂錛岀▼搴忓嚭鐜頒簡姝誨驚鐜紝鍦ㄧ瓑寰呰繙紼嬬嚎紼嬫墽琛孎reeLibaray瀹屾瘯鏃朵笉榪斿洖浜嗐?/p>
銆銆娉ㄦ剰涓婇潰浠g爜涓璂LL_PROCESS_DETACH鐨勪唬鐮侊紝SendMessage鐢ㄦ潵鍏抽棴紿楀彛錛岀獥鍙d細鍦╓M_DESTROY閫氱煡涓嬭皟鐢≒ostQuitMessage(0)浣垮緱綰跨▼鐨勬秷鎭驚鐜鍑猴紝浠庤岀嚎紼嬮鍑恒備絾鏄疻aitForSingleObject鍑芥暟鏃犳硶榪斿洖銆?/p>
銆銆鍚庢潵鍙戠幇榪欓噷瀛樺湪姝誨驚鐜紝鍥犱負鎵цDllMain鐨勭嚎紼嬫槸搴忓垪鍖栫殑錛屽繀欏葷瓑寰呬竴涓嚎紼嬫墽琛屽畬姣曚箣鍚庡彟涓涓嚎紼嬫墠鑳芥墽琛屻傚湪SendMessage鍚庯紝瀵艱嚧鍒涘緩鐨勭嚎紼嬪嵆灝嗛鍑猴紝榪欐椂璇ョ嚎紼嬩細璋冪敤DllMain錛屽茍浠LL_THREAD_DETACH浣滀負閫氱煡銆傚彲鏄皟鐢⊿endMessage鐨勭嚎紼嬭皟鐢―llMain鏃跺嵈榪樺湪絳夊緟鍗沖皢閫鍑虹殑綰跨▼緇撴潫錛孌llMain榪樻病鏈夎繑鍥烇紝鍥犳瀛樺湪浜嗘寰幆銆?/p>
銆銆鍥犳錛屽湪DllMain涓笉閫傚悎璋冪敤WaitForSingleObject絳夊嚱鏁版潵絳夊緟綰跨▼瀹屾瘯銆?/p>
]]>

int WINAPI _tWinMain(HINSTANCE hInstExe, HINSTANCE, PTSTR pszCmdLine, int) {
// Convert command-line character to uppercase.
CharUpperBuff(pszCmdLine, 1);
TCHAR cWhatToDo = pszCmdLine[0];

if ((cWhatToDo != TEXT('S')) && (cWhatToDo != TEXT('R'))) {
// An invalid 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, Dlg_Proc)) {
case IDC_SAVE:
cWhatToDo = TEXT('S');
break;
case IDC_RESTORE:
cWhatToDo = TEXT('R');
break;
}
}

if (cWhatToDo == 0) {
// The user doesn't want to do anything.
return(0);
}
// The Desktop ListView window is the grandchild of the ProgMan window.
HWND hWndLV = GetFirstChild(GetFirstChild(
FindWindow(TEXT("ProgMan"), NULL)));
chASSERT(IsWindow(hWndLV));
// Set hook that injects our DLL into the Explorer'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.
chVERIFY(SetDIPSHook(GetWindowThreadProcessId(hWndLV, NULL)));
// Wait for the DIPS server window to be created.
MSG msg;
GetMessage(&msg, NULL, 0, 0); // 璇鋒敞鎰忚繖閲?/span>
// 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 whether the items should be saved or restored.
BOOL bSave = (cWhatToDo == TEXT('S'));
SendMessage(hWndDIPS, WM_APP, (WPARAM) hWndLV, bSave);
// Tell the DIPS window to destroy itself. Use SendMessage
// instead of PostMessage so that we know the window is
// destroyed before the hook is removed.
SendMessage(hWndDIPS, WM_CLOSE, 0, 0);
// Make sure that the window was destroyed.
chASSERT(!IsWindow(hWndDIPS));
// Unhook the DLL, removing the DIPS dialog box procedure
// from the Explorer's address space.
SetDIPSHook(0); 
return(0);
}
銆銆鐪嬪埌涓婇潰浠g爜涓殑GetMessage鍑芥暟錛堝姞綰㈣壊娉ㄩ噴閭h錛夛紝璇ュ嚱鏁版槸鍦ㄦ帴鏀朵竴涓潵鑷猠xplorer.exe榪涚▼鐨勬秷鎭紝榪欎釜娑堟伅鏄湪鎸傞挬DLL娉ㄥ叆涔嬪悗錛岀敱鎸傞挬榪囨護鍑芥暟鍙戦佺殑銆傛寕閽╄繃婊ゅ嚱鏁頒唬鐮佸涓嬶細

LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) {
static BOOL bFirstTime = TRUE;

if (bFirstTime) {
// The DLL just got injected.
bFirstTime = FALSE;
// Uncomment the line below to invoke the debugger
// on the process that just got the injected DLL.
// ForceDebugBreak();
// 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));
}
銆銆鏄庢樉鍦幫紝榪欓噷鍙戦佷簡涓涓猈M_NULL娑堟伅緇橠IPS榪涚▼錛屽綋浣跨敤緇忓吀鏍峰紡鐨勬帶浠舵椂涓鍒囧畨濂斤紝緇忚皟璇曞緱鍒扮殑MSG緇撴瀯涓殑鍚勪釜瀛楁涓烘紜殑鍊箋備絾鏄姞涓婁簡涓婇潰閭h閾炬帴鍛戒護鍚庯紝璋冭瘯寰楀埌鐨凪SG緇撴瀯鐨勫瓧孌靛帇鏍瑰氨涓嶆槸WM_NULL銆?銆?錛岃屾槸涓涓暟鍊間負49211鐨勬秷鎭紝榪欐牱瀵艱嚧浜咲IPS涓葷嚎紼嬪敜閱掞紝闅忓悗鐨凢indWindow鍙兘浼氳繑鍥炰竴涓狽ULL錛屽洜涓鴻娑堟伅騫朵笉鏄寕閽╄繃婊ゅ嚱鏁扮殑鍙戦佺殑娑堟伅銆傚綋鐒訛紝濡傛灉鍦ㄨ繖閲孲leep涓涓嬶紝鍙互寰楀埌姝g‘鐨勭獥鍙e彞鏌勶紝鎴戝湪GetMessage鍑芥暟涓婂姞浜嗕竴涓猟o-while寰幆錛岀粨鏋滀篃鐨勭‘鏄繖鏍鳳紝鍑犳寰幆涔嬪悗鍙互鏀跺埌娑堟伅涓篧M_NULL鐨勬秷鎭紝涓斿弬鏁板潎涓?銆?br>銆銆浣嗘槸鎴戜笉鏄庣櫧涓轟粈涔堝姞涓婁簡涓鏉¢摼鎺ュ懡浠や細榪欐牱錛熶笉濡ㄥぇ瀹墮兘璇曡瘯鐪嬶紝鎴戠敤鐨処DE鏄疺S2005銆?br>銆銆鍝綅楂樻墜鍙互鏉ユ寚瀵兼垜涓涓嬪憿錛?
]]>
{
static HANDLE hThread;
static DWORD dwThreadId;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hInstDll = hInstDll;
hThread = BEGINTHREADEX(NULL, 0, ThreadProc, (PVOID)hInstDll, 0, &dwThreadId);
if (hThread == NULL)
{
return FALSE;
}
break;
case DLL_PROCESS_DETACH:
SendMessage(g_hWnd, WM_CLOSE, 0, 0);
WaitForSingleObject(hThread, INFINITE); // 榪欓噷瀛樺湪姝誨驚鐜?/span>
CloseHandle(hThread); // 鎵ц涓嶅埌榪欓噷
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
default:
break;
}
return TRUE;
}