From 05776ee6af55e162a378a8a384619e4f677ffa8b Mon Sep 17 00:00:00 2001 From: Bashar Astifan Date: Sun, 30 Apr 2023 08:54:54 +0400 Subject: [PATCH] Major update --- Common/File/DirListing.cpp | 24 +- Common/File/FileUtil.cpp | 83 +-- Core/FileLoaders/LocalFileLoader.cpp | 19 - Core/FileSystems/DirectoryFileSystem.cpp | 18 - Core/FileSystems/VirtualDiscFileSystem.cpp | 38 - Core/Util/GameManager.cpp | 10 - UI/DevScreens.cpp | 2 +- UI/NativeApp.cpp | 3 +- UWP/App.cpp | 1 - UWP/PPSSPP_UWPMain.cpp | 4 +- UWP/Package.appxmanifest | 102 +-- UWP/PackageGold.appxmanifest | 108 +-- UWP/PackageNormal.appxmanifest | 102 +-- UWP/UWP.vcxproj | 22 +- UWP/UWP.vcxproj.filters | 48 -- UWP/UWPHelpers/LaunchItem.h | 10 +- UWP/UWPHelpers/PPSSPPTypesHelpers.cpp | 85 --- UWP/UWPHelpers/PPSSPPTypesHelpers.h | 19 - UWP/UWPHelpers/StorageAccess.cpp | 168 +---- UWP/UWPHelpers/StorageAccess.h | 11 +- UWP/UWPHelpers/StorageAsync.cpp | 20 +- UWP/UWPHelpers/StorageAsync.h | 27 +- UWP/UWPHelpers/StorageConfig.h | 23 - UWP/UWPHelpers/StorageExtensions.cpp | 316 -------- UWP/UWPHelpers/StorageExtensions.h | 93 --- UWP/UWPHelpers/StorageFileW.h | 281 ------- UWP/UWPHelpers/StorageFolderW.h | 577 -------------- UWP/UWPHelpers/StorageHandler.cpp | 132 ---- UWP/UWPHelpers/StorageHandler.h | 137 ---- UWP/UWPHelpers/StorageInfo.h | 24 - UWP/UWPHelpers/StorageItemW.h | 324 -------- UWP/UWPHelpers/StorageLog.h | 17 - UWP/UWPHelpers/StorageManager.cpp | 826 ++++----------------- UWP/UWPHelpers/StorageManager.h | 72 +- UWP/UWPHelpers/StoragePath.cpp | 272 ------- UWP/UWPHelpers/StoragePath.h | 113 --- UWP/UWPHelpers/StoragePickers.cpp | 12 +- UWP/UWPHelpers/StoragePickers.h | 4 - UWP/UWPHelpers/UWP2C.cpp | 93 --- UWP/UWPHelpers/UWP2C.h | 26 - ext/libzip/zip_source_file_win32_utf16.c | 15 - 41 files changed, 396 insertions(+), 3885 deletions(-) delete mode 100644 UWP/UWPHelpers/PPSSPPTypesHelpers.cpp delete mode 100644 UWP/UWPHelpers/PPSSPPTypesHelpers.h delete mode 100644 UWP/UWPHelpers/StorageConfig.h delete mode 100644 UWP/UWPHelpers/StorageExtensions.cpp delete mode 100644 UWP/UWPHelpers/StorageExtensions.h delete mode 100644 UWP/UWPHelpers/StorageFileW.h delete mode 100644 UWP/UWPHelpers/StorageFolderW.h delete mode 100644 UWP/UWPHelpers/StorageHandler.cpp delete mode 100644 UWP/UWPHelpers/StorageHandler.h delete mode 100644 UWP/UWPHelpers/StorageInfo.h delete mode 100644 UWP/UWPHelpers/StorageItemW.h delete mode 100644 UWP/UWPHelpers/StorageLog.h delete mode 100644 UWP/UWPHelpers/StoragePath.cpp delete mode 100644 UWP/UWPHelpers/StoragePath.h delete mode 100644 UWP/UWPHelpers/UWP2C.cpp delete mode 100644 UWP/UWPHelpers/UWP2C.h diff --git a/Common/File/DirListing.cpp b/Common/File/DirListing.cpp index b6fe3332a9..7eac82dbbf 100644 --- a/Common/File/DirListing.cpp +++ b/Common/File/DirListing.cpp @@ -6,10 +6,7 @@ #include #if PPSSPP_PLATFORM(UWP) #include -#if !defined(__LIBRETRO__) -#include "UWP/UWPHelpers/StorageManager.h" -#include "UWP/UWPHelpers/PPSSPPTypesHelpers.h" -#endif +#include #endif #else #include @@ -71,11 +68,6 @@ bool GetFileInfo(const Path &path, FileInfo * fileInfo) { WIN32_FILE_ATTRIBUTE_DATA attrs; #if PPSSPP_PLATFORM(UWP) if (!GetFileAttributesExFromAppW(path.ToWString().c_str(), GetFileExInfoStandard, &attrs)) { -#if !defined(__LIBRETRO__) - if (GetFileInfoUWP(path.ToString(), fileInfo)) { - return true; - } -#endif #else if (!GetFileAttributesExW(path.ToWString().c_str(), GetFileExInfoStandard, &attrs)) { #endif @@ -230,11 +222,9 @@ bool GetFilesInDir(const Path &directory, std::vector *files, const ch #endif if (hFind == INVALID_HANDLE_VALUE) { #if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - // Getting folder contents need extra work - // request must be done within StorageManager - auto contents = GetFolderContents(directory.ToString()); - if (ItemsInfoUWPToFilesInfo(contents, files, filter, filters)) { - std::sort(files->begin(), files->end()); + // This step just to avoid empty results by adding fake folders + // It will help also to navigate back between selected folder + if(GetFakeFolders(directory, files, filter, filters)){ return true; } #endif @@ -337,13 +327,7 @@ std::vector GetWindowsDrives() { CHAR driveName[] = { (CHAR)(TEXT('A') + i), TEXT(':'), TEXT('\\'), TEXT('\0') }; std::string str(driveName); -#if !defined(__LIBRETRO__) - if (CheckDriveAccess(driveName, true)) { - drives.push_back(driveName); - } -#else drives.push_back(driveName); -#endif } } return drives; diff --git a/Common/File/FileUtil.cpp b/Common/File/FileUtil.cpp index fd65b62ced..47b3cdbb27 100644 --- a/Common/File/FileUtil.cpp +++ b/Common/File/FileUtil.cpp @@ -53,10 +53,8 @@ #include // getcwd #if PPSSPP_PLATFORM(UWP) #include -#if !defined(__LIBRETRO__) #include "UWP/UWPHelpers/StorageManager.h" #endif -#endif #else #include #include @@ -161,13 +159,13 @@ FILE *OpenCFile(const Path &path, const char *mode) { #if defined(_WIN32) && defined(UNICODE) #if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - // We shouldn't use _wfopen specificly for custom memory stick location + // We shouldn't use _wfopen here, + // this function is not allowed to read outside Local and Installation folders + // FileSystem (broadFileSystemAccess) doesn't apply on _wfopen + // if we have custom memory stick location _wfopen will return null + // 'GetFileStreamFromApp' will convert 'mode' to [access, share, creationDisposition] + // then it will call 'CreateFile2FromAppW' -> convert HANDLE to FILE* FILE* file = GetFileStreamFromApp(path.ToString(), mode); - - if (!file) { - // Call UWP storage helper - file = GetFileStream(path.ToString(), mode); - } return file; #else return _wfopen(path.ToWString().c_str(), ConvertUTF8ToWString(mode).c_str()); @@ -272,10 +270,6 @@ static bool ResolvePathVista(const std::wstring &path, wchar_t *buf, DWORD bufSi if (getFinalPathNameByHandleW) { #if PPSSPP_PLATFORM(UWP) HANDLE hFile = CreateFile2FromAppW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr); -#if !defined(__LIBRETRO__) - //Use UWP StorageManager to get handle - hFile = CreateFileUWP(path, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING); -#endif #else HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); #endif @@ -391,11 +385,6 @@ bool Exists(const Path &path) { WIN32_FILE_ATTRIBUTE_DATA data{}; #if PPSSPP_PLATFORM(UWP) if (!GetFileAttributesExFromAppW(path.ToWString().c_str(), GetFileExInfoStandard, &data) || data.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { -#if !defined(__LIBRETRO__) - if (IsExistsUWP(path.ToString())) { - return true; - } -#endif return false; } #else @@ -434,11 +423,6 @@ bool IsDirectory(const Path &filename) { WIN32_FILE_ATTRIBUTE_DATA data{}; #if PPSSPP_PLATFORM(UWP) if (!GetFileAttributesExFromAppW(filename.ToWString().c_str(), GetFileExInfoStandard, &data) || data.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { -#if !defined(__LIBRETRO__) - if (IsDirectoryUWP(filename.ToString())) { - return true; - } -#endif #else if (!GetFileAttributesEx(filename.ToWString().c_str(), GetFileExInfoStandard, &data) || data.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { #endif @@ -492,11 +476,6 @@ bool Delete(const Path &filename) { #ifdef _WIN32 #if PPSSPP_PLATFORM(UWP) if (!DeleteFileFromAppW(filename.ToWString().c_str())) { -#if !defined(__LIBRETRO__) - if (DeleteUWP(filename.ToString())) { - return true; - } -#endif WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s", filename.c_str(), GetLastErrorMsg().c_str()); return false; } @@ -551,19 +530,8 @@ bool CreateDir(const Path &path) { DEBUG_LOG(COMMON, "CreateDir('%s')", path.c_str()); #ifdef _WIN32 #if PPSSPP_PLATFORM(UWP) - if (CreateDirectoryFromAppW(path.ToWString().c_str(), NULL)) { + if (CreateDirectoryFromAppW(path.ToWString().c_str(), NULL)) return true; - } - else { -#if !defined(__LIBRETRO__) - if (File::Exists(path)) { - return true; - } - else { - CreateDirectoryUWP(path.ToString()); - } -#endif - } #else if (::CreateDirectory(path.ToWString().c_str(), NULL)) return true; @@ -657,16 +625,8 @@ bool DeleteDir(const Path &path) { #ifdef _WIN32 #if PPSSPP_PLATFORM(UWP) - if (RemoveDirectoryFromAppW(path.ToWString().c_str())) { + if (RemoveDirectoryFromAppW(path.ToWString().c_str())) return true; - } - else { -#if !defined(__LIBRETRO__) - if (DeleteUWP(path.ToString())) { - return true; - } -#endif - } #else if (::RemoveDirectory(path.ToWString().c_str())) return true; @@ -710,16 +670,14 @@ bool Rename(const Path &srcFilename, const Path &destFilename) { INFO_LOG(COMMON, "Rename: %s --> %s", srcFilename.c_str(), destFilename.c_str()); #if defined(_WIN32) && defined(UNICODE) +#if PPSSPP_PLATFORM(UWP) + if (MoveFileFromAppW(srcFilename.ToWString().c_str(), destFilename.ToWString().c_str())) + return true; +#else std::wstring srcw = srcFilename.ToWString(); std::wstring destw = destFilename.ToWString(); if (_wrename(srcw.c_str(), destw.c_str()) == 0) return true; -#if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - else { - if (RenameUWP(srcFilename.ToString(), destFilename.ToString())) { - return true; - } -} #endif #else if (rename(srcFilename.c_str(), destFilename.c_str()) == 0) @@ -755,13 +713,6 @@ bool Copy(const Path &srcFilename, const Path &destFilename) { #if PPSSPP_PLATFORM(UWP) if (CopyFileFromAppW(srcFilename.ToWString().c_str(), destFilename.ToWString().c_str(), FALSE)) return true; -#if !defined(__LIBRETRO__) - else { - if (CopyUWP(srcFilename.ToString(), destFilename.ToString())) { - return true; - } - } -#endif #else if (CopyFile(srcFilename.ToWString().c_str(), destFilename.ToWString().c_str(), FALSE)) return true; @@ -846,11 +797,6 @@ bool Move(const Path &srcFilename, const Path &destFilename) { } else if (Copy(srcFilename, destFilename)) { return Delete(srcFilename); } else { -#if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - if (MoveUWP(srcFilename.ToString(), destFilename.ToString())) { - return true; - } -#endif return false; } } @@ -900,9 +846,6 @@ uint64_t GetFileSize(const Path &filename) { WIN32_FILE_ATTRIBUTE_DATA attr; #if PPSSPP_PLATFORM(UWP) if (!GetFileAttributesExFromAppW(filename.ToWString().c_str(), GetFileExInfoStandard, &attr)) { -#if !defined(__LIBRETRO__) - return (uint64_t)GetSizeUWP(filename.ToString()); -#endif #else if (!GetFileAttributesEx(filename.ToWString().c_str(), GetFileExInfoStandard, &attr)){ #endif @@ -1020,9 +963,7 @@ bool OpenFileInEditor(const Path &fileName) { #if PPSSPP_PLATFORM(WINDOWS) #if PPSSPP_PLATFORM(UWP) -#if !defined(__LIBRETRO__) OpenFile(fileName.ToString()); -#endif #else ShellExecuteW(nullptr, L"open", fileName.ToWString().c_str(), nullptr, nullptr, SW_SHOW); #endif diff --git a/Core/FileLoaders/LocalFileLoader.cpp b/Core/FileLoaders/LocalFileLoader.cpp index 71f7097c0e..3a329cc36d 100644 --- a/Core/FileLoaders/LocalFileLoader.cpp +++ b/Core/FileLoaders/LocalFileLoader.cpp @@ -33,9 +33,6 @@ #include "Common/CommonWindows.h" #if PPSSPP_PLATFORM(UWP) #include -#if !defined(__LIBRETRO__) -#include "UWP/UWPHelpers/StorageManager.h" -#endif #endif #else #include @@ -111,15 +108,7 @@ LocalFileLoader::LocalFileLoader(const Path &filename) handle_ = CreateFile(filename.ToWString().c_str(), access, share, nullptr, mode, flags, nullptr); #endif if (handle_ == INVALID_HANDLE_VALUE) { -#if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - //Use UWP StorageManager to get handle - handle_ = CreateFileUWP(filename_.ToString(), access, share, mode); - if (handle_ == INVALID_HANDLE_VALUE) { - return; - } -#else return; -#endif } LARGE_INTEGER end_offset; const LARGE_INTEGER zero{}; @@ -170,11 +159,7 @@ bool LocalFileLoader::Exists() { if (File::GetFileInfo(filename_, &info)) { return info.exists; } else { -#if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - return IsExistsUWP(filename_.ToString()); -#else return false; -#endif } } @@ -183,11 +168,7 @@ bool LocalFileLoader::IsDirectory() { if (File::GetFileInfo(filename_, &info)) { return info.exists && info.isDirectory; } -#if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - return IsDirectoryUWP(filename_.ToString()); -#else return false; -#endif } s64 LocalFileLoader::FileSize() { diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index c3defa8a81..f6b5659243 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -52,10 +52,6 @@ #include #if PPSSPP_PLATFORM(UWP) #include -#if !defined(__LIBRETRO__) -#include "UWP/UWPHelpers/StorageManager.h" -#include "UWP/UWPHelpers/PPSSPPTypesHelpers.h" -#endif #endif #undef FILE_OPEN #else @@ -175,13 +171,6 @@ bool DirectoryFileHandle::Open(const Path &basePath, std::string &fileName, File hFile = CreateFile(fullName.ToWString().c_str(), desired, sharemode, 0, openmode, 0, 0); #endif bool success = hFile != INVALID_HANDLE_VALUE; -#if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - if (!success) { - //Use UWP StorageManager to get handle - hFile = CreateFileUWP(fullName.ToString(), desired, sharemode, openmode); - success = hFile != INVALID_HANDLE_VALUE; - } -#endif if (!success) { DWORD w32err = GetLastError(); @@ -194,13 +183,6 @@ bool DirectoryFileHandle::Open(const Path &basePath, std::string &fileName, File hFile = CreateFile(fullName.ToWString().c_str(), desired, sharemode, 0, openmode, 0, 0); #endif success = hFile != INVALID_HANDLE_VALUE; -#if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - if (!success) { - //Use UWP StorageManager to get handle - hFile = CreateFileUWP(fullName.ToString(), desired, sharemode, openmode); - success = hFile != INVALID_HANDLE_VALUE; - } -#endif if (!success) { w32err = GetLastError(); } diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 4e97dbec89..d141b5a419 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -41,10 +41,6 @@ #include #if PPSSPP_PLATFORM(UWP) #include -#if !defined(__LIBRETRO__) -#include "UWP/UWPHelpers/StorageManager.h" -#include "UWP/UWPHelpers/PPSSPPTypesHelpers.h" -#endif #endif #else #include @@ -688,40 +684,6 @@ std::vector VirtualDiscFileSystem::GetDirListing(const std::string hFind = FindFirstFileEx(w32path.c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0); #endif if (hFind == INVALID_HANDLE_VALUE) { -#if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - // Getting folder contents will need extra work - // request must be done within StorageManager - auto contents = GetFolderContents(w32path); - if (!contents.empty()) { - //Copy files data from 'files' to 'myVector' - for each (auto item in contents) { - PSPFileInfo entry; - if (item.isDirectory) { - entry.type = FILETYPE_DIRECTORY; - } - else { - entry.type = FILETYPE_NORMAL; - } - - entry.access = 0555; - entry.exists = true; - entry.size = item.size; - entry.name = item.name; - //tmFromFiletime(entry.atime, file.atime); //find solution if this value is important - //tmFromFiletime(entry.ctime, file.ctime); //find solution if this value is important - //tmFromFiletime(entry.mtime, file.mtime); //find solution if this value is important - entry.isOnSectorSystem = true; - - std::string fullRelativePath = path + "/" + entry.name; - int fileIndex = getFileListIndex(fullRelativePath); - if (fileIndex != -1) - entry.startSector = fileList[fileIndex].firstBlock; - - myVector.push_back(entry); - } - return myVector; - } -#endif if (exists) *exists = false; return myVector; //the empty list diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index 77aa86c2f6..9d5fe26d43 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -48,10 +48,6 @@ #include "Core/Util/GameManager.h" #include "Common/Data/Text/I18n.h" -#if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) -#include "UWP/UWPHelpers/StorageManager.h" -#endif - GameManager g_GameManager; static struct zip *ZipOpenPath(Path fileName) { @@ -79,12 +75,6 @@ GameManager::GameManager() { Path GameManager::GetTempFilename() const { #ifdef _WIN32 -#if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - std::string tmpFile = GetTempFile("PSP.tmp"); - if (!tmpFile.empty()) { - return Path(tmpFile); - } -#endif wchar_t tempPath[MAX_PATH]; GetTempPath(MAX_PATH, tempPath); wchar_t buffer[MAX_PATH]; diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 3cd51828ce..7587be8dac 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -67,7 +67,7 @@ #include "UI/ControlMappingScreen.h" #include "UI/GameSettingsScreen.h" -#if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) +#if PPSSPP_PLATFORM(UWP) #include "UWP/UWPHelpers/StorageManager.h" #endif diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index bb43d122c0..0c3d28a309 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -522,7 +522,6 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch else { INFO_LOG(SYSTEM, "No memstick directory file found (tried to open '%s')", pathResolved.c_str()); } - SetWorkingFolder(g_Config.memStickDirectory.ToString()); #elif PPSSPP_PLATFORM(IOS) g_Config.defaultCurrentDirectory = g_Config.internalDataDirectory; g_Config.memStickDirectory = DarwinFileSystemServices::appropriateMemoryStickDirectoryToUse(); @@ -788,7 +787,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch DEBUG_LOG(SYSTEM, "ScreenManager!"); g_screenManager = new ScreenManager(); #if PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) - if (g_Config.memStickDirectory.empty() || (IsFirstStart() && isLocalState(g_Config.memStickDirectory.ToString()))) { + if (g_Config.memStickDirectory.empty() || (g_Config.bFirstRun && isLocalState(g_Config.memStickDirectory.ToString()))) { #else if (g_Config.memStickDirectory.empty()) { #endif diff --git a/UWP/App.cpp b/UWP/App.cpp index 11797bab4d..c0dd8d2ee9 100644 --- a/UWP/App.cpp +++ b/UWP/App.cpp @@ -14,7 +14,6 @@ #include -#include #include #include diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 8a69ec3adc..b85cf7bdc5 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -134,8 +134,6 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptrChangeFileLog(GetLogFile().c_str()); } @@ -590,7 +588,7 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string { auto dataPackage = ref new DataPackage(); dataPackage->RequestedOperation = DataPackageOperation::Copy; - dataPackage->SetText(convert(param1)); + dataPackage->SetText(ToPlatformString(param1)); Clipboard::SetContent(dataPackage); return true; } diff --git a/UWP/Package.appxmanifest b/UWP/Package.appxmanifest index 947d21d2e3..e8bc127e9e 100644 --- a/UWP/Package.appxmanifest +++ b/UWP/Package.appxmanifest @@ -1,53 +1,53 @@ - + - - - - PPSSPP - PSP emulator - Henrik Rydgård - Assets\StoreLogo.png - - - - - - - - - - - - - - - - - - - - - - .cso - .bin - .iso - .elf - - - - - - - - - - - - - - - - - - - + + + + PPSSPP - PSP emulator + Henrik Rydgård + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + .cso + .bin + .iso + .elf + + + + + + + + + + + + + + + + + + + diff --git a/UWP/PackageGold.appxmanifest b/UWP/PackageGold.appxmanifest index 034b3fa83a..019a4fc4bf 100644 --- a/UWP/PackageGold.appxmanifest +++ b/UWP/PackageGold.appxmanifest @@ -1,57 +1,57 @@ - - - - PPSSPP Gold - PSP emulator - Henrik Rydgård - Assets\StoreLogo.png - - - - - - - - - - - - - - - - - - - - - - - - - - .cso - .bin - .iso - .elf - - - - - - - - - - - - - - - - - - - + + + + PPSSPP Gold - PSP emulator + Henrik Rydgård + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + .cso + .bin + .iso + .elf + + + + + + + + + + + + + + + + + + + diff --git a/UWP/PackageNormal.appxmanifest b/UWP/PackageNormal.appxmanifest index d6dbb88220..408af92dd5 100644 --- a/UWP/PackageNormal.appxmanifest +++ b/UWP/PackageNormal.appxmanifest @@ -1,53 +1,53 @@ - + - - - - PPSSPP - PSP emulator - Henrik Rydgård - Assets\StoreLogo.png - - - - - - - - - - - - - - - - - - - - - - .cso - .bin - .iso - .elf - - - - - - - - - - - - - - - - - - - + + + + PPSSPP - PSP emulator + Henrik Rydgård + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + .cso + .bin + .iso + .elf + + + + + + + + + + + + + + + + + + + diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index 94cdf9344e..0b7590b0fe 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -89,12 +89,14 @@ True False Never - C8DEB388B9BC89D1DC61324E4E9D9FE6A796B7AA False - 1 + 0 OnApplicationRun True PPSSPP_UWP_TemporaryKey.pfx + SHA256 + True + 0 @@ -458,21 +460,10 @@ - - - - - - - - - - - @@ -485,15 +476,10 @@ - - - - - Create diff --git a/UWP/UWP.vcxproj.filters b/UWP/UWP.vcxproj.filters index 1a889435c7..90e1982f5e 100644 --- a/UWP/UWP.vcxproj.filters +++ b/UWP/UWP.vcxproj.filters @@ -17,78 +17,30 @@ a5564d79-b131-4b27-9f5f-d80671731d94 bmp;fbx;gif;jpg;jpeg;tga;tiff;tif;png - - UWPHelpers - UWPHelpers UWPHelpers - - UWPHelpers - - - UWPHelpers - - - UWPHelpers - - - UWPHelpers - - - UWPHelpers - - - UWPHelpers - - - UWPHelpers - - - UWPHelpers - UWPHelpers - - UWPHelpers - UWPHelpers - - UWPHelpers - - - UWPHelpers - UWPHelpers UWPHelpers - - UWPHelpers - - - UWPHelpers - UWPHelpers - - UWPHelpers - UWPHelpers - - UWPHelpers - Common diff --git a/UWP/UWPHelpers/LaunchItem.h b/UWP/UWPHelpers/LaunchItem.h index df161efe07..e351879056 100644 --- a/UWP/UWPHelpers/LaunchItem.h +++ b/UWP/UWPHelpers/LaunchItem.h @@ -8,7 +8,7 @@ #include #include "Common/Log.h" -#include "StorageExtensions.h" +#include "UWPUtil.h" #include @@ -41,7 +41,7 @@ public: if (arg->Name == "cmd") { - auto command = convert(arg->Value); + auto command = FromPlatformString(arg->Value); DEBUG_LOG(FILESYS, "Launch command %s", command.c_str()); std::regex rgx("\"(.+\[^\/]+)\""); @@ -59,7 +59,7 @@ public: } } else if (arg->Name == "launchOnExit") { - launchOnExit = convert(arg->Value); + launchOnExit = FromPlatformString(arg->Value); DEBUG_LOG(FILESYS, "On exit URI %s", launchOnExit.c_str()); } } @@ -89,7 +89,7 @@ public: std::string GetFilePath() { std::string path = launchPath; if (storageFile != nullptr) { - path = convert(storageFile->Path); + path = FromPlatformString(storageFile->Path); } return path; } @@ -101,7 +101,7 @@ public: if (!launchOnExit.empty()) { DEBUG_LOG(FILESYS, "Calling back %s", launchOnExit.c_str()); - auto uri = ref new Windows::Foundation::Uri(convert(launchOnExit)); + auto uri = ref new Windows::Foundation::Uri(ToPlatformString(launchOnExit)); Windows::System::Launcher::LaunchUriAsync(uri); } launchOnExit = std::string(); diff --git a/UWP/UWPHelpers/PPSSPPTypesHelpers.cpp b/UWP/UWPHelpers/PPSSPPTypesHelpers.cpp deleted file mode 100644 index 8230f5ebae..0000000000 --- a/UWP/UWPHelpers/PPSSPPTypesHelpers.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan -// GitHub: https://github.com/basharast/UWP2Win32 - -#include "PPSSPPTypesHelpers.h" -#include "StorageManager.h" -#include "Common/Log.h" - -bool ItemsInfoUWPToFilesInfo(std::list items, std::vector* files, const char* filter, std::set filters) { - bool state = false; - if (!items.empty()) { - for each (auto item in items) { - File::FileInfo info; - info.name = item.name; - info.fullName = Path(item.fullName); - info.exists = true; - info.size = item.size; - info.isDirectory = item.isDirectory; - info.isWritable = (item.attributes & FILE_ATTRIBUTE_READONLY) == 0; - info.atime = item.lastAccessTime; - info.mtime = item.lastWriteTime; - info.ctime = item.creationTime; - if (item.attributes & FILE_ATTRIBUTE_READONLY) { - info.access = 0444; // Read - } - else { - info.access = 0666; // Read/Write - } - if (item.attributes & FILE_ATTRIBUTE_DIRECTORY) { - info.access |= 0111; // Execute - } - if (!info.isDirectory) { - std::string ext = info.fullName.GetFileExtension(); - if (!ext.empty()) { - ext = ext.substr(1); // Remove the dot. - if (filter && filters.find(ext) == filters.end()) { - continue; - } - } - } - files->push_back(info); - } - state = true; - } - - return state; -} - -void UpdateFileInfoByItemInfo(ItemInfoUWP item, File::FileInfo* info) { - info->name = item.name; - info->fullName = Path(item.fullName); - info->exists = true; - info->size = item.size; - info->isDirectory = item.isDirectory; - info->isWritable = (item.attributes & FILE_ATTRIBUTE_READONLY) == 0; - info->atime = item.lastAccessTime; - info->mtime = item.lastWriteTime; - info->ctime = item.creationTime; - if (item.attributes & FILE_ATTRIBUTE_READONLY) { - info->access = 0444; // Read - } - else { - info->access = 0666; // Read/Write - } - if (item.attributes & FILE_ATTRIBUTE_DIRECTORY) { - info->access |= 0111; // Execute - } -} - -bool GetFileInfoUWP(std::string path, File::FileInfo* info) { - bool state = false; - VERBOSE_LOG(FILESYS, "GetFileInfoUWP (%s)", path.c_str()); - auto itemInfo = GetItemInfoUWP(path); - if (itemInfo.attributes != INVALID_FILE_ATTRIBUTES) { - UpdateFileInfoByItemInfo(itemInfo, info); - state = true; - } - else { - VERBOSE_LOG(FILESYS, "GetFileInfoUWP failed! (%s)", path.c_str()); - } - - return state; -} diff --git a/UWP/UWPHelpers/PPSSPPTypesHelpers.h b/UWP/UWPHelpers/PPSSPPTypesHelpers.h deleted file mode 100644 index 4ad619da7c..0000000000 --- a/UWP/UWPHelpers/PPSSPPTypesHelpers.h +++ /dev/null @@ -1,19 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan -// GitHub: https://github.com/basharast/UWP2Win32 - -#pragma once - -#include -#include -#include -#include - -#include "StorageInfo.h" -#include "Common/File/Path.h" -#include "Common/File/DirListing.h" - -bool ItemsInfoUWPToFilesInfo(std::list items,std::vector* files, const char* filter, std::set filters); -bool GetFileInfoUWP(std::string path, File::FileInfo* info); diff --git a/UWP/UWPHelpers/StorageAccess.cpp b/UWP/UWPHelpers/StorageAccess.cpp index 44c0c8f209..ba6eff3d6d 100644 --- a/UWP/UWPHelpers/StorageAccess.cpp +++ b/UWP/UWPHelpers/StorageAccess.cpp @@ -4,30 +4,10 @@ // Telegram: @basharastifan // GitHub: https://github.com/basharast/UWP2Win32 -// Functions: -// GetDataFromLocalSettings(Platform::String^ key) -// AddDataToLocalSettings(Platform::String^ key, Platform::String^ data, bool replace) -// -// AddFolderToFutureList(StorageFolder^ folder) -// AddFileToFutureList(StorageFile^ file) -// -// AddToAccessibleDirectories(StorageFolder^ folder) -// AddToAccessibleFiles(StorageFile^ file) -// UpdateDirectoriesByFutureList() -// UpdateFilesByFutureList() -// FillAccessLists() -// -// GetFolderByKey(Platform::String^ key) -// GetFileByKey(Platform::String^ key) -// AppendFolderByToken(Platform::String^ token) -// AppendFileByToken(Platform::String^ token) - -#include "StorageConfig.h" -#include "StorageLog.h" -#include "StorageExtensions.h" #include "StorageAsync.h" #include "StorageAccess.h" -#include "StorageItemW.h" +#include "UWPUtil.h" +#include using namespace Platform; using namespace Windows::Storage; @@ -36,8 +16,12 @@ using namespace Windows::Foundation::Collections; using namespace Windows::Storage::AccessCache; using namespace Windows::ApplicationModel; -// Main lookup list -std::list FutureAccessItems; +std::list alist; +void AppendToAccessList(Platform::String^ path) +{ + Path p(FromPlatformString(path)); + alist.push_back(p.ToString()); +} // Get value from app local settings Platform::String^ GetDataFromLocalSettings(Platform::String^ key) { @@ -54,7 +38,7 @@ Platform::String^ GetDataFromLocalSettings(Platform::String^ key) { } std::string GetDataFromLocalSettings(std::string key) { - return convert(GetDataFromLocalSettings(convert(key))); + return FromPlatformString(GetDataFromLocalSettings(ToPlatformString(key))); } // Add or replace value in app local settings @@ -77,31 +61,15 @@ bool AddDataToLocalSettings(Platform::String^ key, Platform::String^ data, bool } bool AddDataToLocalSettings(std::string key, std::string data, bool replace) { - return AddDataToLocalSettings(convert(key), convert(data),replace); + return AddDataToLocalSettings(ToPlatformString(key), ToPlatformString(data),replace); } -// Add item to history list (FutureAccessItems) -void AddToAccessibleItems(IStorageItem^ item) { - bool isFolderAddedBefore = false; - for each (auto folderItem in FutureAccessItems) { - if (folderItem.Equal(item)) { - isFolderAddedBefore = true; - break; - } - } - - if (!isFolderAddedBefore) { - FutureAccessItems.push_back(StorageItemW(item)); - } -} - - // Add folder to future list (to avoid request picker again) void AddItemToFutureList(IStorageItem^ item) { try { if (item != nullptr) { Platform::String^ folderToken = AccessCache::StorageApplicationPermissions::FutureAccessList->Add(item); - AddToAccessibleItems(item); + AppendToAccessList(item->Path); } } catch (Platform::COMException^ e) { @@ -120,104 +88,30 @@ IStorageItem^ GetItemByKey(Platform::String^ key) { return item; } -// Append folder by token to (FutureAccessFolders) -void AppendItemByToken(Platform::String^ token) { - try { - if (token != nullptr && AccessCache::StorageApplicationPermissions::FutureAccessList->ContainsItem(token)) { - IStorageItem^ storageItem; - ExecuteTask(storageItem, AccessCache::StorageApplicationPermissions::FutureAccessList->GetItemAsync(token)); - AddToAccessibleItems(storageItem); - } - } - catch (Platform::COMException^ e) { - } -} - -// Update the history list by the future list (to restore all the picked items) -void UpdateItemsByFutureList() { - auto AccessList = AccessCache::StorageApplicationPermissions::FutureAccessList->Entries; - for each (auto ListItem in AccessList) { - Platform::String^ itemToken = ListItem.Token; - AppendItemByToken(itemToken); - } -} - -bool fillListsCalled = false; -bool fillListInProgress = false; -void FillLookupList() { - if (fillListsCalled) { - // Should be called only once - // but let's wait in case we got too calls at once - CoreWindow^ corewindow = CoreWindow::GetForCurrentThread(); - while (fillListInProgress) - { +std::list GetFutureAccessList() { + if (alist.empty()) { + auto AccessList = AccessCache::StorageApplicationPermissions::FutureAccessList->Entries; + for (auto it = 0; it != AccessList->Size; ++it){ + auto item = AccessList->GetAt(it); try { - if (corewindow) { - corewindow->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); - } - else { - corewindow = CoreWindow::GetForCurrentThread(); + auto token = item.Token; + if (token != nullptr && AccessCache::StorageApplicationPermissions::FutureAccessList->ContainsItem(token)) { + IStorageItem^ storageItem; + ExecuteTask(storageItem, AccessCache::StorageApplicationPermissions::FutureAccessList->GetItemAsync(token)); + if (storageItem != nullptr) { + AppendToAccessList(storageItem->Path); + } + else { + AccessCache::StorageApplicationPermissions::FutureAccessList->Remove(token); + } } } - catch (...) { - + catch (Platform::COMException^ e) { } } - return; + + AppendToAccessList(ApplicationData::Current->LocalFolder->Path); + AppendToAccessList(ApplicationData::Current->TemporaryFolder->Path); } - fillListsCalled = true; - fillListInProgress = true; - // Clean access list from any deleted/moved items - for each (auto listItem in AccessCache::StorageApplicationPermissions::FutureAccessList->Entries) { - try { - IStorageItem^ test; - ExecuteTask(test, AccessCache::StorageApplicationPermissions::FutureAccessList->GetItemAsync(listItem.Token)); - if (test == nullptr) { - // Access denied or file moved/deleted - AccessCache::StorageApplicationPermissions::FutureAccessList->Remove(listItem.Token); - } - } - catch (Platform::COMException^ e) { - // Access denied or file moved/deleted - AccessCache::StorageApplicationPermissions::FutureAccessList->Remove(listItem.Token); - } - } - - // Get files/folders selected by the user - UpdateItemsByFutureList(); - - // Append known folders -#if APPEND_APP_LOCALDATA_LOCATION - AddToAccessibleItems(ApplicationData::Current->LocalFolder); - AddToAccessibleItems(ApplicationData::Current->TemporaryFolder); -#endif - -#if APPEND_APP_INSTALLATION_LOCATION - AddToAccessibleItems(Package::Current->InstalledLocation); -#endif - -#if APPEND_DOCUMENTS_LOCATION - // >>>>DOCUMENTS (requires 'documentsLibrary' capability) - AddToAccessibleItems(KnownFolders::DocumentsLibrary); -#endif - -#if APPEND_VIDEOS_LOCATION - // >>>>VIDEOS (requires 'videosLibrary' capability) - AddToAccessibleItems(KnownFolders::VideosLibrary); -#endif - -#if APPEND_PICTURES_LOCATION - // >>>>VIDEOS (requires 'picturesLibrary' capability) - AddToAccessibleItems(KnownFolders::PicturesLibrary); -#endif - -#if APPEND_MUSIC_LOCATION - // >>>>MUSIC (requires 'musicLibrary' capability) - AddToAccessibleItems(KnownFolders::MusicLibrary); -#endif - - // No need to append `RemovableDevices` - // they will be allowed for access once you added the capability - - fillListInProgress = false; + return alist; } diff --git a/UWP/UWPHelpers/StorageAccess.h b/UWP/UWPHelpers/StorageAccess.h index 5eddc94afb..248227338b 100644 --- a/UWP/UWPHelpers/StorageAccess.h +++ b/UWP/UWPHelpers/StorageAccess.h @@ -4,19 +4,12 @@ // Telegram: @basharastifan // GitHub: https://github.com/basharast/UWP2Win32 -// Functions: -// GetDataFromLocalSettings(std::string key) -// AddDataToLocalSettings(std::string key, std::string data, bool replace) -// -// FillLookupList() - #pragma once +#include #include // Local settings std::string GetDataFromLocalSettings(std::string key); bool AddDataToLocalSettings(std::string key, std::string data, bool replace); - -// Lookup list -void FillLookupList(); +std::list GetFutureAccessList(); diff --git a/UWP/UWPHelpers/StorageAsync.cpp b/UWP/UWPHelpers/StorageAsync.cpp index 543c8ff05f..70c9891f1e 100644 --- a/UWP/UWPHelpers/StorageAsync.cpp +++ b/UWP/UWPHelpers/StorageAsync.cpp @@ -7,20 +7,20 @@ // Thanks to RetroArch/Libretro team for this idea // This is improved version of the original idea -// Functions: -// ExecuteTask(out, task) [for IAsyncOperation] -// ExecuteTask(out, task, def) [for IAsyncOperation] -// ExecuteTask(action) [for IAsyncAction such as 'Delete'] - #include "StorageAsync.h" bool ActionPass(Windows::Foundation::IAsyncAction^ action) { - return TaskHandler([&]() { - return concurrency::create_task(action).then([]() { - return true; - }); - }, false); + try { + return TaskHandler([&]() { + return concurrency::create_task(action).then([]() { + return true; + }); + }, false); + } + catch (...) { + return false; + } } // Async action such as 'Delete' file diff --git a/UWP/UWPHelpers/StorageAsync.h b/UWP/UWPHelpers/StorageAsync.h index 1ef9b5bba5..b023715e35 100644 --- a/UWP/UWPHelpers/StorageAsync.h +++ b/UWP/UWPHelpers/StorageAsync.h @@ -7,11 +7,6 @@ // Thanks to RetroArch/Libretro team for this idea // This is improved version of the original idea -// Functions: -// ExecuteTask(out, task) [for IAsyncOperation] -// ExecuteTask(out, task, def) [for IAsyncOperation] -// ExecuteTask(action) [for IAsyncAction such as 'Delete'] - #pragma once #include "pch.h" @@ -20,8 +15,8 @@ #include #include -#include "StorageLog.h" -#include "StorageExtensions.h" +#include "Common/Log.h" +#include "UWPUtil.h" using namespace Windows::UI::Core; @@ -38,11 +33,11 @@ T TaskHandler(std::function()> wtask, T def) wtask().then([&](concurrency::task t) { try { - result = t.get(); + result = t.get(); } catch (Platform::Exception^ exception_) { - UWP_ERROR_LOG(UWPSMT, convertToChar(exception_->Message)); + ERROR_LOG(FILESYS, FromPlatformString(exception_->Message).c_str()); } done = true; }); @@ -86,7 +81,12 @@ bool ActionPass(Windows::Foundation::IAsyncAction^ action); template void ExecuteTask(T& out, Windows::Foundation::IAsyncOperation^ task) { - out = TaskPass(task, T()); + try { + out = TaskPass(task, T()); + } + catch (...) { + out = T(); + } }; // For specific return default value @@ -96,7 +96,12 @@ void ExecuteTask(T& out, Windows::Foundation::IAsyncOperation^ task) template void ExecuteTask(T& out, Windows::Foundation::IAsyncOperation^ task, T def) { - out = TaskPass(task, def); + try{ + out = TaskPass(task, def); + } + catch (...) { + out = def; + } }; diff --git a/UWP/UWPHelpers/StorageConfig.h b/UWP/UWPHelpers/StorageConfig.h deleted file mode 100644 index 89f3b3dbea..0000000000 --- a/UWP/UWPHelpers/StorageConfig.h +++ /dev/null @@ -1,23 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan -// GitHub: https://github.com/basharast/UWP2Win32 - -#pragma once - -#include - -// Known locations -// ACTIVATE BELOW ONLY IF YOU ADDED THE CAPABILITY -#define APPEND_APP_LOCALDATA_LOCATION 1 // recommended to be always 1 -#define APPEND_APP_INSTALLATION_LOCATION 1 // recommended to be always 1 -#define APPEND_DOCUMENTS_LOCATION 0 // (requires 'documentsLibrary' capability) -#define APPEND_VIDEOS_LOCATION 0 // (requires 'videosLibrary' capability) -#define APPEND_MUSIC_LOCATION 0 // (requires musicLibrary' capability) -#define APPEND_PICTURES_LOCATION 0 // (requires 'picturesLibrary' capability) - - -// Working folder -// set this value by calling `SetWorkingFolder` from `StorageManager.h` -static std::string AppWorkingFolder; diff --git a/UWP/UWPHelpers/StorageExtensions.cpp b/UWP/UWPHelpers/StorageExtensions.cpp deleted file mode 100644 index 482be1ae3d..0000000000 --- a/UWP/UWPHelpers/StorageExtensions.cpp +++ /dev/null @@ -1,316 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan -// GitHub: https://github.com/basharast/UWP2Win32 - -// Functions: -// replace(std::string& str, const std::string& from, const std::string& to) -// replace2(const std::string str, const std::string& from, const std::string& to) -// split(const std::string s, char seperator) -// -// isChild(std::string parent, std::string child) -// isParent(std::string parent, std::string child, std::string childName) -// -// iequals(const std::string a, const std::string b) case-insenstive -// equals(const std::string a, const std::string b) case-senstive -// ends_with(std::string const& value, std::string const& ending) -// starts_with(std::string str, std::string prefix) -// -// convert(const std::string input) -// convertToWString(const std::string input) -// convert(Platform::String^ input) -// convert(std::wstring input) -// convert(const char* input) -// convertToLPCWSTR(Platform::String^ input) -// convertToLPCWSTR(std::string input) -// convertToChar(Platform::String^ input) -// -// tolower(std::string& input) -// tolower(Platform::String^ &input) -// toupper(std::string& input) -// toupper(Platform::String^& input) -// -// windowsPath(std::string& path) -// windowsPath(Platform::String^ &path) -// merge(std::string targetFullPath, std::string subFullPath) -// -// findInList(std::list& inputList, T& str) -// isWriteMode(const char* mode) -// getSubRoot(std::string parent, std::string child) - -#include "StorageExtensions.h" - -#pragma region Inernal Helpers -std::string make_string(const std::wstring& wstring) -{ - if (wstring.empty()) - { - return std::string(); - } - size_t pos; - size_t begin = 0; - std::string ret; - size_t size; - pos = wstring.find(static_cast(0), begin); - while (pos != std::wstring::npos && begin < wstring.length()) - { - std::wstring segment = std::wstring(&wstring[begin], pos - begin); - size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], (int)segment.size(), NULL, 0, NULL, NULL); - std::string converted = std::string(size, 0); - WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], (int)segment.size(), &converted[0], (int)converted.size(), NULL, NULL); - ret.append(converted); - ret.append({ 0 }); - begin = pos + 1; - pos = wstring.find(static_cast(0), begin); - } - if (begin <= wstring.length()) - { - std::wstring segment = std::wstring(&wstring[begin], wstring.length() - begin); - size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], (int)segment.size(), NULL, 0, NULL, NULL); - std::string converted = std::string(size, 0); - WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], (int)segment.size(), &converted[0], (int)converted.size(), NULL, NULL); - ret.append(converted); - } - - return ret; -} - -std::wstring make_wstring(const std::string& string) -{ - size_t requiredSize = 0; - std::wstring answer; - wchar_t* pWTempString = NULL; - - requiredSize = mbstowcs(NULL, string.c_str(), 0) + 1; - - pWTempString = (wchar_t*)malloc(requiredSize * sizeof(wchar_t)); - if (pWTempString != NULL) - { - size_t size = mbstowcs(pWTempString, string.c_str(), requiredSize); - if (size != (size_t)(-1)) - { - answer = pWTempString; - } - } - - if (pWTempString != NULL) - { - free(pWTempString); - } - - return answer; -} -#pragma endregion - -bool replace(std::string& str, const std::string& from, const std::string& to) { - size_t start_pos = str.find(from); - if (start_pos == std::string::npos) - return false; - str.replace(start_pos, from.length(), to); - return true; -} - -std::string replace2(const std::string str, const std::string& from, const std::string& to) { - std::string cpy = str; - size_t start_pos = cpy.find(from); - if (start_pos == std::string::npos) - return str; - cpy.replace(start_pos, from.length(), to); - return cpy; -} - -std::vector split(const std::string s, char seperator) -{ - std::vector output; - - std::string::size_type prev_pos = 0, pos = 0; - - while ((pos = s.find(seperator, pos)) != std::string::npos) - { - std::string substring(s.substr(prev_pos, pos - prev_pos)); - - output.push_back(substring); - - prev_pos = ++pos; - } - - output.push_back(s.substr(prev_pos, pos - prev_pos)); - - return output; -} - -bool isChild(std::string parent, std::string child) { - windowsPath(parent); - windowsPath(child); - tolower(parent); - tolower(child); - - return child.find(parent) != std::string::npos; -} - -// Parent full path, child full path, child name only -bool isParent(std::string parent, std::string child, std::string childName) { - windowsPath(parent); - windowsPath(child); - tolower(parent); - tolower(child); - tolower(childName); - - parent.append("\\"+ childName); - return parent == child; -} - -bool iequals(const std::string a, const std::string b) -{ - auto result = _stricmp(a.c_str(), b.c_str()); - return result == 0; -} - -bool equals(const std::string a, const std::string b) -{ - auto result = strcmp(a.c_str(), b.c_str()); - return result == 0; -} - -bool ends_with(std::string const& value, std::string const& ending) -{ - if (ending.size() > value.size()) return false; - return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); -} - -bool starts_with(std::string str, std::string prefix) -{ - return str.size() >= prefix.size() && 0 == str.compare(0, prefix.size(), prefix); -} - -Platform::String^ convert(const std::string input) -{ - auto wstr = make_wstring(input); - Platform::String^ output = ref new Platform::String(wstr.c_str()); - return output; -} - -std::wstring convertToWString(const std::string input) -{ - auto wstr = make_wstring(input); - return wstr; -} - -std::string convert(Platform::String^ input) { - std::wstring wsstr(input->Data()); - auto utf8Str = make_string(wsstr); // UTF8-encoded text - - return utf8Str; -} - -std::string convert(std::wstring input) { - auto utf8Str = make_string(input); // UTF8-encoded text - - return utf8Str; -} - -std::string convert(const char* input) { - std::wstring wsstr((const wchar_t*)input); - auto utf8Str = make_string(wsstr); // UTF8-encoded text - - return utf8Str; -} - -LPCWSTR convertToLPCWSTR(std::string input) { - std::wstring stemp = make_wstring(input); - LPCWSTR sw = stemp.c_str(); - - return sw; -} - -LPCWSTR convertToLPCWSTR(Platform::String^ input) { - std::string inputString = convert(input); - std::wstring stemp = make_wstring(inputString); - LPCWSTR sw = stemp.c_str(); - - return sw; -} - -const char* convertToChar(Platform::String^ input) { - std::string output = convert(input); - return output.c_str(); -} - -void tolower(std::string& input) { - std::transform(input.begin(), input.end(), input.begin(), std::tolower); -} - -void tolower(Platform::String^ &input) { - std::string temp = convert(input); - tolower(temp); - input = convert(temp); -} - -void toupper(std::string& input) { - std::transform(input.begin(), input.end(), input.begin(), std::toupper); -} - -void toupper(Platform::String^& input) { - std::string temp = convert(input); - toupper(temp); - input = convert(temp); -} - -void windowsPath(std::string& path) { - std::replace(path.begin(), path.end(), '/', '\\'); -} - -void windowsPath(Platform::String^ &path) { - std::string temp = convert(path); - windowsPath(temp); - path = convert(temp); -} - -std::string merge(std::string targetFullPath, std::string subFullPath) { - size_t pos = subFullPath.rfind('\\'); - if (pos != std::string::npos) { - auto itemName = subFullPath.substr(pos + 1); - std::string newPath = targetFullPath + "\\" + itemName; - return newPath; - } - return targetFullPath; -} - -std::string& rtrim(std::string& s, const char* t) -{ - s.erase(s.find_last_not_of(t) + 1); - return s; -} - -// trim from beginning of string (left) -std::string& ltrim(std::string& s, const char* t) -{ - s.erase(0, s.find_first_not_of(t)); - return s; -} - -// trim from both ends of string (right then left) -std::string& trim(std::string& s, const char* t) -{ - return ltrim(rtrim(s, t), t); -} - -bool isWriteMode(const char* mode) { - return (!strcmp(mode, "w") || !strcmp(mode, "wb") || !strcmp(mode, "wt") || !strcmp(mode, "at") || !strcmp(mode, "a")); -} -bool isAppendMode(const char* mode) { - return (!strcmp(mode, "at") || !strcmp(mode, "a")); -} - -// Parent and child full path -std::string getSubRoot(std::string parent, std::string child) { - windowsPath(parent); - windowsPath(child); - auto childCut = child; - replace(childCut, (parent + "\\"), ""); - size_t len = childCut.find_first_of('\\', 0); - auto subRoot = childCut.substr(0, len); - - return parent + "\\"+ subRoot; -} diff --git a/UWP/UWPHelpers/StorageExtensions.h b/UWP/UWPHelpers/StorageExtensions.h deleted file mode 100644 index 9045d13448..0000000000 --- a/UWP/UWPHelpers/StorageExtensions.h +++ /dev/null @@ -1,93 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan -// GitHub: https://github.com/basharast/UWP2Win32 - -// Functions: -// replace(std::string& str, const std::string& from, const std::string& to) -// replace2(const std::string str, const std::string& from, const std::string& to) -// split(const std::string s, char seperator) -// -// isChild(std::string parent, std::string child) -// isParent(std::string parent, std::string child, std::string childName) -// -// iequals(const std::string a, const std::string b) case-insenstive -// equals(const std::string a, const std::string b) case-senstive -// ends_with(std::string const& value, std::string const& ending) -// -// convert(const std::string input) -// convertToWString(const std::string input) -// convert(Platform::String^ input) -// convert(std::wstring input) -// convert(const char* input) -// convertToLPCWSTR(Platform::String^ input) -// convertToLPCWSTR(std::string input) -// convertToChar(Platform::String^ input) -// -// tolower(std::string& input) -// tolower(Platform::String^ &input) -// toupper(std::string& input) -// toupper(Platform::String^& input) -// -// windowsPath(std::string& path) -// windowsPath(Platform::String^ &path) -// merge(std::string targetFullPath, std::string subFullPath) -// -// findInList(std::list& inputList, T& str) -// isWriteMode(const char* mode) -// getSubRoot(std::string parent, std::string child) - -#pragma once - -#include -#include -#include -#include - -bool replace(std::string& str, const std::string& from, const std::string& to); -std::string replace2(const std::string str, const std::string& from, const std::string& to); -std::vector split(const std::string s, char seperator); -// Parent full path, child full path -bool isChild(std::string parent, std::string child); -// Parent full path, child full path, child name only -bool isParent(std::string parent, std::string child, std::string childName); - -bool iequals(const std::string a, const std::string b); -bool equals(const std::string a, const std::string b); -bool ends_with(std::string const& value, std::string const& ending); -bool starts_with(std::string str, std::string prefix); - -Platform::String^ convert(const std::string input); -std::wstring convertToWString(const std::string input); -std::string convert(Platform::String^ input); -std::string convert(std::wstring input); -std::string convert(const char* input); -LPCWSTR convertToLPCWSTR(std::string input); -LPCWSTR convertToLPCWSTR(Platform::String^ input); -const char* convertToChar(Platform::String^ input); - -void tolower(std::string& input); -void tolower(Platform::String^& input); -void toupper(std::string& input); -void toupper(Platform::String^& input); - -void windowsPath(std::string& path); -void windowsPath(Platform::String^& path); - -std::string merge(std::string targetFullPath, std::string subFullPath); - -std::string& rtrim(std::string& s, const char* t = " \t\n\r\f\v"); -std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v"); -std::string& trim(std::string& s, const char* t = " \t\n\r\f\v"); - -template -bool findInList(std::list& inputList, T& str) { - return (std::find(inputList.begin(), inputList.end(), str) != inputList.end()); -}; - -bool isWriteMode(const char* mode); -bool isAppendMode(const char* mode); -// Parent and child full path -std::string getSubRoot(std::string parent, std::string child); - diff --git a/UWP/UWPHelpers/StorageFileW.h b/UWP/UWPHelpers/StorageFileW.h deleted file mode 100644 index 7d5995339e..0000000000 --- a/UWP/UWPHelpers/StorageFileW.h +++ /dev/null @@ -1,281 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan -// GitHub: https://github.com/basharast/UWP2Win32 - -// Functions: -// IsValid() -// Delete() -// Rename(std::string name) -// Copy(StorageFolder^ folder) -// Move(StorageFolder^ folder) -// GetPath() -// GetName() -// Equal(std::string path) -// Equal(Path path) -// Equal(Platform::String^ path) -// Equal(StorageFile^ file) -// GetProperties() -// GetSize(bool updateCache) -// GetHandle(HANDLE* handle, HANDLE_ACCESS_OPTIONS access) -// GetStream(const char* mode) -// GetHandle(FILE* file) -// GetStorageFile() - -#pragma once - -#include "pch.h" -#include -#include - -#include "Common/Log.h" - -#include "StorageLog.h" -#include "StoragePath.h" -#include "StorageExtensions.h" -#include "StorageHandler.h" -#include "StorageAsync.h" -#include "StorageInfo.h" - -using namespace Platform; -using namespace Windows::Storage; -using namespace Windows::Foundation; -using namespace Windows::Storage::FileProperties; - -class StorageFileW { -public: - StorageFileW() { - } - - StorageFileW(StorageFile^ file) { - storageFile = file; - fileSize = 0; - } - StorageFileW(IStorageItem^ file) { - storageFile = (StorageFile^)file; - fileSize = 0; - } - ~StorageFileW() { - delete storageFile; - delete properties; - } - - // Detect if main storage file is not null - bool IsValid() { - return (storageFile != nullptr); - } - - // Delete file - bool Delete() { - bool state = ExecuteTask(storageFile->DeleteAsync()); - if (state) { - storageFile = nullptr; - } - return state; - } - - // Rename file - bool Rename(std::string name) { - auto path = PathUWP(name); - if (path.IsAbsolute()) { - name = path.GetFilename(); - } - return ExecuteTask(storageFile->RenameAsync(convert(name))); - } - - // Copy file - bool Copy(StorageFolder^ folder, std::string name) { - bool state = false; - StorageFile^ newFile; - ExecuteTask(newFile, storageFile->CopyAsync(folder, convert(name), NameCollisionOption::ReplaceExisting)); - if (newFile != nullptr) { - state = true; - } - return state; - } - - // Move file - bool Move(StorageFolder^ folder, std::string name) { - bool state = false; - IStorageItem^ newFile; - state = ExecuteTask(storageFile->MoveAsync(folder, convert(name), NameCollisionOption::GenerateUniqueName)); - if (state) { - ExecuteTask(newFile, folder->TryGetItemAsync(storageFile->Name)); - if (newFile != nullptr) { - storageFile = (StorageFile^)newFile; - } - else { - state = false; - } - } - return state; - } - - // Get file path - std::string GetPath() { - return convert(storageFile->Path); - } - - // Get file name - std::string GetName() { - return convert(storageFile->Name); - } - - // Compare file with std::string - bool Equal(std::string path) { - std::string filePath = GetPath(); - - // Fix slashs back from '/' to '\' - windowsPath(path); - return iequals(filePath, path); - } - - // Compare file with Platform::String - bool Equal(Platform::String^ path) { - return storageFile->Path->Equals(path); - } - - // Compare file with Path - bool Equal(PathUWP path) { - return Equal(path.ToString()); - } - - // Compare file with StorageFile - bool Equal(StorageFile^ file) { - return Equal(file->Path); - } - - // Get file size - __int64 GetSize(bool updateCache = false) { - if (fileSize == 0 || updateCache) { - // Let's try getting size by handle first - HANDLE handle; - HRESULT hr = GetHandle(&handle); - if (handle == INVALID_HANDLE_VALUE || hr != S_OK) { - // We have no other option, fallback to UWP - fileSize = FetchProperties()->Size; - } - else { - LARGE_INTEGER size{ 0 }; - if (FALSE == GetFileSizeEx(handle, &size)) { - LARGE_INTEGER end_offset; - const LARGE_INTEGER zero{}; - if (SetFilePointerEx(handle, zero, &end_offset, FILE_END) == 0) { - CloseHandle(handle); - } - else { - fileSize = end_offset.QuadPart; - SetFilePointerEx(handle, zero, nullptr, FILE_BEGIN); - CloseHandle(handle); - } - } - else { - fileSize = size.QuadPart; - CloseHandle(handle); - } - } - } - return fileSize; - } - - // Get file handle - HRESULT GetHandle(HANDLE* handle, int accessMode = GENERIC_READ, int shareMode = FILE_SHARE_READ) { - return GetFileHandle(storageFile, handle, GetAccessMode(accessMode), GetShareMode(shareMode)); - } - - // Get file stream - FILE* GetStream(const char* mode) { - HANDLE handle; - auto access = GENERIC_READ; - auto share = FILE_SHARE_READ; - bool isWrite = isWriteMode(mode); - if (isWrite) { - access = GENERIC_WRITE; - share = FILE_SHARE_WRITE; - } - HRESULT hr = GetHandle(&handle, access, share); - - FILE* file{}; - if (hr == S_OK && handle != INVALID_HANDLE_VALUE) { - int flags = _O_RDONLY; - if (isWrite) { - flags = _O_RDWR; - } - DEBUG_LOG(FILESYS, "Opening file (%s) with flag:%d mode:%s", GetPath().c_str(), flags, mode); - file = _fdopen(_open_osfhandle((intptr_t)handle, flags), mode); - } - return file; - } - - // Get file handle from stream - HANDLE GetHandle(FILE* file) { - return (HANDLE)_get_osfhandle(_fileno(file)); - } - - // Get file properties - FILE_BASIC_INFO* GetProperties() { - HANDLE handle; - HRESULT hr = GetHandle(&handle); - - size_t size = sizeof(FILE_BASIC_INFO); - FILE_BASIC_INFO* information = (FILE_BASIC_INFO*)(malloc(size)); - if(hr == S_OK && handle != INVALID_HANDLE_VALUE && information){ - information->FileAttributes = (DWORD)storageFile->Attributes; - - if (FALSE == GetFileInformationByHandleEx(handle, FileBasicInfo, information, (DWORD)size)) { - // Fallback to UWP method (Slow) - auto props = FetchProperties(); - information->ChangeTime.QuadPart = props->DateModified.UniversalTime; - information->CreationTime.QuadPart = props->ItemDate.UniversalTime; - information->LastAccessTime.QuadPart = props->DateModified.UniversalTime; - information->LastWriteTime.QuadPart = props->DateModified.UniversalTime; - } - CloseHandle(handle); - } - - return information; - } - - // Get main storage file - StorageFile^ GetStorageFile() { - return storageFile; - } - - time_t filetime_to_timet(LARGE_INTEGER ull) const { - return ull.QuadPart / 10000000ULL - 11644473600ULL; - } - ItemInfoUWP GetFileInfo() { - ItemInfoUWP info; - info.name = GetName(); - info.fullName = GetPath(); - info.isDirectory = false; - - auto sProperties = GetProperties(); - - info.size = (uint64_t)GetSize(); - info.lastAccessTime = (uint64_t)filetime_to_timet(sProperties->LastAccessTime); - info.lastWriteTime = (uint64_t)filetime_to_timet(sProperties->LastWriteTime); - info.changeTime = (uint64_t)filetime_to_timet(sProperties->ChangeTime); - info.creationTime = (uint64_t)filetime_to_timet(sProperties->CreationTime); - - - info.attributes = sProperties->FileAttributes; - - return info; - } - -private: - StorageFile^ storageFile; - BasicProperties^ properties; - __int64 fileSize = 0; - - BasicProperties^ FetchProperties() { - if (properties == nullptr) { - // Very bad and slow way in UWP to get size and other properties - // not preferred to be used on big list of files - ExecuteTask(properties, storageFile->GetBasicPropertiesAsync()); - } - return properties; - } -}; diff --git a/UWP/UWPHelpers/StorageFolderW.h b/UWP/UWPHelpers/StorageFolderW.h deleted file mode 100644 index 714140fb17..0000000000 --- a/UWP/UWPHelpers/StorageFolderW.h +++ /dev/null @@ -1,577 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan -// GitHub: https://github.com/basharast/UWP2Win32 - -// Functions: -// IsValid() -// GetPath() -// GetName() -// Delete() -// Equal(std::string path) -// Equal(Path path) -// Equal(Platform::String^ path) -// Equal(StorageFolder^ folder) -// GetSize(bool updateCache) -// CreateFolder(std::string name, bool replaceExisting) -// CreateFile(std::string name) -// Rename(std::string name) -// GetAllFiles(bool useWindowsIndexer) -// GetAllFolders(bool useWindowsIndexer) -// Contains(Path path, IStorageItem^& storageItem) -// Contains(std::string item) -// Copy(StorageFolderW folder) -// Move(StorageFolderW destination) -// GetHandle(HANDLE* handle, HANDLE_ACCESS_OPTIONS access) -// GetProperties() -// GetStorageFolder() -// GetFileStream(std::string name, const char* mode) - -#pragma once - -#include "pch.h" -#include - -#include "Common/Log.h" - -#include "StorageLog.h" -#include "StoragePath.h" -#include "StorageExtensions.h" -#include "StorageHandler.h" -#include "StorageAsync.h" -#include "StorageFileW.h" -#include "StorageInfo.h" - -using namespace Platform; -using namespace Windows::Storage; -using namespace Windows::Foundation; -using namespace Windows::Foundation::Collections; -using namespace Windows::Storage::FileProperties; -using namespace Windows::Storage::Search; - -class StorageFolderW { -public: - StorageFolderW() { - } - StorageFolderW(StorageFolder^ folder) { - storageFolder = folder; - folderSize = 0; - } - StorageFolderW(IStorageItem^ folder) { - storageFolder = (StorageFolder^)folder; - folderSize = 0; - } - ~StorageFolderW() { - delete storageFolder; - delete properties; - } - - // Detect if storage folder is not null - bool IsValid() { - return (storageFolder != nullptr); - } - - // Get folder path - std::string GetPath() { - return convert(storageFolder->Path); - } - - // Delete folder - bool Delete() { - bool state = ExecuteTask(storageFolder->DeleteAsync()); - if (state) { - storageFolder = nullptr; - } - return state; - } - - // Compare folder with std::string - bool Equal(std::string path) { - std::string folderPath = GetPath(); - - // Fix slashs back from '/' to '\' - windowsPath(path); - return iequals(folderPath, path); - } - - // Compare folder with Platform::String - bool Equal(Platform::String^ path) { - return storageFolder->Path->Equals(path); - } - - // Compare folder with Path - bool Equal(PathUWP path) { - return Equal(path.ToString()); - } - - // Compare folder with StorageFolder - bool Equal(StorageFolder^ folder) { - return Equal(folder->Path); - } - - // Get folder name - std::string GetName() { - return convert(storageFolder->Name); - } - - // Create new folder - bool CreateFolder(std::string name, bool replaceExisting = true) { - bool state = false; - StorageFolder^ newFolder; - ExecuteTask(newFolder, storageFolder->CreateFolderAsync(convert(name), replaceExisting ? CreationCollisionOption::ReplaceExisting : CreationCollisionOption::GenerateUniqueName)); - - if (newFolder != nullptr) { - state = true; - } - - delete newFolder; - return state; - } - - // Create new file - bool CreateFile(std::string name, bool replaceExisting = true) { - bool state = false; - StorageFile^ newFile; - ExecuteTask(newFile, storageFolder->CreateFileAsync(convert(name), replaceExisting ? CreationCollisionOption::ReplaceExisting : CreationCollisionOption::GenerateUniqueName)); - - if (newFile != nullptr) { - state = true; - } - - delete newFile; - return state; - } - - // Rename folder - bool Rename(std::string name) { - auto path = PathUWP(name); - if (path.IsAbsolute()) { - name = path.GetFilename(); - } - return ExecuteTask(storageFolder->RenameAsync(convert(name))); - } - - // Get files 1st level only, no deep scan - std::list GetFiles() { - std::list files; - - IVectorView^ sFiles; - VERBOSE_LOG(FILESYS, "Getting files for %s", GetPath().c_str()); - - ExecuteTask(sFiles, storageFolder->GetFilesAsync()); - if (sFiles != nullptr) { - for (auto it = 0; it != sFiles->Size; ++it) { - auto sItem = sFiles->GetAt(it); - if (sItem != nullptr) { - files.push_back(StorageFileW(sItem)); - } - } - } - delete sFiles; - VERBOSE_LOG(FILESYS, "Total files added (%d) in (%s)", files.size(), GetPath().c_str()); - - return files; - } - - std::list GetFolders() { - std::list folders; - - IVectorView^ sFolders; - VERBOSE_LOG(FILESYS, "Getting folders for %s", GetPath().c_str()); - - ExecuteTask(sFolders, storageFolder->GetFoldersAsync()); - if (sFolders != nullptr) { - VERBOSE_LOG(FILESYS, "Sub folders founded (%d) in (%s)", sFolders->Size, GetPath().c_str()); - for (auto it = 0; it != sFolders->Size; ++it) { - auto sItem = sFolders->GetAt(it); - if (sItem != nullptr) { - folders.push_back(StorageFolderW(sItem)); - } - } - } - delete sFolders; - VERBOSE_LOG(FILESYS, "Total folders added (%d) in (%s)", folders.size(), GetPath().c_str()); - - return folders; - } - - // Get all files including files in sub folders (deep scan) - std::list GetAllFiles(bool useWindowsIndexer = false) { - std::list files; // No structure one-level list - - VERBOSE_LOG(FILESYS, "Getting all files for %s", GetPath().c_str()); - IVectorView^ sFiles; - - // Set query options to create groups of files within result - QueryOptions^ queryOptions = ref new QueryOptions(CommonFolderQuery::DefaultQuery); - queryOptions->FolderDepth = FolderDepth::Deep; // Search in all levels - - // Windows indexer is very bad, it will return missing results if the files recently copied - // It's better to search without it, even if it will be slower - queryOptions->IndexerOption = useWindowsIndexer ? IndexerOption::UseIndexerWhenAvailable : IndexerOption::DoNotUseIndexer; - StorageFileQueryResult^ filesResult = storageFolder->CreateFileQueryWithOptions(queryOptions); - - // Windows search query is slow but it's the only solution (or we need to build safe recursive function) - // Regular 'StorageFolder->GetFilesAsync()' will not search in sub dirs - ExecuteTask(sFiles, filesResult->GetFilesAsync()); - - if (sFiles != nullptr) { - for (auto it = 0; it != sFiles->Size; ++it) { - auto sItem = sFiles->GetAt(it); - if (sItem != nullptr) { - files.push_back(StorageFileW(sItem)); - } - } - } - delete sFiles; - - VERBOSE_LOG(FILESYS, "Total files added (%d) in (%s)", files.size(), GetPath().c_str()); - - return files; - } - - // Get all sub folders (deep scan) - std::list GetAllFolders(bool useWindowsIndexer = false) { - std::list folders; - - IVectorView^ sFolders; - VERBOSE_LOG(FILESYS, "Getting all folders for %s", GetPath().c_str()); - - // Set query options to create groups of files within result - QueryOptions^ queryOptions = ref new QueryOptions(CommonFolderQuery::DefaultQuery); - queryOptions->FolderDepth = FolderDepth::Deep; // Search in all levels - - // Windows indexer is very bad, it will return missing results if the files recently copied - // It's better to search without it, even if it will be slower - queryOptions->IndexerOption = useWindowsIndexer ? IndexerOption::UseIndexerWhenAvailable : IndexerOption::DoNotUseIndexer; - StorageFolderQueryResult^ foldersResult = storageFolder->CreateFolderQueryWithOptions(queryOptions); - - // Windows search query is slow but it's the only solution (or we need to build safe recursive function) - // Regular 'StorageFolder->GetFoldersAsync()' will not search in sub dirs - ExecuteTask(sFolders, foldersResult->GetFoldersAsync()); - if (sFolders != nullptr) { - VERBOSE_LOG(FILESYS, "Sub folders founded (%d) in (%s)", sFolders->Size, GetPath().c_str()); - for (auto it = 0; it != sFolders->Size; ++it) { - auto sItem = sFolders->GetAt(it); - if (sItem != nullptr) { - folders.push_back(StorageFolderW(sItem)); - } - } - } - delete sFolders; - VERBOSE_LOG(FILESYS, "Total folders added (%d) in (%s)", folders.size(), GetPath().c_str()); - - return folders; - } - - // Ensure item path without root - std::string CleanItemPath(PathUWP& path) { - std::string itemName = path.ToString(); - // Ensure slashs changed from '/' to '\' - windowsPath(itemName); - - if (path.IsAbsolute()) { - - // If full path detected item in sub location, - // root path must be removed - replace(itemName, convert(storageFolder->Path + "\\"), ""); - replace(itemName, GetPath(), ""); - } - - // Do some fixes because 'TryGetItemAsync' is very sensetive - replace(itemName, "\\\\", "\\"); - replace(itemName, "//", "/"); - replace(itemName, "*", ""); - rtrim(itemName, ":"); // remove ':' at the end of the path (if any) - - path = PathUWP(itemName); - - return itemName; - } - - // Check if folder contains item by name or path - bool Contains(PathUWP path, IStorageItem^& storageItem) { - auto pathString = CleanItemPath(path); - - // If the path is for parent then ignore - if (!path.IsAbsolute()) { - VERBOSE_LOG(FILESYS, "Looking for (%s) in (%s)", pathString.c_str(), GetPath().c_str()); - ExecuteTask(storageItem, storageFolder->TryGetItemAsync(convert(pathString))); - } - - return storageItem != nullptr; - } - - bool Contains(std::string path) { - IStorageItem^ tempItem; - return Contains(PathUWP(path), tempItem); - } - - void BuildStructure(StorageFolder^& folder, std::string path) { - std::string folderName; - std::vector locationParts = split(path, '\\'); - for each (auto dir in locationParts) { - folderName.append(dir); - // Create folder - ExecuteTask(folder, storageFolder->CreateFolderAsync(convert(folderName), CreationCollisionOption::OpenIfExists)); - folderName.append("\\"); - } - } - - void BuildStructure(StorageFolder^& folder, std::string path, StorageFolder^ target) { - IStorageItem^ test = nullptr; - ExecuteTask(test, target->TryGetItemAsync(convert(path))); - if (test == nullptr) { - std::string folderName; - std::vector locationParts = split(path, '\\'); - for each (auto dir in locationParts) { - folderName.append(dir); - // Create folder - ExecuteTask(folder, target->CreateFolderAsync(convert(folderName), CreationCollisionOption::OpenIfExists)); - folderName.append("\\"); - } - } - else { - folder = (StorageFolder^)test; - } - } - - StorageFolder^ GetOrCreateFolder(PathUWP path) { - StorageFolder^ folder; - auto pathString = CleanItemPath(path); - BuildStructure(folder, pathString); - - return folder; - } - - StorageFile^ GetOrCreateFile(PathUWP path) { - StorageFile^ file; - StorageFolder^ folder; - auto name = path.GetFilename(); - auto dir = PathUWP(path.GetDirectory()); - auto dirString = CleanItemPath(dir); - BuildStructure(folder, dirString); - if (folder != nullptr) { - ExecuteTask(file, folder->CreateFileAsync(convert(name), CreationCollisionOption::OpenIfExists)); - } - return file; - - } - - // Copy to another folder - bool Copy(StorageFolderW folder, bool move = false) { - auto files = GetAllFiles(); - bool state = false; - int failedCount = 0; - if (!files.empty()) { - auto destination = folder.GetStorageFolder(); - - // Copy files one by one to avoid 'access violation' issues with deep-level tasks - std::string rootName = convert(storageFolder->Name); - std::string rootPath = PathUWP(GetPath()).GetDirectory(); - windowsPath(rootPath); - - if (destination != nullptr) { - for each (auto file in files) { - auto fItem = file.GetStorageFile(); - - // Get file full path - std::string targetLocation = convert(fItem->Path); - // Remove root path but keep the parent name - replace(targetLocation, rootPath, ""); - replace(targetLocation, convert("\\" + fItem->Name), ""); - ltrim(targetLocation, "\\"); - rtrim(targetLocation, "\\"); - - // Build folder structure - StorageFolder^ targetFolder; - BuildStructure(targetFolder, targetLocation, destination); - - if (targetFolder != nullptr) { - // Copy file - StorageFile^ testFile; - if (move) { - ExecuteTask(fItem->MoveAsync((IStorageFolder^)targetFolder, fItem->Name, NameCollisionOption::ReplaceExisting)); - ExecuteTask(testFile, targetFolder->GetFileAsync(fItem->Name)); // testing, it can be ignored - } - else { - ExecuteTask(testFile, fItem->CopyAsync((IStorageFolder^)targetFolder, fItem->Name, NameCollisionOption::ReplaceExisting)); - } - - if (testFile == nullptr) { - // File failed to copy, we can handle this later - failedCount++; - } - } - } - // Try to get the new folder - IStorageItem^ newFolder; - ExecuteTask(newFolder, destination->TryGetItemAsync(convert(rootName))); - if (newFolder != nullptr) { - if (move) { - if (failedCount == 0) { - // If all files moved, we can safely remove the folder - ExecuteTask(storageFolder->DeleteAsync()); - } - storageFolder = (StorageFolder^)newFolder; - } - state = true; - } - } - } - return state; - } - - // Copy to another folder using StorageFolder^ - bool Copy(StorageFolder^ folder, bool move = false) { - return Copy(StorageFolderW(folder), move); - } - - // Move to another folder - bool Move(StorageFolderW destination) { - return Copy(destination, true); - } - - // Get storage folder handle - HRESULT GetHandle(HANDLE* handle, int accessMode = GENERIC_READ, int shareMode = FILE_SHARE_READ) { - return GetFolderHandle(storageFolder, handle, GetAccessMode(accessMode),GetShareMode(shareMode)); - } - - // Get storage folder handle - HRESULT GetHandleForFile(HANDLE* handle, std::string filename, int accessMode = GENERIC_READ, int shareMode = FILE_SHARE_READ, int openMode = OPEN_EXISTING) { - return GetFileHandleFromFolder(storageFolder, filename, handle, GetAccessMode(accessMode), GetShareMode(shareMode), GetOpenMode(openMode)); - } - - // Get file stream - FILE* GetFileStream(std::string name, const char* mode) { - FILE* file{}; - - bool createIfNotExists = isWriteMode(mode); - bool isAppend = isAppendMode(mode); - - StorageFile^ sfile; - - if (createIfNotExists) { - auto createMode = isAppend ? CreationCollisionOption::OpenIfExists : CreationCollisionOption::ReplaceExisting; - ExecuteTask(sfile, storageFolder->CreateFileAsync(convert(name), createMode)); - } - else { - IStorageItem^ tempItem; - ExecuteTask(tempItem, storageFolder->TryGetItemAsync(convert(name))); - sfile = (StorageFile^)tempItem; - } - - StorageFileW storageFile(sfile); - if (storageFile.IsValid()) { - file = storageFile.GetStream(mode); - } - - return file; - } - - // Get folder size - __int64 GetSize(bool updateCache = false) { - if (folderSize == 0 || updateCache) { - // Let's try getting size by handle first - HANDLE handle; - HRESULT hr = GetHandle(&handle); - if (handle == INVALID_HANDLE_VALUE || hr != S_OK) { - // We have no other option, fallback to UWP - // This need to sum all files inside - auto files = GetAllFiles(true); - for each (auto file in files) { - folderSize += file.GetSize(); - } - } - else { - LARGE_INTEGER size{ 0 }; - if (FALSE == GetFileSizeEx(handle, &size)) { - LARGE_INTEGER end_offset; - const LARGE_INTEGER zero{}; - if (SetFilePointerEx(handle, zero, &end_offset, FILE_END) == 0) { - CloseHandle(handle); - } - else { - folderSize = end_offset.QuadPart; - SetFilePointerEx(handle, zero, nullptr, FILE_BEGIN); - CloseHandle(handle); - } - } - else { - folderSize = size.QuadPart; - CloseHandle(handle); - } - } - - } - return folderSize; - } - - // Get folder basic properties - FILE_BASIC_INFO* GetProperties() { - HANDLE handle; - HRESULT hr = GetHandle(&handle); - - size_t size = sizeof(FILE_BASIC_INFO); - FILE_BASIC_INFO* information = (FILE_BASIC_INFO*)(malloc(size)); - if (hr == S_OK && handle != INVALID_HANDLE_VALUE && information) { - information->FileAttributes = (DWORD)storageFolder->Attributes; - - if (FALSE == GetFileInformationByHandleEx(handle, FileBasicInfo, information, (DWORD)size)) { - // Fallback to UWP method (Slow) - auto props = FetchProperties(); - information->ChangeTime.QuadPart = props->DateModified.UniversalTime; - information->CreationTime.QuadPart = props->ItemDate.UniversalTime; - information->LastAccessTime.QuadPart = props->DateModified.UniversalTime; - information->LastWriteTime.QuadPart = props->DateModified.UniversalTime; - } - CloseHandle(handle); - } - - return information; - } - - // Get main storage folder - StorageFolder^ GetStorageFolder() { - return storageFolder; - } - - time_t filetime_to_timet(LARGE_INTEGER ull) const { - return ull.QuadPart / 10000000ULL - 11644473600ULL; - } - ItemInfoUWP GetFolderInfo() { - ItemInfoUWP info; - info.name = GetName(); - info.fullName = GetPath(); - info.isDirectory = true; - - - auto sProperties = GetProperties(); - - info.size = (uint64_t)GetSize(); - info.lastAccessTime = (uint64_t)filetime_to_timet(sProperties->LastAccessTime); - info.lastWriteTime = (uint64_t)filetime_to_timet(sProperties->LastWriteTime); - info.changeTime = (uint64_t)filetime_to_timet(sProperties->ChangeTime); - info.creationTime = (uint64_t)filetime_to_timet(sProperties->CreationTime); - - - info.attributes = sProperties->FileAttributes; - - return info; - } - -private: - StorageFolder^ storageFolder; - BasicProperties^ properties; - __int64 folderSize = 0; - - BasicProperties^ FetchProperties() { - if (properties == nullptr) { - // Very bad and slow way in UWP to get size and other properties - // not preferred to be used on big list of files - ExecuteTask(properties, storageFolder->GetBasicPropertiesAsync()); - } - return properties; - } -}; diff --git a/UWP/UWPHelpers/StorageHandler.cpp b/UWP/UWPHelpers/StorageHandler.cpp deleted file mode 100644 index d053a21b66..0000000000 --- a/UWP/UWPHelpers/StorageHandler.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan - -// Functions: -// GetFileHandle(StorageFile^ file, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode) -// GetFileHandleFromFolder(StorageFolder^ folder, std::string filename, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode, HANDLE_CREATION_OPTIONS openMode) -// GetFolderHandle(StorageFolder^ folder, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode) -// -// GetAccessMode(int accessMode) -// GetShareMode(int shareMode) -// GetOpenMode(int openMode) - -#include "StorageHandler.h" -#include "StorageExtensions.h" - -using namespace Windows::Storage; - -HRESULT GetFileHandle(StorageFile^ file, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode) -{ - if (file != nullptr) { - Microsoft::WRL::ComPtr abiPointer(reinterpret_cast(file)); - Microsoft::WRL::ComPtr handleAccess; - if (SUCCEEDED(abiPointer.As(&handleAccess))) - { - HANDLE hFile = INVALID_HANDLE_VALUE; - - if (SUCCEEDED(handleAccess->Create(accessMode, - shareMode, - HO_NONE, - nullptr, - &hFile))) - { - *handle = hFile; - return S_OK; - } - } - } - return E_FAIL; -} - -HRESULT GetFileHandleFromFolder(StorageFolder^ folder, std::string filename, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode, HANDLE_CREATION_OPTIONS openMode) -{ - if (folder != nullptr) { - Microsoft::WRL::ComPtr abiPointer(reinterpret_cast(folder)); - Microsoft::WRL::ComPtr handleAccess; - if (SUCCEEDED(abiPointer.As(&handleAccess))) - { - HANDLE hFolder = INVALID_HANDLE_VALUE; - auto fn = convertToLPCWSTR(filename); - if (SUCCEEDED(handleAccess->Create(fn, - openMode, - accessMode, - shareMode, - HO_NONE, - nullptr, - &hFolder))) - { - *handle = hFolder; - return S_OK; - } - } - } - return E_FAIL; -} - -HRESULT GetFolderHandle(StorageFolder^ folder, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode) -{ - if (folder != nullptr) { - Microsoft::WRL::ComPtr abiPointer(reinterpret_cast(folder)); - Microsoft::WRL::ComPtr handleAccess; - if (SUCCEEDED(abiPointer.As(&handleAccess))) - { - HANDLE hFolder = INVALID_HANDLE_VALUE; - - if (SUCCEEDED(handleAccess->Create(accessMode, - shareMode, - HO_NONE, - nullptr, - &hFolder))) - { - *handle = hFolder; - return S_OK; - } - } - } - return E_FAIL; -} - -HANDLE_ACCESS_OPTIONS GetAccessMode(int accessMode) { - switch (accessMode) { - case GENERIC_READ: - return HAO_READ | HAO_READ_ATTRIBUTES; - case GENERIC_WRITE: - return HAO_WRITE | HAO_READ; - case GENERIC_ALL: - return HAO_READ | HAO_READ_ATTRIBUTES | HAO_WRITE | HAO_DELETE; - default: - return HAO_READ; - } -} - -HANDLE_SHARING_OPTIONS GetShareMode(int shareMode) { - switch (shareMode) - { - case FILE_SHARE_READ: - return HSO_SHARE_READ; - case FILE_SHARE_WRITE: - return HSO_SHARE_READ | HSO_SHARE_WRITE; - case FILE_SHARE_DELETE: - return HSO_SHARE_DELETE; - default: - return HSO_SHARE_READ; - } -} - -HANDLE_CREATION_OPTIONS GetOpenMode(int openMode) { - switch (openMode) - { - case CREATE_NEW: - return HCO_CREATE_NEW; - case CREATE_ALWAYS: - return HCO_CREATE_ALWAYS; - case OPEN_ALWAYS: - return HCO_OPEN_ALWAYS; - case OPEN_EXISTING: - return HCO_OPEN_EXISTING; - default: - return HCO_OPEN_EXISTING; - } -} diff --git a/UWP/UWPHelpers/StorageHandler.h b/UWP/UWPHelpers/StorageHandler.h deleted file mode 100644 index 1b707aacb8..0000000000 --- a/UWP/UWPHelpers/StorageHandler.h +++ /dev/null @@ -1,137 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan - -// Functions: -// GetFileHandle(StorageFile^ file, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode) -// GetFileHandleFromFolder(StorageFolder^ folder, std::string filename, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode, HANDLE_CREATION_OPTIONS openMode) -// GetFolderHandle(StorageFolder^ folder, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode) -// -// GetAccessMode(int accessMode) -// GetShareMode(int shareMode) -// GetOpenMode(int openMode) - -#pragma once - -#include "pch.h" -#include -#include -#include -#include - -using namespace Windows::Storage; - -#pragma region WindowsStorageCOM -// These APIs have been accidentally placed inside the WINAPI_PARTITION_DESKTOP partition -// (they're not desktop-specific; they're available to UWPs). -// This will be addressed in future SDK updates. -// These are copied from WindowsStorageCOM.h -// You can remove this region once the real file has been updated -// to fix the WINAPI_PARTITION_DESKTOP block -// Source: https://stackoverflow.com/questions/42799235/how-can-i-get-a-win32-handle-for-a-storagefile-or-storagefolder-in-uwp - -typedef interface IOplockBreakingHandler IOplockBreakingHandler; -typedef interface IStorageItemHandleAccess IStorageItemHandleAccess; -typedef interface IStorageFolderHandleAccess IStorageFolderHandleAccess; - -#ifdef __cplusplus -extern "C" { -#endif - - typedef - enum HANDLE_OPTIONS - { - HO_NONE = 0, - HO_OPEN_REQUIRING_OPLOCK = 0x40000, - HO_DELETE_ON_CLOSE = 0x4000000, - HO_SEQUENTIAL_SCAN = 0x8000000, - HO_RANDOM_ACCESS = 0x10000000, - HO_NO_BUFFERING = 0x20000000, - HO_OVERLAPPED = 0x40000000, - HO_WRITE_THROUGH = 0x80000000 - } HANDLE_OPTIONS; - - DEFINE_ENUM_FLAG_OPERATORS(HANDLE_OPTIONS); - typedef - enum HANDLE_ACCESS_OPTIONS - { - HAO_NONE = 0, - HAO_READ_ATTRIBUTES = 0x80, - HAO_READ = 0x120089, - HAO_WRITE = 0x120116, - HAO_DELETE = 0x10000 - } HANDLE_ACCESS_OPTIONS; - - DEFINE_ENUM_FLAG_OPERATORS(HANDLE_ACCESS_OPTIONS); - typedef - enum HANDLE_SHARING_OPTIONS - { - HSO_SHARE_NONE = 0, - HSO_SHARE_READ = 0x1, - HSO_SHARE_WRITE = 0x2, - HSO_SHARE_DELETE = 0x4 - } HANDLE_SHARING_OPTIONS; - - DEFINE_ENUM_FLAG_OPERATORS(HANDLE_SHARING_OPTIONS); - typedef - enum HANDLE_CREATION_OPTIONS - { - HCO_CREATE_NEW = 0x1, - HCO_CREATE_ALWAYS = 0x2, - HCO_OPEN_EXISTING = 0x3, - HCO_OPEN_ALWAYS = 0x4, - HCO_TRUNCATE_EXISTING = 0x5 - } HANDLE_CREATION_OPTIONS; - - - EXTERN_C const IID IID_IOplockBreakingHandler; - MIDL_INTERFACE("826ABE3D-3ACD-47D3-84F2-88AAEDCF6304") - IOplockBreakingHandler : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE OplockBreaking(void) = 0; - - }; - - EXTERN_C const IID IID_IStorageItemHandleAccess; - MIDL_INTERFACE("5CA296B2-2C25-4D22-B785-B885C8201E6A") - IStorageItemHandleAccess : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE Create( - HANDLE_ACCESS_OPTIONS accessOptions, - HANDLE_SHARING_OPTIONS sharingOptions, - HANDLE_OPTIONS options, - __RPC__in_opt IOplockBreakingHandler * oplockBreakingHandler, - __RPC__deref_out_opt HANDLE * interopHandle) = 0; - - }; - - EXTERN_C const IID IID_IStorageFolderHandleAccess; - MIDL_INTERFACE("DF19938F-5462-48A0-BE65-D2A3271A08D6") - IStorageFolderHandleAccess : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE Create( - __RPC__in_string LPCWSTR fileName, - HANDLE_CREATION_OPTIONS creationOptions, - HANDLE_ACCESS_OPTIONS accessOptions, - HANDLE_SHARING_OPTIONS sharingOptions, - HANDLE_OPTIONS options, - __RPC__in_opt IOplockBreakingHandler * oplockBreakingHandler, - __RPC__deref_out_opt HANDLE * interopHandle) = 0; - - }; -#ifdef __cplusplus -} -#endif -#pragma endregion - -HRESULT GetFileHandle(StorageFile^ file, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode); -HRESULT GetFileHandleFromFolder(StorageFolder^ folder, std::string filename, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode, HANDLE_CREATION_OPTIONS openMode); -HRESULT GetFolderHandle(StorageFolder^ folder, HANDLE* handle, HANDLE_ACCESS_OPTIONS accessMode, HANDLE_SHARING_OPTIONS shareMode); - -HANDLE_ACCESS_OPTIONS GetAccessMode(int accessMode); -HANDLE_SHARING_OPTIONS GetShareMode(int shareMode); -HANDLE_CREATION_OPTIONS GetOpenMode(int openMode); diff --git a/UWP/UWPHelpers/StorageInfo.h b/UWP/UWPHelpers/StorageInfo.h deleted file mode 100644 index 52fee32949..0000000000 --- a/UWP/UWPHelpers/StorageInfo.h +++ /dev/null @@ -1,24 +0,0 @@ -// UWP STORAGE MANAGER -// For updates check: https://github.com/basharast/UWP2Win32 - -#pragma once - -#include -#include -#include -#include - -struct ItemInfoUWP { - std::string name; - std::string fullName; - - bool isDirectory = false; - - uint64_t size = 0; - uint64_t lastAccessTime = 0; - uint64_t lastWriteTime = 0; - uint64_t changeTime = 0; - uint64_t creationTime = 0; - - DWORD attributes = 0; -}; diff --git a/UWP/UWPHelpers/StorageItemW.h b/UWP/UWPHelpers/StorageItemW.h deleted file mode 100644 index 32b63acf55..0000000000 --- a/UWP/UWPHelpers/StorageItemW.h +++ /dev/null @@ -1,324 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan -// GitHub: https://github.com/basharast/UWP2Win32 - -#pragma once - -#include "pch.h" -#include -#include - -#include "StorageLog.h" -#include "StoragePath.h" -#include "StorageExtensions.h" -#include "StorageHandler.h" -#include "StorageAsync.h" -#include "StorageFolderW.h" - -using namespace Platform; -using namespace Windows::Storage; -using namespace Windows::Foundation; -using namespace Windows::Storage::FileProperties; - -class StorageItemW { -public: - StorageItemW() { - } - - StorageItemW(IStorageItem^ item) { - storageItem = item; - itemSize = 0; - if (item != nullptr) { - isDirectory = storageItem->IsOfType(StorageItemTypes::Folder); - if (isDirectory) { - storageFolderW = StorageFolderW(item); - } - else { - storageFileW = StorageFileW(item); - } - } - } - StorageItemW(StorageFolderW folder) { - StorageItemW((IStorageItem^)folder.GetStorageFolder()); - } - StorageItemW(StorageFileW file) { - StorageItemW((IStorageItem^)file.GetStorageFile()); - } - ~StorageItemW() { - delete storageItem; - } - - bool IsDirectory() { - return isDirectory; - } - - // Detect if main storage item is not null - bool IsValid() { - return (storageItem != nullptr); - } - - // Delete item - bool Delete() { - bool state = ExecuteTask(storageItem->DeleteAsync()); - if (state) { - storageItem = nullptr; - } - return state; - } - - // Rename item - bool Rename(std::string name) { - auto path = PathUWP(name); - if (path.IsAbsolute()) { - name = path.GetFilename(); - } - return ExecuteTask(storageItem->RenameAsync(convert(name))); - } - - // Copy item - bool Copy(StorageFolder^ folder) { - bool state = false; - if (IsDirectory()) { - state = storageFolderW.Copy(folder); - } - else { - state = storageFileW.Copy(folder, storageFileW.GetName()); - } - return state; - } - - - // Copy item - bool Copy(StorageItemW folder) { - return Copy(folder.GetStorageFolder()); - } - - bool Copy(StorageFolder^ folder, std::string name) { - bool state = false; - if (IsDirectory()) { - state = storageFolderW.Copy(folder); - } - else { - state = storageFileW.Copy(folder, name); - } - return state; - } - - bool Copy(StorageItemW folder, std::string name) { - return Copy(folder.GetStorageFolder(), name); - } - - // Move item - bool Move(StorageFolder^ folder) { - bool state = false; - if (IsDirectory()) { - state = storageFolderW.Copy(folder, true); - } - else { - state = storageFileW.Move(folder, storageFileW.GetName()); - } - return state; - } - - bool Move(StorageItemW folder) { - return Move(folder.GetStorageFolder()); - } - - // Move item - bool Move(StorageFolder^ folder, std::string name) { - bool state = false; - if (IsDirectory()) { - state = storageFolderW.Copy(folder, true); - } - else { - state = storageFileW.Move(folder, name); - } - return state; - } - - bool Move(StorageItemW folder, std::string name) { - return Move(folder.GetStorageFolder(), name); - } - - // Get item path - std::string GetPath() { - return convert(storageItem->Path); - } - - // Get item name - std::string GetName() { - return convert(storageItem->Name); - } - - // Compare item with std::string - bool Equal(std::string path) { - std::string itemPath = GetPath(); - - // Fix slashs back from '/' to '\' - windowsPath(path); - return iequals(itemPath, path); - } - - // Compare item with Platform::String - bool Equal(Platform::String^ path) { - return storageItem->Path->Equals(path); - } - - // Compare item with Path - bool Equal(PathUWP path) { - return Equal(path.ToString()); - } - - // Compare item with StorageItem - bool Equal(IStorageItem^ item) { - return Equal(item->Path); - } - - // Get item size - __int64 GetSize(bool updateCache = false) { - if (itemSize == 0 || updateCache) { - if (IsDirectory()) { - itemSize = storageFolderW.GetSize(updateCache); - } - else { - itemSize = storageFileW.GetSize(updateCache); - } - } - return itemSize; - } - - // Get item handle - HRESULT GetHandle(HANDLE* handle, int accessMode = GENERIC_READ, int shareMode = FILE_SHARE_READ) { - HRESULT hr = E_FAIL; - if(IsDirectory()){ - hr = GetFolderHandle(storageFolderW.GetStorageFolder(), handle, GetAccessMode(accessMode), GetShareMode(shareMode)); - } - else { - hr = GetFileHandle(storageFileW.GetStorageFile(), handle, GetAccessMode(accessMode), GetShareMode(shareMode)); - } - return hr; - } - - // Get file stream - FILE* GetStream(const char* mode) { - FILE* file{}; - if (!IsDirectory()) { - file = storageFileW.GetStream(mode); - } - return file; - } - - // Get files stream from folder - FILE* GetFileStream(std::string name, const char* mode) { - FILE* file{}; - if (IsDirectory()) { - file = storageFolderW.GetFileStream(name, mode); - } - return file; - } - - // Get item handle from stream - HANDLE GetHandleFromStream(FILE* file) { - return (HANDLE)_get_osfhandle(_fileno(file)); - } - - - // Create or open folder if exists - StorageFolderW CreateFolder(PathUWP path) { - return StorageFolderW(storageFolderW.GetOrCreateFolder(path)); - } - - // Create or open file if exists - StorageFileW CreateFile(PathUWP path) { - return StorageFileW(storageFolderW.GetOrCreateFile(path)); - } - - // Create new folder - bool CreateFolder(std::string name, bool replaceExisting = true) { - return storageFolderW.CreateFolder(name, replaceExisting); - } - - // Create new file - bool CreateFile(std::string name, bool replaceExisting = true) { - return storageFolderW.CreateFile(name, replaceExisting); - } - - // Check if folder contains item by name or path - bool Contains(PathUWP path, IStorageItem^& storageItem) { - return storageFolderW.Contains(path, storageItem); - } - - // Get all sub folders (deep scan) - std::list GetAllFolders(bool useWindowsIndexer = false) { - return storageFolderW.GetAllFolders(useWindowsIndexer); - } - - // Get all files including files in sub folders (deep scan) - std::list GetAllFiles(bool useWindowsIndexer = false) { - return storageFolderW.GetAllFiles(useWindowsIndexer); - } - - std::list GetFolders() { - return storageFolderW.GetFolders(); - } - - std::list GetFiles() { - return storageFolderW.GetFiles(); - } - - // Get item properties - FILE_BASIC_INFO* GetProperties() { - if (IsDirectory()) { - return storageFolderW.GetProperties(); - } - else { - return storageFileW.GetProperties(); - } - } - - // Get main storage item - IStorageItem^ GetStorageItem() { - return storageItem; - } - - // Get Wrapped StorageFolder - StorageFolderW GetStorageFolderW() { - return storageFolderW; - } - - // Get Wrapped StorageFolder - StorageFolder^ GetStorageFolder() { - return storageFolderW.GetStorageFolder(); - } - - // Get Wrapped StorageFile - StorageFileW GetStorageFileW() { - return storageFileW; - } - - // Get StorageFile^ - StorageFile^ GetStorageFile() { - return storageFileW.GetStorageFile(); - } - - ItemInfoUWP GetItemInfo() { - ItemInfoUWP info; - if (IsDirectory()) { - info = storageFolderW.GetFolderInfo(); - } - else { - info = storageFileW.GetFileInfo(); - } - return info; - } - -private: - IStorageItem^ storageItem; - StorageFileW storageFileW; - StorageFolderW storageFolderW; - - __int64 itemSize = 0; - bool isDirectory = false; -}; diff --git a/UWP/UWPHelpers/StorageLog.h b/UWP/UWPHelpers/StorageLog.h deleted file mode 100644 index 3c427d1a74..0000000000 --- a/UWP/UWPHelpers/StorageLog.h +++ /dev/null @@ -1,17 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan -// GitHub: https://github.com/basharast/UWP2Win32 - -#pragma once - -// Link your debug function below -// IGNORE THIS FILE FOR PPSSPP -// WE ALREADY USING PPSSPP's LOGS FUNCTIONS -#define UWP_ERROR_LOG(t,...) do { } while (false) -#define UWP_WARN_LOG(t,...) do { } while (false) -#define UWP_NOTICE_LOG(t,...) do { } while (false) -#define UWP_INFO_LOG(t,...) do { } while (false) -#define UWP_DEBUG_LOG(t,...) do { } while (false) -#define UWP_VERBOSE_LOG(t,...) do { } while (false) diff --git a/UWP/UWPHelpers/StorageManager.cpp b/UWP/UWPHelpers/StorageManager.cpp index 1b29263b56..500bf45f6c 100644 --- a/UWP/UWPHelpers/StorageManager.cpp +++ b/UWP/UWPHelpers/StorageManager.cpp @@ -4,56 +4,20 @@ // Telegram: @basharastifan // GitHub: https://github.com/basharast/UWP2Win32 -// Functions: -// GetWorkingFolder() -// SetWorkingFolder(std::string location) -// GetInstallationFolder() -// GetLocalFolder() -// GetTempFolder() -// GetPicturesFolder() -// GetVideosFolder() -// GetDocumentsFolder() -// GetMusicFolder() -// GetPreviewPath(std::string path) -// -// CreateFileUWP(std::string path, int accessMode, int shareMode, int openMode) -// CreateFileUWP(std::wstring path, int accessMode, int shareMode, int openMode) -// GetFileStream(std::string path, const char* mode) -// IsValidUWP(std::string path) -// IsExistsUWP(std::string path) -// IsDirectoryUWP(std::string path) -// -// GetFolderContents(std::string path, T& files) -// GetFolderContents(std::wstring path, T& files) -// GetFileInfoUWP(std::string path, T& info) -// -// GetSizeUWP(std::string path) -// DeleteUWP(std::string path) -// CreateDirectoryUWP(std::string path, bool replaceExisting) -// RenameUWP(std::string path, std::string name) -// CopyUWP(std::string path, std::string name) -// MoveUWP(std::string path, std::string name) -// -// OpenFile(std::string path) -// OpenFolder(std::string path) -// IsFirstStart() -// -// GetLogFile() -// SaveLogs() -// CleanupLogs() - #include "pch.h" +#include +#include + #include "Common/Log.h" +#include "Core/Config.h" +#include "Common/File/Path.h" +#include "Common/StringUtils.h" +#include "UWPUtil.h" -#include "StorageConfig.h" #include "StorageManager.h" -#include "StorageExtensions.h" -#include "StorageHandler.h" #include "StorageAsync.h" #include "StorageAccess.h" -#include "StorageItemW.h" -#include "StorageLog.h" using namespace Platform; @@ -61,37 +25,33 @@ using namespace Windows::Storage; using namespace Windows::Foundation; using namespace Windows::ApplicationModel; -extern std::list FutureAccessItems; #pragma region Locations std::string GetWorkingFolder() { - if (AppWorkingFolder.empty()) { + if (g_Config.memStickDirectory.empty()) { return GetLocalFolder(); } else { - return AppWorkingFolder; + return g_Config.memStickDirectory.ToString(); } } -void SetWorkingFolder(std::string location) { - AppWorkingFolder = location; -} std::string GetInstallationFolder() { - return convert(Package::Current->InstalledLocation->Path); + return FromPlatformString(Package::Current->InstalledLocation->Path); } StorageFolder^ GetLocalStorageFolder() { return ApplicationData::Current->LocalFolder; } std::string GetLocalFolder() { - return convert(GetLocalStorageFolder()->Path); + return FromPlatformString(GetLocalStorageFolder()->Path); } std::string GetTempFolder() { - return convert(ApplicationData::Current->TemporaryFolder->Path); + return FromPlatformString(ApplicationData::Current->TemporaryFolder->Path); } std::string GetTempFile(std::string name) { StorageFile^ tmpFile; - ExecuteTask(tmpFile, ApplicationData::Current->TemporaryFolder->CreateFileAsync(convert(name), CreationCollisionOption::GenerateUniqueName)); + ExecuteTask(tmpFile, ApplicationData::Current->TemporaryFolder->CreateFileAsync(ToPlatformString(name), CreationCollisionOption::GenerateUniqueName)); if (tmpFile != nullptr) { - return convert(tmpFile->Path); + return FromPlatformString(tmpFile->Path); } else { return ""; @@ -99,231 +59,56 @@ std::string GetTempFile(std::string name) { } std::string GetPicturesFolder() { // Requires 'picturesLibrary' capability - return convert(KnownFolders::PicturesLibrary->Path); + return FromPlatformString(KnownFolders::PicturesLibrary->Path); } std::string GetVideosFolder() { // Requires 'videosLibrary' capability - return convert(KnownFolders::VideosLibrary->Path); + return FromPlatformString(KnownFolders::VideosLibrary->Path); } std::string GetDocumentsFolder() { // Requires 'documentsLibrary' capability - return convert(KnownFolders::DocumentsLibrary->Path); + return FromPlatformString(KnownFolders::DocumentsLibrary->Path); } std::string GetMusicFolder() { // Requires 'musicLibrary' capability - return convert(KnownFolders::MusicLibrary->Path); + return FromPlatformString(KnownFolders::MusicLibrary->Path); } std::string GetPreviewPath(std::string path) { std::string pathView = path; - windowsPath(pathView); - replace(pathView, GetLocalFolder(), "LocalState"); - replace(pathView, GetTempFolder(), "TempState"); - replace(pathView, GetInstallationFolder(), "Installation folder"); + + pathView = ReplaceAll(pathView, "/", "\\"); + pathView = ReplaceAll(pathView, GetLocalFolder(), "LocalState"); + pathView = ReplaceAll(pathView, GetTempFolder(), "TempState"); + pathView = ReplaceAll(pathView, GetInstallationFolder(), "Installation folder"); return pathView; } bool isLocalState(std::string path) { - return iequals(GetPreviewPath(path), "LocalState"); + return !_stricmp(GetPreviewPath(path).c_str(), "LocalState"); } #pragma endregion #pragma region Internal -PathUWP PathResolver(PathUWP path) { +Path PathResolver(Path path) { auto root = path.GetDirectory(); auto newPath = path.ToString(); - if (path.IsRoot() || iequals(root, "/") || iequals(root, "\\")) { + if (path.IsRoot() || !_stricmp(root.c_str(), "/") || !_stricmp(root.c_str(), "\\")) { // System requesting file from app data - replace(newPath, "/", (GetLocalFolder() + (path.size() > 1 ? "/": ""))); + newPath = ReplaceAll(newPath, "/", (GetLocalFolder() + (path.size() > 1 ? "/" : ""))); } - path = PathUWP(newPath); - return path; + return Path(newPath); } -PathUWP PathResolver(std::string path) { - return PathResolver(PathUWP(path)); +Path PathResolver(std::string path) { + return PathResolver(Path(path)); } std::string ResolvePathUWP(std::string path) { return PathResolver(path).ToString(); } - -// Return closer parent -StorageItemW GetStorageItemParent(PathUWP path) { - path = PathResolver(path); - StorageItemW parent; - - for (auto& fItem : FutureAccessItems) { - if (isChild(fItem.GetPath(), path.ToString())) { - if (fItem.IsDirectory()) { - parent = fItem; - break; - } - } - } - - return parent; -} - -StorageItemW GetStorageItem(PathUWP path, bool createIfNotExists = false, bool forceFolderType = false) { - // Fill call will be ignored internally after the first call - FillLookupList(); - - path = PathResolver(path); - StorageItemW item; - - // Look for match in FutureAccessItems - for (auto& fItem : FutureAccessItems) { - if (fItem.Equal(path)) { - item = fItem; - break; - } - } - - if (!item.IsValid()) { - // Look for match inside FutureAccessFolders - for (auto& fItem : FutureAccessItems) { - if (fItem.IsDirectory()) { - IStorageItem^ storageItem; - if (fItem.Contains(path, storageItem)) { - item = StorageItemW(storageItem); - break; - } - } - } - } - - if (!item.IsValid() && createIfNotExists) { - // Create and return new folder - auto parent = GetStorageItemParent(path); - if (parent.IsValid()) { - if (!forceFolderType) { - // File creation must be called in this case - // Create folder usually will be called from 'CreateDirectory' - item = StorageItemW(parent.CreateFile(path)); - } - else { - item = StorageItemW(parent.CreateFolder(path)); - } - } - } - return item; -} - -StorageItemW GetStorageItem(std::string path, bool createIfNotExists = false, bool forceFolderType = false) { - return GetStorageItem(PathUWP(path), createIfNotExists, forceFolderType); -} - -std::list GetStorageItemsByParent(PathUWP path) { - path = PathResolver(path); - std::list items; - - // Look for match in FutureAccessItems - for (auto& fItem : FutureAccessItems) { - if (isParent(path.ToString(), fItem.GetPath(), fItem.GetName())) { - items.push_back(fItem); - } - } - - return items; -} - -std::list GetStorageItemsByParent(std::string path) { - return GetStorageItemsByParent(PathUWP(path)); -} - -bool IsContainsAccessibleItems(PathUWP path) { - path = PathResolver(path); - - for (auto& fItem : FutureAccessItems) { - if (isParent(path.ToString(), fItem.GetPath(), fItem.GetName())) { - return true; - } - } - - return false; -} - -bool IsContainsAccessibleItems(std::string path) { - return IsContainsAccessibleItems(PathUWP(path)); -} - -bool IsRootForAccessibleItems(PathUWP path, std::list& subRoot, bool breakOnFirstMatch = false) { - path = PathResolver(path); - - for (auto& fItem : FutureAccessItems) { - if (isChild(path.ToString(), fItem.GetPath())) { - if (breakOnFirstMatch) { - // Just checking, we don't need to loop for each item - return true; - } - auto sub = getSubRoot(path.ToString(), fItem.GetPath()); - - // This check can be better, but that's how I can do it in C++ - if (!ends_with(sub, ":")) { - bool alreadyAdded = false; - for each (auto sItem in subRoot) { - if (iequals(sItem, sub)) { - alreadyAdded = true; - break; - } - } - if (!alreadyAdded) { - subRoot.push_back(sub); - } - } - } - } - return !subRoot.empty(); -} - -bool IsRootForAccessibleItems(std::string path, std::list& subRoot, bool breakOnFirstMatch = false) { - return IsRootForAccessibleItems(PathUWP(path), subRoot, breakOnFirstMatch); -} -bool IsRootForAccessibleItems(std::string path) { - std::list tmp; - return IsRootForAccessibleItems(path, tmp, true); -} #pragma endregion #pragma region Functions -bool CreateIfNotExists(int openMode) { - switch (openMode) - { - case OPEN_ALWAYS: - case CREATE_NEW: - return true; - break; - default: - return false; - } -} - -HANDLE CreateFileUWP(std::string path, int accessMode, int shareMode, int openMode) { - HANDLE handle = INVALID_HANDLE_VALUE; - if (IsValidUWP(path)) { - bool createIfNotExists = CreateIfNotExists(openMode); - auto storageItem = GetStorageItem(path, createIfNotExists); - - if (storageItem.IsValid()) { - DEBUG_LOG(FILESYS, "Getting handle (%s)", path.c_str()); - HRESULT hr = storageItem.GetHandle(&handle, accessMode, shareMode); - if (hr == E_FAIL) { - handle = INVALID_HANDLE_VALUE; - } - } - else { - handle = INVALID_HANDLE_VALUE; - DEBUG_LOG(FILESYS, "Couldn't find or access (%s)", path.c_str()); - } - } - return handle; -} - -HANDLE CreateFileUWP(std::wstring path, int accessMode, int shareMode, int openMode) { - auto pathString = convert(path); - return CreateFileUWP(pathString, accessMode, shareMode, openMode); -} - std::map accessState; -bool CheckDriveAccess(std::string driveName, bool checkIfContainsFutureAccessItems) { +bool CheckDriveAccess(std::string driveName) { bool state = false; HANDLE searchResults; @@ -334,140 +119,41 @@ bool CheckDriveAccess(std::string driveName, bool checkIfContainsFutureAccessIte } else { try { - wchar_t* filteredPath = _wcsdup(convert(driveName)->Data()); + wchar_t* filteredPath = _wcsdup(ConvertUTF8ToWString(driveName).c_str()); wcscat_s(filteredPath, sizeof(L"\\*.*"), L"\\*.*"); -#if !defined(_M_ARM) + searchResults = FindFirstFileExFromAppW( filteredPath, FindExInfoBasic, &findDataResult, FindExSearchNameMatch, NULL, 0); -#else - searchResults = FindFirstFileEx( - filteredPath, FindExInfoBasic, &findDataResult, - FindExSearchNameMatch, NULL, 0); -#endif + state = searchResults != NULL && searchResults != INVALID_HANDLE_VALUE; if (state) { FindClose(searchResults); } + // Cache the state accessState.insert(std::make_pair(driveName, state)); } catch (...) { } } - - if (!state && checkIfContainsFutureAccessItems) { - // Consider the drive accessible in case it contain files/folder selected before to avoid empty results - state = IsRootForAccessibleItems(driveName) || IsContainsAccessibleItems(driveName); + if (!state) { + state = IsRootForAccessibleItems(driveName); } return state; } -bool IsValidUWP(std::string path) { - auto p = PathResolver(path); - //Check valid path - if (p.Type() == PathTypeUWP::UNDEFINED || !p.IsAbsolute()) { - // Nothing to do here - VERBOSE_LOG(FILESYS, "File is not valid (%s)", p.ToString().c_str()); - return false; - } - - - bool state = false; - - auto resolvedPathStr = p.ToString(); - if (ends_with(resolvedPathStr, "LocalState") || ends_with(resolvedPathStr, "TempState") || ends_with(resolvedPathStr, "LocalCache")) { - state = true; - } - else - if (isChild(GetLocalFolder(), resolvedPathStr)) { - state = true; - } - else if (isChild(GetInstallationFolder(), resolvedPathStr)) { - state = true; - } - else if (isChild(GetTempFolder(), resolvedPathStr)) { - state = true; - } - - if (!state) - { - auto p = PathUWP(path); - std::string driveName = p.GetRootVolume().ToString(); - state = CheckDriveAccess(driveName, false); - } - - return !state; +bool isWriteMode(const char* mode) { + return (!strcmp(mode, "w") || !strcmp(mode, "wb") || !strcmp(mode, "wt") || !strcmp(mode, "at") || !strcmp(mode, "a")); } - -bool IsExistsUWP(std::string path) { - if (IsValidUWP(path)) { - auto storageItem = GetStorageItem(path); - if (storageItem.IsValid()) { - return true; - } - - // If folder is not accessible but contains accessible items - // consider it exists - if (IsContainsAccessibleItems(path)) { - return true; - } - - // If folder is not accessible but is part of accessible items - // consider it exists - std::list tmp; - if (IsRootForAccessibleItems(path, tmp, true)) { - return true; - } - } - // ERROR_LOG(FILESYS, "Couldn't find or access (%s)", path.c_str()); - return false; -} - -bool IsDirectoryUWP(std::string path) { - if (IsValidUWP(path)) { - auto storageItem = GetStorageItem(path); - if (storageItem.IsValid()) { - if (storageItem.IsDirectory()) { - return true; - } - } - } - return false; -} - -FILE* GetFileStream(std::string path, const char* mode) { - FILE* file{}; - if (IsValidUWP(path)) { - auto storageItem = GetStorageItem(path); - if (storageItem.IsValid()) { - file = storageItem.GetStream(mode); - } - else { - // Forward the request to parent folder - auto p = PathUWP(path); - auto itemName = p.GetFilename(); - auto rootPath = p.GetDirectory(); - if (IsValidUWP(rootPath)) { - storageItem = GetStorageItem(rootPath); - if (storageItem.IsValid()) { - file = storageItem.GetFileStream(itemName, mode); - } - else { - ERROR_LOG(FILESYS, "Couldn't find or access (%s)", rootPath.c_str()); - ERROR_LOG(FILESYS, "Couldn't find or access (%s)", path.c_str()); - } - } - } - } - - return file; +bool isAppendMode(const char* mode) { + return (!strcmp(mode, "at") || !strcmp(mode, "a")); } FILE* GetFileStreamFromApp(std::string path, const char* mode) { FILE* file{}; - auto pathResolved = PathUWP(ResolvePathUWP(path)); + auto pathResolved = Path(ResolvePathUWP(path)); HANDLE handle; auto access = GENERIC_READ; auto share = FILE_SHARE_READ; @@ -480,11 +166,8 @@ FILE* GetFileStreamFromApp(std::string path, const char* mode) { share = FILE_SHARE_WRITE; creation = isAppend ? OPEN_ALWAYS : CREATE_ALWAYS; } -#if !defined(_M_ARM) handle = CreateFile2FromAppW(pathResolved.ToWString().c_str(), access, share, creation, nullptr); -#else - handle = CreateFile2(pathResolved.ToWString().c_str(), access, share, creation, nullptr); -#endif + if (handle != INVALID_HANDLE_VALUE) { int flags = _O_RDONLY; if (isWrite) { @@ -496,262 +179,121 @@ FILE* GetFileStreamFromApp(std::string path, const char* mode) { return file; } -#pragma region Content Helpers -ItemInfoUWP GetFakeFolderInfo(std::string folder) { - ItemInfoUWP info; - auto folderPath = PathUWP(folder); - info.name = folderPath.GetFilename(); - info.fullName = folderPath.ToString(); - - info.isDirectory = true; - - info.size = 1; - info.lastAccessTime = 1000; - info.lastWriteTime = 1000; - info.changeTime = 1000; - info.creationTime = 1000; - - info.attributes = FILE_ATTRIBUTE_DIRECTORY; - - return info; -} - #pragma endregion -std::list GetFolderContents(std::string path, bool deepScan) { - std::list contents; +#pragma region FakeFolders +// Parent and child full path +std::string getSubRoot(std::string parent, std::string child) { + auto childCut = child; + childCut = ReplaceAll(childCut, (parent + "/"), ""); + size_t len = childCut.find_first_of('/', 0); + auto subRoot = childCut.substr(0, len); - if (IsValidUWP(path)) { - auto storageItem = GetStorageItem(path); - if (storageItem.IsValid()) { + return parent + "/" + subRoot; +} - // Files - // deepScan is slow, try to avoid it - auto rfiles = deepScan ? storageItem.GetAllFiles() : storageItem.GetFiles(); - for each (auto file in rfiles) { - contents.push_back(file.GetFileInfo()); +bool isChild(std::string parent, std::string child) { + return child.find(parent) != std::string::npos; +} + +// Parent full path, child full path, child name only +bool isParent(std::string parent, std::string child, std::string childName) { + parent.append("/" + childName); + return parent == child; +} + +bool IsRootForAccessibleItems(Path path, std::list& subRoot, bool breakOnFirstMatch = false) { + path = PathResolver(path); + auto FutureAccessItems = GetFutureAccessList(); + for (auto& fItem : FutureAccessItems) { + if (isChild(path.ToString(), fItem)) { + if (breakOnFirstMatch) { + // Just checking, we don't need to loop for each item + return true; } + auto sub = getSubRoot(path.ToString(), fItem); - // Folders - // deepScan is slow, try to avoid it - auto rfolders = deepScan ? storageItem.GetAllFolders() : storageItem.GetFolders(); - for each (auto folder in rfolders) { - contents.push_back(folder.GetFolderInfo()); - } - } - else { - DEBUG_LOG(FILESYS, "Cannot get contents!, checking for other options.. (%s)", path.c_str()); - } -; } - - if (contents.size() == 0) { - // Folder maybe not accessible or not exists - // if not accessible, maybe some items inside it were selected before - // and they already in our accessible list - if (IsContainsAccessibleItems(path)) { - DEBUG_LOG(FILESYS, "Folder contains accessible items (%s)", path.c_str()); - - // Check contents - auto cItems = GetStorageItemsByParent(path); - if (!cItems.empty()) { - for each (auto item in cItems) { - VERBOSE_LOG(FILESYS, "Appending accessible item (%s)", item.GetPath().c_str()); - contents.push_back(item.GetItemInfo()); - } - } - } - else - { - // Check if this folder is root for accessible item - // then add fake folder as sub root to avoid empty results - std::list subRoot; - if (IsRootForAccessibleItems(path, subRoot)) { - DEBUG_LOG(FILESYS, "Folder is root for accessible items (%s)", path.c_str()); - - if (!subRoot.empty()) { - for each (auto sItem in subRoot) { - VERBOSE_LOG(FILESYS, "Appending fake folder (%s)", sItem.c_str()); - contents.push_back(GetFakeFolderInfo(sItem)); + // This check can be better, but that's how I can do it in C++ + if (!endsWith(sub, ":")) { + bool alreadyAdded = false; + for each (auto sItem in subRoot) { + if (!strcmp(sItem.c_str(), sub.c_str())) { + alreadyAdded = true; + break; } } - } - else { - VERBOSE_LOG(FILESYS, "Cannot get any content!.. (%s)", path.c_str()); + if (!alreadyAdded) { + subRoot.push_back(sub); + } } } } - return contents; + return !subRoot.empty(); } -std::list GetFolderContents(std::wstring path, bool deepScan) { - return GetFolderContents(convert(path), deepScan); +bool IsRootForAccessibleItems(std::string path) +{ + std::list tmp; + return IsRootForAccessibleItems(Path(path), tmp, true); } -ItemInfoUWP GetItemInfoUWP(std::string path) { - ItemInfoUWP info; - info.size = -1; - info.attributes = INVALID_FILE_ATTRIBUTES; - - if (IsValidUWP(path)) { - auto storageItem = GetStorageItem(path); - if (storageItem.IsValid()) { - info = storageItem.GetItemInfo(); - } - else { - ERROR_LOG(FILESYS, "Couldn't find or access (%s)", path.c_str()); +bool GetFakeFolders(Path path, std::vector* files, const char* filter, std::set filters) { + bool state = false; + std::list subRoot; + if (IsRootForAccessibleItems(path, subRoot)) { + if (!subRoot.empty()) { + for each (auto sItem in subRoot) { + auto folderPath = Path(sItem); + auto attributes = FILE_ATTRIBUTE_DIRECTORY; + File::FileInfo info; + info.name = folderPath.GetFilename(); + info.fullName = folderPath; + info.exists = true; + info.size = 1; + info.isDirectory = true; + info.isWritable = (attributes & FILE_ATTRIBUTE_READONLY) == 0; + info.atime = 1000; + info.mtime = 1000; + info.ctime = 1000; + if (attributes & FILE_ATTRIBUTE_READONLY) { + info.access = 0444; // Read + } + else { + info.access = 0666; // Read/Write + } + if (attributes & FILE_ATTRIBUTE_DIRECTORY) { + info.access |= 0111; // Execute + } + if (!info.isDirectory) { + std::string ext = info.fullName.GetFileExtension(); + if (!ext.empty()) { + ext = ext.substr(1); // Remove the dot. + if (filter && filters.find(ext) == filters.end()) { + continue; + } + } + } + files->push_back(info); + state = true; + } } } - return info; + return state; } + #pragma endregion -#pragma region Basics -int64_t GetSizeUWP(std::string path) { - int64_t size = 0; - if (IsValidUWP(path)) { - auto storageItem = GetStorageItem(path); - if (storageItem.IsValid()) { - size = storageItem.GetSize(); - } - else { - ERROR_LOG(FILESYS, "Couldn't find or access (%s)", path.c_str()); - } - } - return size; -} - -bool DeleteUWP(std::string path) { - bool state = false; - if (IsValidUWP(path)) { - auto storageItem = GetStorageItem(path); - if (storageItem.IsValid()) { - DEBUG_LOG(FILESYS, "Delete (%s)", path.c_str()); - state = storageItem.Delete(); - } - else { - DEBUG_LOG(FILESYS, "Couldn't find or access (%s)", path.c_str()); - } - } - - return state; -} - -bool CreateDirectoryUWP(std::string path, bool replaceExisting) { - bool state = false; - auto p = PathUWP(path); - auto itemName = p.GetFilename(); - auto rootPath = p.GetDirectory(); - - if (IsValidUWP(rootPath)) { - auto storageItem = GetStorageItem(rootPath); - if (storageItem.IsValid()) { - DEBUG_LOG(FILESYS, "Create new folder (%s)", path.c_str()); - state = storageItem.CreateFolder(itemName, replaceExisting); - } - else { - ERROR_LOG(FILESYS, "Couldn't find or access (%s)", rootPath.c_str()); - } - } - - return state; -} - -bool CopyUWP(std::string path, std::string dest) { - bool state = false; - - if (IsValidUWP(path) && IsValidUWP(dest)) { - auto srcStorageItem = GetStorageItem(path); - if (srcStorageItem.IsValid()) { - auto destDir = dest; - auto srcName = srcStorageItem.GetName(); - auto dstPath = PathUWP(dest); - auto dstName = dstPath.GetFilename(); - // Destination must be parent folder - destDir = dstPath.GetDirectory(); - auto dstStorageItem = GetStorageItem(destDir, true, true); - if (dstStorageItem.IsValid()) { - DEBUG_LOG(FILESYS, "Copy (%s) to (%s)", path.c_str(), dest.c_str()); - state = srcStorageItem.Copy(dstStorageItem, dstName); - } - else { - ERROR_LOG(FILESYS, "Couldn't find or access (%s)", dest.c_str()); - } - } - else { - ERROR_LOG(FILESYS, "Couldn't find or access (%s)", path.c_str()); - } - } - - return state; -} - -bool MoveUWP(std::string path, std::string dest) { - bool state = false; - - if (IsValidUWP(path) && IsValidUWP(dest)) { - auto srcStorageItem = GetStorageItem(path); - - if (srcStorageItem.IsValid()) { - auto destDir = dest; - auto srcName = srcStorageItem.GetName(); - auto dstPath = PathUWP(dest); - auto dstName = dstPath.GetFilename(); - // Destination must be parent folder - destDir = dstPath.GetDirectory(); - auto dstStorageItem = GetStorageItem(destDir, true, true); - if (dstStorageItem.IsValid()) { - DEBUG_LOG(FILESYS, "Move (%s) to (%s)", path.c_str(), dest.c_str()); - state = srcStorageItem.Move(dstStorageItem, dstName); - } - else { - ERROR_LOG(FILESYS, "Couldn't find or access (%s)", dest.c_str()); - } - } - else { - ERROR_LOG(FILESYS, "Couldn't find or access (%s)", path.c_str()); - } - } - - return state; -} - -bool RenameUWP(std::string path, std::string name) { - bool state = false; - - auto srcRoot = PathUWP(path).GetDirectory(); - auto dstRoot = PathUWP(name).GetDirectory(); - // Check if system using rename to move - if (iequals(srcRoot, dstRoot)) { - auto srcStorageItem = GetStorageItem(path); - if (srcStorageItem.IsValid()) { - DEBUG_LOG(FILESYS, "Rename (%s) to (%s)", path.c_str(), name.c_str()); - state = srcStorageItem.Rename(name); - } - else { - DEBUG_LOG(FILESYS, "Couldn't find or access (%s)", path.c_str()); - } - } - else { - DEBUG_LOG(FILESYS, " Rename used as move -> call move (%s) to (%s)", path.c_str(), name.c_str()); - state = MoveUWP(path, name); - } - - return state; -} -#pragma endregion - - #pragma region Helpers bool OpenFile(std::string path) { bool state = false; + path = ReplaceAll(path, "/", "\\"); - auto storageItem = GetStorageItem(path); - if (storageItem.IsValid()) { - if (!storageItem.IsDirectory()) { - ExecuteTask(state, Windows::System::Launcher::LaunchFileAsync(storageItem.GetStorageFile()), false); - } + StorageFile^ storageItem; + ExecuteTask(storageItem, StorageFile::GetFileFromPathAsync(ToPlatformString(path))); + if (storageItem != nullptr) { + ExecuteTask(state, Windows::System::Launcher::LaunchFileAsync(storageItem), false); } else { - auto uri = ref new Windows::Foundation::Uri(convert(path)); + auto uri = ref new Windows::Foundation::Uri(ToPlatformString(path)); ExecuteTask(state, Windows::System::Launcher::LaunchUriAsync(uri), false); } return state; @@ -759,16 +301,12 @@ bool OpenFile(std::string path) { bool OpenFolder(std::string path) { bool state = false; - auto uri = ref new Windows::Foundation::Uri(convert(path)); - - auto storageItem = GetStorageItem(path); - if (storageItem.IsValid()) { - if (storageItem.IsDirectory()) { - ExecuteTask(state, Windows::System::Launcher::LaunchFolderAsync(storageItem.GetStorageFolder()), false); - } - else { - OpenFile(storageItem.GetPath()); - } + path = ReplaceAll(path, "/", "\\"); + + StorageFolder^ storageItem; + ExecuteTask(storageItem, StorageFolder::GetFolderFromPathAsync(ToPlatformString(path))); + if (storageItem != nullptr) { + ExecuteTask(state, Windows::System::Launcher::LaunchFolderAsync(storageItem), false); } return state; } @@ -781,89 +319,13 @@ bool IsFirstStart() { #pragma endregion #pragma region Logs -// Get log file name -std::string currentLogFile; -std::string getLogFileName() { - //Initial new name each session/launch - if (currentLogFile.empty() || currentLogFile.size() == 0) { - std::time_t now = std::time(0); - char mbstr[100]; - std::strftime(mbstr, 100, "ppsspp %d-%m-%Y (%T).txt", std::localtime(&now)); - std::string formatedDate(mbstr); - std::replace(formatedDate.begin(), formatedDate.end(), ':', '-'); - currentLogFile = formatedDate; - } - - return currentLogFile; -} - -// Get current log file location -StorageFolder^ GetLogsStorageFolder() { - // Ensure 'LOGS' folder is created - auto workingFolder = GetStorageItem(GetWorkingFolder()); - StorageFolder^ logsFolder; - if (workingFolder.IsValid()) { - auto workingStorageFolder = workingFolder.GetStorageFolder(); - ExecuteTask(logsFolder, workingStorageFolder->CreateFolderAsync("LOGS", CreationCollisionOption::OpenIfExists)); - } - return logsFolder; -} std::string GetLogFile() { - std::string logFilePath = ""; - - // Ensure 'LOGS' folder is created - StorageFolder^ logsFolder = GetLogsStorageFolder(); - - if (logsFolder != nullptr) { - auto logFileName = convert(getLogFileName()); - StorageFile^ logFile; - ExecuteTask(logFile, logsFolder->CreateFileAsync(logFileName, CreationCollisionOption::OpenIfExists)); - - if (logFile != nullptr) { - logFilePath = convert(logFile->Path); - } + Path logFilePath = Path(GetWorkingFolder() + "\\PSP\\ppsspp.txt"); + HANDLE h = CreateFile2FromAppW(logFilePath.ToWString().c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, CREATE_ALWAYS, nullptr); + if (h == INVALID_HANDLE_VALUE) { + return std::string(); } - - return logFilePath; + return logFilePath.ToString(); } -// Save logs to folder selected by the user -bool SaveLogs() { - try { - auto folderPicker = ref new Windows::Storage::Pickers::FolderPicker(); - folderPicker->SuggestedStartLocation = Windows::Storage::Pickers::PickerLocationId::Desktop; - folderPicker->FileTypeFilter->Append("*"); - - StorageFolder^ saveFolder; - ExecuteTask(saveFolder, folderPicker->PickSingleFolderAsync()); - - if (saveFolder != nullptr) { - StorageFolder^ logsFolder = GetLogsStorageFolder(); - - if (logsFolder != nullptr) { - StorageFolderW logsCache(logsFolder); - logsCache.Copy(saveFolder); - } - } - } - catch (...) { - return false; - } - return true; -} - -void CleanupLogs() { - StorageFolder^ logsFolder = GetLogsStorageFolder(); - if (logsFolder != nullptr) { - StorageFolderW logsCache(logsFolder); - std::list files = logsCache.GetFiles(); - if (!files.empty()) { - for each (auto fItem in files) { - if (fItem.GetSize() == 0) { - fItem.Delete(); - } - } - } - } -} #pragma endregion diff --git a/UWP/UWPHelpers/StorageManager.h b/UWP/UWPHelpers/StorageManager.h index 4f3c55c888..5930547891 100644 --- a/UWP/UWPHelpers/StorageManager.h +++ b/UWP/UWPHelpers/StorageManager.h @@ -4,56 +4,18 @@ // Telegram: @basharastifan // GitHub: https://github.com/basharast/UWP2Win32 -// Functions: -// GetWorkingFolder() -// SetWorkingFolder(std::string location) -// GetInstallationFolder() -// GetLocalFolder() -// GetTempFolder() -// GetPicturesFolder() -// GetVideosFolder() -// GetDocumentsFolder() -// GetMusicFolder() -// GetPreviewPath(std::string path) -// -// CreateFileUWP(std::string path, int accessMode, int shareMode, int openMode) -// CreateFileUWP(std::wstring path, int accessMode, int shareMode, int openMode) -// GetFileStream(std::string path, const char* mode) -// IsValidUWP(std::string path) -// IsExistsUWP(std::string path) -// IsDirectoryUWP(std::string path) -// -// GetFolderContents(std::string path, T& files) -// GetFolderContents(std::wstring path, T& files) -// GetFileInfoUWP(std::string path, T& info) -// -// GetSizeUWP(std::string path) -// DeleteUWP(std::string path) -// CreateDirectoryUWP(std::string path, bool replaceExisting) -// RenameUWP(std::string path, std::string name) -// CopyUWP(std::string path, std::string name) -// MoveUWP(std::string path, std::string name) -// -// OpenFile(std::string path) -// OpenFolder(std::string path) -// IsFirstStart() -// -// GetLogFile() -// SaveLogs() -// CleanupLogs() - #pragma once #include +#include + +#include "Common/File/DirListing.h" -#include "StoragePath.h" -#include "StorageInfo.h" #include "StorageAccess.h" #include "StoragePickers.h" // Locations std::string GetWorkingFolder(); // Where main data is, default is app data -void SetWorkingFolder(std::string location); // Change working location std::string GetInstallationFolder(); std::string GetLocalFolder(); std::string GetTempFolder(); @@ -66,32 +28,13 @@ std::string GetPreviewPath(std::string path); bool isLocalState(std::string path); // Management -HANDLE CreateFileUWP(std::string path, int accessMode = GENERIC_READ, int shareMode = FILE_SHARE_READ, int openMode = OPEN_EXISTING); -HANDLE CreateFileUWP(std::wstring path, int accessMode = GENERIC_READ, int shareMode = FILE_SHARE_READ, int openMode = OPEN_EXISTING); -FILE* GetFileStream(std::string path, const char* mode); // `GetFileStreamFromApp` Will use Windows UWP API, use it instead of fopen..etc FILE* GetFileStreamFromApp(std::string path, const char* mode); -bool IsValidUWP(std::string path); -bool IsExistsUWP(std::string path); -bool IsDirectoryUWP(std::string path); -std::list GetFolderContents(std::string path, bool deepScan = false); -std::list GetFolderContents(std::wstring path, bool deepScan = false); -ItemInfoUWP GetItemInfoUWP(std::string path); -bool IsContainsAccessibleItems(std::string path); +// 'driveName' like C: +bool CheckDriveAccess(std::string driveName); +bool GetFakeFolders(Path path, std::vector* files, const char* filter, std::set filters); bool IsRootForAccessibleItems(std::string path); -// 'checkIfContainsFutureAccessItems' for listing purposes not real access, 'driveName' like C: -bool CheckDriveAccess(std::string driveName, bool checkIfContainsFutureAccessItems); - -// Basics -int64_t GetSizeUWP(std::string path); -bool DeleteUWP(std::string path); -bool CreateDirectoryUWP(std::string path, bool replaceExisting = true); -bool RenameUWP(std::string path, std::string name); -// Add file name to destination path -bool CopyUWP(std::string path, std::string dest); -// Add file name to destination path -bool MoveUWP(std::string path, std::string dest); // Helpers bool OpenFile(std::string path); @@ -101,6 +44,3 @@ std::string ResolvePathUWP(std::string path); // Log helpers std::string GetLogFile(); -bool SaveLogs(); // With picker -void CleanupLogs(); - diff --git a/UWP/UWPHelpers/StoragePath.cpp b/UWP/UWPHelpers/StoragePath.cpp deleted file mode 100644 index 77f9189225..0000000000 --- a/UWP/UWPHelpers/StoragePath.cpp +++ /dev/null @@ -1,272 +0,0 @@ -// UWP STORAGE MANAGER -// Based on 'Path' from PPSSPP -// For updates check: https://github.com/basharast/UWP2Win32 - -#include -#include -#include - -#include "StoragePath.h" -#include "StorageLog.h" -#include "StorageExtensions.h" - -PathUWP::PathUWP(const std::string &str) { - Init(str); -} - -PathUWP::PathUWP(const std::wstring &str) { - type_ = PathTypeUWP::NATIVE; - Init(convert(str)); -} - -void PathUWP::Init(const std::string &str) { - if (str.empty()) { - type_ = PathTypeUWP::UNDEFINED; - path_.clear(); - } else if (starts_with(str, "http://") || starts_with(str, "https://")) { - type_ = PathTypeUWP::HTTP; - path_ = str; - } else { - type_ = PathTypeUWP::NATIVE; - path_ = str; - } - - // Flip all the slashes around. We flip them back on ToWString(). - for (size_t i = 0; i < path_.size(); i++) { - if (path_[i] == '\\') { - path_[i] = '/'; - } - } - - // Don't pop_back if it's just "/". - if (type_ == PathTypeUWP::NATIVE && path_.size() > 1 && path_.back() == '/') { - path_.pop_back(); - } -} - -// We always use forward slashes internally, we convert to backslash only when -// converted to a wstring. -PathUWP PathUWP::operator /(const std::string &subdir) const { - // Direct string manipulation. - - if (subdir.empty()) { - return PathUWP(path_); - } - std::string fullPath = path_; - if (subdir.front() != '/' && (fullPath.empty() || fullPath.back() != '/')) { - fullPath += "/"; - } - fullPath += subdir; - // Prevent adding extra slashes. - if (fullPath.back() == '/') { - fullPath.pop_back(); - } - return PathUWP(fullPath); -} - -void PathUWP::operator /=(const std::string &subdir) { - *this = *this / subdir; -} - -PathUWP PathUWP::WithExtraExtension(const std::string &ext) const { - return PathUWP(path_ + ext); -} - -PathUWP PathUWP::WithReplacedExtension(const std::string &oldExtension, const std::string &newExtension) const { - if (ends_with(path_, oldExtension)) { - std::string newPath = path_.substr(0, path_.size() - oldExtension.size()); - return PathUWP(newPath + newExtension); - } else { - return PathUWP(*this); - } -} - -PathUWP PathUWP::WithReplacedExtension(const std::string &newExtension) const { - if (path_.empty()) { - return PathUWP(*this); - } - std::string extension = GetFileExtension(); - std::string newPath = path_.substr(0, path_.size() - extension.size()) + newExtension; - return PathUWP(newPath); -} - -std::string PathUWP::GetFilename() const { - size_t pos = path_.rfind('/'); - if (pos != std::string::npos) { - return path_.substr(pos + 1); - } - return path_; -} - -static std::string GetExtFromString(const std::string &str) { - size_t pos = str.rfind("."); - if (pos == std::string::npos) { - return ""; - } - size_t slash_pos = str.rfind("/"); - if (slash_pos != std::string::npos && slash_pos > pos) { - // Don't want to detect "df/file" from "/as.df/file" - return ""; - } - std::string ext = str.substr(pos); - for (size_t i = 0; i < ext.size(); i++) { - ext[i] = tolower(ext[i]); - } - return ext; -} - -std::string PathUWP::GetFileExtension() const { - return GetExtFromString(path_); -} - -std::string PathUWP::GetDirectory() const { - size_t pos = path_.rfind('/'); - if (type_ == PathTypeUWP::HTTP) { - // Things are a bit different for HTTP, because we probably ended with /. - if (pos + 1 == path_.size()) { - pos = path_.rfind('/', pos - 1); - if (pos != path_.npos && pos > 8) { - return path_.substr(0, pos + 1); - } - } - } - - if (pos != std::string::npos) { - if (pos == 0) { - return "/"; // We're at the root. - } - return path_.substr(0, pos); - } else if (path_.size() == 2 && path_[1] == ':') { - // Windows fake-root. - return "/"; - } else { - // There could be a ':', too. Unlike the slash, let's include that - // in the returned directory. - size_t c_pos = path_.rfind(':'); - if (c_pos != std::string::npos) { - return path_.substr(0, c_pos + 1); - } - } - // No directory components, we're a relative path. - return path_; -} - -bool PathUWP::FilePathContainsNoCase(const std::string &needle) const { - std::string haystack; - - haystack = path_; - auto pred = [](char ch1, char ch2) { return std::toupper(ch1) == std::toupper(ch2); }; - auto found = std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), pred); - return found != haystack.end(); -} - -bool PathUWP::StartsWith(const PathUWP &other) const { - if (type_ != other.type_) { - // Bad - return false; - } - return starts_with(path_, other.path_); -} - -const std::string &PathUWP::ToString() const { - return path_; -} - -std::wstring PathUWP::ToWString() const { - std::wstring w = convertToWString(path_); - for (size_t i = 0; i < w.size(); i++) { - if (w[i] == '/') { - w[i] = '\\'; - } - } - return w; -} - -std::string PathUWP::ToVisualString() const { - if (type_ == PathTypeUWP::NATIVE) { - return replace2(path_, "/", "\\"); - } else { - return path_; - } -} - -bool PathUWP::CanNavigateUp() const { - if (path_ == "/" || path_.empty()) { - return false; - } - if (type_ == PathTypeUWP::HTTP) { - size_t rootSlash = path_.find_first_of('/', strlen("https://")); - if (rootSlash == path_.npos || path_.size() < rootSlash + 1) { - // This means, "http://server" or "http://server/". Can't go up. - return false; - } - } - return true; -} - -PathUWP PathUWP::NavigateUp() const { - std::string dir = GetDirectory(); - return PathUWP(dir); -} - -PathUWP PathUWP::GetRootVolume() const { - if (!IsAbsolute()) { - // Can't do anything - return PathUWP(path_); - } - - if (path_[1] == ':') { - // Windows path with drive letter - std::string path = path_.substr(0, 2); - return PathUWP(path); - } - // Support UNC and device paths. - if (path_[0] == '/' && path_[1] == '/') { - size_t next = 2; - if ((path_[2] == '.' || path_[2] == '?') && path_[3] == '/') { - // Device path, or "\\.\UNC" path, skip the dot and consider the device the root. - next = 4; - } - - size_t len = path_.find_first_of('/', next); - return PathUWP(path_.substr(0, len)); - } - return PathUWP("/"); -} - -bool PathUWP::IsAbsolute() const { - if (path_.empty()) - return true; - else if (path_.front() == '/') - return true; - else if (path_.size() > 3 && path_[1] == ':') - return true; // Windows path with drive letter - else - return false; -} - -bool PathUWP::ComputePathTo(const PathUWP &other, std::string &path) const { - if (other == *this) { - path.clear(); - return true; - } - - if (!other.StartsWith(*this)) { - // Can't do this. Should return an error. - return false; - } - - if (*this == other) { - // Equal, the path is empty. - path.clear(); - return true; - } - - if (path_ == "/") { - path = other.path_.substr(1); - return true; - } else { - path = other.path_.substr(path_.size() + 1); - return true; - } -} diff --git a/UWP/UWPHelpers/StoragePath.h b/UWP/UWPHelpers/StoragePath.h deleted file mode 100644 index 94d6e79405..0000000000 --- a/UWP/UWPHelpers/StoragePath.h +++ /dev/null @@ -1,113 +0,0 @@ -// UWP STORAGE MANAGER -// Based on 'Path' from PPSSPP -// For updates check: https://github.com/basharast/UWP2Win32 - -#pragma once - -#include - -#define HOST_IS_CASE_SENSITIVE 0 - -enum class PathTypeUWP { - UNDEFINED = 0, - NATIVE = 1, // Can be relative. - CONTENT_URI = 2, // Android only. Can only be absolute! - HTTP = 3, // http://, https:// -}; - -// Windows paths are always stored with '/' slashes in a Path. -// On .ToWString(), they are flipped back to '\'. - -class PathUWP { -private: - void Init(const std::string &str); - -public: - PathUWP() : type_(PathTypeUWP::UNDEFINED) {} - explicit PathUWP(const std::string &str); - - explicit PathUWP(const std::wstring &str); - - PathTypeUWP Type() const { - return type_; - } - - bool Valid() const { return !path_.empty(); } - bool IsRoot() const { return path_ == "/"; } // Special value - only path that can end in a slash. - - // Some std::string emulation for simplicity. - bool empty() const { return !Valid(); } - void clear() { - type_ = PathTypeUWP::UNDEFINED; - path_.clear(); - } - size_t size() const { - return path_.size(); - } - - // WARNING: Potentially unsafe usage, if it's not NATIVE. - const char *c_str() const { - return path_.c_str(); - } - - bool IsAbsolute() const; - - // Returns a path extended with a subdirectory. - PathUWP operator /(const std::string &subdir) const; - - // Navigates down into a subdir. - void operator /=(const std::string &subdir); - - // File extension manipulation. - PathUWP WithExtraExtension(const std::string &ext) const; - PathUWP WithReplacedExtension(const std::string &oldExtension, const std::string &newExtension) const; - PathUWP WithReplacedExtension(const std::string &newExtension) const; - - // Removes the last component. - std::string GetFilename() const; // Really, GetLastComponent. Could be a file or directory. Includes the extension. - std::string GetFileExtension() const; // Always lowercase return. Includes the dot. - std::string GetDirectory() const; - - const std::string &ToString() const; - - std::wstring ToWString() const; - - std::string ToVisualString() const; - - bool CanNavigateUp() const; - PathUWP NavigateUp() const; - - // Navigates as far up as possible from this path. If not possible to navigate upwards, returns the same path. - // Not actually always the root of the volume, especially on systems like Mac and Linux where things are often mounted. - // For Android directory trees, navigates to the root of the tree. - PathUWP GetRootVolume() const; - - bool ComputePathTo(const PathUWP&other, std::string &path) const; - - bool operator ==(const PathUWP&other) const { - return path_ == other.path_ && type_ == other.type_; - } - bool operator !=(const PathUWP&other) const { - return path_ != other.path_ || type_ != other.type_; - } - - bool FilePathContainsNoCase(const std::string &needle) const; - - bool StartsWith(const PathUWP&other) const; - - bool operator <(const PathUWP&other) const { - return path_ < other.path_; - } - bool operator >(const PathUWP&other) const { - return path_ > other.path_; - } - -private: - // The internal representation is currently always the plain string. - // For CPU efficiency we could keep an AndroidStorageContentURI too, - // but I don't think the encode/decode cost is significant. We simply create - // those for processing instead. - std::string path_; - - PathTypeUWP type_; -}; diff --git a/UWP/UWPHelpers/StoragePickers.cpp b/UWP/UWPHelpers/StoragePickers.cpp index 4795e7e0f2..e61808c180 100644 --- a/UWP/UWPHelpers/StoragePickers.cpp +++ b/UWP/UWPHelpers/StoragePickers.cpp @@ -3,14 +3,8 @@ // Email: bashar@astifan.online // Telegram: @basharastifan -// Functions: -// ChooseFolder() -// ChooseFile(std::vector exts) - #include "pch.h" -#include "StorageLog.h" -#include "StorageExtensions.h" #include "StorageAsync.h" #include "StorageAccess.h" @@ -47,7 +41,7 @@ concurrency::task PickSingleFile(std::vector ext if (exts.size() > 0) { for each (auto ext in exts) { - filePicker->FileTypeFilter->Append(convert(ext)); + filePicker->FileTypeFilter->Append(ToPlatformString(ext)); } } else @@ -68,13 +62,13 @@ concurrency::task PickSingleFile(std::vector ext concurrency::task ChooseFile(std::vector exts) { return PickSingleFile(exts).then([](Platform::String^ filePath) { - return convert(filePath); + return FromPlatformString(filePath); }); } concurrency::task ChooseFolder() { return PickSingleFolder().then([](Platform::String^ folderPath) { - return convert(folderPath); + return FromPlatformString(folderPath); }); } diff --git a/UWP/UWPHelpers/StoragePickers.h b/UWP/UWPHelpers/StoragePickers.h index 601a942510..9b22c01e4b 100644 --- a/UWP/UWPHelpers/StoragePickers.h +++ b/UWP/UWPHelpers/StoragePickers.h @@ -3,10 +3,6 @@ // Email: bashar@astifan.online // Telegram: @basharastifan -// Functions: -// ChooseFolder() -// ChooseFile(std::vector exts) - #pragma once #include diff --git a/UWP/UWPHelpers/UWP2C.cpp b/UWP/UWPHelpers/UWP2C.cpp deleted file mode 100644 index bdddac39be..0000000000 --- a/UWP/UWPHelpers/UWP2C.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan -// GitHub: https://github.com/basharast/UWP2Win32 - -// This is small bridge to invoke UWP Storage manager - -// Functions: -// CreateFileUWP(const char* path, int accessMode, int shareMode, int openMode) -// GetFileAttributesUWP(const void* name, void* lpFileInformation) -// DeleteFileUWP(const void* name) - -#include "UWP2C.h" -#include "StorageManager.h" -#include "StorageExtensions.h" - -#ifdef __cplusplus -extern "C" { -#endif -void* CreateFileUWP(const char* path, int accessMode, int shareMode, int openMode) { - std::string fn = convert(path); - - return (void*)CreateFileUWP(fn, accessMode, shareMode, openMode); -} - -int GetFileAttributesUWP(const void* name, void* lpFileInformation) { - size_t size = sizeof(WIN32_FILE_ATTRIBUTE_DATA); - WIN32_FILE_ATTRIBUTE_DATA* file_attributes = (WIN32_FILE_ATTRIBUTE_DATA*)(malloc(size)); - - std::string fn = convert((const char*)name); - HANDLE handle = CreateFileUWP(fn); - - FILETIME createTime{}; - FILETIME changeTime{}; - - DWORD fileSizeHigh = 0; - DWORD fileSizeLow = 0; - DWORD fileAttributes = 32; - - if (handle != INVALID_HANDLE_VALUE) { - size_t size = sizeof(FILE_BASIC_INFO); - FILE_BASIC_INFO* information = (FILE_BASIC_INFO*)(malloc(size)); - if (information) { - if (FALSE != GetFileInformationByHandleEx(handle, FileBasicInfo, information, (DWORD)size)) { - createTime.dwHighDateTime = information->CreationTime.HighPart; - createTime.dwLowDateTime = information->CreationTime.LowPart; - changeTime.dwHighDateTime = information->ChangeTime.HighPart; - changeTime.dwLowDateTime = information->ChangeTime.LowPart; - fileAttributes = information->FileAttributes; - } - } - LARGE_INTEGER fsize{ 0 }; - if (FALSE == GetFileSizeEx(handle, &fsize)) { - LARGE_INTEGER end_offset; - const LARGE_INTEGER zero{}; - if (SetFilePointerEx(handle, zero, &end_offset, FILE_END) == 0) { - CloseHandle(handle); - } - else { - fileSizeHigh = (DWORD)end_offset.HighPart; - fileSizeLow = (DWORD)end_offset.LowPart; - SetFilePointerEx(handle, zero, nullptr, FILE_BEGIN); - CloseHandle(handle); - } - } - else { - fileSizeHigh = (DWORD)fsize.HighPart; - fileSizeLow = (DWORD)fsize.LowPart; - - CloseHandle(handle); - } - } - - ((WIN32_FILE_ATTRIBUTE_DATA*)lpFileInformation)->ftCreationTime = createTime; - ((WIN32_FILE_ATTRIBUTE_DATA*)lpFileInformation)->ftLastAccessTime = changeTime; - ((WIN32_FILE_ATTRIBUTE_DATA*)lpFileInformation)->ftLastWriteTime = changeTime; - ((WIN32_FILE_ATTRIBUTE_DATA*)lpFileInformation)->nFileSizeHigh = fileSizeHigh; - ((WIN32_FILE_ATTRIBUTE_DATA*)lpFileInformation)->nFileSizeLow = fileSizeLow; - ((WIN32_FILE_ATTRIBUTE_DATA*)lpFileInformation)->dwFileAttributes = fileAttributes; - - return 1; -} - -int DeleteFileUWP(const void* name) { - std::string fn = convert((const char*)name); - bool state = DeleteUWP(fn); - - return state ? 1 : 0; -} -#ifdef __cplusplus -} -#endif diff --git a/UWP/UWPHelpers/UWP2C.h b/UWP/UWPHelpers/UWP2C.h deleted file mode 100644 index baa56f710d..0000000000 --- a/UWP/UWPHelpers/UWP2C.h +++ /dev/null @@ -1,26 +0,0 @@ -// UWP STORAGE MANAGER -// Copyright (c) 2023 Bashar Astifan. -// Email: bashar@astifan.online -// Telegram: @basharastifan -// GitHub: https://github.com/basharast/UWP2Win32 - -// This is small bridge to invoke UWP Storage manager - -// Functions: -// CreateFileUWP(const char* path, int accessMode, int shareMode, int openMode) -// GetFileAttributesUWP(const void* name, void* lpFileInformation) -// DeleteFileUWP(const void* name) - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -void* CreateFileUWP(const char* path, int accessMode, int shareMode, int openMode); -int GetFileAttributesUWP(const void* name, void* lpFileInformation); -int DeleteFileUWP(const void* name); - -#ifdef __cplusplus -} -#endif diff --git a/ext/libzip/zip_source_file_win32_utf16.c b/ext/libzip/zip_source_file_win32_utf16.c index 7e0e377852..8a179cd78b 100644 --- a/ext/libzip/zip_source_file_win32_utf16.c +++ b/ext/libzip/zip_source_file_win32_utf16.c @@ -32,9 +32,6 @@ */ #ifdef MS_UWP #include -#if !defined(__LIBRETRO__) -#include "UWP/UWPHelpers/UWP2C.h" -#endif #endif #include "zip_source_file_win32.h" @@ -47,18 +44,11 @@ static char *utf16_strdup(const char *string); #ifdef MS_UWP && !defined(__LIBRETRO__) static BOOL __stdcall GetFileAttr(const void* name, GET_FILEEX_INFO_LEVELS info_level, void* lpFileInformation) { BOOL state = GetFileAttributesExFromAppW(name, info_level, lpFileInformation); - if (state == FALSE) { - // Ignore `info_level` not in use for now - state = GetFileAttributesUWP(name, lpFileInformation); - } return state; } static BOOL __stdcall DelFile(const void* name) { BOOL state = DeleteFileFromAppW(name); - if (state == FALSE) { - state = DeleteFileUWP(name); - } return state; } @@ -130,11 +120,6 @@ utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_AT return CreateFile2((const wchar_t *)name, access, share_mode, creation_disposition, &extParams); #else HANDLE h = CreateFile2FromAppW((const wchar_t *)name, access, share_mode, creation_disposition, NULL); -#if !defined(__LIBRETRO__) - if (h == INVALID_HANDLE_VALUE) { - h = CreateFileUWP(name, (int)access, (int)share_mode, (int)creation_disposition); - } -#endif return h; #endif #else