📄 write.cod
字号:
; Listing generated by Microsoft (R) Optimizing Compiler Version 12.00.9044.0
TITLE F:\W2DDK\src\kernel\serial\write.c
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
$$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS ENDS
$$TYPES SEGMENT BYTE USE32 'DEBTYP'
$$TYPES ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
PAGESER SEGMENT PARA USE32 PUBLIC ''
PAGESER ENDS
; COMDAT _RtlConvertLongToLargeInteger@4
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _SerialWrite@8
PAGESER SEGMENT PARA USE32 PUBLIC ''
PAGESER ENDS
; COMDAT _SerialStartWrite@4
PAGESER SEGMENT PARA USE32 PUBLIC ''
PAGESER ENDS
; COMDAT _SerialGetNextWrite@20
PAGESER SEGMENT PARA USE32 PUBLIC ''
PAGESER ENDS
; COMDAT _SerialCompleteWrite@16
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _SerialProcessEmptyTransmit@4
PAGESER SEGMENT PARA USE32 PUBLIC ''
PAGESER ENDS
; COMDAT _SerialGiveWriteToIsr@4
PAGESER SEGMENT PARA USE32 PUBLIC ''
PAGESER ENDS
; COMDAT _SerialCancelCurrentWrite@8
PAGESER SEGMENT PARA USE32 PUBLIC ''
PAGESER ENDS
; COMDAT _SerialWriteTimeout@16
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _SerialGrabWriteFromIsr@4
PAGESER SEGMENT PARA USE32 PUBLIC ''
PAGESER ENDS
; COMDAT _SerialGrabXoffFromIsr@4
PAGESER SEGMENT PARA USE32 PUBLIC ''
PAGESER ENDS
; COMDAT _SerialCompleteXoff@16
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _SerialTimeoutXoff@16
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _SerialCancelCurrentXoff@8
PAGESER SEGMENT PARA USE32 PUBLIC ''
PAGESER ENDS
; COMDAT _SerialGiveXoffToIsr@4
PAGESER SEGMENT PARA USE32 PUBLIC ''
PAGESER ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif
INCLUDELIB LIBC
INCLUDELIB OLDNAMES
PUBLIC _SerialWrite@8
PUBLIC _SerialStartWrite@4
EXTRN _SerialIRPPrologue@8:NEAR
EXTRN _SerialIRPEpilogue@4:NEAR
EXTRN __imp_@IofCompleteRequest@8:NEAR
EXTRN _SerialStartOrQueue@20:NEAR
EXTRN _SerialCompleteIfError@8:NEAR
; Function compile flags: /Ogsy
; File f:\w2ddk\src\kernel\serial\write.c
; COMDAT _SerialWrite@8
PAGESER SEGMENT
_DeviceObject$ = 8
_Irp$ = 12
_SerialWrite@8 PROC NEAR ; COMDAT
; 100 : {
00000 53 push ebx
; 101 :
; 102 : PSERIAL_DEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
00001 8b 5c 24 08 mov ebx, DWORD PTR _DeviceObject$[esp]
00005 56 push esi
; 103 : NTSTATUS status;
; 104 :
; 105 : SERIAL_LOCKED_PAGED_CODE();
; 106 :
; 107 : SerialDump(SERTRACECALLS, ("Entering SerialWrite\n"));
; 108 :
; 109 : if ((status = SerialIRPPrologue(Irp, Extension)) != STATUS_SUCCESS) {
00006 8b 74 24 10 mov esi, DWORD PTR _Irp$[esp+4]
0000a 57 push edi
0000b 8b 7b 28 mov edi, DWORD PTR [ebx+40]
0000e 57 push edi
0000f 56 push esi
00010 e8 00 00 00 00 call _SerialIRPPrologue@8
00015 85 c0 test eax, eax
00017 74 04 je SHORT $L14802
00019 8b d8 mov ebx, eax
0001b eb 3e jmp SHORT $L15164
$L14802:
; 110 : SerialCompleteRequest(Extension, Irp, IO_NO_INCREMENT);
; 111 : SerialDump(SERTRACECALLS, ("Leaving SerialWrite (1)\n"));
; 112 : return status;
; 113 : }
; 114 :
; 115 : SerialDump(
; 116 : SERIRPPATH,
; 117 : ("SERIAL: Dispatch entry for: %x\n",Irp)
; 118 : );
; 119 : if (SerialCompleteIfError(
; 120 : DeviceObject,
; 121 : Irp
; 122 : ) != STATUS_SUCCESS) {
0001d 56 push esi
0001e 53 push ebx
0001f e8 00 00 00 00 call _SerialCompleteIfError@8
00024 85 c0 test eax, eax
00026 74 07 je SHORT $L14806
; 123 :
; 124 : SerialDump(SERTRACECALLS, ("Leaving SerialWrite (2)\n"));
; 125 :
; 126 : return STATUS_CANCELLED;
00028 b8 20 01 00 c0 mov eax, -1073741536 ; c0000120H
0002d eb 3e jmp SHORT $L14815
$L14806:
; 127 :
; 128 : }
; 129 :
; 130 : Irp->IoStatus.Information = 0L;
; 131 :
; 132 : //
; 133 : // Quick check for a zero length write. If it is zero length
; 134 : // then we are already done!
; 135 : //
; 136 :
; 137 : if (IoGetCurrentIrpStackLocation(Irp)->Parameters.Write.Length) {
0002f 8b 46 60 mov eax, DWORD PTR [esi+96]
00032 33 db xor ebx, ebx
00034 89 5e 1c mov DWORD PTR [esi+28], ebx
00037 39 58 04 cmp DWORD PTR [eax+4], ebx
0003a 74 1c je SHORT $L14811
; 138 :
; 139 : //
; 140 : // Well it looks like we actually have to do some
; 141 : // work. Put the write on the queue so that we can
; 142 : // process it when our previous writes are done.
; 143 : //
; 144 :
; 145 :
; 146 : SerialDump(SERTRACECALLS, ("Leaving SerialWrite (3)\n"));
; 147 :
; 148 : return SerialStartOrQueue(
; 149 : Extension,
; 150 : Irp,
; 151 : &Extension->WriteQueue,
; 152 : &Extension->CurrentWriteIrp,
; 153 : SerialStartWrite
; 154 : );
0003c 8d 87 c8 00 00
00 lea eax, DWORD PTR [edi+200]
00042 68 00 00 00 00 push OFFSET FLAT:_SerialStartWrite@4
00047 50 push eax
00048 8d 87 ac 00 00
00 lea eax, DWORD PTR [edi+172]
0004e 50 push eax
0004f 56 push esi
00050 57 push edi
00051 e8 00 00 00 00 call _SerialStartOrQueue@20
00056 eb 15 jmp SHORT $L14815
$L14811:
; 155 :
; 156 : } else {
; 157 :
; 158 : Irp->IoStatus.Status = STATUS_SUCCESS;
00058 89 5e 18 mov DWORD PTR [esi+24], ebx
$L15164:
; 159 : SerialDump(
; 160 : SERIRPPATH,
; 161 : ("SERIAL: Complete Irp: %x\n",Irp)
; 162 : );
; 163 : SerialCompleteRequest(Extension, Irp, 0);
0005b 32 d2 xor dl, dl
0005d 8b ce mov ecx, esi
0005f ff 15 00 00 00
00 call DWORD PTR __imp_@IofCompleteRequest@8
00065 57 push edi
00066 e8 00 00 00 00 call _SerialIRPEpilogue@4
; 164 :
; 165 : SerialDump(SERTRACECALLS, ("Leaving SerialWrite (4)\n"));
; 166 : return STATUS_SUCCESS;
0006b 8b c3 mov eax, ebx
$L14815:
0006d 5f pop edi
0006e 5e pop esi
0006f 5b pop ebx
; 167 :
; 168 : }
; 169 :
; 170 : }
00070 c2 08 00 ret 8
_SerialWrite@8 ENDP
PAGESER ENDS
PUBLIC _SerialGiveWriteToIsr@4
PUBLIC _SerialCancelCurrentWrite@8
PUBLIC _SerialGrabXoffFromIsr@4
PUBLIC _SerialGetNextWrite@20
EXTRN __imp__KeSynchronizeExecution@12:NEAR
EXTRN __imp_@InterlockedExchange@8:NEAR
EXTRN __imp_@KfAcquireSpinLock@4:NEAR
EXTRN __imp_@KfReleaseSpinLock@8:NEAR
EXTRN __imp__IoAcquireCancelSpinLock@4:NEAR
EXTRN _SerialSetTimer@20:NEAR
EXTRN __imp__IoReleaseCancelSpinLock@4:NEAR
EXTRN _SerialTryToCompleteCurrent@44:NEAR
EXTRN __allmul:NEAR
; Function compile flags: /Ogsy
; COMDAT _SerialStartWrite@4
PAGESER SEGMENT
_Extension$ = 8
_NewIrp$ = -16
_OldIrql$ = -5
_TotalTime$ = -24
_UseATimer$ = 11
_Timeouts$ = -44
_SetFirstStatus$ = -1
_FirstStatus$ = -12
_SerialStartWrite@4 PROC NEAR ; COMDAT
; 196 : {
00000 55 push ebp
00001 8b ec mov ebp, esp
00003 83 ec 2c sub esp, 44 ; 0000002cH
; 197 :
; 198 : PIRP NewIrp;
; 199 : KIRQL OldIrql;
; 200 : LARGE_INTEGER TotalTime;
; 201 : BOOLEAN UseATimer;
; 202 : SERIAL_TIMEOUTS Timeouts;
; 203 : BOOLEAN SetFirstStatus = FALSE;
00006 80 65 ff 00 and BYTE PTR _SetFirstStatus$[ebp], 0
0000a 53 push ebx
0000b 8b 5d 08 mov ebx, DWORD PTR _Extension$[ebp]
0000e 56 push esi
0000f 57 push edi
$L14837:
; 204 : NTSTATUS FirstStatus;
; 205 :
; 206 : SERIAL_LOCKED_PAGED_CODE();
; 207 :
; 208 : SerialDump(SERTRACECALLS, ("SERIAL: SerialStartWrite\n"));
; 209 :
; 210 : do {
; 211 :
; 212 : //
; 213 : // If there is an xoff counter then complete it.
; 214 : //
; 215 :
; 216 : IoAcquireCancelSpinLock(&OldIrql);
00010 8d 45 fb lea eax, DWORD PTR _OldIrql$[ebp]
00013 50 push eax
00014 ff 15 00 00 00
00 call DWORD PTR __imp__IoAcquireCancelSpinLock@4
; 217 :
; 218 : //
; 219 : // We see if there is a actually an Xoff counter irp.
; 220 : //
; 221 : // If there is, we put the write irp back on the head
; 222 : // of the write list. We then kill the xoff counter.
; 223 : // The xoff counter killing code will actually make the
; 224 : // xoff counter back into the current write irp, and
; 225 : // in the course of completing the xoff (which is now
; 226 : // the current write) we will restart this irp.
; 227 : //
; 228 :
; 229 : if (Extension->CurrentXoffIrp) {
0001a 8d 8b dc 00 00
00 lea ecx, DWORD PTR [ebx+220]
00020 33 d2 xor edx, edx
00022 8b 01 mov eax, DWORD PTR [ecx]
00024 3b c2 cmp eax, edx
00026 74 34 je SHORT $L14840
; 230 :
; 231 : if (SERIAL_REFERENCE_COUNT(Extension->CurrentXoffIrp)) {
00028 8b 40 60 mov eax, DWORD PTR [eax+96]
0002b 39 50 10 cmp DWORD PTR [eax+16], edx
0002e 74 2c je SHORT $L14840
; 232 :
; 233 : //
; 234 : // The reference count is non-zero. This implies that
; 235 : // the xoff irp has not made it through the completion
; 236 : // path yet. We will increment the reference count
; 237 : // and attempt to complete it ourseleves.
; 238 : //
; 239 :
; 240 : SERIAL_SET_REFERENCE(
; 241 : Extension->CurrentXoffIrp,
; 242 : SERIAL_REF_XOFF_REF
; 243 : );
00030 83 48 10 10 or DWORD PTR [eax+16], 16 ; 00000010H
; 244 :
; 245 : Extension->CurrentXoffIrp->IoStatus.Information = 0;
00034 8b 01 mov eax, DWORD PTR [ecx]
; 246 :
; 247 : //
; 248 : // The following call will actually release the
; 249 : // cancel spin lock.
; 250 : //
; 251 :
; 252 : SerialTryToCompleteCurrent(
; 253 : Extension,
; 254 : SerialGrabXoffFromIsr,
; 255 : OldIrql,
; 256 : STATUS_SERIAL_MORE_WRITES,
; 257 : &Extension->CurrentXoffIrp,
; 258 : NULL,
; 259 : NULL,
; 260 : &Extension->XoffCountTimer,
; 261 : NULL,
; 262 : NULL,
; 263 : SERIAL_REF_XOFF_REF
; 264 : );
00036 6a 10 push 16 ; 00000010H
00038 52 push edx
00039 89 50 1c mov DWORD PTR [eax+28], edx
0003c 8d 83 50 04 00
00 lea eax, DWORD PTR [ebx+1104]
00042 52 push edx
00043 50 push eax
00044 52 push edx
00045 52 push edx
00046 51 push ecx
00047 68 08 00 00 40 push 1073741832 ; 40000008H
0004c ff 75 fb push DWORD PTR _OldIrql$[ebp]
0004f 68 00 00 00 00 push OFFSET FLAT:_SerialGrabXoffFromIsr@4
00054 53 push ebx
00055 e8 00 00 00 00 call _SerialTryToCompleteCurrent@44
; 265 :
; 266 : } else {
0005a eb 09 jmp SHORT $L14855
$L14840:
; 267 :
; 268 : //
; 269 : // The irp is well on its way to being finished.
; 270 : // We can let the regular completion code do the
; 271 : // work. Just release the spin lock.
; 272 : //
; 273 :
; 274 : IoReleaseCancelSpinLock(OldIrql);
; 275 :
; 276 : }
; 277 :
; 278 : } else {
; 279 :
; 280 : IoReleaseCancelSpinLock(OldIrql);
0005c ff 75 fb push DWORD PTR _OldIrql$[ebp]
0005f ff 15 00 00 00
00 call DWORD PTR __imp__IoReleaseCancelSpinLock@4
$L14855:
; 281 :
; 282 : }
; 283 :
; 284 : UseATimer = FALSE;
00065 80 65 0b 00 and BYTE PTR _UseATimer$[ebp], 0
; 285 :
; 286 : //
; 287 : // Calculate the timeout value needed for the
; 288 : // request. Note that the values stored in the
; 289 : // timeout record are in milliseconds. Note that
; 290 : // if the timeout values are zero then we won't start
; 291 : // the timer.
; 292 : //
; 293 :
; 294 : KeAcquireSpinLock(
; 295 : &Extension->ControlLock,
; 296 : &OldIrql
; 297 : );
00069 8d 8b e4 01 00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -