puffel
驱动牛犊
驱动牛犊
  • 注册日期2005-03-14
  • 最后登录2014-09-17
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望50点
  • 贡献值0点
  • 好评度18点
  • 原创分1分
  • 专家分0分
阅读:2922回复:6

关于在过滤驱动中直接访问物理磁盘失败的问题

楼主#
更多 发布于:2007-07-04 12:50
在做一个过滤驱动的项目,碰到了这样的问题:

要再DriverEntry访问MBR中的数据,判断驱动是否启用。访问MBR的函数代码如下:

NTSTATUS
GetMBRFilterInfo (
    OUT PULONG FilterEnabled
    )
{
    struct _MBR_Block     MBR;
    OBJECT_ATTRIBUTES     ObjAttr;
    UNICODE_STRING         ustrDevName;
    HANDLE                 FileHandle;
    IO_STATUS_BLOCK    IOStatusBlk;
    LARGE_INTEGER        ilBytesOffset;
    LARGE_INTEGER         AllocSize ;

    NTSTATUS             Status = STATUS_SUCCESS;

    ilBytesOffset.LowPart = ilBytesOffset.HighPart = 0;
        
    RtlZeroMemory(&MBR, sizeof (struct _MBR_Block));
    RtlZeroMemory(&IOStatusBlk, sizeof(IO_STATUS_BLOCK));

    RtlInitUnicodeString (&ustrDevName, L"\\??\\PhysicalDrive0");//L"\\Device\\Harddisk0");//
    InitializeObjectAttributes (&ObjAttr, &ustrDevName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE , NULL, NULL);

    Status = IoCreateFile (&FileHandle, GENERIC_READ, &ObjAttr, &IOStatusBlk, NULL, FILE_ATTRIBUTE_NORMAL,
                          FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
                          FILE_NON_DIRECTORY_FILE,// |FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING);


    DbgPrint(("WF!GetMBRFilterInfo: IoCreateFile result \"%wZ\", Status=%08x\n", &ustrDevName, Status));

    Status = ZwReadFile(FileHandle, NULL, NULL, NULL, &IOStatusBlk, &MBR, 512, &ilBytesOffset, NULL );
    DbgPrint(("WFGetMBRFilterInfo: ZwReadFile result. Size=%08x, Status=%08x\n", sizeof(MBR) ,Status));

    ZwClose (&FileHandle);

    RtlCopyMemory(FilterEnabled, MBR.ulEnableFlag, sizeof(FilterEnabled));

    DbgPrint(("WF!GetMBRFilterInfo: record get: Status = %08x, FilterEnabled = %08x", Status, *FilterEnabled);

    if (MBR.ucSystemID != 0x45)  Status = STATUS_UNSUCCESSFUL;

    return Status;
}

如果以SERVICE_BOOT_START启动该驱动,将无法正常读取到磁盘,IoCreateFile 就会返回 0xC0000034,STATUS_OBJECT_NAME_NOT_FOUND错误。

在此寻求高人指点:)
aizhonghua
驱动牛犊
驱动牛犊
  • 注册日期2005-01-22
  • 最后登录2012-06-08
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-07-05 08:41
失败原因:在系统刚启动过程中(SERVICE_BOOT_START),调用用标准的内核例程和引用还未建立的内核对象,可能会导致错误

建议:可以是试一试如下方法
    RtlInitUnicodeString(&TargetDisk,L"\\Device\\Harddisk0\\DR0");
    IoGetDeviceObjectPointer(
                                                                 &TargetDisk,
                                                                 FILE_READ_DATA,
                                                                &Ext->TargetFileObj,
                                                                &Ext->TargetDevObj);
    DiskBuf = ExAllocatePoolWithTag(NonPagedPool,SECTOR_SIZE * n,(ULONG)'fTdK');
    KeInitializeEvent(&Event,NotificationEvent,FALSE);
    Irp = IoBuildSynchronousFsdRequest(                            IRP_MJ_READ,
            Ext->TargetDevObj,
            DiskBuf,
            SECTOR_SIZE *  n,
            (PLARGE_INTEGER) &Offset,
            &Event,
            &IoStatusBlk
            );
    Status = IoCallDriver(Ext->TargetDevObj,Irp);
    if(Status == STATUS_PENDING ){
        KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
    }

注:本人功底有限,以上只是一点建议,\\Device\\Harddisk0\\DR0 代表第一块硬盘

aizhonghua
strpic
驱动小牛
驱动小牛
  • 注册日期2006-11-01
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望238点
  • 贡献值0点
  • 好评度156点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-07-05 10:27
学习
puffel
驱动牛犊
驱动牛犊
  • 注册日期2005-03-14
  • 最后登录2014-09-17
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望50点
  • 贡献值0点
  • 好评度18点
  • 原创分1分
  • 专家分0分
地板#
发布于:2007-07-05 13:15
谢谢回复:)

看来是这个问题。只能发IRP了。尝试中,不过好像在net start service时IoGetDeviceObjectPointer会返回0xC0000043, STATUS_SHARING_VIOLATION的错误。:(
puffel
驱动牛犊
驱动牛犊
  • 注册日期2005-03-14
  • 最后登录2014-09-17
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望50点
  • 贡献值0点
  • 好评度18点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2007-07-16 16:18
由于我的Filter需要尽早被调取,我在KD中看到当我的驱动起来时,根本没有\Device\Harddisk0 或者\??\PhysicalDrive0之类的名称注册,只有\Device\RawDisk。

我尝试用IoCreateFile打开正常,但无法用ZwReadFile访问。

请教我应该如何处理RawDisk的访问?欢迎一切建议和文档的推荐。

万分感谢!!!
daviswu
驱动牛犊
驱动牛犊
  • 注册日期2007-03-07
  • 最后登录2009-01-16
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望40点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-09-14 12:20
\??\下的symblinc是win32使用的名字 然后IO Mngr 转到对应的设备名
你这里的名字用错了 应该用\device\xxxxx
还有你的filter必须是在文件系统上的 这个时候怎么可能没有DISK呢?
puffel
驱动牛犊
驱动牛犊
  • 注册日期2005-03-14
  • 最后登录2014-09-17
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望50点
  • 贡献值0点
  • 好评度18点
  • 原创分1分
  • 专家分0分
6楼#
发布于:2007-10-24 16:11
前段时间忙别的项目去了。问题还是没有解决,请求高人指点:)

附一段KD的输出。可以看到,在我的驱动被启动时,还没有加载\\Device\\Harddisk0\\,而只有RawDisk。

从文档上看到的关于RAW文件系统对象的解释如下:
A system-supplied FSD that is the "last resort" for all I/O requests requiring file system support. When the I/O Manager calls active file systems to mount a volume, RAW is always called last because it supports all disk and tape media.
However, RAW supplies very primitive file handling capabilities. That is, it does not impose any on-disk file structure or metadata structures for the information on the media; it simply allows read/write access to the logical blocks on the physical disk. For example, it treats the whole disk as a single file and supplies physical-disk-level VBN access to the disk.

RAW is not an acronym.

也就是说,设备对象还是应该支持读、写的。我也能够拿到设备对象的指针,可就是IRP_MJ_READ请求时会报STATUS_INVALID_DEVICE_REQUEST (0xC0000010L)。究竟是RawDisk不支持IRP_MJ_READ?还是我的请求参数有问题?
附件名称/大小 下载次数 最后更新
dbgout.txt (9KB)  17 2007-10-24 16:11
游客

返回顶部