public static unsafe object QueryContextAttributes(SafeDeleteContext securityContext, ContextAttribute contextAttribute)
        {
            int size = IntPtr.Size;
            Type handleType = null;
            switch (contextAttribute)
            {
                case ContextAttribute.Sizes:
                    size = SecSizes.SizeOf;
                    break;

                case ContextAttribute.Names:
                    handleType = typeof(SafeFreeContextBuffer);
                    break;

                case ContextAttribute.Lifespan:
                    size = LifeSpan_Struct.Size;
                    break;

                case ContextAttribute.StreamSizes:
                    size = StreamSizes.SizeOf;
                    break;

                case ContextAttribute.SessionKey:
                    handleType = typeof(SafeFreeContextBuffer);
                    size = SecPkgContext_SessionKey.Size;
                    break;

                case ContextAttribute.PackageInfo:
                    handleType = typeof(SafeFreeContextBuffer);
                    break;

                case ContextAttribute.NegotiationInfo:
                    handleType = typeof(SafeFreeContextBuffer);
                    size = Marshal.SizeOf(typeof(NegotiationInfo));
                    break;

                case ContextAttribute.Flags:
                    break;

                case ContextAttribute.RemoteCertificate:
                    handleType = typeof(SafeFreeCertContext);
                    break;

                case ContextAttribute.LocalCertificate:
                    handleType = typeof(SafeFreeCertContext);
                    break;

                case ContextAttribute.ConnectionInfo:
                    size = Marshal.SizeOf(typeof(SslConnectionInfo));
                    break;

                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("contextAttribute", (int) contextAttribute, typeof(ContextAttribute)));
            }
            SafeHandle refHandle = null;
            object obj2 = null;
            try
            {
                byte[] buffer = new byte[size];
                int error = QueryContextAttributes(securityContext, contextAttribute, buffer, handleType, out refHandle);
                if (error != 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                }
                switch (contextAttribute)
                {
                    case ContextAttribute.Sizes:
                        break;

                    case ContextAttribute.Names:
                        return Marshal.PtrToStringUni(refHandle.DangerousGetHandle());

                    case ContextAttribute.Lifespan:
                        return new LifeSpan(buffer);

                    case ContextAttribute.DceInfo:
                    case (ContextAttribute.StreamSizes | ContextAttribute.Names):
                    case ContextAttribute.Authority:
                    case (ContextAttribute.Authority | ContextAttribute.Names):
                    case ((ContextAttribute) 8):
                    case (ContextAttribute.PackageInfo | ContextAttribute.Names):
                    case (ContextAttribute.NegotiationInfo | ContextAttribute.Names):
                        return obj2;

                    case ContextAttribute.StreamSizes:
                        return new StreamSizes(buffer);

                    case ContextAttribute.SessionKey:
                        try
                        {
                            byte[] buffer4;
                            if (((buffer4 = buffer) == null) || (buffer4.Length == 0))
                            {
                                fixed (IntPtr* ptrRef2 = null)
                                {
                                }
                            }
                            obj2 = new SecuritySessionKeyClass(refHandle, Marshal.ReadInt32(new IntPtr((void*) ptrRef2)));
                        }
                        finally
                        {
                            ptrRef2 = null;
                        }
                        return obj2;

                    case ContextAttribute.PackageInfo:
                        return new SecurityPackageInfoClass(refHandle, 0);

                    case ContextAttribute.NegotiationInfo:
                        try
                        {
                            byte[] buffer3;
                            if (((buffer3 = buffer) == null) || (buffer3.Length == 0))
                            {
                                fixed (IntPtr* ptrRef = null)
                                {
                                }
                            }
                            return new NegotiationInfoClass(refHandle, Marshal.ReadInt32(new IntPtr((void*) ptrRef), NegotiationInfo.NegotiationStateOffset));
                        }
                        finally
                        {
                            ptrRef = null;
                        }
                        goto Label_026A;

                    case ContextAttribute.Flags:
                        try
                        {
                            fixed (byte* numRef = buffer)
                            {
                                return Marshal.ReadInt32(new IntPtr((void*) numRef));
                            }
                        }
                        finally
                        {
                            numRef = null;
                        }
                        break;

                    case ContextAttribute.RemoteCertificate:
                    case ContextAttribute.LocalCertificate:
                        goto Label_026A;

                    case ContextAttribute.ConnectionInfo:
                        return new SslConnectionInfo(buffer);

                    default:
                        return obj2;
                }
                return new SecSizes(buffer);
            Label_026A:
                obj2 = refHandle;
                refHandle = null;
                return obj2;
            }
            finally
            {
                if (refHandle != null)
                {
                    refHandle.Close();
                }
            }
            return obj2;
        }
        public static unsafe object QueryContextAttributes(SafeDeleteContext securityContext, ContextAttribute contextAttribute)
        {
            int  size       = IntPtr.Size;
            Type handleType = null;

            switch (contextAttribute)
            {
            case ContextAttribute.Sizes:
                size = SecSizes.SizeOf;
                break;

            case ContextAttribute.Names:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case ContextAttribute.Lifespan:
                size = LifeSpan_Struct.Size;
                break;

            case ContextAttribute.StreamSizes:
                size = StreamSizes.SizeOf;
                break;

            case ContextAttribute.SessionKey:
                handleType = typeof(SafeFreeContextBuffer);
                size       = SecPkgContext_SessionKey.Size;
                break;

            case ContextAttribute.PackageInfo:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case ContextAttribute.NegotiationInfo:
                handleType = typeof(SafeFreeContextBuffer);
                size       = Marshal.SizeOf(typeof(NegotiationInfo));
                break;

            case ContextAttribute.Flags:
                break;

            case ContextAttribute.RemoteCertificate:
                handleType = typeof(SafeFreeCertContext);
                break;

            case ContextAttribute.LocalCertificate:
                handleType = typeof(SafeFreeCertContext);
                break;

            case ContextAttribute.ConnectionInfo:
                size = Marshal.SizeOf(typeof(SslConnectionInfo));
                break;

            default:
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("contextAttribute", (int)contextAttribute, typeof(ContextAttribute)));
            }
            SafeHandle refHandle = null;
            object     obj2      = null;

            try
            {
                byte[] buffer = new byte[size];
                int    error  = QueryContextAttributes(securityContext, contextAttribute, buffer, handleType, out refHandle);
                if (error != 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                }
                switch (contextAttribute)
                {
                case ContextAttribute.Sizes:
                    break;

                case ContextAttribute.Names:
                    return(Marshal.PtrToStringUni(refHandle.DangerousGetHandle()));

                case ContextAttribute.Lifespan:
                    return(new LifeSpan(buffer));

                case ContextAttribute.DceInfo:
                case (ContextAttribute.StreamSizes | ContextAttribute.Names):
                case ContextAttribute.Authority:
                case (ContextAttribute.Authority | ContextAttribute.Names):
                case ((ContextAttribute)8):
                case (ContextAttribute.PackageInfo | ContextAttribute.Names):
                case (ContextAttribute.NegotiationInfo | ContextAttribute.Names):
                    return(obj2);

                case ContextAttribute.StreamSizes:
                    return(new StreamSizes(buffer));

                case ContextAttribute.SessionKey:
                    try
                    {
                        byte[] buffer4;
                        if (((buffer4 = buffer) == null) || (buffer4.Length == 0))
                        {
                            fixed(IntPtr *ptrRef2 = null)
                            {
                            }
                        }
                        obj2 = new SecuritySessionKeyClass(refHandle, Marshal.ReadInt32(new IntPtr((void *)ptrRef2)));
                    }
                    finally
                    {
                        ptrRef2 = null;
                    }
                    return(obj2);

                case ContextAttribute.PackageInfo:
                    return(new SecurityPackageInfoClass(refHandle, 0));

                case ContextAttribute.NegotiationInfo:
                    try
                    {
                        byte[] buffer3;
                        if (((buffer3 = buffer) == null) || (buffer3.Length == 0))
                        {
                            fixed(IntPtr *ptrRef = null)
                            {
                            }
                        }
                        return(new NegotiationInfoClass(refHandle, Marshal.ReadInt32(new IntPtr((void *)ptrRef), NegotiationInfo.NegotiationStateOffset)));
                    }
                    finally
                    {
                        ptrRef = null;
                    }
                    goto Label_026A;

                case ContextAttribute.Flags:
                    try
                    {
                        fixed(byte *numRef = buffer)
                        {
                            return(Marshal.ReadInt32(new IntPtr((void *)numRef)));
                        }
                    }
                    finally
                    {
                        numRef = null;
                    }
                    break;

                case ContextAttribute.RemoteCertificate:
                case ContextAttribute.LocalCertificate:
                    goto Label_026A;

                case ContextAttribute.ConnectionInfo:
                    return(new SslConnectionInfo(buffer));

                default:
                    return(obj2);
                }
                return(new SecSizes(buffer));

Label_026A:
                obj2      = refHandle;
                refHandle = null;
                return(obj2);
            }
            finally
            {
                if (refHandle != null)
                {
                    refHandle.Close();
                }
            }
            return(obj2);
        }
        public static unsafe object QueryContextAttributes(
            SafeDeleteContext securityContext,
            ContextAttribute contextAttribute)
        {
            int  nativeBlockSize = IntPtr.Size;
            Type handleType      = null;

            switch (contextAttribute)
            {
            case ContextAttribute.Flags:
                break;

            case ContextAttribute.Sizes:
                nativeBlockSize = SecSizes.SizeOf;
                break;

            case ContextAttribute.StreamSizes:
                nativeBlockSize = StreamSizes.SizeOf;
                break;

            case ContextAttribute.Names:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case ContextAttribute.PackageInfo:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case ContextAttribute.NegotiationInfo:
                handleType      = typeof(SafeFreeContextBuffer);
                nativeBlockSize = Marshal.SizeOf(typeof(NegotiationInfo));
                break;

            case ContextAttribute.RemoteCertificate:
                handleType = typeof(SafeFreeCertContext);
                break;

            case ContextAttribute.LocalCertificate:
                handleType = typeof(SafeFreeCertContext);
                break;

            case ContextAttribute.ConnectionInfo:
                nativeBlockSize = Marshal.SizeOf(typeof(SslConnectionInfo));
                break;

            case ContextAttribute.Lifespan:
                nativeBlockSize = LifeSpan_Struct.Size;
                break;

            case ContextAttribute.SessionKey:
                handleType      = typeof(SafeFreeContextBuffer);
                nativeBlockSize = SecPkgContext_SessionKey.Size;
                break;

            default:
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("contextAttribute", (int)contextAttribute,
                                                                                                           typeof(ContextAttribute)));
            }

            SafeHandle sspiHandle = null;
            object     attribute  = null;

            try
            {
                byte[] nativeBuffer = new byte[nativeBlockSize];
                int    errorCode    = QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle);
                if (errorCode != 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
                }

                switch (contextAttribute)
                {
                case ContextAttribute.Flags:
                    fixed(byte *pnativeBuffer = nativeBuffer)
                    {
                        attribute = (object)Marshal.ReadInt32(new IntPtr(pnativeBuffer));
                    }
                    break;

                case ContextAttribute.Sizes:
                    attribute = new SecSizes(nativeBuffer);
                    break;

                case ContextAttribute.StreamSizes:
                    attribute = new StreamSizes(nativeBuffer);
                    break;

                case ContextAttribute.Names:
                    attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
                    break;

                case ContextAttribute.PackageInfo:
                    attribute = new SecurityPackageInfoClass(sspiHandle, 0);
                    break;

                case ContextAttribute.NegotiationInfo:
                    unsafe
                    {
                        fixed(void *ptr = nativeBuffer)
                        {
                            attribute = new NegotiationInfoClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr), NegotiationInfo.NegotiationStateOffset));
                        }
                    }
                    break;

                case ContextAttribute.LocalCertificate:
                    goto case ContextAttribute.RemoteCertificate;

                case ContextAttribute.RemoteCertificate:
                    attribute  = sspiHandle;
                    sspiHandle = null;
                    break;

                case ContextAttribute.ConnectionInfo:
                    attribute = new SslConnectionInfo(nativeBuffer);
                    break;

                case ContextAttribute.Lifespan:
                    attribute = new LifeSpan(nativeBuffer);
                    break;

                case ContextAttribute.SessionKey:
                    unsafe
                    {
                        fixed(void *ptr = nativeBuffer)
                        {
                            attribute = new SecuritySessionKeyClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr)));
                        }
                    }
                    break;

                default:
                    // will return null
                    break;
                }
            }
            finally
            {
                if (sspiHandle != null)
                {
                    sspiHandle.Close();
                }
            }
            return(attribute);
        }
        public static unsafe object QueryContextAttributes(
            SafeDeleteContext securityContext,
            ContextAttribute contextAttribute)
        {
            int nativeBlockSize = IntPtr.Size;
            Type handleType = null;

            switch (contextAttribute)
            {
                case ContextAttribute.Flags:
                    break;
                case ContextAttribute.Sizes:
                    nativeBlockSize = SecSizes.SizeOf;
                    break;
                case ContextAttribute.StreamSizes:
                    nativeBlockSize = StreamSizes.SizeOf;
                    break;
                case ContextAttribute.Names:
                    handleType = typeof(SafeFreeContextBuffer);
                    break;
                case ContextAttribute.PackageInfo:
                    handleType = typeof(SafeFreeContextBuffer);
                    break;
                case ContextAttribute.NegotiationInfo:
                    handleType = typeof(SafeFreeContextBuffer);
                    nativeBlockSize = Marshal.SizeOf(typeof(NegotiationInfo));
                    break;
                case ContextAttribute.RemoteCertificate:
                    handleType = typeof(SafeFreeCertContext);
                    break;
                case ContextAttribute.LocalCertificate:
                    handleType = typeof(SafeFreeCertContext);
                    break;
                case ContextAttribute.ConnectionInfo:
                    nativeBlockSize = Marshal.SizeOf(typeof(SslConnectionInfo));
                    break;
                case ContextAttribute.Lifespan:
                    nativeBlockSize = LifeSpan_Struct.Size;
                    break;
                case ContextAttribute.SessionKey:
                    handleType = typeof(SafeFreeContextBuffer);
                    nativeBlockSize = SecPkgContext_SessionKey.Size;
                    break;
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("contextAttribute", (int)contextAttribute,
                    typeof(ContextAttribute)));
            }

            SafeHandle sspiHandle = null;
            object attribute = null;
            try
            {
                byte[] nativeBuffer = new byte[nativeBlockSize];
                int errorCode = QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle);
                if (errorCode != 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
                }

                switch (contextAttribute)
                {
                    case ContextAttribute.Flags:
                        fixed (byte* pnativeBuffer = nativeBuffer)
                        {
                            attribute = (object)Marshal.ReadInt32(new IntPtr(pnativeBuffer));
                        }
                        break;
                    case ContextAttribute.Sizes:
                        attribute = new SecSizes(nativeBuffer);
                        break;
                    case ContextAttribute.StreamSizes:
                        attribute = new StreamSizes(nativeBuffer);
                        break;
                    case ContextAttribute.Names:
                        attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
                        break;
                    case ContextAttribute.PackageInfo:
                        attribute = new SecurityPackageInfoClass(sspiHandle, 0);
                        break;
                    case ContextAttribute.NegotiationInfo:
                        unsafe
                        {
                            fixed (void* ptr = nativeBuffer)
                            {
                                attribute = new NegotiationInfoClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr), NegotiationInfo.NegotiationStateOffset));
                            }
                        }
                        break;
                    case ContextAttribute.LocalCertificate:
                        goto case ContextAttribute.RemoteCertificate;
                    case ContextAttribute.RemoteCertificate:
                        attribute = sspiHandle;
                        sspiHandle = null;
                        break;
                    case ContextAttribute.ConnectionInfo:
                        attribute = new SslConnectionInfo(nativeBuffer);
                        break;
                    case ContextAttribute.Lifespan:
                        attribute = new LifeSpan(nativeBuffer);
                        break;
                    case ContextAttribute.SessionKey:
                        unsafe
                        {
                            fixed (void* ptr = nativeBuffer)
                            {
                                attribute = new SecuritySessionKeyClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr)));
                            }
                        }
                        break;
                    default:
                        // will return null
                        break;
                }
            }
            finally
            {
                if (sspiHandle != null)
                {
                    sspiHandle.Close();
                }
            }
            return attribute;
        }