使用IOCTL_SCSI_PASS_THROUGH_DIRECT获取硬盘的名称
2021-09-07
206
0
Windows下的物理磁盘名称被命名为PhysicalDrive0~N
可以通过IOCTL_SCSI_PASS_THROUGH_DIRECT获取该磁盘的名称
BOOL CDisk::GetDiskNameById(int nId, TCHAR* pName)
{
TCHAR buff[512];
_stprintf_s(buff, TEXT("\\\\.\\PhysicalDrive%d"), nId);
HANDLE hDevice = CreateFile(buff, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
return FALSE;
}
#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER
#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
typedef struct _SCSI_PASS_THROUGH_DIRECT {
USHORT Length;
UCHAR ScsiStatus;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR CdbLength;
UCHAR SenseInfoLength;
UCHAR DataIn;
ULONG DataTransferLength;
ULONG TimeOutValue;
PVOID DataBuffer;
ULONG SenseInfoOffset;
UCHAR Cdb[16];
}SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
SCSI_PASS_THROUGH_DIRECT sc;
memset(&sc, 0, sizeof(SCSI_PASS_THROUGH_DIRECT));
sc.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
sc.CdbLength = 16;
sc.DataIn = 1;
sc.DataTransferLength = 64;
sc.TimeOutValue = 2;
sc.Cdb[0] = 0x12;
sc.Cdb[4] = 0x40;
sc.DataBuffer = (PVOID)buff;
ULONG d;
memset(buff, 0, sizeof(buff));
BOOL ok = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sc, sizeof(sc), &sc, sizeof(sc), &d, NULL);
if (!ok)
{
CloseHandle(hDevice);
return FALSE;
}
CHAR* p = (CHAR*)buff + 8;
for (unsigned int i = 0; i < strlen(p); i++)
{
pName[i] = p[i];
}
CloseHandle(hDevice);
return TRUE;
}