[comp.sys.ibm.pc] Looking for Interrupt 2Eh info

bgeer@esunix.UUCP (Bob Geer) (07/05/90)

>From article <159@evtprp0b.UUCP>, by tea6219@evtprp0b.UUCP (Terry E. Acker):
>> In article <54516@lanl.gov> ryg@lanl.gov (Richard S Grandy) writes:
>>>I'm looking for info on how the 'undocumented' DOS v3.x Interrupt
>>>2Eh works.  I want to be able to *permanently* alter environmental
>>>variables from within a program.  (as opposed to altering the
>>>environment of *the program*)

<< This is my second try at posting this...also, I sent email to
<< RSGrandy but no response; don't know what's working & not.

The following program fragments are from a program I wrote to edit the
environment's PATH variable.  The program compiled under Turbo Pascal
3 & ran under dos 2.0 to 3.3.  Be sure there is enough environment
space available; I think there is a /E:nnn switch you can use somewhere
in the config.sys file to increase enviro-space.

As I recall, anything you wish to enter into the environment space can
be done this way, as long as there's room.  Note the format for the
string submitted to `2Eh' includes a string length byte, the string,
followed by a carriage return & a null.  Muy importante!  The
environment variable that is changed will end up as the last
environment variable after `2Eh' is done with it.

If this type of program is run from a batch file, remember that the
*master* environment is changed, but the batch file's is not!  Nor is
any other program's environment changed that is run subsequently by
that batch file; it will get the batch file's environment.

It's been a long time since I played with this; trust my recollection
with that in mind.  Experiment with caution!  Be backed up!

Bob Geer, bear-person
< I'll get that .signature file done someday! >

   EXECUTE         = $2E ; { DOS execute software interrupt }
                           { see Dr. Dobb's Journal #122 (Dec 1986) }
   PATH_LENGTH     = 127   ; { apparent length limit dos 3.0 }
   TMPDS : INTEGER = $0000 ;
   TMPSI : INTEGER = $0000 ;
   MY_SS : INTEGER = $0000 ; { typed constants for saving ss,sp }
   MY_SP : INTEGER = $FFFE ; { in procedure set_new_path }

      IF (LENGTH(path_str.str)+6 <= PATH_LENGTH) THEN
         BEGIN { if }
         new_path.str := CONCAT('SET ', path_str.str) ;
         new_path.bytes[1+LENGTH(new_path.str)] := CARRIAGE_RETURN ;
         new_path.bytes[2+LENGTH(new_path.str)] := NULL ;
         TMPDS := SEG(new_path) ; { path command segment for dos }
         TMPSI := OFS(new_path) ; { path command offset  for dos }
         INLINE ($1E/                 { push ds ; save environment }
                 $55/                 { push bp ;   " }
                 $2E/$8E/$1E/TMPDS/   { mov ds,cs:TMPDS ; prepare for fn }
                 $2E/$8B/$36/TMPSI/   { mov si,cs:TMPSI }
{importante!}    $2E/$8C/$16/MY_SS/   { mov cs:MY_SS,ss ; save stack seg }
                 $2E/$89/$26/MY_SP/   { mov cs:MY_SP,sp ; & stack ptr }
                 $CD/$2E/             { int 2e ; call msdos }
                 $2E/$8E/$16/MY_SS/   { mov ss,cs:MY_SS }
                 $2E/$8B/$26/MY_SP/   { mov sp,cs:MY_SP }
                 $5D/                 { pop bp }
                 $1F) ;               { pop ds }
         END   { if }
         ELSE
         BEGIN { if-else }
         WRITE   ('New path is too long; length=',LENGTH(path_str.str)) ;
         WRITELN (' (limit=',PATH_LENGTH-6, ').') ;
         WRITELN ('Master environment block''s path not changed!') ;
         END ; { if-else }

BEGIN { program pathedit }
MY_SS := SSEG ;
MY_SP := $FFFE ;

...[prepare desired path string]
set_new_path( arguments ) ;

END . { program pathedit }