TIP: Click on subject to list as thread! ANSI
echo: power_bas
to: ALL
from: ANDRAS HOEFFKEN
date: 1998-03-03 00:47:00
subject: WIN95SPY.BAS (2 of 2)

'>>> Page 2 of WIN95SPY.BAS begins here.
    incr all_int21(status)             'Variablenzugriff ueber DS moeglich
    if v86 then incr v86_int21(status)
    CHAIN_vector=old_vec1              'ersetzt die C-Funktion
!   call near pop_and_chain            ; "_chain_intr(old_vector)"
'----------------------------------------------------------------------------
INT_serv2:                             'ISR fuer 2. Interrupt (INT 2F)
!   CALL near push_for_chain
!   CALL near READ_PB_regs
!   mov k,ax
!   mov i,ah
    if win then     'die verschiedenen Stadien von Windows registrieren
      if k     = %W_INIT_CODE  then
        status=%W_INIT
      elseif k = %W_READY_CODE then
        status=%W_READY: t2 = count_t   't2 = WIN start
      elseif k = %W_EXIT_CODE  then
        status=%W_EXIT : t3 = count_t   't3 = WIN endet
      elseif k = %W_DONE_CODE  then
        status=%W_DONE
      end if
      if status = %W_READY then
        incr int2F(i)
        incr iopl_int2F(iopl)
        incr vm_int2F(vmid)
      end if
    else
      incr int2F(i)
    end if
    incr all_int2F(status)
    if v86 then incr v86_int2F(status)
    CHAIN_vector=old_vec2
!   call near pop_and_chain
'---------------------------------------------------------------------------
'Der primaere Timer-Interrupt &H08 (Hardware-IRQ0 ueber den 8259-Controller)
'tickt IMMER GENAU alle 55 Millisekunden. - Der nachgehaengte Timer-Interrupt
'&H1C (Software INT) ist unkritischer,tickt aber UNGENAU, wenn in der
'&H1C-ISR zu viel Zeit verbraucht wird !!!
timer_int:                             'Timer tick
!   pushf                              ;diese 2 Zeilen simulieren einen INT!
!   call dword ptr old.timer.vector    ;ZUERST die alte &H08-ISR bedienen !!!
!   CALL near push_ALL                 ;regs retten (Aufrufer-STACK)
!   CALL near READ_PB_regs             ;PB Regs lesen
    incr count_t                       'Variablenzugriff ueber DS moeglich
!   CALL near pop_ALL                  ;regs restaurieren (Aufrufer-STACK)
!   iret
'---------------------------------------------------------------------------
push_for_chain:  'muss IMMER paarweise mit "pop_and_chain" auftreten!
'   hier: zuerst return_address, dann ax
!   push bx
!   push cx
!   push dx
!   push es
!   push ds
!   push si
!   push di
!   push bp
!   mov  bp,sp       ;Bezugs-BP
!   mov  bx,[bp+16]  ;bx = return addresse holen
!   mov  [bp+16],ax  ;jetzt ax dorthin
!   push bx          ;<-- return addresse
!   retn
pop_and_chain:       'DS muss unbedingt noch intakt sein, alle anderen nicht
!   pop  ax          ;return addresse weg
!   mov  bp,sp       ;Bezugs-BP restaurieren
!   mov  ax,[bp+16]  ;ax + bx restaurieren und
!   mov  bx,[bp+14]  ;  2 Plaetze frei machen
!   mov  cx,CHAIN_vector[00]
!   mov  [bp+14],cx  ;chain Addresse LO word (offset)
!   mov  cx,CHAIN_vector[02]
!   mov  [bp+16],cx  ;chain Addresse HI word (segment)
!   pop  bp          ;restl. Register restaurieren
!   pop  di
!   pop  si
!   pop  ds
!   pop  es
!   pop  dx
!   pop  cx
!   cli              ;wird von der chain routine erwartet
!   retf             ;Absprung zur chain routine
'---------------------------------------------------------------------------
push_ALL:     'PUSH_ALL und POP_ALL muessen IMMER paarweise verwendet werden!
'   hier: return Addresse BLEIBT auf dem Stack!!
!   push ax
!   push bx
!   push cx
!   push dx
!   push es
!   push ds
!   push si
!   push di
!   push bp
!   mov  bp,sp
!   mov  ax,[bp+18]  ;ax=RETURN address
!   push ax          ;<== RETURN address
!   retn
pop_ALL:
!   mov  bp,sp
!   mov  ax,[bp]     ;ax=RETURN address
!   mov  [bp+20],ax  ;first TO this location
!   pop  bp          ;THEN throw away
!   pop  bp          ;pop all registers
!   pop  di
!   pop  si
!   pop  ds
!   pop  es
!   pop  dx
!   pop  cx
!   pop  bx
!   pop  ax
!   retn
'---------------------------------------------------------------------------
SAVE_PB_regs:        'wird NUR vor dem SHELL Befehl aufgerufen!
!   mov  PB.regs[00],si
!   mov  PB.regs[02],di
!   mov  PB.regs[04],bp
!   mov  PB.regs[06],ds
!   retn
READ_PB_regs:             'ss/sp darf hier NICHT gelesen werden (wegen retn)
!   mov  ds, PB.regs[06]  ;PB-Regs
!   mov  bp, PB.regs[04]
!   mov  di, PB.regs[02]
!   mov  si, PB.regs[00]
!   retn
prepare_old_timvec:
!   mov   ax, old_vec3[00]             ;vector von DS nach CS umspeichern
!   mov   old.timer.vector, ax         ;offset
!   mov   ax, old_vec3[02]
!   mov   old.timer.vector[02], ax     ;segment
!   retn
'-------------------- Datenbereich im Codesegment: --------------------------
old.timer.vector:
!   dd 0
PB.regs:
!   dd 0   ;si,di
!   dd 0   ;bp,ds
'******************* Ende der Inline-ASM (NEAR) Routinen *******************
FUNCTION win_version () AS STRING
    DIM major AS INTEGER, minor AS INTEGER
!   mov ax, &h1600
!   INT &h2F
!   mov major, al
!   mov minor, ah
    IF major=0 OR major=&H80 THEN
      win_version=" keine"
    ELSEIF major=1 OR major=&HFF THEN
      win_version=" WIN/386 V2.x"
    ELSE
      win_version$ = STR$(major) + "." + LTRIM$(STR$(minor))
    END IF
END FUNCTION
FUNCTION vmid () AS INTEGER 'liest Virtual Machine ID (unter WIN)
!   mov ax, &h1683
!   INT &h2f
!   mov FUNCTION[00], bx
END FUNCTION
function iopl () as integer 'liest IOPL Status (unter WIN)
!   pushf
!   pop ax
!   and ax,3
!   mov FUNCTION[00],ax
end function
FUNCTION v86 () AS INTEGER  'liest PE bit (DOS oder WIN/DOS-Fenster)
!   dw  &H010F              ;0F01E0 = "smsw ax" (store machine status word)
!   db  &HE0
!   AND ax,1
!   mov FUNCTION[00],ax
END FUNCTION
SUB CmdLine (argc AS INTEGER, argv() AS STRING, maxargs AS INTEGER)
'   Aufteilung der Kommandozeile in Einzelelemente (Argumente)
'   argv(0) - immer Programmpfad + Name
'   argc    - Anzahl zusaetzlicher Argumente ohne argv(0) (ist in C anders!!)
'   argv()  - Array zur Rueckgabe der Argumente
'   maxargs - Maximal erlaubte Anzahl Argumente, wegen DIM argv(0:maxargs)
    DIM EnvSeg AS WORD, EnvOfs AS WORD
    DIM Char   AS BYTE, Temp   AS STRING, C AS STRING
    DIM i AS INTEGER, l AS INTEGER, in_arg AS INTEGER
 !  push DS                             ;Teil 1 stammt aus der DOSUNIT von PB
 !  mov  AX, &H6200                     ;PSP Addresse
 !  int  &H21                           ;von DOS erfragen
 !  mov  DS, BX                         ;PSP segment in DS
 !  mov  AX, DS:[&H2C]                  ;environment Segment in AX
 !  mov  EnvSeg, AX                     ;in EnvSeg variable
 !  pop  DS                             ;restore DS
    DEF SEG = EnvSeg: EnvOfs = 0
    WHILE PEEKI(EnvOfs) > 0             '2 Null-bytes suchen
     INCR EnvOfs
    WEND
    INCR EnvOfs, 4                      'das ist der Beginn des Strings
    Char = PEEK(EnvOfs)
    WHILE Char > 0                      'bis zum Trennzeicehne CHR$(0)
      Temp = Temp + CHR$(Char)          'den ges. String lesen
      INCR EnvOfs
      Char = PEEK(EnvOfs)
    WEND
    DEF SEG
    argv(0) = Temp                      'Ergebn. z.B.: "C:\PATH\MYPROG.EXE"
    argc = 0                            'Teil 2: selbst gemacht
    in_arg = %FALSE                     '  (DOSUNIT von PB zu umstaendlich)
    Temp = COMMAND$                     'Kommandozeile uebernehmen
    L = LEN(Temp)
    FOR I = 1 TO L                      'Jedes Zeichen pruefen
      C = MID$(Temp, I, 1)
      IF C  " " AND C  CHR$(9) THEN 'Space oder Tab = Trennzeichen?
        IF NOT in_arg THEN              'neues Argument beginnt
          IF argc = maxargs THEN EXIT FOR
          argc = argc + 1
          in_arg = %TRUE
        END IF
        argv(argc) = argv(argc) + C     'Zeichen uebernehmen
      ELSE
        in_arg = %FALSE
      END IF
    NEXT I
 '  argc=argc+1                         'so waer's C-konform
END SUB
FUNCTION dos_getvect (BYVAL intr AS BYTE) AS DWORD
!   mov   ah, &H35                     ;DOS: GET INTERRUPT vector
!   mov   al, intr                     ;     al = INTERRUPT number
!   INT   &H21
!   mov   function[02], es             ;ES:BX = INTERRUPT vector
!   mov   function[00], bx
END FUNCTION
SUB dos_setvect (BYVAL intr AS BYTE, BYVAL vectorptr AS DWORD)
!   push  ds
!   mov   ah, &H25                     ;DOS: set INTERRUPT vector
!   mov   al, intr                     ;     al = INTERRUPT number
!   mov   ds, vectorptr[02]            ;DS:DX = INTERRUPT vector
!   mov   dx, vectorptr[00]
!   INT   &H21
!   pop   ds
END SUB
function hex2 (i as integer) as string
    dim x as string
    x = hex$(i)
    if len(x)=1 then x="0"+x
    hex2=x
end function
function screen_redir() as integer
!   mov   ax, &H4400                   ;IOCTL - Geraeteauskunft holen
!   mov   bx, 1                        ;handle 1 = standard Output STDOUT
!   int   &H21
!   not   dx                           ;alle bits umdrehen, dann gilt:
!   and   dx, &H80                     ;bit 7 = 0 --> Zeichentreiber (Screen)
!   mov   function[00], dx             ;bit 7 = 1 --> Blocktreiber (File)
end function
'>>> Page 2 of WIN95SPY.BAS ends here. Last page.
--- CrossPoint v3.11 R
---------------
* Origin: Fido Point of Disillusion (2:2480/13.34)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.