Registriert seit: 19. Dez 2004
Ort: Münster
96 Beiträge
|
Hilfe bei Übersetzung von C nach Delphi
14. Jul 2008, 22:11
Hi an alle,
Ich hab die Frage hier schonmal gestellt, aber mach jetzt nochmal einen neuen Thread damit der Titel besser passt.
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 hdparm und bewirkt das Auslesen des Status:
Code:
__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);
Hier sind die Flags dazu:
Code:
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,
Und hier ist die Funktion do_drive_cmd, die dadurch aufgerufen wird:
Code:
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!
}
So, und jetzt die Frage:
Wie kann man obigen Delphi-Code entsprechend abwandeln, so dass er den Status abfragt?
Freue mich über jede Antwort!
Cu, Chris
|