Microsoft提供了一种documented方法,用于防止上次访问时间被文件句柄上的操作更新。我已经使用此方法成功地在本地访问文件,但不是远程访问。这应该适用于远程文件吗?
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <assert.h>
#include <string>
#define FAIL(x) { printf(x" FAILED: %d\n", GetLastError()); exit(-1); }
static std::wstring GetDateTimeString(SYSTEMTIME* datetime)
{
TCHAR buffer[256];
TCHAR* current = buffer;
int idx = GetDateFormat(LOCALE_SYSTEM_DEFAULT,NULL, datetime, L"dd-MMM-yyyy", current, 256);
if(idx > 0)
{
buffer[idx -1] = ' ';
current += idx;
int idx2 = GetTimeFormat(LOCALE_SYSTEM_DEFAULT,NULL, datetime, L"HH:mm:ss", current, 256 - idx);
if(idx2 > 0)
{
current += idx2 - 1;
_sntprintf(current, 256 - (idx + idx2), L".%d", datetime->wMilliseconds);
}
else
FAIL("GetTimeFormat");
}
else
FAIL("GetDateFormat");
return std::wstring(buffer);
}
static void ReportLastAccessTime(TCHAR* path)
{
WIN32_FILE_ATTRIBUTE_DATA data;
if(GetFileAttributesEx(path, GetFileExInfoStandard, &data))
{
SYSTEMTIME accessSysTime;
if(FileTimeToSystemTime(&data.ftLastAccessTime, &accessSysTime))
{
SYSTEMTIME nowSysTime;
GetSystemTime(&nowSysTime);
printf("(%S) LastAccess=%S\n", GetDateTimeString(&nowSysTime).c_str(), GetDateTimeString(&accessSysTime).c_str());
}
else
FAIL("FileTimeToSystemTime");
}
else
FAIL("GetFileAttributesEx");
}
static void TestPreservingLastAccessTime(TCHAR* path)
{
printf("Checking times before opening the file handle...\n");
ReportLastAccessTime(path);
HANDLE hFile = CreateFile(
path,
GENERIC_READ | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
static const FILETIME ftLeaveUnchanged = { 0xFFFFFFFF, 0xFFFFFFFF };
printf("Handle open, SetFileTime -1...\n");
if(SetFileTime(hFile, NULL, &ftLeaveUnchanged, NULL))
{
char buf[512];
DWORD numRead = 0;
printf("Checking times after opening handle and SetFileTime...\n");
ReportLastAccessTime(path);
printf("Reading the file...\n");
long total = 0;
while (ReadFile(hFile, buf, sizeof(buf), &numRead, NULL))
{
if (numRead == 0) break;
total += numRead;
printf("Read: %d bytes (total=%d)\n", numRead, total);
Sleep(1000);
}
printf("Checking times after reading the file...\n");
ReportLastAccessTime(path);
printf("Sleeping 30\n");
Sleep(30 * 1000);
printf("Checking times after reading the file before closing the file...\n");
ReportLastAccessTime(path);
printf("Closing the file\n");
CloseHandle(hFile);
printf("Sleeping 30\n");
Sleep(30 * 1000);
printf("Checking times after closing the file...\n");
ReportLastAccessTime(path);
}
else
{
CloseHandle(hFile);
FAIL("SetFileTime");
}
}
else
FAIL("CreateFile");
}
int _tmain(int argc, TCHAR* argv[])
{
TCHAR* localPath = L"C:\\tmp\\file.txt";
TCHAR* uncPath = L"\\\\localhost\\C$\\tmp\\file.txt";
printf("Testing local path: %S\n", localPath);
TestPreservingLastAccessTime(localPath);
printf("Sleeping 30\n");
Sleep(30 * 1000);
printf("Testing UNC path: %S\n", uncPath);
TestPreservingLastAccessTime(uncPath);
return 0;
}
运行上述结果:
Testing local path: C:\tmp\file.txt
Checking times before opening the file handle...
(08-Nov-2011 21:06:18.432) LastAccess=08-Nov-2011 19:50:20.833
Handle open, SetFileTime -1...
Checking times after opening handle and SetFileTime...
(08-Nov-2011 21:06:18.432) LastAccess=08-Nov-2011 19:50:20.833
Reading the file...
Read: 512 bytes (total=512)
....
Read: 512 bytes (total=7680)
Checking times after reading the file...
(08-Nov-2011 21:06:33.432) LastAccess=08-Nov-2011 19:50:20.833
Sleeping 30
Checking times after reading the file before closing the file...
(08-Nov-2011 21:07:03.432) LastAccess=08-Nov-2011 19:50:20.833
Closing the file
Sleeping 30
Checking times after closing the file...
(08-Nov-2011 21:07:33.432) LastAccess=08-Nov-2011 19:50:20.833
Sleeping 30
Testing UNC path: \\localhost\C$\tmp\file.txt
Checking times before opening the file handle...
(08-Nov-2011 21:08:03.448) LastAccess=08-Nov-2011 19:50:20.833
Handle open, SetFileTime -1...
Checking times after opening handle and SetFileTime...
(08-Nov-2011 21:08:03.448) LastAccess=08-Nov-2011 19:50:20.833
Reading the file...
Read: 512 bytes (total=512)
....
Read: 512 bytes (total=7680)
Checking times after reading the file...
(08-Nov-2011 21:08:18.448) LastAccess=08-Nov-2011 19:50:20.833
Sleeping 30
Checking times after reading the file before closing the file...
(08-Nov-2011 21:08:48.448) LastAccess=08-Nov-2011 19:50:20.833
Closing the file
Sleeping 30
Checking times after closing the file...
(08-Nov-2011 21:09:18.448) LastAccess=08-Nov-2011 21:08:48.448
答案 0 :(得分:0)
您无法识别的请求是
#define FSCTL_READ_FILE_USN_DATA CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 58, METHOD_NEITHER, FILE_ANY_ACCESS) // Read the Usn Record for a file
哪个是docomented here
如果在SET_FILE_INFO之前为您使用的句柄发送了这个,那么这就解释了为什么您无法对上次访问时间更改进行调整。