2012-03-14 11 views
8

He escrito una aplicación que examina todos los permisos del sistema de archivos en un directorio.El encuentro con un valor FileSystemRights que no está definido en la enumeración

Un directorio tiene una serie de reglas de acceso (de tipo FileSystemAccessRule).

Cada regla de acceso tiene una propiedad FileSystemRights, que es una enumeración bandera.

Al ejecutar esto, sigo encontrando un valor FileSystemRights de 268435456 (que viene a 0x10000000 en hexadecimal).

Este valor simplemente no aparece en la enumeración! En realidad, es más alto que el valor de indicador único más alto (Synchronize, que tiene un valor de 0x100000).

¿Alguien sabe de qué se trata?

Respuesta

11

Ver http://cjwdev.wordpress.com/2011/06/28/permissions-not-included-in-net-accessrule-filesystemrights-enum/

Desde esa página:

El uso de .NET se puede pensar que la determinación de qué permisos se asignados a un directorio/archivo debería ser bastante fácil, ya que hay una FileSystemRights Enum definido que parece contener todos los permisos posibles de que un archivo/directorio puede tener y llamando al AccessRule.FileSystemRights devuelve una combinación de estos valores. Sin embargo, pronto encontrará algunos permisos donde el valor en esta propiedad no coincide con ninguno de los valores en FileSystemRights Enum (Ojalá no nombrasen algunas propiedades con el mismo nombre como tipo pero oigan)

El resultado final de esto es que para algunos archivos/directorios, simplemente no puede determinar qué permisos se les asignan. Si lo hace AccessRule.FileSystemRights.ToString entonces para estos valores todo lo que ves es un número en lugar de una descripción (por ejemplo modificar, borrar, FullControl etc). números comunes que se pueden ver son:

-1610612736, -536 805 376 y 268 435 456

de averiguar qué estos permisos son en realidad, es necesario mirar a qué bits se establecen cuando usted trata a ese número como 32 separada bits de en lugar de como un entero (como enteros son de 32 bits de largo), y comparar a este diagrama: http://msdn.microsoft.com/en-us/library/aa374896(v=vs.85).aspx

Así, por ejemplo, -1610612736 tiene el primer bit y el tercer conjunto de bits, lo que significa que es GENERIC_READ combinado con GENERIC_EXECUTE. Así que ahora, , puede convertir estos permisos genéricos en los permisos del sistema de archivos específicos a los que corresponden.

Puede ver qué permisos corresponden a cada permiso genérico aquí: http://msdn.microsoft.com/en-us/library/aa364399.aspx. Sólo ten en cuenta que STANDARD_RIGHTS_READ, STANDARD_RIGHTS_EXECUTE y STANDARD_RIGHTS_WRITE son la misma cosa (ni idea de por qué, parece extraño para mí) y, de hecho todos iguales los FileSystemRights.Valor de ReadPermissions.

2

Aquí está mi solución para corregir FileSystemRights por lo se ajustan a la enumeración.

Hay varios documentos al respecto. Las referencias están incluidas en el código.

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