Chinaunix首页 | 论坛 | 博客
  • 博客访问: 363241
  • 博文数量: 112
  • 博客积分: 5245
  • 博客等级: 大校
  • 技术积分: 1120
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-07 09:20
个人简介

静下来,定好方向,好好干。

文章分类
文章存档

2017年(1)

2012年(1)

2011年(5)

2010年(6)

2009年(16)

2008年(59)

2007年(24)

我的朋友

分类: WINDOWS

2008-05-21 14:09:50

用apc机制,参考代码如下:  
  #include   "ntddk.h"  
  #include   "apc.h"  
   
   
  NTSTATUS  
  DriverDispatch(  
          IN   PDEVICE_OBJECT   DeviceObject,  
          IN   PIRP                       Irp  
          );  
   
  VOID  
  DriverUnload(  
          IN   PDRIVER_OBJECT   DriverObject  
          );  
           
  NTSTATUS   init();  
  void   MapBuf(PVOID   p);  
  void   MyRoutine(struct   _KAPC   *Apc,  
  PKNORMAL_ROUTINE   norm_routine,  
  void   *context,  
  void   *SysArg1,  
  void   *SysArg2);  
  void   SendAPC(ULONG   addr,   ULONG   arg1,   ULONG   arg2,   ULONG   arg3);  
  ULONG   APC_Routine=0;  
  PKTHREAD   APC_Thread=NULL;  
  PVOID   Buf=NULL;  
   
  void   KeInitializeApc(struct   _KAPC   *Apc,   PKTHREAD   pthread,  
  unsigned   char   state_index,  
  PKKERNEL_ROUTINE   ker_routine,  
  PKRUNDOWN_ROUTINE   rd_routine,  
  PKNORMAL_ROUTINE   nor_routine,  
  unsigned   char   mode,  
  void   *context);  
   
  void   KeInsertQueueApc(struct   _KAPC   *APC,  
  void   *SysArg1,  
  void   *SysArg2,  
  unsigned   char   arg4);  
   
   
  NTSTATUS   init()  
  {  
  DbgPrint("%S:init\n",DRIVER_DEVICE_NAME);  
  return   STATUS_SUCCESS;  
  }  
   
  struct   _KAPC   *apc;  
   
  void   MyRoutine(struct   _KAPC   *Apc,  
  PKNORMAL_ROUTINE   norm_routine,  
  void   *context,  
  void   *SysArg1,  
  void   *SysArg2)  
  {  
  DbgPrint("%S:Kernel   Routine\n",DRIVER_DEVICE_NAME);  
  ExFreePool(Apc);  
  return;  
  }  
   
  void   SendAPC(ULONG   addr,   ULONG   arg1,   ULONG   arg2,   ULONG   arg3)    
  {  
  unsigned   char   *b=NULL;  
  DbgPrint("%S:Send   APC\n",DRIVER_DEVICE_NAME);  
  apc=ExAllocatePool(NonPagedPool,   sizeof(struct   _KAPC));  
  if(apc==NULL)  
  {  
  DbgPrint("%S:ExAllocatePool   for   APC   fail.\n",DRIVER_DEVICE_NAME);  
  return;  
  }  
   
  /*  
  arg1=(ULONG)APC_Routine;  
  arg2=(ULONG)APC_Thread;  
  arg3=(ULONG)apc;*/  
   
  b=(unsigned   char   *)Buf;  
  if(b)  
  {  
  b[0]='a';  
   
  b[2]='b';  
   
  b[4]='c';  
   
  }  
  KeInitializeApc(apc,   APC_Thread,   0,(PKKERNEL_ROUTINE)&MyRoutine,   0,(PKNORMAL_ROUTINE)addr,   1,   (PVOID)arg1);  
  KeInsertQueueApc(apc,   (PVOID)arg2,   (PVOID)arg3,   0);  
  }  
   
  void   MapBuf(PVOID   p)  
  {  
  PHYSICAL_ADDRESS   pa;  
  pa=MmGetPhysicalAddress(p);  
  DbgPrint("%S:p:%08x,pa:%08x.\n",DRIVER_DEVICE_NAME,p,pa.LowPart);  
   
  Buf=MmMapIoSpace(pa,1024*4,FALSE);  
  if   (Buf==NULL)  
   
  {  
    DbgPrint("%S:MmMapIoSpace   Fail.\n",DRIVER_DEVICE_NAME);  
    return;  
     
  }  
  else  
  {  
  DbgPrint("%S:MmMapIoSpace   OK:%08x.\n",DRIVER_DEVICE_NAME,Buf);  
  }  
   
   
  }  
   
   
  NTSTATUS  
  DriverEntry(IN   PDRIVER_OBJECT     DriverObject,IN   PUNICODE_STRING   RegistryPath)  
  {  
   
  PDEVICE_OBJECT                   deviceObject                 =   NULL;    
  NTSTATUS                               ntStatus;    
  WCHAR                                     deviceNameBuffer[]     =   L"\\Device\\"DRIVER_DEVICE_NAME;    
  UNICODE_STRING                   deviceNameUnicodeString;    
  WCHAR                                     deviceLinkBuffer[]     =   L"\\DosDevices\\"DRIVER_DEVICE_NAME;    
  UNICODE_STRING                   deviceLinkUnicodeString;    
   
  DbgPrint("%S:DriverEntry\n",DRIVER_DEVICE_NAME);  
  RtlInitUnicodeString   (&deviceNameUnicodeString,   deviceNameBuffer);    
  ntStatus   =   IoCreateDevice   (DriverObject,    
        0,    
        &deviceNameUnicodeString,    
        FILE_DEVICE_TESTSYS,    
        0,    
        FALSE,    
        &deviceObject    
        );    
   
  if   (!NT_SUCCESS(ntStatus))   return   ntStatus;  
        RtlInitUnicodeString   (&deviceLinkUnicodeString,   deviceLinkBuffer);  
        ntStatus   =   IoCreateSymbolicLink   (&deviceLinkUnicodeString,     &deviceNameUnicodeString);  
        if   (!NT_SUCCESS(ntStatus))    
        {  
                IoDeleteDevice   (deviceObject);    
                return   ntStatus;    
        }    
   
  ntStatus=init();    
   
  if   (!NT_SUCCESS(ntStatus))    
  {  
                IoDeleteDevice   (deviceObject);    
                IoDeleteSymbolicLink(&deviceLinkUnicodeString);    
                return   ntStatus;    
  }    
   
   
        DriverObject->MajorFunction[IRP_MJ_CREATE]                   =     DriverObject->MajorFunction[IRP_MJ_CLOSE]                     =         DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]   =   DriverDispatch;    
        DriverObject->DriverUnload                                                   =   DriverUnload;    
        return   STATUS_SUCCESS;    
   
  }  
   
   
  NTSTATUS  
  DriverDispatch(  
          IN   PDEVICE_OBJECT   DeviceObject,  
          IN   PIRP                       Irp  
          )  
  {  
          PIO_STACK_LOCATION   pCurStack;  
          //NTSTATUS   status;  
          pmydata   pData;  
       
           
           
          pCurStack   =IoGetCurrentIrpStackLocation(Irp);  
          pData=   (pmydata)Irp->AssociatedIrp.SystemBuffer;  
             
          switch(pCurStack->MajorFunction)  
          {  
          case   IRP_MJ_DEVICE_CONTROL:  
          DbgPrint("%S:   DriverDispatch:IRP_MJ_DEVICE_CONTROL\n",DRIVER_DEVICE_NAME);  
          switch(pCurStack->Parameters.DeviceIoControl.IoControlCode)  
          {  
          case   IOCTL_PASS_HANDLE:  
          switch(pData->cmdType)  
          {  
          case   PASS_APC_ROUTINE:  
          APC_Routine=pData->APC_Routine;  
          APC_Thread=KeGetCurrentThread();  
          MapBuf(pData->Buf);  
          DbgPrint("%S:   APC_Routine:%08x,APC_Thread:%08x.\n",DRIVER_DEVICE_NAME,APC_Routine,APC_Thread);  
          break;  
           
          case   CALL_APC_ROUTINE:  
          if(APC_Routine)   SendAPC(APC_Routine,0,0,0);  
          break;  
           
          default:  
          break;  
          }  
          break;  
          default:  
           
          break;  
           
          }  
           
           
          break;  
           
          case   IRP_MJ_CREATE:  
          DbgPrint("%S:   DriverDispatch:IRP_MJ_CREATE\n",DRIVER_DEVICE_NAME);  
          break;  
           
          case   IRP_MJ_CLOSE:  
          DbgPrint("%S:   DriverDispatch:IRP_MJ_CLOSE\n",DRIVER_DEVICE_NAME);  
          break;  
          default:  
          break;  
          }  
           
          Irp->IoStatus.Status             =   STATUS_SUCCESS;  
          IoCompleteRequest   (Irp,  
                                                IO_NO_INCREMENT  
                                                );  
          return   STATUS_SUCCESS;   //Irp->IoStatus.Status;  
  }  
   
   
   
  VOID  
  DriverUnload(  
          IN   PDRIVER_OBJECT   DriverObject  
          )  
  {  
          WCHAR                                     deviceLinkBuffer[]     =   L"\\DosDevices\\"DRIVER_DEVICE_NAME;  
          UNICODE_STRING                   deviceLinkUnicodeString;  
   
           
          if   (Buf)   MmUnmapIoSpace(Buf,1024*4);              
             
          RtlInitUnicodeString   (&deviceLinkUnicodeString,  
                                                      deviceLinkBuffer  
                                                      );  
   
          IoDeleteSymbolicLink   (&deviceLinkUnicodeString);  
          IoDeleteDevice   (DriverObject->DeviceObject);  
   
          DbgPrint("%S:DriverUnload\n",DRIVER_DEVICE_NAME);  
  }  
 
应用程序代码:  
  #include    
  #include    
   
  #include   ".\APC.h"  
  void   MyApcRoutine(ULONG   arg1,   ULONG   arg2,   ULONG   arg3);  
  DWORD   MyThread(PVOID   param);  
   
  ULONG   buf[1024]={0};  
   
   
  void   main(int   argc,char   *argv[])  
  {  
   
  HANDLE   Handle=0;  
  DWORD   ThreadID;  
     
  Handle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&MyThread,0,0,&ThreadID);  
  if(Handle)    
  {  
  CloseHandle(Handle);  
  printf("APC   Thread   is   running.\n");  
  }  
  else  
  {  
  printf("APC   Thread   Create   fail.\n");  
  return;  
  }  
   
   
  printf("Press   any   key   to   end.\n");  
  _getch();  
     
   
  }  
   
   
  void   MyApcRoutine(ULONG   arg1,   ULONG   arg2,   ULONG   arg3)  
  {  
   
  printf("APC   is   called.\n");  
  printf("Buf:%S\n",(char   *)buf);  
  //printf("arg1:%08x,arg2:%08x,arg3:%08x.\n",arg1,arg2,arg3);  
   
   
  }  
   
  DWORD   MyThread(PVOID   param)  
  {  
  DWORD   retBytes;  
  HANDLE   Handle;  
  mydata   pData;  
    int   ret;  
   
   
   
  Handle   =   CreateFile("\\\\.\\sys_apc",  
          GENERIC_READ   |   GENERIC_WRITE,    
          0,  
          NULL,  
          OPEN_EXISTING,  
          0,  
          NULL);  
  if   (Handle   ==   INVALID_HANDLE_VALUE)  
  {  
  printf("CreateFile   Fail:%lx\n",GetLastError());  
  return   0;  
   
  }  
   
   
  pData.cmdType=PASS_APC_ROUTINE;  
  pData.APC_Routine=(ULONG)MyApcRoutine;  
  pData.Buf=(PVOID)&buf;  
  ret=DeviceIoControl(Handle,IOCTL_PASS_HANDLE,&pData,sizeof(pData),NULL,0,&retBytes,NULL);  
  if   (ret==0)  
  {  
  printf("DeviceIoControl   Error:%lx\n",GetLastError());  
  CloseHandle(Handle);  
  return   0;  
  }  
   
       
  CloseHandle(Handle);  
   
  printf("buf:%08x\n",pData.Buf);  
   
  printf("Wait   APC   CALL.\n");  
  while   (TRUE)  
  SleepEx(-1,   TRUE);  
   
  return   0;  
  }   
 
 
测试程序:  
  #include    
  #include    
   
  #include   ".\APC.h"  
   
  void   main(int   argc,char   *argv[])  
  {  
   
   
   
  DWORD   retBytes;  
  HANDLE   Handle;  
  mydata   pData;  
    int   ret;  
   
   
   
  Handle   =   CreateFile("\\\\.\\sys_apc",  
          GENERIC_READ   |   GENERIC_WRITE,    
          0,  
          NULL,  
          OPEN_EXISTING,  
          0,  
          NULL);  
  if   (Handle   ==   INVALID_HANDLE_VALUE)  
  {  
  printf("CreateFile   Fail:%lx\n",GetLastError());  
  return;  
   
  }  
   
   
  pData.cmdType=CALL_APC_ROUTINE;  
   
  ret=DeviceIoControl(Handle,IOCTL_PASS_HANDLE,&pData,sizeof(pData),NULL,0,&retBytes,NULL);  
  if   (ret==0)  
  {  
  printf("DeviceIoControl   Error:%lx\n",GetLastError());  
  CloseHandle(Handle);  
  return;  
  }  
   
       
  CloseHandle(Handle);  
   
  printf("\n");  
   
     
   
  }   
/////////////////////////////////////

《设备驱动程序通知应用程序的几种方法》

各部分实现的部分代码如下:

. init()

{

VMINFO *pVmInfo;

if(bCreated){

        pVmInfo = _HeapAllocate(sizeof(VMINFO),0);

        if(pVmInfo){

               pVmInfo ->bCreated = TRUE;

               pVmInfo ->hVm = 0;

               strcpy(pVmInfo->buffer, "Apc test program!");

               _VWIN32_QueueUserApc(backcallFunc,(DWORD)pVmInfo,appThread);

                                           //向应用程序发送消息,调用回调函数。

        }

}

return;

}

 

hEventRing3 = CreateEvent( 0,FALSE,FALSE,NULL); //主线程:创建一个Ring3事件

if(!hEventRing3){

       AfxMessageBox("Cannot Create the event!");

       exit(1);

}

hKernel32Dll = LoadLibrary("Kernel32.dll"); //加载未公开的动态链接库。

if(!hKernel32Dll){

       AfxMessageBox("Cannot load the Kernel32.dll");

       exit(1);

}

pfOpenVxDHandle = (HANDLE(WINAPI*)(HANDLE))

                            GetProcAddress(hKernel32Dll,"OpenVxDHandle");

//调用GetProcAddress获取OpenVxDHandle的地址。

if(!pfOpenVxDHandle){

              AfxMessageBox("Cannot Open the VxD handler");

              exit(1);

}

hEventRing0 = (*pfOpenVxDHandle)(hEventRing3);  //得到Ring3事件的Ring0句柄。

if(!hEventRing0){

       AfxMessageBox("Cannot create the ring0 handler!");

       exit(1);

}

hDevice = CreateFile("\\\\.\\eventvxd.vxd",0,0,0,

             CREATE_NEW,FILE_FLAG_DELETE_ON_CLOSE,0); //动态加载设备驱动程序

if(!hDevice){

report("Cannot Load VxD eror = %x",GetLastError());

exit(1);

}

DWORD x;

DWORD cbBytesReturn;     

if(!DeviceIoControl(hDevice,EVENT_REGISTER,hEventRing0,sizeof(hEventRing0),&x,sizeof(DWORD),&cbBytesReturn,0)){ //将事件的Ring0句柄传送给设备驱动程序。

              report("DeviceIoControl failed:error %x",GetLastError());

           exit(1);

       }

pVmDDB = (VmDDB *)x;

AfxBeginThread(backCallFunc,GetSafeHwnd()); //创建一个辅助线程等待事件的有信号。

………………………………  //主线程干其它的事情。

 

UINT backCallFunc(LPVOID lParam)  //辅助线程

{

       while(1)

       {

              WaitForSingleObject((HANDLE)hEventRing3,INFINITE);//等待事件的发生。

              ……………………………… //响应VxD的通知。

       }

       return 0;

}

设备驱动程序部分:

       case EVENT_REGISTER:

              hEventRing0 = p->dioc_InBuf;   //得到事件的Ring0句柄。

           *(DWORD *)p->dioc_OutBuf = (DWORD *)(&pVmDDB);

              *(DWORD *)p->dioc_bytesret = sizeof (DWORD);//(DWORD *)(&pVmDDB);

              returnCode = 0;

              break;

 

       case EVENT_MESSAGE:

        oper.a = ((operators*)(p->dioc_InBuf))->a;

              oper.b = ((operators*)(p->dioc_InBuf))->b;

        pVmDDB.z = oper.a * oper.b;

              _VWIN32_SetWin32Event(hEventRing0);

//条件成熟时,设备驱动程序将事件设置为有信号状态。

              returnCode = 0;

              break;

 

#define WM_MY_MESSAGE 0x0410  //自定义消息

BEGIN_MESSAGE_MAP(CIrqTest, CDialog)  //将自定义消息加入消息循环。

    ON_MESSAGE(WM_MY_MESSAGE,MyMessage)

       //{{AFX_MSG_MAP(CIrqTest)

       ON_BN_CLICKED(IDC_START, OnStart)

       ON_BN_CLICKED(IDC_STOP, OnStop)

       //}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

void CIrqTest::OnStart()

{

       // TODO: Add your control notification handler code here

       hDevice =

CreateFile("\\\\.\\testirq.vxd",0,0,0,CREATE_NEW,FILE_FLAG_DELETE_ON_CLOSE,0);

                                              //动态加载设备驱动程序。

       if(hDevice == INVALID_HANDLE_VALUE){

              DWORD errorCode;

              errorCode = GetLastError();

              AfxMessageBox("Cannot load the testIrq.vxd");

              if(errorCode == ERROR_NOT_SUPPORTED){

                     DeleteFile("\\\\.\\testirq");

              }

              exit(1);

       }

       HWND hWnd = GetSafeHwnd();   //获得当前窗口的句柄。

       if(!DeviceIoControl(hDevice,W32IF_PASS_EVENT,&hWnd,sizeof(DWORD),NULL,0,NULL,0))    //将当前窗口句柄传送给设备驱动程序。

    AfxMessageBox("DeviceIoControl failed!");

    GetDlgItem(IDC_START)->EnableWindow(FALSE);

}

 

LRESULT CIrqTest::MyMessage(WPARAM wParam, LPARAM lParam) 

//自定义消息处理函数

{

       UpdateData(TRUE);

    if(m_nLing == "")

              m_nLing = "lingling";

       else

              m_nLing = "";

       UpdateData(FALSE);

       return 0;

}

设备驱动程序部分:

#define WM_MY_MESSAGE 0x0410  //自定义消息

case W32IF_PASS_EVENT:

       PostMsghWnd=(DWORD*)p->dioc_InBuf; 

       hWnd=(HANDLE)*PostMsghWnd;       //获得主窗口句柄

       returnCode = 0;

       break;

 

VOID _stdcall EventHandler(VMHANDLE hVM,PVOID RefData,CLIENT_STRUCT *pRegs)

{

       //在中断服务例程中,对中断计数器计数并向Ring 3层应用程序发送自定义消息;

       if( hWnd && ( TickCounter%100 == 0 ) ){

              SHELL_PostMessage(hWnd,WM_MY_MESSAGE,0,0,NULL,NULL);

                                          //条件成熟时,设备驱动程序向应用程序发送消息。

       }

       TickCounter++;

       ReadCMOS(STATREG_C);//清除RTC状态标志      

}

 

HANDLE hWdm1 = CreateFile("\\\\.\\Wdm1dev-0",  //加载设备驱动程序。

              GENERIC_READ | GENERIC_WRITE,

              FILE_SHARE_READ | FILE_SHARE_WRITE,

              NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL);

if( hWdm1==INVALID_HANDLE_VALUE){

              printf("XXX  Could not find open Wdm1 device\n");

              return 1;

}

printf("     Opened OK\n");

 

DWORD junk;

OVERLAPPED Overlapped;

DWORD BytesReturned;

 

Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 

//创建一个手动复位的事件,事件的初始状态为无信号状态。

DWORD code;

if (DeviceIoControl(hWdm1,IOCTL_WDM1_ASYN,

                                   NULL, 0, // Input

                                   NULL, 0, // Output

                                   &BytesReturned,&Overlapped)){

   code= 0; 

}else{

       code = GetLastError();

       printf("return device pending:%d\n",code);

}

………………………………//进行一些其它的工作。

WaitForSingleObject(Overlapped.hEvent,INFINITE); //等待事件变成有信号状态。

ResetEvent(Overlapped.hEvent );   //手动复位事件。

if (code == ERROR_IO_PENDING){

       if (GetOverlappedResult(hWdm1, &Overlapped, &junk, TRUE)){ //重叠I/O操作。

    code = 0;

       }

       else

              code = GetLastError();

}

if (code != 0)

       printf("Error!\n");

else

       printf("Ansynchronic I/O ok!\n");

设备驱动程序部分:

       // Get access to the shared buffer

       KIRQL irql;

       KeAcquireSpinLock(&BufferLock,&irql);

       switch( ControlCode){

       ………………………………

       case IOCTL_WDM1_ASYN:

              IoMarkIrpPending(Irp);    //IRP标志为挂起状态。

              IoStartPacket(fdo,Irp,1,CancelIrp);

 //如果当前设备驱动程序忙,则将IRP放入队列中,否则马上调用StartIo例程。

              KeReleaseSpinLock(&BufferLock,irql);

              status = STATUS_PENDING;  

              return status;

       ………………………………             

}

VOID CancelIrp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )  //取消例程。

{

       if(Irp == DeviceObject->CurrentIrp) {

              IoReleaseCancelSpinLock(Irp->CancelIrql);

              IoStartNextPacket(DeviceObject,TRUE);

       } else {

              KeRemoveEntryDeviceQueue(

                     &DeviceObject->DeviceQueue,

                     &Irp->Tail.Overlay.DeviceQueueEntry        

              );

              IoReleaseCancelSpinLock(Irp->CancelIrql);

       }

       Irp->IoStatus.Status = STATUS_CANCELLED;

       Irp->IoStatus.Information = 0;

       IoCompleteRequest(Irp,IO_NO_INCREMENT);

       return;

}

NTSTATUS CompleteIrp( PIRP Irp, NTSTATUS status, ULONG info)

//在适当的时候调用它,完成IRP

{

       Irp->IoStatus.Status = status;

       Irp->IoStatus.Information = info;

       IoCompleteRequest(Irp,IO_NO_INCREMENT);

       return status;

}

VOID StartIo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) //StartIo例程

{

       ULONG i,j,k;

       ULONG z;

       …………………………//进行一些其它的处理。

       CompleteIrp(Irp,STATUS_SUCCESS,0);  //完成IRP

       return;

}

 

HANDLE hEvent;

DWORD junk;

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);         //创建一个事件

if(!DeviceIoControl(hWdm1,IOCTL_WDM1_EVENT,&hEvent,sizeof(hEvent),NULL,0,&junk,NULL)){                                    //将事件句柄传送给设备驱动程序

        printf("Error %d in IOCTL_REGISTER_EVENT call\n", GetLastError());

        CloseHandle(hEvent);

        CloseHandle(hWdm1);

        return 1;

}

HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, &junk);

//创建辅助线程

辅助线程部分:

DWORD WINAPI ThreadProc(LPVOID junkola)

{                                               // ThreadProc

       WaitForSingleObject(hEvent, INFINITE);       //等待事件变成有信号状态。

       puts("\nEvent happened\n");

       return 0;

}                             //ThreadProc

设备驱动程序部分:

case IOCTL_WDM1_EVENT:

        if( InputLength != sizeof(HANDLE))

               status = STATUS_INVALID_PARAMETER;

        else{

               HANDLE EventMsg = *(PHANDLE)Irp->AssociatedIrp.SystemBuffer;

                                              //获取事件的句柄。

               status = ObReferenceObjectByHandle(EventMsg,

                         EVENT_MODIFY_STATE,

                         *ExEventObjectType,

                         Irp->RequestorMode,

                         (PVOID*)(&dx->pEvent),

                         NULL);                                //得到事件的参考地址。

        }

…………………………………………………………

KeSetEvent(dx->pEvent,0,FALSE);     //当条件具备时,将事件置为有信号状态。

 

NTSTATUS Wdm1Close(IN PDEVICE_OBJECT fdo,IN PIRP Irp){

PWDM1_DEVICE_EXTENSION

dx = (PWDM1_DEVICE_EXTENSION)fdo->DeviceExtension;

if(dx->pEvent){

        ObDereferenceObject(dx->pEvent);  

        dx->pEvent = NULL;

}

 ………………;

}

 

   
阅读(1844) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~