SCSI_PASS_THROUGH_DIRECT
时间: 2023-09-13 21:05:05 浏览: 336
引用中提到,SCSI_PASS_THROUGH_DIRECT是一个结构体,用于描述发送给U盘设备的SCSI命令。这个结构体通常作为参数传递,方便使用。在SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER结构体中,sptd是SCSI_PASS_THROUGH_DIRECT的一个成员,ucSenseBuf是一个长度为SPT_SENSE_LENGTH的数组,用于存储感知信息。
在引用中提到,Length是SCSI_PASS_THROUGH结构体的大小。
在引用中提到,PathId代表控制SCSI设备的SCSI主机适配器的总线编号。通常情况下,这个值为0,但一些SCSI主机适配器可能有多个SCSI总线。
在引用中给出了SCSI_PASS_THROUGH结构体的定义,其中包括了Length、ScsiStatus、PathId等成员。Cdb是一个长度为16的数组,用于存储SCSI命令描述符。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
相关问题
BOOL status = 0; DWORD accessMode = 0, shareMode = 0; HANDLE fileHandle = NULL; //PUCHAR dataBuffer = NULL; SCSI_PASS_THROUGH_WITH_BUFFERS sptwb; SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb; UCHAR buffer[ 2048 ]; UCHAR string[ 25 ]; ULONG length = 0, errorCode = 0; DWORD returned = 0; strcpy(string, "\\\\.\\"); strcat(string, "I:"); shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;//default accessMode = GENERIC_WRITE | GENERIC_READ;//default fileHandle = CreateFile( string, accessMode, shareMode, NULL, OPEN_EXISTING, 0, NULL ); if (fileHandle == INVALID_HANDLE_VALUE) { MessageBox(NULL, "Create file fail", "tester", MB_OK); return false; } ZeroMemory(&sptwb, sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS)); sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH); sptwb.spt.PathId = 0; sptwb.spt.TargetId = 1; sptwb.spt.Lun = 0; sptwb.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb.spt.SenseInfoLength = 24; sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN; sptwb.spt.DataTransferLength = 192; sptwb.spt.TimeOutValue = 2; sptwb.spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf); sptwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf); sptwb.spt.Cdb[0] = SCSI_OPCODE_HWTEST_COMMAND; //SCSI_OPCODE_SIGMATEL_WRITE_COMMAND;// sptwb.spt.Cdb[1] = HWTEST_DISPLAY_ID;//ALLOCATE_MEDIA; sptwb.spt.Cdb[4] = 192; length = offsetof( SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf ) + sptwb.spt.DataTransferLength; status = DeviceIoControl( fileHandle, IOCTL_SCSI_PASS_THROUGH, &sptwb, sizeof(SCSI_PASS_THROUGH), &sptwb, length, &returned, FALSE ); if (!status) { MessageBox(NULL, "Device I/0 control fail!", "tester", MB_OK); errorCode = GetLastError(); ShowMessage(IntToStr(errorCode)); PrintError(errorCode); CloseHandle(fileHandle); return false; } CloseHandle( fileHandle ); return true;
这段代码是用来打开一个名为"I:"的设备文件,并创建一个文件句柄。其中,accessMode表示文件的访问模式,shareMode表示文件的共享模式,fileHandle表示文件句柄。此外,还定义了一些变量和数组用于后续的操作。
windows下用C++实现SCSI READ一次命令读取512K数据代码
以下是一个简单的 C++ 代码示例,用于在 Windows 环境下使用 SCSI READ 命令读取 512K 数据:
```c++
#include <windows.h>
#include <winioctl.h>
#define SECTOR_SIZE 512
#define BUFFER_SIZE (SECTOR_SIZE * 1024)
int main()
{
HANDLE hDevice = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("Failed to open device, error code: %d\n", GetLastError());
return 1;
}
BYTE buffer[BUFFER_SIZE] = { 0 };
DWORD bytesReturned = 0;
STORAGE_PROPERTY_QUERY storagePropertyQuery = { 0 };
STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader = { 0 };
storagePropertyQuery.PropertyId = StorageAdapterProperty;
storagePropertyQuery.QueryType = PropertyStandardQuery;
if (!DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
&storagePropertyQuery, sizeof(storagePropertyQuery), &storageDescriptorHeader,
sizeof(storageDescriptorHeader), &bytesReturned, NULL))
{
printf("Failed to retrieve adapter property, error code: %d\n", GetLastError());
CloseHandle(hDevice);
return 1;
}
STORAGE_READ_CAPACITY readCapacity = { 0 };
if (!DeviceIoControl(hDevice, IOCTL_STORAGE_READ_CAPACITY, NULL, 0, &readCapacity,
sizeof(readCapacity), &bytesReturned, NULL))
{
printf("Failed to retrieve read capacity, error code: %d\n", GetLastError());
CloseHandle(hDevice);
return 1;
}
DWORD sectorCount = readCapacity.DiskLength.QuadPart / SECTOR_SIZE;
DWORD startingSector = 0;
if (!DeviceIoControl(hDevice, IOCTL_STORAGE_CHECK_VERIFY, NULL, 0, NULL, 0,
&bytesReturned, NULL))
{
printf("Failed to verify device, error code: %d\n", GetLastError());
CloseHandle(hDevice);
return 1;
}
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb = { 0 };
sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
sptdwb.sptd.PathId = 0;
sptdwb.sptd.TargetId = 0;
sptdwb.sptd.Lun = 0;
sptdwb.sptd.TimeOutValue = 2;
sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_IN;
sptdwb.sptd.DataTransferLength = BUFFER_SIZE;
sptdwb.sptd.DataBuffer = buffer;
sptdwb.sptd.SenseInfoLength = SPT_SENSE_LENGTH;
sptdwb.sptd.CdbLength = 10;
sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, SenseBuf);
sptdwb.sptd.Cdb[0] = 0x28; // SCSI READ command
sptdwb.sptd.Cdb[1] = 0;
sptdwb.sptd.Cdb[2] = (startingSector >> 24) & 0xFF;
sptdwb.sptd.Cdb[3] = (startingSector >> 16) & 0xFF;
sptdwb.sptd.Cdb[4] = (startingSector >> 8) & 0xFF;
sptdwb.sptd.Cdb[5] = startingSector & 0xFF;
sptdwb.sptd.Cdb[6] = 0;
sptdwb.sptd.Cdb[7] = (BUFFER_SIZE / SECTOR_SIZE) & 0xFF;
sptdwb.sptd.Cdb[8] = 0;
sptdwb.sptd.Cdb[9] = 0;
if (!DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptdwb,
sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), &sptdwb,
sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), &bytesReturned, NULL))
{
printf("Failed to execute SCSI READ command, error code: %d\n", GetLastError());
CloseHandle(hDevice);
return 1;
}
CloseHandle(hDevice);
return 0;
}
```
请注意,这只是一个简单的示例代码,可能需要根据实际情况进行更改。同时,使用 SCSI 命令需要具有足够的权限,并且必须小心谨慎,以免意外损坏设备。
阅读全文