Make findfirst/findnext more MSDOS compatible:

* ignore 0x40 (D_DEVICE) in search attribute.
* if you specify D_VOLID + one or more of D_HIDDEN, D_SYSTEM, and D_DIR you
  will get files *and* volume labels in the specified directory, not forced
  to the root directory.
* VOLID searches must look at the search pattern name too, or do not match.


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1438 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2009-06-12 20:38:40 +00:00
parent f5696a4a7e
commit 07d2b24149
2 changed files with 24 additions and 36 deletions

View File

@ -1021,6 +1021,8 @@ COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name)
const char *p;
COUNT i;
/* make sure the next search fails */
sda_tmp_dm.dm_entry = 0xffff;
/* Found a matching device. Hence there cannot be wildcards. */
SearchDir.dir_attrib = D_DEVICE;
SearchDir.dir_time = dos_gettime();
@ -1043,10 +1045,6 @@ COUNT DosFindNext(void)
COUNT rc;
register dmatch FAR *dmp = dta;
/* findnext will always fail on a device name device name or volume id */
if (dmp->dm_attr_fnd & (D_DEVICE | D_VOLID))
return DE_NFILES;
/*
* The new version of SHSUCDX 1.0 looks at the dm_drive byte to
* test 40h. I used RamView to see location MSD 116:04be and
@ -1068,6 +1066,12 @@ COUNT DosFindNext(void)
printf("findnext: %d\n", dmp->dm_drive);
#endif
fmemcpy(&sda_tmp_dm, dmp, 21);
/* findnext will always fail on a volume id search or device name */
if ((sda_tmp_dm.dm_attr_srch & ~(D_RDONLY | D_ARCHIVE | D_DEVICE)) == D_VOLID
|| sda_tmp_dm.dm_entry == 0xffff)
return DE_NFILES;
memset(&SearchDir, 0, sizeof(struct dirent));
dta = &sda_tmp_dm;
rc = (sda_tmp_dm.dm_drive & 0x80) ?

View File

@ -283,6 +283,7 @@ COUNT dos_findfirst(UCOUNT attr, BYTE * name)
REG f_node_ptr fnp;
REG dmatch *dmp = &sda_tmp_dm;
REG COUNT i;
char *fname;
/* printf("ff %Fs\n", name);*/
@ -308,13 +309,13 @@ COUNT dos_findfirst(UCOUNT attr, BYTE * name)
/* 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 (while ignoring LFN entries). */
/* RBIL: ignore ReaDONLY and ARCHIVE bits */
/* RBIL: ignore ReaDONLY and ARCHIVE bits but DEVICE ignored too*/
/* For compatibility with bad search requests, only treat as */
/* volume search if only volume bit set, else ignore it. */
if ((attr & ~(D_RDONLY | D_ARCHIVE))==D_VOLID) /* if ONLY label wanted */
i = 3; /* redirect search to root dir (?) in volume label case */
else
attr &= ~D_VOLID; /* ignore volume mask */
fname = &name[i];
if ((attr & ~(D_RDONLY | D_ARCHIVE | D_DEVICE)) == D_VOLID)
/* if ONLY label wanted redirect search to root dir */
i = 3;
/* Now open this directory so that we can read the */
/* fnode entry and do a match on it. */
@ -329,32 +330,10 @@ COUNT dos_findfirst(UCOUNT attr, BYTE * name)
}
/* Now initialize the dirmatch structure. */
ConvertNameSZToName83(dmp->dm_name_pat, &name[i]);
ConvertNameSZToName83(dmp->dm_name_pat, fname);
dmp->dm_drive = name[0] - 'A';
dmp->dm_attr_srch = attr;
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)
{
memcpy(&SearchDir, &fnp->f_dir, sizeof(struct dirent));
#ifdef DEBUG
printf("dos_findfirst: %11s\n", fnp->f_dir.dir_name);
#endif
return SUCCESS;
}
dmp->dm_entry++;
}
/* Now that we've done our failed search, return an error. */
return DE_NFILES;
}
/* Otherwise just do a normal find next */
return dos_findnext();
}
@ -388,8 +367,8 @@ COUNT dos_findnext(void)
while (dir_read(fnp) == 1)
{
++dmp->dm_entry;
if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED
&& !(fnp->f_dir.dir_attrib & D_VOLID))
if (fnp->f_dir.dir_name[0] != DELETED
&& (fnp->f_dir.dir_attrib & D_LFN) != D_LFN)
{
if (fcmp_wild(dmp->dm_name_pat, fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
{
@ -401,8 +380,13 @@ COUNT dos_findnext(void)
*/
/* 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) &
/* It's either a special volume label search or an */
/* attribute inclusive search. The attribute inclusive search */
/* can also find volume labels if you set e.g. D_DIR|D_VOLUME */
UBYTE attr_srch;
attr_srch = dmp->dm_attr_srch & ~(D_RDONLY | D_ARCHIVE | D_DEVICE);
if ((attr_srch == D_VOLID && (fnp->f_dir.dir_attrib & D_VOLID)) ||
!(~attr_srch & (D_DIR | D_SYSTEM | D_HIDDEN | D_VOLID) &
fnp->f_dir.dir_attrib))
{
/* If found, transfer it to the dmatch structure */