aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/SDK/ml_iso
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/SDK/ml_iso
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Plugins/SDK/ml_iso')
-rw-r--r--Src/Plugins/SDK/ml_iso/ToISO.cpp366
-rw-r--r--Src/Plugins/SDK/ml_iso/api__ml_iso.h10
-rw-r--r--Src/Plugins/SDK/ml_iso/main.cpp150
-rw-r--r--Src/Plugins/SDK/ml_iso/main.h12
-rw-r--r--Src/Plugins/SDK/ml_iso/ml_iso.rc122
-rw-r--r--Src/Plugins/SDK/ml_iso/ml_iso.sln24
-rw-r--r--Src/Plugins/SDK/ml_iso/ml_iso.vcxproj246
-rw-r--r--Src/Plugins/SDK/ml_iso/ml_iso.vcxproj.filters41
-rw-r--r--Src/Plugins/SDK/ml_iso/resource.h26
-rw-r--r--Src/Plugins/SDK/ml_iso/version.rc239
10 files changed, 1036 insertions, 0 deletions
diff --git a/Src/Plugins/SDK/ml_iso/ToISO.cpp b/Src/Plugins/SDK/ml_iso/ToISO.cpp
new file mode 100644
index 00000000..1a5e132f
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/ToISO.cpp
@@ -0,0 +1,366 @@
+#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;
diff --git a/Src/Plugins/SDK/ml_iso/api__ml_iso.h b/Src/Plugins/SDK/ml_iso/api__ml_iso.h
new file mode 100644
index 00000000..f95dc35f
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/api__ml_iso.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <api/service/api_service.h>
+
+#include <api/application/api_application.h>
+#define WASABI_API_APP applicationApi
+
+#include "../playlist/api_playlistmanager.h"
+extern api_playlistmanager *playlistManagerApi;
+#define AGAVE_API_PLAYLISTMANAGER playlistManagerApi
diff --git a/Src/Plugins/SDK/ml_iso/main.cpp b/Src/Plugins/SDK/ml_iso/main.cpp
new file mode 100644
index 00000000..764e25e6
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/main.cpp
@@ -0,0 +1,150 @@
+#include "main.h"
+#include "../Winamp/wa_ipc.h"
+#include "api__ml_iso.h"
+#include <api/service/waservicefactory.h>
+
+
+/* wasabi services we'll be using */
+api_service *WASABI_API_SVC = 0;
+api_application *WASABI_API_APP = 0;
+api_playlistmanager *AGAVE_API_PLAYLISTMANAGER = 0;
+
+/* gen_ml calls this function when it loads your plugin. return non-zero to abort loading your plugin */
+int Init()
+{
+ // this plugin requires an interface only present on 5.54 and up, so we'll just refuse to load on older versions
+ if (SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETVERSION) < 0x5054)
+ return 1;
+
+ // go ahead and grab the wasabi service manager. we'll need it later when we get an ISO Creator object
+ WASABI_API_SVC = (api_service *)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+
+ // get the application API
+ // we need this to get/set Winamp's current working directory
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(applicationApiServiceGuid);
+ if (factory)
+ WASABI_API_APP = (api_application *)factory->getInterface();
+
+ // get the playlist manager API
+ // we'll need this for loading playlists
+ factory = WASABI_API_SVC->service_getServiceByGuid(api_playlistmanagerGUID);
+ if (factory)
+ AGAVE_API_PLAYLISTMANAGER = (api_playlistmanager *)factory->getInterface();
+
+ // this media library plugin doesn't add a node to the treeview, so we don't really do anything in here besides
+ // grabbing the service manager
+ // all of the action will come via Send-To which is handled in MessageProc
+
+ return 0;
+}
+
+void Quit()
+{
+
+}
+
+INT_PTR MessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3)
+{
+ switch(message_type)
+ {
+ // this gets sent when Winamp wants to build the send-to menu. If we want to be in the send-to
+ // we make some API calls during this function
+ case ML_MSG_ONSENDTOBUILD:
+ {
+ INT_PTR source_type = param1; // param 1 is the source type
+ INT_PTR context = param2; // param 2 is just some context value that we have to use when we call back into the API
+
+ // we only accept certain types of sources, so we'll explicitly check
+ // if we were to handle ALL types, checking against the known types
+ // is good practice in case new Winamp versions add additional source types
+ switch(source_type)
+ {
+ case ML_TYPE_ITEMRECORDLIST: // Item Record List. Used by the local media library
+ case ML_TYPE_FILENAMES: // raw list of filenames
+ case ML_TYPE_PLAYLIST: // a playlist. we'll use the playlist loading API to crack it open
+ case ML_TYPE_PLAYLISTS: // a list of playlists. we'll use the playlist loading API to crack each one open
+ case ML_TYPE_ITEMRECORDLISTW: // unicode version of an Item Record List
+ case ML_TYPE_FILENAMESW: // raw list of unicode filenames
+ {
+ // add ourselves to the send-to menu!
+ mlAddToSendToStructW s;
+ s.context = context; // pass in the context value passed to this function.
+ s.desc = L"Create new ISO image";
+ s.user32 = (INT_PTR)MessageProc; // this value has to be some unique value that you can identify later
+ // by convention, use the pointer to this function, since it's obviously unique
+
+ SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)&s, ML_IPC_ADDTOSENDTOW);
+ }
+ // returning 0 tells the media library to continue building the send-to menu
+ // it doesn't mean we added or didn't add items to the send-to menu
+ return 0;
+ case ML_TYPE_STREAMNAMES: // doesn't make sense to burn a stream to an ISO file so we won't even popup on the send-to menu when it's streams
+ case ML_TYPE_CDTRACKS: // we'll avoid CD tracks. in theory we could use the ripping API but let's not complicate this example
+ case ML_TYPE_QUERYSTRING: // media library query. not sure that this is even used anywhere. either way we're not going to handle it
+ case ML_TYPE_STREAMNAMESW: // don't cross the streams
+ case ML_TYPE_TREEITEM: // not even sure this is used
+ // break out of here because it's not supported. returning 0 just tells the send-to menu to continue building,
+ // it doesn't mean we added or didn't add items to the send-to menu
+ return 0;
+ }
+ // shouldn't get here
+ return 0;
+ }
+
+// this gets sent when a send-to menu item got selected
+ // it might be ours. it might not.
+ case ML_MSG_ONSENDTOSELECT:
+ {
+ // let's see if it's ours. We check 'user32' against the function pointer for this function
+ INT_PTR unique = param3;
+ if (unique != (INT_PTR)MessageProc) // not ours? let's bail
+ return 0; // remember to always return 0 or else other media library plugins won't get the notification
+
+ INT_PTR type = param1; // what type of data got sent
+ INT_PTR data = param2; // pointer to the data. depends on the type
+
+ switch(type)
+ {
+ case ML_TYPE_ITEMRECORDLIST: // Item Record List. Used by the local media library
+ ConvertItemRecordListToISO((const itemRecordList *)data);
+ return 1; // return 1 to say we handled it
+ case ML_TYPE_FILENAMES: // raw list of filenames
+ ConvertFilenamesToISO((const char *)data);
+ return 1; // return 1 to say we handled it
+ case ML_TYPE_PLAYLIST: // a playlist. we'll use the playlist loading API to crack it open
+ ConvertPlaylistToISO((const mlPlaylist *)data);
+ return 1; // return 1 to say we handled it
+ case ML_TYPE_PLAYLISTS: // a list of playlists. we'll use the playlist loading API to crack each one open
+ ConvertPlaylistsToISO((const mlPlaylist **)data);
+ return 1; // return 1 to say we handled it
+ case ML_TYPE_ITEMRECORDLISTW: // unicode version of an Item Record List
+ ConvertUnicodeItemRecordListToISO((const itemRecordListW *)data);
+ return 1; // return 1 to say we handled it
+ case ML_TYPE_FILENAMESW: // raw list of unicode filenames
+ ConvertUnicodeFilenamesToISO((const wchar_t *)data);
+ return 1; // return 1 to say we handled it
+
+ default: // something we didn't support
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
+
+winampMediaLibraryPlugin plugin =
+{
+ MLHDR_VER,
+ "ISO Creator",
+ Init,
+ Quit,
+ MessageProc,
+ 0,
+ 0,
+ 0,
+};
+
+extern "C" __declspec(dllexport) winampMediaLibraryPlugin *winampGetMediaLibraryPlugin()
+ {
+ return &plugin;
+ }
diff --git a/Src/Plugins/SDK/ml_iso/main.h b/Src/Plugins/SDK/ml_iso/main.h
new file mode 100644
index 00000000..f9b04b6e
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/main.h
@@ -0,0 +1,12 @@
+#pragma once
+#include "..\..\General\gen_ml\ml.h"
+
+extern winampMediaLibraryPlugin plugin;
+
+void ConvertItemRecordListToISO(const itemRecordList *list);
+void ConvertFilenamesToISO(const char *filenames);
+void ConvertPlaylistToISO(const mlPlaylist *playlist);
+void ConvertPlaylistsToISO(const mlPlaylist **playlist);
+void ConvertUnicodeItemRecordListToISO(const itemRecordListW *list);
+void ConvertUnicodeFilenamesToISO(const wchar_t *filenames);
+
diff --git a/Src/Plugins/SDK/ml_iso/ml_iso.rc b/Src/Plugins/SDK/ml_iso/ml_iso.rc
new file mode 100644
index 00000000..07c90471
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/ml_iso.rc
@@ -0,0 +1,122 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_VIEW_BM_ACCELERATORS ACCELERATORS
+BEGIN
+
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_NULLSOFT_ISO "Nullsoft ISO Example Media Library Plug-in v%s"
+ 65535 "{A3A1E7C0-761B-4391-A08A-F0D7AF38931C}"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_ISO "ISO"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/SDK/ml_iso/ml_iso.sln b/Src/Plugins/SDK/ml_iso/ml_iso.sln
new file mode 100644
index 00000000..cc6aefdf
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/ml_iso.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32802.440
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ml_iso", "ml_iso.vcxproj", "{229EE189-137B-4E20-804D-CA1F71810332}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {229EE189-137B-4E20-804D-CA1F71810332}.Debug|x86.ActiveCfg = Debug|Win32
+ {229EE189-137B-4E20-804D-CA1F71810332}.Debug|x86.Build.0 = Debug|Win32
+ {229EE189-137B-4E20-804D-CA1F71810332}.Release|x86.ActiveCfg = Release|Win32
+ {229EE189-137B-4E20-804D-CA1F71810332}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {85243140-49BA-42D9-AC20-4B3F643E9127}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj b/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj
new file mode 100644
index 00000000..97c12b70
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{229EE189-137B-4E20-804D-CA1F71810332}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>16.0.32629.160</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules />
+ <CodeAnalysisRuleAssemblies />
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnabled>false</VcpkgEnabled>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ML_ISO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ML_ISO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ML_ISO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <IgnoreSpecificDefaultLibraries>msvcprt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ML_ISO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <IgnoreSpecificDefaultLibraries>msvcprt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="ToISO.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api__ml_iso.h" />
+ <ClInclude Include="main.h" />
+ <ClInclude Include="resource.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ml_iso.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj.filters b/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj.filters
new file mode 100644
index 00000000..2e8c4e3d
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/ml_iso.vcxproj.filters
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ToISO.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="main.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="api__ml_iso.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ml_iso.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/SDK/ml_iso/resource.h b/Src/Plugins/SDK/ml_iso/resource.h
new file mode 100644
index 00000000..d24b69a0
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/resource.h
@@ -0,0 +1,26 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ml_iso.rc
+//
+#define IDS_ISO 1
+#define IDR_MENU1 101
+#define IDC_CURSOR1 105
+#define IDB_BITMAP1 106
+#define IDR_VIEW_BM_ACCELERATORS 111
+#define IDC_BUTTON_CUSTOM 1000
+#define IDC_LIST 1001
+#define ID_Menu 40001
+#define ID_ISO_HELP 40002
+#define ID_ISO_SENDTO 40003
+#define IDS_NULLSOFT_ISO 65534
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 112
+#define _APS_NEXT_COMMAND_VALUE 40004
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/SDK/ml_iso/version.rc2 b/Src/Plugins/SDK/ml_iso/version.rc2
new file mode 100644
index 00000000..7298f068
--- /dev/null
+++ b/Src/Plugins/SDK/ml_iso/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "..\..\..\Winamp\buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Media Library Plug-in"
+ VALUE "FileVersion", "1,0,0,1"
+ VALUE "InternalName", "Nullsoft ISO"
+ VALUE "LegalCopyright", "Copyright © 2003-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "ml_iso.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END