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

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

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的編程起到十分重要的作用。希望本文能給大家帶來一些幫助。
關鍵詞:虛擬設備驅動
主站蜘蛛池模板: 旬邑县| 河南省| 池州市| 屯昌县| 涿州市| 常州市| 新竹县| 察雅县| 五台县| 金堂县| 吉首市| 郴州市| 若尔盖县| 容城县| 获嘉县| 台江县| 秦皇岛市| 大足县| 青龙| 南溪县| 桂东县| 台北市| 景洪市| 辽源市| 龙川县| 泰兴市| 湘潭市| 鹰潭市| 于田县| 广德县| 新宁县| 焦作市| 仙桃市| 扶余县| 商河县| 兴安县| 余干县| 湘阴县| 巴中市| 玛纳斯县| 晴隆县|