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

On NE process creation, move major part of NE EXE module loading and

NE instance creation into the child process.
parent 3922ca74
......@@ -202,11 +202,12 @@ extern FARPROC16 NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal );
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 HINSTANCE16 MODULE_LoadModule16( LPCSTR name, BOOL implicit );
extern BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info );
extern BOOL NE_InitProcess( NE_MODULE *pModule );
/* loader/ne/resource.c */
extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16);
......
......@@ -95,8 +95,6 @@ typedef struct _PDB
HANDLE *dos_handles; /* Handles mapping DOS -> Win32 */
struct _PDB *next; /* List reference - list of PDB's */
WORD winver; /* Windows version figured out by VERSION_GetVersion */
WORD hInstance; /* hInstance on startup */
WORD hPrevInstance; /* hPrevInstance on startup */
struct _SERVICETABLE *service_table; /* Service table for service thread */
} PDB;
......@@ -161,7 +159,6 @@ extern PDB *PROCESS_IdToPDB( DWORD id );
extern void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule );
extern PDB *PROCESS_Create( struct _NE_MODULE *pModule,
LPCSTR cmd_line, LPCSTR env,
HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
BOOL inherit, DWORD flags,
STARTUPINFOA *startup, PROCESS_INFORMATION *info );
......
......@@ -146,9 +146,7 @@ typedef struct _THHOOK
extern THHOOK *pThhook;
extern void (*TASK_AddTaskEntryBreakpoint)( HTASK16 hTask );
extern BOOL TASK_Create( struct _NE_MODULE *pModule,
HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
UINT16 cmdShow );
extern BOOL TASK_Create( struct _NE_MODULE *pModule, UINT16 cmdShow );
extern void TASK_KillTask( HTASK16 hTask );
extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
extern void TASK_Reschedule(void);
......
......@@ -498,7 +498,7 @@ BOOL MZ_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, LPCSTR env,
return FALSE;
}
inherit = TRUE; /* bad hack for inheriting the CreatePipe... */
if (!PROCESS_Create( pModule, cmdline, env, 0, 0,
if (!PROCESS_Create( pModule, cmdline, env,
psa, tsa, inherit, flags, startup, info ))
return FALSE;
}
......
......@@ -309,7 +309,7 @@ HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] )
pModule->flags = NE_FFLAGS_WIN32;
pModule->module32 = wm->module;
if (!TASK_Create( pModule, 0, 0, FALSE )) return 0;
if (!TASK_Create( pModule, FALSE )) return 0;
/* Initialize GDI and USER */
if (!LoadLibraryA( "GDI32.DLL" )) return 0;
......
......@@ -45,6 +45,8 @@ static HMODULE16 NE_LoadBuiltin(LPCSTR name,BOOL force) { return 0; }
HMODULE16 (*fnBUILTIN_LoadModule)(LPCSTR name,BOOL force) = NE_LoadBuiltin;
static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep );
static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only );
/***********************************************************************
* NE_GetPtr
*/
......@@ -758,7 +760,7 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
/* its handle in the list of DLLs to initialize. */
HMODULE16 hDLL;
if ((hDLL = MODULE_LoadModule16( buffer, TRUE )) < 32)
if ((hDLL = MODULE_LoadModule16( buffer, TRUE, TRUE )) < 32)
{
/* FIXME: cleanup what was done */
......@@ -783,31 +785,24 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
/**********************************************************************
* NE_LoadFileModule
* NE_DoLoadModule
*
* Load first instance of NE module from file.
* (Note: caller is responsible for ensuring the module isn't
* already loaded!)
*
* pModule must point to a module structure prepared by NE_LoadExeHeader.
* This routine must never be called twice on a module.
*
*/
static HINSTANCE16 NE_LoadFileModule( HFILE16 hFile, OFSTRUCT *ofs,
BOOL implicit )
static HINSTANCE16 NE_DoLoadModule( NE_MODULE *pModule )
{
HINSTANCE16 hInstance;
HMODULE16 hModule;
NE_MODULE *pModule;
/* Create the module structure */
hModule = NE_LoadExeHeader( hFile, ofs );
if (hModule < 32) return hModule;
pModule = NE_GetPtr( hModule );
/* Allocate the segments for this module */
if (!NE_CreateSegments( pModule ) ||
!(hInstance = NE_CreateInstance( pModule, NULL, FALSE )))
{
GlobalFreeAll16( hModule );
GlobalFreeAll16( pModule->self );
return 8; /* Insufficient memory */
}
......@@ -815,7 +810,7 @@ static HINSTANCE16 NE_LoadFileModule( HFILE16 hFile, OFSTRUCT *ofs,
if (!NE_LoadDLLs( pModule ))
{
NE_FreeModule(hModule,0);
NE_FreeModule( pModule->self, 0 );
return 2;
}
......@@ -838,14 +833,22 @@ static HINSTANCE16 NE_LoadFileModule( HFILE16 hFile, OFSTRUCT *ofs,
/**********************************************************************
* NE_LoadModule
*
* Load first instance of NE module, deciding whether to use
* built-in module or load module from file.
* (Note: caller is responsible for ensuring the module isn't
* already loaded!)
* Load first instance of NE module. (Note: caller is responsible for
* ensuring the module isn't already loaded!)
*
* If the module turns out to be an executable module, only a
* handle to a module stub is returned; this needs to be initialized
* by calling NE_DoLoadModule later, in the context of the newly
* created process.
*
* If lib_only is TRUE, however, the module is perforce treated
* like a DLL module, even if it is an executable module.
*
*/
HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL implicit )
HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL implicit, BOOL lib_only )
{
HINSTANCE16 hInstance;
NE_MODULE *pModule;
HMODULE16 hModule;
HFILE16 hFile;
OFSTRUCT ofs;
......@@ -863,10 +866,17 @@ HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL implicit )
}
}
hInstance = NE_LoadFileModule( hFile, &ofs, implicit );
hModule = NE_LoadExeHeader( hFile, &ofs );
_lclose16( hFile );
return hInstance;
if (hModule < 32) return hModule;
pModule = NE_GetPtr( hModule );
if ( !pModule ) return hModule;
if ( !lib_only && !( pModule->flags & NE_FFLAGS_LIBMODULE ) )
return hModule;
return NE_DoLoadModule( pModule );
}
......@@ -877,7 +887,7 @@ HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL implicit )
* The caller is responsible that the module is not loaded already.
*
*/
HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit )
static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only )
{
HINSTANCE16 hinst;
int i;
......@@ -891,7 +901,7 @@ HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit )
{
case MODULE_LOADORDER_DLL:
TRACE("Trying native dll '%s'\n", libname);
hinst = NE_LoadModule(libname, implicit);
hinst = NE_LoadModule(libname, implicit, lib_only);
break;
case MODULE_LOADORDER_ELFDLL:
......@@ -970,7 +980,6 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
LPCVOID env = NULL;
STARTUPINFOA startup;
PROCESS_INFORMATION info;
HINSTANCE16 hInstance, hPrevInstance = 0;
HMODULE16 hModule;
NE_MODULE *pModule;
PDB *pdb;
......@@ -984,31 +993,46 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
if ( !( pModule = NE_GetPtr( hModule ) ) ) return (HINSTANCE16)11;
if ( pModule->module32 ) return (HINSTANCE16)21;
hInstance = NE_CreateInstance( pModule, &hPrevInstance, lib_only );
if ( hInstance != hPrevInstance ) /* not a library */
NE_LoadSegment( pModule, pModule->dgroup );
/* Increment refcount */
pModule->count++;
/* If library module, we just retrieve the instance handle */
if ( ( pModule->flags & NE_FFLAGS_LIBMODULE ) || lib_only )
return NE_CreateInstance( pModule, NULL, TRUE );
}
else
{
/* Main case: load first instance of NE module */
if ( (hInstance = MODULE_LoadModule16( name, FALSE )) < 32 )
return hInstance;
if ( (hModule = MODULE_LoadModule16( name, FALSE, lib_only )) < 32 )
return hModule;
if ( !(pModule = NE_GetPtr( hInstance )) )
if ( !(pModule = NE_GetPtr( hModule )) )
return (HINSTANCE16)11;
}
/* If library module, we're finished */
if ( ( pModule->flags & NE_FFLAGS_LIBMODULE ) || lib_only )
return hInstance;
return hModule;
}
/* Create a task for this instance */
pModule->flags |= NE_FFLAGS_GUI; /* FIXME: is this necessary? */
/*
* At this point, we need to create a new process.
*
* pModule points either to an already loaded module, whose refcount
* has already been incremented (to avoid having the module vanish
* in the meantime), or else to a stub module which contains only header
* information.
*
* All remaining initialization (really loading the module in the second
* case, and creating the new instance in both cases) are to be done in
* the context of the new process. This happens in the NE_InitProcess
* routine, which will be called from the 32-bit process initialization.
*/
params = (LOADPARAMS16 *)paramBlock;
cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
......@@ -1035,7 +1059,6 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
SYSLEVEL_ReleaseWin16Lock();
pdb = PROCESS_Create( pModule, new_cmd_line, env,
hInstance, hPrevInstance,
NULL, NULL, TRUE, 0, &startup, &info );
SYSLEVEL_RestoreWin16Lock();
......@@ -1044,7 +1067,8 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
if (params->hEnvironment) GlobalUnlock16( params->hEnvironment );
HeapFree( GetProcessHeap(), 0, new_cmd_line );
return hInstance;
return GetProcessDword( info.dwProcessId, GPD_HINSTANCE16 );
}
/**********************************************************************
......@@ -1055,11 +1079,12 @@ BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env,
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info )
{
HINSTANCE16 hInstance, hPrevInstance = 0;
HMODULE16 hModule;
NE_MODULE *pModule;
HFILE16 hFile16;
SYSLEVEL_EnterWin16Lock();
/* Special case: second instance of an already loaded NE module */
if ( ( hModule = GetModuleHandle16( ofs->szPathName ) ) != 0 )
......@@ -1069,13 +1094,9 @@ BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env,
|| pModule->module32 )
{
SetLastError( ERROR_BAD_FORMAT );
return FALSE;
goto error;
}
hInstance = NE_CreateInstance( pModule, &hPrevInstance, FALSE );
if ( hInstance != hPrevInstance ) /* not a library */
NE_LoadSegment( pModule, pModule->dgroup );
pModule->count++;
}
......@@ -1085,7 +1106,7 @@ BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env,
/* If we didn't get a file handle, return */
if ( hFile == HFILE_ERROR )
return FALSE;
goto error;
/* Allocate temporary HFILE16 for NE_LoadFileModule */
......@@ -1094,40 +1115,98 @@ BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env,
0, FALSE, DUPLICATE_SAME_ACCESS ))
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
goto error;
}
hFile16 = FILE_AllocDosHandle( hFile );
/* Load module */
hInstance = NE_LoadFileModule( hFile16, ofs, TRUE );
hModule = NE_LoadExeHeader( hFile16, ofs );
_lclose16( hFile16 );
if ( hInstance < 32 )
if ( hModule < 32 )
{
SetLastError( hInstance );
return FALSE;
SetLastError( hModule );
goto error;
}
if ( !( pModule = NE_GetPtr( hInstance ) )
if ( !( pModule = NE_GetPtr( hModule ) )
|| ( pModule->flags & NE_FFLAGS_LIBMODULE) )
{
/* FIXME: cleanup */
GlobalFreeAll16( hModule );
SetLastError( ERROR_BAD_FORMAT );
return FALSE;
goto error;
}
}
/* Create a task for this instance */
pModule->flags |= NE_FFLAGS_GUI; /* FIXME: is this necessary? */
SYSLEVEL_LeaveWin16Lock();
if ( !PROCESS_Create( pModule, cmd_line, env,
hInstance, hPrevInstance,
psa, tsa, inherit, flags, startup, info ) )
return FALSE;
return TRUE;
error:
SYSLEVEL_LeaveWin16Lock();
return FALSE;
}
/**********************************************************************
* NE_InitProcess
*/
BOOL NE_InitProcess( NE_MODULE *pModule )
{
HINSTANCE16 hInstance, hPrevInstance;
BOOL retv = TRUE;
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
WORD sp;
TDB *pTask;
SYSLEVEL_EnterWin16Lock();
if ( pModule->count > 0 )
{
/* Second instance of an already loaded NE module */
/* Note that the refcount was already incremented by the parent */
hInstance = NE_CreateInstance( pModule, &hPrevInstance, FALSE );
if ( hInstance != hPrevInstance ) /* not a library */
NE_LoadSegment( pModule, pModule->dgroup );
}
else
{
/* Load first instance of NE module */
pModule->flags |= NE_FFLAGS_GUI; /* FIXME: is this necessary? */
hInstance = NE_DoLoadModule( pModule );
hPrevInstance = 0;
if ( hInstance < 32 )
{
SetLastError( hInstance );
retv = FALSE;
}
}
/* Enter instance handles into task struct */
pTask = (TDB *)GlobalLock16( GetCurrentTask() );
pTask->hInstance = hInstance;
pTask->hPrevInstance = hPrevInstance;
/* Use DGROUP for 16-bit stack */
if (!(sp = pModule->sp))
sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
sp &= ~1; sp -= sizeof(STACK16FRAME);
pTask->teb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( hInstance, sp );
SYSLEVEL_LeaveWin16Lock();
return retv;
}
/***********************************************************************
......
......@@ -984,7 +984,7 @@ BOOL PE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env,
/* Create new process */
if ( !PROCESS_Create( pModule, cmd_line, env,
0, 0, psa, tsa, inherit, flags, startup, info ) )
psa, tsa, inherit, flags, startup, info ) )
return FALSE;
/* Note: PE_CreateModule and the remaining process initialization will
......
......@@ -275,16 +275,13 @@ void TASK_CallToStart(void)
* by entering the Win16Lock while linking the task into the
* global task list.
*/
BOOL TASK_Create( NE_MODULE *pModule, HINSTANCE16 hInstance,
HINSTANCE16 hPrevInstance, UINT16 cmdShow)
BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow)
{
HTASK16 hTask;
TDB *pTask;
LPSTR cmd_line;
WORD sp;
char name[10];
PDB *pdb32 = PROCESS_Current();
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
/* Allocate the task structure */
......@@ -304,9 +301,12 @@ BOOL TASK_Create( NE_MODULE *pModule, HINSTANCE16 hInstance,
if (pModule->lpDosTask)
pTask->flags |= TDBF_WINOLDAP;
pTask->hInstance = pModule->self;
pTask->hPrevInstance = 0;
/* NOTE: for 16-bit tasks, the instance handles are updated later on
in NE_InitProcess */
pTask->version = pModule->expected_version;
pTask->hInstance = hInstance? hInstance : pModule->self;
pTask->hPrevInstance = hPrevInstance;
pTask->hModule = pModule->self;
pTask->hParent = GetCurrentTask();
pTask->magic = TDB_MAGIC;
......@@ -388,16 +388,6 @@ BOOL TASK_Create( NE_MODULE *pModule, HINSTANCE16 hInstance,
pTask->teb->htask16 = pTask->teb->process->task = hTask;
TRACE_(task)("module='%s' cmdline='%s' task=%04x\n", name, cmd_line, hTask );
/* If we have a DGROUP/hInstance, use it for 16-bit stack */
if ( hInstance )
{
if (!(sp = pModule->sp))
sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
sp &= ~1; sp -= sizeof(STACK16FRAME);
pTask->teb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( hInstance, sp );
}
/* If requested, add entry point breakpoint */
if ( TASK_AddTaskEntryBreakpoint )
......
......@@ -168,7 +168,7 @@ int main( int argc, char *argv[] )
/* Create initial task */
if ( !(pModule = NE_GetPtr( GetModuleHandle16( "KERNEL" ) )) ) return 1;
if ( !TASK_Create( pModule, 0, 0, FALSE ) ) return 1;
if ( !TASK_Create( pModule, FALSE ) ) return 1;
/* Switch to initial task */
PostEvent16( PROCESS_Current()->task );
......
......@@ -411,7 +411,12 @@ void PROCESS_Start(void)
/* Create a task for this process */
if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW)
cmdShow = pdb->env_db->startup_info->wShowWindow;
if (!TASK_Create( pModule, pdb->hInstance, pdb->hPrevInstance, cmdShow ))
if (!TASK_Create( pModule, cmdShow ))
goto error;
/* Perform Win16 specific process initialization */
if ( type == PROC_WIN16 )
if ( !NE_InitProcess( pModule ) )
goto error;
/* Note: The USIG_PROCESS_CREATE signal is supposed to be sent in the
......@@ -502,13 +507,13 @@ void PROCESS_Start(void)
* Create a new process database and associated info.
*/
PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
BOOL inherit, DWORD flags, STARTUPINFOA *startup,
PROCESS_INFORMATION *info )
{
HANDLE handles[2], load_done_evt = INVALID_HANDLE_VALUE;
DWORD exitcode, size;
BOOL alloc_stack16;
int server_thandle;
struct new_process_request *req = get_req_buffer();
TEB *teb = NULL;
......@@ -554,21 +559,24 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
size = header->SizeOfStackReserve;
if (header->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
pdb->flags |= PDB32_CONSOLE_PROC;
alloc_stack16 = TRUE;
}
else if (!pModule->dos_image) /* Win16 process */
{
alloc_stack16 = FALSE;
size = 0;
pdb->flags |= PDB32_WIN16_PROC;
}
else /* DOS process */
{
alloc_stack16 = FALSE;
size = 0;
pdb->flags |= PDB32_DOS_PROC;
}
/* Create the main thread */
if (!(teb = THREAD_Create( pdb, 0L, size, hInstance == 0, tsa, &server_thandle )))
if (!(teb = THREAD_Create( pdb, 0L, size, alloc_stack16, tsa, &server_thandle )))
goto error;
info->hThread = server_thandle;
info->dwThreadId = (DWORD)teb->tid;
......@@ -579,10 +587,8 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
DuplicateHandle( GetCurrentProcess(), load_done_evt,
info->hProcess, &pdb->load_done_evt, 0, TRUE, DUPLICATE_SAME_ACCESS );
/* Pass module/instance to new process (FIXME: hack) */
/* Pass module to new process (FIXME: hack) */
pdb->module = pModule->self;
pdb->hInstance = hInstance;
pdb->hPrevInstance = hPrevInstance;
SYSDEPS_SpawnThread( teb );
/* Wait until process is initialized (or initialization failed) */
......
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