Delphi - объектно-ориентированный язык программирования, разработанный компанией Borland в 1995 году. Он основан на языке программирования Pascal, но имеет более расширенные возможности и добавлены новые функции.
Delphi является интегрированной средой разработки (IDE), которая позволяет разрабатывать программное обеспечение для различных платформ, включая Windows, macOS, Android и iOS. Delphi достигает многоплатформенности с помощью...
{ **** UBPFD *********** by delphibase.endimus.com **** >> Поличение серийного номера IDE диска. Функция получает серийный номер первого физического диска IDE (не серийный номер тома!). Используется S.M.A.R.T. API, а под Windows NT/2K/XP запрос производится не напрямую к диску, а через miniport драйвер контроллера, что позволяет читать серийный номер не имея прав администратора. Функция может не работать, если первый контролер в системе не ATA или если первое устройство не является винчестером, который поддерживает SMART (современные винчестеры поддерживают). Если Вы хотите получить другие параметры диска/других дисков, то смотрите пример IdeInfo2 с моего сайта. На Windows 9x требует наличия драйвера smartvsd.vxd (должен быть в стандартной поставке), просто скопируйте его в windowssystemiosubsys и перезагрузите компьютер. Зависимости: Windows, SysUtils Автор: Alex Konshin, akonshin@earthlink.net, Boston, USA Copyright: http://home.earthlink.net/~akonshin/index.htm Дата: 30 декабря 2002 г. ***************************************************** } functionGetIdeDiskSerialNumber: string
; type
TSrbIoControl = packed
record
HeaderLength: ULONG; Signature: array
[0..7] of
Char; Timeout: ULONG; ControlCode: ULONG; ReturnCode: ULONG; Length: ULONG; end
; SRB_IO_CONTROL = TSrbIoControl; PSrbIoControl = ^TSrbIoControl; 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
; IDEREGS = TIDERegs; PIDERegs = ^TIDERegs; TSendCmdInParams = packed
record
cBufferSize: DWORD; // Buffer size in bytes irDriveRegs: TIDERegs; // Structure with drive register values. bDriveNumber: Byte; // Physical drive number to send command to (0,1,2,3). bReserved: array
[0..2] of
Byte; // Reserved for future expansion. dwReserved: array
[0..3] of
DWORD; // For future use. bBuffer: array
[0..0] of
Byte; // Input buffer. end
; SENDCMDINPARAMS = TSendCmdInParams; PSendCmdInParams = ^TSendCmdInParams; 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: ULONG; wMultSectorStuff: Word; ulTotalAddressableSectors: ULONG; wSingleWordDMA: Word; wMultiWordDMA: Word; bReserved: array
[0..127] of
Byte; end
; PIdSector = ^TIdSector; const
IDE_ID_FUNCTION = $EC; IDENTIFY_BUFFER_SIZE = 512; DFP_RECEIVE_DRIVE_DATA = $0007C088; IOCTL_SCSI_MINIPORT = $0004D008; IOCTL_SCSI_MINIPORT_IDENTIFY = $001B0501; DataSize = sizeof(TSendCmdInParams) - 1 + IDENTIFY_BUFFER_SIZE; BufferSize = SizeOf(SRB_IO_CONTROL) + DataSize; W9xBufferSize = IDENTIFY_BUFFER_SIZE + 16; var
hDevice: THandle; cbBytesReturned: DWORD; pInData: PSendCmdInParams; pOutData: Pointer; // PSendCmdInParams; Buffer: array
[0..BufferSize - 1] of
Byte; srbControl: TSrbIoControl absolute
Buffer; 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 := ''; FillChar(Buffer, BufferSize, #0); if
Win32Platform = VER_PLATFORM_WIN32_NT then
begin
// Windows NT, Windows 2000 // Get SCSI port handle hDevice := CreateFile('\.Scsi0:', GENERIC_READ or
GENERIC_WRITE, FILE_SHARE_READ or
FILE_SHARE_WRITE, nil
, OPEN_EXISTING, 0, 0); if
hDevice = INVALID_HANDLE_VALUE then
Exit; try
srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL); System.Move('SCSIDISK', srbControl.Signature, 8); srbControl.Timeout := 2; srbControl.Length := DataSize; srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY; pInData := PSendCmdInParams(PChar(@Buffer) + SizeOf(SRB_IO_CONTROL)); pOutData := pInData; with
pInData^ do
begin
cBufferSize := IDENTIFY_BUFFER_SIZE; bDriveNumber := 0; with
irDriveRegs do
begin
bFeaturesReg := 0; bSectorCountReg := 1; bSectorNumberReg := 1; bCylLowReg := 0; bCylHighReg := 0; bDriveHeadReg := $A0; bCommandReg := IDE_ID_FUNCTION; end
; end
; if
not
DeviceIoControl(hDevice, IOCTL_SCSI_MINIPORT, @Buffer, BufferSize, @Buffer, BufferSize, cbBytesReturned, nil
) then
Exit; finally
CloseHandle(hDevice); end
; end
else
begin
// Windows 95 OSR2, Windows 98 hDevice := CreateFile('\.SMARTVSD', 0, 0, nil
, CREATE_NEW, 0, 0); if
hDevice = INVALID_HANDLE_VALUE then
Exit; try
pInData := PSendCmdInParams(@Buffer); pOutData := PChar(@pInData^.bBuffer); with
pInData^ do
begin
cBufferSize := IDENTIFY_BUFFER_SIZE; bDriveNumber := 0; with
irDriveRegs do
begin
bFeaturesReg := 0; bSectorCountReg := 1; bSectorNumberReg := 1; bCylLowReg := 0; bCylHighReg := 0; bDriveHeadReg := $A0; bCommandReg := IDE_ID_FUNCTION; end
; end
; if
not
DeviceIoControl(hDevice, DFP_RECEIVE_DRIVE_DATA, pInData, SizeOf(TSendCmdInParams) - 1, pOutData, W9xBufferSize, cbBytesReturned, nil
) then
Exit; finally
CloseHandle(hDevice); end
; end
; with
PIdSector(PChar(pOutData) + 16)^ do
begin
ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber)); SetString(Result, sSerialNumber, SizeOf(sSerialNumber)); end
; end
;
Пример использования:
vars: string
; rc: DWORD; begin
s := GetIdeDiskSerialNumber; if
s = '' then
begin
rc := GetLastError; if
rc = 0 then
WriteLn('IDE drive is not support SMART feature') else
WriteLn(SysErrorMessage(rc)); end
else
WriteLn('Disk serial number: ''', s, ''''); end
.