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

📄 fcbfns.c

📁 DOS操作系统的C语言源代码 强烈推荐!!! 可以用来学习基于字符界面的操作系统的设计
💻 C
📖 第 1 页 / 共 3 页
字号:
		{
			if(*lpszFcbFext != ' ')
				pszBuffer[nDrvIdx + nFnameIdx + nFextIdx] =
				 *lpszFcbFext++;
			else
				break;
		}
	}
	else
		nFextIdx = 0;
	pszBuffer[nDrvIdx + nFnameIdx + nFextIdx] = '\0';
}

/* Ascii only file name match routines                  */
static BOOL 
FcbCharMatch (COUNT s, COUNT d, COUNT mode)
{
	if(s >= 'a' && s <= 'z')
		s -= 'a' - 'A';
	if(d >= 'a' && d <= 'z')
		d -= 'a' - 'A';
	if(mode && s == '?' && (d >= 'A' && s <= 'Z'))
		return TRUE;
	return s == d;
}


static BOOL 
FcbFnameMatch (BYTE FAR *s, BYTE FAR *d, COUNT n, COUNT mode)
{
	while(n--)
	{
		if(!FcbCharMatch(*s++, *d++, mode))
			return FALSE;
	}
	return TRUE;
}


BOOL FcbOpen(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_open(PriPathName, O_RDWR);
	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 = dos_getfsize(sftp -> sft_status);
		dos_getftime(sftp -> sft_status,
		 (date FAR *)&lpFcb -> fcb_date,
		 (time FAR *)&lpFcb -> fcb_time);
		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;
}


BOOL FcbDelete(lpXfcb)
xfcb FAR *lpXfcb;
{
	COUNT FcbDrive;

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

	/* check for a device                                           */
	/* if we have an extension, can't be a device                   */
	if(IsDevice(PriPathName))
	{
		return FALSE;
	}
	else
	{
		BYTE FAR *lpOldDta = dta;
		dmatch Dmatch;

		dta = (BYTE FAR *)&Dmatch;
		if(dos_findfirst(D_ALL, PriPathName[1] == ':' ? &PriPathName[2] : PriPathName) != SUCCESS)
		{
			dta = lpOldDta;
			return FALSE;
		}
		do
		{
			if(dos_delete(Dmatch.dm_name) != SUCCESS)
			{
				dta = lpOldDta;
				return FALSE;
			}
		}
		while(dos_findnext() == SUCCESS);
		dta = lpOldDta;
		return TRUE;
	}
}


BOOL FcbRename(lpXfcb)
xfcb FAR *lpXfcb;
{
	rfcb FAR *lpRenameFcb;
	COUNT FcbDrive;

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

	/* check for a device                                           */
	/* if we have an extension, can't be a device                   */
	if(IsDevice(PriPathName))
	{
		return FALSE;
	}
	else
	{
		BYTE FAR *lpOldDta = dta;
		dmatch Dmatch;

		dta = (BYTE FAR *)&Dmatch;
		if(dos_findfirst(D_ALL, PriPathName[1] == ':' ? &PriPathName[2] : PriPathName) != SUCCESS)
		{
			dta = lpOldDta;
			return FALSE;
		}


		do
		{
			fcb LocalFcb;
			BYTE *pToName, *pszFrom;
			BYTE FAR *pFromPattern;
			COUNT nIndex;

			/* First, expand the find match into fcb style  */
			/* file name entry                              */
			/* Fill with blanks first                       */
			for(pToName = LocalFcb.fcb_fname, nIndex = 0;
			 nIndex < FNAME_SIZE; nIndex++)
			{
				*pToName++ = ' ';
			}
			for(pToName = LocalFcb.fcb_fext, nIndex = 0;
			 nIndex < FEXT_SIZE; nIndex++)
			{
				*pToName++ = ' ';
			}

			/* next move in the file name while overwriting */
			/* the filler blanks                            */
			pszFrom = Dmatch.dm_name;
			pToName = LocalFcb.fcb_fname;
			for(nIndex = 0; nIndex < FNAME_SIZE; nIndex++)
			{
				if(*pszFrom != 0 && *pszFrom != '.')
					*pToName++ = *pszFrom++;
				else if(*pszFrom == '.')
				{
					++pszFrom;
					break;
				}
				else
					break;
			}

			if(*pszFrom != '\0')
			{
				pToName = LocalFcb.fcb_fext;
				for(nIndex = 0; nIndex < FEXT_SIZE; nIndex++)
				{
					if(*pszFrom != '\0')
						*pToName++ = *pszFrom++;
					else
						break;
				}
			}

			/* Overlay the pattern, skipping '?'            */
			/* I'm cheating because this assumes that the   */
			/* struct alignments are on byte boundaries     */
			pToName = LocalFcb.fcb_fname;
			for(pFromPattern = lpRenameFcb -> renNewName,
			 nIndex = 0; nIndex < FNAME_SIZE + FEXT_SIZE; nIndex++)
			{
				if(*pFromPattern != '?')
					*pToName++ = *pFromPattern++;
				else
					++pFromPattern;
			}

			/* now to build a dos name again                */
			LocalFcb.fcb_drive = 0;
			FcbNameInit((fcb FAR *)&LocalFcb, PriPathName, &FcbDrive);

			if(dos_rename(Dmatch.dm_name,
			 PriPathName[1] == ':' ? &PriPathName[2] : PriPathName) != SUCCESS)
			{
				dta = lpOldDta;
				return FALSE;
			}
		}
		while(dos_findnext() == SUCCESS);
		dta = lpOldDta;
		return TRUE;
	}
}


void MoveDirInfo(lpDmatch, lpDir)
dmatch FAR *lpDmatch;
struct dirent FAR *lpDir;
{
	BYTE FAR *lpToName, FAR *lpszFrom;
	COUNT nIndex;

	/* First, expand the find match into dir style  */
	/* file name entry                              */
	/* Fill with blanks first                       */
	for(lpToName = lpDir -> dir_name, nIndex = 0;
	 nIndex < FNAME_SIZE; nIndex++)
	{
		*lpToName++ = ' ';
	}
	for(lpToName = lpDir -> dir_ext, nIndex = 0;
	 nIndex < FEXT_SIZE; nIndex++)
	{
		*lpToName++ = ' ';
	}

	/* next move in the file name while overwriting */
	/* the filler blanks                            */
	lpszFrom = lpDmatch -> dm_name;
	lpToName = lpDir -> dir_name;
	for(nIndex = 0; nIndex < FNAME_SIZE; nIndex++)
	{
		if(*lpszFrom != 0 && *lpszFrom != '.')
			*lpToName++ = *lpszFrom++;
		else
			break;
	}
	    
	if(*lpszFrom != '\0')
	{
		if(*lpszFrom == '.')
			++lpszFrom;
		lpToName = lpDir -> dir_ext;
		for(nIndex = 0; nIndex < FEXT_SIZE; nIndex++)
		{
			if(*lpszFrom != '\0')
				*lpToName++ = *lpszFrom++;
			else
				break;
		}
	}
	for(nIndex = 0; nIndex < 10; nIndex++)
		lpDir -> dir_reserved[nIndex] = 0;
	lpDir -> dir_attrib = lpDmatch ->dm_attr_fnd;
	lpDir -> dir_time = lpDmatch ->dm_time;
	lpDir -> dir_date = lpDmatch ->dm_date;
	lpDir -> dir_start = lpDmatch ->dm_cluster;
	lpDir -> dir_size = lpDmatch ->dm_size;
}


BOOL FcbClose(lpXfcb)
xfcb FAR *lpXfcb;
{
	sft FAR *s;

	/* 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 just drop the count if a device, else    */
	/* call file system handler                     */
	if(s -> sft_flags & SFT_FDEVICE)
	{
		s -> sft_count -= 1;
		return TRUE;
	}
	else
	{
		s -> sft_count -= 1;
		if(s -> sft_count > 0)
			return SUCCESS;
		else
		{
			/* change time and set file size                */
			dos_setftime(s -> sft_status,
			 (date FAR *)&lpFcb -> fcb_date,
			 (time FAR *)&lpFcb -> fcb_time);
			dos_setfsize(s -> sft_status,
			 lpFcb -> fcb_fsize);
			return dos_close(s -> sft_status) == SUCCESS;
		}
	}
}


BOOL FcbFindFirst(lpXfcb)
xfcb FAR *lpXfcb;
{
	BYTE FAR *lpOldDta;
	BYTE FAR *lpDir;
	COUNT nIdx, FcbDrive;
	psp FAR *lpPsp = MK_FP(cu_psp,0);

	/* First, move the dta to a local and change it around to match */
	/* our functions.                                               */
	lpDir = (BYTE FAR *)dta;
	dta = (BYTE FAR *)&Dmatch;
	
	/* Next initialze local variables by moving them from the fcb   */
	lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
	if(lpXfcb -> xfcb_flag == 0xff)
	{
		wAttr = lpXfcb -> xfcb_attrib;
		fbcopy(lpXfcb, lpDir, 7);
		lpDir += 7;
	}
	else
		wAttr = D_ALL;

	*lpDir++ = PriPathName[0] - 'A';
	if(dos_findfirst(wAttr, PriPathName) != SUCCESS)       
	{
		dta = lpPsp -> ps_dta;
		return FALSE;
	}

	MoveDirInfo((dmatch FAR *)&Dmatch, (struct dirent FAR *)lpDir);
	lpFcb -> fcb_dirclst = Dmatch.dm_cluster;
	lpFcb -> fcb_diroff = Dmatch.dm_entry;
	dta = lpPsp -> ps_dta;
	return TRUE;
}


BOOL FcbFindNext(lpXfcb)
xfcb FAR *lpXfcb;
{
	BYTE FAR *lpOldDta;
	BYTE FAR *lpDir;
	COUNT nIdx, FcbDrive;
	psp FAR *lpPsp = MK_FP(cu_psp,0);

	/* First, move the dta to a local and change it around to match */
	/* our functions.                                               */
	lpDir = (BYTE FAR *)dta;
	dta = (BYTE FAR *)&Dmatch;

	/* Next initialze local variables by moving them from the fcb   */
	lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
	if((xfcb FAR *)lpFcb != lpXfcb)
	{
		wAttr = lpXfcb -> xfcb_attrib;
		fbcopy(lpXfcb, lpDir, 7);
		lpDir += 7;
	}
	else
		wAttr = D_ALL;

	/* Reconstrct the dirmatch structure from the fcb               */
	*lpDir++ = FcbDrive;
	Dmatch.dm_drive = FcbDrive? FcbDrive - 1 : default_drive;

	fbcopy(lpFcb -> fcb_fname, (BYTE FAR *)Dmatch.dm_name_pat, FNAME_SIZE+FEXT_SIZE);
	upMem((BYTE FAR *)Dmatch.dm_name_pat, FNAME_SIZE+FEXT_SIZE);
	Dmatch.dm_attr_srch = wAttr;
	Dmatch.dm_entry = lpFcb -> fcb_diroff;
	Dmatch.dm_cluster = lpFcb -> fcb_dirclst;

	if(dos_findnext() != SUCCESS)
	{
		dta = lpPsp -> ps_dta;
		return FALSE;
	}

	MoveDirInfo((dmatch FAR *)&Dmatch, (struct dirent FAR *)lpDir);
	lpFcb -> fcb_dirclst = Dmatch.dm_cluster;
	lpFcb -> fcb_diroff = Dmatch.dm_entry;
	dta = lpPsp -> ps_dta;
	return TRUE;
}
#endif

⌨️ 快捷键说明

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