📄 read.cod
字号:
; 420 : // We have some timer values to calculate.
; 421 : //
; 422 :
; 423 : useTotalTimer = TRUE;
00328 c6 45 0b 01 mov BYTE PTR _useTotalTimer$[ebp], 1
$L15006:
; 424 : multiplierVal = timeoutsForIrp.ReadTotalTimeoutMultiplier;
; 425 : constantVal = timeoutsForIrp.ReadTotalTimeoutConstant;
; 426 :
; 427 : }
; 428 :
; 429 : }
; 430 :
; 431 : if (useTotalTimer) {
; 432 :
; 433 : totalTime.QuadPart = ((LONGLONG)(UInt32x32To64(
; 434 : Extension->NumberNeededForRead,
; 435 : multiplierVal
; 436 : )
; 437 : + constantVal))
; 438 : * -10000;
0032c 8b 83 0c 01 00
00 mov eax, DWORD PTR [ebx+268]
00332 6a ff push -1
00334 f7 e1 mul ecx
00336 33 c9 xor ecx, ecx
00338 03 45 cc add eax, DWORD PTR _timeoutsForIrp$[ebp+8]
0033b 68 f0 d8 ff ff push -10000 ; ffffd8f0H
00340 13 d1 adc edx, ecx
00342 52 push edx
00343 50 push eax
00344 e8 00 00 00 00 call __allmul
00349 89 45 e4 mov DWORD PTR _totalTime$[ebp], eax
0034c 89 55 e8 mov DWORD PTR _totalTime$[ebp+4], edx
$L15008:
; 439 :
; 440 : }
; 441 :
; 442 :
; 443 : //
; 444 : // We do this copy in the hope of getting most (if not
; 445 : // all) of the characters out of the interrupt buffer.
; 446 : //
; 447 : // Note that we need to protect this operation with a
; 448 : // spinlock since we don't want a purge to hose us.
; 449 : //
; 450 :
; 451 : KeAcquireSpinLock(
; 452 : &Extension->ControlLock,
; 453 : &controlIrql
; 454 : );
0034f 8b ce mov ecx, esi
00351 ff 15 00 00 00
00 call DWORD PTR __imp_@KfAcquireSpinLock@4
; 455 :
; 456 : updateChar.CharsCopied = SerialGetCharsFromIntBuffer(Extension);
00357 53 push ebx
00358 88 45 fe mov BYTE PTR _controlIrql$[ebp], al
0035b e8 00 00 00 00 call _SerialGetCharsFromIntBuffer@4
; 457 :
; 458 : //
; 459 : // See if we have any cause to return immediately.
; 460 : //
; 461 :
; 462 : if (returnWithWhatsPresent || (!Extension->NumberNeededForRead) ||
; 463 : (os2ssreturn &&
; 464 : Extension->CurrentReadIrp->IoStatus.Information)) {
00360 80 7d fc 00 cmp BYTE PTR _returnWithWhatsPresent$[ebp], 0
00364 89 45 dc mov DWORD PTR _updateChar$[ebp+4], eax
00367 0f 85 ef 00 00
00 jne $L15015
0036d 83 bb 0c 01 00
00 00 cmp DWORD PTR [ebx+268], 0
00374 0f 84 e2 00 00
00 je $L15015
0037a 80 7d fd 00 cmp BYTE PTR _os2ssreturn$[ebp], 0
0037e 74 10 je SHORT $L15014
00380 8b 83 c4 00 00
00 mov eax, DWORD PTR [ebx+196]
00386 83 78 1c 00 cmp DWORD PTR [eax+28], 0
0038a 0f 85 cc 00 00
00 jne $L15015
$L15014:
; 488 :
; 489 : }
; 490 :
; 491 : } else {
; 492 :
; 493 : //
; 494 : // The irp might go under control of the isr. It
; 495 : // won't hurt to initialize the reference count
; 496 : // right now.
; 497 : //
; 498 :
; 499 : SERIAL_INIT_REFERENCE(Extension->CurrentReadIrp);
00390 8d b3 c4 00 00
00 lea esi, DWORD PTR [ebx+196]
00396 8b 06 mov eax, DWORD PTR [esi]
00398 8b 40 60 mov eax, DWORD PTR [eax+96]
0039b 83 60 10 00 and DWORD PTR [eax+16], 0
; 500 :
; 501 : IoAcquireCancelSpinLock(&oldIrql);
0039f 8d 45 f0 lea eax, DWORD PTR _oldIrql$[ebp]
003a2 50 push eax
003a3 ff 15 00 00 00
00 call DWORD PTR __imp__IoAcquireCancelSpinLock@4
; 502 :
; 503 : //
; 504 : // We need to see if this irp should be canceled.
; 505 : //
; 506 :
; 507 : if (Extension->CurrentReadIrp->Cancel) {
003a9 8b 06 mov eax, DWORD PTR [esi]
003ab 80 78 24 00 cmp BYTE PTR [eax+36], 0
003af 74 36 je SHORT $L15027
; 508 :
; 509 : IoReleaseCancelSpinLock(oldIrql);
003b1 ff 75 f0 push DWORD PTR _oldIrql$[ebp]
003b4 ff 15 00 00 00
00 call DWORD PTR __imp__IoReleaseCancelSpinLock@4
; 510 : KeReleaseSpinLock(
; 511 : &Extension->ControlLock,
; 512 : controlIrql
; 513 : );
003ba 8a 55 fe mov dl, BYTE PTR _controlIrql$[ebp]
003bd 8d 8b e4 01 00
00 lea ecx, DWORD PTR [ebx+484]
003c3 ff d7 call edi
; 514 : Extension->CurrentReadIrp->IoStatus.Status =
; 515 : STATUS_CANCELLED;
003c5 8b 0e mov ecx, DWORD PTR [esi]
003c7 b8 20 01 00 c0 mov eax, -1073741536 ; c0000120H
003cc 89 41 18 mov DWORD PTR [ecx+24], eax
; 516 : Extension->CurrentReadIrp->IoStatus.Information = 0;
003cf 8b 0e mov ecx, DWORD PTR [esi]
003d1 83 61 1c 00 and DWORD PTR [ecx+28], 0
$L15424:
; 517 :
; 518 : if (!setFirstStatus) {
003d5 80 7d ff 00 cmp BYTE PTR _setFirstStatus$[ebp], 0
003d9 0f 85 b5 00 00
00 jne $L15017
; 519 :
; 520 : firstStatus = STATUS_CANCELLED;
003df 89 45 f4 mov DWORD PTR _firstStatus$[ebp], eax
; 521 : setFirstStatus = TRUE;
; 522 :
; 523 : }
; 524 :
; 525 : } else {
003e2 e9 a9 00 00 00 jmp $L15421
$L15027:
; 526 :
; 527 : //
; 528 : // If we are supposed to crunch the read down to
; 529 : // one character, then update the read length
; 530 : // in the irp and truncate the number needed for
; 531 : // read down to one. Note that if we are doing
; 532 : // this crunching, then the information must be
; 533 : // zero (or we would have completed above) and
; 534 : // the number needed for the read must still be
; 535 : // equal to the read length.
; 536 : //
; 537 :
; 538 : if (crunchDownToOne) {
003e7 80 7d fb 00 cmp BYTE PTR _crunchDownToOne$[ebp], 0
003eb 74 3c je SHORT $L15032
; 539 :
; 540 : ASSERT(
; 541 : (!Extension->CurrentReadIrp->IoStatus.Information)
; 542 : &&
; 543 : (Extension->NumberNeededForRead ==
; 544 : IoGetCurrentIrpStackLocation(
; 545 : Extension->CurrentReadIrp
; 546 : )->Parameters.Read.Length)
; 547 : );
003ed 83 78 1c 00 cmp DWORD PTR [eax+28], 0
003f1 75 0e jne SHORT $L15034
003f3 8b 40 60 mov eax, DWORD PTR [eax+96]
003f6 8b 8b 0c 01 00
00 mov ecx, DWORD PTR [ebx+268]
003fc 3b 48 04 cmp ecx, DWORD PTR [eax+4]
003ff 74 17 je SHORT $L15033
$L15034:
00401 6a 00 push 0
00403 68 23 02 00 00 push 547 ; 00000223H
00408 68 00 00 00 00 push OFFSET FLAT:$SG15036
0040d 68 00 00 00 00 push OFFSET FLAT:$SG15037
00412 ff 15 00 00 00
00 call DWORD PTR __imp__RtlAssert@16
$L15033:
; 548 :
; 549 : Extension->NumberNeededForRead = 1;
; 550 : IoGetCurrentIrpStackLocation(
; 551 : Extension->CurrentReadIrp
; 552 : )->Parameters.Read.Length = 1;
00418 8b 0e mov ecx, DWORD PTR [esi]
0041a 33 c0 xor eax, eax
0041c 40 inc eax
0041d 89 83 0c 01 00
00 mov DWORD PTR [ebx+268], eax
00423 8b 49 60 mov ecx, DWORD PTR [ecx+96]
00426 89 41 04 mov DWORD PTR [ecx+4], eax
$L15032:
; 553 :
; 554 : }
; 555 :
; 556 : //
; 557 : // We still need to get more characters for this read.
; 558 : // synchronize with the isr so that we can update the
; 559 : // number of characters and if necessary it will have the
; 560 : // isr switch to copying into the users buffer.
; 561 : //
; 562 :
; 563 : KeSynchronizeExecution(
; 564 : Extension->Interrupt,
; 565 : SerialUpdateAndSwitchToUser,
; 566 : &updateChar
; 567 : );
00429 8d 45 d8 lea eax, DWORD PTR _updateChar$[ebp]
0042c 50 push eax
0042d 68 00 00 00 00 push OFFSET FLAT:_SerialUpdateAndSwitchToUser@4
00432 ff b3 a0 00 00
00 push DWORD PTR [ebx+160]
00438 ff 15 00 00 00
00 call DWORD PTR __imp__KeSynchronizeExecution@12
; 568 :
; 569 : if (!updateChar.Completed) {
0043e 80 7d e0 00 cmp BYTE PTR _updateChar$[ebp+8], 0
00442 74 79 je SHORT $L15402
; 629 :
; 630 : }
; 631 : return firstStatus;
; 632 :
; 633 : } else {
; 634 :
; 635 : IoReleaseCancelSpinLock(oldIrql);
00444 ff 75 f0 push DWORD PTR _oldIrql$[ebp]
00447 ff 15 00 00 00
00 call DWORD PTR __imp__IoReleaseCancelSpinLock@4
; 636 : KeReleaseSpinLock(
; 637 : &Extension->ControlLock,
; 638 : controlIrql
; 639 : );
0044d 8a 55 fe mov dl, BYTE PTR _controlIrql$[ebp]
00450 8d 8b e4 01 00
00 lea ecx, DWORD PTR [ebx+484]
00456 ff d7 call edi
; 640 : Extension->CurrentReadIrp->IoStatus.Status =
; 641 : STATUS_SUCCESS;
00458 8b 06 mov eax, DWORD PTR [esi]
; 642 :
; 643 : if (!setFirstStatus) {
; 644 :
; 645 : firstStatus = STATUS_SUCCESS;
; 646 : setFirstStatus = TRUE;
0045a eb 26 jmp SHORT $L15423
$L15015:
; 465 :
; 466 : //
; 467 : // We got all we needed for this read.
; 468 : // Update the number of characters in the
; 469 : // interrupt read buffer.
; 470 : //
; 471 :
; 472 : KeSynchronizeExecution(
; 473 : Extension->Interrupt,
; 474 : SerialUpdateInterruptBuffer,
; 475 : &updateChar
; 476 : );
0045c 8d 45 d8 lea eax, DWORD PTR _updateChar$[ebp]
0045f 50 push eax
00460 68 00 00 00 00 push OFFSET FLAT:_SerialUpdateInterruptBuffer@4
00465 ff b3 a0 00 00
00 push DWORD PTR [ebx+160]
0046b ff 15 00 00 00
00 call DWORD PTR __imp__KeSynchronizeExecution@12
; 477 :
; 478 : KeReleaseSpinLock(
; 479 : &Extension->ControlLock,
; 480 : controlIrql
; 481 : );
00471 8a 55 fe mov dl, BYTE PTR _controlIrql$[ebp]
00474 8d 8b e4 01 00
00 lea ecx, DWORD PTR [ebx+484]
0047a ff d7 call edi
; 482 :
; 483 : Extension->CurrentReadIrp->IoStatus.Status = STATUS_SUCCESS;
0047c 8b 83 c4 00 00
00 mov eax, DWORD PTR [ebx+196]
$L15423:
00482 83 60 18 00 and DWORD PTR [eax+24], 0
; 484 : if (!setFirstStatus) {
00486 80 7d ff 00 cmp BYTE PTR _setFirstStatus$[ebp], 0
0048a 75 08 jne SHORT $L15017
; 485 :
; 486 : firstStatus = STATUS_SUCCESS;
0048c 83 65 f4 00 and DWORD PTR _firstStatus$[ebp], 0
$L15421:
; 487 : setFirstStatus = TRUE;
00490 c6 45 ff 01 mov BYTE PTR _setFirstStatus$[ebp], 1
$L15017:
; 647 :
; 648 : }
; 649 :
; 650 : }
; 651 :
; 652 : }
; 653 :
; 654 : }
; 655 :
; 656 : }
; 657 :
; 658 : //
; 659 : // Well the operation is complete.
; 660 : //
; 661 :
; 662 : SerialGetNextIrp(
; 663 : &Extension->CurrentReadIrp,
; 664 : &Extension->ReadQueue,
; 665 : &newIrp,
; 666 : TRUE,
; 667 : Extension
; 668 : );
00494 53 push ebx
00495 8d 45 ec lea eax, DWORD PTR _newIrp$[ebp]
00498 6a 01 push 1
0049a 50 push eax
0049b 8d 83 a4 00 00
00 lea eax, DWORD PTR [ebx+164]
004a1 8d b3 c4 00 00
00 lea esi, DWORD PTR [ebx+196]
004a7 50 push eax
004a8 56 push esi
004a9 e8 00 00 00 00 call _SerialGetNextIrp@20
; 669 :
; 670 : } while (newIrp);
004ae 83 7d ec 00 cmp DWORD PTR _newIrp$[ebp], 0
004b2 0f 85 7c fd ff
ff jne $L14985
004b8 e9 d3 00 00 00 jmp $L15403
$L15402:
; 570 :
; 571 : //
; 572 : // The irp still isn't complete. The
; 573 : // completion routines will end up reinvoking
; 574 : // this routine. So we simply leave.
; 575 : //
; 576 : // First thought we should start off the total
; 577 : // timer for the read and increment the reference
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -