本文主要是介绍读取USB HDD(USB移动硬盘信息)序列号的代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
读取USB HDD(USB移动硬盘)序列号的代码,型号及分位。
使用Visual Studio 2010编译成功。
代码使用了CrystalDiskInfo中的代码smartata.c中相关代码:
如下的连接解释了为何使用scsi的相关代码,需要USB IC的数据转换。
http://blog.csdn.net/waityoualife/article/details/5656589
实现代码如下:
// DiskInfo.cpp : Defines the entry point for the console application.
//#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winioctl.h>
#include <stddef.h>
#include <memory.h>#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)typedef struct _IDENTIFY_DEVICE{WORD GeneralConfiguration; //0WORD LogicalCylinders; //1 ObsoleteWORD SpecificConfiguration; //2WORD LogicalHeads; //3 ObsoleteWORD Retired1[2]; //4-5WORD LogicalSectors; //6 ObsoleteDWORD ReservedForCompactFlash; //7-8WORD Retired2; //9CHAR SerialNumber[20]; //10-19WORD Retired3; //20WORD BufferSize; //21 Obsolete
// WORD Obsolute4; //22CHAR FirmwareRev[8]; //23-26CHAR Model[40]; //27-46WORD MaxNumPerInterupt; //47WORD Reserved1; //48WORD Capabilities1; //49WORD Capabilities2; //50DWORD Obsolute5; //51-52WORD Field88and7064; //53WORD Obsolute6[5]; //54-58WORD MultSectorStuff; //59DWORD TotalAddressableSectors; //60-61WORD Obsolute7; //62WORD MultiWordDma; //63WORD PioMode; //64WORD MinMultiwordDmaCycleTime; //65WORD RecommendedMultiwordDmaCycleTime; //66WORD MinPioCycleTimewoFlowCtrl; //67WORD MinPioCycleTimeWithFlowCtrl; //68WORD Reserved2[6]; //69-74WORD QueueDepth; //75WORD SerialAtaCapabilities; //76WORD SerialAtaAdditionalCapabilities; //77WORD SerialAtaFeaturesSupported; //78WORD SerialAtaFeaturesEnabled; //79WORD MajorVersion; //80WORD MinorVersion; //81WORD CommandSetSupported1; //82WORD CommandSetSupported2; //83WORD CommandSetSupported3; //84WORD CommandSetEnabled1; //85WORD CommandSetEnabled2; //86WORD CommandSetDefault; //87WORD UltraDmaMode; //88WORD TimeReqForSecurityErase; //89WORD TimeReqForEnhancedSecure; //90WORD CurrentPowerManagement; //91WORD MasterPasswordRevision; //92WORD HardwareResetResult; //93WORD AcoustricManagement; //94WORD StreamMinRequestSize; //95WORD StreamingTimeDma; //96WORD StreamingAccessLatency; //97DWORD StreamingPerformance; //98-99ULONGLONG MaxUserLba; //100-103WORD StremingTimePio; //104WORD Reserved3; //105WORD SectorSize; //106WORD InterSeekDelay; //107WORD IeeeOui; //108WORD UniqueId3; //109WORD UniqueId2; //110WORD UniqueId1; //111WORD Reserved4[4]; //112-115WORD Reserved5; //116DWORD WordsPerLogicalSector; //117-118WORD Reserved6[8]; //119-126WORD RemovableMediaStatus; //127WORD SecurityStatus; //128WORD VendorSpecific[31]; //129-159WORD CfaPowerMode1; //160WORD ReservedForCompactFlashAssociation[7]; //161-167WORD DeviceNominalFormFactor; //168WORD DataSetManagement; //169WORD AdditionalProductIdentifier[4]; //170-173WORD Reserved7[2]; //174-175CHAR CurrentMediaSerialNo[60]; //176-205WORD SctCommandTransport; //206WORD ReservedForCeAta1[2]; //207-208WORD AlignmentOfLogicalBlocks; //209DWORD WriteReadVerifySectorCountMode3; //210-211DWORD WriteReadVerifySectorCountMode2; //212-213WORD NvCacheCapabilities; //214DWORD NvCacheSizeLogicalBlocks; //215-216WORD NominalMediaRotationRate; //217WORD Reserved8; //218WORD NvCacheOptions1; //219WORD NvCacheOptions2; //220WORD Reserved9; //221WORD TransportMajorVersionNumber; //222WORD TransportMinorVersionNumber; //223WORD ReservedForCeAta2[10]; //224-233WORD MinimumBlocksPerDownloadMicrocode; //234WORD MaximumBlocksPerDownloadMicrocode; //235WORD Reserved10[19]; //236-254WORD IntegrityWord; //255
}IDENTIFY_DEVICE;typedef enum _COMMAND_TYPE{CMD_TYPE_PHYSICAL_DRIVE = 0,CMD_TYPE_SCSI_MINIPORT,CMD_TYPE_SILICON_IMAGE,CMD_TYPE_SAT, // SAT = SCSI_ATA_TRANSLATIONCMD_TYPE_SUNPLUS,CMD_TYPE_IO_DATA,CMD_TYPE_LOGITEC,CMD_TYPE_JMICRON,CMD_TYPE_CYPRESS,CMD_TYPE_PROLIFIC, // Not imprementCMD_TYPE_CSMI, // CSMI = Common Storage Management InterfaceCMD_TYPE_CSMI_PHYSICAL_DRIVE, // CSMI = Common Storage Management Interface CMD_TYPE_WMI,CMD_TYPE_DEBUG
}COMMAND_TYPE;// retrieve the properties of a storage device or adapter.
typedef enum _STORAGE_QUERY_TYPE {PropertyStandardQuery = 0,PropertyExistsQuery,PropertyMaskQuery,PropertyQueryMaxDefined
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;// retrieve the properties of a storage device or adapter.typedef struct _STORAGE_PROPERTY_QUERY {STORAGE_PROPERTY_ID PropertyId;STORAGE_QUERY_TYPE QueryType;UCHAR AdditionalParameters[1];
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;#define FILE_DEVICE_SCSI 0x0000001b
#define IOCTL_SCSI_MINIPORT_IDENTIFY ((FILE_DEVICE_SCSI << 16) + 0x0501)
#define IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS ((FILE_DEVICE_SCSI << 16) + 0x0502)
#define IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS ((FILE_DEVICE_SCSI << 16) + 0x0503)
#define IOCTL_SCSI_MINIPORT_ENABLE_SMART ((FILE_DEVICE_SCSI << 16) + 0x0504)
#define IOCTL_SCSI_MINIPORT_DISABLE_SMART ((FILE_DEVICE_SCSI << 16) + 0x0505)#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER
#define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)//
// Define values for pass-through DataIn field.
//
#define SCSI_IOCTL_DATA_OUT 0
#define SCSI_IOCTL_DATA_IN 1
#define SCSI_IOCTL_DATA_UNSPECIFIED 2//
// Define the SCSI pass through structure.
//
typedef struct _SCSI_PASS_THROUGH {USHORT Length;UCHAR ScsiStatus;UCHAR PathId;UCHAR TargetId;UCHAR Lun;UCHAR CdbLength;UCHAR SenseInfoLength;UCHAR DataIn;ULONG DataTransferLength;ULONG TimeOutValue;ULONG_PTR DataBufferOffset;ULONG SenseInfoOffset;UCHAR Cdb[16];
}SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS {
SCSI_PASS_THROUGH Spt;
ULONG Filler; // realign buffers to double word boundary
UCHAR SenseBuf[32];
UCHAR DataBuf[512];
} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS;static void dump_buffer(const char* title, const unsigned char* buffer, int len)
{int i = 0;int j;printf ("\n-- %s --\n", title);if (len > 0){printf ("%8.8s ", " ");for (j = 0; j < 16; ++j){printf (" %2X", j);}printf (" ");for (j = 0; j < 16; ++j){printf ("%1X", j);}printf ("\n");}while (i < len){printf("%08x ", i);for (j = 0; j < 16; ++j){if ((i + j) < len)printf (" %02x", (int) buffer[i +j]);elseprintf (" ");}printf (" ");for (j = 0; j < 16; ++j){if ((i + j) < len)printf ("%c", isprint (buffer[i + j]) ? buffer [i + j] : '.');elseprintf (" ");}printf ("\n");i += 16;}printf ("-- DONE --\n");
}void ChangeByteOrder(PCHAR szString, USHORT uscStrSize)
{USHORT i;CHAR temp;for (i = 0; i < uscStrSize; i+=2){temp = szString[i];szString[i] = szString[i+1];szString[i+1] = temp;}
}BOOL DoIdentifyDeviceSat(HANDLE physicalDriveId, BYTE target, IDENTIFY_DEVICE* data, COMMAND_TYPE type)
{BOOL bRet;HANDLE hIoCtrl;DWORD dwReturned;DWORD length;SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;if(data == NULL){printf("Data\n");return FALSE;}ZeroMemory(data, sizeof(IDENTIFY_DEVICE));hIoCtrl = physicalDriveId;if(hIoCtrl == INVALID_HANDLE_VALUE){printf("Handle\n");return FALSE;}ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));sptwb.Spt.Length = sizeof(SCSI_PASS_THROUGH);sptwb.Spt.PathId = 0;sptwb.Spt.TargetId = 0;sptwb.Spt.Lun = 0;sptwb.Spt.SenseInfoLength = 24;sptwb.Spt.DataIn = SCSI_IOCTL_DATA_IN;sptwb.Spt.DataTransferLength = IDENTIFY_BUFFER_SIZE;sptwb.Spt.TimeOutValue = 2;sptwb.Spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, DataBuf);sptwb.Spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, SenseBuf);if(type == CMD_TYPE_SAT){sptwb.Spt.CdbLength = 12;sptwb.Spt.Cdb[0] = 0xA1;//ATA PASS THROUGH(12) OPERATION CODE(A1h)sptwb.Spt.Cdb[1] = (4 << 1) | 0; //MULTIPLE_COUNT=0,PROTOCOL=4(PIO Data-In),Reservedsptwb.Spt.Cdb[2] = (1 << 3) | (1 << 2) | 2;//OFF_LINE=0,CK_COND=0,Reserved=0,T_DIR=1(ToDevice),BYTE_BLOCK=1,T_LENGTH=2sptwb.Spt.Cdb[3] = 0;//FEATURES (7:0)sptwb.Spt.Cdb[4] = 1;//SECTOR_COUNT (7:0)sptwb.Spt.Cdb[5] = 0;//LBA_LOW (7:0)sptwb.Spt.Cdb[6] = 0;//LBA_MID (7:0)sptwb.Spt.Cdb[7] = 0;//LBA_HIGH (7:0)sptwb.Spt.Cdb[8] = target;sptwb.Spt.Cdb[9] = 0xEC;//COMMAND}else if(type == CMD_TYPE_SUNPLUS){sptwb.Spt.CdbLength = 12;sptwb.Spt.Cdb[0] = 0xF8;sptwb.Spt.Cdb[1] = 0x00;sptwb.Spt.Cdb[2] = 0x22;sptwb.Spt.Cdb[3] = 0x10;sptwb.Spt.Cdb[4] = 0x01;sptwb.Spt.Cdb[5] = 0x00; sptwb.Spt.Cdb[6] = 0x01; sptwb.Spt.Cdb[7] = 0x00; sptwb.Spt.Cdb[8] = 0x00;sptwb.Spt.Cdb[9] = 0x00;sptwb.Spt.Cdb[10] = target; sptwb.Spt.Cdb[11] = 0xEC; // ID_CMD}else if(type == CMD_TYPE_IO_DATA){sptwb.Spt.CdbLength = 12;sptwb.Spt.Cdb[0] = 0xE3;sptwb.Spt.Cdb[1] = 0x00;sptwb.Spt.Cdb[2] = 0x00;sptwb.Spt.Cdb[3] = 0x01;sptwb.Spt.Cdb[4] = 0x01;sptwb.Spt.Cdb[5] = 0x00; sptwb.Spt.Cdb[6] = 0x00; sptwb.Spt.Cdb[7] = target;sptwb.Spt.Cdb[8] = 0xEC; // ID_CMDsptwb.Spt.Cdb[9] = 0x00;sptwb.Spt.Cdb[10] = 0x00; sptwb.Spt.Cdb[11] = 0x00;}else if(type == CMD_TYPE_LOGITEC){sptwb.Spt.CdbLength = 10;sptwb.Spt.Cdb[0] = 0xE0;sptwb.Spt.Cdb[1] = 0x00;sptwb.Spt.Cdb[2] = 0x00;sptwb.Spt.Cdb[3] = 0x00;sptwb.Spt.Cdb[4] = 0x00;sptwb.Spt.Cdb[5] = 0x00; sptwb.Spt.Cdb[6] = 0x00; sptwb.Spt.Cdb[7] = target; sptwb.Spt.Cdb[8] = 0xEC; // ID_CMDsptwb.Spt.Cdb[9] = 0x4C;}else if(type == CMD_TYPE_JMICRON){sptwb.Spt.CdbLength = 12;sptwb.Spt.Cdb[0] = 0xDF;sptwb.Spt.Cdb[1] = 0x10;sptwb.Spt.Cdb[2] = 0x00;sptwb.Spt.Cdb[3] = 0x02;sptwb.Spt.Cdb[4] = 0x00;sptwb.Spt.Cdb[5] = 0x00; sptwb.Spt.Cdb[6] = 0x01; sptwb.Spt.Cdb[7] = 0x00; sptwb.Spt.Cdb[8] = 0x00;sptwb.Spt.Cdb[9] = 0x00;sptwb.Spt.Cdb[10] = target; sptwb.Spt.Cdb[11] = 0xEC; // ID_CMD}else if(type == CMD_TYPE_CYPRESS){sptwb.Spt.CdbLength = 16;sptwb.Spt.Cdb[0] = 0x24;sptwb.Spt.Cdb[1] = 0x24;sptwb.Spt.Cdb[2] = 0x00;sptwb.Spt.Cdb[3] = 0xBE;sptwb.Spt.Cdb[4] = 0x01;sptwb.Spt.Cdb[5] = 0x00; sptwb.Spt.Cdb[6] = 0x00; sptwb.Spt.Cdb[7] = 0x01; sptwb.Spt.Cdb[8] = 0x00;sptwb.Spt.Cdb[9] = 0x00;sptwb.Spt.Cdb[10] = 0x00; sptwb.Spt.Cdb[11] = target;sptwb.Spt.Cdb[12] = 0xEC; // ID_CMDsptwb.Spt.Cdb[13] = 0x00;sptwb.Spt.Cdb[14] = 0x00;sptwb.Spt.Cdb[15] = 0x00;}else{return FALSE;}length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, DataBuf) + sptwb.Spt.DataTransferLength;bRet = DeviceIoControl(hIoCtrl, IOCTL_SCSI_PASS_THROUGH, &sptwb, sizeof(SCSI_PASS_THROUGH),&sptwb, length, &dwReturned, NULL);CloseHandle(hIoCtrl);if(bRet == FALSE || dwReturned != length){return FALSE;}memcpy(data, sptwb.DataBuf, sizeof(IDENTIFY_DEVICE));return TRUE;
}int main(int argc, char *argv[]) {HANDLE hDevice=NULL;STORAGE_PROPERTY_QUERY sQuery;STORAGE_DEVICE_DESCRIPTOR* pDescriptor;char *model, *firmware, *serialnumber;char usb_hdd_model[41], usb_hdd_firmware[9], usb_hdd_Serialnumber[21];IDENTIFY_DEVICE identify = {0};char pcbData[4096];int dwLen = 4096;DWORD dwRet;BOOL bRet;hDevice=CreateFileA("\\\\.\\PhysicalDrive1",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);if(hDevice==INVALID_HANDLE_VALUE){ fprintf(stderr, "CreateFile()\n");exit(1); }memset(pcbData, 0, 4096);sQuery.PropertyId = StorageDeviceProperty;sQuery.QueryType = PropertyStandardQuery;bRet = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &sQuery, sizeof(STORAGE_PROPERTY_QUERY), pcbData,dwLen,&dwRet,NULL);if(bRet){pDescriptor = (STORAGE_DEVICE_DESCRIPTOR*)pcbData;if(pDescriptor->BusType == BusTypeUsb){printf("USB-Type\n");}if(pDescriptor->ProductIdOffset){model = (char*)pDescriptor + pDescriptor->ProductIdOffset;printf("Model: %s\n", model);}if(pDescriptor->ProductRevisionOffset){firmware = (char*)pDescriptor + pDescriptor->ProductRevisionOffset;printf("Firmware: %s\n", firmware);}if(pDescriptor->SerialNumberOffset){serialnumber = (char*)pDescriptor + pDescriptor->SerialNumberOffset;printf("Serial number: %s\n", serialnumber);}}
/*CMD_TYPE_SAT, // SAT = SCSI_ATA_TRANSLATIONCMD_TYPE_SUNPLUS,CMD_TYPE_IO_DATA,CMD_TYPE_LOGITEC,CMD_TYPE_JMICRON,CMD_TYPE_CYPRESS,
*/if(DoIdentifyDeviceSat(hDevice, 0xa0, &identify, CMD_TYPE_SAT)){printf("0xA0-CMD_TYPE_SAT-Return ok");} else if(DoIdentifyDeviceSat(hDevice, 0xa0, &identify, CMD_TYPE_SUNPLUS)){printf("0xA0-CMD_TYPE_SUNPLUS-Return ok");}else if(DoIdentifyDeviceSat(hDevice, 0xa0, &identify, CMD_TYPE_IO_DATA)){printf("0xA0-CMD_TYPE_IO_DATA-Return ok");}else if(DoIdentifyDeviceSat(hDevice, 0xa0, &identify, CMD_TYPE_LOGITEC)){printf("0xA0-CMD_TYPE_LOGITEC-Return ok");}else if(DoIdentifyDeviceSat(hDevice, 0xa0, &identify, CMD_TYPE_JMICRON)){printf("0xA0-CMD_TYPE_JMICRON-Return ok");}else if(DoIdentifyDeviceSat(hDevice, 0xb0, &identify, CMD_TYPE_SAT)){printf("0xB0-CMD_TYPE_SAT-Return ok");} else if(DoIdentifyDeviceSat(hDevice, 0xb0, &identify, CMD_TYPE_SUNPLUS)){printf("0xB0-CMD_TYPE_SUNPLUS-Return ok");}else if(DoIdentifyDeviceSat(hDevice, 0xb0, &identify, CMD_TYPE_IO_DATA)){printf("0xB0-CMD_TYPE_IO_DATA-Return ok");}else if(DoIdentifyDeviceSat(hDevice, 0xb0, &identify, CMD_TYPE_LOGITEC)){printf("0xB0-CMD_TYPE_LOGITEC-Return ok");}else if(DoIdentifyDeviceSat(hDevice, 0xb0, &identify, CMD_TYPE_JMICRON)){printf("0xB0-CMD_TYPE_JMICRON-Return ok");}else{printf("Return ng\n");}#define debug 0
#if debugdump_buffer("data", (const unsigned char *)&identify, sizeof(IDENTIFY_DEVICE));
#endifmemcpy(usb_hdd_model, identify.Model, 40);ChangeByteOrder(usb_hdd_model, 40);usb_hdd_model[40]='\0';memcpy(usb_hdd_firmware, identify.FirmwareRev, 8);ChangeByteOrder(usb_hdd_firmware, 8);usb_hdd_firmware[8]='\0';memcpy(usb_hdd_Serialnumber, identify.SerialNumber, 20);ChangeByteOrder(usb_hdd_Serialnumber, 20);usb_hdd_Serialnumber[20]='\0';printf("\nUSB-HDD Model name: %s", usb_hdd_model);printf("\nUSB-HDD Firmware Rev: %s", usb_hdd_firmware);printf("\nUSB-HDD Serial number: %s", usb_hdd_Serialnumber);return 0;
}
这篇关于读取USB HDD(USB移动硬盘信息)序列号的代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!