// (c) 2006 Richard Grimes // www.grimes.demon.co.uk using System; using System.Reflection; using System.Security; using System.Security.Permissions; [assembly: AssemblyKeyFile("key.snk")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AllowPartiallyTrustedCallers] [Flags, Serializable] public enum DiskAccess{ None = 0, Size = 1, Label = 2, Type = 4, All = 7 } [Serializable] public sealed class DiskPermission : CodeAccessPermission, IUnrestrictedPermission { DiskAccess diskAccess; public DiskPermission(PermissionState state) { if (state == PermissionState.Unrestricted) diskAccess = DiskAccess.All; else diskAccess = DiskAccess.None; } public DiskPermission(DiskAccess access) { diskAccess = access; } public bool IsUnrestricted() { return (diskAccess == DiskAccess.All); } public DiskAccess Access { get { return diskAccess; } set { diskAccess = value; } } public override IPermission Copy() { return new DiskPermission(diskAccess); } public override IPermission Intersect(IPermission target) { if (target == null) return null; DiskPermission targetItem = target as DiskPermission; if (targetItem == null) throw new ArgumentException("Argument must be of type DiskPermission"); // If either is DiskAccess.None then the intersection is None if (this.diskAccess == DiskAccess.None || targetItem.diskAccess == DiskAccess.None) { return new DiskPermission(DiskAccess.None); } // DiskAccess is a bitmap so the intersection is simply a logical AND return new DiskPermission(this.diskAccess & targetItem.diskAccess); } public override IPermission Union(IPermission target) { if (target == null) return null; DiskPermission targetItem = target as DiskPermission; if (targetItem == null) throw new ArgumentException("Argument must be of type DiskPermission"); // DiskAccess is a bitmap so the union is simply a logical OR return new DiskPermission(this.diskAccess | targetItem.diskAccess); } public override SecurityElement ToXml() { SecurityElement e = new SecurityElement("IPermission"); e.AddAttribute("class", this.GetType().AssemblyQualifiedName); e.AddAttribute("version", "1"); if (this.diskAccess == DiskAccess.All) { e.AddAttribute("Unrestricted", "true"); } else { e.AddAttribute("Access", diskAccess.ToString()); } return e; } public override void FromXml(SecurityElement elem) { string unrestricted = elem.Attribute("Unrestricted"); if (unrestricted != null) { if (unrestricted == "true") { this.diskAccess = DiskAccess.All; return; } } string strAccess = elem.Attribute("Access"); if (strAccess != null) { diskAccess = (DiskAccess)Enum.Parse(typeof(DiskAccess), strAccess); } } public override bool IsSubsetOf(IPermission target) { if (target == null) return false; DiskPermission targetItem = target as DiskPermission; if (targetItem == null) throw new ArgumentException("Argument must be of type DiskPermission"); // If either is DiskAccess.None then the result is false if (this.diskAccess == DiskAccess.None || targetItem.diskAccess == DiskAccess.None) { return false; } // If there is more access in this than the target, then the // check should fail if (this.diskAccess > targetItem.diskAccess) { return false; } // If both are the same then result is true if (this.diskAccess == targetItem.diskAccess) { return true; } // If the target is All then the result is true if (targetItem.diskAccess == DiskAccess.All) { return true; } // All other cases are false return false; } } [Serializable, AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = true, Inherited = false)] public sealed class DiskPermissionAttribute : CodeAccessSecurityAttribute { DiskAccess diskAccess = DiskAccess.None; public DiskPermissionAttribute(SecurityAction action) : base(action) { } public new bool Unrestricted { get { return diskAccess == DiskAccess.All; } set { if (value) diskAccess = DiskAccess.All; else diskAccess = DiskAccess.None; } } public DiskAccess Access { get { return diskAccess; } set { diskAccess = value; } } public override IPermission CreatePermission() { return new DiskPermission(diskAccess); } }