OcAppleDiskImageLib: Update the rest of the code style.

This commit is contained in:
Download-Fritz 2019-03-30 20:31:29 +01:00
parent c8c99a5a48
commit 48296d28c3
4 changed files with 506 additions and 529 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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