(WinAPI) [HELP] Files kopieren :: Zugriffsverletzung



  • Hi,

    ich habe ein Prog, das macht Backup von Dateien, die bestimmte Extensions haben.
    Das läuft wunderbar bei sogut wie jedem.
    Allerdings hat ca jeder 500ste ein "Zugriffsverletzung un Modul ...".
    Das muss beim Kopieren der Dateien auftreten. Ich habe schon versucht die Dateien per WinAPI-Funktionen zu kopieren und auch per High-Level mit FILE-Pointer.
    Bei den "Problemfällen" klappt aber all das nicht.

    Einer von denen hat mal sein OS neu aufgespielt und danach hat es funktioniert.
    Auch die Windows-Versaonen kann man nicht festmachen. Mal XP mal W2k mal ...

    Hat jemand ne Idee, wie ich noch kopieren könnte?

    Oder ist es möglich, dass ne andere BCB-Version (ich benutze BCB5) das so kompiliert, dass es auf den "ProblemPCs" läuft?

    Ich bin ziemlich ratlos.
    Danke im Voraus!

    MfGr,
    Mid



  • Poste doch mal den Quellcode, womit du die Datei öffnest und speicherst. Eine Zugriffsverletzung kann normalerweise nichts mit anderen Dateien zu tun haben.



  • Also wie gesagt, habe ich mehrere Varianten probiert. 2x WinAPI und einmal HighLevel. Also schiebt micht nicht wieder ins WinAPI, wenn ich das hier losgeschickt habe. 😃

    Variante 1:

    // Funktion fCopy()
    int fCopy(AnsiString *orgName, AnsiString *bakName, int runs)
    {
     FILE *fp1, *fp2;
     unsigned int c;
     char *fin, *fout;
    
     for (int i=0; i<runs; i++)
     {
         // Dateien öffnen
         fp1 = fopen( (*(orgName + i)).c_str(), "rb");
         fp2 = fopen( (*(bakName + i)).c_str(), "wb");
    
         // Dateiinhalte kopieren
         while (  ( c = getc(fp1) ) != EOF  )
             putc( c, fp2 );
    
         // Dateien schließen
         fclose(fp1);
         fclose(fp2);
     }
    
     return 0;
    }
    

    Variante 2:

    int fCopy ( AnsiString *orgName, AnsiString *bakName, int runs )
    {
         // Datei orgName nach bakName kopieren
         // runs = Anzahl der gefundenen *.part.met
         for (int i=0; i<runs; i++)
         {
             // falls CopyFile () fehlschlägt, Wert ungleich 0 zurückliefern
             // an aufrufende Funktion
             if (   CopyFile (    (*(orgName + i)).c_str(),
                                  (*(bakName + i)).c_str(),
                                  false
                              ) == 0  )
                 return 1;
         }
    
         return 0;
    }
    

    Variante 3:

    int fCopy ( AnsiString *orgName, AnsiString *bakName, int runs )
    {
        HANDLE hSrc, hDest;
        char pBuffer[1024];
        DWORD dwRead, dwWritten;
    
        // Datei orgName nach bakName kopieren
        // runs = Anzahl der gefundenen *.part.met
        for (int i=0; i<runs; i++)
        {
            // Quelldatei öffnen - Handle ermitteln
            hSrc = CreateFile (  (*(orgName + i)).c_str(),
                                 GENERIC_READ, 0, NULL, OPEN_EXISTING,
                                 FILE_ATTRIBUTE_NORMAL, 0 );
            // falls ungültiges Handle, dann Abbruch und entspr. Return-Wert
            if ( hSrc == INVALID_HANDLE_VALUE )
            {
                Application->MessageBox( MSG_FAILED_A, BOXTITLE_ERROR, MB_OK );
                return 1;
            }
    
            // Zieldatei öffnen - Handle ermitteln
            hDest = CreateFile (  (*(bakName + i)).c_str(),
                                  GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                                  FILE_ATTRIBUTE_NORMAL, 0);
            // falls ungültiges Handle, dann Abbruch und entspr. Return-Wert
            if ( hDest == INVALID_HANDLE_VALUE )
            {
                Application->MessageBox( MSG_FAILED_A, BOXTITLE_ERROR, MB_OK );
                return 1;
            }
    
            // Kopiervorgang
            do
            {
                ReadFile(hSrc, pBuffer, sizeof(pBuffer), &dwRead, NULL);
                if (dwRead != 0)
                    WriteFile(hDest, pBuffer, dwRead, &dwWritten, NULL);
            } while (dwRead != 0);
    
            // Handles schließen
            CloseHandle(hSrc);
            CloseHandle(hDest);
    
            return 0;
        }
    }
    

    Ich habe mir diese Funktionen jeweils so geschrieben, dass ich neben den Arrays, die die Filenamen enthalten auch gleichtzietig ne Zahl übergebe, die sagt, wieviele Dateinamen übergeben wurden, ergo wieviele Kopiervorgänge notwendig sind. Und die werden dann auch gleich durchgeführt.

    greetz,
    mid



  • ok, jetzt bitte noch die exakte Fehlermeldung und die ungefähre Position wo dieser Fehler auftritt.



  • zugriffsverletzung
    > bei adresse 00481298 in modul "pmbackup v1.1e.exe

    Es ist irgendwo in der fCopy Funktion. Ich kann das leider nicht genauer lokalisieren, da ich diese Fehlermeldung selbst noch nie erhalten habe. Ich hbas nur von 3-4 Usern per Mail erhalten. Sorry. Ich weiß ja selbst nicht mehr, woran das noch liegen kann. 😕



  • hm,

    mir sind bei den Windowsversionen über Version 98 deraretige Probleme auch schon aufgefallen. Dateien lassen sich nihct schreiben, obwohl Schreibrechte auf dem Laufwerk existieren.

    Am besten ist, wenn man I/O- Funktionen benutzt die Betriebssystem spezifisch angeboten werden. Ich würde hier also mit API arbeiten. Variante 3 scheint mir also am besten geeignet. Allerdings solltest du CopyFile benutzen.

    Ansonsten überprüfe du im Zielverzeichnis schreibrechte hast.

    Siehe FILE_ATTRIBUTE_READONLY
    und _WIN32_FIND_DATA oder ähnliches...

    ich kann mir aber nihct vorstellen, das bei dieser Geschichte eine Zugriffsverletztung bei herausspringen soll. WriteFile wird da false zurückliefern ( warum fragst du das eigentlich nicht ab, um dich zu vergewissern, dass der Vorgang erfolgreich war) aber keine Zugriffsverletztung rausschmeissen. Die Zugriffsverletztung kommt woanders her..



  • Hi Andreas,

    ich danke Dir,
    ich werd mir das nochmal alles genauer anschauen müssen und vielleicht noch ein paar Daten mehr sammeln, von den Leuten, bei denen es nicht geht.

    Thanks anyway!
    mid



  • Ich schiebe diese mal nach API. Vieleicht haben die dort noch Lösungsansätzte.


Anmelden zum Antworten