示例#1
0
bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize) {
	PARTITION* partition;
	devoptab_t* devops;
	char* nameCopy;
	
	devops = _FAT_mem_allocate (sizeof(devoptab_t) + strlen(name) + 1);
	if (!devops) {
		return false;
	}
	// Use the space allocated at the end of the devoptab struct for storing the name
	nameCopy = (char*)(devops+1);

	
	// Initialize the file system
	partition = _FAT_partition_constructor (interface, cacheSize, startSector);
	if (!partition) {
		_FAT_mem_free (devops);
		return false;
	}
	
	// Add an entry for this device to the devoptab table
	memcpy (devops, &dotab_fat, sizeof(dotab_fat));
	strcpy (nameCopy, name);
	devops->name = nameCopy;
	devops->deviceData = partition;
	
	My_AddDevice (devops);
	
	return true;
}
示例#2
0
文件: cache.c 项目: Almamu/gbaemu4DS
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, unsigned int bytesPerSector) {
	CACHE* cache;
	unsigned int i;
	CACHE_ENTRY* cacheEntries;

	if (numberOfPages < 2) {
		numberOfPages = 2;
	}

	if (sectorsPerPage < 8) {
		sectorsPerPage = 8;
	}

	cache = (CACHE*) _FAT_mem_allocate (sizeof(CACHE));
	if (cache == NULL) {
		return NULL;
	}

	cache->disc = discInterface;
	cache->endOfPartition = endOfPartition;
	cache->numberOfPages = numberOfPages;
	cache->sectorsPerPage = sectorsPerPage;
	cache->bytesPerSector = bytesPerSector;


	cacheEntries = (CACHE_ENTRY*) _FAT_mem_allocate ( sizeof(CACHE_ENTRY) * numberOfPages);
	if (cacheEntries == NULL) {
		_FAT_mem_free (cache);
		return NULL;
	}

	for (i = 0; i < numberOfPages; i++) {
		cacheEntries[i].sector = CACHE_FREE;
		cacheEntries[i].count = 0;
		cacheEntries[i].last_access = 0;
		cacheEntries[i].dirty = false;
		cacheEntries[i].cache = (uint8_t*) _FAT_mem_align ( sectorsPerPage * bytesPerSector );
	}

	cache->cacheEntries = cacheEntries;

	return cache;
}
示例#3
0
bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage) {
	PARTITION* partition;
	struct devoptab_t* devops;
	//char* nameCopy;

	if(!name || strlen(name) > 8 || !interface)
		return false;

	if(!interface->startup())
		return false;

	if(!interface->isInserted())
		return false;

	//char devname[10];
	//sprintf(devname, "%s:", name);
	//if(FindDevice(devname) >= 0)
	//	return true;

	devops = (struct devoptab_t*)_FAT_mem_allocate (sizeof(struct devoptab_t) + strlen(name) + 1);
	if (!devops) {
		return false;
	}

#ifdef LIBFAT_PC
	_sole_device = devops;
#endif

	// Use the space allocated at the end of the devoptab struct for storing the name
	//nameCopy = (char*)(devops+1);

	// Initialize the file system
	partition = _FAT_partition_constructor (interface, cacheSize, SectorsPerPage, startSector);
	if (!partition) {
		_FAT_mem_free (devops);
		return false;
	}

	// Add an entry for this device to the devoptab table
	memcpy (devops, &dotab_fat, sizeof(dotab_fat));
	//strcpy (nameCopy, name);
	//devops->name = nameCopy;
	devops->deviceData = partition;

	//AddDevice (devops);

	return true;
}
示例#4
0
void fatGetVolumeLabel (const char* name, char *label) {
	devoptab_t *devops;
	PARTITION* partition;
	char *buf;
	int namelen,i;

	if(!name || !label)
		return;

	namelen = strlen(name);
	buf=(char*)_FAT_mem_allocate(sizeof(char)*namelen+2);	
	strcpy(buf,name);

	if (name[namelen-1] == '/') {
		buf[namelen-1]='\0';
		namelen--;
	}

	if (name[namelen-1] != ':') {
		buf[namelen]=':';
		buf[namelen+1]='\0';
	}

	devops = (devoptab_t*)GetDeviceOpTab(buf);

	for(i=0;buf[i]!='\0' && buf[i]!=':';i++);  
	if (!devops || strncasecmp(buf,devops->name,i)) {
		_FAT_mem_free(buf);
		return;
	}

	_FAT_mem_free(buf);

	// Perform a quick check to make sure we're dealing with a libfat controlled device
	if (devops->open_r != dotab_fat.open_r) {
		return;
	}	

	partition = (PARTITION*)devops->deviceData;

	if(!_FAT_directory_getVolumeLabel(partition, label)) { 
		strncpy(label,partition->label,11);
		label[11]='\0';
	}
	if(!strncmp(label, "NO NAME", 7)) label[0]='\0';
}
示例#5
0
PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, sec_t startSector) {
	PARTITION* partition;
	int i;
	uint8_t sectorBuffer[BYTES_PER_READ] = {0};

	// Read first sector of disc
	if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
		return NULL;
	}

	// Make sure it is a valid MBR or boot sector
	if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
		return NULL;
	}

	if (startSector != 0) {
		// We're told where to start the partition, so just accept it
	} else if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
		// Check if there is a FAT string, which indicates this is a boot sector
		startSector = 0;
	} else if (!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
		// Check for FAT32
		startSector = 0;
	} else {
		// This is an MBR
		// Find first valid partition from MBR
		// First check for an active partition
		for (i=0x1BE; (i < 0x1FE) && (sectorBuffer[i] != 0x80); i+= 0x10);
		// If it didn't find an active partition, search for any valid partition
		if (i == 0x1FE) {
			for (i=0x1BE; (i < 0x1FE) && (sectorBuffer[i+0x04] == 0x00); i+= 0x10);
		}
		
		if ( i != 0x1FE) {
			// Go to first valid partition
			startSector = u8array_to_u32(sectorBuffer, 0x8 + i);
			// Load the BPB
			if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
					return NULL;
			}
			// Make sure it is a valid BPB
			if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
				return NULL;
			}
		} else {
			// No partition found, assume this is a MBR free disk
			startSector = 0;
		}
	}

	// Now verify that this is indeed a FAT partition
	if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) && 
		memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
	{
		return NULL;
	}

	partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION));
	if (partition == NULL) {
		return NULL;
	}

	// Init the partition lock
	_FAT_lock_init(&partition->lock);
	
	// Set partition's disc interface
	partition->disc = disc;

	// Store required information about the file system
	partition->fat.sectorsPerFat = u8array_to_u16(sectorBuffer, BPB_sectorsPerFAT);
	if (partition->fat.sectorsPerFat == 0) {
		partition->fat.sectorsPerFat = u8array_to_u32( sectorBuffer, BPB_FAT32_sectorsPerFAT32); 
	}

	partition->numberOfSectors = u8array_to_u16( sectorBuffer, BPB_numSectorsSmall); 
	if (partition->numberOfSectors == 0) {
		partition->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors);	
	}

	partition->bytesPerSector = BYTES_PER_READ;	// Sector size is redefined to be 512 bytes
	partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster] * u8array_to_u16(sectorBuffer, BPB_bytesPerSector) / BYTES_PER_READ;
	partition->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster;
	partition->fat.fatStart = startSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors); 

	partition->rootDirStart = partition->fat.fatStart + (sectorBuffer[BPB_numFATs] * partition->fat.sectorsPerFat);
	partition->dataStart = partition->rootDirStart + 
		(( u8array_to_u16(sectorBuffer, BPB_rootEntries) * DIR_ENTRY_DATA_SIZE) / partition->bytesPerSector);

	partition->totalSize = ((uint64_t)partition->numberOfSectors - (partition->dataStart - startSector)) * (uint64_t)partition->bytesPerSector;

	// Store info about FAT
	partition->fat.lastCluster = (partition->numberOfSectors - (uint32_t)(partition->dataStart - startSector)) / partition->sectorsPerCluster;
	partition->fat.firstFree = CLUSTER_FIRST;

	if (partition->fat.lastCluster < CLUSTERS_PER_FAT12) {
		partition->filesysType = FS_FAT12;	// FAT12 volume
	} else if (partition->fat.lastCluster < CLUSTERS_PER_FAT16) {
		partition->filesysType = FS_FAT16;	// FAT16 volume
	} else {
		partition->filesysType = FS_FAT32;	// FAT32 volume
	}

	if (partition->filesysType != FS_FAT32) {
		partition->rootDirCluster = FAT16_ROOT_DIR_CLUSTER;
	} else {
		// Set up for the FAT32 way
		partition->rootDirCluster = u8array_to_u32(sectorBuffer, BPB_FAT32_rootClus); 
		// Check if FAT mirroring is enabled
		if (!(sectorBuffer[BPB_FAT32_extFlags] & 0x80)) {
			// Use the active FAT
			partition->fat.fatStart = partition->fat.fatStart + ( partition->fat.sectorsPerFat * (sectorBuffer[BPB_FAT32_extFlags] & 0x0F));
		}
	}

	// Create a cache to use
	partition->cache = _FAT_cache_constructor (cacheSize, partition->disc);


	// Set current directory to the root
	partition->cwdCluster = partition->rootDirCluster;
	
	// Check if this disc is writable, and set the readOnly property appropriately
	partition->readOnly = !(_FAT_disc_features(disc) & FEATURE_MEDIUM_CANWRITE);
	
	// There are currently no open files on this partition
	partition->openFileCount = 0;
	partition->firstOpenFile = NULL;

	return partition;
}
示例#6
0
PARTITION* _FAT_partition_constructor_buf (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector, uint8_t *sectorBuffer)
{
	PARTITION* partition;

	// Read first sector of disc
	if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
		return NULL;
	}

	// Make sure it is a valid MBR or boot sector
	if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA && sectorBuffer[BPB_bootSig_AA] != 0xAB)) {
		return NULL;
	}

	if (startSector != 0) {
		// We're told where to start the partition, so just accept it
	} else if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
		// Check if there is a FAT string, which indicates this is a boot sector
		startSector = 0;
	} else if (!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
		// Check for FAT32
		startSector = 0;
	} else {
		startSector = FindFirstValidPartition_buf(disc, sectorBuffer);
		if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
			return NULL;
		}
	}

	if (!isValidMBR(sectorBuffer))
	{
		return NULL;
	}

	partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION));
	if (partition == NULL) {
		return NULL;
	}

	// Init the partition lock
	_FAT_lock_init(&partition->lock);

	if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
		strncpy(partition->label, (char*)(sectorBuffer + BPB_FAT16_volumeLabel), 11);
	else
		strncpy(partition->label, (char*)(sectorBuffer + BPB_FAT32_volumeLabel), 11);
	partition->label[11] = '\0';

	// Set partition's disc interface
	partition->disc = disc;

	// Store required information about the file system
	partition->fat.sectorsPerFat = u8array_to_u16(sectorBuffer, BPB_sectorsPerFAT);
	if (partition->fat.sectorsPerFat == 0) {
		partition->fat.sectorsPerFat = u8array_to_u32( sectorBuffer, BPB_FAT32_sectorsPerFAT32);
	}

	partition->numberOfSectors = u8array_to_u16( sectorBuffer, BPB_numSectorsSmall);
	if (partition->numberOfSectors == 0) {
		partition->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors);
	}

	partition->bytesPerSector = u8array_to_u16(sectorBuffer, BPB_bytesPerSector);
	if(partition->bytesPerSector < MIN_SECTOR_SIZE || partition->bytesPerSector > MAX_SECTOR_SIZE) {
		// Unsupported sector size
		_FAT_mem_free(partition);
		return NULL;
	}

	partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster];
	partition->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster;
	partition->fat.fatStart = startSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors);

	partition->rootDirStart = partition->fat.fatStart + (sectorBuffer[BPB_numFATs] * partition->fat.sectorsPerFat);
	partition->dataStart = partition->rootDirStart +
		(( u8array_to_u16(sectorBuffer, BPB_rootEntries) * DIR_ENTRY_DATA_SIZE) / partition->bytesPerSector);

	partition->totalSize = ((uint64_t)partition->numberOfSectors - (partition->dataStart - startSector)) * (uint64_t)partition->bytesPerSector;

	//FS info sector
	partition->fsInfoSector = startSector + (u8array_to_u16(sectorBuffer, BPB_FAT32_fsInfo) ? u8array_to_u16(sectorBuffer, BPB_FAT32_fsInfo) : 1);

	// Store info about FAT
	uint32_t clusterCount = (partition->numberOfSectors - (uint32_t)(partition->dataStart - startSector)) / partition->sectorsPerCluster;
	partition->fat.lastCluster = clusterCount + CLUSTER_FIRST - 1;
	partition->fat.firstFree = CLUSTER_FIRST;
	partition->fat.numberFreeCluster = 0;
	partition->fat.numberLastAllocCluster = 0;

	if (clusterCount < CLUSTERS_PER_FAT12) {
		partition->filesysType = FS_FAT12;	// FAT12 volume
	} else if (clusterCount < CLUSTERS_PER_FAT16) {
		partition->filesysType = FS_FAT16;	// FAT16 volume
	} else {
		partition->filesysType = FS_FAT32;	// FAT32 volume
	}

	if (partition->filesysType != FS_FAT32) {
		partition->rootDirCluster = FAT16_ROOT_DIR_CLUSTER;
	} else {
		// Set up for the FAT32 way
		partition->rootDirCluster = u8array_to_u32(sectorBuffer, BPB_FAT32_rootClus);
		// Check if FAT mirroring is enabled
		if (!(sectorBuffer[BPB_FAT32_extFlags] & 0x80)) {
			// Use the active FAT
			partition->fat.fatStart = partition->fat.fatStart + ( partition->fat.sectorsPerFat * (sectorBuffer[BPB_FAT32_extFlags] & 0x0F));
		}
	}

	// Create a cache to use
	partition->cache = _FAT_cache_constructor (cacheSize, sectorsPerPage, partition->disc, startSector+partition->numberOfSectors, partition->bytesPerSector);

	// Set current directory to the root
	partition->cwdCluster = partition->rootDirCluster;

	// Check if this disc is writable, and set the readOnly property appropriately
	partition->readOnly = !(_FAT_disc_features(disc) & FEATURE_MEDIUM_CANWRITE);

	// There are currently no open files on this partition
	partition->openFileCount = 0;
	partition->firstOpenFile = NULL;

	_FAT_partition_readFSinfo(partition);

	return partition;
}