Adapted to CreateProcess changes.

This commit is contained in:
Ulrich Weigand 1999-02-28 11:19:10 +00:00 committed by Alexandre Julliard
parent fe14b6603d
commit f6a9361942
7 changed files with 125 additions and 128 deletions

View File

@ -30,10 +30,7 @@ typedef struct _DOSTASK {
#define MZ_SUPPORTED
struct _NE_MODULE;
extern int MZ_InitTask( LPDOSTASK lpDosTask );
extern int MZ_InitMemory( LPDOSTASK lpDosTask, struct _NE_MODULE *pModule );
extern BOOL MZ_InitTask( LPDOSTASK lpDosTask );
extern void MZ_KillModule( LPDOSTASK lpDosTask );
extern LPDOSTASK MZ_AllocDPMITask( HMODULE16 hModule );
@ -43,8 +40,9 @@ extern LPDOSTASK MZ_AllocDPMITask( HMODULE16 hModule );
extern void MZ_Tick( WORD handle );
extern HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env, BOOL inherit,
LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info );
extern BOOL MZ_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline,
LPCSTR env, BOOL inherit, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info );
extern int DOSVM_Enter( PCONTEXT context );
extern void DOSVM_SetTimer( unsigned ticks );
extern unsigned DOSVM_GetTimer( void );

View File

@ -33,10 +33,10 @@ extern HRSRC PE_FindResourceExW(struct _wine_modref*,LPCWSTR,LPCWSTR,WORD);
extern DWORD PE_SizeofResource(HMODULE,HRSRC);
extern HMODULE PE_LoadLibraryExA(LPCSTR,HFILE,DWORD);
extern HGLOBAL PE_LoadResource(struct _wine_modref *wm,HRSRC);
extern HMODULE PE_LoadImage( LPCSTR name, OFSTRUCT *ofs, LPCSTR *modName );
extern HMODULE PE_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR *modName );
extern struct _wine_modref *PE_CreateModule( HMODULE hModule, OFSTRUCT *ofs,
DWORD flags, BOOL builtin );
extern HINSTANCE16 PE_CreateProcess( LPCSTR name, LPCSTR cmd_line,
extern BOOL PE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line,
LPCSTR env, BOOL inherit, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info );

View File

@ -18,6 +18,7 @@
#include <sys/time.h>
#include "windef.h"
#include "wine/winbase16.h"
#include "winerror.h"
#include "module.h"
#include "peexe.h"
#include "neexe.h"
@ -174,11 +175,11 @@ static WORD MZ_InitEnvironment( LPDOSTASK lpDosTask, LPCSTR env, LPCSTR name )
return seg;
}
int MZ_InitMemory( LPDOSTASK lpDosTask, NE_MODULE *pModule )
static BOOL MZ_InitMemory( LPDOSTASK lpDosTask, NE_MODULE *pModule )
{
int x;
if (lpDosTask->img_ofs) return 32; /* already allocated */
if (lpDosTask->img_ofs) return TRUE; /* already allocated */
/* allocate 1MB+64K shared memory */
lpDosTask->img_ofs=START_OFFSET;
@ -199,7 +200,7 @@ int MZ_InitMemory( LPDOSTASK lpDosTask, NE_MODULE *pModule )
#endif
if (lpDosTask->img==(LPVOID)-1) {
ERR(module,"could not map shared memory, error=%s\n",strerror(errno));
return 0;
return FALSE;
}
TRACE(module,"DOS VM86 image mapped at %08lx\n",(DWORD)lpDosTask->img);
pModule->dos_image=lpDosTask->img;
@ -210,10 +211,10 @@ int MZ_InitMemory( LPDOSTASK lpDosTask, NE_MODULE *pModule )
MZ_InitHandlers(lpDosTask);
MZ_InitXMS(lpDosTask);
MZ_InitDPMI(lpDosTask);
return lpDosTask->hModule;
return TRUE;
}
static int MZ_LoadImage( HFILE16 hFile, LPCSTR name, LPCSTR cmdline,
static BOOL MZ_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline,
LPCSTR env, LPDOSTASK lpDosTask, NE_MODULE *pModule )
{
IMAGE_DOS_HEADER mz_header;
@ -223,14 +224,12 @@ static int MZ_LoadImage( HFILE16 hFile, LPCSTR name, LPCSTR cmdline,
SEGPTR reloc;
WORD env_seg;
if ((_hread16(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
_llseek(hFile,0,FILE_BEGIN);
if ((_lread(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
(mz_header.e_magic != IMAGE_DOS_SIGNATURE)) {
#if 0
return 11; /* invalid exe */
#endif
old_com=1; /* assume .COM file */
image_start=0;
image_size=GetFileSize(FILE_GetHandle(hFile),NULL);
image_size=GetFileSize(hFile,NULL);
min_size=0x10000; max_size=0x100000;
mz_header.e_crlc=0;
mz_header.e_ss=0; mz_header.e_sp=0xFFFE;
@ -248,20 +247,22 @@ static int MZ_LoadImage( HFILE16 hFile, LPCSTR name, LPCSTR cmdline,
MZ_InitMemory(lpDosTask,pModule);
/* allocate environment block */
env_seg=MZ_InitEnvironment(lpDosTask,env,name);
env_seg=MZ_InitEnvironment(lpDosTask,env,ofs->szPathName);
/* allocate memory for the executable */
TRACE(module,"Allocating DOS memory (min=%ld, max=%ld)\n",min_size,max_size);
avail=DOSMEM_Available(lpDosTask->hModule);
if (avail<min_size) {
ERR(module, "insufficient DOS memory\n");
return 0;
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
if (avail>max_size) avail=max_size;
psp_start=DOSMEM_GetBlock(lpDosTask->hModule,avail,&lpDosTask->psp_seg);
if (!psp_start) {
ERR(module, "error allocating DOS memory\n");
return 0;
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
lpDosTask->load_seg=lpDosTask->psp_seg+(old_com?0:PSP_SIZE);
load_start=psp_start+(PSP_SIZE<<4);
@ -269,18 +270,22 @@ static int MZ_LoadImage( HFILE16 hFile, LPCSTR name, LPCSTR cmdline,
/* load executable image */
TRACE(module,"loading DOS %s image, %08lx bytes\n",old_com?"COM":"EXE",image_size);
_llseek16(hFile,image_start,FILE_BEGIN);
if ((_hread16(hFile,load_start,image_size)) != image_size)
return 11; /* invalid exe */
_llseek(hFile,image_start,FILE_BEGIN);
if ((_lread(hFile,load_start,image_size)) != image_size) {
SetLastError(ERROR_BAD_FORMAT);
return FALSE;
}
if (mz_header.e_crlc) {
/* load relocation table */
TRACE(module,"loading DOS EXE relocation table, %d entries\n",mz_header.e_crlc);
/* FIXME: is this too slow without read buffering? */
_llseek16(hFile,mz_header.e_lfarlc,FILE_BEGIN);
_llseek(hFile,mz_header.e_lfarlc,FILE_BEGIN);
for (x=0; x<mz_header.e_crlc; x++) {
if (_lread16(hFile,&reloc,sizeof(reloc)) != sizeof(reloc))
return 11; /* invalid exe */
if (_lread(hFile,&reloc,sizeof(reloc)) != sizeof(reloc)) {
SetLastError(ERROR_BAD_FORMAT);
return FALSE;
}
*(WORD*)SEGPTR16(load_start,reloc)+=lpDosTask->load_seg;
}
}
@ -291,8 +296,7 @@ static int MZ_LoadImage( HFILE16 hFile, LPCSTR name, LPCSTR cmdline,
lpDosTask->init_sp=mz_header.e_sp;
TRACE(module,"entry point: %04x:%04x\n",lpDosTask->init_cs,lpDosTask->init_ip);
return lpDosTask->hModule;
return TRUE;
}
LPDOSTASK MZ_AllocDPMITask( HMODULE16 hModule )
@ -335,17 +339,17 @@ static void MZ_InitTimer( LPDOSTASK lpDosTask, int ver )
}
}
int MZ_InitTask( LPDOSTASK lpDosTask )
BOOL MZ_InitTask( LPDOSTASK lpDosTask )
{
int read_fd[2],write_fd[2];
pid_t child;
char *fname,*farg,arg[16],fproc[64],path[256],*fpath;
if (!lpDosTask) return 0;
if (!lpDosTask) return FALSE;
/* create read pipe */
if (pipe(read_fd)<0) return 0;
if (pipe(read_fd)<0) return FALSE;
if (pipe(write_fd)<0) {
close(read_fd[0]); close(read_fd[1]); return 0;
close(read_fd[0]); close(read_fd[1]); return FALSE;
}
lpDosTask->read_pipe=read_fd[0];
lpDosTask->write_pipe=write_fd[1];
@ -361,7 +365,7 @@ int MZ_InitTask( LPDOSTASK lpDosTask )
TRACE(module,"Loading DOS VM support module (hmodule=%04x)\n",lpDosTask->hModule);
if ((child=fork())<0) {
close(write_fd[0]); close(write_fd[1]);
close(read_fd[0]); close(read_fd[1]); return 0;
close(read_fd[0]); close(read_fd[1]); return FALSE;
}
if (child!=0) {
/* parent process */
@ -376,7 +380,7 @@ int MZ_InitTask( LPDOSTASK lpDosTask )
/* failure */
ERR(module,"dosmod has failed to initialize\n");
if (lpDosTask->mm_name[0]!=0) unlink(lpDosTask->mm_name);
return 0;
return FALSE;
}
} while (0);
/* the child has now mmaped the temp file, it's now safe to unlink.
@ -408,35 +412,31 @@ int MZ_InitTask( LPDOSTASK lpDosTask )
ERR(module,"Failed to spawn dosmod, error=%s\n",strerror(errno));
exit(1);
}
return lpDosTask->hModule;
return TRUE;
}
HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env, BOOL inherit,
LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info )
BOOL MZ_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline,
LPCSTR env, BOOL inherit, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info )
{
LPDOSTASK lpDosTask = NULL; /* keep gcc from complaining */
HMODULE16 hModule;
HINSTANCE16 hInstance;
PDB *pdb = PROCESS_Current();
TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
NE_MODULE *pModule = pTask ? NE_GetPtr( pTask->hModule ) : NULL;
HFILE16 hFile;
OFSTRUCT ofs;
int err, alloc = !(pModule && pModule->dos_image);
int alloc = !(pModule && pModule->dos_image);
GlobalUnlock16( GetCurrentTask() );
if (alloc && (lpDosTask = calloc(1, sizeof(DOSTASK))) == NULL)
return 0;
if ((hFile = OpenFile16( name, &ofs, OF_READ )) == HFILE_ERROR16)
return 2; /* File not found */
if (alloc && (lpDosTask = calloc(1, sizeof(DOSTASK))) == NULL) {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
if ((!env)&&pdb) env = pdb->env_db->environ;
if (alloc) {
if ((hModule = MODULE_CreateDummyModule(&ofs, NULL)) < 32)
return hModule;
if ((hModule = MODULE_CreateDummyModule(ofs, NULL)) < 32) {
SetLastError(hModule);
return FALSE;
}
lpDosTask->hModule = hModule;
pModule = (NE_MODULE *)GlobalLock16(hModule);
@ -444,32 +444,29 @@ HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env, BOOL inhe
lpDosTask->img=NULL; lpDosTask->mm_name[0]=0; lpDosTask->mm_fd=-1;
} else lpDosTask=pModule->lpDosTask;
err = MZ_LoadImage( hFile, name, cmdline, env, lpDosTask, pModule );
_lclose16(hFile);
if (!MZ_LoadImage( hFile, ofs, cmdline, env, lpDosTask, pModule )) {
if (alloc) {
pModule->dos_image = lpDosTask->img;
if (err<32) {
if (lpDosTask->mm_name[0]!=0) {
if (lpDosTask->img!=NULL) munmap(lpDosTask->img,0x110000-START_OFFSET);
if (lpDosTask->mm_fd>=0) close(lpDosTask->mm_fd);
unlink(lpDosTask->mm_name);
} else
if (lpDosTask->img!=NULL) VirtualFree(lpDosTask->img,0x110000,MEM_RELEASE);
return err;
}
err = MZ_InitTask( lpDosTask );
if (err<32) {
return FALSE;
}
if (alloc) {
pModule->dos_image = lpDosTask->img;
if (!MZ_InitTask( lpDosTask )) {
MZ_KillModule( lpDosTask );
/* FIXME: cleanup hModule */
return err;
SetLastError(ERROR_GEN_FAILURE);
return FALSE;
}
hInstance = NE_CreateInstance(pModule, NULL, (cmdline == NULL));
PROCESS_Create( pModule, cmdline, env, hInstance, 0, inherit, startup, info );
return hInstance;
} else {
return (err<32) ? err : pTask->hInstance;
if (!PROCESS_Create( pModule, cmdline, env, 0, 0, inherit, startup, info ))
return FALSE;
}
return TRUE;
}
void MZ_KillModule( LPDOSTASK lpDosTask )
@ -494,11 +491,13 @@ void MZ_KillModule( LPDOSTASK lpDosTask )
#else /* !MZ_SUPPORTED */
HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env, BOOL inherit,
LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info )
BOOL MZ_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmdline,
LPCSTR env, BOOL inherit, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info )
{
WARN(module,"DOS executables not supported on this architecture\n");
return (HMODULE16)11; /* invalid exe */
SetLastError(ERROR_BAD_FORMAT);
return FALSE;
}
#endif

View File

@ -267,7 +267,6 @@ HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] )
NE_MODULE *pModule;
OFSTRUCT ofs;
HMODULE16 hModule;
HINSTANCE16 hInstance;
/* Create the initial process */
if (!PROCESS_Init()) return 0;
@ -292,9 +291,7 @@ HINSTANCE MAIN_WinelibInit( int *argc, char *argv[] )
pModule->flags = NE_FFLAGS_WIN32;
pModule->module32 = wm->module;
hInstance = NE_CreateInstance( pModule, NULL, TRUE );
PROCESS_Current()->task = TASK_Create( THREAD_Current(), pModule, hInstance, 0, FALSE );
if (!TASK_Create( THREAD_Current(), pModule, 0, 0, FALSE )) return 0;
TASK_StartTask( PROCESS_Current()->task );
/* Initialize GDI and USER */

View File

@ -43,6 +43,7 @@
#include <sys/mman.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "callback.h"
#include "file.h"
#include "heap.h"
@ -452,10 +453,9 @@ static void do_relocations( unsigned int load_addr, IMAGE_BASE_RELOCATION *r )
* BUT we have to map the whole image anyway, for Win32 programs sometimes
* want to access them. (HMODULE32 point to the start of it)
*/
HMODULE PE_LoadImage( LPCSTR name, OFSTRUCT *ofs, LPCSTR *modName )
HMODULE PE_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR *modName )
{
HMODULE hModule;
HFILE hFile;
HANDLE mapping;
IMAGE_NT_HEADERS *nt;
@ -464,20 +464,6 @@ HMODULE PE_LoadImage( LPCSTR name, OFSTRUCT *ofs, LPCSTR *modName )
BY_HANDLE_FILE_INFORMATION bhfi;
int i, rawsize, lowest_va, lowest_fa, vma_size, file_size = 0;
DWORD load_addr, aoep, reloc = 0;
char dllname[256], *p;
/* Append .DLL to name if no extension present */
strcpy( dllname, name );
if ((p = strrchr( dllname, '\\' ))) p++; else p = dllname;
if (!strchr( p, '.' )) strcat( dllname, ".DLL" );
/* Open PE file */
hFile = OpenFile( dllname, ofs, OF_READ | OF_SHARE_DENY_WRITE );
if ( hFile == HFILE_ERROR )
{
WARN( win32, "OpenFile error %ld\n", GetLastError() );
return 2;
}
/* Retrieve file size */
if ( GetFileInformationByHandle( hFile, &bhfi ) )
@ -486,7 +472,6 @@ HMODULE PE_LoadImage( LPCSTR name, OFSTRUCT *ofs, LPCSTR *modName )
/* Map the PE file somewhere */
mapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | SEC_COMMIT,
0, 0, NULL );
CloseHandle( hFile );
if (!mapping)
{
WARN( win32, "CreateFileMapping error %ld\n", GetLastError() );
@ -810,27 +795,39 @@ HMODULE PE_LoadLibraryExA (LPCSTR name,
HMODULE16 hModule16;
NE_MODULE *pModule;
WINE_MODREF *wm;
BOOL builtin;
BOOL builtin = TRUE;
char dllname[256], *p;
/* Check for already loaded module */
if ((hModule32 = MODULE_FindModule( name )))
return hModule32;
/* try to load builtin, enabled modules first */
if ((hModule32 = BUILTIN32_LoadImage( name, &ofs, FALSE )))
builtin = TRUE;
/* try to load the specified dll/exe */
else if ((hModule32 = PE_LoadImage( name, &ofs, &modName )) >= 32)
builtin = FALSE;
/* Now try the built-in even if disabled */
else if ((hModule32 = BUILTIN32_LoadImage( name, &ofs, TRUE )))
/* Append .DLL to name if no extension present */
strcpy( dllname, name );
if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
strcat( dllname, ".DLL" );
/* Try to load builtin enabled modules first */
if ( !(hModule32 = BUILTIN32_LoadImage( name, &ofs, FALSE )) )
{
WARN( module, "Could not load external DLL '%s', using built-in module.\n", name );
builtin = TRUE;
/* Load PE module */
hFile = OpenFile( dllname, &ofs, OF_READ | OF_SHARE_DENY_WRITE );
if ( hFile != HFILE_ERROR )
if ( (hModule32 = PE_LoadImage( hFile, &ofs, &modName )) >= 32 )
builtin = FALSE;
CloseHandle( hFile );
}
/* Now try the built-in even if disabled */
if ( builtin )
if ( (hModule32 = BUILTIN32_LoadImage( name, &ofs, TRUE )) )
WARN( module, "Could not load external DLL '%s', using built-in module.\n", name );
else
return 0;
/* Create 16-bit dummy module */
if ((hModule16 = MODULE_CreateDummyModule( &ofs, modName )) < 32) return hModule16;
pModule = (NE_MODULE *)GlobalLock16( hModule16 );
@ -853,45 +850,52 @@ HMODULE PE_LoadLibraryExA (LPCSTR name,
}
/*****************************************************************************
* Load the PE main .EXE. All other loading is done by PE_LoadLibraryEx32A
* FIXME: this function should use PE_LoadLibraryEx32A, but currently can't
* Load the PE main .EXE. All other loading is done by PE_LoadLibraryExA
* FIXME: this function should use PE_LoadLibraryExA, but currently can't
* due to the PROCESS_Create stuff.
*/
HINSTANCE16 PE_CreateProcess( LPCSTR name, LPCSTR cmd_line,
BOOL PE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line,
LPCSTR env, BOOL inherit, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info )
{
LPCSTR modName = NULL;
HMODULE16 hModule16;
HMODULE hModule32;
HINSTANCE16 hInstance;
NE_MODULE *pModule;
OFSTRUCT ofs;
PDB *process;
/* Load file */
if ((hModule32 = PE_LoadImage( name, &ofs, &modName )) < 32)
return hModule32;
if ( (hModule32 = PE_LoadImage( hFile, ofs, &modName )) < 32 )
{
SetLastError( hModule32 );
return FALSE;
}
#if 0
if (PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL)
return 20; /* FIXME: not the right error code */
{
SetLastError( 20 ); /* FIXME: not the right error code */
return FALSE;
}
#endif
/* Create 16-bit dummy module */
if ((hModule16 = MODULE_CreateDummyModule( &ofs, modName )) < 32) return hModule16;
if ( (hModule16 = MODULE_CreateDummyModule( ofs, modName )) < 32 )
{
SetLastError( hModule16 );
return FALSE;
}
pModule = (NE_MODULE *)GlobalLock16( hModule16 );
pModule->flags = NE_FFLAGS_WIN32;
pModule->module32 = hModule32;
/* Create new process */
hInstance = NE_CreateInstance( pModule, NULL, FALSE );
process = PROCESS_Create( pModule, cmd_line, env,
hInstance, 0, inherit, startup, info );
if ( !PROCESS_Create( pModule, cmd_line, env,
0, 0, inherit, startup, info ) )
return FALSE;
/* Note: PE_CreateModule and the remaining process initialization will
be done in the context of the new process, in TASK_CallToStart */
return hInstance;
return TRUE;
}
/*********************************************************************

View File

@ -119,7 +119,6 @@ void MAIN_EmulatorRun( void )
int main( int argc, char *argv[] )
{
NE_MODULE *pModule;
HINSTANCE16 hInstance;
extern char * DEBUG_argv0;
__winelib = 0; /* First of all, clear the Winelib flag */
@ -166,8 +165,7 @@ int main( int argc, char *argv[] )
/* Create initial task */
if ( !(pModule = NE_GetPtr( GetModuleHandle16( "KERNEL32" ) )) ) return 1;
hInstance = NE_CreateInstance( pModule, NULL, TRUE );
PROCESS_Current()->task = TASK_Create( THREAD_Current(), pModule, hInstance, 0, FALSE );
if ( !TASK_Create( THREAD_Current(), pModule, 0, 0, FALSE ) ) return 1;
/* Initialize CALL32 routines */
/* This needs to be done just before switching stacks */

View File

@ -14,7 +14,8 @@
#include "miscemu.h"
#include "msdos.h"
#include "task.h"
#include "thread.h"
#include "thread.h" /* for !MZ_SUPPORTED */
#include "stackframe.h" /* for !MZ_SUPPORTED */
#include "toolhelp.h"
#include "selectors.h"
#include "process.h"
@ -293,7 +294,7 @@ callrmproc_again:
if (!(CurrRMCB || pModule->lpDosTask)) {
FIXME(int31,"DPMI real-mode call using DOS VM task system, not fully tested!\n");
TRACE(int31,"creating VM86 task\n");
if (MZ_InitTask( MZ_AllocDPMITask( pModule->self ) ) < 32) {
if (!MZ_InitTask( MZ_AllocDPMITask( pModule->self ) )) {
ERR(int31,"could not setup VM86 task\n");
return 1;
}