Shop OBEX P1 Docs P2 Docs Learn Events
FSRW - modified date not working — Parallax Forums

FSRW - modified date not working

I am having a problem with the file modification date using FSRW Version 2.6. When you use "popen(s, mode)" with mode="a" for append or "w" for write the file's "last modified date and time" should be updated. I am using "setdate(year, month, day, hour, minute, second)" prior to the popen command to set up the date and time values. This works because if I use popen to create a new file its creation date and time are correctly written.

When I use my laptop running Windows 10 to view the SD card directory the file's modification date and time is the same as its creation date and time even though I have written or append data to it days after its creation. If I am looking at the code correctly the creation date and time is set by
brwlong(s+$e, i) ' write create time and date
and the modification date and time are set using
brwlong(s+$16, i) ' write last modified date and time

How could one work correctly without the other? Can anyone suggest where I am missing the boat?

Here is the code within fsrw:
pub setdate(year, month, day, hour, minute, second)
{{
'   Set the current date and time, as a long, in the format
'   required by FAT16.  Various limits are not checked.
}}
   pdate := ((year-1980) << 25) + (month << 21) + (day << 16)
   pdate += (hour << 11) + (minute << 5) + (second >> 1)
pub popen(s, mode) : r | i, sentinel, dirptr, freeentry
{{
'   Close any currently open file, and open a new one with the given
'   file name and mode.  Mode can be "r" "w" "a" or "d" (delete).
'   If the file is opened successfully, 0 will be returned.  If the
'   file did not exist, and the mode was not "w" or "a", -1 will be
'   returned.  Otherwise abort will be called with a negative error
'   code.
}}
   pclose
   i := 0
   repeat while (i<8 and byte[s] and byte[s] <> ".")
      padname[i++] := uc(byte[s++])
   repeat while (i<8)
      padname[i++] := " "
   repeat while (byte[s] and byte[s] <> ".")
      s++
   if (byte[s] == ".")
      s++
   repeat while (i<11 and byte[s])
      padname[i++] := uc(byte[s++])
   repeat while (i < 11)
      padname[i++] := " "
   sentinel := 0
   freeentry := 0
   repeat dirptr from rootdir to rootdirend - DIRSIZE step DIRSIZE
      s := readbytec(dirptr)
      if (freeentry == 0 and (byte[s] == 0 or byte[s] == $e5))
         freeentry := dirptr
      if (byte[s] == 0)
         sentinel := dirptr
         quit
      repeat i from 0 to 10
         if (padname[i] <> byte[s][i])
            quit
      if (i == 11 and 0 == (byte[s][$0b] & $18)) ' this always returns
         fclust := brword(s+$1a)
         if (filesystem == 2)
            fclust += brword(s+$14) << 16
         firstcluster := fclust
         filesize := brlong(s+$1c)
         if (mode == "r")
            frem := (clustersize) <# (filesize)
            return 0
         if (byte[s][11] & $d9)
            abort(-6) ' no permission to write
         if (mode == "d")
            brwword(s, $e5)
            if (fclust)
               freeclusters(fclust)
            flushifdirty
            return 0
         if (mode == "w")
            brwword(s+$1a, 0)
            brwword(s+$14, 0)
            brwlong(s+$1c, 0)
            writelink := 0
            direntry := dirptr
            if (fclust)
               freeclusters(fclust)
            bufend := SECTORSIZE
            fclust := 0
            filesize := 0
            frem := 0
            return 0
         elseif (mode == "a")
' this code will eventually be moved to seek
            frem := filesize
            freeentry := clustersize
            if (fclust => endofchain)
               fclust := 0
            repeat while (frem > freeentry)
               if (fclust < 2)
                  abort(-7) ' eof repeat while following chain
               fclust := nextcluster
               frem -= freeentry
            floc := filesize & constant(!(SECTORSIZE - 1))
            bufend := SECTORSIZE
            bufat := frem & constant(SECTORSIZE - 1)
            writelink := 0
            direntry := dirptr
            if (bufat)
               sdspi.readblock(datablock, @buf)
               frem := freeentry - (floc & (freeentry - 1))
            else
               if (fclust < 2 or frem == freeentry)
                  frem := 0
               else
                  frem := freeentry - (floc & (freeentry - 1))
            if (fclust => 2)
               followchain
            return 0
         else
            abort(-3) ' bad argument
   if (mode <> "w" and mode <> "a")
      return -1 ' not found
   direntry := freeentry
   if (direntry == 0)
      abort(-2) ' no empty directory entry
   ' write (or new append): create valid directory entry
   s := readbytec(direntry)
   bytefill(s, 0, DIRSIZE)
   bytemove(s, @padname, 11)
   brwword(s+$1a, 0)
   brwword(s+$14, 0)
   i := pdate
   brwlong(s+$e, i) ' write create time and date
   brwlong(s+$16, i) ' write last modified date and time
   if (direntry == sentinel and direntry + DIRSIZE < rootdirend)
      brwword(readbytec(direntry+DIRSIZE), 0)
   flushifdirty
   writelink := 0
   fclust := 0
   bufend := SECTORSIZE
   ' return r (default return)

And this is my code for setting the date and time:
PUB SetSDcardTime

'Read the current time and date from the RTC
  RTC.readtime
'Set date and time variable in SDcard utility setdate(year, month, day, hour, minute, second)    
  SDcard.setdate( RTC.clockYear, RTC.clockMonth, RTC.clockDate, RTC.clockHour, RTC.clockMinute, RTC.clockSecond )

  RETURN

Comments

  • Tracy AllenTracy Allen Posts: 6,656
    edited 2016-06-09 16:10
    I've been using a version of FSRW I modified to track both creation and modified dates and it works. Compare it to yours. From the comments:
            v2.6A  TTA  formatting, comments moved under method, some edited.  Methods capitalized
            v2.6B TTA Nextfile method captures the create and modified datetimes as longs,
                      methods GetCreated and GetModified return those datetimes as longs.
                      Popen(s, mode) updates the created date location only when file is opened as mode = "w".
                      The "modified" date/time location is updated on either mode="a" or mode="w".
    
  • Your version is updating the modified date correctly when accessing it with mode ="a".

    Thank you very much!
Sign In or Register to comment.