private static byte[] BinaryFormFromSddlForm(string sddlForm)
{
if (sddlForm == null)
{
throw new ArgumentNullException(nameof(sddlForm));
}
Contract.EndContractBlock();
int error;
IntPtr byteArray = IntPtr.Zero;
uint byteArraySize = 0;
byte[] binaryForm = null;
try
{
if (!Interop.Advapi32.ConvertStringSdToSd(
sddlForm,
GenericSecurityDescriptor.Revision,
out byteArray,
ref byteArraySize))
{
error = Marshal.GetLastWin32Error();
if (error == Interop.Errors.ERROR_INVALID_PARAMETER ||
error == Interop.Errors.ERROR_INVALID_ACL ||
error == Interop.Errors.ERROR_INVALID_SECURITY_DESCR ||
error == Interop.Errors.ERROR_UNKNOWN_REVISION)
{
throw new ArgumentException(
SR.ArgumentException_InvalidSDSddlForm,
nameof(sddlForm));
}
else if (error == Interop.Errors.ERROR_NOT_ENOUGH_MEMORY)
{
throw new OutOfMemoryException();
}
else if (error == Interop.Errors.ERROR_INVALID_SID)
{
throw new ArgumentException(
SR.AccessControl_InvalidSidInSDDLString,
nameof(sddlForm));
}
else if (error != Interop.Errors.ERROR_SUCCESS)
{
Debug.Assert(false, string.Format(CultureInfo.InvariantCulture, "Unexpected error out of Win32.ConvertStringSdToSd: {0}", error));
// TODO : This should be a Win32Exception once that type is available
throw new Exception();
}
}
binaryForm = new byte[byteArraySize];
//
// Extract the data from the returned pointer
//
Marshal.Copy(byteArray, binaryForm, 0, (int)byteArraySize);
}
finally
{
//
// Now is a good time to get rid of the returned pointer
//
if (byteArray != IntPtr.Zero)
{
Interop.Kernel32.LocalFree(byteArray);
}
}
return binaryForm;
}