![]() |
Re: Problem beim auslesen der Festplatten Seriennummer
Wie wärs denn damit ?
Delphi-Quellcode:
_STORAGE_PROPERTY_QUERY=record
PropertyId:STORAGE_PROPERTY_ID; QueryType:STORAGE_QUERY_TYPE; AdditionalParameters:Array[0..0] of UCHAR; end; STORAGE_PROPERTY_QUERY=_STORAGE_PROPERTY_QUERY; PSTORAGE_PROPERTY_QUERY=^STORAGE_PROPERTY_QUERY; |
Re: Problem beim auslesen der Festplatten Seriennummer
hmmm
Undefinierter Bezeichner 'STORAGE_PROPERTY_ID' Undefinierter Bezeichner 'STORAGE_QUERY_TYPE' was hast du da noch eingebunden ? Ist das in der winioctl.h drin ? Die hatte er bei c++ eingebunden, aber ich finde das equivalent in Delphi nicht :/ Gruß Oliver |
Re: Problem beim auslesen der Festplatten Seriennummer
ok.. hier der rest...
Delphi-Quellcode:
uses
Windows; const Method_Buffered = 0; File_Any_Access = 0; File_Device_Mass_Storage = $0000002D; IOCTL_Storage_Base = File_Device_Mass_Storage; MAX_IDE_DRIVES = 16; type PSTORAGE_BUS_TYPE = ^STORAGE_BUS_TYPE; STORAGE_BUS_TYPE = (BusTypeUnknown = $00, BusTypeScsi, BusTypeAtapi, BusTypeAta, BusType1394, BusTypeSsa, BusTypeFibre, BusTypeUsb, BusTypeRAID, BusTypeMaxReserved = $7F); PSTORAGE_QUERY_TYPE = ^STORAGE_QUERY_TYPE; STORAGE_QUERY_TYPE = (PropertyStandardQuery = 0, PropertyExistsQuery, PropertyMaskQuery, PropertyQueryMaxDefined); PSTORAGE_PROPERTY_ID = ^STORAGE_PROPERTY_ID; STORAGE_PROPERTY_ID = (StorageDeviceProperty = 0, StorageAdapterProperty); PSTORAGE_PROPERTY_QUERY = ^STORAGE_PROPERTY_QUERY; STORAGE_PROPERTY_QUERY = record PropertyId: STORAGE_PROPERTY_ID; QueryType: STORAGE_QUERY_TYPE; AdditionalParameters: array[0..0] of UCHAR; end; PSTORAGE_DEVICE_DESCRIPTOR = ^STORAGE_DEVICE_DESCRIPTOR; STORAGE_DEVICE_DESCRIPTOR = record Version: ULONG; Size: ULONG; DeviceType: UCHAR; DeviceTypeModifier: UCHAR; RemovableMedia: Boolean; CommandQueueing: Boolean; VendorIdOffset: ULONG; ProductIdOffset: ULONG; ProductRevisionOffset: ULONG; SerialNumberOffset: ULONG; BusType: STORAGE_BUS_TYPE; RawPropertiesLength: ULONG; RawDeviceProperties: array[0..0] of UCHAR; end; |
Re: Problem beim auslesen der Festplatten Seriennummer
hmmm *kopfqualm* :wiejetzt:
So ganz verstehe ich nicht was der da treibt :( Ich habe mal die Funktion mit deinen Änderungen versucht in Delphi zu übertragen. Im Moment erstmal bis zum Aufruf von DeviceIoControl Aber leider liefert der immer false. Steigt vielleicht jemand mehr durch den c++ code von oben durch und sieht was ich falsch mache? Gruß Oliver
Delphi-Quellcode:
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; PSTORAGE_BUS_TYPE = ^STORAGE_BUS_TYPE; STORAGE_BUS_TYPE = (BusTypeUnknown = $00, BusTypeScsi, BusTypeAtapi, BusTypeAta, BusType1394, BusTypeSsa, BusTypeFibre, BusTypeUsb, BusTypeRAID, BusTypeMaxReserved = $7F); PSTORAGE_QUERY_TYPE = ^STORAGE_QUERY_TYPE; STORAGE_QUERY_TYPE = (PropertyStandardQuery = 0, PropertyExistsQuery, PropertyMaskQuery, PropertyQueryMaxDefined); PSTORAGE_PROPERTY_ID = ^STORAGE_PROPERTY_ID; STORAGE_PROPERTY_ID = (StorageDeviceProperty = 0, StorageAdapterProperty); PSTORAGE_PROPERTY_QUERY = ^STORAGE_PROPERTY_QUERY; STORAGE_PROPERTY_QUERY = record PropertyId: STORAGE_PROPERTY_ID; QueryType: STORAGE_QUERY_TYPE; AdditionalParameters: array[0..0] of UCHAR; end; PSTORAGE_DEVICE_DESCRIPTOR = ^STORAGE_DEVICE_DESCRIPTOR; STORAGE_DEVICE_DESCRIPTOR = record Version: ULONG; Size: ULONG; DeviceType: UCHAR; DeviceTypeModifier: UCHAR; RemovableMedia: Boolean; CommandQueueing: Boolean; VendorIdOffset: ULONG; ProductIdOffset: ULONG; ProductRevisionOffset: ULONG; SerialNumberOffset: ULONG; BusType: STORAGE_BUS_TYPE; RawPropertiesLength: ULONG; RawDeviceProperties: array[0..0] of UCHAR; end; 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. Must be 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; const Method_Buffered = 0; File_Any_Access = 0; File_Device_Mass_Storage = $0000002D; IOCTL_Storage_Base = File_Device_Mass_Storage; MAX_IDE_DRIVES = 16; 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; query : STORAGE_PROPERTY_QUERY; IOCTL_STORAGE_QUERY_PROPERTY : cardinal; begin IOCTL_STORAGE_QUERY_PROPERTY := CTL_CODE(IOCTL_STORAGE_BASE, $0500, METHOD_BUFFERED, FILE_ANY_ACCESS); Result := ''; FillChar(Buffer,BufferSize,#0); if Win32Platform=VER_PLATFORM_WIN32_NT then begin // Windows NT, Windows 2000 hDevice := CreateFile( '\\.\PhysicalDrive0', 0, //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 query.PropertyId := StorageDeviceProperty; query.QueryType := PropertyStandardQuery; if not DeviceIoControl( hDevice, IOCTL_STORAGE_QUERY_PROPERTY, @query, sizeof (query), @Buffer, BufferSize, cbBytesReturned, nil ) then Exit; finally CloseHandle(hDevice); end; end; end; |
Re: Problem beim auslesen der Festplatten Seriennummer
Hallo,
gibt es denn keinen C++ Profi hier der sich des funktionierenden C++ codes mal annehmen könnte und ihn nach Delphi zu portieren? :love: Ich komme damit nicht wirklich weiter :wiejetzt: Gruß Oliver |
Re: Problem beim auslesen der Festplatten Seriennummer
Hast du hier eine Lösung gefunden ? Würde das auch sehr gerne nutzen...
|
Re: Problem beim auslesen der Festplatten Seriennummer
Dazu sollte wohl nur mal erwähnt werden, daß man sich an die windows-/systemspezifischen Typen, Ausrichtungen, und Größen halten sollte, wenn man schon versucht derartiges zu machen.
hier nun eine korrekte Typendefinition (so wie sie von windows verwendet wird):
Delphi-Quellcode:
Und hier noch eine zwar nicht ganz korrekte, aber dennoch Funtionierende:
STORAGE_QUERY_TYPE = cardinal{PropertyStandardQuery = 0, PropertyExistsQuery = 1, PropertyMaskQuery = 2,
PropertyQueryMaxDefined = 3}; STORAGE_PROPERTY_ID = cardinal{StorageDeviceProperty = 0, StorageAdapterProperty = 1}; STORAGE_PROPERTY_QUERY = packed record PropertyId: STORAGE_PROPERTY_ID; QueryType: STORAGE_QUERY_TYPE; AdditionalParameters: array[0..3] of UCHAR; end; In C++ sind STORAGE_QUERY_TYPE und STORAGE_PROPERTY_ID 4 Byte groß und nicht 1 Byte (so wie in Delphi).
Delphi-Quellcode:
STORAGE_QUERY_TYPE = (PropertyStandardQuery, PropertyExistsQuery, PropertyMaskQuery,
PropertyQueryMaxDefined); STORAGE_PROPERTY_ID = (StorageDeviceProperty, StorageAdapterProperty); STORAGE_PROPERTY_QUERY = packed record PropertyId: STORAGE_PROPERTY_ID; _fill1: array[0..2] of byte; QueryType: STORAGE_QUERY_TYPE; _fill2: array[0..2] of byte; AdditionalParameters: array[0..3] of UCHAR; end;
Delphi-Quellcode:
function GetIdeDiskSerialNumber: String;
function CTL_CODE(DeviceType, Function_, Method, Access: cardinal): cardinal; begin result := (DeviceType shl 16) or (Access shl 14) or (Function_ shl 2) or Method; end; 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; PSTORAGE_BUS_TYPE = ^STORAGE_BUS_TYPE; STORAGE_BUS_TYPE = (BusTypeUnknown = $00, BusTypeScsi, BusTypeAtapi, BusTypeAta, BusType1394, BusTypeSsa, BusTypeFibre, BusTypeUsb, BusTypeRAID, BusTypeMaxReserved = $7F); PSTORAGE_QUERY_TYPE = ^STORAGE_QUERY_TYPE; STORAGE_QUERY_TYPE = cardinal{PropertyStandardQuery = 0, PropertyExistsQuery = 1, PropertyMaskQuery = 2, PropertyQueryMaxDefined = 3}; PSTORAGE_PROPERTY_ID = ^STORAGE_PROPERTY_ID; STORAGE_PROPERTY_ID = cardinal{StorageDeviceProperty = 0, StorageAdapterProperty = 1}; PSTORAGE_PROPERTY_QUERY = ^STORAGE_PROPERTY_QUERY; STORAGE_PROPERTY_QUERY = packed record PropertyId: STORAGE_PROPERTY_ID; QueryType: STORAGE_QUERY_TYPE; AdditionalParameters: array[0..3] of UCHAR; end; PSTORAGE_DEVICE_DESCRIPTOR = ^STORAGE_DEVICE_DESCRIPTOR; STORAGE_DEVICE_DESCRIPTOR = record Version: ULONG; Size: ULONG; DeviceType: UCHAR; DeviceTypeModifier: UCHAR; RemovableMedia: Boolean; CommandQueueing: Boolean; VendorIdOffset: ULONG; ProductIdOffset: ULONG; ProductRevisionOffset: ULONG; SerialNumberOffset: ULONG; BusType: STORAGE_BUS_TYPE; RawPropertiesLength: ULONG; RawDeviceProperties: array[0..0] of UCHAR; end; 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. Must be 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; const Method_Buffered = 0; File_Any_Access = 0; File_Device_Mass_Storage = $0000002D; IOCTL_Storage_Base = File_Device_Mass_Storage; MAX_IDE_DRIVES = 16; 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; query : STORAGE_PROPERTY_QUERY; IOCTL_STORAGE_QUERY_PROPERTY : cardinal; begin IOCTL_STORAGE_QUERY_PROPERTY := CTL_CODE(IOCTL_STORAGE_BASE, $0500, METHOD_BUFFERED, FILE_ANY_ACCESS); Result := ''; FillChar(Buffer,BufferSize,#0); if Win32Platform=VER_PLATFORM_WIN32_NT then begin // Windows NT, Windows 2000 hDevice := CreateFile( '\\.\PhysicalDrive0', 0, //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 query.PropertyId := 0{StorageDeviceProperty}; query.QueryType := 0{PropertyStandardQuery}; if not DeviceIoControl( hDevice, IOCTL_STORAGE_QUERY_PROPERTY, @query, sizeof (query), @Buffer, BufferSize, cbBytesReturned, nil ) then begin Form1.Label1.Caption := SysErrorMessage(GetLastError); Exit; end; finally CloseHandle(hDevice); end; end; end; ach ja, für'n Anfang hätte man och ma versuchen können, sich die Fehlermeldung zu besorgen!
Delphi-Quellcode:
und bei der gegebenen Fehlermeldung ist wohl das Erste und Einfachste eine Vergößerung/Anpassung der Größer der Ein-/Ausgabepuffer. :zwinker:
SysErrorMessage(GetLastError);
|
Re: Problem beim auslesen der Festplatten Seriennummer
Liste der Anhänge anzeigen (Anzahl: 1)
Hi dbdeath74,
hab dir die Datei hddinfo.pas angehangen. Die Original-Version ist nicht von mir, habe aber diese so angepasst, dass sie nun auch unter NoAdmin-Rechten läuft (getestet mit Gast-Rechten) und ein paar Fehler behoben.
Delphi-Quellcode:
unit hddinfo;
interface uses Windows, SysUtils, Classes; const IOCTL_STORAGE_QUERY_PROPERTY = $2D1400; type THDDInfo = class (TObject) private FDriveNumber: Byte; FFileHandle: Cardinal; FInfoAvailable: Boolean; FProductRevision: string; FProductId: string; FSerialNumber: string; FVendorId: string; procedure ReadInfo; procedure SetDriveNumber(const Value: Byte); public constructor Create; property DriveNumber: Byte read FDriveNumber write SetDriveNumber; property VendorId: string read FVendorId; property ProductId: string read FProductId; property ProductRevision: string read FProductRevision; property SerialNumber: string read FSerialNumber; function SerialNumberInt: Cardinal; function SerialNumberText: string; function IsInfoAvailable: Boolean; end; implementation type STORAGE_PROPERTY_QUERY = packed record PropertyId: DWORD; QueryType: DWORD; AdditionalParameters: array[0..3] of Byte; end; STORAGE_DEVICE_DESCRIPTOR = packed record Version: ULONG; Size: ULONG; DeviceType: Byte; DeviceTypeModifier: Byte; RemovableMedia: Boolean; CommandQueueing: Boolean; VendorIdOffset: ULONG; ProductIdOffset: ULONG; ProductRevisionOffset: ULONG; SerialNumberOffset: ULONG; STORAGE_BUS_TYPE: DWORD; RawPropertiesLength: ULONG; RawDeviceProperties: array[0..511] of Byte; end; function ByteToChar(const B: Byte): Char; begin Result := Chr(B + $30) end; function SerialNumberToCardinal (SerNum: String): Cardinal; begin HexToBin(PChar(SerNum), PChar(@Result), SizeOf(Cardinal)); end; function SerialNumberToString(SerNum: String): String; var I, StrLen: Integer; Pair: string; B: Byte; Ch: Char absolute B; begin Result := ''; StrLen := Length(SerNum); if Odd(StrLen) then Exit; I := 1; while I < StrLen do begin Pair := Copy (SerNum, I, 2); HexToBin(PChar(Pair), PChar(@B), 1); Result := Result + Chr(B); Inc(I, 2); end; I := 1; while I < Length(Result) do begin Ch := Result[I]; Result[I] := Result[I + 1]; Result[I + 1] := Ch; Inc(I, 2); end; end; constructor THddInfo.Create; begin inherited; SetDriveNumber(0); end; function THDDInfo.IsInfoAvailable: Boolean; begin Result := FInfoAvailable end; procedure THDDInfo.ReadInfo; type PCharArray = ^TCharArray; TCharArray = array[0..32767] of Char; var Returned: Cardinal; Status: LongBool; PropQuery: STORAGE_PROPERTY_QUERY; DeviceDescriptor: STORAGE_DEVICE_DESCRIPTOR; PCh: PChar; begin FInfoAvailable := False; FProductRevision := ''; FProductId := ''; FSerialNumber := ''; FVendorId := ''; try FFileHandle := CreateFile( PChar('\\.\PhysicalDrive' + ByteToChar(FDriveNumber)), 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 ); if FFileHandle = INVALID_HANDLE_VALUE then RaiseLastOSError; ZeroMemory(@PropQuery, SizeOf(PropQuery)); ZeroMemory(@DeviceDescriptor, SizeOf(DeviceDescriptor)); DeviceDescriptor.Size := SizeOf(DeviceDescriptor); Status := DeviceIoControl( FFileHandle, IOCTL_STORAGE_QUERY_PROPERTY, @PropQuery, SizeOf(PropQuery), @DeviceDescriptor, DeviceDescriptor.Size, Returned, nil ); if not Status then RaiseLastOSError; if DeviceDescriptor.VendorIdOffset <> 0 then begin PCh := @PCharArray(@DeviceDescriptor)^[DeviceDescriptor.VendorIdOffset]; FVendorId := PCh; end; if DeviceDescriptor.ProductIdOffset <> 0 then begin PCh := @PCharArray(@DeviceDescriptor)^[DeviceDescriptor.ProductIdOffset]; FProductId := PCh; end; if DeviceDescriptor.ProductRevisionOffset <> 0 then begin PCh := @PCharArray(@DeviceDescriptor)^[DeviceDescriptor.ProductRevisionOffset]; FProductRevision := PCh; end; if DeviceDescriptor.SerialNumberOffset <> 0 then begin PCh := @PCharArray(@DeviceDescriptor)^[DeviceDescriptor.SerialNumberOffset]; FSerialNumber := PCh; end; FInfoAvailable := True; finally if FFileHandle <> INVALID_HANDLE_VALUE then CloseHandle(FFileHandle); end; end; function THDDInfo.SerialNumberInt: Cardinal; begin Result := 0; if ((IsInfoAvailable = True) and (FSerialNumber <> '')) then Result := SerialNumberToCardinal(FSerialNumber) end; function THDDInfo.SerialNumberText: string; begin Result := ''; if ((IsInfoAvailable = True) and (FSerialNumber <> '')) then Result := SerialNumberToString(FSerialNumber) end; procedure THDDInfo.SetDriveNumber(const Value: Byte); begin FDriveNumber := Value; ReadInfo; end; end. |
Re: Problem beim auslesen der Festplatten Seriennummer
Zitat:
habe den Code mal eben in eine Unit kopiert. Auf den Notebook mit IDE funktioniert das. Auf meiner Wks mit Ultra320 kommt nur ein Leerstring zurück. Gruß K.-D. |
Re: Problem beim auslesen der Festplatten Seriennummer
Auf
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz