Read the code, model and sub-position of the serial number of the USB HDD (USB removable hard drive).
Compiled successfully with Visual Studio 2010.
The code uses the relevant code in code SMARTATA.C in Crystaldiskinfo:
The following connection explains why the use of SCSI-related code requires the data conversion of the USB IC.
http://blog.csdn.net/waityoualife/article/details/5656589
The implementation code is as follows:
DiskInfo.cpp:Defines the entry point for the console application.//#include "stdafx.h" #include <stdio.h> #includ E <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 {Pro Pertystandardquery = 0, Propertyexistsquery, Propertymaskquery, propertyquerymaxdefined} STORAGE_QUERY_TYPE, * pstorage_query_type;//retrieve the properties of a storage device or adapter.typedef struct _storage_property_query {ST ORAGE_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 <<) + 0x0501) #defineIOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS ((FILE_DEVICE_SCSI << + 0x0502) #define Ioctl_scsi_miniport_read_smart_thresholds ((FILE_DEVICE_SCSI << +) + 0x0503) # Define Ioctl_scsi_miniport_enable_smart (File_device_scsi << + 0x0504) #define Ioctl_scsi_miniport_disable_ SMART ((file_device_scsi << + 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_io Ctl_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 < ++j) {printf ("%2x", j); } printf (""); for (j = 0; J < ++j) {printf ("%1x", j); } printf ("\ n"); } while (I < len) {printf ("%08x", I); for (j = 0; J < ++j) {if ((i + j) < Len) printf ("%02x", (int) buffer[i +j]); else printf (""); } printf (""); for (j = 0; J < ++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 () 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, usb_hdd_model[40]=); memcpy (Usb_hdd_firmware, identify. Firmwarerev, 8); Changebyteorder (Usb_hdd_firmware, 8); usb_hdd_firmware[8]= ' + '; memcpy (Usb_hdd_serialnumber, identify. SerialNumber, 20); Changebyteorder (usb_hdd_serialnumber), usb_hdd_serialnumber[20]= ';p rintf ("\NUSB-HDD Model Name:%s", usb_hdd_ Model);p rintf ("\nusb-hdd Firmware Rev:%s", Usb_hdd_firmware);p rintf ("\nusb-hdd Serial Number:%s", usb_hdd_ serialnumber); return 0;}
Code to read the serial number of the USB HDD (USB removable hard drive information)