Merge git://github.com/peterix/dfhack

develop
rampaging-poet 2011-11-04 18:06:08 -07:00
commit 9a45e8d328
18 changed files with 394 additions and 437 deletions

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

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

@ -378,6 +378,7 @@ namespace DFHack
HANDLE console_in; HANDLE console_in;
HANDLE console_out; HANDLE console_out;
HWND ConsoleWindow; HWND ConsoleWindow;
HWND MainWindow;
WORD default_attributes; WORD default_attributes;
// current state // current state
enum console_state enum console_state
@ -402,7 +403,29 @@ Console::Console():std::ostream(0), std::ios(0)
Console::~Console() 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) bool Console::init(bool)
{ {
d = new Private(); d = new Private();
@ -411,6 +434,21 @@ bool Console::init(bool)
CONSOLE_SCREEN_BUFFER_INFO coninfo; CONSOLE_SCREEN_BUFFER_INFO coninfo;
FILE *fp; FILE *fp;
DWORD oldMode, newMode; 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! // Allocate a console!
AllocConsole(); AllocConsole();
@ -450,6 +488,8 @@ bool Console::init(bool)
std::cin.tie(this); std::cin.tie(this);
clear(); clear();
inited = true; inited = true;
// DOESN'T WORK - locks up DF!
// ForceForegroundWindow(d->MainWindow);
return true; return true;
} }
// FIXME: looks awfully empty, doesn't it? // FIXME: looks awfully empty, doesn't it?
@ -480,11 +520,18 @@ int Console::printerr( const char* format, ... )
va_list args; va_list args;
lock_guard <mutex> g(*wlock); lock_guard <mutex> g(*wlock);
int ret; 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 else
{ {
va_start( args, format ); va_start( args, format );
ret = d->vprinterr(format, args); ret = d->vprinterr(format, args);
vfprintf(stderr, format, args);
va_end(args); va_end(args);
} }
return ret; return ret;

@ -174,6 +174,8 @@ void fIOthread(void * iodata)
} }
string first = parts[0]; string first = parts[0];
parts.erase(parts.begin()); parts.erase(parts.begin());
cerr << "Invoking: " << command << endl;
// let's see what we actually got // let's see what we actually got
if(first=="help" || first == "?") if(first=="help" || first == "?")
{ {
@ -351,7 +353,7 @@ void fIOthread(void * iodata)
command_result res = plug_mgr->InvokeCommand(first, parts); command_result res = plug_mgr->InvokeCommand(first, parts);
if(res == CR_NOT_IMPLEMENTED) if(res == CR_NOT_IMPLEMENTED)
{ {
con.printerr("Invalid command.\n"); con.printerr("%s is not a recognized command.\n", first.c_str());
clueless_counter ++; clueless_counter ++;
} }
/* /*
@ -393,6 +395,23 @@ Core::Core()
misc_data_mutex=0; 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() bool Core::Init()
{ {
if(started) if(started)
@ -406,30 +425,48 @@ bool Core::Init()
#else #else
const char * path = "hack\\Memory.xml"; const char * path = "hack\\Memory.xml";
#endif #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); p = new DFHack::Process(vif);
vinfo = p->getDescriptor(); vinfo = p->getDescriptor();
if(!vinfo || !p->isIdentified()) 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; errorstate = true;
delete p; delete p;
p = NULL; p = NULL;
return false; return false;
} }
cerr << "Version: " << vinfo->getVersion() << endl;
cerr << "Initializing Console.\n";
// init the console. // init the console.
Gui * g = getGui(); 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)) is_text_mode = true;
{
con.init(true);
}
else con.init(false);
} }
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 // dump offsets to a file
std::ofstream dump("offsets.log"); std::ofstream dump("offsets.log");
@ -444,18 +481,22 @@ bool Core::Init()
AccessMutex = new mutex(); AccessMutex = new mutex();
misc_data_mutex=new mutex(); misc_data_mutex=new mutex();
core_cond = new Core::Cond(); core_cond = new Core::Cond();
cerr << "Initializing Plugins.\n";
// create plugin manager // create plugin manager
plug_mgr = new PluginManager(this); plug_mgr = new PluginManager(this);
cerr << "Starting IO thread.\n";
// create IO thread // create IO thread
IODATA *temp = new IODATA; IODATA *temp = new IODATA;
temp->core = this; temp->core = this;
temp->plug_mgr = plug_mgr; temp->plug_mgr = plug_mgr;
thread * IO = new thread(fIOthread, (void *) temp); thread * IO = new thread(fIOthread, (void *) temp);
cerr << "Starting DF input capture thread.\n";
// set up hotkey capture // set up hotkey capture
HotkeyMutex = new mutex(); HotkeyMutex = new mutex();
HotkeyCond = new condition_variable(); HotkeyCond = new condition_variable();
thread * HK = new thread(fHKthread, (void *) temp); thread * HK = new thread(fHKthread, (void *) temp);
started = true; started = true;
cerr << "DFHack is running.\n";
return true; return true;
} }
/// sets the current hotkey command /// 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. // FIXME: needs to terminate the IO threads and properly dismantle all the machinery involved.
int Core::Shutdown ( void ) int Core::Shutdown ( void )
{ {
if(errorstate)
return true;
errorstate = 1; errorstate = 1;
if(plug_mgr) if(plug_mgr)
{ {

@ -132,6 +132,11 @@ DFhackCExport int wgetch(WINDOW *win)
static int (*_SDL_Init)(uint32_t flags) = 0; static int (*_SDL_Init)(uint32_t flags) = 0;
DFhackCExport int SDL_Init(uint32_t flags) 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 // find real functions
_SDL_Init = (int (*)( uint32_t )) dlsym(RTLD_NEXT, "SDL_Init"); _SDL_Init = (int (*)( uint32_t )) dlsym(RTLD_NEXT, "SDL_Init");
_SDL_Quit = (void (*)( void )) dlsym(RTLD_NEXT, "SDL_Quit"); _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. // FIXME: this has to be thread-safe.
bool FirstCall() bool FirstCall()
{ {
// reroute stdout and stderr
freopen("stdout.log", "w", stdout);
freopen("stderr.log", "w", stderr);
HMODULE realSDLlib = LoadLibrary("SDLreal.dll"); HMODULE realSDLlib = LoadLibrary("SDLreal.dll");
if(!realSDLlib) if(!realSDLlib)
{ {

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

@ -1,332 +1,239 @@
/* /*
* This is the C++ implementation of the MD5 Message-Digest * This code implements the MD5 message-digest algorithm.
* Algorithm desrcipted in RFC 1321. * The algorithm is due to Ron Rivest. This code was
* I translated the C code from this RFC to C++. * written by Colin Plumb in 1993, no copyright is claimed.
* There is now warranty. * This code is in the public domain; do with it what you wish.
*
* Feb. 12. 2005
* Benjamin Grüdelbach
*/ */
/* #include <memory.h> /* for memcpy() */
* Changed unsigned long int types into uint32_t to make this work on 64bit systems.
* Sep. 5. 2009
* Petr Mrázek
*/
/*
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
* rights reserved.
*
* License to copy and use this software is granted provided that it
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
* Algorithm" in all material mentioning or referencing this software
* or this function.
*
* License is also granted to make and use derivative works provided
* that such works are identified as "derived from the RSA Data
* Security, Inc. MD5 Message-Digest Algorithm" in all material
* mentioning or referencing the derived work.
*
* RSA Data Security, Inc. makes no representations concerning either
* the merchantability of this software or the suitability of this
* software for any particular purpose. It is provided "as is"
* without express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this
* documentation and/or software.
*/
//md5 class include
#include "md5.h" #include "md5.h"
// Constants for MD5Transform routine. #ifndef HIGHFIRST
#define S11 7 #define byteReverse(buf, len) /* Nothing */
#define S12 12 #else
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions. */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits. */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* /*
FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. * Note: this code is harmless on little-endian machines.
Rotation is separate from addition to prevent recomputation. */
*/ void byteReverse(unsigned char *buf, unsigned longs)
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context. */
void MD5::MD5Init (MD5_CTX *context)
{ {
context->count[0] = context->count[1] = 0; uint32 t;
context->state[0] = 0x67452301; do {
context->state[1] = 0xefcdab89; t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
context->state[2] = 0x98badcfe; ((unsigned) buf[1] << 8 | buf[0]);
context->state[3] = 0x10325476; *(uint32 *) buf = t;
buf += 4;
} while (--longs);
} }
#endif
/* /*
MD5 block update operation. Continues an MD5 message-digest * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
operation, processing another message block, and updating the * initialization constants.
context.
*/
void MD5::MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ( (context->count[0] += ((unsigned long int)inputLen << 3))
< ((unsigned long int)inputLen << 3))
context->count[1]++;
context->count[1] += ((unsigned long int)inputLen >> 29);
partLen = 64 - index;
/*
* Transform as many times as possible.
*/ */
if (inputLen >= partLen) void MD5Init(MD5Context *ctx)
{ {
MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen); ctx->buf[0] = 0x67452301;
MD5Transform (context->state, context->buffer); ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
for (i = partLen; i + 63 < inputLen; i += 64) ctx->buf[3] = 0x10325476;
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */ ctx->bits[0] = 0;
MD5_memcpy ((POINTER)&context->buffer[index], ctx->bits[1] = 0;
(POINTER)&input[i],
inputLen-i);
} }
/* /*
* MD5 finalization. Ends an MD5 message-digest operation, writing the * Update context to reflect the concatenation of another buffer full
* the message digest and zeroizing the context. * of bytes.
*/ */
void MD5::MD5Final (unsigned char digest[16], MD5_CTX *context) void MD5Update( MD5Context *ctx, unsigned char *buf, unsigned len)
{ {
unsigned char bits[8]; uint32_t t;
unsigned int index, padLen;
/* Save number of bits */ /* Update bitcount */
Encode (bits, context->count, 8);
/* t = ctx->bits[0];
* Pad out to 56 mod 64. if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
*/ ctx->bits[1]++; /* Carry from low to high */
index = (unsigned int)((context->count[0] >> 3) & 0x3f); ctx->bits[1] += len >> 29;
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
MD5Update (context, bits, 8);
/* Store state in digest */ /* Handle any leading odd-sized chunks */
Encode (digest, context->state, 16); if (t)
{
unsigned char *p = (unsigned char *) ctx->in + t;
/* t = 64 - t;
* Zeroize sensitive information. if (len < t)
*/ {
MD5_memset ((POINTER)context, 0, sizeof (*context)); memcpy(p, buf, len);
return;
}
memcpy(p, buf, t);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
buf += t;
len -= t;
}
/* Process data in 64-byte chunks */
while (len >= 64)
{
memcpy(ctx->in, buf, 64);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
buf += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
memcpy(ctx->in, buf, len);
} }
/* /*
* MD5 basic transformation. Transforms state based on block. * Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/ */
void MD5::MD5Transform (uint32_t state[4], unsigned char block[64]) void MD5Final(unsigned char digest[16], MD5Context *ctx)
{ {
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; unsigned count;
unsigned char *p;
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */ /* Compute number of bytes mod 64 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ count = (ctx->bits[0] >> 3) & 0x3F;
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */ /* Set the first char of padding to 0x80. This is safe since there is
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ always at least one byte free */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ p = ctx->in + count;
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ *p++ = 0x80;
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */ /* Bytes of padding needed to make 64 bytes */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ count = 64 - 1 - count;
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a; /* Pad out to 56 mod 64 */
state[1] += b; if (count < 8)
state[2] += c; {
state[3] += d; /* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
/* /* Now fill the next block with 56 bytes */
* Zeroize sensitive information. memset(ctx->in, 0, 56);
*/ }
MD5_memset ((POINTER)x, 0, sizeof (x)); else
} {
/* Pad block to 56 bytes */
memset(p, 0, count - 8);
}
byteReverse(ctx->in, 14);
/* /* Append length in bits and transform */
* Encodes input (unsigned long int) into output (unsigned char). Assumes len is ((uint32_t *) ctx->in)[14] = ctx->bits[0];
* a multiple of 4. ((uint32_t *) ctx->in)[15] = ctx->bits[1];
*/
void MD5::Encode (unsigned char *output, uint32_t *input, unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) { MD5Transform(ctx->buf, (uint32_t *) ctx->in);
output[j] = (unsigned char)(input[i] & 0xff); byteReverse((unsigned char *) ctx->buf, 4);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); memcpy(digest, ctx->buf, 16);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
} }
/*
* Decodes input (unsigned char) into output (unsigned long int). Assumes len is
* a multiple of 4.
*/
void MD5::Decode (uint32_t *output, unsigned char *input, unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) /* The four core functions - F1 is optimized somewhat */
output[i] = ((uint32_t)input[j]) |
(((uint32_t)input[j+1]) << 8) |
(((uint32_t)input[j+2]) << 16) |
(((uint32_t)input[j+3]) << 24);
}
/* /* #define F1(x, y, z) (x & y | ~x & z) */
* Note: Replace "for loop" with standard memcpy if possible. #define F1(x, y, z) (z ^ (x & (y ^ z)))
*/ #define F2(x, y, z) F1(z, x, y)
void MD5::MD5_memcpy (POINTER output, POINTER input, unsigned int len) #define F3(x, y, z) (x ^ y ^ z)
{ #define F4(x, y, z) (y ^ (x | ~z))
unsigned int i;
for (i = 0; i < len; i++) /* This is the central step in the MD5 algorithm. */
output[i] = input[i]; #define MD5STEP(f, w, x, y, z, data, s) \
} ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
/* /*
* Note: Replace "for loop" with standard memset if possible. * The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/ */
void MD5::MD5_memset (POINTER output,int value,unsigned int len) void MD5Transform(uint32_t buf[4], uint32_t in[16])
{ {
unsigned int i; register uint32_t a, b, c, d;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value; a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
} }
/*
* EOF
*/

@ -1,92 +1,36 @@
/* #pragma once
* This is the C++ implementation of the MD5 Message-Digest
* Algorithm desrcipted in RFC 1321. /* The following tests optimise behaviour on little-endian
* I translated the C code from this RFC to C++. machines, where there is no need to reverse the byte order
* There is now warranty. of 32 bit words in the MD5 computation. By default,
* HIGHFIRST is defined, which indicates we're running on a
* Feb. 12. 2005 big-endian (most significant byte first) machine, on which
* Benjamin Grüdelbach the byteReverse function in md5.c must be invoked. However,
*/ byteReverse is coded in such a way that it is an identity
function when run on a little-endian machine, so calling it
/* on such a platform causes no harm apart from wasting time.
* Changed unsigned long int types into uint32_t to make this work on 64bit systems. If the platform is known to be little-endian, we speed
* Sep. 5. 2009 things up by undefining HIGHFIRST, which defines
* Petr Mrázek byteReverse as a null macro. Doing things in this manner
*/ insures we work on new platforms regardless of their byte
order. */
/*
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All #define HIGHFIRST
* rights reserved.
* #ifdef __i386__
* License to copy and use this software is granted provided that it #undef HIGHFIRST
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest #endif
* Algorithm" in all material mentioning or referencing this software
* or this function.
*
* License is also granted to make and use derivative works provided
* that such works are identified as "derived from the RSA Data
* Security, Inc. MD5 Message-Digest Algorithm" in all material
* mentioning or referencing the derived work.
*
* RSA Data Security, Inc. makes no representations concerning either
* the merchantability of this software or the suitability of this
* software for any particular purpose. It is provided "as is"
* without express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this
* documentation and/or software.
*/
//----------------------------------------------------------------------
//include protection
#ifndef MD5_H
#define MD5_H
//----------------------------------------------------------------------
//STL includes
#include <string>
#include <stdint.h> #include <stdint.h>
//----------------------------------------------------------------------
//typedefs
typedef unsigned char *POINTER;
/* struct MD5Context
* MD5 context.
*/
typedef struct
{ {
uint32_t state[4]; /* state (ABCD) */ uint32_t buf[4];
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ uint32_t bits[2];
unsigned char buffer[64]; /* input buffer */ unsigned char in[64];
} MD5_CTX;
/*
* MD5 class
*/
class MD5
{
private:
void MD5Transform (uint32_t state[4], unsigned char block[64]);
void Encode (unsigned char*, uint32_t*, unsigned int);
void Decode (uint32_t*, unsigned char*, unsigned int);
void MD5_memcpy (POINTER, POINTER, unsigned int);
void MD5_memset (POINTER, int, unsigned int);
public:
void MD5Init (MD5_CTX*);
void MD5Update (MD5_CTX*, unsigned char*, unsigned int);
void MD5Final (unsigned char [16], MD5_CTX*);
MD5(){};
}; };
//---------------------------------------------------------------------- extern void MD5Init( MD5Context *ctx);
//End of include protection extern void MD5Update( MD5Context *ctx, unsigned char *buf, unsigned len);
#endif extern void MD5Final(unsigned char digest[16], MD5Context *ctx);
extern void MD5Transform(uint32_t buf[4], uint32_t in[16]);
/*
* EOF
*/

@ -38,18 +38,18 @@
*/ */
std::string md5wrapper::hashit(std::string text) std::string md5wrapper::hashit(std::string text)
{ {
MD5_CTX ctx; MD5Context ctx;
//init md5 //init md5
md5->MD5Init(&ctx); MD5Init(&ctx);
//update with our string //update with our string
md5->MD5Update(&ctx, MD5Update(&ctx,
(unsigned char*)text.c_str(), (unsigned char*)text.c_str(),
text.length()); text.length());
//create the hash //create the hash
unsigned char buff[16] = ""; unsigned char buff[16] = "";
md5->MD5Final((unsigned char*)buff,&ctx); MD5Final((unsigned char*)buff,&ctx);
//converte the hash to a string and return it //converte the hash to a string and return it
return convToString(buff); return convToString(buff);
@ -80,14 +80,12 @@ std::string md5wrapper::convToString(unsigned char *bytes)
//constructor //constructor
md5wrapper::md5wrapper() md5wrapper::md5wrapper()
{ {
md5 = new MD5();
} }
//destructor //destructor
md5wrapper::~md5wrapper() md5wrapper::~md5wrapper()
{ {
delete md5;
} }
/* /*
@ -111,7 +109,7 @@ std::string md5wrapper::getHashFromString(std::string text)
std::string md5wrapper::getHashFromFile(std::string filename, uint32_t & length, char * first_kb) std::string md5wrapper::getHashFromFile(std::string filename, uint32_t & length, char * first_kb)
{ {
FILE *file; FILE *file;
MD5_CTX context; MD5Context context;
int len; int len;
int saved = 0; int saved = 0;
@ -124,7 +122,7 @@ std::string md5wrapper::getHashFromFile(std::string filename, uint32_t & length,
} }
length = 0; length = 0;
//init md5 //init md5
md5->MD5Init (&context); MD5Init (&context);
//read the filecontent //read the filecontent
while (1) while (1)
@ -148,18 +146,18 @@ std::string md5wrapper::getHashFromFile(std::string filename, uint32_t & length,
} }
if(feof(file)) if(feof(file))
{ {
md5->MD5Update (&context, buffer, len); MD5Update (&context, buffer, len);
break; break;
} }
} }
md5->MD5Update (&context, buffer, len); MD5Update (&context, buffer, len);
} }
/* /*
generate hash, close the file and return the generate hash, close the file and return the
hash as std::string hash as std::string
*/ */
md5->MD5Final (digest, &context); MD5Final (digest, &context);
fclose (file); fclose (file);
return convToString(digest); return convToString(digest);
} }

@ -24,14 +24,9 @@
#include <string> #include <string>
#include <stdint.h> #include <stdint.h>
//forwards
class MD5;
class md5wrapper class md5wrapper
{ {
private: private:
MD5 *md5;
/* /*
* internal hash function, calling * internal hash function, calling
* the basic methods from md5.h * the basic methods from md5.h

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

@ -143,6 +143,9 @@ namespace DFHack
bool ncurses_wgetch(int in, int & out); bool ncurses_wgetch(int in, int & out);
Core(Core const&); // Don't Implement Core(Core const&); // Don't Implement
void operator=(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; bool errorstate;
// regulate access to DF // regulate access to DF
struct Cond; struct Cond;

@ -39,7 +39,7 @@ namespace DFHack
{ {
friend class ProcessEnumerator; friend class ProcessEnumerator;
public: public:
VersionInfoFactory(std::string path_to_xml); VersionInfoFactory();
~VersionInfoFactory(); ~VersionInfoFactory();
// memory info entries loaded from a file // memory info entries loaded from a file
bool loadFile( std::string path_to_xml); bool loadFile( std::string path_to_xml);
@ -47,6 +47,7 @@ namespace DFHack
VersionInfo * getVersionInfoByMD5(std::string md5string); VersionInfo * getVersionInfoByMD5(std::string md5string);
VersionInfo * getVersionInfoByPETimestamp(uint32_t timestamp); VersionInfo * getVersionInfoByPETimestamp(uint32_t timestamp);
std::vector<VersionInfo*> versions; std::vector<VersionInfo*> versions;
void clear( void );
private: private:
void ParseVTable(TiXmlElement* vtable, VersionInfo* mem); void ParseVTable(TiXmlElement* vtable, VersionInfo* mem);
void ParseBase (TiXmlElement* base, 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()) 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 // dump single material
con.print("%-3d : [%s] %s\n", con.print("%-3d : [%s] %s\n",
index, index,
mat->Inorganic_ID.c_str(), mat->ID.c_str(),
mat->STATE_NAME_SOLID.c_str()); mat->mat.state_name[DFHack::state_solid].c_str());
con.print("MAX EDGE: %d\n",mat->MAX_EDGE); con.print("MAX EDGE: %d\n",mat->mat.MAX_EDGE);
} }
else else
{ {
@ -74,7 +74,7 @@ DFhackCExport command_result rawdump_i (Core * c, vector <string> & parameters)
// dump all materials // dump all materials
for(int i = 0; i < mats->df_inorganic->size();i++) 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(); c->Resume();

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

@ -1 +1 @@
Subproject commit afea122f225b309f1c7052766ff491c213cc421a Subproject commit b1b1414ab7b46d9c408c9bdb1c561ee3684d86ed