12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241 |
- #define SKIP_OVER
- #include "main.h"
- #include "api__in_cdda.h"
- #include "CDPlay.h"
- #include "DAEPlay.h"
- #include "MCIPlay.h"
- #include "WindacPlay.h"
- #include "cddb.h"
- #include "../nu/AutoWide.h"
- #include "../nu/AutoChar.h"
- #include "../nde/ndestring.h"
- #include "../nu/ListView.h"
- #ifndef IGNORE_API_GRACENOTE
- #include "../primo/obj_primo.h"
- #endif
- #include "../Winamp/wa_ipc.h"
- #include <api/service/waservicefactory.h>
- #include <shlwapi.h>
- #include <atlbase.h>
- #include <strsafe.h>
- #if 0
- BOOL CALLBACK ripConfigProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
- #endif
- static int cachedev_used;
- static MCIDEVICEID cachedev;
- static wchar_t last_fn[8];
- extern "C" __declspec(dllexport) int winampGetExtendedFileInfoW(const wchar_t *fn, const char *data, wchar_t *dest, int destlen)
- {
- s_last_error = NULL;
- if (!_stricmp(data, "type"))
- {
- lstrcpynW(dest, L"0", destlen); //audio
- return 1;
- }
- else if (!_stricmp(data, "family"))
- {
- LPCWSTR e, p(NULL);
- DWORD lcid;
- e = PathFindExtensionW(fn);
- if (L'.' != *e) return 0;
- e++;
- lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
- if (CSTR_EQUAL == CompareStringW(lcid, NORM_IGNORECASE, e, -1, L"CDA", -1)) p = WASABI_API_LNGSTRINGW(IDS_FAMILY_STRING);
- if (p && S_OK == StringCchCopyW(dest, destlen, p)) return 1;
- return 0;
- }
- else if (!_stricmp(data, "ext_cdda"))
- {
- lstrcpynW(dest, L"1", destlen); //audio
- return 1;
- }
- // TODO determine if we even keep any of this...
- /*
- else if (!_stricmp(data, "cdda_config_text"))
- {
- WASABI_API_LNGSTRINGW_BUF(IDS_RIPPING,dest,destlen);
- return 1;
- }
- else if (!_strnicmp(data, "cdda_cf_", 8))
- {
- HWND parent = (HWND)atoi(data + 8);
- dest[0] = 0;
- if (parent && IsWindow(parent))
- {
- parent = WASABI_API_CREATEDIALOGW(IDD_PREFS_CDRIP, parent, ripConfigProc);
- _itow((int)parent, dest, 10);
- }
- return 1;
- }
- */
- if (!lstrcmpiW(PathFindExtensionW(fn), L".cda") && !_wcsnicmp(fn + 1, L":\\track", 7)) // stupid hack, converts x:\\trackXX.cda to cda://x,XX
- {
- static wchar_t fakebuf[128];
- StringCchPrintf(fakebuf, 128, L"cda://%c,%d", fn[0], _wtoi(PathFindFileNameW(fn) + 5));
- fn = fakebuf;
- }
- if (!_wcsnicmp(fn, L"cda://", 6)) // determine length of cd track via MCI
- {
- int track = lstrlenW(fn) > 8 ? _wtoi(fn + 8) : 0;
- int device = fn[6];
- if (device >= 'a' && device <= 'z') device += 'A' -'a';
- MCIDEVICEID dev2 = 0;
- if (cachedev_used) dev2 = cachedev;
- if (!_stricmp(data, "discid") || !_stricmp(data, "cddbid"))
- {
- dest[0] = 0;
- #ifdef DISCID
- DiscId *disc = discid_new();
- wchar_t drive[4] = {device, L':'};
- if (!discid_read_sparse(disc, drive, 0)) {
- discid_free(disc);
- return 0;
- }
- if (!_stricmp(data, "cddbid"))
- lstrcpynW(dest, AutoWide(discid_get_freedb_id(disc)), destlen);
- else
- lstrcpynW(dest, AutoWide(discid_get_id(disc)), destlen);
- discid_free(disc);
- #endif
- }
- else if (!_stricmp(data, "cdengine"))
- {
- dest[0] = 0;
- if (g_cdplay && device && g_cdplay->IsPlaying(device))
- {
- if (g_cdplay == daePlayer)
- lstrcpynW(dest, L"DAE", destlen);
- else if (g_cdplay == windacPlayer)
- {
- if (hDLL)
- lstrcpynW(dest, L"ASPI", destlen);
- else
- lstrcpynW(dest, L"SPTI", destlen);
- }
- else if (g_cdplay == mciPlayer)
- lstrcpynW(dest, L"MCI", destlen);
- }
- return 1;
- }
- else if (!_stricmp(data, "<begin>"))
- {
- if (!CDOpen(&cachedev, device, L"cache"))
- cachedev = 0;
-
- if (NULL != dest && destlen > 1)
- {
- dest[0] = (NULL != cachedev) ? L'1' : L'0';
- dest[1] = L'\0';
- }
-
- cachedev_used = 1;
- //OutputDebugString("begin device caching\n");
- }
- else if (!_stricmp(data, "<end>"))
- {
- if (cachedev_used && cachedev)
- CDClose(&cachedev);
- //OutputDebugString("end device caching\n");
- cachedev_used = 0;
- cachedev = 0;
- }
- else if (!_stricmp(data, "<eject>"))
- {
- if (!cachedev_used)
- {
- if (!CDOpen(&dev2, device, L"eject"))
- dev2 = 0;
- }
- if (dev2)
- {
- CDEject(dev2);
- if (dev2 != cachedev)
- CDClose(&dev2);
- }
- }
- else if (!_stricmp(data, "ntracks"))
- {
- if (!cachedev_used)
- {
- if (!CDOpen(&dev2, device, L"ntracks")) dev2 = 0;
- }
- if (dev2)
- {
- _itow(CDGetTracks(dev2), dest, 10);
- if (dev2 != cachedev) CDClose(&dev2);
- }
- else
- {
- if (NULL != dest && destlen > 1)
- {
- dest[0] = L'0';
- dest[1] = L'\0';
- }
- }
- }
- else if (!_stricmp(data, "tracktype"))
- {
- if (!cachedev_used)
- {
- if (!CDOpen(&dev2, device, L"tracktype")) dev2 = 0;
- }
- if (dev2)
- {
- MCI_STATUS_PARMS sMCIStatus;
- sMCIStatus.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
- sMCIStatus.dwTrack = track;
- if (mciSendCommand(dev2, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) &sMCIStatus))
- WASABI_API_LNGSTRINGW_BUF(IDS_UNKNOWN,dest,destlen);
- else lstrcpynW(dest, (sMCIStatus.dwReturn != MCI_CDA_TRACK_AUDIO ? L"data" : L"audio"), destlen);
- if (dev2 != cachedev) CDClose(&dev2);
- }
- }
- else if (!_stricmp(data, "length"))
- {
- if (!cachedev_used)
- {
- if (!CDOpen(&dev2, device, L"length")) dev2 = 0;
- }
- if (dev2)
- {
- MCI_SET_PARMS sMCISet;
- sMCISet.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
- MCISendCommand(dev2, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)(LPVOID) &sMCISet);
- _itow(CDGetTrackLength(dev2, track), dest, 10);
- sMCISet.dwTimeFormat = MCI_FORMAT_TMSF;
- MCISendCommand(dev2, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)(LPVOID) &sMCISet);
- if (dev2 != cachedev)
- CDClose(&dev2);
- }
- }
- else if (!_stricmp(data, "album") || !_stricmp(data, "artist") ||
- !_stricmp(data, "year") || !_stricmp(data, "genre") ||
- !_stricmp(data, "title") || !_stricmp(data, "comment") ||
- !_stricmp(data, "tuid") || !_stricmp(data, "albumartist") ||
- !_stricmp(data, "publisher") || !_stricmp(data, "disc") ||
- !_stricmp(data, "conductor") || !_stricmp(data, "composer") ||
- !_stricmp(data, "remixing") || !_stricmp(data, "isrc") ||
- !_stricmp(data, "GracenoteFileID") || !_stricmp(data, "GracenoteExtData")
- )
- {
- int cached = 0;
- //cache our myps
- static DINFO myps;
- /*static unsigned int last_time;
- unsigned int now = GetTickCount();*/
- cached = !_wcsnicmp(fn, last_fn, 7);
- // TODO disabled as this is causing more access issues than it seems to help...
- /*if (cached)
- {
- if (now > last_time + 1000) cached = 0;
- if (now < last_time - 1000) cached = 0; // counter wrapped
- }*/
- if (!cached)
- {
- lstrcpynW(last_fn, fn, 8);
- memset(&myps, 0, sizeof(myps));
- if (!cachedev_used)
- {
- if (CDOpen(&dev2, device, L"extinfo"))
- {
- GetDiscID(dev2, &myps);
- CDClose(&dev2);
- }
- }
- else GetDiscID(dev2, &myps);
- }
- if (myps.CDDBID)
- {
- // try to get CDDB information and then revert to CD-Text if CDDB is not available
- if (GetCDDBInfo(&myps, device))
- {
- wchar_t cache[] = {L"cda://x"};
- cache[6] = device;
- PostMessage(line.hMainWindow, WM_WA_IPC, (WPARAM)cache, IPC_REFRESHPLCACHE);
- }
- else if (!cached && !myps.populated)
- {
- if (DoCDText(&myps, device))
- {
- wchar_t cache[] = {L"cda://x"};
- cache[6] = device;
- PostMessage(line.hMainWindow, WM_WA_IPC, (WPARAM)cache, IPC_REFRESHPLCACHE);
- }
- }
- if (!_stricmp(data, "album"))
- {
- if (myps.title)
- lstrcpynW(dest, myps.title, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "artist") && track>0 && track<100)
- {
- if (myps.tracks[track-1].artist)
- lstrcpynW(dest, myps.tracks[track-1].artist, destlen);
- else if (myps.artist)
- lstrcpynW(dest, myps.artist, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "albumartist"))
- {
- if (myps.artist)
- lstrcpynW(dest, myps.artist, destlen);
- else if (track == 0)
- WASABI_API_LNGSTRINGW_BUF(IDS_UNKNOWN_ARTIST,dest,destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "title") && track>0 && track<100)
- {
- if (myps.tracks[track-1].title)
- lstrcpynW(dest, myps.tracks[track-1].title, destlen);
- else
- StringCchPrintfW(dest, destlen, WASABI_API_LNGSTRINGW(IDS_TRACK_X), track);
- }
- else if (!_stricmp(data, "year"))
- {
- if (myps.year)
- lstrcpynW(dest, myps.year, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "genre"))
- {
- if (myps.genre)
- lstrcpynW(dest, myps.genre, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "comment"))
- {
- if (myps.notes)
- lstrcpynW(dest, myps.notes, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "publisher"))
- {
- if (myps.label)
- lstrcpynW(dest, myps.label, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "composer"))
- {
- if (track>0 && myps.tracks[track-1].composer)
- lstrcpynW(dest, myps.tracks[track-1].composer, destlen);
- else if (myps.composer)
- lstrcpynW(dest, myps.composer, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "remixing"))
- {
- if (track>0 && myps.tracks[track-1].remixing)
- lstrcpynW(dest, myps.tracks[track-1].remixing, destlen);
- else if (myps.composer)
- lstrcpynW(dest, myps.remixing, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "conductor"))
- {
- if (track>0 && myps.tracks[track-1].conductor)
- lstrcpynW(dest, myps.tracks[track-1].conductor, destlen);
- else if (myps.conductor)
- lstrcpynW(dest, myps.conductor, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "isrc") && track>0 && track<100)
- {
- if (myps.tracks[track-1].isrc)
- lstrcpynW(dest, myps.tracks[track-1].isrc, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "GracenoteFileID") && track>0 && track<100)
- {
- if (myps.tracks[track-1].tagID)
- lstrcpynW(dest, myps.tracks[track-1].tagID, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "GracenoteExtData") && track>0 && track<100)
- {
- if (myps.tracks[track-1].extData)
- lstrcpynW(dest, myps.tracks[track-1].extData, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "tuid"))
- {
- if (myps.tuid)
- lstrcpynW(dest, myps.tuid, destlen);
- else
- dest[0]=0;
- }
- else if (!_stricmp(data, "disc"))
- {
- if (myps.numdiscs > 0)
- StringCchPrintf(dest, destlen, L"%u/%u", myps.discnum, myps.numdiscs);
- else if (myps.discnum)
- StringCchPrintf(dest, destlen, L"%u", myps.discnum);
- else
- dest[0] = 0;
- }
- else
- {
- // last_time = GetTickCount();
- return 0;// some error condition (such as track == 0) got us here
- }
- }
- else
- {
- if (!_stricmp(data, "title") && track>0 && track<100)
- {
- StringCchPrintfW(dest, destlen, WASABI_API_LNGSTRINGW(IDS_TRACK_X), track);
- }
- last_fn[0] = 0x00;
- }
- // last_time = GetTickCount();
- }
- else if (!_stricmp(data, "cdtype"))
- {
- dest[0] = 0;
- #ifndef IGNORE_API_GRACENOTE
- DWORD retCode = PRIMOSDK_OK + 1;
- obj_primo *primo=0;
- waServiceFactory *sf = line.service->service_getServiceByGuid(obj_primo::getServiceGuid());
- if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
- if (primo)
- {
- DWORD unit = (DWORD)fn[6];
- DWORD mediumtype;
- DWORD mediumformat;
- DWORD erasable;
- DWORD tracks, used, free;
- retCode = primo->DiscInfo(&unit, &mediumtype, &mediumformat, &erasable, &tracks, &used, &free);
- if (retCode == PRIMOSDK_OK)
- {
- if (mediumformat > 0xf0 && mediumformat < 0xff) lstrcpynW(dest, L"DVD", destlen);
- else lstrcpynW(dest, L"CD", destlen);
- if (mediumtype == PRIMOSDK_BLANK || mediumtype == PRIMOSDK_COMPLIANTGOLD) StringCchCatW(dest, destlen, L"R");
- if (erasable) StringCchCatW(dest, destlen, L"W");
- }
- sf->releaseInterface(primo);
- }
- return (retCode == PRIMOSDK_OK);
- #else
- return 0;
- #endif
- }
- else if (!_stricmp(data, "cdtype2"))
- {
- dest[0] = 0;
- #ifndef IGNORE_API_GRACENOTE
- DWORD retCode = PRIMOSDK_OK + 1;
- obj_primo *primo=0;
- waServiceFactory *sf = line.service->service_getServiceByGuid(obj_primo::getServiceGuid());
- if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
- if (primo)
- {
- DWORD unit = (DWORD)fn[6];
- DWORD mediumType;
- DWORD mediumFormat;
- DWORD erasable;
- DWORD tracks, used, free;
- DWORD medium = -1, protectedDVD = -1, mediumEx = -1;
- DWORD rfu;
- retCode = primo->DiscInfoEx(&unit, 1, &mediumType, &mediumFormat, &erasable, &tracks, &used, &free);
- if (retCode == PRIMOSDK_OK)
- {
- primo->DiscInfo2(&unit, &medium, &protectedDVD, NULL, &mediumEx, &rfu);
- //format: mediumType;mediumFormat;mediumEx;protectedDVD;erasable;tracks;used;free
- StringCchPrintfW(dest, destlen, L"%d;%d;%d;%d;%d;%d;%d;%d", mediumType, mediumFormat, mediumEx, protectedDVD, erasable, tracks, used, free);
- }
- sf->releaseInterface(primo);
- }
- return (retCode == PRIMOSDK_OK);
- #else
- return 0;
- #endif
- }
- else if (!_stricmp(data, "cdlengths"))
- {
- dest[0] = 0;
- #ifndef IGNORE_API_GRACENOTE
- obj_primo *primo=0;
- waServiceFactory *sf = line.service->service_getServiceByGuid(obj_primo::getServiceGuid());
- if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
- if (primo)
- {
- DWORD unit = (DWORD)fn[6];
- DWORD mediumtype;
- DWORD mediumformat;
- DWORD erasable;
- DWORD tracks, used, free;
- if (primo->DiscInfo(&unit, &mediumtype, &mediumformat, &erasable, &tracks, &used, &free) == PRIMOSDK_OK)
- {
- StringCchPrintfW(dest, destlen, L"%d,%d", free, used);
- }
- sf->releaseInterface(primo);
- }
- #endif
- }
- else if (!_stricmp(data, "cdspeeds"))
- {
- dest[0] = 0;
- #ifndef IGNORE_API_GRACENOTE
- DWORD retCode = PRIMOSDK_OK + 1;
- obj_primo *primo=0;
- waServiceFactory *sf = line.service->service_getServiceByGuid(obj_primo::getServiceGuid());
- if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
- if (primo)
- {
- DWORD unit = (DWORD)fn[6];
- DWORD cdspeeds[32];
- DWORD dvdspeeds[32];
- DWORD capabilities;
- retCode = primo->UnitSpeeds(&unit, (unsigned long *) & cdspeeds, (unsigned long *) & dvdspeeds, &capabilities);
- if (retCode == PRIMOSDK_OK)
- {
- wchar_t *p = dest;
- //reading speeds
- int i;
- for (i = 0;cdspeeds[i] != 0xFFFFFFFF;i++);
- i++;
- //CD-R speeds
- for (;cdspeeds[i] != 0xFFFFFFFF;i++)
- {
- StringCchPrintfW(p, destlen, L"%d", cdspeeds[i]);
- StringCchCatW(p, destlen, L"/");
- p += lstrlenW(p);
- }
- *p = ';';
- p++;
- i++;
- //CD-RW speeds
- for (;cdspeeds[i] != 0xFFFFFFFF;i++)
- {
- StringCchPrintfW(p, destlen, L"%d", cdspeeds[i]);
- StringCchCatW(p, destlen, L"/");
- p += lstrlenW(p);
- }
- }
- sf->releaseInterface(primo);
- }
- return (retCode == PRIMOSDK_OK);
- #else
- return 0;
- #endif
- }
- else if (!_stricmp(data, "cdinfo"))
- {
- dest[0] = 0;
- #ifndef IGNORE_API_GRACENOTE
- DWORD retCode = PRIMOSDK_OK + 1;
- obj_primo *primo=0;
- waServiceFactory *sf = line.service->service_getServiceByGuid(obj_primo::getServiceGuid());
- if (sf) primo = reinterpret_cast<obj_primo *>(sf->getInterface());
- if (primo)
- {
- DWORD unit = (DWORD)fn[6];
- DWORD type;
- BYTE szUnitDescr[64 + 1] = {0,}; // Unit Vendor, Model and FW. version
- retCode = primo->UnitInfo(&unit, &type, szUnitDescr, NULL);
- if (retCode == PRIMOSDK_OK)
- {
- StringCchPrintfW(dest, destlen, L"%d;%s", type, (wchar_t *)AutoWide((char *)szUnitDescr));
- }
- sf->releaseInterface(primo);
- }
- return (retCode == PRIMOSDK_OK);
- #else
- return 0;
- #endif
- }
- else if (!_stricmp(data, "cdlock"))
- {
- dest[0] = 0;
- #ifndef IGNORE_API_GRACENOTE
- if (!m_veritas_handle)
- {
- waServiceFactory *sf = line.service->service_getServiceByGuid(obj_primo::getServiceGuid());
- if (sf) m_veritas_handle = reinterpret_cast<obj_primo *>(sf->getInterface());
- }
- if (!m_veritas_handle)
- return 0;
- m_nblock++;
- DWORD unit = (DWORD)fn[6];
- m_veritas_handle->UnitLock(&unit, PRIMOSDK_LOCK);
- lstrcpynW(dest, L"locked", destlen);
- return 1;
- #else
- return 0;
- #endif
- }
- else if (!_stricmp(data, "cdunlock"))
- {
- if (!m_nblock) return 0;
- #ifndef IGNORE_API_GRACENOTE
- if (!m_veritas_handle)
- {
- waServiceFactory *sf = line.service->service_getServiceByGuid(obj_primo::getServiceGuid());
- if (sf) m_veritas_handle = reinterpret_cast<obj_primo *>(sf->getInterface());
- }
- if (!m_veritas_handle)
- return 0;
- DWORD unit = (DWORD)fn[6];
- m_veritas_handle->UnitLock(&unit, PRIMOSDK_UNLOCK);
- m_nblock--;
- lstrcpynW(dest, L"unlocked", destlen);
- return 1;
- #else
- return 0;
- #endif
- }
- else if (!_stricmp(data, "track") && track)
- {
- StringCchPrintfW(dest, destlen, L"%d", track);
- return 1;
- }
- else if (!_stricmp(data, "bitrate") && track)
- {
- StringCchPrintfW(dest, destlen, L"%d", 1411/*200*/);
- return 1;
- }
- else
- return 0;
- return 1;
- }
- return 0;
- }
- static wchar_t m_eiw_lastdrive;
- //#ifndef IGNORE_API_GRACENOTE
- static DINFO setInfo;
- //#endif
- void ParseIntSlashInt(const wchar_t *string, int *part, int *parts);
- extern "C" __declspec(dllexport) int winampSetExtendedFileInfoW(const wchar_t *fn, const char *data, wchar_t *val)
- {
- //#ifndef IGNORE_API_GRACENOTE
- s_last_error = NULL;
- if (!lstrcmpiW(PathFindExtensionW(fn), L".cda") && !_wcsnicmp(fn + 1, L":\\track", 7)) // stupid hack, converts x:\\trackXX.cda to cda://x,XX
- {
- static wchar_t fakebuf[128];
- StringCchPrintf(fakebuf, 128, L"cda://%c,%d", fn[0], _wtoi(PathFindFileNameW(fn) + 5));
- fn = fakebuf;
- }
- wchar_t drive = 0;
- int tracknum = -1;
- if (!ParseName(fn, drive, tracknum))
- return 0;
- if (drive < 'A' || drive > 'Z') return 0;
- if (drive != m_eiw_lastdrive)
- {
- setInfo.Reset();
- setInfo.populated=false;
- m_eiw_lastdrive = 0;
- MCIDEVICEID dev2 = 0;
- if (!CDOpen(&dev2, drive, L"setinfo")) dev2 = 0;
- if (dev2)
- {
- int ret = GetDiscID(dev2, &setInfo);
- CDClose(&dev2);
- if (!ret)
- {
- GetCDDBInfo(&setInfo, drive);
- m_eiw_lastdrive = drive;
- }
- }
- }
- if (!m_eiw_lastdrive)
- return 0;
- #define DO_TRACK(comparetag, field) if (tracknum > 0 && tracknum < 100 && !_stricmp(data, comparetag)) {\
- ndestring_release(setInfo.tracks[tracknum-1]. ## field);\
- setInfo.tracks[tracknum-1]. ## field=0;\
- if (val && *val) setInfo.tracks[tracknum-1]. ## field=ndestring_wcsdup(val);\
- }
- #define DO_DISC(comparetag, field) if (!_stricmp(data, comparetag)) {\
- ndestring_release(setInfo. ## field);\
- setInfo. ## field=0;\
- if (val && *val) setInfo. ## field=ndestring_wcsdup(val);\
- }
- if (tracknum > 0 && tracknum < 100 && !_stricmp(data, "artist"))
- {
- if (val && setInfo.tracks[tracknum-1].artist == 0 && setInfo.artist && !_wcsicmp(setInfo.artist, val))
- val=0;
- ndestring_release(setInfo.tracks[tracknum-1].artist);
- setInfo.tracks[tracknum-1].artist=0;
- if (val && *val) setInfo.tracks[tracknum-1].artist=ndestring_wcsdup(val);
- }
- else DO_TRACK("title", title)
- else DO_TRACK("composer", composer)
- else DO_TRACK("conductor", conductor)
- else DO_TRACK("GracenoteFileID", tagID)
- else DO_TRACK("GracenoteExtData", extData)
- else DO_DISC("album", title)
- else DO_DISC("albumartist", artist)
- else DO_DISC("genre", genre)
- else DO_DISC("year", year)
- else DO_DISC("comment", notes)
- else DO_DISC("publisher", label)
- else DO_DISC("tuid", tuid)
- else DO_DISC("composer", composer)
- else DO_DISC("conductor", conductor)
- else if (!_stricmp(data, "disc"))
- ParseIntSlashInt(val , &setInfo.discnum, &setInfo.numdiscs);
- else
- //#endif
- return 0;
- return 1;
- }
- extern "C" __declspec(dllexport) int winampWriteExtendedFileInfo()
- {
- s_last_error = NULL;
- // write it out
- if (m_eiw_lastdrive)
- {
- //#ifndef IGNORE_API_GRACENOTE
- CddbCache_SetDisc(&setInfo, S_OK);
- StoreDINFO(setInfo.CDDBID, &setInfo);
- m_eiw_lastdrive = 0;
- last_fn[0]=0;
- if (cachedev_used)
- {
- CDClose(&cachedev);
- cachedev_used=0;
- }
- return 1;
- //#endif
- }
- return 0;
- }
- // return 1 if you want winamp to show it's own file info dialogue, 0 if you want to show your own (via In_Module.InfoBox)
- // if returning 1, remember to implement winampGetExtendedFileInfo("formatinformation")!
- extern "C" __declspec(dllexport) int winampUseUnifiedFileInfoDlg(const wchar_t * fn)
- {
- return 1;
- }
- #define SET_IF(hwndDlg, id, data) if (data) SetDlgItemText(hwndDlg, id, data); else SetDlgItemText(hwndDlg, id, L"");
- static void Fill(HWND hwndDlg, const DINFO *info)
- {
- SET_IF(hwndDlg, IDC_TITLE, info->title);
- SET_IF(hwndDlg, IDC_ARTIST, info->artist);
- if (info->discnum)
- SetDlgItemInt(hwndDlg, IDC_DISC, info->discnum, FALSE);
- else
- SetDlgItemText(hwndDlg, IDC_DISCS, L"");
- if (info->numdiscs)
- SetDlgItemInt(hwndDlg, IDC_DISCS, info->numdiscs, FALSE);
- else
- SetDlgItemText(hwndDlg, IDC_DISCS, L"");
- SET_IF(hwndDlg, IDC_YEAR, info->year);
- SET_IF(hwndDlg, IDC_LABEL, info->label);
- SET_IF(hwndDlg, IDC_NOTES, info->notes);
- SET_IF(hwndDlg, IDC_GENRE, info->genre);
- SendDlgItemMessage(hwndDlg, IDC_TRACKLIST, LB_RESETCONTENT, 0, 0);
- #ifndef IGNORE_API_GRACENOTE
- for (int x = 0; x < info->ntracks; x ++)
- {
- wchar_t buf[1100] = {0};
- if (!info->tracks[x].title)
- StringCchPrintfW(buf, 1100, L"%d.", x+1);
- else if (info->tracks[x].artist && info->tracks[x].artist[0] && wcscmp(info->tracks[x].artist, info->artist))
- StringCchPrintfW(buf, 1100, L"%d. %s - %s", x+1, info->tracks[x].artist, info->tracks[x].title);
- else
- StringCchPrintfW(buf, 1100, L"%d. %s", x+1, info->tracks[x].title);
- SendDlgItemMessageW(hwndDlg, IDC_TRACKLIST, LB_ADDSTRING, 0, (LPARAM)buf);
- }
- #endif
- }
- #ifndef IGNORE_API_GRACENOTE
- struct LookupData
- {
- LookupData(HWND hwndDlg)
- {
- hwnd=hwndDlg;
- dlgItem=0;
- device=0;
- tracknum=0;
- use=false;
- disc=0;
- memset(szTOC, 0, sizeof(szTOC));
- }
- ~LookupData()
- {
- if (disc)
- disc->Release();
- }
- HWND hwnd;
- int dlgItem;
- wchar_t szTOC[2048];
- char device;
- int tracknum;
- bool use;
- ICddbDisc *disc;
- DINFO info;
- };
- static HRESULT CALLBACK Cddb_LookupCallback(HRESULT result, ICddbDisc *pDisc, DWORD *pdwAutoCloseDelay, ULONG_PTR user)
- {
- LookupData *data = (LookupData *)user;
- if (S_OK == result)
- {
- data->info.Reset();
- data->info.populated=false;
- if (data->disc)
- data->disc->Release();
- data->disc=pDisc;
- data->disc->AddRef();
- GetDiscInfo(pDisc, &data->info);
- Fill(data->hwnd, &data->info);
- ICddbCacheManager* pCache;
- HRESULT hr = Cddb_GetICacheManger((void**)&pCache);
- if (SUCCEEDED(hr))
- {
- pCache->StoreDiscByToc(data->szTOC, data->disc);
- pCache->Release();
- }
- }
- else
- {
- *pdwAutoCloseDelay = AUTOCLOSE_NEVER;
- }
- return S_OK;
- }
- static HRESULT CALLBACK Cddb_EditCallback(HRESULT result, ICddbDisc *pDisc, DWORD *pdwAutoCloseDelay, ULONG_PTR user)
- {
- LookupData *data = (LookupData *)user;
- if (FAILED(result))
- {
- *pdwAutoCloseDelay = AUTOCLOSE_NEVER;
- return S_OK;
- }
- if (SUCCEEDED(result))
- {
- HRESULT hr(S_OK);
- ICDDBControl *pControl;
- CDDBUIFlags uiFlags = UI_EDITMODE;
- if (SUCCEEDED(hr)) hr = Cddb_GetIControl((void**)&pControl);
- if (SUCCEEDED(hr))
- {
- if (!pDisc)
- {
- uiFlags = UI_SUBMITNEW;
- hr = pControl->GetSubmitDisc(data->szTOC, 0, 0, &pDisc);
- if (FAILED(hr)) pDisc = NULL;
- }
- else
- pDisc->AddRef();
- if (pDisc)
- {
- HWND parent = GetParent(data->hwnd);
- Cddb_DisplayDiscInfo(pDisc, &uiFlags, parent);
- if (uiFlags & UI_DATA_CHANGED)
- {
- ICddbCacheManager* pCache;
- hr = Cddb_GetICacheManger((void**)&pCache);
- if (SUCCEEDED(hr))
- {
- pCache->StoreDiscByToc(data->szTOC, pDisc);
- pCache->Release();
- }
- data->info.Reset();
- data->info.populated=false;
- if (data->disc)
- data->disc->Release();
- data->disc=pDisc;
- data->disc->AddRef();
- GetDiscInfo(pDisc, &data->info);
- Fill(data->hwnd, &data->info);
- }
- pDisc->Release();
- }
- pControl->Release();
- }
- }
- return S_OK;
- }
- bool SubmitEdit(ICddbDisc *pDisc)
- {
- //CDDBUIFlags uiFlags = UI_EDITMODE;
- ICDDBControl *pControl;
- HRESULT hr = Cddb_GetIControl((void**)&pControl);
- if (SUCCEEDED(hr))
- {
- long val;
- pControl->SubmitDisc(pDisc, 0, &val);
- pControl->Release();
- if (val == 0)
- return true;
- }
- return false;
- }
- #endif
- #define SEND_DISC(field, val) SendMessage(hwndParent,WM_USER, (WPARAM)field,(LPARAM)(val?val:L""));
- #define SEND_DISC_OR_TRACK(field, disc_val, track_val) { if (track_val) SendMessage(hwndParent,WM_USER, (WPARAM)field,(LPARAM)track_val); else if (disc_val) SendMessage(hwndParent,WM_USER, (WPARAM)field,(LPARAM)disc_val); else SendMessage(hwndParent,WM_USER, (WPARAM)field,(LPARAM)L"");}
- #define SEND_TRACK(field, val) SendMessage(hwndParent,WM_USER, (WPARAM)field,(LPARAM)(val?val:L""));
- #ifndef IGNORE_API_GRACENOTE
- static void NotifyParent_MusicID(HWND hwndParent, const LookupData *data)
- {
- DINFO disc = data->info;
- TRACKINFO dummy;
- TRACKINFO &track = data->tracknum?disc.tracks[data->tracknum-1]:dummy;
- SEND_DISC(L"album", disc.title);
- SEND_DISC(L"albumartist", disc.artist);
- SEND_DISC_OR_TRACK(L"artist", disc.artist, track.artist);
- SEND_DISC(L"tuid", disc.tuid);
- SEND_DISC(L"year", disc.year);
- SEND_DISC(L"genre", disc.genre);
- SEND_DISC(L"publisher", disc.label);
- SEND_DISC(L"comment", disc.notes);
- SEND_DISC_OR_TRACK(L"conductor", disc.conductor, track.conductor);
- SEND_DISC_OR_TRACK(L"composer", disc.composer, track.composer);
- wchar_t disc_temp[64] = {0};
- if (disc.numdiscs)
- StringCchPrintfW(disc_temp, 64, L"%d/%d", disc.discnum, disc.numdiscs);
- else if (disc.discnum)
- StringCchPrintfW(disc_temp, 64, L"%d", disc.discnum);
- else
- disc_temp[0]=0;
- SEND_DISC(L"disc", disc_temp);
- SEND_TRACK(L"title", track.title);
- SEND_TRACK(L"GracenoteFileID", track.tagID);
- SEND_TRACK(L"GracenoteExtData", track.extData);
- }
- static INT_PTR CALLBACK MusicID_Proc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_INITDIALOG:
- {
- LookupData *data = new LookupData(hwndDlg);
- wchar_t *filename = (wchar_t *)lParam;
- if (ParseName(AutoChar(filename), data->device, data->tracknum)) // TODO: remove AutoChar here, I'm just being lazy
- {
- MCIDEVICEID d = 0;
- if (CDOpen(&d, data->device, L"MusicID_Dlg"))
- {
- GetDiscID(d, &data->info);
- CDClose(&d);
- if (Cddb_CalculateTOC(&data->info, data->szTOC, sizeof(data->szTOC)/sizeof(wchar_t)))
- {
- ICddbCacheManager *pCache;
- if (SUCCEEDED(Cddb_GetICacheManger((void**)&pCache)))
- {
- if (SUCCEEDED(pCache->FetchDiscByToc(data->szTOC, &data->disc)))
- {
- GetDiscInfo(data->disc, &data->info);
- Fill(hwndDlg, &data->info);
- }
- pCache->Release();
- }
- }
- }
- }
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)data);
- }
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDOK:
- {
- LookupData *data = (LookupData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- if (data->use && data->disc)
- {
- StoreDisc(data->info.CDDBID, data->disc);
- CddbCache_SetDisc(&data->info, S_OK);
- }
- }
- break;
- case IDC_LOOKUP:
- {
- LookupData *data = (LookupData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- if (data)
- {
- data->dlgItem = LOWORD(wParam);
- HWND parent = GetParent(hwndDlg);
- UINT flags = CDDB_NOCACHE | CDDB_UI_MODAL | CDDB_UI_MULTIPLE | CDDB_UI_RESULT_MODAL;
- HRESULT hr = Cddb_DoLookup(data->szTOC, parent, Cddb_LookupCallback, flags, (ULONG_PTR)data);
- if (FAILED(hr)) Cddb_DisplayResultDlg(parent, hr, AUTOCLOSE_NEVER, flags);
- }
- }
- break;
- case IDC_USE:
- {
- LookupData *data = (LookupData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- data->use=true;
- NotifyParent_MusicID(GetParent(hwndDlg), data);
- }
- break;
- case IDC_EDIT_GRACENOTE:
- {
- LookupData *data = (LookupData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- data->dlgItem = LOWORD(wParam);
- HWND parent = GetParent(hwndDlg);
- UINT flags = CDDB_UI_MODAL | CDDB_UI_MULTIPLE | CDDB_UI_RESULT_MODAL;
- HRESULT hr = Cddb_DoLookup(data->szTOC, parent, Cddb_EditCallback, flags, (ULONG_PTR)data);
- if (FAILED(hr)) Cddb_DisplayResultDlg(parent, hr, AUTOCLOSE_NEVER, flags);
- }
- break;
- case IDC_SUBMIT:
- {
- LookupData *data = (LookupData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- if (data && data->disc)
- SubmitEdit(data->disc);
- }
- break;
- }
- break;
- case WM_DESTROY:
- {
- LookupData *data = (LookupData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- delete data;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)0);
- }
- break;
- }
- return 0;
- }
- #endif
- struct CDTextData
- {
- public:
- CDTextData()
- {
- device=0;
- tracknum=0;
- use=false;
- }
- DINFO info;
- wchar_t device;
- int tracknum;
- bool use;
- };
- static void Send_CDText(HWND hwndParent, const CDTextData *data)
- {
- DINFO disc = data->info;
- TRACKINFO dummy;
- TRACKINFO &track = data->tracknum ? disc.tracks[data->tracknum-1] : dummy;
- SEND_DISC(L"album", disc.title);
- SEND_DISC(L"albumartist", disc.artist);
- SEND_DISC_OR_TRACK(L"artist", disc.artist, track.artist);
- SEND_DISC_OR_TRACK(L"composer", disc.composer, track.composer);
- SEND_TRACK(L"title", track.title);
- SEND_DISC_OR_TRACK(L"genre", disc.genre, track.genre);
- }
- static void FillDialog_CDText(HWND hwndDlg, const DINFO &info)
- {
- SET_IF(hwndDlg, IDC_ARTIST, info.artist);
- SET_IF(hwndDlg, IDC_ALBUM, info.title);
- SET_IF(hwndDlg, IDC_COMPOSER, info.composer);
- W_ListView listview(GetDlgItem(hwndDlg, IDC_TRACKS));
- listview.Clear();
- for (int i=0;i<info.ntracks;i++)
- {
- const TRACKINFO &track = info.tracks[i];
- wchar_t num[64] = {0};
- StringCchPrintfW(num, 64, L"%d", i+1);
- int index = listview.AppendItem(num, 0);
- if (track.artist)
- listview.SetItemText(index, 1, track.artist);
- if (track.title)
- listview.SetItemText(index, 2, track.title);
- if (track.genre)
- listview.SetItemText(index, 3, track.genre);
- if (track.composer)
- listview.SetItemText(index, 4, track.composer);
- }
- }
- static INT_PTR CALLBACK CDText_Proc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_INITDIALOG:
- {
- W_ListView listview;
- listview.setwnd(GetDlgItem(hwndDlg, IDC_TRACKS));
- listview.AddCol(WASABI_API_LNGSTRINGW(IDS_TRACK), 50);
- listview.AddCol(WASABI_API_LNGSTRINGW(IDS_ARTIST), 150);
- listview.AddCol(WASABI_API_LNGSTRINGW(IDS_TITLE), 150);
- // TODO
- listview.AddCol(L"Genre"/*WASABI_API_LNGSTRINGW(IDS_GENRE)*/, 150);
- listview.AddCol(WASABI_API_LNGSTRINGW(IDS_COMPOSER), 150);
- CDTextData *data = new CDTextData;
- wchar_t *filename = (wchar_t *)lParam;
- if (ParseName(filename, data->device, data->tracknum))
- {
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)data);
- }
- else
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
- // this is slow if there's no CD Text
- PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_LOOKUP, BN_CLICKED), (LPARAM)GetDlgItem(hwndDlg, IDC_LOOKUP));
- }
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDOK:
- {
- CDTextData *data = (CDTextData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- if (data && data->use)
- StoreCDText(data->info.CDDBID, data->device);
- }
- break;
- case IDC_LOOKUP:
- {
- CDTextData *data = (CDTextData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- if (data && DoCDText(&data->info, data->device))
- {
- FillDialog_CDText(hwndDlg, data->info);
- }
- }
- break;
- case IDC_USE:
- {
- CDTextData *data = (CDTextData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- if (data)
- {
- data->use=true;
- Send_CDText(GetParent(hwndDlg), data);
- }
- }
- break;
- }
- break;
- case WM_DESTROY:
- {
- CDTextData *data = (CDTextData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- delete data;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)0);
- }
- break;
- }
- return 0;
- }
- // should return a child window of 513x271 pixels (341x164 in msvc dlg units), or return NULL for no tab.
- // Fill in name (a buffer of namelen characters), this is the title of the tab (defaults to "Advanced").
- // filename will be valid for the life of your window. n is the tab number. This function will first be
- // called with n == 0, then n == 1 and so on until you return NULL (so you can add as many tabs as you like).
- // The window you return will recieve WM_COMMAND, IDOK/IDCANCEL messages when the user clicks OK or Cancel.
- // when the user edits a field which is duplicated in another pane, do a SendMessage(GetParent(hwnd),WM_USER,(WPARAM)L"fieldname",(LPARAM)L"newvalue");
- // this will be broadcast to all panes (including yours) as a WM_USER.
- extern "C" __declspec(dllexport) HWND winampAddUnifiedFileInfoPane(int n, const wchar_t * filename, HWND parent, wchar_t *name, size_t namelen)
- {
- if (!lstrcmpiW(PathFindExtensionW(filename), L".cda") && !_wcsnicmp(filename + 1, L":\\track", 7)) // stupid hack, converts x:\\trackXX.cda to cda://x,XX
- {
- static wchar_t fakebuf[128];
- StringCchPrintf(fakebuf, 128, L"cda://%c,%d", filename[0], _wtoi(PathFindFileNameW(filename) + 5));
- filename = fakebuf;
- }
- #ifndef IGNORE_API_GRACENOTE
- switch (n)
- {
- case 0: // MusicID
- StringCchCopyW(name, namelen, L"MusicID"); // benski> this is purposefully not translatable
- return WASABI_API_CREATEDIALOGPARAMW(IDD_MUSICID,parent,MusicID_Proc,(LPARAM)_wcsdup(filename));
- case 1: // CD Text
- WASABI_API_LNGSTRINGW_BUF(IDS_CDTEXT,name, namelen);
- return WASABI_API_CREATEDIALOGPARAMW(IDD_CDTEXT,parent,CDText_Proc,(LPARAM)_wcsdup(filename));
- default:
- return 0;
- }
- #else
- switch (n)
- {
- case 0: // CD Text
- {
- //if (DoCDText(0, filename[6])) // this is slow if there's no CD Text
- {
- WASABI_API_LNGSTRINGW_BUF(IDS_CDTEXT,name, namelen);
- return WASABI_API_CREATEDIALOGPARAMW(IDD_CDTEXT,parent,CDText_Proc,(LPARAM)_wcsdup(filename));
- }
- return 0;
- }
- default:
- return 0;
- }
- #endif
- }
|