📄 streamrun.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of your Microsoft Windows CE
// Source Alliance Program license form. If you did not accept the terms of
// such a license, you are not authorized to use this source code.
//
#include "fatfs.h"
// 初始化该stream对应的run变量的信息,并将第一个run的起始簇设置为FirstCluster参数的值
VOID InitStreamRunList(PStreamRunList pRunList, PVOLUME pvol, DWORD FirstCluster)
{
pRunList->r_pvol = pvol;
pRunList->r_StartPosition = 0;
pRunList->r_EndPosition = 0;
pRunList->r_StartBlock = 0;
pRunList->r_CurrentIndex = 0;
//
memset (pRunList->r_RunList, 0, sizeof(pRunList->r_RunList));
ResetRunList(pRunList, FirstCluster);
}
VOID SetRunSize(PStreamRunList pRunList, DWORD Size)
{
// Only called by non-cluster mapped streams, to set up one fixed run
//
pRunList->r_EndPosition = Size;
}
VOID SetRunStartBlock(PStreamRunList pRunList, DWORD StartBlock)
{
// Only called by non-cluster mapped streams, to set up one fixed run
//
pRunList->r_StartBlock = StartBlock;
}
//NumClusters实际上是run是否为空的标记
DWORD ResetRunList (PStreamRunList pRunList, DWORD FirstCluster)
{
pRunList->r_StartPosition = 0;
if ((FirstCluster < DATA_CLUSTER) || (FirstCluster == UNKNOWN_CLUSTER))
{
pRunList->r_RunList[0].StartCluster = FirstCluster;
//NumClusters实际上是run是否为空的标记
pRunList->r_RunList[0].NumClusters = 0;
pRunList->r_EndPosition = 0;
}
else
{
pRunList->r_RunList[0].StartCluster = FirstCluster;
pRunList->r_RunList[0].NumClusters = 1;
pRunList->r_EndPosition = pRunList->r_pvol->v_cbClus;
}
pRunList->r_CurrentIndex = 0;
return ERROR_SUCCESS;
}
//将cluster挂载到run合适的位置
DWORD AppendRunList (PStreamRunList pRunList, DWORD Position, DWORD Cluster)
{
DWORD Result = ERROR_SUCCESS;
//判断是否比当前流还位置还要靠后
BOOL IsEofCluster = ISEOF (pRunList->r_pvol, Cluster);
if (Cluster < DATA_CLUSTER)
{
DEBUGMSGBREAK (1, (TEXT("FATFS!AppendRunList: Invalid cluster (%d)"), Cluster));
Result = ERROR_INVALID_PARAMETER;
goto exit;
}
// The position is not required, and is only used for verification purposes
// in a stream extend case
//
if ((Position != INVALID_POS) && (Position != pRunList->r_EndPosition))
{
DEBUGMSGBREAK (1, (TEXT("FATFS!AppendRunList: Invalid Position (%d)"), Position));
Result = ERROR_INVALID_PARAMETER;
goto exit;
}
// If the current run is pointed to an empty run, then move
// the index back one place, if possible
// 判断当前run是否是空,如果为空将前面的一个run设置为当前run
if ((pRunList->r_RunList[pRunList->r_CurrentIndex].NumClusters == 0) && (pRunList->r_CurrentIndex != 0))
{
ASSERT (Position != INVALID_POS);
pRunList->r_CurrentIndex--;
}
//如果和当前流的比最后一个簇大1,则直接挂到当前运行的上
if (!IsEofCluster && (GetEndClusterInRun(pRunList, pRunList->r_CurrentIndex) + 1) == Cluster)
{
// Add the new cluster to the current run
//
pRunList->r_RunList[pRunList->r_CurrentIndex].NumClusters++;
pRunList->r_EndPosition += pRunList->r_pvol->v_cbClus;
}
else
{
// Shift the runs down one slot if there is no more room
// left for the new run. Else, add new run in next slot.
// 如果当前run不再最后一个位置,则将新的run添加到下一个位置,否则移出第一个run
// 并将新的run添加到最后一个位置
if (pRunList->r_CurrentIndex == (NUM_STREAM_RUNS - 1))
{
//将第一个run删除,后面的9个run整体前移,空出第10个run的位置
ShiftRunList(pRunList);
}
else if (pRunList->r_RunList[pRunList->r_CurrentIndex].NumClusters != 0)
{
//将新的run添加到当前run的下一个位置
pRunList->r_CurrentIndex++;
}
//将当前run的startcluster移位到Cluster,相当于舍弃了前面的cluster
pRunList->r_RunList[pRunList->r_CurrentIndex].StartCluster = Cluster;
if (IsEofCluster)
{
pRunList->r_RunList[pRunList->r_CurrentIndex].NumClusters = 0;
}
else
{
pRunList->r_RunList[pRunList->r_CurrentIndex].NumClusters = 1;
pRunList->r_EndPosition += pRunList->r_pvol->v_cbClus;
}
}
exit:
DEBUGMSG (ZONE_READVERIFY, (TEXT("FATFS!AppendRunList: Position = %d, Cluster = %d.\r\n"), Position, Cluster));
ASSERT (ValidateRunListIntegrity(pRunList));
return Result;
}
//移除当前Position后所有的run,当然了,首先要查询Position在run中的位置
DWORD TruncateRunList(PStreamRunList pRunList, DWORD Position)
{
DWORD Result = ERROR_SUCCESS;
DWORD CurrentIndex = 0;
DWORD CurrentStartPosition = pRunList->r_StartPosition;
DWORD CurrentEndPosition = CurrentStartPosition + GetRunSize(pRunList, CurrentIndex);
if (Position < pRunList->r_StartPosition || Position > pRunList->r_EndPosition)
{
DEBUGMSGBREAK (1, (TEXT("FATFS!TruncateRun: Invalid Position (%d)"), Position));
Result = ERROR_INVALID_PARAMETER;
goto exit;
}
while (Position > CurrentEndPosition)
{
CurrentIndex++;
if (CurrentIndex > pRunList->r_CurrentIndex)
{
DEBUGMSGBREAK (1, (TEXT("FATFS!TruncateRun: Invalid run index (%d)."), CurrentIndex));
Result = ERROR_INVALID_PARAMETER;
goto exit;
}
CurrentStartPosition = CurrentEndPosition;
CurrentEndPosition = CurrentStartPosition + GetRunSize(pRunList, CurrentIndex);
}
// Number of clusters is Position - CurrentStartPosition in terms of clusters, rounded up
// 通过+pRunList->r_pvol->v_cbClus - 1和移位的方式获取了Position所处位置的
// cluster号,例如cluster大小为12,Position为3,则计算出的cluster号为1,如果为17,则计算出来的为2
pRunList->r_RunList[CurrentIndex].NumClusters = (Position - CurrentStartPosition + pRunList->r_pvol->v_cbClus - 1) >>
pRunList->r_pvol->v_log2cbBlk >> pRunList->r_pvol->v_log2cblkClus;
pRunList->r_EndPosition = CurrentStartPosition + GetRunSize(pRunList, CurrentIndex);
// Remove the run from the list if it is zero length
//
if (pRunList->r_RunList[CurrentIndex].NumClusters == 0)
{
if (CurrentIndex)
{
CurrentIndex--;
}
else
{
pRunList->r_RunList[CurrentIndex].StartCluster = 0;
}
}
pRunList->r_CurrentIndex = CurrentIndex;
exit:
DEBUGMSG (ZONE_READVERIFY, (TEXT("FATFS!TruncateRun: Position = %d.\r\n"), Position));
ASSERT (ValidateRunListIntegrity(pRunList));
return Result;
}
//判断Position在pRunList的第几个run上,并通过pRunInfo返回那个run的开始和长度信息
DWORD GetRunInfo (PStreamRunList pRunList, DWORD Position, PRunInfo pRunInfo)
{
DWORD Result = ERROR_SUCCESS;
DWORD CurrentIndex = 0;
DWORD CurrentStartPosition = 0;
DWORD CurrentEndPosition = 0;
if (Position < pRunList->r_StartPosition || Position > pRunList->r_EndPosition)
{
DEBUGMSGBREAK (1, (TEXT("FATFS!GetRunInfo: Invalid Position (%d)"), Position));
Result = ERROR_INVALID_PARAMETER;
goto exit;
}
//表示pRunList并不包含任何有效的run
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -