阅读:1547回复:1
如何取得非PAGING IO的 WRITE数据?(追补) LU0,Coolice,vcmfc,Tom_lyd ,tooflat 请看
LU0
Coolice vcmfc Tom_lyd tooflat 昨日看了 本版精华贴 (置顶) 中LU0和Coolice的一片争论, http://www.driverdevelop.com/forum/viewthread.php?tid=31975 看来绝对有人已经进行了更加深入地研究。 不知是否有时间帮忙给小弟回答一下问题? 我测试的用的是FAT32。WIN2K SP4 Pro -------以下是我请教问题的原文。 各位老兄,请教一个问题。刚才给别人的帖子中提到的。 在IRP_MJ_WRITE的处理中, 对于 IRP_MN_MDL的情况和 IRP_MN_MDL_COMPLETE的两种情况 有下面的怪现象 对于 IRP_MN_MDL_COMPLETE ASSERT( MmGetMdlByteCount(Irp->MdlAddress) >= irpSp->Parameters.Write.Length); DbgPrint("MmGetMdlByteCount =0x%08x,Write.Length=0x%08x,MinorFunction =%xn", MmGetMdlByteCount(Irp->MdlAddress), irpSp->Parameters.Write.Length, irpSp->MinorFunction); pBuffer = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,NormalPagePriority ); 。。。。。。。 IoSkipCurrentIrpStackLocation( Irp ); Context->ntStatus = IoCallDriver( ((PEZIOMONITOR_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); 对于 IRP_MN_MDL .....在IoCallDriver之前,Irp->MdlAddress是NULL。这个正确。 IoSkipCurrentIrpStackLocation( Irp ); Context->ntStatus = IoCallDriver( ((PEZIOMONITOR_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); ..... ASSERT( MmGetMdlByteCount(Irp->MdlAddress) >= irpSp->Parameters.Write.Length); DbgPrint("MmGetMdlByteCount =0x%08x,Write.Length=0x%08x,MinorFunction =%xn", MmGetMdlByteCount(Irp->MdlAddress), irpSp->Parameters.Write.Length, irpSp->MinorFunction); pBuffer = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,NormalPagePriority ); 。。。。。。。 问题出在 ASSERT( MmGetMdlByteCount(Irp->MdlAddress) >= irpSp->Parameters.Write.Length); 也就是说系统下层FSDAlloc的Mdl大小比要写得内容少。 而且下层FSD和 CIFS竟然能够正常处理,没有问题!!! 对于IRP_MN_NORMAL没有这些问题。 说怪其实也不怪。MS¥的文档里有说。 Kernel mode callers of the read and write interface (IRP_MJ_READ and IRP_MJ_WRITE) can utilize an interface that allows retrieval of a pointer to the data as it is located in the file system data cache. This allows the kernel mode caller to retrieve the data for the file without an additional data copy. For example, the AFD file system driver has an API function it exports that takes a socket handle and a file handle. The file contents are “copied” directly to the corresponding communications socket. The AFD driver accomplishes this task by sending an IRP_MJ_READ with the IRP_MN_MDL minor operation. The FSD then retrieves an MDL describing the cached data (at Irp->MdlAddress) and completes the request. When AFD has completed processing the operation it must return the MDL to the FSD by sending an IRP_MJ_READ with the IRP_MN_MDL_COMPLETE minor operation specified. For a file system filter driver, the write operation may be a bit more confusing. When a caller specifies IRP_MJ_WRITE/IRP_MN_MDL the returned MDL may point to uninitialized data regions within the cache. That is because the cache manager will refrain from reading the current data in from disk (unless necessary) in anticipation of the caller replacing the data. When the caller has updated the data, it releases the buffer by calling IRP_MJ_WRITE/IRP_MN_MDL_COMPLETE. At that point the data has been written back to the cache. An FSD that is integrated with the cache manager can implement these minor functions by calling CcMdlRead and CcPrepareMdlWrite. The corresponding functions for NTFSD Frequently Asked Questions Content provided by 24 OSR Open Systems Resources, Inc. completing these are CcMdlReadComplete and CcMdlWriteComplete. An FSD that is not integrated with the cache manager can either indicate these operations are not supported (in which case the caller must send a buffer and support the “standard” read/write mechanism) or it can implement them in some other manner that is appropriate. 由于所有监视到的PAGINGIO都是IRP_MN_NORMAL,所以,我可以通过MDLAddress取到数据。 我的问题是,如果我不想用PAGING IO.我应该如何取到数据呢? (我做的是同步处理。) 上面的情况主要在CIFS上发生,也就是 文件共享的时候出现!! 你们当初是如何做的呢? [编辑 - 8/8/04 by zdhe] |
|
沙发#
发布于:2004-08-08 18:25
自己顶一下。 :D
|
|