📄 fatdir.c
字号:
/* Search through the FAT to find the block */
/* that this entry is in. */
#ifdef DISPLAY_GETBLOCK
printf("dir_write: ");
#endif
if (map_cluster(fnp, XFR_READ) != SUCCESS)
{
release_f_node(fnp);
return FALSE;
}
bp = getblock_from_off(fnp, secsize);
bp->b_flag &= ~(BFR_DATA | BFR_FAT);
bp->b_flag |= BFR_DIR | BFR_VALID;
#ifdef DISPLAY_GETBLOCK
printf("DIR (dir_write)\n");
#endif
}
/* Now that we have a block, transfer the directory */
/* entry into the block. */
if (bp == NULL)
{
release_f_node(fnp);
return FALSE;
}
swap_deleted(fnp->f_dir.dir_name);
putdirent(&fnp->f_dir, &bp->b_buffer[(fnp->f_diroff * DIRENT_SIZE) %
fnp->f_dpb->dpb_secsize]);
swap_deleted(fnp->f_dir.dir_name);
bp->b_flag &= ~(BFR_DATA | BFR_FAT);
bp->b_flag |= BFR_DIR | BFR_DIRTY | BFR_VALID;
}
return TRUE;
}
#endif
VOID dir_close(REG f_node_ptr fnp)
{
/* Test for invalid f_nodes */
if (fnp == NULL || !(fnp->f_flags & F_DDIR))
return;
#ifndef IPL
/* Write out the entry */
dir_write(fnp);
#endif
/* Clear buffers after release */
/* hazard: no error checking! */
flush_buffers(fnp->f_dpb->dpb_unit);
/* and release this instance of the fnode */
release_f_node(fnp);
}
#ifndef IPL
COUNT dos_findfirst(UCOUNT attr, BYTE * name)
{
REG f_node_ptr fnp;
REG dmatch *dmp = &sda_tmp_dm;
REG COUNT i;
/* printf("ff %Fs\n", name);*/
/* 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. */
/* Parse out the file name */
i = ParseDosName(name, SearchDir.dir_name, TRUE);
if (i < SUCCESS)
return i;
/*
printf("\nff %s", Tname);
printf("ff %s", fcbname);
*/
/* Now search through the directory to find the entry... */
/* 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|D_DIR))==D_VOLID)
i = 3;
/* Now open this directory so that we can read the */
/* fnode entry and do a match on it. */
/* printf("dir_open %s\n", szDirName);*/
{
char tmp = name[i];
name[i] = '\0';
if ((fnp = dir_open(name)) == NULL)
return DE_PATHNOTFND;
name[i] = tmp;
}
/* Now initialize the dirmatch structure. */
dmp->dm_drive = name[0] - 'A';
dmp->dm_attr_srch = attr;
/* Copy the raw pattern from our data segment to the DTA. */
fmemcpy(dmp->dm_name_pat, SearchDir.dir_name, FNAME_SIZE + FEXT_SIZE);
if ((attr & (D_VOLID|D_DIR))==D_VOLID)
{
/* Now do the search */
while (dir_read(fnp) == 1)
{
/* Test the attribute and return first found */
if ((fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE)) == D_VOLID &&
fnp->f_dir.dir_name[0] != DELETED)
{
dmp->dm_dircluster = fnp->f_dirstart; /* TE */
memcpy(&SearchDir, &fnp->f_dir, sizeof(struct dirent));
#ifdef DEBUG
printf("dos_findfirst: %11s\n", fnp->f_dir.dir_name);
#endif
dir_close(fnp);
return SUCCESS;
}
fnp->f_diroff++;
}
/* Now that we've done our failed search, close it and */
/* return an error. */
dir_close(fnp);
return DE_NFILES;
}
/* Otherwise just do a normal find next */
else
{
dmp->dm_entry = 0;
dmp->dm_dircluster = fnp->f_dirstart;
dir_close(fnp);
return dos_findnext();
}
}
/*
BUGFIX TE 06/28/01
when using FcbFindXxx, the only information available is
the cluster number + entrycount. everything else MUST\
be recalculated.
a good test for this is MSDOS CHKDSK, which now (seems too) work
*/
COUNT dos_findnext(void)
{
REG f_node_ptr fnp;
REG dmatch *dmp = &sda_tmp_dm;
/* Allocate an fnode if possible - error return (0) if not. */
if ((fnp = get_f_node()) == (f_node_ptr) 0)
{
return DE_NFILES;
}
memset(fnp, 0, sizeof(*fnp));
/* Force the fnode into read-write mode */
fnp->f_mode = RDWR;
/* Select the default to help non-drive specified path */
/* searches... */
fnp->f_dpb = get_dpb(dmp->dm_drive);
if (media_check(fnp->f_dpb) < 0)
{
release_f_node(fnp);
return DE_NFILES;
}
dir_init_fnode(fnp, dmp->dm_dircluster);
/* Search through the directory to find the entry, but do a */
/* seek first. */
fnp->f_diroff = dmp->dm_entry;
/* Loop through the directory */
while (dir_read(fnp) == 1)
{
++dmp->dm_entry;
++fnp->f_diroff;
if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED
&& !(fnp->f_dir.dir_attrib & D_VOLID))
{
if (fcmp_wild(dmp->dm_name_pat, fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
{
/*
MSD Command.com uses FCB FN 11 & 12 with attrib set to 0x16.
Bits 0x21 seem to get set some where in MSD so Rd and Arc
files are returned.
RdOnly + Archive bits are ignored
*/
/* Test the attribute as the final step */
if (!(fnp->f_dir.dir_attrib & D_VOLID) &&
!(~dmp->dm_attr_srch & (D_DIR | D_SYSTEM | D_HIDDEN) &
fnp->f_dir.dir_attrib))
{
/* If found, transfer it to the dmatch structure */
dmp->dm_dircluster = fnp->f_dirstart;
memcpy(&SearchDir, &fnp->f_dir, sizeof(struct dirent));
/* return the result */
release_f_node(fnp);
return SUCCESS;
}
}
}
}
#ifdef DEBUG
printf("dos_findnext: %11s\n", fnp->f_dir.dir_name);
#endif
/* return the result */
release_f_node(fnp);
return DE_NFILES;
}
#endif
/*
this receives a name in 11 char field NAME+EXT and builds
a zeroterminated string
unfortunately, blanks are allowed in filenames. like
"test e", " test .y z",...
so we have to work from the last blank backward
*/
void ConvertName83ToNameSZ(BYTE FAR * destSZ, BYTE FAR * srcFCBName)
{
int loop;
int noExtension = FALSE;
if (*srcFCBName == '.')
{
noExtension = TRUE;
}
fmemcpy(destSZ, srcFCBName, FNAME_SIZE);
srcFCBName += FNAME_SIZE;
for (loop = FNAME_SIZE; --loop >= 0;)
{
if (destSZ[loop] != ' ')
break;
}
destSZ += loop + 1;
if (!noExtension) /* not for ".", ".." */
{
for (loop = FEXT_SIZE; --loop >= 0;)
{
if (srcFCBName[loop] != ' ')
break;
}
if (loop >= 0)
{
*destSZ++ = '.';
fmemcpy(destSZ, srcFCBName, loop + 1);
destSZ += loop + 1;
}
}
*destSZ = '\0';
}
#if 0
/*
returns the asciiSZ length of a 8.3 filename
*/
int FileName83Length(BYTE * filename83)
{
BYTE buff[13];
ConvertName83ToNameSZ(buff, filename83);
return strlen(buff);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -