成人午夜激情影院,小视频免费在线观看,国产精品夜夜嗨,欧美日韩精品一区二区在线播放

虛擬設備驅動程序關鍵問題之消息隊列

2010-08-28 10:45:15來源:西部e網作者:

    因為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的編程起到十分重要的作用。希望本文能給大家帶來一些幫助。
關鍵詞:虛擬設備驅動
主站蜘蛛池模板: 怀集县| 邢台市| 龙门县| 古蔺县| 盘山县| 洛宁县| 西丰县| 山阴县| 新泰市| 二连浩特市| 竹溪县| 称多县| 天台县| 孟州市| 鄂托克前旗| 南雄市| 岳阳市| 门源| 化德县| 金阳县| 惠东县| 满城县| 通许县| 克东县| 平顶山市| 永宁县| 孟连| 尼勒克县| 庄河市| 游戏| 洞口县| 翁牛特旗| 临城县| 浦江县| 宽甸| 荆州市| 阿合奇县| 高唐县| 宜兴市| 万山特区| 调兵山市|