Process creation sequence reorganized:

- Removed instance data segment for all but NE modules.
- Check binary type in CreateProcess before loading module.
- Unix process creation moved from WinExec to CreateProcess.
- Bugfix: fill in thdb->teb.htask16 member correctly.
This commit is contained in:
Ulrich Weigand 1999-02-28 11:14:32 +00:00 committed by Alexandre Julliard
parent 38d9ce811d
commit 6e0d38603e
6 changed files with 419 additions and 298 deletions

View file

@ -163,8 +163,10 @@ 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 NE_LoadModule( LPCSTR name, HINSTANCE16 *hPrevInstance,
BOOL implicit, BOOL lib_only );
extern HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL implicit );
extern BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line,
LPCSTR env, BOOL inherit, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info );
/* loader/ne/resource.c */
extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16);

View file

@ -146,9 +146,9 @@ typedef struct _THHOOK
extern THHOOK *pThhook;
extern void (*TASK_AddTaskEntryBreakpoint)( HTASK16 hTask );
extern HTASK16 TASK_Create( struct _THDB *thdb, struct _NE_MODULE *pModule,
HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
UINT16 cmdShow );
extern BOOL TASK_Create( struct _THDB *thdb, struct _NE_MODULE *pModule,
HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance,
UINT16 cmdShow );
extern void TASK_StartTask( HTASK16 hTask );
extern void TASK_KillCurrentTask( INT16 exitCode );
extern HTASK16 TASK_GetNextTask( HTASK16 hTask );

View file

@ -12,6 +12,7 @@
#include <unistd.h>
#include "wine/winuser16.h"
#include "wine/winbase16.h"
#include "windef.h"
#include "winerror.h"
#include "class.h"
#include "file.h"
@ -29,8 +30,6 @@
#include "debug.h"
#include "callback.h"
extern BOOL THREAD_InitDone;
/*************************************************************************
* MODULE32_LookupHMODULE
@ -208,11 +207,11 @@ HMODULE MODULE_CreateDummyModule( const OFSTRUCT *ofs, LPCSTR modName )
pModule->count = 1;
pModule->next = 0;
pModule->flags = 0;
pModule->dgroup = 1;
pModule->dgroup = 0;
pModule->ss = 1;
pModule->cs = 2;
pModule->heap_size = 0xe000;
pModule->stack_size = 0x1000;
pModule->heap_size = 0;
pModule->stack_size = 0;
pModule->seg_count = 2;
pModule->modref_count = 0;
pModule->nrname_size = 0;
@ -226,7 +225,7 @@ HMODULE MODULE_CreateDummyModule( const OFSTRUCT *ofs, LPCSTR modName )
((OFSTRUCT *)(pModule+1))->cBytes = of_size - 1;
pSegment = (SEGTABLEENTRY*)((char*)(pModule + 1) + of_size);
pModule->seg_table = pModule->dgroup_entry = (int)pSegment - (int)pModule;
pModule->seg_table = (int)pSegment - (int)pModule;
/* Data segment */
pSegment->size = 0;
pSegment->flags = NE_SEGFLAGS_DATA;
@ -402,110 +401,316 @@ HMODULE MODULE_FindModule(
return 0;
}
/**********************************************************************
* NE_CreateProcess
/***********************************************************************
* MODULE_GetBinaryType
*
* The GetBinaryType function determines whether a file is executable
* or not and if it is it returns what type of executable it is.
* The type of executable is a property that determines in which
* subsystem an executable file runs under.
*
* Binary types returned:
* SCS_32BIT_BINARY: A Win32 based application
* SCS_DOS_BINARY: An MS-Dos based application
* SCS_WOW_BINARY: A Win16 based application
* SCS_PIF_BINARY: A PIF file that executes an MS-Dos based app
* SCS_POSIX_BINARY: A POSIX based application ( Not implemented )
* SCS_OS216_BINARY: A 16bit OS/2 based application ( Not implemented )
*
* Returns TRUE if the file is an executable in which case
* the value pointed by lpBinaryType is set.
* Returns FALSE if the file is not an executable or if the function fails.
*
* To do so it opens the file and reads in the header information
* if the extended header information is not presend it will
* assume that that the file is a DOS executable.
* If the extended header information is present it will
* determine if the file is an 16 or 32 bit Windows executable
* by check the flags in the header.
*
* Note that .COM and .PIF files are only recognized by their
* file name extension; but Windows does it the same way ...
*/
static HINSTANCE16 NE_CreateProcess( LPCSTR name, LPCSTR cmd_line, LPCSTR env,
BOOL inherit, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info )
static BOOL MODULE_GetBinaryType( HFILE hfile, OFSTRUCT *ofs,
LPDWORD lpBinaryType )
{
HINSTANCE16 hInstance, hPrevInstance;
NE_MODULE *pModule;
IMAGE_DOS_HEADER mz_header;
char magic[4], *ptr;
/* Load module */
hInstance = NE_LoadModule( name, &hPrevInstance, TRUE, FALSE );
if (hInstance < 32) return hInstance;
if ( !(pModule = NE_GetPtr(hInstance))
|| (pModule->flags & NE_FFLAGS_LIBMODULE))
/* Seek to the start of the file and read the DOS header information.
*/
if ( _llseek( hfile, 0, SEEK_SET ) >= 0 &&
_lread( hfile, &mz_header, sizeof(mz_header) ) == sizeof(mz_header) )
{
/* FIXME: cleanup */
return 11;
/* Now that we have the header check the e_magic field
* to see if this is a dos image.
*/
if ( mz_header.e_magic == IMAGE_DOS_SIGNATURE )
{
BOOL lfanewValid = FALSE;
/* We do have a DOS image so we will now try to seek into
* the file by the amount indicated by the field
* "Offset to extended header" and read in the
* "magic" field information at that location.
* This will tell us if there is more header information
* to read or not.
*/
/* But before we do we will make sure that header
* structure encompasses the "Offset to extended header"
* field.
*/
if ( (mz_header.e_cparhdr<<4) >= sizeof(IMAGE_DOS_HEADER) )
if ( ( mz_header.e_crlc == 0 && mz_header.e_lfarlc == 0 ) ||
( mz_header.e_lfarlc >= sizeof(IMAGE_DOS_HEADER) ) )
if ( mz_header.e_lfanew >= sizeof(IMAGE_DOS_HEADER) &&
_llseek( hfile, mz_header.e_lfanew, SEEK_SET ) >= 0 &&
_lread( hfile, magic, sizeof(magic) ) == sizeof(magic) )
lfanewValid = TRUE;
if ( !lfanewValid )
{
/* If we cannot read this "extended header" we will
* assume that we have a simple DOS executable.
*/
*lpBinaryType = SCS_DOS_BINARY;
return TRUE;
}
else
{
/* Reading the magic field succeeded so
* we will try to determine what type it is.
*/
if ( *(DWORD*)magic == IMAGE_NT_SIGNATURE )
{
/* This is an NT signature.
*/
*lpBinaryType = SCS_32BIT_BINARY;
return TRUE;
}
else if ( *(WORD*)magic == IMAGE_OS2_SIGNATURE )
{
/* The IMAGE_OS2_SIGNATURE indicates that the
* "extended header is a Windows executable (NE)
* header. This is a bit misleading, but it is
* documented in the SDK. ( for more details see
* the neexe.h file )
*/
*lpBinaryType = SCS_WOW_BINARY;
return TRUE;
}
else
{
/* Unknown extended header, so abort.
*/
return FALSE;
}
}
}
}
/* Create a task for this instance */
/* If we get here, we don't even have a correct MZ header.
* Try to check the file extension for known types ...
*/
ptr = strrchr( ofs->szPathName, '.' );
if ( ptr && !strchr( ptr, '\\' ) && !strchr( ptr, '/' ) )
{
if ( !lstrcmpiA( ptr, ".COM" ) )
{
*lpBinaryType = SCS_DOS_BINARY;
return TRUE;
}
pModule->flags |= NE_FFLAGS_GUI; /* FIXME: is this necessary? */
if ( !lstrcmpiA( ptr, ".PIF" ) )
{
*lpBinaryType = SCS_PIF_BINARY;
return TRUE;
}
}
PROCESS_Create( pModule, cmd_line, env, hInstance,
hPrevInstance, inherit, startup, info );
return hInstance;
return FALSE;
}
/**********************************************************************
* LoadModule16 (KERNEL.45)
/***********************************************************************
* GetBinaryTypeA [KERNEL32.280]
*/
HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType )
{
LOADPARAMS16 *params;
LPSTR cmd_line, new_cmd_line;
LPCVOID env = NULL;
STARTUPINFOA startup;
PROCESS_INFORMATION info;
HINSTANCE16 hInstance, hPrevInstance;
NE_MODULE *pModule;
PDB *pdb;
BOOL ret = FALSE;
HFILE hfile;
OFSTRUCT ofs;
/* Load module */
TRACE( win32, "%s\n", lpApplicationName );
if (!paramBlock || (paramBlock == (LPVOID)-1))
return LoadLibrary16( name );
/* Sanity check.
*/
if ( lpApplicationName == NULL || lpBinaryType == NULL )
return FALSE;
hInstance = NE_LoadModule( name, &hPrevInstance, FALSE, FALSE );
if ( hInstance < 32 || !(pModule = NE_GetPtr(hInstance))
|| (pModule->flags & NE_FFLAGS_LIBMODULE))
return hInstance;
/* Open the file indicated by lpApplicationName for reading.
*/
if ( (hfile = OpenFile( lpApplicationName, &ofs, OF_READ )) == HFILE_ERROR )
return FALSE;
/* Create a task for this instance */
/* Check binary type
*/
ret = MODULE_GetBinaryType( hfile, &ofs, lpBinaryType );
pModule->flags |= NE_FFLAGS_GUI; /* FIXME: is this necessary? */
/* Close the file.
*/
CloseHandle( hfile );
params = (LOADPARAMS16 *)paramBlock;
cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
if (!cmd_line) cmd_line = "";
else if (*cmd_line) cmd_line++; /* skip the length byte */
return ret;
}
if (!(new_cmd_line = HeapAlloc( GetProcessHeap(), 0,
strlen(cmd_line)+strlen(name)+2 )))
return 0;
strcpy( new_cmd_line, name );
strcat( new_cmd_line, " " );
strcat( new_cmd_line, cmd_line );
/***********************************************************************
* GetBinaryTypeW [KERNEL32.281]
*/
BOOL WINAPI GetBinaryTypeW( LPCWSTR lpApplicationName, LPDWORD lpBinaryType )
{
BOOL ret = FALSE;
LPSTR strNew = NULL;
if (params->hEnvironment) env = GlobalLock16( params->hEnvironment );
TRACE( win32, "%s\n", debugstr_w(lpApplicationName) );
memset( &info, '\0', sizeof(info) );
memset( &startup, '\0', sizeof(startup) );
startup.cb = sizeof(startup);
if (params->showCmd)
/* Sanity check.
*/
if ( lpApplicationName == NULL || lpBinaryType == NULL )
return FALSE;
/* Convert the wide string to a ascii string.
*/
strNew = HEAP_strdupWtoA( GetProcessHeap(), 0, lpApplicationName );
if ( strNew != NULL )
{
startup.dwFlags = STARTF_USESHOWWINDOW;
startup.wShowWindow = ((UINT16 *)PTR_SEG_TO_LIN(params->showCmd))[1];
ret = GetBinaryTypeA( strNew, lpBinaryType );
/* Free the allocated string.
*/
HeapFree( GetProcessHeap(), 0, strNew );
}
pdb = PROCESS_Create( pModule, new_cmd_line, env,
hInstance, hPrevInstance, TRUE, &startup, &info );
CloseHandle( info.hThread );
CloseHandle( info.hProcess );
if (params->hEnvironment) GlobalUnlock16( params->hEnvironment );
HeapFree( GetProcessHeap(), 0, new_cmd_line );
/* Start task */
if (pdb) TASK_StartTask( pdb->task );
return hInstance;
return ret;
}
/**********************************************************************
* LoadModule32 (KERNEL32.499)
* MODULE_CreateUnixProcess
*/
static BOOL MODULE_CreateUnixProcess( LPCSTR filename, LPCSTR lpCmdLine,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInfo,
BOOL useWine )
{
DOS_FULL_NAME full_name;
const char *unixfilename = filename;
const char *argv[256], **argptr;
BOOL iconic = FALSE;
/* Get Unix file name and iconic flag */
if ( lpStartupInfo->dwFlags & STARTF_USESHOWWINDOW )
if ( lpStartupInfo->wShowWindow == SW_SHOWMINIMIZED
|| lpStartupInfo->wShowWindow == SW_SHOWMINNOACTIVE )
iconic = TRUE;
if ( strchr(filename, '/')
|| strchr(filename, ':')
|| strchr(filename, '\\') )
{
if ( DOSFS_GetFullName( filename, TRUE, &full_name ) )
unixfilename = full_name.long_name;
}
if ( !unixfilename )
{
SetLastError( ERROR_FILE_NOT_FOUND );
return FALSE;
}
/* Build argument list */
argptr = argv;
if ( !useWine )
{
char *p = strdup(lpCmdLine);
*argptr++ = unixfilename;
if (iconic) *argptr++ = "-iconic";
while (1)
{
while (*p && (*p == ' ' || *p == '\t')) *p++ = '\0';
if (!*p) break;
*argptr++ = p;
while (*p && *p != ' ' && *p != '\t') p++;
}
}
else
{
*argptr++ = "wine";
if (iconic) *argptr++ = "-iconic";
*argptr++ = lpCmdLine;
}
*argptr++ = 0;
/* Fork and execute */
if ( !fork() )
{
/* Note: don't use Wine routines here, as this process
has not been correctly initialized! */
execvp( argv[0], (char**)argv );
/* Failed ! */
if ( useWine )
fprintf( stderr, "CreateProcess: can't exec 'wine %s'\n",
lpCmdLine );
exit( 1 );
}
/* Fake success return value */
memset( lpProcessInfo, '\0', sizeof( *lpProcessInfo ) );
lpProcessInfo->hProcess = INVALID_HANDLE_VALUE;
lpProcessInfo->hThread = INVALID_HANDLE_VALUE;
SetLastError( ERROR_SUCCESS );
return TRUE;
}
/***********************************************************************
* WinExec16 (KERNEL.166)
*/
HINSTANCE16 WINAPI WinExec16( LPCSTR lpCmdLine, UINT16 nCmdShow )
{
return WinExec( lpCmdLine, nCmdShow );
}
/***********************************************************************
* WinExec (KERNEL32.566)
*/
HINSTANCE WINAPI WinExec( LPCSTR lpCmdLine, UINT nCmdShow )
{
LOADPARAMS params;
UINT16 paramCmdShow[2];
if (!lpCmdLine)
return 2; /* File not found */
/* Set up LOADPARAMS buffer for LoadModule */
memset( &params, '\0', sizeof(params) );
params.lpCmdLine = (LPSTR)lpCmdLine;
params.lpCmdShow = paramCmdShow;
params.lpCmdShow[0] = 2;
params.lpCmdShow[1] = nCmdShow;
/* Now load the executable file */
return LoadModule( NULL, &params );
}
/**********************************************************************
* LoadModule (KERNEL32.499)
*/
HINSTANCE WINAPI LoadModule( LPCSTR name, LPVOID paramBlock )
{
@ -521,10 +726,16 @@ HINSTANCE WINAPI LoadModule( LPCSTR name, LPVOID paramBlock )
startup.dwFlags = STARTF_USESHOWWINDOW;
startup.wShowWindow = params->lpCmdShow? params->lpCmdShow[1] : 0;
if (!CreateProcessA( name, params->lpCmdLine,
NULL, NULL, FALSE, 0, params->lpEnvAddress,
NULL, &startup, &info ))
return GetLastError(); /* guaranteed to be < 32 */
if ( !CreateProcessA( name, params->lpCmdLine,
NULL, NULL, FALSE, 0, params->lpEnvAddress,
NULL, &startup, &info ) )
{
hInstance = GetLastError();
if ( hInstance < 32 ) return hInstance;
FIXME( module, "Strange error set by CreateProcess: %d\n", hInstance );
return 11;
}
/* Get 16-bit hInstance/hTask from process */
pdb = PROCESS_IdToPDB( info.dwProcessId );
@ -539,19 +750,21 @@ HINSTANCE WINAPI LoadModule( LPCSTR name, LPVOID paramBlock )
}
/**********************************************************************
* CreateProcess32A (KERNEL32.171)
* CreateProcessA (KERNEL32.171)
*/
BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles, DWORD dwCreationFlags,
LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInfo )
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles, DWORD dwCreationFlags,
LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInfo )
{
HINSTANCE16 hInstance;
BOOL retv = FALSE;
HFILE hFile;
OFSTRUCT ofs;
DWORD type;
LPCSTR cmdline;
PDB *pdb;
char name[256];
/* Get name and command line */
@ -667,35 +880,91 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine,
FIXME(module, "(%s,...): STARTF_USEHOTKEY ignored\n", name);
/* Try NE module */
hInstance = NE_CreateProcess( name, cmdline, lpEnvironment, bInheritHandles,
lpStartupInfo, lpProcessInfo );
/* When in WineLib, always fork new Unix process */
/* Try PE module */
if (hInstance == 21)
hInstance = PE_CreateProcess( name, cmdline, lpEnvironment, bInheritHandles,
lpStartupInfo, lpProcessInfo );
if ( __winelib )
return MODULE_CreateUnixProcess( name, cmdline,
lpStartupInfo, lpProcessInfo, TRUE );
/* Try DOS module */
if (hInstance == 11)
hInstance = MZ_CreateProcess( name, cmdline, lpEnvironment, bInheritHandles,
lpStartupInfo, lpProcessInfo );
/* Check for special case: second instance of NE module */
if (hInstance < 32)
lstrcpynA( ofs.szPathName, name, sizeof( ofs.szPathName ) );
retv = NE_CreateProcess( HFILE_ERROR, &ofs, cmdline, lpEnvironment,
bInheritHandles, lpStartupInfo, lpProcessInfo );
/* Load file and create process */
if ( !retv )
{
SetLastError( hInstance );
return FALSE;
/* Open file and determine executable type */
if ( (hFile = OpenFile( name, &ofs, OF_READ )) == HFILE_ERROR )
{
SetLastError( ERROR_FILE_NOT_FOUND );
return FALSE;
}
if ( !MODULE_GetBinaryType( hFile, &ofs, &type ) )
{
CloseHandle( hFile );
/* FIXME: Try Unix executable only when appropriate! */
if ( MODULE_CreateUnixProcess( name, cmdline,
lpStartupInfo, lpProcessInfo, FALSE ) )
return TRUE;
SetLastError( ERROR_BAD_FORMAT );
return FALSE;
}
/* Create process */
switch ( type )
{
case SCS_32BIT_BINARY:
retv = PE_CreateProcess( hFile, &ofs, cmdline, lpEnvironment,
bInheritHandles, lpStartupInfo, lpProcessInfo );
break;
case SCS_DOS_BINARY:
retv = MZ_CreateProcess( hFile, &ofs, cmdline, lpEnvironment,
bInheritHandles, lpStartupInfo, lpProcessInfo );
break;
case SCS_WOW_BINARY:
retv = NE_CreateProcess( hFile, &ofs, cmdline, lpEnvironment,
bInheritHandles, lpStartupInfo, lpProcessInfo );
break;
case SCS_PIF_BINARY:
case SCS_POSIX_BINARY:
case SCS_OS216_BINARY:
FIXME( module, "Unsupported executable type: %ld\n", type );
/* fall through */
default:
SetLastError( ERROR_BAD_FORMAT );
retv = FALSE;
break;
}
CloseHandle( hFile );
}
/* Get hTask from process and start the task */
pdb = PROCESS_IdToPDB( lpProcessInfo->dwProcessId );
if (pdb) TASK_StartTask( pdb->task );
return TRUE;
if ( retv )
{
PDB *pdb = PROCESS_IdToPDB( lpProcessInfo->dwProcessId );
if (pdb) TASK_StartTask( pdb->task );
}
return retv;
}
/**********************************************************************
* CreateProcess32W (KERNEL32.172)
* CreateProcessW (KERNEL32.172)
* NOTES
* lpReserved is not converted
*/
@ -897,163 +1166,6 @@ void WINAPI PrivateFreeLibrary(HINSTANCE handle)
}
/***********************************************************************
* WinExec16 (KERNEL.166)
*/
HINSTANCE16 WINAPI WinExec16( LPCSTR lpCmdLine, UINT16 nCmdShow )
{
return WinExec( lpCmdLine, nCmdShow );
}
/***********************************************************************
* WinExec32 (KERNEL32.566)
*/
HINSTANCE WINAPI WinExec( LPCSTR lpCmdLine, UINT nCmdShow )
{
HINSTANCE handle = 2;
char *p, filename[256];
int spacelimit = 0, exhausted = 0;
LOADPARAMS params;
UINT16 paramCmdShow[2];
if (!lpCmdLine)
return 2; /* File not found */
/* Set up LOADPARAMS32 buffer for LoadModule32 */
memset( &params, '\0', sizeof(params) );
params.lpCmdLine = (LPSTR)lpCmdLine;
params.lpCmdShow = paramCmdShow;
params.lpCmdShow[0] = 2;
params.lpCmdShow[1] = nCmdShow;
/* Keep trying to load a file by trying different filenames; e.g.,
for the cmdline "abcd efg hij", try "abcd" with args "efg hij",
then "abcd efg" with arg "hij", and finally "abcd efg hij" with
no args */
while(!exhausted && handle == 2) {
int spacecount = 0;
/* Build the filename and command-line */
lstrcpynA(filename, lpCmdLine,
sizeof(filename) - 4 /* for extension */);
/* Keep grabbing characters until end-of-string, tab, or until the
number of spaces is greater than the spacelimit */
for (p = filename; ; p++) {
if(*p == ' ') {
++spacecount;
if(spacecount > spacelimit) {
++spacelimit;
break;
}
}
if(*p == '\0' || *p == '\t') {
exhausted = 1;
break;
}
}
*p = '\0';
/* Now load the executable file */
if (!__winelib)
{
handle = LoadModule( filename, &params );
if (handle == 2) /* file not found */
{
/* Check that the original file name did not have a suffix */
p = strrchr(filename, '.');
/* if there is a '.', check if either \ OR / follow */
if (!p || strchr(p, '/') || strchr(p, '\\'))
{
p = filename + strlen(filename);
strcpy( p, ".exe" );
handle = LoadModule( filename, &params );
*p = '\0'; /* Remove extension */
}
}
}
else
handle = 2; /* file not found */
if (handle < 32)
{
/* Try to start it as a unix program */
if (!fork())
{
/* Child process */
DOS_FULL_NAME full_name;
const char *unixfilename = NULL;
const char *argv[256], **argptr;
int iconic = (nCmdShow == SW_SHOWMINIMIZED ||
nCmdShow == SW_SHOWMINNOACTIVE);
THREAD_InitDone = FALSE; /* we didn't init this process */
/* get unixfilename */
if (strchr(filename, '/') ||
strchr(filename, ':') ||
strchr(filename, '\\'))
{
if (DOSFS_GetFullName( filename, TRUE, &full_name ))
unixfilename = full_name.long_name;
}
else unixfilename = filename;
if (unixfilename)
{
/* build argv */
argptr = argv;
if (iconic) *argptr++ = "-iconic";
*argptr++ = unixfilename;
p = strdup(lpCmdLine);
while (1)
{
while (*p && (*p == ' ' || *p == '\t')) *p++ = '\0';
if (!*p) break;
*argptr++ = p;
while (*p && *p != ' ' && *p != '\t') p++;
}
*argptr++ = 0;
/* Execute */
execvp(argv[0], (char**)argv);
}
/* Failed ! */
if (__winelib)
{
/* build argv */
argptr = argv;
*argptr++ = "wine";
if (iconic) *argptr++ = "-iconic";
*argptr++ = lpCmdLine;
*argptr++ = 0;
/* Execute */
execvp(argv[0] , (char**)argv);
/* Failed ! */
MSG("WinExec: can't exec 'wine %s'\n",
lpCmdLine);
}
exit(1);
}
}
} /* while (!exhausted && handle < 32) */
return handle;
}
/***********************************************************************
* WIN32_GetProcAddress16 (KERNEL32.36)
* Get procaddress in 16bit module from win32... (kernel32 undoc. ordinal func)

View file

@ -259,9 +259,6 @@ static void TASK_CallToStart(void)
if (PE_HEADER(pModule->module32)->OptionalHeader.Subsystem==IMAGE_SUBSYSTEM_WINDOWS_CUI)
AllocConsole();
if (pModule->heap_size)
LocalInit16( pTask->hInstance, 0, pModule->heap_size );
MODULE_InitializeDLLs( 0, DLL_PROCESS_ATTACH, (LPVOID)-1 );
TRACE(relay, "(entryproc=%p)\n", entry );
@ -336,8 +333,8 @@ static void TASK_CallToStart(void)
* any real problems with that, since we operated merely on a private
* TDB structure that is not yet linked into the task list.
*/
HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
HINSTANCE16 hPrevInstance, UINT16 cmdShow)
BOOL TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
HINSTANCE16 hPrevInstance, UINT16 cmdShow)
{
HTASK16 hTask;
TDB *pTask, *pInitialTask;
@ -354,7 +351,7 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
hTask = GLOBAL_Alloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(TDB),
pModule->self, FALSE, FALSE, FALSE );
if (!hTask) return 0;
if (!hTask) return FALSE;
pTask = (TDB *)GlobalLock16( hTask );
/* Fill the task structure */
@ -369,7 +366,7 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
pTask->flags |= TDBF_WINOLDAP;
pTask->version = pModule->expected_version;
pTask->hInstance = hInstance;
pTask->hInstance = hInstance? hInstance : pModule->self;
pTask->hPrevInstance = hPrevInstance;
pTask->hModule = pModule->self;
pTask->hParent = GetCurrentTask();
@ -445,16 +442,23 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
if ( pInitialTask )
pTask->userhandler = pInitialTask->userhandler;
/* 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->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( hInstance, sp );
}
/* Create the 16-bit stack frame */
if (!(sp = pModule->sp))
sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
sp &= ~1; sp -= 2*sizeof(STACK16FRAME);
pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( pTask->hInstance, sp );
pTask->thdb->cur_stack -= sizeof(STACK16FRAME);
frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
frame16->ebp = sp + (int)&((STACK16FRAME *)0)->bp;
frame16->ebp = OFFSETOF( pTask->thdb->cur_stack ) + (int)&((STACK16FRAME *)0)->bp;
frame16->bp = LOWORD(frame16->ebp);
frame16->ds = frame16->es = pTask->hInstance;
frame16->ds = frame16->es = hInstance;
frame16->fs = 0;
frame16->entry_point = 0;
frame16->entry_cs = 0;
@ -474,11 +478,14 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
frame32->retaddr = (DWORD)TASK_CallToStart;
/* The remaining fields will be initialized in TASK_Reschedule */
/* Enter task handle into thread and process */
pTask->thdb->teb.htask16 = pTask->thdb->process->task = hTask;
TRACE(task, "module='%s' cmdline='%s' task=%04x\n",
name, cmd_line, hTask );
return hTask;
return TRUE;
}
/***********************************************************************

View file

@ -420,7 +420,6 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
THDB *thdb = NULL;
PDB *parent = PROCESS_Current();
PDB *pdb = PROCESS_CreatePDB( parent, inherit );
TDB *pTask;
if (!pdb) return NULL;
info->hThread = info->hProcess = INVALID_HANDLE_VALUE;
@ -452,8 +451,9 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve;
else
size = 0;
if (!(thdb = THREAD_Create( pdb, size, FALSE, &server_thandle, &server_phandle,
NULL, NULL ))) goto error;
if (!(thdb = THREAD_Create( pdb, size, hInstance == 0,
&server_thandle, &server_phandle, NULL, NULL )))
goto error;
if ((info->hThread = HANDLE_Alloc( parent, &thdb->header, THREAD_ALL_ACCESS,
FALSE, server_thandle )) == INVALID_HANDLE_VALUE)
goto error;
@ -480,8 +480,8 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
if (startup->dwFlags & STARTF_USESHOWWINDOW)
cmdShow = startup->wShowWindow;
pdb->task = TASK_Create( thdb, pModule, hInstance, hPrevInstance, cmdShow);
if (!pdb->task) goto error;
if ( !TASK_Create( thdb, pModule, hInstance, hPrevInstance, cmdShow) )
goto error;
/* Map system DLLs into this process (from initial process) */

View file

@ -226,7 +226,7 @@ THDB *THREAD_CreateInitialThread( PDB *pdb )
/* Now proceed with normal initialization */
if (!THREAD_InitTHDB( &initial_thdb, 0, FALSE, NULL, NULL )) return NULL;
if (!THREAD_InitTHDB( &initial_thdb, 0, TRUE, NULL, NULL )) return NULL;
return &initial_thdb;
}
@ -244,7 +244,7 @@ THDB *THREAD_Create( PDB *pdb, DWORD stack_size, BOOL alloc_stack16,
thdb->header.refcount = 1;
thdb->process = pdb;
thdb->teb.except = (void *)-1;
thdb->teb.htask16 = 0; /* FIXME */
thdb->teb.htask16 = pdb->task;
thdb->teb.self = &thdb->teb;
thdb->teb.flags = (pdb->flags & PDB32_WIN16_PROC)? 0 : TEBF_WIN32;
thdb->teb.tls_ptr = thdb->tls_array;