4 * ReactOS MSVCRT.DLL Compatibility Library
8 #include <internal/wine/msvcrt.h>
10 unsigned int _osplatform
= 0;
11 unsigned int _osver
= 0;
12 unsigned int _winminor
= 0;
13 unsigned int _winmajor
= 0;
14 unsigned int _winver
= 0;
16 unsigned int __setlc_active
= 0;
17 unsigned int __unguarded_readlc_active
= 0;
18 char *_acmdln
= NULL
; /* pointer to ascii command line */
19 wchar_t *_wcmdln
= NULL
; /* pointer to wide character command line */
22 char **_environ
= NULL
; /* pointer to environment block */
23 wchar_t **_wenviron
= NULL
; /* pointer to environment block */
24 char **__initenv
= NULL
; /* pointer to initial environment block */
25 wchar_t **__winitenv
= NULL
; /* pointer to initial environment block */
27 char *_pgmptr
= NULL
; /* pointer to program name */
29 wchar_t *_wpgmptr
= NULL
; /* pointer to program name */
30 int __app_type
= _UNKNOWN_APP
; /* application type */
31 int _commode
= _IOCOMMIT
;
34 int BlockEnvToEnvironA(void)
36 char *ptr
, *environment_strings
;
41 TRACE("BlockEnvToEnvironA()\n");
43 environment_strings
= GetEnvironmentStringsA();
44 if (environment_strings
== NULL
) {
48 for (ptr
= environment_strings
; *ptr
; ptr
+= len
)
50 len
= strlen(ptr
) + 1;
51 /* Skip drive letter settings. */
56 __initenv
= _environ
= malloc(count
* sizeof(char*));
59 for (ptr
= environment_strings
, envptr
= _environ
; count
> 1; ptr
+= len
)
61 len
= strlen(ptr
) + 1;
62 /* Skip drive letter settings. */
65 if ((*envptr
= malloc(len
)) == NULL
)
67 for (envptr
--; envptr
>= _environ
; envptr
--)
69 FreeEnvironmentStringsA(environment_strings
);
71 __initenv
= _environ
= NULL
;
74 memcpy(*envptr
++, ptr
, len
);
78 /* Add terminating NULL entry. */
82 FreeEnvironmentStringsA(environment_strings
);
83 return _environ
? 0 : -1;
86 int BlockEnvToEnvironW(void)
88 wchar_t *ptr
, *environment_strings
;
93 TRACE("BlockEnvToEnvironW()\n");
95 environment_strings
= GetEnvironmentStringsW();
96 if (environment_strings
== NULL
) {
100 for (ptr
= environment_strings
; *ptr
; ptr
+= len
)
102 len
= wcslen(ptr
) + 1;
103 /* Skip drive letter settings. */
108 __winitenv
= _wenviron
= malloc(count
* sizeof(wchar_t*));
111 for (ptr
= environment_strings
, envptr
= _wenviron
; count
> 1; ptr
+= len
)
113 len
= wcslen(ptr
) + 1;
114 /* Skip drive letter settings. */
117 if ((*envptr
= malloc(len
* sizeof(wchar_t))) == NULL
)
119 for (envptr
--; envptr
>= _wenviron
; envptr
--)
121 FreeEnvironmentStringsW(environment_strings
);
123 __winitenv
= _wenviron
= NULL
;
126 memcpy(*envptr
++, ptr
, len
* sizeof(wchar_t));
130 /* Add terminating NULL entry. */
134 FreeEnvironmentStringsW(environment_strings
);
135 return _wenviron
? 0 : -1;
139 * Internal function to duplicate environment block. Although it's
140 * parameter are defined as char**, it's able to work also with
141 * wide character environment block which are of type wchar_t**.
143 * @param original_environment
144 * Environment to duplicate.
146 * Set to zero for multibyte environments, non-zero otherwise.
148 * @return Original environment in case of failure, otherwise
149 * pointer to new environment block.
151 char **DuplicateEnvironment(char **original_environment
, int wide
)
154 char **envptr
, **newenvptr
, **newenv
;
156 for (envptr
= original_environment
; *envptr
!= NULL
; envptr
++, count
++)
159 newenvptr
= newenv
= malloc(count
* sizeof(char*));
161 return original_environment
;
163 for (envptr
= original_environment
; count
> 1; newenvptr
++, count
--)
166 *newenvptr
= (char*)_wcsdup((wchar_t*)*envptr
++);
168 *newenvptr
= _strdup(*envptr
++);
169 if (*newenvptr
== NULL
)
171 for (newenvptr
--; newenvptr
>= newenv
; newenvptr
--)
174 return original_environment
;
183 * Internal function to deallocate environment block. Although it's
184 * parameter are defined as char**, it's able to work also with
185 * wide character environment block which are of type wchar_t**.
188 * Environment to free.
190 void FreeEnvironment(char **environment
)
193 for (envptr
= environment
; *envptr
!= NULL
; envptr
++)
199 * Internal version of _wputenv and _putenv. It works duplicates the
200 * original envirnments created during initilization if needed to prevent
201 * having spurious pointers floating around. Then it updates the internal
202 * environment tables (_environ and _wenviron) and at last updates the
205 * Note that there can happen situation when the internal [_w]environ
206 * arrays will be updated, but the OS environment update will fail. In
207 * this case we don't undo the changes to the [_w]environ tables to
208 * comply with the Microsoft behaviour (and it's also much easier :-).
210 int SetEnv(const wchar_t *option
)
212 wchar_t *epos
, *name
;
216 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 wnewenv
= realloc(_wenviron
, count
* sizeof(wchar_t*));
270 /* Remove the option from multibyte environment. We assume
271 * the environments are in sync and the option is at the
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
)
279 result
= SetEnvironmentVariableW(name
, NULL
) ? 0 : -1;
283 /* Make a copy of the option that we will store in the environment block. */
284 woption
= _wcsdup((wchar_t*)option
);
291 /* Create a multibyte copy of the option. */
292 size
= WideCharToMultiByte(CP_ACP
, 0, option
, -1, NULL
, 0, NULL
, NULL
);
293 mboption
= malloc(size
);
294 if (mboption
== NULL
)
300 WideCharToMultiByte(CP_ACP
, 0, option
, -1, mboption
, size
, NULL
, NULL
);
304 /* Replace the current entry. */
307 free(_environ
[index
]);
308 _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 errno_t
_get_osplatform(unsigned int *pValue
)
418 if (!MSVCRT_CHECK_PMT(pValue
!= NULL
)) {
423 *pValue
= _osplatform
;
430 int *__p___mb_cur_max(void)
432 return &get_locinfo()->mb_cur_max
;
435 /*********************************************************************
436 * ___mb_cur_max_func(MSVCRT.@)
438 int CDECL
___mb_cur_max_func(void)
440 return get_locinfo()->mb_cur_max
;
446 unsigned int *__p__osver(void)
454 char **__p__pgmptr(void)
462 int _get_pgmptr(char** p
)
464 if (!MSVCRT_CHECK_PMT(p
))
477 wchar_t **__p__wpgmptr(void)
485 int _get_wpgmptr(WCHAR
** p
)
487 if (!MSVCRT_CHECK_PMT(p
))
500 unsigned int *__p__winmajor(void)
508 unsigned int *__p__winminor(void)
516 unsigned int *__p__winver(void)