private static void FillUserNamePasswordLogonInfoBuffer(string domain, string username, string password, out int logonInfoSize, out SafeHGlobalHandle pLogonInfo)
        {
            //LogonInfo
            logonInfoSize = 0;
            int domainLength = 0; int usernameLength = 0; int passwordLength = 0;

            byte[] domainBytes = null; byte[] userNameBytes = null; byte[] passwordBytes = null;
            IntPtr LogonDomainNamePtr = IntPtr.Zero;
            IntPtr UsernamePtr        = IntPtr.Zero;
            IntPtr PasswordPtr        = IntPtr.Zero;

            if (!String.IsNullOrEmpty(domain))
            {
                domainBytes  = System.Text.Encoding.Unicode.GetBytes(domain);
                domainLength = domainBytes.Length;
            }
            if (!String.IsNullOrEmpty(username))
            {
                userNameBytes  = System.Text.Encoding.Unicode.GetBytes(username);
                usernameLength = userNameBytes.Length;
            }
            if (!String.IsNullOrEmpty(password))
            {
                passwordBytes  = System.Text.Encoding.Unicode.GetBytes(password);
                passwordLength = passwordBytes.Length;
            }

            logonInfoSize = checked (Marshal.SizeOf(typeof(INTERACTIVE_LOGON)) + usernameLength + passwordLength + domainLength);
            pLogonInfo    = SafeHGlobalHandle.AllocHGlobal(logonInfoSize);
            unsafe
            {
                LogonDomainNamePtr = new IntPtr(pLogonInfo.DangerousGetHandle().ToInt64() + Marshal.SizeOf(typeof(INTERACTIVE_LOGON)));
                if (domainBytes != null)
                {
                    Marshal.Copy(domainBytes, 0, LogonDomainNamePtr, domainLength);
                }

                UsernamePtr = new IntPtr(pLogonInfo.DangerousGetHandle().ToInt64() + Marshal.SizeOf(typeof(INTERACTIVE_LOGON)) + domainLength);
                if (userNameBytes != null)
                {
                    Marshal.Copy(userNameBytes, 0, UsernamePtr, usernameLength);
                }

                PasswordPtr = new IntPtr(pLogonInfo.DangerousGetHandle().ToInt64() + Marshal.SizeOf(typeof(INTERACTIVE_LOGON)) + domainLength + usernameLength);
                if (passwordBytes != null)
                {
                    Marshal.Copy(passwordBytes, 0, PasswordPtr, passwordLength);
                }

                INTERACTIVE_LOGON *pInfo = (INTERACTIVE_LOGON *)pLogonInfo.DangerousGetHandle().ToPointer();
                pInfo->MessageType     = (int)KERB_LOGON_SUBMIT_TYPE.KerbInteractiveLogon;
                pInfo->LogonDomainName = new UNICODE_INTPTR_STRING(domainLength, domainLength + 1, LogonDomainNamePtr);
                pInfo->UserName        = new UNICODE_INTPTR_STRING(usernameLength, usernameLength + 1, UsernamePtr);
                pInfo->Password        = new UNICODE_INTPTR_STRING(passwordLength, passwordLength + 1, PasswordPtr);
            }
        }
 //callers should delete the allocated memory by closing SafeHGlobalHandle pHandle
 internal static UNICODE_INTPTR_STRING ConvertByteStringToUnicodeIntPtrString(byte[] byteString, out SafeHGlobalHandle pHandle)
 {
     pHandle = SafeHGlobalHandle.AllocHGlobal(byteString.Length + 1);
     Marshal.Copy(byteString, 0, pHandle.DangerousGetHandle(), byteString.Length);
     return(new UNICODE_INTPTR_STRING(byteString.Length, byteString.Length + 1, pHandle.DangerousGetHandle()));
 }