02f8345576915780e51240113ab6dc6802a2451f
5 * ReactOS MSVCRT.DLL Compatibility Library
9 #include <internal/tls.h>
14 #include <internal/debug.h>
17 unsigned int _osver
= 0;
18 unsigned int _winminor
= 0;
19 unsigned int _winmajor
= 0;
20 unsigned int _winver
= 0;
23 char *_acmdln
= NULL
; /* pointer to ascii command line */
24 wchar_t *_wcmdln
= NULL
; /* pointer to wide character command line */
27 char **_environ
= NULL
; /* pointer to environment block */
28 wchar_t **_wenviron
= NULL
; /* pointer to environment block */
29 char **__initenv
= NULL
; /* pointer to initial environment block */
30 wchar_t **__winitenv
= NULL
; /* pointer to initial environment block */
32 char *_pgmptr
= NULL
; /* pointer to program name */
34 wchar_t *_wpgmptr
= NULL
; /* pointer to program name */
35 int __app_type
= 0; //_UNKNOWN_APP; /* application type */
38 int _commode
= _IOCOMMIT
;
41 int BlockEnvToEnvironA(void)
43 char *ptr
, *environment_strings
;
47 DPRINT("BlockEnvToEnvironA()\n");
49 environment_strings
= GetEnvironmentStringsA();
50 if (environment_strings
== NULL
) {
54 for (ptr
= environment_strings
; *ptr
; ptr
+= len
)
56 len
= strlen(ptr
) + 1;
57 /* Skip drive letter settings. */
62 __initenv
= _environ
= malloc(count
* sizeof(char*));
65 for (ptr
= environment_strings
, envptr
= _environ
; count
> 1; ptr
+= len
)
67 len
= strlen(ptr
) + 1;
68 /* Skip drive letter settings. */
71 if ((*envptr
= malloc(len
)) == NULL
)
73 for (envptr
--; envptr
>= _environ
; envptr
--);
75 FreeEnvironmentStringsA(environment_strings
);
77 __initenv
= _environ
= NULL
;
80 memcpy(*envptr
++, ptr
, len
);
84 /* Add terminating NULL entry. */
88 FreeEnvironmentStringsA(environment_strings
);
89 return _environ
? 0 : -1;
92 int BlockEnvToEnvironW(void)
94 wchar_t *ptr
, *environment_strings
;
98 DPRINT("BlockEnvToEnvironW()\n");
100 environment_strings
= GetEnvironmentStringsW();
101 if (environment_strings
== NULL
) {
105 for (ptr
= environment_strings
; *ptr
; ptr
+= len
)
107 len
= wcslen(ptr
) + 1;
108 /* Skip drive letter settings. */
113 __winitenv
= _wenviron
= malloc(count
* sizeof(wchar_t*));
116 for (ptr
= environment_strings
, envptr
= _wenviron
; count
> 1; ptr
+= len
)
118 len
= wcslen(ptr
) + 1;
119 /* Skip drive letter settings. */
122 if ((*envptr
= malloc(len
* sizeof(wchar_t))) == NULL
)
124 for (envptr
--; envptr
>= _wenviron
; envptr
--);
126 FreeEnvironmentStringsW(environment_strings
);
128 __winitenv
= _wenviron
= NULL
;
131 memcpy(*envptr
++, ptr
, len
* sizeof(wchar_t));
135 /* Add terminating NULL entry. */
139 FreeEnvironmentStringsW(environment_strings
);
140 return _wenviron
? 0 : -1;
144 * Internal function to duplicate environment block. Although it's
145 * parameter are defined as char**, it's able to work also with
146 * wide character environment block which are of type wchar_t**.
148 * @param original_environment
149 * Environment to duplicate.
151 * Set to zero for multibyte environments, non-zero otherwise.
153 * @return Original environment in case of failure, otherwise
154 * pointer to new environment block.
156 char **DuplicateEnvironment(char **original_environment
, int wide
)
159 char **envptr
, **newenvptr
, **newenv
;
161 for (envptr
= original_environment
; *envptr
!= NULL
; envptr
++, count
++)
164 newenvptr
= newenv
= malloc(count
* sizeof(char*));
166 return original_environment
;
168 for (envptr
= original_environment
; count
> 1; newenvptr
++, count
--)
171 *newenvptr
= (char*)_wcsdup((wchar_t*)*envptr
++);
173 *newenvptr
= _strdup(*envptr
++);
174 if (*newenvptr
== NULL
)
176 for (newenvptr
--; newenvptr
>= newenv
; newenvptr
--);
179 return original_environment
;
188 * Internal function to deallocate environment block. Although it's
189 * parameter are defined as char**, it's able to work also with
190 * wide character environment block which are of type wchar_t**.
193 * Environment to free.
195 void FreeEnvironment(char **environment
)
198 for (envptr
= environment
; *envptr
!= NULL
; envptr
++)
204 * Internal version of _wputenv and _putenv. It works duplicates the
205 * original envirnments created during initilization if needed to prevent
206 * having spurious pointers floating around. Then it updates the internal
207 * environment tables (_environ and _wenviron) and at last updates the
210 * Note that there can happen situation when the internal [_w]environ
211 * arrays will be updated, but the OS environment update will fail. In
212 * this case we don't undo the changes to the [_w]environ tables to
213 * comply with the Microsoft behaviour (and it's also much easier :-).
215 int SetEnv(const wchar_t *option
)
217 wchar_t *epos
, *name
;
221 int remove
, index
, count
, size
, result
= 0, found
= 0;
223 if (option
== NULL
|| (epos
= wcschr(option
, L
'=')) == NULL
)
225 remove
= (epos
[1] == 0);
227 /* Duplicate environment if needed. */
228 if (_environ
== __initenv
)
230 if ((_environ
= DuplicateEnvironment(_environ
, 0)) == __initenv
)
233 if (_wenviron
== __winitenv
)
235 if ((_wenviron
= (wchar_t**)DuplicateEnvironment((char**)_wenviron
, 1)) ==
240 /* Create a copy of the option name. */
241 name
= malloc((epos
- option
+ 1) * sizeof(wchar_t));
244 memcpy(name
, option
, (epos
- option
) * sizeof(wchar_t));
245 name
[epos
- option
] = 0;
247 /* Find the option we're trying to modify. */
248 for (index
= 0, wenvptr
= _wenviron
; *wenvptr
!= NULL
; wenvptr
++, index
++)
250 if (!_wcsnicmp(*wenvptr
, option
, epos
- option
))
265 /* Remove the option from wide character environment. */
267 for (count
= index
; *wenvptr
!= NULL
; wenvptr
++, count
++)
268 *wenvptr
= *(wenvptr
+ 1);
269 _wenviron
= realloc(_wenviron
, count
* sizeof(wchar_t*));
271 /* Remove the option from multibyte environment. We assume
272 * the environments are in sync and the option is at the
274 free(_environ
[index
]);
275 memmove(&_environ
[index
], &_environ
[index
+1], (count
- index
) * sizeof(char*));
276 _environ
= realloc(_environ
, count
* sizeof(char*));
278 result
= SetEnvironmentVariableW(name
, NULL
) ? 0 : -1;
282 /* Make a copy of the option that we will store in the environment block. */
283 woption
= _wcsdup((wchar_t*)option
);
290 /* Create a multibyte copy of the option. */
291 size
= WideCharToMultiByte(CP_ACP
, 0, option
, -1, NULL
, 0, NULL
, NULL
);
292 mboption
= malloc(size
);
293 if (mboption
== NULL
)
299 WideCharToMultiByte(CP_ACP
, 0, option
, -1, mboption
, size
, NULL
, NULL
);
303 /* Replace the current entry. */
306 free(_environ
[index
]);
307 _environ
[index
] = mboption
;
314 /* Get the size of the original environment. */
315 for (count
= index
; *wenvptr
!= NULL
; wenvptr
++, count
++)
318 /* Create a new entry. */
319 if ((wnewenv
= realloc(_wenviron
, (count
+ 2) * sizeof(wchar_t*))) == NULL
)
327 if ((mbnewenv
= realloc(_environ
, (count
+ 2) * sizeof(char*))) == NULL
)
336 /* Set the last entry to our option. */
337 _wenviron
[count
] = woption
;
338 _environ
[count
] = mboption
;
339 _wenviron
[count
+ 1] = NULL
;
340 _environ
[count
+ 1] = NULL
;
343 /* And finally update the OS environment. */
344 result
= SetEnvironmentVariableW(name
, epos
+ 1) ? 0 : -1;
354 int *__p__commode(void) // not exported by NTDLL
362 void __set_app_type(int app_type
)
364 __app_type
= app_type
;
370 char **__p__acmdln(void)
378 wchar_t **__p__wcmdln(void)
386 char ***__p__environ(void)
394 wchar_t ***__p__wenviron(void)
402 char ***__p___initenv(void)
410 wchar_t ***__p___winitenv(void)
418 int *__p___mb_cur_max(void)
420 return &__mb_cur_max
;
426 unsigned int *__p__osver(void)
434 char **__p__pgmptr(void)
442 wchar_t **__p__wpgmptr(void)
450 unsigned int *__p__winmajor(void)
458 unsigned int *__p__winminor(void)
466 unsigned int *__p__winver(void)