Board index » delphi » Pascal and the DOS-Environment; HELP needed

Pascal and the DOS-Environment; HELP needed

Hi all!

I need urgent help for the following problem:

I did a program in TP 6.0 that passes an DOS environment variable to
the this program calling DOS-batch-process (dos version 6.2x). Because I
didn't find a procedure in TP's DOS.TPU that could serve me well, I made a
procedure that writes directly to the DOS environment space of the callig
command.com. It looks in its own PSP for the PSP of the calling program
(which is my permanent command.com, started in config.sys with
SHELL= .... /E:2048 /P), where it can find the segment and offset of the
environment space of this command.com.

All went well with pure DOS 6.22 on my own PC (running EMM386 and HIMEM.
SYS). The procedure placed new variables correct as well as it removed or
altered already existing varibles without problems. Just like the SET
command of the command.com. I tested it to death.

The problems arised when I had this program to run on a PC managed by QEMM
V8.0. Although the variables were set correctly, the machine hung from time
to time, especially just in the moment when my programm terminated and
returned to the batch, but also when I called or terminated some other
applications. I figured out (some time after one of the hangs destroyed the
FAT of the second HDD !!) - or at least I *hope* to have figured out - that
the problem came with the fully installed DOS-UP-option of QEMM. After
turning this option to only partly placing DOS-stuff somewhere beyond 640K  
(i.e. keeping command.com and some dos-data low) all went fine, and I
couldn't provoke any more hangs - up to now. But as you may imagine I'm a
little bit afraid of using this procedure of mine any longer... even with a
reconfigurated QEMM. I don't want to have another HDD scrambled (BTW I could
rescue nearly all data of the aforementioned disk with 'scandisk'...
really!). The thing is that not only *I* want to use this program, but also
some other people...

And now my question (  :-) THX for reading so far):  How can I safely manage
the DOS-environment of the first permanent command.com with TP 6.0 or TP7.0?
Is there something like a 'setenv' procedure?

Please one of you high-skilled programmers help a rookie. I'm pretty sure
there's a simple Pascal or DOS trick that could be applied. TIA!

Michael

P.S. Just doing   exec(getenv('comspec'),'/c set xyz=hello_world')   won't
do, because 'xyz' is only altered in the new started command.com, not in the
underlying permanent command.com. And I cannot start a new permanent
command.com every time my program terminates...

 

Re:Pascal and the DOS-Environment; HELP needed


Quote
Michael Wolberg <wolb...@chemie.uni-oldenburg.de> wrote:
>command.com. It looks in its own PSP for the PSP of the calling program

You should make sure that you are at the root PSP; ie, say you have a data
structure defined:
  Type
    PPSP = ^PSP
    PSP = record
     [...]
      EnvironmentSeg: Word;
      ParentPSP: Word;
     [...]
     end;

Then to find the master program environment go
(PPSP points to own PSP)
  repeat PPSP := Ptr(PPSP^.ParentPSP) until Seg(PPSP^) = PPSP^.ParentPSP;
then alter the environment pointed to by the field in that PSP's
environment.

Quote
>P.S. Just doing   exec(getenv('comspec'),'/c set xyz=hello_world')   won't
>do, because 'xyz' is only altered in the new started command.com, not in the
>underlying permanent command.com. And I cannot start a new permanent
>command.com every time my program terminates...

Nice idea, however it can't work without cheating:

  Interrupt 2E

4DOS provides full, documented support for the undocumented COMMAND.COM
"back door" entry, INT 2E (hex).  INT 2E allows pplications to call the
primary copy of the command processor to execute commands, without loading
a secondary shell.

To use INT 2E, set DS:SI to the address of a buffer containing the
command, then issue an INT 2E.  The buffer format is:

     First byte  Length of the command, not including this
                 byte or the last byte
     Text bytes  The command text
     Last byte   CR (ASCII 13)

You must release enough memory for 4DOS to reload its transient portion,
and provide about 80 bytes of available stack space for the INT 2E handler
to use.  INT 2E can not be called from a TSR while 4DOS is running (for
example, a TSR popped up at the 4DOS prompt or from within LIST or
SELECT), but can be called from within any application or from within a
TSR while an application (including the 4DOS HELP system) is running.

[snip]

On return from INT 2E, all registers will be destroyed except SS and SP.
AX will be set as follows:

     FFFFh  An error occurred before processing the command:  not enough
            memory was available, INT 2E was called from a TSR, or another
            error made it impossible to handle the interrupt.

     0      The command was processed without error.

     > 0    There was an error in processing the command.  AX is the error
            number, equivalent to the %_? value from an internal command
            or the %? value from an external command.  If a batch file is
            run, the value will be the error level returned by the batch
            file (via QUIT n or CANCEL n) or the last command within it.
            If an alias is run the value will be the exit code returned by
            the last command in the alias.

If you want any more information about this, give me a yell via email.
--

Quote
>:-P

Sam Vilain, diony...@sans.vuw.ac.nz

Re:Pascal and the DOS-Environment; HELP needed


Re:Pascal and the DOS-Environment; HELP needed


1st:

Hi *.*!

   I have to apologize for asking for something that is on a FAQ.
   Obviously I was a little bit to hasty... sorry!

2nd:

Hi Dionysus!

Quote
>You should make sure that you are at the root PSP; ie, say you have a data
>structure defined:
>  Type
>    PPSP = ^PSP
>    PSP = record
>     [...]
>      EnvironmentSeg: Word;
>      ParentPSP: Word;
>     [...]
>     end;

>Then to find the master program environment go
>(PPSP points to own PSP)
>  repeat PPSP := Ptr(PPSP^.ParentPSP) until Seg(PPSP^) = PPSP^.ParentPSP;

Ahh, good short algorithm that 'tunnels through' to the first
(permanent) command.com and brings you onto the safe side.

Quote
>Interrupt 2E
>[...]

OK, another great feature of 4DOS. But unfortunately one cannot expect
everybody to have 4DOS run when planning a program (especially in the case
you have to surround it by a batch). I presume I cannot handle int $2E
of original MS-DOS the same way, right?

Votis Kokavessis <paratiritis.the.forthnet...@popper.forthnet.gr> suggested
to simply take the segment of int $2E itself... let me see... where I have
it...ah, here it is:

<< There is a very simple way to get a pointer to the so-called master DOS
   environment:

    function master_environment:pointer; assembler;
      asm
        mov ax,352Eh
        int 21h                    {actually getintvec of int 2Eh}
        mov dx,word ptr es:[2Ch]   {ES now holds the 1st command.com PSP!}
        xor ax,ax                  {DX:AX is the returned pointer}
      end;

   I have read this method not very recently in some book or magazine.
   It might be dangerous, because it assumes that interrupt 2Eh is
   pointing inside DOS, i.e. no other program (maybe a de{*word*81} or another
   command interpreter) has hooked it. If you decide to use this method,
   a good check could be to search the returned address for strings like
   'COMSPEC=' and 'PATH=', to be sure it really is a DOS environment.  >>

I checked this by dumping 0000:00B8. Indeed int $2E points right into the
master command.com (offset $013F), even when I start 'debug' from a 2nd
shell ('command /c c:\dos\debug').

But why using undocumented MS-DOS interrupts for just reading from and
writing to the master environment? For this purpose the method you gave at
first is IMHO by far the better solution. Nevertheless this 'back door'
thing is an interesting one...

Thanks a lot for your help!  :-)

Later...

Michael

PS: There comes something to my mind that is related to all this stuff:
    I experienced the 'getenv' procedure of TP to read only from the
    copy of the environment the program is provided with when started.
    Hence 'getenv' is useless when you alter the master environment
    and want to come back on it later in your program.

Other Threads