-fixed not working force FAT (should fix dolphin-emu sd card)

-lets use static buffers for partition handler instead of new 
allocating them every time
This commit is contained in:
fix94.1 2012-10-01 12:53:49 +00:00
parent 4a67f26e1b
commit 9381e97e8d
3 changed files with 65 additions and 93 deletions

View File

@ -31,8 +31,6 @@ EOF
if [ -n "$rev_old" ]; then if [ -n "$rev_old" ]; then
echo "Changed Rev $rev_old to $rev_new" >&2 echo "Changed Rev $rev_old to $rev_new" >&2
else
echo "svnrev.h created" >&2
fi fi
rev_new=`expr $rev_new + 1` rev_new=`expr $rev_new + 1`

View File

@ -42,13 +42,13 @@
//! libfat stuff //! libfat stuff
extern "C" extern "C"
{ {
sec_t FindFirstValidPartition(const DISC_INTERFACE* disc); sec_t FindFirstValidPartition(const DISC_INTERFACE* disc);
} }
#define CACHE 32 #define CACHE 32
#define SECTORS 64 #define SECTORS 64
static inline const char * PartFromType(int type) static inline const char *PartFromType(int type)
{ {
switch (type) switch (type)
{ {
@ -113,34 +113,34 @@ bool PartitionHandle::IsMounted(int pos)
bool PartitionHandle::Mount(int pos, const char * name, bool forceFAT) bool PartitionHandle::Mount(int pos, const char * name, bool forceFAT)
{ {
if(!valid(pos)) if(valid(pos))
return false; UnMount(pos);
if(!name) if(!name)
return false; return false;
UnMount(pos);
if(pos >= (int) MountNameList.size()) if(pos >= (int) MountNameList.size())
MountNameList.resize(pos+1); MountNameList.resize(pos+1);
MountNameList[pos] = name; MountNameList[pos] = name;
SetWbfsHandle(pos, NULL);
//! Some stupid partition manager think they don't need to edit the freaken MBR. //! Some stupid partition manager think they don't need to edit the freaken MBR.
//! So we need to check the first 64 sectors and see if some partition is there. //! So we need to check the first 64 sectors and see if some partition is there.
//! libfat does that by default so let's use it. //! libfat does that by default so let's use it.
//! We do that only on sd not on usb. //! We do that only on sd not on usb.
if(forceFAT && (!GetFSName(pos) || strcmp(GetFSName(pos), "Unknown") == 0)) if(forceFAT && (strlen(GetFSName(pos)) == 0 || strcmp(GetFSName(pos), "Unknown") == 0))
{ {
if (fatMount(MountNameList[pos].c_str(), interface, 0, CACHE, SECTORS)) if (fatMount(MountNameList[pos].c_str(), interface, 0, CACHE, SECTORS))
{ {
sec_t FAT_startSector = FindFirstValidPartition(interface); sec_t FAT_startSector = FindFirstValidPartition(interface);
AddPartition("FAT", FAT_startSector, 0xdeadbeaf, true, 0x0c, 0); AddPartition("FAT", FAT_startSector, 0xdeadbeaf, true, 0x0c, 0);
SetWbfsHandle(pos, NULL);
return true; return true;
} }
} }
if(!valid(pos))
return false;
SetWbfsHandle(pos, NULL);
if(strncmp(GetFSName(pos), "FAT", 3) == 0 || strcmp(GetFSName(pos), "GUID-Entry") == 0) if(strncmp(GetFSName(pos), "FAT", 3) == 0 || strcmp(GetFSName(pos), "GUID-Entry") == 0)
{ {
if (fatMount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS)) if (fatMount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS))
@ -224,42 +224,33 @@ bool PartitionHandle::IsExisting(u64 lba)
return false; return false;
} }
int PartitionHandle::FindPartitions() s8 PartitionHandle::FindPartitions()
{ {
MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD *) malloc(MAX_BYTES_PER_SECTOR); MASTER_BOOT_RECORD mbr[MAX_BYTES_PER_SECTOR] ATTRIBUTE_ALIGN(32);
if(!mbr) return -1;
// Read the first sector on the device // Read the first sector on the device
if (!interface->readSectors(0, 1, mbr)) if(!interface->readSectors(0, 1, mbr))
{
free(mbr);
return -1; return -1;
}
// If this is the devices master boot record // If this is the devices master boot record
if (mbr->signature != MBR_SIGNATURE) if(mbr->signature != MBR_SIGNATURE)
{
free(mbr);
return -1; return -1;
}
for (int i = 0; i < 4; i++) for(u8 i = 0; i < 4; i++)
{ {
PARTITION_RECORD * partition = (PARTITION_RECORD *) &mbr->partitions[i]; PARTITION_RECORD *partition = (PARTITION_RECORD *)&mbr->partitions[i];
if(partition->type == PARTITION_TYPE_GPT) if(partition->type == PARTITION_TYPE_GPT)
{ {
int ret = CheckGPT(i); s8 ret = CheckGPT(i);
if(ret == 0) // if it's a GPT we don't need to go on looking through the mbr anymore if(ret == 0) // if it's a GPT we don't need to go on looking through the mbr anymore
return ret; return ret;
} }
if(partition->type == PARTITION_TYPE_DOS33_EXTENDED || partition->type == PARTITION_TYPE_WIN95_EXTENDED) if(partition->type == PARTITION_TYPE_DOS33_EXTENDED || partition->type == PARTITION_TYPE_WIN95_EXTENDED)
{ {
CheckEBR(i, le32(partition->lba_start)); CheckEBR(i, le32(partition->lba_start));
continue; continue;
} }
if(le32(partition->block_count) > 0 && !IsExisting(le32(partition->lba_start))) if(le32(partition->block_count) > 0 && !IsExisting(le32(partition->lba_start)))
{ {
AddPartition(PartFromType(partition->type), le32(partition->lba_start), AddPartition(PartFromType(partition->type), le32(partition->lba_start),
@ -267,31 +258,24 @@ int PartitionHandle::FindPartitions()
} }
} }
free(mbr);
return 0; return 0;
} }
static u8 HeaderBuffer[MAX_BYTES_PER_SECTOR] ATTRIBUTE_ALIGN(32);
static u8 AddingBuffer[MAX_BYTES_PER_SECTOR] ATTRIBUTE_ALIGN(32);
void PartitionHandle::CheckEBR(u8 PartNum, sec_t ebr_lba) void PartitionHandle::CheckEBR(u8 PartNum, sec_t ebr_lba)
{ {
EXTENDED_BOOT_RECORD *ebr = (EXTENDED_BOOT_RECORD *) malloc(MAX_BYTES_PER_SECTOR); EXTENDED_BOOT_RECORD *ebr = (EXTENDED_BOOT_RECORD *)HeaderBuffer;
if(!ebr) return;
sec_t next_erb_lba = 0; sec_t next_erb_lba = 0;
do do
{ {
// Read and validate the extended boot record // Read and validate the extended boot record
if (!interface->readSectors(ebr_lba + next_erb_lba, 1, ebr)) if(!interface->readSectors(ebr_lba + next_erb_lba, 1, ebr))
{
free(ebr);
return; return;
} if(ebr->signature != EBR_SIGNATURE)
if (ebr->signature != EBR_SIGNATURE)
{
free(ebr);
return; return;
}
if(le32(ebr->partition.block_count) > 0 && !IsExisting(ebr_lba + next_erb_lba + le32(ebr->partition.lba_start))) if(le32(ebr->partition.block_count) > 0 && !IsExisting(ebr_lba + next_erb_lba + le32(ebr->partition.lba_start)))
{ {
@ -303,49 +287,36 @@ void PartitionHandle::CheckEBR(u8 PartNum, sec_t ebr_lba)
next_erb_lba = le32(ebr->next_ebr.lba_start); next_erb_lba = le32(ebr->next_ebr.lba_start);
} }
while(next_erb_lba > 0); while(next_erb_lba > 0);
free(ebr);
} }
static const u8 TYPE_UNUSED[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; static const u8 TYPE_UNUSED[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
static const u8 TYPE_BIOS[16] = { 0x48,0x61,0x68,0x21,0x49,0x64,0x6F,0x6E,0x74,0x4E,0x65,0x65,0x64,0x45,0x46,0x49 }; static const u8 TYPE_BIOS[16] = { 0x48,0x61,0x68,0x21,0x49,0x64,0x6F,0x6E,0x74,0x4E,0x65,0x65,0x64,0x45,0x46,0x49 };
static const u8 TYPE_LINUX_MS_BASIC_DATA[16] = { 0xA2,0xA0,0xD0,0xEB,0xE5,0xB9,0x33,0x44,0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7 }; static const u8 TYPE_LINUX_MS_BASIC_DATA[16] = { 0xA2,0xA0,0xD0,0xEB,0xE5,0xB9,0x33,0x44,0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7 };
int PartitionHandle::CheckGPT(u8 PartNum) s8 PartitionHandle::CheckGPT(u8 PartNum)
{ {
GPT_HEADER *gpt_header = (GPT_HEADER *) malloc(MAX_BYTES_PER_SECTOR); GPT_HEADER *gpt_header = (GPT_HEADER *)HeaderBuffer;
if(!gpt_header) return -1;
// Read and validate the extended boot record // Read and validate the extended boot record
if (!interface->readSectors(1, 1, gpt_header)) if(!interface->readSectors(1, 1, gpt_header))
{
free(gpt_header);
return -1; return -1;
}
if(strncmp(gpt_header->magic, "EFI PART", 8) != 0) if(strncmp(gpt_header->magic, "EFI PART", 8) != 0)
{
free(gpt_header);
return -1; return -1;
}
gpt_header->part_table_lba = le64(gpt_header->part_table_lba); gpt_header->part_table_lba = le64(gpt_header->part_table_lba);
gpt_header->part_entries = le32(gpt_header->part_entries); gpt_header->part_entries = le32(gpt_header->part_entries);
gpt_header->part_entry_size = le32(gpt_header->part_entry_size); gpt_header->part_entry_size = le32(gpt_header->part_entry_size);
gpt_header->part_entry_checksum = le32(gpt_header->part_entry_checksum); gpt_header->part_entry_checksum = le32(gpt_header->part_entry_checksum);
u8 * sector_buf = new u8[MAX_BYTES_PER_SECTOR];
u64 next_lba = gpt_header->part_table_lba; u64 next_lba = gpt_header->part_table_lba;
for(u32 i = 0; i < gpt_header->part_entries; ++i) for(u32 i = 0; i < gpt_header->part_entries; ++i)
{ {
if (!interface->readSectors(next_lba, 1, sector_buf)) if(!interface->readSectors(next_lba, 1, AddingBuffer))
break; break;
for(u32 n = 0; n < BYTES_PER_SECTOR/gpt_header->part_entry_size; ++n, ++i) for(u32 n = 0; n < BYTES_PER_SECTOR/gpt_header->part_entry_size; ++n, ++i)
{ {
GUID_PART_ENTRY * part_entry = (GUID_PART_ENTRY *) (sector_buf+gpt_header->part_entry_size*n); GUID_PART_ENTRY * part_entry = (GUID_PART_ENTRY *) (AddingBuffer + gpt_header->part_entry_size*n);
if(memcmp(part_entry->part_type_guid, TYPE_UNUSED, 16) == 0) if(memcmp(part_entry->part_type_guid, TYPE_UNUSED, 16) == 0)
continue; continue;
@ -357,61 +328,64 @@ int PartitionHandle::CheckGPT(u8 PartNum)
AddPartition("GUID-Entry", le64(part_entry->part_first_lba), le64(part_entry->part_last_lba), bootable, PARTITION_TYPE_GPT, PartNum); AddPartition("GUID-Entry", le64(part_entry->part_first_lba), le64(part_entry->part_last_lba), bootable, PARTITION_TYPE_GPT, PartNum);
} }
next_lba++; next_lba++;
} }
delete [] sector_buf;
free(gpt_header);
return 0; return 0;
} }
void PartitionHandle::AddPartition(const char * name, u64 lba_start, u64 sec_count, bool bootable, u8 part_type, u8 part_num) void PartitionHandle::AddPartition(const char *name, u64 lba_start, u64 sec_count, bool bootable, u8 part_type, u8 part_num)
{ {
char *buffer = (char *) malloc(MAX_BYTES_PER_SECTOR); if(!interface->readSectors(lba_start, 1, AddingBuffer))
if (!interface->readSectors(lba_start, 1, buffer))
{
free(buffer);
return; return;
}
wbfs_head_t *head = (wbfs_head_t *) buffer; wbfs_head_t *head = (wbfs_head_t *)AddingBuffer;
if (head->magic == wbfs_htonl(WBFS_MAGIC)) if(head->magic == wbfs_htonl(WBFS_MAGIC))
{ {
name = "WBFS"; name = "WBFS";
part_type = 0xBF; //Override partition type on WBFS part_type = 0xBF; //Override partition type on WBFS
//! correct sector size in physical sectors (512 bytes per sector) //! correct sector size in physical sectors (512 bytes per sector)
sec_count = (u64) head->n_hd_sec * (u64) (1 << head->hd_sec_sz_s) / (u64) BYTES_PER_SECTOR; sec_count = (u64) head->n_hd_sec * (u64) (1 << head->hd_sec_sz_s) / (u64) BYTES_PER_SECTOR;
} }
else if(*((u16 *) (buffer + 0x1FE)) == 0x55AA) else if(*((u16 *) (AddingBuffer + 0x1FE)) == 0x55AA)
{ {
//! Partition typ can be missleading the correct partition format. Stupid lazy ass Partition Editors. //! Partition typ can be missleading the correct partition format. Stupid lazy ass Partition Editors.
if((memcmp(buffer + 0x36, "FAT", 3) == 0 || memcmp(buffer + 0x52, "FAT", 3) == 0) && if((memcmp(AddingBuffer + 0x36, "FAT", 3) == 0 || memcmp(AddingBuffer + 0x52, "FAT", 3) == 0) &&
strncmp(PartFromType(part_type), "FAT", 3) != 0) strncmp(PartFromType(part_type), "FAT", 3) != 0)
{ {
name = "FAT32"; name = "FAT32";
part_type = 0x0c; part_type = 0x0c;
} }
if (memcmp(buffer + 0x03, "NTFS", 4) == 0) if (memcmp(AddingBuffer + 0x03, "NTFS", 4) == 0)
{ {
name = "NTFS"; name = "NTFS";
part_type = 0x07; part_type = 0x07;
} }
} }
PartitionFS PartitionEntrie; PartitionFS PartitionEntry;
PartitionEntrie.FSName = name; PartitionEntry.FSName = name;
PartitionEntrie.LBA_Start = lba_start; PartitionEntry.LBA_Start = lba_start;
PartitionEntrie.SecCount = sec_count; PartitionEntry.SecCount = sec_count;
PartitionEntrie.Bootable = bootable; PartitionEntry.Bootable = bootable;
PartitionEntrie.PartitionType = part_type; PartitionEntry.PartitionType = part_type;
PartitionEntrie.PartitionNum = part_num; PartitionEntry.PartitionNum = part_num;
PartitionList.push_back(PartitionEntry);
PartitionList.push_back(PartitionEntrie); }
free(buffer); wbfs_t *PartitionHandle::GetWbfsHandle(int pos)
{
if(valid(pos))
return PartitionList[pos].wbfshandle;
return NULL;
}
bool PartitionHandle::SetWbfsHandle(int pos, wbfs_t *wbfshandle)
{
if(valid(pos))
{
PartitionList[pos].wbfshandle = wbfshandle;
return true;
}
return false;
} }

View File

@ -154,16 +154,16 @@ public:
//! Get the disc interface of this handle //! Get the disc interface of this handle
const DISC_INTERFACE * GetDiscInterface() { return interface; }; const DISC_INTERFACE * GetDiscInterface() { return interface; };
//! Get the wbfs mount handle //! Get the wbfs mount handle
wbfs_t *GetWbfsHandle(int pos) { if(valid(pos)) return PartitionList[pos].wbfshandle; else return 0; }; wbfs_t *GetWbfsHandle(int pos);
//! Set the wbfs mount handle //! Set the wbfs mount handle
bool SetWbfsHandle(int pos, wbfs_t * wbfshandle) { if(valid(pos)) {PartitionList[pos].wbfshandle = wbfshandle; return true;} else return false; }; bool SetWbfsHandle(int pos, wbfs_t *wbfshandle);
protected: protected:
bool valid(int pos) { return (pos >= 0 && pos < (int) PartitionList.size()); } bool valid(int pos) { return (pos >= 0 && pos < (int)PartitionList.size()); };
void AddPartition(const char * name, u64 lba_start, u64 sec_count, bool bootable, u8 part_type, u8 part_num); void AddPartition(const char *name, u64 lba_start, u64 sec_count, bool bootable, u8 part_type, u8 part_num);
bool IsExisting(u64 lba); bool IsExisting(u64 lba);
int FindPartitions(); s8 FindPartitions();
void CheckEBR(u8 PartNum, sec_t ebr_lba); void CheckEBR(u8 PartNum, sec_t ebr_lba);
int CheckGPT(u8 PartNum); s8 CheckGPT(u8 PartNum);
const DISC_INTERFACE *interface; const DISC_INTERFACE *interface;
vector<PartitionFS> PartitionList; vector<PartitionFS> PartitionList;