⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 streamrun.c

📁 Windows操作系统中文件系统过滤驱动和设备驱动之间的相似
💻 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 + -