国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

用拷貝鉤子實現對文件夾的監控

2019-11-17 05:30:14
字體:
來源:轉載
供稿:網友

  本文原出處已不知。原作:webber84, 經ccrun(老妖)修改并在BCB在調試通過。
ICopyHook是一個用于創建拷貝鉤子處理程序COM接口,它決定一個文件夾或者打印機對象是否可以被移動,拷貝,重命名或刪除。Shell在執行這些操作之前,會調用ICopyHook接口的CopyCallback方法對它們進行驗證。CopyCallback返回一個int值指示Shell是否應該繼續執行這個操作。返回值IDYES表示繼續,而返回值IDNO和IDCANCEL則表示終止。

一個文件夾對象可以安裝多個拷貝鉤子處理程序。假如出現這種情況,Shell會依次調用每個處理程序。只有當每個處理程序都返回IDYES時,Shell才真正執行用戶請求的操作。

拷貝鉤子處理程序的作用是在上述四種操作執行前對它們進行驗證,但是Shell并不會把操作的結果通知給拷貝鉤子處理程序。而windows提供的API函數FindFirstChangeNotification和FindNextChangeNotification卻可以實現這個功能。因此,只有把這種兩種方法結合起來,才能對一個文件夾的狀態進行完全的監控。

拷貝鉤子處理程序實現并不困難,首先創建一個作為進程內組件的COM對象,它只需要暴露一個ICopyHook接口(當然還有IUnknown)。然后用regsrv32.exe注冊這個COM組件。最后一步是向Shell注冊你的這個拷貝鉤子處理程序,方法是在注冊表HKEY_CLASSES_ROOT/Directory/Shellex/CopyHookHandlers下創建一個名稱任意的sub key,在此sub key中創建一個類型為REG_SZ的項并將你的COM對象的CLSID作為它的默認值就可以了。

下面就是一個拷貝鉤子的實現程序(注:以下代碼經老妖改動并添加了具體操作過程,在BCB6中成功編譯并通過測試)

1. 從ICopyHook接口創建TCopyHook,從IClassFactory接口創建TClassFactory:

// TCopyHook.h
// TCopyHook類實現了ICopyHook接口,TClassFactory實現了IClassFactory接口
//---------------------------------------------------------------------------
#define NO_WIN32_LEAN_AND_MEAN
#include <shlobj.h>
//---------------------------------------------------------------------------
class TCopyHook: public ICopyHook
{
public:
    TCopyHook():m_refcnt(0) {}
    STDMETHODIMP QueryInterface(REFIID iid,void **ppvObject);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();
    STDMETHODIMP_(UINT) CopyCallback(HWND hwnd, UINT wFunc, UINT wFlags,
            LPCTSTR pszSrcFile, DWord dwSrcAttribs,
            LPCTSTR pszDestFile, DWORD dwDestAttribs);
PRivate:
    int m_refcnt;
};
//---------------------------------------------------------------------------
class TClassFactory : public IClassFactory
{
public:
    TClassFactory():m_refcnt(0) {}
    STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();
    STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject);

    STDMETHODIMP LockServer(BOOL fLock);
private:
    int m_refcnt;
};


// TCopyHook.cpp
// TCopyHook對象和TClassFactory對象的實現文件
#include <stdio.h>
#include "TCopyHook.h"
//---------------------------------------------------------------------------
extern LONG nLocks;          // 對象計數,用于DllCanUnloadNow
ULONG __stdcall TCopyHook::AddRef()
{
    if(m_refcnt == 0)
        nLocks++;
    m_refcnt++;
    return m_refcnt;
}
//---------------------------------------------------------------------------
ULONG __stdcall TCopyHook::Release()
{
    int nNewCnt = --m_refcnt;
    if(nNewCnt <= 0)
    {
        nLocks--;
        delete this;
    }
    return nNewCnt;
}
//---------------------------------------------------------------------------
HRESULT __stdcall TCopyHook::QueryInterface(REFIID dwIID, void **ppvObject)
{
    if(dwIID == IID_IUnknown)
        *ppvObject = static_cast<IUnknown*>(this);
    else
        if(dwIID == IID_IShellCopyHook)
            *ppvObject = static_cast<ICopyHook*>(this);
        else
            return E_NOINTERFACE;
    reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
    return S_OK;
}
//---------------------------------------------------------------------------
// 這就是CopyCallback方法,拷貝鉤子的所有功能由它實現。參數的具體值參看MSDN
UINT __stdcall TCopyHook::CopyCallback(HWND hwnd, UINT wFunc, UINT wFlags,
        LPCTSTR pszSrcFile, DWORD dwSrcAttribs,
        LPCTSTR pszDestFile, DWORD dwDestAttribs)
{
    char szMessage[MAX_PATH+14];
    sprintf(szMessage, "對%s進行的操作,是否繼續?", pszSrcFile);
    return MessageBox(NULL, szMessage, "確認", MB_YESNO MB_ICONEXCLAMATION);
}
//---------------------------------------------------------------------------

ULONG __stdcall TClassFactory::AddRef()
{
    if(m_refcnt==0)
        nLocks++;
    m_refcnt++;
    return m_refcnt;
}
//---------------------------------------------------------------------------
ULONG __stdcall TClassFactory::Release()
{

    int nNewCnt = --m_refcnt;

    if(nNewCnt <= 0)
    {
        nLocks--;
        delete this;
    }
    return nNewCnt;
}
//---------------------------------------------------------------------------
HRESULT __stdcall TClassFactory::QueryInterface(REFIID dwIID, void **ppvObject)
{
    if(dwIID == IID_IUnknown)
        *ppvObject = static_cast<IUnknown*>(this);
    else
        if(dwIID == IID_IClassFactory)
            *ppvObject = static_cast<IClassFactory*>(this);
        else
            return E_NOINTERFACE;
    reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
    return S_OK;
}
//---------------------------------------------------------------------------
HRESULT __stdcall TClassFactory::CreateInstance(IUnknown* pUnkownOuter,
 &

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 喀喇沁旗| 凉山| 日喀则市| 镇平县| 韶山市| 黄陵县| 深水埗区| 胶州市| 石台县| 丰都县| 巴林左旗| 桃园县| 安多县| 贺兰县| 视频| 集贤县| 贵阳市| 远安县| 青州市| 孝感市| 慈利县| 封开县| 黔西县| 双柏县| 新津县| 平谷区| 嘉荫县| 连南| 句容市| 宁武县| 城市| 永安市| 白玉县| 天长市| 南平市| 义乌市| 茂名市| 河南省| 梓潼县| 车致| 崇仁县|