Release 970305

Sun Mar  2 14:57:37 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [*/*]
	Completed transition to new Win32 types.

	* [tools/build.c]
	Changed CallTo16_regs to take a CONTEXT argument.

	* [memory/virtual.c]
	Rewrote Virtual* functions. Implemented CreateFileMapping and
	OpenFileMapping. Broke MapViewOfFile ;-)

	* [win32/k32obj.c]
	Implemented named objects.

Sun Mar  2 00:33:21 1997  Mikolaj Zalewski <zmikolaj@free.polbox.pl>

	* [misc/ole2nls.c] [resources/sysres_Pl.c]
	Added Polish language support.

Sat Mar  1 13:31:25 1997  David Faure <david.faure@ifhamy.insa-lyon.fr>

	* [windows/keyboard.c]
	Wrote VkKeyScan and tested with Winword. Works ok except for dead
	chars.

Fri Feb 28 09:34:03 1997  John Harvey <john@division.co.uk>

	* [graphics/win16drv/font.c] [graphics/win16drv/init.c]
	  [graphics/win16drv/obects.c]
	Added start of SelectObject call for printer driver. Write should
	now run with the printer driver enabled.

Wed Feb 26 20:03:32 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [debugger/*.c]
	Re-added a disassembly command (list serves another functionality
	now).

	* [loader/pe_resource.c]
	Added # support.

	* [misc/ole2nls.c]
	GetStringType* added.

	* [objects/color.c]
	VGA16 fixes.

	* [windows/class.c]
	Look for global widget classes too in GetClassInfo32.

	* [windows/sysmetrics.c] [include/windows.h]
	Added Win32 sysmetrics.

Sat Feb 22 23:56:29 1997  Jukka Iivonen <iivonen@cc.helsinki.fi>

	* [documentation/languages]
	The fourth case updated.

	* [if1632/ntdll.spec]
	Added some is* and to* functions.

Sat Feb 22 23:05:47 1997  Morten Welinder  <terra@diku.dk>

	* [configure.in]
	Add tests for wait4 and waitpid.

	* [loader/signal.c]
	Clean up OS-dependent code.  I hope I got it right, :-)

	* [tools/wineconf]
	Recognise vfat file systems.  Ignore floppy drives specified in
	/etc/fstab.

	* [files/*]
	Fix function names in error messages.

Sat Feb 22 06:15:13 1997  Pablo Saratxaga <srtxg@chanae.stben.be>

	* [windows/keyboard.c] [windows/message.c]
	Support for more latin alphabet dead keys for iso-8859-{1,2,3,4,9}
	characters sets.

Fri Feb 21 20:37:50 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [controls/edit.c]
	Fix incorrect arg order in LOCAL_Alloc() call.

Fri Feb 21 18:19:17 1997  Andrew Taylor  <andrew@riscan.com>

	* [multimedia/mmsystem.c] [multimedia/mcistring.c]
	Fixed bug related to device IDs returned by multimedia
	system.  Implemented mciGetDeviceID.

Sat Feb 15 00:58:19 1997  Jimen Ching  <jching@aloha.com>

	* [debugger/dbg.y]
	Do not dereference invalid expressions.
diff --git a/loader/main.c b/loader/main.c
index 64854d6..8fd8b5d 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -60,10 +60,14 @@
     extern BOOL32 RELAY_Init(void);
     extern BOOL32 WIN16DRV_Init(void);
     extern BOOL32 SIGNAL_Init(void);
+    extern BOOL32 VIRTUAL_Init(void);
     extern BOOL32 WIDGETS_Init(void);
 
     int queueSize;
 
+    /* Initialize virtual memory management */
+    if (!VIRTUAL_Init()) return 0;
+
     /* Create the system and SEGPTR heaps */
     if (!(SystemHeap = HeapCreate( HEAP_GROWABLE, 0x10000, 0 ))) return 0;
     if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return 0;
diff --git a/loader/module.c b/loader/module.c
index 4f4c1e4..b247489 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -848,7 +848,7 @@
     FARPROC16 ret;
     static HMODULE16 hModule = 0;
 
-    if (!hModule) hModule = GetModuleHandle( "WPROCS" );
+    if (!hModule) hModule = GetModuleHandle16( "WPROCS" );
     ordinal = MODULE_GetOrdinal( hModule, name );
     if (!(ret = MODULE_GetEntryPoint( hModule, ordinal )))
         fprintf( stderr, "GetWndProc16: %s not found, please report\n", name );
@@ -1129,7 +1129,7 @@
 		SEGTABLEENTRY * pSegTable = (SEGTABLEENTRY *) NE_SEG_TABLE(pModule);
 		SELFLOADHEADER *selfloadheader;
                 STACK16FRAME *stack16Top;
-		HMODULE16 hselfload = GetModuleHandle("WPROCS");
+		HMODULE16 hselfload = GetModuleHandle16("WPROCS");
 		WORD oldss, oldsp, saved_dgroup = pSegTable[pModule->dgroup - 1].selector;
 		fprintf (stderr, "Warning:  %*.*s is a self-loading module\n"
                                 "Support for self-loading modules is very experimental\n",
@@ -1142,7 +1142,7 @@
 		selfloadheader->EntryAddrProc = 
                                            MODULE_GetEntryPoint(hselfload,27);
 		selfloadheader->MyAlloc  = MODULE_GetEntryPoint(hselfload,28);
-		selfloadheader->SetOwner = MODULE_GetEntryPoint(GetModuleHandle("KERNEL"),403);
+		selfloadheader->SetOwner = MODULE_GetEntryPoint(GetModuleHandle16("KERNEL"),403);
 		pModule->self_loading_sel = GlobalHandleToSel(
 					GLOBAL_Alloc (GMEM_ZEROINIT,
 					0xFF00, hModule, FALSE, FALSE, FALSE)
@@ -1262,9 +1262,9 @@
 
 
 /**********************************************************************
- *	    LoadModule    (KERNEL.45)
+ *	    LoadModule16    (KERNEL.45)
  */
-HINSTANCE16 LoadModule( LPCSTR name, LPVOID paramBlock )
+HINSTANCE16 LoadModule16( LPCSTR name, LPVOID paramBlock )
 {
     return MODULE_Load( name, paramBlock, TRUE );
 }
@@ -1288,7 +1288,7 @@
 
 
 /**********************************************************************
- *	    GetModuleHandle    (KERNEL.47)
+ *	    GetModuleHandle16    (KERNEL.47)
  */
 HMODULE16 WIN16_GetModuleHandle( SEGPTR name )
 {
@@ -1296,7 +1296,7 @@
     return MODULE_FindModule( PTR_SEG_TO_LIN(name) );
 }
 
-HMODULE16 GetModuleHandle( LPCSTR name )
+HMODULE16 GetModuleHandle16( LPCSTR name )
 {
     return MODULE_FindModule( name );
 }
@@ -1410,9 +1410,9 @@
 
 
 /***********************************************************************
- *           FreeLibrary   (KERNEL.96)
+ *           FreeLibrary16   (KERNEL.96)
  */
-void FreeLibrary( HINSTANCE16 handle )
+void FreeLibrary16( HINSTANCE16 handle )
 {
     dprintf_module( stddeb,"FreeLibrary: %04x\n", handle );
     FreeModule16( handle );
@@ -1477,7 +1477,7 @@
 	params.cmdLine  = (SEGPTR)WIN16_GlobalLock16( cmdLineHandle );
 	params.showCmd  = (SEGPTR)WIN16_GlobalLock16( cmdShowHandle );
 	params.reserved = 0;
-	handle = LoadModule( filename, &params );
+	handle = LoadModule16( filename, &params );
 	if (handle == 2)  /* file not found */
 	{
 	    /* Check that the original file name did not have a suffix */
@@ -1487,7 +1487,7 @@
             {
                 p = filename + strlen(filename);
                 strcpy( p, ".exe" );
-                handle = LoadModule( filename, &params );
+                handle = LoadModule16( filename, &params );
                 *p = '\0';  /* Remove extension */
             }
 	}
@@ -1675,7 +1675,7 @@
  */
 BOOL16 ModuleFindName( MODULEENTRY *lpme, LPCSTR name )
 {
-    lpme->wNext = GetModuleHandle( name );
+    lpme->wNext = GetModuleHandle16( name );
     return ModuleNext( lpme );
 }
 
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 9bbdf21..f81cf82 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -31,7 +31,7 @@
 /***********************************************************************
  *           NE_LoadSegment
  */
-BOOL NE_LoadSegment( HMODULE16 hModule, WORD segnum )
+BOOL32 NE_LoadSegment( HMODULE16 hModule, WORD segnum )
 {
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegTable, *pSeg;
@@ -62,8 +62,8 @@
     lseek( fd, pSeg->filepos << pModule->alignment, SEEK_SET );
     size = pSeg->size ? pSeg->size : 0x10000;
     mem = GlobalLock16(pSeg->selector);
-    if (pModule->flags & NE_FFLAGS_SELFLOAD && segnum > 1) {	
-#ifndef WINELIB
+    if (pModule->flags & NE_FFLAGS_SELFLOAD && segnum > 1)
+    {
  	/* Implement self loading segments */
  	SELFLOADHEADER *selfloadheader;
         STACK16FRAME *stack16Top;
@@ -110,10 +110,7 @@
  	
  	IF1632_Saved16_ss = oldss;
  	IF1632_Saved16_sp = oldsp;
-#else
-	fprintf(stderr,"JBP: Ignoring self loading segments in NE_LoadSegment.\n");
-#endif
-     }
+    }
     else if (!(pSeg->flags & NE_SEGFLAGS_ITERATED))
       read(fd, mem, size);
     else {
@@ -362,9 +359,6 @@
  */
 void NE_FixupPrologs( NE_MODULE *pModule )
 {
-#ifdef WINELIB
-	fprintf(stderr,"NE_FixupPrologs should not be called for libwine\n");
-#else
     SEGTABLEENTRY *pSegTable;
     WORD dgroup = 0;
     WORD sel;
@@ -443,7 +437,6 @@
             p += (sel == 0xff) ? 6 : 3;  
         }
     }
-#endif
 }
 
 
@@ -452,12 +445,11 @@
  *
  * Call the DLL initialization code
  */
-static BOOL NE_InitDLL( HMODULE16 hModule )
+static BOOL32 NE_InitDLL( HMODULE16 hModule )
 {
-#ifndef WINELIB
-    int cs_reg, ds_reg, ip_reg, cx_reg, di_reg, bp_reg;
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegTable;
+    CONTEXT context;
 
     /* Registers at initialization must be:
      * cx     heap size
@@ -473,6 +465,8 @@
         (pModule->flags & NE_FFLAGS_WIN32)) return TRUE; /*not a library*/
     if (!pModule->cs) return TRUE;  /* no initialization code */
 
+    memset( &context, 0, sizeof(context) );
+
     if (!(pModule->flags & NE_FFLAGS_SINGLEDATA))
     {
         if (pModule->flags & NE_FFLAGS_MULTIPLEDATA || pModule->dgroup)
@@ -483,31 +477,28 @@
         }
         else  /* DATA NONE DLL */
         {
-            ds_reg = 0;
-            cx_reg = 0;
+            DS_reg(&context)  = 0;
+            ECX_reg(&context) = 0;
         }
     }
     else  /* DATA SINGLE DLL */
     {
-        ds_reg = pSegTable[pModule->dgroup-1].selector;
-        cx_reg = pModule->heap_size;
+        DS_reg(&context)  = pSegTable[pModule->dgroup-1].selector;
+        ECX_reg(&context) = pModule->heap_size;
     }
 
-    cs_reg = pSegTable[pModule->cs-1].selector;
-    ip_reg = pModule->ip;
-    di_reg = ds_reg ? ds_reg : hModule;
-    bp_reg = IF1632_Saved16_sp + ((WORD)&((STACK16FRAME*)1)->bp - 1);
+    CS_reg(&context)  = pSegTable[pModule->cs-1].selector;
+    EIP_reg(&context) = pModule->ip;
+    EBP_reg(&context) = IF1632_Saved16_sp + (WORD)&((STACK16FRAME*)0)->bp;
+    EDI_reg(&context) = DS_reg(&context) ? DS_reg(&context) : hModule;
+
 
     pModule->cs = 0;  /* Don't initialize it twice */
-    dprintf_dll( stddeb, "Calling LibMain, cs:ip=%04x:%04x ds=%04x di=%04x cx=%04x\n", 
-                 cs_reg, ip_reg, ds_reg, di_reg, cx_reg );
-    return CallTo16_regs_( (FARPROC16)(cs_reg << 16 | ip_reg), ds_reg,
-                           0 /*es*/, 0 /*bp*/, 0 /*ax*/, 0 /*bx*/,
-                           cx_reg, 0 /*dx*/, 0 /*si*/, di_reg );
-#else
-    fprintf( stderr,"JBP: Ignoring call to LibMain\n" );
-    return FALSE;
-#endif
+    dprintf_dll( stddeb, "Calling LibMain, cs:ip=%04lx:%04x ds=%04lx di=%04x cx=%04x\n", 
+                 CS_reg(&context), IP_reg(&context), DS_reg(&context),
+                 DI_reg(&context), CX_reg(&context) );
+    CallTo16_regs_( &context );
+    return TRUE;
 }
 
 
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 59d15cb..24cf3e9 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -406,9 +406,9 @@
 	load_addr = pe->load_addr = (int)xmalloc(pe->vma_size);
 	memset( load_addr, 0, pe->vma_size);
 #else
-	load_addr =  pe->load_addr = VirtualAlloc( NULL, pe->vma_size,
-                                                   MEM_COMMIT,
-                                                   PAGE_EXECUTE_READWRITE );
+	load_addr = (int) VirtualAlloc( NULL, pe->vma_size, MEM_COMMIT,
+                                         PAGE_EXECUTE_READWRITE );
+        pe->load_addr = load_addr;
 #endif
 
 	dprintf_win32(stddeb, "Load addr is really %x, range %x\n",
@@ -510,9 +510,11 @@
 		[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].Size)
 		dprintf_win32(stdnimp,"Global Pointer (MIPS) ignored\n");
 
+#ifdef NOT	/* we initialize this later */
 	if(pe->pe_header->OptionalHeader.DataDirectory
 		[IMAGE_DIRECTORY_ENTRY_TLS].Size)
 		 dprintf_win32(stdnimp,"Thread local storage ignored\n");
+#endif
 
 	if(pe->pe_header->OptionalHeader.DataDirectory
 		[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size)
@@ -647,4 +649,30 @@
 	}
 	PE_InitDLL( hModule );
 }
+
+void PE_InitTls( PE_MODULE *module )
+{
+   /* FIXME: tls callbacks ??? */
+   DWORD  index;
+   DWORD  datasize;
+   DWORD  size;
+   LPVOID mem;
+   LPIMAGE_TLS_DIRECTORY pdir;
+
+    if (!module->pe_header->OptionalHeader.DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress)
+        return;
+
+    pdir = (LPVOID)(module->load_addr + module->pe_header->OptionalHeader.
+               DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress);
+    index = TlsAlloc();
+    datasize = pdir->EndAddressOfRawData-pdir->StartAddressOfRawData;
+    size     = datasize + pdir->SizeOfZeroFill;
+        
+    mem = VirtualAlloc(0,size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
+    
+    memcpy(mem,(LPVOID) pdir->StartAddressOfRawData, datasize);
+    TlsSetValue(index,mem);
+    *(pdir->AddressOfIndex)=index;   
+}
+
 #endif /* WINELIB */
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index 08655d0..2d2bbaf 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -11,6 +11,7 @@
  * Copyright 1997 Marcus Meissner
  */
 
+#include <stdlib.h>
 #include <sys/types.h>
 #include "wintypes.h"
 #include "windows.h"
@@ -54,7 +55,12 @@
     int namelen;
 
     if (HIWORD(name)) {
-    /* FIXME: what about #xxx names? */
+    	if (name[0]=='#') {
+		char	buf[10];
+
+		lstrcpynWtoA(buf,name+1,10);
+		return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root);
+	}
 	entryTable = (LPIMAGE_RESOURCE_DIRECTORY_ENTRY) (
 			(BYTE *) resdirptr + 
                         sizeof(IMAGE_RESOURCE_DIRECTORY));
diff --git a/loader/resource.c b/loader/resource.c
index d2f50fe..37dc9c1 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -111,9 +111,15 @@
     if (!hModule) hModule = GetTaskDS();
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
     dprintf_resource(stddeb, "FindResource32W: module=%08x type=", hModule );
-    PrintId( type );
+    if (HIWORD(type))
+    	dprintf_resource(stddeb,"%p",type);
+    else
+	dprintf_resource(stddeb,"#%p",type);
     dprintf_resource( stddeb, " name=" );
-    PrintId( name );
+    if (HIWORD(name))
+    	dprintf_resource(stddeb,"%p",name);
+    else
+	dprintf_resource(stddeb,"#%p",name);
     dprintf_resource( stddeb, "\n" );
     if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
     if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;
diff --git a/loader/signal.c b/loader/signal.c
index e1fba1f..17739ec 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -48,6 +48,21 @@
 	errno = -sig;
 	return -1;
 }
+#endif /* linux */
+
+
+#ifdef linux
+#define HANDLER_DEF(name) void name (int signal, SIGCONTEXT context_struct)
+#define HANDLER_PROLOG SIGCONTEXT *context = &context_struct; (void)context; {
+#define HANDLER_EPILOG }
+#elif defined(__svr4__) || defined(_SCO_DS)
+#define HANDLER_DEF(name) void name (int signal, void *siginfo, SIGCONTEXT *context)
+#define HANDLER_PROLOG  /* nothing */
+#define HANDLER_EPILOG  /* nothing */
+#else
+#define HANDLER_DEF(name) void name (int signal, int code, SIGCONTEXT *context)
+#define HANDLER_PROLOG  /* nothing */
+#define HANDLER_EPILOG  /* nothing */
 #endif
 
 extern BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context );
@@ -57,19 +72,13 @@
  *
  * SIGALRM handler.
  */
-#ifdef linux
-static void wine_timer(int signal, SIGCONTEXT context_struct)
+static
+HANDLER_DEF(wine_timer)
 {
-#elif defined(__svr4__)
-static void wine_timer(int signal, void *siginfo, SIGCONTEXT *context)
-{
-#else
-static void wine_timer(int signal, int code, SIGCONTEXT *context)
-{
-#endif
-    /* Should do real-time timers here */
-
-    DOSMEM_Tick();
+  HANDLER_PROLOG;
+  /* Should do real-time timers here */
+  DOSMEM_Tick();
+  HANDLER_EPILOG;
 }
 
 /**********************************************************************
@@ -77,19 +86,13 @@
  * 
  * Handle Ctrl-C and such
  */
-#ifdef linux
-static void SIGNAL_break(int signal, SIGCONTEXT context_struct)
+static
+HANDLER_DEF(SIGNAL_break)
 {
-    SIGCONTEXT *context = &context_struct;
-#elif defined(__svr4__) || defined(_SCO_DS)
-static void SIGNAL_break(int signal, void *siginfo, SIGCONTEXT *context)
-{
-#else
-static void SIGNAL_break(int signal, int code, SIGCONTEXT *context)
-{
-#endif
-    if (Options.debug) wine_debug( signal, context );  /* Enter our debugger */
-    exit(0);
+  HANDLER_PROLOG;
+  if (Options.debug) wine_debug( signal, context );  /* Enter our debugger */
+  exit(0);
+  HANDLER_EPILOG;
 }
 
 /**********************************************************************
@@ -97,13 +100,19 @@
  * 
  * wait4 terminated child processes
  */
-static void SIGNAL_child(void)
+static
+HANDLER_DEF(SIGNAL_child)
 {
-#if defined(__svr4__) || defined(__EMX__)
-    wait(NULL);
+  HANDLER_PROLOG;
+#ifdef HAVE_WAIT4
+  wait4( 0, NULL, WNOHANG, NULL);
+#elif defined (HAVE_WAITPID)
+  /* I am sort-of guessing that this is the same as the wait4 call.  */
+  waitpid (0, NULL, WNOHANG);
 #else
-    wait4( 0, NULL, WNOHANG, NULL);
+  wait(NULL);
 #endif
+  HANDLER_EPILOG;
 }
 
 
@@ -112,18 +121,12 @@
  *
  * SIGTRAP handler.
  */
-#ifdef linux
-static void SIGNAL_trap(int signal, SIGCONTEXT context_struct)
+static
+HANDLER_DEF(SIGNAL_trap)
 {
-    SIGCONTEXT *context = &context_struct;
-#elif defined(__svr4__) || defined(_SCO_DS)
-static void SIGNAL_trap(int signal, void *siginfo, SIGCONTEXT *context)
-{
-#else
-static void SIGNAL_trap(int signal, int code, SIGCONTEXT *context)
-{
-#endif
-    wine_debug( signal, context );  /* Enter our debugger */
+  HANDLER_PROLOG;
+  wine_debug( signal, context );  /* Enter our debugger */
+  HANDLER_EPILOG;
 }
 
 
@@ -132,30 +135,24 @@
  *
  * Segfault handler.
  */
-#ifdef linux
-static void SIGNAL_fault(int signal, SIGCONTEXT context_struct)
+static
+HANDLER_DEF(SIGNAL_fault)
 {
-    SIGCONTEXT *context = &context_struct;
-#elif defined(__svr4__) || defined(_SCO_DS)
-static void SIGNAL_fault(int signal, void *siginfo, SIGCONTEXT *context)
-{
-#else
-static void SIGNAL_fault(int signal, int code, SIGCONTEXT *context)
-{
-#endif
-    if (CS_sig(context) == WINE_CODE_SELECTOR)
+  HANDLER_PROLOG;
+  if (CS_sig(context) == WINE_CODE_SELECTOR)
     {
         fprintf( stderr, "Segmentation fault in Wine program (%x:%lx)."
                          "  Please debug.\n",
                  CS_sig(context), EIP_sig(context) );
     }
-    else
+  else
     {
         if (INSTR_EmulateInstruction( context )) return;
         fprintf( stderr, "Segmentation fault in Windows program %x:%lx.\n",
                  CS_sig(context), EIP_sig(context) );
     }
-    wine_debug( signal, context );
+  wine_debug( signal, context );
+  HANDLER_EPILOG;
 }
 
 
diff --git a/loader/task.c b/loader/task.c
index d9a666f..38e6028 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -40,6 +40,7 @@
 #define MIN_THUNKS  32
 
 extern void USER_AppExit( HTASK16, HINSTANCE16, HQUEUE16 );
+extern void PE_InitTls( PE_MODULE *module );
 
   /* Saved 16-bit stack for current process (Win16 only) */
 WORD IF1632_Saved16_ss = 0;
@@ -315,7 +316,7 @@
  *
  * Free a MakeProcInstance() thunk.
  */
-static BOOL TASK_FreeThunk( HTASK16 hTask, SEGPTR thunk )
+static BOOL32 TASK_FreeThunk( HTASK16 hTask, SEGPTR thunk )
 {
     TDB *pTask;
     THUNKS *pThunk;
@@ -347,7 +348,6 @@
 #ifndef WINELIB
 static void TASK_CallToStart(void)
 {
-    int cs_reg, ds_reg, ip_reg;
     int exit_code = 1;
     TDB *pTask = (TDB *)GlobalLock16( hCurrentTask );
     NE_MODULE *pModule = MODULE_GetPtr( pTask->hModule );
@@ -384,19 +384,22 @@
          * ss   stack selector
          * sp   top of the stack
          */
+        CONTEXT context;
 
-        cs_reg = pSegTable[pModule->cs - 1].selector;
-        ip_reg = pModule->ip;
-        ds_reg = pSegTable[pModule->dgroup - 1].selector;
+        memset( &context, 0, sizeof(context) );
+        CS_reg(&context)  = pSegTable[pModule->cs - 1].selector;
+        DS_reg(&context)  = pSegTable[pModule->dgroup - 1].selector;
+        ES_reg(&context)  = pTask->hPDB;
+        EIP_reg(&context) = pModule->ip;
+        EBX_reg(&context) = pModule->stack_size;
+        ECX_reg(&context) = pModule->heap_size;
+        EDI_reg(&context) = context.SegDs;
 
-        dprintf_task( stddeb, "Starting main program: cs:ip=%04x:%04x ds=%04x ss:sp=%04x:%04x\n",
-                      cs_reg, ip_reg, ds_reg,
-                      IF1632_Saved16_ss, IF1632_Saved16_sp);
+        dprintf_task( stddeb, "Starting main program: cs:ip=%04lx:%04x ds=%04lx ss:sp=%04x:%04x\n",
+                      CS_reg(&context), IP_reg(&context), DS_reg(&context),
+                      IF1632_Saved16_ss, IF1632_Saved16_sp );
 
-        CallTo16_regs_( (FARPROC16)(cs_reg << 16 | ip_reg), ds_reg,
-                        pTask->hPDB /*es*/, 0 /*bp*/, 0 /*ax*/,
-                        pModule->stack_size /*bx*/, pModule->heap_size /*cx*/,
-                        0 /*dx*/, 0 /*si*/, ds_reg /*di*/ );
+        CallTo16_regs_( &context );
         /* This should never return */
         fprintf( stderr, "TASK_CallToStart: Main program returned!\n" );
         TASK_KillCurrentTask( 1 );
@@ -498,7 +501,8 @@
     pTask->pdb.int20 = 0x20cd;
     pTask->pdb.dispatcher[0] = 0x9a;  /* ljmp */
 #ifndef WINELIB
-    *(FARPROC16 *)&pTask->pdb.dispatcher[1] = MODULE_GetEntryPoint( GetModuleHandle("KERNEL"), 102 );  /* KERNEL.102 is DOS3Call() */
+    *(FARPROC16 *)&pTask->pdb.dispatcher[1] = MODULE_GetEntryPoint(
+            GetModuleHandle16("KERNEL"), 102 );  /* KERNEL.102 is DOS3Call() */
 #endif
     pTask->pdb.savedint22 = INT_GetHandler( 0x22 );
     pTask->pdb.savedint23 = INT_GetHandler( 0x23 );
@@ -541,6 +545,11 @@
             (LPTHREAD_START_ROUTINE)(pModule->pe_module->load_addr +
             pModule->pe_module->pe_header->OptionalHeader.AddressOfEntryPoint);
         pTask->thdb = THREAD_Create( pdb32, 0, start );
+#ifndef WINELIB
+        /* FIXME: should not be done here */
+        pCurrentThread = pTask->thdb;
+        PE_InitTls( pModule->pe_module );
+#endif
     }
     else
         pTask->thdb = THREAD_Create( pdb32, 0, NULL );
@@ -1501,9 +1510,18 @@
 
 
 /***********************************************************************
- *           GetAppCompatFlags   (KERNEL.354) (USER32.205)
+ *           GetAppCompatFlags16   (KERNEL.354)
  */
-DWORD GetAppCompatFlags( HTASK32 hTask )
+DWORD GetAppCompatFlags16( HTASK16 hTask )
+{
+    return GetAppCompatFlags32( hTask );
+}
+
+
+/***********************************************************************
+ *           GetAppCompatFlags32   (USER32.205)
+ */
+DWORD GetAppCompatFlags32( HTASK32 hTask )
 {
     TDB *pTask;