AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi 2 Verzeichnisse physikalisch identisch? NTFS-Hardlinks!
Thema durchsuchen
Ansicht
Themen-Optionen

2 Verzeichnisse physikalisch identisch? NTFS-Hardlinks!

Offene Frage von "blackdrake"
Ein Thema von blackdrake · begonnen am 22. Apr 2009 · letzter Beitrag vom 27. Apr 2009
Antwort Antwort
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#1

2 Verzeichnisse physikalisch identisch? NTFS-Hardlinks!

  Alt 22. Apr 2009, 22:16
Hallo.

Ich möchte gerne herausfinden, ob zwei Verzeichnisse physikalisch identisch sind.

Bis jetzt habe ich folgenden Code:

Delphi-Quellcode:
{$DEFINE CHECK_UNC}

function ExpandFilePath(AFileName: string): string;
begin
  {$IFDEF CHECK_UNC}
  result := ExpandUNCFileName(AFileName);
  {$ELSE}
  result := ExpandFileName(AFileName);
  {$ENDIF}
end;

function AreFilesOrDirectoriesIdentical(A, B: string): boolean;
begin
  A := ExpandFilePath(A);
  B := ExpandFilePath(B);

  // Damit C:\Windows und C:\Windows\ als gleich gekennzeichnet
  // werden, fügen wir beiden einen Backslash hinzu - auch wenn es sich
  // um Dateien handelt.
  // Grund: Sowohl für ExpandUNCFileName() als auch für SameFileName()
  // ist es nicht von Bedeutung, ob die Datei / das Verzeichnis existiert
  // oder nicht.
  // Außerdem teilen sich Dateien und Ordner in allen Betriebssystemen
  // den selben Namensraum.

  A := IncludeTrailingPathDelimiter(A);
  B := IncludeTrailingPathDelimiter(B);

  result := SameFileName(A, B);
end;
Ich kann in diese Funktion Dateien und Ordner reinschrieben und es gibt kein Problem, wenn Pfadangaben durch .. oder . Angaben abgeändert wurden.

Bei NTFS-Dateisystemen gibt es aber jetzt folgende Probleme:

1. Gleiche Verzeichnisse durch NTFS-HardLinks

Die Verzeichnisse
C:\Ordner\Symlink\
und
C:\AndererOrdner\
könnten gleich sein, wenn C:\AndererOrdner\ ein Hardlink von C:\Ordner\Symlink\ ist.

Ebenfalls könnten aber auch
C:\Ordner\Symlink\X\
und
C:\AndererOrdner\X\
gleich sein, obwohl C:\AndererOrdner\X\ kein Hardlink von C:\Ordner\Symlink\X\ ist (denn der Hardlink ist eine Stufe tiefer).

Ich befürchte, dass man eventuell beliebig komplizierte Szenarios hinbekommen kann, bei denen ein eventueller Algorithmus, der den Verzeichnisbaum abläuft, fehlschlagen könnte. Ich bin mir da aber nicht ganz sicher.

1b. Gleiche Verzeichnisse durch Linux-Symlinks

Ich möchte nach Möglichkeit portablen Code schreiben. Deswegen soll Problem #1 auch für Linux' SymLinks funktionieren (durch Compiler-Flag-Variante).
(Leider habe ich derzeit hierfür überhaupt keine Testmöglichkeit.)

2. Gleiche Verzeichnisse durch NTFS-MountPoints

Sei z.B. eine externe Festplatte sowohl auf X:\ als auch in C:\ExterneHDD\ gemounted (letzteres mittels NTFS-MountPoints).

Dann sind X:\ und C:\ExterneHDD\ physikalisch identisch, obwohl (möglichweise) kein echter HardLink vorliegt.

...

Ob es andere Szenarios gibt, bei denen man physikalisch identische Verzeichnisse hinbekommt, bin ich mir nicht ganz sicher.

Könnt ihr mir bitte Tipps oder Codebeispiele geben, wie ich eine Funktion hinbekommen kann, die auch bei NTFS-Hardlinks/Symlinks/NTFS-MountPoints (zuverlässig) funktioniert?

Triviale Lösung: Ich könnte zwar in das Verzeichnis einfach eine Zufallsdatei erstellen und schauen, ob diese im anderen Verzeichnis plötzlich auch erschienen ist ... aber ich erachte das als schlechten Programmierstil, da ich die Datenverzeichnisse der Endanwender nicht mit Temp-Dateien zumüllen möchte.

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Satty67

Registriert seit: 24. Feb 2007
Ort: Baden
1.566 Beiträge
 
Delphi 2007 Professional
 
#2

Re: 2 Verzeichnisse physikalisch identisch? NTFS-Hardlinks!

  Alt 22. Apr 2009, 23:34
Vielleicht reicht GetFileInformationByHandle, das ja auch für Directories funktioniert.

Das gibt auch einen FileIndex zurück, der pro Volume eindeutig ist. (Gleiche Volume Number kann ja sowieso vorab getestet werden).

Kommt halt darauf an, ob so ein Hardlink einen eigenen Index bekommt... oder nicht.
  Mit Zitat antworten Zitat
Reinhard Kern

Registriert seit: 22. Okt 2006
772 Beiträge
 
#3

Re: 2 Verzeichnisse physikalisch identisch? NTFS-Hardlinks!

  Alt 23. Apr 2009, 00:33
Zitat von blackdrake:
Ich befürchte, dass man eventuell beliebig komplizierte Szenarios hinbekommen kann, bei denen ein eventueller Algorithmus, der den Verzeichnisbaum abläuft, fehlschlagen könnte. Ich bin mir da aber nicht ganz sicher.
Hallo,

soweit ich mich erinnern kann, ist es unter Unix durchaus zu schaffen, einen geschlossenen Kreis von Hardlinks zu konstruieren, in dem das System endlos den Links folgen müsste - tut es glaube ich nicht, da gibt es wohl eine obere Grenze.

Von Unix aus betrachtet kann ich mir nur eine Lösung vorstellen: Backup-Programme u.ä. arbeiten den realen Baum ohne Symlinks ab und speichern die Symlinks als speziellen Dateieintrag, beim Restore werden sie wieder aktiviert. Sonst würde ein Vielfaches an Dateien gespeichert, denn unter Unix werden Symlinks ganz massiv zur Versionskontrolle benutzt: das Programm sucht unter MeinProgramm/Einstellungen, tatsächlich stehen die Daten aber unter MeinProgramm/Version 3.1.56/Einstellungen. Das kann man nur herausbekommen, wenn man sich den Baum ansieht, OHNE den Symlinks zu folgen.

Gruss Reinhard
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#4

Re: 2 Verzeichnisse physikalisch identisch? NTFS-Hardlinks!

  Alt 23. Apr 2009, 01:55
Hallo.

Danke für eure Antworten.

Zu GetFileInformationByHandle habe ich in der MSDN folgendes gefunden:

Zitat:
You can compare the VolumeSerialNumber and FileIndex members returned in the BY_HANDLE_FILE_INFORMATION structure to determine if two paths map to the same target; for example, you can compare two file paths and determine if they map to the same directory.
( http://msdn.microsoft.com/en-us/library/aa364952(VS.85).aspx )

Mir ist dort der Begriff "VolumeSerialNumber" aufgefallen... war das nicht die unaussagekräftige 4-Byte "Seriennummer" des Datenträgers? Wenn ja, wird es Grenzfälle geben, bei denen die Seriennummern gleich, die Datenträger aber unterschiedlich sind. Ein einfaches Beispiel wäre, wenn ich eine Diskette kopiere, dann wäre danach VolumeSerialNumber[A:] == VolumeSerialNumber[B:] und damit würde der Algorithmus zu dem Ergebnis DirIdentical('A:\x\', 'B:\x\') == true kommen, wenn zusätzlich beide Verzeichnisse x auf den Disketten durch Zufall die selbe interne Nummer haben.

Problem 2: Die Funktion kann bei Netzwerklaufwerken fehlschlagen. Was ist dann zu tun? Es kann ja auch ein Netzlaufwerk geben, bei dem der Samba-Daemon den Symlinks folgt.

Ich befürchte, mir bleibt nichts anderes übrig, als wirklich eine Datei in Verzeichnis A zu schreiben und zu schauen, ob sie in Verzeichnis B existiert, wenn ich größtmöglichste Kompatibilität haben möchte.

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von Codewalker
Codewalker

Registriert seit: 18. Nov 2005
Ort: Ratingen
945 Beiträge
 
Delphi XE2 Professional
 
#5

Re: 2 Verzeichnisse physikalisch identisch? NTFS-Hardlinks!

  Alt 23. Apr 2009, 07:52
Zitat von Reinhard Kern:
soweit ich mich erinnern kann, ist es unter Unix durchaus zu schaffen, einen geschlossenen Kreis von Hardlinks zu konstruieren, in dem das System endlos den Links folgen müsste - tut es glaube ich nicht, da gibt es wohl eine obere Grenze.
Das geht relativ einfach: In einem Verzeichnis einen SymLink auf das übergeordnete Verzeichnis anlegen (geht auch unter Windows). Ist das Programm schlecht (z.B. Backup-Tools) wird es eine endlose Verzeichnisfolge auflisten, ist es gut erkennt es den Hardlink und sichert wirklich nur das eine existierende Verzeichnis
Thomas
  Mit Zitat antworten Zitat
DevilsCamp
(Gast)

n/a Beiträge
 
#6

Re: 2 Verzeichnisse physikalisch identisch? NTFS-Hardlinks!

  Alt 23. Apr 2009, 09:10
Unter Linux kann man doch prüfen bei zwei Dateien
1. prüfen ob sie im selben MOUNT hängen
Code:
> df -k .
Sollte die Ausgabe gleich sein bzgl. des Mount-Pointes, so kann man einen Schritt weitergehen und
2. prüfen ob es sich um die selbe INODE handelt (zumindest bei ext2/3/4 Dateisystemen).

Sollten 1 und 2 zutreffen handelt es sich um die selbe Datei/das selbe Verzeichnis.

Möglicherweise ist Schritt 2 bei anderen Dateisystem (native Linux-Dateisysteme) gleich.


Auf NTFS/FAT bin ich mir nicht sicher ob und wie man da an eindeutige Dateiinformationen kommt.

Bzgl. Code für NTFS:
Ich habe da Funktionen mit denen man Hardlinks/Junctions usw. anlegen kann und auch das Ziel eines Hardlinks/Junction bestimmen kann.
Ich weiß nicht mehr, wo ich ihn gefunden habe, kann also den ursprünglichen Autor nicht nennen (ich war es jedenfalls nicht).
Dateien im Anhang.
Angehängte Dateien
Dateityp: zip junctions_105.zip (4,2 KB, 34x aufgerufen)
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#7

Re: 2 Verzeichnisse physikalisch identisch? NTFS-Hardlinks!

  Alt 27. Apr 2009, 04:03
Hallo.

Danke, ich werde mir die Units mal ansehen.

Besonders wichtig ist mir eine Funktion der Form:

Delphi-Quellcode:
function IsSymlink(A, B: string): boolean; // A und B vertauschbar
begin
  {$IFDEF WINDOWS}
  if NTFSAvailable then
    result := NTFS_IsHardLink(A, B)...
  else
    result := false;
  {$ELSE}
  result := Linux_IsSymlink(A, B)... // <-- Problem
  {$ENDIF}
end;
Jetzt suche ich noch eine Funktion, die mit Linux arbeitet und dort den Compilerschalterfall mit sinnvollem Code für die Linux-Dateisysteme belegt. Von den Linux Dateisystem-Interna weiß ich leider recht wenig.

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
DevilsCamp
(Gast)

n/a Beiträge
 
#8

Re: 2 Verzeichnisse physikalisch identisch? NTFS-Hardlinks!

  Alt 27. Apr 2009, 08:47
Für Unix:
Stichworte: fpStat, fpLStat, fpReadLink

Zitat:
FpStat
Retrieve file information about a file descriptor. (Folgt einem Symlink)
Zitat:
fpLstat
Return information about symbolic link. Do not follow the link
Zitat:
fpReadLink
Read destination of symbolic link
Bei einer echten Datei (und bei Hardlinks) sind die Informationen von FpStat und fpLstat identisch, bei Symlinks unterscheiden sie sich. => Sollte recht zuverlässig einen Symlink erkennen. Zur Sicherheit fpReadLink verwenden.

Sollten die Informationen identisch sein, kann es sich um entweder um eine Datei mit Hardlink handeln (falls der Wert für st_nlink aus dem Stat-Record größer 1) oder um die selbe Datei, falls man beim zweiten Pfad per Symlink/hardlink eines Verzeichnisses zu der Datei gelangt (hier kann st_nlink aus dem Stat-Record größer oder gleich 1 sein).
Ist der Wert für st_nlink aus dem Stat-Record gleich 1 so hast du definitiv die selbe Datei betrachtet.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz