Index: trunk/src/kernel32/environ.cpp
===================================================================
--- trunk/src/kernel32/environ.cpp	(revision 4223)
+++ trunk/src/kernel32/environ.cpp	(revision 4224)
@@ -1,3 +1,3 @@
-/* $Id: environ.cpp,v 1.5 2000-09-07 21:40:28 phaller Exp $ */
+/* $Id: environ.cpp,v 1.6 2000-09-08 18:07:49 sandervl Exp $ */
 
 /*
@@ -17,9 +17,4 @@
  *
  */
-
-/*****************************************************************************
- * Includes                                                                  *
- *****************************************************************************/
-
 #include <odin.h>
 #include <odinwrap.h>
@@ -38,20 +33,14 @@
 #include "dbglocal.h"
 
-/*****************************************************************************
- * Defines                                                                   *
- *****************************************************************************/
-
-ODINDEBUGCHANNEL(KERNEL32-ENVIRONMENT)
-
-
-//******************************************************************************
-//******************************************************************************
-ODINFUNCTION0(LPSTR, GetEnvironmentStringsA)
-{
-  return (LPSTR) O32_GetEnvironmentStrings();
-}
-//******************************************************************************
-//******************************************************************************
-ODINFUNCTION0(LPWSTR, GetEnvironmentStringsW)
+//******************************************************************************
+//******************************************************************************
+LPSTR WIN32API GetEnvironmentStringsA(void)
+{
+    dprintf(("KERNEL32:  OS2GetEnvironmentStringsA\n"));
+    return (LPSTR) O32_GetEnvironmentStrings();
+}
+//******************************************************************************
+//******************************************************************************
+LPWSTR WIN32API GetEnvironmentStringsW(VOID)
 {
  char *envstrings = (char *)O32_GetEnvironmentStrings();
@@ -59,4 +48,6 @@
  LPWSTR wenvstrings;
  int len, i;
+
+  dprintf(("KERNEL32:  GetEnvironmentStringsW\n"));
 
   if(envstrings == NULL)
@@ -82,72 +73,64 @@
 //******************************************************************************
 //******************************************************************************
-ODINFUNCTION1(BOOL, FreeEnvironmentStringsA,
-              LPSTR, envstrings)
-{
-  dprintf(("not correctly implemented.\n"));
-  //free(envstrings);
+BOOL WIN32API FreeEnvironmentStringsA(LPSTR envstrings)
+{
+  dprintf(("KERNEL32:  FreeEnvironmentStringsA\n"));
   return(TRUE);
 }
 //******************************************************************************
 //******************************************************************************
-ODINFUNCTION1(BOOL,   FreeEnvironmentStringsW,
-              LPWSTR, envstrings)
-{
-  dprintf(("not correctly implemented.\n"));
-  //free(envstrings);
+BOOL WIN32API FreeEnvironmentStringsW(LPWSTR envstrings)
+{
+  dprintf(("KERNEL32:  FreeEnvironmentStringsW\n"));
+  free(envstrings);
   return(TRUE);
 }
 //******************************************************************************
 //******************************************************************************
-ODINFUNCTION2(BOOL,   SetEnvironmentVariableA,
-              LPCSTR, lpszName,
-              LPCSTR, lpszValue)
-{
-  return O32_SetEnvironmentVariable(lpszName, lpszValue);
-}
-//******************************************************************************
-//******************************************************************************
-ODINFUNCTION2(BOOL,    SetEnvironmentVariableW,
-              LPCWSTR, lpszName,
-              LPCWSTR, lpszValue)
-{
-  char *asciiname, *asciivalue;
-  BOOL  rc;
-
-  asciiname  = UnicodeToAsciiString((LPWSTR)lpszName);
-  asciivalue = UnicodeToAsciiString((LPWSTR)lpszValue);
-  rc = O32_SetEnvironmentVariable(asciiname, asciivalue);
-  FreeAsciiString(asciivalue);
-  FreeAsciiString(asciiname);
-  return(rc);
-}
-//******************************************************************************
-//******************************************************************************
-ODINFUNCTION3(DWORD,  GetEnvironmentVariableA,
-              LPCSTR, lpName,
-              LPSTR,  lpBuffer,
-              DWORD,  nSize)
-{
-  return O32_GetEnvironmentVariable(lpName, lpBuffer, nSize);
-}
-//******************************************************************************
-//******************************************************************************
-ODINFUNCTION3(DWORD,   GetEnvironmentVariableW,
-              LPCWSTR, lpName,
-              LPWSTR,  lpBuffer,
-              DWORD,   nSize)
+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;
 
-  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);
+    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);
 }
 /***********************************************************************
@@ -186,66 +169,67 @@
  *****************************************************************************/
 
-ODINFUNCTION3(DWORD,  ExpandEnvironmentStringsA,
-              LPCSTR, lpSrc,
-              LPSTR,  lpDst,
-              DWORD,  nSize)
+DWORD WIN32API ExpandEnvironmentStringsA( LPCSTR src, LPSTR dst, DWORD count )
 {
     DWORD len, total_size = 1;  /* 1 for terminating '\0' */
     LPCSTR p, var;
 
-    if (!nSize) lpDst = NULL;
-
-    while (*lpSrc)
-    {
-        if (*lpSrc != '%')
+    dprintf(("KERNEL32:ExpandEnvironmentStringsA '%s', %08x, %08x",
+              src, dst, count
+              ));
+
+    if (!count) dst = NULL;
+
+    while (*src)
+    {
+        if (*src != '%')
         {
-            if ((p = strchr( lpSrc, '%' ))) len = p - lpSrc;
-            else len = strlen(lpSrc);
-            var = lpSrc;
-            lpSrc += len;
+            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( lpSrc + 1, '%' )))
+            if ((p = strchr( src + 1, '%' )))
             {
-                len = p - lpSrc - 1;  /* Length of the variable name */	
+                len = p - src - 1;  /* Length of the variable name */	
                 if ((var = ENV_FindVariable( GetEnvironmentStringsA(),
-                                             lpSrc + 1, len )))
+                                             src + 1, len )))
                 {
-                    lpSrc += len + 2;  /* Skip the variable name */
+                    src += len + 2;  /* Skip the variable name */
                     len = strlen(var);
                 }
                 else
                 {
-                    var = lpSrc;  /* Copy original name instead */
+                    var = src;  /* Copy original name instead */
                     len += 2;
-                    lpSrc += len;
+                    src += len;
                 }
             }
             else  /* unfinished variable name, ignore it */
             {
-                var = lpSrc;
-                len = strlen(lpSrc);  /* Copy whole string */
-                lpSrc += len;
+                var = src;
+                len = strlen(src);  /* Copy whole string */
+                src += len;
             }
         }
         total_size += len;
-        if (lpDst)
+        if (dst)
         {
-            if (nSize < len) len = nSize;
-            memcpy( lpDst, var, len );
-            lpDst += len;
-            nSize -= len;
+            if (count < len) len = count;
+            memcpy( dst, var, len );
+            dst += len;
+            count -= len;
         }
     }
 
     /* Null-terminate the string */
-    if (lpDst)
-    {
-        if (!nSize) lpDst--;
-        *lpDst = '\0';
+    if (dst)
+    {
+        if (!count) dst--;
+        *dst = '\0';
     }
     dprintf(("KERNEL32:ExpandEnvironmentStringsA returned %s %d",
-              lpDst, total_size));
+              dst, total_size));
     return total_size;
 }
@@ -270,12 +254,11 @@
  *****************************************************************************/
 
-ODINFUNCTION3(DWORD,  ExpandEnvironmentStringsW,
-              LPCWSTR,lpSrc,
-              LPWSTR, lpDst,
-              DWORD,  nSize)
+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)
Index: trunk/src/kernel32/exceptions.cpp
===================================================================
--- trunk/src/kernel32/exceptions.cpp	(revision 4223)
+++ trunk/src/kernel32/exceptions.cpp	(revision 4224)
@@ -1,3 +1,7 @@
-/* $Id: exceptions.cpp,v 1.42 2000-07-20 18:06:59 sandervl Exp $ */
+/* $Id: exceptions.cpp,v 1.43 2000-09-08 18:07:49 sandervl Exp $ */
+
+/* WARNING: Compiling this module with ICC with optimizations turned on   */
+/* currently breaks this module. To get correct code, it is not necessary */
+/* to turn all optimizations off, just use the -Op- flag.                 */
 
 /*
@@ -67,5 +71,5 @@
 #include "exceptstackdump.h"
 
-#define DBG_LOCALLOG	DBG_exceptions
+#define DBG_LOCALLOG    DBG_exceptions
 #include "dbglocal.h"
 
@@ -80,4 +84,9 @@
 void KillWin32Process(void);
 
+#ifdef DEBUG
+void PrintWin32ExceptionChain(PWINEXCEPTION_FRAME pframe);
+#else
+#define PrintWin32ExceptionChain(a)
+#endif
 
 /*****************************************************************************
@@ -142,4 +151,6 @@
   dprintf(("KERNEL32: RaiseException(%08xh)\n",
            dwExceptionCode));
+
+  memset(&record, 0, sizeof(record));
 
   /* compose an exception record */
@@ -182,8 +193,12 @@
   if(rc == ExceptionContinueSearch && UnhandledExceptionFilter != NULL)
   {
+    dprintf(("KERNEL32: RaiseException calling UnhandledExceptionFilter.\n"));
+
     ExceptionInfo.ExceptionRecord = &record;
     ExceptionInfo.ContextRecord   = &context;
 
     rc = UnhandledExceptionFilter(&ExceptionInfo);
+    //FIXME: UnhandledExceptionFilter does NOT return the same values as
+    //       other filters!!
   }
 
@@ -196,6 +211,9 @@
   }
 
+  dprintf(("KERNEL32: RaiseException returns.\n"));
   return;
 }
+
+
 //******************************************************************************
 //******************************************************************************
@@ -212,10 +230,19 @@
   pframe      = (PWINEXCEPTION_FRAME)winteb->except;
 
+  dprintf(("KERNEL32: RtlDispatchException entered"));
+
+  PrintWin32ExceptionChain(pframe);
+
   // walk the exception chain
   while( (pframe != NULL) && (pframe != ((void *)0xFFFFFFFF)) )
   {
-    	dispatch=0;
-
-    	dprintf(("Calling exception handler %x", pframe->Handler));
+        dprintf(("KERNEL32: RtlDispatchException - pframe=%08X, pframe->Prev=%08X", pframe, pframe->Prev));
+        if (pframe == pframe->Prev) {
+            dprintf(("KERNEL32: RtlDispatchException - Invalid exception frame!!"));
+            return 0;
+        }
+
+        dispatch=0;
+
         /* Check frame address */
         if (((void*)pframe < winteb->stack_low) ||
@@ -223,12 +250,20 @@
             (int)pframe & 3)
         {
+            dprintf(("Invalid stack! low=%08X, top=%08X, pframe = %08X",
+                    winteb->stack_low, winteb->stack_top, pframe));
+
             pRecord->ExceptionFlags |= EH_STACK_INVALID;
             break;
         }
 
-    	rc = pframe->Handler(pRecord,
+        dprintf(("KERNEL32: RtlDispatchException - calling exception handler %08X", pframe->Handler));
+
+        rc = pframe->Handler(pRecord,
                              pframe,
                              pContext,
                              dispatch);
+
+        dprintf(("KERNEL32: RtlDispatchException - exception handler returned %#x", rc));
+        PrintWin32ExceptionChain(pframe);
 
         if (pframe == nested_frame)
@@ -239,10 +274,12 @@
         }
 
-    	dprintf(("exception handler returned %x", rc));
 
         switch(rc)
         {
         case ExceptionContinueExecution:
-            if (!(pRecord->ExceptionFlags & EH_NONCONTINUABLE)) return rc;
+            if (!(pRecord->ExceptionFlags & EH_NONCONTINUABLE)) {
+                dprintf(("KERNEL32: RtlDispatchException returns %#x (ContinueExecution)", rc));
+                return rc;
+            }
             break;
         case ExceptionContinueSearch:
@@ -256,6 +293,13 @@
         }
 
+        dprintf(("KERNEL32: RtlDispatchException - going from frame %08X to previous frame %08X", pframe, pframe->Prev));
+        if (pframe == pframe->Prev) {
+            dprintf(("KERNEL32: RtlDispatchException - Invalid exception frame!!"));
+            break;
+        }
         pframe = pframe->Prev;
   }
+  dprintf(("KERNEL32: RtlDispatchException returns %#x", rc));
+  PrintWin32ExceptionChain(pframe);
   return rc;
 }
@@ -284,7 +328,8 @@
   WINEXCEPTION_RECORD record, newrec;
   WINCONTEXT          context;
-  int                 rc;
-
-  dprintf(("KERNEL32: RtlUnwind %x %x\n", pEndFrame, pRecord));
+  DWORD               rc;
+
+  dprintf(("KERNEL32: RtlUnwind pEndFrame=%08X, unusedEip=%08X, pRecord=%08X, returnEax=%#x\n", pEndFrame, unusedEip, pRecord, returnEax));
+
 
   memset(&context, 0, sizeof(context));
@@ -310,4 +355,5 @@
   if(!pRecord)
   {
+    memset(&record, 0, sizeof(record));
     record.ExceptionCode    = STATUS_UNWIND;
     record.ExceptionFlags   = 0;
@@ -324,4 +370,6 @@
   TEB *winteb = GetThreadTEB();
   frame       = (PWINEXCEPTION_FRAME)winteb->except;
+
+  PrintWin32ExceptionChain(frame);
 
   while ((frame != (PWINEXCEPTION_FRAME)0xffffffff) && (frame != pEndFrame))
@@ -334,6 +382,6 @@
             newrec.ExceptionRecord  = pRecord;
             newrec.NumberParameters = 0;
-    	    dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
-	    DosExit(EXIT_THREAD, 0);
+            dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
+            DosExit(EXIT_THREAD, 0);
         }
         if (((void*)frame < winteb->stack_low) ||
@@ -345,11 +393,13 @@
             newrec.ExceptionRecord  = pRecord;
             newrec.NumberParameters = 0;
-    	    dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
-	    DosExit(EXIT_THREAD, 0);
+            dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
+            DosExit(EXIT_THREAD, 0);
         }
 
         /* Call handler */
-    	dprintf(("Calling exception handler %x", frame->Handler));
-        switch(frame->Handler(pRecord, frame, &context, &dispatch ))
+        dprintf(("KERNEL32: RtlUnwind - calling exception handler %08X", frame->Handler));
+        rc = frame->Handler(pRecord, frame, &context, &dispatch);
+        dprintf(("KERNEL32: RtlUnwind - handler returned %#x", rc));
+        switch (rc)
         {
         case ExceptionContinueSearch:
@@ -363,11 +413,75 @@
             newrec.ExceptionRecord  = pRecord;
             newrec.NumberParameters = 0;
-    	    dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
-	    DosExit(EXIT_THREAD, 0);
+            dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
+            DosExit(EXIT_THREAD, 0);
             break;
         }
+        dprintf(("KERNEL32: RtlUnwind (before)- frame=%08X, frame->Prev=%08X", frame, frame->Prev));
         SetExceptionChain((DWORD)frame->Prev);
         frame = frame->Prev;
-  }
+        dprintf(("KERNEL32: RtlUnwind (after) - frame=%08X, frame->Prev=%08X", frame, frame->Prev));
+  }
+
+
+  /* Note: I _think_ that on Win32, RtlUnwind unwinds exception handlers up  */
+  /*  and _including_ the handler in pEndFrame argument. My reasons are:     */
+  /*   - MSVCRT sometimes calls RtlUnwind with the address of the very first */
+  /*     exception handler - could be just inefficient code                  */
+  /*   - after a call to RtlUnwind, MSVCRT in some cases tries to restore    */
+  /*     the original exception handler. If RtlUnwind didn't remove it,      */
+  /*     the exception chain gets looped, spelling very bad mojo!            */
+  if (frame == pEndFrame)
+  {
+        /* Just repeat what we did in the while loop above */
+        /* Check frame address */
+        if (pEndFrame && (frame > pEndFrame))
+        {
+            newrec.ExceptionCode    = STATUS_INVALID_UNWIND_TARGET;
+            newrec.ExceptionFlags   = EH_NONCONTINUABLE;
+            newrec.ExceptionRecord  = pRecord;
+            newrec.NumberParameters = 0;
+            dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
+            DosExit(EXIT_THREAD, 0);
+        }
+        if (((void*)frame < winteb->stack_low) ||
+            ((void*)(frame+1) > winteb->stack_top) ||
+            (int)frame & 3)
+        {
+            newrec.ExceptionCode    = STATUS_BAD_STACK;
+            newrec.ExceptionFlags   = EH_NONCONTINUABLE;
+            newrec.ExceptionRecord  = pRecord;
+            newrec.NumberParameters = 0;
+            dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
+            DosExit(EXIT_THREAD, 0);
+        }
+
+        /* Call handler */
+        dprintf(("KERNEL32: RtlUnwind - calling exception handler %08X", frame->Handler));
+        rc = frame->Handler(pRecord, frame, &context, &dispatch);
+        dprintf(("KERNEL32: RtlUnwind - handler returned %#x", rc));
+        switch (rc)
+        {
+        case ExceptionContinueSearch:
+            break;
+        case ExceptionCollidedUnwind:
+            frame = dispatch;
+            break;
+        default:
+            newrec.ExceptionCode    = STATUS_INVALID_DISPOSITION;
+            newrec.ExceptionFlags   = EH_NONCONTINUABLE;
+            newrec.ExceptionRecord  = pRecord;
+            newrec.NumberParameters = 0;
+            dprintf(("KERNEL32: RtlUnwind terminating thread.\n"));
+            DosExit(EXIT_THREAD, 0);
+            break;
+        }
+        dprintf(("KERNEL32: RtlUnwind (before)- frame=%08X, frame->Prev=%08X", frame, frame->Prev));
+        SetExceptionChain((DWORD)frame->Prev);
+        frame = frame->Prev;
+        dprintf(("KERNEL32: RtlUnwind (after) - frame=%08X, frame->Prev=%08X", frame, frame->Prev));
+  }
+
+  dprintf(("KERNEL32: RtlUnwind returning.\n"));
+  PrintWin32ExceptionChain(frame);
   return(0);
 }
@@ -415,8 +529,11 @@
                                   };
 
-  dprintf(("KERNEL32: UnhandledExceptionFilter\n"));
-
-  if(CurrentUnhExceptionFlt && !(CurrentErrorMode & (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX)))
+  dprintf(("KERNEL32: Default UnhandledExceptionFilter, CurrentErrorMode=%X", CurrentErrorMode));
+
+  // We must not care about ErrorMode here!! The app expects that its own
+  // UnhandledExceptionFilter will be cared even if it never touched ErrorMode.
+  if(CurrentUnhExceptionFlt) // && !(CurrentErrorMode & (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX)))
   {
+    dprintf(("KERNEL32: Calling user UnhandledExceptionFilter"));
     rc = CurrentUnhExceptionFlt(lpexpExceptionInfo);
     if(rc != WINEXCEPTION_CONTINUE_SEARCH)
@@ -492,5 +609,5 @@
   LPTOP_LEVEL_EXCEPTION_FILTER old = CurrentUnhExceptionFlt;
 
-  dprintf(("KERNEL32: SetUnhandledExceptionFilter to %X\n",
+  dprintf(("KERNEL32: SetUnhandledExceptionFilter to %08X\n",
            lpTopLevelExceptionFilter));
 
@@ -524,7 +641,7 @@
 
   if(fEntry == FALSE) {
-	fEntry = TRUE;
-  	ExitProcess(666);
-	return;
+        fEntry = TRUE;
+        ExitProcess(666);
+        return;
   }
   //Restore original OS/2 TIB selector
@@ -857,9 +974,9 @@
 
   if (pCtxRec->ContextFlags & CONTEXT_CONTROL)         /* check flags */
-    dprintf(("   SS:ESP=%04x:%08x EFLAGS=%08x\n"
-             "       CS:EIP=%04x:%08x EBP   =%08x\n",
+    dprintf(("   SS:ESP=%04x:%08x EFLAGS=%08x\n",
              pCtxRec->ctx_SegSs,
              pCtxRec->ctx_RegEsp,
-             pCtxRec->ctx_EFlags,
+             pCtxRec->ctx_EFlags));
+    dprintf(("   CS:EIP=%04x:%08x EBP   =%08x\n",
              pCtxRec->ctx_SegCs,
              pCtxRec->ctx_RegEip,
@@ -867,9 +984,9 @@
 
   if (pCtxRec->ContextFlags & CONTEXT_INTEGER)         /* check flags */
-    dprintf(("   EAX=%08x EBX=%08x ESI=%08x\n"
-             "       ECX=%08x EDX=%08x EDI=%08x\n",
+    dprintf(("   EAX=%08x EBX=%08x ESI=%08x\n",
              pCtxRec->ctx_RegEax,
              pCtxRec->ctx_RegEbx,
-             pCtxRec->ctx_RegEsi,
+             pCtxRec->ctx_RegEsi));
+    dprintf(("   ECX=%08x EDX=%08x EDI=%08x\n",
              pCtxRec->ctx_RegEcx,
              pCtxRec->ctx_RegEdx,
@@ -877,8 +994,8 @@
 
   if (pCtxRec->ContextFlags & CONTEXT_SEGMENTS)        /* check flags */
-    dprintf(("   DS=%04x     ES=%08x"
-             "       FS=%04x     GS=%04x\n",
+    dprintf(("   DS=%04x     ES=%08x",
               pCtxRec->ctx_SegDs,
-              pCtxRec->ctx_SegEs,
+              pCtxRec->ctx_SegEs));
+    dprintf(("   FS=%04x     GS=%04x\n",
               pCtxRec->ctx_SegFs,
               pCtxRec->ctx_SegGs));
@@ -936,7 +1053,14 @@
                                    PVOID                        p)
 {
+  //MN: If EH_NESTED_CALL is set, an exception occurred during the execution
+  //    of this exception handler. We better bail out ASAP or we'll likely
+  //    recurse infinitely until we run out of stack space!!
+  if (pERepRec->fHandlerFlags & EH_NESTED_CALL)
+      return XCPT_CONTINUE_SEARCH;
+
   //SvL: Check if exception inside debug fprintf -> if so, clear lock so
   //     next dprintf won't wait forever
   CheckLogException();
+
 
   /* Access violation at a known location */
@@ -950,62 +1074,62 @@
   case XCPT_FLOAT_STACK_CHECK:
   case XCPT_FLOAT_UNDERFLOW:
-  	dprintfException(pERepRec, pERegRec, pCtxRec, p);
-  	dprintf(("KERNEL32: OS2ExceptionHandler: FPU exception\n"));
-	if(fIsOS2Image == FALSE)  //Only for real win32 apps
-	{
-		if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p) == FALSE)
-		{
-		        pCtxRec->ctx_env[0] |= 0x1F;
-		        pCtxRec->ctx_stack[0].losig = 0;
-		        pCtxRec->ctx_stack[0].hisig = 0;
-		        pCtxRec->ctx_stack[0].signexp = 0;
-		}
-  		dprintf(("KERNEL32: OS2ExceptionHandler: fix and continue\n"));
-	      	return (XCPT_CONTINUE_EXECUTION);
-	}
-	else
-	{
-	  	dprintf(("KERNEL32: OS2ExceptionHandler: continue search\n"));
-	  	return (XCPT_CONTINUE_SEARCH);
-	}
+        dprintfException(pERepRec, pERegRec, pCtxRec, p);
+        dprintf(("KERNEL32: OS2ExceptionHandler: FPU exception\n"));
+        if(fIsOS2Image == FALSE)  //Only for real win32 apps
+        {
+                if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p) == FALSE)
+                {
+                        pCtxRec->ctx_env[0] |= 0x1F;
+                        pCtxRec->ctx_stack[0].losig = 0;
+                        pCtxRec->ctx_stack[0].hisig = 0;
+                        pCtxRec->ctx_stack[0].signexp = 0;
+                }
+                dprintf(("KERNEL32: OS2ExceptionHandler: fix and continue\n"));
+                return (XCPT_CONTINUE_EXECUTION);
+        }
+        else
+        {
+                dprintf(("KERNEL32: OS2ExceptionHandler: continue search\n"));
+                return (XCPT_CONTINUE_SEARCH);
+        }
 
   case XCPT_PROCESS_TERMINATE:
   case XCPT_ASYNC_PROCESS_TERMINATE:
-  	dprintfException(pERepRec, pERegRec, pCtxRec, p);
-      	SetExceptionChain((ULONG)-1);
-      	return (XCPT_CONTINUE_SEARCH);
+        dprintfException(pERepRec, pERegRec, pCtxRec, p);
+        SetExceptionChain((ULONG)-1);
+        return (XCPT_CONTINUE_SEARCH);
 
   case XCPT_ACCESS_VIOLATION:
-  {	
+  {
    Win32MemMap *map;
    BOOL  fWriteAccess = FALSE;
    ULONG offset, accessflag;
 
-	if(pERepRec->ExceptionInfo[1] == 0 && pERepRec->ExceptionInfo[1] == XCPT_DATA_UNKNOWN) {
-		goto continueFail;
-	}
-	switch(pERepRec->ExceptionInfo[0]) {
-	case XCPT_READ_ACCESS:
-		accessflag = MEMMAP_ACCESS_READ;
-		break;
-	case XCPT_WRITE_ACCESS:
-		accessflag = MEMMAP_ACCESS_WRITE;
-		fWriteAccess = TRUE;
-		break;
-	case XCPT_EXECUTE_ACCESS:
-		accessflag = MEMMAP_ACCESS_EXECUTE;
-		break;
-	default:
-		goto continueFail;
-	}
-
-       	map = Win32MemMapView::findMapByView(pERepRec->ExceptionInfo[1], &offset, accessflag);
-	if(map == NULL) {
-		goto continueFail;
-	}
-	if(map->commitPage(offset, fWriteAccess) == TRUE)
-		return (XCPT_CONTINUE_EXECUTION);
-
-	//no break;
+        if(pERepRec->ExceptionInfo[1] == 0 && pERepRec->ExceptionInfo[1] == XCPT_DATA_UNKNOWN) {
+                goto continueFail;
+        }
+        switch(pERepRec->ExceptionInfo[0]) {
+        case XCPT_READ_ACCESS:
+                accessflag = MEMMAP_ACCESS_READ;
+                break;
+        case XCPT_WRITE_ACCESS:
+                accessflag = MEMMAP_ACCESS_WRITE;
+                fWriteAccess = TRUE;
+                break;
+        case XCPT_EXECUTE_ACCESS:
+                accessflag = MEMMAP_ACCESS_EXECUTE;
+                break;
+        default:
+                goto continueFail;
+        }
+
+        map = Win32MemMapView::findMapByView(pERepRec->ExceptionInfo[1], &offset, accessflag);
+        if(map == NULL) {
+                goto continueFail;
+        }
+        if(map->commitPage(offset, fWriteAccess) == TRUE)
+                return (XCPT_CONTINUE_EXECUTION);
+
+        //no break;
   }
 continueFail:
@@ -1014,15 +1138,15 @@
 #ifdef DEBUGSTACK
   if(pCtxRec->ContextFlags & CONTEXT_CONTROL) {
-    	ULONG *stackptr;
-    	APIRET rc;
-    	int    i;
-  	ULONG  ulOffset, ulModule, ulObject;
-  	CHAR   szModule[CCHMAXPATH];
-
-	stackptr = (ULONG *)pCtxRec->ctx_RegEsp;
-	dprintf(("Stack DUMP:"));
-	for(i=0;i<16;i++) {
-		rc = DosQueryModFromEIP(&ulModule,
-        	                        &ulObject,
+        ULONG *stackptr;
+        APIRET rc;
+        int    i;
+        ULONG  ulOffset, ulModule, ulObject;
+        CHAR   szModule[CCHMAXPATH];
+
+        stackptr = (ULONG *)pCtxRec->ctx_RegEsp;
+        dprintf(("Stack DUMP:"));
+        for(i=0;i<16;i++) {
+                rc = DosQueryModFromEIP(&ulModule,
+                                        &ulObject,
                                         sizeof(szModule),
                                         szModule,
@@ -1030,10 +1154,10 @@
                                         (ULONG)*stackptr);
 
-  		if (rc == NO_ERROR)
-    			dprintf(("0x%8x: 0x%8x %s (#%u), obj #%u:%08x", stackptr, *stackptr, szModule, ulModule, ulObject, ulOffset));
-		else	dprintf(("0x%8x: 0x%8x", stackptr, *stackptr));
-		stackptr++;
-	}
-	dprintf(("Stack DUMP END"));
+                if (rc == NO_ERROR)
+                        dprintf(("0x%8x: 0x%8x %s (#%u), obj #%u:%08x", stackptr, *stackptr, szModule, ulModule, ulObject, ulOffset));
+                else    dprintf(("0x%8x: 0x%8x", stackptr, *stackptr));
+                stackptr++;
+        }
+        dprintf(("Stack DUMP END"));
   }
 #endif
@@ -1052,28 +1176,28 @@
 CrashAndBurn:
 #ifdef DEBUG
-	dprintfException(pERepRec, pERegRec, pCtxRec, p);
-  	if(pCtxRec->ContextFlags & CONTEXT_CONTROL) {
-		dbgPrintStack(pERepRec, pERegRec, pCtxRec, p);
-	}
+        dprintfException(pERepRec, pERegRec, pCtxRec, p);
+        if(pCtxRec->ContextFlags & CONTEXT_CONTROL) {
+                dbgPrintStack(pERepRec, pERegRec, pCtxRec, p);
+        }
 #endif
-	if(fIsOS2Image == FALSE)  //Only for real win32 apps
-	{
-		if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p) == TRUE)
-		{
-		      	return (XCPT_CONTINUE_EXECUTION);
-		}
-	}
-	else	return XCPT_CONTINUE_SEARCH; //pass on to OS/2 RTL or app exception handler
-
-    	dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill\n"));
-    	pCtxRec->ctx_RegEip = (ULONG)KillWin32Process;
-    	pCtxRec->ctx_RegEsp = pCtxRec->ctx_RegEsp + 0x10;
-    	pCtxRec->ctx_RegEax = pERepRec->ExceptionNum;
-    	pCtxRec->ctx_RegEbx = pCtxRec->ctx_RegEip;
-    	return (XCPT_CONTINUE_EXECUTION);
+        if(fIsOS2Image == FALSE)  //Only for real win32 apps
+        {
+                if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p) == TRUE)
+                {
+                        return (XCPT_CONTINUE_EXECUTION);
+                }
+        }
+        else    return XCPT_CONTINUE_SEARCH; //pass on to OS/2 RTL or app exception handler
+
+        dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill\n"));
+        pCtxRec->ctx_RegEip = (ULONG)KillWin32Process;
+        pCtxRec->ctx_RegEsp = pCtxRec->ctx_RegEsp + 0x10;
+        pCtxRec->ctx_RegEax = pERepRec->ExceptionNum;
+        pCtxRec->ctx_RegEbx = pCtxRec->ctx_RegEip;
+        return (XCPT_CONTINUE_EXECUTION);
 
   //@@@PH: growing thread stacks might need special treatment
   case XCPT_GUARD_PAGE_VIOLATION:
-    dprintf(("KERNEL32: OS2ExceptionHandler: trying to grow stack (continue)\n"));
+    dprintf(("KERNEL32: OS2ExceptionHandler: trying to grow stack (continue search)"));
     return (XCPT_CONTINUE_SEARCH);
 
@@ -1081,11 +1205,11 @@
       if(pERepRec->ExceptionInfo[0] == XCPT_SIGNAL_KILLPROC)          /* resolve signal information */
       {
-      	SetExceptionChain((ULONG)-1);
-      	return (XCPT_CONTINUE_SEARCH);
+        SetExceptionChain((ULONG)-1);
+        return (XCPT_CONTINUE_SEARCH);
       }
       goto CrashAndBurn;
 
   default: //non-continuable exceptions
-	dprintfException(pERepRec, pERegRec, pCtxRec, p);
+        dprintfException(pERepRec, pERegRec, pCtxRec, p);
         return (XCPT_CONTINUE_SEARCH);
   }
@@ -1129,9 +1253,23 @@
   dprintf(("Exception chain list:"));
   while(pExceptRec != 0 && (ULONG)pExceptRec != -1) {
-	dprintf(("record %x", pExceptRec));
-	pExceptRec = pExceptRec->prev_structure;
+        dprintf(("record %x", pExceptRec));
+        pExceptRec = pExceptRec->prev_structure;
   }
   SetFS(sel);
 }
+
+void PrintWin32ExceptionChain(PWINEXCEPTION_FRAME pframe)
+{
+  dprintf(("Win32 exception chain:"));
+  while ((pframe != NULL) && ((ULONG)pframe != 0xFFFFFFFF)) {
+        dprintf(("Record at %08X, Prev at %08X, handler at %08X", pframe, pframe->Prev, pframe->Handler));
+        if (pframe == pframe->Prev) {
+            dprintf(("Chain corrupted! Record at %08X pointing to itself!", pframe));
+            break;
+        }
+        pframe = pframe->Prev;
+  }
+}
+
 #endif
 
@@ -1173,11 +1311,11 @@
 
     if(sel == 0x150b) {
-	SetFS(sel);
-	return FALSE;
+        SetFS(sel);
+        return FALSE;
     }
     pExceptRec = (PEXCEPTIONREGISTRATIONRECORD)QueryExceptionChain();
     if(pExceptRec->ExceptionHandler != OS2ExceptionHandler) {
-	SetFS(sel);
-	return FALSE;
+        SetFS(sel);
+        return FALSE;
     }
     SetFS(sel);
Index: trunk/src/kernel32/exceptutil.asm
===================================================================
--- trunk/src/kernel32/exceptutil.asm	(revision 4223)
+++ trunk/src/kernel32/exceptutil.asm	(revision 4224)
@@ -1,3 +1,3 @@
-; $Id: exceptutil.asm,v 1.10 2000-09-04 18:24:42 sandervl Exp $
+; $Id: exceptutil.asm,v 1.11 2000-09-08 18:07:49 sandervl Exp $
 
 ;/*
@@ -53,4 +53,10 @@
 
 _RtlUnwind@16 proc near
+        ; fudge return address
+        push eax
+        mov  eax, dword ptr [esp+12]
+        mov  dword ptr [esp+4], eax
+        pop  eax
+
         push dword ptr [esp+4]  ;PWINEXCEPTION_FRAME  pEndFrame
         push dword ptr [esp+12] ;LPVOID unusedEip
@@ -135,99 +141,99 @@
         PUBLIC getEAX
         PUBLIC getEBX
-getEAX 	proc near
-        ret
-getEAX 	endp
-
-getEBX 	proc near
+getEAX  proc near
+        ret
+getEAX  endp
+
+getEBX  proc near
         mov  eax, ebx
         ret
-getEBX 	endp
+getEBX  endp
 
         PUBLIC GetFS
-GetFS  	proc near
-	mov	eax, fs
-	ret
-GetFS  	endp
+GetFS   proc near
+        mov     eax, fs
+        ret
+GetFS   endp
 
         PUBLIC SetFS
-SetFS	proc near
-	mov  	eax, [esp+4]
-	mov	fs, eax
-	ret
-SetFS	endp
+SetFS   proc near
+        mov     eax, [esp+4]
+        mov     fs, eax
+        ret
+SetFS   endp
 
         PUBLIC getCS
-getCS  	proc near
-	mov	eax, cs
-	ret
-getCS  	endp
+getCS   proc near
+        mov     eax, cs
+        ret
+getCS   endp
 
         PUBLIC getDS
-getDS  	proc near
-	mov	eax, ds
-	ret
-getDS  	endp
-
-	PUBLIC SetReturnFS
+getDS   proc near
+        mov     eax, ds
+        ret
+getDS   endp
+
+        PUBLIC SetReturnFS
 SetReturnFS proc near
-	push	fs
-	mov  	eax, [esp+8]
-	mov	fs, eax
-	pop	eax
-	ret
+        push    fs
+        mov     eax, [esp+8]
+        mov     fs, eax
+        pop     eax
+        ret
 SetReturnFS endp
 
         PUBLIC getSS
-getSS	proc near
-	mov	ax, ss
-	ret
-getSS	endp
+getSS   proc near
+        mov     ax, ss
+        ret
+getSS   endp
 
         PUBLIC getES
-getES  	proc near
-	mov	eax, es
-	ret
-getES  	endp
+getES   proc near
+        mov     eax, es
+        ret
+getES   endp
 
         PUBLIC getGS
-getGS  	proc near
-	mov	eax, gs
-	ret
-getGS  	endp
-
-	PUBLIC getESP
+getGS   proc near
+        mov     eax, gs
+        ret
+getGS   endp
+
+        PUBLIC getESP
 getESP  proc near
-	mov	eax, esp
-	ret
-getESP	endp
-
-	PUBLIC RestoreOS2FS
+        mov     eax, esp
+        ret
+getESP  endp
+
+        PUBLIC RestoreOS2FS
 RestoreOS2FS proc near
-	push	150bh
-	mov	ax, fs
-	pop	fs
-	ret
+        push    150bh
+        mov     ax, fs
+        pop     fs
+        ret
 RestoreOS2FS endp
 
-	PUBLIC _Mul32x32to64
+        PUBLIC _Mul32x32to64
 _Mul32x32to64 proc near
-	push	ebp
-	mov	ebp, esp
-	push	eax
-	push	edx
-	push	edi
-
-	mov	edi, [ebp+8]	;64 bits result
-	mov	eax, [ebp+12]	;op1
-	mov	edx, [ebp+16]	;op2
-	mul	edx
-	mov	[edi], eax
-	mov	[edi+4], edx
-
-	pop	edi
-	pop	edx
-	pop	eax
-	pop	ebp
-	ret
+        push    ebp
+        mov     ebp, esp
+        push    eax
+        push    edx
+        push    edi
+
+        mov     edi, [ebp+8]    ;64 bits result
+        mov     eax, [ebp+12]   ;op1
+        mov     edx, [ebp+16]   ;op2
+        mul     edx
+        mov     [edi], eax
+        mov     [edi+4], edx
+
+        pop     edi
+        pop     edx
+        pop     eax
+        pop     ebp
+        ret
 _Mul32x32to64 endp
 
Index: trunk/src/kernel32/heap.cpp
===================================================================
--- trunk/src/kernel32/heap.cpp	(revision 4223)
+++ trunk/src/kernel32/heap.cpp	(revision 4224)
@@ -1,3 +1,3 @@
-/* $Id: heap.cpp,v 1.21 2000-09-08 04:28:46 phaller Exp $ */
+/* $Id: heap.cpp,v 1.22 2000-09-08 18:07:50 sandervl Exp $ */
 
 /*
@@ -180,7 +180,5 @@
 //******************************************************************************
 //******************************************************************************
-ODINFUNCTIONNODBG2(HLOCAL, LocalAlloc,
-                   UINT,   fuFlags,
-                   DWORD,  cbBytes)
+HLOCAL WIN32API LocalAlloc(UINT fuFlags, DWORD cbBytes)
 {
  HLOCAL lmem;
@@ -219,15 +217,14 @@
 //******************************************************************************
 //******************************************************************************
-ODINFUNCTIONNODBG1(HLOCAL, LocalFree,
-                   HLOCAL, hMem)
-{
-  if(OS2ProcessHeap->GetLockCnt((LPVOID)hMem) != 0)
-  {
-    dprintf(("LocalFree, lock count != 0\n"));
-    return(hMem);   //TODO: SetLastError
-  }
-  if(OS2ProcessHeap->Free(0, (LPVOID)hMem) == FALSE) 
-  {
-    return(hMem);   //TODO: SetLastError
+HLOCAL WIN32API LocalFree(HLOCAL hMem)
+{
+  dprintf(("KERNEL32: LocalFree %X\n", hMem));
+
+  if(OS2ProcessHeap->GetLockCnt((LPVOID)hMem) != 0) {
+      	dprintf(("LocalFree, lock count != 0\n"));
+      	return(hMem);   //TODO: SetLastError
+  }
+  if(OS2ProcessHeap->Free(0, (LPVOID)hMem) == FALSE) {
+      	return(hMem);   //TODO: SetLastError
   }
   return NULL; //success
@@ -252,11 +249,10 @@
 //TODO: cbBytes==0 && fuFlags & LMEM_MOVEABLE not handled!!
 //******************************************************************************
-ODINFUNCTIONNODBG3(HLOCAL, LocalReAlloc,
-                   HLOCAL, hMem,
-                   DWORD,  cbBytes,
-                   UINT,   fuFlags)
+HLOCAL WIN32API LocalReAlloc(HLOCAL hMem, DWORD cbBytes, UINT fuFlags)
 {
   HLOCAL hLocalNew;
   LPVOID lpMem;
+
+  dprintf(("KERNEL32: LocalReAlloc %X %d %X\n", hMem, cbBytes, fuFlags));
 
   //SvL: 8-8-'98: Notepad bugfix (assumes address is identical when new size < old size)
@@ -322,10 +318,18 @@
 }
 //******************************************************************************
+#ifdef DEBUG
+static ULONG totalGlobalAlloc = 0;
+#endif
 //******************************************************************************
 HGLOBAL WIN32API GlobalAlloc(UINT fuFlags, DWORD dwBytes)
 {
-    dprintf(("KERNEL32:  GlobalAlloc %d\n", dwBytes));
-
-    return O32_GlobalAlloc(fuFlags, dwBytes);
+ HGLOBAL ret;
+
+    ret = O32_GlobalAlloc(fuFlags, dwBytes);
+#ifdef DEBUG
+    totalGlobalAlloc += dwBytes;
+#endif
+    dprintf(("KERNEL32: GlobalAlloc %x %d returned %x (total %x)", fuFlags, dwBytes, ret, totalGlobalAlloc));
+    return ret;
 }
 //******************************************************************************
@@ -333,7 +337,12 @@
 HGLOBAL WIN32API GlobalFree( HGLOBAL arg1)
 {
-    dprintf(("KERNEL32:  GlobalFree\n"));
-
-    return O32_GlobalFree(arg1);
+ HGLOBAL ret;
+
+#ifdef DEBUG
+    totalGlobalAlloc -= O32_GlobalSize(arg1);
+#endif
+    ret = O32_GlobalFree(arg1);
+    dprintf(("KERNEL32: GlobalFree %x returned %x (lasterr=%x) total %x", arg1, ret, GetLastError(), totalGlobalAlloc));
+    return ret;
 }
 //******************************************************************************
@@ -365,7 +374,9 @@
 PVOID WIN32API GlobalLock(HGLOBAL arg1)
 {
-    dprintf(("KERNEL32: GlobalLock\n"));
-
-    return O32_GlobalLock(arg1);
+ PVOID ret;
+
+    ret = O32_GlobalLock(arg1);
+    dprintf(("KERNEL32: GlobalLock %x returned %x", arg1, ret));
+    return ret;
 }
 //******************************************************************************
Index: trunk/src/kernel32/makefile
===================================================================
--- trunk/src/kernel32/makefile	(revision 4223)
+++ trunk/src/kernel32/makefile	(revision 4224)
@@ -1,3 +1,3 @@
-# $Id: makefile,v 1.99 2000-09-03 18:04:54 phaller Exp $
+# $Id: makefile,v 1.100 2000-09-08 18:07:50 sandervl Exp $
 
 #
@@ -181,2 +181,6 @@
 !include $(PDWIN32_INCLUDE)/pdwin32.post
 
+
+#override flags for exceptions.cpp
+$(OBJDIR)\exceptions.obj: exceptions.cpp
+    $(CXX) $(CXXFLAGS) -Op- -Fo$(OBJDIR)\$(@B).obj -c exceptions.cpp
Index: trunk/src/kernel32/oslibexcept.cpp
===================================================================
--- trunk/src/kernel32/oslibexcept.cpp	(revision 4223)
+++ trunk/src/kernel32/oslibexcept.cpp	(revision 4224)
@@ -1,3 +1,3 @@
-/* $Id: oslibexcept.cpp,v 1.2 2000-02-16 14:25:45 sandervl Exp $ */
+/* $Id: oslibexcept.cpp,v 1.3 2000-09-08 18:07:50 sandervl Exp $ */
 /*
  * Exception handler util. procedures
@@ -18,6 +18,7 @@
 #include "oslibexcept.h"
 #include <exceptions.h>
-
-#define DBG_LOCALLOG	DBG_oslibexcept
+#include <wprocess.h>
+
+#define DBG_LOCALLOG    DBG_oslibexcept
 #include "dbglocal.h"
 
@@ -27,7 +28,7 @@
 //         FALSE, otherwise
 //******************************************************************************
-BOOL OSLibDispatchException(PEXCEPTIONREPORTRECORD pReportRec, 
-                            PEXCEPTIONREGISTRATIONRECORD pRegistrationRec, 
-                            PCONTEXTRECORD pContextRec, PVOID p)
+BOOL APIENTRY OSLibDispatchException(PEXCEPTIONREPORTRECORD pReportRec,
+                                     PEXCEPTIONREGISTRATIONRECORD pRegistrationRec,
+                                     PCONTEXTRECORD pContextRec, PVOID p)
 {
  WINEXCEPTION_RECORD winreportrec;
@@ -40,65 +41,65 @@
   switch(pReportRec->ExceptionNum) {
   case XCPT_FLOAT_DENORMAL_OPERAND:
-	winreportrec.ExceptionCode = EXCEPTION_FLT_DENORMAL_OPERAND;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_FLT_DENORMAL_OPERAND;
+        break;
   case XCPT_FLOAT_DIVIDE_BY_ZERO:
-	winreportrec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
+        break;
   case XCPT_FLOAT_INEXACT_RESULT:
-	winreportrec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
+        break;
   case XCPT_FLOAT_INVALID_OPERATION:
-	winreportrec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
+        break;
   case XCPT_FLOAT_OVERFLOW:
-	winreportrec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
+        break;
   case XCPT_FLOAT_STACK_CHECK:
-	winreportrec.ExceptionCode = EXCEPTION_FLT_STACK_CHECK;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_FLT_STACK_CHECK;
+        break;
   case XCPT_FLOAT_UNDERFLOW:
-	winreportrec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
+        break;
   case XCPT_INTEGER_DIVIDE_BY_ZERO:
-	winreportrec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
+        break;
   case XCPT_INTEGER_OVERFLOW:
-	winreportrec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
+        break;
   case XCPT_PRIVILEGED_INSTRUCTION:
-	winreportrec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
+        break;
   case XCPT_BREAKPOINT:
-	winreportrec.ExceptionCode = EXCEPTION_BREAKPOINT;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_BREAKPOINT;
+        break;
   case XCPT_SINGLE_STEP:
-	winreportrec.ExceptionCode = EXCEPTION_SINGLE_STEP;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_SINGLE_STEP;
+        break;
   case XCPT_ARRAY_BOUNDS_EXCEEDED:
-	winreportrec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
+        break;
   case XCPT_DATATYPE_MISALIGNMENT:
-	winreportrec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
+        break;
   case XCPT_ILLEGAL_INSTRUCTION:
-	winreportrec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+        break;
   case XCPT_INVALID_LOCK_SEQUENCE:
-	winreportrec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+        break;
   case XCPT_GUARD_PAGE_VIOLATION:
-	winreportrec.ExceptionCode = EXCEPTION_GUARD_PAGE;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_GUARD_PAGE;
+        break;
   case XCPT_UNABLE_TO_GROW_STACK:
-	winreportrec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
+        break;
   case XCPT_IN_PAGE_ERROR:
-	winreportrec.ExceptionCode = EXCEPTION_IN_PAGE_ERROR;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_IN_PAGE_ERROR;
+        break;
   case XCPT_ACCESS_VIOLATION:
-	winreportrec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
-	break;
+        winreportrec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
+        break;
   default: //no other exceptions should be dispatched to win32 apps
-	return FALSE;
+        return FALSE;
   }
   //TODO:
@@ -109,38 +110,49 @@
   memset(&wincontextrec, 0, sizeof(wincontextrec));
   if(pContextRec->ContextFlags & CONTEXT_CONTROL) {
-	wincontextrec.ContextFlags |= WINCONTEXT_CONTROL;
-	wincontextrec.Ebp     = pContextRec->ctx_RegEbp;
-	wincontextrec.Eip     = pContextRec->ctx_RegEip;
-	wincontextrec.SegCs   = pContextRec->ctx_SegCs;
-	wincontextrec.EFlags  = pContextRec->ctx_EFlags;
-	wincontextrec.Esp     = pContextRec->ctx_RegEsp;
-	wincontextrec.SegSs   = pContextRec->ctx_SegSs;
+        wincontextrec.ContextFlags |= WINCONTEXT_CONTROL;
+        wincontextrec.Ebp     = pContextRec->ctx_RegEbp;
+        wincontextrec.Eip     = pContextRec->ctx_RegEip;
+        wincontextrec.SegCs   = pContextRec->ctx_SegCs;
+        wincontextrec.EFlags  = pContextRec->ctx_EFlags;
+        wincontextrec.Esp     = pContextRec->ctx_RegEsp;
+        wincontextrec.SegSs   = pContextRec->ctx_SegSs;
   }
   if(pContextRec->ContextFlags & CONTEXT_INTEGER) {
-	wincontextrec.ContextFlags |= WINCONTEXT_INTEGER;
-	wincontextrec.Edi     = pContextRec->ctx_RegEdi;
-	wincontextrec.Esi     = pContextRec->ctx_RegEsi;
-	wincontextrec.Ebx     = pContextRec->ctx_RegEbx;
-	wincontextrec.Edx     = pContextRec->ctx_RegEdx;
-	wincontextrec.Ecx     = pContextRec->ctx_RegEcx;
-	wincontextrec.Eax     = pContextRec->ctx_RegEax;
-  }
+        wincontextrec.ContextFlags |= WINCONTEXT_INTEGER;
+        wincontextrec.Edi     = pContextRec->ctx_RegEdi;
+        wincontextrec.Esi     = pContextRec->ctx_RegEsi;
+        wincontextrec.Ebx     = pContextRec->ctx_RegEbx;
+        wincontextrec.Edx     = pContextRec->ctx_RegEdx;
+        wincontextrec.Ecx     = pContextRec->ctx_RegEcx;
+        wincontextrec.Eax     = pContextRec->ctx_RegEax;
+  }
+
+  TEB  *winteb = GetThreadTEB();
+  THDB *thdb   = (THDB *)(winteb+1);
+
   if(pContextRec->ContextFlags & CONTEXT_SEGMENTS) {
-	wincontextrec.ContextFlags |= WINCONTEXT_SEGMENTS;
-	wincontextrec.SegGs   = pContextRec->ctx_SegGs;
-	wincontextrec.SegFs   = pContextRec->ctx_SegFs;
-	wincontextrec.SegEs   = pContextRec->ctx_SegEs;
-	wincontextrec.SegDs   = pContextRec->ctx_SegDs;
+        wincontextrec.ContextFlags |= WINCONTEXT_SEGMENTS;
+        wincontextrec.SegGs   = pContextRec->ctx_SegGs;
+//   This resets FS to 0x150B - we DON'T want that!!
+//      wincontextrec.SegFs   = pContextRec->ctx_SegFs;
+        wincontextrec.SegFs   = thdb->teb_sel;
+        wincontextrec.SegEs   = pContextRec->ctx_SegEs;
+        wincontextrec.SegDs   = pContextRec->ctx_SegDs;
   }
   if(pContextRec->ContextFlags & CONTEXT_FLOATING_POINT) {
-	wincontextrec.ContextFlags |= WINCONTEXT_FLOATING_POINT;
-	//TODO: First 7 dwords the same?
-	memcpy(&wincontextrec.FloatSave, pContextRec->ctx_env, sizeof(pContextRec->ctx_env));
-	memcpy(&wincontextrec.FloatSave.RegisterArea, pContextRec->ctx_stack, sizeof(pContextRec->ctx_stack));
+        wincontextrec.ContextFlags |= WINCONTEXT_FLOATING_POINT;
+        //TODO: First 7 dwords the same?
+        memcpy(&wincontextrec.FloatSave, pContextRec->ctx_env, sizeof(pContextRec->ctx_env));
+        memcpy(&wincontextrec.FloatSave.RegisterArea, pContextRec->ctx_stack, sizeof(pContextRec->ctx_stack));
   }
   //It doesn't seem correct if we dispatch real exceptions to win32 apps
   //Some just call RtlUnwind and continue as if they were processing an
   //exception thrown by C++ code. (instead of real OS exception)
-#if 0
+#if 1
+  // We need to reset FS to its original (Win32) value, otherwise we'll likely
+  // fuck up the Win32 exception handlers. They could end up using the wrong
+  // exception chain if they access FS:[0] directly.
+  DWORD oldsel = SetReturnFS(thdb->teb_sel);
+
   switch(pReportRec->ExceptionNum) {
   case XCPT_FLOAT_DENORMAL_OPERAND:
@@ -151,10 +163,10 @@
   case XCPT_FLOAT_STACK_CHECK:
   case XCPT_FLOAT_UNDERFLOW:
-	rc = RtlDispatchException(&winreportrec, &wincontextrec);
-	break;
+        rc = RtlDispatchException(&winreportrec, &wincontextrec);
+        break;
 
   case XCPT_ACCESS_VIOLATION:
-	rc = RtlDispatchException(&winreportrec, &wincontextrec);
-	break;
+        rc = RtlDispatchException(&winreportrec, &wincontextrec);
+        break;
 
   case XCPT_INTEGER_DIVIDE_BY_ZERO:
@@ -170,93 +182,95 @@
   case XCPT_UNABLE_TO_GROW_STACK:
   case XCPT_IN_PAGE_ERROR:
-	return FALSE; //let's no dispatch those for now
-  }
+	SetFS(oldsel);	//restore FS
+        return FALSE; //let's not dispatch those for now
+  }
+  SetFS(oldsel);	//restore FS
 
   if(rc == ExceptionContinueExecution) {
-  	dprintf(("Win32 exception handler returned ExceptionContinueExecution"));
-  	if(wincontextrec.ContextFlags & WINCONTEXT_CONTROL) {
-		pContextRec->ctx_RegEbp = wincontextrec.Ebp;
-		pContextRec->ctx_RegEip = wincontextrec.Eip;
-		pContextRec->ctx_SegCs  = wincontextrec.SegCs;
-		pContextRec->ctx_EFlags = wincontextrec.EFlags;
-		pContextRec->ctx_RegEsp = wincontextrec.Esp;
-		pContextRec->ctx_SegSs  = wincontextrec.SegSs;
-  	}
-	if(wincontextrec.ContextFlags & WINCONTEXT_INTEGER) {
-		pContextRec->ctx_RegEdi = wincontextrec.Edi;
-		pContextRec->ctx_RegEsi = wincontextrec.Esi;
-		pContextRec->ctx_RegEbx = wincontextrec.Ebx;
-		pContextRec->ctx_RegEdx = wincontextrec.Edx;
-		pContextRec->ctx_RegEcx = wincontextrec.Ecx;
-		pContextRec->ctx_RegEax = wincontextrec.Eax;
-	}
+        dprintf(("Win32 exception handler returned ExceptionContinueExecution"));
+        if(wincontextrec.ContextFlags & WINCONTEXT_CONTROL) {
+                pContextRec->ctx_RegEbp = wincontextrec.Ebp;
+                pContextRec->ctx_RegEip = wincontextrec.Eip;
+                pContextRec->ctx_SegCs  = wincontextrec.SegCs;
+                pContextRec->ctx_EFlags = wincontextrec.EFlags;
+                pContextRec->ctx_RegEsp = wincontextrec.Esp;
+                pContextRec->ctx_SegSs  = wincontextrec.SegSs;
+        }
+        if(wincontextrec.ContextFlags & WINCONTEXT_INTEGER) {
+                pContextRec->ctx_RegEdi = wincontextrec.Edi;
+                pContextRec->ctx_RegEsi = wincontextrec.Esi;
+                pContextRec->ctx_RegEbx = wincontextrec.Ebx;
+                pContextRec->ctx_RegEdx = wincontextrec.Edx;
+                pContextRec->ctx_RegEcx = wincontextrec.Ecx;
+                pContextRec->ctx_RegEax = wincontextrec.Eax;
+        }
 #if 0
-	//This is not a good idea
-	if(wincontextrec.ContextFlags & WINCONTEXT_SEGMENTS) {
-		pContextRec->ctx_SegGs = wincontextrec.SegGs;
-		pContextRec->ctx_SegFs = wincontextrec.SegFs;
-		pContextRec->ctx_SegEs = wincontextrec.SegEs;
-		pContextRec->ctx_SegDs = wincontextrec.SegDs;
-	}
+        //This is not a good idea
+        if(wincontextrec.ContextFlags & WINCONTEXT_SEGMENTS) {
+                pContextRec->ctx_SegGs = wincontextrec.SegGs;
+                pContextRec->ctx_SegFs = wincontextrec.SegFs;
+                pContextRec->ctx_SegEs = wincontextrec.SegEs;
+                pContextRec->ctx_SegDs = wincontextrec.SegDs;
+        }
 #endif
-	if(wincontextrec.ContextFlags & WINCONTEXT_FLOATING_POINT) {
-		//TODO: First 7 dwords the same?
-		memcpy(pContextRec->ctx_env, &wincontextrec.FloatSave, sizeof(pContextRec->ctx_env));
-		memcpy(pContextRec->ctx_stack, &wincontextrec.FloatSave.RegisterArea, sizeof(pContextRec->ctx_stack));
-	}
-  	if (pContextRec->ContextFlags & CONTEXT_CONTROL)         /* check flags */
-    		dprintf(("   SS:ESP=%04x:%08x EFLAGS=%08x\n"
-		             "   CS:EIP=%04x:%08x EBP   =%08x\n",
-		             pContextRec->ctx_SegSs,
-		             pContextRec->ctx_RegEsp,
-		             pContextRec->ctx_EFlags,
-		             pContextRec->ctx_SegCs,
-		             pContextRec->ctx_RegEip,
-		             pContextRec->ctx_RegEbp));
-
-	if (pContextRec->ContextFlags & CONTEXT_INTEGER)         /* check flags */
-		    dprintf(("   EAX=%08x EBX=%08x ESI=%08x\n"
-		             "   ECX=%08x EDX=%08x EDI=%08x\n",
-		             pContextRec->ctx_RegEax,
-		             pContextRec->ctx_RegEbx,
-		             pContextRec->ctx_RegEsi,
-		             pContextRec->ctx_RegEcx,
-		             pContextRec->ctx_RegEdx,
-		             pContextRec->ctx_RegEdi));
-		
-	if (pContextRec->ContextFlags & CONTEXT_SEGMENTS)        /* check flags */
-		    dprintf(("   DS=%04x     ES=%08x"
-		             "   FS=%04x     GS=%04x\n",
-		              pContextRec->ctx_SegDs,
-		              pContextRec->ctx_SegEs,
-		              pContextRec->ctx_SegFs,
-		              pContextRec->ctx_SegGs));
-
-	if (pContextRec->ContextFlags & CONTEXT_FLOATING_POINT)  /* check flags */
-	{
-	    ULONG ulCounter;                 /* temporary local counter for fp stack */
-
-		dprintf(("   Env[0]=%08x Env[1]=%08x Env[2]=%08x Env[3]=%08x\n",
-		             pContextRec->ctx_env[0],
-		             pContextRec->ctx_env[1],
-		             pContextRec->ctx_env[2],
-		             pContextRec->ctx_env[3]));
-		
-		dprintf(("   Env[4]=%08x Env[5]=%08x Env[6]=%08x\n",
-			     pContextRec->ctx_env[4],
-			     pContextRec->ctx_env[5],
-		             pContextRec->ctx_env[6]));
-
-    		for (ulCounter = 0;
-		     ulCounter < 8; /* see TOOLKIT\INCLUDE\BSEEXPT.H, _CONTEXT structure */
-		     ulCounter ++)
-		      dprintf(("   FP-Stack[%u] losig=%08x hisig=%08x signexp=%04x\n",
-		               ulCounter,
-		               pContextRec->ctx_stack[0].losig,
-		               pContextRec->ctx_stack[0].hisig,
-		               pContextRec->ctx_stack[0].signexp));
-	}
-	
-	return TRUE;
+        if(wincontextrec.ContextFlags & WINCONTEXT_FLOATING_POINT) {
+                //TODO: First 7 dwords the same?
+                memcpy(pContextRec->ctx_env, &wincontextrec.FloatSave, sizeof(pContextRec->ctx_env));
+                memcpy(pContextRec->ctx_stack, &wincontextrec.FloatSave.RegisterArea, sizeof(pContextRec->ctx_stack));
+        }
+        if (pContextRec->ContextFlags & CONTEXT_CONTROL)         /* check flags */
+                dprintf(("   SS:ESP=%04x:%08x EFLAGS=%08x\n",
+                             pContextRec->ctx_SegSs,
+                             pContextRec->ctx_RegEsp,
+                             pContextRec->ctx_EFlags));
+                dprintf(("   CS:EIP=%04x:%08x EBP   =%08x\n",
+                             pContextRec->ctx_SegCs,
+                             pContextRec->ctx_RegEip,
+                             pContextRec->ctx_RegEbp));
+
+        if (pContextRec->ContextFlags & CONTEXT_INTEGER)         /* check flags */
+                    dprintf(("   EAX=%08x EBX=%08x ESI=%08x\n",
+                             pContextRec->ctx_RegEax,
+                             pContextRec->ctx_RegEbx,
+                             pContextRec->ctx_RegEsi));
+                    dprintf(("   ECX=%08x EDX=%08x EDI=%08x\n",
+                             pContextRec->ctx_RegEcx,
+                             pContextRec->ctx_RegEdx,
+                             pContextRec->ctx_RegEdi));
+
+        if (pContextRec->ContextFlags & CONTEXT_SEGMENTS)        /* check flags */
+                    dprintf(("   DS=%04x     ES=%08x"
+                             "   FS=%04x     GS=%04x\n",
+                              pContextRec->ctx_SegDs,
+                              pContextRec->ctx_SegEs,
+                              pContextRec->ctx_SegFs,
+                              pContextRec->ctx_SegGs));
+
+        if (pContextRec->ContextFlags & CONTEXT_FLOATING_POINT)  /* check flags */
+        {
+            ULONG ulCounter;                 /* temporary local counter for fp stack */
+
+                dprintf(("   Env[0]=%08x Env[1]=%08x Env[2]=%08x Env[3]=%08x\n",
+                             pContextRec->ctx_env[0],
+                             pContextRec->ctx_env[1],
+                             pContextRec->ctx_env[2],
+                             pContextRec->ctx_env[3]));
+
+                dprintf(("   Env[4]=%08x Env[5]=%08x Env[6]=%08x\n",
+                             pContextRec->ctx_env[4],
+                             pContextRec->ctx_env[5],
+                             pContextRec->ctx_env[6]));
+
+                for (ulCounter = 0;
+                     ulCounter < 8; /* see TOOLKIT\INCLUDE\BSEEXPT.H, _CONTEXT structure */
+                     ulCounter ++)
+                      dprintf(("   FP-Stack[%u] losig=%08x hisig=%08x signexp=%04x\n",
+                               ulCounter,
+                               pContextRec->ctx_stack[0].losig,
+                               pContextRec->ctx_stack[0].hisig,
+                               pContextRec->ctx_stack[0].signexp));
+        }
+
+        return TRUE;
   }
   dprintf(("Win32 exception handler returned %x", rc));
Index: trunk/src/kernel32/oslibexcept.h
===================================================================
--- trunk/src/kernel32/oslibexcept.h	(revision 4223)
+++ trunk/src/kernel32/oslibexcept.h	(revision 4224)
@@ -1,3 +1,3 @@
-/* $Id: oslibexcept.h,v 1.1 1999-10-09 15:03:24 sandervl Exp $ */
+/* $Id: oslibexcept.h,v 1.2 2000-09-08 18:07:50 sandervl Exp $ */
 /*
  * Exception handler util. procedures
@@ -14,7 +14,7 @@
 //         FALSE, otherwise
 //******************************************************************************
-BOOL OSLibDispatchException(PEXCEPTIONREPORTRECORD pReportRec, 
-                            PEXCEPTIONREGISTRATIONRECORD pRegistrationRec, 
-                            PCONTEXTRECORD pContextRec, PVOID p);
+BOOL APIENTRY OSLibDispatchException(PEXCEPTIONREPORTRECORD pReportRec,
+                                     PEXCEPTIONREGISTRATIONRECORD pRegistrationRec,
+                                     PCONTEXTRECORD pContextRec, PVOID p);
 
 #endif
Index: trunk/src/kernel32/resource.cpp
===================================================================
--- trunk/src/kernel32/resource.cpp	(revision 4223)
+++ trunk/src/kernel32/resource.cpp	(revision 4224)
@@ -1,3 +1,3 @@
-/* $Id: resource.cpp,v 1.16 2000-05-28 16:45:12 sandervl Exp $ */
+/* $Id: resource.cpp,v 1.17 2000-09-08 18:07:50 sandervl Exp $ */
 
 /*
@@ -206,5 +206,5 @@
     if (pModule == NULL)
     {
-        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); //todo: right error????
         return FALSE;
     }
@@ -244,5 +244,5 @@
     if (pModule == NULL)
     {
-        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); //todo: right error????
         return FALSE;
     }
@@ -277,10 +277,17 @@
                                      LONG lParam)
 {
-
-  dprintf(("KERNEL32:EnumResourceLanguagesA(%08x,%08x,%08x,%08x,%08x)\n not implemented",
-           hModule, lpType, lpName, lpEnumFunc, lParam
-          ));
-
-  return (FALSE);
+    Win32ImageBase *pModule;
+
+    dprintf(("KERNEL32:EnumResourceLanguagesA(%08x,%08x,%08x,%08x,%08x)",
+              hModule, lpType, lpName, lpEnumFunc, lParam));
+
+    pModule = Win32ImageBase::findModule(hModule);
+    if (pModule == NULL)
+    {
+        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); //todo: right error????
+        return FALSE;
+    }
+
+    return pModule->enumResourceLanguagesA(hModule, lpType, lpName, lpEnumFunc, lParam);
 }
 
@@ -311,13 +318,17 @@
                                      LONG lParam)
 {
-
-  dprintf(("KERNEL32:EnumResourceLanguagesW(%08x,%08x,%08x,%08x,%08x)\n not implemented",
-           hModule, lpType, lpName, lpEnumFunc, lParam
-          ));
-
-  return (FALSE);
-}
-
-
+    Win32ImageBase *pModule;
+
+    dprintf(("KERNEL32:EnumResourceLanguagesW(%08x,%08x,%08x,%08x,%08x)",
+              hModule, lpType, lpName, lpEnumFunc, lParam));
+
+    pModule = Win32ImageBase::findModule(hModule);
+    if (pModule == NULL)
+    {
+        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); //todo: right error????
+        return FALSE;
+    }
+    return pModule->enumResourceLanguagesW(hModule, lpType, lpName, lpEnumFunc, lParam);
+}
 
 /*****************************************************************************
@@ -331,5 +342,5 @@
  * Variables :
  * Result    : If the function succeeds, the return value is nonzero.
- * If the function fails, the return value is zero
+ *             If the function fails, the return value is zero
  * Remark    :
  * Status    : UNTESTED STUB
@@ -349,5 +360,5 @@
     if (pModule == NULL)
     {
-        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); //todo: right error????
         return FALSE;
     }
@@ -366,5 +377,5 @@
  * Variables :
  * Result    : If the function succeeds, the return value is nonzero.
- * If the function fails, the return value is zero
+ *             If the function fails, the return value is zero
  * Remark    :
  * Status    : UNTESTED STUB
@@ -384,5 +395,5 @@
     if (pModule == NULL)
     {
-        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); //todo: right error????
         return FALSE;
     }
Index: trunk/src/kernel32/stubs.cpp
===================================================================
--- trunk/src/kernel32/stubs.cpp	(revision 4223)
+++ trunk/src/kernel32/stubs.cpp	(revision 4224)
@@ -1739,5 +1739,8 @@
                                  LPDWORD lpNumberOfBytesWritten)
 {
-  dprintf(("Kernel32: WriteProcessMemory(%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
+  // do some (faked) access check
+  if (hProcess != GetCurrentProcess())
+  {
+    dprintf(("Kernel32: WriteProcessMemory(%08xh,%08xh,%08xh,%08xh,%08xh) not implemented (different process!!)",
            hProcess,
            lpBaseAddress,
@@ -1745,11 +1748,13 @@
            cbWrite,
            lpNumberOfBytesWritten));
-  
-  // do some (faked) access check
-  if (hProcess != GetCurrentProcess())
-  {
     SetLastError(ERROR_ACCESS_DENIED);
     return FALSE;
   }
+  dprintf(("Kernel32: WriteProcessMemory(%08xh,%08xh,%08xh,%08xh,%08xh))",
+           hProcess,
+           lpBaseAddress,
+           lpBuffer,
+           cbWrite,
+           lpNumberOfBytesWritten));
   
   // FIXME: check this, if we ever run win32 binaries in different addressspaces
Index: trunk/src/kernel32/winimagebase.h
===================================================================
--- trunk/src/kernel32/winimagebase.h	(revision 4223)
+++ trunk/src/kernel32/winimagebase.h	(revision 4224)
@@ -1,3 +1,3 @@
-/* $Id: winimagebase.h,v 1.14 2000-08-16 08:04:44 sandervl Exp $ */
+/* $Id: winimagebase.h,v 1.15 2000-09-08 18:07:51 sandervl Exp $ */
 
 /*
@@ -82,4 +82,8 @@
 	BOOL  enumResourceTypesW(HMODULE hmod, ENUMRESTYPEPROCW lpEnumFunc, 
                                  LONG lParam);
+	BOOL  enumResourceLanguagesA(HMODULE hmod, LPCSTR lpType, LPCSTR lpName, 
+                                     ENUMRESLANGPROCA lpEnumFunc, LONG lParam);
+	BOOL  enumResourceLanguagesW(HMODULE hmod, LPCWSTR lpType, LPCWSTR lpName, 
+                                     ENUMRESLANGPROCW lpEnumFunc, LONG lParam);
 
 	ULONG getVersionSize();
Index: trunk/src/kernel32/winimgres.cpp
===================================================================
--- trunk/src/kernel32/winimgres.cpp	(revision 4223)
+++ trunk/src/kernel32/winimgres.cpp	(revision 4224)
@@ -1,3 +1,3 @@
-/* $Id: winimgres.cpp,v 1.45 2000-08-17 18:22:18 sandervl Exp $ */
+/* $Id: winimgres.cpp,v 1.46 2000-09-08 18:07:52 sandervl Exp $ */
 
 /*
@@ -810,2 +810,98 @@
 //******************************************************************************
 //******************************************************************************
+BOOL Win32ImageBase::enumResourceLanguagesA(HMODULE hmod, LPCSTR lpszType, 
+                                            LPCSTR lpszName, 
+                                            ENUMRESLANGPROCA lpEnumFunc, 
+                                            LONG lParam)
+{
+ PIMAGE_RESOURCE_DIRECTORY pResDirRet;
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY paResDirEntries;
+ BOOL   fRet;
+
+    if (pResRootDir == NULL)
+    {
+        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+        return FALSE;
+    }
+
+    if ((ULONG)lpEnumFunc < 0x10000 || (ULONG)lpEnumFunc >= 0xc0000000)
+    {
+        SetLastError(ERROR_NOACCESS);
+        return FALSE;
+    }
+
+    pResDirRet = getResSubDirA(pResRootDir, lpszType);
+    if(!pResDirRet) {
+	SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
+	return FALSE;
+    }
+    pResDirRet = getResSubDirA(pResDirRet, lpszName);
+    if(!pResDirRet) {
+	SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
+	return FALSE;
+    }
+
+    paResDirEntries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG)pResDirRet + sizeof(*pResDirRet));
+    if(pResDirRet->NumberOfNamedEntries) {
+	DebugInt3();
+    }
+    paResDirEntries += pResDirRet->NumberOfNamedEntries;
+
+    for(int i = 0;i < pResDirRet->NumberOfIdEntries;i++) 
+    {
+	fRet = lpEnumFunc(hmod, lpszType, lpszName, paResDirEntries[i].u1.Id, lParam);
+	if(!fRet)
+		break;
+    }
+    return fRet;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL Win32ImageBase::enumResourceLanguagesW(HMODULE hmod, LPCWSTR lpszType, 
+                                            LPCWSTR lpszName, 
+                                            ENUMRESLANGPROCW lpEnumFunc, 
+                                            LONG lParam)
+{
+ PIMAGE_RESOURCE_DIRECTORY pResDirRet;
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY paResDirEntries;
+ BOOL   fRet;
+
+    if (pResRootDir == NULL)
+    {
+        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+        return FALSE;
+    }
+
+    if ((ULONG)lpEnumFunc < 0x10000 || (ULONG)lpEnumFunc >= 0xc0000000)
+    {
+        SetLastError(ERROR_NOACCESS);
+        return FALSE;
+    }
+
+    pResDirRet = getResSubDirW(pResRootDir, lpszType);
+    if(!pResDirRet) {
+	SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
+	return FALSE;
+    }
+    pResDirRet = getResSubDirW(pResDirRet, lpszName);
+    if(!pResDirRet) {
+	SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
+	return FALSE;
+    }
+
+    paResDirEntries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((ULONG)pResDirRet + sizeof(*pResDirRet));
+    if(pResDirRet->NumberOfNamedEntries) {
+	DebugInt3();
+    }
+    paResDirEntries += pResDirRet->NumberOfNamedEntries;
+
+    for(int i = 0;i < pResDirRet->NumberOfIdEntries;i++) 
+    {
+	fRet = lpEnumFunc(hmod, lpszType, lpszName, paResDirEntries[i].u1.Id, lParam);
+	if(!fRet)
+		break;
+    }
+    return fRet;
+}
+//******************************************************************************
+//******************************************************************************
