mirror of
https://github.com/reactos/wine.git
synced 2025-02-22 22:01:51 +00:00
Moved some system dependencies to loader/dos/dosvm.c. Implemented
environmental argv[0] passing to DOS apps. Added XMS hooks.
This commit is contained in:
parent
7e5b3b3d83
commit
7dc3c60658
@ -6,20 +6,16 @@
|
|||||||
|
|
||||||
#ifdef linux
|
#ifdef linux
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/ipc.h>
|
|
||||||
#include <sys/shm.h>
|
|
||||||
#include <sys/vm86.h>
|
|
||||||
#include "wintypes.h"
|
#include "wintypes.h"
|
||||||
|
|
||||||
typedef struct _DOSTASK {
|
typedef struct _DOSTASK {
|
||||||
LPVOID img;
|
LPVOID img;
|
||||||
unsigned img_ofs;
|
unsigned img_ofs;
|
||||||
WORD psp_seg,load_seg;
|
WORD psp_seg,load_seg;
|
||||||
|
WORD init_cs,init_ip,init_ss,init_sp;
|
||||||
|
WORD xms_seg;
|
||||||
WORD dpmi_seg,dpmi_sel,dpmi_flag;
|
WORD dpmi_seg,dpmi_sel,dpmi_flag;
|
||||||
HMODULE16 hModule;
|
HMODULE16 hModule;
|
||||||
struct vm86plus_struct VM86;
|
|
||||||
int fn, state;
|
|
||||||
char mm_name[128];
|
char mm_name[128];
|
||||||
int mm_fd;
|
int mm_fd;
|
||||||
int read_pipe,write_pipe;
|
int read_pipe,write_pipe;
|
||||||
@ -30,9 +26,7 @@ typedef struct _DOSTASK {
|
|||||||
|
|
||||||
extern int MZ_InitTask( LPDOSTASK lpDosTask );
|
extern int MZ_InitTask( LPDOSTASK lpDosTask );
|
||||||
extern int MZ_InitMemory( LPDOSTASK lpDosTask, NE_MODULE *pModule );
|
extern int MZ_InitMemory( LPDOSTASK lpDosTask, NE_MODULE *pModule );
|
||||||
extern int MZ_RunModule( LPDOSTASK lpDosTask );
|
|
||||||
extern void MZ_KillModule( LPDOSTASK lpDosTask );
|
extern void MZ_KillModule( LPDOSTASK lpDosTask );
|
||||||
extern int DOSVM_Process( LPDOSTASK lpDosTask );
|
|
||||||
|
|
||||||
#endif /* linux */
|
#endif /* linux */
|
||||||
|
|
||||||
|
@ -59,9 +59,12 @@ extern void WINAPI INT_Int25Handler(CONTEXT*);
|
|||||||
/* msdos/int2f.c */
|
/* msdos/int2f.c */
|
||||||
extern void WINAPI INT_Int2fHandler(CONTEXT*);
|
extern void WINAPI INT_Int2fHandler(CONTEXT*);
|
||||||
|
|
||||||
/* msdos/int31.c */
|
/* msdos/dpmi.c */
|
||||||
extern void WINAPI INT_Int31Handler(CONTEXT*);
|
extern void WINAPI INT_Int31Handler(CONTEXT*);
|
||||||
|
|
||||||
|
/* msdos/xms.c */
|
||||||
|
extern void WINAPI XMS_Handler(CONTEXT*);
|
||||||
|
|
||||||
/* loader/signal.c */
|
/* loader/signal.c */
|
||||||
extern BOOL32 SIGNAL_Init(void);
|
extern BOOL32 SIGNAL_Init(void);
|
||||||
extern void SIGNAL_SetHandler( int sig, void (*func)(), int flags );
|
extern void SIGNAL_SetHandler( int sig, void (*func)(), int flags );
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "msdos.h"
|
#include "msdos.h"
|
||||||
#include "miscemu.h"
|
#include "miscemu.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "debugger.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "ldt.h"
|
#include "ldt.h"
|
||||||
@ -28,19 +29,23 @@
|
|||||||
|
|
||||||
#ifdef MZ_SUPPORTED
|
#ifdef MZ_SUPPORTED
|
||||||
|
|
||||||
static void DOSVM_Dump( LPDOSTASK lpDosTask)
|
#include <sys/mman.h>
|
||||||
|
#include <sys/vm86.h>
|
||||||
|
|
||||||
|
static void DOSVM_Dump( LPDOSTASK lpDosTask, int fn,
|
||||||
|
struct vm86plus_struct*VM86 )
|
||||||
{
|
{
|
||||||
unsigned iofs;
|
unsigned iofs;
|
||||||
BYTE*inst;
|
BYTE*inst;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
switch (VM86_TYPE(lpDosTask->fn)) {
|
switch (VM86_TYPE(fn)) {
|
||||||
case VM86_SIGNAL:
|
case VM86_SIGNAL:
|
||||||
printf("Trapped signal\n"); break;
|
printf("Trapped signal\n"); break;
|
||||||
case VM86_UNKNOWN:
|
case VM86_UNKNOWN:
|
||||||
printf("Trapped unhandled GPF\n"); break;
|
printf("Trapped unhandled GPF\n"); break;
|
||||||
case VM86_INTx:
|
case VM86_INTx:
|
||||||
printf("Trapped INT %02x\n",VM86_ARG(lpDosTask->fn)); break;
|
printf("Trapped INT %02x\n",VM86_ARG(fn)); break;
|
||||||
case VM86_STI:
|
case VM86_STI:
|
||||||
printf("Trapped STI\n"); break;
|
printf("Trapped STI\n"); break;
|
||||||
case VM86_PICRETURN:
|
case VM86_PICRETURN:
|
||||||
@ -48,7 +53,7 @@ static void DOSVM_Dump( LPDOSTASK lpDosTask)
|
|||||||
case VM86_TRAP:
|
case VM86_TRAP:
|
||||||
printf("Trapped debug request\n"); break;
|
printf("Trapped debug request\n"); break;
|
||||||
}
|
}
|
||||||
#define REGS lpDosTask->VM86.regs
|
#define REGS VM86->regs
|
||||||
fprintf(stderr,"AX=%04lX CX=%04lX DX=%04lX BX=%04lX\n",REGS.eax,REGS.ebx,REGS.ecx,REGS.edx);
|
fprintf(stderr,"AX=%04lX CX=%04lX DX=%04lX BX=%04lX\n",REGS.eax,REGS.ebx,REGS.ecx,REGS.edx);
|
||||||
fprintf(stderr,"SI=%04lX DI=%04lX SP=%04lX BP=%04lX\n",REGS.esi,REGS.edi,REGS.esp,REGS.ebp);
|
fprintf(stderr,"SI=%04lX DI=%04lX SP=%04lX BP=%04lX\n",REGS.esi,REGS.edi,REGS.esp,REGS.ebp);
|
||||||
fprintf(stderr,"CS=%04X DS=%04X ES=%04X SS=%04X\n",REGS.cs,REGS.ds,REGS.es,REGS.ss);
|
fprintf(stderr,"CS=%04X DS=%04X ES=%04X SS=%04X\n",REGS.cs,REGS.ds,REGS.es,REGS.ss);
|
||||||
@ -77,27 +82,28 @@ static int DOSVM_Int(int vect, PCONTEXT context )
|
|||||||
CP(ss,SegSs); CP(fs,SegFs); CP(gs,SegGs); \
|
CP(ss,SegSs); CP(fs,SegFs); CP(gs,SegGs); \
|
||||||
CP(eip,Eip); CP(eflags,EFlags)
|
CP(eip,Eip); CP(eflags,EFlags)
|
||||||
|
|
||||||
int DOSVM_Process( LPDOSTASK lpDosTask )
|
static int DOSVM_Process( LPDOSTASK lpDosTask, int fn,
|
||||||
|
struct vm86plus_struct*VM86 )
|
||||||
{
|
{
|
||||||
CONTEXT context;
|
CONTEXT context;
|
||||||
int ret=0;
|
int ret=0;
|
||||||
|
|
||||||
#define CP(x,y) context.y = lpDosTask->VM86.regs.x
|
#define CP(x,y) context.y = VM86->regs.x
|
||||||
CV;
|
CV;
|
||||||
#undef CP
|
#undef CP
|
||||||
(void*)V86BASE(&context)=lpDosTask->img;
|
(void*)V86BASE(&context)=lpDosTask->img;
|
||||||
|
|
||||||
switch (VM86_TYPE(lpDosTask->fn)) {
|
switch (VM86_TYPE(fn)) {
|
||||||
case VM86_SIGNAL:
|
case VM86_SIGNAL:
|
||||||
printf("Trapped signal\n");
|
printf("Trapped signal\n");
|
||||||
ret=-1; break;
|
ret=-1; break;
|
||||||
case VM86_UNKNOWN: /* unhandled GPF */
|
case VM86_UNKNOWN: /* unhandled GPF */
|
||||||
DOSVM_Dump(lpDosTask);
|
DOSVM_Dump(lpDosTask,fn,VM86);
|
||||||
ctx_debug(SIGSEGV,&context);
|
ctx_debug(SIGSEGV,&context);
|
||||||
break;
|
break;
|
||||||
case VM86_INTx:
|
case VM86_INTx:
|
||||||
TRACE(int,"DOS EXE calls INT %02x with AX=%04lx\n",VM86_ARG(lpDosTask->fn),context.Eax);
|
TRACE(int,"DOS EXE calls INT %02x with AX=%04lx\n",VM86_ARG(fn),context.Eax);
|
||||||
ret=DOSVM_Int(VM86_ARG(lpDosTask->fn),&context); break;
|
ret=DOSVM_Int(VM86_ARG(fn),&context); break;
|
||||||
case VM86_STI:
|
case VM86_STI:
|
||||||
break;
|
break;
|
||||||
case VM86_PICRETURN:
|
case VM86_PICRETURN:
|
||||||
@ -106,11 +112,10 @@ int DOSVM_Process( LPDOSTASK lpDosTask )
|
|||||||
ctx_debug(SIGTRAP,&context);
|
ctx_debug(SIGTRAP,&context);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DOSVM_Dump(lpDosTask);
|
DOSVM_Dump(lpDosTask,fn,VM86);
|
||||||
}
|
}
|
||||||
|
|
||||||
lpDosTask->fn=VM86_ENTER;
|
#define CP(x,y) VM86->regs.x = context.y
|
||||||
#define CP(x,y) lpDosTask->VM86.regs.x = context.y
|
|
||||||
CV;
|
CV;
|
||||||
#undef CP
|
#undef CP
|
||||||
return ret;
|
return ret;
|
||||||
@ -121,6 +126,7 @@ int DOSVM_Enter( PCONTEXT context )
|
|||||||
TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
|
TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
|
||||||
NE_MODULE *pModule = NE_GetPtr( pTask->hModule );
|
NE_MODULE *pModule = NE_GetPtr( pTask->hModule );
|
||||||
LPDOSTASK lpDosTask;
|
LPDOSTASK lpDosTask;
|
||||||
|
struct vm86plus_struct VM86;
|
||||||
int stat;
|
int stat;
|
||||||
|
|
||||||
GlobalUnlock16( GetCurrentTask() );
|
GlobalUnlock16( GetCurrentTask() );
|
||||||
@ -147,18 +153,47 @@ int DOSVM_Enter( PCONTEXT context )
|
|||||||
} else lpDosTask=pModule->lpDosTask;
|
} else lpDosTask=pModule->lpDosTask;
|
||||||
|
|
||||||
if (context) {
|
if (context) {
|
||||||
#define CP(x,y) lpDosTask->VM86.regs.x = context->y
|
#define CP(x,y) VM86.regs.x = context->y
|
||||||
CV;
|
CV;
|
||||||
#undef CP
|
#undef CP
|
||||||
|
} else {
|
||||||
|
/* initial setup */
|
||||||
|
memset(&VM86,0,sizeof(VM86));
|
||||||
|
VM86.regs.cs=lpDosTask->init_cs;
|
||||||
|
VM86.regs.eip=lpDosTask->init_ip;
|
||||||
|
VM86.regs.ss=lpDosTask->init_ss;
|
||||||
|
VM86.regs.esp=lpDosTask->init_sp;
|
||||||
|
VM86.regs.ds=lpDosTask->psp_seg;
|
||||||
|
VM86.regs.es=lpDosTask->psp_seg;
|
||||||
|
/* hmm, what else do we need? */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* main loop */
|
/* main exchange loop */
|
||||||
while ((stat = MZ_RunModule(lpDosTask)) >= 0)
|
stat = VM86_ENTER;
|
||||||
if (stat > 0 && DOSVM_Process(lpDosTask) < 0)
|
do {
|
||||||
break;
|
/* transmit VM86 structure to dosmod task */
|
||||||
|
if (write(lpDosTask->write_pipe,&stat,sizeof(stat))!=sizeof(stat))
|
||||||
|
return -1;
|
||||||
|
if (write(lpDosTask->write_pipe,&VM86,sizeof(VM86))!=sizeof(VM86))
|
||||||
|
return -1;
|
||||||
|
/* wait for response */
|
||||||
|
do {
|
||||||
|
if (read(lpDosTask->read_pipe,&stat,sizeof(stat))!=sizeof(stat)) {
|
||||||
|
if ((errno==EINTR)||(errno==EAGAIN)) continue;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
do {
|
||||||
|
if (read(lpDosTask->read_pipe,&VM86,sizeof(VM86))!=sizeof(VM86)) {
|
||||||
|
if ((errno==EINTR)||(errno==EAGAIN)) continue;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
/* got response */
|
||||||
|
} while (DOSVM_Process(lpDosTask,stat,&VM86)>=0);
|
||||||
|
|
||||||
if (context) {
|
if (context) {
|
||||||
#define CP(x,y) context->y = lpDosTask->VM86.regs.x
|
#define CP(x,y) context->y = VM86.regs.x
|
||||||
CV;
|
CV;
|
||||||
#undef CP
|
#undef CP
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#ifdef MZ_SUPPORTED
|
#ifdef MZ_SUPPORTED
|
||||||
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/vm86.h>
|
|
||||||
|
|
||||||
/* define this to try mapping through /proc/pid/mem instead of a temp file,
|
/* define this to try mapping through /proc/pid/mem instead of a temp file,
|
||||||
but Linus doesn't like mmapping /proc/pid/mem, so it doesn't work for me */
|
but Linus doesn't like mmapping /proc/pid/mem, so it doesn't work for me */
|
||||||
@ -44,7 +43,7 @@
|
|||||||
#define SEG16(ptr,seg) ((LPVOID)((BYTE*)ptr+((DWORD)(seg)<<4)))
|
#define SEG16(ptr,seg) ((LPVOID)((BYTE*)ptr+((DWORD)(seg)<<4)))
|
||||||
#define SEGPTR16(ptr,segptr) ((LPVOID)((BYTE*)ptr+((DWORD)SELECTOROF(segptr)<<4)+OFFSETOF(segptr)))
|
#define SEGPTR16(ptr,segptr) ((LPVOID)((BYTE*)ptr+((DWORD)SELECTOROF(segptr)<<4)+OFFSETOF(segptr)))
|
||||||
|
|
||||||
static void MZ_InitPSP( LPVOID lpPSP, LPCSTR cmdline, LPCSTR env )
|
static void MZ_InitPSP( LPVOID lpPSP, LPCSTR cmdline, WORD env )
|
||||||
{
|
{
|
||||||
PDB*psp=lpPSP;
|
PDB*psp=lpPSP;
|
||||||
const char*cmd=cmdline?strchr(cmdline,' '):NULL;
|
const char*cmd=cmdline?strchr(cmdline,' '):NULL;
|
||||||
@ -52,6 +51,7 @@ static void MZ_InitPSP( LPVOID lpPSP, LPCSTR cmdline, LPCSTR env )
|
|||||||
psp->int20=0x20CD; /* int 20 */
|
psp->int20=0x20CD; /* int 20 */
|
||||||
/* some programs use this to calculate how much memory they need */
|
/* some programs use this to calculate how much memory they need */
|
||||||
psp->nextParagraph=0x9FFF;
|
psp->nextParagraph=0x9FFF;
|
||||||
|
psp->environment=env;
|
||||||
/* copy parameters */
|
/* copy parameters */
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
#if 0
|
#if 0
|
||||||
@ -66,36 +66,78 @@ static void MZ_InitPSP( LPVOID lpPSP, LPCSTR cmdline, LPCSTR env )
|
|||||||
/* FIXME: integrate the PDB stuff from Wine (loader/task.c) */
|
/* FIXME: integrate the PDB stuff from Wine (loader/task.c) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char enter_xms[]={
|
||||||
|
/* XMS hookable entry point */
|
||||||
|
0xEB,0x03, /* jmp entry */
|
||||||
|
0x90,0x90,0x90, /* nop;nop;nop */
|
||||||
|
/* entry: */
|
||||||
|
/* real entry point */
|
||||||
|
/* for simplicity, we'll just use the same hook as DPMI below */
|
||||||
|
0xCD,0x31, /* int 0x31 */
|
||||||
|
0xCB /* retf */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void MZ_InitXMS( LPDOSTASK lpDosTask )
|
||||||
|
{
|
||||||
|
LPBYTE start=DOSMEM_GetBlock(lpDosTask->hModule,sizeof(enter_xms),&(lpDosTask->xms_seg));
|
||||||
|
memcpy(start,enter_xms,sizeof(enter_xms));
|
||||||
|
}
|
||||||
|
|
||||||
static char enter_pm[]={
|
static char enter_pm[]={
|
||||||
0x50, /* pushw %ax */
|
0x50, /* pushw %ax */
|
||||||
0x52, /* pushw %dx */
|
0x52, /* pushw %dx */
|
||||||
0x55, /* pushw %bp */
|
0x55, /* pushw %bp */
|
||||||
0x89,0xE5, /* movw %sp,%bp */
|
0x89,0xE5, /* movw %sp,%bp */
|
||||||
/* get return CS */
|
/* get return CS */
|
||||||
0x8B,0x56,0x08, /* movw 8(%bp),%dx */
|
0x8B,0x56,0x08, /* movw 8(%bp),%dx */
|
||||||
/* just call int 31 here to get into protected mode... */
|
/* just call int 31 here to get into protected mode... */
|
||||||
/* it'll check whether it was called from dpmi_seg... */
|
/* it'll check whether it was called from dpmi_seg... */
|
||||||
0xCD,0x31, /* int 0x31 */
|
0xCD,0x31, /* int 0x31 */
|
||||||
/* fixup our stack; return address will be lost, but we won't worry quite yet */
|
/* we are now in the context of a 16-bit relay call */
|
||||||
0x8E,0xD0, /* movw %ax,%ss */
|
/* need to fixup our stack;
|
||||||
0x89,0xEC, /* movw %bp,%sp */
|
* 16-bit relay return address will be lost, but we won't worry quite yet */
|
||||||
|
0x8E,0xD0, /* movw %ax,%ss */
|
||||||
|
0x66,0x0F,0xB7,0xE5, /* movzwl %bp,%esp */
|
||||||
/* set return CS */
|
/* set return CS */
|
||||||
0x89,0x56,0x08, /* movw %dx,8(%bp) */
|
0x89,0x56,0x08, /* movw %dx,8(%bp) */
|
||||||
0x5D, /* popw %bp */
|
0x5D, /* popw %bp */
|
||||||
0x5A, /* popw %dx */
|
0x5A, /* popw %dx */
|
||||||
0x58, /* popw %ax */
|
0x58, /* popw %ax */
|
||||||
0xCB /* retf */
|
0xCB /* retf */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void MZ_InitDPMI( LPDOSTASK lpDosTask )
|
static void MZ_InitDPMI( LPDOSTASK lpDosTask )
|
||||||
{
|
{
|
||||||
LPBYTE start=DOSMEM_GetBlock(lpDosTask->hModule,sizeof(enter_pm),&(lpDosTask->dpmi_seg));
|
LPBYTE start=DOSMEM_GetBlock(lpDosTask->hModule,sizeof(enter_pm),&(lpDosTask->dpmi_seg));
|
||||||
|
|
||||||
lpDosTask->dpmi_sel = SELECTOR_AllocBlock( start, sizeof(enter_pm), SEGMENT_CODE, FALSE, TRUE );
|
lpDosTask->dpmi_sel = SELECTOR_AllocBlock( start, sizeof(enter_pm), SEGMENT_CODE, FALSE, FALSE );
|
||||||
|
|
||||||
memcpy(start,enter_pm,sizeof(enter_pm));
|
memcpy(start,enter_pm,sizeof(enter_pm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WORD MZ_InitEnvironment( LPDOSTASK lpDosTask, LPCSTR env, LPCSTR name )
|
||||||
|
{
|
||||||
|
unsigned sz=0;
|
||||||
|
WORD seg;
|
||||||
|
LPSTR envblk;
|
||||||
|
|
||||||
|
if (env) {
|
||||||
|
/* get size of environment block */
|
||||||
|
while (env[sz++]) sz+=strlen(env+sz);
|
||||||
|
} else sz++;
|
||||||
|
/* allocate it */
|
||||||
|
envblk=DOSMEM_GetBlock(lpDosTask->hModule,sz+sizeof(WORD)+strlen(name)+1,&seg);
|
||||||
|
/* fill it */
|
||||||
|
if (env) {
|
||||||
|
memcpy(envblk,env,sz);
|
||||||
|
} else envblk[0]=0;
|
||||||
|
/* DOS 3.x: the block contains 1 additional string */
|
||||||
|
*(WORD*)(envblk+sz)=1;
|
||||||
|
/* being the program name itself */
|
||||||
|
strcpy(envblk+sz+sizeof(WORD),name);
|
||||||
|
return seg;
|
||||||
|
}
|
||||||
|
|
||||||
int MZ_InitMemory( LPDOSTASK lpDosTask, NE_MODULE *pModule )
|
int MZ_InitMemory( LPDOSTASK lpDosTask, NE_MODULE *pModule )
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
@ -129,18 +171,20 @@ int MZ_InitMemory( LPDOSTASK lpDosTask, NE_MODULE *pModule )
|
|||||||
/* initialize the memory */
|
/* initialize the memory */
|
||||||
TRACE(module,"Initializing DOS memory structures\n");
|
TRACE(module,"Initializing DOS memory structures\n");
|
||||||
DOSMEM_Init(lpDosTask->hModule);
|
DOSMEM_Init(lpDosTask->hModule);
|
||||||
|
MZ_InitXMS(lpDosTask);
|
||||||
MZ_InitDPMI(lpDosTask);
|
MZ_InitDPMI(lpDosTask);
|
||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env,
|
static int MZ_LoadImage( HFILE16 hFile, LPCSTR name, LPCSTR cmdline,
|
||||||
LPDOSTASK lpDosTask, NE_MODULE *pModule )
|
LPCSTR env, LPDOSTASK lpDosTask, NE_MODULE *pModule )
|
||||||
{
|
{
|
||||||
IMAGE_DOS_HEADER mz_header;
|
IMAGE_DOS_HEADER mz_header;
|
||||||
DWORD image_start,image_size,min_size,max_size,avail;
|
DWORD image_start,image_size,min_size,max_size,avail;
|
||||||
BYTE*psp_start,*load_start;
|
BYTE*psp_start,*load_start;
|
||||||
int x,old_com=0;
|
int x,old_com=0;
|
||||||
SEGPTR reloc;
|
SEGPTR reloc;
|
||||||
|
WORD env_seg;
|
||||||
|
|
||||||
if ((_hread16(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
|
if ((_hread16(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
|
||||||
(mz_header.e_magic != IMAGE_DOS_SIGNATURE)) {
|
(mz_header.e_magic != IMAGE_DOS_SIGNATURE)) {
|
||||||
@ -166,7 +210,8 @@ static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env,
|
|||||||
|
|
||||||
MZ_InitMemory(lpDosTask,pModule);
|
MZ_InitMemory(lpDosTask,pModule);
|
||||||
|
|
||||||
/* FIXME: allocate memory for environment variables */
|
/* allocate environment block */
|
||||||
|
env_seg=MZ_InitEnvironment(lpDosTask,env,name);
|
||||||
|
|
||||||
/* allocate memory for the executable */
|
/* allocate memory for the executable */
|
||||||
TRACE(module,"Allocating DOS memory (min=%ld, max=%ld)\n",min_size,max_size);
|
TRACE(module,"Allocating DOS memory (min=%ld, max=%ld)\n",min_size,max_size);
|
||||||
@ -183,10 +228,10 @@ static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env,
|
|||||||
}
|
}
|
||||||
lpDosTask->load_seg=lpDosTask->psp_seg+(old_com?0:PSP_SIZE);
|
lpDosTask->load_seg=lpDosTask->psp_seg+(old_com?0:PSP_SIZE);
|
||||||
load_start=psp_start+(PSP_SIZE<<4);
|
load_start=psp_start+(PSP_SIZE<<4);
|
||||||
MZ_InitPSP(psp_start, cmdline, env);
|
MZ_InitPSP(psp_start, cmdline, env_seg);
|
||||||
|
|
||||||
/* load executable image */
|
/* load executable image */
|
||||||
TRACE(module,"loading DOS %s image size, %08lx bytes\n",old_com?"COM":"EXE",image_size);
|
TRACE(module,"loading DOS %s image, %08lx bytes\n",old_com?"COM":"EXE",image_size);
|
||||||
_llseek16(hFile,image_start,FILE_BEGIN);
|
_llseek16(hFile,image_start,FILE_BEGIN);
|
||||||
if ((_hread16(hFile,load_start,image_size)) != image_size)
|
if ((_hread16(hFile,load_start,image_size)) != image_size)
|
||||||
return 11; /* invalid exe */
|
return 11; /* invalid exe */
|
||||||
@ -203,26 +248,12 @@ static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize module variables */
|
lpDosTask->init_cs=lpDosTask->load_seg+mz_header.e_cs;
|
||||||
pModule->cs=lpDosTask->load_seg+mz_header.e_cs;
|
lpDosTask->init_ip=mz_header.e_ip;
|
||||||
pModule->ip=mz_header.e_ip;
|
lpDosTask->init_ss=lpDosTask->load_seg+mz_header.e_ss;
|
||||||
pModule->ss=lpDosTask->load_seg+mz_header.e_ss;
|
lpDosTask->init_sp=mz_header.e_sp;
|
||||||
pModule->sp=mz_header.e_sp;
|
|
||||||
pModule->self_loading_sel=lpDosTask->psp_seg;
|
|
||||||
|
|
||||||
TRACE(module,"entry point: %04x:%04x\n",pModule->cs,pModule->ip);
|
TRACE(module,"entry point: %04x:%04x\n",lpDosTask->init_cs,lpDosTask->init_ip);
|
||||||
|
|
||||||
/* initialize vm86 struct */
|
|
||||||
/* note: this may be moved soon, to be able to remove VM86 from lpDosTask
|
|
||||||
(got tired of all those compiler warnings, and don't like the system dependency) */
|
|
||||||
memset(&lpDosTask->VM86,0,sizeof(lpDosTask->VM86));
|
|
||||||
lpDosTask->VM86.regs.cs=lpDosTask->load_seg+mz_header.e_cs;
|
|
||||||
lpDosTask->VM86.regs.eip=mz_header.e_ip;
|
|
||||||
lpDosTask->VM86.regs.ss=lpDosTask->load_seg+mz_header.e_ss;
|
|
||||||
lpDosTask->VM86.regs.esp=mz_header.e_sp;
|
|
||||||
lpDosTask->VM86.regs.ds=lpDosTask->psp_seg;
|
|
||||||
lpDosTask->VM86.regs.es=lpDosTask->psp_seg;
|
|
||||||
/* hmm, what else do we need? */
|
|
||||||
|
|
||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
@ -240,8 +271,6 @@ int MZ_InitTask( LPDOSTASK lpDosTask )
|
|||||||
}
|
}
|
||||||
lpDosTask->read_pipe=read_fd[0];
|
lpDosTask->read_pipe=read_fd[0];
|
||||||
lpDosTask->write_pipe=write_fd[1];
|
lpDosTask->write_pipe=write_fd[1];
|
||||||
lpDosTask->fn=VM86_ENTER;
|
|
||||||
lpDosTask->state=1;
|
|
||||||
/* if we have a mapping file, use it */
|
/* if we have a mapping file, use it */
|
||||||
fname=lpDosTask->mm_name; farg=NULL;
|
fname=lpDosTask->mm_name; farg=NULL;
|
||||||
if (!fname[0]) {
|
if (!fname[0]) {
|
||||||
@ -251,7 +280,7 @@ int MZ_InitTask( LPDOSTASK lpDosTask )
|
|||||||
fname=fproc; farg=arg;
|
fname=fproc; farg=arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(module,"Preparing to load DOS VM support module: forking\n");
|
TRACE(module,"Loading DOS VM support module (hmodule=%04x)\n",lpDosTask->hModule);
|
||||||
if ((child=fork())<0) {
|
if ((child=fork())<0) {
|
||||||
close(write_fd[0]); close(write_fd[1]);
|
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 0;
|
||||||
@ -331,7 +360,7 @@ HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env,
|
|||||||
|
|
||||||
lpDosTask->img=NULL; lpDosTask->mm_name[0]=0; lpDosTask->mm_fd=-1;
|
lpDosTask->img=NULL; lpDosTask->mm_name[0]=0; lpDosTask->mm_fd=-1;
|
||||||
} else lpDosTask=pModule->lpDosTask;
|
} else lpDosTask=pModule->lpDosTask;
|
||||||
err = MZ_LoadImage( hFile, cmdline, env, lpDosTask, pModule );
|
err = MZ_LoadImage( hFile, name, cmdline, env, lpDosTask, pModule );
|
||||||
_lclose16(hFile);
|
_lclose16(hFile);
|
||||||
if (alloc) {
|
if (alloc) {
|
||||||
pModule->dos_image = lpDosTask->img;
|
pModule->dos_image = lpDosTask->img;
|
||||||
@ -368,38 +397,11 @@ void MZ_KillModule( LPDOSTASK lpDosTask )
|
|||||||
close(lpDosTask->read_pipe);
|
close(lpDosTask->read_pipe);
|
||||||
close(lpDosTask->write_pipe);
|
close(lpDosTask->write_pipe);
|
||||||
kill(lpDosTask->task,SIGTERM);
|
kill(lpDosTask->task,SIGTERM);
|
||||||
|
#if 0
|
||||||
|
/* FIXME: this seems to crash */
|
||||||
if (lpDosTask->dpmi_sel)
|
if (lpDosTask->dpmi_sel)
|
||||||
UnMapLS(PTR_SEG_OFF_TO_SEGPTR(lpDosTask->dpmi_sel,0));
|
UnMapLS(PTR_SEG_OFF_TO_SEGPTR(lpDosTask->dpmi_sel,0));
|
||||||
}
|
#endif
|
||||||
|
|
||||||
int MZ_RunModule( LPDOSTASK lpDosTask )
|
|
||||||
{
|
|
||||||
/* transmit the current context structure to the DOS task */
|
|
||||||
if (lpDosTask->state==1) {
|
|
||||||
if (write(lpDosTask->write_pipe,&lpDosTask->fn,sizeof(lpDosTask->fn))!=sizeof(lpDosTask->fn))
|
|
||||||
return -1;
|
|
||||||
if (write(lpDosTask->write_pipe,&lpDosTask->VM86,sizeof(lpDosTask->VM86))!=sizeof(lpDosTask->VM86))
|
|
||||||
return -1;
|
|
||||||
lpDosTask->state=2;
|
|
||||||
}
|
|
||||||
/* wait for another context structure to appear (this may block) */
|
|
||||||
if (lpDosTask->state==2) {
|
|
||||||
if (read(lpDosTask->read_pipe,&lpDosTask->fn,sizeof(lpDosTask->fn))!=sizeof(lpDosTask->fn)) {
|
|
||||||
if ((errno==EINTR)||(errno==EAGAIN)) return 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
lpDosTask->state=3;
|
|
||||||
}
|
|
||||||
if (lpDosTask->state==3) {
|
|
||||||
if (read(lpDosTask->read_pipe,&lpDosTask->VM86,sizeof(lpDosTask->VM86))!=sizeof(lpDosTask->VM86)) {
|
|
||||||
if ((errno==EINTR)||(errno==EAGAIN)) return 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* got one */
|
|
||||||
lpDosTask->state=1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !MZ_SUPPORTED */
|
#else /* !MZ_SUPPORTED */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user