Announcement

Collapse
No announcement yet.

Steuerung von Bandlaufwerken über API

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Steuerung von Bandlaufwerken über API

    wir verwenden zur Datensicherung auf einem Win NT4 Server die von Microsoft mitgelieferte Backup-Lösung auf einem
    Dat-Streamer von HP. Für eine bessere Kontrolle der Datensicherung möchte ich nun per Programm abfragen, welches
    Band im Laufwertk liegt (Bandname).

    Kennt jemand einen Weg ?

    Danke !

    mfg

    Hauke Gintner

  • #2
    Hallo,

    das Bandlaufwerk ist unter Windows NT nur eine "Datei", die zum Beispiel über die API-Funktion CreateFile über den Namen <B>\\.\Tape0</b> geöffnet werden kann ("...<I>Windows NT/2000: You can open tape drives using a file name of the form \\.\TAPEx where x is a number indicating which drive to open, starting with tape drive 0. To open tape drive 0 in C, use the file name "\\\\.\\TAPE0". For more information on manipulating tape drives for backup or other applications, see Tape Backup.</i>").

    Die verschiedenen Backups verwenden eigene Label-Informationen, zum Beispiel kann im Fall des Microsoft SQL Server 7 über T-SQL das Label eines Bandes ausgelesen werden:
    <pre>
    RESTORE LABELONLY
    FROM TAPE = \\.\TAPE0
    </pre>

    Im Gegensatz dazu verwendet Windows NT ein eigenes Backup-Format, wobei dafür auch eine Funktionsbeschreibung in der Hilfedatei des Microsoft Platform SDK ist: "<i>Tape Backup - The tape functions provided by the Microsoft® Win32® API enable backup applications to read from and write to a tape, initialize a tape, and retrieve tape or tape drive information. </i>". Ich würde daher unter den folgenden API-Funktionen nachsehen: <br>
    - BackupRead <br>
    - BackupSeek<br>
    - BackupWrite<br>
    - CreateTapePartition<br>
    - EraseTape<br>
    - GetTapeParameters<br>
    - GetTapePosition<br>
    - GetTapeStatus<br>
    - PrepareTape<br>
    - SetTapeParameters
    - SetTapePosition
    - WriteTapemar

    Comment


    • #3
      die folgende Beschreibung habe ich vom Microsoft-Server:

      To perform any input or output on a tape, a backup application must first obtain a handle of the tape device. The following code sample shows how to use the CreateFile function to open a tape device.

      HANDLE hTape; // handle to tape device

      hTape = CreateFile(

      "\\\\.\\TAPE0", // name of tape device to open

      GENERIC_READ | GENERIC_WRITE, // read/write access

      0, // not used

      0, // not used

      OPEN_EXISTING, // required for tape devices

      0, // not used

      NULL); // not used

      Mein Funktionsaufruf in Delphi

      Var h : tHandle;

      h := createFile('\\\\.\\Tape0', GENERIC_READ, 0, 0, OPEN_EXISTING, 0, NULL);

      führt jedoch immer nur zu der Fehlermeldung

      "Ungültige Vaiant-Typ-UMWANDLUNG2

      Hat jemand eine Idee, wo mein Fehler sitzt ?

      Danke und Gru&#223

      Comment


      • #4
        Hallo,

        der letzte Parameter <b>Null</b> ist ein Variant - hier ist bestimmt <b>0</b> gemeint - oder

        Comment


        • #5
          0 und Null sind eben zweierlei - soviel zu den Informationen von Microsoft !

          Danke

          hm

          Comment


          • #6
            Hallo,

            in diesem Fall ist Microsoft - ausnahmsweise - einmal unschuldig, der Übertäter ist hier die Sprache <b>C</b>, die so etwas zulässt. Nicht ohne Grund versucht MS nun, alle von den Vorteilen von <b>C#</b> zu überzeugen ;-)

            P.S: Eventuell hätte Borland auch für NULL einen anderen Namen finden können, der nicht mit C kollidiert ;-

            Comment


            • #7
              CreateFile funktioniert jetzt, den Bandstatus kann ich zwischenzeitlich mit GetTapeStatus ebenfalls korrekt abfragen.
              Das auslesen von Daten ist jedoch nicht zu machen.
              Nachdem die Doku zu den beiden Funktionen BackupWrite und BackupRead etwas mißverständlich ist, habe ich es mit beiden versucht:

              nNumberOfBytesToRead := 2048;

              GetMem(lpPuffer, 2050);

              if not BackupRead(h, lpPuffer, nNumberOfBytesToRead, lpnNumberOfBytesRead, false, false, lpContext) then begin

              // if not BackupWrite(h, lpPuffer, nNumberOfBytesTowrite, lpnNumberOfByteswrite, false, false, lpContext) then begin

              application.Messagebox(PChar('Fehler'),'',0);

              end else begin

              res := integer(lpnNumberOfBytesRead);

              // res := integer(lpnNumberOfByteswrite);

              application.Messagebox(PChar(intToStr(res)),'',0);

              application.Messagebox(pchar(string(lpPuffer)),'', 0);

              end;

              FreeMem(lpPuffer, 2050);

              CloseHandle(h);

              In beiden Fällen erhalte ich jeweils null (verzeihung, ich meine natürlich 0) gelesene/geschriebene Bytes und der Versuch den Pufferinhalt anzuzeigen bringt nur eine leere Messagebox.

              Danke für alle Hinweise (insbesondere auch Ihnen Herr Kosch)

              Gruß

              hm

              Comment


              • #8
                Hallo,

                in der MSDN Library habe ich auf die Schnelle die folgende Übersichtsbeschreibung gefunden:

                <i><b>Creating a Backup Application</b><br>
                To perform any input or output on a tape, a backup application must first obtain a handle of the tape device. The following code sample shows how to use the CreateFile function to open a tape device.
                </i><pre>
                HANDLE hTape; // handle to tape device

                hTape = CreateFile(
                "\\\\.\\TAPE0", // name of tape device to open
                GENERIC_READ | GENERIC_WRITE, // read/write access
                0, // not used
                0, // not used
                OPEN_EXISTING, // required for tape devices
                0, // not used
                NULL); // not used
                </pre>
                <i>To back up a directory tree to a tape, an application must use the FindFirstFile and FindNextFile functions to traverse the directory tree. Each time a file is found, the application should get the file's attributes by using the GetFileAttributes function. If there are hard links, the application should determine the number of links and save the file's unique identifier in a table for future comparisons. The first time a file is found, the application should use CreateFile to open the file and the BackupRead function to begin the backup. Then it can use the WriteFile function repeatedly to transfer all the information in the buffer filled by BackupRead to the tape. The second time a file is found (checked against the table of file identifiers when there are hard links), the application can simply write the general file information to the tape, followed by a stream whose identifier is BACKUP_LINK.

                When restoring files from tape to disk, an application must use the CreateFile, BackupWrite, and ReadFile functions. For each file on the tape, the application should use CreateFile to create a new file on disk and BackupWrite to begin restoring the file. Then it should use ReadFile repeatedly until all the information for the file has been read from the tape into the buffer filled by BackupWrite. If one of the streams in the BackupWrite buffer has a BACKUP_LINK stream identifier, the application must establish a hard link. If the data needed to establish the link does not exist, BackupWrite fails. The application can use a preexisting catalog to locate and restore the original data, or it can notify the user that the file data to be restored is in a different location. </i>

                Bei derartigen speziellen Aufgaben greife ich immer zu meiner Platform SDK-CDROM, um die C/C++-Beispielprojekte über Setup nachzuinstallieren (da die mittlerweile über ein 1GB benötigen, hole ich immer nur den Themenbereich auf die Platte, der mich zur Zeit interessiert - und das ich bei mir meistens nur COM/COM+ ). Sind alle Beispiele installiert, kann man dann nach einem Microsoft-Beispiel suchen, wo diese API-Funktionen verwendet werden

                Comment


                • #9
                  übers Wochenende habe ich herumexperimentiert.

                  Band := ;
                  h := createFile('\\.\Tape0', GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
                  res := GetTapeStatus(h);

                  liefert mir korrekte Informationen über den Status des Bandlaufwerkes, ich kann jedoch
                  mit

                  res := ReadFile(h, Puffer, nNumberOfBytesToRead, lpnNumberOfBytesRead, nil);

                  keine Daten lesen.

                  Gebe ich bei der CreateFile Anweisung nicht die Bezeichnung \\.\Tape0 für das Bandlaufwerk an, sondern z. B. c:\autoexec.bat, dann bekomme ich die ersten 256 Zeichen dieser Datei, d. h. der Aufruf von ReadFile kann nicht völlig falsch sein.

                  Oder ???

                  Gruß

                  hm

                  Comment


                  • #10
                    Hallo,

                    konnte das Problem mit dem Bandlaufwerk gelöst werden?

                    Gruß
                    Rolf Do

                    Comment


                    • #11
                      NULL ist in C = 0 = nil. Ein <b>NULL</b> im C Source sollte immer in <b>nil</b> im Pascal Source umgewandelt werden und hat rein garnichts mit den <b>NULL</b> in Delphi zu tun. Dieses ist nämlich tatsächlich ein NULL Variant, oder ein leerer Variant.

                      Der "Fehler" liegt hier wohl eher bei den Borland'ianern mit ihrerer mißdeutenden Definifition.

                      Gruß Hage

                      Comment


                      • #12
                        Moin Moin,

                        in meinem letzten Beitrag hierzu ist der von mir verwendete Funktionsaufruf abgebildet.

                        Er enthält wie du empfohlen hast nil statt null. Die Resultate waren leider negativ.

                        Das Problem habe ich bis heute noch nicht lösen können !

                        Herzlichen Dank

                        H. Gintne

                        Comment

                        Working...
                        X