winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 52a3e7dda035a1e26ee7a52f401ac00b9f10e804
parent 8ea9ef28ac6d85aa8119cb16185bbfe190876588
Author: Anders <sredna@gmail.com>
Date:   Wed, 19 Jan 2022 19:38:03 +0100

Check FS feature flags instead of checking for NTFS (#1859)


Diffstat:
Msrc/AppInstallerCommonCore/Downloader.cpp | 17+++++++++++------
Msrc/AppInstallerCommonCore/Public/AppInstallerRuntime.h | 4++--
Msrc/AppInstallerCommonCore/Runtime.cpp | 52+++++++++++++++++++++++++++++++++-------------------
3 files changed, 46 insertions(+), 27 deletions(-)

diff --git a/src/AppInstallerCommonCore/Downloader.cpp b/src/AppInstallerCommonCore/Downloader.cpp @@ -248,14 +248,19 @@ namespace AppInstaller::Utility return false; } + + static inline bool FileSupportsMotw(const std::filesystem::path& path) + { + return SupportsNamedStreams(path); + } void ApplyMotwIfApplicable(const std::filesystem::path& filePath, URLZONE zone) { AICLI_LOG(Core, Info, << "Started applying motw to " << filePath << " with zone: " << zone); - if (!IsNTFS(filePath)) + if (!FileSupportsMotw(filePath)) { - AICLI_LOG(Core, Info, << "File system is not NTFS. Skipped applying motw"); + AICLI_LOG(Core, Info, << "File system does not support ADS. Skipped applying motw"); return; } @@ -274,9 +279,9 @@ namespace AppInstaller::Utility { AICLI_LOG(Core, Info, << "Started removing motw to " << filePath); - if (!IsNTFS(filePath)) + if (!FileSupportsMotw(filePath)) { - AICLI_LOG(Core, Info, << "File system is not NTFS. Skipped removing motw"); + AICLI_LOG(Core, Info, << "File system does not support ADS. Skipped removing motw"); return; } @@ -307,9 +312,9 @@ namespace AppInstaller::Utility { AICLI_LOG(Core, Info, << "Started applying motw using IAttachmentExecute to " << filePath); - if (!IsNTFS(filePath)) + if (!FileSupportsMotw(filePath)) { - AICLI_LOG(Core, Info, << "File system is not NTFS. Skipped applying motw"); + AICLI_LOG(Core, Info, << "File system does not support ADS. Skipped applying motw"); return S_OK; } diff --git a/src/AppInstallerCommonCore/Public/AppInstallerRuntime.h b/src/AppInstallerCommonCore/Public/AppInstallerRuntime.h @@ -58,8 +58,8 @@ namespace AppInstaller::Runtime // Determines whether the process is running with administrator privileges. bool IsRunningAsAdmin(); - // Checks if the file system is NTFS - bool IsNTFS(const std::filesystem::path& filePath); + // Checks if the file system at path supports named streams/ADS + bool SupportsNamedStreams(const std::filesystem::path& path); // Checks if the file system at path supports hard links bool SupportsHardLinks(const std::filesystem::path& path); diff --git a/src/AppInstallerCommonCore/Runtime.cpp b/src/AppInstallerCommonCore/Runtime.cpp @@ -415,39 +415,53 @@ namespace AppInstaller::Runtime return wil::test_token_membership(nullptr, SECURITY_NT_AUTHORITY, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS); } - // TODO: Replace this function with proper checks for supported functionality rather - // than simply relying on "is it NTFS?", even if those functions delegate to - // this one for the answer. - bool IsNTFS(const std::filesystem::path& filePath) + DWORD GetVolumeInformationFlagsByHandle(HANDLE anyFileHandle) { - wil::unique_hfile fileHandle{ CreateFileW( - filePath.c_str(), /*lpFileName*/ - FILE_READ_ATTRIBUTES, /*dwDesiredAccess*/ - 0, /*dwShareMode*/ - NULL, /*lpSecurityAttributes*/ - OPEN_EXISTING, /*dwCreationDisposition*/ - FILE_ATTRIBUTE_NORMAL, /*dwFlagsAndAttributes*/ - NULL /*hTemplateFile*/) }; - - THROW_LAST_ERROR_IF(fileHandle.get() == INVALID_HANDLE_VALUE); - + DWORD flags = 0; wchar_t fileSystemName[MAX_PATH]; THROW_LAST_ERROR_IF(!GetVolumeInformationByHandleW( - fileHandle.get(), /*hFile*/ + anyFileHandle, /*hFile*/ NULL, /*lpVolumeNameBuffer*/ 0, /*nVolumeNameSize*/ NULL, /*lpVolumeSerialNumber*/ NULL, /*lpMaximumComponentLength*/ - NULL, /*lpFileSystemFlags*/ + &flags, /*lpFileSystemFlags*/ fileSystemName, /*lpFileSystemNameBuffer*/ MAX_PATH /*nFileSystemNameSize*/)); - return _wcsicmp(fileSystemName, L"NTFS") == 0; + // Vista and older does not report all flags, fix them up here + if (!(flags & FILE_SUPPORTS_HARD_LINKS) && !_wcsicmp(fileSystemName, L"NTFS")) + { + flags |= FILE_SUPPORTS_HARD_LINKS|FILE_SUPPORTS_EXTENDED_ATTRIBUTES|FILE_SUPPORTS_OPEN_BY_FILE_ID|FILE_SUPPORTS_USN_JOURNAL; + } + + return flags; + } + + DWORD GetVolumeInformationFlags(const std::filesystem::path& anyPath) + { + wil::unique_hfile fileHandle{ CreateFileW( + anyPath.c_str(), /*lpFileName*/ + 0, /*dwDesiredAccess*/ + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /*dwShareMode*/ + NULL, /*lpSecurityAttributes*/ + OPEN_EXISTING, /*dwCreationDisposition*/ + FILE_ATTRIBUTE_NORMAL, /*dwFlagsAndAttributes*/ + NULL /*hTemplateFile*/) }; + + THROW_LAST_ERROR_IF(fileHandle.get() == INVALID_HANDLE_VALUE); + + return GetVolumeInformationFlagsByHandle(fileHandle.get()); + } + + bool SupportsNamedStreams(const std::filesystem::path& path) + { + return (GetVolumeInformationFlags(path) & FILE_NAMED_STREAMS) != 0; } bool SupportsHardLinks(const std::filesystem::path& path) { - return IsNTFS(path); + return (GetVolumeInformationFlags(path) & FILE_SUPPORTS_HARD_LINKS) != 0; } constexpr bool IsReleaseBuild()