helper.cpp
来自「WinCE5.0部分核心源码」· C++ 代码 · 共 1,836 行 · 第 1/5 页
CPP
1,836 行
DWORD *tmpbuffer;
int numEntries = 0;
if (pChecksum)
*pChecksum = 0;
tmpbuffer = (DWORD *)(buffer + STORESTART);
numEntries = ((DriverState *)tmpbuffer)->dwNumParts;
if (!numEntries)
return TRUE;
// this is the max # of partitions we'll hold, if the count is larger, the sector is hosed
if (numEntries > HIDDEN_PART_SEC_COUNT*3)
return FALSE;
numEntries *= sizeof(OnDiskPartState);
// # DWORDS to checksum
numEntries >>= 2;
tmpbuffer = (DWORD *)(buffer + STORESTART + offsetof(DriverState, hDsk));
// simple DWORD checksum - don't worry about overflow
while (numEntries)
{
dwChecksum += tmpbuffer[numEntries];
numEntries --;
}
if (pChecksum)
*pChecksum = dwChecksum;
tmpbuffer = (DWORD *)(buffer + STORESTART);
if (((DriverState *)tmpbuffer)->dwChecksum == dwChecksum)
return TRUE;
else
return FALSE;
}
/*****************************************************************************
* CreatePBR - creates a partition boot record within the extended partition
* and links it to the previous and next partition if they apply.
*
* Input: state - structure for this store
* snLastPBRSec - LBA of the PBR that points to this PBR
* snNextPBRSec - LBA of the PBR that this PBR will point to
* snPBRSector - LBA of this PBR
* snNumSectors - number of sectors for this partition
* fileSysType - partition type of this partition
*
* Output: none
*
* Return: TRUE if PBR created successfully, FALSE if not
*
*****************************************************************************/
BOOL CreatePBR(DriverState *state, SECTORNUM snLastPBRSec, SECTORNUM snNextPBRSec, SECTORNUM snPBRSector, SECTORNUM snNumSectors, BYTE fileSysType)
{
BOOL bResult;
PBYTE buffer=NULL, buffer1=NULL;
PPARTENTRY tmpbuffer, tmpbuffer1;
SECTORNUM snDataStart;
// the partition data starts at the next head location
if (state->diskInfo.di_heads > 1)
snDataStart = snPBRSector + state->diskInfo.di_sectors;
else
snDataStart = snPBRSector + 1;
buffer = (PBYTE)LocalAlloc(LMEM_ZEROINIT, state->diskInfo.di_bytes_per_sect);
if (!buffer)
return FALSE;
// set the trailer signature for the EBR
*(WORD *)(buffer + BOOT_SIGNATURE) = BOOTSECTRAILSIGH;
tmpbuffer = (PPARTENTRY)(buffer + PARTTABLE_OFFSET);
// build up the entry for the new PBR first
bResult = ConvertLBAtoCHS (state, snDataStart, &tmpbuffer->Part_FirstTrack, &tmpbuffer->Part_FirstHead, &tmpbuffer->Part_FirstSector);
bResult = ConvertLBAtoCHS (state, snPBRSector + snNumSectors -1, &tmpbuffer->Part_LastTrack, &tmpbuffer->Part_LastHead, &tmpbuffer->Part_LastSector);
tmpbuffer->Part_FileSystem = fileSysType;
// start sector of the data area is relative to the beginning of the logical drive
if (state->diskInfo.di_heads > 1)
tmpbuffer->Part_StartSector = state->diskInfo.di_sectors;
else
tmpbuffer->Part_StartSector = 1;
// sector count does not include the PBR sector(s)
tmpbuffer->Part_TotalSectors =(DWORD)snNumSectors - tmpbuffer->Part_StartSector;
if (snNextPBRSec)
{
buffer1 = NULL;
bResult = ReadSectors (state, snNextPBRSec, 1, &buffer1);
if (!bResult)
{
LocalFree(buffer);
return FALSE;
}
tmpbuffer1 = (PPARTENTRY)(buffer + PARTTABLE_OFFSET);
// if we're hooking in between two logical drives, we need an entry in this PBR to point to the next one
tmpbuffer++;
// start sector of the data area is relative to the beginning of the logical drive
tmpbuffer->Part_StartSector = (DWORD)(snNextPBRSec - state->snExtPartSector);
// sector count comes from the length of the next logical drive
tmpbuffer->Part_TotalSectors = tmpbuffer1->Part_StartSector + tmpbuffer1->Part_TotalSectors;
bResult = ConvertLBAtoCHS (state, snNextPBRSec, &tmpbuffer->Part_FirstTrack, &tmpbuffer->Part_FirstHead, &tmpbuffer->Part_FirstSector);
bResult = ConvertLBAtoCHS (state, snNextPBRSec + tmpbuffer->Part_TotalSectors -1, &tmpbuffer->Part_LastTrack, &tmpbuffer->Part_LastHead, &tmpbuffer->Part_LastSector);
// the file system type for the next logical drive is always the extended partition type, not the actual FS type
tmpbuffer->Part_FileSystem = PART_EXTENDED;
LocalFree(buffer1);
}
bResult = WriteSectors(state, snPBRSector, 1, buffer);
LocalFree(buffer);
if (!bResult)
return FALSE;
// We have successfully written out the new PBR and (possibly) linked it to the next one in the chain
// The last thing that needs to be done is hook this into the previous PBR if it exists
if (!snLastPBRSec)
return TRUE;
buffer = NULL;
bResult = ReadSectors (state, snLastPBRSec, 1, &buffer);
if (!bResult)
return FALSE;
tmpbuffer = (PPARTENTRY)(buffer + PARTTABLE_OFFSET + sizeof(PARTENTRY));
bResult = ConvertLBAtoCHS (state, snPBRSector, &tmpbuffer->Part_FirstTrack, &tmpbuffer->Part_FirstHead, &tmpbuffer->Part_FirstSector);
bResult = ConvertLBAtoCHS (state, snPBRSector + snNumSectors -1, &tmpbuffer->Part_LastTrack, &tmpbuffer->Part_LastHead, &tmpbuffer->Part_LastSector);
tmpbuffer->Part_FileSystem = PART_EXTENDED;
// start sector of the data area is relative to the beginning of the logical drive
tmpbuffer->Part_StartSector = (DWORD)(snPBRSector - state->snExtPartSector);
// sector count comes from the length of the next logical drive and includes the PBR track
tmpbuffer->Part_TotalSectors = (DWORD)snNumSectors;
bResult = WriteSectors(state, snLastPBRSec, 1, buffer);
LocalFree(buffer);
if (!bResult)
return FALSE;
return TRUE;
}
/*****************************************************************************
* Delete PBR - deletes the partition boot record for the partition and updates
* the previous PBR if one exists.
*
* Input: state - structure for this store
* pPartState - partition structure for the PBR to delete
* pPrevPartState - partition structure for the partition that preceeds
* the partition being deleted
*
* Output: none
*
*
* Return: TRUE if PBR successfully deleted, FALSE if not
*
*****************************************************************************/
BOOL DeletePBR(DriverState *state, PartState *pPartState, PartState *pPrevPartState)
{
BOOL bResult;
PBYTE buffer = NULL, buffer1 = NULL;
PPARTENTRY tmpbuffer, tmpbuffer1;
// first get the PBR sector for the logical drive that's being deleted
bResult = ReadSectors (state, pPartState->snPBRSector, 1, &buffer);
if (!bResult)
{
LocalFree(buffer);
return FALSE;
}
// if this logical drive follows another logical drive, the previous PBR needs to be updated
if (pPrevPartState && pPrevPartState->snPBRSector)
{
buffer1 = NULL;
bResult = ReadSectors (state, pPrevPartState->snPBRSector, 1, &buffer1);
if (!bResult)
{
LocalFree(buffer);
return FALSE;
}
// copy the partition entry that points to the next logical drive (from the PBR being deleted)
// and update the previous PBR to point to it
tmpbuffer = (PPARTENTRY)(buffer + PARTTABLE_OFFSET + sizeof(PARTENTRY));
tmpbuffer1 = (PPARTENTRY)(buffer1 + PARTTABLE_OFFSET + sizeof(PARTENTRY));
memcpy(tmpbuffer1, tmpbuffer, sizeof(PARTENTRY));
// update the previous PBR - which removes the link to the part being deleted
bResult = WriteSectors(state, pPrevPartState->snPBRSector, 1, buffer1);
LocalFree(buffer1);
if (!bResult)
{
LocalFree(buffer);
return FALSE;
}
// zero out the old PBR so it isn't mistakenly used as a PBR anymore by some ill behaved code
memset(buffer, 0, state->diskInfo.di_bytes_per_sect);
bResult = WriteSectors(state, pPartState->snPBRSector, 1, buffer);
}
else
{
// this is the first logical drive in the extended partition - all that needs to be done is zero
// the entry for this logical drive, the pointer to the next logical drive remains in tact
// at part entry 2
tmpbuffer = (PPARTENTRY)(buffer + PARTTABLE_OFFSET);
memset(tmpbuffer, 0, sizeof(PARTENTRY));
bResult = WriteSectors(state, pPartState->snPBRSector, 1, buffer);
}
LocalFree(buffer);
return bResult;
}
/*****************************************************************************
* UpdateMBR - updates the size of an entry in the MBR.
*
* Input: state - structure for this store
* pPartState - partition structure for the partition to update
*
* Output: none
*
*
* Return: TRUE if MBR updated successfully, FALSE if not
*
*****************************************************************************/
BOOL UpdateMBR(DriverState *state, PartState *pPartState)
{
PBYTE buffer = NULL;
PPARTENTRY tmpbuffer;
BOOL bResult;
int i;
bResult = ReadSectors (state, 0, 1, &buffer);
if (!bResult)
return FALSE;
for (i = 0, tmpbuffer = (PPARTENTRY)(buffer + PARTTABLE_OFFSET); i < 4; i++, tmpbuffer++) {
if (tmpbuffer->Part_StartSector == pPartState->snStartSector)
break;
}
if (i >= 4)
{
// for some reason we didn't find the partition we're trying to delete - this should never happen
LocalFree(buffer);
SetLastError(ERROR_GEN_FAILURE);
return FALSE;
}
// update the partition info
bResult = ConvertLBAtoCHS (state, (DWORD)pPartState->snStartSector, &tmpbuffer->Part_FirstTrack, &tmpbuffer->Part_FirstHead, &tmpbuffer->Part_FirstSector);
tmpbuffer->Part_FileSystem = pPartState->partType;
tmpbuffer->Part_StartSector = (DWORD)pPartState->snStartSector;
tmpbuffer->Part_TotalSectors = (DWORD)pPartState->snNumSectors;
bResult = ConvertLBAtoCHS (state, tmpbuffer->Part_StartSector + tmpbuffer->Part_TotalSectors -1, &tmpbuffer->Part_LastTrack, &tmpbuffer->Part_LastHead, &tmpbuffer->Part_LastSector);
bResult = WriteSectors(state, 0, 1, buffer);
LocalFree(buffer);
return bResult;
}
/*****************************************************************************
* DeleteMBR - deletes a partition entry in the master boot record - all
* partition records that follow the one to be deleted are shifted back 1
* entry so no holes exist in the MBR.
*
* Input: state - structure for this store
* pPartState - partition structure for the partition to delete
*
* Output: none
*
*
* Return: TRUE if MBR updated successfully, FALSE if not
*
*****************************************************************************/
BOOL DeleteMBR(DriverState *state, PartState *pPartState)
{
PBYTE buffer = NULL;
PPARTENTRY tmpbuffer, tmpbuffer1;
BOOL bResult;
int i, partNum, partIndex = -1;
bResult = ReadSectors (state, 0, 1, &buffer);
if (!bResult)
return FALSE;
for (i = 0, partNum = 3, tmpbuffer = (PPARTENTRY)(buffer + PARTTABLE_OFFSET); i < 4; i++, tmpbuffer++) {
if (tmpbuffer->Part_StartSector == pPartState->snStartSector)
partIndex = i;
if (tmpbuffer->Part_TotalSectors == 0)
{
partNum = i - 1;
break;
}
}
if ((partIndex == -1 || partNum == -1))
{
// for some reason we didn't find the partition we're trying to delete - this should never happen
LocalFree(buffer);
SetLastError(ERROR_GEN_FAILURE);
return FALSE;
}
tmpbuffer = (PPARTENTRY)(buffer + PARTTABLE_OFFSET + (partIndex * sizeof(PARTENTRY)));
tmpbuffer1 = (PPARTENTRY)(buffer + PARTTABLE_OFFSET + ((partIndex +1) * sizeof(PARTENTRY)));
// remove this partition entry by shifting all the others up in the table
for (; partIndex < partNum; partIndex++)
{
memcpy(tmpbuffer, tmpbuffer1, sizeof(PARTENTRY));
tmpbuffer++;
tmpbuffer1++;
}
// set the last entry to 0's
memset (tmpbuffer, 0, sizeof(PARTENTRY));
bResult = WriteSectors(state, 0, 1, buffer);
LocalFree(buffer);
return bResult;
}
/*****************************************************************************
* WriteMBR - adds a partition entry to the master boot record. The partition
* table is traversed to find the placement for this partition. Entries within
* the MBR are sorted by the start sector.
*
* Input: state - structure for this store
* snSectorNum - start sector number for this partition
* snNumSectors - number of sectors in this partition
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?