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

📄 fatdir.c

📁 DOS操用系统源代码,C语言编写,对操作系统的认识有很大的帮助.
💻 C
📖 第 1 页 / 共 2 页
字号:
			fnp -> f_offset = fnp -> f_diroff;
			fnp -> f_back = LONG_LAST_CLUSTER;
			fnp -> f_cluster = fnp -> f_dirstart;

			/* Search through the FAT to find the block     */
			/* that this entry is in.                       */
			if(map_cluster(fnp, XFR_READ) != SUCCESS)
			{
				fnp -> f_flags.f_dfull = TRUE;
				release_f_node(fnp);
				return 0;
			}

			/* If the returned cluster is FREE, return zero */
			/* bytes read.                                  */
			if(fnp -> f_cluster == FREE)
			{
				release_f_node(fnp);
				return 0;
			}

			/* Compute the block within the cluster and the */
			/* offset within the block.                     */
			fnp -> f_sector =
			 (fnp -> f_offset / secsize)
			  & fnp -> f_dpb -> dpb_clsmask;
			fnp -> f_boff = fnp -> f_offset % secsize;


			/* Get the block we need from cache             */
			bp = getblock(
				(LONG)clus2phys(fnp -> f_cluster,
					fnp -> f_dpb -> dpb_clssize,
					fnp -> f_dpb -> dpb_data)
					 + fnp -> f_sector,
				fnp -> f_dpb -> dpb_unit);
			bp -> b_flag &= ~(BFR_DATA | BFR_FAT);
			bp -> b_flag |= BFR_DIR;
		}

		/* Now that we have a block, transfer the diectory      */
		/* entry into the block.                                */
		if(bp == NULL)
		{
			release_f_node(fnp);
			return 0;
		}
		putdirent((struct dirent FAR *)&fnp -> f_dir,
		 (VOID FAR *)&bp -> b_buffer[fnp -> f_diroff % fnp -> f_dpb -> dpb_secsize]);
		bp -> b_flag |= BFR_DIRTY;
	}
	return DIRENT_SIZE;
}
#endif


VOID 
dir_close (REG struct f_node FAR *fnp)
{
	REG COUNT disk = fnp -> f_dpb -> dpb_unit;

	/* Test for invalid f_nodes                                     */
	if(fnp == NULL)
		return;

#ifndef IPL
	/* Write out the entry                                          */
	dir_write(fnp);

#endif 
	/* Clear buffers after release                                  */
	flush_buffers(disk);
	setinvld(disk);

	/* and release this instance of the fnode                       */
	--(fnp -> f_dpb) -> dpb_count;
	release_f_node(fnp);
}


#ifndef IPL
COUNT 
dos_findfirst (UCOUNT attr, BYTE FAR *name)
{
	REG struct f_node FAR *fnp;
	REG dmatch FAR *dmp = (dmatch FAR *)dta;
	REG COUNT i;
	COUNT nDrive;
	BYTE *p;

	/* The findfirst/findnext calls are probably the worst of the   */
	/* DOS calls. They must work somewhat on the fly (i.e. - open   */
	/* but never close). Since we don't want to lose fnodes every   */
	/* time a directory is searched, we will initialize the DOS     */
	/* dirmatch structure and then for every find, we will open the */
	/* current directory, do a seek and read, then close the fnode. */
	   
	/* Start out by initializing the dirmatch structure.            */
	dmp -> dm_drive = default_drive;
	dmp -> dm_entry = 0;
	dmp -> dm_cluster = 0;

	dmp -> dm_attr_srch = attr;

	/* Parse out the drive, file name and file extension.		*/
	ParseDosName(name, &nDrive, &LocalPath[2],
		SearchDir.dir_name, SearchDir.dir_ext);

	if(nDrive >= 0)
	{
		dmp -> dm_drive = nDrive;
	}
	else
		nDrive = default_drive;

	/* Now build a directory.					*/
	if(!LocalPath[2])
		strcpy(&LocalPath[2], ".");

	/* Build the match pattern out of the passed string             */
	for(p = SearchDir.dir_name, i = 0; i < FNAME_SIZE; i++)
	{
		/* test for a valid file name terminator                */
		if(*p != '\0')
		{
			/* If not a wildcard ('*'), just transfer       */
			if(*p != '*')
				dmp -> dm_name_pat[i] = *p++;
			else
			{
				/* swallow the wildcard                 */
				++p;

				/* fill with character wildcard (?)     */
				for( ; i < FNAME_SIZE; i++)
					dmp -> dm_name_pat[i] = '?';
				/* and skip to seperator                */
				while(*p != '\0'
				 && *p != '.' && *p != '/' && *p != '\\')
					++p;

				break;
			}
		}
		else
			break;
	}
	for( ; i < FNAME_SIZE; i++)
		dmp -> dm_name_pat[i] = ' ';

	/* and the extension (don't forget to add trailing spaces)...   */
	i = 0;
	for(p = SearchDir.dir_ext; i < FEXT_SIZE; i++)
	{
		if(*p != '\0' && *p != '.' && *p != '/' && *p != '\\')
		{
			if(*p != '*')
				dmp -> dm_name_pat[i+FNAME_SIZE] = *p++;
			else
			{
				for( ; i < FEXT_SIZE; i++)
					dmp -> dm_name_pat[i+FNAME_SIZE] = '?';
				break;
			}
		}
		else
			break;
	}
	for( ; i < FEXT_SIZE; i++)
		dmp -> dm_name_pat[i+FNAME_SIZE] = ' ';

	/* Now search through the directory to find the entry...        */
	upMem((BYTE FAR *)dmp -> dm_name_pat, FNAME_SIZE+FEXT_SIZE);

	/* Special handling - the volume id is only in the root         */
	/* directory and only searched for once.  So we need to open    */
	/* the root and return only the first entry that contains the   */
	/* volume id bit set.                                           */
	if(attr & D_VOLID)
	{
		/* Now open this directory so that we can read the      */
		/* fnode entry and do a match on it.                    */
		if((fnp = dir_open((BYTE FAR *)"\\")) == NULL)
			return DE_PATHNOTFND;

		/* Now do the search                                    */
		while(dir_read(fnp) == DIRENT_SIZE)
		{
			/* Test the attribute and return first found    */
			if(fnp -> f_dir.dir_attrib & D_VOLID)
			{
				pop_dmp(dmp, fnp);
				dir_close(fnp);
				return SUCCESS;
			}
		}

		/* Now that we've done our failed search, close it and  */
		/* return an error.                                     */
		dir_close(fnp);
		return DE_FILENOTFND;
	}

	/* Otherwise just do a normal find next                         */
	else
	{
		/* Complete building the directory from the passed in	*/
		/* name							*/
		if(nDrive >= 0)
		{
			LocalPath[0] = 'A' + nDrive;
		}
		else
		{
			LocalPath[0] = 'A' + default_drive;
		}
		LocalPath[1] = ':';

		/* Now open this directory so that we can read the      */
		/* fnode entry and do a match on it.                    */
		if((fnp = dir_open((BYTE FAR *)LocalPath)) == NULL)
			return DE_PATHNOTFND;

		pop_dmp(dmp, fnp);
		dmp -> dm_entry = 0;
		if(!fnp -> f_flags.f_droot)
		{        
			dmp -> dm_cluster = fnp -> f_dirstart;
			dmp -> dm_dirstart = fnp -> f_dirstart;
		}
		else
		{
			dmp -> dm_cluster = 0;
			dmp -> dm_dirstart = 0;
		}
		dir_close(fnp);
		return dos_findnext();
	}
}


COUNT 
dos_findnext (void)
{
	REG dmatch FAR *dmp = (dmatch FAR *)dta;
	REG struct f_node FAR *fnp;
	BOOL found = FALSE;
	BYTE FAR *p, *q;

	/* assign our match parameters pointer.                         */
	dmp = (dmatch FAR *)dta;

	/* Allocate an fnode if possible - error return (0) if not.     */
	if((fnp = get_f_node()) == (struct f_node FAR *)0)
	{
		return DE_FILENOTFND;
	}

	/* Force the fnode into read-write mode                         */
	fnp -> f_mode = RDWR;

	/* Select the default to help non-drive specified path          */
	/* searches...                                                  */
	fnp -> f_dpb = &blk_devices[dmp -> dm_drive];
	++(fnp -> f_dpb) -> dpb_count;
	if(media_check(fnp -> f_dpb) < 0)
	{
		--(fnp -> f_dpb) -> dpb_count;
		release_f_node(fnp);
		return DE_FILENOTFND;
	}

	
	fnp -> f_dsize = DIRENT_SIZE * (fnp -> f_dpb) -> dpb_dirents;

	/* Search through the directory to find the entry, but do a     */
	/* seek first.                                                  */
	if(dmp -> dm_entry > 0)
		fnp -> f_diroff = (dmp -> dm_entry - 1) * DIRENT_SIZE;

	fnp -> f_offset = fnp -> f_highwater = fnp -> f_diroff;
	fnp -> f_cluster = dmp -> dm_cluster;
	fnp -> f_flags.f_dmod = dmp -> dm_flags.f_dmod;
	fnp -> f_flags.f_droot = dmp -> dm_flags.f_droot;
	fnp -> f_flags.f_dnew = dmp -> dm_flags.f_dnew;
	fnp -> f_flags.f_ddir = dmp -> dm_flags.f_ddir;
	fnp -> f_flags.f_dfull = dmp -> dm_flags.f_dfull;

	fnp -> f_dirstart = dmp -> dm_dirstart;
	
	/* Loop through the directory                                   */
	while(dir_read(fnp) == DIRENT_SIZE)
	{
		++dmp -> dm_entry;
		if(fnp -> f_dir.dir_name[0] != '\0' && fnp -> f_dir.dir_name[0] != DELETED)
		{
			if(fcmp_wild((BYTE FAR *)(dmp -> dm_name_pat), (BYTE FAR *)fnp -> f_dir.dir_name, FNAME_SIZE+FEXT_SIZE))
			{
				/* Test the attribute as the final step */
				if(fnp -> f_dir.dir_attrib & D_VOLID)
					continue;
				else if(
				 ((~(dmp -> dm_attr_srch | D_ARCHIVE | D_RDONLY) 
				  & fnp -> f_dir.dir_attrib)
				 & (D_DIR | D_SYSTEM | D_HIDDEN)) == 0)
				{
					found = TRUE;
					break;
				}
				else
					continue;
			}
		}
	}

	/* If found, transfer it to the dmatch structure                */
	if(found)
		pop_dmp(dmp, fnp);

	/* return the result                                            */
	--(fnp -> f_dpb) -> dpb_count;
	release_f_node(fnp);

	return found ? SUCCESS : DE_FILENOTFND;
}

static VOID pop_dmp(dmp, fnp)
dmatch FAR *dmp;
struct f_node FAR *fnp;
{
	COUNT idx;
	BYTE FAR *p;
	BYTE FAR *q;

	dmp -> dm_attr_fnd = fnp -> f_dir.dir_attrib;
	dmp -> dm_time = fnp -> f_dir.dir_time;
	dmp -> dm_date = fnp -> f_dir.dir_date;
	dmp -> dm_size = fnp -> f_dir.dir_size;
	/* dmp -> dm_cluster = fnp -> f_cluster; */
	dmp -> dm_flags.f_droot = fnp -> f_flags.f_droot;
	dmp -> dm_flags.f_ddir = fnp -> f_flags.f_ddir;
	dmp -> dm_flags.f_dmod = fnp -> f_flags.f_dmod;
	dmp -> dm_flags.f_dnew = fnp -> f_flags.f_dnew;
	p = dmp -> dm_name;
	if(fnp -> f_dir.dir_name[0] == '.')
	{
		for(idx = 0, q = (BYTE FAR *)fnp -> f_dir.dir_name;
		 idx < FNAME_SIZE; idx++)
		{
			if(*q == ' ')
				break;
			*p++ = *q++;
		}
	}
	else
	{
		for(idx = 0, q = (BYTE FAR *)fnp -> f_dir.dir_name;
		 idx < FNAME_SIZE; idx++)
		{
			if(*q == ' ')
				break;
			*p++ = *q++;
		}
		if(fnp -> f_dir.dir_ext[0] != ' ')
		{
			*p++ = '.';
			for(idx = 0, q = (BYTE FAR *)fnp -> f_dir.dir_ext; idx < FEXT_SIZE; idx++)
			{
				if(*q == ' ')
					break;
				*p++ = *q++;
			}
		}
	}
	*p++ = NULL;
}
#endif

⌨️ 快捷键说明

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