📄 openclos.cod
字号:
; 455 : // Holds a character time.
; 456 : //
; 457 : LARGE_INTEGER charTime;
; 458 :
; 459 : //
; 460 : // Just what it says. This is the serial specific device
; 461 : // extension of the device object create for the serial driver.
; 462 : //
; 463 : PSERIAL_DEVICE_EXTENSION extension = DeviceObject->DeviceExtension;
00006 8b 45 08 mov eax, DWORD PTR _DeviceObject$[ebp]
00009 53 push ebx
0000a 56 push esi
0000b 57 push edi
0000c 8b 70 28 mov esi, DWORD PTR [eax+40]
; 464 :
; 465 : NTSTATUS status;
; 466 :
; 467 : //
; 468 : // Number of opens still active
; 469 : //
; 470 :
; 471 : LONG openCount;
; 472 :
; 473 : //
; 474 : // Number of DPC's still pending
; 475 : //
; 476 :
; 477 : ULONG pendingDPCs;
; 478 :
; 479 : ULONG flushCount;
; 480 :
; 481 : //
; 482 : // Grab a mutex
; 483 : //
; 484 :
; 485 : ExAcquireFastMutex(&extension->CloseMutex);
0000f 8d 8e 54 05 00
00 lea ecx, DWORD PTR [esi+1364]
00015 89 4d f8 mov DWORD PTR -8+[ebp], ecx
00018 ff 15 00 00 00
00 call DWORD PTR __imp_@ExAcquireFastMutex@4
; 486 :
; 487 :
; 488 : //
; 489 : // We succeed a close on a removing device
; 490 : //
; 491 :
; 492 : if ((status = SerialIRPPrologue(Irp, extension)) != STATUS_SUCCESS) {
0001e 56 push esi
0001f ff 75 0c push DWORD PTR _Irp$[ebp]
00022 e8 00 00 00 00 call _SerialIRPPrologue@8
00027 8b f8 mov edi, eax
00029 33 db xor ebx, ebx
0002b 3b fb cmp edi, ebx
0002d 74 4e je SHORT $L14869
; 493 : SerialDump(SERERRORS, ("SERIAL: Close prologue failed for: %x\n",Irp));
; 494 : if (status == STATUS_DELETE_PENDING) {
0002f 81 ff 56 00 00
c0 cmp edi, -1073741738 ; c0000056H
00035 75 1e jne SHORT $L14874
; 495 : extension->BufferSize = 0;
; 496 : ExFreePool(extension->InterruptReadBuffer);
00037 8d be e8 00 00
00 lea edi, DWORD PTR [esi+232]
0003d 89 9e 04 01 00
00 mov DWORD PTR [esi+260], ebx
00043 ff 37 push DWORD PTR [edi]
00045 ff 15 00 00 00
00 call DWORD PTR __imp__ExFreePool@4
; 497 : extension->InterruptReadBuffer = NULL;
; 498 : status = Irp->IoStatus.Status = STATUS_SUCCESS;
0004b 8b 45 0c mov eax, DWORD PTR _Irp$[ebp]
0004e 89 1f mov DWORD PTR [edi], ebx
00050 33 ff xor edi, edi
00052 89 58 18 mov DWORD PTR [eax+24], ebx
$L14874:
; 499 : }
; 500 :
; 501 : SerialCompleteRequest(extension, Irp, IO_NO_INCREMENT);
00055 8b 4d 0c mov ecx, DWORD PTR _Irp$[ebp]
00058 32 d2 xor dl, dl
0005a ff 15 00 00 00
00 call DWORD PTR __imp_@IofCompleteRequest@8
00060 56 push esi
00061 e8 00 00 00 00 call _SerialIRPEpilogue@4
; 502 : openCount = InterlockedDecrement(&extension->OpenCount);
00066 8d 8e e8 04 00
00 lea ecx, DWORD PTR [esi+1256]
0006c ff 15 00 00 00
00 call DWORD PTR __imp_@InterlockedDecrement@4
; 503 : ASSERT(openCount == 0);
; 504 : ExReleaseFastMutex(&extension->CloseMutex);
00072 8b 4d f8 mov ecx, DWORD PTR -8+[ebp]
00075 ff 15 00 00 00
00 call DWORD PTR __imp_@ExReleaseFastMutex@4
; 505 : return status;
0007b eb 30 jmp SHORT $L15130
$L14869:
; 506 : }
; 507 :
; 508 : ASSERT(extension->OpenCount == 1);
; 509 :
; 510 : if (extension->OpenCount != 1) {
0007d 8d 86 e8 04 00
00 lea eax, DWORD PTR [esi+1256]
00083 89 45 f4 mov DWORD PTR -12+[ebp], eax
00086 83 38 01 cmp DWORD PTR [eax], 1
00089 74 29 je SHORT $L14886
; 511 : SerialDump(SERERRORS, ("SERIAL: Close open count bad for: 0x%x\n",Irp));
; 512 : SerialDump(SERERRORS, ("------: Count: %x Addr: 0x%x\n",
; 513 : extension->OpenCount, &extension->OpenCount));
; 514 : ExReleaseFastMutex(&extension->CloseMutex);
0008b 8b 4d f8 mov ecx, DWORD PTR -8+[ebp]
0008e ff 15 00 00 00
00 call DWORD PTR __imp_@ExReleaseFastMutex@4
; 515 : Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
00094 8b 4d 0c mov ecx, DWORD PTR _Irp$[ebp]
00097 bf 10 00 00 c0 mov edi, -1073741808 ; c0000010H
; 516 : SerialCompleteRequest(extension, Irp, IO_NO_INCREMENT);
0009c 32 d2 xor dl, dl
0009e 89 79 18 mov DWORD PTR [ecx+24], edi
000a1 ff 15 00 00 00
00 call DWORD PTR __imp_@IofCompleteRequest@8
000a7 56 push esi
000a8 e8 00 00 00 00 call _SerialIRPEpilogue@4
$L15130:
; 517 : return STATUS_INVALID_DEVICE_REQUEST;
000ad 8b c7 mov eax, edi
000af e9 f6 01 00 00 jmp $L14860
$L14886:
; 518 : }
; 519 :
; 520 : SerialDump(
; 521 : SERIRPPATH,
; 522 : ("SERIAL: Dispatch entry for: %x\n",Irp)
; 523 : );
; 524 : SerialDump(
; 525 : SERDIAG3,
; 526 : ("SERIAL: In SerialClose\n")
; 527 : );
; 528 :
; 529 : charTime.QuadPart = -SerialGetCharTime(extension).QuadPart;
000b4 56 push esi
000b5 e8 00 00 00 00 call _SerialGetCharTime@4
000ba f7 d8 neg eax
000bc 13 d3 adc edx, ebx
; 530 :
; 531 : //
; 532 : // Do this now so that if the isr gets called it won't do anything
; 533 : // to cause more chars to get sent. We want to run down the hardware.
; 534 : //
; 535 :
; 536 : extension->DeviceIsOpened = FALSE;
; 537 :
; 538 : //
; 539 : // Synchronize with the isr to turn off break if it
; 540 : // is already on.
; 541 : //
; 542 :
; 543 : KeSynchronizeExecution(
; 544 : extension->Interrupt,
; 545 : SerialTurnOffBreak,
; 546 : extension
; 547 : );
000be 56 push esi
000bf f7 da neg edx
000c1 68 00 00 00 00 push OFFSET FLAT:_SerialTurnOffBreak@4
000c6 89 45 ec mov DWORD PTR _charTime$[ebp], eax
000c9 89 55 f0 mov DWORD PTR _charTime$[ebp+4], edx
000cc ff b6 a0 00 00
00 push DWORD PTR [esi+160]
000d2 88 9e 9d 01 00
00 mov BYTE PTR [esi+413], bl
000d8 ff 15 00 00 00
00 call DWORD PTR __imp__KeSynchronizeExecution@12
; 548 :
; 549 : //
; 550 : // Wait a reasonable amount of time (20 * fifodepth) until all characters
; 551 : // have been emptied out of the hardware.
; 552 : //
; 553 :
; 554 : for (flushCount = (20 * 16); flushCount != 0; flushCount--) {
000de c7 45 fc 40 01
00 00 mov DWORD PTR _flushCount$[ebp], 320 ; 00000140H
$L14892:
; 555 : if ((READ_LINE_STATUS(extension->Controller) &
; 556 : (SERIAL_LSR_THRE | SERIAL_LSR_TEMT)) !=
; 557 : (SERIAL_LSR_THRE | SERIAL_LSR_TEMT)) {
000e5 8b 86 98 00 00
00 mov eax, DWORD PTR [esi+152]
000eb 83 c0 05 add eax, 5
000ee 50 push eax
000ef ff 15 00 00 00
00 call DWORD PTR __imp__READ_PORT_UCHAR@4
000f5 24 60 and al, 96 ; 00000060H
000f7 3c 60 cmp al, 96 ; 00000060H
000f9 74 11 je SHORT $L14896
; 558 :
; 559 : KeDelayExecutionThread(KernelMode, FALSE, &charTime);
000fb 8d 45 ec lea eax, DWORD PTR _charTime$[ebp]
000fe 50 push eax
000ff 53 push ebx
00100 53 push ebx
00101 ff 15 00 00 00
00 call DWORD PTR __imp__KeDelayExecutionThread@12
00107 ff 4d fc dec DWORD PTR _flushCount$[ebp]
0010a 75 d9 jne SHORT $L14892
$L14896:
; 560 : } else {
; 561 : break;
; 562 : }
; 563 : }
; 564 :
; 565 : if (flushCount == 0) {
0010c 39 5d fc cmp DWORD PTR _flushCount$[ebp], ebx
0010f 75 06 jne SHORT $L14898
; 566 : SerialMarkHardwareBroken(extension);
00111 56 push esi
00112 e8 00 00 00 00 call _SerialMarkHardwareBroken@4
$L14898:
; 567 : }
; 568 :
; 569 : //
; 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 : );
00117 56 push esi
00118 68 00 00 00 00 push OFFSET FLAT:_SerialMarkClose@4
0011d ff b6 a0 00 00
00 push DWORD PTR [esi+160]
00123 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) {
00129 f6 86 20 01 00
00 02 test BYTE PTR [esi+288], 2
00130 74 6e je SHORT $L14915
; 588 :
; 589 : //
; 590 : // Loop until the holding register is empty.
; 591 : //
; 592 :
; 593 : while (!(READ_LINE_STATUS(extension->Controller) &
; 594 : SERIAL_LSR_THRE)) {
00132 eb 0c jmp SHORT $L15129
$L14903:
; 595 :
; 596 : KeDelayExecutionThread(
; 597 : KernelMode,
; 598 : FALSE,
; 599 : &charTime
; 600 : );
00134 8d 45 ec lea eax, DWORD PTR _charTime$[ebp]
00137 50 push eax
00138 53 push ebx
00139 53 push ebx
0013a ff 15 00 00 00
00 call DWORD PTR __imp__KeDelayExecutionThread@12
$L15129:
00140 8b 86 98 00 00
00 mov eax, DWORD PTR [esi+152]
00146 83 c0 05 add eax, 5
00149 50 push eax
0014a ff 15 00 00 00
00 call DWORD PTR __imp__READ_PORT_UCHAR@4
00150 a8 20 test al, 32 ; 00000020H
00152 74 e0 je SHORT $L14903
; 601 :
; 602 : }
; 603 :
; 604 : WRITE_TRANSMIT_HOLDING(
; 605 : extension->Controller,
; 606 : extension->SpecialChars.XonChar
; 607 : );
00154 8a 86 70 01 00
00 mov al, BYTE PTR [esi+368]
0015a 50 push eax
0015b ff b6 98 00 00
00 push DWORD PTR [esi+152]
00161 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--) {
00167 c7 45 fc 40 01
00 00 mov DWORD PTR _flushCount$[ebp], 320 ; 00000140H
$L14909:
; 615 : if ((READ_LINE_STATUS(extension->Controller) &
; 616 : (SERIAL_LSR_THRE | SERIAL_LSR_TEMT)) !=
; 617 : (SERIAL_LSR_THRE | SERIAL_LSR_TEMT)) {
0016e 8b 86 98 00 00
00 mov eax, DWORD PTR [esi+152]
00174 83 c0 05 add eax, 5
00177 50 push eax
00178 ff 15 00 00 00
00 call DWORD PTR __imp__READ_PORT_UCHAR@4
0017e 24 60 and al, 96 ; 00000060H
00180 3c 60 cmp al, 96 ; 00000060H
00182 74 11 je SHORT $L14913
; 618 :
; 619 : KeDelayExecutionThread(KernelMode, FALSE, &charTime);
00184 8d 45 ec lea eax, DWORD PTR _charTime$[ebp]
00187 50 push eax
00188 53 push ebx
00189 53 push ebx
0018a ff 15 00 00 00
00 call DWORD PTR __imp__KeDelayExecutionThread@12
00190 ff 4d fc dec DWORD PTR _flushCount$[ebp]
00193 75 d9 jne SHORT $L14909
$L14913:
; 620 : } else {
; 621 : break;
; 622 : }
; 623 : }
; 624 :
; 625 : if (flushCount == 0) {
00195 39 5d fc cmp DWORD PTR _flushCount$[ebp], ebx
00198 75 06 jne SHORT $L14915
; 626 : SerialMarkHardwareBroken(extension);
0019a 56 push esi
0019b e8 00 00 00 00 call _SerialMarkHardwareBroken@4
$L14915:
; 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;
001a0 53 push ebx
001a1 6a 0a push 10 ; 0000000aH
001a3 ff 75 f0 push DWORD PTR _charTime$[ebp+4]
001a6 ff 75 ec push DWORD PTR _charTime$[ebp]
001a9 e8 00 00 00 00 call __allmul
001ae 89 45 e4 mov DWORD PTR _tenCharDelay$[ebp], eax
; 637 :
; 638 : KeDelayExecutionThread(
; 639 : KernelMode,
; 640 : TRUE,
; 641 : &tenCharDelay
; 642 : );
001b1 8d 45 e4 lea eax, DWORD PTR _tenCharDelay$[ebp]
001b4 50 push eax
001b5 6a 01 push 1
001b7 53 push ebx
001b8 89 55 e8 mov DWORD PTR _tenCharDelay$[ebp+4], edx
001bb ff 15 00 00 00
00 call DWORD PTR __imp__KeDelayExecutionThread@12
; 643 :
; 644 : SerialClrDTR(extension);
001c1 56 push esi
001c2 e8 00 00 00 00 call _SerialClrDTR@4
; 645 :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -