C # obtain the hard disk serial number
// ======================== Call method =========================== ====================
Harddiskinfo HDD = atapidevice. gethddinfo (0); // the first hard disk
Console. writeline ("module number: {0}", HDD. modulenumber );
Console. writeline ("serial number: {0}", HDD. serialnumber );
Console. writeline ("firmware: {0}", HDD. Firmware );
Console. writeline ("Capacity: {0} m", HDD. capacity );
// ======================== Call method =========================== ====================
Copy the following code to a class:
Using system;
Using system. runtime. interopservices;
Using system. text;
Namespace hardware
{
[Serializable]
Public struct harddiskinfo
{
/// <Summary>
/// Model
/// </Summary>
Public String modulenumber;
/// <Summary>
/// Firmware version
/// </Summary>
Public String firmware;
/// <Summary>
/// Serial number
/// </Summary>
Public String serialnumber;
/// <Summary>
/// Capacity, in MB
/// </Summary>
Public uint capacity;
}
# Region internal structs
[Structlayout (layoutkind. Sequential, pack = 1)]
Internal struct getversionoutparams
{
Public byte bversion;
Public byte brevision;
Public byte breserved;
Public byte bidedevicemap;
Public uint fcapabilities;
[Financialas (unmanagedtype. byvalarray, sizeconst = 4)]
Public uint [] dwreserved; // for future use.
}
[Structlayout (layoutkind. Sequential, pack = 1)]
Internal struct ideregs
{
Public byte bfeaturesreg;
Public byte bsectorcounregulatory;
Public byte bsectornumberreg;
Public byte bcyllowreg;
Public byte bcylhighreg;
Public byte bdriveheadreg;
Public byte bcommandreg;
Public byte breserved;
}
[Structlayout (layoutkind. Sequential, pack = 1)]
Internal struct sendcmdinparams
{
Public uint cbuffersize;
Public ideregs irdriveregs;
Public byte bdrivenumber;
[Financialas (unmanagedtype. byvalarray, sizeconst = 3)]
Public byte [] breserved;
[Financialas (unmanagedtype. byvalarray, sizeconst = 4)]
Public uint [] dwreserved;
Public byte bbuffer;
}
[Structlayout (layoutkind. Sequential, pack = 1)]
Internal struct driverstatus
{
Public byte bdrivererror;
Public byte bidestatus;
[Financialas (unmanagedtype. byvalarray, sizeconst = 2)]
Public byte [] breserved;
[Financialas (unmanagedtype. byvalarray, sizeconst = 2)]
Public uint [] dwreserved;
}
[Structlayout (layoutkind. Sequential, pack = 1)]
Internal struct sendcmdoutparams
{
Public uint cbuffersize;
Public driverstatus;
Public idsector bbuffer;
}
[Structlayout (layoutkind. Sequential, pack = 1, size = 512)]
Internal struct idsector
{
Public ushort wgenconfig;
Public ushort wnumcyls;
Public ushort wreserved;
Public ushort wnumheads;
Public ushort wbytespertrack;
Public ushort wbytespersector;
Public ushort wsectorspertrack;
[Financialas (unmanagedtype. byvalarray, sizeconst = 3)]
Public ushort [] wvendorunique;
[Financialas (unmanagedtype. byvalarray, sizeconst = 20)]
Public byte [] sserialnumber;
Public ushort wbuffertype;
Public ushort wbuffersize;
Public ushort weccsize;
[Financialas (unmanagedtype. byvalarray, sizeconst = 8)]
Public byte [] sfirmwarerev;
[Financialas (unmanagedtype. byvalarray, sizeconst = 40)]
Public byte [] smodelnumber;
Public ushort wmorevendorunique;
Public ushort wdoublewordio;
Public ushort wcapabilities;
Public ushort wreserved1;
Public ushort wpiotiming;
Public ushort wdmatiming;
Public ushort WBS;
Public ushort wnumcurrentcyls;
Public ushort wnumcurrentheads;
Public ushort wnumcurrentsectorspertrack;
Public uint ulcurrentsectorcapacity;
Public ushort wmultsectorstuff;
Public uint ultotaladdressablesectors;
Public ushort wsingleworddma;
Public ushort wmultiworddma;
[Financialas (unmanagedtype. byvalarray, sizeconst = 128)]
Public byte [] breserved;
}
# Endregion
/// <Summary>
/// Atapi driver
/// </Summary>
Public class atapidevice
{
# Region dllimport
[Dllimport ("kernel32.dll", setlasterror = true)]
Static extern int closehandle (intptr hobject );
[Dllimport ("kernel32.dll", setlasterror = true)]
Static extern intptr createfile (
String lpfilename,
Uint dwdesiredaccess,
Uint dww.mode,
Intptr lpsecurityattributes,
Uint dwcreationdisposition,
Uint dwflagsandattributes,
Intptr htemplatefile );
[Dllimport ("kernel32.dll")]
Static extern int deviceiocontrol (
Intptr hdevice,
Uint dwiocontrolcode,
Intptr lpinbuffer,
Uint ninbuffersize,
Ref getversionoutparams lpoutbuffer,
Uint noutbuffersize,
Ref uint lpbytesreturned,
[Out] intptr lpoverlapped );
[Dllimport ("kernel32.dll")]
Static extern int deviceiocontrol (
Intptr hdevice,
Uint dwiocontrolcode,
Ref sendcmdinparams lpinbuffer,
Uint ninbuffersize,
Ref sendcmdoutparams lpoutbuffer,
Uint noutbuffersize,
Ref uint lpbytesreturned,
[Out] intptr lpoverlapped );
Const uint dfp_get_version = 0x00074080;
Const uint dfp_send_drive_command = 0x0007c084;
Const uint dfp_receive_drive_data = 0x0007c088;
Const uint generic_read = 0x80000000;
Const uint generic_write = 0x40000000;
Const uint file_1__read = 0x00000001;
Const uint file_pai_write = 0x00000002;
Const uint create_new = 1;
Const uint open_existing = 3;
# Endregion
# Region gethddinfo
/// <Summary>
/// Obtain hard disk Information
/// </Summary>
/// <Param name = "driveindex"> hard disk number </param>
/// <Returns> hard disk Information </returns>
/// <Remarks>
/// Reference lu0 article: http://lu0s1.3322.org/App/2k1103.html
/// By sunmast for everyone
/// Thanks lu0 for his great works
/// In Windows 98/Me, S. m.a. R. T is not installed by default. Copy smartvsd. Vxd to the % System % \ iosubsys directory.
/// In Windows 2000/2003, you need the permissions of the Administrators group.
/// </Remarks>
/// <Example>
/// Atapidevice. gethddinfo ()
/// </Example>
Public static harddiskinfo gethddinfo (byte driveindex)
{
Switch (environment. osversion. Platform)
{
Case platformid. win32windows:
Return gethddinfo9x (driveindex );
Case platformid. win32nt:
Return gethddinfont (driveindex );
Case platformid. win32s:
Throw new notsupportedexception ("win32s is not supported .");
Case platformid. wince:
Throw new notsupportedexception ("wince is not supported .");
Default:
Throw new notsupportedexception ("unknown platform .");
}
}
# Region gethddinfo9x
Private Static harddiskinfo gethddinfo9x (byte driveindex)
{
Getversionoutparams vers = new getversionoutparams ();
Sendcmdinparams inparam = new sendcmdinparams ();
Sendcmdoutparams outparam = new sendcmdoutparams ();
Uint bytesreturned = 0;
Intptr hdevice = createfile (
@ "[Url = file: // \. \ smartvsd] \. \ smartvsd [/url]",
0,
0,
Intptr. Zero,
Create_new,
0,
Intptr. Zero );
If (hdevice = intptr. Zero)
{
Throw new exception ("Open smartvsd. VxD failed .");
}
If (0 = deviceiocontrol (
Hdevice,
Dfp_get_version,
Intptr. Zero,
0,
Ref vers,
(Uint) Marshal. sizeof (VERs ),
Ref bytesreturned,
Intptr. Zero ))
{
Closehandle (hdevice );
Throw new exception ("deviceiocontrol failed: dfp_get_version ");
}
// If ide identify command not supported, fails
If (0 = (vers. fcapabilities & 1 ))
{
Closehandle (hdevice );
Throw new exception ("error: ide identify command not supported .");
}
If (0! = (Driveindex & 1 ))
{
Inparam. irdriveregs. bdriveheadreg = 0xb0;
}
Else
{
Inparam. irdriveregs. bdriveheadreg = 0xa0;
}
If (0! = (Vers. fcapabilities & (16> driveindex )))
{
// We don't detect a atapi device.
Closehandle (hdevice );
Throw new exception (string. Format ("drive {0} is a atapi device, we don't detect it", driveindex + 1 ));
}
Else
{
Inparam. irdriveregs. bcommandreg = 0xec;
}
Inparam. bdrivenumber = driveindex;
Inparam. irdriveregs. bsectorcounreg = 1;
Inparam. irdriveregs. bsectornumberreg = 1;
Inparam. cbuffersize = 512;
If (0 = deviceiocontrol (
Hdevice,
Dfp_receive_drive_data,
Ref inparam,
(Uint) Marshal. sizeof (inparam ),
Ref outparam,
(Uint) Marshal. sizeof (outparam ),
Ref bytesreturned,
Intptr. Zero ))
{
Closehandle (hdevice );
Throw new exception ("deviceiocontrol failed: dfp_receive_drive_data ");
}
Closehandle (hdevice );
Return getharddiskinfo (outparam. bbuffer );
}
# Endregion
# Region gethddinfont
Private Static harddiskinfo gethddinfont (byte driveindex)
{
Getversionoutparams vers = new getversionoutparams ();
Sendcmdinparams inparam = new sendcmdinparams ();
Sendcmdoutparams outparam = new sendcmdoutparams ();
Uint bytesreturned = 0;
// We start in NT/Win2000
Intptr hdevice = createfile (
String. Format (@ "[url = file: // \. \ physicaldrive {0}] \. \ physicaldrive {0}", driveindex [/url]),
Generic_read | generic_write,
File_pai_read | file_pai_write,
Intptr. Zero,
Open_existing,
0,
Intptr. Zero );
If (hdevice = intptr. Zero)
{
Throw new exception ("createfile faild .");
}
If (0 = deviceiocontrol (
Hdevice,
Dfp_get_version,
Intptr. Zero,
0,
Ref vers,
(Uint) Marshal. sizeof (VERs ),
Ref bytesreturned,
Intptr. Zero ))
{
Closehandle (hdevice );
Throw new exception (string. Format ("drive {0} may not exists.", driveindex + 1 ));
}
// If ide identify command not supported, fails
If (0 = (vers. fcapabilities & 1 ))
{
Closehandle (hdevice );
Throw new exception ("error: ide identify command not supported .");
}
// Identify the IDE drives
If (0! = (Driveindex & 1 ))
{
Inparam. irdriveregs. bdriveheadreg = 0xb0;
}
Else
{
Inparam. irdriveregs. bdriveheadreg = 0xa0;
}
If (0! = (Vers. fcapabilities & (16> driveindex )))
{
// We don't detect a atapi device.
Closehandle (hdevice );
Throw new exception (string. Format ("drive {0} is a atapi device, we don't detect it.", driveindex + 1 ));
}
Else
{
Inparam. irdriveregs. bcommandreg = 0xec;
}
Inparam. bdrivenumber = driveindex;
Inparam. irdriveregs. bsectorcounreg = 1;
Inparam. irdriveregs. bsectornumberreg = 1;
Inparam. cbuffersize = 512;
If (0 = deviceiocontrol (
Hdevice,
Dfp_receive_drive_data,
Ref inparam,
(Uint) Marshal. sizeof (inparam ),
Ref outparam,
(Uint) Marshal. sizeof (outparam ),
Ref bytesreturned,
Intptr. Zero ))
{
Closehandle (hdevice );
Throw new exception ("deviceiocontrol failed: dfp_receive_drive_data ");
}
Closehandle (hdevice );
Return getharddiskinfo (outparam. bbuffer );
}
# Endregion
Private Static harddiskinfo getharddiskinfo (idsector phdinfo)
{
Harddiskinfo hddinfo = new harddiskinfo ();
Changebyteorder (phdinfo. smodelnumber );
Hddinfo. modulenumber = encoding. ASCII. getstring (phdinfo. smodelnumber). Trim ();
Changebyteorder (phdinfo. sfirmwarerev );
Hddinfo. Firmware = encoding. ASCII. getstring (phdinfo. sfirmwarerev). Trim ();
Changebyteorder (phdinfo. sserialnumber );
Hddinfo. serialnumber = encoding. ASCII. getstring (phdinfo. sserialnumber). Trim ();
Hddinfo. capacity = phdinfo. ultotaladdressablesectors/2/1024;
Return hddinfo;
}
Private Static void changebyteorder (byte [] chararray)
{
Byte temp;
For (INT I = 0; I <chararray. length; I + = 2)
{
Temp = chararray;
Chararray= Chararray [I + 1];
Chararray [I + 1] = temp;
}
}
# Endregion
}
}