Ejemplo n.º 1
0
//---------------------------------------------------------------------------
static TStringList * TVPGetConfigFileOptions(AnsiString filename)
{
	// load .cf file
	AnsiString errmsg;
	if(!FileExists(filename))
		errmsg = "file not found.";

	TStringList * ret = new TStringList();
	if(errmsg == "")
	{
		try
		{
			ret->LoadFromFile(filename);
		}
		catch(Exception & e)
		{
			errmsg = e.Message;
		}
		catch(...)
		{
			delete ret;
			throw;
		}
	}

	if(errmsg != "")
		TVPAddImportantLog(ttstr("(info) Loading configuration file \"") + filename.c_str() +
			"\" failed (ignoring) : " + errmsg.c_str());
	else
		TVPAddImportantLog(ttstr("(info) Loading configuration file \"") + filename.c_str() +
			"\" succeeded.");

	return ret;
}
Ejemplo n.º 2
0
//---------------------------------------------------------------------------
void TVPEnsureDataPathDirectory()
{
	if(!TVPDataPathDirectoryEnsured)
	{
		TVPDataPathDirectoryEnsured = true;
		// ensure data path existence
		if(!TVPCheckExistentLocalFolder(TVPNativeDataPath.c_str()))
		{
			ttstr msg("(info) Data path does not exist, trying to make it ... ");
			if(TVPCreateFolders(TVPNativeDataPath.c_str()))
				TVPAddImportantLog(msg + "ok.");
			else
				TVPAddImportantLog(msg + "failed.");
		}
	}
}
Ejemplo n.º 3
0
//---------------------------------------------------------------------------
void __fastcall TTVPMainForm::SystemWatchTimerTimer(TObject *Sender)
{
	if(TVPTerminated)
	{
		// this will ensure terminating the application.
		// the WM_QUIT message disappears in some unknown situations...
		::PostMessage(TVPMainForm->Handle, WM_USER+0x31/*dummy msg*/, 0, 0);
		Application->Terminate();
		::PostMessage(TVPMainForm->Handle, WM_USER+0x31/*dummy msg*/, 0, 0);
	}

	// call events
	DWORD tick = GetTickCount();

	// push environ noise
	TVPPushEnvironNoise(&tick, sizeof(tick));
	TVPPushEnvironNoise(&LastCompactedTick, sizeof(LastCompactedTick));
	TVPPushEnvironNoise(&LastShowModalWindowSentTick, sizeof(LastShowModalWindowSentTick));
	TVPPushEnvironNoise(&MixedIdleTick, sizeof(MixedIdleTick));
	POINT pt;
	GetCursorPos(&pt);
	TVPPushEnvironNoise(&pt, sizeof(pt));

	// CPU clock monitoring
	{
		static bool clock_rough_printed = false;
		if(!clock_rough_printed && TVPCPUClockAccuracy == ccaRough)
		{
			tjs_char msg[80];
			TJS_sprintf(msg, TJS_W("(info) CPU clock (roughly) : %dMHz"), (int)TVPCPUClock);
			TVPAddImportantLog(msg);
			clock_rough_printed = true;
		}
		static bool clock_printed = false;
		if(!clock_printed && TVPCPUClockAccuracy == ccaAccurate)
		{
			tjs_char msg[80];
			TJS_sprintf(msg, TJS_W("(info) CPU clock : %.1fMHz"), (float)TVPCPUClock);
			TVPAddImportantLog(msg);
			clock_printed = true;
		}
	}

	// check status and deliver events
	DeliverEvents();

	// call TickBeat
	tjs_int count = TVPGetWindowCount();
	for(tjs_int i = 0; i<count; i++)
	{
		tTJSNI_Window *win = TVPGetWindowListAt(i);
		win->TickBeat();
	}

	if(!ContinuousEventCalling && tick - LastCompactedTick > 4000)
	{
		// idle state over 4 sec.
		LastCompactedTick = tick;

		// fire compact event
		TVPDeliverCompactEvent(TVP_COMPACT_LEVEL_IDLE);
	}

	if(!ContinuousEventCalling && tick > LastRehashedTick + 1500)
	{
		// TJS2 object rehash
		LastRehashedTick = tick;
		TJSDoRehash();
	}

	if(LastCloseClickedTick && tick - LastCloseClickedTick > 3100)
	{
		// display force suicide confirmation form
		if(TVPHaltWarnForm)
		{
			TVPHaltWarnForm->Visible = true;
		}
		else
		{
			TVPHaltWarnForm = new TTVPHaltWarnForm(Application);
			TVPHaltWarnForm->Visible = true;
		}
	}

	// ensure modal window visible
	if(tick > LastShowModalWindowSentTick + 4100)
	{
		//	::PostMessage(Handle, WM_USER+0x32, 0, 0);
		// This is currently disabled because IME composition window
		// hides behind the window which is bringed top by the
		// window-rearrangement.
		LastShowModalWindowSentTick = tick;
	}

}
Ejemplo n.º 4
0
/**
 * copyright表示用
 */
void showXMLCopyright()
{
	TVPAddImportantLog(ttstr(copyright));
}
Ejemplo n.º 5
0
USEFORM("..\..\..\..\tools\win32\krdevui\ConfMainFrameUnit.cpp", ConfMainFrame); /* TFrame: File Type */
//---------------------------------------------------------------------------
#ifdef TVP_SUPPORT_ERI
#	pragma link "../../../../Lib/liberina.lib"
#endif
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	// try starting the program!
	bool engine_init = false;
	try
	{
		if(TVPCheckProcessLog()) return 0; // sub-process for processing object hash map log


		TVPInitScriptEngine();
		engine_init = true;

		// banner
		TVPAddImportantLog(TJS_W("Program started on ") + TVPGetOSName() +
			TJS_W(" (") + TVPGetPlatformName() + TJS_W(")"));

		// TVPInitializeBaseSystems
		TVPInitializeBaseSystems();

		Application->Initialize();

		if(TVPCheckPrintDataPath()) return 0;
		if(TVPCheckCmdDescription()) return 0;
		if(TVPExecuteUserConfig()) return 0; // userconf

		TVPSystemInit();

		if(TVPCheckAbout()) return 0; // version information dialog box;

		Application->Title = "‹g—¢‹g—¢";
		Application->CreateForm(__classid(TTVPMainForm), &TVPMainForm);
		TVPLoadPluigins(); // load plugin module *.tpm
		if(TVPProjectDirSelected) TVPInitializeStartupScript();

		Application->Run();

		try
		{
			TVPSystemUninit();
		}
		catch(...)
		{
			// ignore errors
		}
	}
	catch (EAbort &e)
	{
		// nothing to do
	}
	catch (Exception &exception)
	{
		TVPOnError();
		if(!TVPSystemUninitCalled)
			Application->ShowException(&exception);
	}
	catch (eTJSScriptError &e)
	{
		TVPOnError();
		if(!TVPSystemUninitCalled)
			Application->ShowException(&Exception(e.GetMessage().AsAnsiString()));
	}
	catch (eTJS &e)
	{
		TVPOnError();
		if(!TVPSystemUninitCalled)
			Application->ShowException(&Exception(e.GetMessage().AsAnsiString()));
	}
	catch(...)
	{
		Application->ShowException(&Exception("Unknown error!"));
	}

	if(engine_init) TVPUninitScriptEngine();

#ifndef _DEBUG
	// delete application and exit forcely
	// this prevents ugly exception message on exit

	delete Application;
	ExitProcess(TVPTerminateCode);
#endif
	return TVPTerminateCode;
}
Ejemplo n.º 6
0
bool tTVPApplication::StartApplication( int argc, char* argv[] ) {
	_set_se_translator(se_translator_function);

	ArgC = argc;
	ArgV = argv;
	for( int i = 0; i < argc; i++ ) {
		if(!strcmp(argv[i], "-@processohmlog")) {
			has_map_report_process_ = true;
		}
	}
	TVPTerminateCode = 0;

	CheckConsole();

	// try starting the program!
	bool engine_init = false;
	try {
		if(TVPCheckProcessLog()) return true; // sub-process for processing object hash map log

		TVPInitScriptEngine();
		engine_init = true;

		// banner
		TVPAddImportantLog( TVPFormatMessage(TVPProgramStartedOn, TVPGetOSName(), TVPGetPlatformName()) );

		// TVPInitializeBaseSystems
		TVPInitializeBaseSystems();

		Initialize();

		if(TVPCheckPrintDataPath()) return true;
		if(TVPExecuteUserConfig()) return true;
		
		image_load_thread_ = new tTVPAsyncImageLoader();

		TVPSystemInit();

		if(TVPCheckAbout()) return true; // version information dialog box;

		SetTitle( std::wstring(TVPKirikiri) );
		TVPSystemControl = new tTVPSystemControl();
#ifndef TVP_IGNORE_LOAD_TPM_PLUGIN
		TVPLoadPluigins(); // load plugin module *.tpm
#endif
		// Check digitizer
		CheckDigitizer();

		// start image load thread
		image_load_thread_->Resume();

		if(TVPProjectDirSelected) TVPInitializeStartupScript();

		Run();

		try {
			// image_load_thread_->ExitRequest();
			delete image_load_thread_;
			image_load_thread_ = NULL;
		} catch(...) {
			// ignore errors
		}
		try {
			TVPSystemUninit();
		} catch(...) {
			// ignore errors
		}
	} catch( const EAbort & ) {
		// nothing to do
	} catch( const Exception &exception ) {
		TVPOnError();
		if(!TVPSystemUninitCalled)
			ShowException(exception.what());
	} catch( const TJS::eTJSScriptError &e ) {
		TVPOnError();
		if(!TVPSystemUninitCalled)
			ShowException( e.GetMessage().c_str() );
	} catch( const TJS::eTJS &e) {
		TVPOnError();
		if(!TVPSystemUninitCalled)
			ShowException( e.GetMessage().c_str() );
	} catch( const std::exception &e ) {
		ShowException( ttstr(e.what()).c_str() );
	} catch( const char* e ) {
		ShowException( ttstr(e).c_str() );
	} catch( const wchar_t* e ) {
		ShowException( e );
	} catch( const SEHException& e ) {
		PEXCEPTION_RECORD rec = e.ExceptionPointers->ExceptionRecord;
		std::wstring text(SECodeToMessage(e.Code));
		ttstr result = TJSGetStackTraceString( 10 );
		PrintConsole( result.c_str(), result.length(), true );

		TVPDumpHWException();
		ShowException( text.c_str() );
	} catch(...) {
		ShowException( (const tjs_char*)TVPUnknownError );
	}

	if(engine_init) TVPUninitScriptEngine();

	if(TVPSystemControl) delete TVPSystemControl;
	TVPSystemControl = NULL;

	CloseConsole();

	return false;
}
Ejemplo n.º 7
0
//---------------------------------------------------------------------------
// tTVPSusiePlugin
//---------------------------------------------------------------------------
tTVPSusiePlugin::tTVPSusiePlugin(HINSTANCE inst, const char *api)
{
	ModuleInstance = inst;

	// get functions
	*(FARPROC*)&GetPluginInfo = GetProcAddress(inst, "GetPluginInfo");
	*(FARPROC*)&IsSupported = GetProcAddress(inst, "IsSupported");

	*(FARPROC*)&GetPicture = GetProcAddress(inst, "GetPicture");


	*(FARPROC*)&GetArchiveInfo = GetProcAddress(inst, "GetArchiveInfo");
	*(FARPROC*)&GetFile = GetProcAddress(inst, "GetFile");

	if(!memcmp(api, "00IN", 4))
	{
		if(!GetPluginInfo || !IsSupported || !GetPicture)
			TVPThrowExceptionMessage(TVPNotSusiePlugin);
	}
	else if(!memcmp(api, "00AM", 4))
	{
		if(!GetPluginInfo || !IsSupported || !GetArchiveInfo || !GetFile)
			TVPThrowExceptionMessage(TVPNotSusiePlugin);
	}
	else
	{
		TVPThrowInternalError;
	}

	// check API version and dump copyright information
	char buffer[256];
	char buffer2[256];

	if(GetPluginInfo(0, buffer, 255) >= 4)
	{
		if(memcmp(buffer, api, 4))
			TVPThrowExceptionMessage(TVPNotSusiePlugin);
	}
	else
	{
		TVPThrowExceptionMessage(TVPNotSusiePlugin);
	}

	memset(buffer, 0, 256);
	GetPluginInfo(1, buffer, 255);
	if(buffer[0]) TVPAddImportantLog(TJS_W("(info) Susie plugin info : ") + ttstr(buffer));

	// retrieve format information
	tjs_int i;
	for(i = 0; ; i++)
	{
		int r = GetPluginInfo(2*i + 2, buffer, 255);
		if(r == 0) break;
		buffer[255] = 0;

		// here buffer contains exetension information such as "*.JPG" "*.RGB;*.Q0"
		strlwr(buffer);

		// split buffer to each extensions
		char *p = buffer;
		while((p = strstr(p, "*.")) != NULL)
		{
			p++;
			char *b2 = buffer2;
			while(*p && *p != ' ' && *p != ';')
			{
				*b2 = *p;
				b2++;
				p++;
			}
			*b2 = 0;
			Extensions.push_back(ttstr(buffer2));
		}
	}
};
Ejemplo n.º 8
0
void TVPBeforeSystemInit()
{
	RegisterDllLoadHook();
		// register DLL delayed import hook to support _inmm.dll

	TVPInitProgramArgumentsAndDataPath(false); // ensure command line

#ifdef TVP_REPORT_HW_EXCEPTION
	__dee_hacked_set_getExceptionObjectHook(TVP__dee_hacked_getExceptionObjectHook);
		// register hook function for hardware exceptions
#endif

	Application->HintHidePause = 24*60*60*1000;
		// not to hide tool tip hint immediately
	Application->ShowHint = false;
	Application->ShowHint = true;
		// to ensure assigning new HintWindow Class defined in HintWindow.cpp 


	// randomize
	TVPInitRandomGenerator();

	// memory usage
	{
		MEMORYSTATUS status;
		status.dwLength = sizeof(status);
		GlobalMemoryStatus(&status);

		TVPPushEnvironNoise(&status, sizeof(status));

		TVPTotalPhysMemory = status.dwTotalPhys;

		TVPAddImportantLog(TJS_W("(info) Total physical memory : ") +
			ttstr((int)TVPTotalPhysMemory) );

		tTJSVariant opt;
		if(TVPGetCommandLine(TJS_W("-memusage"), &opt))
		{
			ttstr str(opt);
			if(str == TJS_W("low"))
				TVPTotalPhysMemory = 0; // assumes zero
		}

		if(TVPTotalPhysMemory <= 36*1024*1024)
		{
			// very very low memory, forcing to assume zero memory
			TVPTotalPhysMemory = 0;
		}

		if(TVPTotalPhysMemory < 48*1024*1024)
		{
			// extra low memory
			if(TJSObjectHashBitsLimit > 0)
				TJSObjectHashBitsLimit = 0;
			TVPSegmentCacheLimit = 0;
			TVPFreeUnusedLayerCache = true; // in LayerIntf.cpp
		}
		else if(TVPTotalPhysMemory < 64*1024*1024)
		{
			// low memory
			if(TJSObjectHashBitsLimit > 4)
				TJSObjectHashBitsLimit = 4;
		}
	}


	char buf[MAX_PATH];
	bool bufset = false;
	bool nosel = false;
	bool forcesel = false;

	bool forcedataxp3 = GetSystemSecurityOption("forcedataxp3") != 0;
	bool acceptfilenameargument = GetSystemSecurityOption("acceptfilenameargument") != 0;

	if(!forcedataxp3 && !acceptfilenameargument)
	{
		if(TVPGetCommandLine(TJS_W("-nosel")) || TVPGetCommandLine(TJS_W("-about")))
		{
			nosel = true;
		}
		else
		{
			for(tjs_int i = 1; i<_argc; i++)
			{
				if(_argv[i][0] == '-' &&
					_argv[i][1] == '-' && _argv[i][2] == 0)
					break;

				if(_argv[i][0] != '-')
				{
					// TODO: set the current directory
					strncpy(buf, _argv[i], MAX_PATH-1);
					buf[MAX_PATH-1] = '\0';
					if(DirectoryExists(buf)) // is directory?
						strcat(buf, "\\");

					TVPProjectDirSelected = true;
					bufset = true;
					nosel = true;
				}
			}
		}
	}

	// check "-sel" option, to force show folder selection window
	if(!forcedataxp3 && TVPGetCommandLine(TJS_W("-sel")))
	{
		// sel option was set
		if(bufset)
		{
			char path[MAX_PATH];
			char *dum = 0;
			GetFullPathName(buf, MAX_PATH-1, path, &dum);
			strcpy(buf, path);
			TVPProjectDirSelected = false;
			bufset = true;
		}
		nosel = true;
		forcesel = true;
	}

	// check "content-data" directory
	if(!forcedataxp3 && !nosel)
	{
		char tmp[MAX_PATH];
		strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ParamStr(0))).c_str());
		strcat(tmp, "content-data");
		if(DirectoryExists(tmp))
		{
			strcat(tmp, "\\");
			strcpy(buf, tmp);
			TVPProjectDirSelected = true;
			bufset = true;
			nosel = true;
		}
	}

	// check "data.xp3" archive
 	if(!nosel)
	{
		char tmp[MAX_PATH];
		strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ParamStr(0))).c_str());
		strcat(tmp, "data.xp3");
		if(FileExists(tmp))
		{
			strcpy(buf, tmp);
			TVPProjectDirSelected = true;
			bufset = true;
			nosel = true;
		}
	}

	// check "data.exe" archive
 	if(!nosel)
	{
		char tmp[MAX_PATH];
		strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ParamStr(0))).c_str());
		strcat(tmp, "data.exe");
		if(FileExists(tmp))
		{
			strcpy(buf, tmp);
			TVPProjectDirSelected = true;
			bufset = true;
			nosel = true;
		}
	}

	// check self combined xpk archive
	if(!nosel)
	{
		if(TVPIsXP3Archive(TVPNormalizeStorageName(ParamStr(0))))
		{
			strcpy(buf, ParamStr(0).c_str());
			TVPProjectDirSelected = true;
			bufset = true;
			nosel = true;
		}
	}


	// check "data" directory
	if(!forcedataxp3 && !nosel)
	{
		char tmp[MAX_PATH];
		strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ParamStr(0))).c_str());
		strcat(tmp, "data");
		if(DirectoryExists(tmp))
		{
			strcat(tmp, "\\");
			strcpy(buf, tmp);
			TVPProjectDirSelected = true;
			bufset = true;
			nosel = true;
		}
	}

	// decide a directory to execute or to show folder selection
	if(!bufset)
	{
		if(forcedataxp3) throw EAbort("Aborted");
		strcpy(buf, ExtractFileDir(ParamStr(0)).c_str());
		int curdirlen = strlen(buf);
		if(buf[curdirlen-1] != '\\') buf[curdirlen] = '\\', buf[curdirlen+1] = 0;
	}

	if(!forcedataxp3 && (!nosel || forcesel))
	{
		// load krdevui.dll ( TVP[KiRikiri] Development User Interface )
		HMODULE krdevui = LoadLibrary("krdevui.dll");
		if(!krdevui)
		{
			AnsiString toolspath = (IncludeTrailingBackslash(
					ExtractFilePath(ParamStr(0))) + "tools\\krdevui.dll");
			krdevui = LoadLibrary(toolspath.c_str());
		}

		if(!krdevui)
		{
			// cannot locate the dll
			throw Exception(
				ttstr(TVPCannnotLocateUIDLLForFolderSelection).AsAnsiString());
		}

		typedef int PASCAL (*UIShowFolderSelectorForm_t)(void *reserved, char *buf);
		typedef void PASCAL (*UIGetVersion_t)(DWORD *hi, DWORD *low);

		UIShowFolderSelectorForm_t	UIShowFolderSelectorForm;
		UIGetVersion_t				UIGetVersion;

		UIShowFolderSelectorForm =
			(UIShowFolderSelectorForm_t)GetProcAddress(krdevui, "UIShowFolderSelectorForm");
		UIGetVersion =
			(UIGetVersion_t)GetProcAddress(krdevui, "UIGetVersion");

		if(!UIShowFolderSelectorForm || !UIGetVersion)
		{
			FreeLibrary(krdevui);
			throw Exception(ttstr(TVPInvalidUIDLL).AsAnsiString());
		}

		DWORD h, l;
		UIGetVersion(&h, &l);
		if(h != TVP_NEED_UI_VERSION)
		{
			FreeLibrary(krdevui);
			throw Exception(ttstr(TVPInvalidUIDLL).AsAnsiString());
		}


		int result = UIShowFolderSelectorForm(Application->Handle, buf);

//		FreeLibrary(krdevui);
		// FIXME: the library should be freed as soon as finishing to use it.

		if(result == mrAbort)
		{
			// display the main window
		}
		else
		if(result == mrCancel)
		{
			// cancel
			throw EAbort("Canceled");
		}
		else
		if(result == mrOk)
		{
			// ok, prepare to execute the script
			TVPProjectDirSelected = true;
		}
	}

	// check project dir and store some environmental variables
	if(TVPProjectDirSelected)
	{
		Application->ShowMainForm=false;
	}

	tjs_int buflen = strlen(buf);
	if(buflen >= 1)
	{
		if(buf[buflen-1] != '\\') buf[buflen] = TVPArchiveDelimiter, buf[buflen+1] = 0;
	}

	TVPProjectDir = TVPNormalizeStorageName(buf);
	TVPSetCurrentDirectory(TVPProjectDir);
	TVPNativeProjectDir = buf;

	if(TVPProjectDirSelected)
	{
		TVPAddImportantLog(TJS_W("(info) Selected project directory : ") +
			TVPProjectDir);
	}
}
Ejemplo n.º 9
0
//---------------------------------------------------------------------------
static void TVPInitProgramArgumentsAndDataPath(bool stop_after_datapath_got)
{
	if(!TVPProgramArgumentsInit)
	{
		TVPProgramArgumentsInit = true;


		// find options from self executable image
		const int num_option_layers = 3;
		TStringList * options[num_option_layers];
		for(int i = 0; i < num_option_layers; i++) options[i] = NULL;
		try
		{
			// read embedded options and default configuration file
			options[0] = TVPGetEmbeddedOptions();
			options[1] = TVPGetConfigFileOptions(TConfMainFrame::GetConfigFileName(ParamStr(0)));

			// at this point, we need to push all exsting known options
			// to be able to see datapath
			PushAllCommandlineArguments();
			PushConfigFileOptions(options[1]); // has more priority
			PushConfigFileOptions(options[0]); // has lesser priority

			// read datapath
			tTJSVariant val;
			AnsiString config_datapath;
			if(TVPGetCommandLine(TJS_W("-datapath"), &val))
				config_datapath = ((ttstr)val).AsAnsiString();
			TVPNativeDataPath = TConfMainFrame::GetDataPathDirectory(config_datapath, ParamStr(0));

			if(stop_after_datapath_got) return;

			// read per-user configuration file
			options[2] = TVPGetConfigFileOptions(TConfMainFrame::GetUserConfigFileName(config_datapath, ParamStr(0)));

			// push each options into option stock
			// we need to clear TVPProgramArguments first because of the
			// option priority order.
			TVPProgramArguments.clear();
			PushAllCommandlineArguments();
			PushConfigFileOptions(options[2]); // has more priority
			PushConfigFileOptions(options[1]); // has more priority
			PushConfigFileOptions(options[0]); // has lesser priority
		}
		__finally
		{
			for(int i = 0; i < num_option_layers; i++)
				if(options[i]) delete options[i];
		}


		// set data path
		TVPDataPath = TVPNormalizeStorageName(TVPNativeDataPath);
		TVPAddImportantLog(ttstr("(info) Data path : ") + TVPDataPath);

		// set log output directory
		TVPSetLogLocation(TVPNativeDataPath);

		// increment TVPCommandLineArgumentGeneration
		TVPCommandLineArgumentGeneration++;
	}
Ejemplo n.º 10
0
//---------------------------------------------------------------------------
static TStringList * TVPGetEmbeddedOptions()
{
	AnsiString filename = ParamStr(0);
	TStream *stream = new TFileStream(filename, fmOpenRead|fmShareDenyWrite);

	char *buf = NULL;
	TStringList *ret = NULL;

	const char * errmsg = NULL;

	tjs_uint offset;
	try
	{
		ret = new TStringList();
		unsigned int size = stream->Size;
		if(size < TVP_FIND_OPTION_MIN_OFS)
			errmsg = "too small executable size."; // too small

		if(!errmsg)
		{
			if(size > TVP_FIND_OPTION_MAX_OFS) size = TVP_FIND_OPTION_MAX_OFS;
			buf = new char [size - TVP_FIND_OPTION_MIN_OFS];
			stream->Position = TVP_FIND_OPTION_MIN_OFS;
			stream->Read(buf, size - TVP_FIND_OPTION_MIN_OFS);

			// search "XOPT_EMBED_AREA_" ( aligned by 16 )
			static char XPT_1[] = "XOPT_EMBED\0\0";
			static char XPT_2[] = "_AREA_";
			char mark[17];
			strcpy(mark, XPT_1);
			strcat(mark, XPT_2); // combine string to avoid search the mark in code itself
			bool found = false;
			for(offset = TVP_FIND_OPTION_MIN_OFS; offset < size; offset += 16)
			{
				if(buf[offset - TVP_FIND_OPTION_MIN_OFS] == 'X')
				{
					if(!memcmp(buf+offset - TVP_FIND_OPTION_MIN_OFS,
						mark, 16))
					{
						ret->Text = buf + offset + 16 + 4 - TVP_FIND_OPTION_MIN_OFS;
						found = true;
						break;
					}
				}
			}

			if(!found) errmsg = "not found in executable.";
		}
	}
	catch(...)
	{
		if(buf) delete [] buf;
		if(ret) delete ret;
		delete stream;
		throw;
	}
	delete [] buf;
	delete stream;

	if(errmsg)
		TVPAddImportantLog(ttstr("(info) Loading executable embedded options failed (ignoring) : ") +
			errmsg);
	else
		TVPAddImportantLog("(info) Loading executable embedded options succeeded.");
	return ret;
}