📄 openclos.cod
字号:
; 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) {
001c7 8d be 3c 01 00
00 lea edi, DWORD PTR [esi+316]
001cd 39 1f cmp DWORD PTR [edi], ebx
001cf 74 22 je SHORT $L14916
$L14917:
; 663 :
; 664 : do {
; 665 :
; 666 : KeDelayExecutionThread(
; 667 : KernelMode,
; 668 : FALSE,
; 669 : &charTime
; 670 : );
001d1 8d 45 ec lea eax, DWORD PTR _charTime$[ebp]
001d4 50 push eax
001d5 53 push ebx
001d6 53 push ebx
001d7 ff 15 00 00 00
00 call DWORD PTR __imp__KeDelayExecutionThread@12
; 671 :
; 672 : } while (extension->CountOfTryingToLowerRTS);
001dd 39 1f cmp DWORD PTR [edi], ebx
001df 75 f0 jne SHORT $L14917
; 673 :
; 674 : KeSynchronizeExecution(
; 675 : extension->Interrupt,
; 676 : SerialNullSynch,
; 677 : NULL
; 678 : );
001e1 53 push ebx
001e2 68 00 00 00 00 push OFFSET FLAT:_SerialNullSynch@4
001e7 ff b6 a0 00 00
00 push DWORD PTR [esi+160]
001ed ff 15 00 00 00
00 call DWORD PTR __imp__KeSynchronizeExecution@12
$L14916:
; 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);
001f3 56 push esi
001f4 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) {
001f9 8d be e8 00 00
00 lea edi, DWORD PTR [esi+232]
001ff 89 9e 20 01 00
00 mov DWORD PTR [esi+288], ebx
00205 89 9e 1c 01 00
00 mov DWORD PTR [esi+284], ebx
0020b 88 9e f0 05 00
00 mov BYTE PTR [esi+1520], bl
00211 8b 07 mov eax, DWORD PTR [edi]
00213 89 9e 04 01 00
00 mov DWORD PTR [esi+260], ebx
00219 3b c3 cmp eax, ebx
0021b 74 07 je SHORT $L14922
; 711 : ExFreePool(extension->InterruptReadBuffer);
0021d 50 push eax
0021e ff 15 00 00 00
00 call DWORD PTR __imp__ExFreePool@4
$L14922:
; 712 : }
; 713 : extension->InterruptReadBuffer = NULL;
; 714 :
; 715 : //
; 716 : // Stop waiting for wakeup
; 717 : //
; 718 :
; 719 : extension->SendWaitWake = FALSE;
; 720 :
; 721 : if (extension->PendingWakeIrp != NULL) {
00224 8b 86 88 05 00
00 mov eax, DWORD PTR [esi+1416]
0022a 89 1f mov DWORD PTR [edi], ebx
0022c 3b c3 cmp eax, ebx
0022e 88 9e 84 05 00
00 mov BYTE PTR [esi+1412], bl
00234 74 07 je SHORT $L14925
; 722 : IoCancelIrp(extension->PendingWakeIrp);
00236 50 push eax
00237 ff 15 00 00 00
00 call DWORD PTR __imp__IoCancelIrp@4
$L14925:
; 723 : }
; 724 :
; 725 : //
; 726 : // Power down our device stack
; 727 : //
; 728 :
; 729 : (void)SerialGotoPowerState(DeviceObject, extension, PowerDeviceD3);
0023d 6a 04 push 4
0023f 56 push esi
00240 ff 75 08 push DWORD PTR _DeviceObject$[ebp]
00243 e8 00 00 00 00 call _SerialGotoPowerState@12
; 730 :
; 731 : Irp->IoStatus.Status = STATUS_SUCCESS;
00248 8b 4d 0c mov ecx, DWORD PTR _Irp$[ebp]
; 732 : Irp->IoStatus.Information=0L;
; 733 :
; 734 : SerialDump(
; 735 : SERIRPPATH,
; 736 : ("SERIAL: Complete Irp: %x\n",Irp)
; 737 : );
; 738 : SerialCompleteRequest(extension, Irp, IO_NO_INCREMENT);
0024b 32 d2 xor dl, dl
0024d 89 59 18 mov DWORD PTR [ecx+24], ebx
00250 89 59 1c mov DWORD PTR [ecx+28], ebx
00253 ff 15 00 00 00
00 call DWORD PTR __imp_@IofCompleteRequest@8
00259 56 push esi
0025a 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);
0025f 8b 3d 00 00 00
00 mov edi, DWORD PTR __imp_@InterlockedDecrement@4
00265 8d 8e 30 06 00
00 lea ecx, DWORD PTR [esi+1584]
0026b 89 4d 0c mov DWORD PTR 12+[ebp], ecx
0026e ff d7 call edi
; 751 : LOGENTRY(LOG_CNT, 'DpD7', 0, extension->DpcCount, 0);
; 752 :
; 753 : if (pendingDPCs) {
00270 85 c0 test eax, eax
00272 74 11 je SHORT $L14936
; 754 : SerialDump(SERDIAG1, ("SERIAL: Drainging DPC's: %x\n",Irp));
; 755 : KeWaitForSingleObject(&extension->PendingDpcEvent, Executive,
; 756 : KernelMode, FALSE, NULL);
00274 53 push ebx
00275 53 push ebx
00276 53 push ebx
00277 81 c6 34 06 00
00 add esi, 1588 ; 00000634H
0027d 53 push ebx
0027e 56 push esi
0027f ff 15 00 00 00
00 call DWORD PTR __imp__KeWaitForSingleObject@20
$L14936:
; 757 : }
; 758 :
; 759 :
; 760 : SerialDump(SERDIAG1, ("SERIAL: DPC's drained: %x\n",Irp));
; 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);
00285 8b 4d f8 mov ecx, DWORD PTR -8+[ebp]
00288 ff 15 00 00 00
00 call DWORD PTR __imp_@ExReleaseFastMutex@4
; 770 :
; 771 : //
; 772 : // Reset for next open
; 773 : //
; 774 :
; 775 : InterlockedIncrement(&extension->DpcCount);
0028e 8b 4d 0c mov ecx, DWORD PTR 12+[ebp]
00291 ff 15 00 00 00
00 call DWORD PTR __imp_@InterlockedIncrement@4
; 776 : LOGENTRY(LOG_CNT, 'DpI6', 0, extension->DpcCount, 0);
; 777 :
; 778 : openCount = InterlockedDecrement(&extension->OpenCount);
00297 8b 4d f4 mov ecx, DWORD PTR -12+[ebp]
0029a ff d7 call edi
; 779 :
; 780 : ASSERT(openCount == 0);
; 781 : SerialUnlockPagableImageSection(SerialGlobals.PAGESER_Handle);
0029c ff 35 08 00 00
00 push DWORD PTR _SerialGlobals+8
002a2 ff 15 00 00 00
00 call DWORD PTR __imp__MmUnlockPagableImageSection@4
; 782 :
; 783 : return STATUS_SUCCESS;
002a8 33 c0 xor eax, eax
$L14860:
002aa 5f pop edi
002ab 5e pop esi
002ac 5b pop ebx
; 784 :
; 785 : }
002ad c9 leave
002ae c2 08 00 ret 8
_SerialClose@8 ENDP
; Function compile flags: /Ogsy
PAGESER ENDS
; COMDAT _SerialCheckOpen@4
PAGESER SEGMENT
_Context$ = 8
_SerialCheckOpen@4 PROC NEAR ; COMDAT
; 834 :
; 835 : PSERIAL_DEVICE_EXTENSION extensionToOpen =
; 836 : ((PSERIAL_CHECK_OPEN)Context)->Extension;
00000 8b 4c 24 04 mov ecx, DWORD PTR _Context$[esp-4]
00004 53 push ebx
00005 56 push esi
; 837 : NTSTATUS *status = ((PSERIAL_CHECK_OPEN)Context)->StatusOfOpen;
; 838 : PLIST_ENTRY firstEntry = &extensionToOpen->CommonInterruptObject;
; 839 : PLIST_ENTRY currentEntry = firstEntry;
00006 33 db xor ebx, ebx
00008 8b 01 mov eax, DWORD PTR [ecx]
0000a 8b 51 04 mov edx, DWORD PTR [ecx+4]
0000d 8d 70 10 lea esi, DWORD PTR [eax+16]
00010 8b ce mov ecx, esi
$L14950:
; 840 : PSERIAL_DEVICE_EXTENSION currentExtension;
; 841 :
; 842 : do {
; 843 :
; 844 : currentExtension = CONTAINING_RECORD(
; 845 : currentEntry,
; 846 : SERIAL_DEVICE_EXTENSION,
; 847 : CommonInterruptObject
; 848 : );
; 849 :
; 850 : if (currentExtension->DeviceIsOpened) {
00012 38 99 8d 01 00
00 cmp BYTE PTR [ecx+397], bl
00018 75 08 jne SHORT $L14952
; 851 :
; 852 : break;
; 853 :
; 854 : }
; 855 :
; 856 : currentEntry = currentExtension->CommonInterruptObject.Flink;
0001a 8b 09 mov ecx, DWORD PTR [ecx]
; 857 :
; 858 : } while (currentEntry != firstEntry);
0001c 3b ce cmp ecx, esi
0001e 75 f2 jne SHORT $L14950
00020 eb 1c jmp SHORT $L14964
$L14952:
; 859 :
; 860 : if (currentEntry == firstEntry) {
00022 3b ce cmp ecx, esi
; 861 :
; 862 : //
; 863 : // We searched the whole list and found no other opens
; 864 : // mark the status as successful and call the regular
; 865 : // opening routine.
; 866 : //
; 867 :
; 868 : *status = STATUS_SUCCESS;
; 869 : SerialMarkOpen(extensionToOpen);
; 870 :
; 871 : } else {
00024 74 18 je SHORT $L14964
; 872 :
; 873 : if (!extensionToOpen->PortOnAMultiportCard) {
00026 38 98 a3 01 00
00 cmp BYTE PTR [eax+419], bl
0002c 75 08 jne SHORT $L14961
$L15137:
; 874 :
; 875 : *status = STATUS_SHARED_IRQ_BUSY;
0002e c7 02 6c 01 00
c0 mov DWORD PTR [edx], -1073741460 ; c000016cH
; 876 :
; 877 : } else {
00034 eb 10 jmp SHORT $L14966
$L14961:
; 878 :
; 879 : if (!currentExtension->PortOnAMultiportCard) {
00036 38 99 93 01 00
00 cmp BYTE PTR [ecx+403], bl
; 880 :
; 881 : *status = STATUS_SHARED_IRQ_BUSY;
; 882 :
; 883 : } else {
0003c 74 f0 je SHORT $L15137
$L14964:
; 884 :
; 885 : *status = STATUS_SUCCESS;
; 886 : SerialMarkOpen(extensionToOpen);
0003e 50 push eax
0003f 89 1a mov DWORD PTR [edx], ebx
00041 e8 00 00 00 00 call _SerialMarkOpen@4
$L14966:
00046 5e pop esi
; 887 :
; 888 : }
; 889 :
; 890 : }
; 891 :
; 892 : }
; 893 :
; 894 : return FALSE;
00047 32 c0 xor al, al
00049 5b pop ebx
; 895 :
; 896 : }
0004a c2 04 00 ret 4
_SerialCheckOpen@4 ENDP
PAGESER ENDS
EXTRN _SerialReset@4:NEAR
; Function compile flags: /Ogsy
; COMDAT _SerialMarkOpen@4
PAGESER SEGMENT
_Context$ = 8
_SerialMarkOpen@4 PROC NEAR ; COMDAT
; 921 : {
00000 56 push esi
; 922 :
; 923 : PSERIAL_DEVICE_EXTENSION extension = Context;
; 924 :
; 925 : SerialReset(extension);
00001 8b 74 24 08 mov esi, DWORD PTR _Context$[esp]
00005 57 push edi
00006 56 push esi
00007 e8 00 00 00 00 call _SerialReset@4
; 926 :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -