📄 fatdir.c
字号:
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 + -