Skip to content

Commit

Permalink
Check FS feature flags instead of checking for NTFS (microsoft#1859)
Browse files Browse the repository at this point in the history
  • Loading branch information
sredna authored Jan 19, 2022
1 parent 8ea9ef2 commit 52a3e7d
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 27 deletions.
17 changes: 11 additions & 6 deletions src/AppInstallerCommonCore/Downloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions src/AppInstallerCommonCore/Public/AppInstallerRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
52 changes: 33 additions & 19 deletions src/AppInstallerCommonCore/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit 52a3e7d

Please sign in to comment.