当前位置: 首页 > news >正文

nt!IoSynchronousPageWrite函数分析之atapi!IdeReadWrite----非常重要


第一部分:预分析

1: kd> g
Breakpoint 7 hit
atapi!IdeReadWrite:
f729cb2a 55              push    ebp
1: kd> kc
 #
00 atapi!IdeReadWrite
01 atapi!IdeSendCommand
02 atapi!AtapiStartIo
03 atapi!IdeStartIoSynchronized
04 nt!KeSynchronizeExecution
05 atapi!IdePortAllocateAccessToken
06 PCIIDEX!BmReceiveScatterGatherList
07 hal!HalBuildScatterGatherList
08 hal!HalGetScatterGatherList
09 PCIIDEX!BmSetup
0a atapi!IdePortStartIo
0b nt!IoStartPacket
0c atapi!IdePortDispatch
0d nt!IofCallDriver
0e CLASSPNP!SubmitTransferPacket
0f CLASSPNP!ServiceTransferRequest
10 CLASSPNP!ClassReadWrite
11 nt!IofCallDriver
12 PartMgr!PmReadWrite
13 nt!IofCallDriver
14 ftdisk!FtDiskReadWrite
15 nt!IofCallDriver
16 volsnap!VolSnapWrite
17 nt!IofCallDriver
18 Ntfs!NtfsSingleAsync
19 Ntfs!NtfsNonCachedIo
1a Ntfs!NtfsCommonWrite
1b Ntfs!NtfsFsdWrite
1c nt!IofCallDriver
1d nt!IoSynchronousPageWrite
1e nt!MiFlushSectionInternal
1f nt!MmFlushSection
20 nt!CcFlushCache
21 Ntfs!LfsFlushLfcb
22 Ntfs!LfsFlushToLsnPriv
23 Ntfs!LfsWriteLfsRestart
24 Ntfs!LfsWriteRestartArea
25 Ntfs!NtfsCheckpointVolume
26 Ntfs!NtfsCheckpointAllVolumes
27 nt!ExpWorkerThread
28 nt!PspSystemThreadStartup
29 nt!KiThreadStartup


1: kd> dt HW_DEVICE_EXTENSION 0x895e98a8
atapi!HW_DEVICE_EXTENSION
   +0x000 CurrentSrb       : 0x898f9d7c _SCSI_REQUEST_BLOCK
   +0x004 BaseIoAddress1   : _IDE_REGISTERS_1
   +0x028 BaseIoAddress2   : _IDE_REGISTERS_2
   +0x034 BaseIoAddress1Length : 8
   +0x038 BaseIoAddress2Length : 1
   +0x03c MaxIdeDevice     : 2
   +0x040 MaxIdeTargetId   : 2
   +0x044 CurrentIdeDevice : 0
   +0x048 MoreWait         : 0
   +0x04c NoRetry          : 0
   +0x050 NumberOfCylinders : [4] 0x4443
   +0x060 NumberOfHeads    : [4] 0xf
   +0x070 SectorsPerTrack  : [4] 0x3f
   +0x080 InterruptMode    : 1
   +0x084 DataBuffer       : 0x894ef000  "FILE0"
   +0x088 BytesLeft        : 0
   +0x08c ErrorCount       : 0
   +0x090 TimeoutCount     : [4] 0
   +0x0a0 LastLun          : [4] 0
   +0x0b0 DeviceFlags      : [4] 0x30e01
   +0x0c0 MaximumBlockXfer : [4]  "@"
   +0x0c4 ExpectingInterrupt : 0 ''
   +0x0c5 DMAInProgress    : 0 ''
   +0x0c6 scsi2atapi       : 0 ''
   +0x0c7 RDP              : 0 ''
   +0x0c8 DriverMustPoll   : 0 ''
   +0x0c9 PrimaryAddress   : 0x1 ''
   +0x0ca SecondaryAddress : 0 ''
   +0x0cb NoPioSetTransferMode : 0 ''
   +0x0cc OriginalCdb      : [16]  ""
   +0x0dc SmartCommand     : 0 ''
   +0x0dd ReturningMediaStatus : 0 ''
   +0x0de IdentifyData     : [4] _IDENTIFY_DATA
   +0x8e0 BusMasterInterface : _PCIIDE_BUSMASTER_INTERFACE
   +0x928 DeviceParameters : [4] _DEVICE_PARAMETERS
   +0xa18 ResetState       : RESET_STATE
1: kd> dx -id 0,0,899a2278 -r1 (*((atapi!_IDE_REGISTERS_1 *)0x895e98ac))
(*((atapi!_IDE_REGISTERS_1 *)0x895e98ac))                 [Type: _IDE_REGISTERS_1]
    [+0x000] RegistersBaseAddress : 0x1f0 : Unable to read memory at Address 0x1f0 [Type: unsigned char *]
    [+0x004] Data             : 0x1f0 : Unable to read memory at Address 0x1f0 [Type: unsigned short *]
    [+0x008] Error            : 0x1f1 : Unable to read memory at Address 0x1f1 [Type: unsigned char *]
    [+0x00c] BlockCount       : 0x1f2 : Unable to read memory at Address 0x1f2 [Type: unsigned char *]
    [+0x010] BlockNumber      : 0x1f3 : Unable to read memory at Address 0x1f3 [Type: unsigned char *]
    [+0x014] CylinderLow      : 0x1f4 : Unable to read memory at Address 0x1f4 [Type: unsigned char *]
    [+0x018] CylinderHigh     : 0x1f5 : Unable to read memory at Address 0x1f5 [Type: unsigned char *]
    [+0x01c] DriveSelect      : 0x1f6 : Unable to read memory at Address 0x1f6 [Type: unsigned char *]
    [+0x020] Command          : 0x1f7 : Unable to read memory at Address 0x1f7 [Type: unsigned char *]

1: kd> dx -r1 ((atapi!_SCSI_REQUEST_BLOCK *)0x898f9d7c)
((atapi!_SCSI_REQUEST_BLOCK *)0x898f9d7c)                 : 0x898f9d7c [Type: _SCSI_REQUEST_BLOCK *]
    [+0x000] Length           : 0x40 [Type: unsigned short]
    [+0x002] Function         : 0x0 [Type: unsigned char]
    [+0x003] SrbStatus        : 0x0 [Type: unsigned char]
    [+0x004] ScsiStatus       : 0x0 [Type: unsigned char]
    [+0x005] PathId           : 0x0 [Type: unsigned char]
    [+0x006] TargetId         : 0x0 [Type: unsigned char]
    [+0x007] Lun              : 0x0 [Type: unsigned char]
    [+0x008] QueueTag         : 0x0 [Type: unsigned char]
    [+0x009] QueueAction      : 0x20 [Type: unsigned char]
    [+0x00a] CdbLength        : 0xa [Type: unsigned char]
    [+0x00b] SenseInfoBufferLength : 0x12 [Type: unsigned char]
    [+0x00c] SrbFlags         : 0x40210180 [Type: unsigned long]
    [+0x010] DataTransferLength : 0x2000 [Type: unsigned long]
    [+0x014] TimeOutValue     : 0xa [Type: unsigned long]
    [+0x018] DataBuffer       : 0x89537000 [Type: void *]
    [+0x01c] SenseInfoBuffer  : 0x898f9d68 [Type: void *]
    [+0x020] NextSrb          : 0x0 [Type: _SCSI_REQUEST_BLOCK *]
    [+0x024] OriginalRequest  : 0x898f9b38 [Type: void *]
    [+0x028] SrbExtension     : 0x2 [Type: void *]
    [+0x02c] InternalStatus   : 0x5e3c57 [Type: unsigned long]
    [+0x02c] QueueSortKey     : 0x5e3c57 [Type: unsigned long]
    [+0x030] Cdb              [Type: unsigned char [16]]


1: kd> db 0x89537000
89537000  52 43 52 44 28 00 09 00-1a 0b 0f 08 00 00 00 00  RCRD(...........
89537010  01 00 00 00 02 00 01 00-d0 08 00 00 00 00 00 00  ................
89537020  0f 0b 0f 08 00 00 00 00-dc 0e db 01 00 00 00 00  ................
89537030  00 00 01 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
89537040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
89537050  0a 0a 0f 08 00 00 00 00-eb 09 0f 08 00 00 00 00  ................
89537060  eb 09 0f 08 00 00 00 00-98 00 00 00 00 00 00 00  ................
89537070  01 00 00 00 18 00 00 00-00 00 00 00 00 00 00 00  ................
1: kd> dd 0x89537000
89537000  44524352 00090028 080f0b1a 00000000
89537010  00000001 00010002 000008d0 00000000
89537020  080f0b0f 00000000 01db0edc 00000000
89537030  00010000 00000000 00000000 00000000
89537040  00000000 00000000 00000000 00000000
89537050  080f0a0a 00000000 080f09eb 00000000
89537060  080f09eb 00000000 00000098 00000000
89537070  00000001 00000018 00000000 00000000
1: kd> dd c2c45000
c2c45000  44524352 00090028 080f0b1a 00000000
c2c45010  00000001 00010002 000008d0 00000000
c2c45020  080f0b0f 00000000 00000edc 00000000
c2c45030  00000000 00000000 00000000 00000000
c2c45040  00000000 00000000 00000000 00000000
c2c45050  080f0a0a 00000000 080f09eb 00000000
c2c45060  080f09eb 00000000 00000098 00000000
c2c45070  00000001 00000018 00000000 00000000

1: kd> dd 0x89538000
89538000  44524352 00090028 080f0c44 00000000
89538010  00000001 00020002 00000220 00000000
89538020  080f0c0c 00000000 00240edd 00000000
89538030  00000000 0000000c 00000000 00000000
89538040  00000000 00000000 00000000 00000000
89538050  00000000 00000000 00000000 00000000
89538060  080f0c0c 00000000 080f0b1a 00000000
89538070  080f0b1a 00000000 00000190 00000000
1: kd> dd c2c46000
c2c46000  44524352 00090028 080f0c44 00000000
c2c46010  00000001 00020002 00000220 00000000
c2c46020  080f0c0c 00000000 00000edd 00000000
c2c46030  00000000 00000000 00000000 00000000
c2c46040  00000000 00000000 00000000 00000000
c2c46050  00000000 00000000 00000000 00000000
c2c46060  080f0c0c 00000000 080f0b1a 00000000
c2c46070  080f0b1a 00000000 00000190 00000000


    [+0x010] DataTransferLength : 0x2000 [Type: unsigned long]
    [+0x014] TimeOutValue     : 0xa [Type: unsigned long]
    [+0x018] DataBuffer       : 0x89537000 [Type: void *]


    //
    // Set data buffer pointer and words left.
    //

    deviceExtension->DataBuffer = (PUCHAR)Srb->DataBuffer;
    deviceExtension->BytesLeft = Srb->DataTransferLength;

第二部分:


    //
    // Select device 0 or 1.
    //
    SelectIdeDevice(baseIoAddress1, Srb->TargetId, 0);


1: kd> p
atapi!IdeReadWrite+0x20:
f729cb4a 50              push    eax
1: kd> p
atapi!IdeReadWrite+0x21:
f729cb4b ff7620          push    dword ptr [esi+20h]
1: kd> p
atapi!IdeReadWrite+0x24:
f729cb4e ffd3            call    ebx
1: kd> r
eax=000000a0 ebx=804f4d68 ecx=00000000 edx=00000001 esi=895e98a8 edi=898f9d7c
eip=f729cb4e esp=f78d1bd8 ebp=f78d1bf4 iopl=0         nv up ei ng nz na pe cy
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000287
atapi!IdeReadWrite+0x24:
f729cb4e ffd3            call    ebx {hal!WRITE_PORT_UCHAR (804f4d68)}


cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port    01f6            [+0x01c] DriveSelect      : 0x1f6 :
        mov     al,[esp+8]              ; (al) = Value    a0
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR


1: kd> p
eax=000000a0 ebx=804f4d68 ecx=00000000 edx=000001f6 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei ng nz na pe cy
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000287
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


#define SelectIdeDevice(BaseIoAddress, deviceNumber, additional) {\
    SelectIdeLine(BaseIoAddress, (deviceNumber) >>1);\
    WRITE_PORT_UCHAR ((BaseIoAddress)->DriveSelect, (UCHAR)((((deviceNumber) & 0x1) << 4) | 0xA0 | additional));\
    }


    //
    // Select device 0 or 1.
    //
    SelectIdeDevice(baseIoAddress1, Srb->TargetId, 0);

[+0x006] TargetId         : 0x0 [Type: unsigned char]

如果是[+0x006] TargetId         : 0x1 [Type: unsigned char],则
10000
0x10

0x10 | 0xA0= |0xB0


第三部分:


    GetStatus(baseIoAddress1, statusByte2);


cPublicProc _READ_PORT_UCHAR ,1
cPublicFpo 1, 0

        xor     eax, eax        ; Eliminate partial stall on return to caller

        mov     edx,[esp+4]             ; (dx) = Port    1f7     [+0x020] Command          : 0x1f7
        in      al,dx                00
        stdRET    _READ_PORT_UCHAR

stdENDP _READ_PORT_UCHAR


1: kd> p
eax=00000000 ebx=804f4d68 ecx=00000000 edx=000001f7 esi=895e98a8 edi=898f9d7c
eip=804f4d06 esp=f78d1bd8 ebp=f78d1bf4 iopl=0         nv up ei pl zr na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000246
hal!READ_PORT_UCHAR+0x6:
804f4d06 ec              in      al,dx
1: kd> p
eax=00000050 ebx=804f4d68 ecx=00000000 edx=000001f7 esi=895e98a8 edi=898f9d7c
eip=804f4d07 esp=f78d1bd8 ebp=f78d1bf4 iopl=0         nv up ei pl zr na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000246
hal!READ_PORT_UCHAR+0x7:
804f4d07 c20400          ret     4

eax=00000050    #define IDE_STATUS_IDLE              0x50


//
// IDE status definitions
//
#define IDE_STATUS_ERROR             0x01
#define IDE_STATUS_INDEX             0x02
#define IDE_STATUS_CORRECTED_ERROR   0x04
#define IDE_STATUS_DRQ               0x08
#define IDE_STATUS_DSC               0x10
#define IDE_STATUS_DRDY              0x40
#define IDE_STATUS_IDLE              0x50
#define IDE_STATUS_BUSY              0x80


    if (statusByte2 & IDE_STATUS_BUSY) {
        DebugPrint((DBG_CRASHDUMP | DBG_READ_WRITE,
                    "IdeReadWrite: Returning BUSY status\n"));
        return SRB_STATUS_BUSY;
    }


第四部分:

    //
    // Set data buffer pointer and words left.
    //

    deviceExtension->DataBuffer = (PUCHAR)Srb->DataBuffer;
    deviceExtension->BytesLeft = Srb->DataTransferLength;

   +0x084 DataBuffer       : 0x89537000  "RCRD("
   +0x088 BytesLeft        : 0x2000

第五部分:


1: kd> ?(0x2000 + 0x1FF)/0x200
Evaluate expression: 16 = 00000010


    //                                                         
    // Set up sector count register. Round up to next block.
    //
    IdePortOutPortByte (
                       baseIoAddress1->BlockCount,
                       (UCHAR)((Srb->DataTransferLength + 0x1FF) / 0x200));

cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port        [+0x00c] BlockCount       : 0x1f2 :
        mov     al,[esp+8]              ; (al) = Value        10
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR

1: kd> p
eax=00000010 ebx=804f4d68 ecx=00000000 edx=000001f2 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei pl nz na po cy
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000203
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


第六部分:

    //
    // Get starting sector number from CDB.
    //

    startingSector = ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte3 |        0x57
                     ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte2 << 8 |        0x3c00
                     ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 |        0x5e0000
                     ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24;


  +0x000 CDB10            : _CDB10
      +0x000 OperationCode    : 0x2a '*'
      +0x001 RelativeAddress  : 0y0
      +0x001 Reserved1        : 0y00
      +0x001 ForceUnitAccess  : 0y1
      +0x001 DisablePageOut   : 0y0
      +0x001 LogicalUnitNumber : 0y000
      +0x002 LogicalBlockByte0 : 0 ''
      +0x003 LogicalBlockByte1 : 0x5e '^'
      +0x004 LogicalBlockByte2 : 0x3c '<'
      +0x005 LogicalBlockByte3 : 0x57 'W'
      +0x006 Reserved2        : 0 ''
      +0x007 TransferBlocksMsb : 0 ''
      +0x008 TransferBlocksLsb : 0x10 ''
      +0x009 Control          : 0 ''

0x5e3c57

1: kd> p
atapi!IdeReadWrite+0xb7:
f729cbe1 50              push    eax
1: kd> p
atapi!IdeReadWrite+0xb8:
f729cbe2 682eca29f7      push    offset atapi!IdeReadWriteExt+0x35e (f729ca2e)
1: kd> r
eax=005e3c57

第七部分:


   if (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_LBA) {


1: kd> dt HW_DEVICE_EXTENSION 0x895e98a8

   +0x0b0 DeviceFlags      : [4] 0x30e01
1: kd> dx -id 0,0,899a2278 -r1 (*((atapi!unsigned long (*)[4])0x895e9958))
(*((atapi!unsigned long (*)[4])0x895e9958))                 [Type: unsigned long [4]]
    [0]              : 0x30e01 [Type: unsigned long]
    [1]              : 0x0 [Type: unsigned long]
    [2]              : 0x0 [Type: unsigned long]
    [3]              : 0x0 [Type: unsigned long]

1: kd> db 0x895e98a8+0x0b0
895e9958  01 0e 03 00 00 00 00 00-00 00 00 00 00 00 00 00  ................


#define DFLAGS_LBA                   (1 << 10)   // support LBA addressing


 100 0000 0000

0x400


1110 0000 0001


第八部分:

    if (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_LBA) {

        SelectIdeDevice(baseIoAddress1,
                        Srb->TargetId,
                        (IDE_LBA_MODE | ((startingSector & 0x0f000000) >> 24)));

        IdePortOutPortByte (
                           baseIoAddress1->BlockNumber,
                           (UCHAR) ((startingSector & 0x000000ff) >> 0));
        IdePortOutPortByte (
                           baseIoAddress1->CylinderLow,
                           (UCHAR) ((startingSector & 0x0000ff00) >> 8));

        IdePortOutPortByte (
                           baseIoAddress1->CylinderHigh,
                           (UCHAR) ((startingSector & 0x00ff0000) >> 16));


#define IDE_LBA_MODE                                    (1 << 6)

100    0000
0x40


005e3c57 & 0x0f000000

        SelectIdeDevice(baseIoAddress1,
                        Srb->TargetId,
                        (IDE_LBA_MODE | ((startingSector & 0x0f000000) >> 24)));

0x40
0x0| 0xA0 |0x40=0xe0

#define SelectIdeDevice(BaseIoAddress, deviceNumber, additional) {\
    SelectIdeLine(BaseIoAddress, (deviceNumber) >>1);\
    WRITE_PORT_UCHAR ((BaseIoAddress)->DriveSelect, (UCHAR)((((deviceNumber) & 0x1) << 4) | 0xA0 | additional));\
    }

cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port    01f6
        mov     al,[esp+8]              ; (al) = Value    e0
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR

1: kd> p
eax=800000e0 ebx=804f4d68 ecx=000000e0 edx=000001f6 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei ng nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000282
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


第九部分:

 [+0x010] BlockNumber      : 0x1f3 : Unable to read memory at Address 0x1f3 [Type: unsigned char *]
    [+0x014] CylinderLow      : 0x1f4 : Unable to read memory at Address 0x1f4 [Type: unsigned char *]
    [+0x018] CylinderHigh     : 0x1f5 : Unable to read memory at Address 0x1f5 [Type: unsigned char *]


        IdePortOutPortByte (
                           baseIoAddress1->BlockNumber,                 [+0x010] BlockNumber      : 0x1f3
                           (UCHAR) ((startingSector & 0x000000ff) >> 0));        0x57

005e3c57& 0x000000ff=0x57

cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port
        mov     al,[esp+8]              ; (al) = Value
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR


1: kd> p
eax=80000057 ebx=804f4d68 ecx=000000e0 edx=000001f3 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei ng nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000282
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


第十部分:

        IdePortOutPortByte (
                           baseIoAddress1->CylinderLow,            [+0x014] CylinderLow      : 0x1f4
                           (UCHAR) ((startingSector & 0x0000ff00) >> 8));    3c

cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port        01f4
        mov     al,[esp+8]              ; (al) = Value        3c
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR

1: kd> p
eax=00005e3c ebx=804f4d68 ecx=000000e0 edx=000001f4 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei pl nz na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000206
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


第十一部分:


        IdePortOutPortByte (
                           baseIoAddress1->CylinderHigh,            [+0x018] CylinderHigh     : 0x1f5
                           (UCHAR) ((startingSector & 0x00ff0000) >> 16));    5e
    
cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port            01f5
        mov     al,[esp+8]              ; (al) = Value            5e
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR

1: kd> p
eax=0000005e ebx=804f4d68 ecx=000000e0 edx=000001f5 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei pl nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000202
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al


第十二部分:

//
// SRB Flag Bits
//

#define SRB_FLAGS_QUEUE_ACTION_ENABLE       0x00000002
#define SRB_FLAGS_DISABLE_DISCONNECT        0x00000004
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER    0x00000008

#define SRB_FLAGS_BYPASS_FROZEN_QUEUE       0x00000010
#define SRB_FLAGS_DISABLE_AUTOSENSE         0x00000020
#define SRB_FLAGS_DATA_IN                   0x00000040
#define SRB_FLAGS_DATA_OUT                  0x00000080            #define SRB_FLAGS_DATA_OUT         
#define SRB_FLAGS_NO_DATA_TRANSFER          0x00000000
#define SRB_FLAGS_UNSPECIFIED_DIRECTION      (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)

#define SRB_FLAGS_NO_QUEUE_FREEZE           0x00000100            #define SRB_FLAGS_NO_QUEUE_FREEZE
#define SRB_FLAGS_ADAPTER_CACHE_ENABLE      0x00000200
#define SRB_FLAGS_FREE_SENSE_BUFFER         0x00000400

#define SRB_FLAGS_IS_ACTIVE                 0x00010000            #define SRB_FLAGS_IS_ACTIVE
#define SRB_FLAGS_ALLOCATED_FROM_ZONE       0x00020000
#define SRB_FLAGS_SGLIST_FROM_POOL          0x00040000
#define SRB_FLAGS_BYPASS_LOCKED_QUEUE       0x00080000

#define SRB_FLAGS_NO_KEEP_AWAKE             0x00100000
#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE    0x00200000        #define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE
#define SRB_FLAGS_PORT_DRIVER_SENSEHASPORT  0x00400000
#define SRB_FLAGS_DONT_START_NEXT_PACKET    0x00800000

#define SRB_FLAGS_PORT_DRIVER_RESERVED      0x0F000000
#define SRB_FLAGS_CLASS_DRIVER_RESERVED     0xF0000000

    //
    // Check if write request.
    //

    if (Srb->SrbFlags & SRB_FLAGS_DATA_IN) {        //不是读操作,是写操作


1: kd> dx -r1 ((atapi!_SCSI_REQUEST_BLOCK *)0x898f9d7c)
((atapi!_SCSI_REQUEST_BLOCK *)0x898f9d7c)                 : 0x898f9d7c [Type: _SCSI_REQUEST_BLOCK *]
    [+0x000] Length           : 0x40 [Type: unsigned short]
    [+0x002] Function         : 0x0 [Type: unsigned char]
    [+0x003] SrbStatus        : 0x0 [Type: unsigned char]
    [+0x004] ScsiStatus       : 0x0 [Type: unsigned char]
    [+0x005] PathId           : 0x0 [Type: unsigned char]
    [+0x006] TargetId         : 0x0 [Type: unsigned char]
    [+0x007] Lun              : 0x0 [Type: unsigned char]
    [+0x008] QueueTag         : 0x0 [Type: unsigned char]
    [+0x009] QueueAction      : 0x20 [Type: unsigned char]
    [+0x00a] CdbLength        : 0xa [Type: unsigned char]
    [+0x00b] SenseInfoBufferLength : 0x12 [Type: unsigned char]
    [+0x00c] SrbFlags         : 0x40210180 [Type: unsigned long]        #define SRB_FLAGS_DATA_OUT                  0x00000080

第十三部分:


    } else {


        //
        // Send write command.
        //
        if (SRB_USES_DMA(Srb)) {        //符合条件:    [+0x028] SrbExtension     : 0x2 [Type: void *]

            IdePortOutPortByte (
                               baseIoAddress1->Command,
                               IDE_COMMAND_WRITE_DMA);


#define SRB_USES_DMA(Srb)               (((ULONG_PTR)Srb->SrbExtension) & 2)


    [+0x028] SrbExtension     : 0x2 [Type: void *]

#define IDE_COMMAND_WRITE_DMA                   0xCA

cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0

        mov     edx,[esp+4]             ; (dx) = Port        01f7
        mov     al,[esp+8]              ; (al) = Value        ca
        out     dx,al
        stdRET    _WRITE_PORT_UCHAR

stdENDP _WRITE_PORT_UCHAR

1: kd> p
eax=000000ca ebx=804f4d68 ecx=000000e0 edx=000001f7 esi=895e98a8 edi=898f9d7c
eip=804f4d70 esp=f78d1bd4 ebp=f78d1bf4 iopl=0         nv up ei pl nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000202
hal!WRITE_PORT_UCHAR+0x8:
804f4d70 ee              out     dx,al

http://www.lqws.cn/news/558613.html

相关文章:

  • 23种设计模式——策略模式:像换口红一样切换你的算法
  • Learning to Prompt for Continual Learning
  • 数据结构与算法 --- 双向链表
  • 问卷标记语言(QML):简化调查问卷设计与部署的XML解决方案
  • 【YOLOv13保姆级教程#03】自建数据集训练与验证(Train Val)全流程 | 手把手教你构建数据集、标签格式转换与yaml配置
  • Go开发工程师-Golang基础知识篇
  • Vue工程化实现约定式路由自动注册
  • 使用vue3构建一套网站
  • TCP 和 UDP 是什么?
  • 【Python基础】06 实战:视频压缩迷你脚本设计
  • 深入理解C#委托操作:添加、移除与调用全解析
  • 港澳地区,海外服务器ping通可能是地区运营商问题
  • MySQL为什么要使用b+树
  • 1 Studying《Computer Architecture A Quantitative Approach》1-4
  • 鸿蒙HarmonyOS 5小游戏实践:数字记忆挑战(附:源代码)
  • 信号处理学习——文献精读与code复现之TFN——嵌入时频变换的可解释神经网络(下)
  • 给定一个整型矩阵map,求最大的矩形区域为1的数量
  • Insar 相位展开真实的数据集的生成与下载(随机矩阵放大,zernike 仿真包裹相位)
  • Launcher3中的CellLayout 和ShortcutAndWidgetContainer 的联系和各自职责
  • 剑指offer50_0到n-1中缺失的数字
  • python -日期与天数的转换
  • autoas/as 工程的RTE静态消息总线实现与端口数据交换机制详解
  • 解决flash-attn安装报错的问题
  • 【C】陷波滤波器
  • 鸿蒙开发:资讯项目实战之底部导航封装
  • MySQL之MVCC实现原理深度解析
  • 类和对象(中)
  • springboot+Vue驾校管理系统
  • 开疆智能ModbusTCP转CClinkIE网关连接台达DVP-ES3 PLC配置案例
  • Java-正则表达式