工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 技术跟踪 > Windows编程 > 正文
虚拟设备驱动程序关键问题之消息队列
[文章信息]
作者:陈国友
时间:2004-11-30
出处:中国操作系统支持者
责任编辑:方舟
[文章导读]
因为Windows采用基于消息的事件驱动机制,而VxD并不提供直接发往应用程序线程的消息
advertisement
热点推荐
· 禁止QQ登录的方法
· 给你的XML文件做个数字签名
· ImageReady制作“焰火”小动画
· Java加密和数字签名编程快速入门
· 在VB6中用命令行为模式控制GUI动作
[正文]
  因为Windows采用基于消息的事件驱动机制,而VxD并不提供直接发往应用程序线程的消息,所以PostMessage所发消息与其它众多的消息都在主线程的消息循环中处理。这样,当执行一些界面操作时,大量的消息占据了消息队列,VxD所发送的消息就有可能得不到相应的处理。

  为解决这一问题,在实际设计中可采用的方法有两种:第一种是仍采用PostMessage,但在应用程序和VxD中需设置标志位,判断消息是否被处理并作了相应的工作(如重传数据);第二种是使用Win32事件机制,将一个线程专用于等待响应Win32事件,而另一些线程用于其它处理。下面给出VxD利用Win32事件机制激活Win32应用程序线程的部分例程(见程序2)。当生成或消除(destroy)一个VM,VxD便通知注册的应用程序,并显示出相应的信息。

  在VxD中,

  DWORD OnW32Deviceiocontrol ( PDIOCPARAMETERS p ) //VxD与Win32应用程序的接口函数
  {
  DWORD rc;
  swirch ( p-$#@62;dwIoControlCode )
  {
  case DIOC_OPEN: //系统定义功能号:设备打开
  rc = 0;
  break;
  case DIOC_CLOSEHANDLE: //设备关闭
  bClientRegistered = FALSE;
  rc = 0;
  break;
  case EVENTVXD_REGISTER: //自定义功能号
  hWin32Event = p-$#@62;lpvInBuffer;
  *( (DWORD *) (p-$#@62;lpvOutBuffer) ) = (DWORD) & GlobalVMInfo;
  *( (DWORD *) (p-$#@62;lpcbBytesReturned) ) = sizeof (DWORD);
  bClientRegistered = TRUE;
  rc = 0;
  break;
  default:
  rc = 0xffffffff;
  }
  return rc; //若返回0表示成功
  }

  BOOL OnVmInit ( VMHANDLE hVM ) //一旦有VM被初始化便执行

  {
  if ( bClientRegistered )
  {
  GlobalVMInfo.hVM = hVM;
  GlobalVMInfo.bVmCreated = TRUE;
  Call_Priority_VM_Event (LOW_PRI_DEVICE_BOOST , Get_Sys_VM_Handle() ,
  PEF_WAIT_FOR_STI+PEF_WAIT_NOT_CRIT ,
  hWin32Event , PriorityEventThunk , 0 );

  //使System VM为当前运行状态,将Ring0级事件句柄作为回调过程的参数

  }

  return TRUE;
  }
 
  VOID OnVmTerminate ( VMHANDLE hVM ) //一旦有VM被终结便执行

  {
  if ( bClientRegistered )
  {
  GlobalVMInfo.hVM = hVM;
  GlobalVMInfo.bVmCreated = FALSE;
  Call_Priority_VM_Event (LOW_PRI_DEVICE_BOOST , Get_Sys_VM_Handle() ,
  PEF_WAIT_FOR_STI+PEF_WAIT_NOT_CRIT ,
  hWin32Event , PriorityEventThunk , 0 );
  }
  }

  VOID _stdcall PriorityEventHandler ( VMHANDLE hVM , PVOID Refdata , CRS * pRegs )
  {
  HANDLE hWin32Event = Refdata;
  _VWIN32_SetWin32Event ( hWin32Event ); //激活事件对象
  }

  在Win32应用程序中;

  VOID main ( int ac , char *av[ ] )
  {
  hEventRing3 = CreateEvent ( 0 , FALSE , FALSE , NULL ); //生成Ring3级事件句柄
  if ( !hEventRing3 )
  {
  printf ( "Cannot create Ring3 event\n" );
  exit ( 1 );
  }
 
  hKernel32Dll = LoadLibrary ( "kernel32.dll" );
  if ( !hKernel32Dll )
  {
  printf ( "Cannot load KERNEL32.DLL\n" );
  exit ( 1 );
  }
  
  pfOpenVxDHandle = ( HANDLE ( WINAPI * ) ( HANDLE ) )
  GetProcAddress ( Kernel32Dll , "OpenVxDHandle" );
  If ( !pfOpenVxDHandle )
  {
  printf ( "Cannot get addr of OpenVxDHandle\n" );
  exit ( 1 );
  }
 
  hEventRing0 = (*pfOpenVxDHandle ) ( hEventRing3 ); //将Ring3级事件句柄转换为Ring0级事件句柄

  if ( !hEventRing0 )
  {
  printf ( "Cannot create Ring0 event\n" );
  exit ( 1 );
  }
 
  hDevice = CreateFile ( VxDName , 0 , 0 , 0 , CREATE_NEW , FILE_FLAG_DELETE_ON_CLOSE , 0 );

  //动态加载VxD

  if ( !hDevice )
  {
  printf ( "Cannot load VxD error = %x\n" , GetLastError ( ) );
  exit ( 1 );
  }
  
  if ( !DeviceIoControl ( hDevice , EVENTVXD_REGISTER , hEventRing0 , sizeof ( hEventRing0 ) , &pVMInfo , sizeof ( pVMInfo ) , &cbBytestReturned , 0 ) )

  //Win32程序与VxD的接口函数,将Ring0级事件句柄传入VxD,从VxD传出GlobalVMInfo结构的指针

  {
  printf ( "DeviceIoControl REGISTER failed\n" );
  exit ( 1 );
  }

  CreateThread ( 0 , 0x1000 , SecondThread , hEventRing3 , 0 , &tid ); //创建线程
  printf ( "Press any key to exit..." );
  getch ( );
  CloseHandle ( hDevice );
  }
 
  DWORD WINAPI SecondThread ( PVOID hEventRing3 )
  {
  while ( TRUE )
  {
  WaitForSingleObject ( ( HANDLE ) hEventRing3 , INFINITE ); //等待相应事件
  printf ( "VM %081x was %x" , pVMInfo-$#@62;hVM , pVMInfo-$#@62;bCreated ? "created": "destroyed" );

  //显示被created或destroyed的VM

  }
  return 0;
  }
  (程序2)

  三、结束语

  虽然VxD的设计还涉及到其它许多方面,但掌握解决以上关键问题的细节将对VxD的编程起到十分重要的作用。希望本文能给大家带来一些帮助。

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • 打开”金笼子”——VXD技术漫谈
  • 民营家电商排队造手机 设备商全面杀入
  • 英特尔澄清杨旭任职传闻 官方没宣布此消息
  • 国资委河北密制联通拆分方案
  • 垃圾邮件害人害企害国 清除垃圾邮件不手软
  • 中兴携手阿尔卡特 全球逐鹿CDMA
  • 用友总裁王文京:誓将ERP变成“大众消费”
  • 香港消费者委员会:数码相机最贵未必最好
  • 外电称中兴正评估西门子手机业务 或能并购
  • Advertisement

    天极无线


    奇妙科幻|美好风光|清风车影|漫画卡通|星座生肖|明星写真|动物世界
    老鼠爱大米
    挥着翅膀的女孩
    女人味
    栀子花开
    白月光
    刚刚好
    江南
    快乐崇拜
    亲爱的你怎么不在我身边
    小薇
    2002年的第一场雪
    有多少爱可以重来
    我的地盘
    七里香
    情人
     
    老鼠爱大米 老板电话
    冲动的惩罚 七里香
    我不是黄蓉 女生撒娇
    盛夏的果实 坚持到底
    孤单北半球 眉飞色舞
    挪威的森林 可爱女人
    最浪漫的事 老板电话

    CSEEK搜索