From 7248d47fd2f8c01ba6224ed5d627cac47635bb2f Mon Sep 17 00:00:00 2001 From: Ove Kaaven Date: Mon, 31 Jul 2000 20:56:28 +0000 Subject: [PATCH] Convert DOS (MZ) binary loader to the new DOS process model. --- include/dosexe.h | 6 +- loader/dos/module.c | 181 ++++++++++++++++++++------------------------ 2 files changed, 81 insertions(+), 106 deletions(-) diff --git a/include/dosexe.h b/include/dosexe.h index e3fc3a1bbae..de4f3b6cd58 100644 --- a/include/dosexe.h +++ b/include/dosexe.h @@ -26,7 +26,6 @@ typedef struct _DOSTASK { WORD init_cs,init_ip,init_ss,init_sp; WORD xms_seg; WORD dpmi_seg,dpmi_sel,dpmi_flag; - HMODULE16 hModule; char mm_name[128]; int mm_fd; HANDLE hReadPipe,hXPipe,hConInput,hConOutput; @@ -62,10 +61,7 @@ extern LPDOSTASK MZ_AllocDPMITask( void ); #define V86_FLAG 0x00020000 -extern BOOL MZ_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmdline, LPCSTR env, - LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, - BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, - LPPROCESS_INFORMATION info ); +extern BOOL MZ_LoadImage( HMODULE module, HANDLE hFile, LPCSTR filename ); extern LPDOSTASK MZ_Current( void ); extern int DOSVM_Enter( CONTEXT86 *context ); extern void DOSVM_Wait( int read_pipe, HANDLE hObject ); diff --git a/loader/dos/module.c b/loader/dos/module.c index 98fed055f5e..8fa92518da5 100644 --- a/loader/dos/module.c +++ b/loader/dos/module.c @@ -55,15 +55,26 @@ DEFAULT_DEBUG_CHANNEL(module) #define SEG16(ptr,seg) ((LPVOID)((BYTE*)ptr+((DWORD)(seg)<<4))) #define SEGPTR16(ptr,segptr) ((LPVOID)((BYTE*)ptr+((DWORD)SELECTOROF(segptr)<<4)+OFFSETOF(segptr))) -static void MZ_InitPSP( LPVOID lpPSP, LPCSTR cmdline, WORD env ) +static LPDOSTASK dos_current; + +static void MZ_Launch(void); + +static void MZ_CreatePSP( LPVOID lpPSP, WORD env ) { PDB16*psp=lpPSP; - const char*cmd=cmdline?strchr(cmdline,' '):NULL; psp->int20=0x20CD; /* int 20 */ /* some programs use this to calculate how much memory they need */ psp->nextParagraph=0x9FFF; psp->environment=env; + /* FIXME: more PSP stuff */ +} + +static void MZ_FillPSP( LPVOID lpPSP, LPCSTR cmdline ) +{ + PDB16*psp=lpPSP; + const char*cmd=cmdline?strchr(cmdline,' '):NULL; + /* copy parameters */ if (cmd) { #if 0 @@ -74,8 +85,7 @@ static void MZ_InitPSP( LPVOID lpPSP, LPCSTR cmdline, WORD env ) strcpy(psp->cmdLine+1,cmd); psp->cmdLine[psp->cmdLine[0]+1]='\r'; } else psp->cmdLine[1]='\r'; - /* FIXME: integrate the memory stuff from Wine (msdos/dosmem.c) */ - /* FIXME: integrate the PDB stuff from Wine (loader/task.c) */ + /* FIXME: more PSP stuff */ } /* default INT 08 handler: increases timer tick counter but not much more */ @@ -184,8 +194,6 @@ static WORD MZ_InitEnvironment( LPDOSTASK lpDosTask, LPCSTR env, LPCSTR name ) static BOOL MZ_InitMemory( LPDOSTASK lpDosTask ) { - int x; - if (lpDosTask->img) return TRUE; /* already allocated */ /* allocate 1MB+64K shared memory */ @@ -200,8 +208,7 @@ static BOOL MZ_InitMemory( LPDOSTASK lpDosTask ) lpDosTask->mm_fd=open(lpDosTask->mm_name,O_RDWR|O_CREAT /* |O_TRUNC */,S_IRUSR|S_IWUSR); if (lpDosTask->mm_fd<0) ERR("file %s could not be opened\n",lpDosTask->mm_name); /* expand file to 1MB+64K */ - lseek(lpDosTask->mm_fd,0x110000-1,SEEK_SET); - x=0; write(lpDosTask->mm_fd,&x,1); + ftruncate(lpDosTask->mm_fd,0x110000); /* map it in */ lpDosTask->img=mmap(NULL,0x110000-START_OFFSET,PROT_READ|PROT_WRITE,MAP_SHARED,lpDosTask->mm_fd,0); #endif @@ -213,23 +220,34 @@ static BOOL MZ_InitMemory( LPDOSTASK lpDosTask ) /* initialize the memory */ TRACE("Initializing DOS memory structures\n"); - DOSMEM_Init(lpDosTask->hModule); + DOSMEM_Init(TRUE); MZ_InitHandlers(lpDosTask); MZ_InitXMS(lpDosTask); MZ_InitDPMI(lpDosTask); return TRUE; } -static BOOL MZ_LoadImage( HANDLE hFile, LPCSTR filename, LPCSTR cmdline, - LPCSTR env, LPDOSTASK lpDosTask, NE_MODULE *pModule ) +BOOL MZ_LoadImage( HMODULE module, HANDLE hFile, LPCSTR filename ) { - IMAGE_DOS_HEADER mz_header; - DWORD image_start,image_size,min_size,max_size,avail; - BYTE*psp_start,*load_start; - int x,old_com=0; - SEGPTR reloc; - WORD env_seg; - DWORD len; + LPDOSTASK lpDosTask = dos_current; + IMAGE_NT_HEADERS *win_hdr = PE_HEADER(module); + IMAGE_DOS_HEADER mz_header; + DWORD image_start,image_size,min_size,max_size,avail; + BYTE*psp_start,*load_start; + int x, old_com=0, alloc=0; + SEGPTR reloc; + WORD env_seg; + DWORD len; + + win_hdr->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; + win_hdr->OptionalHeader.AddressOfEntryPoint = (LPBYTE)MZ_Launch - (LPBYTE)module; + + if (!lpDosTask) { + alloc=1; + lpDosTask = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DOSTASK)); + lpDosTask->mm_fd = -1; + dos_current = lpDosTask; + } SetFilePointer(hFile,0,NULL,FILE_BEGIN); if ( !ReadFile(hFile,&mz_header,sizeof(mz_header),&len,NULL) @@ -255,7 +273,7 @@ static BOOL MZ_LoadImage( HANDLE hFile, LPCSTR filename, LPCSTR cmdline, MZ_InitMemory(lpDosTask); /* allocate environment block */ - env_seg=MZ_InitEnvironment(lpDosTask,env,filename); + env_seg=MZ_InitEnvironment(lpDosTask,GetEnvironmentStringsA(),filename); /* allocate memory for the executable */ TRACE("Allocating DOS memory (min=%ld, max=%ld)\n",min_size,max_size); @@ -263,25 +281,25 @@ static BOOL MZ_LoadImage( HANDLE hFile, LPCSTR filename, LPCSTR cmdline, if (availmax_size) avail=max_size; psp_start=DOSMEM_GetBlock(avail,&lpDosTask->psp_seg); if (!psp_start) { ERR("error allocating DOS memory\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; + goto load_error; } lpDosTask->load_seg=lpDosTask->psp_seg+(old_com?0:PSP_SIZE); load_start=psp_start+(PSP_SIZE<<4); - MZ_InitPSP(psp_start, cmdline, env_seg); + MZ_CreatePSP(psp_start, env_seg); /* load executable image */ TRACE("loading DOS %s image, %08lx bytes\n",old_com?"COM":"EXE",image_size); SetFilePointer(hFile,image_start,NULL,FILE_BEGIN); if (!ReadFile(hFile,load_start,image_size,&len,NULL) || len != image_size) { SetLastError(ERROR_BAD_FORMAT); - return FALSE; + goto load_error; } if (mz_header.e_crlc) { @@ -292,7 +310,7 @@ static BOOL MZ_LoadImage( HANDLE hFile, LPCSTR filename, LPCSTR cmdline, for (x=0; xload_seg; } @@ -303,20 +321,40 @@ static BOOL MZ_LoadImage( HANDLE hFile, LPCSTR filename, LPCSTR cmdline, lpDosTask->init_ss=lpDosTask->load_seg+mz_header.e_ss; lpDosTask->init_sp=mz_header.e_sp; - TRACE("entry point: %04x:%04x\n",lpDosTask->init_cs,lpDosTask->init_ip); - return TRUE; + TRACE("entry point: %04x:%04x\n",lpDosTask->init_cs,lpDosTask->init_ip); + + if (!MZ_InitTask(lpDosTask)) { + MZ_KillTask(lpDosTask); + SetLastError(ERROR_GEN_FAILURE); + return FALSE; + } + + return TRUE; + +load_error: + if (alloc) { + dos_current = NULL; + 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 FALSE; } LPDOSTASK MZ_AllocDPMITask( void ) { - LPDOSTASK lpDosTask = calloc(1, sizeof(DOSTASK)); + LPDOSTASK lpDosTask = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DOSTASK)); - if (lpDosTask) { - lpDosTask->img=NULL; lpDosTask->mm_name[0]=0; lpDosTask->mm_fd=-1; - - MZ_InitMemory(lpDosTask); - } - return lpDosTask; + if (lpDosTask) { + lpDosTask->mm_fd = -1; + dos_current = lpDosTask; + MZ_InitMemory(lpDosTask); + } + return lpDosTask; } static void MZ_InitTimer( LPDOSTASK lpDosTask, int ver ) @@ -340,20 +378,18 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask ) int write_fd[2],x_fd; pid_t child; char *fname,*farg,arg[16],fproc[64],path[256],*fpath; - SECURITY_ATTRIBUTES attr={sizeof(attr),NULL,TRUE}; struct get_read_fd_request *r_req = get_req_buffer(); struct get_write_fd_request *w_req = get_req_buffer(); if (!lpDosTask) return FALSE; /* create pipes */ - /* this happens in the wrong process context, so we have to let the new process - inherit it... (FIXME: call MZ_InitTask in the right process context) */ - if (!CreatePipe(&(lpDosTask->hReadPipe),&(lpDosTask->hXPipe),&attr,0)) return FALSE; + if (!CreatePipe(&(lpDosTask->hReadPipe),&(lpDosTask->hXPipe),NULL,0)) return FALSE; if (pipe(write_fd)<0) { CloseHandle(lpDosTask->hReadPipe); CloseHandle(lpDosTask->hXPipe); return FALSE; } + r_req->handle = lpDosTask->hReadPipe; server_call_fd( REQ_GET_READ_FD, -1, &lpDosTask->read_pipe ); w_req->handle = lpDosTask->hXPipe; @@ -377,7 +413,7 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask ) fname=fproc; farg=arg; } - TRACE("Loading DOS VM support module (hmodule=%04x)\n",lpDosTask->hModule); + TRACE("Loading DOS VM support module\n"); if ((child=fork())<0) { close(write_fd[0]); close(lpDosTask->read_pipe); @@ -443,64 +479,15 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask ) return TRUE; } -#if 0 -BOOL MZ_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmdline, LPCSTR env, - LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, - BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, - LPPROCESS_INFORMATION info ) +static void MZ_Launch(void) { - LPDOSTASK lpDosTask = NULL; /* keep gcc from complaining */ - HMODULE16 hModule; - PDB *pdb = PROCESS_Current(); - TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() ); - NE_MODULE *pModule = pTask ? NE_GetPtr( pTask->hModule ) : NULL; - int alloc = !(pModule && pModule->dos_image); + LPDOSTASK lpDosTask = MZ_Current(); + BYTE *psp_start = (BYTE*)lpDosTask->img + ((DWORD)lpDosTask->psp_seg << 4); - if (alloc && (lpDosTask = calloc(1, sizeof(DOSTASK))) == NULL) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } + MZ_FillPSP(psp_start, GetCommandLineA()); - if ((!env)&&pdb) env = pdb->env_db->environ; - if (alloc) { - if ((hModule = MODULE_CreateDummyModule(filename, 0)) < 32) { - SetLastError(hModule); - return FALSE; - } - lpDosTask->hModule = hModule; - - pModule = (NE_MODULE *)GlobalLock16(hModule); - pModule->lpDosTask = lpDosTask; - - lpDosTask->img=NULL; lpDosTask->mm_name[0]=0; lpDosTask->mm_fd=-1; - } else lpDosTask=pModule->lpDosTask; - if (!MZ_LoadImage( hFile, filename, cmdline, env, lpDosTask, pModule )) { - if (alloc) { - 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 FALSE; - } - if (alloc) { - pModule->dos_image = lpDosTask->img; - if (!MZ_InitTask( lpDosTask )) { - MZ_KillTask( lpDosTask ); - /* FIXME: cleanup hModule */ - SetLastError(ERROR_GEN_FAILURE); - return FALSE; - } - inherit = TRUE; /* bad hack for inheriting the CreatePipe... */ - if (!PROCESS_Create( pModule, hFile, cmdline, env, - psa, tsa, inherit, flags, startup, info )) - return FALSE; - } - return TRUE; + DOSVM_Enter(NULL); } -#endif void MZ_KillTask( LPDOSTASK lpDosTask ) { @@ -541,15 +528,7 @@ void MZ_KillTask( LPDOSTASK lpDosTask ) LPDOSTASK MZ_Current( void ) { - TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() ); - NE_MODULE *pModule = pTask ? NE_GetPtr( pTask->hModule ) : NULL; - - GlobalUnlock16( GetCurrentTask() ); - - if (pModule) - return pModule->lpDosTask; - - return NULL; + return dos_current; } #else /* !MZ_SUPPORTED */