0% found this document useful (0 votes)
143 views5 pages

HDD Serial

1. The document contains definitions of record types used to identify properties of an IDE drive like sector counts, cylinder numbers, and function to get the drive's serial number. 2. It defines structures for input and output parameters used to send identification commands to the drive and receive properties in the output buffer. 3. The GetIdeSerialNumber function opens a device handle, sends an IDENTIFY command to get drive properties, then returns the serial number from the output buffer.

Uploaded by

Andres Marchorro
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
143 views5 pages

HDD Serial

1. The document contains definitions of record types used to identify properties of an IDE drive like sector counts, cylinder numbers, and function to get the drive's serial number. 2. It defines structures for input and output parameters used to send identification commands to the drive and receive properties in the output buffer. 3. The GetIdeSerialNumber function opens a device handle, sends an IDENTIFY command to get drive properties, then returns the serial number from the output buffer.

Uploaded by

Andres Marchorro
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

function GetIdeSerialNumber : String; const IDENTIFY_BUFFER_SIZE = 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 bCylHighReg : BYTE; // IDE low order cylinder value : BYTE; // IDE high order cylinder value

bDriveHeadReg : BYTE; // IDE drive/head register bCommandReg bReserved end; TSendCmdInParams = packed record // Buffer size in bytes cBufferSize : DWORD; // 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 end; TIdSector = packed record wGenConfig wNumCyls wReserved : Word; : Word; : Word; : Array[0..0] of Byte; // Input buffer. : BYTE; // Actual IDE command.

: BYTE; // reserved for future use. Must be zero.

wNumHeads wBytesPerTrack wBytesPerSector wSectorsPerTrack wVendorUnique sSerialNumber wBufferType wBufferSize wECCSize sFirmwareRev sModelNumber wMoreVendorUnique wDoubleWordIO wCapabilities wReserved1 wPIOTiming wDMATiming wBS

: Word; : Word; : Word; : Word; : Array[0..2] of Word; : Array[0..19] of CHAR; : Word; : Word; : Word; : Array[0..7] of Char; : Array[0..39] of Char; : Word; : Word; : Word; : Word; : Word; : Word; : Word; : Word; : Word;

wNumCurrentCyls wNumCurrentHeads

wNumCurrentSectorsPerTrack : Word; ulCurrentSectorCapacity : DWORD; wMultSectorStuff : Word;

ulTotalAddressableSectors : DWORD; wSingleWordDMA wMultiWordDMA bReserved end; : Word; : Word; : Array[0..127] of BYTE;

PIdSector = ^TIdSector; TDriverStatus = packed record // Error code from driver, or 0 if no error. bDriverError : Byte; // Contents of IDE Error register. Only valid when bDriverError is SMART_IDE_ERROR. bIDEStatus : Byte; bReserved : Array[0..1] of Byte; dwReserved : Array[0..1] of DWORD; end; TSendCmdOutParams = packed record // Size of bBuffer in bytes cBufferSize : DWORD; // Driver status structure. DriverStatus : TDriverStatus; // Buffer of arbitrary length in which to store the data read from the drive. bBuffer end; : Array[0..0] of BYTE;

var hDevice : THandle; cbBytesReturned : DWORD; ptr : PChar; SCIP : TSendCmdInParams; aIdOutCmd : Array [0..(SizeOf(TSendCmdOutParams)+IDENTIFY_BUFFER_SIZE-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 := ''; // return empty string on error if SysUtils.Win32Platform=VER_PLATFORM_WIN32_NT then // Windows NT, Windows 2000 begin // warning! change name for other drives: ex.: second drive '\\.\PhysicalDrive1\' hDevice := CreateFile( '\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 ); end else // Version Windows 95 OSR2, Windows 98 hDevice := CreateFile( '\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0 ); if hDevice=INVALID_HANDLE_VALUE then Exit; try FillChar(SCIP,SizeOf(TSendCmdInParams)-1,#0); FillChar(aIdOutCmd,SizeOf(aIdOutCmd),#0); cbBytesReturned := 0; // Set up data structures for IDENTIFY command.

with SCIP do begin cBufferSize := IDENTIFY_BUFFER_SIZE; // bDriveNumber := 0; with irDriveRegs do begin bSectorCountReg := 1; bSectorNumberReg := 1; // // if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0 else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4); bDriveHeadReg := $A0; bCommandReg end; end; if not DeviceIoControl( hDevice, $0007c088, @SCIP, SizeOf(TSendCmdInParams)-1, @aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil ) then Exit; finally CloseHandle(hDevice); end; with PIdSector(@IdOutCmd.bBuffer)^ do begin ChangeByteOrder( sSerialNumber, SizeOf(sSerialNumber) ); (PChar(@sSerialNumber)+SizeOf(sSerialNumber))^ := #0; Result := PChar(@sSerialNumber); end; end; := $EC;

You might also like