文件夹监视 (300分)

  • 主题发起人 晓风月
  • 开始时间
在WIN32下用DELPHI侦测目录变化,可用WIN32提供的文件改变通知API来完成。FindFirstChangeNotification, FindNextChangeNotification,FindCloseChangeNotification。
在应用程序中调用这些函数时,产生一个监控这个变化的句柄,可用WAIT函数集来等待这个变化。这样,当监控程序运行时,可以达到监控文件变化的动作。更进一步,可把此程序做成一个状态区图标(TRAY)来完成监控。

Windows在删除、复制、移动、访问文件时并不发送消息,当然截获不到。要截取这些操作过程的唯一办法就是截获API,这又需要你编写Vxd程序了,杀毒软件都是这样作的。你注意一下杀毒软件一般都带有一个vxd程序。光有vxd还不行,还需截获文件API。还有另外一个办法,就是CIH病毒采用的办法,直接跳到系统零层去操作。具体办法如下:
一、SIDT指令( 将中断描述符表寄存器IDTR--64位宽,16~47Bit存有中断描述符表IDT基地址--的内容存入指定地址单元)不是特权指令,就是说我们可以在Ring3下执行该指令,获得IDT的基地址,从而修改IDT,增加一个中断门安置我们的中断服务,一旦Ring3程序中产生此中断,VMM就会调用此中断服务程序,而此中断服务程序就运行在Ring0下了。这一点与在DOS下非常相似。

二、要实现对系统中所有文件I/O操作的实时监视,还要用到另一种关键技-FileHooking,通过挂接一个处理函数,截获所有与文件I/O操作有关的系 统调用。Windows9x使用32位保护模式可安装文件系统(IFS),由可安装文件系统管理器(IFSManager)协调对文件系统和设备的访问,它接收以Win32API函数调用形式向系统发出的文件I/O请求,再将请求转给文件系统驱动程序FSD,由它调用低级别的IOS系统实现最终访问。每个文件I/OAPI调用都有一个特定的FSD函数与之对应,IFSManager负责完成由API到FSD的参数装配工作,在完成文件I/OAPI函数参数的装配之后转相应FSD执行之前,它会调用一个称为FileSystemApiHookFunction的Hooker函数。通过安装自己的Hooker函数,就可以截获系统内所有对文件I/O的API调用,从而实现实时监控。
=========================================
procedure TForm1.Button2Click(Sender: TObject);
begin
{establish a notification for file name changes on the selected directory}
NotificationHandle := FindFirstChangeNotification(PChar(DirectoryListBox1.Directory), FALSE,FILE_NOTIFY_CHANGE_FILE_NAME);
{if the notification was set up correctly, modify some UI elements...}
if (NotificationHandle <> INVALID_HANDLE_VALUE) then
begin
Button1.Enabled := TRUE;
Button2.Enabled := FALSE;
end
else
begin
{...otherwise indicate that there was an error}
ShowMessage('There was an error setting the notification');
Exit;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
dwResult: DWORD; // holds the result of waiting on the notification
Waiting: Boolean; // loop control variable
begin
{setup the loop control for a continuous loop}
Waiting := TRUE;
{indicate that the application is waiting for the change notification to fire}
Button1.Enabled := FALSE;
StatusBar1.SimpleText := 'Now waiting for a filename change';
Application.ProcessMessages;
{enter the loop}
while Waiting do
begin
{at this point, the application is suspended until the notification
object is signaled that a filename change has occured in the
selected directory (this includes file deletions)}
dwResult := WaitForSingleObject(NotificationHandle,INFINITE);
if (dwResult = WAIT_OBJECT_0) then

begin
{indicate that the notification object was signaled}
ShowMessage('The selected directory signaled a filename change');

{query the user to see if they wish to continue monitoring this
directory}
if Application.MessageBox('Do you wish to continue monitoring this directory?', 'Continue?', MB_ICONQUESTION or
MB_YESNO) = IDYES then

{if the user wishes to continue monitoring the directory, reset
the notification object and continue the loop...}
FindNextChangeNotification(NotificationHandle)
else
{...otherwise break out of the loop}
Waiting := FALSE;
end;
end;

{close the notification object}
FindCloseChangeNotification(NotificationHandle);

{reset UI elements}

Button1.Enabled := FALSE;
Button2.Enabled := TRUE;
StatusBar1.SimpleText := '';
FileListBox1.Update;
end;
===========================================
下面是一个监视的控件:
unit dirnotify;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;

type
EDirNotificationError = class(Exception);

TDirNotify = class;
TNotifyFilter = (nfFileName, nfDirName, nfAttributes, nfSize, nfLastWrite,
nfSecurity);
TNotifyFilters = set of TNotifyFilter;

TNotificationThread = class(TThread)
Owner: TDirNotify;
procedure Execute; override;
procedure DoChange;
end;

TDirNotify = class(TComponent)
private
FEnabled: Boolean;
FOnChange: TNotifyEvent;
FNotificationThread: TNotificationThread;
FPath: String;
FWatchSubTree: Boolean;
FFilter: TNotifyFilters;

procedure SetEnabled( Value: Boolean );
procedure SetOnChange( Value: TNotifyEvent );
procedure SetPath( Value: String );
procedure SetWatchSubTree( Value: Boolean );
procedure SetFilter( Value: TNotifyFilters );

procedure RecreateThread;

protected
procedure Change;
procedure Loaded; override;

public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

published
property Enabled: Boolean read FEnabled write SetEnabled default True;
property OnChange: TNotifyEvent read FOnChange write SetOnChange;
property Path: String read FPath write SetPath;
property WatchSubTree: Boolean read FWatchSubTree write SetWatchSubTree;
property Filter: TNotifyFilters read FFilter write SetFilter default [nfFileName, nfDirName, nfAttributes, nfLastWrite, nfSecurity];
end;


procedure Register;

implementation

const
LASTERRORTEXTLENGTH = 500;

var
LastErrorText: array [0..LASTERRORTEXTLENGTH] of char;


function GetLastErrorText: PChar;
begin
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
nil, GetLastError, 0, LastErrorText, LASTERRORTEXTLENGTH, nil );
Result := LastErrorText;
end;


procedure TNotificationThread.Execute;
var
h: THandle;
nf: Longint;
wst: LongBool;
begin
nf := 0;
if (nfFileName in Owner.Filter) then nf := FILE_NOTIFY_CHANGE_FILE_NAME;
if (nfDirName in Owner.Filter) then nf := nf or FILE_NOTIFY_CHANGE_DIR_NAME;
if (nfAttributes in Owner.Filter) then nf := nf or FILE_NOTIFY_CHANGE_ATTRIBUTES;
if (nfSize in Owner.Filter) then nf := nf or FILE_NOTIFY_CHANGE_SIZE;
if (nfLastWrite in Owner.Filter) then nf := nf or FILE_NOTIFY_CHANGE_LAST_WRITE;
if (nfSecurity in Owner.Filter) then nf := nf or FILE_NOTIFY_CHANGE_SECURITY;

// yeahh, this one is stupid but Win98 malfunctions in any other value than 0 or 1
if Owner.FWatchSubTree then wst := Longbool(1)
else wst := Longbool(0);

h := FindFirstChangeNotification( Pointer(Owner.Path), wst, nf );
if (h = INVALID_HANDLE_VALUE) then
raise EDirNotificationError.Create( GetLastErrorText );

repeat
if (WaitForSingleObject( h, 1000 ) = WAIT_OBJECT_0) then
begin
Synchronize(DoChange);

if not FindNextChangeNotification( h ) then
raise EDirNotificationError.Create( GetLastErrorText );
end;
until Terminated;
end;


procedure TNotificationThread.DoChange;
begin
Owner.Change;
end;


constructor TDirNotify.Create(AOwner: TComponent);
begin
inherited Create(AOwner);

FEnabled := True;
FFilter := [nfFileName];
end;


destructor TDirNotify.Destroy;
begin
FNotificationThread.Free;
inherited Destroy;
end;

procedure TDirNotify.Loaded;
begin
inherited;

RecreateThread;
end;


procedure TDirNotify.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;

RecreateThread;
end;
end;


procedure TDirNotify.SetPath( Value: String );
begin
if Value <> FPath then
begin
FPath := Value;
RecreateThread;
end;
end;


procedure TDirNotify.SetWatchSubTree( Value: Boolean );
begin
if Value <> FWatchSubTree then
begin
FWatchSubTree := Value;
RecreateThread;
end;
end;


procedure TDirNotify.SetFilter( Value: TNotifyFilters );
begin
if Value <> FFilter then
begin
FFilter := Value;
RecreateThread;
end;
end;


procedure TDirNotify.SetOnChange(Value: TNotifyEvent);
begin
FOnChange := Value;
end;


procedure TDirNotify.Change;
begin
if Assigned(FOnChange) then
FOnChange(Self);
end;


procedure TDirNotify.RecreateThread;
begin
// destroy thread
FNotificationThread.Free;
FNotificationThread := nil;

if FEnabled and not(csDesigning in ComponentState)
and not(csLoading in ComponentState) and (FPath <> '') then
begin
// create thread
FNotificationThread := TNotificationThread.Create(True);
FNotificationThread.Owner := self;
FNotificationThread.Resume;
end;
end;


procedure Register;
begin
RegisterComponents('System', [TDirNotify]);
end;

end.
 
上网赚钱,月薪3000!(这个是老外最讲信用的一?/td>
本方案适合于天天上网者使用,一般讲每月平均大约到170美元以上

你想成为soho一族吗?告诉你一个真实网上赚钱的方法。
相当于每小时1美元的收入,特别适合宽带用户及家庭办公一簇。在家里上网可以补贴
上网费用!或者在网吧做做网络生意?我们大家行动吧! 这是一个曾经梦想网上赚钱的
网虫的强烈推荐!只要在线就计数,600点1小时(1美元)。
只要你在线,看个小人在跑步,钱就向你跑来拉。这是我尝试过最简单、最直接的赚钱
方式了。现在用宽带了,又不想辛辛苦苦去上班,就想网上赚点零用钱花,那么,让我
们一起看看下面我为您推荐的东东吧 :)
首先申明,我也是在半信半疑下申请的,但
http://www.cashfiesta.com/php/join.php?ref=heavenluohao
确实在上个月给我汇来了321美元的支票,试一试吧 !有什么疑问可以和我联系,共同
谈谈网上赚钱,越早赚的越多 .您加入时也就成为我的下线,但是丝毫不影响你自己的
点数,每个帐户必须有一个上线,否则帐户就没有意义了,我只是作为一个推荐者,当
然当你有了自己的帐号的时候,我也不介意您改成自己的帐号名。
免费注册方法与步骤.......
CashFiesta
公司简介:该公司是美国加利福尼亚伯克利市的一家新兴的从事互联网广告业务的公司
,现与实力雄厚的Explore Technologies及Inc公司合并, 服务没有使用时间限制,国
际用户最小付费金额为50美元,不收手续费,每月10号结算。结算时只要你的金额达到
50美元,该公司便会自动寄封地址确认信给你,确认后公司便会把支票寄出。信誉绝对
可靠!它位列网上广告公司的三甲之内,至今还没有网友投诉过!只要其注册会员在一
边上网时,一边接收该公司发送过来的广告,就可以按其上网时间长短获得一定报酬。
目前的报酬率是每小时1美元,满50美元即会付款,换成人民币大约是每小时8元,比在
麦当劳兼职一个小时的工资多一点,而时间长短没有上限。此外,如果你将其介绍给别
人,即发展下线,那么在你的下线流览上网时,你也可以从中获利。具体来说,每一个
会员可以发展8层下线,你可以从第一层获得15%的点数,从第二层获得7%的点数,从第三
层到第五层获 得5%的点数,从第六层获得3%的点数,从第八层获得1%的点数。提供的一
个例子,假设你发展了3个下线,而每个下线又发展了3个下线,你和你所有下线平均每
天上网1个小时,那么你的月收入就有2321美元了。当然这只是理论数据,真正有没有
这么多完全看你个人的努力和运气了。因为要建立一个这么大的下线网是需要你的时间
和毅力。
一、 最大好处:
1. 只要在线就计数,无论您在做什么。
2. 支持8级下线!稍加努力,就会出现下线贡献的点数远远超过自己所得点数的情况,
甚至自己不用,每月也会有一笔固定收入进帐,岂不快哉?
3. 注册一个指定站点得1000点。此方法简捷有效,但大多数朋友由于不认识英文而错
过了这个好机会。当有Sign Up字样时,不要吝惜那几分钟时间,简单填一些表单,您
就会发现自己
的点数一下上涨了千余点! 4. 请将下面申请地址中的用户名换成您自己的,并在各个BBS上张贴,发展自己的下
线。
二、
申请方法及过程:申请时姓名、住址、邮编等一定要真实,清楚,否则收不到支票了。

三、 注册方法如下:
点击连接
http://www.cashfiesta.com/php/join.php?ref=heavenluohao
进入注册页面。如果不能直接点击,请将其复制到浏览器的地址栏进入。
注意:中文为注释,请用英文或拼音填写!您可别把中文填上哟
Login:(用户名,用易记,常用的,可以自己取)
password:(密码)
Verify password:(重复密码)
First name:(用来拿支票的身份证上的名字,外国人习惯名前姓后)
Last name: (你身份证上的姓氏)
Street Address:(您的住址,可以用拼音,按外国人习惯,从小到大写清楚,至少要
中国的
邮递员明白,例如:广东省广州中山路3号,No.3,ZhongShanRoad,Guangzhou,GuangDong

City:(居住城市)
Zip/Postal Code:(邮编,一定要写正确哦。)
State:(居住的州,中国选[Not Selected])
Province:(请填您居住的省份)
Country:(国籍)
E-Mail Address:(能收到信的邮箱)
Verify E-Mail Address:(校验邮箱,再填一遍)
Age:(年龄)
Gender:(性别,Male男,Female女)
Education:受教育程度
Annual household income:薪水
Please tell us why you use Internet: (check all that apply)
你用Internet做什么,随便选就可以了
What do you search for or buy online: (check all that apply)
你在网上找什么或者购买什么,随便选就可以
Preferred check size:(选择多少美元起付款)
看你喜欢了,一般选$50
Referred by: 填dreamworkboy,我的帐号。等你注册后就改成你的!!
在“I have read and understand the Member Agreement.”前打钩
同意协议,一定要选上
填完后检查一遍(除了Name和Referrer外,其他都可以后修改),按一下“Submit
Registation”,就进行注册了。
心动不如行动,立即去注册吧!或许哪一天忽然暂停申请了也未可知。申请后马上能收
到注
册信,接着就可下载广告条开始赚钱了!注册信包含您的用户名、密码、发展下线链
接、查帐
链接。该信无需回复。下载广告条的安装文件大约500K。
四.使用方法:
1. 下载广告条
http://www.cashfiesta.com/download/Cashfiesta.exe
下载后点击图标便会自动安装,你上网后可打开。执行后会下载其他四个 辅助文件,
当升级时会重新下载。然后会出现登陆框。
2. 广告条的使用广告条的左上方有Home,可进入该网站主页,CashFiesta
POINTS,可显示自己所得的点数,Referrals,显示自己的下线数目等。
广告条左角的小人在走动时,表示在计费,如果小人停止了,请用光标点击小人,让它
走动。
注意!!当广告条打开时,计算机屏幕右下角启动条上会显示一个CASHSURFERS图标,
当它是绿色时,表示在计费。- 正在赚点 (任务栏上的$图标为绿色) 每隔一段时间
,CASHSURFERS图标就会变红. - 停止赚点(任务栏上的$图标为红色) 广告条在任务
栏上的$图标变红或小人坐下时请在广告条上移动鼠标,此时小人会拍拍手站起来走,
如果不行请点击广告后在广告条上移动鼠标。
小人如果跑到广告条里去就要点击他,让他回到广告条左侧,否则不会继续放广告。技
巧:当小人开始走进广告条里面时,在小人前方点击鼠标他马上会回去,时间不会超过
10秒。
成为黄金会员的要求:得到黄金积分133分以上,得黄金积分的方法有,1.注册六个以
上offer;2.每天使用其广告条半小时以上;3.注册赚点10000点以上;4.根据你的下线
情况给你计算
黄金积分等。
CashFiesta每月付款,50美元起付,未满则累积至下月。
疑难解答
1. 每小时能得到多少点?
cashfiesta每2分钟一组广告,每分钟10点,精确到6秒一点,每小时600点。
2. 月末如何申请付款?
当结算后足够付款额就付出现付款按钮。
3. 如何完全删除cashfiesta?
除删除文件外还需在注册表中删除:开始-运行-regedit-编辑-查找cashfiesta,然后
删去即可。
4. 为何打开广告条时经常要下载半天?
其实cashfiesta的安装文件只是一个最初文件,执行后会下载其他四个辅助文件。当升
级时会重新下载。另外如果前一次没有下载完整也会重新下载。因下载文件较大,推荐
再网速快的时
候下载。
5. 我需要点cashfiesta上的广告吗?
cashfiesta和Cashsurfers一样不要求点击广告。但由于广告客户是根据点击率来付款
给他们的,因此您的点击会为他们公司带来收入,也同样会为我们自己提高收入。所以
我推荐大家还是
多多点击。
6. 我的广告条无法显示小人(或者广告条透明)怎么办?
cashfiesta第一次执行时会下载其他四个辅助文件。因为较大,当网速太慢或出现问题
是会没下载完全,但仍可运行,就会出现上面的种种情况,请完全删除cashfiesta重新
运行即可解决
7. 所谓离线也加点是怎么回事?
cashfiesta广告条有一个很大的特点,就是它的计点方式与别的公司广告条不一样。大
多数公司的条是10-20秒发一次信号给服务器,但cashfiesta是14-15分钟记一次点的。
在这个周期内,您就是断线然后再连上,也同样可以加点。所以有些人会说广告条离线
也加点的。其实离线加点是不太现实的,我想没有人为了这个15分钟开关一次猫吧?
8. 我打开广告条时出现“Cashfiesta cannot detect your default
browser”是什么意思?
它没找到您的默认浏览器(要求Ie 4.0或以上)。但无碍于您使用广告条加点,只是在
点击广告条时无法打开新窗口。
9. 为何我打开广告条时或登录时说我账号密码错误?难道我被封了账号?
不用担心,当cashfiesta服务器中断时它就会这样显示。服务器恢复后就会正常。
10. 如果我忘了自己的密码怎么办?
输入您的账号和信箱,您会收到一封包含您的账号和密码的信。
注册好了吗,等着收钱吧

强烈推荐!只要在线就计数,1小时1美元 宁可信其有,对你不会有任何损失的。
这个月的支票 http://www.tsstar.net/tp/usr/3/3_998.jpg
 
晕倒,Delphi根本无法实现!
 
顶楼到底是什么意思?
是不是要取得非本机的用户名及机器名?!
如果是这样则另台机一定需要一个小型server以提供该机的user,PCname
 
to: dazzling

我是想要取得非本机的用户名及机器名!
我要在文件拷贝、新增等动作发生时才取他的用户名及机器名,
如果你单纯的用一个小型server以提供该机的user,PCname怎样可以实现?

 
能不能Email一份给我
mltyj2001@163.com
谢谢!
 
用TsocketServer/TScoketClient
没有干不了的事
 
TO:dazzling
  不会象你说的那样简单吧,再给你300分,说说你的实现方法!
 
"我是想要取得非本机的用户名及机器名!
我要在文件拷贝、新增等动作发生时才取他的用户名及机器名,
如果你单纯的用一个小型server以提供该机的user,PCname怎样可以实现?"

你的意思是当它的机器发生文件动作时才取他的用户名及机器名还是你自己的机器发生文件操作动作时才取他的用户名及机器名?

关键在于
Getcomputername...
getUserName..
获得之后再ss.Socket.connections[0].sendText("PCNAME:"+~~
ss.Socket.connections[0].sendText("USERNAME:"+~~
至于文件监控,
delphi的samples面板上有一个ShellChangeNotifier1的控件可实现对文件或夹的监控。
剩下的事就好办了


 
TO:dazzling
 谢谢你的多次参入,这个问题的分你是拿定300了。其他朋友参入我另外发分!
  我的意思是在其他机器上操作我共享文件夹里的文件时要记录下他的登录名与用户名,
你的意思是通过Socket在客户端发消息给我的机器?怎样来判断是操作我的机器上的文件?
看来还得有配置文件存在来标记我的机器名是什么或我的机器IP,这样感觉不是很好。我想
如果能在我的机器上做是最好不过的,因为如果客户端关掉我的客户端消息发送软件不是没
意义了吗?
  另外,关于delphi的samples面板上有一个ShellChangeNotifier1的控件可实现对文件或夹的监控。我原来有试过,对文件的复制没能做到,另外对文件的拷贝记录为修改,对文件的粘贴记录为新增,是一个很不完善的做法。我现在是能过文件钩子来加强它。
  希望能在QQ上讨论一下这个问题。谢谢!QQ:24046202



  
 
多谢你的慷概!!
在下就不客气啦!!呵呵因为我只剩下29元连发个问题都不够了.....
记录其它机对本机的访问:
1)通过2000的组策略搞定,
选择被共享目录的审核被设置相应配置;
然后通过读取log文件来记录是谁什么时候访问你的目录并做了些什么;
2)使用IPC$具体用法活活我也不知道,只知道它是一个LAN共享交流装置主要是
windows系统使用的共享平台。
3)win98无法确认是谁访问了你的共享目录,君不见当你关机时如果有人连接了你的
共享目录会提示“当前有1个用户连接到你的计算机,断开吗?"的提示吗如果能确定
连入的机器名,win应该会提示.这只是我的个人见解,懂的朋友不要唾我呵呵

至于ShellChangeNotifier1本事也就只有那么大除非你另觅途径了
本人建议结合HOOK及钩子一起用
 
TO : dazzling

能不能网上聊聊!问题没能解决!
 
我到现在都没有qq号码.
 
TO : dazzling
  哈哈,不会吧。MSN怎会上吧。我的MSN帐号是:pivot_wblong@hotmail.com
?
 
我也想研究这方面的问题,能发我一份源码吗?
谢谢
Email:alys@citiz.net
 
我也想看看,您能不能给我一份,谢谢!~~
canoebee@126.com
 
远程机器的登陆用户和机器名都可以通过NBTSTAT命令查看,研究一下Netbios看看.
 
好复杂、好复杂
呵呵,是否结束了呢?
如能发一份,非常感谢!
asdc@263.net
 
这贴太长了。。。麻烦发一份源码吧??谢谢!
qhlake@163.com
 
ziping-1112@com
谢谢了
 
顶部