网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > C/C++
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.在C语言中引入类的概念.
.C++的中抽象.
.C++箴言:将new出来的对象存入智.
.一段指针的经典程序.
.在C/C++中如何构造通用的对象链表.
.c语言中时间陷阱的实现.
.C++辨析系列谈(三).
.试一下 moving ball.
.如何学好C.
.Visual FoxPro3.0经验14条.
.C++箴言:多态基类中将析构函数声.
.如何使用OnIdle事件.
.轻轻松松从C一路走到C++系列文章.
.通讯录的源代码(用链表实现).
.C语言图形处理.
.玩转BCB的IDE,体验ToolsAPI.
.C++ 中园形三角形按钮的实现.
.用c写CGI 程序简要指南.
.C语言实现MATLAB 6.5中M文件的方.
.TC 中的汉字技术.

用拷贝钩子实现对文件夹的监控

发表日期:2008-3-8



  本文原出处已不知。原作: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,
 &
上一篇:用纯粹的C++编写COM组件 人气:1202
下一篇:用键盘移动光标的简单介绍 人气:852
浏览全部C/C++的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐