Title: Changing Creation and Last accessed dat/time for files
Question: The normal sysutils function FileSetdate only alters the Last Written Time and does NOT set the date of creation or the date of last access. All Win 32 files from Windows 95 store these. How does one alter these?
Answer:
You can view the File creation and access times from Windows Explorer on W2k (and possibly XP) by right clicking the column headers in the details and adding the columns. Programmatically, the TSearchRec (used in FindFirst & FindNext) returns a record of type Twin32FindData and this contains these values as well. This record from windows.pas shows these extra fields:
_WIN32_FIND_DATAA = record
dwFileAttributes: DWORD;
ftCreationTime: TFileTime; ftLastAccessTime: TFileTime; ftLastWriteTime: TFileTime;
nFileSizeHigh: DWORD;
nFileSizeLow: DWORD;
dwReserved0: DWORD;
dwReserved1: DWORD;
cFileName: array[0..MAX_PATH - 1] of AnsiChar;
cAlternateFileName: array[0..13] of AnsiChar;
Also in windows.pas in FileSetDate, and by modifying the two nil parameters in the SetFileTime call to @FileTime you can set creation and last access to the same value when setting last written time. Here is my version of that.
function MyFileSetDate(Handle: Integer; Age: Integer): Integer;
var
LocalFileTime, FileTime: TFileTime;
begin
Result := 0;
if DosDateTimeToFileTime(LongRec(Age).Hi, LongRec(Age).Lo, LocalFileTime) and
LocalFileTimeToFileTime(LocalFileTime, FileTime) and
SetFileTime(Handle, @FileTime, @FileTime, @FileTime) then Exit;
Result := GetLastError;
end;
The example below processes a path recursively and sets the file dates etc to that specified.
procedure TfrmTouch.ProcessPath(Filepath : string);
var sr : tSearchrec;
ErrorValue : integer;
Filename : string;
function MyFileSetDate(Handle: Integer; Age: Integer): Integer;
var
LocalFileTime, FileTime: TFileTime;
begin
Result := 0;
if DosDateTimeToFileTime(LongRec(Age).Hi, LongRec(Age).Lo, LocalFileTime) and
LocalFileTimeToFileTime(LocalFileTime, FileTime) and
SetFileTime(Handle, @FileTime, @FileTime, @FileTime) then Exit;
Result := GetLastError;
end;
procedure ProcessFile;
var
fh : integer;
fd : double;
dfd : integer;
begin // Date is 20th May 1998 at 2:14:31 secs (AM)
fd := EncodeDate(1998,5,20)+encodetime(2,14,31,0);
dfd := DateTimeToFileDate(fd);
fh := FileOpen(Filepath+filename, fmOpenWrite or fmShareDenyNone);
fd := Myfilesetdate(fh,dfd);
fileclose(fh);
end;
begin
if FilePath[length(FilePath)]'\' then
Filepath := FilePath +'\';
ErrorValue := Findfirst(Filepath+'*.*',faAnyfile,Sr);
while ErrorValue =0 do
begin
Filename := Sr.FindData.cFileName;
if (Sr.Attr and faDirectory = faDirectory) then
begin
if (Sr.Name[1]'.') and RecurseTree then
ProcessPath(Filepath+Filename);
end
else
ProcessFile;
ErrorValue := FindNext(Sr);
end;
end;
procedure TfrmTouch.BtnStartClick(Sender: TObject);
var path : string;
begin
path := '';
Screen.Cursor := crHourglass;
Attrval := 0;
Count := 0;
Total := 0;
RecurseTree := true;
ProcessPath(Path);
Screen.Cursor := crDefault;
end;