阅读:1388回复:3
求救!系统运行一段时间后就会系统资源不足。。。。。
在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 ); } |
|
沙发#
发布于:2007-09-03 18:26
至少我看到这段代码不是所有的路径都释放分配的内存。
|
|
板凳#
发布于:2007-09-04 10:07
惭愧。。。写代码规范不好,没对齐,谢谢。。
|
|
地板#
发布于:2007-09-04 20:52
养成使用__try{} __finally{}的好习惯
|
|
|