1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795 |
- #include "iPodDevice.h"
- //#include <assert.h>
- #include "..\..\General\gen_ml/itemlist.h"
- #include "../nu/AutoWide.h"
- #include "../nu/AutoChar.h"
- #include "../Winamp/wa_ipc.h"
- #include <math.h>
- #include "../Agave/Language/api_language.h"
- #include "api.h"
- #include <tataki/bitmap/bitmap.h>
- #include <tataki/canvas/bltcanvas.h>
- #include "iPodSD.h"
- #include <strsafe.h>
- #include <shlwapi.h>
- //#include "../nu/combobox.h"
- // needed to query for replaygain stuff
- static const GUID playbackConfigGroupGUID =
- { 0xb6cb4a7c, 0xa8d0, 0x4c55, { 0x8e, 0x60, 0x9f, 0x7a, 0x7a, 0x23, 0xda, 0xf } };
- extern PMPDevicePlugin plugin;
- extern time_t mactime_to_wintime (const unsigned long mactime);
- extern unsigned long wintime_to_mactime (const __time64_t time);
- extern wchar_t* UTF8_to_UTF16(char *str);
- extern BOOL EjectVolume(TCHAR cDriveLetter);
- extern std::vector<iPodDevice*> iPods;
- static __int64 fileSize(const wchar_t * filename);
- iPodDevice::iPodDevice(char deviceDrive)
- {
- fwid=0;
- info=0;
- artdb=0;
- gapscanner=0;
- transcoder=0;
- image16 = 0;
- image160 = 0;
- drive = deviceDrive;
- driveW = ((int)(drive - 'A')) + L'A';
- transferQueueLength=0;
- db=NULL;
- srand(GetTickCount());
- dirnum = rand() % 20;
-
- {
- wchar_t artwork[] = {driveW,L":\\iPod_Control\\Artwork"};
- _wmkdir(artwork);
- wchar_t device[] = {driveW,L":\\iPod_Control\\Device"};
- _wmkdir(device);
- }
- iPods.push_back(this);
- pmpDeviceLoading load;
- load.dev = this;
- load.UpdateCaption = NULL;
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)&load,PMP_IPC_DEVICELOADING);
- if(load.UpdateCaption)
- {
- load.UpdateCaption(WASABI_API_LNGSTRINGW(IDS_IPOD_LOADING),load.context);
- }
- info = GetiPodInfo(driveW);
-
- // Get the artwork formats that are supported
- if(info && info->numberOfSupportedFormats >0)
- {
- // formats are already available, read from the sysinfo xml
- // just use them
- for (int i=0; i<info->numberOfSupportedFormats; i++)
- {
- thumbs.push_back(&info->supportedArtworkFormats[i]);
- }
- }
- else
- {
- // revert to the static list of supported artwork formats
- const ArtworkFormat* art = GetArtworkFormats(info);
- if(art) for(int i=0; art[i].type != THUMB_INVALID; i++)
- {
- if(art[i].type >= THUMB_COVER_SMALL && art[i].type <= THUMB_COVER_LARGE)
- thumbs.push_back(&art[i]);
- }
- }
- if(!info || parseiTunesDB(thumbs.size()!=0) < 0)
- {
- //iPods.eraseObject(this);
- auto it = std::find(iPods.begin(), iPods.end(), this);
- if (it != iPods.end())
- {
- iPods.erase(it);
- }
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)this,PMP_IPC_DEVICEDISCONNECTED);
- delete this;
- return;
- }
- image16 = info->image16;
- image160 = info->image160;
- db->mhsdplaylists->mhlp->SortPlaylists();
- int n = db->mhsdplaylists->mhlp->GetChildrenCount();
- for(int i=0; i<n; i++)
- playlists.Add(db->mhsdplaylists->mhlp->GetPlaylist(i));
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)this,PMP_IPC_DEVICECONNECTED);
- transcoder = (Transcoder*)SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(WPARAM)this,PMP_IPC_GET_TRANSCODER);
- if(transcoder)
- {
- transcoder->AddAcceptableFormat(mmioFOURCC('M','4','A',' '));
- transcoder->AddAcceptableFormat(L"mp3");
- //transcoder->AddAcceptableFormat(L"wav");
- transcoder->AddAcceptableFormat(L"m4v");
- transcoder->AddAcceptableFormat(L"m4b");
- transcoder->AddAcceptableFormat(L"aa\0\0");
- transcoder->AddAcceptableFormat(L"mp4");
- }
- if (info->fwid)
- {
- fwid = (uint8_t *)malloc(8);
- memcpy(fwid, info->fwid, 8);
- }
- }
- iPodDevice::~iPodDevice() {
- if(gapscanner) SendMessage(gapscanner,WM_CLOSE,0,0);
- if(db) delete db; db=NULL;
- char lockPath[] = {drive, ":\\iPod_Control\\iTunes\\iTunesLock"};
- _unlink(lockPath);
- if(transcoder) SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(WPARAM)transcoder,PMP_IPC_RELEASE_TRANSCODER);
- delete info;
- info=0;
- free(fwid);
- }
- static unsigned char * readFile(char * path, int &len) {
- FILE * f = fopen(path,"rb");
- if(!f) return 0;
- fseek(f,0,2); //seek to end
- int l = ftell(f); //length of file
- unsigned char * data = (unsigned char *)malloc(l);
- if(!data)
- {
- fclose(f);
- return 0;
- }
- fseek(f,0,0);
- if(fread(data,1,l,f) != l) { fclose(f); free(data); return 0; }
- fclose(f);
- len = l;
- return data;
- }
- static unsigned char * readFile(char * path) {
- int l=0;
- return readFile(path,l);
- }
- static HANDLE iTunesLock(char drive) { // returns false for unable to aquire lock.
- char lockPath[] = {drive, ":\\iPod_Control\\iTunes\\iTunesLock"};
- HANDLE h=CreateFileA(lockPath,GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
- if(h == INVALID_HANDLE_VALUE) return h;
- while(!LockFile(h,0,0,0,0)) Sleep(50);
- return h;
- }
- static void iTunesUnlock(HANDLE h) {
- UnlockFile(h,0,0,0,0);
- CloseHandle(h);
- }
- int iPodDevice::parseiTunesDB(bool parseArt) {
- HANDLE hLock = iTunesLock(drive);
- if(hLock == INVALID_HANDLE_VALUE) return -1;
- char dbPath[] = "x:\\iPod_Control\\iTunes\\iTunesDB";
- dbPath[0]=drive;
- unsigned char * data = readFile(dbPath);
- if(data==0) {
- iTunesUnlock(hLock);
- return -1;
- }
- db = new iPod_mhbd;
- int ret = db->parse(data);
- free(data);
- bool changed=false;
- char playcounts[] = "x:\\iPod_Control\\iTunes\\Play Counts";
- playcounts[0]=drive;
- data = readFile(playcounts);
- if(data) {
- iPod_mhdp * mhdp = new iPod_mhdp;
- int l = db->mhsdsongs->mhlt->GetChildrenCount();
- if(mhdp->parse(data) == l) {
- changed=true;
- for(int i=0; i<l; i++) {
- PCEntry p = mhdp->GetPlayCount(i);
- iPod_mhit * mhit = db->mhsdsongs->mhlt->GetTrack(i);
- if(!mhit) continue;
- mhit->bookmarktime = p.bookmarktime;
- mhit->lastplayedtime = p.lastplayedtime;
- mhit->stars = (unsigned char)p.stars;
- mhit->playcount = p.playcount;
- mhit->skipcount = p.skipcount;
- mhit->skippedtime = p.skippedtime;
- }
- }
- delete mhdp;
- free(data);
- }
- _unlink(playcounts);
- db->mhsdplaylists->mhlp->GetPlaylist(0)->mhit = &db->mhsdsongs->mhlt->mhit;
- char otg[] = "x:\\iPod_Control\\iTunes\\OTGPlaylistInfo";
- otg[0]=drive;
- data = readFile(otg);
- if(data) {
- iPod_mhpo * mhpo = new iPod_mhpo;
- mhpo->parse(data);
- mhpo->CreatePlaylistFromOTG(db,L"On The Go");
- changed=true;
- delete mhpo;
- free(data);
- }
- _unlink(otg);
- iTunesUnlock(hLock);
- if(changed) writeiTunesDB();
- if(parseArt) {
- char dbPath[] = "x:\\iPod_Control\\Artwork\\ArtworkDB";
- dbPath[0]=drive;
- int l=0;
- unsigned char * data = readFile(dbPath,l);
- bool createNew=false;
- if(data) {
- artdb = new ArtDB();
- int r = artdb->parse(data,l,driveW);
- if(r<0) {
- delete artdb;
- artdb=NULL;
- }
- free(data);
- } else createNew=true;
- if(createNew) {
- char dir[] = {drive,":\\iPod_Control\\Artwork"};
- CreateDirectoryA(dir,NULL);
- artdb = new ArtDB();
- artdb->makeEmptyDB(driveW);
- }
- }
- return ret;
- }
- extern bool ParseSysInfoXML(wchar_t drive_letter, char * xml, int xmllen);
- static unsigned char *GetFwId(wchar_t drive, unsigned char *fwid)
- {
- char xml[65536] = {0};
- if(!ParseSysInfoXML(drive, xml, sizeof(xml)/sizeof(char))) return NULL;
- char *p = strstr(xml,"<key>FireWireGUID</key>");
- if(!p) return 0;
- p = strstr(p,"<string>");
- if(!p) return 0;
- p += strlen("<string>");
- for(int i=0; i<8 && *p; i++) {
- char num[3]={0,0,0};
- num[0] = *(p++);
- num[1] = *(p++);
- fwid[i] = (uint8_t)strtoul(num,NULL,16);
- }
- return fwid;
- }
- int iPodDevice::writeiTunesDB()
- {
- char dbPath[] = "x:\\iPod_Control\\iTunes\\iTunesDB"; dbPath[0]=drive;
- char dbPathOld[] = "x:\\iPod_Control\\iTunes\\iTunesDB.old_mlpmp"; dbPathOld[0]=drive;
- char dbPathNew[] = "x:\\iPod_Control\\iTunes\\iTunesDB.new_mlpmp"; dbPathNew[0]=drive;
- if(!db) return -1;
- HANDLE hLock = iTunesLock(drive);
- if(hLock == INVALID_HANDLE_VALUE) return -1;
- uint32_t allocate = (uint32_t)fileSize(AutoWide(dbPath));
- int incr = 10000000;
- bool done=false;
- int i=0;
- int ret=0;
- unsigned char * data;
- while(!done)
- {
- if(i++ > 10)
- {
- iTunesUnlock(hLock);
- return -1;
- }
- allocate += incr;
- data = (unsigned char*)malloc(allocate);
- if(!data) return -1; //what else can we do?
- // TODO: i'd like to cut this but it seems to still be causing problems to parse it from XML
- unsigned char fwid[8]={0};
- GetFwId(driveW, fwid);
- #ifdef _DEBUG
- if (memcmp(fwid, this->fwid, 8) || memcmp(fwid, info->fwid, 8))
- {
- DebugBreak();
- }
- #endif
- int len = db->write(data,allocate, fwid);
- if(len > 0) {
- _unlink(dbPathOld);
- _unlink(dbPathNew);
- FILE * f = fopen(dbPathNew,"wb");
- if(!f) {
- iTunesUnlock(hLock);
- return -1;
- }
- fwrite(data,1,len,f);
- fclose(f);
- rename(dbPath,dbPathOld);
- _unlink(dbPath);
- rename(dbPathNew,dbPath);
- done=true;
- ret=len;
- } else free(data);
- }
-
- if(data)
- {
- if (info->shadow_db_version == 1)
- {
- iTunesSD1 sd;
- int l = sd.write(&db->mhsdsongs->mhlt->mhit, data,allocate);
- if(l>0)
- {
- char dbPath[] = "x:\\iPod_Control\\iTunes\\iTunesSD"; dbPath[0]=drive;
- FILE * f = fopen(dbPath,"wb");
- if(f) {
- fwrite(data,1,l,f);
- fclose(f);
- }
- }
- }
- else if (info->shadow_db_version == 2)
- {
- iTunesSD2 sd;
- int l = sd.write(db->mhsdsongs->mhlt, db->mhsdplaylists->mhlp, data,allocate);
- if(l>0)
- {
- char dbPath[] = "x:\\iPod_Control\\iTunes\\iTunesSD"; dbPath[0]=drive;
- FILE * f = fopen(dbPath,"wb");
- if(f) {
- fwrite(data,1,l,f);
- fclose(f);
- }
- }
- }
- }
- if(artdb && data) {
- int l = artdb->write(data,allocate);
- if(l>0) {
- char dbPath[] = "x:\\iPod_Control\\Artwork\\ArtworkDB"; dbPath[0]=drive;
- FILE * f = fopen(dbPath,"wb");
- if(f) {
- fwrite(data,1,l,f);
- fclose(f);
- }
- }
- }
- iTunesUnlock(hLock);
- if(data) free(data);
- return ret;
- }
- __int64 iPodDevice::getDeviceCapacityAvailable() {
- ULARGE_INTEGER tfree={0,}, total={0,}, freeb={0,};
- wchar_t path[4]=L"x:\\";
- path[0]=drive;
- GetDiskFreeSpaceEx(path, &tfree, &total, &freeb);
- return freeb.QuadPart;
- }
- __int64 iPodDevice::getDeviceCapacityTotal() {
- ULARGE_INTEGER tfree={0,}, total={0,}, freeb={0,};
- wchar_t path[4]=L"x:\\";
- path[0]=drive;
- GetDiskFreeSpaceEx(path, &tfree, &total, &freeb);
- return total.QuadPart;
- }
- void iPodDevice::Close()
- {
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)this,PMP_IPC_DEVICEDISCONNECTED);
- //writeiTunesDB();
-
- //iPods.eraseObject(this);
- auto it = std::find(iPods.begin(), iPods.end(), this);
- if (it != iPods.end())
- {
- iPods.erase(it);
- }
- delete this;
- }
- void iPodDevice::Eject()
- {
- //iPods.eraseObject(this);
- auto it = std::find(iPods.begin(), iPods.end(), this);
- if (it != iPods.end())
- {
- iPods.erase(it);
- }
- if(EjectVolume(drive))
- {
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)this,PMP_IPC_DEVICEDISCONNECTED);
- delete this;
- }
- else
- {
- wchar_t titleStr[32] = {0};
- iPods.push_back(this);
- MessageBox(plugin.hwndLibraryParent,WASABI_API_LNGSTRINGW(IDS_FAILED_TO_EJECT_IPOD),
- WASABI_API_LNGSTRINGW_BUF(IDS_ERROR,titleStr,32),0);
- }
- }
- extern int CopyFile(const wchar_t * infile, const wchar_t * outfile, void * callbackContext, void (*callback)(void * callbackContext, wchar_t * status), int * killswitch);
- static __int64 fileSize(const wchar_t * filename)
- {
- WIN32_FIND_DATA f={0};
- HANDLE h = FindFirstFileW(filename,&f);
- if(h == INVALID_HANDLE_VALUE) return -1;
- FindClose(h);
- ULARGE_INTEGER i;
- i.HighPart = f.nFileSizeHigh;
- i.LowPart = f.nFileSizeLow;
- return i.QuadPart;
- }
- void GetFileInfo(const wchar_t * file, const wchar_t * metadata, wchar_t * buf, int len) {
- buf[0]=0;
- extendedFileInfoStructW m = {file,metadata,buf,(size_t)len};
- SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)&m,IPC_GET_EXTENDED_FILE_INFOW);
- }
- __int64 GetFileInfoInt64(wchar_t * file, wchar_t * metadata, BOOL *w=NULL) {
- wchar_t buf[100]=L"";
- GetFileInfo(file,metadata,buf,100);
- if(w && buf[0]==0) {(*w) = 0; return 0;}
- return _wtoi64(buf);
- }
- int GetFileInfoInt(wchar_t * file, wchar_t * metadata, BOOL *w=NULL) {
- wchar_t buf[100]=L"";
- GetFileInfo(file,metadata,buf,100);
- if(w && buf[0]==0) {(*w) = 0; return 0;}
- return _wtoi(buf);
- }
- int iPodDevice::transferTrackToDevice(const itemRecordW *track,void * callbackContext,void (*callback)(void * callbackContext, wchar_t * status),songid_t * songid,int * killswitch)
- {
- bool transcodefile = false;
- wchar_t outfile[2048] = {0};
- wchar_t infile[MAX_PATH] = {0};
- StringCchCopy(infile, MAX_PATH, track->filename);
- bool nocopy=false;
- iPod_mhit * mhit = db->mhsdsongs->mhlt->NewTrack();
- dirnum = (dirnum + 1) % 20;
- // create the output filename and directory
- wchar_t ext[10]=L"";
- const wchar_t *e = wcsrchr(infile,L'.');
- if(e)
- StringCbCopyW(ext, sizeof(ext), e);
- if(transcoder && transcoder->ShouldTranscode(infile)) {
- int r = transcoder->CanTranscode(infile,ext, track->length);
- if(r != 0 && r != -1) transcodefile = true;
- }
- bool video = !_wcsicmp(ext,L".m4v");
- if(!_wcsicmp(ext,L".mp4")) {
- wchar_t buf[100]=L"0";
- extendedFileInfoStructW m = {infile,L"type",buf,100};
- SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)&m,IPC_GET_EXTENDED_FILE_INFOW);
- if(!wcscmp(buf,L"1")) { video=true; wcsncpy(ext,L".m4v",10); }
- else wcsncpy(ext,L".m4a",10);
- }
- // and the location in the ipod naming scheme
- if (infile[0] == drive && infile[1] && infile[1] == L':')
- {
- // file already on the ipod? add it directly
- StringCbCopy(outfile, sizeof(outfile), infile);
- nocopy=true;
- }
- else
- {
- StringCbPrintf(outfile,sizeof(outfile),L"%c:\\iPod_Control\\Music\\F%02d\\",(wchar_t)drive,dirnum);
- CreateDirectory(outfile,NULL);
- StringCbPrintf(outfile,sizeof(outfile),L"%c:\\iPod_Control\\Music\\F%02d\\w%05d%s",(wchar_t)drive,dirnum,mhit->id,ext);
- }
- wchar_t location[2048] = {0};
- StringCbCopy(location, sizeof(location), outfile+2);
- int i=0;
- while(location[i] != 0) { if(location[i]==L'\\') location[i]=L':'; i++; }
- {
- wchar_t buf[100]=L"";
- int which = AGAVE_API_CONFIG->GetUnsigned(playbackConfigGroupGUID, L"replaygain_source", 0);
- extendedFileInfoStructW m = {infile,which?L"replaygain_album_gain":L"replaygain_track_gain",buf,100};
- SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)&m,IPC_GET_EXTENDED_FILE_INFOW);
- if(buf[0]) {
- double gain = _wtof(&buf[buf[0]==L'+'?1:0]);
- mhit->soundcheck = (unsigned long)(1000.0 * pow(10.0,-0.1*gain));
- }
- }
- // fill in the new MHIT (track item) with our metadata
- mhit->AddString(MHOD_TITLE)->SetString(track->title);
- mhit->AddString(MHOD_LOCATION)->SetString(location);
- mhit->AddString(MHOD_ALBUM)->SetString(track->album);
- mhit->AddString(MHOD_ARTIST)->SetString(track->artist);
- mhit->AddString(MHOD_GENRE)->SetString(track->genre);
- mhit->AddString(MHOD_COMMENT)->SetString(track->comment);
- mhit->AddString(MHOD_ALBUMARTIST)->SetString(track->albumartist);
- mhit->AddString(MHOD_COMPOSER)->SetString(track->composer);
- mhit->length = (track->length>0)?track->length*1000:0;
- mhit->year = (track->year>0)?track->year:0;
- mhit->tracknum = (track->track>0)?track->track:0;
- mhit->totaltracks = (track->tracks>0)?track->tracks:0;
- mhit->stars = (unsigned char)(mhit->app_rating = track->rating);
- mhit->playcount = mhit->playcount2 = track->playcount;
- mhit->lastplayedtime = wintime_to_mactime(track->lastplay);
- mhit->lastmodifiedtime = wintime_to_mactime(track->lastupd);
- mhit->compilation = track->albumartist && !_wcsicmp(track->albumartist, L"various artists");
- mhit->samplerate = 44100; // TODO: benski> we could query this from the input plugin, but we'd have to be careful with HE-AAC
- mhit->samplerate2 = 44100.0f;
- mhit->mediatype = video?0x02:0x01;
- mhit->movie_flag = video?1:0;
- mhit->cdnum = (track->disc>0)?track->disc:0;
- mhit->totalcds = (track->discs>0)?track->discs:0;
- mhit->BPM=(track->bpm>0)?track->bpm:0;
- wchar_t *pubdate = getRecordExtendedItem(track,L"podcastpubdate");
- if(pubdate && *pubdate) mhit->releasedtime=wintime_to_mactime(_wtoi(pubdate));
- // copy the file over
- int r;
- if(transcodefile)
- r = transcoder->TranscodeFile(infile,outfile,killswitch,callback,callbackContext);
- else if (!nocopy)
- r = CopyFile(infile,outfile,callbackContext,callback,killswitch);
- else
- {
- if (callback)
- {
- wchar_t langtemp[100] = {0};
- callback(callbackContext, WASABI_API_LNGSTRINGW_BUF(IDS_DONE, langtemp, 100));
- }
- r=0;
- }
- if(r == 0)
- {
- StringCbCopyW(ext, sizeof(ext), wcsrchr(outfile,L'.'));
- if (!_wcsicmp(ext, L".m4a") || !_wcsicmp(ext, L".mp4"))
- {
- mhit->vbr = 0;
- mhit->type = 0;
- mhit->unk14 = 51;
- mhit->filetype = FILETYPE_M4A;
- }
- else if (!_wcsicmp(ext, L".mp3"))
- {
- mhit->type = 1;
- mhit->unk27 = 1;
- mhit->unk14 = 12;
- mhit->AddString(MHOD_FILETYPE)->SetString(L"MPEG audio file");
- mhit->filetype = FILETYPE_MP3;
- }
- else if (!_wcsicmp(ext, L".wav"))
- {
- mhit->filetype = FILETYPE_WAV;
- }
- mhit->samplecount = GetFileInfoInt64(outfile,L"numsamples");
- mhit->pregap = (unsigned long)GetFileInfoInt64(outfile,L"pregap");
- mhit->postgap = (unsigned long)GetFileInfoInt64(outfile,L"postgap");
- mhit->gaplessData = (unsigned long)GetFileInfoInt64(outfile,L"endoffset");
- mhit->trackgapless = 1;
- mhit->size = (unsigned long)fileSize(outfile);
- if (!transcodefile && track->bitrate > 0)
- mhit->bitrate = track->bitrate;
- else
- {
- mhit->bitrate = (unsigned long)GetFileInfoInt64(outfile,L"bitrate");
- if (!mhit->bitrate)
- {
- if (track->length > 0)
- mhit->bitrate = (mhit->size / track->length)/125;
- else
- mhit->bitrate = 128;
- }
- }
- *songid = (songid_t)mhit;
- }
- else
- {
- DeleteFileW(outfile);
- delete mhit;
- }
- return r;
- }
- int iPodDevice::trackAddedToTransferQueue(const itemRecordW *track) {
- __int64 l;
- if(transcoder && transcoder->ShouldTranscode(track->filename)) {
- int k = transcoder->CanTranscode(track->filename, 0, track->length);
- if(k == -1) return -2;
- if(k == 0) l = (__int64)fileSize(track->filename);
- else l = (__int64)k;
- } else {
- wchar_t * ext = wcsrchr(track->filename,L'.');
- if(!ext) return -2;
- if(_wcsicmp(ext,L".mp3") && _wcsicmp(ext,L".wav") && _wcsicmp(ext,L".m4a") &&
- _wcsicmp(ext,L".m4b") && _wcsicmp(ext,L".aa") && _wcsicmp(ext,L".m4v") &&
- _wcsicmp(ext,L".mp4")) return -2;
- l = (__int64)fileSize(track->filename);
- }
- __int64 avail = getDeviceCapacityAvailable();
- __int64 cmp = transferQueueLength;
- cmp += l;
- cmp += (__int64)3000000;
- if(cmp > avail)
- return -1;
- else {
- transferQueueLength += l;
- return 0;
- }
- }
- void iPodDevice::trackRemovedFromTransferQueue(const itemRecordW *track) {
- __int64 l = (__int64)fileSize(track->filename);
- if(transcoder && transcoder->ShouldTranscode(track->filename)) {
- int k = transcoder->CanTranscode(track->filename, 0, track->length);
- if(k != -1 && k != 0) l = (__int64)k;
- }
- transferQueueLength -= l;
- }
- __int64 iPodDevice::getTrackSizeOnDevice(const itemRecordW *track) {
- if(transcoder && transcoder->ShouldTranscode(track->filename)) {
- int k = transcoder->CanTranscode(track->filename, 0, track->length);
- if(k != -1 && k != 0) return k;
- }
- wchar_t * ext = wcsrchr(track->filename,'.');
- if(!ext) return 0;
- if(_wcsicmp(ext,L".mp3") && _wcsicmp(ext,L".wav") && _wcsicmp(ext,L".m4a") &&
- _wcsicmp(ext,L".m4b") && _wcsicmp(ext,L".aa") && _wcsicmp(ext,L".m4v") &&
- _wcsicmp(ext,L"mp4")) return 0;
- return fileSize(track->filename);
- }
- void iPodDevice::deleteTrack(songid_t songid) {
- iPod_mhit * mhit = (iPod_mhit *)songid;
- iPod_mhod * mhod = mhit->FindString(MHOD_LOCATION);
- if(!mhod) return;
- wchar_t * t = mhod->str;
- // change ':' to '\\;
- wchar_t * p = t;
- int l = wcslen(t);
- for(int j=0; j<l; j++) if(*(p++)==L':') *(p-1)=L'\\';
- // add drive onto front
- wchar_t file[2048] = L"x:\\";
- file[0] = driveW;
- wcscat(file,t);
- //check this file isn't playing...
- wchar_t* curPlaying = (wchar_t*)SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_GET_PLAYING_FILENAME);
- if(curPlaying && !_wcsicmp(curPlaying,file)) SendMessage(plugin.hwndWinampParent,WM_COMMAND,40047,0); //stop
- //delete :)
- // benski> we might have a file that has been deleted from the disk but not the DB
- if(!DeleteFileW(file) // check for file failure
- && GetFileAttributes(file) != INVALID_FILE_ATTRIBUTES) // but only fail if the file actually exists
- return;
- setArt(songid,NULL,0,0);
- l = playlists.GetSize();
- for(int i=0; i<l; i++) {
- iPod_mhyp * mhyp = ((iPod_mhyp*)playlists.Get(i)); //->DeletePlaylistEntryByID(mhit->id);
- for(unsigned int j=0; j<mhyp->GetMhipChildrenCount(); j++) {
- if(mhyp->GetPlaylistEntry(j)->songindex == mhit->id) mhyp->DeletePlaylistEntry(j);
- }
- }
- db->mhsdsongs->mhlt->DeleteTrackByID(mhit->id);
- }
- int iPodDevice::getPlaylistCount() {
- return playlists.GetSize();
- }
- static void readStringMHOD(iPod_mhod * mhod, wchar_t * buf, int len) {
- if(mhod) lstrcpyn(buf,mhod->str,len);
- else buf[0]=0;
- }
- static void setStringMHOD(iPod_mhod * mhod, const wchar_t *buf) {
- mhod->SetString(buf);
- }
- void iPodDevice::getPlaylistName(int playlistnumber, wchar_t * buf, int len) {
- iPod_mhod * name = ((iPod_mhyp*)playlists.Get(playlistnumber))->FindString(MHOD_TITLE);
- readStringMHOD(name,buf,len);
- }
- int iPodDevice::getPlaylistLength(int playlistnumber) {
- return ((iPod_mhyp*)playlists.Get(playlistnumber))->GetMhipChildrenCount();
- }
- static iPod_mhit blank;
- songid_t iPodDevice::getPlaylistTrack(int playlistnumber,int songnum) {
- int idx = ((iPod_mhyp*)playlists.Get(playlistnumber))->GetPlaylistEntry(songnum)->songindex;
- iPod_mhlt::mhit_map_t::const_iterator f = db->mhsdsongs->mhlt->mhit.find(idx);
- if(f != db->mhsdsongs->mhlt->mhit.end() && idx) return (songid_t)f->second;
- else {
- iPod_mhip* m = ((iPod_mhyp*)playlists.Get(playlistnumber))->GetPlaylistEntry(songnum);
- blank.DeleteString(4);
- if(m->podcastgroupflag && m->mhod[0]) {
- iPod_mhod * mh = blank.AddString(4);
- mh->SetString(m->mhod[0]->str);
- }
- return (songid_t)␣
- }
- }
- void iPodDevice::setPlaylistName(int playlistnumber, const wchar_t *buf) {
- iPod_mhod * name = ((iPod_mhyp*)playlists.Get(playlistnumber))->FindString(MHOD_TITLE);
- if(!name) name = ((iPod_mhyp*)playlists.Get(playlistnumber))->AddString(MHOD_TITLE);
- setStringMHOD(name,buf);
- if(playlistnumber == 0) {
- wchar_t volumename[12] = {0};
- const wchar_t * p = buf;
- for(int i=0; i<11;) {
- if(*p!=L' ' && *p!=L'\t') volumename[i++]=*p;
- if(*(p++)==0) break;
- }
- volumename[11]=0;
- char root[] = {drive,":\\"};
- SetVolumeLabel(AutoWide(root),volumename);
- }
- }
- void iPodDevice::playlistSwapItems(int playlistnumber, int posA, int posB) {
- iPod_mhyp * p = ((iPod_mhyp*)playlists.Get(playlistnumber));
- iPod_mhip * a = p->mhip.at(posA);
- iPod_mhip * b = p->mhip.at(posB);
- if(a && b) {
- p->mhip[posA] = b;
- p->mhip[posB] = a;
- }
- }
- static iPod_mhyp * sortpl;
- static int sortby;
- static iPod_mhbd * sortdb;
- #define CMPFIELDS(x) { int v=0; iPod_mhod * am = a->FindString(x); iPod_mhod * bm = b->FindString(x); if(am && bm) v = lstrcmpi(am->str,bm->str); else if(am != bm) v = am==NULL?-1:1; if(v!=0) return v<0; }
- #define CMPINTFIELDS(x,y) { int v = x-y; if(v!=0) return v<0; }
- struct PlaylistItemSort {
- bool operator()(iPod_mhip*& ap,iPod_mhip*& bp) {
- int use_by = sortby;
- iPod_mhit * a = sortdb->mhsdsongs->mhlt->mhit.find(ap->songindex)->second;
- iPod_mhit * b = sortdb->mhsdsongs->mhlt->mhit.find(bp->songindex)->second;
- // this might be too slow, but it'd be nice
- int x;
- for (x = 0; x < 5; x ++)
- {
- if (use_by == SORTBY_TITLE) // title -> artist -> album -> disc -> track
- {
- CMPFIELDS(MHOD_TITLE);
- use_by=SORTBY_ARTIST;
- }
- else if (use_by == SORTBY_ARTIST) // artist -> album -> disc -> track -> title
- {
- CMPFIELDS(MHOD_ARTIST);
- use_by=SORTBY_ALBUM;
- }
- else if (use_by == SORTBY_ALBUM) // album -> disc -> track -> title -> artist
- {
- CMPFIELDS(MHOD_ALBUM);
- use_by=SORTBY_DISCNUM;
- }
- else if (use_by == SORTBY_DISCNUM) // disc -> track -> title -> artist -> album
- {
- CMPINTFIELDS(a->cdnum,b->cdnum);
- use_by=SORTBY_TRACKNUM;
- }
- else if (use_by == SORTBY_TRACKNUM) // track -> title -> artist -> album -> disc
- {
- CMPINTFIELDS(a->tracknum,b->tracknum);
- use_by=SORTBY_TITLE;
- }
- else if (use_by == SORTBY_GENRE) // genre -> artist -> album -> disc -> track
- {
- CMPFIELDS(MHOD_GENRE);
- use_by=SORTBY_ARTIST;
- }
- else if (use_by == SORTBY_PLAYCOUNT) // size -> artist -> album -> disc -> track
- {
- CMPINTFIELDS(a->playcount,b->playcount);
- use_by=SORTBY_ARTIST;
- }
- else if (use_by == SORTBY_RATING) // size -> artist -> album -> disc -> track
- {
- CMPINTFIELDS(a->stars,b->stars);
- use_by=SORTBY_ARTIST;
- }
- else if (use_by == SORTBY_LASTPLAYED)
- {
- double t = difftime(a->lastplayedtime,b->lastplayedtime);
- if(t != 0) return t>0;
- use_by=SORTBY_ARTIST;
- }
- else break; // no sort order?
- }
- return false;
- }
- };
- #undef CMPFIELDS
- #undef CMPINTFIELDS
- void iPodDevice::sortPlaylist(int playlistnumber, int sortby0) {
- sortpl = ((iPod_mhyp*)playlists.Get(playlistnumber));
- sortby = sortby0;
- sortdb = db;
- std::sort(sortpl->mhip.begin(),sortpl->mhip.end(),PlaylistItemSort());
- }
- void iPodDevice::addTrackToPlaylist(int playlistnumber, songid_t songid)
- {
- iPod_mhit *mhit = (iPod_mhit *)songid;
- if (playlistnumber == 0)
- {
- db->mhsdsongs->mhlt->AddTrack(mhit);
- db->mhsdplaylists->mhlp->GetDefaultPlaylist()->AddPlaylistEntry(NULL, mhit->id);
- }
- else
- {
- ((iPod_mhyp*)playlists.Get(playlistnumber))->AddPlaylistEntry(NULL, mhit->id);
- }
- }
- void iPodDevice::removeTrackFromPlaylist(int playlistnumber, int songnum) {
- ((iPod_mhyp*)playlists.Get(playlistnumber))->DeletePlaylistEntry(songnum);
- }
- void iPodDevice::deletePlaylist(int playlistnumber) {
- iPod_mhyp* p = ((iPod_mhyp*)playlists.Get(playlistnumber));
- playlists.Del(playlistnumber);
- db->mhsdplaylists->mhlp->DeletePlaylistByID(p->playlistID);
- }
- int iPodDevice::newPlaylist(const wchar_t *name) {
- iPod_mhyp * p = db->mhsdplaylists->mhlp->AddPlaylist();
- playlists.Add(p);
- int ret = db->mhsdplaylists->mhlp->GetChildrenCount() - 1;
- setPlaylistName(ret,name);
- db->mhsdplaylists->mhlp->SortPlaylists();
- return ret;
- }
- void iPodDevice::getTrackArtist(songid_t songid, wchar_t * buf, int len) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_ARTIST);
- readStringMHOD(mhod,buf,len);
- }
- void iPodDevice::getTrackAlbum(songid_t songid, wchar_t * buf, int len) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_ALBUM);
- readStringMHOD(mhod,buf,len);
- }
- void iPodDevice::getTrackTitle(songid_t songid, wchar_t * buf, int len) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_TITLE);
- readStringMHOD(mhod,buf,len);
- }
- void iPodDevice::getTrackGenre(songid_t songid, wchar_t * buf, int len) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_GENRE);
- readStringMHOD(mhod,buf,len);
- }
- int iPodDevice::getTrackTrackNum(songid_t songid) {
- return ((iPod_mhit *)songid)->tracknum;
- }
- int iPodDevice::getTrackDiscNum(songid_t songid) {
- return ((iPod_mhit *)songid)->cdnum;
- }
- int iPodDevice::getTrackYear(songid_t songid) {
- return (int)(((iPod_mhit *)songid)->year);
- }
- __int64 iPodDevice::getTrackSize(songid_t songid) {
- return ((iPod_mhit *)songid)->size;
- }
- int iPodDevice::getTrackLength(songid_t songid) {
- return ((iPod_mhit *)songid)->length;
- }
- int iPodDevice::getTrackBitrate(songid_t songid) {
- return ((iPod_mhit *)songid)->bitrate;
- }
- int iPodDevice::getTrackPlayCount(songid_t songid) {
- return ((iPod_mhit *)songid)->playcount;
- }
- int iPodDevice::getTrackRating(songid_t songid) {
- return ((iPod_mhit *)songid)->stars / 20;
- }
- __time64_t iPodDevice::getTrackLastPlayed(songid_t songid) {
- return mactime_to_wintime(((iPod_mhit *)songid)->lastplayedtime);
- }
- __time64_t iPodDevice::getTrackLastUpdated(songid_t songid) {
- return mactime_to_wintime(((iPod_mhit *)songid)->lastmodifiedtime);
- }
- void iPodDevice::getTrackAlbumArtist(songid_t songid, wchar_t * buf, int len) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_ALBUMARTIST);
- readStringMHOD(mhod,buf,len);
- if(!mhod) getTrackArtist(songid,buf,len);
- }
- void iPodDevice::getTrackComposer(songid_t songid, wchar_t * buf, int len) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_COMPOSER);
- readStringMHOD(mhod,buf,len);
- }
- int iPodDevice::getTrackType(songid_t songid) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_LOCATION);
- if(!mhod) return 0;
- wchar_t * ext = wcsrchr(mhod->str,L'.');
- if(!ext) return 0;
- if(!_wcsicmp(ext,L".m4v")) return 1;
- return 0;
- }
- void iPodDevice::getTrackExtraInfo(songid_t songid, const wchar_t *field, wchar_t * buf, int len) {
- if(!wcscmp(field,FIELD_EXTENSION)) {
- wchar_t buf2[1024]=L"";
- getFilename(buf2,1024,songid);
- wchar_t * ext = wcsrchr(buf2,L'.');
- if(ext) { ext++; lstrcpyn(buf,ext,len); }
- }
- }
- void iPodDevice::setTrackArtist(songid_t songid, const wchar_t *value) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_ARTIST);
- if(!mhod) mhod = ((iPod_mhit *)songid)->AddString(MHOD_ARTIST);
- setStringMHOD(mhod,value);
- }
- void iPodDevice::setTrackAlbum(songid_t songid, const wchar_t *value) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_ALBUM);
- if(!mhod) mhod = ((iPod_mhit *)songid)->AddString(MHOD_ALBUM);
- setStringMHOD(mhod,value);
- }
- void iPodDevice::setTrackTitle(songid_t songid, const wchar_t *value) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_TITLE);
- if(!mhod) mhod = ((iPod_mhit *)songid)->AddString(MHOD_TITLE);
- setStringMHOD(mhod,value);
- }
- void iPodDevice::setTrackTrackNum(songid_t songid, int value) {
- ((iPod_mhit *)songid)->tracknum = value;
- }
- void iPodDevice::setTrackDiscNum(songid_t songid, int value) {
- ((iPod_mhit *)songid)->cdnum = value;
- }
- void iPodDevice::setTrackGenre(songid_t songid, const wchar_t *value) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_GENRE);
- if(!mhod) mhod = ((iPod_mhit *)songid)->AddString(MHOD_GENRE);
- setStringMHOD(mhod,value);
- }
- void iPodDevice::setTrackYear(songid_t songid, int value) {
- ((iPod_mhit *)songid)->year = (unsigned long)value;
- }
- void iPodDevice::setTrackPlayCount(songid_t songid, int value) {
- ((iPod_mhit *)songid)->playcount = value;
- }
- void iPodDevice::setTrackRating(songid_t songid, int value) {
- ((iPod_mhit *)songid)->app_rating = ((iPod_mhit *)songid)->stars = value*20;
- }
- void iPodDevice::setTrackLastPlayed(songid_t songid, __time64_t value) {
- ((iPod_mhit *)songid)->lastplayedtime = wintime_to_mactime(value);
- }
- void iPodDevice::setTrackLastUpdated(songid_t songid, __time64_t value) {
- ((iPod_mhit *)songid)->lastmodifiedtime = wintime_to_mactime(value);
- }
- void iPodDevice::setTrackAlbumArtist(songid_t songid, const wchar_t *value) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_ALBUMARTIST);
- if(!mhod) mhod = ((iPod_mhit *)songid)->AddString(MHOD_ALBUMARTIST);
- setStringMHOD(mhod,value);
- }
- void iPodDevice::setTrackComposer(songid_t songid, const wchar_t *value) {
- iPod_mhod * mhod = ((iPod_mhit *)songid)->FindString(MHOD_COMPOSER);
- if(!mhod) mhod = ((iPod_mhit *)songid)->AddString(MHOD_COMPOSER);
- setStringMHOD(mhod,value);
- }
- void iPodDevice::getFilename(char * buf, int len, songid_t song) {
- iPod_mhod * mhod = ((iPod_mhit *)song)->FindString(MHOD_LOCATION);
- if(!mhod) {buf[0]=0; return;}
- char * filename = UTF16_to_char(mhod->str,mhod->length);
- char * p = filename;
- buf[0] = drive;
- buf[1] = ':';
- int j=2;
- while(p && *p && j < len-1) { if(*p==':') buf[j]='\\'; else buf[j]=*p; p++; j++; }
- buf[j]=0;
- free(filename);
- }
- void iPodDevice::getFilename(wchar_t * buf, int len, songid_t song) {
- iPod_mhod * mhod = ((iPod_mhit *)song)->FindString(MHOD_LOCATION);
- if(!mhod) {buf[0]=0; return;}
- wchar_t * filename = mhod->str;
- wchar_t * p = filename;
- buf[0] = drive;
- buf[1] = L':';
- int j=2;
- while(p && *p && j < len-1) { if(*p==L':') buf[j]=L'\\'; else buf[j]=*p; p++; j++; }
- buf[j]=0;
- }
- typedef struct { songid_t song; Device * dev; const wchar_t * filename; } tagItem;
- static wchar_t * tagFunc(const wchar_t * tag, void * p) { //return 0 if not found, -1 for empty tag
- tagItem * s = (tagItem *)p;
- int len = 2048;
- wchar_t * buf = (wchar_t *)malloc(sizeof(wchar_t)*len);
- if (!_wcsicmp(tag, L"artist")) s->dev->getTrackArtist(s->song,buf,len);
- else if (!_wcsicmp(tag, L"album")) s->dev->getTrackAlbum(s->song,buf,len);
- else if (!_wcsicmp(tag, L"title")) s->dev->getTrackTitle(s->song,buf,len);
- else if (!_wcsicmp(tag, L"genre")) s->dev->getTrackGenre(s->song,buf,len);
- else if (!_wcsicmp(tag, L"year"))
- {
- int year = s->dev->getTrackYear(s->song);
- if (year>0)
- StringCchPrintf(buf,len,L"%d",year);
- else
- buf[0]=0;
- }
- else if (!_wcsicmp(tag, L"tracknumber") || !_wcsicmp(tag, L"track"))
- {
- int track = s->dev->getTrackTrackNum(s->song);
- if (track>0)
- StringCchPrintf(buf,len,L"%d",track);
- else
- buf[0]=0;
- }
- else if (!_wcsicmp(tag, L"discnumber"))
- {
- int disc = s->dev->getTrackDiscNum(s->song);
- if (disc>0)
- StringCchPrintf(buf,len,L"%d",disc);
- else
- buf[0]=0;
- }
- else if (!_wcsicmp(tag, L"bitrate"))
- {
- int bitrate = s->dev->getTrackBitrate(s->song);
- if (bitrate>0)
- StringCchPrintf(buf,len,L"%d",bitrate);
- else
- buf[0]=0;
- }
- else if (!_wcsicmp(tag, L"filename")) lstrcpyn(buf,s->filename,len);
- else buf[0]=0;
- return buf;
- }
- static void tagFreeFunc(wchar_t *tag, void *p) { if(tag) free(tag); }
- void getTitle(Device * dev, songid_t song, const wchar_t * filename, wchar_t * buf, int len) {
- buf[0]=0; buf[len-1]=0;
- tagItem item = {song,dev,filename};
- waFormatTitleExtended fmt={filename,0,NULL,&item,buf,len,tagFunc,tagFreeFunc};
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&fmt, IPC_FORMAT_TITLE_EXTENDED);
- }
- bool iPodDevice::playTracks(songid_t * songidList, int listLength, int startPlaybackAt, bool enqueue) {
- //char buf[2048]="";
- wchar_t wbuf[2048]=L"";
- if(!enqueue) { //clear playlist
- SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_DELETE);
- /*int l=SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_PE_GETINDEXTOTAL);
- while(l>=0) SendMessage(plugin.hwndWinampParent,WM_WA_IPC,--l,IPC_PE_DELETEINDEX);*/
- }
- for(int i=0; i<listLength; i++) {
- getFilename(wbuf,2048,songidList[i]);
- //strcpy(buf,AutoChar(wbuf));
- wchar_t title[2048] = {0};
- getTitle(this,songidList[i],wbuf,title,2048);
- /*enqueueFileWithMetaStruct s={buf,strdup(AutoChar(title)),getTrackLength(songidList[i])/1000};
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_PLAYFILE);
- free((void*)s.title);*/
- enqueueFileWithMetaStructW s={wbuf,_wcsdup(title),PathFindExtensionW(wbuf),getTrackLength(songidList[i]) / 1000};
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_PLAYFILEW);
- free((void*)s.title);
- }
- if(!enqueue) { //play item startPlaybackAt
- SendMessage(plugin.hwndWinampParent,WM_WA_IPC,startPlaybackAt,IPC_SETPLAYLISTPOS);
- SendMessage(plugin.hwndWinampParent,WM_COMMAND,40047,0); //stop
- SendMessage(plugin.hwndWinampParent,WM_COMMAND,40045,0); //play
- }
- return true;
- }
- int iPodDevice::copyToHardDrive(songid_t song, // the song to copy
- wchar_t * path, // path to copy to, in the form "c:\directory\song". The directory will already be created, you must append ".mp3" or whatever to this string! (there is space for at least 10 new characters).
- void * callbackContext, //pass this to the callback
- void (*callback)(void * callbackContext, wchar_t * status), // call this every so often so the GUI can be updated. Including when finished!
- int * killswitch // if this gets set to anything other than zero, the transfer has been cancelled by the user
- ) // -1 for failed/not supported. 0 for success.
- {
- wchar_t fn[2048] = {0}; // song filename on ipod
- getFilename(fn,2048,song);
- wchar_t * ext = wcsrchr(fn,L'.');
- if(!ext) { callback(callbackContext,WASABI_API_LNGSTRINGW(IDS_INVALID_TRACK)); return -1; }
- wcscat(path,ext);
- return CopyFile(fn,path,callbackContext,callback,killswitch);
- }
- // art functions
- static void fileputinhole(const wchar_t* file, unsigned int pos, int len, void* newdata) {
- __int64 fs = fileSize(file);
- int open_flags = OPEN_EXISTING;
- if(fs <= 0) open_flags = CREATE_NEW;
- HANDLE hw = CreateFile(file,GENERIC_WRITE | GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,open_flags,0,NULL);
- if(hw == INVALID_HANDLE_VALUE) return;
- SetFilePointer(hw,pos,NULL,FILE_BEGIN);
- DWORD written=0;
- WriteFile(hw,newdata,len,&written,NULL);
- CloseHandle(hw);
- }
- ArtDataObject * makeThumbMetadata(const ArtworkFormat * thumb, wchar_t drive, Image * image, ArtDB *artdb) {
- wchar_t file[MAX_PATH] = {0};
- wsprintfW(file,L"%c:\\iPod_Control\\Artwork\\F%04d_1.ithmb",drive,thumb->correlation_id);
- bool found=false;
- ArtFile *f=NULL;
- for(size_t i=0; i < artdb->fileListDS->fileList->files.size(); i++) {
- f = artdb->fileListDS->fileList->files[i];
- if(f->corrid == thumb->correlation_id) { found=true; break; }
- }
- if(!found) {
- f = new ArtFile;
- f->corrid = thumb->correlation_id;
- f->imagesize = image->get16BitSize(thumb->row_align, thumb->image_align);
- artdb->fileListDS->fileList->files.push_back(f);
- f->file = _wcsdup(file);
- }
- ArtDataObject * ms = new ArtDataObject;
- ms->type=2;
- ms->image = new ArtImageName;
- ms->image->corrid = thumb->correlation_id;
- ms->image->imgw = thumb->width;
- ms->image->imgh = thumb->height;
- ms->image->imagesize = image->get16BitSize(thumb->row_align, thumb->image_align);
- //__int64 fs = fileSize(file);
- //ms->image->ithmboffset = fs>0?fs:0;
- ms->image->ithmboffset = f->getNextHole(ms->image->imagesize);
- wchar_t buf[100] = {0};
- StringCchPrintf(buf,100,L":F%04d_1.ithmb",thumb->correlation_id);
- ms->image->filename = new ArtDataObject;
- ms->image->filename->type=3;
- ms->image->filename->SetString(buf);
- unsigned short *data = (unsigned short *)calloc(ms->image->imagesize,1);
- image->exportToRGB565((RGB565*)data, thumb->format, thumb->row_align, thumb->image_align);
- fileputinhole(file,ms->image->ithmboffset,ms->image->imagesize,data);
- //writeDataToThumb(file,data,thumb->width * thumb->height);
- free(data);
- f->images.push_back(new ArtFileImage(ms->image->ithmboffset,ms->image->imagesize,1));
- f->sortImages();
- return ms;
- }
- void GetTempFilePath(wchar_t *path) {
- wchar_t dir[MAX_PATH] = {0};
- GetTempPath(MAX_PATH,dir);
- GetTempFileName(dir,L"ml_pmp",0,path);
- }
- static void fileclosehole(const wchar_t* file, unsigned int pos, int len) {
- HANDLE hw = CreateFile(file,GENERIC_WRITE | GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
- if(hw == INVALID_HANDLE_VALUE) return;
- HANDLE hr = CreateFile(file,GENERIC_WRITE | GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
- if(hr == INVALID_HANDLE_VALUE) { CloseHandle(hw); return; }
- SetFilePointer(hw,pos,NULL,FILE_BEGIN);
- SetFilePointer(hr,pos+len,NULL,FILE_BEGIN);
- DWORD fs = GetFileSize(hw,NULL);
- if(pos == 0 && len == fs) { CloseHandle(hr); CloseHandle(hw); _wunlink(file); return; }
- unsigned int p = pos;
- while(1) {
- BYTE buf[65536] = {0};
- DWORD read=0;
- ReadFile(hr,buf,sizeof(buf),&read,NULL);
- if(!read) break;
- DWORD written=0;
- WriteFile(hw,buf,read,&written,NULL);
- if(!written) break;
- p+=read;
- if(p>=fs) break;
- }
- SetFilePointer(hw,fs - len,NULL,FILE_BEGIN);
- SetEndOfFile(hw);
- CloseHandle(hr);
- CloseHandle(hw);
- }
- static bool replaceart(songid_t songid, wchar_t driveW, ArtDB *artdb, std::vector<const ArtworkFormat*> * thumbs, std::vector<Image*> * images) {
- //return false;
- __int64 dbid = ((iPod_mhit*)songid)->dbid;
- int done=0;
- ArtImageList::ArtImageMapIterator art = artdb->imageListDS->imageList->images.find(dbid);
- if(art != artdb->imageListDS->imageList->images.end() && art->second) { // replace old art
- for(size_t i=0; i!=art->second->dataobjs.size(); i++) if(art->second->dataobjs[i]->image) {
- ArtImageName * in = art->second->dataobjs[i]->image;
- for(size_t j=0; j!=thumbs->size(); j++)
- {
- if(in->corrid == thumbs->at(j)->correlation_id) {
- wchar_t file[MAX_PATH] = {0};
- wsprintfW(file,L"%c:\\iPod_Control\\Artwork\\F%04d_1.ithmb",driveW,in->corrid);
- int size = images->at(j)->get16BitSize(thumbs->at(j)->row_align, thumbs->at(j)->image_align);
- if(size == in->imagesize) {
- unsigned short *data = (unsigned short *)malloc(size);
- images->at(j)->exportToRGB565((RGB565*)data, thumbs->at(j)->format, thumbs->at(j)->row_align, thumbs->at(j)->image_align);
- fileputinhole(file,in->ithmboffset,in->imagesize,data);
- free(data);
- done++;
- }
- }
- }
- }
- }
- return (done == thumbs->size());
- }
- void iPodDevice::setArt(songid_t songid, void *bits, int w, int h) { //buf is in format ARGB32*
- if(!artdb || !thumbs.size()) return; // art not supported
- iPod_mhit * mhit = (iPod_mhit *)songid;
- if(bits == NULL || w == 0 || h == 0) { // remove art
- ArtImageList::ArtImageMapIterator arti = artdb->imageListDS->imageList->images.find(mhit->dbid);
- if(arti == artdb->imageListDS->imageList->images.end() || !arti->second) return;
- ArtImage * art = arti->second;
- for(auto j = art->dataobjs.begin(); j!=art->dataobjs.end(); j++) {
- ArtImageName *n = (*j)->image;
- if(n)
- {
- ArtFile * f = artdb->fileListDS->fileList->getFile(n->corrid);
- if(f)
- {
- bool found=false;
- for(size_t i=0; i!=f->images.size(); i++)
- {
- if(!found && f->images[i]->start == n->ithmboffset && --f->images[i]->refcount==0)
- {
- delete f->images[i];
- f->images.erase(f->images.begin() + i);
- i--;
- found=true;
- }
- }
- }
- }
- }
- mhit->mhii_link = 0;
- mhit->artworkcount = 0;
- mhit->hasArtwork = 0;
- artdb->imageListDS->imageList->images.erase(arti);
- delete art;
- } else {
- //setArt(songid,NULL,0,0); // clear old art first
- HQSkinBitmap albumart((ARGB32*)bits, w, h); // wrap image into a bitmap object (no copying done)
- std::vector<Image*> images;
- for(size_t i=0; i!=thumbs.size(); i++) {
- BltCanvas canvas(thumbs[i]->width,thumbs[i]->height);
- albumart.stretch(&canvas, 0, 0, thumbs[i]->width,thumbs[i]->height);
- images.push_back(new Image((ARGB32 *)canvas.getBits(), thumbs[i]->width,thumbs[i]->height));
- }
- if(!replaceart(songid,driveW,artdb,&thumbs,&images)) {
- setArt(songid,NULL,0,0);
- ArtImage * artimg = new ArtImage();
- artimg->songid = mhit->dbid;
- artimg->id = artdb->nextid++;
- artimg->srcImageSize = w*h*4;//0; //fileSize(infile);
- //artimg->srcImageSize = mhit->unk45 = rand();
- mhit->artworksize = 0;
- for(size_t i=0; i!=thumbs.size(); i++)
- {
- artimg->dataobjs.push_back(makeThumbMetadata(thumbs[i],driveW,images[i],artdb));
- mhit->artworksize += thumbs[i]->width * thumbs[i]->height * sizeof(short);
- }
- artdb->imageListDS->imageList->images.insert(ArtImageList::ArtImageMapPair(artimg->songid,artimg));
- mhit->artworkcount = 1;//thumbs.size();
- mhit->hasArtwork = 1;//thumbs.size();
- mhit->mhii_link = artimg->id;
- }
- //images.deleteAll();
- for (auto image : images)
- {
- delete image;
- }
- images.clear();
- }
- }
- class ipodart_t {
- public:
- ipodart_t(ArtImageName *in, wchar_t driveW,int w, int h, const ArtworkFormat* format): w(w),h(h),image(0),error(0),resized(0),format(format) {
- wsprintf(fn,L"%c:\\iPod_Control\\Artwork",driveW);
- wchar_t *p = fn+wcslen(fn);
- in->filename->GetString(p,MAX_PATH - (p - fn));
- while(p && *p) {if(*p == L':') *p=L'\\'; p++;}
- offset = in->ithmboffset;
- }
- ~ipodart_t() { if(image) delete image; }
- Image * GetImage() {
- if(image || error) return image;
- int size = Image::get16BitSize(w,h,format->row_align, format->image_align);
- RGB565 * r = (RGB565*)calloc(size,1);
- if(!r) { return 0; error=1; }
- FILE *f = _wfopen(fn,L"rb");
- if(!f) { free(r); error=1; return 0; }
- fseek(f,offset,0);
- if(fread(r,size,1,f) != 1) { free(r); fclose(f); error=1; return 0; }
- fclose(f);
- image = new Image(r,w,h,format->format,format->row_align, format->image_align);
- free(r);
- return image;
- }
- Image * RegetImage() {
- if(image) delete image; image=0;
- return GetImage();
- }
- int GetError() {return error;}
- int getHeight(){if(image) return image->getHeight(); else return h;}
- int getWidth() {if(image) return image->getWidth(); else return w;}
- int resized;
- void Resize(int neww, int newh)
- {
- HQSkinBitmap temp(image->getData(), image->getWidth(), image->getHeight()); // wrap into a SkinBitmap (no copying involved)
- BltCanvas newImage(neww,newh);
- temp.stretch(&newImage, 0, 0, neww, newh);
- delete image;
- image = new Image((ARGB32 *)newImage.getBits(), neww, newh);
- resized=1;
- }
- private:
- wchar_t fn[MAX_PATH];
- int offset;
- int w,h;
- Image * image;
- int error;
- const ArtworkFormat* format;
- };
- pmpart_t iPodDevice::getArt(songid_t songid) {
- if(!artdb) return 0;
- __int64 dbid = ((iPod_mhit*)songid)->dbid;
- ArtImageList::ArtImageMapIterator art = artdb->imageListDS->imageList->images.find(dbid);
- if(art == artdb->imageListDS->imageList->images.end() || !art->second) return 0;
- int l = art->second->dataobjs.size();
- ArtImageName * in=0;
- int w=0,h=0;
- const ArtworkFormat * format=0;
- for(int i=0; i<l; i++) {
- if(art->second->dataobjs[i]->image && (w < art->second->dataobjs[i]->image->imgw || h < art->second->dataobjs[i]->image->imgh)) {
- in = art->second->dataobjs[i]->image;
- w = in->imgw;
- h = in->imgh;
- for(size_t i=0; i < thumbs.size(); i++)
- {
- const ArtworkFormat *f = thumbs.at(i);
- if(f->width == w && f->height == h)
- format = f;
- }
- }
- }
- if(!in || !format) return 0;
- return (pmpart_t)new ipodart_t(in,driveW,w,h,format);
- }
- void iPodDevice::releaseArt(pmpart_t art) {
- if(!art) return;
- ipodart_t *image = (ipodart_t *)art;
- delete image;
- }
- int iPodDevice::drawArt(pmpart_t art, HDC dc, int x, int y, int w, int h) {
- Image *image = ((ipodart_t*)art)->GetImage();
- if(!image) return 0;
- HQSkinBitmap temp(image->getData(), image->getWidth(), image->getHeight()); // wrap into a SkinBitmap (no copying involved)
- DCCanvas canvas(dc);
- temp.stretch(&canvas,x,y,w,h);
- return 1;
- }
- void iPodDevice::getArtNaturalSize(pmpart_t art, int *w, int *h){
- ipodart_t *image = (ipodart_t*)art;
- if(!image) return;
- *h = image->getHeight();
- *w = image->getWidth();
- }
- void iPodDevice::setArtNaturalSize(pmpart_t art, int w, int h){
- Image *image = ((ipodart_t*)art)->GetImage();
- if(!image) return;
- if(w == image->getWidth() && h == image->getHeight()) return;
- if(((ipodart_t*)art)->resized) {
- image = ((ipodart_t*)art)->RegetImage();
- if(!image) return;
- }
- ((ipodart_t*)art)->Resize(w, h);
- }
- void iPodDevice::getArtData(pmpart_t art, void* data){ // data ARGB32* is at natural size
- Image *image = ((ipodart_t*)art)->GetImage();
- if(!image) return;
- image->exportToARGB32((ARGB32*)data);
- }
- bool iPodDevice::artIsEqual(pmpart_t at, pmpart_t bt) {
- if(at == bt) return true;
- if(!at || !bt) return false;
- if(((ipodart_t*)at)->getWidth() != ((ipodart_t*)bt)->getWidth()) return false;
- if(((ipodart_t*)at)->getHeight() != ((ipodart_t*)bt)->getHeight()) return false;
- Image *a = ((ipodart_t*)at)->RegetImage();
- Image *b = ((ipodart_t*)bt)->RegetImage();
- if(!a && !b) return true;
- if(!a || !b) return false;
- if(a->getWidth() != b->getWidth()) return false;
- if(b->getHeight() != b->getHeight()) return false;
- return memcmp(a->getData(),b->getData(),a->getWidth()*a->getHeight()*sizeof(ARGB32)) == 0;
- }
- static INT_PTR CALLBACK gapscan_dialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam) {
- static iPodDevice * dev;
- static int i;
- switch(uMsg) {
- case WM_INITDIALOG:
- SetWindowPos(hwndDlg,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
- dev = (iPodDevice*)lParam;
- i=0;
- dev->gapscanner = hwndDlg;
- SendDlgItemMessage(hwndDlg,IDC_PROGRESS1,PBM_SETRANGE32,0,dev->getPlaylistLength(0));
- SendDlgItemMessage(hwndDlg,IDC_PROGRESS1,PBM_SETPOS,0,0);
- SetTimer(hwndDlg,1,100,NULL);
- break;
- case WM_TIMER:
- if(wParam == 1) {
- KillTimer(hwndDlg,1);
- int l = dev->getPlaylistLength(0);
- int j=0;
- for(;;) {
- if(i >= l) return gapscan_dialogProc(hwndDlg,WM_CLOSE,0,0);
- iPod_mhit * mhit = (iPod_mhit *)dev->getPlaylistTrack(0,i++);
- if(!mhit->trackgapless && !mhit->gaplessData) {
- wchar_t artist[50] = {0}, title[50] = {0}, buf[200] = {0};
- dev->getTrackArtist((songid_t)mhit,artist,50);
- dev->getTrackTitle((songid_t)mhit,title,50);
- StringCchPrintf(buf,200,L"%d/%d: %s - %s",i+1,l,artist,title);
- SetDlgItemText(hwndDlg,IDC_CAPTION,buf);
- wchar_t infile[MAX_PATH]=L"";
- dev->getFilename(infile,MAX_PATH,(songid_t)mhit);
- BOOL worked=TRUE;
- mhit->samplecount = GetFileInfoInt64(infile,L"numsamples",&worked);
- mhit->pregap = (unsigned long)GetFileInfoInt64(infile,L"pregap",&worked);
- mhit->postgap = (unsigned long)GetFileInfoInt64(infile,L"postgap",&worked);
- mhit->gaplessData = (unsigned long)GetFileInfoInt64(infile,L"endoffset",&worked);
- mhit->trackgapless = worked?1:0;
- j++;
- } else if(!(i%23)) SetDlgItemText(hwndDlg,IDC_CAPTION,WASABI_API_LNGSTRINGW(IDS_SCANNING));
- if(j > 3 || !(i % 50)) {
- SendDlgItemMessage(hwndDlg,IDC_PROGRESS1,PBM_SETPOS,i,0);
- SetTimer(hwndDlg,1,25,NULL);
- return 0;
- }
- }
- }
- break;
- case WM_CLOSE:
- dev->writeiTunesDB();
- EndDialog(hwndDlg,0);
- dev->gapscanner = NULL;
- break;
- case WM_DESTROY:
- dev->gapscanner = NULL;
- break;
- case WM_COMMAND:
- switch(LOWORD(wParam)) {
- case IDCANCEL:
- gapscan_dialogProc(hwndDlg,WM_CLOSE,0,0);
- break;
- case IDC_BG:
- ShowWindow(hwndDlg,SW_HIDE);
- break;
- }
- break;
- }
- return 0;
- }
- static INT_PTR CALLBACK config_dialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam) {
- static iPodDevice * dev;
- switch(uMsg) {
- case WM_INITDIALOG:
- {
- prefsParam* p = (prefsParam*)lParam;
- p->config_tab_init(hwndDlg,p->parent);
- dev = (iPodDevice*)p->dev;
- if(dev->artdb && dev->thumbs.size()) {
- wchar_t inifile[] = {dev->driveW,L":\\iPod_Control\\iTunes\\ml_pmp.ini"};
- ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC_ARTGROUP),SW_SHOWNA);
- ShowWindow(GetDlgItem(hwndDlg,IDC_CHECK_USEART),SW_SHOWNA);
- CheckDlgButton(hwndDlg,IDC_CHECK_USEART,GetPrivateProfileInt(L"ml_pmp",L"albumart",1,inifile));
- //ShowWindow(GetDlgItem(hwndDlg,IDC_COMBO_ARTMODE),SW_SHOWNA);
- /*ComboBox combo(hwndDlg,IDC_COMBO_USEART);
- combo.AddString(L"Add to all tracks");
- combo.AddString(L"Only add to the first track in an album");
- combo.AddString(L"Don't add to any tracks");
- */
- }
- }
- break;
- case WM_COMMAND:
- switch(LOWORD(wParam)) {
- case IDC_SCAN:
- if(dev->gapscanner) ShowWindow(dev->gapscanner,SW_SHOW);
- else WASABI_API_DIALOGBOXPARAM(IDD_GAPSCAN,NULL,gapscan_dialogProc,(LPARAM)dev);
- break;
- case IDC_CHECK_USEART:
- wchar_t inifile[] = {dev->driveW,L":\\iPod_Control\\iTunes\\ml_pmp.ini"}, s[32] = {0};
- StringCchPrintf(s, 32, L"%d", (IsDlgButtonChecked(hwndDlg, IDC_CHECK_USEART)==BST_CHECKED));
- WritePrivateProfileString(L"ml_pmp", L"albumart", s, inifile);
- break;
- }
- break;
- }
- return 0;
- }
- static const intptr_t encoder_blacklist[] =
- {
- mmioFOURCC('W','M','A',' '),
- mmioFOURCC('A','A','C','H'),
- mmioFOURCC('A','A','C','P'),
- mmioFOURCC('A','A','C','r'),
- mmioFOURCC('F','L','A','C'),
- mmioFOURCC('O','G','G',' '),
- mmioFOURCC('M','P','2',' '),
- mmioFOURCC('M','4','A','H'),
- mmioFOURCC('M','4','A','+'),
- mmioFOURCC('A','D','T','S'),
- };
- intptr_t iPodDevice::extraActions(intptr_t param1, intptr_t param2, intptr_t param3,intptr_t param4) {
- switch(param1) {
- case DEVICE_SET_ICON: // icons
- {
- MLTREEIMAGE * i = (MLTREEIMAGE*)param2;
- i->hinst = plugin.hDllInstance;
- i->resourceId = image16;
- }
- break;
- case DEVICE_GET_ICON:
- {
- if (param2 <= 16 && param3 <= 16)
- {
- // TODO: get the name of the DLL at load time
- StringCchPrintfW((wchar_t *)param4, 260, L"res://%s/PNG/#%u", L"pmp_ipod.dll", image16);
- }
- else
- {
- // TODO: get the name of the DLL at load time
- StringCchPrintfW((wchar_t *)param4, 260, L"res://%s/PNG/#%u", L"pmp_ipod.dll", image160);
- }
- }
- break;
- case DEVICE_SUPPORTED_METADATA:
- return 0xffff | (artdb?SUPPORTS_ALBUMART:0);
- case DEVICE_CAN_RENAME_DEVICE:
- return 1;
- case DEVICE_GET_INI_FILE:
- {
- wchar_t inifile[] = {driveW,L":\\iPod_Control\\iTunes\\ml_pmp.ini"};
- wcsncpy((wchar_t*)param2,inifile,MAX_PATH);
- }
- break;
- case DEVICE_GET_PREFS_DIALOG:
- if(param3 == 0) {
- pref_tab * p = (pref_tab *)param2;
- p->hinst = WASABI_API_LNG_HINST;
- p->dlg_proc = config_dialogProc;
- p->res_id = IDD_CONFIG;
- WASABI_API_LNGSTRINGW_BUF(IDS_ADVANCED,p->title,100);
- }
- break;
- case DEVICE_REFRESH:
- {
- char drive = this->drive;
-
- //iPods.eraseObject(this);
- auto it = std::find(iPods.begin(), iPods.end(), this);
- if (it != iPods.end())
- {
- iPods.erase(it);
- }
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)this,PMP_IPC_DEVICEDISCONNECTED);
- delete this;
- new iPodDevice(drive);
- }
- break;
- case DEVICE_ADDPODCASTGROUP:
- {
- int pos = param3;
- wchar_t * name = (wchar_t *)param4;
- iPod_mhyp* pl = (iPod_mhyp*)playlists.Get(param2);
- pl->podcastflag=1;
- iPod_mhip * mhip = new iPod_mhip();
- mhip->podcastgroupflag=256;
- mhip->podcastgroupref=0;
- iPod_mhod * d = new iPod_mhod();
- d->SetString(name);
- d->type=1;
- mhip->mhod.push_back(d);
- pl->mhip.insert(pl->mhip.begin()+pos,mhip);
- }
- break;
- case DEVICE_ADDPODCASTGROUP_FINISH:
- {
- iPod_mhyp* pl = (iPod_mhyp*)playlists.Get(param2);
- pl->numLibraryMHODs=0x18;
- int groupref=0;
- for(size_t i=0; i < pl->mhip.size(); i++) {
- iPod_mhip * m = pl->mhip[i];
- m->groupid = i+1000000;
- if(m->podcastgroupflag & 256) groupref = m->groupid;
- else m->podcastgroupref = groupref;
- }
- }
- break;
- case DEVICE_SUPPORTS_VIDEO:
- return 1;
- case DEVICE_VETO_ENCODER:
- {
- for (size_t i=0;i<sizeof(encoder_blacklist)/sizeof(*encoder_blacklist);i++)
- {
- // TODO: check device info XML for aacPlus support
- if (param2 == encoder_blacklist[i])
- return 1;
- }
- }
- return 0;
- case DEVICE_GET_MODEL:
- {
- wchar_t *model_buffer = (wchar_t *)param2;
- unsigned int cch = (unsigned int)param3;
- if (!info)
- {
- StringCchCopyW(model_buffer, cch, L"Apple iPod");
- }
- else switch(info->family_id)
- {
- default:
- StringCchCopyW(model_buffer, cch, L"Apple iPod");
- break;
- case 3:
- StringCchCopyW(model_buffer, cch, L"Apple iPod Mini");
- break;
- case 4:
- StringCchCopyW(model_buffer, cch, L"Apple iPod 4G");
- break;
- case 5:
- StringCchCopyW(model_buffer, cch, L"Apple iPod Photo");
- break;
- case 6:
- StringCchCopyW(model_buffer, cch, L"Apple iPod 5G");
- break;
- case 7:
- StringCchCopyW(model_buffer, cch, L"Apple iPod Nano 1G");
- break;
- case 9:
- StringCchCopyW(model_buffer, cch, L"Apple iPod Nano 2G");
- break;
- case 11:
- StringCchCopyW(model_buffer, cch, L"Apple iPod Classic");
- break;
- case 12:
- StringCchCopyW(model_buffer, cch, L"Apple iPod Fat Nano");
- break;
- case 15:
- StringCchCopyW(model_buffer, cch, L"Apple iPod Nano4G");
- break;
- case 128:
- StringCchCopyW(model_buffer, cch, L"Apple iPod Shuffle");
- break;
- case 130:
- StringCchCopyW(model_buffer, cch, L"Apple iPod Shuffle 2G");
- break;
- case 132:
- StringCchCopyW(model_buffer, cch, L"Apple iPod Shuffle 3G");
- break;
- }
- }
- return 1;
- }
- return 0;
- }
|