home *** CD-ROM | disk | FTP | other *** search
- {$A+,B-,D-,E-,F+,G-,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X+}
- {$M 16384,0,655360}
- (*========================================================*)
- (* REMBASE.PAS v. 1.1 *)
- (* Slave-Programm für REMOTE *)
- (* (C) 1993 Ralf Hensmann & DMV-Verlag *)
- (* Compiler: Turbo/Borland Pascal 7.0, Real Mode Target *)
- (* ====================================================== *)
- {$DEFINE LapLink} (* wird auch in den Units benötigt! *)
- (* Unbedingt zusätzlich im Compiler- *)
- (* menü [O]ptions | [C]ompiler *)
- (* | [C]ond. defines setzen !!! *)
- {$DEFINE NoKeyBreak} (* kein Tastatur-Abbruch während *)
- (* das Remotesystem aktiv ist *)
- PROGRAM RemoteSlave;
- USES
- Dos, Crt, Graph, Crc, ParData, ParCRC, Strings, Rem_Type;
-
- CONST
- File_Max = 17;
- DoProtocol = FALSE;
- (* Falls protokolliert werden soll, die Grafik- *)
- (* initialisierung auskommentieren! *)
- NoContact: STRING[23] = 'Kontakt abgebrochen ...';
- ExitMsg :
- {$IFNDEF NoKeyBreak}
- STRING[58] = ' »Taste« zum Abbruch (dann sofort' +
- ' Remotelaufwerk unloaden)';
- {$ELSE}
- STRING[41] = ' Abbruch nur per Unload vom Master-System';
- {$ENDIF}
-
- TYPE
- tBufArray = ARRAY [0..65534] OF BYTE;
-
- VAR
- st, lw, (* Hilfsstrings für Eingaben *)
- Path, (* Pfad des Befehls *)
- FileName, (* Dateiname *)
- CurDir : STRING; (* aktuelles Verzeichnis *)
- nr, Error, (* für Val() *)
- i, j : WORD; (* Laufvariablen *)
- Head : fx_Command_head; (* Kommandobefehl *)
- NoDrive : BOOLEAN; (* Laufwerk nicht echt ... *)
- Buf : ARRAY [0..255] OF BYTE;
- (* allgemeiner Puffer *)
- NetPath : ASCIIZ; (* Pfad als ASCIIZ *)
- FileNr : BYTE; (* Hilfsvariable aktuelle Datei *)
- f : ARRAY [0..File_Max] OF File;
- (* Puffer für offene Datei *)
- Free : ARRAY [0..File_Max] OF BOOLEAN;
- (* Welche sind frei ? *)
- f_PSP : ARRAY [0..File_Max] OF WORD;
- (* PSP des offenen Files *)
- t : SearchRec; (* für FindFirst/Next *)
- DataBuf : ^tBufArray;(* Datenübertragung *)
- DataBuf2 : ^WORD; (* Sicherheit wegen 64 kByte *)
- fn2 : ASCIIZ; (* für Rename *)
- LwTbl : ARRAY [1..27] OF CHAR;
- (* Tabelle der mögl. Laufwerke *)
- ch : CHAR; (* für Tastendruck abwarten ... *)
- grResult, (* Ergebnis der Grafik-Initial. *)
- GraphDriver, (* verwendeter Grafiktreiber *)
- GraphMode , (* verwendeter Grafikmodus *)
- XOld, YOld : INTEGER; (* alte X/Y-Koord. des Logo *)
- OldExitProc: POINTER; (* Zeiger auf die Exit-Prozedur *)
- MaxX, MaxY : INTEGER; (* Grafik MaxX/MaxY *)
- p1, p2 : POINTER; (* Zeiger auf die Bitmaps *)
- PicSize, (* Größe der »toolbox«-Bitmap *)
- BarColor, (* Farbe des »toolbox«-Balken *)
- FrameColor, (* Farbe des Bitmap-Rahmen *)
- BackColor, (* Hintergrundfarbe d. Bitmap *)
- ShadeColor, (* Schattenfarbe d. Schriftzugs *)
- BarStyle, (* Style des Balken i.d. Bitmap *)
- BkStyle, (* Hintergrund-Style *)
- txColor : WORD; (* Farbe des Schriftzugs *)
-
- (* die notwendigen BGI-Treiber einbinden: *)
- PROCEDURE HercDriverProc; EXTERNAL; {$L HERC.OBJ }
- PROCEDURE EGAVGADriverProc; EXTERNAL; {$L EGAVGA.OBJ}
- PROCEDURE CGADriverProc; EXTERNAL; {$L CGA.OBJ }
- PROCEDURE ATT400DriverProc; EXTERNAL; {$L ATT.OBJ }
- PROCEDURE PC3270DriverProc; EXTERNAL; {$L PC3270.OBJ}
-
- (* die verwendeten Schriften einbinden: *)
- PROCEDURE SmallFontProc; EXTERNAL; {$L LITT.OBJ }
- PROCEDURE TriplexFontProc; EXTERNAL; {$L TRIP.OBJ }
-
- PROCEDURE DisplayLogo;
- (* DisplayLogo löscht das alte Display und zeigt das neue *)
- (* Logo auf einer Random-Bildschirmposition an *)
- VAR
- x, y : WORD;
- p : ShortInt;
- BEGIN
- Randomize; (* Zufallszähler initialis. *)
- x := Random(MaxX - 191); (* x-Position und *)
- y := Random(MaxY - 100); (* y-Position = Zufallswert *)
- IF x = 0 THEN x := 190; (* ... aber > 0 *)
- IF y = 0 THEN y := 60;
- PutImage(XOld, YOld, p2^, CopyPut); (* Löschen alt *)
- PutImage(x, y, p1^, CopyPut); (* Setzen neu *)
- IF GraphDriver IN [EGA, EGA64, VGA] THEN BEGIN
- Randomize;
- p := Random(64); (* Zufallspalette *)
- IF p MOD 8 = 0 THEN p := 63; (* Rahmenfarbe per *)
- SetPalette(FrameColor, p); (* Palette steuern *)
- END;
- XOld := x; YOld := y; (* Position merken *)
- END;
-
- PROCEDURE BuildLogo;
- (* Aufbau der Grafik. Zeichnen und Abspeichern des Logo *)
- CONST
- txName: STRING[ 7] = 'toolbox';
- STitle: STRING[33] = 'Die Programmierer-Fachzeitschrift';
- {$IFDEF SaveBMP}
- VAR
- f : File;
- {$ENDIF}
- BEGIN
- XOld := 1; (* Voreinstellungen für alte Werte *)
- YOld := 1;
- MaxX := GetMaxX; (* grafikkartenunabhängige Auflösung *)
- MaxY := GetMaxY; (* in X- und Y-Richtung *)
-
- CASE GraphDriver OF
- CGA, MCGA, ATT400: (* zwei-Farben / Colorkarten *)
- BEGIN
- FrameColor := White; (* Rahmenfarbe *)
- BarColor := Black; (* Balkenfarbe *)
- BackColor := Black; (* Logo-Hintergrund *)
- BarStyle := CloseDotFill; (* Balken-Muster *)
- txColor := White; (* Textfarbe *)
- ShadeColor := Black; (* Schattenfarbe *)
- BkStyle := SolidFill; (* Hgr.-Füllmuster *)
- END;
- EGAMono, HercMono, PC3270: (* zwei Farben / Monochrom *)
- BEGIN
- FrameColor := Blue; (* Rahmenfarbe *)
- BarColor := LightGray; (* Balkenfarbe *)
- BackColor := Black; (* Logo-Hintergrund *)
- BarStyle := CloseDotFill; (* Balken-Muster *)
- txColor := White; (* Textfarbe *)
- ShadeColor := Black; (* Schattenfarbe *)
- BkStyle := SolidFill; (* Hgr.-Füllmuster *)
- END
- ELSE (* EGA, EGA64, VGA *) (* 16 Farben *)
- SetPalette(Green, 127); (* grün <<-->> weiß *)
- FrameColor := LightBlue; (* Rahmenfarbe *)
- SetPalette(FrameColor, 63); (* hellblau -> weiß *)
- BarColor := LightRed; (* Balkenfarbe *)
- BackColor := Blue; (* Logo-Hintergrund *)
- BarStyle := SolidFill; (* Balken-Muster *)
- ShadeColor := Black; (* Schattenfarbe *)
- txColor := White; (* Schriftfarbe *)
- BkStyle := SolidFill; (* Hgr.-Füllmuster *)
- END;
-
- SetBkColor(Black); (* BS-Hintergrundfarbe schwarz *)
- ClearDevice; (* Bildschirm löschen *)
-
- SetLineStyle(SolidLn, $3C, ThickWidth);
- SetFillStyle(BkStyle, BackColor);
- Bar(101, 91, 289, 149); (* Logo-Hintergrund *)
-
- SetColor(FrameColor); (* Rahmenfarbe setzen *)
- Rectangle(102, 92, 288, 148); (* Rahmen um Bild ziehen *)
-
- SetFillStyle(BarStyle, BarColor); (* Balken-Design *)
- Bar(103, 115, 287, 131); (* Logo-Balken zeichnen *)
-
- SetTextStyle(TriplexFont, HorizDir, 5);
- SetColor(ShadeColor); (* Schattenfarbe *)
- OutTextXY(120, 90, txName); (* Schriftzug 'toolbox' *)
- OutTextXY(121, 90, txName); (* Schatten ... *)
- OutTextXY(120, 91, txName); (* vierfach dick *)
- OutTextXY(121, 91, txName);
-
- SetColor(txColor);
- OutTextXY(116, 92, txName); (* Vordergrundschrift *)
- OutTextXY(116, 91, txName); (* ... vierfach dick *)
- OutTextXY(117, 92, txName);
- OutTextXY(117, 91, txName);
-
- SetTextStyle(SmallFont, HorizDir, 2); (* Kleinschrift *)
- SetLineStyle(SolidLn, $3C, NormWidth); (* Linentyp *)
- OutTextXY(136, 136, STitle); (* Unterzeile *)
- Line(136, 145, 260, 145); (* ... unterstreichen *)
-
- PicSize := ImageSize(100, 90, 290, 150);(* Bitmapgröße *)
- GetMem(p1, PicSize); (* Speicher anfordern *)
- GetImage(100, 90, 290, 150, p1^); (* 1.BMP sichern *)
- SetFillStyle(SolidFill, GetBkColor); (* Bild ... *)
- Bar(100, 90, 290, 150); (* schwärzen ... *)
- GetMem(p2, PicSize); (* und 2. Bitmap *)
- GetImage(100, 90, 290, 150, p2^); (* abspeichern *)
- {$IFDEF SaveBMP}
- Assign(f, 'TXLOGO.PIC'); (* die beiden *)
- Rewrite(f, 1); (* Bilder für *)
- BlockWrite(f, p1^, PicSize); (* Wiederverwen- *)
- Close(f); (* dung in Da- *)
- Assign(f, 'EMPTY.PIC'); (* teien spei- *)
- Rewrite(f, 1); (* chern *)
- BlockWrite(f, p2^, PicSize);
- Close(f);
- {$ENDIF}
-
- SetTextStyle(SmallFont, HorizDir, 4); (* Infotext ... *)
- SetTextJustify(CenterText, CenterText);(* formatieren...*)
- SetColor(txColor); (*... und zeigen *)
- OutTextXY(GetMaxX DIV 2, GetMaxY - 10, ExitMsg);
-
- DisplayLogo; (* Logo anzeigen *)
- END;
-
- FUNCTION HexW(w : WORD) : STRING;
- CONST
- h : ARRAY [0..15] OF CHAR = '0123456789ABCDEF';
- BEGIN
- HexW[0] := #4;
- HexW[1] := h[Hi(w) SHR 4];
- HexW[2] := h[Hi(w) AND $F];
- HexW[3] := h[Lo(w) SHR 4];
- HexW[4] := h[Lo(w) AND $F];
- END;
-
- TYPE
- tOut_String = STRING[16];
- CONST
- Cmd_String: ARRAY [_RemDir.._ExtendOpen] OF tOut_String =
- ('01h RemDir :', '03h MakeDir :',
- '05h ChangeDir :', '06h CloseFile :',
- '07h CommitFile :', '08h ReadFile :',
- '09h WriteFile :', '0Ch GetSpace :',
- '0Eh SetAttr :', '0Fh GetAttr :',
- '11h Rename :', '13h Delete :',
- '16h Open :', '17h Create :',
- '1Bh FindFirst :', '1Ch FindNext :',
- '21h SeekEnd :', '22h Close all :',
- '2Eh ExtendOpen :');
-
- PROCEDURE MyExitProc;
- (* Exitprozedur, die bei »Halt()« in den Textmodus (falls *)
- (* notwendig) schaltet und die Meldung ausgibt. Sie wech- *)
- (* selt außerdem ins Ursprungsverzeichnis zurück. *)
- BEGIN
- IF grResult = grOk THEN CloseGraph;
- ClrScr;
- WriteLn(NoContact);
- ChDir(CurDir);
- ExitProc := OldExitProc; (* weiter hangeln ... *)
- END;
-
- PROCEDURE ProtocolCommand;
- (* ProtocolCommand dient zur Ausgabe eines Protokolls für *)
- (* Debuggingzwecke. Es gibt die Kommandonummer, den *)
- (* Befehl und den Dateinamen aus. *)
- VAR
- Buf : ASCIIZ;
- BEGIN
- Write(Cmd_String[Head.Command]);
- Write(' ', HexW(Head.Current_PSP), ' ');
- IF ((Head.Command >= _Close) AND (Head.Command <= _Write))
- OR (Head.Command=_SeekEnd) THEN
- WriteLn(StrLCopy(Buf, Head.SFT.FCB_fn, 11), ' ',
- HexW(Head.Param1), 'h')
- ELSE
- IF Head.Command = _FindNext THEN
- WriteLn(Head.SDB.Srch_Attr, ' ',
- StrLCopy(Buf, Head.SDB.Srch_Tmpl, 11))
- ELSE
- WriteLn(Head.fn1, ' ', HexW(Head.Param0), 'h');
- END;
-
- FUNCTION ProcessFN1 : BOOLEAN;
- (* ProcessFN1 trennt den Pfad in zwei Teile: den File- *)
- (* namen und das Verzeichnis. Wenn das Verzeichnis nicht *)
- (* vorhanden ist, weil der Laufwerksname fehlt, setzt *)
- (* ProcessFN1 die Variable nodrive. Die Prozeduren müssen *)
- (* dann entsprechend reagieren. *)
- VAR
- Len : BYTE;
- BEGIN
- Len := StrLen(Head.fn1); (* Dateinamen abtrennen *)
- REPEAT
- Dec(Len)
- UNTIL (Len < id_max) OR (Head.fn1[Len] = '\');
- (* kein '\' gefunden ... --> unglaublicher Fehler! *)
- IF (Head.fn1[Len] <> '\') THEN BEGIN
- NoDrive := TRUE;
- ProcessFN1 := FALSE;
- Exit;
- END;
- ProcessFN1 := TRUE;
- (* Dateinamen abspeichern *)
- FileName := StrPas(@Head.fn1[Len + 1]);
- IF (Len < id_max) THEN BEGIN
- (* kein Laufwerk ausgewählt *)
- NoDrive := TRUE;
- IF FileName[1] = '?' THEN Path := ''
- ELSE BEGIN
- Path := FileName[1] + ':\';
- FileName := '';
- END;
- END ELSE BEGIN
- NoDrive := FALSE;
- Head.fn1[Len + 1] := #0;
- Path := StrPas(@Head.fn1[id_max - 1]);
- Path[1] := Path[2];
- Path[2] := ':';
- END;
- END;
-
- FUNCTION ProcessFN2 : STRING;
- (* ProcessFN2 macht aus dem Pfad den korrekten DOS-Pfad...*)
- VAR
- Len : BYTE;
- BEGIN
- Len := StrLen(fn2); (* Dateinamen ermitteln *)
- REPEAT
- Dec(Len)
- UNTIL (Len < id_max) OR (fn2[Len] = '\');
- (* kein '\' gefunden ... --> unglaublicher Fehler! *)
- IF (fn2[Len] <> '\') THEN BEGIN
- NoDrive := TRUE;
- Exit;
- END;
- IF (Len < id_max) THEN BEGIN (* kein Laufwerk ausgewählt*)
- NoDrive := TRUE;
- ProcessFN2 := '';
- END ELSE BEGIN
- ProcessFN2 := StrPas(@fn2[id_max - 1]);
- ProcessFN2[1] := fn2[id_max];
- ProcessFN2[2] := ':';
- END;
- END;
-
- PROCEDURE NameToFCB(VAR st : STRING; VAR FCB : FCBArray);
- VAR
- h, e : INTEGER;
- BEGIN
- FillChar(FCB, SizeOf(FCB), ' ');
- IF (st = '.') OR (st = '..') THEN BEGIN
- FCB[0] := '.';
- IF Length(st) = 2 THEN FCB[1] := '.';
- Exit;
- END;
- h := Pos('.', st) - 1;
- IF h= -1 THEN h := Length(st);
- e := Length(st) - h - 1;
- IF e > 3 THEN e := 3;
- IF (e >= 0) THEN Move(st[h + 2], FCB[8], e);
- IF h > 8 THEN h := 8;
- IF h > 0 THEN Move(st[1], FCB, h);
- END;
-
- FUNCTION MakeCanonical(VAR pc1, pc2) : BOOLEAN; ASSEMBLER;
- (* MakeCanonical wandelt den ersten Dateinamen in einen *)
- (* absoluten Dateinamen um. *)
- ASM
- PUSH DS
- MOV AH, 60H
- LDS SI, pc1
- LES DI, pc2
- INT 21H
- POP DS
- MOV AL, 1
- JNC @Ok
- SUB AL, AL
- @Ok:
- END;
-
- (* ServerCall ruft Int21h Routinen über die Funktion *)
- (* $5D00 auf. Diese erlaubt das Setzen von Wildcards für *)
- (* Delete und Rename *)
- PROCEDURE ServerCall(VAR r : Registers);
-
- TYPE
- tDPL = RECORD
- AX, BX, CX, DX, SI, DI, DS, ES : WORD;
- Reserved, computer_id, Process_ID : WORD;
- END;
-
- VAR
- dpl : tDPL;
- pt : ^tDPL;
-
- BEGIN
- pt := @dpl;
- dpl.AX := r.AX;
- dpl.BX := r.BX;
- dpl.CX := r.CX;
- dpl.DX := r.DX;
- dpl.SI := r.SI;
- dpl.DI := r.DI;
- dpl.DS := r.DS;
- dpl.ES := r.ES;
- dpl.Reserved := 0;
- dpl.computer_id := 0;
- dpl.Process_ID := 0;
- ASM
- MOV AX, 5D00H
- PUSH DS
- LDS DI, pt
- MOV DX, DI
- INT 21H
- PUSH DS
- PUSH SI
- PUSHF
- LDS SI, r
- POP Registers([SI]).&Flags
- MOV Registers([SI]).&AX, AX
- MOV Registers([SI]).&BX, BX
- MOV Registers([SI]).&CX, CX
- MOV Registers([SI]).&DX, DX
- POP AX
- MOV Registers([SI]).&si, AX
- MOV Registers([SI]).&DI, DI
- POP AX
- MOV Registers([SI]).&DS, AX
- MOV AX, ES
- MOV Registers([SI]).&ES, AX
- POP DS
- END;
- END;
-
- FUNCTION Multi_Rename(st1, st2 : STRING) : WORD;
- VAR
- p1, p2, a1, a2 : ARRAY [0..127] OF CHAR;
- r : Registers;
- BEGIN
- StrPCopy(p1, st1);
- StrPCopy(p2, st2);
- MakeCanonical(p1, a1);
- MakeCanonical(p2, a2);
- r.AX := $5600;
- r.DS := Seg(a1);
- r.DX := Ofs(a1);
- r.ES := Seg(a2);
- r.DI := Ofs(a2);
- r.BX := 0;
- r.CX := 0;
- r.SI := 0;
- ServerCall(r);
- IF (r.Flags AND FCarry = 0) OR (r.AX = $12) THEN
- Multi_Rename := 0
- ELSE
- Multi_Rename := r.AX;
- END;
-
- FUNCTION Multi_Delete(st1 : STRING; Mask : BYTE) : WORD;
- VAR
- p1, a1 : ARRAY [0..127] OF CHAR;
- r : Registers;
- BEGIN
- StrPCopy(p1, st1);
- MakeCanonical(p1, a1);
- r.AX := $4100;
- r.DS := Seg(a1);
- r.DX := Ofs(a1);
- r.ES := 0;
- r.DI := 0;
- r.BX := 0;
- r.CX := Mask;
- r.si := 0;
- ServerCall(r);
- IF (r.Flags AND FCarry = 0) THEN Multi_Delete := 0
- ELSE Multi_Delete := r.AX;
- END;
-
- PROCEDURE RemakePath;
- (* RemakePath konstruiert aus dem echten Pfad und Datei- *)
- (* namen wieder den für das Netzlaufwerk gewünschten *)
- (* Namen. *)
-
- BEGIN
- StrCopy(NetPath, id_Drv); (* ID des Netzlaufwerks *)
- IF NoDrive THEN BEGIN
- NetPath[id_max] := FileName[1];
- NetPath[id_max + 1] := #0;
- END ELSE BEGIN
- NetPath[id_max] := Path[1];
- (* Pfad anhängen *)
- Move(Path[3], NetPath[id_max + 1], Length(Path) - 2);
- (* Filename anhängen *)
- Move(FileName[1], NetPath[id_max + Length(Path) - 1],
- Length(FileName));
- NetPath[id_max + Length(Path) +
- Length(FileName) - 1] := #0;
- END;
- END;
-
- PROCEDURE SendReply(Size : WORD);
- VAR
- ans : Ans_RemDir ABSOLUTE Buf;
- i : INTEGER;
- BEGIN
- i := IOResult;
- IF i = 103 THEN i := 2;
- IF i <> 0 THEN
- ans.Flags := ans.Flags OR FCarry (* Carry setzen *)
- ELSE
- ans.Flags := ans.Flags AND NOT FCarry;(* Carry löschen*)
- ans.AX := i; (* Fehlercode *)
- IF DoProtocol THEN
- WriteLn('--> ', HexW(ans.Flags), ' ', HexW(ans.AX));
- SendCRCBuf(ans, Size);
- END;
-
- PROCEDURE Fail(Size : WORD);
- VAR
- a : Ans_RemDir ABSOLUTE Buf;
- BEGIN
- a.Flags := a.Flags OR FCarry;
- a.AX := 5;
- IF DoProtocol THEN
- WriteLn('--> ', HexW(a.Flags), ' ', HexW(a.AX));
- SendCRCBuf(a, Size);
- END;
-
- PROCEDURE P_RemDir;
- (* Remove Directory - Subfunktion 01h *)
- VAR
- ans : Ans_RemDir ABSOLUTE Buf;
- b : BOOLEAN;
- io : WORD;
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- ProcessFN1; (* Pfad ermitteln *)
- IF NoDrive THEN BEGIN
- Fail(SizeOf(ans)); (* Pseudopfad... *)
- Exit;
- END;
- ChDir(Copy(Path, 1, 3));
- RmDir(Path + FileName); (* Verzeichnis löschen *)
- SendReply(SizeOf(ans));
- END;
-
- PROCEDURE P_MakeDir;
- (* Make Directory - Subfunktion 03h *)
- VAR
- ans : ans_MakeDir ABSOLUTE Buf;
- b : BOOLEAN;
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- ProcessFN1; (* Pfad ermitteln *)
- IF NoDrive THEN BEGIN
- Fail(SizeOf(ans)); (* Pseudopfad... *)
- Exit;
- END;
- MkDir(Path + FileName); (* Verzeichnis erzeugen *)
- SendReply(SizeOf(ans));
- END;
-
- PROCEDURE P_ChDir;
- (* Change Directory - Subfunktion 05h *)
- VAR
- ans : ans_ChDir ABSOLUTE Buf;
- b : BOOLEAN;
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- IF StrComp(Head.fn1, id_Drv) <> 0 THEN BEGIN
- ProcessFN1; (* Pfad ermitteln *)
- ChDir(Path + FileName); (* Verzeichnis erzeugen *)
- RemakePath; (* neuer Pfad *)
- IF InOutRes <> 0 THEN
- StrCopy(ans.curr_path, NetPath);
- END ELSE
- StrCopy(ans.curr_path, Head.fn1);
- SendReply(SizeOf(ans));
- END;
-
- PROCEDURE P_Close;
- (* Close File - Subfunktion 06h *)
- VAR
- ans : ans_Close ABSOLUTE Buf;
- l : LongInt;
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- Dec(Head.SFT.Handle_Cnt);
- (* DOS scheint es nicht zu machen *)
- FileNr := os(Head.SFT.DevDrv_Ptr).o;
- (* für Redirector frei... *)
- os(l).o := Head.SFT.F_Time; (* File updaten ... *)
- os(l).s := Head.SFT.F_Date;
- SetFTime(f[FileNr], l);
- Close(f[FileNr]); (* ... und schließen *)
- SetFAttr(f[FileNr], Head.SFT.Attr_Byte);
- ans.SFT := Head.SFT; (* Felder zurückgeben *)
- SendReply(SizeOf(ans));
- Free[FileNr] := TRUE;
- END;
-
-
- PROCEDURE P_Commit;
- (* Commit File - Subfunktion 07h *)
- BEGIN
- (* Dummy-Funktion, alle Buffer werden ohnehin geflusht *)
- END;
-
- PROCEDURE P_Read;
- (* Read from File - Subfunktion 08h *)
- VAR
- ans : Ans_Read ABSOLUTE Buf;
- sp : Sft_Ptr;
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- FileNr := os(Head.SFT.DevDrv_Ptr).o;
- (* --> für Redirector frei *)
- Seek(f[FileNr], Head.SFT.F_Pos); (* Adresse suchen ... *)
- BlockRead(f[FileNr], DataBuf^, Head.Param1, ans.Size);
- (* Daten lesen *)
- ans.SFT := Head.SFT;
- ans.SFT.F_Pos := ans.SFT.F_Pos + ans.Size;
- SendReply(SizeOf(ans)); (* Status und Größe übertragen *)
- IF ((ans.Flags AND FCarry) = 0) AND (ans.Size > 0) THEN
- SendCRCBuf(DataBuf^, ans.Size);
- END;
-
- PROCEDURE P_Write;
- (* Write to File - Subfunktion 09h *)
- VAR
- ans : Ans_Write ABSOLUTE Buf;
- sp : Sft_Ptr;
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- IF Head.Param1 > 0 THEN
- ReceiveCRCBuf(DataBuf^, Head.Param1);
- FileNr := os(Head.SFT.DevDrv_Ptr).o;
- (* für Redirector frei *)
- Seek(f[FileNr], Head.SFT.F_Pos); (* Adresse suchen ... *)
- BlockWrite(f[FileNr], DataBuf^, Head.Param1, ans.Size);
- ans.SFT := Head.SFT;
- ans.SFT.F_Pos := ans.SFT.F_Pos + ans.Size;
- ans.SFT.F_Size := FileSize(f[FileNr]);
- ans.SFT.Dev_Info := ans.SFT.Dev_Info AND NOT $40;
- SendReply(SizeOf(ans));
- END;
-
- PROCEDURE P_GetSpace;
- (* Get Disk Space - Subfunktion 0Ch *)
- VAR
- ans : Ans_GetSpace ABSOLUTE Buf;
- BEGIN
- IF StrComp(Head.fn1, id_Drv) = 0 THEN
- Path[1] := 'C'
- ELSE
- ProcessFN1;
- ASM
- MOV AH, 36H
- MOV DL, Byte(Path[1])
- SUB DL, Byte('@')
- INT 21H
- MOV ans.spc, AX
- MOV ans.totc, DX
- MOV ans.bps, CX
- MOV ans.freec, BX
- END;
- IF DoProtocol THEN WriteLn;
- SendCRCBuf(ans, SizeOf(ans));
- END;
-
- PROCEDURE P_SetAttr;
- (* Set File Attributes - Subfunktion 0Eh *)
- VAR
- ans : Ans_SetAttr ABSOLUTE Buf;
- hp, lp : ARRAY [0..127] OF CHAR;
- lPtr : POINTER;
- BEGIN
- ProcessFN1;
- IF NoDrive THEN BEGIN
- Fail(SizeOf(ans)); (* Pseudopfad... *)
- Exit;
- END;
- StrPCopy(hp, Path);
- StrPCopy(StrECopy(lp, hp), FileName);
- lPtr := @lp;
- ASM
- PUSH DS
- MOV AX, $4301
- MOV CX, Head.Param0
- LDS si, lPtr
- MOV DX, SI
- INT 21H
- PUSHF
- MOV ans.&AX, AX
- POP AX
- MOV ans.Flags, AX
- POP DS
- END;
- IF DoProtocol THEN
- WriteLn('--> ', HexW(ans.Flags), ' ', HexW(ans.AX));
- SendCRCBuf(ans, SizeOf(ans));
- END;
-
- PROCEDURE P_GetAttr;
- (* Get File Attributes - Subfunktion 0Fh *)
- VAR
- ans : ans_GetAttr ABSOLUTE Buf;
- hp, lp : ARRAY [0..127] OF CHAR;
- lPtr : POINTER;
- f : File;
- long : LongInt;
- BEGIN
- ProcessFN1;
- IF NoDrive THEN BEGIN
- Fail(SizeOf(ans)); (* Pseudopfad... *)
- Exit;
- END;
- StrPCopy(hp, Path);
- StrPCopy(StrECopy(lp, hp), FileName);
- lPtr := @lp;
- ASM
- PUSH DS
- MOV AX, $4300
- LDS SI, lPtr
- MOV DX, SI
- INT 21H
- POP DS
- PUSHF
- POP ans.Flags
- MOV ans.&AX, AX
- JC @weiter
- MOV ans.&AX, CX
- @weiter:
- END;
- IF (ans.Flags AND FCarry = 0) THEN BEGIN
- Assign(f, Path + FileName);
- Reset(f, 1);
- long := FileSize(f);
- ans.BX := os(long).s;
- ans.DI := os(long).o;
- Close(f);
- ans.AX := IOResult;
- IF ans.AX <> 0 THEN ans.Flags := FCarry
- ELSE ans.Flags:= 0;
- END;
- IF DoProtocol THEN
- WriteLn('--> ', HexW(ans.Flags), ' ', HexW(ans.AX));
- SendCRCBuf(ans, SizeOf(ans));
- END;
-
- PROCEDURE P_Rename;
- (* Rename File - Subfunktion 11h *)
- VAR
- ans : Ans_Rename ABSOLUTE Buf;
- f2 : STRING;
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- ProcessFN1;
- ReceiveCRCBuf(fn2, SizeOf(fn2));
- f2 := ProcessFN2;
- IF NoDrive THEN BEGIN
- Fail(SizeOf(ans)); (* Pseudopfad... *)
- Exit;
- END;
- ans.AX := Multi_Rename(Path + FileName, f2);
- IF ans.AX <> 0 THEN ans.Flags := FCarry;
- SendReply(SizeOf(ans));
- END;
-
-
- PROCEDURE P_Delete;
- (* Delete File - Subfunktion 13h *)
- VAR
- ans : Ans_Delete ABSOLUTE Buf;
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- ProcessFN1;
- IF NoDrive THEN BEGIN
- Fail(SizeOf(ans)); (* Pseudopfad... *)
- Exit;
- END;
- ans.AX := Multi_Delete(Path + FileName, $27) ;
- IF ans.AX <> 0 THEN ans.Flags := FCarry;
- SendReply(SizeOf(ans));
- END;
-
- PROCEDURE P_Open;
- (* Open Existing File - Subfunktion 16h *)
- VAR
- ans : Ans_Open ABSOLUTE Buf;
- fm, i : BYTE;
- Attr : WORD;
- long : LongInt;
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- ProcessFN1;
- i := 1;
- WHILE (i <= File_Max) AND NOT Free[i] DO Inc(i);
- IF (i > File_Max) THEN BEGIN
- ans.AX := 4;
- ans.Flags := FCarry;
- IF DoProtocol THEN
- WriteLn('--> ', HexW(ans.Flags), ' ', HexW(ans.AX));
- SendCRCBuf(ans, SizeOf(ans));
- Exit;
- END;
- IF NoDrive OR (i > File_Max) OR (FileName='') THEN BEGIN
- Fail(SizeOf(ans)); (* Pseudopfad... *)
- Exit;
- END;
- fm := FileMode;
- FileMode := Lo(Head.Param0);
- Attr := Hi(Head.Param0);
- Assign(f[i], Path + FileName);
- Reset(f[i], 1);
- IF InOutRes = 0 THEN BEGIN
- Free[i] := FALSE;
- f_PSP[i] := Head.Current_PSP;
- END;
- GetFTime(f[i], long);
- FileMode := fm;
- (* SFT updaten *)
- ans.SFT.F_Size := FileSize(f[i]);
- ans.SFT.F_Date := os(long).s;
- ans.SFT.F_Time := os(long).o;
- NameToFCB(FileName, ans.SFT.FCB_fn);
- ans.SFT.Attr_Byte := Attr AND Anyfile;
- ans.SFT.Open_Mode := Lo(Head.Param0) AND $7F;
- ans.SFT.Dir_Sector := 0;
- ans.SFT.Dir_EntryNo := 0;
- ans.SFT.DevDrv_Ptr := NIL;
- ans.SFT.F_Pos := 0;
- (* eigene Nummer abspeichern *)
- os(ans.SFT.DevDrv_Ptr).o := i;
- SendReply(SizeOf(ans));
- END;
-
- PROCEDURE P_Create;
- (* Truncate/Create File - Subfunktion 17h *)
- VAR
- ans : Ans_Create ABSOLUTE Buf;
- i : BYTE;
- Attr : WORD;
- long : LongInt;
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- ProcessFN1;
- i := 1;
- WHILE (i <= File_Max) AND NOT Free[i] DO Inc(i);
- IF (i > File_Max) THEN BEGIN
- ans.AX := 4;
- ans.Flags := FCarry;
- IF DoProtocol THEN
- WriteLn('--> ', HexW(ans.Flags), ' ', HexW(ans.AX));
- SendCRCBuf(ans, SizeOf(ans));
- Exit;
- END;
- IF NoDrive OR (FileName = '') THEN BEGIN
- Fail(SizeOf(ans)); (* Pseudopfad... *)
- Exit;
- END;
- Assign(f[i], Path + FileName);
- Rewrite(f[i], 1);
- IF InOutRes = 0 THEN BEGIN
- Free[i] := FALSE;
- f_PSP[i] := Head.Current_PSP;
- END;
- Attr := Lo(Head.Param0);
- GetFTime(f[i], long);
- (* SFT updaten *)
- ans.SFT.F_Size := FileSize(f[i]);
- ans.SFT.F_Date := os(long).s;
- ans.SFT.F_Time := os(long).o;
- NameToFCB(FileName, ans.SFT.FCB_fn);
- ans.SFT.Attr_Byte := Attr;
- ans.SFT.Open_Mode := FileMode;
- ans.SFT.Dir_Sector := 0;
- ans.SFT.Dir_EntryNo := 0;
- ans.SFT.DevDrv_Ptr := NIL;
- ans.SFT.F_Pos := 0;
- os(ans.SFT.DevDrv_Ptr).o := i;
- SendReply(SizeOf(ans));
- END;
-
- PROCEDURE P_FindFirst;
- (* FindFirst - Subfunktion 1Bh *)
- VAR
- ans : Ans_FindFirst ABSOLUTE Buf;
-
- FUNCTION Found(ch : CHAR) : BOOLEAN;
- VAR
- i : BYTE;
- BEGIN
- i := 1;
- Found := TRUE;
- WHILE LwTbl[i] <> #0 DO BEGIN
- IF UpCase(ch) = UpCase(LwTbl[i]) THEN Exit;
- Inc(i);
- END;
- Found := FALSE;
- END;
-
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- ProcessFN1;
- IF NoDrive THEN BEGIN (* Verzeichnis simulieren *)
- IF Lo(Head.Param0) = $08 THEN BEGIN
- NameToFCB(FileName, ans.SDB.Srch_Tmpl);
- StrPCopy(ans.DIB.FName, 'toolbox olé');
- ans.DIB.FAttr := VolumeID;
- ans.SDB.Par_ClStr := 0;
- END ELSE BEGIN
- FillChar(ans.DIB.FName[1], 10, ' ');
- IF Head.fn1[id_max] = '?' THEN BEGIN
- ans.DIB.FName[0] := LwTbl[1];
- ans.DIB.FAttr := Directory;
- ans.SDB.Par_ClStr := 1;
- ans.AX := 0;
- ans.Flags := 0;
- END ELSE BEGIN
- IF (Head.fn1[id_max+1] = #0) AND
- Found(Head.fn1[id_max]) THEN BEGIN
- ans.DIB.FName[0] := Head.fn1[id_max];
- ans.DIB.FAttr := Directory;
- ans.SDB.Par_ClStr := 26;
- ans.AX := 0;
- ans.Flags := 0;
- END ELSE BEGIN
- ans.DIB.FName[0] := Head.fn1[id_max];
- ans.DIB.FAttr := Directory;
- ans.SDB.Par_ClStr := 26;
- ans.AX := 18;
- ans.Flags := FCarry;
- END;
- END;
- END;
- ans.SDB.Srch_Attr := Lo(Head.Param0);
- ans.SDB.Dir_Entry := 0;
- ans.DIB.Time_LStupd := 0;
- ans.DIB.Date_LStupd := 0;
- ans.DIB.FSiz := 0;
- ans.SDB.f1[1] := 255;
- SendCRCBuf(ans, SizeOf(ans));
- Exit;
- END;
- FindFirst(Path + FileName, Head.Param0, t);
- InOutRes := DosError;
- Move(t.Fill, ans.SDB, 21); (* SDB und DIR_REC updaten *)
- ans.SDB.f1[1] := ans.SDB.Drv_Lett;
- NameToFCB(t.Name, ans.DIB.FName);
- ans.DIB.FAttr := t.Attr AND Anyfile;
- ans.DIB.Time_LStupd := os(t.Time).o;
- ans.DIB.Date_LStupd := os(t.Time).s;
- ans.DIB.FSiz := t.Size;
- ans.SDB.Drv_Lett := ans.SDB.Drv_Lett OR $80;
- SendReply(SizeOf(ans));
- END;
-
- PROCEDURE P_FindNext;
- (* FindNext - Subfunktion 1Ch *)
- VAR
- ans : Ans_FindNext ABSOLUTE Buf;
- pc : WORD;
- BEGIN
- IF Head.SDB.f1[1] = 255 THEN BEGIN
- pc := Head.SDB.Par_ClStr + 1;
- ans.SDB.Par_ClStr := pc;
- ans.SDB.f1[1] := 255;
- FillChar(ans.DIB.FName[1], 10, ' ');
- ans.DIB.FName[0] := LwTbl[pc];
- ans.DIB.FAttr := Directory OR ReadOnly;
- ans.DIB.Time_LStupd := 0; (* wow, welch Werte *)
- ans.DIB.Date_LStupd := 0;
- ans.DIB.FSiz := 0;
- IF LwTbl[pc] = #0 THEN BEGIN
- ans.AX := 18;
- ans.Flags := FCarry;
- END ELSE BEGIN
- ans.AX := 0;
- ans.Flags := 0;
- END;
- IF DoProtocol THEN
- WriteLn('--> ', HexW(ans.Flags), ' ', HexW(ans.AX));
- SendCRCBuf(ans, SizeOf(ans));
- Exit;
- END;
- Head.SDB.Drv_Lett := Head.SDB.f1[1];
- Move(Head.SDB, t.Fill, 21);
- FindNext(t);
- InOutRes := DosError;
- Move(t.Fill, ans.SDB, 21); (* SDB und DIR_REC updaten *)
- ans.SDB.f1[1] := ans.SDB.Drv_Lett;
- NameToFCB(t.Name, ans.DIB.FName);
- ans.DIB.FAttr := t.Attr;
- ans.DIB.Time_LStupd := os(t.Time).o;
- ans.DIB.Date_LStupd := os(t.Time).s;
- ans.DIB.FSiz := t.Size;
- SendReply(SizeOf(ans));
- END;
-
- PROCEDURE P_SeekEnd;
- (* Seek From End Of File - Subfunktion 21h *)
- BEGIN
- (* Dummy *)
- END;
-
- PROCEDURE P_Hook;
- (* Process termination hook - Subfunktion 22h *)
- VAR
- i : BYTE;
- BEGIN
- FOR i := 0 TO File_Max DO BEGIN
- IF (NOT Free[i]) AND
- (f_PSP[i] = Head.Current_PSP) THEN BEGIN
- Close(f[i]);
- Free[i] := TRUE;
- END;
- END;
- IF DoProtocol THEN WriteLn;
- END;
-
- PROCEDURE P_ExtendOpen;
- (* Special Multi-Purpose Open File - Subfunktion 2Eh *)
- VAR
- ans : Ans_ExtendOpen ABSOLUTE Buf;
- SPop : tSpecPop;
- i, fm : BYTE;
- Attr : WORD;
- long : LongInt;
- BEGIN
- IF grResult = grOk THEN DisplayLogo;
- ReceiveCRCBuf(SPop, SizeOf(tSpecPop));
- ProcessFN1;
- i := 1;
- WHILE (i <= File_Max) AND NOT Free[i] DO
- Inc(i);
- IF (i > File_Max) THEN BEGIN
- ans.AX := 4;
- ans.Flags := FCarry;
- IF DoProtocol THEN
- WriteLn('--> ', HexW(ans.Flags), ' ', HexW(ans.AX));
- SendCRCBuf(ans, SizeOf(ans));
- Exit;
- END;
- IF NoDrive OR (FileName = '') THEN BEGIN
- Fail(SizeOf(ans)); (* Pseudopfad... *)
- Exit;
- END;
- Assign(f[i], Path + FileName);
- GetFAttr(f[i], Attr);
- IF (DosError = 0) AND (Attr AND $10 <> 0) THEN
- DosError := 5;
- IF ((SPop.SPop_Act AND $F = 0) AND (DosError = 0)) OR
- ((SPop.SPop_Act AND $F0 = 0) AND (DosError <> 0)) THEN
- BEGIN
- (* von Aktionscode so gewünscht *)
- Fail(SizeOf(ans));
- Exit;
- END;
- fm := FileMode;
- FileMode := SPop.SPop_Mode;
- IF (SPop.SPop_Act = 2) OR (DosError <> 0) THEN BEGIN
- (* neuen Dateieintrag erzeugen *)
- IF DosError = 0 THEN ans.CX := 3 ELSE ans.CX := 2;
- Rewrite(f[i], 1);
- Attr := SPop.SPop_Attr;
- END ELSE BEGIN
- Reset(f[i], 1);
- ans.CX := 1;
- END;
- IF InOutRes = 0 THEN BEGIN
- Free[i] := FALSE;
- f_PSP[i] := Head.Current_PSP;
- END;
- FileMode := fm;
- GetFTime(f[i], long);
- (* SFT updaten *)
- ans.SFT.F_Size := FileSize(f[i]);
- ans.SFT.F_Date := os(long).s;
- ans.SFT.F_Time := os(long).o;
- NameToFCB(FileName, ans.SFT.FCB_fn);
- ans.SFT.Attr_Byte := Attr;
- ans.SFT.Open_Mode := SPop.SPop_Mode;
- ans.SFT.Dir_Sector := 0;
- ans.SFT.Dir_EntryNo := 0;
- ans.SFT.DevDrv_Ptr := NIL;
- ans.SFT.F_Pos := 0;
- (* eigene Nummer abspeichern *)
- os(ans.SFT.DevDrv_Ptr).o := i;
- SendReply(SizeOf(ans));
- END;
-
- FUNCTION GetHex(VAR s : STRING; VAR Val : WORD) : WORD;
- VAR
- hw, w : WORD;
- i : BYTE;
- BEGIN
- IF Length(s) > 4 THEN BEGIN
- GetHex := 5;
- Exit;
- END;
- w := 0;
- FOR i := 1 TO Length(s) DO BEGIN
- hw := 0;
- s[i] := UpCase(s[i]);
- IF (s[i] >= '0') AND (s[i] <= '9') THEN
- hw := Ord(s[i]) - BYTE('0')
- ELSE IF (s[i] >= 'A') AND (s[i] <= 'F') THEN
- hw := Ord(s[i]) - BYTE('A') + 10
- ELSE BEGIN
- GetHex := i;
- Exit;
- END;
- w := w SHL 4 + hw;
- END;
- Val := w;
- GetHex := 0;
- END;
-
- TYPE
- tSubFunc = PROCEDURE;
- Proc_Tbl = ARRAY [_RemDir.._ExtendOpen] OF tSubFunc;
-
- CONST
- FuncTbl : Proc_Tbl =
- (P_RemDir, P_MakeDir, P_ChDir, P_Close,
- P_Commit, P_Read, P_Write, P_GetSpace,
- P_SetAttr, P_GetAttr, P_Rename, P_Delete,
- P_Open, P_Create, P_FindFirst, P_FindNext,
- P_SeekEnd, P_Hook, P_ExtendOpen);
-
- PROCEDURE ReDirector;
- BEGIN
- REPEAT
- ReceiveCRCBuf(Head, SizeOf(Head));
- IF Head.Command = _KillContact THEN Exit;
- IF LastResult <> ReadyToTransfer THEN Exit;
- IF DoProtocol THEN ProtocolCommand;
- FuncTbl[Head.Command];
- UNTIL (LastResult <> ReadyToTransfer);
- END;
-
- PROCEDURE InfoText;
- BEGIN
- WriteLn('Aufruf: REMBASE [Laufwerke] [LptNr] oder '^M^J,
- ' REMBASE [Laufwerke] $[LPT-Adresse]');
- WriteLn('Beispiele: »REMBASE ac 1« oder »REMBASE acde ',
- '$378«'^J);
- Halt(1);
- END;
-
- PROCEDURE DisplayText;
- CONST
- InfoMsg : STRING[40] =
- ' toolbox-Remote-Laufwerk ';
- CopyrMsg: STRING[40] =
- ' Copyright (c) R. Hensmann & DMV-Verlag ';
- VAR
- i : INTEGER;
- BEGIN
- ClrScr;
- FOR i := 1 TO 25 * 80 - 1 DO Write('*');
- GotoXY(40 - Length(InfoMsg) DIV 2, 13);
- Write(InfoMsg);
- GotoXY(40 - Length(CopyrMsg) DIV 2, 14);
- Write(CopyrMsg);
- GotoXY(80 - Length(ExitMsg), 25);
- Write(ExitMsg);
- END;
-
- BEGIN
- grResult := -1;
- CheckBreak := FALSE;
- (* Grafiktreiber und Fonts anmelden: *)
- RegisterBGIFont(@SmallFontProc);
- RegisterBGIFont(@TriplexFontProc);
- RegisterBGIDriver(@HercDriverProc);
- RegisterBGIDriver(@EGAVGADriverProc);
- RegisterBGIDriver(@CGADriverProc);
- RegisterBGIDriver(@ATT400DriverProc);
- RegisterBGIDriver(@PC3270DriverProc);
-
- (* aktuelles Laufwerk, um anschließend wieder hierher *)
- (* zu wechseln: *)
- GetDir(0, CurDir);
- IF ParamCount = 0 THEN BEGIN
- WriteLn('Remote-Drive Basis v1.1'^M^J +
- 'Copyright (C) 1993 R. Hensmann & DMV'^M^J +
- 'Starten Sie dieses Programm auf dem Rechner');
- WriteLn('den sie als Laufwerk einsetzen wollen.'^J);
- Write('Alle Laufwerke, die verwendet werden sollen: ' +
- '(z. B. ac) ');
- ReadLn(lw);
- Write('Adresse der Schnittstelle (1, 2, 3 oder in Hex ',
- '(z. B. $378) : ');
- ReadLn(st);
- Delay(500);
- END ELSE IF ParamCount = 2 THEN BEGIN
- lw := ParamStr(1);
- st := ParamStr(2);
- END ELSE InfoText;
- IF st[1] = '$' THEN BEGIN
- Delete(st, 1, 1);
- Error := GetHex(st, nr)
- END ELSE
- Val(st, nr, Error);
- IF Error <> 0 THEN
- InfoText
- ELSE IF nr <= 3 THEN
- nr := GetLPTAdress(nr);
- FillChar(LwTbl, SizeOf(LwTbl), #0);
- FOR i := 1 TO Length(lw) DO BEGIN
- lw[i] := UpCase(lw[i]);
- IF (lw[i] >= 'A') AND (lw[i] <= 'Z') THEN BEGIN
- j := 1;
- WHILE (LwTbl[j] <> lw[i]) AND (LwTbl[j] <> #0) DO
- Inc(j);
- IF LwTbl[j] = #0 THEN LwTbl[j] := lw[i];
- END;
- END;
- IF LwTbl[1] = #0 THEN BEGIN
- WriteLn('Nicht allzuviele Laufwerke...');
- Halt(1);
- END;
- OldExitProc := ExitProc;
- ExitProc := @MyExitProc;
- (* alle frei... *)
- FillChar(Free, SizeOf(Free), #1);
- New(DataBuf);
- New(DataBuf2);
- UnitInit(nr);
- WriteLn('Warten auf Hauptprogramm ... ' +
- '(Abbruch mit beliebiger Taste)');
- WHILE KeyPressed DO ch := ReadKey;
- SetKbdWatchdog; (* Abbruch mit beliebiger Taste möglich *)
- StartReceive;
- IF ParaResult <> ReadyToTransfer THEN BEGIN
- NoContact := '... abgebrochen'; (* String patchen *)
- Halt(1);
- END;
- (* Erst jetzt die Grafik initialisieren: *)
- DetectGraph(GraphDriver, GraphMode);
- InitGraph(GraphDriver, GraphMode, '');
- grResult := GraphResult;
- IF grResult = grOk THEN BuildLogo ELSE DisplayText;
- ReceiveCRCBuf(id_Drv, SizeOf(id_Drv));
- {$IFDEF NoKeyBreak} (* kein Abbruch mehr per Tastendruck *)
- ClrKbdWatchDog; (* möglich! Falls der Master-PC aus- *)
- {$ENDIF} (* geschaltet wird, muß der Slave-PC *)
- (* warmgestartet werden! *)
- ReDirector; (* Programm-Hauptschleife *)
- IF grResult = grOk THEN BEGIN (* es war Grafikmodus *)
- FreeMem(p1, PicSize); (* Speicher wieder frei- *)
- FreeMem(p2, PicSize); (* geben. *)
- END;
- (* die restliche Restaurierungen und Ausgaben werden in *)
- (* der Exit-Prozedur »MyExitProc« vorgenommen. *)
- END.
-
- (*========================================================*)
- (* Ende von REMBASE.PAS *)
-