阅读:2922回复:6
关于在过滤驱动中直接访问物理磁盘失败的问题
在做一个过滤驱动的项目,碰到了这样的问题:
要再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错误。 在此寻求高人指点:) |
|
沙发#
发布于: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 |
|
板凳#
发布于:2007-07-05 10:27
学习
|
|
地板#
发布于:2007-07-05 13:15
谢谢回复:)
看来是这个问题。只能发IRP了。尝试中,不过好像在net start service时IoGetDeviceObjectPointer会返回0xC0000043, STATUS_SHARING_VIOLATION的错误。:( |
|
地下室#
发布于:2007-07-16 16:18
由于我的Filter需要尽早被调取,我在KD中看到当我的驱动起来时,根本没有\Device\Harddisk0 或者\??\PhysicalDrive0之类的名称注册,只有\Device\RawDisk。
我尝试用IoCreateFile打开正常,但无法用ZwReadFile访问。 请教我应该如何处理RawDisk的访问?欢迎一切建议和文档的推荐。 万分感谢!!! |
|
5楼#
发布于:2007-09-14 12:20
\??\下的symblinc是win32使用的名字 然后IO Mngr 转到对应的设备名
你这里的名字用错了 应该用\device\xxxxx 还有你的filter必须是在文件系统上的 这个时候怎么可能没有DISK呢? |
|
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?还是我的请求参数有问题? |
|
|