Re: Other information and dates of an archive

new topic     » goto parent     » topic index » view thread      » older message » newer message

[snipped code]

i couldn't help but keep trying at this code, if nothing else but for my own
education. i wrapped the FileTimeToLocalFileTime function, which handles all
the time zone, daylight savings time, time bias, etc. for you. i also added
the windows api documentation more for my benefit. i tried to leave the 
original coding style in place to not confuse the original author.

-- gather other time stamp info from files. based on code posted to the forum:
--		Date: 2007 Feb 5 15:35
--		From: CChris <christian.cuvier at agriculture.gouv.fr>
--		Subject: Re: Other information and dates of an archive

--	API documentation and FileTimeToLocalFileTime added by OtterDad

without warning
include win32lib.ew
sequence fname, creation, lastAccess, updated, local_creation, local_lastAccess,
local_updated
atom hfile, year, month, dow, day, hour, min, sec, msec
integer return_code

fname = "C:\\ex.err"
fname = "C:\\boot.ini" -- set this to the actual file name

-----------------------------------------------------------------------------
procedure wwait(object messag )
	atom result, rr
	rr = getSelf() 
	if sequence (messag) then
		result = message_box(messag , "Message !", MB_ICONEXCLAMATION  + MB_TASKMODAL)
	else
result = message_box(sprintf( "%d\n", messag), "Message !", MB_ICONEXCLAMATION
 + MB_TASKMODAL)
	end if
--	setFocus(rr)
end procedure
-----------------------------------------------------------------------------

-----------------------------------------------------------------------------
procedure makeDate(sequence field, object data)
	-- reads and translates a SYSTEMTIME structure
	year  = peek(data +  0) + (peek(data +  1) * 256)
	month = peek(data +  2) + (peek(data +  3) * 256)
	dow   = peek(data +  4) + (peek(data +  5) * 256)
	day   = peek(data +  6) + (peek(data +  7) * 256)
	hour  = peek(data +  8) + (peek(data +  9) * 256)
	min   = peek(data + 10) + (peek(data + 11) * 256)
	sec   = peek(data + 12) + (peek(data + 13) * 256)
	msec  = peek(data + 14) + (peek(data + 15) * 256)
	if match(field, "system_create_time") then
creation = sprintf("%04d/%02d/%02d  %02d:%02d:%02d", {year, month, day, hour,
min, sec})
	elsif match(field, "system_last_access") then
lastAccess = sprintf("%04d/%02d/%02d  %02d:%02d:%02d", {year, month, day,
hour, min, sec})
	elsif match(field, "system_last_write") then
updated = sprintf("%04d/%02d/%02d  %02d:%02d:%02d", {year, month, day, hour,
min, sec})
	elsif match(field, "local_system_create_time") then
local_creation = sprintf("%04d/%02d/%02d  %02d:%02d:%02d", {year, month, day,
hour, min, sec})
	elsif match(field, "local_system_last_access") then
local_lastAccess = sprintf("%04d/%02d/%02d  %02d:%02d:%02d", {year, month,
day, hour, min, sec})
	elsif match(field, "local_system_last_write") then
local_updated = sprintf("%04d/%02d/%02d  %02d:%02d:%02d", {year, month, day,
hour, min, sec})
	end if	
end procedure
-----------------------------------------------------------------------------

-----------------------------------------------------------------------------
-- wrap a few functions from kernel32.dll
constant kernel32 = open_dll("kernel32.dll"), 
GetFileTime = define_c_func(kernel32, "GetFileTime", repeat(C_POINTER, 4),
C_LONG),

	--	GetFileTime 11/30/2006 
--	This function retrieves the date and time that a file was created, last
accessed, and last modified.
	--	Syntax
--		BOOL GetFileTime(HANDLE hFile, LPFILETIME lpCreationTime, LPFILETIME
lpLastAccessTime,
	--			LPFILETIME lpLastWriteTime ); 
	--	Parameters
--		hFile - [in] Handle to the files for which to get dates and times. The file
handle must have been
	--			created with GENERIC_READ access to the file. 
--		lpCreationTime - [out] Pointer to a FILETIME structure to receive the date
and time the file was created.
--			This parameter can be NULL if the application does not require this
information.
--		lpLastAccessTime - [out] Pointer to a FILETIME structure to receive the
date and time the file was last
--			accessed. The last access time includes	the last time the file was written
to, read from, or, in the
--			case of executable files, run. This parameter can be NULL if the
application does not require this
	--			information. 
--		lpLastWriteTime - [out] Pointer to a FILETIME structure to receive the date
and time the file was last
--			written to. This parameter can be NULL if the application does not require
this information.
	--	Return Value
	--		Nonzero indicates success. 
	--		Zero indicates failure. 
	--	Remarks
--		The FAT and NTFS file systems support the file creation, last access, and
last write time values.
--		The Windows Embedded CE object store returns the same creation time value
for all three parameters.
--		In general, file system drivers will vary how they support this function.
The precision of the time
--		for a file in a FAT file system is one second. The time precision for files
in other file systems,
--		such as those connected through a network or installed on a peripheral
device, depends on the file
	--		system but may also be limited by the target device.
	--	Requirements
	--		Header: Winbase.h.
	--		Link Library: Coredll.lib.

	--	FILETIME
--		Contains a 64-bit value representing the number of 100-nanosecond intervals
since January 1, 1601 (UTC).
	--	typedef struct _FILETIME {  DWORD dwLowDateTime;  DWORD dwHighDateTime;
	--		} FILETIME,  *PFILETIME;
	--	Members
	--		dwLowDateTime - The low-order part of the file time. 
	--		dwHighDateTime - The high-order part of the file time. 
	--	Remarks
--		To convert a FILETIME structure into a time that is easy to display to a
user, use the
	--		FileTimeToSystemTime function.
--		It is not recommended that you add and subtract values from the FILETIME
structure to obtain
	--		relative times. Instead, you should:
--			Copy the resulting FILETIME structure to a ULARGE_INTEGER structure using
memcpy (using memcpy
--				instead of direct assignment can prevent alignment faults on 64-bit
Windows).
	--			Use normal 64-bit arithmetic on the ULARGE_INTEGER value. 
--		Not all file systems can record creation and last access time and not all
file systems record them in
--			the same manner. For example, on NT FAT, create time has a resolution of
10 milliseconds, write time
--			has a resolution of 2 seconds, and access time has a resolution of 1 day
(really, the access date).
--			On NTFS, access time has a resolution of 1 hour. Therefore, the
GetFileTime function may not return
--			the same file time information set using the SetFileTime function.
Furthermore, FAT records times on
--			disk in local time. However, NTFS records times on disk in UTC. For more
information, see File Times.

FileTimeToSystemTime = define_c_func(kernel32, "FileTimeToSystemTime",
repeat(C_POINTER, 2), C_LONG),
	--	Converts a file time to system time format.
	--	BOOL FileTimeToSystemTime(
	--		const FILETIME* lpFileTime,
	--		LPSYSTEMTIME lpSystemTime
	--	);
	-- Parameters
--		lpFileTime - [in] A pointer to a FILETIME structure containing the file
time to convert to system date
--			and time format. This value must be less than 0x8000000000000000.
Otherwise, the function fails.
--		lpSystemTime - [out] A pointer to a SYSTEMTIME structure to receive the
converted file time.
	--	Return Value
	--		If the function succeeds, the return value is nonzero.
--		If the function fails, the return value is zero. To get extended error
information, call GetLastError.

	--	SYSTEMTIME - 11/30/2006 
--		This structure represents a date and time using individual members for the
month, day, year, weekday,
	--		hour, minute, second, and millisecond. 
	--	Syntax
	--		typedef struct _SYSTEMTIME { 
	--		WORD wYear; 
	--		WORD wMonth; 
	--		WORD wDayOfWeek; 
	--		WORD wDay; 
	--		WORD wHour; 
	--		WORD wMinute; 
	--		WORD wSecond; 
	--		WORD wMilliseconds; 
	--	} SYSTEMTIME;
	--	Members
	--		wYear - Specifies the current year. 
--		wMonth - Specifies the current month; January = 1, February = 2, and so on.
--		wDayOfWeek - Specifies the current day of the week; Sunday = 0, Monday = 1,
and so on.
	--		wDay - Specifies the current day of the month. 
	--		wHour - Specifies the current hour. 
	--		wMinute - Specifies the current minute. 
	--		wSecond - Specifies the current second. 
	--		wMilliseconds - Specifies the current millisecond. 
	--	Remarks
--		Millisecond granularity may not be supported by a hardware platform. The
caller of this function should
	--		not rely on more than second granularity.
--		It is not recommended that you add and subtract values from this structure
to obtain relative times.
	--		The following list shows tasks to perform instead: 
	--			Convert the SYSTEMTIME structure to a FILETIME structure.
	--			Copy the resulting FILETIME structure to a ULARGE_INTEGER structure.
	--			Use usual 64-bit arithmetic on the ULARGE_INTEGER value.
	--	Requirements
	--	Header: Winbase.h.

FileTimeToLocalFileTime = define_c_func(kernel32, "FileTimeToLocalFileTime",
repeat(C_POINTER, 2), C_LONG),
	--	Converts a file time to a local file time.
	--	BOOL FileTimeToLocalFileTime(
	--		const FILETIME* lpFileTime,
	--		LPFILETIME lpLocalFileTime
	--	);
	--	Parameters
--		lpFileTime - [in] A pointer to a FILETIME structure containing the
UTC-based file time to be
	--			converted into a local file time. 
--		lpLocalFileTime - [out] A pointer to a FILETIME structure to receive the
converted local file time.
	--			This parameter cannot be the same as the lpFileTime parameter. 
	--	Return Value
	--		If the function succeeds, the return value is nonzero.
--		If the function fails, the return value is zero. To get extended error
information, call GetLastError.
	--	Remarks
--		FileTimeToLocalFileTime uses the current settings for the time zone and
daylight saving time.
--		Therefore, if it is daylight saving time, this function will take daylight
saving time into account,
--		even if the time you are converting is in standard time. You can use the
following sequence of functions
	--		as an alternative.
	--			FileTimeToSystemTime 
	--			SystemTimeToTzSpecificLocalTime 
	--			SystemTimeToFileTime 

CreateFileA = define_c_func(kernel32, "CreateFileA", repeat(C_POINTER, 7),
C_POINTER),
	CloseHandle = define_c_func(kernel32, "CloseHandle", {C_POINTER}, C_LONG), 
GetTimeZoneInformation = define_c_func(kernel32, "GetTimeZoneInformation",
{C_POINTER}, C_ULONG),

	--	GetTimeZoneInformation
--		This function retrieves the current time-zone parameters. These parameters
control the translations
	--		between UTC and local time. 
--	DWORD GetTimeZoneInformation( LPTIME_ZONE_INFORMATION lpTimeZoneInformation
);
	--	Parameters
--		lpTimeZoneInformation - [out] Pointer to a TIME_ZONE_INFORMATION structure
to receive the current
	--			time-zone parameters. 
	--	Return Values
	--		If the function succeeds, the return value is one of the following values:
	--		Value Description 
--			TIME_ZONE_ID_UNKNOWN = 0 The system cannot determine the current time
zone. If daylight saving
--				time is not used in the current time zone, this value is returned because
there are no
	--				transition dates. 
--			TIME_ZONE_ID_STANDARD = 1 The system is operating in the range covered by
the StandardDate member
	--				of the TIME_ZONE_INFORMATION structure. 
--			TIME_ZONE_ID_DAYLIGHT = 2 The system is operating in the range covered by
the DaylightDate member
	--				of the TIME_ZONE_INFORMATION structure. 
	--		If the function fails, the return value is TIME_ZONE_ID_UNKNOWN. 
	--	Remarks
--		All translations between UTC and local time are based on the following
formula.
	--		UTC = local time + bias 
	--		The bias is the difference, in minutes, between UTC and local time. 
--		If a call to SetTimeZoneInformation supplies a bias value but no transition
date,
--			GetTimeZoneInformation will return either TIME_ZONE_ID_STANDARD or
TIME_ZONE_ID_DAYLIGHT.
	--	Requirements
	--		Header: Winbase.h.
	--		Link Library: Coredll.lib.

TIME_ZONE_ID_UNKNOWN = 0,
TIME_ZONE_ID_STANDARD = 1,
TIME_ZONE_ID_DAYLIGHT = 2,

-- reserving some memory
mem_area = allocate(72 + 24 + 48), 

-- area for FILETIME raw data
file_create_time = mem_area, 
file_last_access = mem_area+8, 
file_last_write = mem_area+16, 

-- area for local FILETIME raw data
local_file_create_time = mem_area+24, 
local_file_last_access = mem_area+32, 
local_file_last_write = mem_area+40, 

-- area for SYSTEMTIME usable data
system_create_time = mem_area+48, 
system_last_access = mem_area+64, 
system_last_write = mem_area+80, 

-- area for local SYSTEMTIME usable data
local_system_create_time = mem_area+96, 
local_system_last_access = mem_area+112, 
local_system_last_write = mem_area+128, 

-- this flag is used later: it tells the OS to fail upon opening a file
-- whiCloseHandle doesn't exist
OPEN_EXISTING = 3, 

-- and get some storage for a TIME_ZONE_INFO structure
TimeZoneInformation = allocate(172)

integer bias, std_bias, svt_bias, TIME_ZONE_ID

-- fill the structure
TIME_ZONE_ID = c_func(GetTimeZoneInformation, {TimeZoneInformation})
-- rc may be an error code, or say if we are in std time, xaving time or don't
know
bias = peek4s(TimeZoneInformation)
--warnErr(sprint(TIME_ZONE_ID) & " " & sprint(bias))
std_bias = bias+peek4s(TimeZoneInformation+84) -- usually = bias
svt_bias = bias+peek4s(TimeZoneInformation+168)
-- free memory
free(TimeZoneInformation)

-- set hfile to a handle on your file
hfile = c_func(CreateFileA, {allocate_string(fname), 0, 0, 0, OPEN_EXISTING, 0,
0})
                 
if not hfile then
	-- something went wrong, do something useful here
	warnErr("can't open " & fname) abort(1)
end if

-- now we have a file handle, let's get the timestamps
-- you may wish to Check if return_code = 0, which notifies of an error
return_code = c_func(GetFileTime, {hfile, file_create_time, file_last_access,
file_last_write})

-- convert the data to something of use. Again, return_code = 0 means something
went wrong
return_code = c_func(FileTimeToSystemTime, {file_create_time,
system_create_time})
makeDate("system_create_time", system_create_time)

return_code = c_func(FileTimeToSystemTime, {file_last_access,
system_last_access})
makeDate("system_last_access", system_last_access)

return_code = c_func(FileTimeToSystemTime, {file_last_write, system_last_write})
makeDate("system_last_write", system_last_write)

wwait(sprintf("modified   = %s \ncreation    = %s \nlastAccess = %s", {updated, 
creation, lastAccess}))

-- now convert to local time
return_code = c_func(FileTimeToLocalFileTime, {file_create_time,
local_file_create_time})
return_code = c_func(FileTimeToSystemTime, {local_file_create_time,
local_system_create_time})
makeDate("local_system_create_time", local_system_create_time)

return_code = c_func(FileTimeToLocalFileTime, {file_last_access,
local_file_last_access})
return_code = c_func(FileTimeToSystemTime, {local_file_last_access,
local_system_last_access})
makeDate("local_system_last_access", local_system_last_access)

return_code = c_func(FileTimeToLocalFileTime, {file_last_write,
local_file_last_write})
return_code = c_func(FileTimeToSystemTime, {local_file_last_write,
local_system_last_write})
makeDate("local_system_last_write", local_system_last_write)

wwait(sprintf("modified   = %s \ncreation    = %s \nlastAccess = %s",
{local_updated,
local_creation, local_lastAccess}))

return_code = c_func(CloseHandle, {hfile})


Yours, OtterDad

Don't sweat it -- it's not real life. It's only ones and zeroes. Gene Spafford

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu