Thema: Delphi Festplattenzugriffe

Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#39

Re: Festplattenzugriffe

  Alt 1. Sep 2006, 13:15
So, dann mach ich auch mal mit ... irgendwas stimmt wohl wirklich mit den Befehlen nicht.

In diesem Code (ist im Grunde vom Aufbau her wie der Erste hier im Thread) reagiert Find*ChangeNotification/WaitForSingleObject sehr oft auf Änderungen (aber auch nicht immer), wobei ReadDirectoryChangesW entweger garnichts zurückgibt und die Ausführung dort zum Stehen kommt, oder ebenfalls nur die letzte Änderung ankommt.
Delphi-Quellcode:
Function DCSourceChangesThread(DC: TDirectoryCompare): LongWord; StdCall;
  Const BufferSize = 4096{65536};

  Var DH, NH: THandle;
    Buffer, P: PWideChar;
    Name: Widestring;
    Status: TDCObjStatus;
    i: Integer;
    W: LongWord;

  Label LExit;

  Begin
    Result := 0;
    DH := CreateFileW(PWideChar(Copy(DC._SourceRoot, 1, Length(DC._SourceRoot) - 1)), GENERIC_READ or FILE_LIST_DIRECTORY,
      FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
    NH := FindFirstChangeNotificationW(PWideChar(Copy(DC._SourceRoot, 1, Length(DC._SourceRoot) - 1)),
      True, FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME or FILE_NOTIFY_CHANGE_ATTRIBUTES or
      FILE_NOTIFY_CHANGE_SIZE or FILE_NOTIFY_CHANGE_LAST_WRITE or FILE_NOTIFY_CHANGE_CREATION);
    Buffer := GetMemory(BufferSize);
    If (DH <> INVALID_HANDLE_VALUE) and (NH <> INVALID_HANDLE_VALUE) and (Buffer <> nil) Then
      Repeat
        If (DC._DestChangesThread = INVALID_HANDLE_VALUE) or (DC._Pause = 2) Then GoTo LExit;
        Case WaitForSingleObject(NH, 1000) of
          WAIT_FAILED: Break;
          WAIT_OBJECT_0:
            If ReadDirectoryChangesW(DH, Buffer, BufferSize, True, FILE_NOTIFY_CHANGE_FILE_NAME
              or FILE_NOTIFY_CHANGE_DIR_NAME or FILE_NOTIFY_CHANGE_ATTRIBUTES or FILE_NOTIFY_CHANGE_SIZE
              or FILE_NOTIFY_CHANGE_LAST_WRITE or FILE_NOTIFY_CHANGE_CREATION, @W, nil, nil) Then Begin
              P := Buffer;
              Repeat
                SetLength(Name, PFileNotifiInformation(P)^.FileNameLength div 2);
                Move(PFileNotifiInformation(P)^.FileName, Name[1], PFileNotifiInformation(P)^.FileNameLength + 1);
                Case PFileNotifiInformation(P)^.Action of
                  FILE_ACTION_ADDED: Status := [dcsDeleted];
                  FILE_ACTION_REMOVED: Status := [dcsCreated];
                  FILE_ACTION_MODIFIED: Status := [dcsSize..dcsLastWriteTime, dcsContent..dcsAttrEncrypted];
                  FILE_ACTION_RENAMED_OLD_NAME: Status := [dcsName];
                  FILE_ACTION_RENAMED_NEW_NAME: Status := [dcsName];
                  Else Status := [dcsSize..dcsAttrEncrypted];
                End;
                Lock(DC._Lock);
                i := High(DC._SourceChangesList);
                While i >= 0 do
                  If WideSameText(DC._SourceChangesList[i].Name, Name) Then Break
                  Else Dec(i);
                If i < 0 Then Begin
                  i := Length(DC._SourceChangesList);
                  SetLength(DC._SourceChangesList, i + 1);
                  DC._SourceChangesList[i].Name := Name;
                  //UniqueString(DC._SourceChangesList[i].Name); // WideString/OLE-String is always an UniqueString.
                  DC._SourceChangesList[i].Changes := [];
                End;
                DC._SourceChangesList[i].Changes := DC._SourceChangesList[i].Changes + Status;
                DC._SourceChangesList[i].Time := GetTickCount;
                Unlock(DC._Lock);
                P := Buffer + PFileNotifiInformation(P)^.NextEntryOffset;
              Until PFileNotifiInformation(P)^.NextEntryOffset = 0;
            End Else Break;
        End;
      Until not FindNextChangeNotification(NH);
    DC._CallStatusProc(dcsErrorSourceDirChangesThread, '', Integer(DC));

    LExit:
    FreeMemory(Buffer);
    FindCloseChangeNotification(NH);
    CloseHandle(DH);
    LockedSet(DC._SourceChangesThread, INVALID_HANDLE_VALUE);
  End;
Probleme mit dem Dateizugriff sollte es nicht geben, da hier nicht auf die Dateien zugegriffen wird, dieses würde erst Zeitversetzt ein einem anderem Thread geschehen.
$2B or not $2B
  Mit Zitat antworten Zitat