12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913 |
- #include "usbdevice.h"
- #include "resource.h"
- #include "usbplaylist.h"
- #include "usbplaylistsaver.h"
- #include "api.h"
- #include "../winamp/wa_ipc.h"
- #include <tataki/bitmap/bitmap.h>
- #include <tataki/canvas/bltcanvas.h>
- #include <shlobj.h>
- #include <strsafe.h>
- #include <shlwapi.h>
- // from main.cpp
- extern PMPDevicePlugin plugin;
- extern std::vector<USBDevice*> devices;
- extern bool loading_devices[26];
- // from utils.cpp
- extern BOOL RecursiveCreateDirectory(wchar_t* buf);
- extern bool supportedFormat(wchar_t * file, wchar_t * supportedFormats);
- extern DeviceType detectDeviceType(wchar_t drive);
- extern __int64 fileSize(wchar_t * filename);
- extern void removebadchars(wchar_t *s);
- extern wchar_t * fixReplacementVars(wchar_t *str, int str_size, Device * dev, songid_t song);
- static INT_PTR CALLBACK prefs_dialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
- int CopyFile(const wchar_t *infile, const wchar_t *outfile, void * callbackContext, void (*callback)(void * callbackContext, wchar_t * status), int * killswitch);
- // called from ml_pmp
- extern BOOL EjectVolume(TCHAR cDriveLetter);
- void CopyAlbumArt(const wchar_t *source, const wchar_t *destination);
- __int64 USBDevice::getDeviceCapacityAvailable() // in bytes
- {
- 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;
- }
- // called from ml_pmp
- __int64 USBDevice::getDeviceCapacityTotal()
- {
- // in bytes
- 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;
- }
- // called from ml_pmp
- void USBDevice::Eject()
- {
- // if you ejected successfully, you MUST call PMP_IPC_DEVICEDISCONNECTED and delete this
- for(size_t i=0; i < devices.size(); i++)
- {
- USBDevice *device = devices.at(i);
- if (device == this)
- {
- if (EjectVolume(drive))
- {
- devices.erase(devices.begin() + i);
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)this,PMP_IPC_DEVICEDISCONNECTED);
- delete this;
- break;
- }
- else
- {
- wchar_t titleStr[128] = {0};
- MessageBox(plugin.hwndLibraryParent,WASABI_API_LNGSTRINGW(IDS_FAILED_TO_EJECT_DRIVE), WASABI_API_LNGSTRINGW_BUF(IDS_ERROR,titleStr,128),0);
- break;
- }
- }
- }
- }
- // called from ml_pmp
- void USBDevice::Close()
- {
- // save any changes, and call PMP_IPC_DEVICEDISCONNECTED AND delete this
- for(size_t i=0; i < devices.size(); i++)
- {
- if(((USBDevice*)devices.at(i)) == this)
- {
- devices.erase(devices.begin() + i);
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)this,PMP_IPC_DEVICEDISCONNECTED);
- delete this;
- break;
- }
- }
- }
- // called from ml_pmp
- // return 0 for success, -1 for failed or cancelled
- int USBDevice::transferTrackToDevice(const itemRecordW * track, // the track to transfer
- 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!
- songid_t * songid, // fill in the songid when you are finished
- int * killswitch) // if this gets set to anything other than zero, the transfer has been cancelled by the user
- {
- wchar_t fn[MAX_PATH] = L"X:\\";
- lstrcpyn(fn, songFormat, MAX_PATH);
- fn[0] = drive;
- wchar_t * src = track->filename;
- wchar_t ext[10] = {0};
- wchar_t *e = wcsrchr(src,L'.');
- if (e) lstrcpyn(ext, e, 10);
- bool transcodefile = false;
- if (transcoder && transcoder->ShouldTranscode(src))
- {
- int r = transcoder->CanTranscode(src, ext);
- if (r != 0 && r != -1) transcodefile = true;
- }
- UsbSong *s = new UsbSong();
- lstrcpyn(s->filename, src, MAX_PATH); //this will get written over, but for now we have this so that the user can keep the old filename
- fillMetaData(s); // TODO: benski> used cached info inside track (itemRecordW) if available
- fixReplacementVars(fn, MAX_PATH, this, (songid_t)s);
- StringCchCat(fn, MAX_PATH, ext); //place extension
- StringCchCopy(s->filename, MAX_PATH, fn);
- wchar_t * dir = wcsrchr(fn,L'\\');
- wchar_t * dir2 = wcsrchr(fn,L'/');
- wchar_t slash;
- if (dir2 > dir)
- {
- dir = dir2;
- slash=L'/';
- }
- else slash = L'\\';
- if (dir) *dir = 0;
- RecursiveCreateDirectory(fn);
- if (dir) *dir = slash;
- int r;
- if (transcodefile)
- {
- r = transcoder->TranscodeFile(src, fn, killswitch, callback, callbackContext);
- }
- else
- {
- r = CopyFile(src, fn, callbackContext, callback, killswitch);
- }
- if (r == 0)
- {
- // TODO: benski> do we need to update any fields from the transcoded filed?
- CopyAlbumArt(src, fn);
- writeRecordToDB(s);
- callback(callbackContext, WASABI_API_LNGSTRINGW(IDS_DONE));
- *songid = (songid_t)s;
- }
- else
- {
- callback(callbackContext, WASABI_API_LNGSTRINGW(IDS_TRANSFER_FAILED));
- delete s;
- }
- return r;
- }
- // called from ml_pmp
- int USBDevice::trackAddedToTransferQueue(const itemRecordW *track)
- {
- // return 0 to accept, -1 for "not enough space", -2 for "incorrect format"
- __int64 k = getTrackSizeOnDevice(track);
- if(!k) return -2;
- __int64 l = (__int64)k;
- __int64 avail = getDeviceCapacityAvailable();
- __int64 cmp = transferQueueLength;
- cmp += l;
- if(cmp > avail) return -1;
- else {
- transferQueueLength += l;
- return 0;
- }
- }
- // called from ml_pmp
- void USBDevice::trackRemovedFromTransferQueue(const itemRecordW *track)
- {
- transferQueueLength -= (__int64)getTrackSizeOnDevice(track);
- }
- // called from ml_pmp
- // return the amount of space that will be taken up on the device by the track (once it has been tranferred)
- // or 0 for incompatable. This is usually the filesize, unless you are transcoding. An estimate is acceptable.
- __int64 USBDevice::getTrackSizeOnDevice(const itemRecordW *track)
- {
- if(transcoder) {
- if(transcoder->ShouldTranscode(track->filename)) {
- int k = transcoder->CanTranscode(track->filename);
- if(k != -1 && k != 0) return k;
- return 0;
- } else return fileSize(track->filename);
- } else {
- if(!supportedFormat(track->filename,supportedFormats)) return 0;
- return fileSize(track->filename);
- }
- }
- // called from ml_pmp
- void USBDevice::deleteTrack(songid_t songid)
- {
- // physically remove from device. Be sure to remove it from all the playlists!
- UsbSong * s = (UsbSong*)songid;
- //errno == 2 is ENOENT
- if(!_wunlink(s->filename) || errno == 2) { //will continue delete if file was deleted successfully or file path does not exist in the first place (errno==2)
- for(size_t i=0; i < usbPlaylists.size(); i++) {
- USBPlaylist * pl = usbPlaylists.at(i);
- size_t l = pl->songs.size();
- while(l--)
- {
- if(((UsbSong*)pl->songs.at(l)) == s)
- {
- // remove the track and rewrite the playlist
- removeTrackFromPlaylist((int)i, (int)l);
- }
- }
- if(purgeFolders[0]=='1')
- {
- RemoveDirectory(s->filename);
- }
- }
- delete (UsbSong*)songid;
- } else {
- char titleStr[32] = {0};
- MessageBoxA(plugin.hwndLibraryParent,WASABI_API_LNGSTRING(IDS_TRACK_IN_USE),
- WASABI_API_LNGSTRING_BUF(IDS_ERROR,titleStr,32),0);
- }
- }
- // called from ml_pmp
- // optional. Will be called at a good time to save changes
- void USBDevice::commitChanges()
- {
- //update cache
- tag();
- cacheUpToDate = true;
- SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)0,IPC_WRITE_EXTENDED_FILE_INFO);
- }
- // called from ml_pmp
- int USBDevice::getPlaylistCount()
- {
- // always at least 1. playlistnumber 0 is the Master Playlist containing all tracks.
- return (int)usbPlaylists.size();
- }
- // called from ml_pmp
- // PlaylistName(0) should return the name of the device.
- void USBDevice::getPlaylistName(int playlistnumber, wchar_t *buf, int len)
- {
- wchar_t * pathName = usbPlaylists.at(playlistnumber)->filename;
- if(playlistnumber != 0)
- {
- if(pathName[0])
- {
- wchar_t * playlistName = PathFindFileNameW(pathName);
- lstrcpyn(buf,playlistName,len);
- PathRemoveExtension(buf);
- }
- }
- else //playlist number = 0 -> this is the device
- {
- if(pathName[0])
- { //if we have a custom device name
- lstrcpyn(buf,pathName,len);
- }
- else
- {
- WASABI_API_LNGSTRINGW_BUF(IDS_USB_DRIVE_X,buf,len);
- wchar_t * x = wcsrchr(buf,L'X');
- if(x) *x = drive;
- }
- }
- }
- // called from ml_pmp
- int USBDevice::getPlaylistLength(int playlistnumber)
- {
- return (int)usbPlaylists.at(playlistnumber)->songs.size();
- }
- // called from ml_pmp
- songid_t USBDevice::getPlaylistTrack(int playlistnumber,int songnum)
- {
- // returns a songid
- return (songid_t) usbPlaylists.at(playlistnumber)->songs.at(songnum);
- }
- // called from ml_pmp
- void USBDevice::setPlaylistName(int playlistnumber, const wchar_t *buf)
- {
- // with playlistnumber==0, set the name of the device.
- USBPlaylist * pl = usbPlaylists.at(playlistnumber);
- if(playlistnumber==0)
- {
- WritePrivateProfileString(L"pmp_usb",L"customName",buf,iniFile);
- lstrcpyn(pl->filename,buf,sizeof(pl->filename)/sizeof(wchar_t));
- }
- else
- {
- wchar_t currentFilename[MAX_PATH] = {0};
- lstrcpynW(currentFilename, pl->filename, MAX_PATH);
-
- wchar_t * newFilename = const_cast<wchar_t *>(buf);
- if(wcslen(buf) >= MAX_PATH-1) newFilename[MAX_PATH-1]=0;
- while(newFilename && *newFilename && *newFilename == L'.') newFilename++;
- removebadchars(newFilename);
- StringCchPrintf(pl->filename,MAX_PATH,L"%s\\%s.m3u",pldir,newFilename);
- pl->filename[0]=drive;
- MoveFile(currentFilename, pl->filename);
- pl->dirty=true;
- }
- }
- // called from ml_pmp
- void USBDevice::playlistSwapItems(int playlistnumber, int posA, int posB)
- {
- // swap the songs at position posA and posB
- USBPlaylist * pl = (USBPlaylist*)usbPlaylists.at(playlistnumber);
- UsbSong* a = pl->songs.at(posA);
- UsbSong* b = pl->songs.at(posB);
- pl->songs.insert(pl->songs.begin() + posA, b);
- pl->songs.erase(pl->songs.begin() + posA + 1);
- pl->songs.insert(pl->songs.begin() + posB, a);
- pl->songs.erase(pl->songs.begin() + posB + 1);
- pl->dirty = true;
- }
- // called from ml_pmp
- void USBDevice::sortPlaylist(int playlistnumber, int sortBy)
- {
- // TODO: implement
- }
- // called from ml_pmp
- void USBDevice::addTrackToPlaylist(int playlistnumber, songid_t songid)
- {
- // adds songid to the end of the playlist
- UsbSong* song = (UsbSong *) songid;
- USBPlaylist * pl = (USBPlaylist*)usbPlaylists.at(playlistnumber);
- pl->songs.push_back(song);
- pl->dirty=true;
- }
- // called from ml_pmp
- void USBDevice::removeTrackFromPlaylist(int playlistnumber, int songnum)
- {
- //where songnum is the position of the track in the playlist
- USBPlaylist * pl = (USBPlaylist*)usbPlaylists.at(playlistnumber);
- pl->songs.erase(pl->songs.begin() + songnum);
- pl->dirty=true;
- }
- // called from ml_pmp
- void USBDevice::deletePlaylist(int playlistnumber)
- {
- USBPlaylist * pl = (USBPlaylist*)usbPlaylists.at(playlistnumber);
- _wunlink(pl->filename);
- usbPlaylists.erase(usbPlaylists.begin() + playlistnumber);
- delete pl;
- }
- // called from ml_pmp
- int USBDevice::newPlaylist(const wchar_t *name)
- {
- // create empty playlist, returns playlistnumber. -1 for failed.
- wchar_t plname[MAX_PATH] = {0};
- StringCchCopy(plname, MAX_PATH, name);
- removebadchars(plname);
- wchar_t buff[MAX_PATH] = {0};
- StringCchPrintf(buff, MAX_PATH, L"%s\\%s.m3u",pldir,plname);
- USBPlaylist * pl = new USBPlaylist(*this, buff, false);
- pl->filename[0]=drive;
- //Lets save the playlist right away
- USBPlaylistSaver playlistSaver(pl->filename, L"autosaved", pl);
- playlistSaver.Save();
- usbPlaylists.push_back(pl);
- return (int)usbPlaylists.size()-1;
- }
- // called from ml_pmp
- void USBDevice::getTrackArtist(songid_t songid, wchar_t *buf, int len)
- {
- UsbSong* song = (UsbSong*)songid;
- if (!song) return;
- buf[0] = L'\0';
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- StringCchCopy(buf, len, song->artist);
- }
- // called from ml_pmp
- void USBDevice::getTrackAlbum(songid_t songid, wchar_t *buf, int len)
- {
- UsbSong* song = (UsbSong*)songid;
- if (!song) return;
-
- buf[0] = L'\0';
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- StringCchCopy(buf, len, song->album);
- }
- // called from ml_pmp
- void USBDevice::getTrackTitle(songid_t songid, wchar_t *buf, int len)
- {
- UsbSong* song = (UsbSong*)songid;
- if (!song) return;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- StringCchCopy(buf, len, song->title);
- }
- // called from ml_pmp
- int USBDevice::getTrackTrackNum(songid_t songid)
- {
- UsbSong* song = (UsbSong*)songid;
- if (!song) return 0;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- return song->track;
- }
- // called from ml_pmp
- int USBDevice::getTrackDiscNum(songid_t songid)
- {
- UsbSong* song = (UsbSong*)songid;
- if (!song) return 0;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- return song->discnum;
- }
- // called from ml_pmp
- void USBDevice::getTrackGenre(songid_t songid, wchar_t * buf, int len)
- {
- UsbSong* song = (UsbSong*)songid;
- if (!song) return;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- StringCchCopy(buf, len, song->genre);
- }
- // called from ml_pmp
- int USBDevice::getTrackYear(songid_t songid)
- {
- UsbSong* song = (UsbSong*)songid;
- if (!song) return 0;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- return song->year;
- }
- // called from ml_pmp
- __int64 USBDevice::getTrackSize(songid_t songid)
- {
- // in bytes
- UsbSong* song = (UsbSong*)songid;
- if (!song) return 0;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- return song->size;
- }
- // called from ml_pmp
- int USBDevice::getTrackLength(songid_t songid)
- {
- // in millisecs
- UsbSong* song = (UsbSong*)songid;
- if (!song) return 0;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- return song->length;
- }
- // called from ml_pmp
- int USBDevice::getTrackBitrate(songid_t songid)
- {
- // in kbps
- UsbSong* song = (UsbSong*)songid;
- if (!song) return 0;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- return song->bitrate;
- }
- // called from ml_pmp
- int USBDevice::getTrackPlayCount(songid_t songid)
- {
- UsbSong* song = (UsbSong*)songid;
- if (!song) return 0;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- return song->playcount;
- }
- // called from ml_pmp
- int USBDevice::getTrackRating(songid_t songid)
- {
- //0-5
- // TODO: implement
- return 0;
- }
- // called from ml_pmp
- __time64_t USBDevice::getTrackLastPlayed(songid_t songid)
- {
- // in unix time format
- // TODO: implement
- return 0;
- }
- // called from ml_pmp
- __time64_t USBDevice::getTrackLastUpdated(songid_t songid)
- {
- // in unix time format
- // TODO: implement
- return 0;
- }
- // called from ml_pmp
- void USBDevice::getTrackAlbumArtist(songid_t songid, wchar_t *buf, int len)
- {
- UsbSong* song = (UsbSong*)songid;
- if (!song) return;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- StringCchCopy(buf, len, song->albumartist);
- }
- // called from ml_pmp
- void USBDevice::getTrackPublisher(songid_t songid, wchar_t *buf, int len)
- {
- UsbSong* song = (UsbSong*)songid;
- if (!song) return;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- StringCchCopy(buf, len, song->publisher);
- }
- // called from ml_pmp
- void USBDevice::getTrackComposer(songid_t songid, wchar_t *buf, int len)
- {
- UsbSong* song = (UsbSong*)songid;
- if (!song) return;
-
- if(!loadedUpToDate)
- {
- this->fillMetaData(song);
- }
- StringCchCopy(buf, len, song->composer);
- }
- // called from ml_pmp
- int USBDevice::getTrackType(songid_t songid)
- {
- // TODO: implement
- return 0;
- }
- // called from ml_pmp
- void USBDevice::getTrackExtraInfo(songid_t songid, const wchar_t *field, wchar_t *buf, int len)
- {
- // TODO: implement
- //optional
- }
- // called from ml_pmp
- // feel free to ignore any you don't support
- void USBDevice::setTrackArtist(songid_t songid, const wchar_t *value)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- updateTrackField(song, DEVICEVIEW_COL_ARTIST, value, FIELD_STRING);
- StringCchCopy(song->artist, FIELD_LENGTH, value);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"artist", value);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackAlbum(songid_t songid, const wchar_t *value)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- updateTrackField(song, DEVICEVIEW_COL_ALBUM, value, FIELD_STRING);
- StringCchCopy(song->album, FIELD_LENGTH, value);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"album", value);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackTitle(songid_t songid, const wchar_t *value)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- updateTrackField(song, DEVICEVIEW_COL_TITLE, value, FIELD_STRING);
- StringCchCopy(song->title, FIELD_LENGTH, value);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"title", value);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackTrackNum(songid_t songid, int value)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- wchar_t track[FIELD_LENGTH] = {0};
- updateTrackField(song, DEVICEVIEW_COL_TRACK, &value, FIELD_INTEGER);
- song->track = value;
- StringCchPrintf(track, FIELD_LENGTH, L"%d", value);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"track", track);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackDiscNum(songid_t songid, int value)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- wchar_t discNum[FIELD_LENGTH] = {0};
- updateTrackField(song, DEVICEVIEW_COL_DISC_NUMBER, &value, FIELD_INTEGER);
- song->discnum = value;
- StringCchPrintf(discNum, FIELD_LENGTH, L"%d", value);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"disc", discNum);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackGenre(songid_t songid, const wchar_t *value)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- updateTrackField(song, DEVICEVIEW_COL_GENRE, value, FIELD_STRING);
- StringCchCopy(song->genre, FIELD_LENGTH, value);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"genre", value);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackYear(songid_t songid, int year)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- wchar_t yearStr[FIELD_LENGTH] = {0};
- updateTrackField(song, DEVICEVIEW_COL_YEAR, &year, FIELD_INTEGER);
- song->year = year;
- StringCchPrintf(yearStr, FIELD_LENGTH, L"%d", year);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"year", yearStr);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackPlayCount(songid_t songid, int value)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- wchar_t playCount[FIELD_LENGTH] = {0};
- updateTrackField(song, DEVICEVIEW_COL_PLAY_COUNT, &value, FIELD_INTEGER);
- song->playcount = value;
- StringCchPrintf(playCount, FIELD_LENGTH, L"%d", value);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"playcount", playCount);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackRating(songid_t songid, int value)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- wchar_t rating[FIELD_LENGTH] = {0};
- updateTrackField(song, DEVICEVIEW_COL_PLAY_COUNT, &value, FIELD_INTEGER);
- song->playcount = value;
- StringCchPrintf(rating, FIELD_LENGTH, L"%d", value);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"rating", rating);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackLastPlayed(songid_t songid, __time64_t value)
- {
- // TODO: implement
- } // in unix time format
- // called from ml_pmp
- void USBDevice::setTrackLastUpdated(songid_t songid, __time64_t value)
- {
- // TODO: implement
- } // in unix time format
- // called from ml_pmp
- void USBDevice::setTrackAlbumArtist(songid_t songid, const wchar_t *value)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- updateTrackField(song, DEVICEVIEW_COL_ALBUM_ARTIST, value, FIELD_STRING);
- StringCchCopy(song->albumartist, FIELD_LENGTH, value);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"albumartist", value);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackPublisher(songid_t songid, const wchar_t *value)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- updateTrackField(song, DEVICEVIEW_COL_PUBLISHER, value, FIELD_STRING);
- StringCchCopy(song->publisher, FIELD_LENGTH, value);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"publisher", value);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackComposer(songid_t songid, const wchar_t *value)
- {
- UsbSong *song = (UsbSong *) songid;
- if (song)
- {
- updateTrackField(song, DEVICEVIEW_COL_COMPOSER, value, FIELD_STRING);
- StringCchCopy(song->composer, FIELD_LENGTH, value);
- AGAVE_API_METADATA->SetExtendedFileInfo(song->filename, L"composer", value);
- }
- }
- // called from ml_pmp
- void USBDevice::setTrackExtraInfo(songid_t songid, const wchar_t *field, const wchar_t *value)
- {
- // TODO: implement
- } //optional
- // called from ml_pmp
- bool USBDevice::playTracks(songid_t * songidList, int listLength, int startPlaybackAt, bool enqueue)
- {
- // return false if unsupported
- if(!enqueue) //clear playlist
- {
- SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_DELETE);
- }
- for(int i=0; i<listLength; i++)
- {
- UsbSong *curSong = (UsbSong*)songidList[i];
- if (curSong)
- {
- enqueueFileWithMetaStructW s={0};
- s.filename = _wcsdup(curSong->filename);
- s.title = _wcsdup(curSong->title);
- s.ext = NULL;
- s.length = curSong->length/1000;
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_PLAYFILEW);
- }
- else
- {
- char titleStr[32] = {0};
- MessageBoxA(plugin.hwndWinampParent,WASABI_API_LNGSTRING(IDS_CANNOT_OPEN_FILE),
- WASABI_API_LNGSTRING_BUF(IDS_ERROR,titleStr,32),0);
- }
- }
- 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;
- }
- // called from ml_pmp
- intptr_t USBDevice::extraActions(intptr_t param1, intptr_t param2, intptr_t param3,intptr_t param4)
- {
- switch(param1)
- {
- case DEVICE_SET_ICON:
- {
- MLTREEIMAGE * i = (MLTREEIMAGE*)param2;
- i->hinst = plugin.hDllInstance;
- switch(devType)
- {
- case TYPE_PSP:
- i->resourceId = IDR_PSP_ICON;
- break;
- default:
- i->resourceId = IDR_USB_ICON;
- break;
- }
- }
- 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_usb.dll", (devType==TYPE_PSP)?IDR_PSP_ICON:IDR_USB_ICON);
- }
- }
- break;
- case DEVICE_SUPPORTED_METADATA:
- {
- intptr_t supported = SUPPORTS_ARTIST | SUPPORTS_ALBUM | SUPPORTS_TITLE | SUPPORTS_TRACKNUM | SUPPORTS_DISCNUM | SUPPORTS_GENRE |
- SUPPORTS_YEAR | SUPPORTS_SIZE | SUPPORTS_LENGTH | SUPPORTS_BITRATE | SUPPORTS_LASTUPDATED | SUPPORTS_ALBUMARTIST |
- SUPPORTS_COMPOSER | SUPPORTS_PUBLISHER | SUPPORTS_ALBUMART;
- return supported;
- }
- break;
- case DEVICE_CAN_RENAME_DEVICE:
- return 1;
- case DEVICE_GET_INI_FILE:
- StringCchCopy((wchar_t*)param2, MAX_PATH, iniFile);
- break;
- case DEVICE_GET_PREFS_DIALOG:
- if(param3 == 0)
- {
- pref_tab * p = (pref_tab *)param2;
- p->hinst = WASABI_API_LNG_HINST;
- p->dlg_proc = prefs_dialogProc;
- p->res_id = IDD_CONFIG;
- WASABI_API_LNGSTRINGW_BUF(IDS_ADVANCED,p->title,100);
- }
- break;
- case DEVICE_DONE_SETTING:
- UsbSong * song = (UsbSong *) param2;
- AGAVE_API_METADATA->WriteExtendedFileInfo(song->filename);
- return true;
- break;
- }
- return false;
- }
- // called from ml_pmp
- bool USBDevice::copyToHardDriveSupported()
- {
- return true;
- }
- // called from ml_pmp
- __int64 USBDevice::songSizeOnHardDrive(songid_t song)
- {
- // how big a song will be when copied back. Return -1 for not supported.
- // TODO: implement
- return 0;
- }
- // called from ml_pmp
- int USBDevice::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.
- UsbSong* track = (UsbSong*)song;
- wchar_t * ext = PathFindExtensionW(track->filename);
- if(ext && (lstrlen(ext)<10)) StringCchCat(path,MAX_PATH, ext); // append correct extention
- return CopyFile(track->filename,path,callbackContext, callback, killswitch);
- }
- // called from ml_pmp
- // art functions
- void USBDevice::setArt(songid_t songid, void *buf, int w, int h)
- {
- //buf is in format ARGB32*
- // TODO: implement
- }
- // called from ml_pmp
- pmpart_t USBDevice::getArt(songid_t songid)
- {
- UsbSong *song = (UsbSong *)songid;
- ARGB32 *bits;
- int w, h;
- if (AGAVE_API_ALBUMART && AGAVE_API_ALBUMART->GetAlbumArt(song->filename, L"cover", &w, &h, &bits) == ALBUMART_SUCCESS && bits)
- {
- return (pmpart_t) new USBArt(bits, w, h);
- }
- return 0;
- }
- // called from ml_pmp
- void USBDevice::releaseArt(pmpart_t art)
- {
- USBArt *image = (USBArt *)art;
- delete image;
- }
- // called from ml_pmp
- int USBDevice::drawArt(pmpart_t art, HDC dc, int x, int y, int w, int h)
- {
- USBArt *image = (USBArt *)art;
- if (image)
- {
- HQSkinBitmap temp(image->bits, image->w, image->h); // wrap into a SkinBitmap (no copying involved)
- DCCanvas canvas(dc);
- temp.stretch(&canvas,x,y,w,h);
- return 1;
- }
- return 0;
- }
- // called from ml_pmp
- void USBDevice::getArtNaturalSize(pmpart_t art, int *w, int *h)
- {
- // TODO: implement
- USBArt *image = (USBArt *)art;
- if (image)
- {
- *w = image->w;
- *h = image->h;
- }
- }
- // called from ml_pmp
- void USBDevice::setArtNaturalSize(pmpart_t art, int w, int h)
- {
- // TODO: implement
- }
- // called from ml_pmp
- void USBDevice::getArtData(pmpart_t art, void* data)
- {
- USBArt *image = (USBArt *)art;
- if (image)
- memcpy(data, image->bits, image->w*image->h*sizeof(ARGB32));
- // data ARGB32* is at natural size
- }
- // called from ml_pmp
- bool USBDevice::artIsEqual(pmpart_t a, pmpart_t b)
- {
- if (a == b)
- return true;
- // TODO: implement
- return false;
- }
- //////////////////////////////////////////////////////////////////////////////////////////
- // Initialize class statics
- nde_database_t USBDevice::discDB = 0;
- // The getter that returns the master playlist
- // the playlist vector always carries a master playlist
- USBPlaylist* USBDevice::getMasterPlaylist()
- {
- for (std::vector<USBPlaylist*>::const_iterator e = usbPlaylists.begin(); e != usbPlaylists.end(); e++)
- {
- USBPlaylist* playlist = (*e);
- if (playlist->isMaster()) return playlist;
- }
- return NULL;
- }
- // constructor
- USBDevice::USBDevice(wchar_t drive, pmpDeviceLoading * load): transcoder(NULL) {
- deviceTable = 0;
- StringCchPrintf(ndeDataFile, 100, L"%c:\\winamp_metadata.dat", drive);
- StringCchPrintf(ndeIndexFile, 100, L"%c:\\winamp_metadata.idx", drive);
- load->dev = this;
- load->UpdateCaption = NULL;
- //pass load to ml_pmp, ml updates load->UpdateCaption and context
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)load,PMP_IPC_DEVICELOADING);
- if(load->UpdateCaption) {
- wchar_t buf[100] = L"";
- WASABI_API_LNGSTRINGW_BUF(IDS_LOADING_DRIVE_X,buf,100);
- wchar_t * x = wcsrchr(buf,L'X');
- if(x) *x = drive;
- load->UpdateCaption(buf,load->context);
- }
-
- devType = detectDeviceType(drive);
- // load settings
- StringCchCopy(iniFile,MAX_PATH,L"x:\\pmp_usb.ini");
- iniFile[0]=drive;
- wchar_t customName[FIELD_LENGTH] = {0};
- GetPrivateProfileString(L"pmp_usb",L"pldir",devType==TYPE_PSP?L"X:\\PSP\\MUSIC":L"X:",pldir,sizeof(pldir)/sizeof(wchar_t),iniFile);
- GetPrivateProfileString(L"pmp_usb",L"songFormat",devType==TYPE_PSP?L"X:\\PSP\\MUSIC\\<Artist> - <Album>\\## - <Title>":L"X:\\<Artist>\\<Album>\\## - <Title>",songFormat,sizeof(songFormat)/sizeof(wchar_t),iniFile);
- GetPrivateProfileString(L"pmp_usb",L"supportedFormats",L"mp3;wav;wma;m4a;aac;ogg;flac",supportedFormats,sizeof(supportedFormats)/sizeof(wchar_t),iniFile);
- GetPrivateProfileString(L"pmp_usb",L"purgeFolders",L"1",purgeFolders,sizeof(purgeFolders)/sizeof(wchar_t),iniFile);
- GetPrivateProfileString(L"pmp_usb",L"customName",devType==TYPE_PSP?L"Sony PSP":L"",customName,sizeof(customName)/sizeof(wchar_t),iniFile);
- pl_write_mode = GetPrivateProfileInt(L"pmp_usb",L"pl_write_mode",0,iniFile);
- pldir[0] = drive;
- songFormat[0] = drive;
- transferQueueLength = 0;
- this->drive = drive;
- USBPlaylist * mpl = new USBPlaylist(*this, customName, true);
- usbPlaylists.push_back(mpl);
- wchar_t * pl = _wcsdup(pldir);
- pl[0] = drive;
- RecursiveCreateDirectory(pl);
- wchar_t root[3] = L"X:";
- root[0] = drive;
- openDeviceTable();
- fileProbe(root);
- // sort out and read playlists....
- if (WASABI_API_PLAYLISTMNGR != NULL && WASABI_API_PLAYLISTMNGR != (api_playlistmanager *)1)
- {
- for (std::vector<USBPlaylist*>::const_iterator e = usbPlaylists.begin(); e != usbPlaylists.end(); e++)
- {
- USBPlaylist* playlist = (*e);
- if (playlist && playlist->isMaster() == false)
- {
- WASABI_API_PLAYLISTMNGR->Load(playlist->getFilename(), playlist);
- }
- }
- }
- tag();
- devices.push_back(this);
- extern HWND config;
- if(config) PostMessage(config,WM_USER,0,0);
- SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)this,PMP_IPC_DEVICECONNECTED);
- setupTranscoder();
- loading_devices[drive-'A']=false;
- }
- USBDevice::USBDevice() : transcoder(NULL), drive(0), devType(TYPE_OTHER), pl_write_mode(0), transferQueueLength(0), cacheUpToDate(false), loadedUpToDate(false)
- {
- deviceTable = 0;
- ZeroMemory(ndeDataFile, sizeof(ndeDataFile));
- ZeroMemory(ndeIndexFile, sizeof(ndeIndexFile));
- ZeroMemory(iniFile, sizeof(iniFile));
- ZeroMemory(pldir, sizeof(pldir));
- ZeroMemory(songFormat, sizeof(songFormat));
- ZeroMemory(supportedFormats, sizeof(supportedFormats));
- ZeroMemory(purgeFolders, sizeof(purgeFolders));
- }
- USBDevice::~USBDevice()
- {
- closeDeviceTable();
- if (transcoder) SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(WPARAM)transcoder,PMP_IPC_RELEASE_TRANSCODER);
- }
- //read files from device's folder 'indir'
- void USBDevice::fileProbe(wchar_t * indir) {
- wchar_t dir[MAX_PATH] = {0};
- WIN32_FIND_DATA FindFileData = {0};
- StringCchPrintf(dir,MAX_PATH,L"%s\\*",indir);
- HANDLE hFind = FindFirstFile(dir, &FindFileData);
- if (hFind == INVALID_HANDLE_VALUE) return;
- do {
- if(wcscmp(FindFileData.cFileName,L".") && wcscmp(FindFileData.cFileName,L"..")) {
- wchar_t fullfile[MAX_PATH] = {0};
- StringCchPrintf(fullfile,MAX_PATH,L"%s\\%s",indir,FindFileData.cFileName);
-
- if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //file is directory
- {
- fileProbe(fullfile); //call until we have found a file
- }
- else // found a file!
- {
- wchar_t * ext = wcsrchr(FindFileData.cFileName,'.');
- if(!ext) continue; //no files with extensions in the directory
- ext++;
- if(!_wcsicmp(ext,L"m3u")) // its a playlist
- {
- USBPlaylist *playlist = new USBPlaylist(*this, fullfile, false);
- usbPlaylists.push_back(playlist);
- continue;
- } //its a file
- if(supportedFormat(fullfile,supportedFormats)) //check extension
- {
- UsbSong *s = new UsbSong();
- lstrcpynW(s->filename, fullfile, MAX_PATH);
- this->getMasterPlaylist()->songs.push_back(s); //add track to alltrack list (playlist 0)
- }
- }
- }
- } while(FindNextFile(hFind, &FindFileData) != 0);
- FindClose(hFind);
- }
- int USBDevice::getFileInfoW(const wchar_t *filename, const wchar_t *metadata, wchar_t *dest, size_t len)
- {
- dest[0]=0;
- return AGAVE_API_METADATA->GetExtendedFileInfo(filename, metadata, dest, len);
- }
- // read all metadata from the metadata wasabi service
- void USBDevice::fillMetaData(UsbSong *t)
- {
- if (!t->filled)
- {
- wchar_t tmp[1024] = {0};
- if (getFileInfoW(t->filename,L"artist",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- StringCchCopyW(t->artist, FIELD_LENGTH, tmp);
- t->filled = true;
- }
- if (getFileInfoW(t->filename,L"title",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- StringCchCopyW(t->title, FIELD_LENGTH, tmp);
- t->filled = true;
- }
- if (getFileInfoW(t->filename,L"album",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- StringCchCopyW(t->album, FIELD_LENGTH, tmp);
- t->filled = true;
- }
- if (getFileInfoW(t->filename,L"composer",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- StringCchCopyW(t->composer, FIELD_LENGTH, tmp);
- t->filled = true;
- }
- if (getFileInfoW(t->filename,L"publisher",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- StringCchCopyW(t->publisher, FIELD_LENGTH, tmp);
- t->filled = true;
- }
- if (getFileInfoW(t->filename,L"albumartist",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- StringCchCopyW(t->albumartist, FIELD_LENGTH, tmp);
- t->filled = true;
- }
- if (getFileInfoW(t->filename, L"length",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- t->length = _wtoi(tmp);
- t->filled = true;
- }
- if (getFileInfoW(t->filename, L"track",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- t->track = _wtoi(tmp);
- t->filled = true;
- }
- if (getFileInfoW(t->filename, L"disc",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- t->discnum = _wtoi(tmp);
- t->filled = true;
- }
- if (getFileInfoW(t->filename, L"genre",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- StringCchCopyW(t->genre, FIELD_LENGTH, tmp);
- t->filled = true;
- }
- if (getFileInfoW(t->filename, L"year",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- if (!wcsstr(tmp,L"__") && !wcsstr(tmp,L"/") && !wcsstr(tmp,L"\\") && !wcsstr(tmp,L"."))
- {
- wchar_t *p = tmp;
- while (p && *p)
- {
- if (*p == L'_') *p=L'0';
- p++;
- }
- t->year = _wtoi(tmp);
- t->filled = true;
- }
- }
- if (getFileInfoW(t->filename, L"bitrate",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- t->bitrate = _wtoi(tmp);
- t->filled = true;
- }
- if (getFileInfoW(t->filename, L"size",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- t->size = _wtoi(tmp);
- t->filled = true;
- }
- else
- {
- t->size = fileSize(t->filename);
- t->filled = true;
- }
- if (getFileInfoW(t->filename, L"playcount",tmp,sizeof(tmp)/sizeof(wchar_t)) && tmp[0])
- {
- t->playcount = _wtoi(tmp);
- t->filled = true;
- }
- }
- }
- int USBDevice::openDeviceDatabase()
- {
- Nullsoft::Utility::AutoLock lock(dbcs);
- if (!discDB)
- {
- discDB = NDE_CreateDatabase(plugin.hDllInstance);
- }
- return NDE_USB_SUCCESS;
- }
- void USBDevice::createDeviceFields()
- {
- // create defaults
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_FILENAME, L"filename", FIELD_FILENAME);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_ARTIST, L"artist", FIELD_STRING);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_ALBUM, L"album", FIELD_STRING);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_TITLE, L"title", FIELD_STRING);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_GENRE, L"genre", FIELD_STRING);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_ALBUM_ARTIST, L"albumartist", FIELD_STRING);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_PUBLISHER, L"publisher", FIELD_STRING);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_COMPOSER, L"composer", FIELD_STRING);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_YEAR, L"year", FIELD_INTEGER);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_TRACK, L"track", FIELD_INTEGER);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_BITRATE, L"bitrate", FIELD_INTEGER);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_DISC_NUMBER, L"discnumber", FIELD_INTEGER);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_LENGTH, L"length", FIELD_INTEGER);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_SIZE, L"size", FIELD_INTEGER);
- NDE_Table_NewColumnW(deviceTable, DEVICEVIEW_COL_PLAY_COUNT, L"playcount", FIELD_INTEGER);
- NDE_Table_PostColumns(deviceTable);
- NDE_Table_AddIndexByIDW(deviceTable, 0, L"filename");
- }
- int USBDevice::openDeviceTable() {
- Nullsoft::Utility::AutoLock lock(dbcs);
- int ret = openDeviceDatabase();
- if (ret != NDE_USB_SUCCESS)
- return ret;
- if (!deviceTable)
- {
- deviceTable = NDE_Database_OpenTable(discDB, ndeDataFile, ndeIndexFile,NDE_OPEN_ALWAYS,NDE_CACHE);
- if (deviceTable) {
- createDeviceFields();
- }
- }
- return deviceTable?NDE_USB_SUCCESS:NDE_USB_FAILURE;
- }
- void USBDevice::closeDeviceTable()
- {
- if (deviceTable)
- {
- NDE_Table_Sync(deviceTable);
- NDE_Database_CloseTable(discDB, deviceTable);
- deviceTable=0;
- }
- }
- void USBDevice::CloseDatabase()
- {
- if (discDB)
- NDE_DestroyDatabase(discDB);
- discDB=0;
- }
- static void db_setFieldInt(nde_scanner_t s, unsigned char id, int data)
- {
- nde_field_t f = NDE_Scanner_GetFieldByID(s, id);
- if (!f) f = NDE_Scanner_NewFieldByID(s, id);
- NDE_IntegerField_SetValue(f, data);
- }
- static void db_setFieldString(nde_scanner_t s, unsigned char id, const wchar_t *data)
- {
- nde_field_t f = NDE_Scanner_GetFieldByID(s, id);
- if (!f) f = NDE_Scanner_NewFieldByID(s, id);
- NDE_StringField_SetString(f, data);
- }
- static void db_removeField(nde_scanner_t s, unsigned char id)
- {
- nde_field_t f = NDE_Scanner_GetFieldByID(s, id);
- if (f)
- {
- NDE_Scanner_DeleteField(s, f);
- }
- }
- static int db_getFieldInt(nde_scanner_t s, unsigned char id, int defaultVal)
- {
- nde_field_t f = NDE_Scanner_GetFieldByID(s, id);
- if (f)
- {
- return NDE_IntegerField_GetValue(f);
- }
- else
- {
- return defaultVal;
- }
- }
- static wchar_t* db_getFieldString(nde_scanner_t s, unsigned char id)
- {
- nde_field_t f = NDE_Scanner_GetFieldByID(s, id);
- if (f)
- {
- return NDE_StringField_GetString(f);
- }
- else
- {
- return 0;
- }
- }
- void USBDevice::refreshNDECache(void) {
- tag();
- SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)0,IPC_WRITE_EXTENDED_FILE_INFO);
- }
- int filenamecmp(const wchar_t *f1, const wchar_t *f2)
- {
- for (;;)
- {
- wchar_t c1 = *f1++;
- wchar_t c2 = *f2++;
- if (!c1 && !c2)
- return 0;
- if (!c1)
- return -1;
- if (!c2)
- return 1;
- c1 = towupper(c1);
- c2 = towupper(c2);
- if (c1 == '\\')
- c1 = '/';
- if (c2 == '\\')
- c2 = '/';
- if (c1 < c2)
- return -1;
- else if (c1 > c2)
- return 1;
- }
- }
- //
- UsbSong *USBDevice::findSongInMasterPlaylist(const wchar_t *songfn) {
- USBPlaylist* mpl = this->getMasterPlaylist();
- for (std::vector<UsbSong*>::const_iterator e = mpl->songs.begin(); e != mpl->songs.end(); e++)
- {
- if (filenamecmp(songfn, (*e)->filename) == 0) {
- return (*e);
- }
- }
- return NULL;
- }
- void USBDevice::tag(void)
- {
- /**
- loop thru the newly probed disk
- check for updates on each of the songs
- if there is an update or if metadata does not exist for the file, re-read the metadata
- if there is no update and the song is found in the master playlist, just read from the db
- */
- USBPlaylist *mpl = this->getMasterPlaylist();
- int top = (int)mpl->songs.size();
- //first load in all songs data from ID3 - this is what we were trying to avoid
- for(int i = 0; i < top; i++)
- {
- UsbSong *t = (UsbSong *)mpl->songs.at(i);
- // now check if this song has changed
- // check if the nde cache exists in the first place
- if (songChanged(t))
- {
- this->fillMetaData(t);
- // now since we've refreshed the metadata write to NDE
- this->writeRecordToDB(t);
- }
- else
- {
- // read the record from NDE
- if (this->readRecordFromDB(t) == false)
- {
- this->fillMetaData(t);
- this->writeRecordToDB(t);
- }
- }
- }
- for (size_t i=0;i<usbPlaylists.size();i++)
- {
- USBPlaylist *pl = usbPlaylists[i];
- if (pl->dirty)
- {
- // Lets delete the current playlist file
- _wunlink(pl->filename);
- USBPlaylistSaver playlistSaver(pl->filename, L"autosaved", pl);
- playlistSaver.Save();
- pl->dirty = false;
- }
- }
- cacheUpToDate = true;
- loadedUpToDate = true;
- }
- // check change in filetimes for the song
- bool USBDevice::songChanged(UsbSong* song)
- {
- if (!song) return true;
- if (!PathFileExists(ndeDataFile)) return true;
- //For fLastAccess/LastWrite information, use GetFileAttributesEx
- WIN32_FILE_ATTRIBUTE_DATA cacheFileInfo, tempInfo;
- GetFileAttributesExW(ndeDataFile, GetFileExInfoStandard, (LPVOID)&cacheFileInfo);
- if(song->filename)
- {
- GetFileAttributesExW(song->filename, GetFileExInfoStandard, (LPVOID)&tempInfo);
- }
- else
- {
- return true;
- }
- //cachetime - song time
- if(CompareFileTime(&cacheFileInfo.ftLastWriteTime, &tempInfo.ftLastWriteTime) < 0)
- {
- return true;
- }
- return false;
- }
- // read metadata for a specific song from the NDE cache
- bool USBDevice::readRecordFromDB(UsbSong* song)
- {
- if (!song) return false;
- Nullsoft::Utility::AutoLock lock(dbcs);
- openDeviceTable();
- nde_scanner_t scanner = NDE_Table_CreateScanner(deviceTable);
- if (NDE_Scanner_LocateFilename(scanner, DEVICEVIEW_COL_FILENAME, FIRST_RECORD, song->filename))
- {
- nde_field_t artist = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_ARTIST);
- wchar_t* artistString = NDE_StringField_GetString(artist);
- lstrcpyn(song->artist, artistString, FIELD_LENGTH);
- nde_field_t album = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_ALBUM);
- wchar_t* albumString = NDE_StringField_GetString(album);
- lstrcpyn(song->album, albumString, FIELD_LENGTH);
- nde_field_t albumArtist = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_ALBUM_ARTIST);
- wchar_t* albumArtistString = NDE_StringField_GetString(albumArtist);
- lstrcpyn(song->albumartist, albumArtistString, FIELD_LENGTH);
- nde_field_t publisher = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_PUBLISHER);
- wchar_t* publisherString = NDE_StringField_GetString(publisher);
- lstrcpyn(song->publisher, publisherString, FIELD_LENGTH);
- nde_field_t composer = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_COMPOSER);
- wchar_t* composerString = NDE_StringField_GetString(composer);
- lstrcpyn(song->composer, composerString, FIELD_LENGTH);
- nde_field_t title = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_TITLE);
- wchar_t* titleString = NDE_StringField_GetString(title);
- lstrcpyn(song->title, titleString, FIELD_LENGTH);
- nde_field_t genre = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_GENRE);
- wchar_t* genreString = NDE_StringField_GetString(genre);
- lstrcpyn(song->genre, genreString, FIELD_LENGTH);
- nde_field_t track = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_TRACK);
- int trackInt= NDE_IntegerField_GetValue(track);
- song->track = trackInt;
- nde_field_t year = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_YEAR);
- int yearInt= NDE_IntegerField_GetValue(year);
- song->year = yearInt;
- nde_field_t discNumber = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_DISC_NUMBER);
- int discNumberInt= NDE_IntegerField_GetValue(discNumber);
- song->discnum = discNumberInt;
- nde_field_t length = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_LENGTH);
- int lengthInt= NDE_IntegerField_GetValue(length);
- song->length = lengthInt;
- nde_field_t bitrate = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_BITRATE);
- int bitrateInt= NDE_IntegerField_GetValue(bitrate);
- song->bitrate = bitrateInt;
- nde_field_t size = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_SIZE);
- int sizeInt= NDE_IntegerField_GetValue(size);
- song->size = sizeInt;
- nde_field_t playcount = NDE_Scanner_GetFieldByID(scanner, DEVICEVIEW_COL_PLAY_COUNT);
- int playcountInt = NDE_IntegerField_GetValue(playcount);
- song->playcount = playcountInt;
- }
- else
- {
- return false;
- }
- NDE_Table_DestroyScanner(deviceTable, scanner);
- //closeDeviceTable();
- return true;
- }
- // write a single record to the nde database
- void USBDevice::writeRecordToDB(UsbSong* songToPrint) {
- Nullsoft::Utility::AutoLock lock(dbcs);
- openDeviceTable();
- nde_scanner_t s = NDE_Table_CreateScanner(deviceTable);
- if (! NDE_Scanner_LocateFilename(s, DEVICEVIEW_COL_FILENAME, FIRST_RECORD, songToPrint->filename))
- {
- NDE_Scanner_New(s);
- }
- if (songToPrint->filename)
- {
- db_setFieldString(s, DEVICEVIEW_COL_FILENAME, songToPrint->filename);
- }
- if (songToPrint->artist)
- {
- db_setFieldString(s, DEVICEVIEW_COL_ARTIST, songToPrint->artist);
- }
- if (songToPrint->albumartist)
- {
- db_setFieldString(s, DEVICEVIEW_COL_ALBUM_ARTIST, songToPrint->albumartist);
- }
- if (songToPrint->publisher)
- {
- db_setFieldString(s, DEVICEVIEW_COL_PUBLISHER, songToPrint->publisher);
- }
- if (songToPrint->composer)
- {
- db_setFieldString(s, DEVICEVIEW_COL_COMPOSER, songToPrint->composer);
- }
- if (songToPrint->album)
- {
- db_setFieldString(s, DEVICEVIEW_COL_ALBUM, songToPrint->album);
- }
- if (songToPrint->title)
- {
- db_setFieldString(s, DEVICEVIEW_COL_TITLE, songToPrint->title);
- }
- if (songToPrint->genre)
- {
- db_setFieldString(s, DEVICEVIEW_COL_GENRE, songToPrint->genre);
- }
- if (songToPrint->year)
- {
- db_setFieldInt(s, DEVICEVIEW_COL_YEAR, songToPrint->year);
- }
- if (songToPrint->track)
- {
- db_setFieldInt(s, DEVICEVIEW_COL_TRACK, songToPrint->track);
- }
- if (songToPrint->bitrate)
- {
- db_setFieldInt(s, DEVICEVIEW_COL_BITRATE, songToPrint->bitrate);
- }
- if (songToPrint->discnum)
- {
- db_setFieldInt(s, DEVICEVIEW_COL_DISC_NUMBER, songToPrint->discnum);
- }
- if (songToPrint->length)
- {
- db_setFieldInt(s, DEVICEVIEW_COL_LENGTH, songToPrint->length);
- }
- if (songToPrint->size)
- {
- db_setFieldInt(s, DEVICEVIEW_COL_SIZE, (int)songToPrint->size);
- }
- if (songToPrint->playcount)
- {
- db_setFieldInt(s, DEVICEVIEW_COL_PLAY_COUNT, songToPrint->playcount);
- }
- NDE_Scanner_Post(s);
- NDE_Table_DestroyScanner(deviceTable, s);
- //NDE_Table_Sync(deviceTable);
- //closeDeviceTable();
- }
- void USBDevice::setupTranscoder() {
- if(transcoder) SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(WPARAM)transcoder,PMP_IPC_RELEASE_TRANSCODER);
- transcoder = (Transcoder*)SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(WPARAM)this,PMP_IPC_GET_TRANSCODER);
- if(!transcoder) return;
-
- wchar_t * p = supportedFormats;
- while(p && *p) {
- wchar_t * np = wcschr(p,L';');
- if(np) *np = 0;
- transcoder->AddAcceptableFormat(p);
- if(np) { *np = L';'; p=np+1; }
- else return;
- }
- }
- BOOL CALLBACK browseEnumProc(HWND hwnd, LPARAM lParam)
- {
- wchar_t cl[32] = {0};
- GetClassNameW(hwnd, cl, ARRAYSIZE(cl));
- if (!lstrcmpiW(cl, WC_TREEVIEW))
- {
- PostMessage(hwnd, TVM_ENSUREVISIBLE, 0, (LPARAM)TreeView_GetSelection(hwnd));
- return FALSE;
- }
- return TRUE;
- }
- wchar_t pldir[MAX_PATH] = {0};
- int CALLBACK WINAPI BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
- {
- if(uMsg == BFFM_INITIALIZED)
- {
- SendMessageW(hwnd, BFFM_SETSELECTIONW, 1, (LPARAM)pldir);
- // this is not nice but it fixes the selection not working correctly on all OSes
- EnumChildWindows(hwnd, browseEnumProc, 0);
- }
- return 0;
- }
- static INT_PTR CALLBACK prefs_dialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam) {
- static USBDevice * dev;
- switch(uMsg) {
- case WM_INITDIALOG:
- {
- prefsParam* p = (prefsParam*)lParam;
- dev = (USBDevice*)p->dev;
- p->config_tab_init(hwndDlg,p->parent);
- SetDlgItemTextW(hwndDlg,IDC_NAMEFORMAT,dev->songFormat);
- SetDlgItemTextW(hwndDlg,IDC_PLDIR,dev->pldir);
- SetDlgItemTextW(hwndDlg,IDC_SUPPORTEDFORMATS,dev->supportedFormats);
- if(dev->purgeFolders[0]=='1') CheckDlgButton(hwndDlg,IDC_PURGEFOLDERS,BST_CHECKED);
- else CheckDlgButton(hwndDlg,IDC_PURGEFOLDERS,BST_UNCHECKED);
- SendDlgItemMessageW(hwndDlg,IDC_PL_WRITE_COMBO,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRINGW(IDS_SLASH_AT_START));
- SendDlgItemMessageW(hwndDlg,IDC_PL_WRITE_COMBO,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRINGW(IDS_DOT_AT_START));
- SendDlgItemMessageW(hwndDlg,IDC_PL_WRITE_COMBO,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRINGW(IDS_NO_SLASH_OR_DOT));
- SendDlgItemMessage(hwndDlg,IDC_PL_WRITE_COMBO,CB_SETCURSEL,dev->pl_write_mode,0);
- SetDlgItemTextW(hwndDlg,IDC_PL_WRITE_EG,WASABI_API_LNGSTRINGW(IDS_EG_SLASH+dev->pl_write_mode));
- }
- break;
- case WM_COMMAND:
- switch(LOWORD(wParam))
- {
- case IDC_NAMEFORMAT:
- if(HIWORD(wParam)==EN_CHANGE)
- {
- GetDlgItemTextW(hwndDlg,IDC_NAMEFORMAT,dev->songFormat,sizeof(dev->songFormat)/sizeof(wchar_t));
- WritePrivateProfileStringW(L"pmp_usb",L"songFormat",dev->songFormat,dev->iniFile);
- }
- break;
-
- case IDC_PLDIR:
- if(HIWORD(wParam)==EN_CHANGE)
- {
- GetDlgItemTextW(hwndDlg,IDC_PLDIR,dev->pldir,sizeof(dev->pldir)/sizeof(wchar_t));
- WritePrivateProfileStringW(L"pmp_usb",L"pldir",dev->pldir,dev->iniFile);
- }
- break;
- case IDC_SUPPORTEDFORMATS:
- if(HIWORD(wParam)==EN_CHANGE)
- {
- GetDlgItemTextW(hwndDlg,IDC_SUPPORTEDFORMATS,dev->supportedFormats,sizeof(dev->supportedFormats)/sizeof(wchar_t));
- WritePrivateProfileStringW(L"pmp_usb",L"supportedFormats",dev->supportedFormats,dev->iniFile);
- }
- break;
- case IDC_REFRESHCACHE:
- {
- char titleStr[32] = {0};
- dev->refreshNDECache();
- MessageBoxA(hwndDlg,WASABI_API_LNGSTRING(IDS_CACHE_UPDATED),
- WASABI_API_LNGSTRING_BUF(IDS_SUCCESS,titleStr,32),MB_OK);
- break;
- }
- case IDC_PL_WRITE_COMBO:
- {
- dev->pl_write_mode = (int)SendMessage((HWND)lParam,CB_GETCURSEL,0,0);
- SetDlgItemTextW(hwndDlg,IDC_PL_WRITE_EG,WASABI_API_LNGSTRINGW(IDS_EG_SLASH+dev->pl_write_mode));
-
- wchar_t tmp[16] = {0};
- StringCchPrintf(tmp, 16, L"%d", dev->pl_write_mode);
- WritePrivateProfileStringW(L"pmp_usb",L"pl_write_mode",tmp,dev->iniFile);
- break;
- }
- case IDC_FILENAMEHELP:
- {
- char titleStr[64] = {0};
- MessageBoxA(hwndDlg,WASABI_API_LNGSTRING(IDS_FILENAME_FORMATTING_INFO),
- WASABI_API_LNGSTRING_BUF(IDS_FILENAME_FORMAT_HELP,titleStr,64),MB_OK);
- }
- break;
-
- case IDC_PLBROWSE:
- {
- wchar_t *tempWS;
- BROWSEINFO bi = {0};
- LPMALLOC lpm = 0;
- wchar_t bffFileName[MAX_PATH] = {0};
- bi.hwndOwner = hwndDlg;
- bi.pszDisplayName = bffFileName;
- bi.lpszTitle = WASABI_API_LNGSTRINGW(IDS_SELECT_FOLDER_TO_LOAD_PLAYLISTS);
- bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_EDITBOX | BIF_NEWDIALOGSTYLE;
- bi.lpfn = BrowseCallbackProc;
- lstrcpynW(pldir, dev->pldir, MAX_PATH);
- LPITEMIDLIST iil = SHBrowseForFolder(&bi);
- if(iil)
- {
- SHGetPathFromIDListW(iil,bffFileName);
- SHGetMalloc(&lpm);
- // path is now in bffFileName
- }
- tempWS = _wcsdup(bffFileName);
- if(tempWS[0] == dev->drive)
- {
- lstrcpynW(dev->pldir, tempWS, MAX_PATH);
- SetDlgItemText(hwndDlg,IDC_PLDIR,tempWS);
- }
- else
- {
- if(bffFileName[0] != 0) //dont print error if the user selected 'cancel'
- {
- char titleStr[32] = {0};
- MessageBoxA(hwndDlg,WASABI_API_LNGSTRING(IDS_ERR_SELECTED_PATH_NOT_ON_DEVICE),
- WASABI_API_LNGSTRING_BUF(IDS_ERROR,titleStr,32), MB_OK);
- }
- }
- free(tempWS);
- }
- break;
-
- case IDC_FORMATSHELP:
- {
- char titleStr[64] = {0};
- MessageBoxA(hwndDlg,WASABI_API_LNGSTRING(IDS_SUPPORTED_FORMAT_INFO),
- WASABI_API_LNGSTRING_BUF(IDS_SUPPORTED_FORMAT_HELP,titleStr,64),MB_OK);
- }
- break;
- case IDC_PURGEFOLDERS:
- {
- StringCchCopy(dev->purgeFolders, ARRAYSIZE(dev->purgeFolders),
- ((IsDlgButtonChecked(hwndDlg,IDC_PURGEFOLDERS) == BST_CHECKED) ? L"1" : L"0"));
- WritePrivateProfileStringW(L"pmp_usb",L"purgeFolders",dev->purgeFolders,dev->iniFile);
- }
- break;
- case IDC_RESCAN:
- {
- //update changes
- SetFileAttributesW(dev->iniFile,FILE_ATTRIBUTE_HIDDEN);
- wchar_t driveletter = dev->drive; //hold on to driveletter before it goes away
- //disconnect
- dev->Close();
- //connect
- pmpDeviceLoading load;
- dev = new USBDevice(driveletter,&load);
- char titleStr[64] = {0};
- MessageBoxA(hwndDlg,WASABI_API_LNGSTRING(IDS_RESCAN_COMPLETE_SAVED),
- WASABI_API_LNGSTRING_BUF(IDS_RESCAN_COMPLETE,titleStr,64),MB_OK);
- }
- break;
- }
- }
- return 0;
- }
- // update a track with new metadata (string)
- void USBDevice::updateTrackField(UsbSong* song, unsigned int col, const void* newValue, int fieldType)
- {
- if (!song) return;
- Nullsoft::Utility::AutoLock lock(dbcs);
- openDeviceTable();
- nde_scanner_t s = NDE_Table_CreateScanner(deviceTable);
- if (NDE_Scanner_LocateFilename(s, DEVICEVIEW_COL_FILENAME, FIRST_RECORD, song->filename))
- {
- switch (fieldType)
- {
- case FIELD_STRING:
- db_setFieldString(s, col, (wchar_t *)(newValue));
- break;
- case FIELD_INTEGER:
- db_setFieldInt(s, col, *((int *)newValue));
- default:
- break;
- }
- }
- NDE_Scanner_Post(s);
- NDE_Table_DestroyScanner(deviceTable, s);
- //NDE_Table_Sync(deviceTable);
- //closeDeviceTable();
- }
- UsbSong::UsbSong() {
- filename[0]=artist[0]=album[0]=title[0]=genre[0]=albumartist[0]=publisher[0]=composer[0]=0;
- filled=year=track=length=discnum=bitrate=playcount=(int)(size=0);
- }
- USBArt::USBArt(ARGB32 *bits, int w, int h) :bits(bits), w(w), h(h)
- {
- }
- USBArt::~USBArt()
- {
- if (bits)
- WASABI_API_MEMMGR->sysFree(bits);
- }
|