Exemplo n.º 1
0
/*==========================================================================
 * Utility function to make a device tree string from an EFI_GUID
 */
static inline char * mallocStringForGuid(EFI_GUID const *pGuid)
{
	char *string = malloc(37);
	efi_guid_unparse_upper(pGuid, string);
	return string;
}
Exemplo n.º 2
0
BVRef diskScanGPTBootVolumes(int biosdev, int * countPtr)
{
    _DISK_DEBUG_DUMP("In diskScanGPTBootVolumes(%d)\n", biosdev);

    void *buffer = malloc(BPS);

    if (readBytes(biosdev, 1, 0, BPS, buffer) == 0)
    {
        int gptID = 1;

        gpt_ent * gptMap = 0;
        gpt_hdr * headerMap = buffer;

        // Partition header signature present?
        if (memcmp(headerMap->hdr_sig, GPT_HDR_SIG, strlen(GPT_HDR_SIG)) == 0)
        {
            UInt32 headerSize = OSSwapLittleToHostInt32(headerMap->hdr_size);

            // Valid partition header size?
            if (headerSize >= offsetof(gpt_hdr, padding))
            {
                // No header size overrun (limiting to 512 bytes)?
                if (headerSize <= BPS)
                {
                    UInt32 headerCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_self);

                    headerMap->hdr_crc_self = 0;

                    // Valid partition header checksum?
                    if (crc32(0, headerMap, headerSize) == headerCheck)
                    {
                        UInt64	gptBlock = OSSwapLittleToHostInt64(headerMap->hdr_lba_table);
                        UInt32	gptCount = OSSwapLittleToHostInt32(headerMap->hdr_entries);
                        UInt32	gptSize  = OSSwapLittleToHostInt32(headerMap->hdr_entsz);

                        free(buffer);

                        if (gptSize >= sizeof(gpt_ent))
                        {
                            UInt32 bufferSize = IORound(gptCount * gptSize, BPS);

                            buffer = malloc(bufferSize); // Allocate a buffer.

                            if (readBytes(biosdev, gptBlock, 0, bufferSize, buffer) == 0)
                            {
                                // Allocate a new map for this device and insert it into the chain.
                                struct DiskBVMap *map = malloc(sizeof(*map));

                                map->biosdev	= biosdev;
                                map->bvr		= NULL;
                                map->bvrcnt		= 0;
                                map->next		= gDiskBVMap;
                                gDiskBVMap		= map;

                                for (; gptID <= gptCount; gptID++)
                                {
                                    gptMap = (gpt_ent *) (buffer + ((gptID - 1) * gptSize));

                                    if (isPartitionUsed(gptMap))
                                    {
                                        BVRef bvr = NULL;
                                        int bvrFlags = -1;
#if DEBUG_DISK
                                        char stringuuid[100];
                                        efi_guid_unparse_upper((EFI_GUID*)gptMap->ent_type, stringuuid);
                                        printf("Reading GPT partition %d, type %s\n", gptID, stringuuid);
                                        sleep(1);
#endif

                                        if (efi_guid_compare(&GPT_HFS_GUID, (EFI_GUID const *)gptMap->ent_type) == 0)
                                        {
                                            _DISK_DEBUG_DUMP("Matched: GPT_HFS_GUID\n");

                                            bvrFlags = kBVFlagZero;
                                        }
                                        /* else if (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const *)gptMap->ent_type) == 0)
                                        {
                                        	_DISK_DEBUG_DUMP("Matched: GPT_BOOT_GUID\n");

                                        	bvrFlags = kBVFlagBooter;
                                        } */
#if EFI_SYSTEM_PARTITION_SUPPORT
                                        else if (efi_guid_compare(&GPT_EFISYS_GUID, (EFI_GUID const *)gptMap->ent_type) == 0)
                                        {
                                            _DISK_DEBUG_DUMP("Matched: GPT_EFISYS_GUID, probing for HFS format...\n");

                                            //-------------- START -------------
                                            // Allocate buffer for 4 sectors.
                                            void * probeBuffer = malloc(2048);

                                            bool probeOK = false;

                                            // Read the first 4 sectors.
                                            if (readBytes(biosdev, gptMap->ent_lba_start, 0, 2048, (void *)probeBuffer) == 0)
                                            {
                                                //  Probing (returns true for HFS partitions).
                                                probeOK = HFSProbe(probeBuffer);

                                                _DISK_DEBUG_DUMP("HFSProbe status: Is %s a HFS partition.\n", probeOK ? "" : "not");

                                            }

                                            free(probeBuffer);

                                            // Veto non-HFS partitions to be invalid.
                                            if (!probeOK)
                                            {
                                                continue;
                                            }

                                            //-------------- END ---------------

                                            bvrFlags = kBVFlagEFISystem;
                                        }
#endif
                                        // Only true when we found a usable partition.
                                        if (bvrFlags >= 0)
                                        {
                                            bvr = newGPTBVRef(biosdev, gptID, gptMap->ent_lba_start, gptMap, bvrFlags);

                                            if (bvr)
                                            {
                                                bvr->part_type = FDISK_HFS;
                                                bvr->next = map->bvr;
                                                map->bvr = bvr;
                                                ++map->bvrcnt;

                                                // Don't waste time checking for boot.efi on ESP partitions.
                                                if ((bvrFlags & kBVFlagEFISystem) == 0)
                                                {
                                                    // Flag System Volumes with kBVFlagSystemVolume.
                                                    hasBootEFI(bvr);
                                                }

                                                // True on the initial run only.
                                                if (gPlatform.BootVolume == NULL)
                                                {
                                                    // Initialize with the first bootable volume.
                                                    gPlatform.BootVolume = gPlatform.RootVolume = bvr;

                                                    _DISK_DEBUG_DUMP("Init B/RootVolume - partition: %d, flags: %d, gptID: %d\n", bvr->part_no, bvr->flags, gptID);
                                                }

                                                // Bail out after finding the first System Volume.
                                                if (bvr->flags & kBVFlagSystemVolume)
                                                {
                                                    _DISK_DEBUG_DUMP("Partition %d is a System Volume\n", gptID);

                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }

                                free(buffer);
                                *countPtr = map->bvrcnt;

                                _DISK_DEBUG_DUMP("map->bvrcnt: %d\n", map->bvrcnt);
                                _DISK_DEBUG_SLEEP(5);

                                return map->bvr;
                            }
                        }
                    }
                }
            }
        }
    }

    free(buffer);
    *countPtr = 0;

    _DISK_DEBUG_SLEEP(5);

    return NULL;
}