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

📄 sectorinfo.c

📁 AMD公司官方版FLASH文件系统。有详细说明文档和Windows仿真测试环境。
💻 C
字号:
/**
 * File: Sector.c
 * Description: This file contains a set of functions for 
 *   defining and using the sector architecture information
 *   that is supplied by the user for the specific application.
 * A local copy of DeviceArchitecture is created when using
 *   dms_SectorInfoDefineArchitecture.
 */

#include "SectorInfo.h"
#include "BlockTable.h"
#include <malloc.h>

/* local structures used only by functions in this file */
typedef struct {
	DWORD dwAddress;
	DWORD dwSize;
    DWORD dwBlockTableAddress;
    DWORD dwDataBlockAddress;
    WORD  wBlockCount;
} SECTOR_INFO;

/* file local variables */
static SECTOR_INFO* lpSectorInfo = NULL;
static WORD lwSectorCount = 0;
static WORD lwIndexOfLargestSector = 0;
static DWORD ldwLargestSectorSize = 0;
static DWORD ldwTotalSectorSize = 0;
static DWORD ldwTotalNumberOfBlocks = 0;

/* locally used functions */
WORD dms_lSectorInfoComputeBlockCount(DWORD dwSectorSize);

/**
 *  dms_SectorInfoDefineArchitecture
 *  Initialize all sector information functions
 *    must be called before any other functions in this
 *    file except dms_SectorInfoFinalize
 *  returns No_Error if initialization was sucessfull.
 */
DMS_STATUS dms_SectorInfoDefineArchitecture(SECTOR_DESCRIPTIOR *apDeviceArchitecture){
  WORD wSectorIndex;
  DMS_STATUS eTmpStatus;
  
  if (lpSectorInfo != NULL) {
    /* assume memory from old DeviceArchitecture needs freed */
    dms_SectorInfoFinalize();
  }
  /* count number of sectors */
  for(wSectorIndex = 0;!(   apDeviceArchitecture[wSectorIndex].dwAddress == 0
                         && apDeviceArchitecture[wSectorIndex].dwSize == 0); wSectorIndex++);
  lwSectorCount = wSectorIndex;
  if (wSectorIndex == 0) {
    return Invalid_Sector_Count;
  }
  /* Create local copy of DeviceArchitecture */
  lpSectorInfo = (SECTOR_INFO*) malloc(sizeof(SECTOR_INFO) * wSectorIndex);
  if (lpSectorInfo == NULL){
    return Out_Of_Memory_Error;
  }
  for(wSectorIndex = 0; wSectorIndex < lwSectorCount; wSectorIndex++) {
    lpSectorInfo[wSectorIndex].dwAddress = apDeviceArchitecture[wSectorIndex].dwAddress;
    lpSectorInfo[wSectorIndex].dwSize    = apDeviceArchitecture[wSectorIndex].dwSize   ;
    lpSectorInfo[wSectorIndex].dwBlockTableAddress
        = apDeviceArchitecture[wSectorIndex].dwAddress + sizeof(SECTOR_HEADER);
    lpSectorInfo[wSectorIndex].wBlockCount = dms_lSectorInfoComputeBlockCount(lpSectorInfo[wSectorIndex].dwSize);
    lpSectorInfo[wSectorIndex].dwDataBlockAddress = lpSectorInfo[wSectorIndex].dwBlockTableAddress 
    	+ sizeof(BLOCK_TABLE_ENTRY) * lpSectorInfo[wSectorIndex].wBlockCount;
  }
  /* Compute commonly used attributes of the DeviceArchitecture */
  ldwTotalSectorSize = 0;
  ldwLargestSectorSize = 0;
  for(wSectorIndex = 0; wSectorIndex < lwSectorCount; wSectorIndex++) {
    ldwTotalSectorSize += lpSectorInfo[wSectorIndex].dwSize;
    ldwTotalNumberOfBlocks += lpSectorInfo[wSectorIndex].wBlockCount;
    if (lpSectorInfo[wSectorIndex].dwSize > ldwLargestSectorSize){
      ldwLargestSectorSize = lpSectorInfo[wSectorIndex].dwSize;
      lwIndexOfLargestSector = wSectorIndex;
    }
  }
  /* Check validity of DeviceArchitecture */
  eTmpStatus = dms_SectorInfoCheckArchitectureValidity();
  if (eTmpStatus != No_Error) {
    dms_SectorInfoFinalize();
    return eTmpStatus;
  }
  return No_Error;
}

/**
 *  dms_SectorInfoFinalize
 *  Must be called when finished with dms software.
 *  This will free allocated memory and set dms_SectorInfoGetCount()
 *    to zero.
 *  After this function has been called no other functions in this 
 *    file may be called until dms_SectorInfoDefineArchecture is called
 *    again. 
 */
void dms_SectorInfoFinalize(void){
  if (lpSectorInfo != NULL){
    free(lpSectorInfo);
    lpSectorInfo = NULL;
  }
  lwSectorCount = 0;
  lwIndexOfLargestSector = 0;
  ldwLargestSectorSize = 0;
  ldwTotalSectorSize = 0;
  ldwTotalNumberOfBlocks = 0;
}

/**
 *  dms_SectorInfoGetIndexFromAddress
 *  Calculate the sector that is hosting the address.
 *  determines sector index that hosts the address.
 *  Returns Sector_Invalid_Address if address not found
 */
DMS_STATUS dms_SectorInfoGetIndexFromAddress(DWORD adwAddress, WORD *awSectorIndex){
  WORD	wSectorIndex;
  for (wSectorIndex = 0; wSectorIndex < dms_SectorInfoGetCount(); wSectorIndex++){
    if (   (adwAddress >= dms_SectorInfoGetAddress(wSectorIndex))
        && (adwAddress <= dms_SectorInfoGetEndingAddress(wSectorIndex))){
      (*awSectorIndex) = wSectorIndex;
      return No_Error;
    }
  }
  return Sector_Invalid_Address;
}

/**
 *  dms_SectorInfoIsValidAddress
 *  Returns 1 if the provided address is contained in the
 *  DeviceArchitecture
 */
WORD dms_SectorInfoIsValidAddress(DWORD adwAddress){
  WORD wUnused;
  if (dms_SectorInfoGetIndexFromAddress(adwAddress,&wUnused) == No_Error) return 1;
  else return 0;
}

/**
 *  dms_SectorInfoGetAddress
 *  Returns the address for the requested sector.
 *  NOTE: Sector Index must be valid otherwise result
 *    is undefined or function may crash.
 *  A valid index is >= 0 and < dms_SectorInfoGetCount()
 */
DWORD dms_SectorInfoGetAddress(WORD awSectorIndex){
  return lpSectorInfo[awSectorIndex].dwAddress;
}

/**
 *  dms_SectorInfoGetBlockTableAddress
 *  Returns the address of the Block Table in the requested sector.
 *  NOTE: Sector Index must be valid otherwise result
 *    is undefined or function may crash.
 *  A valid index is >= 0 and < dms_SectorInfoGetCount()
 */
DWORD dms_SectorInfoGetBlockTableAddress(WORD awSectorIndex){
  return lpSectorInfo[awSectorIndex].dwBlockTableAddress;
}

/**
 *  dms_SectorInfoGetBlockAddress
 *  Returns the address start of the Data Blocks in the requested sector.
 *  NOTE: Sector Index must be valid otherwise result
 *    is undefined or function may crash.
 *  A valid index is >= 0 and < dms_SectorInfoGetCount()
 */
DWORD dms_SectorInfoGetBlockAddress(WORD awSectorIndex, WORD awSectorBlockIndex){
  return lpSectorInfo[awSectorIndex].dwDataBlockAddress + awSectorBlockIndex * sizeof(DATABLOCK);
}

/**
 *  dms_SectorInfoGetEndingAddress
 *  Returns the last address for the requested sector.
 *  NOTE: Sector Index must be valid otherwise result
 *    is undefined or function may crash.
 *  A valid index is >= 0 and < dms_SectorInfoGetCount()
 */
DWORD dms_SectorInfoGetEndingAddress(WORD awSectorIndex){
  return lpSectorInfo[awSectorIndex].dwAddress 
       + lpSectorInfo[awSectorIndex].dwSize - 1;
}

/**
 *  dms_SectorInfoGetBlockCount
 *  Returns the number of blocks in the requested sector.
 *  NOTE: Sector Index must be valid otherwise result
 *    is undefined or function may crash. 
 *  A valid index is >= 0 and < dms_SectorInfoGetCount()
 */
WORD dms_SectorInfoGetBlockCount(WORD awSectorIndex){
  return lpSectorInfo[awSectorIndex].wBlockCount;
}

/**
 *  dms_SectorInfoGetSize
 *  Returns the size in bytes for the requested sector.
 *  NOTE: Sector Index must be valid otherwise result
 *    is undefined or function may crash. 
 *  A valid index is >= 0 and < dms_SectorInfoGetCount()
 */
DWORD dms_SectorInfoGetSize(WORD awSectorIndex){
  return lpSectorInfo[awSectorIndex].dwSize;
}

/**
 *  dms_SectorInfoGetCount
 *  Returns the number of sectors defined in DeviceArchitecture
 */
WORD dms_SectorInfoGetCount(void){
  return lwSectorCount;
}

/**
 *  dms_SectorInfoGetIndexOfLargestSector
 *  Returns the index of the first largest sector in
 *  DeviceArchecture
 */
WORD dms_SectorInfoGetIndexOfLargestSector(void){
  return lwIndexOfLargestSector;
}

/**
 *  dms_SectorInfoGetLargestSectorBlockCount
 *  Returns the size in bytes of the first largest sector in
 *  DeviceArchecture
 */
WORD dms_SectorInfoGetLargestSectorBlockCount(void){
  return lpSectorInfo[lwIndexOfLargestSector].wBlockCount;
}

/**
 *  dms_SectorInfoGetTotalSize
 *  Returns the sum of the sizes of all the sectors in
 *  DeviceArchecture
 */
DWORD dms_SectorInfoGetTotalSize(void){
  return ldwTotalSectorSize;
}

/**
 *  dms_SectorInfoGetTotalBlockCount
 *  Returns the total number of blocks in the 
 *  DeviceArchecture
 */
DWORD dms_SectorInfoGetTotalBlockCount(void){
  return ldwTotalNumberOfBlocks;
}

/**
 *  dms_SectorInfoCheckArchitectureValidity
 *  This function performs all checks on the DeviceArchitecture
 *    that are required for proper dms functionality.
 *  NOTE:  This function is called by dms_SectorInfoDefineArchitecture
 *    and should not be needed to be called by anything else.
 */
DMS_STATUS dms_SectorInfoCheckArchitectureValidity(void){
  WORD	wSectorIndexA;
  WORD	wSectorIndexB;
  DWORD dwSectorSize; 

  /*
   * Check to make sure that there are at least two or more sectors
   */
  if (dms_SectorInfoGetCount() < 2) {
    return Invalid_Sector_Count;
  }

  /*
   * Check that each sector size > 0
   * and that the block count > 0
   */
  for(wSectorIndexA = 0; wSectorIndexA < dms_SectorInfoGetCount(); wSectorIndexA++) {
    dwSectorSize = dms_SectorInfoGetSize(wSectorIndexA);
    if (dwSectorSize <= 0) {
      return Invalid_Sector_Size;
    }
    if (dms_lSectorInfoComputeBlockCount(dwSectorSize) <= 0){
      return Invalid_Sector_Size;
    }
  }

  /*
   * Check for over lapping addresses
   * algorithm:  If any sectors starting or ending address is between 
   *   another sectors starting or ending address then there is overlap.
   */
  for(wSectorIndexA = 0; wSectorIndexA < dms_SectorInfoGetCount(); wSectorIndexA++) {
    for(wSectorIndexB = 0; wSectorIndexB < dms_SectorInfoGetCount(); wSectorIndexB++) {
      if (wSectorIndexA != wSectorIndexB) {
        if (   (   (dms_SectorInfoGetAddress(wSectorIndexA) >= dms_SectorInfoGetAddress(wSectorIndexB))
                && (dms_SectorInfoGetAddress(wSectorIndexA) <= dms_SectorInfoGetEndingAddress(wSectorIndexB)))
            || (   (dms_SectorInfoGetEndingAddress(wSectorIndexA) >= dms_SectorInfoGetAddress(wSectorIndexB))
                && (dms_SectorInfoGetEndingAddress(wSectorIndexA) <= dms_SectorInfoGetEndingAddress(wSectorIndexB)))){
          return Sector_Address_Overlap;
        }
      }
    }
  }

  /* all checks passed */
  return No_Error;
}


/**
 * dms_lSectorInfoComputeBlockCount
 * Computes the number of blocks that will fit in a sector.
 * NOTE:  if dwSectorSize is < sizeof(SECTOR_HEADER) then function
 *   will return incorrect value because WORD is unsigned.  However
 *   the Validity check will catch this an fail.
 * NOTE:  if this equation changes it must also be changed in the 
 *   Validity check function.
 */
WORD dms_lSectorInfoComputeBlockCount(DWORD dwSectorSize){
  return (WORD) ( (dwSectorSize - sizeof(SECTOR_HEADER)) / 
                  (sizeof(BLOCK_TABLE_ENTRY) + sizeof(DATABLOCK)) );
}




⌨️ 快捷键说明

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