Windows外壳扩展保护文件夹

利用Windows外壳扩展保护文件夹  
   
  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对象的过程,由于Delphi4.0以上的版本支持Windows外壳扩展和COM组件模型,所以可以利用Delphi来编写外壳扩展程序。  
  利用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外壳允许操作、阻止操作,但是其他操作继续、阻止当前操作,取消为执行的操作。  
  下面是具体的程序实现:  
  首先在Delphi的菜单中选 File|New选项,选择其中的DLL图标,按Ok键建立一个DLL工程文件,在其中添加以下代码:  
  library CopyHook;  
   
  uses  
  ComServ,  
  CopyMain in 'CopyMain.pas';  
   
  exports  
  DllGetClassObject,  
  DllCanUnloadNow,  
  DllRegisterServer,  
  DllUnregisterServer;  
   
  {$R *.TLB}  
   
  {$R *.RES}  
   
  begin  
  end.  
  将文件保存为 CopyHook.dpr。再在Delphi菜单中选File|New选项,选择其中的Unit图标,按Ok键建立一个Pas文件,在其中加入以下代码:  
  unit CopyMain;  
   
  interface  
   
  uses Windows, ComObj, ShlObj;  
   
  type  
  TCopyHook = class(TComObject, ICopyHook)  
  protected  
  function CopyCallback(Wnd: HWND; wFunc, wFlags: UINT; pszSrcFile: PAnsiChar;  
  dwSrcAttribs: DWORD; pszDestFile: PAnsiChar; dwDestAttribs: DWORD): UINT; stdcall;  
  end;  
   
  TCopyHookFactory = class(TComObjectFactory)  
  protected  
  function GetProgID: string; override;  
  procedure ApproveShellExtension(Register: Boolean; const ClsID: string);  
  virtual;  
  public  
  procedure UpdateRegistry(Register: Boolean); override;  
  end;  
   
  implementation  
   
  uses ComServ, SysUtils, Registry;  
   
  { TCopyHook }  
   
  file://当/Windows外壳程序执行文件夹或者打印机端口操作时,CopyCallBack  
  file://方/法就会被调用。  
  function TCopyHook.CopyCallback(Wnd: HWND; wFunc, wFlags: UINT;  
  pszSrcFile: PAnsiChar; dwSrcAttribs: DWORD; pszDestFile: PAnsiChar;  
  dwDestAttribs: DWORD): UINT;  
  const  
  FO_COPY = 2;  
  FO_DELETE = 3;  
  FO_MOVE = 1;  
  FO_RENAME = 4;  
  var  
  sOp:string;  
  begin  
  Case wFunc of  
  FO_COPY: sOp:=format('你确定要将 %s 拷贝到 %s 吗?',[pszSrcFile,pszDestFile]);  
  FO_DELETE: sOp:=format('你确定要将 %s 删除吗?',[pszSrcFile]);  
  FO_MOVE: sOp:=format('你确定要将 %s 转移到 %s 吗?',[pszSrcFile,pszDestFile]);  
  FO_RENAME: sOp:=format('你确定要将 %s 重命名为 %s 吗?',[pszSrcFile,pszDestFile]);  
  else  
  sOp:=format('无法识别的操作代码 %d',[wFlags]);  
  end;  
  // 提示,让用户决定是否执行操作  
  Result := MessageBox(Wnd, PChar(sOp),  
  '文件挂钩演示', MB_YESNOCANCEL);  
  end;  
   
  { TCopyHookFactory }  
   
  function TCopyHookFactory.GetProgID: string;  
  begin  
  Result := '';  
  end;  
   
  procedure TCopyHookFactory.UpdateRegistry(Register: Boolean);  
  var  
  ClsID: string;  
  begin  
  ClsID := GUIDToString(ClassID);  
  inherited UpdateRegistry(Register);  
  ApproveShellExtension(Register, ClsID);  
  if Register then  
  file://将/clsid 加入到注册表的CopyHookHandlers中  
  CreateRegKey('directory/shellex/CopyHookHandlers/' + ClassName, '',  
  ClsID)  
  else  
  DeleteRegKey('directory/shellex/CopyHookHandlers/' + ClassName);  
  end;  
   
  procedure TCopyHookFactory.ApproveShellExtension(Register: Boolean;  
  const ClsID: string);  
  const  
  SApproveKey = 'SOFTWARE/Microsoft/Windows/CurrentVersion/Shell Extensions/Approved';  
  begin  
  with TRegistry.Create do  
  try  
  RootKey := HKEY_LOCAL_MACHINE;  
  if not OpenKey(SApproveKey, True) then Exit;  
  if Register then WriteString(ClsID, Description)  
  else DeleteValue(ClsID);  
  finally  
  Free;  
  end;  
  end;  
   
  const  
  CLSID_CopyHook: TGUID = '{66CD5F60-A044-11D0-A9BF-00A024E3867F}';  
  LIBID_CopyHook: TGUID = '{D2F531A0-0861-11D2-AE5C-74640BC10000}';  
   
  initialization  
  TCopyHookFactory.Create(ComServer, TCopyHook, CLSID_CopyHook,  
  'CR_CopyHook', '文件操作挂钩演示',ciMultiInstance, tmApartment);  
  end.  
  将文件保存为CopyMain.Pas文件,然后编译程序为CopyHook.Dll文件,然后注册CopyHook.Dll文件,你可以使用Windows提供的RegSvr32.exe来注册,注册的方法是在Dos窗口中进入Windows的System子目录,然后在其中输入Regsvr32 x:/xxx/xxx/copyhook.dll ,其中x:/xxx/xxx/是编译的CopyHook.dll所在的全路径名。也可以在Run菜单中选择Register ActiveX Server来注册。  
  当文件注册成功之后,在Windows的Explore中任意改变一个文件夹的名字或者移动一个目录,就会有一个提示框弹出,提示用户是否确定执行操作。如图所示:  
   
   
   
  按“是”将执行文件夹操作,按“否”或者“取消”将取消相应的文件夹操作。  
  上面介绍的只是Delphi实现Windows外壳扩展的一种,参照上面的程序和Delphi关于Windows的COM组件模型的编程,就可以编写出十分专业化的Windows外壳扩展程序

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值