mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
OcAppleDiskImageLib: Update the rest of the code style.
This commit is contained in:
parent
c8c99a5a48
commit
48296d28c3
@ -25,6 +25,14 @@
|
||||
|
||||
#include "OcAppleDiskImageLibInternal.h"
|
||||
|
||||
#define DMG_CONTROLLER_DP_GUID \
|
||||
{ 0x957932CC, 0x7E8E, 0x433B, \
|
||||
{ 0x8F, 0x41, 0xD3, 0x91, 0xEA, 0x3C, 0x10, 0xF8 } }
|
||||
|
||||
#define DMG_SIZE_DP_GUID \
|
||||
{ 0x004B07E8, 0x0B9C, 0x427E, \
|
||||
{ 0xB0, 0xD4, 0xA4, 0x66, 0xE6, 0xE5, 0x7A, 0x62 } }
|
||||
|
||||
#define DMG_FILE_PATH_LEN (L_STR_LEN (L"DMG_.dmg") + 16 + 1)
|
||||
|
||||
#pragma pack(1)
|
||||
@ -70,6 +78,9 @@ typedef struct {
|
||||
RAM_DMG_HEADER *RamDmgHeader;
|
||||
} OC_APPLE_DISK_IMAGE_MOUNTED_DATA;
|
||||
|
||||
STATIC CONST EFI_GUID mDmgControllerDpGuid = DMG_CONTROLLER_DP_GUID;
|
||||
STATIC CONST EFI_GUID mDmgSizeDpGuid = DMG_SIZE_DP_GUID;
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
@ -158,7 +169,7 @@ InternalConstructDmgDevicePath (
|
||||
DevPath->Controller.Header.Type = HARDWARE_DEVICE_PATH;
|
||||
DevPath->Controller.Header.SubType = HW_VENDOR_DP;
|
||||
DevPath->Controller.Key = 0;
|
||||
CopyGuid (&DevPath->Controller.Guid, &gDmgControllerDpGuid);
|
||||
CopyGuid (&DevPath->Controller.Guid, &mDmgControllerDpGuid);
|
||||
SetDevicePathNodeLength (&DevPath->Controller, sizeof (DevPath->Controller));
|
||||
|
||||
DevPath->MemMap.Header.Type = HARDWARE_DEVICE_PATH;
|
||||
@ -180,8 +191,8 @@ InternalConstructDmgDevicePath (
|
||||
|
||||
DevPath->Size.Header.Type = MESSAGING_DEVICE_PATH;
|
||||
DevPath->Size.Header.SubType = MSG_VENDOR_DP;
|
||||
DevPath->Size.Guid = gDmgSizeDpGuid;
|
||||
DevPath->Size.Length = DmgSize;
|
||||
CopyGuid (&DevPath->Size.Guid, &mDmgSizeDpGuid);
|
||||
SetDevicePathNodeLength (&DevPath->Size, sizeof (DevPath->Size));
|
||||
|
||||
SetDevicePathEndNode (&DevPath->End);
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/OcAppleDiskImageLib.h>
|
||||
#include <Library/OcGuardLib.h>
|
||||
#include <Library/OcCompressionLib.h>
|
||||
|
||||
#include "OcAppleDiskImageLibInternal.h"
|
||||
@ -28,61 +27,63 @@ InternalSwapTrailerData (
|
||||
IN OUT APPLE_DISK_IMAGE_TRAILER *Trailer
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
ASSERT (Trailer != NULL);
|
||||
|
||||
Trailer->Signature = SwapBytes32 (Trailer->Signature);
|
||||
Trailer->Version = SwapBytes32 (Trailer->Version);
|
||||
Trailer->Signature = SwapBytes32 (Trailer->Signature);
|
||||
Trailer->Version = SwapBytes32 (Trailer->Version);
|
||||
Trailer->HeaderSize = SwapBytes32 (Trailer->HeaderSize);
|
||||
Trailer->Flags = SwapBytes32 (Trailer->Flags);
|
||||
Trailer->Flags = SwapBytes32 (Trailer->Flags);
|
||||
|
||||
// Swap main fields.
|
||||
Trailer->RunningDataForkOffset = SwapBytes64 (Trailer->RunningDataForkOffset);
|
||||
Trailer->DataForkOffset = SwapBytes64 (Trailer->DataForkOffset);
|
||||
Trailer->DataForkLength = SwapBytes64 (Trailer->DataForkLength);
|
||||
Trailer->RsrcForkOffset = SwapBytes64 (Trailer->RsrcForkOffset);
|
||||
Trailer->RsrcForkLength = SwapBytes64 (Trailer->RsrcForkLength);
|
||||
Trailer->SegmentNumber = SwapBytes32 (Trailer->SegmentNumber);
|
||||
Trailer->SegmentCount = SwapBytes32 (Trailer->SegmentCount);
|
||||
Trailer->DataForkOffset = SwapBytes64 (Trailer->DataForkOffset);
|
||||
Trailer->DataForkLength = SwapBytes64 (Trailer->DataForkLength);
|
||||
Trailer->RsrcForkOffset = SwapBytes64 (Trailer->RsrcForkOffset);
|
||||
Trailer->RsrcForkLength = SwapBytes64 (Trailer->RsrcForkLength);
|
||||
Trailer->SegmentNumber = SwapBytes32 (Trailer->SegmentNumber);
|
||||
Trailer->SegmentCount = SwapBytes32 (Trailer->SegmentCount);
|
||||
|
||||
// Swap data fork checksum.
|
||||
Trailer->DataForkChecksum.Type = SwapBytes32 (Trailer->DataForkChecksum.Type);
|
||||
Trailer->DataForkChecksum.Size = SwapBytes32 (Trailer->DataForkChecksum.Size);
|
||||
for (UINTN i = 0; i < APPLE_DISK_IMAGE_CHECKSUM_SIZE; i++)
|
||||
Trailer->DataForkChecksum.Data[i] = SwapBytes32 (Trailer->DataForkChecksum.Data[i]);
|
||||
for (Index = 0; Index < APPLE_DISK_IMAGE_CHECKSUM_SIZE; ++Index) {
|
||||
Trailer->DataForkChecksum.Data[Index] = SwapBytes32 (
|
||||
Trailer->DataForkChecksum.Data[Index]
|
||||
);
|
||||
}
|
||||
|
||||
// Swap XML info.
|
||||
Trailer->XmlOffset = SwapBytes64 (Trailer->XmlOffset);
|
||||
Trailer->XmlLength = SwapBytes64 (Trailer->XmlLength);
|
||||
|
||||
// Swap main checksum.
|
||||
Trailer->Checksum.Type = SwapBytes32 (Trailer->Checksum.Type);
|
||||
Trailer->Checksum.Size = SwapBytes32 (Trailer->Checksum.Size);
|
||||
for (UINTN i = 0; i < APPLE_DISK_IMAGE_CHECKSUM_SIZE; i++)
|
||||
Trailer->Checksum.Data[i] = SwapBytes32 (Trailer->Checksum.Data[i]);
|
||||
for (Index = 0; Index < APPLE_DISK_IMAGE_CHECKSUM_SIZE; ++Index) {
|
||||
Trailer->Checksum.Data[Index] = SwapBytes32 (Trailer->Checksum.Data[Index]);
|
||||
}
|
||||
|
||||
// Swap addition fields.
|
||||
Trailer->ImageVariant = SwapBytes32 (Trailer->ImageVariant);
|
||||
Trailer->SectorCount = SwapBytes64 (Trailer->SectorCount);
|
||||
Trailer->SectorCount = SwapBytes64 (Trailer->SectorCount);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
OcAppleDiskImageInitializeContext (
|
||||
IN VOID *Buffer,
|
||||
IN UINTN BufferLength,
|
||||
OUT OC_APPLE_DISK_IMAGE_CONTEXT **Context
|
||||
IN VOID *Buffer,
|
||||
IN UINTN BufferLength,
|
||||
OUT OC_APPLE_DISK_IMAGE_CONTEXT **Context
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
OC_APPLE_DISK_IMAGE_CONTEXT *DmgContext = NULL;
|
||||
UINTN DmgLength;
|
||||
UINT8 *BufferBytes = NULL;
|
||||
UINT8 *BufferBytesCurrent = NULL;
|
||||
APPLE_DISK_IMAGE_TRAILER *BufferTrailer;
|
||||
APPLE_DISK_IMAGE_TRAILER Trailer;
|
||||
UINT32 DmgBlockCount;
|
||||
OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT *DmgBlocks = NULL;
|
||||
UINT32 Crc32;
|
||||
EFI_STATUS Status;
|
||||
OC_APPLE_DISK_IMAGE_CONTEXT *DmgContext;
|
||||
UINTN TrailerOffset;
|
||||
UINT8 *BufferBytes;
|
||||
UINT8 *BufferBytesCurrent;
|
||||
APPLE_DISK_IMAGE_TRAILER *BufferTrailer;
|
||||
APPLE_DISK_IMAGE_TRAILER Trailer;
|
||||
UINT32 DmgBlockCount;
|
||||
OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT *DmgBlocks;
|
||||
UINT32 Crc32;
|
||||
UINT32 SwappedSig;
|
||||
|
||||
ASSERT (Buffer != NULL);
|
||||
ASSERT (BufferLength > 0);
|
||||
@ -92,86 +93,73 @@ OcAppleDiskImageInitializeContext (
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Look for trailer signature.
|
||||
//
|
||||
BufferBytes = (UINT8*)Buffer;
|
||||
BufferBytesCurrent = BufferBytes + BufferLength - sizeof (APPLE_DISK_IMAGE_TRAILER);
|
||||
SwappedSig = SwapBytes32 (APPLE_DISK_IMAGE_MAGIC);
|
||||
|
||||
BufferBytes = (UINT8*)Buffer;
|
||||
BufferTrailer = NULL;
|
||||
while (BufferBytesCurrent >= BufferBytes) {
|
||||
// Check for trailer signature.
|
||||
if (ReadUnaligned32 ((UINT32*)BufferBytesCurrent) == SwapBytes32 (APPLE_DISK_IMAGE_MAGIC)) {
|
||||
BufferTrailer = (APPLE_DISK_IMAGE_TRAILER*)BufferBytesCurrent;
|
||||
DmgLength = BufferBytesCurrent - BufferBytes + sizeof (APPLE_DISK_IMAGE_TRAILER);
|
||||
|
||||
for (
|
||||
BufferBytesCurrent = (BufferBytes + (BufferLength - sizeof (APPLE_DISK_IMAGE_TRAILER)));
|
||||
BufferBytesCurrent >= BufferBytes;
|
||||
--BufferBytesCurrent
|
||||
) {
|
||||
if (ReadUnaligned32 ((UINT32 *)BufferBytesCurrent) == SwappedSig) {
|
||||
BufferTrailer = (APPLE_DISK_IMAGE_TRAILER *)BufferBytesCurrent;
|
||||
TrailerOffset = (BufferBytesCurrent - BufferBytes);
|
||||
break;
|
||||
}
|
||||
|
||||
// Move to previous byte.
|
||||
BufferBytesCurrent--;
|
||||
}
|
||||
|
||||
//
|
||||
// If trailer not found, fail.
|
||||
//
|
||||
if (BufferTrailer == NULL)
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
//
|
||||
// Get trailer.
|
||||
//
|
||||
CopyMem (&Trailer, BufferTrailer, sizeof (APPLE_DISK_IMAGE_TRAILER));
|
||||
InternalSwapTrailerData (&Trailer);
|
||||
|
||||
//
|
||||
// Ensure signature and size are valid.
|
||||
//
|
||||
if (Trailer.Signature != APPLE_DISK_IMAGE_MAGIC ||
|
||||
Trailer.HeaderSize != sizeof (APPLE_DISK_IMAGE_TRAILER)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// If data fork checksum is CRC32, verify it.
|
||||
if (Trailer.DataForkChecksum.Type == APPLE_DISK_IMAGE_CHECKSUM_TYPE_CRC32) {
|
||||
Crc32 = CalculateCrc32 (
|
||||
((UINT8*)Buffer + Trailer.DataForkOffset),
|
||||
Trailer.DataForkLength
|
||||
);
|
||||
if (Crc32 != Trailer.DataForkChecksum.Data[0])
|
||||
return EFI_COMPROMISED_DATA;
|
||||
}
|
||||
|
||||
//
|
||||
// Ensure XML offset/length is valid and in range.
|
||||
//
|
||||
if (Trailer.XmlOffset == 0 || Trailer.XmlOffset >= (DmgLength - sizeof (APPLE_DISK_IMAGE_TRAILER)) ||
|
||||
Trailer.XmlLength == 0 || (Trailer.XmlOffset + Trailer.XmlLength) > (DmgLength - sizeof (APPLE_DISK_IMAGE_TRAILER))) {
|
||||
if (BufferTrailer == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Parse XML.
|
||||
//
|
||||
Status = ParsePlist (Buffer, Trailer.XmlOffset, Trailer.XmlLength, &DmgBlockCount, &DmgBlocks);
|
||||
if (EFI_ERROR(Status))
|
||||
return Status;
|
||||
CopyMem (&Trailer, BufferTrailer, sizeof (Trailer));
|
||||
InternalSwapTrailerData (&Trailer);
|
||||
|
||||
//
|
||||
// Allocate DMG file structure.
|
||||
//
|
||||
DmgContext = AllocateZeroPool (sizeof (OC_APPLE_DISK_IMAGE_CONTEXT));
|
||||
if (!DmgContext) {
|
||||
if (Trailer.HeaderSize != sizeof (APPLE_DISK_IMAGE_TRAILER)
|
||||
|| (Trailer.XmlOffset == 0)
|
||||
|| (Trailer.XmlOffset >= TrailerOffset)
|
||||
|| (Trailer.XmlLength == 0)
|
||||
|| ((Trailer.XmlOffset + Trailer.XmlLength) > TrailerOffset)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (Trailer.DataForkChecksum.Type == APPLE_DISK_IMAGE_CHECKSUM_TYPE_CRC32) {
|
||||
Crc32 = CalculateCrc32 (
|
||||
(BufferBytes + Trailer.DataForkOffset),
|
||||
Trailer.DataForkLength
|
||||
);
|
||||
if (Crc32 != Trailer.DataForkChecksum.Data[0]) {
|
||||
return EFI_COMPROMISED_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
Status = InternalParsePlist (
|
||||
Buffer,
|
||||
(UINT32)Trailer.XmlOffset,
|
||||
(UINT32)Trailer.XmlLength,
|
||||
&DmgBlockCount,
|
||||
&DmgBlocks
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
DmgContext = AllocateZeroPool (sizeof (*DmgContext));
|
||||
if (DmgContext == NULL) {
|
||||
FreePool (DmgBlocks);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
// Fill DMG file structure.
|
||||
DmgContext->Buffer = Buffer;
|
||||
DmgContext->Length = DmgLength;
|
||||
CopyMem (&(DmgContext->Trailer), &Trailer, sizeof (APPLE_DISK_IMAGE_TRAILER));
|
||||
DmgContext->Buffer = BufferBytes;
|
||||
DmgContext->Length = (TrailerOffset + sizeof (APPLE_DISK_IMAGE_TRAILER));
|
||||
DmgContext->BlockCount = DmgBlockCount;
|
||||
DmgContext->Blocks = DmgBlocks;
|
||||
DmgContext->Blocks = DmgBlocks;
|
||||
CopyMem (&DmgContext->Trailer, &Trailer, sizeof (DmgContext->Trailer));
|
||||
|
||||
*Context = DmgContext;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@ -181,142 +169,126 @@ OcAppleDiskImageFreeContext (
|
||||
IN OC_APPLE_DISK_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
UINT64 Index;
|
||||
OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT *CurrentBlockContext;
|
||||
UINT64 Index;
|
||||
OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT *CurrentBlockContext;
|
||||
|
||||
ASSERT (Context != NULL);
|
||||
|
||||
// Free blocks.
|
||||
if (Context->Blocks) {
|
||||
for (Index = 0; Index < Context->BlockCount; Index++) {
|
||||
// Get block.
|
||||
CurrentBlockContext = Context->Blocks + Index;
|
||||
for (Index = 0; Index < Context->BlockCount; ++Index) {
|
||||
CurrentBlockContext = &Context->Blocks[Index];
|
||||
|
||||
// Free block data.
|
||||
if (CurrentBlockContext->CfName != NULL)
|
||||
FreePool (CurrentBlockContext->CfName);
|
||||
if (CurrentBlockContext->Name != NULL)
|
||||
FreePool (CurrentBlockContext->Name);
|
||||
if (CurrentBlockContext->BlockData != NULL)
|
||||
FreePool(CurrentBlockContext->BlockData);
|
||||
}
|
||||
FreePool (Context->Blocks);
|
||||
FreePool (CurrentBlockContext->CfName);
|
||||
FreePool (CurrentBlockContext->Name);
|
||||
FreePool (CurrentBlockContext->BlockData);
|
||||
}
|
||||
|
||||
FreePool (Context->Blocks);
|
||||
FreePool (Context);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
OcAppleDiskImageRead(
|
||||
IN OC_APPLE_DISK_IMAGE_CONTEXT *Context,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN BufferSize,
|
||||
OUT VOID *Buffer) {
|
||||
OcAppleDiskImageRead (
|
||||
IN OC_APPLE_DISK_IMAGE_CONTEXT *Context,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN BufferSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// Create variables.
|
||||
EFI_STATUS Status;
|
||||
APPLE_DISK_IMAGE_BLOCK_DATA *BlockData;
|
||||
APPLE_DISK_IMAGE_CHUNK *Chunk;
|
||||
UINT64 ChunkTotalLength;
|
||||
UINT64 ChunkLength;
|
||||
UINT64 ChunkOffset;
|
||||
UINT8 *ChunkData;
|
||||
UINT8 *ChunkDataCurrent;
|
||||
|
||||
// Chunk to read.
|
||||
APPLE_DISK_IMAGE_BLOCK_DATA *BlockData;
|
||||
APPLE_DISK_IMAGE_CHUNK *Chunk;
|
||||
UINTN ChunkTotalLength;
|
||||
UINTN ChunkLength;
|
||||
UINTN ChunkOffset;
|
||||
UINT8 *ChunkData;
|
||||
UINT8 *ChunkDataCurrent;
|
||||
EFI_LBA LbaCurrent;
|
||||
EFI_LBA LbaOffset;
|
||||
EFI_LBA LbaLength;
|
||||
UINTN RemainingBufferSize;
|
||||
UINTN BufferChunkSize;
|
||||
UINT8 *BufferCurrent;
|
||||
|
||||
// Buffer.
|
||||
EFI_LBA LbaCurrent;
|
||||
EFI_LBA LbaOffset;
|
||||
EFI_LBA LbaLength;
|
||||
UINTN RemainingBufferSize;
|
||||
UINTN BufferChunkSize;
|
||||
UINT8 *BufferCurrent;
|
||||
UINTN OutSize;
|
||||
|
||||
// zlib data.
|
||||
UINTN OutSize;
|
||||
ASSERT (Context != NULL);
|
||||
ASSERT (Buffer != NULL);
|
||||
ASSERT (Lba < Context->Trailer.SectorCount);
|
||||
|
||||
ASSERT (Context != NULL);
|
||||
ASSERT (Buffer != NULL);
|
||||
ASSERT (Lba < Context->Trailer.SectorCount);
|
||||
LbaCurrent = Lba;
|
||||
RemainingBufferSize = BufferSize;
|
||||
BufferCurrent = Buffer;
|
||||
|
||||
// Read blocks.
|
||||
LbaCurrent = Lba;
|
||||
RemainingBufferSize = BufferSize;
|
||||
BufferCurrent = Buffer;
|
||||
while (RemainingBufferSize) {
|
||||
// Determine block in DMG.
|
||||
Status = GetBlockChunk(Context, LbaCurrent, &BlockData, &Chunk);
|
||||
if (EFI_ERROR(Status)) {
|
||||
while (RemainingBufferSize > 0) {
|
||||
Status = InternalGetBlockChunk (Context, LbaCurrent, &BlockData, &Chunk);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
LbaOffset = (LbaCurrent - DMG_SECTOR_START_ABS (BlockData, Chunk));
|
||||
LbaLength = (Chunk->SectorCount - LbaOffset);
|
||||
ChunkOffset = (LbaOffset * APPLE_DISK_IMAGE_SECTOR_SIZE);
|
||||
ChunkTotalLength = (Chunk->SectorCount * APPLE_DISK_IMAGE_SECTOR_SIZE);
|
||||
ChunkLength = (ChunkTotalLength - ChunkOffset);
|
||||
|
||||
BufferChunkSize = (UINTN)MIN (RemainingBufferSize, ChunkLength);
|
||||
|
||||
switch (Chunk->Type) {
|
||||
case APPLE_DISK_IMAGE_CHUNK_TYPE_ZERO:
|
||||
case APPLE_DISK_IMAGE_CHUNK_TYPE_IGNORE:
|
||||
{
|
||||
ZeroMem (BufferCurrent, BufferChunkSize);
|
||||
break;
|
||||
}
|
||||
|
||||
case APPLE_DISK_IMAGE_CHUNK_TYPE_RAW:
|
||||
{
|
||||
ChunkData = (Context->Buffer + BlockData->DataOffset + Chunk->CompressedOffset);
|
||||
ChunkDataCurrent = (ChunkData + ChunkOffset);
|
||||
|
||||
CopyMem (BufferCurrent, ChunkDataCurrent, BufferChunkSize);
|
||||
break;
|
||||
}
|
||||
|
||||
case APPLE_DISK_IMAGE_CHUNK_TYPE_ZLIB:
|
||||
{
|
||||
ChunkData = AllocateZeroPool (ChunkTotalLength);
|
||||
if (ChunkData == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
ChunkDataCurrent = ChunkData + ChunkOffset;
|
||||
OutSize = DecompressZLIB (
|
||||
ChunkData,
|
||||
ChunkTotalLength,
|
||||
(Context->Buffer + BlockData->DataOffset + Chunk->CompressedOffset),
|
||||
Chunk->CompressedLength
|
||||
);
|
||||
if (OutSize != ChunkTotalLength) {
|
||||
FreePool (ChunkData);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
CopyMem (BufferCurrent, ChunkDataCurrent, BufferChunkSize);
|
||||
FreePool (ChunkData);
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine offset into source DMG.
|
||||
LbaOffset = LbaCurrent - DMG_SECTOR_START_ABS(BlockData, Chunk);
|
||||
LbaLength = Chunk->SectorCount - LbaOffset;
|
||||
ChunkOffset = LbaOffset * APPLE_DISK_IMAGE_SECTOR_SIZE;
|
||||
ChunkTotalLength = (UINTN)Chunk->SectorCount * APPLE_DISK_IMAGE_SECTOR_SIZE;
|
||||
ChunkLength = ChunkTotalLength - ChunkOffset;
|
||||
|
||||
// If the buffer size is bigger than the chunk, there will be more chunks to get.
|
||||
BufferChunkSize = RemainingBufferSize;
|
||||
if (BufferChunkSize > ChunkLength)
|
||||
BufferChunkSize = ChunkLength;
|
||||
|
||||
// Determine type.
|
||||
switch(Chunk->Type) {
|
||||
// No data, write zeroes.
|
||||
case APPLE_DISK_IMAGE_CHUNK_TYPE_ZERO:
|
||||
case APPLE_DISK_IMAGE_CHUNK_TYPE_IGNORE:
|
||||
// Zero destination buffer.
|
||||
ZeroMem(BufferCurrent, BufferChunkSize);
|
||||
break;
|
||||
|
||||
// Raw data, write data as-is.
|
||||
case APPLE_DISK_IMAGE_CHUNK_TYPE_RAW:
|
||||
// Determine pointer to source data.
|
||||
ChunkData = (Context->Buffer + BlockData->DataOffset + Chunk->CompressedOffset);
|
||||
ChunkDataCurrent = ChunkData + ChunkOffset;
|
||||
|
||||
// Copy to destination buffer.
|
||||
CopyMem(BufferCurrent, ChunkDataCurrent, BufferChunkSize);
|
||||
ChunkData = ChunkDataCurrent = NULL;
|
||||
break;
|
||||
|
||||
// zlib-compressed data, inflate and write uncompressed data.
|
||||
case APPLE_DISK_IMAGE_CHUNK_TYPE_ZLIB:
|
||||
// Allocate buffer for inflated data.
|
||||
ChunkData = AllocateZeroPool(ChunkTotalLength);
|
||||
ChunkDataCurrent = ChunkData + ChunkOffset;
|
||||
OutSize = DecompressZLIB (
|
||||
ChunkData,
|
||||
ChunkTotalLength,
|
||||
(Context->Buffer + BlockData->DataOffset + Chunk->CompressedOffset),
|
||||
Chunk->CompressedLength
|
||||
);
|
||||
if (OutSize != ChunkTotalLength) {
|
||||
FreePool (ChunkData);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
// Copy to destination buffer.
|
||||
CopyMem(BufferCurrent, ChunkDataCurrent, BufferChunkSize);
|
||||
FreePool(ChunkData);
|
||||
ChunkData = ChunkDataCurrent = NULL;
|
||||
break;
|
||||
|
||||
// Unknown chunk type.
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
default:
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
// Move to next chunk.
|
||||
RemainingBufferSize -= BufferChunkSize;
|
||||
BufferCurrent += BufferChunkSize;
|
||||
LbaCurrent += LbaLength;
|
||||
}
|
||||
RemainingBufferSize -= BufferChunkSize;
|
||||
BufferCurrent += BufferChunkSize;
|
||||
LbaCurrent += LbaLength;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@ -12,56 +12,48 @@
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Protocol/BlockIo.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/OcAppleDiskImageLib.h>
|
||||
#include <Library/OcXmlLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
#include "OcAppleDiskImageLibInternal.h"
|
||||
|
||||
// DP GUIDs.
|
||||
EFI_GUID gDmgControllerDpGuid = DMG_CONTROLLER_DP_GUID;
|
||||
EFI_GUID gDmgSizeDpGuid = DMG_SIZE_DP_GUID;
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FindPlistDictChild(
|
||||
IN XML_NODE *Node,
|
||||
IN CHAR8 *KeyName,
|
||||
OUT XML_NODE **Key,
|
||||
OUT XML_NODE **Value) {
|
||||
// Create variables.
|
||||
UINT32 ChildCount;
|
||||
XML_NODE *ChildValue = NULL;
|
||||
XML_NODE *ChildKey = NULL;
|
||||
CONST CHAR8 *ChildKeyStr = NULL;
|
||||
InternalFindPlistDictChild (
|
||||
IN XML_NODE *Node,
|
||||
IN CHAR8 *KeyName,
|
||||
OUT XML_NODE **Key,
|
||||
OUT XML_NODE **Value
|
||||
)
|
||||
{
|
||||
UINT32 ChildCount;
|
||||
XML_NODE *ChildValue;
|
||||
XML_NODE *ChildKey;
|
||||
CONST CHAR8 *ChildKeyName;
|
||||
UINT32 Index;
|
||||
|
||||
ASSERT (Node != NULL);
|
||||
ASSERT (KeyName != NULL);
|
||||
ASSERT (Key != NULL);
|
||||
ASSERT (Value != NULL);
|
||||
ASSERT (Node != NULL);
|
||||
ASSERT (KeyName != NULL);
|
||||
ASSERT (Key != NULL);
|
||||
ASSERT (Value != NULL);
|
||||
|
||||
// Search for key.
|
||||
ChildCount = PlistDictChildren(Node);
|
||||
for (UINT32 i = 0; i < ChildCount; i++) {
|
||||
// Get child key/value and key name.
|
||||
ChildKey = PlistDictChild(Node, i, &ChildValue);
|
||||
ChildKeyStr = PlistKeyValue(ChildKey);
|
||||
ChildCount = PlistDictChildren (Node);
|
||||
for (Index = 0; Index < ChildCount; ++Index) {
|
||||
ChildKey = PlistDictChild (Node, Index, &ChildValue);
|
||||
ChildKeyName = PlistKeyValue (ChildKey);
|
||||
|
||||
// Check if key matches.
|
||||
if (ChildKeyStr && !AsciiStrCmp(ChildKeyStr, KeyName)) {
|
||||
*Key = ChildKey;
|
||||
*Value = ChildValue;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
if ((ChildKeyName != NULL)
|
||||
&& (AsciiStrCmp (ChildKeyName, KeyName) == 0)) {
|
||||
*Key = ChildKey;
|
||||
*Value = ChildValue;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, we couldn't find it.
|
||||
return EFI_NOT_FOUND;
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
STATIC
|
||||
@ -70,244 +62,280 @@ InternalSwapBlockData (
|
||||
IN OUT APPLE_DISK_IMAGE_BLOCK_DATA *BlockData
|
||||
)
|
||||
{
|
||||
APPLE_DISK_IMAGE_CHUNK *Chunk;
|
||||
APPLE_DISK_IMAGE_CHUNK *Chunk;
|
||||
UINT32 Index;
|
||||
|
||||
// Swap block fields.
|
||||
BlockData->Version = SwapBytes32(BlockData->Version);
|
||||
BlockData->SectorNumber = SwapBytes64(BlockData->SectorNumber);
|
||||
BlockData->SectorCount = SwapBytes64(BlockData->SectorCount);
|
||||
BlockData->DataOffset = SwapBytes64(BlockData->DataOffset);
|
||||
BlockData->BuffersNeeded = SwapBytes32(BlockData->BuffersNeeded);
|
||||
BlockData->BlockDescriptors = SwapBytes32(BlockData->BlockDescriptors);
|
||||
BlockData->Version = SwapBytes32 (BlockData->Version);
|
||||
BlockData->SectorNumber = SwapBytes64 (BlockData->SectorNumber);
|
||||
BlockData->SectorCount = SwapBytes64 (BlockData->SectorCount);
|
||||
BlockData->DataOffset = SwapBytes64 (BlockData->DataOffset);
|
||||
BlockData->BuffersNeeded = SwapBytes32 (BlockData->BuffersNeeded);
|
||||
BlockData->BlockDescriptors = SwapBytes32 (BlockData->BlockDescriptors);
|
||||
BlockData->Checksum.Type = SwapBytes32 (BlockData->Checksum.Type);
|
||||
BlockData->Checksum.Size = SwapBytes32 (BlockData->Checksum.Size);
|
||||
|
||||
// Swap checksum.
|
||||
BlockData->Checksum.Type = SwapBytes32(BlockData->Checksum.Type);
|
||||
BlockData->Checksum.Size = SwapBytes32(BlockData->Checksum.Size);
|
||||
for (UINTN i = 0; i < APPLE_DISK_IMAGE_CHECKSUM_SIZE; i++)
|
||||
BlockData->Checksum.Data[i] = SwapBytes32(BlockData->Checksum.Data[i]);
|
||||
for (Index = 0; Index < APPLE_DISK_IMAGE_CHECKSUM_SIZE; ++Index) {
|
||||
BlockData->Checksum.Data[Index] = SwapBytes32 (
|
||||
BlockData->Checksum.Data[Index]
|
||||
);
|
||||
}
|
||||
|
||||
// Swap chunks.
|
||||
BlockData->ChunkCount = SwapBytes32(BlockData->ChunkCount);
|
||||
for (UINT32 c = 0; c < BlockData->ChunkCount; c++) {
|
||||
Chunk = &BlockData->Chunks[c];
|
||||
Chunk->Type = SwapBytes32(Chunk->Type);
|
||||
Chunk->Comment = SwapBytes32(Chunk->Comment);
|
||||
Chunk->SectorNumber = SwapBytes64(Chunk->SectorNumber);
|
||||
Chunk->SectorCount = SwapBytes64(Chunk->SectorCount);
|
||||
Chunk->CompressedOffset = SwapBytes64(Chunk->CompressedOffset);
|
||||
Chunk->CompressedLength = SwapBytes64(Chunk->CompressedLength);
|
||||
}
|
||||
BlockData->ChunkCount = SwapBytes32 (BlockData->ChunkCount);
|
||||
|
||||
for (Index = 0; Index < BlockData->ChunkCount; ++Index) {
|
||||
Chunk = &BlockData->Chunks[Index];
|
||||
|
||||
Chunk->Type = SwapBytes32 (Chunk->Type);
|
||||
Chunk->Comment = SwapBytes32 (Chunk->Comment);
|
||||
Chunk->SectorNumber = SwapBytes64 (Chunk->SectorNumber);
|
||||
Chunk->SectorCount = SwapBytes64 (Chunk->SectorCount);
|
||||
Chunk->CompressedOffset = SwapBytes64 (Chunk->CompressedOffset);
|
||||
Chunk->CompressedLength = SwapBytes64 (Chunk->CompressedLength);
|
||||
}
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ParsePlist(
|
||||
IN VOID *Buffer,
|
||||
IN UINT64 XmlOffset,
|
||||
IN UINT64 XmlLength,
|
||||
OUT UINT32 *BlockCount,
|
||||
OUT OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT **Blocks) {
|
||||
InternalParsePlist (
|
||||
IN VOID *Buffer,
|
||||
IN UINT32 XmlOffset,
|
||||
IN UINT32 XmlLength,
|
||||
OUT UINT32 *BlockCount,
|
||||
OUT OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT **Blocks
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// Create variables.
|
||||
EFI_STATUS Status;
|
||||
CHAR8 *XmlPlistBuffer;
|
||||
XML_DOCUMENT *XmlPlistDoc;
|
||||
XML_NODE *NodeRoot;
|
||||
XML_NODE *NodeResourceForkKey;
|
||||
XML_NODE *NodeResourceForkValue;
|
||||
XML_NODE *NodeBlockListKey;
|
||||
XML_NODE *NodeBlockListValue;
|
||||
|
||||
// Plist buffer.
|
||||
CHAR8 *XmlPlistBuffer = NULL;
|
||||
XML_DOCUMENT *XmlPlistDoc = NULL;
|
||||
XML_NODE *XmlPlistNodeRoot = NULL;
|
||||
XML_NODE *XmlPlistNodeResourceForkKey = NULL;
|
||||
XML_NODE *XmlPlistNodeResourceForkValue = NULL;
|
||||
XML_NODE *XmlPlistNodeBlockListKey = NULL;
|
||||
XML_NODE *XmlPlistNodeBlockListValue = NULL;
|
||||
XML_NODE *NodeBlockDict;
|
||||
XML_NODE *BlockDictChildKey;
|
||||
XML_NODE *BlockDictChildValue;
|
||||
UINT32 BlockDictChildDataSize;
|
||||
|
||||
// Plist blocks.
|
||||
XML_NODE *XmlPlistNodeBlockDict = NULL;
|
||||
XML_NODE *XmlPlistBlockDictChildKey = NULL;
|
||||
XML_NODE *XmlPlistBlockDictChildValue = NULL;
|
||||
UINT32 XmlPlistBlockDictChildDataSize;
|
||||
UINT32 NumDmgBlocks;
|
||||
OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT *DmgBlocks;
|
||||
OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT *Block;
|
||||
|
||||
// DMG blocks.
|
||||
UINT32 DmgBlockCount;
|
||||
OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT *DmgBlocks;
|
||||
UINT32 Index;
|
||||
|
||||
OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT *Block;
|
||||
ASSERT (Buffer != NULL);
|
||||
ASSERT (XmlLength > 0);
|
||||
ASSERT (BlockCount != NULL);
|
||||
ASSERT (Blocks != NULL);
|
||||
|
||||
ASSERT (Buffer != NULL);
|
||||
ASSERT (XmlLength > 0);
|
||||
ASSERT (BlockCount != NULL);
|
||||
ASSERT (Blocks != NULL);
|
||||
XmlPlistDoc = NULL;
|
||||
|
||||
// Allocate buffer for plist and copy plist to it.
|
||||
XmlPlistBuffer = AllocateCopyPool(XmlLength, (UINT8*)Buffer + XmlOffset);
|
||||
if (!XmlPlistBuffer) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
XmlPlistBuffer = AllocateCopyPool (XmlLength, ((UINT8 *)Buffer + XmlOffset));
|
||||
if (XmlPlistBuffer == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
XmlPlistDoc = XmlDocumentParse (XmlPlistBuffer, XmlLength, FALSE);
|
||||
if (XmlPlistDoc == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
NodeRoot = PlistDocumentRoot (XmlPlistDoc);
|
||||
if (NodeRoot == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
Status = InternalFindPlistDictChild (
|
||||
NodeRoot,
|
||||
DMG_PLIST_RESOURCE_FORK_KEY,
|
||||
&NodeResourceForkKey,
|
||||
&NodeResourceForkValue
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
Status = InternalFindPlistDictChild (
|
||||
NodeResourceForkValue,
|
||||
DMG_PLIST_BLOCK_LIST_KEY,
|
||||
&NodeBlockListKey,
|
||||
&NodeBlockListValue
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
NumDmgBlocks = XmlNodeChildren (NodeBlockListValue);
|
||||
DmgBlocks = AllocateZeroPool (NumDmgBlocks * sizeof (*DmgBlocks));
|
||||
if (DmgBlocks == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < NumDmgBlocks; ++Index) {
|
||||
Block = &DmgBlocks[Index];
|
||||
|
||||
NodeBlockDict = XmlNodeChild (NodeBlockListValue, Index);
|
||||
|
||||
// TODO they are actually string.
|
||||
Status = InternalFindPlistDictChild (
|
||||
NodeBlockDict,
|
||||
DMG_PLIST_ATTRIBUTES,
|
||||
&BlockDictChildKey,
|
||||
&BlockDictChildValue
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
// Open plist and get root node.
|
||||
XmlPlistDoc = XmlDocumentParse(XmlPlistBuffer, (UINT32)XmlLength, FALSE);
|
||||
if (!XmlPlistDoc) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
XmlPlistNodeRoot = PlistDocumentRoot(XmlPlistDoc);
|
||||
if (!XmlPlistNodeRoot) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
PlistIntegerValue (
|
||||
BlockDictChildValue,
|
||||
&Block->Attributes,
|
||||
sizeof(Block->Attributes),
|
||||
FALSE
|
||||
);
|
||||
|
||||
Status = InternalFindPlistDictChild (
|
||||
NodeBlockDict,
|
||||
DMG_PLIST_CFNAME,
|
||||
&BlockDictChildKey,
|
||||
&BlockDictChildValue
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
// Get resource fork dictionary.
|
||||
Status = FindPlistDictChild(XmlPlistNodeRoot, DMG_PLIST_RESOURCE_FORK_KEY,
|
||||
&XmlPlistNodeResourceForkKey, &XmlPlistNodeResourceForkValue);
|
||||
if (EFI_ERROR(Status))
|
||||
goto DONE_ERROR;
|
||||
BlockDictChildDataSize = 0;
|
||||
PlistStringSize (BlockDictChildValue, &BlockDictChildDataSize);
|
||||
Block->CfName = AllocateZeroPool (BlockDictChildDataSize);
|
||||
if (Block->CfName == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
PlistStringValue (
|
||||
BlockDictChildValue,
|
||||
Block->CfName,
|
||||
&BlockDictChildDataSize
|
||||
);
|
||||
|
||||
// Get block list dictionary.
|
||||
Status = FindPlistDictChild(XmlPlistNodeResourceForkValue, DMG_PLIST_BLOCK_LIST_KEY,
|
||||
&XmlPlistNodeBlockListKey, &XmlPlistNodeBlockListValue);
|
||||
if (EFI_ERROR(Status))
|
||||
goto DONE_ERROR;
|
||||
|
||||
// Get block count and allocate space for blocks.
|
||||
DmgBlockCount = XmlNodeChildren(XmlPlistNodeBlockListValue);
|
||||
DmgBlocks = AllocateZeroPool(DmgBlockCount * sizeof(OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT));
|
||||
if (!DmgBlocks) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
Status = InternalFindPlistDictChild (
|
||||
NodeBlockDict,
|
||||
DMG_PLIST_NAME,
|
||||
&BlockDictChildKey,
|
||||
&BlockDictChildValue
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
// Get blocks in plist.
|
||||
for (UINT32 b = 0; b < DmgBlockCount; b++) {
|
||||
Block = &DmgBlocks[b];
|
||||
BlockDictChildDataSize = 0;
|
||||
PlistStringSize (BlockDictChildValue, &BlockDictChildDataSize);
|
||||
Block->Name = AllocateZeroPool (BlockDictChildDataSize);
|
||||
if (Block->Name == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
PlistStringValue (
|
||||
BlockDictChildValue,
|
||||
Block->Name,
|
||||
&BlockDictChildDataSize
|
||||
);
|
||||
|
||||
// Get dictionary.
|
||||
XmlPlistNodeBlockDict = XmlNodeChild(XmlPlistNodeBlockListValue, b);
|
||||
|
||||
// Get attributes. TODO they are actually string.
|
||||
Status = FindPlistDictChild(XmlPlistNodeBlockDict, DMG_PLIST_ATTRIBUTES,
|
||||
&XmlPlistBlockDictChildKey, &XmlPlistBlockDictChildValue);
|
||||
if (EFI_ERROR(Status))
|
||||
goto DONE_ERROR;
|
||||
PlistIntegerValue(XmlPlistBlockDictChildValue,
|
||||
&Block->Attributes, sizeof(Block->Attributes), FALSE);
|
||||
|
||||
// Get CFName node.
|
||||
Status = FindPlistDictChild(XmlPlistNodeBlockDict, DMG_PLIST_CFNAME,
|
||||
&XmlPlistBlockDictChildKey, &XmlPlistBlockDictChildValue);
|
||||
if (EFI_ERROR(Status))
|
||||
goto DONE_ERROR;
|
||||
|
||||
// Allocate CFName string and get it.
|
||||
XmlPlistBlockDictChildDataSize = 0;
|
||||
PlistStringSize(XmlPlistBlockDictChildValue, &XmlPlistBlockDictChildDataSize);
|
||||
Block->CfName = AllocateZeroPool(XmlPlistBlockDictChildDataSize);
|
||||
if (!Block->CfName) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
PlistStringValue(XmlPlistBlockDictChildValue,
|
||||
Block->CfName, &XmlPlistBlockDictChildDataSize);
|
||||
|
||||
// Get Name node.
|
||||
Status = FindPlistDictChild(XmlPlistNodeBlockDict, DMG_PLIST_NAME,
|
||||
&XmlPlistBlockDictChildKey, &XmlPlistBlockDictChildValue);
|
||||
if (EFI_ERROR(Status))
|
||||
goto DONE_ERROR;
|
||||
|
||||
// Allocate Name string and get it.
|
||||
XmlPlistBlockDictChildDataSize = 0;
|
||||
PlistStringSize(XmlPlistBlockDictChildValue, &XmlPlistBlockDictChildDataSize);
|
||||
Block->Name = AllocateZeroPool(XmlPlistBlockDictChildDataSize);
|
||||
if (!Block->Name) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
PlistStringValue(XmlPlistBlockDictChildValue,
|
||||
Block->Name, &XmlPlistBlockDictChildDataSize);
|
||||
|
||||
// Get ID.
|
||||
Status = FindPlistDictChild(XmlPlistNodeBlockDict, DMG_PLIST_ID,
|
||||
&XmlPlistBlockDictChildKey, &XmlPlistBlockDictChildValue);
|
||||
if (EFI_ERROR(Status))
|
||||
goto DONE_ERROR;
|
||||
PlistIntegerValue(XmlPlistBlockDictChildValue,
|
||||
&Block->Id, sizeof(Block->Id), FALSE);
|
||||
|
||||
// Get block data.
|
||||
Status = FindPlistDictChild(XmlPlistNodeBlockDict, DMG_PLIST_DATA,
|
||||
&XmlPlistBlockDictChildKey, &XmlPlistBlockDictChildValue);
|
||||
if (EFI_ERROR(Status))
|
||||
goto DONE_ERROR;
|
||||
|
||||
// Allocate block data and get it.
|
||||
XmlPlistBlockDictChildDataSize = 0;
|
||||
PlistDataSize(XmlPlistBlockDictChildValue, &XmlPlistBlockDictChildDataSize);
|
||||
Block->BlockData = AllocateZeroPool(XmlPlistBlockDictChildDataSize);
|
||||
if (!Block->BlockData) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
PlistDataValue(XmlPlistBlockDictChildValue,
|
||||
(UINT8*)Block->BlockData, &XmlPlistBlockDictChildDataSize);
|
||||
|
||||
InternalSwapBlockData (Block->BlockData);
|
||||
Status = InternalFindPlistDictChild (
|
||||
NodeBlockDict,
|
||||
DMG_PLIST_ID,
|
||||
&BlockDictChildKey,
|
||||
&BlockDictChildValue
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
// Success.
|
||||
*BlockCount = DmgBlockCount;
|
||||
*Blocks = DmgBlocks;
|
||||
Status = EFI_SUCCESS;
|
||||
goto DONE;
|
||||
PlistIntegerValue (
|
||||
BlockDictChildValue,
|
||||
&Block->Id,
|
||||
sizeof (Block->Id),
|
||||
FALSE
|
||||
);
|
||||
|
||||
Status = InternalFindPlistDictChild (
|
||||
NodeBlockDict,
|
||||
DMG_PLIST_DATA,
|
||||
&BlockDictChildKey,
|
||||
&BlockDictChildValue
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
BlockDictChildDataSize = 0;
|
||||
PlistDataSize (BlockDictChildValue, &BlockDictChildDataSize);
|
||||
Block->BlockData = AllocateZeroPool (BlockDictChildDataSize);
|
||||
if (Block->BlockData == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto DONE_ERROR;
|
||||
}
|
||||
|
||||
PlistDataValue (
|
||||
BlockDictChildValue,
|
||||
(UINT8*)Block->BlockData,
|
||||
&BlockDictChildDataSize
|
||||
);
|
||||
|
||||
InternalSwapBlockData (Block->BlockData);
|
||||
}
|
||||
|
||||
*BlockCount = NumDmgBlocks;
|
||||
*Blocks = DmgBlocks;
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
DONE_ERROR:
|
||||
|
||||
DONE:
|
||||
// Free XML.
|
||||
if (XmlPlistDoc)
|
||||
XmlDocumentFree(XmlPlistDoc);
|
||||
if (XmlPlistBuffer)
|
||||
FreePool(XmlPlistBuffer);
|
||||
return Status;
|
||||
if (XmlPlistDoc != NULL) {
|
||||
XmlDocumentFree (XmlPlistDoc);
|
||||
}
|
||||
|
||||
if (XmlPlistBuffer != NULL) {
|
||||
FreePool (XmlPlistBuffer);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetBlockChunk(
|
||||
IN OC_APPLE_DISK_IMAGE_CONTEXT *Context,
|
||||
IN EFI_LBA Lba,
|
||||
OUT APPLE_DISK_IMAGE_BLOCK_DATA **Data,
|
||||
OUT APPLE_DISK_IMAGE_CHUNK **Chunk) {
|
||||
InternalGetBlockChunk (
|
||||
IN OC_APPLE_DISK_IMAGE_CONTEXT *Context,
|
||||
IN EFI_LBA Lba,
|
||||
OUT APPLE_DISK_IMAGE_BLOCK_DATA **Data,
|
||||
OUT APPLE_DISK_IMAGE_CHUNK **Chunk
|
||||
)
|
||||
{
|
||||
UINT32 BlockIndex;
|
||||
UINT32 ChunkIndex;
|
||||
APPLE_DISK_IMAGE_BLOCK_DATA *BlockData;
|
||||
APPLE_DISK_IMAGE_CHUNK *BlockChunk;
|
||||
|
||||
// Create variables.
|
||||
APPLE_DISK_IMAGE_BLOCK_DATA *BlockData;
|
||||
APPLE_DISK_IMAGE_CHUNK *BlockChunk;
|
||||
for (BlockIndex = 0; BlockIndex < Context->BlockCount; ++BlockIndex) {
|
||||
BlockData = Context->Blocks[BlockIndex].BlockData;
|
||||
|
||||
// Search for chunk.
|
||||
for (UINT32 b = 0; b < Context->BlockCount; b++) {
|
||||
// Get block data.
|
||||
BlockData = Context->Blocks[b].BlockData;
|
||||
if ((Lba >= BlockData->SectorNumber) &&
|
||||
(Lba < (BlockData->SectorNumber + BlockData->SectorCount))) {
|
||||
for (ChunkIndex = 0; ChunkIndex < BlockData->ChunkCount; ++ChunkIndex) {
|
||||
BlockChunk = &BlockData->Chunks[ChunkIndex];
|
||||
|
||||
// Is the desired sector part of this block?
|
||||
if ((Lba >= BlockData->SectorNumber) &&
|
||||
(Lba < (BlockData->SectorNumber + BlockData->SectorCount))) {
|
||||
// Determine chunk.
|
||||
for (UINT32 c = 0; c < BlockData->ChunkCount; c++) {
|
||||
// Get chunk.
|
||||
BlockChunk = BlockData->Chunks + c;
|
||||
|
||||
// Is the desired sector part of this chunk?
|
||||
if ((Lba >= DMG_SECTOR_START_ABS(BlockData, BlockChunk)) &&
|
||||
(Lba < (DMG_SECTOR_START_ABS(BlockData, BlockChunk) + BlockChunk->SectorCount))) {
|
||||
// Found the chunk.
|
||||
*Data = BlockData;
|
||||
*Chunk = BlockChunk;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
if ((Lba >= DMG_SECTOR_START_ABS (BlockData, BlockChunk))
|
||||
&& (Lba < (DMG_SECTOR_START_ABS (BlockData, BlockChunk) + BlockChunk->SectorCount))) {
|
||||
*Data = BlockData;
|
||||
*Chunk = BlockChunk;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find chunk.
|
||||
return EFI_NOT_FOUND;
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
@ -13,103 +13,69 @@
|
||||
#ifndef APPLE_DISK_IMAGE_LIB_INTERNAL_H_
|
||||
#define APPLE_DISK_IMAGE_LIB_INTERNAL_H_
|
||||
|
||||
#include <Library/OcXmlLib.h>
|
||||
#define BASE_256B 0x0100U
|
||||
#define SIZE_512B 0x0200U
|
||||
|
||||
// Sizes.
|
||||
#define BASE_256B 0x100
|
||||
#define SIZE_512B 0x200
|
||||
#define DMG_SECTOR_START_ABS(b, c) (((b)->SectorNumber) + ((c)->SectorNumber))
|
||||
|
||||
// Used for determining absolute sector start within chunk.
|
||||
#define DMG_SECTOR_START_ABS(b, c) ((b->SectorNumber) + (c->SectorNumber))
|
||||
#define DMG_PLIST_RESOURCE_FORK_KEY "resource-fork"
|
||||
#define DMG_PLIST_BLOCK_LIST_KEY "blkx"
|
||||
#define DMG_PLIST_ATTRIBUTES "Attributes"
|
||||
#define DMG_PLIST_CFNAME "CFName"
|
||||
#define DMG_PLIST_DATA "Data"
|
||||
#define DMG_PLIST_ID "ID"
|
||||
#define DMG_PLIST_NAME "Name"
|
||||
|
||||
#define DMG_PLIST_RESOURCE_FORK_KEY "resource-fork"
|
||||
#define DMG_PLIST_BLOCK_LIST_KEY "blkx"
|
||||
#define DMG_PLIST_ATTRIBUTES "Attributes"
|
||||
#define DMG_PLIST_CFNAME "CFName"
|
||||
#define DMG_PLIST_DATA "Data"
|
||||
#define DMG_PLIST_ID "ID"
|
||||
#define DMG_PLIST_NAME "Name"
|
||||
|
||||
//
|
||||
// Device path stuff.
|
||||
//
|
||||
#pragma pack(1)
|
||||
|
||||
// DMG controller device path.
|
||||
#define DMG_CONTROLLER_DP_GUID { \
|
||||
0x957932CC, 0x7E8E, 0x433B, { 0x8F, 0x41, 0xD3, 0x91, 0xEA, 0x3C, 0x10, 0xF8 } \
|
||||
}
|
||||
extern EFI_GUID gDmgControllerDpGuid;
|
||||
|
||||
// DMG vendor device path node.
|
||||
typedef struct {
|
||||
typedef PACKED struct {
|
||||
EFI_DEVICE_PATH_PROTOCOL Header;
|
||||
EFI_GUID Guid;
|
||||
UINT32 Key;
|
||||
EFI_GUID Guid;
|
||||
UINT32 Key;
|
||||
} DMG_CONTROLLER_DEVICE_PATH;
|
||||
|
||||
// DMG size device path.
|
||||
#define DMG_SIZE_DP_GUID { \
|
||||
0x004B07E8, 0x0B9C, 0x427E, { 0xB0, 0xD4, 0xA4, 0x66, 0xE6, 0xE5, 0x7A, 0x62 } \
|
||||
}
|
||||
extern EFI_GUID gDmgSizeDpGuid;
|
||||
|
||||
// DMG size device path node.
|
||||
typedef struct {
|
||||
typedef PACKED struct {
|
||||
EFI_DEVICE_PATH_PROTOCOL Header;
|
||||
EFI_GUID Guid;
|
||||
UINT64 Length;
|
||||
EFI_GUID Guid;
|
||||
UINT64 Length;
|
||||
} DMG_SIZE_DEVICE_PATH;
|
||||
#pragma pack()
|
||||
|
||||
//
|
||||
// RAM DMG structures used by boot.efi.
|
||||
//
|
||||
#pragma pack(1)
|
||||
#define RAM_DMG_SIGNATURE 0x544E5458444D4152ULL // "RAMDXTNT"
|
||||
#define RAM_DMG_VERSION 0x010000U
|
||||
|
||||
#define RAM_DMG_SIGNATURE 0x544E5458444D4152ULL // "RAMDXTNT"
|
||||
#define RAM_DMG_VERSION 0x10000
|
||||
|
||||
// RAM DMG extent info.
|
||||
typedef struct {
|
||||
UINT64 Start;
|
||||
UINT64 Length;
|
||||
UINT64 Start;
|
||||
UINT64 Length;
|
||||
} RAM_DMG_EXTENT_INFO;
|
||||
|
||||
// RAM DMG header.
|
||||
typedef struct {
|
||||
UINT64 Signature;
|
||||
UINT32 Version;
|
||||
UINT32 ExtentCount;
|
||||
RAM_DMG_EXTENT_INFO ExtentInfo[0xFE];
|
||||
UINT64 Reserved;
|
||||
UINT64 Signature2;
|
||||
UINT64 Signature;
|
||||
UINT32 Version;
|
||||
UINT32 ExtentCount;
|
||||
RAM_DMG_EXTENT_INFO ExtentInfo[0xFE];
|
||||
UINT64 Reserved;
|
||||
UINT64 Signature2;
|
||||
} RAM_DMG_HEADER;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FindPlistDictChild(
|
||||
IN XML_NODE *Node,
|
||||
IN CHAR8 *KeyName,
|
||||
OUT XML_NODE **Key,
|
||||
OUT XML_NODE **Value);
|
||||
InternalParsePlist (
|
||||
IN VOID *Buffer,
|
||||
IN UINT32 XmlOffset,
|
||||
IN UINT32 XmlLength,
|
||||
OUT UINT32 *BlockCount,
|
||||
OUT OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT **Blocks
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ParsePlist(
|
||||
IN VOID *Buffer,
|
||||
IN UINT64 XmlOffset,
|
||||
IN UINT64 XmlLength,
|
||||
OUT UINT32 *BlockCount,
|
||||
OUT OC_APPLE_DISK_IMAGE_BLOCK_CONTEXT **Blocks);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetBlockChunk(
|
||||
IN OC_APPLE_DISK_IMAGE_CONTEXT *Context,
|
||||
IN EFI_LBA Lba,
|
||||
OUT APPLE_DISK_IMAGE_BLOCK_DATA **Data,
|
||||
OUT APPLE_DISK_IMAGE_CHUNK **Chunk);
|
||||
InternalGetBlockChunk (
|
||||
IN OC_APPLE_DISK_IMAGE_CONTEXT *Context,
|
||||
IN EFI_LBA Lba,
|
||||
OUT APPLE_DISK_IMAGE_BLOCK_DATA **Data,
|
||||
OUT APPLE_DISK_IMAGE_CHUNK **Chunk
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user