我正在尝试使用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
答案 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;
}
请注意,这必须从管理员帐户或提升的上下文运行。