📄 fcbfns.c
字号:
}
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 = 0;
FcbParseFname(&i, 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 + -