Adapted fwpatcher to patch both H110/H115 and H120/H140 firmwares. Unpatched firmwares are detected by md5sum, and the patched firmware's md5sum is compared to the matching entry, so it should be even more safe than before.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7086 a1c6a512-1295-4272-9138-f99709370657
diff --git a/tools/fwpatcher/Makefile b/tools/fwpatcher/Makefile
index f525597..7dd56f0 100644
--- a/tools/fwpatcher/Makefile
+++ b/tools/fwpatcher/Makefile
@@ -7,8 +7,12 @@
 # $Id$
 #
 
+#value for crosscompiling on linux
 PREFIX=i586-mingw32msvc-
 
+#value for compiling on cygwin
+#PREFIX=
+
 TARGET = fwpatchernu.exe
 TARGETU = fwpatcher.exe
 
@@ -16,9 +20,15 @@
 CC = $(PREFIX)gcc
 
 UNICODE = -DUNICODE -D_UNICODE
+
+#values for crosscompiling on linux
 CFLAGS = -I. -Os -s -fomit-frame-pointer
 LDFLAGS = -lmingw32 -mwindows -s
 
+#values for compiling on cygwin
+#CFLAGS = -I. -Os -s -fomit-frame-pointer -mno-cygwin -DNOCYGWIN
+#LDFLAGS = -lmingw32 -mwindows -s -mno-cygwin
+
 OBJS= resource.o iriver.o main.o md5.o
 OBJSU= resource.o iriveru.o mainu.o md5.o
 
@@ -30,7 +40,7 @@
 $(TARGETU): $(OBJSU)
 	$(CC) $(LDFLAGS) $(OBJSU) -o $@
 
-resource.o: resource.rc bootloader.bin rockbox.ico
+resource.o: resource.rc bootloader-h100.bin bootloader-h120.bin rockbox.ico
 	$(WINDRES) -v $< $@
 
 iriveru.o: iriver.c iriver.h
diff --git a/tools/fwpatcher/checksums.h b/tools/fwpatcher/checksums.h
deleted file mode 100644
index 22f0a7f..0000000
--- a/tools/fwpatcher/checksums.h
+++ /dev/null
@@ -1,6 +0,0 @@
-"4935d52ad3b720b6a156465201245eab", /* 1.63eu */
-"e87c75ea6788d417d9be7b3700cf0557", /* 1.63k */
-"d302d3b90bb26f55f01332fd47968647", /* 1.63us */
-"ffdf317356cc0a964a2708d6b90f59cb", /* 1.65eu */
-"30a33bbfcc37dd4980e36974a5122f02", /* 1.65k */
-"35b19d2acafe795c30c42d0208af1af8", /* 1.65us */
diff --git a/tools/fwpatcher/h100sums.h b/tools/fwpatcher/h100sums.h
new file mode 100644
index 0000000..1605faf
--- /dev/null
+++ b/tools/fwpatcher/h100sums.h
@@ -0,0 +1,9 @@
+/* Checksums of firmwares for ihp_100 */
+/* order: unpatched, patched */
+
+/* 1.65-EU */
+{"478dc657b97e77d1b4944ef26c3dcb8e", "b20d9674c449ef6d929ad5fe2ce3132b"},
+/* 1.65-K */
+{"97ba82fb8099bb23ca0c78fc119f8cce", "5851315169e535b7ae69174d888ceec5"},
+/* 1.65-US */
+{"d3725865e0948cd5f604b00db2ec89aa", "4ff207b3034aac0d1e1dfbf93b046624"},
diff --git a/tools/fwpatcher/h120sums.h b/tools/fwpatcher/h120sums.h
new file mode 100644
index 0000000..70d42d7
--- /dev/null
+++ b/tools/fwpatcher/h120sums.h
@@ -0,0 +1,15 @@
+/* Checksums of firmwares for ihp_120 */
+/* order: unpatched, patched */
+
+/* ihp_120-1.63-EU.hex */
+{"14488347a171480c63c94bc7b885225d", "c4c514656277d7bf81c9951cf56bcdbc"},
+/* ihp_120-1.63-K.hex */
+{"3401fe8845e569156abfaddf05ca7771", "3db4a3dbb30e1464ecf0415f27366215"},
+/* ihp_120-1.63-US.hex */
+{"d9078209105c186cee5246055fdb99c9", "c8531d1b614a1ca514631fc94e2ced21"},
+/* ihp_120-1.65-EU.hex */
+{"c9e71aac4a498f1e2f0e684c2d554ea1", "e41a9c06b7233d62bee044a8942e6b57"},
+/* ihp_120-1.65-K.hex */
+{"360c0c565266f84e9bca610c596f3207", "928120696964d3f71bf81fbfbf4819c4"},
+/* ihp_120-1.65-US.hex */
+{"b9e516d4b8a0265605f46f254897bfb0", "b341f2360a981f7ce21b24c312152cbf"},
diff --git a/tools/fwpatcher/main.c b/tools/fwpatcher/main.c
index 0d0cc19..c16696a 100644
--- a/tools/fwpatcher/main.c
+++ b/tools/fwpatcher/main.c
@@ -39,9 +39,19 @@
 
 #define CTL_NUM 4
 
-/* include precalculated checksums */
-static char *checksums[] = {
-#include "checksums.h"
+struct sumpairs {
+    char *unpatched;
+    char *patched;
+};
+
+/* precalculated checksums for H110/H115 */
+static struct sumpairs h100pairs[] = {
+#include "h100sums.h"
+};
+
+/* precalculated checksums for H120/H140 */
+static struct sumpairs h120pairs[] = {
+#include "h120sums.h"
 };
 
 HICON rbicon;
@@ -156,6 +166,17 @@
 
 /* end mkboot.c excerpt */
 
+int intable(char *md5, struct sumpairs *table, int len)
+{
+    int i;
+    for (i = 0; i < len; i++) {
+        if (strncmp(md5, table[i].unpatched, 32) == 0) {
+            return i;
+        }
+    }
+    return -1;
+}
+
 int FileMD5(TCHAR *name, char *md5)
 {
     int i, read;
@@ -182,7 +203,7 @@
     return 1;
 }
 
-int PatchFirmware()
+int PatchFirmware(int series, int table_entry)
 {
     TCHAR fn[MAX_PATH];
     TCHAR name1[MAX_PATH], name2[MAX_PATH], name3[MAX_PATH];
@@ -192,9 +213,19 @@
     unsigned char md5sum_str[256];
     DWORD blsize;
     int i;
-      
-    /* get pointer to bootloader.bin */
-    res = FindResource(NULL, MAKEINTRESOURCE(IDI_BOOTLOADER), TEXT("BIN"));
+    struct sumpairs *sums;
+    
+    /* get pointer to the correct bootloader.bin */
+    switch(series) {
+        case 100:
+            res = FindResource(NULL, MAKEINTRESOURCE(IDI_BOOTLOADERH100), TEXT("BIN"));
+            sums = &h100pairs[0];
+            break;
+        case 120:
+            res = FindResource(NULL, MAKEINTRESOURCE(IDI_BOOTLOADERH120), TEXT("BIN"));
+            sums = &h120pairs[0];
+            break;
+    }
     resload = LoadResource(NULL, res);
     bootloader = (unsigned char *)LockResource(resload);
     blsize = SizeofResource(NULL, res);
@@ -229,26 +260,24 @@
                    TEXT("Error"), MB_ICONERROR);
         goto error;
     }
-    for (i = 0; i < sizeof(checksums)/sizeof(char *); ++i) {
-        if (strncmp(checksums[i], md5sum_str, 32) == 0) {
-            /* delete temp files */
-            DeleteFile(name1);
-            DeleteFile(name2);
-            /* all is fine, rename the patched file to original name of the firmware */
-            if (DeleteFile(fn) && MoveFile(name3, fn)) {
-                return 1;
-            }
-            else {
-                DeleteFile(name3); /* Deleting a perfectly good firmware here really */
-                MessageBox(NULL,
-                           TEXT("Couldn't modify existing file.\n")
-                           TEXT("Check if file is write protected, then try again."),
-                           TEXT("Error"), MB_ICONERROR);
-                return 0;
-            }
+    if (strncmp(sums[table_entry].patched, md5sum_str, 32) == 0) {
+        /* delete temp files */
+        DeleteFile(name1);
+        DeleteFile(name2);
+        /* all is fine, rename the patched file to original name of the firmware */
+        if (DeleteFile(fn) && MoveFile(name3, fn)) {
+            return 1;
+        }
+        else {
+            DeleteFile(name3); /* Deleting a perfectly good firmware here really */
+            MessageBox(NULL,
+                       TEXT("Couldn't modify existing file.\n")
+                       TEXT("Check if file is write protected, then try again."),
+                       TEXT("Error"), MB_ICONERROR);
+            return 0;
         }
     }
-    MessageBox(NULL, 
+    MessageBox(NULL,
                TEXT("Checksum doesn't match known good patched firmware.\n")
                TEXT("Download another firmware image, then try again."),
                TEXT("Error"), MB_ICONERROR);
@@ -286,8 +315,10 @@
 
 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-   int i;
+   int i, series, table_entry;
+   unsigned char md5sum_str[256];
    switch (msg) {
+   TCHAR fn[MAX_PATH];
    case WM_CREATE:
        /* text label */
        controls[LABEL_FILENAME] = 
@@ -332,9 +363,31 @@
         }
         /* user pressed patch button */
         if (((HWND)lParam == controls[BUTTON_PATCH])) {
-            if (PatchFirmware())
-                MessageBox(NULL, TEXT("Firmware patched successfully"),
-                           TEXT("Success"), MB_OK);
+            GetWindowText(controls[EDIT_FILENAME], fn, MAX_PATH);
+            if (!FileMD5(fn, md5sum_str)) {
+                MessageBox(NULL, TEXT("Couldn't open firmware"), TEXT("Fail"), MB_OK);
+            }
+            else {
+                /* Check firmware against md5sums in h120sums and h100sums */
+                series = 0;
+                table_entry = intable(md5sum_str, &h120pairs[0],
+                                      sizeof(h120pairs)/sizeof(struct sumpairs));
+                if (table_entry >= 0) {
+                    series = 120;
+                }
+                else {
+                    table_entry = intable(md5sum_str, &h100pairs[0],
+                                          sizeof(h100pairs)/sizeof(struct sumpairs));
+                    if (table_entry >= 0)
+                        series = 100;
+                }
+                if (series == 0) {
+                    MessageBox(NULL, TEXT("Unrecognised firmware"), TEXT("Fail"), MB_OK);
+                }
+                else if (PatchFirmware(series, table_entry))
+                    MessageBox(NULL, TEXT("Firmware patched successfully"),
+                               TEXT("Success"), MB_OK);
+            }
         }
         break;
     case WM_USER:
diff --git a/tools/fwpatcher/resource.h b/tools/fwpatcher/resource.h
index 9847eee..c255bff 100644
--- a/tools/fwpatcher/resource.h
+++ b/tools/fwpatcher/resource.h
@@ -1,3 +1,4 @@
 #define IDI_RBICON  101
-#define IDI_BOOTLOADER 102
+#define IDI_BOOTLOADERH100 102
+#define IDI_BOOTLOADERH120 103
 
diff --git a/tools/fwpatcher/resource.rc b/tools/fwpatcher/resource.rc
index f1196df..a1dcb48 100644
--- a/tools/fwpatcher/resource.rc
+++ b/tools/fwpatcher/resource.rc
@@ -1,4 +1,5 @@
 #include "resource.h"
 
 IDI_RBICON ICON "rockbox.ico"
-IDI_BOOTLOADER BIN "bootloader.bin"
+IDI_BOOTLOADERH100 BIN "bootloader-h100.bin"
+IDI_BOOTLOADERH120 BIN "bootloader-h120.bin"