Handle dos_getfattr and dos_setfattr directly at the directory level, instead

of opening the file, to avoid needing to claim SFTs in later changes.
Clarify and implement parts of the correct SHARE behaviour.


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1393 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2009-05-23 02:04:03 +00:00
parent 7083b0a4fa
commit affddaaf64
2 changed files with 43 additions and 58 deletions

View File

@ -1206,34 +1206,6 @@ COUNT DosGetFattr(BYTE FAR * name)
if (result & IS_DEVICE)
return DE_FILENOTFND;
/* /// Use truename()'s result, which we already have in PriPathName.
I copy it to tmp_name because PriPathName is global and seems
to get trashed somewhere in transit.
The reason for using truename()'s result is that dos_?etfattr()
are very low-level functions and don't handle full path expansion
or cleanup, such as converting "c:\a\b\.\c\.." to "C:\A\B".
- Ron Cemer
*/
/*
memcpy(SecPathName,PriPathName,sizeof(SecPathName));
return dos_getfattr(SecPathName, attrp);
*/
/* no longer true. dos_getfattr() is
A) intelligent (uses dos_open) anyway
B) there are some problems with MAX_PARSE, i.e. if PATH ~= 64
and TRUENAME adds a C:, which leeds to trouble.
the problem was discovered, when VC did something like
fd = DosOpen(filename,...)
jc can't_copy_dialog;
attr = DosGetAttrib(filename);
jc can't_copy_dialog;
and suddenly, the filehandle stays open
shit.
tom
*/
return dos_getfattr(PriPathName);
}
@ -1254,17 +1226,16 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp)
if (result & IS_DEVICE)
return DE_FILENOTFND;
/* /// Use truename()'s result, which we already have in PriPathName.
I copy it to tmp_name because PriPathName is global and seems
to get trashed somewhere in transit.
- Ron Cemer
*/
/*
memcpy(SecPathName,PriPathName,sizeof(SecPathName));
return dos_setfattr(SecPathName, attrp);
see DosGetAttr()
*/
if (IsShareInstalled(TRUE))
{
/* XXX SHARE should ideally close the file if it is opened in
* compatibility mode, else generate a critical error.
* Here just generate a critical error by opening in "rw compat"
* mode */
if ((result = share_open_check(PriPathName, cu_psp, O_RDWR, 0)) < 0)
return result;
share_close_file(result);
}
return dos_setfattr(PriPathName, attrp);
}

View File

@ -501,6 +501,7 @@ STATIC void copy_file_changes(f_node_ptr src, f_node_ptr dst)
dst->f_dir.dir_size = src->f_dir.dir_size;
dst->f_dir.dir_date = src->f_dir.dir_date;
dst->f_dir.dir_time = src->f_dir.dir_time;
dst->f_dir.dir_attrib = src->f_dir.dir_attrib;
}
STATIC COUNT delete_dir_entry(f_node_ptr fnp)
@ -1935,21 +1936,28 @@ COUNT dos_getfattr_fd(COUNT fd)
COUNT dos_getfattr(BYTE * name)
{
COUNT result, fd;
f_node_ptr fnp;
char fcbname[FNAME_SIZE + FEXT_SIZE];
COUNT result;
fd = (short)dos_open(name, O_RDONLY | O_OPEN, 0);
if (fd < SUCCESS)
return fd;
/* split the passed dir into components (i.e. - path to */
/* new directory and name of new directory. */
if ((fnp = split_path(name, fcbname, &fnode[0])) == NULL)
return DE_PATHNOTFND;
result = dos_getfattr_fd(fd);
dos_close(fd);
if (find_fname(fnp, fcbname, D_ALL))
result = fnp->f_dir.dir_attrib;
else
result = DE_FILENOTFND;
dir_close(fnp);
return result;
}
COUNT dos_setfattr(BYTE * name, UWORD attrp)
{
COUNT fd;
f_node_ptr fnp;
char fcbname[FNAME_SIZE + FEXT_SIZE];
/* JPP-If user tries to set VOLID or RESERVED bits, return error.
We used to also check for D_DIR here, but causes issues with deltree
@ -1960,29 +1968,35 @@ COUNT dos_setfattr(BYTE * name, UWORD attrp)
if ((attrp & (D_VOLID | 0xC0)) != 0)
return DE_ACCESS;
fd = (short)dos_open(name, O_RDONLY | O_OPEN, 0);
if (fd < SUCCESS)
return fd;
/* split the passed dir into components (i.e. - path to */
/* new directory and name of new directory. */
if ((fnp = split_path(name, fcbname, &fnode[0])) == NULL)
return DE_PATHNOTFND;
fnp = xlt_fd(fd);
/* Set the attribute from the fnode and return */
/* clear all attributes but DIR and VOLID */
fnp->f_dir.dir_attrib &= (D_VOLID | D_DIR); /* JPP */
if (!find_fname(fnp, fcbname, D_ALL)) {
dir_close(fnp);
return DE_FILENOTFND;
}
/* if caller tries to set DIR on non-directory, return error */
if ((attrp & D_DIR) && !(fnp->f_dir.dir_attrib & D_DIR))
{
dos_close(fd);
dir_close(fnp);
return DE_ACCESS;
}
/* Set the attribute from the fnode and return */
/* clear all attributes but DIR and VOLID */
fnp->f_dir.dir_attrib &= (D_VOLID | D_DIR); /* JPP */
/* set attributes that user requested */
fnp->f_dir.dir_attrib |= attrp; /* JPP */
fnp->f_flags |= F_DMOD | F_DDATE;
/* should really close the file instead of merge */
merge_file_changes(fnp, FALSE);
save_far_f_node(fnp);
dos_close(fd);
dir_write(fnp);
dir_close(fnp);
return SUCCESS;
}
#endif