FF_ERROR FF_IncreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) { FF_ERROR Error; //FF_PendSemaphore(pIoman->pSemaphore); //{ if(!pIoman->pPartition->FreeClusterCount) { pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error); if(Error) { return Error; } } else { pIoman->pPartition->FreeClusterCount += Count; } //} //FF_ReleaseSemaphore(pIoman->pSemaphore); return FF_ERR_NONE; }
FF_ERROR FF_DecreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) { FF_ERROR Error; //FF_lockFAT(pIoman); //{ if(!pIoman->pPartition->FreeClusterCount) { pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error); if(Error) { return Error; } } else { pIoman->pPartition->FreeClusterCount -= Count; } //} //FF_unlockFAT(pIoman); return FF_ERR_NONE; }
FF_ERROR FF_IncreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) { FF_ERROR Error; #ifdef FF_WRITE_FREE_COUNT FF_BUFFER *pBuffer; #endif if(!pIoman->pPartition->FreeClusterCount) { pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error); if(FF_isERR(Error)) { return Error; } } else { pIoman->pPartition->FreeClusterCount += Count; } #ifdef FF_WRITE_FREE_COUNT // FAT32 update the FSINFO sector. if(pIoman->pPartition->Type == FF_T_FAT32) { // Find the FSINFO sector. pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FSInfoLBA, FF_MODE_WRITE); { if(!pBuffer) { return FF_ERR_DEVICE_DRIVER_FAILED | FF_INCREASEFREECLUSTERS; } if(FF_getLong(pBuffer->pBuffer, 0) == 0x41615252 && FF_getLong(pBuffer->pBuffer, 484) == 0x61417272) { // FSINFO sector magic nums we're verified. Safe to write. FF_putLong(pBuffer->pBuffer, 488, pIoman->pPartition->FreeClusterCount); FF_putLong(pBuffer->pBuffer, 492, pIoman->pPartition->LastFreeCluster); } } Error = FF_ReleaseBuffer(pIoman, pBuffer); if(FF_isERR(Error)) { return Error; } } #endif return FF_ERR_NONE; }
/** * @public * @brief Mounts the Specified partition, the volume specified by the FF_IOMAN object provided. * * The device drivers must adhere to the specification provided by * FF_WRITE_BLOCKS and FF_READ_BLOCKS. * * @param pIoman FF_IOMAN object. * @param PartitionNumber The primary partition number to be mounted. (0 - 3). * * @return 0 on success. * @return FF_ERR_NULL_POINTER if a pIoman object wasn't provided. * @return FF_ERR_IOMAN_INVALID_PARTITION_NUM if the partition number is out of range. * @return FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION if no partition was found. * @return FF_ERR_IOMAN_INVALID_FORMAT if the master boot record or partition boot block didn't provide sensible data. * @return FF_ERR_IOMAN_NOT_FAT_FORMATTED if the volume or partition couldn't be determined to be FAT. (@see ff_config.h) * **/ FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) { FF_PARTITION *pPart; FF_BUFFER *pBuffer = 0; FF_ERROR Error; FF_T_UINT8 ucPartitionType; int partCount; if(!pIoman) { return FF_ERR_NULL_POINTER; } /*if(PartitionNumber > 3) { return FF_ERR_IOMAN_INVALID_PARTITION_NUM; }*/ pPart = pIoman->pPartition; memset (pIoman->pBuffers, '\0', sizeof(FF_BUFFER) * pIoman->CacheSize); memset (pIoman->pCacheMem, '\0', pIoman->BlkSize * pIoman->CacheSize); FF_IOMAN_InitBufferDescriptors(pIoman); pIoman->FirstFile = 0; pBuffer = FF_GetBuffer(pIoman, 0, FF_MODE_READ); if(!pBuffer) { return FF_ERR_DEVICE_DRIVER_FAILED; } partCount = FF_PartitionCount (pBuffer->pBuffer); pPart->BlkSize = FF_getShort(pBuffer->pBuffer, FF_FAT_BYTES_PER_SECTOR); if (partCount == 0) { //(pPart->BlkSize % 512) == 0 && pPart->BlkSize > 0) { // Volume is not partitioned (MBR Found) pPart->BeginLBA = 0; } else { ucPartitionType = FF_getChar(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID); // Ensure its not an EFI partition! if(ucPartitionType != 0xEE) { if(PartitionNumber > 3) { FF_ReleaseBuffer(pIoman, pBuffer); return FF_ERR_IOMAN_INVALID_PARTITION_NUM; } // Primary Partitions to deal with! pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_LBA + (16 * PartitionNumber)); } FF_ReleaseBuffer(pIoman, pBuffer); if(ucPartitionType == 0xEE) { pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_LBA); Error = FF_GetEfiPartitionEntry(pIoman, PartitionNumber); if(Error) { return Error; } } if(!pPart->BeginLBA) { return FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION; } // Now we get the Partition sector. pBuffer = FF_GetBuffer(pIoman, pPart->BeginLBA, FF_MODE_READ); if(!pBuffer) { return FF_ERR_DEVICE_DRIVER_FAILED; } pPart->BlkSize = FF_getShort(pBuffer->pBuffer, FF_FAT_BYTES_PER_SECTOR); if((pPart->BlkSize % 512) != 0 || pPart->BlkSize == 0) { FF_ReleaseBuffer(pIoman, pBuffer); return FF_ERR_IOMAN_INVALID_FORMAT; } } // Assume FAT16, then we'll adjust if its FAT32 pPart->ReservedSectors = FF_getShort(pBuffer->pBuffer, FF_FAT_RESERVED_SECTORS); pPart->FatBeginLBA = pPart->BeginLBA + pPart->ReservedSectors; pPart->NumFATS = (FF_T_UINT8) FF_getShort(pBuffer->pBuffer, FF_FAT_NUMBER_OF_FATS); pPart->SectorsPerFAT = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FF_FAT_16_SECTORS_PER_FAT); pPart->SectorsPerCluster = FF_getChar(pBuffer->pBuffer, FF_FAT_SECTORS_PER_CLUS); pPart->BlkFactor = (FF_T_UINT8) (pPart->BlkSize / pIoman->BlkSize); // Set the BlockFactor (How many real-blocks in a fake block!). if(pPart->SectorsPerFAT == 0) { // FAT32 pPart->SectorsPerFAT = FF_getLong(pBuffer->pBuffer, FF_FAT_32_SECTORS_PER_FAT); pPart->RootDirCluster = FF_getLong(pBuffer->pBuffer, FF_FAT_ROOT_DIR_CLUSTER); pPart->ClusterBeginLBA = pPart->BeginLBA + pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT); pPart->TotalSectors = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FF_FAT_16_TOTAL_SECTORS); if(pPart->TotalSectors == 0) { pPart->TotalSectors = FF_getLong(pBuffer->pBuffer, FF_FAT_32_TOTAL_SECTORS); } memcpy (pPart->VolLabel, pBuffer->pBuffer + FF_FAT_32_VOL_LABEL, sizeof pPart->VolLabel); } else { // FAT16 pPart->ClusterBeginLBA = pPart->BeginLBA + pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT); pPart->TotalSectors = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FF_FAT_16_TOTAL_SECTORS); pPart->RootDirCluster = 1; // 1st Cluster is RootDir! if(pPart->TotalSectors == 0) { pPart->TotalSectors = FF_getLong(pBuffer->pBuffer, FF_FAT_32_TOTAL_SECTORS); } memcpy (pPart->VolLabel, pBuffer->pBuffer + FF_FAT_16_VOL_LABEL, sizeof pPart->VolLabel); } FF_ReleaseBuffer(pIoman, pBuffer); // Release the buffer finally! if(!pPart->BlkSize) { return FF_ERR_IOMAN_INVALID_FORMAT; } pPart->RootDirSectors = ((FF_getShort(pBuffer->pBuffer, FF_FAT_ROOT_ENTRY_COUNT) * 32) + pPart->BlkSize - 1) / pPart->BlkSize; pPart->FirstDataSector = pPart->ClusterBeginLBA + pPart->RootDirSectors; pPart->DataSectors = pPart->TotalSectors - (pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT) + pPart->RootDirSectors); if(!pPart->SectorsPerCluster) { return FF_ERR_IOMAN_INVALID_FORMAT; } pPart->NumClusters = pPart->DataSectors / pPart->SectorsPerCluster; Error = FF_DetermineFatType(pIoman); if(Error) { return Error; } #ifdef FF_MOUNT_FIND_FREE pPart->LastFreeCluster = FF_FindFreeCluster(pIoman); pPart->FreeClusterCount = FF_CountFreeClusters(pIoman); #else pPart->LastFreeCluster = 0; pPart->FreeClusterCount = 0; #endif return FF_ERR_NONE; }