Hard Disk real serial number

For issues with communication ports, protocols, etc.
Post Reply
ike
Posts: 387
Joined: Jan 17, 2011 18:59

Hard Disk real serial number

Post by ike »

How to read HD real serial nmb?
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: Hard Disk real serial number

Post by TJF »

On Debian based systems execute
  • sudo hdparm -I /dev/sda | grep "Serial Number"
bcohio2001
Posts: 556
Joined: Mar 10, 2007 15:44
Location: Ohio, USA
Contact:

Re: Hard Disk real serial number

Post by bcohio2001 »

With Windows

Code: Select all

#Include "windows.bi"

Function DriveSerNum(ByVal Drv As String) As Integer
	Dim As String DrvPath = Left(Drv,1)+":\"
	Dim As Integer GotData, SNum
	GotData = GetVolumeInformation(DrvPath,NULL,NULL,@SNum,NULL,NULL,NULL,NULL)
	Return SNum
End Function

Function DriveSerNum62(ByVal Drv As String) As String
	Dim As String HexSerNum
	Dim As Integer HexHalf
	'
	Dim As Integer GotData = DriveSerNum(Drv)
	'
	HexHalf = HiWord(GotData)
	HexSerNum = Hex(HexHalf,4)
	HexSerNum += "-"
	HexHalf = LoWord(GotData)
	HexSerNum += Hex(HexHalf,4)
	Return HexSerNum
End Function
ike
Posts: 387
Joined: Jan 17, 2011 18:59

Re: Hard Disk real serial number

Post by ike »

@bcohio That is Volume serial number and it changes when you format disk

Here is code for hard coded serial numer (I have found this code on this forum, can not find it again)
But I am not sure why it is not giving me same info always. It return same serial number but in different way???

Code: Select all

'==============================================================================

'---------------------------------------------------
'' The base I/O addresses of the *standard* primary
'' and secondary ATA interface channels.
'---------------------------------------------------

#define IOBASE1 &h1F0
#define IOBASE2 &h170

'---------------------------------------------------------------
'' The offsets of the necessary Command/Control Block registers
'' from the base I/O address. The Data Register is 16 bits wide
'' and accessed through a 16-bit I/O port. All other registers
'' are 8 bits wide and accessed through 8-bit I/O ports.
'---------------------------------------------------------------

#define DATA_OFFSET         0       '' Data Register
#define SECTOR_COUNT_OFFSET 2       '' Sector Count Register
#define CYL_LOW_OFFSET      4       '' Cylinder Low Register
#define CYL_HIGH_OFFSET     5       '' Cylinder High Register
#define DEVICE_HEAD_OFFSET  6       '' Device/Head Register
#define COMMAND_OFFSET      7       '' Command Register (write)
#define STATUS_OFFSET       7       '' Status Register (read)
#define ALT_STATUS_OFFSET   &h206   '' Alternate Status Register (read)

'------------------------------------------------------------
'' The necessary Command/Control Block bit masks. The status
'' register IDX bit is not supported for all devices and/or
'' interfaces.
'------------------------------------------------------------

#define DEVICE_HEAD_DEV_MASK  &h10  '' Device (0=master,1=slave)
#define STATUS_ERR_MASK       1     '' Last command returned an error
#define STATUS_IDX_MASK       2     '' Active once per revolution
#define STATUS_DRQ_MASK       8     '' Data Request (ready for transfer)
#define STATUS_DRDY_MASK      &h40  '' Device Ready (to accept a command)
#define STATUS_BSY_MASK       &h80  '' Device Busy

'------------------------------------
'' The Identify Device command code.
'------------------------------------

#define ATA_IDENTIFY_DEVICE   &hEC

'-------------------------------------------------------
'' Error code values returned by the IdDevice function.
'-------------------------------------------------------

#define ID_ERROR_NO_DEVICE     1
#define ID_ERROR_TIMEOUT_BSY   2
#define ID_ERROR_TIMEOUT_NODRQ 3
#define ID_ERROR_UNEXPECTED    4

'==============================================================================

dim shared as ushort s_deviceinfo(255)

'==============================================================================

#define SLEEP_MS 200

function IdDevice( basePort as integer, fSlave as integer ) as integer

    dim as integer i, dhrValue, scrValue, status

    dim as any ptr ps_deviceinfo = @s_deviceinfo(0)

    '--------------------------------------------------------
    '' Get and save the value from the Device/Head Register.
    '--------------------------------------------------------

    dhrValue = inp(basePort+DEVICE_HEAD_OFFSET)

    sleep SLEEP_MS

    '----------------------------------------------------------------
    '' Set or clear the Device/Head Register DEV bit (set for slave,
    '' clear for master) and write the value back to the register.
    '----------------------------------------------------------------

    if fSlave then
        out basePort+DEVICE_HEAD_OFFSET, dhrValue or DEVICE_HEAD_DEV_MASK
    else
        out basePort+DEVICE_HEAD_OFFSET, dhrValue and not DEVICE_HEAD_DEV_MASK
    end if

    sleep SLEEP_MS

    '------------------------------------------------------------
    '' Determine if the Sector Count Register exists by writing
    '' a test value to the register and reading the value back.
    '' If the register does not exist, indicating that no devices
    '' are connected to the channel, exit and return the
    '' appropriate error code. Otherwise, restore the original
    '' value and continue.
    ''
    '' Note that the result of the NOT operation must be masked
    '' to a byte because we are comparing it to a byte value.
    '------------------------------------------------------------

    scrValue = inp(basePort+SECTOR_COUNT_OFFSET)
    sleep SLEEP_MS
    out basePort+SECTOR_COUNT_OFFSET, not scrValue and &hFF
    sleep SLEEP_MS
    if inp(basePort+SECTOR_COUNT_OFFSET) <> (not scrValue and &hFF) then
        return ID_ERROR_NO_DEVICE
    end if
    out basePort+SECTOR_COUNT_OFFSET, scrValue
    sleep SLEEP_MS

    '---------------------------------------------------------
    '' Wait for the device to indicate that it is not busy.
    '' If the Device Busy bit in the Alternate Status Register
    '' is not clear within the delay period, exit and return
    '' the appropriate error code.
    '---------------------------------------------------------

    for i = 1 to 10
        sleep SLEEP_MS
        if (inp(baseport+ALT_STATUS_OFFSET) and STATUS_BSY_MASK) = 0 then
            exit for
        end if
    next
    if i > 10 then
        return ID_ERROR_TIMEOUT_BSY
    end if

    '----------------------------------------------------------------
    '' Send the ATA Identify Device command to the Command Register.
    '----------------------------------------------------------------

    out baseport+COMMAND_OFFSET, ATA_IDENTIFY_DEVICE
    sleep SLEEP_MS

    '-----------------------------------------------------------------------
    '' For an ATAPI device the ATA Identify Device command will return with
    '' the error bit in the Alternate Status Register set, and since we are
    '' only looking for ATA drives return ID_ERROR_NO_DEVICE.
    '-----------------------------------------------------------------------

    if inp(baseport+ALT_STATUS_OFFSET) and STATUS_ERR_MASK then
        return ID_ERROR_NO_DEVICE
    end if

    '----------------------------------------------------------
    '' Wait for the device to clear the Device Busy bit in the
    '' Alternate Status Register and set the Data Request bit.
    '' If the device does not do so within the delay period,
    '' exit and return the appropriate error code.
    '----------------------------------------------------------

    for i = 1 to 5
        sleep SLEEP_MS
        status = inp(baseport+ALT_STATUS_OFFSET)
        status and= STATUS_BSY_MASK or STATUS_DRQ_MASK
        if status = STATUS_DRQ_MASK then
            exit for
        end if
    next
    if i > 5 then
        return ID_ERROR_TIMEOUT_NODRQ
    end if

    '----------------------------------------------
    '' If the last command returned an error, exit
    '' and return the appropriate error code.
    '----------------------------------------------

    if inp(baseport+ALT_STATUS_OFFSET) and STATUS_ERR_MASK then
        return ID_ERROR_UNEXPECTED
    end if

    '-----------------------------------------------------------
    '' Read the contents of the device's sector buffer into the
    '' shared device information array. Note that the read must
    '' go through a 16-bit I/O port, so we cannot use INP.
    '-----------------------------------------------------------

    asm
        mov edi, [ps_deviceinfo]
        mov edx, [baseport]
        add edx, DATA_OFFSET
        mov ecx, 256
        rep insw
    end asm

    '------------------------------------
    '' Restore the Device/Head Register.
    '------------------------------------

    out basePort+DEVICE_HEAD_OFFSET, dhrValue

    '----------------------------
    '' Return zero for no error.
    '----------------------------

    return 0

end function

'=========================================================================

function SerialNumber() as string

    '--------------------------------------------------------
    '' Return the 20-character serial number from the shared
    '' device information array, or a null string if the
    '' serial number is not specified.
    '--------------------------------------------------------

    dim as string sn

    if s_deviceinfo(10) = 0 then exit function

    for i as integer = 10 to 19
        sn &= chr(hibyte(s_deviceinfo(i)))
        sn &= chr(lobyte(s_deviceinfo(i)))
    next

    return ltrim(sn)

end function

'=========================================================================

dim as integer r

r = IdDevice( IOBASE1, 0 )
if r = 0 then print SerialNumber() else print "Error1"
r = IdDevice( IOBASE1, -1 )
if r = 0 then print SerialNumber() else print "Error2"
r = IdDevice( IOBASE2, 0 )
if r = 0 then print SerialNumber() else print "Error3"
r = IdDevice( IOBASE2, -1 )
if r = 0 then print SerialNumber() else print "Error4"

sleep

'=========================================================================
 
Post Reply