Commit c75d0e16 authored by Ulrich Weigand's avatar Ulrich Weigand Committed by Alexandre Julliard

Implemented new Wine startup sequence, separating startup into

KERNEL/USER/GDI related parts, allowing native replacement. Implemented initial 'kernel' task.
parent ddea38d7
...@@ -93,9 +93,9 @@ extern const WIN16_DESCRIPTOR WPROCS_Descriptor; ...@@ -93,9 +93,9 @@ extern const WIN16_DESCRIPTOR WPROCS_Descriptor;
static BUILTIN16_DLL BuiltinDLLs[] = static BUILTIN16_DLL BuiltinDLLs[] =
{ {
{ &KERNEL_Descriptor, DLL_FLAG_ALWAYS_USED }, { &KERNEL_Descriptor, 0 },
{ &USER_Descriptor, DLL_FLAG_ALWAYS_USED }, { &USER_Descriptor, 0 },
{ &GDI_Descriptor, DLL_FLAG_ALWAYS_USED }, { &GDI_Descriptor, 0 },
{ &SYSTEM_Descriptor, DLL_FLAG_ALWAYS_USED }, { &SYSTEM_Descriptor, DLL_FLAG_ALWAYS_USED },
{ &DISPLAY_Descriptor, DLL_FLAG_ALWAYS_USED }, { &DISPLAY_Descriptor, DLL_FLAG_ALWAYS_USED },
{ &WPROCS_Descriptor, DLL_FLAG_ALWAYS_USED }, { &WPROCS_Descriptor, DLL_FLAG_ALWAYS_USED },
...@@ -202,10 +202,8 @@ static HMODULE16 BUILTIN_DoLoadModule16( const WIN16_DESCRIPTOR *descr ) ...@@ -202,10 +202,8 @@ static HMODULE16 BUILTIN_DoLoadModule16( const WIN16_DESCRIPTOR *descr )
BOOL32 BUILTIN_Init(void) BOOL32 BUILTIN_Init(void)
{ {
BUILTIN16_DLL *dll; BUILTIN16_DLL *dll;
NE_MODULE *pModule;
WORD vector; WORD vector;
HMODULE16 hModule; HMODULE16 hModule;
WORD cs, ds;
fnBUILTIN_LoadModule = BUILTIN_LoadModule; fnBUILTIN_LoadModule = BUILTIN_LoadModule;
...@@ -215,48 +213,6 @@ BOOL32 BUILTIN_Init(void) ...@@ -215,48 +213,6 @@ BOOL32 BUILTIN_Init(void)
if (!BUILTIN_DoLoadModule16( dll->descr )) return FALSE; if (!BUILTIN_DoLoadModule16( dll->descr )) return FALSE;
} }
/* Set the USER and GDI heap selectors */
pModule = NE_GetPtr( GetModuleHandle16( "USER" ));
USER_HeapSel = pModule ? GlobalHandleToSel((NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->hSeg) : 0;
pModule = NE_GetPtr( GetModuleHandle16( "GDI" ));
GDI_HeapSel = pModule ? GlobalHandleToSel((NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->hSeg) : 0;
/* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */
hModule = GetModuleHandle16( "KERNEL" );
NE_SetEntryPoint( hModule, 178, GetWinFlags() );
/* Initialize KERNEL.454/455 (__FLATCS/__FLATDS) */
GET_CS(cs); GET_DS(ds);
NE_SetEntryPoint( hModule, 454, cs );
NE_SetEntryPoint( hModule, 455, ds );
/* Initialize KERNEL.THHOOK */
TASK_InstallTHHook((THHOOK *)PTR_SEG_TO_LIN(
(SEGPTR)NE_GetEntryPoint( hModule, 332 )));
/* Initialize the real-mode selector entry points */
#define SET_ENTRY_POINT( num, addr ) \
NE_SetEntryPoint( hModule, (num), GLOBAL_CreateBlock( GMEM_FIXED, \
DOSMEM_MapDosToLinear(addr), 0x10000, hModule, \
FALSE, FALSE, FALSE, NULL ))
SET_ENTRY_POINT( 183, 0x00000 ); /* KERNEL.183: __0000H */
SET_ENTRY_POINT( 174, 0xa0000 ); /* KERNEL.174: __A000H */
SET_ENTRY_POINT( 181, 0xb0000 ); /* KERNEL.181: __B000H */
SET_ENTRY_POINT( 182, 0xb8000 ); /* KERNEL.182: __B800H */
SET_ENTRY_POINT( 195, 0xc0000 ); /* KERNEL.195: __C000H */
SET_ENTRY_POINT( 179, 0xd0000 ); /* KERNEL.179: __D000H */
SET_ENTRY_POINT( 190, 0xe0000 ); /* KERNEL.190: __E000H */
SET_ENTRY_POINT( 173, 0xf0000 ); /* KERNEL.173: __ROMBIOS */
SET_ENTRY_POINT( 194, 0xf0000 ); /* KERNEL.194: __F000H */
NE_SetEntryPoint( hModule, 193, DOSMEM_BiosSeg ); /* KERNEL.193: __0040H */
#undef SET_ENTRY_POINT
/* Set interrupt vectors from entry points in WPROCS.DLL */ /* Set interrupt vectors from entry points in WPROCS.DLL */
hModule = GetModuleHandle16( "WPROCS" ); hModule = GetModuleHandle16( "WPROCS" );
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
#ifndef __WINE_MAIN_H #ifndef __WINE_MAIN_H
#define __WINE_MAIN_H #define __WINE_MAIN_H
extern BOOL32 MAIN_KernelInit(void);
extern void MAIN_Usage(char*); extern void MAIN_Usage(char*);
extern BOOL32 MAIN_UserInit(void); extern BOOL32 MAIN_MainInit(void);
extern BOOL32 MAIN_WineInit( int *argc, char *argv[] ); extern BOOL32 MAIN_WineInit( int *argc, char *argv[] );
extern HINSTANCE32 MAIN_WinelibInit( int *argc, char *argv[] );
extern int MAIN_GetLanguageID(char*lang, char*country, char*charset, char*dialect); extern int MAIN_GetLanguageID(char*lang, char*country, char*charset, char*dialect);
extern BOOL32 RELAY_Init(void); extern BOOL32 RELAY_Init(void);
......
...@@ -32,19 +32,22 @@ ...@@ -32,19 +32,22 @@
#include "spy.h" #include "spy.h"
#include "tweak.h" #include "tweak.h"
#include "user.h" #include "user.h"
#include "global.h"
#include "dce.h" #include "dce.h"
#include "shell.h" #include "shell.h"
#include "winproc.h" #include "winproc.h"
#include "syslevel.h" #include "syslevel.h"
#include "thread.h"
#include "task.h"
#include "debug.h" #include "debug.h"
int __winelib = 1; /* Winelib run-time flag */ int __winelib = 1; /* Winelib run-time flag */
/*********************************************************************** /***********************************************************************
* Kernel initialisation routine * Main initialisation routine
*/ */
BOOL32 MAIN_KernelInit(void) BOOL32 MAIN_MainInit(void)
{ {
/* Initialize syslevel handling */ /* Initialize syslevel handling */
SYSLEVEL_Init(); SYSLEVEL_Init();
...@@ -73,43 +76,133 @@ BOOL32 MAIN_KernelInit(void) ...@@ -73,43 +76,133 @@ BOOL32 MAIN_KernelInit(void)
/* Initialize IO-port permissions */ /* Initialize IO-port permissions */
IO_port_init(); IO_port_init();
/* registry initialisation */
SHELL_LoadRegistry();
return TRUE; return TRUE;
} }
/***********************************************************************
* KERNEL initialisation routine
*/
BOOL32 WINAPI MAIN_KernelInit(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
static BOOL32 initDone = FALSE;
NE_MODULE *pModule;
HMODULE16 hModule;
if ( initDone ) return TRUE;
initDone = TRUE;
/* Create and switch to initial task */
pModule = NE_GetPtr( GetModuleHandle16( "KERNEL32" ) );
if ( pModule )
{
THDB *thdb = THREAD_Current();
HINSTANCE16 hInstance = NE_CreateInstance( pModule, NULL, TRUE );
thdb->process->task = TASK_Create( thdb, pModule, hInstance, 0, FALSE );
TASK_StartTask( thdb->process->task );
}
/* Initialize special KERNEL entry points */
hModule = GetModuleHandle16( "KERNEL" );
if ( hModule )
{
WORD cs, ds;
/* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */
NE_SetEntryPoint( hModule, 178, GetWinFlags() );
/* Initialize KERNEL.454/455 (__FLATCS/__FLATDS) */
GET_CS(cs); GET_DS(ds);
NE_SetEntryPoint( hModule, 454, cs );
NE_SetEntryPoint( hModule, 455, ds );
/* Initialize KERNEL.THHOOK */
TASK_InstallTHHook((THHOOK *)PTR_SEG_TO_LIN(
(SEGPTR)NE_GetEntryPoint( hModule, 332 )));
/* Initialize the real-mode selector entry points */
#define SET_ENTRY_POINT( num, addr ) \
NE_SetEntryPoint( hModule, (num), GLOBAL_CreateBlock( GMEM_FIXED, \
DOSMEM_MapDosToLinear(addr), 0x10000, hModule, \
FALSE, FALSE, FALSE, NULL ))
SET_ENTRY_POINT( 183, 0x00000 ); /* KERNEL.183: __0000H */
SET_ENTRY_POINT( 174, 0xa0000 ); /* KERNEL.174: __A000H */
SET_ENTRY_POINT( 181, 0xb0000 ); /* KERNEL.181: __B000H */
SET_ENTRY_POINT( 182, 0xb8000 ); /* KERNEL.182: __B800H */
SET_ENTRY_POINT( 195, 0xc0000 ); /* KERNEL.195: __C000H */
SET_ENTRY_POINT( 179, 0xd0000 ); /* KERNEL.179: __D000H */
SET_ENTRY_POINT( 190, 0xe0000 ); /* KERNEL.190: __E000H */
SET_ENTRY_POINT( 173, 0xf0000 ); /* KERNEL.173: __ROMBIOS */
SET_ENTRY_POINT( 194, 0xf0000 ); /* KERNEL.194: __F000H */
NE_SetEntryPoint( hModule, 193, DOSMEM_BiosSeg ); /* KERNEL.193: __0040H */
#undef SET_ENTRY_POINT
}
return TRUE;
}
/*********************************************************************** /***********************************************************************
* USER (and GDI) initialisation routine * GDI initialisation routine
*/ */
BOOL32 MAIN_UserInit(void) BOOL32 WINAPI MAIN_GdiInit(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{ {
int queueSize; NE_MODULE *pModule;
if ( GDI_HeapSel ) return TRUE;
/* Create USER and GDI heap */ /* Create GDI heap */
if (!USER_HeapSel) pModule = NE_GetPtr( GetModuleHandle16( "GDI" ) );
if ( pModule )
{ {
USER_HeapSel = GlobalAlloc16( GMEM_FIXED, 0x10000 ); GDI_HeapSel = GlobalHandleToSel( (NE_SEG_TABLE( pModule ) +
LocalInit( USER_HeapSel, 0, 0xffff ); pModule->dgroup - 1)->hSeg );
} }
if (!GDI_HeapSel) else
{ {
GDI_HeapSel = GlobalAlloc16( GMEM_FIXED, GDI_HEAP_SIZE ); GDI_HeapSel = GlobalAlloc16( GMEM_FIXED, GDI_HEAP_SIZE );
LocalInit( GDI_HeapSel, 0, GDI_HEAP_SIZE-1 ); LocalInit( GDI_HeapSel, 0, GDI_HEAP_SIZE-1 );
} }
/* GDI initialisation */
return GDI_Init();
}
/***********************************************************************
* USER initialisation routine
*/
BOOL32 WINAPI MAIN_UserInit(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
NE_MODULE *pModule;
int queueSize;
if ( USER_HeapSel ) return TRUE;
/* Create USER heap */
pModule = NE_GetPtr( GetModuleHandle16( "USER" ) );
if ( pModule )
{
USER_HeapSel = GlobalHandleToSel( (NE_SEG_TABLE( pModule ) +
pModule->dgroup - 1)->hSeg );
}
else
{
USER_HeapSel = GlobalAlloc16( GMEM_FIXED, 0x10000 );
LocalInit( USER_HeapSel, 0, 0xffff );
}
/* Initialize Wine tweaks */ /* Initialize Wine tweaks */
if (!TWEAK_Init()) return FALSE; if (!TWEAK_Init()) return FALSE;
/* Initialize OEM Bitmaps */ /* Initialize OEM Bitmaps */
if (!OBM_Init()) return FALSE; if (!OBM_Init()) return FALSE;
/* registry initialisation */
SHELL_LoadRegistry();
/* Global atom table initialisation */ /* Global atom table initialisation */
if (!ATOM_Init()) return FALSE; if (!ATOM_Init( USER_HeapSel )) return FALSE;
/* GDI initialisation */
if (!GDI_Init()) return FALSE;
/* Initialize system colors and metrics*/ /* Initialize system colors and metrics*/
SYSMETRICS_Init(); SYSMETRICS_Init();
...@@ -152,6 +245,13 @@ BOOL32 MAIN_UserInit(void) ...@@ -152,6 +245,13 @@ BOOL32 MAIN_UserInit(void)
/* Set double click time */ /* Set double click time */
SetDoubleClickTime32( GetProfileInt32A("windows","DoubleClickSpeed",452) ); SetDoubleClickTime32( GetProfileInt32A("windows","DoubleClickSpeed",452) );
/* Create task message queue for the initial task */
if ( GetCurrentTask() )
{
queueSize = GetProfileInt32A( "windows", "DefaultQueueSize", 8 );
if (!SetMessageQueue32( queueSize )) return FALSE;
}
return TRUE; return TRUE;
} }
...@@ -159,19 +259,50 @@ BOOL32 MAIN_UserInit(void) ...@@ -159,19 +259,50 @@ BOOL32 MAIN_UserInit(void)
/*********************************************************************** /***********************************************************************
* Winelib initialisation routine * Winelib initialisation routine
*/ */
BOOL32 MAIN_WinelibInit( int *argc, char *argv[] ) HINSTANCE32 MAIN_WinelibInit( int *argc, char *argv[] )
{ {
WINE_MODREF *wm;
NE_MODULE *pModule;
OFSTRUCT ofs;
HMODULE16 hModule;
HINSTANCE16 hInstance;
/* Create the initial process */ /* Create the initial process */
if (!PROCESS_Init()) return FALSE; if (!PROCESS_Init()) return 0;
/* Parse command line arguments */ /* Parse command line arguments */
MAIN_WineInit( argc, argv ); MAIN_WineInit( argc, argv );
/* Initialize the kernel */ /* Main initialization */
if (!MAIN_KernelInit()) return FALSE; if (!MAIN_MainInit()) return 0;
/* Initialize all the USER stuff */ /* Initialize KERNEL */
if (!MAIN_UserInit()) return FALSE; if (!MAIN_KernelInit(0, 0, NULL)) return 0;
return TRUE; /* Initialize GDI */
if (!MAIN_GdiInit(0, 0, NULL)) return 0;
/* Initialize USER */
if (!MAIN_UserInit(0, 0, NULL)) return 0;
/* Create and switch to initial task */
if (!(wm = ELF_CreateDummyModule( argv[0], argv[0], PROCESS_Current() )))
return 0;
PROCESS_Current()->exe_modref = wm;
strcpy( ofs.szPathName, wm->modname );
if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) return 0;
pModule = (NE_MODULE *)GlobalLock16( hModule );
pModule->flags = NE_FFLAGS_WIN32;
pModule->module32 = wm->module;
hInstance = NE_CreateInstance( pModule, NULL, TRUE );
PROCESS_Current()->task = TASK_Create( THREAD_Current(), pModule, hInstance, 0, FALSE );
TASK_StartTask( PROCESS_Current()->task );
InitApp( hInstance );
return wm->module;
} }
...@@ -425,9 +425,8 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance, ...@@ -425,9 +425,8 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
if (!(sp = pModule->sp)) if (!(sp = pModule->sp))
sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size; sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
sp &= ~1; sp &= ~1; sp -= 2*sizeof(STACK16FRAME);
pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( pTask->hInstance, sp ); pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( pTask->hInstance, sp );
pTask->thdb->cur_stack -= 2*sizeof(STACK16FRAME);
frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack ); frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
frame16->ebp = sp + (int)&((STACK16FRAME *)0)->bp; frame16->ebp = sp + (int)&((STACK16FRAME *)0)->bp;
frame16->bp = LOWORD(frame16->ebp); frame16->bp = LOWORD(frame16->ebp);
...@@ -451,9 +450,6 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance, ...@@ -451,9 +450,6 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
frame32->retaddr = (DWORD)TASK_CallToStart; frame32->retaddr = (DWORD)TASK_CallToStart;
/* The remaining fields will be initialized in TASK_Reschedule */ /* The remaining fields will be initialized in TASK_Reschedule */
if (!THREAD_Current()->cur_stack)
THREAD_Current()->cur_stack = pTask->thdb->cur_stack;
TRACE(task, "module='%s' cmdline='%s' task=%04x\n", TRACE(task, "module='%s' cmdline='%s' task=%04x\n",
name, cmd_line, hTask ); name, cmd_line, hTask );
...@@ -483,11 +479,10 @@ void TASK_StartTask( HTASK16 hTask ) ...@@ -483,11 +479,10 @@ void TASK_StartTask( HTASK16 hTask )
we simply Yield(). If we are 32-bit however, we need to signal we simply Yield(). If we are 32-bit however, we need to signal
the main process somehow (NOT YET IMPLEMENTED!) */ the main process somehow (NOT YET IMPLEMENTED!) */
if ( GetCurrentTask() ) if ( THREAD_IsWin16( THREAD_Current() ) )
if ( THREAD_IsWin16( THREAD_Current() ) ) OldYield();
Yield16(); else
else FIXME(task, "Don't know how to start 16-bit task from 32-bit thread. Move the mouse!\n");
FIXME(task, "Don't know how to start 16-bit task from 32-bit thread. Move the mouse!\n");
} }
...@@ -584,7 +579,7 @@ void TASK_KillCurrentTask( INT16 exitCode ) ...@@ -584,7 +579,7 @@ void TASK_KillCurrentTask( INT16 exitCode )
TASK_DeleteTask( hTaskToKill ); TASK_DeleteTask( hTaskToKill );
} }
if (nTaskCount <= 1) if (nTaskCount <= 2) /* FIXME */
{ {
TRACE(task, "this is the last task, exiting\n" ); TRACE(task, "this is the last task, exiting\n" );
USER_ExitWindows(); USER_ExitWindows();
...@@ -630,6 +625,34 @@ void TASK_Reschedule(void) ...@@ -630,6 +625,34 @@ void TASK_Reschedule(void)
HTASK16 hTask = 0; HTASK16 hTask = 0;
STACK16FRAME *newframe16; STACK16FRAME *newframe16;
/* Get the initial task up and running */
if (!hCurrentTask && GetCurrentTask())
{
/* We need to remove one pair of stackframes (exept for Winelib) */
STACK16FRAME *oldframe16 = CURRENT_STACK16;
STACK32FRAME *oldframe32 = oldframe16->frame32;
STACK16FRAME *newframe16 = PTR_SEG_TO_LIN( oldframe32->frame16 );
STACK32FRAME *newframe32 = newframe16->frame32;
if (newframe32)
{
newframe16->entry_ip = oldframe16->entry_ip;
newframe16->entry_cs = oldframe16->entry_cs;
newframe16->ip = oldframe16->ip;
newframe16->cs = oldframe16->cs;
newframe32->ebp = oldframe32->ebp;
newframe32->restore_addr = oldframe32->restore_addr;
newframe32->codeselector = oldframe32->codeselector;
newframe32->retaddr = oldframe32->retaddr; /* don't call TASK_CallToStart */
THREAD_Current()->cur_stack = oldframe32->frame16;
}
hCurrentTask = GetCurrentTask();
pNewTask = (TDB *)GlobalLock16( hCurrentTask );
pNewTask->ss_sp = pNewTask->thdb->cur_stack;
return;
}
/* NOTE: As we are entered from 16-bit code, we hold the Win16Lock. /* NOTE: As we are entered from 16-bit code, we hold the Win16Lock.
We hang onto it thoughout most of this routine, so that accesses We hang onto it thoughout most of this routine, so that accesses
to global variables (most notably the task list) are protected. */ to global variables (most notably the task list) are protected. */
...@@ -1229,6 +1252,13 @@ HANDLE32 WINAPI GetFastQueue( void ) ...@@ -1229,6 +1252,13 @@ HANDLE32 WINAPI GetFastQueue( void )
if (!thdb) return 0; if (!thdb) return 0;
if (!(thdb->teb.queue)) if (!(thdb->teb.queue))
{
HMODULE16 hModule = GetModuleHandle16( "USER" );
FARPROC16 proc = WIN32_GetProcAddress16( hModule, "InitThreadInput" );
Callbacks->CallBootAppProc( proc, 0, 4 ); /* FIXME! */
}
if (!(thdb->teb.queue))
FIXME( task, "(): should initialize thread-local queue, expect failure!\n" ); FIXME( task, "(): should initialize thread-local queue, expect failure!\n" );
return (HANDLE32)thdb->teb.queue; return (HANDLE32)thdb->teb.queue;
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* *
*/ */
#include <assert.h>
#include "callback.h" #include "callback.h"
#include "debug.h" #include "debug.h"
#include "debugger.h" #include "debugger.h"
...@@ -13,6 +14,7 @@ ...@@ -13,6 +14,7 @@
#include "process.h" #include "process.h"
#include "win16drv.h" #include "win16drv.h"
#include "psdrv.h" #include "psdrv.h"
#include "thread.h"
#include "windows.h" #include "windows.h"
...@@ -21,13 +23,13 @@ ...@@ -21,13 +23,13 @@
*/ */
BOOL32 MAIN_EmulatorInit(void) BOOL32 MAIN_EmulatorInit(void)
{ {
/* Initialize the kernel */ /* Main initialization */
if (!MAIN_KernelInit()) return FALSE; if (!MAIN_MainInit()) return FALSE;
/* Initialize relay code */ /* Initialize relay code */
if (!RELAY_Init()) return FALSE; if (!RELAY_Init()) return FALSE;
/* Initialize signal handling */ /* Initialize signal handling */
if (!SIGNAL_InitEmulator()) return FALSE; if (!SIGNAL_InitEmulator()) return FALSE;
/* Create the Win16 printer driver */ /* Create the Win16 printer driver */
...@@ -36,8 +38,46 @@ BOOL32 MAIN_EmulatorInit(void) ...@@ -36,8 +38,46 @@ BOOL32 MAIN_EmulatorInit(void)
/* Create the Postscript printer driver (FIXME: should be in Winelib) */ /* Create the Postscript printer driver (FIXME: should be in Winelib) */
if (!PSDRV_Init()) return FALSE; if (!PSDRV_Init()) return FALSE;
/* Initialize all the USER stuff */ /* Load system DLLs into the initial process (and initialize them) */
return MAIN_UserInit(); if (!LoadLibrary16( "KERNEL" )) return FALSE; /* always built-in */
if (!LoadLibrary32A( "KERNEL32" )) return FALSE; /* always built-in */
if (!LoadLibrary16( "GDI.EXE" )) return FALSE;
if (!LoadLibrary32A( "GDI32.DLL" )) return FALSE;
if (!LoadLibrary16( "USER.EXE" )) return FALSE;
if (!LoadLibrary32A( "USER32.DLL" )) return FALSE;
return TRUE;
}
/***********************************************************************
* Main loop of initial task
*/
void MAIN_EmulatorRun( void )
{
BOOL32 (*WINAPI pGetMessage)(MSG32* lpmsg,HWND32 hwnd,UINT32 min,UINT32 max);
BOOL32 (*WINAPI pTranslateMessage)( const MSG32* msg );
LONG (*WINAPI pDispatchMessage)( const MSG32* msg );
MSG32 msg;
HMODULE32 hModule = GetModuleHandle32A( "USER32" );
pGetMessage = GetProcAddress32( hModule, "GetMessageA" );
pTranslateMessage = GetProcAddress32( hModule, "TranslateMessage" );
pDispatchMessage = GetProcAddress32( hModule, "DispatchMessageA" );
assert( pGetMessage );
assert( pTranslateMessage );
assert( pDispatchMessage );
while ( GetNumTasks() > 1 && pGetMessage( &msg, 0, 0, 0 ) )
{
pTranslateMessage( &msg );
pDispatchMessage( &msg );
}
ExitProcess( 0 );
} }
...@@ -131,8 +171,10 @@ int main( int argc, char *argv[] ) ...@@ -131,8 +171,10 @@ int main( int argc, char *argv[] )
if (Options.debug) DEBUG_AddModuleBreakpoints(); if (Options.debug) DEBUG_AddModuleBreakpoints();
ctx_debug_call = ctx_debug; ctx_debug_call = ctx_debug;
#if 0 /* FIXME!! */
IF1632_CallLargeStack = (int (*)(int (*func)(), void *arg))CALL32_Init(); IF1632_CallLargeStack = (int (*)(int (*func)(), void *arg))CALL32_Init();
Yield16(); /* Start the first task */ #endif
MAIN_EmulatorRun();
MSG("WinMain: Should never happen: returned from Yield16()\n" ); MSG("WinMain: Should never happen: returned from Yield16()\n" );
return 0; return 0;
} }
name gdi32 name gdi32
type win32 type win32
init MAIN_GdiInit
0 stub AbortDoc 0 stub AbortDoc
1 stdcall AbortPath(long) AbortPath32 1 stdcall AbortPath(long) AbortPath32
......
name kernel32 name kernel32
type win32 type win32
init MAIN_KernelInit
# Functions exported by the Win95 kernel32.dll # Functions exported by the Win95 kernel32.dll
# (these need to have these exact ordinals, for some win95 dlls # (these need to have these exact ordinals, for some win95 dlls
......
name user32 name user32
type win32 type win32
init MAIN_UserInit
1 stub ActivateKeyboardLayout 1 stub ActivateKeyboardLayout
2 stdcall AdjustWindowRect(ptr long long) AdjustWindowRect32 2 stdcall AdjustWindowRect(ptr long long) AdjustWindowRect32
......
...@@ -254,7 +254,7 @@ BOOL32 PROCESS_Init(void) ...@@ -254,7 +254,7 @@ BOOL32 PROCESS_Init(void)
/* Create the initial process and thread structures */ /* Create the initial process and thread structures */
if (!(pdb = PROCESS_CreatePDB( NULL ))) return FALSE; if (!(pdb = PROCESS_CreatePDB( NULL ))) return FALSE;
if (!(thdb = THREAD_Create( pdb, 0, TRUE, NULL, NULL, NULL, NULL ))) return FALSE; if (!(thdb = THREAD_Create( pdb, 0, FALSE, NULL, NULL, NULL, NULL ))) return FALSE;
thdb->unix_pid = getpid(); thdb->unix_pid = getpid();
PROCESS_InitialProcessID = PDB_TO_PROCESS_ID(pdb); PROCESS_InitialProcessID = PDB_TO_PROCESS_ID(pdb);
...@@ -346,6 +346,12 @@ PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, ...@@ -346,6 +346,12 @@ PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
pdb->task = TASK_Create( thdb, pModule, hInstance, hPrevInstance, cmdShow); pdb->task = TASK_Create( thdb, pModule, hInstance, hPrevInstance, cmdShow);
if (!pdb->task) goto error; if (!pdb->task) goto error;
/* Map system DLLs into this process (from initial process) */
/* FIXME: this is a hack */
pdb->modref_list = PROCESS_Initial()->modref_list;
return pdb; return pdb;
error: error:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment