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

📄 log2physmap.cpp

📁 基于WINCE的文件系统FAL驱动
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                address; otherwise NULL if the secondary table doesn't exist.
------------------------------------------------------------------------------*/
PBYTE MappingTable::GetPhysicalSectorAddr(SECTOR_ADDR logicalSectorAddr, PSECTOR_ADDR pPhysicalSectorAddr)
{
    static DWORD dwSecondaryTableID = 0;
    static DWORD dwOffset = 0;

    //----- 0. Check the parameters to insure they are legitimate -----
    if(pPhysicalSectorAddr == NULL)
    {
        ReportError((TEXT("FLASHDRV.DLL:MappingTable::GetPhysicalSectorAddr() - Invalid parameter: pPhysicalSectorAddr == NULL\r\n")));
        return NULL;
    }

    *pPhysicalSectorAddr = UNMAPPED_LOGICAL_SECTOR;

    if (logicalSectorAddr < m_dwStartLogSector || logicalSectorAddr >= (m_dwStartLogSector + m_dwNumLogSectors))
    {
        ReportError((TEXT("FLASHDRV.DLL:MappingTable::GetPhysicalSectorAddr() - Logical sector(0x%x) is out of range\r\n"), logicalSectorAddr));
        return NULL;
    }

    //----- 1.  Rebase the logical sector that we are interested in before looking it up in the secondary table -----
    logicalSectorAddr -= m_dwStartLogSector;

    //----- 2. Determine the secondary table for this logical sector address -----
    //         NOTE: Notice that a shift operation is used to avoid a potentially expensive
    //               division operation if the # of sectors/secondary table is a power of 2
    if(m_bIsNumSectorsPerSecTableLog2)
    {
        dwSecondaryTableID = logicalSectorAddr >> m_dwNumSectorsPerSecTable;
    }else
    {
        dwSecondaryTableID = logicalSectorAddr / m_dwNumSectorsPerSecTable;
    }

	if (dwSecondaryTableID >= MASTER_TABLE_SIZE)
		goto GET_ERROR;

    //----- 3. If this logical sector's secondary table isn't setup, a logical --> physical mapping does NOT exist -----
    if(m_pDynamicLUT[dwSecondaryTableID] == NULL)
    {
        DEBUGMSG(ZONE_INIT, (TEXT("FLASHDRV.DLL:MappingTable::GetPhysicalSectorAddr() - Secondary table doesn't exist for logical sector 0x%x!!!\r\n"), logicalSectorAddr));
        *pPhysicalSectorAddr = 0xFFFFFFFF;      // Logical sector is NOT mapped to a physical sector...
        goto GET_ERROR;
    }

    //----- 4. Determine the offset within the secondary table for this logical sector address -----
    COMPUTE_OFFSET(logicalSectorAddr);

    //----- 5. Lookup the physical sector address in the secondary table -----
    //         NOTE: For performance reasons, all multiplications are avoided.  Hence, it is necessary to explicitly
    //               handle the four different cases for the physical sector address width.
    switch(m_cbPhysicalAddr)
    {
    case ONE_BYTE_PHYSICAL_ADDR:                //  0  >= FLASH media <= 2^8  sectors
        *pPhysicalSectorAddr  = MAX_PHYSICAL_ADDR_FOR_ONE_BYTES & (UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr));
        if(*pPhysicalSectorAddr == MAX_PHYSICAL_ADDR_FOR_ONE_BYTES)
        {
            *pPhysicalSectorAddr = 0xFFFFFFFF;  // Logical sector is NOT mapped to a physical sector...
        }
        break;

    case TWO_BYTE_PHYSICAL_ADDR:                // 2^8 >  FLASH media <= 2^16 sectors
        *pPhysicalSectorAddr  = MAX_PHYSICAL_ADDR_FOR_TWO_BYTES & ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr))<<8);
        *pPhysicalSectorAddr += (UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+1));
        if(*pPhysicalSectorAddr == MAX_PHYSICAL_ADDR_FOR_TWO_BYTES)
        {
            *pPhysicalSectorAddr = 0xFFFFFFFF;  // Logical sector is NOT mapped to a physical sector...
        }
        break;

    case THREE_BYTE_PHYSICAL_ADDR:              // 2^16 >  FLASH media <= 2^24 sectors
        *pPhysicalSectorAddr  = MAX_PHYSICAL_ADDR_FOR_THREE_BYTES & ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr))<<16);
        *pPhysicalSectorAddr += ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+1))<<8);
        *pPhysicalSectorAddr += (UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+2));
        if(*pPhysicalSectorAddr == MAX_PHYSICAL_ADDR_FOR_THREE_BYTES)
        {
            *pPhysicalSectorAddr = 0xFFFFFFFF;  // Logical sector is NOT mapped to a physical sector...
        }
        break;

    case FOUR_BYTE_PHYSICAL_ADDR:               // 2^24 > FLASH media <= 2^32 sectors
        *pPhysicalSectorAddr  = MAX_PHYSICAL_ADDR_FOR_FOUR_BYTES & ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr))<<24);
        *pPhysicalSectorAddr += ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+1))<<16);
        *pPhysicalSectorAddr += ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+2))<<8);
        *pPhysicalSectorAddr += (UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+3));
        break;
    }

    CELOG_GetPhysicalSectorAddr (logicalSectorAddr, *pPhysicalSectorAddr);

    return (PBYTE)(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr);

GET_ERROR:
    return NULL;
}



/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       MappingTable::MapLogicalSector()

Description:    Maps the specified logical sector address to the specified
                physical sector address.

Notes:          If the logical sector is already mapped to a physical sector,
                the secondary table is appropriately updated with the new
                physical sector address.

Returns:        Pointer to the position in secondary table containing physical sector
                address; otherwise NULL if the secondary table doesn't exist.
------------------------------------------------------------------------------*/
PBYTE MappingTable::MapLogicalSector(SECTOR_ADDR logicalSectorAddr, SECTOR_ADDR physicalSectorAddr,
                           PSECTOR_ADDR pExistingPhysicalSectorAddr)

{
    static PBYTE       pMappedPhysicalSectorAddr  = 0;
    static DWORD       dwSecondaryTableID         = 0;

    //----- 0. Check the parameters to insure they are legitimate -----
    if(pExistingPhysicalSectorAddr == NULL)
    {
        ReportError((TEXT("FLASHDRV.DLL:MappingTable::MapLogicalSector() - Invalid parameter: pExistingPhysicalSectorAddr == NULL\r\n")));
        return NULL;
    }

    *pExistingPhysicalSectorAddr = UNMAPPED_LOGICAL_SECTOR;

    if (logicalSectorAddr < m_dwStartLogSector || logicalSectorAddr >= (m_dwStartLogSector + m_dwNumLogSectors))
    {
        ReportError((TEXT("FLASHDRV.DLL:MappingTable::MapLogicalSector() - Logical sector(0x%x) is out of range\r\n"), logicalSectorAddr));
        return NULL;
    }

    //----- 1. Get a pointer to the mapped physical sector address in our secondary table -----
    pMappedPhysicalSectorAddr = GetPhysicalSectorAddr(logicalSectorAddr, pExistingPhysicalSectorAddr);

    //----- 2.  Rebase the logical sector that we are interested in before looking it up in the secondary table -----
    logicalSectorAddr -= m_dwStartLogSector;

    if(pMappedPhysicalSectorAddr == NULL)
    {
        //----- 3. Secondary table for this logical sector address does NOT exist, let's create it... -----
        //         NOTE: Notice that a shift operation is used to avoid a potentially expensive
        //               division operation if the # of sectors/secondary table is a power of 2
        if(m_bIsNumSectorsPerSecTableLog2)
        {
            dwSecondaryTableID = logicalSectorAddr >> m_dwNumSectorsPerSecTable;
        }else
        {
            dwSecondaryTableID = logicalSectorAddr / m_dwNumSectorsPerSecTable;
        }

		if (dwSecondaryTableID >= MASTER_TABLE_SIZE)
			goto MAPPING_ERROR;

        if((m_pDynamicLUT[dwSecondaryTableID] = (PBYTE)LocalAlloc(LMEM_FIXED, m_dwSecondaryTableSize)) == NULL)
        {
            ReportError((TEXT("FLASHDRV.DLL:MapLogicalSector() - Unable to allocate secondary table for logical sector %d\r\n"), logicalSectorAddr));
            goto MAPPING_ERROR;
        }

        //----- 4. Initialize the secondary table so that all logical sector addresses are unmapped (physical sector address is all '1's) -----
        memset(m_pDynamicLUT[dwSecondaryTableID], 0xFF, m_dwSecondaryTableSize);

        //----- 5. Determine the offset within the secondary table for this logical sector address -----
        COMPUTE_OFFSET(logicalSectorAddr);

        //----- 6. Get a pointer to the position in the secondary table that stores the physical sector address -----
        pMappedPhysicalSectorAddr = (PBYTE)(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr);
    }

    //----- 7. Map the specified logical sector address to the specified physical sector address -----
    //         NOTE: For performance reasons, all multiplications are avoided.  Hence, it is necessary to explicitly
    //               handle the four different cases for the physical sector address width.
    switch(m_cbPhysicalAddr)
    {
    case ONE_BYTE_PHYSICAL_ADDR:                //  0  >= FLASH media <= 2^8  sectors
        *pMappedPhysicalSectorAddr     = (UCHAR)physicalSectorAddr;
        break;

    case TWO_BYTE_PHYSICAL_ADDR:                // 2^8 >  FLASH media <= 2^16 sectors
        *pMappedPhysicalSectorAddr     = (UCHAR)(physicalSectorAddr>>8);
        *(pMappedPhysicalSectorAddr+1) = (UCHAR)(physicalSectorAddr);
        break;

    case THREE_BYTE_PHYSICAL_ADDR:              // 2^16 > FLASH media <= 2^24 sectors
        *pMappedPhysicalSectorAddr     = (UCHAR)(physicalSectorAddr>>16);
        *(pMappedPhysicalSectorAddr+1) = (UCHAR)(physicalSectorAddr>>8);
        *(pMappedPhysicalSectorAddr+2) = (UCHAR)(physicalSectorAddr);
        break;

    case FOUR_BYTE_PHYSICAL_ADDR:               // 2^24 > FLASH media <= 2^32 sectors
        *pMappedPhysicalSectorAddr     = (UCHAR)(physicalSectorAddr>>24);
        *(pMappedPhysicalSectorAddr+1) = (UCHAR)(physicalSectorAddr>>16);
        *(pMappedPhysicalSectorAddr+2) = (UCHAR)(physicalSectorAddr>>8);
        *(pMappedPhysicalSectorAddr+3) = (UCHAR)(physicalSectorAddr);
        break;
    }

    CELOG_MapLogicalSector(logicalSectorAddr, physicalSectorAddr, *pMappedPhysicalSectorAddr);

    return pMappedPhysicalSectorAddr;

MAPPING_ERROR:
    return NULL;
}



//--------------------------------------- Helper Functions ------------------------------------
BOOL MappingTable::IsValidLogicalSector(SECTOR_ADDR logicalSectorAddr)
{
    if (logicalSectorAddr < m_dwStartLogSector || logicalSectorAddr >= (m_dwStartLogSector + m_dwNumLogSectors))
        return FALSE;
    else
        return TRUE;
}


⌨️ 快捷键说明

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