(copy-file FileTime info - (FixFileTime workaround

Started by CaveGuy, June 21, 2009, 06:04:59 PM

Previous topic - Next topic

CaveGuy

I am using (copy-file to make a backup file and it is putting the current date- time in the (file-info of the new copy. I need to be able to preserve the FileTime info on the copy or find a way to put it back to what it was.

.......
Bob the Caveguy aka Lord High Fixer.

CaveGuy

#1
Given a full path to the source and destination file, FixFileTime will copy the FileTime info from the src file to the dest file.



While this is far from an elegant solution it solved my problem and hopefully someone elses along the way. I am open to suggestions.


(define (FixFileTime src dest)
    (if (not SetFileTime)
        (begin
           (import "kernel32.DLL" "_lopen")
           (import "kernel32.DLL" "_lclose")
           (import "kernel32.DLL" "GetFileTime")
           (import "kernel32.DLL" "SetFileTime")
           (setq lpCreationTime 0
                 lpLastAccessTime 0
                 lpLastWriteTime 0)))
    (setq hFileS (_lopen src 1)
          hFileD (_lopen dest 1) )  
    (if (and (> hFileS 0) (> hFileD 0))
        (begin
            (GetFileTime hFileS
                (address lpCreationTime)
                (address lpLastAccessTime)
                (address lpLastWriteTime) )  
            (SetFileTime hFileD
                (address lpCreationTime)
                (address lpLastAccessTime)
                (address lpLastWriteTime))))          
    (if (> hFileS 0) (_lclose hFileS))
    (if (> hFileD 0) (_lclose hFileD)) )
Bob the Caveguy aka Lord High Fixer.

Lutz

#2
Very nice, and a good example how to import functions in Windows .



I have put this (assuming your permission) with minor adjustments into the Code Snippets file accessible form the first link on the page:



http://www.newlisp.org/index.cgi?Tips_and_Tricks">http://www.newlisp.org/index.cgi?Tips_and_Tricks



ps: you probably meant "hFileD" in the last line.

CaveGuy

#3
I fixed my typo in the last line, and you are always welcome to my PUDDERings. (Programing Under Deliberately Difficult Environmental Restrictions :)



I just looked and you missed (_lclose hFileD) on that last line.



Here is a second example. (reset-archive-flag...  will reset the Archive Flag on the file specified by file-name.



(define (reset-archive-flag file-name)
   (if (not GetFileAttributesA)
       (begin
           (import "kernel32.DLL" "GetFileAttributesA")
           (import "kernel32.DLL" "SetFileAttributesA")))
   (setq fname file-name
         file-attrib (GetFileAttributesA (address fname))
         new-attrib (^ file-attrib (& file-attrib 0x20)))      
   (SetFileAttributesA (address fname) new-attrib) )
Bob the Caveguy aka Lord High Fixer.

m35

#4
I recall seeing a http://www.alh.net/newlisp/phpbb/viewtopic.php?p=13507">similar question some time ago. It seems the POSIX function to do this is http://www.opengroup.org/onlinepubs/009695399/functions/utime.html">utime. Information about the Windows version can be found http://msdn.microsoft.com/en-us/library/aa273399%28VS.60%29.aspx">here. I assume this function can be imported from msvcrt.dll.

CaveGuy

#5
My first reaction to using _utime, _wutime was that they did update all three time stamps. In this case my goal was to duplicate/preserve all three timestamps on the coppied file. I was already using several other (import "kernel32.DLL" ....'s and did not want to have to worry if the target system had a copy of MSVCRT.LIB or not.  Without "kernel32.DLL" windows it would be dead, I know it is present and its version :)

Thanks for the thought, though ....
Bob the Caveguy aka Lord High Fixer.

m35

#6
Quote from: "CaveGuy"did not want to have to worry if the target system had a copy of MSVCRT.LIB or not.  Without "kernel32.DLL" windows it would be dead, I know it is present and its version :)


If I'm not mistaken, newLISP needs msvcrt.dll to run on Windows. In any case, I was just thinking if Lutz wanted to add these functions to newLISP, identifying the POSIX functions would be the first step. In that earlier thread I had also suggested using those same Windows specific functions to modify the timestamps (which was then countered with some witty old-school interrupt hacking).