Beispiel #1
0
COUNT DosForceDup(COUNT OldHandle, COUNT NewHandle)
{
  psp FAR *p = MK_FP(cu_psp, 0);
  sft FAR *Sftp;

  /* Get the SFT block that contains the SFT                      */
  if ((Sftp = get_sft(OldHandle)) == (sft FAR *) - 1)
    return DE_INVLDHNDL;

  /* If not open - exit                                           */
  if (Sftp->sft_count <= 0)
    return DE_INVLDHNDL;

  /* now close the new handle if it's open                        */
  if ((UBYTE) p->ps_filetab[NewHandle] != 0xff)
  {
    COUNT ret;

    if ((ret = DosClose(NewHandle)) != SUCCESS)
      return ret;
  }

  /* If everything looks ok, bump it up.                          */
  if ((Sftp->sft_flags & SFT_FDEVICE) || (Sftp->sft_status >= 0))
  {
    p->ps_filetab[NewHandle] = p->ps_filetab[OldHandle];

    Sftp->sft_count += 1;
    return NewHandle;
  }
  else
    return DE_INVLDHNDL;
}
Beispiel #2
0
COUNT DosSetFtime(COUNT hndl, date FAR * dp, time FAR * tp)
{
  sft FAR *s;
  sfttbl FAR *sp;

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

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

  /* If this is not opened another error          */
  if (s->sft_count == 0)
    return DE_ACCESS;

  /* If SFT entry refers to a device, do nothing */
  if (s->sft_flags & SFT_FDEVICE)
    return SUCCESS;

  if (s->sft_flags & SFT_FSHARED)
  {
    s->sft_date = *dp;
    s->sft_time = *tp;
    return SUCCESS;
  }

  /* call file system handler                     */
  return dos_setftime(s->sft_status, dp, tp);
}
Beispiel #3
0
COUNT DosDup(COUNT Handle)
{
  psp FAR *p = MK_FP(cu_psp, 0);
  COUNT NewHandle;
  sft FAR *Sftp;

  /* Get the SFT block that contains the SFT                      */
  if ((Sftp = get_sft(Handle)) == (sft FAR *) - 1)
    return DE_INVLDHNDL;

  /* If not open - exit                                           */
  if (Sftp->sft_count <= 0)
    return DE_INVLDHNDL;

  /* now get a free handle                                        */
  if ((NewHandle = get_free_hndl()) == 0xff)
    return DE_TOOMANY;

  /* If everything looks ok, bump it up.                          */
  if ((Sftp->sft_flags & SFT_FDEVICE) || (Sftp->sft_status >= 0))
  {
    p->ps_filetab[NewHandle] = p->ps_filetab[Handle];
    Sftp->sft_count += 1;
    return NewHandle;
  }
  else
    return DE_INVLDHNDL;
}
Beispiel #4
0
COUNT DosSeek(COUNT hndl, LONG new_pos, COUNT mode, ULONG * set_pos)
{
  sft FAR *s;
  ULONG lrx;

  /* Test for invalid mode                        */
  if (mode < 0 || mode > 2)
    return DE_INVLDFUNC;

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

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

  lpCurSft = (sfttbl FAR *) s;

  if (s->sft_flags & SFT_FSHARED)
  {
    if (mode == 2)
    {                           /* seek from end of file */
      int2f_Remote_call(REM_LSEEK, 0, (UWORD) FP_SEG(new_pos), (UWORD) FP_OFF(new_pos), (VOID FAR *) s, 0, 0);
      *set_pos = s->sft_posit;
      return SUCCESS;
    }
    if (mode == 0)
    {
      s->sft_posit = new_pos;
      *set_pos = new_pos;
      return SUCCESS;
    }
    if (mode == 1)
    {
      s->sft_posit += new_pos;
      *set_pos = s->sft_posit;
      return SUCCESS;
    }
    return DE_INVLDFUNC;
  }

  /* Do special return for character devices      */
  if (s->sft_flags & SFT_FDEVICE)
  {
    *set_pos = 0l;
    return SUCCESS;
  }
  else
  {
    *set_pos = dos_lseek(s->sft_status, new_pos, mode);
    if ((LONG) * set_pos < 0)
      return (int)*set_pos;
    else
      return SUCCESS;
  }
}
Beispiel #5
0
int StdinBusy(void)
{
  sft FAR *s = get_sft(STDIN);
  struct dhdr FAR *dev = sft_to_dev(s);

  if (dev)
    return Busy(&dev);

  return s->sft_posit >= s->sft_size;
}
Beispiel #6
0
COUNT CloneHandle(COUNT hndl)
{
  sft FAR *sftp;

  /* now get the system file table entry                          */
  if ((sftp = get_sft(hndl)) == (sft FAR *) - 1)
    return DE_INVLDHNDL;

  /* now that we have the system file table entry, get the fnode  */
  /* index, and increment the count, so that we've effectively    */
  /* cloned the file.                                             */
  sftp->sft_count += 1;
  return SUCCESS;
}
Beispiel #7
0
COUNT DosClose(COUNT hndl)
{
  psp FAR *p = MK_FP(cu_psp, 0);
  sft FAR *s;

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

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

  /* If this is not opened another error          */
  if (s->sft_count == 0)
    return DE_ACCESS;

  lpCurSft = (sfttbl FAR *) s;
/*
   remote sub sft_count.
 */
  if (s->sft_flags & SFT_FSHARED)
  {
    int2f_Remote_call(REM_CLOSE, 0, 0, 0, (VOID FAR *) s, 0, 0);
    p->ps_filetab[hndl] = 0xff;
    s->sft_flags = 0;
    return SUCCESS;
  }

  /* now just drop the count if a device, else    */
  /* call file system handler                     */
  if (s->sft_flags & SFT_FDEVICE)
  {
    p->ps_filetab[hndl] = 0xff;
    s->sft_count -= 1;
    return SUCCESS;
  }
  else
  {
    p->ps_filetab[hndl] = 0xff;
    s->sft_count -= 1;
    if (s->sft_count > 0)
      return SUCCESS;
    else
      return dos_close(s->sft_status);
  }
}
Beispiel #8
0
void write_char_stdout(int c)
{
  unsigned char count = 1;
  unsigned flags = get_sft(STDOUT)->sft_flags;

  /* ah=2, ah=9 should expand tabs even for raw devices and disk files */
  if ((flags & (SFT_FDEVICE|SFT_FBINARY)) != SFT_FDEVICE)
  {
    if (c == HT) {
      count = 8 - (scr_pos & 7);
      c = ' ';
    }
    /* for raw CONOUT devices already updated in dosfns.c */
    if ((flags & (SFT_FDEVICE|SFT_FCONOUT)) != (SFT_FDEVICE|SFT_FCONOUT))
      update_scr_pos(c, count);
  }

  do {
    write_char(c, get_sft_idx(STDOUT));
  } while (--count != 0);
}
Beispiel #9
0
LONG DosGetFsize(COUNT hndl)
{
  sft FAR *s;
/*  sfttbl FAR *sp;*/

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

  /* If this is not opened another error          */
  if (s->sft_count == 0)
    return DE_ACCESS;

  /* If SFT entry refers to a device, return the date and time of opening */
  if (s->sft_flags & (SFT_FDEVICE | SFT_FSHARED))
  {
    return s->sft_size;
  }

  /* call file system handler                     */
  return dos_getfsize(s->sft_status);
}
Beispiel #10
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 #11
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 #12
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 #13
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 #14
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 #15
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;
}