diff --git a/dllmain.cpp b/dllmain.cpp index 6fdacd9..e3f2333 100644 --- a/dllmain.cpp +++ b/dllmain.cpp @@ -17,6 +17,9 @@ static BOOL(WINAPI *TrueCloseHandle)(HANDLE hObject) = CloseHandle; static DWORD(WINAPI *TrueGetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh) = GetFileSize; static decltype(GetFileSizeEx) *TrueGetFileSizeEx = GetFileSizeEx; static DWORD(WINAPI *TrueSetFilePointer)(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) = SetFilePointer; +static decltype(GetFileType) *TrueGetFileType = GetFileType; +static decltype(GetFileAttributesW) *TrueGetFileAttributesW = GetFileAttributesW; +static decltype(GetFileAttributesExW) *TrueGetFileAttributesExW = GetFileAttributesExW; static Config config; static std::wstring defaultFont; @@ -144,6 +147,27 @@ DWORD WINAPI HookedSetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDi return TrueSetFilePointer(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod); } +DWORD WINAPI HookedGetFileType(HANDLE hFile) { + if (vfs.ContainsHandle(hFile)) { + return FILE_TYPE_DISK; + } + return TrueGetFileType(hFile); +} + +DWORD WINAPI HookedGetFileAttributesW(LPCWSTR lpFileName) { + if (vfs.ContainsFile(lpFileName)) { + return FILE_ATTRIBUTE_READONLY; + } + return TrueGetFileAttributesW(lpFileName); +} + +BOOL WINAPI HookedGetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation) { + if (vfs.ContainsFile(lpFileName)) { + return vfs.GetFileAttributesExW(lpFileName, fInfoLevelId, lpFileInformation); + } + return TrueGetFileAttributesExW(lpFileName, fInfoLevelId, lpFileInformation); +} + extern "C" __declspec(dllexport) void Attach() { config.Load("config.txt"); if (!wchar_util::str_to_wstr(defaultFont, config.configs["defaultFont"], CP_UTF8)) { @@ -169,6 +193,9 @@ extern "C" __declspec(dllexport) void Attach() { DetourAttach(&TrueGetFileSize, HookedGetFileSize); DetourAttach(&TrueGetFileSizeEx, HookedGetFileSizeEx); DetourAttach(&TrueSetFilePointer, HookedSetFilePointer); + DetourAttach(&TrueGetFileType, HookedGetFileType); + DetourAttach(&TrueGetFileAttributesW, HookedGetFileAttributesW); + DetourAttach(&TrueGetFileAttributesExW, HookedGetFileAttributesExW); DetourTransactionCommit(); std::string stringReplaceFile = config.configs["stringReplaceFile"]; if (!stringReplaceFile.empty()) { @@ -195,6 +222,9 @@ extern "C" __declspec(dllexport) void Detach() { DetourDetach(&TrueGetFileSize, HookedGetFileSize); DetourDetach(&TrueGetFileSizeEx, HookedGetFileSizeEx); DetourDetach(&TrueSetFilePointer, HookedSetFilePointer); + DetourDetach(&TrueGetFileType, HookedGetFileType); + DetourDetach(&TrueGetFileAttributesW, HookedGetFileAttributesW); + DetourDetach(&TrueGetFileAttributesExW, HookedGetFileAttributesExW); DetourTransactionCommit(); } diff --git a/vfs.cpp b/vfs.cpp index bdb0411..12780bd 100644 --- a/vfs.cpp +++ b/vfs.cpp @@ -3,6 +3,7 @@ #include "str_util.h" #include "fileop.h" #include "shlwapi.h" +#include "time_util.h" VFS::VFS() { WCHAR exePath[MAX_PATH]; @@ -42,7 +43,7 @@ bool VFS::AddArchive(std::string path) { } std::string name = st.name; name = str_util::str_replace(name, "/", "\\"); - files[name] = st.size; + files[name] = st; } return true; } @@ -74,7 +75,7 @@ bool VFS::AddArchiveFromResource(HMODULE hModule, int resourceID) { } std::string name = st.name; name = str_util::str_replace(name, "/", "\\"); - files[name] = st.size; + files[name] = st; } return true; } @@ -193,7 +194,7 @@ DWORD VFS::GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) { } auto data = *f; auto name = data.second; - auto size = files[name]; + auto size = files[name].size; if (lpFileSizeHigh) { *lpFileSizeHigh = size >> 32; } @@ -208,7 +209,7 @@ BOOL VFS::GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize) { } auto data = *f; auto name = data.second; - auto size = files[name]; + auto size = files[name].size; lpFileSize->LowPart = size & 0xFFFFFFFF; lpFileSize->HighPart = size >> 32; return TRUE; @@ -239,3 +240,37 @@ DWORD VFS::SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceTo std::string VFS::GetBasePath() { return base_path; } + +BOOL VFS::GetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation) { + std::string path; + if (!wchar_util::wstr_to_str(path, lpFileName, CP_UTF8)) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + path = str_util::str_replace(path, "/", "\\"); + if (fileop::isabs(path)) { + path = fileop::relpath(path, base_path); + } + auto c = files.find(path); + if (c == files.end()) { + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } + auto st = (*c).second; + if (fInfoLevelId == GetFileExInfoStandard) { + if (!lpFileInformation) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + WIN32_FILE_ATTRIBUTE_DATA data; + data.dwFileAttributes = FILE_ATTRIBUTE_READONLY; + time_util::time_t_to_file_time(st.mtime, &data.ftLastWriteTime); + data.ftCreationTime = data.ftLastWriteTime; + data.ftLastAccessTime = data.ftLastWriteTime; + data.nFileSizeHigh = st.size >> 32; + data.nFileSizeLow = st.size & 0xFFFFFFFF; + memcpy(lpFileInformation, &data, sizeof(data)); + return TRUE; + } + return FALSE; +} diff --git a/vfs.hpp b/vfs.hpp index 43d588d..f6ff2c2 100644 --- a/vfs.hpp +++ b/vfs.hpp @@ -40,10 +40,11 @@ class VFS { HANDLE CreateFileW(std::wstring path); bool ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead); void CloseHandle(HANDLE hFile); + BOOL GetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation); DWORD GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh); BOOL GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize); DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod); - std::unordered_map files; + std::unordered_map files; std::string GetBasePath(); private: std::string base_path;