ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

int SetEnv ( const wchar_t option)

Internal version of _wputenv and _putenv. It works duplicates the original envirnments created during initilization if needed to prevent having spurious pointers floating around. Then it updates the internal environment tables (_environ and _wenviron) and at last updates the OS environemnt.

Note that there can happen situation when the internal [_w]environ arrays will be updated, but the OS environment update will fail. In this case we don't undo the changes to the [_w]environ tables to comply with the Microsoft behaviour (and it's also much easier :-).

Definition at line 210 of file environ.c.

{
   wchar_t *epos, *name;
   wchar_t **wenvptr;
   wchar_t *woption;
   char *mboption;
   int remove, index, count, size, result = 0, found = 0;

   if (option == NULL || (epos = wcschr(option, L'=')) == NULL)
      return -1;
   remove = (epos[1] == 0);

   /* Duplicate environment if needed. */
   if (_environ == __initenv)
   {
      if ((_environ = DuplicateEnvironment(_environ, 0)) == __initenv)
         return -1;
   }
   if (_wenviron == __winitenv)
   {
      if ((_wenviron = (wchar_t**)DuplicateEnvironment((char**)_wenviron, 1)) ==
          __winitenv)
         return -1;
   }

   /* Create a copy of the option name. */
   name = malloc((epos - option + 1) * sizeof(wchar_t));
   if (name == NULL)
      return -1;
   memcpy(name, option, (epos - option) * sizeof(wchar_t));
   name[epos - option] = 0;

   /* Find the option we're trying to modify. */
   for (index = 0, wenvptr = _wenviron; *wenvptr != NULL; wenvptr++, index++)
   {
      if (!_wcsnicmp(*wenvptr, option, epos - option))
      {
         found = 1;
         break;
      }
   }

   if (remove)
   {
      if (!found)
      {
         free(name);
         return 0;
      }

      /* Remove the option from wide character environment. */
      free(*wenvptr);
      for (count = index; *wenvptr != NULL; wenvptr++, count++)
         *wenvptr = *(wenvptr + 1);
      _wenviron = realloc(_wenviron, count * sizeof(wchar_t*));

      /* Remove the option from multibyte environment. We assume
       * the environments are in sync and the option is at the
       * same position. */
      free(_environ[index]);
      memmove(&_environ[index], &_environ[index+1], (count - index) * sizeof(char*));
      _environ = realloc(_environ, count * sizeof(char*));

      result = SetEnvironmentVariableW(name, NULL) ? 0 : -1;
   }
   else
   {
      /* Make a copy of the option that we will store in the environment block. */
      woption = _wcsdup((wchar_t*)option);
      if (woption == NULL)
      {
         free(name);
         return -1;
      }

      /* Create a multibyte copy of the option. */
      size = WideCharToMultiByte(CP_ACP, 0, option, -1, NULL, 0, NULL, NULL);
      mboption = malloc(size);
      if (mboption == NULL)
      {
         free(name);
         free(woption);
         return -1;
      }
      WideCharToMultiByte(CP_ACP, 0, option, -1, mboption, size, NULL, NULL);

      if (found)
      {
         /* Replace the current entry. */
         free(*wenvptr);
         *wenvptr = woption;
         free(_environ[index]);
         _environ[index] = mboption;
      }
      else
      {
         wchar_t **wnewenv;
         char **mbnewenv;

         /* Get the size of the original environment. */
         for (count = index; *wenvptr != NULL; wenvptr++, count++)
            ;

         /* Create a new entry. */
         if ((wnewenv = realloc(_wenviron, (count + 2) * sizeof(wchar_t*))) == NULL)
         {
            free(name);
            free(mboption);
            free(woption);
            return -1;
         }
         _wenviron = wnewenv;
         if ((mbnewenv = realloc(_environ, (count + 2) * sizeof(char*))) == NULL)
         {
            free(name);
            free(mboption);
            free(woption);
            return -1;
         }
         _environ = mbnewenv;

         /* Set the last entry to our option. */
         _wenviron[count] = woption;
         _environ[count] = mboption;
         _wenviron[count + 1] = NULL;
         _environ[count + 1] = NULL;
      }

      /* And finally update the OS environment. */
      result = SetEnvironmentVariableW(name, epos + 1) ? 0 : -1;
   }
   free(name);

   return result;
}

Generated on Mon May 28 2012 06:05:59 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.