diff --git a/reactos/lib/msvcrt/Makefile b/reactos/lib/msvcrt/Makefile index 27619dccf86..17b8c795593 100644 --- a/reactos/lib/msvcrt/Makefile +++ b/reactos/lib/msvcrt/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.46 2004/08/22 20:37:05 hbirr Exp $ +# $Id: Makefile,v 1.47 2004/08/27 03:08:23 navaraf Exp $ PATH_TO_TOP = ../.. @@ -454,7 +454,6 @@ TIME_OBJECTS = \ WINE_OBJECTS = \ wine/cpp.o \ wine/cppexcept.o \ - wine/data.o \ wine/heap.o \ wine/lock.o \ wine/main.o \ diff --git a/reactos/lib/msvcrt/misc/dllmain.c b/reactos/lib/msvcrt/misc/dllmain.c index f9ceeaadc05..61f9356172c 100644 --- a/reactos/lib/msvcrt/misc/dllmain.c +++ b/reactos/lib/msvcrt/misc/dllmain.c @@ -1,4 +1,4 @@ -/* $Id: dllmain.c,v 1.23 2004/08/15 18:16:37 chorns Exp $ +/* $Id: dllmain.c,v 1.24 2004/08/27 03:08:23 navaraf Exp $ * * dllmain.c * @@ -14,9 +14,9 @@ * DISCLAMED. This includes but is not limited to warrenties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * $Revision: 1.23 $ - * $Author: chorns $ - * $Date: 2004/08/15 18:16:37 $ + * $Revision: 1.24 $ + * $Author: navaraf $ + * $Date: 2004/08/27 03:08:23 $ * */ @@ -33,17 +33,22 @@ //void __fileno_init(void); extern BOOL __fileno_init(void); -extern int BlockEnvToEnviron(void); +extern int BlockEnvToEnvironA(void); +extern int BlockEnvToEnvironW(void); +extern void FreeEnvironment(char **environment); extern unsigned int _osver; extern unsigned int _winminor; extern unsigned int _winmajor; extern unsigned int _winver; -extern char* _acmdln; /* pointer to ascii command line */ +extern char* _acmdln; /* pointer to ascii command line */ +extern wchar_t* _wcmdln; /* pointer to wide character command line */ #undef _environ -extern char** _environ; /* pointer to environment block */ -extern char** __initenv; /* pointer to initial environment block */ +extern char** _environ; /* pointer to environment block */ +extern char** __initenv; /* pointer to initial environment block */ +extern wchar_t** _wenviron; /* pointer to environment block */ +extern wchar_t** __winitenv; /* pointer to initial environment block */ /* LIBRARY GLOBAL VARIABLES ***************************************************/ @@ -77,17 +82,22 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) if (!CreateThreadData()) return FALSE; - _acmdln = strdup(GetCommandLineA()); + if (BlockEnvToEnvironA() < 0) + return FALSE; - /* FIXME: This crashes all applications */ - if (BlockEnvToEnviron() < 0) - return FALSE; + if (BlockEnvToEnvironW() < 0) + { + FreeEnvironment((char**)_wenviron); + return FALSE; + } + + _acmdln = strdup(GetCommandLineA()); + _wcmdln = wcsdup(GetCommandLineW()); /* FIXME: more initializations... */ /* FIXME: Initialization of the WINE code */ msvcrt_init_mt_locks(); - msvcrt_init_args(); DPRINT("Attach done\n"); break; @@ -107,16 +117,16 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) /* destroy tls stuff */ DestroyThreadData(); + if (__winitenv && __winitenv != _wenviron) + FreeEnvironment((char**)__winitenv); + if (_wenviron) + FreeEnvironment((char**)_wenviron); + if (__initenv && __initenv != _environ) - { - free(__initenv[0]); - free(__initenv); - } + FreeEnvironment(__initenv); if (_environ) - { - free(_environ[0]); - free(_environ); - } + FreeEnvironment(_environ); + /* destroy heap */ HeapDestroy(hHeap); diff --git a/reactos/lib/msvcrt/misc/environ.c b/reactos/lib/msvcrt/misc/environ.c index c6670d89a1f..3e63fd6e76a 100644 --- a/reactos/lib/msvcrt/misc/environ.c +++ b/reactos/lib/msvcrt/misc/environ.c @@ -1,4 +1,4 @@ -/* $Id: environ.c,v 1.9 2004/08/15 18:16:37 chorns Exp $ +/* $Id: environ.c,v 1.10 2004/08/27 03:08:23 navaraf Exp $ * * dllmain.c * @@ -19,20 +19,334 @@ unsigned int _winminor = 0; unsigned int _winmajor = 0; unsigned int _winver = 0; -char *_acmdln = NULL; /* pointer to ascii command line */ -unsigned _envvar_count; /* number of environment vars within current environment */ +char *_acmdln = NULL; /* pointer to ascii command line */ +wchar_t *_wcmdln = NULL; /* pointer to wide character command line */ #undef _environ -char **_environ = NULL; /* pointer to environment block */ -char ***_environ_dll = &_environ;/* pointer to environment block */ -char **__initenv = NULL; +#undef _wenviron +char **_environ = NULL; /* pointer to environment block */ +wchar_t **_wenviron = NULL; /* pointer to environment block */ +char **__initenv = NULL; /* pointer to initial environment block */ +wchar_t **__winitenv = NULL; /* pointer to initial environment block */ #undef _pgmptr -char *_pgmptr = NULL; /* pointer to program name */ +char *_pgmptr = NULL; /* pointer to program name */ int __app_type = 0; //_UNKNOWN_APP; /* application type */ int __mb_cur_max = 1; int _commode = _IOCOMMIT; +int BlockEnvToEnvironA(void) +{ + char *ptr, *environment_strings; + char **envptr; + int count = 1, len; + + DPRINT("BlockEnvToEnvironA()\n"); + + environment_strings = GetEnvironmentStringsA(); + if (environment_strings == NULL) { + return -1; + } + + for (ptr = environment_strings; *ptr; ptr += len) + { + len = strlen(ptr) + 1; + /* Skip drive letter settings. */ + if (*ptr != '=') + count++; + } + + _environ = HeapAlloc(GetProcessHeap(), 0, count * sizeof(char*)); + if (_environ) + { + for (ptr = environment_strings, envptr = _environ; count > 1; ptr += len) + { + len = strlen(ptr) + 1; + /* Skip drive letter settings. */ + if (*ptr != '=') + { + if ((*envptr = malloc(len)) == NULL) + { + for (envptr--; envptr >= _environ; envptr--); + free(*envptr); + FreeEnvironmentStringsA(environment_strings); + HeapFree(GetProcessHeap(), 0, _environ); + return -1; + } + memcpy(*envptr++, ptr, len); + count--; + } + } + /* Add terminating NULL entry. */ + *envptr = NULL; + } + + FreeEnvironmentStringsA(environment_strings); + return _environ ? 0 : -1; +} + +int BlockEnvToEnvironW(void) +{ + wchar_t *ptr, *environment_strings; + wchar_t **envptr; + int count = 1, len; + + DPRINT("BlockEnvToEnvironW()\n"); + + environment_strings = GetEnvironmentStringsW(); + if (environment_strings == NULL) { + return -1; + } + + for (ptr = environment_strings; *ptr; ptr += len) + { + len = wcslen(ptr) + 1; + /* Skip drive letter settings. */ + if (*ptr != '=') + count++; + } + + _wenviron = HeapAlloc(GetProcessHeap(), 0, count * sizeof(wchar_t*)); + if (_wenviron) + { + for (ptr = environment_strings, envptr = _wenviron; count > 1; ptr += len) + { + len = wcslen(ptr) + 1; + /* Skip drive letter settings. */ + if (*ptr != '=') + { + if ((*envptr = malloc(len * sizeof(wchar_t))) == NULL) + { + for (envptr--; envptr >= _wenviron; envptr--); + free(*envptr); + FreeEnvironmentStringsW(environment_strings); + HeapFree(GetProcessHeap(), 0, _wenviron); + return -1; + } + memcpy(*envptr++, ptr, len * sizeof(wchar_t)); + count--; + } + } + /* Add terminating NULL entry. */ + *envptr = NULL; + } + + FreeEnvironmentStringsW(environment_strings); + return _wenviron ? 0 : -1; +} + +/** + * Internal function to duplicate environment block. Although it's + * parameter are defined as char**, it's able to work also with + * wide character environment block which are of type wchar_t**. + * + * @param original_environment + * Environment to duplicate. + * @param wide + * Set to zero for multibyte environments, non-zero otherwise. + * + * @return Original environment in case of failure, otherwise + * pointer to new environment block. + */ +char **DuplicateEnvironment(char **original_environment, int wide) +{ + int count = 1; + char **envptr, **newenvptr, **newenv; + + for (envptr = original_environment; *envptr != NULL; envptr++, count++) + ; + + newenvptr = newenv = HeapAlloc(GetProcessHeap(), 0, count * sizeof(char*)); + if (newenv == NULL) + return original_environment; + + for (envptr = original_environment; count > 1; newenvptr++, count--) + { + if (wide) + *newenvptr = (char*)wcsdup((wchar_t*)*envptr++); + else + *newenvptr = strdup(*envptr++); + if (*newenvptr == NULL) + { + for (newenvptr--; newenvptr >= newenv; newenvptr--); + free(*newenvptr); + HeapFree(GetProcessHeap(), 0, newenv); + return original_environment; + } + } + + return newenv; +} + +/** + * Internal function to deallocate environment block. Although it's + * parameter are defined as char**, it's able to work also with + * wide character environment block which are of type wchar_t**. + * + * @param environment + * Environment to free. + */ +void FreeEnvironment(char **environment) +{ + char **envptr; + for (envptr = environment; *envptr != NULL; envptr++) + free(*envptr); + HeapFree(GetProcessHeap(), 0, environment); +} + +/** + * 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 :-). + */ +int SetEnv(const wchar_t *option) +{ + wchar_t *epos, *name; + wchar_t **wenvptr; + wchar_t *woption; + char *mboption; + int remove, index, count, size, result = 0, found = 0; + + if (option == NULL || (epos = wcschr(option, L'=')) == NULL) + return -1; + remove = (epos[1] == 0); + + /* Duplicate environment if needed. */ + if (_environ == __initenv) + { + if ((_environ = DuplicateEnvironment(_environ, 0)) == __initenv) + return -1; + } + if (_wenviron == __winitenv) + { + if ((_wenviron = (wchar_t**)DuplicateEnvironment((char**)_wenviron, 1)) == + __winitenv) + return -1; + } + + /* Create a copy of the option name. */ + name = malloc(epos - option + 1); + if (name == NULL) + return -1; + memcpy(name, option, (epos - option) * sizeof(wchar_t)); + name[epos - option] = 0; + + /* Find the option we're trying to modify. */ + for (index = 0, wenvptr = _wenviron; *wenvptr != NULL; wenvptr++, index++) + { + if (!wcsnicmp(*wenvptr, option, epos - option)) + { + found = 1; + break; + } + } + + if (remove) + { + if (!found) + { + free(name); + return -1; + } + + /* Remove the option from wide character environment. */ + free(*wenvptr); + for (count = index; *wenvptr != NULL; wenvptr++, count++) + *wenvptr = *(wenvptr + 1); + _wenviron = HeapReAlloc(GetProcessHeap(), 0, _wenviron, + count * sizeof(wchar_t*)); + + /* Remove the option from multibyte environment. We assume + * the environments are in sync and the option is at the + * same position. */ + free(_environ[index]); + for (; _environ[index] != NULL; index++) + _environ[index] = _environ[index + 1]; + _environ = HeapReAlloc(GetProcessHeap(), 0, _environ, + count * sizeof(char*)); + + result = SetEnvironmentVariableW(name, NULL) ? 0 : -1; + } + else + { + /* Make a copy of the option that we will store in the environment block. */ + woption = wcsdup((wchar_t*)option); + if (woption == NULL) + { + free(name); + return -1; + } + + /* Create a multibyte copy of the option. */ + size = WideCharToMultiByte(CP_ACP, 0, option, 0, NULL, 0, NULL, NULL); + mboption = malloc(size); + if (mboption == NULL) + { + free(name); + free(woption); + return -1; + } + WideCharToMultiByte(CP_ACP, 0, option, 0, mboption, size, NULL, NULL); + + if (found) + { + /* Replace the current entry. */ + free(*wenvptr); + *wenvptr = woption; + free(_environ[index]); + _environ[index] = mboption; + } + else + { + wchar_t **wnewenv; + char **mbnewenv; + + /* Get the size of the original environment. */ + for (count = index; *wenvptr != NULL; wenvptr++, count++) + ; + + /* Create a new entry. */ + if ((wnewenv = HeapReAlloc(GetProcessHeap(), 0, _wenviron, + (count + 2) * sizeof(wchar_t*))) == NULL) + { + free(name); + free(mboption); + free(woption); + return -1; + } + _wenviron = wnewenv; + if ((mbnewenv = HeapReAlloc(GetProcessHeap(), 0, _environ, + (count + 2) * sizeof(char*))) == NULL) + { + free(name); + free(mboption); + free(woption); + return -1; + } + _environ = mbnewenv; + + /* Set the last entry to our option. */ + _wenviron[count] = woption; + _environ[count] = mboption; + _wenviron[count + 1] = NULL; + _environ[count + 1] = NULL; + } + + /* And finally update the OS environment. */ + result = SetEnvironmentVariableW(name, epos + 1) ? 0 : -1; + } + free(name); + + return result; +} + /* * @implemented */ @@ -41,79 +355,6 @@ int *__p__commode(void) // not exported by NTDLL return &_commode; } -int BlockEnvToEnviron(void) -{ - char * ptr, * ptr2; - int i, count, len, size; - - DPRINT("BlockEnvToEnviron()\n"); - - ptr2 = ptr = (char*)GetEnvironmentStringsA(); - if (ptr == NULL) { - return -1; - } - - size = 0; - count = 0; - while (*ptr2) { - len = strlen(ptr2); - if (*ptr2 != '=') { - count++; - size += len + 1; - } - ptr2 += len + 1; - } - - if (count != _envvar_count) { - if (_environ && _environ != __initenv) { - free(_environ[0]); - _environ = realloc(_environ, (count + 1) * sizeof(char*)); - } else { - _environ = malloc((count + 1) * sizeof(char*)); - } - if (_environ == NULL) { - FreeEnvironmentStringsA(ptr); - _envvar_count = 0; - return -1; - } - _environ[0] = NULL; - } - if (_environ[0] != NULL) { - free(_environ[0]); - } - - _environ[0] = malloc(size); - if (_environ[0] == NULL) { - FreeEnvironmentStringsA(ptr); - free(_environ); - _envvar_count = 0; - return -1; - } - - ptr2 = ptr; - i = 0; - while (*ptr2 && i < count) { - len = strlen(ptr2); - /* skip current directory of the form "=C:=C:\directory\" */ - if (*ptr2 != '=') { - memcpy(_environ[i], ptr2, len + 1); - i++; - if (i < count) { - _environ[i] = _environ[i - 1] + len + 1; - } - } - ptr2 += len + 1; - } - _environ[i] = NULL; - _envvar_count = count; - if (__initenv == NULL) - { - __initenv = _environ; - } - FreeEnvironmentStringsA(ptr); - return 0; -} - /* * @implemented */ @@ -135,7 +376,15 @@ char **__p__acmdln(void) */ char ***__p__environ(void) { - return _environ_dll; + return &_environ; +} + +/* + * @implemented + */ +wchar_t ***__p__wenviron(void) +{ + return &_wenviron; } /* @@ -146,6 +395,14 @@ char ***__p___initenv(void) return &__initenv; } +/* + * @implemented + */ +wchar_t ***__p___winitenv(void) +{ + return &__winitenv; +} + /* * @implemented */ diff --git a/reactos/lib/msvcrt/misc/getargs.c b/reactos/lib/msvcrt/misc/getargs.c index 9e7d975703a..3a57cea4e74 100644 --- a/reactos/lib/msvcrt/misc/getargs.c +++ b/reactos/lib/msvcrt/misc/getargs.c @@ -12,6 +12,8 @@ extern char**_environ; #undef __argc char**__argv = NULL; +#undef __wargv +wchar_t**__wargv = NULL; int __argc = 0; extern HANDLE hHeap; @@ -21,6 +23,7 @@ char* strndup(char* name, int len) char *s = malloc(len + 1); if (s != NULL) { strncpy(s, name, len); + name[len] = 0; } return s; } @@ -31,14 +34,12 @@ int add(char* name) { char** _new; if ((__argc % SIZE) == 0) { - _new = malloc(sizeof(char*) * (__argc + SIZE)); - if (_new == NULL) { + if (__argv == NULL) + _new = malloc(sizeof(char*) * SIZE); + else + _new = realloc(__argv, sizeof(char*) * (__argc + SIZE)); + if (_new == NULL) return -1; - } - if (__argv) { - memcpy(_new, __argv, sizeof(char*) * __argc); - free(__argv); - } __argv = _new; } __argv[__argc++] = name; @@ -139,6 +140,18 @@ int __getmainargs(int* argc, char*** argv, char*** env, int flag) return 0; } +/* + * @unimplemented + */ +void __wgetmainargs(int* argc, wchar_t*** wargv, wchar_t*** wenv, + int expand_wildcards, int* new_mode) +{ + extern wchar_t **__winitenv; + *argc = 0; + *wargv = NULL; + *wenv = __winitenv; +} + /* * @implemented */ diff --git a/reactos/lib/msvcrt/msvcrt.def b/reactos/lib/msvcrt/msvcrt.def index 6bbe908bc8a..9b9ef8fc5a4 100644 --- a/reactos/lib/msvcrt/msvcrt.def +++ b/reactos/lib/msvcrt/msvcrt.def @@ -1,4 +1,4 @@ -; $Id: msvcrt.def,v 1.35 2004/05/15 12:55:47 jfilby Exp $ +; $Id: msvcrt.def,v 1.36 2004/08/27 03:08:23 navaraf Exp $ ; ; ReactOS MSVCRT Compatibility Library ; @@ -129,7 +129,7 @@ __p___argv __p___wargv __p___initenv __p___mb_cur_max -;__p___winitenv +__p___winitenv __p__acmdln ;__p__amblksiz __p__commode @@ -148,7 +148,7 @@ __p__pwctype ;__p__timezone ;__p__tzname ;__p__wcmdln -;__p__wenviron +__p__wenviron __p__winmajor __p__winminor __p__winver @@ -164,9 +164,9 @@ __toascii __unDName ;__unDNameEx ;__unguarded_readlc_active -;__wargv +__wargv __wgetmainargs -;__winitenv +__winitenv ;___lc_codepage_func ;___lc_handle_func ;___mb_cur_max_func @@ -246,7 +246,6 @@ _dup2 _ecvt _endthread _endthreadex -_environ_dll DATA ;_environ _eof _errno @@ -561,7 +560,7 @@ _waccess _wasctime _wchdir _wchmod -_wcmdln=MSVCRT__wcmdln +_wcmdln _wcreat _wcsdup ;_wcserror diff --git a/reactos/lib/msvcrt/process/_system.c b/reactos/lib/msvcrt/process/_system.c index 4eb0c047ea9..c983bd2de79 100644 --- a/reactos/lib/msvcrt/process/_system.c +++ b/reactos/lib/msvcrt/process/_system.c @@ -1,4 +1,4 @@ -/* $Id: _system.c,v 1.10 2004/08/15 18:16:37 chorns Exp $ +/* $Id: _system.c,v 1.11 2004/08/27 03:08:23 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -39,10 +39,7 @@ int system(const char *command) if (szComSpec == NULL) return 0; else - { - free(szComSpec); return -1; - } } // should return 127 or 0 ( MS ) if the shell is not found diff --git a/reactos/lib/msvcrt/process/process.c b/reactos/lib/msvcrt/process/process.c index 231740cd0b6..8a375430aa3 100644 --- a/reactos/lib/msvcrt/process/process.c +++ b/reactos/lib/msvcrt/process/process.c @@ -85,7 +85,6 @@ const char* find_exec(const char* path, char* rpath) } } } - free(env); } } diff --git a/reactos/lib/msvcrt/stdio/popen.c b/reactos/lib/msvcrt/stdio/popen.c index 7b0753b04b8..5c9b5583877 100644 --- a/reactos/lib/msvcrt/stdio/popen.c +++ b/reactos/lib/msvcrt/stdio/popen.c @@ -30,12 +30,9 @@ FILE *_popen (const char *cm, const char *md) /* program name, pipe mode */ return NULL; szComSpec = getenv("COMSPEC"); - if (szComSpec == NULL) { - szComSpec = strdup("cmd.exe"); - if (szComSpec == NULL) - return NULL; + szComSpec = "cmd.exe"; } s = max(strrchr(szComSpec, '\\'), strrchr(szComSpec, '/')); @@ -47,7 +44,6 @@ FILE *_popen (const char *cm, const char *md) /* program name, pipe mode */ szCmdLine = malloc(strlen(s) + 4 + strlen(cm) + 1); if (szCmdLine == NULL) { - free (szComSpec); return NULL; } @@ -60,7 +56,6 @@ FILE *_popen (const char *cm, const char *md) /* program name, pipe mode */ if ( !CreatePipe(&hReadPipe,&hWritePipe,&sa,1024)) { - free (szComSpec); free (szCmdLine); return NULL; } @@ -87,7 +82,6 @@ FILE *_popen (const char *cm, const char *md) /* program name, pipe mode */ NULL, &StartupInfo, &ProcessInformation); - free (szComSpec); free (szCmdLine); if (result == FALSE) @@ -152,9 +146,7 @@ FILE *_wpopen (const wchar_t *cm, const wchar_t *md) /* program name, pipe mode if (szComSpec == NULL) { - szComSpec = _wcsdup(L"cmd.exe"); - if (szComSpec == NULL) - return NULL; + szComSpec = L"cmd.exe"; } s = max(wcsrchr(szComSpec, L'\\'), wcsrchr(szComSpec, L'/')); @@ -166,7 +158,6 @@ FILE *_wpopen (const wchar_t *cm, const wchar_t *md) /* program name, pipe mode szCmdLine = malloc((wcslen(s) + 4 + wcslen(cm) + 1) * sizeof(wchar_t)); if (szCmdLine == NULL) { - free (szComSpec); return NULL; } @@ -179,7 +170,6 @@ FILE *_wpopen (const wchar_t *cm, const wchar_t *md) /* program name, pipe mode if ( !CreatePipe(&hReadPipe,&hWritePipe,&sa,1024)) { - free (szComSpec); free (szCmdLine); return NULL; } @@ -206,7 +196,6 @@ FILE *_wpopen (const wchar_t *cm, const wchar_t *md) /* program name, pipe mode NULL, &StartupInfo, &ProcessInformation); - free (szComSpec); free (szCmdLine); if (result == FALSE) diff --git a/reactos/lib/msvcrt/stdlib/getenv.c b/reactos/lib/msvcrt/stdlib/getenv.c index a0320fea09b..ba704782643 100644 --- a/reactos/lib/msvcrt/stdlib/getenv.c +++ b/reactos/lib/msvcrt/stdlib/getenv.c @@ -4,23 +4,24 @@ #define NDEBUG #include +#undef environ /* * @implemented */ char *getenv(const char *name) { - char *buffer = (char*)0xffffffff; - int len = GetEnvironmentVariableA(name,buffer,0) + 1; - DPRINT("getenv(%s)\n", name); - buffer = (char *)malloc(len); - DPRINT("getenv('%s') %d %x\n", name, len, buffer); - if (buffer == NULL || GetEnvironmentVariableA(name,buffer,len) == 0 ) - { - free(buffer); - return NULL; - } - return buffer; + char **environ; + unsigned int length = strlen(name); + + for (environ = *__p__environ(); *environ; environ++) + { + char *str = *environ; + char *pos = strchr(str,'='); + if (pos && ((pos - str) == length) && !strnicmp(str, name, length)) + return pos + 1; + } + return NULL; } /* @@ -28,14 +29,15 @@ char *getenv(const char *name) */ wchar_t *_wgetenv(const wchar_t *name) { - wchar_t *buffer = (wchar_t*)0xffffffff; - int len = GetEnvironmentVariableW(name, buffer,0) + 1; - DPRINT("_wgetenv(%S)\n", name); - buffer = (wchar_t *)malloc(len * sizeof(wchar_t)); - if (buffer == NULL || GetEnvironmentVariableW(name,buffer,len) == 0) - { - free(buffer); - return NULL; - } - return buffer; + wchar_t **environ; + unsigned int length = wcslen(name); + + for (environ = *__p__wenviron(); *environ; environ++) + { + wchar_t *str = *environ; + wchar_t *pos = wcschr(str, L'='); + if (pos && ((pos - str) == length) && !wcsnicmp(str, name, length)) + return pos + 1; + } + return NULL; } diff --git a/reactos/lib/msvcrt/stdlib/malloc.c b/reactos/lib/msvcrt/stdlib/malloc.c index e89024932ee..95e715ae76f 100644 --- a/reactos/lib/msvcrt/stdlib/malloc.c +++ b/reactos/lib/msvcrt/stdlib/malloc.c @@ -56,6 +56,8 @@ void* calloc(size_t _nmemb, size_t _size) */ void* realloc(void* _ptr, size_t _size) { + if (!_ptr) + return HeapAlloc(hHeap, 0, _size); return HeapReAlloc(hHeap, 0, _ptr, _size); } diff --git a/reactos/lib/msvcrt/stdlib/putenv.c b/reactos/lib/msvcrt/stdlib/putenv.c index 1ecab513895..aa7a7480cb0 100644 --- a/reactos/lib/msvcrt/stdlib/putenv.c +++ b/reactos/lib/msvcrt/stdlib/putenv.c @@ -5,30 +5,23 @@ #define NDEBUG #include - -extern int BlockEnvToEnviron(); // defined in misc/dllmain.c +/* misc/environ.c */ +int SetEnv(const wchar_t *option); /* * @implemented */ int _putenv(const char* val) { - char* buffer; - char* epos; - int res; - - DPRINT("_putenv('%s')\n", val); - epos = strchr(val, '='); - if ( epos == NULL ) - return -1; - buffer = (char*)malloc(epos - val + 1); - if (buffer == NULL) - return -1; - strncpy(buffer, val, epos - val); - buffer[epos - val] = 0; - res = SetEnvironmentVariableA(buffer, epos+1); - free(buffer); - if (BlockEnvToEnviron()) - return 0; - return res; + int size, result; + wchar_t *woption; + + size = MultiByteToWideChar(CP_ACP, 0, val, 0, NULL, 0); + woption = malloc(size); + if (woption == NULL) + return -1; + MultiByteToWideChar(CP_ACP, 0, val, 0, woption, size); + result = SetEnv(woption); + free(woption); + return result; } diff --git a/reactos/lib/msvcrt/stdlib/wputenv.c b/reactos/lib/msvcrt/stdlib/wputenv.c index f1ddbebaee6..8b34b510a96 100644 --- a/reactos/lib/msvcrt/stdlib/wputenv.c +++ b/reactos/lib/msvcrt/stdlib/wputenv.c @@ -5,30 +5,13 @@ #define NDEBUG #include - -extern int BlockEnvToEnviron(); // defined in misc/dllmain.c +/* misc/environ.c */ +int SetEnv(const wchar_t *option); /* * @implemented */ int _wputenv(const wchar_t* val) { - wchar_t* buffer; - wchar_t* epos; - int res; - - DPRINT("_wputenv('%S')\n", val); - epos = wcsrchr(val, L'='); - if (epos == NULL) - return -1; - buffer = (wchar_t*)malloc((epos - val + 1) * sizeof(wchar_t)); - if (buffer == NULL) - return -1; - wcsncpy(buffer, val, epos - val); - buffer[epos - val] = 0; - res = SetEnvironmentVariableW(buffer, epos+1); - free(buffer); - if (BlockEnvToEnviron()) - return 0; - return res; + return SetEnv(val); } diff --git a/reactos/lib/msvcrt/wine/data.c b/reactos/lib/msvcrt/wine/data.c deleted file mode 100644 index 676c8e88cd2..00000000000 --- a/reactos/lib/msvcrt/wine/data.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * msvcrt.dll dll data items - * - * Copyright 2000 Jon Griffiths - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include "msvcrt.h" - -#include "stdlib.h" -#include "string.h" - -//#include "wine/library.h" -#include "wine/unicode.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); - -unsigned int MSVCRT___argc; -unsigned int MSVCRT_basemajor;/* FIXME: */ -unsigned int MSVCRT_baseminor;/* FIXME: */ -unsigned int MSVCRT_baseversion; /* FIXME: */ -unsigned int MSVCRT__commode; -unsigned int MSVCRT__fmode; -unsigned int MSVCRT_osmajor;/* FIXME: */ -unsigned int MSVCRT_osminor;/* FIXME: */ -unsigned int MSVCRT_osmode;/* FIXME: */ -unsigned int MSVCRT__osver; -unsigned int MSVCRT_osversion; /* FIXME: */ -unsigned int MSVCRT__winmajor; -unsigned int MSVCRT__winminor; -unsigned int MSVCRT__winver; -unsigned int MSVCRT__sys_nerr; /* FIXME: not accessible from Winelib apps */ -char** MSVCRT__sys_errlist; /* FIXME: not accessible from Winelib apps */ -unsigned int MSVCRT___setlc_active; -unsigned int MSVCRT___unguarded_readlc_active; -double MSVCRT__HUGE; -char **MSVCRT___argv; -MSVCRT_wchar_t **MSVCRT___wargv; -char *MSVCRT__acmdln; -MSVCRT_wchar_t *MSVCRT__wcmdln; -char **MSVCRT__environ = 0; -MSVCRT_wchar_t **MSVCRT__wenviron = 0; -char **MSVCRT___initenv = 0; -MSVCRT_wchar_t **MSVCRT___winitenv = 0; -int MSVCRT_timezone; -int MSVCRT_app_type; -char* MSVCRT__pgmptr = 0; -WCHAR* MSVCRT__wpgmptr = 0; - -/* Get a snapshot of the current environment - * and construct the __p__environ array - * - * The pointer returned from GetEnvironmentStrings may get invalid when - * some other module cause a reallocation of the env-variable block - * - * blk is an array of pointers to environment strings, ending with a NULL - * and after that the actual copy of the environment strings, ending in a \0 - */ -char ** msvcrt_SnapshotOfEnvironmentA(char **blk) -{ - char* environ_strings = GetEnvironmentStringsA(); - int count = 1, len = 1, i = 0; /* keep space for the trailing NULLS */ - char *ptr; - - for (ptr = environ_strings; *ptr; ptr += strlen(ptr) + 1) - { - count++; - len += strlen(ptr) + 1; - } - if (blk) - blk = HeapReAlloc( GetProcessHeap(), 0, blk, count* sizeof(char*) + len ); - else - blk = HeapAlloc(GetProcessHeap(), 0, count* sizeof(char*) + len ); - - if (blk) - { - if (count) - { - memcpy(&blk[count],environ_strings,len); - for (ptr = (char*) &blk[count]; *ptr; ptr += strlen(ptr) + 1) - { - blk[i++] = ptr; - } - } - blk[i] = NULL; - } - FreeEnvironmentStringsA(environ_strings); - return blk; -} - -MSVCRT_wchar_t ** msvcrt_SnapshotOfEnvironmentW(MSVCRT_wchar_t **wblk) -{ - MSVCRT_wchar_t* wenviron_strings = GetEnvironmentStringsW(); - int count = 1, len = 1, i = 0; /* keep space for the trailing NULLS */ - MSVCRT_wchar_t *wptr; - - for (wptr = wenviron_strings; *wptr; wptr += strlenW(wptr) + 1) - { - count++; - len += strlenW(wptr) + 1; - } - if (wblk) - wblk = HeapReAlloc( GetProcessHeap(), 0, wblk, count* sizeof(MSVCRT_wchar_t*) + len * sizeof(MSVCRT_wchar_t)); - else - wblk = HeapAlloc(GetProcessHeap(), 0, count* sizeof(MSVCRT_wchar_t*) + len * sizeof(MSVCRT_wchar_t)); - if (wblk) - { - if (count) - { - memcpy(&wblk[count],wenviron_strings,len * sizeof(MSVCRT_wchar_t)); - for (wptr = (MSVCRT_wchar_t*)&wblk[count]; *wptr; wptr += strlenW(wptr) + 1) - { - wblk[i++] = wptr; - } - } - wblk[i] = NULL; - } - FreeEnvironmentStringsW(wenviron_strings); - return wblk; -} - -typedef void (*_INITTERMFUN)(void); -#ifndef __REACTOS__ -/*********************************************************************** - * __p___argc (MSVCRT.@) - */ -int* __p___argc(void) { return &MSVCRT___argc; } - -/*********************************************************************** - * __p__commode (MSVCRT.@) - */ -unsigned int* __p__commode(void) { return &MSVCRT__commode; } - -/*********************************************************************** - * __p__pgmptr (MSVCRT.@) - */ -char** __p__pgmptr(void) { return &MSVCRT__pgmptr; } - -/*********************************************************************** - * __p__wpgmptr (MSVCRT.@) - */ -WCHAR** __p__wpgmptr(void) { return &MSVCRT__wpgmptr; } - -/*********************************************************************** - * __p__fmode (MSVCRT.@) - */ -unsigned int* __p__fmode(void) { return &MSVCRT__fmode; } - -/*********************************************************************** - * __p__osver (MSVCRT.@) - */ -unsigned int* __p__osver(void) { return &MSVCRT__osver; } - -/*********************************************************************** - * __p__winmajor (MSVCRT.@) - */ -unsigned int* __p__winmajor(void) { return &MSVCRT__winmajor; } - -/*********************************************************************** - * __p__winminor (MSVCRT.@) - */ -unsigned int* __p__winminor(void) { return &MSVCRT__winminor; } - -/*********************************************************************** - * __p__winver (MSVCRT.@) - */ -unsigned int* __p__winver(void) { return &MSVCRT__winver; } - -/********************************************************************* - * __p__acmdln (MSVCRT.@) - */ -char** __p__acmdln(void) { return &MSVCRT__acmdln; } - -/********************************************************************* - * __p__wcmdln (MSVCRT.@) - */ -MSVCRT_wchar_t** __p__wcmdln(void) { return &MSVCRT__wcmdln; } - -/********************************************************************* - * __p___argv (MSVCRT.@) - */ -char*** __p___argv(void) { return &MSVCRT___argv; } - -/********************************************************************* - * __p___wargv (MSVCRT.@) - */ -MSVCRT_wchar_t*** __p___wargv(void) { return &MSVCRT___wargv; } - -/********************************************************************* - * __p__environ (MSVCRT.@) - */ -char*** __p__environ(void) -{ - if (!MSVCRT__environ) - MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(NULL); - return &MSVCRT__environ; -} - -/********************************************************************* - * __p__wenviron (MSVCRT.@) - */ -MSVCRT_wchar_t*** __p__wenviron(void) -{ - if (!MSVCRT__wenviron) - MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(NULL); - return &MSVCRT__wenviron; -} - -/********************************************************************* - * __p___initenv (MSVCRT.@) - */ -char*** __p___initenv(void) { return &MSVCRT___initenv; } - -/********************************************************************* - * __p___winitenv (MSVCRT.@) - */ -MSVCRT_wchar_t*** __p___winitenv(void) { return &MSVCRT___winitenv; } - -/********************************************************************* - * __p__timezone (MSVCRT.@) - */ -int* __p__timezone(void) { return &MSVCRT_timezone; } -#endif -/* INTERNAL: Create a wide string from an ascii string */ -static MSVCRT_wchar_t *wstrdupa(const char *str) -{ - const size_t len = strlen(str) + 1 ; - MSVCRT_wchar_t *wstr = malloc(len* sizeof (MSVCRT_wchar_t)); - if (!wstr) - return NULL; - MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,str,len,wstr,len); - return wstr; -} - -/* INTERNAL: Since we can't rely on Winelib startup code calling w/getmainargs, - * we initialise data values during DLL loading. When called by a native - * program we simply return the data we've already initialised. This also means - * you can call multiple times without leaking - */ -void msvcrt_init_args(void) -{ - DWORD version; - - MSVCRT__acmdln = _strdup( GetCommandLineA() ); - MSVCRT__wcmdln = wstrdupa(MSVCRT__acmdln); - //MSVCRT___argc = __wine_main_argc; - //MSVCRT___argv = __wine_main_argv; - //MSVCRT___wargv = __wine_main_wargv; - - TRACE("got '%s', wide = %s argc=%d\n", MSVCRT__acmdln, - debugstr_w(MSVCRT__wcmdln),MSVCRT___argc); - - version = GetVersion(); - MSVCRT__osver = version >> 16; - MSVCRT__winminor = version & 0xFF; - MSVCRT__winmajor = (version>>8) & 0xFF; - MSVCRT_baseversion = version >> 16; - MSVCRT__winver = ((version >> 8) & 0xFF) + ((version & 0xFF) << 8); - MSVCRT_baseminor = (version >> 16) & 0xFF; - MSVCRT_basemajor = (version >> 24) & 0xFF; - MSVCRT_osversion = version & 0xFFFF; - MSVCRT_osminor = version & 0xFF; - MSVCRT_osmajor = (version>>8) & 0xFF; - MSVCRT__sys_nerr = 43; - MSVCRT__HUGE = HUGE_VAL; - MSVCRT___setlc_active = 0; - MSVCRT___unguarded_readlc_active = 0; - MSVCRT_timezone = 0; - - MSVCRT___initenv= msvcrt_SnapshotOfEnvironmentA(NULL); - MSVCRT___winitenv= msvcrt_SnapshotOfEnvironmentW(NULL); - - MSVCRT__pgmptr = HeapAlloc(GetProcessHeap(), 0, MAX_PATH); - if (MSVCRT__pgmptr) - GetModuleFileNameA(0, MSVCRT__pgmptr, MAX_PATH); - - MSVCRT__wpgmptr = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR)); - if (MSVCRT__wpgmptr) - GetModuleFileNameW(0, MSVCRT__wpgmptr, MAX_PATH); -} - - -/* INTERNAL: free memory used by args */ -void msvcrt_free_args(void) -{ - /* FIXME: more things to free */ - if (MSVCRT___initenv) HeapFree(GetProcessHeap(), 0, MSVCRT___initenv); - if (MSVCRT___winitenv) HeapFree(GetProcessHeap(), 0, MSVCRT___winitenv); - if (MSVCRT__environ) HeapFree(GetProcessHeap(), 0, MSVCRT__environ); - if (MSVCRT__wenviron) HeapFree(GetProcessHeap(), 0, MSVCRT__wenviron); - if (MSVCRT__pgmptr) HeapFree(GetProcessHeap(), 0, MSVCRT__pgmptr); - if (MSVCRT__wpgmptr) HeapFree(GetProcessHeap(), 0, MSVCRT__wpgmptr); -} -#ifndef __REACTOS__ -/********************************************************************* - * __getmainargs (MSVCRT.@) - */ -void __getmainargs(int *argc, char** *argv, char** *envp, - int expand_wildcards, int *new_mode) -{ - TRACE("(%p,%p,%p,%d,%p).\n", argc, argv, envp, expand_wildcards, new_mode); - *argc = MSVCRT___argc; - *argv = MSVCRT___argv; - *envp = MSVCRT___initenv; - if (new_mode) - MSVCRT__set_new_mode( *new_mode ); -} -#endif -/********************************************************************* - * __wgetmainargs (MSVCRT.@) - */ -void __wgetmainargs(int *argc, MSVCRT_wchar_t** *wargv, MSVCRT_wchar_t** *wenvp, - int expand_wildcards, int *new_mode) -{ - TRACE("(%p,%p,%p,%d,%p).\n", argc, wargv, wenvp, expand_wildcards, new_mode); - *argc = MSVCRT___argc; - *wargv = MSVCRT___wargv; - *wenvp = MSVCRT___winitenv; - if (new_mode) - MSVCRT__set_new_mode( *new_mode ); -} -#ifndef __REACTOS__ -/********************************************************************* - * _initterm (MSVCRT.@) - */ -unsigned int _initterm(_INITTERMFUN *start,_INITTERMFUN *end) -{ - _INITTERMFUN* current = start; - - TRACE("(%p,%p)\n",start,end); - while (current