Nikita Nikita - 11 months ago 101
C++ Question

How to get what ATA Standards are supported by HDD?

How to get ATA Standards that are supported by HDD? I'm using C++, WINAPI. I can't use WMI.

I meen these ATA Standards:

I'm already using this struct in my project: , but there no information about supported ATA standards.

I'm looking for any programm solution, I think that if need I can write to a file supported standards with other language and then read them with c++.

Answer Source

You can send 0xEC ATA command to HDD and retrieve IDENTIFY_DEVICE_DATA structure, which contain information about your HDD. It requires irb.h library include from WDK (Windows Driver Kit).

BOOL getAtaCompliance() { 
  DWORD dwBytes;
  BOOL  bResult;

  CONST UINT bufferSize = 512;
  CONST BYTE identifyDataCommandId =  0xEC;

  UCHAR identifyDataBuffer[bufferSize
        + sizeof(ATA_PASS_THROUGH_EX)] = { 0 };

  ATA_PASS_THROUGH_EX & PTE = *(ATA_PASS_THROUGH_EX *) identifyDataBuffer;
  PTE.Length = sizeof(PTE);
  PTE.TimeOutValue = 10;
  PTE.DataTransferLength = 512;
  PTE.DataBufferOffset = sizeof(ATA_PASS_THROUGH_EX);

  IDEREGS * ideRegs = (IDEREGS *) PTE.CurrentTaskFile;
  ideRegs->bCommandReg = identifyDataCommandId;
  ideRegs->bSectorCountReg = 1;


  bResult = DeviceIoControl(hDevice, IOCTL_ATA_PASS_THROUGH, &PTE,
                      sizeof(identifyDataBuffer), &PTE,
                      sizeof(identifyDataBuffer), &dwBytes, 0);

  if (bResult == FALSE) {
    std::cout << "Oops, something went wrong, error code: "
              << GetLastError() << std::endl;
    return bResult;

  WORD *data = (WORD *)(identifyDataBuffer + sizeof(ATA_PASS_THROUGH_EX));

  int16_t ataSupportBits = data[80];

  return bResult;

ataSupportBits will contain 16 bits about supported ATA standarts. From Information technology - AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)

word #80, ATA/ATAPI Compliance bitmap