📄 fcbfns.c
字号:
lpFcb->fcb_curec = (UBYTE)lpFcb->fcb_rndm & 127;}UBYTE FcbRandomBlockIO(xfcb FAR * lpXfcb, UWORD *nRecords, int mode){ UBYTE nErrorCode; fcb FAR *lpFcb; unsigned long old; FcbCalcRec(lpXfcb); /* Convert to fcb if necessary */ lpFcb = ExtFcbToFcb(lpXfcb); old = lpFcb->fcb_rndm; nErrorCode = FcbReadWrite(lpXfcb, *nRecords, mode); *nRecords = (UWORD)(lpFcb->fcb_rndm - old); /* Now update the fcb */ FcbCalcRec(lpXfcb); return nErrorCode;}UBYTE FcbRandomIO(xfcb FAR * lpXfcb, int mode){ UWORD uwCurrentBlock; UBYTE ucCurrentRecord; UBYTE nErrorCode; fcb FAR *lpFcb; FcbCalcRec(lpXfcb); /* Convert to fcb if necessary */ lpFcb = ExtFcbToFcb(lpXfcb); uwCurrentBlock = lpFcb->fcb_cublock; ucCurrentRecord = lpFcb->fcb_curec; nErrorCode = FcbReadWrite(lpXfcb, 1, mode); lpFcb->fcb_cublock = uwCurrentBlock; lpFcb->fcb_curec = ucCurrentRecord; return nErrorCode;}/* merged fcbOpen and FcbCreate - saves ~200 byte */UBYTE FcbOpen(xfcb FAR * lpXfcb, unsigned flags){ sft FAR *sftp; COUNT sft_idx, FcbDrive; unsigned attr = 0; /* Build a traditional DOS file name */ fcb FAR *lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive); if ((flags & O_CREAT) && lpXfcb->xfcb_flag == 0xff) /* pass attribute without constraints (dangerous for directories) */ attr = lpXfcb->xfcb_attrib; sft_idx = (short)DosOpenSft(SecPathName, flags, attr); if (sft_idx < 0) { CritErrCode = -sft_idx; return FCB_ERROR; } sftp = idx_to_sft(sft_idx); sftp->sft_mode |= O_FCB; lpFcb->fcb_sftno = sft_idx; lpFcb->fcb_curec = 0; lpFcb->fcb_rndm = 0; lpFcb->fcb_recsiz = 0; /* true for devices */ if (!(sftp->sft_flags & SFT_FDEVICE)) /* check for a device */ { lpFcb->fcb_drive = FcbDrive; lpFcb->fcb_recsiz = 128; } lpFcb->fcb_fsize = sftp->sft_size; lpFcb->fcb_date = sftp->sft_date; lpFcb->fcb_time = sftp->sft_time; return FCB_SUCCESS;}STATIC fcb FAR *ExtFcbToFcb(xfcb FAR * lpExtFcb){ if (*((UBYTE FAR *) lpExtFcb) == 0xff) sda_lpFcb = &lpExtFcb->xfcb_fcb; else sda_lpFcb = (fcb FAR *) lpExtFcb; return sda_lpFcb;}STATIC fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer, COUNT * pCurDrive){ fcb FAR *lpFcb; /* convert to fcb if needed first */ sda_lpFcb = lpFcb = ExtFcbToFcb(lpExtFcb); /* Build a traditional DOS file name */ FcbNameInit(lpFcb, pszBuffer, pCurDrive); /* and return the fcb pointer */ return lpFcb;}STATIC void FcbNameInit(fcb FAR * lpFcb, BYTE * szBuffer, COUNT * pCurDrive){ BYTE *pszBuffer = szBuffer; /* Build a traditional DOS file name */ *pCurDrive = default_drive + 1; if (lpFcb->fcb_drive != 0) { *pCurDrive = lpFcb->fcb_drive; pszBuffer[0] = 'A' + lpFcb->fcb_drive - 1; pszBuffer[1] = ':'; pszBuffer += 2; } ConvertName83ToNameSZ(pszBuffer, lpFcb->fcb_fname);}UBYTE FcbDelete(xfcb FAR * lpXfcb){ COUNT FcbDrive; UBYTE result = FCB_SUCCESS; void FAR *lpOldDta = dta; /* Build a traditional DOS file name */ CommonFcbInit(lpXfcb, SecPathName, &FcbDrive); /* check for a device */ if (IsDevice(SecPathName)) { result = FCB_ERROR; } else { int attr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL); dmatch Dmatch; dta = &Dmatch; if ((CritErrCode = -DosFindFirst(attr, SecPathName)) != SUCCESS) { result = FCB_ERROR; } else do { SecPathName[0] = 'A' + FcbDrive - 1; SecPathName[1] = ':'; strcpy(&SecPathName[2], Dmatch.dm_name); if (DosDelete(SecPathName, attr) != SUCCESS) { result = FCB_ERROR; break; } } while ((CritErrCode = -DosFindNext()) == SUCCESS); } dta = lpOldDta; return result;}UBYTE FcbRename(xfcb FAR * lpXfcb){ rfcb FAR *lpRenameFcb; COUNT FcbDrive; UBYTE result = FCB_SUCCESS; void FAR *lpOldDta = dta; /* Build a traditional DOS file name */ lpRenameFcb = (rfcb FAR *) CommonFcbInit(lpXfcb, SecPathName, &FcbDrive); /* check for a device */ if (IsDevice(SecPathName)) { result = FCB_ERROR; } else { dmatch Dmatch; COUNT result; wAttr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL); dta = &Dmatch; if ((CritErrCode = -DosFindFirst(wAttr, SecPathName)) != SUCCESS) { result = FCB_ERROR; } else do { /* 'A:' + '.' + '\0' */ BYTE loc_szBuffer[2 + FNAME_SIZE + 1 + FEXT_SIZE + 1]; fcb LocalFcb; BYTE *pToName; const BYTE FAR *pFromPattern = Dmatch.dm_name; int i; UBYTE mode = 0; FcbParseFname(&mode, pFromPattern, &LocalFcb); /* Overlay the pattern, skipping '?' */ /* I'm cheating because this assumes that the */ /* struct alignments are on byte boundaries */ pToName = LocalFcb.fcb_fname; pFromPattern = lpRenameFcb->renNewName; for (i = 0; i < FNAME_SIZE + FEXT_SIZE; i++) { if (*pFromPattern != '?') *pToName = *pFromPattern; pToName++; pFromPattern++; } SecPathName[0] = 'A' + FcbDrive - 1; SecPathName[1] = ':'; strcpy(&SecPathName[2], Dmatch.dm_name); result = truename(SecPathName, PriPathName, 0); if (result < SUCCESS || (result & IS_DEVICE)) { result = FCB_ERROR; break; } /* now to build a dos name again */ LocalFcb.fcb_drive = FcbDrive; FcbNameInit(&LocalFcb, loc_szBuffer, &FcbDrive); result = truename(loc_szBuffer, SecPathName, 0); if (result < SUCCESS || (result & (IS_NETWORK|IS_DEVICE)) == IS_DEVICE || DosRenameTrue(PriPathName, SecPathName, wAttr) != SUCCESS) { result = FCB_ERROR; break; } } while ((CritErrCode = -DosFindNext()) == SUCCESS); } dta = lpOldDta; return result;}/* TE:the MoveDirInfo() is now done by simply copying the dirEntry into the FCB this prevents problems with ".", ".." and saves code BO:use global SearchDir, as produced by FindFirst/Next*/UBYTE FcbClose(xfcb FAR * lpXfcb){ sft FAR *s; /* Convert to fcb if necessary */ fcb FAR *lpFcb = ExtFcbToFcb(lpXfcb); /* An already closed FCB can be closed again without error */ if (lpFcb->fcb_sftno == (BYTE) 0xff) return FCB_SUCCESS; /* Get the SFT block that contains the SFT */ if ((s = idx_to_sft(lpFcb->fcb_sftno)) == (sft FAR *) - 1) return FCB_ERROR; /* change time and set file size */ s->sft_size = lpFcb->fcb_fsize; if (!(s->sft_flags & SFT_FSHARED)) dos_setfsize(s->sft_status, lpFcb->fcb_fsize); DosSetFtimeSft(lpFcb->fcb_sftno, lpFcb->fcb_date, lpFcb->fcb_time); if ((CritErrCode = -DosCloseSft(lpFcb->fcb_sftno, FALSE)) == SUCCESS) { lpFcb->fcb_sftno = (BYTE) 0xff; return FCB_SUCCESS; } return FCB_ERROR;}/* close all files the current process opened by FCBs */VOID FcbCloseAll(){ COUNT idx = 0; sft FAR *sftp; for (idx = 0; (sftp = idx_to_sft(idx)) != (sft FAR *) - 1; idx++) if ((sftp->sft_mode & O_FCB) && sftp->sft_psp == cu_psp) DosCloseSft(idx, FALSE);}UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First){ void FAR *orig_dta = dta; BYTE FAR *lpDir; COUNT FcbDrive; fcb FAR *lpFcb; /* First, move the dta to a local and change it around to match */ /* our functions. */ lpDir = dta; dta = &Dmatch; /* Next initialze local variables by moving them from the fcb */ lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive); /* Reconstrct the dirmatch structure from the fcb - doesn't hurt for first */ Dmatch.dm_drive = lpFcb->fcb_sftno; fmemcpy(Dmatch.dm_name_pat, lpFcb->fcb_fname, FNAME_SIZE + FEXT_SIZE); DosUpFMem((BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE); Dmatch.dm_attr_srch = wAttr; Dmatch.dm_entry = lpFcb->fcb_strtclst; Dmatch.dm_dircluster = lpFcb->fcb_dirclst; wAttr = D_ALL; if ((xfcb FAR *) lpFcb != lpXfcb) { wAttr = lpXfcb->xfcb_attrib; fmemcpy(lpDir, lpXfcb, 7); lpDir += 7; } CritErrCode = -(First ? DosFindFirst(wAttr, SecPathName) : DosFindNext()); if (CritErrCode != SUCCESS) { dta = orig_dta; return FCB_ERROR; } *lpDir++ = FcbDrive; fmemcpy(lpDir, &SearchDir, sizeof(struct dirent)); lpFcb->fcb_dirclst = (UWORD) Dmatch.dm_dircluster; lpFcb->fcb_strtclst = Dmatch.dm_entry; /* This is undocumented and seen using Pcwatch and Ramview. The First byte is the current directory count and the second seems to be the attribute byte. */ lpFcb->fcb_sftno = Dmatch.dm_drive; /* MSD seems to save this @ fcb_date. */#if 0 lpFcb->fcb_cublock = Dmatch.dm_entry; lpFcb->fcb_cublock *= 0x100; lpFcb->fcb_cublock += wAttr;#endif dta = orig_dta; return FCB_SUCCESS;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -