ATA pass through read sectors

Hello

http://msdn.microsoft.com/en-us/library/windows/hardware/ff551322(v=vs.85).aspx
I’m trying to read a few sectors with ATA pass through interface (APTI), that works when I read the MBR because we read sector 0, of size 1. So even with putting shit into the CurrentTaskFile that works because almost all the fields are 0.

Now I’m trying to read in a given place, let’s say sector 4000 (decimal) and that doesn’t work.
The definition of CurrentTaskFile isn’t the same on several places.

On MSDN it’s the following (CHS):

[quote]0 Features Register
1 Sector Count Register
2 Sector Number Register
3 Cylinder Low Register
4 Cylinder High Register
5 Device/Head Register
6 Command Register
7 Reserved[/quote]

And on a source I found: http://www.smartmontools.org/browser/trunk/smartmontools/scsiata.cpp#L229 as well as t10 documentation ftp://ftp.t10.org/t10/document.04/04-262r8.pdf
it’s using an ATA command of size 12 or 16 (while ATA_PASS_THROUGH_DIRECT structure has CurrentTaskFile of size 8), and they put LBA inside while MSDN tells to use CHS.

What is the correct way to use it?
My code:

void Disk::FillAPTI(PATA_PASS_THROUGH_DIRECT pATAData, bool write, BYTE\* outBuff, int sizeBuff, int nbSectors, int sectorOffset, CHS sectorNum, UCHAR command, bool useDMA)  
{  
 //http://msdn.microsoft.com/en-us/library/windows/hardware/ff551322%28v=vs.85%29.aspx  
  
//Clear the contents  
 ZeroMemory(pATAData, sizeof(ATA_PASS_THROUGH_DIRECT));  
  
// Init input / output buffs  
 ZeroMemory(outBuff, sizeBuff);  
  
//Fill in query data  
 pATAData-\>Length = sizeof(ATA_PASS_THROUGH_DIRECT);  
 pATAData-\>AtaFlags = (write ? ATA_FLAGS_DATA_OUT : ATA_FLAGS_DATA_IN) | (useDMA ? ATA_FLAGS_USE_DMA : 0) | ATA_FLAGS_DRDY_REQUIRED | (nbSectors == 1 ? ATA_FLAGS_NO_MULTIPLE : 0);  
 pATAData-\>PathId = 0; // Set by the port driver  
 pATAData-\>TargetId = 0; // Set by the port driver  
 pATAData-\>Lun = 0; // Set by the port driver  
 pATAData-\>DataTransferLength = sizeBuff;  
 pATAData-\>TimeOutValue = 5; //Seconds  
 pATAData-\>DataBuffer = outBuff;  
  
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff559015%28v=vs.85%29.aspx  
 PIDEREGS pIdeRegs = (PIDEREGS) &pATAData-\>CurrentTaskFile[0];  
  
pIdeRegs-\>bFeaturesReg = 0x0; //Feature ID  
 pIdeRegs-\>bSectorCountReg = LOBYTE(LOWORD(nbSectors); //Number of sectors  
 pIdeRegs-\>bSectorNumberReg = LOBYTE(LOWORD(sectorNum.Sector));  
 pIdeRegs-\>bCylLowReg = LOBYTE(LOWORD(sectorNum.Cylinder));  
 pIdeRegs-\>bCylHighReg = HIBYTE(LOWORD(sectorNum.Cylinder));  
 pIdeRegs-\>bDriveHeadReg = LOBYTE(LOWORD(sectorNum.Head));  
 pIdeRegs-\>bCommandReg = command; //Command  
 pIdeRegs-\>bReserved = 0x0; //Res  
}  

How am I supposed to pass that CDB block? Is it the same as CurrentTaskFile?

Don’t use CHS. Look up how to use the PreviousTaskFile and CurrentTaskFile arrays to store a 48-bit LBA. Look up how to store an LBA in the CurrentTaskFile for pre-48 bit commands.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.fr
Sent: Friday, January 09, 2015 3:07 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] ATA pass through read sectors

Hello

http://msdn.microsoft.com/en-us/library/windows/hardware/ff551322(v=vs.85).aspx
I’m trying to read a few sectors with ATA pass through interface (APTI), that works when I read the MBR because we read sector 0, of size 1. So even with putting shit into the CurrentTaskFile that works because almost all the fields are 0.

Now I’m trying to read in a given place, let’s say sector 4000 (decimal) and that doesn’t work.
The definition of CurrentTaskFile isn’t the same on several places.

On MSDN it’s the following (CHS):

[quote]0 Features Register
1 Sector Count Register
2 Sector Number Register
3 Cylinder Low Register
4 Cylinder High Register
5 Device/Head Register
6 Command Register
7 Reserved[/quote]

And on a source I found: http://www.smartmontools.org/browser/trunk/smartmontools/scsiata.cpp#L229 as well as t10 documentation ftp://ftp.t10.org/t10/document.04/04-262r8.pdf
it’s using an ATA command of size 12 or 16 (while ATA_PASS_THROUGH_DIRECT structure has CurrentTaskFile of size 8), and they put LBA inside while MSDN tells to use CHS.

What is the correct way to use it?
My code:

void Disk::FillAPTI(PATA_PASS_THROUGH_DIRECT pATAData, bool write, BYTE\* outBuff, int sizeBuff, int nbSectors, int sectorOffset, CHS sectorNum, UCHAR command, bool useDMA) {  
 //http://msdn.microsoft.com/en-us/library/windows/hardware/ff551322%28v=vs.85%29.aspx  
  
//Clear the contents  
 ZeroMemory(pATAData, sizeof(ATA_PASS_THROUGH_DIRECT));  
  
// Init input / output buffs  
 ZeroMemory(outBuff, sizeBuff);  
  
//Fill in query data  
 pATAData-\>Length = sizeof(ATA_PASS_THROUGH_DIRECT);  
 pATAData-\>AtaFlags = (write ? ATA_FLAGS_DATA_OUT : ATA_FLAGS_DATA_IN) | (useDMA ? ATA_FLAGS_USE_DMA : 0) | ATA_FLAGS_DRDY_REQUIRED | (nbSectors == 1 ? ATA_FLAGS_NO_MULTIPLE : 0);  
 pATAData-\>PathId = 0; // Set by the port driver  
 pATAData-\>TargetId = 0; // Set by the port driver  
 pATAData-\>Lun = 0; // Set by the port driver  
 pATAData-\>DataTransferLength = sizeBuff;  
 pATAData-\>TimeOutValue = 5; //Seconds  
 pATAData-\>DataBuffer = outBuff;  
  
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff559015%28v=vs.85%29.aspx  
 PIDEREGS pIdeRegs = (PIDEREGS) &pATAData-\>CurrentTaskFile[0];  
  
pIdeRegs-\>bFeaturesReg = 0x0; //Feature ID  
 pIdeRegs-\>bSectorCountReg = LOBYTE(LOWORD(nbSectors); //Number of sectors  
 pIdeRegs-\>bSectorNumberReg = LOBYTE(LOWORD(sectorNum.Sector));  
 pIdeRegs-\>bCylLowReg = LOBYTE(LOWORD(sectorNum.Cylinder));  
 pIdeRegs-\>bCylHighReg = HIBYTE(LOWORD(sectorNum.Cylinder));  
 pIdeRegs-\>bDriveHeadReg = LOBYTE(LOWORD(sectorNum.Head));  
 pIdeRegs-\>bCommandReg = command; //Command  
 pIdeRegs-\>bReserved = 0x0; //Res  
}  

How am I supposed to pass that CDB block? Is it the same as CurrentTaskFile?


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Thanks, that works :slight_smile:
However, on VBox XP, if you don’t use DMA the system adds a weird padding of about 20 bytes (FF value) between each sector. Figured it out by using DMA all the time.