Go to the Delphi Super Page. There's a component there called DriveD, I believe. It's written by Peter Below, and it's. > >> if somebody know how I may read serial number of hard drive in my > >> application, please mail me or post message in newsgroup. > >If you're writing 32-bit stuff, it's easy. Look up the reference for.
Quote Can anyone help me with above task? I have tried everything possible (I think). Only thing I keep bumping into is how to get the hard drive serial, the one that occurs when the hard drive is formatted, not the actual hard drive serial, the one that is set at the factory. 'When a disk/diskette is formatted, Windows stores a serial number in the boot sector. This number is calculated using the system time and is not guaranteed to be unique, but it is quite unlikely that two disks taken at random have the same serial number.
![Get hard drive serial number delphi number Get hard drive serial number delphi number](http://www.devlib.net/images/screenshots/tgetdiskserial-vcl-delphi2009-screenshot.gif)
To obtain the serial number you have to call the GetVolumeInformation API function declared in the Windows unit.' Pascal Newsletter # 11 (27-NOV-2000): I think you will also find a function in the JCL (JEDI Code Library) that does the same thing.
See JclSysInfo.pas; specifically, look for function GetVolumeSerialNumber, which uses GetVolumeInfoHelper.
Dear all, I'm trying to read serial no of the hard disk as a unique id of the machine. I tried the code as follows: class function TDeviceUtils.GetDeviceId: string; const IDENTIFYBUFFERSIZE = 512; type TIDERegs = packed record bFeaturesReg: BYTE; // Used for specifying SMART 'commands'.
BSectorCountReg: BYTE; // IDE sector count register bSectorNumberReg: BYTE; // IDE sector number register bCylLowReg: BYTE; // IDE low order cylinder value bCylHighReg: BYTE; // IDE high order cylinder value bDriveHeadReg: BYTE; // IDE drive/head register bCommandReg: BYTE; // Actual IDE command. BReserved: BYTE; // reserved for future use. Must be zero. End; TSendCmdInParams = packed record // Buffer size in bytes cBufferSize: LongInt; // Structure with drive register values.
IrDriveRegs: TIDERegs; // Physical drive number to send command to (0,1,2,3). BDriveNumber: BYTE; bReserved: array 0.
2 of BYTE; dwReserved: array 0. 3 of DWORD; bBuffer: array 0. 0 of BYTE; // Input buffer. End; TIdSector = packed record wGenConfig: Word; wNumCyls: Word; wReserved: Word; wNumHeads: Word; wBytesPerTrack: Word; wBytesPerSector: Word; wSectorsPerTrack: Word; wVendorUnique: array 0. 2 of Word; sSerialNumber: array 0.
19 of CHAR; wBufferType: Word; wBufferSize: Word; wECCSize: Word; sFirmwareRev: array 0. 7 of CHAR; sModelNumber: array 0. 39 of CHAR; wMoreVendorUnique: Word; wDoubleWordIO: Word; wCapabilities: Word; wReserved1: Word; wPIOTiming: Word; wDMATiming: Word; wBS: Word; wNumCurrentCyls: Word; wNumCurrentHeads: Word; wNumCurrentSectorsPerTrack: Word; ulCurrentSectorCapacity: DWORD; wMultSectorStuff: Word; ulTotalAddressableSectors: DWORD; wSingleWordDMA: Word; wMultiWordDMA: Word; bReserved: array 0. 127 of BYTE; end; PIdSector = ^TIdSector; TDriverStatus = packed record bDriverError: BYTE; bIDEStatus: BYTE; bReserved: array 0.
1 of BYTE; dwReserved: array 0. 1 of DWORD; end; TSendCmdOutParams = packed record // bBuffer的大小 cBufferSize: DWORD; DriverStatus: TDriverStatus; bBuffer: array 0. 0 of BYTE; end; var hDevice: Thandle; cbBytesReturned: DWORD; SCIP: TSendCmdInParams; aIdOutCmd: array 0. (SizeOf(TSendCmdOutParams) + IDENTIFYBUFFERSIZE - 1) - 1 of BYTE; IdOutCmd: TSendCmdOutParams absolute aIdOutCmd; procedure ChangeByteOrder(var Data; Size: Integer); var ptr: pchar; i: Integer; c: CHAR; begin ptr:= @Data; for i:= 0 to (Size shr 1) - 1 do begin c:= ptr^; ptr^:= (ptr + 1)^; (ptr + 1)^:= c; Inc(ptr, 2); end; end; begin Result:= '; // '.
PhysicalDrive0 means the first drive, use '. PhysicalDrive1 ' for the second one, etc. HDevice:= CreateFile( '. PhysicalDrive0', GENERICREAD or GENERICWRITE, FILESHAREREAD or FILESHAREWRITE, nil, OPENEXISTING, 0, 0); if hDevice = INVALIDHANDLEVALUE then Exit; try FillChar(SCIP, SizeOf(TSendCmdInParams) - 1, #0); FillChar(aIdOutCmd, SizeOf(aIdOutCmd), #0); cbBytesReturned:= 0; // Set up data structures for IDENTIFY command. Dear all, I'm trying to read serial no of the hard disk as a unique id of the machine. I tried the code as follows: class function TDeviceUtils.GetDeviceId: string; const IDENTIFYBUFFERSIZE = 512; type TIDERegs = packed record bFeaturesReg: BYTE; // Used for specifying SMART 'commands'. BSectorCountReg: BYTE; // IDE sector count register bSectorNumberReg: BYTE; // IDE sector number register bCylLowReg: BYTE; // IDE low order cylinder value bCylHighReg: BYTE; // IDE high order cylinder value bDriveHeadReg: BYTE; // IDE drive/head register bCommandReg: BYTE; // Actual IDE command.
BReserved: BYTE; // reserved for future use. Must be zero. End; TSendCmdInParams = packed record // Buffer size in bytes cBufferSize: LongInt; // Structure with drive register values. IrDriveRegs: TIDERegs; // Physical drive number to send command to (0,1,2,3).
BDriveNumber: BYTE; bReserved: array 0. 2 of BYTE; dwReserved: array 0. 3 of DWORD; bBuffer: array 0. 0 of BYTE; // Input buffer. End; TIdSector = packed record wGenConfig: Word; wNumCyls: Word; wReserved: Word; wNumHeads: Word; wBytesPerTrack: Word; wBytesPerSector: Word; wSectorsPerTrack: Word; wVendorUnique: array 0. 2 of Word; sSerialNumber: array 0.
19 of CHAR; wBufferType: Word; wBufferSize: Word; wECCSize: Word; sFirmwareRev: array 0. 7 of CHAR; sModelNumber: array 0. 39 of CHAR; wMoreVendorUnique: Word; wDoubleWordIO: Word; wCapabilities: Word; wReserved1: Word; wPIOTiming: Word; wDMATiming: Word; wBS: Word; wNumCurrentCyls: Word; wNumCurrentHeads: Word; wNumCurrentSectorsPerTrack: Word; ulCurrentSectorCapacity: DWORD; wMultSectorStuff: Word; ulTotalAddressableSectors: DWORD; wSingleWordDMA: Word; wMultiWordDMA: Word; bReserved: array 0. 127 of BYTE; end; PIdSector = ^TIdSector; TDriverStatus = packed record bDriverError: BYTE; bIDEStatus: BYTE; bReserved: array 0.
1 of BYTE; dwReserved: array 0. 1 of DWORD; end; TSendCmdOutParams = packed record // bBuffer??? CBufferSize: DWORD; DriverStatus: TDriverStatus; bBuffer: array 0. 0 of BYTE; end; var hDevice: Thandle; cbBytesReturned: DWORD; SCIP: TSendCmdInParams; aIdOutCmd: array 0.
(SizeOf(TSendCmdOutParams) + IDENTIFYBUFFERSIZE - 1) - 1 of BYTE; IdOutCmd: TSendCmdOutParams absolute aIdOutCmd; procedure ChangeByteOrder(var Data; Size: Integer); var ptr: pchar; i: Integer; c: CHAR; begin ptr:= @Data; for i:= 0 to (Size shr 1) - 1 do begin c:= ptr^; ptr^:= (ptr + 1)^; (ptr + 1)^:= c; Inc(ptr, 2); end; end; begin Result:= '; // '. PhysicalDrive0 means the first drive, use '. PhysicalDrive1 ' for the second one, etc. HDevice:= CreateFile( '. PhysicalDrive0', GENERICREAD or GENERICWRITE, FILESHAREREAD or FILESHAREWRITE, nil, OPENEXISTING, 0, 0); if hDevice = INVALIDHANDLEVALUE then Exit; try FillChar(SCIP, SizeOf(TSendCmdInParams) - 1, #0); FillChar(aIdOutCmd, SizeOf(aIdOutCmd), #0); cbBytesReturned:= 0; // Set up data structures for IDENTIFY command. Dear all, I'm trying to read serial no of the hard disk as a unique id of the machine. I tried the code as follows: class function TDeviceUtils.GetDeviceId: string; const IDENTIFYBUFFERSIZE = 512; type TIDERegs = packed record bFeaturesReg: BYTE; // Used for specifying SMART 'commands'.
BSectorCountReg: BYTE; // IDE sector count register bSectorNumberReg: BYTE; // IDE sector number register bCylLowReg: BYTE; // IDE low order cylinder value bCylHighReg: BYTE; // IDE high order cylinder value bDriveHeadReg: BYTE; // IDE drive/head register bCommandReg: BYTE; // Actual IDE command. BReserved: BYTE; // reserved for future use. Must be zero. End; TSendCmdInParams = packed record // Buffer size in bytes cBufferSize: LongInt; // Structure with drive register values. IrDriveRegs: TIDERegs; // Physical drive number to send command to (0,1,2,3).
BDriveNumber: BYTE; bReserved: array 0. 2 of BYTE; dwReserved: array 0. 3 of DWORD; bBuffer: array 0. 0 of BYTE; // Input buffer.
End; TIdSector = packed record wGenConfig: Word; wNumCyls: Word; wReserved: Word; wNumHeads: Word; wBytesPerTrack: Word; wBytesPerSector: Word; wSectorsPerTrack: Word; wVendorUnique: array 0. 2 of Word; sSerialNumber: array 0. 19 of CHAR; wBufferType: Word; wBufferSize: Word; wECCSize: Word; sFirmwareRev: array 0. 7 of CHAR; sModelNumber: array 0. 39 of CHAR; wMoreVendorUnique: Word; wDoubleWordIO: Word; wCapabilities: Word; wReserved1: Word; wPIOTiming: Word; wDMATiming: Word; wBS: Word; wNumCurrentCyls: Word; wNumCurrentHeads: Word; wNumCurrentSectorsPerTrack: Word; ulCurrentSectorCapacity: DWORD; wMultSectorStuff: Word; ulTotalAddressableSectors: DWORD; wSingleWordDMA: Word; wMultiWordDMA: Word; bReserved: array 0.
127 of BYTE; end; PIdSector = ^TIdSector; TDriverStatus = packed record bDriverError: BYTE; bIDEStatus: BYTE; bReserved: array 0. 1 of BYTE; dwReserved: array 0. 1 of DWORD; end; TSendCmdOutParams = packed record // bBuffer??? CBufferSize: DWORD; DriverStatus: TDriverStatus; bBuffer: array 0. 0 of BYTE; end; var hDevice: Thandle; cbBytesReturned: DWORD; SCIP: TSendCmdInParams; aIdOutCmd: array 0. (SizeOf(TSendCmdOutParams) + IDENTIFYBUFFERSIZE - 1) - 1 of BYTE; IdOutCmd: TSendCmdOutParams absolute aIdOutCmd; procedure ChangeByteOrder(var Data; Size: Integer); var ptr: pchar; i: Integer; c: CHAR; begin ptr:= @Data; for i:= 0 to (Size shr 1) - 1 do begin c:= ptr^; ptr^:= (ptr + 1)^; (ptr + 1)^:= c; Inc(ptr, 2); end; end; begin Result:= '; // '.
PhysicalDrive0 means the first drive, use '. PhysicalDrive1 ' for the second one, etc.
HDevice:= CreateFile( '. PhysicalDrive0', GENERICREAD or GENERICWRITE, FILESHAREREAD or FILESHAREWRITE, nil, OPENEXISTING, 0, 0); if hDevice = INVALIDHANDLEVALUE then Exit; try FillChar(SCIP, SizeOf(TSendCmdInParams) - 1, #0); FillChar(aIdOutCmd, SizeOf(aIdOutCmd), #0); cbBytesReturned:= 0; // Set up data structures for IDENTIFY command. George, Yes, it is for windows only. It is not perfect but can give you some clues. Each platform you will need to find a different approach. There is not such component that works on all platforms that I am aware of. I am in need of that either.
There is no HD on an android for example. You can use the build Serial number, but you will find that it is not always reliable. Cheap chinese androids commonly repeats the same serials.
Not sure how it works on apple platforms. So it is quite a work to find out. Dear all, I'm trying to read serial no of the hard disk as a unique id of the machine. I tried the code as follows: class function TDeviceUtils.GetDeviceId: string; const IDENTIFYBUFFERSIZE = 512; type TIDERegs = packed record bFeaturesReg: BYTE; // Used for specifying SMART 'commands'. BSectorCountReg: BYTE; // IDE sector count register bSectorNumberReg: BYTE; // IDE sector number register bCylLowReg: BYTE; // IDE low order cylinder value bCylHighReg: BYTE; // IDE high order cylinder value bDriveHeadReg: BYTE; // IDE drive/head register bCommandReg: BYTE; // Actual IDE command. BReserved: BYTE; // reserved for future use. Must be zero.
End; TSendCmdInParams = packed record // Buffer size in bytes cBufferSize: LongInt; // Structure with drive register values. IrDriveRegs: TIDERegs; // Physical drive number to send command to (0,1,2,3). BDriveNumber: BYTE; bReserved: array 0.
2 of BYTE; dwReserved: array 0. 3 of DWORD; bBuffer: array 0. 0 of BYTE; // Input buffer.
End; TIdSector = packed record wGenConfig: Word; wNumCyls: Word; wReserved: Word; wNumHeads: Word; wBytesPerTrack: Word; wBytesPerSector: Word; wSectorsPerTrack: Word; wVendorUnique: array 0. 2 of Word; sSerialNumber: array 0. 19 of CHAR; wBufferType: Word; wBufferSize: Word; wECCSize: Word; sFirmwareRev: array 0. 7 of CHAR; sModelNumber: array 0. 39 of CHAR; wMoreVendorUnique: Word; wDoubleWordIO: Word; wCapabilities: Word; wReserved1: Word; wPIOTiming: Word; wDMATiming: Word; wBS: Word; wNumCurrentCyls: Word; wNumCurrentHeads: Word; wNumCurrentSectorsPerTrack: Word; ulCurrentSectorCapacity: DWORD; wMultSectorStuff: Word; ulTotalAddressableSectors: DWORD; wSingleWordDMA: Word; wMultiWordDMA: Word; bReserved: array 0. 127 of BYTE; end; PIdSector = ^TIdSector; TDriverStatus = packed record bDriverError: BYTE; bIDEStatus: BYTE; bReserved: array 0. 1 of BYTE; dwReserved: array 0.
1 of DWORD; end; TSendCmdOutParams = packed record // bBuffer??? CBufferSize: DWORD; DriverStatus: TDriverStatus; bBuffer: array 0. 0 of BYTE; end; var hDevice: Thandle; cbBytesReturned: DWORD; SCIP: TSendCmdInParams; aIdOutCmd: array 0. (SizeOf(TSendCmdOutParams) + IDENTIFYBUFFERSIZE - 1) - 1 of BYTE; IdOutCmd: TSendCmdOutParams absolute aIdOutCmd; procedure ChangeByteOrder(var Data; Size: Integer); var ptr: pchar; i: Integer; c: CHAR; begin ptr:= @Data; for i:= 0 to (Size shr 1) - 1 do begin c:= ptr^; ptr^:= (ptr + 1)^; (ptr + 1)^:= c; Inc(ptr, 2); end; end; begin Result:= '; // '.
PhysicalDrive0 means the first drive, use '. PhysicalDrive1 ' for the second one, etc. HDevice:= CreateFile( '. PhysicalDrive0', GENERICREAD or GENERICWRITE, FILESHAREREAD or FILESHAREWRITE, nil, OPENEXISTING, 0, 0); if hDevice = INVALIDHANDLEVALUE then Exit; try FillChar(SCIP, SizeOf(TSendCmdInParams) - 1, #0); FillChar(aIdOutCmd, SizeOf(aIdOutCmd), #0); cbBytesReturned:= 0; // Set up data structures for IDENTIFY command. I'm trying to read serial no of the hard disk as a unique id of the machine.
I tried the code as follows: Magenta Systems WMI and SMART Component from might help, however the SMART APIs were designed for PCs with only four IDE ATA drives and drives less than 128 gig, whereas SATA PCs may have six or more drives. Also they only work with physical drives and not SCSI connected or RAID drives.
There are Intel RST APIs that access the underlaying drives in PCs using Intel chipsets which Smartmontools supports, but it's complex C code and not easy to translate to Delphi. I'm trying to read serial no of the hard disk as a unique id of the machine. I tried the code as follows: Magenta Systems WMI and SMART Component from might help, however the SMART APIs were designed for PCs with only four IDE ATA drives and drives less than 128 gig, whereas SATA PCs may have six or more drives. Also they only work with physical drives and not SCSI connected or RAID drives.
There are Intel RST APIs that access the underlaying drives in PCs using Intel chipsets which Smartmontools supports, but it's complex C code and not easy to translate to Delphi.