lzw06061139
驱动牛犊
驱动牛犊
  • 注册日期2011-09-26
  • 最后登录2014-02-19
  • 粉丝0
  • 关注2
  • 积分36分
  • 威望251点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1902回复:2

磁盘过滤驱动与磁盘阵列(RAID-5)的问题

楼主#
更多 发布于:2011-12-15 23:23
问题描述如下:现有一个磁盘过滤驱动(采用diskperf框架), 可以过滤基本磁盘,动态磁盘中的简单卷、跨区卷、带区卷以及镜像卷,但是没法过滤RAID-5磁盘,产生问题的地方是:在过滤后的IRP_MJ_WRITE的操作中,对hook的数据的偏移由物理偏移转化为逻辑偏移时出现了错误,使用的命令为:IOCTL_VOLUME_PHYSICAL_TO_LOGICAL, NTSTATUS值为:STATUS_INVALID_PARAMETER.
 
部分代码如下:望大虾们赐教!
 
代码逻辑如下:
 
pCdpDetail[CdpId].CdpVolumeDeviceObject, 是在之前已经获取的一个RAID的Device Object。
 
(1)先构建IOCTL_VOLUME_PHYSICAL_TO_LOGICAL 类型的IRP
  (2)  获取对应磁盘的文件对象PFILE_OBJECT
 (3)调用IoCallDriver,将刚才构建的IRP发往下层驱动处理,(出错得地方就是这个例程的返回值)
 
 

 Irp = IoBuildDeviceIoControlRequest(IOCTL_VOLUME_PHYSICAL_TO_LOGICAL,
          pCdpDetail[CdpId].CdpVolumeDeviceObject,
          &PhyOffset,
          sizeof(VOLUME_PHYSICAL_OFFSET),
          &LogiOffset,
          sizeof(VOLUME_LOGICAL_OFFSET),
          FALSE,       //IPR_MJ_DEVICE_CONTROL
          &event,
          &ioStatus);      //when the request is completed by the lower-driver, this parameter will be set
 if ( NULL == Irp ) {
  DebugPrint(("<Routine>:DiskPerfPoffsetToLoffset (%d) "
   "<Error>:Calls IoBuildDeviceIoControlRequest to allocate and set up Irp error.\n"), __LINE__);
  CleanupCdpDetail(pCdpDetail);
  return Status;
 }
 
 Status = ObReferenceObjectByHandle(pCdpDetail[CdpId].CdpVolumeHandle, THREAD_ALL_ACCESS, *IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
 if ( !NT_SUCCESS(Status) ) {
  DebugPrint(("<Routine>:DiskPerfPoffsetToLoffset (%d) <Error>:get cdp file object failed, ntstatus:%ld\n"), __LINE__, Status);
  CleanupCdpDetail(pCdpDetail);
  return Status;
 }
 ObDereferenceObject(FileObject);
 StackLocation = IoGetNextIrpStackLocation(Irp);
 StackLocation->FileObject = FileObject;
 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
 Status = IoCallDriver(pCdpDetail[CdpId].CdpVolumeDeviceObject, Irp); //返回出错
if ( Status == STATUS_PENDING ) {
  KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
  Status = ioStatus.Status;
 }
 if ( STATUS_INVALID_PARAMETER == Status ) {
  DebugPrint(("<Routine>:DiskPerfPoffsetToLoffset (%d) <Error>: STATUS_INVALID_PARAMETER error.\n"), __LINE__);
  return Status;      
 }
 if ( !NT_SUCCESS(Status) ) {
  DebugPrint(("<Routine>:DiskPerfPoffsetToLoffset (%d) "
   "<Error>:Calls IoCallDriver to convert physical offset to logical offset error.\n"), __LINE__);
  CleanupCdpDetail(pCdpDetail);
  return Status;
 }
lzw06061139
驱动牛犊
驱动牛犊
  • 注册日期2011-09-26
  • 最后登录2014-02-19
  • 粉丝0
  • 关注2
  • 积分36分
  • 威望251点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2012-02-05 20:11
物理偏移转化为逻辑偏移时出现了错误
原因是:
      在过滤IRP_MJ_WRITE消息时,没有正常将该IRP分发懂RAID中对应的卷,导致上述的参数错误问题
eleqi
驱动小牛
驱动小牛
  • 注册日期2005-12-20
  • 最后登录2014-01-03
  • 粉丝4
  • 关注2
  • 积分172分
  • 威望1475点
  • 贡献值0点
  • 好评度115点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2012-03-09 16:01
学习,感谢分享!
游客

返回顶部