Index: trunk/src/kernel32/KERNEL32.DEF
===================================================================
--- trunk/src/kernel32/KERNEL32.DEF	(revision 278)
+++ trunk/src/kernel32/KERNEL32.DEF	(revision 281)
@@ -1,3 +1,3 @@
-; $Id: KERNEL32.DEF,v 1.15 1999-07-04 11:44:03 sandervl Exp $
+; $Id: KERNEL32.DEF,v 1.16 1999-07-07 08:11:09 sandervl Exp $
 
 ;Created by BLAST for IBM's compiler
@@ -932,5 +932,5 @@
 
 ;Used by tibfix page in exe (change ordinal in lx.cpp too!!)
-    RegisterResourceUsage         = _RegisterResourceUsage@20      @1203
+    RegisterExe                   = _RegisterExe@48      	   @1203
 ;VMutex
    enter__6VMutexFUl                                               @1204
@@ -939,6 +939,6 @@
    __dt__6VMutexFv                                                 @1207
 ;Used by tibfix page in dll (change ordinal in lx.cpp too!!)
-    DLLExitList                   = _DLLExitList@4                 @1208
-    RegisterDll                   = _RegisterDll@20                @1209
+;;;    DLLExitList                   = _DLLExitList@4                 @1208
+    RegisterDll                   = _RegisterDll@48                @1209
 ;Unicode
    UnicodeToAsciiString = _UnicodeToAsciiString@4                  @1210
Index: trunk/src/kernel32/except.asm
===================================================================
--- trunk/src/kernel32/except.asm	(revision 278)
+++ trunk/src/kernel32/except.asm	(revision 281)
@@ -1,3 +1,3 @@
-; $Id: except.asm,v 1.5 1999-06-26 18:24:50 sandervl Exp $
+; $Id: except.asm,v 1.6 1999-07-07 08:11:09 sandervl Exp $
 
 ;/*
@@ -175,4 +175,13 @@
 SetFS	endp
 
+	PUBLIC SetReturnFS
+SetReturnFS proc near
+	push	fs
+	mov  	eax, [esp+8]
+	mov	fs, eax
+	pop	eax
+	ret
+SetReturnFS endp
+
         PUBLIC getSS
 getSS	proc near
Index: trunk/src/kernel32/makefile
===================================================================
--- trunk/src/kernel32/makefile	(revision 278)
+++ trunk/src/kernel32/makefile	(revision 281)
@@ -1,3 +1,3 @@
-# $Id: makefile,v 1.11 1999-07-06 15:48:48 phaller Exp $
+# $Id: makefile,v 1.12 1999-07-07 08:11:10 sandervl Exp $
 
 #
@@ -69,5 +69,5 @@
        pefile.OBJ \
        winimgres.OBJ \
-       tls.obj \
+       wintls.obj \
        async.OBJ \
        fileio.obj \
@@ -125,5 +125,5 @@
     $(PDWIN32_INCLUDE)\unicode.h
 
-tls.obj: tls.cpp
+wintls.obj: wintls.cpp $(PDWIN32_INCLUDE)\winimage.h $(PDWIN32_INCLUDE)\winexe.h $(PDWIN32_INCLUDE)\windll.h
 
 fileio.obj: fileio.cpp \
@@ -133,4 +133,5 @@
     .\thread.cpp \
     $(PDWIN32_INCLUDE)\wprocess.h \
+    $(PDWIN32_INCLUDE)\winimage.h $(PDWIN32_INCLUDE)\winexe.h $(PDWIN32_INCLUDE)\windll.h \
     thread.h
 
Index: trunk/src/kernel32/thread.cpp
===================================================================
--- trunk/src/kernel32/thread.cpp	(revision 278)
+++ trunk/src/kernel32/thread.cpp	(revision 281)
@@ -1,3 +1,3 @@
-/* $Id: thread.cpp,v 1.6 1999-06-20 10:55:36 sandervl Exp $ */
+/* $Id: thread.cpp,v 1.7 1999-07-07 08:11:10 sandervl Exp $ */
 
 /*
@@ -14,6 +14,8 @@
 #include "thread.h"
 #include "except.h"
-#include "misc.h"
+#include <misc.h>
 #include <wprocess.h>
+#include <windll.h>
+#include <winexe.h>
 
 static DWORD OPEN32API Win32ThreadProc(LPVOID lpData);
@@ -46,6 +48,5 @@
 DWORD WIN32API GetCurrentThreadId()
 {
-  dprintf(("GetCurrentThreadId\n"));
-
+////  dprintf(("GetCurrentThreadId\n"));
   return(O32_GetCurrentThreadId());
 }
@@ -121,7 +122,8 @@
            exitcode));
 
-#ifdef WIN32_TIBSEL
+  Win32Dll::detachThreadFromAllDlls(); 	//send DLL_THREAD_DETACH message to all dlls
+  Win32Dll::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
+  WinExe->tlsDetachThread();			//destroy TLS structure of main exe
   DestroyTIB();
-#endif
   O32_ExitThread(exitcode);
 }
@@ -153,4 +155,5 @@
  WIN32THREADPROC  winthread = me->pCallback;
  LPVOID           userdata  = me->lpUserData;
+ DWORD            rc;
 
   delete me;    //only called once
@@ -158,5 +161,4 @@
   dprintf(("Win32ThreadProc %d\n", GetCurrentThreadId()));
 
-#ifdef WIN32_TIBSEL
   TEB *winteb = (TEB *)InitializeTIB();
   if(winteb == NULL) {
@@ -170,9 +172,17 @@
   thdb->entry_point = (void *)winthread;
   thdb->entry_arg   = (void *)userdata;
+
   SetWin32TIB();
-#else
-  ReplaceExceptionHandler();
-#endif
-  return(winthread(userdata));
+  WinExe->tlsAttachThread();		  //setup TLS structure of main exe
+  Win32Dll::tlsAttachThreadToAllDlls(); //setup TLS structures of all dlls
+  Win32Dll::attachThreadToAllDlls();	  //send DLL_THREAD_ATTACH message to all dlls
+
+  rc = winthread(userdata);
+
+  Win32Dll::detachThreadFromAllDlls();  //send DLL_THREAD_DETACH message to all dlls
+  Win32Dll::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
+  WinExe->tlsDetachThread();		  //destroy TLS structure of main exe
+  DestroyTIB();
+  return rc;
 }
 //******************************************************************************
Index: trunk/src/kernel32/tls.cpp
===================================================================
--- trunk/src/kernel32/tls.cpp	(revision 278)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/* $Id: tls.cpp,v 1.1 1999-06-28 07:55:33 sandervl Exp $ */
-/*
- * Win32 TLS API functions
- *
- * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
- *
- *
- * Project Odin Software License can be found in LICENSE.TXT
- *
- */
-#include <os2win.h>
-
-//******************************************************************************
-//******************************************************************************
-DWORD WIN32API TlsAlloc()
-{
-  dprintf(("KERNEL32:  TlsAlloc\n"));
-  return(O32_TlsAlloc());
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API TlsFree(DWORD index)
-{
-  dprintf(("KERNEL32:  TlsFree\n"));
-  return(O32_TlsFree(index));
-}
-//******************************************************************************
-//******************************************************************************
-LPVOID WIN32API TlsGetValue(DWORD index)
-{
- LPVOID rc;
-
-  rc = O32_TlsGetValue(index);
-//  dprintf(("KERNEL32:  TlsGetValue %d returned %X\n", index, rc));
-  return(rc);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API TlsSetValue(DWORD index, LPVOID val)
-{
-//  dprintf(("KERNEL32:  TlsSetValue\n"));
-  return(O32_TlsSetValue(index, val));
-}
-//******************************************************************************
-//******************************************************************************
Index: trunk/src/kernel32/windll.cpp
===================================================================
--- trunk/src/kernel32/windll.cpp	(revision 278)
+++ trunk/src/kernel32/windll.cpp	(revision 281)
@@ -1,3 +1,3 @@
-/* $Id: windll.cpp,v 1.6 1999-06-20 17:54:53 sandervl Exp $ */
+/* $Id: windll.cpp,v 1.7 1999-07-07 08:11:10 sandervl Exp $ */
 
 /*
@@ -22,9 +22,10 @@
 #include <iostream.h>
 #include <fstream.h>
-#include "misc.h"
-#include "nameid.h"
-#include "win32type.h"
-#include "pefile.h"
-#include "windll.h"
+#include <misc.h>
+#include <nameid.h>
+#include <win32type.h>
+#include <pefile.h>
+#include <windll.h>
+#include <wprocess.h>
 #include "cio.h"
 #include "os2util.h"
@@ -131,7 +132,5 @@
   if(errorState == NO_ERROR && !fUnloaded) 
   {
-	if(!fSystemDll) {
-		detachProcess();
-	}	
+	detachProcess();
   }
 }
@@ -304,40 +303,111 @@
 BOOL Win32Dll::attachProcess()
 {
-  if(fSystemDll || fSkipEntryCalls || !fNativePEImage)
+ BOOL rc;
+ USHORT sel;
+
+  //Allocate TLS index for this module
+  tlsAlloc();
+  tlsAttachThread();	//setup TLS (main thread)
+
+  if(fSystemDll || fSkipEntryCalls) {
+        dprintf(("attachProcess not required for dll %s", szModule));
 	return(TRUE);
-
-  if(getenv("WIN32_IOPL2")) {
-	io_init1();
-  }
-  return dllEntryPoint((ULONG)this, DLL_PROCESS_ATTACH, 0);
+  }
+
+  dprintf(("attachProcess to dll %s", szModule));
+
+  sel = SetWin32TIB();
+  rc = dllEntryPoint(hinstance, DLL_PROCESS_ATTACH, 0);
+  SetFS(sel);
+  return rc;
 }
 //******************************************************************************
 //******************************************************************************
 BOOL Win32Dll::detachProcess()
+{
+ BOOL   rc;
+ USHORT sel;
+
+  if(fSystemDll || fSkipEntryCalls) {
+        tlsDetachThread();	//destroy TLS (main thread)
+	return(TRUE);
+  }
+
+  dprintf(("detachProcess from dll %s", szModule));
+
+  fUnloaded = TRUE;
+  sel = SetWin32TIB();
+  rc = dllEntryPoint(hinstance, DLL_PROCESS_DETACH, 0);
+  SetFS(sel);
+  tlsDetachThread();	//destroy TLS (main thread)
+  return rc;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL Win32Dll::attachThread()
 {
   if(fSystemDll || fSkipEntryCalls)
 	return(TRUE);
 
-  if(fNativePEImage)
-	return dllEntryPoint((ULONG)this, DLL_PROCESS_DETACH, 0);
-  else  return dllEntryPoint((ULONG)this, DLL_PROCESS_ATTACH, 0);  //reversed in converted code
-}
-//******************************************************************************
-//******************************************************************************
-BOOL Win32Dll::attachThread()
+  dprintf(("attachThread to dll %s", szModule));
+  return dllEntryPoint(hinstance, DLL_THREAD_ATTACH, 0);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL Win32Dll::detachThread()
 {
   if(fSystemDll || fSkipEntryCalls)
 	return(TRUE);
 
-  return dllEntryPoint((ULONG)this, DLL_THREAD_ATTACH, 0);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL Win32Dll::detachThread()
-{
-  if(fSystemDll || fSkipEntryCalls)
-	return(TRUE);
-
-  return dllEntryPoint((ULONG)this, DLL_THREAD_DETACH, 0);
+  dprintf(("attachThread from dll %s", szModule));
+  return dllEntryPoint(hinstance, DLL_THREAD_DETACH, 0);
+}
+//******************************************************************************
+//Send DLL_THREAD_ATTACH message to all dlls for a new thread
+//******************************************************************************
+void Win32Dll::attachThreadToAllDlls()
+{
+ Win32Dll *dll = Win32Dll::head;
+
+  while(dll) {
+	dll->attachThread();
+	dll = dll->getNext();
+  }
+}
+//******************************************************************************
+//Send DLL_THREAD_DETACH message to all dlls for thread that's about to die
+//******************************************************************************
+void Win32Dll::detachThreadFromAllDlls()
+{
+ Win32Dll *dll = Win32Dll::head;
+
+  while(dll) {
+	dll->detachThread();
+	dll = dll->getNext();
+  }
+}
+//******************************************************************************
+//Setup TLS structure for all dlls for a new thread
+//******************************************************************************
+void Win32Dll::tlsAttachThreadToAllDlls()
+{
+ Win32Dll *dll = Win32Dll::head;
+
+  while(dll) {
+	dll->tlsAttachThread();
+	dll = dll->getNext();
+  }
+}
+//******************************************************************************
+//Destroy TLS structure for all dlls for a thread that's about to die
+//******************************************************************************
+void Win32Dll::tlsDetachThreadFromAllDlls()
+{
+ Win32Dll *dll = Win32Dll::head;
+
+  while(dll) {
+	dll->tlsDetachThread();
+	dll = dll->getNext();
+  }
 }
 //******************************************************************************
Index: trunk/src/kernel32/winexe.cpp
===================================================================
--- trunk/src/kernel32/winexe.cpp	(revision 278)
+++ trunk/src/kernel32/winexe.cpp	(revision 281)
@@ -1,3 +1,3 @@
-/* $Id: winexe.cpp,v 1.7 1999-06-20 10:55:36 sandervl Exp $ */
+/* $Id: winexe.cpp,v 1.8 1999-07-07 08:11:10 sandervl Exp $ */
 
 /*
@@ -87,4 +87,9 @@
 
   fExeStarted  = TRUE;
+
+  //Allocate TLS index for this module
+  tlsAlloc();
+  tlsAttachThread();	//setup TLS (main thread)
+
   SetWin32TIB();
   rc = ((WIN32EXEENTRY)entryPoint)();
Index: trunk/src/kernel32/winimage.cpp
===================================================================
--- trunk/src/kernel32/winimage.cpp	(revision 278)
+++ trunk/src/kernel32/winimage.cpp	(revision 281)
@@ -1,3 +1,3 @@
-/* $Id: winimage.cpp,v 1.4 1999-06-19 10:54:43 sandervl Exp $ */
+/* $Id: winimage.cpp,v 1.5 1999-07-07 08:11:10 sandervl Exp $ */
 
 /*
@@ -60,4 +60,5 @@
     nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL),
     szFileName(NULL), NameTable(NULL), Win32Table(NULL), fullpath(NULL),
+    tlsAddress(0), tlsIndexAddr(0), tlsInitSize(0), tlsTotalSize(0), tlsCallBackAddr(0), tlsIndex(-1),
     pResSection(NULL), pResDir(NULL), winres(NULL), VersionId(-1)
 {
@@ -84,4 +85,5 @@
     nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL),
     szFileName(NULL), NameTable(NULL), Win32Table(NULL), fullpath(NULL),
+    tlsAddress(0), tlsIndexAddr(0), tlsInitSize(0), tlsTotalSize(0), tlsCallBackAddr(0), tlsIndex(-1),
     pResSection(NULL), pResDir(NULL), winres(NULL)
 {
Index: trunk/src/kernel32/wintls.cpp
===================================================================
--- trunk/src/kernel32/wintls.cpp	(revision 281)
+++ trunk/src/kernel32/wintls.cpp	(revision 281)
@@ -0,0 +1,156 @@
+/* $Id: wintls.cpp,v 1.1 1999-07-07 08:11:58 sandervl Exp $ */
+/*
+ * Win32 TLS API functions
+ *
+ * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#include <os2win.h>
+#include <winimage.h>
+#include <thread.h>
+#include <wprocess.h>
+
+//******************************************************************************
+//******************************************************************************
+void Win32Image::tlsAlloc()	//Allocate TLS index for this module
+{
+   if(!tlsAddress) 
+	return;
+
+   tlsIndex = TlsAlloc();
+   if(tlsIndex >= TLS_MINIMUM_AVAILABLE) {
+	dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex));
+	DebugInt3();
+	return;  	
+   }
+   dprintf(("Win32Image::tlsAlloc (%d) for module %x", tlsIndex, hinstance));
+}
+//******************************************************************************
+//******************************************************************************
+void Win32Image::tlsDelete()	//Free TLS index for this module
+{
+   if(!tlsAddress) 
+	return;
+
+   if(tlsIndex >= TLS_MINIMUM_AVAILABLE) {
+	dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex));
+	DebugInt3();
+	return;  	
+   }
+   dprintf(("Win32Image::tlsDestroy (%d) for module %x", tlsIndex, hinstance));
+   TlsFree(tlsIndex);
+   tlsIndex = -1;
+}
+//******************************************************************************
+//******************************************************************************
+void Win32Image::tlsAttachThread()	//setup TLS structures for new thread
+{
+ PIMAGE_TLS_CALLBACK *pCallback;
+ TEB  *winteb;
+ char *tibmem;
+
+   if(!tlsAddress) 
+	return;
+
+   if(tlsIndex >= TLS_MINIMUM_AVAILABLE) {
+	dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex));
+	DebugInt3();
+	return;  	
+   }
+
+   dprintf(("Win32Image::tlsAttachThread for module %x, thread id %x", hinstance, GetCurrentThreadId()));
+   dprintf(("tlsAddress:      %x", tlsAddress));
+   dprintf(("tlsInitSize:     %x", tlsInitSize));
+   dprintf(("tlsTotalSize     %x", tlsTotalSize));
+   dprintf(("tlsIndexAddr     %x", tlsIndexAddr));
+   dprintf(("tlsCallbackAddr  %x", tlsCallBackAddr));
+   dprintf(("*tlsCallbackAddr %x", *tlsCallBackAddr));
+   tibmem = (char *)VirtualAlloc(0, tlsTotalSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
+   if(tibmem == NULL) {
+	dprintf(("tlsAttachThread: tibmem == NULL!!!!"));
+	DebugInt3();
+	return;
+   }
+   memset(tibmem, 0, tlsTotalSize);
+   memcpy(tibmem, tlsAddress, tlsInitSize);
+
+   winteb = (TEB *)TIBFlatPtr;
+   winteb->tls_ptr[tlsIndex] = tibmem;
+   *tlsIndexAddr = tlsIndex;
+
+   if((ULONG)*tlsCallBackAddr != 0) {
+	pCallback = tlsCallBackAddr;
+	while(*pCallback) {
+		dprintf(("tlsAttachThread: calling TLS Callback %x", *pCallback));
+		(*pCallback)((LPVOID)hinstance, DLL_THREAD_ATTACH, 0);
+		dprintf(("tlsAttachThread: finished calling TLS Callback %x", *pCallback));
+		*pCallback++;
+	}
+   }
+   return;
+}
+//******************************************************************************
+//******************************************************************************
+void Win32Image::tlsDetachThread()	//destroy TLS structures
+{
+ PIMAGE_TLS_CALLBACK *pCallback;
+ TEB  *winteb;
+
+   if(!tlsAddress) 
+	return;
+
+   dprintf(("Win32Image::tlsDetachThread for module %x, thread id %x", hinstance, GetCurrentThreadId()));
+
+   if((ULONG)*tlsCallBackAddr != 0) {
+	pCallback = tlsCallBackAddr;
+	while(*pCallback) {
+		dprintf(("tlsDetachThread: calling TLS Callback %x", *pCallback));
+		(*pCallback)((LPVOID)hinstance, DLL_THREAD_DETACH, 0);
+		dprintf(("tlsDetachThread: finished calling TLS Callback %x", *pCallback));
+		*pCallback++;
+	}
+   }
+   winteb = (TEB *)TIBFlatPtr;
+   VirtualFree(winteb->tls_ptr[tlsIndex], tlsTotalSize, MEM_RELEASE);
+
+   TlsFree(tlsIndex);
+}
+//******************************************************************************
+//******************************************************************************
+
+//******************************************************************************
+//******************************************************************************
+DWORD WIN32API TlsAlloc()
+{
+  dprintf(("KERNEL32:  TlsAlloc\n"));
+  return(O32_TlsAlloc());
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API TlsFree(DWORD index)
+{
+  dprintf(("KERNEL32:  TlsFree\n"));
+  return(O32_TlsFree(index));
+}
+//******************************************************************************
+//******************************************************************************
+LPVOID WIN32API TlsGetValue(DWORD index)
+{
+ LPVOID rc;
+
+  rc = O32_TlsGetValue(index);
+//  dprintf(("KERNEL32:  TlsGetValue %d returned %X\n", index, rc));
+  return(rc);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API TlsSetValue(DWORD index, LPVOID val)
+{
+//  dprintf(("KERNEL32:  TlsSetValue\n"));
+  return(O32_TlsSetValue(index, val));
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/kernel32/wprocess.cpp
===================================================================
--- trunk/src/kernel32/wprocess.cpp	(revision 278)
+++ trunk/src/kernel32/wprocess.cpp	(revision 281)
@@ -1,3 +1,3 @@
-/* $Id: wprocess.cpp,v 1.12 1999-06-20 12:46:09 sandervl Exp $ */
+/* $Id: wprocess.cpp,v 1.13 1999-07-07 08:11:10 sandervl Exp $ */
 
 /*
@@ -45,5 +45,4 @@
 TEB *InitializeTIB(BOOL fMainThread)
 {
-#ifdef WIN32_TIBSEL
   TEB   *winteb;
   THDB  *thdb;
@@ -108,7 +107,4 @@
    dprintf(("InitializeTIB: FS(%x):[0] = %x", GetFS(), QueryExceptionChain()));
    return winteb;
-#else
-   return 0;
-#endif
 }
 //******************************************************************************
@@ -117,5 +113,4 @@
 void DestroyTIB()
 {
-#ifdef WIN32_TIBSEL
  SHORT  orgtibsel;
  TEB   *winteb;
@@ -141,5 +136,4 @@
    TIBFlatPtr = NULL;
    return;
-#endif
 }
 /******************************************************************************/
@@ -147,5 +141,4 @@
 void WIN32API RestoreOS2TIB()
 {
-#ifdef WIN32_TIBSEL
  SHORT  orgtibsel;
  TEB   *winteb;
@@ -160,11 +153,9 @@
    	SetFS(orgtibsel);
    }
-#endif
 }
 /******************************************************************************/
 /******************************************************************************/
-void WIN32API SetWin32TIB()
-{
-#ifdef WIN32_TIBSEL
+USHORT WIN32API SetWin32TIB()
+{
  SHORT  win32tibsel;
  TEB   *winteb;
@@ -177,109 +168,121 @@
 
 	//Restore our win32 FS selector
-   	SetFS(win32tibsel);
+   	return SetReturnFS(win32tibsel);
    }
    else DebugInt3();
-#endif
+
+   return 0;
 }
 /******************************************************************************/
-//SvL: 4-10-'98: Put in separate procedure, as ICC changes FS:0 when there
-//               are new or delete calls present.
-//******************************************************************************
-void RegisterExe(LONG Win32TableId, LONG NameTableId, LONG VersionResId,
-                 LONG Pe2lxVersion, HINSTANCE hinstance)
+//******************************************************************************
+void WIN32API RegisterExe(WIN32EXEENTRY EntryPoint, PIMAGE_TLS_CALLBACK *TlsCallbackAddr, 
+			  LPDWORD TlsIndexAddr, ULONG TlsInitSize, 
+			  ULONG TlsTotalSize, LPVOID TlsAddress,
+	         	  LONG Win32TableId, LONG NameTableId, LONG VersionResId,
+                 	  LONG Pe2lxVersion, HINSTANCE hinstance, ULONG dwReserved)
 {
   if(WinExe != NULL) //should never happen
     delete(WinExe);
 
+  CheckVersion(Pe2lxVersion, OS2GetDllName(hinstance));
+
+  if(getenv("WIN32_IOPL2")) {
+    io_init1();
+  }
+
   //SvL: Use 0 instead of the real instance handle (for resource lookup)
   Win32Exe *winexe = new Win32Exe(0, NameTableId, Win32TableId);
+
   if(winexe) {
-    winexe->setVersionId(VersionResId);
-    winexe->setOS2InstanceHandle(hinstance);
+	dprintf(("RegisterExe Win32TableId = %x", Win32TableId));
+	dprintf(("RegisterExe NameTableId  = %x", NameTableId));
+	dprintf(("RegisterExe VersionResId = %x", VersionResId));
+	dprintf(("RegisterExe Pe2lxVersion = %x", Pe2lxVersion));
+
+    	winexe->setVersionId(VersionResId);
+    	winexe->setOS2InstanceHandle(hinstance);
+	winexe->setEntryPoint((ULONG)EntryPoint);
+	winexe->setTLSAddress(TlsAddress);
+	winexe->setTLSInitSize(TlsInitSize);
+	winexe->setTLSTotalSize(TlsTotalSize);
+	winexe->setTLSIndexAddr(TlsIndexAddr);
+	winexe->setTLSCallBackAddr(TlsCallbackAddr);
+
+	char *modname = getenv("WIN32MODULE");
+
+  	if(modname != NULL)
+  	{
+    		dprintf(("Set full path for exe to %s", modname));
+    		winexe->setFullPath(modname);
+  	}
+	winexe->start();
   }
   else {
-    eprintf(("Win32Exe creation failed!\n"));
-    DebugInt3();
-  }
-
-  char *modname = getenv("WIN32MODULE");
-
-  if(modname != NULL)
-  {
-    dprintf(("Set full path for exe to %s", modname));
-    winexe->setFullPath(modname);
-  }
-
-  fExeStarted  = TRUE;
-}
-//******************************************************************************
-//******************************************************************************
-VOID WIN32API RegisterResourceUsage(LONG Win32TableId, LONG NameTableId,
-                    LONG VersionResId, LONG Pe2lxVersion,
-                    HINSTANCE hinstance)
-{
-  SetWin32TIB();
-
-  if(getenv("WIN32_IOPL2")) {
-    io_init1();
-  }
-  dprintf(("RegisterResourceUsage %X resid = %d\n", hinstance, VersionResId));
-
-  CheckVersion(Pe2lxVersion, OS2GetDllName(hinstance));
-
-  RegisterExe(Win32TableId, NameTableId, VersionResId, Pe2lxVersion, hinstance);
-
-  dprintf(("RegisterResourceUsage: FS(%x):[0] = %x", GetFS(), QueryExceptionChain()));
-}
-//******************************************************************************
-//******************************************************************************
-void CreateDll(LONG Win32TableId, LONG NameTableId, LONG VersionResId,
-               HINSTANCE hinstance, WIN32DLLENTRY pfnDllEntry)
-{
+    	eprintf(("Win32Exe creation failed!\n"));
+    	DebugInt3();
+	return;
+  }
+}
+//******************************************************************************
+//******************************************************************************
+ULONG WIN32API RegisterDll(WIN32DLLENTRY pfnDllEntry, PIMAGE_TLS_CALLBACK *TlsCallbackAddr, 
+			   LPDWORD TlsIndexAddr, ULONG TlsInitSize, 
+			   ULONG TlsTotalSize, LPVOID TlsAddress,
+	          	   LONG Win32TableId, LONG NameTableId, LONG VersionResId,
+                 	   LONG Pe2lxVersion, HINSTANCE hinstance, ULONG dwAttachType)
+{
+ char *name;
+
   Win32Dll *winmod = Win32Dll::findModule(hinstance);
-
-  if(winmod != NULL) {
-    //dll manually loaded by PE loader (Win32Dll::init)
-    winmod->OS2DllInit(hinstance, NameTableId, Win32TableId, pfnDllEntry);
-    return;
-  }
-
-  //converted win32 dll loaded by OS/2 loader
-  winmod = new Win32Dll(hinstance, NameTableId, Win32TableId, pfnDllEntry);
-  if(winmod == NULL) {
-    eprintf(("Failed to allocate module object!\n"));
-    DebugInt3();
-    return;
-  }
-  //SvL: 19-8-'98
-  winmod->AddRef();
-  winmod->setVersionId(VersionResId);
-}
-//******************************************************************************
-//******************************************************************************
-VOID WIN32API RegisterDll(LONG Win32TableId, LONG NameTableId,
-                          LONG VersionResId, LONG Pe2lxVersion,
-                          HINSTANCE hinstance)
-{
- WIN32DLLENTRY  pfnDllEntry;
- char *name;
-
-  pfnDllEntry = (WIN32DLLENTRY)GetDllEntryPoint();  //== return address
-
-  if(getenv("WIN32_IOPL2")) {
-    io_init1();
-  }
-  name = OS2GetDllName(hinstance);
-  CheckVersion(Pe2lxVersion, name);
-
-  dprintf(("RegisterDll %X %s\n", hinstance, name));
-
-  CreateDll(Win32TableId, NameTableId, VersionResId, hinstance, pfnDllEntry);
-
-  /* @@@PH 1998/03/17 console devices initialization */
-  iConsoleDevicesRegister();
-
-  SetWin32TIB();
-  dprintf(("RegisterDll: FS = %x", GetFS()));
+  if(dwAttachType == 0) 
+  { //Process attach
+  	if(getenv("WIN32_IOPL2")) {
+    		io_init1();
+  	}
+  	name = OS2GetDllName(hinstance);
+  	CheckVersion(Pe2lxVersion, name);
+
+	dprintf(("RegisterDll %X %s reason %d\n", hinstance, name, dwAttachType));
+	dprintf(("RegisterDll Win32TableId = %x", Win32TableId));
+	dprintf(("RegisterDll NameTableId  = %x", NameTableId));
+	dprintf(("RegisterDll VersionResId = %x", VersionResId));
+	dprintf(("RegisterDll Pe2lxVersion = %x", Pe2lxVersion));
+
+  	if(winmod != NULL) {
+    		//dll manually loaded by PE loader (Win32Dll::init)
+    		winmod->OS2DllInit(hinstance, NameTableId, Win32TableId, pfnDllEntry);
+  	}
+	else {
+  		//converted win32 dll loaded by OS/2 loader
+  		winmod = new Win32Dll(hinstance, NameTableId, Win32TableId, pfnDllEntry);
+  		if(winmod == NULL) {
+    			eprintf(("Failed to allocate module object!\n"));
+    			DebugInt3();
+    			return 0;	//fail dll load
+  		}
+	}
+	winmod->setTLSAddress(TlsAddress);
+	winmod->setTLSInitSize(TlsInitSize);
+	winmod->setTLSTotalSize(TlsTotalSize);
+	winmod->setTLSIndexAddr(TlsIndexAddr);
+	winmod->setTLSCallBackAddr(TlsCallbackAddr);
+
+  	/* @@@PH 1998/03/17 console devices initialization */
+  	iConsoleDevicesRegister();
+
+  	//SvL: 19-8-'98
+  	winmod->AddRef();
+  	winmod->setVersionId(VersionResId);
+
+	winmod->attachProcess();
+   }
+   else {//process detach
+  	if(winmod != NULL && !fFreeLibrary) {
+		return 0;	//don't unload (OS/2 dll unload bug)
+	}
+//Runtime environment could already be gone, so don't do this
+//	dprintf(("KERNEL32: Dll Removed by FreeLibrary or ExitProcess\n"));
+   }
+   return 1;	//success
 }
 //******************************************************************************
@@ -294,24 +297,4 @@
   }
   return;
-}
-//******************************************************************************
-//Called when a dll is detached (either at process exit or when FreeLibrary is called)
-//******************************************************************************
-BOOL WIN32API DLLExitList(HINSTANCE hInstance)
-{
-//  dprintf(("DLLExitList"));
-  Win32Dll *winmod = Win32Dll::findModule(hInstance);
-
-  if(winmod == NULL) {//probably called after we manually unloaded it in ExitProcess
-    return(1);  //remove it from memory
-  }
-  dprintf(("DllExitList for %s (%X)\n", OS2GetDllName(winmod->getInstanceHandle()), winmod->getInstanceHandle()));
-  delete(winmod);
-
-  if(fFreeLibrary) {
-    dprintf(("KERNEL32: DLLExitList Ditched by FreeLibrary\n"));
-    return(1);  //remove it as we no longer need it
-  }
-  return(0);    //don't remove it (OS/2 can unload them at process exit in the wrong order!)
 }
 //******************************************************************************
@@ -513,10 +496,5 @@
 
   dprintf(("KERNEL32:  GetCommandLine %s\n", cmdline));
-#ifdef WIN32_TIBSEL
   dprintf(("KERNEL32:  FS = %x\n", GetFS()));
-#else
-  //SvL: Replace original startup code exception handler
-  ReplaceExceptionHandler();
-#endif
   return(cmdline);
 }
@@ -528,10 +506,5 @@
          char *asciicmdline = NULL;
 
-#ifdef WIN32_TIBSEL
     dprintf(("KERNEL32:  FS = %x\n", GetFS()));
-#else
-    //SvL: Replace original startup code exception handler
-    ReplaceExceptionHandler();
-#endif
 
     if(UnicodeCmdLine)
Index: trunk/src/pe2lx/LX.CPP
===================================================================
--- trunk/src/pe2lx/LX.CPP	(revision 278)
+++ trunk/src/pe2lx/LX.CPP	(revision 281)
@@ -1,3 +1,3 @@
-/* $Id: LX.CPP,v 1.3 1999-06-10 17:08:51 phaller Exp $ */
+/* $Id: LX.CPP,v 1.4 1999-07-07 08:11:10 sandervl Exp $ */
 
 /*
@@ -59,122 +59,83 @@
 //Register module in kernel32 (resource managment)
 // EXE:
-//push  [esp+4]                 ;instance handle
+//push  [esp+8]			;reserved (to use same startup code as dll)
+//push  [esp+8]                 ;instance handle
 //push  internal pe2lx version
 //push  version resource id
 //push  name_lookup_tableid
 //push  orgres_lookup_tableid
+//push  tib_object_address
+//push  tib_object_size
+//push  tib_index_address
+//push  tib_callback_address
+//push  original_entrypoint
 //mov   ecx, KERNEL32:RegisterResourceInfo (stdcall)
 //call  ecx
-//
-//call  original_entrypoint
 //ret
 //
 // DLL:
-//cmp   [esp+8], 1
-//je    detach
-//push  [esp+4]                 ;instance handle
+//push  [esp+8]			;attach or detach
+//push  [esp+8]                 ;instance handle
 //push  internal pe2lx version
 //push  version resource id
 //push  name_lookup_tableid
 //push  orgres_lookup_tableid
+//push  tib_object_address
+//push  tib_index_address
+//push  tib_callback_address
 //mov   ecx, KERNEL32:RegisterDll (stdcall)
+//push  original_entrypoint
 //call  ecx
-///DLL entrypoint:
-/// BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
-//push  0
-//mov   ecx, [esp+12]
-//xor   ecx, 1          //0 -> 1, 1 -> 0
-//push  ecx             //push entry type (1 = attach process, 0 = detach process)
-//push  [esp+12]        //push module handle
-//call  testje
 //ret
-//detach:
-//push  [esp+4]         //instance handle
-//call  KERNEL32:DllExitList
-//ret
-
-#define EXE_OFF_ENTRYFIX    (1+19+2+10)
-#define EXE_OFF_TIBCALL     (EXE_OFF_ENTRYFIX-1)
-#define EXE_OFF_NAMETABLE   (3+2+10)
+
 //SvL: 18-7-'98: offsets for internal pe2lx version & version resource id
-#define EXE_OFF_PE2LXVER    (5)
-#define EXE_OFF_VERRESID    (10)
-#define EXE_TIBSIZE         sizeof(szEXETIBFix)
-#define EXE_OFF_KERIMP      (EXE_OFF_NAMETABLE+10)
-
-#define DLL_OFF_ENTRYFIX    (15+28+10)
-//#define DLL_OFF_ENTRYFIX   (16+28+10)
-#define DLL_OFF_TIBCALL     (DLL_OFF_ENTRYFIX-1)
-//SvL: 18-7-'98: offsets for internal pe2lx version & version resource id
-#define DLL_OFF_PE2LXVER    (12)
-#define DLL_OFF_VERRESID    (17)
-#define DLL_OFF_NAMETABLE   (12+10)
-//#define DLL_OFF_NAMETABLE   12+1+10
-#define DLL_TIBSIZE         sizeof(szDLLTIBFix)
-#define DLL_OFF_KERIMP      (DLL_OFF_NAMETABLE+10)
-#define DLL_OFF_KERIMP2     (sizeof(szDLLTIBFix)-5)
+#define EXE_OFF_PE2LXVER     (9)
+#define EXE_OFF_VERRESID     (14)
+#define EXE_OFF_NAMETABLE    (19)
+#define EXE_OFF_ORGRESTABLE  (24)
+#define EXE_OFF_TIBOBJ_ADDR  (29)
+#define EXE_OFF_TIBINIT_SIZE (34)
+#define EXE_OFF_TIBOBJ_SIZE  (39)
+#define EXE_OFF_TIB_INDEX    (44)
+#define EXE_OFF_TIB_CALLBACK_ADDR  (49)
+#define EXE_OFF_ENTRYPOINT   (54)
+#define EXE_OFF_ENTRYFIX     (59)
+#define EXE_TIB_SIZE         sizeof(szEXETIBFix)
 
 #define SIZE_TIBCALL         5
 
-#define EXTRA_FIXUPS         2  //extra kernel32 imports
+#define EXTRA_FIXUPS         1  //extra kernel32 import
+#define EXTRA_TLS_FIXUPS     3  //3 data fixups for TLS support (start, index & callback)
 
 static unsigned char szEXETIBFix[] = {
-//push [esp+4]
-        0xFF, 0x74, 0x24, 0x04,
+//push  [esp+8]
+        0xFF, 0x74, 0x24, 0x08,
+//push  [esp+4]
+        0xFF, 0x74, 0x24, 0x08,
 //SvL: 18-7-'98: push internal pe2lx version
         0x68, 0x00, 0x00, 0x00, 0x00,
 //SvL: 18-7-'98: push version resource id (-1 = no version resource present)
         0x68, 0xFF, 0xFF, 0xFF, 0xFF,
-//push [table id1] (kernel32 proc depends on 0x77777777 & 0x88888888!!)
+//push  [table id1] (kernel32 proc depends on 0x77777777 & 0x88888888!!)
 //Svl: So does void LXHeader::SaveConvertedNames()!
         0x68, 0x77, 0x77, 0x77, 0x77,
-//push [table id1]
+//push  [table id1]
         0x68, 0x88, 0x88, 0x88, 0x88,
-//mov  ecx, KERNEL32:RegisterResourceInfo (stdcall)
+//push  tib_object_address
+        0x68, 0x00, 0x00, 0x00, 0x00,
+//push  tib_initialized_size
+        0x68, 0x00, 0x00, 0x00, 0x00,
+//push  tib_object_size
+        0x68, 0x00, 0x00, 0x00, 0x00,
+//push  tib_index_address
+        0x68, 0x00, 0x00, 0x00, 0x00,
+//push  tib_callback_address
+        0x68, 0x00, 0x00, 0x00, 0x00,
+//push  original_entrypoint
+        0x68, 0x00, 0x00, 0x00, 0x00,
+//mov   ecx, KERNEL32:RegisterResourceInfo (stdcall)
         0xB9, 0x99, 0x99, 0x99, 0x99,
-//call ecx
+//call  ecx
         0xFF, 0xD1,
-//call entrypoint
-        0xE8, 0x8C, 0xFF, 0xFF, 0xFF,
-//ret
-        0xC3};
-
-//WARNING: Kernel32.dll depends on this layout (offsets of dllexitlist &
-//         entry point call are hardcoded! (both calculated in RegisterDll)
-static unsigned char szDLLTIBFix[] = {
-//cmp [esp+8], 1
-//      0xCC, 0x80, 0x7C, 0x24, 0x08, 0x01,
-        0x80, 0x7C, 0x24, 0x08, 0x01,
-//je detach
-        0x74, 0x33,
-//push [esp+4]
-        0xFF, 0x74, 0x24, 0x04,
-//SvL: 18-7-'98: push internal pe2lx version
-        0x68, 0x00, 0x00, 0x00, 0x00,
-//SvL: 18-7-'98: push version resource id (-1 = no version resource present)
-        0x68, 0xFF, 0xFF, 0xFF, 0xFF,
-//push [table id1] (kernel32 proc depends on 0x77777777 & 0x88888888!!)
-//Svl: So does void LXHeader::SaveConvertedNames()!
-        0x68, 0x77, 0x77, 0x77, 0x77,
-//push [table id1]
-        0x68, 0x88, 0x88, 0x88, 0x88,
-//mov  ecx, KERNEL32:RegisterDll (stdcall)
-        0xB9, 0x99, 0x99, 0x99, 0x99,
-//call ecx
-        0xFF, 0xD1,
-//push 0
-        0x6A, 0x00,
-        0x8B, 0x4C, 0x24, 0x0C,
-        0x83, 0xF1, 0x01,
-        0x51, 0xFF, 0x74, 0x24, 0x0C,
-//call entrypoint
-        0xE8, 0x80, 0xFF, 0xFF, 0xFF,
-//ret
-        0xC3,
-//detach:
-//push [esp+4]
-        0xFF, 0x74, 0x24, 0x04,
-//call KERNEL32:DllExitList (stdcall)
-        0xE8, 0x00, 0x00, 0x00, 0x00,
 //ret
         0xC3};
@@ -191,5 +152,6 @@
                        cvtname(NULL), curcvtname(0), nrcvtnames(0), datapage(NULL),
                        cvtnametableid(0), orgrestableid(0), orgrestable(NULL), nrorgres(0),
-                       kernel32Object(-1), TIBOffKerImport(0), fConsole(FALSE),
+                       kernel32Object(-1), fConsole(FALSE), 
+		       tlsAddress(0), tlsIndexAddr(0), tlsInitSize(0), tlsTotalSize(0), tlsCallBackAddr(0),
                        VersionResourceId(-1), impnamesize(0), impmodulesize(0)
 {
@@ -214,13 +176,4 @@
   ZERO(ResSection);
   memset(&PESection[0], 0, sizeof(PESection));
-
-  szTIBFix    = &szEXETIBFix[0];
-  TIBSize     = EXE_TIBSIZE;
-  TIBOffEntry = EXE_OFF_ENTRYFIX;
-  TIBOffCall  = EXE_OFF_TIBCALL;
-  TIBOffName  = EXE_OFF_NAMETABLE;
-  //SvL: 18-7-'98: Internal pe2lx version and version resource id offsets
-  TIBOffPe2lxVer = EXE_OFF_PE2LXVER;
-  TIBOffVerResId = EXE_OFF_VERRESID;
 }
 //******************************************************************************
@@ -252,25 +205,7 @@
   this->IsEXE = IsEXE;
   if(IsEXE) {
-        szTIBFix          = &szEXETIBFix[0];
-        TIBSize           = EXE_TIBSIZE;
-        TIBOffEntry       = EXE_OFF_ENTRYFIX;
-        TIBOffCall        = EXE_OFF_TIBCALL;
-        TIBOffName        = EXE_OFF_NAMETABLE;
-        TIBOffKerImport   = EXE_OFF_KERIMP;
-        //SvL: 18-7-'98: Internal pe2lx version and version resource id offsets
-        TIBOffPe2lxVer    = EXE_OFF_PE2LXVER;
-        TIBOffVerResId    = EXE_OFF_VERRESID;
-        LXHdr.e32_mflags |= E32MODEXE;
+  	LXHdr.e32_mflags |= E32MODEXE;
   }
   else {//Assuming per process initialization/termination...
-        szTIBFix          = &szDLLTIBFix[0];
-        TIBSize           = DLL_TIBSIZE;
-        TIBOffEntry       = DLL_OFF_ENTRYFIX;
-        TIBOffCall        = DLL_OFF_TIBCALL;
-        TIBOffName        = DLL_OFF_NAMETABLE;
-        TIBOffKerImport   = DLL_OFF_KERIMP;
-        //SvL: 18-7-'98: Internal pe2lx version and version resource id offsets
-        TIBOffPe2lxVer    = DLL_OFF_PE2LXVER;
-        TIBOffVerResId    = DLL_OFF_VERRESID;
         LXHdr.e32_mflags |= E32LIBINIT | E32LIBTERM | E32MODDLL;
   }
@@ -437,5 +372,5 @@
   rawsize = CombinedData.rawsize;
 
-  datapage[0].size  = TIBSize;
+  datapage[0].size  = EXE_TIB_SIZE;
   datapage[0].flags = 0;
   idx               = 1;
@@ -616,10 +551,42 @@
 void LXHeader::SetNrOff32Fixups(int nr)
 {
-  intfixuprec = (intfixup *)malloc(nr*sizeof(intfixup));
-  memset(intfixuprec, 0, nr*sizeof(intfixup));
-}
-//******************************************************************************
-//******************************************************************************
-void LXHeader::AddOff32Fixup(int address)
+  intfixuprec = (intfixup *)malloc((nr+EXTRA_TLS_FIXUPS)*sizeof(intfixup));
+  memset(intfixuprec, 0, (nr+EXTRA_TLS_FIXUPS)*sizeof(intfixup));
+}
+//******************************************************************************
+//SvL: TLS Section support
+//Add three interal fixups. One for start of TLS section, one for DWORD that
+//receives the TLS index and one for the array of TLS callbacks
+//Also one for the entrypoint address.
+//******************************************************************************
+void LXHeader::AddExtraFixups()
+{
+  *(ULONG *)&szEXETIBFix[EXE_OFF_TIBOBJ_ADDR] = tlsAddress;
+  *(ULONG *)&szEXETIBFix[EXE_OFF_TIBINIT_SIZE] = tlsInitSize;
+  *(ULONG *)&szEXETIBFix[EXE_OFF_TIBOBJ_SIZE] = tlsTotalSize;
+  *(ULONG *)&szEXETIBFix[EXE_OFF_TIB_INDEX]   = tlsIndexAddr;
+  *(ULONG *)&szEXETIBFix[EXE_OFF_TIB_CALLBACK_ADDR] = tlsCallBackAddr;
+  *(ULONG *)&szEXETIBFix[EXE_OFF_ENTRYPOINT] = EntryAddress;
+
+  if(LXHdr.e32_mflags & E32NOINTFIX)
+	return;		//no internal fixups, so we don't have to add them either
+
+  AddOff32Fixup(PESection[0].address + EXE_OFF_ENTRYPOINT, TRUE);
+
+  if(tlsAddress == 0)
+	return;	//no TLS section in this image
+
+  AddOff32Fixup(PESection[0].address + EXE_OFF_TIBOBJ_ADDR, TRUE);
+  AddOff32Fixup(PESection[0].address + EXE_OFF_TIB_INDEX, TRUE);
+  AddOff32Fixup(PESection[0].address + EXE_OFF_TIB_CALLBACK_ADDR, TRUE);
+
+  return;  
+}
+//******************************************************************************
+//SvL: if fLookatStartupCode is set to true, we'll read the szEXETIBFix
+//     fixup addresses instead of those in the section
+//     (section 0 is main code section which doesn't include szEXETIBFix)
+//******************************************************************************
+void LXHeader::AddOff32Fixup(int address, BOOL fLookatStartupCode)
 {
  static intfixup  crossedpage;
@@ -654,5 +621,11 @@
   if(type == 0) { // +1 for tibfix page
         assert(PESection[type].type & SECTION_CODE);
-        targetaddr = *(int *)(PESection[type].rawdata + (address - (PESection[type].address + (PESection[type].nrinvalidpages+1)*PAGE_SIZE)));
+	if(fLookatStartupCode)
+	{
+		targetaddr = *(int *)(&szEXETIBFix[0] + (address & 0xFF));
+	}
+	else {
+        	targetaddr = *(int *)(PESection[type].rawdata + (address - (PESection[type].address + (PESection[type].nrinvalidpages+1)*PAGE_SIZE)));
+	}
   }
   else  targetaddr = *(int *)(PESection[type].rawdata + (address - (PESection[type].address + PESection[type].nrinvalidpages*PAGE_SIZE)));
@@ -836,4 +809,12 @@
                 dest += size-4;
         }
+#if 0
+	else
+        if(strcmp(dest, "OLE32") == 0) {//SvL: Name conflict with Lotus OLE32 dll
+              strcpy(dest, "OLE32OS2");
+              dest[-1] = 8;   //change module name length
+              dest    += 8;
+        }
+#endif
         else {
                 if(strcmp(dest, "KERNEL32") == 0) {
@@ -1018,10 +999,8 @@
                         if(PESection[i].type == SECTION_COMBINEDDATA) {
                                 if(j == PESection[i].nrinvalidpages) {
-                                        objpage[idx].o32_pagesize        = (USHORT)(TIBSize);
+                                        objpage[idx].o32_pagesize        = (USHORT)(EXE_TIB_SIZE);
                                         objpage[idx].o32_pageflags       = 0;
-                                        pagedataoffset                  += TIBSize;
+                                        pagedataoffset                  += EXE_TIB_SIZE;
                                         LXHdr.e32_mpages++;
-                                        //Modify entry point address, and write original to TIBFix code
-                                        *(LONG *)&szTIBFix[TIBOffEntry]  = LXHdr.e32_eip + PAGE_SIZE - TIBOffCall - SIZE_TIBCALL;
                                         LXHdr.e32_eip                    = PAGE_SIZE*PESection[i].nrinvalidpages;
                                         objtable.o32_size                = objtable.o32_mapsize*PAGE_SIZE;
@@ -1044,10 +1023,8 @@
                         else //take care of TIBFix code!
                         if(fFirstCode == FALSE && PESection[i].type & SECTION_CODE && j == PESection[i].nrinvalidpages) {
-                                objpage[idx].o32_pagesize        = (USHORT)TIBSize;
+                                objpage[idx].o32_pagesize        = (USHORT)EXE_TIB_SIZE;
                                 objpage[idx].o32_pageflags       = 0;
-                                pagedataoffset                  += TIBSize;
+                                pagedataoffset                  += EXE_TIB_SIZE;
                                 LXHdr.e32_mpages++;
-                                //Modify entry point address, and write original to TIBFix code
-                                *(LONG *)&szTIBFix[TIBOffEntry]  = LXHdr.e32_eip + PAGE_SIZE - TIBOffCall - SIZE_TIBCALL;
 
                                 LXHdr.e32_eip                    = PAGE_SIZE*PESection[i].nrinvalidpages;
@@ -1197,5 +1174,5 @@
                 kerord->nr_stype   = 0x07;              //32 bits offset
                 kerord->nr_flags   = 0x01 | 0x40;       //import by ordinal + mod offset = 16 bits
-                kerord->r32_soff   = TIBOffKerImport;
+                kerord->r32_soff   = EXE_OFF_ENTRYFIX;
                 kerord->r32_objmod = kernel32Object + 1;
                 if(IsEXE)
@@ -1204,13 +1181,4 @@
 
                 currealrec = (realintfixup *)((int)currealrec + sizeof(realnamefixup));
-                if(!IsEXE) {
-                        kerord = (realordfixup *)currealrec;
-                        kerord->nr_stype   = 0x08;              //32 bits self referencing offset
-                        kerord->nr_flags   = 0x01 | 0x40;       //import by ordinal + mod offset = 16 bits
-                        kerord->r32_soff   = DLL_OFF_KERIMP2;
-                        kerord->r32_objmod = kernel32Object + 1;
-                        kerord->ord        = ORD_KERNEL32DLLEXITLIST;
-                        currealrec = (realintfixup *)((int)currealrec + sizeof(realnamefixup));
-                }
         }
         //SvL: 16-9-'97, for multiple import pages
@@ -1233,7 +1201,5 @@
 
   //Add extra kernel32 imports
-  if(IsEXE)
-        nrimpfixups++;
-  else  nrimpfixups += EXTRA_FIXUPS;
+  nrimpfixups += EXTRA_FIXUPS;
 
   //Write fixup page table
@@ -1258,5 +1224,5 @@
   //Write Import Procedure Name array
   if(impnamesize) {
-  DosWrite(win32handle, impnames, impnamesize, &ulWrite);
+  	DosWrite(win32handle, impnames, impnamesize, &ulWrite);
   }
 
@@ -1270,5 +1236,5 @@
                 //Put our special TIB fix to code section first! (SvL: 30-7-'97)
                 if(PESection[i].type & SECTION_CODE && fFirstCode == FALSE) {
-                        DosWrite(win32handle, szTIBFix, TIBSize, &ulWrite);
+                        DosWrite(win32handle, szEXETIBFix, EXE_TIB_SIZE, &ulWrite);
                         fFirstCode = TRUE;
                 }
@@ -1596,5 +1562,5 @@
 
         //fill in parameter for RegisterResourceInfo
-        *(LONG *)&szTIBFix[TIBOffName] = cvtnametableid;
+        *(LONG *)&szEXETIBFix[EXE_OFF_NAMETABLE] = cvtnametableid;
 
         StoreResource(cvtnametableid, RT_RCDATA, (int)curcvtname - (int)cvtname, (char *)cvtname);
@@ -1606,14 +1572,14 @@
 
         //fill in parameter for RegisterResourceInfo
-        *(LONG *)&szTIBFix[TIBOffName+5] = (fConsole << 24) | orgrestableid;
+        *(LONG *)&szEXETIBFix[EXE_OFF_ORGRESTABLE] = (fConsole << 24) | orgrestableid;
 
         StoreResource(orgrestableid, RT_RCDATA, (nrorgres+1)*sizeof(ULONG), (char *)orgrestable);
   }
   else {
-        *(LONG *)&szTIBFix[TIBOffName+5] = (fConsole << 24) | 0x888888;
+        *(LONG *)&szEXETIBFix[EXE_OFF_ORGRESTABLE] = (fConsole << 24) | 0x888888;
   }
   //SvL: 18-7-'98: Store internal pe2lx version and version resource id
-  *(LONG *)&szTIBFix[TIBOffPe2lxVer] = PE2LX_VERSION;
-  *(LONG *)&szTIBFix[TIBOffVerResId] = VersionResourceId;
+  *(LONG *)&szEXETIBFix[EXE_OFF_PE2LXVER] = PE2LX_VERSION;
+  *(LONG *)&szEXETIBFix[EXE_OFF_VERRESID] = VersionResourceId;
 }
 /******************************************************************************/
Index: trunk/src/pe2lx/LX.H
===================================================================
--- trunk/src/pe2lx/LX.H	(revision 278)
+++ trunk/src/pe2lx/LX.H	(revision 281)
@@ -1,3 +1,3 @@
-/* $Id: LX.H,v 1.3 1999-06-10 17:08:51 phaller Exp $ */
+/* $Id: LX.H,v 1.4 1999-07-07 08:11:11 sandervl Exp $ */
 
 /*
@@ -145,5 +145,8 @@
                ~LXHeader();
 
-       void SetEntryAddress(int address);
+       void SetEntryAddress(int address);	//relative
+
+       void SetEntryPoint(int address) { EntryAddress = address; }; //absolute virtual address
+
        void SetExeType(BOOL IsEXE);
        void SetNoFixups();
@@ -159,5 +162,5 @@
        BOOL SaveNewExeFile(char *filename);
        void SetModuleType(int type);
-       void AddOff32Fixup(int address);
+       void AddOff32Fixup(int address, BOOL fLookatStartupCode = FALSE);
        void SetNrOff32Fixups(int nr);
        void AddNameExport(int address, char *name, int ordinal);
@@ -178,4 +181,12 @@
        //SvL: 18-7-'98: Set version resource id
        void SetVersionResourceId(int id) { VersionResourceId = id; };
+
+       void SetTLSAddress(ULONG dwTlsAddress)     	{ tlsAddress = dwTlsAddress; };
+       void SetTLSIndexAddress(ULONG dwTlsIndexAddr)	{ tlsIndexAddr = dwTlsIndexAddr; };
+       void SetTLSInitSize(ULONG dwTlsSize)		{ tlsInitSize = dwTlsSize; };
+       void SetTLSTotalSize(ULONG dwTlsSize)		{ tlsTotalSize = dwTlsSize; };
+       void SetTLSCallBackAddr(ULONG dwTlsCallBackAddr)	{ tlsCallBackAddr = dwTlsCallBackAddr; };
+
+       void AddExtraFixups();
 
 private:
@@ -240,13 +251,9 @@
   ULONG          VersionResourceId;
 
-  unsigned char *szTIBFix;
-  int        TIBSize;
-  int        TIBOffEntry;
-  int        TIBOffCall;
-  int            TIBOffName;
-  int            TIBOffKerImport;
-  //SvL: 18-7-'98: Internal pe2lx version and version resource id offsets
-  int            TIBOffPe2lxVer;
-  int            TIBOffVerResId;
+  ULONG 	tlsAddress;		//address of TLS data
+  ULONG 	tlsIndexAddr;		//address of DWORD that receives the TLS index
+  ULONG 	tlsInitSize;		//size of initialized TLS memory block
+  ULONG 	tlsTotalSize;		//size of TLS memory block
+  ULONG 	tlsCallBackAddr;	//ptr to TLS callback array
 };
 
Index: trunk/src/pe2lx/pe.cpp
===================================================================
--- trunk/src/pe2lx/pe.cpp	(revision 278)
+++ trunk/src/pe2lx/pe.cpp	(revision 281)
@@ -1,3 +1,3 @@
-/* $Id: pe.cpp,v 1.5 1999-07-06 08:50:11 sandervl Exp $ */
+/* $Id: pe.cpp,v 1.6 1999-07-07 08:11:11 sandervl Exp $ */
 
 /*
@@ -230,4 +230,6 @@
   else  OS2Exe.SetModuleName(os2file);
 
+  OS2Exe.SetEntryPoint(oh.AddressOfEntryPoint+oh.ImageBase);
+
   nSections = NR_SECTIONS(win32file);
 
@@ -276,4 +278,22 @@
                         continue;
                 }
+		if(strcmp(psh[i].Name, ".tls") == 0)
+		{
+ 		  IMAGE_TLS_DIRECTORY *tlsDir;
+
+			tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS);
+			if(tlsDir) {
+				cout << "TLS Directory" << endl;
+				cout << "TLS Address of Index     " << hex((ULONG)tlsDir->AddressOfIndex) << endl;
+				cout << "TLS Address of Callbacks " << hex((ULONG)tlsDir->AddressOfCallBacks) << endl;
+				cout << "TLS SizeOfZeroFill       " << hex(tlsDir->SizeOfZeroFill) << endl;
+				cout << "TLS Characteristics      " << hex(tlsDir->Characteristics) << endl;
+				OS2Exe.SetTLSAddress(tlsDir->StartAddressOfRawData);
+				OS2Exe.SetTLSIndexAddress((ULONG)tlsDir->AddressOfIndex);
+				OS2Exe.SetTLSInitSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData);
+				OS2Exe.SetTLSTotalSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData + tlsDir->SizeOfZeroFill);
+				OS2Exe.SetTLSCallBackAddr((ULONG)tlsDir->AddressOfCallBacks);
+			}
+		}
 
                 if ((psh[i].Characteristics & IMAGE_SCN_CNT_CODE)
@@ -287,4 +307,5 @@
                                 OS2Exe.SetEntryAddress(oh.AddressOfEntryPoint - oh.BaseOfCode);
                         else    OS2Exe.SetEntryAddress(oh.AddressOfEntryPoint-psh[i].VirtualAddress);
+
                         OS2Exe.StoreSection((char *)win32file+psh[i].PointerToRawData,
                                             psh[i].SizeOfRawData, psh[i].Misc.VirtualSize,
@@ -332,4 +353,7 @@
   prel = (PIMAGE_BASE_RELOCATION) ImageDirectoryOffset (win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC);
   OS2Exe.SetNrOff32Fixups((prel) ? oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size/2 : 0);
+
+  //SvL: Add EntryPoint & TLS fixups (if required)
+  OS2Exe.AddExtraFixups();
 
   if(prel) {
