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

📄 dosfns.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 3 页
字号:
13 O_NOCRIT do not invoke int23 (not implemented yet)12 O_LARGEFILE allow files >= 2gb but < 4gb (not implemented yet)11 O_LEGACY not called from int21/ah=6c: find right fn for redirector10 O_CREAT if file does not exist, create it9 O_TRUNC if file exists, truncate and open it \ not both 8 O_OPEN  if file exists, open it              /7 O_NOINHERIT do not inherit handle on exec6 \ 5  - sharing modes4 / 3 reserved 2 bits 2,1,0 = 100: RDONLY and do not modify file's last access time                    (not implemented yet)1 \ 0=O_RDONLY, 1=O_WRONLY,0 / 2=O_RDWR, 3=O_EXECCASE (preserve case for redirector EXEC,                            (not implemented yet))*/long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib){  COUNT sft_idx;  sft FAR *sftp;  struct dhdr FAR *dhp;  long result;  result = truename(fname, PriPathName, CDS_MODE_CHECK_DEV_PATH);  if (result < SUCCESS)    return result;  /* now get a free system file table entry       */  if ((sftp = get_free_sft(&sft_idx)) == (sft FAR *) - 1)    return DE_TOOMANY;  fmemset(sftp, 0, sizeof(sft));  sftp->sft_psp = cu_psp;  sftp->sft_mode = flags & 0xf0ff;  OpenMode = (BYTE) flags;  sftp->sft_shroff = -1;        /* /// Added for SHARE - Ron Cemer */  sftp->sft_attrib = attrib = attrib | D_ARCHIVE;  if (result & IS_NETWORK)  {    int status;    unsigned cmd;    if ((flags & (O_TRUNC | O_CREAT)) == O_CREAT)      attrib |= 0x100;    lpCurSft = sftp;    cmd = REM_CREATE;    if (!(flags & O_LEGACY))    {      extern UWORD ASM ext_open_mode, ASM ext_open_attrib, ASM ext_open_action;      ext_open_mode = flags & 0x70ff;      ext_open_attrib = attrib & 0xff;      ext_open_action = ((flags & 0x0300) >> 8) | ((flags & O_CREAT) >> 6);      cmd = REM_EXTOC;    }    else if (!(flags & O_CREAT))    {      cmd = REM_OPEN;      attrib = (BYTE)flags;    }    status = (int)network_redirector_mx(cmd, sftp, (void *)attrib);    if (status >= SUCCESS)    {      if (sftp->sft_count == 0)        sftp->sft_count++;      return sft_idx | ((long)status << 16);    }    return status;  }  /* check for a device   */  if ((result & IS_DEVICE) && (dhp = IsDevice(fname)) != NULL)  {    int rc = DeviceOpenSft(dhp, sftp);    /* check the status code returned by the     * driver when we tried to open it     */    if (rc < SUCCESS)      return rc;    return sft_idx;  }/* /// Added for SHARE.  - Ron Cemer */  if (IsShareInstalled())  {    if ((sftp->sft_shroff =         share_open_check(PriPathName, cu_psp,                          flags & 0x03, (flags >> 4) & 0x07)) < 0)      return sftp->sft_shroff;  }  /* /// End of additions for SHARE.  - Ron Cemer */  /* NEVER EVER allow directories to be created */  /* ... though FCB's are weird :) */  if (!(flags & O_FCB) &&      (attrib & ~(D_RDONLY | D_HIDDEN | D_SYSTEM | D_ARCHIVE | D_VOLID)))    return DE_ACCESS;    result = dos_open(PriPathName, flags, attrib);  if (result >= 0)  {    int status = (int)(result >> 16);    if (status == S_OPENED)    {      sftp->sft_attrib = dos_getfattr_fd((COUNT)result);      /* Check permissions. -- JPP         (do not allow to open volume labels/directories) */      if (sftp->sft_attrib & (D_DIR | D_VOLID))      {        dos_close((COUNT)result);        return DE_ACCESS;      }      sftp->sft_size = dos_getfsize((COUNT)result);    }    sftp->sft_status = (COUNT)result;    sftp->sft_flags = PriPathName[0] - 'A';    sftp->sft_count += 1;    DosGetFile(PriPathName, sftp->sft_name);    dos_getftime(sftp->sft_status,                 (date FAR *) & sftp->sft_date,                 (time FAR *) & sftp->sft_time);    return sft_idx | ((long)status << 16);  }  else  {/* /// Added for SHARE *** CURLY BRACES ADDED ALSO!!! ***.  - Ron Cemer */    if (IsShareInstalled())    {      share_close_file(sftp->sft_shroff);      sftp->sft_shroff = -1;    }/* /// End of additions for SHARE.  - Ron Cemer */    return result;  }    }long DosOpen(char FAR * fname, unsigned mode, unsigned attrib){  long result;  unsigned hndl;    /* test if mode is in range                     */  if ((mode & ~O_VALIDMASK) != 0)    return DE_INVLDACC;  /* get a free handle  */  if ((result = get_free_hndl()) < 0)    return result;  hndl = (unsigned)result;  result = DosOpenSft(fname, mode, attrib);  if (result < SUCCESS)    return result;  ((psp FAR *)MK_FP(cu_psp, 0))->ps_filetab[hndl] = (UBYTE)result;  return hndl | (result & 0xffff0000l);}COUNT CloneHandle(unsigned hndl){  /* now get the system file table entry                          */  sft FAR *sftp = get_sft(hndl);  if (sftp == (sft FAR *) -1 || (sftp->sft_mode & O_NOINHERIT))    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;}long DosDup(unsigned Handle){  long NewHandle;  if ((NewHandle = get_free_hndl()) < 0)    return NewHandle;  if (DosForceDup(Handle, (unsigned)NewHandle) < 0)    return DE_INVLDHNDL;  else    return NewHandle;}COUNT DosForceDup(unsigned OldHandle, unsigned 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;  /* 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 | SFT_FSHARED))      || (Sftp->sft_status >= 0))  {    p->ps_filetab[NewHandle] = p->ps_filetab[OldHandle];    /* possible hazard: integer overflow ska*/    Sftp->sft_count += 1;    return SUCCESS;  }  else    return DE_INVLDHNDL;}COUNT DosCloseSft(int sft_idx, BOOL commitonly){  sft FAR *sftp = idx_to_sft(sft_idx);  if (FP_OFF(sftp) == (size_t) - 1)    return DE_INVLDHNDL;  lpCurSft = sftp;/*   remote sub sft_count. */  if (sftp->sft_flags & SFT_FSHARED)  {    /* printf("closing SFT %d = %p\n",sft_idx,sftp); */    return network_redirector_fp(commitonly ? REM_FLUSH: REM_CLOSE, sftp);  }  /* now just drop the count if a device, else    */  /* call file system handler                     */  if (!commitonly)    sftp->sft_count -= 1;  if (sftp->sft_flags & SFT_FDEVICE)  {    if (sftp->sft_dev->dh_attr & SFT_FOCRM)    {      /* if Open/Close/RM bit in driver's attribute is set       * then issue a Close request to the driver       */      struct dhdr FAR *dev = sftp->sft_dev;      if (BinaryCharIO(&dev, 0, MK_FP(0x0000, 0x0000), C_CLOSE) != SUCCESS)        return DE_ACCESS;    }    return SUCCESS;  }  if (commitonly || sftp->sft_count > 0)    return dos_commit(sftp->sft_status);/* /// Added for SHARE *** CURLY BRACES ADDED ALSO!!! ***.  - Ron Cemer */  if (IsShareInstalled())  {    if (sftp->sft_shroff >= 0)      share_close_file(sftp->sft_shroff);    sftp->sft_shroff = -1;  }/* /// End of additions for SHARE.  - Ron Cemer */  return dos_close(sftp->sft_status);}COUNT DosClose(COUNT hndl){  psp FAR *p = MK_FP(cu_psp, 0);  COUNT ret;  /* Get the SFT block that contains the SFT      */  ret = DosCloseSft(get_sft_idx(hndl), FALSE);  if (ret != DE_INVLDHNDL && ret != DE_ACCESS)    p->ps_filetab[hndl] = 0xff;  return ret;}UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc){  /* navc==NULL means: called from FatGetDrvData, fcbfns.c */  struct dpb FAR *dpbp;  struct cds FAR *cdsp;  COUNT rg[4];  UWORD spc;  /* next - "log" in the drive            */  drive = (drive == 0 ? default_drive : drive - 1);  /* first check for valid drive          */  spc = -1;  cdsp = get_cds(drive);  if (cdsp == NULL)    return spc;  if (cdsp->cdsFlags & CDSNETWDRV)  {    if (remote_getfree(cdsp, rg) != SUCCESS)      return spc;    /* for int21/ah=1c:       Undoc DOS says, its not supported for       network drives. so it's probably OK */    /* some programs such as RHIDE want it though and       the redirector can provide all info       - Bart, 2002 Apr 1 */    spc = rg[0];    if (navc != NULL)    {      *navc = (COUNT) rg[3];      spc &= 0xff; /* zero out media ID byte */    }    *nc = (COUNT) rg[1];    *bps = (COUNT) rg[2];    return spc;  }  dpbp = cdsp->cdsDpb;  if (dpbp == NULL)    return spc;  if (navc == NULL)  {      /* hazard: no error checking! */    flush_buffers(dpbp->dpb_unit);    dpbp->dpb_flags = M_CHANGED;  }  if (media_check(dpbp) < 0)    return spc;  /* get the data available from dpb      */  spc = (dpbp->dpb_clsmask + 1);  *bps = dpbp->dpb_secsize;  /* now tell fs to give us free cluster  */  /* count                                */#ifdef WITHFAT32  if (ISFAT32(dpbp))  {    ULONG cluster_size, ntotal, nfree;    /* we shift ntotal until it is equal to or below 0xfff6 */    cluster_size = (ULONG) dpbp->dpb_secsize << dpbp->dpb_shftcnt;    ntotal = dpbp->dpb_xsize - 1;    if (navc != NULL)      nfree = dos_free(dpbp);    while (ntotal > FAT_MAGIC16 && cluster_size < 0x8000)    {      cluster_size <<= 1;      spc <<= 1;      ntotal >>= 1;      nfree >>= 1;    }    /* get the data available from dpb      */    *nc = ntotal > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT) ntotal;    /* now tell fs to give us free cluster  */    /* count                                */    if (navc != NULL)      *navc = nfree > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT) nfree;    return spc;  }#endif  /* a passed navc of NULL means: skip free; see FatGetDrvData     fcbfns.c */  if (navc != NULL)    *navc = (COUNT) dos_free(dpbp);  *nc = dpbp->dpb_size - 1;  if (spc > 64)  {    /* fake for 64k clusters do confuse some DOS programs, but let       others work without overflowing */    spc >>= 1;    if (navc != NULL)      *navc = ((unsigned)*navc < FAT_MAGIC16 / 2) ?        ((unsigned)*navc << 1) : FAT_MAGIC16;    *nc = ((unsigned)*nc < FAT_MAGIC16 / 2) ? ((unsigned)*nc << 1) : FAT_MAGIC16;  }  return spc;}#ifdef WITHFAT32/* network names like \\SERVER\C aren't supported yet */#define IS_SLASH(ch) (ch == '\\' || ch == '/')COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp){  struct dpb FAR *dpbp;  struct cds FAR *cdsp;  UCOUNT rg[4];  if (IS_SLASH(DriveString[0]) || !IS_SLASH(DriveString[2])      || DriveString[1] != ':')    return DE_INVLDDRV;  cdsp = get_cds(DosUpFChar(*DriveString) - 'A');  if (cdsp == NULL)    return DE_INVLDDRV;  if (cdsp->cdsFlags & CDSNETWDRV)  {    if (remote_getfree(cdsp, rg) != SUCCESS)      return DE_INVLDDRV;    xfsp->xfs_clussize = rg[0];    xfsp->xfs_totalclusters = rg[1];    xfsp->xfs_secsize = rg[2];    xfsp->xfs_freeclusters = rg[3];  }  else  {    dpbp = cdsp->cdsDpb;    if (dpbp == NULL || media_check(dpbp) < 0)      return DE_INVLDDRV;    xfsp->xfs_secsize = dpbp->dpb_secsize;    xfsp->xfs_totalclusters =        (ISFAT32(dpbp) ? dpbp->dpb_xsize : dpbp->dpb_size);    xfsp->xfs_freeclusters = dos_free(dpbp);    xfsp->xfs_clussize = dpbp->dpb_clsmask + 1;  }  xfsp->xfs_totalunits = xfsp->xfs_totalclusters;  xfsp->xfs_freeunits = xfsp->xfs_freeclusters;  xfsp->xfs_totalsectors = xfsp->xfs_totalclusters * xfsp->xfs_clussize;  xfsp->xfs_freesectors = xfsp->xfs_freeclusters * xfsp->xfs_clussize;  xfsp->xfs_datasize = sizeof(struct xfreespace);  fmemset(xfsp->xfs_reserved, 0, 8);  return SUCCESS;}#endifCOUNT DosGetCuDir(UBYTE drive, BYTE FAR * s){  BYTE *cp;  struct cds FAR *cdsp;  /* next - "log" in the drive            */  /* first check for valid drive          */  cdsp = get_cds(drive == 0 ? default_drive : drive - 1);  if (cdsp == NULL)    return DE_INVLDDRV;  fmemcpy(&TempCDS, cdsp, sizeof(TempCDS));  cp = TempCDS.cdsCurrentPath;  /* ensure termination of fstrcpy */  cp[MAX_CDSPATH - 1] = '\0';  if ((TempCDS.cdsFlags & CDSNETWDRV) == 0)  {    /* dos_cd ensures that the path exists; if not, we       need to change to the root directory */    int result = dos_cd(cp);    if (result == DE_PATHNOTFND)      cp[TempCDS.cdsBackslashOffset + 1] =        cdsp->cdsCurrentPath[TempCDS.cdsBackslashOffset + 1] = '\0';    else if (result < SUCCESS)      return result;  }  cp += TempCDS.cdsBackslashOffset;  if (*cp == '\0')    s[0] = '\0';  else    fstrcpy(s, cp + 1);  return SUCCESS;}#undef CHDIR_DEBUGCOUNT DosChangeDir(BYTE FAR * s){  COUNT result;  BYTE FAR *p;  /* don't do wildcard CHDIR --TE */  for (p = s; *p; p++)    if (*p == '*' || *p == '?')      return DE_PATHNOTFND;  result = truename(s, PriPathName, CDS_MODE_CHECK_DEV_PATH);  if (result < SUCCESS)  {    return result;  }  if ((FP_OFF(current_ldt) != 0xFFFF) &&

⌨️ 快捷键说明

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