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

📄 fal.cpp

📁 基于WINCE的文件系统FAL驱动
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            {
                // NOTE: Since we don't know the contents of the sector mapping info for this physical sector,
                //       we can safely write all '1's (except the bit used to indicate the sector is "dirty").
                memset(&sectorMappingInfo, 0xFF, sizeof(SectorMappingInfo));
                MarkSectorDirty(sectorMappingInfo);

                if(!FMD.pWriteSector(existingPhysicalSectorAddr, NULL, (PSectorInfo)&sectorMappingInfo, 1))
                {
                    DEBUGMSG(ZONE_WRITE_OPS,(TEXT("FLASHDRV.DLL:WriteToMedia() - Unable to mark old physical sector 0x%08x as DIRTY!  Calling HandleWriteFailure()\r\n"),
                                                   existingPhysicalSectorAddr));

                    // WRITE operation failed, try to recover...
                    if(!HandleWriteFailure(existingPhysicalSectorAddr))
                    {
                        ReportError((TEXT("FLASHDRV.DLL:WriteToMedia() - Unable to handle the WRITE failure to sector 0x%08x\r\n"), physicalSectorAddr));
                        goto WRITE_ERROR;
                    }
                    continue;                                           // Try the WRITE at another physical sector...
                }


                // Inform the Sector Manager that this sector is DIRTY...
                if(!m_pSectorMgr->MarkSectorsAsDirty(existingPhysicalSectorAddr, 1))
                {
                    ReportError((TEXT("FLASHDRV.DLL:WriteToMedia() - FATAL_ERROR: SM_MarkSectorsAsDirty(0x%08x) failed!\r\n"), existingPhysicalSectorAddr));
                    goto WRITE_ERROR;
                }
            }

            //----- 8. At this point, the WRITE operation has completed successfully. -----
            break;
        }

        dwSGBuffPos  += g_pFlashMediaInfo->dwDataBytesPerSector;
    }

    return ERROR_SUCCESS;

WRITE_ERROR:
    return dwError;
}




/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       HandleWriteFailure()

Description:    Handles the case when a WRITE to the media fails.  If a WRITE operation
                fails, this is an indication that this FLASH block is going bad.
                Consequently, any remaining FREE sectors in this block should be removed
                from the Sector Manager and the block should be compacted.

Notes:          The second parameter to CompactBlock() handles the rare situation when
                marking an existing MAPPED sector as DIRTY fails.  In this situation, the
                block needs to be compacted and this sector needs to be treated as DIRTY
                regardless of what the mapping information says...

Returns:        Boolean indicating success.
------------------------------------------------------------------------------------*/
BOOL FileSysFal::HandleWriteFailure(SECTOR_ADDR physicalSectorAddr)
{
    BLOCK_ID     dwBlockID                    = 0;
    SECTOR_ADDR  firstPhysicalSectorAddr    = 0;

    //----- 1. Determine the dwBlockID for this physical sector address -----
    dwBlockID = m_pSectorMgr->GetBlockFromSector (physicalSectorAddr);

    //----- 2. Determine first physical sector address for this block -----
    firstPhysicalSectorAddr = m_pSectorMgr->GetStartSectorInBlock (dwBlockID);

    //----- 3. Inform the Sector Manager that any FREE sectors in this block should be removed... -----
    if(!m_pSectorMgr->UnmarkSectorsAsFree(firstPhysicalSectorAddr, m_pRegion->dwSectorsPerBlock))
    {
        ReportError((TEXT("FLASHDRV.DLL:HandleWriteFailure() - m_pSectorMgr->UnmarkSectorsAsFree(%d, %d) failed!\r\n"), firstPhysicalSectorAddr, m_pRegion->dwSectorsPerBlock));
        // NOTE: If this call FAILS, keep on going because CompactBlock() may be still be able to FREE some sectors in order for
        //       for the WRITE to complete.
    }

    //----- 4. Mark the failed sector as dirty, since CompactBlock will unmark it as dirty
    //
    if(!m_pSectorMgr->MarkSectorsAsDirty(physicalSectorAddr, 1))
    {
        ReportError((TEXT("FLASHDRV.DLL:HandleWriteFailure() - Unable to mark physical sector 0x%08x as DIRTY\r\n"), physicalSectorAddr));
    }

    //----- 5. Compact the block.  Any MAPPED sectors are relocated to another portion of the media -----
    //         and any DIRTY sectors are recycled into FREE sectors.
    if(m_pCompactor->CompactBlock(dwBlockID, physicalSectorAddr) == BLOCK_COMPACTION_ERROR)
    {
        ReportError((TEXT("FLASHDRV.DLL:HandleWriteFailure() - CompactBlock(%d, 0x%08x) failed!\r\n"), dwBlockID, physicalSectorAddr));
        goto HANDLE_WRITE_FAILURE_ERROR;
    }

    return TRUE;

HANDLE_WRITE_FAILURE_ERROR:
    return FALSE;
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       DeleteSectors()

Description:    Deletes the specified range of logical sectors.

Notes:          To "delete" a logical sector, the appropriate physical
                sector simply needs to be marked as DIRTY.

Returns:        Boolean indicating success.
-------------------------------------------------------------------*/
BOOL FileSysFal::DeleteSectors(DWORD dwStartLogSector, DWORD dwNumSectors)
{
    SECTOR_ADDR dwPhysSector = 0;
    DWORD i = 0;
    SectorMappingInfo sectorMappingInfo;

    if (m_fReadOnly)
    {
        SetLastError(ERROR_WRITE_PROTECT);
        return FALSE;
    }

    //----- 1. Check to make sure this deletion request doesn't run off the end of the media! -----
    if((dwStartLogSector+dwNumSectors) > g_dwAvailableSectors)
    {
        ReportError((TEXT("FLASHDRV.DLL:DeleteSectors() - Delete sectors (0x%08x - 0x%08x) exceeds the media size!\r\n"),
                                    dwStartLogSector, dwStartLogSector+dwNumSectors));
        goto DELETE_ERROR;
    }

    CELOG_DeleteSectors(dwStartLogSector, dwNumSectors);

    //----- 2. Setup the sector mapping info to mark this physical sector as DIRTY -----
    //         NOTE: Since we don't know the contents of the sector mapping info for this physical sector,
    //               we can safely write all '1's (except the bit used to indicate the sector is DIRTY ).
    memset(&sectorMappingInfo, 0xFF, sizeof(SectorMappingInfo));
    MarkSectorDirty(sectorMappingInfo);

    for(i=0; i<dwNumSectors; i++)
    {

        //----- 3. Lookup the physical sector address for this logical sector -----
        if((!m_pMap->GetPhysicalSectorAddr((SECTOR_ADDR)(dwStartLogSector+i), &dwPhysSector)) || (dwPhysSector == UNMAPPED_LOGICAL_SECTOR))
        {
            // Redundant call to delete sector.  Just ignore it.
            return TRUE;
        }

        //----- 4. Mark the physical sector address as DIRTY -----
        if(!FMD.pWriteSector(dwPhysSector, NULL, (PSectorInfo)&sectorMappingInfo, 1))
        {
            ReportError((TEXT("FLASHDRV.DLL:DeleteSectors() - Unable to mark old physical sector 0x%08x as dirty!\r\n"), dwPhysSector));
            goto DELETE_ERROR;
        }

        //----- 5. Update the logical-->physical mapper to indicate this logical sector is no longer mapped -----
        if(!m_pMap->MapLogicalSector((dwStartLogSector+i), UNMAPPED_LOGICAL_SECTOR, &dwPhysSector))
        {
            ReportError((TEXT("FLASHDRV.DLL:DeleteSectors() = FATAL_ERROR: Unable to map logical sector 0x%08x to physical sector 0x%08x\r\n"),
                                        (dwStartLogSector+i), UNMAPPED_LOGICAL_SECTOR));
            goto DELETE_ERROR;
        }

        //----- 6. Inform the Sector Manager that this sector is dirty... -----
        if(!m_pSectorMgr->MarkSectorsAsDirty(dwPhysSector, 1))
        {
            ReportError((TEXT("FLASHDRV.DLL:DeleteSectors() - FATAL_ERROR: SM_MarkSectorsAsDirty(0x%08x) failed!\r\n"), dwPhysSector));
            goto DELETE_ERROR;
        }
    }

    return TRUE;

DELETE_ERROR:
    return FALSE;
}

BOOL FileSysFal::SecureWipe()
{
    DWORD i = 0;
    DWORD dwFirstGoodBlock = 0;
    DWORD dwSecondGoodBlock = 0;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("FLASHDRV.DLL:SecureWipe() - Enter\r\n")));

    // ----- 1. Mark the first good block with secure in progress
    dwFirstGoodBlock = SetSecureWipeFlag (m_pRegion->dwStartPhysBlock);
    if (dwFirstGoodBlock == INVALID_BLOCK_ID)
    {
        return FALSE;
    }

    // ----- 2. Erase all of the valid blocks on the FLASH region, except
    // -----    except the first, which contains the secure in progress bit
    for(i = dwFirstGoodBlock + 1; i < m_pRegion->dwStartPhysBlock + m_pRegion->dwNumPhysBlocks; i++)
    {
        if(FMD.pGetBlockStatus((BLOCK_ID)i) & (BLOCK_STATUS_BAD | BLOCK_STATUS_RESERVED))
        {
            // Don't erase bad blocks on the media or blocks reserved for other use (such as bootloader).
            continue;
        }

        if(!FMD.pEraseBlock((BLOCK_ID)i))
        {
            ReportError((TEXT("FLASHDRV.DLL:SecureWipe() - FMD_EraseBlock(%d) failed\r\n"), i));

            if(!FMD.pSetBlockStatus((BLOCK_ID)i, BLOCK_STATUS_BAD))
            {
                ReportError((TEXT("FLASHDRV.SecureWipe() - FMD_MarkBlockBad(%d) failed\r\n"), i));
            }
            continue;
        }
    }

    // ----- 3. Mark the second good block with secure in progress
    dwSecondGoodBlock = SetSecureWipeFlag (dwFirstGoodBlock + 1);
    if (dwSecondGoodBlock == INVALID_BLOCK_ID)
    {
        return FALSE;
    }

    // ----- 4. Erase the first good block
    if(!FMD.pEraseBlock((BLOCK_ID)dwFirstGoodBlock))
    {
        ReportError((TEXT("FLASHDRV.DLL:SecureWipe() - FMD_EraseBlock(%d) failed\r\n"), dwFirstGoodBlock));

        if(!FMD.pSetBlockStatus((BLOCK_ID)dwFirstGoodBlock, BLOCK_STATUS_BAD))
        {
            ReportError((TEXT("FLASHDRV.SecureWipe() - FMD_MarkBlockBad(%d) failed\r\n"), dwFirstGoodBlock));
        }
    }

    // ----- 5. Erase the second good block
    if(!FMD.pEraseBlock((BLOCK_ID)dwSecondGoodBlock))
    {
        ReportError((TEXT("FLASHDRV.DLL:SecureWipe() - FMD_EraseBlock(%d) failed\r\n"), dwSecondGoodBlock));

        if(!FMD.pSetBlockStatus((BLOCK_ID)dwSecondGoodBlock, BLOCK_STATUS_BAD))
        {
            ReportError((TEXT("FLASHDRV.SecureWipe() - FMD_MarkBlockBad(%d) failed\r\n"), dwSecondGoodBlock));
        }
    }
    DEBUGMSG(ZONE_FUNCTION, (TEXT("FLASHDRV.DLL:SecureWipe() - Exit\r\n")));

    return TRUE;
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       SetSecureWipeFlag()

Description:    Sets the secure wipe flag in the sector info.  Starts
                looking at the block specified by dwStartBlock.  If
                dwStartBlock is INVALID_BLOCK_ID, start from the
                beginning of the region.

Returns:        The block in which the flag was set.
                INVALID_BLOCK_ID on error.
-------------------------------------------------------------------*/

DWORD FileSysFal::SetSecureWipeFlag(DWORD dwStartBlock)
{
    DWORD i = 0;
    SectorMappingInfo sectorMappingInfo;
    DWORD dwBlock = dwStartBlock;

    if (m_fReadOnly)
    {
        SetLastError(ERROR_WRITE_PROTECT);
        return INVALID_BLOCK_ID;
    }

    // If a starting block wasn't provided, start from the beginning of the region.
    if (dwStartBlock == INVALID_BLOCK_ID)
    {
        dwBlock = m_pRegion->dwStartPhysBlock;
    }

    if (!m_pRegion->dwNumPhysBlocks || (dwBlock < m_pRegion->dwStartPhysBlock))
    {
        return INVALID_BLOCK_ID;
    }

    while (FMD.pGetBlockStatus((BLOCK_ID)dwBlock) & (BLOCK_STATUS_BAD | BLOCK_STATUS_RESERVED) &&
           dwBlock < m_pRegion->dwStartPhysBlock + m_pRegion->dwNumPhysBlocks)
    {
        dwBlock++;
    }

    if (dwBlock >= m_pRegion->dwStartPhysBlock + m_pRegion->dwNumPhysBlocks)
    {
        return INVALID_BLOCK_ID;
    }

    // Mark the first good block with secure in progress
    DWORD dwPhysSector = m_pSectorMgr->GetStartSectorInBlock (dwBlock);
    memset(&sectorMappingInfo, 0xFF, sizeof(SectorMappingInfo));
    MarkSecureWipeInProgress(sectorMappingInfo);

    if(!FMD.pWriteSector(dwPhysSector, NULL, (PSectorInfo)&sectorMappingInfo, 1))
    {
        ReportError((TEXT("FLASHDRV.DLL:FileSysFal::SecureWipe() - Unable to mark sector in progress!\r\n")));
        return INVALID_BLOCK_ID;
    }

    return dwBlock;
}

⌨️ 快捷键说明

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