5 * ReactOS MSVCRT.DLL Compatibility Library
9 #include <internal/tls.h>
14 unsigned int _osver
= 0;
15 unsigned int _winminor
= 0;
16 unsigned int _winmajor
= 0;
17 unsigned int _winver
= 0;
20 char *_acmdln
= NULL
; /* pointer to ascii command line */
21 wchar_t *_wcmdln
= NULL
; /* pointer to wide character command line */
24 char **_environ
= NULL
; /* pointer to environment block */
25 wchar_t **_wenviron
= NULL
; /* pointer to environment block */
26 char **__initenv
= NULL
; /* pointer to initial environment block */
27 wchar_t **__winitenv
= NULL
; /* pointer to initial environment block */
29 char *_pgmptr
= NULL
; /* pointer to program name */
31 wchar_t *_wpgmptr
= NULL
; /* pointer to program name */
32 int __app_type
= 0; //_UNKNOWN_APP; /* application type */
35 int _commode
= _IOCOMMIT
;
38 int BlockEnvToEnvironA(void)
40 char *ptr
, *environment_strings
;
44 TRACE("BlockEnvToEnvironA()\n");
46 environment_strings
= GetEnvironmentStringsA();
47 if (environment_strings
== NULL
) {
51 for (ptr
= environment_strings
; *ptr
; ptr
+= len
)
53 len
= strlen(ptr
) + 1;
54 /* Skip drive letter settings. */
59 __initenv
= _environ
= malloc(count
* sizeof(char*));
62 for (ptr
= environment_strings
, envptr
= _environ
; count
> 1; ptr
+= len
)
64 len
= strlen(ptr
) + 1;
65 /* Skip drive letter settings. */
68 if ((*envptr
= malloc(len
)) == NULL
)
70 for (envptr
--; envptr
>= _environ
; envptr
--);
72 FreeEnvironmentStringsA(environment_strings
);
74 __initenv
= _environ
= NULL
;
77 memcpy(*envptr
++, ptr
, len
);
81 /* Add terminating NULL entry. */
85 FreeEnvironmentStringsA(environment_strings
);
86 return _environ
? 0 : -1;
89 int BlockEnvToEnvironW(void)
91 wchar_t *ptr
, *environment_strings
;
95 TRACE("BlockEnvToEnvironW()\n");
97 environment_strings
= GetEnvironmentStringsW();
98 if (environment_strings
== NULL
) {
102 for (ptr
= environment_strings
; *ptr
; ptr
+= len
)
104 len
= wcslen(ptr
) + 1;
105 /* Skip drive letter settings. */
110 __winitenv
= _wenviron
= malloc(count
* sizeof(wchar_t*));
113 for (ptr
= environment_strings
, envptr
= _wenviron
; count
> 1; ptr
+= len
)
115 len
= wcslen(ptr
) + 1;
116 /* Skip drive letter settings. */
119 if ((*envptr
= malloc(len
* sizeof(wchar_t))) == NULL
)
121 for (envptr
--; envptr
>= _wenviron
; envptr
--);
123 FreeEnvironmentStringsW(environment_strings
);
125 __winitenv
= _wenviron
= NULL
;
128 memcpy(*envptr
++, ptr
, len
* sizeof(wchar_t));
132 /* Add terminating NULL entry. */
136 FreeEnvironmentStringsW(environment_strings
);
137 return _wenviron
? 0 : -1;
141 * Internal function to duplicate environment block. Although it's
142 * parameter are defined as char**, it's able to work also with
143 * wide character environment block which are of type wchar_t**.
145 * @param original_environment
146 * Environment to duplicate.
148 * Set to zero for multibyte environments, non-zero otherwise.
150 * @return Original environment in case of failure, otherwise
151 * pointer to new environment block.
153 char **DuplicateEnvironment(char **original_environment
, int wide
)
156 char **envptr
, **newenvptr
, **newenv
;
158 for (envptr
= original_environment
; *envptr
!= NULL
; envptr
++, count
++)
161 newenvptr
= newenv
= malloc(count
* sizeof(char*));
163 return original_environment
;
165 for (envptr
= original_environment
; count
> 1; newenvptr
++, count
--)
168 *newenvptr
= (char*)_wcsdup((wchar_t*)*envptr
++);
170 *newenvptr
= _strdup(*envptr
++);
171 if (*newenvptr
== NULL
)
173 for (newenvptr
--; newenvptr
>= newenv
; newenvptr
--);
176 return original_environment
;
185 * Internal function to deallocate environment block. Although it's
186 * parameter are defined as char**, it's able to work also with
187 * wide character environment block which are of type wchar_t**.
190 * Environment to free.
192 void FreeEnvironment(char **environment
)
195 for (envptr
= environment
; *envptr
!= NULL
; envptr
++)
201 * Internal version of _wputenv and _putenv. It works duplicates the
202 * original envirnments created during initilization if needed to prevent
203 * having spurious pointers floating around. Then it updates the internal
204 * environment tables (_environ and _wenviron) and at last updates the
207 * Note that there can happen situation when the internal [_w]environ
208 * arrays will be updated, but the OS environment update will fail. In
209 * this case we don't undo the changes to the [_w]environ tables to
210 * comply with the Microsoft behaviour (and it's also much easier :-).
212 int SetEnv(const wchar_t *option
)
214 wchar_t *epos
, *name
;
218 int remove
, index
, count
, size
, result
= 0, found
= 0;
220 if (option
== NULL
|| (epos
= wcschr(option
, L
'=')) == NULL
)
222 remove
= (epos
[1] == 0);
224 /* Duplicate environment if needed. */
225 if (_environ
== __initenv
)
227 if ((_environ
= DuplicateEnvironment(_environ
, 0)) == __initenv
)
230 if (_wenviron
== __winitenv
)
232 if ((_wenviron
= (wchar_t**)DuplicateEnvironment((char**)_wenviron
, 1)) ==
237 /* Create a copy of the option name. */
238 name
= malloc((epos
- option
+ 1) * sizeof(wchar_t));
241 memcpy(name
, option
, (epos
- option
) * sizeof(wchar_t));
242 name
[epos
- option
] = 0;
244 /* Find the option we're trying to modify. */
245 for (index
= 0, wenvptr
= _wenviron
; *wenvptr
!= NULL
; wenvptr
++, index
++)
247 if (!_wcsnicmp(*wenvptr
, option
, epos
- option
))
262 /* Remove the option from wide character environment. */
264 for (count
= index
; *wenvptr
!= NULL
; wenvptr
++, count
++)
265 *wenvptr
= *(wenvptr
+ 1);
266 _wenviron
= realloc(_wenviron
, count
* sizeof(wchar_t*));
268 /* Remove the option from multibyte environment. We assume
269 * the environments are in sync and the option is at the
271 free(_environ
[index
]);
272 memmove(&_environ
[index
], &_environ
[index
+1], (count
- index
) * sizeof(char*));
273 _environ
= realloc(_environ
, count
* sizeof(char*));
275 result
= SetEnvironmentVariableW(name
, NULL
) ? 0 : -1;
279 /* Make a copy of the option that we will store in the environment block. */
280 woption
= _wcsdup((wchar_t*)option
);
287 /* Create a multibyte copy of the option. */
288 size
= WideCharToMultiByte(CP_ACP
, 0, option
, -1, NULL
, 0, NULL
, NULL
);
289 mboption
= malloc(size
);
290 if (mboption
== NULL
)
296 WideCharToMultiByte(CP_ACP
, 0, option
, -1, mboption
, size
, NULL
, NULL
);
300 /* Replace the current entry. */
303 free(_environ
[index
]);
304 _environ
[index
] = mboption
;
311 /* Get the size of the original environment. */
312 for (count
= index
; *wenvptr
!= NULL
; wenvptr
++, count
++)
315 /* Create a new entry. */
316 if ((wnewenv
= realloc(_wenviron
, (count
+ 2) * sizeof(wchar_t*))) == NULL
)
324 if ((mbnewenv
= realloc(_environ
, (count
+ 2) * sizeof(char*))) == NULL
)
333 /* Set the last entry to our option. */
334 _wenviron
[count
] = woption
;
335 _environ
[count
] = mboption
;
336 _wenviron
[count
+ 1] = NULL
;
337 _environ
[count
+ 1] = NULL
;
340 /* And finally update the OS environment. */
341 result
= SetEnvironmentVariableW(name
, epos
+ 1) ? 0 : -1;
351 int *__p__commode(void) // not exported by NTDLL
359 void __set_app_type(int app_type
)
361 __app_type
= app_type
;
367 char **__p__acmdln(void)
375 wchar_t **__p__wcmdln(void)
383 char ***__p__environ(void)
391 wchar_t ***__p__wenviron(void)
399 char ***__p___initenv(void)
407 wchar_t ***__p___winitenv(void)
415 int *__p___mb_cur_max(void)
417 return &__mb_cur_max
;
423 unsigned int *__p__osver(void)
431 char **__p__pgmptr(void)
439 wchar_t **__p__wpgmptr(void)
447 unsigned int *__p__winmajor(void)
455 unsigned int *__p__winminor(void)
463 unsigned int *__p__winver(void)