home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1989 / 01 / extra / protect.asm next >
Encoding:
Assembly Source File  |  1988-09-22  |  23.3 KB  |  800 lines

  1. ;* ------------------------------------------------------- *
  2. ;*                    PROTECT.ASM                          *
  3. ;*                                                         *
  4. ;*            Utility zum Schutz vor Viren                 *
  5. ;*         (c) 1988 by Jörg Peter und TOOLBOX              *
  6. ;* ------------------------------------------------------- *
  7. ;*  Achtung, innerhalb des residenten Teils dürfen keine   *
  8. ;*  DOS-Funktionen benutzt werden. Da das Programm selbst  *
  9. ;*  DOS-Funktionen über den Interrupt 9 unterbricht,       *
  10. ;*  würde dies zu Stack-Kollisionen führen.                *
  11. ;*  Assemblieren mit: masm protect.asm                     *
  12. ;*  Linken mit      : link protect.obj                     *
  13. ;*             -->    protect.exe                          *
  14. ;* ------------------------------------------------------- *
  15.  
  16. keystroke      equ  1     ;Tastencode Programm (de)aktiviert
  17. seite          equ  0     ;Nummer der zu verwendenden
  18.                           ;Bildschirmseite
  19. max_intvektor  equ  29H*4 ;25H = letzter nicht berücksichtigter
  20.                           ;Int-Vektor
  21. max_lines      equ  10    ;Anzahl der Zeilen, die auf dem
  22.                           ;Bildschirm ausgegeben werden, bevor
  23.                           ;eine Warteabfrage gestellt wird
  24.  
  25. CODE SEGMENT PARA 'CODE'
  26.      assume cs:code, ds:code, es:code
  27.      org 100H
  28.      jmp hp
  29.  
  30. pointer   dw offset puffer  ;zeigt auf den noch verbleibenden
  31.                             ;Platz im Puffer "puffer"
  32. puffer    db 1000 dup (0)   ;dient zum Abspeichern der Namen
  33.                             ;der geöffneten Dateien
  34. puffer_ende:                ;Dient zum Erkennen des Pufferendes
  35.                             ;dadurch kann "puffer" ohne Pro-
  36.                             ;bleme in der Größe geändert werden
  37.  
  38. int_vektoren db max_intvektor dup (?)
  39.                   ;Feld dient zum Sichern der Interruptvektoren
  40.  
  41.  
  42. geladen      db 13,10,'** PROTECT geladen, Copyright (c) 1988 '
  43.              db 'by Jörg Peter **'
  44.              db 13,10,'   (De)Aktivieren über <Ctrl>+<Alt>+'
  45.              db '<Esc>',13,10,'$'
  46. aktivieren   db 13,'*** ACHTUNG !, PROTECT aktiviert ',13,'$'
  47. deaktivieren db 13,'*** PROTECT deaktiviert ! ***',13,13
  48.              db 'Schreibversuche    Diskette    $'
  49. da_2         db 13,'                   Festplatte  ','$'
  50. warnung      db 13,13,'Versuchter Zugriff auf Spur 0','$'
  51. dateinamen   db 13,13,'Folgende Dateien wurden geöffnet :'
  52. ausgabe_cr   db 13,'$'
  53. warten       db 13,'Weiter --> eine Taste betätigen ',13,'$'
  54. int_veraenderung db 13,'Diese Interrupt Vektoren wurden '
  55.              db 'verändert, Wiederherstellen (J/N) ? $'
  56.  
  57. int_13    dd   ?   ;Pointer auf die Interrupt 13H
  58.                    ;Handling Routine im BIOS
  59. int9      dd   ?   ;Pointer Interrupt 9 Routine im BIOS
  60. int21     dd   ?   ;Pointer auf die Interrupt 21H Routine
  61.  
  62. warning   db   0   ;Byte wird auf den Wert 255 gesetzt,
  63.                    ;falls ein Zugriff auf die
  64.                    ;Bootspur erfolgt
  65. attribut  db   ?   ;dient zum Sichern des festgestellten
  66.                    ;Ausgabeattributs
  67. on        db   0   ;=255 wenn Protect aktiv, =0 wenn nicht
  68. f_count   dw   0   ;Zähler für Floppy   Schreibzugriffe
  69. h_count   dw   0   ;Zähler für Harddisk Schreibzugriffe
  70.  
  71. page_count db 0    ;wichtig für die Prozedur Textausgabe,
  72.                    ;zählt wie viele Zeilen
  73.                    ;auf dem Bildschirm ausgegeben wurden
  74.  
  75. change_int db 0    ;wird auf 255 gesetzt, falls das Programm
  76.                    ;eine Veränderung eines oder mehrerer
  77.                    ;Interruptvektoren festellt
  78.  
  79. aktiv db 0         ;enthält den Wert 255, falls das residente
  80.                    ;Programm bereits über den Interrupt 9
  81.                    ;aktiviert wurde
  82.  
  83.  
  84. LESE_CURSOR_POSITION PROC NEAR
  85.                    ;Prozedur liest die aktuelle Cursorposition
  86.                    ;und gibt diesen Wert in DX zurück
  87.       push ax
  88.       push cx
  89.       mov ah,3
  90.       mov bh,seite
  91.       int 10H
  92.       pop cx
  93.       pop ax
  94.       ret
  95.  
  96. LESE_CURSOR_POSITION ENDP
  97.  
  98. WERT_AUSGEBEN PROC NEAR
  99.                    ;Prozedur gibt den Wert in AX an der
  100.                    ;aktuellen Cursorposition aus, der
  101.                    ;Cursor bleibt auf der letzten Ziffer
  102.                    ;der ausgegebenen Zahl stehen.
  103.                    ;Voranstehende Nullen werden unterdrückt
  104.                    ;Die Register AX,BX,CX werden verändert
  105.      push dx       ;AX an aktueller Cursorposition ausgeben
  106.      xor dx,dx
  107.      mov bx,10
  108.      div bx        ;AX durch 10 teilen, Ergebnis in AX,
  109.                    ;Restwert steht dann in DX
  110.      push dx       ;letzte Ziffer wird auf den Stack gelegt
  111.      cmp ax,0      ;Wenn Ausgangswert kleiner 10 war, ist AX
  112.                    ;jetzt null. Somit muß kein weiterer Wert
  113.                    ;ausgegeben werden
  114.      je wa_1
  115.      xor dx,dx
  116.      div bx        ;Vorletzte Ziffer errechnen ...
  117.      push dx       ;... und auf dem Stapel ablegen
  118.      cmp ax,0
  119.      je wa_2
  120.      xor dx,dx
  121.      div bx
  122.      push dx
  123.      cmp ax,0
  124.      je wa_3
  125.      xor dx,dx
  126.      div bx
  127.      push dx
  128.      call lese_cursor_position     ;erstes Zeichen ausgeben
  129.      mov cx,1
  130.      pop ax
  131.      mov ah,10
  132.      add al,'0'
  133.      int 10H
  134.      inc dl
  135.      mov ah,2
  136.      int 10H
  137.      ;zweites Zeichen
  138. wa_3:
  139.      call lese_cursor_position
  140.      pop ax
  141.      mov ah,10
  142.      add al,'0'
  143.      int 10H
  144.      inc dl
  145.      mov ah,2
  146.      int 10H
  147. wa_2:
  148.      call lese_cursor_position
  149.      ;drittes Zeichen
  150.      pop ax
  151.      mov ah,10
  152.      add al,'0'
  153.      int 10H
  154.      inc dl
  155.      mov ah,2
  156.      int 10H
  157. wa_1:
  158.      call lese_cursor_position
  159.      ;viertes Zeichen
  160.      pop ax
  161.      mov ah,10
  162.      add al,'0'
  163.      int 10H
  164.      pop dx
  165.      ret
  166.  
  167. WERT_AUSGEBEN ENDP
  168.  
  169.  
  170. WRITE_CR PROC NEAR
  171.                    ;Schreibt CR in den Tastatur-Puffer. Dadurch
  172.                    ;wird an das Programm, das als nächstes über
  173.                    ;den Interrupt 16 die Tastatur ausliest, ein
  174.                    ;<Return> übergeben.
  175.      push ds
  176.      push ax
  177.      mov ax,40H
  178.      mov ds,ax
  179.      mov ds:word ptr[1AH],1EH
  180.      mov ds:word ptr[1CH],20H
  181.      mov ds:word ptr[1EH],1C0DH
  182.      pop ax
  183.      pop ds
  184.      ret
  185.  
  186. WRITE_CR ENDP
  187.  
  188.  
  189. LF PROC NEAR
  190.                    ;Input: DH=aktuelle Zeile des Cursors(0..24)
  191.                    ;       DL=aktuelle Spalte
  192.                    ;Prozedur erhöht die aktuelle Zeile, wird
  193.                    ;dabei der Bildschirmbereich verlassen,
  194.                    ;führt die Prozedur ein Scrolling durch. DH
  195.                    ;bleibt dann konstant. Die entstehende
  196.                    ;Leerzeile am unteren Bildschirmrand wird
  197.                    ;wird mit dem Attribut, das in "attribut"
  198.                    ;steht, gefüllt.
  199.                    ;Die Register DX,CX werden verändert
  200.      cmp dh,24
  201.      jb kein_scrolling
  202.      push dx
  203.      mov ax,601H
  204.      mov cx,0
  205.      mov dh,24
  206.      mov dl,79
  207.      mov bh,cs:Attribut
  208.      int 10H
  209.      pop dx
  210.      dec dh
  211. kein_scrolling:
  212.      inc dh
  213.      mov dl,0
  214.      ret
  215.  
  216. LF ENDP
  217.  
  218.  
  219. TEXT_AUSGABE PROC NEAR
  220.      push ds       ;Input: DS:SI -> zeigt auf den auszugebenden
  221.                    ;Text. '$' muß als Endekennung am Ende der
  222.                    ;Zeichenkette stehen.
  223.                    ;Die Prozedur entspricht der Funktion 9 des
  224.                    ;Interrupts 21H, dieser konnte nicht ver-
  225.                    ;wendet werden, da die Gefahr einer Stack-
  226.                    ;kollision besteht.
  227.      push si       ;Lesen der aktuellen Cursorposizion,
  228.                    ;wird in DX zurückgegeben
  229.      call lese_cursor_position
  230.      cld
  231. ausgabe_loop:
  232.      ;Bildschirm voll ?
  233.      cmp cs:page_count,max_lines
  234.                    ;Festellen, ob Abfrage erfolgen soll
  235.      jb nicht_voll
  236.      mov cs:page_count,0
  237.      mov si,offset warten
  238.      call text_ausgabe ;Ausgabe des Textes "Weiter --> Eine .."
  239.      xor ax,ax
  240.      int 16H           ; Warte bis Taste gedrückt wird
  241. nicht_voll:
  242.      ;Cursor setzen   ;setzen des Cursors auf die Position, die
  243.                       ;in DX stehen muß
  244.      mov ah,2
  245.      mov bh,seite
  246.      int 10H
  247.      pop si           ;Restaurieren des Pointers auf den
  248.                       ;auszugebenden Text
  249.      lodsb            ;Zeichen holen
  250.      push si          ;aktuelle Lesepostion wieder sichern
  251.      cmp al,'$'       ;Ende erreicht ?
  252.      je ausgabe_ende
  253.      cmp al,13        ;Soll ein LF erfolgen
  254.      jne kein_lf
  255.      call lf
  256.      inc cs:page_count ;Anzahl der ausgegebenen Zeilen erhöhen
  257.      jmp ausgabe_loop  ;Rücksprung, nächstes Zeichen holen
  258. kein_lf:
  259.      ;Zeichen ausgeben
  260.      mov ah,10
  261.      mov bh,seite
  262.      mov cx,1
  263.      int 10H           ;Zeichen in AL ausgeben
  264.      inc dl            ;Spaltenpsosition erhöhen
  265.      cmp dl,80         ;letzte Spalte erreicht ?
  266.      jl ausgabe_loop
  267.      call lf           ;LF ausführen und
  268.      inc cs:page_count ;Anzahl der ausgebenen Zeilen erhöhen
  269.      jmp ausgabe_loop
  270. ausgabe_ende:
  271.      mov cs:page_count,0
  272.      pop si
  273.      pop ds
  274.      ret
  275.  
  276. TEXT_AUSGABE ENDP
  277.  
  278.  
  279. SAVE_INT_VEKTOREN PROC NEAR
  280.                    ;Diese Prozedur sichert alle Interrupt-
  281.                    ;vektoren bis zum Vektor "max_intvektor"/4
  282.                    ;in den Puffer "int_vektoren"
  283.      push cx
  284.      push si
  285.      push di
  286.      push ds
  287.      push es
  288.      mov ax,0
  289.      mov ds,ax
  290.      mov ax,cs
  291.      mov es,ax
  292.      mov si,0
  293.      mov di,offset int_vektoren
  294.      mov cx,max_intvektor
  295.      shr cx,1
  296.      cld
  297.      rep movsw
  298.      pop es
  299.      pop ds
  300.      pop di
  301.      pop si
  302.      pop cx
  303.      add dh,2
  304.      ret
  305.  
  306. SAVE_INT_VEKTOREN ENDP
  307.  
  308.  
  309. CURSOR_WEITERSETZEN PROC NEAR
  310.                    ;liest die aktuelle Cursorposition aus und
  311.                    ;setzt Cursor um eine Stelle weiter
  312.        push cx
  313.        mov bh,seite
  314.        mov ah,3
  315.        int 10H
  316.        inc dl
  317.        mov ah,2
  318.        int 10H
  319.        pop cx
  320.        ret
  321.  
  322. CURSOR_WEITERSETZEN ENDP
  323.  
  324.  
  325. RESTORE_INT_VEKTOREN PROC NEAR
  326.                    ;Stellt fest, ob Interruptvektoren verändert
  327.                    ;wurden (durch Vergleich mit dem entspre-
  328.                    ;chenden Puffer. Falls eine Veränderung
  329.                    ;stattgefunden hat, wird nachgefragt, ob
  330.                    ;diese wieder restauriert werden soll
  331.      push cx
  332.      push di
  333.      push si
  334.      push ds
  335.      push es
  336.      mov cs:change_int,0
  337.      mov si,offset ausgabe_cr  ;SI zeigt auf zwei CR-Zeichen
  338.      call text_ausgabe
  339.      ;Hat ein Veränderung stattgefunden ?
  340.      mov ax,0
  341.      mov es,ax
  342.      mov ax,cs
  343.      mov ds,ax
  344.      mov di,0
  345.      mov si,offset int_vektoren
  346.      cld
  347.      mov cx,max_intvektor
  348.      shr cx,1
  349.      push dx
  350. next_intvektor:
  351.      repe cmpsw    ;Vergleich des Puffers "int_vektoren" mit
  352.                    ;den Interruptvektoren
  353.      cmp di,max_intvektor
  354.                    ;Falls Ende erreicht, Vergleich beenden
  355.      jae restore_control_ende
  356.        push cx
  357.        mov cs:change_int,255
  358.                    ;Unterschied festgestellt daher Kennungsbyte
  359.                    ;auf 255 setzen und
  360.        mov ax,di
  361.        mov cl,2
  362.        shr ax,cl
  363.        push ax
  364.        call wert_ausgeben
  365.                    ;Nummer des geänderten Interrupts ausgeben
  366.        call cursor_weitersetzen
  367.        mov al,','            ;Komma ausgeben
  368.        mov ah,10
  369.        mov bh,seite
  370.        mov cx,1
  371.        int 10H
  372.        call cursor_weitersetzen
  373.        pop ax
  374.                    ;Wiederherstellen des Pointers auf das
  375.                    ;Zeichen innerhalb von "int_vektoren" an
  376.                    ;der Vergleich fortgesetzt werden soll
  377.        inc ax
  378.        mov cl,2
  379.        shl ax,cl
  380.        mov di,ax
  381.        add ax,offset int_vektoren
  382.        mov si,ax
  383.        pop cx
  384.        jmp next_intvektor
  385. restore_control_ende:
  386.      pop dx
  387.      inc dh
  388.      cmp cs:change_int,255
  389.      jne restore_ende
  390.      mov si,offset int_veraenderung
  391.                    ;Textausgabe "Diese Interruptvektoren..."
  392.      call text_ausgabe
  393.      xor ax,ax
  394.      int 16H
  395.      cmp ah,24H       ;Ist die gedrückte Taste "J" ?
  396.      jne restore_ende ;Falls nicht, Prozedur beenden
  397.      mov di,0         ;ansonsten Interruptvektoren restaurieren
  398.      mov si,offset int_vektoren
  399.      mov cx,max_intvektor
  400.      shr cx,1
  401.      cld
  402.      rep movsw
  403. restore_ende:
  404.      pop es
  405.      pop ds
  406.      pop si
  407.      pop di
  408.      pop cx
  409.      ret
  410.  
  411. RESTORE_INT_VEKTOREN ENDP
  412.  
  413.  
  414. DATEN_AUSGABE PROC NEAR
  415.                    ;Diese Prozedur wird nach dem Deaktivieren
  416.                    ;des Programmes aufgerufen. Sie übernimmt
  417.                    ;die gesamte Datenausgabe
  418.                    ;Ausgabe der Anzahl der Schreibzugriffe auf
  419.                    ;Disketten und Festplatten
  420.      mov ax,cs
  421.      mov ds,ax
  422.      mov si,offset deaktivieren
  423.      call text_ausgabe
  424.      mov ax,cs:f_count
  425.      call wert_ausgeben
  426.      mov si,offset da_2
  427.      call text_ausgabe
  428.      mov ax,cs:h_count
  429.      call wert_ausgeben
  430.  
  431.      ;Ausgabe Warnung ?
  432.      cmp cs:warning,255
  433.                    ;Wurde ein Schreibversuch auf die Bootspur
  434.                    ;versucht ?
  435.      jne keine_warnung
  436.      mov si,offset warnung
  437.                    ;Ja, daher spezielle Meldung ausgeben
  438.      call text_ausgabe
  439. keine_warnung:
  440.                    ;Kontrolle, ob Interruptvektoren verändert
  441.                    ;wurden. Falls Ja, Abfrage ob diese wieder
  442.                    ;restauriert werden sollen
  443.      call restore_int_vektoren
  444.                    ;Ausgabe der Dateinamen, auf die nach dem
  445.                    ;Aktivieren von Protect zugegriffen wurde
  446.      mov si,offset dateinamen
  447.      call text_ausgabe
  448.      mov si,offset puffer
  449.      cld
  450. da_loop:
  451.      cmp si,[pointer]
  452.      je da_loop_ausgabe
  453.      lodsb
  454.      cmp al,0
  455.      jne da_loop
  456.      mov ds:byte ptr[si-1],13
  457.      jmp da_loop
  458. da_loop_ausgabe:
  459.      mov ds:byte ptr[si],'$'
  460.      mov si,offset puffer
  461.      call text_ausgabe
  462.      ret
  463.  
  464. DATEN_AUSGABE ENDP
  465.  
  466.  
  467. INT13_HANDLING PROC NEAR
  468.                    ;Diese Prozedur übernimmt die Kontrolle des
  469.                    ;Interrupt 13H. Sie wird nur aktiv, wenn die
  470.                    ;die Speicherzelle "on" den Wert 255 enthält
  471.      cmp cs:on,255
  472.      je handling
  473.      jmp dword ptr cs:[int_13]
  474. handling:
  475.                    ;Prüfen ob ein Schreibzugriff oder Formatie-
  476.                    ;rungversuch erfolgen soll. Falls nein, wird
  477.                    ;die ursprüngliche BIOS Routine aufgerufen.
  478.                    ;Falls Ja, wird notiert, ob der Zugriff auf
  479.                    ;Diskette oder Festplatte erfolgen sollte
  480.                    ;und wieviele Sektoren geschrieben werden
  481.                    ;sollten. Findet ein Zugriff auf Spur Null
  482.                    ;statt, wird die Speicherzelle "warning" auf
  483.                    ;255 gesetzt, danach kehrt die Routine zum
  484.                    ;aufrufenden Programm zurück
  485.      cmp ah,3      ;Funktionsnummer: Schreiben
  486.      je stop
  487.      cmp ah,5      ;Funktionsnr.: Formatieren
  488.      je stop
  489.      cmp ah,11     ;Funktionsnr.: Erweitertes Schreiben
  490.      je stop
  491.      jmp dword ptr cs:[int_13]
  492. stop:
  493.      cmp ch,0      ;Zugriff auf Spur 0,
  494.                    ;CH enthält Teil der Zylindernummer
  495.      jne no_warning
  496.       cmp dh,0
  497.       jne no_warning
  498.       mov ah,cl
  499.       and ah,11000000B
  500.                    ;Bit 8&7 sind Bit 10&9 der Zylindernummer
  501.       cmp ah,0
  502.       jne no_warning
  503.       mov cs:warning,255
  504. no_warning:
  505.      xor ah,ah
  506.      cmp dl,80H    ;Zugriff auf Festplatte ?
  507.      jae ih_hd
  508.      add cs:f_count,ax
  509.                    ;Nein, daher Anzahl der zu schreibenden
  510.                    ;Sektoren zu "f_cound" addieren
  511.      jmp ih_e
  512. ih_hd:
  513.      add cs:h_count,ax   ;ansonsten Wert zu "h_count" addieren
  514. ih_e:
  515.                    ;Carry Flag löschen, um dem Programm ein
  516.                    ;fehlerfreies Schreiben vorzugaukeln
  517.      push bp
  518.      mov bp,sp
  519.      mov ax,ss:[bp+6]  ;Flags nach AX bringen
  520.      and ax,11111110B  ;Carry löschen
  521.      mov ss:[bp+6],ax  ; und zurückschreiben
  522.      pop bp
  523.      iret              ;Zurück zum aufrufenden Programm
  524.  
  525. INT13_HANDLING ENDP
  526.  
  527.  
  528. SWITCH PROC NEAR
  529.                    ;Diese Prozedur übernimmt das Umschalten von
  530.                    ;"on"
  531.                    ;1: Prozedur wird aufgerufen, und "on"
  532.                    ; erhält den Wert 0. Kommentar "Protect
  533.                    ; aktiviert" wird ausgegeben
  534.                    ; Interuptvektoren werden über die Prozedur
  535.                    ; "save_int_vektoren" gesichert.
  536.                    ; "on" wird auf 255 gesetzt, die Funtionen
  537.                    ; "int13_handling" und "int21_handling"
  538.                    ; werden damit 'scharf' gemacht
  539.                    ;2: Prozedur wird aufgerufen und "on"
  540.                    ; erhält den Wert 255. Kommentar "Protect
  541.                    ; deaktiviert" wird ausgegeben
  542.                    ; Prozedur "daten_ausgabe" wird aufgerufen
  543.                    ; "on" wird auf 0 gesetzt
  544.      push ax
  545.      push bx
  546.      push cx
  547.      push dx
  548.      push si
  549.      push di
  550.      push ds
  551.      push es       ;Attribut lesen
  552.      mov ah,8
  553.      mov bh,seite
  554.      int 10H
  555.      mov cs:attribut,ah
  556.      cmp cs:on,0
  557.      je einschalten
  558.        call daten_ausgabe
  559.        mov cs:on,0
  560.                    ;Löschen der restlichen Parameter
  561.        mov cs:f_count,0
  562.        mov cs:h_count,0
  563.        mov cs:[pointer],offset puffer
  564.        mov cs:warning,0
  565.        jmp switch_ende
  566. einschalten:
  567.      call save_int_vektoren
  568.      mov ax,cs
  569.      mov ds,ax
  570.      mov si,offset aktivieren
  571.      call text_ausgabe
  572.      mov cs:on,255
  573. switch_ende:
  574.      call write_cr
  575.      pop es
  576.      pop ds
  577.      pop di
  578.      pop si
  579.      pop dx
  580.      pop cx
  581.      pop bx
  582.      pop ax
  583.      ret
  584.      ret
  585.  
  586. SWITCH ENDP
  587.  
  588.  
  589. SAVE_FCB PROC NEAR
  590.                    ;Input: DS:DX muß auf den normalen oder
  591.                    ;erweiterten File Control Block zeigen
  592.                    ;Die Prozedur hat die Aufgabe, den
  593.                    ;Dateinamen aus dem FCB in den Puffer
  594.                    ;"puffer" zu übertragen.
  595.      push ax
  596.      push bx
  597.      push cx
  598.      push dx
  599.      push si
  600.      push di
  601.      push ds
  602.      push es
  603.      mov si,dx
  604.      mov al,ds:[si] ;erstes Byte des FCB
  605.      cmp al,255     ;Handelt es sich um einen erweiterten FCB ?
  606.      jne fcb_weiter
  607.       add dx,8      ;JA, daher DX auf Dateiname setzen
  608. fcb_weiter:
  609.      mov ax,cs
  610.      mov es,ax
  611.      mov di,cs:pointer ;ES:DI -> "puffer"
  612.      mov cx,8       ;CX = Länge des Dateinamen, ohne Extension
  613.      mov si,dx
  614.      cld
  615.      cmp di,offset puffer_ende-15
  616.                    ;Ist im Puffer noch genügend Platz für den
  617.                    ;Dateinamen ?
  618.      jbe fcb_loop_name
  619.      mov di,offset puffer
  620.                    ;Pointer wieder auf den Pufferanfang setzen
  621. fcb_loop_name:
  622.      rep movsb     ;Dateinamen übertragen
  623.      mov al,'.'
  624.      stosb         ;Punkt nach Dateinamen setzen, Ziel ist die
  625.                    ;Trennung von Namen und Extention
  626.      mov cx,3
  627.      rep movsb     ;Extention übertragen
  628.      mov al,0      ;Endekennung schreiben
  629.      stosb
  630.      mov cs:pointer,di   ;neues Pufferende sichern
  631.      pop es
  632.      pop ds
  633.      pop di
  634.      pop si
  635.      pop dx
  636.      pop cx
  637.      pop bx
  638.      pop ax
  639.      ret
  640.  
  641. SAVE_FCB ENDP
  642.  
  643.  
  644. SAVE_HANDLE PROC NEAR
  645.                    ;Input DS:DX zeigt auf den Dateinamen
  646.      push ax
  647.      push bx
  648.      push cx
  649.      push dx
  650.      push si
  651.      push di
  652.      push ds
  653.      push es
  654.      cld
  655.      mov ax,cs
  656.      mov es,ax
  657.      mov si,dx
  658.      mov di,cs:pointer
  659.      cmp di,offset puffer_ende-15
  660.                    ;noch genügend Platz im Puffer ?
  661.      jbe loop_open_name
  662.      mov di,offset puffer
  663.                    ;Nein, daher Pointer wieder auf Pufferanfang
  664. loop_open_name:    ;Übertragen des Dateinamens
  665.      lodsb
  666.      stosb
  667.      cmp al,0      ;Solange, bis Endekennung "0"
  668.                    ;übertragen wurde
  669.      jne loop_open_name
  670.      mov cs:pointer,di   ;Neues Pufferende sichern
  671.      pop es
  672.      pop ds
  673.      pop di
  674.      pop si
  675.      pop dx
  676.      pop cx
  677.      pop bx
  678.      pop ax
  679.      ret
  680.  
  681. SAVE_HANDLE ENDP
  682.  
  683.  
  684. INT21_HANDLING PROC NEAR
  685.                    ;Diese Prozedur übernimmt die Kontrolle des
  686.                    ;Interrupt 21H, falls die Speicherzelle "on"
  687.                    ;den Wert 255 enthält. Sie stellt fest, ob
  688.                    ;eine Datei über eine FCB- oder eine Handle-
  689.                    ;Funktion geöffnet werden soll. Falls dies
  690.                    ;der Fall ist, wird über die entsprechende
  691.                    ;Funktion ("save_fcb","save_handle") der
  692.                    ;Name der zu öffnenden Datei gesichert.
  693.                    ;Danach wird die Interrupt 21H-Routine
  694.                    ;von DOS angesprungen. Es wird keinerlei
  695.                    ;Schreibzugriff unterbunden, das erledigt
  696.                    ;die Prozedur "int13_handling".
  697.      cmp cs:on,255
  698.      je start
  699.      jmp cs:dword ptr[int21]
  700. start:
  701.      cmp ah,15     ;Funktionsnr.: öffne Datei über FCB
  702.      je fcb
  703.      cmp ah,61     ;Funktionsnr.: öffne Datei über Handle
  704.      je handle
  705.      jmp cs:dword ptr[int21]
  706. fcb:
  707.      call save_fcb
  708.      jmp cs:dword ptr[int21]
  709. handle:
  710.      call save_handle
  711.      jmp cs:dword ptr[int21]
  712.                    ;Entsprechende DOS Funktion aufrufen
  713. INT21_HANDLING ENDP
  714.  
  715.  
  716. INT9_HANDLING PROC NEAR
  717.                    ;übernimmt die Kontrolle der Hotkeys
  718.      push ax
  719.      cmp cs:aktiv,255  ;Wird die Routine gerade abgearbeitet ?
  720.      je int9_ende
  721.      in al,60H     ;Nummer der gedrückten Taste vom Keyboard-
  722.                    ;Controller holen
  723.      cmp al,keystroke
  724.                    ;handelt es sich dabei um die oben defi-
  725.                    ;nierte Taste, wird kontrolliert, ob auch
  726.                    ;<Ctrl> und <Alt> gedrückt sind.
  727.                    ;Ist dies der Fall wird die Routine
  728.                    ;"switch" aufgerufen
  729.      je status_byte
  730.      pop ax
  731.      jmp cs:dword ptr[int9]
  732. status_byte:
  733.      push ds
  734.      mov ax,40H
  735.      mov ds,ax
  736.      mov al,ds:[17H]
  737.      and al,1100B
  738.      pop ds
  739.      cmp al,12
  740.      je int9_start
  741. int9_ende:
  742.      pop ax
  743.      jmp cs:dword ptr[int9]
  744. int9_start:        ;Tastenkombination wurde gedrückt
  745.      mov cs:aktiv,255
  746.                    ;Verhindern, daß Routine zweimal aufgerufen
  747.                    ;wird, Tastatur wieder freigeben
  748.      in al,61H
  749.      mov ah,al
  750.      or al,80H
  751.      out 61H,al
  752.      mov al,ah
  753.      out 61H,al    ;Interruptsperre löschen
  754.      mov al,20H
  755.      out 20H,al
  756.      sti
  757.      call switch
  758.      cli
  759.      pop ax
  760.      mov cs:aktiv,0 ;Betreten der Routine ist wieder erlaubt
  761.      iret
  762. INT9_HANDLING ENDP
  763.  
  764. HP:            ;Meldung ausgeben, daß Programm geladen wurde
  765.      mov ax,cs
  766.      mov ds,ax
  767.      mov dx,offset geladen
  768.      mov ah,9
  769.      int 21H       ;Intvektor 13H sichern & ändern
  770.      mov ax,3513H
  771.      int 21H
  772.      mov word ptr[int_13],bx
  773.      mov word ptr[int_13+2],es
  774.      mov dx,offset int13_handling
  775.      mov ax,2513H
  776.      int 21H       ;Interrupt 9 sichern und ändern
  777.      mov ax,3509H
  778.      int 21H
  779.      mov word ptr [int9],bx
  780.      mov word ptr [int9+2],es
  781.      mov dx,offset int9_handling
  782.      mov ax,2509H
  783.      int 21H       ;Interrupt 21H sichern und ändern
  784.      mov ax,3521H
  785.      int 21H
  786.      mov word ptr [int21],bx
  787.      mov word ptr [int21+2],es
  788.      mov dx,offset int21_handling
  789.      mov ax,2521H
  790.      int 21H       ;Programm resident beenden
  791.      mov dx,offset hp
  792.      mov cl,4
  793.      shr dx,cl
  794.      add dx,21H
  795.      mov ax,3100H
  796.      int 21H
  797.  
  798. CODE ENDS
  799.      END
  800.