loader.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2
  3. // Refer to the license.txt file included.
  4. #include <memory>
  5. #include "core/file_sys/archive_romfs.h"
  6. #include "core/loader/3dsx.h"
  7. #include "core/loader/elf.h"
  8. #include "core/loader/ncch.h"
  9. #include "core/hle/kernel/archive.h"
  10. #include "core/mem_map.h"
  11. ////////////////////////////////////////////////////////////////////////////////////////////////////
  12. namespace Loader {
  13. /**
  14. * Identifies the type of a bootable file
  15. * @param filename String filename of bootable file
  16. * @todo (ShizZy) this function sucks... make it actually check file contents etc.
  17. * @return FileType of file
  18. */
  19. FileType IdentifyFile(const std::string &filename) {
  20. if (filename.size() == 0) {
  21. ERROR_LOG(LOADER, "invalid filename %s", filename.c_str());
  22. return FileType::Error;
  23. }
  24. size_t extension_loc = filename.find_last_of('.');
  25. if (extension_loc == std::string::npos)
  26. return FileType::Unknown;
  27. std::string extension = Common::ToLower(filename.substr(extension_loc));
  28. // TODO(bunnei): Do actual filetype checking instead of naively checking the extension
  29. if (extension == ".elf") {
  30. return FileType::ELF;
  31. } else if (extension == ".axf") {
  32. return FileType::ELF;
  33. } else if (extension == ".cxi") {
  34. return FileType::CXI;
  35. } else if (extension == ".cci") {
  36. return FileType::CCI;
  37. } else if (extension == ".bin") {
  38. return FileType::BIN;
  39. } else if (extension == ".3dsx") {
  40. return FileType::THREEDSX;
  41. }
  42. return FileType::Unknown;
  43. }
  44. /**
  45. * Identifies and loads a bootable file
  46. * @param filename String filename of bootable file
  47. * @return ResultStatus result of function
  48. */
  49. ResultStatus LoadFile(const std::string& filename) {
  50. INFO_LOG(LOADER, "Loading file %s...", filename.c_str());
  51. switch (IdentifyFile(filename)) {
  52. //3DSX file format...
  53. case FileType::THREEDSX:
  54. return AppLoader_THREEDSX(filename).Load();
  55. // Standard ELF file format...
  56. case FileType::ELF:
  57. return AppLoader_ELF(filename).Load();
  58. // NCCH/NCSD container formats...
  59. case FileType::CXI:
  60. case FileType::CCI: {
  61. AppLoader_NCCH app_loader(filename);
  62. // Load application and RomFS
  63. if (ResultStatus::Success == app_loader.Load()) {
  64. Kernel::CreateArchive(new FileSys::Archive_RomFS(app_loader), "RomFS");
  65. return ResultStatus::Success;
  66. }
  67. break;
  68. }
  69. // Raw BIN file format...
  70. case FileType::BIN:
  71. {
  72. INFO_LOG(LOADER, "Loading BIN file %s...", filename.c_str());
  73. FileUtil::IOFile file(filename, "rb");
  74. if (file.IsOpen()) {
  75. file.ReadBytes(Memory::GetPointer(Memory::EXEFS_CODE_VADDR), (size_t)file.GetSize());
  76. Kernel::LoadExec(Memory::EXEFS_CODE_VADDR);
  77. } else {
  78. return ResultStatus::Error;
  79. }
  80. return ResultStatus::Success;
  81. }
  82. // Error occurred durring IdentifyFile...
  83. case FileType::Error:
  84. // IdentifyFile could know identify file type...
  85. case FileType::Unknown:
  86. default:
  87. return ResultStatus::ErrorInvalidFormat;
  88. }
  89. return ResultStatus::Error;
  90. }
  91. } // namespace Loader