Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

File Notification using ReadDirectoryChanges API

Posted on 1998-11-04
4
Medium Priority
?
2,729 Views
Last Modified: 2012-06-27
I'm trying to get the ReadDirectoryChangesW call for Win NT to work (it is not supported for Win 95).  Below is the code.  Has anyone implemented it successufully in Delphi?  If so could you post the code?  In the code below, the call to GetQueuedCompletionStatus holds until a file change is made in the c:\temp2 directory.  That's cool, but I can't figure out how to decode the information returned.  The code is based on an example from MSDN.


interface

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

const
  FILE_LIST_DIRECTORY = $0001;
  MAX_PATH = 80;
  MAX_BUFFER = 4096;
type
  PDirectoryInfo = ^TDirectoryInfo;

  PBuffer = ^TBuffer;
  TBuffer = array [0..MAX_BUFFER - 1] of Char;

  TDirectoryInfo = record
    hDir: THandle;
    lpszDirName: array [0..MAX_PATH - 1] of WChar;
    lpBuffer: array [0..MAX_BUFFER - 1] of Char;
    dwBufLength: DWORD;
    Overlapped: POverlapped;
  end;

  PFileNotifyInformation = ^TFileNotifyInformation;
  TFileNotifyInformation = record
    NextEntryOffset: DWord;
    Action: DWord;
    FileNameLength: DWord;
    FileName: WideChar;
  end;

type
  TForm3 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.DFM}

procedure TForm3.Button1Click(Sender: TObject);
var
  ChangeBuffer: PFileNotifyInformation;
  fni: PFileNotifyInformation;
  Info, NumBytes, Offset, LastError: DWord;
  DirHandle, CompletionPort: THandle;
  Overlapped: POverlapped;
  Queue, ReadResult: BOOL;
  BytesReturned: PDWord;
  PFileNotifyInfo: PFileNotifyInformation;
begin
  New(ChangeBuffer);

  New(Overlapped);

  DirHandle := CreateFile(PChar('c:\temp2')
                          , FILE_LIST_DIRECTORY
                          , (FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE)
                          , nil
                          , OPEN_EXISTING
                          , FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED
                          , 0);

  if DirHandle = INVALID_HANDLE_VALUE then begin
    ShowMessage('Unable to get handle to directory c:\temp2');
    exit;
  end;

  try
    CompletionPort := CreateIOCompletionPort(DirHandle, 0, 5, 0);
    try
      SetLastError(0);
      ReadResult := ReadDirectoryChangesW(DirHandle
                           , ChangeBuffer
                           , SizeOf(ChangeBuffer)
                           , LongBool(TRUE)
                           , FILE_NOTIFY_CHANGE_LAST_WRITE
                           , BytesReturned
                           , Overlapped
                           , 0);

      LastError := GetLastError;
      if not ReadResult then begin
        ShowMessage(SysErrorMessage(LastError));
        exit;
      end;

      repeat
        Queue := GetQueuedCompletionStatus(CompletionPort
                                         , NumBytes
                                         , Info
                                         , Overlapped
                                         , INFINITE);
        LastError := GetLastError;
        if not Queue then begin
          ShowMessage(Format('GetQueuedCompletionStatus Error %d', [LastError]));
          exit;
        end;

        if Info > 0 then begin
          fni := ChangeBuffer;
          repeat
            OffSet := byte(fni) + fni^.NextEntryOffset;
            fni:= Ptr(Offset);
          until Offset < 1;
        end;

        ReadDirectoryChangesW(DirHandle
                             , ChangeBuffer
                             , SizeOf(ChangeBuffer)
                             , LongBool(FALSE)
                             , FILE_NOTIFY_CHANGE_LAST_WRITE
                             , BytesReturned
                             , Overlapped
                             , 0);

      until Info < 1;

      Dispose(ChangeBuffer);
    finally
      PostQueuedCompletionStatus(CompletionPort, 0, 0, 0);
    end;
  finally
    CloseHandle(DirHandle);
  end;
end;


end.
0
Comment
Question by:pswenson
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
4 Comments
 
LVL 8

Expert Comment

by:ZifNab
ID: 1345641
what do you want to know?
0
 
LVL 8

Accepted Solution

by:
ZifNab earned 1600 total points
ID: 1345642
pwenson,

 here is a component which already uses this :

 ftp://ftp.is.co.za/programming/delphi/d30free/fngb2401.exe

 Free with source.

 Why making it difficult? :-)

Regards, Zif.
0
 

Author Comment

by:pswenson
ID: 1345643
How did you know the component was at the site?  Is there a directory somewhere?
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1345644
pswenson,

 I was searching for some information about ReadDirectoryChangesW, because I was interested too in this problem. I couldn't find anything usefull, so as last resort I used a searchengine (what normally doesn't help a lot) and by holy there it pointed me out to Delphi Super Page. (Invisible components of D3)

But, DSP has also a search engine. But normally, these specific functions aren't implemented in custom source codes. That's why I didn't checked for components at DSP.

Regards, Zif.
0

Featured Post

Tech or Treat!

Submit an article about your scariest tech experience—and the solution—and you’ll be automatically entered to win one of 4 fantastic tech gadgets.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question