diff --git a/tdutils/td/utils/port/FileFd.cpp b/tdutils/td/utils/port/FileFd.cpp index 9795128eb..274595b87 100644 --- a/tdutils/td/utils/port/FileFd.cpp +++ b/tdutils/td/utils/port/FileFd.cpp @@ -212,7 +212,8 @@ Result FileFd::open(CSlice filepath, int32 flags, int32 mode) { extended_parameters.dwSize = sizeof(extended_parameters); extended_parameters.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; extended_parameters.dwFileFlags = native_flags; - auto handle = td::CreateFile2FromAppW(w_filepath.c_str(), desired_access, share_mode, creation_disposition, &extended_parameters); + auto handle = td::CreateFile2FromAppW(w_filepath.c_str(), desired_access, share_mode, creation_disposition, + &extended_parameters); #endif if (handle == INVALID_HANDLE_VALUE) { return OS_ERROR(PSLICE() << "File \"" << filepath << "\" can't be " << PrintFlags{flags}); diff --git a/tdutils/td/utils/port/FromApp.h b/tdutils/td/utils/port/FromApp.h index d969ad34b..16627b6e0 100644 --- a/tdutils/td/utils/port/FromApp.h +++ b/tdutils/td/utils/port/FromApp.h @@ -1,115 +1,90 @@ #pragma once + #include "td/utils/common.h" #ifdef TD_PORT_WINDOWS -#include + +namespace td { + #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) inline HMODULE GetKernelModule() { - static HMODULE kernelModule; - if (kernelModule == nullptr) { + static const auto kernel_module = []() -> HMODULE { MEMORY_BASIC_INFORMATION mbi; if (VirtualQuery(VirtualQuery, &mbi, sizeof(MEMORY_BASIC_INFORMATION))) { - kernelModule = reinterpret_cast(mbi.AllocationBase); + return reinterpret_cast(mbi.AllocationBase); } - } - - return kernelModule; + return nullptr; + }(); + return kernel_module; } inline HMODULE LoadLibrary(LPCTSTR lpFileName) { - typedef HMODULE(WINAPI * pLoadLibrary)(_In_ LPCTSTR); - static const auto procLoadLibrary = reinterpret_cast(GetProcAddress(GetKernelModule(), "LoadLibraryW")); - - return procLoadLibrary(lpFileName); + using pLoadLibrary = HMODULE(WINAPI *)(_In_ LPCTSTR); + static const auto proc_load_library = + reinterpret_cast(GetProcAddress(GetKernelModule(), "LoadLibraryW")); + return proc_load_library(lpFileName); } inline HMODULE GetFromAppModule() { - static const HMODULE fromAppModule = LoadLibrary(L"api-ms-win-core-file-fromapp-l1-1-0.dll"); - return fromAppModule; + static const HMODULE from_app_module = LoadLibrary(L"api-ms-win-core-file-fromapp-l1-1-0.dll"); + return from_app_module; +} +#endif + +template +T *get_from_app_function(const char *name, T *original_func) { +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + return original_func; +#else + static T *func = [name, original_func]() -> T * { + auto func_pointer = GetProcAddress(GetFromAppModule(), name); + if (func_pointer == nullptr) { + return original_func; + } + return reinterpret_cast(func_pointer); + }(); + return func; +#endif } -namespace td { inline HANDLE CreateFile2FromAppW(_In_ LPCWSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, _In_ DWORD dwCreationDisposition, _In_opt_ LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams) { - using pCreateFile2FromAppW = - HANDLE(WINAPI *)(_In_ LPCWSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, - _In_ DWORD dwCreationDisposition, _In_opt_ LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams); - static const auto createFile2FromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "CreateFile2FromAppW")); - if (createFile2FromAppW != nullptr) { - return createFile2FromAppW(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams); - } - - return CreateFile2(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams); + auto func = get_from_app_function<0>("CreateFile2FromAppW", &CreateFile2); + return func(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams); } inline BOOL CreateDirectoryFromAppW(_In_ LPCWSTR lpPathName, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes) { - using pCreateDirectoryFromAppW = - BOOL(WINAPI *)(_In_ LPCWSTR lpPathName, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes); - static const auto createDirectoryFromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "CreateDirectoryFromAppW")); - if (createDirectoryFromAppW != nullptr) { - return createDirectoryFromAppW(lpPathName, lpSecurityAttributes); - } - - return CreateDirectoryW(lpPathName, lpSecurityAttributes); + auto func = get_from_app_function<1>("CreateDirectoryFromAppW", &CreateDirectory); + return func(lpPathName, lpSecurityAttributes); } inline BOOL RemoveDirectoryFromAppW(_In_ LPCWSTR lpPathName) { - using pRemoveDirectoryFromAppW = BOOL(WINAPI *)(_In_ LPCWSTR lpPathName); - static const auto removeDirectoryFromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "RemoveDirectoryFromAppW")); - if (removeDirectoryFromAppW != nullptr) { - return removeDirectoryFromAppW(lpPathName); - } - - return RemoveDirectoryW(lpPathName); + auto func = get_from_app_function<2>("RemoveDirectoryFromAppW", &RemoveDirectory); + return func(lpPathName); } inline BOOL DeleteFileFromAppW(_In_ LPCWSTR lpFileName) { - using pDeleteFileFromAppW = BOOL(WINAPI *)(_In_ LPCWSTR lpFileName); - static const auto deleteFileFromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "DeleteFileFromAppW")); - if (deleteFileFromAppW != nullptr) { - return deleteFileFromAppW(lpFileName); - } - - return DeleteFileW(lpFileName); + auto func = get_from_app_function<3>("DeleteFileFromAppW", &DeleteFile); + return func(lpFileName); } inline BOOL MoveFileExFromAppW(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) { - using pMoveFileFromAppW = BOOL(WINAPI *)(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName); - static const auto moveFileFromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "MoveFileFromAppW")); - if (moveFileFromAppW != nullptr) { - if (dwFlags == MOVEFILE_REPLACE_EXISTING) { - DeleteFileFromAppW(lpNewFileName); - } - - return moveFileFromAppW(lpExistingFileName, lpNewFileName); + auto func = get_from_app_function<4>("MoveFileFromAppW", &MoveFileEx); + if (func != &MoveFileEx && (dwFlags & MOVEFILE_REPLACE_EXISTING) != 0) { + td::DeleteFileFromAppW(lpNewFileName); } - - return MoveFileEx(lpExistingFileName, lpNewFileName, dwFlags); + return func(lpExistingFileName, lpNewFileName, dwFlags); } inline HANDLE FindFirstFileExFromAppW(_In_ LPCWSTR lpFileName, _In_ FINDEX_INFO_LEVELS fInfoLevelId, _Out_writes_bytes_(sizeof(WIN32_FIND_DATAW)) LPVOID lpFindFileData, _In_ FINDEX_SEARCH_OPS fSearchOp, _Reserved_ LPVOID lpSearchFilter, _In_ DWORD dwAdditionalFlags) { - using pFindFirstFileExFromAppW = HANDLE(WINAPI *)(_In_ LPCWSTR lpFileName, _In_ FINDEX_INFO_LEVELS fInfoLevelId, - _Out_writes_bytes_(sizeof(WIN32_FIND_DATAW)) LPVOID lpFindFileData, - _In_ FINDEX_SEARCH_OPS fSearchOp, _Reserved_ LPVOID lpSearchFilter, - _In_ DWORD dwAdditionalFlags); - static const auto findFirstFileExFromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "FindFirstFileExFromAppW")); - if (findFirstFileExFromAppW != nullptr) { - return findFirstFileExFromAppW(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, - dwAdditionalFlags); - } - - return FindFirstFileExW(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); + auto func = get_from_app_function<5>("FindFirstFileExFromAppW", &FindFirstFileEx); + return func(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); } + } // namespace td -#endif + #endif diff --git a/tdutils/td/utils/port/path.cpp b/tdutils/td/utils/port/path.cpp index f2f53c69d..58bfb1792 100644 --- a/tdutils/td/utils/port/path.cpp +++ b/tdutils/td/utils/port/path.cpp @@ -391,11 +391,7 @@ Status WalkPath::do_run(CSlice path, const detail::WalkFunction &func) { Status mkdir(CSlice dir, int32 mode) { TRY_RESULT(wdir, to_wstring(dir)); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) - auto status = CreateDirectoryW(wdir.c_str(), nullptr); -#else auto status = td::CreateDirectoryFromAppW(wdir.c_str(), nullptr); -#endif if (status == 0 && GetLastError() != ERROR_ALREADY_EXISTS) { return OS_ERROR(PSLICE() << "Can't create directory \"" << dir << '"'); } @@ -405,11 +401,7 @@ Status mkdir(CSlice dir, int32 mode) { Status rename(CSlice from, CSlice to) { TRY_RESULT(wfrom, to_wstring(from)); TRY_RESULT(wto, to_wstring(to)); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) - auto status = MoveFileExW(wfrom.c_str(), wto.c_str(), MOVEFILE_REPLACE_EXISTING); -#else auto status = td::MoveFileExFromAppW(wfrom.c_str(), wto.c_str(), MOVEFILE_REPLACE_EXISTING); -#endif if (status == 0) { return OS_ERROR(PSLICE() << "Can't rename \"" << from << "\" to \"" << to << '\"'); } @@ -452,11 +444,7 @@ Status chdir(CSlice dir) { Status rmdir(CSlice dir) { TRY_RESULT(wdir, to_wstring(dir)); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) - int status = RemoveDirectoryW(wdir.c_str()); -#else int status = td::RemoveDirectoryFromAppW(wdir.c_str()); -#endif if (!status) { return OS_ERROR(PSLICE() << "Can't delete directory \"" << dir << '"'); } @@ -465,11 +453,7 @@ Status rmdir(CSlice dir) { Status unlink(CSlice path) { TRY_RESULT(wpath, to_wstring(path)); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) - int status = DeleteFileW(wpath.c_str()); -#else int status = td::DeleteFileFromAppW(wpath.c_str()); -#endif if (!status) { return OS_ERROR(PSLICE() << "Can't unlink \"" << path << '"'); } @@ -566,12 +550,8 @@ static Result walk_path_dir(const std::wstring &dir_name, const std::function &func) { std::wstring name = dir_name + L"\\*"; WIN32_FIND_DATA file_data; -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) - auto handle = FindFirstFileExW(name.c_str(), FindExInfoStandard, &file_data, FindExSearchNameMatch, nullptr, 0); -#else auto handle = td::FindFirstFileExFromAppW(name.c_str(), FindExInfoStandard, &file_data, FindExSearchNameMatch, nullptr, 0); -#endif if (handle == INVALID_HANDLE_VALUE) { return OS_ERROR(PSLICE() << "FindFirstFileEx" << tag("name", from_wstring(name).ok())); }