GARANTIR DESCONTO

Fórum obter Nº Serial do HD #351257

02/01/2008

0

Seguinte, estou usando uma função para obter o serial do HD. Mas esbarrei em um problema, ao executar a função
no ambiente NT (Win2000 / 2003) a função não me retorna nada, ja no WinXP funciona normal.
Vou postar a função que estou utilizando caso alguem possa me ajudar ou postar outra função que funcione em qq ambiente. Utilizo o Delphi 7.

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;
{ função que pega o serial number FÍSICO do HD e retorna string }

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



OBS.: Testei essa outra função e esta funciona em qq ambiente mas o problema é que ela me retorna o label/volume do HD e não o Numero de Serie (fabricante).
- Caso alguem saiba como buscar o serial do processador ficarei grato tb...

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;



Carlos_tedex

Carlos_tedex

Responder

Posts

02/01/2008

Anonimus.info

da uma olhada ai... talvez lhe ajuda... no que voce esta querendo.


procedure TForm1.Button1Click(Sender: TObject);
var
SerialNum : pdword;
a, b : dword;
Buffer : array [0..255] of char;
begin
if GetVolumeInformation(´c:\´, Buffer, SizeOf(Buffer), SerialNum, a, b, nil, 0) then
Label1.Caption := IntToStr(SerialNum^);
end;


Responder

Gostei + 0

02/01/2008

Carlos_tedex

da uma olhada ai... talvez lhe ajuda... no que voce esta querendo.


Amigo, testei desta forma mas não me retornou nada.

mas valew, qq coisa posta ai novamente... abraços


Responder

Gostei + 0

02/01/2008

Otto

Colega,

veja se este link lhe ajuda:

:arrow: http://forum.devmedia.com.br/viewtopic.php?t=43652&highlight=serial


Responder

Gostei + 0

03/01/2008

Carlos_tedex

Colega, veja se este link lhe ajuda: :arrow: http://forum.devmedia.com.br/viewtopic.php?t=43652&highlight=serial


Amigo dei uma vrf nesse link mas tb não tive sucesso aqui no Win2000/2003.
A unica maneira que consegui fazer funcionar foi utilizando uma DLL de terceiro (DiskSerial.dll) mas o incoveniente e que toda vez que uso a DLL ela me mostra uma tela de propaganda e me joga pro site deles...
Caso vc encontre algo a mais posta aqui pra nois... valew


Responder

Gostei + 0

03/01/2008

Carlos_tedex

Caso queira testar:

[url]http://www.caishen168.com/DiskSerial/DiskSerial/DiskSerial.zip[/url]


Responder

Gostei + 0

04/01/2008

Carlos_tedex

Pessoal,

Finalmente consegui extrair o Numero de Serie do HD em qq versão do Windows utilizando um componente open source:
VDOUtils


- Não gosto de usar componentes mas foi o jeito... rsrsrs


Responder

Gostei + 0

18/11/2008

Devmedia

Pessoal, Finalmente consegui extrair o Numero de Serie do HD em qq versão do Windows utilizando um componente open source:
VDOUtils
- Não gosto de usar componentes mas foi o jeito... rsrsrs


Amigo, carlos_tedex!

Tem como voce me enviar o componente ou link?
Agradeço.


Responder

Gostei + 0

18/11/2008

Carlos_tedex

me passa um e-mail que eu lhe envio.


Responder

Gostei + 0

19/11/2008

Carlos_tedex

*Voce testou com HD´s sata?


- Funciona em HD´s satas tb... inclusive tb testei em diversos S.O. e até agora não tive problemas...
- Esse componente tb obtem o Mac Address da placa de rede.

OBS.: Já envieu pro seu e-mail qq duvida é só falar.


Responder

Gostei + 0

19/11/2008

Carlos_tedex

- Outra informação: Testei esse mesmo componente do delphi 7 no RAD STUDIO 2007 e funcionou normal.


Responder

Gostei + 0

19/11/2008

Helio Nascimento

Colega voce pode enviar para mim tambem.
helionas@hotmail.com

Obrigado.


Responder

Gostei + 0

19/11/2008

Bononi

Pode mandar para mim também por favor ?

wmbononi@yahoo.com.br


Responder

Gostei + 0

20/11/2008

Carlos_tedex

Já envieu pra vc´s caso tenha algum problema com o e-mail vou deixar disponivel esse link:

SerialHD_MacAddress.rar


Responder

Gostei + 0

20/11/2008

Carlos_tedex

Link correto :D

SerialHD_MacAddress.rar


Responder

Gostei + 0

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

Aceitar