A computer components & hardware forum. HardwareBanter

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

Go Back   Home » HardwareBanter forum » General Hardware & Peripherals » General
Site Map Home Register Authors List Search Today's Posts Mark Forums Read Web Partners

Get the Serial Number with Visual Basic



 
 
Thread Tools Display Modes
  #1  
Old November 13th 03, 01:38 PM
Michael Wittmann
external usenet poster
 
Posts: n/a
Default Get the Serial Number with Visual Basic

Hi folks,

I have to write a Visual Basic 6.0 Program and need to uniquely identify a
computer in a network and the user mustn't be able to change that id while my
program is running. So the Volume Serial Number of the HDD isn't a possibility,
because you can set the Volume SN whatever you want and therefore it's not
unique in a Network. I heard that there's a manufacturer's Serial Number on the
HDD that can't be changed and that is unique (worldwide?). How can I get that SN
with VB6? Or do you have any other ideas? Like a BIOS SN?

Thanks a lot in advance,

Michael
PS: Answer in German is ok.

  #2  
Old November 13th 03, 02:55 PM
J French
external usenet poster
 
Posts: n/a
Default

On Thu, 13 Nov 2003 13:38:13 +0100, "Michael Wittmann"
wrote:

Hi folks,

I have to write a Visual Basic 6.0 Program and need to uniquely identify a
computer in a network and the user mustn't be able to change that id while my
program is running. So the Volume Serial Number of the HDD isn't a possibility,
because you can set the Volume SN whatever you want and therefore it's not
unique in a Network. I heard that there's a manufacturer's Serial Number on the
HDD that can't be changed and that is unique (worldwide?). How can I get that SN
with VB6? Or do you have any other ideas? Like a BIOS SN?


I've tried the Disk Serial number stuff, I think it is called SMART
- it does not work on one of my older disks

You could get the MAC address from the network card
- the API seems to be GetAdaptersInfo
- but it requires Win98+ or W2k+

(info in the downloadable API Guide from www.AllAPI.net )

Personally I am not so sure about this 'unique' hardware stuff

To me the only thing that is 'unique' is something that I issue, and I
*never* issue more than one of them

You only seem to be worried about keeping it 'unique' while your App
is running - this makes things simpler
- the 'unique' ID is unique to the session

Cannot you request a unique ID from a server when your App starts
- the server dishes up a 'number' which it will never dish up again

For security, I would also use an additional sequence number

Yet again, I would be inclined to go for a longer term 'unique naming'
approach
- the 'client' requests a unique ID - the server gives one
- that remains with the Client for life
- along with a Client and Server sequence number

Should the Client be cloned, then the sequence numbers are guaranteed
to fail
- which is a pretty good indicator that something fishy is going on
- also - just one of the clients will be able to continue

IMO tying a stream of transactions is safer if it is tied to data
- hardware can change
- but your server will never issue the same code twice

However here is the code I snipped some time ago for SMART
- credits unknown
- also ignore the stuff about the FSO

A small snippet in a Form
and a monster in a .BAS module

======== STUFF IN FORM ==========

Option Explicit

Private Sub Command1_Click()
Dim drv_info As DRIVE_INFO

drv_info = GetDriveInfo(0)
With drv_info
If .bDriveType = 0 Then Label1.Caption = "[Not present]"
If .bDriveType = 2 Then Label1.Caption = "[ATAPI drive - info
not available]"
If .bDriveType = 1 Then
Label1.Caption = Trim(.SerialNumber)
End If
End With

End Sub


====== STUFF IN .BAS MODULE =======

' 20th July 2002 from NG
' Works for Drive 0 - not 1

'Hi,
'
'Most hard disks sold in the last few years support SMART
(Self-Monitoring,
'Analysis, and Reporting Technology) using Microsoft scripting you can
use
'this to return the hard disk physical serial number, NOT the volume
serial
'number. This will not change with a reformat, re-install of OS etc,
etc. It
'will ONLY change if you replace the hard disk.
'
'To do this, use add a reference for Microsoft Scripting Runtime.
'
'Add the following to a .bas module (this was assembled from MSDN
online
'somewhere...)

'********************START OF BAS MODULE********************

Option Explicit

Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type
Private Declare Function GetVersionEx Lib "kernel32" Alias
"GetVersionExA" (LpVersionInformation As OSVERSIONINFO) As Long

Private Type ATTR_DATA
AttrID As Byte
AttrName As String
AttrValue As Byte
ThresholdValue As Byte
WorstValue As Byte
StatusFlags As STATUS_FLAGS
End Type

Public Type DRIVE_INFO
bDriveType As Byte
SerialNumber As String
Model As String
FirmWare As String
Cilinders As Long
Heads As Long
SecPerTrack As Long
BytesPerSector As Long
BytesperTrack As Long
NumAttributes As Byte
Attributes() As ATTR_DATA
End Type

Public Enum IDE_DRIVE_NUMBER
PRIMARY_MASTER
PRIMARY_SLAVE
SECONDARY_MASTER
SECONDARY_SLAVE
End Enum

Private Declare Function CreateFile _
Lib "kernel32" Alias "CreateFileA" _
(ByVal lpFileName As String, ByVal dwDesiredAccess As Long,
ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle _
Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function DeviceIoControl _
Lib "kernel32" (ByVal hDevice As Long, _
ByVal dwIoControlCode As Long, _
lpInBuffer As Any, _
ByVal nInBufferSize As Long, _
lpOutBuffer As Any, _
ByVal nOutBufferSize As Long, _
lpBytesReturned As Long, _
ByVal lpOverlapped As Long) As Long
Public Declare Sub CopyMemory _
Lib "kernel32" _
Alias "RtlMoveMemory" (Destination As Any, _
Source As Any, ByVal Length As Long)

Private Const GENERIC_READ = &H80000000
Private Const GENERIC_WRITE = &H40000000

Private Const FILE_SHARE_READ = &H1
Private Const FILE_SHARE_WRITE = &H2
Private Const OPEN_EXISTING = 3
Private Const FILE_ATTRIBUTE_SYSTEM = &H4
Private Const CREATE_NEW = 1

Private Const INVALID_HANDLE_VALUE = -1
Dim di As DRIVE_INFO

Public Const MAX_IDE_DRIVES = 4
' // Max number of drives assuming primary/secondary, master/slave
topology
Public Const READ_ATTRIBUTE_BUFFER_SIZE = 512
Public Const IDENTIFY_BUFFER_SIZE = 512
Public Const READ_THRESHOLD_BUFFER_SIZE = 512
Public Const OUTPUT_DATA_SIZE = IDENTIFY_BUFFER_SIZE + 16

'IOCTL commands
Public Const DFP_GET_VERSION = &H74080
Public Const DFP_SEND_DRIVE_COMMAND = &H7C084
Public Const DFP_RECEIVE_DRIVE_DATA = &H7C088

'---------------------------------------------------------------------
' GETVERSIONOUTPARAMS contains the data returned from the
' Get Driver Version function.
'---------------------------------------------------------------------
Public Type GETVERSIONOUTPARAMS
bVersion As Byte ' Binary driver version.
bRevision As Byte ' Binary driver revision.
bReserved As Byte ' Not used.
bIDEDeviceMap As Byte ' Bit map of IDE devices.
fCapabilities As Long ' Bit mask of driver capabilities.
dwReserved(3) As Long ' For future use.
End Type

'Bits returned in the fCapabilities member of GETVERSIONOUTPARAMS
Public Const CAP_IDE_ID_FUNCTION = 1 ' ATA ID command
supported
Public Const CAP_IDE_ATAPI_ID = 2 ' ATAPI ID command
supported
Public Const CAP_IDE_EXECUTE_SMART_FUNCTION = 4 ' SMART commannds
supported

'---------------------------------------------------------------------
' IDE registers
'---------------------------------------------------------------------
Public Type IDEREGS
bFeaturesReg As Byte ' // Used for specifying SMART "commands".
bSectorCountReg As Byte ' // IDE sector count register
bSectorNumberReg As Byte ' // IDE sector number register
bCylLowReg As Byte ' // IDE low order cylinder value
bCylHighReg As Byte ' // IDE high order cylinder value
bDriveHeadReg As Byte ' // IDE drive/head register
bCommandReg As Byte ' // Actual IDE command.
bReserved As Byte ' // reserved for future use. Must be
zero.
End Type

'---------------------------------------------------------------------
' SENDCMDINPARAMS contains the input parameters for the
' Send Command to Drive function.
'---------------------------------------------------------------------
Public Type SENDCMDINPARAMS
cBufferSize As Long ' Buffer size in bytes
irDriveRegs As IDEREGS ' Structure with drive register values.
bDriveNumber As Byte ' Physical drive number to send command
to(0,1,2,3).
bReserved(2) As Byte ' Bytes reserved
dwReserved(3) As Long ' DWORDS reserved
bBuffer() As Byte ' Input buffer.
End Type

' Valid values for the bCommandReg member of IDEREGS.
Public Const IDE_ATAPI_ID = &HA1 ' Returns ID sector for
ATAPI.
Public Const IDE_ID_FUNCTION = &HEC ' Returns ID sector for
ATA.
Public Const IDE_EXECUTE_SMART_FUNCTION = &HB0 ' Performs SMART cmd.
' Requires valid
bFeaturesReg,
' bCylLowReg, and
bCylHighReg

' Cylinder register values required when issuing SMART command
Public Const SMART_CYL_LOW = &H4F
Public Const SMART_CYL_HI = &HC2

'---------------------------------------------------------------------
' Status returned from driver
'---------------------------------------------------------------------
Public Type DRIVERSTATUS
bDriverError As Byte ' Error code from driver, or 0 if no
error.
bIDEStatus As Byte ' Contents of IDE Error register.
' Only valid when bDriverError is
SMART_IDE_ERROR.
bReserved(1) As Byte
dwReserved(1) As Long
End Type

' bDriverError values
Public Enum DRIVER_ERRORS
SMART_NO_ERROR = 0 ' No error
SMART_IDE_ERROR = 1 ' Error from IDE controller
SMART_INVALID_FLAG = 2 ' Invalid command flag
SMART_INVALID_COMMAND = 3 ' Invalid command byte
SMART_INVALID_BUFFER = 4 ' Bad buffer (null, invalid addr..)
SMART_INVALID_DRIVE = 5 ' Drive number not valid
SMART_INVALID_IOCTL = 6 ' Invalid IOCTL
SMART_ERROR_NO_MEM = 7 ' Could not lock user's buffer
SMART_INVALID_REGISTER = 8 ' Some IDE Register not valid
SMART_NOT_SUPPORTED = 9 ' Invalid cmd flag set
SMART_NO_IDE_DEVICE = 10 ' Cmd issued to device not present
' although drive number is valid
' 11-255 reserved
End Enum
'---------------------------------------------------------------------
' The following struct defines the interesting part of the IDENTIFY
' buffer:
'---------------------------------------------------------------------
Public Type IDSECTOR
wGenConfig As Integer
wNumCyls As Integer
wReserved As Integer
wNumHeads As Integer
wBytesPerTrack As Integer
wBytesPerSector As Integer
wSectorsPerTrack As Integer
wVendorUnique(2) As Integer
sSerialNumber(19) As Byte
wBufferType As Integer
wBufferSize As Integer
wECCSize As Integer
sFirmwareRev(7) As Byte
sModelNumber(39) As Byte
wMoreVendorUnique As Integer
wDoubleWordIO As Integer
wCapabilities As Integer
wReserved1 As Integer
wPIOTiming As Integer
wDMATiming As Integer
wBS As Integer
wNumCurrentCyls As Integer
wNumCurrentHeads As Integer
wNumCurrentSectorsPerTrack As Integer
ulCurrentSectorCapacity As Long
wMultSectorStuff As Integer
ulTotalAddressableSectors As Long
wSingleWordDMA As Integer
wMultiWordDMA As Integer
bReserved(127) As Byte
End Type

'---------------------------------------------------------------------
' Structure returned by SMART IOCTL for several commands
'---------------------------------------------------------------------
Public Type SENDCMDOUTPARAMS
cBufferSize As Long ' Size of bBuffer in
bytes(IDENTIFY_BUFFER_SIZE in our case)
DRIVERSTATUS As DRIVERSTATUS ' Driver status structure.
bBuffer() As Byte ' Buffer of arbitrary length in which
to store the data read from the drive.
End Type

'---------------------------------------------------------------------
' Feature register defines for SMART "sub commands"
'---------------------------------------------------------------------

Public Const SMART_READ_ATTRIBUTE_VALUES = &HD0
Public Const SMART_READ_ATTRIBUTE_THRESHOLDS = &HD1
Public Const SMART_ENABLE_DISABLE_ATTRIBUTE_AUTOSAVE = &HD2
Public Const SMART_SAVE_ATTRIBUTE_VALUES = &HD3
Public Const SMART_EXECUTE_OFFLINE_IMMEDIATE = &HD4
' Vendor specific commands:
Public Const SMART_ENABLE_SMART_OPERATIONS = &HD8
Public Const SMART_DISABLE_SMART_OPERATIONS = &HD9
Public Const SMART_RETURN_SMART_STATUS = &HDA

'---------------------------------------------------------------------
' The following structure defines the structure of a Drive Attribute
'---------------------------------------------------------------------

Public Const NUM_ATTRIBUTE_STRUCTS = 30

Public Type DRIVEATTRIBUTE
bAttrID As Byte ' Identifies which attribute
wStatusFlags As Integer 'Integer ' see bit definitions below
bAttrValue As Byte ' Current normalized value
bWorstValue As Byte ' How bad has it ever been?
bRawValue(5) As Byte ' Un-normalized value
bReserved As Byte ' ...
End Type
'---------------------------------------------------------------------
' Status Flags Values
'---------------------------------------------------------------------
Public Enum STATUS_FLAGS
PRE_FAILURE_WARRANTY = &H1
ON_LINE_COLLECTION = &H2
PERFORMANCE_ATTRIBUTE = &H4
ERROR_RATE_ATTRIBUTE = &H8
EVENT_COUNT_ATTRIBUTE = &H10
SELF_PRESERVING_ATTRIBUTE = &H20
End Enum

'---------------------------------------------------------------------
' The following structure defines the structure of a Warranty
Threshold
' Obsoleted in ATA4!
'--------------------------------------------------------------------

Public Type ATTRTHRESHOLD
bAttrID As Byte ' Identifies which attribute
bWarrantyThreshold As Byte ' Triggering value
bReserved(9) As Byte ' ...
End Type

'---------------------------------------------------------------------
' Valid Attribute IDs
'---------------------------------------------------------------------
Public Enum ATTRIBUTE_ID
ATTR_INVALID = 0
ATTR_READ_ERROR_RATE = 1
ATTR_THROUGHPUT_PERF = 2
ATTR_SPIN_UP_TIME = 3
ATTR_START_STOP_COUNT = 4
ATTR_REALLOC_SECTOR_COUNT = 5
ATTR_READ_CHANNEL_MARGIN = 6
ATTR_SEEK_ERROR_RATE = 7
ATTR_SEEK_TIME_PERF = 8
ATTR_POWER_ON_HRS_COUNT = 9
ATTR_SPIN_RETRY_COUNT = 10
ATTR_CALIBRATION_RETRY_COUNT = 11
ATTR_POWER_CYCLE_COUNT = 12
ATTR_SOFT_READ_ERROR_RATE = 13
ATTR_G_SENSE_ERROR_RATE = 191
ATTR_POWER_OFF_RETRACT_CYCLE = 192
ATTR_LOAD_UNLOAD_CYCLE_COUNT = 193
ATTR_TEMPERATURE = 194
ATTR_REALLOCATION_EVENTS_COUNT = 196
ATTR_CURRENT_PENDING_SECTOR_COUNT = 197
ATTR_UNCORRECTABLE_SECTOR_COUNT = 198
ATTR_ULTRADMA_CRC_ERROR_RATE = 199
ATTR_WRITE_ERROR_RATE = 200
ATTR_DISK_SHIFT = 220
ATTR_G_SENSE_ERROR_RATEII = 221
ATTR_LOADED_HOURS = 222
ATTR_LOAD_UNLOAD_RETRY_COUNT = 223
ATTR_LOAD_FRICTION = 224
ATTR_LOAD_UNLOAD_CYCLE_COUNTII = 225
ATTR_LOAD_IN_TIME = 226
ATTR_TORQUE_AMPLIFICATION_COUNT = 227
ATTR_POWER_OFF_RETRACT_COUNT = 228
ATTR_GMR_HEAD_AMPLITUDE = 230
ATTR_TEMPERATUREII = 231
ATTR_READ_ERROR_RETRY_RATE = 250
End Enum

Dim colAttrNames As Collection
'************************************************* **************************
' Open SMART to allow DeviceIoControl communications. Return SMART
handle
'************************************************* **************************
Private Function OpenSmart(drv_num As IDE_DRIVE_NUMBER) As Long
If IsWindowsNT Then
OpenSmart = CreateFile("\\.\PhysicalDrive" _
& CStr(drv_num), _
GENERIC_READ Or GENERIC_WRITE, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
ByVal 0&, OPEN_EXISTING, 0, 0)
Else
OpenSmart = CreateFile("\\.\SMARTVSD", _
0, 0, ByVal 0&, CREATE_NEW, 0, 0)
End If
End Function

'************************************************* **************************
' CheckSMARTEnable - Check if SMART enable
' FUNCTION: Send a SMART_ENABLE_SMART_OPERATIONS command to the drive
' bDriveNum = 0-3
'************************************************* **************************

Private Function CheckSMARTEnable(ByVal hDrive As Long, _
DriveNum As IDE_DRIVE_NUMBER) As Boolean
'Set up data structures for Enable SMART Command.
Dim SCIP As SENDCMDINPARAMS
Dim SCOP As SENDCMDOUTPARAMS
Dim lpcbBytesReturned As Long
With SCIP
.cBufferSize = 0
With .irDriveRegs
.bFeaturesReg = SMART_ENABLE_SMART_OPERATIONS
.bSectorCountReg = 1
.bSectorNumberReg = 1
.bCylLowReg = SMART_CYL_LOW
.bCylHighReg = SMART_CYL_HI
'Compute the drive number.
.bDriveHeadReg = &HA0 ' Or (DriveNum And 1) * 16
.bCommandReg = IDE_EXECUTE_SMART_FUNCTION
End With
.bDriveNumber = DriveNum
End With
CheckSMARTEnable = DeviceIoControl(hDrive, _
DFP_SEND_DRIVE_COMMAND, SCIP, _
Len(SCIP) - 4, _
SCOP, Len(SCOP) - 4, lpcbBytesReturned, ByVal
0&)
End Function

'************************************************* **************************

' DoIdentify
' Function: Send an IDENTIFY command to the drive
' DriveNum = 0-3
' IDCmd = IDE_ID_FUNCTION or IDE_ATAPI_ID
'************************************************* **************************

Private Function IdentifyDrive(ByVal hDrive As Long, _
ByVal IDCmd As Byte, _
ByVal DriveNum As IDE_DRIVE_NUMBER) As
Boolean
Dim SCIP As SENDCMDINPARAMS
Dim IDSEC As IDSECTOR
Dim bArrOut(OUTPUT_DATA_SIZE - 1) As Byte
Dim sMsg As String
Dim lpcbBytesReturned As Long
Dim barrfound(100) As Long
Dim i As Long
Dim lng As Long
' Set up data structures for IDENTIFY command.
With SCIP
.cBufferSize = IDENTIFY_BUFFER_SIZE
.bDriveNumber = CByte(DriveNum)
With .irDriveRegs
.bFeaturesReg = 0
.bSectorCountReg = 1
.bSectorNumberReg = 1
.bCylLowReg = 0
.bCylHighReg = 0
' Compute the drive number.
.bDriveHeadReg = &HA0
If Not IsWindowsNT Then _
.bDriveHeadReg = .bDriveHeadReg _
Or (DriveNum And 1) * 16
' The command can either be IDE identify or ATAPI identify.
.bCommandReg = CByte(IDCmd)
End With
End With
If DeviceIoControl(hDrive, DFP_RECEIVE_DRIVE_DATA, _
SCIP, Len(SCIP) - 4, _
bArrOut(0), OUTPUT_DATA_SIZE, _
lpcbBytesReturned, ByVal 0&) Then
IdentifyDrive = True
CopyMemory IDSEC, bArrOut(16), Len(IDSEC)
di.Model = SwapStringBytes(StrConv(IDSEC.sModelNumber,
vbUnicode))
di.FirmWare = SwapStringBytes(StrConv(IDSEC.sFirmwareRev,
vbUnicode))
di.SerialNumber = SwapStringBytes(StrConv(IDSEC.sSerialNumber,
vbUnicode))
di.Cilinders = IDSEC.wNumCyls
di.Heads = IDSEC.wNumHeads
di.SecPerTrack = IDSEC.wSectorsPerTrack
End If
End Function

'************************************************* **************************
' ReadAttributesCmd
' FUNCTION: Send a SMART_READ_ATTRIBUTE_VALUES command to the drive
' bDriveNum = 0-3
'************************************************* **************************

Private Function ReadAttributesCmd(ByVal hDrive As Long, _
DriveNum As IDE_DRIVE_NUMBER) As
Boolean
Dim cbBytesReturned As Long
Dim SCIP As SENDCMDINPARAMS
Dim drv_attr As DRIVEATTRIBUTE
Dim bArrOut(OUTPUT_DATA_SIZE - 1) As Byte
Dim sMsg As String
Dim i As Long
With SCIP
' Set up data structures for Read Attributes SMART Command.
.cBufferSize = READ_ATTRIBUTE_BUFFER_SIZE
.bDriveNumber = DriveNum
With .irDriveRegs
.bFeaturesReg = SMART_READ_ATTRIBUTE_VALUES
.bSectorCountReg = 1
.bSectorNumberReg = 1
.bCylLowReg = SMART_CYL_LOW
.bCylHighReg = SMART_CYL_HI
' Compute the drive number.
.bDriveHeadReg = &HA0
If Not IsWindowsNT Then _
.bDriveHeadReg = .bDriveHeadReg Or _
(DriveNum And 1) * 16
.bCommandReg = IDE_EXECUTE_SMART_FUNCTION
End With
End With
ReadAttributesCmd = DeviceIoControl(hDrive, DFP_RECEIVE_DRIVE_DATA,
_
SCIP, Len(SCIP) - 4, _
bArrOut(0), _
OUTPUT_DATA_SIZE, _
cbBytesReturned, ByVal 0&)
On Error Resume Next
For i = 0 To NUM_ATTRIBUTE_STRUCTS - 1
If bArrOut(18 + i * 12) 0 Then
di.Attributes(di.NumAttributes).AttrID = bArrOut(18 + i * 12)
di.Attributes(di.NumAttributes).AttrName _
= "Unknown value (" & bArrOut(18 + i * 12) &
")"
' di.Attributes(di.NumAttributes).AttrName = colAttrNames
(CStr(bArrOut(18 + i * 12)))
di.NumAttributes = di.NumAttributes + 1
ReDim Preserve di.Attributes(di.NumAttributes)
CopyMemory di.Attributes(di.NumAttributes).StatusFlags, _
bArrOut(19 + i * 12), 2
di.Attributes(di.NumAttributes).AttrValue = bArrOut(21 + i *
12)
di.Attributes(di.NumAttributes).WorstValue = bArrOut(22 + i *
12)
End If
Next i
End Function

Private Function ReadThresholdsCmd(ByVal hDrive As Long, _
DriveNum As IDE_DRIVE_NUMBER) As Boolean
Dim cbBytesReturned As Long
Dim SCIP As SENDCMDINPARAMS
Dim IDSEC As IDSECTOR
Dim bArrOut(OUTPUT_DATA_SIZE - 1) As Byte
Dim sMsg As String
Dim thr_attr As ATTRTHRESHOLD
Dim i As Long, j As Long
With SCIP
' Set up data structures for Read Attributes SMART Command.
.cBufferSize = READ_THRESHOLD_BUFFER_SIZE
.bDriveNumber = DriveNum
With .irDriveRegs
.bFeaturesReg = SMART_READ_ATTRIBUTE_THRESHOLDS
.bSectorCountReg = 1
.bSectorNumberReg = 1
.bCylLowReg = SMART_CYL_LOW
.bCylHighReg = SMART_CYL_HI
' Compute the drive number.
.bDriveHeadReg = &HA0
If Not IsWindowsNT Then _
.bDriveHeadReg = .bDriveHeadReg Or _
(DriveNum And 1) * 16
.bCommandReg = IDE_EXECUTE_SMART_FUNCTION
End With
End With
ReadThresholdsCmd = DeviceIoControl(hDrive, _
DFP_RECEIVE_DRIVE_DATA, SCIP, _
Len(SCIP) - 4, bArrOut(0), _
OUTPUT_DATA_SIZE, cbBytesReturned, ByVal 0&)
For i = 0 To NUM_ATTRIBUTE_STRUCTS - 1
CopyMemory thr_attr, bArrOut(18 + i * Len(thr_attr)),
Len(thr_attr)
If thr_attr.bAttrID 0 Then
For j = 0 To UBound(di.Attributes)
If thr_attr.bAttrID = di.Attributes(j).AttrID Then
di.Attributes(j).ThresholdValue =
thr_attr.bWarrantyThreshold
Exit For
End If
Next j
End If
Next i
End Function

Private Function GetSmartVersion(ByVal hDrive As Long, VersionParams
As GETVERSIONOUTPARAMS) As Boolean
Dim cbBytesReturned As Long
GetSmartVersion = DeviceIoControl(hDrive, _
DFP_GET_VERSION, ByVal 0&, 0, _
VersionParams, _
Len(VersionParams), _
cbBytesReturned, ByVal 0&)
End Function

Public Function GetDriveInfo(DriveNum As IDE_DRIVE_NUMBER) As
DRIVE_INFO
Dim hDrive As Long
Dim VerParam As GETVERSIONOUTPARAMS
Dim cb As Long

di.bDriveType = 0
di.NumAttributes = 0

ReDim di.Attributes(0)

hDrive = OpenSmart(DriveNum)
If hDrive = INVALID_HANDLE_VALUE Then Exit Function
If Not GetSmartVersion(hDrive, VerParam) Then Exit Function
If Not IsBitSet(VerParam.bIDEDeviceMap, DriveNum) Then Exit
Function
di.bDriveType = 1 + Abs(IsBitSet(VerParam.bIDEDeviceMap, DriveNum
+ 4))
If Not CheckSMARTEnable(hDrive, DriveNum) Then Exit Function
FillAttrNameCollection
Call IdentifyDrive(hDrive, IDE_ID_FUNCTION, DriveNum)
Call ReadAttributesCmd(hDrive, DriveNum)
Call ReadThresholdsCmd(hDrive, DriveNum)
GetDriveInfo = di
CloseHandle hDrive
Set colAttrNames = Nothing
End Function

Private Function IsWindowsNT() As Boolean
Dim verinfo As OSVERSIONINFO
verinfo.dwOSVersionInfoSize = Len(verinfo)
If (GetVersionEx(verinfo)) = 0 Then Exit Function
If verinfo.dwPlatformId = 2 Then IsWindowsNT = True
End Function

Private Function IsBitSet(iBitString As Byte, ByVal lBitNo As Integer)
As Boolean
If lBitNo = 7 Then
IsBitSet = iBitString 0
Else
IsBitSet = iBitString And (2 ^ lBitNo)
End If
End Function

Private Function SwapStringBytes(ByVal sIn As String) As String
Dim sTemp As String
Dim i As Integer
sTemp = Space(Len(sIn))
For i = 1 To Len(sIn) - 1 Step 2
Mid(sTemp, i, 1) = Mid(sIn, i + 1, 1)
Mid(sTemp, i + 1, 1) = Mid(sIn, i, 1)
Next i
SwapStringBytes = sTemp
End Function

Public Sub FillAttrNameCollection()
Set colAttrNames = New Collection
With colAttrNames
.Add "ATTR_INVALID", "0"
.Add "READ_ERROR_RATE", "1"
.Add "THROUGHPUT_PERF", "2"
.Add "SPIN_UP_TIME", "3"
.Add "START_STOP_COUNT", "4"
.Add "REALLOC_SECTOR_COUNT", "5"
.Add "READ_CHANNEL_MARGIN", "6"
.Add "SEEK_ERROR_RATE", "7"
.Add "SEEK_TIME_PERF", "8"
.Add "POWER_ON_HRS_COUNT", "9"
.Add "SPIN_RETRY_COUNT", "10"
.Add "CALIBRATION_RETRY_COUNT", "11"
.Add "POWER_CYCLE_COUNT", "12"
.Add "SOFT_READ_ERROR_RATE", "13"
.Add "G_SENSE_ERROR_RATE", "191"
.Add "POWER_OFF_RETRACT_CYCLE", "192"
.Add "LOAD_UNLOAD_CYCLE_COUNT", "193"
.Add "TEMPERATURE", "194"
.Add "REALLOCATION_EVENTS_COUNT", "196"
.Add "CURRENT_PENDING_SECTOR_COUNT", "197"
.Add "UNCORRECTABLE_SECTOR_COUNT", "198"
.Add "ULTRADMA_CRC_ERROR_RATE", "199"
.Add "WRITE_ERROR_RATE", "200"
.Add "DISK_SHIFT", "220"
.Add "G_SENSE_ERROR_RATEII", "221"
.Add "LOADED_HOURS", "222"
.Add "LOAD_UNLOAD_RETRY_COUNT", "223"
.Add "LOAD_FRICTION", "224"
.Add "LOAD_UNLOAD_CYCLE_COUNTII", "225"
.Add "LOAD_IN_TIME", "226"
.Add "TORQUE_AMPLIFICATION_COUNT", "227"
.Add "POWER_OFF_RETRACT_COUNT", "228"
.Add "GMR_HEAD_AMPLITUDE", "230"
.Add "TEMPERATUREII", "231"
.Add "READ_ERROR_RETRY_RATE", "250"
End With
End Sub


'********************END OF BAS MODULE********************

'In the example assume a label called label2 on a form, could easily
be a
'string etc etc....

'Add the following to your code:

' Dim drv_info As DRIVE_INFO
'
' drv_info = GetDriveInfo(0)
' With drv_info
' If .bDriveType = 0 Then Label2.Caption = "[Not present]"
' If .bDriveType = 2 Then Label2.Caption = "[ATAPI drive - info
not available]"
' If .bDriveType = 1 Then
' Label2.Caption = Trim(.SerialNumber)
' End If
' End With
'
'Label2 will display the actual physical serial number of the drive,
NOT the
'volume number.



  #3  
Old November 13th 03, 08:44 PM
@drian
external usenet poster
 
Posts: n/a
Default

"Michael Wittmann" wrote in message
...
Hi folks,

I have to write a Visual Basic 6.0 Program and need to uniquely identify a
computer in a network and the user mustn't be able to change that id while

my
program is running. So the Volume Serial Number of the HDD isn't a

possibility,
because you can set the Volume SN whatever you want and therefore it's not
unique in a Network. I heard that there's a manufacturer's Serial Number

on the
HDD that can't be changed and that is unique (worldwide?). How can I get

that SN
with VB6? Or do you have any other ideas? Like a BIOS SN?


What's wrong with the NIC's MAC address?

@drian.


  #4  
Old November 13th 03, 10:37 PM
Michael Wittmann
external usenet poster
 
Posts: n/a
Default

What's wrong with the NIC's MAC address?
There might be also single stations using my program... There's not always a
network card in the workstation

Michael

PS: Answer only to the newsgroup you read (some people already complained)

  #5  
Old November 13th 03, 10:54 PM
Eric Gisin
external usenet poster
 
Posts: n/a
Default


"Michael Wittmann" wrote in message
...
| What's wrong with the NIC's MAC address?
| There might be also single stations using my program... There's not always a
| network card in the workstation
|
Make them buy a NIC then.

There are plenty of workstations were you cannot get a disk serial number.
RAID and poor IDE drivers.

  #6  
Old November 13th 03, 11:54 PM
mcheu
external usenet poster
 
Posts: n/a
Default

On Thu, 13 Nov 2003 13:38:13 +0100, "Michael Wittmann"
wrote::

Hi folks,

I have to write a Visual Basic 6.0 Program and need to uniquely identify a
computer in a network and the user mustn't be able to change that id while my
program is running. So the Volume Serial Number of the HDD isn't a possibility,
because you can set the Volume SN whatever you want and therefore it's not
unique in a Network. I heard that there's a manufacturer's Serial Number on the
HDD that can't be changed and that is unique (worldwide?). How can I get that SN
with VB6? Or do you have any other ideas? Like a BIOS SN?

Thanks a lot in advance,

Michael
PS: Answer in German is ok.


What about a software solution? As you're using VB, I guess it's for
windows systems. Under normal operating conditions, windows will lock
out file write access to all other apps if it's currently in use.
While not efficient, and not terribly secure, it will hamper
modification attempts so long as the program's running. Just code
your app to open a filestream to the serial number file, and keep it
open until the app closes. Just be sure to have clean up code in
place, as leaving it up to the OS can cause problems -- especially
when we're talking VB, which is flakey already.

As for uniqueness, that would be up to you to generate a unique serial
number for each installation.

If you want a hardware solution, there's the suggested MAC address
which was previously mentioned, or if you know how to do it, you could
have the program refuse to run unless the CPU ID feature is enabled.
Of course, your users would probably have issue with that.
----------------------------------------
Thanks,
MCheu
  #7  
Old November 14th 03, 12:29 AM
Michael Stum
external usenet poster
 
Posts: n/a
Default

@drian schrieb:

"Michael Wittmann" wrote

HDD that can't be changed and that is unique (worldwide?). How can I get


that SN

with VB6? Or do you have any other ideas? Like a BIOS SN?



What's wrong with the NIC's MAC address?


It can be changed by the User easily and is therefore neither Unique nor
secure.

  #8  
Old November 14th 03, 07:16 AM
@drian
external usenet poster
 
Posts: n/a
Default

"Michael Stum" wrote in message
...
@drian schrieb:

"Michael Wittmann" wrote

HDD that can't be changed and that is unique (worldwide?). How can I get


that SN

with VB6? Or do you have any other ideas? Like a BIOS SN?



What's wrong with the NIC's MAC address?


It can be changed by the User easily and is therefore neither Unique nor
secure.


The MAC address? The MAC address is a fixed, unique number embedded in the
NIC. So how do you change the MAC on your NIC card? I'm interested.

@drian.


  #9  
Old November 14th 03, 07:27 AM
@drian
external usenet poster
 
Posts: n/a
Default

"@drian" wrote in message
...
The MAC address? The MAC address is a fixed, unique number embedded in

the
NIC. So how do you change the MAC on your NIC card? I'm interested.


I'm thinking of cable modem's that have the difficult to change MAC address.

@drian.


  #10  
Old November 14th 03, 10:55 AM
Howard Henry Schlunder
external usenet poster
 
Posts: n/a
Default

It isn't clear to me if you need a unique session ID number, or a =
permanent and unique ID number identifying the computer, but in the case =
of sessions, you can use the CoCreateGuid API function to create a 128 =
bit number which is assured to a high degree of probability to be =
completely unique accross the world for now and in the future weather =
networked or not.

Howard Henry Schlunder

"Michael Wittmann" wrote in message =
...
Hi folks,
=20
I have to write a Visual Basic 6.0 Program and need to uniquely =

identify a
computer in a network and the user mustn't be able to change that id =

while my
program is running. So the Volume Serial Number of the HDD isn't a =

possibility,
because you can set the Volume SN whatever you want and therefore it's =

not
unique in a Network. I heard that there's a manufacturer's Serial =

Number on the
HDD that can't be changed and that is unique (worldwide?). How can I =

get that SN
with VB6? Or do you have any other ideas? Like a BIOS SN?
=20
Thanks a lot in advance,
=20
Michael
PS: Answer in German is ok.

 




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Modem and other on same serial, alternately? Rick General 4 October 25th 03 06:13 PM
USB, Parallel Scanner, Serial Joystick The Kid General 2 September 1st 03 04:38 AM
serial to parallel adapter Old guy General 2 July 30th 03 11:11 PM
Adding ten or so serial ports? Paul Hutchings General 4 July 23rd 03 08:54 AM
KVM Switch for Both PS/2 and AT Connectors Alien Zord General 5 July 9th 03 07:19 PM


All times are GMT +1. The time now is 08:34 PM.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright ©2004-2024 HardwareBanter.
The comments are property of their posters.