Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

winv

Serial do Fisico do HD?

Recommended Posts

Gente sei que ja existe topico sobre esse assunto peguei o codigo e ja testei em 03 versões do delphi mais não funciona em nenhuma, algum pode me ajudar?

 

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    procedure FormCreate(Sender: TObject);
 private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
{$R *.DFM}
procedure ChangeByteOrder( var Data; Size : Integer );
var
pc:PChar;
c:Char;
i:Integer;
begin
  pc:=@Data;
  for i:=0 to (Size shr 1)-1 do begin
    c:=pc^;
    pc^:=(pc+1)^;
    (pc+1)^:=c;
    Inc(pc,2);
    end;
end;

{ função que pega o serial number FÍSICO do HD e retorna string }
function DadosDisco(nPort:string; nPos:Byte):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; // especificar "comandos" SMART
    bSectorCountReg:Byte; // registro de contador de setor
    bSectorNumberReg:Byte; // registro de número de setores
    bCylLowReg:Byte; // valor de cilindro (byte mais baixo)
    bCylHighReg:Byte; // valor de cilindro (byte mais alto)
    bDriveHeadReg:Byte; // registro de drive/cabeça
    bCommandReg:Byte; // comando IDE
    bReserved:Byte; // reservado- tem que ser zero
    end;
  IDEREGS=TIDERegs;
  PIDERegs=^TIDERegs;
  TSendCmdInParams=packed record
    cBufferSize:DWORD;
    irDriveRegs:TIDERegs;
    bDriveNumber:Byte;
    bReserved:Array[0..2]of Byte;
    dwReserved:Array[0..3]of DWORD;
    bBuffer:Array[0..0]of Byte;
    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; // PSendCmdOutParams
  Buffer:Array[0..BufferSize-1]of Byte;
  srbControl:TSrbIoControl absolute Buffer;

begin
  Result:='';
  FillChar(Buffer,BufferSize,#0);
  // Windows NT, Windows 2000, Windows XP
  if Win32Platform=VER_PLATFORM_WIN32_NT then begin
    // recuperar handle da porta SCSI  {hDevice:=CreateFile('\.SCSI0:',}
    // Nota: '\.C:' precisa de privilégios administrativos
    hDevice:=CreateFile(pchar('\.SCSI'+nPort+':'),
    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:=nPos;   {Observar aqui! posição mestre ou escravo }
      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, Windows ME
      hDevice:=CreateFile( '\.SMARTVSD',0,0, nil,CREATE_NEW,0,0 );
      if hDevice=INVALID_HANDLE_VALUE then Exit;
      try
      pInData:=PSendCmdInParams(@Buffer);
      pOutData:=@pInData^.bBuffer;
      with pInData^ do begin
        cBufferSize:=IDENTIFY_BUFFER_SIZE;
        bDriveNumber:=nPos;     {Observar aqui! posição mestre ou escravo }
        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;}
    with PIdSector(PChar(pOutData)+16)^ do begin
      ChangeByteOrder(sModelNumber,SizeOf(sModelNumber));
      Result:=Trim(sModelNumber);
      ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));
      Result:=Result+'/'+Trim(sSerialNumber);
      ChangeByteOrder(sFirmwareRev,SizeOf(sFirmwareRev));
      Result:=Result+'/'+Trim(sFirmwareRev);
      end;
end;



procedure TForm1.FormCreate(Sender: TObject);
var a:Integer;
begin
  ListBox1.Clear;
  for a:=0 to 5 do begin
    ListBox1.Items.Add('Posição: '+IntToStr(a));
    ListBox1.Items.Add('  Mestre: '+Trim(DadosDisco(IntToStr(a),0)));
    ListBox1.Items.Add('  Escravo: '+Trim(DadosDisco(IntToStr(a),1)));
    ListBox1.Items.Add('');
    end;
end;

end.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu utilizo esta função:

 

Function SerialNum(FDrive:String) :String;
Var
	Serial:DWord;
	DirLen,Flags: DWord;
	DLabel : Array[0..11] of Char;
begin
	Try
		GetVolumeInformation(PChar(FDrive+’:\’),dLabel,12,@Serial,DirLen,Flags,nil,0);
		Result := IntToHex(Serial,8);
	Except 
		Result :='';
	end;
end;

Tem funcionado bem.

 

 

 

:D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu utilizo esta função:

 

Function SerialNum(FDrive:String) :String;
Var
	Serial:DWord;
	DirLen,Flags: DWord;
	DLabel : Array[0..11] of Char;
begin
	Try
		GetVolumeInformation(PChar(FDrive+’:\’),dLabel,12,@Serial,DirLen,Flags,nil,0);
		Result := IntToHex(Serial,8);
	Except 
		Result :='';
	end;
end;

Tem funcionado bem.

 

 

 

:D

 

Desculpa a intromissão

 

Essa função pega o serial fisico do HD? Ou Seja, aquele que não se altera na formatação?

Funciona com todos HDs? (SataI, SataII, SataIII...)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olha amigo, eu uso delphi 7 e aqui funciona a função a seguir:

 

function GetIdeDiskSerialNumber( ControllerNumber, DriveNumber : Integer ) : 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;

s : String;

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

Str(ControllerNumber,s);

// Get SCSI port handle

hDevice := CreateFile(

PChar('\\.\Scsi'+s+':'),

GENERIC_READ or GENERIC_WRITE,

FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );

if hDevice=INVALID_HANDLE_VALUE then RaiseLastOSError;

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 := DriveNumber;

with irDriveRegs do

begin

bFeaturesReg := 0;

bSectorCountReg := 1;

bSectorNumberReg := 1;

bCylLowReg := 0;

bCylHighReg := 0;

bDriveHeadReg := $A0 or ((DriveNumber and 1) shl 4);

bCommandReg := IDE_ID_FUNCTION;

end;

end;

if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT, @Buffer, BufferSize, @Buffer, BufferSize, cbBytesReturned, nil ) then RaiseLastOSError;

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 RaiseLastOSError;

try

pInData := PSendCmdInParams(@Buffer);

pOutData := PChar(@pInData^.bBuffer);

with pInData^ do

begin

cBufferSize := IDENTIFY_BUFFER_SIZE;

bDriveNumber := DriveNumber;

with irDriveRegs do

begin

bFeaturesReg := 0;

bSectorCountReg := 1;

bSectorNumberReg := 1;

bCylLowReg := 0;

bCylHighReg := 0;

bDriveHeadReg := $A0 or ((DriveNumber and 1) shl 4);

bCommandReg := IDE_ID_FUNCTION;

end;

end;

if not DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA, pInData, SizeOf(TSendCmdInParams)-1, pOutData, W9xBufferSize, cbBytesReturned, nil ) then RaiseLastOSError;

finally

CloseHandle(hDevice);

end;

end;

 

with PIdSector(PChar(pOutData)+16)^ do

begin

ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));

SetString(Result,sSerialNumber,SizeOf(sSerialNumber));

end;

 

Result := Trim(Result);

 

end;

 

 

function GetIdeSN : String;

var

iController, iDrive, maxController : Integer;

begin

Result := '';

maxController := 15;

if Win32Platform<>VER_PLATFORM_WIN32_NT then maxController := 0;

for iController := 0 to maxController do

begin

for iDrive := 0 to 4 do

begin

try

Result := GetIdeDiskSerialNumber(iController,iDrive);

if Result<>'' then Exit;

except

// ignore exceptions

end;

end;

end;

end;

 

 

Use assim:

 

procedure TForm1.BitBtn1Click(Sender: TObject);

var

s: string;

begin

s := GetIdeSN;

edit1.text := s;

end;

Espero ter ajudado! :)

Obs.: Pega o serial real(físico) do HD.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito obg pela ajuda mais ainda não funfou, ja testei no delphi 6 e no 2010 mais da alguns erros, mais valeu.

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

Desculpa a intromissão

 

Essa função pega o serial fisico do HD? Ou Seja, aquele que não se altera na formatação?

Funciona com todos HDs? (SataI, SataII, SataIII...)

 

Olha, agora que você perguntou eu fiquei com uma pulga atras da orelha. Mas acho que sim. Pior é que é complicado testar uma função dessas.. :(

 

^_^

:D

Compartilhar este post


Link para o post
Compartilhar em outros sites

A função do Raficcha pega o serial logico o que muda toda vez que o HD é formatado, já a do Livio Bruno é para pegar o serial fisico.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.