summaryrefslogtreecommitdiff
path: root/src/core/loader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/loader.cpp')
-rw-r--r--src/core/loader.cpp168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/core/loader.cpp b/src/core/loader.cpp
new file mode 100644
index 000000000..5d039dc94
--- /dev/null
+++ b/src/core/loader.cpp
@@ -0,0 +1,168 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include "file_util.h"
6#include "loader.h"
7#include "system.h"
8#include "core.h"
9#include "file_sys/directory_file_system.h"
10#include "elf/elf_reader.h"
11
12////////////////////////////////////////////////////////////////////////////////////////////////////
13
14/// Loads an extracted CXI from a directory
15bool LoadDirectory_CXI(std::string &filename) {
16 std::string full_path = filename;
17 std::string path, file, extension;
18 SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension);
19#if EMU_PLATFORM == PLATFORM_WINDOWS
20 path = ReplaceAll(path, "/", "\\");
21#endif
22 DirectoryFileSystem *fs = new DirectoryFileSystem(&System::g_ctr_file_system, path);
23 System::g_ctr_file_system.Mount("fs:", fs);
24
25 std::string final_name = "fs:/" + file + extension;
26 File::IOFile f(filename, "rb");
27
28 if (f.IsOpen()) {
29 // TODO(ShizZy): read here to memory....
30 }
31 ERROR_LOG(TIME, "Unimplemented function!");
32 return true;
33}
34
35/// Loads a CTR ELF file
36bool Load_ELF(std::string &filename) {
37 std::string full_path = filename;
38 std::string path, file, extension;
39 SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension);
40#if EMU_PLATFORM == PLATFORM_WINDOWS
41 path = ReplaceAll(path, "/", "\\");
42#endif
43 File::IOFile f(filename, "rb");
44
45 if (f.IsOpen()) {
46 u64 size = f.GetSize();
47 u8* buffer = new u8[size];
48 ElfReader* elf_reader = NULL;
49
50 f.ReadBytes(buffer, size);
51
52 elf_reader = new ElfReader(buffer);
53 elf_reader->LoadInto(0x00100000);
54
55 Core::g_app_core->SetPC(elf_reader->GetEntryPoint());
56
57 delete[] buffer;
58 delete elf_reader;
59 } else {
60 return false;
61 }
62 f.Close();
63
64 return true;
65}
66
67namespace Loader {
68
69bool IsBootableDirectory() {
70 ERROR_LOG(TIME, "Unimplemented function!");
71 return true;
72}
73
74/**
75 * Identifies the type of a bootable file
76 * @param filename String filename of bootable file
77 * @todo (ShizZy) this function sucks... make it actually check file contents etc.
78 * @return FileType of file
79 */
80FileType IdentifyFile(std::string &filename) {
81 if (filename.size() == 0) {
82 ERROR_LOG(LOADER, "invalid filename %s", filename.c_str());
83 return FILETYPE_ERROR;
84 }
85 std::string extension = filename.size() >= 5 ? filename.substr(filename.size() - 4) : "";
86
87 if (File::IsDirectory(filename)) {
88 if (IsBootableDirectory()) {
89 return FILETYPE_DIRECTORY_CXI;
90 }
91 else {
92 return FILETYPE_NORMAL_DIRECTORY;
93 }
94 }
95 else if (!strcasecmp(extension.c_str(), ".elf")) {
96 return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p
97 }
98 else if (!strcasecmp(extension.c_str(), ".zip")) {
99 return FILETYPE_ARCHIVE_ZIP;
100 }
101 else if (!strcasecmp(extension.c_str(), ".rar")) {
102 return FILETYPE_ARCHIVE_RAR;
103 }
104 else if (!strcasecmp(extension.c_str(), ".r00")) {
105 return FILETYPE_ARCHIVE_RAR;
106 }
107 else if (!strcasecmp(extension.c_str(), ".r01")) {
108 return FILETYPE_ARCHIVE_RAR;
109 }
110 return FILETYPE_UNKNOWN;
111}
112
113/**
114 * Identifies and loads a bootable file
115 * @param filename String filename of bootable file
116 * @param error_string Point to string to put error message if an error has occurred
117 * @return True on success, otherwise false
118 */
119bool LoadFile(std::string &filename, std::string *error_string) {
120 INFO_LOG(LOADER, "Identifying file...");
121
122 // Note that this can modify filename!
123 switch (IdentifyFile(filename)) {
124
125 case FILETYPE_CTR_ELF:
126 return Load_ELF(filename);
127
128 case FILETYPE_DIRECTORY_CXI:
129 return LoadDirectory_CXI(filename);
130
131 case FILETYPE_ERROR:
132 ERROR_LOG(LOADER, "Could not read file");
133 *error_string = "Error reading file";
134 break;
135
136 case FILETYPE_ARCHIVE_RAR:
137#ifdef WIN32
138 *error_string = "RAR file detected (Require WINRAR)";
139#else
140 *error_string = "RAR file detected (Require UnRAR)";
141#endif
142 break;
143
144 case FILETYPE_ARCHIVE_ZIP:
145#ifdef WIN32
146 *error_string = "ZIP file detected (Require WINRAR)";
147#else
148 *error_string = "ZIP file detected (Require UnRAR)";
149#endif
150 break;
151
152 case FILETYPE_NORMAL_DIRECTORY:
153 ERROR_LOG(LOADER, "Just a directory.");
154 *error_string = "Just a directory.";
155 break;
156
157 case FILETYPE_UNKNOWN_BIN:
158 case FILETYPE_UNKNOWN_ELF:
159 case FILETYPE_UNKNOWN:
160 default:
161 ERROR_LOG(LOADER, "Failed to identify file");
162 *error_string = "Failed to identify file";
163 break;
164 }
165 return false;
166}
167
168} // namespace \ No newline at end of file