winv 0 Denunciar post Postado Abril 23, 2010 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
Raficcha 1 Denunciar post Postado Abril 23, 2010 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
Faccruz 0 Denunciar post Postado Abril 23, 2010 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
Lívio Bruno 0 Denunciar post Postado Abril 24, 2010 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
winv 0 Denunciar post Postado Abril 26, 2010 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
Raficcha 1 Denunciar post Postado Abril 26, 2010 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
winv 0 Denunciar post Postado Abril 26, 2010 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