Exemplo n.º 1
0
//*************************************************************************
//  Function:		CETYPE FS_Flush(FSFILE* filePtr)
//  Summary:		Update file information and FAT entry for the file
//  Input:
//    				filePtr -  Pointer to the file to flush to disk
//  Return Values:
//    				CE_GOOD 	- File flushed successfully 
//    				Other code 	- Error closing the file
//  Description:
//    				This function will update the directory entry for the 
//   				file pointed to by 'fo' with the information contained
//    				in 'fo,' including the new file size and attributes.
//    				Timestamp information will also be updated. The file 
//					entry will then be written to the device.  Finally, 
//					the memory used for the specified file object will be 
//					freed from the array of FSFILE objects.
//  Remarks:
//    				A function to flush data to the device without closing 
//					the file can be created by removing the portion of this
//    				function that frees the memory and the line that clears
//    				the write flag.
//*************************************************************************
CETYPE FS_Flush(FSFILE   *filePtr)
	{
 	//----------------------------------------------------------------
	// Validate conditions and parameters
 	//----------------------------------------------------------------
 	if (!SDFS_InitStatus)
 		return CE_NOT_INIT;		// FS is not initialized!
 	if (NULL == filePtr)
 		return CE_INVALID_ARGUMENT;		
 	//----------------------------------------------------------------
    CETYPE 	RC;
 	//----------------------------------------------------------------
    if	( !FS_IsReadOnly(filePtr) )
    	{
        // Save directory entry for the file
    	RC = SDFS_DataCacheWrite(	filePtr->dirLBA, &filePtr->dirFileEntry,
						   	   		filePtr->dirOffset, sizeof(DIRENTRY) );
		if (CE_GOOD != RC)
			return RC;
	    // Flush data
        if ( (RC = SDFS_DataCacheFlush()) != CE_GOOD)
			return RC;
    	}
 	//----------------------------------------------------------------
    return CE_GOOD;
	} 
Exemplo n.º 2
0
//*********************************************************************************
//  Function:		CETYPE FS_Write(FSFILE* filePtr, const void* origin, WORD length)
//  Summary:		Write data to a file
//  Conditions:		File opened in FS_CREATE_NEW, FS_APPEND, or FS_OPEN_EXISTING mode
//  Input:
//    				filePtr	-	Pointer to file structure
//    				origin 	-	Pointer to source buffer
//    				length 	-    Length of the source buffer (data to write)
//  Return:
//    				CETYPE 	- 	Error code (expected: CE_GOOD)
//  Description:
//    				The FS_Write function will write data to a file. First, the sector
//					that corresponds to the current position in the file will be loaded 
//					(if it hasn't already been cached in the global data buffer). Data 
//					will then be written to the device from the specified buffer until 
//					the specified amount has been written.    
//					If the end of a cluster is reached, the next cluster will be
// 					loaded, unless the end-of-file flag for the specified file has been 
//					set. If it has, a new cluster will be allocated to the file. Finally, 
//					the new position and filesize will be stored in the FSFILE object.
//*********************************************************************************
CETYPE  FS_Write(FSFILE* filePtr, const void* origin, WORD length )
	{
 	//----------------------------------------------------------------
	// Validate conditions and parameters
 	//----------------------------------------------------------------
 	if (!SDFS_InitStatus)
 		return CE_NOT_INIT;		// FS is not initialized!
 	if (NULL == filePtr)
 		return CE_INVALID_ARGUMENT;		
 	//----------------------------------------------------------------
    // Check if the file attributes allow write
    if( (filePtr->dirFileEntry.DIR_Attr & ATTR_READONLY) == ATTR_READONLY )
        return CE_READONLY;
    // Check if pointer is valid	
    if (origin == NULL)
        return CE_INVALID_ARGUMENT;
    // Check if length is valid	
    if (length == 0)
        return CE_INVALID_ARGUMENT;
	//-----------------------------------------------------------------
 
	DWORD   LBA;
 	BYTE*	ptrFrom	= (BYTE*)origin;
 	WORD	ChunkSize;
	CETYPE 	RC;
    	
    // Write data to the file
    //{
	//------------------------------------------------------------	
    // Loop while writing bytes, exit loop if:
    //	* All bytes are written
    //	* Error encountered
	//------------------------------------------------------------	
 	while (length > 0)
		{
        //----------------------------------------------------
        // Make sure we have defined a place to write to
        //----------------------------------------------------
		//{
        if (filePtr->fileCrntSecPos == SDFS_VolumeInfo.sectorSize)
        	{
	        //----------------------------------------------------
	        // Current sector is filled in...
	        //----------------------------------------------------
	        // NOTE: fileCrntSec is a 0-based counter (index)
	        //----------------------------------------------------
           	if (filePtr->fileCrntSec == SDFS_VolumeInfo.SecPerClus - 1)
            	{
	 			//----------------------------------------------------
	 			// Current cluster is exhausted - move to the next one
				//----------------------------------------------------
				RC = SDFS_ClusterGetNext(filePtr);
				if ( CE_EOF == RC )
					// Oops! Reached end-of-file - try to add another cluster
					RC = SDFS_ClusterAllocateNew(filePtr);
				//----------------------------------------------------
				if ( CE_GOOD != RC )
					// Bad luck - no cluster to advance to!
	                return RC;
            	}
            else
            	{
	            // It is safe to move to the next sector in the current cluster
	            filePtr->fileCrntSec++;		    // move to the next sector
	            filePtr->fileCrntSecPos = 0;	// reset position
	            }
	        //----------------------------------------------------
         	}   	
		//}
		//-----------------------------------------------------------------   
	    LBA	= SDFS_FATClusterToLBA( filePtr->fileCrntCls)
	    			  		+ filePtr->fileCrntSec;	// add the sector number to it
		ChunkSize = length <= SDFS_VolumeInfo.sectorSize - filePtr->fileCrntSecPos ? 
							  length 
							: SDFS_VolumeInfo.sectorSize - filePtr->fileCrntSecPos;
		//-----------------------------------------------------------------   
		if	(CE_GOOD != (RC = SDFS_DataCacheWrite (LBA, ptrFrom, filePtr->fileCrntSecPos, ChunkSize )))	
			return RC;					
		//-----------------------------------------------------------------   
		length 	-= ChunkSize;
		ptrFrom	+= ChunkSize;
		//----------------------
		filePtr->fileCrntSecPos	+= ChunkSize;
		filePtr->fileSeek		+= ChunkSize;
		if (filePtr->dirFileEntry.DIR_FileSize < filePtr->fileSeek)
			filePtr->dirFileEntry.DIR_FileSize = filePtr->fileSeek;
		} 

	//-----------------------------------
    return CE_GOOD;
	} // write