System.Data.SqlClient.TdsParser.ProcessSNIError C# (CSharp) Метод

ProcessSNIError() приватный Метод

private ProcessSNIError ( System.Data.SqlClient.TdsParserStateObject stateObj ) : SqlError
stateObj System.Data.SqlClient.TdsParserStateObject
Результат SqlError
        internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
        {
#if DEBUG
            // There is an exception here for MARS as its possible that another thread has closed the connection just as we see an error
            Debug.Assert(SniContext.Undefined != stateObj.DebugOnlyCopyOfSniContext || ((_fMARS) && ((_state == TdsParserState.Closed) || (_state == TdsParserState.Broken))), "SniContext must not be None");
#endif
#if MANAGED_SNI
            SNIError sniError = SNIProxy.Singleton.GetLastError();
#else
            SNINativeMethodWrapper.SNI_Error sniError;
            SNINativeMethodWrapper.SNIGetLastError(out sniError);
#endif // MANAGED_SNI
            if (sniError.sniError != 0)
            {
                // handle special SNI error codes that are converted into exception which is not a SqlException.
                switch (sniError.sniError)
                {
                    case (int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithMoreThan64IPs:
                        // Connecting with the MultiSubnetFailover connection option to a SQL Server instance configured with more than 64 IP addresses is not supported.
                        throw SQL.MultiSubnetFailoverWithMoreThan64IPs();

                    case (int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithInstanceSpecified:
                        // Connecting to a named SQL Server instance using the MultiSubnetFailover connection option is not supported.
                        throw SQL.MultiSubnetFailoverWithInstanceSpecified();

                    case (int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithNonTcpProtocol:
                        // Connecting to a SQL Server instance using the MultiSubnetFailover connection option is only supported when using the TCP protocol.
                        throw SQL.MultiSubnetFailoverWithNonTcpProtocol();
                        // continue building SqlError instance
                }
            }
            // PInvoke code automatically sets the length of the string for us
            // So no need to look for \0
            string errorMessage = sniError.errorMessage;

            //  Format SNI errors and add Context Information
            //
            //  General syntax is:
            //  <sqlclient message>
            //  (provider:<SNIx provider>, error: <SNIx error code> - <SNIx error message>)
            //
            // errorMessage | sniError |
            // -------------------------------------------
            // ==null       | x        | must never happen
            // !=null       | != 0     | retrieve corresponding errorMessage from resources
            // !=null       | == 0     | replace text left of errorMessage
            //

#if MANAGED_SNI
            Debug.Assert(!string.IsNullOrEmpty(errorMessage) || sniError.sniError != 0, "Empty error message received from SNI");
#else
            Debug.Assert(!string.IsNullOrEmpty(errorMessage), "Empty error message received from SNI");
#endif

            string sqlContextInfo = SR.GetResourceString(Enum.GetName(typeof(SniContext), stateObj.SniContext), Enum.GetName(typeof(SniContext), stateObj.SniContext));
            string providerRid = String.Format((IFormatProvider)null, "SNI_PN{0}", (int)sniError.provider);
            string providerName = SR.GetResourceString(providerRid, providerRid);
            Debug.Assert(!string.IsNullOrEmpty(providerName), String.Format((IFormatProvider)null, "invalid providerResourceId '{0}'", providerRid));
            uint win32ErrorCode = sniError.nativeError;

            if (sniError.sniError == 0)
            {
                // Provider error. The message from provider is preceded with non-localizable info from SNI
                // strip provider info from SNI
                //
                int iColon = errorMessage.IndexOf(':');
                Debug.Assert(0 <= iColon, "':' character missing in sni errorMessage");
                Debug.Assert(errorMessage.Length > iColon + 1 && errorMessage[iColon + 1] == ' ', "Expecting a space after the ':' character");

                // extract the message excluding the colon and trailing cr/lf chars
                if (0 <= iColon)
                {
                    int len = errorMessage.Length;
                    len -= Environment.NewLine.Length; // exclude newline sequence
                    iColon += 2;  // skip over ": " sequence
                    len -= iColon;
                    /*
                        The error message should come back in the following format: "TCP Provider: MESSAGE TEXT"
                        If the message is received on a Win9x OS, the error message will not contain MESSAGE TEXT 
                        If we get a error message with no message text, just return the entire message otherwise 
                        return just the message text.
                    */
                    if (len > 0)
                    {
                        errorMessage = errorMessage.Substring(iColon, len);
                    }
                }
            }
            else
            {
#if MANAGED_SNI
                // SNI error. Append additional error message info if available.
                //
                string sniLookupMessage = SQL.GetSNIErrorMessage((int)sniError.sniError);
                errorMessage =  (sniError.errorMessage != string.Empty) ?
                                (sniLookupMessage + ": " + sniError.errorMessage) :
                                sniLookupMessage;
#else
                // SNI error. Replace the entire message.
                //
                errorMessage = SQL.GetSNIErrorMessage((int)sniError.sniError);

                // If its a LocalDB error, then nativeError actually contains a LocalDB-specific error code, not a win32 error code
                if (sniError.sniError == (int)SNINativeMethodWrapper.SniSpecialErrors.LocalDBErrorCode)
                {
                    errorMessage += LocalDBAPI.GetLocalDBMessage((int)sniError.nativeError);
                    win32ErrorCode = 0;
                }
#endif // MANAGED_SNI
            }
            errorMessage = String.Format((IFormatProvider)null, "{0} (provider: {1}, error: {2} - {3})",
                sqlContextInfo, providerName, (int)sniError.sniError, errorMessage);

#if MANAGED_SNI
            return new SqlError((int)sniError.nativeError, 0x00, TdsEnums.FATAL_ERROR_CLASS,
                                _server, errorMessage, sniError.function, (int)sniError.lineNumber, win32ErrorCode, sniError.exception);
#else
            return new SqlError((int)sniError.nativeError, 0x00, TdsEnums.FATAL_ERROR_CLASS,
                    _server, errorMessage, sniError.function, (int)sniError.lineNumber, win32ErrorCode);
#endif
        }

Usage Example

Пример #1
0
        internal TdsParserStateObject(TdsParser parser, SNIHandle physicalConnection, bool async)
        {
            // Construct a MARS session
            Debug.Assert(null != parser, "no parser?");
            _parser = parser;
            SniContext = SniContext.Snix_GetMarsSession;

            Debug.Assert(null != _parser._physicalStateObj, "no physical session?");
            Debug.Assert(null != _parser._physicalStateObj._inBuff, "no in buffer?");
            Debug.Assert(null != _parser._physicalStateObj._outBuff, "no out buffer?");
            Debug.Assert(_parser._physicalStateObj._outBuff.Length ==
                         _parser._physicalStateObj._inBuff.Length, "Unexpected unequal buffers.");

            // Determine packet size based on physical connection buffer lengths.
            SetPacketSize(_parser._physicalStateObj._outBuff.Length);

            SNINativeMethodWrapper.ConsumerInfo myInfo = CreateConsumerInfo(async);
            _sessionHandle = new SNIHandle(myInfo, physicalConnection);

            if (_sessionHandle.Status != TdsEnums.SNI_SUCCESS)
            {
                AddError(parser.ProcessSNIError(this));
                ThrowExceptionAndWarning();
            }

            // we post a callback that represents the call to dispose; once the
            // object is disposed, the next callback will cause the GC Handle to
            // be released.
            IncrementPendingCallbacks();
            _lastSuccessfulIOTimer = parser._physicalStateObj._lastSuccessfulIOTimer;
        }
All Usage Examples Of System.Data.SqlClient.TdsParser::ProcessSNIError
TdsParser