public static void SetFileSecurity(string filePath, string portableSDDL, PreserveSMBPermissions preserveSMBPermissions)
        {
            if (PreserveSMBPermissions.None == preserveSMBPermissions)
            {
                return;
            }

            if (string.IsNullOrEmpty(portableSDDL))
            {
                return;
            }

            IntPtr  pSecurityDescriptor      = new IntPtr();
            UIntPtr securityDescriptorLength = new UIntPtr();

            if (!FileSecurityNativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptor(portableSDDL,
                                                                                               FileSecurityNativeMethods.SDDL_REVISION_1,
                                                                                               out pSecurityDescriptor,
                                                                                               out securityDescriptorLength))
            {
                throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
            }

            try
            {
                FileSecurityNativeMethods.SetFileSecurity(filePath,
                                                          (int)(ToSecurityInfo(preserveSMBPermissions)),
                                                          pSecurityDescriptor);

                int errorCode = Marshal.GetLastWin32Error();
                int hresult   = Marshal.GetHRForLastWin32Error();

                if ((errorCode == FileSecurityNativeMethods.ERROR_PRIVILEGE_NOT_HELD) ||
                    (errorCode == FileSecurityNativeMethods.ERROR_ACCESS_DENIED) ||
                    (errorCode == FileSecurityNativeMethods.ERROR_INVALID_OWNER))
                {
                    throw new Win32Exception(errorCode);
                }

                if (errorCode != 0)
                {
                    Marshal.ThrowExceptionForHR(hresult);
                }
            }
            finally
            {
                FileSecurityNativeMethods.LocalFree(pSecurityDescriptor);
            }
        }
        private static string GetFileSDDL(
            string filePath,
            FileSecurityNativeMethods.SECURITY_INFORMATION securityInfo)
        {
            // Note: to get the SACL, special permissions are needed. Refer https://docs.microsoft.com/en-us/windows/win32/api/aclapi/nf-aclapi-getsecurityinfo
            IntPtr pZero = IntPtr.Zero;
            IntPtr pSid  = pZero;
            IntPtr psd   = pZero;

            uint errorReturn = FileSecurityNativeMethods.GetNamedSecurityInfoW(
                filePath,
                FileSecurityNativeMethods.SE_OBJECT_TYPE.SE_FILE_OBJECT,
                securityInfo,
                out pSid, out pZero, out pZero, out pZero, out psd);

            if (errorReturn != 0)
            {
                throw new Win32Exception((int)errorReturn);
            }

            try
            {
                IntPtr  sdString           = IntPtr.Zero;
                UIntPtr sd_string_size_ptr = new UIntPtr();
                bool    success            = FileSecurityNativeMethods.ConvertSecurityDescriptorToStringSecurityDescriptor(psd, FileSecurityNativeMethods.SDDL_REVISION_1, securityInfo, out sdString, out sd_string_size_ptr);
                try
                {
                    return(Marshal.PtrToStringAuto(sdString));
                }
                finally
                {
                    Marshal.FreeHGlobal(sdString);
                }
            }
            finally
            {
                FileSecurityNativeMethods.LocalFree(psd);
            }
        }
        private static string GetDomainSid(string accountName)
        {
            uint sidLength        = 0;
            uint domainNameLength = 0;

            byte[]        sid        = null;
            StringBuilder domainName = new StringBuilder();

            FileSecurityNativeMethods.SID_NAME_USE peUse;

            // Query buffer size requirement by passing in NULL for Sid and ReferencedDomainName
            if (!FileSecurityNativeMethods.LookupAccountName(null,       // lpSystemName
                                                             accountName,
                                                             null,       // Sid
                                                             ref sidLength,
                                                             domainName, // ReferencedDomainName
                                                             ref domainNameLength,
                                                             out peUse))
            {
                int errorCode = Marshal.GetLastWin32Error();

                if (errorCode != FileSecurityNativeMethods.ERROR_INSUFFICIENT_BUFFER)
                {
                    throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
                }

                sid = new byte[sidLength];
                domainName.EnsureCapacity((int)domainNameLength);

                if (!FileSecurityNativeMethods.LookupAccountName(null,
                                                                 accountName,
                                                                 sid,
                                                                 ref sidLength,
                                                                 domainName,
                                                                 ref domainNameLength,
                                                                 out peUse))
                {
                    throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
                }
            }
            else
            {
                throw new TransferException("Unexpected LookupAccountName success");
            }

            // Get domain Sid from User Sid
            uint domainSidLength = 0;

            byte[] domainSid = null;
            if (!FileSecurityNativeMethods.GetWindowsAccountDomainSid(sid, domainSid, ref domainSidLength))
            {
                int errorCode = Marshal.GetLastWin32Error();

                if (errorCode != FileSecurityNativeMethods.ERROR_INSUFFICIENT_BUFFER)
                {
                    throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
                }

                domainSid = new byte[domainSidLength];

                if (!FileSecurityNativeMethods.GetWindowsAccountDomainSid(sid, domainSid, ref domainSidLength))
                {
                    throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
                }
            }
            else
            {
                throw new TransferException("Unexpected GetWindowsAccountDomainSid success");
            }

            // Get string corresponding to SID
            IntPtr domainSidPtr;

            if (!FileSecurityNativeMethods.ConvertSidToStringSid(domainSid, out domainSidPtr))
            {
                throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
            }

            try
            {
                return(Marshal.PtrToStringAuto(domainSidPtr));
            }
            finally
            {
                FileSecurityNativeMethods.LocalFree(domainSidPtr);
            }
        }