From ac1501c3578b318f9bd938c0cdf62b83d13c3c00 Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Sun, 10 Mar 2024 15:00:13 +0000 Subject: [PATCH] [+] AuOptional AuFS::NewTempFile() [+] AuOptional AuFS::NewTempDirectory() --- Include/Aurora/IO/FS/Resources.hpp | 4 ++ Source/AuProcAddresses.NT.cpp | 3 ++ Source/AuProcAddresses.NT.hpp | 6 +++ Source/IO/FS/Resources.cpp | 85 ++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+) diff --git a/Include/Aurora/IO/FS/Resources.hpp b/Include/Aurora/IO/FS/Resources.hpp index beeadfa3..af84b1ba 100644 --- a/Include/Aurora/IO/FS/Resources.hpp +++ b/Include/Aurora/IO/FS/Resources.hpp @@ -62,4 +62,8 @@ namespace Aurora::IO::FS * @brief Get user installable application directory */ AUKN_SYM bool GetUserProgramsFolder(AuString &path); + + AUKN_SYM AuOptional NewTempFile(); + + AUKN_SYM AuOptional NewTempDirectory(); } \ No newline at end of file diff --git a/Source/AuProcAddresses.NT.cpp b/Source/AuProcAddresses.NT.cpp index 7665487a..88e27080 100644 --- a/Source/AuProcAddresses.NT.cpp +++ b/Source/AuProcAddresses.NT.cpp @@ -249,6 +249,7 @@ namespace Aurora ADD_GET_PROC_BI(Kernel32, KernelBase, UnmapViewOfFile2) ADD_GET_PROC_BI(Kernel32, KernelBase, CreateFileW) ADD_GET_PROC_BI(Kernel32, KernelBase, CreateFile2W) + ADD_GET_PROC_BI(Kernel32, KernelBase, GetTempPathW) ADD_GET_PROC(Kernel32, GetSystemCpuSetInformation) ADD_GET_PROC(Kernel32, GetLogicalProcessorInformation) @@ -434,6 +435,8 @@ namespace Aurora pFindClose = FindClose; + pGetTempPathW = GetTempPath2W; + pGetSystemCpuSetInformation = GetSystemCpuSetInformation; pGetLogicalProcessorInformation = GetLogicalProcessorInformation; diff --git a/Source/AuProcAddresses.NT.hpp b/Source/AuProcAddresses.NT.hpp index 4e609abc..6f240de7 100644 --- a/Source/AuProcAddresses.NT.hpp +++ b/Source/AuProcAddresses.NT.hpp @@ -296,6 +296,12 @@ namespace Aurora inline PVOID(__stdcall *pAddDllDirectory)( PCWSTR NewDirectory ); + + inline DWORD(__stdcall *pGetTempPathW)( + DWORD nBufferLength, + LPWSTR lpBuffer + ); + inline BOOL(__stdcall *pPrefetchVirtualMemory)( HANDLE hProcess, ULONG_PTR NumberOfEntries, diff --git a/Source/IO/FS/Resources.cpp b/Source/IO/FS/Resources.cpp index 30517d72..c059c148 100644 --- a/Source/IO/FS/Resources.cpp +++ b/Source/IO/FS/Resources.cpp @@ -36,6 +36,7 @@ namespace Aurora::IO::FS static AuOptional gSystemLibPath2; static AuOptional gUserLibPath; static AuOptional gUserLibPath2; + static AuString gTempDir; // Should the following be /opt? Probably, if it were a direct replacement for Windows' appdata on Linux for global software packages outside of our ecosystem, sure; however, this is strictly a fallback for when there is no home // We don't support initially-undefined global application configurations across users on Unix targets. We can therefore conclue the application running is a service whose user is without a home, and should be subject to the same rules as an application deployed by a real package manager // For internal packages, in our own ecosystem of tools, I think this follows the UNIX spec, not that I care what arcahic C-with-vendor-packages-as-an-OS specification says. @@ -127,6 +128,11 @@ namespace Aurora::IO::FS return CSIDL_COMMON_APPDATA; } + if (rfid == FOLDERID_Documents) + { + return CSIDL_COMMON_DOCUMENTS; + } + if (rfid == FOLDERID_System || rfid == FOLDERID_SystemX86) { @@ -220,6 +226,20 @@ namespace Aurora::IO::FS } } } + + if (pGetTempPathW) + { + wchar_t tempPath[2048]; + if (auto uLength = pGetTempPathW(AuArraySize(tempPath), tempPath)) + { + gTempDir = AuLocale::ConvertFromWChar(tempPath, uLength); + } + } + + if (gTempDir.empty()) + { + gTempDir = GetSpecialDir(FOLDERID_Documents) + "/Temp/"; + } } #elif defined(AURORA_PLATFORM_LINUX) || defined(AURORA_PLATFORM_BSD) @@ -299,6 +319,13 @@ namespace Aurora::IO::FS gGlobalWritableAppDirectory = "/opt"; gAdminWritableAppDirectory = kUnixAppData; gUserWritableAppData = gApplicationData; + + // iOS/MacOS : NSTemporaryDirectory + #if defined(AURORA_PLATFORM_ANDROID) + gTempDir = "/data/local/tmp/"; + #else + gTempDir = "/tmp/"; + #endif } #else @@ -493,6 +520,64 @@ namespace Aurora::IO::FS return path.size(); } + AUKN_SYM AuOptional NewTempFile() + { + AuString path; + + path = gTempDir; + if (path.empty()) + { + SysPushErrorUninitialized(); + return {}; + } + + path += fmt::format("TempFile_{}", AuRNG::ReadString(128, AuRNG::ERngStringCharacters::eNumericCharacters)); + + if (!AuFS::WriteNewFile(path, {})) + { + SysPushErrorIO(); + return {}; + } + + auto normalizedPath = AuFS::NormalizePathRet(path); + + #if defined(AURORA_PLATFORM_WIN32) + auto widePath = AuLocale::ConvertFromUTF8(normalizedPath); + MoveFileExW(widePath.c_str(), nullptr, MOVEFILE_DELAY_UNTIL_REBOOT); + #endif + + return normalizedPath; + } + + AUKN_SYM AuOptional NewTempDirectory() + { + AuString path; + + path = gTempDir; + if (path.empty()) + { + SysPushErrorUninitialized(); + return {}; + } + + path += fmt::format("TempDirectory_{}", AuRNG::ReadString(64, AuRNG::ERngStringCharacters::eNumericCharacters)); + + if (!_MkDir(path)) + { + SysPushErrorIO(); + return {}; + } + + auto normalizedPath = AuFS::NormalizePathRet(path); + + #if defined(AURORA_PLATFORM_WIN32) + auto widePath = AuLocale::ConvertFromUTF8(normalizedPath); + MoveFileExW(widePath.c_str(), nullptr, MOVEFILE_DELAY_UNTIL_REBOOT); + #endif + + return normalizedPath + AuString(1, kPathSplitter); + } + #if defined(AURORA_PLATFORM_WIN32) static void Win32FixGlobalAppDataAcl(const AuString &path) {