/*! Return a string containing the default CD device if none is specified. */ char * cdio_get_default_device_freebsd() { #ifndef HAVE_FREEBSD_CDROM return NULL; #else char drive[40]; bool exists=true; char c; /* Scan the system for CD-ROM drives. */ #ifdef USE_ETC_FSTAB struct fstab *fs; setfsent(); /* Check what's in /etc/fstab... */ while ( (fs = getfsent()) ) { if (strncmp(fs->fs_spec, "/dev/sr", 7)) return strdup(fs->fs_spec); } #endif /* Scan the system for CD-ROM drives. Not always 100% reliable, so use the USE_MNTENT code above first. */ /* Scan SCSI and CAM devices */ for ( c='0'; exists && c <='9'; c++ ) { sprintf(drive, "/dev/cd%c%s", c, DEVICE_POSTFIX); exists = cdio_is_cdrom(drive, NULL); if ( exists ) { return strdup(drive); } } /* Scan are ATAPI devices */ exists = true; for ( c='0'; exists && c <='9'; c++ ) { sprintf(drive, "/dev/acd%c%s", c, DEVICE_POSTFIX); exists = cdio_is_cdrom(drive, NULL); if ( exists ) { return strdup(drive); } } return NULL; #endif /*HAVE_FREEBSD_CDROM*/ }
/*! Return a string containing the default CD device. */ char * cdio_get_default_device_linux(void) { #ifndef HAVE_LINUX_CDROM return NULL; #else unsigned int i; char drive[40]; bool exists; char *ret_drive; /* Scan the system for CD-ROM drives. */ for ( i=0; strlen(checklist1[i]) > 0; ++i ) { sprintf(drive, "/dev/%s", checklist1[i]); if ( (exists=cdio_is_cdrom(drive, NULL)) > 0 ) { return strdup(drive); } } /* Now check the currently mounted CD drives */ if (NULL != (ret_drive = cdio_check_mounts("/etc/mtab"))) return ret_drive; /* Finally check possible mountable drives in /etc/fstab */ if (NULL != (ret_drive = cdio_check_mounts("/etc/fstab"))) return ret_drive; /* Scan the system for CD-ROM drives. Not always 100% reliable, so use the USE_MNTENT code above first. */ for ( i=0; strlen(checklist2[i]) > 0; ++i ) { unsigned int j; char *insert; exists = true; for ( j=checklist2[i][1]; exists; ++j ) { sprintf(drive, "/dev/%s", &checklist2[i][3]); insert = strchr(drive, '?'); if ( insert != NULL ) { *insert = j; } if ( (exists=cdio_is_cdrom(drive, NULL)) > 0 ) { return(strdup(drive)); } } } return NULL; #endif /*HAVE_LINUX_CDROM*/ }
IBlobReader* CreateBlobReader(const std::string& filename) { if (cdio_is_cdrom(filename)) return DriveReader::Create(filename); if (!File::Exists(filename)) return nullptr; if (IsWbfsBlob(filename)) return WbfsFileReader::Create(filename); if (IsCompressedBlob(filename)) return CompressedBlobReader::Create(filename); if (IsCISOBlob(filename)) return CISOFileReader::Create(filename); // Still here? Assume plain file - since we know it exists due to the File::Exists check above. return PlainFileReader::Create(filename); }
bool SCoreStartupParameter::AutoSetup(EBootBS2 _BootBS2) { std::string Region(EUR_DIR); switch (_BootBS2) { case BOOT_DEFAULT: { bool bootDrive = cdio_is_cdrom(m_strFilename); // Check if the file exist, we may have gotten it from a --elf command line // that gave an incorrect file name if (!bootDrive && !File::Exists(m_strFilename)) { PanicAlertT("The specified file \"%s\" does not exist", m_strFilename.c_str()); return false; } std::string Extension; SplitPath(m_strFilename, nullptr, nullptr, &Extension); if (!strcasecmp(Extension.c_str(), ".gcm") || !strcasecmp(Extension.c_str(), ".iso") || !strcasecmp(Extension.c_str(), ".wbfs") || !strcasecmp(Extension.c_str(), ".ciso") || !strcasecmp(Extension.c_str(), ".gcz") || bootDrive) { m_BootType = BOOT_ISO; std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename)); if (pVolume == nullptr) { if (bootDrive) PanicAlertT("Could not read \"%s\". " "There is no disc in the drive, or it is not a GC/Wii backup. " "Please note that original GameCube and Wii discs cannot be read " "by most PC DVD drives.", m_strFilename.c_str()); else PanicAlertT("\"%s\" is an invalid GCM/ISO file, or is not a GC/Wii ISO.", m_strFilename.c_str()); return false; } m_strName = pVolume->GetName(); m_strUniqueID = pVolume->GetUniqueID(); m_strRevisionSpecificUniqueID = pVolume->GetRevisionSpecificUniqueID(); // Check if we have a Wii disc bWii = DiscIO::IsVolumeWiiDisc(pVolume.get()); switch (pVolume->GetCountry()) { case DiscIO::IVolume::COUNTRY_USA: bNTSC = true; Region = USA_DIR; break; case DiscIO::IVolume::COUNTRY_TAIWAN: case DiscIO::IVolume::COUNTRY_KOREA: // TODO: Should these have their own Region Dir? case DiscIO::IVolume::COUNTRY_JAPAN: bNTSC = true; Region = JAP_DIR; break; case DiscIO::IVolume::COUNTRY_EUROPE: case DiscIO::IVolume::COUNTRY_FRANCE: case DiscIO::IVolume::COUNTRY_ITALY: case DiscIO::IVolume::COUNTRY_RUSSIA: bNTSC = false; Region = EUR_DIR; break; default: if (PanicYesNoT("Your GCM/ISO file seems to be invalid (invalid country)." "\nContinue with PAL region?")) { bNTSC = false; Region = EUR_DIR; break; } else { return false; } } } else if (!strcasecmp(Extension.c_str(), ".elf")) { bWii = CBoot::IsElfWii(m_strFilename); Region = USA_DIR; m_BootType = BOOT_ELF; bNTSC = true; } else if (!strcasecmp(Extension.c_str(), ".dol")) { CDolLoader dolfile(m_strFilename); bWii = dolfile.IsWii(); Region = USA_DIR; m_BootType = BOOT_DOL; bNTSC = true; } else if (!strcasecmp(Extension.c_str(), ".dff")) { bWii = true; Region = USA_DIR; bNTSC = true; m_BootType = BOOT_DFF; std::unique_ptr<FifoDataFile> ddfFile(FifoDataFile::Load(m_strFilename, true)); if (ddfFile) { bWii = ddfFile->GetIsWii(); } } else if (DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename).IsValid()) { std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename)); const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename); if (ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex()) == nullptr) { //WAD is valid yet cannot be booted. Install instead. u64 installed = DiscIO::CNANDContentManager::Access().Install_WiiWAD(m_strFilename); if (installed) SuccessAlertT("The WAD has been installed successfully"); return false; //do not boot } switch (ContentLoader.GetCountry()) { case DiscIO::IVolume::COUNTRY_USA: bNTSC = true; Region = USA_DIR; break; case DiscIO::IVolume::COUNTRY_TAIWAN: case DiscIO::IVolume::COUNTRY_KOREA: // TODO: Should these have their own Region Dir? case DiscIO::IVolume::COUNTRY_JAPAN: bNTSC = true; Region = JAP_DIR; break; case DiscIO::IVolume::COUNTRY_EUROPE: case DiscIO::IVolume::COUNTRY_FRANCE: case DiscIO::IVolume::COUNTRY_ITALY: case DiscIO::IVolume::COUNTRY_RUSSIA: bNTSC = false; Region = EUR_DIR; break; default: bNTSC = false; Region = EUR_DIR; break; } bWii = true; m_BootType = BOOT_WII_NAND; if (pVolume) { m_strName = pVolume->GetName(); m_strUniqueID = pVolume->GetUniqueID(); } else { // null pVolume means that we are loading from nand folder (Most Likely Wii Menu) // if this is the second boot we would be using the Name and id of the last title m_strName.clear(); m_strUniqueID.clear(); } // Use the TitleIDhex for name and/or unique ID if launching from nand folder // or if it is not ascii characters (specifically sysmenu could potentially apply to other things) std::string titleidstr = StringFromFormat("%016" PRIx64, ContentLoader.GetTitleID()); if (m_strName.empty()) { m_strName = titleidstr; } if (m_strUniqueID.empty()) { m_strUniqueID = titleidstr; } } else { PanicAlertT("Could not recognize ISO file %s", m_strFilename.c_str()); return false; } } break; case BOOT_BS2_USA: Region = USA_DIR; m_strFilename.clear(); bNTSC = true; break; case BOOT_BS2_JAP: Region = JAP_DIR; m_strFilename.clear(); bNTSC = true; break; case BOOT_BS2_EUR: Region = EUR_DIR; m_strFilename.clear(); bNTSC = false; break; } // Setup paths CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardA, Region, true); CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, Region, false); m_strSRAM = File::GetUserPath(F_GCSRAM_IDX); if (!bWii) { if (!bHLE_BS2) { m_strBootROM = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + Region + DIR_SEP GC_IPL; if (!File::Exists(m_strBootROM)) m_strBootROM = File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + Region + DIR_SEP GC_IPL; if (!File::Exists(m_strBootROM)) { WARN_LOG(BOOT, "Bootrom file %s not found - using HLE.", m_strBootROM.c_str()); bHLE_BS2 = true; } } } else if (bWii && !bHLE_BS2) { WARN_LOG(BOOT, "GC bootrom file will not be loaded for Wii mode."); bHLE_BS2 = true; } return true; }
bool SConfig::AutoSetup(EBootBS2 _BootBS2) { std::string set_region_dir(EUR_DIR); switch (_BootBS2) { case BOOT_DEFAULT: { bool bootDrive = cdio_is_cdrom(m_strFilename); // Check if the file exist, we may have gotten it from a --elf command line // that gave an incorrect file name if (!bootDrive && !File::Exists(m_strFilename)) { PanicAlertT("The specified file \"%s\" does not exist", m_strFilename.c_str()); return false; } std::string Extension; SplitPath(m_strFilename, nullptr, nullptr, &Extension); if (!strcasecmp(Extension.c_str(), ".gcm") || !strcasecmp(Extension.c_str(), ".iso") || !strcasecmp(Extension.c_str(), ".wbfs") || !strcasecmp(Extension.c_str(), ".ciso") || !strcasecmp(Extension.c_str(), ".gcz") || bootDrive) { m_BootType = BOOT_ISO; std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename)); if (pVolume == nullptr) { if (bootDrive) PanicAlertT("Could not read \"%s\". " "There is no disc in the drive, or it is not a GC/Wii backup. " "Please note that original GameCube and Wii discs cannot be read " "by most PC DVD drives.", m_strFilename.c_str()); else PanicAlertT("\"%s\" is an invalid GCM/ISO file, or is not a GC/Wii ISO.", m_strFilename.c_str()); return false; } m_strName = pVolume->GetInternalName(); m_strUniqueID = pVolume->GetUniqueID(); m_revision = pVolume->GetRevision(); // Check if we have a Wii disc bWii = pVolume->GetVolumeType() == DiscIO::IVolume::WII_DISC; const char* retrieved_region_dir = GetRegionOfCountry(pVolume->GetCountry()); if (!retrieved_region_dir) { if (!PanicYesNoT("Your GCM/ISO file seems to be invalid (invalid country)." "\nContinue with PAL region?")) return false; retrieved_region_dir = EUR_DIR; } set_region_dir = retrieved_region_dir; bNTSC = set_region_dir == USA_DIR || set_region_dir == JAP_DIR; } else if (!strcasecmp(Extension.c_str(), ".elf")) { bWii = CBoot::IsElfWii(m_strFilename); // TODO: Right now GC homebrew boots in NTSC and Wii homebrew in PAL. // This is intentional so that Wii homebrew can boot in both 50Hz and 60Hz, without forcing all GC homebrew to 50Hz. // In the future, it probably makes sense to add a Region setting for homebrew somewhere in the emulator config. bNTSC = bWii ? false : true; set_region_dir = bNTSC ? USA_DIR : EUR_DIR; m_BootType = BOOT_ELF; } else if (!strcasecmp(Extension.c_str(), ".dol")) { CDolLoader dolfile(m_strFilename); bWii = dolfile.IsWii(); // TODO: See the ELF code above. bNTSC = bWii ? false : true; set_region_dir = bNTSC ? USA_DIR : EUR_DIR; m_BootType = BOOT_DOL; } else if (!strcasecmp(Extension.c_str(), ".dff")) { bWii = true; set_region_dir = USA_DIR; bNTSC = true; m_BootType = BOOT_DFF; std::unique_ptr<FifoDataFile> ddfFile(FifoDataFile::Load(m_strFilename, true)); if (ddfFile) { bWii = ddfFile->GetIsWii(); } } else if (DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename).IsValid()) { std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename)); const DiscIO::CNANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename); if (ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex()) == nullptr) { //WAD is valid yet cannot be booted. Install instead. u64 installed = DiscIO::CNANDContentManager::Access().Install_WiiWAD(m_strFilename); if (installed) SuccessAlertT("The WAD has been installed successfully"); return false; //do not boot } const char* retrieved_region_dir = GetRegionOfCountry(ContentLoader.GetCountry()); set_region_dir = retrieved_region_dir ? retrieved_region_dir : EUR_DIR; bNTSC = set_region_dir == USA_DIR || set_region_dir == JAP_DIR; bWii = true; m_BootType = BOOT_WII_NAND; if (pVolume) { m_strName = pVolume->GetInternalName(); m_strUniqueID = pVolume->GetUniqueID(); } else { // null pVolume means that we are loading from nand folder (Most Likely Wii Menu) // if this is the second boot we would be using the Name and id of the last title m_strName.clear(); m_strUniqueID.clear(); } // Use the TitleIDhex for name and/or unique ID if launching from nand folder // or if it is not ascii characters (specifically sysmenu could potentially apply to other things) std::string titleidstr = StringFromFormat("%016" PRIx64, ContentLoader.GetTitleID()); if (m_strName.empty()) { m_strName = titleidstr; } if (m_strUniqueID.empty()) { m_strUniqueID = titleidstr; } } else { PanicAlertT("Could not recognize ISO file %s", m_strFilename.c_str()); return false; } } break; case BOOT_BS2_USA: set_region_dir = USA_DIR; m_strFilename.clear(); bNTSC = true; break; case BOOT_BS2_JAP: set_region_dir = JAP_DIR; m_strFilename.clear(); bNTSC = true; break; case BOOT_BS2_EUR: set_region_dir = EUR_DIR; m_strFilename.clear(); bNTSC = false; break; } // Setup paths CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardA, set_region_dir, true); CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, set_region_dir, false); m_strSRAM = File::GetUserPath(F_GCSRAM_IDX); if (!bWii) { if (!bHLE_BS2) { m_strBootROM = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + set_region_dir + DIR_SEP GC_IPL; if (!File::Exists(m_strBootROM)) m_strBootROM = File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + set_region_dir + DIR_SEP GC_IPL; if (!File::Exists(m_strBootROM)) { WARN_LOG(BOOT, "Bootrom file %s not found - using HLE.", m_strBootROM.c_str()); bHLE_BS2 = true; } } } else if (bWii && !bHLE_BS2) { WARN_LOG(BOOT, "GC bootrom file will not be loaded for Wii mode."); bHLE_BS2 = true; } return true; }
static char * cdio_check_mounts(const char *mtab) { FILE *mntfp; struct mntent *mntent; mntfp = setmntent(mtab, "r"); if ( mntfp != NULL ) { char *tmp; char *mnt_type; char *mnt_dev; while ( (mntent=getmntent(mntfp)) != NULL ) { mnt_type = malloc(strlen(mntent->mnt_type) + 1); if (mnt_type == NULL) continue; /* maybe you'll get lucky next time. */ mnt_dev = malloc(strlen(mntent->mnt_fsname) + 1); if (mnt_dev == NULL) { free(mnt_type); continue; } strcpy(mnt_type, mntent->mnt_type); strcpy(mnt_dev, mntent->mnt_fsname); /* Handle "supermount" filesystem mounts */ if ( strcmp(mnt_type, "supermount") == 0 ) { tmp = strstr(mntent->mnt_opts, "fs="); if ( tmp ) { free(mnt_type); mnt_type = strdup(tmp + strlen("fs=")); if ( mnt_type ) { tmp = strchr(mnt_type, ','); if ( tmp ) { *tmp = '\0'; } } } tmp = strstr(mntent->mnt_opts, "dev="); if ( tmp ) { free(mnt_dev); mnt_dev = strdup(tmp + strlen("dev=")); if ( mnt_dev ) { tmp = strchr(mnt_dev, ','); if ( tmp ) { *tmp = '\0'; } } } } if ( strcmp(mnt_type, "iso9660") == 0 ) { if (cdio_is_cdrom(mnt_dev, mnt_type) > 0) { free(mnt_dev); free(mnt_type); endmntent(mntfp); return strdup(mnt_dev); } } free(mnt_dev); free(mnt_type); } endmntent(mntfp); } return NULL; }
std::unique_ptr<BootParameters> BootParameters::GenerateFromFile(const std::string& path, const std::optional<std::string>& savestate_path) { const bool is_drive = cdio_is_cdrom(path); // Check if the file exist, we may have gotten it from a --elf command line // that gave an incorrect file name if (!is_drive && !File::Exists(path)) { PanicAlertT("The specified file \"%s\" does not exist", path.c_str()); return {}; } std::string extension; SplitPath(path, nullptr, nullptr, &extension); std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); static const std::unordered_set<std::string> disc_image_extensions = { { ".gcm", ".iso", ".tgc", ".wbfs", ".ciso", ".gcz", ".dol", ".elf" } }; if (disc_image_extensions.find(extension) != disc_image_extensions.end() || is_drive) { std::unique_ptr<DiscIO::Volume> volume = DiscIO::CreateVolumeFromFilename(path); if (volume) return std::make_unique<BootParameters>(Disc{ path, std::move(volume) }); if (extension == ".elf") { return std::make_unique<BootParameters>(Executable{ path, std::make_unique<ElfReader>(path) }, savestate_path); } if (extension == ".dol") { return std::make_unique<BootParameters>(Executable{ path, std::make_unique<DolReader>(path) }, savestate_path); } if (is_drive) { PanicAlertT("Could not read \"%s\". " "There is no disc in the drive or it is not a GameCube/Wii backup. " "Please note that Dolphin cannot play games directly from the original " "GameCube and Wii discs.", path.c_str()); } else { PanicAlertT("\"%s\" is an invalid GCM/ISO file, or is not a GC/Wii ISO.", path.c_str()); } return {}; } if (extension == ".dff") return std::make_unique<BootParameters>(DFF{ path }, savestate_path); if (extension == ".wad") return std::make_unique<BootParameters>(DiscIO::WiiWAD{ path }, savestate_path); PanicAlertT("Could not recognize file %s", path.c_str()); return {}; }