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

📄 fcbfns.c

📁 DOS操作系统的C语言源代码 强烈推荐!!! 可以用来学习基于字符界面的操作系统的设计
💻 C
📖 第 1 页 / 共 3 页
字号:

/****************************************************************/
/*                                                              */
/*                          fcbfns.c                            */
/*                                                              */
/*           Old CP/M Style Function Handlers for Kernel        */
/*                                                              */
/*                      Copyright (c) 1995                      */
/*                      Pasquale J. Villani                     */
/*                      All Rights Reserved                     */
/*                                                              */
/* This file is part of DOS-C.                                  */
/*                                                              */
/* DOS-C is free software; you can redistribute it and/or       */
/* modify it under the terms of the GNU General Public License  */
/* as published by the Free Software Foundation; either version */
/* 2, or (at your option) any later version.                    */
/*                                                              */
/* DOS-C is distributed in the hope that it will be useful, but */
/* WITHOUT ANY WARRANTY; without even the implied warranty of   */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See    */
/* the GNU General Public License for more details.             */
/*                                                              */
/* You should have received a copy of the GNU General Public    */
/* License along with DOS-C; see the file COPYING.  If not,     */
/* write to the Free Software Foundation, 675 Mass Ave,         */
/* Cambridge, MA 02139, USA.                                    */
/****************************************************************/

#include "../../hdr/portab.h"
#include "globals.h"

/* $Logfile:   C:/dos-c/src/fs/fcbfns.c_v  $ */
#ifdef VERSION_STRINGS
static BYTE *RcsId = "$Header:   C:/dos-c/src/fs/fcbfns.c_v   1.6   04 Jan 1998 23:14:38   patv  $";
#endif

/* $Log:   C:/dos-c/src/fs/fcbfns.c_v  $
 * 
 *    Rev 1.6   04 Jan 1998 23:14:38   patv
 * Changed Log for strip utility
 * 
 *    Rev 1.5   03 Jan 1998  8:36:02   patv
 * Converted data area to SDA format
 * 
 *    Rev 1.4   16 Jan 1997 12:46:38   patv
 * pre-Release 0.92 feature additions
 * 
 *    Rev 1.3   29 May 1996 21:15:14   patv
 * bug fixes for v0.91a
 * 
 *    Rev 1.2   01 Sep 1995 17:48:44   patv
 * First GPL release.
 * 
 *    Rev 1.1   30 Jul 1995 20:50:26   patv
 * Eliminated version strings in ipl
 * 
 *    Rev 1.0   02 Jul 1995  8:06:06   patv
 * Initial revision.
 */
/* $EndLog$ */

#define FCB_SUCCESS     0
#define FCB_ERR_NODATA  1
#define FCB_ERR_EOF     3
#define FCB_ERR_WRITE   1
#define D_ALL   D_NORMAL | D_RDONLY | D_HIDDEN | D_SYSTEM | D_DIR | D_ARCHIVE

#ifdef PROTO
fcb FAR *ExtFcbToFcb(xfcb FAR *lpExtFcb);
fcb FAR *CommonFcbInit(xfcb FAR *lpExtFcb, BYTE *pszBuffer, COUNT *pCurDrive);
void FcbNameInit(fcb FAR *lpFcb, BYTE *pszBuffer, COUNT *pCurDrive);
sft FAR *FcbGetSft(COUNT SftIndex);
VOID FcbNextRecord(fcb FAR *lpFcb);
sft FAR *FcbGetFreeSft(WORD FAR *sft_idx);
BOOL FcbFnameMatch(BYTE FAR *s, BYTE FAR *d, COUNT n, COUNT mode);
BOOL FcbCharMatch(COUNT s, COUNT d, COUNT mode);
BOOL FcbCalcRec(xfcb FAR *lpXfcb);
VOID MoveDirInfo(dmatch FAR *lpDmatch, struct dirent FAR *lpDir);
#else
fcb FAR *ExtFcbToFcb();
fcb FAR *CommonFcbInit();
void FcbNameInit();
sft FAR *FcbGetSft();
VOID FcbNextRecord();
sft FAR *FcbGetFreeSft();
BOOL FcbFnameMatch();
BOOL FcbCharMatch();
BOOL FcbCalcRec();
VOID MoveDirInfo();
#endif
	
static dmatch Dmatch;

VOID DosOutputString(BYTE FAR *s)
{
	while(*s != '$')
		DosCharOutput(*s++);
}

static BYTE *con_name = "CON";

int DosCharInputEcho(VOID)
{
	BYTE cb;

	CharReqHdr.r_length = sizeof(request);
	CharReqHdr.r_command = C_INPUT;
	CharReqHdr.r_count = 1;
	CharReqHdr.r_trans = (VOID FAR *)&cb;
	CharReqHdr.r_status = 0;
	execrh((request FAR *)&CharReqHdr, syscon);
	if(CharReqHdr.r_status & S_ERROR)
		return char_error(&CharReqHdr, con_name);
	DosCharOutput(cb);
	return cb;
}


int DosCharInput(VOID)
{
	BYTE cb;

	CharReqHdr.r_length = sizeof(request);
	CharReqHdr.r_command = C_INPUT;
	CharReqHdr.r_count = 1;
	CharReqHdr.r_trans = (VOID FAR *)&cb;
	CharReqHdr.r_status = 0;
	execrh((request FAR *)&CharReqHdr, syscon);
	if(CharReqHdr.r_status & S_ERROR)
		return char_error(&CharReqHdr, con_name);
	return cb;
}


VOID DosDirectConsoleIO(iregs FAR *r)
{
	BYTE buf;

	if(r -> DL == 0xff)
	{
		r -> FLAGS &= ~FLG_ZERO;

		CharReqHdr.r_length = sizeof(request);
		CharReqHdr.r_command = C_ISTAT;
		CharReqHdr.r_status = 0;
		execrh((request FAR *)&CharReqHdr, syscon);
		if(CharReqHdr.r_status & S_ERROR)
		{
			char_error(&CharReqHdr, con_name);
			return;
		}

		if(CharReqHdr.r_status & S_BUSY)
		{
			CharReqHdr.r_length = sizeof(request);
			CharReqHdr.r_command = C_INPUT;
			CharReqHdr.r_count = 1;
			CharReqHdr.r_trans = (VOID FAR *)&buf;
			CharReqHdr.r_status = 0;
			execrh((request FAR *)&CharReqHdr, syscon);
			if(CharReqHdr.r_status & S_ERROR)
			{
				char_error(&CharReqHdr, con_name);
				return;
			}

			r -> AL = buf;
			r -> FLAGS |= FLG_ZERO;
		}

	}
	else
	{
		CharReqHdr.r_length = sizeof(request);
		CharReqHdr.r_command = C_OUTPUT;
		CharReqHdr.r_count = 1;
		CharReqHdr.r_trans = (VOID FAR *)(&buf);
		CharReqHdr.r_status = 0;
		execrh((request FAR *)&CharReqHdr, syscon);
		if(CharReqHdr.r_status & S_ERROR)
			char_error(&CharReqHdr, con_name);
	}
}

/* Console output with printer echo                                     */
VOID DosCharOutput(COUNT c)
{
	BYTE buf = c;

	/* Test for break first                                         */
	if(con_break())
		return;

	/* Now do an output directly to the console                     */
	CharReqHdr.r_length = sizeof(request);
	CharReqHdr.r_command = C_OUTPUT;
	CharReqHdr.r_count = 1;
	CharReqHdr.r_trans = (VOID FAR *)(&buf);
	CharReqHdr.r_status = 0;
	execrh((request FAR *)&CharReqHdr, syscon);
	if(CharReqHdr.r_status & S_ERROR)
		char_error(&CharReqHdr, con_name);
	++scr_pos;

	/* printer echo stuff                                   */
}


VOID DosDisplayOutput(COUNT c)
{
	/* Non-portable construct                                       */
	if(c < ' ' || c == 0x7f)
	{
		switch(c)
		{
		case '\r':
			scr_pos = 0;
			break;

		case 0x7f:
			++scr_pos;
			break;

		case '\b':
			if(scr_pos > 0)
				--scr_pos;
			break;

		case '\t':
			do
				DosCharOutput(' ');
			while(scr_pos & 7);
			return;

		default:
			break;
		}
		DosCharOutput(c);
	}
	else
	{
		DosCharOutput(c);
	}
}


VOID 
FatGetDrvData (COUNT drive, COUNT FAR *spc, COUNT FAR *bps, COUNT FAR *nc, BYTE FAR **mdp)
{
	struct dpb *dpbp;

	/* first check for valid drive                                  */
	if(drive < 0 || drive > NDEVS)
	{
		*spc = -1;
		return;
	}

	/* next - "log" in the drive                                    */
	drive = (drive == 0 ? default_drive : drive - 1);
	dpbp = &blk_devices[drive];
	++(dpbp -> dpb_count);
	dpbp -> dpb_flags = -1;
	if((media_check(dpbp) < 0) || (dpbp -> dpb_count <= 0))
	{
		*spc = -1;
		return;
	}

	/* get the data vailable from dpb                       */
	*nc = dpbp -> dpb_size;
	*spc = dpbp -> dpb_clsmask;
	*bps = dpbp -> dpb_secsize;

	/* Point to the media desctriptor fotr this drive               */
	*mdp = &(dpbp -> dpb_mdb);
	--(dpbp -> dpb_count);
}

#define PARSE_SEP_STOP          0x01
#define PARSE_DFLT_DRIVE        0x02
#define PARSE_BLNK_FNAME        0x04
#define PARSE_BLNK_FEXT         0x08

#define PARSE_RET_NOWILD        0
#define PARSE_RET_WILD          1
#define PARSE_RET_BADDRIVE      0xff

#ifndef IPL
WORD FcbParseFname(wTestMode, lpFileName, lpFcb)
REG WORD wTestMode;
BYTE FAR **lpFileName;
fcb FAR *lpFcb;
{
	COUNT   nIndex;
	WORD    wRetCode = PARSE_RET_NOWILD;

	/* pjv -- ExtFcbToFcb?                                          */
	/* Start out with some simple stuff first.  Check if we are     */
	/* going to use a default drive specificaton.                   */
	if(!(wTestMode & PARSE_DFLT_DRIVE))
		lpFcb -> fcb_drive = FDFLT_DRIVE;
	if(!(wTestMode & PARSE_BLNK_FNAME))
	{
		for(nIndex = 0; nIndex < FNAME_SIZE; ++nIndex)
			lpFcb -> fcb_fname[nIndex] = ' ';
	}
	if(!(wTestMode & PARSE_BLNK_FEXT))
	{
		for(nIndex = 0; nIndex < FEXT_SIZE; ++nIndex)
			lpFcb -> fcb_fext[nIndex] = ' ';
	}                              

	/* Undocumented behavior, set record number & record size to 0  */
	lpFcb -> fcb_cublock = lpFcb -> fcb_recsiz = 0;

	if(!(wTestMode & PARSE_SEP_STOP))
	{
		*lpFileName = ParseSkipWh(*lpFileName);
		if(TestCmnSeps(*lpFileName))
			++*lpFileName;
	}

	/* Undocumented "feature," we skip white space anyway           */
	*lpFileName = ParseSkipWh(*lpFileName);

	/* Now check for drive specification                            */
	if(*(*lpFileName + 1) == ':')
	{
		REG BYTE Drive = upChar(**lpFileName);

		/* non-portable construct to be changed                 */
		if(Drive < 'A' || Drive > 'Z')
			return PARSE_RET_BADDRIVE;
		Drive -= ('A' - 1);
		if(Drive > nblkdev)
			return PARSE_RET_BADDRIVE;
		else
			lpFcb -> fcb_drive = Drive;
		*lpFileName += 2;
	}

	/* Now to format the file name into the string                  */
	*lpFileName = GetNameField(*lpFileName, (BYTE FAR *)lpFcb -> fcb_fname, FNAME_SIZE, (BOOL *)&wRetCode);

	/* Do we have an extension? If do, format it else return        */
	if(**lpFileName == '.')
		*lpFileName = GetNameField(++*lpFileName, (BYTE FAR *)lpFcb -> fcb_fext, FEXT_SIZE, (BOOL *)&wRetCode);

	return wRetCode ? PARSE_RET_WILD : PARSE_RET_NOWILD;
}


BYTE FAR *
ParseSkipWh (BYTE FAR *lpFileName)
{
	while(*lpFileName == ' ' || *lpFileName == '\t')
		++lpFileName;
	return lpFileName;
}


BOOL 
TestCmnSeps (BYTE FAR *lpFileName)
{
	BYTE *pszTest, *pszCmnSeps = ":<|>+=,";

	for(pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)
		if(*lpFileName == *pszTest)
			return TRUE;
	return FALSE;
}

BOOL 
TestFieldSeps (BYTE FAR *lpFileName)
{
	BYTE *pszTest, *pszCmnSeps = "/\"[]<>|.";

	/* Another non-portable construct                               */
	if(*lpFileName <= ' ')
		return TRUE;

	for(pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)
		if(*lpFileName == *pszTest)
			return TRUE;
	return FALSE;
}

BYTE FAR *
GetNameField (BYTE FAR *lpFileName, BYTE FAR *lpDestField, COUNT nFieldSize, BOOL *pbWildCard)
{
	COUNT nIndex = 0;
	BYTE cFill = ' ';

	*pbWildCard = FALSE;
	while(*lpFileName != '\0' && !TestFieldSeps(lpFileName) && nIndex< nFieldSize)
	{
		if(*lpFileName == ' ')
			break;
		if(*lpFileName == '*')
		{
			*pbWildCard = TRUE;
			cFill = '?';
			++lpFileName;
			break;
		}
		if(*lpFileName == '?')
			*pbWildCard = TRUE;
		*lpDestField++ = upChar(*lpFileName++);
		++nIndex;
	}

	/* Blank out remainder of field on exit                         */
	for( ; nIndex < nFieldSize; ++nIndex)
		*lpDestField++ = cFill;
	return lpFileName;
}

static sft FAR *FcbGetSft(SftIndex)
COUNT SftIndex;
{
	/* Get the SFT block that contains the SFT      */
	for(lpCurSft = sfthead; lpCurSft != (sfttbl FAR *)-1;
	 lpCurSft = lpCurSft -> sftt_next)
	{
		if(SftIndex < lpCurSft -> sftt_count)
			break;
		else
			SftIndex -= lpCurSft -> sftt_count;
	}

	/* If not found, return an error                */
	if(lpCurSft == (sfttbl FAR *)-1)
		return (sft FAR *)-1;

	/* finally, point to the right entry            */
	return (sft FAR *)&(lpCurSft -> sftt_table[SftIndex]);
}


static VOID FcbNextRecord(lpFcb)

⌨️ 快捷键说明

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