4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/* $Id$ */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * ElTorito.c
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright (C) 2012 Oracle Corporation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * available from http://www.virtualbox.org. This file is free software;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * General Public License (GPL) as published by the Free Software
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * The contents of this file may alternatively be used under the terms
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * of the Common Development and Distribution License Version 1.0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution, in which case the provisions of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * CDDL are applicable instead of those of the GPL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * You may elect to license modified versions of this file under the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * terms and conditions of either the GPL or the CDDL or both.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Decode an El Torito formatted CD-ROM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynchttp://opensource.org/licenses/bsd-license.php
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "Partition.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Install child handles if the Handle supports El Torito format.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Calling context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Handle Parent Handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DiskIo Parent DiskIo interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo Parent BlockIo interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockIo2 Parent BlockIo2 interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DevicePath Parent Device Path
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Child handle(s) was added.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_MEDIA_CHANGED Media changed Detected.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other no child handle was added.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPartitionInstallElToritoChildHandles (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DRIVER_BINDING_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE Handle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DISK_IO_PROTOCOL *DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 VolDescriptorLba;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Lba;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_BLOCK_IO_MEDIA *Media;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CDROM_VOLUME_DESCRIPTOR *VolDescriptor;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ELTORITO_CATALOG *Catalog;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Check;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN BootEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN MaxIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 *CheckBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CDROM_DEVICE_PATH CdDev;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 SubBlockSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 SectorCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Found;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 VolSpaceSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
76a9bce2b9ca58813ae03900c71fa04b93a04f1avboxsync VBoxLogFlowFuncMarkDP(DevicePath);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Found = EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Media = BlockIo->Media;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VolSpaceSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // CD_ROM has the fixed block size as 2048 bytes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Media->BlockSize != 2048) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VolDescriptor = AllocatePool ((UINTN) Media->BlockSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VolDescriptor == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Catalog = (ELTORITO_CATALOG *) VolDescriptor;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the ISO-9660 volume descriptor starts at 32k on the media
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // and CD_ROM has the fixed block size as 2048 bytes, so...
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ((16*2048) / Media->BlockSize) - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VolDescriptorLba = 15;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop: handle one volume descriptor per time
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (TRUE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VolDescriptorLba += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VolDescriptorLba > Media->LastBlock) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // We are pointing past the end of the device so exit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = DiskIo->ReadDisk (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Media->MediaId,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32 (VolDescriptorLba, Media->BlockSize),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Media->BlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VolDescriptor
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Found = Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check for valid volume descriptor signature
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VolDescriptor->Unknown.Type == CDVOL_TYPE_END ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CompareMem (VolDescriptor->Unknown.Id, CDVOL_ID, sizeof (VolDescriptor->Unknown.Id)) != 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // end of Volume descriptor list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the 32-bit numerical values is stored in Both-byte orders
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VolDescriptor->PrimaryVolume.Type == CDVOL_TYPE_CODED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VolSpaceSize = VolDescriptor->PrimaryVolume.VolSpaceSize[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Is it an El Torito volume descriptor?
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareMem (VolDescriptor->BootRecordVolume.SystemId, CDVOL_ELTORITO_ID, sizeof (CDVOL_ELTORITO_ID) - 1) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read in the boot El Torito boot catalog
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Lba = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Lba > Media->LastBlock) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = DiskIo->ReadDisk (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Media->MediaId,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32 (Lba, Media->BlockSize),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Media->BlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Catalog
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "EltCheckDevice: error reading catalog %r\n", Status));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // We don't care too much about the Catalog header's contents, but we do want
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // to make sure it looks like a Catalog header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header IDs not correct\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CheckBuffer = (UINT16 *) Catalog;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check += CheckBuffer[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Check & 0xFFFF) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header checksum failed\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MaxIndex = Media->BlockSize / sizeof (ELTORITO_CATALOG);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 1, BootEntry = 1; Index < MaxIndex; Index += 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Next entry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Catalog += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check this entry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SubBlockSize = 512;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SectorCount = Catalog->Boot.SectorCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Catalog->Boot.MediaType) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ELTORITO_NO_EMULATION:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SubBlockSize = Media->BlockSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ELTORITO_HARD_DISK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ELTORITO_12_DISKETTE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SectorCount = 0x50 * 0x02 * 0x0F;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ELTORITO_14_DISKETTE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SectorCount = 0x50 * 0x02 * 0x12;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ELTORITO_28_DISKETTE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SectorCount = 0x50 * 0x02 * 0x24;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INIT, "EltCheckDevice: unsupported El Torito boot media type %x\n", Catalog->Boot.MediaType));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SectorCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SubBlockSize = Media->BlockSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create child device handle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CdDev.Header.Type = MEDIA_DEVICE_PATH;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CdDev.Header.SubType = MEDIA_CDROM_DP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetDevicePathNodeLength (&CdDev.Header, sizeof (CdDev));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Index == 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This is the initial/default entry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootEntry = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CdDev.BootEntry = (UINT32) BootEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootEntry++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CdDev.PartitionStart = Catalog->Boot.Lba;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SectorCount < 2) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // When the SectorCount < 2, set the Partition as the whole CD.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VolSpaceSize > (Media->LastBlock + 1)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CdDev.PartitionSize = (UINT32)(Media->LastBlock - Catalog->Boot.Lba + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CdDev.PartitionSize = (UINT32)(VolSpaceSize - Catalog->Boot.Lba);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CdDev.PartitionSize = DivU64x32 (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32 (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SectorCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SubBlockSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) + Media->BlockSize - 1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Media->BlockSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PartitionInstallChildHandle (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Handle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DiskIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockIo2,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevicePath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_DEVICE_PATH_PROTOCOL *) &CdDev,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Catalog->Boot.Lba,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Catalog->Boot.Lba + CdDev.PartitionSize - 1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SubBlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Found = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (VolDescriptor);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Found;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}