From: <ny...@us...> - 2007-02-21 17:36:25
|
Revision: 383 http://svn.sourceforge.net/pmplib/?rev=383&view=rev Author: nyaochi Date: 2007-02-21 09:36:23 -0800 (Wed, 21 Feb 2007) Log Message: ----------- Incremental commit: free allocated memory blocks. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h trunk/pmplib/lib/pmp_ipod/pmp_ipod.c trunk/pmplib/lib/pmp_ipod/serialize.c trunk/pmplib/lib/pmp_ipod/serialize.h Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-21 15:56:22 UTC (rev 382) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-21 17:36:23 UTC (rev 383) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -45,7 +45,7 @@ void ipod_finish(ipod_t* ipod) { - + itunesdb_finish(ipod->itunesdb); } result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb) Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-02-21 15:56:22 UTC (rev 382) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-02-21 17:36:23 UTC (rev 383) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -38,6 +38,26 @@ #include "util.h" #include "itunesdb.h" + + +static void chunk_finish(itunesdb_chunk_t* chunk) +{ + free(chunk->data); + memset(chunk, 0, sizeof(*chunk)); +} + +static int mhbd_init(itunesdb_chunk_t* chunk, int dataonly) +{ + if (!dataonly) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhbd", 4); + chunk->size = sizeof(chunk_mhbd_t) + 12; + chunk->overall_size = chunk->size; + } + chunk->data = calloc(1, sizeof(chunk_mhbd_t)); + return chunk->data ? 0 : 1; +} + static int mhbd_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { chunk_mhbd_t* mhbd = (chunk_mhbd_t*)chunk->data; @@ -45,10 +65,10 @@ if (serialize_uint32le(sio, "unknown1", "%d", &mhbd->unknown1)) return 1; if (serialize_uint32le(sio, "version", "%d", &mhbd->version)) return 1; if (serialize_uint32le(sio, "num_children", "%d", &mhbd->num_children)) return 1; - if (serialize_uint64le(sio, "identifier", "%lX", &mhbd->identifier)) return 1; + if (serialize_uint64le(sio, "identifier", "%016llX", &mhbd->identifier)) return 1; if (serialize_uint16le(sio, "unkonwn2", "%d", &mhbd->unknown2)) return 1; if (serialize_uint16le(sio, "unkonwn3", "%d", &mhbd->unknown3)) return 1; - if (serialize_uint64le(sio, "unknown4", "%lX", &mhbd->unknown4)) return 1; + if (serialize_uint64le(sio, "unknown4", "%016llX", &mhbd->unknown4)) return 1; if (serialize_uint8_array(sio, "unknown5", "%02X ", mhbd->unknown5, sizeof(mhbd->unknown5))) return 1; if (serialize_uint8_array(sio, "language", "%c ", mhbd->language, sizeof(mhbd->language))) return 1; if (serialize_uint8_array(sio, "unknown6", "%02X ", mhbd->unknown6, sizeof(mhbd->unknown6))) return 1; @@ -56,6 +76,20 @@ return 0; } + + +static mhsd_init(itunesdb_chunk_t* chunk, int dataonly) +{ + if (!dataonly) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhsd", 4); + chunk->size = sizeof(chunk_mhsd_t) + 12; + chunk->overall_size = chunk->size; + } + chunk->data = calloc(1, sizeof(chunk_mhsd_t)); + return chunk->data ? 0 : 1; +} + static int mhsd_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { chunk_mhsd_t* mhsd = (chunk_mhsd_t*)chunk->data; @@ -66,6 +100,20 @@ return 0; } + + +static mhlt_init(itunesdb_chunk_t* chunk, int dataonly) +{ + if (!dataonly) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhlt", 4); + chunk->size = 0; /* stands for number of children for "mhlt" chunk. */ + chunk->overall_size = sizeof(chunk_mhlt_t) + 12; + } + chunk->data = calloc(1, sizeof(chunk_mhlt_t)); + return chunk->data ? 0 : 1; +} + static int mhlt_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { chunk_mhlt_t* mhlt = (chunk_mhlt_t*)chunk->data; @@ -75,6 +123,20 @@ return 0; } + + +static mhit_init(itunesdb_chunk_t* chunk, int dataonly) +{ + if (!dataonly) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhit", 4); + chunk->size = sizeof(chunk_mhit_t) + 12; + chunk->overall_size = chunk->size; + } + chunk->data = calloc(1, sizeof(chunk_mhit_t)); + return chunk->data ? 0 : 1; +} + static int mhit_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { chunk_mhit_t* mhit = (chunk_mhit_t*)chunk->data; @@ -108,7 +170,7 @@ if (serialize_uint32le(sio, "user_id", "%u", &mhit->user_id)) return 1; if (serialize_uint32le(sio, "date_added", "%u", &mhit->date_added)) return 1; if (serialize_uint32le(sio, "bookmark_time", "%u", &mhit->bookmark_time)) return 1; - if (serialize_uint64le(sio, "dbid", "%X", &mhit->dbid)) return 1; + if (serialize_uint64le(sio, "dbid", "%016llX", &mhit->dbid)) return 1; if (serialize_uint8(sio, "is_checked", "%u", &mhit->is_checked)) return 1; if (serialize_uint8(sio, "rating_itunes", "%u", &mhit->rating_itunes)) return 1; if (serialize_uint16le(sio, "bpm", "%u", &mhit->bpm)) return 1; @@ -128,14 +190,14 @@ if (serialize_uint8(sio, "skip_when_shuffling", "%u", &mhit->skip_when_shuffling)) return 1; if (serialize_uint8(sio, "remember_playback_position", "%u", &mhit->remember_playback_position)) return 1; if (serialize_uint8(sio, "flag4", "%u", &mhit->flag4)) return 1; - if (serialize_uint64le(sio, "dbid2", "%X", &mhit->dbid2)) return 1; + if (serialize_uint64le(sio, "dbid2", "%016llX", &mhit->dbid2)) return 1; if (serialize_uint8(sio, "has_lyrics", "%u", &mhit->has_lyrics)) return 1; if (serialize_uint8(sio, "is_movie", "%u", &mhit->is_movie)) return 1; if (serialize_uint8(sio, "is_played", "%u", &mhit->is_played)) return 1; if (serialize_uint8(sio, "unk17", "%u", &mhit->unk17)) return 1; if (serialize_uint32le(sio, "unk21", "%u", &mhit->unk21)) return 1; if (serialize_int32le(sio, "encoder_delay", "%d", &mhit->encoder_delay)) return 1; - if (serialize_uint64le(sio, "num_samples", "%u", &mhit->num_samples)) return 1; + if (serialize_uint64le(sio, "num_samples", "%llu", &mhit->num_samples)) return 1; if (serialize_uint32le(sio, "unk25", "%u", &mhit->unk25)) return 1; if (serialize_int32le(sio, "padding_samples", "%d", &mhit->padding_samples)) return 1; if (serialize_uint32le(sio, "unk27", "%u", &mhit->unk27)) return 1; @@ -157,6 +219,20 @@ return 0; } + + +static mhlp_init(itunesdb_chunk_t* chunk, int dataonly) +{ + if (!dataonly) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhlp", 4); + chunk->size = 0; /* stands for number of children for "mhlt" chunk. */ + chunk->overall_size = sizeof(chunk_mhlp_t) + 12; + } + chunk->data = calloc(1, sizeof(chunk_mhlp_t)); + return chunk->data ? 0 : 1; +} + static int mhlp_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { chunk_mhlp_t* mhlp = (chunk_mhlp_t*)chunk->data; @@ -166,6 +242,20 @@ return 0; } + + +static mhyp_init(itunesdb_chunk_t* chunk, int dataonly) +{ + if (dataonly) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhyp", 4); + chunk->size = sizeof(chunk_mhyp_t) + 12; + chunk->overall_size = chunk->size; + } + chunk->data = calloc(1, sizeof(chunk_mhyp_t)); + return chunk->data ? 0 : 1; +} + static int mhyp_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { chunk_mhyp_t* mhyp = (chunk_mhyp_t*)chunk->data; @@ -177,7 +267,7 @@ if (serialize_uint8(sio, "flag_unkonwn2", "%u", &mhyp->flag_unkonwn2)) return 1; if (serialize_uint8(sio, "flag_unkonwn3", "%u", &mhyp->flag_unkonwn3)) return 1; if (serialize_uint32le(sio, "timestamp", "%u", &mhyp->timestamp)) return 1; - if (serialize_uint64le(sio, "id", "%u", &mhyp->id)) return 1; + if (serialize_uint64le(sio, "id", "%016llX", &mhyp->id)) return 1; if (serialize_uint32le(sio, "unk3", "%u", &mhyp->unk3)) return 1; if (serialize_uint16le(sio, "unk4", "%u", &mhyp->unk4)) return 1; if (serialize_uint16le(sio, "flag_podcast", "%u", &mhyp->flag_podcast)) return 1; @@ -187,6 +277,20 @@ return 0; } + + +static mhip_init(itunesdb_chunk_t* chunk, int dataonly) +{ + if (!dataonly) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhip", 4); + chunk->size = sizeof(chunk_mhip_t) + 12; + chunk->overall_size = chunk->size; + } + chunk->data = calloc(1, sizeof(chunk_mhip_t)); + return chunk->data ? 0 : 1; +} + static int mhip_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { chunk_mhip_t* mhyp = (chunk_mhip_t*)chunk->data; @@ -201,12 +305,20 @@ return 0; } + + +static void mhod_string_finish(itunesdb_chunk_t* chunk) +{ + chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + chunk_mhod_string_t* string = &mhod->data.str; + ucs2free(string->value); + memset(string, 0, sizeof(*string)); +} + static int mhod_string_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio) { chunk_mhod_string_t* string = &((chunk_mhod_t*)chunk->data)->data.str; - if (serialize_uint32le(sio, "unk1", "%u", &string->unk1)) return 1; - if (serialize_uint32le(sio, "unk2", "%u", &string->unk2)) return 1; if (serialize_uint32le(sio, "position", "%u", &string->position)) return 1; if (serialize_uint32le(sio, "size", "%u", &string->size)) return 1; if (serialize_uint32le(sio, "unknown", "%u", &string->unknown)) return 1; @@ -216,26 +328,38 @@ return 0; } +static void mhod_url_finish(itunesdb_chunk_t* chunk) +{ + chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + chunk_mhod_url_t* url = &mhod->data.url; + ucs2free(url->value); + memset(url, 0, sizeof(*url)); +} + static int mhod_url_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio) { chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; chunk_mhod_url_t* url = &mhod->data.url; - if (serialize_uint32le(sio, "unk1", "%u", &url->unk1)) return 1; - if (serialize_uint32le(sio, "unk2", "%u", &url->unk2)) return 1; - if (serialize_utf8str_fixed(sio, name, "%s", &url->value, chunk->data_size - chunk->chunk_size)) return 1; + if (serialize_utf8str_fixed(sio, name, "%s", &url->value, chunk->size - chunk->overall_size)) return 1; return 0; } +static void mhod_index_finish(itunesdb_chunk_t* chunk) +{ + chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + chunk_mhod_index_t* index = &mhod->data.index; + ucs2free(index->entries); + memset(index, 0, sizeof(*index)); +} + static int mhod_index_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio) { uint32_t i; chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; chunk_mhod_index_t* index = &mhod->data.index; - if (serialize_uint32le(sio, "unk1", "%u", &index->unk1)) return 1; - if (serialize_uint32le(sio, "unk2", "%u", &index->unk2)) return 1; if (serialize_uint32le(sio, "type", "%u", &index->type)) return 1; if (serialize_uint32le(sio, "num_entries", "%u", &index->num_entries)) return 1; if (serialize_uint8_array(sio, "padding", "%02X ", index->padding, sizeof(index->padding))) return 1; @@ -257,16 +381,22 @@ return 0; } +static void mhod_playlist_column_finish(itunesdb_chunk_t* chunk) +{ + chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + chunk_mhod_playlist_column_t* pc = &mhod->data.pc; + ucs2free(pc->columns); + memset(pc, 0, sizeof(*pc)); +} + static int mhod_playlist_column_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio) { uint32_t i; chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; chunk_mhod_playlist_column_t* pc = &mhod->data.pc; - if (serialize_uint32le(sio, "unk1", "%u", &pc->unk1)) return 1; - if (serialize_uint32le(sio, "unk2", "%u", &pc->unk2)) return 1; if (serialize_uint32le(sio, "unk3", "%u", &pc->unk3)) return 1; - if (serialize_uint64le(sio, "unk4", "%u", &pc->unk4)) return 1; + if (serialize_uint64le(sio, "unk4", "%016llX", &pc->unk4)) return 1; if (serialize_uint32le(sio, "unk8", "%u", &pc->unk8)) return 1; if (serialize_uint16le(sio, "unk9", "%u", &pc->unk9)) return 1; if (serialize_uint16le(sio, "unk10", "%u", &pc->unk10)) return 1; @@ -294,19 +424,24 @@ sprintf(fieldname, "columns[%d].sort_direction", i); if (serialize_uint32le(sio, fieldname, "%u", &def->sort_direction)) return 1; sprintf(fieldname, "columns[%d].padding", i); - if (serialize_uint64le(sio, fieldname, "%u", &def->padding)) return 1; + if (serialize_uint64le(sio, fieldname, "%016llX", &def->padding)) return 1; } return 0; } +static void mhod_playlist_order_finish(itunesdb_chunk_t* chunk) +{ + chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + chunk_mhod_playlist_order_t* po = &mhod->data.po; + memset(po, 0, sizeof(*po)); +} + static int mhod_playlist_order_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio) { chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; chunk_mhod_playlist_order_t* po = &mhod->data.po; - if (serialize_uint32le(sio, "unk1", "%u", &po->unk1)) return 1; - if (serialize_uint32le(sio, "unk2", "%u", &po->unk2)) return 1; if (serialize_uint32le(sio, "position", "%u", &po->position)) return 1; if (serialize_uint8_array(sio, "padding", "%02X ", po->padding, sizeof(po->padding))) return 1; @@ -316,23 +451,23 @@ static const itunesdb_mhoddecl_t* find_mhoddecl(itunesdb_chunk_t* chunk) { static const itunesdb_mhoddecl_t mds[] = { - {1, "title", 0, mhod_string_serialize}, - {2, "location", 0, mhod_string_serialize}, - {3, "album", 0, mhod_string_serialize}, - {4, "artist", 0, mhod_string_serialize}, - {5, "genre", 0, mhod_string_serialize}, - {6, "filetype", 0, mhod_string_serialize}, - {7, "EQ setting", 0, mhod_string_serialize}, - {8, "comment", 0, mhod_string_serialize}, - {9, "category", 0, mhod_string_serialize}, - {12, "composer", 0, mhod_string_serialize}, - {13, "grouping", 0, mhod_string_serialize}, - {14, "description", 0, mhod_string_serialize}, - {15, "podcast_enclosure_url", 0, mhod_url_serialize}, - {16, "podcast_rss_url", 0, mhod_url_serialize}, - {52, "index", 0, mhod_index_serialize}, - {100, "playlist_column", 0x288, mhod_playlist_column_serialize}, - {100, "playlist_order", 0x2C, mhod_playlist_order_serialize}, + {1, "title", 0, mhod_string_finish, mhod_string_serialize}, + {2, "location", 0, mhod_string_finish, mhod_string_serialize}, + {3, "album", 0, mhod_string_finish, mhod_string_serialize}, + {4, "artist", 0, mhod_string_finish, mhod_string_serialize}, + {5, "genre", 0, mhod_string_finish, mhod_string_serialize}, + {6, "filetype", 0, mhod_string_finish, mhod_string_serialize}, + {7, "EQ setting", 0, mhod_string_finish, mhod_string_serialize}, + {8, "comment", 0, mhod_string_finish, mhod_string_serialize}, + {9, "category", 0, mhod_string_finish, mhod_string_serialize}, + {12, "composer", 0, mhod_string_finish, mhod_string_serialize}, + {13, "grouping", 0, mhod_string_finish, mhod_string_serialize}, + {14, "description", 0, mhod_string_finish, mhod_string_serialize}, + {15, "podcast_enclosure_url", 0, mhod_url_finish, mhod_url_serialize}, + {16, "podcast_rss_url", 0, mhod_url_finish, mhod_url_serialize}, + {52, "index", 0, mhod_index_finish, mhod_index_serialize}, + {100, "playlist_column", 0x288, mhod_playlist_column_finish, mhod_playlist_column_serialize}, + {100, "playlist_order", 0x2C, mhod_playlist_order_finish, mhod_playlist_order_serialize}, {0, NULL, 0, NULL}, }; const itunesdb_mhoddecl_t* decl = mds; @@ -340,7 +475,7 @@ while (decl->name) { if (decl->type == mhod->type) { - if (decl->chunk_size == 0 || decl->chunk_size == chunk->chunk_size) { + if (decl->overall_size == 0 || decl->overall_size == chunk->overall_size) { return decl; } } @@ -349,12 +484,36 @@ return NULL; } +static int mhod_init(itunesdb_chunk_t* chunk, int dataonly) +{ + if (!dataonly) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhod", 4); + chunk->size = 0x18; + chunk->overall_size = chunk->size; + } + chunk->data = calloc(1, sizeof(chunk_mhod_t)); + return chunk->data ? 0 : 1; +} + +static void mhod_finish(itunesdb_chunk_t* chunk) +{ + chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + const itunesdb_mhoddecl_t* decl = NULL; + decl = find_mhoddecl(chunk); + if (decl) { + decl->finish(chunk); + } +} + static int mhod_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; const itunesdb_mhoddecl_t* decl = NULL; if (serialize_uint32le(sio, "type", "%u", &mhod->type)) return 1; + if (serialize_uint32le(sio, "unk1", "%u", &mhod->unk1)) return 1; + if (serialize_uint32le(sio, "unk2", "%u", &mhod->unk2)) return 1; decl = find_mhoddecl(chunk); if (decl) { @@ -373,15 +532,15 @@ static const itunesdb_chunkdecl_t* find_chunkdecl(itunesdb_chunk_t* chunk) { static const itunesdb_chunkdecl_t cds[] = { - {"mhbd", sizeof(chunk_mhbd_t), mhbd_serialize}, - {"mhsd", sizeof(chunk_mhsd_t), mhsd_serialize}, - {"mhlt", sizeof(chunk_mhlt_t), mhlt_serialize}, - {"mhit", sizeof(chunk_mhit_t), mhit_serialize}, - {"mhlp", sizeof(chunk_mhlp_t), mhlp_serialize}, - {"mhyp", sizeof(chunk_mhyp_t), mhyp_serialize}, - {"mhip", sizeof(chunk_mhip_t), mhip_serialize}, - {"mhod", sizeof(chunk_mhod_t), mhod_serialize}, - {NULL, 0, NULL}, + {"mhbd", mhbd_init, chunk_finish, mhbd_serialize}, + {"mhsd", mhsd_init, chunk_finish, mhsd_serialize}, + {"mhlt", mhlt_init, chunk_finish, mhlt_serialize}, + {"mhit", mhit_init, chunk_finish, mhit_serialize}, + {"mhlp", mhlp_init, chunk_finish, mhlp_serialize}, + {"mhyp", mhyp_init, chunk_finish, mhyp_serialize}, + {"mhip", mhip_init, chunk_finish, mhip_serialize}, + {"mhod", mhod_init, mhod_finish, mhod_serialize}, + {NULL, NULL, NULL, NULL}, }; const itunesdb_chunkdecl_t* decl = cds; @@ -394,6 +553,21 @@ return NULL; } +void itunesdb_finish(itunesdb_chunk_t* chunk) +{ + uint32_t i; + const itunesdb_chunkdecl_t* decl = NULL; + + for (i = 0;i < chunk->num_children;++i) { + itunesdb_finish(&chunk->childlen[i]); + } + + decl = find_chunkdecl(chunk); + if (decl) { + decl->finish(chunk); + } +} + int itunesdb_repr(itunesdb_chunk_t* chunk, size_t index, serializer_t* sio) { uint32_t i; @@ -409,9 +583,9 @@ serialize_indent(sio); fprintf(sio->fp, "offset: %08X\n", chunk->offset); serialize_indent(sio); - fprintf(sio->fp, "data_size: %d\n", chunk->data_size); + fprintf(sio->fp, "size: %d\n", chunk->size); serialize_indent(sio); - fprintf(sio->fp, "chunk_size: %d\n", chunk->chunk_size); + fprintf(sio->fp, "overall_size: %d\n", chunk->overall_size); /* Show fields in the chunk data */ decl = find_chunkdecl(chunk); @@ -449,26 +623,25 @@ /* Read the chunk ID and header information */ chunk->offset = begin; if (serialize_uint8_array(sio, "id", "%c ", chunk->id, sizeof(chunk->id))) return 1; - if (serialize_uint32le(sio, "data_size", "%d", &chunk->data_size)) return 1; - if (serialize_uint32le(sio, "chunk_size", "%d", &chunk->chunk_size)) return 1; + if (serialize_uint32le(sio, "size", "%d", &chunk->size)) return 1; + if (serialize_uint32le(sio, "overall_size", "%d", &chunk->overall_size)) return 1; /* Read the chunk data if this chunk is 'known' */ decl = find_chunkdecl(chunk); if (decl) { - chunk->data = calloc(1, decl->data_size); - if (chunk->data) { + if (decl->init(chunk, 1) == 0) { if (decl->serialize(chunk, sio)) return 1; } } if (strncmp(chunk->id, "mhod", 4) == 0) { - uint32_t next = begin + chunk->chunk_size; + uint32_t next = begin + chunk->overall_size; if (next < serialize_tell(sio)) { fprintf(stderr, "WARNING: backward seeking.\n"); } serialize_seek(sio, next); } else { - uint32_t next = begin + chunk->data_size; + uint32_t next = begin + chunk->size; if (next < serialize_tell(sio)) { fprintf(stderr, "WARNING: backward seeking.\n"); } @@ -477,17 +650,17 @@ /* Read children for this chunk. */ if (strncmp(chunk->id, "mhlt", 4) == 0 || strncmp(chunk->id, "mhlp", 4) == 0) { - /* chunk->chunk_size represents the number of children for "mhlt" and "mhlp" chunks */ - chunk->num_children = chunk->chunk_size; + /* chunk->overall_size represents the number of children for "mhlt" and "mhlp" chunks */ + chunk->num_children = chunk->overall_size; chunk->childlen = (itunesdb_chunk_t*)calloc(chunk->num_children, sizeof(itunesdb_chunk_t)); for (i = 0;i < chunk->num_children;++i) { itunesdb_read(&chunk->childlen[i], sio); } } else { - /* chunk->chunk_size represents the size in bytes of this chunk */ + /* chunk->overall_size represents the size in bytes of this chunk */ chunk->num_children = 0; chunk->childlen = NULL; - while (sio->offset - begin < chunk->chunk_size) { + while (sio->offset - begin < chunk->overall_size) { chunk->num_children; chunk->childlen = realloc(chunk->childlen, sizeof(itunesdb_chunk_t) * (chunk->num_children + 1)); memset(&chunk->childlen[chunk->num_children], 0, sizeof(itunesdb_chunk_t)); @@ -498,29 +671,3 @@ return 0; } - -#if 0 -int main(int argc, char *argv[]) -{ - FILE *fp = fopen("C:\\pmplib\\ipod_nano\\iPod_Control\\iTunes\\iTunesDB", "rb"); - if (fp) { - serializer_t sio; - uint8_t* buffer = NULL; - long size = 0; - itunesdb_chunk_t root; - - fread_all(fp, &buffer, &size); - fclose(fp); - - serialize_init_read(&sio, buffer, (size_t)size); - chunk_read(&root, &sio); - serialize_finish(&sio); - - serialize_init_dump(&sio, stdout, 2); - chunk_repr(&root, 0, &sio); - serialize_finish(&sio); - } - - return 0; -} -#endif \ No newline at end of file Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-02-21 15:56:22 UTC (rev 382) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-02-21 17:36:23 UTC (rev 383) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifndef __ITUNESDB_H__ #define __ITUNESDB_H__ @@ -153,8 +153,6 @@ } chunk_mhip_t; typedef struct { - uint32_t unk1; - uint32_t unk2; uint32_t position; uint32_t size; uint32_t unknown; @@ -163,14 +161,10 @@ } chunk_mhod_string_t; typedef struct { - uint32_t unk1; - uint32_t unk2; char* value; } chunk_mhod_url_t; typedef struct { - uint32_t unk1; - uint32_t unk2; uint32_t type; uint32_t num_entries; uint8_t padding[40]; @@ -199,14 +193,14 @@ } chunk_mhod_playlist_column_t; typedef struct { - uint32_t unk1; - uint32_t unk2; uint32_t position; uint8_t padding[16]; } chunk_mhod_playlist_order_t; typedef struct { uint32_t type; + uint32_t unk1; + uint32_t unk2; union { chunk_mhod_string_t str; chunk_mhod_url_t url; @@ -219,8 +213,8 @@ struct tag_itunesdb_chunk { int8_t id[4]; - uint32_t data_size; - uint32_t chunk_size; + uint32_t size; + uint32_t overall_size; void* data; uint32_t num_children; /* This field does not exist in iTunesDB. */ @@ -231,17 +225,20 @@ typedef struct { uint32_t type; const char* name; - size_t chunk_size; + size_t overall_size; + void (*finish)(itunesdb_chunk_t* chunk); int (*serialize)(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio); } itunesdb_mhoddecl_t; typedef struct { const char* name; - size_t data_size; + int (*init)(itunesdb_chunk_t* chunk, int dataonly); + void (*finish)(itunesdb_chunk_t* chunk); int (*serialize)(itunesdb_chunk_t* chunk, serializer_t* sio); } itunesdb_chunkdecl_t; -int itunesdb_repr(itunesdb_chunk_t* chunk, size_t index, serializer_t* sio); -int itunesdb_read(itunesdb_chunk_t* chunk, serializer_t* sio); +void itunesdb_finish(itunesdb_chunk_t* mhbd); +int itunesdb_repr(itunesdb_chunk_t* mhbd, size_t index, serializer_t* sio); +int itunesdb_read(itunesdb_chunk_t* mhbd, serializer_t* sio); #endif/*__ITUNESDB_H__*/ Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-21 15:56:22 UTC (rev 382) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-21 17:36:23 UTC (rev 383) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -63,7 +63,7 @@ static const ipod_descriptor_t g_model_descriptions[] = { { - "ipod", "Apple", "iPod", "UM", + "apple_ipod", "Apple", "iPod", "UM", "---", "---", "iPod_Control\\iTunes\\iTunesDB", ".mp3\0", Modified: trunk/pmplib/lib/pmp_ipod/serialize.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/serialize.c 2007-02-21 15:56:22 UTC (rev 382) +++ trunk/pmplib/lib/pmp_ipod/serialize.c 2007-02-21 17:36:23 UTC (rev 383) @@ -251,7 +251,7 @@ serialize_uint8(sio, name, format, (uint8_t*)&str[i]); } } else if (sio->mode < 0) { - char* str = calloc(size+1, sizeof(char)); + char* str = (char*)ucs2calloc(sizeof(char) * (size+1)); for (i = 0;i < size;++i) { serialize_uint8(sio, name, format, (uint8_t*)&str[i]); } @@ -276,7 +276,7 @@ return 0; } -uint32_t serialize_tell(serializer_t* sio) +size_t serialize_tell(serializer_t* sio) { return sio->offset; } Modified: trunk/pmplib/lib/pmp_ipod/serialize.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/serialize.h 2007-02-21 15:56:22 UTC (rev 382) +++ trunk/pmplib/lib/pmp_ipod/serialize.h 2007-02-21 17:36:23 UTC (rev 383) @@ -54,7 +54,7 @@ int serialize_utf8str_fixed(serializer_t* sio, const char *name, const char *format, char** value, size_t size); int serialize_seek(serializer_t* sio, size_t offset); -uint32_t serialize_tell(serializer_t* sio); +size_t serialize_tell(serializer_t* sio); void serialize_indent(serializer_t* sio); void serialize_indent_ascend(serializer_t* sio); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-02-22 16:17:50
|
Revision: 384 http://svn.sourceforge.net/pmplib/?rev=384&view=rev Author: nyaochi Date: 2007-02-22 08:08:29 -0800 (Thu, 22 Feb 2007) Log Message: ----------- Incremental commit. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/ipod.h trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h trunk/pmplib/lib/pmp_ipod/pmp_ipod.c Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-21 17:36:23 UTC (rev 383) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-22 16:08:29 UTC (rev 384) @@ -1,5 +1,5 @@ /* - * iPod + * iPod Manupulation library. * * Copyright (c) 2005-2007 Naoaki Okazaki * @@ -32,12 +32,61 @@ #include <string.h> #endif/*HAVE_STRING_H*/ #include <pmplib/ucs2char.h> +#include <pmplib/pmp.h> #include "serialize.h" #include "util.h" #include "ipod.h" #include "itunesdb.h" +#define COMP(a, b) ((a)>(b))-((a)<(b)) + +static const ipod_descriptor_t g_model_descriptions[] = { + { + "apple_ipod", "Apple", "iPod", "UM", + "---", "---", + "iPod_Control\\iTunes\\iTunesDB", + ".mp3\0", + {PMPCODEC_MPEGLAYER3, 0, 0, 0, 0, 0, 0, 0}, + "iPod_Control", "iPod_Control\\Music", "Playlists", + }, + { + NULL, NULL, NULL, NULL, + NULL, NULL, + NULL, + NULL, + {0, 0, 0, 0, 0, 0, 0, 0}, + NULL, NULL, NULL, + }, +}; + +const ipod_descriptor_t* ipod_detect(const ucs2char_t* path_to_device, const char *id) +{ + const ipod_descriptor_t* md = NULL; + + // Find a suitable model for the device. + md = g_model_descriptions; + for (;md->id;++md) { + if (id && *id) { + // Match the device identifier. + if (strcmp(md->id, id) == 0) { + break; + } + } + } + return md->id ? md : NULL; +} + +const ipod_descriptor_t* ipod_next_descriptor(const ipod_descriptor_t* md) +{ + if (md) { + ++md; + return md->id ? md : NULL; + } else { + return g_model_descriptions; + } +} + void ipod_init(ipod_t* ipod) { ipod->itunesdb = calloc(1, sizeof(itunesdb_chunk_t)); @@ -46,6 +95,7 @@ void ipod_finish(ipod_t* ipod) { itunesdb_finish(ipod->itunesdb); + free(ipod->itunesdb); } result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb) @@ -79,3 +129,332 @@ serialize_finish(&sio); return 0; } + +static int set_music_record(itunesdb_chunk_t* mhit, const pmp_music_record_t* rec, uint32_t uid) +{ + itunesdb_chunk_t* mhod = NULL; + chunk_mhit_t* mhit_data = (chunk_mhit_t*)mhit->data; + + mhit_data->uid = uid; + mhit_data->visible = 1; + mhit_data->filetype = 0x4D503320; + mhit_data->type1 = 0x01; + mhit_data->type2 = 0x01; + mhit_data->compilation = 0; + mhit_data->rating = 0; + mhit_data->last_modified = rec->ts_update; + mhit_data->filesize = rec->filesize; + mhit_data->duration = rec->duration * 1000; + mhit_data->track_number = rec->track_number; + mhit_data->total_tracks = 100; + mhit_data->year = 2000; + mhit_data->bitrate = rec->bitrate / 1000; + mhit_data->samplerate = rec->sample_rate; + mhit_data->date_added = rec->ts_import; + mhit_data->dbid = 0; + mhit_data->unk9 = 0xFFFF; + mhit_data->unk14_1 = 12; + mhit_data->is_played = 2; + mhit_data->unk27 = 1; + mhit_data->media_type = 1; + + /* Construct an "mhod" chunk for title. */ + if (rec->title && *rec->title) { + mhod = itunesdb_new_child(mhit); + if (mhod) { + itunesdb_init(mhod, "mhod", "title"); + itunesdb_set_mhod_string(mhod, rec->title); + } + } + + /* Construct an "mhod" chunk for artist. */ + if (rec->artist && *rec->artist) { + mhod = itunesdb_new_child(mhit); + if (mhod) { + itunesdb_init(mhod, "mhod", "artist"); + itunesdb_set_mhod_string(mhod, rec->artist); + } + } + + /* Construct an "mhod" chunk for album. */ + if (rec->album && *rec->album) { + mhod = itunesdb_new_child(mhit); + if (mhod) { + itunesdb_init(mhod, "mhod", "album"); + itunesdb_set_mhod_string(mhod, rec->album); + } + } + + /* Construct an "mhod" chunk for filetype. */ + mhod = itunesdb_new_child(mhit); + if (mhod) { + itunesdb_init(mhod, "mhod", "filetype"); + itunesdb_set_mhod_string(mhod, L"MPEG Audio file"); + } + + /* Construct an "mhod" chunk for comment. */ + mhod = itunesdb_new_child(mhit); + if (mhod) { + itunesdb_init(mhod, "mhod", "comment"); + itunesdb_set_mhod_string(mhod, L"Some comment"); + } + + /* Construct an "mhod" chunk for location. */ + if (rec->filename && *rec->filename) { + mhod = itunesdb_new_child(mhit); + if (mhod) { + ucs2char_t pathname[MAX_PATH], *p = NULL; + itunesdb_init(mhod, "mhod", "location"); + ucs2cpy(pathname, rec->filename); + for (p = pathname;*p;++p) { + if (*p == PATHCHAR) *p = ':'; + } + itunesdb_set_mhod_string(mhod, pathname); + } + } + + mhit_data->num_children = mhit->num_children; + return 0; +} + +static int comp_title(const void *_x, const void *_y) +{ + const sorted_index_t *xi = (const sorted_index_t*)_x; + const sorted_index_t *yi = (const sorted_index_t*)_y; + const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; + const pmp_music_record_t* x = &base[xi->index]; + const pmp_music_record_t* y = &base[yi->index]; + + return ucs2cmp(x->title, y->title); +} + +static int comp_album(const void *_x, const void *_y) +{ + int ret = 0; + const sorted_index_t *xi = (const sorted_index_t*)_x; + const sorted_index_t *yi = (const sorted_index_t*)_y; + const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; + const pmp_music_record_t* x = &base[xi->index]; + const pmp_music_record_t* y = &base[yi->index]; + + ret = ucs2cmp(x->album, y->album); + if (ret == 0) { + ret = COMP(x->track_number, y->track_number); + if (ret == 0) { + return ucs2cmp(x->title, y->title); + } + } + return ret; +} + +static int comp_artist(const void *_x, const void *_y) +{ + int ret = 0; + const sorted_index_t *xi = (const sorted_index_t*)_x; + const sorted_index_t *yi = (const sorted_index_t*)_y; + const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; + const pmp_music_record_t* x = &base[xi->index]; + const pmp_music_record_t* y = &base[yi->index]; + + ret = ucs2cmp(x->artist, y->artist); + if (ret == 0) { + return comp_album(_x, _y); + } + return ret; +} + +static int comp_genre(const void *_x, const void *_y) +{ + int ret = 0; + const sorted_index_t *xi = (const sorted_index_t*)_x; + const sorted_index_t *yi = (const sorted_index_t*)_y; + const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; + const pmp_music_record_t* x = &base[xi->index]; + const pmp_music_record_t* y = &base[yi->index]; + + ret = ucs2cmp(x->genre, y->genre); + if (ret == 0) { + return comp_artist(_x, _y); + } + return ret; +} + +static int comp_composer(const void *_x, const void *_y) +{ + int ret = 0; + const sorted_index_t *xi = (const sorted_index_t*)_x; + const sorted_index_t *yi = (const sorted_index_t*)_y; + const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; + const pmp_music_record_t* x = &base[xi->index]; + const pmp_music_record_t* y = &base[yi->index]; + + ret = ucs2cmp(x->composer, y->composer); + if (ret == 0) { + return ucs2cmp(x->title, y->title); + } + return ret; +} + +static int set_master_playlist(itunesdb_chunk_t* mhyp, const pmp_music_record_t* records, int num_records) +{ + int i; + itunesdb_chunk_t *mhod = NULL, *mhip = NULL; + chunk_mhyp_t* mhyp_data = (chunk_mhyp_t*)mhyp->data; + sorted_index_t* si = (sorted_index_t*)calloc(num_records, sizeof(sorted_index_t)); + + if (!si) { + return 1; + } else { + for (i = 0;i < num_records;++i) { + si[i].base = records; + si[i].index = i; + } + } + + mhyp_data->flag_master = 1; + mhyp_data->id = 0x7520EA5FA870F9EA; + mhyp_data->unk3 = 0; + mhyp_data->unk4 = 1; + mhyp_data->sort_order = 1; + + /* Construct an "mhod" chunk for title. */ + mhod = itunesdb_new_child(mhyp); + if (mhod) { + itunesdb_init(mhod, "mhod", "title"); + itunesdb_set_mhod_string(mhod, L"Nyaopod"); + } + + /* Construct an "mhod" chunk for title index. */ + mhod = itunesdb_new_child(mhyp); + if (mhod) { + itunesdb_init(mhod, "mhod", "index"); + qsort(si, num_records, sizeof(si[0]), comp_title); + itunesdb_set_mhod_index(mhod, 0x03, si, num_records); + } + + /* Construct an "mhod" chunk for album index. */ + mhod = itunesdb_new_child(mhyp); + if (mhod) { + itunesdb_init(mhod, "mhod", "index"); + qsort(si, num_records, sizeof(si[0]), comp_album); + itunesdb_set_mhod_index(mhod, 0x04, si, num_records); + } + + /* Construct an "mhod" chunk for artist index. */ + mhod = itunesdb_new_child(mhyp); + if (mhod) { + itunesdb_init(mhod, "mhod", "index"); + qsort(si, num_records, sizeof(si[0]), comp_artist); + itunesdb_set_mhod_index(mhod, 0x05, si, num_records); + } + + /* Construct an "mhod" chunk for genre index. */ + mhod = itunesdb_new_child(mhyp); + if (mhod) { + itunesdb_init(mhod, "mhod", "index"); + qsort(si, num_records, sizeof(si[0]), comp_genre); + itunesdb_set_mhod_index(mhod, 0x06, si, num_records); + } + + /* Construct an "mhod" chunk for composer index. */ + mhod = itunesdb_new_child(mhyp); + if (mhod) { + itunesdb_init(mhod, "mhod", "index"); + qsort(si, num_records, sizeof(si[0]), comp_composer); + itunesdb_set_mhod_index(mhod, 0x12, si, num_records); + } + + /* End of the series of "mhod" chunks. */ + mhyp_data->num_mhod = mhyp->num_children; + + /* */ + for (i = 0;i < num_records;++i) { + mhip = itunesdb_new_child(mhyp); + if (mhip) { + chunk_mhip_t* mhip_data = NULL; + itunesdb_init(mhip, "mhip", NULL); + mhip_data = (chunk_mhip_t*)mhip->data; + + mhip_data->flag_podcast_group = 0; + mhip_data->track_id = i; + mhip_data->group_id = i + num_records; + + mhod = itunesdb_new_child(mhip); + if (mhod) { + itunesdb_init(mhod, "mhod", "playlist_order"); + itunesdb_set_mhod_playlist_order(mhod, i+1); + } + + mhip_data->num_mhod = mhip->num_children; + } + } + + mhyp_data->num_mhip = mhyp->num_children - mhyp_data->num_mhod; + return 0; +} + +result_t ipod_set(ipod_t* ipod, const pmp_music_record_t* records, int num_records, const pmp_playlist_t* playlists, int num_playlists) +{ + int i; + itunesdb_chunk_t mhbd, *mhsd = NULL; + itunesdb_chunk_t *mhlt = NULL, *mhit = NULL; + itunesdb_chunk_t *mhlp = NULL, *mhyp = NULL; + + /* Construct "mhbd" chunk. */ + itunesdb_init(&mhbd, "mhbd", NULL); + + /* Construct "mhsd" chunk with track type. */ + mhsd = itunesdb_new_child(&mhbd); + if (mhsd) { + chunk_mhsd_t* mhsd_data = NULL; + itunesdb_init(mhsd, "mhsd", NULL); + mhsd_data = (chunk_mhsd_t*)mhsd->data; + mhsd_data->type = 1; /* track type. */ + + /* Construct "mhlt" chunk. */ + mhlt = itunesdb_new_child(mhsd); + if (mhlt) { + itunesdb_init(mhlt, "mhlt", NULL); + mhlt->num_children = num_records; + + /* For all records... */ + for (i = 0;i < num_records;++i) { + const pmp_music_record_t* rec = &records[i]; + + /* Construct "mhit" chunk. */ + mhit = itunesdb_new_child(mhlt); + if (mhit) { + itunesdb_init(mhit, "mhit", NULL); + + /* This will fill "mhit" chunk and create "mhod" chunks. */ + set_music_record(mhit, rec, i); + } + } + } + } + + /* Construct "mhsd" chunk with playlist type. */ + mhsd = itunesdb_new_child(&mhbd); + if (mhsd) { + chunk_mhsd_t* mhsd_data = NULL; + itunesdb_init(mhsd, "mhsd", NULL); + mhsd_data = (chunk_mhsd_t*)mhsd->data; + mhsd_data->type = 2; /* playlist type. */ + + /* Construct "mhlp" chunk. */ + mhlp = itunesdb_new_child(mhsd); + if (mhlp) { + itunesdb_init(mhlp, "mhlp", NULL); + mhlp->num_children = 1; + + mhyp = itunesdb_new_child(mhlp); + if (mhyp) { + chunk_mhyp_t* mhyp_data = NULL; + itunesdb_init(mhyp, "mhyp", NULL); + mhyp_data = (chunk_mhyp_t*)mhyp->data; + + set_master_playlist(mhyp, records, num_records); + } + } + } +} Modified: trunk/pmplib/lib/pmp_ipod/ipod.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.h 2007-02-21 17:36:23 UTC (rev 383) +++ trunk/pmplib/lib/pmp_ipod/ipod.h 2007-02-22 16:08:29 UTC (rev 384) @@ -1,6 +1,44 @@ +/* + * iPod Manupulation library. + * + * Copyright (c) 2005-2007 Naoaki Okazaki + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* $Id$ */ + #ifndef __IPOD_H__ #define __IPOD_H__ +typedef struct { + const char *id; + const char *manufacturer; + const char *name; + const char *mode; + const char *min_version; + const char *max_version; + const char *itunesdb_filename; + const char *extensions; + uint32_t codecs[8]; + const char *path_to_system; + const char *path_to_music; + const char *path_to_playlist; +} ipod_descriptor_t; + struct tag_itunesdb_chunk; typedef struct tag_itunesdb_chunk itunesdb_chunk_t; @@ -8,6 +46,9 @@ itunesdb_chunk_t* itunesdb; } ipod_t; +const ipod_descriptor_t* ipod_detect(const ucs2char_t* path_to_device, const char *id); +const ipod_descriptor_t* ipod_next_descriptor(const ipod_descriptor_t* md); + void ipod_init(ipod_t* ipod); void ipod_finish(ipod_t* ipod); result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb); Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-02-21 17:36:23 UTC (rev 383) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-02-22 16:08:29 UTC (rev 384) @@ -46,16 +46,31 @@ memset(chunk, 0, sizeof(*chunk)); } -static int mhbd_init(itunesdb_chunk_t* chunk, int dataonly) +static int mhbd_init(itunesdb_chunk_t* chunk, int def) { - if (!dataonly) { + chunk_mhbd_t* mhbd = NULL; + + if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhbd", 4); chunk->size = sizeof(chunk_mhbd_t) + 12; chunk->overall_size = chunk->size; } - chunk->data = calloc(1, sizeof(chunk_mhbd_t)); - return chunk->data ? 0 : 1; + + mhbd = (chunk_mhbd_t*)calloc(1, sizeof(chunk_mhbd_t)); + if (def && mhbd) { + mhbd->unknown1 = 1; + mhbd->version = 0x13; /* iTunes 7 */ + mhbd->num_children = 0; + mhbd->identifier = 0x8CD2513B66EF2541; + mhbd->unknown2 = 2; + mhbd->unknown3 = 611; + mhbd->unknown4 = 0xBCD054CD8C063208; + mhbd->language[0] = 'j'; + mhbd->language[1] = 'a'; + } + chunk->data = mhbd; + return mhbd ? 0 : 1; } static int mhbd_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) @@ -78,16 +93,24 @@ -static mhsd_init(itunesdb_chunk_t* chunk, int dataonly) +static mhsd_init(itunesdb_chunk_t* chunk, int def) { - if (!dataonly) { + chunk_mhsd_t* mhsd = NULL; + + if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhsd", 4); chunk->size = sizeof(chunk_mhsd_t) + 12; chunk->overall_size = chunk->size; } - chunk->data = calloc(1, sizeof(chunk_mhsd_t)); - return chunk->data ? 0 : 1; + + mhsd = (chunk_mhsd_t*)calloc(1, sizeof(chunk_mhsd_t)); + if (mhsd && def) { + mhsd->type = 0; /* Initialize type 0 for now. */ + } + + chunk->data = mhsd; + return mhsd ? 0 : 1; } static int mhsd_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) @@ -102,16 +125,20 @@ -static mhlt_init(itunesdb_chunk_t* chunk, int dataonly) +static mhlt_init(itunesdb_chunk_t* chunk, int def) { - if (!dataonly) { + chunk_mhlt_t* mhlt = NULL; + + if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhlt", 4); chunk->size = 0; /* stands for number of children for "mhlt" chunk. */ chunk->overall_size = sizeof(chunk_mhlt_t) + 12; } - chunk->data = calloc(1, sizeof(chunk_mhlt_t)); - return chunk->data ? 0 : 1; + mhlt = (chunk_mhlt_t*)calloc(1, sizeof(chunk_mhlt_t)); + + chunk->data = mhlt; + return mhlt ? 0 : 1; } static int mhlt_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) @@ -125,16 +152,24 @@ -static mhit_init(itunesdb_chunk_t* chunk, int dataonly) +static mhit_init(itunesdb_chunk_t* chunk, int def) { - if (!dataonly) { + chunk_mhit_t* mhit = NULL; + + if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhit", 4); chunk->size = sizeof(chunk_mhit_t) + 12; chunk->overall_size = chunk->size; } - chunk->data = calloc(1, sizeof(chunk_mhit_t)); - return chunk->data ? 0 : 1; + + mhit = (chunk_mhit_t*)calloc(1, sizeof(chunk_mhit_t)); + if (mhit && def) { + mhit->visible = 1; /* Visible by default. */ + } + + chunk->data = mhit; + return mhit ? 0 : 1; } static int mhit_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) @@ -221,16 +256,20 @@ -static mhlp_init(itunesdb_chunk_t* chunk, int dataonly) +static mhlp_init(itunesdb_chunk_t* chunk, int def) { - if (!dataonly) { + chunk_mhlp_t* mhlp = NULL; + + if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhlp", 4); chunk->size = 0; /* stands for number of children for "mhlt" chunk. */ chunk->overall_size = sizeof(chunk_mhlp_t) + 12; } - chunk->data = calloc(1, sizeof(chunk_mhlp_t)); - return chunk->data ? 0 : 1; + + mhlp = (chunk_mhlp_t*)calloc(1, sizeof(chunk_mhlp_t)); + chunk->data = mhlp; + return mhlp ? 0 : 1; } static int mhlp_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) @@ -244,16 +283,20 @@ -static mhyp_init(itunesdb_chunk_t* chunk, int dataonly) +static mhyp_init(itunesdb_chunk_t* chunk, int def) { - if (dataonly) { + chunk_mhyp_t* mhyp = NULL; + + if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhyp", 4); chunk->size = sizeof(chunk_mhyp_t) + 12; chunk->overall_size = chunk->size; } - chunk->data = calloc(1, sizeof(chunk_mhyp_t)); - return chunk->data ? 0 : 1; + + mhyp = (chunk_mhyp_t*)calloc(1, sizeof(chunk_mhyp_t)); + chunk->data = mhyp; + return mhyp ? 0 : 1; } static int mhyp_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) @@ -279,28 +322,32 @@ -static mhip_init(itunesdb_chunk_t* chunk, int dataonly) +static mhip_init(itunesdb_chunk_t* chunk, int def) { - if (!dataonly) { + chunk_mhip_t* mhip = NULL; + + if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhip", 4); chunk->size = sizeof(chunk_mhip_t) + 12; chunk->overall_size = chunk->size; } - chunk->data = calloc(1, sizeof(chunk_mhip_t)); - return chunk->data ? 0 : 1; + + mhip = (chunk_mhip_t*)calloc(1, sizeof(chunk_mhip_t)); + chunk->data = mhip; + return mhip ? 0 : 1; } static int mhip_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { - chunk_mhip_t* mhyp = (chunk_mhip_t*)chunk->data; + chunk_mhip_t* mhip = (chunk_mhip_t*)chunk->data; - if (serialize_uint32le(sio, "num_mhod", "%u", &mhyp->num_mhod)) return 1; - if (serialize_uint32le(sio, "flag_podcast_group", "%X", &mhyp->flag_podcast_group)) return 1; - if (serialize_uint32le(sio, "group_id", "%u", &mhyp->group_id)) return 1; - if (serialize_uint32le(sio, "track_id", "%u", &mhyp->track_id)) return 1; - if (serialize_uint32le(sio, "timestamp", "%u", &mhyp->timestamp)) return 1; - if (serialize_uint32le(sio, "podcast_parent", "%u", &mhyp->podcast_parent)) return 1; + if (serialize_uint32le(sio, "num_mhod", "%u", &mhip->num_mhod)) return 1; + if (serialize_uint32le(sio, "flag_podcast_group", "%X", &mhip->flag_podcast_group)) return 1; + if (serialize_uint32le(sio, "group_id", "%u", &mhip->group_id)) return 1; + if (serialize_uint32le(sio, "track_id", "%u", &mhip->track_id)) return 1; + if (serialize_uint32le(sio, "timestamp", "%u", &mhip->timestamp)) return 1; + if (serialize_uint32le(sio, "podcast_parent", "%u", &mhip->podcast_parent)) return 1; return 0; } @@ -448,28 +495,29 @@ return 0; } +static const itunesdb_mhoddecl_t mds[] = { + {1, "title", 0, mhod_string_finish, mhod_string_serialize}, + {2, "location", 0, mhod_string_finish, mhod_string_serialize}, + {3, "album", 0, mhod_string_finish, mhod_string_serialize}, + {4, "artist", 0, mhod_string_finish, mhod_string_serialize}, + {5, "genre", 0, mhod_string_finish, mhod_string_serialize}, + {6, "filetype", 0, mhod_string_finish, mhod_string_serialize}, + {7, "EQ setting", 0, mhod_string_finish, mhod_string_serialize}, + {8, "comment", 0, mhod_string_finish, mhod_string_serialize}, + {9, "category", 0, mhod_string_finish, mhod_string_serialize}, + {12, "composer", 0, mhod_string_finish, mhod_string_serialize}, + {13, "grouping", 0, mhod_string_finish, mhod_string_serialize}, + {14, "description", 0, mhod_string_finish, mhod_string_serialize}, + {15, "podcast_enclosure_url", 0, mhod_url_finish, mhod_url_serialize}, + {16, "podcast_rss_url", 0, mhod_url_finish, mhod_url_serialize}, + {52, "index", 0, mhod_index_finish, mhod_index_serialize}, + {100, "playlist_column", 0x288, mhod_playlist_column_finish, mhod_playlist_column_serialize}, + {100, "playlist_order", 0x2C, mhod_playlist_order_finish, mhod_playlist_order_serialize}, + {0, NULL, 0, NULL}, +}; + static const itunesdb_mhoddecl_t* find_mhoddecl(itunesdb_chunk_t* chunk) { - static const itunesdb_mhoddecl_t mds[] = { - {1, "title", 0, mhod_string_finish, mhod_string_serialize}, - {2, "location", 0, mhod_string_finish, mhod_string_serialize}, - {3, "album", 0, mhod_string_finish, mhod_string_serialize}, - {4, "artist", 0, mhod_string_finish, mhod_string_serialize}, - {5, "genre", 0, mhod_string_finish, mhod_string_serialize}, - {6, "filetype", 0, mhod_string_finish, mhod_string_serialize}, - {7, "EQ setting", 0, mhod_string_finish, mhod_string_serialize}, - {8, "comment", 0, mhod_string_finish, mhod_string_serialize}, - {9, "category", 0, mhod_string_finish, mhod_string_serialize}, - {12, "composer", 0, mhod_string_finish, mhod_string_serialize}, - {13, "grouping", 0, mhod_string_finish, mhod_string_serialize}, - {14, "description", 0, mhod_string_finish, mhod_string_serialize}, - {15, "podcast_enclosure_url", 0, mhod_url_finish, mhod_url_serialize}, - {16, "podcast_rss_url", 0, mhod_url_finish, mhod_url_serialize}, - {52, "index", 0, mhod_index_finish, mhod_index_serialize}, - {100, "playlist_column", 0x288, mhod_playlist_column_finish, mhod_playlist_column_serialize}, - {100, "playlist_order", 0x2C, mhod_playlist_order_finish, mhod_playlist_order_serialize}, - {0, NULL, 0, NULL}, - }; const itunesdb_mhoddecl_t* decl = mds; chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; @@ -484,9 +532,22 @@ return NULL; } -static int mhod_init(itunesdb_chunk_t* chunk, int dataonly) +static const itunesdb_mhoddecl_t* find_mhoddecl_by_name(const char *name) { - if (!dataonly) { + const itunesdb_mhoddecl_t* decl = mds; + + while (decl->name) { + if (strcmp(decl->name, name) == 0) { + return decl; + } + ++decl; + } + return NULL; +} + +static int mhod_init(itunesdb_chunk_t* chunk, int def) +{ + if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhod", 4); chunk->size = 0x18; @@ -529,7 +590,7 @@ } -static const itunesdb_chunkdecl_t* find_chunkdecl(itunesdb_chunk_t* chunk) +static const itunesdb_chunkdecl_t* find_chunkdecl(const int8_t* name) { static const itunesdb_chunkdecl_t cds[] = { {"mhbd", mhbd_init, chunk_finish, mhbd_serialize}, @@ -545,7 +606,7 @@ const itunesdb_chunkdecl_t* decl = cds; while (decl->name) { - if (strncmp(decl->name, chunk->id, 4) == 0) { + if (strncmp(decl->name, name, 4) == 0) { return decl; } ++decl; @@ -553,6 +614,25 @@ return NULL; } +int itunesdb_init(itunesdb_chunk_t* chunk, const char *name, const char *subtype) +{ + const itunesdb_chunkdecl_t* decl = find_chunkdecl((int8_t*)name); + if (decl) { + decl->init(chunk, 1); + if (strncmp(name, "mhod", 4) == 0) { + chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + const itunesdb_mhoddecl_t* decl2 = find_mhoddecl_by_name(subtype); + if (decl2) { + chunk->overall_size = decl2->overall_size; + mhod->type = decl2->type; + } + } + return 0; + } else { + return 1; + } +} + void itunesdb_finish(itunesdb_chunk_t* chunk) { uint32_t i; @@ -562,7 +642,7 @@ itunesdb_finish(&chunk->childlen[i]); } - decl = find_chunkdecl(chunk); + decl = find_chunkdecl(chunk->id); if (decl) { decl->finish(chunk); } @@ -588,7 +668,7 @@ fprintf(sio->fp, "overall_size: %d\n", chunk->overall_size); /* Show fields in the chunk data */ - decl = find_chunkdecl(chunk); + decl = find_chunkdecl(chunk->id); if (decl) { decl->serialize(chunk, sio); } else { @@ -627,9 +707,9 @@ if (serialize_uint32le(sio, "overall_size", "%d", &chunk->overall_size)) return 1; /* Read the chunk data if this chunk is 'known' */ - decl = find_chunkdecl(chunk); + decl = find_chunkdecl(chunk->id); if (decl) { - if (decl->init(chunk, 1) == 0) { + if (decl->init(chunk, 0) == 0) { if (decl->serialize(chunk, sio)) return 1; } } @@ -661,7 +741,6 @@ chunk->num_children = 0; chunk->childlen = NULL; while (sio->offset - begin < chunk->overall_size) { - chunk->num_children; chunk->childlen = realloc(chunk->childlen, sizeof(itunesdb_chunk_t) * (chunk->num_children + 1)); memset(&chunk->childlen[chunk->num_children], 0, sizeof(itunesdb_chunk_t)); itunesdb_read(&chunk->childlen[chunk->num_children], sio); @@ -671,3 +750,70 @@ return 0; } + +itunesdb_chunk_t* itunesdb_new_child(itunesdb_chunk_t* chunk) +{ + chunk->childlen = (itunesdb_chunk_t*)realloc( + chunk->childlen, sizeof(itunesdb_chunk_t) * (chunk->num_children + 1)); + if (chunk->childlen) { + itunesdb_chunk_t* child = &chunk->childlen[chunk->num_children]; + memset(child, 0, sizeof(itunesdb_chunk_t)); + ++chunk->num_children; + return child; + } else { + return NULL; + } +} + +int itunesdb_set_mhod_string(itunesdb_chunk_t* chunk, const ucs2char_t* value) +{ + chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + chunk_mhod_string_t* str = &mhod->data.str; + + /* Make sure this is an "mhod" chunk. */ + if (strncmp(chunk->id, "mhod", 4) != 0) { + return 1; + } + + /* Store the string value. */ + str->position = 1; + str->size = ucs2len(value) * sizeof(ucs2char_t); + str->unknown = 1; + str->value = ucs2ndup(value, 512); + return 0; +} + +int itunesdb_set_mhod_index(itunesdb_chunk_t* chunk, uint32_t type, sorted_index_t* si, uint32_t n) +{ + uint32_t i; + chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + chunk_mhod_index_t* index = &mhod->data.index; + + /* Make sure this is an "mhod" chunk. */ + if (strncmp(chunk->id, "mhod", 4) != 0) { + return 1; + } + + /* Store the index. */ + index->type = type; + index->num_entries = n; + index->entries = (uint32_t*)calloc(n, sizeof(uint32_t)); + for (i = 0;i < n;++i) { + index->entries[i] = si[i].index; + } + return 0; +} + +int itunesdb_set_mhod_playlist_order(itunesdb_chunk_t* chunk, uint32_t order) +{ + chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + chunk_mhod_playlist_order_t* po = &mhod->data.po; + + /* Make sure this is an "mhod" chunk. */ + if (strncmp(chunk->id, "mhod", 4) != 0) { + return 1; + } + + po->position = order; + return 0; +} Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-02-21 17:36:23 UTC (rev 383) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-02-22 16:08:29 UTC (rev 384) @@ -237,8 +237,20 @@ int (*serialize)(itunesdb_chunk_t* chunk, serializer_t* sio); } itunesdb_chunkdecl_t; -void itunesdb_finish(itunesdb_chunk_t* mhbd); -int itunesdb_repr(itunesdb_chunk_t* mhbd, size_t index, serializer_t* sio); -int itunesdb_read(itunesdb_chunk_t* mhbd, serializer_t* sio); +typedef struct { + uint32_t index; + const void* base; +} sorted_index_t; +int itunesdb_init(itunesdb_chunk_t* chunk, const char *name, const char *subtype); +itunesdb_chunk_t* itunesdb_new_child(itunesdb_chunk_t* chunk); +void itunesdb_finish(itunesdb_chunk_t* chunk); + +int itunesdb_set_mhod_string(itunesdb_chunk_t* chunk, const ucs2char_t* str); +int itunesdb_set_mhod_index(itunesdb_chunk_t* chunk, uint32_t type, sorted_index_t* si, uint32_t n); +int itunesdb_set_mhod_playlist_order(itunesdb_chunk_t* chunk, uint32_t order); + +int itunesdb_repr(itunesdb_chunk_t* chunk, size_t index, serializer_t* sio); +int itunesdb_read(itunesdb_chunk_t* chunk, serializer_t* sio); + #endif/*__ITUNESDB_H__*/ Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-21 17:36:23 UTC (rev 383) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-22 16:08:29 UTC (rev 384) @@ -47,40 +47,6 @@ typedef struct { - const char *id; - const char *manufacturer; - const char *name; - const char *mode; - const char *min_version; - const char *max_version; - const char *itunesdb_filename; - const char *extensions; - uint32_t codecs[8]; - const char *path_to_system; - const char *path_to_music; - const char *path_to_playlist; -} ipod_descriptor_t; - -static const ipod_descriptor_t g_model_descriptions[] = { - { - "apple_ipod", "Apple", "iPod", "UM", - "---", "---", - "iPod_Control\\iTunes\\iTunesDB", - ".mp3\0", - {PMPCODEC_MPEGLAYER3, 0, 0, 0, 0, 0, 0, 0}, - "iPod_Control", "iPod_Control\\Music", "Playlists", - }, - { - NULL, NULL, NULL, NULL, - NULL, NULL, - NULL, - NULL, - {0, 0, 0, 0, 0, 0, 0, 0}, - NULL, NULL, NULL, - }, -}; - -typedef struct { const ipod_descriptor_t* decl; } pmp_internal_t; @@ -108,18 +74,6 @@ #define COMP(a, b) ((a)>(b))-((a)<(b)) -static char* strip(char *str) -{ - char *p = str + strlen(str) - 1; - while (*str && isspace(*str)) { - str++; - } - while (str <= p && isspace(*p)) { - *p-- = 0; - } - return str; -} - static const char *strcpy_if_empty(char *dst, const char *src) { return *dst ? dst : strcpy(dst, src); @@ -204,31 +158,13 @@ } -static int compare_version(const char *x, const char *y) -{ - char *p = NULL, *q = NULL; - for (;;) { - long a = strtol(x, &p, 10); - long b = strtol(y, &q, 10); - int value = COMP(a, b); - if (value != 0) { - return value; - } - if (!*p || !*q || *p != *q) { - return COMP(*p, *q); - } - x = p+1; - y = q+1; - } -} - PMPIPODAPI result_t pmp_enumerate_devid(pmplib_enumerate_devid_callback_t callback, void *instance) { - const ipod_descriptor_t* md = g_model_descriptions; - for (;md->id;++md) { + const ipod_descriptor_t* md = NULL; + while (md = ipod_next_descriptor(md)) { callback(instance, md->id); } return 0; @@ -249,22 +185,11 @@ *ptr_pmp = 0; // Find a suitable model for the device. - md = g_model_descriptions; - for (;md->id;++md) { - if (id && *id) { - // Match the device identifier. - if (strcmp(md->id, id) == 0) { - // This will fill some members in decl. - //detect_model(path_to_device, md, &info); - set_device_info(id, path_to_device, md, &info); - break; - } - } - } - - if (!md->id) { + md = ipod_detect(path_to_device, id); + if (!md) { return PMPERR_DEVICENOTFOUND; } + set_device_info(id, path_to_device, md, &info); // Allocate PMP class instance. pmp = (pmp_t*)calloc(1, sizeof(pmp_t)); @@ -475,16 +400,16 @@ static uint32_t pmpmusic_close(pmp_music_t* music) { - //ip3db_t ip3db; + ipod_t ipod; result_t ret = 0; pmp_t* pmp = music->pmp; pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; - /* - // Initialize IP3DB. - ip3db_init(&ip3db); + // Initialize ipod library. + ipod_init(&ipod); if (pmp->flag & PMPOF_MUSIC_DB_WRITE) { + /* int i; ucs2char_t dat[MAX_PATH], dic[MAX_PATH], idx[MAX_PATH]; ip3db_music_record_t* records = NULL; @@ -554,10 +479,11 @@ ip3db_record_finish(&ip3db, &records[i]); } free(records); + */ } - ip3db_finish(&ip3db); - */ +exit_this: + ipod_finish(&ipod); return ret; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-02-23 06:22:53
|
Revision: 385 http://svn.sourceforge.net/pmplib/?rev=385&view=rev Author: nyaochi Date: 2007-02-22 22:22:53 -0800 (Thu, 22 Feb 2007) Log Message: ----------- Memorial commit: implemented the database generation for iPod. It's still in the early stage (lack of MP4 support, MP3 gapless playback, update mode, playlists, etc), but iTunesDB was recognized by iPod and iTunes. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/ipod.h trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h trunk/pmplib/lib/pmp_ipod/pmp_ipod.c trunk/pmplib/lib/pmp_ipod/serialize.c Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-22 16:08:29 UTC (rev 384) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-23 06:22:53 UTC (rev 385) @@ -121,6 +121,22 @@ } } +result_t ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb) +{ + FILE *fp = NULL; + serializer_t sio; + + serialize_init_write(&sio, 0x10000); + itunesdb_write(ipod->itunesdb, &sio); + + fp = ucs2fopen(itunesdb, "wb"); + fwrite(sio.base, 1, sio.offset, fp); + fclose(fp); + + serialize_finish(&sio); + return 0; +} + result_t ipod_dump(ipod_t* ipod, FILE *fpo) { serializer_t sio; @@ -185,6 +201,15 @@ } } + /* Construct an "mhod" chunk for album. */ + if (rec->genre && *rec->genre) { + mhod = itunesdb_new_child(mhit); + if (mhod) { + itunesdb_init(mhod, "mhod", "genre"); + itunesdb_set_mhod_string(mhod, rec->genre); + } + } + /* Construct an "mhod" chunk for filetype. */ mhod = itunesdb_new_child(mhit); if (mhod) { @@ -205,7 +230,7 @@ if (mhod) { ucs2char_t pathname[MAX_PATH], *p = NULL; itunesdb_init(mhod, "mhod", "location"); - ucs2cpy(pathname, rec->filename); + ucs2cpy(pathname, rec->filename + 2); for (p = pathname;*p;++p) { if (*p == PATHCHAR) *p = ':'; } @@ -217,6 +242,17 @@ return 0; } +static int comp_string(const ucs2char_t* x, const ucs2char_t*y) +{ + int ret = 0; + if (!x || !*x) { + ret = ((!y || !*y) ? 0 : 1); + } else { + ret = ((!y || !*y) ? -1 : ucs2icmp(x, y)); + } + return ret; +} + static int comp_title(const void *_x, const void *_y) { const sorted_index_t *xi = (const sorted_index_t*)_x; @@ -225,7 +261,7 @@ const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; - return ucs2cmp(x->title, y->title); + return comp_string(x->title, y->title); } static int comp_album(const void *_x, const void *_y) @@ -237,11 +273,11 @@ const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; - ret = ucs2cmp(x->album, y->album); + ret = comp_string(x->album, y->album); if (ret == 0) { ret = COMP(x->track_number, y->track_number); if (ret == 0) { - return ucs2cmp(x->title, y->title); + return comp_string(x->title, y->title); } } return ret; @@ -256,7 +292,7 @@ const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; - ret = ucs2cmp(x->artist, y->artist); + ret = comp_string(x->artist, y->artist); if (ret == 0) { return comp_album(_x, _y); } @@ -272,7 +308,7 @@ const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; - ret = ucs2cmp(x->genre, y->genre); + ret = comp_string(x->genre, y->genre); if (ret == 0) { return comp_artist(_x, _y); } @@ -288,9 +324,9 @@ const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; - ret = ucs2cmp(x->composer, y->composer); + ret = comp_string(x->composer, y->composer); if (ret == 0) { - return ucs2cmp(x->title, y->title); + return comp_string(x->title, y->title); } return ret; } @@ -396,15 +432,19 @@ result_t ipod_set(ipod_t* ipod, const pmp_music_record_t* records, int num_records, const pmp_playlist_t* playlists, int num_playlists) { int i; - itunesdb_chunk_t mhbd, *mhsd = NULL; + itunesdb_chunk_t *mhbd = NULL, *mhsd = NULL; itunesdb_chunk_t *mhlt = NULL, *mhit = NULL; itunesdb_chunk_t *mhlp = NULL, *mhyp = NULL; + chunk_mhbd_t* mhbd_data = NULL; /* Construct "mhbd" chunk. */ - itunesdb_init(&mhbd, "mhbd", NULL); + mhbd = (itunesdb_chunk_t*)calloc(1, sizeof(itunesdb_chunk_t)); + memset(mhbd, 0, sizeof(*mhbd)); + itunesdb_init(mhbd, "mhbd", NULL); + mhbd_data = (chunk_mhbd_t*)mhbd->data; /* Construct "mhsd" chunk with track type. */ - mhsd = itunesdb_new_child(&mhbd); + mhsd = itunesdb_new_child(mhbd); if (mhsd) { chunk_mhsd_t* mhsd_data = NULL; itunesdb_init(mhsd, "mhsd", NULL); @@ -415,7 +455,6 @@ mhlt = itunesdb_new_child(mhsd); if (mhlt) { itunesdb_init(mhlt, "mhlt", NULL); - mhlt->num_children = num_records; /* For all records... */ for (i = 0;i < num_records;++i) { @@ -434,7 +473,7 @@ } /* Construct "mhsd" chunk with playlist type. */ - mhsd = itunesdb_new_child(&mhbd); + mhsd = itunesdb_new_child(mhbd); if (mhsd) { chunk_mhsd_t* mhsd_data = NULL; itunesdb_init(mhsd, "mhsd", NULL); @@ -445,7 +484,6 @@ mhlp = itunesdb_new_child(mhsd); if (mhlp) { itunesdb_init(mhlp, "mhlp", NULL); - mhlp->num_children = 1; mhyp = itunesdb_new_child(mhlp); if (mhyp) { @@ -457,4 +495,9 @@ } } } + + mhbd_data->num_children = mhbd->num_children; + + ipod->itunesdb = mhbd; + return 0; } Modified: trunk/pmplib/lib/pmp_ipod/ipod.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.h 2007-02-22 16:08:29 UTC (rev 384) +++ trunk/pmplib/lib/pmp_ipod/ipod.h 2007-02-23 06:22:53 UTC (rev 385) @@ -24,6 +24,8 @@ #ifndef __IPOD_H__ #define __IPOD_H__ +#include <pmplib/pmp.h> + typedef struct { const char *id; const char *manufacturer; @@ -51,7 +53,9 @@ void ipod_init(ipod_t* ipod); void ipod_finish(ipod_t* ipod); +result_t ipod_set(ipod_t* ipod, const pmp_music_record_t* records, int num_records, const pmp_playlist_t* playlists, int num_playlists); result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb); +result_t ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb); result_t ipod_dump(ipod_t* ipod, FILE *fpo); #endif/*__IPOD_H__*/ Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-02-22 16:08:29 UTC (rev 384) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-02-23 06:22:53 UTC (rev 385) @@ -53,7 +53,7 @@ if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhbd", 4); - chunk->size = sizeof(chunk_mhbd_t) + 12; + chunk->size = 104; chunk->overall_size = chunk->size; } @@ -100,7 +100,7 @@ if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhsd", 4); - chunk->size = sizeof(chunk_mhsd_t) + 12; + chunk->size = 96; chunk->overall_size = chunk->size; } @@ -132,8 +132,8 @@ if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhlt", 4); - chunk->size = 0; /* stands for number of children for "mhlt" chunk. */ - chunk->overall_size = sizeof(chunk_mhlt_t) + 12; + chunk->size = 92; + chunk->overall_size = 0; /* stands for number of children for "mhlt" chunk. */ } mhlt = (chunk_mhlt_t*)calloc(1, sizeof(chunk_mhlt_t)); @@ -159,7 +159,7 @@ if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhit", 4); - chunk->size = sizeof(chunk_mhit_t) + 12; + chunk->size = 328; chunk->overall_size = chunk->size; } @@ -263,8 +263,8 @@ if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhlp", 4); - chunk->size = 0; /* stands for number of children for "mhlt" chunk. */ - chunk->overall_size = sizeof(chunk_mhlp_t) + 12; + chunk->size = 92; + chunk->overall_size = 0; } mhlp = (chunk_mhlp_t*)calloc(1, sizeof(chunk_mhlp_t)); @@ -290,7 +290,7 @@ if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhyp", 4); - chunk->size = sizeof(chunk_mhyp_t) + 12; + chunk->size = 108; chunk->overall_size = chunk->size; } @@ -329,7 +329,7 @@ if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhip", 4); - chunk->size = sizeof(chunk_mhip_t) + 12; + chunk->size = 76; chunk->overall_size = chunk->size; } @@ -550,7 +550,7 @@ if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhod", 4); - chunk->size = 0x18; + chunk->size = 24; chunk->overall_size = chunk->size; } chunk->data = calloc(1, sizeof(chunk_mhod_t)); @@ -751,6 +751,53 @@ return 0; } +int itunesdb_write(itunesdb_chunk_t* chunk, serializer_t* sio) +{ + uint32_t i, offset = 0; + uint8_t zero = 0; + const itunesdb_chunkdecl_t* decl = NULL; + + /* Store the offset position of this chunk for the future use of rewind. */ + chunk->offset = serialize_tell(sio); + + /* Write the chunk ID and header information. The overall_size may be incorrect at this moment. */ + if (serialize_uint8_array(sio, "id", "%c ", chunk->id, sizeof(chunk->id))) return 1; + if (serialize_uint32le(sio, "size", "%d", &chunk->size)) return 1; + if (serialize_uint32le(sio, "overall_size", "%d", &chunk->overall_size)) return 1; + + /* Write the chunk data if this chunk is 'known' */ + decl = find_chunkdecl(chunk->id); + if (decl) { + if (decl->serialize(chunk, sio)) return 1; + } + + /* Pad 0x00 in the rest of file header. */ + for (i = serialize_tell(sio);i < chunk->offset + chunk->size;++i) { + serialize_uint8(sio, NULL, NULL, &zero); + } + + /* Write children for this chunk. */ + for (i = 0;i < chunk->num_children;++i) { + itunesdb_write(&chunk->childlen[i], sio); + } + + /* Calculate chunk->overall_size. */ + if (strncmp(chunk->id, "mhlt", 4) == 0 || strncmp(chunk->id, "mhlp", 4) == 0) { + /* chunk->overall_size represents the number of children for "mhlt" and "mhlp" chunks */ + chunk->overall_size = chunk->num_children; + } else { + /* chunk->overall_size represents the size in bytes of this chunk */ + chunk->overall_size = serialize_tell(sio) - chunk->offset; + } + + offset = serialize_tell(sio); + serialize_seek(sio, chunk->offset + 2 * sizeof(uint32_t)); + if (serialize_uint32le(sio, "overall_size", "%d", &chunk->overall_size)) return 1; + serialize_seek(sio, offset); + + return 0; +} + itunesdb_chunk_t* itunesdb_new_child(itunesdb_chunk_t* chunk) { chunk->childlen = (itunesdb_chunk_t*)realloc( Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-02-22 16:08:29 UTC (rev 384) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-02-23 06:22:53 UTC (rev 385) @@ -252,5 +252,6 @@ int itunesdb_repr(itunesdb_chunk_t* chunk, size_t index, serializer_t* sio); int itunesdb_read(itunesdb_chunk_t* chunk, serializer_t* sio); +int itunesdb_write(itunesdb_chunk_t* chunk, serializer_t* sio); #endif/*__ITUNESDB_H__*/ Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-22 16:08:29 UTC (rev 384) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-23 06:22:53 UTC (rev 385) @@ -404,82 +404,18 @@ result_t ret = 0; pmp_t* pmp = music->pmp; pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; + ucs2char_t itunesdb[MAX_PATH]; // Initialize ipod library. ipod_init(&ipod); - if (pmp->flag & PMPOF_MUSIC_DB_WRITE) { - /* - int i; - ucs2char_t dat[MAX_PATH], dic[MAX_PATH], idx[MAX_PATH]; - ip3db_music_record_t* records = NULL; + // Read the music database. + set_filenames(itunesdb, music->pmp); - // Allocate an array of music records. - records = (ip3db_music_record_t*)malloc(sizeof(ip3db_music_record_t) * pmpmi->num_records); - - // Build an array of IP3DB records. - for (i = 0;i < pmpmi->num_records;++i) { - const pmp_music_record_t* src = &pmpmi->records[i]; - ip3db_variant_t* dst = records[i]; - - ip3db_record_init(&ip3db, &records[i]); - ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILEPATH], filepath_changeroot(src->filename, pmp->info.path_to_root)); - filepath_remove_filespec(dst[IP3DBF_MUSIC_FILEPATH].value.str); - filepath_addslash(dst[IP3DBF_MUSIC_FILEPATH].value.str); - filepath_slash(dst[IP3DBF_MUSIC_FILEPATH].value.str); - ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILENAME], filepath_skippath(src->filename)); - ip3db_variant_set_str(&dst[IP3DBF_MUSIC_ARTIST], src->artist); - ip3db_variant_set_str(&dst[IP3DBF_MUSIC_ALBUM], src->album); - ip3db_variant_set_str(&dst[IP3DBF_MUSIC_GENRE], src->genre); - ip3db_variant_set_str(&dst[IP3DBF_MUSIC_TITLE], src->title); - ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_DURATION], src->duration); - ip3db_variant_set_word(&dst[IP3DBF_MUSIC_RATING], (uint16_t)src->rating); - switch (src->codec) { - case PMPCODEC_MPEGLAYER3: - ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 0); - break; - case PMPCODEC_VORBIS: - ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 3); - break; - case PMPCODEC_WMA: - ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 5); - break; - } - ip3db_variant_set_word(&dst[IP3DBF_MUSIC_TRACKNUMBER], (uint16_t)src->track_number); - ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_BITRATE], src->bitrate); - ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_CLUSA], src->ts_update); - ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_UID], (uint32_t)i+1); - } - - // Register records (and playlists) to the database. - if (pmp->flag & PMPOF_MUSIC_PL_WRITE) { - ip3db_set( - &ip3db, - (const ip3db_music_record_t*)records, - pmpmi->num_records, - pmpmi->playlists, - pmpmi->num_playlists - ); - } else { - ip3db_set( - &ip3db, - (const ip3db_music_record_t*)records, - pmpmi->num_records, - NULL, - 0 - ); - } - - // Write out the music database. - set_filenames(dat, dic, idx, pmp); - ret = ip3db_write(&ip3db, dat, dic, idx); - - // Free IP3DB records. - for (i = 0;i < pmpmi->num_records;++i) { - ip3db_record_finish(&ip3db, &records[i]); - } - free(records); - */ + if (pmp->flag & PMPOF_MUSIC_DB_WRITE) { + ipod_set(&ipod, pmpmi->records, pmpmi->num_records, pmpmi->playlists, pmpmi->num_playlists); + ipod_write(&ipod, itunesdb); + ipod_dump(&ipod, stdout); } exit_this: Modified: trunk/pmplib/lib/pmp_ipod/serialize.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/serialize.c 2007-02-22 16:08:29 UTC (rev 384) +++ trunk/pmplib/lib/pmp_ipod/serialize.c 2007-02-23 06:22:53 UTC (rev 385) @@ -270,9 +270,7 @@ int serialize_seek(serializer_t* sio, size_t offset) { - if (sio->mode < 0) { - sio->offset = offset; - } + sio->offset = offset; return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-02-23 06:58:34
|
Revision: 386 http://svn.sourceforge.net/pmplib/?rev=386&view=rev Author: nyaochi Date: 2007-02-22 22:58:35 -0800 (Thu, 22 Feb 2007) Log Message: ----------- Compute the size of padded data automatically. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h trunk/pmplib/lib/pmp_ipod/serialize.c Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-02-23 06:22:53 UTC (rev 385) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-02-23 06:58:35 UTC (rev 386) @@ -86,7 +86,6 @@ if (serialize_uint64le(sio, "unknown4", "%016llX", &mhbd->unknown4)) return 1; if (serialize_uint8_array(sio, "unknown5", "%02X ", mhbd->unknown5, sizeof(mhbd->unknown5))) return 1; if (serialize_uint8_array(sio, "language", "%c ", mhbd->language, sizeof(mhbd->language))) return 1; - if (serialize_uint8_array(sio, "unknown6", "%02X ", mhbd->unknown6, sizeof(mhbd->unknown6))) return 1; return 0; } @@ -118,7 +117,6 @@ chunk_mhsd_t* mhsd = (chunk_mhsd_t*)chunk->data; if (serialize_uint32le(sio, "type", "%d", &mhsd->type)) return 1; - if (serialize_uint8_array(sio, "unknown1", "%02X ", mhsd->unknown1, sizeof(mhsd->unknown1))) return 1; return 0; } @@ -145,7 +143,7 @@ { chunk_mhlt_t* mhlt = (chunk_mhlt_t*)chunk->data; - if (serialize_uint8_array(sio, "unknown1", "%02X ", mhlt->unknown1, sizeof(mhlt->unknown1))) return 1; + if (serialize_uint8(sio, "unknown", "%02X", &mhlt->unknown)) return 1; return 0; } @@ -276,7 +274,7 @@ { chunk_mhlp_t* mhlp = (chunk_mhlp_t*)chunk->data; - if (serialize_uint8_array(sio, "unknown1", "%02X ", mhlp->unknown1, sizeof(mhlp->unknown1))) return 1; + if (serialize_uint8(sio, "unknown", "%02X", &mhlp->unknown)) return 1; return 0; } @@ -315,7 +313,6 @@ if (serialize_uint16le(sio, "unk4", "%u", &mhyp->unk4)) return 1; if (serialize_uint16le(sio, "flag_podcast", "%u", &mhyp->flag_podcast)) return 1; if (serialize_uint32le(sio, "sort_order", "%u", &mhyp->sort_order)) return 1; - if (serialize_uint8_array(sio, "padding", "%02X ", mhyp->padding, sizeof(mhyp->padding))) return 1; return 0; } @@ -490,7 +487,7 @@ chunk_mhod_playlist_order_t* po = &mhod->data.po; if (serialize_uint32le(sio, "position", "%u", &po->position)) return 1; - if (serialize_uint8_array(sio, "padding", "%02X ", po->padding, sizeof(po->padding))) return 1; + if (serialize_uint8_array(sio, "unknown", "%02X ", po->unknown, sizeof(po->unknown))) return 1; return 0; } @@ -676,6 +673,13 @@ fprintf(sio->fp, "!unknown_chunk!\n"); } + /* Show padded data. */ + if (chunk->padding && chunk->padding_size) { + char msg[128]; + sprintf(msg, "padding (%d)", chunk->padding_size); + if (serialize_uint8_array(sio, msg, "%02X ", chunk->padding, chunk->padding_size)) return 1; + } + /* Show number of children */ serialize_indent(sio); fprintf(sio->fp, "#children: %d\n", chunk->num_children); @@ -696,8 +700,8 @@ int itunesdb_read(itunesdb_chunk_t* chunk, serializer_t* sio) { - uint32_t i; - size_t begin = serialize_tell(sio); + uint32_t i, next; + uint32_t begin = (uint32_t)serialize_tell(sio); const itunesdb_chunkdecl_t* decl = NULL; /* Read the chunk ID and header information */ @@ -714,17 +718,27 @@ } } + /* Determine the size of padded data for this chunk. */ if (strncmp(chunk->id, "mhod", 4) == 0) { - uint32_t next = begin + chunk->overall_size; - if (next < serialize_tell(sio)) { - fprintf(stderr, "WARNING: backward seeking.\n"); - } - serialize_seek(sio, next); + next = begin + chunk->overall_size; + chunk->padding_size = next - serialize_tell(sio); } else { - uint32_t next = begin + chunk->size; - if (next < serialize_tell(sio)) { - fprintf(stderr, "WARNING: backward seeking.\n"); + next = begin + chunk->size; + chunk->padding_size = next - serialize_tell(sio); + } + + /* Read the padded data. */ + if (0 < chunk->padding_size) { + chunk->padding = (uint8_t*)calloc(chunk->padding_size, sizeof(uint8_t)); + if (chunk->padding) { + if (serialize_uint8_array(sio, "padding", "%02X ", chunk->padding, chunk->padding_size)) return 1; } + } else if (chunk->padding_size < 0) { + /* For some reason, we read too much data for this chunk. */ + fprintf(stderr, "WARNING: backward seeking.\n"); + chunk->padding_size = 0; + chunk->padding = NULL; + /* Rewind to the correct position. */ serialize_seek(sio, next); } @@ -758,7 +772,7 @@ const itunesdb_chunkdecl_t* decl = NULL; /* Store the offset position of this chunk for the future use of rewind. */ - chunk->offset = serialize_tell(sio); + chunk->offset = (uint32_t)serialize_tell(sio); /* Write the chunk ID and header information. The overall_size may be incorrect at this moment. */ if (serialize_uint8_array(sio, "id", "%c ", chunk->id, sizeof(chunk->id))) return 1; @@ -772,7 +786,7 @@ } /* Pad 0x00 in the rest of file header. */ - for (i = serialize_tell(sio);i < chunk->offset + chunk->size;++i) { + for (i = (uint32_t)serialize_tell(sio);i < chunk->offset + chunk->size;++i) { serialize_uint8(sio, NULL, NULL, &zero); } @@ -787,10 +801,10 @@ chunk->overall_size = chunk->num_children; } else { /* chunk->overall_size represents the size in bytes of this chunk */ - chunk->overall_size = serialize_tell(sio) - chunk->offset; + chunk->overall_size = (uint32_t)serialize_tell(sio) - chunk->offset; } - offset = serialize_tell(sio); + offset = (uint32_t)serialize_tell(sio); serialize_seek(sio, chunk->offset + 2 * sizeof(uint32_t)); if (serialize_uint32le(sio, "overall_size", "%d", &chunk->overall_size)) return 1; serialize_seek(sio, offset); @@ -824,7 +838,7 @@ /* Store the string value. */ str->position = 1; - str->size = ucs2len(value) * sizeof(ucs2char_t); + str->size = (uint32_t)(ucs2len(value) * sizeof(ucs2char_t)); str->unknown = 1; str->value = ucs2ndup(value, 512); return 0; Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-02-23 06:22:53 UTC (rev 385) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-02-23 06:58:35 UTC (rev 386) @@ -34,16 +34,14 @@ uint64_t unknown4; uint8_t unknown5[26]; /* zero padded. */ uint8_t language[2]; /* e.g., "en", "ja" */ - uint8_t unknown6[32]; /* zero padded. */ } chunk_mhbd_t; typedef struct { uint32_t type; /* 1 (track list), 2 (playlist list), or 3 (podcast list). */ - uint8_t unknown1[16*5]; /* zero padded. */ } chunk_mhsd_t; typedef struct { - uint8_t unknown1[16*5]; /* zero padded. */ + uint8_t unknown; /* zero padded. */ } chunk_mhlt_t; typedef struct { @@ -124,7 +122,7 @@ } chunk_mhit_t; typedef struct { - uint8_t unknown1[16*5]; /* zero padded. */ + uint8_t unknown; /* zero padded. */ } chunk_mhlp_t; typedef struct { @@ -140,7 +138,6 @@ uint16_t unk4; uint16_t flag_podcast; uint32_t sort_order; - uint8_t padding[0x3C]; } chunk_mhyp_t; typedef struct { @@ -194,7 +191,7 @@ typedef struct { uint32_t position; - uint8_t padding[16]; + uint8_t unknown[16]; } chunk_mhod_playlist_order_t; typedef struct { @@ -217,15 +214,20 @@ uint32_t overall_size; void* data; + uint32_t num_children; /* This field does not exist in iTunesDB. */ struct tag_itunesdb_chunk* childlen; + + int32_t padding_size; + uint8_t* padding; + uint32_t offset; /* This field does not exist in iTunesDB. */ }; typedef struct { uint32_t type; const char* name; - size_t overall_size; + uint32_t overall_size; void (*finish)(itunesdb_chunk_t* chunk); int (*serialize)(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio); } itunesdb_mhoddecl_t; Modified: trunk/pmplib/lib/pmp_ipod/serialize.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/serialize.c 2007-02-23 06:22:53 UTC (rev 385) +++ trunk/pmplib/lib/pmp_ipod/serialize.c 2007-02-23 06:58:35 UTC (rev 386) @@ -267,7 +267,6 @@ return 0; } - int serialize_seek(serializer_t* sio, size_t offset) { sio->offset = offset; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-02-23 07:46:47
|
Revision: 387 http://svn.sourceforge.net/pmplib/?rev=387&view=rev Author: nyaochi Date: 2007-02-22 23:46:45 -0800 (Thu, 22 Feb 2007) Log Message: ----------- Added some comments. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-02-23 06:58:35 UTC (rev 386) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-02-23 07:46:45 UTC (rev 387) @@ -1,5 +1,5 @@ /* - * iTunesDB + * iTunesDB reader/writer/dumper. * * Copyright (c) 2005-2007 Naoaki Okazaki * @@ -43,6 +43,7 @@ static void chunk_finish(itunesdb_chunk_t* chunk) { free(chunk->data); + free(chunk->padding); memset(chunk, 0, sizeof(*chunk)); } @@ -54,14 +55,14 @@ memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhbd", 4); chunk->size = 104; - chunk->overall_size = chunk->size; + chunk->overall_size = 0; /* to be filled */ } mhbd = (chunk_mhbd_t*)calloc(1, sizeof(chunk_mhbd_t)); if (def && mhbd) { mhbd->unknown1 = 1; mhbd->version = 0x13; /* iTunes 7 */ - mhbd->num_children = 0; + mhbd->num_children = 0; /* to be filled */ mhbd->identifier = 0x8CD2513B66EF2541; mhbd->unknown2 = 2; mhbd->unknown3 = 611; @@ -100,12 +101,12 @@ memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhsd", 4); chunk->size = 96; - chunk->overall_size = chunk->size; + chunk->overall_size = 0; /* to be filled */ } mhsd = (chunk_mhsd_t*)calloc(1, sizeof(chunk_mhsd_t)); if (mhsd && def) { - mhsd->type = 0; /* Initialize type 0 for now. */ + mhsd->type = 0; /* to be filled */ } chunk->data = mhsd; @@ -131,7 +132,7 @@ memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhlt", 4); chunk->size = 92; - chunk->overall_size = 0; /* stands for number of children for "mhlt" chunk. */ + chunk->overall_size = 0; /* to be filled */ } mhlt = (chunk_mhlt_t*)calloc(1, sizeof(chunk_mhlt_t)); @@ -158,12 +159,13 @@ memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhit", 4); chunk->size = 328; - chunk->overall_size = chunk->size; + chunk->overall_size = 0; /* to be filled */ } mhit = (chunk_mhit_t*)calloc(1, sizeof(chunk_mhit_t)); if (mhit && def) { - mhit->visible = 1; /* Visible by default. */ + mhit->visible = 1; /* visible by default */ + /* other fields to be filled later */ } chunk->data = mhit; @@ -262,7 +264,7 @@ memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhlp", 4); chunk->size = 92; - chunk->overall_size = 0; + chunk->overall_size = 0; /* to be filled */ } mhlp = (chunk_mhlp_t*)calloc(1, sizeof(chunk_mhlp_t)); @@ -289,7 +291,7 @@ memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhyp", 4); chunk->size = 108; - chunk->overall_size = chunk->size; + chunk->overall_size = 0; /* to be filled */ } mhyp = (chunk_mhyp_t*)calloc(1, sizeof(chunk_mhyp_t)); @@ -327,7 +329,7 @@ memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhip", 4); chunk->size = 76; - chunk->overall_size = chunk->size; + chunk->overall_size = 0; /* to be filled */ } mhip = (chunk_mhip_t*)calloc(1, sizeof(chunk_mhip_t)); @@ -562,6 +564,7 @@ if (decl) { decl->finish(chunk); } + chunk_finish(chunk); } static int mhod_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-02-23 06:58:35 UTC (rev 386) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-02-23 07:46:45 UTC (rev 387) @@ -1,5 +1,5 @@ /* - * iTunesDB + * iTunesDB reader/writer/dumper. * * Copyright (c) 2005-2007 Naoaki Okazaki * @@ -19,7 +19,7 @@ * */ -/* $Id$ */ +/* $Id:$ */ #ifndef __ITUNESDB_H__ #define __ITUNESDB_H__ @@ -244,12 +244,52 @@ const void* base; } sorted_index_t; -int itunesdb_init(itunesdb_chunk_t* chunk, const char *name, const char *subtype); +/** + * Initialize a chunk with identifier and subtype (for "mhod" chunk) + * @param chunk The pointer to itunesdb_chunk_t to be initialized. + * @param identifer Chunk identifier. + * @param subtype Chunk sub-type for "mhod" chunk. + * @retval int zero if succeeded, otherwise nonzero. + */ +int itunesdb_init(itunesdb_chunk_t* chunk, const char *identifer, const char *subtype); + +/** + * Create a new chunk and append it to the children of the parent chunk. + * @param chunk The chunk where a new child will be appended. + * @retval itunesdb_chunk_t* Pointer to the new chunk if succeeded, otherwise NULL. + */ itunesdb_chunk_t* itunesdb_new_child(itunesdb_chunk_t* chunk); + +/** + * Uninitialize a chunk. + * @param chunk The pointer to itunesdb_chunk_t to be freed. + */ void itunesdb_finish(itunesdb_chunk_t* chunk); +/** + * Set UCS-2 string to "mhod" chunk. + * @param chunk The pointer to "mhod" chunk. + * @param str The pointer to UCS-2 string. + * @retval int zero if succeeded, otherwise nonzero. + */ int itunesdb_set_mhod_string(itunesdb_chunk_t* chunk, const ucs2char_t* str); -int itunesdb_set_mhod_index(itunesdb_chunk_t* chunk, uint32_t type, sorted_index_t* si, uint32_t n); + +/** + * Set sorted index to "mhod" chunk. + * @param chunk The pointer to "mhod" chunk. + * @param sort_order The sort order. + * @param si The sorted index. + * @param n The number of entries in the sorted index. + * @retval int zero if succeeded, otherwise nonzero. + */ +int itunesdb_set_mhod_index(itunesdb_chunk_t* chunk, uint32_t sort_order, sorted_index_t* si, uint32_t n); + +/** + * Set ordinal value to "mhod" chunk. + * @param chunk The pointer to "mhod" chunk. + * @param order The ordinal value. + * @retval int zero if succeeded, otherwise nonzero. + */ int itunesdb_set_mhod_playlist_order(itunesdb_chunk_t* chunk, uint32_t order); int itunesdb_repr(itunesdb_chunk_t* chunk, size_t index, serializer_t* sio); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-02-27 14:18:07
|
Revision: 398 http://svn.sourceforge.net/pmplib/?rev=398&view=rev Author: nyaochi Date: 2007-02-27 06:15:54 -0800 (Tue, 27 Feb 2007) Log Message: ----------- Automatic detection of iPod player by issuing SCSI INQUIRY commands to the device. The detection mechanism is based on the information available at: http://www.ipodlinux.org/Device_Information This code might not work with iPod generation 3 or earlier. The routine to manipulate SCSI devices uses SPTI WinNT API (for Windows 2000/XP/Vista). This code will not run on Win9x environments. The source code "ipodprop_win32spti.c" requires Windows DDK to be compiled; I generated ipodprop_win32spti.lib for those who do not install DDK. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/ipod.h trunk/pmplib/lib/pmp_ipod/pmp_ipod.c trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj Added Paths: ----------- trunk/pmplib/lib/pmp_ipod/ipodprop.h trunk/pmplib/lib/pmp_ipod/win32spti/ trunk/pmplib/lib/pmp_ipod/win32spti/README.txt trunk/pmplib/lib/pmp_ipod/win32spti/ipodprop_win32spti.c trunk/pmplib/lib/pmp_ipod/win32spti/ipodprop_win32spti.lib trunk/pmplib/lib/pmp_ipod/win32spti/makefile trunk/pmplib/lib/pmp_ipod/win32spti/sources Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-27 09:45:39 UTC (rev 397) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-27 14:15:54 UTC (rev 398) @@ -37,6 +37,7 @@ #include "serialize.h" #include "util.h" #include "ipod.h" +#include "ipodprop.h" #include "itunesdb.h" #define COMP(a, b) ((a)>(b))-((a)<(b)) @@ -60,8 +61,66 @@ }, }; -const ipod_descriptor_t* ipod_detect(const ucs2char_t* path_to_device, const char *id) +static int get_string_value(const char *xml, const char *key, char *value, size_t size) { + char *p, *q, *r; + char *keystr = (char*)alloca(strlen(key) + 5 + 6 + 1); + static const char *xeo_string = "<string>"; + static const char *xee_string = "</string>"; + + sprintf(keystr, "<key>%s</key>", key); + p = strstr(xml, keystr); + if (p) { + q = strstr(p += strlen(keystr), xeo_string); + if (q) { + r = strstr(q += strlen(xeo_string), xee_string); + if (r && (size_t)(r - q) < size) { + strncpy(value, q, r-q); + value[r-q] = 0; + return 0; + } + } + } + return -1; +} + +static int detect_model( + const ucs2char_t* path_to_device, + const ipod_descriptor_t* md, + pmp_device_information_t* ptr_info + ) +{ + int ret = 0; + ipodprop_t ip; + char *path = ucs2dupmbs(path_to_device); + + ipodprop_init(&ip); + + if (ipodprop_get(path, &ip) == 0) { + if (ip.vendor && strncmp(ip.vendor, "Apple", 5) == 0 && + ip.product && strncmp(ip.product, "iPod", 4) == 0) { + /* This is iPod. */ + ret = 1; + + /* Obtain the version number from the XML. */ + if (ip.info) { + get_string_value(ip.info, "VisibleBuildID", (char*)ptr_info->decl.version, PMP_DECLSIZE); + get_string_value(ip.info, "Language", (char*)ptr_info->decl.language, PMP_DECLSIZE); + } + } + } + + ipodprop_finish(&ip); + ucs2free(path); + return ret; +} + +const ipod_descriptor_t* ipod_detect( + const ucs2char_t* path_to_device, + const char *id, + pmp_device_information_t* ptr_info + ) +{ const ipod_descriptor_t* md = NULL; // Find a suitable model for the device. @@ -70,8 +129,15 @@ if (id && *id) { // Match the device identifier. if (strcmp(md->id, id) == 0) { + // This will fill some members in decl. + detect_model(path_to_device, md, ptr_info); break; } + } else { + // Detect the model automatically. + if (detect_model(path_to_device, md, ptr_info)) { + break; + } } } return md->id ? md : NULL; @@ -123,6 +189,7 @@ result_t ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb) { + result_t ret = 0; FILE *fp = NULL; serializer_t sio; @@ -130,11 +197,15 @@ itunesdb_write(ipod->itunesdb, &sio); fp = ucs2fopen(itunesdb, "wb"); - fwrite(sio.base, 1, sio.offset, fp); - fclose(fp); + if (fp) { + fwrite(sio.base, 1, sio.offset, fp); + fclose(fp); + } else { + ret = PMPERR_OPENFORWRITE; + } serialize_finish(&sio); - return 0; + return ret; } result_t ipod_dump(ipod_t* ipod, FILE *fpo) Modified: trunk/pmplib/lib/pmp_ipod/ipod.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.h 2007-02-27 09:45:39 UTC (rev 397) +++ trunk/pmplib/lib/pmp_ipod/ipod.h 2007-02-27 14:15:54 UTC (rev 398) @@ -48,7 +48,7 @@ itunesdb_chunk_t* itunesdb; } ipod_t; -const ipod_descriptor_t* ipod_detect(const ucs2char_t* path_to_device, const char *id); +const ipod_descriptor_t* ipod_detect(const ucs2char_t* path_to_device, const char *id, pmp_device_information_t* ptr_info); const ipod_descriptor_t* ipod_next_descriptor(const ipod_descriptor_t* md); void ipod_init(ipod_t* ipod); Added: trunk/pmplib/lib/pmp_ipod/ipodprop.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipodprop.h (rev 0) +++ trunk/pmplib/lib/pmp_ipod/ipodprop.h 2007-02-27 14:15:54 UTC (rev 398) @@ -0,0 +1,45 @@ +/* + * iPod property retrieval. + * + * Copyright (c) 2005-2007 Naoaki Okazaki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit + * http://www.gnu.org/copyleft/gpl.html . + * + */ + +/* $Id:$ */ + +#ifndef __IPODPROP_H__ +#define __IPODPROP_H__ + +#ifdef _WIN32 +#define IPODPROPAPI __cdecl +#else +#define IPODPROPAPI +#endif/*_WIN32*/ + +typedef struct { + char* vendor; + char* product; + char* revision; + char* info; +} ipodprop_t; + +void IPODPROPAPI ipodprop_init(ipodprop_t *prop); +void IPODPROPAPI ipodprop_finish(ipodprop_t *prop); +int IPODPROPAPI ipodprop_get(const char *path_to_root, ipodprop_t *prop); + +#endif/*__IPODPROP_H__*/ Property changes on: trunk/pmplib/lib/pmp_ipod/ipodprop.h ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-27 09:45:39 UTC (rev 397) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-27 14:15:54 UTC (rev 398) @@ -185,7 +185,7 @@ *ptr_pmp = 0; // Find a suitable model for the device. - md = ipod_detect(path_to_device, id); + md = ipod_detect(path_to_device, id, &info); if (!md) { return PMPERR_DEVICENOTFOUND; } Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-02-27 09:45:39 UTC (rev 397) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-02-27 14:15:54 UTC (rev 398) @@ -61,6 +61,7 @@ /> <Tool Name="VCLinkerTool" + AdditionalDependencies=".\win32spti\ipodprop_win32spti.lib shlwapi.lib" LinkIncremental="2" GenerateDebugInformation="true" SubSystem="2" @@ -193,10 +194,6 @@ > </File> <File - RelativePath=".\settledb.c" - > - </File> - <File RelativePath=".\util.c" > </File> @@ -211,15 +208,15 @@ > </File> <File - RelativePath=".\itunesdb.h" + RelativePath=".\ipodprop.h" > </File> <File - RelativePath=".\serialize.h" + RelativePath=".\itunesdb.h" > </File> <File - RelativePath=".\settledb.h" + RelativePath=".\serialize.h" > </File> <File Added: trunk/pmplib/lib/pmp_ipod/win32spti/README.txt =================================================================== --- trunk/pmplib/lib/pmp_ipod/win32spti/README.txt (rev 0) +++ trunk/pmplib/lib/pmp_ipod/win32spti/README.txt 2007-02-27 14:15:54 UTC (rev 398) @@ -0,0 +1 @@ +This source code requires Microsoft Windows DDK to be compiled. Property changes on: trunk/pmplib/lib/pmp_ipod/win32spti/README.txt ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Added: trunk/pmplib/lib/pmp_ipod/win32spti/ipodprop_win32spti.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/win32spti/ipodprop_win32spti.c (rev 0) +++ trunk/pmplib/lib/pmp_ipod/win32spti/ipodprop_win32spti.c 2007-02-27 14:15:54 UTC (rev 398) @@ -0,0 +1,286 @@ +/* + * iPod property retrieval through Win32 SPTI (for 2000/XP/Vista). + * + * Copyright (c) 2005-2007 Naoaki Okazaki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit + * http://www.gnu.org/copyleft/gpl.html . + * + */ + +/* I used the following information to access to the property of + * iPod players: + * http://www.ipodlinux.org/Device_Information + * + * This source code is based on the sample program found in Windows + * DDK, Enumdisk.c written by Raju Ramanathan. + */ + +/* $Id:$ */ + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <windows.h> +#include <shlwapi.h> +#include <devioctl.h> +#include <ntdddisk.h> +#include <ntddscsi.h> + +#include "../ipodprop.h" + + + +#define CDB6GENERIC_LENGTH 6 +#define CDB10GENERIC_LENGTH 10 + +#define SCSIOP_INQUIRY 0x12 + +typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS { + SCSI_PASS_THROUGH Spt; + ULONG Filler; + UCHAR SenseBuf[32]; + UCHAR DataBuf[512]; +} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS; + + + +void __cdecl ipodprop_init(ipodprop_t *prop) +{ + memset(prop, 0, sizeof(*prop)); +} + +void __cdecl ipodprop_finish(ipodprop_t *prop) +{ + free(prop->vendor); + free(prop->product); + free(prop->revision); + free(prop->info); + memset(prop, 0, sizeof(*prop)); +} + +int __cdecl ipodprop_get(const char *path_to_root, ipodprop_t *prop) +{ + int ret = 0; + DWORD i; + int j, k, n; + BOOL status; + UCHAR *p, outBuf[512]; + STORAGE_PROPERTY_QUERY query; + PSTORAGE_DEVICE_DESCRIPTOR devDesc; + SCSI_PASS_THROUGH_WITH_BUFFERS sptwb; + HANDLE hDevice = INVALID_HANDLE_VALUE; + ULONG length = 0, returned = 0; + int num_pages = 0; + UCHAR pages[256]; + size_t info_size = 0; + CHAR drive[7]; + + memset(pages, 0, sizeof(pages)); + + /* Obtain the drive letter. */ + drive[0] = '\\'; + drive[1] = '\\'; + drive[2] = '.'; + drive[3] = '\\'; + drive[4] = 'A' + PathGetDriveNumber(path_to_root); + drive[5] = ':'; + drive[6] = 0; + + /* Open the device. */ + hDevice = CreateFile( + drive, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + if (hDevice == INVALID_HANDLE_VALUE) { + ret = -1; + goto error_exit; + } + + /* Query the property of the device. */ + query.PropertyId = StorageDeviceProperty; + query.QueryType = PropertyStandardQuery; + status = DeviceIoControl( + hDevice, + IOCTL_STORAGE_QUERY_PROPERTY, + &query, + sizeof(STORAGE_PROPERTY_QUERY), + &outBuf, + 512, + &returned, + NULL + ); + if (!status) { + ret = -1; + goto error_exit; + } + + /* Obtain vendor, product and revision of the device. */ + devDesc = (PSTORAGE_DEVICE_DESCRIPTOR)outBuf; + p = (PUCHAR)outBuf; + if (devDesc->VendorIdOffset && p[devDesc->VendorIdOffset]) { + for (n = 0, i = devDesc->VendorIdOffset;p[i] && i < returned;i++) { + n++; + } + prop->vendor = (char*)calloc(n+1, sizeof(char)); + strncpy(prop->vendor, &p[devDesc->VendorIdOffset], n); + } + if (devDesc->ProductIdOffset && p[devDesc->ProductIdOffset]) { + for (n = 0, i = devDesc->ProductIdOffset;p[i] && i < returned;i++) { + n++; + } + prop->product = (char*)calloc(n+1, sizeof(char)); + strncpy(prop->product, &p[devDesc->ProductIdOffset], n); + } + + if ( devDesc->ProductRevisionOffset && p[devDesc->ProductRevisionOffset] ) { + for (n = 0, i = devDesc->ProductRevisionOffset;p[i] && i < returned;i++) { + n++; + } + prop->revision = (char*)calloc(n+1, sizeof(char)); + strncpy(prop->revision, &p[devDesc->ProductRevisionOffset], n); + } + + /* Access to SCSI INQUIRY page 0xC0. */ + ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS)); + sptwb.Spt.Length = sizeof(SCSI_PASS_THROUGH); + sptwb.Spt.PathId = 0; + sptwb.Spt.TargetId = 1; + sptwb.Spt.Lun = 0; + sptwb.Spt.CdbLength = CDB6GENERIC_LENGTH; + sptwb.Spt.SenseInfoLength = 24; + sptwb.Spt.DataIn = SCSI_IOCTL_DATA_IN; + sptwb.Spt.DataTransferLength = 255; + sptwb.Spt.TimeOutValue = 2; + sptwb.Spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,DataBuf); + sptwb.Spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,SenseBuf); + sptwb.Spt.Cdb[0] = SCSIOP_INQUIRY; + sptwb.Spt.Cdb[1] = 0x01; + sptwb.Spt.Cdb[2] = 0xC0; + sptwb.Spt.Cdb[4] = 255; + length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,DataBuf) + sptwb.Spt.DataTransferLength; + + status = DeviceIoControl(hDevice, + IOCTL_SCSI_PASS_THROUGH, + &sptwb, + sizeof(SCSI_PASS_THROUGH), + &sptwb, + length, + &returned, + FALSE + ); + + if (!status) { + ret = -1; + goto error_exit; + } + + /* Obtain the number of pages and list of pages. */ + num_pages = (int)sptwb.DataBuf[3]; + for (j = 0;j < num_pages;++j) { + pages[j] = sptwb.DataBuf[j+4]; + } + + /* Access to all pages available. */ + for (j = 0;j < num_pages;++j) { + ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS)); + sptwb.Spt.Length = sizeof(SCSI_PASS_THROUGH); + sptwb.Spt.PathId = 0; + sptwb.Spt.TargetId = 1; + sptwb.Spt.Lun = 0; + sptwb.Spt.CdbLength = CDB6GENERIC_LENGTH; + sptwb.Spt.SenseInfoLength = 24; + sptwb.Spt.DataIn = SCSI_IOCTL_DATA_IN; + sptwb.Spt.DataTransferLength = 255; + sptwb.Spt.TimeOutValue = 2; + sptwb.Spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,DataBuf); + sptwb.Spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,SenseBuf); + sptwb.Spt.Cdb[0] = SCSIOP_INQUIRY; + sptwb.Spt.Cdb[1] = 0x01; + sptwb.Spt.Cdb[2] = pages[j]; + sptwb.Spt.Cdb[4] = 255; + length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,DataBuf) + + sptwb.Spt.DataTransferLength; + + status = DeviceIoControl(hDevice, + IOCTL_SCSI_PASS_THROUGH, + &sptwb, + sizeof(SCSI_PASS_THROUGH), + &sptwb, + length, + &returned, + FALSE + ); + + if (!status) { + ret = -1; + goto error_exit; + } + + /* Obtain the number of characters in this page. */ + n = (int)sptwb.DataBuf[3]; + /* Expand the buffer storing the information. */ + prop->info = realloc(prop->info, sizeof(char) * (info_size + n + 1)); + /* Storing the information in the current page. */ + for (k = 0;k < n;++k) { + prop->info[info_size+k] = sptwb.DataBuf[k+4]; + } + info_size += n; + prop->info[info_size] = 0; + } + + if (!CloseHandle(hDevice)) { + ret = -1; + goto error_exit; + } + return 0; + +error_exit: + free(prop->vendor); + free(prop->product); + free(prop->revision); + free(prop->info); + memset(prop, 0, sizeof(*prop)); + if (hDevice != INVALID_HANDLE_VALUE) { + CloseHandle(hDevice); + } + return ret; +} + +#if 0 +int __cdecl main(int argc, char *argv[]) +{ + ipodprop_t prop; + + ipodprop_init(&prop); + + if (ipodprop_get("D:\\", &prop) == 0) { + if (prop.vendor) printf("Vendor: %s\n", prop.vendor); + if (prop.product) printf("Product: %s\n", prop.product); + if (prop.revision) printf("Revision: %s\n", prop.revision); + if (prop.info) printf("Info:\n%s\n", prop.info); + } + + ipodprop_finish(&prop); + + return 0; +} +#endif Property changes on: trunk/pmplib/lib/pmp_ipod/win32spti/ipodprop_win32spti.c ___________________________________________________________________ Name: svn:keywords + Id Added: trunk/pmplib/lib/pmp_ipod/win32spti/ipodprop_win32spti.lib =================================================================== (Binary files differ) Property changes on: trunk/pmplib/lib/pmp_ipod/win32spti/ipodprop_win32spti.lib ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/pmplib/lib/pmp_ipod/win32spti/makefile =================================================================== --- trunk/pmplib/lib/pmp_ipod/win32spti/makefile (rev 0) +++ trunk/pmplib/lib/pmp_ipod/win32spti/makefile 2007-02-27 14:15:54 UTC (rev 398) @@ -0,0 +1,8 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the driver components of the Windows NT DDK +# + +!INCLUDE $(NTMAKEENV)\makefile.def + Added: trunk/pmplib/lib/pmp_ipod/win32spti/sources =================================================================== --- trunk/pmplib/lib/pmp_ipod/win32spti/sources (rev 0) +++ trunk/pmplib/lib/pmp_ipod/win32spti/sources 2007-02-27 14:15:54 UTC (rev 398) @@ -0,0 +1,8 @@ +TARGETNAME=ipodprop_win32spti +TARGETTYPE=LIBRARY + +TARGETPATH=obj + +TARGETLIBS=$(DDK_LIB_PATH)\user32.lib $(DDK_LIB_PATH)\shlwapi.lib + +SOURCES=ipodprop_win32spti.c This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-02-28 08:17:04
|
Revision: 401 http://svn.sourceforge.net/pmplib/?rev=401&view=rev Author: nyaochi Date: 2007-02-28 00:17:04 -0800 (Wed, 28 Feb 2007) Log Message: ----------- Added reader/dumper for "Play Count" file. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/ipod.h trunk/pmplib/lib/pmp_ipod/pmp_ipod.c trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj Added Paths: ----------- trunk/pmplib/lib/pmp_ipod/playcounts.c trunk/pmplib/lib/pmp_ipod/playcounts.h Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-27 15:20:57 UTC (rev 400) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-02-28 08:17:04 UTC (rev 401) @@ -39,6 +39,7 @@ #include "ipod.h" #include "ipodprop.h" #include "itunesdb.h" +#include "playcounts.h" #define COMP(a, b) ((a)>(b))-((a)<(b)) @@ -47,6 +48,7 @@ "apple_ipod", "Apple", "iPod", "UM", "---", "---", "iPod_Control\\iTunes\\iTunesDB", + "iPod_Control\\iTunes\\Play Counts", ".mp3\0.m4a\0", {PMPCODEC_MPEGLAYER3, PMPCODEC_MPEG4AUDIO, 0, 0, 0, 0, 0, 0}, "iPod_Control", "iPod_Control\\Music", "Playlists", @@ -56,6 +58,7 @@ NULL, NULL, NULL, NULL, + NULL, {0, 0, 0, 0, 0, 0, 0, 0}, NULL, NULL, NULL, }, @@ -155,19 +158,23 @@ void ipod_init(ipod_t* ipod) { - ipod->itunesdb = calloc(1, sizeof(itunesdb_chunk_t)); + ipod->itunesdb = (itunesdb_chunk_t*)calloc(1, sizeof(itunesdb_chunk_t)); + ipod->pcs = (playcounts_t*)calloc(1, sizeof(playcounts_t)); } void ipod_finish(ipod_t* ipod) { + playcounts_finish(ipod->pcs); itunesdb_finish(ipod->itunesdb); + free(ipod->pcs); free(ipod->itunesdb); } -result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb) +result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts) { FILE *fp = NULL; + /* Read iTunesDB. */ fp = ucs2fopen(itunesdb, "rb"); if (fp) { serializer_t sio; @@ -179,12 +186,28 @@ serialize_init_read(&sio, buffer, (size_t)size); itunesdb_read(ipod->itunesdb, &sio); - serialize_finish(&sio); + serialize_finish(&sio); /* This will free the buffer. */ + } else { + return 1; + } - return 0; + /* Read "Play Counts". */ + fp = ucs2fopen(playcounts, "rb"); + if (fp) { + serializer_t sio; + uint8_t* buffer = NULL; + long size = 0; + + fread_all(fp, &buffer, &size); + fclose(fp); + + serialize_init_read(&sio, buffer, (size_t)size); + playcounts_serialize(ipod->pcs, &sio); + serialize_finish(&sio); /* This will free the buffer. */ } else { return 1; } + return 0; } result_t ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb) @@ -212,7 +235,15 @@ { serializer_t sio; serialize_init_dump(&sio, fpo, 2); + + fprintf(fpo, "[iTunesDB]\n"); itunesdb_repr(ipod->itunesdb, 0, &sio); + fprintf(fpo, "\n"); + + fprintf(fpo, "[Play Counts]\n"); + playcounts_serialize(ipod->pcs, &sio); + fprintf(fpo, "\n"); + serialize_finish(&sio); return 0; } Modified: trunk/pmplib/lib/pmp_ipod/ipod.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.h 2007-02-27 15:20:57 UTC (rev 400) +++ trunk/pmplib/lib/pmp_ipod/ipod.h 2007-02-28 08:17:04 UTC (rev 401) @@ -34,6 +34,7 @@ const char *min_version; const char *max_version; const char *itunesdb_filename; + const char *playcounts_filename; const char *extensions; uint32_t codecs[8]; const char *path_to_system; @@ -44,8 +45,12 @@ struct tag_itunesdb_chunk; typedef struct tag_itunesdb_chunk itunesdb_chunk_t; +struct tag_playcounts; +typedef struct tag_playcounts playcounts_t; + typedef struct { itunesdb_chunk_t* itunesdb; + playcounts_t* pcs; } ipod_t; const ipod_descriptor_t* ipod_detect(const ucs2char_t* path_to_device, const char *id, pmp_device_information_t* ptr_info); @@ -54,7 +59,7 @@ void ipod_init(ipod_t* ipod); void ipod_finish(ipod_t* ipod); result_t ipod_set(ipod_t* ipod, const pmp_music_record_t* records, int num_records, const pmp_playlist_t* playlists, int num_playlists); -result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb); +result_t ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts); result_t ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb); result_t ipod_dump(ipod_t* ipod, FILE *fpo); Added: trunk/pmplib/lib/pmp_ipod/playcounts.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/playcounts.c (rev 0) +++ trunk/pmplib/lib/pmp_ipod/playcounts.c 2007-02-28 08:17:04 UTC (rev 401) @@ -0,0 +1,147 @@ +/* + * Reader and dumper for "Play Counts" file. + * + * Copyright (c) 2005-2007 Naoaki Okazaki + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* $Id:$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif/*HAVE_CONFIG_H*/ + +#include <os.h> +#include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_STRING_H +#include <string.h> +#endif/*HAVE_STRING_H*/ +#include <pmplib/ucs2char.h> + +#include "ipod.h" +#include "serialize.h" +#include "util.h" +#include "playcounts.h" + +static void playcount_init(playcount_entry_t* entry) +{ + memset(entry, 0, sizeof(*entry)); +} + +static int playcount_serialize(playcount_entry_t* entry, const playcounts_t* pcs, serializer_t* sio) +{ + size_t begin = serialize_tell(sio); + + if (serialize_uint32le(sio, "play_count", "%u", &entry->play_count)) return 1; + if (serialize_uint32le(sio, "last_played", "%u", &entry->last_played)) return 1; + if (serialize_uint32le(sio, "audio_bookmark", "%u", &entry->audio_bookmark)) return 1; + + if (serialize_reading(sio) && begin + pcs->entry_size <= serialize_tell(sio)) return 0; + if (serialize_uint32le(sio, "rating", "%u", &entry->rating)) return 1; + + if (serialize_reading(sio) && begin + pcs->entry_size <= serialize_tell(sio)) return 0; + if (serialize_uint32le(sio, "unknown", "%u", &entry->unknown)) return 1; + + if (serialize_reading(sio) && begin + pcs->entry_size <= serialize_tell(sio)) return 0; + if (serialize_uint32le(sio, "skip_count", "%u", &entry->skip_count)) return 1; + if (serialize_uint32le(sio, "last_skipped", "%u", &entry->last_skipped)) return 1; + + /* Padding data if any. */ + if (serialize_reading(sio)) { + if (serialize_tell(sio) < begin + pcs->entry_size) { + entry->padding_size = pcs->entry_size - (serialize_tell(sio) - begin); + entry->padding = (uint8_t*)calloc(entry->padding_size, 1); + } + } + if (entry->padding) { + if (serialize_uint8_array(sio, "padding", "%02X ", entry->padding, entry->padding_size)) return 1; + } + + return 0; +} + +void playcounts_init(playcounts_t* pcs) +{ + memset(pcs, 0, sizeof(*pcs)); + strncpy(pcs->id, "mhdp", 4); + pcs->header_size = 0x60; + pcs->entry_size = 0x1C; +} + +void playcounts_finish(playcounts_t* pcs) +{ + free(pcs->entries); +} + +int playcounts_serialize(playcounts_t* pcs, serializer_t* sio) +{ + uint32_t i; + size_t begin = serialize_tell(sio); + + if (serialize_reading(sio)) { + if (serialize_uint8_array(sio, "id", "%c ", pcs->id, sizeof(pcs->id))) return 1; + } else if (serialize_dumping(sio)) { + serialize_indent(sio); + fprintf(sio->fp, "Chunk %c%c%c%c = {\n", pcs->id[0], pcs->id[1], pcs->id[2], pcs->id[3]); + } + serialize_indent_ascend(sio); + + if (serialize_uint32le(sio, "header_size", "%u", &pcs->header_size)) return 1; + if (serialize_uint32le(sio, "entry_size", "%u", &pcs->entry_size)) return 1; + if (serialize_uint32le(sio, "num_entries", "%u", &pcs->num_entries)) return 1; + + /* Padding data if any. */ + if (serialize_reading(sio)) { + if (serialize_tell(sio) < begin + pcs->header_size) { + pcs->padding_size = pcs->header_size - (serialize_tell(sio) - begin); + pcs->padding = (uint8_t*)calloc(pcs->padding_size, 1); + } + } + if (pcs->padding) { + if (serialize_uint8_array(sio, "padding", "%02X ", pcs->padding, pcs->padding_size)) return 1; + } + + if (serialize_reading(sio)) { + pcs->entries = (playcount_entry_t*)calloc(pcs->num_entries, sizeof(playcount_entry_t)); + for (i = 0;i < pcs->num_entries;++i) { + playcount_init(&pcs->entries[i]); + } + } + + for (i = 0;i < pcs->num_entries;++i) { + if (serialize_dumping(sio)) { + serialize_indent(sio); + fprintf(sio->fp, "entry (%d) = {\n", i); + serialize_indent_ascend(sio); + } + if (playcount_serialize(&pcs->entries[i], pcs, sio)) return 1; + if (serialize_dumping(sio)) { + serialize_indent_descend(sio); + serialize_indent(sio); + fprintf(sio->fp, "}\n"); + } + } + + serialize_indent_descend(sio); + if (serialize_dumping(sio)) { + serialize_indent(sio); + fprintf(sio->fp, "}\n"); + } + + return 0; +} Property changes on: trunk/pmplib/lib/pmp_ipod/playcounts.c ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Added: trunk/pmplib/lib/pmp_ipod/playcounts.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/playcounts.h (rev 0) +++ trunk/pmplib/lib/pmp_ipod/playcounts.h 2007-02-28 08:17:04 UTC (rev 401) @@ -0,0 +1,54 @@ +/* + * Reader and dumper for "Play Counts" file. + * + * Copyright (c) 2005-2007 Naoaki Okazaki + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* $Id:$ */ + +#ifndef __PLAYCOUNTS_H__ +#define __PLAYCOUNTS_H__ + +typedef struct { + uint32_t play_count; + uint32_t last_played; + uint32_t audio_bookmark; + uint32_t rating; + uint32_t unknown; + uint32_t skip_count; + uint32_t last_skipped; + + int32_t padding_size; + uint8_t* padding; +} playcount_entry_t; + +struct tag_playcounts { + int8_t id[4]; + uint32_t header_size; + uint32_t entry_size; + uint32_t num_entries; + int32_t padding_size; + uint8_t* padding; + playcount_entry_t* entries; +}; + +void playcounts_init(playcounts_t* pcs); +void playcounts_finish(playcounts_t* pcs); +int playcounts_serialize(playcounts_t* pcs, serializer_t* sio); + +#endif/*__PLAYCOUNTS_H__*/ Property changes on: trunk/pmplib/lib/pmp_ipod/playcounts.h ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-27 15:20:57 UTC (rev 400) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-02-28 08:17:04 UTC (rev 401) @@ -145,16 +145,25 @@ memset(info, 0, sizeof(*info)); } -static void set_filenames(ucs2char_t *itunesdb, pmp_t *pmp) +static void set_filenames(ucs2char_t *itunesdb, ucs2char_t* playcounts, pmp_t *pmp) { ucs2char_t* ucs2 = NULL; pmp_internal_t* pmpi = (pmp_internal_t*)pmp->instance; - ucs2cpy(itunesdb, pmp->info.path_to_root); - filepath_addslash(itunesdb); - ucs2 = mbsdupucs2(pmpi->decl->itunesdb_filename); - ucs2cat(itunesdb, ucs2); - ucs2free(ucs2); + if (itunesdb) { + ucs2cpy(itunesdb, pmp->info.path_to_root); + filepath_addslash(itunesdb); + ucs2 = mbsdupucs2(pmpi->decl->itunesdb_filename); + ucs2cat(itunesdb, ucs2); + ucs2free(ucs2); + } + if (playcounts) { + ucs2cpy(playcounts, pmp->info.path_to_root); + filepath_addslash(playcounts); + ucs2 = mbsdupucs2(pmpi->decl->playcounts_filename); + ucs2cat(playcounts, ucs2); + ucs2free(ucs2); + } } @@ -404,13 +413,13 @@ result_t ret = 0; pmp_t* pmp = music->pmp; pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; - ucs2char_t itunesdb[MAX_PATH]; + ucs2char_t itunesdb[MAX_PATH], playcounts[MAX_PATH]; // Initialize ipod library. ipod_init(&ipod); // Read the music database. - set_filenames(itunesdb, music->pmp); + set_filenames(itunesdb, playcounts, music->pmp); if (pmp->flag & PMPOF_MUSIC_DB_WRITE) { ipod_set(&ipod, pmpmi->records, pmpmi->num_records, pmpmi->playlists, pmpmi->num_playlists); @@ -458,14 +467,14 @@ { ipod_t ipod; result_t ret = 0; - ucs2char_t itunesdb[MAX_PATH]; + ucs2char_t itunesdb[MAX_PATH], playcounts[MAX_PATH]; // Initialize IP3DB. ipod_init(&ipod); // Read the music database. - set_filenames(itunesdb, music->pmp); - ret = ipod_read(&ipod, itunesdb); + set_filenames(itunesdb, playcounts, music->pmp); + ret = ipod_read(&ipod, itunesdb, playcounts); if (ret) { goto exit_this; } Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-02-27 15:20:57 UTC (rev 400) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-02-28 08:17:04 UTC (rev 401) @@ -186,6 +186,10 @@ > </File> <File + RelativePath=".\playcounts.c" + > + </File> + <File RelativePath=".\pmp_ipod.c" > </File> @@ -216,6 +220,10 @@ > </File> <File + RelativePath=".\playcounts.h" + > + </File> + <File RelativePath=".\serialize.h" > </File> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-09-12 14:25:34
|
Revision: 409 http://pmplib.svn.sourceforge.net/pmplib/?rev=409&view=rev Author: nyaochi Date: 2007-09-12 07:25:36 -0700 (Wed, 12 Sep 2007) Log Message: ----------- - Added "itunes_" prefix to structure names - Initial attempt to support iTunes 7.4.1; database dump appears to work Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-05-12 02:26:41 UTC (rev 408) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-12 14:25:36 UTC (rev 409) @@ -290,7 +290,7 @@ { int ret = 0; itunesdb_chunk_t* mhod = NULL; - chunk_mhit_t* mhit_data = (chunk_mhit_t*)mhit->data; + itunesdb_mhit_t* mhit_data = (itunesdb_mhit_t*)mhit->data; mhit_data->uid = uid; mhit_data->visible = 1; @@ -418,7 +418,7 @@ uint32_t i; int ret = 0; itunesdb_chunk_t* mhod = NULL; - chunk_mhit_t* mhit_data = (chunk_mhit_t*)mhit->data; + itunesdb_mhit_t* mhit_data = (itunesdb_mhit_t*)mhit->data; switch (mhit_data->filetype) { case 0x4D503320: @@ -588,7 +588,7 @@ int i; int ret = 0; itunesdb_chunk_t *mhod = NULL, *mhip = NULL; - chunk_mhyp_t* mhyp_data = (chunk_mhyp_t*)mhyp->data; + itunesdb_mhyp_t* mhyp_data = (itunesdb_mhyp_t*)mhyp->data; sorted_index_t* si = (sorted_index_t*)calloc(num_records, sizeof(sorted_index_t)); const static ucs2char_t ucs2cs_master[] = {'M','a','s','t','e','r',0}; @@ -660,9 +660,9 @@ for (i = 0;i < num_records;++i) { mhip = itunesdb_new_child(mhyp); if (mhip) { - chunk_mhip_t* mhip_data = NULL; + itunesdb_mhip_t* mhip_data = NULL; if (ret = itunesdb_init(mhip, "mhip", NULL)) return ret; - mhip_data = (chunk_mhip_t*)mhip->data; + mhip_data = (itunesdb_mhip_t*)mhip->data; mhip_data->flag_podcast_group = 0; mhip_data->track_id = i; @@ -703,7 +703,7 @@ int i; int ret = 0; itunesdb_chunk_t *mhod = NULL, *mhip = NULL; - chunk_mhyp_t* mhyp_data = (chunk_mhyp_t*)mhyp->data; + itunesdb_mhyp_t* mhyp_data = (itunesdb_mhyp_t*)mhyp->data; mhyp_data->flag_master = 0; mhyp_data->id = 0x7520EA5FA870F9EA; @@ -728,9 +728,9 @@ if (index < num_records) { mhip = itunesdb_new_child(mhyp); if (mhip) { - chunk_mhip_t* mhip_data = NULL; + itunesdb_mhip_t* mhip_data = NULL; if (ret = itunesdb_init(mhip, "mhip", NULL)) return ret; - mhip_data = (chunk_mhip_t*)mhip->data; + mhip_data = (itunesdb_mhip_t*)mhip->data; mhip_data->flag_podcast_group = 0; mhip_data->track_id = index; @@ -769,7 +769,7 @@ itunesdb_chunk_t *mhbd = NULL, *mhsd = NULL; itunesdb_chunk_t *mhlt = NULL, *mhit = NULL; itunesdb_chunk_t *mhlp = NULL, *mhyp = NULL; - chunk_mhbd_t* mhbd_data = NULL; + itunesdb_mhbd_t* mhbd_data = NULL; /* Construct "mhbd" chunk. */ mhbd = (itunesdb_chunk_t*)calloc(1, sizeof(itunesdb_chunk_t)); @@ -777,14 +777,14 @@ return IPODE_FAILEDNEWCHUNK; } if (ret = itunesdb_init(mhbd, "mhbd", NULL)) return ret; - mhbd_data = (chunk_mhbd_t*)mhbd->data; + mhbd_data = (itunesdb_mhbd_t*)mhbd->data; /* Construct "mhsd" chunk with track type. */ mhsd = itunesdb_new_child(mhbd); if (mhsd) { - chunk_mhsd_t* mhsd_data = NULL; + itunesdb_mhsd_t* mhsd_data = NULL; if (ret = itunesdb_init(mhsd, "mhsd", NULL)) return ret; - mhsd_data = (chunk_mhsd_t*)mhsd->data; + mhsd_data = (itunesdb_mhsd_t*)mhsd->data; mhsd_data->type = 1; /* track type. */ /* Construct "mhlt" chunk. */ @@ -817,9 +817,9 @@ /* Construct "mhsd" chunk with playlist type. */ mhsd = itunesdb_new_child(mhbd); if (mhsd) { - chunk_mhsd_t* mhsd_data = NULL; + itunesdb_mhsd_t* mhsd_data = NULL; if (ret = itunesdb_init(mhsd, "mhsd", NULL)) return ret; - mhsd_data = (chunk_mhsd_t*)mhsd->data; + mhsd_data = (itunesdb_mhsd_t*)mhsd->data; mhsd_data->type = 2; /* playlist type. */ /* Construct "mhlp" chunk. */ @@ -830,7 +830,7 @@ /* Create a master playlist. */ mhyp = itunesdb_new_child(mhlp); if (mhyp) { - chunk_mhyp_t* mhyp_data = NULL; + itunesdb_mhyp_t* mhyp_data = NULL; if (ret = itunesdb_init(mhyp, "mhyp", NULL)) return ret; if (ret = set_master_playlist(mhyp, records, num_records)) return ret; } @@ -839,7 +839,7 @@ for (i = 0;i < num_playlists;++i) { mhyp = itunesdb_new_child(mhlp); if (mhyp) { - chunk_mhyp_t* mhyp_data = NULL; + itunesdb_mhyp_t* mhyp_data = NULL; if (ret = itunesdb_init(mhyp, "mhyp", NULL)) return ret; if (ret = set_playlist(mhyp, &playlists[i], records, num_records)) return ret; } else { @@ -883,7 +883,7 @@ for (i = 0;i < mhbd->num_children;++i) { mhsd = &mhbd->childlen[i]; if (mhsd && strncmp(mhsd->id, "mhsd", 4) == 0) { - chunk_mhsd_t* mhsd_data = (chunk_mhsd_t*)mhsd->data; + itunesdb_mhsd_t* mhsd_data = (itunesdb_mhsd_t*)mhsd->data; if (mhsd_data->type == 1) { /* Track list. */ for (j = 0;j < mhsd->num_children;++j) { Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-05-12 02:26:41 UTC (rev 408) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-12 14:25:36 UTC (rev 409) @@ -50,7 +50,7 @@ static int mhbd_init(itunesdb_chunk_t* chunk, int def) { - chunk_mhbd_t* mhbd = NULL; + itunesdb_mhbd_t* mhbd = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); @@ -59,7 +59,7 @@ chunk->overall_size = 0; /* to be filled */ } - mhbd = (chunk_mhbd_t*)calloc(1, sizeof(chunk_mhbd_t)); + mhbd = (itunesdb_mhbd_t*)calloc(1, sizeof(itunesdb_mhbd_t)); if (def && mhbd) { mhbd->unknown1 = 1; mhbd->version = 0x13; /* iTunes 7 */ @@ -78,7 +78,7 @@ static int mhbd_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { int ret = 0; - chunk_mhbd_t* mhbd = (chunk_mhbd_t*)chunk->data; + itunesdb_mhbd_t* mhbd = (itunesdb_mhbd_t*)chunk->data; if (ret = serialize_uint32le(sio, "unknown1", "%d", &mhbd->unknown1)) return ret; if (ret = serialize_uint32le(sio, "version", "%d", &mhbd->version)) return ret; @@ -97,7 +97,7 @@ static mhsd_init(itunesdb_chunk_t* chunk, int def) { - chunk_mhsd_t* mhsd = NULL; + itunesdb_mhsd_t* mhsd = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); @@ -106,7 +106,7 @@ chunk->overall_size = 0; /* to be filled */ } - mhsd = (chunk_mhsd_t*)calloc(1, sizeof(chunk_mhsd_t)); + mhsd = (itunesdb_mhsd_t*)calloc(1, sizeof(itunesdb_mhsd_t)); if (mhsd && def) { mhsd->type = 0; /* to be filled */ } @@ -118,7 +118,7 @@ static int mhsd_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { int ret = 0; - chunk_mhsd_t* mhsd = (chunk_mhsd_t*)chunk->data; + itunesdb_mhsd_t* mhsd = (itunesdb_mhsd_t*)chunk->data; if (ret = serialize_uint32le(sio, "type", "%d", &mhsd->type)) return ret; @@ -127,9 +127,68 @@ +static mhla_init(itunesdb_chunk_t* chunk, int def) +{ + itunesdb_mhla_t* mhla = NULL; + + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhla", 4); + chunk->size = 92; + chunk->overall_size = 0; /* to be filled */ + } + mhla = (itunesdb_mhla_t*)calloc(1, sizeof(itunesdb_mhla_t)); + + chunk->data = mhla; + return mhla ? 0 : IPODE_OUTOFMEMORY; +} + +static int mhla_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) +{ + int ret = 0; + itunesdb_mhla_t* mhla = (itunesdb_mhla_t*)chunk->data; + + if (ret = serialize_uint8(sio, "unknown", "%02X", &mhla->unknown)) return ret; + + return 0; +} + + + +static mhia_init(itunesdb_chunk_t* chunk, int def) +{ + itunesdb_mhia_t* mhia = NULL; + + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhia", 4); + chunk->size = 88; + chunk->overall_size = 0; /* to be filled */ + } + mhia = (itunesdb_mhia_t*)calloc(1, sizeof(itunesdb_mhia_t)); + + chunk->data = mhia; + return mhia ? 0 : IPODE_OUTOFMEMORY; +} + +static int mhia_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) +{ + int ret = 0; + itunesdb_mhia_t* mhia = (itunesdb_mhia_t*)chunk->data; + + if (ret = serialize_uint32le(sio, "num_children", "%u", &mhia->num_children)) return ret; + if (ret = serialize_uint32le(sio, "album_id", "%u", &mhia->album_id)) return ret; + if (ret = serialize_uint64le(sio, "timestamp", "%u", &mhia->timestamp)) return ret; + if (ret = serialize_uint32le(sio, "unknown1", "%u", &mhia->unknown1)) return ret; + + return 0; +} + + + static mhlt_init(itunesdb_chunk_t* chunk, int def) { - chunk_mhlt_t* mhlt = NULL; + itunesdb_mhlt_t* mhlt = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); @@ -137,7 +196,7 @@ chunk->size = 92; chunk->overall_size = 0; /* to be filled */ } - mhlt = (chunk_mhlt_t*)calloc(1, sizeof(chunk_mhlt_t)); + mhlt = (itunesdb_mhlt_t*)calloc(1, sizeof(itunesdb_mhlt_t)); chunk->data = mhlt; return mhlt ? 0 : IPODE_OUTOFMEMORY; @@ -146,7 +205,7 @@ static int mhlt_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { int ret = 0; - chunk_mhlt_t* mhlt = (chunk_mhlt_t*)chunk->data; + itunesdb_mhlt_t* mhlt = (itunesdb_mhlt_t*)chunk->data; if (ret = serialize_uint8(sio, "unknown", "%02X", &mhlt->unknown)) return ret; @@ -157,7 +216,7 @@ static mhit_init(itunesdb_chunk_t* chunk, int def) { - chunk_mhit_t* mhit = NULL; + itunesdb_mhit_t* mhit = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); @@ -166,7 +225,7 @@ chunk->overall_size = 0; /* to be filled */ } - mhit = (chunk_mhit_t*)calloc(1, sizeof(chunk_mhit_t)); + mhit = (itunesdb_mhit_t*)calloc(1, sizeof(itunesdb_mhit_t)); if (mhit && def) { mhit->visible = 1; /* visible by default */ /* other fields to be filled later */ @@ -179,7 +238,7 @@ static int mhit_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { int ret = 0; - chunk_mhit_t* mhit = (chunk_mhit_t*)chunk->data; + itunesdb_mhit_t* mhit = (itunesdb_mhit_t*)chunk->data; if (ret = serialize_uint32le(sio, "num_children", "%u", &mhit->num_children)) return ret; if (ret = serialize_uint32le(sio, "uid", "%u", &mhit->uid)) return ret; @@ -263,7 +322,7 @@ static mhlp_init(itunesdb_chunk_t* chunk, int def) { - chunk_mhlp_t* mhlp = NULL; + itunesdb_mhlp_t* mhlp = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); @@ -272,7 +331,7 @@ chunk->overall_size = 0; /* to be filled */ } - mhlp = (chunk_mhlp_t*)calloc(1, sizeof(chunk_mhlp_t)); + mhlp = (itunesdb_mhlp_t*)calloc(1, sizeof(itunesdb_mhlp_t)); chunk->data = mhlp; return mhlp ? 0 : IPODE_OUTOFMEMORY; } @@ -280,7 +339,7 @@ static int mhlp_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { int ret = 0; - chunk_mhlp_t* mhlp = (chunk_mhlp_t*)chunk->data; + itunesdb_mhlp_t* mhlp = (itunesdb_mhlp_t*)chunk->data; if (ret = serialize_uint8(sio, "unknown", "%02X", &mhlp->unknown)) return ret; @@ -291,7 +350,7 @@ static mhyp_init(itunesdb_chunk_t* chunk, int def) { - chunk_mhyp_t* mhyp = NULL; + itunesdb_mhyp_t* mhyp = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); @@ -300,7 +359,7 @@ chunk->overall_size = 0; /* to be filled */ } - mhyp = (chunk_mhyp_t*)calloc(1, sizeof(chunk_mhyp_t)); + mhyp = (itunesdb_mhyp_t*)calloc(1, sizeof(itunesdb_mhyp_t)); chunk->data = mhyp; return mhyp ? 0 : IPODE_OUTOFMEMORY; } @@ -308,7 +367,7 @@ static int mhyp_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { int ret = 0; - chunk_mhyp_t* mhyp = (chunk_mhyp_t*)chunk->data; + itunesdb_mhyp_t* mhyp = (itunesdb_mhyp_t*)chunk->data; if (ret = serialize_uint32le(sio, "num_mhod", "%u", &mhyp->num_mhod)) return ret; if (ret = serialize_uint32le(sio, "num_mhip", "%u", &mhyp->num_mhip)) return ret; @@ -330,7 +389,7 @@ static mhip_init(itunesdb_chunk_t* chunk, int def) { - chunk_mhip_t* mhip = NULL; + itunesdb_mhip_t* mhip = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); @@ -339,7 +398,7 @@ chunk->overall_size = 0; /* to be filled */ } - mhip = (chunk_mhip_t*)calloc(1, sizeof(chunk_mhip_t)); + mhip = (itunesdb_mhip_t*)calloc(1, sizeof(itunesdb_mhip_t)); chunk->data = mhip; return mhip ? 0 : IPODE_OUTOFMEMORY; } @@ -347,7 +406,7 @@ static int mhip_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { int ret = 0; - chunk_mhip_t* mhip = (chunk_mhip_t*)chunk->data; + itunesdb_mhip_t* mhip = (itunesdb_mhip_t*)chunk->data; if (ret = serialize_uint32le(sio, "num_mhod", "%u", &mhip->num_mhod)) return ret; if (ret = serialize_uint32le(sio, "flag_podcast_group", "%X", &mhip->flag_podcast_group)) return ret; @@ -363,8 +422,8 @@ static void mhod_string_finish(itunesdb_chunk_t* chunk) { - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_string_t* string = &mhod->data.str; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_string_t* string = &mhod->data.str; ucs2free(string->value); memset(string, 0, sizeof(*string)); } @@ -372,7 +431,7 @@ static int mhod_string_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio) { int ret = 0; - chunk_mhod_string_t* string = &((chunk_mhod_t*)chunk->data)->data.str; + itunesdb_mhod_string_t* string = &((itunesdb_mhod_t*)chunk->data)->data.str; if (ret = serialize_uint32le(sio, "position", "%u", &string->position)) return ret; if (ret = serialize_uint32le(sio, "size", "%u", &string->size)) return ret; @@ -385,8 +444,8 @@ static void mhod_url_finish(itunesdb_chunk_t* chunk) { - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_url_t* url = &mhod->data.url; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_url_t* url = &mhod->data.url; ucs2free(url->value); memset(url, 0, sizeof(*url)); } @@ -394,8 +453,8 @@ static int mhod_url_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio) { int ret = 0; - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_url_t* url = &mhod->data.url; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_url_t* url = &mhod->data.url; if (ret = serialize_utf8str_fixed(sio, name, "%s", &url->value, chunk->size - chunk->overall_size)) return ret; @@ -404,8 +463,8 @@ static void mhod_index_finish(itunesdb_chunk_t* chunk) { - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_index_t* index = &mhod->data.index; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_index_t* index = &mhod->data.index; ucs2free(index->entries); memset(index, 0, sizeof(*index)); } @@ -414,8 +473,8 @@ { uint32_t i; int ret = 0; - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_index_t* index = &mhod->data.index; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_index_t* index = &mhod->data.index; if (ret = serialize_uint32le(sio, "type", "%u", &index->type)) return ret; if (ret = serialize_uint32le(sio, "num_entries", "%u", &index->num_entries)) return ret; @@ -438,10 +497,54 @@ return 0; } +static void mhod_library_playlist_index_finish(itunesdb_chunk_t* chunk) +{ + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_library_playlist_index_t* lp_index = &mhod->data.lp_index; + ucs2free(lp_index->entries); + memset(lp_index, 0, sizeof(*lp_index)); +} + +static int mhod_library_playlist_index_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio) +{ + uint32_t i; + int ret = 0; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_library_playlist_index_t* lp_index = &mhod->data.lp_index; + + if (ret = serialize_uint32le(sio, "type", "%u", &lp_index->type)) return ret; + if (ret = serialize_uint32le(sio, "num_entries", "%u", &lp_index->num_entries)) return ret; + if (ret = serialize_uint32le(sio, "unknown1", "%u", &lp_index->unknown1)) return ret; + if (ret = serialize_uint32le(sio, "unknown2", "%u", &lp_index->unknown2)) return ret; + + /* Allocate array when reading. */ + if (serialize_reading(sio)) { + lp_index->entries = calloc( + lp_index->num_entries, + sizeof(itunesdb_mhod_library_playlist_entry_t) + ); + if (!lp_index->entries) { + return IPODE_OUTOFMEMORY; + } + } + + for (i = 0;i < lp_index->num_entries;++i) { + char fieldname[128]; + sprintf(fieldname, "entries[%d].unknown1", i); + if (ret = serialize_uint32le(sio, fieldname, "%u", &lp_index->entries[i].unknown1)) return ret; + sprintf(fieldname, "entries[%d].unknown2", i); + if (ret = serialize_uint32le(sio, fieldname, "%u", &lp_index->entries[i].unknown2)) return ret; + sprintf(fieldname, "entries[%d].unknown3", i); + if (ret = serialize_uint32le(sio, fieldname, "%u", &lp_index->entries[i].unknown3)) return ret; + } + + return 0; +} + static void mhod_playlist_column_finish(itunesdb_chunk_t* chunk) { - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_playlist_column_t* pc = &mhod->data.pc; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_playlist_column_t* pc = &mhod->data.pc; ucs2free(pc->columns); memset(pc, 0, sizeof(*pc)); } @@ -450,8 +553,8 @@ { uint32_t i; int ret = 0; - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_playlist_column_t* pc = &mhod->data.pc; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_playlist_column_t* pc = &mhod->data.pc; if (ret = serialize_uint32le(sio, "unk3", "%u", &pc->unk3)) return ret; if (ret = serialize_uint64le(sio, "unk4", "%016llX", &pc->unk4)) return ret; @@ -464,8 +567,8 @@ /* Allocate array when reading. */ if (serialize_reading(sio)) { - pc->columns = (chunk_mhod_playlist_column_definition_t*)calloc( - pc->num_columns, sizeof(chunk_mhod_playlist_column_definition_t)); + pc->columns = (itunesdb_mhod_playlist_column_definition_t*)calloc( + pc->num_columns, sizeof(itunesdb_mhod_playlist_column_definition_t)); if (!pc->columns) { return IPODE_OUTOFMEMORY; } @@ -473,7 +576,7 @@ for (i = 0;i < pc->num_columns;++i) { char fieldname[128]; - chunk_mhod_playlist_column_definition_t* def = &pc->columns[i]; + itunesdb_mhod_playlist_column_definition_t* def = &pc->columns[i]; sprintf(fieldname, "columns[%d].id", i); if (ret = serialize_uint16le(sio, fieldname, "%u", &def->id)) return ret; @@ -490,16 +593,16 @@ static void mhod_playlist_order_finish(itunesdb_chunk_t* chunk) { - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_playlist_order_t* po = &mhod->data.po; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_playlist_order_t* po = &mhod->data.po; memset(po, 0, sizeof(*po)); } static int mhod_playlist_order_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio) { int ret = 0; - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_playlist_order_t* po = &mhod->data.po; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_playlist_order_t* po = &mhod->data.po; if (ret = serialize_uint32le(sio, "position", "%u", &po->position)) return ret; if (ret = serialize_uint8_array(sio, "unknown", "%02X ", po->unknown, sizeof(po->unknown))) return ret; @@ -522,16 +625,24 @@ {14, "description", 0, mhod_string_finish, mhod_string_serialize}, {15, "podcast_enclosure_url", 0, mhod_url_finish, mhod_url_serialize}, {16, "podcast_rss_url", 0, mhod_url_finish, mhod_url_serialize}, + {27, "sort_title", 0, mhod_string_finish, mhod_string_serialize}, + {28, "sort_album", 0, mhod_string_finish, mhod_string_serialize}, + {29, "sort_albumartist", 0, mhod_string_finish, mhod_string_serialize}, + {30, "sort_composer", 0, mhod_string_finish, mhod_string_serialize}, {52, "index", 0, mhod_index_finish, mhod_index_serialize}, + {53, "library_playlist_index", 0, mhod_library_playlist_index_finish, mhod_library_playlist_index_serialize}, {100, "playlist_column", 0x288, mhod_playlist_column_finish, mhod_playlist_column_serialize}, {100, "playlist_order", 0x2C, mhod_playlist_order_finish, mhod_playlist_order_serialize}, + {200, "album_albumlist", 0, mhod_string_finish, mhod_string_serialize}, + {201, "artist_albumlist", 0, mhod_string_finish, mhod_string_serialize}, + {202, "sort_artist_albumlist", 0, mhod_string_finish, mhod_string_serialize}, {0, NULL, 0, NULL}, }; static const itunesdb_mhoddecl_t* find_mhoddecl(itunesdb_chunk_t* chunk) { const itunesdb_mhoddecl_t* decl = mds; - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; while (decl->name) { if (decl->type == mhod->type) { @@ -565,13 +676,13 @@ chunk->size = 24; chunk->overall_size = chunk->size; } - chunk->data = calloc(1, sizeof(chunk_mhod_t)); + chunk->data = calloc(1, sizeof(itunesdb_mhod_t)); return chunk->data ? 0 : IPODE_OUTOFMEMORY; } static void mhod_finish(itunesdb_chunk_t* chunk) { - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; const itunesdb_mhoddecl_t* decl = NULL; decl = find_mhoddecl(chunk); if (decl) { @@ -583,7 +694,7 @@ static int mhod_serialize(itunesdb_chunk_t* chunk, serializer_t* sio) { int ret = 0; - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; const itunesdb_mhoddecl_t* decl = NULL; if (ret = serialize_uint32le(sio, "type", "%u", &mhod->type)) return ret; @@ -609,6 +720,8 @@ static const itunesdb_chunkdecl_t cds[] = { {"mhbd", mhbd_init, chunk_finish, mhbd_serialize}, {"mhsd", mhsd_init, chunk_finish, mhsd_serialize}, + {"mhla", mhla_init, chunk_finish, mhla_serialize}, + {"mhia", mhia_init, chunk_finish, mhia_serialize}, {"mhlt", mhlt_init, chunk_finish, mhlt_serialize}, {"mhit", mhit_init, chunk_finish, mhit_serialize}, {"mhlp", mhlp_init, chunk_finish, mhlp_serialize}, @@ -638,7 +751,7 @@ if (ret = decl->init(chunk, 1)) return ret; if (strncmp(name, "mhod", 4) == 0) { - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; const itunesdb_mhoddecl_t* decl2 = find_mhoddecl_by_name(subtype); if (!decl2) { decl->finish(chunk); @@ -653,7 +766,7 @@ int itunesdb_ischunk(itunesdb_chunk_t* chunk, const char *name, const char *subtype) { if (strncmp(name, "mhod", 4) == 0) { - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; const itunesdb_mhoddecl_t* decl = find_mhoddecl(chunk); return (decl && strcmp(decl->name, subtype) == 0) ? 1 : 0; } else { @@ -875,8 +988,8 @@ int itunesdb_set_mhod_string(itunesdb_chunk_t* chunk, const ucs2char_t* value) { - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_string_t* str = &mhod->data.str; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_string_t* str = &mhod->data.str; /* Make sure this is an "mhod" chunk. */ if (strncmp(chunk->id, "mhod", 4) != 0) { @@ -896,8 +1009,8 @@ int itunesdb_get_mhod_string(itunesdb_chunk_t* chunk, ucs2char_t** value) { - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_string_t* str = &mhod->data.str; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_string_t* str = &mhod->data.str; /* Make sure this is an "mhod" chunk. */ if (strncmp(chunk->id, "mhod", 4) != 0) { @@ -915,8 +1028,8 @@ int itunesdb_set_mhod_index(itunesdb_chunk_t* chunk, uint32_t type, sorted_index_t* si, uint32_t n) { uint32_t i; - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_index_t* index = &mhod->data.index; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_index_t* index = &mhod->data.index; /* Make sure this is an "mhod" chunk. */ if (strncmp(chunk->id, "mhod", 4) != 0) { @@ -938,8 +1051,8 @@ int itunesdb_set_mhod_playlist_order(itunesdb_chunk_t* chunk, uint32_t order) { - chunk_mhod_t* mhod = (chunk_mhod_t*)chunk->data; - chunk_mhod_playlist_order_t* po = &mhod->data.po; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_playlist_order_t* po = &mhod->data.po; /* Make sure this is an "mhod" chunk. */ if (strncmp(chunk->id, "mhod", 4) != 0) { Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-05-12 02:26:41 UTC (rev 408) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-09-12 14:25:36 UTC (rev 409) @@ -34,15 +34,26 @@ uint64_t unknown4; uint8_t unknown5[26]; /* zero padded. */ uint8_t language[2]; /* e.g., "en", "ja" */ -} chunk_mhbd_t; +} itunesdb_mhbd_t; typedef struct { uint32_t type; /* 1 (track list), 2 (playlist list), or 3 (podcast list). */ -} chunk_mhsd_t; +} itunesdb_mhsd_t; typedef struct { + uint8_t unknown; /* Zero padded. */ +} itunesdb_mhla_t; + +typedef struct { + uint32_t num_children; + uint32_t album_id; + uint64_t timestamp; + uint32_t unknown1; +} itunesdb_mhia_t; + +typedef struct { uint8_t unknown; /* zero padded. */ -} chunk_mhlt_t; +} itunesdb_mhlt_t; typedef struct { uint32_t num_children; @@ -119,11 +130,11 @@ uint32_t unk38; uint16_t gapless_track; uint16_t gapless_album; -} chunk_mhit_t; +} itunesdb_mhit_t; typedef struct { uint8_t unknown; /* zero padded. */ -} chunk_mhlp_t; +} itunesdb_mhlp_t; typedef struct { uint32_t num_mhod; @@ -138,7 +149,7 @@ uint16_t unk4; uint16_t flag_podcast; uint32_t sort_order; -} chunk_mhyp_t; +} itunesdb_mhyp_t; typedef struct { uint32_t num_mhod; @@ -147,7 +158,7 @@ uint32_t track_id; uint32_t timestamp; uint32_t podcast_parent; -} chunk_mhip_t; +} itunesdb_mhip_t; typedef struct { uint32_t position; @@ -155,25 +166,25 @@ uint32_t unknown; uint32_t unk4; ucs2char_t* value; -} chunk_mhod_string_t; +} itunesdb_mhod_string_t; typedef struct { char* value; -} chunk_mhod_url_t; +} itunesdb_mhod_url_t; typedef struct { uint32_t type; uint32_t num_entries; uint8_t padding[40]; uint32_t* entries; -} chunk_mhod_index_t; +} itunesdb_mhod_index_t; typedef struct { uint16_t id; uint16_t width; uint32_t sort_direction; uint64_t padding; -} chunk_mhod_playlist_column_definition_t; +} itunesdb_mhod_playlist_column_definition_t; typedef struct { uint32_t unk1; @@ -186,26 +197,41 @@ uint32_t sort_type; uint32_t num_columns; uint32_t unknown; - chunk_mhod_playlist_column_definition_t* columns; -} chunk_mhod_playlist_column_t; + itunesdb_mhod_playlist_column_definition_t* columns; +} itunesdb_mhod_playlist_column_t; typedef struct { + uint32_t unknown1; + uint32_t unknown2; + uint32_t unknown3; +} itunesdb_mhod_library_playlist_entry_t; + +typedef struct { + uint32_t type; + uint32_t num_entries; + uint32_t unknown1; + uint32_t unknown2; + itunesdb_mhod_library_playlist_entry_t *entries; +} itunesdb_mhod_library_playlist_index_t; + +typedef struct { uint32_t position; uint8_t unknown[16]; -} chunk_mhod_playlist_order_t; +} itunesdb_mhod_playlist_order_t; typedef struct { uint32_t type; uint32_t unk1; uint32_t unk2; union { - chunk_mhod_string_t str; - chunk_mhod_url_t url; - chunk_mhod_index_t index; - chunk_mhod_playlist_column_t pc; - chunk_mhod_playlist_order_t po; + itunesdb_mhod_string_t str; + itunesdb_mhod_url_t url; + itunesdb_mhod_index_t index; + itunesdb_mhod_playlist_column_t pc; + itunesdb_mhod_playlist_order_t po; + itunesdb_mhod_library_playlist_index_t lp_index; } data; -} chunk_mhod_t; +} itunesdb_mhod_t; struct tag_itunesdb_chunk { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-09-12 17:04:51
|
Revision: 412 http://pmplib.svn.sourceforge.net/pmplib/?rev=412&view=rev Author: nyaochi Date: 2007-09-12 10:04:54 -0700 (Wed, 12 Sep 2007) Log Message: ----------- - Added mhsd (type = 4). Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/itunesdb.c Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-12 16:20:00 UTC (rev 411) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-12 17:04:54 UTC (rev 412) @@ -535,6 +535,22 @@ return ret; } +static int comp_album_for_list(const void *_x, const void *_y) +{ + int ret = 0; + const sorted_index_t *xi = (const sorted_index_t*)_x; + const sorted_index_t *yi = (const sorted_index_t*)_y; + const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; + const pmp_music_record_t* x = &base[xi->index]; + const pmp_music_record_t* y = &base[yi->index]; + + ret = comp_string(x->album, y->album); + if (ret == 0) { + ret = comp_string(x->artist, y->artist); + } + return ret; +} + static int comp_artist(const void *_x, const void *_y) { int ret = 0; @@ -583,6 +599,59 @@ return ret; } +static int set_album_list(itunesdb_chunk_t* mhla, const pmp_music_record_t* records, int num_records) +{ + int i; + int ret = 0; + const ucs2char_t* prev_album = NULL; + const ucs2char_t* prev_artist = NULL; + itunesdb_chunk_t *mhod = NULL, *mhia = NULL; + itunesdb_mhia_t *mhia_data = NULL; + sorted_index_t* si = (sorted_index_t*)calloc(num_records, sizeof(sorted_index_t)); + + if (!si) { + return IPODE_OUTOFMEMORY; + } + for (i = 0;i < num_records;++i) { + si[i].base = records; + si[i].index = i; + } + qsort(si, num_records, sizeof(si[0]), comp_album_for_list); + + for (i = 0;i < num_records;++i) { + const pmp_music_record_t* cur = &records[si[i].index]; + const ucs2char_t* album = cur->album; + const ucs2char_t* artist = cur->artist; + + if (prev_album == NULL || ucs2cmp(prev_album, album) != 0) { + mhia = itunesdb_new_child(mhla); + if (ret = itunesdb_init(mhia, "mhia", NULL)) return ret; + mhia_data = (itunesdb_mhia_t*)mhia->data; + + mhod = itunesdb_new_child(mhia); + if (mhod) { + if (ret = itunesdb_init(mhod, "mhod", "album_albumlist")) return ret; + if (ret = itunesdb_set_mhod_string(mhod, album)) return ret; + } + + mhod = itunesdb_new_child(mhia); + if (mhod) { + if (ret = itunesdb_init(mhod, "mhod", "artist_albumlist")) return ret; + if (ret = itunesdb_set_mhod_string(mhod, artist)) return ret; + } + + mhia_data->num_children = 2; + mhia_data->album_id = i; + mhia_data->timestamp = 0; + mhia_data->unknown1 = 2; + } + + prev_album = album; + } + + return 0; +} + static int set_master_playlist(itunesdb_chunk_t* mhyp, const pmp_music_record_t* records, int num_records) { int i; @@ -807,6 +876,7 @@ int i; int ret = 0; itunesdb_chunk_t *mhbd = NULL, *mhsd = NULL; + itunesdb_chunk_t *mhla = NULL; itunesdb_chunk_t *mhlt = NULL, *mhit = NULL; itunesdb_chunk_t *mhlp = NULL, *mhyp = NULL; itunesdb_mhbd_t* mhbd_data = NULL; @@ -820,7 +890,25 @@ mhbd_data = (itunesdb_mhbd_t*)mhbd->data; /* Construct "mhsd" chunk with album_list type (type = 4). */ + mhsd = itunesdb_new_child(mhbd); + if (mhsd) { + itunesdb_mhsd_t* mhsd_data = NULL; + if (ret = itunesdb_init(mhsd, "mhsd", NULL)) return ret; + mhsd_data = (itunesdb_mhsd_t*)mhsd->data; + mhsd_data->type = 4; /* album_list type. */ + /* Construct "mhla" chunk. */ + mhla = itunesdb_new_child(mhsd); + if (mhla) { + if (ret = itunesdb_init(mhla, "mhla", NULL)) return ret; + if (ret = set_album_list(mhla, records, num_records)) return ret; + } else { + return IPODE_FAILEDNEWCHUNK; + } + } else { + return IPODE_FAILEDNEWCHUNK; + } + /* Construct "mhsd" chunk with track type (type = 1). */ mhsd = itunesdb_new_child(mhbd); if (mhsd) { Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-12 16:20:00 UTC (rev 411) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-12 17:04:54 UTC (rev 412) @@ -960,7 +960,7 @@ } /* Calculate chunk->overall_size. */ - if (strncmp(chunk->id, "mhlt", 4) == 0 || strncmp(chunk->id, "mhlp", 4) == 0) { + if (strncmp(chunk->id, "mhla", 4) == 0 || strncmp(chunk->id, "mhlt", 4) == 0 || strncmp(chunk->id, "mhlp", 4) == 0) { /* chunk->overall_size represents the number of children for "mhlt" and "mhlp" chunks */ chunk->overall_size = chunk->num_children; } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-09-17 12:14:27
|
Revision: 413 http://pmplib.svn.sourceforge.net/pmplib/?rev=413&view=rev Author: nyaochi Date: 2007-09-17 05:14:30 -0700 (Mon, 17 Sep 2007) Log Message: ----------- - Updated the layout of "mhsd" chunk. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-12 17:04:54 UTC (rev 412) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-17 12:14:30 UTC (rev 413) @@ -889,6 +889,7 @@ if (ret = itunesdb_init(mhbd, "mhbd", NULL)) return ret; mhbd_data = (itunesdb_mhbd_t*)mhbd->data; +#if 0 /* Construct "mhsd" chunk with album_list type (type = 4). */ mhsd = itunesdb_new_child(mhbd); if (mhsd) { @@ -908,6 +909,7 @@ } else { return IPODE_FAILEDNEWCHUNK; } +#endif /* Construct "mhsd" chunk with track type (type = 1). */ mhsd = itunesdb_new_child(mhbd); Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-12 17:04:54 UTC (rev 412) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-17 12:14:30 UTC (rev 413) @@ -64,12 +64,18 @@ mhbd->unknown1 = 1; mhbd->version = 0x19; /* iTunes 7.4.1 */ mhbd->num_children = 0; /* to be filled */ - mhbd->identifier = 0x7F6BBD850EB674E2; + mhbd->identifier = 0x5967FDF4464C603D; mhbd->unknown2 = 2; mhbd->unknown3 = 611; mhbd->unknown4 = 0xBCD054CD8C063208; + mhbd->unknown5 = 0; + mhbd->unknown6 = 1; mhbd->language[0] = 'j'; mhbd->language[1] = 'a'; + mhbd->unknown7 = 0x39F6D17B62A94AC7; + mhbd->unknown8 = 1; + mhbd->unknown9 = 13; + mhbd->timezone = 0x00007E90; } chunk->data = mhbd; return mhbd ? 0 : IPODE_OUTOFMEMORY; @@ -87,8 +93,15 @@ if (ret = serialize_uint16le(sio, "unkonwn2", "%d", &mhbd->unknown2)) return ret; if (ret = serialize_uint16le(sio, "unkonwn3", "%d", &mhbd->unknown3)) return ret; if (ret = serialize_uint64le(sio, "unknown4", "%016llX", &mhbd->unknown4)) return ret; - if (ret = serialize_uint8_array(sio, "unknown5", "%02X ", mhbd->unknown5, sizeof(mhbd->unknown5))) return ret; + if (ret = serialize_uint32le(sio, "unknown5", "%d", &mhbd->unknown5)) return ret; + if (ret = serialize_uint16le(sio, "unknown6", "%d", &mhbd->unknown6)) return ret; + if (ret = serialize_uint8_array(sio, "hash32", "%02X ", mhbd->hash32, sizeof(mhbd->hash32))) return ret; if (ret = serialize_uint8_array(sio, "language", "%c ", mhbd->language, sizeof(mhbd->language))) return ret; + if (ret = serialize_uint64le(sio, "unknown7", "%016llX", &mhbd->unknown7)) return ret; + if (ret = serialize_uint32le(sio, "unknown8", "%d", &mhbd->unknown8)) return ret; + if (ret = serialize_uint32le(sio, "unknown9", "%d", &mhbd->unknown9)) return ret; + if (ret = serialize_uint8_array(sio, "hash58", "%02X ", mhbd->hash58, sizeof(mhbd->hash58))) return ret; + if (ret = serialize_uint32le(sio, "timezone", "%d", &mhbd->timezone)) return ret; return 0; } Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-09-12 17:04:54 UTC (rev 412) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-09-17 12:14:30 UTC (rev 413) @@ -32,8 +32,15 @@ uint16_t unknown2; /* always set to 2. */ uint16_t unknown3; /* 0x0263 */ uint64_t unknown4; - uint8_t unknown5[26]; /* zero padded. */ + uint32_t unknown5; + uint16_t unknown6; + uint8_t hash32[20]; uint8_t language[2]; /* e.g., "en", "ja" */ + uint64_t unknown7; + uint32_t unknown8; + uint32_t unknown9; + uint8_t hash58[20]; + uint32_t timezone; } itunesdb_mhbd_t; typedef struct { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-09-17 13:00:29
|
Revision: 414 http://pmplib.svn.sourceforge.net/pmplib/?rev=414&view=rev Author: nyaochi Date: 2007-09-17 06:00:32 -0700 (Mon, 17 Sep 2007) Log Message: ----------- Supported iPod nano 3rd gen. Many thanks go to those who analyzed the algorithm to compute the hash value in "mhbd" chunk, especially wtbw, nopcode, retar_d, oleavr, and desrt at #gtkpod. Other new iPod models are not supported at this moment due to the lack of the code to obtain the serial string on USB devices. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj Added Paths: ----------- trunk/pmplib/lib/pmp_ipod/hash58.c trunk/pmplib/lib/pmp_ipod/hash58.h trunk/pmplib/lib/pmp_ipod/sha1.c trunk/pmplib/lib/pmp_ipod/sha1.h Added: trunk/pmplib/lib/pmp_ipod/hash58.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/hash58.c (rev 0) +++ trunk/pmplib/lib/pmp_ipod/hash58.c 2007-09-17 13:00:32 UTC (rev 414) @@ -0,0 +1,173 @@ +/* +SHA1 hash value generator for offset 0x58 of "mhbd" chunk. + +This source code is taken from the implementation at: +http://main.wtbw.co.uk/hash58.zip + +Many thanks to those who involved in the analysis at #gtkpod +(wtbw, nopcode, retar_d, oleavr, desrt) +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif/*HAVE_CONFIG_H*/ + +#include <os.h> +#include <memory.h> +#include "sha1.h" + +#define MIN2(a, b) ((a) < (b) ? (a) : (b)) + +unsigned char invTable[256] = { + 0x74, 0x85, 0x96, 0xA7, 0xB8, 0xC9, 0xDA, 0xEB, 0xFC, 0x0D, 0x1E, 0x2F, 0x40, 0x51, 0x62, 0x73, + 0x84, 0x95, 0xA6, 0xB7, 0xC8, 0xD9, 0xEA, 0xFB, 0x0C, 0x1D, 0x2E, 0x3F, 0x50, 0x61, 0x72, 0x83, + 0x94, 0xA5, 0xB6, 0xC7, 0xD8, 0xE9, 0xFA, 0x0B, 0x1C, 0x2D, 0x3E, 0x4F, 0x60, 0x71, 0x82, 0x93, + 0xA4, 0xB5, 0xC6, 0xD7, 0xE8, 0xF9, 0x0A, 0x1B, 0x2C, 0x3D, 0x4E, 0x5F, 0x70, 0x81, 0x92, 0xA3, + 0xB4, 0xC5, 0xD6, 0xE7, 0xF8, 0x09, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F, 0x80, 0x91, 0xA2, 0xB3, + 0xC4, 0xD5, 0xE6, 0xF7, 0x08, 0x19, 0x2A, 0x3B, 0x4C, 0x5D, 0x6E, 0x7F, 0x90, 0xA1, 0xB2, 0xC3, + 0xD4, 0xE5, 0xF6, 0x07, 0x18, 0x29, 0x3A, 0x4B, 0x5C, 0x6D, 0x7E, 0x8F, 0xA0, 0xB1, 0xC2, 0xD3, + 0xE4, 0xF5, 0x06, 0x17, 0x28, 0x39, 0x4A, 0x5B, 0x6C, 0x7D, 0x8E, 0x9F, 0xB0, 0xC1, 0xD2, 0xE3, + 0xF4, 0x05, 0x16, 0x27, 0x38, 0x49, 0x5A, 0x6B, 0x7C, 0x8D, 0x9E, 0xAF, 0xC0, 0xD1, 0xE2, 0xF3, + 0x04, 0x15, 0x26, 0x37, 0x48, 0x59, 0x6A, 0x7B, 0x8C, 0x9D, 0xAE, 0xBF, 0xD0, 0xE1, 0xF2, 0x03, + 0x14, 0x25, 0x36, 0x47, 0x58, 0x69, 0x7A, 0x8B, 0x9C, 0xAD, 0xBE, 0xCF, 0xE0, 0xF1, 0x02, 0x13, + 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, 0x8A, 0x9B, 0xAC, 0xBD, 0xCE, 0xDF, 0xF0, 0x01, 0x12, 0x23, + 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x9A, 0xAB, 0xBC, 0xCD, 0xDE, 0xEF, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x10, 0x21, 0x32, 0x43, + 0x54, 0x65, 0x76, 0x87, 0x98, 0xA9, 0xBA, 0xCB, 0xDC, 0xED, 0xFE, 0x0F, 0x20, 0x31, 0x42, 0x53, + 0x64, 0x75, 0x86, 0x97, 0xA8, 0xB9, 0xCA, 0xDB, 0xEC, 0xFD, 0x0E, 0x1F, 0x30, 0x41, 0x52, 0x63 +}; + +unsigned char table1[256] = { + 0x3A, 0x3F, 0x3E, 0x72, 0xBD, 0xA2, 0xD6, 0xB4, 0x63, 0xC0, 0x6E, 0x62, 0x59, 0x1E, 0xE2, 0x71, + 0xB5, 0x0D, 0xE8, 0x0C, 0x25, 0x38, 0xCE, 0x23, 0x7C, 0xB7, 0xAD, 0x16, 0xDF, 0x47, 0x3D, 0xB3, + 0x7E, 0x8C, 0xAA, 0x61, 0x31, 0x66, 0xBE, 0x4F, 0x97, 0x14, 0x54, 0xF0, 0x70, 0xEB, 0x30, 0xC4, + 0x27, 0x4E, 0xFA, 0x1A, 0x2B, 0x11, 0xF4, 0x45, 0x8E, 0x5D, 0x73, 0xED, 0x22, 0x2E, 0x7D, 0xA4, + 0x28, 0xDA, 0x2F, 0xC5, 0x92, 0x09, 0x05, 0x13, 0x9D, 0x32, 0x51, 0x4A, 0xC8, 0xBA, 0x96, 0xA7, + 0x6A, 0x50, 0xF3, 0xBC, 0x93, 0xBF, 0xB0, 0xD2, 0xD5, 0x82, 0x19, 0x98, 0x35, 0xCF, 0x6B, 0xB6, + 0x83, 0x56, 0x15, 0xF2, 0x9A, 0x9C, 0xCA, 0x74, 0x34, 0x58, 0x8D, 0xA6, 0x03, 0xFF, 0x46, 0x7B, + 0xD0, 0x7A, 0x33, 0x76, 0xDD, 0xAC, 0xCB, 0x24, 0x7F, 0xB1, 0x85, 0x60, 0xC3, 0x26, 0x8A, 0x1D, + 0x1C, 0x8F, 0x2A, 0xEF, 0x06, 0xDE, 0x67, 0x5E, 0xE7, 0xAE, 0xD9, 0xCC, 0x07, 0x6C, 0xF8, 0x0A, + 0xD3, 0x40, 0x36, 0x1F, 0x2D, 0x95, 0x43, 0xDB, 0x01, 0x89, 0x4B, 0xF7, 0xB9, 0x39, 0xC2, 0x52, + 0x53, 0xFD, 0x65, 0xF5, 0x68, 0xC1, 0xC7, 0x9F, 0x4D, 0xEA, 0xAF, 0x6D, 0x10, 0x44, 0x87, 0xD8, + 0xEE, 0x1B, 0xFE, 0x3C, 0xDC, 0x84, 0x69, 0x48, 0x6F, 0xD1, 0x57, 0x55, 0xD4, 0xA5, 0x49, 0x5B, + 0xE5, 0x0B, 0x94, 0xC9, 0x5F, 0xE1, 0x17, 0x81, 0xBB, 0xEC, 0xD7, 0xC6, 0x02, 0x4C, 0x42, 0x75, + 0xA3, 0x99, 0xE4, 0xA1, 0x9B, 0x5A, 0xF1, 0x29, 0xA0, 0x64, 0x9E, 0x18, 0x41, 0x80, 0x2C, 0x79, + 0x20, 0x8B, 0xAB, 0x90, 0x08, 0xB8, 0xA9, 0x77, 0x12, 0xF9, 0x0E, 0x88, 0xE9, 0x04, 0xFB, 0x86, + 0x0F, 0xE0, 0xA8, 0x5C, 0xE6, 0x21, 0xCD, 0x3B, 0x00, 0x78, 0xFC, 0xF6, 0xE3, 0x37, 0xB2, 0x91 +}; + +unsigned char table2[256] = { + 0xF3, 0xE4, 0x1B, 0x38, 0xE5, 0x6F, 0xE8, 0x9D, 0x3E, 0x55, 0xBA, 0xC7, 0xAC, 0xEA, 0x66, 0xA2, + 0xB9, 0x7A, 0x34, 0x43, 0x02, 0x4E, 0xFE, 0x36, 0x41, 0x57, 0x1A, 0xB1, 0x31, 0x87, 0x04, 0x52, + 0x21, 0x22, 0xE1, 0x13, 0x7F, 0x03, 0x3A, 0x90, 0xF7, 0x69, 0x78, 0x12, 0x83, 0x0B, 0x9A, 0x97, + 0x4D, 0xB7, 0x8C, 0xBF, 0x2D, 0x94, 0xD1, 0x93, 0x2F, 0x42, 0x23, 0xA4, 0xE0, 0x92, 0xDC, 0x68, + 0xD3, 0xDD, 0xAF, 0x91, 0x9F, 0xED, 0x3D, 0x8F, 0xA1, 0x51, 0xD9, 0xE9, 0x70, 0x28, 0xEF, 0xB3, + 0x49, 0xA5, 0x0D, 0xC5, 0xD0, 0x60, 0xB4, 0x2B, 0x07, 0xF8, 0xDF, 0xE6, 0x16, 0xC0, 0x30, 0x71, + 0x85, 0xFD, 0x72, 0x95, 0x29, 0x79, 0x0A, 0x7B, 0x46, 0x11, 0x7D, 0x88, 0x1D, 0x2A, 0x48, 0x1F, + 0x45, 0x89, 0x47, 0xEE, 0xBB, 0xBE, 0x6E, 0xC3, 0x6C, 0xCE, 0x10, 0x5A, 0x2C, 0xCA, 0xFB, 0xB2, + 0xCB, 0x1C, 0x9C, 0xEC, 0x2E, 0x56, 0x59, 0x9B, 0xA6, 0x53, 0xAE, 0x17, 0x25, 0xC1, 0x3F, 0x6A, + 0x0F, 0x09, 0x01, 0xA3, 0xD6, 0xA0, 0xD8, 0x08, 0xE3, 0x74, 0x06, 0x6D, 0x19, 0x98, 0x1E, 0x77, + 0x76, 0xBC, 0xEB, 0x3C, 0xB0, 0xC4, 0xC8, 0x64, 0x0E, 0x86, 0x63, 0xD7, 0xDB, 0xBD, 0xA7, 0x82, + 0x39, 0x4F, 0x27, 0xD2, 0x5F, 0x73, 0xF4, 0x75, 0x6B, 0xC2, 0xD5, 0x67, 0x5D, 0x80, 0xAB, 0x81, + 0xDE, 0xF0, 0xAD, 0xAA, 0xCD, 0xB6, 0xF6, 0x7C, 0xFC, 0x33, 0x05, 0x14, 0x96, 0x15, 0xC9, 0x9E, + 0x35, 0x5C, 0x7E, 0x44, 0x54, 0x58, 0x3B, 0x40, 0x20, 0xA8, 0x8B, 0x5E, 0x4A, 0x24, 0x99, 0x8E, + 0xF5, 0xB5, 0x62, 0x00, 0x37, 0x5B, 0x18, 0x65, 0x8D, 0x32, 0xE2, 0xF9, 0xDA, 0x8A, 0xD4, 0xCC, + 0x26, 0xF2, 0xF1, 0xE7, 0x4B, 0xC6, 0xCF, 0xFF, 0x4C, 0x84, 0x61, 0xFA, 0xB8, 0x0C, 0xA9, 0x50 +}; + +unsigned char fixed[18] = { + 0x67, 0x23, 0xFE, 0x30, 0x45, 0x33, 0xF8, 0x90, 0x99, 0x21, 0x07, 0xC1, 0xD0, 0x12, 0xB2, 0xA1, 0x07, 0x81 +}; + +int GCD(int a, int b){ + while( 1 ) + { + a = a % b; + if( a == 0 ) + return b; + b = b % a; + if( b == 0 ) + return a; + } +} + +int LCM(int a, int b) +{ + if(a==0 || b==0) + return 1; + + return (a*b)/GCD(a,b); +} + + +//pFWID -> 8 bytes +//pKey -> 64 byte buffer +void GenerateKey(unsigned char *pFWID, unsigned char *pKey) +{ + int i; + SHA1_CTX context; + unsigned char y[16]; + + memset(pKey,0, 64); + + //take LCM of each two bytes in the FWID in turn + for(i=0;i<4;i++){ + int a=pFWID[i*2]; + int b=pFWID[i*2+1]; + int lcm = LCM(a,b); + + unsigned char hi = (lcm & 0xFF00) >> 8; + unsigned char lo = lcm & 0xFF; + + y[i*4] = ((table1[hi] * 0xB5) - 3); + y[i*4 + 1] = ((table2[hi] * 0xB7) + 0x49); + y[i*4 + 2] = ((table1[lo] * 0xB5) - 3); + y[i*4 + 3] = ((table2[lo] * 0xB7) + 0x49); + } + + //convert y + for(i=0;i<16;i++){ + y[i] = invTable[y[i]]; + } + + //hash + SHA1Init(&context); + SHA1Update(&context, fixed, 18); + SHA1Update(&context, y, 16); + SHA1Final(pKey, &context); +} + +#define SIZE_OF_HEADERS 0x6C + +//pDataBase -> iTunesDB +//pFWID -> 8 bytes +//pHash -> 20 byte buffer +void GenerateHash(uint8_t *pFWID, uint8_t *pDataBase, size_t lSize, uint8_t *pHash) +{ + int i; + SHA1_CTX context; + unsigned char key[64]; + size_t lSizeWithoutHeaders = lSize - SIZE_OF_HEADERS; + size_t lSizeToUse = MIN2((long)0x40000, lSizeWithoutHeaders) + SIZE_OF_HEADERS; + + //generate invtable + GenerateKey(pFWID, key); + + //hmac sha1 + for (i=0; i < 64; i++) + key[i] ^= 0x36; + + + SHA1Init(&context); + SHA1Update(&context, key, 64); + SHA1Update(&context, pDataBase, lSizeToUse); + SHA1Final(pHash, &context); + + for (i=0; i < 64; i++) + key[i] ^= 0x36 ^ 0x5c; + + SHA1Init(&context); + SHA1Update(&context, key, 64); + SHA1Update(&context, pHash, 20); + SHA1Final(pHash, &context); +} Added: trunk/pmplib/lib/pmp_ipod/hash58.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/hash58.h (rev 0) +++ trunk/pmplib/lib/pmp_ipod/hash58.h 2007-09-17 13:00:32 UTC (rev 414) @@ -0,0 +1,6 @@ +#ifndef __HASH58_H__ +#define __HASH58_H__ + +void GenerateHash(uint8_t *pFWID, uint8_t *pDataBase, size_t lSize, uint8_t *pHash); + +#endif/*__HASH58_H__*/ Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-17 12:14:30 UTC (rev 413) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-17 13:00:32 UTC (rev 414) @@ -248,6 +248,9 @@ fp = ucs2fopen(itunesdb, "wb"); if (fp) { + /* Finalize the database (fill the hash58 value). */ + itunesdb_finalize(sio.base, sio.offset); + if (fwrite(sio.base, 1, sio.offset, fp) != sio.offset) { return (IPODC_ITUNESDB|IPODE_FILEWRITEERROR); } Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-17 12:14:30 UTC (rev 413) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-17 13:00:32 UTC (rev 414) @@ -38,9 +38,9 @@ #include "serialize.h" #include "util.h" #include "itunesdb.h" +#include "hash58.h" - static void chunk_finish(itunesdb_chunk_t* chunk) { free(chunk->data); @@ -989,6 +989,31 @@ return 0; } +int itunesdb_finalize(uint8_t* buffer, size_t size) +{ + uint8_t* src = NULL; + uint8_t hash58[20]; + uint8_t fwid[8] = { + 0x00, 0x0A, 0x27, 0x00, 0x1A, 0x1D, 0x72, 0xF1 + }; /* iPod nano 3rd gen only for now. */ + + src = (uint8_t*)malloc(size); + if (src == NULL) { + return 1; + } + memcpy(src, buffer, size); + + memset(src+0x18, 0, 8); + memset(src+0x32, 0, 20); + memset(src+0x58, 0, 20); + GenerateHash(fwid, src, size, hash58); + free(src); + + memcpy(buffer+0x58, hash58, sizeof(hash58)); + return 0; +} + + itunesdb_chunk_t* itunesdb_new_child(itunesdb_chunk_t* chunk) { chunk->childlen = (itunesdb_chunk_t*)realloc( Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-09-17 12:14:30 UTC (rev 413) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-09-17 13:00:32 UTC (rev 414) @@ -332,5 +332,6 @@ int itunesdb_repr(itunesdb_chunk_t* chunk, size_t index, serializer_t* sio); int itunesdb_read(itunesdb_chunk_t* chunk, serializer_t* sio); int itunesdb_write(itunesdb_chunk_t* chunk, serializer_t* sio); +int itunesdb_finalize(uint8_t* buffer, size_t size); #endif/*__ITUNESDB_H__*/ Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-09-17 12:14:30 UTC (rev 413) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-09-17 13:00:32 UTC (rev 414) @@ -179,6 +179,10 @@ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > <File + RelativePath=".\hash58.c" + > + </File> + <File RelativePath=".\ipod.c" > </File> @@ -199,6 +203,10 @@ > </File> <File + RelativePath=".\sha1.c" + > + </File> + <File RelativePath=".\util.c" > </File> @@ -209,6 +217,10 @@ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > <File + RelativePath=".\hash58.h" + > + </File> + <File RelativePath=".\ipod.h" > </File> @@ -229,6 +241,10 @@ > </File> <File + RelativePath=".\sha1.h" + > + </File> + <File RelativePath=".\status.h" > </File> Added: trunk/pmplib/lib/pmp_ipod/sha1.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/sha1.c (rev 0) +++ trunk/pmplib/lib/pmp_ipod/sha1.c 2007-09-17 13:00:32 UTC (rev 414) @@ -0,0 +1,245 @@ +/* +SHA-1 in C +By Steve Reid <st...@ed...> +100% Public Domain + +Test Vectors (from FIPS PUB 180-1) +"abc" +A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" +84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" +34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +#define LITTLE_ENDIAN /* This should be #define'd if true. */ +/* #define SHA1HANDSOFF * Copies data before messing with it. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif/*HAVE_CONFIG_H*/ + +#include <os.h> +#include <stdio.h> +#include <string.h> + +typedef struct { + unsigned long state[5]; + unsigned long count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +void SHA1Transform(unsigned long state[5], unsigned char buffer[64]); +void SHA1Init(SHA1_CTX* context); +void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len); +void SHA1Final(unsigned char digest[20], SHA1_CTX* context); + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#ifdef LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#else +#define blk0(i) block->l[i] +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void SHA1Transform(unsigned long state[5], unsigned char buffer[64]) +{ + unsigned long a, b, c, d, e; + typedef union { + unsigned char c[64]; + unsigned long l[16]; + } CHAR64LONG16; + CHAR64LONG16* block; + + /* + printf("SHA1Transform:\n"); + for (k = 0; k < 4; k++) { + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + printf("%02X", buffer[k*16+i*4+j]); + } + putchar(' '); + } + putchar('\n'); + } + printf("SHA1Transform (translated):\n"); + for (k = 0; k < 4; k++) { + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + long x = buffer[k*16+i*4+j] & 0xFF; + printf("%02X", cryptTable[x] & 0xFF); + } + putchar(' '); + } + putchar('\n'); + } + */ + +#ifdef SHA1HANDSOFF + static unsigned char workspace[64]; + block = (CHAR64LONG16*)workspace; + memcpy(block, buffer, 64); +#else + block = (CHAR64LONG16*)buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* SHA1Init - Initialize new context */ + +void SHA1Init(SHA1_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len) +{ + unsigned int i, j; + + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; + context->count[1] += (len >> 29); + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ + +void SHA1Final(unsigned char digest[20], SHA1_CTX* context) +{ + unsigned long i, j; + unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1Update(context, (unsigned char *)"\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1Update(context, (unsigned char *)"\0", 1); + } + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + i = j = 0; + memset(context->buffer, 0, 64); + memset(context->state, 0, 20); + memset(context->count, 0, 8); + memset(&finalcount, 0, 8); +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ + SHA1Transform(context->state, context->buffer); +#endif +} + + +/*************************************************************/ + +/* +int main(int argc, char** argv) +{ + int i, j; + SHA1_CTX context; + unsigned char digest[20], buffer[16384]; + FILE* file; + + if (argc > 2) { + puts("Public domain SHA-1 implementation - by Steve Reid <st...@ed...>"); + puts("Produces the SHA-1 hash of a file, or stdin if no file is specified."); + exit(0); + } + if (argc < 2) { + file = stdin; + } + else { + if (!(file = fopen(argv[1], "rb"))) { + fputs("Unable to open file.", stderr); + exit(-1); + } + } + SHA1Init(&context); + while (!feof(file)) { /* note: what if ferror(file) + i = fread(buffer, 1, 16384, file); + SHA1Update(&context, buffer, i); + } + SHA1Final(digest, &context); + fclose(file); + for (i = 0; i < 5; i++) { + for (j = 0; j < 4; j++) { + printf("%02X", digest[i*4+j]); + } + putchar(' '); + } + putchar('\n'); + exit(0); +} +*/ Added: trunk/pmplib/lib/pmp_ipod/sha1.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/sha1.h (rev 0) +++ trunk/pmplib/lib/pmp_ipod/sha1.h 2007-09-17 13:00:32 UTC (rev 414) @@ -0,0 +1,13 @@ +#ifndef __SHA1_H__ + +typedef struct { + unsigned long state[5]; + unsigned long count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +void SHA1Init(SHA1_CTX* context); +void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len); +void SHA1Final(unsigned char digest[20], SHA1_CTX* context); + +#endif/*__SHA1_H__*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-09-24 03:34:28
|
Revision: 415 http://pmplib.svn.sourceforge.net/pmplib/?rev=415&view=rev Author: nyaochi Date: 2007-09-23 20:34:31 -0700 (Sun, 23 Sep 2007) Log Message: ----------- - Fixed several bugs. - Support SmartPlaylist Data mhod type. - Read/write album_artist fields. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h trunk/pmplib/lib/pmp_ipod/util.c Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-17 13:00:32 UTC (rev 414) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-24 03:34:31 UTC (rev 415) @@ -359,6 +359,15 @@ } } + /* Construct an "mhod" chunk for album artist. */ + if (rec->artist && *rec->artist) { + mhod = itunesdb_new_child(mhit); + if (mhod) { + if (ret = itunesdb_init(mhod, "mhod", "album_artist")) return ret; + if (ret = itunesdb_set_mhod_string(mhod, rec->album_artist)) return ret; + } + } + /* Construct an "mhod" chunk for album. */ if (rec->album && *rec->album) { mhod = itunesdb_new_child(mhit); @@ -466,6 +475,8 @@ if (ret = itunesdb_get_mhod_string(mhod, &rec->title)) return ret; } else if (itunesdb_ischunk(mhod, "mhod", "artist")) { if (ret = itunesdb_get_mhod_string(mhod, &rec->artist)) return ret; + } else if (itunesdb_ischunk(mhod, "mhod", "album_artist")) { + if (ret = itunesdb_get_mhod_string(mhod, &rec->album_artist)) return ret; } else if (itunesdb_ischunk(mhod, "mhod", "album")) { if (ret = itunesdb_get_mhod_string(mhod, &rec->album)) return ret; } else if (itunesdb_ischunk(mhod, "mhod", "genre")) { Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-17 13:00:32 UTC (rev 414) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-24 03:34:31 UTC (rev 415) @@ -331,6 +331,7 @@ if (ret = serialize_uint32le(sio, "unk38", "%u", &mhit->unk38)) return ret; if (ret = serialize_uint16le(sio, "gapless_track", "%u", &mhit->gapless_track)) return ret; if (ret = serialize_uint16le(sio, "gapless_album", "%u", &mhit->gapless_album)) return ret; + if (ret = serialize_uint8_array(sio, "unknown_hash", "%02X ", mhit->unknown_hash, sizeof(mhit->unknown_hash))) return ret; return 0; } @@ -478,6 +479,34 @@ return 0; } +static void mhod_smartplaylist_data_finish(itunesdb_chunk_t* chunk) +{ + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_smartplaylist_data_t* spd = &mhod->data.spd; + memset(spd, 0, sizeof(*spd)); +} + +static int mhod_smartplaylist_data_serialize(itunesdb_chunk_t* chunk, const char *name, serializer_t* sio) +{ + int ret = 0; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_smartplaylist_data_t* spd = &mhod->data.spd; + + if (ret = serialize_uint8(sio, "live_update", "%d", &spd->live_update)) return ret; + if (ret = serialize_uint8(sio, "check_rules", "%d", &spd->check_rules)) return ret; + if (ret = serialize_uint8(sio, "check_limits", "%d", &spd->check_limits)) return ret; + if (ret = serialize_uint8(sio, "limit_type", "%d", &spd->limit_type)) return ret; + if (ret = serialize_uint8(sio, "limit_sort", "%d", &spd->limit_sort)) return ret; + if (ret = serialize_uint8(sio, "unknown1", "%d", &spd->unknown1)) return ret; + if (ret = serialize_uint8(sio, "unknown2", "%d", &spd->unknown2)) return ret; + if (ret = serialize_uint8(sio, "unknown3", "%d", &spd->unknown3)) return ret; + if (ret = serialize_uint32le(sio, "limit_value", "%d", &spd->limit_value)) return ret; + if (ret = serialize_uint8(sio, "match_checked_only", "%d", &spd->match_checked_only)) return ret; + if (ret = serialize_uint8(sio, "reverse_limit_sort", "%d", &spd->reverse_limit_sort)) return ret; + + return ret; +} + static void mhod_index_finish(itunesdb_chunk_t* chunk) { itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; @@ -642,10 +671,13 @@ {14, "description", 0, mhod_string_finish, mhod_string_serialize}, {15, "podcast_enclosure_url", 0, mhod_url_finish, mhod_url_serialize}, {16, "podcast_rss_url", 0, mhod_url_finish, mhod_url_serialize}, + {22, "album_artist", 0, mhod_string_finish, mhod_string_serialize}, + {23, "sort_artist", 0, mhod_string_finish, mhod_string_serialize}, {27, "sort_title", 0, mhod_string_finish, mhod_string_serialize}, {28, "sort_album", 0, mhod_string_finish, mhod_string_serialize}, {29, "sort_albumartist", 0, mhod_string_finish, mhod_string_serialize}, {30, "sort_composer", 0, mhod_string_finish, mhod_string_serialize}, + {50, "smartplaylist_data", 0, mhod_smartplaylist_data_finish, mhod_smartplaylist_data_serialize}, {52, "index", 0, mhod_index_finish, mhod_index_serialize}, {53, "library_playlist_index", 0, mhod_library_playlist_index_finish, mhod_library_playlist_index_serialize}, {100, "playlist_column", 0x288, mhod_playlist_column_finish, mhod_playlist_column_serialize}, @@ -919,7 +951,7 @@ } /* Read children for this chunk. */ - if (strncmp(chunk->id, "mhlt", 4) == 0 || strncmp(chunk->id, "mhlp", 4) == 0) { + if (strncmp(chunk->id, "mhla", 4) == 0 || strncmp(chunk->id, "mhlt", 4) == 0 || strncmp(chunk->id, "mhlp", 4) == 0) { /* chunk->overall_size represents the number of children for "mhlt" and "mhlp" chunks */ chunk->num_children = chunk->overall_size; chunk->childlen = (itunesdb_chunk_t*)calloc(chunk->num_children, sizeof(itunesdb_chunk_t)); Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-09-17 13:00:32 UTC (rev 414) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-09-24 03:34:31 UTC (rev 415) @@ -137,6 +137,7 @@ uint32_t unk38; uint16_t gapless_track; uint16_t gapless_album; + uint8_t unknown_hash[20]; } itunesdb_mhit_t; typedef struct { @@ -180,6 +181,20 @@ } itunesdb_mhod_url_t; typedef struct { + uint8_t live_update; + uint8_t check_rules; + uint8_t check_limits; + uint8_t limit_type; + uint8_t limit_sort; + uint8_t unknown1; + uint8_t unknown2; + uint8_t unknown3; + uint32_t limit_value; + uint8_t match_checked_only; + uint8_t reverse_limit_sort; +} itunesdb_mhod_smartplaylist_data_t; + +typedef struct { uint32_t type; uint32_t num_entries; uint8_t padding[40]; @@ -233,6 +248,7 @@ union { itunesdb_mhod_string_t str; itunesdb_mhod_url_t url; + itunesdb_mhod_smartplaylist_data_t spd; itunesdb_mhod_index_t index; itunesdb_mhod_playlist_column_t pc; itunesdb_mhod_playlist_order_t po; Modified: trunk/pmplib/lib/pmp_ipod/util.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/util.c 2007-09-17 13:00:32 UTC (rev 414) +++ trunk/pmplib/lib/pmp_ipod/util.c 2007-09-24 03:34:31 UTC (rev 415) @@ -42,7 +42,7 @@ { size_t i; for (i = 0;i < size;i++) { - if (array[0] != value) { + if (array[i] != value) { return 0; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-09-25 16:23:30
|
Revision: 417 http://pmplib.svn.sourceforge.net/pmplib/?rev=417&view=rev Author: nyaochi Date: 2007-09-25 09:23:32 -0700 (Tue, 25 Sep 2007) Log Message: ----------- More work on analyzing the iTunesDB format. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/ipod.h trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-25 14:27:01 UTC (rev 416) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-25 16:23:32 UTC (rev 417) @@ -40,6 +40,7 @@ #include "util.h" #include "ipod.h" #include "ipodprop.h" +#include "ipodserial.h" #include "itunesdb.h" #include "playcounts.h" @@ -117,6 +118,7 @@ ipodprop_finish(&ip); ucs2free(path); + return ret; } @@ -360,7 +362,7 @@ } /* Construct an "mhod" chunk for album artist. */ - if (rec->artist && *rec->artist) { + if (rec->album_artist && *rec->album_artist) { mhod = itunesdb_new_child(mhit); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "album_artist")) return ret; @@ -565,7 +567,7 @@ return ret; } -static int comp_artist(const void *_x, const void *_y) +static int comp_sortartist(const void *_x, const void *_y) { int ret = 0; const sorted_index_t *xi = (const sorted_index_t*)_x; @@ -581,6 +583,41 @@ return ret; } +static int comp_albumartist(const void *_x, const void *_y) +{ + int ret = 0; + const sorted_index_t *xi = (const sorted_index_t*)_x; + const sorted_index_t *yi = (const sorted_index_t*)_y; + const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; + const pmp_music_record_t* x = &base[xi->index]; + const pmp_music_record_t* y = &base[yi->index]; + + ret = comp_string(x->album_artist, y->album_artist); + if (ret == 0) { + return comp_album(_x, _y); + } + return ret; +} + +static int comp_albumartist_sortartist(const void *_x, const void *_y) +{ + int ret = 0; + const sorted_index_t *xi = (const sorted_index_t*)_x; + const sorted_index_t *yi = (const sorted_index_t*)_y; + const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; + const pmp_music_record_t* x = &base[xi->index]; + const pmp_music_record_t* y = &base[yi->index]; + + ret = comp_string(x->album_artist, y->album_artist); + if (ret == 0) { + ret = comp_string(x->artist, y->artist); + if (ret == 0) { + return comp_album(_x, _y); + } + } + return ret; +} + static int comp_genre(const void *_x, const void *_y) { int ret = 0; @@ -592,7 +629,7 @@ ret = comp_string(x->genre, y->genre); if (ret == 0) { - return comp_artist(_x, _y); + return comp_sortartist(_x, _y); } return ret; } @@ -654,10 +691,16 @@ if (ret = itunesdb_set_mhod_string(mhod, artist)) return ret; } - mhia_data->num_children = 2; + mhod = itunesdb_new_child(mhia); + if (mhod) { + if (ret = itunesdb_init(mhod, "mhod", "sort_artist_albumlist")) return ret; + if (ret = itunesdb_set_mhod_string(mhod, artist)) return ret; + } + + mhia_data->num_children = 3; mhia_data->album_id = i; mhia_data->timestamp = 0; - mhia_data->unknown1 = 2; + mhia_data->unknown1 = 258; } prev_album = album; @@ -684,7 +727,7 @@ } mhyp_data->flag_master = 1; - mhyp_data->id = 0x7520EA5FA870F9EA; + mhyp_data->id = 0xC6EEB59E19650DDA; mhyp_data->unk3 = 0; mhyp_data->unk4 = 1; mhyp_data->sort_order = 1; @@ -696,7 +739,7 @@ if (ret = itunesdb_set_mhod_string(mhod, ucs2cs_master)) return ret; } - /* Construct an "mhod" chunk for title index. */ + /* Construct an "mhod" chunk for index: title. */ mhod = itunesdb_new_child(mhyp); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; @@ -704,15 +747,15 @@ if (ret = itunesdb_set_mhod_index(mhod, 0x03, si, num_records)) return ret; } - /* Construct an "mhod" chunk for artist index. */ + /* Construct an "mhod" chunk for index: sortartist, disc/tracknumber, title. */ mhod = itunesdb_new_child(mhyp); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; - qsort(si, num_records, sizeof(si[0]), comp_artist); + qsort(si, num_records, sizeof(si[0]), comp_sortartist); if (ret = itunesdb_set_mhod_index(mhod, 0x05, si, num_records)) return ret; } - /* Construct an "mhod" chunk for album index. */ + /* Construct an "mhod" chunk for index: album, disc/tracknumber, title. */ mhod = itunesdb_new_child(mhyp); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; @@ -720,7 +763,7 @@ if (ret = itunesdb_set_mhod_index(mhod, 0x04, si, num_records)) return ret; } - /* Construct an "mhod" chunk for genre index. */ + /* Construct an "mhod" chunk for index: genre, sortartist, album, disc/tracknumber, title */ mhod = itunesdb_new_child(mhyp); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; @@ -728,7 +771,7 @@ if (ret = itunesdb_set_mhod_index(mhod, 0x07, si, num_records)) return ret; } - /* Construct an "mhod" chunk for composer index. */ + /* Construct an "mhod" chunk for index: composer, title. */ mhod = itunesdb_new_child(mhyp); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; @@ -736,23 +779,23 @@ if (ret = itunesdb_set_mhod_index(mhod, 0x12, si, num_records)) return ret; } - /* Construct an "mhod" chunk for 'unknown' index. */ + /* Construct an "mhod" chunk for index: albumartist, sortartist, disc/tracknumber, title. */ mhod = itunesdb_new_child(mhyp); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; - qsort(si, num_records, sizeof(si[0]), comp_album); + qsort(si, num_records, sizeof(si[0]), comp_albumartist_sortartist); if (ret = itunesdb_set_mhod_index(mhod, 0x23, si, num_records)) return ret; } - /* Construct an "mhod" chunk for 'unknown' index. */ + /* Construct an "mhod" chunk for index: albumartist, album, disc/tracknumber, title*/ mhod = itunesdb_new_child(mhyp); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; - qsort(si, num_records, sizeof(si[0]), comp_album); + qsort(si, num_records, sizeof(si[0]), comp_albumartist); if (ret = itunesdb_set_mhod_index(mhod, 0x24, si, num_records)) return ret; } - /* Construct an "mhod" chunk for 'unknown' index. */ + /* Construct an "mhod" chunk for index: title?. */ mhod = itunesdb_new_child(mhyp); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; @@ -760,7 +803,7 @@ if (ret = itunesdb_set_mhod_index(mhod, 0x1D, si, num_records)) return ret; } - /* Construct an "mhod" chunk for 'unknown' index. */ + /* Construct an "mhod" chunk for index: title?. */ mhod = itunesdb_new_child(mhyp); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; @@ -768,7 +811,7 @@ if (ret = itunesdb_set_mhod_index(mhod, 0x1E, si, num_records)) return ret; } - /* Construct an "mhod" chunk for 'unknown' index. */ + /* Construct an "mhod" chunk for index: title?. */ mhod = itunesdb_new_child(mhyp); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; @@ -903,7 +946,6 @@ if (ret = itunesdb_init(mhbd, "mhbd", NULL)) return ret; mhbd_data = (itunesdb_mhbd_t*)mhbd->data; -#if 0 /* Construct "mhsd" chunk with album_list type (type = 4). */ mhsd = itunesdb_new_child(mhbd); if (mhsd) { @@ -923,7 +965,6 @@ } else { return IPODE_FAILEDNEWCHUNK; } -#endif /* Construct "mhsd" chunk with track type (type = 1). */ mhsd = itunesdb_new_child(mhbd); Modified: trunk/pmplib/lib/pmp_ipod/ipod.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.h 2007-09-25 14:27:01 UTC (rev 416) +++ trunk/pmplib/lib/pmp_ipod/ipod.h 2007-09-25 16:23:32 UTC (rev 417) @@ -51,6 +51,7 @@ typedef struct { itunesdb_chunk_t* itunesdb; playcounts_t* pcs; + uint8_t serial[8]; } ipod_t; const ipod_descriptor_t* ipod_detect(const ucs2char_t* path_to_device, const char *id, pmp_device_information_t* ptr_info); Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-25 14:27:01 UTC (rev 416) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-25 16:23:32 UTC (rev 417) @@ -576,12 +576,12 @@ for (i = 0;i < lp_index->num_entries;++i) { char fieldname[128]; - sprintf(fieldname, "entries[%d].unknown1", i); - if (ret = serialize_uint32le(sio, fieldname, "%u", &lp_index->entries[i].unknown1)) return ret; - sprintf(fieldname, "entries[%d].unknown2", i); - if (ret = serialize_uint32le(sio, fieldname, "%u", &lp_index->entries[i].unknown2)) return ret; - sprintf(fieldname, "entries[%d].unknown3", i); - if (ret = serialize_uint32le(sio, fieldname, "%u", &lp_index->entries[i].unknown3)) return ret; + sprintf(fieldname, "entries[%d].value", i); + if (ret = serialize_uint32le(sio, fieldname, "%u", &lp_index->entries[i].value)) return ret; + sprintf(fieldname, "entries[%d].begin", i); + if (ret = serialize_uint32le(sio, fieldname, "%u", &lp_index->entries[i].begin)) return ret; + sprintf(fieldname, "entries[%d].num", i); + if (ret = serialize_uint32le(sio, fieldname, "%u", &lp_index->entries[i].num)) return ret; } return 0; Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-09-25 14:27:01 UTC (rev 416) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-09-25 16:23:32 UTC (rev 417) @@ -223,9 +223,9 @@ } itunesdb_mhod_playlist_column_t; typedef struct { - uint32_t unknown1; - uint32_t unknown2; - uint32_t unknown3; + uint32_t value; + uint32_t begin; + uint32_t num; } itunesdb_mhod_library_playlist_entry_t; typedef struct { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-09-30 15:57:52
|
Revision: 418 http://pmplib.svn.sourceforge.net/pmplib/?rev=418&view=rev Author: nyaochi Date: 2007-09-30 08:57:53 -0700 (Sun, 30 Sep 2007) Log Message: ----------- - PMPlib now works with iPod nano 3rd gen. Setting dbid and/or dbid2 fields in "mhit" chunk made this magic. - Sync with the latest fields in "mhit" chunk although I'm not sure these new fields are necessary to the latest iPods. - Generating prefix indices ("mhod" chunk type 53). Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-25 16:23:32 UTC (rev 417) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-09-30 15:57:53 UTC (rev 418) @@ -294,10 +294,11 @@ ) { int ret = 0; + const ucs2char_t* value = NULL; itunesdb_chunk_t* mhod = NULL; itunesdb_mhit_t* mhit_data = (itunesdb_mhit_t*)mhit->data; - mhit_data->uid = uid; + mhit_data->uid = 1008 + uid * 2; mhit_data->visible = 1; switch (rec->codec) { case PMPCODEC_MPEGLAYER3: @@ -306,12 +307,12 @@ mhit_data->type2 = rec->is_vbr ? 0x01 : 0x00; break; default: - mhit_data->type1 = 0x01; + mhit_data->type1 = 0x00; mhit_data->type2 = 0x01; break; } mhit_data->compilation = rec->is_compilation ? 1 : 0; - mhit_data->rating = rec->rating * 20; + mhit_data->rating = rec->rating + 1; mhit_data->last_modified = (uint32_t)from_time((time_t)rec->ts_update); mhit_data->filesize = rec->filesize; mhit_data->duration = rec->duration; @@ -323,7 +324,7 @@ mhit_data->disc_number = rec->disc_number; mhit_data->total_discs = rec->total_discs; mhit_data->date_added = (uint32_t)from_time((time_t)rec->ts_import); - mhit_data->dbid = 0; + mhit_data->dbid = 0xFA14A98319EB2BBD + uid; mhit_data->unk9 = 0xFFFF; switch (rec->codec) { case PMPCODEC_MPEGLAYER3: @@ -338,10 +339,16 @@ break; } mhit_data->unk14_1 = 12; - mhit_data->is_played = 2; + mhit_data->is_played = 1; mhit_data->unk27 = 1; mhit_data->media_type = 1; mhit_data->num_samples = rec->num_samples; + mhit_data->dbid2 = 0xC6EEB59E19650E3C + uid; + mhit_data->unk40 = 1011; + mhit_data->newunk3 = 0xBCD054CD8C063208; + mhit_data->unk43 = 0x0000808080808080; + mhit_data->newunk5 = 106; + mhit_data->newunk7 = 32; /* Construct an "mhod" chunk for title. */ if (rec->title && *rec->title) { @@ -362,11 +369,12 @@ } /* Construct an "mhod" chunk for album artist. */ - if (rec->album_artist && *rec->album_artist) { + value = (rec->album_artist && *rec->album_artist) ? rec->album_artist : rec->artist; + if (value && *value) { mhod = itunesdb_new_child(mhit); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "album_artist")) return ret; - if (ret = itunesdb_set_mhod_string(mhod, rec->album_artist)) return ret; + if (ret = itunesdb_set_mhod_string(mhod, value)) return ret; } } @@ -520,8 +528,8 @@ static int comp_title(const void *_x, const void *_y) { - const sorted_index_t *xi = (const sorted_index_t*)_x; - const sorted_index_t *yi = (const sorted_index_t*)_y; + const itunesdb_playlist_entry_t *xi = (const itunesdb_playlist_entry_t*)_x; + const itunesdb_playlist_entry_t *yi = (const itunesdb_playlist_entry_t*)_y; const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; @@ -529,11 +537,16 @@ return comp_string(x->title, y->title); } +static uint32_t prefix_title(const pmp_music_record_t* record) +{ + return ((record->title != NULL) ? record->title[0] : 0); +} + static int comp_album(const void *_x, const void *_y) { int ret = 0; - const sorted_index_t *xi = (const sorted_index_t*)_x; - const sorted_index_t *yi = (const sorted_index_t*)_y; + const itunesdb_playlist_entry_t *xi = (const itunesdb_playlist_entry_t*)_x; + const itunesdb_playlist_entry_t *yi = (const itunesdb_playlist_entry_t*)_y; const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; @@ -551,11 +564,16 @@ return ret; } +static uint32_t prefix_album(const pmp_music_record_t* record) +{ + return ((record->album != NULL) ? record->album[0] : 0); +} + static int comp_album_for_list(const void *_x, const void *_y) { int ret = 0; - const sorted_index_t *xi = (const sorted_index_t*)_x; - const sorted_index_t *yi = (const sorted_index_t*)_y; + const itunesdb_playlist_entry_t *xi = (const itunesdb_playlist_entry_t*)_x; + const itunesdb_playlist_entry_t *yi = (const itunesdb_playlist_entry_t*)_y; const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; @@ -570,8 +588,8 @@ static int comp_sortartist(const void *_x, const void *_y) { int ret = 0; - const sorted_index_t *xi = (const sorted_index_t*)_x; - const sorted_index_t *yi = (const sorted_index_t*)_y; + const itunesdb_playlist_entry_t *xi = (const itunesdb_playlist_entry_t*)_x; + const itunesdb_playlist_entry_t *yi = (const itunesdb_playlist_entry_t*)_y; const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; @@ -583,11 +601,16 @@ return ret; } +static uint32_t prefix_sortartist(const pmp_music_record_t* record) +{ + return ((record->artist != NULL) ? record->artist[0] : 0); +} + static int comp_albumartist(const void *_x, const void *_y) { int ret = 0; - const sorted_index_t *xi = (const sorted_index_t*)_x; - const sorted_index_t *yi = (const sorted_index_t*)_y; + const itunesdb_playlist_entry_t *xi = (const itunesdb_playlist_entry_t*)_x; + const itunesdb_playlist_entry_t *yi = (const itunesdb_playlist_entry_t*)_y; const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; @@ -602,8 +625,8 @@ static int comp_albumartist_sortartist(const void *_x, const void *_y) { int ret = 0; - const sorted_index_t *xi = (const sorted_index_t*)_x; - const sorted_index_t *yi = (const sorted_index_t*)_y; + const itunesdb_playlist_entry_t *xi = (const itunesdb_playlist_entry_t*)_x; + const itunesdb_playlist_entry_t *yi = (const itunesdb_playlist_entry_t*)_y; const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; @@ -621,8 +644,8 @@ static int comp_genre(const void *_x, const void *_y) { int ret = 0; - const sorted_index_t *xi = (const sorted_index_t*)_x; - const sorted_index_t *yi = (const sorted_index_t*)_y; + const itunesdb_playlist_entry_t *xi = (const itunesdb_playlist_entry_t*)_x; + const itunesdb_playlist_entry_t *yi = (const itunesdb_playlist_entry_t*)_y; const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; @@ -634,11 +657,16 @@ return ret; } +static uint32_t prefix_genre(const pmp_music_record_t* record) +{ + return ((record->genre != NULL) ? record->genre[0] : 0); +} + static int comp_composer(const void *_x, const void *_y) { int ret = 0; - const sorted_index_t *xi = (const sorted_index_t*)_x; - const sorted_index_t *yi = (const sorted_index_t*)_y; + const itunesdb_playlist_entry_t *xi = (const itunesdb_playlist_entry_t*)_x; + const itunesdb_playlist_entry_t *yi = (const itunesdb_playlist_entry_t*)_y; const pmp_music_record_t* base = (const pmp_music_record_t*)xi->base; const pmp_music_record_t* x = &base[xi->index]; const pmp_music_record_t* y = &base[yi->index]; @@ -650,6 +678,25 @@ return ret; } +static uint32_t prefix_composer(const pmp_music_record_t* record) +{ + return ((record->composer != NULL) ? record->composer[0] : 0); +} + + +typedef uint32_t (*prefix_func)(const pmp_music_record_t* record); + +static void set_prefix(itunesdb_playlist_entry_t* array, size_t n, prefix_func func) +{ + size_t i; + + for (i = 0;i < n;++i) { + itunesdb_playlist_entry_t *x = &array[i]; + const pmp_music_record_t* base = (const pmp_music_record_t*)x->base; + x->prefix = func(&base[x->index]); + } +} + static int set_album_list(itunesdb_chunk_t* mhla, const pmp_music_record_t* records, int num_records) { int i; @@ -658,7 +705,7 @@ const ucs2char_t* prev_artist = NULL; itunesdb_chunk_t *mhod = NULL, *mhia = NULL; itunesdb_mhia_t *mhia_data = NULL; - sorted_index_t* si = (sorted_index_t*)calloc(num_records, sizeof(sorted_index_t)); + itunesdb_playlist_entry_t* si = (itunesdb_playlist_entry_t*)calloc(num_records, sizeof(itunesdb_playlist_entry_t)); if (!si) { return IPODE_OUTOFMEMORY; @@ -715,7 +762,8 @@ int ret = 0; itunesdb_chunk_t *mhod = NULL, *mhip = NULL; itunesdb_mhyp_t* mhyp_data = (itunesdb_mhyp_t*)mhyp->data; - sorted_index_t* si = (sorted_index_t*)calloc(num_records, sizeof(sorted_index_t)); + itunesdb_playlist_entry_t* si = + (itunesdb_playlist_entry_t*)calloc(num_records, sizeof(itunesdb_playlist_entry_t)); const static ucs2char_t ucs2cs_master[] = {'M','a','s','t','e','r',0}; if (!si) { @@ -744,7 +792,14 @@ if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_title); - if (ret = itunesdb_set_mhod_index(mhod, 0x03, si, num_records)) return ret; + if (ret = itunesdb_set_mhod_order(mhod, 0x03, si, num_records)) return ret; + + mhod = itunesdb_new_child(mhyp); + if (mhod) { + if (ret = itunesdb_init(mhod, "mhod", "library_playlist_index")) return ret; + set_prefix(si, num_records, prefix_title); + if (ret = itunesdb_set_mhod_index(mhod, 0x03, si, num_records)) return ret; + } } /* Construct an "mhod" chunk for index: sortartist, disc/tracknumber, title. */ @@ -752,7 +807,14 @@ if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_sortartist); - if (ret = itunesdb_set_mhod_index(mhod, 0x05, si, num_records)) return ret; + if (ret = itunesdb_set_mhod_order(mhod, 0x05, si, num_records)) return ret; + + mhod = itunesdb_new_child(mhyp); + if (mhod) { + if (ret = itunesdb_init(mhod, "mhod", "library_playlist_index")) return ret; + set_prefix(si, num_records, prefix_sortartist); + if (ret = itunesdb_set_mhod_index(mhod, 0x05, si, num_records)) return ret; + } } /* Construct an "mhod" chunk for index: album, disc/tracknumber, title. */ @@ -760,7 +822,14 @@ if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_album); - if (ret = itunesdb_set_mhod_index(mhod, 0x04, si, num_records)) return ret; + if (ret = itunesdb_set_mhod_order(mhod, 0x04, si, num_records)) return ret; + + mhod = itunesdb_new_child(mhyp); + if (mhod) { + if (ret = itunesdb_init(mhod, "mhod", "library_playlist_index")) return ret; + set_prefix(si, num_records, prefix_album); + if (ret = itunesdb_set_mhod_index(mhod, 0x04, si, num_records)) return ret; + } } /* Construct an "mhod" chunk for index: genre, sortartist, album, disc/tracknumber, title */ @@ -768,7 +837,14 @@ if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_genre); - if (ret = itunesdb_set_mhod_index(mhod, 0x07, si, num_records)) return ret; + if (ret = itunesdb_set_mhod_order(mhod, 0x07, si, num_records)) return ret; + + mhod = itunesdb_new_child(mhyp); + if (mhod) { + if (ret = itunesdb_init(mhod, "mhod", "library_playlist_index")) return ret; + set_prefix(si, num_records, prefix_genre); + if (ret = itunesdb_set_mhod_index(mhod, 0x07, si, num_records)) return ret; + } } /* Construct an "mhod" chunk for index: composer, title. */ @@ -776,7 +852,14 @@ if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_composer); - if (ret = itunesdb_set_mhod_index(mhod, 0x12, si, num_records)) return ret; + if (ret = itunesdb_set_mhod_order(mhod, 0x12, si, num_records)) return ret; + + mhod = itunesdb_new_child(mhyp); + if (mhod) { + if (ret = itunesdb_init(mhod, "mhod", "library_playlist_index")) return ret; + set_prefix(si, num_records, prefix_composer); + if (ret = itunesdb_set_mhod_index(mhod, 0x12, si, num_records)) return ret; + } } /* Construct an "mhod" chunk for index: albumartist, sortartist, disc/tracknumber, title. */ @@ -784,7 +867,7 @@ if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_albumartist_sortartist); - if (ret = itunesdb_set_mhod_index(mhod, 0x23, si, num_records)) return ret; + if (ret = itunesdb_set_mhod_order(mhod, 0x23, si, num_records)) return ret; } /* Construct an "mhod" chunk for index: albumartist, album, disc/tracknumber, title*/ @@ -792,7 +875,7 @@ if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_albumartist); - if (ret = itunesdb_set_mhod_index(mhod, 0x24, si, num_records)) return ret; + if (ret = itunesdb_set_mhod_order(mhod, 0x24, si, num_records)) return ret; } /* Construct an "mhod" chunk for index: title?. */ @@ -800,7 +883,14 @@ if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_title); - if (ret = itunesdb_set_mhod_index(mhod, 0x1D, si, num_records)) return ret; + if (ret = itunesdb_set_mhod_order(mhod, 0x1D, si, num_records)) return ret; + + mhod = itunesdb_new_child(mhyp); + if (mhod) { + if (ret = itunesdb_init(mhod, "mhod", "library_playlist_index")) return ret; + set_prefix(si, num_records, prefix_title); + if (ret = itunesdb_set_mhod_index(mhod, 0x1D, si, num_records)) return ret; + } } /* Construct an "mhod" chunk for index: title?. */ @@ -808,7 +898,7 @@ if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_title); - if (ret = itunesdb_set_mhod_index(mhod, 0x1E, si, num_records)) return ret; + if (ret = itunesdb_set_mhod_order(mhod, 0x1E, si, num_records)) return ret; } /* Construct an "mhod" chunk for index: title?. */ @@ -816,7 +906,7 @@ if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_title); - if (ret = itunesdb_set_mhod_index(mhod, 0x1F, si, num_records)) return ret; + if (ret = itunesdb_set_mhod_order(mhod, 0x1F, si, num_records)) return ret; } /* End of the series of "mhod" chunks. */ @@ -831,13 +921,13 @@ mhip_data = (itunesdb_mhip_t*)mhip->data; mhip_data->flag_podcast_group = 0; - mhip_data->track_id = i; - mhip_data->group_id = i + num_records; + mhip_data->track_id = 1008 + i * 2; + mhip_data->group_id = 1008 + i * 2 + 1; mhod = itunesdb_new_child(mhip); if (mhod) { if (ret = itunesdb_init(mhod, "mhod", "playlist_order")) return ret; - if (ret = itunesdb_set_mhod_playlist_order(mhod, i+1)) return ret; + if (ret = itunesdb_set_mhod_playlist_order(mhod, 1008 + i * 2 + 1)) return ret; } else { return IPODE_OUTOFMEMORY; } @@ -946,6 +1036,7 @@ if (ret = itunesdb_init(mhbd, "mhbd", NULL)) return ret; mhbd_data = (itunesdb_mhbd_t*)mhbd->data; +#if 0 /* Construct "mhsd" chunk with album_list type (type = 4). */ mhsd = itunesdb_new_child(mhbd); if (mhsd) { @@ -965,6 +1056,7 @@ } else { return IPODE_FAILEDNEWCHUNK; } +#endif /* Construct "mhsd" chunk with track type (type = 1). */ mhsd = itunesdb_new_child(mhbd); Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-25 16:23:32 UTC (rev 417) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-09-30 15:57:53 UTC (rev 418) @@ -332,6 +332,17 @@ if (ret = serialize_uint16le(sio, "gapless_track", "%u", &mhit->gapless_track)) return ret; if (ret = serialize_uint16le(sio, "gapless_album", "%u", &mhit->gapless_album)) return ret; if (ret = serialize_uint8_array(sio, "unknown_hash", "%02X ", mhit->unknown_hash, sizeof(mhit->unknown_hash))) return ret; + if (ret = serialize_uint32le(sio, "newunk1", "%u", &mhit->newunk1)) return ret; + if (ret = serialize_uint32le(sio, "newunk2", "%u", &mhit->newunk2)) return ret; + if (ret = serialize_uint32le(sio, "unk40", "%u", &mhit->unk40)) return ret; + if (ret = serialize_uint64le(sio, "newunk3", "%016llX", &mhit->newunk3)) return ret; + if (ret = serialize_uint32le(sio, "unk41", "%u", &mhit->unk41)) return ret; + if (ret = serialize_uint32le(sio, "unk42", "%u", &mhit->unk42)) return ret; + if (ret = serialize_uint64le(sio, "unk43", "%016llX", &mhit->unk43)) return ret; + if (ret = serialize_uint8_array(sio, "newunk4", "%02X ", mhit->newunk4, sizeof(mhit->newunk4))) return ret; + if (ret = serialize_uint32le(sio, "newunk5", "%u", &mhit->newunk5)) return ret; + if (ret = serialize_uint32le(sio, "newunk6", "%u", &mhit->newunk6)) return ret; + if (ret = serialize_uint32le(sio, "newunk7", "%u", &mhit->newunk7)) return ret; return 0; } @@ -1099,7 +1110,7 @@ } -int itunesdb_set_mhod_index(itunesdb_chunk_t* chunk, uint32_t type, sorted_index_t* si, uint32_t n) +int itunesdb_set_mhod_order(itunesdb_chunk_t* chunk, uint32_t type, itunesdb_playlist_entry_t* si, uint32_t n) { uint32_t i; itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; @@ -1123,6 +1134,51 @@ return 0; } +int itunesdb_set_mhod_index(itunesdb_chunk_t* chunk, uint32_t type, itunesdb_playlist_entry_t* si, uint32_t n) +{ + uint32_t i, m = 0, prev = 0; + itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; + itunesdb_mhod_library_playlist_index_t* index = &mhod->data.lp_index; + + /* Make sure this is an "mhod" chunk. */ + if (strncmp(chunk->id, "mhod", 4) != 0) { + return IPODE_INCOMPATIBLECHUNK; + } + + /* Store the index type. */ + index->type = type; + /* Initialize the number of entries as zero. */ + index->num_entries = 0; + + /* Does nothing for an empty array. */ + if (n <= 0) { + return 0; + } + + /* Allocate the entry array with the maximum size. */ + index->entries = (itunesdb_mhod_library_playlist_entry_t*)calloc( + n, sizeof(itunesdb_mhod_library_playlist_entry_t)); + if (!index->entries) { + return IPODE_OUTOFMEMORY; + } + + prev = si[0].prefix + 1; + for (i = 0;i < n;++i) { + if (prev != si[i].prefix) { + index->entries[m].value = si[i].prefix; + index->entries[m].begin = i; + index->entries[m].num = 1; + ++m; + } else { + ++index->entries[m-1].num; + } + prev = si[i].prefix; + } + + index->num_entries = m; + return 0; +} + int itunesdb_set_mhod_playlist_order(itunesdb_chunk_t* chunk, uint32_t order) { itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-09-25 16:23:32 UTC (rev 417) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-09-30 15:57:53 UTC (rev 418) @@ -138,6 +138,17 @@ uint16_t gapless_track; uint16_t gapless_album; uint8_t unknown_hash[20]; + uint32_t newunk1; + uint32_t newunk2; + uint32_t unk40; + uint64_t newunk3; + uint32_t unk41; + uint32_t unk42; + uint64_t unk43; + uint8_t newunk4[36]; + uint32_t newunk5; + uint32_t newunk6; + uint32_t newunk7; } itunesdb_mhit_t; typedef struct { @@ -289,9 +300,10 @@ } itunesdb_chunkdecl_t; typedef struct { - uint32_t index; - const void* base; -} sorted_index_t; + uint32_t index; + uint32_t prefix; + const void* base; +} itunesdb_playlist_entry_t; /** * Initialize a chunk with identifier and subtype (for "mhod" chunk) @@ -335,7 +347,8 @@ * @param n The number of entries in the sorted index. * @retval int zero if succeeded, otherwise nonzero. */ -int itunesdb_set_mhod_index(itunesdb_chunk_t* chunk, uint32_t sort_order, sorted_index_t* si, uint32_t n); +int itunesdb_set_mhod_order(itunesdb_chunk_t* chunk, uint32_t sort_order, itunesdb_playlist_entry_t* si, uint32_t n); +int itunesdb_set_mhod_index(itunesdb_chunk_t* chunk, uint32_t sort_order, itunesdb_playlist_entry_t* si, uint32_t n); /** * Set ordinal value to "mhod" chunk. Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-09-25 16:23:32 UTC (rev 417) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-09-30 15:57:53 UTC (rev 418) @@ -40,7 +40,7 @@ <Tool Name="VCCLCompilerTool" Optimization="0" - AdditionalIncludeDirectories="$(SolutionDir)include" + AdditionalIncludeDirectories="$(SolutionDir)include;win32" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PMP_IPOD_EXPORTS" MinimalRebuild="true" BasicRuntimeChecks="3" @@ -61,7 +61,7 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies=".\win32spti\ipodprop_win32spti.lib shlwapi.lib" + AdditionalDependencies=".\win32\usbinfo_win32.lib .\win32spti\ipodprop_win32spti.lib shlwapi.lib" LinkIncremental="2" GenerateDebugInformation="true" SubSystem="2" @@ -117,7 +117,7 @@ /> <Tool Name="VCCLCompilerTool" - AdditionalIncludeDirectories="$(SolutionDir)include" + AdditionalIncludeDirectories="$(SolutionDir)include;win32" PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;PMP_IPOD_EXPORTS" RuntimeLibrary="2" UsePrecompiledHeader="0" @@ -136,7 +136,7 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies=".\win32spti\ipodprop_win32spti.lib shlwapi.lib" + AdditionalDependencies=".\win32\usbinfo_win32.lib .\win32spti\ipodprop_win32spti.lib shlwapi.lib" LinkIncremental="1" GenerateDebugInformation="true" SubSystem="2" @@ -187,6 +187,10 @@ > </File> <File + RelativePath=".\ipodserial_win32.c" + > + </File> + <File RelativePath=".\itunesdb.c" > </File> @@ -229,6 +233,10 @@ > </File> <File + RelativePath=".\ipodserial.h" + > + </File> + <File RelativePath=".\itunesdb.h" > </File> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-10-05 14:47:50
|
Revision: 420 http://pmplib.svn.sourceforge.net/pmplib/?rev=420&view=rev Author: nyaochi Date: 2007-10-05 07:47:54 -0700 (Fri, 05 Oct 2007) Log Message: ----------- Initial commit of ArtworkDB routines. Added Paths: ----------- trunk/pmplib/lib/pmp_ipod/artworkdb.c trunk/pmplib/lib/pmp_ipod/artworkdb.h Added: trunk/pmplib/lib/pmp_ipod/artworkdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/artworkdb.c (rev 0) +++ trunk/pmplib/lib/pmp_ipod/artworkdb.c 2007-10-05 14:47:54 UTC (rev 420) @@ -0,0 +1,375 @@ +/* + * ArtworkDB reader/writer/dumper. + * + * Copyright (c) 2005-2007 Naoaki Okazaki + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* $Id:$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif/*HAVE_CONFIG_H*/ + +#include <os.h> +#include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_STRING_H +#include <string.h> +#endif/*HAVE_STRING_H*/ +#include <pmplib/ucs2char.h> + +#include "status.h" +#include "ipod.h" +#include "serialize.h" +#include "util.h" +#include "artworkdb.h" + +static void chunk_finish(artworkdb_chunk_t* chunk) +{ + free(chunk->data); + free(chunk->padding); + memset(chunk, 0, sizeof(*chunk)); +} + +static int mhfd_init(artworkdb_chunk_t* chunk, int def) +{ + artworkdb_mhfd_t* mhfd = NULL; + + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhfd", 4); + chunk->size = 132; + chunk->overall_size = 0; /* to be filled */ + } + + mhfd = (artworkdb_mhfd_t*)calloc(1, sizeof(artworkdb_mhfd_t)); + if (def && mhfd) { + mhfd->unknown1 = 0; + mhfd->version = 2; /* iTunes 4.9 or above */ + mhfd->num_children = 0; /* to be filled */ + mhfd->unknown3 = 0; + mhfd->next_nhii = 0; + mhfd->unknown5 = 0; + mhfd->unknown6 = 0; + mhfd->unknown7 = 2; + mhfd->unknown8 = 0; + mhfd->unknown9 = 0; + mhfd->unknown10 = 0; + mhfd->unknown11 = 0; + } + chunk->data = mhfd; + return mhfd ? 0 : IPODE_OUTOFMEMORY; +} + +static int mhfd_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +{ + int ret = 0; + artworkdb_mhfd_t* mhfd = (artworkdb_mhfd_t*)chunk->data; + + if (ret = serialize_uint32le(sio, "unknown1", "%d", &mhfd->unknown1)) return ret; + if (ret = serialize_uint32le(sio, "version", "%d", &mhfd->version)) return ret; + if (ret = serialize_uint32le(sio, "num_children", "%d", &mhfd->num_children)) return ret; + if (ret = serialize_uint32le(sio, "unknown3", "%d", &mhfd->unknown3)) return ret; + if (ret = serialize_uint32le(sio, "next_nhii", "%d", &mhfd->next_nhii)) return ret; + if (ret = serialize_uint64le(sio, "unknown5", "%016llX", &mhfd->unknown5)) return ret; + if (ret = serialize_uint64le(sio, "unknown6", "%016llX", &mhfd->unknown6)) return ret; + if (ret = serialize_uint32le(sio, "unknown7", "%d", &mhfd->unknown7)) return ret; + if (ret = serialize_uint32le(sio, "unknown8", "%d", &mhfd->unknown8)) return ret; + if (ret = serialize_uint32le(sio, "unknown9", "%d", &mhfd->unknown9)) return ret; + if (ret = serialize_uint32le(sio, "unknown10", "%d", &mhfd->unknown10)) return ret; + if (ret = serialize_uint32le(sio, "unknown11", "%d", &mhfd->unknown10)) return ret; + + return 0; +} + + + +static mhsd_init(artworkdb_chunk_t* chunk, int def) +{ + artworkdb_mhsd_t* mhsd = NULL; + + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhsd", 4); + chunk->size = 96; + chunk->overall_size = 0; /* to be filled */ + } + + mhsd = (artworkdb_mhsd_t*)calloc(1, sizeof(artworkdb_mhsd_t)); + if (mhsd && def) { + mhsd->type = 0; /* to be filled */ + } + + chunk->data = mhsd; + return mhsd ? 0 : IPODE_OUTOFMEMORY; +} + +static int mhsd_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +{ + int ret = 0; + artworkdb_mhsd_t* mhsd = (artworkdb_mhsd_t*)chunk->data; + + if (ret = serialize_uint32le(sio, "type", "%d", &mhsd->type)) return ret; + + return 0; +} + + + +static mhli_init(artworkdb_chunk_t* chunk, int def) +{ + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhli", 4); + chunk->size = 96; + chunk->overall_size = 0; /* to be filled */ + } + + chunk->data = 0; + return 0; +} + +static int mhli_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +{ + return 0; +} + + + +static int mhii_init(artworkdb_chunk_t* chunk, int def) +{ + artworkdb_mhii_t* mhii = NULL; + + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhii", 4); + chunk->size = 104; + chunk->overall_size = 0; /* to be filled */ + } + + mhii = (artworkdb_mhii_t*)calloc(1, sizeof(artworkdb_mhii_t)); + if (def && mhii) { + mhii->num_children = 0; + mhii->id = 0; + mhii->song_id = 0; + mhii->unknown4 = 0; + mhii->rating = 0; + mhii->unknown6 = 0; + mhii->ts_file = 0; + mhii->ts_import = 0; + mhii->original_size = 0; + } + chunk->data = mhii; + return mhii ? 0 : IPODE_OUTOFMEMORY; +} + +static int mhii_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +{ + int ret = 0; + artworkdb_mhii_t* mhii = (artworkdb_mhii_t*)chunk->data; + + if (ret = serialize_uint32le(sio, "num_children", "%d", &mhii->num_children)) return ret; + if (ret = serialize_uint32le(sio, "id", "%d", &mhii->id)) return ret; + if (ret = serialize_uint64le(sio, "song_id", "%016llX", &mhii->song_id)) return ret; + if (ret = serialize_uint32le(sio, "unknown4", "%d", &mhii->unknown4)) return ret; + if (ret = serialize_uint32le(sio, "rating", "%d", &mhii->rating)) return ret; + if (ret = serialize_uint32le(sio, "unknown6", "%d", &mhii->unknown6)) return ret; + if (ret = serialize_uint32le(sio, "ts_file", "%d", &mhii->ts_file)) return ret; + if (ret = serialize_uint32le(sio, "ts_import", "%d", &mhii->ts_import)) return ret; + if (ret = serialize_uint32le(sio, "original_size", "%d", &mhii->original_size)) return ret; + + return 0; +} + + +static int mhni_init(artworkdb_chunk_t* chunk, int def) +{ + artworkdb_mhni_t* mhni = NULL; + + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhni", 4); + chunk->size = 104; + chunk->overall_size = 0; /* to be filled */ + } + + mhni = (artworkdb_mhni_t*)calloc(1, sizeof(artworkdb_mhni_t)); + if (def && mhni) { + mhni->num_children = 0; + mhni->correlation_id = 0; + mhni->ithmb_offset = 0; + mhni->ithmb_size = 0; + mhni->vertical_padding = 0; + mhni->horizontal_padding = 0; + mhni->height = 0; + mhni->width = 0; + } + chunk->data = mhni; + return mhni ? 0 : IPODE_OUTOFMEMORY; +} + +static int mhni_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +{ + int ret = 0; + artworkdb_mhni_t* mhni = (artworkdb_mhni_t*)chunk->data; + + if (ret = serialize_uint32le(sio, "num_children", "%d", &mhni->num_children)) return ret; + if (ret = serialize_uint32le(sio, "correlation_id", "%d", &mhni->correlation_id)) return ret; + if (ret = serialize_uint32le(sio, "ithmb_offset", "%d", &mhni->ithmb_offset)) return ret; + if (ret = serialize_uint32le(sio, "ithmb_size", "%d", &mhni->ithmb_size)) return ret; + if (ret = serialize_uint16le(sio, "vertical_padding", "%d", &mhni->vertical_padding)) return ret; + if (ret = serialize_uint16le(sio, "horizontal_padding", "%d", &mhni->horizontal_padding)) return ret; + if (ret = serialize_uint16le(sio, "height", "%d", &mhni->height)) return ret; + if (ret = serialize_uint16le(sio, "width", "%d", &mhni->width)) return ret; + if (ret = serialize_uint32le(sio, "unknown", "%d", &mhni->unknown)) return ret; + if (ret = serialize_uint32le(sio, "image_size", "%d", &mhni->image_size)) return ret; + + return 0; +} + + + +static int mhba_init(artworkdb_chunk_t* chunk, int def) +{ + artworkdb_mhba_t* mhba = NULL; + + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhba", 4); + chunk->size = 104; + chunk->overall_size = 0; /* to be filled */ + } + + mhba = (artworkdb_mhba_t*)calloc(1, sizeof(artworkdb_mhba_t)); + if (def && mhba) { + } + chunk->data = mhba; + return mhba ? 0 : IPODE_OUTOFMEMORY; +} + +static int mhba_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +{ + int ret = 0; + artworkdb_mhba_t* mhba = (artworkdb_mhba_t*)chunk->data; + + if (ret = serialize_uint32le(sio, "num_mhod", "%d", &mhba->num_mhod)) return ret; + if (ret = serialize_uint32le(sio, "num_mhia", "%d", &mhba->num_mhia)) return ret; + if (ret = serialize_uint32le(sio, "playlist_id", "%d", &mhba->playlist_id)) return ret; + if (ret = serialize_uint32le(sio, "unk2", "%d", &mhba->unk2)) return ret; + if (ret = serialize_uint16le(sio, "unk3", "%d", &mhba->unk3)) return ret; + if (ret = serialize_uint8(sio, "album_type", "%d", &mhba->album_type)) return ret; + if (ret = serialize_uint8(sio, "play_music", "%d", &mhba->play_music)) return ret; + if (ret = serialize_uint8(sio, "repeat", "%d", &mhba->repeat)) return ret; + if (ret = serialize_uint8(sio, "random", "%d", &mhba->random)) return ret; + if (ret = serialize_uint8(sio, "show_titles", "%d", &mhba->show_titles)) return ret; + if (ret = serialize_uint8(sio, "transition_direction", "%d", &mhba->transition_direction)) return ret; + if (ret = serialize_uint32le(sio, "slide_duration", "%d", &mhba->slide_duration)) return ret; + if (ret = serialize_uint32le(sio, "transition_duration", "%d", &mhba->transition_duration)) return ret; + if (ret = serialize_uint32le(sio, "unk7", "%d", &mhba->unk7)) return ret; + if (ret = serialize_uint32le(sio, "unk8", "%d", &mhba->unk8)) return ret; + if (ret = serialize_uint64le(sio, "dbid2", "%016llX", &mhba->dbid2)) return ret; + if (ret = serialize_uint32le(sio, "prev_playlist_id", "%d", &mhba->prev_playlist_id)) return ret; + + return 0; +} + + + +static mhia_init(artworkdb_chunk_t* chunk, int def) +{ + artworkdb_mhia_t* mhia = NULL; + + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhia", 4); + chunk->size = 96; + chunk->overall_size = 0; /* to be filled */ + } + + mhia = (artworkdb_mhia_t*)calloc(1, sizeof(artworkdb_mhia_t)); + if (mhia && def) { + } + + chunk->data = mhia; + return mhia ? 0 : IPODE_OUTOFMEMORY; +} + +static int mhia_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +{ + int ret = 0; + artworkdb_mhia_t* mhia = (artworkdb_mhia_t*)chunk->data; + + if (ret = serialize_uint32le(sio, "unk1", "%d", &mhia->unk1)) return ret; + if (ret = serialize_uint32le(sio, "image_id", "%d", &mhia->image_id)) return ret; + + return 0; +} + + + +static mhlf_init(artworkdb_chunk_t* chunk, int def) +{ + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhlf", 4); + chunk->size = 96; + chunk->overall_size = 0; /* to be filled */ + } + + chunk->data = 0; + return 0; +} + +static int mhlf_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +{ + return 0; +} + + + +static mhif_init(artworkdb_chunk_t* chunk, int def) +{ + artworkdb_mhif_t* mhif = NULL; + + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhif", 4); + chunk->size = 96; + chunk->overall_size = 0; /* to be filled */ + } + + mhif = (artworkdb_mhif_t*)calloc(1, sizeof(artworkdb_mhif_t)); + if (mhif && def) { + } + + chunk->data = mhif; + return mhif ? 0 : IPODE_OUTOFMEMORY; +} + +static int mhif_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +{ + int ret = 0; + artworkdb_mhif_t* mhif = (artworkdb_mhif_t*)chunk->data; + + if (ret = serialize_uint32le(sio, "unknown1", "%d", &mhif->unknown1)) return ret; + if (ret = serialize_uint32le(sio, "correlation_id", "%d", &mhif->correlation_id)) return ret; + if (ret = serialize_uint32le(sio, "image_size", "%d", &mhif->image_size)) return ret; + + return 0; +} + Property changes on: trunk/pmplib/lib/pmp_ipod/artworkdb.c ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Added: trunk/pmplib/lib/pmp_ipod/artworkdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/artworkdb.h (rev 0) +++ trunk/pmplib/lib/pmp_ipod/artworkdb.h 2007-10-05 14:47:54 UTC (rev 420) @@ -0,0 +1,183 @@ +/* + * ArtworkDB reader/writer/dumper. + * + * Copyright (c) 2005-2007 Naoaki Okazaki + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* $Id:$ */ + +#ifndef __ARTWORKDB_H__ +#define __ARTWORKDB_H__ + +typedef struct { + uint32_t unknown1; /* always set to 0. */ + uint32_t version; /* should be 2. */ + uint32_t num_children; /* usually 3. */ + uint32_t unknown3; /* always set to 0. */ + uint32_t next_nhii; + uint64_t unknown5; + uint64_t unknown6; + uint32_t unknown7; /* always set to 2. */ + uint32_t unknown8; /* always set to 0. */ + uint32_t unknown9; /* always set to 0. */ + uint32_t unknown10; + uint32_t unknown11; +} artworkdb_mhfd_t; + +typedef struct { + uint32_t type; /* 1 (image list), 2 (album list), or 3 (file list). */ +} artworkdb_mhsd_t; + +typedef struct { + uint8_t unknown; /* zero padded. */ +} artworkdb_mhli_t; + +typedef struct { + uint32_t num_children; + uint32_t id; + uint64_t song_id; + uint32_t unknown4; + uint32_t rating; + uint32_t unknown6; + uint32_t ts_file; + uint32_t ts_import; + uint32_t original_size; +} artworkdb_mhii_t; + +typedef struct { + uint32_t num_children; + uint32_t correlation_id; + uint32_t ithmb_offset; + uint32_t ithmb_size; + uint16_t vertical_padding; + uint16_t horizontal_padding; + uint16_t height; + uint16_t width; + uint32_t unknown; + uint32_t image_size; +} artworkdb_mhni_t; + +typedef struct { + uint32_t num_mhod; + uint32_t num_mhia; + uint32_t playlist_id; + uint32_t unk2; + uint16_t unk3; + uint8_t album_type; + uint8_t play_music; + uint8_t repeat; + uint8_t random; + uint8_t show_titles; + uint8_t transition_direction; + uint32_t slide_duration; + uint32_t transition_duration; + uint32_t unk7; + uint32_t unk8; + uint64_t dbid2; + uint32_t prev_playlist_id; +} artworkdb_mhba_t; + +typedef struct { + uint32_t unk1; + uint32_t image_id; +} artworkdb_mhia_t; + +typedef struct { + uint32_t unknown1; + uint32_t correlation_id; + uint32_t image_size; +} artworkdb_mhif_t; + +typedef struct { + uint32_t length; + uint32_t encoding; + uint32_t unknown; + ucs2char_t* value; +} artworkdb_mhod_ucs2string_t; + +typedef struct { + uint32_t length; + uint32_t encoding; + uint32_t unknown; + char* value; +} artworkdb_mhod_utf8string_t; + +typedef struct { + uint16_t type; + uint16_t unk1; + union { + artworkdb_mhod_ucs2string_t ucs2str; + artworkdb_mhod_utf8string_t ucs8str; + } data; +} artworkdb_mhod_t; + + +struct tag_artworkdb_chunk { + int8_t id[4]; + uint32_t size; + uint32_t overall_size; + + void* data; + + uint32_t num_children; /* This field does not exist in the actual database. */ + struct tag_artworkdb_chunk* childlen; + + int32_t padding_size; + uint8_t* padding; + + uint32_t offset; /* This field does not exist in the actual database. */ +}; + +typedef struct tag_artworkdb_chunk artworkdb_chunk_t; + +typedef struct { + uint32_t type; + const char* name; + uint32_t overall_size; + void (*finish)(artworkdb_chunk_t* chunk); + int (*serialize)(artworkdb_chunk_t* chunk, const char *name, serializer_t* sio); +} albumartdb_mhoddecl_t; + +typedef struct { + const char* name; + int (*init)(artworkdb_chunk_t* chunk, int dataonly); + void (*finish)(artworkdb_chunk_t* chunk); + int (*serialize)(artworkdb_chunk_t* chunk, serializer_t* sio); +} albumartdb_chunkdecl_t; + +int albumartdb_init(artworkdb_chunk_t* chunk, const char *identifer, const char *subtype); + +int albumartdb_ischunk(artworkdb_chunk_t* chunk, const char *name, const char *subtype); + +artworkdb_chunk_t* albumartdb_new_child(artworkdb_chunk_t* chunk); + +void albumartdb_finish(artworkdb_chunk_t* chunk); + +int albumartdb_set_mhod_ucs2string(artworkdb_chunk_t* chunk, const ucs2char_t* str); + +int albumartdb_get_mhod_ucs2string(artworkdb_chunk_t* chunk, ucs2char_t** str); + +int albumartdb_set_mhod_utf8string(artworkdb_chunk_t* chunk, const char* str); + +int albumartdb_get_mhod_utf8string(artworkdb_chunk_t* chunk, char** str); + +int albumartdb_repr(artworkdb_chunk_t* chunk, size_t index, serializer_t* sio); +int albumartdb_read(artworkdb_chunk_t* chunk, serializer_t* sio); +int albumartdb_write(artworkdb_chunk_t* chunk, serializer_t* sio); + +#endif/*__ARTWORKDB_H__*/ Property changes on: trunk/pmplib/lib/pmp_ipod/artworkdb.h ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-10-05 17:13:18
|
Revision: 421 http://pmplib.svn.sourceforge.net/pmplib/?rev=421&view=rev Author: nyaochi Date: 2007-10-05 10:13:21 -0700 (Fri, 05 Oct 2007) Log Message: ----------- pmp_ipod now dumps ArtworkDB content. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/artworkdb.c trunk/pmplib/lib/pmp_ipod/artworkdb.h trunk/pmplib/lib/pmp_ipod/chunk.c trunk/pmplib/lib/pmp_ipod/chunk.h trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/ipod.h trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/pmp_ipod.c Modified: trunk/pmplib/lib/pmp_ipod/artworkdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/artworkdb.c 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/artworkdb.c 2007-10-05 17:13:21 UTC (rev 421) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -37,16 +37,17 @@ #include "ipod.h" #include "serialize.h" #include "util.h" +#include "chunk.h" #include "artworkdb.h" -static void chunk_finish(artworkdb_chunk_t* chunk) +static void chunk_finish(itunes_chunk_t* chunk) { free(chunk->data); free(chunk->padding); memset(chunk, 0, sizeof(*chunk)); } -static int mhfd_init(artworkdb_chunk_t* chunk, int def) +static int mhfd_init(itunes_chunk_t* chunk, int def) { artworkdb_mhfd_t* mhfd = NULL; @@ -64,19 +65,18 @@ mhfd->num_children = 0; /* to be filled */ mhfd->unknown3 = 0; mhfd->next_nhii = 0; - mhfd->unknown5 = 0; - mhfd->unknown6 = 0; + mhfd->unknown5 = 0x0E777BDE5D06AD9B; + mhfd->unknown6 = 0x368B84B5E61BC6ED; mhfd->unknown7 = 2; mhfd->unknown8 = 0; mhfd->unknown9 = 0; - mhfd->unknown10 = 0; - mhfd->unknown11 = 0; + mhfd->unknown10 = 0x15C516AB8F8EB3A4; } chunk->data = mhfd; return mhfd ? 0 : IPODE_OUTOFMEMORY; } -static int mhfd_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhfd_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhfd_t* mhfd = (artworkdb_mhfd_t*)chunk->data; @@ -91,15 +91,14 @@ if (ret = serialize_uint32le(sio, "unknown7", "%d", &mhfd->unknown7)) return ret; if (ret = serialize_uint32le(sio, "unknown8", "%d", &mhfd->unknown8)) return ret; if (ret = serialize_uint32le(sio, "unknown9", "%d", &mhfd->unknown9)) return ret; - if (ret = serialize_uint32le(sio, "unknown10", "%d", &mhfd->unknown10)) return ret; - if (ret = serialize_uint32le(sio, "unknown11", "%d", &mhfd->unknown10)) return ret; + if (ret = serialize_uint64le(sio, "unknown10", "%016llX", &mhfd->unknown10)) return ret; return 0; } -static mhsd_init(artworkdb_chunk_t* chunk, int def) +static mhsd_init(itunes_chunk_t* chunk, int def) { artworkdb_mhsd_t* mhsd = NULL; @@ -119,7 +118,7 @@ return mhsd ? 0 : IPODE_OUTOFMEMORY; } -static int mhsd_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhsd_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhsd_t* mhsd = (artworkdb_mhsd_t*)chunk->data; @@ -131,12 +130,12 @@ -static mhli_init(artworkdb_chunk_t* chunk, int def) +static mhli_init(itunes_chunk_t* chunk, int def) { if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhli", 4); - chunk->size = 96; + chunk->size = 92; chunk->overall_size = 0; /* to be filled */ } @@ -144,21 +143,21 @@ return 0; } -static int mhli_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhli_serialize(itunes_chunk_t* chunk, serializer_t* sio) { return 0; } -static int mhii_init(artworkdb_chunk_t* chunk, int def) +static int mhii_init(itunes_chunk_t* chunk, int def) { artworkdb_mhii_t* mhii = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhii", 4); - chunk->size = 104; + chunk->size = 152; chunk->overall_size = 0; /* to be filled */ } @@ -178,7 +177,7 @@ return mhii ? 0 : IPODE_OUTOFMEMORY; } -static int mhii_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhii_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhii_t* mhii = (artworkdb_mhii_t*)chunk->data; @@ -192,19 +191,22 @@ if (ret = serialize_uint32le(sio, "ts_file", "%d", &mhii->ts_file)) return ret; if (ret = serialize_uint32le(sio, "ts_import", "%d", &mhii->ts_import)) return ret; if (ret = serialize_uint32le(sio, "original_size", "%d", &mhii->original_size)) return ret; + if (ret = serialize_uint32le(sio, "unknown10", "%d", &mhii->unknown10)) return ret; + if (ret = serialize_uint32le(sio, "unknown11", "%d", &mhii->unknown11)) return ret; + if (ret = serialize_uint32le(sio, "unknown12", "%d", &mhii->unknown12)) return ret; return 0; } -static int mhni_init(artworkdb_chunk_t* chunk, int def) +static int mhni_init(itunes_chunk_t* chunk, int def) { artworkdb_mhni_t* mhni = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhni", 4); - chunk->size = 104; + chunk->size = 76; chunk->overall_size = 0; /* to be filled */ } @@ -223,7 +225,7 @@ return mhni ? 0 : IPODE_OUTOFMEMORY; } -static int mhni_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhni_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhni_t* mhni = (artworkdb_mhni_t*)chunk->data; @@ -244,14 +246,14 @@ -static int mhba_init(artworkdb_chunk_t* chunk, int def) +static int mhba_init(itunes_chunk_t* chunk, int def) { artworkdb_mhba_t* mhba = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhba", 4); - chunk->size = 104; + chunk->size = 104; /* ??? */ chunk->overall_size = 0; /* to be filled */ } @@ -262,7 +264,7 @@ return mhba ? 0 : IPODE_OUTOFMEMORY; } -static int mhba_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhba_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhba_t* mhba = (artworkdb_mhba_t*)chunk->data; @@ -289,15 +291,35 @@ } +static mhla_init(itunes_chunk_t* chunk, int def) +{ + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhla", 4); + chunk->size = 92; + chunk->overall_size = 0; /* to be filled */ + } -static mhia_init(artworkdb_chunk_t* chunk, int def) + chunk->data = 0; + return 0; +} + +static int mhla_serialize(itunes_chunk_t* chunk, serializer_t* sio) { + return 0; +} + + + + +static mhia_init(itunes_chunk_t* chunk, int def) +{ artworkdb_mhia_t* mhia = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhia", 4); - chunk->size = 96; + chunk->size = 96; /* ??? */ chunk->overall_size = 0; /* to be filled */ } @@ -309,7 +331,7 @@ return mhia ? 0 : IPODE_OUTOFMEMORY; } -static int mhia_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhia_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhia_t* mhia = (artworkdb_mhia_t*)chunk->data; @@ -322,12 +344,12 @@ -static mhlf_init(artworkdb_chunk_t* chunk, int def) +static mhlf_init(itunes_chunk_t* chunk, int def) { if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhlf", 4); - chunk->size = 96; + chunk->size = 92; chunk->overall_size = 0; /* to be filled */ } @@ -335,21 +357,21 @@ return 0; } -static int mhlf_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhlf_serialize(itunes_chunk_t* chunk, serializer_t* sio) { return 0; } -static mhif_init(artworkdb_chunk_t* chunk, int def) +static mhif_init(itunes_chunk_t* chunk, int def) { artworkdb_mhif_t* mhif = NULL; if (def) { memset(chunk, 0, sizeof(*chunk)); strncpy(chunk->id, "mhif", 4); - chunk->size = 96; + chunk->size = 124; chunk->overall_size = 0; /* to be filled */ } @@ -361,7 +383,7 @@ return mhif ? 0 : IPODE_OUTOFMEMORY; } -static int mhif_serialize(artworkdb_chunk_t* chunk, serializer_t* sio) +static int mhif_serialize(itunes_chunk_t* chunk, serializer_t* sio) { int ret = 0; artworkdb_mhif_t* mhif = (artworkdb_mhif_t*)chunk->data; @@ -373,3 +395,140 @@ return 0; } +static void mhod_container_finish(itunes_chunk_t* chunk) +{ + artworkdb_mhod_t* mhod = (artworkdb_mhod_t*)chunk->data; + memset(mhod, 0, sizeof(*mhod)); +} + +static int mhod_container_serialize(itunes_chunk_t* chunk, const char *name, serializer_t* sio) +{ + return 0; +} + +static void mhod_string_finish(itunes_chunk_t* chunk) +{ + artworkdb_mhod_t* mhod = (artworkdb_mhod_t*)chunk->data; + artworkdb_mhod_string_t* string = &mhod->data.str; + ucs2free(string->ucs2); + ucs2free(string->utf8); + memset(string, 0, sizeof(*string)); +} + +static int mhod_string_serialize(itunes_chunk_t* chunk, const char *name, serializer_t* sio) +{ + int ret = 0; + artworkdb_mhod_string_t* string = &((artworkdb_mhod_t*)chunk->data)->data.str; + + if (ret = serialize_uint32le(sio, "size", "%u", &string->size)) return ret; + if (ret = serialize_uint32le(sio, "encoding", "%u", &string->encoding)) return ret; + if (ret = serialize_uint32le(sio, "unknown", "%u", &string->unknown)) return ret; + if (string->encoding == 2) { + if (ret = serialize_ucs2lestr_fixed(sio, name, "%s", &string->ucs2, string->size / sizeof(ucs2char_t))) return ret; + } else { + if (ret = serialize_utf8str_fixed(sio, name, "%s", &string->utf8, string->size)) return ret; + } + + return 0; +} + +static const artworkdb_mhoddecl_t mds[] = { + {1, "album", 0, mhod_string_finish, mhod_string_serialize}, + {2, "thumbnail", 1, mhod_container_finish, mhod_container_serialize}, + {3, "filename", 0, mhod_string_finish, mhod_string_serialize}, + {5, "fullsize", 1, mhod_container_finish, mhod_container_serialize}, + {0, NULL, 0, NULL}, +}; + +static const artworkdb_mhoddecl_t* find_mhoddecl(itunes_chunk_t* chunk) +{ + const artworkdb_mhoddecl_t* decl = mds; + artworkdb_mhod_t* mhod = (artworkdb_mhod_t*)chunk->data; + + while (decl->name) { + if (decl->type == mhod->type) { + return decl; + } + ++decl; + } + return NULL; +} + +static const artworkdb_mhoddecl_t* find_mhoddecl_by_name(const char *name) +{ + const artworkdb_mhoddecl_t* decl = mds; + + while (decl->name) { + if (strcmp(decl->name, name) == 0) { + return decl; + } + ++decl; + } + return NULL; +} + +static int mhod_init(itunes_chunk_t* chunk, int def) +{ + if (def) { + memset(chunk, 0, sizeof(*chunk)); + strncpy(chunk->id, "mhod", 4); + chunk->size = 24; + chunk->overall_size = chunk->size; + } + chunk->data = calloc(1, sizeof(artworkdb_mhod_t)); + return chunk->data ? 0 : IPODE_OUTOFMEMORY; +} + +static void mhod_finish(itunes_chunk_t* chunk) +{ + artworkdb_mhod_t* mhod = (artworkdb_mhod_t*)chunk->data; + const artworkdb_mhoddecl_t* decl = NULL; + decl = find_mhoddecl(chunk); + if (decl) { + decl->finish(chunk); + } + chunk_finish(chunk); +} + +static int mhod_serialize(itunes_chunk_t* chunk, serializer_t* sio) +{ + int ret = 0; + artworkdb_mhod_t* mhod = (artworkdb_mhod_t*)chunk->data; + const artworkdb_mhoddecl_t* decl = NULL; + + if (ret = serialize_uint16le(sio, "type", "%u", &mhod->type)) return ret; + if (ret = serialize_uint8(sio, "unknown1", "%u", &mhod->unknown1)) return ret; + if (ret = serialize_uint8(sio, "padding_length", "%u", &mhod->padding_length)) return ret; + if (ret = serialize_uint32le(sio, "unknown2", "%u", &mhod->unknown2)) return ret; + if (ret = serialize_uint32le(sio, "unknown3", "%u", &mhod->unknown2)) return ret; + + decl = find_mhoddecl(chunk); + if (decl) { + if (ret = decl->serialize(chunk, decl->name, sio)) return ret; + if (!decl->is_container) chunk->size = chunk->overall_size; + } else { + if (serialize_dumping(sio)) { + serialize_indent(sio); + fprintf(sio->fp, "!unknown_mhod_type!\n"); + } + chunk->size = chunk->overall_size; + } + + return 0; +} + +const itunes_chunkdecl_t artworkdb_cds[] = { + {"mhfd", 0, mhfd_init, chunk_finish, mhfd_serialize}, + {"mhsd", 0, mhsd_init, chunk_finish, mhsd_serialize}, + {"mhli", 1, mhli_init, chunk_finish, mhli_serialize}, + {"mhii", 0, mhii_init, chunk_finish, mhii_serialize}, + {"mhni", 0, mhni_init, chunk_finish, mhni_serialize}, + {"mhba", 0, mhba_init, chunk_finish, mhba_serialize}, + {"mhla", 1, mhla_init, chunk_finish, mhla_serialize}, + {"mhia", 0, mhia_init, chunk_finish, mhia_serialize}, + {"mhlf", 1, mhlf_init, chunk_finish, mhlf_serialize}, + {"mhif", 0, mhif_init, chunk_finish, mhif_serialize}, + {"mhod", 0, mhod_init, mhod_finish, mhod_serialize}, + {NULL, 0, NULL, NULL, NULL}, +}; + Modified: trunk/pmplib/lib/pmp_ipod/artworkdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/artworkdb.h 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/artworkdb.h 2007-10-05 17:13:21 UTC (rev 421) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifndef __ARTWORKDB_H__ #define __ARTWORKDB_H__ @@ -35,8 +35,7 @@ uint32_t unknown7; /* always set to 2. */ uint32_t unknown8; /* always set to 0. */ uint32_t unknown9; /* always set to 0. */ - uint32_t unknown10; - uint32_t unknown11; + uint64_t unknown10; } artworkdb_mhfd_t; typedef struct { @@ -57,6 +56,9 @@ uint32_t ts_file; uint32_t ts_import; uint32_t original_size; + uint32_t unknown10; + uint32_t unknown11; + uint32_t unknown12; } artworkdb_mhii_t; typedef struct { @@ -104,80 +106,38 @@ } artworkdb_mhif_t; typedef struct { - uint32_t length; + uint32_t size; uint32_t encoding; uint32_t unknown; - ucs2char_t* value; -} artworkdb_mhod_ucs2string_t; + ucs2char_t* ucs2; + char* utf8; +} artworkdb_mhod_string_t; typedef struct { - uint32_t length; - uint32_t encoding; - uint32_t unknown; - char* value; -} artworkdb_mhod_utf8string_t; - -typedef struct { uint16_t type; - uint16_t unk1; + uint8_t unknown1; + uint8_t padding_length; + uint32_t unknown2; + uint32_t unknown3; union { - artworkdb_mhod_ucs2string_t ucs2str; - artworkdb_mhod_utf8string_t ucs8str; + artworkdb_mhod_string_t str; } data; } artworkdb_mhod_t; -struct tag_artworkdb_chunk { - int8_t id[4]; - uint32_t size; - uint32_t overall_size; - - void* data; - - uint32_t num_children; /* This field does not exist in the actual database. */ - struct tag_artworkdb_chunk* childlen; - - int32_t padding_size; - uint8_t* padding; - - uint32_t offset; /* This field does not exist in the actual database. */ -}; - -typedef struct tag_artworkdb_chunk artworkdb_chunk_t; - typedef struct { uint32_t type; const char* name; - uint32_t overall_size; - void (*finish)(artworkdb_chunk_t* chunk); - int (*serialize)(artworkdb_chunk_t* chunk, const char *name, serializer_t* sio); -} albumartdb_mhoddecl_t; + int is_container; + void (*finish)(itunes_chunk_t* chunk); + int (*serialize)(itunes_chunk_t* chunk, const char *name, serializer_t* sio); +} artworkdb_mhoddecl_t; -typedef struct { - const char* name; - int (*init)(artworkdb_chunk_t* chunk, int dataonly); - void (*finish)(artworkdb_chunk_t* chunk); - int (*serialize)(artworkdb_chunk_t* chunk, serializer_t* sio); -} albumartdb_chunkdecl_t; +int albumartdb_set_mhod_ucs2string(itunes_chunk_t* chunk, const ucs2char_t* str); +int albumartdb_get_mhod_ucs2string(itunes_chunk_t* chunk, ucs2char_t** str); +int albumartdb_set_mhod_utf8string(itunes_chunk_t* chunk, const char* str); +int albumartdb_get_mhod_utf8string(itunes_chunk_t* chunk, char** str); -int albumartdb_init(artworkdb_chunk_t* chunk, const char *identifer, const char *subtype); +extern const itunes_chunkdecl_t artworkdb_cds[]; -int albumartdb_ischunk(artworkdb_chunk_t* chunk, const char *name, const char *subtype); - -artworkdb_chunk_t* albumartdb_new_child(artworkdb_chunk_t* chunk); - -void albumartdb_finish(artworkdb_chunk_t* chunk); - -int albumartdb_set_mhod_ucs2string(artworkdb_chunk_t* chunk, const ucs2char_t* str); - -int albumartdb_get_mhod_ucs2string(artworkdb_chunk_t* chunk, ucs2char_t** str); - -int albumartdb_set_mhod_utf8string(artworkdb_chunk_t* chunk, const char* str); - -int albumartdb_get_mhod_utf8string(artworkdb_chunk_t* chunk, char** str); - -int albumartdb_repr(artworkdb_chunk_t* chunk, size_t index, serializer_t* sio); -int albumartdb_read(artworkdb_chunk_t* chunk, serializer_t* sio); -int albumartdb_write(artworkdb_chunk_t* chunk, serializer_t* sio); - #endif/*__ARTWORKDB_H__*/ Modified: trunk/pmplib/lib/pmp_ipod/chunk.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/chunk.c 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/chunk.c 2007-10-05 17:13:21 UTC (rev 421) @@ -222,13 +222,13 @@ } /* Determine the size of padded data for this chunk. */ - if (strncmp(chunk->id, "mhod", 4) == 0) { - next = begin + chunk->overall_size; - chunk->padding_size = next - serialize_tell(sio); - } else { + //if (strncmp(chunk->id, "mhod", 4) == 0) { + // next = begin + chunk->overall_size; + // chunk->padding_size = next - serialize_tell(sio); + //} else { next = begin + chunk->size; chunk->padding_size = next - serialize_tell(sio); - } + //} /* Read the padded data. */ if (0 < chunk->padding_size) { @@ -251,8 +251,8 @@ } /* Read children for this chunk. */ - if (strncmp(chunk->id, "mhla", 4) == 0 || strncmp(chunk->id, "mhlt", 4) == 0 || strncmp(chunk->id, "mhlp", 4) == 0) { - /* chunk->overall_size represents the number of children for "mhlt" and "mhlp" chunks */ + if (decl && decl->overall_size_is_num_children) { + /* chunk->overall_size represents the number of children. */ chunk->num_children = chunk->overall_size; chunk->childlen = (itunes_chunk_t*)calloc(chunk->num_children, sizeof(itunes_chunk_t)); for (i = 0;i < chunk->num_children;++i) { @@ -309,8 +309,8 @@ } /* Calculate chunk->overall_size. */ - if (strncmp(chunk->id, "mhla", 4) == 0 || strncmp(chunk->id, "mhlt", 4) == 0 || strncmp(chunk->id, "mhlp", 4) == 0) { - /* chunk->overall_size represents the number of children for "mhlt" and "mhlp" chunks */ + if (decl && decl->overall_size_is_num_children) { + /* chunk->overall_size represents the number of children. */ chunk->overall_size = chunk->num_children; } else { /* chunk->overall_size represents the size in bytes of this chunk */ Modified: trunk/pmplib/lib/pmp_ipod/chunk.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/chunk.h 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/chunk.h 2007-10-05 17:13:21 UTC (rev 421) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifndef __CHUNK_H__ #define __CHUNK_H__ @@ -41,6 +41,7 @@ typedef struct { const char* name; + int overall_size_is_num_children; int (*init)(itunes_chunk_t* chunk, int dataonly); void (*finish)(itunes_chunk_t* chunk); int (*serialize)(itunes_chunk_t* chunk, serializer_t* sio); Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-10-05 17:13:21 UTC (rev 421) @@ -43,6 +43,7 @@ #include "ipodserial.h" #include "chunk.h" #include "itunesdb.h" +#include "artworkdb.h" #include "playcounts.h" #define COMP(a, b) ((a)>(b))-((a)<(b)) @@ -52,6 +53,7 @@ "apple_ipod", "Apple", "iPod", "UM", "---", "---", "iPod_Control\\iTunes\\iTunesDB", + "iPod_Control\\Artwork\\ArtworkDB", "iPod_Control\\iTunes\\Play Counts", ".mp3\0.m4a\0", {PMPCODEC_MPEGLAYER3, PMPCODEC_MPEG4AUDIO, 0, 0, 0, 0, 0, 0}, @@ -63,6 +65,7 @@ NULL, NULL, NULL, + NULL, {0, 0, 0, 0, 0, 0, 0, 0}, NULL, NULL, NULL, }, @@ -167,6 +170,10 @@ if (!ipod->itunesdb) { return IPODE_OUTOFMEMORY; } + ipod->artworkdb = (itunes_chunk_t*)calloc(1, sizeof(itunes_chunk_t)); + if (!ipod->artworkdb) { + return IPODE_OUTOFMEMORY; + } ipod->pcs = (playcounts_t*)calloc(1, sizeof(playcounts_t)); if (!ipod->pcs) { return IPODE_OUTOFMEMORY; @@ -178,11 +185,12 @@ { playcounts_finish(ipod->pcs); itunesdb_finish(itunesdb_cds, ipod->itunesdb); + itunesdb_finish(artworkdb_cds, ipod->artworkdb); free(ipod->pcs); free(ipod->itunesdb); } -int ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts) +int ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* artworkdb, const ucs2char_t* playcounts) { int ret = 0; FILE *fp = NULL; @@ -211,6 +219,30 @@ return (IPODC_ITUNESDB|IPODE_FILEOPENFORREAD); } + /* Read ArtworkDB. */ + fp = ucs2fopen(artworkdb, "rb"); + if (fp) { + serializer_t sio; + uint8_t* buffer = NULL; + long size = 0; + + ret = fread_all(fp, &buffer, &size); + if (IPODFAILED(ret)) { + return (IPODC_ITUNESDB|ret); + } + fclose(fp); + + serialize_init_read(&sio, buffer, (size_t)size); + ret = itunesdb_read(artworkdb_cds, ipod->artworkdb, &sio); + if (IPODFAILED(ret)) { + return (IPODC_ITUNESDB|ret); + } + serialize_finish(&sio); + free(buffer); + } else { + return (IPODC_ITUNESDB|IPODE_FILEOPENFORREAD); + } + /* Read "Play Counts". Don't care if this file does not exist. */ fp = ucs2fopen(playcounts, "rb"); if (fp) { @@ -237,7 +269,7 @@ return 0; } -int ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts) +int ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* artworkdb, const ucs2char_t* playcounts) { int ret = 0; FILE *fp = NULL; @@ -264,6 +296,24 @@ serialize_finish(&sio); + serialize_init_write(&sio, 0x10000); + ret = itunesdb_write(artworkdb_cds, ipod->artworkdb, &sio); + if (IPODFAILED(ret)) { + return (IPODC_ITUNESDB|ret); + } + + fp = ucs2fopen(artworkdb, "wb"); + if (fp) { + if (fwrite(sio.base, 1, sio.offset, fp) != sio.offset) { + return (IPODC_ITUNESDB|IPODE_FILEWRITEERROR); + } + fclose(fp); + } else { + ret = (IPODC_ITUNESDB|IPODE_FILEOPENFORWRITE); + } + + serialize_finish(&sio); + /* Remove "Play Counts" file, which is always created by the player. */ filepath_removefile(playcounts); @@ -279,6 +329,10 @@ itunesdb_repr(itunesdb_cds, ipod->itunesdb, 0, &sio); fprintf(fpo, "\n"); + fprintf(fpo, "[ArtworkDB]\n"); + itunesdb_repr(artworkdb_cds, ipod->artworkdb, 0, &sio); + fprintf(fpo, "\n"); + fprintf(fpo, "[Play Counts]\n"); playcounts_serialize(ipod->pcs, &sio); fprintf(fpo, "\n"); Modified: trunk/pmplib/lib/pmp_ipod/ipod.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.h 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/ipod.h 2007-10-05 17:13:21 UTC (rev 421) @@ -34,6 +34,7 @@ const char *min_version; const char *max_version; const char *itunesdb_filename; + const char *artworkdb_filename; const char *playcounts_filename; const char *extensions; uint32_t codecs[8]; @@ -50,6 +51,7 @@ typedef struct { itunes_chunk_t* itunesdb; + itunes_chunk_t* artworkdb; playcounts_t* pcs; uint8_t serial[8]; } ipod_t; @@ -59,8 +61,8 @@ int ipod_init(ipod_t* ipod); void ipod_finish(ipod_t* ipod); -int ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts); -int ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* playcounts); +int ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* artworkdb, const ucs2char_t* playcounts); +int ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* artworkdb, const ucs2char_t* playcounts); int ipod_dump(ipod_t* ipod, FILE *fpo); int ipod_set( ipod_t* ipod, Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-10-05 17:13:21 UTC (rev 421) @@ -772,21 +772,24 @@ } } + /* The size field in "MHOD" chunk is always 24. */ + chunk->size = chunk->overall_size; + return 0; } const itunes_chunkdecl_t itunesdb_cds[] = { - {"mhbd", mhbd_init, chunk_finish, mhbd_serialize}, - {"mhsd", mhsd_init, chunk_finish, mhsd_serialize}, - {"mhla", mhla_init, chunk_finish, mhla_serialize}, - {"mhia", mhia_init, chunk_finish, mhia_serialize}, - {"mhlt", mhlt_init, chunk_finish, mhlt_serialize}, - {"mhit", mhit_init, chunk_finish, mhit_serialize}, - {"mhlp", mhlp_init, chunk_finish, mhlp_serialize}, - {"mhyp", mhyp_init, chunk_finish, mhyp_serialize}, - {"mhip", mhip_init, chunk_finish, mhip_serialize}, - {"mhod", mhod_init, mhod_finish, mhod_serialize}, - {NULL, NULL, NULL, NULL}, + {"mhbd", 0, mhbd_init, chunk_finish, mhbd_serialize}, + {"mhsd", 0, mhsd_init, chunk_finish, mhsd_serialize}, + {"mhla", 1, mhla_init, chunk_finish, mhla_serialize}, + {"mhia", 0, mhia_init, chunk_finish, mhia_serialize}, + {"mhlt", 1, mhlt_init, chunk_finish, mhlt_serialize}, + {"mhit", 0, mhit_init, chunk_finish, mhit_serialize}, + {"mhlp", 1, mhlp_init, chunk_finish, mhlp_serialize}, + {"mhyp", 0, mhyp_init, chunk_finish, mhyp_serialize}, + {"mhip", 0, mhip_init, chunk_finish, mhip_serialize}, + {"mhod", 0, mhod_init, mhod_finish, mhod_serialize}, + {NULL, 0, NULL, NULL, NULL}, }; int itunesdb_mhod_init( Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-10-05 14:47:54 UTC (rev 420) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-10-05 17:13:21 UTC (rev 421) @@ -145,7 +145,7 @@ memset(info, 0, sizeof(*info)); } -static void set_filenames(ucs2char_t *itunesdb, ucs2char_t* playcounts, pmp_t *pmp) +static void set_filenames(ucs2char_t *itunesdb, ucs2char_t *artworkdb, ucs2char_t* playcounts, pmp_t *pmp) { ucs2char_t* ucs2 = NULL; pmp_internal_t* pmpi = (pmp_internal_t*)pmp->instance; @@ -157,6 +157,13 @@ ucs2cat(itunesdb, ucs2); ucs2free(ucs2); } + if (artworkdb) { + ucs2cpy(artworkdb, pmp->info.path_to_root); + filepath_addslash(artworkdb); + ucs2 = mbsdupucs2(pmpi->decl->artworkdb_filename); + ucs2cat(artworkdb, ucs2); + ucs2free(ucs2); + } if (playcounts) { ucs2cpy(playcounts, pmp->info.path_to_root); filepath_addslash(playcounts); @@ -331,18 +338,18 @@ result_t ret = 0; pmp_t* pmp = music->pmp; pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; - ucs2char_t itunesdb[MAX_PATH], playcounts[MAX_PATH]; + ucs2char_t itunesdb[MAX_PATH], artworkdb[MAX_PATH], playcounts[MAX_PATH]; // Initialize ipod library. ipod_init(&ipod); // Read the music database. - set_filenames(itunesdb, playcounts, music->pmp); + set_filenames(itunesdb, artworkdb, playcounts, music->pmp); if (pmp->flag & (PMPOF_MUSIC_DB_READ|PMPOF_MUSIC_PL_READ)) { int num_records = 0, num_playlists = 0; - ipod_read(&ipod, itunesdb, playcounts); + ipod_read(&ipod, itunesdb, artworkdb, playcounts); ipod_get(&ipod, NULL, &num_records, NULL, &num_playlists, pmp->info.path_to_root); // Allocate records. @@ -393,17 +400,17 @@ result_t ret = 0; pmp_t* pmp = music->pmp; pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; - ucs2char_t itunesdb[MAX_PATH], playcounts[MAX_PATH]; + ucs2char_t itunesdb[MAX_PATH], artworkdb[MAX_PATH], playcounts[MAX_PATH]; // Initialize ipod library. ipod_init(&ipod); // Read the music database. - set_filenames(itunesdb, playcounts, music->pmp); + set_filenames(itunesdb, artworkdb, playcounts, music->pmp); if (pmp->flag & PMPOF_MUSIC_DB_WRITE) { ipod_set(&ipod, pmpmi->records, pmpmi->num_records, pmpmi->playlists, pmpmi->num_playlists, pmp->info.path_to_root); - ipod_write(&ipod, itunesdb, playcounts); + ipod_write(&ipod, itunesdb, artworkdb, playcounts); } exit_this: @@ -447,14 +454,14 @@ { ipod_t ipod; result_t ret = 0; - ucs2char_t itunesdb[MAX_PATH], playcounts[MAX_PATH]; + ucs2char_t itunesdb[MAX_PATH], artworkdb[MAX_PATH], playcounts[MAX_PATH]; // Initialize IP3DB. ipod_init(&ipod); // Read the music database. - set_filenames(itunesdb, playcounts, music->pmp); - ret = ipod_read(&ipod, itunesdb, playcounts); + set_filenames(itunesdb, artworkdb, playcounts, music->pmp); + ret = ipod_read(&ipod, itunesdb, artworkdb, playcounts); if (ret) { goto exit_this; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-10-06 01:17:50
|
Revision: 422 http://pmplib.svn.sourceforge.net/pmplib/?rev=422&view=rev Author: nyaochi Date: 2007-10-05 18:17:54 -0700 (Fri, 05 Oct 2007) Log Message: ----------- Obtain serial IDs from iPod device information. We don't have to query USB serial directly to the USB port driver. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/ipod.h trunk/pmplib/lib/pmp_ipod/itunesdb.c trunk/pmplib/lib/pmp_ipod/itunesdb.h trunk/pmplib/lib/pmp_ipod/pmp_ipod.c trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-10-05 17:13:21 UTC (rev 421) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-10-06 01:17:54 UTC (rev 422) @@ -40,7 +40,6 @@ #include "util.h" #include "ipod.h" #include "ipodprop.h" -#include "ipodserial.h" #include "chunk.h" #include "itunesdb.h" #include "artworkdb.h" @@ -94,6 +93,14 @@ return IPODE_DEVICEINFO; } +static uint8_t get_uint8(const char *str, int begin) +{ + char value[] = {'0','x','0','0',0}; + value[2] = str[begin]; + value[3] = str[begin+1]; + return (uint8_t)strtoul(value, NULL, 16); +} + static int detect_model( const ucs2char_t* path_to_device, const ipod_descriptor_t* md, @@ -164,20 +171,50 @@ } } -int ipod_init(ipod_t* ipod) +int ipod_init(ipod_t* ipod, const ucs2char_t* path_to_device) { + int i; + ipodprop_t ip; + char *path = ucs2dupmbs(path_to_device); + + memset(ipod, 0, sizeof(*ipod)); + + /* Obtain the device information. */ + ipodprop_init(&ip); + if (ipodprop_get(path, &ip) == 0) { + if (ip.vendor && strncmp(ip.vendor, "Apple", 5) == 0 && + ip.product && strncmp(ip.product, "iPod", 4) == 0) { + + char serial[128]; + + if (ip.info) { + ipod->xml = strdup(ip.info); + + get_string_value(ip.info, "FireWireGUID", (char*)serial, sizeof(serial)); + for (i = 0;i < 8;++i) { + ipod->serial[i] = get_uint8(serial, 2*i); + } + } + } + } + ipodprop_finish(&ip); + ucs2free(path); + ipod->itunesdb = (itunes_chunk_t*)calloc(1, sizeof(itunes_chunk_t)); if (!ipod->itunesdb) { return IPODE_OUTOFMEMORY; } + ipod->artworkdb = (itunes_chunk_t*)calloc(1, sizeof(itunes_chunk_t)); if (!ipod->artworkdb) { return IPODE_OUTOFMEMORY; } + ipod->pcs = (playcounts_t*)calloc(1, sizeof(playcounts_t)); if (!ipod->pcs) { return IPODE_OUTOFMEMORY; } + return 0; } @@ -188,6 +225,7 @@ itunesdb_finish(artworkdb_cds, ipod->artworkdb); free(ipod->pcs); free(ipod->itunesdb); + free(ipod->xml); } int ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* artworkdb, const ucs2char_t* playcounts) @@ -284,7 +322,7 @@ fp = ucs2fopen(itunesdb, "wb"); if (fp) { /* Finalize the database (fill the hash58 value). */ - itunesdb_finalize(sio.base, sio.offset); + itunesdb_finalize(sio.base, sio.offset, ipod->serial); if (fwrite(sio.base, 1, sio.offset, fp) != sio.offset) { return (IPODC_ITUNESDB|IPODE_FILEWRITEERROR); Modified: trunk/pmplib/lib/pmp_ipod/ipod.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.h 2007-10-05 17:13:21 UTC (rev 421) +++ trunk/pmplib/lib/pmp_ipod/ipod.h 2007-10-06 01:17:54 UTC (rev 422) @@ -53,13 +53,14 @@ itunes_chunk_t* itunesdb; itunes_chunk_t* artworkdb; playcounts_t* pcs; + char *xml; uint8_t serial[8]; } ipod_t; const ipod_descriptor_t* ipod_detect(const ucs2char_t* path_to_device, const char *id, pmp_device_information_t* ptr_info); const ipod_descriptor_t* ipod_next_descriptor(const ipod_descriptor_t* md); -int ipod_init(ipod_t* ipod); +int ipod_init(ipod_t* ipod, const ucs2char_t* path_to_device); void ipod_finish(ipod_t* ipod); int ipod_read(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* artworkdb, const ucs2char_t* playcounts); int ipod_write(ipod_t* ipod, const ucs2char_t* itunesdb, const ucs2char_t* artworkdb, const ucs2char_t* playcounts); Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-10-05 17:13:21 UTC (rev 421) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.c 2007-10-06 01:17:54 UTC (rev 422) @@ -822,13 +822,10 @@ -int itunesdb_finalize(uint8_t* buffer, size_t size) +int itunesdb_finalize(uint8_t* buffer, size_t size, uint8_t fwid[8]) { uint8_t* src = NULL; uint8_t hash58[20]; - uint8_t fwid[8] = { - 0x00, 0x0A, 0x27, 0x00, 0x1A, 0x1D, 0x72, 0xF1 - }; /* iPod nano 3rd gen only for now. */ src = (uint8_t*)malloc(size); if (src == NULL) { Modified: trunk/pmplib/lib/pmp_ipod/itunesdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-10-05 17:13:21 UTC (rev 421) +++ trunk/pmplib/lib/pmp_ipod/itunesdb.h 2007-10-06 01:17:54 UTC (rev 422) @@ -311,7 +311,7 @@ */ int itunesdb_set_mhod_playlist_order(itunes_chunk_t* chunk, uint32_t order); -int itunesdb_finalize(uint8_t* buffer, size_t size); +int itunesdb_finalize(uint8_t* buffer, size_t size, uint8_t fwid[8]); int itunesdb_mhod_init(itunes_chunk_t* chunk, const char *name); int itunesdb_is_mhodchunk(itunes_chunk_t* chunk, const char *type); Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-10-05 17:13:21 UTC (rev 421) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.c 2007-10-06 01:17:54 UTC (rev 422) @@ -341,7 +341,7 @@ ucs2char_t itunesdb[MAX_PATH], artworkdb[MAX_PATH], playcounts[MAX_PATH]; // Initialize ipod library. - ipod_init(&ipod); + ipod_init(&ipod, pmp->info.path_to_root); // Read the music database. set_filenames(itunesdb, artworkdb, playcounts, music->pmp); @@ -403,7 +403,7 @@ ucs2char_t itunesdb[MAX_PATH], artworkdb[MAX_PATH], playcounts[MAX_PATH]; // Initialize ipod library. - ipod_init(&ipod); + ipod_init(&ipod, pmp->info.path_to_root); // Read the music database. set_filenames(itunesdb, artworkdb, playcounts, music->pmp); @@ -454,10 +454,11 @@ { ipod_t ipod; result_t ret = 0; + pmp_t* pmp = music->pmp; ucs2char_t itunesdb[MAX_PATH], artworkdb[MAX_PATH], playcounts[MAX_PATH]; // Initialize IP3DB. - ipod_init(&ipod); + ipod_init(&ipod, pmp->info.path_to_root); // Read the music database. set_filenames(itunesdb, artworkdb, playcounts, music->pmp); Modified: trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj =================================================================== --- trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-10-05 17:13:21 UTC (rev 421) +++ trunk/pmplib/lib/pmp_ipod/pmp_ipod.vcproj 2007-10-06 01:17:54 UTC (rev 422) @@ -195,10 +195,6 @@ > </File> <File - RelativePath=".\ipodserial_win32.c" - > - </File> - <File RelativePath=".\itunesdb.c" > </File> @@ -245,14 +241,6 @@ > </File> <File - RelativePath=".\ipodprop.h" - > - </File> - <File - RelativePath=".\ipodserial.h" - > - </File> - <File RelativePath=".\itunesdb.h" > </File> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-10-06 02:22:42
|
Revision: 423 http://pmplib.svn.sourceforge.net/pmplib/?rev=423&view=rev Author: nyaochi Date: 2007-10-05 19:22:44 -0700 (Fri, 05 Oct 2007) Log Message: ----------- Renamt correlation_id -> format_id since these values are associated with the dictionary entries of <key>FormatId</key>. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/artworkdb.c trunk/pmplib/lib/pmp_ipod/artworkdb.h Modified: trunk/pmplib/lib/pmp_ipod/artworkdb.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/artworkdb.c 2007-10-06 01:17:54 UTC (rev 422) +++ trunk/pmplib/lib/pmp_ipod/artworkdb.c 2007-10-06 02:22:44 UTC (rev 423) @@ -213,7 +213,7 @@ mhni = (artworkdb_mhni_t*)calloc(1, sizeof(artworkdb_mhni_t)); if (def && mhni) { mhni->num_children = 0; - mhni->correlation_id = 0; + mhni->format_id = 0; mhni->ithmb_offset = 0; mhni->ithmb_size = 0; mhni->vertical_padding = 0; @@ -231,7 +231,7 @@ artworkdb_mhni_t* mhni = (artworkdb_mhni_t*)chunk->data; if (ret = serialize_uint32le(sio, "num_children", "%d", &mhni->num_children)) return ret; - if (ret = serialize_uint32le(sio, "correlation_id", "%d", &mhni->correlation_id)) return ret; + if (ret = serialize_uint32le(sio, "format_id", "%d", &mhni->format_id)) return ret; if (ret = serialize_uint32le(sio, "ithmb_offset", "%d", &mhni->ithmb_offset)) return ret; if (ret = serialize_uint32le(sio, "ithmb_size", "%d", &mhni->ithmb_size)) return ret; if (ret = serialize_uint16le(sio, "vertical_padding", "%d", &mhni->vertical_padding)) return ret; @@ -389,7 +389,7 @@ artworkdb_mhif_t* mhif = (artworkdb_mhif_t*)chunk->data; if (ret = serialize_uint32le(sio, "unknown1", "%d", &mhif->unknown1)) return ret; - if (ret = serialize_uint32le(sio, "correlation_id", "%d", &mhif->correlation_id)) return ret; + if (ret = serialize_uint32le(sio, "format_id", "%d", &mhif->format_id)) return ret; if (ret = serialize_uint32le(sio, "image_size", "%d", &mhif->image_size)) return ret; return 0; Modified: trunk/pmplib/lib/pmp_ipod/artworkdb.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/artworkdb.h 2007-10-06 01:17:54 UTC (rev 422) +++ trunk/pmplib/lib/pmp_ipod/artworkdb.h 2007-10-06 02:22:44 UTC (rev 423) @@ -63,7 +63,7 @@ typedef struct { uint32_t num_children; - uint32_t correlation_id; + uint32_t format_id; uint32_t ithmb_offset; uint32_t ithmb_size; uint16_t vertical_padding; @@ -101,7 +101,7 @@ typedef struct { uint32_t unknown1; - uint32_t correlation_id; + uint32_t format_id; uint32_t image_size; } artworkdb_mhif_t; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-10-08 14:16:15
|
Revision: 428 http://pmplib.svn.sourceforge.net/pmplib/?rev=428&view=rev Author: nyaochi Date: 2007-10-08 07:16:18 -0700 (Mon, 08 Oct 2007) Log Message: ----------- Merge chunk_new_chid() and chunk_init() for simplicity. Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/chunk.c trunk/pmplib/lib/pmp_ipod/chunk.h trunk/pmplib/lib/pmp_ipod/ipod.c trunk/pmplib/lib/pmp_ipod/ipod_photo.c Modified: trunk/pmplib/lib/pmp_ipod/chunk.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/chunk.c 2007-10-08 08:40:37 UTC (rev 427) +++ trunk/pmplib/lib/pmp_ipod/chunk.c 2007-10-08 14:16:18 UTC (rev 428) @@ -53,6 +53,54 @@ return NULL; } +chunk_t* chunk_new( + const chunkdecl_t* cds, + chunk_t* parent, + const char *name + ) +{ + chunk_t* child = NULL; + const chunkdecl_t* decl = NULL; + + /* Find the chunk description. */ + if (name != NULL) { + decl = find_chunkdecl(cds, (int8_t*)name); + } + + if (parent != NULL) { + /* Expand the child array. */ + parent->childlen = (chunk_t*)realloc( + parent->childlen, + sizeof(chunk_t) * (parent->num_children + 1) + ); + if (parent->childlen) { + child = &parent->childlen[parent->num_children]; + memset(child, 0, sizeof(chunk_t)); + ++parent->num_children; + } + + /* Initialize the child. */ + if (child != NULL && decl != NULL) { + if (decl->init(child, 1)) { + return NULL; + } + } + } else { + /* Create a new chunk. */ + child = (chunk_t*)calloc(1, sizeof(chunk_t)); + if (child != NULL && decl != NULL) { + if (decl->init(child, 1)) { + /* Failed to initialize the chunk. */ + free(child); + child = NULL; + } + } + } + + return child; +} + +/* int chunk_init( const chunkdecl_t* cds, chunk_t* chunk, @@ -66,20 +114,9 @@ } if (ret = decl->init(chunk, 1)) return ret; - /* - if (strncmp(name, "mhod", 4) == 0) { - itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; - const itunes_mhoddecl_t* decl2 = find_mhoddecl_by_name(subtype); - if (!decl2) { - decl->finish(chunk); - return IPODE_UNKNOWNSUBTYPE; - } - chunk->overall_size = decl2->overall_size; - mhod->type = decl2->type; - } - */ return 0; } +*/ void chunk_finish( const chunkdecl_t* cds, @@ -99,6 +136,7 @@ } } +/* chunk_t* chunk_new_child(chunk_t* chunk) { chunk->childlen = (chunk_t*)realloc( @@ -112,21 +150,14 @@ return NULL; } } +*/ int chunk_is( chunk_t* chunk, const char *name ) { - /* - if (strncmp(name, "mhod", 4) == 0) { - itunesdb_mhod_t* mhod = (itunesdb_mhod_t*)chunk->data; - const itunes_mhoddecl_t* decl = find_mhoddecl(chunk); - return (decl && strcmp(decl->name, subtype) == 0) ? 1 : 0; - } else { - */ - return (strncmp(chunk->id, name, 4) == 0); -/* }*/ + return (strncmp(chunk->id, name, 4) == 0); } int chunk_repr( Modified: trunk/pmplib/lib/pmp_ipod/chunk.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/chunk.h 2007-10-08 08:40:37 UTC (rev 427) +++ trunk/pmplib/lib/pmp_ipod/chunk.h 2007-10-08 14:16:18 UTC (rev 428) @@ -47,10 +47,11 @@ int (*serialize)(chunk_t* chunk, serializer_t* sio); } chunkdecl_t; -int chunk_init(const chunkdecl_t* cds, chunk_t* chunk, const char *name); +chunk_t* chunk_new(const chunkdecl_t* cds, chunk_t* chunk, const char *name); +//int chunk_init(const chunkdecl_t* cds, chunk_t* chunk, const char *name); void chunk_finish(const chunkdecl_t* cds, chunk_t* chunk); int chunk_is(chunk_t* chunk, const char *name); -chunk_t* chunk_new_child(chunk_t* chunk); +//chunk_t* chunk_new_child(chunk_t* chunk); int chunk_repr(const chunkdecl_t* cds, chunk_t* chunk, size_t index, serializer_t* sio); int chunk_read(const chunkdecl_t* cds, chunk_t* chunk, serializer_t* sio); int chunk_write(const chunkdecl_t* cds, chunk_t* chunk, serializer_t* sio); Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-10-08 08:40:37 UTC (rev 427) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-10-08 14:16:18 UTC (rev 428) @@ -545,9 +545,8 @@ /* Construct an "mhod" chunk for title. */ if (rec->title && *rec->title) { - mhod = chunk_new_child(mhit); + mhod = chunk_new(itunesdb_cds, mhit, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "title")) return ret; if (ret = itunesdb_set_mhod_string(mhod, rec->title)) return ret; } @@ -555,9 +554,8 @@ /* Construct an "mhod" chunk for artist. */ if (rec->artist && *rec->artist) { - mhod = chunk_new_child(mhit); + mhod = chunk_new(itunesdb_cds, mhit, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "artist")) return ret; if (ret = itunesdb_set_mhod_string(mhod, rec->artist)) return ret; } @@ -566,9 +564,8 @@ /* Construct an "mhod" chunk for album artist. */ value = (rec->album_artist && *rec->album_artist) ? rec->album_artist : rec->artist; if (value && *value) { - mhod = chunk_new_child(mhit); + mhod = chunk_new(itunesdb_cds, mhit, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "album_artist")) return ret; if (ret = itunesdb_set_mhod_string(mhod, value)) return ret; } @@ -576,9 +573,8 @@ /* Construct an "mhod" chunk for album. */ if (rec->album && *rec->album) { - mhod = chunk_new_child(mhit); + mhod = chunk_new(itunesdb_cds, mhit, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "album")) return ret; if (ret = itunesdb_set_mhod_string(mhod, rec->album)) return ret; } @@ -586,27 +582,24 @@ /* Construct an "mhod" chunk for album. */ if (rec->genre && *rec->genre) { - mhod = chunk_new_child(mhit); + mhod = chunk_new(itunesdb_cds, mhit, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "genre")) return ret; if (ret = itunesdb_set_mhod_string(mhod, rec->genre)) return ret; } } /* Construct an "mhod" chunk for filetype. */ - mhod = chunk_new_child(mhit); + mhod = chunk_new(itunesdb_cds, mhit, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "filetype")) return ret; if (ret = itunesdb_set_mhod_string(mhod, L"MPEG Audio file")) return ret; } /* Construct an "mhod" chunk for comment. */ if (rec->comment && *rec->comment) { - mhod = chunk_new_child(mhit); + mhod = chunk_new(itunesdb_cds, mhit, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "comment")) return ret; if (ret = itunesdb_set_mhod_string(mhod, rec->comment)) return ret; } @@ -614,14 +607,13 @@ /* Construct an "mhod" chunk for location. */ if (rec->filename && *rec->filename) { - mhod = chunk_new_child(mhit); + mhod = chunk_new(itunesdb_cds, mhit, "mhod"); if (mhod) { ucs2char_t pathname[MAX_PATH], *p = NULL; ucs2cpy(pathname, filepath_skiproot(rec->filename, path_to_root, 1)); for (p = pathname;*p;++p) { if (*p == PATHCHAR) *p = ':'; } - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "location")) return ret; if (ret = itunesdb_set_mhod_string(mhod, pathname)) return ret; } @@ -923,27 +915,23 @@ const ucs2char_t* artist = cur->artist; if (prev_album == NULL || ucs2cmp(prev_album, album) != 0) { - mhia = chunk_new_child(mhla); - if (ret = chunk_init(itunesdb_cds, mhia, "mhia")) return ret; + mhia = chunk_new(itunesdb_cds, mhla, "mhia"); mhia_data = (itunesdb_mhia_t*)mhia->data; - mhod = chunk_new_child(mhia); + mhod = chunk_new(itunesdb_cds, mhia, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "album_albumlist")) return ret; if (ret = itunesdb_set_mhod_string(mhod, album)) return ret; } - mhod = chunk_new_child(mhia); + mhod = chunk_new(itunesdb_cds, mhia, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "artist_albumlist")) return ret; if (ret = itunesdb_set_mhod_string(mhod, artist)) return ret; } - mhod = chunk_new_child(mhia); + mhod = chunk_new(itunesdb_cds, mhia, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "sort_artist_albumlist")) return ret; if (ret = itunesdb_set_mhod_string(mhod, artist)) return ret; } @@ -985,24 +973,21 @@ mhyp_data->sort_order = 1; /* Construct an "mhod" chunk for title. */ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "title")) return ret; if (ret = itunesdb_set_mhod_string(mhod, ucs2cs_master)) return ret; } /* Construct an "mhod" chunk for index: title. */ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_title); if (ret = itunesdb_set_mhod_order(mhod, 0x03, si, num_records)) return ret; - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "library_playlist_index")) return ret; set_prefix(si, num_records, prefix_title); if (ret = itunesdb_set_mhod_index(mhod, 0x03, si, num_records)) return ret; @@ -1010,16 +995,14 @@ } /* Construct an "mhod" chunk for index: sortartist, disc/tracknumber, title. */ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_sortartist); if (ret = itunesdb_set_mhod_order(mhod, 0x05, si, num_records)) return ret; - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "library_playlist_index")) return ret; set_prefix(si, num_records, prefix_sortartist); if (ret = itunesdb_set_mhod_index(mhod, 0x05, si, num_records)) return ret; @@ -1027,16 +1010,14 @@ } /* Construct an "mhod" chunk for index: album, disc/tracknumber, title. */ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_album); if (ret = itunesdb_set_mhod_order(mhod, 0x04, si, num_records)) return ret; - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "library_playlist_index")) return ret; set_prefix(si, num_records, prefix_album); if (ret = itunesdb_set_mhod_index(mhod, 0x04, si, num_records)) return ret; @@ -1044,16 +1025,14 @@ } /* Construct an "mhod" chunk for index: genre, sortartist, album, disc/tracknumber, title */ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_genre); if (ret = itunesdb_set_mhod_order(mhod, 0x07, si, num_records)) return ret; - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "library_playlist_index")) return ret; set_prefix(si, num_records, prefix_genre); if (ret = itunesdb_set_mhod_index(mhod, 0x07, si, num_records)) return ret; @@ -1061,16 +1040,14 @@ } /* Construct an "mhod" chunk for index: composer, title. */ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_composer); if (ret = itunesdb_set_mhod_order(mhod, 0x12, si, num_records)) return ret; - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "library_playlist_index")) return ret; set_prefix(si, num_records, prefix_composer); if (ret = itunesdb_set_mhod_index(mhod, 0x12, si, num_records)) return ret; @@ -1078,34 +1055,30 @@ } /* Construct an "mhod" chunk for index: albumartist, sortartist, disc/tracknumber, title. */ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_albumartist_sortartist); if (ret = itunesdb_set_mhod_order(mhod, 0x23, si, num_records)) return ret; } /* Construct an "mhod" chunk for index: albumartist, album, disc/tracknumber, title*/ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_albumartist); if (ret = itunesdb_set_mhod_order(mhod, 0x24, si, num_records)) return ret; } /* Construct an "mhod" chunk for index: title?. */ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_title); if (ret = itunesdb_set_mhod_order(mhod, 0x1D, si, num_records)) return ret; - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "library_playlist_index")) return ret; set_prefix(si, num_records, prefix_title); if (ret = itunesdb_set_mhod_index(mhod, 0x1D, si, num_records)) return ret; @@ -1113,18 +1086,16 @@ } /* Construct an "mhod" chunk for index: title?. */ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_title); if (ret = itunesdb_set_mhod_order(mhod, 0x1E, si, num_records)) return ret; } /* Construct an "mhod" chunk for index: title?. */ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "index")) return ret; qsort(si, num_records, sizeof(si[0]), comp_title); if (ret = itunesdb_set_mhod_order(mhod, 0x1F, si, num_records)) return ret; @@ -1135,19 +1106,16 @@ /* */ for (i = 0;i < num_records;++i) { - mhip = chunk_new_child(mhyp); + mhip = chunk_new(itunesdb_cds, mhyp, "mhip"); if (mhip) { - itunesdb_mhip_t* mhip_data = NULL; - if (ret = chunk_init(itunesdb_cds, mhip, "mhip")) return ret; - mhip_data = (itunesdb_mhip_t*)mhip->data; + itunesdb_mhip_t* mhip_data = (itunesdb_mhip_t*)mhip->data; mhip_data->flag_podcast_group = 0; mhip_data->track_id = 1008 + i * 2; mhip_data->group_id = 1008 + i * 2 + 1; - mhod = chunk_new_child(mhip); + mhod = chunk_new(itunesdb_cds, mhip, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "playlist_order")) return ret; if (ret = itunesdb_set_mhod_playlist_order(mhod, 1008 + i * 2 + 1)) return ret; } else { @@ -1190,9 +1158,8 @@ mhyp_data->sort_order = 1; /* Construct an "mhod" chunk for title. */ - mhod = chunk_new_child(mhyp); + mhod = chunk_new(itunesdb_cds, mhyp, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "title")) return ret; if (ret = itunesdb_set_mhod_string(mhod, playlist->name)) return ret; } @@ -1205,19 +1172,15 @@ int index = (int)get_record_index(playlist->entries[i], records, num_records); if (index < num_records) { - mhip = chunk_new_child(mhyp); + mhip = chunk_new(itunesdb_cds, mhyp, "mhip"); if (mhip) { - itunesdb_mhip_t* mhip_data = NULL; - if (ret = chunk_init(itunesdb_cds, mhip, "mhip")) return ret; - mhip_data = (itunesdb_mhip_t*)mhip->data; - + itunesdb_mhip_t* mhip_data = (itunesdb_mhip_t*)mhip->data; mhip_data->flag_podcast_group = 0; mhip_data->track_id = index; mhip_data->group_id = index + num_records; - mhod = chunk_new_child(mhip); + mhod = chunk_new(itunesdb_cds, mhip, "mhod"); if (mhod) { - if (ret = chunk_init(itunesdb_cds, mhod, "mhod")) return ret; if (ret = itunesdb_mhod_init(mhod, "playlist_order")) return ret; if (ret = itunesdb_set_mhod_playlist_order(mhod, i+1)) return ret; } else { @@ -1253,11 +1216,10 @@ itunesdb_mhbd_t* mhbd_data = NULL; /* Construct "mhbd" chunk. */ - mhbd = (chunk_t*)calloc(1, sizeof(chunk_t)); + mhbd = chunk_new(itunesdb_cds, NULL, "mhbd"); if (!mhbd) { return IPODE_FAILEDNEWCHUNK; } - if (ret = chunk_init(itunesdb_cds, mhbd, "mhbd")) return ret; mhbd_data = (itunesdb_mhbd_t*)mhbd->data; #if 0 @@ -1283,27 +1245,21 @@ #endif /* Construct "mhsd" chunk with track type (type = 1). */ - mhsd = chunk_new_child(mhbd); + mhsd = chunk_new(itunesdb_cds, mhbd, "mhsd"); if (mhsd) { - itunesdb_mhsd_t* mhsd_data = NULL; - if (ret = chunk_init(itunesdb_cds, mhsd, "mhsd")) return ret; - mhsd_data = (itunesdb_mhsd_t*)mhsd->data; + itunesdb_mhsd_t* mhsd_data = (itunesdb_mhsd_t*)mhsd->data; mhsd_data->type = 1; /* track type. */ /* Construct "mhlt" chunk. */ - mhlt = chunk_new_child(mhsd); + mhlt = chunk_new(itunesdb_cds, mhsd, "mhlt"); if (mhlt) { - if (ret = chunk_init(itunesdb_cds, mhlt, "mhlt")) return ret; - /* For all records... */ for (i = 0;i < num_records;++i) { const pmp_music_record_t* rec = &records[i]; /* Construct "mhit" chunk. */ - mhit = chunk_new_child(mhlt); + mhit = chunk_new(itunesdb_cds, mhlt, "mhit"); if (mhit) { - if (ret = chunk_init(itunesdb_cds, mhit, "mhit")) return ret; - /* This will fill "mhit" chunk and create "mhod" chunks. */ if (ret = set_music_record(mhit, rec, i, path_to_root)) return ret; } else { @@ -1320,32 +1276,24 @@ /* Construct "mhsd" chunk with playlist type (type = 3). */ /* Construct "mhsd" chunk with playlist type (type = 2). */ - mhsd = chunk_new_child(mhbd); + mhsd = chunk_new(itunesdb_cds, mhbd, "mhsd"); if (mhsd) { - itunesdb_mhsd_t* mhsd_data = NULL; - if (ret = chunk_init(itunesdb_cds, mhsd, "mhsd")) return ret; - mhsd_data = (itunesdb_mhsd_t*)mhsd->data; + itunesdb_mhsd_t* mhsd_data = (itunesdb_mhsd_t*)mhsd->data; mhsd_data->type = 2; /* playlist type. */ /* Construct "mhlp" chunk. */ - mhlp = chunk_new_child(mhsd); + mhlp = chunk_new(itunesdb_cds, mhsd, "mhlp"); if (mhlp) { - if (ret = chunk_init(itunesdb_cds, mhlp, "mhlp")) return ret; - /* Create a master playlist. */ - mhyp = chunk_new_child(mhlp); + mhyp = chunk_new(itunesdb_cds, mhlp, "mhyp"); if (mhyp) { - itunesdb_mhyp_t* mhyp_data = NULL; - if (ret = chunk_init(itunesdb_cds, mhyp, "mhyp")) return ret; if (ret = set_master_playlist(mhyp, records, num_records)) return ret; } /* Create user's playlists. */ for (i = 0;i < num_playlists;++i) { - mhyp = chunk_new_child(mhlp); + mhyp = chunk_new(itunesdb_cds, mhlp, "mhyp"); if (mhyp) { - itunesdb_mhyp_t* mhyp_data = NULL; - if (ret = chunk_init(itunesdb_cds, mhyp, "mhyp")) return ret; if (ret = set_playlist(mhyp, &playlists[i], records, num_records)) return ret; } else { return IPODE_FAILEDNEWCHUNK; Modified: trunk/pmplib/lib/pmp_ipod/ipod_photo.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod_photo.c 2007-10-08 08:40:37 UTC (rev 427) +++ trunk/pmplib/lib/pmp_ipod/ipod_photo.c 2007-10-08 14:16:18 UTC (rev 428) @@ -82,15 +82,13 @@ int ret = 0; chunk_t* mhod = NULL; - mhod = chunk_new_child(mhii); + mhod = chunk_new(artworkdb_cds, mhii, "mhod"); if (mhod) { chunk_t* mhni = NULL; - if (ret = chunk_init(artworkdb_cds, mhod, "mhod")) return ret; if (ret = artworkdb_mhod_init(mhod, 2)) return ret; - mhni = chunk_new_child(mhod); - if (ret = chunk_init(artworkdb_cds, mhni, "mhni")) return ret; + mhni = chunk_new(artworkdb_cds, mhod, "mhni"); if (mhni) { chunk_t* mhod = NULL; artworkdb_mhni_t *mhni_data = (artworkdb_mhni_t*)mhni->data; @@ -102,9 +100,8 @@ mhni_data->width = tn->width; mhni_data->height = tn->height; - mhod = chunk_new_child(mhni); + mhod = chunk_new(artworkdb_cds, mhni, "mhod"); if (mhod) { - if (ret = chunk_init(artworkdb_cds, mhod, "mhod")) return ret; if (ret = artworkdb_mhod_init(mhod, 3)) return ret; if (ret = artworkdb_mhod_set_ucs2string(mhod, tn->filename)) return ret; } @@ -137,32 +134,25 @@ uint32_t i; chunk_t *mhba = NULL, *mhod = NULL, *mhia = NULL; - mhba = chunk_new_child(mhla); + mhba = chunk_new(artworkdb_cds, mhla, "mhba"); if (mhba) { - artworkdb_mhba_t *mhba_data = NULL; - if (ret = chunk_init(artworkdb_cds, mhba, "mhba")) return ret; - - mhba_data = (artworkdb_mhba_t*)mhba->data; + artworkdb_mhba_t *mhba_data = (artworkdb_mhba_t*)mhba->data; mhba_data->num_mhod = 1; mhba_data->num_mhia = album->num_entries; mhba_data->playlist_id = 263; mhba_data->prev_playlist_id = 100; mhba_data->album_type = 1; - mhod = chunk_new_child(mhba); + mhod = chunk_new(artworkdb_cds, mhba, "mhod"); if (mhod) { - if (ret = chunk_init(artworkdb_cds, mhod, "mhod")) return ret; if (ret = artworkdb_mhod_init(mhod, 1)) return ret; if (ret = artworkdb_mhod_set_utf8string(mhod, album->name)) return ret; } for (i = 0;i < album->num_entries;++i) { - mhia = chunk_new_child(mhba); + mhia = chunk_new(artworkdb_cds, mhba, "mhia"); if (mhia) { - artworkdb_mhia_t *mhia_data = NULL; - if (ret = chunk_init(artworkdb_cds, mhia, "mhia")) return ret; - - mhia_data = (artworkdb_mhia_t*)mhia->data; + artworkdb_mhia_t *mhia_data = (artworkdb_mhia_t*)mhia->data; mhia_data->image_id = 100+i; } } @@ -192,29 +182,24 @@ pmp_photo_album_t ma; /* Construct "mhfd" chunk. */ - mhfd = (chunk_t*)calloc(1, sizeof(chunk_t)); + mhfd = chunk_new(artworkdb_cds, NULL, "mhfd"); if (!mhfd) { return IPODE_FAILEDNEWCHUNK; } - if (ret = chunk_init(artworkdb_cds, mhfd, "mhfd")) return ret; - mhfd_data = (artworkdb_mhfd_t*)mhfd->data; + mhfd_data = (artworkdb_mhfd_t*)mhfd->data; mhfd_data->unknown8 = 2; mhfd_data->next_nhii = num_records; /* Construct "mhsd" chunk (type = 1). */ - mhsd = chunk_new_child(mhfd); + mhsd = chunk_new(artworkdb_cds, mhfd, "mhsd"); if (mhsd) { - artworkdb_mhsd_t* mhsd_data = NULL; - if (ret = chunk_init(artworkdb_cds, mhsd, "mhsd")) return ret; - mhsd_data = (artworkdb_mhsd_t*)mhsd->data; + artworkdb_mhsd_t* mhsd_data = (artworkdb_mhsd_t*)mhsd->data; mhsd_data->type = 1; /* */ /* Construct "mhli" chunk. */ - mhli = chunk_new_child(mhsd); - if (mhli) { - if (ret = chunk_init(artworkdb_cds, mhli, "mhli")) return ret; - } else { + mhli = chunk_new(artworkdb_cds, mhsd, "mhli"); + if (mhli == NULL) { return IPODE_FAILEDNEWCHUNK; } @@ -223,11 +208,9 @@ const ipod_photo_record_t* rec = &records[i]; /* Construct "mhii" chunk. */ - mhii = chunk_new_child(mhli); + mhii = chunk_new(artworkdb_cds, mhli, "mhii"); if (mhii) { - artworkdb_mhii_t* mhii_data = NULL; - if (ret = chunk_init(artworkdb_cds, mhii, "mhii")) return ret; - mhii_data = (artworkdb_mhii_t*)mhii->data; + artworkdb_mhii_t* mhii_data = (artworkdb_mhii_t*)mhii->data; /* This will fill "mhii" chunk and create "mhod" chunks. */ if (ret = set_photo_record(mhii, rec, i, path_to_root)) return ret; @@ -242,18 +225,14 @@ } /* Construct "mhsd" chunk (type = 2). */ - mhsd = chunk_new_child(mhfd); + mhsd = chunk_new(artworkdb_cds, mhfd, "mhsd"); if (mhsd) { - artworkdb_mhsd_t* mhsd_data = NULL; - if (ret = chunk_init(artworkdb_cds, mhsd, "mhsd")) return ret; - mhsd_data = (artworkdb_mhsd_t*)mhsd->data; + artworkdb_mhsd_t* mhsd_data = (artworkdb_mhsd_t*)mhsd->data; mhsd_data->type = 2; /* */ /* Construct "mhla" chunk. */ - mhla = chunk_new_child(mhsd); - if (mhla) { - if (ret = chunk_init(artworkdb_cds, mhla, "mhla")) return ret; - } else { + mhla = chunk_new(artworkdb_cds, mhsd, "mhla"); + if (mhla == NULL) { return IPODE_FAILEDNEWCHUNK; } @@ -272,24 +251,19 @@ } /* Construct "mhsd" chunk (type = 3). */ - mhsd = chunk_new_child(mhfd); + mhsd = chunk_new(artworkdb_cds, mhfd, "mhsd"); if (mhsd) { - artworkdb_mhsd_t* mhsd_data = NULL; - if (ret = chunk_init(artworkdb_cds, mhsd, "mhsd")) return ret; - mhsd_data = (artworkdb_mhsd_t*)mhsd->data; + artworkdb_mhsd_t* mhsd_data = (artworkdb_mhsd_t*)mhsd->data; mhsd_data->type = 3; /* */ /* Construct "mhlf" chunk. */ - mhlf = chunk_new_child(mhsd); - if (mhlf) { - if (ret = chunk_init(artworkdb_cds, mhlf, "mhlf")) return ret; - } else { + mhlf = chunk_new(artworkdb_cds, mhsd, "mhlf"); + if (mhlf == NULL) { return IPODE_FAILEDNEWCHUNK; } for (i = 0;i < ipod->num_photo_formats;++i) { - mhif = chunk_new_child(mhlf); - if (ret = chunk_init(artworkdb_cds, mhif, "mhif")) return ret; + mhif = chunk_new(artworkdb_cds, mhlf, "mhif"); mhif_data = (artworkdb_mhif_t*)mhif->data; mhif_data->format_id = ipod->photo_formats[i].format; mhif_data->image_size = ipod->photo_formats[i].size; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-10-08 14:27:24
|
Revision: 429 http://pmplib.svn.sourceforge.net/pmplib/?rev=429&view=rev Author: nyaochi Date: 2007-10-08 07:27:27 -0700 (Mon, 08 Oct 2007) Log Message: ----------- Rename chunk_finish() to chunk_delete(). Source-code cleanup for chunk.[c,h] Modified Paths: -------------- trunk/pmplib/lib/pmp_ipod/chunk.c trunk/pmplib/lib/pmp_ipod/chunk.h trunk/pmplib/lib/pmp_ipod/ipod.c Modified: trunk/pmplib/lib/pmp_ipod/chunk.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/chunk.c 2007-10-08 14:16:18 UTC (rev 428) +++ trunk/pmplib/lib/pmp_ipod/chunk.c 2007-10-08 14:27:27 UTC (rev 429) @@ -39,7 +39,8 @@ #include "util.h" #include "chunk.h" -static const chunkdecl_t* find_chunkdecl( +static const chunkdecl_t* +find_chunkdecl( const chunkdecl_t* cds, const int8_t* name ) @@ -53,7 +54,8 @@ return NULL; } -chunk_t* chunk_new( +chunk_t* +chunk_new( const chunkdecl_t* cds, chunk_t* parent, const char *name @@ -100,59 +102,29 @@ return child; } -/* -int chunk_init( +void +chunk_delete( const chunkdecl_t* cds, - chunk_t* chunk, - const char *name - ) -{ - int ret = 0; - const chunkdecl_t* decl = find_chunkdecl(cds, (int8_t*)name); - if (!decl) { - return IPODE_UNKNOWNCHUNK; - } - - if (ret = decl->init(chunk, 1)) return ret; - return 0; -} -*/ - -void chunk_finish( - const chunkdecl_t* cds, chunk_t* chunk ) { uint32_t i; const chunkdecl_t* decl = NULL; + /* Delete children (recursively). */ for (i = 0;i < chunk->num_children;++i) { - chunk_finish(cds, &chunk->childlen[i]); + chunk_delete(cds, &chunk->childlen[i]); } + /* Delete this chunk. */ decl = find_chunkdecl(cds, chunk->id); if (decl) { decl->finish(chunk); } } -/* -chunk_t* chunk_new_child(chunk_t* chunk) -{ - chunk->childlen = (chunk_t*)realloc( - chunk->childlen, sizeof(chunk_t) * (chunk->num_children + 1)); - if (chunk->childlen) { - chunk_t* child = &chunk->childlen[chunk->num_children]; - memset(child, 0, sizeof(chunk_t)); - ++chunk->num_children; - return child; - } else { - return NULL; - } -} -*/ - -int chunk_is( +int +chunk_is( chunk_t* chunk, const char *name ) @@ -160,7 +132,8 @@ return (strncmp(chunk->id, name, 4) == 0); } -int chunk_repr( +int +chunk_repr( const chunkdecl_t* cds, chunk_t* chunk, size_t index, @@ -173,7 +146,7 @@ /* Start of a chunk */ serialize_indent(sio); - fprintf(sio->fp, "Chunk %c%c%c%c (%d) = {\n", chunk->id[0], chunk->id[1], chunk->id[2], chunk->id[3], index); + fprintf(sio->fp, "CHUNK %c%c%c%c (%d) = {\n", chunk->id[0], chunk->id[1], chunk->id[2], chunk->id[3], index); serialize_indent_ascend(sio); /* Show information of the chunk header */ @@ -223,7 +196,8 @@ return 0; } -int chunk_read( +int +chunk_read( const chunkdecl_t* cds, chunk_t* chunk, serializer_t* sio @@ -253,13 +227,8 @@ } /* Determine the size of padded data for this chunk. */ - //if (strncmp(chunk->id, "mhod", 4) == 0) { - // next = begin + chunk->overall_size; - // chunk->padding_size = next - serialize_tell(sio); - //} else { - next = begin + chunk->size; - chunk->padding_size = next - serialize_tell(sio); - //} + next = begin + chunk->size; + chunk->padding_size = next - serialize_tell(sio); /* Read the padded data. */ if (0 < chunk->padding_size) { @@ -304,7 +273,8 @@ return 0; } -int chunk_write( +int +chunk_write( const chunkdecl_t* cds, chunk_t* chunk, serializer_t* sio @@ -348,6 +318,7 @@ chunk->overall_size = (uint32_t)serialize_tell(sio) - chunk->offset; } + /* Finalize the size of this chunk (including the descendants). */ offset = (uint32_t)serialize_tell(sio); if (ret = serialize_seek(sio, chunk->offset + 2 * sizeof(uint32_t))) return ret; if (ret = serialize_uint32le(sio, "overall_size", "%d", &chunk->overall_size)) return ret; Modified: trunk/pmplib/lib/pmp_ipod/chunk.h =================================================================== --- trunk/pmplib/lib/pmp_ipod/chunk.h 2007-10-08 14:16:18 UTC (rev 428) +++ trunk/pmplib/lib/pmp_ipod/chunk.h 2007-10-08 14:27:27 UTC (rev 429) @@ -48,10 +48,8 @@ } chunkdecl_t; chunk_t* chunk_new(const chunkdecl_t* cds, chunk_t* chunk, const char *name); -//int chunk_init(const chunkdecl_t* cds, chunk_t* chunk, const char *name); -void chunk_finish(const chunkdecl_t* cds, chunk_t* chunk); +void chunk_delete(const chunkdecl_t* cds, chunk_t* chunk); int chunk_is(chunk_t* chunk, const char *name); -//chunk_t* chunk_new_child(chunk_t* chunk); int chunk_repr(const chunkdecl_t* cds, chunk_t* chunk, size_t index, serializer_t* sio); int chunk_read(const chunkdecl_t* cds, chunk_t* chunk, serializer_t* sio); int chunk_write(const chunkdecl_t* cds, chunk_t* chunk, serializer_t* sio); Modified: trunk/pmplib/lib/pmp_ipod/ipod.c =================================================================== --- trunk/pmplib/lib/pmp_ipod/ipod.c 2007-10-08 14:16:18 UTC (rev 428) +++ trunk/pmplib/lib/pmp_ipod/ipod.c 2007-10-08 14:27:27 UTC (rev 429) @@ -290,9 +290,9 @@ void ipod_finish(ipod_t* ipod) { - chunk_finish(artworkdb_cds, ipod->photodb); - chunk_finish(itunesdb_cds, ipod->itunesdb); - chunk_finish(artworkdb_cds, ipod->artworkdb); + chunk_delete(artworkdb_cds, ipod->photodb); + chunk_delete(itunesdb_cds, ipod->itunesdb); + chunk_delete(artworkdb_cds, ipod->artworkdb); playcounts_finish(ipod->pcs); free(ipod->photo_formats); free(ipod->pcs); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |