📄 write.cod
字号:
; 204 : NTSTATUS FirstStatus;
; 205 :
; 206 : SERIAL_LOCKED_PAGED_CODE();
0013d 8b 35 00 00 00
00 mov esi, DWORD PTR __imp__KeGetCurrentIrql@0
00143 57 push edi
00144 ff d6 call esi
00146 3c 01 cmp al, 1
00148 76 32 jbe SHORT $L14954
0014a 83 3d 14 00 00
00 00 cmp DWORD PTR _SerialGlobals+20, 0
00151 75 29 jne SHORT $L14954
00153 ff d6 call esi
00155 0f b6 c0 movzx eax, al
00158 50 push eax
00159 68 00 00 00 00 push OFFSET FLAT:$SG14949
0015e e8 00 00 00 00 call _DbgPrint
00163 59 pop ecx
00164 59 pop ecx
00165 6a 00 push 0
00167 68 ce 00 00 00 push 206 ; 000000ceH
0016c 68 00 00 00 00 push OFFSET FLAT:$SG14952
00171 68 00 00 00 00 push OFFSET FLAT:$SG14953
00176 ff 15 00 00 00
00 call DWORD PTR __imp__RtlAssert@16
$L14954:
; 207 :
; 208 : SerialDump(SERTRACECALLS, ("SERIAL: SerialStartWrite\n"));
0017c f6 05 00 00 00
00 40 test BYTE PTR _SerialDebugLevel, 64 ; 00000040H
00183 74 0b je SHORT $L14955
00185 68 00 00 00 00 push OFFSET FLAT:$SG14960
0018a e8 00 00 00 00 call _DbgPrint
0018f 59 pop ecx
$L14955:
00190 8b 5d 08 mov ebx, DWORD PTR _Extension$[ebp]
$L14967:
; 209 :
; 210 : do {
; 211 :
; 212 : //
; 213 : // If there is an xoff counter then complete it.
; 214 : //
; 215 :
; 216 : IoAcquireCancelSpinLock(&OldIrql);
00193 8d 45 fb lea eax, DWORD PTR _OldIrql$[ebp]
00196 50 push eax
00197 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) {
0019d 8d bb dc 00 00
00 lea edi, DWORD PTR [ebx+220]
001a3 8b 07 mov eax, DWORD PTR [edi]
001a5 85 c0 test eax, eax
001a7 74 54 je SHORT $L14970
; 230 :
; 231 : if (SERIAL_REFERENCE_COUNT(Extension->CurrentXoffIrp)) {
001a9 8b 70 60 mov esi, DWORD PTR [eax+96]
001ac 33 c0 xor eax, eax
001ae 39 46 10 cmp DWORD PTR [esi+16], eax
001b1 74 4a je SHORT $L14970
; 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 : );
001b3 f6 46 10 10 test BYTE PTR [esi+16], 16 ; 00000010H
001b7 74 18 je SHORT $L14979
001b9 50 push eax
001ba 68 f3 00 00 00 push 243 ; 000000f3H
001bf 68 00 00 00 00 push OFFSET FLAT:$SG14981
001c4 68 00 00 00 00 push OFFSET FLAT:$SG14982
001c9 ff 15 00 00 00
00 call DWORD PTR __imp__RtlAssert@16
001cf 33 c0 xor eax, eax
$L14979:
001d1 83 4e 10 10 or DWORD PTR [esi+16], 16 ; 00000010H
; 244 :
; 245 : Extension->CurrentXoffIrp->IoStatus.Information = 0;
001d5 8b 0f mov ecx, DWORD PTR [edi]
; 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 : );
001d7 6a 10 push 16 ; 00000010H
001d9 50 push eax
001da 89 41 1c mov DWORD PTR [ecx+28], eax
001dd 8d 8b 50 04 00
00 lea ecx, DWORD PTR [ebx+1104]
001e3 50 push eax
001e4 51 push ecx
001e5 50 push eax
001e6 50 push eax
001e7 57 push edi
001e8 68 08 00 00 40 push 1073741832 ; 40000008H
001ed ff 75 fb push DWORD PTR _OldIrql$[ebp]
001f0 68 00 00 00 00 push OFFSET FLAT:_SerialGrabXoffFromIsr@4
001f5 53 push ebx
001f6 e8 00 00 00 00 call _SerialTryToCompleteCurrent@44
; 265 :
; 266 : } else {
001fb eb 09 jmp SHORT $L14989
$L14970:
; 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);
001fd ff 75 fb push DWORD PTR _OldIrql$[ebp]
00200 ff 15 00 00 00
00 call DWORD PTR __imp__IoReleaseCancelSpinLock@4
$L14989:
; 281 :
; 282 : }
; 283 :
; 284 : UseATimer = FALSE;
00206 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 : );
0020a 8d 8b e4 01 00
00 lea ecx, DWORD PTR [ebx+484]
00210 ff 15 00 00 00
00 call DWORD PTR __imp_@KfAcquireSpinLock@4
; 298 :
; 299 : Timeouts = Extension->Timeouts;
00216 6a 05 push 5
00218 8d b3 58 01 00
00 lea esi, DWORD PTR [ebx+344]
0021e 59 pop ecx
0021f 8d 7d d4 lea edi, DWORD PTR _Timeouts$[ebp]
00222 f3 a5 rep movsd
; 300 :
; 301 : KeReleaseSpinLock(
; 302 : &Extension->ControlLock,
; 303 : OldIrql
; 304 : );
00224 8a d0 mov dl, al
00226 8d 8b e4 01 00
00 lea ecx, DWORD PTR [ebx+484]
0022c 88 45 fb mov BYTE PTR _OldIrql$[ebp], al
0022f ff 15 00 00 00
00 call DWORD PTR __imp_@KfReleaseSpinLock@8
; 305 :
; 306 : if (Timeouts.WriteTotalTimeoutConstant ||
; 307 : Timeouts.WriteTotalTimeoutMultiplier) {
00235 33 ff xor edi, edi
00237 39 7d e4 cmp DWORD PTR _Timeouts$[ebp+16], edi
0023a 75 05 jne SHORT $L14991
0023c 39 7d e0 cmp DWORD PTR _Timeouts$[ebp+12], edi
0023f 74 38 je SHORT $L14990
$L14991:
; 308 :
; 309 : PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(
; 310 : Extension->CurrentWriteIrp
; 311 : );
00241 8b 83 c8 00 00
00 mov eax, DWORD PTR [ebx+200]
; 312 : UseATimer = TRUE;
00247 c6 45 0b 01 mov BYTE PTR _UseATimer$[ebp], 1
0024b 8b 40 60 mov eax, DWORD PTR [eax+96]
; 313 :
; 314 : //
; 315 : // We have some timer values to calculate.
; 316 : //
; 317 : // Take care, we might have an xoff counter masquerading
; 318 : // as a write.
; 319 : //
; 320 :
; 321 : TotalTime.QuadPart =
; 322 : ((LONGLONG)((UInt32x32To64(
; 323 : (IrpSp->MajorFunction == IRP_MJ_WRITE)?
; 324 : (IrpSp->Parameters.Write.Length):
; 325 : (1),
; 326 : Timeouts.WriteTotalTimeoutMultiplier
; 327 : )
; 328 : + Timeouts.WriteTotalTimeoutConstant)))
; 329 : * -10000;
0024e 80 38 04 cmp BYTE PTR [eax], 4
00251 75 05 jne SHORT $L15459
00253 8b 40 04 mov eax, DWORD PTR [eax+4]
00256 eb 03 jmp SHORT $L15460
$L15459:
00258 33 c0 xor eax, eax
0025a 40 inc eax
$L15460:
0025b f7 65 e0 mul DWORD PTR _Timeouts$[ebp+12]
0025e 33 c9 xor ecx, ecx
00260 03 45 e4 add eax, DWORD PTR _Timeouts$[ebp+16]
00263 6a ff push -1
00265 68 f0 d8 ff ff push -10000 ; ffffd8f0H
0026a 13 d1 adc edx, ecx
0026c 52 push edx
0026d 50 push eax
0026e e8 00 00 00 00 call __allmul
00273 89 45 e8 mov DWORD PTR _TotalTime$[ebp], eax
00276 89 55 ec mov DWORD PTR _TotalTime$[ebp+4], edx
$L14990:
; 330 :
; 331 : }
; 332 :
; 333 : //
; 334 : // The irp may be going to the isr shortly. Now
; 335 : // is a good time to initialize its reference counts.
; 336 : //
; 337 :
; 338 : SERIAL_INIT_REFERENCE(Extension->CurrentWriteIrp);
00279 8d b3 c8 00 00
00 lea esi, DWORD PTR [ebx+200]
0027f 8b 06 mov eax, DWORD PTR [esi]
00281 8b 40 60 mov eax, DWORD PTR [eax+96]
00284 89 78 10 mov DWORD PTR [eax+16], edi
; 339 :
; 340 : //
; 341 : // We need to see if this irp should be canceled.
; 342 : //
; 343 :
; 344 : IoAcquireCancelSpinLock(&OldIrql);
00287 8d 45 fb lea eax, DWORD PTR _OldIrql$[ebp]
0028a 50 push eax
0028b ff 15 00 00 00
00 call DWORD PTR __imp__IoAcquireCancelSpinLock@4
; 345 : if (Extension->CurrentWriteIrp->Cancel) {
00291 8b 06 mov eax, DWORD PTR [esi]
00293 80 78 24 00 cmp BYTE PTR [eax+36], 0
00297 74 42 je SHORT $L15005
; 346 :
; 347 : IoReleaseCancelSpinLock(OldIrql);
00299 ff 75 fb push DWORD PTR _OldIrql$[ebp]
0029c ff 15 00 00 00
00 call DWORD PTR __imp__IoReleaseCancelSpinLock@4
; 348 : Extension->CurrentWriteIrp->IoStatus.Status = STATUS_CANCELLED;
002a2 8b 0e mov ecx, DWORD PTR [esi]
; 349 :
; 350 : if (!SetFirstStatus) {
002a4 80 7d ff 00 cmp BYTE PTR _SetFirstStatus$[ebp], 0
002a8 b8 20 01 00 c0 mov eax, -1073741536 ; c0000120H
002ad 89 41 18 mov DWORD PTR [ecx+24], eax
002b0 75 07 jne SHORT $L15007
; 351 :
; 352 : FirstStatus = STATUS_CANCELLED;
002b2 89 45 f4 mov DWORD PTR _FirstStatus$[ebp], eax
; 353 : SetFirstStatus = TRUE;
002b5 c6 45 ff 01 mov BYTE PTR _SetFirstStatus$[ebp], 1
$L15007:
; 422 : break;
; 423 :
; 424 : }
; 425 :
; 426 : //
; 427 : // Well the write was canceled before we could start it up.
; 428 : // Try to get another.
; 429 : //
; 430 :
; 431 : SerialGetNextWrite(
; 432 : &Extension->CurrentWriteIrp,
; 433 : &Extension->WriteQueue,
; 434 : &NewIrp,
; 435 : TRUE,
; 436 : Extension
; 437 : );
002b9 53 push ebx
002ba 8d 45 f0 lea eax, DWORD PTR _NewIrp$[ebp]
002bd 6a 01 push 1
002bf 50 push eax
002c0 8d 83 ac 00 00
00 lea eax, DWORD PTR [ebx+172]
002c6 50 push eax
002c7 56 push esi
002c8 e8 00 00 00 00 call _SerialGetNextWrite@20
; 438 :
; 439 : } while (NewIrp);
002cd 39 7d f0 cmp DWORD PTR _NewIrp$[ebp], edi
002d0 0f 85 bd fe ff
ff jne $L14967
002d6 e9 af 00 00 00 jmp $L14969
$L15005:
; 354 :
; 355 : }
; 356 :
; 357 : } else {
; 358 :
; 359 : if (!SetFirstStatus) {
002db 80 7d ff 00 cmp BYTE PTR _SetFirstStatus$[ebp], 0
002df 75 10 jne SHORT $L15010
; 360 :
; 361 : //
; 362 : // If we haven't set our first status, then
; 363 : // this is the only irp that could have possibly
; 364 : // not been on the queue. (It could have been
; 365 : // on the queue if this routine is being invoked
; 366 : // from the completion routine.) Since this
; 367 : // irp might never have been on the queue we
; 368 : // should mark it as pending.
; 369 : //
; 370 :
; 371 : IoMarkIrpPending(Extension->CurrentWriteIrp);
002e1 8b 06 mov eax, DWORD PTR [esi]
; 372 : SetFirstStatus = TRUE;
; 373 : FirstStatus = STATUS_PENDING;
002e3 c7 45 f4 03 01
00 00 mov DWORD PTR _FirstStatus$[ebp], 259 ; 00000103H
002ea 8b 40 60 mov eax, DWORD PTR [eax+96]
002ed 80 48 03 01 or BYTE PTR [eax+3], 1
$L15010:
; 374 :
; 375 : }
; 376 :
; 377 : //
; 378 : // We give the irp to to the isr to write out.
; 379 : // We set a cancel routine that knows how to
; 380 : // grab the current write away from the isr.
; 381 : //
; 382 : // Since the cancel routine has an implicit reference
; 383 : // to this irp up the reference count.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -