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 GetUserName()
        {
            StringBuilder userNameBuffer = new StringBuilder(64);
            int           nSize          = 64;

            if (!FileSecurityNativeMethods.GetUserName(userNameBuffer, ref nSize))
            {
                if (Marshal.GetLastWin32Error() == FileSecurityNativeMethods.ERROR_INSUFFICIENT_BUFFER)
                {
                    userNameBuffer.EnsureCapacity(nSize);

                    if (!FileSecurityNativeMethods.GetUserName(userNameBuffer, ref nSize))
                    {
                        throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
                    }
                }
                else
                {
                    throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
                }
            }

            return(userNameBuffer.ToString());
        }
        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);
            }
        }
        private static bool SetPrivilege(
            string securityPrivilege,
            bool bEnablePrivilege      // to enable or disable privilege
            )
        {
            var identity    = WindowsIdentity.GetCurrent(TokenAccessLevels.AdjustPrivileges | TokenAccessLevels.Query);
            var accessToken = identity.Token;

            FileSecurityNativeMethods.TOKEN_PRIVILEGES tp;
            FileSecurityNativeMethods.LUID             luid = new FileSecurityNativeMethods.LUID();

            if (!FileSecurityNativeMethods.LookupPrivilegeValue(
                    null,              // lookup privilege on local system
                    securityPrivilege, // privilege to lookup
                    ref luid))         // receives LUID of privilege
            {
                throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
            }

            tp.PrivilegeCount     = 1;
            tp.Privileges         = new FileSecurityNativeMethods.LUID_AND_ATTRIBUTES[1];
            tp.Privileges[0].Luid = luid;
            if (bEnablePrivilege)
            {
                tp.Privileges[0].Attributes = FileSecurityNativeMethods.SE_PRIVILEGE_ENABLED;
            }
            else
            {
                tp.Privileges[0].Attributes = FileSecurityNativeMethods.SE_PRIVILEGE_DISABLED;
            }

            FileSecurityNativeMethods.TOKEN_PRIVILEGES previousPrivileges = new FileSecurityNativeMethods.TOKEN_PRIVILEGES();
            uint previousPrivilegesLength = 0;

            // Enable the privilege or disable all privileges.
            bool succeeded = FileSecurityNativeMethods.AdjustTokenPrivileges(
                accessToken,
                false,
                ref tp,
                1024,
                ref previousPrivileges,
                out previousPrivilegesLength);

            if (!succeeded)
            {
                throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
            }
            else if (Marshal.GetLastWin32Error() == FileSecurityNativeMethods.ERROR_NOT_ALL_ASSIGNED)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            if ((previousPrivileges.Privileges.Count() == 1) &&
                (previousPrivileges.Privileges[0].Luid.LowPart == luid.LowPart) &&
                (previousPrivileges.Privileges[0].Luid.HighPart == luid.HighPart) &&
                (previousPrivileges.Privileges[0].Attributes == FileSecurityNativeMethods.SE_PRIVILEGE_ENABLED))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }