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

📄 dosfns.c

📁 用C语言实现的DOS操作系统的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	for(--froot; length > 0 && !(*froot == '/' || *froot == '\\'); --froot)
		;
	return ++froot;
}


/* Ascii only file name match routines                  */
static BOOL 
cmatch (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 
fnmatch (BYTE FAR *s, BYTE FAR *d, COUNT n, COUNT mode)
{
	while(n--)
	{
		if(!cmatch(*s++, *d++, mode))
			return FALSE;
	}
	return TRUE;
}


#ifndef IPL
COUNT 
DosCreat (BYTE FAR *fname, COUNT attrib)
{
	psp FAR *p = MK_FP(cu_psp,0);
	WORD hndl, sft_idx;
	sft FAR *sftp;
	struct dhdr FAR *dhp;
	BYTE FAR *froot;
	WORD i;

	/* get a free handle                            */
	if((hndl = get_free_hndl()) == 0xff)
		return DE_TOOMANY;

	/* now get a free system file table entry       */
	if((sftp = get_free_sft((WORD FAR *)&sft_idx)) == (sft FAR *)-1)
		return DE_TOOMANY;
	
	/* check for a device                           */
	froot = get_root(fname);
	for(i = 0; i < FNAME_SIZE; i++)
	{
		if(*froot != '\0' && *froot != '.')
			PriPathName[i] = *froot++;
		else
			break;
	}

	for( ; i < FNAME_SIZE; i++)
		PriPathName[i] = ' ';

	/* if we have an extension, can't be a device   */
	if(*froot != '.');
	{
		for(dhp = (struct dhdr FAR *)&nul_dev; dhp != (struct dhdr FAR *)-1; dhp = dhp -> dh_next)
		{
			if(fnmatch((BYTE FAR *)PriPathName, (BYTE FAR *)dhp -> dh_name, FNAME_SIZE, FALSE))
			{
				sftp -> sft_count += 1;
				sftp -> sft_mode = SFT_MRDWR;
				sftp -> sft_attrib = attrib;
				sftp -> sft_flags = 
				  (dhp -> dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FEOF;
				sftp -> sft_psp = cu_psp;
				fbcopy((BYTE FAR *)PriPathName, sftp -> sft_name, FNAME_SIZE+FEXT_SIZE);
				sftp -> sft_dev = dhp;
				p -> ps_filetab[hndl] = sft_idx;
				return hndl;
			}
		}
	}
	sftp -> sft_status = dos_creat(fname, attrib);
	if(sftp -> sft_status >= 0)
	{
		p -> ps_filetab[hndl] = sft_idx;
		sftp -> sft_count += 1;
		sftp -> sft_mode = SFT_MRDWR;
		sftp -> sft_attrib = attrib;
		sftp -> sft_flags = 0;
		sftp -> sft_psp = cu_psp;
		fbcopy((BYTE FAR *)PriPathName, sftp -> sft_name, FNAME_SIZE+FEXT_SIZE);
		return hndl;
	}
	else
		return sftp -> sft_status;
}
#endif


COUNT 
CloneHandle (COUNT hndl)
{
	sft FAR *sftp;

	/* now get the system file table entry                          */
	if((sftp = get_sft(hndl)) == (sft FAR *)-1)
		return DE_INVLDHNDL;
	
	/* now that we have the system file table entry, get the fnode  */
	/* index, and increment the count, so that we've effectively    */
	/* cloned the file.                                             */
	sftp -> sft_count += 1;
	return hndl;
}


COUNT 
DosDup (COUNT Handle)
{
	psp FAR *p = MK_FP(cu_psp,0);
	COUNT NewHandle;
	sft FAR *Sftp;

	/* Get the SFT block that contains the SFT                      */
	if((Sftp = get_sft(Handle)) == (sft FAR *)-1)
		return DE_INVLDACC;

	/* If not open - exit                                           */
	if(Sftp -> sft_count <= 0)
		return DE_INVLDACC;

	/* now get a free handle                                        */
	if((NewHandle = get_free_hndl()) == 0xff)
		return DE_TOOMANY;

	/* If everything looks ok, bump it up.                          */
	if((Sftp -> sft_flags & SFT_FDEVICE) || (Sftp -> sft_status >= 0))
	{
		p -> ps_filetab[NewHandle] = p -> ps_filetab[Handle];
		Sftp -> sft_count += 1;
		return NewHandle;
	}
	else
		return DE_INVLDACC;
}




COUNT 
DosForceDup (COUNT OldHandle, COUNT NewHandle)
{
	psp FAR *p = MK_FP(cu_psp,0);
	sft FAR *Sftp;

	/* Get the SFT block that contains the SFT                      */
	if((Sftp = get_sft(OldHandle)) == (sft FAR *)-1)
		return DE_INVLDACC;

	/* If not open - exit                                           */
	if(Sftp -> sft_count <= 0)
		return DE_INVLDACC;

	/* now close the new handle if it's open                        */
	if(p -> ps_filetab[NewHandle] != 0xff)
	{
		COUNT ret;

		if((ret = DosClose(NewHandle)) != SUCCESS)
			return ret;
	}

	/* If everything looks ok, bump it up.                          */
	if((Sftp -> sft_flags & SFT_FDEVICE) || (Sftp -> sft_status >= 0))
	{
		p -> ps_filetab[NewHandle] = p -> ps_filetab[OldHandle];
		
		Sftp -> sft_count += 1;
		return SUCCESS;
	}
	else
		return DE_INVLDACC;
}


COUNT 
DosOpen (BYTE FAR *fname, COUNT mode)
{
	psp FAR *p = MK_FP(cu_psp,0);
	WORD hndl, sft_idx;
	sft FAR *sftp;
	struct dhdr FAR *dhp;
	BYTE FAR *froot;
	WORD i;

	/* test if mode is in range                     */
	if((mode & ~SFT_OMASK) != 0)
		return DE_INVLDACC;

	mode &= 3;

	if (cu_psp != DOS_PSP)
	{
	    /* get a free handle                            */
	    if((hndl = get_free_hndl()) == 0xff)
		return DE_TOOMANY;
	}

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

	/* check for a device                           */
	froot = get_root(fname);
	for(i = 0; i < FNAME_SIZE; i++)
	{
		if(*froot != '\0' && *froot != '.')
			PriPathName[i] = *froot++;
		else
			break;
	}

	for( ; i < FNAME_SIZE; i++)
		PriPathName[i] = ' ';

	/* if we have an extension, can't be a device   */
	if(*froot != '.');
	{
		for(dhp = (struct dhdr FAR *)&nul_dev; dhp != (struct dhdr FAR *)-1; dhp = dhp -> dh_next)
		{
			if(fnmatch((BYTE FAR *)PriPathName, (BYTE FAR *)dhp -> dh_name, FNAME_SIZE, FALSE))
			{
				sftp -> sft_count += 1;
				sftp -> sft_mode = mode;
				sftp -> sft_attrib = 0;
				sftp -> sft_flags = 
				  (dhp -> dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FEOF;
				sftp -> sft_psp = cu_psp;
				fbcopy((BYTE FAR *)PriPathName, sftp -> sft_name, FNAME_SIZE+FEXT_SIZE);
				sftp -> sft_dev = dhp;
				
				if (cu_psp != DOS_PSP)
				    p -> ps_filetab[hndl] = sft_idx;
				return hndl;
			}
		}
	}
	sftp -> sft_status = dos_open(fname, mode);
	if(sftp -> sft_status >= 0)
	{
		if (cu_psp != DOS_PSP)
		    p -> ps_filetab[hndl] = sft_idx;
		
		sftp -> sft_count += 1;
		sftp -> sft_mode = mode;
		sftp -> sft_attrib = 0;
		sftp -> sft_flags = 0;
		sftp -> sft_psp = cu_psp;
		fbcopy((BYTE FAR *)PriPathName, sftp -> sft_name, FNAME_SIZE+FEXT_SIZE);
		return hndl;
	}
	else
		return sftp -> sft_status;
}


COUNT 
DosClose (COUNT hndl)
{
	psp FAR *p = MK_FP(cu_psp,0);
	sft FAR *s;

	/* Test that the handle is valid                */
	if(hndl < 0)
		return DE_INVLDHNDL;

	/* Get the SFT block that contains the SFT      */
	if((s = get_sft(hndl)) == (sft FAR *)-1)
		return DE_INVLDHNDL;

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

	/* now just drop the count if a device, else    */
	/* call file system handler                     */
	if(s -> sft_flags & SFT_FDEVICE)
	{
		p -> ps_filetab[hndl] = 0xff;

		return SUCCESS;
	}
	else
	{
		p -> ps_filetab[hndl] = 0xff;
		s -> sft_count -= 1;
		if(s -> sft_count > 0)
			return SUCCESS;
		else
			return dos_close(s -> sft_status);
	}
}

VOID 
DosGetFree (COUNT drive, COUNT FAR *spc, COUNT FAR *navc, COUNT FAR *bps, COUNT FAR *nc)
{
	struct dpb *dpbp;

	/* first check for valid drive          */
	if(drive < 0 || drive > nblkdev)
	{
		*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_clssize;
	*bps = dpbp -> dpb_secsize;

	/* now tell fs to give us free cluster  */
	/* count                                */
	*navc = dos_free(dpbp);
	--(dpbp -> dpb_count);
}


COUNT 
DosGetCuDir (COUNT drive, BYTE FAR *s)
{
	REG struct dpb *dpbp;

	/* first check for valid drive          */
	if(drive < 0 || drive > nblkdev)
		return DE_INVLDDRV;

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

	/* now get fs to give current           */
	/* directory                            */
	dos_pwd(dpbp, s);
	--(dpbp -> dpb_count);
	return SUCCESS;
}


COUNT 
DosChangeDir (BYTE FAR *s)
{
	REG struct dpb *dpbp;
	REG COUNT drive;
	struct f_node FAR *fp;
	COUNT ret;

	/* test for path existance from fs      */
	if((fp = dir_open((BYTE FAR *)s)) == (struct f_node FAR *)0)
		return DE_PATHNOTFND;
	else
		dir_close(fp);

	/* Parse and extract drive              */
	if(*(s + 1) == ':')
	{
		drive = *s - '@';
		if (drive > 26) drive -= 'a' - 'A';
	}
	else
		drive = 0;

	/* first check for valid drive          */
	if(drive < 0 || drive > nblkdev)
		return DE_INVLDDRV;

	/* 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))
		return DE_INVLDDRV;
	
	/* now get fs to change to new          */
	/* directory                            */
	ret = dos_cd(dpbp, s);
	--(dpbp -> dpb_count);
	return ret;
}

COUNT 
DosFindFirst (UCOUNT attr, BYTE FAR *name)
{
	return dos_findfirst(attr, name);
}


COUNT 
DosFindNext (void)
{
	return dos_findnext();
}


#ifndef IPL
COUNT DosGetFtime(hndl, dp, tp)
COUNT hndl;
date FAR *dp;
time FAR *tp;
{
	sft FAR *s;
	sfttbl FAR *sp;

	/* Test that the handle is valid                */
	if(hndl < 0)
		return DE_INVLDHNDL;

	/* Get the SFT block that contains the SFT      */
	if((s = get_sft(hndl)) == (sft FAR *)-1)
		return DE_INVLDHNDL;

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

	/* call file system handler                     */
	return dos_getftime(s -> sft_status, dp, tp);
}

COUNT DosSetFtime(hndl, dp, tp)
COUNT hndl;
date FAR *dp;
time FAR *tp;
{
	sft FAR *s;
	sfttbl FAR *sp;

	/* Test that the handle is valid                */
	if(hndl < 0)
		return DE_INVLDHNDL;

	/* Get the SFT block that contains the SFT      */
	if((s = get_sft(hndl)) == (sft FAR *)-1)
		return DE_INVLDHNDL;

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

	/* call file system handler                     */
	return dos_setftime(s -> sft_status, dp, tp);
}
#endif

COUNT 
DosGetFattr (BYTE FAR *name, UWORD FAR *attrp)
{
	return dos_getfattr(name, attrp);
}


COUNT 
DosSetFattr (BYTE FAR *name, UWORD FAR *attrp)
{
	return dos_setfattr(name, attrp);
}


⌨️ 快捷键说明

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