mirror of https://github.com/FDOS/kernel.git
dir_read() no longer updates the diroff counter. This eliminates the NEW
field, simplifies remove_lfn_entries(), and avoids a bug if you delete the first entry in the root directory on FAT32. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@911 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
976efed7a5
commit
ecfcb9be29
|
@ -54,9 +54,8 @@ struct f_node {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define F_DMOD 1 /* directory has been modified */
|
#define F_DMOD 1 /* directory has been modified */
|
||||||
#define F_DNEW 2 /* fnode is new and needs fill */
|
#define F_DDIR 2 /* fnode is assigned to dir */
|
||||||
#define F_DDIR 4 /* fnode is assigned to dir */
|
#define F_DDATE 4 /* date set using setdate */
|
||||||
#define F_DDATE 8 /* date set using setdate */
|
|
||||||
|
|
||||||
typedef struct f_node *f_node_ptr;
|
typedef struct f_node *f_node_ptr;
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ static BYTE *fatdirRcsId =
|
||||||
VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart)
|
VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart)
|
||||||
{
|
{
|
||||||
/* reset the directory flags */
|
/* reset the directory flags */
|
||||||
fnp->f_flags = F_DDIR | F_DNEW;
|
fnp->f_flags = F_DDIR;
|
||||||
fnp->f_diroff = 0;
|
fnp->f_diroff = 0;
|
||||||
fnp->f_offset = 0l;
|
fnp->f_offset = 0l;
|
||||||
fnp->f_cluster_offset = 0;
|
fnp->f_cluster_offset = 0;
|
||||||
|
@ -143,6 +143,7 @@ f_node_ptr dir_open(register const char *dirname)
|
||||||
i = TRUE;
|
i = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
fnp->f_diroff++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i || !(fnp->f_dir.dir_attrib & D_DIR))
|
if (!i || !(fnp->f_dir.dir_attrib & D_DIR))
|
||||||
|
@ -198,22 +199,11 @@ COUNT dir_read(REG f_node_ptr fnp)
|
||||||
{
|
{
|
||||||
struct buffer FAR *bp;
|
struct buffer FAR *bp;
|
||||||
REG UWORD secsize = fnp->f_dpb->dpb_secsize;
|
REG UWORD secsize = fnp->f_dpb->dpb_secsize;
|
||||||
unsigned new_diroff = fnp->f_diroff;
|
|
||||||
|
|
||||||
/* can't have more than 65535 directory entries
|
/* can't have more than 65535 directory entries */
|
||||||
remove lfn entries may call us with new_diroff == -1
|
if (fnp->f_diroff >= 65535U)
|
||||||
for root directories though */
|
|
||||||
if (fnp->f_dirstart != 0 && new_diroff >= 65535U)
|
|
||||||
return DE_SEEK;
|
return DE_SEEK;
|
||||||
|
|
||||||
/* Directories need to point to their current offset, not for */
|
|
||||||
/* next op. Therefore, if it is anything other than the first */
|
|
||||||
/* directory entry, we will update the offset on entry rather */
|
|
||||||
/* than wait until exit. If it was new, clear the special new */
|
|
||||||
/* flag. */
|
|
||||||
if (!(fnp->f_flags & F_DNEW))
|
|
||||||
new_diroff++;
|
|
||||||
|
|
||||||
/* Determine if we hit the end of the directory. If we have, */
|
/* Determine if we hit the end of the directory. If we have, */
|
||||||
/* bump the offset back to the end and exit. If not, fill the */
|
/* bump the offset back to the end and exit. If not, fill the */
|
||||||
/* dirent portion of the fnode, clear the f_dmod bit and leave, */
|
/* dirent portion of the fnode, clear the f_dmod bit and leave, */
|
||||||
|
@ -221,10 +211,10 @@ COUNT dir_read(REG f_node_ptr fnp)
|
||||||
|
|
||||||
if (fnp->f_dirstart == 0)
|
if (fnp->f_dirstart == 0)
|
||||||
{
|
{
|
||||||
if (new_diroff >= fnp->f_dpb->dpb_dirents)
|
if (fnp->f_diroff >= fnp->f_dpb->dpb_dirents)
|
||||||
return DE_SEEK;
|
return DE_SEEK;
|
||||||
|
|
||||||
bp = getblock(new_diroff / (secsize / DIRENT_SIZE)
|
bp = getblock(fnp->f_diroff / (secsize / DIRENT_SIZE)
|
||||||
+ fnp->f_dpb->dpb_dirstrt, fnp->f_dpb->dpb_unit);
|
+ fnp->f_dpb->dpb_dirstrt, fnp->f_dpb->dpb_unit);
|
||||||
#ifdef DISPLAY_GETBLOCK
|
#ifdef DISPLAY_GETBLOCK
|
||||||
printf("DIR (dir_read)\n");
|
printf("DIR (dir_read)\n");
|
||||||
|
@ -233,7 +223,7 @@ COUNT dir_read(REG f_node_ptr fnp)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Do a "seek" to the directory position */
|
/* Do a "seek" to the directory position */
|
||||||
fnp->f_offset = new_diroff * (ULONG)DIRENT_SIZE;
|
fnp->f_offset = fnp->f_diroff * (ULONG)DIRENT_SIZE;
|
||||||
|
|
||||||
/* Search through the FAT to find the block */
|
/* Search through the FAT to find the block */
|
||||||
/* that this entry is in. */
|
/* that this entry is in. */
|
||||||
|
@ -258,14 +248,13 @@ COUNT dir_read(REG f_node_ptr fnp)
|
||||||
bp->b_flag |= BFR_DIR | BFR_VALID;
|
bp->b_flag |= BFR_DIR | BFR_VALID;
|
||||||
|
|
||||||
getdirent((BYTE FAR *) & bp->
|
getdirent((BYTE FAR *) & bp->
|
||||||
b_buffer[(new_diroff * DIRENT_SIZE) % fnp->f_dpb->dpb_secsize],
|
b_buffer[(fnp->f_diroff * DIRENT_SIZE) % fnp->f_dpb->dpb_secsize],
|
||||||
&fnp->f_dir);
|
&fnp->f_dir);
|
||||||
|
|
||||||
swap_deleted(fnp->f_dir.dir_name);
|
swap_deleted(fnp->f_dir.dir_name);
|
||||||
|
|
||||||
/* Update the fnode's directory info */
|
/* Update the fnode's directory info */
|
||||||
fnp->f_flags &= ~(F_DMOD | F_DNEW);
|
fnp->f_flags &= ~F_DMOD;
|
||||||
fnp->f_diroff = new_diroff;
|
|
||||||
|
|
||||||
/* and for efficiency, stop when we hit the first */
|
/* and for efficiency, stop when we hit the first */
|
||||||
/* unused entry. */
|
/* unused entry. */
|
||||||
|
@ -278,9 +267,6 @@ COUNT dir_read(REG f_node_ptr fnp)
|
||||||
* situation fnode is released.
|
* situation fnode is released.
|
||||||
* The caller should set
|
* The caller should set
|
||||||
* 1. F_DMOD flag if original directory entry was modified.
|
* 1. F_DMOD flag if original directory entry was modified.
|
||||||
* 2. F_DMOD & F_DNEW flags if new directory entry is created. In this
|
|
||||||
* case the reserved fields is cleared, but only if new dentry isn't
|
|
||||||
* a LFN entry (has D_LFN attribute).
|
|
||||||
* Return value.
|
* Return value.
|
||||||
* TRUE - all OK.
|
* TRUE - all OK.
|
||||||
* FALSE - error occured (fnode is released).
|
* FALSE - error occured (fnode is released).
|
||||||
|
@ -348,9 +334,6 @@ BOOL dir_write(REG f_node_ptr fnp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fnp->f_flags & F_DNEW) && fnp->f_dir.dir_attrib != D_LFN)
|
|
||||||
fmemset(&fnp->f_dir.dir_case, 0, 8);
|
|
||||||
|
|
||||||
swap_deleted(fnp->f_dir.dir_name);
|
swap_deleted(fnp->f_dir.dir_name);
|
||||||
|
|
||||||
putdirent(&fnp->f_dir, &bp->b_buffer[(fnp->f_diroff * DIRENT_SIZE) %
|
putdirent(&fnp->f_dir, &bp->b_buffer[(fnp->f_diroff * DIRENT_SIZE) %
|
||||||
|
@ -454,6 +437,7 @@ COUNT dos_findfirst(UCOUNT attr, BYTE * name)
|
||||||
dir_close(fnp);
|
dir_close(fnp);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
fnp->f_diroff++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that we've done our failed search, close it and */
|
/* Now that we've done our failed search, close it and */
|
||||||
|
@ -509,17 +493,13 @@ COUNT dos_findnext(void)
|
||||||
|
|
||||||
/* Search through the directory to find the entry, but do a */
|
/* Search through the directory to find the entry, but do a */
|
||||||
/* seek first. */
|
/* seek first. */
|
||||||
fnp->f_flags |= F_DNEW;
|
fnp->f_diroff = dmp->dm_entry;
|
||||||
if (dmp->dm_entry > 0)
|
|
||||||
{
|
|
||||||
fnp->f_diroff = dmp->dm_entry - 1;
|
|
||||||
fnp->f_flags &= ~F_DNEW;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop through the directory */
|
/* Loop through the directory */
|
||||||
while (dir_read(fnp) == 1)
|
while (dir_read(fnp) == 1)
|
||||||
{
|
{
|
||||||
++dmp->dm_entry;
|
++dmp->dm_entry;
|
||||||
|
++fnp->f_diroff;
|
||||||
if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED
|
if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED
|
||||||
&& (fnp->f_dir.dir_attrib & D_VOLID) != D_VOLID)
|
&& (fnp->f_dir.dir_attrib & D_VOLID) != D_VOLID)
|
||||||
{
|
{
|
||||||
|
|
|
@ -407,6 +407,7 @@ STATIC BOOL find_fname(f_node_ptr fnp, char *fcbname, int attr)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
fnp->f_diroff++;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -428,10 +429,7 @@ COUNT remove_lfn_entries(f_node_ptr fnp)
|
||||||
{
|
{
|
||||||
if (fnp->f_diroff == 0)
|
if (fnp->f_diroff == 0)
|
||||||
break;
|
break;
|
||||||
fnp->f_diroff -= 2;
|
fnp->f_diroff--;
|
||||||
/* it cannot / should not get below 0 because of '.' and '..'
|
|
||||||
* except for root directories... but then dir_read() makes it 0
|
|
||||||
* again */
|
|
||||||
if (dir_read(fnp) <= 0) {
|
if (dir_read(fnp) <= 0) {
|
||||||
dir_close(fnp);
|
dir_close(fnp);
|
||||||
return DE_BLKINVLD;
|
return DE_BLKINVLD;
|
||||||
|
@ -442,7 +440,7 @@ COUNT remove_lfn_entries(f_node_ptr fnp)
|
||||||
fnp->f_flags |= F_DMOD;
|
fnp->f_flags |= F_DMOD;
|
||||||
if (!dir_write(fnp)) return DE_BLKINVLD;
|
if (!dir_write(fnp)) return DE_BLKINVLD;
|
||||||
}
|
}
|
||||||
fnp->f_diroff = original_diroff - 1;
|
fnp->f_diroff = original_diroff;
|
||||||
if (dir_read(fnp) <= 0) {
|
if (dir_read(fnp) <= 0) {
|
||||||
dir_close(fnp);
|
dir_close(fnp);
|
||||||
return DE_BLKINVLD;
|
return DE_BLKINVLD;
|
||||||
|
@ -642,6 +640,7 @@ COUNT dos_rmdir(BYTE * path)
|
||||||
return DE_ACCESS;
|
return DE_ACCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fnp1->f_diroff++;
|
||||||
dir_read(fnp1);
|
dir_read(fnp1);
|
||||||
if (fnp1->f_dir.dir_name[0] != '.')
|
if (fnp1->f_dir.dir_name[0] != '.')
|
||||||
{
|
{
|
||||||
|
@ -652,18 +651,18 @@ COUNT dos_rmdir(BYTE * path)
|
||||||
/* Now search through the directory and make certain */
|
/* Now search through the directory and make certain */
|
||||||
/* that there are no entries. */
|
/* that there are no entries. */
|
||||||
found = FALSE;
|
found = FALSE;
|
||||||
|
fnp1->f_diroff++;
|
||||||
while (dir_read(fnp1) == 1)
|
while (dir_read(fnp1) == 1)
|
||||||
{
|
{
|
||||||
if (fnp1->f_dir.dir_name[0] == '\0')
|
if (fnp1->f_dir.dir_name[0] == '\0')
|
||||||
break;
|
break;
|
||||||
if (fnp1->f_dir.dir_name[0] == DELETED
|
if (fnp1->f_dir.dir_name[0] != DELETED
|
||||||
|| fnp1->f_dir.dir_attrib == D_LFN)
|
&& fnp1->f_dir.dir_attrib != D_LFN)
|
||||||
continue;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
fnp1->f_diroff++;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir_close(fnp1);
|
dir_close(fnp1);
|
||||||
|
@ -817,8 +816,11 @@ STATIC BOOL find_free(f_node_ptr fnp)
|
||||||
COUNT rc;
|
COUNT rc;
|
||||||
|
|
||||||
while ((rc = dir_read(fnp)) == 1)
|
while ((rc = dir_read(fnp)) == 1)
|
||||||
|
{
|
||||||
if (fnp->f_dir.dir_name[0] == DELETED)
|
if (fnp->f_dir.dir_name[0] == DELETED)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
fnp->f_diroff++;
|
||||||
|
}
|
||||||
return rc >= 0;
|
return rc >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue