📄 openclos.cod
字号:
; 570 : // Synchronize with the ISR to let it know that interrupts are
; 571 : // no longer important.
; 572 : //
; 573 :
; 574 : KeSynchronizeExecution(
; 575 : extension->Interrupt,
; 576 : SerialMarkClose,
; 577 : extension
; 578 : );
0037b 56 push esi
0037c 68 00 00 00 00 push OFFSET FLAT:_SerialMarkClose@4
00381 ff b6 a0 00 00
00 push DWORD PTR [esi+160]
00387 ff 15 00 00 00
00 call DWORD PTR __imp__KeSynchronizeExecution@12
; 579 :
; 580 :
; 581 : //
; 582 : // If the driver has automatically transmitted an Xoff in
; 583 : // the context of automatic receive flow control then we
; 584 : // should transmit an Xon.
; 585 : //
; 586 :
; 587 : if (extension->RXHolding & SERIAL_RX_XOFF) {
0038d f6 86 20 01 00
00 02 test BYTE PTR [esi+288], 2
00394 74 6e je SHORT $L15073
; 588 :
; 589 : //
; 590 : // Loop until the holding register is empty.
; 591 : //
; 592 :
; 593 : while (!(READ_LINE_STATUS(extension->Controller) &
; 594 : SERIAL_LSR_THRE)) {
00396 eb 0c jmp SHORT $L15357
$L15061:
; 595 :
; 596 : KeDelayExecutionThread(
; 597 : KernelMode,
; 598 : FALSE,
; 599 : &charTime
; 600 : );
00398 8d 45 ec lea eax, DWORD PTR _charTime$[ebp]
0039b 50 push eax
0039c 53 push ebx
0039d 53 push ebx
0039e ff 15 00 00 00
00 call DWORD PTR __imp__KeDelayExecutionThread@12
$L15357:
003a4 8b 86 98 00 00
00 mov eax, DWORD PTR [esi+152]
003aa 83 c0 05 add eax, 5
003ad 50 push eax
003ae ff 15 00 00 00
00 call DWORD PTR __imp__READ_PORT_UCHAR@4
003b4 a8 20 test al, 32 ; 00000020H
003b6 74 e0 je SHORT $L15061
; 601 :
; 602 : }
; 603 :
; 604 : WRITE_TRANSMIT_HOLDING(
; 605 : extension->Controller,
; 606 : extension->SpecialChars.XonChar
; 607 : );
003b8 8a 86 70 01 00
00 mov al, BYTE PTR [esi+368]
003be 50 push eax
003bf ff b6 98 00 00
00 push DWORD PTR [esi+152]
003c5 ff 15 00 00 00
00 call DWORD PTR __imp__WRITE_PORT_UCHAR@8
; 608 :
; 609 : //
; 610 : // Wait a reasonable amount of time for the characters
; 611 : // to be emptied out of the hardware.
; 612 : //
; 613 :
; 614 : for (flushCount = (20 * 16); flushCount != 0; flushCount--) {
003cb c7 45 fc 40 01
00 00 mov DWORD PTR _flushCount$[ebp], 320 ; 00000140H
$L15067:
; 615 : if ((READ_LINE_STATUS(extension->Controller) &
; 616 : (SERIAL_LSR_THRE | SERIAL_LSR_TEMT)) !=
; 617 : (SERIAL_LSR_THRE | SERIAL_LSR_TEMT)) {
003d2 8b 86 98 00 00
00 mov eax, DWORD PTR [esi+152]
003d8 83 c0 05 add eax, 5
003db 50 push eax
003dc ff 15 00 00 00
00 call DWORD PTR __imp__READ_PORT_UCHAR@4
003e2 24 60 and al, 96 ; 00000060H
003e4 3c 60 cmp al, 96 ; 00000060H
003e6 74 11 je SHORT $L15071
; 618 :
; 619 : KeDelayExecutionThread(KernelMode, FALSE, &charTime);
003e8 8d 45 ec lea eax, DWORD PTR _charTime$[ebp]
003eb 50 push eax
003ec 53 push ebx
003ed 53 push ebx
003ee ff 15 00 00 00
00 call DWORD PTR __imp__KeDelayExecutionThread@12
003f4 ff 4d fc dec DWORD PTR _flushCount$[ebp]
003f7 75 d9 jne SHORT $L15067
$L15071:
; 620 : } else {
; 621 : break;
; 622 : }
; 623 : }
; 624 :
; 625 : if (flushCount == 0) {
003f9 39 5d fc cmp DWORD PTR _flushCount$[ebp], ebx
003fc 75 06 jne SHORT $L15073
; 626 : SerialMarkHardwareBroken(extension);
003fe 56 push esi
003ff e8 00 00 00 00 call _SerialMarkHardwareBroken@4
$L15073:
; 627 : }
; 628 : }
; 629 :
; 630 :
; 631 : //
; 632 : // The hardware is empty. Delay 10 character times before
; 633 : // shut down all the flow control.
; 634 : //
; 635 :
; 636 : tenCharDelay.QuadPart = charTime.QuadPart * 10;
00404 53 push ebx
00405 6a 0a push 10 ; 0000000aH
00407 ff 75 f0 push DWORD PTR _charTime$[ebp+4]
0040a ff 75 ec push DWORD PTR _charTime$[ebp]
0040d e8 00 00 00 00 call __allmul
00412 89 45 e4 mov DWORD PTR _tenCharDelay$[ebp], eax
; 637 :
; 638 : KeDelayExecutionThread(
; 639 : KernelMode,
; 640 : TRUE,
; 641 : &tenCharDelay
; 642 : );
00415 8d 45 e4 lea eax, DWORD PTR _tenCharDelay$[ebp]
00418 50 push eax
00419 6a 01 push 1
0041b 53 push ebx
0041c 89 55 e8 mov DWORD PTR _tenCharDelay$[ebp+4], edx
0041f ff 15 00 00 00
00 call DWORD PTR __imp__KeDelayExecutionThread@12
; 643 :
; 644 : SerialClrDTR(extension);
00425 56 push esi
00426 e8 00 00 00 00 call _SerialClrDTR@4
; 645 :
; 646 : //
; 647 : // We have to be very careful how we clear the RTS line.
; 648 : // Transmit toggling might have been on at some point.
; 649 : //
; 650 : // We know that there is nothing left that could start
; 651 : // out the "polling" execution path. We need to
; 652 : // check the counter that indicates that the execution
; 653 : // path is active. If it is then we loop delaying one
; 654 : // character time. After each delay we check to see if
; 655 : // the counter has gone to zero. When it has we know that
; 656 : // the execution path should be just about finished. We
; 657 : // make sure that we still aren't in the routine that
; 658 : // synchronized execution with the ISR by synchronizing
; 659 : // ourselve with the ISR.
; 660 : //
; 661 :
; 662 : if (extension->CountOfTryingToLowerRTS) {
0042b 8d be 3c 01 00
00 lea edi, DWORD PTR [esi+316]
00431 39 1f cmp DWORD PTR [edi], ebx
00433 74 22 je SHORT $L15074
$L15075:
; 663 :
; 664 : do {
; 665 :
; 666 : KeDelayExecutionThread(
; 667 : KernelMode,
; 668 : FALSE,
; 669 : &charTime
; 670 : );
00435 8d 45 ec lea eax, DWORD PTR _charTime$[ebp]
00438 50 push eax
00439 53 push ebx
0043a 53 push ebx
0043b ff 15 00 00 00
00 call DWORD PTR __imp__KeDelayExecutionThread@12
; 671 :
; 672 : } while (extension->CountOfTryingToLowerRTS);
00441 39 1f cmp DWORD PTR [edi], ebx
00443 75 f0 jne SHORT $L15075
; 673 :
; 674 : KeSynchronizeExecution(
; 675 : extension->Interrupt,
; 676 : SerialNullSynch,
; 677 : NULL
; 678 : );
00445 53 push ebx
00446 68 00 00 00 00 push OFFSET FLAT:_SerialNullSynch@4
0044b ff b6 a0 00 00
00 push DWORD PTR [esi+160]
00451 ff 15 00 00 00
00 call DWORD PTR __imp__KeSynchronizeExecution@12
$L15074:
; 679 :
; 680 : //
; 681 : // The execution path should no longer exist that
; 682 : // is trying to push down the RTS. Well just
; 683 : // make sure it's down by falling through to
; 684 : // code that forces it down.
; 685 : //
; 686 :
; 687 : }
; 688 :
; 689 : SerialClrRTS(extension);
00457 56 push esi
00458 e8 00 00 00 00 call _SerialClrRTS@4
; 690 :
; 691 : //
; 692 : // Clean out the holding reasons (since we are closed).
; 693 : //
; 694 :
; 695 : extension->RXHolding = 0;
; 696 : extension->TXHolding = 0;
; 697 :
; 698 : //
; 699 : // Mark device as not busy for WMI
; 700 : //
; 701 :
; 702 : extension->WmiCommData.IsBusy = FALSE;
; 703 :
; 704 : //
; 705 : // All is done. The port has been disabled from interrupting
; 706 : // so there is no point in keeping the memory around.
; 707 : //
; 708 :
; 709 : extension->BufferSize = 0;
; 710 : if (extension->InterruptReadBuffer != NULL) {
0045d 8d be e8 00 00
00 lea edi, DWORD PTR [esi+232]
00463 89 9e 20 01 00
00 mov DWORD PTR [esi+288], ebx
00469 89 9e 1c 01 00
00 mov DWORD PTR [esi+284], ebx
0046f 88 9e f0 05 00
00 mov BYTE PTR [esi+1520], bl
00475 8b 07 mov eax, DWORD PTR [edi]
00477 89 9e 04 01 00
00 mov DWORD PTR [esi+260], ebx
0047d 3b c3 cmp eax, ebx
0047f 74 07 je SHORT $L15080
; 711 : ExFreePool(extension->InterruptReadBuffer);
00481 50 push eax
00482 ff 15 00 00 00
00 call DWORD PTR __imp__ExFreePool@4
$L15080:
; 712 : }
; 713 : extension->InterruptReadBuffer = NULL;
; 714 :
; 715 : //
; 716 : // Stop waiting for wakeup
; 717 : //
; 718 :
; 719 : extension->SendWaitWake = FALSE;
; 720 :
; 721 : if (extension->PendingWakeIrp != NULL) {
00488 8b 86 88 05 00
00 mov eax, DWORD PTR [esi+1416]
0048e 89 1f mov DWORD PTR [edi], ebx
00490 3b c3 cmp eax, ebx
00492 88 9e 84 05 00
00 mov BYTE PTR [esi+1412], bl
00498 74 07 je SHORT $L15083
; 722 : IoCancelIrp(extension->PendingWakeIrp);
0049a 50 push eax
0049b ff 15 00 00 00
00 call DWORD PTR __imp__IoCancelIrp@4
$L15083:
; 723 : }
; 724 :
; 725 : //
; 726 : // Power down our device stack
; 727 : //
; 728 :
; 729 : (void)SerialGotoPowerState(DeviceObject, extension, PowerDeviceD3);
004a1 6a 04 push 4
004a3 56 push esi
004a4 ff 75 08 push DWORD PTR _DeviceObject$[ebp]
004a7 e8 00 00 00 00 call _SerialGotoPowerState@12
; 730 :
; 731 : Irp->IoStatus.Status = STATUS_SUCCESS;
004ac 8b 7d 0c mov edi, DWORD PTR _Irp$[ebp]
004af 89 5f 18 mov DWORD PTR [edi+24], ebx
; 732 : Irp->IoStatus.Information=0L;
004b2 89 5f 1c mov DWORD PTR [edi+28], ebx
; 733 :
; 734 : SerialDump(
; 735 : SERIRPPATH,
; 736 : ("SERIAL: Complete Irp: %x\n",Irp)
; 737 : );
004b5 f6 05 00 00 00
00 20 test BYTE PTR _SerialDebugLevel, 32 ; 00000020H
004bc 74 0d je SHORT $L15087
004be 57 push edi
004bf 68 00 00 00 00 push OFFSET FLAT:$SG15092
004c4 e8 00 00 00 00 call _DbgPrint
004c9 59 pop ecx
004ca 59 pop ecx
$L15087:
; 738 : SerialCompleteRequest(extension, Irp, IO_NO_INCREMENT);
004cb 32 d2 xor dl, dl
004cd 8b cf mov ecx, edi
004cf ff 15 00 00 00
00 call DWORD PTR __imp_@IofCompleteRequest@8
004d5 56 push esi
004d6 e8 00 00 00 00 call _SerialIRPEpilogue@4
; 739 :
; 740 : //
; 741 : // Unlock the pages. If this is the last reference to the section
; 742 : // then the driver code will be flushed out.
; 743 : //
; 744 :
; 745 : //
; 746 : // First, we have to let the DPC's drain. No more should be queued
; 747 : // since we aren't taking interrupts now....
; 748 : //
; 749 :
; 750 : pendingDPCs = InterlockedDecrement(&extension->DpcCount);
004db 8d be 30 06 00
00 lea edi, DWORD PTR [esi+1584]
004e1 8b cf mov ecx, edi
004e3 ff 15 00 00 00
00 call DWORD PTR __imp_@InterlockedDecrement@4
; 751 : LOGENTRY(LOG_CNT, 'DpD7', 0, extension->DpcCount, 0);
004e9 53 push ebx
004ea 89 45 08 mov DWORD PTR _pendingDPCs$[ebp], eax
004ed ff 37 push DWORD PTR [edi]
004ef 53 push ebx
004f0 68 37 44 70 44 push 1148208183 ; 44704437H
004f5 6a 02 push 2
004f7 e8 00 00 00 00 call _SerialDebugLogEntry@20
; 752 :
; 753 : if (pendingDPCs) {
004fc 39 5d 08 cmp DWORD PTR _pendingDPCs$[ebp], ebx
004ff 74 29 je SHORT $L15117
; 754 : SerialDump(SERDIAG1, ("SERIAL: Drainging DPC's: %x\n",Irp));
00501 f6 05 00 00 00
00 01 test BYTE PTR _SerialDebugLevel, 1
00508 74 0f je SHORT $L15104
0050a ff 75 0c push DWORD PTR _Irp$[ebp]
0050d 68 00 00 00 00 push OFFSET FLAT:$SG15109
00512 e8 00 00 00 00 call _DbgPrint
00517 59 pop ecx
00518 59 pop ecx
$L15104:
; 755 : KeWaitForSingleObject(&extension->PendingDpcEvent, Executive,
; 756 : KernelMode, FALSE, NULL);
00519 53 push ebx
0051a 53 push ebx
0051b 53 push ebx
0051c 81 c6 34 06 00
00 add esi, 1588 ; 00000634H
00522 53 push ebx
00523 56 push esi
00524 ff 15 00 00 00
00 call DWORD PTR __imp__KeWaitForSingleObject@20
$L15117:
; 757 : }
; 758 :
; 759 :
; 760 : SerialDump(SERDIAG1, ("SERIAL: DPC's drained: %x\n",Irp));
0052a f6 05 00 00 00
00 01 test BYTE PTR _SerialDebugLevel, 1
00531 74 0f je SHORT $L15118
00533 ff 75 0c push DWORD PTR _Irp$[ebp]
00536 68 00 00 00 00 push OFFSET FLAT:$SG15123
0053b e8 00 00 00 00 call _DbgPrint
00540 59 pop ecx
00541 59 pop ecx
$L15118:
; 761 :
; 762 :
; 763 :
; 764 : //
; 765 : // Pages must be locked to release the mutex, so don't unlock
; 766 : // them until after we release the mutex
; 767 : //
; 768 :
; 769 : ExReleaseFastMutex(&extension->CloseMutex);
00542 8b 4d f8 mov ecx, DWORD PTR -8+[ebp]
00545 ff 15 00 00 00
00 call DWORD PTR __imp_@ExReleaseFastMutex@4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -