?? volume.c
字號:
}
pbpb = &pbgbs->bgbsBPB;
// Preliminary FAT32 detection: if FAT32 support is disabled, then ALWAYS
// set VOLF_INVALID; otherwise, do it only if there is a version mismatch.
if (!(pvol->v_flags & VOLF_INVALID) && pbpb->oldBPB.BPB_SectorsPerFAT == 0) {
#ifdef FAT32
if (pbpb->BGBPB_FS_Version > FAT32_Curr_FS_Version) {
RETAILMSG(TRUE,(TEXT("FATFS!InitVolume: FAT32 volume version unsupported (%d > %d)\r\n"),
pbpb->BGBPB_FS_Version, FAT32_Curr_FS_Version));
#else
RETAILMSG(TRUE,(TEXT("FATFS!InitVolume: FAT32 volumes not supported in this build\r\n")));
#endif
pvol->v_flags |= VOLF_INVALID;
#ifdef FAT32
}
if (!(pvol->v_flags & VOLF_INVALID)) {
pvol->v_flags |= VOLF_32BIT_FAT;
pvol->v_secFSInfo = pbpb->BGBPB_FSInfoSec;
}
#endif
}
if (pvol->v_flags & VOLF_INVALID) {
memset(&pvol->v_bMediaDesc, 0, offsetof(VOLUME, v_pstmFAT) - offsetof(VOLUME, v_bMediaDesc));
memset(&pstmFAT->s_runList, 0, sizeof(pstmFAT->s_runList));
memset(&pstmRoot->s_runList, 0, sizeof(pstmRoot->s_runList));
goto exit;
}
// Now compute volume dimensions, etc, from BPB data
pvol->v_bMediaDesc = pbpb->oldBPB.BPB_MediaDescriptor;
// 當bootsector中 fat表的個數大于1的時候,將volume的標記位設置為pvol->v_flags |= VOLF_BACKUP_FAT
if (pbpb->oldBPB.BPB_NumberOfFATs > 1)
pvol->v_flags |= VOLF_BACKUP_FAT;
// Compute sector bias for volume (for sector-based I/O)
pvol->v_secVolBias = pbpb->oldBPB.BPB_HiddenSectors;
// Compute sector bias for block 0 (for block-based I/O only)
// 計算fat表的起始位置,以sector為單位
pvol->v_secBlkBias = pbpb->oldBPB.BPB_HiddenSectors + pbpb->oldBPB.BPB_ReservedSectors;
// Compute how many sectors are on the volume
pvol->v_csecTotal = pbpb->oldBPB.BPB_TotalSectors;
if (pvol->v_csecTotal == 0)
pvol->v_csecTotal = pbpb->oldBPB.BPB_BigTotalSectors;
if (pvol->v_csecTotal <= pbpb->oldBPB.BPB_ReservedSectors) {
DEBUGMSGBREAK(ZONE_INIT || ZONE_ERRORS,
(DBGTEXT("FATFS!InitVolume: total sectors (%d) is incorrect, adjusting to match driver\n"), pvol->v_csecTotal));
pvol->v_csecTotal = pvol->v_pdsk->d_diActive.di_total_sectors - pvol->v_secBlkBias;
}
else
pvol->v_csecTotal -= pbpb->oldBPB.BPB_ReservedSectors;
#ifdef DEBUG
if (!(pvol->v_pdsk->d_diActive.di_flags & DISK_INFO_FLAG_CHS_UNCERTAIN) &&
(pvol->v_pdsk->d_diActive.di_heads != pbpb->oldBPB.BPB_Heads ||
pvol->v_pdsk->d_diActive.di_sectors != pbpb->oldBPB.BPB_SectorsPerTrack)) {
DEBUGMSG(ZONE_INIT || ZONE_ERRORS,
(DBGTEXT("FATFS!InitVolume: driver disagrees with BPB (BPB CHS=%d:%d:%d)\r\n"),
(pvol->v_csecTotal + pvol->v_secBlkBias) / (pbpb->oldBPB.BPB_Heads * pbpb->oldBPB.BPB_SectorsPerTrack),
pbpb->oldBPB.BPB_Heads,
pbpb->oldBPB.BPB_SectorsPerTrack));
}
#endif
// We've seen cases where the driver thinks there are fewer sectors on
// the disk than the BPB does, which means that any I/O near the end of
// the volume will probably fail. So for now, we'll try to catch these
// cases, report them, and then adjust our values to agree with the driver.
if (pvol->v_pdsk->d_diActive.di_total_sectors < pvol->v_csecTotal + pvol->v_secBlkBias) {
DEBUGMSG(ZONE_INIT || ZONE_ERRORS,
(DBGTEXT("FATFS!InitVolume: driver reports fewer sectors than BPB! (%d vs. %d)\r\n"),
pvol->v_pdsk->d_diActive.di_total_sectors, pvol->v_csecTotal + pvol->v_secBlkBias));
pvol->v_csecTotal = pvol->v_pdsk->d_diActive.di_total_sectors - pvol->v_secBlkBias;
}
// For now, force block size to equal sector size.
pvol->v_log2csecClus = Log2(pbpb->oldBPB.BPB_SectorsPerCluster);
pvol->v_log2cbSec = Log2(pbpb->oldBPB.BPB_BytesPerSector);
pvol->v_cbBlk = pbpb->oldBPB.BPB_BytesPerSector;
pvol->v_log2cbBlk = pvol->v_log2cbSec;
// 此處直接設置為0
pvol->v_log2cblkSec = 0;
pvol->v_log2cblkClus = pvol->v_log2cblkSec + pvol->v_log2csecClus;
pvol->v_cbClus = 1 << (pvol->v_log2cbSec + pvol->v_log2csecClus);
#ifdef FAT32
if (pbpb->oldBPB.BPB_SectorsPerFAT == 0) {
// 卷的ID號直接從BPB相應單元中讀出
pvol->v_serialID = pbgbs->bgbsVolumeID;
memcpy(pvol->v_label, pbgbs->bgbsVolumeLabel, sizeof(pbgbs->bgbsVolumeLabel));
// 直接從磁盤讀出的值
pvol->v_csecFAT = pbpb->BGBPB_BigSectorsPerFAT;
// Set up the FAT DSTREAM structure
pvol->v_secEndFAT = pbpb->BGBPB_BigSectorsPerFAT * (pbpb->BGBPB_ExtFlags & BGBPB_F_ActiveFATMsk);
pvol->v_secEndAllFATs = pbpb->BGBPB_BigSectorsPerFAT * pbpb->oldBPB.BPB_NumberOfFATs;
// pstmFAT用來存放全部的fat表
pstmFAT->s_size = pbpb->BGBPB_BigSectorsPerFAT << pvol->v_log2cbSec;
// 設置pstmFAT對應run的長度
SetRunSize (&pstmFAT->s_runList, pstmFAT->s_size);
// 設置pstmFAT對應run的開始扇區號
SetRunStartBlock(&pstmFAT->s_runList, pvol->v_secEndFAT << pvol->v_log2cblkSec);
pvol->v_secEndFAT += pbpb->BGBPB_BigSectorsPerFAT;
// Set up the root directory DSTREAM structure
// 設置pstmRoot的長度和開始簇號
pstmRoot->s_size = MAX_DIRSIZE;
pstmRoot->s_clusFirst = pbpb->BGBPB_RootDirStrtClus;
ResetRunList(&pstmRoot->s_runList, pstmRoot->s_clusFirst);
pvol->v_csecUsed = pvol->v_secEndAllFATs;
// Compute block bias for cluster 0. The first data cluster is 2.
pvol->v_blkClusBias = (pvol->v_csecUsed << pvol->v_log2cblkSec) -
(DATA_CLUSTER << pvol->v_log2cblkClus);
// Set the maximum cluster # supported for this volume; it is the
// smaller of 1) total clusters on the media and 2) total cluster entries
// the FAT can contain.
cmaxClus = pstmFAT->s_size/sizeof(DWORD) - DATA_CLUSTER;
pvol->v_clusMax = ((pvol->v_csecTotal - pvol->v_csecUsed) >> pvol->v_log2csecClus);
if (pvol->v_clusMax > cmaxClus) {
DEBUGMSGBREAK(ZONE_INIT || ZONE_ERRORS,
(DBGTEXT("FATFS!InitVolume: total clusters (%d) exceeds FAT32 size (%d), reducing...\r\n"), pvol->v_clusMax, cmaxClus));
pvol->v_clusMax = cmaxClus;
}
pvol->v_clusMax++; // now convert total clusters to max cluster #
// 下面這三行什么意思
pvol->v_unpack = Unpack32;
pvol->v_pack = Pack32;
pvol->v_clusEOF = FAT32_EOF_MIN;
} else
#endif // FAT32
{
// 16-bit or 12-bit FAT volume
PBOOTSEC pbs = (PBOOTSEC)pbgbs;
pvol->v_serialID = pbs->bsVolumeID;
memcpy(pvol->v_label, pbs->bsVolumeLabel, sizeof(pbs->bsVolumeLabel));
pvol->v_csecFAT = pbpb->oldBPB.BPB_SectorsPerFAT;
// Set up the FAT DSTREAM structure; always assume that the first FAT
// is the active one
pvol->v_secEndFAT = pbpb->oldBPB.BPB_SectorsPerFAT;
pvol->v_secEndAllFATs = pbpb->oldBPB.BPB_SectorsPerFAT * pbpb->oldBPB.BPB_NumberOfFATs;
pstmFAT->s_size = pbpb->oldBPB.BPB_SectorsPerFAT << pvol->v_log2cbSec;
SetRunSize (&pstmFAT->s_runList, pstmFAT->s_size);
SetRunStartBlock(&pstmFAT->s_runList, 0);
// Set up the root directory DSTREAM structure
pstmRoot->s_size = pbpb->oldBPB.BPB_RootEntries * sizeof(DIRENTRY);
pstmRoot->s_clusFirst = ROOT_PSEUDO_CLUSTER;
SetRunSize (&pstmRoot->s_runList, pstmRoot->s_size);
SetRunStartBlock(&pstmRoot->s_runList, pvol->v_secEndAllFATs << pvol->v_log2cblkSec);
pvol->v_csecUsed = pvol->v_secEndAllFATs + ((pstmRoot->s_size + pbpb->oldBPB.BPB_BytesPerSector-1) >> pvol->v_log2cbSec);
// Compute block bias for cluster 0. The first data cluster is 2.
pvol->v_blkClusBias = (pvol->v_csecUsed << pvol->v_log2cblkSec) -
(DATA_CLUSTER << pvol->v_log2cblkClus);
// clusMax is temporarily the total # of clusters, and cmaxClus is
// temporarily the total number of BITS contained in the FAT (we'll divide
// that by 12 or 16 as appropriate, and then use it to make sure clusMax is valid).
pvol->v_clusMax = (pvol->v_csecTotal - pvol->v_csecUsed) >> pvol->v_log2csecClus;
cmaxClus = pvol->v_csecFAT << (pvol->v_log2cbSec+3); // add 3 to get # bits instead of # bytes
if (pvol->v_clusMax >= FAT1216_THRESHOLD) {
cmaxClus /= 16;
pvol->v_flags |= VOLF_16BIT_FAT;
pvol->v_unpack = Unpack16;
pvol->v_pack = Pack16;
pvol->v_clusEOF = FAT16_EOF_MIN;
} else {
cmaxClus /= 12;
pvol->v_flags |= VOLF_12BIT_FAT;
pvol->v_unpack = Unpack12;
pvol->v_pack = Pack12;
pvol->v_clusEOF = (pvol->v_clusMax < FAT12_EOF_SPECIAL-1)? FAT12_EOF_SPECIAL : FAT12_EOF_MIN;
}
// Set the maximum cluster # supported for this volume; it is the
// smaller of 1) total clusters on the media and 2) total cluster entries
// the FAT can contain.
cmaxClus -= DATA_CLUSTER;
if (pvol->v_clusMax > cmaxClus) {
DEBUGMSGBREAK(ZONE_INIT || ZONE_ERRORS,
(DBGTEXT("FATFS!InitVolume: total clusters (%d) exceeds FAT size (%d), reducing...\r\n"), pvol->v_clusMax, cmaxClus));
pvol->v_clusMax = cmaxClus;
}
pvol->v_clusMax++; // now convert total clusters to max cluster #
}
#ifdef TFAT
if (pvol->v_fTfat) {
pvol->v_clusFrozenHead = NO_CLUSTER;
// Setup a bit arry to record what FAT sector is changed, init to -1 in order to sync FAT1 with FAT0 when volume is mounted
pvol->v_DirtySectorsInFAT.dwSize = (pvol->v_csecFAT + 7) >> 3;
// note that InitVolume can be called again, for example, at FormatVolume where the FAT size may change
if(pvol->v_DirtySectorsInFAT.lpBits)
HeapFree(hHeap, 0, pvol->v_DirtySectorsInFAT.lpBits);
pvol->v_DirtySectorsInFAT.lpBits = (LPBYTE)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, pvol->v_DirtySectorsInFAT.dwSize);
// No sectors of FAT0 are cached;
pvol->v_secFATBufferBias = NO_CLUSTER;
// don't alloc in the beginning, need to free it in case InitVolume is called again
// in case it is called again at FormatVolume, the cluster size may change
if(pvol->v_ClusBuf)
{
HeapFree(hHeap, 0, pvol->v_ClusBuf);
pvol->v_ClusBuf = NULL;
}
pvol->v_pFATBuffer = (LPBYTE)HeapAlloc (hHeap, 0, pvol->v_pdsk->d_diActive.di_bytes_per_sect * FAT_CACHE_SECTORS);
if (!pvol->v_pFATBuffer)
return FALSE;
pvol->v_pBootSec = (LPBYTE)HeapAlloc (hHeap, 0, pvol->v_pdsk->d_diActive.di_bytes_per_sect);
if (!pvol->v_pBootSec)
return FALSE;
}
#endif
exit:
pvol->v_clusAlloc = pvol->v_cclusFree = UNKNOWN_CLUSTER;
pvol->v_pFreeClusterList = NULL;
pvol->v_clusterListSize = 0;
// If the FORMATTING bit is set and the volume is valid, then we assume that the volume
// has just been reformatted, and therefore that the number of free clusters is the same
// as total clusters.
if ((pvol->v_flags & (VOLF_INVALID|VOLF_FORMATTING)) == VOLF_FORMATTING)
pvol->v_cclusFree = pvol->v_clusMax-1;
CloseStream(pstmRoot);
CloseStream(pstmFAT);
// Don't cache invalid volumes.
if (!(pvol->v_flags & VOLF_INVALID)) {
SetupDiskCache(pvol);
}
#ifdef TFAT
if (pvol->v_fTfat && !(pvol->v_flags & VOLF_INVALID)) {
// Keep a copy of boot sector
DWORD dwError = ReadWriteDisk( pvol, pvol->v_pdsk->d_hdsk, READ_DISK_CMD, &pvol->v_pdsk->d_diActive,
pvol->v_secVolBias, 1, pvol->v_pBootSec, FALSE );
if (dwError != ERROR_SUCCESS)
{
DEBUGMSG(ZONE_INIT || ZONE_ERRORS,(DBGTEXT("FATFS!InitVolume: ReadWriteDisk failed on boot sector (%d)\r\n"), dwError));
pvol->v_flags |= (VOLF_INVALID|VOLF_UNCERTAIN);
return FALSE;
}
if (!InitFATs(pvol))
{
DEBUGMSG(ZONE_INIT || ZONE_ERRORS,(DBGTEXT("FATFS!InitVolume: InitFATs failed\r\n")));
pvol->v_flags |= (VOLF_INVALID|VOLF_UNCERTAIN);
return FALSE;
}
}
#endif
// Calculate the free space and set up a list of free cluster counts
if (!(pvol->v_flags & VOLF_INVALID)) {
CalculateFreeClustersInRAM(pvol);
}
DEBUGMSG(ZONE_INIT, (DBGTEXT("FATFS!InitVolume: FAT version: %d\r\n"),
(pvol->v_flags & VOLF_32BIT_FAT) ? 32 : ((pvol->v_flags & VOLF_16BIT_FAT) ? 16 : 12)));
DEBUGMSG(ZONE_INIT, (DBGTEXT("FATFS!InitVolume: Cluster Size (Sectors): %d\r\n"),
pbpb->oldBPB.BPB_SectorsPerCluster));
#ifdef TFAT
DEBUGMSG(ZONE_INIT, (DBGTEXT("FATFS!InitVolume: TFAT enabled: %s\r\n"), pvol->v_fTfat ? TEXT("TRUE") : TEXT("FALSE")));
#endif
return pstmFAT && pstmRoot;
}
/* ValidateFATSector - Verify FAT sector has valid media ID
*
* ENTRY
* pvol - pointer to VOLUME
* pvSector - pointer to memory containing FAT sector
*
* EXIT
* TRUE if given FAT sector appears to be valid, FALSE if not
*/
// 通過檢測fat表的 開始幾個字節來判斷fat表的有效性
BOOL ValidateFATSector(PVOLUME pvol, PVOID pvSector)
{
DWORD dwMask;
dwMask = 0xff0;
if (pvol->v_bMediaDesc == MEDIA_HD)
dwMask = 0xff8;
if (pvol->v_flags & VOLF_16BIT_FAT)
dwMask |= 0xfff0;
#ifdef FAT32
else if (pvol->v_flags & VOLF_32BIT_FAT)
dwMask |= 0x0ffffff0;
#endif
else
ASSERT(pvol->v_flags & VOLF_12BIT_FAT);
if ((*(PDWORD)pvSector & dwMask) < dwMask)
return FALSE;
// Needs to add more checking
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -