围观网络之三 -- 浅探索NDIS5.1(2)

二、       各个组件的绑定

1.       生成设备

 

当PNP管理器检测到有NIC的时候,会遍历所有注册的微端口驱动,通知他们要AddDevice ,从ndisRegisterMiniportDriver可以看到这个过程已经被NDIS托管

 

int __stdcall ndisAddDevice(int DriverObject, _UNICODE_STRING **SourceString, PDEVICE_OBJECTTargetDevice, char a4)

 

ndisAddDevice的大体逻辑是:

a, DriverBlock = IoGetDriverObjectExtension(DriverObject, 'NMID'); 得到驱动的 驱动块(DriverHandle) ,遍历ndisMiniDriverList 找到与之对应的节点

 

b, 创建一个设备对象,attach到\Device\PnPManager

其中 微端口设备块(_NDIS_MINIPORT_BLOCK)作为设备扩展的一部分miniPortBlock = (DeviceObject->DeviceExtension+ 72);

 

这是一个非常大的结构,在AddService中主要对这个结构一些初始化,需要注意的是以下几点

 

 *(DeviceObject->DeviceExtension + 20) = _DriverBlock; 设备扩展前面这个结构0x48的小结构没有搞清,但可以明确这里保存了驱动块
 miniPortBlock->PrimaryMiniport =miniPortBlock;
 miniPortBlock->PhysicalDeviceObject =_TargetDevice;   //指向挂载的设备
 miniPortBlock->DeviceObject = DeviceObject;                 //指向自己所属的驱动设备
miniPortBlock->NextDeviceObject =TargetDevice;
 miniPortBlock->WrapperContext =DeviceObject->DeviceExtension;     指向设备扩展
 miniPortBlock->NextGlobalMiniport = ndisMiniportList;挂入全局链表
 ndisMiniportList = miniPortBlock;


 

2.协议帮顶下层真实微端口驱动

PART ONE 绑定初始化

 

在passthru!PtBindAdpter被调用时可以看到堆栈

 

Passthru!PtBindAdapter
NDIS!ndisInitializeBinding
NDIS!ndisCheckAdapterBindings
NDIS!ndisCheckProtocolBindings
NDIS!NdisReEnumerateProtocolBindings
Passthru!PtPnPNetEventReconfigure
Passthru!PtPNPHandler
NDIS!ndisIMCheckDeviceInstance
NDIS!ndisPnPDispatch
nt!IopfCallDriver
nt!IopSynchronousCall
nt!IopStartDevice
nt!PipProcessStartPhase1
nt!PipProcessDevNodeTree
nt!PiRestartDevice
nt!PipDeviceActionWorker
nt!ExpWorkerThread
nt!PspSystemThreadStartup
nt!KiThreadStartup


 

PNP管理器检索一个驱动设备并调用nt!IopStartDevice 这里之前和WDM都一样

 

NDIS!ndisPnPDispatch托管函数托管了IRP_MJ_PNP 

 

IRP_MN_START_DEVICE的时候将执行以下代码


if (!Minor ) 
  {
    pMiniPortBlock->PnPFlags =&_NULL_IMPORT_DESCRIPTOR | pMiniPortBlock->PnPFlags & 0xFFFFFFEF;
    IrpSp = v6->Tail.Overlay.___u4.CurrentStackLocation;
memcpy(&IrpSp[-1], IrpSp, 0x1Cu);
    *(&IrpSp->Control - 36) = 0;
    v5 = ndisPassIrpDownTheStack(pIrp, v14);  //向设备栈下一层下发
    if ( v5 >= 0 )
    {
      _DriverBlock =pMiniPortBlock->DriverHandle;
      if ( _DriverBlock->Flags & 1 ) //这个标志表示这是一个中间层驱动的 驱动块
      {
        BYTE1(pMiniPortBlock->Flags) |=0x80u;
        if (ndisIMCheckDeviceInstance(_DriverBlock, &pMiniPortBlock->MiniportName,&pDevObj) )
       {
         KeWaitForSingleObject(&pMiniPortBlock->DriverHandle->IMStartRemoveMutex,0, 0, 0, 0);
          v5 = ndisIMInitializeDeviceInstance(pMiniPortBlock,pDevObj, 1);
         KeReleaseMutex(&pMiniPortBlock->DriverHandle->IMStartRemoveMutex,0);
        }
      }
      Else //否则这是一个miniport
      {
        if (ndisPnPStartDevice(pDevObj, pIrp)== 0 && BYTE2(pMiniPortBlock->Flags) & 2  &&  !ndisMediaTypeCl[p
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值