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) );
}