- Complete rewrite of environment variable handling to get rid of memory leaks, heap...
authorFilip Navara <filip.navara@gmail.com>
Fri, 27 Aug 2004 03:08:23 +0000 (03:08 +0000)
committerFilip Navara <filip.navara@gmail.com>
Fri, 27 Aug 2004 03:08:23 +0000 (03:08 +0000)
- Remove some ancient Wine stuff that either wasn't used or didn't work.
- Fix realloc to not call HeapReAlloc for allocating new memory.

svn path=/trunk/; revision=10703

13 files changed:
reactos/lib/msvcrt/Makefile
reactos/lib/msvcrt/misc/dllmain.c
reactos/lib/msvcrt/misc/environ.c
reactos/lib/msvcrt/misc/getargs.c
reactos/lib/msvcrt/msvcrt.def
reactos/lib/msvcrt/process/_system.c
reactos/lib/msvcrt/process/process.c
reactos/lib/msvcrt/stdio/popen.c
reactos/lib/msvcrt/stdlib/getenv.c
reactos/lib/msvcrt/stdlib/malloc.c
reactos/lib/msvcrt/stdlib/putenv.c
reactos/lib/msvcrt/stdlib/wputenv.c
reactos/lib/msvcrt/wine/data.c [deleted file]

index 27619dc..17b8c79 100644 (file)
@@ -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 \
index f9ceeaa..61f9356 100644 (file)
@@ -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 $
  *
  */
 
 
 //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);
 
index c6670d8..3e63fd6 100644 (file)
@@ -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
  */
index 9e7d975..3a57cea 100644 (file)
@@ -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
  */
index 6bbe908..9b9ef8f 100644 (file)
@@ -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
index 4eb0c04..c983bd2 100644 (file)
@@ -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
index 231740c..8a37543 100644 (file)
@@ -85,7 +85,6 @@ const char* find_exec(const char* path, char* rpath)
                  }
               }
            }
-           free(env);
        }
     }
     
index 7b0753b..5c9b558 100644 (file)
@@ -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)
index a0320fe..ba70478 100644 (file)
@@ -4,23 +4,24 @@
 #define NDEBUG
 #include <msvcrt/msvcrtdbg.h>
 
+#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;
 }
index e890249..95e715a 100644 (file)
@@ -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);
 }
 
index 1ecab51..aa7a748 100644 (file)
@@ -5,30 +5,23 @@
 #define NDEBUG
 #include <msvcrt/msvcrtdbg.h>
 
-
-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;
 }
index f1ddbeb..8b34b51 100644 (file)
@@ -5,30 +5,13 @@
 #define NDEBUG
 #include <msvcrt/msvcrtdbg.h>
 
-
-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 (file)
index 676c8e8..0000000
+++ /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 <math.h>
-#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<end)
-  {
-    if (*current)
-    {
-      TRACE("Call init function %p\n",*current);
-      (**current)();
-      TRACE("returned\n");
-    }
-    current++;
-  }
-  return 0;
-}
-#endif
-/*********************************************************************
- *             __set_app_type (MSVCRT.@)
- */
-void MSVCRT___set_app_type(int app_type)
-{
-  TRACE("(%d) %s application\n", app_type, app_type == 2 ? "Gui" : "Console");
-  MSVCRT_app_type = app_type;
-}