Обнаружение значения FileSystemRights, которое не определено в перечислении
Я написал приложение, которое проверяет все разрешения файловой системы на каталог.
Каталог имеет ряд правил доступа (типа FileSystemAccessRule
).
Каждое правило доступа имеет свойство FileSystemRights
, которое является перечислением флагов.
При запуске этого приложения я постоянно сталкиваюсь с FileSystemRights
значением 268435456
(которое приходит к 0x10000000
в шестнадцатеричном виде).
Это значение просто не появляется в перечислении! Это на самом деле выше, чем самое высокое значение одиночного флага (Synchronize
, имеющее значение из 0x100000
).
Кто-нибудь знает, что это такое?
3 ответа:
С этой страницы:
Используя .NET, вы можете подумать, что определение того, какие разрешения являются назначение директории / файла должно быть достаточно простым, так как имеется Перечисление FileSystemRights определено, которое, по-видимому, содержит все возможные разрешение, которое может иметь файл/каталог и вызов AccessRule.FileSystemRights возвращает комбинацию этих значений. Однако вскоре вы столкнетесь с некоторыми разрешениями, где значение в это свойство не соответствует ни одному из значений в FileSystemRights Перечисление (я бы хотел, чтобы они не называли некоторые свойства с тем же именем как тип, но эй).
Конечным результатом этого является то, что для некоторых файлов/каталогов вы просто не удается определить, какие разрешения им назначены. Если вы это сделаете AccessRule.FileSystemRights.ToString тогда для этих значений все, что вы видите это число, а не а описание (например, изменить, удалить, FullControl прием). Общие числа, которые вы можете увидеть:
-1610612736, -536805376 и 268435456
Чтобы выяснить, каковы эти разрешения на самом деле, вам нужно посмотреть на какие биты задаются, когда вы рассматриваете это число как 32 отдельных бита а не как целое число (поскольку целые числа имеют длину 32 бита), и сравнить их к этой диаграмме: http://msdn.microsoft.com/en-us/library/aa374896 (v=против 85).aspx
Так, например, -1610612736 имеет Первый БИТ и третий бит набора, что означает, что это GENERIC_READ в сочетании с GENERIC_EXECUTE. Теперь эти общие разрешения можно преобразовать в конкретный файл системные разрешения, которым они соответствуют.
Здесь вы можете увидеть, какие разрешения сопоставляет каждое универсальное разрешение: http://msdn.microsoft.com/en-us/library/aa364399.aspx . просто осознавайте что STANDARD_RIGHTS_READ, STANDARD_RIGHTS_EXECUTE и STANDARD_RIGHTS_WRITE - это все то же самое (не знаю почему, кажется странно для меня) и на самом деле все равны FileSystemRights.Значение ReadPermissions.
268435456-FullControl
-536805376-Изменить, Синхронизировать
-1610612736-ReadAndExecute, Synchronize
(чтобы сэкономить вам немного математики)
Вот мое решение для исправления FileSystemRights, чтобы они соответствовали перечислению.
Об этом есть несколько документов. Ссылки включены в код.public static FileSystemRights FileSystemRightsCorrector(FileSystemRights fsRights, bool removeSynchronizePermission = false) { // from: https://msdn.microsoft.com/en-us/library/aa374896%28v=vs.85%29.aspx const int C_BitGenericRead = (1 << 31); const int C_BitGenericWrite = (1 << 30); const int C_BitGenericExecute = (1 << 29); const int C_BitGenericAll = (1 << 28); // https://msdn.microsoft.com/en-us/library/aa364399.aspx // FILE_GENERIC_READ = FILE_READ_ATTRIBUTES | FILE_READ_DATA | FILE_READ_EA | STANDARD_RIGHTS_READ | SYNCHRONIZE // FILE_GENERIC_WRITE = FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA | FILE_WRITE_EA | STANDARD_RIGHTS_WRITE | SYNCHRONIZE // FILE_GENERIC_EXECUTE = FILE_EXECUTE | FILE_READ_ATTRIBUTES | STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE //from Winnt.h //#define STANDARD_RIGHTS_READ (READ_CONTROL) //#define STANDARD_RIGHTS_WRITE (READ_CONTROL) //#define STANDARD_RIGHTS_EXECUTE (READ_CONTROL) // from: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379607%28v=vs.85%29.aspx // READ_CONTROL = "The right to read the information in the object's security descriptor," // ==> STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE, STANDARD_RIGHTS_EXECUTE == FileSystemRights.ReadPermissions // translation for the generic rights to the FileSystemRights enum const FileSystemRights C_FsrGenericRead = FileSystemRights.ReadAttributes | FileSystemRights.ReadData | FileSystemRights.ReadExtendedAttributes | FileSystemRights.ReadPermissions | FileSystemRights.Synchronize; const FileSystemRights C_FsrGenericWrite = FileSystemRights.AppendData | FileSystemRights.WriteAttributes | FileSystemRights.WriteData | FileSystemRights.WriteExtendedAttributes | FileSystemRights.ReadPermissions | FileSystemRights.Synchronize; const FileSystemRights C_FsrGenericExecute = FileSystemRights.ExecuteFile | FileSystemRights.ReadAttributes | FileSystemRights.ReadPermissions | FileSystemRights.Synchronize; if (((int)fsRights & C_BitGenericRead) != 0) { fsRights |= C_FsrGenericRead; } if (((int)fsRights & C_BitGenericWrite) != 0) { fsRights |= C_FsrGenericWrite; } if (((int)fsRights & C_BitGenericExecute) != 0) { fsRights |= C_FsrGenericExecute; } if (((int)fsRights & C_BitGenericAll) != 0) { fsRights |= FileSystemRights.FullControl; } // delete the 4 highest bits if present fsRights = (FileSystemRights)((int)fsRights & ~(C_BitGenericRead | C_BitGenericWrite | C_BitGenericExecute | C_BitGenericAll)); // for some purposes the "Synchronize" flag must be deleted if (removeSynchronizePermission == true) { fsRights = (FileSystemRights)((int)fsRights & ~((int)FileSystemRights.Synchronize)); } return fsRights; }