<form id="hz9zz"></form>
  • <form id="hz9zz"></form>

      <nobr id="hz9zz"></nobr>

      <form id="hz9zz"></form>

    1. 明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

      實時偵測目錄中文件變化

      [摘要]在WIN32下用DELPHI偵測目錄變化,可用WIN32提供的文件改變通知API來完成。FindFirstChangeNotification, FindNextChangeNotification...
      在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. 


      日韩精品一区二区三区高清