`

触摸屏应用相关技术之二——鼠标键盘hook

    博客分类:
  • VC++
阅读更多

触摸屏应用相关技术之二——鼠标键盘hook

上文提及,在系统启动过程中,到访问内容完全占据桌面的间隙,桌面直接暴露给访客,这是危险的间隙,需要想办法解决。
我们的应对措施是:在这段间隙中,对鼠标键盘进行完全锁定,直至访问内容全屏打开。开放鼠标左键,允许访客交互内容。
利用hook,我们可以在客户端统计点击数,及长时间无人点击时自动切回内容首页。


为此需要利用hook技术,并在Winlogon中载入。
在注册表中登记项如下:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\CET]
"Asynchronous"=dword:00000000
"Dllname"="SetHook.dll"
"Impersonate"=dword:00000000
"Logoff"="StopProcessAtWinLogoff"
"Logon"="StartProcessAtWinLogon"

SetHook.dll中的关键代码如下:

//全局变量
HHOOK hKeyBoardHook=NULL; //keyboard hook
HHOOK hMouseHook=NULL; //mouse hook
HWND hOutPutWnd=NULL; //Display Pass Wnd


//Winlogon加载函数
VOID APIENTRY StartProcessAtWinLogon (PWLX_NOTIFICATION_INFO pInfo)
{
  //start hook
  hThread= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,NULL,0,&dwThreadId);
  //get jk_path
  getJkPath();
}


//Winlogon卸载函数
VOID APIENTRY StopProcessAtWinLogoff (PWLX_NOTIFICATION_INFO pInfo)
{
    //MessageBox(NULL,"系统正在注销!","Winlogon   Notification   Package",MB_OK);   
}



//鼠标键盘hook
DWORD WINAPI ThreadFunc()
{
    HDESK hDesk;

 //_H同一桌面上进程之间只能发送窗口消息。无法跨进程与其他桌面发送它们。
 //_H同样,Windows消息是限制应用程序定义挂钩。
 //_H特定桌面中运行的进程挂钩过程将〈〈只获得针对同一桌面上创建窗口消息。〉〉
 //_H详见http://support.microsoft.com/kb/171890/zh-cn
 //_H所以,这里必须设置钩子所在线程的桌面为Default桌面
 //_H才能使得钩子所在线程能接收到Default桌面的消息
 hDesk = OpenDesktop("Default",0,FALSE,MAXIMUM_ALLOWED);
 SetThreadDesktop(hDesk);
 CloseHandle(hDesk);


 //_H设置低级键盘钩子,屏蔽非SAS window的热键
 //_H需要#define _WIN32_WINNT 0x0500
  hMouseHook=SetWindowsHookEx(WH_MOUSE_LL,MouseHookProc,glhInstance,0);
  hKeyBoardHook=SetWindowsHookEx(WH_KEYBOARD_LL,KeyBoardProc,glhInstance,0);
 if (hMouseHook == NULL)
 {
  OutputDebugString("Set hook failed..");
  //__leave;
  return 1;
 }
 OutputDebugString("钩子成功设置");

// ::ShowWindow(::FindWindow("ProgMan",NULL),SW_HIDE);   
// ::ShowWindow(::FindWindow("Shell_TrayWnd",NULL),SW_HIDE);
//_H在非GUI线程中使用消息钩子必须主动接收并分发收到的消息
 MSG msg;
 while(GetMessage(&msg, NULL, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
return 1;
}



//取消hook
void CloseMe(){
    if(hOutPutWnd!=NULL)
        ::SendMessage(hOutPutWnd,WM_IDLE,2,0);
    BOOL mHook=UnhookWindowsHookEx(hMouseHook);
    BOOL kHook=UnhookWindowsHookEx(hKeyBoardHook);
    TerminateThread(hThread,1);
    CloseHandle(hThread);
    hThread=NULL;
}



//向桌面程序发送鼠标消息,在此基础上可以统计点击数,及长时间无人点击自动切回内容首页
void OnEvent(){
    ::SendMessage(hOutPutWnd,WM_IDLE,1,0);
}



//如果检查到桌面程序被强制关闭了,再启动它!
void ShellJK(){
  PROCESS_INFORMATION   pi;  
  STARTUPINFO   sti;  
  ZeroMemory(&sti,sizeof(sti));  
  sti.cb=sizeof(sti);  
  sti.lpDesktop="winsta0\\default";  
  CreateProcess(jk_file,NULL,NULL,NULL,FALSE,0,NULL,jk_path, &sti,   &pi);   
}

//键盘hook,按Ctrl+ESC或者Ctrl+Space退出hook
LRESULT WINAPI KeyBoardProc(int nCode,WPARAM wParam,LPARAM lParam)
{ //keyboard hook proc
    BOOL bUnlock1=FALSE;
    BOOL bUnlock2=FALSE;
    OnEvent();
    if (nCode == HC_ACTION){
    switch (wParam) {
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        case WM_KEYUP:
        case WM_SYSKEYUP:
            PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam;
            bUnlock1=(p->vkCode == VK_ESCAPE) && ((GetKeyState(VK_CONTROL) & 0x8000) != 0);//Ctrl+Esc
            bUnlock2=(p->vkCode == VK_SPACE) && ((GetKeyState(VK_CONTROL) & 0x8000) != 0);//Ctrl+Space
        break;
        }
    }
    if(bUnlock1 || bUnlock2){
        CloseMe();
    }
    return CallNextHookEx(hKeyBoardHook,nCode,wParam,lParam);
}



//鼠标hook,在hOutPutWnd为NULL前屏蔽所有事件,之后允许左键
LRESULT WINAPI MouseHookProc(int nCode,WPARAM wParam ,LPARAM lParam)
{
    //LPMOUSEHOOKSTRUCT lpMouse=(MOUSEHOOKSTRUCT FAR*)lParam;
    if(wParam==WM_RBUTTONDOWN | wParam==WM_RBUTTONUP
        | wParam==WM_LBUTTONDBLCLK){
        return TRUE;
    }
    if(hOutPutWnd!=NULL){
        if(wParam==WM_LBUTTONDOWN && nCode>=0){
            if(!IsWindow(hOutPutWnd)){
                ShellJK();
                return TRUE;
            }
            OnEvent();
        }
        return CallNextHookEx(hMouseHook,nCode,wParam,lParam);
    }
    else
        return TRUE;
}



//桌面程序全屏之后通知hook程序其窗口句柄
BOOL CHook::StartHook(HWND hwnd, int span, int dev)
{

  if(hThread==NULL)
     hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,NULL,0,&dwThreadId);
  hOutPutWnd=hwnd;
    return TRUE;
}

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics