123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- #include "Main.h"
- #include "../Agave/Component/ifc_wa5component.h"
- #include <vector>
- #include "api.h"
- #include "LazyServiceFactory.h"
- extern LARGE_INTEGER freq;
- std::vector<ifc_wa5component*> systemComponents;
- std::vector<LazyServiceFactory*> lazyFactories;
- enum
- {
- W5S_LOAD = 0,
- W5S_LAZYLOAD = 1,
- };
- static uint32_t magic_word = 0xdeadbeefUL;
- /* layout (binary)
- 0xdeadbeef - 32 bits
- service guid - 128 bits
- service fourcc - 32 bits
- length of service name - 16bits
- service name - see previous
- length of test string - 16 bits
- test string - see previous
- repeat as necessary
- */
- static int w5s_load_binary_manifest(const wchar_t *filename, const wchar_t *w5s_filename)
- {
- HANDLE manifest = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
- if (manifest != INVALID_HANDLE_VALUE)
- {
- for(;;)
- {
- uint32_t manifest_magic_word;
- GUID service_guid;
- FOURCC service_fourcc;
- DWORD bytesRead=0;
- ReadFile(manifest, &manifest_magic_word, sizeof(manifest_magic_word), &bytesRead, NULL);
- if (bytesRead == 0) // EOF
- {
- CloseHandle(manifest);
- return W5S_LAZYLOAD;
- }
- if (bytesRead != sizeof(manifest_magic_word) || memcmp(&manifest_magic_word, &magic_word, sizeof(magic_word)))
- break;
- bytesRead=0;
- ReadFile(manifest, &service_guid, sizeof(service_guid), &bytesRead, NULL);
- if (bytesRead != sizeof(service_guid))
- break;
- bytesRead=0;
- ReadFile(manifest, &service_fourcc, sizeof(service_fourcc), &bytesRead, NULL);
- if (bytesRead != sizeof(service_fourcc))
- break;
- uint16_t service_name_length;
- bytesRead=0;
- ReadFile(manifest, &service_name_length, sizeof(service_name_length), &bytesRead, NULL);
- if (bytesRead != sizeof(service_name_length))
- break;
- char *service_name = 0;
- if (service_name_length)
- {
- service_name = (char *)calloc(service_name_length + 1, sizeof(char));
- if (service_name)
- {
- bytesRead=0;
- ReadFile(manifest, service_name, service_name_length, &bytesRead, NULL);
- if (bytesRead != service_name_length)
- {
- free(service_name);
- break;
- }
- }
- }
- uint16_t service_test_string_length;
- bytesRead=0;
- ReadFile(manifest, &service_test_string_length, sizeof(service_test_string_length), &bytesRead, NULL);
- if (bytesRead != sizeof(service_test_string_length))
- break;
- char *service_test_string = 0;
- if (service_test_string_length)
- {
- service_test_string = (char *)calloc(service_test_string_length + 1, sizeof(char));
- if (service_name)
- {
- bytesRead=0;
- ReadFile(manifest, service_test_string, service_test_string_length, &bytesRead, NULL);
- if (bytesRead != service_test_string_length)
- {
- free(service_name);
- free(service_test_string);
- break;
- }
- }
- }
- // if we got here, we're OK :)
- LazyServiceFactory *factory = new LazyServiceFactory(service_fourcc, service_guid, service_name, service_test_string, w5s_filename);
- lazyFactories.push_back(factory);
- WASABI_API_SVC->service_register(factory);
- }
- // file seems to be malformed, go ahead and load w5s.
- // any lazy factories we already loaded will self-destruct when the real services load
- CloseHandle(manifest);
- return W5S_LOAD;
- }
- return W5S_LOAD;
- }
- void w5s_load(const wchar_t *filename)
- {
- HMODULE hLib = LoadLibraryW(filename);
- if (hLib == NULL)
- {
- auto err = GetLastError();
- }
-
- if (hLib)
- {
- typedef ifc_wa5component *(*W5SGetter)();
- W5SGetter pr = (W5SGetter)GetProcAddress(hLib,"GetWinamp5SystemComponent");
- if (pr)
- {
- ifc_wa5component *mod = pr();
- if (mod)
- {
- if (g_safeMode)
- {
- try
- {
- int retval = 0;
- mod->_dispatch(15, &retval);
- if (!retval)
- {
- FreeLibrary(hLib);
- return;
- }
- }
- catch(...)
- {
- FreeLibrary(hLib);
- return;
- }
- }
- systemComponents.push_back(mod);
- mod->hModule = hLib;
- mod->RegisterServices(WASABI_API_SVC);
- }
- }
- }
- }
- void w5s_init()
- {
- WIN32_FIND_DATAW d = {0};
- wchar_t dirstr[MAX_PATH] = {0};
- // pre-load so we're definitely available to other services which need this
- PathCombineW(dirstr, SYSPLUGINDIR, L"wasabi2.w5s");
- w5s_load(dirstr);
- PathCombineW(dirstr, SYSPLUGINDIR, L"*.W5S");
- HANDLE h = FindFirstFileW(dirstr, &d);
- if (h != INVALID_HANDLE_VALUE)
- {
- do
- {
- // due to how this plug-in works, is better to do a filename check to not load in
- // safe mode as it otherwise causes the FreeLibrary(..) call to crash Winamp :o(
- if (g_safeMode)
- {
- if (!wcsnicmp(d.cFileName, L"UnicodeTaskbarFix.w5s", 21)) continue;
- if (!wcsnicmp(d.cFileName, L"fpl.w5s", 7)) continue;
- if (!wcsnicmp(d.cFileName, L"mpcpl.w5s", 9)) continue;
- }
- if (lstrcmpiW(L"wasabi2.w5s", d.cFileName))
- {
- wchar_t manifeststr[MAX_PATH] = {0}, namestr[MAX_PATH] = {0};
- PathCombineW(manifeststr, SYSPLUGINDIR, d.cFileName);
- PathRemoveExtensionW(manifeststr);
- PathAddExtensionW(manifeststr, L".wbm");
- PathCombineW(namestr, SYSPLUGINDIR, d.cFileName);
- if (w5s_load_binary_manifest(manifeststr, namestr) == W5S_LOAD)
- {
- w5s_load(namestr);
- }
- }
- }
- while (FindNextFileW(h, &d));
- FindClose(h);
- }
- Wasabi_FindSystemServices();
- }
- void w5s_deinit()
- {
- Wasabi_ForgetSystemServices();
- for ( ifc_wa5component *l_wa5_component : systemComponents )
- {
- l_wa5_component->DeregisterServices( WASABI_API_SVC );
- l_wa5_component = 0;
- }
- systemComponents.clear();
- //lazyFactories.deleteAll();
- for ( auto obj : lazyFactories )
- {
- delete obj;
- }
- lazyFactories.clear();
- }
|