Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Floppy Image schreiben endet mit einer Access Violation (https://www.delphipraxis.net/10395-floppy-image-schreiben-endet-mit-einer-access-violation.html)

Luckie 17. Okt 2003 16:02


Floppy Image schreiben endet mit einer Access Violation
 
Ich habe eien Funktion, die mir ein Image von einer Floppy erstellt:
Delphi-Quellcode:
function WriteFile(Filename: string): Integer;
var
  SrcDrive: string;
  hDrive: THandle;
  Geometry: DISK_GEOMETRY;
  hFile: THandle;
  IOBuffer: Pointer;
  BytesRead, BytesWritten: DWORD;
  VirtBufferSize: DWORD;
  NumBufs: DWORD;
  Loop: Integer;
  b: Boolean;
begin
  SrcDrive := '\\.\' + DRIVE;
  hDrive := CreateFile(@SrcDrive[1], GENERIC_READ or GENERIC_WRITE,
    FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
  if hDrive <> INVALID_HANDLE_VALUE then
  begin
    if LockVolume(hDrive) then
    begin
      if GetDiskGeometry(hDrive, Geometry) then
      begin
        hFile := CreateFile(@Filename[1], GENERIC_READ or GENERIC_WRITE, 0, nil,
          CREATE_ALWAYS, 0, 0);
        if hFile <> INVALID_HANDLE_VALUE then
        begin
          NumBufs := Geometry.Cylinders.LowPart;
          VirtBufferSize := Geometry.TracksPerCylinder * Geometry.SectorsPerTrack
            * Geometry.BytesPerSector;
          IOBuffer := VirtualAlloc(nil, VirtBufferSize, MEM_COMMIT,
            PAGE_READWRITE);
          if Assigned(IOBuffer) then
          begin
            SendMessage(hApp, DIM_START, 0, NumBufs);
            for Loop := NumBufs downto 0 do
            begin
              b := Windows.ReadFile(hDrive, IOBuffer, VirtBufferSize, BytesRead, nil);
              if b and (BytesRead > 0) then
              begin
                b := Windows.WriteFile(hFile, IOBuffer, BytesRead, BytesWritten,
                  nil);
                if (not b) and (BytesRead <> BytesWritten) then
                  break;
                SendMessage(hApp, DIM_PROGRESS, 0, NumBufs-Loop);
              end;
            end; // for
            VirtualFree(IOBuffer, sizeof(VirtBufferSize), MEM_RELEASE);
          end; // Assigned
          CloseHandle(hFile);
        end; // hFile
      end;
    end;
  end;
  DismountVolume(hDrive);
  UnlockVolume(hDrive);
  if hDrive <> INVALID_HANDLE_VALUE then
    CloseHandle(hDrive);
  result := GetLastError();
end;
Sie läuft wunderbar durch, nur am Ende bekomme ich eine Access Violation. Setze ich den Cursor auf die letzte Zeile und starte mit F4, läuft er bis dahin, drücke ich dann F7 bekomme ich die Access Vialotion. Aufgerufen wird die Funktion aus einem Thread raus:
Delphi-Quellcode:
function MakeImgThread(p: Pointer): Integer;
var
  Filename: string;
  ECode: Integer;
begin
  Filename := PTThreadParams(p)^.FFilename;
  EnableWindow(GetDlgItem(hTabDlgs[0], IDC_BTNSAVEAS), False);
  EnableWindow(GetDlgItem(hTabDlgs[0], IDC_BTNMAKEIMG), False);
  ECode := Writefile(Filename);
  if ECode <> 0 then
    MessageBox(hApp, @SysErrorMessage(ECode)[1], 'Fehler beim Erstellen des Images', MB_ICONSTOP);
  EnableWindow(GetDlgItem(hTabDlgs[0], IDC_BTNSAVEAS), True);
  EnableWindow(GetDlgItem(hTabDlgs[0], IDC_BTNMAKEIMG), True);
  SendDlgItemMessage(hStatus, IDC_PROGRESS, PBM_SETPOS, 0, 0);
  result := 0;
  FreeMem(p);
end;
Aber das scheint es nicht zu sein. Ich bekomme sie auch, wenn ich es ohne Thread mache. Auskommentieren der letzten zeilen bring auch nichts.

Was verursacht also die AV um Himmels Willen? http://www.luckie-online.de/pics/mecker.gif

Luckie 17. Okt 2003 17:47

Re: Floppy Image schreiben endet mit einer Access Violation
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, ich habe debuggt bis der Arzt kommt und es hat nichts geholfen. Wenn ich in Einzelschritten durchgege, komme ich bis zur letzten Zeile und dann kracht es.

Ich hänge mal das Projekt an, eventuell könnt hier auch mal debuggen.

Christian Seehase 17. Okt 2003 18:23

Re: Floppy Image schreiben endet mit einer Access Violation
 
Moin Luckie,

zwei Sachen:
Deine Schleife hat einen Durchlauf zuviel
Delphi-Quellcode:
for Loop := NumBufs downto 0 do
entweder NumBufs-1 oder downto 1

Der eigentliche Fehler dürfte aber das hier sein:

Code:
b := Windows.ReadFile(hDrive, [color=red]IOBuffer[/color], VirtBufferSize, BytesRead, nil);
Code:
b := Windows.ReadFile(hDrive, IOBuffer[color=red]^[/color], VirtBufferSize, BytesRead, nil);
(beim Schreiben natürlich auch)

Luckie 17. Okt 2003 18:28

Re: Floppy Image schreiben endet mit einer Access Violation
 
Das war schon mal sehr gut. Dank dir. Jetzt bekomme ich nur als Fehlermeldung:
Zitat:

Falscher Parameter.
am Ende von WriteFile.

Aber er stürtzt zu mindest nicht mehr ab. :P

Luckie 17. Okt 2003 18:32

Re: Floppy Image schreiben endet mit einer Access Violation
 
Hab den Schuldigen gefunden:
Delphi-Quellcode:
VirtualFree(IOBuffer, sizeof(VirtBufferSize), MEM_RELEASE);
So muß es heißen
Code:
VirtualFree(IOBuffer, sizeof(VirtBufferSize), [b]MEM_DECOMMIT[/b]);

Christian Seehase 17. Okt 2003 18:51

Re: Floppy Image schreiben endet mit einer Access Violation
 
Moin Luckie,

ich würde mal sagen:

Code:
VirtualFree(IOBuffer, [color=red]0[/color], MEM_RELEASE);
denn:

Zitat:

Zitat von PSDK VirtualFree
MEM_RELEASE
...If you specify this value, dwSize must be zero, and lpAddress must point to the base address returned by the VirtualAlloc function when the region was reserved.
...

Remarks
...
If a page is decommitted but not released, its state changes to reserved. You can subsequently call VirtualAlloc to commit it, or VirtualFree to release it.
...


Luckie 17. Okt 2003 18:57

Re: Floppy Image schreiben endet mit einer Access Violation
 
Hm. :gruebel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:12 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz