阅读:1792回复:18
如何禁止对一个文件的写入
参考的例子是sfilter,想实现上述功能请问用到哪些处理例程
|
|
沙发#
发布于:2005-05-10 10:13
请大虾们多多提点,要多少分我都可以给
|
|
板凳#
发布于:2005-05-10 12:28
create, cleanup, close, write, set_information
|
|
地板#
发布于:2005-05-10 13:02
你可否讲的详细一点呢,我跟踪了一下,如E:下有一个x.txt文件当我在x.txt中写一些字符时会触发create,write等处理例程,但具体不知该在这些例程中做何种设置,这个问题比较急,我先给10分,之后再给50分
|
|
地下室#
发布于:2005-05-10 13:25
主要处理好IRP_MJ_WRITE,fastiowrite
还有一个地方能写文件,但是一般很少用到,和文件系统没太大关系 |
|
5楼#
发布于:2005-05-10 13:29
我拦截IRP_MJ_WRITE的,但是只有在你要保存的时候显示不能保存。不知道你的要求是什么?难道用户一写就要弹出提示?
|
|
6楼#
发布于:2005-05-10 13:53
to zhjie374:
只要最终没有写进去就行,不管提示是先出现还是后出现,你是怎么做的 |
|
7楼#
发布于:2005-05-10 14:39
直接调用
IoCompleteRequest( Irp, IO_NO_INCREMENT ); 返回一个STATUS_SUCCESS,不往下CALLDRIVER 就行了,也不会弹出提示,上层系统认为写进去了,实际没有写进去 但是只处理IRP_MJ_WRITE是不够的 |
|
8楼#
发布于:2005-05-10 14:50
我觉的你说的有道理,但写有两种情况(1)写入一个新文件(2)在已存在的文件上写,我又如何来区分呢,现在不好给分了,过会儿一定散分,请继续关注
|
|
9楼#
发布于:2005-05-10 15:37
区分(1)写入一个新文件(2)在已存在的文件上写 基本上不准,只能在IRP_MJ_CREATE处判断,因为在IRP_MJ_WRITE处只能拿到一个fielobject,无法区分该FILEOBJECT是打开已知的还是创建的新的
首先判断create disposition values,然后call下层driver,判断Irp->IoStatus.Information,如果是FILE_OPENED或者FILE_OVERWRITTEN基本上认为是打开一个已有文件,其他的也能粗略的区分,不是很准 |
|
10楼#
发布于:2005-05-10 15:49
我直接拦截IRP_MJ_WRITE了。没有问题,保存的时候弹出提示。
写新文件是什么意思? 禁止新建文件不行吗? |
|
11楼#
发布于:2005-05-10 16:20
to zhjie374:
你在IRP_MJ_WRITE中处理是怎么做的,如何区分某个文件是已经存在的还是新建的呢 |
|
12楼#
发布于:2005-05-10 16:46
只处理IRP_MJ_WRITE是不行的,有兴趣的话可以用filemon看看link是怎么工作的,一个IRP_MJ_WRITE都没有,照样生成了文件
|
|
13楼#
发布于:2005-05-10 17:59
我按你的建议添加了一段代码,如下,帮我看看为什么不执行,
在IRP_MJ_CREATE处理例程中: ULONG disposion; disposion = (currentIrpStack->Parameters.Create.Options >> 24) & 0xFF; IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine( Irp, SfCreateCompletion1, &disposion, TRUE, TRUE, TRUE); return IoCallDriver(xxxx); 然后在完成例程SfCreateCompletion1中这样处理 { BOOLEAN is = FALSE; ULONG dis = Context; UNREFERENCED_PARAMETER( DeviceObject ); if(Irp->PendingReturned) IoMarkIrpPending(Irp); if(dis == FILE_OPENED || dis == FILE_OVERWRITE) { is = TRUE; } else is = FALSE; return STATUS_SUCCESS; } 我这样写是否有问题,在完成例程中的if-else语句根本没执行,你说的首先判断create disposition values,我不知判断什么 |
|
14楼#
发布于:2005-05-10 19:35
这样试试
{ KEVENT waitEvent; ULONG disposion; disposion = (currentIrpStack->Parameters.Create.Options >> 24) & 0xFF; IoCopyCurrentIrpStackLocationToNext(Irp); KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); IoSetCompletionRoutine( Irp, SfCreateCompletion1, &waitEvent, TRUE, TRUE, TRUE); ntStatus = IoCallDriver(xxxx); if (STATUS_PENDING == ntStatus) { ntStatus = KeWaitForSingleObject( &waitEvent, Executive, KernelMode, FALSE, NULL ); ASSERT(STATUS_SUCCESS == ntStatus); } dis = Irp->IoStatus.Information; if(dis == FILE_OPENED || dis == FILE_OVERWRITE) { is = TRUE; } else is = FALSE; ...... .... } SfCreateCompletion1(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { KeSetEvent( (PKEVENT)Context, IO_NO_INCREMENT, FALSE ); return STATUS_MORE_PROCESSING_REQUIRED; } 随手写的,自己修饰一下,逻辑上应该没问题 |
|
15楼#
发布于:2005-05-10 21:54
很多软件写文件的时候都是先写临时文件,然后再删除原文件,再把临时文件重命名成目标文件的,所以你还需要处理set information
|
|
16楼#
发布于:2005-05-11 12:05
那这样只要禁止删除就行了
我以前还发现一种情况,以FILE_OVERWRITE_IF 打开的话,即使没有写入,文件也会被清空 |
|
17楼#
发布于:2005-05-11 13:51
谢谢各位的帮助,我实现这个功能了,主要在IRP_MJ_SET_INFORMATION处理例程中处理,这里不好给分,我重新开贴,qiangguo64,zhjie374你们去领分吧
|
|
18楼#
发布于:2005-05-11 19:56
说一说具体怎么实现的呀.
|
|