diff --git a/components/files/linuxpath.cpp b/components/files/linuxpath.cpp index c485002fd..b11f27305 100644 --- a/components/files/linuxpath.cpp +++ b/components/files/linuxpath.cpp @@ -154,6 +154,76 @@ boost::filesystem::path LinuxPath::getRuntimeDataPath() const return boost::filesystem::path("./data/"); } +boost::filesystem::path LinuxPath::getInstallPath() const +{ + char *homePath = getenv("HOME"); + if(!homePath) + { + return boost::filesystem::path(""); + } + + boost::filesystem::path wineDefaultRegistry(homePath); + wineDefaultRegistry /= ".wine/system.reg"; + + boost::filesystem::path wineDriveC(homePath); + wineDriveC /= ".wine/drive_c"; + + boost::filesystem::file_status fileStatus = boost::filesystem::status(wineDefaultRegistry); + boost::filesystem::file_status dirStatus = boost::filesystem::status(wineDriveC); + if(!boost::filesystem::is_regular_file(fileStatus) || !boost::filesystem::is_directory(dirStatus)) + { + return boost::filesystem::path(""); + } + + + boost::filesystem::ifstream file(wineDefaultRegistry); + bool isRegEntry = false; + std::string line; + int startPos, pos; + + while (std::getline(file, line)) + { + if(line.length() > 0 && line[0] == '[') // we found an entry + { + std::string regkey = line.substr(1, line.find(']')-1); + if( regkey.compare("SOFTWARE\\\\Wow6432Node\\\\Bethesda Softworks\\\\Morrowind") == 0 + || regkey.compare("SOFTWARE\\\\Bethesda Softworks\\\\Morrowind") == 0 ) + { + isRegEntry = true; + } + } + else if(isRegEntry) + { + if(line.length() == 0 || line[0] != '"') // empty line means new registry key + { + break; + } + std::string key = line.substr(1, line.find('"', 1)-1); + if(key.compare("Installed Path") == 0) { + startPos = line.find('=')+2; + std::string installPath = line.substr(startPos, line.find('"', startPos+1)-startPos); + installPath.replace(0, 2, wineDriveC.string()); + + pos = -1; + do + { + pos = static_cast(installPath.find("\\\\", pos+1)); + if(static_cast(pos) == std::string::npos) + { + break; + } + + installPath.replace(pos, 2, "/"); + } while(true); + + return boost::filesystem::path(installPath); + } + } + } + + return boost::filesystem::path(""); +} + } /* namespace Files */ diff --git a/components/files/linuxpath.hpp b/components/files/linuxpath.hpp index d6e717fc4..62cf93664 100644 --- a/components/files/linuxpath.hpp +++ b/components/files/linuxpath.hpp @@ -26,6 +26,7 @@ #if defined(__linux__) #include +#include /** * \namespace Files @@ -81,6 +82,13 @@ struct LinuxPath * \return boost::filesystem::path */ boost::filesystem::path getRuntimeDataPath() const; + + /** + * \brief Gets the path of the installed Morrowind version if there is one. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getInstallPath() const; }; } /* namespace Files */ diff --git a/components/files/path.hpp b/components/files/path.hpp index 5a4cf337b..5139d9f78 100644 --- a/components/files/path.hpp +++ b/components/files/path.hpp @@ -76,6 +76,7 @@ struct Path , mLocalDataPath(mPath.getLocalDataPath()) , mGlobalDataPath(mPath.getGlobalDataPath()) , mRuntimeDataPath(mPath.getRuntimeDataPath()) + , mInstalledPath(mPath.getInstallPath()) { if (!application_name.empty()) { @@ -209,6 +210,26 @@ struct Path mRuntimeDataPath = path; } + /** + * \brief Return path pointing to the directory where application was started. + * + * \return boost::filesystem::path + */ + const boost::filesystem::path& getInstalledPath() const + { + return mInstalledPath; + } + + /** + * \brief Sets new runtime data directory. + * + * \param [in] path - New path + */ + void setInstalledPath(const boost::filesystem::path& path) + { + mInstalledPath = path; + } + private: PathType mPath; @@ -223,6 +244,7 @@ struct Path boost::filesystem::path mRuntimeDataPath; /**< Runtime path to the configuration files. By default it is a 'data' directory in same directory where application was run */ + boost::filesystem::path mInstalledPath; /**< Runtime path to the configuration files. */ };