zhangheyang
驱动牛犊
驱动牛犊
  • 注册日期2007-05-19
  • 最后登录2014-04-17
  • 粉丝0
  • 关注0
  • 积分140分
  • 威望30点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
阅读:1388回复:3

求救!系统运行一段时间后就会系统资源不足。。。。。

楼主#
更多 发布于:2007-09-03 16:50
在Sfilter的基础上改的,我的目标是对我指定的一个目录进行一些控制,让指定的进程可以读或写操作,
1、借用了FileMon中的得到进程名的代码;
2、把FastIO都返回FALSE
3、修改了SfPassThrough

但驱动加载一段时间后,系统就会资源不足。

NTSTATUS
SfPassThrough (
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    )
{
            NTSTATUS status;                 //张加的
    PNAME_CONTROL fileName = NULL;    //张加的
    NAME_LOOKUP_FLAGS LookupFlags = 0x00000000;   //张加的
    PSFILTER_DEVICE_EXTENSION devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);  //张加的
    BOOLEAN cacheName;  //张加的
    UNICODE_STRING filterPath;    //=UNICODE_STRING("2860f21a-6dd2-4dac-b901-afadd00b702b");  //过滤路径

    CHAR            name[PROCNAMELEN];    //得到当前的进程名      张加入
    int foundread,foundwrite;
    PIO_STACK_LOCATION pIrp = IoGetCurrentIrpStackLocation( Irp );

    RtlInitUnicodeString(&filterPath,L"2860f21a-6dd2-4dac-b901-afadd00b702b");                  //"2860F21A-6DD2-4DAC-B901-AFADD00b702B");
    PAGED_CODE();   //张加入


    //
    //  Sfilter doesn't allow handles to its control device object to be
    //  created, therefore, no other operation should be able to come through.
    //

    ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ));

    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));

    //
    //  File systems should NEVER receive a power IRP
    //

    ASSERT(pIrp->MajorFunction != IRP_MJ_POWER);
    // 我们仅关心卷过滤设备对象
    // We only care about volume filter device object
    //

    //if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO)))
    //{
    //    // 不是上面的这些操作,向下传
    //     KdPrint(("sfilter!访问Cache了\n"));
    //    IoSkipCurrentIrpStackLocation(Irp);
    //    return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
    //}
    //cacheName = FALSE;
    //改为把所有的都过滤了  //这样会蓝屏,为何?  ||(pIrp->MajorFunction==IRP_MJ_SHUTDOWN)
    //if ((pIrp->MajorFunction==IRP_MJ_READ)||(pIrp->MajorFunction==IRP_MJ_WRITE)||(pIrp->MajorFunction==IRP_MJ_DIRECTORY_CONTROL)
    //    ||(pIrp->MajorFunction==IRP_MJ_FLUSH_BUFFERS))
    if (!(pIrp->MajorFunction==IRP_MJ_SHUTDOWN)){

        //初始化LookupFlags
            if (FlagOn( SfDebug, SFDEBUG_GET_CREATE_NAMES |
                         SFDEBUG_DISPLAY_CREATE_NAMES ) &&
                  !FlagOn(devExt->Flags,SFDEVFL_DISABLE_VOLUME)) {

                  //
                  //  Debugging specifies that we need to get the filename
                  //

                  NAME_LOOKUP_FLAGS LookupFlags = 0x00000000;

                 //
                 //  If DosName has been set, indicate via flags that we
                 //  want to use it when getting the full file name.
                 //

                if (devExt->NLExtHeader.DosName.Length != 0) {

                      SetFlag( LookupFlags, NLFL_USE_DOS_DEVICE_NAME );
                 }

                //
                //  Indicate we are in pre-create
                //

                SetFlag( LookupFlags, NLFL_IN_CREATE );

                if (FlagOn( pIrp->Parameters.Create.Options, FILE_OPEN_BY_FILE_ID )) {

                      //
                      //  The file is being opened by ID, not file name.
                      //

                      SetFlag( LookupFlags, NLFL_OPEN_BY_ID );
                 }

                  if (FlagOn( pIrp->Flags, SL_OPEN_TARGET_DIRECTORY )) {

                      //
                      //  The file's parent directory should be opened
                      //

                       SetFlag( LookupFlags, NLFL_OPEN_TARGET_DIR );
                 }
            }
                foundread=0;
                foundwrite=0;
                //ProcessNameOffset = FilemonGetProcessNameOffset();   //得到进程的编移量  //移到驱动入口
               //得到进程名
                FilemonGetProcess(name);
                if(memcmp(SkipRead,name,strlen(SkipRead))==0)                       //对于我指定的进程可读,但不可写
                {
                
                   foundread=1;
                   if (pIrp->MajorFunction==IRP_MJ_WRITE){                          //禁止写磁盘
                               KdPrint(("sfilter!%s不能写磁盘\n",&name));
                           Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
                         Irp->IoStatus.Information = 0;
                         IoCompleteRequest(Irp, IO_NO_INCREMENT);
                        //return Irp->IoStatus.Status;  //IoCompleteRequest后不能再调用IRP
                        return STATUS_NOT_SUPPORTED;
                   }
                }else if(memcmp(SkipWrite,name,strlen(SkipWrite))==0){
                   foundwrite=1;
                }
            status = NLAllocateNameControl( &fileName, &gSfNameBufferLookasideList );
            if (NT_SUCCESS( status ))
            {
                    if (devExt->NLExtHeader.DosName.Length!=0) SetFlag(LookupFlags,NLFL_USE_DOS_DEVICE_NAME);
                         //得到完整路径
                        status = NLGetFullPathName( pIrp->FileObject, fileName,&devExt->NLExtHeader,LookupFlags,&gSfNameBufferLookasideList,&cacheName );
            }
            if (fileName != NULL)
            {

                    if (wcsstr((fileName->Name.Buffer),(filterPath.Buffer))!=NULL){   //包括我要写的磁盘

                        //除我指定的进程外全都Over掉。
                        if (!(foundread || foundwrite)){
                                    KdPrint(("sfilter!非我的进程%s,操作保护目录%wZ\n",name,&fileName->Name));
                                    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
                                    Irp->IoStatus.Information = 0;
                                    IoCompleteRequest(Irp, IO_NO_INCREMENT);
                                    NLFreeNameControl( fileName, &gSfNameBufferLookasideList );
                                    //return Irp->IoStatus.Status;  //IoCompleteRequest后不能再调用IRP
                                     return STATUS_NOT_SUPPORTED;
                        }
                        else{
                            if (foundwrite && pIrp->MajorFunction==IRP_MJ_READ){  //写的进程不能读
                                   KdPrint(("sfilter!写的进程%s不能读保护目录%wZ\n",name,&fileName->Name));
                                    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
                                    Irp->IoStatus.Information = 0;
                                    IoCompleteRequest(Irp, IO_NO_INCREMENT);
                                    NLFreeNameControl( fileName, &gSfNameBufferLookasideList );
                                     return STATUS_NOT_SUPPORTED;
                            }          
                        }  //处理受保护的目录
                       NLFreeNameControl( fileName, &gSfNameBufferLookasideList );
                 }
            }
            else{
               KdPrint(("sfilter!没取到文件名\n"));
            }  
    }  //改为把所有的都过滤了
    //
    //  Get this driver out of the driver stack and get to the next driver as
    //  quickly as possible.
    //

    IoSkipCurrentIrpStackLocation( Irp );

    //
    //  Call the appropriate file system driver with the request.
    //
    return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->NLExtHeader.AttachedToDeviceObject,
                          Irp );
}
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-09-03 18:26
至少我看到这段代码不是所有的路径都释放分配的内存。
zhangheyang
驱动牛犊
驱动牛犊
  • 注册日期2007-05-19
  • 最后登录2014-04-17
  • 粉丝0
  • 关注0
  • 积分140分
  • 威望30点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-09-04 10:07
惭愧。。。写代码规范不好,没对齐,谢谢。。
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
地板#
发布于:2007-09-04 20:52
养成使用__try{} __finally{}的好习惯
人总在矛盾中徘徊。。。
游客

返回顶部