2014-04-08 19:15:46 -04:00
|
|
|
// Copyright 2014 Citra Emulator Project
|
|
|
|
// Licensed under GPLv2
|
|
|
|
// Refer to the license.txt file included.
|
2013-09-19 23:21:22 -04:00
|
|
|
|
2014-06-16 18:03:13 -04:00
|
|
|
#include "core/loader/loader.h"
|
2014-06-16 23:05:10 -04:00
|
|
|
#include "core/loader/elf.h"
|
2014-06-16 22:57:09 -04:00
|
|
|
#include "core/loader/ncch.h"
|
2014-04-21 23:09:10 -04:00
|
|
|
|
2013-09-19 23:21:22 -04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
namespace Loader {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Identifies the type of a bootable file
|
|
|
|
* @param filename String filename of bootable file
|
|
|
|
* @todo (ShizZy) this function sucks... make it actually check file contents etc.
|
|
|
|
* @return FileType of file
|
|
|
|
*/
|
|
|
|
FileType IdentifyFile(std::string &filename) {
|
2014-03-31 22:23:55 -04:00
|
|
|
if (filename.size() == 0) {
|
|
|
|
ERROR_LOG(LOADER, "invalid filename %s", filename.c_str());
|
|
|
|
return FILETYPE_ERROR;
|
|
|
|
}
|
|
|
|
std::string extension = filename.size() >= 5 ? filename.substr(filename.size() - 4) : "";
|
|
|
|
|
2014-06-16 23:18:10 -04:00
|
|
|
if (!strcasecmp(extension.c_str(), ".elf")) {
|
2014-03-31 22:23:55 -04:00
|
|
|
return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p
|
|
|
|
}
|
2014-05-15 18:54:57 -04:00
|
|
|
else if (!strcasecmp(extension.c_str(), ".axf")) {
|
|
|
|
return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p
|
|
|
|
}
|
2014-06-16 17:53:25 -04:00
|
|
|
else if (!strcasecmp(extension.c_str(), ".cxi")) {
|
|
|
|
return FILETYPE_CTR_CXI; // TODO(bunnei): Do some filetype checking :p
|
|
|
|
}
|
|
|
|
else if (!strcasecmp(extension.c_str(), ".cci")) {
|
|
|
|
return FILETYPE_CTR_CCI; // TODO(bunnei): Do some filetype checking :p
|
|
|
|
}
|
2014-03-31 22:23:55 -04:00
|
|
|
return FILETYPE_UNKNOWN;
|
2013-09-19 23:21:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Identifies and loads a bootable file
|
|
|
|
* @param filename String filename of bootable file
|
|
|
|
* @param error_string Point to string to put error message if an error has occurred
|
|
|
|
* @return True on success, otherwise false
|
|
|
|
*/
|
|
|
|
bool LoadFile(std::string &filename, std::string *error_string) {
|
2014-03-31 22:23:55 -04:00
|
|
|
INFO_LOG(LOADER, "Identifying file...");
|
|
|
|
|
|
|
|
// Note that this can modify filename!
|
|
|
|
switch (IdentifyFile(filename)) {
|
|
|
|
|
|
|
|
case FILETYPE_CTR_ELF:
|
2014-06-16 23:18:10 -04:00
|
|
|
return Loader::Load_ELF(filename, error_string);
|
2014-04-30 23:50:14 -04:00
|
|
|
|
2014-06-16 22:57:09 -04:00
|
|
|
case FILETYPE_CTR_CXI:
|
|
|
|
case FILETYPE_CTR_CCI:
|
|
|
|
return Loader::Load_NCCH(filename, error_string);
|
|
|
|
|
2014-03-31 22:23:55 -04:00
|
|
|
case FILETYPE_ERROR:
|
|
|
|
ERROR_LOG(LOADER, "Could not read file");
|
|
|
|
*error_string = "Error reading file";
|
|
|
|
break;
|
2013-09-19 23:21:22 -04:00
|
|
|
|
2014-03-31 22:23:55 -04:00
|
|
|
case FILETYPE_UNKNOWN:
|
|
|
|
default:
|
|
|
|
ERROR_LOG(LOADER, "Failed to identify file");
|
2014-04-30 23:50:14 -04:00
|
|
|
*error_string = " Failed to identify file";
|
2014-03-31 22:23:55 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return false;
|
2013-09-19 23:21:22 -04:00
|
|
|
}
|
|
|
|
|
2014-06-16 23:18:10 -04:00
|
|
|
} // namespace Loader
|