Release 970101

Wed Jan  1 15:36:17 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/listbox.c]
	Use FindFirstFile/FindNextFile in LISTBOX_Directory.

	* [files/dos_fs.c]
	Rewrote FindFirstFile/FindNextFile to use DOSFS_FindNext().

	* [files/file.c] [files/directory.c]
	Use Win32 kernel objects and handles for file handles.
	Unified SearchPath() and OpenFile().

	* [loader/builtin.c]
	Moved to if1632/ directory.

	* [tools/build.c] [debugger/*] [miscemu/*]
	Win16 register functions now receive the same CONTEXT * structure
	as Win32 functions.

	* [include/sigcontext.h] [miscemu/instr.c]
	Added new macros to get register values from the SIGCONTEXT
	structure (only used for instruction emulation now).

	* [scheduler/process.c] [scheduler/thread.c] (New files)
	Allocate process and thread structures.

	* [scheduler/process.c] [win32/k32obj.c]
	Added Win32 kernel objects and handles management.

	* [loader/task.c]
	Create a Win32 process and thread for every Win16 task.

	* [misc/commdlg.c] [misc/shell.c] [windows/msgbox.c]
	Built-in resources are now in Win32 format. This also avoids
	16-bit callbacks for built-in dialogs.

	* [misc/lzexpand.c]
	Differentiate between 16-bit and 32-bit file handles.

	* [miscemu/int*.c]
	Moved all int emulation to msdos/ directory.

	* [msdos/*]
	New directory msdos/ contains all MS-DOS emulation code that can
	also be used for Winelib; this should enable Winelib apps to use
	DOS3Call and related functions.

	* [rc/winerc.c]
	A few bug fixes for Win32 resource format.

	* [windows/winpos.c]
	Hack in WINPOS_ReorderOwnerPopups() to avoid X crashed (still not
	right though).

Sun Dec 29 17:47:55 1996  O. Flebbe <flebbe@science-computing.uni-tuebingen.de>

	* [loader/pe_image.c]
	Make sure BSS of a PE_Image is zero.

Sat Dec 28 22:15:34 1996 Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [windows/scroll.c]
	ScrollWindowEx() rewrite, ScrollDC() fix.

	* [windows/nonclient.c] [controls/menu.c]
	Fixed Alt-Space crashes in dialogs.

	* [windows/event.c] [windows/message.c]
	Some changes in mouse message generation.

Thu Dec 26 09:25:24 1996  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [debugger/stabs.c]
	Dummy DEBUG_ReadExecutableDbgInfo provided for !__ELF__ case.

Tue Dec 24 00:59:05 MET 1996  Martin Buck <martin-2.buck@student.uni-ulm.de>

	* [windows/event.c]
	Changed XK_Page_{Up,Down} to XK_{Prior,Next} for X11R5
	compatibility.
diff --git a/loader/task.c b/loader/task.c
index 1795097..9443dfa 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -11,10 +11,8 @@
 #include "windows.h"
 #include "task.h"
 #include "callback.h"
-#include "directory.h"
 #include "dos_fs.h"
 #include "file.h"
-#include "debugger.h"
 #include "global.h"
 #include "instance.h"
 #include "message.h"
@@ -24,19 +22,24 @@
 #include "options.h"
 #include "peexe.h"
 #include "pe_image.h"
+#include "process.h"
 #include "queue.h"
+#include "selectors.h"
 #include "stackframe.h"
+#include "thread.h"
 #include "toolhelp.h"
+#include "winnt.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "dde_proc.h"
 
+#ifndef WINELIB
+#include "debugger.h"
+#endif
+
   /* Min. number of thunks allocated when creating a new segment */
 #define MIN_THUNKS  32
 
-  /* 32-bit stack size for each task */
-#define STACK32_SIZE 0x10000
-
 extern void USER_AppExit( HTASK16, HINSTANCE16, HQUEUE16 );
 
   /* Saved 16-bit stack for current process (Win16 only) */
@@ -45,7 +48,6 @@
 
   /* Saved 32-bit stack for current process (Win16 only) */
 DWORD IF1632_Saved32_esp = 0;
-SEGPTR IF1632_Stack32_base = 0;
 
   /* Original Unix stack */
 DWORD IF1632_Original32_esp;
@@ -279,7 +281,6 @@
  *
  * Allocate a thunk for MakeProcInstance().
  */
-#ifndef WINELIB32
 static SEGPTR TASK_AllocThunk( HTASK16 hTask )
 {
     TDB *pTask;
@@ -308,7 +309,6 @@
     pThunk->free = *(WORD *)((BYTE *)pThunk + pThunk->free);
     return PTR_SEG_OFF_TO_SEGPTR( sel, base );
 }
-#endif
 
 
 /***********************************************************************
@@ -316,7 +316,6 @@
  *
  * Free a MakeProcInstance() thunk.
  */
-#ifndef WINELIB32
 static BOOL TASK_FreeThunk( HTASK16 hTask, SEGPTR thunk )
 {
     TDB *pTask;
@@ -338,7 +337,6 @@
     pThunk->free = LOWORD(thunk) - base;
     return TRUE;
 }
-#endif
 
 
 /***********************************************************************
@@ -350,7 +348,7 @@
 #ifndef WINELIB
 static void TASK_CallToStart(void)
 {
-    int cs_reg, ds_reg, fs_reg, ip_reg;
+    int cs_reg, ds_reg, ip_reg;
     int exit_code = 1;
     TDB *pTask = (TDB *)GlobalLock16( hCurrentTask );
     NE_MODULE *pModule = MODULE_GetPtr( pTask->hModule );
@@ -363,15 +361,12 @@
     {
         /* FIXME: all this is an ugly hack */
 
-        extern void PE_InitTEB( int hTEB );
-        extern void InitTask( SIGCONTEXT *context );
+        extern void InitTask( CONTEXT *context );
         extern void PE_InitializeDLLs( HMODULE16 hModule );
 
         InitTask( NULL );
         InitApp( pTask->hModule );
-        fs_reg = (int)GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, 0x10000 );
-        PE_InitTEB( fs_reg );
-        __asm__ __volatile__("movw %w0,%%fs"::"r" (fs_reg));
+        __asm__ __volatile__("movw %w0,%%fs"::"r" (pCurrentThread->teb_sel));
         PE_InitializeDLLs( pTask->hModule );
         exit_code = CallTaskStart32((FARPROC32)(pModule->pe_module->load_addr + 
                 pModule->pe_module->pe_header->opt_coff.AddressOfEntryPoint) );
@@ -421,6 +416,7 @@
 {
     HTASK16 hTask;
     TDB *pTask;
+    PDB32 *pdb32;
     HGLOBAL16 hParentEnv;
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegTable;
@@ -505,10 +501,10 @@
     pTask->pdb.dispatcher[0] = 0x9a;  /* ljmp */
 #ifndef WINELIB
     *(FARPROC16 *)&pTask->pdb.dispatcher[1] = MODULE_GetEntryPoint( GetModuleHandle("KERNEL"), 102 );  /* KERNEL.102 is DOS3Call() */
+#endif
     pTask->pdb.savedint22 = INT_GetHandler( 0x22 );
     pTask->pdb.savedint23 = INT_GetHandler( 0x23 );
     pTask->pdb.savedint24 = INT_GetHandler( 0x24 );
-#endif
     pTask->pdb.fileHandlesPtr =
         PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel(pTask->hPDB),
                                (int)&((PDB *)0)->fileHandles );
@@ -537,15 +533,14 @@
     pTask->dta = PTR_SEG_OFF_TO_SEGPTR( pTask->hPDB, 
                                 (int)&pTask->pdb.cmdLine - (int)&pTask->pdb );
 
-      /* Allocate the 32-bit stack */
+    /* Create the Win32 part of the task */
 
-    pTask->hStack32 = GLOBAL_Alloc( GMEM_FIXED, STACK32_SIZE, pTask->hPDB,
-                                    FALSE, FALSE, FALSE );
+    pdb32 = PROCESS_Create();
+    pTask->thdb = THREAD_Create( pdb32, 0 );
 
-      /* Create the 32-bit stack frame */
+    /* Create the 32-bit stack frame */
 
-    *(DWORD *)GlobalLock16(pTask->hStack32) = 0xDEADBEEF;
-    stack32Top = (char*)GlobalLock16(pTask->hStack32) + STACK32_SIZE;
+    stack32Top = (char*)pTask->thdb->teb.stack_top;
     frame32 = (STACK32FRAME *)stack32Top - 1;
     frame32->saved_esp = (DWORD)stack32Top;
     frame32->edi = 0;
@@ -633,14 +628,15 @@
     if (!(pTask = (TDB *)GlobalLock16( hTask ))) return;
     hPDB = pTask->hPDB;
 
+    /* Delete the Win32 part of the task */
+
+    PROCESS_Destroy( &pTask->thdb->process->header );
+    THREAD_Destroy( &pTask->thdb->header );
+
     /* Free the task module */
 
     FreeModule16( pTask->hModule );
 
-    /* Close all open files of this task */
-
-    FILE_CloseAllFiles( pTask->hPDB );
-
     /* Free the selector aliases */
 
     GLOBAL_FreeBlock( pTask->hCSAlias );
@@ -667,10 +663,10 @@
  */
 void TASK_KillCurrentTask( INT16 exitCode )
 {
-    extern void EXEC_ExitWindows( int retCode );
+    extern void EXEC_ExitWindows(void);
 
     TDB* pTask = (TDB*) GlobalLock16( hCurrentTask );
-    if (!pTask) EXEC_ExitWindows(0);  /* No current task yet */
+    if (!pTask) EXEC_ExitWindows();  /* No current task yet */
 
     /* Perform USER cleanup */
 
@@ -686,7 +682,7 @@
     if (nTaskCount <= 1)
     {
         dprintf_task( stddeb, "Killing the last task, exiting\n" );
-        EXEC_ExitWindows( 0 );
+        EXEC_ExitWindows();
     }
 
     /* Remove the task from the list to be sure we never switch back to it */
@@ -714,29 +710,6 @@
 }
 
 /***********************************************************************
- *           TASK_YieldToSystem
- *
- * Scheduler interface, this way we ensure that all "unsafe" events are
- * processed outside the scheduler.
- */
-void TASK_YieldToSystem(TDB* pTask)
-{
-  MESSAGEQUEUE*		pQ;
-
-  TASK_SCHEDULE();
-
-  if( pTask )
-  {
-    pQ = (MESSAGEQUEUE*)GlobalLock16(pTask->hQueue);
-    if( pQ && pQ->flags & QUEUE_FLAG_XEVENT )
-    {
-      pQ->flags &= ~QUEUE_FLAG_XEVENT;
-      EVENT_WaitXEvent( FALSE, FALSE );
-    }
-  }
-}
-
-/***********************************************************************
  *           TASK_Reschedule
  *
  * This is where all the magic of task-switching happens!
@@ -830,21 +803,42 @@
       /* Switch to the new stack */
 
     hCurrentTask = hTask;
+    pCurrentThread = pNewTask->thdb;
+    pCurrentProcess = pCurrentThread->process;
     IF1632_Saved16_ss   = pNewTask->ss;
     IF1632_Saved16_sp   = pNewTask->sp;
     IF1632_Saved32_esp  = pNewTask->esp;
-    IF1632_Stack32_base = WIN16_GlobalLock16( pNewTask->hStack32 );
+}
+
+
+/***********************************************************************
+ *           TASK_YieldToSystem
+ *
+ * Scheduler interface, this way we ensure that all "unsafe" events are
+ * processed outside the scheduler.
+ */
+void TASK_YieldToSystem(TDB* pTask)
+{
+  MESSAGEQUEUE*		pQ;
+
+  TASK_SCHEDULE();
+
+  if( pTask )
+  {
+    pQ = (MESSAGEQUEUE*)GlobalLock16(pTask->hQueue);
+    if( pQ && pQ->flags & QUEUE_FLAG_XEVENT )
+    {
+      pQ->flags &= ~QUEUE_FLAG_XEVENT;
+      EVENT_WaitXEvent( FALSE, FALSE );
+    }
+  }
 }
 
 
 /***********************************************************************
  *           InitTask  (KERNEL.91)
  */
-#ifdef WINELIB
-void InitTask(void)
-#else
-void InitTask( SIGCONTEXT *context )
-#endif
+void InitTask( CONTEXT *context )
 {
     TDB *pTask;
     NE_MODULE *pModule;
@@ -852,14 +846,13 @@
     INSTANCEDATA *pinstance;
     LONG stacklow, stackhi;
 
-#ifndef WINELIB
     if (context) EAX_reg(context) = 0;
-#endif
     if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
     if (!(pModule = MODULE_GetPtr( pTask->hModule ))) return;
 
 #ifndef WINELIB
     NE_InitializeDLLs( pTask->hModule );
+#endif
 
     if (context)
     {
@@ -885,7 +878,6 @@
     {
         LocalInit( pTask->hInstance, 0, pModule->heap_size );
     }    
-#endif
 
     /* Initialize the INSTANCEDATA structure */
     pSegTable = NE_SEG_TABLE( pModule );
@@ -1039,12 +1031,10 @@
  */
 FARPROC16 MakeProcInstance16( FARPROC16 func, HANDLE16 hInstance )
 {
-#ifdef WINELIB
-    return func; /* func can be called directly in Winelib */
-#else
     BYTE *thunk;
     SEGPTR thunkaddr;
     
+    if (__winelib) return func; /* func can be called directly in Winelib */
     thunkaddr = TASK_AllocThunk( hCurrentTask );
     if (!thunkaddr) return (FARPROC16)0;
     thunk = PTR_SEG_TO_LIN( thunkaddr );
@@ -1058,7 +1048,6 @@
     *thunk++ = 0xea;    /* ljmp func */
     *(DWORD *)thunk = (DWORD)func;
     return (FARPROC16)thunkaddr;
-#endif
 }
 
 
@@ -1067,10 +1056,8 @@
  */
 void FreeProcInstance16( FARPROC16 func )
 {
-#ifndef WINELIB
     dprintf_task( stddeb, "FreeProcInstance(%08lx)\n", (DWORD)func );
-    TASK_FreeThunk( hCurrentTask, (SEGPTR)func );
-#endif
+    if (!__winelib) TASK_FreeThunk( hCurrentTask, (SEGPTR)func );
 }
 
 
@@ -1079,10 +1066,11 @@
  */
 HANDLE16 GetCodeHandle( FARPROC16 proc )
 {
-#ifndef WINELIB32
     HANDLE16 handle;
     BYTE *thunk = (BYTE *)PTR_SEG_TO_LIN( proc );
 
+    if (__winelib) return 0;
+
     /* Return the code segment containing 'proc'. */
     /* Not sure if this is really correct (shouldn't matter that much). */
 
@@ -1093,9 +1081,6 @@
         handle = GlobalHandle16( HIWORD(proc) );
 
     return handle;
-#else
-    return (HANDLE16)proc;
-#endif
 }
 
 
@@ -1174,7 +1159,7 @@
  *
  * Note: the function is declared as 'register' in the spec file in order
  * to make sure all registers are preserved, but we don't use them in any
- * way, so we don't need a SIGCONTEXT* argument.
+ * way, so we don't need a CONTEXT* argument.
  */
 void SwitchStackBack(void)
 {
@@ -1217,7 +1202,7 @@
  *           GetTaskQueueDS  (KERNEL.118)
  */
 #ifndef WINELIB
-void GetTaskQueueDS( SIGCONTEXT *context )
+void GetTaskQueueDS( CONTEXT *context )
 {
     DS_reg(context) = GlobalHandleToSel( GetTaskQueue(0) );
 }
@@ -1228,7 +1213,7 @@
  *           GetTaskQueueES  (KERNEL.119)
  */
 #ifndef WINELIB
-void GetTaskQueueES( SIGCONTEXT *context )
+void GetTaskQueueES( CONTEXT *context )
 {
     ES_reg(context) = GlobalHandleToSel( GetTaskQueue(0) );
 }