天天看点

如何通过IOCTL_ATA_PASS_THROUGH发送ATA命令并获取ASTS(ATA task file status)

如何发送ATA cmd?如何发送ATA cmd后如何获取ASTS状态?

如何通过IOCTL_ATA_PASS_THROUGH发送ATA命令并获取ASTS(ATA task file status)

发送了fd命令后想获取这里固件返回的ASTS里面的数据,该怎么做呢?

直接上代码:

HANDLE GetIoCtrlHandle(BYTE index)
{
	char szDevicPath[255]={0};
	sprintf(szDevicPath,"\\\\.\\PhysicalDrive%d", index);
	return ::CreateFile(szDevicPath, GENERIC_READ | GENERIC_WRITE, 
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL, OPEN_EXISTING, 0, NULL);
}

BOOL SendAtaCommand(INT physicalDriveId, BYTE cmd)
{
	BOOL	bRet;
	HANDLE	hIoCtrl;
	DWORD	dwReturned;

	hIoCtrl = GetIoCtrlHandle(physicalDriveId);
	if (hIoCtrl == INVALID_HANDLE_VALUE)
	{
		return	FALSE;
	}

	ATA_PASS_THROUGH_EX_WITH_BUFFERS ab;
	::ZeroMemory(&ab, sizeof(ab));
	ab.Apt.Length = sizeof(ATA_PASS_THROUGH_EX);
	ab.Apt.TimeOutValue = 2;
	DWORD size = offsetof(ATA_PASS_THROUGH_EX_WITH_BUFFERS, Buf);
	ab.Apt.DataBufferOffset = size;

    //以下参数按具体需求填充,CurrentTaskFile结构体共8个字节
	ab.Apt.CurrentTaskFile.bFeaturesReg = 0x04;
	ab.Apt.CurrentTaskFile.bSectorCountReg = 0;
	ab.Apt.CurrentTaskFile.bDriveHeadReg = cmd;
	ab.Apt.CurrentTaskFile.bCommandReg = cmd;

    bRet = ::DeviceIoControl(hIoCtrl, IOCTL_ATA_PASS_THROUGH,
			&ab, size, &ab, size, &dwReturned, NULL);
		::CloseHandle(hIoCtrl);
		
	if(pout != NULL){
        //此时ab.Apt.CurrentTaskFile里存储的数据即是ASTS 
	}

	return	bRet;
}           

继续阅读