123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- #include "main.h"
- #include "api__ml_iso.h"
- #include <api/service/waservicefactory.h>
- #include "../burner/obj_isocreator.h"
- #include "../playlist/ifc_playlistloadercallback.h"
- #include <shlwapi.h>
- #include <strsafe.h>
- /**
- ** Playlist Loader callback class
- ** Used when this plugin loads a playlist file
- ** the playlist loader will call the OnFile() function
- ** for each playlist item
- */
- class ISOPlaylistLoader : public ifc_playlistloadercallback
- {
- public:
- ISOPlaylistLoader(obj_isocreator *_creator);
- protected:
- RECVS_DISPATCH;
- private:
- void OnFile(const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info);
- obj_isocreator *creator;
- };
- /**
- ** helper function
- ** for getting a filename location
- ** of where to save the ISO file
- **/
- static bool PromptForFilename(wchar_t *filename, size_t filenameCch)
- {
- wchar_t oldCurPath[MAX_PATH], newCurPath[MAX_PATH];
- OPENFILENAMEW openfilename;
- // null terminate the string or else we'll get a garbage filename as the 'default' filename
- filename[0]=0;
- // GetSaveFileName changes Window's working directory
- // which locks that folder from being deleted until Winamp closes
- // so we save the old working directory name
- // and restore it on complete
- // Winamp maintains its own concept of a working directory
- // to help us avoid this problem
- GetCurrentDirectoryW(MAX_PATH, oldCurPath);
- // initialize the open file name struct
- openfilename.lStructSize = sizeof(openfilename);
- openfilename.hwndOwner = plugin.hwndLibraryParent;
- openfilename.hInstance = plugin.hDllInstance;
- openfilename.lpstrFilter = L"ISO Files\0*.iso\0";
- openfilename.lpstrCustomFilter = 0;
- openfilename.nMaxCustFilter = 0;
- openfilename.nFilterIndex = 0;
- openfilename.lpstrFile = filename;
- openfilename.nMaxFile = filenameCch;
- openfilename.lpstrFileTitle = 0;
- openfilename.nMaxFileTitle = 0;
- // we set the initial directory based on winamp's working path
- openfilename.lpstrInitialDir = WASABI_API_APP->path_getWorkingPath();
- openfilename.lpstrTitle = 0;
- // despite the big note about working directory
- // we don't want to use OFN_NOCHANGEDIR
- // because we're going to manually sync Winamp's working path
- openfilename.Flags = OFN_ENABLESIZING | OFN_EXPLORER | OFN_LONGNAMES;
- openfilename.nFileOffset = 0;
- openfilename.nFileExtension = 0;
- openfilename.lpstrDefExt = L".iso";
- openfilename.lCustData = 0;
- openfilename.lpfnHook = 0;
- openfilename.lpTemplateName = 0;
- if (GetSaveFileNameW(&openfilename))
- {
- // let's re-synch Winamp's working directory
- GetCurrentDirectoryW(MAX_PATH, newCurPath);
- WASABI_API_APP->path_setWorkingPath(newCurPath);
- // set the old path back
- SetCurrentDirectoryW(oldCurPath);
- return true; // success!
- }
- else
- {
- // set the old path back
- SetCurrentDirectoryW(oldCurPath);
- return false; // user hit cancel or something else happened
- }
- }
- /**
- ** helper functions
- ** for creating and deleting
- ** an iso creator object
- ** through the wasabi service manager
- **/
- static obj_isocreator *CreateISOCreator()
- {
- waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(obj_isocreatorGUID);
- if (factory)
- return (obj_isocreator *)factory->getInterface();
- else
- return 0;
- }
- static void ReleaseISOCreator(obj_isocreator *creator)
- {
- if (creator)
- {
- waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(obj_isocreatorGUID);
- if (factory)
- factory->releaseInterface(creator);
- }
- }
- void ConvertItemRecordListToISO(const itemRecordList *list)
- {
- obj_isocreator *isocreator = CreateISOCreator();
- if (isocreator)
- {
- wchar_t destination[MAX_PATH];
- if (PromptForFilename(destination, MAX_PATH))
- {
- // these values are hardcoded for this example.
- isocreator->Open(L"WinampISO", obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
- char destinationPath[MAX_PATH];
- // loop through the files and add them
- for (int i=0;i<list->Size;i++)
- {
- itemRecord &item = list->Items[i];
- // since we have metadata, we're going to auto-generate folders based on the album name
- const char *album = item.album;
- if (!album || !*album)
- album = "Unknown Album";
- // isocreator requires a preceding backslash
- StringCbPrintfA(destinationPath, sizeof(destinationPath), "\\%s\\%s", album, PathFindFileNameA(item.filename));
- // convert to unicode since that's what obj_isocreator requires
- wchar_t unicodeSource[MAX_PATH];
- wchar_t unicodeDest[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, item.filename, -1, unicodeSource, MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, destinationPath, -1, unicodeDest, MAX_PATH);
- isocreator->AddFile(unicodeSource, unicodeDest);
- }
- isocreator->Write(destination, 0);
- }
- ReleaseISOCreator(isocreator);
- }
- }
- void ConvertFilenamesToISO(const char *filenames)
- {
- obj_isocreator *isocreator = CreateISOCreator();
- if (isocreator)
- {
- wchar_t destination[MAX_PATH];
- if (PromptForFilename(destination, MAX_PATH))
- {
- // these values are hardcoded for this example.
- isocreator->Open(L"WinampISO", obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
- wchar_t destinationPath[MAX_PATH];
- // loop through the files and add them
- while (*filenames)
- {
- /**
- ** both playlist loader and iso creator want unicode filenames
- ** so we'll convert it first
- */
- wchar_t unicodeFilename[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, filenames, -1, unicodeFilename, MAX_PATH);
- /**
- ** see if this file is a playlist file
- ** we'll do that by trying to load it
- ** the Load() function will fail gracefully if it's not a playlist file
- ** if it succeeds, it will call loader.OnFile() which adds it to the iso file
- **/
- ISOPlaylistLoader loader(isocreator); // make a callback object for playlist loading
- if (AGAVE_API_PLAYLISTMANAGER->Load(unicodeFilename, &loader) == PLAYLISTMANAGER_LOAD_NO_LOADER)
- {
- // not a playlist file, so load it normally
- // isocreator requires a preceding backslash
- StringCbPrintfW(destinationPath, sizeof(destinationPath), L"\\%s", PathFindFileNameW(unicodeFilename));
- isocreator->AddFile(unicodeFilename, destinationPath);
- }
- filenames+=strlen(filenames)+1;
- }
- isocreator->Write(destination, 0);
- }
- ReleaseISOCreator(isocreator);
- }
- }
- /**
- ** Load Playlist and write it to the ISO file
- ** this function is a bit complex, since we have to load the playlist
- ** through api_playlistmanager. This involves creating an playlist loader callback
- ** (ifc_playlistloadercallback) which gets called for each playlist item
- **/
- void ConvertPlaylistToISO(const mlPlaylist *playlist)
- {
- obj_isocreator *isocreator = CreateISOCreator();
- if (isocreator)
- {
- wchar_t destination[MAX_PATH];
- if (PromptForFilename(destination, MAX_PATH))
- {
- // these values are hardcoded for this example.
- const wchar_t *title=L"WinampISO";
- if (playlist->title) // if there's a playlist title, use it as the volume name
- title = playlist->title;
- isocreator->Open(title, obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
- ISOPlaylistLoader loader(isocreator); // make a callback object for playlist loading
- AGAVE_API_PLAYLISTMANAGER->Load(playlist->filename, &loader);
- isocreator->Write(destination, 0);
- }
- ReleaseISOCreator(isocreator);
- }
- }
- /** Load all playlists and write them to the ISO file
- ** this function is a bit complex, since we have to load the playlist
- ** through api_playlistmanager. This involves creating an playlist loader callback
- ** (ifc_playlistloadercallback) which gets called for each playlist item
- **/
- void ConvertPlaylistsToISO(const mlPlaylist **playlists)
- {
- obj_isocreator *isocreator = CreateISOCreator();
- if (isocreator)
- {
- wchar_t destination[MAX_PATH];
- if (PromptForFilename(destination, MAX_PATH))
- {
- // these values are hardcoded for this example.
- isocreator->Open(L"WinampISO", obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
- while (*playlists)
- {
- const mlPlaylist *playlist = *playlists;
- ISOPlaylistLoader loader(isocreator); // make a callback object for playlist loading
- AGAVE_API_PLAYLISTMANAGER->Load(playlist->filename, &loader);
- playlists++;
- }
- isocreator->Write(destination, 0);
- }
- ReleaseISOCreator(isocreator);
- }
- }
- void ConvertUnicodeItemRecordListToISO(const itemRecordListW *list)
- {
- obj_isocreator *isocreator = CreateISOCreator();
- if (isocreator)
- {
- wchar_t destination[MAX_PATH];
- if (PromptForFilename(destination, MAX_PATH))
- {
- // these values are hardcoded for this example.
- isocreator->Open(L"WinampISO", obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
- wchar_t destinationPath[MAX_PATH];
- // loop through the files and add them
- for (int i=0;i<list->Size;i++)
- {
- itemRecordW &item = list->Items[i];
- // since we have metadata, we're going to auto-generate folders based on the album name
- const wchar_t *album = item.album;
- if (!album || !*album)
- album = L"Unknown Album";
- // isocreator requires a preceding backslash
- StringCbPrintfW(destinationPath, sizeof(destinationPath), L"\\%s\\%s", album, PathFindFileNameW(item.filename));
- isocreator->AddFile(item.filename, destinationPath);
- }
- isocreator->Write(destination, 0);
- }
- ReleaseISOCreator(isocreator);
- }
- }
- void ConvertUnicodeFilenamesToISO(const wchar_t *filenames)
- {
- obj_isocreator *isocreator = CreateISOCreator();
- if (isocreator)
- {
- wchar_t destination[MAX_PATH];
- if (PromptForFilename(destination, MAX_PATH))
- {
- // these values are hardcoded for this example.
- isocreator->Open(L"WinampISO", obj_isocreator::FORMAT_JOLIET, obj_isocreator::MEDIA_CD);
- wchar_t destinationPath[MAX_PATH];
- // loop through the files and add them
- while (*filenames)
- {
- /**
- ** see if this file is a playlist file
- ** we'll do that by trying to load it
- ** the Load() function will fail gracefully if it's not a playlist file
- ** if it succeeds, it will call loader.OnFile() which adds it to the iso file
- **/
- ISOPlaylistLoader loader(isocreator); // make a callback object for playlist loading
- if (AGAVE_API_PLAYLISTMANAGER->Load(filenames, &loader) == PLAYLISTMANAGER_LOAD_NO_LOADER)
- {
- // not a playlist file, so load it normally
- // isocreator requires a preceding backslash
- StringCbPrintfW(destinationPath, sizeof(destinationPath), L"\\%s", PathFindFileNameW(filenames));
- isocreator->AddFile(filenames, destinationPath);
- }
- filenames+=wcslen(filenames)+1;
- }
- isocreator->Write(destination, 0);
- }
- ReleaseISOCreator(isocreator);
- }
- }
- /* --- Playlist Loader definition --- */
- ISOPlaylistLoader::ISOPlaylistLoader(obj_isocreator *_creator)
- {
- creator=_creator;
- }
- void ISOPlaylistLoader::OnFile(const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info)
- {
- // isocreator requires a preceding backslash
- wchar_t destinationPath[MAX_PATH];
- StringCbPrintfW(destinationPath, sizeof(destinationPath), L"\\%s", PathFindFileNameW(filename));
- // add file to .iso image
- creator->AddFile(filename, destinationPath);
- }
- #define CBCLASS ISOPlaylistLoader
- START_DISPATCH;
- VCB(IFC_PLAYLISTLOADERCALLBACK_ONFILE, OnFile)
- //VCB(IFC_PLAYLISTLOADERCALLBACK_ONPLAYLISTINFO, OnPlaylistInfo)
- END_DISPATCH;
|