More init hardening.

develop
Petr Mrázek 2011-11-04 09:08:29 +01:00
parent 0ff7a48848
commit af46b262b5
13 changed files with 148 additions and 35 deletions

@ -25,7 +25,7 @@ set(DF_VERSION_MINOR "31")
set(DF_VERSION_PATCH "25")
set(DF_VERSION "${DF_VERSION_MAJOR}.${DF_VERSION_MINOR}.${DF_VERSION_PATCH}")
set(DFHACK_RELEASE "7d")
set(DFHACK_RELEASE "7e")
## where to install things (after the build is done, classic 'make install' or package structure)
# the dfhack libraries will be installed here:

@ -640,7 +640,6 @@ bool Console::init(bool sharing)
return false;
}
freopen("stdout.log", "w", stdout);
freopen("stderr.log", "w", stderr);
d = new Private();
// make our own weird streams so our IO isn't redirected
d->dfout_C = fopen("/dev/tty", "w");
@ -690,11 +689,18 @@ int Console::printerr( const char* format, ... )
va_list args;
lock_guard <mutex> g(*wlock);
int ret;
if(!inited) ret = -1;
// also mirror in error log
if(!inited)
{
va_start( args, format );
ret = vfprintf(stderr, format, args);
va_end(args);
}
else
{
va_start( args, format );
ret = d->vprinterr(format, args);
vfprintf(stderr, format, args);
va_end(args);
}
return ret;

@ -378,6 +378,7 @@ namespace DFHack
HANDLE console_in;
HANDLE console_out;
HWND ConsoleWindow;
HWND MainWindow;
WORD default_attributes;
// current state
enum console_state
@ -402,7 +403,29 @@ Console::Console():std::ostream(0), std::ios(0)
Console::~Console()
{
}
/*
// DOESN'T WORK - locks up DF!
void ForceForegroundWindow(HWND window)
{
DWORD nForeThread, nAppThread;
nForeThread = GetWindowThreadProcessId(GetForegroundWindow(), 0);
nAppThread = ::GetWindowThreadProcessId(window,0);
if(nForeThread != nAppThread)
{
AttachThreadInput(nForeThread, nAppThread, true);
BringWindowToTop(window);
ShowWindow(window,3);
AttachThreadInput(nForeThread, nAppThread, false);
}
else
{
BringWindowToTop(window);
ShowWindow(window,3);
}
}
*/
bool Console::init(bool)
{
d = new Private();
@ -411,6 +434,21 @@ bool Console::init(bool)
CONSOLE_SCREEN_BUFFER_INFO coninfo;
FILE *fp;
DWORD oldMode, newMode;
DWORD dwTheardId;
HWND h = ::GetTopWindow(0 );
while ( h )
{
DWORD pid;
dwTheardId = ::GetWindowThreadProcessId( h,&pid);
if ( pid == GetCurrentProcessId() )
{
// here h is the handle to the window
break;
}
h = ::GetNextWindow( h , GW_HWNDNEXT);
}
d->MainWindow = h;
// Allocate a console!
AllocConsole();
@ -450,6 +488,8 @@ bool Console::init(bool)
std::cin.tie(this);
clear();
inited = true;
// DOESN'T WORK - locks up DF!
// ForceForegroundWindow(d->MainWindow);
return true;
}
// FIXME: looks awfully empty, doesn't it?
@ -480,11 +520,18 @@ int Console::printerr( const char* format, ... )
va_list args;
lock_guard <mutex> g(*wlock);
int ret;
if(!inited) ret = -1;
// also mirror in error log
if(!inited)
{
va_start( args, format );
ret = vfprintf(stderr, format, args);
va_end(args);
}
else
{
va_start( args, format );
ret = d->vprinterr(format, args);
vfprintf(stderr, format, args);
va_end(args);
}
return ret;

@ -174,6 +174,8 @@ void fIOthread(void * iodata)
}
string first = parts[0];
parts.erase(parts.begin());
cerr << "Invoking: " << command << endl;
// let's see what we actually got
if(first=="help" || first == "?")
{
@ -351,7 +353,7 @@ void fIOthread(void * iodata)
command_result res = plug_mgr->InvokeCommand(first, parts);
if(res == CR_NOT_IMPLEMENTED)
{
con.printerr("Invalid command.\n");
con.printerr("%s is not a recognized command.\n", first.c_str());
clueless_counter ++;
}
/*
@ -393,6 +395,23 @@ Core::Core()
misc_data_mutex=0;
};
void Core::fatal (std::string output, bool deactivate)
{
stringstream out;
out << output ;
if(deactivate)
out << "DFHack will now deactivate.\n";
if(con.isInited())
{
con.printerr("%s", out.str().c_str());
}
fprintf(stderr, "%s\n", out.str().c_str());
#ifndef LINUX_BUILD
out << "Check file stderr.log for details\n";
MessageBox(0,out.str().c_str(),"DFHack error!", MB_OK | MB_ICONERROR);
#endif
}
bool Core::Init()
{
if(started)
@ -406,30 +425,48 @@ bool Core::Init()
#else
const char * path = "hack\\Memory.xml";
#endif
vif = new DFHack::VersionInfoFactory(path);
vif = new DFHack::VersionInfoFactory();
cerr << "Identifying DF version.\n";
try
{
vif->loadFile(path);
}
catch(Error::All & err)
{
std::stringstream out;
out << "Error while reading Memory.xml:\n";
out << err.what() << std::endl;
delete vif;
vif = nullptr;
errorstate = true;
fatal(out.str(), true);
return false;
}
p = new DFHack::Process(vif);
vinfo = p->getDescriptor();
if(!vinfo || !p->isIdentified())
{
cerr << "Not a known DF version. DFHack will now deactivate.\n";
fatal ("Not a known DF version.\n", true);
errorstate = true;
delete p;
p = NULL;
return false;
}
cerr << "Version: " << vinfo->getVersion() << endl;
cerr << "Initializing Console.\n";
// init the console.
Gui * g = getGui();
if(g->init)
bool is_text_mode = false;
if(g->init && g->init->graphics.flags.is_set(GRAPHICS_TEXT))
{
if(g->init->graphics.flags.is_set(GRAPHICS_TEXT))
{
con.init(true);
}
else con.init(false);
is_text_mode = true;
}
else con.init(false);
if(con.init(is_text_mode))
cerr << "Console is running.\n";
else
fatal ("Console has failed to initialize!\n", false);
// dump offsets to a file
std::ofstream dump("offsets.log");
@ -444,18 +481,22 @@ bool Core::Init()
AccessMutex = new mutex();
misc_data_mutex=new mutex();
core_cond = new Core::Cond();
cerr << "Initializing Plugins.\n";
// create plugin manager
plug_mgr = new PluginManager(this);
cerr << "Starting IO thread.\n";
// create IO thread
IODATA *temp = new IODATA;
temp->core = this;
temp->plug_mgr = plug_mgr;
thread * IO = new thread(fIOthread, (void *) temp);
cerr << "Starting DF input capture thread.\n";
// set up hotkey capture
HotkeyMutex = new mutex();
HotkeyCond = new condition_variable();
thread * HK = new thread(fHKthread, (void *) temp);
started = true;
cerr << "DFHack is running.\n";
return true;
}
/// sets the current hotkey command
@ -565,6 +606,8 @@ int Core::Update()
// FIXME: needs to terminate the IO threads and properly dismantle all the machinery involved.
int Core::Shutdown ( void )
{
if(errorstate)
return true;
errorstate = 1;
if(plug_mgr)
{

@ -132,6 +132,11 @@ DFhackCExport int wgetch(WINDOW *win)
static int (*_SDL_Init)(uint32_t flags) = 0;
DFhackCExport int SDL_Init(uint32_t flags)
{
// reroute stderr
freopen("stderr.log", "w", stderr);
// we don't reroute stdout until we figure out if this should be done at all
// See: Console-linux.cpp
// find real functions
_SDL_Init = (int (*)( uint32_t )) dlsym(RTLD_NEXT, "SDL_Init");
_SDL_Quit = (void (*)( void )) dlsym(RTLD_NEXT, "SDL_Quit");

@ -694,6 +694,9 @@ DFhackCExport uint32_t SDL_ThreadID(void)
// FIXME: this has to be thread-safe.
bool FirstCall()
{
// reroute stdout and stderr
freopen("stdout.log", "w", stdout);
freopen("stderr.log", "w", stderr);
HMODULE realSDLlib = LoadLibrary("SDLreal.dll");
if(!realSDLlib)
{

@ -97,13 +97,16 @@ inline bool operator>=(const triple<_T1, _T2, _T3>& __x, const triple<_T1, _T2,
return !(__x < __y);
}
VersionInfoFactory::VersionInfoFactory(string path_to_xml)
VersionInfoFactory::VersionInfoFactory()
{
error = false;
loadFile(path_to_xml);
}
VersionInfoFactory::~VersionInfoFactory()
{
clear();
}
void VersionInfoFactory::clear(void)
{
// for each stored version, delete
for(uint32_t i = 0; i < versions.size();i++)
@ -111,6 +114,8 @@ VersionInfoFactory::~VersionInfoFactory()
delete versions[i];
}
versions.clear();
knownVersions.clear();
error = false;
}
VersionInfo * VersionInfoFactory::getVersionInfoByMD5(string hash)
@ -768,5 +773,6 @@ bool VersionInfoFactory::loadFile(string path_to_xml)
}
}
error = false;
std::cerr << "Loaded " << versions.size() << " DF versions." << std::endl;
return true;
}

@ -164,6 +164,7 @@ namespace DFHack
//void beep (void);
/// A simple line edit (raw mode)
int lineedit(const std::string& prompt, std::string& output, CommandHistory & history );
bool isInited (void) { return inited; };
private:
Private * d;
tthread::mutex * wlock;

@ -126,10 +126,10 @@ namespace DFHack
/// removes the hotkey command and gives it to the caller thread
std::string getHotkeyCmd( void );
/// adds a named pointer (for later or between plugins)
void RegisterData(void *p,std::string key);
/// returns a named pointer.
void *GetData(std::string key);
/// adds a named pointer (for later or between plugins)
void RegisterData(void *p,std::string key);
/// returns a named pointer.
void *GetData(std::string key);
DFHack::Process * p;
DFHack::VersionInfo * vinfo;
@ -143,6 +143,9 @@ namespace DFHack
bool ncurses_wgetch(int in, int & out);
Core(Core const&); // Don't Implement
void operator=(Core const&); // Don't implement
// report error to user while failing
void fatal (std::string output, bool will_deactivate);
// 1 = fatal failure
bool errorstate;
// regulate access to DF
struct Cond;

@ -39,7 +39,7 @@ namespace DFHack
{
friend class ProcessEnumerator;
public:
VersionInfoFactory(std::string path_to_xml);
VersionInfoFactory();
~VersionInfoFactory();
// memory info entries loaded from a file
bool loadFile( std::string path_to_xml);
@ -47,6 +47,7 @@ namespace DFHack
VersionInfo * getVersionInfoByMD5(std::string md5string);
VersionInfo * getVersionInfoByPETimestamp(uint32_t timestamp);
std::vector<VersionInfo*> versions;
void clear( void );
private:
void ParseVTable(TiXmlElement* vtable, VersionInfo* mem);
void ParseBase (TiXmlElement* base, VersionInfo* mem);

@ -1 +1 @@
Subproject commit 0f6389f4121d6cf3d447fb72a5b561d8d66b0de8
Subproject commit ea35678fc408dadef196ed82f61c00709a23b914

@ -56,13 +56,13 @@ DFhackCExport command_result rawdump_i (Core * c, vector <string> & parameters)
{
if( index < mats->df_inorganic->size())
{
df_inorganic_material * mat = mats->df_inorganic->at(index);
df_inorganic_type * mat = mats->df_inorganic->at(index);
// dump single material
con.print("%-3d : [%s] %s\n",
index,
mat->Inorganic_ID.c_str(),
mat->STATE_NAME_SOLID.c_str());
con.print("MAX EDGE: %d\n",mat->MAX_EDGE);
mat->ID.c_str(),
mat->mat.state_name[DFHack::state_solid].c_str());
con.print("MAX EDGE: %d\n",mat->mat.MAX_EDGE);
}
else
{
@ -74,7 +74,7 @@ DFhackCExport command_result rawdump_i (Core * c, vector <string> & parameters)
// dump all materials
for(int i = 0; i < mats->df_inorganic->size();i++)
{
con.print("%-3d : %s\n",i,mats->df_inorganic->at(i)->Inorganic_ID.c_str());
con.print("%-3d : %s\n",i,mats->df_inorganic->at(i)->ID.c_str());
}
}
c->Resume();

@ -198,7 +198,7 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
DFHack::Maps *maps = c->getMaps();
if (!maps->Start())
{
con << "Cannot get map info!" << std::endl;
con.printerr("Cannot get map info!\n");
c->Resume();
return CR_FAILURE;
}
@ -208,13 +208,13 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
DFHack::Materials *mats = c->getMaterials();
if (!mats->df_inorganic)
{
con << "Unable to read inorganic material definitons!" << std::endl;
con.printerr("Unable to read inorganic material definitons!\n");
c->Resume();
return CR_FAILURE;
}
if (showPlants && !mats->df_organic)
{
con << "Unable to read organic material definitons; plants won't be listed!" << std::endl;
con.printerr("Unable to read organic material definitons; plants won't be listed!\n");
showPlants = false;
}
@ -234,21 +234,19 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
if (!(showSlade && maps->ReadGlobalFeatures(globalFeatures)))
{
con << "Unable to read global features; slade won't be listed!" << std::endl;
con.printerr("Unable to read global features; slade won't be listed!\n");
}
if (!maps->ReadLocalFeatures(localFeatures))
{
con << "Unable to read local features; adamantine "
<< (showTemple ? "and demon temples " : "")
<< "won't be listed!" << std::endl;
con.printerr("Unable to read local features; adamantine and demon temples won't be listed.\n" );
}
uint32_t vegCount = 0;
DFHack::Vegetation *veg = c->getVegetation();
if (showPlants && !veg->Start())
{
con << "Unable to read vegetation; plants won't be listed!" << std::endl;
con.printerr("Unable to read vegetation; plants won't be listed!\n" );
}
for(uint32_t z = 0; z < z_max; z++)