![]() |
Hilfe bei Übersetzung von C nach Delphi
Hi an alle,
Ich hab die Frage ![]() Ich möchte den Power-Status (aktiv / Standby) einer Festplatte auslesen. Folgender Delphi-Code bewirkt, dass die Platte in Standby versetzt wird (Dank an hathor):
Delphi-Quellcode:
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; IDEREGS = TIDERegs; PIDERegs = ^TIDERegs; const BufferSize = SizeOf(TIDERegs)+4; IOCTL_IDE_PASS_THROUGH = $0004d028; implementation {$R *.dfm} Function IdeRegPassThrough(Device: String; var ideregs: TIDERegs ): Boolean; var ret:BOOL; hDevice : THandle; cbBytesReturned : DWORD; pInData : PIDERegs; pOutData : Pointer; Buffer : Array[0..BufferSize-1] of Byte; begin Result := False; FillChar(Buffer,BufferSize,#0); hDevice := CreateFile( PChar(Device), 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 pInData := @Buffer; pOutData := pInData; pInData^ := ideregs; ret := DeviceIoControl( hDevice, IOCTL_IDE_PASS_THROUGH, @Buffer, BufferSize, @Buffer, BufferSize, cbBytesReturned, nil ); if not ret then begin Exit; end; ideregs := PIDERegs(pOutData)^; finally CloseHandle(hDevice); end; Result := True; end; function SendToSleep(Device: String): Boolean; var ideregs : TIDERegs; begin Result := False; with ideregs do begin bFeaturesReg := 0; bSectorCountReg := 0; bSectorNumberReg := 0; bCylLowReg := 0; bCylHighReg := 0; bDriveHeadReg := $A0; bCommandReg := $E6; bReserved := 0; end; if not IdeRegPassThrough(Device, ideregs ) then Exit else Result := True; end; //Label1.caption:= BoolToStr(SendToSleep('\\.\PhysicalDrive0')); Folgender C-Code stammt aus dem Linux-Tool ![]()
Code:
Hier sind die Flags dazu:
__u8 args[4] = {ATA_OP_CHECKPOWERMODE1,0,0,0};
const char *state; if (do_drive_cmd(fd, args) && (args[0] = ATA_OP_CHECKPOWERMODE2) /* (single =) try again with 0x98 */ && do_drive_cmd(fd, args)) { err = errno; state = "unknown"; } else { state = (args[2] == 255) ? "active/idle" : "standby"; } printf(" drive state is: %s\n", state);
Code:
Und hier ist die Funktion do_drive_cmd, die dadurch aufgerufen wird:
ATA_OP_CHECKPOWERMODE1 = 0xe5,
ATA_OP_CHECKPOWERMODE2 = 0x98, ATA_OP_STANDBYNOW1 = 0xe0, ATA_OP_SLEEPNOW1 = 0xe6, // das hier wird im Delphi-Code schonmal benutzt ATA_OP_SLEEPNOW2 = 0x99, ATA_OP_SETIDLE1 = 0xe3,
Code:
So, und jetzt die Frage:
int do_drive_cmd (int fd, unsigned char *args)
{ #ifdef SG_IO struct ata_tf tf; void *data = NULL; unsigned int data_bytes = 0; int rc; if (args == NULL) goto use_legacy_ioctl; /* * Reformat and try to issue via SG_IO: */ if (args[3]) { data_bytes = args[3] * 512; data = args + 4; } tf_init(&tf, args[0], 0, args[1]); tf.lob.feat = args[2]; if (tf.command == ATA_OP_SMART) { tf.lob.nsect = args[3]; tf.lob.lbal = args[1]; tf.lob.lbam = 0x4f; tf.lob.lbah = 0xc2; } rc = sg16(fd, SG_READ, &tf, data, data_bytes, 0); if (rc) { if (rc == -1) goto use_legacy_ioctl; errno = rc; rc = -1; } else if (tf.status & (ATA_STAT_ERR | ATA_STAT_DRQ)) { if (verbose) fprintf(stderr, "I/O error, ata_op=0x%02x ata_status=0x%02x ata_error=0x%02x\n", tf.command, tf.status, tf.error); errno = EIO; rc = -1; } args[0] = tf.status; args[1] = tf.error; args[2] = tf.lob.nsect; return rc; use_legacy_ioctl: #endif /* SG_IO */ if (verbose) fprintf(stderr, "Trying legacy HDIO_DRIVE_CMD\n"); return ioctl(fd, HDIO_DRIVE_CMD, args); // das ist wohl die entscheidende Zeile! } Wie kann man obigen Delphi-Code entsprechend abwandeln, so dass er den Status abfragt? Freue mich über jede Antwort! Cu, Chris |
Re: Hilfe bei Übersetzung von C nach Delphi
Hmm, das war vielleicht etwas zu viel...
Kann mir denn vielleicht wenigstens jemand einen Tipp geben, wie ich bei diesem Aufruf den Rückgabewert verarbeiten kann?
Delphi-Quellcode:
ret ist ja nur eine Boolean-Variable, also wird der Wert wohl in einem der Puffer zu finden sein. Aber mit diesen Pointern usw. kenn ich mich nicht aus. Wie kriege ich diesen Wert denn in einen normalen Datentyp, wie bsp. Integer oder String konvertiert?
ret := DeviceIoControl( hDevice, IOCTL_IDE_PASS_THROUGH, @Buffer, BufferSize, @Buffer, BufferSize, cbBytesReturned, nil );
Cu, Chris |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:25 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