ReactOS  0.4.15-dev-2522-g9e0a3cd
wputenv.c File Reference
#include <precomp.h>
Include dependency graph for wputenv.c:

Go to the source code of this file.

Functions

int SetEnv (const wchar_t *option)
 
int _wputenv (const wchar_t *val)
 

Function Documentation

◆ _wputenv()

int _wputenv ( const wchar_t val)

Definition at line 10 of file wputenv.c.

11 {
12  return SetEnv(val);
13 }
GLuint GLfloat * val
Definition: glext.h:7180
int SetEnv(const wchar_t *option)
Definition: environ.c:210

◆ SetEnv()

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.

211 {
212  wchar_t *epos, *name;
213  wchar_t **wenvptr;
214  wchar_t *woption;
215  char *mboption;
216  int remove, index, count, size, result = 0, found = 0;
217  wchar_t **wnewenv;
218  char **mbnewenv;
219 
220  if (option == NULL || (epos = wcschr(option, L'=')) == NULL)
221  return -1;
222  remove = (epos[1] == 0);
223 
224  /* Duplicate environment if needed. */
225  if (_environ == __initenv)
226  {
228  return -1;
229  }
230  if (_wenviron == __winitenv)
231  {
232  if ((_wenviron = (wchar_t**)DuplicateEnvironment((char**)_wenviron, 1)) ==
233  __winitenv)
234  return -1;
235  }
236 
237  /* Create a copy of the option name. */
238  name = malloc((epos - option + 1) * sizeof(wchar_t));
239  if (name == NULL)
240  return -1;
241  memcpy(name, option, (epos - option) * sizeof(wchar_t));
242  name[epos - option] = 0;
243 
244  /* Find the option we're trying to modify. */
245  for (index = 0, wenvptr = _wenviron; *wenvptr != NULL; wenvptr++, index++)
246  {
247  if (!_wcsnicmp(*wenvptr, option, epos - option))
248  {
249  found = 1;
250  break;
251  }
252  }
253 
254  if (remove)
255  {
256  if (!found)
257  {
258  free(name);
259  return 0;
260  }
261 
262  /* Remove the option from wide character environment. */
263  free(*wenvptr);
264  for (count = index; *wenvptr != NULL; wenvptr++, count++)
265  *wenvptr = *(wenvptr + 1);
266  wnewenv = realloc(_wenviron, count * sizeof(wchar_t*));
267  if (wnewenv != NULL)
268  _wenviron = wnewenv;
269 
270  /* Remove the option from multibyte environment. We assume
271  * the environments are in sync and the option is at the
272  * same position. */
273  free(_environ[index]);
274  memmove(&_environ[index], &_environ[index+1], (count - index) * sizeof(char*));
275  mbnewenv = realloc(_environ, count * sizeof(char*));
276  if (mbnewenv != NULL)
277  _environ = mbnewenv;
278 
280  }
281  else
282  {
283  /* Make a copy of the option that we will store in the environment block. */
284  woption = _wcsdup((wchar_t*)option);
285  if (woption == NULL)
286  {
287  free(name);
288  return -1;
289  }
290 
291  /* Create a multibyte copy of the option. */
293  mboption = malloc(size);
294  if (mboption == NULL)
295  {
296  free(name);
297  free(woption);
298  return -1;
299  }
300  WideCharToMultiByte(CP_ACP, 0, option, -1, mboption, size, NULL, NULL);
301 
302  if (found)
303  {
304  /* Replace the current entry. */
305  free(*wenvptr);
306  *wenvptr = woption;
307  free(_environ[index]);
308  _environ[index] = mboption;
309  }
310  else
311  {
312  /* Get the size of the original environment. */
313  for (count = index; *wenvptr != NULL; wenvptr++, count++)
314  ;
315 
316  /* Create a new entry. */
317  if ((wnewenv = realloc(_wenviron, (count + 2) * sizeof(wchar_t*))) == NULL)
318  {
319  free(name);
320  free(mboption);
321  free(woption);
322  return -1;
323  }
324  _wenviron = wnewenv;
325  if ((mbnewenv = realloc(_environ, (count + 2) * sizeof(char*))) == NULL)
326  {
327  free(name);
328  free(mboption);
329  free(woption);
330  return -1;
331  }
332  _environ = mbnewenv;
333 
334  /* Set the last entry to our option. */
335  _wenviron[count] = woption;
336  _environ[count] = mboption;
337  _wenviron[count + 1] = NULL;
338  _environ[count + 1] = NULL;
339  }
340 
341  /* And finally update the OS environment. */
342  result = SetEnvironmentVariableW(name, epos + 1) ? 0 : -1;
343  }
344  free(name);
345 
346  return result;
347 }
#define realloc
Definition: debug_ros.c:6
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define WideCharToMultiByte
Definition: compat.h:111
GLuint64EXT * result
Definition: glext.h:11304
#define CP_ACP
Definition: compat.h:109
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define free
Definition: debug_ros.c:5
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
char ** DuplicateEnvironment(char **original_environment, int wide)
Definition: environ.c:151
char ** _environ
Definition: environ.c:22
char ** __initenv
Definition: environ.c:24
Definition: getopt.h:108
GLuint index
Definition: glext.h:6031
GLuint GLenum option
Definition: glext.h:11211
wchar_t ** _wenviron
Definition: environ.c:23
GLsizeiptr size
Definition: glext.h:5919
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:259
#define index(s, c)
Definition: various.h:29
static const WCHAR L[]
Definition: oid.c:1250
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define NULL
Definition: types.h:112
wchar_t ** __winitenv
Definition: environ.c:25
Definition: name.c:38
#define malloc
Definition: debug_ros.c:4
_Check_return_ _CRTIMP wchar_t *__cdecl _wcsdup(_In_z_ const wchar_t *_Str)
int remove
Definition: msacm.c:1365
GLuint const GLchar * name
Definition: glext.h:6031

Referenced by _wputenv().