BOOL WINAPI IsValidSecurityDescriptor(
  _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor
);

BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
  _In_  LPCSTR              StringSecurityDescriptor,
  _In_  DWORD                StringSDRevision,
  _Out_ PSECURITY_DESCRIPTOR *SecurityDescriptor,
  _Out_ PULONG               SecurityDescriptorSize
);

BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
  _In_  LPWSTR              StringSecurityDescriptor,
  _In_  DWORD                StringSDRevision,
  _Out_ PSECURITY_DESCRIPTOR *SecurityDescriptor,
  _Out_ PULONG               SecurityDescriptorSize
);

BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(
  _In_  PSECURITY_DESCRIPTOR SecurityDescriptor,
  _In_  DWORD                RequestedStringSDRevision,
  _In_  DWORD                SecurityInformation,
  _Out_ LPCSTR               *StringSecurityDescriptor,
  _Out_ PULONG               StringSecurityDescriptorLen
);


BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(
  _In_  PSECURITY_DESCRIPTOR SecurityDescriptor,
  _In_  DWORD                RequestedStringSDRevision,
  _In_  DWORD                SecurityInformation,
  _Out_ LPWSTR               *StringSecurityDescriptor,
  _Out_ PULONG               StringSecurityDescriptorLen
);


/* From Win10 securitybaseapi.h*/


BOOL WINAPI GetSecurityDescriptorControl(
    _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
    _Out_ PSECURITY_DESCRIPTOR_CONTROL pControl,
    _Out_ LPDWORD lpdwRevision
    );



BOOL WINAPI GetSecurityDescriptorDacl(
    _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
    _Out_ LPBOOL lpbDaclPresent,
    _Outptr_ PACL * pDacl,
    _Out_ LPBOOL lpbDaclDefaulted
    );


BOOL WINAPI GetSecurityDescriptorGroup(
    _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
    _Outptr_ PSID * pGroup,
    _Out_ LPBOOL lpbGroupDefaulted
    );


DWORD WINAPI GetSecurityDescriptorLength(
    _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor
    );


BOOL WINAPI GetSecurityDescriptorOwner(
    _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
    _Outptr_ PSID * pOwner,
    _Out_ LPBOOL lpbOwnerDefaulted
    );


DWORD WINAPI GetSecurityDescriptorRMControl(
    _In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
    _Out_ PUCHAR RMControl
    );


BOOL WINAPI GetSecurityDescriptorSacl(
    _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
    _Out_ LPBOOL lpbSaclPresent,
    _Outptr_ PACL * pSacl,
    _Out_ LPBOOL lpbSaclDefaulted
    );

DWORD WINAPI GetLengthSid(
  _In_ PSID pSid
);

BOOL EqualSid(
  PSID pSid1,
  PSID pSid2
);

BOOL CopySid(
  DWORD nDestinationSidLength,
  PSID  pDestinationSid,
  PSID  pSourceSid
);


PSID_IDENTIFIER_AUTHORITY WINAPI GetSidIdentifierAuthority(
    _In_ PSID pSid
);


DWORD WINAPI GetSidLengthRequired(
    _In_ UCHAR nSubAuthorityCount
);


PDWORD WINAPI GetSidSubAuthority(
    _In_ PSID pSid,
    _In_ DWORD nSubAuthority
);

/* Yep not the good definition (return PUCHAR)
 * but who want this function to returns Python String..
 */
LPBYTE WINAPI GetSidSubAuthorityCount(
    _In_ PSID pSid
    );

PVOID WINAPI FreeSid(
    _In_ PSID pSid
    );


BOOL WINAPI GetAce(
    _In_ PACL pAcl,
    _In_ DWORD dwAceIndex,
    _Outptr_ LPVOID * pAce
    );


BOOL WINAPI GetAclInformation(
    _In_ PACL pAcl,
    _Out_ LPVOID pAclInformation,
    _In_ DWORD nAclInformationLength,
    _In_ ACL_INFORMATION_CLASS dwAclInformationClass
    );

/* VOID */
PVOID MapGenericMask(
  PDWORD           AccessMask,
  PGENERIC_MAPPING GenericMapping
);

BOOL AccessCheck(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
  HANDLE               ClientToken,
  DWORD                DesiredAccess,
  PGENERIC_MAPPING     GenericMapping,
  PPRIVILEGE_SET       PrivilegeSet,
  LPDWORD              PrivilegeSetLength,
  LPDWORD              GrantedAccess,
  LPBOOL               AccessStatus
);


DWORD WINAPI GetNamedSecurityInfoA(
  _In_      LPCSTR               pObjectName,
  _In_      SE_OBJECT_TYPE       ObjectType,
  _In_      SECURITY_INFORMATION SecurityInfo,
  _Out_opt_ PSID                 *ppsidOwner,
  _Out_opt_ PSID                 *ppsidGroup,
  _Out_opt_ PACL                 *ppDacl,
  _Out_opt_ PACL                 *ppSacl,
  _Out_opt_ PSECURITY_DESCRIPTOR *ppSecurityDescriptor
);


DWORD WINAPI GetNamedSecurityInfoW(
  _In_      LPWSTR               pObjectName,
  _In_      SE_OBJECT_TYPE       ObjectType,
  _In_      SECURITY_INFORMATION SecurityInfo,
  _Out_opt_ PSID                 *ppsidOwner,
  _Out_opt_ PSID                 *ppsidGroup,
  _Out_opt_ PACL                 *ppDacl,
  _Out_opt_ PACL                 *ppSacl,
  _Out_opt_ PSECURITY_DESCRIPTOR *ppSecurityDescriptor
);


DWORD WINAPI GetSecurityInfo(
  _In_      HANDLE               handle,
  _In_      SE_OBJECT_TYPE       ObjectType,
  _In_      SECURITY_INFORMATION SecurityInfo,
  _Out_opt_ PSID                 *ppsidOwner,
  _Out_opt_ PSID                 *ppsidGroup,
  _Out_opt_ PACL                 *ppDacl,
  _Out_opt_ PACL                 *ppSacl,
  _Out_opt_ PSECURITY_DESCRIPTOR *ppSecurityDescriptor
);

DWORD SetSecurityInfo(
  HANDLE               handle,
  SE_OBJECT_TYPE       ObjectType,
  SECURITY_INFORMATION SecurityInfo,
  PSID                 psidOwner,
  PSID                 psidGroup,
  PACL                 pDacl,
  PACL                 pSacl
);


DWORD SetNamedSecurityInfoA(
  LPSTR                pObjectName,
  SE_OBJECT_TYPE       ObjectType,
  SECURITY_INFORMATION SecurityInfo,
  PSID                 psidOwner,
  PSID                 psidGroup,
  PACL                 pDacl,
  PACL                 pSacl
);


DWORD SetNamedSecurityInfoW(
  LPWSTR               pObjectName,
  SE_OBJECT_TYPE       ObjectType,
  SECURITY_INFORMATION SecurityInfo,
  PSID                 psidOwner,
  PSID                 psidGroup,
  PACL                 pDacl,
  PACL                 pSacl
);

/* Not documented but exported : guess from test*/

DWORD GetStringConditionFromBinary(
  BYTE*               BinaryAceCondition,
  DWORD               BinaryAceConditionSize,
  DWORD               Reserved1,
  LPWSTR              *StringAceCondition
);


BOOL AddAccessAllowedAce(
  PACL  pAcl,
  DWORD dwAceRevision,
  DWORD AccessMask,
  PSID  pSid
);

BOOL SetSecurityDescriptorDacl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
  BOOL                 bDaclPresent,
  PACL                 pDacl,
  BOOL                 bDaclDefaulted
);


BOOL InitializeAcl(
  PACL  pAcl,
  DWORD nAclLength,
  DWORD dwAclRevision
);


BOOL InitializeSecurityDescriptor(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
  DWORD                dwRevision
);


BOOL SetAclInformation(
  PACL                  pAcl,
  LPVOID                pAclInformation,
  DWORD                 nAclInformationLength,
  ACL_INFORMATION_CLASS dwAclInformationClass
);

BOOL AddAccessAllowedAceEx(
  PACL  pAcl,
  DWORD dwAceRevision,
  DWORD AceFlags,
  DWORD AccessMask,
  PSID  pSid
);


BOOL AddAccessDeniedAce(
  PACL  pAcl,
  DWORD dwAceRevision,
  DWORD AccessMask,
  PSID  pSid
);

BOOL AddAccessDeniedAceEx(
  PACL  pAcl,
  DWORD dwAceRevision,
  DWORD AceFlags,
  DWORD AccessMask,
  PSID  pSid
);


DWORD BuildSecurityDescriptorW(
  PTRUSTEE_W           pOwner,
  PTRUSTEE_W           pGroup,
  ULONG                cCountOfAccessEntries,
  PEXPLICIT_ACCESS_W   pListOfAccessEntries,
  ULONG                cCountOfAuditEntries,
  PEXPLICIT_ACCESS_W   pListOfAuditEntries,
  PSECURITY_DESCRIPTOR pOldSD,
  PULONG               pSizeNewSD,
  PSECURITY_DESCRIPTOR *pNewSD
);