ATA命令设备IDENTIFY

时间:2012-10-17 20:13:42

标签: windows ssd ata

我正在尝试使用ATA_PASS_THROUGH_EX识别设备。

当我看到输出缓冲区时,它包含所有无效数据。有人可以帮我解决我做错的事吗?

#include <Windows.h>
#include <ntddscsi.h>
#include <iostream>

void main() {
    WCHAR *fileName = (WCHAR * ) "\\.\PhysicalDrive0";
    HANDLE handle = CreateFile(
       fileName, 
       GENERIC_READ | GENERIC_WRITE, //IOCTL_ATA_PASS_THROUGH requires read-write
       FILE_SHARE_READ, 
       NULL,            //no security attributes
       OPEN_EXISTING,
       0,              //flags and attributes
       NULL             //no template file
    );


    ATA_PASS_THROUGH_EX inputBuffer;
    inputBuffer.Length = sizeof(ATA_PASS_THROUGH_EX);
    inputBuffer.AtaFlags = ATA_FLAGS_DATA_IN;
    inputBuffer.DataTransferLength = 0;
    inputBuffer.DataBufferOffset = 0;

    IDEREGS *ir  = (IDEREGS *) inputBuffer.CurrentTaskFile;
    ir->bCommandReg = 0xEC; //identify device
    ir->bSectorCountReg = 1;

    unsigned int inputBufferSize = sizeof(ATA_PASS_THROUGH_EX);

    UINT8 outputBuffer[512];
    UINT32 outputBufferSize = 512;
    LPDWORD bytesReturned = 0;

    DeviceIoControl( handle, IOCTL_ATA_PASS_THROUGH_DIRECT, &inputBuffer,    inputBufferSize, &outputBuffer, outputBufferSize, bytesReturned, NULL);

    DWORD error = GetLastError();

    std::cout << outputBuffer << std::endl;
    system("pause");
}

更新: 当我检查错误值时,它是5,这意味着它是一个访问冲突。我在管理模式下运行。我做错了吗?

-Nick

1 个答案:

答案 0 :(得分:1)

我使用如下代码完成了这项工作:

int foo()
{
    int iRet( 0 );

    // Open handle to disk.
    HANDLE hDevice( ::CreateFileW( L"\\\\.\\PhysicalDrive0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ) );
    if( hDevice == INVALID_HANDLE_VALUE )
    {
        std::wcout << L"CreateFileW( " << sPath << L" ) failed.  LastError: " << GetLastError() << std::endl;
        return -1;
    }

    //
    // Use IOCTL_ATA_PASS_THROUGH
    //
    std::vector< UCHAR > vBuffer( sizeof( ATA_PASS_THROUGH_EX ) + sizeof( IDENTIFY_DEVICE_DATA ), 0 );
    PATA_PASS_THROUGH_EX pATARequest( reinterpret_cast< PATA_PASS_THROUGH_EX >( &vBuffer[0] ) );
    pATARequest->AtaFlags = ATA_FLAGS_DATA_IN | ATA_FLAGS_DRDY_REQUIRED;
    pATARequest->Length = sizeof( ATA_PASS_THROUGH_EX );
    pATARequest->DataBufferOffset = sizeof( ATA_PASS_THROUGH_EX );
    pATARequest->DataTransferLength = sizeof( IDENTIFY_DEVICE_DATA );
    pATARequest->TimeOutValue = 2;
    pATARequest->CurrentTaskFile[6] = ID_CMD;

    ULONG ulBytesRead;
    if( DeviceIoControl( hDevice, IOCTL_ATA_PASS_THROUGH, 
        &vBuffer[0], ULONG( vBuffer.size() ),
        &vBuffer[0], ULONG( vBuffer.size() ),
        &ulBytesRead, NULL ) == FALSE )
    {
        std::cout << "DeviceIoControl(IOCTL_ATA_PASS_THROUGH) failed.  LastError: " << GetLastError() << std::endl;
        iRet = -1;
    }
    else
    {
        // Fetch identity blob from output buffer.
        PIDENTIFY_DEVICE_DATA pIdentityBlob( reinterpret_cast< PIDENTIFY_DEVICE_DATA >( &vBuffer[ sizeof( ATA_PASS_THROUGH_EX ) ] ) );
    }

    CloseHandle( hDevice );

    return iRet;
}

请注意,这必须从管理员帐户或提升的上下文运行。