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

📄 fcbfns.c

📁 DOS操作系统的C语言源代码 强烈推荐!!! 可以用来学习基于字符界面的操作系统的设计
💻 C
📖 第 1 页 / 共 3 页
字号:
fcb FAR *lpFcb;
{
	if(++lpFcb -> fcb_curec > 128)
	{
		lpFcb -> fcb_curec = 0;
		++lpFcb -> fcb_cublock;
	}
}


BOOL FcbRead(lpXfcb, nErrorCode)
xfcb FAR *lpXfcb;
COUNT *nErrorCode;
{
	sft FAR *s;
	LONG lPosit;
	COUNT nRead;
	psp FAR *p = MK_FP(cu_psp,0);

	/* Convert to fcb if necessary                                  */
	lpFcb = ExtFcbToFcb(lpXfcb);

	/* Get the SFT block that contains the SFT      */
	if((s = FcbGetSft(lpFcb -> fcb_sftno)) == (sft FAR *)-1)
		return FALSE;

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

	/* Now update the fcb and compute where we need to position     */
	/* to.                                                          */
	lPosit = ((lpFcb -> fcb_cublock * 128) + lpFcb -> fcb_curec)
	 * lpFcb -> fcb_recsiz;
	if(dos_lseek(s -> sft_status, lPosit, 0) < 0)
	{
		*nErrorCode = FCB_ERR_EOF;
		return FALSE;
	}

	/* Do the read                                                  */
	nRead = dos_read(s -> sft_status,
	 p -> ps_dta, lpFcb -> fcb_recsiz);

	/* Now find out how we will return and do it.                   */
	if(nRead == lpFcb -> fcb_recsiz)
	{
		*nErrorCode = FCB_SUCCESS;
		FcbNextRecord(lpFcb);
		return TRUE;
	}
	else if(nRead < 0)
	{
		*nErrorCode = FCB_ERR_EOF;
		return TRUE;
	}
	else if(nRead == 0)
	{
		*nErrorCode = FCB_ERR_NODATA;
		return FALSE;
	}
	else
	{
		COUNT nIdx, nCount;
		BYTE FAR *lpDta;

		nCount = lpFcb -> fcb_recsiz - nRead;
		lpDta = (BYTE FAR *)&(p -> ps_dta[nRead]);
		for(nIdx = 0; nIdx < nCount; nIdx++)
			*lpDta++ = 0;
		*nErrorCode = FCB_ERR_EOF;
		FcbNextRecord(lpFcb);
		return FALSE;
	}
}

BOOL FcbWrite(lpXfcb, nErrorCode)
xfcb FAR *lpXfcb;
COUNT *nErrorCode;
{
	sft FAR *s;
	LONG lPosit;
	COUNT nWritten;
	psp FAR *p = MK_FP(cu_psp,0);

	/* Convert to fcb if necessary                                  */
	lpFcb = ExtFcbToFcb(lpXfcb);

	/* Get the SFT block that contains the SFT      */
	if((s = FcbGetSft(lpFcb -> fcb_sftno)) == (sft FAR *)-1)
		return FALSE;

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

	/* Now update the fcb and compute where we need to position     */
	/* to.                                                          */
	lPosit = ((lpFcb -> fcb_cublock * 128) + lpFcb -> fcb_curec)
	 * lpFcb -> fcb_recsiz;
	if(dos_lseek(s -> sft_status, lPosit, 0) < 0)
	{
		*nErrorCode = FCB_ERR_EOF;
		return FALSE;
	}

	/* Do the read                                                  */
	nWritten = dos_write(s -> sft_status,
	 p -> ps_dta, lpFcb -> fcb_recsiz);

	/* Now find out how we will return and do it.                   */
	if(nWritten == lpFcb -> fcb_recsiz)
	{
		lpFcb -> fcb_fsize = dos_getcufsize(s -> sft_status);
		FcbNextRecord(lpFcb);
		*nErrorCode = FCB_SUCCESS;
		return TRUE;
	}
	else if(nWritten <= 0)
	{
		*nErrorCode = FCB_ERR_WRITE;
		return TRUE;
	}
	*nErrorCode = FCB_ERR_WRITE;
	return FALSE;
}


BOOL FcbGetFileSize(lpXfcb)
xfcb FAR *lpXfcb;
{
	COUNT FcbDrive, FileNum;

	/* Build a traditional DOS file name                            */
	lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);

	/* check for a device                                           */
	/* if we have an extension, can't be a device                   */
	if(IsDevice(PriPathName) || (lpFcb -> fcb_recsiz == 0))
	{
		return FALSE;
	}
	FileNum = dos_open(PriPathName, O_RDONLY);
	if(FileNum >= 0)
	{
		LONG fsize;

		/* Get the size                                         */
		fsize = dos_getfsize(FileNum);

		/* compute the size and update the fcb                  */
		lpFcb -> fcb_rndm = fsize / lpFcb -> fcb_recsiz;
		if((fsize % lpFcb -> fcb_recsiz) != 0)
			++lpFcb -> fcb_rndm;

		/* close the file and leave                             */
		return dos_close(FileNum) == SUCCESS;
	}
	else
		return FALSE;
}


BOOL FcbSetRandom(lpXfcb)
xfcb FAR *lpXfcb;
{
	LONG lPosit;

	/* Convert to fcb if necessary                                  */
	lpFcb = ExtFcbToFcb(lpXfcb);

	/* Now update the fcb and compute where we need to position     */
	/* to.                                                          */
	lpFcb -> fcb_rndm = (lpFcb -> fcb_cublock * 128)
	 + lpFcb -> fcb_curec;

	return TRUE;
}


BOOL FcbCalcRec(lpXfcb)
xfcb FAR *lpXfcb;
{
	LONG lPosit;

	/* Convert to fcb if necessary                                  */
	lpFcb = ExtFcbToFcb(lpXfcb);

	/* Now update the fcb and compute where we need to position     */
	/* to.                                                          */
	lpFcb -> fcb_cublock =  lpFcb -> fcb_rndm / 128;
	lpFcb -> fcb_curec =  lpFcb -> fcb_rndm % 128;

	return TRUE;
}


BOOL FcbRandomBlockRead(lpXfcb, nRecords, nErrorCode)
xfcb FAR *lpXfcb;
COUNT nRecords;
COUNT *nErrorCode;
{
	FcbCalcRec(lpXfcb);

	/* Convert to fcb if necessary                                  */
	lpFcb = ExtFcbToFcb(lpXfcb);

	do
		FcbRead(lpXfcb, nErrorCode);
	while ((--nRecords > 0) && (*nErrorCode == 0));

	/* Now update the fcb                                           */
	lpFcb -> fcb_rndm = lpFcb -> fcb_cublock * 128 + lpFcb -> fcb_curec;

	return TRUE;
}


BOOL FcbRandomBlockWrite(lpXfcb, nRecords, nErrorCode)
xfcb FAR *lpXfcb;
COUNT nRecords;
COUNT *nErrorCode;
{
	FcbCalcRec(lpXfcb);

	/* Convert to fcb if necessary                                  */
	lpFcb = ExtFcbToFcb(lpXfcb);

	do
		FcbWrite(lpXfcb, nErrorCode);
	while ((--nRecords > 0) && (*nErrorCode == 0));

	/* Now update the fcb                                           */
	lpFcb -> fcb_rndm = lpFcb -> fcb_cublock * 128 + lpFcb -> fcb_curec;

	return TRUE;
}


BOOL FcbRandomRead(lpXfcb, nErrorCode)
xfcb FAR *lpXfcb;
COUNT *nErrorCode;
{
	UWORD uwCurrentBlock;
	UBYTE ucCurrentRecord;

	FcbCalcRec(lpXfcb);

	/* Convert to fcb if necessary                                  */
	lpFcb = ExtFcbToFcb(lpXfcb);

	uwCurrentBlock = lpFcb -> fcb_cublock;
	ucCurrentRecord = lpFcb -> fcb_curec;

	FcbRead(lpXfcb, nErrorCode);

	lpFcb -> fcb_cublock = uwCurrentBlock;
	lpFcb -> fcb_curec = ucCurrentRecord;
	return TRUE;
}


BOOL FcbRandomWrite(lpXfcb, nErrorCode)
xfcb FAR *lpXfcb;
COUNT *nErrorCode;
{
	UWORD uwCurrentBlock;
	UBYTE ucCurrentRecord;

	FcbCalcRec(lpXfcb);

	/* Convert to fcb if necessary                                  */
	lpFcb = ExtFcbToFcb(lpXfcb);

	uwCurrentBlock = lpFcb -> fcb_cublock;
	ucCurrentRecord = lpFcb -> fcb_curec;

	FcbWrite(lpXfcb, nErrorCode);

	lpFcb -> fcb_cublock = uwCurrentBlock;
	lpFcb -> fcb_curec = ucCurrentRecord;
	return TRUE;
}


static sft FAR *FcbGetFreeSft(sft_idx)
WORD FAR *sft_idx;
{
	WORD sys_idx = 0;
	sfttbl FAR *sp;

	/* Get the SFT block that contains the SFT      */
	for(sp = sfthead; sp != (sfttbl FAR *)-1; sp = sp -> sftt_next)
	{
		REG WORD i;

		for(i = 0; i < sp -> sftt_count; i++)
		{
			if(sp -> sftt_table[i].sft_count == 0)
			{
				*sft_idx = sys_idx + i;
				return (sft FAR *)&sp -> sftt_table[sys_idx + i];
			}
		}
		sys_idx += i;
	}

	/* If not found, return an error                */
	return (sft FAR *)-1;
}


BOOL FcbCreate(lpXfcb)
xfcb FAR *lpXfcb;
{
	WORD sft_idx;
	sft FAR *sftp;
	struct dhdr FAR *dhp;
	COUNT FcbDrive;

	/* get a free system file table entry                           */
	if((sftp = FcbGetFreeSft((WORD FAR *)&sft_idx)) == (sft FAR *)-1)
		return DE_TOOMANY;

	/* Build a traditional DOS file name                            */
	lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);

	/* check for a device                                           */
	/* if we have an extension, can't be a device                   */
	if(IsDevice(PriPathName))
	{
		for(dhp = (struct dhdr FAR *)&nul_dev; dhp != (struct dhdr FAR *)-1; dhp = dhp -> dh_next)
		{
			if(FcbFnameMatch((BYTE FAR *)PriPathName, (BYTE FAR *)dhp -> dh_name, FNAME_SIZE, FALSE))
			{
				sftp -> sft_count += 1;
				sftp -> sft_mode = O_RDWR;
				sftp -> sft_attrib = 0;
				sftp -> sft_flags =
				  (dhp -> dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FEOF;
				sftp -> sft_psp = cu_psp;
				fbcopy(lpFcb -> fcb_fname, sftp -> sft_name, FNAME_SIZE+FEXT_SIZE);
				sftp -> sft_dev = dhp;
				lpFcb -> fcb_sftno = sft_idx;
				lpFcb -> fcb_curec = 0;
				lpFcb -> fcb_recsiz = 0;
				lpFcb -> fcb_fsize = 0;
				lpFcb -> fcb_date = dos_getdate();
				lpFcb -> fcb_time = dos_gettime();
				lpFcb -> fcb_rndm = 0;
				return TRUE;
			}
		}
	}
	sftp -> sft_status = dos_creat(PriPathName, 0);
	if(sftp -> sft_status >= 0)
	{
		lpFcb -> fcb_drive = FcbDrive;
		lpFcb -> fcb_sftno = sft_idx;
		lpFcb -> fcb_curec = 0;
		lpFcb -> fcb_recsiz = 128;
		lpFcb -> fcb_fsize = 0;
		lpFcb -> fcb_date = dos_getdate();
		lpFcb -> fcb_time = dos_gettime();
		lpFcb -> fcb_rndm = 0;
		sftp -> sft_count += 1;
		sftp -> sft_mode = O_RDWR;
		sftp -> sft_attrib = 0;
		sftp -> sft_flags = 0;
		sftp -> sft_psp = cu_psp;
		fbcopy((BYTE FAR *)&lpFcb -> fcb_fname, (BYTE FAR *)&sftp -> sft_name, FNAME_SIZE+FEXT_SIZE);
		return TRUE;
	}
	else
		return FALSE;
}


static fcb FAR *ExtFcbToFcb(xfcb FAR *lpExtFcb)
{
	if(*((UBYTE FAR *)lpExtFcb) == 0xff)
		return &lpExtFcb -> xfcb_fcb;
	else
		return (fcb FAR *)lpExtFcb;
}


static fcb FAR *CommonFcbInit(lpExtFcb, pszBuffer, pCurDrive)
xfcb FAR *lpExtFcb;
BYTE *pszBuffer;
COUNT *pCurDrive;
{
	BYTE FAR *lpszFcbFname, *lpszFcbFext;
	COUNT nDrvIdx, nFnameIdx, nFextIdx;
	fcb FAR *lpFcb;

	/* convert to fcb if needed first                               */
	lpFcb = ExtFcbToFcb(lpExtFcb);

	/* Build a traditional DOS file name                            */
	FcbNameInit(lpFcb, pszBuffer, pCurDrive);

	/* and return the fcb pointer                                   */
	return lpFcb;
}

void FcbNameInit(lpFcb, pszBuffer, pCurDrive)
fcb FAR *lpFcb;
BYTE *pszBuffer;
COUNT *pCurDrive;
{
	BYTE FAR *lpszFcbFname, FAR *lpszFcbFext;
	COUNT nDrvIdx, nFnameIdx, nFextIdx;

	/* Build a traditional DOS file name                            */
	lpszFcbFname = (BYTE FAR *)lpFcb -> fcb_fname;
	if(lpFcb -> fcb_drive != 0)
	{
		*pCurDrive = lpFcb -> fcb_drive;
		pszBuffer[0] = 'A' + lpFcb -> fcb_drive - 1;
		pszBuffer[1] = ':';
		nDrvIdx = 2;
	}           
	else
	{
		*pCurDrive = default_drive + 1;
		nDrvIdx = 0;
	}

	for(nFnameIdx = 0; nFnameIdx < FNAME_SIZE; nFnameIdx++)
	{
		if(*lpszFcbFname != ' ')
			pszBuffer[nDrvIdx + nFnameIdx] = *lpszFcbFname++;
		else
			break;
	}

	lpszFcbFext = (BYTE FAR *)lpFcb -> fcb_fext;
	if(*lpszFcbFext != ' ')
	{
		pszBuffer[nDrvIdx + nFnameIdx++] = '.';
		for(nFextIdx = 0; nFextIdx < FEXT_SIZE; nFextIdx++)

⌨️ 快捷键说明

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