阅读:3530回复:7
关于缓存的问题,求救!!!
做文件保护,只有我的进程可以打开该文件,但我的进程里有个打开对话框。
第一次:我从打开对话框,右键打开该文件,会报拒绝。 当我的程序装入该文件(我的进程是应装入该文件的)后 我再打开打开对话框,右键打开该文件,就可以打开了。 这似乎是文件的一个缓存问题,大家是如何解决的?? |
|
最新喜欢:wingma... |
沙发#
发布于:2007-08-16 11:49
首先被IE打开
|
|
板凳#
发布于:2007-08-17 09:43
不明白,能不能详细解释一下呢??
|
|
地板#
发布于:2007-08-17 09:53
我是从sfilter上加工出来的代码,在SfPassThrough 中作了如下修改
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); cacheName = FALSE; //改为把所有的都过滤了 //这样会蓝屏,为何? if ((pIrp->MajorFunction==IRP_MJ_READ)||(pIrp->MajorFunction==IRP_MJ_WRITE)||(pIrp->MajorFunction==IRP_MJ_DIRECTORY_CONTROL)){ 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")); } } IoSkipCurrentIrpStackLocation( Irp ); return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->NLExtHeader.AttachedToDeviceObject, Irp ); |
|
地下室#
发布于:2007-08-17 22:02
Don't understand most of your logic. It seems you are trying to do some access controls on particular folder. Access control should be done in MJ_CREATE not in MJ_READ or MJ_WRITE. Search previous posts. There were tons of them discussing it.
|
|
5楼#
发布于:2007-08-20 09:59
谢谢michaelgz
我确是是做一个文件控制方面的,我在IRP_MJ_CREATE也做了对应的处理,但一样,先谢谢,我看看旧的贴,看能不能解决。 |
|
6楼#
发布于:2010-07-28 14:02
采用回调可以解决这个问题
|
|
7楼#
发布于:2010-07-28 14:34
当ReadFile时,会调用NtReadFile()系统调用,它会构造一个IRP下发到FSD,FSD会检查这个IRP看是不是可以缓存 的,是的话,如果还没有为此文件建立缓存的话,就会调用 CcInitializeCacheMap()函数建立缓存,它里面会调用内存管理器(VMM)函数建立一个节对象 。当用到时,会把这个节对象(和文件关联)映射到内核空间。如果IRP是可缓存 的,则调用CcCopyRead()函数进行从缓存中读入文件。
|
|