Use the standard CreateThread routine to create 16-bit tasks instead
of duplicating the code.
diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c
index 36f6f8c..1cbd814 100644
--- a/dlls/kernel/kernel_main.c
+++ b/dlls/kernel/kernel_main.c
@@ -26,8 +26,6 @@
static BOOL process_attach(void)
{
HMODULE16 hModule;
- STARTUPINFOA startup_info;
- UINT cmdShow = 1; /* SW_SHOWNORMAL but we don't want to include winuser.h here */
/* Setup codepage info */
CODEPAGE_Init();
@@ -83,11 +81,7 @@
if (!DOSCONF_ReadConfig()) return FALSE;
/* Create 16-bit task */
- GetStartupInfoA( &startup_info );
- if (startup_info.dwFlags & STARTF_USESHOWWINDOW) cmdShow = startup_info.wShowWindow;
- if (!TASK_Create( (NE_MODULE *)GlobalLock16( MapHModuleLS(GetModuleHandleA(0)) ),
- cmdShow, NtCurrentTeb(), NULL, 0 ))
- return FALSE;
+ TASK_CreateMainTask();
return TRUE;
}
diff --git a/include/module.h b/include/module.h
index 72683da..ed89987 100644
--- a/include/module.h
+++ b/include/module.h
@@ -186,6 +186,7 @@
extern FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop );
extern BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset );
extern HANDLE NE_OpenFile( NE_MODULE *pModule );
+extern DWORD NE_StartTask(void);
/* loader/ne/resource.c */
extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16);
diff --git a/include/task.h b/include/task.h
index 7a6b725..5530947 100644
--- a/include/task.h
+++ b/include/task.h
@@ -145,8 +145,9 @@
extern THHOOK *pThhook;
-extern BOOL TASK_Create( struct _NE_MODULE *pModule, UINT16 cmdShow,
- struct _TEB *teb, LPCSTR cmdline, BYTE len );
+extern void TASK_CreateMainTask(void);
+extern HTASK TASK_SpawnTask( struct _NE_MODULE *pModule, WORD cmdShow,
+ LPCSTR cmdline, BYTE len, HANDLE *hThread );
extern void TASK_ExitTask(void);
extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
extern void TASK_Reschedule(void);
diff --git a/include/thread.h b/include/thread.h
index faf7ba8..7d84170 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -125,8 +125,7 @@
/* scheduler/thread.c */
extern void THREAD_Init(void);
-extern TEB *THREAD_Create( int fd, DWORD stack_size, BOOL alloc_stack16 );
-extern TEB *THREAD_InitStack( TEB *teb, DWORD stack_size, BOOL alloc_stack16 );
+extern TEB *THREAD_InitStack( TEB *teb, DWORD stack_size );
extern BOOL THREAD_IsWin16( TEB *thdb );
extern TEB *THREAD_IdToTEB( DWORD id );
diff --git a/loader/ne/module.c b/loader/ne/module.c
index 7985ec5..3914ca2 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -24,7 +24,6 @@
#include "stackframe.h"
#include "debugtools.h"
#include "loadorder.h"
-#include "server.h"
DEFAULT_DEBUG_CHANNEL(module);
DECLARE_DEBUG_CHANNEL(loaddll);
@@ -46,7 +45,6 @@
static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only );
static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep );
-static void NE_InitProcess(void) WINE_NORETURN;
static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only );
@@ -983,35 +981,13 @@
*/
static HINSTANCE16 NE_CreateThread( NE_MODULE *pModule, WORD cmdShow, LPCSTR cmdline )
{
- TEB *teb = NULL;
- HANDLE hThread = 0;
- int socket = -1;
- HTASK hTask;
+ HANDLE hThread;
TDB *pTask;
+ HTASK hTask;
HINSTANCE16 instance = 0;
- SERVER_START_REQ( new_thread )
- {
- req->suspend = 0;
- req->inherit = 0;
- if (!SERVER_CALL_ERR())
- {
- hThread = req->handle;
- socket = wine_server_recv_fd( hThread, 0 );
- }
- }
- SERVER_END_REQ;
- if (!hThread) return 0;
-
- if (!(teb = THREAD_Create( socket, 0, FALSE ))) goto error;
- teb->tibflags &= ~TEBF_WIN32;
- teb->startup = NE_InitProcess;
-
- /* Create a task for this process */
-
- if (!TASK_Create( pModule, cmdShow, teb, cmdline + 1, *cmdline )) goto error;
- hTask = teb->htask16;
- if (SYSDEPS_SpawnThread( teb ) == -1) goto error;
+ if (!(hTask = TASK_SpawnTask( pModule, cmdShow, cmdline + 1, *cmdline, &hThread )))
+ return 0;
/* Post event to start the task */
PostEvent16( hTask );
@@ -1033,13 +1009,8 @@
GlobalUnlock16( hTask );
} while (!instance);
- return instance;
-
- error:
- /* FIXME: free TEB and task */
- close( socket );
CloseHandle( hThread );
- return 0; /* FIXME */
+ return instance;
}
@@ -1138,9 +1109,11 @@
/**********************************************************************
- * NE_InitProcess
+ * NE_StartTask
+ *
+ * Startup code for a new 16-bit task.
*/
-static void NE_InitProcess(void)
+DWORD NE_StartTask(void)
{
TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
NE_MODULE *pModule = NE_GetPtr( pTask->hModule );
@@ -1148,8 +1121,6 @@
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
WORD sp;
- _EnterWin16Lock();
-
if ( pModule->count > 0 )
{
/* Second instance of an already loaded NE module */
@@ -1184,8 +1155,11 @@
pTask->hInstance = hInstance;
pTask->hPrevInstance = hPrevInstance;
+ /* Free the previous stack selector */
+ FreeSelector16( SELECTOROF(pTask->teb->cur_stack) );
+
/* Use DGROUP for 16-bit stack */
-
+
if (!(sp = pModule->sp))
sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
sp &= ~1;
@@ -1224,9 +1198,7 @@
wine_call_to_16_regs_short( &context, 0 );
ExitThread( LOWORD(context.Eax) );
}
-
- _LeaveWin16Lock();
- ExitThread( hInstance );
+ return hInstance; /* error code */
}
/***********************************************************************
diff --git a/loader/task.c b/loader/task.c
index a9661c4..ac86874 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -218,7 +218,7 @@
* by entering the Win16Lock while linking the task into the
* global task list.
*/
-BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline, BYTE len )
+static TDB *TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline, BYTE len )
{
HTASK16 hTask;
TDB *pTask;
@@ -227,7 +227,7 @@
/* Allocate the task structure */
hTask = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, sizeof(TDB) );
- if (!hTask) return FALSE;
+ if (!hTask) return NULL;
pTask = (TDB *)GlobalLock16( hTask );
FarSetOwner16( hTask, pModule->self );
@@ -235,7 +235,7 @@
pTask->hSelf = hTask;
- if (teb->tibflags & TEBF_WIN32)
+ if (teb && teb->tibflags & TEBF_WIN32)
{
pTask->flags |= TDBF_WIN32;
pTask->hInstance = pModule->self;
@@ -323,20 +323,15 @@
if ( !(pTask->flags & TDBF_WIN32) )
NtCreateEvent( &pTask->hEvent, EVENT_ALL_ACCESS, NULL, TRUE, FALSE );
- /* Enter task handle into thread and process */
+ /* Enter task handle into thread */
- teb->htask16 = hTask;
+ if (teb) teb->htask16 = hTask;
if (!initial_task) initial_task = hTask;
- /* Add the task to the linked list */
-
- _EnterWin16Lock();
- TASK_LinkTask( hTask );
- _LeaveWin16Lock();
-
- return TRUE;
+ return pTask;
}
+
/***********************************************************************
* TASK_DeleteTask
*/
@@ -369,6 +364,70 @@
GlobalFreeAll16( hPDB );
}
+
+/***********************************************************************
+ * TASK_CreateMainTask
+ *
+ * Create a task for the main (32-bit) process.
+ */
+void TASK_CreateMainTask(void)
+{
+ TDB *pTask;
+ STARTUPINFOA startup_info;
+ UINT cmdShow = 1; /* SW_SHOWNORMAL but we don't want to include winuser.h here */
+
+ GetStartupInfoA( &startup_info );
+ if (startup_info.dwFlags & STARTF_USESHOWWINDOW) cmdShow = startup_info.wShowWindow;
+ pTask = TASK_Create( (NE_MODULE *)GlobalLock16( MapHModuleLS(GetModuleHandleA(0)) ),
+ cmdShow, NtCurrentTeb(), NULL, 0 );
+ if (!pTask)
+ {
+ ERR("could not create task for main process\n");
+ ExitProcess(1);
+ }
+
+ /* Add the task to the linked list */
+ /* (no need to get the win16 lock, we are the only thread at this point) */
+ TASK_LinkTask( pTask->hSelf );
+}
+
+
+/* startup routine for a new 16-bit thread */
+static DWORD CALLBACK task_start( TDB *pTask )
+{
+ DWORD ret;
+
+ NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
+ NtCurrentTeb()->htask16 = pTask->hSelf;
+
+ _EnterWin16Lock();
+ TASK_LinkTask( pTask->hSelf );
+ pTask->teb = NtCurrentTeb();
+ ret = NE_StartTask();
+ _LeaveWin16Lock();
+ return ret;
+}
+
+
+/***********************************************************************
+ * TASK_SpawnTask
+ *
+ * Spawn a new 16-bit task.
+ */
+HTASK TASK_SpawnTask( NE_MODULE *pModule, WORD cmdShow, LPCSTR cmdline, BYTE len, HANDLE *hThread )
+{
+ TDB *pTask;
+
+ if (!(pTask = TASK_Create( pModule, cmdShow, NULL, cmdline, len ))) return 0;
+ if (!(*hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)task_start, pTask, 0, NULL )))
+ {
+ TASK_DeleteTask( pTask->hSelf );
+ return 0;
+ }
+ return pTask->hSelf;
+}
+
+
/***********************************************************************
* TASK_KillTask
*/
@@ -525,7 +584,7 @@
{
hNewTask = pOldTask->hYieldTo;
pNewTask = (TDB *)GlobalLock16( hNewTask );
- if( !pNewTask || !pNewTask->nEvents) hNewTask = 0;
+ if( !pNewTask || !pNewTask->nEvents || !pNewTask->teb) hNewTask = 0;
pOldTask->hYieldTo = 0;
}
diff --git a/scheduler/process.c b/scheduler/process.c
index e7e7428..482cedb 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -520,7 +520,7 @@
found:
/* allocate main thread stack */
- if (!THREAD_InitStack( NtCurrentTeb(), stack_size, TRUE )) goto error;
+ if (!THREAD_InitStack( NtCurrentTeb(), stack_size )) goto error;
/* switch to the new stack */
SYSDEPS_SwitchToThreadStack( start_process );
@@ -540,7 +540,7 @@
if (!process_init( argv )) exit(1);
/* allocate main thread stack */
- if (!THREAD_InitStack( NtCurrentTeb(), 0, TRUE )) ExitProcess( GetLastError() );
+ if (!THREAD_InitStack( NtCurrentTeb(), 0 )) ExitProcess( GetLastError() );
/* switch to the new stack */
SYSDEPS_SwitchToThreadStack( start_process );
diff --git a/scheduler/thread.c b/scheduler/thread.c
index f8424a2..77daaac 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -131,7 +131,7 @@
*
* Allocate the stack of a thread.
*/
-TEB *THREAD_InitStack( TEB *teb, DWORD stack_size, BOOL alloc_stack16 )
+TEB *THREAD_InitStack( TEB *teb, DWORD stack_size )
{
DWORD old_prot, total_size;
DWORD page_size = getpagesize();
@@ -169,7 +169,7 @@
stack_size = (stack_size + (page_size - 1)) & ~(page_size - 1);
total_size = stack_size + SIGNAL_STACK_SIZE + 3 * page_size;
- if (alloc_stack16) total_size += 0x10000;
+ total_size += 0x10000; /* 16-bit stack */
if (!teb) total_size += page_size;
if (!(base = VirtualAlloc( NULL, total_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE )))
@@ -199,12 +199,10 @@
/* Allocate the 16-bit stack selector */
- if (alloc_stack16)
- {
- teb->stack_sel = SELECTOR_AllocBlock( teb->stack_top, 0x10000, WINE_LDT_FLAGS_DATA );
- if (!teb->stack_sel) goto error;
- teb->cur_stack = MAKESEGPTR( teb->stack_sel, 0x10000 - sizeof(STACK16FRAME) );
- }
+ teb->stack_sel = SELECTOR_AllocBlock( teb->stack_top, 0x10000, WINE_LDT_FLAGS_DATA );
+ if (!teb->stack_sel) goto error;
+ teb->cur_stack = MAKESEGPTR( teb->stack_sel, 0x10000 - sizeof(STACK16FRAME) );
+
return teb;
error:
@@ -255,25 +253,6 @@
DECL_GLOBAL_CONSTRUCTOR(thread_init) { THREAD_Init(); }
-/***********************************************************************
- * THREAD_Create
- *
- */
-TEB *THREAD_Create( int fd, DWORD stack_size, BOOL alloc_stack16 )
-{
- TEB *teb;
-
- if ((teb = THREAD_InitStack( NULL, stack_size, alloc_stack16 )))
- {
- teb->tibflags = TEBF_WIN32;
- teb->process = NtCurrentTeb()->process;
- teb->socket = fd;
- fcntl( fd, F_SETFD, 1 ); /* set close on exec flag */
- TRACE("(%p) succeeded\n", teb);
- }
- return teb;
-}
-
/***********************************************************************
* THREAD_Start
@@ -325,15 +304,20 @@
SERVER_END_REQ;
if (!handle) return 0;
- if (!(teb = THREAD_Create( socket, stack, TRUE )))
+ if (!(teb = THREAD_InitStack( NULL, stack )))
{
close( socket );
return 0;
}
+
+ teb->process = NtCurrentTeb()->process;
+ teb->socket = socket;
teb->entry_point = start;
teb->entry_arg = param;
teb->startup = THREAD_Start;
teb->htask16 = GetCurrentTask();
+ fcntl( socket, F_SETFD, 1 ); /* set close on exec flag */
+
if (id) *id = (DWORD)tid;
if (SYSDEPS_SpawnThread( teb ) == -1)
{