阅读:2703回复:12
怎样确定读写文件的长度?
在文件系统过滤驱动中,如何确定读写文件的长度?
在sfilter中添加SfRead和SfWrite例程, 打印PIO_STACK_LOCATION IrpSp; Length = IrpSp->Parameters.Write.Length;信息时,发现却是4096。 不知道IrpSp中哪个参数可以表示文件的读写长度? |
|
最新喜欢:linshi... |
沙发#
发布于:2007-03-02 17:36
有人说可以利用FCB(文件控制块)进行实现,但不清楚是怎么做的.
有知道的可以给指点一下吗? |
|
板凳#
发布于:2007-03-02 18:01
Irp->IoStatus.Information ??
Irp->FileObject->CurrentByteOffset ?? |
|
地板#
发布于:2007-03-04 04:07
A filter just needs to pay attention to the ByteOffset field in the
stack location (pIrpSp->Parameters.Read.ByteOffset or pIrpSp->Parameters.Write.ByteOffset), EXCEPT when HighPart is -1 and LowPart is one of the two constants FILE_WRITE_TO_END_OF_FILE or FILE_USE_FILE_POINTER_POSITION. In the case of FILE_WRITE_TO_END_OF_FILE, then you need to interpret the write as happening at the current EOF (whatever this means in the context of your filter). In the case of FILE_USE_FILE_POINTER_POSITION, you pull the intended offset from the file object. So a filter should never have to handle FILE_USE_FILE_POINTER_POSITION? I thought this MIGHT be the case because FastFat does not check for this flag. However, the flag is listed right next to FILE_WRITE_TO_END_OF_FILE in ntifs.h, which FastFat DOES check for. I decided to play it safe and handle both. - Nicholas Ryan That flag is never seen in the driver stack. You pass that into NtRead/WriteFile (with HighPart == -1 as well) when you want IO to use the file object cbo as the IO offset. It is equivalent to passing in a NULL ByteOffset pointer to those APIs. NT4 FASTFAT uses FILE_WRITE_TO_END_OF_FILE but does not use FILE_USE_FILE_POINTER_POSITION. Is there a change that these will appear if IRP_NOCACHE bit is set? Nicholas Ryan wrote: Yes, FILE_WRITE_TO_END_OF_FILE is compatible with IRP_NOCACHE (but not IRP_PAGING_IO). - Nicholas Ryan |
|
地下室#
发布于:2007-03-04 04:12
EXCEPT when HighPart is -1 and
LowPart is one of the two constants FILE_WRITE_TO_END_OF_FILE or FILE_USE_FILE_POINTER_POSITION. 关键是这句话,如果HighPart为-1时候,LowPart 为FILE_WRITE_TO_END_OF_FILE或者FILE_USE_FILE_POINTER_POSITION时候,表示为实际的长度 |
|
5楼#
发布于:2007-03-04 04:40
We are writing a filter driver and are having problems ( like many before by
the looks of it ;) ) We are trying to read from file in a completion routine when we receive IRP_MJ_CREATE requests, so that we can identify files we need to decrypt. (we have a header on our files) In the completion routine for the create we queue a work item to try and do the read from and return STATUS_MORE_PROCESSING_REQUIRED. In the worker function we use IoBuildSynchronousFsdRequest to create an IRP for the read and send it on. This all works fine in almost every circumstance... except when filtering LanmanRedirector. Sometimes the read fails with STATUS_ACCESS_DENIED (0xC0000022). Help... does anyone have any ideas? Possibly something to do with security? We have tried SeCreateClientSecurity & SeImpersonateClient to no avail. We have pasted the offending chunk of code below. Thanks for any assitance.. Rob Linegar & Duncan Hume Software Engineers Data Encryption Systems Limited // Running in the context of a worker thread - using ExInitializeWorkItem & ExQueueWorkItem void FSFil_FileCreateWorker( PFILE_CREATE_CONTEXT pContext ) { PDEVICE_OBJECT pTargetDeviceObject; char *pBuffer; IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER ByteOffset; LARGE_INTEGER OrigByteOffset; PFILE_OBJECT pFileObject; pFileObject = IoGetCurrentIrpStackLocation( pContext->pOriginalIrp )->FileObject; // Get the Previous filtered device object pTargetDeviceObject = ((PFSFIL_DEVICEEXTENSION)pContext->pDeviceObject->DeviceExtension)->pPrevDev iceObject; // No point in continuing if there is no FileObject if (pFileObject) { // Allocate memory for our Buffer pBuffer = ExAllocatePool( NonPagedPool, 10 ); if (pBuffer) { ByteOffset.QuadPart = 0; // Store the original byte offset OrigByteOffset = pFileObject->CurrentByteOffset; FO_ReadFile( pContext->pOriginalIrp, pTargetDeviceObject, pFileObject, &ByteOffset, 5, pBuffer, &IoStatusBlock ); // Restore the original byte offset pFileObject->CurrentByteOffset = OrigByteOffset; if (NT_SUCCESS(IoStatusBlock.Status)) { } else { ///FAILS } // Free our read buffer ExFreePool( pBuffer ); } } // Complete the Create Request IoCompleteRequest( pContext->pOriginalIrp, IO_NO_INCREMENT ); // Free the create context data ExFreePool( pContext ); } VOID FO_ReadFile( PIRP pIrp, PDEVICE_OBJECT pDeviceObject, PFILE_OBJECT pFileObject, PLARGE_INTEGER Offset, ULONG Length, char * pBuffer, PIO_STATUS_BLOCK IoStatusBlock ) { KEVENT kEvent; PIRP pReadIrp; NTSTATUS ntStatus; // Initialise an event to wait for after calling the previous driver KeInitializeEvent( &kEvent, NotificationEvent, FALSE ); // Build an Irp for the read pReadIrp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, pDeviceObject, pBuffer, Length, Offset, &kEvent, IoStatusBlock ); if (pReadIrp) { PIO_STACK_LOCATION pReadStack = IoGetNextIrpStackLocation( pReadIrp ); // Caching? no thank you maam! pReadIrp->Flags = IRP_NOCACHE | IRP_READ_OPERATION; pReadIrp->Tail.Overlay.Thread = pIrp->Tail.Overlay.Thread; pReadIrp->RequestorMode = KernelMode; // We need a FileObject to identify the file we are reading pReadStack->FileObject = pFileObject; pReadStack->DeviceObject = pDeviceObject; // Call on to the previous driver ntStatus = IoCallDriver( pDeviceObject, pReadIrp ); if (ntStatus == STATUS_PENDING) { // Wait for the Irp to complete if it is pending KeWaitForSingleObject( &kEvent, Executive, KernelMode, FALSE, NULL ); } else IoStatusBlock->Status = ntStatus; } else { IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES; IoStatusBlock->Information = 0; } } |
|
6楼#
发布于:2007-03-05 08:03
多谢lsxredrain,
我先看一下. |
|
7楼#
发布于:2007-03-06 12:52
好象还是不行呀,l只是在读写完成例程中可以看到读写后的信息,
但如果在读写例程中改变了文件长度,处理后得到还是原来文件长度的内容; sxredrain,能否告知这些相关的资料可以在那个网站上找到? 多谢。 |
|
8楼#
发布于:2007-03-06 13:13
|
|
9楼#
发布于:2007-03-06 13:20
是的,我在调试时也是同样的结果;
只是在进行写操作时可以看到。 如果处理后的长度比原来的大,就需要重新考虑了。 我记得在以前的帖子中,有人给出重新分配一块内存,拷贝原来的Irp进行处理,但不知道最后的结果怎样。 |
|
10楼#
发布于:2007-03-06 13:36
我是用压缩法,不需要改变文件长度,写时把需要解压的长度和位置记下来,读时检查文件头就行了.其实对于磁盘上的文件,只有写时才有文件长度改变的
在osr上面搜索一下相关的资料看看,这几天在准备考博,没有太多时间去钻研这了,有好消息通报通报 |
|
11楼#
发布于:2007-03-08 17:27
我在tooflat所给的代码上进行处理的.
由于使用了分组算法导致文件长度增加,在读时无法正确解密. 比如我要输入40字节的明文,经驱动加密处理后会产生48字节密文, 但在实际写入文件时它只写入了密文的前面40字节. 现在的问题是:如何在实际写入时,写入48字节的密文; 在读时利用48字节的密文将明文还原出来. 关键是怎样写入这48字节的明文. 这其中就牵涉到文件的变长处理问题. 各位大牛们可否给些参考呢? |
|
12楼#
发布于:2007-05-09 19:43
我也遇到了同样的问题,也没有解决
|
|
|