summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2020-02-10 10:51:23 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2020-02-18 17:23:48 -0500
commit3a65665d36022c50637fc53d5c9c1ee022c5b3b5 (patch)
tree655dbb9d4c8d72b88b3fac94deceb350513aa780 /src
parent3db95eb4043b8da20e99dd7476bc82468a4609fb (diff)
wstring_view when possible
first implementation of NtQueryDirectoryFile
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/directoryrefresher.cpp5
-rw-r--r--src/envfs.cpp303
-rw-r--r--src/envfs.h17
-rw-r--r--src/main.cpp2
-rw-r--r--src/shared/directoryentry.cpp76
-rw-r--r--src/shared/directoryentry.h20
-rw-r--r--src/shared/util.cpp7
-rw-r--r--src/shared/util.h1
-rw-r--r--src/usvfsconnector.cpp2
10 files changed, 403 insertions, 33 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ad8f74c0..08421acb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -132,6 +132,7 @@ SET(organizer_SRCS
filerenamer.cpp
texteditor.cpp
env.cpp
+ envfs.cpp
envmetrics.cpp
envmodule.cpp
envsecurity.cpp
@@ -262,6 +263,7 @@ SET(organizer_HDRS
filerenamer.h
texteditor.h
env.h
+ envfs.h
envmetrics.h
envmodule.h
envsecurity.h
@@ -392,6 +394,7 @@ set(downloads
set(env
env
+ envfs
envmetrics
envmodule
envsecurity
diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp
index 87305599..b7dd51ba 100644
--- a/src/directoryrefresher.cpp
+++ b/src/directoryrefresher.cpp
@@ -159,7 +159,7 @@ void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure
, const QStringList &archives)
{
addModFilesToStructure(directoryStructure, modName, priority, directory, stealFiles);
-
+
if (Settings::instance().archiveParsing()) {
addModBSAToStructure(directoryStructure, modName, priority, directory, archives);
}
@@ -167,6 +167,9 @@ void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure
void DirectoryRefresher::refresh()
{
+ SetThisThreadName("DirectoryRefresher");
+ TimeThis tt("DirectoryRefresher::refresh()");
+
QMutexLocker locker(&m_RefreshLock);
delete m_DirectoryStructure;
diff --git a/src/envfs.cpp b/src/envfs.cpp
new file mode 100644
index 00000000..cb2764ae
--- /dev/null
+++ b/src/envfs.cpp
@@ -0,0 +1,303 @@
+#include "envfs.h"
+#include <utility.h>
+#include <log.h>
+
+using namespace MOBase;
+
+struct NtCloser
+{
+ using pointer = HANDLE;
+ void operator()(HANDLE h)
+ {
+ }
+};
+
+using NtHandle = std::unique_ptr<HANDLE, NtCloser>;
+
+typedef struct _UNICODE_STRING {
+ USHORT Length;
+ USHORT MaximumLength;
+ PWSTR Buffer;
+} UNICODE_STRING, *PUNICODE_STRING;
+typedef const UNICODE_STRING *PCUNICODE_STRING;
+
+typedef struct _OBJECT_ATTRIBUTES {
+ ULONG Length;
+ HANDLE RootDirectory;
+ PUNICODE_STRING ObjectName;
+ ULONG Attributes;
+ PVOID SecurityDescriptor;
+ PVOID SecurityQualityOfService;
+} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
+
+
+typedef struct _FILE_DIRECTORY_INFORMATION {
+ ULONG NextEntryOffset;
+ ULONG FileIndex;
+ LARGE_INTEGER CreationTime;
+ LARGE_INTEGER LastAccessTime;
+ LARGE_INTEGER LastWriteTime;
+ LARGE_INTEGER ChangeTime;
+ LARGE_INTEGER EndOfFile;
+ LARGE_INTEGER AllocationSize;
+ ULONG FileAttributes;
+ ULONG FileNameLength;
+ WCHAR FileName[1];
+} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
+
+
+#define FILE_SHARE_VALID_FLAGS 0x00000007
+
+// copied from ntstatus.h
+#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
+#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
+#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L)
+#define STATUS_NO_SUCH_FILE ((NTSTATUS)0xC000000FL)
+
+typedef struct _IO_STATUS_BLOCK IO_STATUS_BLOCK;
+
+typedef struct _IO_STATUS_BLOCK *PIO_STATUS_BLOCK;
+// typedef VOID (NTAPI *PIO_APC_ROUTINE )(__in PVOID ApcContext, __in
+// PIO_STATUS_BLOCK IoStatusBlock, __in ULONG Reserved);
+typedef VOID(NTAPI *PIO_APC_ROUTINE)(PVOID ApcContext,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ ULONG Reserved);
+
+
+typedef enum _FILE_INFORMATION_CLASS {
+ FileDirectoryInformation = 1
+} FILE_INFORMATION_CLASS;
+
+typedef NTSTATUS(WINAPI *NtQueryDirectoryFile_type)(
+ HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG,
+ FILE_INFORMATION_CLASS, BOOLEAN, PUNICODE_STRING, BOOLEAN);
+
+typedef NTSTATUS(WINAPI *NtOpenFile_type)(PHANDLE, ACCESS_MASK,
+ POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
+ ULONG, ULONG);
+
+NtOpenFile_type NtOpenFile = nullptr;
+NtQueryDirectoryFile_type NtQueryDirectoryFile = nullptr;
+
+
+#define FILE_DIRECTORY_FILE 0x00000001
+#define FILE_WRITE_THROUGH 0x00000002
+#define FILE_SEQUENTIAL_ONLY 0x00000004
+#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
+
+#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
+#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
+#define FILE_NON_DIRECTORY_FILE 0x00000040
+#define FILE_CREATE_TREE_CONNECTION 0x00000080
+
+#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
+#define FILE_NO_EA_KNOWLEDGE 0x00000200
+#define FILE_OPEN_REMOTE_INSTANCE 0x00000400
+#define FILE_RANDOM_ACCESS 0x00000800
+
+#define FILE_DELETE_ON_CLOSE 0x00001000
+#define FILE_OPEN_BY_FILE_ID 0x00002000
+#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
+#define FILE_NO_COMPRESSION 0x00008000
+
+#if (_WIN32_WINNT >= _WIN32_WINNT_WIN7)
+#define FILE_OPEN_REQUIRING_OPLOCK 0x00010000
+#endif
+
+#define FILE_RESERVE_OPFILTER 0x00100000
+#define FILE_OPEN_REPARSE_POINT 0x00200000
+#define FILE_OPEN_NO_RECALL 0x00400000
+#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
+
+#define FILE_VALID_OPTION_FLAGS 0x00ffffff
+#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032
+#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032
+#define FILE_VALID_SET_FLAGS 0x00000036
+
+typedef struct _IO_STATUS_BLOCK {
+#pragma warning(push)
+#pragma warning(disable: 4201) // we'll always use the Microsoft compiler
+ union {
+ NTSTATUS Status;
+ PVOID Pointer;
+ } DUMMYUNIONNAME;
+#pragma warning(pop)
+
+ ULONG_PTR Information;
+} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
+
+
+
+namespace env
+{
+
+std::wstring_view toStringView(const UNICODE_STRING* s)
+{
+ if (s && s->Buffer) {
+ return {s->Buffer, (s->Length / sizeof(wchar_t))};
+ } else {
+ return {};
+ }
+}
+
+std::wstring_view toStringView(POBJECT_ATTRIBUTES poa)
+{
+ if (poa->ObjectName) {
+ return toStringView(poa->ObjectName);
+ }
+
+ return {};
+}
+
+QString toString(POBJECT_ATTRIBUTES poa)
+{
+ const auto sv = toStringView(poa);
+ return QString::fromWCharArray(sv.data(), static_cast<int>(sv.size()));
+}
+
+
+constexpr std::size_t AllocSize = 1024 * 1024;
+std::vector<std::unique_ptr<unsigned char[]>> g_buffers;
+
+
+
+void forEachEntryImpl(
+ void* cx, POBJECT_ATTRIBUTES poa, std::size_t depth,
+ DirStartF* dirStartF, DirEndF* dirEndF, FileF* fileF)
+{
+ IO_STATUS_BLOCK iosb;
+ UNICODE_STRING ObjectName;
+ OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };
+ NTSTATUS status;
+
+ //log::debug("{}{}", std::wstring(depth * 2, L' '), toString(poa));
+
+ status = NtOpenFile(
+ &oa.RootDirectory, FILE_GENERIC_READ, poa, &iosb, FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT|FILE_OPEN_REPARSE_POINT|FILE_OPEN_FOR_BACKUP_INTENT);
+
+ if (status < 0) {
+ log::error(
+ "NtOpenFile() failed for '{}', {}",
+ toString(poa), formatSystemMessage(status));
+
+ return;
+ }
+
+ NtHandle rootDirectoryHandle(oa.RootDirectory);
+
+ //std::unique_ptr<unsigned char> buffer(new unsigned char[AllocSize]);
+
+ unsigned char* buffer;
+
+ if (depth >= g_buffers.size()) {
+ g_buffers.emplace_back(std::make_unique<unsigned char[]>(AllocSize));
+ buffer = g_buffers.back().get();
+ } else {
+ buffer = g_buffers[depth].get();
+ }
+
+ union
+ {
+ PVOID pv;
+ PBYTE pb;
+ PFILE_DIRECTORY_INFORMATION DirInfo;
+ };
+
+ for (;;) {
+ status = NtQueryDirectoryFile(
+ oa.RootDirectory, NULL, NULL, NULL, &iosb,
+ buffer, AllocSize, FileDirectoryInformation, FALSE, NULL, FALSE);
+
+ if (status == STATUS_NO_MORE_FILES) {
+ break;
+ } else if (status < 0) {
+ log::error(
+ "NtQueryDirectoryFile() failed for '{}', {}",
+ toString(poa), formatSystemMessage(status));
+ break;
+ }
+
+ ULONG NextEntryOffset = 0;
+
+ pv = buffer;
+
+ auto isDotDir = [](auto* o) {
+ if (o->Length == 2 && o->Buffer[0] == '.') {
+ return true;
+ }
+
+ if (o->Length == 4 && o->Buffer[0] == '.' && o->Buffer[1] == '.') {
+ return true;
+ }
+
+ return false;
+ };
+
+ std::size_t count = 0;
+
+ for (;;) {
+ ++count;
+ pb += NextEntryOffset;
+
+ ObjectName.Buffer = DirInfo->FileName;
+ ObjectName.Length = (USHORT)DirInfo->FileNameLength;
+
+ if (!isDotDir(&ObjectName)) {
+ ObjectName.MaximumLength = ObjectName.Length;
+
+ if (DirInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ dirStartF(cx, toStringView(&oa));
+ forEachEntryImpl(cx, &oa, depth+1, dirStartF, dirEndF, fileF);
+ dirEndF(cx, toStringView(&oa));
+ } else {
+ //log::debug("{}{}", std::wstring((depth + 1) * 2, L' '), toString(&oa));
+ FILETIME ft;
+ ft.dwLowDateTime = DirInfo->LastWriteTime.LowPart;
+ ft.dwHighDateTime = DirInfo->LastWriteTime.HighPart;
+ fileF(cx, toStringView(&oa), ft);
+ }
+ }
+
+ NextEntryOffset = DirInfo->NextEntryOffset;
+
+ if (NextEntryOffset == 0) {
+ break;
+ }
+ }
+
+ //log::debug("{}{} processed {} files", std::wstring(depth * 2, L' '), toString(poa), count);
+
+ if (AllocSize - iosb.Information > (ULONG)FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, FileName[256])) {
+ // NO_MORE_FILES
+ break;
+ }
+ }
+}
+
+void forEachEntry(
+ const std::wstring& path, void* cx,
+ DirStartF* dirStartF, DirEndF* dirEndF, FileF* fileF)
+{
+ if (!NtOpenFile) {
+ HMODULE m = ::LoadLibraryW(L"ntdll.dll");
+ NtOpenFile = (NtOpenFile_type)::GetProcAddress(m, "NtOpenFile");
+ NtQueryDirectoryFile = (NtQueryDirectoryFile_type)::GetProcAddress(m, "NtQueryDirectoryFile");
+ ::FreeLibrary(m);
+ }
+
+ const std::wstring ntpath = std::wstring(L"\\??\\") + path;
+
+ UNICODE_STRING ObjectName = {};
+ ObjectName.Buffer = const_cast<wchar_t*>(ntpath.c_str());
+ ObjectName.Length = (USHORT)ntpath.size() * sizeof(wchar_t);
+ ObjectName.MaximumLength = ObjectName.Length;
+
+ OBJECT_ATTRIBUTES oa = {};
+ oa.Length = sizeof(oa);
+ oa.ObjectName = &ObjectName;
+
+ forEachEntryImpl(cx, &oa, 0, dirStartF, dirEndF, fileF);
+}
+
+} // namespace
diff --git a/src/envfs.h b/src/envfs.h
new file mode 100644
index 00000000..aeaa6796
--- /dev/null
+++ b/src/envfs.h
@@ -0,0 +1,17 @@
+#ifndef ENV_ENVFS_H
+#define ENV_ENVFS_H
+
+namespace env
+{
+
+using DirStartF = void (void*, std::wstring_view);
+using DirEndF = void (void*, std::wstring_view);
+using FileF = void (void*, std::wstring_view, FILETIME);
+
+void forEachEntry(
+ const std::wstring& path, void* cx,
+ DirStartF* dirStartF, DirEndF* dirEndF, FileF* fileF);
+
+} // namespace
+
+#endif // ENV_ENVFS_H
diff --git a/src/main.cpp b/src/main.cpp
index 4b291e75..6e2220ae 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -885,6 +885,8 @@ int main(int argc, char *argv[])
MOApplication application(argc, argv);
QStringList arguments = application.arguments();
+ SetThisThreadName("main");
+
setupPath();
bool forcePrimary = false;
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp
index 6e44cc91..28201a11 100644
--- a/src/shared/directoryentry.cpp
+++ b/src/shared/directoryentry.cpp
@@ -20,6 +20,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "directoryentry.h"
#include "windows_error.h"
#include "error_report.h"
+#include "envfs.h"
+#include <utility.h>
#include <log.h>
#include <bsatk.h>
#include <boost/bind.hpp>
@@ -172,15 +174,15 @@ FileEntry::FileEntry() :
{
}
-FileEntry::FileEntry(Index index, const std::wstring &name, DirectoryEntry *parent) :
- m_Index(index), m_Name(name), m_Origin(-1), m_Archive(L"", -1), m_Parent(parent),
+FileEntry::FileEntry(Index index, std::wstring_view name, DirectoryEntry *parent) :
+ m_Index(index), m_Name(name.begin(), name.end()), m_Origin(-1), m_Archive(L"", -1), m_Parent(parent),
m_FileSize(NoFileSize), m_CompressedFileSize(NoFileSize),
m_LastAccessed(time(nullptr))
{
}
void FileEntry::addOrigin(
- int origin, FILETIME fileTime, const std::wstring &archive, int order)
+ int origin, FILETIME fileTime, std::wstring_view archive, int order)
{
m_LastAccessed = time(nullptr);
if (m_Parent != nullptr) {
@@ -192,7 +194,7 @@ void FileEntry::addOrigin(
// alternatives
m_Origin = origin;
m_FileTime = fileTime;
- m_Archive = std::pair<std::wstring, int>(archive, order);
+ m_Archive = std::pair<std::wstring, int>(std::wstring(archive.begin(), archive.end()), order);
}
else if (
(m_Parent != nullptr) && (
@@ -213,7 +215,7 @@ void FileEntry::addOrigin(
m_Origin = origin;
m_FileTime = fileTime;
- m_Archive = std::pair<std::wstring, int>(archive, order);
+ m_Archive = std::pair<std::wstring, int>(std::wstring(archive.begin(), archive.end()), order);
}
else {
// This mod is just an alternative
@@ -232,14 +234,14 @@ void FileEntry::addOrigin(
if ((m_Parent != nullptr) &&
(m_Parent->getOriginByID(iter->first).getPriority() < m_Parent->getOriginByID(origin).getPriority())) {
- m_Alternatives.insert(iter, {origin, {archive, order}});
+ m_Alternatives.insert(iter, {origin, {std::wstring(archive.begin(), archive.end()), order}});
found = true;
break;
}
}
if (!found) {
- m_Alternatives.push_back({origin, {archive, order}});
+ m_Alternatives.push_back({origin, {std::wstring(archive.begin(), archive.end()), order}});
}
}
}
@@ -509,12 +511,12 @@ bool FileRegister::indexValid(FileEntry::Index index) const
return (m_Files.find(index) != m_Files.end());
}
-FileEntry::Ptr FileRegister::createFile(const std::wstring &name, DirectoryEntry *parent)
+FileEntry::Ptr FileRegister::createFile(std::wstring_view name, DirectoryEntry *parent)
{
FileEntry::Index index = generateIndex();
auto r = m_Files.insert_or_assign(
- index, FileEntry::Ptr(new FileEntry(index, name, parent)));
+ index, FileEntry::Ptr(new FileEntry(index, std::move(name), parent)));
return r.first->second;
}
@@ -637,20 +639,20 @@ void FileRegister::unregisterFile(FileEntry::Ptr file)
DirectoryEntry::DirectoryEntry(
- const std::wstring &name, DirectoryEntry *parent, int originID) :
+ std::wstring name, DirectoryEntry *parent, int originID) :
m_OriginConnection(new OriginConnection),
- m_Name(name), m_Parent(parent), m_Populated(false), m_TopLevel(true)
+ m_Name(std::move(name)), m_Parent(parent), m_Populated(false), m_TopLevel(true)
{
m_FileRegister.reset(new FileRegister(m_OriginConnection));
m_Origins.insert(originID);
}
DirectoryEntry::DirectoryEntry(
- const std::wstring &name, DirectoryEntry *parent, int originID,
+ std::wstring name, DirectoryEntry *parent, int originID,
boost::shared_ptr<FileRegister> fileRegister,
boost::shared_ptr<OriginConnection> originConnection) :
m_FileRegister(fileRegister), m_OriginConnection(originConnection),
- m_Name(name), m_Parent(parent), m_Populated(false), m_TopLevel(false)
+ m_Name(std::move(name)), m_Parent(parent), m_Populated(false), m_TopLevel(false)
{
m_Origins.insert(originID);
}
@@ -1025,8 +1027,8 @@ void DirectoryEntry::removeFiles(const std::set<FileEntry::Index> &indices)
}
FileEntry::Ptr DirectoryEntry::insert(
- const std::wstring &fileName, FilesOrigin &origin, FILETIME fileTime,
- const std::wstring &archive, int order)
+ std::wstring_view fileName, FilesOrigin &origin, FILETIME fileTime,
+ std::wstring_view archive, int order)
{
std::wstring fileNameLower = ToLowerCopy(fileName);
@@ -1050,6 +1052,35 @@ FileEntry::Ptr DirectoryEntry::insert(
void DirectoryEntry::addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOffset)
{
+ struct Context
+ {
+ FilesOrigin& origin;
+ std::stack<DirectoryEntry*> current;
+ };
+
+ Context cx = {origin};
+ cx.current.push(this);
+
+ env::forEachEntry(buffer, &cx,
+ [](void* pcx, std::wstring_view path) {
+ Context* cx = (Context*)pcx;
+ cx->current.push(cx->current.top()->getSubDirectory(path, true, cx->origin.getID()));
+ },
+
+ [](void* pcx, std::wstring_view path) {
+ Context* cx = (Context*)pcx;
+ auto* current= cx->current.top();
+ std::sort(current->m_SubDirectories.begin(), current->m_SubDirectories.end(), &DirCompareByName);
+ cx->current.pop();
+ },
+
+ [](void* pcx, std::wstring_view path, FILETIME ft) {
+ Context* cx = (Context*)pcx;
+ cx->current.top()->insert(path, cx->origin, ft, L"", -1);
+ }
+ );
+
+ /*
WIN32_FIND_DATAW findData;
_snwprintf_s(buffer + bufferOffset, MAXPATH_UNICODE - bufferOffset, _TRUNCATE, L"\\*");
@@ -1087,7 +1118,7 @@ void DirectoryEntry::addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOf
}
std::sort(m_SubDirectories.begin(), m_SubDirectories.end(), &DirCompareByName);
- ::FindClose(searchHandle);
+ ::FindClose(searchHandle);*/
}
void DirectoryEntry::addFiles(
@@ -1119,17 +1150,18 @@ void DirectoryEntry::addFiles(
}
DirectoryEntry *DirectoryEntry::getSubDirectory(
- const std::wstring &name, bool create, int originID)
+ std::wstring_view name, bool create, int originID)
{
- for (DirectoryEntry *entry : m_SubDirectories) {
- if (CaseInsensitiveEqual(entry->getName(), name)) {
- return entry;
- }
+ auto itor = m_SubDirectoriesLookup.find(ToLowerCopy(name));
+
+ if (itor != m_SubDirectoriesLookup.end()) {
+ return itor->second;
}
if (create) {
auto* entry = new DirectoryEntry(
- name, this, originID, m_FileRegister, m_OriginConnection);
+ std::wstring(name.begin(), name.end()), this, originID,
+ m_FileRegister, m_OriginConnection);
addDirectoryToList(entry);
diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h
index e26011d7..1a8a4247 100644
--- a/src/shared/directoryentry.h
+++ b/src/shared/directoryentry.h
@@ -78,7 +78,7 @@ public:
AlternativesVector;
FileEntry();
- FileEntry(Index index, const std::wstring &name, DirectoryEntry *parent);
+ FileEntry(Index index, std::wstring_view name, DirectoryEntry *parent);
Index getIndex() const
{
@@ -91,7 +91,7 @@ public:
}
void addOrigin(
- int origin, FILETIME fileTime, const std::wstring &archive, int order);
+ int origin, FILETIME fileTime, std::wstring_view archive, int order);
// remove the specified origin from the list of origins that contain this
// file. if no origin is left, the file is effectively deleted and true is
@@ -261,7 +261,7 @@ public:
bool indexValid(FileEntry::Index index) const;
- FileEntry::Ptr createFile(const std::wstring &name, DirectoryEntry *parent);
+ FileEntry::Ptr createFile(std::wstring_view name, DirectoryEntry *parent);
FileEntry::Ptr getFile(FileEntry::Index index) const;
size_t size() const
@@ -312,10 +312,10 @@ public:
using FileKey = DirectoryEntryFileKey;
DirectoryEntry(
- const std::wstring &name, DirectoryEntry *parent, int originID);
+ std::wstring name, DirectoryEntry *parent, int originID);
DirectoryEntry(
- const std::wstring &name, DirectoryEntry *parent, int originID,
+ std::wstring name, DirectoryEntry *parent, int originID,
boost::shared_ptr<FileRegister> fileRegister,
boost::shared_ptr<OriginConnection> originConnection);
@@ -501,8 +501,8 @@ private:
DirectoryEntry(const DirectoryEntry &reference);
FileEntry::Ptr insert(
- const std::wstring &fileName, FilesOrigin &origin, FILETIME fileTime,
- const std::wstring &archive, int order);
+ std::wstring_view fileName, FilesOrigin &origin, FILETIME fileTime,
+ std::wstring_view archive, int order);
void addFiles(
FilesOrigin &origin, wchar_t *buffer, int bufferOffset);
@@ -511,10 +511,10 @@ private:
FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime,
const std::wstring &archiveName, int order);
- DirectoryEntry *getSubDirectory(
- const std::wstring &name, bool create, int originID = -1);
+ DirectoryEntry* getSubDirectory(
+ std::wstring_view name, bool create, int originID = -1);
- DirectoryEntry *getSubDirectoryRecursive(
+ DirectoryEntry* getSubDirectoryRecursive(
const std::wstring &path, bool create, int originID = -1);
void removeDirRecursive();
diff --git a/src/shared/util.cpp b/src/shared/util.cpp
index aa4ad4b3..74e386a3 100644
--- a/src/shared/util.cpp
+++ b/src/shared/util.cpp
@@ -130,6 +130,13 @@ std::wstring ToLowerCopy(const std::wstring& text)
return result;
}
+std::wstring ToLowerCopy(std::wstring_view text)
+{
+ std::wstring result(text.begin(), text.end());
+ ToLowerInPlace(result);
+ return result;
+}
+
bool CaseInsenstiveComparePred(wchar_t lhs, wchar_t rhs)
{
return std::tolower(lhs, loc) == std::tolower(rhs, loc);
diff --git a/src/shared/util.h b/src/shared/util.h
index 05522c2d..dc6e72ad 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -41,6 +41,7 @@ std::string ToLowerCopy(const std::string& text);
std::wstring& ToLowerInPlace(std::wstring& text);
std::wstring ToLowerCopy(const std::wstring& text);
+std::wstring ToLowerCopy(std::wstring_view text);
bool CaseInsensitiveEqual(const std::wstring &lhs, const std::wstring &rhs);
diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp
index 59880754..ed6e31ce 100644
--- a/src/usvfsconnector.cpp
+++ b/src/usvfsconnector.cpp
@@ -70,6 +70,8 @@ LogWorker::~LogWorker()
void LogWorker::process()
{
+ MOShared::SetThisThreadName("LogWorker");
+
int noLogCycles = 0;
while (!m_QuitRequested) {
if (GetLogMessages(&m_Buffer[0], m_Buffer.size(), false)) {