5 * ReactOS MSVCRT.DLL Compatibility Library
9 #include <internal/tls.h>
14 unsigned int _osplatform
= 0;
15 unsigned int _osver
= 0;
16 unsigned int _winminor
= 0;
17 unsigned int _winmajor
= 0;
18 unsigned int _winver
= 0;
21 char *_acmdln
= NULL
; /* pointer to ascii command line */
22 wchar_t *_wcmdln
= NULL
; /* pointer to wide character command line */
25 char **_environ
= NULL
; /* pointer to environment block */
26 wchar_t **_wenviron
= NULL
; /* pointer to environment block */
27 char **__initenv
= NULL
; /* pointer to initial environment block */
28 wchar_t **__winitenv
= NULL
; /* pointer to initial environment block */
30 char *_pgmptr
= NULL
; /* pointer to program name */
32 wchar_t *_wpgmptr
= NULL
; /* pointer to program name */
33 int __app_type
= 0; //_UNKNOWN_APP; /* application type */
36 int _commode
= _IOCOMMIT
;
39 int BlockEnvToEnvironA(void)
41 char *ptr
, *environment_strings
;
45 TRACE("BlockEnvToEnvironA()\n");
47 environment_strings
= GetEnvironmentStringsA();
48 if (environment_strings
== NULL
) {
52 for (ptr
= environment_strings
; *ptr
; ptr
+= len
)
54 len
= strlen(ptr
) + 1;
55 /* Skip drive letter settings. */
60 __initenv
= _environ
= malloc(count
* sizeof(char*));
63 for (ptr
= environment_strings
, envptr
= _environ
; count
> 1; ptr
+= len
)
65 len
= strlen(ptr
) + 1;
66 /* Skip drive letter settings. */
69 if ((*envptr
= malloc(len
)) == NULL
)
71 for (envptr
--; envptr
>= _environ
; envptr
--);
73 FreeEnvironmentStringsA(environment_strings
);
75 __initenv
= _environ
= NULL
;
78 memcpy(*envptr
++, ptr
, len
);
82 /* Add terminating NULL entry. */
86 FreeEnvironmentStringsA(environment_strings
);
87 return _environ
? 0 : -1;
90 int BlockEnvToEnvironW(void)
92 wchar_t *ptr
, *environment_strings
;
96 TRACE("BlockEnvToEnvironW()\n");
98 environment_strings
= GetEnvironmentStringsW();
99 if (environment_strings
== NULL
) {
103 for (ptr
= environment_strings
; *ptr
; ptr
+= len
)
105 len
= wcslen(ptr
) + 1;
106 /* Skip drive letter settings. */
111 __winitenv
= _wenviron
= malloc(count
* sizeof(wchar_t*));
114 for (ptr
= environment_strings
, envptr
= _wenviron
; count
> 1; ptr
+= len
)
116 len
= wcslen(ptr
) + 1;
117 /* Skip drive letter settings. */
120 if ((*envptr
= malloc(len
* sizeof(wchar_t))) == NULL
)
122 for (envptr
--; envptr
>= _wenviron
; envptr
--);
124 FreeEnvironmentStringsW(environment_strings
);
126 __winitenv
= _wenviron
= NULL
;
129 memcpy(*envptr
++, ptr
, len
* sizeof(wchar_t));
133 /* Add terminating NULL entry. */
137 FreeEnvironmentStringsW(environment_strings
);
138 return _wenviron
? 0 : -1;
142 * Internal function to duplicate environment block. Although it's
143 * parameter are defined as char**, it's able to work also with
144 * wide character environment block which are of type wchar_t**.
146 * @param original_environment
147 * Environment to duplicate.
149 * Set to zero for multibyte environments, non-zero otherwise.
151 * @return Original environment in case of failure, otherwise
152 * pointer to new environment block.
154 char **DuplicateEnvironment(char **original_environment
, int wide
)
157 char **envptr
, **newenvptr
, **newenv
;
159 for (envptr
= original_environment
; *envptr
!= NULL
; envptr
++, count
++)
162 newenvptr
= newenv
= malloc(count
* sizeof(char*));
164 return original_environment
;
166 for (envptr
= original_environment
; count
> 1; newenvptr
++, count
--)
169 *newenvptr
= (char*)_wcsdup((wchar_t*)*envptr
++);
171 *newenvptr
= _strdup(*envptr
++);
172 if (*newenvptr
== NULL
)
174 for (newenvptr
--; newenvptr
>= newenv
; newenvptr
--);
177 return original_environment
;
186 * Internal function to deallocate environment block. Although it's
187 * parameter are defined as char**, it's able to work also with
188 * wide character environment block which are of type wchar_t**.
191 * Environment to free.
193 void FreeEnvironment(char **environment
)
196 for (envptr
= environment
; *envptr
!= NULL
; envptr
++)
202 * Internal version of _wputenv and _putenv. It works duplicates the
203 * original envirnments created during initilization if needed to prevent
204 * having spurious pointers floating around. Then it updates the internal
205 * environment tables (_environ and _wenviron) and at last updates the
208 * Note that there can happen situation when the internal [_w]environ
209 * arrays will be updated, but the OS environment update will fail. In
210 * this case we don't undo the changes to the [_w]environ tables to
211 * comply with the Microsoft behaviour (and it's also much easier :-).
213 int SetEnv(const wchar_t *option
)
215 wchar_t *epos
, *name
;
219 int remove
, index
, count
, size
, result
= 0, found
= 0;
221 if (option
== NULL
|| (epos
= wcschr(option
, L
'=')) == NULL
)
223 remove
= (epos
[1] == 0);
225 /* Duplicate environment if needed. */
226 if (_environ
== __initenv
)
228 if ((_environ
= DuplicateEnvironment(_environ
, 0)) == __initenv
)
231 if (_wenviron
== __winitenv
)
233 if ((_wenviron
= (wchar_t**)DuplicateEnvironment((char**)_wenviron
, 1)) ==
238 /* Create a copy of the option name. */
239 name
= malloc((epos
- option
+ 1) * sizeof(wchar_t));
242 memcpy(name
, option
, (epos
- option
) * sizeof(wchar_t));
243 name
[epos
- option
] = 0;
245 /* Find the option we're trying to modify. */
246 for (index
= 0, wenvptr
= _wenviron
; *wenvptr
!= NULL
; wenvptr
++, index
++)
248 if (!_wcsnicmp(*wenvptr
, option
, epos
- option
))
263 /* Remove the option from wide character environment. */
265 for (count
= index
; *wenvptr
!= NULL
; wenvptr
++, count
++)
266 *wenvptr
= *(wenvptr
+ 1);
267 _wenviron
= realloc(_wenviron
, count
* sizeof(wchar_t*));
269 /* Remove the option from multibyte environment. We assume
270 * the environments are in sync and the option is at the
272 free(_environ
[index
]);
273 memmove(&_environ
[index
], &_environ
[index
+1], (count
- index
) * sizeof(char*));
274 _environ
= realloc(_environ
, count
* sizeof(char*));
276 result
= SetEnvironmentVariableW(name
, NULL
) ? 0 : -1;
280 /* Make a copy of the option that we will store in the environment block. */
281 woption
= _wcsdup((wchar_t*)option
);
288 /* Create a multibyte copy of the option. */
289 size
= WideCharToMultiByte(CP_ACP
, 0, option
, -1, NULL
, 0, NULL
, NULL
);
290 mboption
= malloc(size
);
291 if (mboption
== NULL
)
297 WideCharToMultiByte(CP_ACP
, 0, option
, -1, mboption
, size
, NULL
, NULL
);
301 /* Replace the current entry. */
304 free(_environ
[index
]);
305 _environ
[index
] = mboption
;
312 /* Get the size of the original environment. */
313 for (count
= index
; *wenvptr
!= NULL
; wenvptr
++, count
++)
316 /* Create a new entry. */
317 if ((wnewenv
= realloc(_wenviron
, (count
+ 2) * sizeof(wchar_t*))) == NULL
)
325 if ((mbnewenv
= realloc(_environ
, (count
+ 2) * sizeof(char*))) == NULL
)
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
;
341 /* And finally update the OS environment. */
342 result
= SetEnvironmentVariableW(name
, epos
+ 1) ? 0 : -1;
352 int *__p__commode(void) // not exported by NTDLL
360 void __set_app_type(int app_type
)
362 __app_type
= app_type
;
368 char **__p__acmdln(void)
376 wchar_t **__p__wcmdln(void)
384 char ***__p__environ(void)
392 wchar_t ***__p__wenviron(void)
400 char ***__p___initenv(void)
408 wchar_t ***__p___winitenv(void)
416 int *__p___mb_cur_max(void)
418 return &__mb_cur_max
;
424 unsigned int *__p__osver(void)
432 char **__p__pgmptr(void)
440 wchar_t **__p__wpgmptr(void)
448 unsigned int *__p__winmajor(void)
456 unsigned int *__p__winminor(void)
464 unsigned int *__p__winver(void)