c++windowsioctlata

How is IOCTL_ATA_PASS_THROUGH used?


I've been working on creating a program to send (preferrably arbitrary) ATA commands, and so far, the only option I've found in Windows is IOCTL_ATA_PASS_THROUGH and a related struct, ATA_PASS_THROUGH_EX using C++.

Unfortunately, I've been finding the documentation to be lacking for those who don't already know what they're doing. Here's what I haven't figured out:


Solution

  • This is a little too long for a comment, so I'm posting it as an answer, but please be aware that it is largely educated guesswork.

    How is IOCTL_ATA_PASS_THROUGH used in a statement?

    This one's easy. Like all control codes, it is sent using the DeviceIoControl function.

    Where do you put the ATA command to send?

    I'm unfamiliar with ATA, but my guess is the "command register", i.e., CurrentTaskFile[6]. I imagine that you could find some documentation on the ATA protocol that should clear this up.

    ATA_PASS_THROUGH_EX.DataTransferLength should be the size of the data buffer, in bytes. Is that the struct + the ATA command, or just the command?

    The documentation says

    If the embedded ATA command is a write operation, the size of the input buffer should be the sum of sizeof(ATA_PASS_THROUGH_EX) and the value in the DataTransferLength member of ATA_PASS_THROUGH_EX.

    So DataTransferLength definitely does not include the length of the ATA_PASS_THROUGH_EX structure.

    How do you select which drive the command is going to?

    Presumably this is determined by the device handle that you pass to DeviceIoControl().

    Where does the response from the drive go?

    Into the DeviceIoControl() output buffer.