Improved Winelib apps initialisation code. No longer need to link
winestub.o with Winelib apps.
diff --git a/Make.rules.in b/Make.rules.in
index 6dd52f1..3df7174 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -30,7 +30,7 @@
X_LIBS = @X_LIBS@
XLIB = @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
DLL_LINK = @DLL_LINK@
-WINELIB = $(WINESTUB) $(DLL_LINK)
+WINELIB = $(DLL_LINK)
LIBS = @LIBS@
YACC = @YACC@
LEX = @LEX@
@@ -58,7 +58,6 @@
MAKEDEP = $(TOPOBJDIR)/tools/makedep@PROGEXT@
WRC = $(TOPOBJDIR)/tools/wrc/wrc@PROGEXT@
WRCFLAGS = -c
-WINESTUB = $(TOPOBJDIR)/library/winestub.o
DLLDIR = $(TOPOBJDIR)/dlls
@SET_MAKE@
@@ -205,11 +204,6 @@
$(BUILD) checkbuild:
cd $(TOPOBJDIR)/tools && $(MAKE) build@PROGEXT@
-# Rule to rebuild winestub.o
-
-$(WINESTUB) check_winestub:
- cd $(TOPOBJDIR)/library && $(MAKE) winestub.o
-
# Rule for main module
$(MODULE).o: $(OBJS) Makefile.in $(TOPSRCDIR)/Make.rules.in
diff --git a/debugger/Makefile.in b/debugger/Makefile.in
index 590b852..a6d15b9 100644
--- a/debugger/Makefile.in
+++ b/debugger/Makefile.in
@@ -44,7 +44,7 @@
lex.yy.c: debug.l
$(LEX) -8 -I $(SRCDIR)/debug.l
-winedbg: $(OBJS) $(WINESTUB)
+winedbg: $(OBJS)
$(CC) -o $@ $(OBJS) $(LDOPTIONS) $(ALL_LIBS)
### Dependencies:
diff --git a/include/callback.h b/include/callback.h
index 389bacb..75603d3 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -22,6 +22,10 @@
typedef void (*RELAY)();
extern FARPROC THUNK_Alloc( FARPROC16 func, RELAY relay );
extern void THUNK_Free( FARPROC thunk );
+extern BOOL THUNK_Init(void);
+extern void THUNK_InitCallout(void);
+
+extern void CALL32_Init( void *func, void *target, void *stack ) WINE_NORETURN;
typedef struct
{
diff --git a/include/main.h b/include/main.h
index 76b920b..9341f36 100644
--- a/include/main.h
+++ b/include/main.h
@@ -9,16 +9,11 @@
extern BOOL MAIN_MainInit( int argc, char *argv[], BOOL win32 );
extern BOOL MAIN_WineInit( int argc, char *argv[] );
-extern HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] );
extern int MAIN_GetLanguageID(char*lang, char*country, char*charset, char*dialect);
extern void MAIN_ParseDebugOptions(const char *options);
extern void MAIN_ParseLanguageOption( const char *arg );
extern BOOL RELAY_Init(void);
-extern void THUNK_InitCallout(void);
extern int RELAY_ShowDebugmsgRelay(const char *func);
-extern void CALL32_Init( void *func, void *target, void *stack );
-
-extern BOOL THUNK_Init(void);
#endif /* __WINE_MAIN_H */
diff --git a/include/module.h b/include/module.h
index 5a62dc4..a8d6a992 100644
--- a/include/module.h
+++ b/include/module.h
@@ -184,7 +184,7 @@
extern WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags );
extern BOOL MODULE_FreeLibrary( WINE_MODREF *wm );
extern WINE_MODREF *MODULE_FindModule( LPCSTR path );
-extern HMODULE MODULE_CreateDummyModule( LPCSTR filename, WORD version );
+extern HMODULE MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 );
extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE hmodule, LPCSTR name );
extern SEGPTR WINAPI HasGPHandler16( SEGPTR address );
extern void MODULE_WalkModref( DWORD id );
@@ -234,7 +234,7 @@
/* relay32/builtin.c */
extern WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags);
-extern HMODULE16 BUILTIN32_LoadExeModule(void);
+extern HMODULE BUILTIN32_LoadExeModule( LPCSTR *filename );
extern void BUILTIN32_UnloadLibrary(WINE_MODREF *wm);
#endif /* __WINE_MODULE_H */
diff --git a/include/thread.h b/include/thread.h
index 8b96738..0c709c0 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -122,6 +122,7 @@
extern TEB *THREAD_CreateInitialThread( struct _PDB *pdb, int server_fd );
extern TEB *THREAD_Create( struct _PDB *pdb, void *pid, void *tid, int fd,
DWORD stack_size, BOOL alloc_stack16 );
+extern TEB *THREAD_InitStack( TEB *teb, struct _PDB *pdb, DWORD stack_size, BOOL alloc_stack16 );
extern BOOL THREAD_IsWin16( TEB *thdb );
extern TEB *THREAD_IdToTEB( DWORD id );
diff --git a/libtest/Makefile.in b/libtest/Makefile.in
index 8dc50b6..a04f247 100644
--- a/libtest/Makefile.in
+++ b/libtest/Makefile.in
@@ -22,7 +22,7 @@
RC_SRCS = \
hello3res.rc
-all: check_wrc check_winestub $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
@MAKE_RULES@
diff --git a/loader/main.c b/loader/main.c
index 48dca56..4ad2956 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -55,7 +55,7 @@
#include "server.h"
#include "loadorder.h"
-DEFAULT_DEBUG_CHANNEL(server)
+DEFAULT_DEBUG_CHANNEL(server);
/***********************************************************************
* Main initialisation routine
@@ -92,20 +92,7 @@
/* Initialize module loadorder */
if (!MODULE_InitLoadOrder()) return FALSE;
- /* Initialize DOS memory */
- if (!DOSMEM_Init(0)) return FALSE;
-
- /* Initialize communications */
- COMM_Init();
-
- /* Initialize IO-port permissions */
- IO_port_init();
-
- /* Read DOS config.sys */
- if (!DOSCONF_ReadConfig()) return FALSE;
-
/* Initialize KERNEL */
- if (!LoadLibrary16( "KRNL386.EXE" )) return FALSE;
if (!LoadLibraryA( "KERNEL32" )) return FALSE;
if (!LoadLibraryA( "x11drv" )) return FALSE;
@@ -127,6 +114,11 @@
if ( initDone ) return TRUE;
initDone = TRUE;
+ /* Initialize DOS memory */
+ if (!DOSMEM_Init(0)) return FALSE;
+
+ if (!LoadLibrary16( "KRNL386.EXE" )) return FALSE;
+
/* Initialize special KERNEL entry points */
hModule = GetModuleHandle16( "KERNEL" );
if ( hModule )
@@ -164,55 +156,20 @@
/* Initialize relay code */
if (!RELAY_Init()) return FALSE;
+ /* Initialize communications */
+ COMM_Init();
+
+ /* Initialize IO-port permissions */
+ IO_port_init();
+
+ /* Read DOS config.sys */
+ if (!DOSCONF_ReadConfig()) return FALSE;
+
return TRUE;
}
/***********************************************************************
- * Winelib initialisation routine
- */
-HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] )
-{
- NE_MODULE *pModule;
- HMODULE16 hModule;
- PDB *curr;
-
- /* Main initialization */
- if (!MAIN_MainInit( *argc, argv, TRUE )) return 0;
- *argc = Options.argc;
-
- /* Load WineLib EXE module */
- if ( (hModule = BUILTIN32_LoadExeModule()) < 32 ) return 0;
- pModule = (NE_MODULE *)GlobalLock16( hModule );
-
- /* Create initial task */
- if (!TASK_Create( pModule, FALSE )) return 0;
-
- /* Create 32-bit MODREF */
- if ( !PE_CreateModule( pModule->module32, NE_MODULE_NAME(pModule), 0, FALSE ) )
- return 0;
-
- /* Increment EXE refcount */
- curr = PROCESS_Current();
- assert( curr->exe_modref );
- curr->exe_modref->refCount++;
-
- /* Load system DLLs into the initial process (and initialize them) */
- if ( !LoadLibrary16("GDI.EXE" ) || !LoadLibraryA("GDI32.DLL" )
- || !LoadLibrary16("USER.EXE") || !LoadLibraryA("USER32.DLL"))
- ExitProcess( 1 );
-
- /* attach the imported DLLs */
- if ( !MODULE_DllProcessAttach( curr->exe_modref, NULL ) )
- ExitProcess( 1 );
-
- /* Get pointers to USER routines called by KERNEL */
- THUNK_InitCallout();
-
- return pModule->module32;
-}
-
-/***********************************************************************
* ExitKernel16 (KERNEL.2)
*
* Clean-up everything and exit the Wine process.
diff --git a/loader/module.c b/loader/module.c
index 7bb5667..10189e3 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -336,7 +336,7 @@
*
* Create a dummy NE module for Win32 or Winelib.
*/
-HMODULE MODULE_CreateDummyModule( LPCSTR filename, WORD version )
+HMODULE MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 )
{
HMODULE hModule;
NE_MODULE *pModule;
@@ -388,8 +388,19 @@
pModule->nrname_size = 0;
pModule->fileinfo = sizeof(NE_MODULE);
pModule->os_flags = NE_OSFLAGS_WINDOWS;
- pModule->expected_version = version;
pModule->self = hModule;
+ pModule->module32 = module32;
+
+ /* Set version and flags */
+ if (module32)
+ {
+ pModule->expected_version =
+ ((PE_HEADER(module32)->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) |
+ (PE_HEADER(module32)->OptionalHeader.MinorSubsystemVersion & 0xff);
+ pModule->flags |= NE_FFLAGS_WIN32;
+ if (PE_HEADER(module32)->FileHeader.Characteristics & IMAGE_FILE_DLL)
+ pModule->flags |= NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA;
+ }
/* Set loaded file information */
ofs = (OFSTRUCT *)(pModule + 1);
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 27c5e0d..2ce45c4 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -892,7 +892,6 @@
struct load_dll_request *req = get_req_buffer();
HMODULE hModule32;
HMODULE16 hModule16;
- NE_MODULE *pModule;
WINE_MODREF *wm;
char filename[256];
HANDLE hFile;
@@ -916,15 +915,12 @@
}
/* Create 16-bit dummy module */
- if ((hModule16 = MODULE_CreateDummyModule( filename, version )) < 32)
+ if ((hModule16 = MODULE_CreateDummyModule( filename, hModule32 )) < 32)
{
CloseHandle( hFile );
SetLastError( (DWORD)hModule16 ); /* This should give the correct error */
return NULL;
}
- pModule = (NE_MODULE *)GlobalLock16( hModule16 );
- pModule->flags = NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA | NE_FFLAGS_WIN32;
- pModule->module32 = hModule32;
/* Create 32-bit MODREF */
if ( !(wm = PE_CreateModule( hModule32, filename, flags, FALSE )) )
@@ -994,14 +990,12 @@
#endif
/* Create 16-bit dummy module */
- if ( (hModule16 = MODULE_CreateDummyModule( filename, version )) < 32 )
+ if ( (hModule16 = MODULE_CreateDummyModule( filename, hModule32 )) < 32 )
{
SetLastError( hModule16 );
return FALSE;
}
pModule = (NE_MODULE *)GlobalLock16( hModule16 );
- pModule->flags = NE_FFLAGS_WIN32;
- pModule->module32 = hModule32;
/* Create new process */
if ( !PROCESS_Create( pModule, hFile, cmd_line, env,
diff --git a/misc/options.c b/misc/options.c
index aee4caa..ff47176 100644
--- a/misc/options.c
+++ b/misc/options.c
@@ -22,6 +22,11 @@
const char *usage;
};
+/* Most Windows C/C++ compilers use something like this to */
+/* access argc and argv globally: */
+int _ARGC;
+char **_ARGV;
+
static void do_config( const char *arg );
static void do_desktop( const char *arg );
static void do_display( const char *arg );
@@ -184,4 +189,6 @@
}
Options.argc = argc;
Options.argv = argv;
+ _ARGC = argc;
+ _ARGV = argv;
}
diff --git a/programs/avitools/Makefile.in b/programs/avitools/Makefile.in
index 94199d7..09f90ae 100644
--- a/programs/avitools/Makefile.in
+++ b/programs/avitools/Makefile.in
@@ -13,7 +13,7 @@
aviinfo.spec \
aviplay.spec
-all: check_wrc check_winestub $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
@MAKE_RULES@
diff --git a/programs/clock/Makefile.in b/programs/clock/Makefile.in
index 36498df..4419c11 100644
--- a/programs/clock/Makefile.in
+++ b/programs/clock/Makefile.in
@@ -21,7 +21,7 @@
RC_SRCS = rsrc.rc
-all: check_wrc check_winestub $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
@MAKE_RULES@
diff --git a/programs/cmdlgtst/Makefile.in b/programs/cmdlgtst/Makefile.in
index 52fbec1..07b4978 100644
--- a/programs/cmdlgtst/Makefile.in
+++ b/programs/cmdlgtst/Makefile.in
@@ -17,7 +17,7 @@
RC_SRCS = \
cmdlgr.rc
-all: check_wrc check_winestub $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
@MAKE_RULES@
diff --git a/programs/control/Makefile.in b/programs/control/Makefile.in
index 603c269..70e98d0 100644
--- a/programs/control/Makefile.in
+++ b/programs/control/Makefile.in
@@ -11,7 +11,7 @@
SPEC_SRCS = control.spec
-all: check_winestub $(PROGRAMS)
+all: $(PROGRAMS)
@MAKE_RULES@
diff --git a/programs/notepad/Makefile.in b/programs/notepad/Makefile.in
index 78de8db..a83922b 100644
--- a/programs/notepad/Makefile.in
+++ b/programs/notepad/Makefile.in
@@ -22,7 +22,7 @@
RC_SRCS = rsrc.rc
-all: check_wrc check_winestub $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
@MAKE_RULES@
diff --git a/programs/osversioncheck/Makefile.in b/programs/osversioncheck/Makefile.in
index 29f28cc..bf361c7 100644
--- a/programs/osversioncheck/Makefile.in
+++ b/programs/osversioncheck/Makefile.in
@@ -15,9 +15,6 @@
@MAKE_RULES@
-#this line is needed to prevent winestub.o being linked
-WINESTUB =
-
osversioncheck: $(OBJS)
$(CC) -o osversioncheck $(OBJS) $(LDOPTIONS) $(ALL_LIBS)
diff --git a/programs/osversioncheck/osversioncheck.c b/programs/osversioncheck/osversioncheck.c
index fd8510f..f7c1ddd 100644
--- a/programs/osversioncheck/osversioncheck.c
+++ b/programs/osversioncheck/osversioncheck.c
@@ -11,13 +11,6 @@
#include <winbase.h>
#include <stdio.h>
-#ifdef WINELIB
-/* External declaration here because we don't want to depend on Wine's
- internal headers. */
-extern HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] );
-#endif /* WINELIB */
-
-
void
show_last_error(void)
{
@@ -47,15 +40,10 @@
}
int
-main(int argc, char ** argv)
+wine_main(int argc, char ** argv)
{
BOOL result;
OSVERSIONINFO oiv;
- HINSTANCE hinst;
-
-#ifdef WINELIB
- if (!(hinst = MAIN_WinelibInit(&argc, argv))) return 0;
-#endif /* WINELIB */
/* FIXME: GetVersionEx() is a Win32 API call, so there should be a
preliminary check to see if we're running bare-bones Windows3.xx
diff --git a/programs/osversioncheck/osversioncheck.spec b/programs/osversioncheck/osversioncheck.spec
index da3eac9..585ef75 100644
--- a/programs/osversioncheck/osversioncheck.spec
+++ b/programs/osversioncheck/osversioncheck.spec
@@ -1,4 +1,4 @@
name osversioncheck
mode cuiexe
type win32
-init main
+init wine_main
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in
index ce6378d..f69ce7c 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -24,7 +24,7 @@
RC_SRCS = rsrc.rc
-all: check_wrc check_winestub $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
@MAKE_RULES@
diff --git a/programs/regapi/Makefile.in b/programs/regapi/Makefile.in
index 55d2461..d3d8127 100644
--- a/programs/regapi/Makefile.in
+++ b/programs/regapi/Makefile.in
@@ -13,7 +13,7 @@
SPEC_SRCS = \
regapi.spec
-all: check_winestub $(PROGRAMS)
+all: $(PROGRAMS)
@MAKE_RULES@
diff --git a/programs/regtest/Makefile.in b/programs/regtest/Makefile.in
index 3078d7b..1cc86f1 100644
--- a/programs/regtest/Makefile.in
+++ b/programs/regtest/Makefile.in
@@ -11,7 +11,7 @@
SPEC_SRCS = regtest.spec
-all: check_winestub $(PROGRAMS)
+all: $(PROGRAMS)
@MAKE_RULES@
diff --git a/programs/view/Makefile.in b/programs/view/Makefile.in
index 94e0b83..f34739e 100644
--- a/programs/view/Makefile.in
+++ b/programs/view/Makefile.in
@@ -19,7 +19,7 @@
RC_SRCS = \
viewrc.rc
-all: check_wrc check_winestub $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
@MAKE_RULES@
diff --git a/programs/wcmd/Makefile.in b/programs/wcmd/Makefile.in
index 60df63e..2da5eb1 100644
--- a/programs/wcmd/Makefile.in
+++ b/programs/wcmd/Makefile.in
@@ -24,9 +24,6 @@
@MAKE_RULES@
-#this line is needed to prevent winestub.o being linked
-WINESTUB =
-
wcmd: $(OBJS)
$(CC) -o wcmd $(OBJS) $(LDOPTIONS) $(ALL_LIBS)
diff --git a/programs/wcmd/wcmd.spec b/programs/wcmd/wcmd.spec
index a78c34d..4c881b5 100644
--- a/programs/wcmd/wcmd.spec
+++ b/programs/wcmd/wcmd.spec
@@ -1,4 +1,4 @@
name wcmd
mode cuiexe
type win32
-init main
+init wine_main
diff --git a/programs/wcmd/wcmdmain.c b/programs/wcmd/wcmdmain.c
index 281c7b2..23f4aa9 100644
--- a/programs/wcmd/wcmdmain.c
+++ b/programs/wcmd/wcmdmain.c
@@ -14,22 +14,12 @@
#include "wcmd.h"
-#ifdef WINELIB
-/* external declaration here because we don't want to depend on Wine headers */
-#ifdef __cplusplus
-extern "C" HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] );
-#else
-extern HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] );
-#endif
-#endif /* WINELIB */
-
char *inbuilt[] = {"ATTRIB", "CALL", "CD", "CHDIR", "CLS", "COPY", "CTTY",
"DATE", "DEL", "DIR", "ECHO", "ERASE", "FOR", "GOTO",
"HELP", "IF", "LABEL", "MD", "MKDIR", "MOVE", "PATH", "PAUSE",
"PROMPT", "REM", "REN", "RENAME", "RD", "RMDIR", "SET", "SHIFT",
"TIME", "TYPE", "VERIFY", "VER", "VOL", "EXIT"};
-HINSTANCE hinst;
int echo_mode = 1, verify_mode = 0;
char nyi[] = "Not Yet Implemented\n\n";
char newline[] = "\n";
@@ -44,19 +34,13 @@
*/
-int main (int argc, char *argv[]) {
+int wine_main (int argc, char *argv[]) {
char string[1024], args[MAX_PATH], param[MAX_PATH];
int status, i;
DWORD count;
HANDLE h;
-#ifdef WINELIB
- if (!(hinst = MAIN_WinelibInit( &argc, argv ))) return 0;
-#else
- hinst = 0;
-#endif
-
args[0] = param[0] = '\0';
if (argc > 1) {
for (i=1; i<argc; i++) {
diff --git a/programs/winemine/Makefile.in b/programs/winemine/Makefile.in
index 2afd0e0..ddd4d01 100644
--- a/programs/winemine/Makefile.in
+++ b/programs/winemine/Makefile.in
@@ -19,7 +19,7 @@
RC_SRCS = rsrc.rc
-all: check_wrc check_winestub $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
@MAKE_RULES@
diff --git a/programs/winhelp/Makefile.in b/programs/winhelp/Makefile.in
index 67a0f5b..9d0d9c7 100644
--- a/programs/winhelp/Makefile.in
+++ b/programs/winhelp/Makefile.in
@@ -21,7 +21,7 @@
RC_SRCS = rsrc.rc
-all: check_wrc check_winestub $(PROGRAMS)
+all: check_wrc $(PROGRAMS)
depend: y.tab.h
diff --git a/programs/winver/Makefile.in b/programs/winver/Makefile.in
index 343ac65..b8b3446 100644
--- a/programs/winver/Makefile.in
+++ b/programs/winver/Makefile.in
@@ -11,7 +11,7 @@
SPEC_SRCS = winver.spec
-all: check_winestub $(PROGRAMS)
+all: $(PROGRAMS)
@MAKE_RULES@
diff --git a/relay32/builtin32.c b/relay32/builtin32.c
index 5a91237..6930f42 100644
--- a/relay32/builtin32.c
+++ b/relay32/builtin32.c
@@ -385,15 +385,13 @@
else BUILTIN32_WarnSecondInstance( builtin_dlls[i]->name );
/* Create 16-bit dummy module */
- if ((hModule16 = MODULE_CreateDummyModule( dllname, 0 )) < 32)
+ if ((hModule16 = MODULE_CreateDummyModule( dllname, dll_modules[i] )) < 32)
{
SetLastError( (DWORD)hModule16 );
return NULL; /* FIXME: Should unload the builtin module */
}
-
pModule = (NE_MODULE *)GlobalLock16( hModule16 );
pModule->flags = NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA | NE_FFLAGS_WIN32 | NE_FFLAGS_BUILTIN;
- pModule->module32 = dll_modules[i];
/* Create 32-bit MODREF */
if ( !(wm = PE_CreateModule( pModule->module32, dllname, flags, TRUE )) )
@@ -419,7 +417,7 @@
/***********************************************************************
* BUILTIN32_LoadExeModule
*/
-HMODULE16 BUILTIN32_LoadExeModule( void )
+HMODULE BUILTIN32_LoadExeModule( LPCSTR *filename )
{
HMODULE16 hModule16;
NE_MODULE *pModule;
@@ -449,14 +447,8 @@
if ( !(dll_modules[exe] = BUILTIN32_DoLoadImage( builtin_dlls[exe] )) )
return 0;
- /* Create 16-bit dummy module */
- hModule16 = MODULE_CreateDummyModule( builtin_dlls[exe]->filename, 0 );
- if ( hModule16 < 32 ) return 0;
- pModule = (NE_MODULE *)GlobalLock16( hModule16 );
- pModule->flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_WIN32 | NE_FFLAGS_BUILTIN;
- pModule->module32 = dll_modules[exe];
-
- return hModule16;
+ *filename = builtin_dlls[exe]->filename;
+ return dll_modules[exe];
}
diff --git a/scheduler/process.c b/scheduler/process.c
index ba2ed7b..b7cd744 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -7,11 +7,13 @@
#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "wine/winbase16.h"
#include "wine/exception.h"
#include "process.h"
+#include "main.h"
#include "module.h"
#include "neexe.h"
#include "file.h"
@@ -28,13 +30,15 @@
#include "callback.h"
#include "debugtools.h"
-DEFAULT_DEBUG_CHANNEL(process)
-DECLARE_DEBUG_CHANNEL(relay)
-DECLARE_DEBUG_CHANNEL(win32)
+DEFAULT_DEBUG_CHANNEL(process);
+DECLARE_DEBUG_CHANNEL(relay);
+DECLARE_DEBUG_CHANNEL(win32);
/* The initial process PDB */
static PDB initial_pdb;
+static ENVDB initial_envdb;
+static STARTUPINFOA initial_startup;
static PDB *PROCESS_First = &initial_pdb;
@@ -297,6 +301,7 @@
*/
BOOL PROCESS_Init( BOOL win32 )
{
+ struct init_process_request *req;
TEB *teb;
int server_fd;
@@ -308,11 +313,13 @@
initial_pdb.threads = 1;
initial_pdb.running_threads = 1;
initial_pdb.ring0_threads = 1;
+ initial_pdb.env_db = &initial_envdb;
initial_pdb.group = &initial_pdb;
initial_pdb.priority = 8; /* Normal */
initial_pdb.flags = win32? 0 : PDB32_WIN16_PROC;
initial_pdb.winver = 0xffff; /* to be determined */
initial_pdb.main_queue = INVALID_HANDLE_VALUE16;
+ initial_envdb.startup_info = &initial_startup;
/* Initialize virtual memory management */
if (!VIRTUAL_Init()) return FALSE;
@@ -338,20 +345,209 @@
/* Initialize signal handling */
if (!SIGNAL_Init()) return FALSE;
- /* Create the environment DB of the first process */
- if (!PROCESS_CreateEnvDB()) return FALSE;
+ /* Retrieve startup info from the server */
+ req = get_req_buffer();
+ req->ldt_copy = ldt_copy;
+ req->ldt_flags = ldt_flags_copy;
+ if (server_call( REQ_INIT_PROCESS )) return FALSE;
+ initial_pdb.exe_file = req->exe_file;
+ initial_startup.dwFlags = req->start_flags;
+ initial_startup.wShowWindow = req->cmd_show;
+ initial_envdb.hStdin = initial_startup.hStdInput = req->hstdin;
+ initial_envdb.hStdout = initial_startup.hStdOutput = req->hstdout;
+ initial_envdb.hStderr = initial_startup.hStdError = req->hstderr;
+ initial_envdb.cmd_line = "";
+
+ /* Copy the parent environment */
+ if (!ENV_InheritEnvironment( NULL )) return FALSE;
/* Create the SEGPTR heap */
if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
- /* Initialize the first process critical section */
+ /* Initialize the critical sections */
InitializeCriticalSection( &initial_pdb.crit_section );
+ InitializeCriticalSection( &initial_envdb.section );
return TRUE;
}
/***********************************************************************
+ * start_process
+ *
+ * Startup routine of a new Win32 process. Runs on the new process stack.
+ */
+static void start_process(void)
+{
+ struct init_process_done_request *req = get_req_buffer();
+ int debugged;
+ HMODULE16 hModule16;
+ UINT cmdShow = SW_SHOWNORMAL;
+ LPTHREAD_START_ROUTINE entry;
+ PDB *pdb = PROCESS_Current();
+ HMODULE main_module = pdb->exe_modref->module;
+
+ /* Increment EXE refcount */
+ pdb->exe_modref->refCount++;
+
+ /* Retrieve entry point address */
+ entry = (LPTHREAD_START_ROUTINE)RVA_PTR( main_module, OptionalHeader.AddressOfEntryPoint );
+
+ /* Create 16-bit dummy module */
+ if ((hModule16 = MODULE_CreateDummyModule( pdb->exe_modref->filename, main_module )) < 32)
+ ExitProcess( hModule16 );
+
+ if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW)
+ cmdShow = pdb->env_db->startup_info->wShowWindow;
+ if (!TASK_Create( (NE_MODULE *)GlobalLock16( hModule16 ), cmdShow )) goto error;
+
+ /* Signal the parent process to continue */
+ req->module = (void *)main_module;
+ req->entry = entry;
+ server_call( REQ_INIT_PROCESS_DONE );
+ debugged = req->debugged;
+
+ if (pdb->flags & PDB32_CONSOLE_PROC) AllocConsole();
+
+ /* Load system DLLs into the initial process (and initialize them) */
+ if (!LoadLibraryA( "KERNEL32" )) goto error;
+ if (!LoadLibraryA( "x11drv" )) goto error;
+
+ if ( !LoadLibrary16("GDI.EXE" ) || !LoadLibraryA("GDI32.DLL" )
+ || !LoadLibrary16("USER.EXE") || !LoadLibraryA("USER32.DLL"))
+ goto error;
+
+ /* Get pointers to USER routines called by KERNEL */
+ THUNK_InitCallout();
+
+ /* Call FinalUserInit routine */
+ Callout.FinalUserInit16();
+
+ /* Note: The USIG_PROCESS_CREATE signal is supposed to be sent in the
+ * context of the parent process. Actually, the USER signal proc
+ * doesn't really care about that, but it *does* require that the
+ * startup parameters are correctly set up, so that GetProcessDword
+ * works. Furthermore, before calling the USER signal proc the
+ * 16-bit stack must be set up, which it is only after TASK_Create
+ * in the case of a 16-bit process. Thus, we send the signal here.
+ */
+
+ PROCESS_CallUserSignalProc( USIG_PROCESS_CREATE, 0 );
+ PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0 );
+ PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0 );
+ PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0 );
+
+ EnterCriticalSection( &pdb->crit_section );
+ PE_InitTls();
+ MODULE_DllProcessAttach( pdb->exe_modref, (LPVOID)1 );
+ LeaveCriticalSection( &pdb->crit_section );
+
+ /* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */
+ if (pdb->flags & PDB32_CONSOLE_PROC)
+ PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
+
+ TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry );
+ if (debugged) DbgBreakPoint();
+ /* FIXME: should use _PEB as parameter for NT 3.5 programs !
+ * Dunno about other OSs */
+ ExitProcess( entry(NULL) );
+
+ error:
+ ExitProcess( GetLastError() );
+}
+
+
+/***********************************************************************
+ * PROCESS_Init32
+ *
+ * Initialisation of a new Win32 process.
+ */
+void PROCESS_Init32( HFILE hFile, LPCSTR filename, LPCSTR cmd_line )
+{
+ WORD version;
+ HMODULE main_module;
+ PDB *pdb = PROCESS_Current();
+
+ pdb->env_db->cmd_line = HEAP_strdupA( GetProcessHeap(), 0, cmd_line );
+
+ /* load main module */
+ if ((main_module = PE_LoadImage( hFile, filename, &version )) < 32)
+ ExitProcess( main_module );
+#if 0
+ if (PE_HEADER(main_module)->FileHeader.Characteristics & IMAGE_FILE_DLL)
+ {
+ SetLastError( 20 ); /* FIXME: not the right error code */
+ goto error;
+ }
+#endif
+
+ /* Create 32-bit MODREF */
+ if (!PE_CreateModule( main_module, filename, 0, FALSE )) goto error;
+
+ /* allocate main thread stack */
+ if (!THREAD_InitStack( NtCurrentTeb(), pdb,
+ PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE ))
+ goto error;
+
+ SIGNAL_Init(); /* reinitialize signal stack */
+
+ /* switch to the new stack */
+ CALL32_Init( &IF1632_CallLargeStack, start_process, NtCurrentTeb()->stack_top );
+ error:
+ ExitProcess( GetLastError() );
+}
+
+
+/***********************************************************************
+ * PROCESS_InitWinelib
+ *
+ * Initialisation of a new Winelib process.
+ */
+void PROCESS_InitWinelib( int argc, char *argv[] )
+{
+ PDB *pdb;
+ HMODULE main_module;
+ LPCSTR filename;
+ LPSTR cmdline, p;
+ int i, len = 0;
+
+ if (!MAIN_MainInit( argc, argv, TRUE )) exit(1);
+ pdb = PROCESS_Current();
+
+ /* build command-line */
+ for (i = 0; Options.argv[i]; i++) len += strlen(Options.argv[i]) + 1;
+ if (!(cmdline = HeapAlloc( GetProcessHeap(), 0, len ))) goto error;
+ for (p = cmdline, i = 0; Options.argv[i]; i++)
+ {
+ strcpy( p, Options.argv[i] );
+ p += strlen(p);
+ *p++ = ' ';
+ }
+ if (p > cmdline) p--;
+ *p = 0;
+ pdb->env_db->cmd_line = cmdline;
+
+ /* create 32-bit module for main exe */
+ if ((main_module = BUILTIN32_LoadExeModule( &filename )) < 32 ) goto error;
+
+ /* Create 32-bit MODREF */
+ if (!PE_CreateModule( main_module, filename, 0, FALSE )) goto error;
+
+ /* allocate main thread stack */
+ if (!THREAD_InitStack( NtCurrentTeb(), pdb,
+ PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve, TRUE ))
+ goto error;
+
+ SIGNAL_Init(); /* reinitialize signal stack */
+
+ /* switch to the new stack */
+ CALL32_Init( &IF1632_CallLargeStack, start_process, NtCurrentTeb()->stack_top );
+ error:
+ ExitProcess( GetLastError() );
+}
+
+
+/***********************************************************************
* PROCESS_Start
*
* Startup routine of a new process. Called in the context of the new process.
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 16ede62..046ae04 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -119,7 +119,7 @@
*
* Allocate the stack of a thread.
*/
-static TEB *THREAD_InitStack( TEB *teb, PDB *pdb, DWORD stack_size, BOOL alloc_stack16 )
+TEB *THREAD_InitStack( TEB *teb, PDB *pdb, DWORD stack_size, BOOL alloc_stack16 )
{
DWORD old_prot, total_size;
DWORD page_size = VIRTUAL_GetPageSize();
diff --git a/tools/build.c b/tools/build.c
index 838a1a7..4bd1cd8 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -733,6 +733,8 @@
fatal_error( "init cannot be used for Win16 spec files\n" );
if (!DLLInitFunc[0])
fatal_error( "Expected function name after init\n" );
+ if (!strcmp(DLLInitFunc, "main"))
+ fatal_error( "The init function cannot be named 'main'\n" );
}
else if (strcmp(token, "import") == 0)
{
@@ -1033,6 +1035,7 @@
ORDDEF *odp;
int i, fwd_size = 0, have_regs = FALSE;
int nr_exports;
+ const char *init_func;
AssignOrdinals();
nr_exports = Base <= Limit ? Limit - Base + 1 : 0;
@@ -1040,8 +1043,7 @@
fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n",
input_file_name );
fprintf( outfile, "#include \"builtin32.h\"\n\n" );
- fprintf( outfile, "extern const BUILTIN32_DESCRIPTOR %s_Descriptor;\n",
- DLLName );
+ fprintf( outfile, "static const BUILTIN32_DESCRIPTOR descriptor;\n" );
/* Output the DLL functions prototypes */
@@ -1065,8 +1067,8 @@
have_regs = TRUE;
break;
case TYPE_STUB:
- fprintf( outfile, "static void __stub_%d() { BUILTIN32_Unimplemented(&%s_Descriptor,%d); }\n",
- odp->ordinal, DLLName, odp->ordinal );
+ fprintf( outfile, "static void __stub_%d() { BUILTIN32_Unimplemented(&descriptor,%d); }\n",
+ odp->ordinal, odp->ordinal );
break;
default:
fprintf(stderr,"build: function type %d not available for Win32\n",
@@ -1075,10 +1077,6 @@
}
}
- /* Output LibMain function */
- if (DLLInitFunc[0]) fprintf( outfile, "extern void %s();\n", DLLInitFunc );
-
-
/* Output code for all register functions */
if ( have_regs )
@@ -1230,12 +1228,65 @@
fprintf( outfile, "\n};\n\n" );
}
+ /* Output LibMain function */
+
+ init_func = DLLInitFunc[0] ? DLLInitFunc : NULL;
+ switch(SpecMode)
+ {
+ case SPEC_MODE_DLL:
+ if (init_func) fprintf( outfile, "extern void %s();\n", init_func );
+ break;
+ case SPEC_MODE_GUIEXE:
+ if (!init_func) init_func = "WinMain";
+ fprintf( outfile,
+ "\n#include <winbase.h>\n"
+ "static void exe_main(void)\n"
+ "{\n"
+ " extern int PASCAL %s(HINSTANCE,HINSTANCE,LPCSTR,INT);\n"
+ " STARTUPINFOA info;\n"
+ " const char *cmdline = GetCommandLineA();\n"
+ " while (*cmdline && *cmdline != ' ') cmdline++;\n"
+ " if (*cmdline) cmdline++;\n"
+ " GetStartupInfoA( &info );\n"
+ " if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = 1;\n"
+ " ExitProcess( %s( GetModuleHandleA(0), 0, cmdline, info.wShowWindow ) );\n"
+ "}\n\n", init_func, init_func );
+ fprintf( outfile,
+ "int main( int argc, char *argv[] )\n"
+ "{\n"
+ " extern void PROCESS_InitWinelib( int, char ** );\n"
+ " PROCESS_InitWinelib( argc, argv );\n"
+ " return 1;\n"
+ "}\n\n" );
+ init_func = "exe_main";
+ break;
+ case SPEC_MODE_CUIEXE:
+ if (!init_func) init_func = "wine_main";
+ fprintf( outfile,
+ "\n#include <winbase.h>\n"
+ "static void exe_main(void)\n"
+ "{\n"
+ " extern int %s( int argc, char *argv[] );\n"
+ " extern int _ARGC;\n"
+ " extern char *_ARGV[];\n"
+ " ExitProcess( %s( _ARGC, _ARGV ) );\n"
+ "}\n\n", init_func, init_func );
+ fprintf( outfile,
+ "int main( int argc, char *argv[] )\n"
+ "{\n"
+ " extern void PROCESS_InitWinelib( int, char ** );\n"
+ " PROCESS_InitWinelib( argc, argv );\n"
+ " return 1;\n"
+ "}\n\n" );
+ init_func = "exe_main";
+ break;
+ }
+
/* Output the DLL descriptor */
if (rsrc_name[0]) fprintf( outfile, "extern const char %s[];\n\n", rsrc_name );
- fprintf( outfile, "const BUILTIN32_DESCRIPTOR %s_Descriptor =\n{\n",
- DLLName );
+ fprintf( outfile, "static const BUILTIN32_DESCRIPTOR descriptor =\n{\n" );
fprintf( outfile, " \"%s\",\n", DLLName );
fprintf( outfile, " \"%s\",\n", DLLFileName );
fprintf( outfile, " %d,\n", nr_exports? Base : 0 );
@@ -1249,7 +1300,7 @@
fprintf( outfile, " %s,\n", nr_exports ? "FuncArgs" : "0" );
fprintf( outfile, " %s,\n", nr_exports ? "ArgTypes" : "0" );
fprintf( outfile, " %s,\n", nb_imports ? "Imports" : "0" );
- fprintf( outfile, " %s,\n", DLLInitFunc[0] ? DLLInitFunc : "0" );
+ fprintf( outfile, " %s,\n", init_func ? init_func : "0" );
fprintf( outfile, " %d,\n", SpecMode == SPEC_MODE_DLL ? IMAGE_FILE_DLL : 0 );
fprintf( outfile, " %s\n", rsrc_name[0] ? rsrc_name : "0" );
fprintf( outfile, "};\n" );
@@ -1265,8 +1316,8 @@
fprintf( outfile, " \"\\t.previous\\n\");\n" );
fprintf( outfile, "}\n" );
fprintf( outfile, "#endif /* defined(__GNUC__) */\n" );
- fprintf( outfile, "static void %s_init(void) { BUILTIN32_RegisterDLL( &%s_Descriptor ); }\n",
- DLLName, DLLName );
+ fprintf( outfile, "static void %s_init(void) { BUILTIN32_RegisterDLL( &descriptor ); }\n",
+ DLLName );
return 0;
}
@@ -1508,7 +1559,7 @@
if (rsrc_name[0]) fprintf( outfile, "extern const char %s[];\n\n", rsrc_name );
- fprintf( outfile, "\nconst BUILTIN16_DESCRIPTOR %s_Descriptor = \n{\n", DLLName );
+ fprintf( outfile, "\nstatic const BUILTIN16_DESCRIPTOR descriptor = \n{\n" );
fprintf( outfile, " \"%s\",\n", DLLName );
fprintf( outfile, " Module,\n" );
fprintf( outfile, " sizeof(Module),\n" );
@@ -1528,8 +1579,8 @@
fprintf( outfile, " \"\\t.previous\\n\");\n" );
fprintf( outfile, "}\n" );
fprintf( outfile, "#endif /* defined(__GNUC__) */\n" );
- fprintf( outfile, "static void %s_init(void) { BUILTIN_RegisterDLL( &%s_Descriptor ); }\n",
- DLLName, DLLName );
+ fprintf( outfile, "static void %s_init(void) { BUILTIN_RegisterDLL( &descriptor ); }\n",
+ DLLName );
return 0;
}