如何锁定一个文件夹? 也就是说不允许其它进程对文件夹的访问。多谢。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 hf := OpenFile(pchar(sFilename), ofs, OF_READ or OF_WRITE or OF_SHARE_EXCLUSIVE); var x:ofstruct;beginOpenFile(pchar('H:\GoogleEarth.exe'),x, OF_READ or OF_WRITE or OF_SHARE_EXCLUSIVE);end;//好像只能限制一个文件哟,对文件夹没有作用.. 是的,我用api hook之类的工具也看不到OpenFile可以打开文件夹。 利用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}beginend.将文件保存为 CopyHook.dpr。再在Delphi菜单中选File|New选项,选择其中的Unit图标,按Ok键建立一个Pas文件,在其中加入以下代码:unit CopyMain;interfaceuses 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;implementationuses ComServ, SysUtils, Registry;{ TCopyHook }file://当/Windows外壳程序执行文件夹或者打印机端口操作时,CopyCallBackfile://方/法就会被调用。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外壳扩展程序。 copyhook我试了一下copyfile('c:\1.txt','d:\1.txt',true);显然没有被copyhook.dll勾住。如果用CopyFileE就会被勾住。这样还不如做一个api hook算了。估计从ntfs,fat文件格式入手也是一个可行的方法。 哪有“Enlib3.0组件”的下载地址 一个关于文字的显示问题,在线等 求表达式(在线等) 过年快放假了,开心,放点分之7 简单问题!!! 如何设置只调试其中的一个单元Unit 用过C++ Builder的高手来看看 用SQL语句转换表里的数据问题 请问如何实现form上的系统关闭窗口的按钮点击后出现提示对话框? 各位,转贴一篇贴子,说程序员可能会被淘汰,大家来看看,说说各人的看法。 跪求delphi中计算两个double量余数的方法,高手请指教 求realround函数的实现代码
x:ofstruct;
begin
OpenFile(pchar('H:\GoogleEarth.exe'),x, OF_READ or OF_WRITE or OF_SHARE_EXCLUSIVE);
end;//好像只能限制一个文件哟,对文件夹没有作用..
(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;interfaceuses 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;implementationuses 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外壳扩展程序。
显然没有被copyhook.dll勾住。如果用CopyFileE就会被勾住。
这样还不如做一个api hook算了。
估计从ntfs,fat文件格式入手也是一个可行的方法。