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:
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()