2012-10-17 1 views
0

J'essaie d'identifier un périphérique en utilisant ATA_PASS_THROUGH_EX.Dispositif de commande ATA IDENTIFY

Lorsque je vois le tampon de sortie, il contient toutes les données non valides. Quelqu'un peut-il m'aider à ce que je fais mal?

#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"); 
} 

mise à jour: Quand je vérifie la valeur d'erreur, il est 5, ce qui signifie qu'il est une violation d'accès. Je cours en mode admin. Est-ce que je fais quelque chose de mal?

-Nick

+0

Je suis arrivé ce code d'ici .. http://stackoverflow.com/questions/5070987/sending-ata-commands-directly-to-device-in-windows?rq=1 – Nick

+0

Une poignée est de ne pas créé? Donc, quelque chose doit être faux là .. – Nick

+0

Vous ne vérifiez jamais la valeur de retour de 'CreateFile()'. Qu'est-ce que 'handle' après cet appel? –

Répondre

1

Je l'ai fait en utilisant le code qui ressemble à ceci:

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; 
} 

Notez que cela doit être exécuté à partir d'un compte administrateur ou d'un contexte élevé.

+0

hey .. merci. Je ne peux pas sembler ajouter le fichier d'en-tête ata.h ou irb.h. Une idée pourquoi? J'utilise win 7, VS. – Nick

+1

Ces en-têtes font partie de Windows DDK, que vous pouvez télécharger à partir de MSDN. – Bukes

Questions connexes