gongxp123456
驱动牛犊
驱动牛犊
  • 注册日期2004-12-15
  • 最后登录2013-10-10
  • 粉丝0
  • 关注0
  • 积分617分
  • 威望383点
  • 贡献值1点
  • 好评度59点
  • 原创分0分
  • 专家分0分
阅读:13426回复:7

微过滤器中对文件路径进行更改代码问题求助

楼主#
更多 发布于:2008-02-23 15:32
在微过滤器中对文件路径进行更改,就是要在后操作回调中更改重解析数据缓冲。具体来说,IRP_MJ_CREATE的后操作过程中,如果一个碰到重解析点,Data->TagData会指想一个重解析数据缓冲。如果微过滤器打算修改这个缓冲,它可以释放了这个缓冲然后重新分配一个(不能为空)。

请教的问题是:如何释放了这个缓冲然后重新分配一个?

我胡乱地这样来更改,但是失败:
FLT_POSTOP_CALLBACK_STATUS
PtPostOperationCreate (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in_opt PVOID CompletionContext,
    __in FLT_POST_OPERATION_FLAGS Flags
)
{
……
FLT_TAG_DATA_BUFFER tagBuffer //定义重解析数据结构
//填充重解析点数据数据结构:
cbPrintName = objname.Length;
pTagBufTail = (PBYTE)(tagBuffer.SymbolicLinkReparseBuffer.PathBuffer);
tagBuffer.FileTag = IO_REPARSE_TAG_SYMLINK;
tagBuffer.UnparsedNameLength = FileObject->FileName.Length;
tagBuffer.TagDataLength = (USHORT)(cbReparseData - REPARSE_DATA_BUFFER_HEADER_SIZE);
tagBuffer.SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
tagBuffer.SymbolicLinkReparseBuffer.SubstituteNameLength = objname.Length;
pTagBufTail += pRepoint->SymbolicLinkReparseBuffer.SubstituteNameOffset;
RtlCopyMemory(pTagBufTail, objname.Buffer, objname.Length);
tagBuffer.SymbolicLinkReparseBuffer.PrintNameLength = (USHORT)cbPrintName;
tagBuffer.SymbolicLinkReparseBuffer.PrintNameOffset = pRepoint->SymbolicLinkReparseBuffer.SubstituteNameLength;
pTagBufTail += tagBuffer.SymbolicLinkReparseBuffer.PrintNameOffset;
RtlCopyMemory(pTagBufTail, objname.Buffer, cbPrintName);
tagBuffer.SymbolicLinkReparseBuffer.Flags = 0;

//下面代码肯定有问题        
ExFreePool(Data->TagData);//希望释放原来结构
Data->TagData = (PFLT_TAG_DATA_BUFFER)ExAllocatePool(NonPagedPool,sizeof(tagBuffer));//分配内存
Data->TagData = &tagBuffer;//指向上述填充的内存

……


上述回调数据结构结构定义
typedef struct _FLT_CALLBACK_DATA {
  FLT_CALLBACK_DATA_FLAGS  Flags;
  PETHREAD CONST  Thread;
  PFLT_IO_PARAMETER_BLOCK CONST  Iopb;
  IO_STATUS_BLOCK  IoStatus;
  struct _FLT_TAG_DATA_BUFFER  *TagData;
  union {
    struct {
      LIST_ENTRY  QueueLinks;
      PVOID  QueueContext[2];
    };
    PVOID  FilterContext[4];
  };
  KPROCESSOR_MODE  RequestorMode;
} FLT_CALLBACK_DATA, *PFLT_CALLBACK_DATA;

重解析数据结构定义
typedef struct _FLT_TAG_DATA_BUFFER {
  ULONG  FileTag;
  USHORT  TagDataLength;
  USHORT  UnparsedNameLength;
  union {
    struct {
        USHORT  SubstituteNameOffset;
        USHORT  SubstituteNameLength;
        USHORT  PrintNameOffset;
        USHORT  PrintNameLength;
        ULONG  Flags;
        WCHAR  PathBuffer[1];
    } SymbolicLinkReparseBuffer;
    struct {
        USHORT  SubstituteNameOffset;
        USHORT  SubstituteNameLength;
        USHORT  PrintNameOffset;
        USHORT  PrintNameLength;
        WCHAR  PathBuffer[1];
    } MountPointReparseBuffer;
    struct {
        UCHAR  DataBuffer[1];
    } GenericReparseBuffer;
    struct {
        GUID  TagGuid;
        UCHAR  DataBuffer[1];
    } GenericGUIDReparseBuffer;
  };
} FLT_TAG_DATA_BUFFER, *PFLT_TAG_DATA_BUFFER;
#define FLT_TAG_DATA_BUFFER_HEADER_SIZE   FIELD_OFFSET(FLT_TAG_DATA_BUFFER, GenericReparseBuffer)

gongxp123456
驱动牛犊
驱动牛犊
  • 注册日期2004-12-15
  • 最后登录2013-10-10
  • 粉丝0
  • 关注0
  • 积分617分
  • 威望383点
  • 贡献值1点
  • 好评度59点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-02-23 15:42
在老的过滤驱动中是这么改的:
SfCreate (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION IrpSp;
PUNICODE_STRING FileName;
PVOID FileNameBuffer;
UNICODE_STRING NewFileName;
BOOLEAN bRedirectFileOpen = FALSE;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
FileName = &(IrpSp->FileObject->FileName);
//分配内存
FileNameBuffer = ExAllocatePool( NonPagedPool,NewFileName.MaximumLength );
//释放老文件名缓冲区
ExFreePool( FileName->Buffer );
FileName->Buffer = FileNameBuffer;
FileName->MaximumLength = NewFileName.MaximumLength;
//将希望更改的新文件名代替原来的文件
RtlCopyUnicodeString( FileName, &NewFileName );
Irp->IoStatus.Status = STATUS_REPARSE;
Irp->IoStatus.Information = IO_REPARSE;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_REPARSE;
}
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-02-23 22:23
老的代码是在PreCreate中处理的,你的minifilter处理的地方不对。
gongxp123456
驱动牛犊
驱动牛犊
  • 注册日期2004-12-15
  • 最后登录2013-10-10
  • 粉丝0
  • 关注0
  • 积分617分
  • 威望383点
  • 贡献值1点
  • 好评度59点
  • 原创分0分
  • 专家分0分
地板#
发布于:2008-02-24 12:05
多谢tooflat回应!老的代码是在PreCreate中处理的,在新的minifilter处理的就是在后操作回调中,对于目录的重定向,我已经实现,我的问题是代码如何实现释放Data->TagData指向一个重解析数据缓冲并重新分配。原因是本人C语言结构和指针操作还不够精通。

这是微软的文档:during the post-operation processing of IRP_MJ_CREATE operations. When a reparse point is encountered, the Data->TagData will point to the reparse data buffer.  If a minifilter wishes to change this buffer in any way, it can free the existing buffer and replace Data->TagData with a new buffer (or NULL) without calling FLT_SET_CALLBACK_DATA_DIRTY().
gongxp123456
驱动牛犊
驱动牛犊
  • 注册日期2004-12-15
  • 最后登录2013-10-10
  • 粉丝0
  • 关注0
  • 积分617分
  • 威望383点
  • 贡献值1点
  • 好评度59点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-02-24 16:11
啃了一大通《C语言设计教程》,按照理解上述代码大致应是这样子:
...
PFLT_TAG_DATA_BUFFER pTagBuffer;
...
//将定义的缓冲指针指向后操作回调的解析数据缓冲区
pTagBuffer = Data->TagData
//清空缓存区
if(NULL != pTagBuffer)ExFreePool(pTagBuffer);
//重新分配内存!
pTagBuffer = (PFLT_TAG_DATA_BUFFER)ExAllocatePool(NonPagedPool,cbReparseData);
//填充数据结构
......
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-02-25 09:15
引用第3楼gongxp123456于2008-02-24 12:05发表的  :
多谢tooflat回应!老的代码是在PreCreate中处理的,在新的minifilter处理的就是在后操作回调中,对于目录的重定向,我已经实现,我的问题是代码如何实现释放Data->TagData指向一个重解析数据缓冲并重新分配。原因是本人C语言结构和指针操作还不够精通。

这是微软的文档:during the post-operation processing of IRP_MJ_CREATE operations. When a reparse point is encountered, the Data->TagData will point to the reparse data buffer.  If a minifilter wishes to change this buffer in any way, it can free the existing buffer and replace Data->TagData with a new buffer (or NULL) without calling FLT_SET_CALLBACK_DATA_DIRTY().


我不知道你要实现什么功能,不过微软的文档的意思是,在Post operation中遇到返回值是reparse的时候(即你的驱动下层的驱动返回了reparse),此时如果你需要修改reparse data,那你可以直接replace TagData,如果是你自己要直接返回reparse,那就在precreate中处理
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
6楼#
发布于:2008-02-26 12:15
直接修改FILEOBJECT 吧,好象那个也还是可以修改的.
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
gongxp123456
驱动牛犊
驱动牛犊
  • 注册日期2004-12-15
  • 最后登录2013-10-10
  • 粉丝0
  • 关注0
  • 积分617分
  • 威望383点
  • 贡献值1点
  • 好评度59点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2008-02-26 22:15
两位大侠说的都对,Sfilter和minifilter在处理路径重解析方面具有较大的差别。
直接修改FILEOBJECT 的办法在Sfilter中只要改文件名,设置返回状态重解析即可,但minifilter改文件名的办法只对在一个卷的文件有效,跨卷的话,好像系统不会重新解析,大概是自己要处理设备对象或者VBP,有点像原来的VXD处理方式。
游客

返回顶部