📄 sectorinfo.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 + -