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:
parent
3922ca74fa
commit
fbea530884
|
@ -202,11 +202,12 @@ extern FARPROC16 NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal );
|
||||||
extern FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop );
|
extern FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop );
|
||||||
extern BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset );
|
extern BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset );
|
||||||
extern HANDLE NE_OpenFile( NE_MODULE *pModule );
|
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,
|
extern BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env,
|
||||||
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
|
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
|
||||||
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
|
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
|
||||||
LPPROCESS_INFORMATION info );
|
LPPROCESS_INFORMATION info );
|
||||||
|
extern BOOL NE_InitProcess( NE_MODULE *pModule );
|
||||||
|
|
||||||
|
|
||||||
/* loader/ne/resource.c */
|
/* loader/ne/resource.c */
|
||||||
extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16);
|
extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16);
|
||||||
|
|
|
@ -95,8 +95,6 @@ typedef struct _PDB
|
||||||
HANDLE *dos_handles; /* Handles mapping DOS -> Win32 */
|
HANDLE *dos_handles; /* Handles mapping DOS -> Win32 */
|
||||||
struct _PDB *next; /* List reference - list of PDB's */
|
struct _PDB *next; /* List reference - list of PDB's */
|
||||||
WORD winver; /* Windows version figured out by VERSION_GetVersion */
|
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 */
|
struct _SERVICETABLE *service_table; /* Service table for service thread */
|
||||||
} PDB;
|
} PDB;
|
||||||
|
|
||||||
|
@ -161,7 +159,6 @@ extern PDB *PROCESS_IdToPDB( DWORD id );
|
||||||
extern void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule );
|
extern void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule );
|
||||||
extern PDB *PROCESS_Create( struct _NE_MODULE *pModule,
|
extern PDB *PROCESS_Create( struct _NE_MODULE *pModule,
|
||||||
LPCSTR cmd_line, LPCSTR env,
|
LPCSTR cmd_line, LPCSTR env,
|
||||||
HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
|
|
||||||
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
|
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
|
||||||
BOOL inherit, DWORD flags,
|
BOOL inherit, DWORD flags,
|
||||||
STARTUPINFOA *startup, PROCESS_INFORMATION *info );
|
STARTUPINFOA *startup, PROCESS_INFORMATION *info );
|
||||||
|
|
|
@ -146,9 +146,7 @@ typedef struct _THHOOK
|
||||||
extern THHOOK *pThhook;
|
extern THHOOK *pThhook;
|
||||||
extern void (*TASK_AddTaskEntryBreakpoint)( HTASK16 hTask );
|
extern void (*TASK_AddTaskEntryBreakpoint)( HTASK16 hTask );
|
||||||
|
|
||||||
extern BOOL TASK_Create( struct _NE_MODULE *pModule,
|
extern BOOL TASK_Create( struct _NE_MODULE *pModule, UINT16 cmdShow );
|
||||||
HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
|
|
||||||
UINT16 cmdShow );
|
|
||||||
extern void TASK_KillTask( HTASK16 hTask );
|
extern void TASK_KillTask( HTASK16 hTask );
|
||||||
extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
|
extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
|
||||||
extern void TASK_Reschedule(void);
|
extern void TASK_Reschedule(void);
|
||||||
|
|
|
@ -498,7 +498,7 @@ BOOL MZ_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline, LPCSTR env,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
inherit = TRUE; /* bad hack for inheriting the CreatePipe... */
|
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 ))
|
psa, tsa, inherit, flags, startup, info ))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,7 +309,7 @@ HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] )
|
||||||
pModule->flags = NE_FFLAGS_WIN32;
|
pModule->flags = NE_FFLAGS_WIN32;
|
||||||
pModule->module32 = wm->module;
|
pModule->module32 = wm->module;
|
||||||
|
|
||||||
if (!TASK_Create( pModule, 0, 0, FALSE )) return 0;
|
if (!TASK_Create( pModule, FALSE )) return 0;
|
||||||
|
|
||||||
/* Initialize GDI and USER */
|
/* Initialize GDI and USER */
|
||||||
if (!LoadLibraryA( "GDI32.DLL" )) return 0;
|
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;
|
HMODULE16 (*fnBUILTIN_LoadModule)(LPCSTR name,BOOL force) = NE_LoadBuiltin;
|
||||||
static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep );
|
static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep );
|
||||||
|
|
||||||
|
static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only );
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* NE_GetPtr
|
* NE_GetPtr
|
||||||
*/
|
*/
|
||||||
|
@ -758,7 +760,7 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
|
||||||
/* its handle in the list of DLLs to initialize. */
|
/* its handle in the list of DLLs to initialize. */
|
||||||
HMODULE16 hDLL;
|
HMODULE16 hDLL;
|
||||||
|
|
||||||
if ((hDLL = MODULE_LoadModule16( buffer, TRUE )) < 32)
|
if ((hDLL = MODULE_LoadModule16( buffer, TRUE, TRUE )) < 32)
|
||||||
{
|
{
|
||||||
/* FIXME: cleanup what was done */
|
/* 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.
|
* 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,
|
static HINSTANCE16 NE_DoLoadModule( NE_MODULE *pModule )
|
||||||
BOOL implicit )
|
|
||||||
{
|
{
|
||||||
HINSTANCE16 hInstance;
|
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 */
|
/* Allocate the segments for this module */
|
||||||
|
|
||||||
if (!NE_CreateSegments( pModule ) ||
|
if (!NE_CreateSegments( pModule ) ||
|
||||||
!(hInstance = NE_CreateInstance( pModule, NULL, FALSE )))
|
!(hInstance = NE_CreateInstance( pModule, NULL, FALSE )))
|
||||||
{
|
{
|
||||||
GlobalFreeAll16( hModule );
|
GlobalFreeAll16( pModule->self );
|
||||||
return 8; /* Insufficient memory */
|
return 8; /* Insufficient memory */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the referenced DLLs */
|
/* Load the referenced DLLs */
|
||||||
|
|
||||||
if (!NE_LoadDLLs( pModule ))
|
if (!NE_LoadDLLs( pModule ))
|
||||||
{
|
{
|
||||||
NE_FreeModule(hModule,0);
|
NE_FreeModule( pModule->self, 0 );
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the segments */
|
/* Load the segments */
|
||||||
|
|
||||||
|
@ -838,14 +833,22 @@ static HINSTANCE16 NE_LoadFileModule( HFILE16 hFile, OFSTRUCT *ofs,
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* NE_LoadModule
|
* NE_LoadModule
|
||||||
*
|
*
|
||||||
* Load first instance of NE module, deciding whether to use
|
* Load first instance of NE module. (Note: caller is responsible for
|
||||||
* built-in module or load module from file.
|
* ensuring the module isn't already loaded!)
|
||||||
* (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;
|
HFILE16 hFile;
|
||||||
OFSTRUCT ofs;
|
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 );
|
_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.
|
* 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;
|
HINSTANCE16 hinst;
|
||||||
int i;
|
int i;
|
||||||
|
@ -891,7 +901,7 @@ HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit )
|
||||||
{
|
{
|
||||||
case MODULE_LOADORDER_DLL:
|
case MODULE_LOADORDER_DLL:
|
||||||
TRACE("Trying native dll '%s'\n", libname);
|
TRACE("Trying native dll '%s'\n", libname);
|
||||||
hinst = NE_LoadModule(libname, implicit);
|
hinst = NE_LoadModule(libname, implicit, lib_only);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MODULE_LOADORDER_ELFDLL:
|
case MODULE_LOADORDER_ELFDLL:
|
||||||
|
@ -970,7 +980,6 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
||||||
LPCVOID env = NULL;
|
LPCVOID env = NULL;
|
||||||
STARTUPINFOA startup;
|
STARTUPINFOA startup;
|
||||||
PROCESS_INFORMATION info;
|
PROCESS_INFORMATION info;
|
||||||
HINSTANCE16 hInstance, hPrevInstance = 0;
|
|
||||||
HMODULE16 hModule;
|
HMODULE16 hModule;
|
||||||
NE_MODULE *pModule;
|
NE_MODULE *pModule;
|
||||||
PDB *pdb;
|
PDB *pdb;
|
||||||
|
@ -984,31 +993,46 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
||||||
if ( !( pModule = NE_GetPtr( hModule ) ) ) return (HINSTANCE16)11;
|
if ( !( pModule = NE_GetPtr( hModule ) ) ) return (HINSTANCE16)11;
|
||||||
if ( pModule->module32 ) return (HINSTANCE16)21;
|
if ( pModule->module32 ) return (HINSTANCE16)21;
|
||||||
|
|
||||||
hInstance = NE_CreateInstance( pModule, &hPrevInstance, lib_only );
|
/* Increment refcount */
|
||||||
if ( hInstance != hPrevInstance ) /* not a library */
|
|
||||||
NE_LoadSegment( pModule, pModule->dgroup );
|
|
||||||
|
|
||||||
pModule->count++;
|
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
|
else
|
||||||
{
|
{
|
||||||
/* Main case: load first instance of NE module */
|
/* Main case: load first instance of NE module */
|
||||||
|
|
||||||
if ( (hInstance = MODULE_LoadModule16( name, FALSE )) < 32 )
|
if ( (hModule = MODULE_LoadModule16( name, FALSE, lib_only )) < 32 )
|
||||||
return hInstance;
|
return hModule;
|
||||||
|
|
||||||
if ( !(pModule = NE_GetPtr( hInstance )) )
|
if ( !(pModule = NE_GetPtr( hModule )) )
|
||||||
return (HINSTANCE16)11;
|
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;
|
params = (LOADPARAMS16 *)paramBlock;
|
||||||
cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
|
cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
|
||||||
|
@ -1035,7 +1059,6 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
||||||
|
|
||||||
SYSLEVEL_ReleaseWin16Lock();
|
SYSLEVEL_ReleaseWin16Lock();
|
||||||
pdb = PROCESS_Create( pModule, new_cmd_line, env,
|
pdb = PROCESS_Create( pModule, new_cmd_line, env,
|
||||||
hInstance, hPrevInstance,
|
|
||||||
NULL, NULL, TRUE, 0, &startup, &info );
|
NULL, NULL, TRUE, 0, &startup, &info );
|
||||||
SYSLEVEL_RestoreWin16Lock();
|
SYSLEVEL_RestoreWin16Lock();
|
||||||
|
|
||||||
|
@ -1044,22 +1067,24 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
||||||
|
|
||||||
if (params->hEnvironment) GlobalUnlock16( params->hEnvironment );
|
if (params->hEnvironment) GlobalUnlock16( params->hEnvironment );
|
||||||
HeapFree( GetProcessHeap(), 0, new_cmd_line );
|
HeapFree( GetProcessHeap(), 0, new_cmd_line );
|
||||||
return hInstance;
|
|
||||||
|
return GetProcessDword( info.dwProcessId, GPD_HINSTANCE16 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* NE_CreateProcess
|
* 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,
|
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
|
||||||
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
|
BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
|
||||||
LPPROCESS_INFORMATION info )
|
LPPROCESS_INFORMATION info )
|
||||||
{
|
{
|
||||||
HINSTANCE16 hInstance, hPrevInstance = 0;
|
|
||||||
HMODULE16 hModule;
|
HMODULE16 hModule;
|
||||||
NE_MODULE *pModule;
|
NE_MODULE *pModule;
|
||||||
HFILE16 hFile16;
|
HFILE16 hFile16;
|
||||||
|
|
||||||
|
SYSLEVEL_EnterWin16Lock();
|
||||||
|
|
||||||
/* Special case: second instance of an already loaded NE module */
|
/* Special case: second instance of an already loaded NE module */
|
||||||
|
|
||||||
if ( ( hModule = GetModuleHandle16( ofs->szPathName ) ) != 0 )
|
if ( ( hModule = GetModuleHandle16( ofs->szPathName ) ) != 0 )
|
||||||
|
@ -1069,13 +1094,9 @@ BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env,
|
||||||
|| pModule->module32 )
|
|| pModule->module32 )
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_BAD_FORMAT );
|
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++;
|
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 we didn't get a file handle, return */
|
||||||
|
|
||||||
if ( hFile == HFILE_ERROR )
|
if ( hFile == HFILE_ERROR )
|
||||||
return FALSE;
|
goto error;
|
||||||
|
|
||||||
/* Allocate temporary HFILE16 for NE_LoadFileModule */
|
/* 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 ))
|
0, FALSE, DUPLICATE_SAME_ACCESS ))
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_INVALID_HANDLE );
|
SetLastError( ERROR_INVALID_HANDLE );
|
||||||
return FALSE;
|
goto error;
|
||||||
}
|
}
|
||||||
hFile16 = FILE_AllocDosHandle( hFile );
|
hFile16 = FILE_AllocDosHandle( hFile );
|
||||||
|
|
||||||
/* Load module */
|
/* Load module */
|
||||||
|
|
||||||
hInstance = NE_LoadFileModule( hFile16, ofs, TRUE );
|
hModule = NE_LoadExeHeader( hFile16, ofs );
|
||||||
_lclose16( hFile16 );
|
_lclose16( hFile16 );
|
||||||
|
|
||||||
if ( hInstance < 32 )
|
if ( hModule < 32 )
|
||||||
{
|
{
|
||||||
SetLastError( hInstance );
|
SetLastError( hModule );
|
||||||
return FALSE;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !( pModule = NE_GetPtr( hInstance ) )
|
if ( !( pModule = NE_GetPtr( hModule ) )
|
||||||
|| ( pModule->flags & NE_FFLAGS_LIBMODULE) )
|
|| ( pModule->flags & NE_FFLAGS_LIBMODULE) )
|
||||||
{
|
{
|
||||||
/* FIXME: cleanup */
|
GlobalFreeAll16( hModule );
|
||||||
SetLastError( ERROR_BAD_FORMAT );
|
SetLastError( ERROR_BAD_FORMAT );
|
||||||
return FALSE;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a task for this instance */
|
SYSLEVEL_LeaveWin16Lock();
|
||||||
|
|
||||||
pModule->flags |= NE_FFLAGS_GUI; /* FIXME: is this necessary? */
|
|
||||||
|
|
||||||
if ( !PROCESS_Create( pModule, cmd_line, env,
|
if ( !PROCESS_Create( pModule, cmd_line, env,
|
||||||
hInstance, hPrevInstance,
|
|
||||||
psa, tsa, inherit, flags, startup, info ) )
|
psa, tsa, inherit, flags, startup, info ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
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 */
|
/* Create new process */
|
||||||
if ( !PROCESS_Create( pModule, cmd_line, env,
|
if ( !PROCESS_Create( pModule, cmd_line, env,
|
||||||
0, 0, psa, tsa, inherit, flags, startup, info ) )
|
psa, tsa, inherit, flags, startup, info ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Note: PE_CreateModule and the remaining process initialization will
|
/* 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
|
* by entering the Win16Lock while linking the task into the
|
||||||
* global task list.
|
* global task list.
|
||||||
*/
|
*/
|
||||||
BOOL TASK_Create( NE_MODULE *pModule, HINSTANCE16 hInstance,
|
BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow)
|
||||||
HINSTANCE16 hPrevInstance, UINT16 cmdShow)
|
|
||||||
{
|
{
|
||||||
HTASK16 hTask;
|
HTASK16 hTask;
|
||||||
TDB *pTask;
|
TDB *pTask;
|
||||||
LPSTR cmd_line;
|
LPSTR cmd_line;
|
||||||
WORD sp;
|
|
||||||
char name[10];
|
char name[10];
|
||||||
PDB *pdb32 = PROCESS_Current();
|
PDB *pdb32 = PROCESS_Current();
|
||||||
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
|
|
||||||
|
|
||||||
/* Allocate the task structure */
|
/* Allocate the task structure */
|
||||||
|
|
||||||
|
@ -304,9 +301,12 @@ BOOL TASK_Create( NE_MODULE *pModule, HINSTANCE16 hInstance,
|
||||||
if (pModule->lpDosTask)
|
if (pModule->lpDosTask)
|
||||||
pTask->flags |= TDBF_WINOLDAP;
|
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->version = pModule->expected_version;
|
||||||
pTask->hInstance = hInstance? hInstance : pModule->self;
|
|
||||||
pTask->hPrevInstance = hPrevInstance;
|
|
||||||
pTask->hModule = pModule->self;
|
pTask->hModule = pModule->self;
|
||||||
pTask->hParent = GetCurrentTask();
|
pTask->hParent = GetCurrentTask();
|
||||||
pTask->magic = TDB_MAGIC;
|
pTask->magic = TDB_MAGIC;
|
||||||
|
@ -388,16 +388,6 @@ BOOL TASK_Create( NE_MODULE *pModule, HINSTANCE16 hInstance,
|
||||||
pTask->teb->htask16 = pTask->teb->process->task = hTask;
|
pTask->teb->htask16 = pTask->teb->process->task = hTask;
|
||||||
TRACE_(task)("module='%s' cmdline='%s' task=%04x\n", name, cmd_line, 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 requested, add entry point breakpoint */
|
||||||
|
|
||||||
if ( TASK_AddTaskEntryBreakpoint )
|
if ( TASK_AddTaskEntryBreakpoint )
|
||||||
|
|
|
@ -168,7 +168,7 @@ int main( int argc, char *argv[] )
|
||||||
|
|
||||||
/* Create initial task */
|
/* Create initial task */
|
||||||
if ( !(pModule = NE_GetPtr( GetModuleHandle16( "KERNEL" ) )) ) return 1;
|
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 */
|
/* Switch to initial task */
|
||||||
PostEvent16( PROCESS_Current()->task );
|
PostEvent16( PROCESS_Current()->task );
|
||||||
|
|
|
@ -411,9 +411,14 @@ void PROCESS_Start(void)
|
||||||
/* Create a task for this process */
|
/* Create a task for this process */
|
||||||
if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW)
|
if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW)
|
||||||
cmdShow = pdb->env_db->startup_info->wShowWindow;
|
cmdShow = pdb->env_db->startup_info->wShowWindow;
|
||||||
if (!TASK_Create( pModule, pdb->hInstance, pdb->hPrevInstance, cmdShow ))
|
if (!TASK_Create( pModule, cmdShow ))
|
||||||
goto error;
|
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
|
/* Note: The USIG_PROCESS_CREATE signal is supposed to be sent in the
|
||||||
* context of the parent process. Actually, the USER signal proc
|
* context of the parent process. Actually, the USER signal proc
|
||||||
* doesn't really care about that, but it *does* require that the
|
* 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.
|
* Create a new process database and associated info.
|
||||||
*/
|
*/
|
||||||
PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
|
PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
|
||||||
HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
|
|
||||||
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
|
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
|
||||||
BOOL inherit, DWORD flags, STARTUPINFOA *startup,
|
BOOL inherit, DWORD flags, STARTUPINFOA *startup,
|
||||||
PROCESS_INFORMATION *info )
|
PROCESS_INFORMATION *info )
|
||||||
{
|
{
|
||||||
HANDLE handles[2], load_done_evt = INVALID_HANDLE_VALUE;
|
HANDLE handles[2], load_done_evt = INVALID_HANDLE_VALUE;
|
||||||
DWORD exitcode, size;
|
DWORD exitcode, size;
|
||||||
|
BOOL alloc_stack16;
|
||||||
int server_thandle;
|
int server_thandle;
|
||||||
struct new_process_request *req = get_req_buffer();
|
struct new_process_request *req = get_req_buffer();
|
||||||
TEB *teb = NULL;
|
TEB *teb = NULL;
|
||||||
|
@ -554,21 +559,24 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
|
||||||
size = header->SizeOfStackReserve;
|
size = header->SizeOfStackReserve;
|
||||||
if (header->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
|
if (header->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
|
||||||
pdb->flags |= PDB32_CONSOLE_PROC;
|
pdb->flags |= PDB32_CONSOLE_PROC;
|
||||||
|
alloc_stack16 = TRUE;
|
||||||
}
|
}
|
||||||
else if (!pModule->dos_image) /* Win16 process */
|
else if (!pModule->dos_image) /* Win16 process */
|
||||||
{
|
{
|
||||||
|
alloc_stack16 = FALSE;
|
||||||
size = 0;
|
size = 0;
|
||||||
pdb->flags |= PDB32_WIN16_PROC;
|
pdb->flags |= PDB32_WIN16_PROC;
|
||||||
}
|
}
|
||||||
else /* DOS process */
|
else /* DOS process */
|
||||||
{
|
{
|
||||||
|
alloc_stack16 = FALSE;
|
||||||
size = 0;
|
size = 0;
|
||||||
pdb->flags |= PDB32_DOS_PROC;
|
pdb->flags |= PDB32_DOS_PROC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the main thread */
|
/* 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;
|
goto error;
|
||||||
info->hThread = server_thandle;
|
info->hThread = server_thandle;
|
||||||
info->dwThreadId = (DWORD)teb->tid;
|
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,
|
DuplicateHandle( GetCurrentProcess(), load_done_evt,
|
||||||
info->hProcess, &pdb->load_done_evt, 0, TRUE, DUPLICATE_SAME_ACCESS );
|
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->module = pModule->self;
|
||||||
pdb->hInstance = hInstance;
|
|
||||||
pdb->hPrevInstance = hPrevInstance;
|
|
||||||
SYSDEPS_SpawnThread( teb );
|
SYSDEPS_SpawnThread( teb );
|
||||||
|
|
||||||
/* Wait until process is initialized (or initialization failed) */
|
/* Wait until process is initialized (or initialization failed) */
|
||||||
|
|
Loading…
Reference in New Issue