Get detailed hard disk info [updated 28/6/10]

Share your advanced PureBasic knowledge/code with the community.
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Get detailed hard disk info [updated 28/6/10]

Post by doctorized »

This code is based on two files that can be found at: http://kc2000labs.110mb.com/pb/zips/4.3 ... o_4.31.zip
The updated code has some new features and lots of new disk families supported. Works on every PB version.
Last edited by doctorized on Mon Jun 28, 2010 1:18 pm, edited 4 times in total.
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

can you provide a version thats works under a actual (4.3) version ?
i can't compile the source without lots of compiler-syntax errors.
SPAMINATOR NR.1
Tranquil
Addict
Addict
Posts: 952
Joined: Mon Apr 28, 2003 2:22 pm
Location: Europe

Post by Tranquil »

Rings is right. Most of us are using PB 4.30, it would be nice to get a working version for this version.

Anyway, many thanks for sharing your knowledge.
Tranquil
dige
Addict
Addict
Posts: 1391
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Post by dige »

Quci'n dirty converted to PB4.31

Code: Select all

Procedure.s DiskFamily(code.s)
  Protected Model.s = ""
  Restore HDD_CODES
  Repeat
    Read.s HDDModel.s
    If HDDModel = ""
      Break
    EndIf
    Read.s HDDCodeExpression.s
    If CreateRegularExpression(0, HDDCodeExpression)
      If MatchRegularExpression(0, code)
        FreeRegularExpression(0)
        Model = HDDModel
        Break
      EndIf
      FreeRegularExpression(0)
    EndIf
  ForEver
  ProcedureReturn Model
EndProcedure

DataSection
	HDD_CODES:
  Data.s "ExcelStor J240", "^ExcelStor Technology J240$"
  Data.s "ExcelStor J340", "^ExcelStor Technology J340$"
  Data.s "ExcelStor J360", "^ExcelStor Technology J360$"
  Data.s "ExcelStor J680", "^ExcelStor Technology J680$"
  Data.s "ExcelStor J880", "^ExcelStor Technology J880$"
  Data.s "IBM Deskstar 60GXP series", "(IBM-|Hitachi )?IC35L0[12346]0AVER07"
  Data.s "IBM Deskstar 40GV & 75GXP series", "(IBM-)?DTLA-30[57]0[123467][05]"
  Data.s "Fujitsu M1623TAU", "^FUJITSU M1623TAU$"
  Data.s "Fujitsu MHM2200AT", "^FUJITSU MHM2200AT"
  Data.s "Fujitsu MHM2150AT", "^FUJITSU MHM2150AT"
  Data.s "Fujitsu MHM2100AT", "^FUJITSU MHM2100AT"
  Data.s "Fujitsu MHM2060AT", "^FUJITSU MHM2060AT"
  Data.s "Fujitsu MHG series", "^FUJITSU MHG2...ATU?"
  Data.s "Fujitsu MHH series", "^FUJITSU MHH2...ATU?"
  Data.s "Fujitsu MHJ series", "^FUJITSU MHJ2...ATU?"
  Data.s "Fujitsu MHK series", "^FUJITSU MHK2...ATU?"
  Data.s "Fujitsu MHL2300AT", "^FUJITSU MHL2300AT$"
  Data.s "Fujitsu MHN series", "^FUJITSU MHN2...AT$"
  Data.s "Fujitsu MHR2020AT", "^FUJITSU MHR2020AT$"
  Data.s "Fujitsu MHR2040AT", "^FUJITSU MHR2040AT$"
  Data.s "Fujitsu MHSxxxxAT family", "^FUJITSU MHS20[6432]0AT(  .)?$"
  Data.s "Fujitsu MHT series", "^FUJITSU MHT2...(AH|AS|AT|BH)U?"
  Data.s "Fujitsu MHU series", "^FUJITSU MHU2...ATU?"
  Data.s "Fujitsu MHV series", "^FUJITSU MHV2...(AH|AS|AT|BH|BS|BT)"
  Data.s "Fujitsu MPA..MPG series", "^FUJITSU MP[A-G]3...A[HTEV]U?"
  Data.s "Fujitsu MHW2 BH", "^FUJITSU MHW2(04|06|08|10|12|16)0BH$"
  Data.s "Samsung SV4012H", "^SAMSUNG SV4012H$"
  Data.s "Samsung SV0412H", "^SAMSUNG SV0412H$"
  Data.s "Samsung SV1204H", "^SAMSUNG SV1204H$"
  Data.s "Samsung SV0322A", "^SAMSUNG SV0322A$"
  Data.s "Samsung SP40A2H with RR100-07 firmware",     "^SAMSUNG SP40A2H$"
  Data.s "Samsung SP8004H with QW100-61 firmware", "^SAMSUNG SP8004H$"
  Data.s "Samsung SpinPoint T133 series", "^SAMSUNG HD(250KD|(30[01]|320|40[01])L[DJ])$"
  Data.s "Samsung SpinPoint T166 series", "^SAMSUNG HD(080G|160H|32[01]K|403L|50[01]L)J$"
  Data.s "Samsung SpinPoint P120 series", "^SAMSUNG SP(16[01]3|2[05][01]4)[CN]$"
  Data.s "Samsung SpinPoint P80 SD series", "^SAMSUNG HD(080H|120I|160J)J$"
  Data.s "Samsung SpinPoint P80 series", "^SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]$"
  Data.s "Maxtor Fireball 541DX family", "^Maxtor 2B0(0[468]|1[05]|20)H1$"
  Data.s "Maxtor Fireball 3 family", "^Maxtor 2F0[234]0[JL]0$"
  Data.s "Maxtor DiamondMax 2160 Ultra ATA family", "^Maxtor 8(2160D2|3228D3|3240D3|4320D4|6480D6|8400D8|8455D8)$"
  Data.s "Maxtor DiamondMax 2880 Ultra ATA family", "^Maxtor 9(0510D4|0576D4|0648D5|0720D5|0840D6|0845D6|0864D6|1008D7|1080D8|1152D8)$"
  Data.s "Maxtor DiamondMax 3400 Ultra ATA family", "^Maxtor 9(1(360|350|202)D8|1190D7|10[12]0D6|0840D5|06[48]0D4|0510D3|1(350|202)E8|1010E6|0840E5|0640E4)$"
  Data.s "Maxtor DiamondMax D540X-4G family", "^Maxtor 4G(120J6|160J[68])$"
  Data.s "Maxtor DiamondMax D540X-4K family", "^MAXTOR 4K(020H1|040H2|060H3|080H4)$"
  Data.s "Maxtor DiamondMax Plus D740X family", "^MAXTOR 6L0(20[JL]1|40[JL]2|60[JL]3|80[JL]4)$"
  Data.s "Maxtor DiamondMax Plus 5120 Ultra ATA 33 family", "^Maxtor 9(0512D2|0680D3|0750D3|0913D4|1024D4|1360D6|1536D6|1792D7|2048D8)$"
  Data.s "Maxtor DiamondMax Plus 6800 Ultra ATA 66 family", "^Maxtor 9(2732U8|2390U7|2049U6|1707U5|1366U4|1024U3|0845U3|0683U2)$"
  Data.s "Maxtor DiamondMax D540X-4D", "^Maxtor 4D0(20H1|40H2|60H3|80H4)$"
  Data.s "Maxtor DiamondMax 16 family", "^Maxtor 4(R0[68]0[JL]0|R1[26]0L0|A160J0|R120L4)$"
  Data.s "Maxtor DiamondMax 4320 Ultra ATA family", "^Maxtor (91728D8|91512D7|91303D6|91080D5|90845D4|90645D3|90648D[34]|90432D2)$"
  Data.s "Maxtor DiamondMax 17 VL family", "^Maxtor 9(0431U1|0641U2|0871U2|1301U3|1741U4)$"
  Data.s "Maxtor DiamondMax 20 VL family", "^Maxtor (94091U8|93071U6|92561U5|92041U4|91731U4|91531U3|91361U3|91021U2|90841U2|90651U2)$"
  Data.s "Maxtor DiamondMax VL 30 family", "^Maxtor (33073U4|32049U3|31536U2|30768U1)$"
  Data.s "Maxtor DiamondMax 36 family", "^Maxtor (93652U8|92739U6|91826U4|91369U3|90913U2|90845U2|90435U1)$"
  Data.s "Maxtor DiamondMax 40 ATA 66 series", "^Maxtor 9(0684U2|1024U2|1362U3|1536U3|2049U4|2562U5|3073U6|4098U8)$"
  Data.s "Maxtor DiamondMax Plus 40 series (Ultra ATA 66 and Ultra ATA 100)", "^Maxtor (54098[UH]8|53073[UH]6|52732[UH]6|52049[UH]4|51536[UH]3|51369[UH]3|51024[UH]2)$"
  Data.s "Maxtor DiamondMax 40 VL Ultra ATA 100 series", "^Maxtor 3(1024H1|1535H2|2049H2|3073H3|4098H4)( B)?$"
  Data.s "Maxtor DiamondMax Plus 45 Ulta ATA 100 family", "^Maxtor 5(4610H6|4098H6|3073H4|2049H3|1536H2|1369H2|1023H2)$"
  Data.s "Maxtor DiamondMax 60 ATA 66 family", "^Maxtor 9(1023U2|1536U2|2049U3|2305U3|3073U4|4610U6|6147U8)$"
  Data.s "Maxtor DiamondMax 60 ATA 100 family", "^Maxtor 9(1023H2|1536H2|2049H3|2305H3|3073H4|4610H6|6147H8)$"
  Data.s "Maxtor DiamondMax Plus 60 family", "^Maxtor 5T0(60H6|40H4|30H3|20H2|10H1)$"
  Data.s "Maxtor DiamondMax 80 family", "^Maxtor (98196H8|96147H6)$"
  Data.s "Maxtor DiamondMax 536DX family", "^Maxtor 4W(100H6|080H6|060H4|040H3|030H2)$"
  Data.s "Maxtor DiamondMax Plus 8 family", "^Maxtor 6(E0[234]|K04)0L0$"
  Data.s "Maxtor DiamondMax 10 family (ATA/133 and SATA/150)", "^Maxtor 6(B(30|25|20|16|12|08)0[MPRS]|L(080[MLP]|(100|120)[MP]|160[MP]|200[MPRS]|250[RS]|300[RS]))0$"
  Data.s "Maxtor DiamondMax 10 family (SATA/300)", "^Maxtor 6V(080E|160E|200E|250F|300F|320F)0$"
  Data.s "Maxtor DiamondMax Plus 9 family", "^Maxtor 6Y((060|080|120|160)L0|(060|080|120|160|200|250)P0|(060|080|120|160|200|250)M0)$"
  Data.s "Maxtor DiamondMax 11 family", "^Maxtor 6H[45]00[FR]0$"
  Data.s "Maxtor DiamondMax 17", "^Maxtor 6G(080L|160[PE])0$"
  Data.s "Seagate Maxtor DiamondMax 20", "^MAXTOR STM3(40|80|160)[28]1[12]0?AS?$"
  Data.s "Seagate Maxtor DiamondMax 21", "^MAXTOR STM3(250|320)820AS?$"
  Data.s "Maxtor MaXLine Plus II", "^Maxtor 7Y250[PM]0$"
  Data.s "Maxtor MaXLine II family", "^Maxtor [45]A(25|30|32)0[JN]0$"
  Data.s "Maxtor MaXLine III family (ATA/133 and SATA/150)", "^Maxtor 7L(25|30)0[SR]0$"
  Data.s "Maxtor MaXLine III family (SATA/300)", "^Maxtor 7V(25|30)0F0$"
  Data.s "Maxtor MaXLine Pro 500 family", "^Maxtor 7H500F0$"
  Data.s "Hitachi DK14FA-20B", "^HITACHI_DK14FA-20B$"
  Data.s "Hitachi Travelstar DK23XX/DK23XXB series", "^HITACHI_DK23..-..B?$"
  Data.s "Hitachi Endurastar J4K20/N4K20", "^(HITACHI_DK23FA-20J|HTA422020F9AT[JN]0)$"
  Data.s "IBM Deskstar 14GXP and 16GP series", "^IBM-DTTA-3(7101|7129|7144|5032|5043|5064|5084|5101|5129|5168)0$"
  Data.s "IBM Deskstar 25GP and 22GXP family", "^IBM-DJNA-3(5(101|152|203|250)|7(091|135|180|220))0$"
  Data.s "IBM Travelstar 4GT family", "^IBM-DTCA-2(324|409)0$"
  Data.s "IBM Travelstar 25GS, 18GT, and 12GN family", "^IBM-DARA-2(25|18|15|12|09|06)000$"
  Data.s "IBM Travelstar 48GH, 30GN, and 15GN family", "^(IBM-|Hitachi )?IC25(T048ATDA05|N0(30|20|15|12|10|07|06|05)ATDA04)-.$"
  Data.s "IBM Travelstar 32GH, 30GT, and 20GN family", "^IBM-DJSA-2(32|30|20|10|05)$"
  Data.s "IBM Travelstar 4GN family", "^IBM-DKLA-2(216|324|432)0$"
  Data.s "IBM Deskstar 37GP and 34GXP family", "^IBM-DPTA-3(5(375|300|225|150)|7(342|273|205|136))0$"
  Data.s "IBM/Hitachi Travelstar 60GH and 40GN family", "^(IBM-|Hitachi )?IC25(T060ATC[SX]05|N0[4321]0ATC[SX]04)-.$"
  Data.s "IBM/Hitachi Travelstar 40GNX family", "^(IBM-|Hitachi )?IC25N0[42]0ATC[SX]05-.$"
  Data.s "Hitachi Travelstar 80GN family", "^(Hitachi )?IC25N0[23468]0ATMR04-.$"
  Data.s "Hitachi Travelstar 4K40", "^(Hitachi )?HTS4240[234]0M9AT00$"
  Data.s "Hitachi Travelstar 5K80 family", "^(Hitachi )?HTS5480[8642]0M9AT00$"
  Data.s "Hitachi Travelstar 5K100 series", "^(Hitachi )?HTS5410[1864]0G9(AT|SA)00$"
  Data.s "Hitachi Travelstar E5K100 series", "^(Hitachi )?HTE541040G9(AT|SA)00$"
  Data.s "Hitachi Travelstar 5K120", "^(Hitachi )?HTS5412(60|80|10|12)H9(AT|SA)00$"
  Data.s "Hitachi Travelstar 5K160 series", "^(Hitachi )?HTS5416([468]0|1[26])J9(AT|SA)00$"
  Data.s "Hitachi Travelstar 7K60", "^(Hitachi )?HTS726060M9AT00$"
  Data.s "Hitachi Travelstar E7K60", "^(Hitachi )?HTE7260[46]0M9AT00$"
  Data.s "Hitachi Travelstar 7K100", "^(Hitachi )?HTS7210[168]0G9(AT|SA)00$"
  Data.s "Hitachi Travelstar E7K100", "^(Hitachi )?HTE7210[168]0G9(AT|SA)00$"
  Data.s "Hitachi Travelstar 7K200", "^(Hitachi )?HTS7220(80|10|12|16|20)K9(A3|SA)00$"
  Data.s "IBM/Hitachi Deskstar 120GXP family", "^(IBM-)?IC35L((020|040|060|080|120)AVVA|0[24]0AVVN)07-[01]$"
  Data.s "IBM/Hitachi Deskstar GXP-180 family", "^(IBM-)?IC35L(030|060|090|120|180)AVV207-[01]$"
  Data.s "IBM Travelstar 14GS", "^IBM-DCYA-214000$"
  Data.s "IBM Travelstar 4LP", "^IBM-DTNA-2(180|216)0$"
  Data.s "Hitachi Deskstar 7K80 series", "^(Hitachi )?HDS7280([48]0PLAT20|(40)?PLA320|80PLA380)$"
  Data.s "Hitachi Deskstar 7K160", "^(Hitachi )?HDS7216(80|16)PLA[3T]80$"
  Data.s "Hitachi Deskstar 7K250 series", "^(Hitachi )?HDS7225((40|80|12|16)VLAT20|(12|16|25)VLAT80|(80|12|16|25)VLSA80)$"
  Data.s "Hitachi Deskstar T7K250 series", "^(Hitachi )?HDT7225((25|20|16)DLA(T80|380))$"
  Data.s "Hitachi Deskstar 7K400 series", "^(Hitachi )?HDS724040KL(AT|SA)80$"
  Data.s "Hitachi Deskstar 7K500 series", "^(Hitachi )?HDS725050KLA(360|T80)$"
  Data.s "Hitachi Deskstar T7K500", "^(Hitachi )?HDT7250(25|32|40|50)VLA(360|380|T80)$"
  Data.s "Hitachi Deskstar 7K1000", "^(Hitachi )?HDS7210(75|10)KLA330$"
  Data.s "Hitachi Ultrastar 7K1000", "^(Hitachi )?HUA7210(50|75|10)KLA330$"
  Data.s "Toshiba 2.5'' HDD series (30-60 GB)", "^TOSHIBA MK((6034|4032)GSX|(6034|4032)GAX|(6026|4026|4019|3019)GAXB?|(6025|6021|4025|4021|4018|3025|3021|3018)GAS|(4036|3029)GACE?|(4018|3017)GAP)$"
  Data.s "Toshiba 2.5'' HDD series (80 GB And above)", "^TOSHIBA MK(80(25GAS|26GAX|32GAX|32GSX)|10(31GAS|32GAX)|12(33GAS|34G[As]X)|2035GSS)$"
  Data.s "Toshiba 1.8'' HDD series", "^TOSHIBA MK[23468]00[4-9]GA[HL]$"
  Data.s "Toshiba MK6022GAX", "^TOSHIBA MK6022GAX$"
  Data.s "Toshiba MK6409MAV", "^TOSHIBA MK6409MAV$"
  Data.s "Toshiba MK3019GAXB SUN30G", "^TOS MK3019GAXB SUN30G$"
  Data.s "Toshiba MK2016GAP", "^TOSHIBA MK2016GAP$"
  Data.s "Toshiba MK2017GAP", "^TOSHIBA MK2017GAP$"
  Data.s "Toshiba MK2018GAP", "^TOSHIBA MK2018GAP$"
  Data.s "Toshiba MK2018GAS", "^TOSHIBA MK2018GAS$"
  Data.s "Toshiba MK2023GAS", "^TOSHIBA MK2023GAS$"
  Data.s "Seagate Momentus family", "^ST9(20|28|40|48)11A$"
  Data.s "Seagate Momentus 42 family", "^ST9(2014|3015|4019)A$"
  Data.s "Seagate Momentus 4200.2 Series", "^ST9(100822|808210|60821|50212|402113|30219)A$"
  Data.s "Seagate Momentus 5400.2 series", "^ST9(808211|60822|408114|308110|120821|10082[34]|8823|6812|4813|3811)AS?$"
  Data.s "Seagate Momentus 5400.3", "^ST9(4081[45]|6081[35]|8081[15]|100828|120822|160821)AS?$"
  Data.s "Seagate Momentus 5400.3 ED", "^ST9(4081[45]|6081[35]|8081[15]|100828|120822|160821)AB$"
  Data.s "Seagate Momentus 7200.1 series", "^ST9(10021|80825|6023|4015)AS?$"
  Data.s "Seagate Momentus 7200.2", "^ST9(80813|100821|120823|160823|200420)ASG?$"
  Data.s "Seagate U Series X family", "^ST3(10014A(CE)?|20014A)$"
  Data.s "Seagate U7 family", "^ST3(30012|40012|60012|80022|120020)A$"
  Data.s "Seagate U Series 6 family", "^ST3(8002|6002|4081|3061|2041)0A$"
  Data.s "Seagate U Series 5 family", "^ST3(40823|30621|20413|15311|10211)A$"
  Data.s "Seagate U4 family", "^ST3(2112|4311|6421|8421)A$"
  Data.s "Seagate U8 family", "^ST3(8410|4313|17221|13021)A$"
  Data.s "Seagate U10 family", "^ST3(20423|15323|10212)A$"
  Data.s "Seagate Barracuda ATA II family", "^ST3(3063|2042|1532|1021)0A$"
  Data.s "Seagate Barracuda ATA III family", "^ST3(40824|30620|20414|15310|10215)A$"
  Data.s "Seagate Barracuda ATA IV family", "^ST3(20011|30011|40016|60021|80021)A$"
  Data.s "Seagate Barracuda ATA V family", "^ST3(12002(3A|4A|9A|3AS)|800(23A|15A|23AS)|60(015A|210A)|40017A)$"
  Data.s "Seagate Barracuda 5400.1", "^ST340015A$"
  Data.s "Seagate Barracuda 7200.7 and 7200.7 Plus family", "^ST3(200021A|200822AS?|16002[13]AS?|12002[26]AS?|1[26]082[78]AS|8001[13]AS?|80817AS|60014A|40111AS|40014AS?)$"
  Data.s "Seagate Barracuda 7200.8 family", "^ST3(400[68]32|300[68]31|250[68]23|200826)AS?$"
  Data.s "Seagate Barracuda 7200.9 family", "^ST3(402111?|80[28]110?|120[28]1[0134]|160[28]1[012]|200827|250[68]24|300[68]22|(320|400)[68]33|500[68](32|41))AS?$"
  Data.s "Seagate Barracuda 7200.10 family", "^ST3((80|160)[28]15|200820|250[34]10|(250|300|320|400)[68]20|500[68]30|750[68]40)AS?$"
  Data.s "Seagate Barracuda 7200.11", "^ST3(500[368]2|750[36]3|1000[36]4)0AS?$"
  Data.s "Seagate Barracuda ES", "^ST3(250[68]2|32062|40062|50063|75064)0NS$"
  Data.s "Seagate Medalist 17240", "^ST317240A$"
  Data.s "Seagate Medalist 13030", "^ST313030A$"
  Data.s "Seagate Medalist 10231", "^ST310231A$"
  Data.s "Seagate Medalist 8420", "^ST38420A$"
  Data.s "Seagate Medalist 4310", "^ST34310A$"
  Data.s "Seagate Medalist 17242", "^ST317242A$"
  Data.s "Seagate Medalist 13032", "^ST313032A$"
  Data.s "Seagate Medalist 10232", "^ST310232A$"
  Data.s "Seagate Medalist 8422", "^ST38422A$"
  Data.s "Seagate Medalist 4312", "^ST34312A$"
  Data.s "Seagate Medalist 2110", "^ST32110A$"
  Data.s "Seagate Medalist 3221", "^ST33221A$"
  Data.s "Seagate Medalist 4321", "^ST34321A$"
  Data.s "Seagate Medalist 6531", "^ST36531A$"
  Data.s "Seagate Medalist 8641", "^ST38641A$"
  Data.s "Seagate NL35 family", "^ST3(250623|250823|400632|400832|250824|250624|400633|400833|500641|500841)NS$"
  Data.s "Western Digital Protege", "^WDC WD([2468]00E|1[26]00A)B-.*$"
  Data.s "Western Digital Caviar family", "^WDC WD(2|3|4|6|8|10|12|16|18|20|25)00BB-.*$"
  Data.s "Western Digital Caviar AC12500", "^WDC AC12500.?"
  Data.s "Western Digital Caviar AC14300", "^WDC AC14300.?"
  Data.s "Western Digital Caviar AC23200", "^WDC AC23200.?"
  Data.s "Western Digital Caviar AC24300", "^WDC AC24300.?"
  Data.s "Western Digital Caviar AC25100", "^WDC AC25100.?"
  Data.s "Western Digital Caviar AC36400", "^WDC AC36400.?"
  Data.s "Western Digital Caviar AC38400", "^WDC AC38400.?"
  Data.s "Western Digital Caviar WDxxxAB series", "^WDC WD(3|4|6)00AB-.*$"
  Data.s "Western Digital Caviar WDxxxAA series", "^WDC WD...?AA(-.*)?$"
  Data.s "Western Digital Caviar WDxxxBA series", "^WDC WD...BA$"
  Data.s "Western Digital Caviar Serial ATA family", "^WDC WD(4|8|20|32)00BD-.*$"
  Data.s "Western Digital Caviar SE family", "^WDC WD((4|6|8|10|12|16|18|20|25|30|32|40|50)00(JB|PB|AAJB|AAKB))-.*$"
  Data.s "Western Digital Caviar SE Serial ATA family", "^WDC WD((4|8|12|16|20|25|32|40)00(JD|KD))-.*$"
  Data.s "Western Digital Caviar Second Generation Serial ATA family", "^WDC WD((8|12|16|20|25|30|32|40|50|75)00(JS|KS|AABS|AAJS|AAKS))-.*$"
  Data.s "Western Digital Caviar RE Serial ATA family", "^WDC WD((12|16|25|32|40|50|75)00(SD|YD|YR|YS|ABYS|AYYS))-.*$"
  Data.s "Western Digital Caviar RE EIDE family", "^WDC WD((12|16|25|32)00SB)-.*$"
  Data.s "Western Digital Raptor family", "^WDC WD((360|740|800)GD|(360|740|1500)ADFD)-.*$"
  Data.s "Western Digital Scorpio family", "^WDC WD((4|6|8|10|12|16|20|25)00(UE|VE|BEAS|BEVE|BEVS))-.*$"
  Data.s "Quantum BIGFOOT TS10.0A", "^QUANTUM BIGFOOT TS10.0A$"
  Data.s "Quantum FIREBALLlct15 20 And QUANTUM FIREBALLlct15 30", "^QUANTUM FIREBALLlct15 [123]0$"
  Data.s "Quantum FIREBALLlct20 series", "^QUANTUM FIREBALLlct20 [234]0$"
  Data.s "Quantum FIREBALL CX10.2A", "^QUANTUM FIREBALL CX10.2A$"
  Data.s "Quantum Fireball Plus LM series", "^QUANTUM FIREBALLP LM(10.2|15|20.5|30)$"
  Data.s "Quantum Fireball CR series", "^QUANTUM FIREBALL CR(4.3|8.4)A$"
  Data.s "Quantum FIREBALLP AS10.2, AS20.5, AS30.0, And AS40.0", "^QUANTUM FIREBALLP AS(10.2|20.5|30.0|40.0)$"
  Data.s "Quantum FIREBALL EX6.4A", "^QUANTUM FIREBALL EX6.4A$"
  Data.s "Quantum FIREBALL ST3.2A", "^QUANTUM FIREBALL ST(3.2|4.3)A$"
  Data.s "Quantum FIREBALL EX3.2A", "^QUANTUM FIREBALL EX3.2A$"
  Data.s "Quantum FIREBALLP KX27.3", "^QUANTUM FIREBALLP KX27.3$"
  Data.s "Quantum Fireball Plus KA series", "^QUANTUM FIREBALLP KA(9|10).1$"
  Data.s "Quantum Fireball SE series", "^QUANTUM FIREBALL SE4.3A$"
  Data.s ""	; Marks end of data
EndDataSection
; IDE Options = PureBasic 4.20 (Windows - x86)
; CursorPosition = 207
; FirstLine = 164
; Folding = -
; EnableXP
; EnableAdmin
; EnableOnError
; CurrentDirectory = F:\120GB\WInfo.exe\
; CompileSourceDirectory
; IncludeFile "HDD_Families.pb"

Structure DeviceData
	GeneralConfiguration.w;				; 0
	LogicalCylinders.w;					; 1	Obsolete
	SpecificConfiguration.w;				; 2
	LogicalHeads.w;						; 3 Obsolete
	Retired1.w[2];						; 4-5
	LogicalSectors.w;						; 6 Obsolete
	ReservedForCompactFlash.l;			; 7-8
	Retired2.w;							; 9
	SerialNumber.c[20];					; 10-19
	Retired3.w;							; 20
	BufferSize.w;							; 21 Obsolete
	ECCSize.w;							; 22
	FirmwareRev.c[8];						; 23-26
	ModelNumber.c[40];							; 27-46
	MaxNumPerInterupt.w;					; 47
	Reserved1.w;							; 48
	Capabilities1.w;						; 49
	Capabilities2.w;						; 50
	Obsolute5.l;							; 51-52
	Field88and7064.w;						; 53
	Obsolute6.w[5];						; 54-58
	MultSectorStuff.w;					; 59
	TotalAddressableSectors.l;			; 60-61
	Obsolute7.w;							; 62
	MultiWordDma.w;						; 63
	PioMode.w;							; 64
	MinMultiwordDmaCycleTime.w;			; 65
	RecommendedMultiwordDmaCycleTime.w;	; 66
	MinPioCycleTimewoFlowCtrl.w;			; 67
	MinPioCycleTimeWithFlowCtrl.w;		; 68
	Reserved2.w[6];						; 69-74
	QueueDepth.w;							; 75
	SerialAtaCapabilities.w;				; 76
	ReservedForFutureSerialAta.w;			; 77
	SerialAtaFeaturesSupported.w;			; 78
	SerialAtaFeaturesEnabled.w;			; 79
	MajorVersion.w;						; 80
	MinorVersion.w;						; 81
	CommandSetSupported1.w;				; 82
	CommandSetSupported2.w;				; 83
	CommandSetSupported3.w;				; 84
	CommandSetEnabled1.w;					; 85
	CommandSetEnabled2.w;					; 86
	CommandSetDefault.w;					; 87
	UltraDmaMode.w;						; 88
	TimeReqForSecurityErase.w;			; 89
	TimeReqForEnhancedSecure.w;			; 90
	CurrentPowerManagement.w;				; 91
	MasterPasswordRevision.w;				; 92
	HardwareResetResult.w;				; 93
	Acoustricmanagement.w;				; 94
	StreamMinRequestSize.w;				; 95
	StreamingTimeDma.w;					; 96
	StreamingAccessLatency.w;				; 97
	StreamingPerformance.l;				; 98-99
	MaxUserLba.q;							; 100-103
	StremingTimePio.w;					; 104
	Reserved3.w;							; 105
	SectorSize.w;							; 106
	InterSeekDelay.w;						; 107
	IeeeOui.w;							; 108
	UniqueId3.w;							; 109
	UniqueId2.w;							; 110
	UniqueId1.w;							; 111
	Reserved4.w[4];						; 112-115
	Reserved5.w;							; 116
	WordsPerLogicalSector.l;				; 117-118
	Reserved6.w[8];						; 119-126
	RemovableMediaStatus.w;				; 127
	SecurityStatus.w;						; 128
	VendorSpecific.w[31];					; 129-159
	CfaPowerMode1.w;						; 160
	Reserved7.w[15];						; 161-175
	CurrentMediaSerialNo.c[60];			; 176-205
	SctCommandTransport.w;				; 206  254
	ReservedForCeAta1.w[2];				; 207-208
	AlignmentOfLogicalBlocks.w;			; 209
	WriteReadVerifySectorCountMode3.l;	; 210-211
	WriteReadVerifySectorCountMode2.l;	; 212-213
	NvCacheCapabilities.w;				; 214
	NvCacheSizeLogicalBlocks.l;			; 215-216
	NominalMediaRotationRate.w;			; 217
	Reserved8.w;							; 218
	NvCacheOptions1.w;					; 219
	NvCacheOptions2.w;					; 220
	Reserved9.w;							; 221
	TransportMajorVersionNumber.w;		; 222
	TransportMinorVersionNumber.w;		; 223
	ReservedForCeAta2.w[10];				; 224-233
	MinimumBlocksPerDownloadMicrocode.w;	; 234
	MaximumBlocksPerDownloadMicrocode.w;	; 235
	Reserved10.w[19];						; 236-254
	IntegrityWord.w;						; 255
EndStructure

Structure IDEREGS 
    bFeaturesReg.b 
    bSectorCountReg.b 
    bSectorNumberReg.b 
    bCylLowReg.b 
    bCylHighReg.b 
    bDriveHeadReg.b 
    bCommandReg.b 
    bReserved.b 
EndStructure 
Structure SENDCMDINPARAMS 
    cBufferSize.l 
    irDriveRegs.IDEREGS 
    bDriveNumber.b 
    bReserved.b[3] 
    dwReserved.l[4]
EndStructure 

Structure  DRIVERSTATUS 
    bDriveError.b 
    bIDEStatus.b 
    bReserved.b[2]
    dwReserved.l[2]
EndStructure 
Structure  SENDCMDOUTPARAMS 
    cBufferSize.l 
    DStatus.DRIVERSTATUS      
    bBuffer.b[512]
EndStructure

Structure SupportedFlags
	SMART.s
	LBA48.s
	AAM.s
	NCQ.s
	NVCache.s
EndStructure

Structure SRB_IO_CONTROL
	HeaderLength.l
	Signature.b[8]
	Timeout.l
	ControlCode.l
	ReturnCode.l
	Length.l
EndStructure

Structure AttrData
   AttrID.c
   AttrName.s
   AttrValue.c
   AttrWorstValue.c
   AttrThreshold.c
   AttrRaw.q
   StatusFlags.w
EndStructure
Structure DriveInfo
	SerialNumber.s
	Model.s
	Family.s
	FirmWare.s
	BufferSize.s
	ECCBytes.s
	LBASectors.s
	CurTransferMode.s
	MaxTransferMode.s
	InterfaceType.s
	Standard.s
	Flags.SupportedFlags
	NumAttributes.l
	Attributes.AttrData[31]
	Temperature.s
	TheoriticalCapacity.s
	RealCapacity.s
	DiskStatus.s
EndStructure

#DFP_RECEIVE_DRIVE_DATA = $7C088
#DFP_SEND_DRIVE_COMMAND	= $7C084
#IOCTL_SCSI_MINIPORT    = $4D008
#IOCTL_SCSI_MINIPORT_ENABLE_SMART = $1B0504
#SCSI_MINIPORT_BUFFER_SIZE = 512

Global idsec.DeviceData
Global Dim di.DriveInfo(1)
Global hdh.l
Global HDDCount.l = -1
Global ATAVersion.l
Global bin.SENDCMDINPARAMS
Global bout.SENDCMDOUTPARAMS

Procedure.s ChangeHighLowByte(Instring.s) 
  ;Change BIG-Little Endian 
  sdummy.s="" 
  L=Len(Instring) 
  For I=1 To L Step 2 
  If (I+1)<=L 
    sdummy = sdummy + Mid(Instring,I+1,1)+Mid(Instring,I,1)  
  EndIf 
  Next I 
  ProcedureReturn sdummy
EndProcedure

Declare ReadAttributes(CurrentDrive.l, SCSITargetID.l)
Declare ReadThresholds(CurrentDrive.l, SCSITargetID.l)

Procedure.s FormatByteSize(n.q)
  Protected s.s=StrQ(n)
  Protected len=Len(s)
  Protected ret.s
 
  For i=0 To len-1
    If i And Not i%3 : ret="." + ret : EndIf; "." is the greek symbol for separating thousands. Use your own.
    ret= Mid(s,len-i,1) +ret
  Next
 
  ProcedureReturn ret
EndProcedure

Procedure.s c2str(num.d, demical.l=0)
;This procedure is used to change the english "." demical separator to the greek ",".
;Use yor own symbol is you want.
ProcedureReturn ReplaceString(StrD(num,demical), ".", ",")
EndProcedure

Procedure OpenSmart(CurrentDrive.l, SCSIPort.l)
If CurrentDrive >= 0; ATA
	Select OSVersion()
		Case #PB_OS_Windows_95, #PB_OS_Windows_98, #PB_OS_Windows_ME
			hdh = CreateFile_("\\.\SMARTVSD.VXD", 0, 0, 0, #CREATE_NEW, 0, 0)
		Default
			hdh = CreateFile_("\\.\PhysicalDrive" + Str(CurrentDrive),#GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ | #FILE_SHARE_WRITE,0, #OPEN_EXISTING, 0, 0) 
	EndSelect
Else; SCSI
	hdh = CreateFile_("\\.\Scsi" + Str(SCSIPort) + ":", #GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ | #FILE_SHARE_WRITE, #Null, #OPEN_EXISTING, 0, #Null)
EndIf
EndProcedure

Procedure.s GetAttributeName(AttribID.l)
Select AttribID
	Case 0
		ProcedureReturn "Invalid Attribute"
	Case 1
		ProcedureReturn "Raw Read Error Rate"
	Case 2
		ProcedureReturn "ThroughPut Performance"
	Case 3
		ProcedureReturn "Spin Up Time"
	Case 4
		ProcedureReturn "Start/Stop Count"
	Case 5
		ProcedureReturn "Reallocated Sector Count"
	Case 6
		ProcedureReturn "Read Channel Margin"
	Case 7
		ProcedureReturn "Seek Error Rate"
	Case 8
		ProcedureReturn "Seek Time Performance"
	Case 9
		ProcedureReturn "Power On Hours Count"
	Case 10
		ProcedureReturn "Spin Retry Count"
	Case 11
		ProcedureReturn "Calibration Retry Count"
	Case 12
		ProcedureReturn "Power Cycle Count"
	Case 13
		ProcedureReturn "Soft Read Error Rate"
	Case 189
		ProcedureReturn "High Fly Writes (WDC)"
	Case 190
		If FindString(di(HDDCount)\Model,"Seagate",1) > 0 
			ProcedureReturn "Temperature Difference from 100"
		Else
			ProcedureReturn "Airflow Temperature (WDC)"
		EndIf
	Case 191
		ProcedureReturn "G Sense Error Rate"
	Case 192
		ProcedureReturn "Power Off Retract Cycle"
	Case 193
		ProcedureReturn "Load/Unload Cycle Count"
	Case 194
		ProcedureReturn "Temperature"
	Case 195
		ProcedureReturn "Hardware ECC Recovered"
	Case 196
		ProcedureReturn "Reallocation Events Count"
	Case 197
		ProcedureReturn "Current Pending Sector Count"
	Case 198
		ProcedureReturn "Uncorrectable Sector Count"
	Case 199
		ProcedureReturn "Ultra DMA CRC Error Rate"
	Case 200
		ProcedureReturn "Write Error Rate / Multi-Zone Error Rate"
	Case 201
		ProcedureReturn "Soft Read Error Rate"
	Case 202
		ProcedureReturn "Data Address Mark errors"
	Case 203
		ProcedureReturn "Run Out Cancel"
	Case 204
		ProcedureReturn "Soft ECC Correction"
	Case 205
		ProcedureReturn "Thermal Asperity Rate"
	Case 206
		ProcedureReturn "Flying Height"
	Case 207
		ProcedureReturn "Spin High Current"
	Case 208
		ProcedureReturn "Spin Buzz"
	Case 209
		ProcedureReturn "Offline Seek Performance"
	Case 211
		ProcedureReturn "Vibration During Write"
	Case 212
		ProcedureReturn "Shock During Write"
	Case 220
		ProcedureReturn "Disk Shift"
	Case 221
		ProcedureReturn "G Sense Error Rate II"
	Case 222
		ProcedureReturn "Loaded Hours"
	Case 223
		ProcedureReturn "Load/Unload Retry Count"
	Case 224
		ProcedureReturn "Load Friction"
	Case 225
		ProcedureReturn "Load/Unload Cycle Count II"
	Case 226
		ProcedureReturn "Load In Time"
	Case 227
		ProcedureReturn "Torque Amplification Count"
	Case 228
		ProcedureReturn "Power Off Retract Count"
	Case 230
		ProcedureReturn "GMR Head Amplitude"
	Case 231
		ProcedureReturn "Temperature II"
	Case 240
		ProcedureReturn "Head Flying Hours"
	Case 250
		ProcedureReturn "Read Error Retry Rate"
	Default 
		ProcedureReturn "Unknown value  ( " + Str(AttribID) + " )"
EndSelect
EndProcedure

Procedure.l CheckSmartEnabled(CurrentDrive.l,SCSIPort.l, SCSITargetID.l)
lBytesReturned.l=0
OpenSmart(CurrentDrive, SCSIPort)
If hdh
	If CurrentDrive >= 0
		With bin
		\irDriveRegs\bFeaturesReg = $D8;SMART_ENABLE_SMART_OPERATIONS
		\irDriveRegs\bSectorCountReg = 1
		\irDriveRegs\bSectorNumberReg = 1
		\irDriveRegs\bCylLowReg = $4F;SMART_CYL_LOW
		\irDriveRegs\bCylHighReg = $C2;SMART_CYL_HI
		\irDriveRegs\bCommandReg = $B0;IDE_EXECUTE_SMART_FUNCTION
		
			\bDriveNumber = CurrentDrive
			\cBufferSize = 0
			If (CurrentDrive & 1)
				\irDriveRegs\bDriveHeadReg = $B0
			Else
				\irDriveRegs\bDriveHeadReg = $A0
			EndIf
		EndWith
		ProcedureReturn DeviceIoControl_(hdh, #DFP_SEND_DRIVE_COMMAND, @bin, SizeOf(SENDCMDINPARAMS), @bout, SizeOf(SENDCMDOUTPARAMS), @lBytesReturned, 0)
	Else
		Dim buffer.b(SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE)
		*p.SRB_IO_CONTROL      = @buffer()
		*pin.SENDCMDINPARAMS   = @buffer() + SizeOf(SRB_IO_CONTROL)
		*pout.SENDCMDOUTPARAMS = *pin
		With *p
			\HeaderLength = SizeOf(SRB_IO_CONTROL)
			\Timeout = 2
			\Length = SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE
			;If command = #DISABLE_SMART
			;	\ControlCode = #IOCTL_SCSI_MINIPORT_DISABLE_SMART
			;Else
				\ControlCode = #IOCTL_SCSI_MINIPORT_ENABLE_SMART
			;EndIf
			CopyMemory(@"SCSIDISK", @\Signature, 8)
			;\Signature = "SCSIDISK"
		EndWith
		With *pin
			\irDriveRegs\bFeaturesReg	= $d8;command
			\irDriveRegs\bSectorCountReg	= 1
			\irDriveRegs\bSectorNumberReg	= 1
			\irDriveRegs\bCylLowReg		= $4f;#SMART_CYL_LOW
			\irDriveRegs\bCylHighReg	= $c2;#SMART_CYL_HI
			\irDriveRegs\bCommandReg	= $b0;#SMART_CMD
			\cBufferSize			= #SCSI_MINIPORT_BUFFER_SIZE
			\bDriveNumber			= SCSITargetID
		EndWith
		ProcedureReturn DeviceIoControl_(hdh, #IOCTL_SCSI_MINIPORT, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDINPARAMS) - 1, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE, @dummy.l, #Null)
	EndIf
EndIf
ProcedureReturn 0
EndProcedure

Procedure.s MaximumTransferMode()
;max value
Max.s
If (idsec\UltraDmaMode & $40)
	Max = "Ultra DMA 133 (Mode 6)"
ElseIf (idsec\UltraDmaMode & $20)
	Max = "Ultra DMA 100 (Mode 5)"
ElseIf (idsec\UltraDmaMode & $10)
	Max = "Ultra DMA 66 (Mode 4)"
ElseIf (idsec\UltraDmaMode & 8)
	Max = "Ultra DMA 44(Mode 3)"
ElseIf (idsec\UltraDmaMode & 4)
	Max = "Ultra DMA 33 (Mode 2)"
ElseIf (idsec\UltraDmaMode & 2)
	Max = "Ultra DMA 25 (Mode 1)"
ElseIf (idsec\UltraDmaMode & 1)
	Max = "Ultra DMA 16 (Mode 0)"
EndIf
If idsec\SerialAtaCapabilities & 8
	Max = "SATA 600"
ElseIf idsec\SerialAtaCapabilities & 4
	Max = "SATA 300"
ElseIf idsec\SerialAtaCapabilities & 2
	Max = "SATA 150"
EndIf
ProcedureReturn Max
EndProcedure

Procedure.s CurrentTransferMode()
;current value
cur.s
If (idsec\UltraDmaMode & $4000)
	Cur = "Ultra DMA 133 (Mode 6)"
ElseIf (idsec\UltraDmaMode & $2000)
	Cur = "Ultra DMA 100 (Mode 5)"
ElseIf (idsec\UltraDmaMode & $1000)
	Cur = "Ultra DMA 66 (Mode 4)"
ElseIf (idsec\UltraDmaMode & 800)
	Cur = "Ultra DMA 44(Mode 3)"
ElseIf (idsec\UltraDmaMode & 400)
	Cur = "Ultra DMA 33 (Mode 2)"
ElseIf (idsec\UltraDmaMode & 200)
	Cur = "Ultra DMA 25 (Mode 1)"
ElseIf (idsec\UltraDmaMode & 100)
	Cur = "Ultra DMA 16 (Mode 0)"
EndIf
;If Cur ="";SATA
If idsec\SerialAtaCapabilities & 8
	Cur = "SATA 600"
ElseIf idsec\SerialAtaCapabilities & 4
	Cur = "SATA 300"
ElseIf idsec\SerialAtaCapabilities & 2
	Cur = "SATA 150"
EndIf
;EndIf
If Cur = "": Cur = "Unknown": EndIf
ProcedureReturn Cur
EndProcedure

Procedure.s GetATAMajorVersion()
If idsec\MajorVersion<>0 And idsec\MajorVersion<> $FFFF
	For i.l=14 To 1 Step -1
		If (idsec\MajorVersion >> i) & 1
			ATAVersion = i
			Break
		EndIf
	Next
	If i>=8
		ProcedureReturn "ATA" + Str(i) + "-ACS"
	ElseIf i>=4
		ProcedureReturn "ATA/ATAPI-" + Str(i)
	ElseIf i=0
		ProcedureReturn "Unknown"
	Else
		ProcedureReturn "ATA-" + Str(i)
	EndIf
EndIf
ProcedureReturn "Unknown"
EndProcedure

Procedure ReadAttributes(CurrentDrive.l, SCSITargetID.l)
   cbBytesReturned.l
   Dim bArrOut.c(527)
   If CurrentDrive >= 0
	   With bin
			\cBufferSize = 512;READ_ATTRIBUTE_BUFFER_SIZE
	       \irDriveRegs\bFeaturesReg = $D0;SMART_READ_ATTRIBUTE_VALUES
	       \irDriveRegs\bSectorCountReg = 1
	       \irDriveRegs\bSectorNumberReg = 1
	       \irDriveRegs\bCylLowReg = $4F;SMART_CYL_LOW
	       \irDriveRegs\bCylHighReg = $C2;SMART_CYL_HI
	       \irDriveRegs\bDriveHeadReg = $A0
	       ;If Not IsWindowsNT Then .bDriveHeadReg = .bDriveHeadReg Or (DriveNum And 1) * 16
	       \irDriveRegs\bCommandReg = $B0;IDE_EXECUTE_SMART_FUNCTION
	       
	       \bDriveNumber = CurrentDrive
       EndWith
       ReadAttributesCmd = DeviceIoControl_(hdh, #DFP_RECEIVE_DRIVE_DATA, @bin, SizeOf(SENDCMDINPARAMS), @bArrOut(), 528, @cbBytesReturned, 0)
	Else
		Dim buffer.b(SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE)
		*p.SRB_IO_CONTROL      = @buffer()
		*pin.SENDCMDINPARAMS   = @buffer() + SizeOf(SRB_IO_CONTROL)
		*pout.SENDCMDOUTPARAMS = *pin
		
		With *p
			\HeaderLength = SizeOf(SRB_IO_CONTROL)
			\Timeout = 2
			\Length = SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE
			\ControlCode = $1b0502;#IOCTL_SCSI_MINIPORT_ENABLE_SMART
			CopyMemory(@"SCSIDISK", @\Signature, 8)
		EndWith
		With *pin
			\irDriveRegs\bFeaturesReg	= $d0;command
			\irDriveRegs\bSectorCountReg	= 1
			\irDriveRegs\bSectorNumberReg	= 1
			\irDriveRegs\bCylLowReg		= $4f;#SMART_CYL_LOW
			\irDriveRegs\bCylHighReg	= $c2;#SMART_CYL_HI
			\irDriveRegs\bCommandReg	= $b0;#SMART_CMD
			\cBufferSize			= #SCSI_MINIPORT_BUFFER_SIZE
			\bDriveNumber			= SCSITargetID
		EndWith
		bRet = DeviceIoControl_(hdh, #IOCTL_SCSI_MINIPORT, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDINPARAMS) - 1, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE, @dummy.l, #Null)
		CopyMemory(@buffer() + SizeOf(SRB_IO_CONTROL),@bArrOut(), SizeOf(SENDCMDOUTPARAMS))
	EndIf 
	For i = 0 To 29
		If bArrOut(18 + i * 12) > 0
			di(HDDCount)\Attributes[i]\AttrID = bArrOut(18 + i * 12)
         di(HDDCount)\Attributes[i]\AttrName = GetAttributeName(bArrOut(18 + i * 12))
         CopyMemory(@bArrOut(23 + i * 12), @di(HDDCount)\Attributes[i]\AttrRaw, 6)
         di(HDDCount)\Attributes[i]\AttrValue = bArrOut(21 + i * 12)
         di(HDDCount)\Attributes[i]\AttrWorstValue = bArrOut(22 + i * 12)
         If bArrOut(18 + i * 12) = $C2; Temperature
         	di(HDDCount)\Temperature = Str(di(HDDCount)\Attributes[i]\AttrRaw & $FF) + " " +Chr(176)+"C"
         EndIf
         di(HDDCount)\NumAttributes + 1
      EndIf
  Next
EndProcedure

Procedure ReadThresholds(CurrentDrive.l, SCSITargetID.l)
	cbBytesReturned.l
	Dim bArrOut.c(527)
	If CurrentDrive >= 0
	  	With bin
			\cBufferSize = 512;READ_ATTRIBUTE_BUFFER_SIZE
			\irDriveRegs\bFeaturesReg = $D1;SMART_READ_ATTRIBUTE_THRESHOLDS
			\irDriveRegs\bSectorCountReg = 1
			\irDriveRegs\bSectorNumberReg = 1
			\irDriveRegs\bCylLowReg = $4F;SMART_CYL_LOW
			\irDriveRegs\bCylHighReg = $C2;SMART_CYL_HI
			
			\irDriveRegs\bDriveHeadReg = $A0
			;If Not IsWindowsNT Then .bDriveHeadReg = .bDriveHeadReg Or (DriveNum And 1) * 16
			\irDriveRegs\bCommandReg = $B0;IDE_EXECUTE_SMART_FUNCTION
			\bDriveNumber = CurrentDrive
		EndWith
		ReadAttributesCmd = DeviceIoControl_(hdh, #DFP_RECEIVE_DRIVE_DATA, @bin, SizeOf(SENDCMDINPARAMS), @bArrOut(), 528, @cbBytesReturned, 0)
	Else
		Dim buffer.b(SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE)
		*p.SRB_IO_CONTROL      = @buffer()
		*pin.SENDCMDINPARAMS   = @buffer() + SizeOf(SRB_IO_CONTROL)
		*pout.SENDCMDOUTPARAMS = *pin
		
		With *p
			\HeaderLength = SizeOf(SRB_IO_CONTROL)
			\Timeout = 2
			\Length = SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE
			\ControlCode = $1b0503
			CopyMemory(@"SCSIDISK", @\Signature, 8)
		EndWith
		With *pin
			\irDriveRegs\bFeaturesReg	= $d1;command
			\irDriveRegs\bSectorCountReg	= 1
			\irDriveRegs\bSectorNumberReg	= 1
			\irDriveRegs\bCylLowReg		= $4f;#SMART_CYL_LOW
			\irDriveRegs\bCylHighReg	= $c2;#SMART_CYL_HI
			\irDriveRegs\bCommandReg	= $b0;#SMART_CMD
			\cBufferSize			= #SCSI_MINIPORT_BUFFER_SIZE
			\bDriveNumber			= SCSITargetID
		EndWith
		bRet = DeviceIoControl_(hdh, #IOCTL_SCSI_MINIPORT, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDINPARAMS) - 1, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE, @dummy.l, #Null)
		CopyMemory(@buffer() + SizeOf(SRB_IO_CONTROL),@bArrOut(), SizeOf(SENDCMDOUTPARAMS))
	EndIf
  For i=0 To 29
  	If bArrOut(18 + i * 12) > 0
  		For j.l=0 To di(HDDCount)\NumAttributes
  			If bArrOut(18 + i * 12) = di(HDDCount)\Attributes[j]\AttrID
  				di(HDDCount)\Attributes[j]\AttrThreshold = bArrOut(19 + i * 12)
  			EndIf
  		Next
  	EndIf
  Next
EndProcedure

Procedure.s DiskStatus()
error.l
caution.l
flagUnknown.l = 1
For j = 0 To di(HDDCount)\NumAttributes-1
	If di(HDDCount)\Attributes[j]\AttrID <> $BE And di(HDDCount)\Attributes[j]\AttrThreshold <> 0 And di(HDDCount)\Attributes[j]\AttrValue <= di(HDDCount)\Attributes[J]\AttrThreshold
		error+1
	EndIf
	Select di(HDDCount)\Attributes[j]\AttrID
;		Case 5: ;;  Reallocated Sectors Count
;; 		Case 0xC4: ;  Reallocation Event Count
;		Case $C5:; ;  Current Pending Sector Count
;		Case $C6: ;;  Off-Line Scan Uncorrectable Sector Count
		Case 5, $C4, $C5, $C6
			If di(HDDCount)\Attributes[j]\AttrRaw & $00FFFFFFFF = $FFFFFFFF
				flagUnknown = 0
			Else
				caution + di(HDDCount)\Attributes[j]\AttrRaw & $FF + (di(HDDCount)\Attributes[j]\AttrRaw >> 8) & $FF
				flagUnknown = 0
			EndIf
	EndSelect
Next

	If Error > 0
		ProcedureReturn "Bad"
	ElseIf flagUnknown = 1
		ProcedureReturn "Unknown"
	ElseIf caution > 0
		ProcedureReturn "Attention"
	Else
		ProcedureReturn "Good"
	EndIf

EndProcedure

Procedure.l HDDInfo(CurrentDrive.l, SCSIPort.l, SCSITargetID.l)
	If CheckSmartEnabled(CurrentDrive,SCSIPort, SCSITargetID)
		If CurrentDrive >= 0
			Dim bout.b(527)
			With bin
	  	      \cBufferSize = 512 ;IDENTIFY_BUFFER_SIZE
	  	      \irDriveRegs\bFeaturesReg = 0
	  	      \irDriveRegs\bSectorCountReg = 1
	         \irDriveRegs\bSectorNumberReg = 1
	         \irDriveRegs\bCylLowReg = 0
	         \irDriveRegs\bCylHighReg = 0
	         \irDriveRegs\bDriveHeadReg = $A0
	         ;If Not IsWindowsNT Then .bDriveHeadReg = .bDriveHeadReg Or (DriveNum And 1) * 16
	         \irDriveRegs\bCommandReg = $EC;CByte(IDCmd)
         
           	\bDriveNumber = CurrentDrive
          EndWith
         Result=DeviceIoControl_(hdh, #DFP_RECEIVE_DRIVE_DATA, @bin, SizeOf(SENDCMDINPARAMS), @bout(), 528,@dummy,0)
         CopyMemory(@bout(16),@idsec,512)
      Else
      	Dim Buffer.b(SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE)
			*p.SRB_IO_CONTROL      = @buffer()
			*pin.SENDCMDINPARAMS   = @buffer() + SizeOf(SRB_IO_CONTROL)
			*pout.SENDCMDOUTPARAMS = *pin
			With *p
				\HeaderLength = SizeOf(SRB_IO_CONTROL)
				\TimeOut = 2
				\length = SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE
				\ControlCode = $1B0501
				CopyMemory(@"SCSIDISK", @\Signature, 8)
			EndWith
			With *pin
				\irDriveRegs\bCommandReg	= $EC;#SMART_CMD
				\bDriveNumber			= SCSITargetID
			EndWith
			bRet = DeviceIoControl_(hdh, #IOCTL_SCSI_MINIPORT, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDINPARAMS) - 1, @buffer(), SizeOf(SRB_IO_CONTROL) + SizeOf(SENDCMDOUTPARAMS) + #SCSI_MINIPORT_BUFFER_SIZE, @dummy.i, #Null)
			CopyMemory(@buffer() + SizeOf(SRB_IO_CONTROL)+16,@idsec, SizeOf(SENDCMDOUTPARAMS))
		EndIf
		If dummy>0
			HDDCount + 1
			If HDDCount > 1:Redim di.DriveInfo(HDDCount): EndIf
			di(HDDCount)\SerialNumber =Trim(ChangeHighLowByte(PeekS(@idsec\SerialNumber[0],20)))
			di(HDDCount)\Model = Trim(ChangeHighLowByte(PeekS(@idsec\ModelNumber[0],40)))
			di(HDDCount)\Family = DiskFamily(di(HDDCount)\Model)
			di(HDDCount)\FirmWare = Trim(ChangeHighLowByte(PeekS(@idsec\FirmwareRev[0],8)))
			di(HDDCount)\BufferSize = Str(idsec\BufferSize / 2) + " KB"; * 512 / 1024 in KBs.
			di(HDDCount)\ECCBytes = Str(idsec\ECCSize) + " bytes"
			di(HDDCount)\LBASectors = FormatByteSize(idsec\MaxUserLba)
			di(HDDCount)\CurTransferMode = CurrentTransferMode()
			di(HDDCount)\MaxTransferMode = MaximumTransferMode()
			If idsec\SerialAtaCapabilities <>0 And SerialAtaCapabilities <> $FFFF
				di(HDDCount)\InterfaceType = "Serial ATA"
			Else
				di(HDDCount)\InterfaceType = "Parallel ATA"
			EndIf
			di(HDDCount)\Standard = GetATAMajorVersion()
			If idsec\MaxUserLba > 0
				di(HDDCount)\TheoriticalCapacity = c2str(idsec\MaxUserLba * 512 / 1000000000,2) + " GB"
				di(HDDCount)\RealCapacity = c2str(idsec\MaxUserLba * 512 / (1024*1024*1024),2) + " GB"
			ElseIf idsec\TotalAddressableSectors > 0
				di(HDDCount)\TheoriticalCapacity = c2str(idsec\TotalAddressableSectors * 512 / 1000000000,2) + " GB"
				di(HDDCount)\RealCapacity = c2str(idsec\TotalAddressableSectors * 512 / (1024*1024*1024),2) + " GB"
			Else
				di(HDDCount)\TheoriticalCapacity = "Not Available"
				di(HDDCount)\RealCapacity = "Not Available"
			EndIf
			If ATAVersion >= 3 And idsec\CommandSetSupported1 & 1
				di(HDDCount)\flags\SMART = "YES"
			Else
				di(HDDCount)\flags\SMART = "NO"
			EndIf
			If ATAVersion >= 5 And idsec\CommandSetSupported2 & (1 << 10)
				di(HDDCount)\flags\LBA48 = "YES"
			Else
				di(HDDCount)\flags\LBA48 = "NO"
			EndIf
			If ATAVersion >= 5 And idsec\CommandSetSupported2 & (1 << 9)
				di(HDDCount)\flags\AAM = "YES"
			Else
				di(HDDCount)\flags\AAM = "NO"
			EndIf
			If ATAVersion >= 6 And idsec\SerialAtaCapabilities & (1 << 8)
				di(HDDCount)\flags\NCQ = "YES"
			Else
				di(HDDCount)\flags\NCQ = "NO"
			EndIf
			If ATAVersion >= 7 And idsec\NvCacheCapabilities & 1
				di(HDDCount)\flags\NVCache = "YES"
			Else
				di(HDDCount)\flags\NVCache = "NO"
			EndIf
			ReadAttributes(CurrentDrive, SCSITargetID)
			ReadThresholds(CurrentDrive, SCSITargetID)
			If di(HDDCount)\Temperature = "": di(HDDCount)\Temperature = "Not Available": EndIf
			di(HDDCount)\DiskStatus = DiskStatus()
			ProcedureReturn 1
		Else
			ProcedureReturn 0
		EndIf
	Else
		ProcedureReturn 0
	EndIf
;EndIf
EndProcedure

For i=0 To 5
	HDDInfo(i,-1,-1)
Next
For i=0 To 3
	For ii=0 To 3
		HDDInfo(-1,i,ii)
	Next
Next

If OpenWindow(0, 100, 200, 500, 620, "Hard Disk Info", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
If CreateGadgetList(WindowID(0))   
 ListIconGadget(0,5,40,490,260,"Item",160,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
 AddGadgetColumn(0,1,"Data",300)
 ListIconGadget(1,5,310,490,300,"ID",40,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
 AddGadgetColumn(1,1,"Name",210)
 AddGadgetColumn(1,2,"Current",50)
 AddGadgetColumn(1,3,"Worst",50)
 AddGadgetColumn(1,4,"Threshold",50)
 AddGadgetColumn(1,5,"Raw",80)
 ComboBoxGadget(2, 5, 10, 300, 20)
 TextGadget(3,320,14,150,20,"<-- Please select a drive.")
EndIf

For i=0 To HDDCount
	AddGadgetItem(2,-1,di(i)\Model)
Next

  Repeat
    EventID = WaitWindowEvent()
    If EventID = #PB_Event_CloseWindow
      Quit = 1
    ElseIf EventID = #PB_Event_Gadget
    	If EventGadget() = 2
      	If CurrentHDD <> GetGadgetState(2)
				CurrentHDD = GetGadgetState(2)
		    	If CurrentHDD < 0: CurrentHDD = 0: EndIf
				SetGadgetState(2, CurrentHDD)
				AddGadgetItem(0,-1,"Model"+Chr(10)+di(CurrentHDD)\Model)
				AddGadgetItem(0,-1,"Family"+Chr(10)+di(CurrentHDD)\Family)
				AddGadgetItem(0,-1,"Serial Number"+Chr(10)+di(CurrentHDD)\SerialNumber)
				AddGadgetItem(0,-1,"FirmWare"+Chr(10)+di(CurrentHDD)\FirmWare)
				AddGadgetItem(0,-1,"Buffer Size"+Chr(10)+di(CurrentHDD)\BufferSize)
				AddGadgetItem(0,-1,"ECC Bytes"+Chr(10)+di(CurrentHDD)\ECCBytes)
				AddGadgetItem(0,-1,"LBA Sectors"+Chr(10)+di(CurrentHDD)\LBASectors)
				AddGadgetItem(0,-1,"Theor Capacity"+Chr(10)+di(CurrentHDD)\TheoriticalCapacity)
				AddGadgetItem(0,-1,"Real Capacity"+Chr(10)+di(CurrentHDD)\RealCapacity)
				AddGadgetItem(0,-1,"Temperature"+Chr(10)+di(CurrentHDD)\Temperature)
				AddGadgetItem(0,-1,"Cur Transfer Mode"+Chr(10)+di(CurrentHDD)\CurTransferMode)
				AddGadgetItem(0,-1,"Max Transfer Mode"+Chr(10)+di(CurrentHDD)\MaxTransferMode)
				AddGadgetItem(0,-1,"Interface Type"+Chr(10)+di(CurrentHDD)\InterfaceType)
				AddGadgetItem(0,-1,"Standard"+Chr(10)+di(CurrentHDD)\Standard)
				AddGadgetItem(0,-1,"Flags")
				AddGadgetItem(0,-1,"SMART"+Chr(10)+di(CurrentHDD)\flags\SMART)
				AddGadgetItem(0,-1,"LBA48"+Chr(10)+di(CurrentHDD)\flags\LBA48)
				AddGadgetItem(0,-1,"AAM"+Chr(10)+di(CurrentHDD)\flags\AAM)
				AddGadgetItem(0,-1,"NCQ"+Chr(10)+di(CurrentHDD)\flags\NCQ)
				AddGadgetItem(0,-1,"NVCache"+Chr(10)+di(CurrentHDD)\flags\NVCache)
				
				For i=0 To di(CurrentHDD)\NumAttributes-1
				If di(CurrentHDD)\Attributes[i]\AttrName="": Break: EndIf
				AddGadgetItem(1,-1,Str(di(CurrentHDD)\Attributes[i]\AttrID) + Chr(10) + di(CurrentHDD)\Attributes[i]\AttrName + Chr(10) + Str(di(CurrentHDD)\Attributes[i]\AttrValue) + Chr(10) + Str(di(CurrentHDD)\Attributes[i]\AttrWorstValue) + Chr(10) + Str(di(CurrentHDD)\Attributes[i]\AttrThreshold) + Chr(10) + RSet(Hex(di(CurrentHDD)\Attributes[i]\AttrRaw),12,"0"))
				Next
			EndIf
		EndIf
    EndIf

  Until Quit = 1
  
EndIf

End 
cas
Enthusiast
Enthusiast
Posts: 597
Joined: Mon Nov 03, 2008 9:56 pm

Post by cas »

Unfortunately, it is not working if you have RAID configuration...

Image

:(
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Post by fsw »

Also this should be added in the loop:

Code: Select all

ClearGadgetItems(0)
ClearGadgetItems(1)
otherwise the lists get longer and longer (duobled entries) if you have more then one hd and you are switching back and forth...
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

adding the ClearGadgetItems(0) and ClearGadgetItems(1) doesn't seem to make any difference here for me. Also the code is using depreciated functions StrQ and CreateGadgetList. It also doesn't see any external drives.

I think the WMI functions are much better for this as all hard drives are reported as well as RAID configurations.
Last edited by SFSxOI on Tue Jun 02, 2009 2:26 pm, edited 1 time in total.
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Post by doctorized »

cas wrote:Unfortunately, it is not working if you have RAID configuration...
Unfortunatelly, I have a 500GB SATA2 Seagate Baracuda drive but I do not use RAID. Also the code does not work under every version of windows Vista and Server 2008. I had installed Vista Ultimate and the code worked fine. After format, no data is returned. Something is going wrong with DeviceIOControl. Maybe some other input data is required. I will try to find a solution. If anyone knows how to fix this problem tell me.
cas
Enthusiast
Enthusiast
Posts: 597
Joined: Mon Nov 03, 2008 9:56 pm

Post by cas »

This code should work in every Windows Vista and Windows 7 version ( and in Server 2008 and 2008 R2 ) but exe must be run with administrator privileges because apps with standard user privileges can't get low disk access.
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Post by doctorized »

cas wrote:Unfortunately, it is not working if you have RAID configuration...
The RAID controller usually hides the physical hard-drives from the OS and instead presents a "logical" drive that is made up of several physical drives. This is hardly Microsoft's fault, it's by design and how hardware raids work.

The software from the RAID manufacturer usually sees all the physical drives, including all their info. We need new code to get these info.
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Post by doctorized »

I made some improvements. Download the code from:

PB 4.20: http://www.geocities.com/kc2000labs/pb/zips/HDDInfo.zip

PB 4.30 (x86 and x64): http://www.geocities.com/kc2000labs/pb/ ... o_4.30.zip
Tranquil
Addict
Addict
Posts: 952
Joined: Mon Apr 28, 2003 2:22 pm
Location: Europe

Post by Tranquil »

Hi doctorized.

Thanks for you great code. Is it also possible using your code to get the actual utilization of a harddrive? (Like Windows can show)?
Tranquil
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Post by doctorized »

Tranquil wrote:Hi doctorized.

Thanks for you great code. Is it also possible using your code to get the actual utilization of a harddrive? (Like Windows can show)?
What exactly do you mean? If we can take the mount of MBs of each folder on the disk?
Tranquil
Addict
Addict
Posts: 952
Joined: Mon Apr 28, 2003 2:22 pm
Location: Europe

Post by Tranquil »

Sorry for my bad english. :)

I'm searching for a way to determine the actual percantage of usage (load) of a harddisc like this:

Image
Tranquil
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Post by doctorized »

Tranquil wrote:Sorry for my bad english. :)

I'm searching for a way to determine the actual percantage of usage (load) of a harddisc like this:
No need to apologize for your english, there are not bad!
Now I know what you want, but I do not know how it can be done. I will check it out and If find something, I will post it.
Post Reply