views:

113

answers:

1

First off: I know that this isn't reliable for actually checking if I can write. I'm writing a file transfer client, and want feature parity between the "remote" and "local" file browser panes. I fully understand I will have to handle any permission related exceptions for any operation performed regardless; it's not a programming check it's just to display to the user.

I've seen several examples for these posted, but everything I've tried either wasn't understandable or didn't work. I've tried the following two methods, but both just returned "yes" for things I definitely can't write to (the contents of C:\Windows or C:\Program Files, for example):

System.Security.Permissions.FileIOPermission fp = new System.Security.Permissions.FileIOPermission(System.Security.Permissions.FileIOPermissionAccess.Write, Path);
return System.Security.SecurityManager.IsGranted(fp);

and

System.Security.Permissions.FileIOPermission fp = new System.Security.Permissions.FileIOPermission(System.Security.Permissions.FileIOPermissionAccess.Write, element.Path);
try
{
    fp.Assert();
    return true;
}
catch(Exception x)
{
    return false;
}

(Again, I'm aware that both catching Exception is horrible and using try/catch for logic is slightly less horrible, I'm just trying to get this to work).

The first one tells me that IsGranted is deprecated and I should be using AppDomain.PermissionSet or Application.PermissionSet, but I can't find any explanation of how to use these that makes sense. I've also seen that I should be manually enumerating all the ACLs to figure it out myself, but again there's no real examples of this. There's quite a few examples for setting permissions, but few for checking them.

Any help would be greatly appreciated.

A: 

Well, here's what I eventually wound up with:

    private readonly static WindowsIdentity _identity = WindowsIdentity.GetCurrent();
    protected static bool GetPermission(FileSystemRights right, string path)
    {
        FileSecurity fs;
        try
        {
            fs = System.IO.File.GetAccessControl(path);
        }
        catch(InvalidOperationException)
        {
            // called on a disk that's not present, ...
            return false;
        }
        catch(UnauthorizedAccessException)
        {
            return false;
        }
        foreach(FileSystemAccessRule fsar in fs.GetAccessRules(true, true, typeof(SecurityIdentifier)))
        {
            if(fsar.IdentityReference == _identity.User && fsar.FileSystemRights.HasFlag(right) && fsar.AccessControlType == AccessControlType.Allow)
            {
                return true;
            }
            else if(_identity.Groups.Contains(fsar.IdentityReference) && fsar.FileSystemRights.HasFlag(right) && fsar.AccessControlType == AccessControlType.Allow)
            {
                return true;
            }
        }
        return false;
    }

Of course, it's not ideal, because it ignores Deny rights. But I have no idea in which order to apply the various ACEs (I think?) in order to find out the "correct" ability. Still, Deny rules are relatively rare, so it works most of the time for me.

JustABill