private bool ResolveAccess( FileAccessManifest manifest, ReportedFileAccess access, AbsolutePath accessPath, AbsolutePath resolvedPath, [CanBeNull] string resolvedPathAsString, bool isDirectoryReparsePoint, out ReportedFileAccess resolvedAccess) { var flags = isDirectoryReparsePoint ? access.FlagsAndAttributes | FlagsAndAttributes.FILE_ATTRIBUTE_DIRECTORY : access.FlagsAndAttributes; // If they are different, this means the original path contains symlinks we need to resolve if (resolvedPath != accessPath) { if (access.ManifestPath == resolvedPath) { // When the manifest path matches the path, we don't store the latter resolvedAccess = access.CreateWithPathAndAttributes( null, access.ManifestPath, flags); } else { resolvedPathAsString ??= resolvedPath.ToString(m_context.PathTable); // In this case we need to normalize the manifest path as well // Observe the resolved path is fully resolved, and therefore if a manifest path is found, it will // also be fully resolved // If no manifest is found for the resolved path, the result is invalid, which is precisely what we need in resolvedManifestPath manifest.TryFindManifestPathFor(resolvedPath, out AbsolutePath resolvedManifestPath, out _); resolvedAccess = access.CreateWithPathAndAttributes( resolvedPath == resolvedManifestPath ? null : resolvedPathAsString, resolvedManifestPath, flags); } return(true); } resolvedAccess = access; return(false); }
private ReportedFileAccess GenerateReadAccessForPath(FileAccessManifest manifest, AbsolutePath currentPath, ReportedFileAccess access) { manifest.TryFindManifestPathFor(currentPath, out AbsolutePath manifestPath, out FileAccessPolicy nodePolicy); return(new ReportedFileAccess( ReportedFileOperation.CreateFile, access.Process, RequestedAccess.Read, (nodePolicy & FileAccessPolicy.AllowRead) != 0 ? FileAccessStatus.Allowed : FileAccessStatus.Denied, (nodePolicy & FileAccessPolicy.ReportAccess) != 0, access.Error, Usn.Zero, DesiredAccess.GENERIC_READ, ShareMode.FILE_SHARE_READ, CreationDisposition.OPEN_ALWAYS, FlagsAndAttributes.FILE_ATTRIBUTE_ARCHIVE, manifestPath, manifestPath == currentPath? null : currentPath.ToString(m_context.PathTable), string.Empty)); }
private ReportedFileAccess GenerateProbeForPath(FileAccessManifest manifest, AbsolutePath currentPath, ReportedFileAccess access) { manifest.TryFindManifestPathFor(currentPath, out AbsolutePath manifestPath, out FileAccessPolicy nodePolicy); return(new ReportedFileAccess( ReportedFileOperation.CreateFile, access.Process, RequestedAccess.Probe, (nodePolicy & FileAccessPolicy.AllowRead) != 0 ? FileAccessStatus.Allowed : FileAccessStatus.Denied, (nodePolicy & FileAccessPolicy.ReportAccess) != 0, access.Error, Usn.Zero, DesiredAccess.GENERIC_READ, ShareMode.FILE_SHARE_READ, CreationDisposition.OPEN_ALWAYS, // These generated accesses represent directory reparse points, so therefore we honor // the directory attribute FlagsAndAttributes.FILE_ATTRIBUTE_DIRECTORY, manifestPath, manifestPath == currentPath? null : currentPath.ToString(m_context.PathTable), string.Empty)); }