diff options
| author | Léo Lam <leo@leolam.fr> | 2019-11-09 21:10:16 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-09 21:10:16 +0100 |
| commit | f4e12f85bce7f0ad3c3fcc5d19d7db495600a41b (patch) | |
| tree | 5960897f371699d1b107c4c7007d541fb8694d79 /Source/Core/Common | |
| parent | 6cb60f8d364fc9887bfb4779993036d5554902a2 (diff) | |
| parent | ea8a3059bff1693ea640777a3aeb0c31daf18951 (diff) | |
Merge pull request #8393 from CookiePLMonster/long-paths
Support Windows 10 long paths
Diffstat (limited to 'Source/Core/Common')
| -rw-r--r-- | Source/Core/Common/CDUtils.cpp | 3 | ||||
| -rw-r--r-- | Source/Core/Common/Common.h | 6 | ||||
| -rw-r--r-- | Source/Core/Common/CommonFuncs.cpp | 23 | ||||
| -rw-r--r-- | Source/Core/Common/CommonFuncs.h | 4 | ||||
| -rw-r--r-- | Source/Core/Common/CompatPatches.cpp | 29 | ||||
| -rw-r--r-- | Source/Core/Common/FileUtil.cpp | 53 | ||||
| -rw-r--r-- | Source/Core/Common/FileUtil.h | 2 |
7 files changed, 70 insertions, 50 deletions
diff --git a/Source/Core/Common/CDUtils.cpp b/Source/Core/Common/CDUtils.cpp index fb67d076c6..559ff0234f 100644 --- a/Source/Core/Common/CDUtils.cpp +++ b/Source/Core/Common/CDUtils.cpp @@ -26,6 +26,7 @@ #include <IOKit/storage/IOMedia.h> #include <paths.h> #else +#include <climits> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/stat.h> @@ -211,7 +212,7 @@ bool IsCDROMDevice(std::string device) #ifndef _WIN32 // Resolve symbolic links. This allows symbolic links to valid // drives to be passed from the command line with the -e flag. - char resolved_path[MAX_PATH]; + char resolved_path[PATH_MAX]; char* devname = realpath(device.c_str(), resolved_path); if (!devname) return false; diff --git a/Source/Core/Common/Common.h b/Source/Core/Common/Common.h index eb0944bd8a..81a6e04ea3 100644 --- a/Source/Core/Common/Common.h +++ b/Source/Core/Common/Common.h @@ -30,12 +30,6 @@ struct CrtDebugBreak #endif -// Windows compatibility -#ifndef _WIN32 -#include <limits.h> -#define MAX_PATH PATH_MAX -#endif - #ifdef _MSC_VER #define __getcwd _getcwd #define __chdir _chdir diff --git a/Source/Core/Common/CommonFuncs.cpp b/Source/Core/Common/CommonFuncs.cpp index 7b109e81c5..a8c1abfea2 100644 --- a/Source/Core/Common/CommonFuncs.cpp +++ b/Source/Core/Common/CommonFuncs.cpp @@ -49,4 +49,27 @@ std::string GetLastErrorString() MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), error_message, BUFFER_SIZE, nullptr); return std::string(error_message); } + +// Obtains a full path to the specified module. +std::optional<std::wstring> GetModuleName(void* hInstance) +{ + DWORD max_size = 50; // Start with space for 50 characters and grow if needed + std::wstring name(max_size, L'\0'); + + DWORD size; + while ((size = GetModuleFileNameW(static_cast<HMODULE>(hInstance), name.data(), max_size)) == + max_size && + GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + max_size *= 2; + name.resize(max_size); + } + + if (size == 0) + { + return std::nullopt; + } + name.resize(size); + return name; +} #endif diff --git a/Source/Core/Common/CommonFuncs.h b/Source/Core/Common/CommonFuncs.h index e276bea7ae..2378aab3db 100644 --- a/Source/Core/Common/CommonFuncs.h +++ b/Source/Core/Common/CommonFuncs.h @@ -4,6 +4,7 @@ #pragma once +#include <optional> #include <string> #include "Common/CommonTypes.h" @@ -47,4 +48,7 @@ std::string LastStrerrorString(); // Wrapper function to get GetLastError() string. // This function might change the error code. std::string GetLastErrorString(); + +// Obtains a full path to the specified module. +std::optional<std::wstring> GetModuleName(void* hInstance); #endif diff --git a/Source/Core/Common/CompatPatches.cpp b/Source/Core/Common/CompatPatches.cpp index 03963ccdee..e07028e9e4 100644 --- a/Source/Core/Common/CompatPatches.cpp +++ b/Source/Core/Common/CompatPatches.cpp @@ -4,12 +4,14 @@ #include <Windows.h> #include <functional> +#include <optional> #include <string> #include <vector> #include <winternl.h> #include <fmt/format.h> +#include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" #include "Common/LdrWatcher.h" #include "Common/StringUtil.h" @@ -162,37 +164,26 @@ struct Version } }; -static bool GetModulePath(const wchar_t* name, std::wstring* path) +static std::optional<std::wstring> GetModulePath(const wchar_t* name) { auto module = GetModuleHandleW(name); if (module == nullptr) - return false; - DWORD path_len = MAX_PATH; -retry: - path->resize(path_len); - path_len = GetModuleFileNameW(module, const_cast<wchar_t*>(path->data()), - static_cast<DWORD>(path->size())); - if (!path_len) - return false; - auto error = GetLastError(); - if (error == ERROR_SUCCESS) - return true; - if (error == ERROR_INSUFFICIENT_BUFFER) - goto retry; - return false; + return std::nullopt; + + return GetModuleName(module); } static bool GetModuleVersion(const wchar_t* name, Version* version) { - std::wstring path; - if (!GetModulePath(name, &path)) + auto path = GetModulePath(name); + if (!path) return false; DWORD handle; - DWORD data_len = GetFileVersionInfoSizeW(path.c_str(), &handle); + DWORD data_len = GetFileVersionInfoSizeW(path->c_str(), &handle); if (!data_len) return false; std::vector<u8> block(data_len); - if (!GetFileVersionInfoW(path.c_str(), handle, data_len, block.data())) + if (!GetFileVersionInfoW(path->c_str(), handle, data_len, block.data())) return false; void* buf; UINT buf_len; diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp index b1885916dc..5fc633c5e9 100644 --- a/Source/Core/Common/FileUtil.cpp +++ b/Source/Core/Common/FileUtil.cpp @@ -639,19 +639,21 @@ std::string CreateTempDir() #endif } -std::string GetTempFilenameForAtomicWrite(const std::string& path) +std::string GetTempFilenameForAtomicWrite(std::string path) { - std::string abs = path; #ifdef _WIN32 - TCHAR absbuf[MAX_PATH]; - if (_tfullpath(absbuf, UTF8ToTStr(path).c_str(), MAX_PATH) != nullptr) - abs = TStrToUTF8(absbuf); + std::unique_ptr<TCHAR[], decltype(&std::free)> absbuf{ + _tfullpath(nullptr, UTF8ToTStr(path).c_str(), 0), std::free}; + if (absbuf != nullptr) + { + path = TStrToUTF8(absbuf.get()); + } #else char absbuf[PATH_MAX]; if (realpath(path.c_str(), absbuf) != nullptr) - abs = absbuf; + path = absbuf; #endif - return abs + ".xxx"; + return std::move(path) + ".xxx"; } #if defined(__APPLE__) @@ -672,22 +674,26 @@ std::string GetBundleDirectory() std::string GetExePath() { - static std::string dolphin_path; - if (dolphin_path.empty()) - { + static const std::string dolphin_path = [] { + std::string result; #ifdef _WIN32 - TCHAR dolphin_exe_path[2048]; - TCHAR dolphin_exe_expanded_path[MAX_PATH]; - GetModuleFileName(nullptr, dolphin_exe_path, ARRAYSIZE(dolphin_exe_path)); - if (_tfullpath(dolphin_exe_expanded_path, dolphin_exe_path, - ARRAYSIZE(dolphin_exe_expanded_path)) != nullptr) - dolphin_path = TStrToUTF8(dolphin_exe_expanded_path); - else - dolphin_path = TStrToUTF8(dolphin_exe_path); + auto dolphin_exe_path = GetModuleName(nullptr); + if (dolphin_exe_path) + { + std::unique_ptr<TCHAR[], decltype(&std::free)> dolphin_exe_expanded_path{ + _tfullpath(nullptr, dolphin_exe_path->c_str(), 0), std::free}; + if (dolphin_exe_expanded_path) + { + result = TStrToUTF8(dolphin_exe_expanded_path.get()); + } + else + { + result = TStrToUTF8(*dolphin_exe_path); + } + } #elif defined(__APPLE__) - dolphin_path = GetBundleDirectory(); - dolphin_path = - dolphin_path.substr(0, dolphin_path.find_last_of("Dolphin.app/Contents/MacOS") + 1); + result = GetBundleDirectory(); + result = result.substr(0, result.find_last_of("Dolphin.app/Contents/MacOS") + 1); #else char dolphin_exe_path[PATH_MAX]; ssize_t len = ::readlink("/proc/self/exe", dolphin_exe_path, sizeof(dolphin_exe_path)); @@ -696,9 +702,10 @@ std::string GetExePath() len = 0; } dolphin_exe_path[len] = '\0'; - dolphin_path = dolphin_exe_path; + result = dolphin_exe_path; #endif - } + return result; + }(); return dolphin_path; } diff --git a/Source/Core/Common/FileUtil.h b/Source/Core/Common/FileUtil.h index ccabf7fdfe..2c13ae07c0 100644 --- a/Source/Core/Common/FileUtil.h +++ b/Source/Core/Common/FileUtil.h @@ -174,7 +174,7 @@ bool SetCurrentDir(const std::string& directory); std::string CreateTempDir(); // Get a filename that can hopefully be atomically renamed to the given path. -std::string GetTempFilenameForAtomicWrite(const std::string& path); +std::string GetTempFilenameForAtomicWrite(std::string path); // Gets a set user directory path // Don't call prior to setting the base user directory |
