diff options
| author | Brian Munro <brian.alexander.munro@gmail.com> | 2018-03-05 11:35:58 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-03-05 11:35:58 +0200 |
| commit | c7e1d9738f06c6c6e7c9b41cdd8d35062d7c06b6 (patch) | |
| tree | c9c92380fcc82a64df8956face14e22bc3d2b4f7 /src/shared | |
| parent | 7dfe0c9a8feae35ba7554493eea4fdb4e33a64d3 (diff) | |
| parent | a540a542a47fe75d0d0e4594158422aef4340b3a (diff) | |
Merge pull request #252 from LePresidente/new_vfs_library
Update master to latest stable code.
Diffstat (limited to 'src/shared')
| -rw-r--r-- | src/shared/appconfig.inc | 4 | ||||
| -rw-r--r-- | src/shared/directoryentry.cpp | 83 | ||||
| -rw-r--r-- | src/shared/directoryentry.h | 15 | ||||
| -rw-r--r-- | src/shared/inject.cpp | 147 | ||||
| -rw-r--r-- | src/shared/inject.h | 31 | ||||
| -rw-r--r-- | src/shared/leaktrace.cpp | 5 | ||||
| -rw-r--r-- | src/shared/util.cpp | 8 |
7 files changed, 63 insertions, 230 deletions
diff --git a/src/shared/appconfig.inc b/src/shared/appconfig.inc index e2dbfe20..e572a32b 100644 --- a/src/shared/appconfig.inc +++ b/src/shared/appconfig.inc @@ -8,13 +8,15 @@ APPPARAM(std::wstring, stylesheetsPath, L"stylesheets") APPPARAM(std::wstring, cachePath, L"webcache")
APPPARAM(std::wstring, tutorialsPath, L"tutorials")
APPPARAM(std::wstring, logPath, L"logs")
+APPPARAM(std::wstring, dumpsDir, L"crashDumps")
APPPARAM(std::wstring, profileTweakIni, L"profile_tweaks.ini")
APPPARAM(std::wstring, logFileName, L"ModOrganizer.log")
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(std::wstring, vfs32DLLName, L"usvfs_x86.dll")
+APPPARAM(std::wstring, vfs64DLLName, L"usvfs_x64.dll")
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..cebf270e 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>
@@ -214,9 +213,9 @@ void FilesOrigin::setName(const std::wstring &name) std::vector<FileEntry::Ptr> FilesOrigin::getFiles() const
{
std::vector<FileEntry::Ptr> result;
- for (FileEntry::Index fileIdx : m_Files) {
- result.push_back(m_FileRegister.lock()->getFile(fileIdx));
- }
+ for (FileEntry::Index fileIdx : m_Files)
+ if (FileEntry::Ptr p = m_FileRegister.lock()->getFile(fileIdx))
+ result.push_back(p);
return result;
}
@@ -237,9 +236,10 @@ void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &arc m_FileTime = fileTime;
m_Archive = archive;
} else if ((m_Parent != nullptr)
- && (m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority())) {
- if (std::find(m_Alternatives.begin(), m_Alternatives.end(), m_Origin) == m_Alternatives.end()) {
- m_Alternatives.push_back(m_Origin);
+ && (m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority())
+ && (archive.size() == 0 || m_Archive.size() > 0 )) {
+ if (std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair<int, std::wstring> &i) -> bool { return i.first == m_Origin; }) == m_Alternatives.end()) {
+ m_Alternatives.push_back(std::pair<int, std::wstring>(m_Origin, m_Archive));
}
m_Origin = origin;
m_FileTime = fileTime;
@@ -250,20 +250,20 @@ void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &arc // already an origin
return;
}
- for (std::vector<int>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) {
- if (*iter == origin) {
+ for (std::vector<std::pair<int, std::wstring>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) {
+ if (iter->first == origin) {
// already an origin
return;
}
if ((m_Parent != nullptr)
- && (m_Parent->getOriginByID(*iter).getPriority() < m_Parent->getOriginByID(origin).getPriority())) {
- m_Alternatives.insert(iter, origin);
+ && (m_Parent->getOriginByID(iter->first).getPriority() < m_Parent->getOriginByID(origin).getPriority())) {
+ m_Alternatives.insert(iter, std::pair<int, std::wstring>(origin, archive));
found = true;
break;
}
}
if (!found) {
- m_Alternatives.push_back(origin);
+ m_Alternatives.push_back(std::pair<int, std::wstring>(origin, archive));
}
}
}
@@ -273,14 +273,14 @@ bool FileEntry::removeOrigin(int origin) if (m_Origin == origin) {
if (!m_Alternatives.empty()) {
// find alternative with the highest priority
- std::vector<int>::iterator currentIter = m_Alternatives.begin();
- for (std::vector<int>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) {
- if ((m_Parent->getOriginByID(*iter).getPriority() > m_Parent->getOriginByID(*currentIter).getPriority()) &&
- (*iter != origin)) {
+ std::vector<std::pair<int, std::wstring>>::iterator currentIter = m_Alternatives.begin();
+ for (std::vector<std::pair<int, std::wstring>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) {
+ if ((m_Parent->getOriginByID(iter->first).getPriority() > m_Parent->getOriginByID(currentIter->first).getPriority()) &&
+ (iter->first != origin)) {
currentIter = iter;
}
}
- int currentID = *currentIter;
+ int currentID = currentIter->first;
m_Alternatives.erase(currentIter);
m_Origin = currentID;
@@ -304,23 +304,13 @@ bool FileEntry::removeOrigin(int origin) return true;
}
} else {
- std::vector<int>::iterator newEnd = std::remove(m_Alternatives.begin(), m_Alternatives.end(), origin);
- m_Alternatives.erase(newEnd, m_Alternatives.end());
+ std::vector<std::pair<int, std::wstring>>::iterator newEnd = std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair<int, std::wstring> &i) -> bool { return i.first == origin; });
+ if (newEnd != m_Alternatives.end())
+ m_Alternatives.erase(newEnd, m_Alternatives.end());
}
return false;
}
-
-// sorted by priority descending
-static bool ByOriginPriority(DirectoryEntry *entry, int LHS, int RHS)
-{
- int l = entry->getOriginByID(LHS).getPriority(); if (l < 0) l = INT_MAX;
- int r = entry->getOriginByID(RHS).getPriority(); if (r < 0) r = INT_MAX;
-
- return l < r;
-}
-
-
FileEntry::FileEntry()
: m_Index(UINT_MAX), m_Name(), m_Origin(-1), m_Parent(nullptr), m_LastAccessed(time(nullptr))
{
@@ -340,10 +330,23 @@ FileEntry::~FileEntry() void FileEntry::sortOrigins()
{
- m_Alternatives.push_back(m_Origin);
- std::sort(m_Alternatives.begin(), m_Alternatives.end(), boost::bind(ByOriginPriority, m_Parent, _1, _2));
- m_Origin = m_Alternatives[m_Alternatives.size() - 1];
- m_Alternatives.pop_back();
+ m_Alternatives.push_back(std::pair<int, std::wstring>(m_Origin, m_Archive));
+ std::sort(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair<int, std::wstring> &LHS, const std::pair<int, std::wstring> &RHS) -> bool {
+ if ((!LHS.second.size() && !RHS.second.size()) || (LHS.second.size() && RHS.second.size())) {
+ int l = m_Parent->getOriginByID(LHS.first).getPriority(); if (l < 0) l = INT_MAX;
+ int r = m_Parent->getOriginByID(RHS.first).getPriority(); if (r < 0) r = INT_MAX;
+
+ return l < r;
+ }
+
+ if (RHS.second.size()) return false;
+ return true;
+ });
+ if (!m_Alternatives.empty()) {
+ m_Origin = m_Alternatives.back().first;
+ m_Archive = m_Alternatives.back().second;
+ m_Alternatives.pop_back();
+ }
}
@@ -704,7 +707,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 +721,7 @@ int DirectoryEntry::getOrigin(const std::wstring &path, bool &archive) return -1;
}
}
-}
+}*/
std::vector<FileEntry::Ptr> DirectoryEntry::getFiles() const
{
@@ -887,9 +890,9 @@ void FileRegister::unregisterFile(FileEntry::Ptr file) // unregister from origin
int originID = file->getOrigin(ignore);
m_OriginConnection->getByID(originID).removeFile(file->getIndex());
- const std::vector<int> &alternatives = file->getAlternatives();
+ const std::vector<std::pair<int, std::wstring>> &alternatives = file->getAlternatives();
for (auto iter = alternatives.begin(); iter != alternatives.end(); ++iter) {
- m_OriginConnection->getByID(*iter).removeFile(file->getIndex());
+ m_OriginConnection->getByID(iter->first).removeFile(file->getIndex());
}
// unregister from directory
@@ -950,12 +953,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..8dbedaf4 100644 --- a/src/shared/directoryentry.h +++ b/src/shared/directoryentry.h @@ -72,7 +72,7 @@ public: // gets the list of alternative origins (origins with lower priority than the primary one).
// if sortOrigins has been called, it is sorted by priority (ascending)
- const std::vector<int> &getAlternatives() const { return m_Alternatives; }
+ const std::vector<std::pair<int, std::wstring>> &getAlternatives() const { return m_Alternatives; }
const std::wstring &getName() const { return m_Name; }
int getOrigin() const { return m_Origin; }
@@ -96,9 +96,9 @@ private: Index m_Index;
std::wstring m_Name;
- int m_Origin;
+ int m_Origin = -1;
std::wstring m_Archive;
- std::vector<int> m_Alternatives;
+ std::vector<std::pair<int, std::wstring>> m_Alternatives;
DirectoryEntry *m_Parent;
mutable FILETIME m_FileTime;
@@ -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/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(¶meters, '\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, ¶meters, 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/inject.h b/src/shared/inject.h deleted file mode 100644 index 7f4f2962..00000000 --- a/src/shared/inject.h +++ /dev/null @@ -1,31 +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/>.
-*/
-
-#pragma once
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#include <string>
-
-namespace MOShared {
-
-void injectDLL(HANDLE processHandle, HANDLE threadHandle, const std::string &dllname, const std::wstring &profileName, int logLevel);
-
-}
diff --git a/src/shared/leaktrace.cpp b/src/shared/leaktrace.cpp index 73786c6b..1ff1fa9d 100644 --- a/src/shared/leaktrace.cpp +++ b/src/shared/leaktrace.cpp @@ -33,8 +33,9 @@ static struct __TraceData { "%d objects not freed, allocated at:\n%s",
iter->second.size(), iter->first.toString().c_str());
printf("Addresses: ");
- for (int i = 0; i < (std::min<int>)(5, iter->second.size()); ++i) {
- printf("%p, ", reinterpret_cast<void*>(iter->second[i]));
+ for (int i = 0;
+ i < (std::min<int>)(5, static_cast<int>(iter->second.size())); ++i) {
+ printf("%p, ", reinterpret_cast<void *>(iter->second[i]));
}
printf("\n");
}
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;
|
