Modules cleanup.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3244 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
vanjeff 2007-07-16 05:48:11 +00:00
parent 9b4b2dcdd7
commit adbcbf8ffc
30 changed files with 4551 additions and 129 deletions

View File

@ -55,7 +55,6 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
################################################################################

View File

@ -67,7 +67,6 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
################################################################################

View File

@ -67,7 +67,6 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
################################################################################

View File

@ -64,7 +64,6 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
################################################################################

View File

@ -59,7 +59,6 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
################################################################################

View File

@ -63,8 +63,6 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
################################################################################
#

View File

@ -49,8 +49,6 @@
usbmouse.c
mousehid.c
usbmouse.h
CommonHeader.h
################################################################################
#
@ -61,8 +59,6 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
################################################################################
#

View File

@ -400,9 +400,9 @@
$(WORKSPACE)/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.inf
$(WORKSPACE)/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
$(WORKSPACE)/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.inf
$(WORKSPACE)/MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.inf
$(WORKSPACE)/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.inf
$(WORKSPACE)/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
$(WORKSPACE)/MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
$(WORKSPACE)/MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
$(WORKSPACE)/MdeModulePkg/Universal/SecurityStubDxe/SecurityStub.inf
$(WORKSPACE)/MdeModulePkg/Universal/Ebc/Dxe/Ebc.inf

View File

@ -0,0 +1,174 @@
/** @file
UEFI Component Name protocol for DiskIo driver.
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "DiskIo.h"
//
// EFI Component Name Protocol
//
EFI_COMPONENT_NAME_PROTOCOL gDiskIoComponentName = {
DiskIoComponentNameGetDriverName,
DiskIoComponentNameGetControllerName,
"eng"
};
static EFI_UNICODE_STRING_TABLE mDiskIoDriverNameTable[] = {
{
"eng",
(CHAR16 *)L"Generic Disk I/O Driver"
},
{
NULL,
NULL
}
};
/**
Retrieves a Unicode string that is the user readable name of
the EFI Driver.
@param This A pointer to the
EFI_COMPONENT_NAME_PROTOCOL instance.
@param Language A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller
is requesting, and it must match one of the
languages specified in SupportedLanguages.
The number of languages supported by a
driver is up to the driver writer. Language
is specified in RFC 3066 language code
format.
@param DriverName A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the
Driver specified by This and the
language specified by Language
was returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This
does not support the language
specified by Language.
**/
EFI_STATUS
EFIAPI
DiskIoComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
{
return LookupUnicodeString (
Language,
gDiskIoComponentName.SupportedLanguages,
mDiskIoDriverNameTable,
DriverName
);
}
/**
Retrieves a Unicode string that is the user readable name of
the controller that is being managed by an EFI Driver.
@param This A pointer to the
EFI_COMPONENT_NAME_PROTOCOL instance.
@param ControllerHandle The handle of a controller that the
driver specified by This is managing.
This handle specifies the controller
whose name is to be returned.
@param ChildHandle The handle of the child controller to
retrieve the name of. This is an
optional parameter that may be NULL.
It will be NULL for device drivers.
It will also be NULL for a bus
drivers that wish to retrieve the
name of the bus controller. It will
not be NULL for a bus driver that
wishes to retrieve the name of a
child controller.
@param Language A pointer to a Null-terminated ASCII
string array indicating the language.
This is the language of the driver
name that the caller is requesting,
and it must match one of the
languages specified in
SupportedLanguages. The number of
languages supported by a driver is up
to the driver writer. Language is
specified in RFC 3066 language code
format.
@param ControllerName A pointer to the Unicode string to
return. This Unicode string is the
name of the controller specified by
ControllerHandle and ChildHandle in
the language specified by Language
from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user
readable name in the language
specified by Language for the
driver specified by This was
returned in DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it
is not a valid EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is
not currently managing the
controller specified by
ControllerHandle and
ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This
does not support the language
specified by Language.
**/
EFI_STATUS
EFIAPI
DiskIoComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
}

View File

@ -0,0 +1,737 @@
/** @file
DiskIo driver that layers it's self on every Block IO protocol in the system.
DiskIo converts a block oriented device to a byte oriented device.
ReadDisk may have to do reads that are not aligned on sector boundaries.
There are three cases:
UnderRun - The first byte is not on a sector boundary or the read request is
less than a sector in length.
Aligned - A read of N contiguous sectors.
OverRun - The last byte is not on a sector boundary.
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "DiskIo.h"
EFI_DRIVER_BINDING_PROTOCOL gDiskIoDriverBinding = {
DiskIoDriverBindingSupported,
DiskIoDriverBindingStart,
DiskIoDriverBindingStop,
0xa,
NULL,
NULL
};
DISK_IO_PRIVATE_DATA gDiskIoPrivateDataTemplate = {
DISK_IO_PRIVATE_DATA_SIGNATURE,
{
EFI_DISK_IO_PROTOCOL_REVISION,
DiskIoReadDisk,
DiskIoWriteDisk
},
NULL
};
/**
Test to see if this driver supports ControllerHandle.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to test
@param RemainingDevicePath Optional parameter use to pick a specific child
device to start.
@retval EFI_SUCCESS This driver supports this device
@retval EFI_ALREADY_STARTED This driver is already running on this device
@retval other This driver does not support this device
**/
EFI_STATUS
EFIAPI
DiskIoDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
EFI_STATUS Status;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
//
// Open the IO Abstraction(s) needed to perform the supported test.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
(VOID **) &BlockIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Close the I/O Abstraction(s) used to perform the supported test.
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_SUCCESS;
}
/**
Start this driver on ControllerHandle by opening a Block IO protocol and
installing a Disk IO protocol on ControllerHandle.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to bind driver to
@param RemainingDevicePath Optional parameter use to pick a specific child
device to start.
@retval EFI_SUCCESS This driver is added to ControllerHandle
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
@retval other This driver does not support this device
**/
EFI_STATUS
EFIAPI
DiskIoDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
EFI_STATUS Status;
DISK_IO_PRIVATE_DATA *Private;
Private = NULL;
//
// Connect to the Block IO interface on ControllerHandle.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
(VOID **) &gDiskIoPrivateDataTemplate.BlockIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Initialize the Disk IO device instance.
//
Private = AllocateCopyPool (sizeof (DISK_IO_PRIVATE_DATA), &gDiskIoPrivateDataTemplate);
if (Private == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
//
// Install protocol interfaces for the Disk IO device.
//
Status = gBS->InstallProtocolInterface (
&ControllerHandle,
&gEfiDiskIoProtocolGuid,
EFI_NATIVE_INTERFACE,
&Private->DiskIo
);
ErrorExit:
if (EFI_ERROR (Status)) {
if (Private != NULL) {
FreePool (Private);
}
gBS->CloseProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
}
return Status;
}
/**
Stop this driver on ControllerHandle by removing Disk IO protocol and closing
the Block IO protocol on ControllerHandle.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to stop driver on
@param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
children is zero stop the entire bus driver.
@param ChildHandleBuffer List of Child Handles to Stop.
@retval EFI_SUCCESS This driver is removed ControllerHandle
@retval other This driver was not removed from this device
**/
EFI_STATUS
EFIAPI
DiskIoDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_STATUS Status;
EFI_DISK_IO_PROTOCOL *DiskIo;
DISK_IO_PRIVATE_DATA *Private;
//
// Get our context back.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
(VOID **) &DiskIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
Private = DISK_IO_PRIVATE_DATA_FROM_THIS (DiskIo);
Status = gBS->UninstallProtocolInterface (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
&Private->DiskIo
);
if (!EFI_ERROR (Status)) {
Status = gBS->CloseProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
}
if (!EFI_ERROR (Status)) {
FreePool (Private);
}
return Status;
}
/**
Read BufferSize bytes from Offset into Buffer.
Reads may support reads that are not aligned on
sector boundaries. There are three cases:
UnderRun - The first byte is not on a sector boundary or the read request is
less than a sector in length.
Aligned - A read of N contiguous sectors.
OverRun - The last byte is not on a sector boundary.
@param This Protocol instance pointer.
@param MediaId Id of the media, changes every time the media is replaced.
@param Offset The starting byte offset to read from
@param BufferSize Size of Buffer
@param Buffer Buffer containing read data
@retval EFI_SUCCESS The data was read correctly from the device.
@retval EFI_DEVICE_ERROR The device reported an error while performing the read.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
@retval EFI_INVALID_PARAMETER The read request contains device addresses that are not
valid for the device.
**/
EFI_STATUS
EFIAPI
DiskIoReadDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
EFI_STATUS Status;
DISK_IO_PRIVATE_DATA *Private;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_BLOCK_IO_MEDIA *Media;
UINT32 BlockSize;
UINT64 Lba;
UINT64 OverRunLba;
UINT32 UnderRun;
UINT32 OverRun;
BOOLEAN TransactionComplete;
UINTN WorkingBufferSize;
UINT8 *WorkingBuffer;
UINTN Length;
UINT8 *Data;
UINT8 *PreData;
UINTN IsBufferAligned;
UINTN DataBufferSize;
BOOLEAN LastRead;
Private = DISK_IO_PRIVATE_DATA_FROM_THIS (This);
BlockIo = Private->BlockIo;
Media = BlockIo->Media;
BlockSize = Media->BlockSize;
if (Media->MediaId != MediaId) {
return EFI_MEDIA_CHANGED;
}
WorkingBuffer = Buffer;
WorkingBufferSize = BufferSize;
//
// Allocate a temporary buffer for operation
//
DataBufferSize = BlockSize * DATA_BUFFER_BLOCK_NUM;
if (Media->IoAlign > 1) {
PreData = AllocatePool (DataBufferSize + Media->IoAlign);
Data = PreData - ((UINTN) PreData & (Media->IoAlign - 1)) + Media->IoAlign;
} else {
PreData = AllocatePool (DataBufferSize);
Data = PreData;
}
if (PreData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Lba = DivU64x32Remainder (Offset, BlockSize, &UnderRun);
Length = BlockSize - UnderRun;
TransactionComplete = FALSE;
Status = EFI_SUCCESS;
if (UnderRun != 0) {
//
// Offset starts in the middle of an Lba, so read the entire block.
//
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
Lba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
if (Length > BufferSize) {
Length = BufferSize;
TransactionComplete = TRUE;
}
CopyMem (WorkingBuffer, Data + UnderRun, Length);
WorkingBuffer += Length;
WorkingBufferSize -= Length;
if (WorkingBufferSize == 0) {
goto Done;
}
Lba += 1;
}
OverRunLba = Lba + DivU64x32Remainder (WorkingBufferSize, BlockSize, &OverRun);
if (!TransactionComplete && WorkingBufferSize >= BlockSize) {
//
// If the DiskIo maps directly to a BlockIo device do the read.
//
if (OverRun != 0) {
WorkingBufferSize -= OverRun;
}
//
// Check buffer alignment
//
IsBufferAligned = (UINTN) WorkingBuffer & (UINTN) (Media->IoAlign - 1);
if (Media->IoAlign <= 1 || IsBufferAligned == 0) {
//
// Alignment is satisfied, so read them together
//
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
Lba,
WorkingBufferSize,
WorkingBuffer
);
if (EFI_ERROR (Status)) {
goto Done;
}
WorkingBuffer += WorkingBufferSize;
} else {
//
// Use the allocated buffer instead of the original buffer
// to avoid alignment issue.
// Here, the allocated buffer (8-byte align) can satisfy the alignment
//
LastRead = FALSE;
do {
if (WorkingBufferSize <= DataBufferSize) {
//
// It is the last calling to readblocks in this loop
//
DataBufferSize = WorkingBufferSize;
LastRead = TRUE;
}
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
Lba,
DataBufferSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
CopyMem (WorkingBuffer, Data, DataBufferSize);
WorkingBufferSize -= DataBufferSize;
WorkingBuffer += DataBufferSize;
Lba += DATA_BUFFER_BLOCK_NUM;
} while (!LastRead);
}
}
if (!TransactionComplete && OverRun != 0) {
//
// Last read is not a complete block.
//
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
OverRunLba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
CopyMem (WorkingBuffer, Data, OverRun);
}
Done:
if (PreData != NULL) {
FreePool (PreData);
}
return Status;
}
/**
Read BufferSize bytes from Offset into Buffer.
Writes may require a read modify write to support writes that are not
aligned on sector boundaries. There are three cases:
UnderRun - The first byte is not on a sector boundary or the write request
is less than a sector in length. Read modify write is required.
Aligned - A write of N contiguous sectors.
OverRun - The last byte is not on a sector boundary. Read modified write
required.
@param This Protocol instance pointer.
@param MediaId Id of the media, changes every time the media is replaced.
@param Offset The starting byte offset to read from
@param BufferSize Size of Buffer
@param Buffer Buffer containing read data
@retval EFI_SUCCESS The data was written correctly to the device.
@retval EFI_WRITE_PROTECTED The device can not be written to.
@retval EFI_DEVICE_ERROR The device reported an error while performing the write.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
@retval EFI_INVALID_PARAMETER The write request contains device addresses that are not
valid for the device.
**/
EFI_STATUS
EFIAPI
DiskIoWriteDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN UINTN BufferSize,
IN VOID *Buffer
)
{
EFI_STATUS Status;
DISK_IO_PRIVATE_DATA *Private;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_BLOCK_IO_MEDIA *Media;
UINT32 BlockSize;
UINT64 Lba;
UINT64 OverRunLba;
UINT32 UnderRun;
UINT32 OverRun;
BOOLEAN TransactionComplete;
UINTN WorkingBufferSize;
UINT8 *WorkingBuffer;
UINTN Length;
UINT8 *Data;
UINT8 *PreData;
UINTN IsBufferAligned;
UINTN DataBufferSize;
BOOLEAN LastWrite;
Private = DISK_IO_PRIVATE_DATA_FROM_THIS (This);
BlockIo = Private->BlockIo;
Media = BlockIo->Media;
BlockSize = Media->BlockSize;
if (Media->ReadOnly) {
return EFI_WRITE_PROTECTED;
}
if (Media->MediaId != MediaId) {
return EFI_MEDIA_CHANGED;
}
DataBufferSize = BlockSize * DATA_BUFFER_BLOCK_NUM;
if (Media->IoAlign > 1) {
PreData = AllocatePool (DataBufferSize + Media->IoAlign);
Data = PreData - ((UINTN) PreData & (Media->IoAlign - 1)) + Media->IoAlign;
} else {
PreData = AllocatePool (DataBufferSize);
Data = PreData;
}
if (PreData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
WorkingBuffer = Buffer;
WorkingBufferSize = BufferSize;
Lba = DivU64x32Remainder (Offset, BlockSize, &UnderRun);
Length = BlockSize - UnderRun;
TransactionComplete = FALSE;
Status = EFI_SUCCESS;
if (UnderRun != 0) {
//
// Offset starts in the middle of an Lba, so do read modify write.
//
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
Lba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
if (Length > BufferSize) {
Length = BufferSize;
TransactionComplete = TRUE;
}
CopyMem (Data + UnderRun, WorkingBuffer, Length);
Status = BlockIo->WriteBlocks (
BlockIo,
MediaId,
Lba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
WorkingBuffer += Length;
WorkingBufferSize -= Length;
if (WorkingBufferSize == 0) {
goto Done;
}
Lba += 1;
}
OverRunLba = Lba + DivU64x32Remainder (WorkingBufferSize, BlockSize, &OverRun);
if (!TransactionComplete && WorkingBufferSize >= BlockSize) {
//
// If the DiskIo maps directly to a BlockIo device do the write.
//
if (OverRun != 0) {
WorkingBufferSize -= OverRun;
}
//
// Check buffer alignment
//
IsBufferAligned = (UINTN) WorkingBuffer & (UINTN) (Media->IoAlign - 1);
if (Media->IoAlign <= 1 || IsBufferAligned == 0) {
//
// Alignment is satisfied, so write them together
//
Status = BlockIo->WriteBlocks (
BlockIo,
MediaId,
Lba,
WorkingBufferSize,
WorkingBuffer
);
if (EFI_ERROR (Status)) {
goto Done;
}
WorkingBuffer += WorkingBufferSize;
} else {
//
// The buffer parameter is not aligned with the request
// So use the allocated instead.
// It can fit almost all the cases.
//
LastWrite = FALSE;
do {
if (WorkingBufferSize <= DataBufferSize) {
//
// It is the last calling to writeblocks in this loop
//
DataBufferSize = WorkingBufferSize;
LastWrite = TRUE;
}
CopyMem (Data, WorkingBuffer, DataBufferSize);
Status = BlockIo->WriteBlocks (
BlockIo,
MediaId,
Lba,
DataBufferSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
WorkingBufferSize -= DataBufferSize;
WorkingBuffer += DataBufferSize;
Lba += DATA_BUFFER_BLOCK_NUM;
} while (!LastWrite);
}
}
if (!TransactionComplete && OverRun != 0) {
//
// Last bit is not a complete block, so do a read modify write.
//
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
OverRunLba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
CopyMem (Data, WorkingBuffer, OverRun);
Status = BlockIo->WriteBlocks (
BlockIo,
MediaId,
OverRunLba,
BlockSize,
Data
);
if (EFI_ERROR (Status)) {
goto Done;
}
}
Done:
if (PreData != NULL) {
FreePool (PreData);
}
return Status;
}
/**
The user Entry Point for module DiskIo. The user code starts with this function.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
InitializeDiskIo (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Install driver model protocol(s).
//
Status = EfiLibInstallAllDriverProtocols (
ImageHandle,
SystemTable,
&gDiskIoDriverBinding,
ImageHandle,
&gDiskIoComponentName,
NULL,
NULL
);
ASSERT_EFI_ERROR (Status);
return Status;
}

View File

@ -0,0 +1,124 @@
/** @file
DiskIo driver that layers it's self on every Block IO protocol in the system.
DiskIo converts a block oriented device to a byte oriented device.
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _DISK_IO_H
#define _DISK_IO_H
#include <Uefi.h>
#include <Protocol/BlockIo.h>
#include <Protocol/ComponentName.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/DiskIo.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#define DISK_IO_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('d', 's', 'k', 'I')
#define DATA_BUFFER_BLOCK_NUM (64)
typedef struct {
UINTN Signature;
EFI_DISK_IO_PROTOCOL DiskIo;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
} DISK_IO_PRIVATE_DATA;
#define DISK_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, DISK_IO_PRIVATE_DATA, DiskIo, DISK_IO_PRIVATE_DATA_SIGNATURE)
//
// Global Variables
//
extern EFI_DRIVER_BINDING_PROTOCOL gDiskIoDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gDiskIoComponentName;
//
// Prototypes
// Driver model protocol interface
//
EFI_STATUS
EFIAPI
DiskIoDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
DiskIoDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
DiskIoDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
//
// Disk I/O Protocol Interface
//
EFI_STATUS
EFIAPI
DiskIoReadDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
DiskIoWriteDisk (
IN EFI_DISK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN UINTN BufferSize,
IN VOID *Buffer
);
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
DiskIoComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
DiskIoComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
#endif

View File

@ -0,0 +1,91 @@
#/** @file
# Component description file for DiskIo module.
#
# Copyright (c) 2006 - 2007, Intel Corporation
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
#**/
################################################################################
#
# Defines Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = DiskIoDxe
FILE_GUID = 6B38F7B4-AD98-40e9-9093-ACA2B5A253C4
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
EDK_RELEASE_VERSION = 0x00020000
EFI_SPECIFICATION_VERSION = 0x00020000
ENTRY_POINT = InitializeDiskIo
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
# DRIVER_BINDING = gDiskIoDriverBinding
# COMPONENT_NAME = gDiskIoComponentName
#
################################################################################
#
# Sources Section - list of files that are required for the build to succeed.
#
################################################################################
[Sources.common]
ComponentName.c
DiskIo.h
DiskIo.c
################################################################################
#
# Package Dependency Section - list of Package files that are required for
# this module.
#
################################################################################
[Packages]
MdePkg/MdePkg.dec
################################################################################
#
# Library Class Section - list of Library Classes that are required for
# this module.
#
################################################################################
[LibraryClasses]
UefiBootServicesTableLib
MemoryAllocationLib
BaseMemoryLib
BaseLib
UefiLib
UefiDriverEntryPoint
DebugLib
################################################################################
#
# Protocol C Name Section - list of Protocol and Protocol Notify C Names
# that this module uses or produces.
#
################################################################################
[Protocols]
gEfiDiskIoProtocolGuid # PROTOCOL BY_START
gEfiBlockIoProtocolGuid # PROTOCOL TO_START

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
<MsaHeader>
<ModuleName>DiskIoDxe</ModuleName>
<ModuleType>UEFI_DRIVER</ModuleType>
<GuidValue>6B38F7B4-AD98-40e9-9093-ACA2B5A253C4</GuidValue>
<Version>1.0</Version>
<Abstract>Component description file for DiskIo module.</Abstract>
<Description>DiskIo driver that layers it's self on every Block IO protocol in the system.</Description>
<Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>
<License>All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
</MsaHeader>
<ModuleDefinitions>
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
<BinaryModule>false</BinaryModule>
<OutputFileBasename>DiskIoDxe</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">
<Keyword>DebugLib</Keyword>
<HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiDriverModelLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiDriverEntryPoint</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseMemoryLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>MemoryAllocationLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiBootServicesTableLib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<FilenameDiskIo.c</Filename>
<Filename>DiskIo.h</Filename>
<Filename>ComponentName.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</PackageDependencies>
<Protocols>
<Protocol Usage="TO_START">
<ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="BY_START">
<ProtocolCName>gEfiDiskIoProtocolGuid</ProtocolCName>
</Protocol>
</Protocols>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
<Extern>
<DriverBinding>gDiskIoDriverBinding</DriverBinding>
<ComponentName>gDiskIoComponentName</ComponentName>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@ -0,0 +1,173 @@
/** @file
UEFI Component Name protocol for Partition driver.
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Partition.h"
//
// EFI Component Name Protocol
//
EFI_COMPONENT_NAME_PROTOCOL gPartitionComponentName = {
PartitionComponentNameGetDriverName,
PartitionComponentNameGetControllerName,
"eng"
};
static EFI_UNICODE_STRING_TABLE mPartitionDriverNameTable[] = {
{
"eng",
(CHAR16 *)L"Partition Driver(MBR/GPT/El Torito)"
},
{
NULL,
NULL
}
};
/**
Retrieves a Unicode string that is the user readable name of
the EFI Driver.
@param This A pointer to the
EFI_COMPONENT_NAME_PROTOCOL instance.
@param Language A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller
is requesting, and it must match one of the
languages specified in SupportedLanguages.
The number of languages supported by a
driver is up to the driver writer. Language
is specified in RFC 3066 language code
format.
@param DriverName A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the
Driver specified by This and the
language specified by Language
was returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This
does not support the language
specified by Language.
**/
EFI_STATUS
EFIAPI
PartitionComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
{
return LookupUnicodeString (
Language,
gPartitionComponentName.SupportedLanguages,
mPartitionDriverNameTable,
DriverName
);
}
/**
Retrieves a Unicode string that is the user readable name of
the controller that is being managed by an EFI Driver.
@param This A pointer to the
EFI_COMPONENT_NAME_PROTOCOL instance.
@param ControllerHandle The handle of a controller that the
driver specified by This is managing.
This handle specifies the controller
whose name is to be returned.
@param ChildHandle The handle of the child controller to
retrieve the name of. This is an
optional parameter that may be NULL.
It will be NULL for device drivers.
It will also be NULL for a bus
drivers that wish to retrieve the
name of the bus controller. It will
not be NULL for a bus driver that
wishes to retrieve the name of a
child controller.
@param Language A pointer to a Null-terminated ASCII
string array indicating the language.
This is the language of the driver
name that the caller is requesting,
and it must match one of the
languages specified in
SupportedLanguages. The number of
languages supported by a driver is up
to the driver writer. Language is
specified in RFC 3066 language code
format.
@param ControllerName A pointer to the Unicode string to
return. This Unicode string is the
name of the controller specified by
ControllerHandle and ChildHandle in
the language specified by Language
from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user
readable name in the language
specified by Language for the
driver specified by This was
returned in DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it
is not a valid EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is
not currently managing the
controller specified by
ControllerHandle and
ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This
does not support the language
specified by Language.
**/
EFI_STATUS
EFIAPI
PartitionComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
}

View File

@ -0,0 +1,275 @@
/** @file
Decode an El Torito formatted CD-ROM
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Partition.h"
/**
Install child handles if the Handle supports El Torito format.
@param[in] This Calling context.
@param[in] Handle Parent Handle
@param[in] DiskIo Parent DiskIo interface
@param[in] BlockIo Parent BlockIo interface
@param[in] DevicePath Parent Device Path
@retval EFI_SUCCESS Child handle(s) was added
@retval EFI_MEDIA_CHANGED Media changed Detected
@retval other no child handle was added
**/
EFI_STATUS
PartitionInstallElToritoChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
EFI_STATUS Status;
UINT32 VolDescriptorLba;
UINT32 Lba;
EFI_BLOCK_IO_MEDIA *Media;
CDROM_VOLUME_DESCRIPTOR *VolDescriptor;
ELTORITO_CATALOG *Catalog;
UINTN Check;
UINTN Index;
UINTN BootEntry;
UINTN MaxIndex;
UINT16 *CheckBuffer;
CDROM_DEVICE_PATH CdDev;
UINT32 SubBlockSize;
UINT32 SectorCount;
EFI_STATUS Found;
UINT32 VolSpaceSize;
Found = EFI_NOT_FOUND;
Media = BlockIo->Media;
VolSpaceSize = 0;
//
// CD_ROM has the fixed block size as 2048 bytes
//
if (Media->BlockSize != 2048) {
return EFI_NOT_FOUND;
}
VolDescriptor = AllocatePool ((UINTN) Media->BlockSize);
if (VolDescriptor == NULL) {
return EFI_NOT_FOUND;
}
Catalog = (ELTORITO_CATALOG *) VolDescriptor;
//
// the ISO-9660 volume descriptor starts at 32k on the media
// and CD_ROM has the fixed block size as 2048 bytes, so...
//
//
// ((16*2048) / Media->BlockSize) - 1;
//
VolDescriptorLba = 15;
//
// Loop: handle one volume descriptor per time
//
while (TRUE) {
VolDescriptorLba += 1;
if (VolDescriptorLba > Media->LastBlock) {
//
// We are pointing past the end of the device so exit
//
break;
}
Status = BlockIo->ReadBlocks (
BlockIo,
Media->MediaId,
VolDescriptorLba,
Media->BlockSize,
VolDescriptor
);
if (EFI_ERROR (Status)) {
Found = Status;
break;
}
//
// Check for valid volume descriptor signature
//
if (VolDescriptor->Type == CDVOL_TYPE_END ||
CompareMem (VolDescriptor->Id, CDVOL_ID, sizeof (VolDescriptor->Id)) != 0
) {
//
// end of Volume descriptor list
//
break;
}
//
// Read the Volume Space Size from Primary Volume Descriptor 81-88 byte,
// the 32-bit numerical values is stored in Both-byte orders
//
if (VolDescriptor->Type == CDVOL_TYPE_CODED) {
VolSpaceSize = VolDescriptor->VolSpaceSize[0];
}
//
// Is it an El Torito volume descriptor?
//
if (CompareMem (VolDescriptor->SystemId, CDVOL_ELTORITO_ID, sizeof (CDVOL_ELTORITO_ID) - 1) != 0) {
continue;
}
//
// Read in the boot El Torito boot catalog
//
Lba = UNPACK_INT32 (VolDescriptor->EltCatalog);
if (Lba > Media->LastBlock) {
continue;
}
Status = BlockIo->ReadBlocks (
BlockIo,
Media->MediaId,
Lba,
Media->BlockSize,
Catalog
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "EltCheckDevice: error reading catalog %r\n", Status));
continue;
}
//
// We don't care too much about the Catalog header's contents, but we do want
// to make sure it looks like a Catalog header
//
if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {
DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header IDs not correct\n"));
continue;
}
Check = 0;
CheckBuffer = (UINT16 *) Catalog;
for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {
Check += CheckBuffer[Index];
}
if (Check & 0xFFFF) {
DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header checksum failed\n"));
continue;
}
MaxIndex = Media->BlockSize / sizeof (ELTORITO_CATALOG);
for (Index = 1, BootEntry = 1; Index < MaxIndex; Index += 1) {
//
// Next entry
//
Catalog += 1;
//
// Check this entry
//
if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {
continue;
}
SubBlockSize = 512;
SectorCount = Catalog->Boot.SectorCount;
switch (Catalog->Boot.MediaType) {
case ELTORITO_NO_EMULATION:
SubBlockSize = Media->BlockSize;
break;
case ELTORITO_HARD_DISK:
break;
case ELTORITO_12_DISKETTE:
SectorCount = 0x50 * 0x02 * 0x0F;
break;
case ELTORITO_14_DISKETTE:
SectorCount = 0x50 * 0x02 * 0x12;
break;
case ELTORITO_28_DISKETTE:
SectorCount = 0x50 * 0x02 * 0x24;
break;
default:
DEBUG ((EFI_D_INIT, "EltCheckDevice: unsupported El Torito boot media type %x\n", Catalog->Boot.MediaType));
SectorCount = 0;
SubBlockSize = Media->BlockSize;
break;
}
//
// Create child device handle
//
CdDev.Header.Type = MEDIA_DEVICE_PATH;
CdDev.Header.SubType = MEDIA_CDROM_DP;
SetDevicePathNodeLength (&CdDev.Header, sizeof (CdDev));
if (Index == 1) {
//
// This is the initial/default entry
//
BootEntry = 0;
}
CdDev.BootEntry = (UINT32) BootEntry;
BootEntry++;
CdDev.PartitionStart = Catalog->Boot.Lba;
if (SectorCount < 2) {
//
// When the SectorCount < 2, set the Partition as the whole CD.
//
if (VolSpaceSize > (Media->LastBlock + 1)) {
CdDev.PartitionSize = (UINT32)(Media->LastBlock - Catalog->Boot.Lba + 1);
} else {
CdDev.PartitionSize = (UINT32)(VolSpaceSize - Catalog->Boot.Lba);
}
} else {
CdDev.PartitionSize = DivU64x32 (
MultU64x32 (
SectorCount,
SubBlockSize
) + Media->BlockSize - 1,
Media->BlockSize
);
}
Status = PartitionInstallChildHandle (
This,
Handle,
DiskIo,
BlockIo,
DevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &CdDev,
Catalog->Boot.Lba,
Catalog->Boot.Lba + CdDev.PartitionSize - 1,
SubBlockSize,
FALSE
);
if (!EFI_ERROR (Status)) {
Found = EFI_SUCCESS;
}
}
}
FreePool (VolDescriptor);
return Found;
}

View File

@ -0,0 +1,720 @@
/** @file
Decode a hard disk partitioned with the GPT scheme in the EFI 1.0
specification.
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Partition.h"
BOOLEAN
PartitionValidGptTable (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_LBA Lba,
OUT EFI_PARTITION_TABLE_HEADER *PartHeader
);
BOOLEAN
PartitionCheckGptEntryArrayCRC (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_PARTITION_TABLE_HEADER *PartHeader
);
BOOLEAN
PartitionRestoreGptTable (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_PARTITION_TABLE_HEADER *PartHeader
);
VOID
PartitionCheckGptEntry (
IN EFI_PARTITION_TABLE_HEADER *PartHeader,
IN EFI_PARTITION_ENTRY *PartEntry,
OUT EFI_PARTITION_ENTRY_STATUS *PEntryStatus
);
BOOLEAN
PartitionCheckCrcAltSize (
IN UINTN MaxSize,
IN UINTN Size,
IN OUT EFI_TABLE_HEADER *Hdr
);
BOOLEAN
PartitionCheckCrc (
IN UINTN MaxSize,
IN OUT EFI_TABLE_HEADER *Hdr
);
VOID
PartitionSetCrcAltSize (
IN UINTN Size,
IN OUT EFI_TABLE_HEADER *Hdr
);
VOID
PartitionSetCrc (
IN OUT EFI_TABLE_HEADER *Hdr
);
/**
Install child handles if the Handle supports GPT partition structure.
@param[in] This - Calling context.
@param[in] Handle - Parent Handle
@param[in] DiskIo - Parent DiskIo interface
@param[in] BlockIo - Parent BlockIo interface
@param[in] DevicePath - Parent Device Path
@retval EFI_SUCCESS Valid GPT disk
@retval EFI_MEDIA_CHANGED Media changed Detected
@retval other Not a valid GPT disk
**/
EFI_STATUS
PartitionInstallGptChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
EFI_STATUS Status;
UINT32 BlockSize;
EFI_LBA LastBlock;
MASTER_BOOT_RECORD *ProtectiveMbr;
EFI_PARTITION_TABLE_HEADER *PrimaryHeader;
EFI_PARTITION_TABLE_HEADER *BackupHeader;
EFI_PARTITION_ENTRY *PartEntry;
EFI_PARTITION_ENTRY_STATUS *PEntryStatus;
UINTN Index;
EFI_STATUS GptValid;
HARDDRIVE_DEVICE_PATH HdDev;
ProtectiveMbr = NULL;
PrimaryHeader = NULL;
BackupHeader = NULL;
PartEntry = NULL;
PEntryStatus = NULL;
BlockSize = BlockIo->Media->BlockSize;
LastBlock = BlockIo->Media->LastBlock;
DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize));
DEBUG ((EFI_D_INFO, " LastBlock : %x \n", LastBlock));
GptValid = EFI_NOT_FOUND;
//
// Allocate a buffer for the Protective MBR
//
ProtectiveMbr = AllocatePool (BlockSize);
if (ProtectiveMbr == NULL) {
return EFI_NOT_FOUND;
}
//
// Read the Protective MBR from LBA #0
//
Status = BlockIo->ReadBlocks (
BlockIo,
BlockIo->Media->MediaId,
0,
BlockIo->Media->BlockSize,
ProtectiveMbr
);
if (EFI_ERROR (Status)) {
GptValid = Status;
goto Done;
}
//
// Verify that the Protective MBR is valid
//
if (ProtectiveMbr->Partition[0].BootIndicator != 0x00 ||
ProtectiveMbr->Partition[0].OSIndicator != PMBR_GPT_PARTITION ||
UNPACK_UINT32 (ProtectiveMbr->Partition[0].StartingLBA) != 1
) {
goto Done;
}
//
// Allocate the GPT structures
//
PrimaryHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));
if (PrimaryHeader == NULL) {
goto Done;
}
BackupHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));
if (BackupHeader == NULL) {
goto Done;
}
//
// Check primary and backup partition tables
//
if (!PartitionValidGptTable (BlockIo, DiskIo, PRIMARY_PART_HEADER_LBA, PrimaryHeader)) {
DEBUG ((EFI_D_INFO, " Not Valid primary partition table\n"));
if (!PartitionValidGptTable (BlockIo, DiskIo, LastBlock, BackupHeader)) {
DEBUG ((EFI_D_INFO, " Not Valid backup partition table\n"));
goto Done;
} else {
DEBUG ((EFI_D_INFO, " Valid backup partition table\n"));
DEBUG ((EFI_D_INFO, " Restore primary partition table by the backup\n"));
if (!PartitionRestoreGptTable (BlockIo, DiskIo, BackupHeader)) {
DEBUG ((EFI_D_INFO, " Restore primary partition table error\n"));
}
if (PartitionValidGptTable (BlockIo, DiskIo, BackupHeader->AlternateLBA, PrimaryHeader)) {
DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
}
}
} else if (!PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {
DEBUG ((EFI_D_INFO, " Valid primary and !Valid backup partition table\n"));
DEBUG ((EFI_D_INFO, " Restore backup partition table by the primary\n"));
if (!PartitionRestoreGptTable (BlockIo, DiskIo, PrimaryHeader)) {
DEBUG ((EFI_D_INFO, " Restore backup partition table error\n"));
}
if (PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {
DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));
}
}
DEBUG ((EFI_D_INFO, " Valid primary and Valid backup partition table\n"));
//
// Read the EFI Partition Entries
//
PartEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY));
if (PartEntry == NULL) {
DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
goto Done;
}
Status = DiskIo->ReadDisk (
DiskIo,
BlockIo->Media->MediaId,
MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockSize),
PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry),
PartEntry
);
if (EFI_ERROR (Status)) {
GptValid = Status;
DEBUG ((EFI_D_INFO, " Partition Entry ReadBlocks error\n"));
goto Done;
}
DEBUG ((EFI_D_INFO, " Partition entries read block success\n"));
DEBUG ((EFI_D_INFO, " Number of partition entries: %d\n", PrimaryHeader->NumberOfPartitionEntries));
PEntryStatus = AllocateZeroPool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS));
if (PEntryStatus == NULL) {
DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
goto Done;
}
//
// Check the integrity of partition entries
//
PartitionCheckGptEntry (PrimaryHeader, PartEntry, PEntryStatus);
//
// If we got this far the GPT layout of the disk is valid and we should return true
//
GptValid = EFI_SUCCESS;
//
// Create child device handles
//
for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
if (CompareGuid (&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeUnusedGuid) ||
PEntryStatus[Index].OutOfRange ||
PEntryStatus[Index].Overlap
) {
//
// Don't use null EFI Partition Entries or Invalid Partition Entries
//
continue;
}
ZeroMem (&HdDev, sizeof (HdDev));
HdDev.Header.Type = MEDIA_DEVICE_PATH;
HdDev.Header.SubType = MEDIA_HARDDRIVE_DP;
SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));
HdDev.PartitionNumber = (UINT32) Index + 1;
HdDev.MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
HdDev.SignatureType = SIGNATURE_TYPE_GUID;
HdDev.PartitionStart = PartEntry[Index].StartingLBA;
HdDev.PartitionSize = PartEntry[Index].EndingLBA - PartEntry[Index].StartingLBA + 1;
CopyMem (HdDev.Signature, &PartEntry[Index].UniquePartitionGUID, sizeof (EFI_GUID));
DEBUG ((EFI_D_INFO, " Index : %d\n", Index));
DEBUG ((EFI_D_INFO, " Start LBA : %x\n", HdDev.PartitionStart));
DEBUG ((EFI_D_INFO, " End LBA : %x\n", PartEntry[Index].EndingLBA));
DEBUG ((EFI_D_INFO, " Partition size: %x\n", HdDev.PartitionSize));
DEBUG ((EFI_D_INFO, " Start : %x", MultU64x32 (PartEntry[Index].StartingLBA, BlockSize)));
DEBUG ((EFI_D_INFO, " End : %x\n", MultU64x32 (PartEntry[Index].EndingLBA, BlockSize)));
Status = PartitionInstallChildHandle (
This,
Handle,
DiskIo,
BlockIo,
DevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
PartEntry[Index].StartingLBA,
PartEntry[Index].EndingLBA,
BlockSize,
CompareGuid(&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)
);
}
DEBUG ((EFI_D_INFO, "Prepare to Free Pool\n"));
Done:
if (ProtectiveMbr != NULL) {
FreePool (ProtectiveMbr);
}
if (PrimaryHeader != NULL) {
FreePool (PrimaryHeader);
}
if (BackupHeader != NULL) {
FreePool (BackupHeader);
}
if (PartEntry != NULL) {
FreePool (PartEntry);
}
if (PEntryStatus != NULL) {
FreePool (PEntryStatus);
}
return GptValid;
}
/**
Install child handles if the Handle supports GPT partition structure.
@param[in] BlockIo Parent BlockIo interface
@param[in] DiskIo Disk Io protocol.
@param[in] Lba The starting Lba of the Partition Table
@param[in] PartHeader Stores the partition table that is read
@retval TRUE The partition table is valid
@retval FALSE The partition table is not valid
**/
BOOLEAN
PartitionValidGptTable (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_LBA Lba,
OUT EFI_PARTITION_TABLE_HEADER *PartHeader
)
{
EFI_STATUS Status;
UINT32 BlockSize;
EFI_PARTITION_TABLE_HEADER *PartHdr;
BlockSize = BlockIo->Media->BlockSize;
PartHdr = AllocateZeroPool (BlockSize);
if (PartHdr == NULL) {
DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
return FALSE;
}
//
// Read the EFI Partition Table Header
//
Status = BlockIo->ReadBlocks (
BlockIo,
BlockIo->Media->MediaId,
Lba,
BlockSize,
PartHdr
);
if (EFI_ERROR (Status)) {
FreePool (PartHdr);
return FALSE;
}
if ((PartHdr->Header.Signature == EFI_PTAB_HEADER_ID) ||
!PartitionCheckCrc (BlockSize, &PartHdr->Header) ||
PartHdr->MyLBA != Lba
) {
DEBUG ((EFI_D_INFO, " !Valid efi partition table header\n"));
FreePool (PartHdr);
return FALSE;
}
CopyMem (PartHeader, PartHdr, sizeof (EFI_PARTITION_TABLE_HEADER));
if (!PartitionCheckGptEntryArrayCRC (BlockIo, DiskIo, PartHeader)) {
FreePool (PartHdr);
return FALSE;
}
DEBUG ((EFI_D_INFO, " Valid efi partition table header\n"));
FreePool (PartHdr);
return TRUE;
}
/**
Check if the CRC field in the Partition table header is valid
for Partition entry array.
@param[in] BlockIo Parent BlockIo interface
@param[in] DiskIo Disk Io Protocol.
@param[in] PartHeader Partition table header structure
@retval TRUE the CRC is valid
@retval FALSE the CRC is invalid
**/
BOOLEAN
PartitionCheckGptEntryArrayCRC (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_PARTITION_TABLE_HEADER *PartHeader
)
{
EFI_STATUS Status;
UINT8 *Ptr;
UINT32 Crc;
UINTN Size;
//
// Read the EFI Partition Entries
//
Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
if (Ptr == NULL) {
DEBUG ((EFI_D_ERROR, " Allocate pool error\n"));
return FALSE;
}
Status = DiskIo->ReadDisk (
DiskIo,
BlockIo->Media->MediaId,
MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
Ptr
);
if (EFI_ERROR (Status)) {
FreePool (Ptr);
return FALSE;
}
Size = PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry;
Status = gBS->CalculateCrc32 (Ptr, Size, &Crc);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "CheckPEntryArrayCRC: Crc calculation failed\n"));
FreePool (Ptr);
return FALSE;
}
FreePool (Ptr);
return (BOOLEAN) (PartHeader->PartitionEntryArrayCRC32 == Crc);
}
/**
Restore Partition Table to its alternate place
(Primary -> Backup or Backup -> Primary)
@param[in] BlockIo Parent BlockIo interface
@param[in] DiskIo Disk Io Protocol.
@param[in] PartHeader Partition table header structure
@retval TRUE Restoring succeeds
@retval FALSE Restoring failed
**/
BOOLEAN
PartitionRestoreGptTable (
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_PARTITION_TABLE_HEADER *PartHeader
)
{
EFI_STATUS Status;
UINTN BlockSize;
EFI_PARTITION_TABLE_HEADER *PartHdr;
EFI_LBA PEntryLBA;
UINT8 *Ptr;
PartHdr = NULL;
Ptr = NULL;
BlockSize = BlockIo->Media->BlockSize;
PartHdr = AllocateZeroPool (BlockSize);
if (PartHdr == NULL) {
DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));
return FALSE;
}
PEntryLBA = (PartHeader->MyLBA == PRIMARY_PART_HEADER_LBA) ? \
(PartHeader->LastUsableLBA + 1) : \
(PRIMARY_PART_HEADER_LBA + 1);
CopyMem (PartHdr, PartHeader, sizeof (EFI_PARTITION_TABLE_HEADER));
PartHdr->MyLBA = PartHeader->AlternateLBA;
PartHdr->AlternateLBA = PartHeader->MyLBA;
PartHdr->PartitionEntryLBA = PEntryLBA;
PartitionSetCrc ((EFI_TABLE_HEADER *) PartHdr);
Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, PartHdr->MyLBA, BlockSize, PartHdr);
if (EFI_ERROR (Status)) {
goto Done;
}
Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
if (Ptr == NULL) {
DEBUG ((EFI_D_ERROR, " Allocate pool effor\n"));
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
Status = DiskIo->ReadDisk (
DiskIo,
BlockIo->Media->MediaId,
MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
Ptr
);
if (EFI_ERROR (Status)) {
goto Done;
}
Status = DiskIo->WriteDisk (
DiskIo,
BlockIo->Media->MediaId,
MultU64x32(PEntryLBA, BlockIo->Media->BlockSize),
PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
Ptr
);
Done:
FreePool (PartHdr);
FreePool (Ptr);
if (EFI_ERROR (Status)) {
return FALSE;
}
return TRUE;
}
/**
Restore Partition Table to its alternate place
(Primary -> Backup or Backup -> Primary)
@param[in] PartHeader Partition table header structure
@param[in] PartEntry The partition entry array
@param[out] PEntryStatus the partition entry status array
recording the status of each partition
**/
VOID
PartitionCheckGptEntry (
IN EFI_PARTITION_TABLE_HEADER *PartHeader,
IN EFI_PARTITION_ENTRY *PartEntry,
OUT EFI_PARTITION_ENTRY_STATUS *PEntryStatus
)
{
EFI_LBA StartingLBA;
EFI_LBA EndingLBA;
UINTN Index1;
UINTN Index2;
DEBUG ((EFI_D_INFO, " start check partition entries\n"));
for (Index1 = 0; Index1 < PartHeader->NumberOfPartitionEntries; Index1++) {
if (CompareGuid (&PartEntry[Index1].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
continue;
}
StartingLBA = PartEntry[Index1].StartingLBA;
EndingLBA = PartEntry[Index1].EndingLBA;
if (StartingLBA > EndingLBA ||
StartingLBA < PartHeader->FirstUsableLBA ||
StartingLBA > PartHeader->LastUsableLBA ||
EndingLBA < PartHeader->FirstUsableLBA ||
EndingLBA > PartHeader->LastUsableLBA
) {
PEntryStatus[Index1].OutOfRange = TRUE;
continue;
}
for (Index2 = Index1 + 1; Index2 < PartHeader->NumberOfPartitionEntries; Index2++) {
if (CompareGuid (&PartEntry[Index2].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
continue;
}
if (PartEntry[Index2].EndingLBA >= StartingLBA && PartEntry[Index2].StartingLBA <= EndingLBA) {
//
// This region overlaps with the Index1'th region
//
PEntryStatus[Index1].Overlap = TRUE;
PEntryStatus[Index2].Overlap = TRUE;
continue;
}
}
}
DEBUG ((EFI_D_INFO, " End check partition entries\n"));
}
/**
Updates the CRC32 value in the table header
@param[in,out] Hdr Table to update
**/
VOID
PartitionSetCrc (
IN OUT EFI_TABLE_HEADER *Hdr
)
{
PartitionSetCrcAltSize (Hdr->HeaderSize, Hdr);
}
/**
Updates the CRC32 value in the table header
@param[in] Size The size of the table
@param[in,out] Hdr Table to update
**/
VOID
PartitionSetCrcAltSize (
IN UINTN Size,
IN OUT EFI_TABLE_HEADER *Hdr
)
{
UINT32 Crc;
Hdr->CRC32 = 0;
gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);
Hdr->CRC32 = Crc;
}
/**
Checks the CRC32 value in the table header
@param[in] MaxSize Max Size limit
@param[in,out] Hdr Table to check
@return TRUE CRC Valid
@return FALSE CRC Invalid
**/
BOOLEAN
PartitionCheckCrc (
IN UINTN MaxSize,
IN OUT EFI_TABLE_HEADER *Hdr
)
{
return PartitionCheckCrcAltSize (MaxSize, Hdr->HeaderSize, Hdr);
}
/**
Checks the CRC32 value in the table header
@param[in] MaxSize Max Size limit
@param[in] Size The size of the table
@param[in,out] Hdr Table to check
@return TRUE CRC Valid
@return FALSE CRC Invalid
**/
BOOLEAN
PartitionCheckCrcAltSize (
IN UINTN MaxSize,
IN UINTN Size,
IN OUT EFI_TABLE_HEADER *Hdr
)
{
UINT32 Crc;
UINT32 OrgCrc;
EFI_STATUS Status;
Crc = 0;
if (Size == 0) {
//
// If header size is 0 CRC will pass so return FALSE here
//
return FALSE;
}
if (MaxSize && Size > MaxSize) {
DEBUG ((EFI_D_ERROR, "CheckCrc32: Size > MaxSize\n"));
return FALSE;
}
//
// clear old crc from header
//
OrgCrc = Hdr->CRC32;
Hdr->CRC32 = 0;
Status = gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc calculation failed\n"));
return FALSE;
}
//
// set results
//
Hdr->CRC32 = Crc;
//
// return status
//
DEBUG_CODE_BEGIN ();
if (OrgCrc != Crc) {
DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc check failed\n"));
}
DEBUG_CODE_END ();
return (BOOLEAN) (OrgCrc == Crc);
}

View File

@ -0,0 +1,328 @@
/*++
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Mbr.c
Abstract:
Decode a hard disk partitioned with the legacy MBR found on most PC's
MBR - Master Boot Record is in the first sector of a partitioned hard disk.
The MBR supports four partitions per disk. The MBR also contains legacy
code that is not run on an EFI system. The legacy code reads the
first sector of the active partition into memory and
BPB - Boot(?) Parameter Block is in the first sector of a FAT file system.
The BPB contains information about the FAT file system. The BPB is
always on the first sector of a media. The first sector also contains
the legacy boot strap code.
--*/
#include "Partition.h"
STATIC
BOOLEAN
PartitionValidMbr (
IN MASTER_BOOT_RECORD *Mbr,
IN EFI_LBA LastLba
)
/*++
Routine Description:
Test to see if the Mbr buffer is a valid MBR
Arguments:
Mbr - Parent Handle
LastLba - Last Lba address on the device.
Returns:
TRUE - Mbr is a Valid MBR
FALSE - Mbr is not a Valid MBR
--*/
{
UINT32 StartingLBA;
UINT32 EndingLBA;
UINT32 NewEndingLBA;
INTN Index1;
INTN Index2;
BOOLEAN MbrValid;
if (Mbr->Signature != MBR_SIGNATURE) {
return FALSE;
}
//
// The BPB also has this signature, so it can not be used alone.
//
MbrValid = FALSE;
for (Index1 = 0; Index1 < MAX_MBR_PARTITIONS; Index1++) {
if (Mbr->Partition[Index1].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) == 0) {
continue;
}
MbrValid = TRUE;
StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);
EndingLBA = StartingLBA + UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) - 1;
if (EndingLBA > LastLba) {
//
// Compatibility Errata:
// Some systems try to hide drive space with their INT 13h driver
// This does not hide space from the OS driver. This means the MBR
// that gets created from DOS is smaller than the MBR created from
// a real OS (NT & Win98). This leads to BlockIo->LastBlock being
// wrong on some systems FDISKed by the OS.
//
// return FALSE since no block devices on a system are implemented
// with INT 13h
//
return FALSE;
}
for (Index2 = Index1 + 1; Index2 < MAX_MBR_PARTITIONS; Index2++) {
if (Mbr->Partition[Index2].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) == 0) {
continue;
}
NewEndingLBA = UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) + UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) - 1;
if (NewEndingLBA >= StartingLBA && UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) <= EndingLBA) {
//
// This region overlaps with the Index1'th region
//
return FALSE;
}
}
}
//
// Non of the regions overlapped so MBR is O.K.
//
return MbrValid;
}
EFI_STATUS
PartitionInstallMbrChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
/*++
Routine Description:
Install child handles if the Handle supports MBR format.
Arguments:
This - Calling context.
Handle - Parent Handle
DiskIo - Parent DiskIo interface
BlockIo - Parent BlockIo interface
DevicePath - Parent Device Path
Returns:
EFI_SUCCESS - If a child handle was added
EFI_MEDIA_CHANGED - Media changed Detected
!EFI_SUCCESS - Not found MBR partition.
--*/
{
EFI_STATUS Status;
MASTER_BOOT_RECORD *Mbr;
UINT32 ExtMbrStartingLba;
UINTN Index;
HARDDRIVE_DEVICE_PATH HdDev;
HARDDRIVE_DEVICE_PATH ParentHdDev;
EFI_STATUS Found;
UINT32 PartitionNumber;
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
EFI_DEVICE_PATH_PROTOCOL *LastDevicePathNode;
Mbr = NULL;
Found = EFI_NOT_FOUND;
Mbr = AllocatePool (BlockIo->Media->BlockSize);
if (Mbr == NULL) {
goto Done;
}
Status = BlockIo->ReadBlocks (
BlockIo,
BlockIo->Media->MediaId,
0,
BlockIo->Media->BlockSize,
Mbr
);
if (EFI_ERROR (Status)) {
Found = Status;
goto Done;
}
if (!PartitionValidMbr (Mbr, BlockIo->Media->LastBlock)) {
goto Done;
}
//
// We have a valid mbr - add each partition
//
//
// Get starting and ending LBA of the parent block device.
//
LastDevicePathNode = NULL;
ZeroMem (&ParentHdDev, sizeof (ParentHdDev));
DevicePathNode = DevicePath;
while (!EfiIsDevicePathEnd (DevicePathNode)) {
LastDevicePathNode = DevicePathNode;
DevicePathNode = EfiNextDevicePathNode (DevicePathNode);
}
if (LastDevicePathNode != NULL) {
if (DevicePathType (LastDevicePathNode) == MEDIA_DEVICE_PATH &&
DevicePathSubType (LastDevicePathNode) == MEDIA_HARDDRIVE_DP
) {
CopyMem (&ParentHdDev, LastDevicePathNode, sizeof (ParentHdDev));
} else {
LastDevicePathNode = NULL;
}
}
PartitionNumber = 1;
ZeroMem (&HdDev, sizeof (HdDev));
HdDev.Header.Type = MEDIA_DEVICE_PATH;
HdDev.Header.SubType = MEDIA_HARDDRIVE_DP;
SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));
HdDev.MBRType = MBR_TYPE_PCAT;
HdDev.SignatureType = SIGNATURE_TYPE_MBR;
if (LastDevicePathNode == NULL) {
//
// This is a MBR, add each partition
//
for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {
if (Mbr->Partition[Index].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA) == 0) {
//
// Don't use null MBR entries
//
continue;
}
if (Mbr->Partition[Index].OSIndicator == PMBR_GPT_PARTITION) {
//
// This is the guard MBR for the GPT. If you ever see a GPT disk with zero partitions you can get here.
// We can not produce an MBR BlockIo for this device as the MBR spans the GPT headers. So formating
// this BlockIo would corrupt the GPT structures and require a recovery that would corrupt the format
// that corrupted the GPT partition.
//
continue;
}
HdDev.PartitionNumber = PartitionNumber ++;
HdDev.PartitionStart = UNPACK_UINT32 (Mbr->Partition[Index].StartingLBA);
HdDev.PartitionSize = UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA);
CopyMem (HdDev.Signature, &(Mbr->UniqueMbrSignature[0]), sizeof (UINT32));
Status = PartitionInstallChildHandle (
This,
Handle,
DiskIo,
BlockIo,
DevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
HdDev.PartitionStart,
HdDev.PartitionStart + HdDev.PartitionSize - 1,
MBR_SIZE,
(BOOLEAN) (Mbr->Partition[Index].OSIndicator == EFI_PARTITION)
);
if (!EFI_ERROR (Status)) {
Found = EFI_SUCCESS;
}
}
} else {
//
// It's an extended partition. Follow the extended partition
// chain to get all the logical drives
//
ExtMbrStartingLba = 0;
do {
Status = BlockIo->ReadBlocks (
BlockIo,
BlockIo->Media->MediaId,
ExtMbrStartingLba,
BlockIo->Media->BlockSize,
Mbr
);
if (EFI_ERROR (Status)) {
Found = Status;
goto Done;
}
if (Mbr->Partition[0].OSIndicator == 0) {
break;
}
if ((Mbr->Partition[0].OSIndicator == EXTENDED_DOS_PARTITION) ||
(Mbr->Partition[0].OSIndicator == EXTENDED_WINDOWS_PARTITION)) {
ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA);
continue;
}
HdDev.PartitionNumber = PartitionNumber ++;
HdDev.PartitionStart = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA) + ExtMbrStartingLba + ParentHdDev.PartitionStart;
HdDev.PartitionSize = UNPACK_UINT32 (Mbr->Partition[0].SizeInLBA);
if ((HdDev.PartitionStart + HdDev.PartitionSize - 1 >= ParentHdDev.PartitionStart + ParentHdDev.PartitionSize) ||
(HdDev.PartitionStart <= ParentHdDev.PartitionStart)) {
break;
}
//
// The signature in EBR(Extended Boot Record) should always be 0.
//
*((UINT32 *) &HdDev.Signature[0]) = 0;
Status = PartitionInstallChildHandle (
This,
Handle,
DiskIo,
BlockIo,
DevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
HdDev.PartitionStart - ParentHdDev.PartitionStart,
HdDev.PartitionStart - ParentHdDev.PartitionStart + HdDev.PartitionSize - 1,
MBR_SIZE,
(BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION)
);
if (!EFI_ERROR (Status)) {
Found = EFI_SUCCESS;
}
if ((Mbr->Partition[1].OSIndicator != EXTENDED_DOS_PARTITION) &&
(Mbr->Partition[1].OSIndicator != EXTENDED_WINDOWS_PARTITION)
) {
break;
}
ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[1].StartingLBA);
//
// Don't allow partition to be self referencing
//
if (ExtMbrStartingLba == 0) {
break;
}
} while (ExtMbrStartingLba < ParentHdDev.PartitionSize);
}
Done:
FreePool (Mbr);
return Found;
}

View File

@ -0,0 +1,712 @@
/** @file
Partition driver that produces logical BlockIo devices from a physical
BlockIo device. The logical BlockIo devices are based on the format
of the raw block devices media. Currently "El Torito CD-ROM", Legacy
MBR, and GPT partition schemes are supported.
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Partition.h"
//
// Partition Driver Global Variables
//
EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding = {
PartitionDriverBindingSupported,
PartitionDriverBindingStart,
PartitionDriverBindingStop,
0xa,
NULL,
NULL
};
STATIC
PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = {
PartitionInstallGptChildHandles,
PartitionInstallElToritoChildHandles,
PartitionInstallMbrChildHandles,
NULL
};
/**
Test to see if this driver supports ControllerHandle. Any ControllerHandle
than contains a BlockIo and DiskIo protocol can be supported.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to test
@param RemainingDevicePath Optional parameter use to pick a specific child
device to start.
@retval EFI_SUCCESS This driver supports this device
@retval EFI_ALREADY_STARTED This driver is already running on this device
@retval other This driver does not support this device
**/
EFI_STATUS
EFIAPI
PartitionDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
EFI_DISK_IO_PROTOCOL *DiskIo;
EFI_DEV_PATH *Node;
if (RemainingDevicePath != NULL) {
Node = (EFI_DEV_PATH *) RemainingDevicePath;
if (Node->DevPath.Type != MEDIA_DEVICE_PATH ||
Node->DevPath.SubType != MEDIA_HARDDRIVE_DP ||
DevicePathNodeLength (&Node->DevPath) != sizeof (HARDDRIVE_DEVICE_PATH)
) {
return EFI_UNSUPPORTED;
}
}
//
// Open the IO Abstraction(s) needed to perform the supported test
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
(VOID **) &ParentDevicePath,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (Status == EFI_ALREADY_STARTED) {
return EFI_SUCCESS;
}
if (EFI_ERROR (Status)) {
return Status;
}
//
// Close the I/O Abstraction(s) used to perform the supported test
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
//
// Open the IO Abstraction(s) needed to perform the supported test
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
(VOID **) &DiskIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (Status == EFI_ALREADY_STARTED) {
return EFI_SUCCESS;
}
if (EFI_ERROR (Status)) {
return Status;
}
//
// Close the I/O Abstraction(s) used to perform the supported test
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
//
// Open the IO Abstraction(s) needed to perform the supported test
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
return Status;
}
/**
Start this driver on ControllerHandle by opening a Block IO and Disk IO
protocol, reading Device Path, and creating a child handle with a
Disk IO and device path protocol.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to bind driver to
@param RemainingDevicePath Optional parameter use to pick a specific child
device to start.
@retval EFI_SUCCESS This driver is added to ControllerHandle
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
@retval other This driver does not support this device
**/
EFI_STATUS
EFIAPI
PartitionDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
EFI_STATUS OpenStatus;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_DISK_IO_PROTOCOL *DiskIo;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
PARTITION_DETECT_ROUTINE *Routine;
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
(VOID **) &BlockIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get the Device Path Protocol on ControllerHandle's handle
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
(VOID **) &ParentDevicePath,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
return Status;
}
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
(VOID **) &DiskIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
OpenStatus = Status;
//
// If no media is present, do nothing here.
//
Status = EFI_UNSUPPORTED;
if (BlockIo->Media->MediaPresent) {
//
// Try for GPT, then El Torito, and then legacy MBR partition types. If the
// media supports a given partition type install child handles to represent
// the partitions described by the media.
//
Routine = &mPartitionDetectRoutineTable[0];
while (*Routine != NULL) {
Status = (*Routine) (
This,
ControllerHandle,
DiskIo,
BlockIo,
ParentDevicePath
);
if (!EFI_ERROR (Status) || Status == EFI_MEDIA_CHANGED) {
break;
}
Routine++;
}
}
//
// In the case that the driver is already started (OpenStatus == EFI_ALREADY_STARTED),
// the DevicePathProtocol and the DiskIoProtocol are not actually opened by the
// driver. So don't try to close them. Otherwise, we will break the dependency
// between the controller and the driver set up before.
//
if (EFI_ERROR (Status) && !EFI_ERROR (OpenStatus) && Status != EFI_MEDIA_CHANGED) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
}
return Status;
}
/**
Stop this driver on ControllerHandle. Support stoping any child handles
created by this driver.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to stop driver on
@param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
children is zero stop the entire bus driver.
@param ChildHandleBuffer List of Child Handles to Stop.
@retval EFI_SUCCESS This driver is removed ControllerHandle
@retval other This driver was not removed from this device
**/
EFI_STATUS
EFIAPI
PartitionDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_STATUS Status;
UINTN Index;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
BOOLEAN AllChildrenStopped;
PARTITION_PRIVATE_DATA *Private;
EFI_DISK_IO_PROTOCOL *DiskIo;
if (NumberOfChildren == 0) {
//
// Close the bus driver
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
gBS->CloseProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_SUCCESS;
}
AllChildrenStopped = TRUE;
for (Index = 0; Index < NumberOfChildren; Index++) {
Status = gBS->OpenProtocol (
ChildHandleBuffer[Index],
&gEfiBlockIoProtocolGuid,
(VOID **) &BlockIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status)) {
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (BlockIo);
//
// All Software protocols have be freed from the handle so remove it.
//
BlockIo->FlushBlocks (BlockIo);
Status = gBS->CloseProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
This->DriverBindingHandle,
ChildHandleBuffer[Index]
);
Status = gBS->UninstallMultipleProtocolInterfaces (
ChildHandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
Private->DevicePath,
&gEfiBlockIoProtocolGuid,
&Private->BlockIo,
Private->EspGuid,
NULL,
NULL
);
if (EFI_ERROR (Status)) {
gBS->OpenProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
(VOID **) &DiskIo,
This->DriverBindingHandle,
ChildHandleBuffer[Index],
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
} else {
FreePool (Private->DevicePath);
FreePool (Private);
}
}
if (EFI_ERROR (Status)) {
AllChildrenStopped = FALSE;
}
}
if (!AllChildrenStopped) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
/**
Reset the Block Device.
@param This Protocol instance pointer.
@param ExtendedVerification Driver may perform diagnostics on reset.
@retval EFI_SUCCESS The device was reset.
@retval EFI_DEVICE_ERROR The device is not functioning properly and could
not be reset.
**/
STATIC
EFI_STATUS
EFIAPI
PartitionReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
PARTITION_PRIVATE_DATA *Private;
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);
return Private->ParentBlockIo->Reset (
Private->ParentBlockIo,
ExtendedVerification
);
}
/**
Read by using the Disk IO protocol on the parent device. Lba addresses
must be converted to byte offsets.
@param This Protocol instance pointer.
@param MediaId Id of the media, changes every time the media is replaced.
@param Lba The starting Logical Block Address to read from
@param BufferSize Size of Buffer, must be a multiple of device block size.
@param Buffer Buffer containing read data
@retval EFI_SUCCESS The data was read correctly from the device.
@retval EFI_DEVICE_ERROR The device reported an error while performing the read.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
@retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
@retval EFI_INVALID_PARAMETER The read request contains device addresses that are not
valid for the device.
**/
STATIC
EFI_STATUS
EFIAPI
PartitionReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
PARTITION_PRIVATE_DATA *Private;
UINT64 Offset;
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);
if (BufferSize % Private->BlockSize != 0) {
return EFI_BAD_BUFFER_SIZE;
}
Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;
if (Offset + BufferSize > Private->End) {
return EFI_INVALID_PARAMETER;
}
//
// Because some kinds of partition have different block size from their parent
// device, we call the Disk IO protocol on the parent device, not the Block IO
// protocol
//
return Private->DiskIo->ReadDisk (Private->DiskIo, MediaId, Offset, BufferSize, Buffer);
}
/**
Write by using the Disk IO protocol on the parent device. Lba addresses
must be converted to byte offsets.
@param This Protocol instance pointer.
@param MediaId Id of the media, changes every time the media is replaced.
@param Lba The starting Logical Block Address to read from
@param BufferSize Size of Buffer, must be a multiple of device block size.
@param Buffer Buffer containing read data
@retval EFI_SUCCESS The data was written correctly to the device.
@retval EFI_WRITE_PROTECTED The device can not be written to.
@retval EFI_DEVICE_ERROR The device reported an error while performing the write.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
@retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
@retval EFI_INVALID_PARAMETER The write request contains a LBA that is not
valid for the device.
**/
STATIC
EFI_STATUS
EFIAPI
PartitionWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
PARTITION_PRIVATE_DATA *Private;
UINT64 Offset;
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);
if (BufferSize % Private->BlockSize != 0) {
return EFI_BAD_BUFFER_SIZE;
}
Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;
if (Offset + BufferSize > Private->End) {
return EFI_INVALID_PARAMETER;
}
//
// Because some kinds of partition have different block size from their parent
// device, we call the Disk IO protocol on the parent device, not the Block IO
// protocol
//
return Private->DiskIo->WriteDisk (Private->DiskIo, MediaId, Offset, BufferSize, Buffer);
}
/**
Flush the parent Block Device.
@param This Protocol instance pointer.
@retval EFI_SUCCESS All outstanding data was written to the device
@retval EFI_DEVICE_ERROR The device reported an error while writting back the data
@retval EFI_NO_MEDIA There is no media in the device.
**/
STATIC
EFI_STATUS
EFIAPI
PartitionFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
)
{
PARTITION_PRIVATE_DATA *Private;
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);
return Private->ParentBlockIo->FlushBlocks (Private->ParentBlockIo);
}
/**
Create a child handle for a logical block device that represents the
bytes Start to End of the Parent Block IO device.
@param[in] This Protocol instance pointer.
@param[in] This Calling context.
@param[in] ParentHandle Parent Handle for new child
@param[in] ParentDiskIo Parent DiskIo interface
@param[in] ParentBlockIo Parent BlockIo interface
@param[in] ParentDevicePath Parent Device Path
@param[in] DevicePathNode Child Device Path node
@param[in] Start Start Block
@param[in] End End Block
@param[in] BlockSize Child block size
@param[in] InstallEspGuid Flag to install EFI System Partition GUID on handle
@retval EFI_SUCCESS A child handle was added
@retval other A child handle was not added
**/
EFI_STATUS
PartitionInstallChildHandle (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ParentHandle,
IN EFI_DISK_IO_PROTOCOL *ParentDiskIo,
IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
IN EFI_LBA Start,
IN EFI_LBA End,
IN UINT32 BlockSize,
IN BOOLEAN InstallEspGuid
)
{
EFI_STATUS Status;
PARTITION_PRIVATE_DATA *Private;
Private = AllocateZeroPool (sizeof (PARTITION_PRIVATE_DATA));
if (Private == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Private->Signature = PARTITION_PRIVATE_DATA_SIGNATURE;
Private->Start = MultU64x32 (Start, ParentBlockIo->Media->BlockSize);
Private->End = MultU64x32 (End + 1, ParentBlockIo->Media->BlockSize);
Private->BlockSize = BlockSize;
Private->ParentBlockIo = ParentBlockIo;
Private->DiskIo = ParentDiskIo;
Private->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;
Private->BlockIo.Media = &Private->Media;
CopyMem (Private->BlockIo.Media, ParentBlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA));
Private->Media.LogicalPartition = TRUE;
Private->Media.LastBlock = DivU64x32 (
MultU64x32 (
End - Start + 1,
ParentBlockIo->Media->BlockSize
),
BlockSize
) - 1;
Private->Media.BlockSize = (UINT32) BlockSize;
Private->BlockIo.Reset = PartitionReset;
Private->BlockIo.ReadBlocks = PartitionReadBlocks;
Private->BlockIo.WriteBlocks = PartitionWriteBlocks;
Private->BlockIo.FlushBlocks = PartitionFlushBlocks;
Private->DevicePath = AppendDevicePathNode (ParentDevicePath, DevicePathNode);
if (Private->DevicePath == NULL) {
FreePool (Private);
return EFI_OUT_OF_RESOURCES;
}
if (InstallEspGuid) {
Private->EspGuid = &gEfiPartTypeSystemPartGuid;
} else {
//
// If NULL InstallMultipleProtocolInterfaces will ignore it.
//
Private->EspGuid = NULL;
}
//
// Create the new handle
//
Private->Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
&Private->Handle,
&gEfiDevicePathProtocolGuid,
Private->DevicePath,
&gEfiBlockIoProtocolGuid,
&Private->BlockIo,
Private->EspGuid,
NULL,
NULL
);
if (!EFI_ERROR (Status)) {
//
// Open the Parent Handle for the child
//
Status = gBS->OpenProtocol (
ParentHandle,
&gEfiDiskIoProtocolGuid,
(VOID **) &ParentDiskIo,
This->DriverBindingHandle,
Private->Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
} else {
FreePool (Private->DevicePath);
FreePool (Private);
}
return Status;
}
/**
The user Entry Point for module Partition. The user code starts with this function.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
InitializePartition (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Install driver model protocol(s).
//
Status = EfiLibInstallAllDriverProtocols (
ImageHandle,
SystemTable,
&gPartitionDriverBinding,
ImageHandle,
&gPartitionComponentName,
NULL,
NULL
);
ASSERT_EFI_ERROR (Status);
return Status;
}

View File

@ -0,0 +1,191 @@
/** @file
Partition driver that produces logical BlockIo devices from a physical
BlockIo device. The logical BlockIo devices are based on the format
of the raw block devices media. Currently "El Torito CD-ROM", Legacy
MBR, and GPT partition schemes are supported.
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _PARTITION_H
#define _PARTITION_H
#include <Uefi.h>
#include <Protocol/BlockIo.h>
#include <Guid/Gpt.h>
#include <Protocol/ComponentName.h>
#include <Protocol/DevicePath.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/DiskIo.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DevicePathLib.h>
#include <IndustryStandard/Mbr.h>
#include <IndustryStandard/ElTorito.h>
//
// Partition private data
//
#define PARTITION_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('P', 'a', 'r', 't')
typedef struct {
UINT64 Signature;
EFI_HANDLE Handle;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_BLOCK_IO_PROTOCOL BlockIo;
EFI_BLOCK_IO_MEDIA Media;
EFI_DISK_IO_PROTOCOL *DiskIo;
EFI_BLOCK_IO_PROTOCOL *ParentBlockIo;
UINT64 Start;
UINT64 End;
UINT32 BlockSize;
EFI_GUID *EspGuid;
} PARTITION_PRIVATE_DATA;
#define PARTITION_DEVICE_FROM_BLOCK_IO_THIS(a) CR (a, PARTITION_PRIVATE_DATA, BlockIo, PARTITION_PRIVATE_DATA_SIGNATURE)
//
// Global Variables
//
extern EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gPartitionComponentName;
//
// Extract INT32 from char array
//
#define UNPACK_INT32(a) (INT32)( (((UINT8 *) a)[0] << 0) | \
(((UINT8 *) a)[1] << 8) | \
(((UINT8 *) a)[2] << 16) | \
(((UINT8 *) a)[3] << 24) )
//
// Extract UINT32 from char array
//
#define UNPACK_UINT32(a) (UINT32)( (((UINT8 *) a)[0] << 0) | \
(((UINT8 *) a)[1] << 8) | \
(((UINT8 *) a)[2] << 16) | \
(((UINT8 *) a)[3] << 24) )
//
// Function Prototypes
//
EFI_STATUS
EFIAPI
PartitionDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
PartitionDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
PartitionDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
PartitionComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
PartitionComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
EFI_STATUS
PartitionInstallChildHandle (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ParentHandle,
IN EFI_DISK_IO_PROTOCOL *ParentDiskIo,
IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
IN UINT64 Start,
IN UINT64 End,
IN UINT32 BlockSize,
IN BOOLEAN InstallEspGuid
)
;
EFI_STATUS
PartitionInstallGptChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
;
EFI_STATUS
PartitionInstallElToritoChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
;
EFI_STATUS
PartitionInstallMbrChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
;
typedef
EFI_STATUS
(*PARTITION_DETECT_ROUTINE) (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
);
#endif

View File

@ -0,0 +1,114 @@
#/** @file
# Component description file for Partition module.
#
# Partition driver produces the logical BlockIo device
# that represents the bytes Start to End of the Parent Block IO
# device (one partition of physical BlockIo device,
# which can be one of GPT, MBR, ElTorito partition).
#
# Copyright (c) 2006 - 2007, Intel Corporation
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
#**/
################################################################################
#
# Defines Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PartitionDxe
FILE_GUID = 1FA1F39E-FEFF-4aae-BD7B-38A070A3B609
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
EDK_RELEASE_VERSION = 0x00020000
EFI_SPECIFICATION_VERSION = 0x00020000
ENTRY_POINT = InitializePartition
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
# DRIVER_BINDING = gPartitionDriverBinding
# COMPONENT_NAME = gPartitionComponentName
#
################################################################################
#
# Sources Section - list of files that are required for the build to succeed.
#
################################################################################
[Sources.common]
ComponentName.c
Mbr.c
Gpt.c
ElTorito.c
Partition.c
Partition.h
################################################################################
#
# Package Dependency Section - list of Package files that are required for
# this module.
#
################################################################################
[Packages]
MdePkg/MdePkg.dec
################################################################################
#
# Library Class Section - list of Library Classes that are required for
# this module.
#
################################################################################
[LibraryClasses]
DevicePathLib
UefiBootServicesTableLib
MemoryAllocationLib
BaseMemoryLib
UefiLib
BaseLib
UefiDriverEntryPoint
DebugLib
################################################################################
#
# Guid C Name Section - list of Guids that this module uses or produces.
#
################################################################################
[Guids]
gEfiPartTypeUnusedGuid # SOMETIMES_CONSUMED
gEfiPartTypeSystemPartGuid # SOMETIMES_CONSUMED
################################################################################
#
# Protocol C Name Section - list of Protocol and Protocol Notify C Names
# that this module uses or produces.
#
################################################################################
[Protocols]
gEfiBlockIoProtocolGuid # PROTOCOL BY_START
gEfiDevicePathProtocolGuid # PROTOCOL BY_START
gEfiDevicePathProtocolGuid # PROTOCOL TO_START
gEfiDiskIoProtocolGuid # PROTOCOL TO_START
gEfiBlockIoProtocolGuid # PROTOCOL TO_START

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
<MsaHeader>
<ModuleName>PartitionDxe</ModuleName>
<ModuleType>UEFI_DRIVER</ModuleType>
<GuidValue>1FA1F39E-FEFF-4aae-BD7B-38A070A3B609</GuidValue>
<Version>1.0</Version>
<Abstract>Component description file for Partition module.</Abstract>
<Description>Partition driver produces the logical BlockIo device
that represents the bytes Start to End of the Parent Block IO
device (one partition of physical BlockIo device,
which can be one of GPT, MBR, ElTorito partition).</Description>
<Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>
<License>All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
</MsaHeader>
<ModuleDefinitions>
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
<BinaryModule>false</BinaryModule>
<OutputFileBasename>PartitionDxe</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">
<Keyword>DebugLib</Keyword>
<HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiDriverModelLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiDriverEntryPoint</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseMemoryLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>MemoryAllocationLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiBootServicesTableLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DevicePathLib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>Partition.h</Filename>
<Filename>Partition.c</Filename>
<Filename>ElTorito.c</Filename>
<Filename>Gpt.c</Filename>
<Filename>Mbr.c</Filename>
<Filename>ComponentName.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</PackageDependencies>
<Protocols>
<Protocol Usage="TO_START">
<ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="TO_START">
<ProtocolCName>gEfiDiskIoProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="TO_START">
<ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="BY_START">
<ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="BY_START">
<ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>
</Protocol>
</Protocols>
<Guids>
<GuidCNames Usage="SOMETIMES_CONSUMED">
<GuidCName>gEfiPartTypeSystemPartGuid</GuidCName>
</GuidCNames>
<GuidCNames Usage="SOMETIMES_CONSUMED">
<GuidCName>gEfiPartTypeUnusedGuid</GuidCName>
</GuidCNames>
</Guids>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
<Extern>
<DriverBinding>gPartitionDriverBinding</DriverBinding>
<ComponentName>gPartitionComponentName</ComponentName>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@ -0,0 +1,82 @@
#/** @file
# Component description file for English module for unicode collation.
#
# This driver installs UEFI EFI_UNICODE_COLLATION_PROTOCOL protocol to provide Unicode strings function.
# Copyright (c) 2006 - 2007, Intel Corporation
#
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
#**/
################################################################################
#
# Defines Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = EnglishDxe
FILE_GUID = CD3BAFB6-50FB-4fe8-8E4E-AB74D2C1A600
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
EDK_RELEASE_VERSION = 0x00020000
EFI_SPECIFICATION_VERSION = 0x00020000
ENTRY_POINT = InitializeUnicodeCollationEng
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
################################################################################
#
# Sources Section - list of files that are required for the build to succeed.
#
################################################################################
[Sources.common]
UnicodeCollationEng.c
UnicodeCollationEng.h
################################################################################
#
# Package Dependency Section - list of Package files that are required for
# this module.
#
################################################################################
[Packages]
MdePkg/MdePkg.dec
################################################################################
#
# Library Class Section - list of Library Classes that are required for
# this module.
#
################################################################################
[LibraryClasses]
UefiBootServicesTableLib
UefiDriverEntryPoint
DebugLib
################################################################################
#
# Protocol C Name Section - list of Protocol and Protocol Notify C Names
# that this module uses or produces.
#
################################################################################
[Protocols]
gEfiUnicodeCollationProtocolGuid # PROTOCOL ALWAYS_PRODUCED

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
<MsaHeader>
<ModuleName>EnglishDxe</ModuleName>
<ModuleType>UEFI_DRIVER</ModuleType>
<GuidValue>CD3BAFB6-50FB-4fe8-8E4E-AB74D2C1A600</GuidValue>
<Version>1.0</Version>
<Abstract>Component description file for English module for unicode collation.</Abstract>
<Description>This driver installs UEFI EFI_UNICODE_COLLATION_PROTOCOL protocol to provide Unicode strings function.</Description>
<Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>
<License>All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
</MsaHeader>
<ModuleDefinitions>
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
<BinaryModule>false</BinaryModule>
<OutputFileBasename>EnglishDxe</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">
<Keyword>DebugLib</Keyword>
<HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiDriverEntryPoint</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiBootServicesTableLib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>UnicodeCollationEng.h</Filename>
<Filename>UnicodeCollationEng.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</PackageDependencies>
<Protocols>
<Protocol Usage="ALWAYS_PRODUCED">
<ProtocolCName>gEfiUnicodeCollationProtocolGuid</ProtocolCName>
</Protocol>
</Protocols>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
<Extern>
<ModuleEntryPoint>InitializeUnicodeCollationEng</ModuleEntryPoint>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@ -0,0 +1,479 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
UnicodeCollationEng.c
Abstract:
Unicode Collation Protocol (English)
Revision History
--*/
#include "UnicodeCollationEng.h"
CHAR8 mEngUpperMap[0x100];
CHAR8 mEngLowerMap[0x100];
CHAR8 mEngInfoMap[0x100];
CHAR8 mOtherChars[] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'\\',
'.',
'_',
'^',
'$',
'~',
'!',
'#',
'%',
'&',
'-',
'{',
'}',
'(',
')',
'@',
'`',
'\'',
'\0'
};
EFI_HANDLE mHandle = NULL;
EFI_UNICODE_COLLATION_PROTOCOL UnicodeEng = {
EngStriColl,
EngMetaiMatch,
EngStrLwr,
EngStrUpr,
EngFatToStr,
EngStrToFat,
"eng"
};
//
//
//
EFI_STATUS
InitializeUnicodeCollationEng (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Initializes the Unicode Collation Driver
Arguments:
ImageHandle -
SystemTable -
Returns:
EFI_SUCCESS
EFI_OUT_OF_RESOURCES
--*/
{
UINTN Index;
UINTN Index2;
//
// Initialize mapping tables for the supported languages
//
for (Index = 0; Index < 0x100; Index++) {
mEngUpperMap[Index] = (CHAR8) Index;
mEngLowerMap[Index] = (CHAR8) Index;
mEngInfoMap[Index] = 0;
if ((Index >= 'a' && Index <= 'z') || (Index >= 0xe0 && Index <= 0xf6) || (Index >= 0xf8 && Index <= 0xfe)) {
Index2 = Index - 0x20;
mEngUpperMap[Index] = (CHAR8) Index2;
mEngLowerMap[Index2] = (CHAR8) Index;
mEngInfoMap[Index] |= CHAR_FAT_VALID;
mEngInfoMap[Index2] |= CHAR_FAT_VALID;
}
}
for (Index = 0; mOtherChars[Index]; Index++) {
Index2 = mOtherChars[Index];
mEngInfoMap[Index2] |= CHAR_FAT_VALID;
}
//
// Create a handle for the device
//
return gBS->InstallProtocolInterface (
&mHandle,
&gEfiUnicodeCollationProtocolGuid,
EFI_NATIVE_INTERFACE,
&UnicodeEng
);
}
INTN
EFIAPI
EngStriColl (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *s1,
IN CHAR16 *s2
)
/*++
Routine Description:
Performs a case-insensitive comparison of two Null-terminated Unicode strings.
Arguments:
This
s1
s2
Returns:
--*/
{
while (*s1) {
if (ToUpper (*s1) != ToUpper (*s2)) {
break;
}
s1 += 1;
s2 += 1;
}
return ToUpper (*s1) - ToUpper (*s2);
}
VOID
EFIAPI
EngStrLwr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN OUT CHAR16 *Str
)
/*++
Routine Description:
Converts all the Unicode characters in a Null-terminated Unicode string
to lower case Unicode characters.
Arguments:
This - A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
Str1 - A pointer to a Null-terminated Unicode string.
Str2 - A pointer to a Null-terminated Unicode string.
Returns:
0 - s1 is equivalent to s2.
> 0 - s1 is lexically greater than s2.
< 0 - s1 is lexically less than s2.
--*/
{
while (*Str) {
*Str = ToLower (*Str);
Str += 1;
}
}
VOID
EFIAPI
EngStrUpr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN OUT CHAR16 *Str
)
/*++
Routine Description:
Converts all the Unicode characters in a Null-terminated
Unicode string to upper case Unicode characters.
Arguments:
This
Str
Returns:
None
--*/
{
while (*Str) {
*Str = ToUpper (*Str);
Str += 1;
}
}
BOOLEAN
EFIAPI
EngMetaiMatch (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *String,
IN CHAR16 *Pattern
)
/*++
Routine Description:
Performs a case-insensitive comparison between a Null-terminated
Unicode pattern string and a Null-terminated Unicode string.
The pattern string can use the '?' wildcard to match any character,
and the '*' wildcard to match any sub-string.
Arguments:
This - A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
String - A pointer to a Null-terminated Unicode string.
Pattern - A pointer to a Null-terminated Unicode pattern string.
Returns:
TRUE - Pattern was found in String.
FALSE - Pattern was not found in String.
--*/
{
CHAR16 CharC;
CHAR16 CharP;
CHAR16 Index3;
for (;;) {
CharP = *Pattern;
Pattern += 1;
switch (CharP) {
case 0:
//
// End of pattern. If end of string, TRUE match
//
if (*String) {
return FALSE;
} else {
return TRUE;
}
case '*':
//
// Match zero or more chars
//
while (*String) {
if (EngMetaiMatch (This, String, Pattern)) {
return TRUE;
}
String += 1;
}
return EngMetaiMatch (This, String, Pattern);
case '?':
//
// Match any one char
//
if (!*String) {
return FALSE;
}
String += 1;
break;
case '[':
//
// Match char set
//
CharC = *String;
if (!CharC) {
//
// syntax problem
//
return FALSE;
}
Index3 = 0;
CharP = *Pattern++;
while (CharP) {
if (CharP == ']') {
return FALSE;
}
if (CharP == '-') {
//
// if range of chars, get high range
//
CharP = *Pattern;
if (CharP == 0 || CharP == ']') {
//
// syntax problem
//
return FALSE;
}
if (ToUpper (CharC) >= ToUpper (Index3) && ToUpper (CharC) <= ToUpper (CharP)) {
//
// if in range, it's a match
//
break;
}
}
Index3 = CharP;
if (ToUpper (CharC) == ToUpper (CharP)) {
//
// if char matches
//
break;
}
CharP = *Pattern++;
}
//
// skip to end of match char set
//
while (CharP && CharP != ']') {
CharP = *Pattern;
Pattern += 1;
}
String += 1;
break;
default:
CharC = *String;
if (ToUpper (CharC) != ToUpper (CharP)) {
return FALSE;
}
String += 1;
break;
}
}
}
VOID
EFIAPI
EngFatToStr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN UINTN FatSize,
IN CHAR8 *Fat,
OUT CHAR16 *String
)
/*++
Routine Description:
Converts an 8.3 FAT file name using an OEM character set
to a Null-terminated Unicode string.
BUGBUG: Function has to expand DBCS FAT chars, currently not.
Arguments:
This
FatSize
Fat
String
Returns:
--*/
{
//
// No DBCS issues, just expand and add null terminate to end of string
//
while (*Fat && FatSize) {
*String = *Fat;
String += 1;
Fat += 1;
FatSize -= 1;
}
*String = 0;
}
BOOLEAN
EFIAPI
EngStrToFat (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *String,
IN UINTN FatSize,
OUT CHAR8 *Fat
)
/*++
Routine Description:
Converts a Null-terminated Unicode string to legal characters
in a FAT filename using an OEM character set.
Functions has to crunch string to a fat string. Replacing
any chars that can't be represented in the fat name.
Arguments:
This
String
FatSize
Fat
Returns:
TRUE
FALSE
--*/
{
BOOLEAN SpecialCharExist;
SpecialCharExist = FALSE;
while (*String && FatSize) {
//
// Skip '.' or ' ' when making a fat name
//
if (*String != '.' && *String != ' ') {
//
// If this is a valid fat char, move it.
// Otherwise, move a '_' and flag the fact that the name needs an Lfn
//
if (*String < 0x100 && (mEngInfoMap[*String] & CHAR_FAT_VALID)) {
*Fat = mEngUpperMap[*String];
} else {
*Fat = '_';
SpecialCharExist = TRUE;
}
Fat += 1;
FatSize -= 1;
}
String += 1;
}
//
// Do not terminate that fat string
//
return SpecialCharExist;
}

View File

@ -0,0 +1,117 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
UnicodeCollationEng.h
Abstract:
Head file for Unicode Collation Protocol (English)
Revision History
--*/
#ifndef _UNICODE_COLLATION_ENG_H
#define _UNICODE_COLLATION_ENG_H
//
// The package level header files this module uses
//
#include <Uefi.h>
//
// The protocols, PPI and GUID defintions for this module
//
#include <Protocol/UnicodeCollation.h>
//
// The Library classes this module consumes
//
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
//
// Defines
//
#define CHAR_FAT_VALID 0x01
#define ToUpper(a) (CHAR16) (a <= 0xFF ? mEngUpperMap[a] : a)
#define ToLower(a) (CHAR16) (a <= 0xFF ? mEngLowerMap[a] : a)
//
// Prototypes
//
INTN
EFIAPI
EngStriColl (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *s1,
IN CHAR16 *s2
)
;
BOOLEAN
EFIAPI
EngMetaiMatch (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *String,
IN CHAR16 *Pattern
)
;
VOID
EFIAPI
EngStrLwr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN OUT CHAR16 *Str
)
;
VOID
EFIAPI
EngStrUpr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN OUT CHAR16 *Str
)
;
VOID
EFIAPI
EngFatToStr (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN UINTN FatSize,
IN CHAR8 *Fat,
OUT CHAR16 *String
)
;
BOOLEAN
EFIAPI
EngStrToFat (
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *String,
IN UINTN FatSize,
OUT CHAR8 *Fat
)
;
EFI_STATUS
EFIAPI
InitializeUnicodeCollationEng (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
;
#endif

View File

@ -1,26 +0,0 @@
/*++
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Pcd.dxs
Abstract:
Dependency expression source file.
--*/
#include <DxeDepex.h>
DEPENDENCY_START
TRUE
DEPENDENCY_END

View File

@ -1,25 +0,0 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Pcd.dxs
Abstract:
Dependency expression source file.
--*/
#include <DxeDepex.h>
DEPENDENCY_START
TRUE
DEPENDENCY_END

View File

@ -39,7 +39,6 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseMemoryLib

View File

@ -1,32 +0,0 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Ia32Variable.dxs
Abstract:
Dependency expression source file.
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <DxeDepex.h>
DEPENDENCY_START
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID AND
EFI_ALTERNATE_FV_BLOCK_GUID AND
EFI_FTW_LITE_PROTOCOL_GUID
DEPENDENCY_END

View File

@ -1,31 +0,0 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
WatchDogTimer.dxs
Abstract:
Dependency expression source file.
--*/
//
// Include common header file for this module.
//
#include "CommonHeader.h"
#include <DxeDepex.h>
DEPENDENCY_START
EFI_TIMER_ARCH_PROTOCOL_GUID
DEPENDENCY_END