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