// // local system if systemName is null
        public LsaWrapper(string systemName)
        {
            LSA_OBJECT_ATTRIBUTES lsaAttr;
            lsaAttr.RootDirectory = IntPtr.Zero;
            lsaAttr.ObjectName = IntPtr.Zero;
            lsaAttr.Attributes = 0;
            lsaAttr.SecurityDescriptor = IntPtr.Zero;
            lsaAttr.SecurityQualityOfService = IntPtr.Zero;
            lsaAttr.Length = Marshal.SizeOf(typeof(LSA_OBJECT_ATTRIBUTES));
            lsaHandle = IntPtr.Zero;
            LSA_UNICODE_STRING[] system = null;
            if (systemName != null)
            {
                system = new LSA_UNICODE_STRING[1];
                system[0] = InitLsaString(systemName);
            }

            uint ret = Win32Sec.LsaOpenPolicy(system, ref lsaAttr,
            (int)Access.POLICY_ALL_ACCESS, out lsaHandle);
            if (ret == 0)
                return;
            if (ret == STATUS_ACCESS_DENIED)
            {
                throw new UnauthorizedAccessException();
            }
            if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
            {
                throw new OutOfMemoryException();
            }
            throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret));
        }
        // helper functions

        static LSA_UNICODE_STRING InitLsaString(string s)
        {
            // Unicode strings max. 32KB
            if (s.Length > 0x7ffe)
            {
                throw new ArgumentException("String too long");
            }
            LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING();

            lus.Buffer        = s;
            lus.Length        = (ushort)(s.Length * sizeof(char));
            lus.MaximumLength = (ushort)(lus.Length + sizeof(char));
            return(lus);
        }
        public void AddPrivileges(string account, string privilege)
        {
            uint ret = 0;

            using (Sid sid = new Sid(account))
            {
                LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1];
                privileges[0] = InitLsaString(privilege);
                ret           = Win32Sec.LsaAddAccountRights(lsaHandle, sid.pSid, privileges, 1);
            }
            if (ret == 0)
            {
                return;
            }
            if (ret == STATUS_ACCESS_DENIED)
            {
                throw new UnauthorizedAccessException();
            }
            if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
            {
                throw new OutOfMemoryException();
            }
            throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret));
        }
 internal static extern uint LsaOpenPolicy(
     LSA_UNICODE_STRING[] SystemName,
     ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
     int AccessMask,
     out IntPtr PolicyHandle
     );
 internal static extern uint LsaAddAccountRights(
     LSA_HANDLE PolicyHandle,
     IntPtr pSID,
     LSA_UNICODE_STRING[] UserRights,
     int CountOfRights
     );
 // helper functions
 static LSA_UNICODE_STRING InitLsaString(string s)
 {
     // Unicode strings max. 32KB
     if (s.Length > 0x7ffe)
         throw new ArgumentException("String too long");
     LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING();
     lus.Buffer = s;
     lus.Length = (ushort)(s.Length * sizeof(char));
     lus.MaximumLength = (ushort)(lus.Length + sizeof(char));
     return lus;
 }
 public void AddPrivileges(string account, string privilege)
 {
     uint ret = 0;
     using (Sid sid = new Sid(account))
     {
         LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1];
         privileges[0] = InitLsaString(privilege);
         ret = Win32Sec.LsaAddAccountRights(lsaHandle, sid.pSid, privileges, 1);
     }
     if (ret == 0)
         return;
     if (ret == STATUS_ACCESS_DENIED)
     {
         throw new UnauthorizedAccessException();
     }
     if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
     {
         throw new OutOfMemoryException();
     }
     throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret));
 }