xuAmigo
驱动小牛
驱动小牛
  • 注册日期2004-11-11
  • 最后登录2006-01-12
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1791回复:18

如何禁止对一个文件的写入

楼主#
更多 发布于:2005-05-09 17:36
参考的例子是sfilter,想实现上述功能请问用到哪些处理例程
xuAmigo
驱动小牛
驱动小牛
  • 注册日期2004-11-11
  • 最后登录2006-01-12
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-05-10 10:13
请大虾们多多提点,要多少分我都可以给
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-05-10 12:28
create, cleanup, close, write, set_information
xuAmigo
驱动小牛
驱动小牛
  • 注册日期2004-11-11
  • 最后登录2006-01-12
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-05-10 13:02
你可否讲的详细一点呢,我跟踪了一下,如E:下有一个x.txt文件当我在x.txt中写一些字符时会触发create,write等处理例程,但具体不知该在这些例程中做何种设置,这个问题比较急,我先给10分,之后再给50分
qiangguo64
驱动牛犊
驱动牛犊
  • 注册日期2005-01-12
  • 最后登录2009-08-28
  • 粉丝0
  • 关注0
  • 积分144分
  • 威望15点
  • 贡献值1点
  • 好评度14点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-05-10 13:25
主要处理好IRP_MJ_WRITE,fastiowrite
还有一个地方能写文件,但是一般很少用到,和文件系统没太大关系
zhjie374
驱动小牛
驱动小牛
  • 注册日期2004-10-27
  • 最后登录2012-01-17
  • 粉丝2
  • 关注1
  • 积分17分
  • 威望144点
  • 贡献值1点
  • 好评度21点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-05-10 13:29
我拦截IRP_MJ_WRITE的,但是只有在你要保存的时候显示不能保存。不知道你的要求是什么?难道用户一写就要弹出提示?
xuAmigo
驱动小牛
驱动小牛
  • 注册日期2004-11-11
  • 最后登录2006-01-12
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-05-10 13:53
to zhjie374:
只要最终没有写进去就行,不管提示是先出现还是后出现,你是怎么做的
qiangguo64
驱动牛犊
驱动牛犊
  • 注册日期2005-01-12
  • 最后登录2009-08-28
  • 粉丝0
  • 关注0
  • 积分144分
  • 威望15点
  • 贡献值1点
  • 好评度14点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2005-05-10 14:39
直接调用
IoCompleteRequest( Irp, IO_NO_INCREMENT );
返回一个STATUS_SUCCESS,不往下CALLDRIVER
就行了,也不会弹出提示,上层系统认为写进去了,实际没有写进去

但是只处理IRP_MJ_WRITE是不够的
xuAmigo
驱动小牛
驱动小牛
  • 注册日期2004-11-11
  • 最后登录2006-01-12
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2005-05-10 14:50
我觉的你说的有道理,但写有两种情况(1)写入一个新文件(2)在已存在的文件上写,我又如何来区分呢,现在不好给分了,过会儿一定散分,请继续关注
qiangguo64
驱动牛犊
驱动牛犊
  • 注册日期2005-01-12
  • 最后登录2009-08-28
  • 粉丝0
  • 关注0
  • 积分144分
  • 威望15点
  • 贡献值1点
  • 好评度14点
  • 原创分0分
  • 专家分0分
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基本上认为是打开一个已有文件,其他的也能粗略的区分,不是很准
zhjie374
驱动小牛
驱动小牛
  • 注册日期2004-10-27
  • 最后登录2012-01-17
  • 粉丝2
  • 关注1
  • 积分17分
  • 威望144点
  • 贡献值1点
  • 好评度21点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2005-05-10 15:49
我直接拦截IRP_MJ_WRITE了。没有问题,保存的时候弹出提示。

写新文件是什么意思?
禁止新建文件不行吗?
xuAmigo
驱动小牛
驱动小牛
  • 注册日期2004-11-11
  • 最后登录2006-01-12
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2005-05-10 16:20
to zhjie374:
你在IRP_MJ_WRITE中处理是怎么做的,如何区分某个文件是已经存在的还是新建的呢
qiangguo64
驱动牛犊
驱动牛犊
  • 注册日期2005-01-12
  • 最后登录2009-08-28
  • 粉丝0
  • 关注0
  • 积分144分
  • 威望15点
  • 贡献值1点
  • 好评度14点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2005-05-10 16:46
只处理IRP_MJ_WRITE是不行的,有兴趣的话可以用filemon看看link是怎么工作的,一个IRP_MJ_WRITE都没有,照样生成了文件
xuAmigo
驱动小牛
驱动小牛
  • 注册日期2004-11-11
  • 最后登录2006-01-12
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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,我不知判断什么
qiangguo64
驱动牛犊
驱动牛犊
  • 注册日期2005-01-12
  • 最后登录2009-08-28
  • 粉丝0
  • 关注0
  • 积分144分
  • 威望15点
  • 贡献值1点
  • 好评度14点
  • 原创分0分
  • 专家分0分
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;
}

随手写的,自己修饰一下,逻辑上应该没问题
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2005-05-10 21:54
很多软件写文件的时候都是先写临时文件,然后再删除原文件,再把临时文件重命名成目标文件的,所以你还需要处理set information
qiangguo64
驱动牛犊
驱动牛犊
  • 注册日期2005-01-12
  • 最后登录2009-08-28
  • 粉丝0
  • 关注0
  • 积分144分
  • 威望15点
  • 贡献值1点
  • 好评度14点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2005-05-11 12:05
那这样只要禁止删除就行了

我以前还发现一种情况,以FILE_OVERWRITE_IF 打开的话,即使没有写入,文件也会被清空
xuAmigo
驱动小牛
驱动小牛
  • 注册日期2004-11-11
  • 最后登录2006-01-12
  • 粉丝0
  • 关注0
  • 积分58分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2005-05-11 13:51
谢谢各位的帮助,我实现这个功能了,主要在IRP_MJ_SET_INFORMATION处理例程中处理,这里不好给分,我重新开贴,qiangguo64,zhjie374你们去领分吧
yearnyan
驱动牛犊
驱动牛犊
  • 注册日期2004-06-17
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望5点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2005-05-11 19:56
  说一说具体怎么实现的呀.
游客

返回顶部