summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Wenger <domonoky@googlemail.com>2007-07-28 14:38:25 +0000
committerDominik Wenger <domonoky@googlemail.com>2007-07-28 14:38:25 +0000
commit488b3db547a09b25eac212e77ccb64ef81f8ce3f (patch)
tree937671a00b37f4f2ca91c9119fe079ea3e837222
parent999676bdd9b19c9fddb143698bfb5e3f4f4ae62a (diff)
downloadrockbox-488b3db547a09b25eac212e77ccb64ef81f8ce3f.tar.gz
rockbox-488b3db547a09b25eac212e77ccb64ef81f8ce3f.zip
rbutilQt: bootloader installation routines for iriver players. Bootloader routines are now completed. They need heavy testing.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14040 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--rbutil/rbutilqt/installbl.cpp55
-rw-r--r--rbutil/rbutilqt/installbl.h4
-rw-r--r--rbutil/rbutilqt/installbootloader.cpp184
-rw-r--r--rbutil/rbutilqt/installbootloader.h11
-rw-r--r--rbutil/rbutilqt/installbootloaderfrm.ui38
-rw-r--r--rbutil/rbutilqt/irivertools/h100sums.h23
-rw-r--r--rbutil/rbutilqt/irivertools/h120sums.h23
-rw-r--r--rbutil/rbutilqt/irivertools/h300sums.h17
-rw-r--r--rbutil/rbutilqt/irivertools/irivertools.cpp532
-rw-r--r--rbutil/rbutilqt/irivertools/irivertools.h69
-rw-r--r--rbutil/rbutilqt/irivertools/md5sum.cpp295
-rw-r--r--rbutil/rbutilqt/irivertools/md5sum.h50
-rw-r--r--rbutil/rbutilqt/rbutilqt.pro12
13 files changed, 1304 insertions, 9 deletions
diff --git a/rbutil/rbutilqt/installbl.cpp b/rbutil/rbutilqt/installbl.cpp
index eae8fc20f6..6d6169f7c6 100644
--- a/rbutil/rbutilqt/installbl.cpp
+++ b/rbutil/rbutilqt/installbl.cpp
@@ -26,6 +26,8 @@ InstallBl::InstallBl(QWidget *parent) : QDialog(parent)
26{ 26{
27 ui.setupUi(this); 27 ui.setupUi(this);
28 connect(ui.buttonBrowse, SIGNAL(clicked()), this, SLOT(browseFolder())); 28 connect(ui.buttonBrowse, SIGNAL(clicked()), this, SLOT(browseFolder()));
29 connect(ui.buttonBrowseOF, SIGNAL(clicked()), this, SLOT(browseOF()));
30
29} 31}
30 32
31void InstallBl::setProxy(QUrl proxy_url) 33void InstallBl::setProxy(QUrl proxy_url)
@@ -43,6 +45,15 @@ void InstallBl::setMountPoint(QString mount)
43 } 45 }
44} 46}
45 47
48void InstallBl::setOFPath(QString path)
49{
50 QFileInfo m(path);
51 if(m.exists()) {
52 ui.lineOriginalFirmware->clear();
53 ui.lineOriginalFirmware->insert(path);
54 }
55}
56
46void InstallBl::browseFolder() 57void InstallBl::browseFolder()
47{ 58{
48 QFileDialog browser(this); 59 QFileDialog browser(this);
@@ -60,6 +71,22 @@ void InstallBl::browseFolder()
60 } 71 }
61} 72}
62 73
74void InstallBl::browseOF()
75{
76 QFileDialog browser(this);
77 if(QFileInfo(ui.lineOriginalFirmware->text()).exists())
78 browser.setDirectory(ui.lineOriginalFirmware->text());
79 else
80 browser.setDirectory("/media");
81 browser.setReadOnly(true);
82 browser.setAcceptMode(QFileDialog::AcceptOpen);
83 if(browser.exec()) {
84 qDebug() << browser.directory();
85 QStringList files = browser.selectedFiles();
86 setOFPath(files.at(0));
87 }
88}
89
63void InstallBl::accept() 90void InstallBl::accept()
64{ 91{
65 QDialog *downloadProgress = new QDialog(this); 92 QDialog *downloadProgress = new QDialog(this);
@@ -77,6 +104,18 @@ void InstallBl::accept()
77 downloadProgress->show(); 104 downloadProgress->show();
78 return; 105 return;
79 } 106 }
107
108 if(QFileInfo(ui.lineOriginalFirmware->text()).exists())
109 {
110 m_OrigFirmware = ui.lineOriginalFirmware->text();
111 }
112 else
113 {
114 dp.listProgress->addItem(tr("Original Firmware Path is wrong!"));
115 dp.buttonAbort->setText(tr("&Ok"));
116 downloadProgress->show();
117 return;
118 }
80 userSettings->sync(); 119 userSettings->sync();
81 120
82 binstaller = new BootloaderInstaller(this); 121 binstaller = new BootloaderInstaller(this);
@@ -89,6 +128,7 @@ void InstallBl::accept()
89 binstaller->setBootloaderMethod(devices->value(plattform + "/bootloadermethod").toString()); 128 binstaller->setBootloaderMethod(devices->value(plattform + "/bootloadermethod").toString());
90 binstaller->setBootloaderName(devices->value(plattform + "/bootloadername").toString()); 129 binstaller->setBootloaderName(devices->value(plattform + "/bootloadername").toString());
91 binstaller->setBootloaderBaseUrl(devices->value("bootloader_url").toString()); 130 binstaller->setBootloaderBaseUrl(devices->value("bootloader_url").toString());
131 binstaller->setOrigFirmwarePath(m_OrigFirmware);
92 132
93 binstaller->install(&dp); 133 binstaller->install(&dp);
94 134
@@ -115,6 +155,21 @@ void InstallBl::done(bool error)
115void InstallBl::setDeviceSettings(QSettings *dev) 155void InstallBl::setDeviceSettings(QSettings *dev)
116{ 156{
117 devices = dev; 157 devices = dev;
158
159 if(userSettings->value("defaults/platform").toString() == "h100" ||
160 userSettings->value("defaults/platform").toString() == "h120" ||
161 userSettings->value("defaults/platform").toString() == "h300")
162 {
163 ui.buttonBrowseOF->show();
164 ui.lineOriginalFirmware->show();
165 ui.label_3->show();
166 }
167 else
168 {
169 ui.buttonBrowseOF->hide();
170 ui.lineOriginalFirmware->hide();
171 ui.label_3->hide();
172 }
118 qDebug() << "Install::setDeviceSettings:" << devices; 173 qDebug() << "Install::setDeviceSettings:" << devices;
119} 174}
120 175
diff --git a/rbutil/rbutilqt/installbl.h b/rbutil/rbutilqt/installbl.h
index 927cfa9b10..9da19eff08 100644
--- a/rbutil/rbutilqt/installbl.h
+++ b/rbutil/rbutilqt/installbl.h
@@ -28,6 +28,7 @@
28#include "ui_installprogressfrm.h" 28#include "ui_installprogressfrm.h"
29 29
30#include "installbootloader.h" 30#include "installbootloader.h"
31#include "irivertools/irivertools.h"
31 32
32class InstallBl : public QDialog 33class InstallBl : public QDialog
33{ 34{
@@ -36,6 +37,7 @@ class InstallBl : public QDialog
36 InstallBl(QWidget *parent = 0); 37 InstallBl(QWidget *parent = 0);
37 void setProxy(QUrl); 38 void setProxy(QUrl);
38 void setMountPoint(QString); 39 void setMountPoint(QString);
40 void setOFPath(QString);
39 void setUserSettings(QSettings*); 41 void setUserSettings(QSettings*);
40 void setDeviceSettings(QSettings*); 42 void setDeviceSettings(QSettings*);
41 43
@@ -54,10 +56,12 @@ class InstallBl : public QDialog
54 QString file; 56 QString file;
55 QString fileName; 57 QString fileName;
56 QString mountPoint; 58 QString mountPoint;
59 QString m_OrigFirmware;
57 BootloaderInstaller* binstaller; 60 BootloaderInstaller* binstaller;
58 61
59 private slots: 62 private slots:
60 void browseFolder(void); 63 void browseFolder(void);
64 void browseOF(void);
61 void done(bool); 65 void done(bool);
62 66
63}; 67};
diff --git a/rbutil/rbutilqt/installbootloader.cpp b/rbutil/rbutilqt/installbootloader.cpp
index 85dd369693..1061210649 100644
--- a/rbutil/rbutilqt/installbootloader.cpp
+++ b/rbutil/rbutilqt/installbootloader.cpp
@@ -60,6 +60,12 @@ void BootloaderInstaller::install(Ui::InstallProgressFrm* dp)
60 connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare())); 60 connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare()));
61 connect(this,SIGNAL(finish()),this,SLOT(sansaFinish())); 61 connect(this,SIGNAL(finish()),this,SLOT(sansaFinish()));
62 } 62 }
63 else if(m_bootloadermethod == "fwpatcher")
64 {
65 // connect internal signal
66 connect(this,SIGNAL(prepare()),this,SLOT(iriverPrepare()));
67 connect(this,SIGNAL(finish()),this,SLOT(iriverFinish()));
68 }
63 else 69 else
64 { 70 {
65 m_dp->listProgress->addItem(tr("unsupported install Method")); 71 m_dp->listProgress->addItem(tr("unsupported install Method"));
@@ -102,6 +108,12 @@ void BootloaderInstaller::uninstall(Ui::InstallProgressFrm* dp)
102 // connect internal signal 108 // connect internal signal
103 connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare())); 109 connect(this,SIGNAL(prepare()),this,SLOT(sansaPrepare()));
104 } 110 }
111 else if(m_bootloadermethod == "fwpatcher")
112 {
113 m_dp->listProgress->addItem(tr("No uninstallation possible"));
114 emit done(true);
115 return;
116 }
105 else 117 else
106 { 118 {
107 m_dp->listProgress->addItem(tr("unsupported install Method")); 119 m_dp->listProgress->addItem(tr("unsupported install Method"));
@@ -885,4 +897,176 @@ void BootloaderInstaller::sansaFinish()
885 897
886} 898}
887 899
900/**************************************************
901*** iriver /fwpatcher secific code
902***************************************************/
903
904void BootloaderInstaller::iriverPrepare()
905{
906 char md5sum_str[32];
907 if (!FileMD5(m_origfirmware, md5sum_str)) {
908 m_dp->listProgress->addItem(tr("Could not MD5Sum original firmware"));
909 emit done(true);
910 return;
911 }
912
913 /* Check firmware against md5sums in h120sums and h100sums */
914 series = 0;
915 table_entry = intable(md5sum_str, &h120pairs[0],
916 sizeof(h120pairs)/sizeof(struct sumpairs));
917 if (table_entry >= 0) {
918 series = 120;
919 }
920 else
921 {
922 table_entry = intable(md5sum_str, &h100pairs[0],
923 sizeof(h100pairs)/sizeof(struct sumpairs));
924 if (table_entry >= 0)
925 {
926 series = 100;
927 }
928 else
929 {
930 table_entry = intable(md5sum_str, &h300pairs[0],
931 sizeof(h300pairs)/sizeof(struct sumpairs));
932 if (table_entry >= 0)
933 series = 300;
934 }
935 }
936 if (series == 0)
937 {
938 m_dp->listProgress->addItem(tr("Could not detect firmware type"));
939 emit done(true);
940 return;
941 }
942
943 QString url = m_bootloaderUrlBase + "/iriver/" + m_bootloadername;
944
945 m_dp->listProgress->addItem(tr("Downloading file %1.%2")
946 .arg(QFileInfo(url).baseName(), QFileInfo(url).completeSuffix()));
947
948 // temporary file needs to be opened to get the filename
949 downloadFile.open();
950 m_tempfilename = downloadFile.fileName();
951 downloadFile.close();
952 // get the real file.
953 getter = new HttpGet(this);
954 getter->setProxy(m_proxy);
955 getter->setFile(&downloadFile);
956 getter->getFile(QUrl(url));
957 // connect signals from HttpGet
958 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
959 //connect(getter, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadRequestFinished(int, bool)));
960 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
961
962}
963
964void BootloaderInstaller::iriverFinish()
965{
966 // Patch firmware
967 char md5sum_str[32];
968 struct sumpairs *sums;
969 int origin;
970
971 /* get pointer to the correct bootloader.bin */
972 switch(series) {
973 case 100:
974 sums = &h100pairs[0];
975 origin = 0x1f0000;
976 break;
977 case 120:
978 sums = &h120pairs[0];
979 origin = 0x1f0000;
980 break;
981 case 300:
982 sums = &h300pairs[0];
983 origin = 0x3f0000;
984 break;
985 }
986
987 // temporary files needs to be opened to get the filename
988 QTemporaryFile firmwareBin, newBin, newHex;
989 firmwareBin.open();
990 newBin.open();
991 newHex.open();
992 QString firmwareBinName = firmwareBin.fileName();
993 QString newBinName = newBin.fileName();
994 QString newHexName = newHex.fileName();
995 firmwareBin.close();
996 newBin.close();
997 newHex.close();
998
999 // iriver decode
1000 if (iriver_decode(m_origfirmware, firmwareBinName, FALSE, STRIP_NONE,m_dp) == -1)
1001 {
1002 m_dp->listProgress->addItem(tr("Error in descramble"));
1003 firmwareBin.remove();
1004 newBin.remove();
1005 newHex.remove();
1006 emit done(true);
1007 return;
1008 }
1009 // mkboot
1010 if (!mkboot(firmwareBinName, newBinName, m_tempfilename, origin,m_dp))
1011 {
1012 m_dp->listProgress->addItem(tr("Error in patching"));
1013 firmwareBin.remove();
1014 newBin.remove();
1015 newHex.remove();
1016 emit done(true);
1017 return;
1018 }
1019 // iriver_encode
1020 if (iriver_encode(newBinName, newHexName, FALSE,m_dp) == -1)
1021 {
1022 m_dp->listProgress->addItem(tr("Error in scramble"));
1023 firmwareBin.remove();
1024 newBin.remove();
1025 newHex.remove();
1026 emit done(true);
1027 return;
1028 }
1029
1030 /* now md5sum it */
1031 if (!FileMD5(newHexName, md5sum_str))
1032 {
1033 m_dp->listProgress->addItem(tr("Error in checksumming"));
1034 firmwareBin.remove();
1035 newBin.remove();
1036 newHex.remove();
1037 emit done(true);
1038 return;
1039 }
1040 if (strncmp(sums[table_entry].patched, md5sum_str, 32) == 0) {
1041 /* delete temp files */
1042 firmwareBin.remove();
1043 newBin.remove();
1044 }
1045
1046 // Load patched Firmware to player
1047 QString dest;
1048 if(series == 100)
1049 dest = m_mountpoint + "/ihp_100.hex";
1050 else if(series == 120)
1051 dest = m_mountpoint + "/ihp_120.hex";
1052 else if(series == 300)
1053 dest = m_mountpoint + "/H300.hex";
1054 // copy file
1055 if(!newHex.copy(dest))
1056 {
1057 m_dp->listProgress->addItem(tr("Could not copy: %1 to %2")
1058 .arg(newHexName,dest));
1059 emit done(true);
1060 return;
1061 }
1062
1063 downloadFile.remove();
1064 newHex.remove();
1065
1066 m_dp->listProgress->addItem(tr("Bootloader install finished successfully."));
1067 m_dp->buttonAbort->setText(tr("&Ok"));
1068
1069 emit done(false); // success
888 1070
1071
1072}
diff --git a/rbutil/rbutilqt/installbootloader.h b/rbutil/rbutilqt/installbootloader.h
index 8f3b6d4b64..f8dfd43c3f 100644
--- a/rbutil/rbutilqt/installbootloader.h
+++ b/rbutil/rbutilqt/installbootloader.h
@@ -24,6 +24,7 @@
24 24
25#include "ui_installprogressfrm.h" 25#include "ui_installprogressfrm.h"
26#include "httpget.h" 26#include "httpget.h"
27#include "irivertools/irivertools.h"
27 28
28extern "C" { 29extern "C" {
29 // Ipodpatcher 30 // Ipodpatcher
@@ -47,10 +48,11 @@ public:
47 48
48 void setMountPoint(QString mountpoint) {m_mountpoint = mountpoint;} 49 void setMountPoint(QString mountpoint) {m_mountpoint = mountpoint;}
49 void setProxy(QUrl proxy) {m_proxy= proxy;} 50 void setProxy(QUrl proxy) {m_proxy= proxy;}
50 void setDevice(QString device) {m_device= device;} 51 void setDevice(QString device) {m_device= device;} // the current plattform
51 void setBootloaderMethod(QString method) {m_bootloadermethod= method;} 52 void setBootloaderMethod(QString method) {m_bootloadermethod= method;}
52 void setBootloaderName(QString name){m_bootloadername= name;} 53 void setBootloaderName(QString name){m_bootloadername= name;}
53 void setBootloaderBaseUrl(QString baseUrl){m_bootloaderUrlBase = baseUrl;} 54 void setBootloaderBaseUrl(QString baseUrl){m_bootloaderUrlBase = baseUrl;}
55 void setOrigFirmwarePath(QString path) {m_origfirmware = path;} //for iriver original firmware
54 56
55signals: 57signals:
56 void done(bool error); //installation finished. 58 void done(bool error); //installation finished.
@@ -83,13 +85,18 @@ private slots:
83 //sansa specific routines 85 //sansa specific routines
84 void sansaPrepare(); 86 void sansaPrepare();
85 void sansaFinish(); 87 void sansaFinish();
88
89 //iriver specific routines
90 void iriverPrepare();
91 void iriverFinish();
86 92
87private: 93private:
88 QString m_mountpoint, m_device,m_bootloadermethod,m_bootloadername; 94 QString m_mountpoint, m_device,m_bootloadermethod,m_bootloadername;
89 QString m_bootloaderUrlBase,m_tempfilename; 95 QString m_bootloaderUrlBase,m_tempfilename,m_origfirmware;
90 QUrl m_proxy; 96 QUrl m_proxy;
91 bool m_install; 97 bool m_install;
92 98
99 int series,table_entry; // for fwpatcher
93 100
94 HttpGet *getter; 101 HttpGet *getter;
95 QTemporaryFile downloadFile; 102 QTemporaryFile downloadFile;
diff --git a/rbutil/rbutilqt/installbootloaderfrm.ui b/rbutil/rbutilqt/installbootloaderfrm.ui
index 93af750143..ebca708cc6 100644
--- a/rbutil/rbutilqt/installbootloaderfrm.ui
+++ b/rbutil/rbutilqt/installbootloaderfrm.ui
@@ -8,8 +8,8 @@
8 <rect> 8 <rect>
9 <x>0</x> 9 <x>0</x>
10 <y>0</y> 10 <y>0</y>
11 <width>673</width> 11 <width>665</width>
12 <height>453</height> 12 <height>499</height>
13 </rect> 13 </rect>
14 </property> 14 </property>
15 <property name="windowTitle" > 15 <property name="windowTitle" >
@@ -43,7 +43,7 @@
43 </property> 43 </property>
44 </widget> 44 </widget>
45 </item> 45 </item>
46 <item row="7" column="2" colspan="2" > 46 <item row="9" column="2" colspan="2" >
47 <widget class="QDialogButtonBox" name="buttonBox" > 47 <widget class="QDialogButtonBox" name="buttonBox" >
48 <property name="orientation" > 48 <property name="orientation" >
49 <enum>Qt::Horizontal</enum> 49 <enum>Qt::Horizontal</enum>
@@ -53,7 +53,7 @@
53 </property> 53 </property>
54 </widget> 54 </widget>
55 </item> 55 </item>
56 <item rowspan="4" row="2" column="1" colspan="3" > 56 <item rowspan="4" row="4" column="1" colspan="3" >
57 <spacer> 57 <spacer>
58 <property name="orientation" > 58 <property name="orientation" >
59 <enum>Qt::Vertical</enum> 59 <enum>Qt::Vertical</enum>
@@ -66,6 +66,36 @@
66 </property> 66 </property>
67 </spacer> 67 </spacer>
68 </item> 68 </item>
69 <item row="3" column="1" >
70 <widget class="QLineEdit" name="lineOriginalFirmware" >
71 <property name="sizePolicy" >
72 <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
73 <horstretch>0</horstretch>
74 <verstretch>0</verstretch>
75 </sizepolicy>
76 </property>
77 <property name="toolTip" >
78 <string>select the original Firmware</string>
79 </property>
80 <property name="accessibleDescription" >
81 <string>select the original Firmware</string>
82 </property>
83 </widget>
84 </item>
85 <item row="2" column="1" >
86 <widget class="QLabel" name="label_3" >
87 <property name="text" >
88 <string>Download and select an original Firmware</string>
89 </property>
90 </widget>
91 </item>
92 <item row="3" column="2" >
93 <widget class="QToolButton" name="buttonBrowseOF" >
94 <property name="text" >
95 <string>Browse</string>
96 </property>
97 </widget>
98 </item>
69 </layout> 99 </layout>
70 </widget> 100 </widget>
71 <resources> 101 <resources>
diff --git a/rbutil/rbutilqt/irivertools/h100sums.h b/rbutil/rbutilqt/irivertools/h100sums.h
new file mode 100644
index 0000000000..ebbdcc28db
--- /dev/null
+++ b/rbutil/rbutilqt/irivertools/h100sums.h
@@ -0,0 +1,23 @@
1/* Checksums of firmwares for ihp_100 */
2/* order: unpatched, patched */
3
4/* 1.63eu */
5{"86103cb05658970b43ce1f40f93d53a8", "4938420d83aa6da3764d33e5a008c8d4"},
6/* 1.63k */
7{"70127fa9ee69afab7645297fbb61636d", "044b737ddb74436353e290d3fbcc3333"},
8/* 1.63us */
9{"7a504a450c76a0dda757fdb6b5531b22", "e51883ed89d49f5677b0a976aef7b154"},
10/* 1.65eu */
11{"478dc657b97e77d1b4944ef26c3dcb8e", "528917d9e5b34a3e5bcac8fe1f4bd7a9"},
12/* 1.65k */
13{"97ba82fb8099bb23ca0c78fc119f8cce", "ef24f69a679e5eba2216045cb24d8b15"},
14/* 1.65us */
15{"d3725865e0948cd5f604b00db2ec89aa", "76d83812b9e1856f768ba913eeba44e1"},
16/* 1.66eu */
17{"fc59f742fe383da3e4d17a660c46afb9", "2aa9d16d3e166a7575fc652db8588daa"},
18/* 1.66k */
19{"22d214401994c276ec6878288caa0dba", "a87dbe604ea98d035450a34b6e184a08"},
20/* 1.66us */
21{"0ae247f567aeafcafecf823a50cbf33e", "f7668e8949f1a78e8ecd685db78b6824"},
22/* 1.66jp */
23{"8bfc8ae5805c270597232efeafade5fd", "72613b75c5196f63e99e41b7a88d7241"},
diff --git a/rbutil/rbutilqt/irivertools/h120sums.h b/rbutil/rbutilqt/irivertools/h120sums.h
new file mode 100644
index 0000000000..09da891ae1
--- /dev/null
+++ b/rbutil/rbutilqt/irivertools/h120sums.h
@@ -0,0 +1,23 @@
1/* Checksums of firmwares for ihp_120 */
2/* order: unpatched, patched */
3
4/* 1.63eu */
5{"14488347a171480c63c94bc7b885225d", "15f09130a1aa02c25f820e8cc68259a4"},
6/* 1.63k */
7{"3401fe8845e569156abfaddf05ca7771", "55e4cb20e36f4da06ad80b31aaaa3054"},
8/* 1.63us */
9{"d9078209105c186cee5246055fdb99c9", "dbdd012a3d821d26f907879cca71e9f4"},
10/* 1.65eu */
11{"c9e71aac4a498f1e2f0e684c2d554ea1", "43454df30c176e55d0df7e3c48e67785"},
12/* 1.65k */
13{"360c0c565266f84e9bca610c596f3207", "d8cb7d9f586186bf9780ee761fc8a677"},
14/* 1.65us */
15{"b9e516d4b8a0265605f46f254897bfb0", "99c5666e990dc782b9daefcb1a087ec0"},
16/* 1.66eu */
17{"a094999b41781f4322a57b9be7fa4534", "e26d2574f39cee0adcdd54fb9f316293"},
18/* 1.66k */
19{"79daba973bb31b60b4b87c2ef497587d", "e76121ba9efe72ecfbb6392eaefe6d96"},
20/* 1.66us */
21{"7fa020a3104c76fbbfcb8313e287dbe2", "12194678a2fdd0814d2e0bb57c8e8e6e"},
22/* 1.66jp */
23{"271d151eb6586929da24b3458ea965fe", "51716393ea0605d225e70a6be29dfdbd"},
diff --git a/rbutil/rbutilqt/irivertools/h300sums.h b/rbutil/rbutilqt/irivertools/h300sums.h
new file mode 100644
index 0000000000..1c6581a6d1
--- /dev/null
+++ b/rbutil/rbutilqt/irivertools/h300sums.h
@@ -0,0 +1,17 @@
1/* Checksums of firmwares for ihp_300 */
2/* order: unpatched, patched */
3
4/* 1.28eu */
5{"0b2083d37f24899b82d21a14d2b38060", "9cd7e291a66f55335c619d63f3a7634b"},
6/* 1.28k */
7{"c6f854ae3d8f48e8982819a4b5302fb0", "90967247ba3f1bcb257432a4d78553bf"},
8/* 1.28jp */
9{"7fcd7bca6b98a34134e2518a616f4e85", "cfd22c20e473727148f11f83d0028fb3"},
10/* 1.29eu */
11{"27d90fc316709c096979ab24c914ee31", "5982302507d57c2a96e9480c242b5de0"},
12/* 1.29k */
13{"44416d97737fc47cd417a64d44064768", "1303e22ef5b1af866aa4def03d6c5f5a"},
14/* 1.29jp */
15{"1ac242c645572a0a5de99ae2b23453b8", "ce433c404ff7531f5852ce3cb61143ee"},
16/* 1.30eu */
17{"8d2d775b018f0532235d38f5317ae10c", "7fb49041294b3e6aea3894218d6d64cf"},
diff --git a/rbutil/rbutilqt/irivertools/irivertools.cpp b/rbutil/rbutilqt/irivertools/irivertools.cpp
new file mode 100644
index 0000000000..f2cc59a8c2
--- /dev/null
+++ b/rbutil/rbutilqt/irivertools/irivertools.cpp
@@ -0,0 +1,532 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Module: rbutil
9 * File: irivertools.cpp
10 *
11 * Copyright (C) 2007 Dominik Wenger
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include "irivertools.h"
22
23
24const unsigned char munge[] = {
25 0x7a, 0x36, 0xc4, 0x43, 0x49, 0x6b, 0x35, 0x4e, 0xa3, 0x46, 0x25, 0x84,
26 0x4d, 0x73, 0x74, 0x61
27};
28
29const unsigned char header_modify[] = "* IHPFIRM-DECODED ";
30
31const char * const models[] = { "iHP-100", "iHP-120/iHP-140", "H300 series",
32 NULL };
33
34/* aligns with models array; expected min firmware size */
35const unsigned int firmware_minsize[] = { 0x100000, 0x100000, 0x200000 };
36/* aligns with models array; expected max firmware size */
37const unsigned int firmware_maxsize[] = { 0x200000, 0x200000, 0x400000 };
38
39const unsigned char header[][16] = {
40 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
41 { 0x20, 0x03, 0x08, 0x27, 0x24, 0x00, 0x02, 0x30, 0x19, 0x17, 0x65, 0x73,
42 0x85, 0x32, 0x83, 0x22 },
43 { 0x20, 0x04, 0x03, 0x27, 0x20, 0x50, 0x01, 0x70, 0x80, 0x30, 0x80, 0x06,
44 0x30, 0x19, 0x17, 0x65 }
45};
46
47/* begin mkboot.c excerpt */
48unsigned char image[0x400000 + 0x220 + 0x400000/0x200];
49
50bool mkboot(QString infile, QString outfile,QString bootloader,int origin,Ui::InstallProgressFrm* dp)
51{
52 int i;
53 int len,bllen;
54 int actual_length, total_length, binary_length, num_chksums;
55
56 memset(image, 0xff, sizeof(image));
57
58 /* First, read the iriver original firmware into the image */
59 QFile f(infile);
60 if(!f.open(QIODevice::ReadOnly))
61 {
62 dp->listProgress->addItem("Could not open: %1" + infile);
63 return false;
64 }
65 i = f.read((char*)image,16);
66 if(i < 16) {
67 dp->listProgress->addItem("reading header failed");
68 return false;
69 }
70
71 /* This is the length of the binary image without the scrambling
72 overhead (but including the ESTFBINR header) */
73 binary_length = image[4] + (image[5] << 8) +
74 (image[6] << 16) + (image[7] << 24);
75
76 /* Read the rest of the binary data, but not the checksum block */
77 len = binary_length+0x200-16;
78 i = f.read((char*)image+16, len);
79 if(i < len) {
80 dp->listProgress->addItem("reading firmware failed");
81 return false;
82 }
83
84 f.close();
85 /* Now, read the boot loader into the image */
86 f.setFileName(bootloader);
87 if(!f.open(QIODevice::ReadOnly))
88 {
89 dp->listProgress->addItem("Could not open: %1" + bootloader);
90 return false;
91 }
92
93 bllen = f.size();
94
95 i = f.read((char*)image+0x220 + origin, bllen);
96 if(i < bllen) {
97 dp->listProgress->addItem("reading bootloader failed");
98 return false;
99 }
100
101 f.close();
102 f.setFileName(outfile);
103 if(!f.open(QIODevice::WriteOnly))
104 {
105 dp->listProgress->addItem("Could not open: %1" + outfile);
106 return false;
107 }
108
109 /* Patch the reset vector to start the boot loader */
110 image[0x220 + 4] = image[origin + 0x220 + 4];
111 image[0x220 + 5] = image[origin + 0x220 + 5];
112 image[0x220 + 6] = image[origin + 0x220 + 6];
113 image[0x220 + 7] = image[origin + 0x220 + 7];
114
115 /* This is the actual length of the binary, excluding all headers */
116 actual_length = origin + bllen;
117
118 /* Patch the ESTFBINR header */
119 image[0x20c] = (actual_length >> 24) & 0xff;
120 image[0x20d] = (actual_length >> 16) & 0xff;
121 image[0x20e] = (actual_length >> 8) & 0xff;
122 image[0x20f] = actual_length & 0xff;
123
124 image[0x21c] = (actual_length >> 24) & 0xff;
125 image[0x21d] = (actual_length >> 16) & 0xff;
126 image[0x21e] = (actual_length >> 8) & 0xff;
127 image[0x21f] = actual_length & 0xff;
128
129 /* This is the length of the binary, including the ESTFBINR header and
130 rounded up to the nearest 0x200 boundary */
131 binary_length = (actual_length + 0x20 + 0x1ff) & 0xfffffe00;
132
133 /* The number of checksums, i.e number of 0x200 byte blocks */
134 num_chksums = binary_length / 0x200;
135
136 /* The total file length, including all headers and checksums */
137 total_length = binary_length + num_chksums + 0x200;
138
139 /* Patch the scrambler header with the new length info */
140 image[0] = total_length & 0xff;
141 image[1] = (total_length >> 8) & 0xff;
142 image[2] = (total_length >> 16) & 0xff;
143 image[3] = (total_length >> 24) & 0xff;
144
145 image[4] = binary_length & 0xff;
146 image[5] = (binary_length >> 8) & 0xff;
147 image[6] = (binary_length >> 16) & 0xff;
148 image[7] = (binary_length >> 24) & 0xff;
149
150 image[8] = num_chksums & 0xff;
151 image[9] = (num_chksums >> 8) & 0xff;
152 image[10] = (num_chksums >> 16) & 0xff;
153 image[11] = (num_chksums >> 24) & 0xff;
154
155 i = f.write((char*)image,total_length);
156 if(i < total_length) {
157 dp->listProgress->addItem("writing bootloader failed");
158 return false;
159 }
160
161 f.close();
162
163 return true;
164}
165
166/* end mkboot.c excerpt */
167
168
169int intable(char *md5, struct sumpairs *table, int len)
170{
171 int i;
172 for (i = 0; i < len; i++) {
173 if (strncmp(md5, table[i].unpatched, 32) == 0) {
174 return i;
175 }
176 }
177 return -1;
178}
179
180
181
182
183static int testheader( const unsigned char * const data )
184{
185 const unsigned char * const d = data+16;
186 const char * const * m = models;
187 int index = 0;
188 while( *m )
189 {
190 if( memcmp( header[ index ], d, 16 ) == 0 )
191 return index;
192 index++;
193 m++;
194 };
195 return -1;
196};
197
198static void modifyheader( unsigned char * data )
199{
200 const unsigned char * h = header_modify;
201 int i;
202 for( i=0; i<512; i++ )
203 {
204 if( *h == '\0' )
205 h = header_modify;
206 *data++ ^= *h++;
207 };
208};
209
210int iriver_decode(QString infile_name, QString outfile_name, unsigned int modify,
211 enum striptype stripmode,Ui::InstallProgressFrm* dp )
212{
213 QFile infile(infile_name);
214 QFile outfile(outfile_name);
215 int i = -1;
216 unsigned char headerdata[512];
217 unsigned long dwLength1, dwLength2, dwLength3, fp = 0;
218 unsigned char blockdata[16+16];
219 unsigned char out[16];
220 unsigned char newmunge;
221 signed long lenread;
222 int s = 0;
223 unsigned char * pChecksums, * ppChecksums = 0;
224 unsigned char ck;
225
226
227 if(!infile.open(QIODevice::ReadOnly))
228 {
229 dp->listProgress->addItem("Could not open: %1" + infile_name);
230 return -1;
231 }
232 if(!outfile.open(QIODevice::WriteOnly))
233 {
234 dp->listProgress->addItem("Could not open: %1" + outfile_name);
235 return -1;
236 }
237 lenread = infile.read( (char*)headerdata, 512);
238 if( lenread != 512 )
239 {
240 dp->listProgress->addItem("This doesn't look like a valid encrypted iHP"
241 "firmware - reason: header length.");
242 infile.close();
243 outfile.close();
244 return -1;
245 };
246
247 i = testheader( headerdata );
248 if( i == -1 )
249 {
250 dp->listProgress->addItem("This firmware is for an unknown model, or is not"
251 " a valid encrypted iHP firmware.");
252 infile.close();
253 outfile.close();
254 return -1;
255 };
256 fprintf( stderr, "Model %s\n", models[ i ] );
257
258 dwLength1 = headerdata[0] | (headerdata[1]<<8) |
259 (headerdata[2]<<16) | (headerdata[3]<<24);
260 dwLength2 = headerdata[4] | (headerdata[5]<<8) |
261 (headerdata[6]<<16) | (headerdata[7]<<24);
262 dwLength3 = headerdata[8] | (headerdata[9]<<8) |
263 (headerdata[10]<<16) | (headerdata[11]<<24);
264
265 if( dwLength1 < firmware_minsize[ i ] ||
266 dwLength1 > firmware_maxsize[ i ] ||
267 dwLength2 < firmware_minsize[ i ] ||
268 dwLength2 > dwLength1 ||
269 dwLength3 > dwLength1 ||
270 dwLength2>>9 != dwLength3 ||
271 dwLength2+dwLength3+512 != dwLength1 )
272 {
273 dp->listProgress->addItem("This doesn't look like a valid encrypted "
274 "iHP firmware - reason: file 'length' data.");
275 infile.close();
276 outfile.close();
277 return -1;
278 };
279
280 pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) );
281
282 if( modify )
283 {
284 modifyheader( headerdata );
285 };
286
287 if( stripmode == STRIP_NONE )
288 outfile.write( (char*)headerdata, 512);
289
290 memset( blockdata, 0, 16 );
291
292 ck = 0;
293 while( ( fp < dwLength2 ) &&
294 ( lenread = infile.read( (char*)blockdata+16, 16) == 16) )
295 {
296 fp += 16;
297
298 for( i=0; i<16; ++i )
299 {
300 newmunge = blockdata[16+i] ^ munge[i];
301 out[i] = newmunge ^ blockdata[i];
302 blockdata[i] = newmunge;
303 ck += out[i];
304 }
305
306 if( fp > ESTF_SIZE || stripmode != STRIP_HEADER_CHECKSUM_ESTF )
307 {
308 outfile.write( (char*)out+4, 12);
309 outfile.write( (char*)out, 4);
310 }
311 else
312 {
313 if( ESTF_SIZE - fp < 16 )
314 {
315 memcpy( out+4, blockdata+16, 12 );
316 memcpy( out, blockdata+28, 4 );
317 outfile.write((char*) blockdata+16+ESTF_SIZE-fp, ESTF_SIZE-fp);
318 }
319 }
320
321
322 if( s == 496 )
323 {
324 s = 0;
325 memset( blockdata, 0, 16 );
326 *ppChecksums++ = ck;
327 ck = 0;
328 }
329 else
330 s+=16;
331 };
332
333 if( fp != dwLength2 )
334 {
335 dp->listProgress->addItem("This doesn't look like a valid encrypted "
336 "iHP firmware - reason: 'length2' mismatch.");
337 infile.close();
338 outfile.close();
339 return -1;
340 };
341
342 fp = 0;
343 ppChecksums = pChecksums;
344 while( ( fp < dwLength3 ) &&
345 ( lenread = infile.read((char*) blockdata, 32 ) ) > 0 )
346 {
347 fp += lenread;
348 if( stripmode == STRIP_NONE )
349 outfile.write((char*) blockdata, lenread );
350 if( memcmp( ppChecksums, blockdata, lenread ) != 0 )
351 {
352 dp->listProgress->addItem("This doesn't look like a valid encrypted "
353 "iHP firmware - reason: Checksum mismatch!");
354 infile.close();
355 outfile.close();
356 return -1;
357 };
358 ppChecksums += lenread;
359 };
360
361 if( fp != dwLength3 )
362 {
363 dp->listProgress->addItem("This doesn't look like a valid encrypted "
364 "iHP firmware - reason: 'length3' mismatch.");
365 infile.close();
366 outfile.close();
367 return -1;
368 };
369
370
371 fprintf( stderr, "File decoded correctly and all checksums matched!\n" );
372 switch( stripmode )
373 {
374 default:
375 case STRIP_NONE:
376 fprintf(stderr, "Output file contains all headers and "
377 "checksums\n");
378 break;
379 case STRIP_HEADER_CHECKSUM:
380 fprintf( stderr, "NB: output file contains only ESTFBINR header"
381 " and decoded firmware code\n" );
382 break;
383 case STRIP_HEADER_CHECKSUM_ESTF:
384 fprintf( stderr, "NB: output file contains only raw decoded "
385 "firmware code\n" );
386 break;
387 };
388
389 infile.close();
390 outfile.close();
391 return 0;
392
393};
394
395int iriver_encode(QString infile_name, QString outfile_name, unsigned int modify,Ui::InstallProgressFrm* dp )
396{
397 QFile infile(infile_name);
398 QFile outfile(outfile_name);
399 int i = -1;
400 unsigned char headerdata[512];
401 unsigned long dwLength1, dwLength2, dwLength3, fp = 0;
402 unsigned char blockdata[16+16];
403 unsigned char out[16];
404 unsigned char newmunge;
405 signed long lenread;
406 int s = 0;
407 unsigned char * pChecksums, * ppChecksums;
408 unsigned char ck;
409
410 if(!infile.open(QIODevice::ReadOnly))
411 {
412 dp->listProgress->addItem("Could not open: %1" + infile_name);
413 return -1;
414 }
415 if(!outfile.open(QIODevice::WriteOnly))
416 {
417 dp->listProgress->addItem("Could not open: %1" + outfile_name);
418 return -1;
419 }
420
421 lenread = infile.read((char*) headerdata, 512 );
422 if( lenread != 512 )
423 {
424 dp->listProgress->addItem("This doesn't look like a valid decoded "
425 "iHP firmware - reason: header length.");
426 infile.close();
427 outfile.close();
428 };
429
430 if( modify )
431 {
432 modifyheader( headerdata ); /* reversible */
433 };
434
435 i = testheader( headerdata );
436 if( i == -1 )
437 {
438 dp->listProgress->addItem("This firmware is for an unknown model, or is not"
439 " a valid decoded iHP firmware.");
440 infile.close();
441 outfile.close();
442 };
443 fprintf( stderr, "Model %s\n", models[ i ] );
444
445 dwLength1 = headerdata[0] | (headerdata[1]<<8) |
446 (headerdata[2]<<16) | (headerdata[3]<<24);
447 dwLength2 = headerdata[4] | (headerdata[5]<<8) |
448 (headerdata[6]<<16) | (headerdata[7]<<24);
449 dwLength3 = headerdata[8] | (headerdata[9]<<8) |
450 (headerdata[10]<<16) | (headerdata[11]<<24);
451
452 if( dwLength1 < firmware_minsize[i] ||
453 dwLength1 > firmware_maxsize[i] ||
454 dwLength2 < firmware_minsize[i] ||
455 dwLength2 > dwLength1 ||
456 dwLength3 > dwLength1 ||
457 dwLength2+dwLength3+512 != dwLength1 )
458 {
459 dp->listProgress->addItem("This doesn't look like a valid decoded "
460 "iHP firmware - reason:file 'length' data.");
461 infile.close();
462 outfile.close();
463 };
464
465 pChecksums = ppChecksums = (unsigned char *)( malloc( dwLength3 ) );
466
467 outfile.write( (char*)headerdata, 512);
468
469 memset( blockdata, 0, 16 );
470 ck = 0;
471 while( ( fp < dwLength2 ) &&
472 ( lenread = infile.read((char*) blockdata+16, 16) ) == 16 )
473 {
474 fp += 16;
475 for( i=0; i<16; ++i )
476 {
477 newmunge = blockdata[16+((12+i)&0xf)] ^ blockdata[i];
478 out[i] = newmunge ^ munge[i];
479 ck += blockdata[16+i];
480 blockdata[i] = newmunge;
481 };
482 outfile.write( (char*)out, 16);
483
484 if( s == 496 )
485 {
486 s = 0;
487 memset( blockdata, 0, 16 );
488 *ppChecksums++ = ck;
489 ck = 0;
490 }
491 else
492 s+=16;
493 };
494
495 if( fp != dwLength2 )
496 {
497 dp->listProgress->addItem("This doesn't look like a valid decoded "
498 "iHP firmware - reason: 'length1' mismatch.");
499 infile.close();
500 outfile.close();
501 };
502
503 /* write out remainder w/out applying descrambler */
504 fp = 0;
505 lenread = dwLength3;
506 ppChecksums = pChecksums;
507 while( ( fp < dwLength3) &&
508 ( lenread = outfile.write((char*) ppChecksums, lenread) ) > 0 )
509 {
510 fp += lenread;
511 ppChecksums += lenread;
512 lenread = dwLength3 - fp;
513 };
514
515 if( fp != dwLength3 )
516 {
517 dp->listProgress->addItem("This doesn't look like a valid decoded "
518 "iHP firmware - 'length2' mismatch.");
519 infile.close();
520 outfile.close();
521 };
522
523 fprintf( stderr, "File encoded successfully and checksum table built!\n" );
524
525 infile.close();
526 outfile.close();
527 return 0;
528
529};
530
531
532
diff --git a/rbutil/rbutilqt/irivertools/irivertools.h b/rbutil/rbutilqt/irivertools/irivertools.h
new file mode 100644
index 0000000000..54809d7645
--- /dev/null
+++ b/rbutil/rbutilqt/irivertools/irivertools.h
@@ -0,0 +1,69 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Module: rbutil
9 * File: irivertools.h
10 *
11 * Copyright (C) 2007 Dominik Wenger
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef IRIVERTOOLS_H_INCLUDED
23#define IRIVERTOOLS_H_INCLUDED
24
25#include <QtGui>
26
27#include "md5sum.h"
28#include "ui_installprogressfrm.h"
29
30#define ESTF_SIZE 32
31
32struct sumpairs {
33 char *unpatched;
34 char *patched;
35};
36
37/* precalculated checksums for H110/H115 */
38static struct sumpairs h100pairs[] = {
39#include "h100sums.h"
40};
41
42/* precalculated checksums for H120/H140 */
43static struct sumpairs h120pairs[] = {
44#include "h120sums.h"
45};
46
47/* precalculated checksums for H320/H340 */
48static struct sumpairs h300pairs[] = {
49#include "h300sums.h"
50};
51
52
53enum striptype
54{
55 STRIP_NONE,
56 STRIP_HEADER_CHECKSUM,
57 STRIP_HEADER_CHECKSUM_ESTF
58};
59
60/* protos for iriver.c */
61
62int intable(char *md5, struct sumpairs *table, int len);
63
64bool mkboot(QString infile, QString outfile,QString bootloader,int origin,Ui::InstallProgressFrm* dp);
65int iriver_decode(QString infile_name, QString outfile_name, unsigned int modify,
66 enum striptype stripmode,Ui::InstallProgressFrm* dp );
67int iriver_encode(QString infile_name, QString outfile_name, unsigned int modify,Ui::InstallProgressFrm* dp);
68
69#endif // IRIVERTOOLS_H_INCLUDED
diff --git a/rbutil/rbutilqt/irivertools/md5sum.cpp b/rbutil/rbutilqt/irivertools/md5sum.cpp
new file mode 100644
index 0000000000..f4d25e67ef
--- /dev/null
+++ b/rbutil/rbutilqt/irivertools/md5sum.cpp
@@ -0,0 +1,295 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Module: rbutil
9 * File: md5sum.cpp
10 *
11 * Copyright (C) 2007 Dominik Wenger
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22/*
23 * RFC 1321 compliant MD5 implementation
24 *
25 * Copyright (C) 2001-2003 Christophe Devine
26 *
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 2 of the License, or
30 * (at your option) any later version.
31 *
32 * This program is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
36 *
37 * You should have received a copy of the GNU General Public License
38 * along with this program; if not, write to the Free Software
39 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40 */
41
42
43#include "md5sum.h"
44
45
46#define GET_UINT32(n,b,i) \
47{ \
48 (n) = ( (uint32) (b)[(i) ] ) \
49 | ( (uint32) (b)[(i) + 1] << 8 ) \
50 | ( (uint32) (b)[(i) + 2] << 16 ) \
51 | ( (uint32) (b)[(i) + 3] << 24 ); \
52}
53
54#define PUT_UINT32(n,b,i) \
55{ \
56 (b)[(i) ] = (uint8) ( (n) ); \
57 (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \
58 (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \
59 (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \
60}
61
62void md5_starts( md5_context *ctx )
63{
64 ctx->total[0] = 0;
65 ctx->total[1] = 0;
66
67 ctx->state[0] = 0x67452301;
68 ctx->state[1] = 0xEFCDAB89;
69 ctx->state[2] = 0x98BADCFE;
70 ctx->state[3] = 0x10325476;
71}
72
73void md5_process( md5_context *ctx, uint8 data[64] )
74{
75 uint32 X[16], A, B, C, D;
76
77 GET_UINT32( X[0], data, 0 );
78 GET_UINT32( X[1], data, 4 );
79 GET_UINT32( X[2], data, 8 );
80 GET_UINT32( X[3], data, 12 );
81 GET_UINT32( X[4], data, 16 );
82 GET_UINT32( X[5], data, 20 );
83 GET_UINT32( X[6], data, 24 );
84 GET_UINT32( X[7], data, 28 );
85 GET_UINT32( X[8], data, 32 );
86 GET_UINT32( X[9], data, 36 );
87 GET_UINT32( X[10], data, 40 );
88 GET_UINT32( X[11], data, 44 );
89 GET_UINT32( X[12], data, 48 );
90 GET_UINT32( X[13], data, 52 );
91 GET_UINT32( X[14], data, 56 );
92 GET_UINT32( X[15], data, 60 );
93
94#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
95
96#define P(a,b,c,d,k,s,t) \
97{ \
98 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
99}
100
101 A = ctx->state[0];
102 B = ctx->state[1];
103 C = ctx->state[2];
104 D = ctx->state[3];
105
106#define F(x,y,z) (z ^ (x & (y ^ z)))
107
108 P( A, B, C, D, 0, 7, 0xD76AA478 );
109 P( D, A, B, C, 1, 12, 0xE8C7B756 );
110 P( C, D, A, B, 2, 17, 0x242070DB );
111 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
112 P( A, B, C, D, 4, 7, 0xF57C0FAF );
113 P( D, A, B, C, 5, 12, 0x4787C62A );
114 P( C, D, A, B, 6, 17, 0xA8304613 );
115 P( B, C, D, A, 7, 22, 0xFD469501 );
116 P( A, B, C, D, 8, 7, 0x698098D8 );
117 P( D, A, B, C, 9, 12, 0x8B44F7AF );
118 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
119 P( B, C, D, A, 11, 22, 0x895CD7BE );
120 P( A, B, C, D, 12, 7, 0x6B901122 );
121 P( D, A, B, C, 13, 12, 0xFD987193 );
122 P( C, D, A, B, 14, 17, 0xA679438E );
123 P( B, C, D, A, 15, 22, 0x49B40821 );
124
125#undef F
126
127#define F(x,y,z) (y ^ (z & (x ^ y)))
128
129 P( A, B, C, D, 1, 5, 0xF61E2562 );
130 P( D, A, B, C, 6, 9, 0xC040B340 );
131 P( C, D, A, B, 11, 14, 0x265E5A51 );
132 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
133 P( A, B, C, D, 5, 5, 0xD62F105D );
134 P( D, A, B, C, 10, 9, 0x02441453 );
135 P( C, D, A, B, 15, 14, 0xD8A1E681 );
136 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
137 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
138 P( D, A, B, C, 14, 9, 0xC33707D6 );
139 P( C, D, A, B, 3, 14, 0xF4D50D87 );
140 P( B, C, D, A, 8, 20, 0x455A14ED );
141 P( A, B, C, D, 13, 5, 0xA9E3E905 );
142 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
143 P( C, D, A, B, 7, 14, 0x676F02D9 );
144 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
145
146#undef F
147
148#define F(x,y,z) (x ^ y ^ z)
149
150 P( A, B, C, D, 5, 4, 0xFFFA3942 );
151 P( D, A, B, C, 8, 11, 0x8771F681 );
152 P( C, D, A, B, 11, 16, 0x6D9D6122 );
153 P( B, C, D, A, 14, 23, 0xFDE5380C );
154 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
155 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
156 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
157 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
158 P( A, B, C, D, 13, 4, 0x289B7EC6 );
159 P( D, A, B, C, 0, 11, 0xEAA127FA );
160 P( C, D, A, B, 3, 16, 0xD4EF3085 );
161 P( B, C, D, A, 6, 23, 0x04881D05 );
162 P( A, B, C, D, 9, 4, 0xD9D4D039 );
163 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
164 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
165 P( B, C, D, A, 2, 23, 0xC4AC5665 );
166
167#undef F
168
169#define F(x,y,z) (y ^ (x | ~z))
170
171 P( A, B, C, D, 0, 6, 0xF4292244 );
172 P( D, A, B, C, 7, 10, 0x432AFF97 );
173 P( C, D, A, B, 14, 15, 0xAB9423A7 );
174 P( B, C, D, A, 5, 21, 0xFC93A039 );
175 P( A, B, C, D, 12, 6, 0x655B59C3 );
176 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
177 P( C, D, A, B, 10, 15, 0xFFEFF47D );
178 P( B, C, D, A, 1, 21, 0x85845DD1 );
179 P( A, B, C, D, 8, 6, 0x6FA87E4F );
180 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
181 P( C, D, A, B, 6, 15, 0xA3014314 );
182 P( B, C, D, A, 13, 21, 0x4E0811A1 );
183 P( A, B, C, D, 4, 6, 0xF7537E82 );
184 P( D, A, B, C, 11, 10, 0xBD3AF235 );
185 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
186 P( B, C, D, A, 9, 21, 0xEB86D391 );
187
188#undef F
189#undef S
190#undef P
191
192
193 ctx->state[0] += A;
194 ctx->state[1] += B;
195 ctx->state[2] += C;
196 ctx->state[3] += D;
197}
198
199void md5_update( md5_context *ctx, uint8 *input, uint32 length )
200{
201 uint32 left, fill;
202
203 if( ! length ) return;
204
205 left = ctx->total[0] & 0x3F;
206 fill = 64 - left;
207
208 ctx->total[0] += length;
209 ctx->total[0] &= 0xFFFFFFFF;
210
211 if( ctx->total[0] < length )
212 ctx->total[1]++;
213
214 if( left && length >= fill )
215 {
216 memcpy( (void *) (ctx->buffer + left),
217 (void *) input, fill );
218 md5_process( ctx, ctx->buffer );
219 length -= fill;
220 input += fill;
221 left = 0;
222 }
223
224 while( length >= 64 )
225 {
226 md5_process( ctx, input );
227 length -= 64;
228 input += 64;
229 }
230
231 if( length )
232 {
233 memcpy( (void *) (ctx->buffer + left),
234 (void *) input, length );
235 }
236}
237
238static uint8 md5_padding[64] =
239{
240 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
244};
245
246void md5_finish( md5_context *ctx, uint8 digest[16] )
247{
248 uint32 last, padn;
249 uint32 high, low;
250 uint8 msglen[8];
251
252 high = ( ctx->total[0] >> 29 )
253 | ( ctx->total[1] << 3 );
254 low = ( ctx->total[0] << 3 );
255
256 PUT_UINT32( low, msglen, 0 );
257 PUT_UINT32( high, msglen, 4 );
258
259 last = ctx->total[0] & 0x3F;
260 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
261
262 md5_update( ctx, md5_padding, padn );
263 md5_update( ctx, msglen, 8 );
264
265 PUT_UINT32( ctx->state[0], digest, 0 );
266 PUT_UINT32( ctx->state[1], digest, 4 );
267 PUT_UINT32( ctx->state[2], digest, 8 );
268 PUT_UINT32( ctx->state[3], digest, 12 );
269}
270
271int FileMD5(QString name, char *md5)
272{
273 int i, read;
274 md5_context ctx;
275 unsigned char md5sum[16];
276 unsigned char block[32768];
277
278 QFile file(name);
279
280 if (!file.open(QIODevice::ReadOnly)) {
281 return 0;
282 }
283 md5_starts(&ctx);
284 while ( !file.atEnd() ) {
285 read = file.read((char*)block, sizeof(block));
286 md5_update(&ctx, block, read);
287 }
288 file.close();
289 md5_finish(&ctx, md5sum);
290 for (i = 0; i < 16; ++i)
291 {
292 sprintf(md5 + 2*i, "%02x", md5sum[i]);
293 }
294 return 1;
295}
diff --git a/rbutil/rbutilqt/irivertools/md5sum.h b/rbutil/rbutilqt/irivertools/md5sum.h
new file mode 100644
index 0000000000..ed22bdbb49
--- /dev/null
+++ b/rbutil/rbutilqt/irivertools/md5sum.h
@@ -0,0 +1,50 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Module: rbutil
9 * File: md5sum.h
10 *
11 * Copyright (C) 2007 Dominik Wenger
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21
22#ifndef MD5SUM_H_INCLUDED
23#define MD5SUM_H_INCLUDED
24
25#ifndef uint8
26#define uint8 unsigned char
27#endif
28
29
30#ifndef uint32
31#define uint32 unsigned long int
32#endif
33
34#include <QtGui>
35
36typedef struct
37{
38 uint32 total[2];
39 uint32 state[4];
40 uint8 buffer[64];
41}
42md5_context;
43
44void md5_starts( md5_context *ctx );
45void md5_update( md5_context *ctx, uint8 *input, uint32 length );
46void md5_finish( md5_context *ctx, uint8 digest[16] );
47
48int FileMD5(QString name, char *md5);
49
50#endif // MD5SUM_H_INCLUDED
diff --git a/rbutil/rbutilqt/rbutilqt.pro b/rbutil/rbutilqt/rbutilqt.pro
index dd8e1bca2c..f42233cc54 100644
--- a/rbutil/rbutilqt/rbutilqt.pro
+++ b/rbutil/rbutilqt/rbutilqt.pro
@@ -9,7 +9,9 @@ SOURCES += rbutilqt.cpp \
9 installbootloader.cpp \ 9 installbootloader.cpp \
10 installbl.cpp \ 10 installbl.cpp \
11 ../ipodpatcher/ipodpatcher.c \ 11 ../ipodpatcher/ipodpatcher.c \
12 ../sansapatcher/sansapatcher.c 12 ../sansapatcher/sansapatcher.c \
13 irivertools/irivertools.cpp \
14 irivertools/md5sum.cpp
13 15
14 16
15HEADERS += rbutilqt.h \ 17HEADERS += rbutilqt.h \
@@ -30,8 +32,12 @@ HEADERS += rbutilqt.h \
30 ../ipodpatcher/ipodio.h \ 32 ../ipodpatcher/ipodio.h \
31 ../ipodpatcher/parttypes.h \ 33 ../ipodpatcher/parttypes.h \
32 ../sansapatcher/sansapatcher.h \ 34 ../sansapatcher/sansapatcher.h \
33 ../sansapatcher/sansaio.h 35 ../sansapatcher/sansaio.h \
34 36 irivertools/irivertools.h \
37 irivertools/md5sum.h \
38 irivertools/h100sums.h \
39 irivertools/h120sums.h \
40 irivertools/h300sums.h
35 41
36TEMPLATE = app 42TEMPLATE = app
37CONFIG += release \ 43CONFIG += release \