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

NE instance creation into the child process.
This commit is contained in:
Ulrich Weigand 1999-07-03 12:26:29 +00:00 committed by Alexandre Julliard
parent 3922ca74fa
commit fbea530884
10 changed files with 167 additions and 96 deletions

View File

@ -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);

View File

@ -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 );

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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,41 +785,34 @@ 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 */
}
/* Load the referenced DLLs */
if (!NE_LoadDLLs( pModule ))
{
NE_FreeModule(hModule,0);
{
NE_FreeModule( pModule->self, 0 );
return 2;
}
}
/* Load the segments */
@ -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 hModule;
}
/* If library module, we're finished */
if ( ( pModule->flags & NE_FFLAGS_LIBMODULE ) || lib_only )
return hInstance;
/*
* 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.
*/
/* Create a task for this instance */
pModule->flags |= NE_FFLAGS_GUI; /* FIXME: is this necessary? */
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,22 +1067,24 @@ 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 );
}
/**********************************************************************
* NE_CreateProcess
*/
BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env,
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 )
{
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;
}
/***********************************************************************

View File

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

View File

@ -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 )

View File

@ -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 );

View File

@ -411,9 +411,14 @@ 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
* context of the parent process. Actually, the USER signal proc
* doesn't really care about that, but it *does* require that 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) */