From 837ea52c2216436f6ffc0fd947ba45a3deb8852a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 31 Mar 2011 05:39:12 +0200 Subject: [PATCH] Fix windows/wine version information bugs related to processes without a PE header. --- library/DFProcess-windows.cpp | 31 ++++++++++++++++++++----- library/DFProcessEnumerator.cpp | 11 +++++++-- library/VersionInfo.cpp | 34 +++++++++++++++++++--------- library/VersionInfoFactory.cpp | 17 +++++++++----- library/include/dfhack/VersionInfo.h | 4 ++-- library/modules/Maps.cpp | 2 +- 6 files changed, 71 insertions(+), 28 deletions(-) diff --git a/library/DFProcess-windows.cpp b/library/DFProcess-windows.cpp index adfb5ec06..2762bde35 100644 --- a/library/DFProcess-windows.cpp +++ b/library/DFProcess-windows.cpp @@ -155,17 +155,23 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory) my_handle = 0; return; } - + //cout << "PE Timestamp: " << hex << pe_header.FileHeader.TimeDateStamp << dec << endl; VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(pe_header.FileHeader.TimeDateStamp); if(vinfo) { + /* + cout << "Using version " << vinfo->getName() << ". Offsets follow:" << endl; + cout << "--------------------------------------------------------------" << endl; + cout << vinfo->PrintOffsets(); + cout << "--------------------------------------------------------------" << endl; + */ // only enumerate threads if this is a valid DF process. the enumeration is costly. vector threads_ids; if(!getThreadIDs( threads_ids )) { // thread enumeration failed. - my_handle = 0; CloseHandle(my_handle); + my_handle = 0; return; } identified = true; @@ -174,8 +180,20 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory) my_descriptor->RebaseAll(base); // keep track of created memory_info object so we can destroy it later my_descriptor->setParentProcess(this); - vector_start = my_descriptor->getGroup("vector")->getOffset("start"); - + try + { + vector_start = my_descriptor->getGroup("vector")->getOffset("start"); + stl.init(this); + } + catch (DFHack::Error::UnsetMemoryDefinition & e) + { + //cout << "WHAT THE FUCK WINE?" << endl; + //cout << "PID:" << pid << endl; + CloseHandle(my_handle); + my_handle = 0; + identified = false; + return; + } for(int i = 0; i < threads_ids.size();i++) { HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads_ids[i]); @@ -184,13 +202,14 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory) else cerr << "Unable to open thread :" << hex << (DWORD) threads_ids[i] << endl; } - stl.init(this); } else { // close handles of processes that aren't DF - my_handle = 0; + //cout << "ABOUT TO FREE HANDLE" << endl; CloseHandle(my_handle); + //cout << "FREE'D HANDLE" << endl; + my_handle = 0; } } diff --git a/library/DFProcessEnumerator.cpp b/library/DFProcessEnumerator.cpp index 94e40450a..8f2c16583 100644 --- a/library/DFProcessEnumerator.cpp +++ b/library/DFProcessEnumerator.cpp @@ -119,18 +119,25 @@ Process * BadProcesses::operator[](uint32_t index) //FIXME: wasteful Process *ProcessEnumerator::Private::GetProcessObject(ProcessID ID) { - +/* Process *p1 = createSHMProcess(ID.pid, meminfo); if(p1->isIdentified()) return p1; else delete p1; - +*/ Process *p2 = createNormalProcess(ID.pid, meminfo); if(p2->isIdentified()) + { + //cout << "IS OK" << endl; return p2; + } else + { + //cout << "ABOUT TO DELETE" << endl; delete p2; + //cout << "AFTER DELETE" << endl; + } #ifdef LINUX_BUILD Process *p3 = createWineProcess(ID.pid, meminfo); if(p3->isIdentified()) diff --git a/library/VersionInfo.cpp b/library/VersionInfo.cpp index 794ed095b..2326da388 100644 --- a/library/VersionInfo.cpp +++ b/library/VersionInfo.cpp @@ -602,7 +602,9 @@ namespace DFHack string version; OSType OS; std::string md5; + bool has_md5; uint32_t PE_timestamp; + bool has_timestamp; }; } @@ -616,8 +618,8 @@ VersionInfo::VersionInfo() d->classindex = 0; d->levels.reserve(NUM_RESERVE_LVLS); d->moods.reserve(NUM_RESERVE_MOODS); - d->md5 = "invalid"; - d->PE_timestamp = 0; + d->has_md5 = false; + d->has_timestamp = false; OffsetGroup(); } @@ -648,7 +650,9 @@ void VersionInfo::copy(const VersionInfo * old) d->version = old->d->version; d->OS = old->d->OS; d->md5 = old->d->md5; + d->has_md5 = old->d->has_md5; d->PE_timestamp = old->d->PE_timestamp; + d->has_timestamp = old->d->has_timestamp; d->base = old->d->base; //d->classes = old.d->classes; for(uint32_t i = 0; i < old->d->classes.size(); i++) @@ -709,21 +713,27 @@ string VersionInfo::getVersion() void VersionInfo::setMD5(const string &v) { d->md5 = v; + d->has_md5 = true; } -string VersionInfo::getMD5() +bool VersionInfo::getMD5( string & output ) { - return d->md5; + if(!d->has_md5) return false; + output = d->md5; + return true; } void VersionInfo::setPE(uint32_t v) { d->PE_timestamp = v; + d->has_timestamp = true; } -uint32_t VersionInfo::getPE() +bool VersionInfo::getPE(uint32_t & output) { - return d->PE_timestamp; + if(!d->has_timestamp) return false; + output = d->PE_timestamp; + return true; } void VersionInfo::setOS(const char *os) @@ -1186,17 +1196,19 @@ std::string VersionInfo::getMood(const uint32_t moodID) std::string VersionInfo::PrintOffsets() { ostringstream ss; + string md5; + uint32_t PE; indentr i; ss << i << "" << endl; i.indent(); switch (getOS()) { - case OS_LINUX: - ss << i << "" << endl; - break; case OS_WINDOWS: - ss << i << "" << endl; - ss << i << "" << endl; + if(getPE(PE)) + ss << i << "" << endl; + case OS_LINUX: + if(getMD5(md5)) + ss << i << "" << endl; break; default: ss << i << " UNKNOWN" << endl; diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp index 20bc61ac4..6484d7e11 100644 --- a/library/VersionInfoFactory.cpp +++ b/library/VersionInfoFactory.cpp @@ -112,26 +112,33 @@ VersionInfo * VersionInfoFactory::getVersionInfoByMD5(string hash) for(uint32_t i = 0; i < versions.size();i++) { vinfo = versions[i]; - if(vinfo->getMD5() == hash) + string test_hash; + if(vinfo->getMD5(test_hash) && hash == test_hash) { return vinfo; } } - return NULL; + return 0; } VersionInfo * VersionInfoFactory::getVersionInfoByPETimestamp(uint32_t timestamp) { VersionInfo * vinfo; + //cout << "lookup size:" << versions.size() << endl; for(uint32_t i = 0; i < versions.size();i++) { vinfo = versions[i]; - if(vinfo->getPE() == timestamp) + uint32_t test_PE; + //cout << "Testing version: " << hex << vinfo <<" No:" << dec << i << endl; + //cout << vinfo->getName() << endl; + if(vinfo->getPE(test_PE) && test_PE == timestamp) { return vinfo; } + //cout << "LOOP ENDS" << endl; } - return NULL; + //cout << "NOTHING!" << endl; + return 0; } @@ -746,8 +753,6 @@ bool VersionInfoFactory::loadFile(string path_to_xml) versions.push_back(version); } } - - // process found things here } error = false; return true; diff --git a/library/include/dfhack/VersionInfo.h b/library/include/dfhack/VersionInfo.h index 39e838234..414be9b2c 100644 --- a/library/include/dfhack/VersionInfo.h +++ b/library/include/dfhack/VersionInfo.h @@ -117,10 +117,10 @@ namespace DFHack void setBase (const uint32_t); void setMD5 (const std::string & _md5); - std::string getMD5(); + bool getMD5(std::string & output); void setPE (uint32_t PE_); - uint32_t getPE(); + bool getPE(uint32_t & output); std::string getMood(const uint32_t moodID); std::string getString (const std::string&); diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 15b1a3a8c..b1e77fd8f 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -166,7 +166,7 @@ Maps::Maps(DFContextShared* _d) { off.world_data = OG_Maps->getAddress("world_data"); d->usesWorldDataPtr = true; - cout << "uses world ptr" << endl; + //cout << "uses world ptr" << endl; }catch(Error::AllMemdef &){} {