mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-10 00:41:26 +12:00
vm_native: improve sparse file implementation (Win32)
Fix sparse attribute set/check, improve logic. Implement actual check of file data. Ask to restart RPCS3 first time (Win7 bug).
This commit is contained in:
parent
2491aad6f2
commit
191cb92300
1 changed files with 40 additions and 17 deletions
|
@ -332,26 +332,49 @@ namespace utils
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
fs::file f;
|
fs::file f;
|
||||||
|
|
||||||
auto set_sparse = [](HANDLE h) -> bool
|
// Get system version
|
||||||
{
|
[[maybe_unused]] static const DWORD version_major = *reinterpret_cast<const DWORD*>(__readgsqword(0x60) + 0x118);
|
||||||
// Get version
|
|
||||||
const DWORD version_major = *reinterpret_cast<const DWORD*>(__readgsqword(0x60) + 0x118);
|
|
||||||
|
|
||||||
// Disable sparse files on Windows 7 or lower
|
auto set_sparse = [](HANDLE h, usz m_size) -> bool
|
||||||
if (version_major <= 7)
|
{
|
||||||
|
FILE_SET_SPARSE_BUFFER arg{.SetSparse = true};
|
||||||
|
FILE_BASIC_INFO info0{};
|
||||||
|
ensure(GetFileInformationByHandleEx(h, FileBasicInfo, &info0, sizeof(info0)));
|
||||||
|
|
||||||
|
if ((info0.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) == 0 && version_major <= 7)
|
||||||
{
|
{
|
||||||
return true;
|
MessageBoxW(0, L"RPCS3 needs to be restarted to create sparse file rpcs3_vm.", L"RPCS3", MB_ICONEXCLAMATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DeviceIoControl(h, FSCTL_SET_SPARSE, nullptr, 0, nullptr, 0, nullptr, nullptr))
|
if ((info0.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) || DeviceIoControl(h, FSCTL_SET_SPARSE, &arg, sizeof(arg), nullptr, 0, nullptr, nullptr))
|
||||||
{
|
{
|
||||||
FILE_STANDARD_INFO info;
|
if ((info0.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) == 0 && version_major <= 7)
|
||||||
ensure(GetFileInformationByHandleEx(h, FileStandardInfo, &info, sizeof(info)));
|
|
||||||
|
|
||||||
if (info.AllocationSize.QuadPart)
|
|
||||||
{
|
{
|
||||||
// Make sure the file is not "dirty"
|
std::abort();
|
||||||
FILE_END_OF_FILE_INFO _eof{};
|
}
|
||||||
|
|
||||||
|
FILE_STANDARD_INFO info;
|
||||||
|
FILE_END_OF_FILE_INFO _eof{};
|
||||||
|
ensure(GetFileInformationByHandleEx(h, FileStandardInfo, &info, sizeof(info)));
|
||||||
|
ensure(GetFileSizeEx(h, &_eof.EndOfFile));
|
||||||
|
|
||||||
|
if (info.AllocationSize.QuadPart && _eof.EndOfFile.QuadPart == m_size)
|
||||||
|
{
|
||||||
|
// Truncate file since it may be dirty (fool-proof)
|
||||||
|
DWORD ret = 0;
|
||||||
|
FILE_ALLOCATED_RANGE_BUFFER dummy{};
|
||||||
|
dummy.Length.QuadPart = m_size;
|
||||||
|
|
||||||
|
if (!DeviceIoControl(h, FSCTL_QUERY_ALLOCATED_RANGES, &dummy, sizeof(dummy), nullptr, 0, &ret, 0) || ret)
|
||||||
|
{
|
||||||
|
_eof.EndOfFile.QuadPart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_eof.EndOfFile.QuadPart != m_size)
|
||||||
|
{
|
||||||
|
// Reset file size to 0 if it doesn't match
|
||||||
|
_eof.EndOfFile.QuadPart = 0;
|
||||||
ensure(SetFileInformationByHandle(h, FileEndOfFileInfo, &_eof, sizeof(_eof)));
|
ensure(SetFileInformationByHandle(h, FileEndOfFileInfo, &_eof, sizeof(_eof)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,12 +388,12 @@ namespace utils
|
||||||
{
|
{
|
||||||
ensure(f.open(storage, fs::read + fs::write + fs::create));
|
ensure(f.open(storage, fs::read + fs::write + fs::create));
|
||||||
}
|
}
|
||||||
else if (!f.open(fs::get_temp_dir() + "rpcs3_vm", fs::read + fs::write + fs::create) || !set_sparse(f.get_handle()))
|
else if (!f.open(fs::get_cache_dir() + "rpcs3_vm", fs::read + fs::write + fs::create) || !set_sparse(f.get_handle(), m_size))
|
||||||
{
|
{
|
||||||
ensure(f.open(fs::get_cache_dir() + "rpcs3_vm", fs::read + fs::write + fs::create));
|
ensure(f.open(fs::get_temp_dir() + "rpcs3_vm", fs::read + fs::write + fs::create));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!set_sparse(f.get_handle()))
|
if (!set_sparse(f.get_handle(), m_size))
|
||||||
{
|
{
|
||||||
MessageBoxW(0, L"Failed to initialize sparse file.", L"RPCS3", MB_ICONERROR);
|
MessageBoxW(0, L"Failed to initialize sparse file.", L"RPCS3", MB_ICONERROR);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue