diff --git a/library/DFProcess-linux-SHM.cpp b/library/DFProcess-linux-SHM.cpp index ace2dacf8..6f6bedb34 100644 --- a/library/DFProcess-linux-SHM.cpp +++ b/library/DFProcess-linux-SHM.cpp @@ -920,3 +920,15 @@ bool SHMProcess::Private::Aux_Core_Attach(bool & versionOK, pid_t & PID) #endif return true; } +string SHMProcess::getPath() +{ + char cwd_name[256]; + char target_name[1024]; + int target_result; + + sprintf(cwd_name,"/proc/%d/cwd", getPID()); + // resolve /proc/PID/exe link + target_result = readlink(cwd_name, target_name, sizeof(target_name)); + target_name[target_result] = '\0'; + return(string(target_name)); +} diff --git a/library/DFProcess-linux-wine.cpp b/library/DFProcess-linux-wine.cpp index 891a4f820..8ab9bc689 100644 --- a/library/DFProcess-linux-wine.cpp +++ b/library/DFProcess-linux-wine.cpp @@ -624,3 +624,15 @@ string WineProcess::readClassName (uint32_t vptr) raw.resize(raw.length() - 2);// trim @@ from end return raw; } +string WineProcess::getPath() +{ + char cwd_name[256]; + char target_name[1024]; + int target_result; + + sprintf(cwd_name,"/proc/%d/cwd", getPID()); + // resolve /proc/PID/exe link + target_result = readlink(cwd_name, target_name, sizeof(target_name)); + target_name[target_result] = '\0'; + return(string(target_name)); +} diff --git a/library/DFProcess-linux.cpp b/library/DFProcess-linux.cpp index 164834543..24bff365a 100644 --- a/library/DFProcess-linux.cpp +++ b/library/DFProcess-linux.cpp @@ -586,3 +586,15 @@ string NormalProcess::readClassName (uint32_t vptr) size_t end = raw.length(); return raw.substr(start,end-start); } +string NormalProcess::getPath() +{ + char cwd_name[256]; + char target_name[1024]; + int target_result; + + sprintf(cwd_name,"/proc/%d/cwd", getPID()); + // resolve /proc/PID/exe link + target_result = readlink(cwd_name, target_name, sizeof(target_name)); + target_name[target_result] = '\0'; + return(string(target_name)); +} diff --git a/library/DFProcess-windows-SHM.cpp b/library/DFProcess-windows-SHM.cpp index 9742ceeca..aa9d50dfe 100644 --- a/library/DFProcess-windows-SHM.cpp +++ b/library/DFProcess-windows-SHM.cpp @@ -929,6 +929,17 @@ string SHMProcess::readClassName (uint32_t vptr) return raw; } +string SHMProcess::getPath() +{ + HMODULE hmod; + DWORD junk; + char String[255]; + HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, d->process_ID ); //get the handle from the process ID + EnumProcessModules(hProcess, &hmod, 1 * sizeof(HMODULE), &junk); //get the module from the handle + GetModuleFileNameEx(hProcess,hmod,String,sizeof(String)); //get the filename from the module + string out(String); + return(out.substr(0,out.find_last_of("\\"))); +} // get module index by name and version. bool 0 = error bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) { diff --git a/library/DFProcess-windows.cpp b/library/DFProcess-windows.cpp index 0b3d7959d..5bc7bbe23 100644 --- a/library/DFProcess-windows.cpp +++ b/library/DFProcess-windows.cpp @@ -488,3 +488,13 @@ string NormalProcess::readClassName (uint32_t vptr) raw.resize(raw.length() - 2);// trim @@ from end return raw; } +string NormalProcess::getPath() +{ + HMODULE hmod; + DWORD junk; + char String[255]; + EnumProcessModules(d->my_handle, &hmod, 1 * sizeof(HMODULE), &junk); //get the module from the handle + GetModuleFileNameEx(d->my_handle,hmod,String,sizeof(String)); //get the filename from the module + string out(String); + return(out.substr(0,out.find_last_of("\\"))); +} \ No newline at end of file diff --git a/library/include/dfhack/DFProcess.h b/library/include/dfhack/DFProcess.h index 282e1b95f..3743cf4b7 100644 --- a/library/include/dfhack/DFProcess.h +++ b/library/include/dfhack/DFProcess.h @@ -163,6 +163,8 @@ namespace DFHack virtual VersionInfo *getDescriptor() = 0; /// get the DF Process ID virtual int getPID() = 0; + /// get the DF Process FilePath + virtual std::string getPath() = 0; /// get module index by name and version. bool 1 = error virtual bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) = 0; /// get the SHM start if available @@ -230,6 +232,7 @@ namespace DFHack void getMemRanges(std::vector & ranges ); VersionInfo *getDescriptor(); int getPID(); + std::string getPath(); // get module index by name and version. bool 1 = error bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) { OUTPUT=0; return false;}; // get the SHM start if available @@ -295,6 +298,7 @@ namespace DFHack void getMemRanges(std::vector & ranges ); VersionInfo *getDescriptor(); int getPID(); + std::string getPath(); // get module index by name and version. bool 1 = error bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT); // get the SHM start if available @@ -364,6 +368,7 @@ namespace DFHack // get the SHM start if available char * getSHMStart (void){return 0;}; bool SetAndWait (uint32_t state){return false;}; + std::string getPath(); }; #endif } diff --git a/library/include/dfhack/modules/WindowIO.h b/library/include/dfhack/modules/WindowIO.h index 6e1af9fcb..5244d2a1c 100644 --- a/library/include/dfhack/modules/WindowIO.h +++ b/library/include/dfhack/modules/WindowIO.h @@ -25,9 +25,9 @@ distribution. #ifndef KEYS_H_INCLUDED #define KEYS_H_INCLUDED -#include "dfhack/DFPragma.h" -#include "dfhack/DFExport.h" -#include "dfhack/DFModule.h" +#include "../DFPragma.h" +#include "../DFExport.h" +#include "../DFModule.h" namespace DFHack { diff --git a/library/modules/WindowIO-windows.cpp b/library/modules/WindowIO-windows.cpp index 37c5eb08c..1a432ade4 100644 --- a/library/modules/WindowIO-windows.cpp +++ b/library/modules/WindowIO-windows.cpp @@ -130,20 +130,19 @@ WindowIO::~WindowIO () void WindowIO::TypeStr (const char *input, int delay, bool useShift) { //sendmessage needs a window handle HWND, so have to get that from the process HANDLE - HWND currentWindow = GetForegroundWindow(); window myWindow; myWindow.pid = d->p->getPID(); EnumWindows (EnumWindowsProc, (LPARAM) &myWindow); - char cChar; - DWORD dfProccess = GetWindowThreadProcessId(myWindow.windowHandle,NULL); - DWORD currentProccess = GetWindowThreadProcessId(currentWindow,NULL); - AttachThreadInput(currentProccess,dfProccess,TRUE); //The two threads have to have attached input in order to change the keyboard state, which is needed to set the shift state + DWORD dfProcess = GetWindowThreadProcessId(myWindow.windowHandle,NULL); + DWORD currentProcess = GetCurrentThreadId(); + AttachThreadInput(currentProcess,dfProcess,TRUE); //The two threads have to have attached input in order to change the keyboard state, which is needed to set the shift state while ( (cChar = *input++)) // loops through chars { short vk = VkKeyScan (cChar); // keycode of char if (useShift || (vk >> 8) &1) // char is capital, so need to hold down shift { + vk = vk & 0xFF; // remove the shift state from the virtual key code BYTE keybstate[256] = {0}; BYTE keybstateOrig[256] = {0}; GetKeyboardState((LPBYTE)&keybstateOrig); @@ -160,7 +159,7 @@ void WindowIO::TypeStr (const char *input, int delay, bool useShift) SendMessage(myWindow.windowHandle,WM_KEYUP,vk,0); } } - AttachThreadInput(currentProccess,dfProccess,FALSE); //detach the threads + AttachThreadInput(currentProcess,dfProcess,FALSE); //detach the threads Sleep (delay); } diff --git a/tools/playground/CMakeLists.txt b/tools/playground/CMakeLists.txt index ab21e3c2d..f21d9170c 100644 --- a/tools/playground/CMakeLists.txt +++ b/tools/playground/CMakeLists.txt @@ -60,6 +60,13 @@ TARGET_LINK_LIBRARIES(dfcatsplosion dfhack) ADD_EXECUTABLE(dfcopypaste copypaste.cpp) TARGET_LINK_LIBRARIES(dfcopypaste dfhack) +# paths +# Author: belal +# dumps the current path to the DF exe, as well as the relative paths to the +# current tileset and color files +ADD_EXECUTABLE(dfpaths paths.cpp) +TARGET_LINK_LIBRARIES(dfpaths dfhack) + # this needs the C bindings IF(BUILD_DFHACK_C_BINDINGS) # for trying out some 'stuff' diff --git a/tools/playground/paths.cpp b/tools/playground/paths.cpp new file mode 100644 index 000000000..cc00f79a3 --- /dev/null +++ b/tools/playground/paths.cpp @@ -0,0 +1,31 @@ +#include +using namespace std; + +#include +using namespace DFHack; + +int main () +{ + DFHack::ContextManager DFMgr("Memory.xml"); + DFHack::Context *DF = DFMgr.getSingleContext(); + try + { + DF->Attach(); + } + catch (exception& e) + { + cerr << e.what() << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + DFHack::Process * Process = DF->getProcess(); + DFHack::Gui * gui = DF->getGui(); + cout << Process->getPath() << endl; + #ifndef LINUX_BUILD + cout << "Done. Press any key to continue" << endl; + cin.ignore(); + #endif + return 0; +} \ No newline at end of file