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