private static T GetSecurityDescriptor <T>(uint lastError, bool isFolder, string path, SafeGlobalMemoryBufferHandle securityDescriptor)
        {
            ObjectSecurity objectSecurity;

            using (securityDescriptor)
            {
                if (lastError == Win32Errors.ERROR_FILE_NOT_FOUND || lastError == Win32Errors.ERROR_PATH_NOT_FOUND)
                {
                    lastError = isFolder ? Win32Errors.ERROR_PATH_NOT_FOUND : Win32Errors.ERROR_FILE_NOT_FOUND;
                }


                // If the function fails, the return value is zero.
                if (lastError != Win32Errors.ERROR_SUCCESS)
                {
                    if (!Utils.IsNullOrWhiteSpace(path))
                    {
                        NativeError.ThrowException(lastError, path);
                    }
                    else
                    {
                        NativeError.ThrowException((int)lastError);
                    }
                }

                if (!NativeMethods.IsValidHandle(securityDescriptor, false))
                {
                    throw new IOException(Resources.Returned_Invalid_Security_Descriptor);
                }


                uint length = Security.NativeMethods.GetSecurityDescriptorLength(securityDescriptor);

                // Seems not to work: Method .CopyTo: length > Capacity, so an Exception is thrown.
                //byte[] managedBuffer = new byte[length];
                //pSecurityDescriptor.CopyTo(managedBuffer, 0, (int) length);

                byte[] managedBuffer = securityDescriptor.ToByteArray(0, (int)length);

                objectSecurity = isFolder ? (ObjectSecurity) new DirectorySecurity() : new FileSecurity();
                objectSecurity.SetSecurityDescriptorBinaryForm(managedBuffer);
            }

            return((T)(object)objectSecurity);
        }