1,在应用层使用 ReadDirectoryChangesW 方法:char buf[ 50*(sizeof(FILE_NOTIFY_INFORMATION)+MAX_PATH) ];
    FILE_NOTIFY_INFORMATION* pNotify=(FILE_NOTIFY_INFORMATION *)buf;
    DWORD BytesReturned;
    while(true)
    {
        memset(buf,0,sizeof(buf));
        if( ReadDirectoryChangesW( hDir,
            pNotify,
            sizeof(buf),
            true,
            FILE_NOTIFY_CHANGE_FILE_NAME|
            FILE_NOTIFY_CHANGE_DIR_NAME|
            FILE_NOTIFY_CHANGE_ATTRIBUTES|
            FILE_NOTIFY_CHANGE_SIZE|
            FILE_NOTIFY_CHANGE_LAST_WRITE|
            FILE_NOTIFY_CHANGE_LAST_ACCESS|
            FILE_NOTIFY_CHANGE_CREATION|
            FILE_NOTIFY_CHANGE_SECURITY,
            &BytesReturned,
            NULL,
            NULL ) )
        {
            pThis->SendOutNotify(pNotify, strDir);        }
        else
        {
            break;
        }
    }
2,使用MINIFILTER 文件微过滤驱动,网上有源码。

解决方案 »

  1.   

    UP,
    ReadDirectoryChangesW 只能监控该目录下,文件改变,但不能检测文件被打开、读取操作;
      

  2.   


    打开后有 FILE_NOTIFY_CHANGE_LAST_ACCESS 消息,如果还要读取消息的话,那你就用 MINIFILTER 文件微过滤驱动好了,可以很好的完成你的需求
    /*************************************************************************
        dispatch callback routines.
    *************************************************************************/
    FLT_PREOP_CALLBACK_STATUS
    PreCreate (
        __inout PFLT_CALLBACK_DATA Data,
        __in PCFLT_RELATED_OBJECTS FltObjects,
        __deref_out_opt PVOID *CompletionContext
        )
    {   
    FLT_PREOP_CALLBACK_STATUS FltStatus = FLT_PREOP_SUCCESS_NO_CALLBACK ;    UNREFERENCED_PARAMETER(CompletionContext);
    UNREFERENCED_PARAMETER(FltObjects) ;
    UNREFERENCED_PARAMETER(Data) ; if (Data->IoStatus.Information == IRP_MJ_CREATE)
    {
    if ( ((Data->Iopb->Parameters.Create.Options>>FILE_FUNCTION_OFFSET) & FILE_FUNCTION_MASK) == FILE_CREATE ||
    ((Data->Iopb->Parameters.Create.Options>>FILE_FUNCTION_OFFSET) & FILE_FUNCTION_MASK) == FILE_OVERWRITE_IF )
    {
    if( Ps_MonitorFileOperator(Data, FILE_TYPE_CREATE ) )
    {
    Data->IoStatus.Status = STATUS_SUCCESS;
    Data->IoStatus.Information = 0;
    return FLT_PREOP_COMPLETE;
    }
    }
    else if (((Data->Iopb->Parameters.Create.Options>>FILE_FUNCTION_OFFSET) & FILE_FUNCTION_MASK) ==FILE_OPEN_IF)
    {
    if( Ps_MonitorFileOperator(Data, FILE_TYPE_WRITE ) )
    {
    Data->Iopb->Parameters.Create.SecurityContext->AccessState->RemainingDesiredAccess &= ~FILE_GENERIC_WRITE;
    Data->IoStatus.Status = STATUS_ACCESS_DENIED;
    Data->IoStatus.Information = 0;
    return FLT_PREOP_COMPLETE;
    }
    }
    else if ( Data->Iopb->OperationFlags == FILE_MOVE_IN )
    {
    if( Ps_MonitorFileOperator(Data, FILE_TYPE_MOVE ) )
    {
    Data->IoStatus.Status = STATUS_SUCCESS;
    Data->IoStatus.Information = 0;
    return FLT_PREOP_COMPLETE;
    }
    }
    else
    {
    if( Ps_MonitorFileOperator(Data, FILE_TYPE_READ ) )
    {
    Data->Iopb->Parameters.Create.SecurityContext->AccessState->RemainingDesiredAccess &= ~FILE_GENERIC_READ; Data->IoStatus.Status = STATUS_SUCCESS;
    Data->IoStatus.Information = 0;
    return FLT_PREOP_COMPLETE;
    }
    }
    }

        return FltStatus ;//FLT_PREOP_SUCCESS_WITH_CALLBACK;
    }
      

  3.   

    Up,谢谢!
    但不太清楚MINIFILTER 怎样使用,能否留一下QQ,谢谢!
      

  4.   

    D:\WinDDK\7600.16385.1\src\filesys  WinDDK 里面有这个使用例子
      

  5.   

    up,新年好!
    请问WinDDk怎样调试?
    谢谢!
      

  6.   

    网上搜, 常用windbg+虚拟机 调试
      

  7.   

    也可以在应用层 hook文件操作API函数来检测
      

  8.   

    如果只是监控某个进程对文件的访问,那可以直接HOOK API来实现,
    如果是全局监控就只能在驱动层实现了。