YJX_Driver_016_为DDK_HelloWorld添加默认派遣例程

1、

【145】IRP简介

【205】IRP作用:

  上层应用程序 与 底层驱动通信。exe程序 与 sys 。

【245】5种常用IRP类型

   【305】IRP也可以用于 驱动与驱动间的通信

  IRP_MJ_CREATE(0x00)  // 一般由用户层的CreateFile函数产生

  IRP_MJ_CLOSE(0x02)   // 一般由用户层的CloseHandle函数产生

  IRP_MJ_READ(0x03)   // ReadFile【495】内核里面 把内核里面的对象当成文件来处理

  IRP_MJ_WRITE(0x04)   // WriteFile

  IRP_MJ_DEVICE_CONTROL(0x0e)  // 一般由用户层的DeviceIoControl函数产生

【765】

过程:

  1、创建IRP处理函数

  2、注册IRP处理函数(一般是在 在驱动的入口函数DriverEntry里,其实也可以在其他函数里注册。但是在函数DriverEntry里面注册是由原因的,以后再讲,它有一些好处)

  3、细化IRP处理函数

 

【905】注册的方式 又有2种:

方法一:统一注册派遣函数

pDriverObject->MajorFunction[IRP_MJ_CREATE] = ddk_DispatchRiutine;

pDriverObject->MajorFunction[IRP_MJ_CLOSE] = ddk_DispatchRiutine;

pDriverObject->MajorFunction[IRP_MJ_READ] = ddk_DispatchRiutine;

pDriverObject->MajorFunction[IRP_MJ_WRITE] = ddk_DispatchRiutine;

pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ddk_DispatchRiutine;

 

NTSTATUS ddk_DispatchRiutine(IN PDEVICE_OBJECT pDevobj, IN PIRP pIrp)

{

  PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(pTrp);

  switch(irpsp->MajorFunction)

  {

    case IRP_MJ_CREATE:

      break;

    IRP_MJ_CLOSE:

      break;

    case IRP_MJ_READ:

      break;

    case IRP_MJ_WRITE:

      break;

    case IRP_MJ_DEVICE_CONTROL:

      break;

    default:

      KdPrint(("其他处理"));

    // 只是完成IRP

  }

  // 成功返回

  return STATUS_SUCCESS;

}

 

【1305】方法二:分开注册

 

【1410】本课是做例子,以IRP_MJ_DEVICE_CONTROL为例

NTSTATUS ddk_DispatchRiutine_CONTROL(IN PDEVICE_OBJECT pDevobj, IN PIRP pIrp)

{

  // 对相应的IRP进行处理

  pIrp->IoStatus.Information = 0; // 设置操作的字节数为0,这里无实际意义

  pIrp->IoStatus.Status = STATUS_SUCCESS; // 返回成功

  IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 指示完成此IRP

  KdPrint(("离开派遣函数\n")); // 调试信息

  return STATUS_SUCCESS; // 返回成功

}

【1480】以第15课为例,将第15课的代码复制出来

  【1530】上一节课,有一个bug:"#pragma INITCODE"放在了前置声明的函数"DDK_Unload"的前面,

  【1570】之所以卸载的时候出错了,上节课好像是蓝屏了。"#pragma INITCODE"表示只加载一次 内存就清除掉了

  【1630】应该把"#pragma INITCODE"移动到 DriverEntry的前面

  【1665】"#pragma INITCODE"放到 DriverEntry的前面,表示DriverEntry这段代码执行之后,它相应的内存马上就释放掉

    ZC: "#pragma ???" 只能负责一个函数吗?还是说 本文件中它下面的所有函数都在它的范围下,直到遇到另一个pragma?待测试...

  【1750】(已经定义了PAGECODE) DDK_Unload 应该放在 PAGECODE[code_seg("PAGE")]里面

    【1820】#pragma PAGECODE 等价于 #pragma code_seg("PAGE")

  【2115】派遣函数一般也是放在分页内存里面的

    【2170】未分页的文件 ==> 在驱动退出之后 它也不会从内存里面清除掉

      ZC: 这个定义 总觉得说的 很... 以后再查查吧

    【2199】把"#pragma PAGECODE"也复制到 ddk_DispatchRiutine_CONTROL 的上面

      ZC: 这也验证了"#pragma ???"智能管一句?还是验证一下为好...

NTSTATUS DriverEntry(PDRIVER_OBJECT _pDrvierObject, PUNICODE_STRING B)
{
  KdPrint(("驱动成功被加载...OK+++++++++"));

  // 注册派遣函数

  _pDrvierObject->MajorFunction[IRP_MJ_CREATE] = ddk_DispatchRiutine_CONTROL;

  // ...


  CreateMyDevice(_pDrvierObject);
  _pDrvierObject->DriverUnload = DDK_Unload;
  return 1;
}

 

【2785】

  "Kernel Detective"  想看一些信息的,出错不能用了...

【2815】XueTr.exe(0.29)

  分了2个部分 exe 和 sys,驱动部分被当成了资源 放到了exe里面,后面再讲

 

ZC: 他说 WDK驱动部分被他删掉了,难道 本套教程 讲解的全是 NT驱动 没有 WDM式驱动?

 

相关内核API:

// 获取指定IRP的栈空间

PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(IN PIRP Irp);

VOID IoCompleteRequest(

  IN PIRP Irp, // 指定需要完成的IRP

  IN CCHAR PriorityBoost // 

);

 

2、

 

posted @ 2016-03-31 16:05  DebugSkill  阅读(250)  评论(0编辑  收藏  举报