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

📄 fal.cpp

📁 基于WINCE的文件系统FAL驱动
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    //----- 5. Initialize and start the compactor -----
    if(!m_pCompactor->Init (pRegion, this))
    {
        ReportError((TEXT("FLASHDRV.DLL:StartupFAL() - Unable to initialize the compactor!!!\r\n")));
        return FALSE;
    }

    return Fal::StartupFAL(pRegion);
}



/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       ShutdownFAL()

Description:    Shuts down the FLASH Abstraction Layer (FAL)

Notes:          The logical --> physical mapper and sector manager
                are appropriately deinitialized.  Note that the caller
                is responsible for deinitializing the FMD.

Returns:        Boolean indicating success.
-------------------------------------------------------------------*/
BOOL FileSysFal::ShutdownFAL()
{
    if(!m_pCompactor->Deinit())
    {
        ReportError((TEXT("FLASHDRV.DLL:ShutdownFAL() - Unable to deinitialize the Compactor\r\n")));
    }

    return Fal::ShutdownFAL();
}


BOOL FileSysFal::BuildupMappingInfo()
{
    DWORD i = 0;
    DWORD dwBlockID = 0;
    DWORD dwPhysSector = m_dwStartPhysSector;
    DWORD dwLogSector = m_dwStartLogSector;
    DWORD dwExistingPhysSector = 0;
    SectorMappingInfo  sectorMappingInfo;
	DWORD counts[10];

	memset(counts,0,sizeof(counts));

    DEBUGMSG(1, (TEXT("FLASHDRV.DLL:BuildupMappingInfo() - Enter. \r\n"), dwBlockID));
RETAILMSG(1,(TEXT("Initialize the FAL BuildupMappingInfo start:%d\r\n"),GetTickCount() ));

    //----- 1. Read the entire media to determine the status of all sectors -----
    for (dwBlockID = m_pRegion->dwStartPhysBlock; dwBlockID < m_pRegion->dwStartPhysBlock + m_pRegion->dwNumPhysBlocks; dwBlockID++)
    {
        //----- 2. What is the status of this block? -----
        DWORD dwStatus = FMD.pGetBlockStatus (dwBlockID);

        if (dwStatus & (BLOCK_STATUS_BAD | BLOCK_STATUS_RESERVED))
        {
counts[0]++;
            if(!m_pSectorMgr->MarkBlockUnusable(dwBlockID))
            {
                ReportError((TEXT("FLASHDRV.DLL:BuildupMappingInfo() - SectorMgr::MarkBlockUnusable(%d) failed. \r\n"), dwBlockID));
            }
            dwPhysSector += m_pRegion->dwSectorsPerBlock; // Move to first sector in next block
            continue;
        }

        //----- 4. Read the sector information stored on the physical media for each sector -----
        for(i=0; i<(m_pRegion->dwSectorsPerBlock); i++, dwPhysSector++)
        {
counts[1]++;
            //----- Notice that SectorMappingInfo is cast to SectorInfo.  SectorInfo is the public -----
            //      definition of the private structure SectorMappingInfo.  Consequently, any
            //      changes to the SectorMappingInfo structure will require the SectorInfo
            //      structure's size be updated accordingly.
            if(!FMD.pReadSector(dwPhysSector, NULL, (PSectorInfo)&sectorMappingInfo, 1))
            {
                ReportError((TEXT("FLASHDRV.DLL:BuildupMappingInfo() - Unable to read sector information for sector %d\r\n"), dwPhysSector));
                goto INIT_ERROR;
            }
/* ctg -- start */
            if (IsSecureWipeInProgress(sectorMappingInfo))
            {
                SecureWipe();
                MarkSectorFree(sectorMappingInfo);
            }
/* ctg -- stop */

            //----- 5. Free sector?  If so, add it to the "free sector list" the Sector Manager uses -----
            //         NOTE: Notice that we ONLY mark this sector as FREE if it is in a valid block.
            if(IsSectorFree(sectorMappingInfo))
            {
counts[2]++;
                // OPTIMIZATION: Because the compactor always adds whole blocks of FREE sectors to the
                //               Sector Manager, we know that if the first sector in a block is FREE then
                //               all other sectors in this block are also FREE.  Consequently, when the first
                //               sector in a block is FREE we don't have to read the other sectors in the block.
                if(i == 0)
                {
                    if(!m_pSectorMgr->AddSectorsToList(SectorMgr::Free, dwPhysSector, m_pRegion->dwSectorsPerBlock))
                    {
                        ReportError((TEXT("FLASHDRV.DLL:BuildupMappingInfo() - Unable to mark sector %x as free.\r\n"), dwPhysSector));
                    }
                    dwPhysSector += m_pRegion->dwSectorsPerBlock;
                    break;

                }

                // The whole block isn't FREE; add just this sector to the Sector Manager's FREE list...
                if(!m_pSectorMgr->AddSectorsToList(SectorMgr::Free, dwPhysSector, 1))
                {
                    ReportError((TEXT("FLASHDRV.DLL:BuildupMappingInfo() - Unable to mark sector %x as free.\r\n"), dwPhysSector));
                }

                continue;
            }

            //----- 6. DIRTY sector?  If so, inform the Sector Manager... -----
            if(IsSectorDirty(sectorMappingInfo))
            {
counts[3]++;
                if(!m_pSectorMgr->MarkSectorsAsDirty(dwPhysSector, 1))
                {
                    ReportError((TEXT("FLASHDRV.DLL:BuildupMappingInfo() - Unable to mark sector %x as dirty.\r\n"), dwPhysSector));
                }
                continue;
            }


            //----- 7. Mapped sector? If so, use logical --> sector mapper to create a mapping -----
            if(IsSectorMapped(sectorMappingInfo))
            {
counts[4]++;
                // First sector in a block must be marked RO to indicate all sectors in the block are RO.
                if ((dwStatus & BLOCK_STATUS_READONLY) && (i == 0))
                {
                    DWORD iSector;

counts[7]++;
                    if(!m_pSectorMgr->AddSectorsToList(SectorMgr::ReadOnly, sectorMappingInfo.logicalSectorAddr, m_pRegion->dwSectorsPerBlock))
                    {
                        ReportError((TEXT("FLASHDRV.DLL:BuildupMappingInfo() - Unable to mark sector %x as read only.\r\n"), dwPhysSector));
                    }

                    for (iSector = 0; iSector < m_pRegion->dwSectorsPerBlock; iSector++)
                    {
                        if(!m_pMap->MapLogicalSector(sectorMappingInfo.logicalSectorAddr + iSector, dwPhysSector + iSector, &dwExistingPhysSector))
                        {
                            ReportError((TEXT("FLASHDRV.DLL:BuildupMappingInfo() - Unable to map logical sector 0x%08x to physical sector 0x%08x\r\n"),
                                                        sectorMappingInfo.logicalSectorAddr + iSector, dwPhysSector + iSector));
                        }
                    }

                    dwPhysSector += m_pRegion->dwSectorsPerBlock;
                    break;
                }


                if(!m_pMap->MapLogicalSector(sectorMappingInfo.logicalSectorAddr, dwPhysSector, &dwExistingPhysSector))
                {
                    ReportError((TEXT("FLASHDRV.DLL:BuildupMappingInfo() - Unable to map logical sector 0x%08x to physical sector 0x%08x\r\n"),
                                                sectorMappingInfo.logicalSectorAddr, dwPhysSector));
                }

                // SPECIAL CASE: It is possible that a power-failure occured just after the contents of a MAPPED
                //               logical sector were updated but BEFORE the old data was marked DIRTY.  This situation
                //               can be detected if (dwExistingPhysSector != UNMAPPED_LOGICAL_SECTOR).  To fix
                //               this case, we should keep the latest logical --> physical mapping information and
                //               mark the data in the dwExistingPhysSector as DIRTY.
                if ((dwExistingPhysSector != UNMAPPED_LOGICAL_SECTOR) && !m_fReadOnly)
                {
counts[5]++;
                    DEBUGMSG(ZONE_WRITE_OPS,(TEXT("FLASHDRV.DLL:BuildupMappingInfo() - Power failure during the last WRITE operation is detected,  \
                                                   insuring data integrity for logical sector %08x\r\n"), sectorMappingInfo.logicalSectorAddr));

                    // 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(dwExistingPhysSector, NULL, (PSectorInfo)&sectorMappingInfo, 1))
                    {
counts[6]++;
                        DEBUGMSG(ZONE_WRITE_OPS,(TEXT("FLASHDRV.DLL:BuildupMappingInfo() - Unable to mark old physical sector 0x%08x as DIRTY!  Calling HandleWriteFailure()\r\n"),
                                                       dwExistingPhysSector));

                        // WRITE operation failed, try to recover...
                        if(!HandleWriteFailure(dwExistingPhysSector))
                        {
                            ReportError((TEXT("FLASHDRV.DLL:BuildupMappingInfo() - Unable to handle the WRITE failure to sector 0x%08x\r\n"), dwPhysSector));
                            goto INIT_ERROR;
                        }
                    }


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

RETAILMSG(1,(TEXT("Initialize the FAL BuildupMappingInfo stop:%d\r\n"),GetTickCount() ));
RETAILMSG(1,(TEXT("counts(9876543210): %d %d %d %d %d %d %d %d %d %d\r\n"),
	counts[9], counts[8], counts[7], counts[6], counts[5],
	counts[4], counts[3], counts[2], counts[1], counts[0] ));
    return TRUE;


INIT_ERROR:
    return FALSE;
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       InternalWriteToMedia()

Description:    Performs the specified scatter/gather WRITE request to the media.

Notes:          After parsing the parameters, the actual WRITE request is handled
                by the FLASH Media Driver (FMD).

Returns:        Boolean indicating success.
-------------------------------------------------------------------------------*/
DWORD FileSysFal::InternalWriteToMedia(DWORD dwStartSector, DWORD dwNumSectors, LPBYTE pBuffer)
{
    DWORD        dwSGBuffNum                  = 0;
    DWORD        dwSGBuffPos                  = 0;
    DWORD        dwSectorAddr                = 0;

    SECTOR_ADDR  physicalSectorAddr          = 0;
    SECTOR_ADDR  existingPhysicalSectorAddr  = 0;

    SectorMappingInfo sectorMappingInfo;

    DWORD dwError = ERROR_GEN_FAILURE;


    for(dwSectorAddr = dwStartSector; dwSectorAddr < (dwStartSector + dwNumSectors); dwSectorAddr++)
    {
        //----- 2. Write the sector data to disk.  Notice that this operation is repetitively -----
        //         tried ONLY if FMD_WriteSector() fails.  Unless the FLASH block we are writing to
        //         has just gone bad, this loop will only execute once.
        for(;;)
        {
            //----- 3. Get a free physical sector to store the data into.  If this call FAILS, the WRITE -----
            //         cannot succeed because the media is full.
            if(!m_pSectorMgr->GetNextFreeSector(&physicalSectorAddr, FALSE))
            {
                ReportError((TEXT("FLASHDRV.DLL:WriteToMedia() - Unable to get next free physical sector address for writing!  The media is full...\r\n")));
                dwError = ERROR_DISK_FULL;
                goto WRITE_ERROR;
            }

            //----- For debugging purposes, print out the logical --> physical mapping... -----
            DEBUGMSG(ZONE_WRITE_OPS, (TEXT("FLASHDRV.DLL:WriteToMedia() - logicalSector 0x%08x --> physicalSector 0x%08x\r\n"), dwSectorAddr, physicalSectorAddr));


            //----- 4. Start the write operation (used to safeguard against power failure conditions) -----
            //         The rationale is as follows: If we lose power during before the data is written
            //         to the media, this bit should be set and this will allow us to detect that a
            //         WRITE was in progress when the power failed.
            memset(&sectorMappingInfo, 0xFF, sizeof(SectorMappingInfo));
            sectorMappingInfo.logicalSectorAddr = dwSectorAddr;
            MarkSectorWriteInProgress(sectorMappingInfo);

            if(!FMD.pWriteSector(physicalSectorAddr, NULL, (PSectorInfo)&sectorMappingInfo, 1))
            {
                DEBUGMSG(ZONE_WRITE_OPS, (TEXT("FLASHDRV.DLL:WriteToMedia() - Unable to start WRITE operation.  Calling HandleWriteFailure()\r\n")));

                // WRITE operation failed, try to recover...
                if(!HandleWriteFailure(physicalSectorAddr))
                {
                    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...
            }

            //----- 5. Invoke the FLASH Media Driver (FMD) to write the sector data to the media -----
            //         NOTE: The write will be marked as "completed" if FMD_WriteSector() succeeeds
            //
            //         NOTE: Currently, only one sector is written at a time (last parameter)
            MarkSectorWriteCompleted(sectorMappingInfo);
            if(!FMD.pWriteSector(physicalSectorAddr, (pBuffer+dwSGBuffPos), (PSectorInfo)&sectorMappingInfo, 1))
            {
                DEBUGMSG(ZONE_WRITE_OPS,(TEXT("FLASHDRV.DLL:WriteToMedia() - Unable to write to physical sector 0x%08x!  Calling HandleWriteFailure()\r\n"),
                                               physicalSectorAddr));

                // WRITE operation failed, try to recover...
                if(!HandleWriteFailure(physicalSectorAddr))
                {
                    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...
            }

            //----- 6. Perform the LOGICAL -> PHYSICAL mapping... -----
            if(!m_pMap->MapLogicalSector(dwSectorAddr, physicalSectorAddr, &existingPhysicalSectorAddr))
            {
                ReportError((TEXT("FLASHDRV.DLL:WriteToMedia() = FATAL_ERROR: Unable to map logical sector 0x%08x to physical sector 0x%08x\r\n"),
                                            dwSectorAddr, physicalSectorAddr));
                goto WRITE_ERROR;
            }

            //----- 7. If this logical sector was already mapped, mark the "stale data" in the existing -----
            //         physical sector as "dirty."
            if(existingPhysicalSectorAddr != UNMAPPED_LOGICAL_SECTOR)

⌨️ 快捷键说明

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