Vielen Dank für deine Mühe, besonders dafür, dass du den Code auch noch didaktisch entwickelt hast, und das um 1:18 Uhr nachts. Auch wenn man förmlich die Watschen hört, gefolgt von einem "Sechs! Setzen!". Aber ich weiß genau, dass hier viele mitlesen, die mit denselben Problemen kämpfen und froh sind über jede Aufklärung.
Natürlich war der Code auch nicht sozusagen als fertige Lösung gedacht, er war lediglich als Machbarkeitsstudie intendiert, weil er überhaupt im Prinzip funktionierte.
Ein kleiner Trost ist es, dass der Code vom Meister auch nicht so ohne weiteres läuft.
Bei
Handle := FindFirstFileNameW(PWideChar(Dateiname),0,@PDatLänge,@PLinkName);
moniert der Compiler, dass die Parameter formal nicht stimmen, genauso wie bei
LinkName : array[0..MAX_PATH] of WideChar;
.
Daher mein nächster Versuch:
Delphi-Quellcode:
procedure TForm1.ZeigeHardlinks;
var
Dateiname : WideString;
PLinkLänge : PDWord;
PLinkName : PWideChar;
Handle : Cardinal;
begin
Dateiname := '
C:\Temp\Hardlink.JPG';
PLinkName := GetMemory(MAX_PATH * 2 + 2);
// +2 für die abschließende #0
PLinkLänge := GetMemory(SizeOf(PDWord));
//PLinkLänge^ := MAX_PATH;
Try
Handle := FindFirstFileNameW(PWideChar(Dateiname), 0, PLinkLänge, PLinkName);
If GetLastError = ERROR_MORE_DATA
then begin
Showmessage(SysErrorMessage(GetLastError));
end else if Handle = INVALID_HANDLE_VALUE
then begin
RaiseLastOSError;
end else begin
Repeat
ShowMessage(PWideChar(@PLinkName));
//PLinkLänge^ := MAX_PATH;
Until not FindNextFileNameW(
Handle, PLinkLänge, PLinkName);
end;
Finally
FreeMemory(PLinkName);
FreeMemory(PLinkLänge);
FileClose(
Handle);
End;
end;
Dieser Code funktioniert in dem Sinn, dass die Namen richtig ausgegeben werden. Bei
FreeMemory(PLinkName);
knallt es aber. Schleierhaft, wieso.
Die Zuweisung
PLinkLänge^ := MAX_PATH;
funktioniert, ist aber unnötig, denn - wie du ja auch ausführst - wird die Variable nur gebraucht, sollte der Puffer von PLinkName zu klein für den Linknamen, sie enthält dann den Wert für die notwendige Größe. Merkwürdig ist nur, dass es bei einer erneuten Zuweisung nach
ShowMessage(PWideChar(@PLinkName));
knallt. Im Debugger sieht man, dass der Wert von PLinkLänge^ nach Aufruf von FindFirstFileNameW plötzlich nicht mehr verfügbar ist. Und leider ebenfalls unverständlich ist mir, dass die Sache mit ERROR_MORE_DATA nicht funktioniert, wenn ich den Puffer von PLinkName absichtlich zu klein bemesse (z.B.
PLinkName := GetMemory(2);
, obwohl das nicht sein dürfte und bei meinen früheren Versuchen auch korrekt ERROR_MORE_DATA zurückgegeben wurde. Klappen tut die Sache trotzdem! Und was passiert da nun?
Noch eine kleine Bemerkung zu "4294967295" statt INVALID_HANDLE_VALUE. Im Entwurfsmodus hat INVALID_HANDLE_VALUE den Wert -1, wird aber dennoch treuherzig als "Cardinal" deklariert. Zur Laufzeit wechselt der Wert im Debugger dann zu den besagten 4294967295, was schon sehr irritierend ist. Ein Ausflug in die Welt von DWORD bei Windows erklärt dann so einiges. Bei mir hat der Compiler in einigen Fällen (nicht in allen ?!) darauf hingewiesen, dass
If Handle = INVALID_HANDLE_VALUE
immer "Falsch" ergibt - logisch bei Cardinal und einem Wert von -1 zur Entwufszeit.
Für weitere Erhellung des Codes oben wäre ich dankbar.