BOOL APIENTRY Detach()
{
switch(DLL_PROCESS_DETACH)
{
case DLL_PROCESS_ATTACH:
sprintf(szOutput,"Dll成功加载于 %d 号进程。",GetCurrentProcessId());
OutputDebugString(szOutput);
//创建更替SAS window回调函数的线程
if(FOldProc == NULL)
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,NULL,0,&dwThreadId);
break;
case DLL_PROCESS_DETACH:
sprintf(szOutput,"Dll成功卸载。",GetCurrentProcessId());
//MessageBox(NULL, szOutput, "ZZ", MB_ICONINFORMATION | MB_OK);
OutputDebugString(szOutput);
//恢复原有SAS window的回调函数
if(FOldProc != NULL)
SetWindowLong(hSASWnd,GWL_WNDPROC,long(FOldProc));
//_H卸载低级键盘钩子
if(hHook != NULL)
{
if(!UnhookWindowsHookEx(hHook))
{
OutputDebugString("Unhook failed..");
//__leave;
break;
}
OutputDebugString("键盘钩子成功取消");
}
TerminateThread(hThread,1);
CloseHandle(hThread);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
//Dll所创建线程的线程函数
DWORD WINAPI ThreadFunc()
{
//打开Winlogon桌面
HDESK hDesk = OpenDesktop("Winlogon",0,FALSE,MAXIMUM_ALLOWED);
//枚举桌面所有窗体
EnumDesktopWindows(hDesk,(WNDENUMPROC)EnumWindowsProc,0);
//修改SAS window的回调函数
if(hSASWnd != NULL)
{
FOldProc = (FARPROC)SetWindowLong(hSASWnd,GWL_WNDPROC,long(SASWindowProc));
}
CloseHandle(hDesk);
//_H同一桌面上进程之间只能发送窗口消息。无法跨进程与其他桌面发送它们。
//_H同样,Windows消息是限制应用程序定义挂钩。
//_H特定桌面中运行的进程挂钩过程将〈〈只获得针对同一桌面上创建窗口消息。〉〉
//_H详见
//_H所以,这里必须设置钩子所在线程的桌面为Default桌面
//_H才能使得钩子所在线程能接收到Default桌面的消息
hDesk = OpenDesktop("Default",0,FALSE,MAXIMUM_ALLOWED);
SetThreadDesktop(hDesk);
CloseHandle(hDesk);
//_H设置低级键盘钩子,屏蔽非SAS window的热键
//_H需要#define _WIN32_WINNT 0x0500
hHook = SetWindowsHookEx(WH_KEYBOARD_LL,KeyboardProc,GetModuleHandle(NULL),0);
if (hHook == NULL)
{
OutputDebugString("Set hook failed..");
//__leave;
return 1;
}
OutputDebugString("键盘钩子成功设置");
//_H在非GUI线程中使用消息钩子必须主动接收并分发收到的消息
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 1;
}
//枚举所有窗体句柄的回调函数
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)
{
char ClassBuf[128];
//获得当前窗体的显示文本
GetWindowText(hwnd,ClassBuf,sizeof(ClassBuf));
//在"Winlogon"桌面中查询窗口"SAS window"。
if(strstr(ClassBuf,"SAS window")!=NULL)
{
//返回SAS window句柄
hSASWnd = hwnd;
return FALSE;
}
return TRUE;
}