Beispiel #1
0
static struct device_info *info_device_ioctl (int unitnum, struct device_info *di, int dummy1, int dummy2)
{
    DEBUG_LOG ("SCSIDEV: unit = %d: info_device_ioctl\n", unitnum);

    if (unitnum < total_drives) {
	struct scsidevdata *sdd = &drives[unitnum];

	media_check (sdd);

	di->bus		    = 0;
	di->target	    = unitnum;
	di->lun		    = 0;
	di->media_inserted  = media_check (sdd);
	di->write_protected = 1;
	di->bytespersector  = 2048;
	di->cylinders	    = 1;
	di->type	    = INQ_ROMD; /* We only support CD/DVD drives for now */
	di->unitnum	    = unitnum + 1;
	/* TODO: Create a more informative device label */
	sprintf (di->label, "[%s]", sdd->name);
    } else {
	di = 0;
    }

    return di;
}
Beispiel #2
0
VOID FatGetDrvData(COUNT drive, COUNT FAR * spc, COUNT FAR * bps,
                   COUNT FAR * nc, BYTE FAR ** mdp)
{
  struct dpb *dpbp;

  printf("FGDD\n");

  /* first check for valid drive                                  */
  if (drive < 0 || drive > NDEVS)
  {
    *spc = -1;
    return;
  }

  /* next - "log" in the drive                                    */
  drive = (drive == 0 ? default_drive : drive - 1);
  dpbp = (struct dpb *)CDSp->cds_table[drive].cdsDpb;
  dpbp->dpb_flags = -1;
  if ((media_check(dpbp) < 0))
  {
    *spc = -1;
    return;
  }

  /* get the data vailable from dpb                       */
  *nc = dpbp->dpb_size;
  *spc = dpbp->dpb_clsmask + 1;
  *bps = dpbp->dpb_secsize;

  /* Point to the media desctriptor fotr this drive               */
  *mdp = &(dpbp->dpb_mdb);
}
Beispiel #3
0
COUNT DosChangeDir(BYTE FAR * s)
{
  REG struct dpb *dpbp;
  REG struct cds FAR *cdsp;
  REG COUNT drive;
  struct f_node FAR *fp;
  COUNT ret;
  /* Parse and extract drive              */
  if (*(s + 1) == ':')
  {
    drive = *s - '@';
    if (drive > 26)
      drive -= 'a' - 'A';
  }
  else
    drive = 0;

  /* next - "log" in the drive            */
  drive = (drive == 0 ? default_drive : drive - 1);

  cdsp = &CDSp->cds_table[drive];

  current_ldt = cdsp;

  if (cdsp->cdsFlags & 0x8000)
  {
    ret = dos_cd(cdsp, s);
    return ret;
  }

  /* first check for valid drive          */
  if (cdsp->cdsDpb == 0)
    return DE_INVLDDRV;

  /* test for path existance from fs      */
  if ((fp = dir_open((BYTE FAR *) s)) == (struct f_node FAR *)0)
    return DE_PATHNOTFND;
  else
    dir_close(fp);

/*  if (drive < 0 || drive > nblkdev)
   return DE_INVLDDRV; */

  dpbp = (struct dpb *)cdsp->cdsDpb;
  if ((media_check(dpbp) < 0))
    return DE_INVLDDRV;
  /* now get fs to change to new          */
  /* directory                            */
  ret = dos_cd(cdsp, s);
  return ret;
}
Beispiel #4
0
VOID DosGetFree(COUNT drive, COUNT FAR * spc, COUNT FAR * navc, COUNT FAR * bps, COUNT FAR * nc)
{
  struct dpb *dpbp;
  struct cds FAR *cdsp;
  static char rg[8];

  /* next - "log" in the drive            */
  drive = (drive == 0 ? default_drive : drive - 1);

  cdsp = &CDSp->cds_table[drive];
  if (cdsp->cdsFlags & 0x8000)
  {
    int2f_Remote_call(REM_GETSPACE, 0, 0, 0, cdsp, 0, &rg);

    *spc = (COUNT) rg[0];
    *navc = (COUNT) rg[2];
    *bps = (COUNT) rg[4];
    *nc = (COUNT) rg[6];
    return;
  }

  /* first check for valid drive          */
  if (drive < 0 || drive > lastdrive)
  {
    *spc = -1;
    return;
  }

  dpbp = (struct dpb *)CDSp->cds_table[drive].cdsDpb;
  if (dpbp == 0)
  {
    *spc = -1;
    return;
  }

  if ((media_check(dpbp) < 0))
  {
    *spc = -1;
    return;
  }

  /* get the data vailable from dpb       */
  *nc = dpbp->dpb_size;
  *spc = dpbp->dpb_clsmask + 1;
  *bps = dpbp->dpb_secsize;

  /* now tell fs to give us free cluster  */
  /* count                                */
  *navc = dos_free(dpbp);
}
Beispiel #5
0
COUNT dos_findnext(void)
{
  REG f_node_ptr fnp;
  REG dmatch *dmp = &sda_tmp_dm;

  /* Allocate an fnode if possible - error return (0) if not.     */
  if ((fnp = get_f_node()) == (f_node_ptr) 0)
  {
    return DE_NFILES;
  }

  memset(fnp, 0, sizeof(*fnp));

  /* Force the fnode into read-write mode                         */
  fnp->f_mode = RDWR;

  /* Select the default to help non-drive specified path          */
  /* searches...                                                  */
  fnp->f_dpb = get_dpb(dmp->dm_drive);
  if (media_check(fnp->f_dpb) < 0)
  {
    release_f_node(fnp);
    return DE_NFILES;
  }

  dir_init_fnode(fnp, dmp->dm_dircluster);

  /* Search through the directory to find the entry, but do a     */
  /* seek first.                                                  */
  fnp->f_diroff = dmp->dm_entry;

  /* Loop through the directory                                   */
  while (dir_read(fnp) == 1)
  {
    ++dmp->dm_entry;
    ++fnp->f_diroff;
    if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED &&
      !(fnp->f_dir.dir_attrib & D_VOLID) &&
      fcmp_wild(dmp->dm_name_pat, fnp->f_dir.dir_name, FNAME_SIZE+FEXT_SIZE) &&
      /*
           MSD Command.com uses FCB FN 11 & 12 with attrib set to 0x16.
           Bits 0x21 seem to get set some where in MSD so Rd and Arc
           files are returned. RdOnly + Archive bits are ignored
       */
      /* Test the attribute as the final step */
      !(~dmp->dm_attr_srch & (D_DIR|D_SYSTEM|D_HIDDEN) & fnp->f_dir.dir_attrib))
    {
      /* If found, transfer it to the dmatch structure */
      dmp->dm_dircluster = fnp->f_dirstart;
      memcpy(&SearchDir, &fnp->f_dir, sizeof(struct dirent));
      /* return the result */
      release_f_node(fnp);
      return SUCCESS;
    }
  }
  FDirDbgPrintf(("dos_findnext: %11s\n", fnp->f_dir.dir_name));
  /* return the result                                            */
  release_f_node(fnp);

  return DE_NFILES;
}
Beispiel #6
0
f_node_ptr dir_open(register const char *dirname)
{
  f_node_ptr fnp;
  int i;
  char fcbname[FNAME_SIZE + FEXT_SIZE];

  FDirDbgPrintf(("dir_open: trying to open %s\n", dirname));
  
  /* Allocate an fnode if possible - error return (0) if not.     */
  if ((fnp = get_f_node()) == (f_node_ptr) 0)
  {
    FDirDbgPrintf(("dir_open: failed to get f_node\n"));
    return (f_node_ptr) 0;
  }

  /* Force the fnode into read-write mode                         */
  fnp->f_mode = RDWR;

  /* determine what drive and dpb we are using...                 */
  fnp->f_dpb = get_dpb(dirname[0]-'A');
  /* Perform all directory common handling after all special      */
  /* handling has been performed.                                 */

  if (media_check(fnp->f_dpb) < 0)
  {
    FDirDbgPrintf(("dir_open: media_check failed\n"));
    release_f_node(fnp);
    return (f_node_ptr) 0;
  }

  /* Walk the directory tree to find the starting cluster         */
  /*                                                              */
  /* Start from the root directory (dirstart = 0)                 */

  /* The CDS's cdsStartCls may be used to shorten the search
     beginning at the CWD, see mapPath() and CDS.H in order
     to enable this behaviour there.
           -- 2001/09/04 ska*/

  dir_init_fnode(fnp, 0);

  dirname += 2;               /* Assume FAT style drive       */
  while(*dirname != '\0')
  {
    /* skip all path seperators                             */
    while (*dirname == '\\')
      ++dirname;
    /* don't continue if we're at the end                   */
    if (*dirname == '\0')
      break;

    /* Convert the name into an absolute name for           */
    /* comparison...                                        */

    memset(fcbname, ' ', FNAME_SIZE + FEXT_SIZE);

    for (i = 0; i < FNAME_SIZE + FEXT_SIZE; i++, dirname++)
    {
      char c = *dirname;
      if (c == '.')
        i = FNAME_SIZE - 1;
      else if (c != '\0' && c != '\\')
        fcbname[i] = c;
      else
        break;
    }

    /* Now search through the directory to  */
    /* find the entry...                    */
    i = FALSE;

    while (dir_read(fnp) == 1)
    {
      if (!(fnp->f_dir.dir_attrib & D_VOLID) &&
          fcbmatch(fcbname, fnp->f_dir.dir_name))
      {
        i = TRUE;
        break;
      }
      fnp->f_diroff++;
    }

    if (!i || !(fnp->f_dir.dir_attrib & D_DIR))
    {
      FDirDbgPrintf(("dir_open: no match found, returning failure\n"));
      release_f_node(fnp);
      return (f_node_ptr) 0;
    }
    else
    {
      /* make certain we've moved off */
      /* root                         */
      dir_init_fnode(fnp, getdstart(fnp->f_dpb, &fnp->f_dir));
    }
  }
  FDirDbgPrintf(("dir_open: returning, ok\n"));
  return fnp;
}
Beispiel #7
0
VOID int21_service(iregs FAR * r)
{
  COUNT rc = 0,
	  rc1;
  psp FAR *p = MK_FP(cu_psp, 0);
  void FAR *FP_DS_DX = MK_FP(r->DS, r->DX); /* this is saved so often,
                                               that this saves ~100 bytes */

    
#define CLEAR_CARRY_FLAG()  r->FLAGS &= ~FLG_CARRY
#define SET_CARRY_FLAG()    r->FLAGS |= FLG_CARRY

  p->ps_stack = (BYTE FAR *) r;

#ifdef DEBUG 
  if (bDumpRegs)
  {
    fbcopy((VOID FAR *) user_r, (VOID FAR *) & error_regs, sizeof(iregs));
    printf("System call (21h): %02x\n", user_r->AX);
    dump_regs = TRUE;
    dump();
  }
#endif

  if(r->AH >=0x38 && r->AH <= 0x4F)
      CLEAR_CARRY_FLAG();
      /* Clear carry by default for these functions */

dispatch:

  /* Check for Ctrl-Break */
  switch (r->AH)
  {
    default:
      if (!break_ena)
        break;
    case 0x01:
    case 0x02:
    case 0x03:
    case 0x04:
    case 0x05:
    case 0x08:
    case 0x09:
    case 0x0a:
    case 0x0b:
      if (control_break())
        handle_break();
  }

  /* The dispatch handler                                         */
  switch (r->AH)
  {
      /* int 21h common error handler                                 */
    case 0x64:
    error_invalid:
      r->AX = -DE_INVLDFUNC;
      goto error_out;
    error_exit:
      r->AX = -rc;
    error_out:
      CritErrCode = r->AX;  /* Maybe set */
      SET_CARRY_FLAG();
      break;

       /* case 0x00:   --> Simulate a DOS-4C-00 */

      /* Read Keyboard with Echo                      */
    case 0x01:
      r->AL = _sti(TRUE);
      sto(r->AL);
      break;

      /* Display Character                                            */
    case 0x02:
      sto(r->DL);
      break;

      /* Auxiliary Input                                                      */
    case 0x03:
     {
      COUNT scratch;
      GenericRead(STDAUX, 1, (BYTE FAR *) & r->AL, (COUNT FAR *) & scratch, TRUE);
      break;
     }

      /* Auxiliary Output                                                     */
    case 0x04:
     {
      COUNT scratch;
      DosWrite(STDAUX, 1, (BYTE FAR *) & r->DL, (COUNT FAR *) &scratch);
      break;
     }
      /* Print Character                                                      */
    case 0x05:
     {       
      COUNT scratch;       
      DosWrite(STDPRN, 1, (BYTE FAR *) & r->DL, (COUNT FAR *) &scratch);
      break;      
     }

      /* Direct Console I/O                                            */
    case 0x06:
      if (r->DL != 0xff)
        sto(r->DL);
      else if (StdinBusy())
      {
        r->AL = 0x00;
        r->FLAGS |= FLG_ZERO;
      }
      else
      {
        r->FLAGS &= ~FLG_ZERO;
        r->AL = _sti(FALSE);
      }
      break;

      /* Direct Console Input                                         */
    case 0x07:
      r->AL = _sti(FALSE);
      break;

      /* Read Keyboard Without Echo                                   */
    case 0x08:
      r->AL = _sti(TRUE);
      break;

      /* Display String                                               */
    case 0x09:
      {
        BYTE FAR * q;
        q = FP_DS_DX;
        while (*q != '$')
          ++q;
        DosWrite(STDOUT, FP_OFF(q) - FP_OFF(FP_DS_DX), FP_DS_DX, (COUNT FAR *) & UnusedRetVal);
      }
      r->AL = '$';
      break;

      /* Buffered Keyboard Input                                      */
    case 0x0a:
      sti_0a((keyboard FAR *) FP_DS_DX);
      break;

      /* Check Stdin Status                                           */
    case 0x0b:
      if (StdinBusy())
        r->AL = 0x00;
      else
        r->AL = 0xFF;
      break;

      /* Flush Buffer, Read Keayboard                                 */
    case 0x0c:
      KbdFlush();
      switch (r->AL)
      {
        case 0x01:
        case 0x06:
        case 0x07:
        case 0x08:
        case 0x0a:
          r->AH = r->AL;
          goto dispatch;

        default:
          r->AL = 0x00;
          break;
      }
      break;

      /* Reset Drive                                                  */
    case 0x0d:
      flush();
      break;

      /* Set Default Drive                                            */
    case 0x0e:
      r->AL = DosSelectDrv(r->DL);
      break;

    case 0x0f:
      if (FcbOpen(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x10:
      if (FcbClose(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x11:
      if (FcbFindFirst(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x12:
      if (FcbFindNext(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x13:
      if (FcbDelete(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x14:
      {
        if (FcbRead(FP_DS_DX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

    case 0x15:
      {
        if (FcbWrite(FP_DS_DX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

    case 0x16:
      if (FcbCreate(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x17:
      if (FcbRename(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    default:
#ifdef DEBUG
       printf("Unsupported INT21 AH = 0x%x, AL = 0x%x.\n", r->AH, r->AL);
#endif
      /* Fall through. */

    /* CP/M compatibility functions                                 */
    case 0x18:
    case 0x1d:
    case 0x1e:
    case 0x20:
#ifndef TSC
    case 0x61:
#endif
    case 0x6b:
      r->AL = 0;
      break;

      /* Get Default Drive                                            */
    case 0x19:
      r->AL = default_drive;
      break;

      /* Set DTA                                                      */
    case 0x1a:
      {
        psp FAR *p = MK_FP(cu_psp, 0);

        p->ps_dta = FP_DS_DX;
        dos_setdta(p->ps_dta);
      }
      break;

      /* Get Default Drive Data                                       */
    case 0x1b:
      {
        BYTE FAR *p;

        FatGetDrvData(0,
                      (COUNT FAR *) & r->AX,
                      (COUNT FAR *) & r->CX,
                      (COUNT FAR *) & r->DX,
                      (BYTE FAR **) & p);
        r->DS = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get Drive Data                                               */
    case 0x1c:
      {
        BYTE FAR *p;

        FatGetDrvData(r->DL,
                      (COUNT FAR *) & r->AX,
                      (COUNT FAR *) & r->CX,
                      (COUNT FAR *) & r->DX,
                      (BYTE FAR **) & p);
        r->DS = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get default DPB                                              */
      /* case 0x1f: see case 0x32 */

      /* Random read using FCB */
    case 0x21:
      {
        if (FcbRandomIO(FP_DS_DX, &CritErrCode, FcbRead))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Random write using FCB */
    case 0x22:
      {
        if (FcbRandomIO(FP_DS_DX, &CritErrCode, FcbWrite))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Get file size in records using FCB */
    case 0x23:
      if (FcbGetFileSize(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

      /* Set random record field in FCB */
    case 0x24:
      FcbSetRandom(FP_DS_DX);
      break;

      /* Set Interrupt Vector                                         */
    case 0x25:
      {
        VOID(INRPT FAR * p) () = FP_DS_DX;

        setvec(r->AL, p);
      }
      break;

      /* Dos Create New Psp                                           */
    case 0x26:
      {
        psp FAR *p = MK_FP(cu_psp, 0);

        new_psp((psp FAR *) MK_FP(r->DX, 0), p->ps_size);
      }
      break;

      /* Read random record(s) using FCB */
    case 0x27:
      {
        if (FcbRandomBlockRead(FP_DS_DX, r->CX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Write random record(s) using FCB */
    case 0x28:
      {
        if (FcbRandomBlockWrite(FP_DS_DX, r->CX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Parse File Name                                              */
    case 0x29:
      {
        BYTE FAR *lpFileName;

        lpFileName = MK_FP(r->DS, r->SI);
        r->AL = FcbParseFname(r->AL,
                              &lpFileName,
                              MK_FP(r->ES, r->DI));
        r->DS = FP_SEG(lpFileName);
        r->SI = FP_OFF(lpFileName);
      }
      break;

      /* Get Date                                                     */
    case 0x2a:
      DosGetDate(
                  (BYTE FAR *) & (r->AL),	/* WeekDay              */
                  (BYTE FAR *) & (r->DH),	/* Month                */
                  (BYTE FAR *) & (r->DL),	/* MonthDay             */
                  (COUNT FAR *) & (r->CX));	/* Year                 */
      break;

      /* Set Date                                                     */
    case 0x2b:
      rc = DosSetDate(
                       (BYTE FAR *) & (r->DH),	/* Month                */
                       (BYTE FAR *) & (r->DL),	/* MonthDay             */
                       (COUNT FAR *) & (r->CX));	/* Year                 */
      if (rc != SUCCESS)
        r->AL = 0xff;
      else
        r->AL = 0;
      break;

      /* Get Time                                                     */
    case 0x2c:
      DosGetTime(
                  (BYTE FAR *) & (r->CH),	/* Hour                 */
                  (BYTE FAR *) & (r->CL),	/* Minutes              */
                  (BYTE FAR *) & (r->DH),	/* Seconds              */
                  (BYTE FAR *) & (r->DL));	/* Hundredths           */
      break;

      /* Set Date                                                     */
    case 0x2d:
      rc = DosSetTime(
                       (BYTE FAR *) & (r->CH),	/* Hour                 */
                       (BYTE FAR *) & (r->CL),	/* Minutes              */
                       (BYTE FAR *) & (r->DH),	/* Seconds              */
                       (BYTE FAR *) & (r->DL));	/* Hundredths           */
      if (rc != SUCCESS)
        r->AL = 0xff;
      else
        r->AL = 0;
      break;

      /* Set verify flag                                              */
    case 0x2e:
      verify_ena = (r->AL ? TRUE : FALSE);
      break;

      /* Get DTA                                                      */
    case 0x2f:
      r->ES = FP_SEG(dta);
      r->BX = FP_OFF(dta);
      break;

      /* Get DOS Version                                              */
    case 0x30:
      r->AL = os_major;
      r->AH = os_minor;
      r->BH = OEM_ID;
      r->CH = REVISION_MAJOR;   /* JPP */
      r->CL = REVISION_MINOR;
      r->BL = REVISION_SEQ;
      
      if (ReturnAnyDosVersionExpected)  
      {
                            /* TE for testing purpose only and NOT 
                               to be documented:
                               return programs, who ask for version == XX.YY
                               exactly this XX.YY. 
                               this makes most MS programs more happy.
                            */
        UBYTE FAR *retp = MK_FP(r->cs, r->ip);
        
        if (     retp[0] == 0x3d  &&     /* cmp ax, xxyy */
                (retp[3] == 0x75 || retp[3] == 0x74)) /* je/jne error    */
        {
            r->AL = retp[1];
            r->AH = retp[2];
        }
        else if(retp[0] == 0x86 &&      /* xchg al,ah   */
                retp[1] == 0xc4 &&
                retp[2] == 0x3d &&      /* cmp ax, xxyy */
               (retp[5] == 0x75 || retp[5] == 0x74)) /* je/jne error    */                               
        {
            r->AL = retp[4];
            r->AH = retp[3];
        }                
            
      }
      
      break;

      /* Keep Program (Terminate and stay resident) */
    case 0x31:
      DosMemChange(cu_psp, r->DX < 6 ? 6 : r->DX, 0);
      return_mode = 3;
      return_code = r->AL;
      tsr = TRUE;
      return_user();
      break;

      /* Get default BPB */
    case 0x1f:
      /* Get DPB                                                      */
    case 0x32:
      /* r->DL is NOT changed by MS 6.22 */
      /* INT21/32 is documented to reread the DPB */
      {
      struct dpb FAR *dpb;  
      UCOUNT drv = r->DL;
      
      if (drv == 0 || r->AH == 0x1f) drv = default_drive;
      else          drv--;

      if (drv >= lastdrive)
      {
        r->AL = 0xFF;
        CritErrCode = 0x0f;
        break;
      }  
        
      dpb = CDSp->cds_table[drv].cdsDpb;
      if (dpb == 0 ||
          CDSp->cds_table[drv].cdsFlags & CDSNETWDRV)
      {
        r->AL = 0xFF;
        CritErrCode = 0x0f;
        break;
      }  
      dpb->dpb_flags = M_CHANGED;       /* force reread of drive BPB/DPB */
          
      if (media_check(dpb) < 0)
      {
          r->AL = 0xff;
          CritErrCode = 0x0f;
          break;
      }
      r->DS = FP_SEG(dpb);
      r->BX = FP_OFF(dpb);
      r->AL = 0;
      }

      break;
/*
    case 0x33:  
    see int21_syscall
*/
      /* Get InDOS flag                                               */
    case 0x34:
      {
        BYTE FAR *p;

        p = (BYTE FAR *) ((BYTE *) & InDOS);
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get Interrupt Vector                                         */
    case 0x35:
      {
        BYTE FAR *p;

        p = getvec((COUNT) r->AL);
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Dos Get Disk Free Space                                      */
    case 0x36:
      DosGetFree(
                  r->DL,
                  (COUNT FAR *) & r->AX,
                  (COUNT FAR *) & r->BX,
                  (COUNT FAR *) & r->CX,
                  (COUNT FAR *) & r->DX);
      break;

      /* Undocumented Get/Set Switchar                                */
    case 0x37:
      switch (r->AL)
      {
          /* Get switch character */
        case 0x00:
          r->DL = switchar;
          r->AL = 0x00;
          break;

          /* Set switch character */
        case 0x01:
          switchar = r->DL;
          r->AL = 0x00;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Get/Set Country Info                                         */
    case 0x38:
      {
      	UWORD cntry = r->AL;

      	if(cntry == 0)
      		cntry = (UWORD)-1;
      	else if(cntry == 0xff)
      		cntry = r->BX;

        if (0xffff == r->DX) {
        	/* Set Country Code */
            if((rc = DosSetCountry(cntry)) < 0)
        		goto error_invalid;
        } else {
        	/* Get Country Information */
            if((rc = DosGetCountryInformation(cntry, FP_DS_DX)) < 0)
        		goto error_invalid;
            /* HACK FIXME */
	    if(cntry == (UWORD)-1)
		cntry = 1;
            /* END OF HACK */
            r->AX = r->BX = cntry;
        }
      }
      break;

      /* Dos Create Directory                                         */
    case 0x39:
      rc = DosMkdir((BYTE FAR *) FP_DS_DX);
      if (rc != SUCCESS)
        goto error_exit;
      break;

      /* Dos Remove Directory                                         */
    case 0x3a:
      rc = DosRmdir((BYTE FAR *) FP_DS_DX);
      if (rc != SUCCESS)
        goto error_exit;
      break;

      /* Dos Change Directory                                         */
    case 0x3b:
      if ((rc = DosChangeDir((BYTE FAR *) FP_DS_DX)) < 0)
        goto error_exit;
      break;

      /* Dos Create File                                              */
    case 0x3c:
      if ((rc = DosCreat(FP_DS_DX, r->CX)) < 0)
        goto error_exit;
      else
        r->AX = rc;
      break;

      /* Dos Open                                                     */
    case 0x3d:
      if ((rc = DosOpen(FP_DS_DX, r->AL)) < 0)
        goto error_exit;
      else
        r->AX = rc;
      break;

      /* Dos Close                                                    */
    case 0x3e:
      if ((rc = DosClose(r->BX)) < 0)
        goto error_exit;
      break;

      /* Dos Read                                                     */
    case 0x3f:
      rc1 = DosRead(r->BX, r->CX, FP_DS_DX, (COUNT FAR *) & rc);
      if (rc != SUCCESS)
        goto error_exit;
      else
        r->AX = rc1;
      break;

      /* Dos Write                                                    */
    case 0x40:
      rc1 = DosWrite(r->BX, r->CX, FP_DS_DX, (COUNT FAR *) & rc);
      if (rc != SUCCESS)
        goto error_exit;
      else
        r->AX = rc1;
      break;

      /* Dos Delete File                                              */
    case 0x41:
      rc = DosDelete((BYTE FAR *) FP_DS_DX);
      if (rc < 0)
        goto error_exit;
      break;

      /* Dos Seek                                                     */
    case 0x42:
      {
      ULONG lrc;
      if ((rc = DosSeek(r->BX, (LONG) ((((LONG) (r->CX)) << 16) + r->DX), r->AL, &lrc)) < 0)
        goto error_exit;
      else
      {
        r->DX = (lrc >> 16);
        r->AX = (UWORD)lrc;
      }
      }
      break;

      /* Get/Set File Attributes                                      */
    case 0x43:
      switch (r->AL)
      {
        case 0x00:
          rc = DosGetFattr((BYTE FAR *) FP_DS_DX);
          if (rc >= SUCCESS)
              r->CX = rc;
          break;

        case 0x01:
          rc = DosSetFattr((BYTE FAR *) FP_DS_DX, r->CX);
          break;

        default:
          goto error_invalid;
      }
      if (rc < SUCCESS)
        goto error_exit;
      break;

      /* Device I/O Control                                           */
    case 0x44:
      rc = DosDevIOctl(r);

      if (rc != SUCCESS)
        goto error_exit;
      break;

      /* Duplicate File Handle                                        */
    case 0x45:
      rc = DosDup(r->BX);
      if (rc < SUCCESS)
        goto error_exit;
      else
        r->AX = rc;
      break;

      /* Force Duplicate File Handle                                  */
    case 0x46:
      rc = DosForceDup(r->BX, r->CX);
      if (rc < SUCCESS)
        goto error_exit;
      break;

      /* Get Current Directory                                        */
    case 0x47:
      if ((rc = DosGetCuDir(r->DL, MK_FP(r->DS, r->SI))) < 0)
        goto error_exit;
      else
        r->AX = 0x0100;         /*jpp: from interrupt list */
      break;

      /* Allocate memory */
    case 0x48:
      if ((rc = DosMemAlloc(r->BX, mem_access_mode, &(r->AX), &(r->BX))) < 0)
      {
        DosMemLargest(&(r->BX));
        goto error_exit;
      }
      else
        ++(r->AX);              /* DosMemAlloc() returns seg of MCB rather than data */
      break;

      /* Free memory */
    case 0x49:
      if ((rc = DosMemFree((r->ES) - 1)) < 0)
        goto error_exit;
      break;

      /* Set memory block size */
    case 0x4a:
      {
        UWORD maxSize;

        if ((rc = DosMemChange(r->ES, r->BX, &maxSize)) < 0)
        {
          if (rc == DE_NOMEM)
            r->BX = maxSize;

#if 0
          if (cu_psp == r->ES)
          {

            psp FAR *p;

            p = MK_FP(cu_psp, 0);
            p->ps_size = r->BX + cu_psp;
          }
#endif
          goto error_exit;
        }

        break;
      }

      /* Load and Execute Program */
    case 0x4b:
      break_flg = FALSE;

      if ((rc = DosExec(r->AL, MK_FP(r->ES, r->BX), FP_DS_DX))
          != SUCCESS)
        goto error_exit;
      break;

      /* Terminate Program                                            */
    case 0x00:
      r->AX = 0x4c00;

      /* End Program                                                  */
    case 0x4c:
      if (cu_psp == RootPsp
          || ((psp FAR *) (MK_FP(cu_psp, 0)))->ps_parent == cu_psp)
        break;
      tsr = FALSE;
      if (ErrorMode)
      {
        ErrorMode = FALSE;
        return_mode = 2;
      }
      else if (break_flg)
      {
        break_flg = FALSE;
        return_mode = 1;
      }
      else
      {
        return_mode = 0;
      }
      return_code = r->AL;
      if (DosMemCheck() != SUCCESS)
        panic("MCB chain corrupted");
#ifdef TSC
      StartTrace();
#endif
      return_user();
      break;

      /* Get Child-program Return Value                               */
    case 0x4d:
      r->AL = return_code;
      r->AH = return_mode;
      break;

      /* Dos Find First                                               */
    case 0x4e:
      /* dta for this call is set on entry.  This     */
      /* needs to be changed for new versions.        */
      if ((rc = DosFindFirst((UCOUNT) r->CX, (BYTE FAR *) FP_DS_DX)) < 0)
        goto error_exit;
      r->AX = 0;
      break;

      /* Dos Find Next                                                */
    case 0x4f:
      /* dta for this call is set on entry.  This     */
      /* needs to be changed for new versions.        */
      if ((rc = DosFindNext()) < 0)
      {
        if (rc == DE_FILENOTFND)
          rc = DE_NFILES;
        goto error_exit;
      }
      else
        r->AX = -SUCCESS;
      break;
/*
    case 0x50:  
    case 0x51:
    see int21_syscall
*/
      /* ************UNDOCUMENTED************************************* */
      /* Get List of Lists                                            */
    case 0x52:
      {
        BYTE FAR *p;

        p = (BYTE FAR *) & DPBp;
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

    case 0x53:
      /*  DOS 2+ internal - TRANSLATE BIOS PARAMETER BLOCK TO DRIVE PARAM BLOCK */
      bpb_to_dpb((bpb FAR *)MK_FP(r->DS, r->SI), (struct dpb FAR *)MK_FP(r->ES, r->BP));
      break;
      
      /* Get verify state                                             */
    case 0x54:
      r->AL = (verify_ena ? TRUE : FALSE);
      break;

      /* ************UNDOCUMENTED************************************* */
      /* Dos Create New Psp & set p_size                              */
    case 0x55:
      new_psp((psp FAR *) MK_FP(r->DX, 0), r->SI);
      cu_psp = r->DX;
      break;

      /* Dos Rename                                                   */
    case 0x56:
      rc = DosRename((BYTE FAR *) FP_DS_DX, (BYTE FAR *) MK_FP(r->ES, r->DI));
      if (rc < SUCCESS)
        goto error_exit;
      else
        CLEAR_CARRY_FLAG();
      break;

      /* Get/Set File Date and Time                                   */
    case 0x57:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x00:
          rc = DosGetFtime(
                            (COUNT) r->BX,	/* Handle               */
                            (date FAR *) & r->DX,	/* FileDate             */
                            (time FAR *) & r->CX);	/* FileTime             */
          if (rc < SUCCESS)
            goto error_exit;
          break;

        case 0x01:
          rc = DosSetFtime(
                            (COUNT) r->BX,	/* Handle               */
                            (date) r->DX,	/* FileDate             */
                            (time) r->CX);	/* FileTime             */
          if (rc < SUCCESS)
            goto error_exit;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Get/Set Allocation Strategy                                  */
    case 0x58:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x00:
          r->AL = mem_access_mode;
          r->AH = 0;
          break;

        case 0x01:
        {
            switch (r->BL)
            {
            case LAST_FIT:
            case LAST_FIT_U:
            case LAST_FIT_UO:
            case BEST_FIT:
            case BEST_FIT_U:
            case BEST_FIT_UO:
            case FIRST_FIT:
            case FIRST_FIT_U:
            case FIRST_FIT_UO:
                mem_access_mode = r->BL;
                break;

            default:
                goto error_invalid;
            }
        }
            break;

        case 0x02:
            r->AL = uppermem_link;
            break;

        case 0x03:
            if (uppermem_root) {
                DosUmbLink(r->BL);
                break;
            } /* else fall through */            

        default:
          goto error_invalid;
#ifdef DEBUG
        case 0xff:
          show_chain();
          break;
#endif
      }
      break;

      /* Get Extended Error */
    case 0x59:
        r->AX = CritErrCode;
        r->ES = FP_SEG(CritErrDev);
        r->DI = FP_OFF(CritErrDev);
        r->CH = CritErrLocus;
        r->BH = CritErrClass;
        r->BL = CritErrAction;
        CLEAR_CARRY_FLAG();
      break;

      /* Create Temporary File */
    case 0x5a:
      if ((rc = DosMkTmp(FP_DS_DX, r->CX)) < 0)
        goto error_exit;
      else
      {
        r->AX = rc;
        CLEAR_CARRY_FLAG();
      }
      break;

      /* Create New File */
    case 0x5b:
      if (!IsDevice(FP_DS_DX) && (rc = DosOpen(FP_DS_DX, 0)) >= 0)
      {
        DosClose(rc);
        r->AX = 80;
        goto error_out;
      }
      else
      {
        if ((rc = DosCreat(FP_DS_DX, r->CX)) < 0)
          goto error_exit;
        else
        {
          r->AX = rc;
          CLEAR_CARRY_FLAG();
        }
      }
      break;

/* /// Added for SHARE.  - Ron Cemer */
      /* Lock/unlock file access */
    case 0x5c:
      if ((rc = DosLockUnlock
        (r->BX,
         (((unsigned long)r->CX)<<16)|(((unsigned long)r->DX)&0xffffL),
         (((unsigned long)r->SI)<<16)|(((unsigned long)r->DI)&0xffffL),
         ((r->AX & 0xff) != 0))) != 0)
          goto error_exit;
      CLEAR_CARRY_FLAG();
      break;
/* /// End of additions for SHARE.  - Ron Cemer */

      /* UNDOCUMENTED: server, share.exe and sda function             */
    case 0x5d:
      switch (r->AL)
      {
          /* Remote Server Call */
        case 0x00:
          {
            UWORD FAR *x = FP_DS_DX;
            r->AX = x[0];
            r->BX = x[1];
            r->CX = x[2];
            r->DX = x[3];
            r->SI = x[4];
            r->DI = x[5];
            r->DS = x[6];
            r->ES = x[7];
          }
          goto dispatch;

        case 0x06:
          r->DS = FP_SEG(internal_data);
          r->SI = FP_OFF(internal_data);
          r->CX = swap_always - internal_data;
          r->DX = swap_indos - internal_data;
          CLEAR_CARRY_FLAG();
          break;

        case 0x07:
        case 0x08:
        case 0x09:
	  rc = -int2f_Remote_call(REM_PRINTREDIR, 0, 0, r->DX, 0, 0, (MK_FP(0, Int21AX)));
	  if (rc != SUCCESS)
            goto error_exit;
          CLEAR_CARRY_FLAG();
          break;
        default:
          goto error_invalid;
      }
      break;

    case 0x5e:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x00:
          r->CX = get_machine_name(FP_DS_DX);
          break;

        case 0x01:
          set_machine_name(FP_DS_DX, r->CX);
          break;

        default:
          rc = -int2f_Remote_call(REM_PRINTSET, r->BX, r->CX, r->DX, (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX)));
	  if (rc != SUCCESS) goto error_exit;
          r->AX=SUCCESS;
          break;
      }
      break;

    case 0x5f:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x07:
          if (r->DL < lastdrive) {
            CDSp->cds_table[r->DL].cdsFlags |= 0x100;
	  }
          break;

        case 0x08:
          if (r->DL < lastdrive) {
            CDSp->cds_table[r->DL].cdsFlags &= ~0x100;
	  }
          break;

        default:
/*              
            void int_2f_111e_call(iregs FAR *r);
            int_2f_111e_call(r);          
          break;*/

          rc = -int2f_Remote_call(REM_DOREDIRECT, r->BX, r->CX, r->DX,
                                 (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX)));
	  if (rc != SUCCESS)
            goto error_exit;
          r->AX=SUCCESS;
          break;
      }
      break;

    case 0x60:                 /* TRUENAME */
      CLEAR_CARRY_FLAG();
      if ((rc = truename(MK_FP(r->DS, r->SI),
                      adjust_far(MK_FP(r->ES, r->DI)), FALSE)) != SUCCESS)
        goto error_exit;
      break;

#ifdef TSC
      /* UNDOCUMENTED: no-op                                          */
      /*                                                              */
      /* DOS-C: tsc support                                           */
    case 0x61:
#ifdef DEBUG
      switch (r->AL)
      {
        case 0x01:
          bTraceNext = TRUE;
          break;

        case 0x02:
          bDumpRegs = FALSE;
          break;
      }
#endif
      r->AL = 0x00;
      break;
#endif

      /* UNDOCUMENTED: return current psp                             
    case 0x62: is in int21_syscall
      r->BX = cu_psp;
      break;
      */
      
      /* UNDOCUMENTED: Double byte and korean tables                  */
    case 0x63:
      {
#define DBLBYTE
#ifdef DBLBYTE
        static char dbcsTable[2] =
        {
          0, 0
        };
        void FAR *dp = &dbcsTable;

        r->DS = FP_SEG(dp);
        r->SI = FP_OFF(dp);
        r->AL = 0;
#else
        /* not really supported, but will pass.                 */
        r->AL = 0x00;           /*jpp: according to interrupt list */	
				/*Bart: fails for PQDI: use the above again */
#endif
        break;
      }
/*
    case 0x64:
      see above (invalid)
*/      

      /* Extended country info                                        */
    case 0x65:
    	switch(r->AL) {
    	case 0x20:				/* upcase single character */
            r->DL = DosUpChar(r->DL);
            break;
        case 0x21:				/* upcase memory area */
            DosUpMem(FP_DS_DX, r->CX);
            break;
        case 0x22:				/* upcase ASCIZ */
            DosUpString(FP_DS_DX);
            break;
    	case 0xA0:				/* upcase single character of filenames */
            r->DL = DosUpFChar(r->DL);
            break;
        case 0xA1:				/* upcase memory area of filenames */
            DosUpFMem(FP_DS_DX, r->CX);
            break;
        case 0xA2:				/* upcase ASCIZ of filenames */
            DosUpFString(FP_DS_DX);
            break;
        case 0x23:				/* check Yes/No response */
            r->AX = DosYesNo(r->DL);
            break;
      	default:
            if ((rc = DosGetData(
                         r->AL, r->BX, r->DX, r->CX,
                         MK_FP(r->ES, r->DI))) < 0) {
#ifdef NLS_DEBUG
   printf("DosGetData() := %d\n", rc);
#endif
               goto error_exit;
            }
#ifdef NLS_DEBUG
   printf("DosGetData() returned successfully\n", rc);
#endif

            break;
         }
		CLEAR_CARRY_FLAG();
      break;
      

      /* Code Page functions */
    case 0x66: {
    	int rc;
      switch (r->AL)
      {
        case 1:
          rc = DosGetCodepage(&r->BX, &r->DX);
			break;
        case 2:
          rc = DosSetCodepage(r->BX, r->DX);
          break;

        default:
          goto error_invalid;
      }
      if(rc != SUCCESS)
      	goto error_exit;
      CLEAR_CARRY_FLAG();
      break;
     }

      /* Set Max file handle count */
    case 0x67:
      if ((rc = SetJFTSize(r->BX)) != SUCCESS)
        goto error_exit;
      else
        CLEAR_CARRY_FLAG();
      break;

      /* Flush file buffer -- COMMIT FILE -- dummy function right now.  */
    case 0x68:
    case 0x6a:
      CLEAR_CARRY_FLAG();
      break;

      /* Get/Set Serial Number */
    case 0x69:
      rc = ( r->BL == 0 ? default_drive : r->BL - 1);
      if (rc < lastdrive)
      {
        UWORD saveCX = r->CX;
        if (CDSp->cds_table[rc].cdsFlags & CDSNETWDRV) {
          goto error_invalid;
        }
        switch(r->AL){
            case 0x00:
            r->AL = 0x0d;
            r->CX = 0x0866;
            rc = DosDevIOctl(r);
            break;

            case 0x01:
            r->AL = 0x0d;
            r->CX = 0x0846;
            rc = DosDevIOctl(r);
            break;
        }
        r->CX = saveCX;
        if (rc != SUCCESS)
          goto error_exit;
        CLEAR_CARRY_FLAG();
        break;
      }
      else
        r->AL = 0xFF;
      break;
/*
    case 0x6a: see case 0x68
    case 0x6b: dummy func: return AL=0
*/    
    /* Extended Open-Creat, not fully functional. (bits 4,5,6 of BH) */
    case 0x6c:
      {
        COUNT x = 0;
      
        if (r->AL != 0 || r->DH != 0 ||
              (r->DL&0x0f) > 0x2 || (r->DL&0xf0) > 0x10)
            goto error_invalid;
        CLEAR_CARRY_FLAG();
        if ((rc = DosOpen(MK_FP(r->DS, r->SI),
                          (r->DL&0x0f) == 0x1 ? r->BL : 0)) < 0)
        {
            if (r->DL < 0x10)
                goto error_exit;
            /* else try to create below */
        }
        else switch (r->DL & 0x0f)
        {
          case 0x0:
            /* fail if file exists */
            DosClose(rc);
            rc = DE_FILEEXISTS;
            goto error_exit;
          case 0x1:
            /* file exists and opened: OK */
            r->CX = 0x01;
            goto break_out;
          case 0x2:  
            /* file exists: replace/open */
            DosClose(rc);
            x = 1;
            break;
        }
        /* cases 0x00, 0x01 are finished now */
        if ((rc = DosCreat(MK_FP(r->DS, r->SI), r->CX)) < 0)
            goto error_exit;
            
        r->CX = x+2;
break_out:        
        r->AX = rc;
        break;
      }


    /* case 0x6d and above not implemented : see default; return AL=0 */
        
  }

#ifdef DEBUG
  if (bDumpRegs)
  {
    fbcopy((VOID FAR *) user_r, (VOID FAR *) & error_regs,
           sizeof(iregs));
    dump_regs = TRUE;
    dump();
  }
#endif
}
Beispiel #8
0
f_node_ptr dir_open(BYTE * dirname)
{
  f_node_ptr fnp;
  COUNT drive;
  BYTE *p;
  WORD i;
  struct cds FAR *cdsp;
  BYTE *pszPath = dirname + 2;

  /* Allocate an fnode if possible - error return (0) if not.     */
  if ((fnp = get_f_node()) == (f_node_ptr)0)
  {
    return (f_node_ptr)0;
  }

  /* Force the fnode into read-write mode                         */
  fnp->f_mode = RDWR;

  /* determine what drive we are using...                         */
  if (ParseDosName(dirname, &drive, (BYTE *) 0, (BYTE *) 0, (BYTE *) 0, FALSE)
      != SUCCESS)
  {
    release_f_node(fnp);
    return NULL;
  }

  /* If the drive was specified, drive is non-negative and        */
  /* corresponds to the one passed in, i.e., 0 = A, 1 = B, etc.   */
  /* We use that and skip the "D:" part of the string.            */
  /* Otherwise, just use the default drive                        */
  if (drive >= 0)
  {
    dirname += 2;               /* Assume FAT style drive       */
  }
  else
  {
    drive = default_drive;
  }
  if (drive >= lastdrive) {
    release_f_node(fnp);
    return NULL;
  }

  cdsp = &CDSp->cds_table[drive];

  /* Generate full path name                                      */
  /* not necessary anymore, since truename did that already
       i = cdsp->cdsJoinOffset;
     ParseDosPath(dirname, (COUNT *) 0, pszPath, (BYTE FAR *) & cdsp->cdsCurrentPath[i]); */

/* for testing only for now */
#if 0
  if ((cdsp->cdsFlags & CDSNETWDRV))
  {
    printf("FailSafe %x \n", Int21AX);
    return fnp;
  }
#endif

  if (cdsp->cdsDpb == 0)
  {
    release_f_node(fnp);
    return NULL;
  }

  fnp->f_dpb = cdsp->cdsDpb;

  /* Perform all directory common handling after all special      */
  /* handling has been performed.                                 */

  if (media_check(fnp->f_dpb) < 0)
  {
    release_f_node(fnp);
    return (f_node_ptr)0;
  }

  /* Walk the directory tree to find the starting cluster         */
  /*                                                              */
  /* Start from the root directory (dirstart = 0)                 */

  dir_init_fnode(fnp, 0);

  for (p = pszPath; *p != '\0';)
  {
    /* skip all path seperators                             */
    while (*p == '\\')
      ++p;
    /* don't continue if we're at the end                   */
    if (*p == '\0')
      break;

    /* Convert the name into an absolute name for           */
    /* comparison...                                        */
    /* first the file name with trailing spaces...          */

    memset(TempBuffer, ' ', FNAME_SIZE+FEXT_SIZE);
    
    for (i = 0; i < FNAME_SIZE; i++)
    {
      if (*p != '\0' && *p != '.' && *p != '/' && *p != '\\')
        TempBuffer[i] = *p++;
      else
        break;
    }

    /* and the extension (don't forget to   */
    /* add trailing spaces)...              */
    if (*p == '.')
      ++p;
    for (i = 0; i < FEXT_SIZE; i++)
    {
      if (*p != '\0' && *p != '.' && *p != '/' && *p != '\\')
        TempBuffer[i + FNAME_SIZE] = *p++;
      else
        break;
    }

    /* Now search through the directory to  */
    /* find the entry...                    */
    i = FALSE;

    DosUpFMem((BYTE FAR *) TempBuffer, FNAME_SIZE + FEXT_SIZE);

    while (dir_read(fnp) == 1)
    {
      if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED)
      {
        if (fcmp(TempBuffer, (BYTE *)fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
        {
          i = TRUE;
          break;
        }
      }
    }

    if (!i || !(fnp->f_dir.dir_attrib & D_DIR))
    {

      release_f_node(fnp);
      return (f_node_ptr)0;
    }
    else
    {
      /* make certain we've moved off */
      /* root                         */
      dir_init_fnode(fnp, getdstart(fnp->f_dir));
    }
  }
  return fnp;
}
Beispiel #9
0
COUNT dos_findnext(void)
{
  REG dmatch *dmp = (dmatch *) TempBuffer;
  REG f_node_ptr fnp;
  BOOL found = FALSE;

  /* Allocate an fnode if possible - error return (0) if not.     */
  if ((fnp = get_f_node()) == (f_node_ptr)0)
  {
    return DE_NFILES;
  }
  
  memset(fnp, 0, sizeof(*fnp));

  /* Force the fnode into read-write mode                         */
  fnp->f_mode = RDWR;

  /* Select the default to help non-drive specified path          */
  /* searches...                                                  */
  fnp->f_dpb = CDSp->cds_table[dmp->dm_drive].cdsDpb;
  if (media_check(fnp->f_dpb) < 0)
  {
    release_f_node(fnp);
    return DE_NFILES;
  }

  dir_init_fnode(fnp, dmp->dm_dircluster);

  /* Search through the directory to find the entry, but do a     */
  /* seek first.                                                  */
  if (dmp->dm_entry > 0)
    {
    fnp->f_diroff = (ULONG)(dmp->dm_entry - 1) * DIRENT_SIZE;
    fnp->f_flags.f_dnew = FALSE;
    }
  else
    {
    fnp->f_diroff = 0;
    fnp->f_flags.f_dnew = TRUE;
    }          

  /* Loop through the directory                                   */
  while (dir_read(fnp) == 1)
  {
    ++dmp->dm_entry;
    if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED
          && (fnp->f_dir.dir_attrib & D_VOLID) != D_VOLID )
    {
      if (fcmp_wild((BYTE FAR *)dmp->dm_name_pat, (BYTE FAR *)fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
      {
        /*
            MSD Command.com uses FCB FN 11 & 12 with attrib set to 0x16.
            Bits 0x21 seem to get set some where in MSD so Rd and Arc
            files are returned. 
            RdOnly + Archive bits are ignored
         */
         
        /* Test the attribute as the final step */
        if (!(fnp->f_dir.dir_attrib & D_VOLID) &&
           ((~dmp->dm_attr_srch & fnp->f_dir.dir_attrib & (D_DIR | D_SYSTEM | D_HIDDEN)) == 0))
        {
          found = TRUE;
          break;
        }
        else
          continue;
      }
    }
  }

  /* If found, transfer it to the dmatch structure                */
  if (found)
    {
    dmp->dm_dircluster = fnp->f_dirstart;
    memcpy(&SearchDir, &fnp->f_dir, sizeof(struct dirent));
    }

  /* return the result                                            */
  release_f_node(fnp);

  return found ? SUCCESS : DE_NFILES;
}
Beispiel #10
0
COUNT dos_findnext(void)
{
  REG dmatch FAR *dmp = (dmatch FAR *) dta;
  REG struct f_node FAR *fnp;
  BOOL found = FALSE;
  BYTE FAR *p;
  BYTE FAR *q;
  COUNT nDrive;
  struct cds FAR *cdsp;

  /* assign our match parameters pointer.                         */
  dmp = (dmatch FAR *) dta;

  nDrive = dmp->dm_drive;

  cdsp = &CDSp->cds_table[nDrive];
  if (cdsp->cdsFlags & 0x8000)
  {
    if (Remote_find(REM_FINDNEXT, 0, 0, dmp) != 0)
      return DE_FILENOTFND;
    return SUCCESS;
  }

  /* Allocate an fnode if possible - error return (0) if not.     */
  if ((fnp = get_f_node()) == (struct f_node FAR *)0)
  {
    return DE_FILENOTFND;
  }

  /* Force the fnode into read-write mode                         */
  fnp->f_mode = RDWR;

  /* Select the default to help non-drive specified path          */
  /* searches...                                                  */
  fnp->f_dpb = (struct dpb *)CDSp->cds_table[dmp->dm_drive].cdsDpb;
  if (media_check(fnp->f_dpb) < 0)
  {
    release_f_node(fnp);
    return DE_FILENOTFND;
  }

  fnp->f_dsize = DIRENT_SIZE * (fnp->f_dpb)->dpb_dirents;

  /* Search through the directory to find the entry, but do a     */
  /* seek first.                                                  */
  if (dmp->dm_entry > 0)
    fnp->f_diroff = (dmp->dm_entry - 1) * DIRENT_SIZE;

  fnp->f_offset = fnp->f_highwater = fnp->f_diroff;
  fnp->f_cluster = dmp->dm_cluster;
  fnp->f_cluster_offset = 0l;   /*JPP */
  fnp->f_flags.f_dmod = dmp->dm_flags.f_dmod;
  fnp->f_flags.f_droot = dmp->dm_flags.f_droot;
  fnp->f_flags.f_dnew = dmp->dm_flags.f_dnew;
  fnp->f_flags.f_ddir = dmp->dm_flags.f_ddir;
  fnp->f_flags.f_dfull = dmp->dm_flags.f_dfull;

  fnp->f_dirstart = dmp->dm_dirstart;

  /* Loop through the directory                                   */
  while (dir_read(fnp) == DIRENT_SIZE)
  {
    ++dmp->dm_entry;
    if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED)
    {
      if (fcmp_wild((BYTE FAR *) (dmp->dm_name_pat), (BYTE FAR *) fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
      {
        /* Test the attribute as the final step */
        if (!(~dmp->dm_attr_srch & fnp->f_dir.dir_attrib))
        {
          found = TRUE;
          break;
        }
        else
          continue;
      }
    }
  }

  /* If found, transfer it to the dmatch structure                */
  if (found)
    pop_dmp(dmp, fnp);

  /* return the result                                            */
  release_f_node(fnp);

  return found ? SUCCESS : DE_FILENOTFND;
}
Beispiel #11
0
struct f_node FAR *dir_open(BYTE FAR * dirname)
{
  struct f_node FAR *fnp;
  COUNT drive;
  BYTE *p;
  WORD i,
    x;
  BYTE *s;
  struct cds FAR *cdsp;
  BYTE *pszPath = &TempCDS.cdsCurrentPath[2];

  /* Allocate an fnode if possible - error return (0) if not.     */
  if ((fnp = get_f_node()) == (struct f_node FAR *)0)
  {
    return (struct f_node FAR *)NULL;
  }

  /* Force the fnode into read-write mode                         */
  fnp->f_mode = RDWR;

  /* and initialize temporary CDS                                 */
  TempCDS.cdsFlags = 0;
  /* determine what drive we are using...                         */
  dirname = adjust_far(dirname);
  if (ParseDosName(dirname, &drive, (BYTE *) 0, (BYTE *) 0, (BYTE *) 0, FALSE)
      != SUCCESS)
  {
    release_f_node(fnp);
    return NULL;
  }

  /* If the drive was specified, drive is non-negative and        */
  /* corresponds to the one passed in, i.e., 0 = A, 1 = B, etc.   */
  /* We use that and skip the "D:" part of the string.            */
  /* Otherwise, just use the default drive                        */
  if (drive >= 0)
  {
    dirname += 2;               /* Assume FAT style drive       */
    TempCDS.cdsDpb = CDSp->cds_table[drive].cdsDpb;
  }
  else
  {
    drive = default_drive;
    TempCDS.cdsDpb = CDSp->cds_table[drive].cdsDpb;

  }

  cdsp = &CDSp->cds_table[drive];

  TempCDS.cdsCurrentPath[0] = 'A' + drive;
  TempCDS.cdsCurrentPath[1] = ':';
  TempCDS.cdsJoinOffset = 2;

  x = cdsp->cdsJoinOffset;

  /* Generate full path name                                      */
  ParseDosPath(dirname, (COUNT *) 0, pszPath, (BYTE FAR *) & cdsp->cdsCurrentPath[x]);

  if ((cdsp->cdsFlags & 0x8000))
  {
    printf("FailSafe %x \n", Int21AX);
    return fnp;
  }

  if (TempCDS.cdsDpb == 0)
  {
    release_f_node(fnp);
    return NULL;
  }

/*  if (drive >= lastdrive)
   {
   release_f_node(fnp);
   return NULL;
   }
 */
  fnp->f_dpb = (struct dpb *)TempCDS.cdsDpb;

  /* Perform all directory common handling after all special      */
  /* handling has been performed.                                 */

  if (media_check((struct dpb *)TempCDS.cdsDpb) < 0)
  {
    release_f_node(fnp);
    return (struct f_node FAR *)0;
  }

  fnp->f_dsize = DIRENT_SIZE * TempCDS.cdsDpb->dpb_dirents;

  fnp->f_diroff = 0l;
  fnp->f_flags.f_dmod = FALSE;  /* a brand new fnode            */
  fnp->f_flags.f_dnew = TRUE;
  fnp->f_flags.f_dremote = FALSE;

  fnp->f_dirstart = 0;

  /* Walk the directory tree to find the starting cluster         */
  /*                                                              */
  /* Set the root flags since we always start from the root       */

  fnp->f_flags.f_droot = TRUE;
  for (p = pszPath; *p != '\0';)
  {
    /* skip all path seperators                             */
    while (*p == '\\')
      ++p;
    /* don't continue if we're at the end                   */
    if (*p == '\0')
      break;

    /* Convert the name into an absolute name for           */
    /* comparison...                                        */
    /* first the file name with trailing spaces...          */
    for (i = 0; i < FNAME_SIZE; i++)
    {
      if (*p != '\0' && *p != '.' && *p != '/' && *p != '\\')
        TempBuffer[i] = *p++;
      else
        break;
    }

    for (; i < FNAME_SIZE; i++)
      TempBuffer[i] = ' ';

    /* and the extension (don't forget to   */
    /* add trailing spaces)...              */
    if (*p == '.')
      ++p;
    for (i = 0; i < FEXT_SIZE; i++)
    {
      if (*p != '\0' && *p != '.' && *p != '/' && *p != '\\')
        TempBuffer[i + FNAME_SIZE] = *p++;
      else
        break;
    }
    for (; i < FEXT_SIZE; i++)
      TempBuffer[i + FNAME_SIZE] = ' ';

    /* Now search through the directory to  */
    /* find the entry...                    */
    i = FALSE;

    upMem((BYTE FAR *) TempBuffer, FNAME_SIZE + FEXT_SIZE);

    while (dir_read(fnp) == DIRENT_SIZE)
    {
      if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED)
      {
        if (fcmp((BYTE FAR *) TempBuffer, (BYTE FAR *) fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
        {
          i = TRUE;
          break;
        }
      }
    }

    if (!i || !(fnp->f_dir.dir_attrib & D_DIR))
    {

      release_f_node(fnp);
      return (struct f_node FAR *)0;
    }
    else
    {
      /* make certain we've moved off */
      /* root                         */
      fnp->f_flags.f_droot = FALSE;
      fnp->f_flags.f_ddir = TRUE;
      /* set up for file read/write   */
      fnp->f_offset = 0l;
      fnp->f_cluster_offset = 0l;	/*JPP */
      fnp->f_highwater = 0l;
      fnp->f_cluster = fnp->f_dir.dir_start;
      fnp->f_dirstart = fnp->f_dir.dir_start;
      /* reset the directory flags    */
      fnp->f_diroff = 0l;
      fnp->f_flags.f_dmod = FALSE;
      fnp->f_flags.f_dnew = TRUE;
      fnp->f_dsize = DIRENT_SIZE * TempCDS.cdsDpb->dpb_dirents;

    }
  }
  return fnp;
}