Beispiel #1
0
STATIC int CharRequest(struct dhdr FAR **pdev, unsigned command)
{
  struct dhdr FAR *dev = *pdev;
  CharReqHdr.r_command = command;
  CharReqHdr.r_unit = 0;
  CharReqHdr.r_status = 0;
  CharReqHdr.r_length = sizeof(request);
  execrh(&CharReqHdr, dev);
  if (CharReqHdr.r_status & S_ERROR)
  {
    for (;;) {
      switch (char_error(&CharReqHdr, dev))
      {
      case ABORT:
      case FAIL:
        return DE_INVLDACC;
      case CONTINUE:
        CharReqHdr.r_count = 0;
        return 0;
      case RETRY:
        return 1;
      }
    }
  }
  return SUCCESS;
}
Beispiel #2
0
COUNT DosSetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, BYTE FAR * hdp)
{
  DosGetDate((BYTE FAR *) & DayOfWeek, (BYTE FAR *) & Month,
             (BYTE FAR *) & DayOfMonth, (COUNT FAR *) & Year);

  ClkRecord.clkHours = *hp;
  ClkRecord.clkMinutes = *mp;
  ClkRecord.clkSeconds = *sp;
  ClkRecord.clkHundredths = *hdp;

  YearsSince1980 = Year - 1980;
  ClkRecord.clkDays = DayOfMonth - 1
      + days[is_leap_year(Year)][Month - 1]
      + ((YearsSince1980) * 365)
      + ((YearsSince1980 + 3) / 4);

  ClkReqHdr.r_length = sizeof(request);
  ClkReqHdr.r_command = C_OUTPUT;
  ClkReqHdr.r_count = sizeof(struct ClockRecord);
  ClkReqHdr.r_trans = (BYTE FAR *) (&ClkRecord);
  ClkReqHdr.r_status = 0;
  execrh((request FAR *) & ClkReqHdr, (struct dhdr FAR *)clock);
  if (ClkReqHdr.r_status & S_ERROR)
    return char_error(&ClkReqHdr, (struct dhdr FAR *)clock);
  return SUCCESS;
}
Beispiel #3
0
UCOUNT BinaryCharIO(struct dhdr FAR * dev, UCOUNT n, void FAR * bp, unsigned command, COUNT *err)
{
  *err = SUCCESS;
    
  FOREVER
  {
    CharReqHdr.r_length = sizeof(request);
    CharReqHdr.r_command = command;
    CharReqHdr.r_count = n;
    CharReqHdr.r_trans = bp;
    CharReqHdr.r_status = 0;
    execrh(&CharReqHdr, dev);
    if (CharReqHdr.r_status & S_ERROR)
    {
    charloop:
      switch (char_error(&CharReqHdr, dev))
      {
        case ABORT:
        case FAIL:
          *err = DE_INVLDACC;
          return 0;
        case CONTINUE:
          break;
        case RETRY:
          continue;
        default:
          goto charloop;
      }
    }
    break;
  }
  return CharReqHdr.r_count;
}
Beispiel #4
0
VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, BYTE FAR * hdp)
{
  ClkReqHdr.r_length = sizeof(request);
  ClkReqHdr.r_command = C_INPUT;
  ClkReqHdr.r_count = sizeof(struct ClockRecord);
  ClkReqHdr.r_trans = (BYTE FAR *) (&ClkRecord);
  ClkReqHdr.r_status = 0;
  execrh((request FAR *) & ClkReqHdr, (struct dhdr FAR *)clock);
  if (ClkReqHdr.r_status & S_ERROR)
    return;

  *hp = ClkRecord.clkHours;
  *mp = ClkRecord.clkMinutes;
  *sp = ClkRecord.clkSeconds;
  *hdp = ClkRecord.clkHundredths;
}
Beispiel #5
0
UCOUNT DosWrite(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err)
{
  sft FAR *s;
  WORD sys_idx;
  sfttbl FAR *sp;
  UCOUNT ReadCount;

  /* Test that the handle is valid                */
  if (hndl < 0)
  {
    *err = DE_INVLDHNDL;
    return 0;
  }

  /* Get the SFT block that contains the SFT      */
  if ((s = get_sft(hndl)) == (sft FAR *) - 1)
  {
    *err = DE_INVLDHNDL;
    return 0;
  }

  /* If this is not opened and it's not a write   */
  /* another error                                */
  if (s->sft_count == 0 ||
      (!(s->sft_mode & SFT_MWRITE) && !(s->sft_mode & SFT_MRDWR)))
  {
    *err = DE_ACCESS;
    return 0;
  }
  if (s->sft_flags & SFT_FSHARED)
  {
    ReadCount = Remote_RW(REM_WRITE, n, bp, s, err);
    if (err)
    {
      return ReadCount;
    }
    else
      return 0;
  }

  /* Do a device write if device                  */
  if (s->sft_flags & SFT_FDEVICE)
  {
    request rq;

    /* set to no EOF                        */
    s->sft_flags &= ~SFT_FEOF;

    /* if null just report full transfer    */
    if (s->sft_flags & SFT_FNUL)
    {
      *err = SUCCESS;
      return n;
    }

    /* Now handle raw and cooked modes      */
    if (s->sft_flags & SFT_FBINARY)
    {
      rq.r_length = sizeof(request);
      rq.r_command = C_OUTPUT;
      rq.r_count = n;
      rq.r_trans = (BYTE FAR *) bp;
      rq.r_status = 0;
      execrh((request FAR *) & rq, s->sft_dev);
      if (rq.r_status & S_ERROR)
      {
        char_error(&rq, s->sft_dev);
      }
      else
      {
        if (s->sft_flags & SFT_FCONOUT)
        {
          WORD cnt = rq.r_count;
          while (cnt--)
          {
            switch (*bp++)
            {
              case CR:
                scr_pos = 0;
                break;
              case LF:
              case BELL:
                break;
              case BS:
                --scr_pos;
                break;
              default:
                ++scr_pos;
            }
          }
        }
        *err = SUCCESS;
        return rq.r_count;
      }
    }
    else
    {
      REG WORD c,
        cnt = n,
        spaces_left = 0,
        next_pos,
        xfer = 0;
      static BYTE space = ' ';

    start:
      if (cnt-- == 0)
        goto end;
      if (*bp == CTL_Z)
        goto end;
      if (s->sft_flags & SFT_FCONOUT)
      {
        switch (*bp)
        {
          case CR:
            next_pos = 0;
            break;
          case LF:
          case BELL:
            next_pos = scr_pos;
            break;
          case BS:
            next_pos = scr_pos ? scr_pos - 1 : 0;
            break;
          case HT:
            spaces_left = 8 - (scr_pos & 7);
            next_pos = scr_pos + spaces_left;
            goto output_space;
          default:
            next_pos = scr_pos + 1;
        }
      }
      rq.r_length = sizeof(request);
      rq.r_command = C_OUTPUT;
      rq.r_count = 1;
      rq.r_trans = bp;
      rq.r_status = 0;
      execrh((request FAR *) & rq, s->sft_dev);
      if (rq.r_status & S_ERROR)
        char_error(&rq, s->sft_dev);
      goto post;
    output_space:
      rq.r_length = sizeof(request);
      rq.r_command = C_OUTPUT;
      rq.r_count = 1;
      rq.r_trans = &space;
      rq.r_status = 0;
      execrh((request FAR *) & rq, s->sft_dev);
      if (rq.r_status & S_ERROR)
        char_error(&rq, s->sft_dev);
      --spaces_left;
    post:
      if (spaces_left)
        goto output_space;
      ++bp;
      ++xfer;
      if (s->sft_flags & SFT_FCONOUT)
        scr_pos = next_pos;
      if (break_ena && control_break())
      {
        handle_break();
        goto end;
      }
      goto start;
    end:
      *err = SUCCESS;
      return xfer;
    }
  }
  else
    /* a block write                           */
  {
    COUNT rc;

    ReadCount = writeblock(s->sft_status, bp, n, &rc);
    if (rc < SUCCESS)
    {
      *err = rc;
      return 0;
    }
    else
    {
      *err = SUCCESS;
      return ReadCount;
    }
  }
  *err = SUCCESS;
  return 0;
}
Beispiel #6
0
/*
 * The `force_binary' parameter is a hack to allow functions 0x01, 0x06, 0x07,
 * and function 0x40 to use the same code for performing reads, even though the
 * two classes of functions behave quite differently: 0x01 etc. always do
 * binary reads, while for 0x40 the type of read (binary/text) depends on what
 * the SFT says. -- ror4
 */
UCOUNT GenericRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err,
                   BOOL force_binary)
{
  sft FAR *s;
  WORD sys_idx;
  sfttbl FAR *sp;
  UCOUNT ReadCount;

  /* Test that the handle is valid                */
  if (hndl < 0)
  {
    *err = DE_INVLDHNDL;
    return 0;
  }

  /* Get the SFT block that contains the SFT      */
  if ((s = get_sft(hndl)) == (sft FAR *) - 1)
  {
    *err = DE_INVLDHNDL;
    return 0;
  }

  /* If not open or write permission - exit       */
  if (s->sft_count == 0 || (s->sft_mode & SFT_MWRITE))
  {
    *err = DE_INVLDACC;
    return 0;
  }

/*
   *   Do remote first or return error.
   *   must have been opened from remote.
 */
  if (s->sft_flags & SFT_FSHARED)
  {
    ReadCount = Remote_RW(REM_READ, n, bp, s, err);
    if (err)
    {
      *err = SUCCESS;
      return ReadCount;
    }
    else
      return 0;
  }
  /* Do a device read if device                   */
  if (s->sft_flags & SFT_FDEVICE)
  {
    request rq;

    /* First test for eof and exit          */
    /* immediately if it is                 */
    if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL))
    {
      s->sft_flags &= ~SFT_FEOF;
      *err = SUCCESS;
      return 0;
    }

    /* Now handle raw and cooked modes      */
    if (force_binary || (s->sft_flags & SFT_FBINARY))
    {
      rq.r_length = sizeof(request);
      rq.r_command = C_INPUT;
      rq.r_count = n;
      rq.r_trans = (BYTE FAR *) bp;
      rq.r_status = 0;
      execrh((request FAR *) & rq, s->sft_dev);
      if (rq.r_status & S_ERROR)
      {
        char_error(&rq, s->sft_dev);
      }
      else
      {
        *err = SUCCESS;
        return rq.r_count;
      }
    }
    else if (s->sft_flags & SFT_FCONIN)
    {
      kb_buf.kb_size = LINESIZE - 1;
      kb_buf.kb_count = 0;
      sti((keyboard FAR *) & kb_buf);
      fbcopy((BYTE FAR *) kb_buf.kb_buf, bp, kb_buf.kb_count);
      *err = SUCCESS;
      return kb_buf.kb_count;
    }
    else
    {
      *bp = _sti();
      *err = SUCCESS;
      return 1;
    }
  }
  else
    /* a block read                            */
  {
    COUNT rc;

    ReadCount = readblock(s->sft_status, bp, n, &rc);
    if (rc != SUCCESS)
    {
      *err = rc;
      return 0;
    }
    else
    {
      *err = SUCCESS;
      return ReadCount;
    }
  }
  *err = SUCCESS;
  return 0;
}
Beispiel #7
0
COUNT DosDevIOctl(iregs FAR * r, COUNT FAR * err)
{
  sft FAR *s;
  struct dpb FAR *dpbp;
  BYTE FAR *pBuffer = MK_FP(r->DS, r->DX);
  COUNT nMode;

  /* Test that the handle is valid                                */
  switch (r->AL)
  {
    case 0x00:
    case 0x01:
    case 0x02:
    case 0x03:
    case 0x06:
    case 0x07:
    case 0x0a:
    case 0x0c:

      /* Get the SFT block that contains the SFT              */
      if ((s = get_sft(r->BX)) == (sft FAR *) - 1)
      {
        *err = DE_INVLDHNDL;
        return 0;
      }
      break;

    case 0x04:
    case 0x05:
    case 0x08:
    case 0x09:
    case 0x0d:
    case 0x0e:
    case 0x0f:
    case 0x10:
    case 0x11:
      if (r->BL > nblkdev)
      {
        *err = DE_INVLDDRV;
        return 0;
      }
      else
      {
/*
   This line previously returned the deviceheader at r->bl. But,
   DOS numbers its drives starting at 1, not 0. A=1, B=2, and so
   on. Changed this line so it is now zero-based.

   -SRM
 */
/* JPP - changed to use default drive if drive=0 */
        if (r->BL == 0)
          dpbp = &blk_devices[default_drive];
        else
          dpbp = &blk_devices[r->BL - 1];
      }
      break;

    case 0x0b:
      /* skip, it's a special case.                           */

      NetDelay = r->CX;
      if (!r->DX)
        NetRetry = r->DX;
      break;

    default:
      *err = DE_INVLDFUNC;
      return 0;
  }

  switch (r->AL)
  {
    case 0x00:
      /* Get the flags from the SFT                           */
      r->DX = r->AX = s->sft_flags;

      /* Test for file and network SFT.  These return a 0 in  */
      /* the AH register.                                     */
      if ((s->sft_flags & SFT_FSHARED)
          || !(s->sft_flags & SFT_FDEVICE))
      {
        r->AH = 0;
      }
      break;

    case 0x01:
      /* sft_flags is a file, return an error because you     */
      /* can't set the status of a file.                      */
      if (!(s->sft_flags & SFT_FDEVICE))
      {
        *err = DE_INVLDFUNC;
        return 0;
      }

      /* Set it to what we got in the DL register from the    */
      /* user.                                                */
      r->AL = s->sft_flags_lo = SFT_FDEVICE | r->DL;
      break;

    case 0x0c:
      nMode = C_GENIOCTL;
      goto IoCharCommon;
    case 0x02:
      nMode = C_IOCTLIN;
      goto IoCharCommon;
    case 0x10:
      nMode = C_IOCTLQRY;
      goto IoCharCommon;
    case 0x03:
      nMode = C_IOCTLOUT;
    IoCharCommon:

      if ((s->sft_flags & SFT_FDEVICE)
          || ((r->AL == 0x10) && !(s->sft_dev->dh_attr & ATTR_QRYIOCTL))
          || ((r->AL == 0x0c) && !(s->sft_dev->dh_attr & ATTR_GENIOCTL)))
      {
        if (s->sft_dev->dh_attr & SFT_FIOCTL)
        {
          CharReqHdr.r_unit = 0;
          CharReqHdr.r_length = sizeof(request);
          CharReqHdr.r_command = nMode;
          CharReqHdr.r_count = r->CX;
          CharReqHdr.r_trans = pBuffer;
          CharReqHdr.r_status = 0;
          execrh((request FAR *) & CharReqHdr, s->sft_dev);

          if (CharReqHdr.r_status & S_ERROR)
            return char_error(&CharReqHdr, s->sft_dev);
          if (r->AL == 0x07)
          {
            r->AL =
                CharReqHdr.r_status & S_BUSY ?
                00 : 0xff;
          }
          break;
        }
      }
      *err = DE_INVLDFUNC;
      return 0;

    case 0x0d:
      nMode = C_GENIOCTL;
      goto IoBlockCommon;
    case 0x04:
      nMode = C_IOCTLIN;
      goto IoBlockCommon;
    case 0x11:
      nMode = C_IOCTLQRY;
      goto IoBlockCommon;
    case 0x05:
      nMode = C_IOCTLOUT;
    IoBlockCommon:
      if ((dpbp->dpb_device->dh_attr & ATTR_IOCTL)
      || ((r->AL == 0x11) && !(dpbp->dpb_device->dh_attr & ATTR_QRYIOCTL))
          || ((r->AL == 0x0d) && !(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL)))
      {
        *err = DE_INVLDFUNC;
        return 0;
      }

      CharReqHdr.r_unit = r->BL;
      CharReqHdr.r_length = sizeof(request);
      CharReqHdr.r_command = nMode;
      CharReqHdr.r_count = r->CX;
      CharReqHdr.r_trans = pBuffer;
      CharReqHdr.r_status = 0;
      execrh((request FAR *) & CharReqHdr,
             dpbp->dpb_device);
      if (r->AL == 0x08)
      {
        if (CharReqHdr.r_status & S_ERROR)
        {
          *err = DE_DEVICE;
          return 0;
        }
        r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
      }
      else
      {
        if (CharReqHdr.r_status & S_ERROR)
        {
          *err = DE_DEVICE;
          return 0;
        }
      }
      break;

    case 0x06:
      if (s->sft_flags & SFT_FDEVICE)
      {
        r->AL = s->sft_flags & SFT_FEOF ? 0 : 0xFF;
      }
      else
        r->AL = s->sft_posit >= s->sft_size ? 0xFF : 0;
      break;

    case 0x07:
      if (s->sft_flags & SFT_FDEVICE)
      {
        goto IoCharCommon;
      }
      r->AL = 0;
      break;

    case 0x08:
      if (dpbp->dpb_device->dh_attr & ATTR_EXCALLS)
      {
        nMode = C_REMMEDIA;
        goto IoBlockCommon;
      }
      *err = DE_INVLDFUNC;
      return 0;

    case 0x09:
      r->DX = dpbp->dpb_device->dh_attr;
      break;

    case 0x0a:
      r->DX = s->sft_dcb->dpb_device->dh_attr;
      break;

    case 0x0e:
      nMode = C_GETLDEV;
      goto IoLogCommon;
    case 0x0f:
      nMode = C_SETLDEV;
    IoLogCommon:
      if ((dpbp->dpb_device->dh_attr & ATTR_GENIOCTL))
      {
        if (r->BL == 0)
          r->BL = default_drive;

        CharReqHdr.r_unit = r->BL;
        CharReqHdr.r_length = sizeof(request);
        CharReqHdr.r_command = nMode;
        CharReqHdr.r_count = r->CX;
        CharReqHdr.r_trans = pBuffer;
        CharReqHdr.r_status = 0;
        execrh((request FAR *) & CharReqHdr,
               dpbp->dpb_device);

        if (CharReqHdr.r_status & S_ERROR)
          *err = DE_ACCESS;
        else
          *err = SUCCESS;
        return 0;
      }
      *err = DE_INVLDFUNC;
      return 0;

    default:
      *err = DE_INVLDFUNC;
      return 0;
  }
  *err = SUCCESS;
  return 0;
}
Beispiel #8
0
UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
              COUNT mode)
{
  register struct dpb FAR *dpbp = get_dpb(dsk);
  if (dpbp == NULL)
  {
    return 0x0201;              /* illegal command */
  }

#if TOM
#define KeyboardShiftState() (*(BYTE FAR *)(MK_FP(0x40,0x17)))

  if (KeyboardShiftState() & 0x01)
  {
    printf("dskxfer:%s %x - %lx %u\n", mode == DSKWRITE ? "write" : "read",
           dsk, blkno, numblocks);
    if ((KeyboardShiftState() & 0x03) == 3)
      dumpBufferCache();
  }
#endif

  for (;;)
  {
    IoReqHdr.r_length = sizeof(request);
    IoReqHdr.r_unit = dpbp->dpb_subunit;

    switch (mode)
    {
      case DSKWRITE:
        if (verify_ena)
        {
          IoReqHdr.r_command = C_OUTVFY;
          break;
        }
        /* else fall through */
      case DSKWRITEINT26:
        IoReqHdr.r_command = C_OUTPUT;
        break;

      case DSKREADINT25:
      case DSKREAD:
        IoReqHdr.r_command = C_INPUT;
        break;
      default:
        return 0x0100;          /* illegal command */
    }

    IoReqHdr.r_status = 0;
    IoReqHdr.r_meddesc = dpbp->dpb_mdb;
    IoReqHdr.r_count = numblocks;
    if ((dpbp->dpb_device->dh_attr & ATTR_HUGE) || blkno >= MAXSHORT)
    {
      IoReqHdr.r_start = HUGECOUNT;
      IoReqHdr.r_huge = blkno;
    }
    else
      IoReqHdr.r_start = (UWORD)blkno;
    /*
     * Some drivers normalise transfer address so HMA transfers are disastrous!
     * Then transfer block through xferbuf (DiskTransferBuffer doesn't work!)
     * (But this won't work for multi-block HMA transfers... are there any?)
     */
    if (FP_SEG(buf) >= 0xa000 && numblocks == 1 && bufloc != LOC_CONV)
    {
      IoReqHdr.r_trans = deblock_buf;
      if (mode == DSKWRITE)
        fmemcpy(deblock_buf, buf, SEC_SIZE);
      execrh((request FAR *) & IoReqHdr, dpbp->dpb_device);
      if (mode == DSKREAD)
        fmemcpy(buf, deblock_buf, SEC_SIZE);
    }
    else
    {
      IoReqHdr.r_trans = (BYTE FAR *) buf;
      execrh((request FAR *) & IoReqHdr, dpbp->dpb_device);
    }
    if ((IoReqHdr.r_status & (S_ERROR | S_DONE)) == S_DONE)
      break;

    /* INT25/26 (_SEEMS_ TO) return immediately with 0x8002,
       if drive is not online,...

       normal operations (DIR) wait for ABORT/RETRY

       other condition codes not tested
     */
    if (mode >= DSKWRITEINT26)
      return (IoReqHdr.r_status);

  loop:
    switch (block_error(&IoReqHdr, dpbp->dpb_unit, dpbp->dpb_device, mode))
    {
      case ABORT:
      case FAIL:
        return (IoReqHdr.r_status);

      case RETRY:
        continue;

      case CONTINUE:
        break;

      default:
        goto loop;
    }
    break;
  }                             /* retry loop */
/* *** Changed 9/4/00  BER */
  return 0;                     /* Success!  Return 0 for a successful operation. */
/* End of change */

}
Beispiel #9
0
Datei: 2OS.C Projekt: ifilex/SRC
COUNT DosDevIOctl(iregs FAR * r, COUNT FAR * err)
{
  sft FAR *s;
  struct dpb FAR *dpbp;
  BYTE FAR *pBuffer = MK_FP(r->DS, r->DX);
  COUNT nMode;

  switch (r->AL)
  {
    case 0x00:
    case 0x01:
    case 0x02:
    case 0x03:
    case 0x06:
    case 0x07:
    case 0x0a:
    case 0x0c:

      if ((s = get_sft(r->BX)) == (sft FAR *) - 1)
      {
        *err = DE_INVLDHNDL;
        return 0;
      }
      break;

    case 0x04:
    case 0x05:
    case 0x08:
    case 0x09:
    case 0x0d:
    case 0x0e:
    case 0x0f:
    case 0x10:
    case 0x11:
      if (r->BL > nblkdev)
      {
        *err = DE_INVLDDRV;
        return 0;
      }
      else
      {
        if (r->BL == 0)
          dpbp = &blk_devices[default_drive];
        else
          dpbp = &blk_devices[r->BL - 1];
      }
      break;

    case 0x0b:
      break;

    default:
      *err = DE_INVLDFUNC;
      return 0;
  }

  switch (r->AL)
  {
    case 0x00:
      r->DX = r->AX = s->sft_flags;

      if ((s->sft_flags & SFT_FSHARED)
          || !(s->sft_flags & SFT_FDEVICE))
      {
        r->AH = 0;
      }
      break;

    case 0x01:
      if (!(s->sft_flags & SFT_FDEVICE))
      {
        *err = DE_INVLDFUNC;
        return 0;
      }

      r->AL = s->sft_flags_lo = SFT_FDEVICE | r->DL;
      break;

    case 0x0c:
      nMode = C_GENIOCTL;
      goto IoCharCommon;
    case 0x02:
      nMode = C_IOCTLIN;
      goto IoCharCommon;
    case 0x10:
      nMode = C_IOCTLQRY;
      goto IoCharCommon;
    case 0x03:
      nMode = C_IOCTLOUT;
    IoCharCommon:
      if (!(s->sft_flags & SFT_FDEVICE)
          || ((r->AL == 0x10) && !(s->sft_dev->dh_attr & ATTR_QRYIOCTL))
          || ((r->AL == 0x0c) && !(s->sft_dev->dh_attr & ATTR_GENIOCTL)))
      {
        if (s->sft_dev->dh_attr & SFT_FIOCTL)
        {
          CharReqHdr.r_unit = 0;
          CharReqHdr.r_length = sizeof(request);
          CharReqHdr.r_command = nMode;
          CharReqHdr.r_count = r->CX;
          CharReqHdr.r_trans = pBuffer;
          CharReqHdr.r_status = 0;
          execrh((request FAR *) & CharReqHdr,
                 s->sft_dev);
          if (CharReqHdr.r_status & S_ERROR)
            return char_error(&CharReqHdr,
                              s->sft_dev);
          if (r->AL == 0x07)
          {
            r->AL =
                CharReqHdr.r_status & S_BUSY ?
                00 : 0xff;
          }
          break;
        }
      }
      *err = DE_INVLDFUNC;
      return 0;

    case 0x0d:
      nMode = C_GENIOCTL;
      goto IoBlockCommon;
    case 0x04:
      nMode = C_IOCTLIN;
      goto IoBlockCommon;
    case 0x11:
      nMode = C_IOCTLQRY;
      goto IoBlockCommon;
    case 0x05:
      nMode = C_IOCTLOUT;
    IoBlockCommon:
      if (!(dpbp->dpb_device->dh_attr & ATTR_IOCTL)
      || ((r->AL == 0x11) && !(dpbp->dpb_device->dh_attr & ATTR_QRYIOCTL))
          || ((r->AL == 0x0d) && !(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL)))
      {
        *err = DE_INVLDFUNC;
        return 0;
      }

      CharReqHdr.r_unit = r->BL;
      CharReqHdr.r_length = sizeof(request);
      CharReqHdr.r_command = nMode;
      CharReqHdr.r_count = r->CX;
      CharReqHdr.r_trans = pBuffer;
      CharReqHdr.r_status = 0;
      execrh((request FAR *) & CharReqHdr,
             dpbp->dpb_device);
      if (r->AL == 0x08)
      {
        if (CharReqHdr.r_status & S_ERROR)
        {
          *err = DE_DEVICE;
          return 0;
        }
        r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
      }
      else
      {
        if (CharReqHdr.r_status & S_ERROR)
        {
          *err = DE_DEVICE;
          return 0;
        }
      }
      break;

    case 0x06:
      if (s->sft_flags & SFT_FDEVICE)
      {
        r->AL = s->sft_flags & SFT_FEOF ? 0 : 0xFF;
      }
      else
        r->AL = s->sft_posit >= s->sft_size ? 0xFF : 0;
      break;

    case 0x07:
      if (s->sft_flags & SFT_FDEVICE)
      {
        goto IoCharCommon;
      }
      r->AL = 0;
      break;

    case 0x08:
      if (dpbp->dpb_device->dh_attr & ATTR_EXCALLS)
      {
        nMode = C_REMMEDIA;
        goto IoBlockCommon;
      }
      *err = DE_INVLDFUNC;
      return 0;

    case 0x09:
      r->DX = dpbp->dpb_device->dh_attr;
      break;

    case 0x0a:
      r->DX = s->sft_dcb->dpb_device->dh_attr;
      break;

    case 0x0e:
      nMode = C_GETLDEV;
      goto IoLogCommon;
    case 0x0f:
      nMode = C_SETLDEV;
    IoLogCommon:
      if (!(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL))
      {
        if (r->BL == 0)
          r->BL = default_drive;

        CharReqHdr.r_unit = r->BL;
        CharReqHdr.r_length = sizeof(request);
        CharReqHdr.r_command = nMode;
        CharReqHdr.r_count = r->CX;
        CharReqHdr.r_trans = pBuffer;
        CharReqHdr.r_status = 0;
        execrh((request FAR *) & CharReqHdr,
               dpbp->dpb_device);

        if (CharReqHdr.r_status & S_ERROR)
          *err = DE_ACCESS;
        else
          *err = SUCCESS;
        return 0;
      }
      *err = DE_INVLDFUNC;
      return 0;

    default:
      *err = DE_INVLDFUNC;
      return 0;
  }
  *err = SUCCESS;
  return 0;
}
Beispiel #10
0
COUNT DosDevIOctl(iregs FAR * r)
{
  sft FAR *s;
  struct dpb FAR *dpbp;
  COUNT nMode;

					/* commonly used, shouldn't harm to do front up */

  CharReqHdr.r_length = sizeof(request);
  CharReqHdr.r_trans  = MK_FP(r->DS, r->DX);
  CharReqHdr.r_status = 0;
  CharReqHdr.r_count  = r->CX;
  


  /* Test that the handle is valid                                */
  switch (r->AL)
  {
    case 0x00:
    case 0x01:
    case 0x02:
    case 0x03:
    case 0x06:
    case 0x07:
    case 0x0a:
    case 0x0c:

      /* Get the SFT block that contains the SFT              */
      if ((s = get_sft(r->BX)) == (sft FAR *) - 1)
        return DE_INVLDHNDL;
      break;

    case 0x04:
    case 0x05:
    case 0x08:
    case 0x09:
    case 0x0d:
    case 0x0e:
    case 0x0f:
    case 0x10:
    case 0x11:

/*
   This line previously returned the deviceheader at r->bl. But,
   DOS numbers its drives starting at 1, not 0. A=1, B=2, and so
   on. Changed this line so it is now zero-based.

   -SRM
 */
/* JPP - changed to use default drive if drive=0 */
/* JT Fixed it */

      CharReqHdr.r_unit = ( r->BL == 0 ? default_drive : r->BL - 1);

      if (CharReqHdr.r_unit >= lastdrive)
        return DE_INVLDDRV;
      else
      {
/*        cdsp = &CDSp->cds_table[CharReqHdr.r_unit];	*/
        dpbp = CDSp->cds_table[CharReqHdr.r_unit].cdsDpb;
      }
      break;

    case 0x0b:
      /* skip, it's a special case.                           */

      NetDelay = r->CX;
      if (!r->DX)
        NetRetry = r->DX;
      break;

    default:
      return DE_INVLDFUNC;
  }

  switch (r->AL)
  {
    case 0x00:
      /* Get the flags from the SFT                           */
      if (s->sft_flags & SFT_FDEVICE)	    
          r->AX = (s->sft_dev->dh_attr & 0xff00) | s->sft_flags_lo;
      else	  
          r->AX = s->sft_flags;
/* Undocumented result, Ax = Dx seen using Pcwatch */
      r->DX = r->AX;	  
      break;

    case 0x01:
      /* sft_flags is a file, return an error because you     */
      /* can't set the status of a file.                      */
      if (!(s->sft_flags & SFT_FDEVICE))
        return DE_INVLDFUNC;

      /* Set it to what we got in the DL register from the    */
      /* user.                                                */
      r->AL = s->sft_flags_lo = SFT_FDEVICE | r->DL;
      break;

    case 0x0c:
      nMode = C_GENIOCTL;
      goto IoCharCommon;
    case 0x02:
      nMode = C_IOCTLIN;
      goto IoCharCommon;
    case 0x10:
      nMode = C_IOCTLQRY;
      goto IoCharCommon;
    case 0x03:
      nMode = C_IOCTLOUT;
    IoCharCommon:
      if ((s->sft_flags & SFT_FDEVICE)
            || ((r->AL == 0x02 ) && (s->sft_dev->dh_attr & SFT_FIOCTL))
            || ((r->AL == 0x03 ) && (s->sft_dev->dh_attr & SFT_FIOCTL))
            || ((r->AL == 0x10) && (s->sft_dev->dh_attr & ATTR_QRYIOCTL))
            || ((r->AL == 0x0c) && (s->sft_dev->dh_attr & ATTR_GENIOCTL)))
      {
          CharReqHdr.r_unit = 0;
          CharReqHdr.r_command = nMode;
          execrh((request FAR *) & CharReqHdr, s->sft_dev);

          if (CharReqHdr.r_status & S_ERROR)
          {
            CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
            return DE_DEVICE;
          }

          if (r->AL == 0x07)
          {
            r->AL = CharReqHdr.r_status & S_BUSY ? 00 : 0xff;

          }
          else if (r->AL == 0x02 || r->AL == 0x03)
          {
            r->AX = CharReqHdr.r_count;
          }

          else if (r->AL == 0x0c || r->AL == 0x10)
          {
            r->AX = CharReqHdr.r_status;
          }
          break;
      }
      return DE_INVLDFUNC;

    case 0x0d:
      nMode = C_GENIOCTL;
      goto IoBlockCommon;
    case 0x04:
      nMode = C_IOCTLIN;
      goto IoBlockCommon;
    case 0x11:
      nMode = C_IOCTLQRY;
      goto IoBlockCommon;
    case 0x05:
      nMode = C_IOCTLOUT;
    IoBlockCommon:
      if(!dpbp)
      {
        return DE_INVLDDRV;
      }
      if ( ((r->AL == 0x04 ) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
            || ((r->AL == 0x05 ) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
            || ((r->AL == 0x11) && !(dpbp->dpb_device->dh_attr & ATTR_QRYIOCTL))
            || ((r->AL == 0x0d) && !(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL)))
      {
        return DE_INVLDFUNC;
      }


      CharReqHdr.r_command = nMode;
      execrh((request FAR *) & CharReqHdr,
             dpbp->dpb_device);

        if (CharReqHdr.r_status & S_ERROR)
        {
            CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
            return DE_DEVICE;
        }
        if (r->AL == 0x08)
        {
            r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;

        }

        else if (r->AL == 0x04 || r->AL == 0x05)
        {
            r->AX = CharReqHdr.r_count;

        }
        else if (r->AL == 0x0d || r->AL == 0x11)
        {
            r->AX = CharReqHdr.r_status;
        }
        break;

    case 0x06:
      if (s->sft_flags & SFT_FDEVICE)
      {
        r->AL = s->sft_flags & SFT_FEOF ? 0xFF : 0;
      }
      else
        r->AL = s->sft_posit >= s->sft_size ? 0xFF : 0;
      break;

    case 0x07:
      if (s->sft_flags & SFT_FDEVICE)
      {
        nMode = C_OSTAT;
        goto IoCharCommon;
      }
      r->AL = 0;
      break;

    case 0x08:
      if(!dpbp)
      {
        return DE_INVLDDRV;
      }
      if (dpbp->dpb_device->dh_attr & ATTR_EXCALLS)
      {
        nMode = C_REMMEDIA;
        goto IoBlockCommon;
      }
      return DE_INVLDFUNC;

    case 0x09:
      if(CDSp->cds_table[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV)
        {
            r->DX = ATTR_REMOTE ;
            r->AX = S_DONE|S_BUSY;
        }
        else
        {
            if(!dpbp)
            {
                return DE_INVLDDRV;
            }
/* Need to add subst bit 15  */
            r->DX = dpbp->dpb_device->dh_attr;
            r->AX = S_DONE|S_BUSY;
        }
      break;

    case 0x0a:
      r->DX = s->sft_flags;
      r->AX = 0;
      break;

    case 0x0e:
      nMode = C_GETLDEV;
      goto IoLogCommon;
    case 0x0f:
      nMode = C_SETLDEV;
    IoLogCommon:
      if(!dpbp)
      {
        return DE_INVLDDRV;
      }
      if ((dpbp->dpb_device->dh_attr & ATTR_GENIOCTL))
      {


        CharReqHdr.r_command = nMode;
        execrh((request FAR *) & CharReqHdr,
               dpbp->dpb_device);

        if (CharReqHdr.r_status & S_ERROR)
        {
          CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
          return DE_ACCESS;
        }
        else
        {
            r->AL = CharReqHdr.r_unit;
            return SUCCESS;
        }
      }
      return DE_INVLDFUNC;

    default:
      return DE_INVLDFUNC;
  }
  return SUCCESS;
}
Beispiel #11
0
/* Changed to UWORD  9/4/00  BER */
UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, COUNT mode)
/* End of change */
{
/*  REG struct dpb *dpbp = &blk_devices[dsk]; */

  REG struct dpb FAR *dpbp = CDSp->cds_table[dsk].cdsDpb;


  if ((UCOUNT)dsk >= lastdrive )
      {
      return 0x0201;        /* illegal command */
      }
  if (!(CDSp->cds_table[dsk].cdsFlags & CDSPHYSDRV))
      {
      return 0x0201;        /* illegal command */
      }
  
#if TOM
#define KeyboardShiftState() (*(BYTE FAR *)(MK_FP(0x40,0x17)))

  if (KeyboardShiftState() & 0x01)
    {
    printf("dskxfer:%s %x - %lx %u\n", mode == DSKWRITE ? "write" : "read", dsk, blkno, numblocks);
    if ((KeyboardShiftState() & 0x03) == 3)
        dumpBufferCache();
    }
#endif

  for (;;)
  {
    IoReqHdr.r_length = sizeof(request);
    IoReqHdr.r_unit = dpbp->dpb_subunit;

    switch(mode) 
        {
	    case DSKWRITE :     if (verify_ena) { IoReqHdr.r_command = C_OUTVFY; break; }
	                                                /* else fall through */
	    case DSKWRITEINT26: IoReqHdr.r_command = C_OUTPUT; break;
	    
	    case DSKREADINT25: 
	    case DSKREAD  :     IoReqHdr.r_command = C_INPUT; break;
	    default:
	        return 0x0100;  /* illegal command */
	    }    
    
    IoReqHdr.r_status = 0;
    IoReqHdr.r_meddesc = dpbp->dpb_mdb;
    IoReqHdr.r_trans = (BYTE FAR *) buf;
    IoReqHdr.r_count = numblocks;
    if (blkno >= MAXSHORT)
    {
      IoReqHdr.r_start = HUGECOUNT;
      IoReqHdr.r_huge = blkno;
    }
    else
      IoReqHdr.r_start = blkno;
    execrh((request FAR *) & IoReqHdr, dpbp->dpb_device);
    if (!(IoReqHdr.r_status & S_ERROR) && (IoReqHdr.r_status & S_DONE))
      break;

                        /* INT25/26 (_SEEMS_ TO) return immediately with 0x8002,
                           if drive is not online,...
                           
                           normal operations (DIR) wait for ABORT/RETRY
                           
                           other condition codes not tested
                        */
    if (mode >= DSKWRITEINT26)
        return (IoReqHdr.r_status);

/* Changed 9/4/00   BER
    return (IoReqHdr.r_status);  
*/


    
    
    /* Skip the abort, retry, fail code...it needs fixed...BER */
/* End of change */

    loop:
      switch (block_error(&IoReqHdr, dpbp->dpb_unit, dpbp->dpb_device))
      {
	case ABORT:
	case FAIL:
	  return (IoReqHdr.r_status);

	case RETRY:
	  continue;

	case CONTINUE:
	  break;

	default:
	  goto loop;
      }

  } /* retry loop */
/* *** Changed 9/4/00  BER */
  return 0;   /* Success!  Return 0 for a successful operation. */
/* End of change */

}
Beispiel #12
0
int DosDevIOctl(lregs * r)
{
  struct dhdr FAR *dev;

  if (r->AL > 0x11)
    return DE_INVLDFUNC;

  switch (r->AL)
  {
    case 0x0b:
      /* skip, it's a special case.                           */
      NetDelay = r->CX;
      if (r->DX)
        NetRetry = r->DX;
      return SUCCESS;

    case 0x00:
    case 0x01:
    case 0x02:
    case 0x03:
    case 0x06:
    case 0x07:
    case 0x0a:
    case 0x0c:
    case 0x10:
    {
      sft FAR *s;
      unsigned flags;

      /* Test that the handle is valid and                    */
      /* get the SFT block that contains the SFT              */
      if ((s = get_sft(r->BX)) == (sft FAR *) - 1)
        return DE_INVLDHNDL;

      flags = s->sft_flags;

      switch (r->AL)
      {
        case 0x00:
          /* Get the flags from the SFT                           */
          if (flags & SFT_FDEVICE)
            r->AX = (flags & 0xff) | (s->sft_dev->dh_attr & 0xff00);
          else
            r->AX = flags;
          /* Undocumented result, Ax = Dx seen using Pcwatch */
          r->DX = r->AX;
          return SUCCESS;

        case 0x01:
          /* sft_flags is a file, return an error because you     */
          /* can't set the status of a file.                      */
          if (!(flags & SFT_FDEVICE))
            return DE_INVLDFUNC;
          /* RBIL says this is only for DOS < 6, but MSDOS 7.10   */
          /* returns this as well... and some buggy program relies*/
          /* on it :(                                             */
          if (r->DH != 0)
            return DE_INVLDDATA;

          /* Undocumented: AL should get the old value            */
          r->AL = s->sft_flags_lo;
          /* Set it to what we got in the DL register from the    */
          /* user.                                                */
          s->sft_flags_lo = SFT_FDEVICE | r->DL;
          return SUCCESS;

        case 0x0a:
          r->DX = flags;
          r->AX = 0;
          return SUCCESS;
      }
      if (!(flags & SFT_FDEVICE))
      {
        if (r->AL == 0x06)
          r->AL = s->sft_posit >= s->sft_size ? 0 : 0xFF;
        else if (r->AL == 0x07)
          r->AL = 0;
        else
          return DE_INVLDFUNC;
        return SUCCESS;
      }
      dev = s->sft_dev;
      CharReqHdr.r_unit = 0;
      break;
    }

    default: /* block IOCTL: 4, 5, 8, 9, d, e, f, 11 */
    {
      struct dpb FAR *dpbp;
      unsigned attr;
/*
   This line previously returned the deviceheader at r->bl. But,
   DOS numbers its drives starting at 1, not 0. A=1, B=2, and so
   on. Changed this line so it is now zero-based.

   -SRM
 */
/* JPP - changed to use default drive if drive=0 */
/* JT Fixed it */

      /* NDN feeds the actual ASCII drive letter to this function */
      dpbp = get_dpb((r->BL & 0x1f) == 0 ? default_drive : (r->BL & 0x1f) - 1);
      if (dpbp)
      {
        CharReqHdr.r_unit = dpbp->dpb_subunit;
        dev = dpbp->dpb_device;
        attr = dev->dh_attr;
      }
      else
      {
        if (r->AL != 9)
          return DE_INVLDDRV;
        dev = NULL;
        attr = ATTR_REMOTE;
      }

      switch (r->AL)
      {
        case 0x09:
        {
          /* note from get_dpb()                            */
          /* that if cdsp == NULL then dev must be NULL too */
          struct cds FAR *cdsp = get_cds1(r->BL & 0x1f);
          if (cdsp == NULL)
            return DE_INVLDDRV;
          if (cdsp->cdsFlags & CDSSUBST)
            attr |= ATTR_SUBST;
          r->AX = S_DONE | S_BUSY;
          r->DX = attr;
          return SUCCESS;
        }
        case 0x0d:
          if ((r->CX & ~(0x486B-0x084A)) == 0x084A)
          {             /* 084A/484A, 084B/484B, 086A/486A, 086B/486B */
            r->AX = 0;  /* (lock/unlock logical/physical volume) */
            /* simulate success for MS-DOS 7+ SCANDISK etc. --LG */
            return SUCCESS;
          }
          /* fall through */
        default: /* 0x04, 0x05, 0x08, 0x0e, 0x0f, 0x11 */
          break;
      }
      break;
    }
  }

  {
    unsigned testattr = ATTR_QRYIOCTL;
    if (r->AL<=0x0f)
      testattr = ATTR_GENIOCTL;
    if (r->AL<=0x08)
      testattr = ATTR_EXCALLS;
    if (r->AL<=0x07)
      testattr = 0xffff;
    if (r->AL<=0x05)
      testattr = ATTR_IOCTL;

    if (!(dev->dh_attr & testattr))
      return DE_INVLDFUNC;
  }

  CharReqHdr.r_command = cmd[r->AL];
  if (r->AL == 0x0C || r->AL == 0x0D || r->AL >= 0x10) /* generic or query */
  {
    CharReqHdr.r_cat = r->CH;            /* category (major) code */
    CharReqHdr.r_fun = r->CL;            /* function (minor) code */
    CharReqHdr.r_si = r->SI;             /* contents of SI and DI */
    CharReqHdr.r_di = r->DI;
    CharReqHdr.r_io = MK_FP(r->DS, r->DX);    /* parameter block */
  }
  else
  {
    CharReqHdr.r_count = r->CX;
    CharReqHdr.r_trans = MK_FP(r->DS, r->DX);
  }
  CharReqHdr.r_length = sizeof(request);
  CharReqHdr.r_status = 0;

  execrh(&CharReqHdr, dev);

  if (CharReqHdr.r_status & S_ERROR)
  {
    CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
    return DE_ACCESS;
  }

  if (r->AL <= 0x05)                       /* 0x02, 0x03, 0x04, 0x05 */
    r->AX = CharReqHdr.r_count;
  else if (r->AL <= 0x07)                  /* 0x06, 0x07 */
    r->AX = (CharReqHdr.r_status & S_BUSY) ? 0000 : 0x00ff;
  else if (r->AL == 0x08)                  /* 0x08 */
    r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
  else if (r->AL == 0x0e || r->AL == 0x0f) /* 0x0e, 0x0f */
    r->AL = CharReqHdr.r_unit;
  else                                     /* 0x0c, 0x0d, 0x10, 0x11 */
    r->AX = CharReqHdr.r_status;
  return SUCCESS;
}