Re: Simple Program to Change a File's Date and Time
- Posted by Juergen Luethje <j.lue at gmx.de> Nov 30, 2005
- 637 views
I had sent the following message more than 4 hours ago by mail via Topica. Since it did not come through until now, I post it again here via web interface: Dr Hank Heyman wrote: > Hello all, > > If I wanted to write a simple program in Euphoria to run in DOS > that allowed me to change a file's date and time, how would I > do that? > > A program that I've used a lot, XTree Gold 3.0, included > such a feature. I know there's a software interrupt > that does this. I also believe that Turbo Pascal has > a function for it. > > A use for this would be to edit a file and change > the file date and time back to its original date > and time to maintain the original chronological > order of a series of files. You'll find a program that does what you want at the end of this post. > Plus it might help me get restarted in programming. Many people consider this DOS interrupt stuff not so simple. If you consider the program "simple", then getting restarted in programming should be easy for you. Anyway, we'll help you here on this list whenever we can.
------------------------------------------------------------------- -- DOS32 routines to get/set date and time of files; -- by Juergen Luethje -- (reference: "Ralf Brown's Interrupt List") -- tested with Euphoria 2.5 -- in the DOS box of Windows 98, and on plain DOS include machine.e function allocate_low_string (sequence string) -- create a C-style null-terminated string in low memory -- (like Euphoria's allocate_string(), but for low memory) integer low_addr low_addr = allocate_low(length(string)+1) if low_addr then poke(low_addr, string) poke(low_addr+length(string), 0) end if return low_addr end function function open_file_DOS32 (sequence filename) -- open existing file for read/write -- out: file handle on success, or -1 on error sequence reg_list atom low_buff reg_list = repeat(0, REG_LIST_SIZE) low_buff = allocate_low_string(filename) reg_list[REG_AX] = #3D02 -- method = read/write reg_list[REG_DS] = floor(low_buff / #10) reg_list[REG_DX] = remainder(low_buff, #10) reg_list[REG_FLAGS] = 1 -- set carry flag reg_list = dos_interrupt(#21, reg_list) free_low(low_buff) if and_bits(reg_list[REG_FLAGS], 1) then return -1 else return reg_list[REG_AX] end if end function procedure close_file_DOS32 (integer handle) sequence reg_list reg_list = repeat(0, REG_LIST_SIZE) reg_list[REG_AX] = #3E00 reg_list[REG_BX] = handle reg_list = dos_interrupt(#21, reg_list) end procedure ------------------------------------------------------------------- global function get_filetime_DOS32 (sequence filename) -- in : filename: name of the target file -- out: date and time in DOS filetime format, or -1 on error sequence reg_list integer handle handle = open_file_DOS32(filename) if handle = -1 then return -1 end if reg_list = repeat(0, REG_LIST_SIZE) reg_list[REG_AX] = #5700 reg_list[REG_BX] = handle reg_list[REG_FLAGS] = 1 -- set carry flag reg_list = dos_interrupt(#21, reg_list) close_file_DOS32(handle) if and_bits(reg_list[REG_FLAGS], 1) then return -1 else return {reg_list[REG_DX], -- file's date reg_list[REG_CX]} -- file's time end if end function global function set_filetime_DOS32 (sequence filename, sequence filetime) -- in : filename: name of the target file -- filetime: sequence of the form {date,time} (DOS filetime format) -- out: 0 on success, or -1 on error sequence reg_list integer handle handle = open_file_DOS32(filename) if handle = -1 then return -1 end if reg_list = repeat(0, REG_LIST_SIZE) reg_list[REG_AX] = #5701 reg_list[REG_BX] = handle reg_list[REG_DX] = filetime[1] -- file's date reg_list[REG_CX] = filetime[2] -- file's time reg_list[REG_FLAGS] = 1 -- set carry flag reg_list = dos_interrupt(#21, reg_list) close_file_DOS32(handle) if and_bits(reg_list[REG_FLAGS], 1) then return -1 else return 0 end if end function constant E_YEAR = 1, E_MONTH = 2, E_DAY = 3, E_HOUR = 4, E_MINUTE = 5, E_SECOND = 6 global function time_to_dos_time (sequence t) -- in : sequence of the form {year,month,day,hour,minute,second} -- out: date and time in DOS filetime format -- (positive 32-bit integer in the interval [#00210000, #F19FBF7E]), -- split in its high and low words integer hiword, loword hiword = ((t[E_YEAR]-1980)*#10 + t[E_MONTH])*#20 + t[E_DAY] -- date loword = (t[E_HOUR]*#40 + t[E_MINUTE])*#20 + floor(t[E_SECOND]/2) -- time return {hiword, loword} end function ------------------------------------------------------------------- -- * Demo * -- include get.e -- for wait_key() procedure wait (sequence msg) object void puts(2, msg & "\n\nPress any key ...") void = wait_key() end procedure sequence filename, dos_time, eu_time integer fn, error -- Sample file name and time filename = "test.txt" eu_time = {2001,3,20,14,23,6} -- Create a test file fn = open(filename, "w") if fn = -1 then wait(sprintf("Cant't create file '%s'.", {filename})) abort(1) end if puts(fn, "This is old text.\n") close(fn) -- Demo 1: "manually" set an old file time dos_time = time_to_dos_time(eu_time) error = set_filetime_DOS32(filename, dos_time) if error then wait(sprintf("Cant't set time of file '%s'.", {filename})) abort(1) end if puts(1, "#1: success\n") -- Demo 2: get the time of an arbitrary file, -- change its contents and reset its time dos_time = get_filetime_DOS32(filename) fn = open(filename, "a") if fn = -1 then wait(sprintf("Cant't open file '%s'.", {filename})) abort(1) end if puts(fn, "This is new text.\n") close(fn) error = set_filetime_DOS32(filename, dos_time) if error then wait(sprintf("Cant't set time of file '%s'.", {filename})) abort(1) end if wait("#2: success\n") -------------------------------------------------------------------
Regards, Juergen -- Have you read a good program lately?