📄 write.cod
字号:
; 529 : KIRQL OldIrql;
; 530 : PIRP Irp;
; 531 : PSERIAL_XOFF_COUNTER Xc;
; 532 :
; 533 : IoAcquireCancelSpinLock(&OldIrql);
00046 8d 45 fc lea eax, DWORD PTR _OldIrql$14912[ebp]
00049 50 push eax
0004a ff 15 00 00 00
00 call DWORD PTR __imp__IoAcquireCancelSpinLock@4
; 534 :
; 535 : Irp = *CurrentOpIrp;
00050 8b 3f mov edi, DWORD PTR [edi]
; 536 : Xc = Irp->AssociatedIrp.SystemBuffer;
00052 8b 5f 0c mov ebx, DWORD PTR [edi+12]
; 537 :
; 538 : //
; 539 : // We should never have a xoff counter when we
; 540 : // get to this point.
; 541 : //
; 542 :
; 543 : ASSERT(!Extension->CurrentXoffIrp);
; 544 :
; 545 : //
; 546 : // We absolutely shouldn't have a cancel routine
; 547 : // at this point.
; 548 : //
; 549 :
; 550 : ASSERT(!Irp->CancelRoutine);
; 551 :
; 552 : //
; 553 : // This could only be a xoff counter masquerading as
; 554 : // a write irp.
; 555 : //
; 556 :
; 557 : Extension->TotalCharsQueued--;
00055 ff 8e 28 01 00
00 dec DWORD PTR [esi+296]
; 558 :
; 559 : //
; 560 : // Check to see of the xoff irp has been set with success.
; 561 : // This means that the write completed normally. If that
; 562 : // is the case, and it hasn't been set to cancel in the
; 563 : // meanwhile, then go on and make it the CurrentXoffIrp.
; 564 : //
; 565 :
; 566 : if (Irp->IoStatus.Status != STATUS_SUCCESS) {
0005b 83 7f 18 00 cmp DWORD PTR [edi+24], 0
0005f 75 76 jne SHORT $L14942
; 567 :
; 568 : //
; 569 : // Oh well, we can just finish it off.
; 570 : //
; 571 : NOTHING;
; 572 :
; 573 : } else if (Irp->Cancel) {
00061 80 7f 24 00 cmp BYTE PTR [edi+36], 0
00065 74 09 je SHORT $L14918
; 574 :
; 575 : Irp->IoStatus.Status = STATUS_CANCELLED;
00067 c7 47 18 20 01
00 c0 mov DWORD PTR [edi+24], -1073741536 ; c0000120H
; 576 :
; 577 : } else {
0006e eb 67 jmp SHORT $L14942
$L14918:
; 578 :
; 579 : //
; 580 : // Give it a new cancel routine, and increment the
; 581 : // reference count because the cancel routine has
; 582 : // a reference to it.
; 583 : //
; 584 :
; 585 : IoSetCancelRoutine(
; 586 : Irp,
; 587 : SerialCancelCurrentXoff
; 588 : );
00070 8d 4f 38 lea ecx, DWORD PTR [edi+56]
00073 ba 00 00 00 00 mov edx, OFFSET FLAT:_SerialCancelCurrentXoff@8
00078 ff 15 00 00 00
00 call DWORD PTR __imp_@InterlockedExchange@8
; 589 :
; 590 : SERIAL_SET_REFERENCE(
; 591 : Irp,
; 592 : SERIAL_REF_CANCEL
; 593 : );
0007e 8b 47 60 mov eax, DWORD PTR [edi+96]
; 594 :
; 595 : //
; 596 : // We don't want to complete the current irp now. This
; 597 : // will now get completed by the Xoff counter code.
; 598 : //
; 599 :
; 600 : CompleteCurrent = FALSE;
00081 80 65 14 00 and BYTE PTR _CompleteCurrent$[ebp], 0
00085 83 c0 10 add eax, 16 ; 00000010H
; 601 :
; 602 : //
; 603 : // Give the counter to the isr.
; 604 : //
; 605 :
; 606 : Extension->CurrentXoffIrp = Irp;
; 607 : KeSynchronizeExecution(
; 608 : Extension->Interrupt,
; 609 : SerialGiveXoffToIsr,
; 610 : Extension
; 611 : );
00088 56 push esi
00089 68 00 00 00 00 push OFFSET FLAT:_SerialGiveXoffToIsr@4
0008e 83 08 02 or DWORD PTR [eax], 2
00091 ff b6 a0 00 00
00 push DWORD PTR [esi+160]
00097 89 be dc 00 00
00 mov DWORD PTR [esi+220], edi
0009d ff 15 00 00 00
00 call DWORD PTR __imp__KeSynchronizeExecution@12
; 612 :
; 613 : //
; 614 : // Start the timer for the counter and increment
; 615 : // the reference count since the timer has a
; 616 : // reference to the irp.
; 617 : //
; 618 :
; 619 : if (Xc->Timeout) {
000a3 8b 03 mov eax, DWORD PTR [ebx]
000a5 85 c0 test eax, eax
000a7 74 2e je SHORT $L14942
; 620 :
; 621 : LARGE_INTEGER delta;
; 622 :
; 623 : delta.QuadPart = -((LONGLONG)UInt32x32To64(
; 624 : 1000,
; 625 : Xc->Timeout
; 626 : ));
000a9 6a ff push -1
000ab 68 18 fc ff ff push -1000 ; fffffc18H
000b0 6a 00 push 0
000b2 50 push eax
000b3 e8 00 00 00 00 call __allmul
; 627 :
; 628 : SerialSetTimer(
; 629 : &Extension->XoffCountTimer,
; 630 : delta,
; 631 : &Extension->XoffCountTimeoutDpc,
; 632 : Extension
; 633 :
; 634 : );
000b8 8d 8e 0c 03 00
00 lea ecx, DWORD PTR [esi+780]
000be 56 push esi
000bf 51 push ecx
000c0 52 push edx
000c1 50 push eax
000c2 8d 86 50 04 00
00 lea eax, DWORD PTR [esi+1104]
000c8 50 push eax
000c9 e8 00 00 00 00 call _SerialSetTimer@20
; 635 :
; 636 : SERIAL_SET_REFERENCE(
; 637 : Irp,
; 638 : SERIAL_REF_TOTAL_TIMER
; 639 : );
000ce 8b 7f 60 mov edi, DWORD PTR [edi+96]
000d1 83 c7 10 add edi, 16 ; 00000010H
000d4 83 0f 04 or DWORD PTR [edi], 4
$L14942:
; 640 :
; 641 : }
; 642 :
; 643 : }
; 644 :
; 645 : IoReleaseCancelSpinLock(OldIrql);
000d7 ff 75 fc push DWORD PTR _OldIrql$14912[ebp]
000da ff 15 00 00 00
00 call DWORD PTR __imp__IoReleaseCancelSpinLock@4
000e0 8b 7d 08 mov edi, DWORD PTR _CurrentOpIrp$[ebp]
$L14911:
; 646 :
; 647 : }
; 648 :
; 649 : //
; 650 : // Note that the following call will (probably) also cause
; 651 : // the current irp to be completed.
; 652 : //
; 653 :
; 654 : SerialGetNextIrp(
; 655 : CurrentOpIrp,
; 656 : QueueToProcess,
; 657 : NewIrp,
; 658 : CompleteCurrent,
; 659 : Extension
; 660 : );
000e3 8b 5d 10 mov ebx, DWORD PTR _NewIrp$[ebp]
000e6 56 push esi
000e7 ff 75 14 push DWORD PTR _CompleteCurrent$[ebp]
000ea 53 push ebx
000eb ff 75 0c push DWORD PTR _QueueToProcess$[ebp]
000ee 57 push edi
000ef e8 00 00 00 00 call _SerialGetNextIrp@20
; 661 :
; 662 : if (!*NewIrp) {
000f4 8b 03 mov eax, DWORD PTR [ebx]
000f6 85 c0 test eax, eax
000f8 74 11 je SHORT $L15185
; 673 :
; 674 : break;
; 675 :
; 676 : } else if (IoGetCurrentIrpStackLocation(*NewIrp)->MajorFunction
; 677 : == IRP_MJ_FLUSH_BUFFERS) {
000fa 8b 48 60 mov ecx, DWORD PTR [eax+96]
000fd 80 39 09 cmp BYTE PTR [ecx], 9
00100 75 2e jne SHORT $L14907
; 678 :
; 679 : //
; 680 : // If we encounter a flush request we just want to get
; 681 : // the next irp and complete the flush.
; 682 : //
; 683 : // Note that if NewIrp is non-null then it is also
; 684 : // equal to CurrentWriteIrp.
; 685 : //
; 686 :
; 687 :
; 688 : ASSERT((*NewIrp) == (*CurrentOpIrp));
; 689 : (*NewIrp)->IoStatus.Status = STATUS_SUCCESS;
00102 83 60 18 00 and DWORD PTR [eax+24], 0
; 690 :
; 691 : } else {
; 692 :
; 693 : break;
; 694 :
; 695 : }
; 696 :
; 697 : } while (TRUE);
00106 e9 ff fe ff ff jmp $L14905
$L15185:
; 663 :
; 664 : KIRQL OldIrql;
; 665 :
; 666 : IoAcquireCancelSpinLock(&OldIrql);
0010b 8d 45 08 lea eax, DWORD PTR _OldIrql$14947[ebp]
0010e 50 push eax
0010f ff 15 00 00 00
00 call DWORD PTR __imp__IoAcquireCancelSpinLock@4
; 667 : KeSynchronizeExecution(
; 668 : Extension->Interrupt,
; 669 : SerialProcessEmptyTransmit,
; 670 : Extension
; 671 : );
00115 56 push esi
00116 68 00 00 00 00 push OFFSET FLAT:_SerialProcessEmptyTransmit@4
0011b ff b6 a0 00 00
00 push DWORD PTR [esi+160]
00121 ff 15 00 00 00
00 call DWORD PTR __imp__KeSynchronizeExecution@12
; 672 : IoReleaseCancelSpinLock(OldIrql);
00127 ff 75 08 push DWORD PTR _OldIrql$14947[ebp]
0012a ff 15 00 00 00
00 call DWORD PTR __imp__IoReleaseCancelSpinLock@4
$L14907:
00130 5f pop edi
00131 5e pop esi
00132 5b pop ebx
; 698 :
; 699 : }
00133 c9 leave
00134 c2 14 00 ret 20 ; 00000014H
_SerialGetNextWrite@20 ENDP
PAGESER ENDS
PUBLIC _SerialCompleteWrite@16
EXTRN _SerialDpcEpilogue@8:NEAR
; Function compile flags: /Ogsy
; COMDAT _SerialCompleteWrite@16
_TEXT SEGMENT
_Dpc$ = 8
_DeferredContext$ = 12
_OldIrql$ = -4
_SerialCompleteWrite@16 PROC NEAR ; COMDAT
; 733 : {
00000 55 push ebp
00001 8b ec mov ebp, esp
00003 51 push ecx
; 734 :
; 735 : PSERIAL_DEVICE_EXTENSION Extension = DeferredContext;
; 736 : KIRQL OldIrql;
; 737 :
; 738 : UNREFERENCED_PARAMETER(SystemContext1);
; 739 : UNREFERENCED_PARAMETER(SystemContext2);
; 740 :
; 741 : SerialDump(SERTRACECALLS, ("SERIAL: SerialCompleteWrite\n"));
; 742 :
; 743 : IoAcquireCancelSpinLock(&OldIrql);
00004 8d 45 fc lea eax, DWORD PTR _OldIrql$[ebp]
00007 56 push esi
00008 50 push eax
00009 ff 15 00 00 00
00 call DWORD PTR __imp__IoAcquireCancelSpinLock@4
; 744 :
; 745 : SerialTryToCompleteCurrent(
; 746 : Extension,
; 747 : NULL,
; 748 : OldIrql,
; 749 : STATUS_SUCCESS,
; 750 : &Extension->CurrentWriteIrp,
; 751 : &Extension->WriteQueue,
; 752 : NULL,
; 753 : &Extension->WriteRequestTotalTimer,
; 754 : SerialStartWrite,
; 755 : SerialGetNextWrite,
; 756 : SERIAL_REF_ISR
; 757 : );
0000f 8b 75 0c mov esi, DWORD PTR _DeferredContext$[ebp]
00012 6a 01 push 1
00014 68 00 00 00 00 push OFFSET FLAT:_SerialGetNextWrite@20
00019 68 00 00 00 00 push OFFSET FLAT:_SerialStartWrite@4
0001e 8d 86 00 04 00
00 lea eax, DWORD PTR [esi+1024]
00024 8d 8e ac 00 00
00 lea ecx, DWORD PTR [esi+172]
0002a 50 push eax
0002b 33 c0 xor eax, eax
0002d 50 push eax
0002e 51 push ecx
0002f 8d 8e c8 00 00
00 lea ecx, DWORD PTR [esi+200]
00035 51 push ecx
00036 50 push eax
00037 ff 75 fc push DWORD PTR _OldIrql$[ebp]
0003a 50 push eax
0003b 56 push esi
0003c e8 00 00 00 00 call _SerialTryToCompleteCurrent@44
; 758 :
; 759 : SerialDpcEpilogue(Extension, Dpc);
00041 ff 75 08 push DWORD PTR _Dpc$[ebp]
00044 56 push esi
00045 e8 00 00 00 00 call _SerialDpcEpilogue@8
0004a 5e pop esi
; 760 :
; 761 : }
0004b c9 leave
0004c c2 10 00 ret 16 ; 00000010H
_SerialCompleteWrite@16 ENDP
_TEXT ENDS
EXTRN _SerialInsertQueueDpc@16:NEAR
EXTRN _SerialPerhapsLowerRTS@4:NEAR
; Function compile flags: /Ogsy
; COMDAT _SerialProcessEmptyTransmit@4
PAGESER SEGMENT
_Context$ = 8
_SerialProcessEmptyTransmit@4 PROC NEAR ; COMDAT
; 793 : {
00000 53 push ebx
00001 56 push esi
; 794 :
; 795 : PSERIAL_DEVICE_EXTENSION Extension = Context;
; 796 : SERIAL_LOCKED_PAGED_CODE();
; 797 :
; 798 : if (Extension->IsrWaitMask && (Extension->IsrWaitMask & SERIAL_EV_TXEMPTY) &&
; 799 : Extension->EmptiedTransmit && (!Extension->TransmitImmediate) &&
; 800 : (!Extension->CurrentWriteIrp) && IsListEmpty(&Extension->WriteQueue)) {
00002 8b 74 24 0c mov esi, DWORD PTR _Context$[esp+4]
00006 33 db xor ebx, ebx
00008 8b 86 10 01 00
00 mov eax, DWORD PTR [esi+272]
0000e 3b c3 cmp eax, ebx
00010 74 6d je SHORT $L14973
00012 a8 04 test al, 4
00014 74 69 je SHORT $L14973
00016 38 9e a2 01 00
00 cmp BYTE PTR [esi+418], bl
0001c 74 61 je SHORT $L14973
0001e 38 9e a1 01 00
00 cmp BYTE PTR [esi+417], bl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -