June, 1994 - Vol. 1 No. 6


Listing A: ENV2.CPP


#include <dos.h>     // _psp & environ
#include <string.h>  // strlen()
#include <stdlib.h>  // putenv()
#include <mem.h>     // memcpy()

//*************************************************
// PSP class from May - BCDJ
// manages Program Segment Prefix pointers and
// a pointer to the environment block

class PSP {
  public:
   PSP(unsigned int pspSegment)
   { pspFarPointer = (char _seg *)pspSegment; }

   unsigned int getParentPSP()
   { return *((unsigned int*) (pspFarPointer + 22)); }
   char* getEnvironmentBlock()
   {  return *((char _seg **)(pspFarPointer + 44)); }

  private:
   char* pspFarPointer;
};

//*************************************************
// EnvBlock class
// encapsulates the code to retrieve and modify an
// environment block

class EnvBlock
{
  public:
    EnvBlock(char*);
    ~EnvBlock();
    char* getenv(const char*);
    int putenv(const char*);
  private:
    unsigned int envSpaceSize;
    char* startOfEnv;
    int envCount;
    char** envVars;
    void delenv(int);
    void addenv(const char* name);
};

//------------------------------------------------
// Constructor for the EnvBlock class

EnvBlock::EnvBlock(char* start) :
 startOfEnv(start) {
  char huge* tempAddress = startOfEnv;
  envSpaceSize = 
    *((unsigned int*)(tempAddress - 13)) * 16;
  tempAddress = startOfEnv;
  int envVarLength;
  envVars = new char*[100];
  envCount = 0;
  while(*tempAddress != 0) {
    envVarLength = strlen((char*)tempAddress);
    addenv((char*)tempAddress);
    tempAddress += envVarLength + 1;
  }
}

//------------------------------------------------
// Destructor for the EnvBlock class

EnvBlock::~EnvBlock() {
  char huge* temp = startOfEnv;
  int stringOffset = 0;
  int count = 0;
  while((stringOffset < envSpaceSize) && (count < envCount)) {
    _fstrcpy((char*)temp, envVars[count]);
    stringOffset += _fstrlen(envVars[count]) + 1;
    temp += _fstrlen(envVars[count]) + 1;
    ++count;
  }
  *temp = 0;
  for(count = 0; count < envCount; ++count)
    delete envVars[count];
}

//------------------------------------------------
// getenv() member function
// duplicates the behavior of the getenv() library
// function with any environment block

char* EnvBlock::getenv(const char* name) {
  char* returnPtr = 0;
  const char huge* nameStart = name;
  const char huge* nameEnd = _fstrchr(name, '=');
  int strlength;
  if(nameEnd != 0)
    strlength = nameEnd - nameStart + 1;
  else
    strlength = _fstrlen(name) + 1;

  char* newName = new char[strlength];
  _fmemcpy(newName, name, strlength);
  newName[strlength] = 0;

  for(int count = 0; count < envCount; ++count) {
    returnPtr = _fstrstr(envVars[count], newName);
    if((nameEnd != 0) && (returnPtr != 0)) {
      delenv(count);
      returnPtr = 0;
      break;
    }
  }
  delete newName;
  return returnPtr;
}

//------------------------------------------------
// putenv() member function
// duplicates the behavior of the putenv() library
// function with any environment block

int EnvBlock::putenv(const char* name) {
  this->getenv(name);
  char huge* endOfName = _fstrchr(name, '=');
  ++endOfName;
  if((*endOfName) != 0) {
    addenv(name);
  }
  return 0;
}

//------------------------------------------------
// addenv() private member function
// adds a new environment variable

void EnvBlock::addenv(const char* name) {
  envVars[envCount] = new 
    char[_fstrlen(name) + 1];
  _fstrcpy(envVars[envCount], name);
  ++envCount; 
}

//------------------------------------------------
// delenv() private member function
// removes an environment variable

void EnvBlock::delenv(int index) {
  delete envVars[index];
  --envCount;
  for(int count = index; count < envCount; ++count)
    envVars[count] = envVars[count + 1];
}

//*************************************************
// body of the program

int main()
{
  PSP myPSP(_psp);
  PSP myParentPSP(myPSP.getParentPSP());
  EnvBlock* parentEnv = new 
    EnvBlock(myParentPSP.getEnvironmentBlock());
  parentEnv->putenv("BCDJ=JUNE");
  parentEnv->getenv("PROMPT=");
  delete parentEnv;
  return 0;
}

Return to "Programming in DOS - Adding a DOS environment variable from inside a program"


Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.