📄 dosfsfat.c
字号:
bestStart = firstContig; }contig_alloc: if (fat16MarkAlloc (pFd, bestStart, number) != OK) goto contig_alloc_error; semGive (pFatDesc->allocSem); DBG_MSG (1, "Allocated %ld clusters starting from cluster %ld\n", number, bestStart,3,4,5,6); pFileHdl->startClust = bestStart; pFileHdl->contigEndPlus1 = bestStart + number; return OK;contig_alloc_error: semGive (pFatDesc->allocSem); return ERROR; } /* fat16ContigAlloc *//********************************************************************************* fat16MaxContigSectors - max free contiguous chain length in sectors* * RETURNS: size of the max contiguous free space in sectors*/ static size_t fat16MaxContigSectors ( FAST DOS_FILE_DESC_ID pFd /* pointer to file descriptor */ ) { uint32_t maxStart; return (fat16MaxContigClustersGet (pFd, &maxStart) * pFd->pVolDesc->secPerClust); } /* fat16MaxContigSectors *//********************************************************************************* fat16Show - display handler specific data** RETURNS: N/A.*/LOCAL void fat16Show ( DOS_VOLUME_DESC_ID pVolDesc /* pointer to volume descriptor */ ) { MS_FAT_DESC_ID pFatDesc = (MS_FAT_DESC_ID) pVolDesc->pFatDesc; DOS_FILE_DESC fileDesc = { 0 }; /* pointer to file descriptor */ fileDesc.pVolDesc = pVolDesc; printf ("FAT handler information:\n"); printf ("------------------------\n"); printf (" - allocation group size: %ld clusters\n", pFatDesc->fatGroupSize); print64Fine (" - free space on volume: ", fat16NFree (&fileDesc), " bytes\n", 10); } /* fat16Show *//********************************************************************************* fat16ClustValueSet - set value to a particular FAT entry** RETURNS: OK or ERROR*/STATUS fat16ClustValueSet ( DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ uint32_t copyNum, /* fat copy number */ uint32_t clustNum, /* cluster number to check */ uint32_t value, uint32_t nextClust ) { DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; MS_FAT_DESC_ID pFatDesc = (void *) pVolDesc->pFatDesc; switch (value) { case DOS_FAT_AVAIL: value = pFatDesc->dos_fat_avail; break; case DOS_FAT_EOF: value = pFatDesc->dos_fat_eof; break; case DOS_FAT_BAD: assert (FALSE); value = pFatDesc->dos_fat_bad; break; case DOS_FAT_RESERV: assert (FALSE); value = pFatDesc->dos_fat_reserv; break; case DOS_FAT_ALLOC: assert ((nextClust >= DOS_MIN_CLUST) && (nextClust < pFd->pVolDesc->nFatEnts)); value = nextClust; break; case DOS_FAT_RAW: value = nextClust; break; case DOS_FAT_SET_ALL: { CBIO_DEV_ID pCbio = pVolDesc->pCbio; cookie_t cookie = (cookie_t) NULL; uint8_t wBuf [64]; /* fill one sector (<value> = sector number) */ value = pFatDesc->fatStartSec + (copyNum * pVolDesc->secPerFat); bfill ((char *)wBuf, sizeof (wBuf), nextClust ); for ( clustNum = 0; clustNum < pFd->pVolDesc->bytesPerSec; clustNum += sizeof (wBuf) ) { if (cbioBytesRW (pCbio, value, clustNum, (addr_t)wBuf, sizeof (wBuf), CBIO_WRITE, &cookie) != OK) { return ERROR; } } /* copy first sector to other FAT sectors */ for ( nextClust = value++; value < nextClust + pVolDesc->secPerFat; value ++ ) { if (cbioBlkCopy (pCbio, nextClust, value, 1) != OK) return ERROR; } return (OK); } case DOS_FAT_INVAL: default: assert (FALSE); } return ENTRY_WRITE (pFd, copyNum, clustNum, value); } /* fat16ClustValueSet *//********************************************************************************* fat16ClustValueGet - get value corresponding to this cluster number in FAT** Get the value of a particular FAT entry, resulting in the* number of the next cluster in chain, or one of the following:** DOS_FAT_AVAIL - available cluster* DOS_FAT_EOF - end of file's cluster chain* DOS_FAT_BAD - bad cluster (damaged media)* DOS_FAT_ALLOC - allocated cluster* DOS_FAT_INVAL - invalid cluster (illegal value)* DOS_FAT_RESERV - reserved cluster** RETURNS: cluster number or special value above*/uint32_t fat16ClustValueGet ( DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ uint32_t copyNum, /* fat copy number */ uint32_t clustNum, /* cluster number to check */ uint32_t * pNextClust /* */ ) { MS_FAT_DESC_ID pFatDesc = (void *) pFd->pVolDesc->pFatDesc; clustNum &= 0x0fffffff; /* high 4 bits in FAT32 are reserved */ if (clustNum == 0) return DOS_FAT_AVAIL; if (clustNum > pFatDesc->dos_fat_bad) return DOS_FAT_EOF; if (clustNum == pFatDesc->dos_fat_bad) return DOS_FAT_BAD; if (clustNum >= pFatDesc->dos_fat_reserv) return DOS_FAT_RESERV; if ((clustNum < DOS_MIN_CLUST) || (clustNum >= pFd->pVolDesc->nFatEnts)) return DOS_FAT_INVAL; *pNextClust = ENTRY_READ (pFd, copyNum, clustNum); if (pFd->fatHdl.errCode == FAT_CBIO_ERR) return DOS_FAT_ERROR; return DOS_FAT_ALLOC; } /* fat16ClustValueGet *//********************************************************************************* fat16VolUnmount - unmount volume** This routine frees all resources, that were allocated for the volume.** RETURNS: N/A*/LOCAL void fat16VolUnmount ( DOS_VOLUME_DESC_ID pVolDesc /* */ ) { return; } /* fat16VolUnmount *//********************************************************************************* fat16VolMount - mount volume** Initialize a new volume** RETURNS: ERROR if FAT is illegal*/STATUS fat16VolMount ( DOS_VOLUME_DESC_ID pVolDesc, /* */ void * arg /* unused */ ) { FAST CBIO_DEV_ID pCbio = pVolDesc->pCbio; /* pointer to CBIO device */ MS_FAT_DESC_ID pFat16Desc; DOS_FILE_DESC fileDesc = { 0 }; /* file descriptor */ uint8_t fsinfoBuf [8]; /* FSINFO sector data */ /* * if previous volume had alternative FAT structure, * unmount previous FAT handler and * allocate FAT handler descriptor */ if (pVolDesc->pFatDesc != NULL && pVolDesc->pFatDesc->volUnmount != fat16VolUnmount && pVolDesc->pFatDesc->volUnmount != NULL) { /* Unmount previous FAT handler */ pVolDesc->pFatDesc->volUnmount( pVolDesc ); } /* Allocate FAT handler descriptor */ pVolDesc->pFatDesc = KHEAP_REALLOC((char *)pVolDesc->pFatDesc, sizeof( *pFat16Desc)); if (pVolDesc->pFatDesc == NULL) return ERROR; pFat16Desc = (void *)pVolDesc->pFatDesc; bzero( (void *)pFat16Desc, sizeof( *pFat16Desc) ); fileDesc.pVolDesc = pVolDesc; /* for fat16NFree() */ /* Number of FAT entries = count of clusters available for files + 2 */ pVolDesc->nFatEnts = pFat16Desc->nFatEnts = ( ((pVolDesc->totalSec - pVolDesc->dataStartSec) / pVolDesc->secPerClust) + DOS_MIN_CLUST ); if (pVolDesc->fatType == FAT32) { /* activeFatStart ??? */ if (cbioBytesRW (pCbio, FSINFO_SEC_NUM, FSINFO_FREE_CLUSTS, (addr_t)fsinfoBuf, sizeof (fsinfoBuf), CBIO_READ, NULL) != OK) goto mount_error; /* Fill free FAT entries count */ pFat16Desc->fatEntFreeCnt = DISK_TO_VX_32 (&fsinfoBuf[0]); /* Fill start cluster for cluster groups allocation */ pFat16Desc->groupAllocStart = DISK_TO_VX_32 (&fsinfoBuf[4]); if ( (pFat16Desc->groupAllocStart < DOS_MIN_CLUST) || (pFat16Desc->groupAllocStart >= pFat16Desc->nFatEnts) ) pFat16Desc->groupAllocStart = DOS_MIN_CLUST; pFat16Desc->entryRead = fat32EntRead; pFat16Desc->entryWrite = fat32EntWrite; pFat16Desc->dos_fat_reserv = 0x0ffffff0; pFat16Desc->dos_fat_bad = 0x0ffffff7; pFat16Desc->dos_fat_eof = 0x0fffffff; } else { /* activeFatStart ??? */ /* -1 in fatEntFreeCnt cause fat16NFree() to fill this field */ pFat16Desc->fatEntFreeCnt = -1; /* Fill cluster groups allocation start cluster */ pFat16Desc->groupAllocStart = DOS_MIN_CLUST; if (pVolDesc->fatType == FAT16) { pFat16Desc->entryRead = fat16EntRead; pFat16Desc->entryWrite = fat16EntWrite; pFat16Desc->dos_fat_reserv = 0xfff0; pFat16Desc->dos_fat_bad = 0xfff7; pFat16Desc->dos_fat_eof = 0xffff; } else if (pVolDesc->fatType == FAT12) { pFat16Desc->entryRead = fat12EntRead; pFat16Desc->entryWrite = fat12EntWrite; pFat16Desc->dos_fat_reserv = 0xff0; pFat16Desc->dos_fat_bad = 0xff7; pFat16Desc->dos_fat_eof = 0xfff; } else goto mount_error; } pFat16Desc->dosFatDesc.volUnmount = fat16VolUnmount; pFat16Desc->dosFatDesc.getNext = fat16GetNext; pFat16Desc->dosFatDesc.contigChk = fat16ContigChk; pFat16Desc->dosFatDesc.show = fat16Show; pFat16Desc->dosFatDesc.truncate = fat16Truncate; /*FIOTRUNC*/ pFat16Desc->dosFatDesc.seek = fat16Seek; /*FIOSEEK*/ pFat16Desc->dosFatDesc.contigAlloc = fat16ContigAlloc;/*FIOCONTIG*/ pFat16Desc->dosFatDesc.maxContig = fat16MaxContigSectors; /*FIONCONTIG*/ pFat16Desc->dosFatDesc.nFree = fat16NFree; /*FIONFREE*/ pFat16Desc->dosFatDesc.flush = fat16MirrorSect; /*FIOFLUSH*/ pFat16Desc->dosFatDesc.syncToggle = fat16SyncToggle; pFat16Desc->dosFatDesc.clustValueSet = fat16ClustValueSet; pFat16Desc->dosFatDesc.clustValueGet = fat16ClustValueGet; pFat16Desc->fatStartSec = pVolDesc->nReservedSecs; /* current version uses only fat copy 0 as active */ pFat16Desc->dosFatDesc.activeCopyNum = 0; /* Number of clusters in allocation group = ??? * must be calculated in future */ pFat16Desc->fatGroupSize = pFat16Desc->nFatEnts / fatClugFac + 1; pFat16Desc->dos_fat_avail = 0x00000000; pFat16Desc->syncEnabled = TRUE; /* enable FAT copies mirroring */ pFat16Desc->allocSem = semMCreate (ALLOC_SEM_OPTIONS); if (NULL == pFat16Desc->allocSem) { goto mount_error; } pFat16Desc->clustAllocStart = DOS_MIN_CLUST; fat16NFree (&fileDesc); /* fill 'fatEntFreeCnt' if it equals -1 */ return OK;mount_error: fat16VolUnmount (pVolDesc); return ERROR; } /* fat16VolMount *//******************************************************************************* dosFsFatInit - init handler and install it into dosFsLib** This function must be called to install the FAT handler,* which is mandatory, once during system initialization.** RETURNS: OK or ERROR if failed to install*/STATUS dosFsFatInit ( void ) { DOS_HDLR_DESC hdlr; hdlr.id = DOS_FATALL_HDLR_ID; hdlr.mountRtn = fat16VolMount; hdlr.arg = NULL; return dosFsHdlrInstall (dosFatHdlrsList, &hdlr); } /* dosFsFatInit() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -