Einzelnen Beitrag anzeigen

Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Festplatte Serialnummer ablesen

  Alt 25. Aug 2005, 14:29
diese etwas abgespeckte Version funktioniert nicht bei allen Festplatten, und auch nur unter NT und folgende.
Delphi-Quellcode:
function GetHarddiskID(HarddiskID: Byte=0): String;
type
   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;
   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;
  TDriverStatus = packed record
    bDriverError : Byte;
    bIDEStatus : Byte;
    bReserved : Array[0..1] of Byte;
    dwReserved : Array[0..1] of DWORD;
  end;
  TSendCmdOutParams = packed record
    cBufferSize : DWORD;
    DriverStatus : TDriverStatus;
    bBuffer : Array[0..0] of BYTE;
  end;
   TIdSector = packed record
    all: Array[0..254] of Char;
   end;
const
   DFP_RECEIVE_DRIVE_DATA = $0007c088;
  IDENTIFY_BUFFER_SIZE = 512;
  BufferSize = SizeOf(TSendCmdOutParams)+IDENTIFY_BUFFER_SIZE-1;
  IDE_ID_FUNCTION = $EC;
  CAP_IDE_ID_FUNCTION = 1;
var SCIP : TSendCmdInParams;
      Buffer : Array [0..BufferSize-1] of Byte;
      SCOP : TSendCmdOutParams absolute Buffer;
      dwBytesReturned : DWORD;
    LBool: LongBool;
    hdevice: THandle;
    IdSectorSize: Integer;
    idsector: TIdSector;
    LGiveback: String;
    LCount: Integer;
    LChar: Char;
begin
  FillChar(idSector, sizeof(idsector), #0);
   FillChar(SCIP,SizeOf(TSendCmdInParams)-1,#0);
   FillChar(Buffer,BufferSize,#0);
   dwBytesReturned := 0;
   // Set up data structures for IDENTIFY command.
   with SCIP do
   begin
      cBufferSize := IDENTIFY_BUFFER_SIZE;
      bDriveNumber := 0;
      with irDriveRegs do
      begin
         bFeaturesReg := 0;
         bSectorCountReg := 1;
         bSectorNumberReg := 1;
         bCylLowReg := 0;
         bCylHighReg := 0;
         bDriveHeadReg := $A0 or ((0 and 1) shl 4);
         bCommandReg := IDE_ID_FUNCTION;   // The command can either be IDE identify or ATAPI identify.
      end;
   end;
   hDevice := CreateFile( PChar('\\.\PhysicalDrive' + IntToStr(HarddiskID)), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );
   LBool := DeviceIoControl(hDevice, DFP_RECEIVE_DRIVE_DATA, @SCIP, SizeOf(TSendCmdInParams)-1, @SCOP, BufferSize, dwBytesReturned, nil );
   if LBool then
   begin
    IDSectorSize := sizeof(IDSector);
      if IdSectorSize > 0 then
       System.Move(SCOP.bBuffer,IdSector,IdSectorSize);
   end;
  CloseHandle(hDevice);
  LGiveback := '';
  for LCount := 0 to 19 do
  begin
    //if idSector.all[20 + LCount] <> ' ' then
      LGiveback := LGiveback + idSector.all[20 + LCount];
  end;
  for LCount := 20 downto 1 do
    if LCount mod 2 = 0 then
    begin
      LChar := LGiveback[LCount];
      LGiveback[LCount] := LGiveback[LCount-1];
      LGiveback[LCount-1] := LChar;
    end;
  result := Trim(LGiveback);
end;
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat