我想禁止用户对某个文件的删除、copy覆盖。
可以截获用户对这个文件操作的消息吗?如果不能,有什么办法可以防止用户对某个文件的删除和修改?

解决方案 »

  1.   

    可以挂IFS HOOK,但是那样的话就要写驱动,很麻烦!!!
      

  2.   

    to mfc168(闶阆) ( ) 
    因为我的这些文件我也要访问的,但不会一次就访问所有的文件啊。
    如果我把目录改短进行访问,可能一些未访问的文件回造成破坏。不过你的哪个思路很好哦。我说一下我的需求。我在做一个远程控制的项目,需要把客户端的资料传回服务端。可是客户端可能不与服务端相连。因此需要把这些资料先保存在客户端。当连接后再传回来。因此要保护这些资料。如果客户端很长时间不与服务端相连,文件数目就会很多。因此一楼和三楼的方法都不行。不用太严格的保护,能防止一般的操作就行了。防君子不防小人嘛。
      

  3.   

    另外问一下lonely001(独行客) ( )可以挂IFS HOOK,怎么写?很麻烦吗?
      

  4.   

    俺知道有个核心对象叫Change Notification;
    他的作用是当一个特定的磁盘子目录发生一件特别的变化时,此对象就被激发
    此对象是由FindFirstChangeNotification()产生!
    其中“当一个特定的磁盘子目录发生一件特别的变化”指的是以下六种变化
    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_SECURITY 目录及子目录中的任何安全属性改变
    俺只是知道有这么个东西,好象能满足楼主的要求,但是俺也没有具体用过
    只有楼主查阅相关的资料了,俺在这里只是提示一下!
    呵呵……
    祝你成功啊!
      

  5.   

    通过Shell扩展编程可以实现简单的控制,但最终必须作驱动程序,要不然是防不住的
      

  6.   

    需要IFS HOOK作文件监控
    但是IFS HOOK的开发包不便宜,去ms看看吧
      

  7.   

    hook kernel32中的CopyFile CopyFileEx DeleteFile就可以了
      

  8.   

    to hedeyong() ( )
    hook kernel32中的CopyFile CopyFileEx DeleteFile就可以了具体怎么实现?能给我个例子吗?谢谢
    Email [email protected]
      

  9.   

    写一个文件系统过滤驱动程序,对过往的IRP包进行监视,非常方便。代码当然应该参考FileMon,极其经典的IFS过滤驱动。
      

  10.   

    Windows外壳扩展是这样实现的。首先要编写外壳扩展程序,一个外壳扩展程序是基于COM(Component Object Model)组件模型的。外壳是通过接口(Interface)来访问对象的。外壳扩展被设计成32位的进程中服务器程序,并且都是以动态链接库的形式为操作系统提供服务的。写好外壳扩展程序后,必须将它们注册才能生效。所有的外壳扩展都必须在Windows注册表的HKEY_CLASSES_ROOT\CLSID键之下进行注册。在该键下面可以找到许多名字像{ACDE002F-0000-0000-C000-000000000046}的键,这类键就是全局唯一类标识符。每一个外壳扩展都必须有一个全局唯一类标识符,Windows正是通过此唯一类标识符来找到外壳扩展处理程序的。在类标识符之下的InProcServer32子键下记录着外壳扩展动态链接库在系统中的位置。 Windows系统支持以下7类的外壳扩展功能:(1)Context menu handlers向特定类型的文件对象增添上下文相关菜单; (2)Drag-and-drop handlers用来支持当用户对某种类型的文件对象进行拖放操作时的OLE数据传输; (3)Icon handlers用来向某个文件对象提供一个特有的图标,也可以给某一类文件对象指定图标; (4)Property sheet handlers给文件对象增添属性页,属性页可以为同一类文件对象所共有,也可以给一个文件对象指定特有的属性页; (5)Copy-hook handlers在文件夹对象或者打印机对象被拷贝、移动、删除和重命名时,就会被系统调用,通过为Windows增加Copy-hook handlers,可以允许或者禁止其中的某些操作; (6)Drop target handlers在一个对象被拖放到另一个对象上时,就会被系统被调用; (7)Data object handlers在文件被拖放、拷贝或者粘贴时,就会被系统被调用。文件夹保护功能就是通过上面的第5类,既Copy-hook handlers来实现的。一个支持Copy-hook handlers的程序除了上面提到的要在注册表的HKEY_CLASSES_ROOT\CLSID下注册之外,还需要在HKEY_CLASSES_ROOT\Directory\shellex\CopyHookHandlers\下注册服务器程序的类。由于Windows外壳服务器程序是基于COM组件模型的,所以编写外壳程序就是构造一个COM对象的过程.
    利用Delphi编写Copy-hook handle需要实现ICopyHook接口。ICopyHook是一个十分简单的接口,要实现的只有CopyCallBack方法。ICopyHook的CopyCallBack方法的定义如下:UINT CopyCallback(  HWND hwnd, file://Handle of the parent window for displaying UI objects  UINT wFunc, file://Operation to perform.  UINT wFlags, file://Flags that control the operation  LPCSTR pszSrcFile, file://Pointer to the source file  DWORD dwSrcAttribs, file://Source file attributes  LPCSTR pszDestFile, file://Pointer to the destination file  DWORD dwDestAttribs file://Destination file attributes  );其中的参数hwnd是一个窗口句柄,Copy-hook handle以此为父窗口。参数wFunc指定要被执行的操作,其取值为下表中所列之一:常量 取值 含义FO_COPY $2 复制由pszSrcFile指定的文件到由pszDestFile指定的位置。FO_DELETE $3 删除由pszSrcFile指定的文件。FO_MOVE $1 移动由pszSrcFile指定的文件到由pszDestFile指定的位置。FO_RENAME $4 重命名由pszSrcFile指定的文件到由pszDestFile指定的文件名。PO_DELETE $13 删除pszSrcFile指定的打印机。PO_PORTCHANGE $20 改变打印机端口。PszSrcFile和pszDestFile为两个以Null结尾的字符串,分别指定当前和新的打印机端口名。PO_RENAME $14 重命名由pszSrcFile指定的打印机端口。PO_REN_PORT $34 PO_RENAME和PO_PORTCHANGE的组合。  参数wFlags指定操作的标志;参数pszSrcFile和pszDestFile指定源文件夹和目标文件夹。参数dwSrcAttribs和dwDesAttribs指定源文件夹和目标文件夹的属性。函数返回值可以为IDYES、IDNO和IDCANCEL。分别指示Windows外壳允许操作、阻止操作,但是其他操作继续、阻止当前操作,取消为执行的操作。
      

  11.   

    Windows shell扩展只能对文件夹有效,对某个文件没有作用,我已试过。可能并不能满足
    wangbab(bab)的要求。
      

  12.   

    Windows shell 有一个CopyHook!对文件夹和文件都有用!
      

  13.   

    DEFINE_GUID( CLSID_CopyHook, 0xebf1799aL, 0x3e97, 0x493a, 0x91, 0x1d, 0xac, 0x93, 0xe2, 0xf6, 0xe7, 0x61 );class CCopyHook : public ICopyHook,
     IShellExtInit  
    {
    protected:
    ULONG        m_cRef;
    LPDATAOBJECT m_pDataObj;public:
    CCopyHook();
    virtual ~CCopyHook(); //IUnknown members
    STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release(); //IShellExtInit methods
    STDMETHODIMP     Initialize(LPCITEMIDLIST pIDFolder, 
                                       LPDATAOBJECT pDataObj, 
                                       HKEY hKeyID);    //ICopyHook method
        STDMETHODIMP_(UINT) CopyCallback(HWND hwnd, 
                                         UINT wFunc, 
                                         UINT wFlags, 
                                         LPCSTR pszSrcFile, 
                                         DWORD dwSrcAttribs,
                                         LPCSTR pszDestFile, 
                                         DWORD dwDestAttribs);};class CCopyHookClassFactory : public IClassFactory 
    {
    protected:
    ULONG m_cRef;public:
    CCopyHookClassFactory();
    virtual ~CCopyHookClassFactory(); //IUnknown members
    STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release(); //IClassFactory members
    STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR *);
    STDMETHODIMP LockServer(BOOL);};#define INITGUID
    #include <initguid.h>
    #include <shlguid.h>
    #include "CopyHook.h"
    #pragma data_seg()// Dll's Global variables
    UINT      g_nDllRefCount = 0;    // Reference count of this DLL
    HINSTANCE g_hThisDll = NULL; // Handle to this DLLextern "C" int APIENTRY DllMain(HINSTANCE hInstance, 
    DWORD dwReason, 
    LPVOID lpReserved)
    {
        if (dwReason == DLL_PROCESS_ATTACH)
        {
            // Extension DLL one-time initialization
            g_hThisDll = hInstance;
        }    return 1;   // ok
    }STDAPI DllCanUnloadNow(void)
    {
        if ( g_nDllRefCount == 0  )
    return S_OK;
    else
    return S_FALSE;
    }STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
    {
    CCopyHookClassFactory *pcf;    *ppvOut = NULL;
        if (IsEqualIID(rclsid, CLSID_CopyHook))
        {
            pcf = new CCopyHookClassFactory;
            return pcf->QueryInterface(riid, ppvOut);
        }    return CLASS_E_CLASSNOTAVAILABLE;
    }////////////////////////////////////////
    // -------- CCopyHookClassFactory ------
    ////////////////////////////////////////
    CCopyHookClassFactory::CCopyHookClassFactory()
    {
        m_cRef = 0L;
        g_nDllRefCount++;
    }

    CCopyHookClassFactory::~CCopyHookClassFactory()
    {
        g_nDllRefCount--;
    }STDMETHODIMP CCopyHookClassFactory::QueryInterface(REFIID riid,
                                                       LPVOID FAR *ppv)
    {
        *ppv = NULL;    // note: Any interface on this object is the object pointer
        if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
        {
            *ppv = (LPCLASSFACTORY)this;
            AddRef();
            return NOERROR;
        }    return E_NOINTERFACE;
    } STDMETHODIMP_(ULONG) CCopyHookClassFactory::AddRef()
    {
        return ++m_cRef;
    }STDMETHODIMP_(ULONG) CCopyHookClassFactory::Release()
    {
        if (--m_cRef)
            return m_cRef;    delete this;
        return 0L;
    }STDMETHODIMP CCopyHookClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
                                                          REFIID riid,
                                                          LPVOID *ppvObj)
    {
        *ppvObj = NULL;    // don't support aggregation
        if (pUnkOuter)
         return CLASS_E_NOAGGREGATION;    CCopyHook *pCopyHook = new CCopyHook();
        if (NULL == pCopyHook)
         return E_OUTOFMEMORY;    return pCopyHook->QueryInterface(riid, ppvObj);
    }
    STDMETHODIMP CCopyHookClassFactory::LockServer(BOOL fLock)
    {
        return NOERROR;
    }
    //////////////////////////////////////////
    // ----------- CCopyHook ----------------
    //////////////////////////////////////////
    CCopyHook::CCopyHook()
    {
        m_cRef = 0L;
        m_pDataObj = NULL;    g_nDllRefCount++;
    }CCopyHook::~CCopyHook()
    {
        if (m_pDataObj)
            m_pDataObj->Release();    g_nDllRefCount--;
    }STDMETHODIMP CCopyHook::QueryInterface(REFIID riid, LPVOID FAR *ppv)
    {
        *ppv = NULL;    if ( IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown) )
        {
         *ppv = (LPSHELLEXTINIT)this;
        }
        else if (IsEqualIID(riid, IID_IShellCopyHook))
        {
            *ppv = (LPCOPYHOOK)this;
        }    if (*ppv)
        {
            AddRef();
            return NOERROR;
        } return E_NOINTERFACE;
    }STDMETHODIMP_(ULONG) CCopyHook::AddRef()
    {
        return ++m_cRef;
    }STDMETHODIMP_(ULONG) CCopyHook::Release()
    {
        if (--m_cRef)
            return m_cRef;    delete this;
        return 0L;
    }STDMETHODIMP CCopyHook::Initialize(LPCITEMIDLIST pIDFolder,
                                       LPDATAOBJECT pDataObj,
                                       HKEY hRegKey)
    {
        // Initialize can be called more than once
        if (m_pDataObj)
         m_pDataObj->Release();    // duplicate the object pointer and registry handle
        if (pDataObj)
        {
         m_pDataObj = pDataObj;
         pDataObj->AddRef();
        }    return NOERROR;
    }STDMETHODIMP_(UINT) CCopyHook::CopyCallback(HWND hwnd, 
                                                UINT wFunc, 
                                                UINT wFlags, 
                                                LPCSTR pszSrcFile, 
                                                DWORD dwSrcAttribs,
                                                LPCSTR pszDestFile, 
                                                DWORD dwDestAttribs)
    {// int ret;//    ret = MessageBox( NULL, "Are you sure?", 
    // "CopyHook Sample", MB_YESNOCANCEL | MB_ICONQUESTION );
        return IDCANCEL;
    }
    wangbab可以试用一下