📄 drobj.c
字号:
Nothing
***************************************************************************/
/* Take an unlinked inode and link it in to the inode chain. Initialize
the open count and sector locater info. */
void pc_marki( FINODE *pfi, DDRIVE *pdrive, BLOCKT sectorno, int index)/*__fn__*/
{
OS_CLAIM_FSCRITICAL()
pfi->my_drive = pdrive;
pfi->my_block = sectorno;
pfi->my_index = index;
pfi->opencount = 1;
/* Stitch the inode at the front of the list */
if (inoroot)
inoroot->pprev = pfi;
pfi->pprev = 0;
pfi->pnext = inoroot;
inoroot = pfi;
OS_RELEASE_FSCRITICAL()
}
/**************************************************************************
PC_SCANI - Search for an inode in the internal inode list.
Description
Each inode is uniquely determined by DRIVE, BLOCK and Index into that
block. This routine searches the current active inode list to see
if the inode is in use. If so the opencount is changed and a pointer is
returned. This guarantees that two processes will work on the same
information when manipulating the same file or directory.
Returns
A pointer to the FINODE for pdrive:sector:index or NULL if not found
****************************************************************************/
/* See if the inode for drive,sector , index is in the list. If so..
bump its open count and return it. Else return NULL */
FINODE *pc_scani( DDRIVE *pdrive, BLOCKT sectorno, int index) /*__fn__*/
{
FINODE *pfi;
OS_CLAIM_FSCRITICAL()
pfi = inoroot;
while (pfi)
{
if ( (pfi->my_drive == pdrive) &&
(pfi->my_block == sectorno) &&
(pfi->my_index == index) )
{
pfi->opencount += 1;
OS_RELEASE_FSCRITICAL()
return (pfi);
}
pfi = pfi->pnext;
}
OS_RELEASE_FSCRITICAL()
return (0);
}
/**************************************************************************
PC_ALLOCOBJ - Allocate a DROBJ structure
Description
Allocates and zeroes the space needed to store a DROBJ structure. Also
allocates and zeroes a FINODE structure and links the two via the
finode field in the DROBJ structure.
Returns
Returns a valid pointer or NULL if no more core.
*****************************************************************************/
DROBJ *pc_allocobj(void) /*__fn__*/
{
DROBJ *pobj;
/* Alloc a DROBJ */
pobj = pc_memory_drobj(0);
if (pobj)
{
pobj->finode = pc_alloci();
if (!pobj->finode)
{
/* Free the DROBJ */
pc_memory_drobj(pobj);
pobj = 0;
}
}
return (pobj);
}
/**************************************************************************
PC_ALLOCI - Allocate a FINODE structure
Description
Allocates and zeroes a FINODE structure.
Returns
Returns a valid pointer or NULL if no more core.
****************************************************************************/
FINODE *pc_alloci(void) /*__fn__*/
{
FINODE *p;
p = pc_memory_finode(0);
return(p);
}
/**************************************************************************
PC_FREE_ALL_I - Release all inode buffers associated with a drive.
Description
For each internally buffered finode (dirent) check if it exists on
pdrive. If so delete it. In debug mode print a message since all
finodes should be freed before pc_dskclose is called.
Returns
Nothing
****************************************************************************/
void pc_free_all_i( DDRIVE *pdrive) /*__fn__*/
{
FINODE *pfi;
OS_CLAIM_FSCRITICAL()
pfi = inoroot;
OS_RELEASE_FSCRITICAL()
while (pfi)
{
if (pfi->my_drive == pdrive)
{
/* Set the opencount to 1 so freei releases the inode */
pfi->opencount = 1;
pc_freei(pfi);
/* Since we changed the list go back to the top */
OS_CLAIM_FSCRITICAL()
pfi = inoroot;
OS_RELEASE_FSCRITICAL()
}
else
{
OS_CLAIM_FSCRITICAL()
pfi = pfi->pnext;
OS_RELEASE_FSCRITICAL()
}
}
}
/*****************************************************************************
PC_FREEI - Release an inode from service
Description
If the FINODE structure is only being used by one file or DROBJ, unlink it
from the internal active inode list and return it to the heap; otherwise
reduce its open count.
Returns
Nothing
****************************************************************************/
void pc_freei( FINODE *pfi) /*__fn__*/
{
if (!pfi)
{
return;
}
OS_CLAIM_FSCRITICAL()
if (pfi->opencount)
{
if (--pfi->opencount) /* Decrement opencount and return if non zero */
{
OS_RELEASE_FSCRITICAL()
return;
}
else
{
if (pfi->pprev) /* Pont the guy behind us at the guy in front*/
{
pfi->pprev->pnext = pfi->pnext;
}
else
{
inoroot = pfi->pnext; /* No prev, we were at the front so
make the next guy the front */
}
if (pfi->pnext) /* Make the next guy point behind */
{
pfi->pnext->pprev = pfi->pprev;
}
}
}
OS_RELEASE_FSCRITICAL()
/* release the core */
pc_memory_finode(pfi);
}
/***************************************************************************
PC_FREEOBJ - Free a DROBJ structure
Description
Return a drobj structure to the heap. Calls pc_freei to reduce the
open count of the finode structure it points to and return it to the
heap if appropriate.
Returns
Nothing
****************************************************************************/
void pc_freeobj( DROBJ *pobj) /*__fn__*/
{
if (pobj)
{
pc_freei(pobj->finode);
/* Release the core */
pc_memory_drobj(pobj);
}
}
/***************************************************************************
PC_DOS2INODE - Convert a dos disk entry to an in memory inode.
Description
Take the data from pbuff which is a raw disk directory entry and copy
it to the inode at pdir. The data goes from INTEL byte ordering to
native during the transfer.
Returns
Nothing
****************************************************************************/
/* Convert a dos inode to in mem form. */
void pc_dos2inode (FINODE *pdir, DOSINODE *pbuff) /*__fn__*/
{
copybuff(&pdir->fname[0],&pbuff->fname[0],8); /*X*/
copybuff(&pdir->fext[0],&pbuff->fext[0],3); /*X*/
pdir->fattribute = pbuff->fattribute; /*X*/
#if (FAT32)
copybuff(&pdir->resarea[0],&pbuff->resarea[0], 8); /*X*/
#else
copybuff(&pdir->resarea[0],&pbuff->resarea[0], 10); /*X*/
#endif
#if (!KS_LITTLE_ENDIAN)
pdir->ftime = to_WORD((byte *) &pbuff->ftime); /*X*/
pdir->fdate = to_WORD((byte *) &pbuff->fdate); /*X*/
#if (FAT32)
pdir->fclusterhi = to_WORD((byte *) &pbuff->fclusterhi); /*X*/
#endif
pdir->fcluster = to_WORD((byte *) &pbuff->fcluster); /*X*/
pdir->fsize = to_DWORD((byte *) &pbuff->fsize); /*X*/
#else
pdir->ftime = pbuff->ftime; /*X*/
pdir->fdate = pbuff->fdate; /*X*/
#if (FAT32)
pdir->fclusterhi = pbuff->fclusterhi; /*X*/
#endif
pdir->fcluster = pbuff->fcluster; /*X*/
pdir->fsize = pbuff->fsize; /*X*/
#endif
}
/**************************************************************************
PC_INIT_INODE - Load an in memory inode up with user supplied values.
Description
Take an uninitialized inode (pdir) and fill in some fields. No other
processing is done. This routine simply copies the arguments into the
FINODE structure.
Note: filename & fileext do not need null termination.
Returns
Nothing
****************************************************************************/
#if (RTFS_WRITE)
/* Load an in memory inode up with user supplied values */
void pc_init_inode(FINODE *pdir, KS_CONSTANT char *filename, /*__fn__*/
KS_CONSTANT char *fileext, byte attr, /* FAT32 */ /*VFAT */
CLUSTERTYPE cluster, dword size, DATESTR *crdate) /*__fn__*/
{
/* Copy the file names and pad with ' ''s */
pc_cppad(pdir->fname,(byte*)filename,8);
pc_cppad(pdir->fext,(byte*)fileext,3);
pdir->fattribute = attr;
pc_memfill(&pdir->resarea[0],10, '\0');
pdir->ftime = crdate->time;
pdir->fdate = crdate->date;
#if (FAT32)
pdir->fclusterhi = (word)(cluster >> 16);
#endif
pdir->fcluster = (word) cluster;
pdir->fsize = size;
#if (VFAT)
pc_zeroseglist(&pdir->s);
#endif
}
#endif
#if (RTFS_WRITE)
/***************************************************************************
PC_INO2DOS - Convert an in memory inode to a dos disk entry.
Description
Take in memory native format inode information and copy it to a
buffer. Translate the inode to INTEL byte ordering during the transfer.
Returns
Nothing
***************************************************************************/
/* Un-Make a disk directory entry */
/* Convert an inmem inode to dos form. */
void pc_ino2dos (DOSINODE *pbuff, FINODE *pdir) /*__fn__*/
{
pc_strn2upper((char *)&pbuff->fname[0],(char *)&pdir->fname[0],8); /*X*/
pc_strn2upper((char *)&pbuff->fext[0],(char *)&pdir->fext[0],3); /*X*/
pbuff->fattribute = pdir->fattribute; /*X*/
#if (FAT32)
copybuff(&pbuff->resarea[0],&pdir->resarea[0], 8); /*X*/
#else
copybuff(&pbuff->resarea[0],&pdir->resarea[0], 10); /*X*/
#endif
#if (KS_LITTLE_ENDIAN)
pbuff->ftime = pdir->ftime;
pbuff->fdate = pdir->fdate;
pbuff->fcluster = pdir->fcluster;
#if (FAT32)
pbuff->fclusterhi = pdir->fclusterhi;
#endif
pbuff->fsize = pdir->fsize;
#else
fr_WORD((byte *) &pbuff->ftime,pdir->ftime); /*X*/
fr_WORD((byte *) &pbuff->fdate,pdir->fdate); /*X*/
fr_WORD((byte *) &pbuff->fcluster,pdir->fcluster); /*X*/
#if (FAT32)
fr_WORD((byte *) &pbuff->fclusterhi,pdir->fclusterhi); /*X*/
#endif
fr_DWORD((byte *) &pbuff->fsize,pdir->fsize); /*X*/
#endif
}
#endif
/**************************************************************************
PC_ISAVOL - Test a DROBJ to see if it is a volume
Description
Looks at the appropriate elements in pobj and determines if it is a root
or subdirectory.
Returns
Returns FALSE if the obj does not point to a directory.
****************************************************************************/
BOOLEAN pc_isavol( DROBJ *pobj) /*__fn__*/
{
if (pobj->finode->fattribute & AVOLUME)
return(TRUE);
else
return(FALSE);
}
/**************************************************************************
PC_ISADIR - Test a DROBJ to see if it is a root or subdirectory
Description
Looks at the appropriate elements in pobj and determines if it is a root
or subdirectory.
Returns
Returns FALSE if the obj does not point to a directory.
****************************************************************************/
BOOLEAN pc_isadir( DROBJ *pobj) /*__fn__*/
{
if ( (pobj->isroot) || (pobj->finode->fattribute & ADIRENT) )
return(TRUE);
else
return(FALSE);
}
/**************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -