Fórum Serial Firmware HD #310945

29/01/2006

0

Alguem conseguiu uma rotina para captar o serial do firmaware do hd,nao o serial Label?


Kroki

Kroki

Responder

Posts

30/01/2006

Radatec

Caro colega

Esta questão já foi publicada. Mas la vai de novo.

http://www.latiumsoftware.com/br/pascal/0044.php

Essa rotina pascoal retorna o número de serie fisico do HD.


Serial de um HD IDE- Usando S.M.A.R.T. IOCTL API

Por Alex Konshin
http://home.earthlink.net/~akonshin/

Tradução: Adilson Vahldick


Muitos FAQs recomendam o uso do GetVolumeInformation para recuperar
o serial do HD, mas esta função fornece o serial do volume e não o
serial do HD. O serial do volume é atribuído e alterando durante a
formatação de uma partição. Algumas empresas utilizam ferramentas
de clonagem para instalar softwares em seus computadores novos,
copiando de um HD para todos os outros. Consequentemente, todos
os números de séries dos volumes destes HDs são os mesmos.

Você pode recuperar o número de série real de um HD IDE, o nome
do modelo, a revisão do firmware e outras informações utilizando
o S.M.A.R.T. IOCTL API.

// Copyright (c) 2000 Alex Konshin

program IdeSN;

// OBJETIVO: Aplicativo console simples que extrai
// o serial do primeiro disco IDE.

{$APPTYPE CONSOLE}

uses
Windows,
SysUtils; // para Win32Platform e SysErrorMessage

// -------------------------------------------------------------
function GetIdeDiskSerialNumber : 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;

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
// Windows NT, Windows 2000, Windows XP
begin
// recuperar handle da porta SCSI
hDevice := CreateFile(´\\.\Scsi0:´,
// Nota: ´\\.\C:´ precisa de privilégios administrativos
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, 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 := 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;


// =============================================================
var s : String;
rc : DWORD;
begin

s := GetIdeDiskSerialNumber;
if s=´´ then
begin
rc := GetLastError;
if rc=0 then WriteLn(´Drive IDE não suporta SMART´)
else WriteLn(SysErrorMessage(rc));
end
else WriteLn(´Número serial do disco: ´´´, s,´´´´);
ReadLn;
end.

Notas:

- Este código funciona somente em drives IDE que suportam o S.M.A.R.T.
(Self Monitoring, Analysis and Reporting Technology). Para drives
SCSI-2 veja: http://www.delphi3000.com/articles/article_1174.asp

- Hardware IDE deve suportar S.M.A.R.T. e o S.M.A.R.T. deve estar
habilitado

- Windows 95 não suporta este recurso antes da versão 95 OSR2.
Este código funciona com Windows 95 OSR2/98/98SE/Me/NT4/2000/XP.

- Windows 9x: SMARTVSD.VXD precisa estar instalado: basta copiá-lo
da pasta de sistema (normalmente C:\WINDOWS\SYSTEM) para a pasta
System\IoSubsys e reiniciar.

- Windows NT/2000/XP: Este código não requer privilégios
administrativos e roda sobre qualquer conta.

- Para mais informações sobre a SMART IOCTL API veja o exemplo
SmartApp no MSDN Knowledge Base:
http://support.microsoft.com/default.aspx?scid=kb¬3Ben-us¬3B208048

- Se você precisar de informações sobre uma unidade escrava ou uma
unidade que esteja conectada numa controladora IDE secundária
então veja o exemplo em minha homepage:
http://home.earhlink.net/~akonshin/

- Para maiores informações sobre S.M.A.R.T. ou outros padrões
relacionados com dispositivos de armazenamento ATA veja o
Technical Committee T13 homepage: http://www.t13.org/
Você pode encontrar mais informações relacionadas com o
tema deste artigo nas páginas 87-105 do documento
http://www.t13.org/project/d1321r3.pdf.


Responder

Gostei + 0

31/01/2006

Kroki

Vou reanalizr esse código porque em um outro site ele nao funcionou no ME aqui,mesmo como SMARTVSD.VXD no lugar certo.
Estvava procurando uma rotina onde nao é nescessario habilitar o Smart,pois o desempenho cai muito,queria igual ao software da Maxtor que faz a leitura direta sem modificaçao do sistema,mas valeu.


Responder

Gostei + 0

31/01/2006

Edilcimar

e o serial de um sata ou scsi, retorna?


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar