Improved Winelib apps initialisation code. No longer need to link

winestub.o with Winelib apps.
This commit is contained in:
Alexandre Julliard 2000-04-15 21:00:55 +00:00
parent f0deb8a17e
commit b44595283f
33 changed files with 337 additions and 169 deletions

View File

@ -30,7 +30,7 @@ X_CFLAGS = @X_CFLAGS@
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 @@ BUILD = $(TOPOBJDIR)/tools/build@PROGEXT@
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 @@ $(MAKEDEP) check_makedep:
$(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

View File

@ -44,7 +44,7 @@ y.tab.c y.tab.h: dbg.y
lex.yy.c: debug.l
$(LEX) -8 -I $(SRCDIR)/debug.l
winedbg: $(OBJS) $(WINESTUB)
winedbg: $(OBJS)
$(CC) -o $@ $(OBJS) $(LDOPTIONS) $(ALL_LIBS)
### Dependencies:

View File

@ -22,6 +22,10 @@ extern int (*IF1632_CallLargeStack)( int (*func)(void), void *arg );
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
{

View File

@ -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 */

View File

@ -184,7 +184,7 @@ extern void MODULE_DllThreadDetach( LPVOID lpReserved );
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 @@ HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD s
/* 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 */

View File

@ -122,6 +122,7 @@ typedef struct _TEB
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 );

View File

@ -22,7 +22,7 @@ SPEC_SRCS = \
RC_SRCS = \
hello3res.rc
all: check_wrc check_winestub $(PROGRAMS)
all: check_wrc $(PROGRAMS)
@MAKE_RULES@

View File

@ -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 @@ BOOL MAIN_MainInit( int argc, char *argv[], BOOL win32 )
/* 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 @@ BOOL WINAPI MAIN_KernelInit(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReser
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,54 +156,19 @@ BOOL WINAPI MAIN_KernelInit(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReser
/* 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)
*

View File

@ -336,7 +336,7 @@ BOOL WINAPI DisableThreadLibraryCalls( HMODULE hModule )
*
* 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 @@ HMODULE MODULE_CreateDummyModule( LPCSTR filename, WORD version )
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);

View File

@ -892,7 +892,6 @@ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags)
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 @@ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags)
}
/* 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 @@ BOOL PE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR en
#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,

View File

@ -22,6 +22,11 @@ struct option
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 @@ void OPTIONS_ParseOptions( int argc, char *argv[] )
}
Options.argc = argc;
Options.argv = argv;
_ARGC = argc;
_ARGV = argv;
}

View File

@ -13,7 +13,7 @@ SPEC_SRCS = \
aviinfo.spec \
aviplay.spec
all: check_wrc check_winestub $(PROGRAMS)
all: check_wrc $(PROGRAMS)
@MAKE_RULES@

View File

@ -21,7 +21,7 @@ SPEC_SRCS = clock.spec
RC_SRCS = rsrc.rc
all: check_wrc check_winestub $(PROGRAMS)
all: check_wrc $(PROGRAMS)
@MAKE_RULES@

View File

@ -17,7 +17,7 @@ SPEC_SRCS = \
RC_SRCS = \
cmdlgr.rc
all: check_wrc check_winestub $(PROGRAMS)
all: check_wrc $(PROGRAMS)
@MAKE_RULES@

View File

@ -11,7 +11,7 @@ C_SRCS = control.c
SPEC_SRCS = control.spec
all: check_winestub $(PROGRAMS)
all: $(PROGRAMS)
@MAKE_RULES@

View File

@ -22,7 +22,7 @@ SPEC_SRCS = notepad.spec
RC_SRCS = rsrc.rc
all: check_wrc check_winestub $(PROGRAMS)
all: check_wrc $(PROGRAMS)
@MAKE_RULES@

View File

@ -15,9 +15,6 @@ all: $(PROGRAMS)
@MAKE_RULES@
#this line is needed to prevent winestub.o being linked
WINESTUB =
osversioncheck: $(OBJS)
$(CC) -o osversioncheck $(OBJS) $(LDOPTIONS) $(ALL_LIBS)

View File

@ -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 @@ show_last_error(void)
}
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

View File

@ -1,4 +1,4 @@
name osversioncheck
mode cuiexe
type win32
init main
init wine_main

View File

@ -24,7 +24,7 @@ SPEC_SRCS = progman.spec
RC_SRCS = rsrc.rc
all: check_wrc check_winestub $(PROGRAMS)
all: check_wrc $(PROGRAMS)
@MAKE_RULES@

View File

@ -13,7 +13,7 @@ C_SRCS = \
SPEC_SRCS = \
regapi.spec
all: check_winestub $(PROGRAMS)
all: $(PROGRAMS)
@MAKE_RULES@

View File

@ -11,7 +11,7 @@ C_SRCS = regtest.c
SPEC_SRCS = regtest.spec
all: check_winestub $(PROGRAMS)
all: $(PROGRAMS)
@MAKE_RULES@

View File

@ -19,7 +19,7 @@ SPEC_SRCS = \
RC_SRCS = \
viewrc.rc
all: check_wrc check_winestub $(PROGRAMS)
all: check_wrc $(PROGRAMS)
@MAKE_RULES@

View File

@ -24,9 +24,6 @@ all: check_wrc $(PROGRAMS)
@MAKE_RULES@
#this line is needed to prevent winestub.o being linked
WINESTUB =
wcmd: $(OBJS)
$(CC) -o wcmd $(OBJS) $(LDOPTIONS) $(ALL_LIBS)

View File

@ -1,4 +1,4 @@
name wcmd
mode cuiexe
type win32
init main
init wine_main

View File

@ -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 @@ BATCH_CONTEXT *context = NULL;
*/
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++) {

View File

@ -19,7 +19,7 @@ SPEC_SRCS = winemine.spec
RC_SRCS = rsrc.rc
all: check_wrc check_winestub $(PROGRAMS)
all: check_wrc $(PROGRAMS)
@MAKE_RULES@

View File

@ -21,7 +21,7 @@ EXTRA_OBJS = y.tab.o lex.yy.o
RC_SRCS = rsrc.rc
all: check_wrc check_winestub $(PROGRAMS)
all: check_wrc $(PROGRAMS)
depend: y.tab.h

View File

@ -11,7 +11,7 @@ C_SRCS = winver.c
SPEC_SRCS = winver.spec
all: check_winestub $(PROGRAMS)
all: $(PROGRAMS)
@MAKE_RULES@

View File

@ -385,15 +385,13 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags)
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 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags)
/***********************************************************************
* BUILTIN32_LoadExeModule
*/
HMODULE16 BUILTIN32_LoadExeModule( void )
HMODULE BUILTIN32_LoadExeModule( LPCSTR *filename )
{
HMODULE16 hModule16;
NE_MODULE *pModule;
@ -449,14 +447,8 @@ HMODULE16 BUILTIN32_LoadExeModule( void )
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];
}

View File

@ -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 @@ static PDB *PROCESS_CreatePDB( PDB *parent, BOOL inherit )
*/
BOOL PROCESS_Init( BOOL win32 )
{
struct init_process_request *req;
TEB *teb;
int server_fd;
@ -308,11 +313,13 @@ BOOL PROCESS_Init( BOOL win32 )
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,19 +345,208 @@ BOOL PROCESS_Init( BOOL win32 )
/* 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
*

View File

@ -119,7 +119,7 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb )
*
* 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();

View File

@ -733,6 +733,8 @@ static void ParseTopLevel(void)
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 @@ static int BuildSpec32File( FILE *outfile )
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 @@ static int BuildSpec32File( FILE *outfile )
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 @@ static int BuildSpec32File( FILE *outfile )
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 @@ static int BuildSpec32File( FILE *outfile )
}
}
/* 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 @@ static int BuildSpec32File( FILE *outfile )
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 @@ static int BuildSpec32File( FILE *outfile )
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 @@ static int BuildSpec32File( FILE *outfile )
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 @@ static int BuildSpec16File( FILE *outfile )
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 @@ static int BuildSpec16File( FILE *outfile )
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;
}