Link to home
Start Free TrialLog in
Avatar of SITPL
SITPL

asked on

Problem to read sector of hard disk via extended ATA commands

I am using extended ATA commands to read Disk drive(SSD or HDD both).
I have been read out many document based on ATA commands and finaly write a code to send extended commands to my disk.
I am using extended because i have to read out large disk like upto 4 TB using LBA addressing.

BOOL status = FALSE;
PATA_PASS_THROUGH_EX pATAData;
DWORD dataSize = sizeof(ATA_PASS_THROUGH_EX) + 512;
BYTE Buffer[sizeof(ATA_PASS_THROUGH_EX) + 512];
DWORD bytescopied = 0;

pATAData = (ATA_PASS_THROUGH_EX*)Buffer;

ZeroMemory(pATAData,dataSize); // clears the buffer

pATAData->Length = sizeof(ATA_PASS_THROUGH_EX);
pATAData->DataBufferOffset = sizeof(ATA_PASS_THROUGH_EX);
pATAData->DataTransferLength = 512;
pATAData->TimeOutValue = 2;

pATAData->CurrentTaskFile[0] = 0x00;
pATAData->CurrentTaskFile[1] = 0x01;         // want to read one sector only
pATAData->CurrentTaskFile[2] = 0x01;         // wnat to read 1st sector
pATAData->CurrentTaskFile[3] = 0x00;
pATAData->CurrentTaskFile[4] = 0x00;
pATAData->CurrentTaskFile[5] = 0x40;         // to support LBA addressing mode
pATAData->CurrentTaskFile[6] = 0x24; 
pATAData->CurrentTaskFile[7]=  0x00;
pATAData->AtaFlags =ATA_FLAGS_48BIT_COMMAND;  

pATAData->PreviousTaskFile[0] = 0x00;
pATAData->PreviousTaskFile[1] = 0x00;
pATAData->PreviousTaskFile[2] = 0x00;
pATAData->PreviousTaskFile[3] = 0x00;
pATAData->PreviousTaskFile[4] = 0x00;
pATAData->PreviousTaskFile[5] = 0x04;
pATAData->PreviousTaskFile[6] = 0x00;
pATAData->PreviousTaskFile[7]=  0x00;

 // command Read Sector(s) Ext(0x24)
/* sends the command to the device, **hDevice** is device handle*/
status = DeviceIoControl(hDevice, IOCTL_ATA_PASS_THROUGH, pATAData, dataSize,Buffer, dataSize, &bytescopied, NULL );

Open in new window


This is the code to read from disk, but it is not working. Function DeviceIoControl() return TRUE but it does not read any data from the disk, output buffer is empty.

The "Status" register (CurrentTaskFile[7] and "Error" register (CurrentTaskFile[0]) both are zero , no error returned.

Everything looks like ok but its not reading data from disk and i am unable to fine out what's wrong in this code.

Kindly provide a solution.

Thank You
ASKER CERTIFIED SOLUTION
Avatar of David
David
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of SITPL
SITPL

ASKER

Thanks for your support.

Now my code is working but there is a small problem. I am unable to read or write more than 256 sectors in one call. Below 256 sector it works.

Kindly read the details:

When I am trying to pass an ATA command call for a data transfer of  > 256 sectors (512 Byte sectors), Through ATA_PASS_THORUGH_EXT struct, here i am sending the ATA 48 Bit(Extended) commands , in that it provides a 16 bit field (8 bit Current and 8 bit Previous reg) for Sector Count and ATA devices support sector counts for Read and Write "extended" (48 bit) commands up to 65536 sector.

Command that i am sending for transfer is WRITE MULTIPLE EXT(0x39),READ MULTIPLE EXT(0x29).

The DeviceIOControl function test program compiles fine, but it returns 0 when i want to transfer more than 256 sectors. If I set the data transfer length and Sector Count registers to 256 or less, it works.

Kindly help me.

Thanks
There is a max sector count that is controller/driver specific.  256 MAY be the limit for what you are using.   Other things, make sure the buffer you are using is aligned in memory. Windows has some form of an alloc command that lets you align in memory, sorry, can't remember what it is, but it is vital.

There is also a max limit on passthrough for the various forms of IOCTL for pass-through.   You'll have to see what the are.
But bottom line, 256 sectors MAY be the limit for your controller.  When I wrote ATA pass-through  years ago, i capped it at 256 because that was the limit that always worked no matter what hardware I used.
Avatar of SITPL

ASKER

Here I am confused. I just want to know the limit of controller where belongs.

Is it related to machine or Hard disk or Windows 7 OS or ATA command library?

Also Is there any way to increase this limit? like using latest ATA commands...


Thanks
The limit of # of blocks is a function of both the hardware controller and the device driver.  Whatever the limit is ... you're stuck with it.