to duz:
 
      我试了,不灵啊!

解决方案 »

  1.   

    我想打开一个路径, 即OPEN_EXISTING,其它参数如何设置?
      

  2.   

    creatfile('e:\aa.txt',generic_read or generic_write,0,nil,open_existing,
              file_attribute_normal or file_flag_overlapped,0);
      

  3.   

    to hawk_js:
           我想监视对硬盘一个路径的访问,想取得该路径的文件句柄,不是打开一个文件。
    代码如下:
    unit Unit1;interface{ ========================== DIR EVENTS MONITORING =============================  == Overview ==  This form demonstrates the use of ReadDirectoryChangesW API function  The function can be used either in synchronous or asynchronous mode.
      Here I implemented the asynchronous mode (ie: function returns immediatly
      and you have to watch for events). There are 3 ways to get results:
      a. call the function with a callback proc that the system calls when an event occurs
      b. associate the directory with an IOCompletionPort that "traps" IO events (that's what I did)
      c. create an Event, wait for it and call GetOverlapped Result  For more information on synchronous calls or on the 2 other asynchronous implementations refer to MSDN  == Implementation notes ==  I assume anyone willing to use this code will have sufficient knowledge of
      basic API Calls so I won't comment on threads, API Structures etc...  I implemented a very basic call to SHBrowseForFolder. If you're interested
      refer to MSDN or download Brad Stower's components at www.delphifreestuff.com  OK, Now we get to the bottom of things.
      Like much of the APIs, Monitoring is quite simple once you know how to get it to work !  First you have to open the directory you want to monitor. Use CreateFile in
      FILE_LIST_DIRECTORY mode and with FILE_FLAG_BACKUP_SEMANTICS privilege.
      Note that you have to add FILE_FLAG_OVERLAPPED for asynchronous operations.  Then create an IOCompletionPort with the directory handle.
      If you open multiple directories, you can reuse the same port, simply
      specify a different cookie for each dir.  Third Call ReadDirectoryChangesW with an empty Overlapped struct and no
      callback proc (asynchronous b method, see overview)  Then wait for events using GetQueuedCompletionStatus. Upon event fire ReadDirectoryChangesW
      again and loop.  Here you have mulmtiple implementation choices. Either you give a TimeOut to GetQueuedCompletionStatus
      and check whether it returned sth or (what I did) you call it in a thread with INFINITE wait time
      In this alternative, post an empty completion status to stop the thread; see PostQueuedCompletionStatus
      call in bStopClick method  When you are finished, release all dir handles and IOCompletionPort with CloseHandle  Events are written as continous TFileNotifyInformation records in a buffer you provide.  >>Important Note<<
      FBytesWritten is not updated by asynchronous calls to ReadDirectoryChangesW
      Thus, don't rely on it for buffer parsing. Rather use the NextEntryOffset which
      is set to 0 for the last record.  == Release Notes ==  This code has been tested with delphi 3.02 running on Windows NT4 SP6
      It should work on all Windows NT platforms, though I haven't tested it under
      Windows NT 3.51 or Windows 2000.  I don't known whether it works under Win9x or not.
      Eventually, it may be kind of you to let me know if you run some tests  You shouldn't have much trouble compiling it with Delphi 2/4/5+ and C++ port is quite easy
      
      Damien Thouvenin  (mailto:[email protected])
    }
    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, ExtCtrls, Buttons;type
      TForm1 = class(TForm)
        lbEvents: TListBox;
        Panel1: TPanel;
        Label1: TLabel;
        ePath: TEdit;
        CJLabel1: TLabel;
        bStart: TButton;
        bStop: TButton;
        ckWatchSubTree: TCheckBox;
        GroupBox1: TGroupBox;
        ckMonitorFileName: TCheckBox;
        ckMonitorDirName: TCheckBox;
        ckMonitorAttributes: TCheckBox;
        ckMonitorSize: TCheckBox;
        ckMonitorLastWrite: TCheckBox;
        ckMonitorSecurity: TCheckBox;
        ckMonitorCreationDate: TCheckBox;
        ckMonitorLastAccess: TCheckBox;
        SpeedButton1: TSpeedButton;
        procedure bStartClick(Sender: TObject);
        procedure bStopClick(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure ePathDblClick(Sender: TObject);
      private
        { D閏larations priv閑s }
        FDirectoryHandle: THandle;
        FNotificationBuffer: array[0..4096] of Byte;
        FWatchThread: TThread;
        FNotifyFilter: DWORD;
        FOverlapped: TOverlapped;
        FPOverlapped: POverlapped;
        FBytesWritten: DWORD;
        FCompletionPort: THandle;
      public
        { D閏larations publiques }
      end;var
      Form1: TForm1;type
      PFileNotifyInformation = ^TFileNotifyInformation;
      TFileNotifyInformation = record
        NextEntryOffset: DWORD;
        Action: DWORD;
        FileNameLength: DWORD;
        FileName: array[0..0] of WideChar;
      end;const
      FILE_LIST_DIRECTORY   = $0001;const
      SAction: array[FILE_ACTION_ADDED..FILE_ACTION_RENAMED_NEW_NAME] of String =
      ( 'ADDED %s',
        'DELETED %s',
        'MODIFIED %s',
        'RENAMED %s [...]',
        '[...] into %s');implementation{$R *.DFM}uses
      ShlObj, ActiveX;type
      TWaitThread = class(TThread)
      private
        FForm: TForm1;
        procedure HandleEvent;
      protected
        procedure Execute; override;
      public
        constructor Create(Form: TForm1);
      end;constructor TWaitThread.Create(Form: TForm1);
    begin
      inherited Create(True);
      FForm := Form;
      FreeOnTerminate := False;
    end;procedure TWaitThread.HandleEvent;
    var
      FileOpNotification: PFileNotifyInformation;
      Offset: Longint;
    begin
      with FForm do
      begin
        Pointer(FileOpNotification) := @FNotificationBuffer[0];
        repeat
          Offset := FileOpNotification^.NextEntryOffset;
          lbEvents.Items.Add(Format(SAction[FileOpNotification^.Action], [WideCharToString(@(FileOpNotification^.FileName))]));
          PChar(FileOpNotification) := PChar(FileOpNotification)+Offset;
        until Offset=0;
      end;
    end;procedure TWaitThread.Execute;
    var
      numBytes: DWORD;
      cbOffset: DWORD;
      CompletionKey: DWORD;
    begin
      while not Terminated do
      begin
        GetQueuedCompletionStatus( FForm.FCompletionPort, numBytes, CompletionKey, FForm.FPOverlapped, INFINITE);
        if CompletionKey <> 0 then
        begin
          Synchronize(HandleEvent);
          with FForm do
          begin
            FBytesWritten := 0;
            ZeroMemory(@FNotificationBuffer, SizeOf(FNotificationBuffer));
            ReadDirectoryChanges(FDirectoryHandle, @FNotificationBuffer, SizeOf(FNotificationBuffer), ckWatchSubTree.Checked, FNotifyFilter, @FBytesWritten, @FOverlapped, nil);
          end;
        end
        else
          Terminate;
      end;
    end;procedure TForm1.bStartClick(Sender: TObject);
    begin
      FNotifyFilter := 0;
      if ckMonitorFileName.Checked then
        FNotifyFilter := FNotifyFilter or FILE_NOTIFY_CHANGE_FILE_NAME;
      if ckMonitorDirName.Checked then
        FNotifyFilter := FNotifyFilter or FILE_NOTIFY_CHANGE_DIR_NAME;
      if ckMonitorAttributes.Checked then
        FNotifyFilter := FNotifyFilter or FILE_NOTIFY_CHANGE_ATTRIBUTES;
      if ckMonitorSize.Checked then
        FNotifyFilter := FNotifyFilter or FILE_NOTIFY_CHANGE_SIZE;
      if ckMonitorLastWrite.Checked then
        FNotifyFilter := FNotifyFilter or FILE_NOTIFY_CHANGE_LAST_WRITE;
      if ckMonitorLastAccess.Checked then
        FNotifyFilter := FNotifyFilter or FILE_NOTIFY_CHANGE_LAST_ACCESS;
      if ckMonitorCreationDate.Checked then
        FNotifyFilter := FNotifyFilter or FILE_NOTIFY_CHANGE_CREATION;
      if ckMonitorSecurity.Checked then
        FNotifyFilter := FNotifyFilter or FILE_NOTIFY_CHANGE_SECURITY;
      if FNotifyFilter = 0 then
      begin
         ShowMessage('Vous devez monitorer au moins 1 関閚ement !');
         exit;
      end;
      lbEvents.Clear;
      FDirectoryHandle := createfile('c:\a.txt',generic_read or generic_write,0,nil,open_existing,
              file_attribute_normal or file_flag_overlapped,0);
     { FDirectoryHandle := CreateFile('c:\',//PChar(ePath.Text),
        GENERIC_READ,// or GENERIC_WRITE,//FILE_LIST_DIRECTORY,
        0,// or FILE_SHARE_WRITE,// or FILE_SHARE_DELETE,
        nil,
        OPEN_EXISTING,
        0,//FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED, //FILE_FLAG_BACKUP_SEMANTICS or
        0);
      }if FDirectoryHandle = INVALID_HANDLE_VALUE then
      begin
        beep;
        FDirectoryHandle := 0;
        ShowMessage(SysErrorMessage(GetLastError));
        exit;
      end;
      FCompletionPort := CreateIoCompletionPort(FDirectoryHandle, 0, Longint(pointer(self)), 0);
      ZeroMemory(@FNotificationBuffer, SizeOf(FNotificationBuffer));
      FBytesWritten := 0;
      if not ReadDirectoryChanges(FDirectoryHandle, @FNotificationBuffer, SizeOf(FNotificationBuffer), ckWatchSubTree.Checked, FNotifyFilter, @FBytesWritten, @FOverlapped, nil) then
      begin
        CloseHandle(FDirectoryHandle);
        FDirectoryHandle := 0;
        CloseHandle(FCompletionPort);
        FCompletionPort := 0;
        ShowMessage(SysErrorMessage(GetLastError));
        exit;
      end;
      ePath.Enabled := False;
      bStart.Enabled := False;
      bStop.Enabled := True;
      FWatchThread := TWaitThread.Create(self);
      TWaitThread(FWatchThread).Resume;
    end;procedure TForm1.bStopClick(Sender: TObject);
    begin
      if FCompletionPort = 0 then
        exit;
      PostQueuedCompletionStatus(FCompletionPort, 0, 0, nil);
      FWatchThread.WaitFor;
      FWatchThread.Free;
      CloseHandle(FDirectoryHandle);
      FDirectoryHandle := 0;
      CloseHandle(FCompletionPort);
      FCompletionPort := 0;
      ePath.Enabled := True;
      bStart.Enabled := True;
      bStop.Enabled := False;
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
      bStop.Click;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      FCompletionPort := 0;
      FDirectoryHandle := 0;
      FPOverlapped := @FOverlapped;
      ZeroMemory(@FOverlapped, SizeOf(FOverlapped));
    end;procedure TForm1.ePathDblClick(Sender: TObject);
    var
      SelectionPIDL: PItemIDList;
      BrowseInfo: TBrowseInfo;
      ShellAllocator: IMalloc;
      PathBuffer: array[0..MAX_PATH] of Char;
    begin
      // simplest implementation of BrowseForFolder
      // to get more information refer to MSDN Library or Check Brad Stower's excellent site www.delphifreestuff.com
      ZeroMemory(@BrowseInfo, SizeOf(BrowseInfo));
      BrowseInfo.hwndOwner := Handle;
      BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS;
      CoInitialize(nil);
      try
        SelectionPIDL := ShBrowseForFolder(BrowseInfo);
        if SelectionPIDL <> nil then
        try
          ZeroMemory(@PathBuffer, SizeOf(PathBuffer));
          if not SHGetPathFromIDList(SelectionPIDL, @PathBuffer) then
          begin
            beep;
            exit;
          end;
          ePath.Text := StrPas(@PathBuffer[0]);
        finally
          if SHGetMalloc(ShellAllocator) = 0 then
          begin
            ShellAllocator.Free(SelectionPIDL);
            ShellAllocator := nil;
          end;
        end;
      finally
        CoUnInitialize;
      end;
    end;end.在NT下这些代码没问题,98下通不过。