Author Topic: utFAT Patch List  (Read 22365 times)

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3243
    • View Profile
    • uTasker
utFAT Patch List
« on: January 05, 2010, 12:48:47 PM »
Hi All

It would be nice to have a new module without any patches, but on the other hand a development which doesn't need patches is of course a fantasy development and not very serious....so here goes.

1) The problem with the Freescale project serving corrupted PDFs was not a Freescale project problem but due to the HTTP module falsely checking the mime type from an undefined FLASH area (supposedly user content area). It was unfortunate that the Freescale memory layout resulted in PDFs being understood as having HTML content (whereas others - through luck - didn't) and these were thus parsed and some dynamic content inserts made (which cause PDF content to be modified).

The patch is in HTTP.c

About line 468

#ifdef SUPPORT_MIME_IDENTIFIER
    if (http_session->ucMimeType == UNKNOWN_MIME) {


Change to

#ifdef SUPPORT_MIME_IDENTIFIER
    if ((http_session->ucMimeType == UNKNOWN_MIME)
    #ifdef HTTP_UTFAT
        && (ucFile != 0)
    #endif

        ) {


Now document content in a format not recognised by the local mime interpreter (if PDFs was actually included in the mime table the problem also didn't result) will be excluded from HTML parsing when originating from the SD card.


2) 19.1.2010 When files are created the file length was not being set to zero. It was assuming that the entry would already be empty, which is false in cases of reuse of location previously used by directories or old files. The following additional line (uMemset()) actively zeroes the file length and solves this potential problem:

static void fnAddEntry(DIR_ENTRY_STRUCTURE_FAT32 *ptrEntry, unsigned long ulPresentCluster, unsigned char ucAttributes)
{
    ptrEntry->DIR_FstClusLO[0] = (unsigned char)ulPresentCluster;
    ptrEntry->DIR_FstClusLO[1] = (unsigned char)(ulPresentCluster >> 8 );
    ptrEntry->DIR_FstClusHI[0] = (unsigned char)(ulPresentCluster >> 16);
    ptrEntry->DIR_FstClusHI[1] = (unsigned char)(ulPresentCluster >> 24);
    ptrEntry->DIR_Attr = ucAttributes;
    uMemset(ptrEntry->DIR_FileSize, 0, sizeof(ptrEntry->DIR_FileSize));
    fnSetTimeDate(ptrEntry);
}




3) 20.1.2010 To correct the fact that the file modification time and date are set to zero on file writes, adjust the following three routines as follows:


static void fnSetTimeDate(DIR_ENTRY_STRUCTURE_FAT32 *ptrEntry, int iCreation) // {3}
{
    unsigned short usCreationTime = (CREATION_SECONDS | (CREATION_MINUTES << 5) | (CREATION_HOURS << 11));
    unsigned short usCreationDate = (CREATION_DAY_OF_MONTH | (CREATION_MONTH_OF_YEAR << 5) | (CREATION_YEAR << 9));
    ptrEntry->DIR_WrtTime[0] = (unsigned char)(usCreationTime);
    ptrEntry->DIR_WrtTime[1] = (unsigned char)(usCreationTime >> 8 );
    ptrEntry->DIR_LstAccDate[0] = ptrEntry->DIR_WrtDate[0] = (unsigned char)(usCreationDate);
    ptrEntry->DIR_LstAccDate[1] = ptrEntry->DIR_WrtDate[1] = (unsigned char)(usCreationDate >> 8 );
    if (iCreation != 0) {
        ptrEntry->DIR_CrtTime[0] = ptrEntry->DIR_WrtTime[0];
        ptrEntry->DIR_CrtTime[1] = ptrEntry->DIR_WrtTime[1];
        ptrEntry->DIR_CrtDate[0] = ptrEntry->DIR_LstAccDate[0];
        ptrEntry->DIR_CrtDate[1] = ptrEntry->DIR_LstAccDate[1];
    }
}

static void fnAddEntry(DIR_ENTRY_STRUCTURE_FAT32 *ptrEntry, unsigned long ulPresentCluster, unsigned char ucAttributes)
{
    ptrEntry->DIR_FstClusLO[0] = (unsigned char)ulPresentCluster;
    ptrEntry->DIR_FstClusLO[1] = (unsigned char)(ulPresentCluster >> 8 );
    ptrEntry->DIR_FstClusHI[0] = (unsigned char)(ulPresentCluster >> 16);
    ptrEntry->DIR_FstClusHI[1] = (unsigned char)(ulPresentCluster >> 24);
    ptrEntry->DIR_Attr = ucAttributes;
    uMemset(ptrEntry->DIR_FileSize, 0, sizeof(ptrEntry->DIR_FileSize));  // {2} set the file size to zero
    fnSetTimeDate(ptrEntry, 1);                                          // {3} add creation time
}

static void fnSetFileInformation(DIR_ENTRY_STRUCTURE_FAT32 *ptrFileEntry, unsigned long ulFileSize)
{
    ptrFileEntry->DIR_FileSize[0] = (unsigned char)(ulFileSize);         // update the file size
    ptrFileEntry->DIR_FileSize[1] = (unsigned char)(ulFileSize >> 8 );
    ptrFileEntry->DIR_FileSize[2] = (unsigned char)(ulFileSize >> 16);
    ptrFileEntry->DIR_FileSize[3] = (unsigned char)(ulFileSize >> 24);
    fnSetTimeDate(ptrFileEntry, 0);                                      // {3} set the modification time
}



4) 21.1.2010

In the function:
static unsigned long fnAllocateCluster(UTDISK *ptr_utDisk, unsigned long ulPresentCluster, unsigned char ucClusterType)

Correct cluster to FAT offset conversion:

    if (ucClusterType & NEW_RELATIVE_CLUSTER) {
        ulAbsoluteCluster = ulPresentCluster;
        ulFAT += (ulPresentCluster/(512/sizeof(signed long)));
    }



5) 12.2.2010

In the function:
extern int utReadFile(UTFILE *ptr_utFile, void *ptrBuffer, unsigned short usReadLength)

Correct a possible error when performing the sequence write, seek, read, write, where the final read could overwrite the final file sector :

        if (((ptr_utFile->ulFilePosition % ptr_utDisk->utFAT.usBytesPerSector) == 0)/* && (ptr_utFile->ulFileSize > ptr_utFile->ulFilePosition)*/) { // on a sector boundary when file end has not already been reached
            int iResult = fnNextSector(ptr_utDisk, &ptr_utFile->public_file_location);
            if (iResult != UTFAT_SUCCESS) {
                return iResult;
            }
        }



6) 16.2.2010

In the function:
static unsigned long fnAllocateCluster(UTDISK *ptr_utDisk, unsigned long ulPresentCluster, unsigned char ucClusterType)

Correction for cluster allocation when working with the FAT32 info block.


// Allocate a single new cluster
//
static unsigned long fnAllocateCluster(UTDISK *ptr_utDisk, unsigned long ulPresentCluster, unsigned char ucClusterType)
{
    unsigned long ulFAT = ptr_utDisk->utFAT.ulFAT_start;                 // sector in which the file's first cluster is located in
    unsigned long ulFatOriginal; // = ulFAT;
    unsigned long ulSectorContent[512/sizeof(signed long)];              // sector to read FAT32 sectors to
    unsigned long ulAbsoluteCluster;
    unsigned char ucClusterEntry;
    unsigned char ucOriginalCluster;
    if (ucClusterType & NEW_RELATIVE_CLUSTER) {
        ulAbsoluteCluster = ulPresentCluster;
      //ulFAT += (ulPresentCluster/(512/sizeof(signed long)));           // moved to be used also by info block referenced case
    }
    else {
        if ((ptr_utDisk->ucDiskFlags & FSINFO_VALID) && (ptr_utDisk->utFileInfo.ulNextFreeCluster <= ptr_utDisk->utFileInfo.ulFreeClusterCount)) { // the info block is valid so reference to next free cluster
            ulAbsoluteCluster = ptr_utDisk->utFileInfo.ulNextFreeCluster;
        }
        else {
            ulAbsoluteCluster = ptr_utDisk->ulDirectoryBase;
        }
        ulPresentCluster = ulAbsoluteCluster;
    }
    ulFAT += (ulPresentCluster/(512/sizeof(signed long)));
    ulFatOriginal = ulFAT;




7) 19.2.2010

In the function:
extern int utOpenDirectory(const CHAR *ptrDirPath, UTDIRECTORY *ptrDirObject)

This corrects a problem with chaining directory clusters when directory content grows to several hundred files


                if (iFullyQualifiedPath != 0) {
                   if (usDirFlags & UTDIR_SET_START) {
                        uMemcpy(ptrDiskLocation, &DirStart, sizeof(DirStart)); // set the location to the start of the lowest directory
                    }

                    return UTFAT_FILE_NOT_FOUND;
                }
                else {
                    return UTFAT_PATH_NOT_FOUND;
                }



Furthermore this also requires a change in
extern int utOpenFile(const CHAR *ptrFilePath, UTFILE *ptr_utFile, unsigned short usAccessMode)

A code block needs to be replaced as follows:


else if (usAccessMode & UTFAT_CREATE) {                              // file doesn't exist so we should create it
...
            if ((DIR_NAME_FREE == ptrFoundEntry->DIR_Name[0]) ....
....
            }
            else {
                int iResult = fnNextDirectoryEntry(ptr_utDisk, ptrDiskLocation);
                if (UTFAT_DIRECTORY_AREA_EXHAUSTED == iResult) {         // the present directory cluster end has been reached so a new one must be started
                    ptrDiskLocation->directory_location.ulSector--;      // set back to previous sector
                    iResult = fnDirectorySectorCreate(ptr_utDisk, &ptrDiskLocation->directory_location); // create additional directory cluster
                }
                if (iResult != UTFAT_SUCCESS) {
                    return iResult;                                      // return error
                }                                                        // else continue to create the file entry in the new cluster

            }






...place for more...:-)



Regards

Mark

 
« Last Edit: February 20, 2010, 12:25:52 AM by mark »

Offline Kevin

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: utFAT Patch List
« Reply #1 on: July 05, 2010, 06:34:19 PM »
Mark-

When I add #7  (first part) above, I get the following

c:\documents and settings\kevin\my documents\downloads\development\utasker\utaskerv1.4_lpc\utasker\utfat\mass_storage.c(2016) : error C2065: 'usDirFlags' : undeclared identifier
c:\documents and settings\kevin\my documents\downloads\development\utasker\utaskerv1.4_lpc\utasker\utfat\mass_storage.c(2016) : error C2065: 'UTDIR_SET_START' : undeclared identifier
c:\documents and settings\kevin\my documents\downloads\development\utasker\utaskerv1.4_lpc\utasker\utfat\mass_storage.c(2017) : error C2065: 'DirStart' : undeclared identifier
c:\documents and settings\kevin\my documents\downloads\development\utasker\utaskerv1.4_lpc\utasker\utfat\mass_storage.c(2017) : error C2065: 'DirStart' : undeclared identifier

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3243
    • View Profile
    • uTasker
Re: utFAT Patch List
« Reply #2 on: July 07, 2010, 11:16:13 AM »
Hi Kevin

I am not sure about #7 since this really seems to need a few other changes that I have in my present version - a quick fix to it is not obvious so I think that it will need to be avoided for the time being. Since I am working towards a new release version with various new features it may be best to generally solve it with the utFAFV1.1 version that will be included in it.

Regards

Mark

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: utFAT Patch List
« Reply #3 on: July 22, 2010, 07:04:10 AM »
Hi Mark,
  I have been using the current uFat for a few months now, and working really well with no problems. I see that you will have an update soon, are there any fixes for current version which I may have not come up against yet? 
 
Is there a list of changes/additions that will be included in your next version?

Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3243
    • View Profile
    • uTasker
Re: utFAT Patch List
« Reply #4 on: July 23, 2010, 10:02:39 PM »
Hi Neil

You have received all relevant patches (note to others: Neil was one of the first intensive users of the utFAT and some of his experienced resulted in a number of patches and also a few new features - he has also been using a newer version during this stage) so there should be nothing significant in the next release. There will also be no compatibility issues.

The next release will simply be a consolidated version with all up-to-date changes. It will also include SD card controller support (for the LPC23XX and LPC24XX since these are the only chips supported with such a peripheral).

Regards

Mark