挑战:文件的最后访问时间的难题(50分)

  • 主题发起人 主题发起人 我爱PASCAL
  • 开始时间 开始时间

我爱PASCAL

Unregistered / Unconfirmed
GUEST, unregistred user!
一个文件,只要你打开看了一下,或都用程序fileopen<br>那么这个文件的最后访问时间就变了,如果你是007,你需要把它的<br>最后访问时间改回去,于是你用<br>FileHandle := FileOpen(FileName, fmOpenReadWrite);<br>GetFileTime(FileHandle, @FileCT, @FileAT, @FileWT);<br>//偷看文件,篡改<br>SetFileTime(FileHandle, nil, @FileAT, @FileWT);<br>但是这样的只能变回最后更改时间;
 
复制到临时目录查看如何?
 
这个和临时目录有何关系,我试过也是一样的。
 
灌水,关键就是这个API函数吧。<br>&nbsp; SetFileTime((HANDLE)destFile.m_hFile, &nbsp; //待写入的文件句柄 &nbsp; <br>&nbsp; &amp;FileInfo.ftCreationTime, &nbsp; //文件的创建时间 &nbsp; <br>&nbsp; &amp;FileInfo.ftLastAccessTime, &nbsp; //文件最近一次的访问时间 &nbsp; <br>&nbsp; &amp;FileInfo.ftLastWriteTime); &nbsp; //文件最近一次的修改时间 &nbsp; <br><br>========<br>一、 &nbsp; 引言 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp;   文件是数据在磁盘上最常用的一种存放形式,也是在程序设计中与之经常打交道的一种编程对象,不少程序尤其是数据传输和处理类的应用程序更是需要频繁的创建、读取和写入文件。对于一些要求不是很严格的程序,我们往往只关心文件的内容是否正确、文件大小是否有增减或是再严格一些,看文件名是否符合规定等等。以上这些要素对于大多数程序而言显然是可以满足实际需求的,但对于某些特殊行业的一些有着比较严格要求的软件系统,仅有以上要素还是远远不够的,往往还需要对文件的所有属性诸如文件的创建时间、文件的最后访问时间、文件的最后修改时间等等进行提取处理与重新设置。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp;   二、 &nbsp; WIN32_FIND_DATA结构 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp;   关于文件的全部属性信息,总计有以下以下9种:文件的标题名、文件的属性(只读、存档,隐藏等)、文件的创建时间、文件的最后访问时间、文件的最后修改时间、文件大小的高位双字、文件大小的低位双字、保留、保留。在这里只有文件标题名和文件的长度可以通过CFile类比较方便的获得,而对于其他几种属性的获取和设置就无能为力了。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp;   在用findfirst()和findnext()函数去查找磁盘文件时经常使用的一个数据结构WIN32_FIND_DATA的成员变量里包含了以上所有的文件属性,因此可以通过这个结构作为获取和更改文件属性的手段。该结构的内容如下: &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; typedef &nbsp; struct &nbsp; _WIN32_FIND_DATA &nbsp; { &nbsp; <br>&nbsp;   DWORD &nbsp; dwFileAttributes; &nbsp; //文件属性 &nbsp; <br>&nbsp;   FILETIME &nbsp; ftCreationTime; &nbsp; // &nbsp; 文件创建时间 &nbsp; <br>&nbsp;   FILETIME &nbsp; ftLastAccessTime; &nbsp; // &nbsp; 文件最后一次访问时间 &nbsp; <br>&nbsp;   FILETIME &nbsp; ftLastWriteTime; &nbsp; // &nbsp; 文件最后一次修改时间 &nbsp; <br>&nbsp;   DWORD &nbsp; nFileSizeHigh; &nbsp; // &nbsp; 文件长度高32位 &nbsp; <br>&nbsp;   DWORD &nbsp; nFileSizeLow; &nbsp; // &nbsp; 文件长度低32位 &nbsp; <br>&nbsp;   DWORD &nbsp; dwReserved0; &nbsp; // &nbsp; 系统保留 &nbsp; <br>&nbsp;   DWORD &nbsp; dwReserved1; &nbsp; // &nbsp; 系统保留 &nbsp; <br>&nbsp;   TCHAR &nbsp; cFileName[ &nbsp; MAX_PATH &nbsp; ]; &nbsp; // &nbsp; 长文件名 &nbsp; <br>&nbsp;   TCHAR &nbsp; cAlternateFileName[ &nbsp; 14 &nbsp; ]; &nbsp; // &nbsp; 8.3格式文件名 &nbsp; <br>&nbsp; } &nbsp; WIN32_FIND_DATA, &nbsp; *PWIN32_FIND_DATA; &nbsp; <br>&nbsp;   可以通过FindFirstFile()函数根据当前的文件存放路径查找该文件来把待操作文件的相关属性读取到WIN32_FIND_DATA结构中去: &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; WIN32_FIND_DATA &nbsp; ffd &nbsp; ; &nbsp; <br>&nbsp; HANDLE &nbsp; hFind &nbsp; = &nbsp; FindFirstFile("c://test.dat",&amp;ffd); &nbsp; <br>&nbsp;   在使用这个结构时不能手工修改这个结构中的任何数据,结构对于开发人员来说只能作为一个只读数据,其所有的成员变量都会由系统完成填写。在MSDN帮助中可以查找到关于WIN32_FIND_DATA结构的更加详细的说明。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp;   三、 &nbsp; 文件属性信息的获取与更改 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp;   为了更好的保存获取到的文件属性信息,对应于文件属性构造一个自定义的FILE_INFO数据结构,获取的属性信息可暂存于此: &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; typedef &nbsp; struct &nbsp; _FILE_INFO &nbsp; { &nbsp; <br>&nbsp;   TCHAR &nbsp; szFileTitle[128]; &nbsp; //文件的标题名 &nbsp; <br>&nbsp;   DWORD &nbsp; dwFileAttributes; &nbsp; //文件的属性 &nbsp; <br>&nbsp;   FILETIME &nbsp; ftCreationTime; &nbsp; //文件的创建时间 &nbsp; <br>&nbsp;   FILETIME &nbsp; ftLastAccessTime; &nbsp; //文件的最后访问时间 &nbsp; <br>&nbsp;   FILETIME &nbsp; ftLastWriteTime; &nbsp; //文件的最后修改时间 &nbsp; <br>&nbsp;   DWORD &nbsp; nFileSizeHigh; &nbsp; //文件大小的高位双字 &nbsp; <br>&nbsp;   DWORD &nbsp; nFileSizeLow; &nbsp; //文件大小的低位双字 &nbsp; <br>&nbsp;   DWORD &nbsp; dwReserved0; &nbsp; //保留,为0 &nbsp; <br>&nbsp;   DWORD &nbsp; dwReserved1; &nbsp; //保留,为0 &nbsp; <br>&nbsp; } &nbsp; FILE_INFO, &nbsp; * &nbsp; PFILE_INFO; &nbsp; <br>&nbsp;   首先用FindFirstFile()函数将文件属性获取到WIN32_FIND_DATA &nbsp; 结构对象FindFileData中去,之后可以用FindClose()将其关闭,并把FindFileData中的有关文件属性信息的内容复制到自定义结构FILE_INFO的结构对象FileInfo中备用。下面是关于这部分描述的部分关键代码: &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; //声明结构对象 &nbsp; <br>&nbsp; FILE_INFO &nbsp; FileInfo; &nbsp; <br>&nbsp; WIN32_FIND_DATA &nbsp; FindFileData; &nbsp; <br>&nbsp; …… &nbsp; <br>&nbsp; //获取文件属性信息 &nbsp; <br>&nbsp; FindClose(FindFirstFile("Test.txt",&amp;FindFileData)); &nbsp; <br>&nbsp; memset(&amp;FileInfo,0,sizeof(FILE_INFO)); &nbsp; <br>&nbsp; …… &nbsp; <br>&nbsp; //将文件属性信息保存到FileInfo中备用 &nbsp; <br>&nbsp; strcpy(FileInfo.szFileTitle,myFile.GetFileTitle()); &nbsp; <br>&nbsp; FileInfo.dwFileAttributes &nbsp; = &nbsp; FindFileData.dwFileAttributes; &nbsp; <br>&nbsp; FileInfo.ftCreationTime &nbsp; = &nbsp; FindFileData.ftCreationTime; &nbsp; <br>&nbsp; FileInfo.ftLastAccessTime &nbsp; = &nbsp; FindFileData.ftLastAccessTime; &nbsp; <br>&nbsp; FileInfo.ftLastWriteTime &nbsp; = &nbsp; FindFileData.ftLastWriteTime; &nbsp; <br>&nbsp; FileInfo.nFileSizeHigh &nbsp; = &nbsp; FindFileData.nFileSizeHigh; &nbsp; <br>&nbsp; FileInfo.nFileSizeLow &nbsp; = &nbsp; FindFileData.nFileSizeLow; &nbsp; <br>&nbsp; …… &nbsp; <br>&nbsp;   在获取到文件的原始属性信息后既可以原封不动的将属性重新写到文件,也可以对其中某一项或某几项属性内容进行修改后再行写入文件,从而达到更改文件属性的目的。比如可以用SetFileTime()函数设置文件的创建时间、最近一次访问时间以及最近一次修改的时间等等: &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; SetFileTime((HANDLE)destFile.m_hFile, &nbsp; //待写入的文件句柄 &nbsp; <br>&nbsp; &amp;FileInfo.ftCreationTime, &nbsp; //文件的创建时间 &nbsp; <br>&nbsp; &amp;FileInfo.ftLastAccessTime, &nbsp; //文件最近一次的访问时间 &nbsp; <br>&nbsp; &amp;FileInfo.ftLastWriteTime); &nbsp; //文件最近一次的修改时间 &nbsp; <br>&nbsp;   也可以用SetFileAttributes() &nbsp; 函数实现对文件属性的修改: &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; SetFileAttributes(FileInfo.szFileTitle,FileInfo.dwFileAttributes); &nbsp; <br>&nbsp;   至于文件名的修改则更加简单,直接在创建文件时在CreateFile()或CFile类的成员函数Open里直接对文件名参数进行设置即可。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp;   小结:本文通过对WIN32_FIND_DATA结构和SetFileTime()、SetFileAttributes()等主要函数实现了对磁盘文件的相关属性信息的获取与修改。用此技术可以在通讯等对文件有严格要求的应用领域实现文件全部信息(包括文件内容、文件名以及文件属性等)的完整传送。
 
迟来一步,同意楼上的,2002年写了一个修改文件时间的程序,用来破解某个加密,<br>该加密就是检查最后访问时间的,有点弱智,但是也挡住万多人,放在某论坛有万多<br>人下载,源代码没了,但方法就是楼上这种用API行的,如果用检查最后访问时间来<br>加密,不是一个好方法,一来不稳定,二来很容易被发现,最后就是很容易被搞掂。
 
多人接受答案了。
 
后退
顶部