Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for label #17 bugs #86

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions hdr/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ extern request /* I/O Request packets */
/* dsk.c */
COUNT ASMCFUNC FAR blk_driver(rqptr rp);
ddt * getddt(int dev);
COUNT writelabelBPB(char drive, const char *name);

/* error.c */
COUNT char_error(request * rq, struct dhdr FAR * lpDevice);
Expand Down
35 changes: 34 additions & 1 deletion kernel/dsk.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,40 @@ ddt *getddt(int dev)
return &(((ddt *) Dyn.Buffer)[dev]);
}

STATIC WORD getbpb(ddt *pddt);
STATIC WORD RWzero(ddt *pddt, UWORD mode);

COUNT writelabelBPB(char drive, const char *name)
{
ddt *pddt = getddt(drive - 'A');
struct FS_info *fs;
int offset;
int ret;

ret = getbpb(pddt);
if (ret != 0)
return ret;

if (DiskTransferBuffer[0x26] == 0x29 &&
pddt->ddt_bpb.bpb_nfsect != 0) // BPB v4.1
offset = 0x27;
else if (DiskTransferBuffer[0x42] == 0x29 &&
pddt->ddt_bpb.bpb_nfsect == 0) // BPB v7 long
offset = 0x43;
else
return -1;

/* store volume name */
fs = (struct FS_info *)&DiskTransferBuffer[offset];
memcpy(&fs->volume[0], name, 11);

ret = RWzero(pddt, LBA_WRITE);
if (ret != 0)
return ret;

return 0;
}

STATIC VOID tmark(ddt *pddt)
{
pddt->ddt_fh.ddt_lasttime = ReadPCClock();
Expand All @@ -122,7 +156,6 @@ STATIC dsk_proc mediachk, bldbpb, blockio, IoctlQueblk,
Genblkdev, Getlogdev, Setlogdev, blk_Open, blk_Close,
blk_Media, blk_noerr, blk_nondr, blk_error;

STATIC WORD getbpb(ddt * pddt);
#ifdef PROTO
STATIC WORD dskerr(COUNT);
#else
Expand Down
72 changes: 67 additions & 5 deletions kernel/fatfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ BYTE *RcsId = "$Id: fatfs.c 1632 2011-06-13 16:29:14Z bartoldeman $";
/* */
STATIC f_node_ptr sft_to_fnode(int fd);
STATIC void fnode_to_sft(f_node_ptr fnp);
STATIC int find_fattr(const char *path, int attr, f_node_ptr fnp);
STATIC int find_fname(const char *path, int attr, f_node_ptr fnp);
/* /// Added - Ron Cemer */
STATIC int merge_file_changes(f_node_ptr fnp, int collect);
Expand Down Expand Up @@ -124,10 +125,36 @@ STATIC void init_direntry(struct dirent *dentry, unsigned attrib,
int dos_open(char *path, unsigned flags, unsigned attrib, int fd)
{
REG f_node_ptr fnp = sft_to_fnode(fd);
int status = find_fname(path, D_ALL | attrib, fnp);
int status;

/* Special handling for volume name (they can coexist with files/directories) */
if (((attrib & (D_DIR | D_VOLID | D_SYSTEM | D_HIDDEN | D_RDONLY)) == D_VOLID) &&
(flags & O_TRUNC))
{
int ret;

/* Count the slashes to see if we are in the root directory */
if (strchr(path + 3, '\\'))
return DE_ACCESS;

/* Check to see if there are any other files with VOLID set */
status = find_fattr(path, D_VOLID, fnp);
if (status == SUCCESS)
return DE_ACCESS;

/* Create our new label */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if you still have a normal
file with that name?
I think that block should be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if you still have a normal
file with that name?
I think that block should be removed.

The point of this patch is that a file or directory can coexist with a label of the same name.

ret = alloc_find_free(fnp, path);
if (ret != SUCCESS)
return ret;
status = S_CREATED;

writelabelBPB(path[0], path + 3);
goto doit;
}

/* Check that we don't have a duplicate name, so if we */
/* find one, truncate it (O_CREAT). */
status = find_fname(path, D_ALL | attrib, fnp);
if (status == SUCCESS)
{
unsigned char dir_attrib = fnp->f_dir.dir_attrib;
Expand Down Expand Up @@ -179,6 +206,8 @@ int dos_open(char *path, unsigned flags, unsigned attrib, int fd)
return status;
}

doit:

/* Now change to file */
fnp->f_sft_idx = fd;
fnp->f_offset = 0l;
Expand Down Expand Up @@ -232,7 +261,7 @@ COUNT dos_close(COUNT fd)
}

/* */
/* split a path into it's component directory and file name */
/* split a path into its component directory and file name */
/* */
f_node_ptr split_path(const char * path, f_node_ptr fnp)
{
Expand Down Expand Up @@ -274,19 +303,52 @@ BOOL fcbmatch(const char *fcbname1, const char *fcbname2)
return memcmp(fcbname1, fcbname2, FNAME_SIZE + FEXT_SIZE) == 0;
}

STATIC int find_fattr(const char *path, int attr, f_node_ptr fnp)
{
/* check for leading backslash and open the directory given that */
/* contains the file given by path. */
if ((fnp = split_path(path, fnp)) == NULL)
return DE_PATHNOTFND;

while (dir_read(fnp) == 1)
{
if ((fnp->f_dir.dir_attrib & attr) == attr)
return SUCCESS;
fnp->f_dmp->dm_entry++;
}
return DE_FILENOTFND;
}

STATIC int find_fname(const char *path, int attr, f_node_ptr fnp)
{
/* check for leading backslash and open the directory given that */
/* contains the file given by path. */
if ((fnp = split_path(path, fnp)) == NULL)
return DE_PATHNOTFND;

/*
* attr = 0x00 returns NORMAL
* 0x02 returns NORMAL + HIDDEN
* 0x04 returns NORMAL + SYSTEM
* 0x06 returns NORMAL + HIDDEN + SYSTEM
* 0x08 returns VOLID only (DOS 3+)
* 0x10 returns DIRECTORIES
*/

while (dir_read(fnp) == 1)
{
if (fcbmatch(fnp->f_dir.dir_name, fnp->f_dmp->dm_name_pat)
&& (fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE | attr)) == 0)
if (fcbmatch(fnp->f_dir.dir_name, fnp->f_dmp->dm_name_pat))
{
return SUCCESS;
if (attr & D_VOLID)
{
if (fnp->f_dir.dir_attrib & D_VOLID)
return SUCCESS;
}
else
{
if ((fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE | attr)) == 0)
return SUCCESS;
}
}
fnp->f_dmp->dm_entry++;
}
Expand Down