Reading a file without modifying its Last Access time.

Reading a file without modifying its Last Access time.

Post by dmitr » Wed, 28 May 2008 08:00:18


ear all,

I have been tasked with reading a file without modifying its access
time (this is for a sort of a backup application). I was under the
impression that to do a proper backup, I had to call CreateFile()
using FILE_FLAG_BACKUP_SEMANTICS flag. Then, Last Access time would
not be changed after the file contents were read. My test program is
attached at the end of this post; it does not work. That is, the Last
Access time stubbornly gets updated every time a file is read. I
tried several combinations of arguments to CreateFile() and using both
ReadFile() and BackupRead() calls to read the data, but to no avail.

I was then pointed to documentation about special trick one can do [1]
by calling SetFileTime() with atime set to 0xFFFFFFFF right after the
file is opened. This _does_ work; however, one has to call
CreateFile() with FILE_WRITE_ATTRIBUTES flag -- otherwise,
SetFileTime() call fails. In my case, the files to be read are on a
read-only share, so calling CreateFIle() with any FILE_WRITE_* flag
fails.

Then I decided to investigate whether other backup/copy applications
are able to do what my program could not. I looked at operation of
ntbackup and robocopy. While both worked (Last Access time remained
unchanged) when reading files from a regular directory, neither did
when reading files from a read-only share. Tracing both programs
using StraceNT [2], I discovered that ntbackup in fact relies on the
SetFileTime() trick; when reading the file from a read-only share the
call fails. robocopy uses CopyFileEx() and it also fails to preserve
Last Access time on a read-only share (how it does it reading files
from a regular directory remains a mystery to me).

The question, therefore, is as follows: is what I am trying to achieve
possible? or is it simply not done because of some limitations that
are not explicitly documented? Am I missing something obvious in my
code below?

Thanks in advance,

- Dmitri.

P.S. I am new to Windows programming, so it took a while to
understand that there are _two_ records of Last Access time [3] in
NTFS. I wrote a separate program (not attached) to print the actual
atime of the file as it is reported for the file, not by what's stored
in its directory entry (this is how dir /ta reports it).

1. http://msdn.microsoft.com/en-us/library/ms724933(VS.85).aspx
2. http://www.intellectualheaven.com/default.asp?BH=projects&H=strace.htm
3. http://technet2.microsoft.com/windowsserver/en/library/8cc5891d-bf8e-4164-862d-dac5418c59481033.mspx?mfr=true

/*
* mycat.cpp -- read a text file and print its contents to console.
*
* Purpose: check out this whole FILE_FLAG_BACKUP_SEMANTICS business.
Does
* atime of a file change when we read it?
*/

#include "stdafx.h"
#include "windows.h"

static BOOL
enable_privilege (LPCWSTR lpPrivName)
{
TOKEN_PRIVILEGES Privileges;

HANDLE hToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|
TOKEN_ADJUST_PRIVILEGES, &hToken)) {
fprintf(stderr, "OpenProcessToken\n");
return FALSE;
}

Privileges.PrivilegeCount = 1;
Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!LookupPrivilegeValue(NULL, lpPrivName,
&Privileges.Privileges[0].Luid)) {
fprintf(stderr, "LookupPrivilegeValue\n");
return FALSE;
}

BOOL bResult = AdjustTokenPrivileges(hToken, FALSE, &Privileges,
0, NULL, NULL);
if (Get
 
 
 

Reading a file without modifying its Last Access time.

Post by Kellie Fit » Wed, 28 May 2008 09:00:33


Hi,

Here is a viable workaround approach when possible:

- Copy the main file into a safe location

- Perform your normal read/backup function

- Copy or move the main file back into its
- original location

Kellie.

 
 
 

Reading a file without modifying its Last Access time.

Post by dmitr » Wed, 28 May 2008 09:04:58


Hi Kellie,

the problem with this approach is that I do not have access to the
file other than via a read-only share. So copying it would result in
its Last Access time being updated, which is what I am trying to
avoid.

- Dmitri.
 
 
 

Reading a file without modifying its Last Access time.

Post by Scott Seli » Wed, 28 May 2008 11:06:14


I may be missing something, but shouldn't a back up application key off
of the last write time? If I play all of my music files, I don't want
my backup app to copy them again just because the access time has been
bumped.

--
--------- Scott Seligman <scott at <firstname> and michelle dot net> ---------
The beginning is the most important part of the work.
-- The Republic by Plato
 
 
 

Reading a file without modifying its Last Access time.

Post by dmitr » Thu, 29 May 2008 01:22:56


That's true, but those are not my requirements.
 
 
 

Reading a file without modifying its Last Access time.

Post by r_z_are » Thu, 29 May 2008 02:59:08

On Mon, 26 May 2008 17:04:58 -0700 (PDT), dmitri < XXXX@XXXXX.COM >




Naive and hopeful:
If you copy the file and read the copy, does the access time on the
original get changed?


-----------------------------------------
To reply to me, remove the underscores (_) from my email address (and please indicate which newsgroup and message).

Robert E. Zaret, eMVP
PenFact, Inc.
20 Park Plaza, Suite 400
Boston, MA 02116
www.penfact.com
Useful reading (be sure to read its disclaimer first):
http://www.yqcomputer.com/ ~esr/faqs/smart-questions.html
 
 
 

Reading a file without modifying its Last Access time.

Post by dmitr » Thu, 29 May 2008 03:08:01


Yes.

- Dmitri.
 
 
 

Reading a file without modifying its Last Access time.

Post by MVP SDK 20 » Thu, 12 Jun 2008 04:17:57


That is not true.. backup apps use either ModifyDate or it's own tracking
metadata. Note however that some video clip formats save something into
file at every view...

I can't see why you would like to not change the AccessDate... it's purpose
is to tell when it was last accessed. ;)
But you really have to, then use FindFirstFile() to save the date, read the
file, open the file and use SetFileTime() to set the access date.

- Sten