Revision: 2234
          http://gtkpod.svn.sourceforge.net/gtkpod/?rev=2234&view=rev
Author:   teuf
Date:     2009-01-21 21:50:17 +0000 (Wed, 21 Jan 2009)

Log Message:
-----------
Start making checksum generation more generic

Modified Paths:
--------------
    libgpod/trunk/ChangeLog
    libgpod/trunk/src/itdb_device.c
    libgpod/trunk/src/itdb_device.h
    libgpod/trunk/src/itdb_itunesdb.c

Modified: libgpod/trunk/ChangeLog
===================================================================
--- libgpod/trunk/ChangeLog     2009-01-21 21:49:08 UTC (rev 2233)
+++ libgpod/trunk/ChangeLog     2009-01-21 21:50:17 UTC (rev 2234)
@@ -1,5 +1,13 @@
 2009-01-21  Christophe Fergeau  <teuf at gnome.org>
 
+       * src/itdb_device.c:
+       * src/itdb_device.h:
+       * src/itdb_itunesdb.c: move checksumming function from
+       itdb_itunesdb.c to itdb_device.c to make it easier to support
+       different checksumming methods depending on the ipod model
+
+2009-01-21  Christophe Fergeau  <teuf at gnome.org>
+
        * src/db-itunes-parser.h: add tons of new fields to struct MhbdHeader 
 
 2009-01-20  Christophe Fergeau  <teuf at gnome.org>

Modified: libgpod/trunk/src/itdb_device.c
===================================================================
--- libgpod/trunk/src/itdb_device.c     2009-01-21 21:49:08 UTC (rev 2233)
+++ libgpod/trunk/src/itdb_device.c     2009-01-21 21:50:17 UTC (rev 2234)
@@ -29,9 +29,12 @@
 |
 |  $Id$
 */
+#include <config.h>
 
+#include "db-itunes-parser.h"
 #include "itdb_device.h"
 #include "itdb_private.h"
+#include "itdb_sha1.h"
 #include <ctype.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -1681,18 +1684,19 @@
     return g_ascii_strtoull (fwid, NULL, 16);
 }
 
-G_GNUC_INTERNAL gboolean itdb_device_requires_checksum (Itdb_Device *device) 
+G_GNUC_INTERNAL ItdbChecksumType itdb_device_get_checksum_type (const 
Itdb_Device *device)
 {
     const Itdb_IpodInfo *info;
 
     if (device == NULL) {
-        return FALSE;
+        return ITDB_CHECKSUM_NONE;
     }
 
     info = itdb_device_get_ipod_info (device);
     if (info == NULL) {
-        return FALSE;
+        return ITDB_CHECKSUM_NONE;
     }
+
     switch (info->ipod_generation) {
     case ITDB_IPOD_GENERATION_CLASSIC_1: 
     case ITDB_IPOD_GENERATION_CLASSIC_2:
@@ -1700,7 +1704,7 @@
     case ITDB_IPOD_GENERATION_NANO_4:
     case ITDB_IPOD_GENERATION_TOUCH_1:
     case ITDB_IPOD_GENERATION_IPHONE_1:
-      return TRUE;
+      return ITDB_CHECKSUM_HASH58;
 
     case ITDB_IPOD_GENERATION_UNKNOWN:
     case ITDB_IPOD_GENERATION_FIRST:
@@ -1718,12 +1722,87 @@
     case ITDB_IPOD_GENERATION_NANO_2:
     case ITDB_IPOD_GENERATION_VIDEO_1:
     case ITDB_IPOD_GENERATION_VIDEO_2:
-            return FALSE;
+            return ITDB_CHECKSUM_NONE;
     }
 
-    return FALSE;
+    return ITDB_CHECKSUM_NONE;
 }
 
+static gboolean itdb_device_write_hash58 (Itdb_Device *device, 
+                                         unsigned char *itdb_data, 
+                                         gsize itdb_len,
+                                         GError **error)
+{
+    guint64 fwid;
+    guchar backup18[8];
+    guchar backup32[20];
+    unsigned char *checksum;
+    gsize len;
+    MhbdHeader *header;
+   
+    if (itdb_device_get_checksum_type (device) != ITDB_CHECKSUM_HASH58) {
+        return TRUE;
+    }  
+
+    fwid = itdb_device_get_firewire_id (device);
+    if (fwid == 0) {
+       g_set_error (error, 0, -1, "Couldn't find the iPod firewire ID");
+       return FALSE;
+    }
+
+    if (itdb_len < 0x6c) {
+       g_set_error (error, 0, -1, "iTunesDB file too small to write checksum");
+       return FALSE;
+    }
+
+    header = (MhbdHeader *)itdb_data;
+    g_assert (strncmp (header->header_id, "mhbd", strlen ("mhbd")) == 0);
+    memcpy (backup18, &header->db_id, sizeof (backup18));
+    memcpy (backup32, &header->unknown6, sizeof (backup32));
+
+    /* Those fields must be zero'ed out for the sha1 calculation */
+    memset(&header->db_id, 0, sizeof (header->db_id));
+    memset(&header->unknown6, 0, sizeof (header->unknown6));
+    memset(&header->hash58, 0, sizeof (header->hash58));
+
+    checksum = itdb_compute_hash (fwid, itdb_data, itdb_len, &len);
+    if (checksum == NULL) {
+       g_set_error (error, 0, -1, "Failed to compute checksum");
+       return FALSE;
+    }
+    g_assert (len <= sizeof (header->hash58));
+    memcpy (&header->hash58, checksum, len);
+    g_free (checksum);
+
+    memcpy (&header->db_id, backup18, sizeof (backup18));
+    memcpy (&header->unknown6, backup32, sizeof (backup32));
+
+    return TRUE;
+}
+
+G_GNUC_INTERNAL gboolean itdb_device_write_checksum (Itdb_Device *device, 
+                                                    unsigned char *itdb_data, 
+                                                    gsize itdb_len,
+                                                    GError **error)
+{
+    switch (itdb_device_get_checksum_type (device)) {
+       case ITDB_CHECKSUM_NONE:
+           return TRUE;
+       case ITDB_CHECKSUM_HASH58:
+           return itdb_device_write_hash58 (device, itdb_data, itdb_len, 
error);
+       case ITDB_CHECKSUM_HASH72:
+           g_set_error (error, 0, -1, "Unsupported checksum type");
+           return FALSE;
+    }  
+    g_assert_not_reached ();
+}
+
+
+G_GNUC_INTERNAL gboolean itdb_device_requires_checksum (Itdb_Device *device) 
+{
+       return (itdb_device_get_checksum_type (device) != ITDB_CHECKSUM_NONE);
+}
+
 #ifdef WIN32
 #include <windows.h>
 #else

Modified: libgpod/trunk/src/itdb_device.h
===================================================================
--- libgpod/trunk/src/itdb_device.h     2009-01-21 21:49:08 UTC (rev 2233)
+++ libgpod/trunk/src/itdb_device.h     2009-01-21 21:50:17 UTC (rev 2234)
@@ -74,6 +74,13 @@
     THUMB_FORMAT_EXPERIMENTAL_BE,
 };
 
+typedef enum _ItdbChecksumType ItdbChecksumType;
+enum _ItdbChecksumType {
+    ITDB_CHECKSUM_NONE         = 0,
+    ITDB_CHECKSUM_HASH58       = 1,
+    ITDB_CHECKSUM_HASH72       = 2
+};
+
 /**
  * Itdb_Device:
  * @mountpoint:         The mountpoint of the iPod
@@ -159,6 +166,12 @@
 G_GNUC_INTERNAL guint64 itdb_device_get_firewire_id (const Itdb_Device 
*device);
 G_GNUC_INTERNAL gboolean itdb_device_supports_sparse_artwork (const 
Itdb_Device *device);
 G_GNUC_INTERNAL gboolean itdb_device_get_storage_info (Itdb_Device *device, 
guint64 *capacity, guint64 *free);
+G_GNUC_INTERNAL ItdbChecksumType itdb_device_get_checksum_type (const 
Itdb_Device *device);
+G_GNUC_INTERNAL gboolean itdb_device_write_checksum (Itdb_Device *device,
+                                                    unsigned char *itdb_data,
+                                                    gsize itdb_len,
+                                                    GError **error);
+
 G_END_DECLS
 
 #endif

Modified: libgpod/trunk/src/itdb_itunesdb.c
===================================================================
--- libgpod/trunk/src/itdb_itunesdb.c   2009-01-21 21:49:08 UTC (rev 2233)
+++ libgpod/trunk/src/itdb_itunesdb.c   2009-01-21 21:50:17 UTC (rev 2234)
@@ -3500,8 +3500,7 @@
   put16lint (cts, 2);   /* always seems to be 2 */
   put16_n0  (cts, 7);  /* unknown */
   /* 0x30 */
-  put16lint (cts, 1);   /* ? but iPod Classic/fat Nanos won't display any song
-                        * if it's not 1 */
+  put16lint (cts, itdb_device_get_checksum_type (fexp->itdb->device));
   put16_n0  (cts, 10);  /* unknown */
   /* 0x46 */
   put16lint (cts, 0);   /* langauge */
@@ -5235,49 +5234,6 @@
     }
 }
 
-static gboolean write_db_checksum (FExport *fexp, GError **error)
-{
-    guint64 fwid;
-    guchar backup18[8];
-    guchar backup32[20];
-    unsigned char *itdb_data;
-    unsigned char *checksum;
-    gsize len;
-    
-    fwid = itdb_device_get_firewire_id (fexp->itdb->device);
-    if ((fwid == 0) && (itdb_device_requires_checksum (fexp->itdb->device))) {
-       g_set_error (error, 0, -1, "Couldn't find the iPod firewire ID");
-       return FALSE;
-    }
-
-    if (fexp->wcontents->pos < 0x6c) {
-       g_set_error (error, 0, -1, "iTunesDB file too small to write checksum");
-       return FALSE;
-    }
-    itdb_data = (unsigned char *)fexp->wcontents->contents;
-
-    memcpy (backup18, itdb_data+0x18, sizeof (backup18));
-    memcpy (backup32, itdb_data+0x32, sizeof (backup32));
-
-    /* Those fields must be zero'ed out for the sha1 calculation */
-    memset(itdb_data+0x18, 0, 8);
-    memset(itdb_data+0x32, 0, 20);
-    memset(itdb_data+0x58, 0, 20);
-
-    checksum = itdb_compute_hash (fwid, itdb_data, fexp->wcontents->pos, &len);
-    if (checksum == NULL) {
-       g_set_error (error, 0, -1, "Failed to compute checksum");
-       return FALSE;
-    }
-    memcpy (itdb_data+0x58, checksum, len);    
-    g_free (checksum);
-
-    memcpy (itdb_data+0x18, backup18, sizeof (backup18));
-    memcpy (itdb_data+0x32, backup32, sizeof (backup32));
-
-    return TRUE;
-}
-
 /**
  * itdb_write_file:
  * @itdb:       the #Itdb_iTunesDB to save
@@ -5344,7 +5300,10 @@
                    /* Set checksum (ipods require it starting from
                     * iPod Classic and fat Nanos)
                     */
-                   write_db_checksum (fexp, &fexp->error);
+                   itdb_device_write_checksum (itdb->device,
+                                               (unsigned char 
*)fexp->wcontents->contents,
+                                               fexp->wcontents->pos,
+                                               &fexp->error);
                }
            }
        }


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2

Reply via email to