Как проверить, доступен ли файл Windows для чтения / записи? - PullRequest
4 голосов
/ 05 июня 2010

Прежде всего: я знаю, что это ненадежно для проверки, могу ли я писать. Я пишу клиент для передачи файлов и хочу, чтобы между «удаленным» и «локальным» панелями браузера файлов был паритет функций. Я полностью понимаю, что мне придется обрабатывать любые связанные с разрешениями исключения для любой операции, выполняемой независимо; это не проверка программирования, а просто отображение пользователю.

Я видел несколько примеров для них, но все, что я пробовал, либо было непонятным, либо не работало. Я попробовал следующие два метода, но оба просто вернули «да» для вещей, в которые я точно не могу записать (например, содержимое C: \ Windows или C: \ Program Files):

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

и

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;
}

(Опять же, я знаю, что оба метода Exception ужасны, а использование try / catch для логики немного менее ужасно, я просто пытаюсь заставить это работать).

Первый говорит мне, что IsGranted устарел, и я должен использовать AppDomain.PermissionSet или Application.PermissionSet, но я не могу найти какое-либо объяснение того, как их использовать, что имеет смысл. Я также видел, что мне нужно вручную перечислять все ACL, чтобы самому это выяснить, но опять же нет реальных примеров этого. Есть довольно много примеров для установки разрешений, но мало для их проверки.

Любая помощь будет принята с благодарностью.

1 Ответ

2 голосов
/ 06 июня 2010

Ну, вот что я в итоге получаю:

    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;
    }

Конечно, это не идеал, потому что он игнорирует права Запретить. Но я понятия не имею, в каком порядке применять различные ACE (я думаю?), Чтобы узнать «правильные» способности. Тем не менее, правила запрета встречаются относительно редко, поэтому они работают для меня большую часть времени.

...