📄 drobj.c
字号:
/* Update the DOS disk */
pc_ino2dos( pi, pobj->finode );
/* Write the data */
retval = pc_write_blk(pobj->pblkbuff);
/* Mark the inode in the inode buffer */
if (retval)
pc_marki(pobj->finode , pobj->pdrive , pd->my_block,
pd->my_index );
pc_free_buf(pbuff, (BOOLEAN)!retval);
return (retval);
}
}
else
{
pc_zeroseglist(&pobj->finode->s);
}
#else /* IF NOT VFAT */
/* End of dir if name is 0 */
if ( (pi->fname[0] == '\0') || (pi->fname[0] == PCDELETE) )
{
pd->my_index = (word)i;
/* Update the DOS disk */
pc_ino2dos( pi, pobj->finode );
/* Write the data */
retval = pc_write_blk(pobj->pblkbuff);
/* Mark the inode in the inode buffer */
if (retval)
pc_marki(pobj->finode , pobj->pdrive , pd->my_block,
pd->my_index );
pc_free_buf(pbuff, (BOOLEAN)(!retval));
return (retval);
}
#endif /* VFAT */
i++;
pi++;
}
/* Not in that block. Try again */
pc_free_buf(pbuff,FALSE);
/* Update the objects block pointer */
if (!pc_next_block(pobj))
#if (VFAT)
{
#if (FAT32)
if (pmom->pdrive->fasize != 8)
#endif
if (pc_isroot(pmom))
return (FALSE);
#if RTFS_SUBDIRS
/* Ok:There ar no slots in mom. We have to make one. And copy our stuf in */
#if (FAT32)
if (pobj->pdrive->fasize == 8)
{
dword tmpcl = pc_finode_cluster(pobj->pdrive,pmom->finode);
if (tmpcl == 0)
tmpcl = pc_sec2cluster(pobj->pdrive, pmom->pdrive->rootblock);
cluster = pc_clgrow(pobj->pdrive , tmpcl);
}
else
#endif
cluster = pc_clgrow(pobj->pdrive, pc_finode_cluster(pobj->pdrive,pmom->finode)); /* FAT32 */
if (!cluster)
return (FALSE);
/* Don't forget where the new item is */
pd->my_block = pc_cl2sector(pobj->pdrive , cluster);
pd->my_index = 0;
/* Zero out the cluster */
if (!pc_clzero( pobj->pdrive , cluster ) )
goto clean_and_fail;
/* Copy the item into the first block */
pobj->pblkbuff = pbuff = pc_init_blk( pobj->pdrive , pd->my_block);
if (!pbuff)
goto clean_and_fail;
#endif /* Subdir */
}
else
#else /* IF NOT VFAT */
break;
#endif /* VFAT */
pobj->pblkbuff = pbuff = pc_read_blk(pobj->pdrive, pobj->blkinfo.my_block);
}
#if (!VFAT)
/* Hmmm - root full ??. This is a problem */
#if (FAT32)
if (pmom->pdrive->fasize != 8)
#endif
if (pc_isroot(pmom))
return (FALSE);
#if RTFS_SUBDIRS
/* Ok:There ar no slots in mom. We have to make one. And copy our stuf in */
#if (FAT32)
if (pobj->pdrive->fasize == 8)
{
dword tmpcl = pc_finode_cluster(pobj->pdrive,pmom->finode);
if (tmpcl == 0)
tmpcl = pc_sec2cluster(pobj->pdrive, pmom->pdrive->rootblock);
cluster = pc_clgrow(pobj->pdrive , tmpcl);
}
else
#endif
cluster = pc_clgrow(pobj->pdrive, pc_finode_cluster(pobj->pdrive,pmom->finode)); /*FAT32 */
if (!cluster)
return (FALSE);
/* Don't forget where the new item is */
pd->my_block = pc_cl2sector(pobj->pdrive , cluster);
pd->my_index = 0;
/* Zero out the cluster */
if (!pc_clzero( pobj->pdrive , cluster ) )
goto clean_and_fail;
/* Copy the item into the first block */
pbuff = pc_init_blk( pobj->pdrive , pd->my_block);
if (!pbuff)
goto clean_and_fail;
pc_ino2dos ( (DOSINODE *) &pbuff->data[0] , pobj->finode ) ;
/* Write it out */
if ( !pc_write_blk ( pbuff ) )
{
pc_free_buf(pbuff,TRUE);
goto clean_and_fail;
}
/* We made a new slot. Mark the inode as belonging there */
pc_marki(pobj->finode , pobj->pdrive , pd->my_block, pd->my_index );
pc_free_buf(pbuff,FALSE);
return (TRUE);
#endif /* Subdir */
#endif /* VFAT */
clean_and_fail:
#if RTFS_SUBDIRS
#if (FAT32)
if (pobj->pdrive->fasize == 8)
{
dword tmpcl = pc_finode_cluster(pobj->pdrive,pmom->finode);
if (tmpcl == 0)
tmpcl = pc_sec2cluster(pmom->pdrive, pmom->pdrive->rootblock);
pc_cl_truncate(pobj->pdrive, tmpcl, cluster);
}
else
#endif /* FAT32 */
pc_cl_truncate(pobj->pdrive, pc_finode_cluster(pobj->pdrive,pmom->finode), cluster); /* FAT32 */
#endif /* Subdir */
return (FALSE);
}
#endif
RTFS_FILE(rmnode.c, pc_rmnode)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)
/***************************************************************************
PC_RMNODE - Delete an inode unconditionally.
Description
Delete the inode at pobj and flush the file allocation table. Does not
check file permissions or if the file is already open. (see also pc_unlink
and pc_rmdir). The inode is marked deleted on the disk and the cluster
chain associated with the inode is freed. (Un-delete won't work)
Returns
Returns TRUE if it successfully deleted the inode an flushed the fat.
*****************************************************************************/
/* Delete a file / dir or volume. Don't check for write access et al */
/* Note: the parent directory is locked before this routine is called */
BOOLEAN pc_rmnode( DROBJ *pobj) /*__fn__*/
{
CLUSTERTYPE cluster;
BOOLEAN ret_val;
/* Don't delete anything that has multiple links */
if (pobj->finode->opencount > 1)
{
#if (VFAT)
err_ex:
#endif
pc_report_error(PCERR_REMINODE);
return (FALSE);
}
/* Mark it deleted and unlink the cluster chain */
pobj->finode->fname[0] = PCDELETE;
#if (VFAT)
if (!pc_deleteseglist(pobj->pdrive, &pobj->finode->s))
goto err_ex;
#endif
cluster = pc_finode_cluster(pobj->pdrive,pobj->finode); /* FAT32 */
/* We free up store right away. Don't leave cluster pointer
hanging around to cause problems. */
pc_pfinode_cluster(pobj->pdrive,pobj->finode,0); /* FAT32 */
/* Convert to native. Overwrite the existing inode.Set archive/date */
if (pc_update_inode(pobj, TRUE, TRUE))
{
/* And clear up the space */
pc_freechain(pobj->pdrive, cluster);
ret_val = pc_flushfat(pobj->pdrive->driveno);
return (ret_val);
}
/* If it gets here we had a probblem */
return(FALSE);
}
#endif
RTFS_FILE(updinode.c, pc_update_inode)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)
/**************************************************************************
PC_UPDATE_INODE - Flush an inode to disk
Summary
Description
Read the disk inode information stored in pobj and write it to
the block and offset on the disk where it belongs. The disk is
first read to get the block and then the inode info is merged in
and the block is written. (see also pc_mknode() )
Returns
Returns TRUE if all went well, no on a write error.
*****************************************************************************
*/
/* Take a DROBJ that contains correct my_index & my_block. And an inode.
Load the block. Copy the inode in and write it back out */
BOOLEAN pc_update_inode(DROBJ *pobj, BOOLEAN set_archive, BOOLEAN set_date) /*__fn__*/
{
BLKBUFF *pbuff;
DOSINODE *pi;
int i;
BOOLEAN retval;
DIRBLK *pd;
DATESTR crdate;
pd = &pobj->blkinfo;
i = pd->my_index;
if ( i >= INOPBLOCK || i < 0 ) /* Index into block */
return (FALSE);
OS_CLAIM_FSCRITICAL()
/* Set the archive bit and the date */
if (set_archive)
pobj->finode->fattribute |= ARCHIVE;
if (set_date)
{
pc_getsysdate(&crdate);
pobj->finode->ftime = crdate.time;
pobj->finode->fdate = crdate.date;
}
OS_RELEASE_FSCRITICAL()
/* Read the data */
pobj->pblkbuff = pbuff = pc_read_blk(pobj->pdrive, pobj->blkinfo.my_block);
if (pbuff)
{
pi = (DOSINODE *) &pbuff->data[0];
/* Copy it off and write it */
pc_ino2dos( (pi+i), pobj->finode );
retval = pc_write_blk(pobj->pblkbuff);
/* Free the buff. If retval == FALSE(fail), pass a TRUE to
freebuf so it will discard the buffer. */
pc_free_buf(pbuff, (BOOLEAN)!retval);
return (retval);
}
return (FALSE);
}
#endif
RTFS_FILE(getroot.c, pc_get_root)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/*************************************************************************
PC_GET_ROOT - Create the special ROOT object for a drive.
Description
Use the information in pdrive to create a special object for accessing
files in the root directory.
Returns
Returns a pointer to a DROBJ, or NULL if no core available.
****************************************************************************/
/* Initialize the special "root" object
Note: We do not read any thing in here we just set up
the block pointers. */
DROBJ *pc_get_root( DDRIVE *pdrive) /*__fn__*/
{
DIRBLK *pd;
DROBJ *pobj;
FINODE *pfi;
pobj = pc_allocobj();
if (!pobj)
return (0);
pfi = pc_scani(pdrive, 0, 0);
if (pfi)
{
pc_freei(pobj->finode);
pobj->finode = pfi;
}
else /* No inode in the inode list. Copy the data over
and mark where it came from */
{
pc_marki(pobj->finode , pdrive , 0, 0);
}
/* Add a TEST FOR DRIVE INIT Here later */
pobj->pdrive = pdrive;
/* Set up the tree stuf so we know it is the root */
pd = &pobj->blkinfo;
pd->my_frstblock = pdrive->rootblock;
pd->my_block = pdrive->rootblock;
pd->my_index = 0;
pobj->isroot = TRUE;
return (pobj);
}
RTFS_FILE(firstblk.c, pc_firstblock)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/****************************************************************************
PC_FIRSTBLOCK - Return the absolute block number of a directory's
contents.
Description
Returns the block number of the first inode in the subdirectory. If
pobj is the root directory the first block of the root will be returned.
Returns
Returns 0 if the obj does not point to a directory, otherwise the
first block in the directory is returned.
*****************************************************************************/
/* Get the first block of a root or subdir */
BLOCKT pc_firstblock( DROBJ *pobj) /*__fn__*/
{
if (!pc_isadir(pobj))
return (BLOCKEQ0);
/* Root dir ? */
#if (RTFS_SUBDIRS)
if (!pobj->isroot)
return (pc_cl2sector(pobj->pdrive , pc_finode_cluster(pobj->pdrive, pobj->finode)) );
else
#endif
return (pobj->blkinfo.my_frstblock);
}
RTFS_FILE(nextblk.c, pc_next_block)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/***************************************************************************
PC_NEXT_BLOCK - Calculate the next block owned by an object.
Description
Find the next block owned by an object in either the root or a cluster
chain and update the blockinfo section of the object.
Returns
Returns TRUE or FALSE on end of chain.
*****************************************************************************/
/* Calculate the next block in an object */
BOOLEAN pc_next_block( DROBJ *pobj) /*__fn__*/
{
BLOCKT nxt;
nxt = pc_l_next_block(pobj->pdrive, pobj->blkinfo.my_block);
if (nxt)
{
pobj->blkinfo.my_block = nxt;
return (TRUE);
}
else
return (FALSE);
}
RTFS_FILE(lnextblk.c, pc_l_next_block)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/**************************************************************************
PC_L_NEXT_BLOCK - Calculate the next block in a chain.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -