⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 task.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 2 页
字号:
    {      COUNT rc;      UBYTE UMBstate = uppermem_link;      UBYTE orig_mem_access = mem_access_mode;            if (mode & 0x80)      {        mem_access_mode |= 0x80;        DosUmbLink(1);            /* link in UMB's */      }            rc = ChildEnv(exp, &env, namep);            /* COMFILES will always be loaded in largest area. is that true TE */      /* yes, see RBIL, int21/ah=48 -- Bart */      if (rc == SUCCESS)        rc = ExecMemLargest(&asize, com_size);            if (rc == SUCCESS)        /* Allocate our memory and pass back any errors         */        rc = ExecMemAlloc(asize, &mem, &asize);      if (rc != SUCCESS)        DosMemFree(env);      if (mode & 0x80)      {        DosUmbLink(UMBstate);       /* restore link state */        mem_access_mode = orig_mem_access;        mode &= 0x7f;      }      if (rc != SUCCESS)        return rc;      ++mem;    }    else      mem = exp->load.load_seg;  }#ifdef DEBUG  printf("DosComLoader. Loading '%S' at %04x\n", namep, mem);#endif  /* Now load the executable                              */  {    BYTE FAR *sp;    if (mode == OVERLAY)  /* memory already allocated */      sp = MK_FP(mem, 0);    else                  /* test the filesize against the allocated memory */      sp = MK_FP(mem, sizeof(psp));    /* MS DOS always only loads the very first 64KB - sizeof(psp) bytes.       -- 1999/04/21 ska */    /* rewind to start */    SftSeek(fd, 0, 0);    /* read everything, but at most 64K - sizeof(PSP)             */    DosRWSft(fd, 0xff00, sp, XFR_READ);    DosCloseSft(fd, FALSE);  }  if (mode == OVERLAY)    return SUCCESS;    {    UWORD fcbcode;    psp FAR *p;    /* point to the PSP so we can build it                  */    setvec(0x22, (intvec)MK_FP(user_r->CS, user_r->IP));    child_psp(mem, cu_psp, mem + asize);    fcbcode = patchPSP(mem - 1, env, exp, namep);    /* set asize to end of segment */    if (asize > 0x1000)      asize = 0x1000;    if (asize < 0x11)      return DE_NOMEM;    asize -= 0x11;    /* CP/M compatibility--size of first segment for .COM files       while preserving the far call to 0:00c0 +       copy in HMA at ffff:00d0 */    p = MK_FP(mem, 0);    p->ps_reentry = MK_FP(0xc - asize, asize << 4);    asize <<= 4;    asize += 0x10e;    exp->exec.stack = MK_FP(mem, asize);    exp->exec.start_addr = MK_FP(mem, 0x100);    *((UWORD FAR *) MK_FP(mem, asize)) = (UWORD) 0;    load_transfer(mem, exp, fcbcode, mode);  }  return SUCCESS;}VOID return_user(void){  psp FAR *p, FAR * q;  REG COUNT i;  iregs FAR *irp;/*  long j;*/  /* restore parent                                       */  p = MK_FP(cu_psp, 0);  /* When process returns - restore the isv               */  setvec(0x22, p->ps_isv22);  setvec(0x23, p->ps_isv23);  setvec(0x24, p->ps_isv24);  /* And free all process memory if not a TSR return      */  network_redirector(REM_PROCESS_END);  /* might be a good idea to do that after closing     but doesn't help NET either TE */  if (!tsr)  {    network_redirector(REM_CLOSEALL);    for (i = 0; i < p->ps_maxfiles; i++)    {      DosClose(i);    }    FcbCloseAll();    FreeProcessMem(cu_psp);  }  cu_psp = p->ps_parent;  q = MK_FP(cu_psp, 0);  irp = (iregs FAR *) q->ps_stack;  irp->CS = FP_SEG(p->ps_isv22);  irp->IP = FP_OFF(p->ps_isv22);  if (InDOS)    --InDOS;  exec_user((iregs FAR *) q->ps_stack, 0);}COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd){  UWORD mem, env, start_seg, asize = 0;  UWORD exe_size;  {    UWORD image_size;    /* compute image size by removing the offset from the   */    /* number pages scaled to bytes plus the remainder and  */    /* the psp                                              */    /*  First scale the size and remove the offset          */    if (ExeHeader.exPages >= 2048)      return DE_INVLDDATA; /* we're not able to get >=1MB in dos memory */    image_size = ExeHeader.exPages * 32 - ExeHeader.exHeaderSize;    /* We should not attempt to allocate       memory if we are overlaying the current process, because the new       process will simply re-use the block we already have allocated.       Jun 11, 2000 - rbc */        if ((mode & 0x7f) != OVERLAY)    {      UBYTE UMBstate = uppermem_link;      UBYTE orig_mem_access = mem_access_mode;      COUNT rc;            /* and finally add in the psp size                      */      image_size += sizeof(psp) / 16;        /*TE 03/20/01 */      exe_size = image_size + ExeHeader.exMinAlloc;            /* Clone the environement and create a memory arena     */      if (mode & 0x80)      {        DosUmbLink(1);          /* link in UMB's */        mem_access_mode |= 0x80;      }            rc = ChildEnv(exp, &env, namep);            if (rc == SUCCESS)        /* Now find out how many paragraphs are available       */        rc = ExecMemLargest(&asize, exe_size);            exe_size = image_size + ExeHeader.exMaxAlloc;      /* second test is for overflow (avoiding longs) --         exMaxAlloc can be high */      if (exe_size > asize || exe_size < image_size)        exe_size = asize;            /* TE if ExeHeader.exMinAlloc == ExeHeader.exMaxAlloc == 0,         DOS will allocate the largest possible memory area         and load the image as high as possible into it.         discovered (and after that found in RBIL), when testing NET */            if ((ExeHeader.exMinAlloc | ExeHeader.exMaxAlloc) == 0)        exe_size = asize;            /* Allocate our memory and pass back any errors         */      if (rc == SUCCESS)        rc = ExecMemAlloc(exe_size, &mem, &asize);            if (rc != SUCCESS)        DosMemFree(env);            if (mode & 0x80)      {        mem_access_mode = orig_mem_access; /* restore old situation */        DosUmbLink(UMBstate);     /* restore link state */      }      if (rc != SUCCESS)        return rc;            mode &= 0x7f; /* forget about high loading from now on */      #ifdef DEBUG      printf("DosExeLoader. Loading '%S' at %04x\n", namep, mem);#endif            /* memory found large enough - continue processing      */      ++mem;      /* /// Added open curly brace and "else" clause.  We should not attempt   to allocate memory if we are overlaying the current process, because   the new process will simply re-use the block we already have allocated.   This was causing execl() to fail in applications which use it to   overlay (replace) the current exe file with a new one.   Jun 11, 2000 - rbc */    }    else /* !!OVERLAY */    {      mem = exp->load.load_seg;    }    /* Now load the executable                              */    /* offset to start of image                             */    if (SftSeek(fd, ExeHeader.exHeaderSize * 16UL, 0) != SUCCESS)    {      if (mode != OVERLAY)      {        DosMemFree(--mem);        DosMemFree(env);      }      return DE_INVLDDATA;    }        /* create the start seg for later computations          */    start_seg = mem;    exe_size = image_size;    if (mode != OVERLAY)    {      exe_size -= sizeof(psp) / 16;      start_seg += sizeof(psp) / 16;      if (exe_size > 0 && (ExeHeader.exMinAlloc | ExeHeader.exMaxAlloc) == 0)      {        mcb FAR *mp = MK_FP(mem - 1, 0);                /* then the image should be placed as high as possible */        start_seg += mp->m_size - image_size;      }    }  }  /* read in the image in 32256 chunks                      */  {    int nBytesRead, toRead = CHUNK;    seg sp = start_seg;    while (1)    {      if (exe_size < CHUNK/16)        toRead = exe_size*16;      nBytesRead = (int)DosRWSft(fd, toRead, MK_FP(sp, 0), XFR_READ);      if (nBytesRead < toRead || exe_size <= CHUNK/16)        break;      sp += CHUNK/16;      exe_size -= CHUNK/16;    }  }  {                             /* relocate the image for new segment                   */    COUNT i;    UWORD reloc[2];    seg FAR *spot;    SftSeek(fd, ExeHeader.exRelocTable, 0);    for (i = 0; i < ExeHeader.exRelocItems; i++)    {      if (DosRWSft          (fd, sizeof(reloc), (VOID FAR *) & reloc[0], XFR_READ) != sizeof(reloc))      {        if (mode != OVERLAY)        {          DosMemFree(--mem);          DosMemFree(env);        }        return DE_INVLDDATA;      }      if (mode == OVERLAY)      {        spot = MK_FP(reloc[1] + mem, reloc[0]);        *spot += exp->load.reloc;      }      else      {        /*      spot = MK_FP(reloc[1] + mem + 0x10, reloc[0]); */        spot = MK_FP(reloc[1] + start_seg, reloc[0]);        *spot += start_seg;      }    }  }  /* and finally close the file                           */  DosCloseSft(fd, FALSE);  /* exit here for overlay                                */  if (mode == OVERLAY)    return SUCCESS;  {    UWORD fcbcode;    /* point to the PSP so we can build it                  */    setvec(0x22, (intvec)MK_FP(user_r->CS, user_r->IP));    child_psp(mem, cu_psp, mem + asize);    fcbcode = patchPSP(mem - 1, env, exp, namep);    exp->exec.stack =      MK_FP(ExeHeader.exInitSS + start_seg, ExeHeader.exInitSP);    exp->exec.start_addr =      MK_FP(ExeHeader.exInitCS + start_seg, ExeHeader.exInitIP);    /* Transfer control to the executable                   */    load_transfer(mem, exp, fcbcode, mode);  }  return SUCCESS;}/* mode = LOAD or EXECUTE   ep = EXE block   lp = filename to load (string)   leb = local copy of exe block */COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp){  COUNT rc;  COUNT fd;  if ((mode & 0x7f) > 3 || (mode & 0x7f) == 2)    return DE_INVLDFMT;   fmemcpy(&TempExeBlock, ep, sizeof(exec_blk));  /* If file not found - free ram and return error        */  if (IsDevice(lp) ||        /* we don't want to execute C:>NUL */      (fd = (short)DosOpenSft(lp, O_LEGACY | O_OPEN | O_RDONLY, 0)) < 0)  {    return DE_FILENOTFND;  }    rc = (int)DosRWSft(fd, sizeof(exe_header), (BYTE FAR *)&ExeHeader, XFR_READ);  if (rc == sizeof(exe_header) &&      (ExeHeader.exSignature == MAGIC || ExeHeader.exSignature == OLD_MAGIC))  {    rc = DosExeLoader(lp, &TempExeBlock, mode, fd);  }  else if (rc != 0)  {    rc = DosComLoader(lp, &TempExeBlock, mode, fd);  }  DosCloseSft(fd, FALSE);  if (mode == LOAD && rc == SUCCESS)    fmemcpy(ep, &TempExeBlock, sizeof(exec_blk));  return rc;}#include "config.h" /* config structure definition *//* start process 0 (the shell) */VOID ASMCFUNC P_0(struct config FAR *Config){  BYTE *tailp, *endp;  exec_blk exb;  UBYTE mode = Config->cfgP_0_startmode;  /* build exec block and save all parameters here as init part will vanish! */  exb.exec.fcb_1 = exb.exec.fcb_2 = (fcb FAR *)-1L;  exb.exec.env_seg = DOS_PSP + 8;  fstrcpy(Shell, MK_FP(FP_SEG(Config), Config->cfgInit));  /* join name and tail */  fstrcpy(Shell + strlen(Shell), MK_FP(FP_SEG(Config), Config->cfgInitTail));  endp =  Shell + strlen(Shell);  for ( ; ; )   /* endless shell load loop - reboot or shut down to exit it! */  {    BYTE *p;    /* if there are no parameters, point to end without "\r\n" */    if((tailp = strchr(Shell,'\t')) == NULL &&       (tailp = strchr(Shell, ' ')) == NULL)        tailp = endp - 2;    /* shift tail to right by 2 to make room for '\0', ctCount */    for (p = endp - 1; p >= tailp; p--)      *(p + 2) = *p;    /* terminate name and tail */    *tailp =  *(endp + 2) = '\0';    /* ctCount: just past '\0' do not count the "\r\n" */    exb.exec.cmd_line = (CommandTail *)(tailp + 1);    exb.exec.cmd_line->ctCount = endp - tailp - 2;#ifdef DEBUG    printf("Process 0 starting: %s%s\n\n", Shell, tailp + 2);#endif    res_DosExec(mode, &exb, Shell);    put_string("Bad or missing Command Interpreter: "); /* failure _or_ exit */    put_string(Shell);    put_string(tailp + 2);    put_string(" Enter the full shell command line: ");    endp = Shell + res_read(STDIN, Shell, NAMEMAX);    *endp = '\0';                             /* terminate string for strchr */  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -