将IRP分解成多个IRP

将IRP分解成多个IRP



将IRP分解成多个IRP

#pragma PAGEDCODE
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,
        IN PIRP pIrp)
{
 KdPrint(("DriverA:Enter AHelloDDKRead\n"));
 NTSTATUS status = STATUS_SUCCESS;

 PIO_STACK_LOCATION stack =IoGetCurrentIrpStackLocation(pIrp);

 ULONG totalLength;
 PVOID virtualAddress;
 if (!pIrp->MdlAddress)
 {
  status =STATUS_UNSUCCESSFUL;
  totalLength = 0;
  goto HelloDDKRead_EXIT;
 }
 
 virtualAddress =MmGetMdlVirtualAddress(pIrp->MdlAddress);
 totalLength =MmGetMdlByteCount(pIrp->MdlAddress);

 RtlFillMemory(virtualAddress,totalLength,0xFF);

 KdPrint(("DriverA:virtualAddress:%x\n",virtualAddress));
 KdPrint(("DriverA:totalLength:%d\n",totalLength));

HelloDDKRead_EXIT:
 // 完成IRP
 pIrp->IoStatus.Status =status;
 pIrp->IoStatus.Information =totalLength; //bytes xfered
 IoCompleteRequest( pIrp, IO_NO_INCREMENT );
 KdPrint(("DriverA:Leave AHelloDDKRead\n"));
 return status;
}
将IRP分解成多个IRP

将IRP分解成多个IRP
#pragma PAGEDCODE
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,
        IN PIRP pIrp)
{
 KdPrint(("DriverB:Enter BHelloDDKRead\n"));
 NTSTATUS status = STATUS_SUCCESS;

 PDEVICE_EXTENSION pDevExt =(PDEVICE_EXTENSION)
  pDevObj->DeviceExtension;

 PIO_STACK_LOCATION stack =IoGetCurrentIrpStackLocation(pIrp);
 
 ULONG totalLength;
 ULONG stageLength;
 PMDL mdl;
 PVOID virtualAddress;
 PMYDRIVER_RW_CONTEXT rwContext = NULL;
 PIO_STACK_LOCATION nextStack;

 if (!pIrp->MdlAddress)
 {
  status =STATUS_UNSUCCESSFUL;
  totalLength = 0;
  goto HelloDDKRead_EXIT;
 }

 //获取MDL的虚拟地址
 virtualAddress =MmGetMdlVirtualAddress(pIrp->MdlAddress);
 //获取MDL的长度
 totalLength =MmGetMdlByteCount(pIrp->MdlAddress);

 KdPrint(("DriverB:(pIrp->MdlAddress)MmGetMdlVirtualAddress:X\n",MmGetMdlVirtualAddress(pIrp->MdlAddress)));
 KdPrint(("DriverB:(pIrp->MdlAddress)MmGetMdlByteCount:%d\n",MmGetMdlByteCount(pIrp->MdlAddress)));

 //将总的传输,分成几个阶段,这里设定每次阶段的长度
   if(totalLength > MAX_PACKAGE_SIZE)
 {
       stageLength = MAX_PACKAGE_SIZE;
    }else
 {
       stageLength = totalLength;
    }

 //创建新的MDL
    mdl =IoAllocateMdl((PVOID) virtualAddress,
                       totalLength,
                       FALSE,
                       FALSE,
                       NULL);

 KdPrint(("DriverB:(newmdl)MmGetMdlVirtualAddress:X\n",MmGetMdlVirtualAddress(mdl)));
 KdPrint(("DriverB:(newmdl)MmGetMdlByteCount:%d\n",MmGetMdlByteCount(mdl)));

    if(mdl ==NULL)
 {
  KdPrint(("DriverB:Failed toalloc mem for mdl\n"));
  status =STATUS_INSUFFICIENT_RESOURCES;
  goto HelloDDKRead_EXIT;
    }

 //将IRP的MDL做重新映射
   IoBuildPartialMdl(pIrp->MdlAddress,
                     mdl,
                     (PVOID) virtualAddress,
                     stageLength);
 KdPrint(("DriverB:(newmdl)MmGetMdlVirtualAddress:X\n",MmGetMdlVirtualAddress(mdl)));
 KdPrint(("DriverB:(newmdl)MmGetMdlByteCount:%d\n",MmGetMdlByteCount(mdl)));

 rwContext = (PMYDRIVER_RW_CONTEXT)
               ExAllocatePool(NonPagedPool,sizeof(MYDRIVER_RW_CONTEXT));

   rwContext->NewMdl   =mdl;
 rwContext->PreviousMdl  =pIrp->MdlAddress;
   rwContext->Length   =totalLength - stageLength;//还剩下多少没读取
   rwContext->Numxfer   =0;      //读了多少字节
   rwContext->VirtualAddress =((ULONG_PTR)virtualAddress + stageLength);//下一阶段开始读取的地址
 rwContext->DeviceExtension =pDevExt;

 //拷贝到底层堆栈
 IoCopyCurrentIrpStackLocationToNext(pIrp);

 nextStack =IoGetNextIrpStackLocation(pIrp);
 //根据底层驱动的实现,底层驱动有可能读取这个数值,也有可能读取mdl的length。
 nextStack->Parameters.Read.Length= stageLength;

 pIrp->MdlAddress = mdl;
 
 //设定完成例程
   IoSetCompletionRoutine(pIrp,
                          (PIO_COMPLETION_ROUTINE)HelloDDKReadCompletion,
                          rwContext,
                          TRUE,
                          TRUE,
                          TRUE);

   IoCallDriver(pDevExt->TargetDevice,pIrp);
 
 pIrp->MdlAddress =rwContext->PreviousMdl;
 IoFreeMdl(rwContext->NewMdl);

HelloDDKRead_EXIT:
 // 完成IRP
 pIrp->IoStatus.Status =status;
 pIrp->IoStatus.Information =totalLength; // bytes xfered
 IoCompleteRequest( pIrp, IO_NO_INCREMENT );
 KdPrint(("DriverB:Leave BHelloDDKRead\n"));
 return status;
}
将IRP分解成多个IRP
const int MAX_PACKAGE_SIZE=1024;

#pragma PAGEDCODE
NTSTATUS
HelloDDKReadCompletion(
    INPDEVICE_OBJECT DeviceObject,
    INPIRP          Irp,
    INPVOID         Context
    )
{
 KdPrint(("DriverB:Enter BHelloDDKReadCompletion\n"));

 PMYDRIVER_RW_CONTEXT rwContext =(PMYDRIVER_RW_CONTEXT) Context;
    NTSTATUSntStatus = Irp->IoStatus.Status;

 ULONG stageLength;

 if(rwContext&& NT_SUCCESS(ntStatus))
 {
  //已经传送了多少字节
  rwContext->Numxfer+= Irp->IoStatus.Information;

      if(rwContext->Length)
    {
    //设定下一阶段读取字节数
           if(rwContext->Length >MAX_PACKAGE_SIZE)
   {
    stageLength= MAX_PACKAGE_SIZE;
           }
           else
   {
               stageLength = rwContext->Length;
           }
   //重新利用MDL
           MmPrepareMdlForReuse(rwContext->NewMdl);

           IoBuildPartialMdl(Irp->MdlAddress,
                             rwContext->NewMdl,
                             (PVOID) rwContext->VirtualAddress,
                             stageLength);
       
           rwContext->VirtualAddress += stageLength;
           rwContext->Length -= stageLength;

   IoCopyCurrentIrpStackLocationToNext(Irp);
           PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation(Irp);

   nextStack->Parameters.Read.Length= stageLength;

           IoSetCompletionRoutine(Irp,
                                  HelloDDKReadCompletion,
                                  rwContext,
                                  TRUE,
                                  TRUE,
                                  TRUE);

           IoCallDriver(rwContext->DeviceExtension->TargetDevice,
                        Irp);

           return STATUS_MORE_PROCESSING_REQUIRED;
       }
       else
  {
   //最后一次传输
           Irp->IoStatus.Information =rwContext->Numxfer;
       }
 }

 KdPrint(("DriverB:Leave BHelloDDKReadCompletion\n"));
 returnSTATUS_MORE_PROCESSING_REQUIRED; 
}

将IRP分解成多个IRP

将IRP分解成多个IRP

将IRP分解成多个IRP

IRPTrace2.00.002.zip ,IRP跟踪工具,支持Windows7。 IRPTrace 2.00.002, Build Date September 23, 2015 File name = README.TXT ====================================================================== CONTENTS ========= 1) IRPTrace Components 2) Release Notes 3) Known problems & limitations 4) Known bugs 5) Update to the documentation 6) List of supported I/O requests We strongly recommend that you read the following information about this release. 1) IRPTrace Components ===================== README.TXT - This file HOWTOREG.TXT - How to register IRPTrace and contact APSoft IRPTrace.EXE - Main application module IRPDRV.SYS - Driver for Windows NT/2000/XP/Server 2003 TERMINAL - Terminal log file TERMINAL.DLL - IRPTrace library UNINSDRV.DLL - IRPTrace library TSCUST.DLL - IRPTrace library IRPTRACE.CHM - Help file TIPS.TXT - 'Tip of the Day' tips GUID.INI - GUID database IRPTRACE.INI - Driver uninstallation information UNINST.ISU - Installation/uninstallation log file 2) Release Notes ================ Release 2.00.002 1. Fixed processing of IRPs at elevated IRQLs 2. Added support for Windows 10 Release (Build 10240) 3. Corrected processing of USB IOCTLs 4. Release 2.00.001 1. Added support for x64 Windows. 2. Added support for Windows Vista, 7 and 8.x. 3. Added decoding of all USB kernel-mode messages. 4. Added decoding of all CDB messages. 5. Revised Terminal tracing. 6. Revised on-line help file. 7. Revised list of known IOCTLs. 8. Revised list of known GUIDs. Release 1.00.007 1. Added support for Microsoft Windows Vista (?). 2. Redesign right panel view. 3. Fix bug with processing of Image hooks. 4. Several minor bugs were fixed. Release 1.00.006 1. A BSOD (blue screen) was fixed, which appeared o
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值