📄 read.cod
字号:
0004b 8d 83 b0 03 00
00 lea eax, DWORD PTR [ebx+944]
00051 50 push eax
00052 e8 00 00 00 00 call _SerialCancelTimer@8
; 307 : SerialCancelTimer(&Extension->ReadRequestIntervalTimer, Extension);
00057 8d 83 d8 03 00
00 lea eax, DWORD PTR [ebx+984]
0005d 53 push ebx
0005e 50 push eax
0005f e8 00 00 00 00 call _SerialCancelTimer@8
; 308 :
; 309 :
; 310 : // KeInitializeTimer(&Extension->ReadRequestTotalTimer);
; 311 : // KeInitializeTimer(&Extension->ReadRequestIntervalTimer);
; 312 :
; 313 : //
; 314 : // We get the *current* timeout values to use for timing
; 315 : // this read.
; 316 : //
; 317 :
; 318 : KeAcquireSpinLock(
; 319 : &Extension->ControlLock,
; 320 : &controlIrql
; 321 : );
00064 8d 8b e4 01 00
00 lea ecx, DWORD PTR [ebx+484]
0006a ff 15 00 00 00
00 call DWORD PTR __imp_@KfAcquireSpinLock@4
; 322 :
; 323 : timeoutsForIrp = Extension->Timeouts;
00070 6a 05 push 5
00072 8d b3 58 01 00
00 lea esi, DWORD PTR [ebx+344]
00078 59 pop ecx
00079 8d 7d c4 lea edi, DWORD PTR _timeoutsForIrp$[ebp]
0007c f3 a5 rep movsd
; 324 :
; 325 : KeReleaseSpinLock(
; 326 : &Extension->ControlLock,
; 327 : controlIrql
; 328 : );
0007e 8b 3d 00 00 00
00 mov edi, DWORD PTR __imp_@KfReleaseSpinLock@8
00084 8d b3 e4 01 00
00 lea esi, DWORD PTR [ebx+484]
0008a 8a d0 mov dl, al
0008c 8b ce mov ecx, esi
0008e ff d7 call edi
; 329 :
; 330 : //
; 331 : // Calculate the interval timeout for the read.
; 332 : //
; 333 :
; 334 : if (timeoutsForIrp.ReadIntervalTimeout &&
; 335 : (timeoutsForIrp.ReadIntervalTimeout !=
; 336 : MAXULONG)) {
00090 8b 4d c4 mov ecx, DWORD PTR _timeoutsForIrp$[ebp]
00093 85 c9 test ecx, ecx
00095 74 37 je SHORT $L14868
00097 83 f9 ff cmp ecx, -1
0009a 74 37 je SHORT $L15146
; 337 :
; 338 : useIntervalTimer = TRUE;
; 339 :
; 340 : Extension->IntervalTime.QuadPart =
; 341 : UInt32x32To64(
; 342 : timeoutsForIrp.ReadIntervalTimeout,
; 343 : 10000
; 344 : );
0009c 8b c1 mov eax, ecx
0009e ba 10 27 00 00 mov edx, 10000 ; 00002710H
000a3 f7 e2 mul edx
000a5 89 43 38 mov DWORD PTR [ebx+56], eax
; 345 :
; 346 :
; 347 : if (Extension->IntervalTime.QuadPart >=
; 348 : Extension->CutOverAmount.QuadPart) {
000a8 8b c2 mov eax, edx
000aa 3b 43 54 cmp eax, DWORD PTR [ebx+84]
000ad c6 45 fa 01 mov BYTE PTR _useIntervalTimer$[ebp], 1
000b1 89 53 3c mov DWORD PTR [ebx+60], edx
000b4 7c 0f jl SHORT $L14867
000b6 7f 08 jg SHORT $L15149
000b8 8b 43 38 mov eax, DWORD PTR [ebx+56]
000bb 3b 43 50 cmp eax, DWORD PTR [ebx+80]
000be 72 05 jb SHORT $L14867
$L15149:
; 349 :
; 350 : Extension->IntervalTimeToUse =
; 351 : &Extension->LongIntervalAmount;
000c0 8d 43 48 lea eax, DWORD PTR [ebx+72]
; 352 :
; 353 : } else {
000c3 eb 03 jmp SHORT $L15162
$L14867:
; 354 :
; 355 : Extension->IntervalTimeToUse =
; 356 : &Extension->ShortIntervalAmount;
000c5 8d 43 40 lea eax, DWORD PTR [ebx+64]
$L15162:
000c8 89 83 88 00 00
00 mov DWORD PTR [ebx+136], eax
$L14868:
; 357 :
; 358 : }
; 359 :
; 360 : }
; 361 :
; 362 : if (timeoutsForIrp.ReadIntervalTimeout == MAXULONG) {
000ce 83 f9 ff cmp ecx, -1
000d1 75 2e jne SHORT $L14869
$L15146:
; 363 :
; 364 : //
; 365 : // We need to do special return quickly stuff here.
; 366 : //
; 367 : // 1) If both constant and multiplier are
; 368 : // 0 then we return immediately with whatever
; 369 : // we've got, even if it was zero.
; 370 : //
; 371 : // 2) If constant and multiplier are not MAXULONG
; 372 : // then return immediately if any characters
; 373 : // are present, but if nothing is there, then
; 374 : // use the timeouts as specified.
; 375 : //
; 376 : // 3) If multiplier is MAXULONG then do as in
; 377 : // "2" but return when the first character
; 378 : // arrives.
; 379 : //
; 380 :
; 381 : if (!timeoutsForIrp.ReadTotalTimeoutConstant &&
; 382 : !timeoutsForIrp.ReadTotalTimeoutMultiplier) {
000d3 83 7d cc 00 cmp DWORD PTR _timeoutsForIrp$[ebp+8], 0
000d7 8b 4d c8 mov ecx, DWORD PTR _timeoutsForIrp$[ebp+4]
000da 75 0a jne SHORT $L14870
000dc 85 c9 test ecx, ecx
000de 75 0c jne SHORT $L15147
; 383 :
; 384 : returnWithWhatsPresent = TRUE;
000e0 c6 45 fc 01 mov BYTE PTR _returnWithWhatsPresent$[ebp], 1
; 385 :
; 386 : } else if ((timeoutsForIrp.ReadTotalTimeoutConstant != MAXULONG)
000e4 eb 4e jmp SHORT $L14878
$L14870:
; 387 : &&
; 388 : (timeoutsForIrp.ReadTotalTimeoutMultiplier
; 389 : != MAXULONG)) {
000e6 83 7d cc ff cmp DWORD PTR _timeoutsForIrp$[ebp+8], -1
000ea 74 48 je SHORT $L14878
$L15147:
000ec 83 f9 ff cmp ecx, -1
; 390 :
; 391 : useTotalTimer = TRUE;
; 392 : os2ssreturn = TRUE;
000ef c6 45 fd 01 mov BYTE PTR _os2ssreturn$[ebp], 1
000f3 c6 45 0b 01 mov BYTE PTR _useTotalTimer$[ebp], 1
; 393 : multiplierVal = timeoutsForIrp.ReadTotalTimeoutMultiplier;
; 394 : constantVal = timeoutsForIrp.ReadTotalTimeoutConstant;
; 395 :
; 396 : } else if ((timeoutsForIrp.ReadTotalTimeoutConstant != MAXULONG)
000f7 75 18 jne SHORT $L14876
; 397 : &&
; 398 : (timeoutsForIrp.ReadTotalTimeoutMultiplier
; 399 : == MAXULONG)) {
; 400 :
; 401 : useTotalTimer = TRUE;
; 402 : os2ssreturn = TRUE;
; 403 : crunchDownToOne = TRUE;
000f9 c6 45 fb 01 mov BYTE PTR _crunchDownToOne$[ebp], 1
; 404 : multiplierVal = 0;
000fd 33 c9 xor ecx, ecx
; 405 : constantVal = timeoutsForIrp.ReadTotalTimeoutConstant;
; 406 :
; 407 : }
; 408 :
; 409 : } else {
000ff eb 10 jmp SHORT $L14876
$L14869:
; 410 :
; 411 : //
; 412 : // If both the multiplier and the constant are
; 413 : // zero then don't do any total timeout processing.
; 414 : //
; 415 :
; 416 : if (timeoutsForIrp.ReadTotalTimeoutMultiplier ||
; 417 : timeoutsForIrp.ReadTotalTimeoutConstant) {
00101 8b 4d c8 mov ecx, DWORD PTR _timeoutsForIrp$[ebp+4]
00104 85 c9 test ecx, ecx
00106 75 05 jne SHORT $L14877
00108 39 4d cc cmp DWORD PTR _timeoutsForIrp$[ebp+8], ecx
0010b 74 27 je SHORT $L14878
$L14877:
; 418 :
; 419 : //
; 420 : // We have some timer values to calculate.
; 421 : //
; 422 :
; 423 : useTotalTimer = TRUE;
0010d c6 45 0b 01 mov BYTE PTR _useTotalTimer$[ebp], 1
$L14876:
; 424 : multiplierVal = timeoutsForIrp.ReadTotalTimeoutMultiplier;
; 425 : constantVal = timeoutsForIrp.ReadTotalTimeoutConstant;
; 426 :
; 427 : }
; 428 :
; 429 : }
; 430 :
; 431 : if (useTotalTimer) {
; 432 :
; 433 : totalTime.QuadPart = ((LONGLONG)(UInt32x32To64(
; 434 : Extension->NumberNeededForRead,
; 435 : multiplierVal
; 436 : )
; 437 : + constantVal))
; 438 : * -10000;
00111 8b 83 0c 01 00
00 mov eax, DWORD PTR [ebx+268]
00117 6a ff push -1
00119 f7 e1 mul ecx
0011b 33 c9 xor ecx, ecx
0011d 03 45 cc add eax, DWORD PTR _timeoutsForIrp$[ebp+8]
00120 68 f0 d8 ff ff push -10000 ; ffffd8f0H
00125 13 d1 adc edx, ecx
00127 52 push edx
00128 50 push eax
00129 e8 00 00 00 00 call __allmul
0012e 89 45 e4 mov DWORD PTR _totalTime$[ebp], eax
00131 89 55 e8 mov DWORD PTR _totalTime$[ebp+4], edx
$L14878:
; 439 :
; 440 : }
; 441 :
; 442 :
; 443 : //
; 444 : // We do this copy in the hope of getting most (if not
; 445 : // all) of the characters out of the interrupt buffer.
; 446 : //
; 447 : // Note that we need to protect this operation with a
; 448 : // spinlock since we don't want a purge to hose us.
; 449 : //
; 450 :
; 451 : KeAcquireSpinLock(
; 452 : &Extension->ControlLock,
; 453 : &controlIrql
; 454 : );
00134 8b ce mov ecx, esi
00136 ff 15 00 00 00
00 call DWORD PTR __imp_@KfAcquireSpinLock@4
; 455 :
; 456 : updateChar.CharsCopied = SerialGetCharsFromIntBuffer(Extension);
0013c 53 push ebx
0013d 88 45 fe mov BYTE PTR _controlIrql$[ebp], al
00140 e8 00 00 00 00 call _SerialGetCharsFromIntBuffer@4
; 457 :
; 458 : //
; 459 : // See if we have any cause to return immediately.
; 460 : //
; 461 :
; 462 : if (returnWithWhatsPresent || (!Extension->NumberNeededForRead) ||
; 463 : (os2ssreturn &&
; 464 : Extension->CurrentReadIrp->IoStatus.Information)) {
00145 80 7d fc 00 cmp BYTE PTR _returnWithWhatsPresent$[ebp], 0
00149 89 45 dc mov DWORD PTR _updateChar$[ebp+4], eax
0014c 0f 85 bf 00 00
00 jne $L14885
00152 83 bb 0c 01 00
00 00 cmp DWORD PTR [ebx+268], 0
00159 0f 84 b2 00 00
00 je $L14885
0015f 80 7d fd 00 cmp BYTE PTR _os2ssreturn$[ebp], 0
00163 74 10 je SHORT $L14884
00165 8b 83 c4 00 00
00 mov eax, DWORD PTR [ebx+196]
0016b 83 78 1c 00 cmp DWORD PTR [eax+28], 0
0016f 0f 85 9c 00 00
00 jne $L14885
$L14884:
; 488 :
; 489 : }
; 490 :
; 491 : } else {
; 492 :
; 493 : //
; 494 : // The irp might go under control of the isr. It
; 495 : // won't hurt to initialize the reference count
; 496 : // right now.
; 497 : //
; 498 :
; 499 : SERIAL_INIT_REFERENCE(Extension->CurrentReadIrp);
00175 8d b3 c4 00 00
00 lea esi, DWORD PTR [ebx+196]
0017b 8b 06 mov eax, DWORD PTR [esi]
0017d 8b 40 60 mov eax, DWORD PTR [eax+96]
00180 83 60 10 00 and DWORD PTR [eax+16], 0
; 500 :
; 501 : IoAcquireCancelSpinLock(&oldIrql);
00184 8d 45 f0 lea eax, DWORD PTR _oldIrql$[ebp]
00187 50 push eax
00188 ff 15 00 00 00
00 call DWORD PTR __imp__IoAcquireCancelSpinLock@4
; 502 :
; 503 : //
; 504 : // We need to see if this irp should be canceled.
; 505 : //
; 506 :
; 507 : if (Extension->CurrentReadIrp->Cancel) {
0018e 8b 06 mov eax, DWORD PTR [esi]
00190 80 78 24 00 cmp BYTE PTR [eax+36], 0
00194 74 33 je SHORT $L14891
; 508 :
; 509 : IoReleaseCancelSpinLock(oldIrql);
00196 ff 75 f0 push DWORD PTR _oldIrql$[ebp]
00199 ff 15 00 00 00
00 call DWORD PTR __imp__IoReleaseCancelSpinLock@4
; 510 : KeReleaseSpinLock(
; 511 : &Extension->ControlLock,
; 512 : controlIrql
; 513 : );
0019f 8a 55 fe mov dl, BYTE PTR _controlIrql$[ebp]
001a2 8d 8b e4 01 00
00 lea ecx, DWORD PTR [ebx+484]
001a8 ff d7 call edi
; 514 : Extension->CurrentReadIrp->IoStatus.Status =
; 515 : STATUS_CANCELLED;
001aa 8b 0e mov ecx, DWORD PTR [esi]
001ac b8 20 01 00 c0 mov eax, -1073741536 ; c0000120H
001b1 89 41 18 mov DWORD PTR [ecx+24], eax
; 516 : Extension->CurrentReadIrp->IoStatus.Information = 0;
001b4 8b 0e mov ecx, DWORD PTR [esi]
001b6 83 61 1c 00 and DWORD PTR [ecx+28], 0
$L15164:
; 517 :
; 518 : if (!setFirstStatus) {
001ba 80 7d ff 00 cmp BYTE PTR _setFirstStatus$[ebp], 0
001be 0f 85 85 00 00
00 jne $L14887
; 519 :
; 520 : firstStatus = STATUS_CANCELLED;
001c4 89 45 f4 mov DWORD PTR _firstStatus$[ebp], eax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -