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

windows 2000 动态磁盘 物理偏移转逻辑偏移失败

楼主#
更多 发布于:2012-04-13 10:21
问题描述如下:

    现有一磁盘过滤驱动:是处在卷和物理磁盘之间的一个上层过滤驱动, 公司是用这个驱动来做CDP的;
    现在的问题是,在其他的系统上都能正常的工作,但在windows 2000 系统,在执行动态磁盘(基本磁盘没有这个问题)的物理偏移到逻辑的偏移的转化过程中,出错(STATUS_INVALID_PARAMTER);
    物理偏移到逻辑偏移的转换接口如下:
NTSTATUS
DiskPerfConvertOffset(
                      IN PCDP_OBJECT pCdpObject,
                      IN PWRITE_DATA_LIST pDataList,
                      IN PFILE_OBJECT FileObject,
                      IN OUT PCHAR pContent
                      ) {
    PIRP        Irp;
    KEVENT        kEvent;
    NTSTATUS    NtStatus = STATUS_SUCCESS;

    VOLUME_PHYSICAL_OFFSET    PhyOffset;
    VOLUME_LOGICAL_OFFSET    LogiOffset;
    IO_STATUS_BLOCK            ioStatus;
    PIO_STACK_LOCATION        StackLocation ;

    UNREFERENCED_PARAMETER(pContent);
    if ( NULL == pCdpObject
        || NULL == pDataList )
        return STATUS_INVALID_PARAMETER;

    PhyOffset.DiskNumber = pDataList->DiskNum;
    PhyOffset.Offset = pCdpObject->pCdpDetail[0].pLogHead->WriteOffset;
  
    KeInitializeEvent(&kEvent, NotificationEvent, FALSE);

    //Allocates and sets up an IRP for a synchronously processed device control request
    Irp = IoBuildDeviceIoControlRequest(
                                        IOCTL_VOLUME_PHYSICAL_TO_LOGICAL,
                                        pCdpObject->pCdpDetail[pDataList->CdpId].CdpVolumeDeviceObject,
                                        &PhyOffset,
                                        sizeof(VOLUME_PHYSICAL_OFFSET),
                                        &LogiOffset,
                                        sizeof(VOLUME_LOGICAL_OFFSET),
                                        FALSE,                            //IPR_MJ_DEVICE_CONTROL
                                        &kEvent,
                                        &ioStatus                        //when the request is completed by the lower-driver, this parameter will be set
                                        );                        
    if ( NULL == Irp ) {

        KdPrint(("<Routine>:DiskPerfPoffsetToLoffset "
            "<Error>:Calls IoBuildDeviceIoControlRequest failed, NtStatus %X.\n", ioStatus.Status));
        return ioStatus.Status;
    }

    NtStatus = ObReferenceObjectByHandle(
                                        pCdpObject->pCdpDetail[pDataList->CdpId].CdpVolumeHandle,
                                        THREAD_ALL_ACCESS,
                                        *IoFileObjectType,
                                        KernelMode,
                                        (PVOID*)&FileObject,
                                        NULL
                                        );
    if ( !NT_SUCCESS(NtStatus) ) {

        KdPrint(("<Routine>:DiskPerfPoffsetToLoffset "
            "<Error>: calls ObReferenceObjectByhandle failed, NtStatus %X.\n", NtStatus));
        return NtStatus;
    }

    ObDereferenceObject(FileObject);
    StackLocation = IoGetNextIrpStackLocation(Irp);
    StackLocation->FileObject = FileObject;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();

    NtStatus = IoCallDriver(pCdpObject->pCdpDetail[pDataList->CdpId].CdpVolumeDeviceObject, Irp);  // 返回STATUS_INVALID_PARAMETER    if ( STATUS_PENDING == NtStatus ) {

        KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
        NtStatus = ioStatus.Status;
    }

    if ( !NT_SUCCESS(NtStatus) ) {

        KdPrint(("<Routine>:DiskPerfPoffsetToLoffset "
            "<Error>:Calls IoCallDriver to convert physical offset to logical offset error, NtStatus %X.\n", NtStatus));
        return NtStatus;
    }

    pCdpObject->pCdpDetail[0].pLogHead->WriteOffset = LogiOffset.LogicalOffset;
    return NtStatus;
}

       上述问题,已尝试在google,百度找答案,都无功而返;希望得到各位的帮助;谢谢!
游客

返回顶部