Index: trunk/src/kernel32/KERNEL32.CPP
===================================================================
--- trunk/src/kernel32/KERNEL32.CPP	(revision 2041)
+++ trunk/src/kernel32/KERNEL32.CPP	(revision 2042)
@@ -1,3 +1,3 @@
-/* $Id: KERNEL32.CPP,v 1.37 1999-11-30 20:19:34 sandervl Exp $ */
+/* $Id: KERNEL32.CPP,v 1.38 1999-12-09 11:00:40 sandervl Exp $ */
 
 /*
@@ -175,52 +175,4 @@
   dprintf(("KERNEL32:  GetACP\n"));
   return(O32_GetACP());
-}
-//******************************************************************************
-//******************************************************************************
-//******************************************************************************
-//******************************************************************************
-LPWSTR WIN32API GetEnvironmentStringsW(VOID)
-{
- char *envstrings = (char *)O32_GetEnvironmentStrings();
- char *tmp;
- LPWSTR wenvstrings;
- int len, i;
-
-  dprintf(("KERNEL32:  GetEnvironmentStringsW\n"));
-
-  if(envstrings == NULL)
-    return(NULL);
-
-  tmp = envstrings;
-  len = 0;
-  while(*tmp != 0)
-  {
-    len += strlen(tmp)+1;
-    tmp = envstrings + len;
-  }
-  len++;        //terminating 0
-  wenvstrings = (LPWSTR)malloc(len*sizeof(WCHAR));
-  for(i=0;
-      i<len;
-      i++)
-  {
-     wenvstrings[i] = envstrings[i];
-  }
-  return(wenvstrings);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API FreeEnvironmentStringsA(LPSTR envstrings)
-{
-  dprintf(("KERNEL32:  FreeEnvironmentStringsA\n"));
-  return(TRUE);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API FreeEnvironmentStringsW(LPWSTR envstrings)
-{
-  dprintf(("KERNEL32:  FreeEnvironmentStringsW\n"));
-  free(envstrings);
-  return(TRUE);
 }
 //******************************************************************************
@@ -314,26 +266,4 @@
 }
 //******************************************************************************
-//******************************************************************************
-BOOL WIN32API SetEnvironmentVariableA(LPCSTR arg1, LPCSTR arg2)
-{
-    dprintf(("KERNEL32:  SetEnvironmentVariable %s to %s\n", arg1, arg2));
-    return O32_SetEnvironmentVariable(arg1, arg2);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue)
-{
- char *asciiname, *asciivalue;
- BOOL  rc;
-
-    dprintf(("KERNEL32:  OS2SetEnvironmentVariableW\n"));
-    asciiname  = UnicodeToAsciiString((LPWSTR)lpName);
-    asciivalue = UnicodeToAsciiString((LPWSTR)lpValue);
-    rc = O32_SetEnvironmentVariable(asciiname, asciivalue);
-    FreeAsciiString(asciivalue);
-    FreeAsciiString(asciiname);
-    return(rc);
-}
-//******************************************************************************
 VOID WIN32API GlobalMemoryStatus( MEMORYSTATUS *arg1)
 {
@@ -348,30 +278,4 @@
     dprintf(("dwAvailVirtual  %X\n", arg1->dwAvailVirtual));
 }
-//******************************************************************************
-//******************************************************************************
-DWORD WIN32API GetEnvironmentVariableA(LPCSTR arg1, LPSTR arg2, DWORD  arg3)
-{
-    dprintf(("KERNEL32:  GetEnvironmentVariable %s\n", arg1));
-    return O32_GetEnvironmentVariable(arg1, arg2, arg3);
-}
-//******************************************************************************
-//******************************************************************************
-DWORD WIN32API GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer,
-                                       DWORD nSize)
-{
-  char *astring, *asciibuffer;
-  DWORD rc;
-
-    dprintf(("KERNEL32:  OS2GetEnvironmentVariableW\n"));
-    asciibuffer = (char *)malloc(nSize+1);
-    *asciibuffer = 0;
-    astring     = UnicodeToAsciiString((LPWSTR)lpName);
-
-    rc = O32_GetEnvironmentVariable(astring, asciibuffer, nSize);
-    AsciiToUnicode(asciibuffer, lpBuffer);
-    FreeAsciiString(astring);
-    free(asciibuffer);
-    return(rc);
-}
 VOID WIN32API Sleep(DWORD arg1)
 {
@@ -464,11 +368,4 @@
     dprintf(("KERNEL32:  OS2FatalExit\n"));
     O32_FatalExit(arg1);
-}
-//******************************************************************************
-//******************************************************************************
-LPSTR WIN32API GetEnvironmentStringsA(void)
-{
-    dprintf(("KERNEL32:  OS2GetEnvironmentStringsA\n"));
-    return (LPSTR) O32_GetEnvironmentStrings();
 }
 //******************************************************************************
Index: trunk/src/kernel32/environ.cpp
===================================================================
--- trunk/src/kernel32/environ.cpp	(revision 2042)
+++ trunk/src/kernel32/environ.cpp	(revision 2042)
@@ -0,0 +1,268 @@
+/* $Id: environ.cpp,v 1.1 1999-12-09 11:01:09 sandervl Exp $ */
+
+/*
+ * Win32 environment file functions for OS/2
+ *
+ * Copyright 1998 Sander van Leeuwen
+ * Copyright 1998 Patrick Haller
+ * Copyright 1998 Peter Fitzsimmons
+ * Copyright 1998 Knut St. Osmundsen
+ *
+ * Parts based on Wine code (ExpandEnvironmentStringsA/W)
+ * (memory\environ.c; 991114)
+ *
+ * Copyright 1996, 1998 Alexandre Julliard
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#include <odin.h>
+#include <odinwrap.h>
+#include <os2sel.h>
+
+#include <os2win.h>
+#include <winnt.h>
+#include <winnls.h>
+#include <stdlib.h>
+#include <string.h>
+#include <heapstring.h>
+
+#include <misc.h>
+
+//******************************************************************************
+//******************************************************************************
+LPSTR WIN32API GetEnvironmentStringsA(void)
+{
+    dprintf(("KERNEL32:  OS2GetEnvironmentStringsA\n"));
+    return (LPSTR) O32_GetEnvironmentStrings();
+}
+//******************************************************************************
+//******************************************************************************
+LPWSTR WIN32API GetEnvironmentStringsW(VOID)
+{
+ char *envstrings = (char *)O32_GetEnvironmentStrings();
+ char *tmp;
+ LPWSTR wenvstrings;
+ int len, i;
+
+  dprintf(("KERNEL32:  GetEnvironmentStringsW\n"));
+
+  if(envstrings == NULL)
+    return(NULL);
+
+  tmp = envstrings;
+  len = 0;
+  while(*tmp != 0)
+  {
+    len += strlen(tmp)+1;
+    tmp = envstrings + len;
+  }
+  len++;        //terminating 0
+  wenvstrings = (LPWSTR)malloc(len*sizeof(WCHAR));
+  for(i=0;
+      i<len;
+      i++)
+  {
+     wenvstrings[i] = envstrings[i];
+  }
+  return(wenvstrings);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API FreeEnvironmentStringsA(LPSTR envstrings)
+{
+  dprintf(("KERNEL32:  FreeEnvironmentStringsA\n"));
+  return(TRUE);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API FreeEnvironmentStringsW(LPWSTR envstrings)
+{
+  dprintf(("KERNEL32:  FreeEnvironmentStringsW\n"));
+  free(envstrings);
+  return(TRUE);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API SetEnvironmentVariableA(LPCSTR arg1, LPCSTR arg2)
+{
+    dprintf(("KERNEL32:  SetEnvironmentVariable %s to %s\n", arg1, arg2));
+    return O32_SetEnvironmentVariable(arg1, arg2);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue)
+{
+ char *asciiname, *asciivalue;
+ BOOL  rc;
+
+    dprintf(("KERNEL32:  OS2SetEnvironmentVariableW\n"));
+    asciiname  = UnicodeToAsciiString((LPWSTR)lpName);
+    asciivalue = UnicodeToAsciiString((LPWSTR)lpValue);
+    rc = O32_SetEnvironmentVariable(asciiname, asciivalue);
+    FreeAsciiString(asciivalue);
+    FreeAsciiString(asciiname);
+    return(rc);
+}
+//******************************************************************************
+//******************************************************************************
+DWORD WIN32API GetEnvironmentVariableA(LPCSTR arg1, LPSTR arg2, DWORD  arg3)
+{
+    dprintf(("KERNEL32:  GetEnvironmentVariable %s\n", arg1));
+    return O32_GetEnvironmentVariable(arg1, arg2, arg3);
+}
+//******************************************************************************
+//******************************************************************************
+DWORD WIN32API GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer,
+                                       DWORD nSize)
+{
+  char *astring, *asciibuffer;
+  DWORD rc;
+
+    dprintf(("KERNEL32:  OS2GetEnvironmentVariableW\n"));
+    asciibuffer = (char *)malloc(nSize+1);
+    *asciibuffer = 0;
+    astring     = UnicodeToAsciiString((LPWSTR)lpName);
+
+    rc = O32_GetEnvironmentVariable(astring, asciibuffer, nSize);
+    AsciiToUnicode(asciibuffer, lpBuffer);
+    FreeAsciiString(astring);
+    free(asciibuffer);
+    return(rc);
+}
+/***********************************************************************
+ *           ENV_FindVariable
+ *
+ * Find a variable in the environment and return a pointer to the value.
+ * Helper function for GetEnvironmentVariable and ExpandEnvironmentStrings.
+ */
+static LPCSTR ENV_FindVariable( LPCSTR env, LPCSTR name, INT len )
+{
+    while (*env)
+    {
+        if (!lstrncmpiA( name, env, len ) && (env[len] == '='))
+            return env + len + 1;
+        env += strlen(env) + 1;
+    }
+    return NULL;
+}
+/*****************************************************************************
+ * Name      : DWORD WIN32API ExpandEnvironmentStringsA
+ * Purpose   : The ExpandEnvironmentStringsA function expands environment-variable
+ *             strings and replaces them with their defined values.
+ * Parameters: LPCSTR lpSrc  pointer to string with environment variables
+ *             LPSTR lpDst   pointer to string with expanded environment variables
+ *             DWORD nSize   maximum characters in expanded string
+ * Variables :
+ * Result    : If the function succeeds, the return value is the number of
+ *             characters stored in the destination buffer. If the number of
+ *             characters is greater than the size of the destination buffer,
+ *             the return value is the size of the buffer required to hold
+ *             the expanded strings.
+ *             If the function fails, the return value is zero
+ * Remark    :
+ * Status    : 
+ *
+ *****************************************************************************/
+
+DWORD WIN32API ExpandEnvironmentStringsA( LPCSTR src, LPSTR dst, DWORD count )
+{
+    DWORD len, total_size = 1;  /* 1 for terminating '\0' */
+    LPCSTR p, var;
+
+    dprintf(("KERNEL32:ExpandEnvironmentStringsA(%08x,%08x,%08x) not implemented\n",
+              src, dst, count
+              ));
+
+    if (!count) dst = NULL;
+
+    while (*src)
+    {
+        if (*src != '%')
+        {
+            if ((p = strchr( src, '%' ))) len = p - src;
+            else len = strlen(src);
+            var = src;
+            src += len;
+        }
+        else  /* we are at the start of a variable */
+        {
+            if ((p = strchr( src + 1, '%' )))
+            {
+                len = p - src - 1;  /* Length of the variable name */	
+                if ((var = ENV_FindVariable( GetEnvironmentStringsA(),
+                                             src + 1, len )))
+                {
+                    src += len + 2;  /* Skip the variable name */
+                    len = strlen(var);
+                }
+                else
+                {
+                    var = src;  /* Copy original name instead */
+                    len += 2;
+                    src += len;
+                }
+            }
+            else  /* unfinished variable name, ignore it */
+            {
+                var = src;
+                len = strlen(src);  /* Copy whole string */
+                src += len;
+            }
+        }
+        total_size += len;
+        if (dst)
+        {
+            if (count < len) len = count;
+            memcpy( dst, var, len );
+            dst += len;
+            count -= len;
+        }
+    }
+
+    /* Null-terminate the string */
+    if (dst)
+    {
+        if (!count) dst--;
+        *dst = '\0';
+    }
+    return total_size;
+}
+
+/*****************************************************************************
+ * Name      : DWORD WIN32API ExpandEnvironmentStringsW
+ * Purpose   : The ExpandEnvironmentStringsA function expands environment-variable
+ *             strings and replaces them with their defined values.
+ * Parameters: LPCWSTR lpSrc  pointer to string with environment variables
+ *             LPWSTR lpDst   pointer to string with expanded environment variables
+ *             DWORD nSize   maximum characters in expanded string
+ * Variables :
+ * Result    : If the function succeeds, the return value is the number of
+ *             characters stored in the destination buffer. If the number of
+ *             characters is greater than the size of the destination buffer,
+ *             the return value is the size of the buffer required to hold
+ *             the expanded strings.
+ *             If the function fails, the return value is zero
+ * Remark    :
+ * Status    : 
+ *
+ *****************************************************************************/
+
+DWORD WIN32API ExpandEnvironmentStringsW(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize)
+{
+    LPSTR srcA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpSrc );
+    LPSTR dstA = lpDst ? (LPSTR)HeapAlloc( GetProcessHeap(), 0, nSize ) : NULL;
+
+    dprintf(("KERNEL32:ExpandEnvironmentStringsW(%08x,%08x,%08x)", lpSrc, lpDst, nSize));
+
+    DWORD ret  = ExpandEnvironmentStringsA( srcA, dstA, nSize );
+    if (dstA)
+    {
+        lstrcpyAtoW( lpDst, dstA );
+        HeapFree( GetProcessHeap(), 0, dstA );
+    }
+    HeapFree( GetProcessHeap(), 0, srcA );
+    return ret;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/kernel32/makefile
===================================================================
--- trunk/src/kernel32/makefile	(revision 2041)
+++ trunk/src/kernel32/makefile	(revision 2042)
@@ -1,3 +1,3 @@
-# $Id: makefile,v 1.67 1999-12-09 00:52:20 sandervl Exp $
+# $Id: makefile,v 1.68 1999-12-09 11:00:40 sandervl Exp $
 
 #
@@ -35,5 +35,5 @@
 LFILE.OBJ NPIPE.OBJ oslibdos.obj oslibmisc.obj MISC.OBJ EXCEPTUTIL.OBJ \
 LANG.OBJ ICCIO.OBJ MAP.OBJ WIN32UTIL.OBJ heap.OBJ heapstring.obj \
-os2heap.OBJ vmutex.OBJ initterm.OBJ handlemanager.OBJ  \
+os2heap.OBJ vmutex.OBJ initterm.OBJ handlemanager.OBJ environ.obj \
 hmdevice.obj hmopen32.obj hmobjects.obj hmevent.obj hmmutex.obj hmcomm.obj \
 hmsemaphore.obj wprocess.OBJ conprop.OBJ conprop2.obj winimagelx.obj \
@@ -390,4 +390,5 @@
 cpu.obj: cpu.cpp cpuhlp.h
 cpuhlp.obj: cpuhlp.asm
+environ.obj: environ.cpp $(PDWIN32_INCLUDE)\misc.h
 
 clean:
Index: trunk/src/kernel32/stubs.cpp
===================================================================
--- trunk/src/kernel32/stubs.cpp	(revision 2041)
+++ trunk/src/kernel32/stubs.cpp	(revision 2042)
@@ -1,3 +1,3 @@
-/* $Id: stubs.cpp,v 1.11 1999-12-01 18:40:48 sandervl Exp $ */
+/* $Id: stubs.cpp,v 1.12 1999-12-09 11:00:40 sandervl Exp $ */
 
 /*
@@ -1547,65 +1547,4 @@
 }
 
-/*****************************************************************************
- * Name      : DWORD WIN32API ExpandEnvironmentStringsA
- * Purpose   : The ExpandEnvironmentStringsA function expands environment-variable
- *             strings and replaces them with their defined values.
- * Parameters: LPCSTR lpSrc  pointer to string with environment variables
- *             LPSTR lpDst   pointer to string with expanded environment variables
- *             DWORD nSize   maximum characters in expanded string
- * Variables :
- * Result    : If the function succeeds, the return value is the number of
- *             characters stored in the destination buffer. If the number of
- *             characters is greater than the size of the destination buffer,
- *             the return value is the size of the buffer required to hold
- *             the expanded strings.
- *             If the function fails, the return value is zero
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Markus Montkowski [Tha, 1998/05/21 20:57]
- *****************************************************************************/
-
-DWORD WIN32API ExpandEnvironmentStringsA(LPCSTR lpSrc,LPSTR lpDst,DWORD nSize)
-{
-
-  dprintf(("KERNEL32:ExpandEnvironmentStringsA(%08x,%08x,%08x) not implemented\n",
-           lpSrc, lpDst, nSize
-          ));
-
-  return (0);
-}
-
-/*****************************************************************************
- * Name      : DWORD WIN32API ExpandEnvironmentStringsW
- * Purpose   : The ExpandEnvironmentStringsA function expands environment-variable
- *             strings and replaces them with their defined values.
- * Parameters: LPCWSTR lpSrc  pointer to string with environment variables
- *             LPWSTR lpDst   pointer to string with expanded environment variables
- *             DWORD nSize   maximum characters in expanded string
- * Variables :
- * Result    : If the function succeeds, the return value is the number of
- *             characters stored in the destination buffer. If the number of
- *             characters is greater than the size of the destination buffer,
- *             the return value is the size of the buffer required to hold
- *             the expanded strings.
- *             If the function fails, the return value is zero
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Markus Montkowski [Tha, 1998/05/21 20:57]
- *****************************************************************************/
-
-DWORD WIN32API ExpandEnvironmentStringsW(LPCWSTR lpSrc,
-                                            LPWSTR lpDst,
-                                            DWORD nSize)
-{
-
-  dprintf(("KERNEL32:ExpandEnvironmentStringsW(%08x,%08x,%08x) not implemented\n",
-           lpSrc, lpDst, nSize
-          ));
-
-  return (0);
-}
 
 /*****************************************************************************
