您现在的位置: 中国教师站 >> 教师关注 >> 电脑技术 >> 编程技术 >> Visual C >> 正文

Google
浅谈 VxD 回调 Win32 应用程序 -- 赵世平
作者:Siny 文章来源:中国教师站cn-teacher 点击数: 更新时间:2007-4-22 13:03:02

 
浅谈 VxD 回调 Win32 应用程序
作者:赵世平

Windows 95 / 98 的虚拟外壳设备( Virtual Shell Device )提供了 VxD 直接回调 Win16 应用程序函数的 VxD 服务,但是没有提供 VxD 直接回调 Win32 应用程序的 VxD 服务。不过 Windows 95 / 98 还是提供了两种 VxD 回调 Win32 应用程序的方法。方法之一是使用 VWIN32.VXD 提供的“异步过程调用( APC )”功能。 Win32 应用程序首先动态加载 VxD ,并使用 DeviceIoControl 函数将回调函数的地址传递给 VxD ,然后 Win32 应用程序调用 SleepEx / WaitForMultipleObjectsEx / WaitForSingleObjectEx 函数,将 Win32 应用程序自身置为“挂起”状态,这时 VxD 可以通过 VWIN32.VXD 提供的 _VWIN32_QueueUserApc 服务调用 Win32 应用程序的回调函数。该方法较简单,目前大多数回调 Win32 应用程序的 VxD 均使用该方法[例如瑞星杀毒软件( RAV )的实时监控 VxD ( RAV_IO.VXD )即使用该方法回调 Win32 查毒/杀毒程序],《 Windows 95 System Programming 4 》一书的配套光盘中有一个名为 IFSMONITOR 的实例程序详细讲述了该方法,由于该书的配套光盘在国内很多 FTP 服务器上都可以找到,此处就不再详述了。 

方法之二是一种比较灵活的方法,这种方法充分利用了 Win32 应用程序的多线程特点和线程间通信的事件机制。 Win32 应用程序设置两个线程并定义一个事件,主线程负责动态加载/卸载 VxD 和通过 DeviceIoControl 函数与 VxD 通信,辅助线程通过 ResetEvent 函数和 WaitForSingleObject / WaitForSingleObjectEx 函数暂时挂起, VxD 可以通过 VWIN32.VXD 提供的 Win32 事件服务中的 _VWIN32_SetWin32Event 服务唤醒辅助线程,从而间接实现 VxD 回调 Win32 应用程序。由于 VWIN32.VXD 提供了与 Win32 API 几乎完全对应的 Win32 事件服务,所以该方法极其灵活,甚至可以通过定义两个事件实现 VxD 在回调 Win32 应用程序时与 Win32 应用程序完全同步。 

笔者为了验证上述方法,编写了一个动态加载/卸载 VxD 的 Win32 应用程序和一个回调 Win32 应用程序的 VxD 。其中 Win32 应用程序用 Delphi 5.0 编写,选用 Delphi 5.0 的原因是 Delphi 5.0 实现多线程非常容易,而且不必将大量代码用在 Win32 应用程序界面上; VxD 使用 VToolsD 2.03 编写,是一个挂接实时钟中断( IRQ 8 )的 VxD ,该 VxD 参照 VToolsD 2.03 中的 CHIME 实例程序编写。程序代码如下: 

Win32 应用程序工程文件( TMR_TEST.DPR ): 


program TMR_TEST; 


uses 

  Forms, 

  TT_MAIN in 'TT_MAIN.pas' {TimerTestMain}, 

  TMR_CLBK in 'TMR_CLBK.pas'; 


{$R *.RES} 


begin 

  Application.Initialize; 

  Application.CreateForm(TTimerTestMain, TimerTestMain); 

  Application.Run; 

end. 


Win32 应用程序主窗体/主线程( TT_MAIN.PAS ): 


unit TT_MAIN; 


interface 


uses 

  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 

  Menus, SyncObjs, TMR_CLBK, StdCtrls; 


type 

  TOpenVxDHandle=function(hSource:THandle):THandle;stdcall; 

   

  TTimerTestMain = class(TForm) 

    MainMenu1: TMainMenu; 

    File1: TMenuItem; 

    Exit1: TMenuItem; 

    Callback1: TMenuItem; 

    Start1: TMenuItem; 

    Label1: TLabel; 

    procedure FormShow(Sender: TObject); 

    procedure FormClose(Sender: TObject; var Action: TCloseAction); 

    procedure Exit1Click(Sender: TObject); 

    procedure Start1Click(Sender: TObject); 

  private 

    { Private declarations } 

    Handle1:THandle; 

    TimerCallback1:TTimerCallback; 

  public 

    { Public declarations } 

  end; 


const 

  TIMER_DIOC_SET_VXD_EVENT=101; 


var 

  TimerTestMain: TTimerTestMain; 


implementation 


{$R *.DFM} 


procedure TTimerTestMain.FormShow(Sender: TObj

[1] [2] [3] [4] [5] 下一页

相关专题:
 
 网友评论:(评论内容只代表网友观点,与本站立场无关!)
GOOGLE广告

阅读排行

相关文章

没有相关文章

| 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 |
中国教师站

中国教师站 版权所有 Copyright © 2006-2020 All Rights Reserved 站长:Sina & Siny
[备用域名:www.JXZYW.Com] 有事请留言有事请留言
【实力成就精品 诚信呵护品牌】

信息产业部备案
苏ICP备06018635号