第20课 钩子与数据库访问

1.Hook简介:
作用是拦截某些消息,关键函数是  SetWindowsHookEX()
SetWindowsHookEX函数的作用是安装一个应用程序定义的钩子过程,并将其放到钩子链中。注意,最后安装的钩子过程总是排列在该链的前面。
(1)鼠标钩子
(2)键盘钩子

(3)把信息传递给下一个钩子过程

2.示例程序:
2.1. 新建一基于对话框工程,  InnerHook,此过程的钩子是只拦截本进程的。
2. 2. OnInitDialog()  中添加代码:
g_hWnd=m_hWnd;
g_hMouse=SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId());  设置了鼠标钩子
g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,NULL,GetCurrentThreadId()); 设置了键盘钩子
2. 3. 完成钩子函数的编写:
(1)定义全局的变量
 HHOOK g_hKeyboard=NULL;
 HHOOK g_hMouse;
 HWND g_hWnd=NULL;
 
 LRESULT CALLBACK MouseProc(
   int nCode,      // hook code
   WPARAM wParam,  // message identifier
   LPARAM lParam   // mouse coordinates
 )
 {
  return 1;
 }
 
 LRESULT CALLBACK KeyboardProc(
   int code,       // hook code
   WPARAM wParam,  // virtual-key code
   LPARAM lParam   // keystroke-message information
 )
 {
  //if(VK_SPACE==wParam || VK_RETURN==wParam)  如果是空格键
  /*if(VK_F4==wParam && (1==(lParam>>29 & 1)))  拦截ALT+F4按键!
   return 1;
  else
   return CallNextHookEx(g_hKeyboard,code,wParam,lParam);*/
  if(VK_F2==wParam)  F2时程序可以退出,这是留的后门。否则程序无法关闭,只能用任务管理器来关闭它了。
  {
   ::SendMessage(g_hWnd,WM_CLOSE,0,0);
   UnhookWindowsHookEx(g_hKeyboard);  当程序退出时最好将钩子移除。
   UnhookWindowsHookEx(g_hMouse);
  }
  return 1;
 }

3.编写一个屏屏蔽所有进程和所有线程的钩子程序。
此时这个钩子必须安装在  DLL中,然后被某个程序调用才行。
3.1. 新建一个 DLL  工程名为 Hook
3. 2. 增加 Hook.cpp
3. 3. 代码如下:
 #include <windows.h>  包含头文件
 
 HHOOK g_hMouse=NULL;
 HHOOK g_hKeyboard=NULL;
 
 #pragma data_seg("MySec")  新建了一个节,用于将下 面的这个变量设为全局共享。
 HWND g_hWnd=NULL;  这个变量是全局共享的。
 #pragma data_seg()
 
 //#pragma comment(linker,"/section:MySec,RWS")
 /*HINSTANCE g_hInst;
 
 BOOL WINAPI DllMain(
   HINSTANCE hinstDLL,  // handle to the DLL module
   DWORD fdwReason,     // reason for calling function
   LPVOID lpvReserved   // reserved
 )
 {
  g_hInst=hinstDLL;
 }*/
 
 LRESULT CALLBACK MouseProc(
   int nCode,      // hook code
   WPARAM wParam,  // message identifier
   LPARAM lParam   // mouse coordinates
 )
 {
  return 1;  拦截了鼠标消息。
 }
 
 LRESULT CALLBACK KeyboardProc(
   int code,       // hook code
   WPARAM wParam,  // virtual-key code
   LPARAM lParam   // keystroke-message information
 )
 {
  if(VK_F2==wParam)  如果是F2键,则退出。
  {
   SendMessage(g_hWnd,WM_CLOSE,0,0);
   UnhookWindowsHookEx(g_hMouse);  当退出时将钩子卸掉。
   UnhookWindowsHookEx(g_hKeyboard);
  }
  return 1;
 }
 
 void SetHook(HWND hwnd)  此函数设置了钩子。
 {
  g_hWnd=hwnd;  注意这种传递调用它的进程的句柄的方法,比较巧妙!
  g_hMouse=SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("Hook"),0);
  g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,GetModuleHandle("Hook"),0);
 } Hook.DEF  的代码如下:
 LIBRARY Hook
 EXPORTS
 SetHook  @2
 SEGMENTS
 MySec READ WRITE SHARED   也可以设置节的属性。
      3. 4.  新建一个工程调用此钩子函数。工程名为 HookTest,基于对话框的。在OnInitDialog()中调用 SetHook(),要事先声明_declspec(dllimport) void SetHook(HWND hwnd);
       然后在Project->Setting->Link->加入..\Hook\Debug\Hook.lib ,并将Hook.Dll拷贝到当前目录。
 int cxScreen,cyScreen;
 cxScreen=GetSystemMetrics(SM_CXSCREEN);
 cyScreen=GetSystemMetrics(SM_CYSCREEN);
 SetWindowPos(&wndTopMost,0,0,cxScreen,cyScreen,SWP_SHOWWINDOW);  将窗口保持在最前面,且将该窗口大小设置为屏幕的大小。这样,用户就只能看到该窗口了。可用它实现类似屏保的功能。
 SetHook(m_hWnd);
      3. 5.DLL  的调试方法,设置断点,然后运行时断点时, step into即可。

4.数据库编程
4.1.ODBC  ADO简介: ADO可以认为是建立在ODBC上的。
   ADO  的三个核心对象
 Connection  对象
   Connection  对象表示了到数据库的连接,它管理应用程序和数据库之间的通信。 RecordsetCommand对象都有一个 ActiveConnection属性,该属性用来引用Connection对象。
 Command  对象
   Command  对象被用来处理重复执行的查询,或处理需要检查在存储过程调用中的输出或返回参数的值的查询。
 Recordset  对象
   Recordset  对象被用来获取数据。 Recordset对象存放查询的结果,这些结果由数据的行 (称为记录) 和列(称为字段 )组成。每一列都存放在Recordset Fields集合中的一个Field对象中。
4. 2. 演示在 VB  中使用ADO的方法,方法比较简单,使用方便。另外在 VB中演示了Connection Command Recordset的方法,用这三种方法都可以执行 SQL语句。
4. 3. VC  中利用ADO访问数据库。
    4.3. 1.  新建一个基于对话框的工程,名为 ADO
    4.3. 2.  在对话框中放一 ListBox和一个Button 控件。
    4.3. 3.  在使用时须导入 MSADO15.dll,方法是在StdAfx.h #import "D:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","rsEOF")
     至少于将 EOF改名为rsEOF ,是为了避免与文件中的 EOF重名。然后编译程序,将产生的 debug目录下的两个文件MSADO15.tlh MSADO15.tli加到工程中,其目的只是方便我们查看而已。并不是编译需要它。
    ADO  也是COM组件,须初始化 COM库方法是CoInitialize(NULL); 使用完后须 CoUninitialize();
     代码如下:
    void CAdoDlg::OnBtnQuery()
{
 // TOD Add your control notification handler code here
 CoInitialize(NULL);  初始化
 _ConnectionPtr pConn(__uuidof(Connection));  产生connection智能指针
 _RecordsetPtr pRst(__uuidof(Recordset));  产生recordset智能指针
 _CommandPtr pCmd(__uuidof(Command));  产生command智能指针 pConn->ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=pubs";数据库信息
 pConn->Open("","","",adConnectUnspecified);  打开数据库 //pRst=pConn->Execute("select * from authors",NULL,adCmdText);用记录集查询数据
 //pRst->Open("select * from authors",_variant_t((IDispatch*)pConn),
 // adOpenDynamic,adLockOptimistic,adCmdText);
 pCmd->put_ActiveConnection(_variant_t((IDispatch*)pConn));
 pCmd->CommandText="select * from authors";  用这种方法也可以查询数据
 pRst=pCmd->Execute(NULL,NULL,adCmdText);
 while(!pRst->rsEOF)  将查询到的数据加到列表框咯。
 {
  ((CListBox*)GetDlgItem(IDC_LIST1))->AddString(
   (_bstr_t)pRst->GetCollect("au_lname"));
  pRst->MoveNext();
 }
 
 pRst->Close();
 pConn->Close();
 pCmd.Release();
 pRst.Release();
 pConn.Release();
 CoUninitialize();
}

猜你喜欢

转载自blog.csdn.net/zhang_zxk/article/details/52401974