Re: Vierten Zeitstempel ermitteln
Zitat:
In meinem Code steht {$ALIGN 8} und {$MINENUMSIZE 4}, um von den Compiler-Einstellungen unabhängig zu sein. Und ich verstehe nicht ganz, warum du unbedingt NtQueryAttributesFile verwenden möchtest (und damit den Win32-Pfad in einen Objektnamen auflösen musst - was fehleranfällig ist, da nicht jeder Dateiname mit einem Laufwerksbuchstaben beginnt (UNC-Präfix, \\?\-Präfix, Volume-Präfix, usw...)). |
Re: Vierten Zeitstempel ermitteln
Wenn man sich ein Handle auf die Datei holt, wird die LastAccessTime geändert, was ich vermeiden möchte.
|
Re: Vierten Zeitstempel ermitteln
Liste der Anhänge anzeigen (Anzahl: 1)
Object_Attributes ist ja so deklariert:
Code:
Da ist ein Handle auf das RootDirectory und der PUNICODE_STRING für den Objektname. Der Dateiname samt Pfad als Object funktioniert nicht. Also müsste man es über das Handle versuchen. Wenn ich den Objektnamen leer lasse und das Handle auf die Datei verwende, funktioniert es:
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES;
Delphi-Quellcode:
Jetzt wollte ich den Pfad aufteilen, damit ich kein Handle auf die Datei nehmen muss.
function GetNTTime(fn: String; var FileInformation: FILE_BASIC_INFORMATION): Boolean;
const FILE_READ_ATTRIBUTES = $0080; var strDosDeviceName : ANSI_STRING; RootDirectory : THandle; FileName : ANSI_STRING; szNtDeviceName : array[0..MAX_PATH] of Char; ObjName : UNICODE_STRING; ObjectAttributes : OBJECT_ATTRIBUTES; Buffer : array of WideChar; Status : NTSTATUS; DosErr : DWORD; Error : PChar; begin Result := False; RtlZeroMemory(@strDosDeviceName, SizeOf(ANSI_STRING)); RtlZeroMemory(@ObjName, SizeOf(UNICODE_STRING)); RtlZeroMemory(@ObjectAttributes, SizeOf(OBJECT_ATTRIBUTES)); RtlZeroMemory(@FileInformation, SizeOf(FILE_BASIC_INFORMATION)); RootDirectory := CreateFile(PAnsiChar(fn), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); InitializeObjectAttributes(@ObjectAttributes, @ObjName, OBJ_CASE_INSENSITIVE, RootDirectory, nil); Status := NtQueryAttributesFile(@ObjectAttributes, @FileInformation); Result := NT_SUCCESS(Status); if not Result then begin doserr := RtlNtStatusToDosError(Status); SetLastError(DosErr); GetMem(Error, 255); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM, nil, GetLastError, 0, @Error, 255, nil); ShowMessage(Trim(Error)); end; end;
Delphi-Quellcode:
Ergibt ein ungültiges Handle. Deshalb
RootDirectory := CreateFile(PAnsiChar(ExtractFileDrive(fn)), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
Delphi-Quellcode:
Allerdings scheint es egal zu sein, wie ich den Dateinamen aufteile:
QueryDosDevice(PAnsiChar(ExtractFileDrive(fn)), szNtDeviceName, MAX_PATH);
RootDirectory := CreateFile(szNtDeviceName, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
Delphi-Quellcode:
QueryDosDevice(PAnsiChar(ExtractFileDrive(fn)), szNtDeviceName, MAX_PATH);
RootDirectory := CreateFile(PAnsiChar(szNtDeviceName + Copy(ExtractFilePath(fn), 3, Length(ExtractFilePath(fn)) - 2)), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); RtlInitAnsiString(@FileName, PAnsiChar(ExtractFileName(fn))); RtlAnsiStringToUnicodeString(@ObjName, @FileName, True);
Delphi-Quellcode:
Es gibt immer diesen Fehler:
QueryDosDevice(PAnsiChar(ExtractFileDrive(fn)), szNtDeviceName, MAX_PATH);
RootDirectory := CreateFile(szNtDeviceName, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); RtlInitAnsiString(@FileName, PAnsiChar(Copy(fn, 4, Length(fn) - 3))); RtlAnsiStringToUnicodeString(@ObjName, @FileName, True);
Code:
Nehme ich das Handle auf die Datei und die Datei als Object:
---------------------------
Filetime --------------------------- Unzulässiger Zugriff auf einen Speicherbereich. --------------------------- OK ---------------------------
Delphi-Quellcode:
bekomme ich den Fehler:
RootDirectory := CreateFile(PAnsiChar(fn), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
RtlInitAnsiString(@FileName, PAnsiChar(ExtractFileName(fn))); RtlAnsiStringToUnicodeString(@ObjName, @FileName, True);
Code:
:wall:
---------------------------
Filetime --------------------------- Das System kann den angegebenen Pfad nicht finden. --------------------------- OK --------------------------- |
Re: Vierten Zeitstempel ermitteln
Liste der Anhänge anzeigen (Anzahl: 1)
Gelöst!
Der Fehler
Code:
lag an
---------------------------
Filetime --------------------------- Unzulässiger Zugriff auf einen Speicherbereich. --------------------------- OK ---------------------------
Delphi-Quellcode:
Das ungültige Handle lag an falschen Parametern. Jetzt sieht es so aus:
QueryDosDevice(PAnsiChar(ExtractFileDrive(fn)), szNtDeviceName, MAX_PATH);
Delphi-Quellcode:
Das scheint auch ein Irrtum zu sein:
function GetNTTime(fn: String; var FileInformation: FILE_BASIC_INFORMATION): Boolean;
const FILE_LIST_DIRECTORY = $0001; var RootDirectory : THandle; FileName : ANSI_STRING; ObjName : UNICODE_STRING; ObjectAttributes : OBJECT_ATTRIBUTES; Status : NTSTATUS; DosErr : DWORD; Error : PChar; begin Result := False; RtlZeroMemory(@ObjName, SizeOf(UNICODE_STRING)); RtlZeroMemory(@ObjectAttributes, SizeOf(OBJECT_ATTRIBUTES)); RtlZeroMemory(@FileInformation, SizeOf(FILE_BASIC_INFORMATION)); RootDirectory := CreateFile(PAnsiChar(ExtractFilePath(fn)), FILE_LIST_DIRECTORY, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); RtlInitAnsiString(@FileName, PAnsiChar(ExtractFileName(fn))); RtlAnsiStringToUnicodeString(@ObjName, @FileName, True); InitializeObjectAttributes(@ObjectAttributes, @ObjName, OBJ_CASE_INSENSITIVE, RootDirectory, nil); Status := NtQueryAttributesFile(@ObjectAttributes, @FileInformation); Result := NT_SUCCESS(Status); if not Result then begin doserr := RtlNtStatusToDosError(Status); SetLastError(DosErr); GetMem(Error, 255); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM, nil, GetLastError, 0, @Error, 255, nil); ShowMessage(Trim(Error)); end; CloseHandle(RootDirectory); end; Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:37 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