⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatlib.c

📁 The high portable FAT filesystem library for embedded system.
💻 C
📖 第 1 页 / 共 3 页
字号:
			filesOpenedRead--;
			openedRead[i].fileHandle = -1;
			return 0;
		}
	}
	for(i = 0; i < filesOpenedWrite; i++)
	{
		if(openedWrite[i].fileHandle == fileHandle)
		{
			filesOpenedWrite--;
			openedWrite[i].fileHandle = -1;
			return 0;
		}
	}
	return -1;
}

/**
 *	determines the location of the cluster of the file or directory
 *	pointed to by the input pathname.  Only the first token in 
 *	the string pointed to by pathname is used (anything before '\').
 *
 *	@param	buf			the buffer to be used to access the MMC/SD card
 *	@param	pathname	pointer to the string of the pathname
 *	@param	cluster		location of the current directory where the
 *						file or directory being seek is located
 *	@param	control		determines whether a file or a directory is being seek
 *	@param	fileSize	stores the size of the file being seeked
 *
 *	@return	0			if the directory or file does not exist
 *	@return ...			the first cluster of the directory or file being seeked
 **/
static unsigned long getFirstCluster(const char *pathname, unsigned long cluster, unsigned char *buf, boolean control, unsigned long * fileSize)
{
	int offset = 0;
	unsigned int sectorCount;
	unsigned long sector;		
	unsigned char i, j;
	unsigned char tokenLength = 0;		// path name contails tokes less than 255 characters long
	const char *tempPathname;
	boolean matchingNames;
	boolean targetFound;

	if((cluster == 1)&&(fileSys == FAT16))
	{
		sector = rootDirectory;
	}
	else
	{
        return 0;
	}

	tempPathname = pathname;

	while((*tempPathname != 0x5C)&&(*tempPathname))
	{
		tokenLength++;
		tempPathname++;
	}
	
	targetFound = FALSE;
	sectorCount = 0;
	i = 0;
	readSector(sector, buf);
	if(((tokenLength < 13)&&(control == FILE)))
	{	
		while((targetFound == FALSE)&&(sector > 0))
		{
			offset = i * 32;
			tempPathname = pathname;
			matchingNames = TRUE;

            if (control == FILE)
			{								
                if (buf[offset] == '\0')
                {
                    // End of entries.
                    break;
                }

                // Check attributes except for ARCHIVE or READONLY, and for deleted entries:
				if(((buf[11+offset] & 0xDE) == 0x00)&&((buf[offset] & 0xFF) != 0xE5))
				{
					for(j = 0; j < 8; j++)
					{					
                        if (*tempPathname != '.' && *tempPathname != '\0')
                        {
                            // Before end of filename, characters must match:
                            if (!charEquals(buf[offset+j], *tempPathname))
                            {
                                matchingNames = FALSE;
                            }

							tempPathname++;
                        }
						else if ((buf[offset+j]) != ' ')
						{
                            // After end of filename, must have blanks.
							matchingNames = FALSE;
						}
					}

                    if (*tempPathname != '\0')
                    {
                        tempPathname++;
                    }

					for(j = 8; j < 11; j++)
					{					
                        if (*tempPathname != '\0')
                        {
                            // Before end of extension, characters must match:
                            if (!charEquals(buf[offset+j], *tempPathname))
                            {
                                matchingNames = FALSE;
                            }

							tempPathname++;
                        }
						else if ((buf[j+offset]) != ' ')
						{
                            // After end of extension, must have blanks.
							matchingNames = FALSE;
						}
					}

					if (matchingNames)
					{
						targetFound = TRUE;
					}
				}

			}
			i++;
			if(i == 16)		// 16 = directory entries per sector (fixed number)
			{
				i = 0;
				sectorCount++;
				if((cluster == 1)&&(fileSys == FAT16))
				{
					if( sectorCount < rootSectors )
					{
						sector++;
					}
					else
					{
						sector = 0;
					}
				}
				else
				{
					if(sectorCount != sectorsPerCluster)
					{
						sector++;
					}
					else
					{
						sectorCount = 0;
						cluster = getNextFAT(cluster, buf);
						if((cluster <= 0xFFF6)&&(cluster >= 2))
						{
							sector = (cluster - 2) * sectorsPerCluster + dataStarts;								
						}
						else
						{
							sector = 0;
						}
					}
				}
				readSector(sector, buf);
			}		
		}
	}

	if(targetFound)
	{
		cluster = buf[26+offset];
		cluster |= (unsigned long int)buf[27+offset] << 8;
		
		*fileSize = buf[28+offset];
		*fileSize += (unsigned long int)buf[29+offset] << 8;
		*fileSize += (unsigned long int)buf[30+offset] << 16;
		*fileSize += (unsigned long int)buf[31+offset] << 24;
	}
	else
	{
		cluster = 0;
	}
	return cluster;
}


/**
 *	creates a new entry (file or directory) at the location indicated by the
 *	input cluster.  The input control determines whether a file or a
 *	directory is created
 *	*****ONLY FILES AND DIRECTORY WITH SHORT FILE NAMES ARE SUPPORTED
 *
 *	@param	buf			the buffer to be used to access the MMC/SD card	
 *	@param	entryName	pointer to the name of the new entry
 *	@param	cluster		location of the current directory where the new entry will be added
 *	@param	control		FILE or DIRECTORY
 *
 *	@return	0			if an error occurs while adding a new entry
 *	@return	...			the location of the first cluster of the new entry
 **/
static unsigned long createNewEntry(const char *entryName, unsigned long cluster, unsigned char *buf, boolean control)
{
	unsigned int offset;
	unsigned int sectorCount = 0;
	unsigned int tokenLength = 0;		
	unsigned long sector;
	unsigned long newCluster;
	unsigned char i;	
	const char *tempEntryName;	
	boolean done = FALSE;

    // Note:  findEmptyCluster() will mark the returned cluster in the FAT
    // as used.  If we fail for some other reason below, we should really
    // free the newCluster, but we don't right now.  Also, unless we are
    // creating a directory, we really shouldn't allocate a first cluster
    // until some data is written to the file.  Additionally, if we re-use a
    // deleted entry, we should re-use the cluster chain, adding clusters as
    // required, but we don't do that right now either.
	newCluster = findEmptyCluster(buf);
	if(newCluster == 0)
	{
		return 0;	// no more empty cluster
	}

	if((cluster == 1) && (fileSys == FAT16))
	{
		sector = rootDirectory;
	}
	else
	{
		sector = (cluster - 2) * sectorsPerCluster + dataStarts;		
	}

	tempEntryName = entryName;

	while((*tempEntryName != '.')&&(*tempEntryName)&&(*tempEntryName != 0x5C))
	{
		tokenLength++;
		tempEntryName++;
	}

	while(!done)
	{				
		readSector(sector, buf);
		i = 0;
		while(i < 16)
		{
			offset = i * 32;			
			if(((buf[offset] & 0xFF) == 0x00) || ( (buf[offset] & 0xFF) == 0xE5) )
			{
				done = TRUE;
				i = 15;
			}
			i++;
		}
		if(!done)
		{
			sectorCount++;
			if((cluster == 1)&&(fileSys == FAT16))
			{
				if(sectorCount < rootSectors)
				{
					sector++;
				}
				else
				{
					return 0;	// no more root directory
				}
			}
			else
			{
                return 0;
			}				
		}
	}

	if(control == FILE)
	{
		buf[offset+11] = 0x20;
		if(tokenLength < 9)
		{			
			for(i = 0; i < 8; i++)
			{
				if(*entryName != '.')
				{
					if((*entryName >= 'a')&&(*entryName <= 'z'))
					{
						buf[offset+i] = (*entryName - 32);
					}
					else
					{
						buf[offset+i] = *entryName ;
					}
					entryName++;
				}
				else
				{
					buf[offset+i] = 0x20;
				}
			}
			entryName++;
			for(i = 8; i < 11; i++)
			{
				if(*entryName)
				{
					if((*entryName >= 'a')&&(*entryName <= 'z'))
					{
						buf[offset+i] = (*entryName - 32);
					}
					else
					{
						buf[offset+i] = *entryName ;
					}
					entryName++;
				}
				else
				{
					buf[offset+i] = 0x20;
				}
			}						
		}
		else
		{
			// file with long file name
			return 0;
		}
	}

	buf[offset+12] = 0x00;
	buf[offset+13] = 0x00;

    // Set the date and time to January 02, 2005 21:00:00 .
    // If a real time clock is available, we could use it.
	buf[offset+14] = (04 >> 1) & 0x1F;  // Seconds.
	buf[offset+14] |= 03 << 5;  // Part of minutes.
	buf[offset+22] = buf[offset+14];

	buf[offset+15] = (03 >> 3) & 0x07;  // More of minutes.
	buf[offset+15] |= 21 << 3;  // Hours.
	buf[offset+23] = buf[offset+15];			
	
	buf[offset+16] = 02 & 0x1F;     // Day.
	buf[offset+16] |= (01 << 5) & 0xE0;   // Part of month.
	buf[offset+18] = buf[offset+16];
	buf[offset+24] = buf[offset+16];
				
	buf[offset+17] = (01 >> 3) & 0x01;   // More of month.
	buf[offset+17] |= (((2005 - 1980) & 0xFF) << 1) & 0xFE;  // Year.
	buf[offset+19] = buf[offset+17];
	buf[offset+25] = buf[offset+17];

	buf[offset+26] = (newCluster & 0xFF);
	buf[offset+27] = (newCluster >> 8) & 0xFF;

	for(i = 28; i < 32; i++)
	{
		buf[offset+i] = 0x00;
	}
	writeSector(sector, buf);

	return newCluster;
}


/**
 *	finds the index of the for the array of pointers which
 *	corresponds to the input file handle.
 *
 *	@param	handle		the handle of the file being seeked
 *
 *	@return	-1			invalid file handle
 *	@return	...			the index to the correct file pointer
 **/
static signed char findFileIndex(signed char handle)
{
	signed char i, tempIndex;

	for(i = 0; i < BUFFER_SIZE; i++)
	{
        tempIndex = openedWrite[i].fileHandle;

		if(openedRead[i].fileHandle != -1)
		{
			if(openedRead[i].fileHandle == handle)
			{
					return i;
			}
		}
		if(tempIndex != -1)
		{
			if(tempIndex == handle)
			{
					return i;
			}
		}
	}
	return -1;
}

/**
 *	checks to see if the file indicated by the input cluster
 *	is already opened for either reading or writing
 *
 *	@pre	the input must be the location of the first cluster 
 *			of a file
 *	@param	cluster		first cluster of the file being checked
 *
 *	@return	-1			file is already opened for reading
 *	@return	-2			file is already opened for writing
 *	@return	0			file is currently not opened
 **/
static signed char openedCheck(unsigned long cluster)
{
	unsigned char i;
	for(i = 0; i < BUFFER_SIZE; i++)
	{
		if(openedRead[i].fileHandle != -1)
		{
			if(openedRead[i].firstCluster == cluster)
			{
				return -1;
			}
		}
	}
	for(i = 0; i < BUFFER_SIZE; i++)
	{
		if(openedWrite[i].fileHandle != -1)
		{
			if(openedWrite[i].firstCluster == cluster)
			{
				return -2;
			}
		}
	}
	return 0;
}

/**
 *	opens the file indicated by the input path name.  If the pathname
 *	points to a valid file, the file is added to the list of currently
 *	opened files for reading and the unique file handle is returned.
 *
 *	@param	pathname	a pointer to the location of the file to be opened
 *	@param	buf			the buffer to be used to access the MMC/SD card
 *
 *	@return	-1			invalid pathname
 *	@return	-2			file does not exist
 *	@return	-3			file already opened for writing
 *	@return -4			file already opened for reading
 *	@return -10			no handles available
 *	@return	-20			memory card error
 *	@return	-128		other error
 *	@return	...			file handle of sucessfully opened file
 **/
signed char fat_openRead(const char *pathname)
{
    char buf[SECTOR_SIZE];
	const char *tempPathname;
	unsigned long cluster;
	unsigned long tempCluster;
	unsigned long fileSize = 0;
	signed char i = 0;
	signed char index = -1;

	if(detectCard() == FALSE)
	{
		return -20;
	}

	if(filesOpenedRead >= BUFFER_SIZE)
	{
		return -10;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -