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.pswp.cn/news/912322.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912322.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软考系统架构设计师经验总结

本文目的 对参加的2025年上半年系统架构设计师考试进行总结提供一些备考思路给未来参加系统架构设计师的同学 个人背景 工作背景 本科计算机与技术&#xff08;学过一些计算机基础课程&#xff09;&#xff0c;15年毕业后从事过b端&#xff08;人群画像、营销、用户增长、硬…

Tailwind CSS工作原理

文章目录 前言1. 指令解析与 AST 操作&#x1f6a9; **核心处理流程**&#x1f9e9; **具体流程说明** 2. **配置驱动的样式生成**3. **JIT 模式&#xff08;Just-In-Time&#xff09;的核心逻辑**4. **插件与自定义扩展**5. **与 PostCSS 管道的协同**6. **优化与 Tree Shakin…

web网页开发,在线%旅游景点管理%系统demo,基于Idea,vscode,html,css,vue,java,maven,springboot,mysql

经验心得 两业务单&#xff0c;都是业务逻辑开发&#xff0c;基本crud&#xff0c;什么是前后端&#xff0c;怎么分离前后端&#xff0c;前后端怎么通讯的&#xff0c;是以什么格式进行通讯这些咱们都需要掌握&#xff0c;后面剩下就是前后端不同层如何优化。管理系统很常见了其…

面试150 长度最小的子数组

思路 联想到滑动窗口法。左窗口的值为0&#xff0c;遍历数组对数组求和&#xff0c;当数组的和大于等于target的时候&#xff0c;窗口要收缩&#xff0c;计算子数组的长度&#xff0c;并及时更新最小的长度&#xff0c;左窗口右移。 class Solution:def minSubArrayLen(self,…

Python字典的查询操作

一、前言 在 Python 中&#xff0c;字典&#xff08;dict&#xff09; 是一种非常常用的数据结构&#xff0c;以键值对&#xff08;Key-Value Pair&#xff09;形式存储数据&#xff0c;支持快速查找、插入和删除操作。 本文将系统性地介绍 Python 字典中常见的查询操作方法&…

pyhton基础【18】面向对象基础一

目录 一.面向对象 二.面向对象概述 三.类与对象 一.面向对象 Python中的面向对象编程OOP是一种编程范式&#xff0c;它使用对象来设计软件。对象是具有属性(称为属性)和可以执行的操作(称为方法)的数据结构。 基础概念 类&#xff1a;class 类是创建对象的蓝图或模板。它…

Requests源码分析:面试考察角度自验(初级)

简单描述执行流程 Q:能简单描述一下发送一个requests.get(url)请求时,在requests库内部的主要执行流程吗?(从调用get方法到收到响应) 入口委托: get() 方法内部调用 requests.request(GET, url)。Session 接管: request() 方法会获取或隐式创建一个 Session 对象,并调用…

鸿蒙5:条件-循环-列表渲染

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…

浅谈AI大模型-MCP

MCP简介 MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议 &#xff09;&#xff0c;24年11月初的时候Anthropic发了一篇技术博客&#xff0c;推出了他们的模型上下文协议MCP&#xff0c;介绍了一种规范&#xff1a;应用如何为LLM提供上下文。官网称MCP为AI应…

MySQL数据库基础概述

前言&#xff1a; MySQL作为全球应用最广泛的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;​&#xff0c;凭借其高性能、高可靠性与零成本特性&#xff0c;已成为Web应用、企业系统的核心数据引擎。它遵循SQL标准&#xff0c;通过表结构实现数据的结构化存储&#x…

桌面小屏幕实战课程:DesktopScreen 16 HTTP

飞书文档http://https://x509p6c8to.feishu.cn/docx/doxcnrxBs55qGn6xoysTcJpqwRf /home/kemp/work/esp/esp-idf/examples/protocols/http_request 源码下载方式参考&#xff1a; 源码下载方式 心知天气 注册账号&#xff0c;申请产品&#xff0c;获取密钥 产品 天气数据 H…

vs2019 + QT下 vs2019创建的项目打开ui文件失败

问题: 在vs2019 QT模式下。使用2019创建工程后。点击ui文件打开时。出现奔溃&#xff0c;如下图 解决方式&#xff1a; ui文件->右键->打开方式->添加->程序->点击三个点->qcreator(qt安装目录) ->设置为默认值->确定 点击设置为默认值&#xff0c;点…

WPS之PPT镂空效果实现

1、准备一张图片&#xff0c;剪切存入剪贴板 2、把图片设为背景 右键 》 设置背景格式 》 图片或纹理填充 》 图片填充选择剪贴板 3、插入一个矩形覆盖全图&#xff0c;设置无线条渐变填充从左到右 4、插入圆角矩形 5、单击小黄点调整弧度 6、选择无线条幻灯片背景填充 7、插…

服务注册中心的本质抉择:从业务本质看AP与CP的终极之选

本文从服务注册中心的本质职责出发&#xff0c;通过分析其核心功能、业务场景和技术约束&#xff0c;深入探讨服务注册中心在架构设计上应该优先保证AP还是CP特性。文章首先剖析服务注册中心的根本使命&#xff0c;然后从分布式系统原理、生产实践案例和性能表现三个维度进行对…

mybatis-plus从入门到入土(一):快速开始

​ 朋友们, 大家好, 从今天开始我想开一个系列博客。名字起的比较随意就叫Mybatis-Plus从入门到入土, 这系列博客的定位是从基础使用开始, 然后逐步深入全面的了解Mybatis-Plus框架, 写这个博客的主要原因是工作中经常用到Mybatis-Plus框架, 因而对这个框架相对比较了解一些, 顺…

如何快速将iPhone中的文本保存到电脑上

您的 iPhone 上是否有很多重要的短信&#xff0c;并且您想将短信备份到计算机上&#xff1f;我们都知道传输消息与传输照片不同&#xff0c;但幸运的是&#xff0c;您可以使用相关的工具和方法来实现。我们介绍了 4 种方法来解释如何将 iPhone 中的文本保存到计算机。所有的办法…

【OpenGL学习】(八)图形变换

OpenGL图形变换介绍&#xff1a;https://learnopengl-cn.github.io/01%20Getting%20started/07%20Transformations 【OpenGL学习】&#xff08;八&#xff09;图形变换 本项目将通过变换矩阵&#xff0c;对【OpenGL学习】&#xff08;七&#xff09;纹理单元 中的图形进行缩放…

从理论到实战:解密大型语言模型的核心技术与应用指南

一、Transformer&#xff1a;语言理解与生成的基石 Transformer 架构的出现&#xff0c;彻底改变了自然语言处理&#xff08;NLP&#xff09;的格局。它以“注意力”为核心&#xff0c;将全局依赖的捕捉效率推向新高。下面用 图简要概览其数据流&#xff1a; 从上图可见&#…

kali换源

在Kali Linux中切换软件源可以提高软件下载速度&#xff0c;下面为你介绍切换源的方法。 一、备份原配置文件 首先备份原配置文件&#xff0c;避免操作失误导致问题&#xff1a; sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak二、编辑源配置文件 使用以下命令编…

从决策树到随机森林:Python机器学习里的“树形家族“深度实战与原理拆解

引言 在机器学习的算法森林中&#xff0c;有一对"树形兄弟"始终占据着C位——决策树像个逻辑清晰的"老教授"&#xff0c;用可视化的树状结构把复杂决策过程拆解成"是/否"的简单判断&#xff1b;而它的进阶版随机森林更像一支"精英军团&quo…