From 96ed96d4dd432b3ee78c081575f888d0692c78c5 Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Mon, 16 Jan 2012 23:09:25 +0100 Subject: [PATCH 1/5] Quick test at getting Morrowinds install path from the registry on windows --- components/files/path.hpp | 2 +- components/files/windowspath.cpp | 37 +++++++++++++++++++++++++++++++- components/files/windowspath.hpp | 7 ++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/components/files/path.hpp b/components/files/path.hpp index 0788cefb1..5a4cf337b 100644 --- a/components/files/path.hpp +++ b/components/files/path.hpp @@ -30,7 +30,7 @@ #include namespace Files { typedef LinuxPath TargetPathType; } -#elif defined(__WIN32) || defined(__WINDOWS__) +#elif defined(__WIN32) || defined(__WINDOWS__) || defined(_WINDOWS) #include namespace Files { typedef WindowsPath TargetPathType; } diff --git a/components/files/windowspath.cpp b/components/files/windowspath.cpp index f42f149c1..5c87eba92 100644 --- a/components/files/windowspath.cpp +++ b/components/files/windowspath.cpp @@ -5,7 +5,10 @@ #include #include -#include +#include +#include + +#pragma comment(lib, "Shlwapi.lib") namespace Files { @@ -67,6 +70,38 @@ boost::filesystem::path WindowsPath::getRuntimeDataPath() const return boost::filesystem::path("./data/"); } +boost::filesystem::path WindowsPath::getInstallPath() const +{ + boost::filesystem::path installPath(""); + + HKEY hKey; + + BOOL f64 = FALSE; + LPCTSTR regkey; + if (IsWow64Process(GetCurrentProcess(), &f64) && f64) + { + regkey = "SOFTWARE\\Wow6432Node\\Bethesda Softworks\\Morrowind"; + } + else + { + regkey = "SOFTWARE\\Bethesda Softworks\\Morrowind"; + } + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(regkey), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) + { + //Key existed, let's try to read the install dir + char* data = new char[4096]; + int len = 4096; + + if (RegQueryValueEx(hKey, TEXT("Installed Path"), NULL, NULL, (LPBYTE)data, (LPDWORD)&len) == ERROR_SUCCESS) + { + installPath = data; + } + } + + return installPath; +} + } /* namespace Files */ #endif /* defined(_WIN32) || defined(__WINDOWS__) */ diff --git a/components/files/windowspath.hpp b/components/files/windowspath.hpp index 47dfc08d8..4550fc05f 100644 --- a/components/files/windowspath.hpp +++ b/components/files/windowspath.hpp @@ -81,6 +81,13 @@ struct WindowsPath * \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 */ From 8663177ad175d549ef9d08c26e9e740d10d2b73e Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Mon, 16 Jan 2012 23:21:13 +0100 Subject: [PATCH 2/5] Oops, forgot the delete... --- components/files/windowspath.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/files/windowspath.cpp b/components/files/windowspath.cpp index 5c87eba92..d83877232 100644 --- a/components/files/windowspath.cpp +++ b/components/files/windowspath.cpp @@ -97,6 +97,8 @@ boost::filesystem::path WindowsPath::getInstallPath() const { installPath = data; } + + delete[] data; } return installPath; From b4174b64195ddf6d03ded66dd574d80879c30708 Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Tue, 17 Jan 2012 09:02:45 +0100 Subject: [PATCH 3/5] Vector instead of new/delete --- components/files/windowspath.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/components/files/windowspath.cpp b/components/files/windowspath.cpp index d83877232..4fa70980e 100644 --- a/components/files/windowspath.cpp +++ b/components/files/windowspath.cpp @@ -90,15 +90,13 @@ boost::filesystem::path WindowsPath::getInstallPath() const if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(regkey), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) { //Key existed, let's try to read the install dir - char* data = new char[4096]; - int len = 4096; + std::vector buf(512); + int len = 512; - if (RegQueryValueEx(hKey, TEXT("Installed Path"), NULL, NULL, (LPBYTE)data, (LPDWORD)&len) == ERROR_SUCCESS) + if (RegQueryValueEx(hKey, TEXT("Installed Path"), NULL, NULL, (LPBYTE)&buf[0], (LPDWORD)&len) == ERROR_SUCCESS) { - installPath = data; + installPath = &buf[0]; } - - delete[] data; } return installPath; From 16c214a17af6c4506d89bad139a4d66e7423f180 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Tue, 17 Jan 2012 19:18:17 +0100 Subject: [PATCH 4/5] find InstalledPath in wine registry; mInstalledPath in Files::Path --- components/files/linuxpath.cpp | 70 ++++++++++++++++++++++++++++++++++ components/files/linuxpath.hpp | 8 ++++ components/files/path.hpp | 22 +++++++++++ 3 files changed, 100 insertions(+) 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. */ }; From 62eaaab69d607c11ae7eb645fe5df56243505383 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Tue, 17 Jan 2012 23:19:17 +0100 Subject: [PATCH 5/5] move include from .hpp to .cpp; line.empty() instead of line.size() > 0; change type of startPos and pos and move to other scope --- components/files/linuxpath.cpp | 12 +++++++----- components/files/linuxpath.hpp | 1 - 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/components/files/linuxpath.cpp b/components/files/linuxpath.cpp index b11f27305..5ca0856f1 100644 --- a/components/files/linuxpath.cpp +++ b/components/files/linuxpath.cpp @@ -28,6 +28,7 @@ #include #include #include +#include /** * \namespace Files @@ -179,11 +180,10 @@ boost::filesystem::path LinuxPath::getInstallPath() const 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 + if(!line.empty() && line[0] == '[') // we found an entry { std::string regkey = line.substr(1, line.find(']')-1); if( regkey.compare("SOFTWARE\\\\Wow6432Node\\\\Bethesda Softworks\\\\Morrowind") == 0 @@ -194,12 +194,14 @@ boost::filesystem::path LinuxPath::getInstallPath() const } else if(isRegEntry) { - if(line.length() == 0 || line[0] != '"') // empty line means new registry key + if(line.empty() || 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) { + std::string::size_type pos, startPos; + startPos = line.find('=')+2; std::string installPath = line.substr(startPos, line.find('"', startPos+1)-startPos); installPath.replace(0, 2, wineDriveC.string()); @@ -207,8 +209,8 @@ boost::filesystem::path LinuxPath::getInstallPath() const pos = -1; do { - pos = static_cast(installPath.find("\\\\", pos+1)); - if(static_cast(pos) == std::string::npos) + pos = installPath.find("\\\\", pos+1); + if(pos == std::string::npos) { break; } diff --git a/components/files/linuxpath.hpp b/components/files/linuxpath.hpp index 62cf93664..62cc14fff 100644 --- a/components/files/linuxpath.hpp +++ b/components/files/linuxpath.hpp @@ -26,7 +26,6 @@ #if defined(__linux__) #include -#include /** * \namespace Files