summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2019-11-09 21:10:16 +0100
committerGitHub <noreply@github.com>2019-11-09 21:10:16 +0100
commitf4e12f85bce7f0ad3c3fcc5d19d7db495600a41b (patch)
tree5960897f371699d1b107c4c7007d541fb8694d79 /Source/Core
parent6cb60f8d364fc9887bfb4779993036d5554902a2 (diff)
parentea8a3059bff1693ea640777a3aeb0c31daf18951 (diff)
Merge pull request #8393 from CookiePLMonster/long-paths
Support Windows 10 long paths
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/CDUtils.cpp3
-rw-r--r--Source/Core/Common/Common.h6
-rw-r--r--Source/Core/Common/CommonFuncs.cpp23
-rw-r--r--Source/Core/Common/CommonFuncs.h4
-rw-r--r--Source/Core/Common/CompatPatches.cpp29
-rw-r--r--Source/Core/Common/FileUtil.cpp53
-rw-r--r--Source/Core/Common/FileUtil.h2
-rw-r--r--Source/Core/Core/PowerPC/Jit64/JitAsm.cpp2
-rw-r--r--Source/Core/DolphinQt/DolphinQt.manifest5
-rw-r--r--Source/Core/UICommon/UICommon.cpp41
-rw-r--r--Source/Core/WinUpdater/Main.cpp23
-rw-r--r--Source/Core/WinUpdater/Updater.exe.manifest5
12 files changed, 105 insertions, 91 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
diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp
index 1389fb05cc..18ed533c0b 100644
--- a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp
@@ -4,6 +4,8 @@
#include "Core/PowerPC/Jit64/JitAsm.h"
+#include <climits>
+
#include "Common/CommonTypes.h"
#include "Common/JitRegister.h"
#include "Common/x64ABI.h"
diff --git a/Source/Core/DolphinQt/DolphinQt.manifest b/Source/Core/DolphinQt/DolphinQt.manifest
index 8c709b5c38..01910f52dc 100644
--- a/Source/Core/DolphinQt/DolphinQt.manifest
+++ b/Source/Core/DolphinQt/DolphinQt.manifest
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
- <windowsSettings>
- <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
+ <windowsSettings xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
+ <dpiAware>true</dpiAware>
+ <longPathAware>true</longPathAware>
</windowsSettings>
</application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
diff --git a/Source/Core/UICommon/UICommon.cpp b/Source/Core/UICommon/UICommon.cpp
index fd9a3d2d8b..ee0609ba26 100644
--- a/Source/Core/UICommon/UICommon.cpp
+++ b/Source/Core/UICommon/UICommon.cpp
@@ -226,46 +226,57 @@ void SetUserDirectory(const std::string& custom_path)
// -> Use GetExeDirectory()\User
// Check our registry keys
+ // TODO: Maybe use WIL when it's available?
HKEY hkey;
DWORD local = 0;
- TCHAR configPath[MAX_PATH] = {0};
+ std::unique_ptr<TCHAR[]> configPath;
if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Dolphin Emulator"), 0, KEY_QUERY_VALUE,
&hkey) == ERROR_SUCCESS)
{
DWORD size = 4;
if (RegQueryValueEx(hkey, TEXT("LocalUserConfig"), nullptr, nullptr,
reinterpret_cast<LPBYTE>(&local), &size) != ERROR_SUCCESS)
+ {
local = 0;
+ }
+
+ size = 0;
+ RegQueryValueEx(hkey, TEXT("UserConfigPath"), nullptr, nullptr, nullptr, &size);
+ configPath = std::make_unique<TCHAR[]>(size / sizeof(TCHAR));
+ if (RegQueryValueEx(hkey, TEXT("UserConfigPath"), nullptr, nullptr,
+ reinterpret_cast<LPBYTE>(configPath.get()), &size) != ERROR_SUCCESS)
+ {
+ configPath.reset();
+ }
- size = MAX_PATH;
- if (RegQueryValueEx(hkey, TEXT("UserConfigPath"), nullptr, nullptr, (LPBYTE)configPath,
- &size) != ERROR_SUCCESS)
- configPath[0] = 0;
RegCloseKey(hkey);
}
- local = local || File::Exists(File::GetExeDirectory() + DIR_SEP "portable.txt");
+ local = local != 0 || File::Exists(File::GetExeDirectory() + DIR_SEP "portable.txt");
- // Get Program Files path in case we need it.
- TCHAR my_documents[MAX_PATH];
- bool my_documents_found = SUCCEEDED(
- SHGetFolderPath(nullptr, CSIDL_MYDOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, my_documents));
+ // Get Documents path in case we need it.
+ // TODO: Maybe use WIL when it's available?
+ PWSTR my_documents = nullptr;
+ bool my_documents_found =
+ SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_DEFAULT, nullptr, &my_documents));
if (local) // Case 1-2
user_path = File::GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP;
- else if (configPath[0]) // Case 3
- user_path = TStrToUTF8(configPath);
+ else if (configPath) // Case 3
+ user_path = TStrToUTF8(configPath.get());
else if (my_documents_found) // Case 4
user_path = TStrToUTF8(my_documents) + DIR_SEP "Dolphin Emulator" DIR_SEP;
else // Case 5
user_path = File::GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP;
+ CoTaskMemFree(my_documents);
+
// Prettify the path: it will be displayed in some places, we don't want a mix
// of \ and /.
- user_path = ReplaceAll(user_path, "\\", DIR_SEP);
+ user_path = ReplaceAll(std::move(user_path), "\\", DIR_SEP);
// Make sure it ends in DIR_SEP.
- if (*user_path.rbegin() != DIR_SEP_CHR)
+ if (user_path.back() != DIR_SEP_CHR)
user_path += DIR_SEP;
#else
@@ -340,7 +351,7 @@ void SetUserDirectory(const std::string& custom_path)
#endif
}
#endif
- File::SetUserPath(D_USER_IDX, user_path);
+ File::SetUserPath(D_USER_IDX, std::move(user_path));
}
void SaveWiimoteSources()
diff --git a/Source/Core/WinUpdater/Main.cpp b/Source/Core/WinUpdater/Main.cpp
index 9196805819..2e1bd36ff8 100644
--- a/Source/Core/WinUpdater/Main.cpp
+++ b/Source/Core/WinUpdater/Main.cpp
@@ -10,6 +10,7 @@
#include <string>
#include <vector>
+#include "Common/CommonFuncs.h"
#include "Common/StringUtil.h"
#include "UpdaterCommon/UI.h"
@@ -33,28 +34,6 @@ std::vector<std::string> CommandLineToUtf8Argv(PCWSTR command_line)
LocalFree(tokenized);
return argv;
}
-
-std::optional<std::wstring> GetModuleName(HINSTANCE hInstance)
-{
- std::wstring name;
- DWORD max_size = 50; // Start with space for 50 characters and grow if needed
- name.resize(max_size);
-
- DWORD size;
- while ((size = GetModuleFileNameW(hInstance, name.data(), max_size)) == max_size &&
- GetLastError() == ERROR_INSUFFICIENT_BUFFER)
- {
- max_size *= 2;
- name.resize(max_size);
- }
-
- if (size == 0)
- {
- return {};
- }
- name.resize(size);
- return name;
-}
}; // namespace
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
diff --git a/Source/Core/WinUpdater/Updater.exe.manifest b/Source/Core/WinUpdater/Updater.exe.manifest
index 0a3ca72f6d..e661623b28 100644
--- a/Source/Core/WinUpdater/Updater.exe.manifest
+++ b/Source/Core/WinUpdater/Updater.exe.manifest
@@ -29,8 +29,9 @@
</compatibility>
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings
- xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
- <dpiAware>True</dpiAware>
+ xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
+ <dpiAware>true</dpiAware>
+ <longPathAware>true</longPathAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly> \ No newline at end of file