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