IOCTL_ATA_PASS_THROUGH的使用

IOCTL_ATA_PASS_THROUGH的使用

控制代码功能:像ATA硬盘发送ATA指令。
IDE/ATA:接口,一个串行,一个并行,一般叫做IDE接口的硬盘和ATA接口的硬盘。
ATA指令:可以操作ATA硬盘的指令,
常用ATAPI指令介绍:
IDENTIFYDEVICE 0xec
READSECTOR 0x20
READMULTIPLE 0xc4
READDMA 0xc8
WRITESECTOR 0x30
WRITEMULTIPLE 0xc5
WRITEDMA 0xca
SETFEATURES 0xef


typedef struct _ATA_PASS_THROUGH_EX {
USHORT Length;	
USHORT AtaFlags;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR ReservedAsUchar;
ULONG DataTransferLength;
ULONG TimeOutValue;
ULONG ReservedAsUlong;
ULONG_PTR DataBufferOffset;
UCHAR PreviousTaskFile[8];
UCHAR CurrentTaskFile[8];
} ATA_PASS_THROUGH_EX, *PATA_PASS_THROUGH_EX;//对应的结构体

Length
Specifies the length in bytes of the ATA_PASS_THROUGH_EX structure.
结构体的大小
AtaFlags
Indicates the direction of data transfer and specifies the kind of operation to be performed. The value of this member must be some combination of the following flags:
ATA flags Meaning
ATA_FLAGS_DRDY_REQUIRED Wait for DRDY status from the device before sending the command to the device.
ATA_FLAGS_DATA_IN Read data from the device.
ATA_FLAGS_DATA_OUT Write data to the device.
ATA_FLAGS_48BIT_COMMAND The ATA command to be sent uses the 48-bit logical block address (LBA) feature set. When this flag is set, the contents of the PreviousTaskFile member in the ATA_PASS_THROUGH_EX structure should be valid.
ATA_FLAGS_USE_DMA Set the transfer mode to DMA.
ATA_FLAGS_NO_MULTIPLE Read single sector only.
 读写标志
PathId
Contains an integer that indicates the IDE port or bus for the request. This value is set by the port driver.
TargetId
Contains an integer that indicates the target device on the bus. This value is set by the port driver.
Lun
Indicates the logical unit number of the device. This value is set by the port driver.
这三个值会在分区位置显示。

ReservedAsUchar
Reserved for future use.
DataTransferLength
Indicates the size, in bytes, of the data buffer. If an underrun occurs, the miniport driver must update this member to the number of bytes that were actually transferred.
通信的数据的总大小
TimeOutValue
Indicates the number of seconds that are allowed for the request to execute before the OS-specific port driver determines that the request has timed out.
超时时间
ReservedAsUlong
Reserved for future use.
DataBufferOffset
Specifies the offset, in bytes, from the beginning of this structure to the data buffer.
|-----------------|-----------------------------                                                 这个值为开始数据到传送BUFF的大小,也就是结构体的大小。
     结构体的大小       需要传送的BUFF大小
PreviousTaskFile
Specifies the contents of the task file input registers prior to the current pass-through command. This member is not used when the ATA_FLAGS_48BIT_COMMAND flag is not set.
CurrentTaskFile
Specifies the content of the task file register on both input and output. On input, the array values in  CurrentTaskFile  map to the task file input registers in the following manner.
各个寄存器
Byte Input Register
0 Features register
1 Sector count register
2 Sector number register
3 Cylinder low register
4 Cylinder high register
5 Device/head register
6 Command register
7 Reserved
 
When  IOCTL_ATA_PASS_THROUGH  completes, the port driver updates  CurrentTaskFile  with the values that are present in the device's output registers at the completion of the embedded command. The array values in  CurrentTaskFile  correspond to the following task file output registers.
Byte Output Register
0 Error register
1 Sector count register
2 Sector number register
3 Cylinder low register
4 Cylinder high register
5 Device/head register
6 Status register
7 Reserved


#include "stdafx.h"
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <tchar.h>
#include <winioctl.h>
#include <ntddscsi.h>


// 以CreateFile方式读取扇区开关
//#define SECTOR 

VOID __cdecl _tmain (INT Argc, _TCHAR *Argv[])
{
int i = 0;


HANDLE hDevice = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ|GENERIC_WRITE, 
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("CreateFile Error\n");
DWORD ret = GetLastError();
printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%x\n",ret);
scanf("%d",&i);
goto error_return;
}
// 这一步是成功的,我可以打开Port 


void* AtaPassThroughExBufferIn = (void*)malloc(sizeof(ATA_PASS_THROUGH_EX));
if (AtaPassThroughExBufferIn == NULL){
printf("IN buffer Error\n");
return ;
}
memset(AtaPassThroughExBufferIn, 0, sizeof(ATA_PASS_THROUGH_EX));
void *AtaPassThroughExBufferOut = (void *)malloc(sizeof(ATA_PASS_THROUGH_EX)+512);
if (AtaPassThroughExBufferOut == NULL){
printf("IN buffer Error\n");
return ;
}
memset(AtaPassThroughExBufferOut, 0, sizeof(ATA_PASS_THROUGH_EX) +512);


ATA_PASS_THROUGH_EX *inputBuffer = ( ATA_PASS_THROUGH_EX * )AtaPassThroughExBufferIn;
ATA_PASS_THROUGH_EX *outputBuffer = ( ATA_PASS_THROUGH_EX * )AtaPassThroughExBufferOut;


inputBuffer->Length = sizeof(ATA_PASS_THROUGH_EX); 
inputBuffer->AtaFlags = ATA_FLAGS_DATA_IN|ATA_FLAGS_NO_MULTIPLE; 
inputBuffer->DataTransferLength = 0; // 1 sector 
inputBuffer->DataBufferOffset = sizeof(ATA_PASS_THROUGH_EX); 




outputBuffer->Length = sizeof(ATA_PASS_THROUGH_EX); 
outputBuffer->AtaFlags = ATA_FLAGS_DATA_OUT; 
outputBuffer->DataTransferLength = 512; // 1 sector 
outputBuffer->DataBufferOffset = sizeof(ATA_PASS_THROUGH_EX); 




//memset(inputBuffer->CurrentTaskFile,0,sizeof(inputBuffer->CurrentTaskFile));
//memset(inputBuffer->PreviousTaskFile,0,sizeof(inputBuffer->PreviousTaskFile));
//inputBuffer->CurrentTaskFile[5] = 0xA0; // Identify Device
//inputBuffer->CurrentTaskFile[6] = 0xEC; // Identify Device




inputBuffer->CurrentTaskFile[0] = 0; // feature reg 
inputBuffer->CurrentTaskFile[1] = 1; // sector count reg 
inputBuffer->CurrentTaskFile[2] = 1; // sector number reg 
inputBuffer->CurrentTaskFile[3] = 1; // cyl low reg 
inputBuffer->CurrentTaskFile[4] = 1; // cyl high reg 
inputBuffer->CurrentTaskFile[5] = 0x0; // device reg 
inputBuffer->CurrentTaskFile[6] = 0x20; // commang reg 
inputBuffer->CurrentTaskFile[7] = 0; 
//操作哪个扇区,多少 等信息

/*inputBuffer->CurrentTaskFile[1] = 1;
inputBuffer->CurrentTaskFile[3] = inputBuffer->CurrentTaskFile[4] = 0;
inputBuffer->CurrentTaskFile[6] = 0xEC;*/


DWORD returned = 0;
BOOL status; 
status = DeviceIoControl(hDevice, 
IOCTL_ATA_PASS_THROUGH, 
inputBuffer, 
sizeof(ATA_PASS_THROUGH_EX), 
AtaPassThroughExBufferOut, 
sizeof(ATA_PASS_THROUGH_EX) + 512, 
&returned, 
NULL); 






if(status == 0) { 
ULONG errorcode = GetLastError();
status = GetLastError();
printf("status:%d,%x\n",status,outputBuffer->CurrentTaskFile[0]);
} 








/*
struct ATA_PASS_THROUGH_EX_WITH_BUFFERS
{
ATA_PASS_THROUGH_EX apt;
BYTE ucDataBuf[512];
};


ATA_PASS_THROUGH_EX_WITH_BUFFERS ab;


memset(&ab, 0, sizeof(ab));
ab.apt.Length = sizeof(ATA_PASS_THROUGH_EX);
ab.apt.TimeOutValue = 10;
unsigned size = sizeof(ATA_PASS_THROUGH_EX_WITH_BUFFERS) + 512;
ab.apt.DataBufferOffset = size;
ab.apt.AtaFlags = ATA_FLAGS_DATA_IN;
ab.apt.DataTransferLength = 512;
size = 512;
ab.ucDataBuf[0] = 0xcf;
ab.apt.CurrentTaskFile[1] = 1;
ab.apt.CurrentTaskFile[3] = ab.apt.CurrentTaskFile[4] = 0;
ab.apt.CurrentTaskFile[6] = 0xEC;


DWORD rByte = 0;
DWORD status = DeviceIoControl( hDevice,
IOCTL_ATA_PASS_THROUGH,
&ab,
size,
&ab,
size,
&rByte,
NULL);
if (status == 0)
{
status = GetLastError();
printf("%d, %x\n", status, ab.apt.CurrentTaskFile);
}
*/








error_return:
scanf("%d",&i);
return;
}





Length
Specifies the length in bytes of the ATA_PASS_THROUGH_EX structure.
结构体的大小
AtaFlags
Indicates the direction of data transfer and specifies the kind of operation to be performed. The value of this member must be some combination of the following flags:
ATA flags Meaning
ATA_FLAGS_DRDY_REQUIRED Wait for DRDY status from the device before sending the command to the device.
ATA_FLAGS_DATA_IN Read data from the device.
ATA_FLAGS_DATA_OUT Write data to the device.
ATA_FLAGS_48BIT_COMMAND The ATA command to be sent uses the 48-bit logical block address (LBA) feature set. When this flag is set, the contents of the PreviousTaskFile member in the ATA_PASS_THROUGH_EX structure should be valid.
ATA_FLAGS_USE_DMA Set the transfer mode to DMA.
ATA_FLAGS_NO_MULTIPLE Read single sector only.
 读写标志
PathId
Contains an integer that indicates the IDE port or bus for the request. This value is set by the port driver.
TargetId
Contains an integer that indicates the target device on the bus. This value is set by the port driver.
Lun
Indicates the logical unit number of the device. This value is set by the port driver.
这三个值会在分区位置显示。
ReservedAsUchar
Reserved for future use.
DataTransferLength
Indicates the size, in bytes, of the data buffer. If an underrun occurs, the miniport driver must update this member to the number of bytes that were actually transferred.
通信的数据的总大小
TimeOutValue
Indicates the number of seconds that are allowed for the request to execute before the OS-specific port driver determines that the request has timed out.
超时时间
ReservedAsUlong
Reserved for future use.
DataBufferOffset
Specifies the offset, in bytes, from the beginning of this structure to the data buffer.
|-----------------|-----------------------------                                                 这个值为开始数据到传送BUFF的大小,也就是结构体的大小。
     结构体的大小       需要传送的BUFF大小
PreviousTaskFile
Specifies the contents of the task file input registers prior to the current pass-through command. This member is not used when the ATA_FLAGS_48BIT_COMMAND flag is not set.
CurrentTaskFile
Specifies the content of the task file register on both input and output. On input, the array values in  CurrentTaskFile  map to the task file input registers in the following manner.
各个寄存器
Byte Input Register
0 Features register
1 Sector count register
2 Sector number register
3 Cylinder low register
4 Cylinder high register
5 Device/head register
6 Command register
7 Reserved
 
When  IOCTL_ATA_PASS_THROUGH  completes, the port driver updates  CurrentTaskFile  with the values that are present in the device's output registers at the completion of the embedded command. The array values in  CurrentTaskFile  correspond to the following task file output registers.
Byte Output Register
0 Error register
1 Sector count register
2 Sector number register
3 Cylinder low register
4 Cylinder high register
5 Device/head register
6 Status register
7 Reserved
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘仕豪

IT发展快就是因为有开源精神

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值