Index: trunk/src/kernel32/Fileio.cpp
===================================================================
--- trunk/src/kernel32/Fileio.cpp	(revision 3482)
+++ trunk/src/kernel32/Fileio.cpp	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: Fileio.cpp,v 1.29 2000-04-15 10:00:44 sandervl Exp $ */
+/* $Id: Fileio.cpp,v 1.30 2000-05-02 20:53:11 sandervl Exp $ */
 
 /*
@@ -6,5 +6,4 @@
  * Copyright 1998 Sander van Leeuwen
  * Copyright 1998 Patrick Haller
- *
  *
  * Project Odin Software License can be found in LICENSE.TXT
@@ -773,26 +772,4 @@
   return(length-1);
 }
-//******************************************************************************
-//******************************************************************************
-ODINFUNCTION3(HANDLE, FindFirstChangeNotificationA,
-              LPCSTR, lpPathName,
-              BOOL, bWatchSubtree,
-              DWORD, dwNotifyFilter)
-{
-  dprintf(("KERNEL32:  FindFirstChangeNotificationA, Not implemented\n"));
-  return(0);
-}
-//******************************************************************************
-//******************************************************************************
-ODINFUNCTION1(BOOL, FindNextChangeNotification,
-              HANDLE, hChange)
-{
-  dprintf(("KERNEL32: FindNextChangeNotification (%08xh), Not implemented\n",
-           hChange));
-
-  return(0);
-}
-//******************************************************************************
-//******************************************************************************
 ODINPROCEDURE0(SetFileApisToANSI)
 {
@@ -933,3 +910,65 @@
 }
 
-
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION3(HANDLE, FindFirstChangeNotificationA,
+              LPCSTR, lpPathName,
+              BOOL, bWatchSubtree,
+              DWORD, dwNotifyFilter)
+{
+  dprintf(("KERNEL32:  FindFirstChangeNotificationA, Not implemented (faked)\n"));
+  return -1;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(BOOL, FindNextChangeNotification,
+              HANDLE, hChange)
+{
+  dprintf(("KERNEL32: FindNextChangeNotification (%08xh), Not implemented\n",
+           hChange));
+
+  return FALSE;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(BOOL, FindCloseChangeNotification, HANDLE, hChange)
+{
+  dprintf(("KERNEL32:  OS2FindNextChangeNotification, Not implemented\n"));
+
+  return(TRUE);
+}
+/*****************************************************************************
+ * Name      : HANDLE WIN32API FindFirstChangeNotificationW
+ * Purpose   : The FindFirstChangeNotification function creates a change
+ *             notification handle and sets up initial change notification
+ *             filter conditions. A wait on a notification handle succeeds when
+ *             a change matching the filter conditions occurs in the specified
+ *             directory or subtree.
+ * Parameters: LPCWSTR lpPathName           pointer to name of directory to watch
+ *             BOOL bWatchSubtree           flag for monitoring directory or
+ *                                          directory tree
+ *             DWORD dwNotifyFilter         filter conditions to watch for
+ * Variables :
+ * Result    : If the function succeeds, the return value is a handle to a find
+ *             change notification object.
+ *             If the function fails, the return value is INVALID_HANDLE_VALUE
+ * Remark    :
+ * Status    : UNTESTED STUB
+ *
+ * Author    : Markus Montkowski [Tha, 1998/05/21 20:57]
+ *****************************************************************************/
+ODINFUNCTION3(HANDLE, FindFirstChangeNotificationW, LPCWSTR, lpPathName,
+                                                    BOOL, bWatchSubtree,
+                                                    DWORD, dwNotifyFilter)
+{
+  LPSTR  lpAsciiPath;
+  HANDLE hChange;
+
+    lpAsciiPath = UnicodeToAsciiString( (LPWSTR) lpPathName);
+    hChange = FindFirstChangeNotificationA(lpAsciiPath, bWatchSubtree, 
+                                           dwNotifyFilter );
+    if (lpAsciiPath) FreeAsciiString(lpAsciiPath);
+    return hChange;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/kernel32/KERNEL32.CPP
===================================================================
--- trunk/src/kernel32/KERNEL32.CPP	(revision 3482)
+++ trunk/src/kernel32/KERNEL32.CPP	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: KERNEL32.CPP,v 1.43 2000-04-08 20:09:42 sandervl Exp $ */
+/* $Id: KERNEL32.CPP,v 1.44 2000-05-02 20:53:11 sandervl Exp $ */
 
 /*
@@ -160,8 +160,10 @@
 //******************************************************************************
 //******************************************************************************
-VOID WIN32API SetLastError( DWORD arg1)
-{
-    dprintf2(("KERNEL32:  SetLastError to %d\n", arg1));
-    O32_SetLastError(arg1);
+VOID WIN32API SetLastError( DWORD dwError)
+{
+    if(dwError != 0) {
+    	dprintf2(("KERNEL32:  SetLastError to %d\n", dwError));
+    }
+    O32_SetLastError(dwError);
 }
 //******************************************************************************
@@ -685,11 +687,4 @@
 }
 
-BOOL WIN32API FindCloseChangeNotification(HANDLE hChange)
-{
-  dprintf(("KERNEL32:  OS2FindNextChangeNotification, Not implemented\n"));
-
-  return(TRUE);
-}
-
 //******************************************************************************
 //******************************************************************************
Index: trunk/src/kernel32/dbglocal.cpp
===================================================================
--- trunk/src/kernel32/dbglocal.cpp	(revision 3482)
+++ trunk/src/kernel32/dbglocal.cpp	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: dbglocal.cpp,v 1.6 2000-04-29 18:26:57 sandervl Exp $ */
+/* $Id: dbglocal.cpp,v 1.7 2000-05-02 20:53:11 sandervl Exp $ */
 
 /*
@@ -117,5 +117,6 @@
 "hmthread",
 "hmprocess",
-"vsemaphore"
+"vsemaphore",
+"exceptstackdump"
 };
 //******************************************************************************
Index: trunk/src/kernel32/dbglocal.h
===================================================================
--- trunk/src/kernel32/dbglocal.h	(revision 3482)
+++ trunk/src/kernel32/dbglocal.h	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: dbglocal.h,v 1.6 2000-04-29 18:26:58 sandervl Exp $ */
+/* $Id: dbglocal.h,v 1.7 2000-05-02 20:53:12 sandervl Exp $ */
 
 /*
@@ -117,5 +117,6 @@
 #define DBG_hmprocess      95
 #define DBG_VSemaphore     96
-#define DBG_MAXFILES       97
+#define DBG_exceptstackdump 97
+#define DBG_MAXFILES       98
 
 extern USHORT DbgEnabled[DBG_MAXFILES];
Index: trunk/src/kernel32/exceptions.cpp
===================================================================
--- trunk/src/kernel32/exceptions.cpp	(revision 3482)
+++ trunk/src/kernel32/exceptions.cpp	(revision 3483)
@@ -1,6 +1,6 @@
-/* $Id: exceptions.cpp,v 1.39 2000-04-14 22:35:27 sandervl Exp $ */
+/* $Id: exceptions.cpp,v 1.40 2000-05-02 20:53:12 sandervl Exp $ */
 
 /*
- * Win32 Device IOCTL API functions for OS/2
+ * Win32 Exception functions for OS/2
  *
  * Ported Wine exception handling code
@@ -65,4 +65,5 @@
 #include <wprocess.h>
 #include "oslibexcept.h"
+#include "exceptstackdump.h"
 
 #define DBG_LOCALLOG	DBG_exceptions
@@ -535,14 +536,4 @@
 
 
-//******************************************************************************
-APIRET APIENTRY DosQueryModFromEIP (PULONG pulModule,
-                                    PULONG pulObject,
-                                    ULONG  ulBufferLength,
-                                    PSZ    pszBuffer,
-                                    PULONG pulOffset,
-                                    ULONG  ulEIP);
-//******************************************************************************
-
-
 /*****************************************************************************
  * Name      : void static dprintfException
@@ -840,6 +831,6 @@
            pERepRec->ExceptionAddress));
 
-  if (rc == NO_ERROR)
-    dprintf(("%s (#%u), obj #%u:%08x\n",
+  if(rc == NO_ERROR && ulObject != -1)
+    dprintf(("<%s> (#%u), obj #%u:%08x\n",
              szModule,
              ulModule,
@@ -847,5 +838,5 @@
              ulOffset));
   else
-    dprintf(("\n"));
+    dprintf(("<win32 app>\n"));
 
 
@@ -920,5 +911,4 @@
   dprintf(("---[End Of Exception Information]-----\n"));
 }
-
 
 /*****************************************************************************
@@ -1058,5 +1048,10 @@
 CrashAndBurn:
 	CheckLogException();
-  	dprintfException(pERepRec, pERegRec, pCtxRec, p);
+#ifdef DEBUG
+	dprintfException(pERepRec, pERegRec, pCtxRec, p);
+  	if(pCtxRec->ContextFlags & CONTEXT_CONTROL) {
+		dbgPrintStack(pERepRec, pERegRec, pCtxRec, p);
+	}
+#endif
 	if(fIsOS2Image == FALSE)  //Only for real win32 apps
 	{
Index: trunk/src/kernel32/exceptstackdump.cpp
===================================================================
--- trunk/src/kernel32/exceptstackdump.cpp	(revision 3483)
+++ trunk/src/kernel32/exceptstackdump.cpp	(revision 3483)
@@ -0,0 +1,312 @@
+/* $Id: exceptstackdump.cpp,v 1.1 2000-05-02 20:53:12 sandervl Exp $ */
+/*
+ * Stack dump code
+ *
+ * Based on XFolder's stack dumping facility:
+ *      	  Copyright (C) 1992-99 Ulrich Mller,
+ *                                      Kim Rasmussen,
+ *                                      Marc Fiammante,
+ *                                      John Currier,
+ *                                      Anthony Cruise.
+ *
+ */
+
+#define INCL_MISC
+#define INCL_BASE
+#include <os2.h>                     //No wrappers needed
+#include <stdio.h>
+#include <string.h>
+#include <misc.h>
+#include "exceptstackdump.h"
+#include "exceptutil.h"
+#include "oslibmisc.h"
+#include "winexebase.h"
+#include "windllbase.h"
+
+#define DBG_LOCALLOG	DBG_exceptstackdump
+#include "dbglocal.h"
+
+int SYSTEM EXPORT WriteLogNoEOL(char *tekst, ...);
+
+#undef dprintf
+#define dprintf(a)     if(DbgEnabled[DBG_LOCALLOG] == 1) WriteLogNoEOL a
+
+/* ******************************************************************
+ *                                                                  *
+ *   PART 3: ANALYZE SYMBOL (.SYM) FILE                             *
+ *                                                                  *
+ ********************************************************************/
+
+/*
+ *@@ dbgPrintSYMInfo:
+ *      this gets called by dbgPrintStack to check if a SYM
+ *      file with the same filename exists and try to
+ *      get the info from there.
+ *
+ *      This gets called for every line of the stack
+ *      walk, but only if getting the information from
+ *      the debug code failed, e.g. because no debug code
+ *      was available.
+ *      The file pointer is in the "Source file" column
+ *      every time.
+ *
+ *      New with V0.84.
+ */
+
+BOOL dbgPrintSYMInfo(CHAR * SymFileName, ULONG Object, ULONG TrapOffset)
+{
+    static FILE    *SymFile;
+    static MAPDEF   MapDef;
+    static SEGDEF   SegDef;
+    static SEGDEF  *pSegDef;
+    static SYMDEF32 SymDef32;
+    static SYMDEF16 SymDef16;
+    static char     Buffer[256];
+    static int      SegNum, SymNum, LastVal;
+    static unsigned long int SegOffset,
+                    SymOffset, SymPtrOffset;
+    int rc = FALSE;
+
+    // open .SYM file
+    SymFile = fopen(SymFileName, "rb");
+    if (SymFile == 0)
+    {
+//        dprintf(("Could not open symbol file %s", SymFileName));
+	goto endofprintsym;
+    }                           // endif
+
+    // read in first map definition
+    fread(&MapDef, sizeof(MAPDEF), 1, SymFile);
+
+    SegOffset = SEGDEFOFFSET(MapDef);
+
+    // go thru all segments
+    for (SegNum = 0; SegNum < MapDef.cSegs; SegNum++)
+    {
+        // printf("Scanning segment #%d Offset %4.4hX",SegNum+1,SegOffset);
+        if (fseek(SymFile, SegOffset, SEEK_SET))
+        {
+            dprintf(("Seek error."));
+	    goto endofprintsym;
+        }
+
+        // read in segment definition
+        fread(&SegDef, sizeof(SEGDEF), 1, SymFile);
+        if (SegNum == Object)
+        {
+            // stack object found:
+            Buffer[0] = 0x00;
+            LastVal = 0;
+
+            // go thru all symbols in this object
+            for (SymNum = 0; SymNum < SegDef.cSymbols; SymNum++)
+            {
+                // read in symbol offset USHORT
+                SymPtrOffset = SYMDEFOFFSET(SegOffset, SegDef, SymNum);
+                fseek(SymFile, SymPtrOffset, SEEK_SET);
+                fread(&SymOffset, sizeof(unsigned short int), 1, SymFile);
+
+                // go to symbol definition
+                fseek(SymFile, SymOffset + SegOffset, SEEK_SET);
+
+                if (SegDef.bFlags & 0x01)
+                {
+                    // 32-bit symbol:
+                    fread(&SymDef32, sizeof(SYMDEF32), 1, SymFile);
+#if 0
+                    if (SymDef32.wSymVal == TrapOffset)
+                    {
+                    	Buffer[0] = SymDef32.achSymName[0];
+                    	fread(&Buffer[1], 1, SymDef32.cbSymName, SymFile);
+                    	Buffer[SymDef32.cbSymName] = 0x00;
+                        dprintf(("%s\n", Buffer));
+			rc = TRUE;
+			break;
+		    }
+#endif
+		    //SvL: If it's an exact match, then the app put a procedure
+                    //     address on the stack; ignore that
+		    if (LastVal == TrapOffset) {
+			break;
+		    }
+                    if (SymDef32.wSymVal > TrapOffset)
+                    {
+                        // symbol found
+                        dprintf(("between %s + 0x%X", Buffer, TrapOffset - LastVal));
+                    }
+                    LastVal = SymDef32.wSymVal;
+                    Buffer[0] = SymDef32.achSymName[0];
+                    fread(&Buffer[1], 1, SymDef32.cbSymName, SymFile);
+                    Buffer[SymDef32.cbSymName] = 0x00;
+
+                    if (SymDef32.wSymVal > TrapOffset)
+                    {
+                        // symbol found, as above
+                        dprintf(("  and %s - 0x%X\n", Buffer, LastVal - TrapOffset));
+			rc = TRUE;
+                        break;
+		    }
+                    /*printf("32 Bit Symbol <%s> Address %p",Buffer,SymDef32.wSymVal); */
+                }
+                else
+                {
+                    // 16-bit symbol:
+                    fread(&SymDef16, sizeof(SYMDEF16), 1, SymFile);
+
+		    //SvL: If it's an exact match, then the app put a procedure
+                    //     address on the stack; ignore that
+		    if (LastVal == TrapOffset) {
+			break;
+		    }
+
+                    if (SymDef16.wSymVal > TrapOffset)
+                    {
+                        dprintf(("between %s + %X", Buffer, TrapOffset - LastVal));
+                    }
+                    LastVal = SymDef16.wSymVal;
+                    Buffer[0] = SymDef16.achSymName[0];
+                    fread(&Buffer[1], 1, SymDef16.cbSymName, SymFile);
+                    Buffer[SymDef16.cbSymName] = 0x00;
+                    if (SymDef16.wSymVal > TrapOffset)
+                    {
+                        dprintf(("  and %s - %X\n", Buffer, LastVal - TrapOffset));
+			rc = TRUE;
+                        break;
+                    }
+                    /*printf("16 Bit Symbol <%s> Address %p",Buffer,SymDef16.wSymVal); */
+                }               // endif
+            }
+            break;
+        }                       // endif
+        SegOffset = NEXTSEGDEFOFFSET(SegDef);
+    }                           // endwhile
+endofprintsym:
+    if(SymFile) fclose(SymFile);
+    if(rc == FALSE) dprintf(("\n"));
+    return rc;
+}
+//******************************************************************************
+//******************************************************************************
+void dbgPrintStack(PEXCEPTIONREPORTRECORD       pERepRec,
+                   PEXCEPTIONREGISTRATIONRECORD pERegRec,
+                   PCONTEXTRECORD               pCtxRec,
+                   PVOID                        p)
+{
+ ULONG  Size, Attr, hMod, ObjNum, Offset, addr;
+ APIRET rc;
+ PTIB   ptib = NULL;
+ PPIB   ppib = NULL;
+ CHAR   Name[CCHMAXPATH] = "unknown";
+ ULONG *stacktop, *stackbase;
+ UCHAR  instr;
+ static BOOL fEntered = FALSE;
+
+  if(DosGetInfoBlocks(&ptib, &ppib) || ptib == NULL) {
+	return;
+  }
+  if(fEntered == TRUE) {
+	return;
+  }
+
+  fEntered = TRUE;
+
+  stacktop  = (ULONG *)ptib->tib_pstacklimit - 4;
+  stackbase = (ULONG *)ptib->tib_pstack;
+  if(pCtxRec->ctx_RegEsp < (ULONG)stacktop && pCtxRec->ctx_RegEsp > (ULONG)stackbase)
+  {
+	stackbase = (ULONG *)pCtxRec->ctx_RegEsp;
+  }
+  else
+  if(pCtxRec->ctx_RegEbp < (ULONG)stacktop && pCtxRec->ctx_RegEbp > (ULONG)stackbase)
+  {
+	stackbase = (ULONG *)pCtxRec->ctx_RegEbp;
+  }
+  else  stackbase = (ULONG *)getESP();
+
+  dprintf(("** BEGIN STACK DUMP **\n"));
+  while(stacktop > stackbase) 
+  {
+    	Size = 10;
+     	rc = DosQueryMem((PVOID) (stacktop), &Size, &Attr);
+       	if(rc != NO_ERROR || !(Attr & PAG_COMMIT) || (Size < 4))
+       	{
+       		break;
+        }
+
+	addr = *stacktop;
+	Size = 16;
+     	rc = DosQueryMem((PVOID) (*stacktop-16), &Size, &Attr);
+      	if(rc != NO_ERROR || ((Attr & (PAG_EXECUTE|PAG_READ|PAG_COMMIT)) != (PAG_EXECUTE|PAG_READ|PAG_COMMIT)) || (Size < 16)) {
+//		dprintf(("skiploop %x (rc %x, Attr %x Size %d)\n", *stacktop, rc, Attr, Size));
+		if(WinExe && WinExe->insideModule(addr) && WinExe->insideModuleCode(addr)) {
+			sprintf(Name, "%s.EXE", WinExe->getModuleName());
+			dprintf(("%-13s      at 0x%08x\n", Name, addr));
+		}
+		else {
+		  	Win32DllBase *dll = Win32DllBase::findModuleByAddr(addr);
+			if(dll && dll->insideModuleCode(addr)) {
+				sprintf(Name, "%s.DLL", dll->getModuleName());
+				dprintf(("%-13s      at 0x%08x\n", Name, addr));
+			}
+		}
+
+		goto skiploop;
+	}
+#if 0
+	instr = *(UCHAR *)(((ULONG)*stacktop) - 5);
+	if(instr == 0xE8) {//call with displacement
+		addr = *(ULONG *)(((ULONG)*stacktop)-4);
+		addr+= (((ULONG)*stacktop)-5);
+  	}
+//	else {
+//	if(*(UCHAR *)(((ULONG)*stacktop) - 6) == 0xff) {
+//		modrm = *(UCHAR *)(((ULONG)*stacktop) - 5);
+//        }
+	else
+#endif
+	addr = *stacktop;
+
+        rc = DosQueryModFromEIP(&hMod, &ObjNum, sizeof(Name),
+                                Name, &Offset, addr);
+        if(rc == NO_ERROR && ObjNum != -1)
+        {
+             	DosQueryModuleName(hMod, sizeof(Name), Name);
+
+	     	int namelen = strlen(Name);
+             	if(namelen > 3)
+             	{
+			if(addr > (ULONG)ptib->tib_pstacklimit || addr < (ULONG)ptib->tib_pstack) {
+             			// print module and object
+             			dprintf(("%-13s %04X at 0x%08x ", OSLibStripPath(Name), ObjNum + 1, addr));
+
+	             		strcpy(Name + namelen - 3, "SYM");
+		                dbgPrintSYMInfo(Name, ObjNum, Offset);
+			}
+             	}
+             	else
+             	{
+			dprintf(("*Unknown* at %x\n", addr));
+             	}
+        }
+	else {
+		if(WinExe && WinExe->insideModule(addr) && WinExe->insideModuleCode(addr)) {
+			sprintf(Name, "%s.EXE", WinExe->getModuleName());
+			dprintf(("%-13s      at 0x%08x\n", Name, addr));
+		}
+		else {
+		  	Win32DllBase *dll = Win32DllBase::findModuleByAddr(addr);
+			if(dll && dll->insideModuleCode(addr)) {
+				sprintf(Name, "%s.DLL", dll->getModuleName());
+				dprintf(("%-13s      at 0x%08x\n", Name, addr));
+			}
+		}
+//		dprintf(("unknown %x at 0x%x\n", stacktop, addr));
+	}
+skiploop:
+	stacktop -= 1;
+  } //while
+  dprintf(("** END OF STACK DUMP **\n"));
+  fEntered = FALSE;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/kernel32/exceptstackdump.h
===================================================================
--- trunk/src/kernel32/exceptstackdump.h	(revision 3483)
+++ trunk/src/kernel32/exceptstackdump.h	(revision 3483)
@@ -0,0 +1,607 @@
+/* $Id: exceptstackdump.h,v 1.1 2000-05-02 20:53:12 sandervl Exp $ */
+#ifndef __EXCEPTSTACKDUMP_H__
+#define __EXCEPTSTACKDUMP_H__
+
+/*
+ *      This file incorporates code from the following:
+ *      -- Marc Fiammante, John Currier, Kim Rasmussen,
+ *         Anthony Cruise (EXCEPT3.ZIP package for a generic
+ *         exception handling DLL, available at Hobbes).
+ *
+ *      This file Copyright (C) 1992-99 Ulrich Mller,
+ *                                      Kim Rasmussen,
+ *                                      Marc Fiammante,
+ *                                      John Currier,
+ *                                      Anthony Cruise.
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation, in version 2 as it comes in the COPYING
+ *      file of the XFolder main distribution.
+ *      This program 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 General Public License for more details.
+ */
+
+#ifndef DEBUG_HEADER_INCLUDED
+    #define DEBUG_HEADER_INCLUDED
+
+    /********************************************************************
+     *                                                                  *
+     *   SYM file declarations                                          *
+     *                                                                  *
+     ********************************************************************/
+
+    // Pointer means offset from beginning of file or beginning of struct
+    #pragma pack(1)
+    typedef struct {
+        unsigned short int ppNextMap;     // paragraph pointer to next map
+        unsigned char      bFlags;        // symbol types
+        unsigned char      bReserved1;    // reserved
+        unsigned short int pSegEntry;     // segment entry point value
+        unsigned short int cConsts;       // count of constants in map
+        unsigned short int pConstDef;     // pointer to constant chain
+        unsigned short int cSegs;         // count of segments in map
+        unsigned short int ppSegDef;      // paragraph pointer to first segment
+        unsigned char      cbMaxSym;      // maximum symbol-name length
+        unsigned char      cbModName;     // length of module name
+        char               achModName[1]; // cbModName Bytes of module-name member
+    } MAPDEF;
+
+    typedef struct {
+        unsigned short int ppNextMap;     // always zero
+        unsigned char      release;       // release number (minor version number)
+        unsigned char      version;       // major version number
+    } LAST_MAPDEF;
+
+    typedef struct {
+        unsigned short int ppNextSeg;     // paragraph pointer to next segment
+        unsigned short int cSymbols;      // count of symbols in list
+        unsigned short int pSymDef;       // offset of symbol chain
+        unsigned short int wReserved1;    // reserved
+        unsigned short int wReserved2;    // reserved
+        unsigned short int wReserved3;    // reserved
+        unsigned short int wReserved4;    // reserved
+        unsigned char      bFlags;        // symbol types; bit 0 signals 32-bit (*UM)
+        unsigned char      bReserved1;    // reserved
+        unsigned short int ppLineDef;     // offset of line number record
+        unsigned char      bReserved2;    // reserved
+        unsigned char      bReserved3;    // reserved
+        unsigned char      cbSegName;     // length of segment name
+        char               achSegName[1]; /* cbSegName Bytes of segment-name member*/
+    } SEGDEF;
+
+    typedef struct {
+        unsigned short int wSymVal;       // symbol address or constant
+        unsigned char      cbSymName;     // length of symbol name
+        char               achSymName[1]; // cbSymName Bytes of symbol-name member
+    } SYMDEF16;
+
+    typedef struct {
+        unsigned       int wSymVal;       // symbol address or constant
+        unsigned char      cbSymName;     // length of symbol name
+        char               achSymName[1]; // cbSymName Bytes of symbol-name member
+    } SYMDEF32;
+
+    typedef struct {
+        unsigned short int ppNextLine;    // ptr to next linedef (0 if last)
+        unsigned short int wReserved1;    // reserved
+        unsigned short int pLines;        // pointer to line numbers
+        unsigned short int cLines;        // reserved
+        unsigned char      cbFileName;    // length of filename
+        char               achFileName[1];// cbFileName Bytes of filename
+    } LINEDEF;
+
+    typedef struct {
+        unsigned short int wCodeOffset;   // executable offset
+        unsigned short int dwFileOffset;  // source offset
+    } LINEINF;
+
+    #define SEGDEFOFFSET(MapDef)     (MapDef.ppSegDef*16)
+    #define NEXTSEGDEFOFFSET(SegDef)  (SegDef.ppNextSeg*16)
+
+    #define ASYMPTROFFSET(SegDefOffset,Segdef) (SegDefOffset+SegDef.pSymDef)
+    #define SYMDEFOFFSET(SegDefOffset,SegDef,n) (ASYMPTROFFSET(SegDefOffset,SegDef)+(n)*(sizeof(unsigned short int)))
+
+    #define ACONSTPTROFFSET(MapDef) (MapDef.ppConstDef)
+    #define CONSTDEFOFFSET(MapDef,n) ((MapDef.ppConstDef)+(n)*(sizeof(unsigned short int)))
+
+    #define LINEDEFOFFSET(SegDef) (SegDef.ppLineDef*16)
+    #define NEXTLINEDEFOFFSET(LineDef) (LineDef.ppNextLine*16)
+    #define LINESOFFSET(LinedefOffset,LineDef) ((LinedefOffset)+LineDef.pLines)
+
+    /********************************************************************
+     *                                                                  *
+     *   Object Module Format (OMF) declarations                        *
+     *                                                                  *
+     ********************************************************************/
+
+    struct exehdr_rec {
+       BYTE     signature[2];              // Must be "MZ"
+       USHORT   image_len;                 // Image Length
+       USHORT   pages;                     // Pages
+       USHORT   reloc_items;               // Relocation table items
+       USHORT   min_paragraphs;            // Mininum 16-bytes paragraphs
+       USHORT   max_paragraphs;            // Maximum 16-bytes paragraphs
+       USHORT   stack_pos;                 // Stack position
+       USHORT   offset_in_sp;              // Offset in SP
+       USHORT   checksum;                  // Checksum
+       USHORT   offset_in_ip;              // Offset in IP
+       USHORT   code_pos;                  // Code segment pos.
+       USHORT   reloc_item_pos;            // Position of first relocation item
+       USHORT   overlay_number;            // Overlay number
+       BYTE     unused[8];                 // Unused bytes
+       USHORT   oem_id;                    // OEM Identifier
+       BYTE     oem_info[24];              // OEM Info
+       ULONG    lexe_offset;               // Offset to linear header
+    };
+
+    struct lexehdr_rec {
+       BYTE     signature[2];              // Must be "LX"
+       BYTE     b_ord;                     // Byte ordering
+       BYTE     w_ord;                     // Word ordering
+       ULONG    format_level;              // Format level
+       USHORT   cpu_type;                  // CPU Type
+       USHORT   os_type;                   // Operating system
+       ULONG    module_version;            // Module version
+       ULONG    mod_flags;                 // Module flags
+       ULONG    mod_pages;                 // Module pages
+       ULONG    EIP_object;                // EIP Object no.
+       ULONG    EIP;                       // EIP Value
+       ULONG    ESP_object;                // ESP Object no
+       ULONG    ESP;                       // ESP Value
+       ULONG    page_size;                 // Page size
+       ULONG    page_ofs_shift;            // Page offset shift
+       ULONG    fixup_sect_size;           // Fixup section size
+       ULONG    fixup_sect_checksum;       // Fixup section checksum
+       ULONG    loader_sect_size;          // Loader section size
+       ULONG    loader_sect_checksum;      // Loader section checksum
+       ULONG    obj_table_ofs;             // Object table offset
+       ULONG    obj_count;                 // Object count
+       ULONG    obj_page_tab_ofs;          // Object page table offset
+       ULONG    obj_iter_page_ofs;         // Object iteration pages offset
+       ULONG    res_tab_ofs;               // Resource table offset
+       ULONG    res_table_entries;         // Resource table entries
+       ULONG    res_name_tab_ofs;          // Resident name table offset;
+       ULONG    ent_tab_ofs;               // Entry table offset
+       ULONG    mod_dir_ofs;               // Module directives offset
+       ULONG    mod_dir_count;             // Number of module directives
+       ULONG    fixup_page_tab_ofs;        // Fixup page table offset
+       ULONG    fixup_rec_tab_ofs;         // Fixup record table offset
+       ULONG    imp_tab_ofs;               // Import module table offset
+       ULONG    imp_mod_entries;           // Import module entries
+       ULONG    imp_proc_tab_ofs;          // Import proc table offset
+       ULONG    per_page_check_ofs;        // Per page checksum offset
+       ULONG    data_page_offset;          // Data pages offset
+       ULONG    preload_page_count;        // Preload pages count
+       ULONG    nonres_tab_ofs;            // Nonresident name table offset
+       ULONG    nonres_tab_len;            // Nonresident name table len
+       ULONG    nonres_tab_check;          // Nonresident tables checksum
+       ULONG    auto_ds_objectno;          // Auto DS object number
+       ULONG    debug_info_ofs;            // Debug info offset
+       ULONG    debug_info_len;            // Debug info length
+       ULONG    inst_preload_count;        // Instance preload count
+       ULONG    inst_demand_count;         // Instance demand count
+       ULONG    heapsize;                  // Heap size
+       ULONG    stacksize;                 // Stack size
+    };
+
+    struct debug_head_rec {
+       BYTE signature[3];                  // Debug signature
+       BYTE type;                          // Debug info type
+    };
+
+    struct dir_inf_rec {
+       USHORT   dirstruct_size;            // Size of directory structure
+       USHORT   number_of_entries;         // Number of dnt_rec's in the array
+       USHORT   unknown;                   // Unknown data
+       // Followed by an array of dnt_rec structures
+    };
+
+    struct dnt_rec {
+       USHORT   subsect_type;              // sst Subsection type
+       USHORT   mod_index;                 // Module index (1-based)
+       ULONG    offset;                    // Offset of start of section
+       ULONG    size;                      // Size of section
+    };
+
+    // Modules subsection
+    struct modules_rec {
+       USHORT   code_seg_base;             // Code segment base
+       ULONG    code_seg_offset;           // Code segment offset
+       ULONG    code_seg_len;              // Code segment length
+       USHORT   overlay_no;                // Overlay number
+       USHORT   lib_idx;                   // Index into library section or 0
+       BYTE     segments;                  // Number of segments
+       BYTE     reserved;
+       BYTE     debug_style[2];            // "HL" for HLL, "CV" or 0 for CodeView
+       BYTE     debug_version[2];          // 00 01 or 00 03 for HLL, 00 00 for CV
+       BYTE     name_len;                  // Length of name (which follows)
+    };
+
+    // Publics subsection
+    struct publics_rec {
+       ULONG    offset;                    // Offset
+       USHORT   segment;                   // Segment
+       USHORT   type;                      // Type index
+       BYTE     name_len;                  // Length of name (wich follows)
+    };
+
+    #if 0
+    // Linenumbers header
+    struct linhead_rec {
+       BYTE     id;                        // 0x95 for flat mem, 32 bit progs
+       USHORT   length;                    // Record length
+       USHORT   base_group;                // Base group
+       USHORT   base_segment;              // Base segment
+    };
+    #endif
+
+    // First linenumber record
+    struct linfirst_rec {
+       USHORT   lineno;                    // Line number (0)
+       BYTE     entry_type;                // Entry type
+       BYTE     reserved;                  // Reserved
+       USHORT   entries_count;             // Number of table entries
+       USHORT   segment_no;                // Segment number
+       ULONG    filename_tabsize;          // File names table size
+    };
+
+
+    // Source line numbers
+    struct linsource_rec {
+       USHORT   source_line;               // Source file line number
+       USHORT   source_idx;                // Source file index
+       ULONG    offset;                    // Offset into segment
+    };
+
+
+    // Listing statement numbers
+    struct linlist_rec {
+       ULONG    list_line;                 // Listing file linenumber
+       ULONG    statement;                 // Listing file statement number
+       ULONG    offset;                    // Offset into segment
+    };
+
+
+    // Source and Listing statement numbers
+    struct linsourcelist_rec {
+       USHORT   source_line;               // Source file line number
+       USHORT   source_idx;                // Source file index
+       ULONG    list_line;                 // Listing file linenumber
+       ULONG    statement;                 // Listing file statement number
+       ULONG    offset;                    // Offset into segment
+    };
+
+
+    // Path table
+    struct pathtab_rec {
+       ULONG    offset;                    // Offset into segment
+       USHORT   path_code;                 // Path code
+       USHORT   source_idx;                // Source file index
+    };
+
+
+    // File names table
+    struct filenam_rec {
+       ULONG    first_char;                // First displayable char in list file
+       ULONG    disp_chars;                // Number of displayable chars in list line
+       ULONG    filecount;                 // Number of source/listing files
+    };
+
+
+    // Symbol types
+    #define SYM_BEGIN          0x00        // Begin block
+    #define SYM_PROC           0x01        // Function
+    #define SYM_END            0x02        // End block of function
+    #define SYM_AUTO           0x04        // Auto variable
+    #define SYM_STATIC         0x05        // Static variable
+    #define SYM_LABEL          0x0B        // Label
+    #define SYM_WITH           0x0C        // With start symbol (not used)
+    #define SYM_REG            0x0D        // Register variable
+    #define SYM_CONST          0x0E        // Constant
+    #define SYM_ENTRY          0x0F        // Secondary entry (not in C)
+    #define SYM_SKIP           0x10        // For incremental linking (not used)
+    #define SYM_CHANGESEG      0x11        // Change segment (#pragma alloc_text)
+    #define SYM_TYPEDEF        0x12        // Typedef variable
+    #define SYM_PUBLIC         0x13        // Public reference
+    #define SYM_MEMBER         0x14        // Member of minor or major structure
+    #define SYM_BASED          0x15        // Based variable
+    #define SYM_TAG            0x16        // Tag in struct, union, enum ...
+    #define SYM_TABLE          0x17        // Table (used in RPG - not C)
+    #define SYM_MAP            0x18        // Map variable (extern in C)
+    #define SYM_CLASS          0x19        // Class symbol (C++)
+    #define SYM_MEMFUNC        0x1A        // Member function
+    #define SYM_AUTOSCOPE      0x1B        // Scoped auto for C++ (not used)
+    #define SYM_STATICSCOPE    0x1C        // scoped static for C++ (not used)
+    #define SYM_CPPPROC        0x1D        // C++ Proc
+    #define SYM_CPPSTAT        0x1E        // C++ Static var
+    #define SYM_COMP           0x40        // Compiler information
+
+
+    // Symbolic begin record
+    struct symbegin_rec {
+       ULONG    offset;                    // Segment offset
+       ULONG    length;                    // Length of block
+       BYTE     name_len;                  // Length of block name
+       // Block name follows
+    };
+
+
+    // Symbolic auto var record
+    struct symauto_rec {
+       ULONG    stack_offset;              // Stack offset
+       USHORT   type_idx;                  // Type index
+       BYTE     name_len;                  // Length of name
+       // Var name follows
+    };
+
+
+    // Symbolic procedure record
+    struct symproc_rec {
+       ULONG    offset;                    // Segment offset
+       USHORT   type_idx;                  // Type index
+       ULONG    length;                    // Length of procedure
+       USHORT   pro_len;                   // Length of prologue
+       ULONG    pro_bodylen;               // Length of prologue + body
+       USHORT   class_type;                // Class type
+       BYTE     near_far;                  // Near or far
+       BYTE     name_len;                  // Length of name
+       // Function name follows
+    };
+
+
+    // Symbolic static var record
+    struct symstatic_rec {
+       ULONG    offset;                    // Segment offset
+       USHORT   segaddr;                   // Segment address
+       USHORT   type_idx;                  // Type index
+       BYTE     name_len;                  // Length of name
+       // Var name follows
+    };
+
+
+    // Symbolic label var record
+    struct symlabel_rec {
+       ULONG    offset;                    // Segment offset
+       BYTE     near_far;                  // Near or far
+       BYTE     name_len;                  // Length of name
+       // Var name follows
+    };
+
+    // Symbolic register var record
+    struct symreg_rec {
+       USHORT   type_idx;                  // Type index
+       BYTE     reg_no;                    // Register number
+       BYTE     name_len;                  // Length of name
+       // Var name follows
+    };
+
+    // Symbolic change-segment record
+    struct symseg_rec {
+       USHORT   seg_no;                    // Segment number
+    };
+
+    // Symbolic typedef record
+    struct symtypedef_rec {
+       USHORT   type_idx;                  // Type index
+       BYTE     name_len;                  // Length of name
+       // Name follows
+    };
+
+    // Symbolic public record
+    struct sympublic_rec {
+       ULONG    offset;                    // Segment offset
+       USHORT   segaddr;                   // Segment address
+       USHORT   type_idx;                  // Type index
+       BYTE     name_len;                  // Length of name
+       // Name follows
+    };
+
+    // Symbolic member record
+    struct symmember_rec {
+       ULONG    offset;                    // Offset to subrecord
+       BYTE     name_len;                  // Length of name
+       // Name follows
+    };
+
+    // Symbolic based record
+    struct symbased_rec {
+       ULONG    offset;                    // Offset to subrecord
+       USHORT   type_idx;                  // Type index
+       BYTE     name_len;                  // Length of name
+       // Name follows
+    };
+
+    // Symbolic tag record
+    struct symtag_rec {
+       USHORT   type_idx;                  // Type index
+       BYTE     name_len;                  // Length of name
+       // Name follows
+    };
+
+
+    // Symbolic table record
+    struct symtable_rec {
+       ULONG    offset;                    // Segment offset
+       USHORT   segaddr;                   // Segment address
+       USHORT   type_idx;                  // Type index
+       ULONG    idx_ofs;                   // Index offset to subrecord
+       BYTE     name_len;                  // Length of name
+       // Name follows
+    };
+
+
+    // Type record
+    struct type_rec {
+       USHORT   length;                    // Length of sub-record
+       BYTE     type;                      // Sub-record type
+       BYTE     type_qual;                 // Type qualifier
+    };
+
+
+
+    // Types
+    #define TYPE_CLASS         0x40        // Class
+    #define TYPE_BASECLASS     0x41        // Base class
+    #define TYPE_FRIEND        0x42        // Friend
+    #define TYPE_CLASSDEF      0x43        // Class definition
+    #define TYPE_MEMBERFUNC    0x45        // Member function
+    #define TYPE_CLASSMEMBER   0x46        // Class member
+    #define TYPE_REF           0x48        // Reference
+    #define TYPE_MEMBERPTR     0x49        // Member pointer
+    #define TYPE_SCALARS       0x51        // Scalars
+    #define TYPE_SET           0x52        // Set
+    #define TYPE_ENTRY         0x53        // Entry
+    #define TYPE_FUNCTION      0x54        // Function
+    #define TYPE_AREA          0x55        // Area
+    #define TYPE_LOGICAL       0x56        // Logical
+    #define TYPE_STACK         0x57        // Stack
+    #define TYPE_MACRO         0x59        // Macro
+    #define TYPE_BITSTRING     0x5C        // Bit string
+    #define TYPE_USERDEF       0x5D        // User defined
+    #define TYPE_CHARSTR       0x60        // Character string
+    #define TYPE_PICTURE       0x61        // Picture
+    #define TYPE_GRAPHIC       0x62        // Graphic
+    #define TYPE_FORMATLAB     0x65        // Format label
+    #define TYPE_FILE          0x67        // File
+    #define TYPE_SUBRANGE      0x6F        // Subrange
+    #define TYPE_CODELABEL     0x72        // Code label
+    #define TYPE_PROCEDURE     0x75        // Procedure
+    #define TYPE_ARRAY         0x78        // Array
+    #define TYPE_STRUCT        0x79        // Structure / Union / Record
+    #define TYPE_POINTER       0x7A        // Pointer
+    #define TYPE_ENUM          0x7B        // Enum
+    #define TYPE_LIST          0x7F        // List
+
+
+    // Type userdef
+    struct type_userdefrec {
+       BYTE     FID_index;                 // Field ID
+       USHORT   type_index;                // Type index
+       BYTE     FID_string;                // String ID
+       BYTE     name_len;                  // Length of name which follows
+    };
+
+
+    // Type function
+    struct type_funcrec {
+       USHORT   params;
+       USHORT   max_params;
+       BYTE     FID_index;                 // Field ID
+       USHORT   type_index;                // Type index of return value
+       BYTE     FID_index1;                // String ID
+       USHORT   typelist_index;            // Index of list of params
+    };
+
+
+    // Type struct
+    struct type_structrec {
+       ULONG    size;                      // Size of structure
+       USHORT   field_count;               // Number of fields in structure
+       BYTE     FID_index;                 // Field ID
+       USHORT   type_list_idx;             // Index to type list
+       BYTE     FID_index1;                // Field ID
+       USHORT   type_name_idx;             // Index to names / offsets
+       BYTE     dont_know;                 // Haven't a clue, but it seems to be needed
+       BYTE     name_len;                  // Length of structure name which follows
+    };
+
+    // Type list, type qualifier 1: contains types for structures
+    // This record is repeated for the number of items in the structure definition
+    struct type_list1 {
+       BYTE     FID_index;                 // Field identifier for index
+       USHORT   type_index;                // Type index.
+    };
+
+    // Type list, type qualifier 2: contains names and offsets for structure items
+    // This record is repeated for the number of items in the structure definition
+    struct type_list2 {
+       BYTE     FID_string;                // String identifier
+       BYTE     name_len;                  // Length of name which follows
+    };
+
+    // Type list, subrecord to the above, contains offset of variable in the structure
+    struct type_list2_1 {
+       BYTE     FID_span;                  // Defines what type of variable follows
+       union {
+          BYTE   b_len;
+          USHORT s_len;
+          ULONG  l_len;
+       } u;
+    };
+
+    // Type pointer
+    struct type_pointerrec {
+       BYTE     FID_index;                 // Index identifier
+       USHORT   type_index;                // Type index
+       BYTE     FID_string;                // String identifier
+       BYTE     name_len;                  // Length of name which follows
+    };
+    #pragma pack()
+
+    /*
+     * dbgPrintStack:
+     *      this takes stack data from the TIB and
+     *      context record data structures and tries
+     *      to analyse what the different stack frames
+     *      correspond to in the source files.
+     *      This analysis is either tried upon debug
+     *      code, if present, or otherwise from a
+     *      .SYM file with the same filestem.
+     *
+     *      New with V0.84.
+     *
+     *      This is based on the EXCEPT3.ZIP package
+     *      for the generic EXCEPTQ.DLL exception handler.
+     *      Appently (W) 1995 or later John Currier.
+     *      See the copyright notices on top of this file.
+     */
+
+
+     void dbgPrintStack(PEXCEPTIONREPORTRECORD       pERepRec,
+                        PEXCEPTIONREGISTRATIONRECORD pERegRec,
+                        PCONTEXTRECORD               pCtxRec,
+                        PVOID                        p);
+
+    /*
+     * DosQueryModFromEIP:
+     *      we need to prototype this undocumented OS/2 API.
+     *      Apparently, it doesn't have to be imported, but
+     *      it's not in the header files.
+     *      This is available on OS/2 2.1 and above.
+     *      This function may be used to get a program module
+     *      name, segment number and offset within the segment
+     *      if you have an absolute address within the calling
+     *      program. Very useful for exception handlers.
+     */
+
+
+extern "C"
+{
+    APIRET APIENTRY DosQueryModFromEIP(HMODULE *phMod,   // out: trapping module
+                                       ULONG *pulObjNum, // out: object/segment number
+                                       ULONG ulBuffLen,  // in:  sizeof(*pszBuff)
+                                       CHAR *pszBuff,    // out: module name
+                                       ULONG *pulOffset, // out: offset in module
+                                       ULONG ulAddress); // in:  address to be analyzed
+
+   APIRET APIENTRY DosQueryModFromEIP (PULONG pulModule,
+                                       PULONG pulObject,
+                                       ULONG  ulBufferLength,
+                                       PSZ    pszBuffer,
+                                       PULONG pulOffset,
+                                       ULONG  ulEIP);
+
+    typedef ULONG  *_Seg16 PULONG16;
+    APIRET16 APIENTRY16 DOS16SIZESEG(USHORT Seg, PULONG16 Size);
+    typedef         APIRET16(APIENTRY16 _PFN16) ();
+    ULONG APIENTRY  DosSelToFlat(ULONG);
+
+    APIRET16 APIENTRY16 DOSQPROCSTATUS(ULONG * _Seg16 pBuf, USHORT cbBuf);
+
+    #define CONVERT(fp,QSsel) MAKEP((QSsel),OFFSETOF(fp))
+}
+#endif
+
+#endif //__EXCEPTSTACKDUMP_H__
Index: trunk/src/kernel32/exceptutil.asm
===================================================================
--- trunk/src/kernel32/exceptutil.asm	(revision 3482)
+++ trunk/src/kernel32/exceptutil.asm	(revision 3483)
@@ -1,3 +1,3 @@
-; $Id: exceptutil.asm,v 1.6 2000-03-29 17:17:18 sandervl Exp $
+; $Id: exceptutil.asm,v 1.7 2000-05-02 20:53:12 sandervl Exp $
 
 ;/*
@@ -196,4 +196,10 @@
 getGS  	endp
 
+	PUBLIC getESP
+getESP  proc near
+	mov	eax, esp
+	ret
+getESP	endp
+
 	PUBLIC RestoreOS2FS
 RestoreOS2FS proc near
Index: trunk/src/kernel32/exceptutil.h
===================================================================
--- trunk/src/kernel32/exceptutil.h	(revision 3482)
+++ trunk/src/kernel32/exceptutil.h	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: exceptutil.h,v 1.7 2000-03-18 19:49:44 sandervl Exp $ */
+/* $Id: exceptutil.h,v 1.8 2000-05-02 20:53:13 sandervl Exp $ */
 
 /*
@@ -34,4 +34,5 @@
 ULONG  getEAX();
 ULONG  getEBX();
+ULONG  getESP();
 USHORT getSS();
 USHORT getDS();
Index: trunk/src/kernel32/lang.cpp
===================================================================
--- trunk/src/kernel32/lang.cpp	(revision 3482)
+++ trunk/src/kernel32/lang.cpp	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: lang.cpp,v 1.17 2000-02-16 14:27:07 sandervl Exp $ */
+/* $Id: lang.cpp,v 1.18 2000-05-02 20:53:13 sandervl Exp $ */
 /*
  * Win32 language API functions for OS/2
@@ -89,6 +89,6 @@
   if (wbuf)
   {
-//    if (*pLen > sizeof(WCHAR))
-    if (*pLen > 2)
+//    if (*pLen >= sizeof(WCHAR))
+    if (*pLen >= 2)
     {
       wbuf[0]=(WCHAR)'0'+wcUniChar;
@@ -569,4 +569,7 @@
       case LOCALE_SABBREVMONTHNAME13:
       case LOCALE_SMONTHNAME13:
+	if(wbuf) {
+		*wbuf = 0;
+	}
         LocaleFromUniStr((LPWSTR)L"\0",wbuf,&ulInfoLen);
         break;
Index: trunk/src/kernel32/makefile
===================================================================
--- trunk/src/kernel32/makefile	(revision 3482)
+++ trunk/src/kernel32/makefile	(revision 3483)
@@ -1,3 +1,3 @@
-# $Id: makefile,v 1.93 2000-04-15 16:32:35 sandervl Exp $
+# $Id: makefile,v 1.94 2000-05-02 20:53:13 sandervl Exp $
 
 #
@@ -124,4 +124,7 @@
 $(OBJDIR)\queue.obj \
 $(OBJDIR)\hmthread.obj \
+!ifdef DEBUG
+$(OBJDIR)\exceptstackdump.obj \
+!endif
 $(OBJDIR)\kernelrsrc.obj
 
Index: trunk/src/kernel32/misc.cpp
===================================================================
--- trunk/src/kernel32/misc.cpp	(revision 3482)
+++ trunk/src/kernel32/misc.cpp	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: misc.cpp,v 1.21 2000-04-13 18:48:02 sandervl Exp $ */
+/* $Id: misc.cpp,v 1.22 2000-05-02 20:53:13 sandervl Exp $ */
 
 /*
@@ -304,4 +304,50 @@
 //******************************************************************************
 //******************************************************************************
+int SYSTEM EXPORT WriteLogNoEOL(char *tekst, ...)
+{
+  USHORT  sel = RestoreOS2FS();
+  va_list argptr;
+
+  ODIN_HEAPCHECK();
+
+  if(!init)
+  {
+    init = TRUE;
+
+#ifdef DEFAULT_LOGGING_OFF
+    if(getenv("WIN32LOG_ENABLED")) {
+#else
+    if(!getenv("NOWIN32LOG")) {
+#endif
+	char logname[CCHMAXPATH];
+
+	sprintf(logname, "odin32_%d.log", loadNr);
+      	flog = fopen(logname, "w");
+	if(flog == NULL) {//probably running exe on readonly device
+		sprintf(logname, "%sodin32_%d.log", kernel32Path, loadNr);
+	      	flog = fopen(logname, "w");
+	}
+    }
+    else
+      fLogging = FALSE;
+  }
+
+  if(fLogging && flog && (dwEnableLogging > 0))
+  {
+    THDB *thdb = GetThreadTHDB();
+
+    va_start(argptr, tekst);
+    if(thdb) { 
+	thdb->logfile = (DWORD)flog;
+    }
+    vfprintf(flog, tekst, argptr);
+    if(thdb) thdb->logfile = 0;
+    va_end(argptr);
+  }
+  SetFS(sel);
+  return 1;
+}
+//******************************************************************************
+//******************************************************************************
 void SYSTEM DecreaseLogCount()
 {
Index: trunk/src/kernel32/stubs.cpp
===================================================================
--- trunk/src/kernel32/stubs.cpp	(revision 3482)
+++ trunk/src/kernel32/stubs.cpp	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: stubs.cpp,v 1.21 2000-03-30 15:37:14 cbratschi Exp $ */
+/* $Id: stubs.cpp,v 1.22 2000-05-02 20:53:13 sandervl Exp $ */
 
 /*
@@ -1367,37 +1367,4 @@
 
 /*****************************************************************************
- * Name      : HANDLE WIN32API FindFirstChangeNotificationW
- * Purpose   : The FindFirstChangeNotification function creates a change
- *             notification handle and sets up initial change notification
- *             filter conditions. A wait on a notification handle succeeds when
- *             a change matching the filter conditions occurs in the specified
- *             directory or subtree.
- * Parameters: LPCWSTR lpPathName           pointer to name of directory to watch
- *             BOOL bWatchSubtree           flag for monitoring directory or
- *                                          directory tree
- *             DWORD dwNotifyFilter         filter conditions to watch for
- * Variables :
- * Result    : If the function succeeds, the return value is a handle to a find
- *             change notification object.
- *             If the function fails, the return value is INVALID_HANDLE_VALUE
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Markus Montkowski [Tha, 1998/05/21 20:57]
- *****************************************************************************/
-
-HANDLE WIN32API FindFirstChangeNotificationW( LPCWSTR lpPathName,
-                                                BOOL bWatchSubtree,
-                                                DWORD dwNotifyFilter)
-{
-
-  dprintf(("KERNEL32: FindFirstChangeNotificationW(%08x,%08x,%08x) not implemented - INVALID_HANDLE_VALUE\n",
-            lpPathName, bWatchSubtree, dwNotifyFilter
-          ));
-
-  return (INVALID_HANDLE_VALUE);
-}
-
-/*****************************************************************************
  * Name      : HANDLE WIN32API FindFirstFileExA
  * Purpose   : The FindFirstFileExA function searches a directory for a file
Index: trunk/src/kernel32/virtual.cpp
===================================================================
--- trunk/src/kernel32/virtual.cpp	(revision 3482)
+++ trunk/src/kernel32/virtual.cpp	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: virtual.cpp,v 1.29 2000-03-28 17:11:50 sandervl Exp $ */
+/* $Id: virtual.cpp,v 1.30 2000-05-02 20:53:13 sandervl Exp $ */
 
 /*
@@ -437,8 +437,11 @@
     if(rc)
     {
-      dprintf(("KERNEL32:VirtualFree:OsLibSetMem rc = #%d\n",
-               rc));
-      SetLastError(ERROR_INVALID_ADDRESS);
-      return(FALSE);
+	if(rc == 32803) { //SvL: ERROR_ALIAS
+      		dprintf(("KERNEL32:VirtualFree:OsLibSetMem rc = #%d; app tries to decommit aliased memory; ignore", rc));
+		return(TRUE);
+	}
+      	dprintf(("KERNEL32:VirtualFree:OsLibSetMem rc = #%d\n", rc));
+      	SetLastError(ERROR_INVALID_ADDRESS);
+	return(FALSE);
     }
   }
Index: trunk/src/kernel32/windllbase.cpp
===================================================================
--- trunk/src/kernel32/windllbase.cpp	(revision 3482)
+++ trunk/src/kernel32/windllbase.cpp	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: windllbase.cpp,v 1.12 2000-03-18 19:49:44 sandervl Exp $ */
+/* $Id: windllbase.cpp,v 1.13 2000-05-02 20:53:14 sandervl Exp $ */
 
 /*
@@ -752,4 +752,22 @@
 //******************************************************************************
 //******************************************************************************
+Win32DllBase *Win32DllBase::findModuleByAddr(ULONG address)
+{
+   dlllistmutex.enter();
+
+   Win32DllBase *mod = Win32DllBase::head;
+   while(mod != NULL) {
+	dbgCheckObj(mod);
+	if(mod->insideModule(address)) {
+		dlllistmutex.leave();
+		return(mod);
+        }
+	mod = mod->next;
+   }
+   dlllistmutex.leave();
+   return(NULL);
+}
+//******************************************************************************
+//******************************************************************************
 BOOL Win32DllBase::isDll()
 {
Index: trunk/src/kernel32/windllbase.h
===================================================================
--- trunk/src/kernel32/windllbase.h	(revision 3482)
+++ trunk/src/kernel32/windllbase.h	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: windllbase.h,v 1.1 2000-03-09 19:03:21 sandervl Exp $ */
+/* $Id: windllbase.h,v 1.2 2000-05-02 20:53:14 sandervl Exp $ */
 
 /*
@@ -115,4 +115,5 @@
 static  Win32DllBase *findModule(HINSTANCE hinstance);
 static  Win32DllBase *findModule(WIN32DLLENTRY DllEntryPoint);
+static  Win32DllBase *findModuleByAddr(ULONG address);
 
 #ifdef DEBUG_ENABLELOG_LEVEL2
Index: trunk/src/kernel32/winexebase.cpp
===================================================================
--- trunk/src/kernel32/winexebase.cpp	(revision 3482)
+++ trunk/src/kernel32/winexebase.cpp	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: winexebase.cpp,v 1.8 2000-04-16 18:05:04 sandervl Exp $ */
+/* $Id: winexebase.cpp,v 1.9 2000-05-02 20:53:14 sandervl Exp $ */
 
 /*
@@ -120,4 +120,7 @@
   //Set default FPU control word (no exceptions); same as in NT
   _control87(0x27F, 0xFFF);
+  ULONG Size = 16, Attr;
+  rc = DosQueryMem((PVOID) (entryPoint), &Size, &Attr);
+  dprintf(("Start exe; Attr = %x, rc = %d", Attr, rc));
   rc = ((WIN32EXEENTRY)entryPoint)(NULL);
   RestoreOS2TIB();
Index: trunk/src/kernel32/winimagebase.cpp
===================================================================
--- trunk/src/kernel32/winimagebase.cpp	(revision 3482)
+++ trunk/src/kernel32/winimagebase.cpp	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: winimagebase.cpp,v 1.18 2000-04-16 10:42:12 sandervl Exp $ */
+/* $Id: winimagebase.cpp,v 1.19 2000-05-02 20:53:14 sandervl Exp $ */
 
 /*
@@ -131,4 +131,18 @@
   dprintf(("Win32ImageBase::getVersion: NOT IMPLEMENTED!"));
   return 0x40000; //NT 4
+}
+//******************************************************************************
+//******************************************************************************
+BOOL Win32ImageBase::insideModule(ULONG address)
+{
+  //dummy
+  return FALSE;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL Win32ImageBase::insideModuleCode(ULONG address)
+{
+  //dummy
+  return FALSE;
 }
 //******************************************************************************
Index: trunk/src/kernel32/winimagebase.h
===================================================================
--- trunk/src/kernel32/winimagebase.h	(revision 3482)
+++ trunk/src/kernel32/winimagebase.h	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: winimagebase.h,v 1.6 2000-04-16 10:42:12 sandervl Exp $ */
+/* $Id: winimagebase.h,v 1.7 2000-05-02 20:53:14 sandervl Exp $ */
 
 /*
@@ -99,4 +99,7 @@
 	void  tlsDetachThread();	//destroy TLS structures
 
+virtual BOOL  insideModule(ULONG address);
+virtual BOOL  insideModuleCode(ULONG address);
+
 virtual	ULONG getApi(char *name)  = 0;
 virtual ULONG getApi(int ordinal) = 0;
Index: trunk/src/kernel32/winimagepeldr.cpp
===================================================================
--- trunk/src/kernel32/winimagepeldr.cpp	(revision 3482)
+++ trunk/src/kernel32/winimagepeldr.cpp	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: winimagepeldr.cpp,v 1.41 2000-04-16 10:42:12 sandervl Exp $ */
+/* $Id: winimagepeldr.cpp,v 1.42 2000-05-02 20:53:15 sandervl Exp $ */
 
 /*
@@ -1475,4 +1475,25 @@
 //******************************************************************************
 //******************************************************************************
+BOOL Win32PeLdrImage::insideModule(ULONG address)
+{
+  if((address >= realBaseAddress) && (address < realBaseAddress + imageSize)) {
+  	return TRUE;
+  }
+  return FALSE;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL Win32PeLdrImage::insideModuleCode(ULONG address)
+{
+ Section *sect;
+
+  sect = findSectionByOS2Addr(address);
+  if(sect && (sect->pageflags & PAG_EXECUTE)) {
+	return TRUE;
+  }
+  return FALSE;
+}
+//******************************************************************************
+//******************************************************************************
 ULONG Win32PeLdrImage::getApi(char *name)
 {
Index: trunk/src/kernel32/winimagepeldr.h
===================================================================
--- trunk/src/kernel32/winimagepeldr.h	(revision 3482)
+++ trunk/src/kernel32/winimagepeldr.h	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: winimagepeldr.h,v 1.1 2000-03-10 16:12:03 sandervl Exp $ */
+/* $Id: winimagepeldr.h,v 1.2 2000-05-02 20:53:15 sandervl Exp $ */
 
 /*
@@ -83,4 +83,7 @@
 virtual BOOL  init(ULONG reservedMem);
 
+    virtual BOOL  insideModule(ULONG address);
+    virtual BOOL  insideModuleCode(ULONG address);
+
     virtual ULONG getApi(char *name);
     virtual ULONG getApi(int ordinal);
Index: trunk/src/kernel32/wprocess.cpp
===================================================================
--- trunk/src/kernel32/wprocess.cpp	(revision 3482)
+++ trunk/src/kernel32/wprocess.cpp	(revision 3483)
@@ -1,3 +1,3 @@
-/* $Id: wprocess.cpp,v 1.79 2000-04-16 10:42:13 sandervl Exp $ */
+/* $Id: wprocess.cpp,v 1.80 2000-05-02 20:53:15 sandervl Exp $ */
 
 /*
@@ -1295,15 +1295,21 @@
         ulAPIOrdinal = (ULONG)lpszProc;
         if (ulAPIOrdinal <= 0x0000FFFF) {
-            proc = (FARPROC)winmod->getApi((int)ulAPIOrdinal);
+            	proc = (FARPROC)winmod->getApi((int)ulAPIOrdinal);
         }
         else    proc = (FARPROC)winmod->getApi((char *)lpszProc);
-    if(proc == 0) {
-        SetLastError(ERROR_PROC_NOT_FOUND);
-    }
-    return proc;
+    	if(proc == 0) {
+#ifdef DEBUG
+        	if(ulAPIOrdinal <= 0x0000FFFF) {
+			dprintf(("GetProcAddress %x %x not found!", hModule, ulAPIOrdinal));
+		}
+		else	dprintf(("GetProcAddress %x %s not found!", hModule, lpszProc));
+#endif
+        	SetLastError(ERROR_PROC_NOT_FOUND);
+    	}
+    	return proc;
   }
   proc = O32_GetProcAddress(hModule, lpszProc);
   if(HIWORD(lpszProc))
-    dprintf(("KERNEL32:  GetProcAddress %s from %X returned %X\n", lpszProc, hModule, proc));
+    	dprintf(("KERNEL32:  GetProcAddress %s from %X returned %X\n", lpszProc, hModule, proc));
   else  dprintf(("KERNEL32:  GetProcAddress %x from %X returned %X\n", lpszProc, hModule, proc));
   return(proc);
