@@ -167,22 +167,14 @@ private void ReadSniError(TdsParserStateObject stateObj, uint error)
167167 stateObj . SendAttention ( mustTakeWriteLock : true ) ;
168168
169169 PacketHandle syncReadPacket = default ;
170- bool readFromNetwork = true ;
171170 RuntimeHelpers . PrepareConstrainedRegions ( ) ;
172171 bool shouldDecrement = false ;
173172 try
174173 {
175174 Interlocked . Increment ( ref _readingCount ) ;
176175 shouldDecrement = true ;
177- readFromNetwork = ! PartialPacketContainsCompletePacket ( ) ;
178- if ( readFromNetwork )
179- {
180- syncReadPacket = ReadSyncOverAsync ( stateObj . GetTimeoutRemaining ( ) , out error ) ;
181- }
182- else
183- {
184- error = TdsEnums . SNI_SUCCESS ;
185- }
176+
177+ syncReadPacket = ReadSyncOverAsync ( stateObj . GetTimeoutRemaining ( ) , out error ) ;
186178
187179 Interlocked . Decrement ( ref _readingCount ) ;
188180 shouldDecrement = false ;
@@ -195,7 +187,7 @@ private void ReadSniError(TdsParserStateObject stateObj, uint error)
195187 }
196188 else
197189 {
198- Debug . Assert ( ! readFromNetwork || ! IsValidPacket ( syncReadPacket ) , "unexpected syncReadPacket without corresponding SNIPacketRelease" ) ;
190+ Debug . Assert ( ! IsValidPacket ( syncReadPacket ) , "unexpected syncReadPacket without corresponding SNIPacketRelease" ) ;
199191 fail = true ; // Subsequent read failed, time to give up.
200192 }
201193 }
@@ -206,7 +198,7 @@ private void ReadSniError(TdsParserStateObject stateObj, uint error)
206198 Interlocked . Decrement ( ref _readingCount ) ;
207199 }
208200
209- if ( readFromNetwork && ! IsPacketEmpty ( syncReadPacket ) )
201+ if ( ! IsPacketEmpty ( syncReadPacket ) )
210202 {
211203 // Be sure to release packet, otherwise it will be leaked by native.
212204 ReleasePacket ( syncReadPacket ) ;
@@ -247,9 +239,60 @@ private void ReadSniError(TdsParserStateObject stateObj, uint error)
247239 AssertValidState ( ) ;
248240 }
249241
250- private uint GetSniPacket ( PacketHandle packet , ref uint dataSize )
242+ public void ProcessSniPacket ( PacketHandle packet , uint error )
251243 {
252- return SniPacketGetData ( packet , _inBuff , ref dataSize ) ;
244+ if ( error != 0 )
245+ {
246+ if ( ( _parser . State == TdsParserState . Closed ) || ( _parser . State == TdsParserState . Broken ) )
247+ {
248+ // Do nothing with callback if closed or broken and error not 0 - callback can occur
249+ // after connection has been closed. PROBLEM IN NETLIB - DESIGN FLAW.
250+ return ;
251+ }
252+
253+ AddError ( _parser . ProcessSNIError ( this ) ) ;
254+ AssertValidState ( ) ;
255+ }
256+ else
257+ {
258+ uint dataSize = 0 ;
259+
260+ uint getDataError = SniPacketGetData ( packet , _inBuff , ref dataSize ) ;
261+
262+ if ( getDataError == TdsEnums . SNI_SUCCESS )
263+ {
264+ if ( _inBuff . Length < dataSize )
265+ {
266+ Debug . Assert ( true , "Unexpected dataSize on Read" ) ;
267+ throw SQL . InvalidInternalPacketSize ( StringsHelper . GetString ( Strings . SqlMisc_InvalidArraySizeMessage ) ) ;
268+ }
269+
270+ _lastSuccessfulIOTimer . _value = DateTime . UtcNow . Ticks ;
271+ _inBytesRead = ( int ) dataSize ;
272+ _inBytesUsed = 0 ;
273+
274+ if ( _snapshot != null )
275+ {
276+ _snapshot . AppendPacketData ( _inBuff , _inBytesRead ) ;
277+ if ( _snapshotReplay )
278+ {
279+ _snapshot . MoveNext ( ) ;
280+ #if DEBUG
281+ _snapshot . AssertCurrent ( ) ;
282+ #endif
283+ }
284+ }
285+
286+ SniReadStatisticsAndTracing ( ) ;
287+ SqlClientEventSource . Log . TryAdvancedTraceBinEvent ( "TdsParser.ReadNetworkPacketAsyncCallback | INFO | ADV | State Object Id {0}, Packet read. In Buffer: {1}, In Bytes Read: {2}" , ObjectID , _inBuff , _inBytesRead ) ;
288+
289+ AssertValidState ( ) ;
290+ }
291+ else
292+ {
293+ throw SQL . ParsingError ( ParsingErrorState . ProcessSniPacketFailed ) ;
294+ }
295+ }
253296 }
254297
255298 private void SetBufferSecureStrings ( )
@@ -321,7 +364,7 @@ public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error)
321364 bool processFinallyBlock = true ;
322365 try
323366 {
324- Debug . Assert ( ( packet . Type == 0 && PartialPacketContainsCompletePacket ( ) ) || ( CheckPacket ( packet , source ) && source != null ) , "AsyncResult null on callback" ) ;
367+ Debug . Assert ( CheckPacket ( packet , source ) && source != null , "AsyncResult null on callback" ) ;
325368
326369 if ( _parser . MARSOn )
327370 {
0 commit comments