test001
驱动小牛
驱动小牛
  • 注册日期2006-11-12
  • 最后登录2008-11-07
  • 粉丝0
  • 关注0
  • 积分990分
  • 威望170点
  • 贡献值0点
  • 好评度169点
  • 原创分0分
  • 专家分0分
阅读:1374回复:12

devia大侠请教一个问题,多谢!(悬赏50分!!!)

楼主#
更多 发布于:2007-05-24 16:50
我想在指定的文件夹下禁止新建文件和文件夹的操作,代码如下:
sfcreate()
{
......
完成当前文件夹是否是指定文件夹的判断

CreateDisposition = (irpSp->Parameters.Create.Options>> 24) & 0x000000ff;
if(CreateDisposition==FILE_CREATE||CreateDisposition==FILE_OPEN_IF||CreateDisposition==FILE_OVERWRITE_IF)
{
    DbgPrint("==================当前是一个新建文件的操作!!!======================\n");
    Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
    Irp->IoStatus.Information = 0;
    status = Irp->IoStatus.Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_ACCESS_DENIED;
}
}

驱动加载后,会出现以下的问题:
(1)在指定的文件夹新建文件夹时,系统也提示“无法创建文件夹,拒绝访问”,但是系统还是会新建文件夹,而且新建的文件夹无法访问;
(2)在指定的文件夹新建文件时,系统也提示“无法创建文件,文件存在”,但是系统还是会999个新建文件,而且新建的文件无法访问。
   看过以前的帖子上也与遇到过来类似的问题,但是没有写是怎么解决的,肯请devia大侠帮忙解答一下!
   多谢!!!

最新喜欢:

精灵dsp精灵dsp
test001
驱动小牛
驱动小牛
  • 注册日期2006-11-12
  • 最后登录2008-11-07
  • 粉丝0
  • 关注0
  • 积分990分
  • 威望170点
  • 贡献值0点
  • 好评度169点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-05-25 09:14
自己顶起来!
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
板凳#
发布于:2007-05-25 14:32
请在SfCreate中尽可能靠近入口的位置写这段代码,
估计你的问题是漏掉了某个IRP而造成的。
人总在矛盾中徘徊。。。
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
地板#
发布于:2007-05-25 14:51
NTSTATUS
SfCreate (
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    )
{
    NTSTATUS status;
    IO_STATUS_BLOCK IoStatus = {0};
    PSFILTER_DEVICE_EXTENSION devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
    
    PAGED_CODE();

    //
    //  If this is for our control device object, don't allow it to be opened.
    //
    
    if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {
        
        //
        //  Sfilter doesn't allow for any communication through its control
        //  device object, therefore it fails all requests to open a handle
        //  to its control device object.
        //
        //  See the FileSpy sample for an example of how to allow creates to
        //  the filter's control device object and manage communication via
        //  that handle.
        //
        
        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        
        IoCompleteRequest( Irp, IO_NO_INCREMENT );
        
        return STATUS_SUCCESS;
    }
    
    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
    
#if 1
    
    if( (irpSp->FileObject != NULL) &&
        (irpSp->FileObject->FileName.Buffer != NULL) &&
        (wcsstr(irpSp->FileObject->FileName.Buffer, L"新建") != NULL) )
    {
        //
        //  失败返回
        //
        
        Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest( Irp, IO_NO_INCREMENT );
        
        return STATUS_ACCESS_DENIED;
    }
    
#endif
   ......
}
人总在矛盾中徘徊。。。
test001
驱动小牛
驱动小牛
  • 注册日期2006-11-12
  • 最后登录2008-11-07
  • 粉丝0
  • 关注0
  • 积分990分
  • 威望170点
  • 贡献值0点
  • 好评度169点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-05-26 11:40
多谢devia大侠,我回去再试试!!!
test001
驱动小牛
驱动小牛
  • 注册日期2006-11-12
  • 最后登录2008-11-07
  • 粉丝0
  • 关注0
  • 积分990分
  • 威望170点
  • 贡献值0点
  • 好评度169点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-05-29 15:08
devia大侠,以下是我的源代码:

NTSTATUS
SfCreate (IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
   NTSTATUS status;
   KEVENT waitEvent;  
   PUNICODE_STRING name;
   GET_NAME_CONTROL nameControl;
   int cmpresult;
   PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
   wchar_t* testmyProtectPath = L"\\Device\\HarddiskVolume1\\user\\";    

    PAGED_CODE();
    if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
    {
    Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;        
        IoCompleteRequest( Irp, IO_NO_INCREMENT );        
        return STATUS_SUCCESS;
    }
    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));

    /////////////////////////////////////////////////////////////////////////////////////////
    KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );
    IoCopyCurrentIrpStackLocationToNext( Irp );
    IoSetCompletionRoutine(Irp,SfCreateCompletion,&waitEvent,TRUE,TRUE,TRUE );
    status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
     name = SfGetFileName( irpSp->FileObject, Irp->IoStatus.Status, &nameControl );
    cmpresult = wcsncmp(name->Buffer, testmyProtectPath,wcslen(testmyProtectPath));
    if(cmpresult == 0)
    {
        if( (irpSp->FileObject != NULL) &&(irpSp->FileObject->FileName.Buffer != NULL) &&(wcsstr(irpSp->FileObject->FileName.Buffer, L"新建") != NULL) )
        {
            DbgPrint("==================当前是一个新建文件的操作!!!======================\n");
            Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
            Irp->IoStatus.Information = 0;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return STATUS_ACCESS_DENIED;
        }
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////

    if (STATUS_PENDING == status)
    {
        NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL);
        ASSERT(STATUS_SUCCESS == localStatus);
    }

    ASSERT(KeReadStateEvent(&waitEvent) || !NT_SUCCESS(Irp->IoStatus.Status));

    if (FlagOn(SfDebug, (SFDEBUG_GET_CREATE_NAMES|SFDEBUG_DISPLAY_CREATE_NAMES)))
    {
        SfDisplayCreateFileName( Irp );
    }
    status = Irp->IoStatus.Status;
    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    return status;
}


NTSTATUS
SfCreateCompletion (IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context)
{
    PKEVENT event = Context;

    UNREFERENCED_PARAMETER( DeviceObject );
    UNREFERENCED_PARAMETER( Irp );

    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));

    KeSetEvent(event, IO_NO_INCREMENT, FALSE);

    return STATUS_MORE_PROCESSING_REQUIRED;
}

我试了你的方法,如果把判断新建文件的操作放在最开始的位置,这样的确可以禁止新建文件,但这样也会禁止整个文件系统都新建文件,而我只是要禁止在user目录下禁止新建文件的操作,所以这里不可避免地要进行获取文件路径的操作,不知道是不是因为获取文件路径会造成IRP的重入?这个问题怎么解决呢?
多谢!
test001
驱动小牛
驱动小牛
  • 注册日期2006-11-12
  • 最后登录2008-11-07
  • 粉丝0
  • 关注0
  • 积分990分
  • 威望170点
  • 贡献值0点
  • 好评度169点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-05-29 18:25
Re:devia大侠请教一个问题,多谢!
50分,求解决问题的方法!
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
7楼#
发布于:2007-05-30 08:38
你可以用WDK中最新的sfilter框架,或者用tooflat的sfilter中方法来获取文件名,
这样可以在你Dispatch到FSD之前来获取文件名;
人总在矛盾中徘徊。。。
devia
论坛版主
论坛版主
  • 注册日期2005-05-14
  • 最后登录2016-04-05
  • 粉丝3
  • 关注0
  • 积分1029分
  • 威望712点
  • 贡献值1点
  • 好评度555点
  • 原创分8分
  • 专家分4分
8楼#
发布于:2007-05-30 08:41
你的代码中也有个明显的错误:
如果你IoCallDirver已经成功,那么你只简单的返回STATUS_ACCESS_DENIED是
不行的,所以你还需要Cancel掉先前的打开操作。
人总在矛盾中徘徊。。。
test001
驱动小牛
驱动小牛
  • 注册日期2006-11-12
  • 最后登录2008-11-07
  • 粉丝0
  • 关注0
  • 积分990分
  • 威望170点
  • 贡献值0点
  • 好评度169点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-05-30 09:10
引用第7楼devia于2007-05-30 08:38发表的  :
你可以用WDK中最新的sfilter框架,或者用tooflat的sfilter中方法来获取文件名,
这样可以在你Dispatch到FSD之前来获取文件名;


其你跟哪里有WDK中最新的sfilter?
谢谢!
test001
驱动小牛
驱动小牛
  • 注册日期2006-11-12
  • 最后登录2008-11-07
  • 粉丝0
  • 关注0
  • 积分990分
  • 威望170点
  • 贡献值0点
  • 好评度169点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2007-05-30 09:16
引用第8楼devia于2007-05-30 08:41发表的  :
你的代码中也有个明显的错误:
如果你IoCallDirver已经成功,那么你只简单的返回STATUS_ACCESS_DENIED是
不行的,所以你还需要Cancel掉先前的打开操作。


我也猜到可能是因为获得文件名的操作引起的,可是不知道怎么处理?因为获取文件名的操作函数是直接用sfilter里的。
devia大侠能具体说说如何Cancel掉先前的打开操作吗?
谢谢!
test001
驱动小牛
驱动小牛
  • 注册日期2006-11-12
  • 最后登录2008-11-07
  • 粉丝0
  • 关注0
  • 积分990分
  • 威望170点
  • 贡献值0点
  • 好评度169点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2007-05-31 14:41
再顶一下!
test001
驱动小牛
驱动小牛
  • 注册日期2006-11-12
  • 最后登录2008-11-07
  • 粉丝0
  • 关注0
  • 积分990分
  • 威望170点
  • 贡献值0点
  • 好评度169点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2007-06-01 14:50
我的问题怎么没有人回答呀?
大牛救救我吧!
游客

返回顶部