NTSTATUS
RtlCreateUserSecurityObject(
  IN  PRTL_ACE_DATA AceData,
  IN  ULONG AceCount,
  IN  PSID OwnerSid,
  IN  PSID GroupSid,
  IN  BOOLEAN IsDirectoryObject,
  IN  PGENERIC_MAPPING GenericMapping,
  OUT PSECURITY_DESCRIPTOR *NewDescriptor
  );

Routine Description:

    This function creates the DACL for the security descriptor based on
    on the ACE information specified, and creates the security descriptor
    which becomes the user-mode security object.

    A sample usage of this function:

        //
        // Structure that describes the mapping of Generic access rights to
        // object specific access rights for the ConfigurationInfo object.
        //

        GENERIC_MAPPING WsConfigInfoMapping = {
            STANDARD_RIGHTS_READ            |      // Generic read
                WKSTA_CONFIG_GUEST_INFO_GET |
                WKSTA_CONFIG_USER_INFO_GET  |
                WKSTA_CONFIG_ADMIN_INFO_GET,
            STANDARD_RIGHTS_WRITE |                // Generic write
                WKSTA_CONFIG_INFO_SET,
            STANDARD_RIGHTS_EXECUTE,               // Generic execute
            WKSTA_CONFIG_ALL_ACCESS                // Generic all
            };

        //
        // Order matters!  These ACEs are inserted into the DACL in the
        // following order.  Security access is granted or denied based on
        // the order of the ACEs in the DACL.
        //

        RTL_ACE_DATA AceData[4] = {
            {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
                   GENERIC_ALL,                  &LocalAdminSid},

            {ACCESS_DENIED_ACE_TYPE,  0, 0,
                   GENERIC_ALL,                  &NetworkSid},

            {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
                   WKSTA_CONFIG_GUEST_INFO_GET |
                   WKSTA_CONFIG_USER_INFO_GET,   &DomainUsersSid},

            {ACCESS_ALLOWED_ACE_TYPE, 0, 0,
                   WKSTA_CONFIG_GUEST_INFO_GET,  &DomainGuestsSid}
            };

        PSECURITY_DESCRIPTOR WkstaSecurityObject;


        return RtlCreateUserSecurityObject(
                   AceData,
                   4,
                   LocalSystemSid,
                   LocalSystemSid,
                   FALSE,
                   &WsConfigInfoMapping,
                   &WkstaSecurityObject
                   );

Arguments:

    AceData - Supplies the structure of information that describes the DACL.

    AceCount - Supplies the number of entries in AceData structure.

    OwnerSid - Supplies the pointer to the SID of the security descriptor
        owner.

    GroupSid - Supplies the pointer to the SID of the security descriptor
        primary group.

    IsDirectoryObject - Supplies the flag which indicates whether the
        user-mode object is a directory object.

    GenericMapping - Supplies the pointer to a generic mapping array denoting
        the mapping between each generic right to specific rights.

    NewDescriptor - Returns a pointer to the self-relative security descriptor
        which represents the user-mode object.

Return Value:

    STATUS_SUCCESS - if successful
    STATUS_NO_MEMORY - if cannot allocate memory for DACL, ACEs, and
        security descriptor.

    Any other status codes returned from the security Rtl routines.

    NOTE : the user security object created by calling this function may be
                freed up by calling RtlDeleteSecurityObject().