📄 openclos.cod
字号:
0006d 68 00 00 00 00 push OFFSET FLAT:$SG14947
00072 e8 00 00 00 00 call _DbgPrint
00077 59 pop ecx
00078 59 pop ecx
00079 6a 00 push 0
0007b 68 96 01 00 00 push 406 ; 00000196H
00080 68 00 00 00 00 push OFFSET FLAT:$SG14950
00085 68 00 00 00 00 push OFFSET FLAT:$SG14951
0008a ff 15 00 00 00
00 call DWORD PTR __imp__RtlAssert@16
$L15322:
; 407 :
; 408 : //
; 409 : // Wait until all characters have been emptied out of the hardware.
; 410 : //
; 411 :
; 412 : while ((READ_LINE_STATUS(PDevExt->Controller) &
; 413 : (SERIAL_LSR_THRE | SERIAL_LSR_TEMT))
; 414 : != (SERIAL_LSR_THRE | SERIAL_LSR_TEMT)) {
00090 8b 7d 08 mov edi, DWORD PTR _PDevExt$[ebp]
00093 8b 35 00 00 00
00 mov esi, DWORD PTR __imp__READ_PORT_UCHAR@4
00099 eb 0d jmp SHORT $L15325
$L14954:
; 415 :
; 416 : KeDelayExecutionThread(KernelMode, FALSE, PDrainTime);
0009b ff 75 0c push DWORD PTR _PDrainTime$[ebp]
0009e 6a 00 push 0
000a0 6a 00 push 0
000a2 ff 15 00 00 00
00 call DWORD PTR __imp__KeDelayExecutionThread@12
$L15325:
000a8 8b 87 98 00 00
00 mov eax, DWORD PTR [edi+152]
000ae 83 c0 05 add eax, 5
000b1 50 push eax
000b2 ff d6 call esi
000b4 24 60 and al, 96 ; 00000060H
000b6 3c 60 cmp al, 96 ; 00000060H
000b8 75 e1 jne SHORT $L14954
000ba 5f pop edi
000bb 5e pop esi
; 417 : }
; 418 : }
000bc 5d pop ebp
000bd c2 08 00 ret 8
_SerialDrainUART@8 ENDP
PAGESRP0 ENDS
PUBLIC _SerialClose@8
PUBLIC _SerialGetCharTime@4
PUBLIC _SerialMarkClose@4
EXTRN __imp__WRITE_PORT_UCHAR@8:NEAR
EXTRN __imp__MmUnlockPagableImageSection@4:NEAR
EXTRN __allmul:NEAR
EXTRN __imp__KeWaitForSingleObject@20:NEAR
EXTRN _SerialMarkHardwareBroken@4:NEAR
EXTRN __imp__IoCancelIrp@4:NEAR
EXTRN _SerialDebugLogEntry@20:NEAR
EXTRN _SerialClrDTR@4:NEAR
EXTRN _SerialClrRTS@4:NEAR
EXTRN _SerialTurnOffBreak@4:NEAR
; COMDAT _SerialClose@8
PAGESER SEGMENT
$SG14976 DB 'SERIAL: Close prologue failed for: %x', 0aH, 00H
ORG $+1
$SG14989 DB 'f:\w2ddk\src\kernel\serial\openclos.c', 00H
ORG $+2
$SG14990 DB 'openCount == 0', 00H
ORG $+1
$SG14993 DB 'f:\w2ddk\src\kernel\serial\openclos.c', 00H
ORG $+2
$SG14994 DB 'extension->OpenCount == 1', 00H
ORG $+2
$SG15002 DB 'SERIAL: Close open count bad for: 0x%x', 0aH, 00H
$SG15015 DB '------: Count: %x Addr: 0x%x', 0aH, 00H
ORG $+1
$SG15030 DB 'SERIAL: Dispatch entry for: %x', 0aH, 00H
$SG15043 DB 'SERIAL: In SerialClose', 0aH, 00H
$SG15092 DB 'SERIAL: Complete Irp: %x', 0aH, 00H
ORG $+2
$SG15109 DB 'SERIAL: Drainging DPC''s: %x', 0aH, 00H
ORG $+3
$SG15123 DB 'SERIAL: DPC''s drained: %x', 0aH, 00H
ORG $+1
$SG15135 DB 'f:\w2ddk\src\kernel\serial\openclos.c', 00H
ORG $+2
$SG15136 DB 'openCount == 0', 00H
; Function compile flags: /Ogs
_DeviceObject$ = 8
_Irp$ = 12
_tenCharDelay$ = -28
_charTime$ = -20
_pendingDPCs$ = 8
_flushCount$ = -4
_SerialClose@8 PROC NEAR ; COMDAT
; 445 : {
001b3 55 push ebp
001b4 8b ec mov ebp, esp
001b6 83 ec 1c sub esp, 28 ; 0000001cH
; 446 :
; 447 : //
; 448 : // This "timer value" is used to wait 10 character times
; 449 : // after the hardware is empty before we actually "run down"
; 450 : // all of the flow control/break junk.
; 451 : //
; 452 : LARGE_INTEGER tenCharDelay;
; 453 :
; 454 : //
; 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;
001b9 8b 45 08 mov eax, DWORD PTR _DeviceObject$[ebp]
001bc 53 push ebx
001bd 56 push esi
001be 57 push edi
001bf 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);
001c2 8d 8e 54 05 00
00 lea ecx, DWORD PTR [esi+1364]
001c8 89 4d f8 mov DWORD PTR -8+[ebp], ecx
001cb 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) {
001d1 56 push esi
001d2 ff 75 0c push DWORD PTR _Irp$[ebp]
001d5 e8 00 00 00 00 call _SerialIRPPrologue@8
001da 8b f8 mov edi, eax
001dc 33 db xor ebx, ebx
001de 3b fb cmp edi, ebx
001e0 0f 84 80 00 00
00 je $L14969
; 493 : SerialDump(SERERRORS, ("SERIAL: Close prologue failed for: %x\n",Irp));
001e6 f6 05 03 00 00
00 40 test BYTE PTR _SerialDebugLevel+3, 64 ; 00000040H
001ed 74 0f je SHORT $L14971
001ef ff 75 0c push DWORD PTR _Irp$[ebp]
001f2 68 00 00 00 00 push OFFSET FLAT:$SG14976
001f7 e8 00 00 00 00 call _DbgPrint
001fc 59 pop ecx
001fd 59 pop ecx
$L14971:
; 494 : if (status == STATUS_DELETE_PENDING) {
001fe 81 ff 56 00 00
c0 cmp edi, -1073741738 ; c0000056H
00204 75 1e jne SHORT $L14984
; 495 : extension->BufferSize = 0;
; 496 : ExFreePool(extension->InterruptReadBuffer);
00206 8d be e8 00 00
00 lea edi, DWORD PTR [esi+232]
0020c 89 9e 04 01 00
00 mov DWORD PTR [esi+260], ebx
00212 ff 37 push DWORD PTR [edi]
00214 ff 15 00 00 00
00 call DWORD PTR __imp__ExFreePool@4
; 497 : extension->InterruptReadBuffer = NULL;
; 498 : status = Irp->IoStatus.Status = STATUS_SUCCESS;
0021a 8b 45 0c mov eax, DWORD PTR _Irp$[ebp]
0021d 89 1f mov DWORD PTR [edi], ebx
0021f 33 ff xor edi, edi
00221 89 58 18 mov DWORD PTR [eax+24], ebx
$L14984:
; 499 : }
; 500 :
; 501 : SerialCompleteRequest(extension, Irp, IO_NO_INCREMENT);
00224 8b 4d 0c mov ecx, DWORD PTR _Irp$[ebp]
00227 32 d2 xor dl, dl
00229 ff 15 00 00 00
00 call DWORD PTR __imp_@IofCompleteRequest@8
0022f 56 push esi
00230 e8 00 00 00 00 call _SerialIRPEpilogue@4
; 502 : openCount = InterlockedDecrement(&extension->OpenCount);
00235 8d 8e e8 04 00
00 lea ecx, DWORD PTR [esi+1256]
0023b ff 15 00 00 00
00 call DWORD PTR __imp_@InterlockedDecrement@4
; 503 : ASSERT(openCount == 0);
00241 85 c0 test eax, eax
00243 74 16 je SHORT $L14987
00245 53 push ebx
00246 68 f7 01 00 00 push 503 ; 000001f7H
0024b 68 00 00 00 00 push OFFSET FLAT:$SG14989
00250 68 00 00 00 00 push OFFSET FLAT:$SG14990
00255 ff 15 00 00 00
00 call DWORD PTR __imp__RtlAssert@16
$L14987:
; 504 : ExReleaseFastMutex(&extension->CloseMutex);
0025b 8b 4d f8 mov ecx, DWORD PTR -8+[ebp]
0025e ff 15 00 00 00
00 call DWORD PTR __imp_@ExReleaseFastMutex@4
; 505 : return status;
00264 eb 7f jmp SHORT $L15358
$L14969:
; 506 : }
; 507 :
; 508 : ASSERT(extension->OpenCount == 1);
00266 8d be e8 04 00
00 lea edi, DWORD PTR [esi+1256]
0026c 89 7d f4 mov DWORD PTR -12+[ebp], edi
0026f 83 3f 01 cmp DWORD PTR [edi], 1
00272 74 78 je SHORT $L15024
00274 53 push ebx
00275 68 fc 01 00 00 push 508 ; 000001fcH
0027a 68 00 00 00 00 push OFFSET FLAT:$SG14993
0027f 68 00 00 00 00 push OFFSET FLAT:$SG14994
00284 ff 15 00 00 00
00 call DWORD PTR __imp__RtlAssert@16
; 509 :
; 510 : if (extension->OpenCount != 1) {
0028a 83 3f 01 cmp DWORD PTR [edi], 1
0028d 74 5d je SHORT $L15024
; 511 : SerialDump(SERERRORS, ("SERIAL: Close open count bad for: 0x%x\n",Irp));
0028f bb 00 00 00 40 mov ebx, 1073741824 ; 40000000H
00294 85 1d 00 00 00
00 test DWORD PTR _SerialDebugLevel, ebx
0029a 74 27 je SHORT $L15010
0029c ff 75 0c push DWORD PTR _Irp$[ebp]
0029f 68 00 00 00 00 push OFFSET FLAT:$SG15002
002a4 e8 00 00 00 00 call _DbgPrint
; 512 : SerialDump(SERERRORS, ("------: Count: %x Addr: 0x%x\n",
; 513 : extension->OpenCount, &extension->OpenCount));
002a9 85 1d 00 00 00
00 test DWORD PTR _SerialDebugLevel, ebx
002af 59 pop ecx
002b0 59 pop ecx
002b1 74 10 je SHORT $L15010
002b3 57 push edi
002b4 ff 37 push DWORD PTR [edi]
002b6 68 00 00 00 00 push OFFSET FLAT:$SG15015
002bb e8 00 00 00 00 call _DbgPrint
002c0 83 c4 0c add esp, 12 ; 0000000cH
$L15010:
; 514 : ExReleaseFastMutex(&extension->CloseMutex);
002c3 8b 4d f8 mov ecx, DWORD PTR -8+[ebp]
002c6 ff 15 00 00 00
00 call DWORD PTR __imp_@ExReleaseFastMutex@4
; 515 : Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
002cc 8b 4d 0c mov ecx, DWORD PTR _Irp$[ebp]
002cf bf 10 00 00 c0 mov edi, -1073741808 ; c0000010H
; 516 : SerialCompleteRequest(extension, Irp, IO_NO_INCREMENT);
002d4 32 d2 xor dl, dl
002d6 89 79 18 mov DWORD PTR [ecx+24], edi
002d9 ff 15 00 00 00
00 call DWORD PTR __imp_@IofCompleteRequest@8
002df 56 push esi
002e0 e8 00 00 00 00 call _SerialIRPEpilogue@4
$L15358:
; 517 : return STATUS_INVALID_DEVICE_REQUEST;
002e5 8b c7 mov eax, edi
002e7 e9 b1 02 00 00 jmp $L14960
$L15024:
; 518 : }
; 519 :
; 520 : SerialDump(
; 521 : SERIRPPATH,
; 522 : ("SERIAL: Dispatch entry for: %x\n",Irp)
; 523 : );
002ec f6 05 00 00 00
00 20 test BYTE PTR _SerialDebugLevel, 32 ; 00000020H
002f3 74 0f je SHORT $L15025
002f5 ff 75 0c push DWORD PTR _Irp$[ebp]
002f8 68 00 00 00 00 push OFFSET FLAT:$SG15030
002fd e8 00 00 00 00 call _DbgPrint
00302 59 pop ecx
00303 59 pop ecx
$L15025:
; 524 : SerialDump(
; 525 : SERDIAG3,
; 526 : ("SERIAL: In SerialClose\n")
; 527 : );
00304 f6 05 00 00 00
00 04 test BYTE PTR _SerialDebugLevel, 4
0030b 74 0b je SHORT $L15038
0030d 68 00 00 00 00 push OFFSET FLAT:$SG15043
00312 e8 00 00 00 00 call _DbgPrint
00317 59 pop ecx
$L15038:
; 528 :
; 529 : charTime.QuadPart = -SerialGetCharTime(extension).QuadPart;
00318 56 push esi
00319 e8 00 00 00 00 call _SerialGetCharTime@4
0031e f7 d8 neg eax
00320 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 : );
00322 56 push esi
00323 f7 da neg edx
00325 68 00 00 00 00 push OFFSET FLAT:_SerialTurnOffBreak@4
0032a 89 45 ec mov DWORD PTR _charTime$[ebp], eax
0032d 89 55 f0 mov DWORD PTR _charTime$[ebp+4], edx
00330 ff b6 a0 00 00
00 push DWORD PTR [esi+160]
00336 88 9e 9d 01 00
00 mov BYTE PTR [esi+413], bl
0033c 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--) {
00342 c7 45 fc 40 01
00 00 mov DWORD PTR _flushCount$[ebp], 320 ; 00000140H
$L15050:
; 555 : if ((READ_LINE_STATUS(extension->Controller) &
; 556 : (SERIAL_LSR_THRE | SERIAL_LSR_TEMT)) !=
; 557 : (SERIAL_LSR_THRE | SERIAL_LSR_TEMT)) {
00349 8b 86 98 00 00
00 mov eax, DWORD PTR [esi+152]
0034f 83 c0 05 add eax, 5
00352 50 push eax
00353 ff 15 00 00 00
00 call DWORD PTR __imp__READ_PORT_UCHAR@4
00359 24 60 and al, 96 ; 00000060H
0035b 3c 60 cmp al, 96 ; 00000060H
0035d 74 11 je SHORT $L15054
; 558 :
; 559 : KeDelayExecutionThread(KernelMode, FALSE, &charTime);
0035f 8d 45 ec lea eax, DWORD PTR _charTime$[ebp]
00362 50 push eax
00363 53 push ebx
00364 53 push ebx
00365 ff 15 00 00 00
00 call DWORD PTR __imp__KeDelayExecutionThread@12
0036b ff 4d fc dec DWORD PTR _flushCount$[ebp]
0036e 75 d9 jne SHORT $L15050
$L15054:
; 560 : } else {
; 561 : break;
; 562 : }
; 563 : }
; 564 :
; 565 : if (flushCount == 0) {
00370 39 5d fc cmp DWORD PTR _flushCount$[ebp], ebx
00373 75 06 jne SHORT $L15056
; 566 : SerialMarkHardwareBroken(extension);
00375 56 push esi
00376 e8 00 00 00 00 call _SerialMarkHardwareBroken@4
$L15056:
; 567 : }
; 568 :
; 569 : //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -