| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781 | /** (c) Nullsoft, Inc.         C O N F I D E N T I A L** Filename: ** Project:** Description:** Author:** Created:**/#include "main.h"#include "resource.h"#include "../nsv/enc_if.h"#include "../nu/threadname.h"#include "../nu/AutoWideFn.h"#include "../nu/AutoCharFn.h"#include "DecodeFile.h"extern DecodeFile *decodeFile;static wchar_t DLL_Dir[MAX_PATH];static intptr_t getEncoderFromFolder(const wchar_t *spec, int bps, int nch, int srate, int dstf, const wchar_t *curdir, int create, HMODULE *pmod, HWND hParent, converterEnumFmtStruct *enumCrap, char * inifile){	WIN32_FIND_DATAW fd = {0};	wchar_t buf[MAX_PATH*2 + 1] = {0};	PathCombineW(buf, curdir, spec);	if (pmod) *pmod = NULL;	HANDLE h = FindFirstFileW(buf, &fd);	if (h != INVALID_HANDLE_VALUE)	{		do		{			PathCombineW(buf, curdir, fd.cFileName);			HMODULE mod = LoadLibraryW(buf);			if (mod)			{				// passes winamp's hwnd to the encoder (if supporting it)				void (*swh)(HWND hwnd);				*((void **)&swh) = GetProcAddress(mod, "SetWinampHWND");				if (swh)				{					swh(hMainWindow);				}				if (enumCrap)				{					unsigned int (*gat)(int idx, char *desc);					*((void **)&gat) = GetProcAddress(mod, "GetAudioTypes3");					if (gat)					{						int i = 0;						for (;;)						{							char desc[1024] = {0};							unsigned int type = gat(i++, desc);							if (!type) break;							enumCrap->enumProc(enumCrap->user_data, desc, type);						}					}				}				else				{					void (*ExtAudio3)(HWND hwndParent, int *ex, int ex_len);					*((void **)&ExtAudio3) = GetProcAddress(mod, "ExtAudio3");					if (ExtAudio3) ExtAudio3(hMainWindow, NULL, 0);					AudioCoder *ac = 0;					AudioCoder *(*ca)(int nch, int srate, int bps, unsigned int srct, unsigned int *outt, char *configfile);					*((void **)&ca) = GetProcAddress(mod, "CreateAudio3");					if (create == 0)					{						HWND (*ca)(HWND hwndParent, HINSTANCE hinst, unsigned int outt, char *configfile);						*((void**)&ca) = GetProcAddress(mod, "ConfigAudio3");						if (ca)						{							HWND h = ca(hParent, mod, dstf, inifile?inifile:INI_FILEA);							if (h)							{								*pmod = mod;								return (intptr_t)h;							}						}					}					//if (ca && (ac=ca(nch,srate,bps,srct,outt,configfile))) return ac;					if (create == 1 && ca && (ac = ca(nch, srate, bps, mmioFOURCC('P', 'C', 'M', ' '), (unsigned int *) & dstf, inifile?inifile:INI_FILEA))) //FUCKO: input format					{						*pmod = mod;						return (intptr_t)ac;					}					if (create == 2) {						unsigned int (*gat)(int idx, char *desc);						*((void **)&gat) = GetProcAddress(mod, "GetAudioTypes3");						if (gat)						{							int i = 0;							for (;;)							{								char desc[1024] = {0};								unsigned int type = gat(i++, desc);								if (!type) break;								if (type == dstf) {									*pmod = mod;									return 0;								}							}						}					}				}				FreeLibrary(mod);			}		}		while (FindNextFileW(h, &fd));		FindClose(h);	}	return 0;}static intptr_t getEncoder(int bps, int nch, int srate, int *destformat, int create, HMODULE *pmod, HWND parent, converterEnumFmtStruct *enumCrap = 0,char * inifile=0){	HKEY hKey = NULL;	if (!DLL_Dir[0] && RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion",		0, KEY_READ, &hKey) == ERROR_SUCCESS)	{		DWORD l = sizeof(DLL_Dir);		DWORD t = 0;		if (RegQueryValueExW(hKey, L"CommonFilesDir", NULL, &t, (LPBYTE)DLL_Dir, &l ) != ERROR_SUCCESS || t != REG_SZ)			DLL_Dir[0] = 0;		PathAppendW(DLL_Dir, L"NSV");		RegCloseKey(hKey);	}	if (!DLL_Dir[0]) GetTempPathW(sizeof(DLL_Dir)/sizeof(*DLL_Dir), DLL_Dir);	//look in plugins folder	int ret;	if (ret = getEncoderFromFolder(L"enc_*.dll", bps, nch, srate, destformat[0], PLUGINDIR, create, pmod, parent, enumCrap,inifile)) 		return ret;	if (GetPrivateProfileIntW(AutoWide(app_name), L"scannsv", 0, INI_FILE))	{		//look in common files folder		if (ret = getEncoderFromFolder(L"nsv_coder_*.dll", bps, nch, srate, destformat[0], DLL_Dir, create, pmod, parent, enumCrap,inifile)) 			return ret;	}	return 0;}static DWORD WINAPI convertThread(void *param){	convertFileStruct *cfs = (convertFileStruct *)param;	ifc_audiostream *decoder = cfs->decoder;	HANDLE fh = cfs->file_handle;	AudioCoder *ac = cfs->audio_coder;	HMODULE mod = cfs->encoder_mod;	int destformat = cfs->destformat[0];	int bps = cfs->bps;	int nch = cfs->channels;	//int srate = cfs->sample_rate;	size_t bytes_per_packet = nch*(bps/8);	size_t ret = 0;	SetThreadName((DWORD)-1, "Transcode");	cfs->bytes_done = 0;	cfs->bytes_out = 0;	DWORD laststatpost = 0;	do	{		int error=0;		char buf[65536] = {0};		size_t buf_size = sizeof(buf);		buf_size -= (buf_size % bytes_per_packet); // don't read half a sample or only some of the channels!		ret = decoder->ReadAudio(buf, buf_size, &cfs->killswitch, &error);		if (destformat == mmioFOURCC('P', 'C', 'M', ' ') /* || destformat==mmioFOURCC('W','A','V',' ')*/)		{			//FUCKO: resample in desired format			DWORD a = 0;			if (ret > 0) WriteFile(fh, buf, (DWORD)ret, &a, NULL);			cfs->bytes_out += a;		}		else		{			int framepos = 0;			int avail = (int) ret;			char *in = buf;			char out[32768] = {0};			// WM encoding needs to know that you're going to be done, before you stop calling Encode(...)			if ( ret == 0 )			{				if (ac && mod)				{					void (*finish)(const char *filename, AudioCoder *coder);					*((void **)&finish) = GetProcAddress(mod, "PrepareToFinish");					if (finish)					{						finish(cfs->destfile, ac);					}				}			}			for (;;)			{				int in_used = 0;				int v = ac->Encode(framepos++, in, avail, &in_used, out, sizeof(out));				if (v > 0)				{					DWORD a = 0;					WriteFile(fh, out, v, &a, NULL);					cfs->bytes_out += v;				}				if (in_used > 0)				{					avail -= in_used;					in += in_used;				}				if (!v && !in_used) break;			}		}		cfs->bytes_done += (int)ret;		if (GetTickCount() - laststatpost > 1000)		{			SendMessageW(cfs->callbackhwnd, WM_WA_IPC, (int)((double)cfs->bytes_done*100.0 / (double)cfs->bytes_total), IPC_CB_CONVERT_STATUS);			laststatpost = GetTickCount();		}	}	while (!cfs->killswitch && ret > 0);	CloseHandle(fh);	if (ac && mod)	{		void (*finish)(const char *filename, AudioCoder *coder);		*((void **)&finish) = GetProcAddress(mod, "FinishAudio3");		if (finish)		{			finish(cfs->destfile, ac);		}	}	decodeFile->CloseAudio(decoder);	if (!cfs->killswitch) PostMessageW(cfs->callbackhwnd, WM_WA_IPC, 0, IPC_CB_CONVERT_DONE);	return 1;}static DWORD WINAPI convertThreadW(void *param){	convertFileStructW *cfs = (convertFileStructW *)param;	ifc_audiostream *decoder = (ifc_audiostream *)cfs->decoder;	HANDLE fh = cfs->file_handle;	AudioCoder *ac = cfs->audio_coder;	HMODULE mod = cfs->encoder_mod;	int destformat = cfs->destformat[0];	int bps = cfs->bps;	int nch = cfs->channels;	//int srate = cfs->sample_rate;	size_t bytes_per_packet = nch*(bps/8);	size_t ret = 0;	SetThreadName((DWORD)-1, "Transcode");	cfs->bytes_done = 0;	cfs->bytes_out = 0;	DWORD laststatpost = 0;	do	{		int error=0;		char buf[65536] = {0};		size_t buf_size = sizeof(buf);		buf_size -= (buf_size % bytes_per_packet); // don't read half a sample or only some of the channels!		ret = decoder->ReadAudio(buf, buf_size, &cfs->killswitch, &error);		if (destformat == mmioFOURCC('P', 'C', 'M', ' ') /* || destformat==mmioFOURCC('W','A','V',' ')*/)		{			//FUCKO: resample in desired format			DWORD a = 0;			if (ret > 0) WriteFile(fh, buf, (DWORD)ret, &a, NULL);			cfs->bytes_out += a;		}		else		{			int framepos = 0;			int avail = (int) ret;			char *in = buf;			char out[32768] = {0};			// WM encoding needs to know that you're going to be done, before you stop calling Encode(...)			if ( ret == 0 )			{				if (ac && mod)				{					// try unicode first					void (*finishW)(const wchar_t *filename, AudioCoder *coder);					*((void **)&finishW) = GetProcAddress(mod, "PrepareToFinishW");					if (finishW)					{						finishW(cfs->destfile, ac);					}					else // otherwise, pass it the 8.3 filename					{						void (*finish)(const char *filename, AudioCoder *coder);						*((void **)&finish) = GetProcAddress(mod, "PrepareToFinish");						if (finish)						{							finish(AutoCharFn(cfs->destfile), ac);						}					}				}			}			for (;;)			{				int in_used = 0;				int v = ac->Encode(framepos++, in, avail, &in_used, out, sizeof(out));				if (v > 0)				{					DWORD a = 0;					WriteFile(fh, out, v, &a, NULL);					cfs->bytes_out += v;				}				if (in_used > 0)				{					avail -= in_used;					in += in_used;				}				if (!v && !in_used) break;			}		}		cfs->bytes_done += (int)ret;		if (GetTickCount() - laststatpost > 1000)		{			SendMessageW(cfs->callbackhwnd, WM_WA_IPC, (int)((double)cfs->bytes_done*100.0 / (double)cfs->bytes_total), IPC_CB_CONVERT_STATUS);			laststatpost = GetTickCount();		}	}	while (!cfs->killswitch && ret > 0);	CloseHandle(fh);	if (ac && mod)	{		void (*finishW)(const wchar_t *filename, AudioCoder *coder);		*((void **)&finishW) = GetProcAddress(mod, "FinishAudio3W");		if (finishW)		{			finishW(cfs->destfile, ac);		}		else // otherwise, try the 8.3 filename		{			void (*finish)(const char *filename, AudioCoder *coder);			*((void **)&finish) = GetProcAddress(mod, "FinishAudio3");			if (finish)			{				finish(AutoCharFn(cfs->destfile), ac);			}		}	}	decodeFile->CloseAudio(decoder);	if (!cfs->killswitch) PostMessageW(cfs->callbackhwnd, WM_WA_IPC, 0, IPC_CB_CONVERT_DONE);	return 1;}// due to the language support, we can't just now return the string in cfs->error// but instead have to have it in a static string so it can be accessed once we// have returned without issues from later use of getString and it's buffer usagestatic char errorStr[2048];int convert_file(convertFileStruct *cfs){	// clear the buffer on starting otherwise we may return an invalid error message	//memset(&errorStr, 0, sizeof(errorStr));	errorStr[0]=0;	if (cfs->destfile && cfs->sourcefile && !_stricmp(cfs->destfile, cfs->sourcefile))	{		cfs->error = getString(IDS_CONV_SRC_EQUALS_DEST,errorStr,2048);		return 0;	}	AudioParameters parameters;	ifc_audiostream *decoder = decodeFile->OpenAudioBackground(AutoWideFn(cfs->sourcefile), ¶meters);	cfs->bytes_total= (int)(parameters.sizeBytes?parameters.sizeBytes:-1);	if (!decoder)	{		switch(parameters.errorCode)		{			case API_DECODEFILE_UNSUPPORTED:				cfs->error = getString(IDS_CONV_DECODER_MISSING,errorStr,2048);				return 0;			case API_DECODEFILE_NO_INTERFACE:				cfs->error = getString(IDS_CONV_INPUT_PLUGIN_NOT_SUPPORTING,errorStr,2048);				return 0;			case API_DECODEFILE_NO_RIGHTS:				cfs->error = getString(IDS_CONV_DRM_DECODE_FAIL,errorStr,2048);				return 0;			case API_DECODEFILE_FAIL_NO_WARN:				return 0;			default:				cfs->error = getString(IDS_CONV_ERROR_OPEN_FILE,errorStr,2048);				return 0;		}	}		cfs->decoder=0;	cfs->convert_thread=0;	cfs->file_handle=0;	cfs->audio_coder=0;	cfs->encoder_mod=0;	cfs->bps=0;	cfs->channels=0;	cfs->sample_rate=0;	//find the encoding DLL	if (cfs->destformat[0] != mmioFOURCC('P', 'C', 'M', ' '))	{		HMODULE mod = NULL;		char * inifile = NULL;		if(cfs->destformat[6] == mmioFOURCC('I','N','I',' ')) inifile = (char*)cfs->destformat[7];		AudioCoder *ac = (AudioCoder *)getEncoder(parameters.bitsPerSample, parameters.channels, parameters.sampleRate, (int *) & cfs->destformat, 1, &mod, NULL,0, inifile);		if (!ac)		{			decodeFile->CloseAudio(decoder);			cfs->error = getString(IDS_CONV_ERROR_OPEN_ENCODER,errorStr,2048);			return 0;		}		cfs->audio_coder = ac;		cfs->encoder_mod = mod;	}	cfs->killswitch = 0;	cfs->decoder = decoder;	cfs->bps = parameters.bitsPerSample;	cfs->channels = parameters.channels;	cfs->sample_rate = parameters.sampleRate;	//open destination file	HANDLE fh = CreateFileA(cfs->destfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);	if ( fh == INVALID_HANDLE_VALUE )	{		decodeFile->CloseAudio(decoder);		delete cfs->audio_coder;		cfs->audio_coder = 0;		cfs->error = getString(IDS_CONV_ERROR_OPEN_DEST,errorStr,2048);		return 0;	}	cfs->file_handle = fh;	DWORD id = 0;	cfs->convert_thread = CreateThread(NULL, 0, convertThread, cfs, 0, &id);	return 1;}static wchar_t errorStrW[2048];int convert_fileW(convertFileStructW *cfs){	// clear the buffer on starting otherwise we may return an invalid error message	memset(&errorStrW, 0, sizeof(errorStrW));	if (cfs->destfile && cfs->sourcefile && !_wcsicmp(cfs->destfile, cfs->sourcefile))	{		cfs->error = getStringW(IDS_CONV_SRC_EQUALS_DEST,errorStrW,2048);		return 0;	}	AudioParameters parameters;	ifc_audiostream *decoder = decodeFile->OpenAudioBackground(cfs->sourcefile, ¶meters);	cfs->bytes_total= (int)(parameters.sizeBytes?parameters.sizeBytes:-1);	if (!decoder)	{		switch(parameters.errorCode)		{			case API_DECODEFILE_UNSUPPORTED:				cfs->error = getStringW(IDS_CONV_DECODER_MISSING,errorStrW,2048);				return 0;			case API_DECODEFILE_NO_INTERFACE:				cfs->error = getStringW(IDS_CONV_INPUT_PLUGIN_NOT_SUPPORTING,errorStrW,2048);				return 0;			case API_DECODEFILE_NO_RIGHTS:				cfs->error = getStringW(IDS_CONV_DRM_DECODE_FAIL,errorStrW,2048);				return 0;			case API_DECODEFILE_FAIL_NO_WARN:				return 0;			default:				cfs->error = getStringW(IDS_CONV_ERROR_OPEN_FILE,errorStrW,2048);				return 0;		}	}	cfs->decoder=0;	cfs->convert_thread=0;	cfs->file_handle=0;	cfs->audio_coder=0;	cfs->encoder_mod=0;	cfs->bps=0;	cfs->channels=0;	cfs->sample_rate=0;	//find the encoding DLL	if (cfs->destformat[0] != mmioFOURCC('P', 'C', 'M', ' '))	{		HMODULE mod = NULL;		char * inifile = NULL;		if(cfs->destformat[6] == mmioFOURCC('I','N','I',' ')) inifile = (char*)cfs->destformat[7];		AudioCoder *ac = (AudioCoder *)getEncoder(parameters.bitsPerSample, parameters.channels, parameters.sampleRate, (int *) & cfs->destformat, 1, &mod, NULL,0, inifile);		if (!ac)		{			decodeFile->CloseAudio(decoder);			cfs->error = getStringW(IDS_CONV_ERROR_OPEN_ENCODER,errorStrW,2048);			return 0;		}		cfs->audio_coder = ac;		cfs->encoder_mod = mod;	}	cfs->killswitch = 0;	cfs->decoder = decoder;	cfs->bps = parameters.bitsPerSample;	cfs->channels = parameters.channels;	cfs->sample_rate = parameters.sampleRate;	//open destination file	HANDLE fh = CreateFileW(cfs->destfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);	if ( fh == INVALID_HANDLE_VALUE )	{		decodeFile->CloseAudio(decoder);		delete cfs->audio_coder;		cfs->audio_coder = 0;		FreeLibrary(cfs->encoder_mod);		cfs->encoder_mod = 0;		cfs->error = getStringW(IDS_CONV_ERROR_OPEN_DEST,errorStrW,2048);		return 0;	}	cfs->file_handle = fh;	DWORD id = 0;	cfs->convert_thread = CreateThread(NULL, 0, convertThreadW, cfs, 0, &id);	return 1;}int convert_file_test(convertFileStructW *cfs){	// clear the buffer on starting otherwise we may return an invalid error message	errorStrW[0]=0;	AudioCoder *ac=0;	HMODULE mod=0;	if (cfs->destfile && cfs->sourcefile && !_wcsicmp(cfs->destfile, cfs->sourcefile))	{		cfs->error = getStringW(IDS_CONV_SRC_EQUALS_DEST,errorStrW,2048);		return 0;	}	AudioParameters parameters;	ifc_audiostream *decoder = decodeFile->OpenAudioBackground(cfs->sourcefile, ¶meters);	cfs->bytes_total= (int)(parameters.sizeBytes?parameters.sizeBytes:-1);	if (!decoder)	{		switch(parameters.errorCode)		{			case API_DECODEFILE_UNSUPPORTED:				cfs->error = getStringW(IDS_CONV_DECODER_MISSING,errorStrW,2048);				return 0;			case API_DECODEFILE_NO_INTERFACE:				cfs->error = getStringW(IDS_CONV_INPUT_PLUGIN_NOT_SUPPORTING,errorStrW,2048);				return 0;			case API_DECODEFILE_NO_RIGHTS:				cfs->error = getStringW(IDS_CONV_DRM_DECODE_FAIL,errorStrW,2048);				return 0;			case API_DECODEFILE_FAIL_NO_WARN:				return 0;			default:				cfs->error = getStringW(IDS_CONV_ERROR_OPEN_FILE,errorStrW,2048);				return 0;		}	}	decodeFile->CloseAudio(decoder);	cfs->decoder=0;	cfs->convert_thread=0;	cfs->file_handle=0;	cfs->audio_coder=0;	cfs->encoder_mod=0;	cfs->bps=0;	cfs->channels=0;	cfs->sample_rate=0;	//find the encoding DLL	if (cfs->destformat[0] != mmioFOURCC('P', 'C', 'M', ' '))	{		char * inifile = NULL;		if(cfs->destformat[6] == mmioFOURCC('I','N','I',' ')) inifile = (char*)cfs->destformat[7];		ac = (AudioCoder *)getEncoder(parameters.bitsPerSample, parameters.channels, parameters.sampleRate, (int *) & cfs->destformat, 1, &mod, NULL,0, inifile);		if (!ac)		{			cfs->error = getStringW(IDS_CONV_ERROR_OPEN_ENCODER,errorStrW,2048);			return 0;		}		cfs->audio_coder = ac;		cfs->encoder_mod = mod;	}	cfs->killswitch = 0;	cfs->decoder = decoder;	cfs->bps = parameters.bitsPerSample;	cfs->channels = parameters.channels;	cfs->sample_rate = parameters.sampleRate;	//open destination file	HANDLE fh = CreateFileW(cfs->destfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);	if ( fh == INVALID_HANDLE_VALUE )	{		delete ac;		cfs->audio_coder = 0;		FreeLibrary(mod);		cfs->encoder_mod = 0;		cfs->error = getStringW(IDS_CONV_ERROR_OPEN_DEST,errorStrW,2048);		return 0;	}	delete ac;	cfs->audio_coder = 0;	FreeLibrary(mod);	cfs->encoder_mod = 0;	CloseHandle(fh);	return 1;}void convert_end(convertFileStruct *cfs){	HANDLE handle = cfs->convert_thread;	cfs->killswitch = 1;	if (handle && handle != INVALID_HANDLE_VALUE)	{		WaitForSingleObject(handle, 20000);		CloseHandle(handle);		cfs->convert_thread = INVALID_HANDLE_VALUE;	}	delete(cfs->audio_coder);	cfs->audio_coder = 0;	HMODULE mod = cfs->encoder_mod;	if (mod)	{		FreeLibrary(mod);		cfs->encoder_mod = 0;	}}void convert_endW(convertFileStructW *cfs){	HANDLE handle = cfs->convert_thread;	cfs->killswitch = 1;	if (handle && handle != INVALID_HANDLE_VALUE)	{		WaitForSingleObject(handle, 20000);		CloseHandle(handle);		cfs->convert_thread = INVALID_HANDLE_VALUE;	}	delete(cfs->audio_coder);	cfs->audio_coder = 0;	HMODULE mod = cfs->encoder_mod;	if (mod)	{		FreeLibrary(mod);		cfs->encoder_mod = 0;	}}void convert_enumfmts(converterEnumFmtStruct *cefs){	//	cefs->enumProc(cefs->user_data, ".WAV output", mmioFOURCC('W', 'A', 'V', ' '));	int destformat[8] = {0};	getEncoder(0, 0, 0, (int *)&destformat, 0, NULL, 0, cefs);}HWND convert_config(convertConfigStruct *ccs){	HMODULE mod = NULL;	int destformat[8] = {ccs->format, };	char * inifile = NULL;	if(ccs->extra_data[6] == mmioFOURCC('I','N','I',' ')) 		inifile = (char*)ccs->extra_data[7];	HWND h = (HWND)getEncoder(0, 0, 0, (int *) & destformat, 0, &mod, ccs->hwndParent,0,inifile);	ccs->hwndConfig = h;	ccs->extra_data[0] = (intptr_t)mod;	return h;}void convert_config_end(convertConfigStruct *ccs){	HMODULE mod = (HMODULE)ccs->extra_data[0];	DestroyWindow(ccs->hwndConfig);	if (mod) FreeLibrary(mod);}void convert_setPriority(convertSetPriority *csp){	if (csp->cfs)	{		HANDLE handle = csp->cfs->convert_thread;		if (handle)			SetThreadPriority(handle, csp->priority);		else		{			//FUCKO> handle when separate process		}	}}void convert_setPriorityW(convertSetPriorityW *csp){	if (csp->cfs)	{		HANDLE handle = (void *)csp->cfs->convert_thread;		if (handle)			SetThreadPriority(handle, csp->priority);		else		{			//FUCKO> handle when separate process		}	}}int convert_setConfigItem(convertConfigItem *cci) {	int ret = 0;	int destformat[8] = {(int)cci->format, };	HMODULE mod = NULL;	if (!cci->configfile) cci->configfile=INI_FILEA;	getEncoder(0,0,0, (int *) & destformat, 2, &mod, NULL,0,cci->configfile);	if(mod) {		int (*sci)(unsigned int outt, char *item, char *data, char *configfile);		*((void **)&sci) = GetProcAddress(mod, "SetConfigItem");		if(sci) {			ret = sci(cci->format,cci->item,cci->data,cci->configfile);		}		FreeLibrary(mod);	}	return ret;}int convert_getConfigItem(convertConfigItem *cci) {	int ret = 0;	int destformat[8] = {(int)cci->format, };	HMODULE mod = NULL;	if (!cci->configfile) cci->configfile=INI_FILEA;	getEncoder(0,0,0, (int *) & destformat, 2, &mod, NULL,0,cci->configfile);	if(mod) {		int (*gci)(unsigned int outt, char *item, char *data, int len, char *configfile);		*((void **)&gci) = GetProcAddress(mod, "GetConfigItem");		if(gci) {			ret = gci(cci->format,cci->item,cci->data,cci->len,cci->configfile);		}		FreeLibrary(mod);	}	return ret;}
 |