*********************************************************
* Function getftime
* Return the create date and time, last access date and time,
* last write date and time from a passed filename.
*
* Passed:
* lcFileName (by value): fully-qualified filename
*
* Returns:
* Logical .t. if completed successfully, .f. if not.
*
* Return variables:
* ldCreateDate (date, by reference): Creation date
* lcCreateTime (character, by reference): Creation time (HH:MM:SS.mm)
* ldAccessDate (date, by reference): Last access date
* lcAccessTime (character, by reference): Last access time (HH:MM:SS.mm)
* lcLastWriteDate (date, by reference): Last write date
* lcLastWriteTime (character, by reference): Last write time (HH:MM:SS.mm)
STORE {} TO m.createdate, m.accessdate, m.lastwritedate
STORE "" TO m.createtime, m.accesstime, m.lastwritetime
m.OK = getftime("C:\Test.txt", @m.createdate, @m.createtime, ;
@m.accessdate, @m.accesstime, @m.lastwritedate, @m.lastwritetime)
IF m.OK
? "Create date: ", m.createdate
? "Create time: " , m.createtime
? "Last access date: ", m.accessdate
? "Last access time: ", m.accesstime
? "Last write date: ", m.lastwritedate
? "Last write time: ", m.lastwritetime
ELSE
? "Error getting file times"
ENDIF
* End of usage example.
FUNCTION getftime
PARAMETERS lcFileName, ldCreateDate, lcCreateTime, ldAccessDate,;
lcAccessTime, ldLastWriteDate, lcLastWriteTime
* DEFINEs for file share mode.
#DEFINE FILE_SHARE_READ 1
#DEFINE FILE_SHARE_WRITE 2
* DEFINEs for access right
#DEFINE GENERIC_READ hex2dec("80000000")
#DEFINE GENERIC_WRITE hex2dec("40000000")
* DEFINES for Create Mode.
#DEFINE CREATE_NEW 1
#DEFINE CREATE_ALWAYS 2
#DEFINE OPEN_EXISTING 3
#DEFINE OPEN_ALWAYS 4
#DEFINE TRUNCATE_EXISTING 5
* File flag.
#DEFINE FILE_ATTRIBUTE_NORMAL hex2dec("80")
* Blank filename or nonexistent file, no need to continue.
IF EMPTY(lcFileName) OR NOT FILE(lcFileName)
RETURN .F.
ENDIF
DECLARE INTEGER CreateFile IN kernel32;
STRING lpFileName, INTEGER dwDesiredAccess,;
INTEGER dwShareMode, INTEGER lpSecurityAttributes,;
INTEGER dwCreationDisposition,;
INTEGER dwFlagsAndAttributes, INTEGER hTemplateFile
DECLARE INTEGER GetFileTime IN kernel32;
INTEGER hFile, STRING @lpCreationTime,;
STRING @lpLastAccessTime, STRING @lpLastWriteTime
DECLARE INTEGER FileTimeToLocalFileTime IN kernel32;
STRING @lpFileTime, STRING @lpLocalFileTime
DECLARE INTEGER FileTimeToSystemTime IN kernel32;
STRING @lpFileTime, STRING @lpSystemTime
DECLARE INTEGER GetLastError IN kernel32
DECLARE INTEGER CloseHandle IN kernel32 INTEGER hObject
* 2 DWORDs * 4 bytes each = an 8-byte buffer.
STORE SPACE(8) TO CreationTime, LastAccessTime, lastwritetime
* Same buffers for local time.
STORE SPACE(8) TO LocalCreationTime,;
LocalLastAccessTime, LocalLastWriteTime
* 16-byte buffers for when we convert from the FILETIME
* structs to the more human-readable SYSTEMTIME structures.
STORE SPACE(16) TO ctSystemTime, laSystemTime, lwSystemTime
* Open an existing file.
lhFileHandle = CreateFile(lcFileName, GENERIC_READ,;
FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
IF lhFileHandle <= 0
=MESSAGEB ("Error in CreateFile - " + lcFileName + ": Error code - " + ;
LTRIM(STR(GetLastError())))
RETURN .F.
ENDIF
* Make the GetFileTime call, to get Create, Access and Update times.
m.retval = GetFileTime (lhFileHandle,;
@CreationTime, @LastAccessTime, @lastwritetime)
IF m.retval = 0
* 32 = Sharing violation
* 87 = Invalid parameter
=MESSAGEB("Error calling GetFileTime. Error code: " + ;
LTRIM(STR(GetLastError())))
RETURN .F.
ENDIF
* Successfully performed the GetFileTime call -
* now convert each of the three times to local time.
* If any of them fail, then exit.
IF FileTimeToLocalFileTime (@CreationTime, @LocalCreationTime) = 0;
OR FileTimeToLocalFileTime (@LastAccessTime,@LocalLastAccessTime) = 0;
OR FileTimeToLocalFileTime (@lastwritetime, @LocalLastWriteTime) = 0
= MESSAGEB("FileTimeToLocalFileTime Failed. Error code: " + ;
LTRIM(STR(GetLastError())))
RETURN .F.
ENDIF
* Now you have a local filetime, convert each to a systemtime that
* you can work with.
* If any of the calls fail, then exit.
IF FileTimeToSystemTime (@LocalCreationTime, @ctSystemTime) = 0;
OR FileTimeToSystemTime (@LocalLastAccessTime, @laSystemTime) = 0;
OR FileTimeToSystemTime (@LocalLastWriteTime, @lwSystemTime) = 0
= MESSAGEB("FileTimeToSystemTime call failed. Error code: " ;
+ LTRIM(STR(GetLastError())))
RETURN .F.
ENDIF
ctstYear = Str2Word(LEFT(ctSystemTime, 2))
ctstMonth = Str2Word(SUBSTR(ctSystemTime, 3, 2))
ctstDayofWeek = Str2Word(SUBSTR(ctSystemTime, 5, 2))
ctstDay = Str2Word(SUBSTR(ctSystemTime, 7, 2))
ctstHour = Str2Word(SUBSTR(ctSystemTime, 9, 2))
ctstMinute = Str2Word(SUBSTR(ctSystemTime, 11, 2))
ctstSecond = Str2Word(SUBSTR(ctSystemTime, 13, 2))
ctstMilliSecond = Str2Word(SUBSTR(ctSystemTime, 15, 2))
* Unpack the integers in last access time SystemTime structure.
lastYear = Str2Word(LEFT(laSystemTime, 2))
lastMonth = Str2Word(SUBSTR(laSystemTime, 3, 2))
lastDayofWeek = Str2Word(SUBSTR(laSystemTime, 5, 2))
lastDay = Str2Word(SUBSTR(laSystemTime, 7, 2))
lastHour = Str2Word(SUBSTR(laSystemTime, 9, 2))
lastMinute = Str2Word(SUBSTR(laSystemTime, 11, 2))
lastSecond = Str2Word(SUBSTR(laSystemTime, 13, 2))
lastMilliSecond = Str2Word(SUBSTR(laSystemTime, 15, 2))
* Unpack the integers in last write time SystemTime structure.
lwstYear = Str2Word(LEFT(lwSystemTime, 2))
lwstMonth = Str2Word(SUBSTR(lwSystemTime, 3, 2))
lwstDayofWeek = Str2Word(SUBSTR(lwSystemTime, 5, 2))
lwstDay = Str2Word(SUBSTR(lwSystemTime, 7, 2))
lwstHour = Str2Word(SUBSTR(lwSystemTime, 9, 2))
lwstMinute = Str2Word(SUBSTR(lwSystemTime, 11, 2))
lwstSecond = Str2Word(SUBSTR(lwSystemTime, 13, 2))
lwstMilliSecond = Str2Word(SUBSTR(lwSystemTime, 15, 2))
* Close the file handle.
llRetCode = CloseHandle(lhFileHandle)
* Format the return variables.
ldCreateDate = CTOD(LTRIM(STR(ctstMonth)) + "/" + ;
LTRIM(STR(ctstDay)) + "/" + LTRIM(STR(ctstYear)))
lcCreateTime = PADL(LTRIM(STR(ctstHour)), 2, "0") + ":" + ;
PADL(LTRIM(STR(ctstMinute)), 2, "0") + ":" + ;
PADL(LTRIM(STR(ctstSecond)), 2, "0") + "." + ;
PADL(LTRIM(STR(ctstMilliSecond)), 3, "0")
ldAccessDate = CTOD(LTRIM(STR(lastMonth)) + "/" + ;
LTRIM(STR(lastDay)) + "/" + LTRIM(STR(lastYear)))
lcAccessTime = PADL(LTRIM(STR(lastHour)), 2, "0") + ":" + ;
PADL(LTRIM(STR(lastMinute)), 2, "0") + ":" + ;
PADL(LTRIM(STR(lastSecond)), 2, "0") + "." + ;
PADL(LTRIM(STR(lastMilliSecond)), 3, "0")
ldLastWriteDate = CTOD(LTRIM(STR(lwstMonth))+ ;
"/"+LTRIM(STR(lwstDay)) + "/" + LTRIM(STR(lwstYear)))
lcLastWriteTime = PADL(LTRIM(STR(lwstHour)), 2, "0") + ":" + ;
PADL(LTRIM(STR(lwstMinute)), 2, "0") + ":" + ;
PADL(LTRIM(STR(lwstSecond)), 2, "0") + "." + ;
PADL(LTRIM(STR(lwstMilliSecond)), 3, "0")
* Function hex2dec - Convert a character hex value into decimal.
* Handy for dealing with Hex declarations in API calls.
* Passed: m.hex (character hex value)
* Returns: Decimal value
FUNCTION hex2dec
PARAMETER m.hex
m.decimal = 0
FOR i = LEN(m.hex) TO 1 STEP -1
m.decimal = m.decimal + (AT(SUBSTR(m.hex, i, 1), ;
"0123456789ABCDEF") - 1) * 16 ^ (LEN(m.hex) - i)
NEXT
RETURN m.decimal
* Function str2word - Converts low-high format string representation
* to a 16-bit integer (word) value. Useful for unrolling structure
* members containg WORD types.
*
* Passed: Low-high string representation of 16-bit integer
* Returns: numeric value
FUNCTION Str2Word
PARAMETERS m.wordstr
PRIVATE i, m.retval
m.retval = 0
FOR i = 0 TO 8 STEP 8
m.retval = m.retval + (ASC(m.wordstr) * (2^i))
m.wordstr = RIGHT(m.wordstr, LEN(m.wordstr) - 1)
NEXT
RETURN m.retval
|