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

📄 fat.c

📁 从大量的wince源代码中剥离出的fat文件系统源代码。移植性非常高。 微软的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (clusIndex > pvol->v_clusMax) {
        DEBUGMSG(ZONE_FATIO|ZONE_ERRORS,(DBGTEXT("FATFS!Unpack16: invalid cluster index: %d\n"), clusIndex));
        return ERROR_INVALID_DATA;
    }

    dwError = GetFAT(pvol, clusIndex*2, &pEntry, NULL);
    if (!dwError)
        *pclusData = *pEntry & FAT16_EOF_MAX;

    return dwError;
}


/*  Pack16 - Pack 16-bit FAT entries
 *
 *  ENTRY
 *      pvol - pointer to VOLUME
 *      clusIndex - cluster index to pack
 *      clusData - cluster data to pack at clusIndex
 *      pclusOld - pointer to old cluster data at clusIndex, NULL if not needed
 *
 *  EXIT
 *      ERROR_SUCCESS if successful, or an error code (eg, ERROR_INVALID_DATA)
 */

DWORD Pack16(PVOLUME pvol, DWORD clusIndex, DWORD clusData, PDWORD pclusOld)
{
    PWORD pEntry;
    DWORD clusOld, dwError;

    ASSERT(OWNCRITICALSECTION(&pvol->v_pstmFAT->s_cs));

    DEBUGMSG(ZONE_FATIO,(DBGTEXT("FATFS!Pack16: packing cluster %d\n"), clusIndex));

    if (clusIndex > pvol->v_clusMax) {
        DEBUGMSG(ZONE_FATIO|ZONE_ERRORS,(DBGTEXT("FATFS!Pack16: invalid cluster index: %d\n"), clusIndex));
        return ERROR_INVALID_DATA;
    }

    dwError = GetFAT(pvol, clusIndex*2, &pEntry, NULL);
    if (dwError)
        return dwError;

    clusData &= FAT16_EOF_MAX;
    clusOld = *pEntry & FAT16_EOF_MAX;

    if (clusOld != clusData) {

        if (ModifyStreamBuffer(pvol->v_pstmFAT, pEntry, 2) == ERROR_SUCCESS) {
            *pEntry = (WORD)clusData;
        }
        if (pvol->v_cclusFree != UNKNOWN_CLUSTER) {
            if (clusData == FREE_CLUSTER)
                pvol->v_cclusFree++;
            else if (clusOld == FREE_CLUSTER)
                pvol->v_cclusFree--;
        }
    }

    if (pclusOld)
        *pclusOld = clusOld;

    return dwError;
}


#ifdef FAT32

/*  Unpack32 - Unpack 32-bit FAT entries
 *
 *  ENTRY
 *      pvol - pointer to VOLUME
 *      clusIndex - cluster index to unpack (to obtain next cluster)
 *      pclusData - pointer to cluster data (UNKNOWN_CLUSTER if error)
 *
 *  EXIT
 *      ERROR_SUCCESS if successful, or an error code (eg, ERROR_INVALID_DATA)
 */

DWORD Unpack32(PVOLUME pvol, DWORD clusIndex, PDWORD pclusData)
{
    PDWORD pEntry;
    DWORD dwError;

    ASSERT(OWNCRITICALSECTION(&pvol->v_pstmFAT->s_cs));

    DEBUGMSG(ZONE_FATIO,(DBGTEXT("FATFS!Unpack32: unpacking cluster %d\n"), clusIndex));

    *pclusData = UNKNOWN_CLUSTER;

    if (clusIndex > pvol->v_clusMax) {
        DEBUGMSG(ZONE_FATIO|ZONE_ERRORS,(DBGTEXT("FATFS!Unpack32: invalid cluster index: %d\n"), clusIndex));
        return ERROR_INVALID_DATA;
    }

    dwError = GetFAT(pvol, clusIndex*4, &pEntry, NULL);
    if (!dwError)
        *pclusData = *pEntry & FAT32_EOF_MAX;

    return dwError;
}


/*  Pack32 - Pack 32-bit FAT entries
 *
 *  ENTRY
 *      pvol - pointer to VOLUME
 *      clusIndex - cluster index to pack
 *      clusData - cluster data to pack at clusIndex
 *      pclusOld - pointer to old cluster data at clusIndex, NULL if not needed
 *
 *  EXIT
 *      ERROR_SUCCESS if successful, or an error code (eg, ERROR_INVALID_DATA)
 */

DWORD Pack32(PVOLUME pvol, DWORD clusIndex, DWORD clusData, PDWORD pclusOld)
{
    PDWORD pEntry;
    DWORD clusOld, dwError;

    ASSERT(OWNCRITICALSECTION(&pvol->v_pstmFAT->s_cs));

    DEBUGMSG(ZONE_FATIO,(DBGTEXT("FATFS!Pack32: packing cluster %d\n"), clusIndex));

    if (clusIndex > pvol->v_clusMax) {
        DEBUGMSG(ZONE_FATIO|ZONE_ERRORS,(DBGTEXT("FATFS!Pack32: invalid cluster index: %d\n"), clusIndex));
        return ERROR_INVALID_DATA;
    }

    dwError = GetFAT(pvol, clusIndex*4, &pEntry, NULL);
    if (dwError)
        return dwError;

    clusData &= FAT32_EOF_MAX;
    clusOld = *pEntry & FAT32_EOF_MAX;

    if (clusOld != clusData) {

        if (ModifyStreamBuffer(pvol->v_pstmFAT, pEntry, 4) == ERROR_SUCCESS) {
            *pEntry = clusData;
        }
        if (pvol->v_cclusFree != UNKNOWN_CLUSTER) {
            if (clusData == FREE_CLUSTER)
                pvol->v_cclusFree++;
            else if (clusOld == FREE_CLUSTER)
                pvol->v_cclusFree--;
        }
    }

    if (pclusOld)
        *pclusOld = clusOld;

    return dwError;
}

#endif  // FAT32




DWORD UnpackRun(PDSTREAM pstm)
{
    DWORD clusNext, dwError;
    PVOLUME pvol = pstm->s_pvol;
    PRUN prun = &pstm->s_run;

    clusNext = prun->r_clusNext;

    // If clusNext is still set to UNKNOWN_CLUSTER, it means that
    // either the stream is not cluster-mapped (eg, FAT, root directory),
    // or no clusters have been allocated to it yet.

    if (clusNext < DATA_CLUSTER || ISEOF(pvol, clusNext))
        return ERROR_HANDLE_EOF;

    // Move clusThis to clusPrev (adjusted by the size of the current run),
    // unless clusThis isn't valid yet.

    prun->r_clusPrev = NO_CLUSTER;

    if (prun->r_clusThis != UNKNOWN_CLUSTER) {

        ASSERT(prun->r_end > prun->r_start);
        prun->r_clusPrev = prun->r_clusThis +
                           ((prun->r_end - prun->r_start-1) >>
                            (pvol->v_log2cblkClus + BLOCK_LOG2));
    }

    // Start decoding the next run now.

    DEBUGMSG(ZONE_FATIO,(DBGTEXT("FATFS!UnpackRun: unpacking run at cluster %d\n"), clusNext));

    prun->r_clusThis = clusNext;
    prun->r_blk = CLUSTERTOBLOCK(pvol, clusNext);
    prun->r_start = prun->r_end;

    LockFAT(pvol);

    do {
        prun->r_end += pvol->v_cbClus;
        clusNext = prun->r_clusNext;
        dwError = UNPACK(pvol, clusNext, &prun->r_clusNext);
    } while (!dwError && prun->r_clusNext == clusNext+1);

    UnlockFAT(pvol);

    DEBUGMSG(ZONE_FATIO,(DBGTEXT("FATFS!UnpackRun: length of run: %d bytes\n"), prun->r_end - prun->r_start));
    return dwError;
}


/*  NewCluster - Find available cluster
 *
 *  ENTRY
 *      pvol - pointer to VOLUME
 *      clusPrev - last allocated cluster
 *      pclusNew - pointer to DWORD to receive new cluster #
 *      (set to UNKNOWN_CLUSTER if no more clusters are available)
 *
 *      If the caller is trying to extend a stream, then he should pass
 *      clusPrev equal to the last cluster in the stream, in the hope of
 *      extending the file contiguously.  Callers that don't care or don't
 *      know can simply pass UNKNOWN_CLUSTER, and we'll start searching
 *      from the last allocated cluster.
 *
 *  EXIT
 *      ERROR_SUCCESS if successful, or an error code (eg, ERROR_INVALID_DATA)
 *
 *  NOTES
 *      We index into the FAT at clusPrev+1, and if the entry is zero
 *      (FREE_CLUSTER), then we return that entry.  Otherwise, we scan
 *      forward, wrapping around to the beginning of the FAT, until we
 *      we reach clusPrev again.
 *
 *      If clusPrev is UNKNOWN_CLUSTER, then we first set clusPrev
 *      to pvol->v_clusAlloc, and if pvol->v_clusAlloc is UNKNOWN_CLUSTER
 *      as well, then we set clusPrev to DATA_CLUSTER-1 (ie, the cluster
 *      immediately preceding the beginning of the data area, for lack of a
 *      better starting point).
 *
 *      At the end of every successful allocation, we set v_clusAlloc
 *      to the cluster just allocated.
 *
 *      To prevent a free cluster from being used before we have a chance
 *      to link it into a cluster chain, the caller must own v_pstmFAT's
 *      critical section.
 *
 *      Last but not least, don't forget that you're holding onto the last
 *      FAT buffer examined, assuming we successfully located a free cluster.
 */

DWORD NewCluster(PVOLUME pvol, DWORD clusPrev, PDWORD pclusNew)
{
    DWORD dwError;
    DWORD clus, cclusTotal;

    ASSERT(OWNCRITICALSECTION(&pvol->v_pstmFAT->s_cs));

    // As long as cclusFree is non-zero (which includes UNKNOWN_CLUSTER, which means
    // we have no idea yet how many free clusters there are, if any), then we have to
    // search the FAT.

    dwError = ERROR_SUCCESS;
    *pclusNew = UNKNOWN_CLUSTER;

    if (pvol->v_cclusFree != 0) {

        if (clusPrev == UNKNOWN_CLUSTER) {
            clusPrev = pvol->v_clusAlloc;
            if (clusPrev == UNKNOWN_CLUSTER) {
                clusPrev = DATA_CLUSTER-1;
            }
        }

        for (cclusTotal = pvol->v_clusMax-1; cclusTotal > 0; cclusTotal--) {

            if (++clusPrev > pvol->v_clusMax)
                clusPrev = DATA_CLUSTER;

            dwError = UNPACK(pvol, clusPrev, &clus);
            if (dwError)
                break;
            ASSERT(clus != UNKNOWN_CLUSTER);

            if (clus == FREE_CLUSTER) {
                pvol->v_clusAlloc = clusPrev;
                *pclusNew = clusPrev;
                break;
            }
        }

        // If we didn't break out of the loop prematurely, there are no more clusters

        if (cclusTotal == 0) {
            ASSERT(dwError == ERROR_SUCCESS && clus != FREE_CLUSTER);
            pvol->v_cclusFree = 0;
        }
    }

    DEBUGMSG(ZONE_FATIO,(DBGTEXT("FATFS!NewCluster: returned cluster 0x%08x (%d)\n"), *pclusNew, dwError));
    return dwError;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -