ICopyHook监控文件夹 (一)


ICopyHook监控文件夹(一)

作者:flyfish 2010-2-2


一 STDMETHODIMP类型的含义
#if defined(_WIN32) || defined(_MPPC_)

// Win32 doesn't support __export

#ifdef _68K_
#define STDMETHODCALLTYPE       __cdecl
#else
#define STDMETHODCALLTYPE       __stdcall
#endif
#define STDMETHODVCALLTYPE      __cdecl

#define STDAPICALLTYPE          __stdcall
#define STDAPIVCALLTYPE         __cdecl

#else

#define STDMETHODCALLTYPE       __export __stdcall
#define STDMETHODVCALLTYPE      __export __cdecl

#define STDAPICALLTYPE          __export __stdcall
#define STDAPIVCALLTYPE         __export __cdecl

#endif

__cdecl
参数传递顺序: 从右向左  最后一个参数先传递,第一个参数最后传递
栈的维护:调用方清空栈
名字修饰约定:在函数名前加上一个下划线

__stdcall
参数传递顺序: 从右向左  最后一个参数先传递,第一个参数最后传递
栈的维护:被调用方清空栈
名字修饰约定:在函数名前面加下划线,后面加“@”符号和参数的字节数

从上面的宏定义可以看出COM接口中的调用方式采用的是__stdcall,也就是由COM来维护栈。

二 那么COM是如何维护栈的呢?

COM规范规定COM接口都必须从IUnknown继承,IUnknown包含三个函数,分别是 QueryInterface、AddRef、

Release。
在IClassFactory中的两个虚函数CreateInstance和LockServer

 IClassFactory : public IUnknown
    {
    public:
        virtual /* [local] */ HRESULT STDMETHODCALLTYPE CreateInstance(
            /* [unique][in] */ IUnknown *pUnkOuter,
            /* [in] */ REFIID riid,
            /* [iid_is][out] */ void **ppvObject) = 0;
       
        virtual /* [local] */ HRESULT STDMETHODCALLTYPE LockServer(
            /* [in] */ BOOL fLock) = 0;
       
    };

 

在IUnknown中可以看到三个虚函数QueryInterface,AddRef,Release
 virtual HRESULT STDMETHODCALLTYPE QueryInterface(
                /* [in] */ REFIID riid,
                /* [iid_is][out] */ __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject) = 0;

            virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0;

            virtual ULONG STDMETHODCALLTYPE Release( void) = 0;

这两段代码在Unknwn.h文件中

COM中对COM对象生存周期的控制使用了“引用计数”技术

每一个COM对象都记录了一个称为“引用计数”的数值,这个在程序中就是

LONG nLocks=0;


nLocks表示为有多少有效指针在引用该COM对象。当得到了一个指向该对象的接口指针时,引用计数值加1,当

用完了该接口指针后,引用计数减1,当引用计数减到0时,COM对象就应该把自己从内存中清除掉,这样也就达

到了维护栈的目的。


在AddRef函数中引用计数值加1,
在Release函数中引用计数减1,如果为0,就清空该COM对象。

 

三 ICopyHook介绍
ICopyHook是一个用于创建拷贝钩子处理程序COM接口,可以用来监控文件夹的拷贝,移动,重命名和删除。如

果我们执行这些操作,那么Shell会在执行这些操作之前,调用ICopyHook接口的CopyCallback方法对这些操作

进行验证。

CopyCallback
函数原型
UINT CopyCallback(          HWND hwnd,
    UINT wFunc,
    UINT wFlags,
    LPCTSTR pszSrcFile,
    DWORD dwSrcAttribs,
    LPCTSTR pszDestFile,
    DWORD dwDestAttribs
);


其中的参数hwnd是一个窗口句柄
参数wFunc指定要被执行的操作,其取值为下表中所列之一:
  常量 取值 含义
  FO_COPY  复制 由pszSrcFile指定的文件到由pszDestFile指定的位置。
  FO_DELETE  删除 由pszSrcFile指定的文件。
  FO_MOVE 移动 由pszSrcFile指定的文件到由pszDestFile指定的位置。
  FO_RENAME  重命名 由pszSrcFile指定的文件。
 

参数wFlags指操作的标志;
参数pszSrcFile指源文件夹
参数dwSrcAttribs指源文件夹属性。
参数pszDestFile指目标文件夹
参数dwDesAttribs目标文件夹属性
函数返回值可以为IDYES、IDNO和IDCANCEL。


CopyCallback返回一个UINT值指示Shell是否应该继续执行这个操作。返回值IDYES表示继续,而返回值IDNO和

IDCANCEL则表示终止。

注意:当一个文件夹对象可以安装多个拷贝钩子处理程序时,Shell会依次调用每个处理程序。只有当每个处理

程序都返回IDYES,或者任何一个拷贝钩子返回IDNO或者IDCANCEL,Shell才真正执行用户请求的操作。


拷贝钩子需要在注册表的下面这些地方注册

注册文件夹的地方
HKEY_CLASSES_ROOT
Directory
Shellex
CopyHookHandlers
your_copyhook
(Default) = {copyhook CLSID value}

 

 

 

你可能感兴趣的:(shell,delete,2010)