读取USB HDD(USB移动硬盘信息)序列号的代码

来源:互联网 发布:java水印铺满 编辑:程序博客网 时间:2024/05/16 05:47

读取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{WORDGeneralConfiguration;//0WORDLogicalCylinders;//1ObsoleteWORDSpecificConfiguration;//2WORDLogicalHeads;//3 ObsoleteWORDRetired1[2];//4-5WORDLogicalSectors;//6 ObsoleteDWORDReservedForCompactFlash;//7-8WORDRetired2;//9CHARSerialNumber[20];//10-19WORDRetired3;//20WORDBufferSize;//21 Obsolete//WORDObsolute4;//22CHARFirmwareRev[8];//23-26CHARModel[40];//27-46WORDMaxNumPerInterupt;//47WORDReserved1;//48WORDCapabilities1;//49WORDCapabilities2;//50DWORDObsolute5;//51-52WORDField88and7064;//53WORDObsolute6[5];//54-58WORDMultSectorStuff;//59DWORDTotalAddressableSectors;//60-61WORDObsolute7;//62WORDMultiWordDma;//63WORDPioMode;//64WORDMinMultiwordDmaCycleTime;//65WORDRecommendedMultiwordDmaCycleTime;//66WORDMinPioCycleTimewoFlowCtrl;//67WORDMinPioCycleTimeWithFlowCtrl;//68WORDReserved2[6];//69-74WORDQueueDepth;//75WORDSerialAtaCapabilities;//76WORDSerialAtaAdditionalCapabilities;//77WORDSerialAtaFeaturesSupported;//78WORDSerialAtaFeaturesEnabled;//79WORDMajorVersion;//80WORDMinorVersion;//81WORDCommandSetSupported1;//82WORDCommandSetSupported2;//83WORDCommandSetSupported3;//84WORDCommandSetEnabled1;//85WORDCommandSetEnabled2;//86WORDCommandSetDefault;//87WORDUltraDmaMode;//88WORDTimeReqForSecurityErase;//89WORDTimeReqForEnhancedSecure;//90WORDCurrentPowerManagement;//91WORDMasterPasswordRevision;//92WORDHardwareResetResult;//93WORDAcoustricManagement;//94WORDStreamMinRequestSize;//95WORDStreamingTimeDma;//96WORDStreamingAccessLatency;//97DWORDStreamingPerformance;//98-99ULONGLONGMaxUserLba;//100-103WORDStremingTimePio;//104WORDReserved3;//105WORDSectorSize;//106WORDInterSeekDelay;//107WORDIeeeOui;//108WORDUniqueId3;//109WORDUniqueId2;//110WORDUniqueId1;//111WORDReserved4[4];//112-115WORDReserved5;//116DWORDWordsPerLogicalSector;//117-118WORDReserved6[8];//119-126WORDRemovableMediaStatus;//127WORDSecurityStatus;//128WORDVendorSpecific[31];//129-159WORDCfaPowerMode1;//160WORDReservedForCompactFlashAssociation[7];//161-167WORDDeviceNominalFormFactor;//168WORDDataSetManagement;//169WORDAdditionalProductIdentifier[4];//170-173WORDReserved7[2];//174-175CHARCurrentMediaSerialNo[60];//176-205WORDSctCommandTransport;//206WORDReservedForCeAta1[2];//207-208WORDAlignmentOfLogicalBlocks;//209DWORDWriteReadVerifySectorCountMode3;//210-211DWORDWriteReadVerifySectorCountMode2;//212-213WORDNvCacheCapabilities;//214DWORDNvCacheSizeLogicalBlocks;//215-216WORDNominalMediaRotationRate;//217WORDReserved8;//218WORDNvCacheOptions1;//219WORDNvCacheOptions2;//220WORDReserved9;//221WORDTransportMajorVersionNumber;//222WORDTransportMinorVersionNumber;//223WORDReservedForCeAta2[10];//224-233WORDMinimumBlocksPerDownloadMicrocode;//234WORDMaximumBlocksPerDownloadMicrocode;//235WORDReserved10[19];//236-254WORDIntegrityWord;//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;#defineFILE_DEVICE_SCSI0x0000001b#defineIOCTL_SCSI_MINIPORT_IDENTIFY((FILE_DEVICE_SCSI << 16) + 0x0501)#defineIOCTL_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 boundaryUCHAR             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]); else    printf ("   ");      }      printf ("  ");      for (j = 0; j < 16; ++j)      { if ((i + j) < len)    printf ("%c", isprint (buffer[i + j]) ? buffer [i + j] : '.'); else    printf (" ");      }      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){BOOLbRet;HANDLEhIoCtrl;DWORDdwReturned;DWORDlength;SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;if(data == NULL){printf("Data\n");returnFALSE;}ZeroMemory(data, sizeof(IDENTIFY_DEVICE));hIoCtrl = physicalDriveId;if(hIoCtrl == INVALID_HANDLE_VALUE){printf("Handle\n");returnFALSE;}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){returnFALSE;}memcpy(data, sptwb.DataBuf, sizeof(IDENTIFY_DEVICE));returnTRUE;}int main(int argc, char *argv[]) {HANDLE hDevice=NULL;STORAGE_PROPERTY_QUERYsQuery;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;DWORDdwRet;BOOLbRet;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;}


0 0
原创粉丝点击