diff options
Diffstat (limited to 'utils/rbutilqt/base/bootloaderinstallipod.cpp')
-rw-r--r-- | utils/rbutilqt/base/bootloaderinstallipod.cpp | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/utils/rbutilqt/base/bootloaderinstallipod.cpp b/utils/rbutilqt/base/bootloaderinstallipod.cpp new file mode 100644 index 0000000000..807c6e870b --- /dev/null +++ b/utils/rbutilqt/base/bootloaderinstallipod.cpp | |||
@@ -0,0 +1,272 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2008 by Dominik Riebeling | ||
10 | * | ||
11 | * All files in this archive are subject to the GNU General Public License. | ||
12 | * See the file COPYING in the source tree root for full license agreement. | ||
13 | * | ||
14 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
15 | * KIND, either express or implied. | ||
16 | * | ||
17 | ****************************************************************************/ | ||
18 | |||
19 | #include <QtCore> | ||
20 | #include "bootloaderinstallbase.h" | ||
21 | #include "bootloaderinstallipod.h" | ||
22 | |||
23 | #include "../ipodpatcher/ipodpatcher.h" | ||
24 | #include "utils.h" | ||
25 | #include "Logger.h" | ||
26 | |||
27 | |||
28 | BootloaderInstallIpod::BootloaderInstallIpod(QObject *parent) | ||
29 | : BootloaderInstallBase(parent) | ||
30 | { | ||
31 | (void)parent; | ||
32 | // initialize sector buffer. The sector buffer is part of the ipod_t | ||
33 | // structure, so a second instance of this class will have its own buffer. | ||
34 | ipod_alloc_buffer(&ipod, BUFFER_SIZE); | ||
35 | } | ||
36 | |||
37 | |||
38 | BootloaderInstallIpod::~BootloaderInstallIpod() | ||
39 | { | ||
40 | if(ipod.sectorbuf) { | ||
41 | ipod_dealloc_buffer(&ipod); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | |||
46 | bool BootloaderInstallIpod::install(void) | ||
47 | { | ||
48 | if(ipod.sectorbuf == nullptr) { | ||
49 | emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR); | ||
50 | emit done(true); | ||
51 | return false; | ||
52 | } | ||
53 | // save buffer pointer before cleaning up ipod_t structure | ||
54 | unsigned char* sb = ipod.sectorbuf; | ||
55 | memset(&ipod, 0, sizeof(struct ipod_t)); | ||
56 | ipod.sectorbuf = sb; | ||
57 | |||
58 | if(!ipodInitialize(&ipod)) { | ||
59 | emit done(true); | ||
60 | return false; | ||
61 | } | ||
62 | |||
63 | if(ipod.nimages <= 0) { | ||
64 | emit logItem(tr("Failed to read firmware directory"), LOGERROR); | ||
65 | emit done(true); | ||
66 | return false; | ||
67 | } | ||
68 | if(getmodel(&ipod,(ipod.ipod_directory[ipod.ososimage].vers>>8)) < 0) { | ||
69 | emit logItem(tr("Unknown version number in firmware (%1)").arg( | ||
70 | ipod.ipod_directory[ipod.ososimage].vers), LOGERROR); | ||
71 | emit done(true); | ||
72 | return false; | ||
73 | } | ||
74 | if(ipod.macpod) { | ||
75 | emit logItem(tr("Warning: This is a MacPod, Rockbox only runs on WinPods. \n" | ||
76 | "See http://www.rockbox.org/wiki/IpodConversionToFAT32"), LOGERROR); | ||
77 | emit done(true); | ||
78 | return false; | ||
79 | } | ||
80 | emit logItem(tr("Downloading bootloader file"), LOGINFO); | ||
81 | |||
82 | downloadBlStart(m_blurl); | ||
83 | connect(this, &BootloaderInstallBase::downloadDone, this, &BootloaderInstallIpod::installStage2); | ||
84 | return true; | ||
85 | } | ||
86 | |||
87 | |||
88 | void BootloaderInstallIpod::installStage2(void) | ||
89 | { | ||
90 | emit logItem(tr("Installing Rockbox bootloader"), LOGINFO); | ||
91 | QCoreApplication::processEvents(); | ||
92 | |||
93 | if(ipod_reopen_rw(&ipod) < 0) { | ||
94 | emit logItem(tr("Could not open Ipod in R/W mode"), LOGERROR); | ||
95 | emit done(true); | ||
96 | return; | ||
97 | } | ||
98 | QCoreApplication::processEvents(); | ||
99 | |||
100 | m_tempfile.open(); | ||
101 | QString blfile = m_tempfile.fileName(); | ||
102 | m_tempfile.close(); | ||
103 | if(add_bootloader(&ipod, blfile.toLatin1().data(), FILETYPE_DOT_IPOD) == 0) { | ||
104 | emit logItem(tr("Successfull added bootloader"), LOGOK); | ||
105 | ipod_close(&ipod); | ||
106 | #if defined(Q_OS_MACX) | ||
107 | m_remountDevice = ipod.diskname; | ||
108 | connect(this, SIGNAL(remounted(bool)), this, SLOT(installStage3(bool))); | ||
109 | waitRemount(); | ||
110 | #else | ||
111 | installStage3(true); | ||
112 | #endif | ||
113 | } | ||
114 | else { | ||
115 | emit logItem(tr("Failed to add bootloader"), LOGERROR); | ||
116 | ipod_close(&ipod); | ||
117 | emit done(true); | ||
118 | return; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | |||
123 | void BootloaderInstallIpod::installStage3(bool mounted) | ||
124 | { | ||
125 | if(mounted) { | ||
126 | logInstall(LogAdd); | ||
127 | emit logItem(tr("Bootloader Installation complete."), LOGINFO); | ||
128 | emit done(false); | ||
129 | return; | ||
130 | } | ||
131 | else { | ||
132 | emit logItem(tr("Writing log aborted"), LOGERROR); | ||
133 | emit done(true); | ||
134 | } | ||
135 | LOG_INFO() << "version installed:" | ||
136 | << m_blversion.toString(Qt::ISODate); | ||
137 | } | ||
138 | |||
139 | |||
140 | bool BootloaderInstallIpod::uninstall(void) | ||
141 | { | ||
142 | emit logItem(tr("Uninstalling bootloader"), LOGINFO); | ||
143 | QCoreApplication::processEvents(); | ||
144 | |||
145 | if(!ipodInitialize(&ipod)) { | ||
146 | emit done(true); | ||
147 | return false; | ||
148 | } | ||
149 | |||
150 | if (ipod.nimages <= 0) { | ||
151 | emit logItem(tr("Failed to read firmware directory"),LOGERROR); | ||
152 | emit done(true); | ||
153 | return false; | ||
154 | } | ||
155 | if (getmodel(&ipod,(ipod.ipod_directory[ipod.ososimage].vers>>8)) < 0) { | ||
156 | emit logItem(tr("Unknown version number in firmware (%1)").arg( | ||
157 | ipod.ipod_directory[ipod.ososimage].vers), LOGERROR); | ||
158 | emit done(true); | ||
159 | return false; | ||
160 | } | ||
161 | |||
162 | if (ipod_reopen_rw(&ipod) < 0) { | ||
163 | emit logItem(tr("Could not open Ipod in R/W mode"), LOGERROR); | ||
164 | emit done(true); | ||
165 | return false; | ||
166 | } | ||
167 | |||
168 | if (ipod_has_bootloader(&ipod) == 0) { | ||
169 | emit logItem(tr("No bootloader detected."), LOGERROR); | ||
170 | emit done(true); | ||
171 | return false; | ||
172 | } | ||
173 | |||
174 | if (delete_bootloader(&ipod)==0) { | ||
175 | emit logItem(tr("Successfully removed bootloader"), LOGOK); | ||
176 | logInstall(LogRemove); | ||
177 | emit logProgress(1, 1); | ||
178 | emit done(false); | ||
179 | ipod_close(&ipod); | ||
180 | return true; | ||
181 | } | ||
182 | else { | ||
183 | emit logItem(tr("Removing bootloader failed."), LOGERROR); | ||
184 | emit done(true); | ||
185 | ipod_close(&ipod); | ||
186 | return false; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | |||
191 | BootloaderInstallBase::BootloaderType BootloaderInstallIpod::installed(void) | ||
192 | { | ||
193 | BootloaderInstallBase::BootloaderType result = BootloaderRockbox; | ||
194 | |||
195 | if(!ipodInitialize(&ipod)) { | ||
196 | LOG_INFO() << "installed: BootloaderUnknown"; | ||
197 | result = BootloaderUnknown; | ||
198 | } | ||
199 | else { | ||
200 | read_directory(&ipod); | ||
201 | getmodel(&ipod,(ipod.ipod_directory[ipod.ososimage].vers>>8)); | ||
202 | if(!ipod_has_bootloader(&ipod)) { | ||
203 | result = BootloaderOther; | ||
204 | } | ||
205 | else { | ||
206 | LOG_INFO() << "installed: BootloaderRockbox"; | ||
207 | } | ||
208 | } | ||
209 | ipod_close(&ipod); | ||
210 | |||
211 | return result; | ||
212 | } | ||
213 | |||
214 | |||
215 | BootloaderInstallBase::Capabilities BootloaderInstallIpod::capabilities(void) | ||
216 | { | ||
217 | return (Install | Uninstall | IsRaw); | ||
218 | } | ||
219 | |||
220 | |||
221 | /** @initialize Ipod by opening its file handle and checking if its an ipod. | ||
222 | * Note: the caller has to make sure the file handle gets closed! | ||
223 | */ | ||
224 | bool BootloaderInstallIpod::ipodInitialize(struct ipod_t *ipod) | ||
225 | { | ||
226 | if(!m_blfile.isEmpty()) { | ||
227 | QString devicename = Utils::resolveDevicename(m_blfile); | ||
228 | if(devicename.isEmpty()) { | ||
229 | emit logItem(tr("Error: could not retrieve device name"), LOGERROR); | ||
230 | return false; | ||
231 | } | ||
232 | #if defined(Q_OS_WIN32) | ||
233 | sprintf(ipod->diskname, "\\\\.\\PhysicalDrive%i", devicename.toInt()); | ||
234 | #elif defined(Q_OS_MACX) | ||
235 | sprintf(ipod->diskname, "%s", | ||
236 | qPrintable(devicename.remove(QRegExp("s[0-9]+$")))); | ||
237 | #else | ||
238 | sprintf(ipod->diskname, "%s", | ||
239 | qPrintable(devicename.remove(QRegExp("[0-9]+$")))); | ||
240 | #endif | ||
241 | LOG_INFO() << "ipodpatcher: overriding scan, using" | ||
242 | << ipod->diskname; | ||
243 | } | ||
244 | else { | ||
245 | emit logItem(tr("Error: no mountpoint specified!"), LOGERROR); | ||
246 | LOG_ERROR() << "no mountpoint specified!"; | ||
247 | } | ||
248 | int result = ipod_open(ipod, 1); | ||
249 | if(result == -2) { | ||
250 | emit logItem(tr("Could not open Ipod: permission denied"), LOGERROR); | ||
251 | return false; | ||
252 | } | ||
253 | else if(result < 0) { | ||
254 | emit logItem(tr("Could not open Ipod"), LOGERROR); | ||
255 | return false; | ||
256 | } | ||
257 | |||
258 | if(read_partinfo(ipod, 1) < 0) { | ||
259 | emit logItem(tr("Error reading partition table - possibly not an Ipod"), LOGERROR); | ||
260 | ipod_close(ipod); | ||
261 | return false; | ||
262 | } | ||
263 | |||
264 | if(ipod->pinfo[0].start == 0) { | ||
265 | emit logItem(tr("No firmware partition on disk"), LOGERROR); | ||
266 | ipod_close(ipod); | ||
267 | return false; | ||
268 | } | ||
269 | read_directory(ipod); | ||
270 | return true; | ||
271 | } | ||
272 | |||