| 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 bitsservice guid - 128 bitsservice fourcc - 32 bitslength of service name - 16bitsservice name - see previouslength of test string - 16 bitstest string - see previousrepeat 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();}
 |