📄 apiutil.c
字号:
}
PC_DRIVE_IO_EXIT(driveno)
/* FSINFO
Set to 0 when the free clusters count is unknown.
Set to 1 when the free clusters count is known. */
pdr->valid_fsinfo = 0;
/* Check the signature of the file system information sector.*/
if ( (b[0] == 'R') && (b[1] == 'R') && (b[2] == 'a') && (b[3] == 'A') &&
(b[0x1e4] == 'r') && (b[0x1e5] == 'r') && (b[0x1e6] == 'A') && (b[0x1e7] == 'a') )
{
/* The count of free clusters on the drive.
Note: Set to -1(0xffffffff) when the count is unknown. */
SWAP32((UINT32 *)&pdr->free_clusters_count,(UINT32 *)&b[0x1e8]);
if (pdr->free_clusters_count == (UINT32)0xffffffff)
pdr->free_clusters_count = 0L;
else
pdr->valid_fsinfo = 1;
/* The cluster number of the cluster that was most recently allocated. */
SWAP32((UINT32 *)&pdr->free_contig_pointer,(UINT32 *)&b[0x1ec]);
}
else
{
pdr->free_clusters_count = 0L;
pdr->free_contig_pointer = 2L;
}
}
/* Calculate the largest index in the file allocation table.
Total # block in the cluster area)/Blockpercluster =='s total
Number of clusters. Entries 0 & 1 are reserved so the highest
valid fat index is 1 + total # clusters.
Note: Max cluster number = Number of clusters + 1 */
pdr->maxfindex = (UINT32)
(1 + (pdr->numsecs - pdr->firstclblock)/pdr->secpalloc);
/* Check the number of next free cluster */
if (pdr->free_contig_pointer > pdr->maxfindex)
pdr->free_contig_pointer = 2L;
if (pdr->fasize == 3)
{
if (pdr->maxfindex > 0x0ff6L)
{
pdr->opencount = 0;
return(NUF_FORMAT);
}
}
else if (pdr->fasize == 4)
{
if (pdr->maxfindex > 0xfff6L)
{
pdr->opencount = 0;
return(NUF_FORMAT);
}
}
else /* FAT32 */
{
if (pdr->maxfindex > 0x0ffffff6L)
{
pdr->opencount = 0;
return(NUF_FORMAT);
}
}
if (NUF_Drive_Fat_Size[driveno] < min_needed)
{
pc_report_error(PCERR_FATCORE);
pdr->opencount = 0;
return(NUF_FATCORE);
}
if (NUF_Drive_Fat_Size[driveno] > (INT)pdr->secpfat)
{
NUF_Drive_Fat_Size[driveno] = (INT)pdr->secpfat;
}
/* Allocate FAT cache buffer */
pdr->fat_swap_structure.data_array =
(UINT8 FAR *)NUF_Alloc(NUF_Drive_Fat_Size[driveno] << 9 );
if (!pdr->fat_swap_structure.data_array)
{
pdr->opencount = 0;
return(NUF_NO_MEMORY);
}
/* Remember how many blocks we alloced */
pdr->fat_swap_structure.n_blocks_total = (UINT16)NUF_Drive_Fat_Size[driveno];
if (NUF_Drive_Fat_Size[driveno] == (INT)pdr->secpfat)
pdr->use_fatbuf = 0;
else
pdr->use_fatbuf = 1;
#ifdef DEBUG0
DEBUG_PRINT ("Oem NAME %8s\n",pdr->oemname);
DEBUG_PRINT ("Bytspsec %d\n",pdr->bytspsector);
DEBUG_PRINT ("secpallc %d\n",pdr->secpalloc);
DEBUG_PRINT ("secres %d\n",pdr->fatblock);
DEBUG_PRINT ("numfat %d\n",pdr->numfats);
DEBUG_PRINT ("numrot %d\n",pdr->numroot);
DEBUG_PRINT ("numsec %d\n",pdr->numsecs);
DEBUG_PRINT ("mediac %d\n",pdr->mediadesc);
DEBUG_PRINT ("secfat %d\n",pdr->secpfat);
DEBUG_PRINT ("sectrk %d\n",pdr->secptrk);
DEBUG_PRINT ("numhed %d\n",pdr->numhead);
DEBUG_PRINT ("numhide %d\n",pdr->numhide);
#endif
/* Clear the current working directory */
fs_user->lcwd[driveno] = NULL;
pdr->bytespcluster = (UINT16) (512 * pdr->secpalloc);
/* bits to mask in to calculate byte offset in cluster from file pointer.
AND file pointer with this to get byte offset in cluster a shift right
9 to get block offset in cluster */
pdr->byte_into_cl_mask = (UINT32) pdr->bytespcluster;
pdr->byte_into_cl_mask -= 1L;
/* save away log of sectors per alloc */
pdr->log2_secpalloc = pc_log_base_2((UINT16)pdr->secpalloc);
/* Number of maximum file clusters */
pdr->maxfsize_cluster = MAXFILE_SIZE >> pdr->log2_secpalloc;
/* Initialize the fat management code */
/* Set driveno now becuse the drive structure is valid */
pdr->driveno = driveno;
if (pdr->use_fatbuf)
{
/* Swap in item 0. (ie read the first page of the FAT) */
ret_stat = pc_pfswap(&pdata, pdr, (UINT32)0, NO);
if (ret_stat != NU_SUCCESS)
{
pc_report_error(PCERR_FATREAD);
NU_Deallocate_Memory((VOID *)pdr->fat_swap_structure.data_array);
pdr->opencount = 0;
return(ret_stat);
}
}
else
{
/* No fat swapping. We use drive.fat_swap_structure elements
to implement an in memory caching scheme. data_map[255] is used
to indicate which blocks are dirty and data_array points to
the buffer to hold the in memory fat */
ltemp = pdr->secpfat;
pdata = pdr->fat_swap_structure.data_array;
fatoffset = pdr->fatblock;
while (ltemp)
{
if (ltemp > MAXSECTORS)
nblocks = MAXSECTORS;
else
nblocks = (UINT16) ltemp;
/* The dirty blocks table data_map[255] was zeroed when we zeroed
the drive structure */
/* Now read the fat */
PC_DRIVE_IO_ENTER(driveno)
if ( !pc_bdevsw[driveno].io_proc(driveno, (UINT32)fatoffset, pdata, nblocks, YES) )
{
PC_DRIVE_IO_EXIT(driveno)
pc_report_error(PCERR_FATREAD);
NU_Deallocate_Memory((VOID *)pdr->fat_swap_structure.data_array);
pdr->opencount = 0;
return(NUF_IO_ERROR);
}
PC_DRIVE_IO_EXIT(driveno)
ltemp -= nblocks;
fatoffset += nblocks;
pdata += (nblocks << 9);
}
}
return(NU_SUCCESS);
}
/************************************************************************
* FUNCTION
*
* pc_idskclose
*
* DESCRIPTION
*
* Given a valid drive number. Flush the file allocation table and
* purge any buffers or objects associated with the drive.
*
* AUTHOR
*
* Kyoichiro Toda
*
* INPUTS
*
* driveno Drive number
*
* OUTPUTS
*
* NU_SUCCESS Unmount successful.
* NUF_BADDRIVE Invalid drive specified.
* NUF_IO_ERROR Driver returned error.
* NUF_INTERNAL Nucleus FILE internal error.
*
*************************************************************************/
STATUS pc_idskclose(INT16 driveno)
{
DDRIVE *pdr;
STATUS ret_val;
UINT8 b[512];
UINT32 fstemp;
INT i;
UINT16 signature;
pdr = pc_drno2dr(driveno);
/* Check drive number */
if (pdr)
{
PC_FAT_ENTER(driveno)
ret_val = pc_flushfat(pdr);
PC_FAT_EXIT(driveno)
if (ret_val == NU_SUCCESS)
{
if (pdr->fasize == 8)
{
/* Build up a Partition FSINFO(File System INFOrmation)
Note: PBR include a BIOS Parameter Block(BPB) */
pc_memfill(&b[0], 512, '\0');
/* FSI signature offset 0 */
pc_cppad(&b[0], (UINT8 *)"RRaA", 4);
/* FSI signature offset 0x1E0 */
pc_cppad(&b[0x1e4], (UINT8 *)"rrAa", 4);
if (!pdr->valid_fsinfo) /* Set the free cluster count. */
pdr->free_clusters_count = pc_ifree(driveno);
SWAP32((UINT32 *)&(b[0x1e8]), (UINT32 *)&pdr->free_clusters_count);
SWAP32((UINT32 *)&(b[0x1ec]), (UINT32 *)&pdr->free_contig_pointer);
/* Signature word */
signature = 0xAA55;
SWAP16((UINT16 *)&(b[0x1fe]), (UINT16 *)&signature);
/* Update FSINFO */
fstemp = (UINT32) pdr->fsinfo;
for (i = 0; i < 2; i++)
{
if ( !pc_bdevsw[driveno].io_proc(driveno, fstemp, &(b[0]), (UINT16) 1, NO) )
{
pc_report_error(PCERR_FMTWBZERO);
ret_val = NUF_IO_ERROR;
break;
}
fstemp += 6;
}
}
if (ret_val == NU_SUCCESS)
{
/* Release the drive if opencount == 0 */
ret_val = pc_dskfree(driveno, NO);
}
}
}
else
{
ret_val = NUF_NOT_OPENED;
}
return(ret_val);
}
/************************************************************************
* FUNCTION
*
* pc_fd2file
*
* DESCRIPTION
*
* Map a file descriptor to a file structure. Return null if the
* file is not open. If an error has occured on the file return
* NULL unless allow_err is true.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* fd File descriptor
*
* OUTPUTS
*
* File representation.丂
* NULL Invalid FD.
*
*************************************************************************/
PC_FILE *pc_fd2file(INT fd)
{
PC_FILE *pfile;
/* Is this descriptor value in correct range ? */
if (0 <= fd && fd <= NUSERFILES)
{
/* Get PFILE memory pool pointer */
pfile = mem_file_pool+fd;
if (pfile && !pfile->is_free)
{
return(pfile);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -