📄 drobj.c
字号:
*
* Takahiro Takahashi
*
* INPUTS
*
* **pobj Create file's DROBJ pointer
* *pmom Drive object
* *filename Create file name
* *fileext Create file extension
* attributes Create file attributes
*
*
* OUTPUTS
*
* NU_SUCCESS If service is successful.
* NUF_ROOT_FULL Root directry full.
* NUF_INVNAME Path or filename includes
* invalid character.
* NUF_NOSPC No space to create directory
* in this disk.
* NUF_NO_BLOCK No block buffer available.
* NUF_NO_FINODE No FINODE buffer available.
* NUF_NO_DROBJ No DROBJ buffer available.
* NUF_IO_ERROR Driver IO error.
* NUF_INTERNAL Nucleus FILE internal error.
*
*************************************************************************/
STATUS pc_mknode(DROBJ **pobj, DROBJ *pmom, UINT8 *filename,
UINT8 *fileext, UINT8 attributes)
{
STATUS ret_stat;
DOSINODE *pdinodes;
FINODE lfinode;
UINT32 cluster;
DATESTR crdate;
BLKBUFF *pbuff;
DDRIVE *pdrive;
DROBJ *psobj;
UINT8 attr;
UINT8 fname[9];
UINT8 fext[4];
UINT8 shortname[13];
INT longfile;
STATUS status;
*pobj = NULL;
pdrive = pmom->pdrive;
ret_stat = NU_SUCCESS;
if (attributes & ADIRENT)
{
/*Grab a cluster for a new dir and cleaer it */
PC_FAT_ENTER(pdrive->driveno)
ret_stat = pc_clalloc(&cluster, pdrive);
#ifdef DEBUG1
DEBUG_PRINT("pc_mknode allocate directory cluster number %d\r\n", cluster);
#endif
PC_FAT_EXIT(pdrive->driveno)
if (ret_stat == NU_SUCCESS)
{
ret_stat = pc_clzero(pdrive, cluster);
if (ret_stat != NU_SUCCESS)
{
PC_FAT_ENTER(pdrive->driveno)
pc_clrelease(pdrive, cluster);
PC_FAT_EXIT(pdrive->driveno)
}
}
}
else
cluster = 0L;
if (ret_stat != NU_SUCCESS)
{
return(ret_stat);
}
/* For a subdirectory. First make it a simple file. We will change the
attribute after all is clean */
attr = attributes;
if (attr & ADIRENT)
attr = ANORMAL;
/* Allocate an empty DROBJ and FINODE to hold the new file */
*pobj = pc_allocobj();
if (!(*pobj))
{
if (cluster)
{
PC_FAT_ENTER(pdrive->driveno)
pc_clrelease(pdrive, cluster);
PC_FAT_EXIT(pdrive->driveno)
}
return(NUF_NO_DROBJ);
}
/* Take a short file name and extension. */
longfile = pc_fileparse(fname, fext, filename, fileext);
if (longfile < 0)
{
ret_stat = (STATUS)longfile;
}
else
{
/* Upperbar short file name ? */
while( (longfile == FUSE_UPBAR) && (ret_stat == NU_SUCCESS) )
{
/* Search the short file name */
pc_cre_shortname((UINT8 *)shortname, fname, fext);
psobj = NULL;
ret_stat = pc_get_inode(&psobj, pmom, (UINT8 *)shortname);
/* File not found. We can use this short filename. */
if (ret_stat == NUF_NOFILE)
{
ret_stat = NU_SUCCESS;
break;
}
else if (ret_stat == NU_SUCCESS)
{
/* Free the short filename object */
pc_freeobj(psobj);
/* Get the next short filename */
pc_next_fparse(fname);
}
}
}
if (ret_stat != NU_SUCCESS)
{
pc_freeobj(*pobj);
if (cluster)
{
PC_FAT_ENTER(pdrive->driveno) /* claim the fat for alloc */
pc_clrelease(pdrive, cluster);
PC_FAT_EXIT(pdrive->driveno)
}
return(ret_stat);
}
/* Load the inode copy name,ext,attr,cluster, size,datetime*/
pc_init_inode( (*pobj)->finode, fname, fext,
attr, cluster, /*size*/ 0L, pc_getsysdate(&crdate) );
/* Convert pobj to native and stitch it in to mom */
ret_stat = pc_insert_inode(*pobj, pmom, filename, longfile);
if (ret_stat != NU_SUCCESS)
{
/* Root directory entry full or Disk full ? */
if ( (ret_stat == NUF_ROOT_FULL) || (ret_stat == NUF_NOSPC) )
{
/* Try again */
ret_stat = pc_insert_inode(*pobj, pmom, filename, longfile);
if (ret_stat != NU_SUCCESS)
{
pc_freeobj(*pobj);
if (cluster)
{
PC_FAT_ENTER(pdrive->driveno)
pc_clrelease(pdrive, cluster);
PC_FAT_EXIT(pdrive->driveno)
}
return(ret_stat);
}
}
else
{
pc_freeobj(*pobj);
if (cluster)
{
PC_FAT_ENTER(pdrive->driveno)
pc_clrelease(pdrive, cluster);
PC_FAT_EXIT(pdrive->driveno)
}
return(ret_stat);
}
}
/* Now if we are creating subdirectory we have to make the DOT and DOT DOT
inodes and then change pobj's attribute to ADIRENT
The DOT and DOTDOT are not buffered inodes. We are simply putting
the to disk */
if (attributes & ADIRENT)
{
/* Set up a buffer to do surgery */
status = pc_alloc_blk(&pbuff, pdrive, pc_cl2sector(pdrive, cluster));
if (status < 0)
{
pc_freeobj(*pobj);
PC_FAT_ENTER(pdrive->driveno) /* claim the fat for alloc */
pc_clrelease(pdrive, cluster);
PC_FAT_EXIT(pdrive->driveno)
return((STATUS)status);
}
pc_memfill(pbuff->data, 512, '\0');
pdinodes = (DOSINODE *) &pbuff->data[0];
/* Load DOT and DOTDOT in native form */
/* DOT first. It points to the begining of this sector */
pc_init_inode(&lfinode, (UINT8 *)".", (UINT8 *)"", ADIRENT, cluster, /*size*/ 0L, &crdate);
/* And to the buffer in intel form */
pc_ino2dos (pdinodes, &lfinode);
/* Now DOTDOT points to mom's cluster */
if (pmom->isroot)
{
pc_init_inode(&lfinode, (UINT8 *)"..", (UINT8 *)"", ADIRENT, 0L, /*size*/ 0L, &crdate);
}
else
{
pc_init_inode(&lfinode, (UINT8 *)"..", (UINT8 *)"", ADIRENT,
pc_sec2cluster(pdrive, (*pobj)->blkinfo.my_frstblock),
/*size*/ 0L, &crdate);
}
/* And to the buffer in intel form */
pc_ino2dos (++pdinodes, &lfinode);
/* Write the cluster out */
ret_stat = pc_write_blk(pbuff);
if (ret_stat != NU_SUCCESS)
{
pc_free_buf(pbuff, YES); /* Error. Chuck the buffer */
pc_freeobj(*pobj);
PC_FAT_ENTER(pdrive->driveno) /* claim the fat for alloc */
pc_clrelease(pdrive, cluster);
PC_FAT_EXIT(pdrive->driveno)
return(ret_stat);
}
else
pc_free_buf(pbuff, NO);
/* And write the node out with the original attributes */
(*pobj)->finode->fattribute = attributes;
/* Convert to native and overwrite the existing inode*/
ret_stat = pc_update_inode(*pobj, DSET_CREATE);
if (ret_stat != NU_SUCCESS)
{
pc_freeobj(*pobj);
PC_FAT_ENTER(pdrive->driveno) /* claim the fat for alloc */
pc_clrelease(pdrive, cluster);
PC_FAT_EXIT(pdrive->driveno)
return(ret_stat);
}
}
PC_FAT_ENTER(pdrive->driveno)
ret_stat = pc_flushfat(pdrive);
PC_FAT_EXIT(pdrive->driveno)
if (ret_stat != NU_SUCCESS)
{
pc_freeobj(*pobj);
PC_FAT_ENTER(pdrive->driveno) /* claim the fat for alloc */
pc_clrelease(pdrive, cluster);
PC_FAT_EXIT(pdrive->driveno)
}
return(ret_stat);
}
/************************************************************************
* FUNCTION
*
* pc_insert_inode
*
* DESCRIPTION
*
* Take mom , a fully defined DROBJ, and pobj, a DROBJ with a
* finode containing name, ext, etc, but not yet stitched into the
* inode buffer pool, and fill in pobj and its inode, write it to
* disk and make the inode visible in the inode buffer pool.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* *pobj Create file's DROBJ
* *pmom Drive object
* *filename Create file name
* longfile If 1, long file name is
* given.
*
* OUTPUTS
*
* NU_SUCCESS If service is successful.
* NUF_ROOT_FULL Root directry full.
* NUF_NOSPC No space to create directory
* in this disk.
* NUF_NO_BLOCK No block buffer available.
* NUF_IO_ERROR Driver IO error.
* NUF_INTERNAL Nucleus FILE internal error.
*
**********************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -