commit dfddc8a7e7b48f390ddc65b3b08c960395358aa4
Author: Nikias Bassen <[email protected]>
Date: Mon Oct 4 01:56:52 2010 +0200
read genius_cuid (mhsd type 9) and also write it back
This new mhsd of type 9 is new since iOS4. It just holds the genius cuid
if genius is activated. Otherwise, this mhsd node is not written to the
iTunesCDB file. Also updates the genius_cuid field in the db_info sqlite
table if available.
src/itdb_itunesdb.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++-
src/itdb_private.h | 1 +
src/itdb_sqlite.c | 7 +++-
3 files changed, 98 insertions(+), 4 deletions(-)
---
diff --git a/src/itdb_itunesdb.c b/src/itdb_itunesdb.c
index bcb8767..921325c 100644
--- a/src/itdb_itunesdb.c
+++ b/src/itdb_itunesdb.c
@@ -1355,6 +1355,7 @@ void itdb_free (Itdb_iTunesDB *itdb)
itdb_device_free (itdb->device);
if (itdb->userdata && itdb->userdata_destroy)
(*itdb->userdata_destroy) (itdb->userdata);
+ g_free (itdb->priv->genius_cuid);
g_free (itdb->priv);
g_free (itdb);
}
@@ -3008,6 +3009,47 @@ static gboolean parse_playlists (FImport *fimp, glong
mhsd_seek)
return TRUE;
}
+static gboolean parse_genius_mhsd(FImport *fimp, glong mhsd_seek)
+{
+ FContents *cts;
+ guint32 hdrlen, mhsdlen;
+ gint32 len;
+ gchar *genius_cuid;
+
+ g_return_val_if_fail (fimp, FALSE);
+ g_return_val_if_fail (fimp->itdb, FALSE);
+ g_return_val_if_fail (fimp->fcontents, FALSE);
+ g_return_val_if_fail (fimp->fcontents->filename, FALSE);
+ g_return_val_if_fail (mhsd_seek >= 0, FALSE);
+
+ cts = fimp->fcontents;
+
+ g_return_val_if_fail (check_header_seek (cts, "mhsd", mhsd_seek),
+ FALSE);
+
+ hdrlen = get32lint (cts, mhsd_seek+4);
+ mhsdlen = get32lint (cts, mhsd_seek+8);
+
+ len = mhsdlen - hdrlen;
+ if (len < 0) {
+ return FALSE;
+ }
+
+ if (len != 32) {
+ g_warning(_("%s: Unexpected length %d for genius_cuid!\n"), __func__,
len);
+ }
+
+ genius_cuid = g_new0(gchar, len+1);
+ if (!seek_get_n_bytes (cts, genius_cuid, mhsd_seek+hdrlen, len)) {
+ g_free (genius_cuid);
+ return FALSE;
+ }
+
+ fimp->itdb->priv->genius_cuid = genius_cuid;
+
+ return TRUE;
+}
+
static gboolean looks_like_itunesdb (FImport *fimp)
{
FContents *cts;
@@ -3039,7 +3081,7 @@ static gboolean parse_fimp (FImport *fimp, gboolean
compressed)
{
glong seek=0;
FContents *cts;
- glong mhsd_1, mhsd_2, mhsd_3, mhsd_5;
+ glong mhsd_1, mhsd_2, mhsd_3, mhsd_5, mhsd_9;
g_return_val_if_fail (fimp, FALSE);
g_return_val_if_fail (fimp->itdb, FALSE);
@@ -3073,6 +3115,10 @@ static gboolean parse_fimp (FImport *fimp, gboolean
compressed)
mhsd_5 = find_mhsd (cts, 5);
CHECK_ERROR (fimp, FALSE);
+ /* read genius cuid mhsd */
+ mhsd_9 = find_mhsd (cts, 9);
+ CHECK_ERROR (fimp, FALSE);
+
fimp->itdb->version = get32lint (cts, seek+0x10);
CHECK_ERROR (fimp, FALSE);
fimp->itdb->id = get64lint (cts, seek+0x18);
@@ -3150,6 +3196,10 @@ static gboolean parse_fimp (FImport *fimp, gboolean
compressed)
parse_playlists (fimp, mhsd_5);
}
+ if (mhsd_9 != -1) {
+ parse_genius_mhsd (fimp, mhsd_9);
+ }
+
return TRUE;
}
@@ -5599,6 +5649,26 @@ static gboolean write_mhsd_type6 (FExport *fexp)
return TRUE;
}
+static gboolean write_genius_mhsd (FExport *fexp)
+{
+ gulong mhsd_seek;
+ WContents *cts;
+
+ g_return_val_if_fail (fexp, FALSE);
+ g_return_val_if_fail (fexp->itdb, FALSE);
+ g_return_val_if_fail (fexp->wcontents, FALSE);
+
+ if (!fexp->itdb->priv->genius_cuid) {
+ return TRUE;
+ }
+ cts = fexp->wcontents;
+ mhsd_seek = cts->pos; /* get position of mhsd header */
+ mk_mhsd (fexp, 9); /* write header */
+ put_string (cts, fexp->itdb->priv->genius_cuid);
+ fix_header (cts, mhsd_seek);
+ return TRUE;
+}
+
/* create a WContents structure */
static WContents *wcontents_new (const gchar *filename)
{
@@ -5850,6 +5920,7 @@ static gboolean itdb_write_file_internal (Itdb_iTunesDB
*itdb,
gulong mhbd_seek = 0;
WContents *cts;
gboolean result = TRUE;
+ guint32 num_mhsds;
g_return_val_if_fail (itdb, FALSE);
g_return_val_if_fail (itdb->device, FALSE);
@@ -5884,7 +5955,15 @@ static gboolean itdb_write_file_internal (Itdb_iTunesDB
*itdb,
}
#endif
- mk_mhbd (fexp, 7); /* seven mhsds */
+ /* default mhsd count */
+ num_mhsds = 7; /* seven mhsds */
+
+ /* if genius_cuid present, we have one more */
+ if (fexp->itdb->priv->genius_cuid) {
+ num_mhsds++;
+ }
+
+ mk_mhbd (fexp, num_mhsds);
/* write tracklist (mhsd type 1) */
if (!fexp->error && !write_mhsd_tracks (fexp)) {
@@ -5947,6 +6026,17 @@ static gboolean itdb_write_file_internal (Itdb_iTunesDB
*itdb,
goto err;
}
+ if (fexp->itdb->priv->genius_cuid) {
+ /* write genius cuid (mhsd type 9) */
+ if (!fexp->error && !write_genius_mhsd (fexp)) {
+ g_set_error (&fexp->error,
+ ITDB_FILE_ERROR,
+ ITDB_FILE_ERROR_ITDB_CORRUPT,
+ _("Error writing mhsd type 9"));
+ goto err;
+ }
+ }
+
fix_header (cts, mhbd_seek);
if (itdb_device_supports_compressed_itunesdb (itdb->device)) {
diff --git a/src/itdb_private.h b/src/itdb_private.h
index 7f78967..afc694e 100644
--- a/src/itdb_private.h
+++ b/src/itdb_private.h
@@ -198,6 +198,7 @@ struct _Itdb_iTunesDB_Private
gint16 unk_0xa4;
gint16 unk_0xa6;
gint16 unk_0xa8;
+ gchar *genius_cuid;
};
/* private data for Itdb_Track */
diff --git a/src/itdb_sqlite.c b/src/itdb_sqlite.c
index 5b8f216..a5a0738 100644
--- a/src/itdb_sqlite.c
+++ b/src/itdb_sqlite.c
@@ -894,8 +894,11 @@ static int mk_Library(Itdb_iTunesDB *itdb,
/* this is +0xA2 */
sqlite3_bind_int(stmt_db_info, ++idx, itdb->priv->subtitle_language);
/* genius cuid */
- /* TODO: unkown meaning, set to NULL */
- sqlite3_bind_null(stmt_db_info, ++idx);
+ if (itdb->priv->genius_cuid) {
+ sqlite3_bind_text(stmt_db_info, ++idx, itdb->priv->genius_cuid, -1,
SQLITE_STATIC);
+ } else {
+ sqlite3_bind_null(stmt_db_info, ++idx);
+ }
/* bib */
/* TODO: unkown meaning, set to NULL */
sqlite3_bind_null(stmt_db_info, ++idx);
------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and,
should the need arise, upgrade to a full multi-node Oracle RAC database
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2