summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/appconfig.inc1
-rw-r--r--src/shared/directoryentry.cpp9
-rw-r--r--src/shared/directoryentry.h9
-rw-r--r--src/shared/fallout3info.cpp71
-rw-r--r--src/shared/fallout3info.h55
-rw-r--r--src/shared/fallout4info.cpp100
-rw-r--r--src/shared/fallout4info.h75
-rw-r--r--src/shared/falloutnvinfo.cpp71
-rw-r--r--src/shared/falloutnvinfo.h (renamed from src/shared/inject.h)34
-rw-r--r--src/shared/gameinfo.cpp167
-rw-r--r--src/shared/gameinfo.h89
-rw-r--r--src/shared/inject.cpp147
-rw-r--r--src/shared/oblivioninfo.cpp71
-rw-r--r--src/shared/oblivioninfo.h54
-rw-r--r--src/shared/skyriminfo.cpp81
-rw-r--r--src/shared/skyriminfo.h58
-rw-r--r--src/shared/util.cpp8
17 files changed, 935 insertions, 165 deletions
diff --git a/src/shared/appconfig.inc b/src/shared/appconfig.inc
index e2dbfe20..ac6c210f 100644
--- a/src/shared/appconfig.inc
+++ b/src/shared/appconfig.inc
@@ -14,7 +14,6 @@ APPPARAM(std::wstring, iniFileName, L"ModOrganizer.ini")
APPPARAM(std::wstring, proxyDLLTarget, L"steam_api.dll")
APPPARAM(std::wstring, proxyDLLOrig, L"steam_api_orig.dll") // needs to be identical to the value used in proxydll-project
APPPARAM(std::wstring, proxyDLLSource, L"proxy.dll")
-APPPARAM(std::wstring, hookDLLName, L"hook.dll") // needs to be identical to the value used in proxydll-project
APPPARAM(const wchar_t*, localSavePlaceholder, L"__MOProfileSave__\\")
APPPARAM(std::wstring, firstStepsTutorial, L"tutorial_firststeps_main.js")
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp
index 54b6efff..df6a7b5a 100644
--- a/src/shared/directoryentry.cpp
+++ b/src/shared/directoryentry.cpp
@@ -24,7 +24,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <bsatk.h>
#include <boost/bind.hpp>
#include <boost/scoped_array.hpp>
-#include <boost/foreach.hpp>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <sstream>
@@ -704,7 +703,7 @@ FilesOrigin &DirectoryEntry::getOriginByName(const std::wstring &name) const
return m_OriginConnection->getByName(name);
}
-
+/*
int DirectoryEntry::getOrigin(const std::wstring &path, bool &archive)
{
const DirectoryEntry *directory = nullptr;
@@ -718,7 +717,7 @@ int DirectoryEntry::getOrigin(const std::wstring &path, bool &archive)
return -1;
}
}
-}
+}*/
std::vector<FileEntry::Ptr> DirectoryEntry::getFiles() const
{
@@ -950,12 +949,12 @@ void FileRegister::removeOriginMulti(std::set<FileEntry::Index> indices, int ori
// the latter should be faster when there are many files in few directories. since this is called
// only when disabling an origin that is probably frequently the case
std::set<DirectoryEntry*> parents;
- BOOST_FOREACH (const FileEntry::Ptr &file, removedFiles) {
+ for (const FileEntry::Ptr &file : removedFiles) {
if (file->getParent() != nullptr) {
parents.insert(file->getParent());
}
}
- BOOST_FOREACH (DirectoryEntry *parent, parents) {
+ for (DirectoryEntry *parent : parents) {
parent->removeFiles(indices);
}
}
diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h
index 2d32450a..04b8782b 100644
--- a/src/shared/directoryentry.h
+++ b/src/shared/directoryentry.h
@@ -207,7 +207,8 @@ public:
DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID);
DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID,
- boost::shared_ptr<FileRegister> fileRegister, boost::shared_ptr<OriginConnection> originConnection);
+ boost::shared_ptr<FileRegister> fileRegister,
+ boost::shared_ptr<OriginConnection> originConnection);
~DirectoryEntry();
@@ -232,7 +233,9 @@ public:
FilesOrigin &getOriginByID(int ID) const;
FilesOrigin &getOriginByName(const std::wstring &name) const;
- int getOrigin(const std::wstring &path, bool &archive);
+ int anyOrigin() const;
+
+ //int getOrigin(const std::wstring &path, bool &archive);
std::vector<FileEntry::Ptr> getFiles() const;
@@ -316,8 +319,6 @@ private:
DirectoryEntry *getSubDirectoryRecursive(const std::wstring &path, bool create, int originID = -1);
- int anyOrigin() const;
-
void removeDirRecursive();
private:
diff --git a/src/shared/fallout3info.cpp b/src/shared/fallout3info.cpp
new file mode 100644
index 00000000..446d4afe
--- /dev/null
+++ b/src/shared/fallout3info.cpp
@@ -0,0 +1,71 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "fallout3info.h"
+#include "util.h"
+#include <tchar.h>
+#include <ShlObj.h>
+#include <sstream>
+#include "windows_error.h"
+#include "error_report.h"
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <boost/assign.hpp>
+
+namespace MOShared {
+
+Fallout3Info::Fallout3Info(const std::wstring &gameDirectory)
+ : GameInfo(gameDirectory)
+{
+ identifyMyGamesDirectory(L"fallout3");
+}
+
+bool Fallout3Info::identifyGame(const std::wstring &searchPath)
+{
+ return FileExists(searchPath, L"Fallout3.exe") &&
+ FileExists(searchPath, L"FalloutLauncher.exe");
+}
+
+std::wstring Fallout3Info::getRegPathStatic()
+{
+ HKEY key;
+ LONG errorcode = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Bethesda Softworks\\Fallout3",
+ 0, KEY_QUERY_VALUE, &key);
+
+ if (errorcode != ERROR_SUCCESS) {
+ return std::wstring();
+ }
+
+ WCHAR temp[MAX_PATH];
+ DWORD bufferSize = MAX_PATH;
+
+ if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) {
+ return std::wstring(temp);
+ } else {
+ return std::wstring();
+ }
+}
+
+
+std::vector<std::wstring> Fallout3Info::getIniFileNames() const
+{
+ return boost::assign::list_of(L"fallout.ini")(L"falloutprefs.ini");
+}
+
+} // namespace MOShared
diff --git a/src/shared/fallout3info.h b/src/shared/fallout3info.h
new file mode 100644
index 00000000..601fc346
--- /dev/null
+++ b/src/shared/fallout3info.h
@@ -0,0 +1,55 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef FALLOUT3INFO_H
+#define FALLOUT3INFO_H
+
+#include "gameinfo.h"
+
+namespace MOShared {
+
+
+class Fallout3Info : public GameInfo
+{
+
+ friend class GameInfo;
+
+public:
+
+ virtual ~Fallout3Info() {}
+
+ static std::wstring getRegPathStatic();
+ virtual std::wstring getRegPath() const { return getRegPathStatic(); }
+
+ // file name of this games ini (no path)
+ virtual std::vector<std::wstring> getIniFileNames() const;
+
+ virtual std::wstring archiveListKey() const { return L"SArchiveList"; }
+
+private:
+
+ Fallout3Info(const std::wstring &gameDirectory);
+
+ static bool identifyGame(const std::wstring &searchPath);
+
+};
+
+} // namespace MOShared
+
+#endif // FALLOUT3INFO_H
diff --git a/src/shared/fallout4info.cpp b/src/shared/fallout4info.cpp
new file mode 100644
index 00000000..aab431ad
--- /dev/null
+++ b/src/shared/fallout4info.cpp
@@ -0,0 +1,100 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "fallout4info.h"
+#include "util.h"
+#include <tchar.h>
+#include <ShlObj.h>
+#include <sstream>
+#include "windows_error.h"
+#include "error_report.h"
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <boost/assign.hpp>
+
+namespace MOShared {
+
+Fallout4Info::Fallout4Info(const std::wstring &gameDirectory)
+ : GameInfo(gameDirectory)
+{
+ identifyMyGamesDirectory(L"fallout4");
+}
+
+bool Fallout4Info::identifyGame(const std::wstring &searchPath)
+{
+ return FileExists(searchPath, L"Fallout4.exe") &&
+ FileExists(searchPath, L"Fallout4Launcher.exe");
+}
+
+std::wstring Fallout4Info::getRegPathStatic()
+{
+ HKEY key;
+ LONG errorcode = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Bethesda Softworks\\Fallout4",
+ 0, KEY_QUERY_VALUE, &key);
+
+ if (errorcode != ERROR_SUCCESS) {
+ return std::wstring();
+ }
+
+ WCHAR temp[MAX_PATH];
+ DWORD bufferSize = MAX_PATH;
+
+ if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) {
+ return std::wstring(temp);
+ } else {
+ return std::wstring();
+ }
+}
+
+
+std::vector<std::wstring> Fallout4Info::getDLCPlugins()
+{
+ return std::vector<std::wstring>();
+}
+
+std::vector<std::wstring> Fallout4Info::getSavegameAttachmentExtensions()
+{
+ return std::vector<std::wstring>();
+}
+
+std::vector<std::wstring> Fallout4Info::getIniFileNames() const
+{
+ return boost::assign::list_of(L"fallout4.ini")(L"fallout4prefs.ini");
+}
+
+std::wstring Fallout4Info::getNexusPage(bool nmmScheme)
+{
+ if (nmmScheme) {
+ return L"http://nmm.nexusmods.com/fallout4";
+ } else {
+ return L"http://www.nexusmods.com/fallout4";
+ }
+}
+
+std::wstring Fallout4Info::getNexusInfoUrlStatic()
+{
+ return L"http://nmm.nexusmods.com/fallout4";
+}
+
+int Fallout4Info::getNexusModIDStatic()
+{
+ return 377160;
+}
+
+} // namespace MOShared
diff --git a/src/shared/fallout4info.h b/src/shared/fallout4info.h
new file mode 100644
index 00000000..70c9b7d3
--- /dev/null
+++ b/src/shared/fallout4info.h
@@ -0,0 +1,75 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef FALLOUT4INFO_H
+#define FALLOUT4INFO_H
+
+
+#include "gameinfo.h"
+
+namespace MOShared {
+
+
+class Fallout4Info : public GameInfo
+{
+
+ friend class GameInfo;
+
+public:
+
+ virtual ~Fallout4Info() {}
+
+ static std::wstring getRegPathStatic();
+ virtual std::wstring getRegPath() const { return getRegPathStatic(); }
+ virtual std::wstring getBinaryName() { return L"Fallout4.exe"; }
+
+ virtual std::wstring getGameName() const { return L"Fallout 4"; }
+ virtual std::wstring getGameShortName() const { return L"Fallout4"; }
+
+ virtual std::vector<std::wstring> getDLCPlugins();
+ virtual std::vector<std::wstring> getSavegameAttachmentExtensions();
+
+ // file name of this games ini (no path)
+ virtual std::vector<std::wstring> getIniFileNames() const;
+
+ virtual std::wstring getNexusPage(bool nmmScheme = true);
+ static std::wstring getNexusInfoUrlStatic();
+ virtual std::wstring getNexusInfoUrl() { return getNexusInfoUrlStatic(); }
+ static int getNexusModIDStatic();
+ virtual int getNexusModID() { return getNexusModIDStatic(); }
+ virtual int getNexusGameID() { return 1151; }
+
+ // get a list of executables (game binary and known-to-work 3rd party tools). All of these are relative to
+ // the game directory
+ //virtual std::vector<ExecutableInfo> getExecutables();
+
+ virtual std::wstring archiveListKey() { return L"SArchiveList"; }
+
+private:
+
+ Fallout4Info(const std::wstring &gameDirectory);
+
+ static bool identifyGame(const std::wstring &searchPath);
+
+
+};
+
+} // namespace MOShared
+
+#endif // FALLOUT3INFO_H
diff --git a/src/shared/falloutnvinfo.cpp b/src/shared/falloutnvinfo.cpp
new file mode 100644
index 00000000..510dfa01
--- /dev/null
+++ b/src/shared/falloutnvinfo.cpp
@@ -0,0 +1,71 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "falloutnvinfo.h"
+#include "util.h"
+#include <tchar.h>
+#include <ShlObj.h>
+#include <sstream>
+#include "windows_error.h"
+#include "error_report.h"
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <boost/assign.hpp>
+
+namespace MOShared {
+
+
+FalloutNVInfo::FalloutNVInfo(const std::wstring &gameDirectory)
+ : GameInfo(gameDirectory)
+{
+ identifyMyGamesDirectory(L"falloutnv");
+}
+
+bool FalloutNVInfo::identifyGame(const std::wstring &searchPath)
+{
+ return FileExists(searchPath, L"FalloutNV.exe") &&
+ FileExists(searchPath, L"FalloutNVLauncher.exe");
+}
+
+std::wstring FalloutNVInfo::getRegPathStatic()
+{
+ HKEY key;
+ LONG errorcode = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Bethesda Softworks\\FalloutNV",
+ 0, KEY_QUERY_VALUE, &key);
+
+ if (errorcode != ERROR_SUCCESS) {
+ return std::wstring();
+ }
+
+ WCHAR temp[MAX_PATH];
+ DWORD bufferSize = MAX_PATH;
+
+ if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) {
+ return std::wstring(temp);
+ } else {
+ return std::wstring();
+ }
+}
+
+std::vector<std::wstring> FalloutNVInfo::getIniFileNames() const
+{
+ return boost::assign::list_of(L"fallout.ini")(L"falloutprefs.ini");
+}
+
+} // namespace MOShared
diff --git a/src/shared/inject.h b/src/shared/falloutnvinfo.h
index 7f4f2962..a9b3b9ec 100644
--- a/src/shared/inject.h
+++ b/src/shared/falloutnvinfo.h
@@ -17,15 +17,37 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
-#pragma once
+#ifndef FALLOUTNVINFO_H
+#define FALLOUTNVINFO_H
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <string>
+#include "gameinfo.h"
namespace MOShared {
-void injectDLL(HANDLE processHandle, HANDLE threadHandle, const std::string &dllname, const std::wstring &profileName, int logLevel);
-}
+class FalloutNVInfo : public GameInfo
+{
+
+ friend class GameInfo;
+
+public:
+
+ virtual ~FalloutNVInfo() {}
+
+ static std::wstring getRegPathStatic();
+ virtual std::wstring getRegPath() const { return getRegPathStatic(); }
+
+ // file name of this games ini (no path)
+ virtual std::vector<std::wstring> getIniFileNames() const;
+
+private:
+
+ FalloutNVInfo(const std::wstring &gameDirectory);
+
+ static bool identifyGame(const std::wstring &searchPath);
+};
+
+} // namespace MOShared
+
+#endif // FALLOUTNVINFO_H
diff --git a/src/shared/gameinfo.cpp b/src/shared/gameinfo.cpp
new file mode 100644
index 00000000..9b097053
--- /dev/null
+++ b/src/shared/gameinfo.cpp
@@ -0,0 +1,167 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "gameinfo.h"
+
+#include "windows_error.h"
+
+#include "oblivioninfo.h"
+#include "fallout3info.h"
+#include "fallout4info.h"
+#include "falloutnvinfo.h"
+#include "skyriminfo.h"
+#include "util.h"
+
+#include <boost/assign.hpp>
+#include <boost/format.hpp>
+
+#include <shlobj.h>
+#include <sstream>
+#include <cassert>
+
+namespace MOShared {
+
+
+GameInfo* GameInfo::s_Instance = nullptr;
+
+
+GameInfo::GameInfo(const std::wstring &gameDirectory)
+ : m_GameDirectory(gameDirectory)
+{
+ atexit(&cleanup);
+}
+
+
+void GameInfo::cleanup() {
+ delete GameInfo::s_Instance;
+ GameInfo::s_Instance = nullptr;
+}
+
+
+void GameInfo::identifyMyGamesDirectory(const std::wstring &file)
+{
+ // this function attempts 3 (three!) ways to determine the correct "My Games" folder.
+ wchar_t myDocuments[MAX_PATH];
+ memset(myDocuments, '\0', MAX_PATH * sizeof(wchar_t));
+
+ m_MyGamesDirectory.clear();
+
+ // a) this is the way it should work. get the configured My Documents\My Games directory
+ if (::SHGetFolderPathW(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_CURRENT, myDocuments) == S_OK) {
+ m_MyGamesDirectory = std::wstring(myDocuments) + L"\\My Games";
+ }
+
+ // b) if there is no <game> directory there, look in the default directory
+ if (m_MyGamesDirectory.empty()
+ || !FileExists(m_MyGamesDirectory + L"\\" + file)) {
+ if (::SHGetFolderPathW(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_DEFAULT, myDocuments) == S_OK) {
+ std::wstring fromDefault = std::wstring(myDocuments) + L"\\My Games";
+ if (FileExists(fromDefault + L"\\" + file)) {
+ m_MyGamesDirectory = fromDefault;
+ }
+ }
+ }
+ // c) finally, look in the registry. This is discouraged
+ if (m_MyGamesDirectory.empty()
+ || !FileExists(m_MyGamesDirectory + L"\\" + file)) {
+ std::wstring fromRegistry = getSpecialPath(L"Personal") + L"\\My Games";
+ if (FileExists(fromRegistry + L"\\" + file)) {
+ m_MyGamesDirectory = fromRegistry;
+ }
+ }
+}
+
+bool GameInfo::identifyGame(const std::wstring &searchPath)
+{
+ if (OblivionInfo::identifyGame(searchPath)) {
+ s_Instance = new OblivionInfo(searchPath);
+ } else if (Fallout3Info::identifyGame(searchPath)) {
+ s_Instance = new Fallout3Info(searchPath);
+ } else if (FalloutNVInfo::identifyGame(searchPath)) {
+ s_Instance = new FalloutNVInfo(searchPath);
+ } else if (SkyrimInfo::identifyGame(searchPath)) {
+ s_Instance = new SkyrimInfo(searchPath);
+ } else if (Fallout4Info::identifyGame(searchPath)) {
+ s_Instance = new Fallout4Info(searchPath);
+ }
+
+ return s_Instance != nullptr;
+}
+
+
+bool GameInfo::init(const std::wstring &moDirectory, const std::wstring &gamePath)
+{
+ if (s_Instance == nullptr) {
+ if (gamePath.length() == 0) {
+ // search upward in the directory until a recognized game-binary is found
+ std::wstring searchPath(moDirectory);
+ while (!identifyGame(searchPath)) {
+ size_t lastSep = searchPath.find_last_of(L"/\\");
+ if (lastSep == std::string::npos) {
+ return false;
+ }
+ searchPath.erase(lastSep);
+ }
+ } else if (!identifyGame(gamePath)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+GameInfo &GameInfo::instance()
+{
+ assert(s_Instance != nullptr && "gameinfo not yet initialized");
+ return *s_Instance;
+}
+
+std::wstring GameInfo::getGameDirectory() const
+{
+ return m_GameDirectory;
+}
+
+std::wstring GameInfo::getSpecialPath(LPCWSTR name) const
+{
+ HKEY key;
+ LONG errorcode = ::RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
+ 0, KEY_QUERY_VALUE, &key);
+
+ if (errorcode != ERROR_SUCCESS) {
+ throw windows_error("failed to look up special folder (path)", errorcode);
+ }
+
+ WCHAR temp[MAX_PATH];
+ DWORD bufferSize = MAX_PATH;
+
+ errorcode = ::RegQueryValueExW(key, name, nullptr, nullptr, (LPBYTE)temp, &bufferSize);
+ if (errorcode != ERROR_SUCCESS) {
+ throw windows_error((boost::format("failed to look up special folder (%1%)") % ToString(name, true)).str(), errorcode);
+ }
+
+ WCHAR temp2[MAX_PATH];
+ // try to expand variables in the path, if any
+ if (::ExpandEnvironmentStringsW(temp, temp2, MAX_PATH) != 0) {
+ return temp2;
+ } else {
+ return temp;
+ }
+}
+
+} // namespace MOShared
diff --git a/src/shared/gameinfo.h b/src/shared/gameinfo.h
new file mode 100644
index 00000000..c99ebef7
--- /dev/null
+++ b/src/shared/gameinfo.h
@@ -0,0 +1,89 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef GAMEINFO_H
+#define GAMEINFO_H
+
+#include <string>
+#include <vector>
+#include <wchar.h>
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+namespace MOShared {
+
+
+/**
+ Class to manage information that depends on the used game type. The intention is to keep
+ as much of the rest of omo is game-agnostic. It is mostly concerned with figuring out the
+ correct paths, filenames and data types.
+*/
+class GameInfo
+{
+
+public:
+
+ virtual ~GameInfo() {}
+
+ //**USED IN HOOKDLL and at startup to set up for hookdll to work
+ // initialise with the path to the mo directory (needs to be where hook.dll is stored). This
+ // needs to be called before the instance can be retrieved
+ static bool init(const std::wstring &moDirectory, const std::wstring &gamePath = L"");
+
+ //**USED ONLY IN HOOKDLL
+ static GameInfo& instance();
+
+ //**USED ONLY IN HOOKDLL
+ virtual std::wstring getGameDirectory() const;
+
+ //**USED ONLY IN HOOKDLL
+ virtual std::wstring getRegPath() const = 0;
+
+ //**USED ONLY IN HOOKDLL
+ // file name of this games ini file(s)
+ virtual std::vector<std::wstring> getIniFileNames() const = 0;
+
+protected:
+
+ GameInfo(const std::wstring &gameDirectory);
+
+ void identifyMyGamesDirectory(const std::wstring &file);
+
+private:
+
+ static bool identifyGame(const std::wstring &searchPath);
+ std::wstring getSpecialPath(LPCWSTR name) const;
+
+ static void cleanup();
+
+private:
+
+ static GameInfo *s_Instance;
+
+ std::wstring m_MyGamesDirectory;
+
+ std::wstring m_GameDirectory;
+
+};
+
+
+} // namespace MOShared
+
+#endif // GAMEINFO_H
diff --git a/src/shared/inject.cpp b/src/shared/inject.cpp
deleted file mode 100644
index fcd4cfab..00000000
--- a/src/shared/inject.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "inject.h"
-/*#if defined UNICODE && !defined _UNICODE
-#define _UNICODE 1
-#endif*/
-#include <wchar.h>
-#include <cstdio>
-#include <tchar.h>
-#include <cstdlib>
-#include <exception>
-#include <stdexcept>
-#include <string>
-#include "windows_error.h"
-#include "error_report.h"
-
-namespace MOShared {
-
-
-struct TParameters {
- char dllname[MAX_PATH];
- wchar_t profileName[101];
- char initstr[5];
- int logLevel;
-};
-
-
-typedef HMODULE (WINAPI *TLoadLibraryType)(LPCTSTR);
-typedef FARPROC (WINAPI *TGetProcAddressType)(HMODULE, LPCSTR);
-
-
-
-void injectDLL(HANDLE processHandle, HANDLE threadHandle, const std::string &dllname, const std::wstring &profileName, int logLevel)
-{
- // prepare parameters that are to be passed to the injected dll
- TParameters parameters;
- memset(&parameters, '\0', sizeof(TParameters));
- strncpy(parameters.dllname, dllname.c_str(), MAX_PATH - 1);
- wcsncpy(parameters.profileName, profileName.c_str(), 100);
- _snprintf(parameters.initstr, 5, "Init"); //this is the name of thie initialisation function we want to call in the target process
-
- HMODULE k32mod = ::LoadLibrary(__TEXT("kernel32.dll"));
- TLoadLibraryType loadLibraryFunc = nullptr;
- TGetProcAddressType getProcAddressFunc = nullptr;
- // ansi binaries
- if (k32mod != nullptr) {
- loadLibraryFunc = reinterpret_cast<TLoadLibraryType>(::GetProcAddress(k32mod, "LoadLibraryA"));
- getProcAddressFunc = reinterpret_cast<TGetProcAddressType>(::GetProcAddress(k32mod, "GetProcAddress"));
- if ((loadLibraryFunc == nullptr) || (getProcAddressFunc == nullptr)) {
- throw windows_error("failed to determine address for required functions");
- }
- } else {
- throw windows_error("kernel32.dll not loaded??");
- }
-
- // allocate memory in the target process and write the parameter-block there
- LPVOID remoteMem = ::VirtualAllocEx(processHandle, nullptr, sizeof(TParameters), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- if (remoteMem == nullptr) {
- throw windows_error("failed to allocate memory in target process");
- }
- SIZE_T written;
- if (!::WriteProcessMemory(processHandle, remoteMem, &parameters, sizeof(TParameters), &written) ||
- (written != sizeof(TParameters))) {
- throw windows_error("failed to write parameters to target process");
- }
-
- // now for the interesting part: write a stub into the target process that is run before any code of the original binary. This code will load
- // our injected dll into the process and run its Init-function which takes the profile name as its parameter
- // obviously this code is ultra-hacky
-
- // construct the stub in beautiful assembler with placeholders
- BYTE stubLocal[] = { 0x60, // PUSHAD
- 0xB8, 0xBA, 0xAD, 0xF0, 0x0D, // MOV EAX, imm32 (LoadLibrary)
- 0x68, 0xBA, 0xAD, 0xF0, 0x0D, // PUSH imm32 (dllname)
- 0xFF, 0xD0, // CALL EAX (=LoadLibrary, leaves module handle of our dll in eax)
- 0x68, 0xBA, 0xAD, 0xF0, 0x0D, // PUSH imm32 ("Init")
- 0x50, // PUSH EAX
- 0xB8, 0xBA, 0xAD, 0xF0, 0x0D, // MOVE EAX, imm32 (GetProcAddress)
- 0xFF, 0xD0, // CALL EAX (=GetProcAddress, leaves address of init function in eax)
- 0x68, 0xBA, 0xAD, 0xF0, 0x0D, // PUSH imm32 (profile name)
- 0x68, 0xBA, 0xAD, 0xF0, 0x0D, // PUSH imm32 (log level)
- 0xFF, 0xD0, // CALL EAX (=InitFunction)
- 0x58, // POP EAX (init function is defined cdecl)
- 0x58, // POP EAX (init function is defined cdecl)
- 0x61, // POPAD
- 0xE9, 0xBA, 0xAD, 0xF0, 0x0D // JMP near, relative (=original entry point)
- };
-
- // reserve memory for the stub
- PBYTE stubRemote = reinterpret_cast<PBYTE>(::VirtualAllocEx(processHandle, nullptr, sizeof(stubLocal), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
- if (stubRemote == nullptr) {
- throw windows_error("failed to allocate memory for stub");
- }
- TParameters *remoteParams = reinterpret_cast<TParameters*>(remoteMem);
-
- // dizzy yet? we still have to calculate the entry point as an address relative to our stub
- ULONG entryPoint = 0;
-
- // not implemented on 64 bit systems
-#ifdef _X86_
- CONTEXT threadContext;
- threadContext.ContextFlags = CONTEXT_CONTROL;
- if (::GetThreadContext(threadHandle, &threadContext) == 0) {
- throw windows_error("failed to access thread context. Please note that Mod Organizer does not support 64bit binaries!");
- } else {
- entryPoint = threadContext.Eip - (reinterpret_cast<ULONG>(stubRemote) + sizeof(stubLocal));
- }
- // now replace each baadf00d by the correct value. The pointers need to be the pointers in the REMOTE memory of course, that's why we copied them there
- *(PULONG)&stubLocal[2] = reinterpret_cast<ULONG>(*loadLibraryFunc);
- *(PULONG)&stubLocal[7] = reinterpret_cast<ULONG>(remoteParams->dllname);
- *(PULONG)&stubLocal[14] = reinterpret_cast<ULONG>(remoteParams->initstr);
- *(PULONG)&stubLocal[20] = reinterpret_cast<ULONG>(*getProcAddressFunc);
- *(PULONG)&stubLocal[27] = reinterpret_cast<ULONG>(remoteParams->profileName);
- *(PULONG)&stubLocal[32] = logLevel;
- *(PULONG)&stubLocal[42] = entryPoint;
- // almost there. copy stub to target process
- if (!::WriteProcessMemory(processHandle, stubRemote, reinterpret_cast<LPCVOID>(stubLocal), sizeof(stubLocal), &written) ||
- (written != sizeof(stubLocal))) {
- throw windows_error("failed to write stub to target process");
- }
-
- // finally, make the stub the new next thing for the thread to execute
- threadContext.Eip = (ULONG)stubRemote;
- if (::SetThreadContext(threadHandle, &threadContext) == 0) {
- throw windows_error("failed to overwrite thread context");
- }
-#endif
-}
-
-} // namespace MOShared
diff --git a/src/shared/oblivioninfo.cpp b/src/shared/oblivioninfo.cpp
new file mode 100644
index 00000000..b290fb36
--- /dev/null
+++ b/src/shared/oblivioninfo.cpp
@@ -0,0 +1,71 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "oblivioninfo.h"
+#include <tchar.h>
+#include <ShlObj.h>
+#include "util.h"
+#include <sstream>
+#include "windows_error.h"
+#include "error_report.h"
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <boost/assign.hpp>
+
+namespace MOShared {
+
+
+OblivionInfo::OblivionInfo(const std::wstring &gameDirectory)
+ : GameInfo(gameDirectory)
+{
+ identifyMyGamesDirectory(L"oblivion");
+}
+
+bool OblivionInfo::identifyGame(const std::wstring &searchPath)
+{
+ return FileExists(searchPath, L"Oblivion.exe") &&
+ FileExists(searchPath, L"OblivionLauncher.exe");
+}
+
+std::wstring OblivionInfo::getRegPathStatic()
+{
+ HKEY key;
+ LONG errorcode = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Bethesda Softworks\\Oblivion",
+ 0, KEY_QUERY_VALUE, &key);
+
+ if (errorcode != ERROR_SUCCESS) {
+ return std::wstring();
+ }
+
+ WCHAR temp[MAX_PATH];
+ DWORD bufferSize = MAX_PATH;
+
+ if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) {
+ return std::wstring(temp);
+ } else {
+ return std::wstring();
+ }
+}
+
+std::vector<std::wstring> OblivionInfo::getIniFileNames() const
+{
+ return boost::assign::list_of(L"oblivion.ini")(L"oblivionprefs.ini");
+}
+
+} // namespace MOShared
diff --git a/src/shared/oblivioninfo.h b/src/shared/oblivioninfo.h
new file mode 100644
index 00000000..6609921a
--- /dev/null
+++ b/src/shared/oblivioninfo.h
@@ -0,0 +1,54 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef OBLIVIONINFO_H
+#define OBLIVIONINFO_H
+
+#include "gameinfo.h"
+
+namespace MOShared {
+
+class OblivionInfo : public GameInfo
+{
+
+ friend class GameInfo;
+
+public:
+
+ virtual ~OblivionInfo() {}
+
+ static std::wstring getRegPathStatic();
+ virtual std::wstring getRegPath() const { return getRegPathStatic(); }
+
+ // file name of this games ini (no path)
+ virtual std::vector<std::wstring> getIniFileNames() const;
+
+ virtual std::wstring archiveListKey() const { return L"SArchiveList"; }
+
+private:
+
+ OblivionInfo(const std::wstring &gameDirectory);
+
+ static bool identifyGame(const std::wstring &searchPath);
+
+};
+
+} // namespace MOShared
+
+#endif // OBLIVIONINFO_H
diff --git a/src/shared/skyriminfo.cpp b/src/shared/skyriminfo.cpp
new file mode 100644
index 00000000..fbe13ae0
--- /dev/null
+++ b/src/shared/skyriminfo.cpp
@@ -0,0 +1,81 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "skyriminfo.h"
+
+#include "util.h"
+#include <tchar.h>
+#include <ShlObj.h>
+#include <sstream>
+#include "windows_error.h"
+#include "error_report.h"
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <Shlwapi.h>
+#include <boost/assign.hpp>
+
+namespace MOShared {
+
+
+SkyrimInfo::SkyrimInfo(const std::wstring &gameDirectory)
+ : GameInfo(gameDirectory)
+{
+ identifyMyGamesDirectory(L"skyrim");
+
+ wchar_t appDataPath[MAX_PATH];
+ if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_LOCAL_APPDATA, nullptr, SHGFP_TYPE_CURRENT, appDataPath))) {
+ m_AppData = appDataPath;
+ }
+}
+
+bool SkyrimInfo::identifyGame(const std::wstring &searchPath)
+{
+ return FileExists(searchPath, L"TESV.exe") &&
+ FileExists(searchPath, L"SkyrimLauncher.exe");
+}
+
+
+
+
+std::wstring SkyrimInfo::getRegPathStatic()
+{
+ HKEY key;
+ LONG errorcode = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Bethesda Softworks\\Skyrim",
+ 0, KEY_QUERY_VALUE, &key);
+
+ if (errorcode != ERROR_SUCCESS) {
+ return std::wstring();
+ }
+
+ WCHAR temp[MAX_PATH];
+ DWORD bufferSize = MAX_PATH;
+
+ if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) {
+ return std::wstring(temp);
+ } else {
+ return std::wstring();
+ }
+}
+
+std::vector<std::wstring> SkyrimInfo::getIniFileNames() const
+{
+ return boost::assign::list_of(L"skyrim.ini")(L"skyrimprefs.ini");
+}
+
+} // namespace MOShared
diff --git a/src/shared/skyriminfo.h b/src/shared/skyriminfo.h
new file mode 100644
index 00000000..a13b834e
--- /dev/null
+++ b/src/shared/skyriminfo.h
@@ -0,0 +1,58 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SKYRIMINFO_H
+#define SKYRIMINFO_H
+
+
+#include "gameinfo.h"
+
+namespace MOShared {
+
+
+class SkyrimInfo : public GameInfo
+{
+
+ friend class GameInfo;
+
+public:
+
+ virtual ~SkyrimInfo() {}
+
+ static std::wstring getRegPathStatic();
+ virtual std::wstring getRegPath() const { return getRegPathStatic(); }
+
+ // file name of this games ini (no path)
+ virtual std::vector<std::wstring> getIniFileNames() const;
+
+private:
+
+ SkyrimInfo(const std::wstring &gameDirectory);
+
+ static bool identifyGame(const std::wstring &searchPath);
+
+private:
+
+ std::wstring m_AppData;
+
+};
+
+} // namespace MOShared
+
+#endif // SKYRIMINFO_H
diff --git a/src/shared/util.cpp b/src/shared/util.cpp
index 3692aae1..5491a9e6 100644
--- a/src/shared/util.cpp
+++ b/src/shared/util.cpp
@@ -81,12 +81,16 @@ std::wstring ToWString(const std::string &source, bool utf8)
if (!utf8) {
codepage = AreFileApisANSI() ? GetACP() : GetOEMCP();
}
- int sizeRequired = ::MultiByteToWideChar(codepage, 0, source.c_str(), source.length(), nullptr, 0);
+ int sizeRequired
+ = ::MultiByteToWideChar(codepage, 0, source.c_str(),
+ static_cast<int>(source.length()), nullptr, 0);
if (sizeRequired == 0) {
throw windows_error("failed to convert string to wide character");
}
result.resize(sizeRequired, L'\0');
- ::MultiByteToWideChar(codepage, 0, source.c_str(), source.length(), &result[0], sizeRequired);
+ ::MultiByteToWideChar(codepage, 0, source.c_str(),
+ static_cast<int>(source.length()), &result[0],
+ sizeRequired);
}
return result;