📄 dosfns.c
字号:
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 + -