[Back to TSR SWAG index] [Back to Main SWAG index] [Original]

    {
    Well, here it is, a program that lists TSRs loaded.
    Anybody willing to enhance it so that it checks the HMA for TSRs too?

    Oh, were do I send this so that it gets into the next SWAGS release?  I was
    unable to find such a program in the all the SWAGS until (and inclusive) the
    latest February '94 release...

    { ------------ Cut Here ----------- }

    Program ListTSRs;

    {
       Written by Alex Karipidis on the 8th of March 1994.
       Donated to the public domain.  Use this code freely.

       You can contact me at:
         Fidonet  : 2:410/204.4
         Hellasnet: 7:2000/50.4
         SBCnet   : 14:2100/201.4
         Zyxelnet : 16:800/108.4
         Pascalnet: 115:3005/1.4

       If you enhance/improve this code in any way, I would appreciate it if you
       sent me a copy of your version.

       I will not be responsible for any damage caused by this code.

       This program will print a list of all programs currently loaded in
       memory.
    }

    Type

      pMCB_Rec = ^MCB_Rec;
      MCB_Rec = Record
        ChainID    : Byte; { 77 if part of MCB chain, 90 if last MCB allocated }
        Owner      : Word; { PSP segment address of the MCB's owner }
        Paragraphs : Word; { Paragraphs related to this MCB }
      end;

    Var
      MCB                  : pMCB_Rec;
      InVarsSeg, InVarsOfs : Word;
      EnvSeg, Counter      : Word;

    begin
      { Dos service 52h returns the address of the DOS "invars" table in ES:BX }
               { !!! This is an undocumented DOS function !!! }
      asm
        MOV   AH,52h
        INT   21h
        MOV   InVarsSeg,ES
        MOV   InVarsOfs,BX
      end;

      {
        The word before the "invars" table is the segment of the first MCB
        allocated by DOS.
      }
      MCB := Ptr (MemW [InVarsSeg:InVarsOfs-2], 0);

      While MCB^.ChainID <> 90 do  { While valid MCBs exist... }
      begin

        If MCB^.Owner = Seg (MCB^) + 1 then { If MCB owns itself, then... }
        begin
          Write ('In memory: ');  { We've found a program in memory }

          {
            The word at offset 2Ch of the program's PSP contains the value of
            the program's environment data area.  That's were the program's name
            is located.
          }
          EnvSeg := MemW [MCB^.Owner:$2C];

          {
            The environment also contains the environment variables as ASCIIZ
            (null-terminated) strings.  Two consecutive null (0) bytes mean that
            the environment variables have ended and the program name follows
            after 4 bytes.  That is also an ASCIIZ string.
          }
          Counter := 0;
          While (Mem [EnvSeg:Counter  ] <> 0) or  { Find 2 consecutive }
                (Mem [EnvSeg:Counter+1] <> 0) do  { null bytes.        }
            inc (counter);

          inc (counter,4); { Program name follows after 4 bytes }

          While Mem [EnvSeg:Counter] <> 0 do { Print program name }
          begin
            Write (Char (Mem [EnvSeg : Counter]));
            Inc (counter);
          end;

          WriteLn;

        end;

        { Point to next MCB }
        MCB := Ptr (Seg (MCB^) + MCB^.Paragraphs + 1, 0);
      end;

      {
        Note: The last MCB is not processed!
              It is assumed that it is this program's MCB.
              In your programs, this may or may not be the case.
      }

    end.

[Back to TSR SWAG index] [Back to Main SWAG index] [Original]