internal static IntPtr CreateAuthData(SecurityWinntAuthIdentity authIndentity)
        {
            IntPtr pAuthData = Marshal.AllocHGlobal(Marshal.SizeOf(authIndentity));

            Marshal.StructureToPtr(authIndentity, pAuthData, false);
            return pAuthData;
        }
        internal static void FreeSecurityWinntAuthIdentity(SecurityWinntAuthIdentity authIdentity)
        {
            if (authIdentity.User != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(authIdentity.User);
                authIdentity.User = IntPtr.Zero;
            }

            if (authIdentity.Domain != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(authIdentity.Domain);
                authIdentity.Domain = IntPtr.Zero;
            }

            if (authIdentity.Password != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(authIdentity.Password);
                authIdentity.Password = IntPtr.Zero;
            }
        }
        internal static void AcquireCredentialsHandle(
            SecurityPackageType packageType,
            AccountCredential accountCredential,
            string serverPrincipal,
            uint fCredentialUse,
            out SecurityHandle credentialHandle)
        {
            string stringPackage = SspiUtility.GetPackageStringName(packageType);

            SecurityInteger expiryTime;
            SecurityWinntAuthIdentity authIdentity = new SecurityWinntAuthIdentity(accountCredential);
            IntPtr pAuthData = IntPtr.Zero;
            SchannelCred schannelCred = new SchannelCred();
            schannelCred.dwVersion = NativeMethods.SCHANNEL_CRED_VERSION;
            schannelCred.cCreds = 0;
            schannelCred.paCred = IntPtr.Zero;
            CredSspCred credSsp = new CredSspCred();

            switch (packageType)
            {
                case SecurityPackageType.Ntlm:
                case SecurityPackageType.Kerberos:
                case SecurityPackageType.Negotiate:
                    pAuthData = SspiUtility.CreateAuthData(authIdentity);
                    break;
                case SecurityPackageType.Schannel:
                    pAuthData = SspiUtility.CreateAuthData(schannelCred);
                    break;
                case SecurityPackageType.CredSsp:
                    credSsp.Type = CredSspSubmitType.CredsspSubmitBufferBoth;
                    credSsp.pSchannelCred = CreateAuthData(schannelCred);
                    credSsp.pSpnegoCred = CreateAuthData(authIdentity);
                    pAuthData = CreateAuthData(credSsp);
                    break;
                //default, if other values, exception will be thrown by GetPackageStringName.
                default:
                    throw new ArgumentException("Invlid packageType value.", "packageType");
            }

            uint result = NativeMethods.AcquireCredentialsHandle(
                serverPrincipal,
                stringPackage,
                fCredentialUse,
                IntPtr.Zero,
                pAuthData,
                IntPtr.Zero,
                IntPtr.Zero,
                out credentialHandle,
                out expiryTime);
            //Free memory
            switch (packageType)
            {
                case SecurityPackageType.Ntlm:
                case SecurityPackageType.Kerberos:
                case SecurityPackageType.Negotiate:
                    SspiUtility.FreeSecurityWinntAuthIdentity(authIdentity);
                    break;
                case SecurityPackageType.Schannel:
                    stringPackage = Schannel;
                    SspiUtility.FreeSchannelCred(schannelCred);
                    break;
                case SecurityPackageType.CredSsp:
                    SspiUtility.FreeSecurityWinntAuthIdentity(authIdentity);
                    SspiUtility.FreeSchannelCred(schannelCred);
                    SspiUtility.FreeCredSspCred(credSsp);
                    break;
                //default, if other values, exception will be thrown by GetPackageStringName.
                default:
                    throw new ArgumentException("Invlid packageType value.", "packageType");
            }
            Marshal.FreeHGlobal(pAuthData);

            if (result != NativeMethods.SEC_E_OK)
            {
                throw new SspiException("AquireCredentialsHandle failed", result);
            }
        }