Use the exe name and file handle we got from the server also when
starting Win16 or DOS programs, to avoid depending on the contents of the command-line.
This commit is contained in:
parent
2362380b64
commit
105b0f4e64
|
@ -333,33 +333,9 @@ load_error:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI MZ_LoadImage( LPCSTR cmdline )
|
||||
void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile )
|
||||
{
|
||||
HFILE hFile;
|
||||
char *name, buffer[MAX_PATH];
|
||||
LPCSTR p = strchr( cmdline, ' ' );
|
||||
|
||||
if (p)
|
||||
{
|
||||
if (!(name = HeapAlloc( GetProcessHeap(), 0, p - cmdline + 1 ))) return FALSE;
|
||||
memcpy( name, cmdline, p - cmdline );
|
||||
name[p - cmdline] = 0;
|
||||
}
|
||||
else name = (char *)cmdline;
|
||||
|
||||
if (!SearchPathA( NULL, name, ".exe", sizeof(buffer), buffer, NULL )) goto error;
|
||||
if ((hFile = CreateFileA( buffer, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE)
|
||||
goto error;
|
||||
if (!MZ_DoLoadImage( hFile, buffer, NULL ))
|
||||
{
|
||||
CloseHandle( hFile );
|
||||
goto error;
|
||||
}
|
||||
MZ_Launch();
|
||||
error:
|
||||
if (name != cmdline) HeapFree( GetProcessHeap(), 0, name );
|
||||
return FALSE;
|
||||
if (MZ_DoLoadImage( hFile, filename, NULL )) MZ_Launch();
|
||||
}
|
||||
|
||||
BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk )
|
||||
|
@ -609,11 +585,10 @@ void WINAPI MZ_Exit( CONTEXT86 *context, BOOL cs_psp, WORD retval )
|
|||
|
||||
#else /* !MZ_SUPPORTED */
|
||||
|
||||
BOOL WINAPI MZ_LoadImage( LPCSTR cmdline )
|
||||
void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile )
|
||||
{
|
||||
WARN("DOS executables not supported on this platform\n");
|
||||
SetLastError(ERROR_BAD_FORMAT);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk )
|
||||
|
|
|
@ -7,7 +7,7 @@ import ntdll.dll
|
|||
|
||||
@ stdcall GetCurrent() MZ_Current
|
||||
@ stdcall LoadDPMI() MZ_AllocDPMITask
|
||||
@ stdcall LoadDosExe(str) MZ_LoadImage
|
||||
@ stdcall LoadDosExe(str long) MZ_LoadImage
|
||||
@ stdcall Exec(ptr str long ptr) MZ_Exec
|
||||
@ stdcall Exit(ptr long long) MZ_Exit
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ extern CALLOUT_TABLE Callout;
|
|||
typedef struct {
|
||||
struct _DOSTASK* WINAPI (*Current)( void );
|
||||
struct _DOSTASK* WINAPI (*LoadDPMI)( void );
|
||||
BOOL WINAPI (*LoadDosExe)( LPCSTR cmdline );
|
||||
void WINAPI (*LoadDosExe)( LPCSTR filename, HANDLE hFile );
|
||||
BOOL WINAPI (*Exec)( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk );
|
||||
void WINAPI (*Exit)( CONTEXT86 *context, BOOL cs_psp, WORD retval );
|
||||
int WINAPI (*Enter)( CONTEXT86 *context );
|
||||
|
|
|
@ -30,7 +30,7 @@ typedef struct _DOSTASK {
|
|||
|
||||
#define V86_FLAG 0x00020000
|
||||
|
||||
extern BOOL WINAPI MZ_LoadImage( LPCSTR cmdline );
|
||||
extern void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile );
|
||||
extern BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk );
|
||||
extern void WINAPI MZ_Exit( CONTEXT86 *context, BOOL cs_psp, WORD retval );
|
||||
extern LPDOSTASK WINAPI MZ_Current( void );
|
||||
|
|
|
@ -404,11 +404,8 @@ HANDLE NE_OpenFile( NE_MODULE *pModule )
|
|||
|
||||
/***********************************************************************
|
||||
* NE_LoadExeHeader
|
||||
*
|
||||
* We always have to close hFile upon exit.
|
||||
* Otherwise we get file sharing trouble !
|
||||
*/
|
||||
static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
||||
static HMODULE16 NE_LoadExeHeader( HANDLE hFile, LPCSTR path )
|
||||
{
|
||||
IMAGE_DOS_HEADER mz_header;
|
||||
IMAGE_OS2_HEADER ne_header;
|
||||
|
@ -420,51 +417,31 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
int fastload_offset = 0, fastload_length = 0;
|
||||
ET_ENTRY *entry;
|
||||
ET_BUNDLE *bundle, *oldbundle;
|
||||
HFILE16 hFile;
|
||||
OFSTRUCT ofs;
|
||||
|
||||
/* Open file */
|
||||
if ((hFile = OpenFile16( filename, &ofs, OF_READ )) == HFILE_ERROR16)
|
||||
return (HMODULE16)2; /* File not found */
|
||||
OFSTRUCT *ofs;
|
||||
|
||||
/* Read a block from either the file or the fast-load area. */
|
||||
#define READ(offset,size,buffer) \
|
||||
((fastload && ((offset) >= fastload_offset) && \
|
||||
((offset)+(size) <= fastload_offset+fastload_length)) ? \
|
||||
(memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
|
||||
(_llseek16( hFile, (offset), SEEK_SET), \
|
||||
_hread16( hFile, (buffer), (size) ) == (size)))
|
||||
(_llseek( hFile, (offset), SEEK_SET), \
|
||||
_lread( hFile, (buffer), (size) ) == (size)))
|
||||
|
||||
_llseek16( hFile, 0, SEEK_SET );
|
||||
if ((_hread16(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
|
||||
_llseek( hFile, 0, SEEK_SET );
|
||||
if ((_lread(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
|
||||
(mz_header.e_magic != IMAGE_DOS_SIGNATURE))
|
||||
{
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
|
||||
_llseek16( hFile, mz_header.e_lfanew, SEEK_SET );
|
||||
if (_hread16( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
|
||||
{
|
||||
_lclose16( hFile );
|
||||
_llseek( hFile, mz_header.e_lfanew, SEEK_SET );
|
||||
if (_lread( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
|
||||
if (ne_header.ne_magic == IMAGE_NT_SIGNATURE)
|
||||
{
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)21; /* win32 exe */
|
||||
}
|
||||
if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) return (HMODULE16)21; /* win32 exe */
|
||||
if (ne_header.ne_magic == IMAGE_OS2_SIGNATURE_LX) {
|
||||
MESSAGE("Sorry, this is an OS/2 linear executable (LX) file !\n");
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)12;
|
||||
}
|
||||
if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE)
|
||||
{
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return (HMODULE16)11; /* invalid exe */
|
||||
|
||||
/* We now have a valid NE header */
|
||||
|
||||
|
@ -485,14 +462,10 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
sizeof(ET_BUNDLE) +
|
||||
2 * (ne_header.ne_cbenttab - ne_header.ne_cmovent*6) +
|
||||
/* loaded file info */
|
||||
sizeof(OFSTRUCT)-sizeof(ofs.szPathName)+strlen(ofs.szPathName)+1;
|
||||
sizeof(OFSTRUCT) - sizeof(ofs->szPathName) + strlen(path) + 1;
|
||||
|
||||
hModule = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, size );
|
||||
if (!hModule)
|
||||
{
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
if (!hModule) return (HMODULE16)11; /* invalid exe */
|
||||
|
||||
FarSetOwner16( hModule, hModule );
|
||||
pModule = (NE_MODULE *)GlobalLock16( hModule );
|
||||
|
@ -521,8 +494,8 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
fastload_offset, fastload_length );
|
||||
if ((fastload = HeapAlloc( GetProcessHeap(), 0, fastload_length )) != NULL)
|
||||
{
|
||||
_llseek16( hFile, fastload_offset, SEEK_SET);
|
||||
if (_hread16(hFile, fastload, fastload_length) != fastload_length)
|
||||
_llseek( hFile, fastload_offset, SEEK_SET);
|
||||
if (_lread(hFile, fastload, fastload_length) != fastload_length)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, fastload );
|
||||
WARN("Error reading fast-load area!\n");
|
||||
|
@ -533,7 +506,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
|
||||
/* Get the segment table */
|
||||
|
||||
pModule->seg_table = (int)pData - (int)pModule;
|
||||
pModule->seg_table = pData - (BYTE *)pModule;
|
||||
buffer = HeapAlloc( GetProcessHeap(), 0, ne_header.ne_cseg *
|
||||
sizeof(struct ne_segment_table_entry_s));
|
||||
if (buffer)
|
||||
|
@ -549,7 +522,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
if (fastload)
|
||||
HeapFree( GetProcessHeap(), 0, fastload );
|
||||
GlobalFree16( hModule );
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
pSeg = (struct ne_segment_table_entry_s *)buffer;
|
||||
|
@ -565,7 +537,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
if (fastload)
|
||||
HeapFree( GetProcessHeap(), 0, fastload );
|
||||
GlobalFree16( hModule );
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
|
||||
|
@ -573,14 +544,11 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
|
||||
if (ne_header.ne_rsrctab < ne_header.ne_restab)
|
||||
{
|
||||
pModule->res_table = (int)pData - (int)pModule;
|
||||
pModule->res_table = pData - (BYTE *)pModule;
|
||||
if (!READ(mz_header.e_lfanew + ne_header.ne_rsrctab,
|
||||
ne_header.ne_restab - ne_header.ne_rsrctab,
|
||||
pData ))
|
||||
{
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
pData += ne_header.ne_restab - ne_header.ne_rsrctab;
|
||||
NE_InitResourceHandler( hModule );
|
||||
}
|
||||
|
@ -588,7 +556,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
|
||||
/* Get the resident names table */
|
||||
|
||||
pModule->name_table = (int)pData - (int)pModule;
|
||||
pModule->name_table = pData - (BYTE *)pModule;
|
||||
if (!READ( mz_header.e_lfanew + ne_header.ne_restab,
|
||||
ne_header.ne_modtab - ne_header.ne_restab,
|
||||
pData ))
|
||||
|
@ -596,7 +564,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
if (fastload)
|
||||
HeapFree( GetProcessHeap(), 0, fastload );
|
||||
GlobalFree16( hModule );
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
pData += ne_header.ne_modtab - ne_header.ne_restab;
|
||||
|
@ -605,7 +572,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
|
||||
if (ne_header.ne_cmod > 0)
|
||||
{
|
||||
pModule->modref_table = (int)pData - (int)pModule;
|
||||
pModule->modref_table = pData - (BYTE *)pModule;
|
||||
if (!READ( mz_header.e_lfanew + ne_header.ne_modtab,
|
||||
ne_header.ne_cmod * sizeof(WORD),
|
||||
pData ))
|
||||
|
@ -613,7 +580,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
if (fastload)
|
||||
HeapFree( GetProcessHeap(), 0, fastload );
|
||||
GlobalFree16( hModule );
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
pData += ne_header.ne_cmod * sizeof(WORD);
|
||||
|
@ -622,7 +588,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
|
||||
/* Get the imported names table */
|
||||
|
||||
pModule->import_table = (int)pData - (int)pModule;
|
||||
pModule->import_table = pData - (BYTE *)pModule;
|
||||
if (!READ( mz_header.e_lfanew + ne_header.ne_imptab,
|
||||
ne_header.ne_enttab - ne_header.ne_imptab,
|
||||
pData ))
|
||||
|
@ -630,7 +596,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
if (fastload)
|
||||
HeapFree( GetProcessHeap(), 0, fastload );
|
||||
GlobalFree16( hModule );
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
pData += ne_header.ne_enttab - ne_header.ne_imptab;
|
||||
|
@ -642,7 +607,7 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
BYTE nr_entries, type, *s;
|
||||
|
||||
TRACE("Converting entry table.\n");
|
||||
pModule->entry_table = (int)pData - (int)pModule;
|
||||
pModule->entry_table = pData - (BYTE *)pModule;
|
||||
if (!READ( mz_header.e_lfanew + ne_header.ne_enttab,
|
||||
ne_header.ne_cbenttab, pTempEntryTable ))
|
||||
{
|
||||
|
@ -650,7 +615,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
if (fastload)
|
||||
HeapFree( GetProcessHeap(), 0, fastload );
|
||||
GlobalFree16( hModule );
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
|
||||
|
@ -716,7 +680,6 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
if (fastload)
|
||||
HeapFree( GetProcessHeap(), 0, fastload );
|
||||
GlobalFree16( hModule );
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
|
||||
|
@ -728,10 +691,12 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
|
||||
/* Store the filename information */
|
||||
|
||||
pModule->fileinfo = (int)pData - (int)pModule;
|
||||
size = sizeof(OFSTRUCT)-sizeof(ofs.szPathName)+strlen(ofs.szPathName)+1;
|
||||
ofs.cBytes = size - 1;
|
||||
memcpy( pData, &ofs, size );
|
||||
pModule->fileinfo = pData - (BYTE *)pModule;
|
||||
size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName) + strlen(path) + 1;
|
||||
ofs = (OFSTRUCT *)pData;
|
||||
ofs->cBytes = size - 1;
|
||||
ofs->fFixedDisk = 1;
|
||||
strcpy( ofs->szPathName, path );
|
||||
pData += size;
|
||||
|
||||
/* Free the fast-load area */
|
||||
|
@ -749,17 +714,15 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
if (!pModule->nrname_handle)
|
||||
{
|
||||
GlobalFree16( hModule );
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
buffer = GlobalLock16( pModule->nrname_handle );
|
||||
_llseek16( hFile, ne_header.ne_nrestab, SEEK_SET );
|
||||
if (_hread16( hFile, buffer, ne_header.ne_cbnrestab )
|
||||
_llseek( hFile, ne_header.ne_nrestab, SEEK_SET );
|
||||
if (_lread( hFile, buffer, ne_header.ne_cbnrestab )
|
||||
!= ne_header.ne_cbnrestab)
|
||||
{
|
||||
GlobalFree16( pModule->nrname_handle );
|
||||
GlobalFree16( hModule );
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
}
|
||||
|
@ -776,16 +739,13 @@ static HMODULE16 NE_LoadExeHeader( LPCSTR filename )
|
|||
{
|
||||
if (pModule->nrname_handle) GlobalFree16( pModule->nrname_handle );
|
||||
GlobalFree16( hModule );
|
||||
_lclose16( hFile );
|
||||
return (HMODULE16)11; /* invalid exe */
|
||||
}
|
||||
}
|
||||
else pModule->dlls_to_init = 0;
|
||||
|
||||
NE_RegisterModule( pModule );
|
||||
SNOOP16_RegisterDLL(pModule,ofs.szPathName);
|
||||
|
||||
_lclose16( hFile );
|
||||
SNOOP16_RegisterDLL(pModule,path);
|
||||
return hModule;
|
||||
}
|
||||
|
||||
|
@ -896,8 +856,15 @@ static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only )
|
|||
NE_MODULE *pModule;
|
||||
HMODULE16 hModule;
|
||||
HINSTANCE16 hInstance;
|
||||
HFILE16 hFile;
|
||||
OFSTRUCT ofs;
|
||||
|
||||
hModule = NE_LoadExeHeader( name );
|
||||
/* Open file */
|
||||
if ((hFile = OpenFile16( name, &ofs, OF_READ )) == HFILE_ERROR16)
|
||||
return (HMODULE16)2; /* File not found */
|
||||
|
||||
hModule = NE_LoadExeHeader( DosFileHandleToWin32Handle(hFile), ofs.szPathName );
|
||||
_lclose16( hFile );
|
||||
if (hModule < 32) return hModule;
|
||||
|
||||
pModule = NE_GetPtr( hModule );
|
||||
|
@ -1004,23 +971,85 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* NE_CreateThread
|
||||
*
|
||||
* Create the thread for a 16-bit module.
|
||||
*/
|
||||
static HINSTANCE16 NE_CreateThread( NE_MODULE *pModule, WORD cmdShow, LPCSTR cmdline )
|
||||
{
|
||||
TEB *teb = NULL;
|
||||
HANDLE hThread = 0;
|
||||
int socket = -1;
|
||||
HTASK hTask;
|
||||
TDB *pTask;
|
||||
HINSTANCE16 instance = 0;
|
||||
|
||||
SERVER_START_REQ
|
||||
{
|
||||
struct new_thread_request *req = server_alloc_req( sizeof(*req), 0 );
|
||||
req->suspend = 0;
|
||||
req->inherit = 0;
|
||||
if (!server_call( REQ_NEW_THREAD ))
|
||||
{
|
||||
hThread = req->handle;
|
||||
socket = wine_server_recv_fd( hThread, 0 );
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (!hThread) return 0;
|
||||
|
||||
if (!(teb = THREAD_Create( socket, 0, FALSE ))) goto error;
|
||||
teb->tibflags &= ~TEBF_WIN32;
|
||||
teb->startup = NE_InitProcess;
|
||||
|
||||
/* Create a task for this process */
|
||||
|
||||
if (!TASK_Create( pModule, cmdShow, teb, cmdline + 1, *cmdline )) goto error;
|
||||
hTask = teb->htask16;
|
||||
if (SYSDEPS_SpawnThread( teb ) == -1) goto error;
|
||||
|
||||
/* Post event to start the task */
|
||||
PostEvent16( hTask );
|
||||
|
||||
/* Wait until we get the instance handle */
|
||||
do
|
||||
{
|
||||
DirectedYield16( hTask );
|
||||
if (!IsTask16( hTask )) /* thread has died */
|
||||
{
|
||||
DWORD exit_code;
|
||||
WaitForSingleObject( hThread, INFINITE );
|
||||
GetExitCodeThread( hThread, &exit_code );
|
||||
CloseHandle( hThread );
|
||||
return exit_code;
|
||||
}
|
||||
if (!(pTask = (TDB *)GlobalLock16( hTask ))) break;
|
||||
instance = pTask->hInstance;
|
||||
GlobalUnlock16( hTask );
|
||||
} while (!instance);
|
||||
|
||||
return instance;
|
||||
|
||||
error:
|
||||
/* FIXME: free TEB and task */
|
||||
close( socket );
|
||||
CloseHandle( hThread );
|
||||
return 0; /* FIXME */
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* LoadModule16 (KERNEL.45)
|
||||
*/
|
||||
HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
||||
{
|
||||
TEB *teb = NULL;
|
||||
BOOL lib_only = !paramBlock || (paramBlock == (LPVOID)-1);
|
||||
LOADPARAMS16 *params;
|
||||
HINSTANCE16 instance = 0;
|
||||
HMODULE16 hModule;
|
||||
NE_MODULE *pModule;
|
||||
HTASK hTask;
|
||||
TDB *pTask;
|
||||
LPSTR cmdline;
|
||||
WORD cmdShow;
|
||||
HANDLE hThread = 0;
|
||||
int socket = -1;
|
||||
|
||||
/* Load module */
|
||||
|
||||
|
@ -1059,65 +1088,40 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
|
|||
* in the meantime), or else to a stub module which contains only header
|
||||
* information.
|
||||
*/
|
||||
|
||||
/* Create the main thread */
|
||||
|
||||
SERVER_START_REQ
|
||||
{
|
||||
struct new_thread_request *req = server_alloc_req( sizeof(*req), 0 );
|
||||
req->suspend = 0;
|
||||
req->inherit = 0;
|
||||
if (!server_call( REQ_NEW_THREAD ))
|
||||
{
|
||||
hThread = req->handle;
|
||||
socket = wine_server_recv_fd( hThread, 0 );
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (!hThread) return 0;
|
||||
|
||||
if (!(teb = THREAD_Create( socket, 0, FALSE ))) goto error;
|
||||
teb->tibflags &= ~TEBF_WIN32;
|
||||
teb->startup = NE_InitProcess;
|
||||
|
||||
/* Create a task for this process */
|
||||
|
||||
params = (LOADPARAMS16 *)paramBlock;
|
||||
cmdShow = ((WORD *)MapSL(params->showCmd))[1];
|
||||
cmdline = MapSL( params->cmdLine );
|
||||
if (!TASK_Create( pModule, cmdShow, teb, cmdline + 1, *cmdline )) goto error;
|
||||
|
||||
hTask = teb->htask16;
|
||||
|
||||
if (SYSDEPS_SpawnThread( teb ) == -1) goto error;
|
||||
|
||||
/* Post event to start the task */
|
||||
PostEvent16( hTask );
|
||||
|
||||
/* Wait until we get the instance handle */
|
||||
do
|
||||
{
|
||||
DirectedYield16( hTask );
|
||||
if (!IsTask16( hTask )) /* thread has died */
|
||||
{
|
||||
DWORD exit_code;
|
||||
WaitForSingleObject( hThread, INFINITE );
|
||||
GetExitCodeThread( hThread, &exit_code );
|
||||
CloseHandle( hThread );
|
||||
return exit_code;
|
||||
return NE_CreateThread( pModule, cmdShow, cmdline );
|
||||
}
|
||||
if (!(pTask = (TDB *)GlobalLock16( hTask ))) break;
|
||||
instance = pTask->hInstance;
|
||||
GlobalUnlock16( hTask );
|
||||
} while (!instance);
|
||||
|
||||
return instance;
|
||||
|
||||
error:
|
||||
/* FIXME: free TEB and task */
|
||||
close( socket );
|
||||
CloseHandle( hThread );
|
||||
return 0; /* FIXME */
|
||||
/**********************************************************************
|
||||
* NE_StartMain
|
||||
*
|
||||
* Start the main NE task.
|
||||
*/
|
||||
HINSTANCE16 NE_StartMain( LPCSTR name, HANDLE file )
|
||||
{
|
||||
STARTUPINFOA info;
|
||||
HMODULE16 hModule;
|
||||
NE_MODULE *pModule;
|
||||
LPSTR cmdline = GetCommandLineA();
|
||||
|
||||
if ((hModule = NE_LoadExeHeader( file, name )) < 32) return hModule;
|
||||
|
||||
if (!(pModule = NE_GetPtr( hModule ))) return (HINSTANCE16)11;
|
||||
if (pModule->flags & NE_FFLAGS_LIBMODULE)
|
||||
{
|
||||
MESSAGE( "%s is not a valid Win16 executable\n", name );
|
||||
ExitProcess( ERROR_BAD_EXE_FORMAT );
|
||||
}
|
||||
|
||||
while (*cmdline && *cmdline != ' ') cmdline++;
|
||||
if (*cmdline) cmdline++;
|
||||
GetStartupInfoA( &info );
|
||||
if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = 1;
|
||||
|
||||
return NE_CreateThread( pModule, info.wShowWindow, cmdline );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,12 @@
|
|||
#include "dosexe.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
extern void PROCESS_InitWine( int argc, char *argv[] ) WINE_NORETURN;
|
||||
static char main_exe_name[MAX_PATH];
|
||||
static HANDLE main_exe_file;
|
||||
|
||||
extern void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name,
|
||||
HANDLE *win16_exe_file ) WINE_NORETURN;
|
||||
extern HINSTANCE16 NE_StartMain( LPCSTR name, HANDLE file );
|
||||
|
||||
/***********************************************************************
|
||||
* Main loop of initial task
|
||||
|
@ -31,12 +36,12 @@ int WINAPI wine_initial_task( HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, INT
|
|||
}
|
||||
THUNK_InitCallout();
|
||||
|
||||
if ((instance = WinExec16( GetCommandLineA(), show )) < 32)
|
||||
if ((instance = NE_StartMain( main_exe_name, main_exe_file )) < 32)
|
||||
{
|
||||
if (instance == 11) /* try DOS format */
|
||||
{
|
||||
if (DPMI_LoadDosSystem())
|
||||
Dosvm.LoadDosExe( GetCommandLineA() );
|
||||
Dosvm.LoadDosExe( main_exe_name, main_exe_file );
|
||||
/* if we get back here it failed */
|
||||
instance = GetLastError();
|
||||
}
|
||||
|
@ -50,6 +55,7 @@ int WINAPI wine_initial_task( HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, INT
|
|||
}
|
||||
ExitProcess(instance);
|
||||
}
|
||||
CloseHandle( main_exe_file ); /* avoid file sharing problems */
|
||||
|
||||
/* Start message loop for desktop window */
|
||||
|
||||
|
@ -68,6 +74,6 @@ int WINAPI wine_initial_task( HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, INT
|
|||
*/
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
PROCESS_InitWine( argc, argv );
|
||||
PROCESS_InitWine( argc, argv, main_exe_name, &main_exe_file );
|
||||
return 1; /* not reached */
|
||||
}
|
||||
|
|
|
@ -437,7 +437,7 @@ void *open_winelib_app( char *argv[] )
|
|||
*
|
||||
* Wine initialisation: load and start the main exe file.
|
||||
*/
|
||||
void PROCESS_InitWine( int argc, char *argv[] )
|
||||
void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win16_exe_file )
|
||||
{
|
||||
DWORD stack_size = 0;
|
||||
|
||||
|
@ -483,8 +483,9 @@ void PROCESS_InitWine( int argc, char *argv[] )
|
|||
/* it must be 16-bit or DOS format */
|
||||
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
|
||||
current_process.flags |= PDB32_WIN16_PROC;
|
||||
strcpy( win16_exe_name, main_exe_name );
|
||||
main_exe_name[0] = 0;
|
||||
CloseHandle( main_exe_file );
|
||||
*win16_exe_file = main_exe_file;
|
||||
main_exe_file = 0;
|
||||
_EnterWin16Lock();
|
||||
|
||||
|
|
Loading…
Reference in New Issue