module System.Win32.Security ( 
        
        SID, PSID,
        ACL, PACL,
        SECURITY_DESCRIPTOR,
        SECURITY_DESCRIPTOR_CONTROL,
        se_OWNER_DEFAULTED,
        se_GROUP_DEFAULTED,
        se_DACL_PRESENT,
        se_DACL_DEFAULTED,
        se_SACL_PRESENT,
        se_SACL_DEFAULTED,
        se_DACL_AUTO_INHERIT_REQ,
        se_SACL_AUTO_INHERIT_REQ,
        se_DACL_AUTO_INHERITED,
        se_SACL_AUTO_INHERITED,
        se_DACL_PROTECTED,
        se_SACL_PROTECTED,
        se_SELF_RELATIVE,
        SECURITY_INFORMATION,
        oWNER_SECURITY_INFORMATION,
        gROUP_SECURITY_INFORMATION,
        dACL_SECURITY_INFORMATION,
        sACL_SECURITY_INFORMATION,
        
        getFileSecurity,
  ) where
import Foreign
import System.Win32.Types
newtype SECURITY_DESCRIPTOR = SECURITY_DESCRIPTOR SECURITY_DESCRIPTOR
type PSECURITY_DESCRIPTOR = Ptr SECURITY_DESCRIPTOR
newtype SecurityDescriptor = SecurityDescriptor (ForeignPtr SECURITY_DESCRIPTOR)
type SECURITY_DESCRIPTOR_CONTROL = WORD
se_OWNER_DEFAULTED        :: SECURITY_DESCRIPTOR_CONTROL
se_OWNER_DEFAULTED        =  1
se_GROUP_DEFAULTED        :: SECURITY_DESCRIPTOR_CONTROL
se_GROUP_DEFAULTED        =  2
se_DACL_PRESENT           :: SECURITY_DESCRIPTOR_CONTROL
se_DACL_PRESENT           =  4
se_DACL_DEFAULTED         :: SECURITY_DESCRIPTOR_CONTROL
se_DACL_DEFAULTED         =  8
se_SACL_PRESENT           :: SECURITY_DESCRIPTOR_CONTROL
se_SACL_PRESENT           =  16
se_SACL_DEFAULTED         :: SECURITY_DESCRIPTOR_CONTROL
se_SACL_DEFAULTED         =  32
se_DACL_AUTO_INHERIT_REQ  :: SECURITY_DESCRIPTOR_CONTROL
se_DACL_AUTO_INHERIT_REQ  =  256
se_SACL_AUTO_INHERIT_REQ  :: SECURITY_DESCRIPTOR_CONTROL
se_SACL_AUTO_INHERIT_REQ  =  512
se_DACL_AUTO_INHERITED    :: SECURITY_DESCRIPTOR_CONTROL
se_DACL_AUTO_INHERITED    =  1024
se_SACL_AUTO_INHERITED    :: SECURITY_DESCRIPTOR_CONTROL
se_SACL_AUTO_INHERITED    =  2048
se_DACL_PROTECTED         :: SECURITY_DESCRIPTOR_CONTROL
se_DACL_PROTECTED         =  4096
se_SACL_PROTECTED         :: SECURITY_DESCRIPTOR_CONTROL
se_SACL_PROTECTED         =  8192
se_SELF_RELATIVE          :: SECURITY_DESCRIPTOR_CONTROL
se_SELF_RELATIVE          =  32768
newtype ACL = ACL ACL   
type PACL = Ptr ACL
newtype SID = SID SID
type PSID = Ptr SID
foreign import stdcall unsafe "windows.h GetSecurityDescriptorControl"
  c_getSecurityDescriptorControl
    :: PSECURITY_DESCRIPTOR 
    -> Ptr SECURITY_DESCRIPTOR_CONTROL 
    -> LPDWORD 
    -> IO BOOL 
foreign import stdcall unsafe "windows.h GetSecurityDescriptorDacl"
  c_getSecurityDescriptorDacl 
    :: PSECURITY_DESCRIPTOR 
    -> LPBOOL 
    -> Ptr PACL 
    -> LPBOOL 
    -> IO BOOL 
foreign import stdcall unsafe "windows.h GetSecurityDescriptorGroup"
  c_getSecurityDescriptorGroup
    :: PSECURITY_DESCRIPTOR 
    -> Ptr PSID 
    -> LPBOOL 
    -> IO BOOL 
foreign import stdcall unsafe "windows.h GetSecurityDescriptorLength"
  c_getSecurityDescriptorLength
    :: PSECURITY_DESCRIPTOR 
    -> IO DWORD 
foreign import stdcall unsafe "windows.h GetSecurityDescriptorOwner"
  c_getSecurityDescriptorOwner
    :: PSECURITY_DESCRIPTOR 
    -> Ptr PSID 
    -> LPBOOL 
    -> IO BOOL 
foreign import stdcall unsafe "windows.h GetSecurityDescriptorSacl"
  c_getSecurityDescriptorSacl
    :: PSECURITY_DESCRIPTOR 
    -> LPBOOL 
    -> Ptr PACL 
    -> LPBOOL 
    -> IO BOOL 
foreign import stdcall unsafe "windows.h InitializeSecurityDescriptor"
  c_initializeSecurityDescriptor
    :: PSECURITY_DESCRIPTOR 
    -> DWORD 
    -> IO BOOL 
foreign import stdcall unsafe "windows.h IsValidSecurityDescriptor"
  c_isValidSecurityDescriptor
    :: PSECURITY_DESCRIPTOR 
    -> IO BOOL 
foreign import stdcall unsafe "windows.h SetSecurityDescriptorDacl"
  c_setSecurityDescriptorDacl
    :: PSECURITY_DESCRIPTOR 
    -> BOOL 
    -> PACL 
    -> BOOL 
    -> IO BOOL 
foreign import stdcall unsafe "windows.h SetSecurityDescriptorGroup"
  c_setSecurityDescriptorGroup
    :: PSECURITY_DESCRIPTOR 
    -> PSID 
    -> BOOL 
    -> IO BOOL 
foreign import stdcall unsafe "windows.h SetSecurityDescriptorOwner"
  c_setSecurityDescriptorOwner
    :: PSECURITY_DESCRIPTOR 
    -> PSID 
    -> BOOL 
    -> IO BOOL 
foreign import stdcall unsafe "windows.h SetSecurityDescriptorSacl"
  c_setSecurityDescriptorSacl
    :: PSECURITY_DESCRIPTOR 
    -> BOOL 
    -> PACL 
    -> BOOL 
    -> IO BOOL 
type SECURITY_INFORMATION = DWORD
oWNER_SECURITY_INFORMATION  :: SECURITY_INFORMATION
oWNER_SECURITY_INFORMATION  =  1
gROUP_SECURITY_INFORMATION  :: SECURITY_INFORMATION
gROUP_SECURITY_INFORMATION  =  2
dACL_SECURITY_INFORMATION  :: SECURITY_INFORMATION
dACL_SECURITY_INFORMATION  =  4
sACL_SECURITY_INFORMATION  :: SECURITY_INFORMATION
sACL_SECURITY_INFORMATION  =  8
getFileSecurity
    :: String
    -> SECURITY_INFORMATION
    -> IO SecurityDescriptor
getFileSecurity filename si =
  withTString filename $ \lpFileName ->
  with 0 $ \lpnLengthNeeded -> do
  c_GetFileSecurity lpFileName si nullPtr 0 lpnLengthNeeded
  needed <- peek lpnLengthNeeded
  fpSd <- mallocForeignPtrBytes (fromIntegral needed)
  withForeignPtr fpSd $ \pSd -> do
  failIfFalse_ "getFileSecurity" $ 
    c_GetFileSecurity lpFileName si pSd needed lpnLengthNeeded
  return (SecurityDescriptor fpSd)
foreign import stdcall unsafe "windows.h GetFileSecurityW"
  c_GetFileSecurity
    :: LPCWSTR 
    -> SECURITY_INFORMATION 
    -> PSECURITY_DESCRIPTOR 
    -> DWORD 
    -> LPDWORD 
    -> IO BOOL