From: bobs@dragons.nest.nl (Bob Swart)
Newsgroups: comp.lang.pascal
Subject: Delphi and DOS environment variables
Date: Fri, 21 Apr 1995 08:25:00 +0100

Hi Steve,

 > I wouldn't recommend using the RTL70 function.  Use the GetDOSEnvironment()
 > API function instead.
And for an example you could refer to The Pascal Magazine issue #5, where the
WINENV unit from The Chief was presented in Dr. Bob's column:

 *** 4. Windows Environment ***

The Chief (laa12@keele.ac.uk) reported to me that the EnvCount and EnvStr
functions from the DOS unit are not available in the WinDos unit for Windows.
This can introduce a bit of a problem with those porting code from DOS, or who
wish to do things with the list of all the environment variables.

Fortunately, The Chief also found a way to get to the environment from a
Windows program. First of all, we use the Windows GetDOSEnvironment function to
obtain a far pointer to the environment string of the current (running) task.
The result is just a concatenation of zero-terminated strings, followed by
another #0 and the application that owns the environment. This structure can be
handled quite well using PChars, so The Chief wrote the Windows versions of
EnvCount and GetEnvStr (see unit below):


Unit WinEnv;
interface

  function EnvCount: Word;
  { Returns the number of environment variables.
  }
  function GetEnvStr(Const Index: Word): String;
  { Returns the environment string number Index.
    You can use this to loop through all the environment variables.
  }

implementation
uses WinTypes,
     WinProcs,
     Strings;

  function EnvCount: Word;
  var p2: pchar;
      i: Word;
  begin
    i := 0;
    p2 := GetDOSEnvironment;
    while p2[0] <> #0 do
    begin
      Inc(i);
      while (p2[0] <> #0) do Inc(p2); { goto end of current }
      Inc(p2) { point to next }
    end;
    EnvCount := i
  end {EnvCount};

  function GetEnvStr(Const Index: Word) : String;
  var p2:pchar;
      i: Word;
  begin
    GetEnvStr := ''; { default }
    i := 0;
    p2 := GetDOSEnvironment;
    while p2[0] <> #0 do
    begin
      Inc(i);
      if i = Index then
      begin
        GetEnvStr := StrPas(p2);
        Exit
      end;
      while (p2[0] <> #0) do Inc(p2); { goto end of current }
      Inc(p2) { point to next }
    end
  end {GetEnvStr};
end.


Testprogram:

uses WinEnv, WinCrt;
var W: Word;
begin
  for W := 1 to EnvCount do Writeln(W,'.',GetEnvStr(W))
end.


So, now we have EnvCount and GetEnvStr. Together with the GetEnvVar (which is
implemented in the WinDos unit), we're complete, right? Almost. We also found a
problem with GetEnvVar under BPW, not a real bug, more a potential lethal
weapon.

If you do
  MyPChar := GetEnvVar('TEMP')

and then you try to do something with the value in MyPChar - e.g.,
  TempDir := StrPas(MyPChar)

you get a GPF if the TEMP environment variable wasn't assigned to a directory.
The on-line help states that GetEnvVar returns "0 If specified environment
variable does not exist", but this 0 is in fact nil, and not #0, so you must
always test for the result of GetEnvVar <> Nil after a call!

Groetjes,
          Dr. Bob

