www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1993/07/31/06:57:30

Date: Sat, 31 Jul 93 12:17:30 +0200
From: Gordon Beaton <gordon AT Minsk DOT DoCS DOT UU DOT SE>
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: DOS Environment

(This message bounced and so I am posting it again, excuse me if
you are not reading it for the first time...)

Wonkoo Kim (WKIM AT vms DOT cis DOT pitt DOT edu) writes:

> (Q1) I might need to write a C program to set a environmental 
> variable under msdos, but the env string set by putenv() will 
> not be kept after returning to dos. How do I set the environmental 
> var in the dos's master(parent) env space? 


What you want to do is generally not possible with conventional 
methods. (There is an example program that comes with some versions 
of MASM, called "what.asm" that prompts the user and then sets a 
variable with the response, it might be all you need).

But there are some ways I know of, none of which is good in every 
case. I have never tried these from anything but real mode programs, 
so I'm not sure they will help you, but they may give you an indication 
of the difficulties involved.

One method is to search for the actual environment space, by following 
the chain of memory control blocks, and checking the owner of each until 
you come to command.com's environment. Then you go in and add or change 
the contents there manually. This is what "what" does. You can get a 
pointer to the head of the mcb chain by calling int 0x21, function 0x52 
(undocumented). This returns a pointer to the list-of-lists in es:bx, 
and a pointer to the mcb-head is then at offset -2.

I have found that it is not always so easy to be sure that an environment
you have found really belongs to the primary shell.

Another method is to use the dos "backdoor" function (also undocumented). 
This allows you to pass a string to the primary shell for execution, so
you could for example pass your "set" command and it would affect the
primary environment. Call int 0x2e with a pointer to the string in ds:si. 

The obvious problems with this method are that the transient portion of
command.com must be loaded when the call is made, and that you get no
return information. All regs are trashed by the call. Experience here has
shown that it is a good idea to hook the ctrl-c handler with a simple iret
while the call to int2e is in progress, since pressing ctrl-c during the
call will (often) hang the system otherwise (Reentrance? what's that?).

Now that I think of it, I remember a patch in Byte or PC a number of 
years ago, to fix a problem in dos 2.1 with setting the comspec variable 
at boot. What they did was search the first XXX bytes, looking only at
page boundaries until the string COMSPEC= was found. The assumption here 
was that COMSPEC the first entry, which it was then (at boot), but
it might not always be.

For more information about the two undocumented calls, see Ralf Brown's
interrupt list.

/Gordon

-----------------------------------------------------------------------------
gordon AT Minsk DOT DoCS DOT UU DOT SE

Gordon Beaton                                               tel.   018-507405
Uppsala University                                              +46-18-507405
Uppsala, Sweden



- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019