📄 read.cod
字号:
_totalTime$ = -28
_timeoutsForIrp$ = -60
_setFirstStatus$ = -1
_firstStatus$ = -12
_SerialStartRead@4 PROC NEAR ; COMDAT
; 222 : {
001c9 55 push ebp
001ca 8b ec mov ebp, esp
001cc 83 ec 3c sub esp, 60 ; 0000003cH
; 223 :
; 224 : SERIAL_UPDATE_CHAR updateChar;
; 225 :
; 226 : PIRP newIrp;
; 227 : KIRQL oldIrql;
; 228 : KIRQL controlIrql;
; 229 :
; 230 : BOOLEAN returnWithWhatsPresent;
; 231 : BOOLEAN os2ssreturn;
; 232 : BOOLEAN crunchDownToOne;
; 233 : BOOLEAN useTotalTimer;
; 234 : BOOLEAN useIntervalTimer;
; 235 :
; 236 : ULONG multiplierVal;
; 237 : ULONG constantVal;
; 238 :
; 239 : LARGE_INTEGER totalTime;
; 240 :
; 241 : SERIAL_TIMEOUTS timeoutsForIrp;
; 242 :
; 243 : BOOLEAN setFirstStatus = FALSE;
001cf 80 65 ff 00 and BYTE PTR _setFirstStatus$[ebp], 0
001d3 53 push ebx
001d4 56 push esi
; 244 : NTSTATUS firstStatus;
; 245 :
; 246 : SERIAL_LOCKED_PAGED_CODE();
001d5 8b 35 00 00 00
00 mov esi, DWORD PTR __imp__KeGetCurrentIrql@0
001db 57 push edi
001dc ff d6 call esi
001de 3c 01 cmp al, 1
001e0 76 32 jbe SHORT $L14972
001e2 83 3d 14 00 00
00 00 cmp DWORD PTR _SerialGlobals+20, 0
001e9 75 29 jne SHORT $L14972
001eb ff d6 call esi
001ed 0f b6 c0 movzx eax, al
001f0 50 push eax
001f1 68 00 00 00 00 push OFFSET FLAT:$SG14967
001f6 e8 00 00 00 00 call _DbgPrint
001fb 59 pop ecx
001fc 59 pop ecx
001fd 6a 00 push 0
001ff 68 f6 00 00 00 push 246 ; 000000f6H
00204 68 00 00 00 00 push OFFSET FLAT:$SG14970
00209 68 00 00 00 00 push OFFSET FLAT:$SG14971
0020e ff 15 00 00 00
00 call DWORD PTR __imp__RtlAssert@16
$L14972:
; 247 :
; 248 :
; 249 : SerialDump(SERTRACECALLS, ("SERIAL: SerialStartRead\n"));
00214 f6 05 00 00 00
00 40 test BYTE PTR _SerialDebugLevel, 64 ; 00000040H
0021b 74 0b je SHORT $L14973
0021d 68 00 00 00 00 push OFFSET FLAT:$SG14978
00222 e8 00 00 00 00 call _DbgPrint
00227 59 pop ecx
$L14973:
; 250 :
; 251 : updateChar.Extension = Extension;
00228 8b 5d 08 mov ebx, DWORD PTR _Extension$[ebp]
0022b 89 5d d8 mov DWORD PTR _updateChar$[ebp], ebx
0022e 8d b3 c4 00 00
00 lea esi, DWORD PTR [ebx+196]
$L14985:
; 252 :
; 253 : do {
; 254 :
; 255 : //
; 256 : // Check to see if this is a resize request. If it is
; 257 : // then go to a routine that specializes in that.
; 258 : //
; 259 :
; 260 : if (IoGetCurrentIrpStackLocation(Extension->CurrentReadIrp)
; 261 : ->MajorFunction != IRP_MJ_READ) {
00234 8b 06 mov eax, DWORD PTR [esi]
; 262 :
; 263 : NTSTATUS localStatus = SerialResizeBuffer(Extension);
00236 53 push ebx
00237 8b 40 60 mov eax, DWORD PTR [eax+96]
0023a 80 38 03 cmp BYTE PTR [eax], 3
0023d 74 0a je SHORT $L14988
0023f e8 00 00 00 00 call _SerialResizeBuffer@4
; 264 :
; 265 : if (!setFirstStatus) {
; 266 :
; 267 : firstStatus = localStatus;
; 268 : setFirstStatus = TRUE;
; 269 :
; 270 : }
; 271 :
; 272 : } else {
00244 e9 8c 01 00 00 jmp $L15424
$L14988:
; 273 :
; 274 : Extension->NumberNeededForRead =
; 275 : IoGetCurrentIrpStackLocation(Extension->CurrentReadIrp)
; 276 : ->Parameters.Read.Length;
00249 8b 40 04 mov eax, DWORD PTR [eax+4]
; 277 :
; 278 : //
; 279 : // Calculate the timeout value needed for the
; 280 : // request. Note that the values stored in the
; 281 : // timeout record are in milliseconds.
; 282 : //
; 283 :
; 284 : useTotalTimer = FALSE;
0024c 80 65 0b 00 and BYTE PTR _useTotalTimer$[ebp], 0
; 285 : returnWithWhatsPresent = FALSE;
00250 80 65 fc 00 and BYTE PTR _returnWithWhatsPresent$[ebp], 0
; 286 : os2ssreturn = FALSE;
00254 80 65 fd 00 and BYTE PTR _os2ssreturn$[ebp], 0
; 287 : crunchDownToOne = FALSE;
00258 80 65 fb 00 and BYTE PTR _crunchDownToOne$[ebp], 0
; 288 : useIntervalTimer = FALSE;
0025c 80 65 fa 00 and BYTE PTR _useIntervalTimer$[ebp], 0
00260 89 83 0c 01 00
00 mov DWORD PTR [ebx+268], eax
; 289 :
; 290 : //
; 291 : //
; 292 : // CIMEXCIMEX -- this is a lie
; 293 : //
; 294 : // Always initialize the timer objects so that the
; 295 : // completion code can tell when it attempts to
; 296 : // cancel the timers whether the timers had ever
; 297 : // been Set.
; 298 : //
; 299 : // CIMEXCIMEX -- this is the truth
; 300 : //
; 301 : // What we want to do is just make sure the timers are
; 302 : // cancelled to the best of our ability and move on with
; 303 : // life.
; 304 : //
; 305 :
; 306 : SerialCancelTimer(&Extension->ReadRequestTotalTimer, Extension);
00266 8d 83 b0 03 00
00 lea eax, DWORD PTR [ebx+944]
0026c 50 push eax
0026d e8 00 00 00 00 call _SerialCancelTimer@8
; 307 : SerialCancelTimer(&Extension->ReadRequestIntervalTimer, Extension);
00272 8d 83 d8 03 00
00 lea eax, DWORD PTR [ebx+984]
00278 53 push ebx
00279 50 push eax
0027a e8 00 00 00 00 call _SerialCancelTimer@8
; 308 :
; 309 :
; 310 : // KeInitializeTimer(&Extension->ReadRequestTotalTimer);
; 311 : // KeInitializeTimer(&Extension->ReadRequestIntervalTimer);
; 312 :
; 313 : //
; 314 : // We get the *current* timeout values to use for timing
; 315 : // this read.
; 316 : //
; 317 :
; 318 : KeAcquireSpinLock(
; 319 : &Extension->ControlLock,
; 320 : &controlIrql
; 321 : );
0027f 8d 8b e4 01 00
00 lea ecx, DWORD PTR [ebx+484]
00285 ff 15 00 00 00
00 call DWORD PTR __imp_@KfAcquireSpinLock@4
; 322 :
; 323 : timeoutsForIrp = Extension->Timeouts;
0028b 6a 05 push 5
0028d 8d b3 58 01 00
00 lea esi, DWORD PTR [ebx+344]
00293 59 pop ecx
00294 8d 7d c4 lea edi, DWORD PTR _timeoutsForIrp$[ebp]
00297 f3 a5 rep movsd
; 324 :
; 325 : KeReleaseSpinLock(
; 326 : &Extension->ControlLock,
; 327 : controlIrql
; 328 : );
00299 8b 3d 00 00 00
00 mov edi, DWORD PTR __imp_@KfReleaseSpinLock@8
0029f 8d b3 e4 01 00
00 lea esi, DWORD PTR [ebx+484]
002a5 8a d0 mov dl, al
002a7 8b ce mov ecx, esi
002a9 ff d7 call edi
; 329 :
; 330 : //
; 331 : // Calculate the interval timeout for the read.
; 332 : //
; 333 :
; 334 : if (timeoutsForIrp.ReadIntervalTimeout &&
; 335 : (timeoutsForIrp.ReadIntervalTimeout !=
; 336 : MAXULONG)) {
002ab 8b 4d c4 mov ecx, DWORD PTR _timeoutsForIrp$[ebp]
002ae 85 c9 test ecx, ecx
002b0 74 37 je SHORT $L14998
002b2 83 f9 ff cmp ecx, -1
002b5 74 37 je SHORT $L15404
; 337 :
; 338 : useIntervalTimer = TRUE;
; 339 :
; 340 : Extension->IntervalTime.QuadPart =
; 341 : UInt32x32To64(
; 342 : timeoutsForIrp.ReadIntervalTimeout,
; 343 : 10000
; 344 : );
002b7 8b c1 mov eax, ecx
002b9 ba 10 27 00 00 mov edx, 10000 ; 00002710H
002be f7 e2 mul edx
002c0 89 43 38 mov DWORD PTR [ebx+56], eax
; 345 :
; 346 :
; 347 : if (Extension->IntervalTime.QuadPart >=
; 348 : Extension->CutOverAmount.QuadPart) {
002c3 8b c2 mov eax, edx
002c5 3b 43 54 cmp eax, DWORD PTR [ebx+84]
002c8 c6 45 fa 01 mov BYTE PTR _useIntervalTimer$[ebp], 1
002cc 89 53 3c mov DWORD PTR [ebx+60], edx
002cf 7c 0f jl SHORT $L14997
002d1 7f 08 jg SHORT $L15407
002d3 8b 43 38 mov eax, DWORD PTR [ebx+56]
002d6 3b 43 50 cmp eax, DWORD PTR [ebx+80]
002d9 72 05 jb SHORT $L14997
$L15407:
; 349 :
; 350 : Extension->IntervalTimeToUse =
; 351 : &Extension->LongIntervalAmount;
002db 8d 43 48 lea eax, DWORD PTR [ebx+72]
; 352 :
; 353 : } else {
002de eb 03 jmp SHORT $L15422
$L14997:
; 354 :
; 355 : Extension->IntervalTimeToUse =
; 356 : &Extension->ShortIntervalAmount;
002e0 8d 43 40 lea eax, DWORD PTR [ebx+64]
$L15422:
002e3 89 83 88 00 00
00 mov DWORD PTR [ebx+136], eax
$L14998:
; 357 :
; 358 : }
; 359 :
; 360 : }
; 361 :
; 362 : if (timeoutsForIrp.ReadIntervalTimeout == MAXULONG) {
002e9 83 f9 ff cmp ecx, -1
002ec 75 2e jne SHORT $L14999
$L15404:
; 363 :
; 364 : //
; 365 : // We need to do special return quickly stuff here.
; 366 : //
; 367 : // 1) If both constant and multiplier are
; 368 : // 0 then we return immediately with whatever
; 369 : // we've got, even if it was zero.
; 370 : //
; 371 : // 2) If constant and multiplier are not MAXULONG
; 372 : // then return immediately if any characters
; 373 : // are present, but if nothing is there, then
; 374 : // use the timeouts as specified.
; 375 : //
; 376 : // 3) If multiplier is MAXULONG then do as in
; 377 : // "2" but return when the first character
; 378 : // arrives.
; 379 : //
; 380 :
; 381 : if (!timeoutsForIrp.ReadTotalTimeoutConstant &&
; 382 : !timeoutsForIrp.ReadTotalTimeoutMultiplier) {
002ee 83 7d cc 00 cmp DWORD PTR _timeoutsForIrp$[ebp+8], 0
002f2 8b 4d c8 mov ecx, DWORD PTR _timeoutsForIrp$[ebp+4]
002f5 75 0a jne SHORT $L15000
002f7 85 c9 test ecx, ecx
002f9 75 0c jne SHORT $L15405
; 383 :
; 384 : returnWithWhatsPresent = TRUE;
002fb c6 45 fc 01 mov BYTE PTR _returnWithWhatsPresent$[ebp], 1
; 385 :
; 386 : } else if ((timeoutsForIrp.ReadTotalTimeoutConstant != MAXULONG)
002ff eb 4e jmp SHORT $L15008
$L15000:
; 387 : &&
; 388 : (timeoutsForIrp.ReadTotalTimeoutMultiplier
; 389 : != MAXULONG)) {
00301 83 7d cc ff cmp DWORD PTR _timeoutsForIrp$[ebp+8], -1
00305 74 48 je SHORT $L15008
$L15405:
00307 83 f9 ff cmp ecx, -1
; 390 :
; 391 : useTotalTimer = TRUE;
; 392 : os2ssreturn = TRUE;
0030a c6 45 fd 01 mov BYTE PTR _os2ssreturn$[ebp], 1
0030e c6 45 0b 01 mov BYTE PTR _useTotalTimer$[ebp], 1
; 393 : multiplierVal = timeoutsForIrp.ReadTotalTimeoutMultiplier;
; 394 : constantVal = timeoutsForIrp.ReadTotalTimeoutConstant;
; 395 :
; 396 : } else if ((timeoutsForIrp.ReadTotalTimeoutConstant != MAXULONG)
00312 75 18 jne SHORT $L15006
; 397 : &&
; 398 : (timeoutsForIrp.ReadTotalTimeoutMultiplier
; 399 : == MAXULONG)) {
; 400 :
; 401 : useTotalTimer = TRUE;
; 402 : os2ssreturn = TRUE;
; 403 : crunchDownToOne = TRUE;
00314 c6 45 fb 01 mov BYTE PTR _crunchDownToOne$[ebp], 1
; 404 : multiplierVal = 0;
00318 33 c9 xor ecx, ecx
; 405 : constantVal = timeoutsForIrp.ReadTotalTimeoutConstant;
; 406 :
; 407 : }
; 408 :
; 409 : } else {
0031a eb 10 jmp SHORT $L15006
$L14999:
; 410 :
; 411 : //
; 412 : // If both the multiplier and the constant are
; 413 : // zero then don't do any total timeout processing.
; 414 : //
; 415 :
; 416 : if (timeoutsForIrp.ReadTotalTimeoutMultiplier ||
; 417 : timeoutsForIrp.ReadTotalTimeoutConstant) {
0031c 8b 4d c8 mov ecx, DWORD PTR _timeoutsForIrp$[ebp+4]
0031f 85 c9 test ecx, ecx
00321 75 05 jne SHORT $L15007
00323 39 4d cc cmp DWORD PTR _timeoutsForIrp$[ebp+8], ecx
00326 74 27 je SHORT $L15008
$L15007:
; 418 :
; 419 : //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -