![]() |
Auf eine Diskette schreiben
Also: ich habe ein kleines Problem: ich würde gerne auf einer Diskette in die ersten Sectoren schreiben können. (ca die ersten 512 bytes ... die meisten wissen, was dort eingebaut werden kann ...) .... nun: mit windows-mitteln ist es ja leoider nicht möglich ... ich habe aber schon einige C-Sourcen gesehen, mit denen es mgl ist (leider waren sie zhalt 1. in c geschrieben und 2. war das ganze unter Linux ... habe von beidem kaum ahnung) ... kann man sowas auch mit Delphi machen?
|
Ja, kann man :)
Guck mal da nach: ![]() Dieses Tool schreibt unter Win95/98/ME/NT/2k/XP Raw-Daten auf Diskette; unter anderem auch in den Bootsektor :) Die Sourcen sind da verfügbar, da GPL. Kommt halt auch aus dem Unix-Bereich. Interessant dürfte für Dich vor allem die Unit 'BlockDev' sein, wo die TNTDisk bzw. die TWin95Disk direkt auf die Physikalischen Sektoren zugreifen. Ich weiss leider nicht, wer der Urheber ist, da im Code nichts entsprechendes vermerkt ist. Deswegen werde ich ihn hier auch nicht posten, obwohl es der GPL unterliegt. Cya, Sebastian |
Hmm - also das Progie scheint mir sehr geeignet .... leider habe ich kei9ne ahnung, wie es genau funzt, da im source das ganze auf so unzähligviele prozeduren verteilt ist .....
gibt es noch ne einfacher (besser: übersichtlichere) Möglichkeit? Im notfall würde ich mit dem Prog auch weiterkommen, aber man will ja auch gerne wissen, wie es Fuzt :-) |
Zitat:
Also, mal im Schnelldurchgang durchsteppen:
Code:
Was wir hier brauchen ist ein schreibfähiges OPEN, ein WritePhysicalSector, und ein Close.
TNTDisk = class(TBlockDevice)
public constructor Create; override; destructor Destroy; override; procedure ReadPhysicalSector (Sector : DWORD; count : DWORD; Buffer : Pointer); override; procedure WritePhysicalSector(Sector : DWORD; count : DWORD; Buffer : Pointer); override; function Open : Boolean; override; function Close : Boolean; override; procedure SetFileName(Name : String); procedure SetMode(Writeable : Boolean); procedure SetPartition(Start : _Large_Integer; Length : _Large_Integer); private FileName : String; h : THandle; Writeable : Boolean; SectorSize : DWORD; Start : _Large_Integer; //longlong; // start Length : _Large_Integer; //longlong; // length end; Zuerst das Open:
Code:
Ist eigentlich ganz einfach:
function TNTDisk.Open : Boolean;
begin if Writeable then begin h := Windows.CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ , nil, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0); end else begin [...] end; if h <> INVALID_HANDLE_VALUE then Result := True else Result := False; end;< CreateFile gibt Dir einfach nur ein Handle zurück. Das hier ist allerdings hardcore-api. Ein F1 auf CreateFile sollte Dir hier schon sehr weit weiterhelfen. Mit diesem Handle kannst Du dann Operationen auf dem angegebenen 'File' durchführen. Also zum Beispiel Deine Daten schreiben. Wir sind nun in WritePhysicalSector. Du übergibst den Sector, in den Du schreiben willst, die Länge der zu schreibenden Daten und die Daten als Pointer auf das erste Byte, das Du schreiben willst. In der Prozedur sieht das dann so aus:
Code:
Hier wird erst berechnet, von welcher Position aus Du schreiben wirst.
begin
Debug('Write sector ' + IntToStr(Sector) + ' count = ' + IntToStr(Count), DebugOff); // work out the start address (of partition/file) WriteStart.QuadPart := Start.QuadPart + (Sector * SectorSize); WriteLength := Count * SectorSize;
Code:
Bis zu der berechneten Stelle wird nun der Cursor in der Datei, also in dem Fall der Sector, verschoben. Das SeekFilePointer ist im Prinzip nichts anderes als ein intelligenter verschiebe - Algorithmus.
// seek to the correct pos
Seek := SetFilePointer(h, WriteStart.LowPart, @WriteStart.HighPart, FILE_BEGIN); if Seek <> $FFFFFFFF then begin // seek successful, lets read if not WriteFile2(h, Buffer, WriteLength, ActualLengthWritten, nil) then begin Error := GetLastError; Debug('Write failed error=' + IntToStr(GetLastError), DebugOff); raise Exception.Create('Write Failed: (' + IntToStr(GetLastError) + ')'#10 + SysErrorMessage(Error)); end else if WriteLength <> ActualLengthWritten then begin Debug('Possible error, only ' + IntToStr(ActualLengthWritten) + ' bytes written', DebugLow); end; end Wenn der Cursor erfolgreich verschoben wurde, das Suchergebnis also keinen ungültigen Wert zurückliefert, wird mit WriteFile2 auf dem Pointer der Datei aus dem Pointer der Quelldaten so viele Bytes geschrieben, wie in WriteLength spezifiziert wurde. In ActualLengthWritten kommt die Anzahl der tatsächlich geschriebenen Bytes zurück. Die beiden Werte sollten eigentlich identisch sein :) Wenn das nicht geklappt haben sollte gibts entsprechende Meldungen. Das Close schmeisst hinterher das Handle auf das File sauber weg und schliesst die Schreibverbindung. Viel mehr Magie steckt da nicht dahinter. Ein bisschen F1 drücken auf den interessanten Schlagworten und die Api-Hilfe sollten hier eigentlich reichen, um da vollständig durchzusteigen. Cya, Sebastian |
Hmm - irgendwie steige ich da immernoch nicht ganz durch .. ist ja aber auch egal (solange das progie das tut, was es soll - funktionieren ;-) ) ....
vielen Dank für deinen Tip |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:58 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