iPodDB.h 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256
  1. /*
  2. *
  3. *
  4. * Copyright (c) 2004 Samuel Wood ([email protected])
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. The name of the author may not be used to endorse or promote products
  16. * derived from this software without specific prior permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  19. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  20. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. *
  30. *
  31. */
  32. // For more information on how all this stuff works, see:
  33. // http://www.ipodlinux.org/ITunesDB
  34. // iPodDB.h: interface for the iPod classes.
  35. //
  36. //////////////////////////////////////////////////////////////////////
  37. #ifndef __IPODDB_H__
  38. #define __IPODDB_H__
  39. #pragma once
  40. #pragma warning( disable : 4786)
  41. #include <algorithm>
  42. #include <windows.h>
  43. #include <bfc/platform/types.h>
  44. #include <map>
  45. #include <vector>
  46. #ifdef _DEBUG
  47. #undef ASSERT
  48. #define ASSERT(x) assert(x)
  49. #else
  50. #define ASSERT(x) {}
  51. #endif
  52. // mhod types
  53. #define MHOD_TITLE 1
  54. #define MHOD_LOCATION 2
  55. #define MHOD_ALBUM 3
  56. #define MHOD_ARTIST 4
  57. #define MHOD_GENRE 5
  58. #define MHOD_FILETYPE 6
  59. #define MHOD_EQSETTING 7
  60. #define MHOD_COMMENT 8
  61. #define MHOD_CATEGORY 9 // iTunes Music Store Podcast category
  62. #define MHOD_COMPOSER 12
  63. #define MHOD_GROUPING 13
  64. #define MHOD_DESCRIPTION 14 // Podcast show notes text - accessible via the center iPod button
  65. #define MHOD_ENCLOSUREURL 15 // Used by iTunes 4.9 for a Podcast's original enclosure URL
  66. #define MHOD_RSSFEEDURL 16 // Used by iTunes 4.9 for a Podcast's RSS 2.0 feed URL
  67. #define MHOD_CHAPTER 17 // M4A-style tagged data that is used to support subsongs/chapters
  68. #define MHOD_SUBTITLE 18
  69. #define MHOD_SHOW 19
  70. #define MHOD_EPISODE 20
  71. #define MHOD_TVNETWORK 21
  72. #define MHOD_ALBUMARTIST 22
  73. #define MHOD_ARTIST_SORT 23
  74. #define MHOD_TITLE_SORT 27
  75. #define MHOD_ALBUM_SORT 28
  76. #define MHOD_ALBUMARTIST_SORT 29
  77. #define MHOD_COMPOSER_SORT 30
  78. #define MHOD_SHOW_SORT 31
  79. #define MHOD_SPLPREF 50
  80. #define MHOD_SPLDATA 51
  81. #define MHOD_LIBRARY 52 // Found in the default hidden playlist
  82. #define MHOD_LIBRARY_LETTER 53 // letter jump table
  83. #define MHOD_PLAYLIST 100
  84. #define MHOD_ALBUMLIST_ALBUM 200
  85. #define MHOD_ALBUMLIST_ARTIST 201
  86. #define MHOD_ALBUMLIST_ARTIST_SORT 202
  87. #define MHOD_ALBUMLIST_PODCASTURL 203
  88. #define MHOD_ALBUMLIST_SHOW 204
  89. // Equalizer defines
  90. #define EQ_NONE -1
  91. #define EQ_ACOUSTIC 100
  92. #define EQ_BASSBOOSTER 101
  93. #define EQ_BASSREDUCER 102
  94. #define EQ_CLASSICAL 103
  95. #define EQ_DANCE 104
  96. #define EQ_DEEP 105
  97. #define EQ_ELECTRONIC 106
  98. #define EQ_FLAT 107
  99. #define EQ_HIPHOP 108
  100. #define EQ_JAZZ 109
  101. #define EQ_LATIN 110
  102. #define EQ_LOUDNESS 111
  103. #define EQ_LOUNGE 112
  104. #define EQ_PIANO 113
  105. #define EQ_POP 114
  106. #define EQ_RNB 115
  107. #define EQ_ROCK 116
  108. #define EQ_SMALLSPEAKERS 117
  109. #define EQ_SPOKENWORD 118
  110. #define EQ_TREBLEBOOSTER 119
  111. #define EQ_TREBLEREDUCER 120
  112. #define EQ_VOCALBOOSTER 121
  113. // Smart Playlist stuff
  114. #define SPLMATCH_AND 0 // AND rule - all of the rules must be true in order for the combined rule to be applied
  115. #define SPLMATCH_OR 1 // OR rule
  116. // Limit Types.. like limit playlist to 100 minutes or to 100 songs
  117. #define LIMITTYPE_MINUTES 0x01
  118. #define LIMITTYPE_MB 0x02
  119. #define LIMITTYPE_SONGS 0x03
  120. #define LIMITTYPE_HOURS 0x04
  121. #define LIMITTYPE_GB 0x05
  122. // Limit Sorts.. Like which songs to pick when using a limit type
  123. // Special note: the values for LIMITSORT_LEAST_RECENTLY_ADDED, LIMITSORT_LEAST_OFTEN_PLAYED,
  124. // LIMITSORT_LEAST_RECENTLY_PLAYED, and LIMITSORT_LOWEST_RATING are really 0x10, 0x14,
  125. // 0x15, 0x17, with the 'limitsort_opposite' flag set. This is the same value as the
  126. // "positive" value (i.e. LIMITSORT_LEAST_RECENTLY_ADDED), and is really very terribly
  127. // awfully weird, so we map the values to iPodDB specific values with the high bit set.
  128. //
  129. // On writing, we check the high bit and write the limitsort_opposite from that. That
  130. // way, we don't have to deal with programs using the class needing to set the wrong
  131. // limit and then make it into the "opposite", which would be frickin' annoying.
  132. #define LIMITSORT_RANDOM 0x02
  133. #define LIMITSORT_SONG_NAME 0x03
  134. #define LIMITSORT_ALBUM 0x04
  135. #define LIMITSORT_ARTIST 0x05
  136. #define LIMITSORT_GENRE 0x07
  137. #define LIMITSORT_MOST_RECENTLY_ADDED 0x10
  138. #define LIMITSORT_COMPOSER 0x12 // Not used by iTunes, but inferred from the Type 52 MHOD's Composer type
  139. #define LIMITSORT_LEAST_RECENTLY_ADDED 0x80000010 // See note above
  140. #define LIMITSORT_MOST_OFTEN_PLAYED 0x14
  141. #define LIMITSORT_LEAST_OFTEN_PLAYED 0x80000014 // See note above
  142. #define LIMITSORT_MOST_RECENTLY_PLAYED 0x15
  143. #define LIMITSORT_LEAST_RECENTLY_PLAYED 0x80000015 // See note above
  144. #define LIMITSORT_HIGHEST_RATING 0x17
  145. #define LIMITSORT_LOWEST_RATING 0x80000017 // See note above
  146. // Smartlist Actions - Used in the rules.
  147. /*
  148. really this is a bitmapped field...
  149. high byte
  150. bit 0 = "string" values if set, "int" values if not set
  151. bit 1 = "not", or to negate the check.
  152. lower 2 bytes
  153. bit 0 = simple "IS" query
  154. bit 1 = contains
  155. bit 2 = begins with
  156. bit 3 = ends with
  157. bit 4 = greater than
  158. bit 5 = unknown, but probably greater than or equal to
  159. bit 6 = less than
  160. bit 7 = unknown, but probably less than or equal to
  161. bit 8 = a range selection
  162. bit 9 = "in the last"
  163. */
  164. #define SPLACTION_IS_INT 0x00000001 // Also called "Is Set" in iTunes
  165. #define SPLACTION_IS_GREATER_THAN 0x00000010 // Also called "Is After" in iTunes
  166. #define SPLACTION_IS_LESS_THAN 0x00000040 // Also called "Is Before" in iTunes
  167. #define SPLACTION_IS_IN_THE_RANGE 0x00000100
  168. #define SPLACTION_IS_IN_THE_LAST 0x00000200
  169. #define SPLACTION_BINARY_AND 0x00000400
  170. #define SPLACTION_IS_STRING 0x01000001
  171. #define SPLACTION_CONTAINS 0x01000002
  172. #define SPLACTION_STARTS_WITH 0x01000004
  173. #define SPLACTION_ENDS_WITH 0x01000008
  174. #define SPLACTION_IS_NOT_INT 0x02000001 // Also called "Is Not Set" in iTunes
  175. #define SPLACTION_IS_NOT_GREATER_THAN 0x02000010 // Note: Not available in iTunes
  176. #define SPLACTION_IS_NOT_LESS_THAN 0x02000040 // Note: Not available in iTunes
  177. #define SPLACTION_IS_NOT_IN_THE_RANGE 0x02000100 // Note: Not available in iTunes
  178. #define SPLACTION_IS_NOT_IN_THE_LAST 0x02000200
  179. #define SPLACTION_UNKNOWN2 0x02000800
  180. #define SPLACTION_IS_NOT 0x03000001
  181. #define SPLACTION_DOES_NOT_CONTAIN 0x03000002
  182. #define SPLACTION_DOES_NOT_START_WITH 0x03000004 // Note: Not available in iTunes
  183. #define SPLACTION_DOES_NOT_END_WITH 0x03000008 // Note: Not available in iTunes
  184. // these are to pass to AddRule() when you need a unit for the two "in the last" action types
  185. // Or, in theory, you can use any time range... iTunes might not like it, but the iPod might.
  186. #define SPLACTION_LAST_DAYS_VALUE 86400 // number of seconds in 24 hours
  187. #define SPLACTION_LAST_WEEKS_VALUE 604800 // number of seconds in 7 days
  188. #define SPLACTION_LAST_MONTHS_VALUE 2628000 // number of seconds in 30.4167 days ~= 1 month
  189. // Hey, why limit ourselves to what iTunes can do? If the iPod can deal with it, excellent!
  190. #define SPLACTION_LAST_SECONDS_RULE 1 // one second
  191. #define SPLACTION_LAST_HOURS_VALUE 3600 // number of seconds in 1 hour
  192. #define SPLACTION_LAST_MINUTES_VALUE 60 // number of seconds in 1 minute
  193. #define SPLACTION_LAST_YEARS_VALUE 31536000 // number of seconds in 365 days
  194. // fun ones.. Near as I can tell, all of these work. It's open like that. :)
  195. #define SPLACTION_LAST_LUNARCYCLE_VALUE 2551443 // a "lunar cycle" is the time it takes the moon to circle the earth
  196. #define SPLACTION_LAST_SIDEREAL_DAY 86164 // a "sidereal day" is time in one revolution of earth on its axis
  197. #define SPLACTION_LAST_SWATCH_BEAT 86 // a "swatch beat" is 1/1000th of a day.. search for "internet time" on google
  198. #define SPLACTION_LAST_MOMENT 90 // a "moment" is 1/40th of an hour, or 1.5 minutes
  199. #define SPLACTION_LAST_OSTENT 600 // an "ostent" is 1/10th of an hour, or 6 minutes
  200. #define SPLACTION_LAST_FORTNIGHT 1209600 // a "fortnight" is 14 days
  201. #define SPLACTION_LAST_VINAL 1728000 // a "vinal" is 20 days
  202. #define SPLACTION_LAST_QUARTER 7889231 // a "quarter" is a quarter year
  203. #define SPLACTION_LAST_SOLAR_YEAR 31556926 // a "solar year" is the time it takes the earth to go around the sun
  204. #define SPLACTION_LAST_SIDEREAL_YEAR 31558150 // a "sidereal year" is the time it takes the earth to reach the same point in space again, compared to the stars
  205. // Smartlist fields - Used for rules.
  206. #define SPLFIELD_SONG_NAME 0x02 // String
  207. #define SPLFIELD_ALBUM 0x03 // String
  208. #define SPLFIELD_ARTIST 0x04 // String
  209. #define SPLFIELD_BITRATE 0x05 // Int (e.g. from/to = 128)
  210. #define SPLFIELD_SAMPLE_RATE 0x06 // Int (e.g. from/to = 44100)
  211. #define SPLFIELD_YEAR 0x07 // Int (e.g. from/to = 2004)
  212. #define SPLFIELD_GENRE 0x08 // String
  213. #define SPLFIELD_KIND 0x09 // String
  214. #define SPLFIELD_DATE_MODIFIED 0x0a // Int/Mac Timestamp (e.g. from/to = bcf93280 == is before 6/19/2004)
  215. #define SPLFIELD_TRACKNUMBER 0x0b // Int (e.g. from = 1, to = 2)
  216. #define SPLFIELD_SIZE 0x0c // Int (e.g. from/to = 0x00600000 for 6MB)
  217. #define SPLFIELD_TIME 0x0d // Int (e.g. from/to = 83999 for 1:23/83 seconds)
  218. #define SPLFIELD_COMMENT 0x0e // String
  219. #define SPLFIELD_DATE_ADDED 0x10 // Int/Mac Timestamp (e.g. from/to = bcfa83ff == is after 6/19/2004)
  220. #define SPLFIELD_COMPOSER 0x12 // String
  221. #define SPLFIELD_PLAYCOUNT 0x16 // Int (e.g. from/to = 1)
  222. #define SPLFIELD_LAST_PLAYED 0x17 // Int/Mac Timestamp (e.g. from = bcfa83ff (6/19/2004), to = 0xbcfbd57f (6/20/2004))
  223. #define SPLFIELD_DISC_NUMBER 0x18 // Int (e.g. from/to = 1)
  224. #define SPLFIELD_RATING 0x19 // Int/Stars Rating (e.g. from/to = 60 (3 stars))
  225. #define SPLFIELD_COMPILATION 0x1f // Int (e.g. is set -> SPLACTION_IS_INT/from=1, is not set -> SPLACTION_IS_NOT_INT/from=1)
  226. #define SPLFIELD_BPM 0x23 // Int (e.g. from/to = 60)
  227. #define SPLFIELD_GROUPING 0x27 // String
  228. #define SPLFIELD_PLAYLIST 0x28 // XXX - Unknown...not parsed correctly...from/to = 0xb6fbad5f for "Purchased Music". Extra data after "to"...
  229. #define SPLFIELD_VIDEO_KIND 0x3C // Logic Int (???)
  230. #define SPLFIELD_TVSHOW 0x3E // Int
  231. #define SPLFIELD_SEASON_NR 0x3F // Int
  232. #define SPLFIELD_SKIPCOUNT 0x44 // Int
  233. #define SPLFIELD_ALBUMARTIST 0x47 // string
  234. #define SPLDATE_IDENTIFIER 0x2dae2dae2dae2dae
  235. // MHOD Type 52 types
  236. #define TYPE52_SONG_NAME 0x03
  237. #define TYPE52_ARTIST 0x05
  238. #define TYPE52_ALBUM 0x04
  239. #define TYPE52_GENRE 0x07
  240. #define TYPE52_COMPOSER 0x12
  241. static const uint32_t FILETYPE_M4A=0x4d344120;
  242. static const uint32_t FILETYPE_MP3=0x4d503320;
  243. static const uint32_t FILETYPE_WAV=0x57415620;
  244. // useful functions
  245. time_t mactime_to_wintime (const unsigned long mactime);
  246. unsigned long wintime_to_mactime (const __time64_t time);
  247. char * UTF16_to_char(wchar_t * str, int length);
  248. // Pre-declare iPod_* classes
  249. class iPod_mhbd;
  250. class iPod_mhsd;
  251. class iPod_mhlt;
  252. class iPod_mhit;
  253. class iPod_mhlp;
  254. class iPod_mhyp;
  255. class iPod_slst;
  256. class iPod_mhip;
  257. class iPod_mhod;
  258. class iPod_mqed;
  259. class iPod_mhpo;
  260. class iPod_pqed;
  261. class iPod_mhla;
  262. // Maximum string length that iTunes writes to the database
  263. #define SPL_MAXSTRINGLENGTH 255
  264. // a struct to hold smart playlist rules in mhods
  265. struct SPLRule
  266. {
  267. SPLRule() :
  268. field(0),
  269. action(0),
  270. length(0),
  271. fromvalue(0),
  272. fromdate(0),
  273. fromunits(0),
  274. tovalue(0),
  275. todate(0),
  276. tounits(0),
  277. unk1(0),
  278. unk2(0),
  279. unk3(0),
  280. unk4(0),
  281. unk5(0)
  282. {
  283. memset(string, 0, sizeof(string));
  284. }
  285. void SetString(const wchar_t *value)
  286. {
  287. if(value)
  288. {
  289. lstrcpynW(string, value, SPL_MAXSTRINGLENGTH);
  290. length = lstrlenW(string) * 2;
  291. }
  292. else
  293. {
  294. memset(string, 0, sizeof(string));
  295. length = 0;
  296. }
  297. }
  298. unsigned long field;
  299. unsigned long action;
  300. unsigned long length;
  301. wchar_t string[SPL_MAXSTRINGLENGTH + 1];
  302. // from and to are pretty stupid.. if it's a date type of field, then
  303. // value = 0x2dae2dae2dae2dae,
  304. // date = some number, like 2 or -2
  305. // units = unit in seconds, like 604800 = a week
  306. // but if this is actually some kind of integer comparison, like rating = 60 (3 stars)
  307. // value = the value we care about
  308. // date = 0
  309. // units = 1
  310. // So we leave these as they are, and will just deal with it in the rules functions.
  311. uint64_t fromvalue;
  312. int64_t fromdate;
  313. uint64_t fromunits;
  314. uint64_t tovalue;
  315. int64_t todate;
  316. uint64_t tounits;
  317. unsigned long unk1;
  318. unsigned long unk2;
  319. unsigned long unk3;
  320. unsigned long unk4;
  321. unsigned long unk5;
  322. };
  323. // PCEntry: Play Count struct for the entries in iPod_mhdp
  324. struct PCEntry
  325. {
  326. unsigned long playcount;
  327. unsigned long lastplayedtime;
  328. unsigned long bookmarktime;
  329. unsigned long stars;
  330. uint32_t unk1;
  331. uint32_t skipcount;
  332. uint32_t skippedtime;
  333. };
  334. /**************************************
  335. iTunesDB Database Layout
  336. MHBD (Database)
  337. |
  338. |-MHSD (Data Set)
  339. | |
  340. | |-MHLT (Track List)
  341. | | |
  342. | | |-MHIT (Track Item)
  343. | | | |
  344. | | | |-MHOD (Description Object)
  345. | | | |-MHOD
  346. | | | | ...
  347. | | |
  348. | | |-MHIT
  349. | | | |
  350. | | | |-MHOD
  351. | | | |-MHOD
  352. | | | | ...
  353. | | |
  354. | | |-...
  355. |
  356. |
  357. |-MHSD
  358. | |
  359. | |-MHLP (Playlists List)
  360. | | |
  361. | | |-MHYP (Playlist)
  362. | | | |
  363. | | | |-MHOD
  364. | | | |-MHIP (Playlist Item)
  365. | | | | ...
  366. | | |
  367. | | |-MHYP
  368. | | | |
  369. | | | |-MHOD
  370. | | | |-MHIP
  371. | | | | ...
  372. | | |
  373. | | |-...
  374. **************************************/
  375. // base class, not used directly
  376. class iPodObj
  377. {
  378. public:
  379. iPodObj();
  380. virtual ~iPodObj();
  381. // parse function is required in all subclasses
  382. // feed it a iTunesDB, it creates an object hierarchy
  383. virtual long parse(const uint8_t *data) = 0;
  384. // write function is required too
  385. // feed it a buffer and the size of the buffer, it fills it with an iTunesDB
  386. // return value is size of the resulting iTunesDB
  387. // return of -1 means the buffer was too small
  388. virtual long write(uint8_t * data, const unsigned long datasize) = 0;
  389. unsigned long size_head;
  390. unsigned long size_total;
  391. };
  392. // MHBD: The database - parent of all items
  393. class iPod_mhbd : public iPodObj
  394. {
  395. public:
  396. iPod_mhbd();
  397. virtual ~iPod_mhbd();
  398. virtual long parse(const uint8_t *data);
  399. virtual long write(uint8_t * data, const unsigned long datasize);
  400. virtual long write(uint8_t * data, const unsigned long datasize, uint8_t * fwid);
  401. uint32_t unk1;
  402. uint32_t dbversion;
  403. uint32_t children;
  404. uint64_t id;
  405. uint16_t platform;
  406. uint16_t language;
  407. uint64_t library_id;
  408. uint32_t unk80;
  409. uint32_t unk84;
  410. int32_t timezone; // in seconds
  411. uint16_t audio_language;
  412. uint16_t subtitle_language;
  413. uint16_t unk164;
  414. uint16_t unk166;
  415. uint16_t unk168;
  416. iPod_mhsd *mhsdsongs;
  417. iPod_mhsd *mhsdplaylists;
  418. iPod_mhsd *mhsdsmartplaylists;
  419. };
  420. // MHSD: List container - parent of MHLT or MHLP, child of MHBD
  421. class iPod_mhsd : public iPodObj
  422. {
  423. public:
  424. iPod_mhsd();
  425. iPod_mhsd(int newindex);
  426. virtual ~iPod_mhsd();
  427. virtual long parse(const uint8_t *data);
  428. virtual long write(unsigned char * data, const unsigned long datasize) {return write(data,datasize,1);}
  429. virtual long write(unsigned char * data, const unsigned long datasize, int index);
  430. uint32_t index; // 1 = mhlt, 3 = mhlp, 2 = legacy mhlp, 4 = album list, 5 = mhlp_smart
  431. iPod_mhlt * mhlt;
  432. iPod_mhlp * mhlp;
  433. iPod_mhlp * mhlp_smart;
  434. iPod_mhla * mhla;
  435. };
  436. class iPod_mhia : public iPodObj
  437. {
  438. public:
  439. iPod_mhia();
  440. virtual ~iPod_mhia();
  441. virtual long parse(const uint8_t *data);
  442. virtual long write(unsigned char * data, const unsigned long datasize);
  443. uint16_t unk1;
  444. uint16_t albumid;
  445. uint64_t dbid;
  446. uint32_t type;
  447. std::vector<iPod_mhod*> mhod;
  448. };
  449. class ArtistAlbumPair
  450. {
  451. public:
  452. const wchar_t* artist;
  453. const wchar_t* album;
  454. ArtistAlbumPair() : artist(0), album(0) {}
  455. ArtistAlbumPair(const wchar_t* artist, const wchar_t* album) : artist(artist), album(album) {}
  456. /*bool operator < (const ArtistAlbumPair& that) const
  457. {
  458. int yy = _wcsicmp(artist, that.artist);
  459. if(yy) return yy < 0;
  460. return _wcsicmp(album, that.album) < 0;
  461. }*/
  462. };
  463. struct ArtistAlbumPairComparer
  464. {
  465. int operator ()(const ArtistAlbumPair &a, const ArtistAlbumPair &b) const
  466. {
  467. int yy = _wcsicmp(a.artist, b.artist);
  468. if(yy) return yy;
  469. return _wcsicmp(a.album, b.album);
  470. }
  471. };
  472. class iPod_mhla : public iPodObj
  473. {
  474. public:
  475. iPod_mhla();
  476. virtual ~iPod_mhla();
  477. virtual long parse(const uint8_t *data);
  478. virtual long write(unsigned char * data, const unsigned long datasize);
  479. uint16_t GetAlbumId(const wchar_t* artist, const wchar_t* album);
  480. void ClearAlbumsList();
  481. //typedef std::map<ArtistAlbumPair, uint16_t> albums_map_t;
  482. typedef std::map<ArtistAlbumPair, uint16_t, ArtistAlbumPairComparer> albums_map_t;
  483. albums_map_t albums;
  484. uint16_t nextAlbumId;
  485. };
  486. // MHLT: song list container - parent of MHIT, child of MHSD
  487. class iPod_mhlt : public iPodObj
  488. {
  489. public:
  490. typedef std::map<uint32_t, iPod_mhit*> mhit_map_t;
  491. //typedef std::map<unsigned long, iPod_mhit*> mhit_map_t; // Map the unique mhit.id to a mhit object
  492. typedef mhit_map_t::value_type mhit_value_t;
  493. iPod_mhlt();
  494. virtual ~iPod_mhlt();
  495. virtual long parse(const uint8_t *data);
  496. virtual long write(unsigned char * data, const unsigned long datasize);
  497. const unsigned long GetChildrenCount() const { return mhit.size(); }
  498. // returns a pointer to the new iPod_mhit object in the track list, which you edit directly
  499. iPod_mhit *NewTrack();
  500. void AddTrack(iPod_mhit *new_track);
  501. // takes a position index, returns a pointer to the track itself, or NULL if the index isn't found.
  502. iPod_mhit *GetTrack(uint32_t index) const;
  503. // searches for a track based on the track's id number (mhit.id). returns mhit pointer, or NULL if the id isn't found.
  504. iPod_mhit * GetTrackByID(const unsigned long id);
  505. // couple of ways to delete a track
  506. bool DeleteTrack(const unsigned long index);
  507. bool DeleteTrackByID(const unsigned long id);
  508. // clears out the tracklist
  509. bool ClearTracks(const bool clearMap = true);
  510. // the map of the tracks themselves
  511. mhit_map_t mhit;
  512. std::vector<uint32_t> mhit_indexer;
  513. uint32_t GetNextID();
  514. private:
  515. volatile uint32_t next_mhit_id;
  516. };
  517. // MHIT: song item - parent of MHOD, child of MHLT
  518. class iPod_mhit : public iPodObj
  519. {
  520. public:
  521. iPod_mhit();
  522. virtual ~iPod_mhit();
  523. virtual long parse(const uint8_t *data);
  524. virtual long write(unsigned char * data, const unsigned long datasize);
  525. const unsigned long GetChildrenCount() const { return(mhod.size()); }
  526. // will add a new mhod string to the mhit
  527. // optional: pass in a type to get an existing string, if there is one,
  528. // or a new one with the type filled in already, if there is not one
  529. iPod_mhod * AddString(const int type=0);
  530. // Find a string by type
  531. iPod_mhod * FindString(const unsigned long type) const;
  532. // deletes a string from the track
  533. // if more than one string of given type exists, all of that type will be deleted,
  534. // to ensure consistency. Pointers to these strings will be invalid after this.
  535. // return val is how many strings were deleted
  536. unsigned long DeleteString(const unsigned long type);
  537. // Creates a copy of the mhit. The operator = is overloaded so you can
  538. // more easily copy mhit's.
  539. static void Duplicate(const iPod_mhit *src, iPod_mhit *dst);
  540. iPod_mhit& operator=(const iPod_mhit& src);
  541. int GetRating() { return stars/20; }
  542. void SetRating(int rating) { stars=rating*20; }
  543. int GetEQSetting();
  544. void SetEQSetting(int value);
  545. unsigned int GetFileTypeID(const wchar_t *filename);
  546. uint32_t id;
  547. uint32_t visible; // 0x01 means the song shows up on the iPod, all other values means it is hidden
  548. uint32_t filetype; // MP3 = 0x4d503320, M4A = 0x4d344120, M4B = 0x4d344220, M4P = 0x4d345020, WAV = 0x57415620, AA = ???
  549. uint8_t vbr;
  550. uint8_t type;
  551. uint8_t compilation;
  552. uint8_t stars;
  553. uint32_t lastmodifiedtime; // iTunes sets this the UTC time value for the Windows Last Modified timestamp
  554. uint32_t size;
  555. uint32_t length;
  556. uint32_t tracknum;
  557. uint32_t totaltracks;
  558. uint32_t year;
  559. uint32_t bitrate;
  560. uint16_t samplerate;
  561. uint16_t samplerate_fixedpoint;
  562. uint32_t volume;
  563. uint32_t starttime;
  564. uint32_t stoptime;
  565. uint32_t soundcheck;
  566. uint32_t playcount;
  567. uint32_t playcount2; // Seems to always be the same as playcount(?!?)
  568. uint32_t lastplayedtime;
  569. uint32_t cdnum;
  570. uint32_t totalcds;
  571. uint32_t userID; // Apple Store User ID
  572. uint32_t addedtime; // iTunes sets this to the UTC time value for when the file was added to the iTunes library
  573. uint32_t bookmarktime;
  574. uint64_t dbid; // 64 bit value that identifies this mhit across iPod databases. iTunes increments this by 1 for each additional song. (previously unk7 and unk8)
  575. uint32_t BPM;
  576. uint32_t app_rating; // The rating set by the application, as opposed to the rating set on the iPod itself
  577. uint8_t checked; // a "checked" song has the value of 0, a non-checked song is 1
  578. uint16_t unk9; // Seems to always be 0xffff...
  579. uint16_t artworkcount; // Number of artwork files attached to this song
  580. uint32_t artworksize; // Size of all artwork files attached to this song, in bytes. (was unk10);
  581. uint32_t unk11;
  582. float samplerate2;
  583. uint32_t releasedtime;
  584. uint32_t unk14;
  585. uint32_t unk15;
  586. uint32_t unk16;
  587. /* --- */
  588. uint32_t skipcount;
  589. uint32_t skippedtime;
  590. uint8_t hasArtwork;
  591. uint8_t skipShuffle;
  592. uint8_t rememberPosition;
  593. uint8_t unk19;
  594. uint64_t dbid2; // same as dbid?
  595. uint8_t lyrics_flag;
  596. uint8_t movie_flag;
  597. uint8_t mark_unplayed;
  598. uint8_t unk20;
  599. uint32_t unk21;
  600. uint32_t pregap;
  601. uint64_t samplecount;
  602. uint32_t unk25;
  603. uint32_t postgap;
  604. uint32_t unk27;
  605. uint32_t mediatype;
  606. uint32_t seasonNumber;
  607. uint32_t episodeNumber;
  608. uint32_t unk31;
  609. uint32_t unk32;
  610. uint32_t unk33;
  611. uint32_t unk34;
  612. uint32_t unk35;
  613. uint32_t unk36;
  614. /* --- */
  615. uint32_t unk37;
  616. uint32_t gaplessData;
  617. uint32_t unk39;
  618. uint16_t albumgapless;
  619. uint16_t trackgapless;
  620. uint32_t unk40;
  621. uint32_t unk41;
  622. uint32_t unk42;
  623. uint32_t unk43;
  624. uint32_t unk44;
  625. uint32_t unk45;
  626. uint32_t unk46;
  627. uint32_t album_id;
  628. uint32_t unk48;
  629. uint32_t unk49;
  630. uint32_t unk50;
  631. uint32_t unk51;
  632. uint32_t unk52;
  633. uint32_t unk53;
  634. uint32_t unk54;
  635. uint32_t unk55;
  636. uint32_t unk56;
  637. /* --- */
  638. // 22 bytes of unknown (we'll just write back zeroes)
  639. uint32_t mhii_link; // TODO: benski> figure this thing out
  640. // 32 more bytes of unknown (we'll just write back zeroes)
  641. /* benski> this is a hack. i'm putting this in here so we can retrieve album art from the transfer thread and add it in the main thread
  642. it doesn't really belong as part of this object, though! */
  643. // protect these members, so stuff doesn't fuck up my cache
  644. protected:
  645. std::vector<iPod_mhod*> mhod;
  646. iPod_mhod * mhodcache[25];
  647. };
  648. // MHLP: playlist container - parent of MHYP, child of MHSD
  649. // Important note: Playlist zero must always be the default playlist, containing every
  650. // track in the DB. To do this, always call "GetDefaultPlaylist()" before you create any
  651. // other playlists, if you start from scratch.
  652. // After you're done adding/deleting tracks in the database, and just before you call
  653. // write(), do the following: GetDefaultPlaylist()->PopulatePlaylist(ptr_to_mhlt);
  654. class iPod_mhlp : public iPodObj
  655. {
  656. public:
  657. iPod_mhlp();
  658. virtual ~iPod_mhlp();
  659. virtual long parse(const uint8_t *data);
  660. virtual long write(unsigned char * data, const unsigned long datasize) {return write(data,datasize,3);}
  661. virtual long write(unsigned char * data, const unsigned long datasize, int index);
  662. const unsigned long GetChildrenCount() const { return mhyp.size(); }
  663. // returns a new playlist for you
  664. iPod_mhyp * AddPlaylist();
  665. // gets a playlist
  666. iPod_mhyp * GetPlaylist(const unsigned long pos) const { return mhyp.at(pos); }
  667. // finds a playlist by its ID
  668. iPod_mhyp * FindPlaylist(const uint64_t playlistID);
  669. // deletes the playlist at a position
  670. bool DeletePlaylist(const unsigned long pos);
  671. // deletes the playlist matching the ID
  672. bool DeletePlaylistByID(const uint64_t playlistID);
  673. // gets the default playlist ( GetPlaylist(0); )
  674. // if there are no playlists yet (empty db), then it creates the default playlist
  675. // and returns a pointer to it
  676. iPod_mhyp * GetDefaultPlaylist();
  677. // erases all playlists, including the default one, so be careful here.
  678. // Set createDefaultPlaylist to create a new, empty default playlist
  679. bool ClearPlaylists(const bool createDefaultPlaylist = false);
  680. // Goes through all playlists and removed any songs that are no longer in the MHLT
  681. void RemoveDeadPlaylistEntries(iPod_mhlt *mhlt);
  682. std::vector<iPod_mhyp*> mhyp;
  683. void SortPlaylists();
  684. private:
  685. bool beingDeleted;
  686. };
  687. int STRCMP_NULLOK(const wchar_t *pa, const wchar_t *pb);
  688. // MHYP: playlist - parent of MHOD or MHIP, child of MHLP
  689. class iPod_mhyp : public iPodObj
  690. {
  691. public:
  692. iPod_mhyp();
  693. virtual ~iPod_mhyp();
  694. virtual long parse(const uint8_t *data);
  695. virtual long write(unsigned char * data, const unsigned long datasize) {return write(data,datasize,3);}
  696. virtual long write(unsigned char * data, const unsigned long datasize, int index);
  697. bool IsSmartPlaylist(void) const { return(isSmartPlaylist); }
  698. // add an entry to the playlist. Creates a new entry, returns the position in the vector
  699. // optionally fills in the songindex for you, with the ID from a track you might have
  700. long AddPlaylistEntry(iPod_mhip * entry, const unsigned long id=0);
  701. // give it a song id, it'll return a position in the playlist
  702. // -1, as always, means not found
  703. // if the same entry is in the playlist multiple times, this only gives back the first one
  704. long FindPlaylistEntry(const unsigned long id) const;
  705. // get an mhip given its position
  706. iPod_mhip * GetPlaylistEntry(const unsigned long pos) const { return mhip.at(pos); }
  707. // deletes an entry from the playlist. Pointers to that entry become invalid
  708. bool DeletePlaylistEntry(const unsigned long pos);
  709. // Removes all playlist entries matching the songindex parameter
  710. bool DeletePlaylistEntryByID(unsigned long songindex);
  711. // clears a playlist of all mhip entries
  712. bool ClearPlaylist();
  713. // populates a playlist to be the same as a track list you pass into it.
  714. // Mainly only useful for building the default playlist after you add/delete tracks
  715. // GetDefaultPlaylist()->PopulatePlaylist(ptr_to_mhlt);
  716. // for example...
  717. long PopulatePlaylist(iPod_mhlt * tracks, int hidden_field=1);
  718. // will add a new string to the playlist
  719. // optional: pass in a type to get an existing string, if there is one,
  720. // or a new one with the type filled in already, if there is not one
  721. iPod_mhod * AddString(const int type=0);
  722. // get an mhod given it's type.. Only really useful with MHOD_TITLE here, until
  723. // smartlists get worked out better
  724. iPod_mhod * FindString(const unsigned long type);
  725. // deletes a string from the playlist
  726. // if more than one string of given type exists, all of that type will be deleted,
  727. // to ensure consistency. Pointers to these strings will be invalid after this.
  728. // ret val is number of strings removed
  729. unsigned long DeleteString(const unsigned long type);
  730. void SetPlaylistTitle(const wchar_t *string);
  731. const unsigned long GetMhodChildrenCount() const { return mhod.size(); }
  732. const unsigned long GetMhipChildrenCount() const { return mhip.size(); }
  733. static void Duplicate(iPod_mhyp *src, iPod_mhyp *dst);
  734. unsigned long hidden;
  735. unsigned long timestamp;
  736. uint64_t playlistID; // ID of the playlist, used in smart playlist rules
  737. unsigned long unk3;
  738. unsigned short numStringMHODs;
  739. unsigned short podcastflag;
  740. unsigned long numLibraryMHODs;
  741. std::vector<iPod_mhod*> mhod;
  742. std::vector<iPod_mhip*> mhip;
  743. struct indexMhit
  744. {
  745. __forceinline bool operator()(indexMhit*& one, indexMhit*& two)
  746. {
  747. #define RETIFNZ(x) { int yy = x; if(yy != 0) return yy < 0; }
  748. //return(STRCMP_NULLOK(one->str.c_str(), two->str.c_str()) < 0 ? true : false);
  749. RETIFNZ(STRCMP_NULLOK(one->str[0],two->str[0]));
  750. RETIFNZ(STRCMP_NULLOK(one->str[1],two->str[1]));
  751. RETIFNZ(STRCMP_NULLOK(one->str[2],two->str[2]));
  752. RETIFNZ(one->track - two->track);
  753. RETIFNZ(STRCMP_NULLOK(one->str[3],two->str[3]));
  754. return true;
  755. #undef RETIFNZ
  756. }
  757. unsigned int index;
  758. const wchar_t *str[4];
  759. int track;
  760. };
  761. iPod_mhlt::mhit_map_t *mhit;
  762. std::vector<uint32_t> mhit_indexer;
  763. bool writeLibraryMHODs;
  764. bool operator()(iPod_mhyp*& one, iPod_mhyp*& two);
  765. protected:
  766. bool isSmartPlaylist;
  767. bool isPopulated;
  768. };
  769. // MHIP: playlist item - child of MHYP
  770. class iPod_mhip : public iPodObj
  771. {
  772. public:
  773. iPod_mhip();
  774. virtual ~iPod_mhip();
  775. virtual long parse(const uint8_t *data);
  776. virtual long write(unsigned char * data, const unsigned long datasize) { return write(data,datasize,0); }
  777. virtual long write(unsigned char * data, const unsigned long datasize, int entrynum);
  778. static void Duplicate(iPod_mhip *src, iPod_mhip *dst);
  779. unsigned long dataobjectcount; // was unk1
  780. unsigned long podcastgroupflag; // was corrid
  781. unsigned long groupid; // was unk2
  782. unsigned long songindex;
  783. unsigned long timestamp;
  784. unsigned long podcastgroupref;
  785. std::vector<iPod_mhod*> mhod;
  786. };
  787. // MHOD: string container item, child of MHIT or MHYP
  788. // MHOD: string container item, child of MHIT or MHYP
  789. class iPod_mhod : public iPodObj
  790. {
  791. public:
  792. iPod_mhod();
  793. virtual ~iPod_mhod();
  794. virtual long parse(const uint8_t *data);
  795. virtual long write(unsigned char * data, const unsigned long datasize);
  796. void SetString(const wchar_t *string);
  797. static void Duplicate(iPod_mhod *src, iPod_mhod *dst);
  798. static bool IsSimpleStringType(const unsigned int type);
  799. uint32_t type;
  800. uint32_t unk1;
  801. uint32_t unk2;
  802. // renamed this from corrid.. all it is is a position in the playlist
  803. // for type 100 mhods that come immediately after mhips.
  804. // for strings, this is the encoded type. 1 == UTF-16, 2 == UTF-8
  805. union
  806. {
  807. uint32_t position;
  808. uint32_t encoding_type;
  809. };
  810. uint32_t length;
  811. uint32_t unk3;
  812. uint32_t unk4;
  813. // string mhods get the string put here, unaltered, still byte reversed
  814. // Use unicode functions to work with this string.
  815. wchar_t *str;
  816. // mhod types 50 and up get the whole thing put here.
  817. // until I can figure out all of these, I won't bother to try to recreate them
  818. // and i'll just copy them back as needed when rewriting the iTunesDB file.
  819. uint8_t * binary;
  820. // stuff for type 50 mhod
  821. uint8_t liveupdate; // "Live Updating" check box
  822. uint8_t checkrules; // "Match X of the following conditions" check box
  823. uint8_t checklimits; // "Limit To..." check box. 1 = checked, 0 = not checked
  824. uint8_t matchcheckedonly; // "Match only checked songs" check box.
  825. uint8_t limitsort_opposite; // Limit Sort rule is reversed (e.g. limitsort == LIMIT_HIGHEST_RATING really means LIMIT_LOWEST_RATING...quite weird...)
  826. uint32_t limittype; // See Limit Types defines above
  827. uint32_t limitsort; // See Limit Sort defines above
  828. uint32_t limitvalue; // Whatever value you type next to "limit type".
  829. // stuff for type 51 mhod
  830. uint32_t unk5; // not sure, probably junk data
  831. uint32_t rules_operator; // "All" (logical AND / value = 0) or "Any" (logical OR / value = 1).
  832. std::vector<SPLRule*> rule;
  833. bool parseSmartPlaylists;
  834. };
  835. // Smart Playlist. A smart playlist doesn't act different from a regular playlist,
  836. // except that it contains a type 50 and type 51 MHOD. But deriving the iPod_slst
  837. // class makes sense, since there are a lot of functions that are only appropriate
  838. // for smart playlists, and it can guarantee that a type 50 and 51 MHOD will always
  839. // be available.
  840. class iPod_slst : public iPod_mhyp
  841. {
  842. public:
  843. enum FieldType
  844. {
  845. ftString,
  846. ftInt,
  847. ftBoolean,
  848. ftDate,
  849. ftPlaylist,
  850. ftUnknown,
  851. ftBinaryAnd,
  852. };
  853. enum ActionType
  854. {
  855. atString,
  856. atInt,
  857. atBoolean,
  858. atDate,
  859. atRange,
  860. atInTheLast,
  861. atPlaylist,
  862. atNone,
  863. atInvalid,
  864. atUnknown,
  865. atBinaryAnd,
  866. };
  867. iPod_slst();
  868. virtual ~iPod_slst();
  869. iPod_mhod* GetPrefs(void) { UpdateMHODPointers(); return(splPref); }
  870. void SetPrefs(const bool liveupdate = true, const bool rules_enabled = true, const bool limits_enabled = false,
  871. const unsigned long limitvalue = 0, const unsigned long limittype = 0, const unsigned long limitsort = 0);
  872. static FieldType GetFieldType(const unsigned long field);
  873. static ActionType GetActionType(const unsigned long field, const unsigned long action);
  874. static uint64_t ConvertDateValueToNum(const uint64_t val) { return(-(int64_t)val); }
  875. static uint64_t ConvertNumToDateValue(const uint64_t val) { return(-(int64_t)val); }
  876. // returns a pointer to the SPLDATA mhod
  877. iPod_mhod* GetRules() { UpdateMHODPointers(); return(splData); }
  878. // get the number of rules in the smart playlist
  879. unsigned long GetRuleCount();
  880. // Returns rule number (0 == first rule, -1 == error)
  881. int AddRule(const unsigned long field,
  882. const unsigned long action,
  883. const wchar_t * string = NULL, // use string for string based rules
  884. const uint64_t value = 0, // use value for single variable rules
  885. const uint64_t from = 0, // use from and to for range based rules
  886. const uint64_t to = 0,
  887. const uint64_t units = 0); // use units for "in the last" based rules
  888. int AddRule(const SPLRule& rule);
  889. void RemoveAllRules(void);
  890. // populates a smart playlist
  891. // Pass in the mhlt with all the songs on the iPod, and it populates the playlist
  892. // given those songs and the current rules
  893. // Return value is number of songs in the resulting playlist.
  894. long PopulateSmartPlaylist(iPod_mhlt * tracks, iPod_mhlp * playlists);
  895. // used in PopulateSmartPlaylist
  896. static bool EvalRule(
  897. SPLRule * r,
  898. iPod_mhit * track,
  899. iPod_mhlt * tracks = NULL, // if you're going to allow playlist type rules
  900. iPod_mhlp * playlists = NULL // these are required to be passed in
  901. );
  902. // Restore default prefs and remove all rules
  903. void Reset(void);
  904. protected:
  905. void UpdateMHODPointers(void);
  906. iPod_mhod *splPref;
  907. iPod_mhod *splData;
  908. };
  909. // MHDP: Play Count class
  910. class iPod_mhdp
  911. {
  912. public:
  913. iPod_mhdp();
  914. ~iPod_mhdp();
  915. unsigned long size_head;
  916. unsigned long entrysize;
  917. const unsigned long GetChildrenCount() const { return children; }
  918. // return value is number of songs or -1 if error.
  919. // you should probably check to make sure the number of songs is the same
  920. // as the number of songs you read in from parsing the iTunesDB
  921. virtual long parse(const uint8_t *data);
  922. // there is no write() function because there is no conceivable need to ever write a
  923. // play counts file.
  924. const PCEntry &GetPlayCount(const unsigned int pos) const { return entry[pos]; }
  925. // playcounts are stored in the Play Counts file, in the same order as the mhits are
  926. // stored in the iTunesDB. So you should apply the changes from these entries to the
  927. // mhits in order and then probably delete the Play Counts file entirely to prevent
  928. // doing it more than once.
  929. PCEntry *entry;
  930. uint32_t children;
  931. };
  932. // MHPO: On-The-Go Playlist class
  933. class iPod_mhpo
  934. {
  935. public:
  936. iPod_mhpo();
  937. virtual ~iPod_mhpo();
  938. unsigned long size_head;
  939. unsigned long unk1;
  940. unsigned long unk2; // this looks like a timestamp, sorta
  941. const unsigned long GetChildrenCount() const { return children; }
  942. virtual long parse(const uint8_t *data);
  943. virtual long write(unsigned char * data, const unsigned long datasize);
  944. // This will create a new playlist from the OTGPlaylist..
  945. // Give it the DB to create the playlist in and from, and a name for the playlist.
  946. // Return value is a pointer to the playlist itself, which will be inside the DB you
  947. // give to it as well.
  948. // Returns NULL on error (can't create the playlist)
  949. iPod_mhyp * CreatePlaylistFromOTG(iPod_mhbd * iPodDB, wchar_t * name);
  950. // OTGPlaylists are stored in the OTGPlaylist file. When iTunes copies them into a
  951. // new playlist, it deletes the file afterwards. I do not know if creating this file
  952. // will make the iPod have an OTGPlaylist after you undock it. I added the write function
  953. // anyway, in case somebody wants to try it. Not much use for it though, IMO.
  954. uint32_t *idList;
  955. uint32_t children;
  956. };
  957. // MQED: EQ Presets holder
  958. class iPod_mqed
  959. {
  960. public:
  961. iPod_mqed();
  962. virtual ~iPod_mqed();
  963. unsigned long size_head;
  964. unsigned long unk1;
  965. unsigned long unk2; // this looks like a timestamp, sorta
  966. const unsigned long GetChildrenCount() const { return eqList.size(); }
  967. virtual long parse(const uint8_t *data);
  968. virtual long write(unsigned char * data, const unsigned long datasize);
  969. std::vector<iPod_pqed*> eqList;
  970. };
  971. // PQED: A single EQ Preset
  972. class iPod_pqed
  973. {
  974. public:
  975. iPod_pqed();
  976. virtual ~iPod_pqed();
  977. unsigned long length; // length of name string
  978. wchar_t * name; // name string
  979. /*
  980. 10 band eq is not exactly what iTunes shows it to be.. It really is these:
  981. 32Hz, 64Hz, 128Hz, 256Hz, 512Hz, 1024Hz, 2048Hz, 4096Hz, 8192Hz, 16384Hz
  982. Also note that although these are longs, The range is only -1200 to +1200. That's dB * 100.
  983. */
  984. signed long preamp; // preamp setting
  985. signed long eq[10]; // iTunes shows 10 bands for EQ presets
  986. signed long short_eq[5]; // This is a 5 band version of the same thing (possibly what the iPod actually uses?)
  987. virtual long parse(const uint8_t *data);
  988. virtual long write(unsigned char * data, const unsigned long datasize);
  989. };
  990. struct iTunesStatsEntry
  991. {
  992. unsigned int GetBookmarkTimeInMilliseconds() { if(bookmarktime == 0xffffff) return(0); return(bookmarktime * 256); }
  993. // These are 3 byte values
  994. unsigned int entry_size;
  995. unsigned int bookmarktime; // In 0.256 seconds units
  996. unsigned int unk1; // Somehow associated with bookmark time
  997. unsigned int unk2;
  998. unsigned int playcount;
  999. unsigned int skippedcount;
  1000. };
  1001. class iTunesStats
  1002. {
  1003. public:
  1004. iTunesStats();
  1005. ~iTunesStats();
  1006. virtual long parse(const uint8_t *data);
  1007. virtual long write(unsigned char * data, const unsigned long datasize);
  1008. const unsigned long GetChildrenCount() const { return children; }
  1009. const iTunesStatsEntry &GetEntry(const unsigned int pos) const { return entry[pos];}
  1010. // This is a 3 byte value
  1011. unsigned int unk1;
  1012. iTunesStatsEntry *entry;
  1013. uint32_t children;
  1014. iPod_mhlt *mhlt;
  1015. };
  1016. class iTunesShuffle
  1017. {
  1018. public:
  1019. iTunesShuffle();
  1020. ~iTunesShuffle();
  1021. virtual long parse(const uint8_t *data);
  1022. virtual long write(unsigned char *data, const unsigned long datasize);
  1023. unsigned int GetChildrenCount() const { return numentries; }
  1024. unsigned int GetEntry(const unsigned int pos) const { return entry[pos]; }
  1025. //void AddEntry(const unsigned int index) { entry.push_back(index); }
  1026. void Randomize();
  1027. void Randomize(const unsigned int numsongs);
  1028. uint32_t *entry;
  1029. uint32_t numentries;
  1030. unsigned int datasize;
  1031. };
  1032. #endif