From 66bb9d448c3fca2135815129a1d1666d21843385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 20 Apr 2011 01:28:47 +0200 Subject: [PATCH] Big messy commit... --- library/DFProcess-SHM.cpp | 3 +- library/DFProcess-linux-base.cpp | 2 +- library/DFProcess-linux-wine.cpp | 8 +- library/DFProcess-linux.cpp | 36 ++++++-- library/MicrosoftSTL.cpp | 5 + library/include/dfhack/DFProcess.h | 18 +++- library/private/MicrosoftSTL.h | 2 +- library/private/SHMProcess.h | 2 +- tools/playground/CMakeLists.txt | 2 - tools/playground/fix-3708.cpp | 14 +-- tools/supported/CMakeLists.txt | 3 + .../{playground => supported}/cleanowned.cpp | 0 tools/supported/dfprospector-all.bat | 1 + tools/supported/prospector.cpp | 91 ++++++++++--------- 14 files changed, 117 insertions(+), 70 deletions(-) rename tools/{playground => supported}/cleanowned.cpp (100%) create mode 100644 tools/supported/dfprospector-all.bat diff --git a/library/DFProcess-SHM.cpp b/library/DFProcess-SHM.cpp index 2168a93c2..44622da51 100644 --- a/library/DFProcess-SHM.cpp +++ b/library/DFProcess-SHM.cpp @@ -476,7 +476,7 @@ size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapa return fit; } -void SHMProcess::writeSTLString(const uint32_t address, const std::string writeString) +size_t SHMProcess::writeSTLString(const uint32_t address, const std::string writeString) { if(!d->locked) throw Error::MemoryAccessDenied(address); @@ -484,4 +484,5 @@ void SHMProcess::writeSTLString(const uint32_t address, const std::string writeS strncpy(D_SHMDATA(char),writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator full_barrier d->SetAndWait(CORE_WRITE_STL_STRING); + return writeString.length(); } diff --git a/library/DFProcess-linux-base.cpp b/library/DFProcess-linux-base.cpp index 2fe712379..4c81222d7 100644 --- a/library/DFProcess-linux-base.cpp +++ b/library/DFProcess-linux-base.cpp @@ -220,7 +220,7 @@ void LinuxProcessBase::writeByte (uint32_t offset, uint8_t data) #endif } -// blah. I hate the kernel devs for crippling /proc/PID/mem. THIS IS RIDICULOUS +// blah. THIS IS RIDICULOUS void LinuxProcessBase::write (uint32_t offset, uint32_t size, uint8_t *source) { uint32_t indexptr = 0; diff --git a/library/DFProcess-linux-wine.cpp b/library/DFProcess-linux-wine.cpp index de4e14e63..f18083f14 100644 --- a/library/DFProcess-linux-wine.cpp +++ b/library/DFProcess-linux-wine.cpp @@ -71,7 +71,7 @@ namespace { void readSTLVector(const uint32_t address, t_vecTriplet & triplet); const std::string readSTLString (uint32_t offset); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); - void writeSTLString(const uint32_t address, const std::string writeString){}; + size_t writeSTLString(const uint32_t address, const std::string writeString); // get class name of an object with rtti/type info std::string readClassName(uint32_t vptr); }; @@ -157,6 +157,12 @@ size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcap return stl.readSTLString(offset, buffer, bufcapacity); } +size_t WineProcess::writeSTLString(const uint32_t address, const std::string writeString) +{ + return stl.writeSTLString(address,writeString); +} + + const string WineProcess::readSTLString (uint32_t offset) { return stl.readSTLString(offset); diff --git a/library/DFProcess-linux.cpp b/library/DFProcess-linux.cpp index ca8d835f4..03a65847e 100644 --- a/library/DFProcess-linux.cpp +++ b/library/DFProcess-linux.cpp @@ -65,8 +65,8 @@ namespace { void readSTLVector(const uint32_t address, t_vecTriplet & triplet); const std::string readSTLString (uint32_t offset); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); - void writeSTLString(const uint32_t address, const std::string writeString){}; - void copySTLString(const uint32_t address, const uint32_t target); + size_t writeSTLString(const uint32_t address, const std::string writeString); + size_t copySTLString(const uint32_t address, const uint32_t target); // get class name of an object with rtti/type info std::string readClassName(uint32_t vptr); }; @@ -126,9 +126,9 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * known_versions) struct _Rep_base { - uint32_t _M_length; - uint32_t _M_capacity; - uint32_t _M_refcount; + uint32_t _M_length; // length of text stored, not including zero termination + uint32_t _M_capacity; // capacity, not including zero termination + uint32_t _M_refcount; // reference count (two STL strings can share a common buffer, copy on write rules apply) }; size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) @@ -141,6 +141,27 @@ size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufc buffer[read_real] = 0; return read_real; } +//void LinuxProcessBase::write (uint32_t offset, uint32_t size, uint8_t *source) +size_t NormalProcess::writeSTLString(const uint32_t address, const std::string writeString) +{ + _Rep_base header; + // get buffer location + uint32_t start = Process::readDWord(address); + // read the header + read(start - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); + + // the buffer has actual size = 1. no space for storing anything more than a zero byte + if(header._M_capacity == 0) + return 0; + + // get writeable length (lesser of our string length and capacity of the target) + uint32_t lstr = writeString.length(); + uint32_t allowed_copy = min(lstr, header._M_capacity); + // write string, add a zero terminator, return bytes written + write(start, allowed_copy, (uint8_t *) writeString.c_str()); + writeByte(start + allowed_copy, 0); + return allowed_copy; +} void NormalProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet) { @@ -162,7 +183,7 @@ const string NormalProcess::readSTLString (uint32_t offset) return ret; } -void NormalProcess::copySTLString (uint32_t offset, uint32_t target) +size_t NormalProcess::copySTLString (uint32_t offset, uint32_t target) { _Rep_base header; @@ -170,7 +191,7 @@ void NormalProcess::copySTLString (uint32_t offset, uint32_t target) uint32_t old_target = Process::readDWord(target); if (offset == old_target) - return; + return 0; read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); @@ -183,6 +204,7 @@ void NormalProcess::copySTLString (uint32_t offset, uint32_t target) write(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); writeDWord(target, offset); + return header._M_length; } string NormalProcess::readClassName (uint32_t vptr) diff --git a/library/MicrosoftSTL.cpp b/library/MicrosoftSTL.cpp index 227ef7aca..98a758903 100644 --- a/library/MicrosoftSTL.cpp +++ b/library/MicrosoftSTL.cpp @@ -100,3 +100,8 @@ string MicrosoftSTL::readClassName (uint32_t vptr) raw.resize(raw.length() - 2);// trim @@ from end return raw; } + +size_t MicrosoftSTL::writeSTLString(const uint32_t address, const std::string writeString) +{ + return 0; +} \ No newline at end of file diff --git a/library/include/dfhack/DFProcess.h b/library/include/dfhack/DFProcess.h index 12e82ae22..c47c9bc3b 100644 --- a/library/include/dfhack/DFProcess.h +++ b/library/include/dfhack/DFProcess.h @@ -161,12 +161,20 @@ namespace DFHack virtual const std::string readSTLString (uint32_t offset) = 0; /// read an STL string virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) = 0; - /// write an STL string - virtual void writeSTLString(const uint32_t address, const std::string writeString) = 0; - /// share the string at source with target; may leak target - virtual void copySTLString(const uint32_t address, const uint32_t target) { - writeSTLString(target, readSTLString(address)); + /** + * write an STL string + * @return length written + */ + virtual size_t writeSTLString(const uint32_t address, const std::string writeString) = 0; + /** + * attempt to copy a string from source address to target address. may truncate or leak, depending on platform + * @return length copied + */ + virtual size_t copySTLString(const uint32_t address, const uint32_t target) + { + return writeSTLString(target, readSTLString(address)); } + /// read a STL vector virtual void readSTLVector(const uint32_t address, t_vecTriplet & triplet) = 0; /// get class name of an object with rtti/type info diff --git a/library/private/MicrosoftSTL.h b/library/private/MicrosoftSTL.h index 7ff2ddce2..1b9eab57b 100644 --- a/library/private/MicrosoftSTL.h +++ b/library/private/MicrosoftSTL.h @@ -39,7 +39,7 @@ namespace DFHack { const std::string readSTLString (uint32_t offset); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); - void writeSTLString(const uint32_t address, const std::string writeString){}; + size_t writeSTLString(const uint32_t address, const std::string writeString); // get class name of an object with rtti/type info std::string readClassName(uint32_t vptr); }; diff --git a/library/private/SHMProcess.h b/library/private/SHMProcess.h index b4e005ec3..9a1936c44 100644 --- a/library/private/SHMProcess.h +++ b/library/private/SHMProcess.h @@ -70,7 +70,7 @@ namespace DFHack const std::string readSTLString (uint32_t offset); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); - void writeSTLString(const uint32_t address, const std::string writeString); + size_t writeSTLString(const uint32_t address, const std::string writeString); void readSTLVector(const uint32_t address, t_vecTriplet & triplet); // get class name of an object with rtti/type info diff --git a/tools/playground/CMakeLists.txt b/tools/playground/CMakeLists.txt index 02489ed98..b86d05940 100644 --- a/tools/playground/CMakeLists.txt +++ b/tools/playground/CMakeLists.txt @@ -92,8 +92,6 @@ DFHACK_TOOL(dfcreature creature.cpp) # Dig a specific pattern (in this case 3x3 bedrooms, modify as you like) DFHACK_TOOL(dfdigpattern digpattern.cpp) -DFHACK_TOOL(dfcleanowned cleanowned.cpp) - DFHACK_TOOL(dffixbug-3708 fix-3708.cpp) # this needs the C bindings diff --git a/tools/playground/fix-3708.cpp b/tools/playground/fix-3708.cpp index 1cfe50d9c..2cfaed912 100644 --- a/tools/playground/fix-3708.cpp +++ b/tools/playground/fix-3708.cpp @@ -157,13 +157,13 @@ int main (int numargs, char ** args) if (goblins.size() >= ghosts.size() && ghosts.size() > 0) { - DFHack::OffsetGroup *ogf = mem->getGroup("Legends")->getGroup("figures"); - uint32_t f_vector = p->readDWord(ogf->getAddress("vector")); - uint32_t f_id = ogf->getOffset("figure_id"); - uint32_t f_unit = ogf->getOffset("unit_id"); - uint32_t f_name = ogf->getOffset("name"); - uint32_t f_race = ogf->getOffset("race"); - uint32_t f_profession = ogf->getOffset("profession"); + DFHack::OffsetGroup *grp_figures = mem->getGroup("Legends")->getGroup("figures"); + uint32_t f_vector = p->readDWord(grp_figures->getAddress("vector")); + uint32_t f_id = grp_figures->getOffset("figure_id"); + uint32_t f_unit = grp_figures->getOffset("unit_id"); + uint32_t f_name = grp_figures->getOffset("name"); + uint32_t f_race = grp_figures->getOffset("race"); + uint32_t f_profession = grp_figures->getOffset("profession"); for (std::list::iterator it = ghosts.begin(); it != ghosts.end(); ++it) { diff --git a/tools/supported/CMakeLists.txt b/tools/supported/CMakeLists.txt index e54e54cda..88f8f22c2 100644 --- a/tools/supported/CMakeLists.txt +++ b/tools/supported/CMakeLists.txt @@ -38,6 +38,9 @@ ENDIF() # cleanmap - removes mud, snow, blood and similar stuff from a map. farmers beware DFHACK_TOOL(dfcleanmap cleanmap.cpp) +# cleanowned - confiscate items owned by dwarves so they can be atomsmashed/reused/etc. +DFHACK_TOOL(dfcleanowned cleanowned.cpp) + # unstuck - make DF run if something goes wrong with the 'normal' memory access method DFHACK_TOOL(dfunstuck unstuck.cpp) diff --git a/tools/playground/cleanowned.cpp b/tools/supported/cleanowned.cpp similarity index 100% rename from tools/playground/cleanowned.cpp rename to tools/supported/cleanowned.cpp diff --git a/tools/supported/dfprospector-all.bat b/tools/supported/dfprospector-all.bat new file mode 100644 index 000000000..0756354a3 --- /dev/null +++ b/tools/supported/dfprospector-all.bat @@ -0,0 +1 @@ +dfprospector.exe -a \ No newline at end of file diff --git a/tools/supported/prospector.cpp b/tools/supported/prospector.cpp index 8e00cdcf8..6abbcf4fd 100644 --- a/tools/supported/prospector.cpp +++ b/tools/supported/prospector.cpp @@ -19,7 +19,7 @@ using namespace std; #include #include -template