@@ -98,8 +98,9 @@ internal bool TryInitialize(TdsParserStateObject stateObj, int columnsCount)
9898 return false ;
9999 }
100100
101- SqlClientEventSource . Log . TryAdvancedTraceEvent ( "TdsParserStateObject.NullBitmap.Initialize | INFO | ADV | State Object Id {0}, NBCROW bitmap received, column count = {1}" , stateObj . _objectID , columnsCount ) ;
102- SqlClientEventSource . Log . TryAdvancedTraceBinEvent ( "TdsParserStateObject.NullBitmap.Initialize | INFO | ADV | State Object Id {0}, Null Bitmap length {1}, NBCROW bitmap data: {2}" , stateObj . _objectID , ( ushort ) _nullBitmap . Length , _nullBitmap ) ;
101+ SqlClientEventSource . Log . TryAdvancedTraceEvent ( "TdsParserStateObject.NullBitmap.Initialize | INFO | ADV | State Object Id {0}, NBCROW bitmap received, column count = {1}" , stateObj . ObjectID , columnsCount ) ;
102+ SqlClientEventSource . Log . TryAdvancedTraceBinEvent ( "TdsParserStateObject.NullBitmap.Initialize | INFO | ADV | State Object Id {0}, NBCROW bitmap data. Null Bitmap {1}, Null bitmap length: {2}" , stateObj . ObjectID , _nullBitmap , ( ushort ) _nullBitmap . Length ) ;
103+
103104 return true ;
104105 }
105106 }
@@ -484,7 +485,7 @@ internal bool TryReadChar(out char value)
484485
485486 AssertValidState ( ) ;
486487 value = ( char ) ( ( buffer [ 1 ] << 8 ) + buffer [ 0 ] ) ;
487-
488+
488489 return true ;
489490 }
490491
@@ -543,7 +544,6 @@ internal bool TryReadInt32(out int value)
543544 AssertValidState ( ) ;
544545 value = ( buffer [ 3 ] << 24 ) + ( buffer [ 2 ] << 16 ) + ( buffer [ 1 ] << 8 ) + buffer [ 0 ] ;
545546 return true ;
546-
547547 }
548548
549549 // This method is safe to call when doing async without snapshot
@@ -564,7 +564,7 @@ internal bool TryReadInt64(out long value)
564564 // then use ReadByteArray since the logic is there to take care of that.
565565
566566 int bytesRead ;
567- if ( ! TryReadByteArray ( _bTmp . AsSpan ( _bTmpRead ) , 8 - _bTmpRead , out bytesRead ) )
567+ if ( ! TryReadByteArray ( _bTmp . AsSpan ( start : _bTmpRead ) , 8 - _bTmpRead , out bytesRead ) )
568568 {
569569 Debug . Assert ( _bTmpRead + bytesRead <= 8 , "Read more data than required" ) ;
570570 _bTmpRead += bytesRead ;
@@ -642,7 +642,7 @@ internal bool TryReadUInt32(out uint value)
642642 // then use ReadByteArray since the logic is there to take care of that.
643643
644644 int bytesRead ;
645- if ( ! TryReadByteArray ( _bTmp . AsSpan ( _bTmpRead ) , 4 - _bTmpRead , out bytesRead ) )
645+ if ( ! TryReadByteArray ( _bTmp . AsSpan ( start : _bTmpRead ) , 4 - _bTmpRead , out bytesRead ) )
646646 {
647647 Debug . Assert ( _bTmpRead + bytesRead <= 4 , "Read more data than required" ) ;
648648 _bTmpRead += bytesRead ;
@@ -1828,13 +1828,13 @@ public void ProcessSniPacket(PacketHandle packet, uint error)
18281828 }
18291829
18301830 SniReadStatisticsAndTracing ( ) ;
1831-
1831+ SqlClientEventSource . Log . TryAdvancedTraceBinEvent ( "TdsParser.ReadNetworkPacketAsyncCallback | INFO | ADV | State Object Id {0}, Packet read. In Buffer {1}, In Bytes Read: {2}" , ObjectID , _inBuff , ( ushort ) _inBytesRead ) ;
18321832
18331833 AssertValidState ( ) ;
18341834 }
18351835 else
18361836 {
1837- throw SQL . ParsingError ( ) ;
1837+ throw SQL . ParsingError ( ParsingErrorState . ProcessSniPacketFailed ) ;
18381838 }
18391839 }
18401840 }
@@ -1896,7 +1896,6 @@ public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error)
18961896 // to the outstanding GCRoot until AppDomain.Unload.
18971897 // We live with the above for the time being due to the constraints of the current
18981898 // reliability infrastructure provided by the CLR.
1899- SqlClientEventSource . Log . TryTraceEvent ( "TdsParserStateObject.ReadAsyncCallback | Info | State Object Id {0}, received error {1} on idle connection" , _objectID , ( int ) error ) ;
19001899
19011900 TaskCompletionSource < object > source = _networkPacketTaskSource ;
19021901#if DEBUG
@@ -1919,7 +1918,7 @@ public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error)
19191918 Debug . Assert ( CheckPacket ( packet , source ) && source != null , "AsyncResult null on callback" ) ;
19201919
19211920 if ( _parser . MARSOn )
1922- {
1921+ {
19231922 // Only take reset lock on MARS and Async.
19241923 CheckSetResetConnectionState ( error , CallbackType . Read ) ;
19251924 }
@@ -1928,10 +1927,10 @@ public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error)
19281927
19291928 // The timer thread may be unreliable under high contention scenarios. It cannot be
19301929 // assumed that the timeout has happened on the timer thread callback. Check the timeout
1931- // synchrnously and then call OnTimeoutSync to force an atomic change of state.
1930+ // synchrnously and then call OnTimeoutSync to force an atomic change of state.
19321931 if ( TimeoutHasExpired )
19331932 {
1934- OnTimeoutSync ( true ) ;
1933+ OnTimeoutSync ( asyncClose : true ) ;
19351934 }
19361935
19371936 // try to change to the stopped state but only do so if currently in the running state
@@ -2125,6 +2124,13 @@ public void WriteAsyncCallback(IntPtr key, PacketHandle packet, uint sniError)
21252124 /////////////////////////////////////////
21262125 // Network/Packet Writing & Processing //
21272126 /////////////////////////////////////////
2127+
2128+ //
2129+ // Takes a secure string and offsets and saves them for a write latter when the information is written out to SNI Packet
2130+ // This method is provided to better handle the life cycle of the clear text of the secure string
2131+ // This method also ensures that the clear text is not held in the unpined managed buffer so that it avoids getting moved around by CLR garbage collector
2132+ // TdsParserStaticMethods.EncryptPassword operation is also done in the unmanaged buffer for the clear text later
2133+ //
21282134 internal void WriteSecureString ( SecureString secureString )
21292135 {
21302136 Debug . Assert ( _securePasswords [ 0 ] == null || _securePasswords [ 1 ] == null , "There are more than two secure passwords" ) ;
@@ -2363,11 +2369,11 @@ internal Task WritePacket(byte flushMode, bool canAccumulate = false)
23632369 // However, since we don't know the version prior to login Is2005OrNewer was always false prior to login
23642370 // So removing the Is2005OrNewer check causes issues since the login packet happens to meet the rest of the conditions below
23652371 // So we need to avoid this check prior to login completing
2366- state == TdsParserState . OpenLoggedIn &&
2367- ! _bulkCopyOpperationInProgress && // ignore the condition checking for bulk copy
2368- _outBytesUsed == ( _outputHeaderLen + BitConverter . ToInt32 ( _outBuff , _outputHeaderLen ) )
2372+ state == TdsParserState . OpenLoggedIn
2373+ && ! _bulkCopyOpperationInProgress // ignore the condition checking for bulk copy
2374+ && _outBytesUsed == ( _outputHeaderLen + BitConverter . ToInt32 ( _outBuff , _outputHeaderLen ) )
23692375 && _outputPacketCount == 0
2370- || _outBytesUsed == _outputHeaderLen
2376+ || _outBytesUsed == _outputHeaderLen
23712377 && _outputPacketCount == 0 )
23722378 {
23732379 return null ;
@@ -2420,6 +2426,7 @@ internal Task WritePacket(byte flushMode, bool canAccumulate = false)
24202426 // If we have been canceled, then ensure that we write the ATTN packet as well
24212427 task = AsyncHelper . CreateContinuationTask ( task , CancelWritePacket ) ;
24222428 }
2429+
24232430 return task;
24242431 }
24252432
@@ -2443,7 +2450,7 @@ private void CancelWritePacket()
24432450 }
24442451 }
24452452
2446- #pragma warning disable 0420 // a reference to a volatile field will not be treated as volatile
2453+ #pragma warning disable 420 // a reference to a volatile field will not be treated as volatile
24472454
24482455 private Task SNIWritePacket( PacketHandle packet , out uint sniError , bool canAccumulate , bool callerHasConnectionLock , bool asyncClose = false)
24492456 {
@@ -2456,9 +2463,7 @@ private Task SNIWritePacket(PacketHandle packet, out uint sniError, bool canAccu
24562463
24572464 Task task = null ;
24582465 _writeCompletionSource = null ;
2459-
24602466 PacketHandle packetPointer = EmptyReadPacket;
2461-
24622467 bool sync = ! _parser . _asyncWrite ;
24632468 if ( sync && _asyncWriteCount > 0 )
24642469 { // for example, SendAttention while there are writes pending
@@ -2493,7 +2498,7 @@ private Task SNIWritePacket(PacketHandle packet, out uint sniError, bool canAccu
24932498
24942499 if ( sniError == TdsEnums . SNI_SUCCESS_IO_PENDING )
24952500 {
2496- Debug . Assert ( ! sync , "Completion should be handled in SniManagedWwrapper " ) ;
2501+ Debug . Assert ( ! sync , "Completion should be handled in SniManagedWrapper " ) ;
24972502 Interlocked. Increment ( ref _asyncWriteCount ) ;
24982503 Debug. Assert ( _asyncWriteCount >= 0 ) ;
24992504 if ( ! canAccumulate )
@@ -2639,7 +2644,7 @@ internal void SendAttention(bool mustTakeWriteLock = false, bool asyncClose = fa
26392644 }
26402645 }
26412646#if DEBUG
2642- }
2647+ }
26432648#endif
26442649
26452650 SetTimeoutSeconds ( AttentionTimeoutSeconds ) ; // Initialize new attention timeout of 5 seconds.
0 commit comments