123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698 |
- #include "IDScanner.h"
- #include "main.h"
- #include "../winamp/wa_ipc.h"
- #include "api__ml_plg.h"
- #include "playlist.h"
- #include <assert.h>
- #include <atlbase.h>
- #include <strsafe.h> // include this last
- //#define DEBUG_CALLBACKS
- IDScanner::IDScanner() : systemCallbacks(0)
- {
- musicID=0;
- killswitch=0;
- filesComplete=0;
- filesTotal=0;
- state=STATE_IDLE;
- m_dwCookie=0;
- syscb_registered=false;
- // Create the stack that will hold our batched up files for step 4 processing
- //process_items;
- }
- IDScanner::~IDScanner()
- {
- // ToDo: Make sure we clean up the processing stack here if we need to do that
- //Shutdown();
- }
- void IDScanner::Shutdown()
- {
- if (musicID)
- {
- IConnectionPoint *icp = GetConnectionPoint(musicID, DIID__ICDDBMusicIDManagerEvents);
- if (icp)
- {
- icp->Unadvise(m_dwCookie);
- icp->Release();
- }
- musicID->Shutdown();
- musicID->Release();
- }
- musicID=0;
- // Deregister the system callbacks
- WASABI_API_SYSCB->syscb_deregisterCallback(this);
- }
- static HRESULT FillTag(ICddbFileInfo *info, BSTR filename)
- {
- ICddbID3TagPtr infotag = NULL;
- infotag.CreateInstance(CLSID_CddbID3Tag);
- ICddbFileTag2_5Ptr tag2_5 = NULL;
- infotag->QueryInterface(&tag2_5);
- itemRecordW *record = AGAVE_API_MLDB->GetFile(filename);
- if (record && infotag && tag2_5)
- {
- wchar_t itemp[64] = {0};
- if (record->artist)
- infotag->put_LeadArtist(record->artist);
- if (record->album)
- infotag->put_Album(record->album);
- if (record->title)
- infotag->put_Title(record->title);
- if (record->genre)
- infotag->put_Genre(record->genre);
- if (record->track > 0)
- infotag->put_TrackPosition(_itow(record->track, itemp, 10));
- // TODO: if (record->tracks > 0)
- if (record->year > 0)
- infotag->put_Year(_itow(record->year, itemp, 10));
- if (record->publisher)
- infotag->put_Label(record->publisher);
- /*
- if (GetFileInfo(filename, L"ISRC", meta, 512) && meta[0])
- infotag->put_ISRC(meta);
- */
- if (record->disc > 0)
- infotag->put_PartOfSet(_itow(record->disc, itemp, 10));
- if (record->albumartist)
- tag2_5->put_DiscArtist(record->albumartist);
- if (record->composer)
- tag2_5->put_Composer(record->composer);
- if (record->length > 0)
- tag2_5->put_LengthMS(_itow(record->length*1000, itemp, 10));
- if (record->bpm > 0)
- infotag->put_BeatsPerMinute(_itow(record->bpm, itemp, 10));
- /*
- if (GetFileInfo(filename, L"conductor", meta, 512) && meta[0])
- tag2_5->put_Conductor(meta);
- */
- AGAVE_API_MLDB->FreeRecord(record);
- }
- if (info) info->put_Tag(infotag);
- return S_OK;
- }
- void IDScanner::CommitFileInfo(ICddbFileInfo *match)
- {
- ICddbFileTagPtr tag;
- match->get_Tag(&tag);
- ICddbDisc2Ptr disc1, disc;
- match->get_Disc(&disc1);
- ICddbDisc2_5Ptr disc2_5;
- ICddbTrackPtr track;
- ICddbTrack2_5Ptr track2;
- if (disc1)
- {
- musicID->GetFullDisc(disc1, &disc);
- if (disc == 0)
- disc=disc1;
- disc->QueryInterface(&disc2_5);
- disc->GetTrack(1, &track);
- if (track)
- track->QueryInterface(&track2);
- }
- CComBSTR file, tagID, extData;
- match->get_Filename(&file);
- tag->get_FileId(&tagID);
- playlistMgr->FileSetTagID(file, tagID, CDDB_UPDATE_NONE);
- ICddbFileTag2_5Ptr tag2;
- tag->QueryInterface(&tag2);
- playlistMgr->FileSetFieldVal(file, gnpl_crit_field_xdev1, L"0"); // mark as done!
- if (tag2) // try tag first
- tag2->get_ExtDataSerialized(&extData);
- if (!extData && track2 != 0) // WMA files don't get their tag object's extended data set correctly, so fallback to track extended data
- track2->get_ExtDataSerialized(&extData);
- if (!extData && disc2_5 != 0) // finally, fall back to disc extended data
- disc2_5->get_ExtDataSerialized(&extData);
- playlistMgr->FileSetExtDataSerialized(file, extData, CDDB_UPDATE_NONE);
- if (tagID)
- AGAVE_API_MLDB->SetField(file, "GracenoteFileID", tagID);
- if (extData)
- AGAVE_API_MLDB->SetField(file, "GracenoteExtData", extData);
- // TODO: if we don't have an artist & album, we might as well grab this out of the tag now
- // TODO: make thread-safe and optional
- /*
- updateFileInfo(file, L"GracenoteFileID", tagID);
- updateFileInfo(file, L"GracenoteExtData", extData);
- WriteFileInfo(file);
- */
- }
- STDMETHODIMP STDMETHODCALLTYPE IDScanner::QueryInterface(REFIID riid, PVOID *ppvObject)
- {
- if (!ppvObject)
- return E_POINTER;
- else if (IsEqualIID(riid, __uuidof(_ICDDBMusicIDManagerEvents)))
- *ppvObject = (_ICDDBMusicIDManagerEvents *)this;
- else if (IsEqualIID(riid, IID_IDispatch))
- *ppvObject = (IDispatch *)this;
- else if (IsEqualIID(riid, IID_IUnknown))
- *ppvObject = this;
- else
- {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- ULONG STDMETHODCALLTYPE IDScanner::AddRef(void)
- {
- return 1;
- }
- ULONG STDMETHODCALLTYPE IDScanner::Release(void)
- {
- return 0;
- }
- HRESULT STDMETHODCALLTYPE IDScanner::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
- {
- switch (dispid)
- {
- case 1: // OnTrackIDStatusUpdate, params: CddbMusicIDStatus Status, BSTR filename, long* Abort
- {
- //long *abort = pdispparams->rgvarg[0].plVal;
- // TODO: is this safe to put here? Or does this make us get partial results
- }
- break;
- case 2: // OnAlbumIDStatusUpdate, params: CddbMusicIDStatus Status, BSTR filename, long current_file, long total_files, long* Abort
- {
- long *abort = pdispparams->rgvarg[0].plVal;
- /*long total_files = pdispparams->rgvarg[1].lVal;
- long current_file= pdispparams->rgvarg[2].lVal;*/
- CddbMusicIDStatus status = (CddbMusicIDStatus)pdispparams->rgvarg[4].lVal;
- BSTR filename = pdispparams->rgvarg[3].bstrVal;
- // TODO: is this safe to put here? Or does this make us get partial results
- if (killswitch)
- *abort = 1;
- }
- break;
- case 3: // OnTrackIDComplete, params: LONG match_code, ICddbFileInfo* pInfoIn, ICddbFileInfoList* pListOut
- break;
- case 4:
- break;// OnAlbumIDComplete, params: LONG match_code, ICddbFileInfoList* pListIn, ICddbFileInfoLists* pListsOut
- case 5:
- break; // OnGetFingerprint
- case 6:
- break;
- case 7://OnLibraryIDListStarted
- break;
- case 8: // OnLibraryIDListComplete
- {
- long *abort = pdispparams->rgvarg[0].plVal;
- if (killswitch)
- *abort = 1;
- /*long FilesError =pdispparams->rgvarg[1].lVal;
- long FilesNoMatch=pdispparams->rgvarg[2].lVal;
- long FilesFuzzy=pdispparams->rgvarg[3].lVal;
- long FilesExact=pdispparams->rgvarg[4].lVal;*/
- filesTotal=pdispparams->rgvarg[5].lVal;
- filesComplete=pdispparams->rgvarg[6].lVal;
- IDispatch *disp = pdispparams->rgvarg[7].pdispVal;
- if (disp)
- {
- ICddbFileInfoList* matchList=0;
- disp->QueryInterface(&matchList);
- if (matchList)
- {
- long matchcount;
- matchList->get_Count(&matchcount);
- for (int j = 1;j <= matchcount;j++)
- {
- ICddbFileInfoPtr match;
- matchList->GetFileInfo(j, &match);
- CommitFileInfo(match);
- }
- matchList->Release();
- }
- return S_OK;
- }
- else
- return E_FAIL;
- }
- break;
- case 9: //OnLibraryIDComplete
- break;
- case 10: // OnGetFingerprintInfo
- {
- long *abort = pdispparams->rgvarg[0].plVal;
- IDispatch *disp = pdispparams->rgvarg[1].pdispVal;
- BSTR filename = pdispparams->rgvarg[2].bstrVal;
- ICddbFileInfoPtr info;
- disp->QueryInterface(&info);
- return AGAVE_API_GRACENOTE->CreateFingerprint(musicID, AGAVE_API_DECODE, info, filename, abort);
- }
- break;
- case 11: // OnGetTagInfo
- {
- pdispparams->rgvarg[0].plVal;
- IDispatch *disp = pdispparams->rgvarg[1].pdispVal;
- BSTR filename = pdispparams->rgvarg[2].bstrVal;
- ICddbFileInfoPtr info;
- disp->QueryInterface(&info);
- return FillTag(info, filename);
- }
- break;
- }
- return DISP_E_MEMBERNOTFOUND;
- }
- HRESULT STDMETHODCALLTYPE IDScanner::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
- {
- *rgdispid = DISPID_UNKNOWN;
- return DISP_E_UNKNOWNNAME;
- }
- HRESULT STDMETHODCALLTYPE IDScanner::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
- {
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE IDScanner::GetTypeInfoCount(unsigned int FAR * pctinfo)
- {
- return E_NOTIMPL;
- }
- void IDScanner::SetGracenoteData(BSTR filename, BSTR tagID, BSTR extData)
- {
- bool foundExt=false;
- if (extData && extData[0])
- {
- playlistMgr->FileSetExtDataSerialized(filename, extData, CDDB_UPDATE_NONE);
- CComBSTR test;
- playlistMgr->FileGetExtDataSerialized(filename, &test, 0); // benski> 24 Jul 2007 - there is a currently a bug that makes this always E_FAIL
- if (test)
- foundExt=true;
- }
- if (!foundExt) // no Extended Data (or invalid), but we have a Tag ID, we'll ask the playlist SDK to do a quick lookup
- {
- playlistMgr->FileSetTagID(filename, tagID, CDDB_UPDATE_EXTENDED);
- // write back to Media Library database
- CComBSTR extData;
- playlistMgr->FileGetExtDataSerialized(filename, &extData, 0); // benski> 24 Jul 2007 - there is a currently a bug that makes this always E_FAIL
- if (extData)
- AGAVE_API_MLDB->SetField(filename, "GracenoteExtData", extData);
- }
- else
- playlistMgr->FileSetTagID(filename, tagID, CDDB_UPDATE_NONE);
- }
- /*
- //void IDScanner::ProcessDatabaseDifferences(Device * dev, C_ItemList * ml0,C_ItemList * itemRecordsOnDevice, C_ItemList * itemRecordsNotOnDevice, C_ItemList * songsInML, C_ItemList * songsNotInML)
- void IDScanner::ProcessDatabaseDifferences(Device * dev, C_ItemList * ml0,C_ItemList * itemRecordsOnDevice, C_ItemList * itemRecordsNotOnDevice, C_ItemList * songsInML, C_ItemList * songsNotInML)
- {
- C_ItemList device2;
- C_ItemList *device0=&device2;
- int l = dev->getPlaylistLength(0);
- for(int i=0; i<l; i++) device0->Add((void*)dev->getPlaylistTrack(0,i));
- qsort(ml0->GetAll(),ml0->GetSize(),sizeof(void*),sortfunc_ItemRecords);
- nu::qsort(device0->GetAll(), device0->GetSize(), sizeof(void*), dev, compareSongs);
- C_ItemList *ml = new C_ItemList;
- C_ItemList *device = new C_ItemList;
-
- int i,j;
-
- {
- itemRecordW * lastice = NULL;
- songid_t lastsong = NULL;
- for(i=0; i<ml0->GetSize(); i++) {
- itemRecordW * it = (itemRecordW*)ml0->Get(i);
- if(lastice) if(compareItemRecords(lastice,it)==0) continue;
- ml->Add(it);
- lastice = it;
- }
- for(i=0; i<device0->GetSize(); i++) {
- songid_t song = (songid_t)device0->Get(i);
- if(lastsong) if(compareSongs((void*)&song,(void*)&lastsong, dev)==0) continue;
- device->Add((void*)song);
- lastsong = song;
- }
- }
- i=0,j=0;
- int li = device->GetSize();
- int lj = ml->GetSize();
- while(i<li && j<lj) {
- itemRecordW * it = (itemRecordW*)ml->Get(j);
- songid_t song = (songid_t)device->Get(i);
-
- int cmp = compareItemRecordAndSongId(it,song, dev);
- if(cmp == 0) { // song on both
- if(itemRecordsOnDevice) itemRecordsOnDevice->Add(it);
- if(songsInML) songsInML->Add((void*)song);
- i++;
- j++;
- }
- else if(cmp > 0) { //song in ml and not on device
- if(itemRecordsNotOnDevice) itemRecordsNotOnDevice->Add(it);
- j++;
- }
- else { // song on device but not in ML
- if(songsNotInML) songsNotInML->Add((void*)song);
- i++;
- }
- }
- // any leftovers?
- if(songsNotInML) while(i<li) {
- songid_t song = (songid_t)device->Get(i++);
-
- songsNotInML->Add((void*)song);
- }
- if(itemRecordsNotOnDevice) while(j<lj) {
- itemRecordW * it = (itemRecordW *)ml->Get(j++);
-
- itemRecordsNotOnDevice->Add(it);
- }
- delete ml; delete device;
- }
- */
- /*
- 2-pass strategy
- Pass 1: Find all tracks with Gracenote Extended Data
- Pass 2: Find File ID & extended data by fingerprint
- */
- void IDScanner::ScanDatabase()
- {
- filesComplete=0;
- filesTotal=0;
- state=STATE_INITIALIZING;
- killswitch=0; // reset just in case
- if (SetupPlaylistSDK())
- {
- // If this is our first time running then lets register the wasabi system callbacks for adding and removing tracks
- if (!syscb_registered)
- {
- WASABI_API_SYSCB->syscb_registerCallback(this);
- syscb_registered = true;
- }
- // Set up the MLDB manager
- InitializeMLDBManager();
- state=STATE_SYNC;
- /* Get a list of files in the media library database */
- itemRecordListW *results = AGAVE_API_MLDB->Query(L"type=0");
- if (results)
- {
- filesTotal=results->Size;
- for (int i=0;i<results->Size;i++)
- {
- if (killswitch)
- break;
- wchar_t * filename = results->Items[i].filename;
- HRESULT hr=playlistMgr->AddEntry(filename); // Add entry to gracenote DB
- assert(SUCCEEDED(S_OK));
- if (hr == S_OK)
- {
- // Fill in Artist & Album info since we have it in the itemRecordList anyway
- // TODO: probably want to use SKIP_THE_AND_WHITESPACE here
- if (results->Items[i].album && results->Items[i].album[0])
- hr=playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_album_name, results->Items[i].album);
- if (results->Items[i].artist && results->Items[i].artist[0])
- hr=playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_track_artist_name, results->Items[i].artist);
- // Populate title information so that we have more complete data.
- if (results->Items[i].title && results->Items[i].title[0])
- hr=playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_track_name, results->Items[i].title);
- wchar_t storage[64] = {0};
- // Populate the file length in milliseconds
- if (results->Items[i].length > 0)
- {
- _itow(results->Items[i].length,storage, 10);
- hr=playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_file_length, storage);
- }
- // Populate the file size in kilobytes
- if (results->Items[i].filesize > 0)
- {
- _itow(results->Items[i].filesize,storage, 10);
- hr=playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_file_size, storage);
- }
- wchar_t *tagID = getRecordExtendedItem(&results->Items[i], L"GracenoteFileID");
- if (tagID && tagID[0])
- {
- SetGracenoteData(filename, tagID, getRecordExtendedItem(&results->Items[i], L"GracenoteExtData"));
- hr=playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_xdev1, L"0"); // done with this file!
- }
- else
- hr=playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_xdev1, L"1"); // move to phase 1
- }
- filesComplete=i+1;
- }
- AGAVE_API_MLDB->FreeRecordList(results);
- state=STATE_METADATA;
- filesComplete=0;
- if (!killswitch)
- Pass1();
- filesComplete=0;
- state=STATE_MUSICID;
- if (!killswitch)
- Pass2();
- state=STATE_DONE;
- if (!killswitch)
- AGAVE_API_MLDB->Sync();
- }
- // Set the pass 2 flag back so that on next generation we dont try to run it
- run_pass2_flag = false;
- }
- else
- state=STATE_ERROR;
- }
- bool IDScanner::GetStatus(long *pass, long *track, long *tracks)
- {
- *pass = state;
- *track = filesComplete;
- *tracks = filesTotal;
- return true;
- }
- // System callback handlers from WASABI
- FOURCC IDScanner::GetEventType()
- {
- return api_mldb::SYSCALLBACK;
- }
- int IDScanner::notify(int msg, intptr_t param1, intptr_t param2)
- {
- wchar_t *filename = (wchar_t *)param1;
- switch (msg)
- {
- case api_mldb::MLDB_FILE_ADDED:
- {
- DebugCallbackMessage(param1, L"File Added: '%s'");
- // Call the add/update function that needs to run on our lonesome playlist generator thread
- WASABI_API_THREADPOOL->RunFunction(plg_thread, IDScanner::MLDBFileAddedOnThread, _wcsdup(filename), (intptr_t)this, api_threadpool::FLAG_REQUIRE_COM_STA);
- }
- break;
- case api_mldb::MLDB_FILE_REMOVED_PRE:
- {
- // We are not concerned with the PRE scenario
- //DebugCallbackMessage(param1, L"File Removed PRE: '%s'");
- }
- break;
- case api_mldb::MLDB_FILE_REMOVED_POST:
- {
- WASABI_API_THREADPOOL->RunFunction(plg_thread, IDScanner::MLDBFileRemovedOnThread, _wcsdup(filename), (intptr_t)this, api_threadpool::FLAG_REQUIRE_COM_STA);
- // We will only care about the post scenario since we just need to remove the file entry from gracenote.
- //DebugCallbackMessage(param1, L"File Removed POST: '%s'");
- }
- break;
- case api_mldb::MLDB_FILE_UPDATED:
- {
- // For now we call the add method even on an update
- WASABI_API_THREADPOOL->RunFunction(plg_thread, IDScanner::MLDBFileAddedOnThread, _wcsdup(filename), (intptr_t)this, api_threadpool::FLAG_REQUIRE_COM_STA);
- //DebugCallbackMessage(param1, L"File Updated: '%s'");
- }
- break;
- case api_mldb::MLDB_CLEARED:
- {
- WASABI_API_THREADPOOL->RunFunction(plg_thread, IDScanner::MLDBClearedOnThread, 0, (intptr_t)this, api_threadpool::FLAG_REQUIRE_COM_STA);
- //DebugCallbackMessage(param1, L"MLDB Cleared");
- }
- break;
- default: return 0;
- }
- return 1;
- }
- // Outputs a messagebox with a filename to know when callbacks are being triggered
- inline void IDScanner::DebugCallbackMessage(const intptr_t text, const wchar_t *message)
- {
- //#ifdef DEBUG_CALLBACKS
- #if defined(DEBUG) && defined(DEBUG_CALLBACKS)
- const int size = MAX_PATH + 256;
- wchar_t *filename = (wchar_t *)text;
- wchar_t buff[size] = {0};
- //wsprintf(buff, size, message, filename);
- StringCchPrintf(buff, size, message, filename);
- MessageBox(0, buff, L"Wasabi Callback Debug", 0);
- #endif
- }
- int IDScanner::MLDBFileAddedOnThread(HANDLE handle, void *user_data, intptr_t id)
- {
- if (!playlistMgr) return 0;
- // Variables to hold information about the file query
- wchar_t *filename = (wchar_t *)user_data;
- IDScanner *scanner = (IDScanner *)id;
- wchar_t buff[1024] = {0};
- _ltow(scanner->state, buff, 10);
-
- itemRecordW *result = AGAVE_API_MLDB->GetFile(filename);
-
- HRESULT hr=playlistMgr->AddEntry(filename); // Add the file entry to the gracenote DB
-
- assert(SUCCEEDED(S_OK));
-
- if (hr == S_OK /*&& results->Size == 1*/)
- {
- // Fill in Artist & Album info since we have it in the itemRecordList anyway
- // TODO: probably want to use SKIP_THE_AND_WHITESPACE here
- if (result->album && result->album[0])
- playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_album_name, result->album);
- if (result->artist && result->artist[0])
- playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_track_artist_name, result->artist);
- // Populate title, file size, and length information so that we have more complete data.
- if (result->title && result->title[0])
- playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_track_name, result->title);
- wchar_t storage[64] = {0};
- // Populate the file length in milliseconds
- if (result->length > 0)
- {
- _itow(result->length,storage, 10);
- playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_file_length, storage);
- }
- // Populate the file size in kilobytes
- if (result->filesize > 0)
- {
- _itow(result->filesize,storage, 10);
- playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_file_size, storage);
- }
- wchar_t *tagID = getRecordExtendedItem(result, L"GracenoteFileID");
- if (tagID && tagID[0])
- {
- scanner->SetGracenoteData(filename, tagID, getRecordExtendedItem(result, L"GracenoteExtData"));
- // We have everything we need at this point in the gracenote DB
- playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_xdev1, L"0"); // done with this file!
- }
- else // Set it to the final scan
- {
- playlistMgr->FileSetFieldVal(filename, gnpl_crit_field_xdev1, L"2"); // move to phase 2, we can skip phase 1
- // Add the current file to the step 4 processing stack
- // TODOD is there a mem leak here??
- ProcessItem *itemz = new ProcessItem();
- itemz->filename = filename;
- //scanner->process_items.push(*itemz); // Add the current item coming in to the queue
- // Set the flag so that we know we will need to rerun step 4 (pass 2) on a playlist regeneration, this only needs to happen if there is an actual change.
- run_pass2_flag = true;
- }
- }
- if (result)
- AGAVE_API_MLDB->FreeRecord(result);
- // ToDo: We need to do this free when we pop it off of the processing stack later
- free(filename); // Clean up the user data
- return 0;
- }
- int IDScanner::MLDBFileRemovedOnThread(HANDLE handle, void *user_data, intptr_t id)
- {
- wchar_t *filename = (wchar_t *)user_data;
- HRESULT hr = playlistMgr->DeleteFile(filename);
- if (hr == S_OK)
- return 0;
- else
- return 1;
- free(filename); // Clean up the user data
- }
- int IDScanner::MLDBClearedOnThread(HANDLE handle, void *user_data, intptr_t id)
- {
- return ResetDB(false);
- }
- int IDScanner::ProcessStackItems(void)
- {
- // ToDo: Run through the stack items and process stage 4 on them
- //this->
- return 1;
- }
- #define CBCLASS IDScanner
- START_DISPATCH;
- CB(SYSCALLBACK_GETEVENTTYPE, GetEventType);
- CB(SYSCALLBACK_NOTIFY, notify);
- END_DISPATCH;
- #undef CBCLASS
|