Filesystem.h (4941B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #pragma once 4 #include <filesystem> 5 #include <map> 6 #include <optional> 7 #include <shtypes.h> 8 9 namespace AppInstaller::Filesystem 10 { 11 // Checks if the file system at path supports named streams/ADS 12 bool SupportsNamedStreams(const std::filesystem::path& path); 13 14 // Checks if the file system at path supports hard links 15 bool SupportsHardLinks(const std::filesystem::path& path); 16 17 // Checks if the file system at path support reparse points 18 bool SupportsReparsePoints(const std::filesystem::path& path); 19 20 // Checks if the canonical form of the path points to a location outside of the provided base path. 21 bool PathEscapesBaseDirectory(const std::filesystem::path& target, const std::filesystem::path& base); 22 23 // Renames the file to a new path. 24 void RenameFile(const std::filesystem::path& from, const std::filesystem::path& to); 25 26 // Creates a symlink that points to the target path. 27 bool CreateSymlink(const std::filesystem::path& target, const std::filesystem::path& link); 28 29 // Verifies that a symlink points to the target path. 30 bool VerifySymlink(const std::filesystem::path& symlink, const std::filesystem::path& target); 31 32 // Appends the .exe extension to the path if not present. 33 void AppendExtension(std::filesystem::path& value, const std::string& extension); 34 35 // Checks if the path is a symlink and exists. 36 bool SymlinkExists(const std::filesystem::path& symlinkPath); 37 bool CreateSymlink(const std::filesystem::path& path, const std::filesystem::path& target); 38 39 // Get expanded file system path. 40 std::filesystem::path GetExpandedPath(const std::string& path); 41 42 // If `source` begins with all of `prefix`, replace that with `replacement`. 43 // Returns true if replacement happened, false otherwise. 44 bool ReplaceCommonPathPrefix(std::filesystem::path& source, const std::filesystem::path& prefix, std::string_view replacement); 45 46 // Gets the path of a known folder. 47 std::filesystem::path GetKnownFolderPath(const KNOWNFOLDERID& id); 48 49 // Verifies that the paths are on the same volume. 50 bool IsSameVolume(const std::filesystem::path& path1, const std::filesystem::path& path2); 51 52 // Verifies if 'path' has parent equal to 'parentPath' 53 bool IsParentPath(const std::filesystem::path& path, const std::filesystem::path& parentPath); 54 55 // The principal that an ACE applies to. 56 enum class ACEPrincipal : uint32_t 57 { 58 CurrentUser, 59 Admins, 60 System, 61 }; 62 63 // The permissions granted to a specific ACE. 64 enum class ACEPermissions : uint32_t 65 { 66 // This is not "Deny All", but rather, "Not mentioned" 67 None = 0x0, 68 Read = 0x1, 69 Write = 0x2, 70 Execute = 0x4, 71 ReadWrite = Read | Write, 72 ReadExecute = Read | Execute, 73 ReadWriteExecute = Read | Write | Execute, 74 // All means that full control will be granted 75 All = 0xFFFFFFFF 76 }; 77 78 DEFINE_ENUM_FLAG_OPERATORS(ACEPermissions); 79 80 // Information about a path that we use and how to set it up. 81 struct PathDetails 82 { 83 std::filesystem::path Path; 84 // Default to creating the directory with inherited ownership and permissions 85 bool Create = true; 86 std::optional<ACEPrincipal> Owner; 87 std::map<ACEPrincipal, ACEPermissions> ACL; 88 89 // Shorthand for setting Owner and giving them ACEPermissions::All 90 void SetOwner(ACEPrincipal owner); 91 92 // Determines if the ACL should be applied. 93 bool ShouldApplyACL() const; 94 95 // Applies the ACL unconditionally. 96 void ApplyACL() const; 97 }; 98 99 // Initializes from the given details and returns the path to it. 100 // The path is moved out of the details. 101 std::filesystem::path InitializeAndGetPathTo(PathDetails&& details); 102 103 // Gets the path to the requested location. 104 template <class PathEnum> 105 std::filesystem::path GetPathTo(PathEnum path, bool forDisplay = false) 106 { 107 return InitializeAndGetPathTo(GetPathDetailsFor(path, forDisplay)); 108 } 109 110 // A shared path. 111 enum class PathName 112 { 113 // Local state root that is specifically unpackaged (even if used from a packaged process). 114 UnpackagedLocalStateRoot, 115 // Local settings root that is specifically unpackaged (even if used from a packaged process). 116 UnpackagedSettingsRoot, 117 }; 118 119 // Gets the PathDetails used for the given path. 120 // This is exposed primarily to allow for testing, GetPathTo should be preferred. 121 PathDetails GetPathDetailsFor(PathName path, bool forDisplay = false); 122 123 // Gets the path to the executable for the given process. 124 std::filesystem::path GetExecutablePathForProcess(HANDLE process); 125 }