diff --git a/common/FileSystem.cpp b/common/FileSystem.cpp index b13b056bfd..ae8d00c47d 100644 --- a/common/FileSystem.cpp +++ b/common/FileSystem.cpp @@ -1183,6 +1183,38 @@ bool FileSystem::SetWorkingDirectory(const char* path) return (SetCurrentDirectoryW(wpath.c_str()) == TRUE); } +bool FileSystem::SetPathCompression(const char* path, bool enable) +{ + const std::wstring wpath(StringUtil::UTF8StringToWideString(path)); + const DWORD attrs = GetFileAttributesW(wpath.c_str()); + if (attrs == INVALID_FILE_ATTRIBUTES) + return false; + + const bool isFile = !(attrs & FILE_ATTRIBUTE_DIRECTORY); + const DWORD flags = isFile ? FILE_ATTRIBUTE_NORMAL : (FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_DIRECTORY); + + const HANDLE handle = CreateFileW(wpath.c_str(), + FILE_GENERIC_WRITE | FILE_GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_DELETE, + nullptr, + OPEN_EXISTING, + flags, + nullptr); + if (handle == INVALID_HANDLE_VALUE) + return false; + + DWORD bytesReturned = 0; + DWORD compressMode = enable ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE; + + bool result = DeviceIoControl( + handle, FSCTL_SET_COMPRESSION, + &compressMode, 2, nullptr, 0, + &bytesReturned, nullptr); + + CloseHandle(handle); + return result; +} + #else static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, const char* Path, const char* Pattern, @@ -1650,4 +1682,9 @@ bool FileSystem::SetWorkingDirectory(const char* path) return (chdir(path) == 0); } +bool FileSystem::SetPathCompression(const char* path, bool enable) +{ + return false; +} + #endif diff --git a/common/FileSystem.h b/common/FileSystem.h index 1ea3cd6208..81d4cf21bb 100644 --- a/common/FileSystem.h +++ b/common/FileSystem.h @@ -175,4 +175,9 @@ namespace FileSystem /// Sets the current working directory. Returns true if successful. bool SetWorkingDirectory(const char* path); + /// Enables/disables NTFS compression on a file or directory. + /// Does not apply the compression flag recursively if called for a directory. + /// Does nothing and returns false on non-Windows platforms. + bool SetPathCompression(const char* path, bool enable); + }; // namespace FileSystem diff --git a/pcsx2-qt/Settings/CreateMemoryCardDialog.cpp b/pcsx2-qt/Settings/CreateMemoryCardDialog.cpp index 4b8750891a..c965672505 100644 --- a/pcsx2-qt/Settings/CreateMemoryCardDialog.cpp +++ b/pcsx2-qt/Settings/CreateMemoryCardDialog.cpp @@ -15,6 +15,7 @@ #include "PrecompiledHeader.h" +#include "common/FileSystem.h" #include "common/StringUtil.h" #include @@ -127,7 +128,7 @@ void CreateMemoryCardDialog::createCard() if (m_ui.ntfsCompression->isChecked() && m_type == MemoryCardType::File) { const std::string fullPath(Path::CombineStdString(EmuFolders::MemoryCards, nameStr)); - NTFS_CompressFile(StringUtil::UTF8StringToWxString(fullPath), true); + FileSystem::SetPathCompression(fullPath.c_str(), true); } #endif diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt index 4d472acec5..c8815fb2c9 100644 --- a/pcsx2/CMakeLists.txt +++ b/pcsx2/CMakeLists.txt @@ -1394,7 +1394,6 @@ set(pcsx2WindowsSources windows/FlatFileReaderWindows.cpp windows/Optimus.cpp windows/VCprojects/IopSif.cpp - windows/WinCompressNTFS.cpp windows/WinConsolePipe.cpp windows/WinKeyCodes.cpp windows/WinPowerProfile.cpp diff --git a/pcsx2/Linux/LnxKeyCodes.cpp b/pcsx2/Linux/LnxKeyCodes.cpp index 300857cabc..226a12c2c0 100644 --- a/pcsx2/Linux/LnxKeyCodes.cpp +++ b/pcsx2/Linux/LnxKeyCodes.cpp @@ -18,8 +18,6 @@ #include -void NTFS_CompressFile( const wxString& file, bool compressStatus ) {} - // Returns a WXK_* keycode, given some kinda GDK input mess! int TranslateGDKtoWXK( u32 keysym ) { diff --git a/pcsx2/MemoryCardFile.cpp b/pcsx2/MemoryCardFile.cpp index 0c0353aa14..c3884c3266 100644 --- a/pcsx2/MemoryCardFile.cpp +++ b/pcsx2/MemoryCardFile.cpp @@ -328,8 +328,8 @@ void FileMemoryCard::Open() // [TODO] : Add memcard size detection and report it to the console log. // (8MB, 256Mb, formatted, unformatted, etc ...) -#ifdef __WXMSW__ - NTFS_CompressFile(str, EmuConfig.McdCompressNTFS); +#ifdef _WIN32 + FileSystem::SetPathCompression(StringUtil::wxStringToUTF8String(str).c_str(), EmuConfig.McdCompressNTFS); #endif if (str.EndsWith(".bin")) diff --git a/pcsx2/System.h b/pcsx2/System.h index 293baa6691..ef0cced5b6 100644 --- a/pcsx2/System.h +++ b/pcsx2/System.h @@ -163,7 +163,6 @@ extern void SysOutOfMemory_EmergencyResponse(uptr blocksize); extern u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller="Unnamed"); extern void vSyncDebugStuff( uint frame ); -extern void NTFS_CompressFile( const wxString& file, bool compressStatus=true ); extern std::string SysGetBiosDiscID(); extern std::string SysGetDiscID(); diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index ca1278e745..15d24f21ee 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -613,8 +613,8 @@ void AppApplySettings( const AppConfig* oldconf ) // Update the compression attribute on the Memcards folder. // Memcards generally compress very well via NTFS compression. - #ifdef __WXMSW__ - NTFS_CompressFile( g_Conf->Folders.MemoryCards.ToString(), g_Conf->EmuOptions.McdCompressNTFS ); + #ifdef _WIN32 + FileSystem::SetPathCompression( g_Conf->Folders.MemoryCards.ToUTF8(), g_Conf->EmuOptions.McdCompressNTFS ); #endif sApp.DispatchEvent( AppStatus_SettingsApplied ); diff --git a/pcsx2/pcsx2.vcxproj b/pcsx2/pcsx2.vcxproj index b059eb39ab..96d77371c4 100644 --- a/pcsx2/pcsx2.vcxproj +++ b/pcsx2/pcsx2.vcxproj @@ -713,7 +713,6 @@ - diff --git a/pcsx2/pcsx2.vcxproj.filters b/pcsx2/pcsx2.vcxproj.filters index 125be43acb..05100976e9 100644 --- a/pcsx2/pcsx2.vcxproj.filters +++ b/pcsx2/pcsx2.vcxproj.filters @@ -896,9 +896,6 @@ AppHost\Panels - - AppHost\Win32 - AppHost\Win32 @@ -3101,4 +3098,4 @@ AppHost\Resources - \ No newline at end of file + diff --git a/pcsx2/pcsx2core.vcxproj b/pcsx2/pcsx2core.vcxproj index 08c46bcf1a..791f9c55bc 100644 --- a/pcsx2/pcsx2core.vcxproj +++ b/pcsx2/pcsx2core.vcxproj @@ -311,7 +311,6 @@ - diff --git a/pcsx2/pcsx2core.vcxproj.filters b/pcsx2/pcsx2core.vcxproj.filters index 7c1acb600e..ccbcb21983 100644 --- a/pcsx2/pcsx2core.vcxproj.filters +++ b/pcsx2/pcsx2core.vcxproj.filters @@ -1241,9 +1241,6 @@ Host - - Host - System\Ps2\GS\Renderers\Hardware @@ -2097,4 +2094,4 @@ System\Ps2\Debug\rdebug - \ No newline at end of file + diff --git a/pcsx2/windows/WinCompressNTFS.cpp b/pcsx2/windows/WinCompressNTFS.cpp deleted file mode 100644 index 78fc3c8a61..0000000000 --- a/pcsx2/windows/WinCompressNTFS.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2010 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "PrecompiledHeader.h" -#include "Win32.h" -#include - -// Throws an exception based on the value returned from GetLastError. -// Performs an option return value success/fail check on hresult. -void StreamException_ThrowLastError( const wxString& streamname, HANDLE result ) -{ - if( result != INVALID_HANDLE_VALUE ) return; - - int error = GetLastError(); - - switch( error ) - { - case ERROR_FILE_NOT_FOUND: - throw Exception::FileNotFound( streamname ); - - case ERROR_PATH_NOT_FOUND: - throw Exception::FileNotFound( streamname ); - - case ERROR_TOO_MANY_OPEN_FILES: - throw Exception::CannotCreateStream( streamname ).SetDiagMsg(L"Too many open files"); - - case ERROR_ACCESS_DENIED: - throw Exception::AccessDenied( streamname ); - - case ERROR_INVALID_HANDLE: - throw Exception::BadStream( streamname ).SetDiagMsg(L"Stream object or handle is invalid"); - - case ERROR_SHARING_VIOLATION: - throw Exception::AccessDenied( streamname ).SetDiagMsg(L"Sharing violation"); - - default: - { - throw Exception::BadStream( streamname ).SetDiagMsg(pxsFmt( L"General Win32 File/stream error [GetLastError: %d]", error )); - } - } -} - -// returns TRUE if an error occurred. -bool StreamException_LogLastError( const wxString& streamname, const wxChar* action, HANDLE result ) -{ - try - { - StreamException_ThrowLastError( streamname, result ); - } - catch( Exception::BadStream& ex ) - { - Console.WriteLn( Color_Yellow, L"%s: %s", action, ex.FormatDiagnosticMessage().c_str() ); - return true; - } - return false; -} - -// Sets the NTFS compression flag for a directory or file. This function does not operate -// recursively. Set compressStatus to false to decompress compressed files (and do nothing -// to already decompressed files). -// -// Exceptions thrown: None. -// (Errors are logged to console. Failures are considered non-critical) -// -void NTFS_CompressFile( const wxString& file, bool compressStatus ) -{ - bool isFile = !wxDirExists( file ); - - if( isFile && !wxFileExists( file ) ) return; - if( GetFileAttributes(file) & FILE_ATTRIBUTE_COMPRESSED ) return; - if( !wxIsWritable( file ) ) return; - - const DWORD flags = isFile ? FILE_ATTRIBUTE_NORMAL : (FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_DIRECTORY); - - HANDLE bloated_crap = CreateFile( file, - FILE_GENERIC_WRITE | FILE_GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - flags, - NULL - ); - - // Fail silently -- non-compression of files and folders is not an errorable offense. - - if( !StreamException_LogLastError( file, L"NTFS Compress Notice", bloated_crap ) ) - { - DWORD bytesReturned = 0; - DWORD compressMode = compressStatus ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE; - - /*BOOL result = */DeviceIoControl( - bloated_crap, FSCTL_SET_COMPRESSION, - &compressMode, 2, NULL, 0, - &bytesReturned, NULL - ); - - // No need to see this every time on my exFAT drive (rama) - //if( !result ) - // StreamException_LogLastError( file, L"NTFS Compress Notice" ); - - CloseHandle( bloated_crap ); - } -}