    {-# INCLUDE <windows.h> #-}
    {-# LINE 1 "System\Win32\Security.hsc" #-}
    -----------------------------------------------------------------------------
    {-# LINE 2 "System\Win32\Security.hsc" #-}
    -- |
    -- Module      :  System.Win32.Security
    -- Copyright   :  (c) Simon Marlow 2007
    -- License     :  BSD-style (see the file LICENSE)
    --
    -- Maintainer  :  Simon Marlow
    -- Stability   :  provisional
    -- Portability :  portable
    --
    -- FFI-bindings to interact with Win32 Security
    --
    -----------------------------------------------------------------------------

    {-# OPTIONS_GHC -w #-}
    -- The above warning supression flag is a temporary kludge.
    -- While working on this module you are encouraged to remove it and fix
    -- any warnings in the module. See
    --     http://hackage.haskell.org/trac/ghc/wiki/WorkingConventions#Warnings
    -- for details

    module System.Win32.Security (
            -- * Types
            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,

            -- * Functions
            getFileSecurity,
      ) where

    import Foreign
    -- import Foreign.C
    import System.Win32.Types

    {-# LINE 58 "System\Win32\Security.hsc" #-}

    -- --------------------------------------------------------------------------
    -- Security Descriptors

    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

    {-# LINE 82 "System\Win32\Security.hsc" #-}

    newtype ACL = ACL ACL   -- abstract
    type PACL = Ptr ACL

    newtype SID = SID SID
    type PSID = Ptr SID

    foreign import stdcall unsafe "windows.h GetSecurityDescriptorControl"
      c_getSecurityDescriptorControl
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> Ptr SECURITY_DESCRIPTOR_CONTROL -- pControl
        -> LPDWORD -- lpdwRevision
        -> IO BOOL

    foreign import stdcall unsafe "windows.h GetSecurityDescriptorDacl"
      c_getSecurityDescriptorDacl
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> LPBOOL -- lpbDaclPresent
        -> Ptr PACL -- pDacl
        -> LPBOOL -- lpbDaclDefaulted
        -> IO BOOL

    foreign import stdcall unsafe "windows.h GetSecurityDescriptorGroup"
      c_getSecurityDescriptorGroup
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> Ptr PSID -- pGroup
        -> LPBOOL -- lpbGroupDefaulted
        -> IO BOOL

    foreign import stdcall unsafe "windows.h GetSecurityDescriptorLength"
      c_getSecurityDescriptorLength
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> IO DWORD

    foreign import stdcall unsafe "windows.h GetSecurityDescriptorOwner"
      c_getSecurityDescriptorOwner
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> Ptr PSID -- pOwner
        -> LPBOOL -- lpbOwnerDefaulted
        -> IO BOOL

    foreign import stdcall unsafe "windows.h GetSecurityDescriptorSacl"
      c_getSecurityDescriptorSacl
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> LPBOOL -- lpbSaclPresent
        -> Ptr PACL -- pSacl
        -> LPBOOL -- lpbSaclDefaulted
        -> IO BOOL

    foreign import stdcall unsafe "windows.h InitializeSecurityDescriptor"
      c_initializeSecurityDescriptor
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> DWORD -- dwRevision
        -> IO BOOL

    foreign import stdcall unsafe "windows.h IsValidSecurityDescriptor"
      c_isValidSecurityDescriptor
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> IO BOOL

    foreign import stdcall unsafe "windows.h SetSecurityDescriptorDacl"
      c_setSecurityDescriptorDacl
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> BOOL -- bDaclPresent
        -> PACL -- pDacl
        -> BOOL -- bDaclDefaulted
        -> IO BOOL

    foreign import stdcall unsafe "windows.h SetSecurityDescriptorGroup"
      c_setSecurityDescriptorGroup
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> PSID -- pGroup
        -> BOOL -- bGroupDefaulted
        -> IO BOOL

    foreign import stdcall unsafe "windows.h SetSecurityDescriptorOwner"
      c_setSecurityDescriptorOwner
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> PSID -- pOwner
        -> BOOL -- bOwnerDefaulted
        -> IO BOOL

    foreign import stdcall unsafe "windows.h SetSecurityDescriptorSacl"
      c_setSecurityDescriptorSacl
        :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> BOOL -- bSaclPresent
        -> PACL -- pSacl
        -> BOOL -- bSaclDefaulted
        -> IO BOOL

    -- ---------------------------------------------------------------------------

    -- PGENERIC_MAPPING
    -- PPRIVILEGE_SET

    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

    {-# LINE 185 "System\Win32\Security.hsc" #-}
    -- , pROTECTED_DACL_SECURITY_INFORMATION = PROTECTED_DACL_SECURITY_INFORMATION
    -- , pROTECTED_SACL_SECURITY_INFORMATION = PROTECTED_SACL_SECURITY_INFORMATION
    -- , uNPROTECTED_DACL_SECURITY_INFORMATION = UNPROTECTED_DACL_SECURITY_INFORMATION
    -- , uNPROTECTED_SACL_SECURITY_INFORMATION = UNPROTECTED_SACL_SECURITY_INFORMATION

    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 -- lpFileName
        -> SECURITY_INFORMATION -- RequestedInformation
        -> PSECURITY_DESCRIPTOR -- pSecurityDescriptor
        -> DWORD -- nLength
        -> LPDWORD -- lpnLengthNeeded
        -> IO BOOL

    --foreign import stdcall unsafe "windows.h AccessCheck"
    --  c_AccessCheck
    --    :: PSECURITY_DESCRIPTOR -- pSecurityDescriptor
    --    -> HANDLE -- ClientToken
    --    -> DWORD -- DesiredAccess
    --    -> PGENERIC_MAPPING -- GenericMapping
    --    -> PPRIVILEGE_SET -- PrivilegeSet
    --    -> LPDWORD -- PrivilegeSetLength
    --    -> LPDWORD -- GrantedAccess
    --    -> LPBOOL -- AccessStatus
    --    -> IO BOOL

    -- foreign import stdcall unsafe "windows.h OpenThreadToken"
    --    OpenThreadToken
    --      :: HANDLE -- ThreadHandle
    --      -> DWORD -- DesiredAccess
    --      -> BOOL -- OpenAsSelf
    --      -> PHANDLE -- TokenHandle
    --      -> IO BOOL