This patch contains basic support to detect UDF volumes on available
discs and then install new child handles that layer on devices that
provide EFI_BLOCK_IO_PROTOCOL/EFI_DISK_IO_PROTOCOL in them.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 MdeModulePkg/MdeModulePkg.dsc                      |   1 +
 MdeModulePkg/Universal/Disk/UdfDxe/ComponentName.c | 185 +++++
 .../Universal/Disk/UdfDxe/FileSystemOperations.c   | 763 ++++++++++++++++++
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c           | 349 ++++++++
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h           | 879 +++++++++++++++++++++
 MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf      |  63 ++
 6 files changed, 2240 insertions(+)
 create mode 100644 MdeModulePkg/Universal/Disk/UdfDxe/ComponentName.c
 create mode 100644 MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
 create mode 100644 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
 create mode 100644 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
 create mode 100644 MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf

diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 60edd99..411008d 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -270,6 +270,7 @@
   MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
   MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
   MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
+  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
   MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
   
MdeModulePkg/Universal/MemoryTest/GenericMemoryTestDxe/GenericMemoryTestDxe.inf
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/ComponentName.c 
b/MdeModulePkg/Universal/Disk/UdfDxe/ComponentName.c
new file mode 100644
index 0000000..32fd600
--- /dev/null
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/ComponentName.c
@@ -0,0 +1,185 @@
+/** @file
+  UEFI Component Name protocol for UDF filesystem driver.
+
+Copyright (c) 2014 Paulo Alcantara <pca...@zytor.com><BR>
+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 "Udf.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gUdfComponentName = 
{
+  UdfComponentNameGetDriverName,
+  UdfComponentNameGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUdfComponentName2 
= {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UdfComponentNameGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UdfComponentNameGetControllerName,
+  "en"
+};
+
+//
+// Driver name table for Udf module.
+// It is shared by the implementation of ComponentName & ComponentName2 
Protocol.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUdfDriverNameTable[] = 
{
+  {
+    "eng;en",
+    L"UDF Filesystem Driver"
+  },
+  {
+    NULL,
+    NULL
+  }
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL 
or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          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 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       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
+UdfComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mUdfDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &gUdfComponentName)
+           );
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified 
by
+  Language, then a pointer to the controller name is returned in 
ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not 
currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL 
or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  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[in]       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[in]          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 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   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 NULL.
+
+  @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
+UdfComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        
OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  )
+{
+  return EFI_UNSUPPORTED;
+}
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c 
b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
new file mode 100644
index 0000000..5492494
--- /dev/null
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
@@ -0,0 +1,763 @@
+/** @file
+  UDF filesystem driver.
+
+Copyright (c) 2014 Paulo Alcantara <pca...@zytor.com><BR>
+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 "Udf.h"
+
+UDF_STANDARD_IDENTIFIER gUdfStandardIdentifiers[STANDARD_IDENTIFIERS_NO] = {
+  { { 'B', 'E', 'A', '0', '1' } },
+  { { 'N', 'S', 'R', '0', '2' } },
+  { { 'N', 'S', 'R', '0', '3' } },
+  { { 'T', 'E', 'A', '0', '1' } },
+};
+
+/**
+  Open the root directory on a volume.
+
+  @param  This Protocol instance pointer.
+  @param  Root Returns an Open file handle for the root directory
+
+  @retval EFI_SUCCESS          The device was opened.
+  @retval EFI_UNSUPPORTED      This volume does not support the file system.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_ACCESS_DENIED    The service denied access to the file.
+  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of 
resources.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfOpenVolume (
+  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL     *This,
+  OUT EFI_FILE_PROTOCOL                  **Root
+  )
+{
+  EFI_TPL                                OldTpl;
+  EFI_STATUS                             Status;
+  PRIVATE_UDF_SIMPLE_FS_DATA             *PrivFsData;
+  PRIVATE_UDF_FILE_DATA                  *PrivFileData;
+  UDF_PARTITION_DESCRIPTOR               PartitionDesc;
+  UDF_LOGICAL_VOLUME_DESCRIPTOR          LogicalVolDesc;
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (This);
+
+  PrivFileData = AllocateZeroPool (sizeof (PRIVATE_UDF_FILE_DATA));
+  if (!PrivFileData) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  Status = FindRootDirectory (
+                  PrivFsData->BlockIo,
+                 PrivFsData->DiskIo,
+                 &PartitionDesc,
+                 &LogicalVolDesc,
+                 &PrivFileData->Root.FileEntry,
+                 &PrivFileData->Root.FileIdentifierDesc
+                  );
+  if (EFI_ERROR (Status)) {
+    goto FreeExit;
+  }
+
+  PrivFileData->Partition.StartingLocation =
+           PartitionDesc.PartitionStartingLocation;
+  PrivFileData->Partition.Length =
+           PartitionDesc.PartitionLength;
+  PrivFileData->Partition.AccessType = PartitionDesc.AccessType;
+
+  CopyMem (
+    (VOID *)&PrivFileData->Volume.Identifier,
+    (VOID *)&LogicalVolDesc.LogicalVolumeIdentifier,
+    LOGICAL_VOLUME_IDENTIFIER_LENGTH
+    );
+
+  PrivFileData->Signature   = PRIVATE_UDF_FILE_DATA_SIGNATURE;
+  PrivFileData->SimpleFs    = This;
+  PrivFileData->BlockIo     = PrivFsData->BlockIo;
+  PrivFileData->DiskIo      = PrivFsData->DiskIo;
+
+  PrivFileData->FileIo.Revision      = EFI_FILE_PROTOCOL_REVISION;
+  PrivFileData->FileIo.Open          = UdfOpen;
+  PrivFileData->FileIo.Close         = UdfClose;
+  PrivFileData->FileIo.Delete        = UdfDelete;
+  PrivFileData->FileIo.Read          = UdfRead;
+  PrivFileData->FileIo.Write         = UdfWrite;
+  PrivFileData->FileIo.GetPosition   = UdfGetPosition;
+  PrivFileData->FileIo.SetPosition   = UdfSetPosition;
+  PrivFileData->FileIo.GetInfo       = UdfGetInfo;
+  PrivFileData->FileIo.SetInfo       = UdfSetInfo;
+  PrivFileData->FileIo.Flush         = UdfFlush;
+
+  PrivFileData->IsRootDirectory   = TRUE;
+  PrivFileData->FilePosition      = 0;
+  PrivFileData->NextEntryOffset   = 0;
+
+  *Root = &PrivFileData->FileIo;
+
+Exit:
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+
+FreeExit:
+  FreePool ((VOID *)PrivFileData);
+
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+/**
+  Opens a new file relative to the source file's location.
+
+  @param  This       The protocol instance pointer.
+  @param  NewHandle  Returns File Handle for FileName.
+  @param  FileName   Null terminated string. "\", ".", and ".." are supported.
+  @param  OpenMode   Open mode for file.
+  @param  Attributes Only used for EFI_FILE_MODE_CREATE.
+
+  @retval EFI_SUCCESS          The device was opened.
+  @retval EFI_NOT_FOUND        The specified file could not be found on the 
device.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_MEDIA_CHANGED    The media has changed.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_ACCESS_DENIED    The service denied access to the file.
+  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of 
resources.
+  @retval EFI_VOLUME_FULL      The volume is full.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfOpen (
+  IN  EFI_FILE_PROTOCOL                  *This,
+  OUT EFI_FILE_PROTOCOL                  **NewHandle,
+  IN  CHAR16                             *FileName,
+  IN  UINT64                             OpenMode,
+  IN  UINT64                             Attributes
+  )
+{
+  return EFI_DEVICE_ERROR;
+}
+
+/**
+  Read data from the file.
+
+  @param  This       Protocol instance pointer.
+  @param  BufferSize On input size of buffer, on output amount of data in 
buffer.
+  @param  Buffer     The buffer in which data is read.
+
+  @retval EFI_SUCCESS          Data was read.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_BUFFER_TO_SMALL  BufferSize is too small. BufferSize contains 
required size.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfRead (
+  IN     EFI_FILE_PROTOCOL               *This,
+  IN OUT UINTN                           *BufferSize,
+  OUT    VOID                            *Buffer
+  )
+{
+  return EFI_DEVICE_ERROR;
+}
+
+/**
+  Close the file handle
+
+  @param  This          Protocol instance pointer.
+
+  @retval EFI_SUCCESS   The file was closed.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfClose (
+  IN EFI_FILE_PROTOCOL                   *This
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  Close and delete the file handle.
+
+  @param  This                     Protocol instance pointer.
+
+  @retval EFI_SUCCESS              The file was closed and deleted.
+  @retval EFI_WARN_DELETE_FAILURE  The handle was closed but the file was not 
deleted.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfDelete (
+  IN EFI_FILE_PROTOCOL  *This
+  )
+{
+  return EFI_WARN_DELETE_FAILURE;
+}
+
+/**
+  Write data to a file.
+
+  @param  This       Protocol instance pointer.
+  @param  BufferSize On input size of buffer, on output amount of data in 
buffer.
+  @param  Buffer     The buffer in which data to write.
+
+  @retval EFI_SUCCESS          Data was written.
+  @retval EFI_UNSUPPORTED      Writes to Open directory are not supported.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_DEVICE_ERROR     An attempt was made to write to a deleted file.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The device is write protected.
+  @retval EFI_ACCESS_DENIED    The file was open for read only.
+  @retval EFI_VOLUME_FULL      The volume is full.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfWrite (
+  IN     EFI_FILE_PROTOCOL  *This,
+  IN OUT UINTN              *BufferSize,
+  IN     VOID               *Buffer
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Get a file's current position
+
+  @param  This            Protocol instance pointer.
+  @param  Position        Byte position from the start of the file.
+
+  @retval EFI_SUCCESS     Position was updated.
+  @retval EFI_UNSUPPORTED Seek request for directories is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfGetPosition (
+  IN  EFI_FILE_PROTOCOL   *This,
+  OUT UINT64              *Position
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Set file's current position
+
+  @param  This            Protocol instance pointer.
+  @param  Position        Byte position from the start of the file.
+
+  @retval EFI_SUCCESS     Position was updated.
+  @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..
+
+**/
+EFI_STATUS
+EFIAPI
+UdfSetPosition (
+  IN EFI_FILE_PROTOCOL             *This,
+  IN UINT64                        Position
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Get information about a file.
+
+  @param  This            Protocol instance pointer.
+  @param  InformationType Type of information to return in Buffer.
+  @param  BufferSize      On input size of buffer, on output amount of data in 
buffer.
+  @param  Buffer          The buffer to return data.
+
+  @retval EFI_SUCCESS          Data was returned.
+  @retval EFI_UNSUPPORTED      InformationType is not supported.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The device is write protected.
+  @retval EFI_ACCESS_DENIED    The file was open for read only.
+  @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in 
BufferSize.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfGetInfo (
+  IN     EFI_FILE_PROTOCOL               *This,
+  IN     EFI_GUID                        *InformationType,
+  IN OUT UINTN                           *BufferSize,
+  OUT    VOID                            *Buffer
+  )
+{
+  return EFI_DEVICE_ERROR;
+}
+
+/**
+  Set information about a file
+
+  @param  File            Protocol instance pointer.
+  @param  InformationType Type of information in Buffer.
+  @param  BufferSize      Size of buffer.
+  @param  Buffer          The data to write.
+
+  @retval EFI_SUCCESS          Data was set.
+  @retval EFI_UNSUPPORTED      InformationType is not supported.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The device is write protected.
+  @retval EFI_ACCESS_DENIED    The file was open for read only.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfSetInfo (
+  IN EFI_FILE_PROTOCOL*This,
+  IN EFI_GUID         *InformationType,
+  IN UINTN            BufferSize,
+  IN VOID             *Buffer
+  )
+{
+  return EFI_WRITE_PROTECTED;
+}
+
+/**
+  Flush data back for the file handle.
+
+  @param  This Protocol instance pointer.
+
+  @retval EFI_SUCCESS          Data was flushed.
+  @retval EFI_UNSUPPORTED      Writes to Open directory are not supported.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The device is write protected.
+  @retval EFI_ACCESS_DENIED    The file was open for read only.
+  @retval EFI_VOLUME_FULL      The volume is full.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfFlush (
+  IN EFI_FILE_PROTOCOL  *This
+  )
+{
+  return EFI_WRITE_PROTECTED;
+}
+
+STATIC
+EFI_STATUS
+FindAnchorVolumeDescriptorPointer (
+  IN EFI_BLOCK_IO_PROTOCOL                   *BlockIo,
+  IN EFI_DISK_IO_PROTOCOL                    *DiskIo,
+  OUT UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER   *AnchorPoint
+  )
+{
+  EFI_STATUS                                 Status;
+
+  Status = DiskIo->ReadDisk (
+                       DiskIo,
+                       BlockIo->Media->MediaId,
+                       FIRST_ANCHOR_POINT_LSN * LOGICAL_SECTOR_SIZE,
+                       sizeof (UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER),
+                       (VOID *)AnchorPoint
+                       );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  //
+  // TODO: In case of failure, look for the other AVDPs at N or N - 256
+  //
+  if (!IS_AVDP (AnchorPoint)) {
+    Status = EFI_VOLUME_CORRUPTED;
+    goto Exit;
+  }
+
+Exit:
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+StartMainVolumeDescriptorSequence (
+  IN EFI_BLOCK_IO_PROTOCOL                   *BlockIo,
+  IN EFI_DISK_IO_PROTOCOL                    *DiskIo,
+  IN UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER    *AnchorPoint,
+  OUT UDF_PARTITION_DESCRIPTOR               *PartitionDesc,
+  OUT UDF_LOGICAL_VOLUME_DESCRIPTOR          *LogicalVolDesc
+  )
+{
+  EFI_STATUS                                 Status;
+  UDF_EXTENT_AD                              *ExtentAd;
+  UINT32                                     StartingLsn;
+  UINT32                                     EndingLsn;
+  UINT8                                      Buffer[LOGICAL_SECTOR_SIZE];
+
+  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;
+
+  if (ExtentAd->ExtentLength / LOGICAL_SECTOR_SIZE < 16) {
+    Status = EFI_VOLUME_CORRUPTED;
+    goto Exit;
+  }
+
+  //
+  // Start Main Volume Descriptor Sequence
+  //
+  // ==> Primary Volume Descriptor
+  // ==> Implementation Use Volume Descriptor
+  // ==> Partition Descriptor
+  // ==> Logical Volume Descriptor
+  // ==> Unallocated Space Descriptor
+  // ==> Terminating Descriptor
+  // ==> if any, Trailing Logical Sectors
+  //
+  StartingLsn = ExtentAd->ExtentLocation;
+  EndingLsn   = StartingLsn + (ExtentAd->ExtentLength / LOGICAL_SECTOR_SIZE);
+
+  while (StartingLsn <= EndingLsn) {
+    Status = DiskIo->ReadDisk (
+                         DiskIo,
+                        BlockIo->Media->MediaId,
+                        StartingLsn * LOGICAL_SECTOR_SIZE,
+                        LOGICAL_SECTOR_SIZE,
+                        (VOID *)&Buffer
+                         );
+    if (EFI_ERROR (Status)) {
+      goto Exit;
+    }
+
+    //
+    // Stop VDS when found Terminating Descriptor
+    //
+    if (IS_TD (Buffer)) {
+      break;
+    }
+
+    if (IS_PD (Buffer)) {
+      CopyMem (
+       (VOID *)PartitionDesc,
+       (VOID *)&Buffer,
+       sizeof (UDF_PARTITION_DESCRIPTOR)
+       );
+    } else if (IS_LVD (Buffer)) {
+      CopyMem (
+       (VOID *)LogicalVolDesc,
+       (VOID *)&Buffer,
+       sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR)
+       );
+    }
+
+    StartingLsn++;
+  }
+
+Exit:
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+FindFileSetDescriptor (
+  IN EFI_BLOCK_IO_PROTOCOL                   *BlockIo,
+  IN EFI_DISK_IO_PROTOCOL                    *DiskIo,
+  IN UDF_PARTITION_DESCRIPTOR                *PartitionDesc,
+  IN UDF_LOGICAL_VOLUME_DESCRIPTOR           *LogicalVolDesc,
+  OUT UDF_FILE_SET_DESCRIPTOR                *FileSetDesc
+  )
+{
+  EFI_STATUS                                 Status;
+  UDF_LONG_ALLOCATION_DESCRIPTOR             *LongAd;
+  UINT64                                     Lsn;
+
+  LongAd = &LogicalVolDesc->LogicalVolumeContentsUse;
+
+  Lsn = (UINT64)(PartitionDesc->PartitionStartingLocation +
+                LongAd->ExtentLocation.LogicalBlockNumber);
+
+  Status = DiskIo->ReadDisk (
+                       DiskIo,
+                       BlockIo->Media->MediaId,
+                       Lsn * LOGICAL_BLOCK_SIZE,
+                       sizeof (UDF_FILE_SET_DESCRIPTOR),
+                       (VOID *)FileSetDesc
+                       );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  if (!IS_FSD (FileSetDesc)) {
+      Status = EFI_VOLUME_CORRUPTED;
+  }
+
+Exit:
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+FindFileEntryRootDirectory (
+  IN EFI_BLOCK_IO_PROTOCOL                   *BlockIo,
+  IN EFI_DISK_IO_PROTOCOL                    *DiskIo,
+  IN UDF_PARTITION_DESCRIPTOR                *PartitionDesc,
+  IN UDF_FILE_SET_DESCRIPTOR                 *FileSetDesc,
+  OUT UDF_FILE_ENTRY                         *FileEntry
+  )
+{
+  EFI_STATUS                                 Status;
+  UDF_LONG_ALLOCATION_DESCRIPTOR             *LongAd;
+  UINT64                                     Lsn;
+
+  LongAd = &FileSetDesc->RootDirectoryIcb;
+
+  Lsn = (UINT64)(PartitionDesc->PartitionStartingLocation +
+                LongAd->ExtentLocation.LogicalBlockNumber);
+
+  Status = DiskIo->ReadDisk (
+                       DiskIo,
+                       BlockIo->Media->MediaId,
+                       Lsn * LOGICAL_BLOCK_SIZE,
+                      sizeof (UDF_FILE_ENTRY),
+                       (VOID *)FileEntry
+                       );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  if (!IS_FE (FileEntry)) {
+      Status = EFI_VOLUME_CORRUPTED;
+      goto Exit;
+  }
+
+  //
+  // Root Directory cannot be file, obivously. Check its file type.
+  //
+  if (!IS_FE_DIRECTORY (FileEntry)) {
+    Status = EFI_VOLUME_CORRUPTED;
+  }
+
+Exit:
+  return Status;
+}
+
+EFI_STATUS
+FindFileIdentifierDescriptorRootDirectory (
+  IN EFI_BLOCK_IO_PROTOCOL                   *BlockIo,
+  IN EFI_DISK_IO_PROTOCOL                    *DiskIo,
+  IN UDF_PARTITION_DESCRIPTOR                *PartitionDesc,
+  IN UDF_FILE_SET_DESCRIPTOR                 *FileSetDesc,
+  OUT UDF_FILE_IDENTIFIER_DESCRIPTOR         *FileIdentifierDesc
+  )
+{
+  UDF_LONG_ALLOCATION_DESCRIPTOR            *LongAd;
+  EFI_STATUS                                 Status;
+  UINT64                                     Lsn;
+
+  LongAd = &FileSetDesc->RootDirectoryIcb;
+
+  //
+  // TODO: Handle strategy type of 4096 as well.
+  //
+  // For ICB strategy type of 4, the File Identifier Descriptor of the Root
+  // Directory immediately follows the File Entry (Root Directory).
+  //
+  Lsn = (UINT64)(PartitionDesc->PartitionStartingLocation +
+                LongAd->ExtentLocation.LogicalBlockNumber + 1);
+
+  Status = DiskIo->ReadDisk (
+                       DiskIo,
+                       BlockIo->Media->MediaId,
+                       Lsn * LOGICAL_BLOCK_SIZE,
+                       LOGICAL_BLOCK_SIZE,
+                       (VOID *)FileIdentifierDesc
+                       );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  if (!IS_FID (FileIdentifierDesc)) {
+    Status = EFI_VOLUME_CORRUPTED;
+  }
+
+Exit:
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+FindRootDirectory (
+  IN EFI_BLOCK_IO_PROTOCOL                   *BlockIo,
+  IN EFI_DISK_IO_PROTOCOL                    *DiskIo,
+  OUT UDF_PARTITION_DESCRIPTOR               *PartitionDesc,
+  OUT UDF_LOGICAL_VOLUME_DESCRIPTOR          *LogicalVolDesc,
+  OUT UDF_FILE_ENTRY                         *FileEntry,
+  OUT UDF_FILE_IDENTIFIER_DESCRIPTOR         *FileIdentifierDesc
+  )
+{
+  EFI_STATUS                                 Status;
+  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER       AnchorPoint;
+  UDF_FILE_SET_DESCRIPTOR                    FileSetDesc;
+
+  Status = FindAnchorVolumeDescriptorPointer (
+                                          BlockIo,
+                                         DiskIo,
+                                         &AnchorPoint
+                                          );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  Status = StartMainVolumeDescriptorSequence (
+                                          BlockIo,
+                                         DiskIo,
+                                         &AnchorPoint,
+                                         PartitionDesc,
+                                         LogicalVolDesc
+                                          );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  Status = FindFileSetDescriptor (
+                              BlockIo,
+                             DiskIo,
+                             PartitionDesc,
+                             LogicalVolDesc,
+                             &FileSetDesc
+                              );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  Status = FindFileEntryRootDirectory (
+                                   BlockIo,
+                                  DiskIo,
+                                  PartitionDesc,
+                                  &FileSetDesc,
+                                  FileEntry
+                                   );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  Status = FindFileIdentifierDescriptorRootDirectory (
+                                                  BlockIo,
+                                                 DiskIo,
+                                                 PartitionDesc,
+                                                 &FileSetDesc,
+                                                 FileIdentifierDesc
+                                                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+Exit:
+  return Status;
+}
+
+EFI_STATUS
+IsSupportedUdfVolume (
+  IN EFI_BLOCK_IO_PROTOCOL                   *BlockIo,
+  IN EFI_DISK_IO_PROTOCOL                    *DiskIo,
+  OUT BOOLEAN                                *Supported
+  )
+{
+  EFI_STATUS                                 Status;
+  UDF_NSR_DESCRIPTOR                         NsrDescriptor;
+
+  *Supported = FALSE;
+
+  //
+  // Start Volume Recognition Sequence
+  //
+  Status = DiskIo->ReadDisk (
+                       DiskIo,
+                       BlockIo->Media->MediaId,
+                       BEA_DESCRIPTOR_LSN * LOGICAL_SECTOR_SIZE,
+                       sizeof (UDF_NSR_DESCRIPTOR),
+                       (VOID *)&NsrDescriptor
+                       );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  if (CompareMem (
+       (VOID *)&NsrDescriptor.StandardIdentifier,
+       (VOID *)&gUdfStandardIdentifiers[BEA_IDENTIFIER],
+       UDF_STANDARD_IDENTIFIER_LENGTH
+       )
+    ) {
+    goto Exit;
+  }
+
+  Status = DiskIo->ReadDisk (
+                       DiskIo,
+                       BlockIo->Media->MediaId,
+                       (BEA_DESCRIPTOR_LSN + 1) * LOGICAL_SECTOR_SIZE,
+                       sizeof (UDF_NSR_DESCRIPTOR),
+                       (VOID *)&NsrDescriptor
+                       );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  if ((CompareMem (
+        (VOID *)&NsrDescriptor.StandardIdentifier,
+        (VOID *)&gUdfStandardIdentifiers[VSD_IDENTIFIER_0],
+        UDF_STANDARD_IDENTIFIER_LENGTH
+        )
+      ) &&
+      (CompareMem (
+       (VOID *)&NsrDescriptor.StandardIdentifier,
+       (VOID *)&gUdfStandardIdentifiers[VSD_IDENTIFIER_1],
+       UDF_STANDARD_IDENTIFIER_LENGTH
+       )
+      )
+    ) {
+    goto Exit;
+  }
+
+  Status = DiskIo->ReadDisk (
+                       DiskIo,
+                       BlockIo->Media->MediaId,
+                       (BEA_DESCRIPTOR_LSN + 2) * LOGICAL_SECTOR_SIZE,
+                       sizeof (UDF_NSR_DESCRIPTOR),
+                       (VOID *)&NsrDescriptor
+                       );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  if (CompareMem (
+       (VOID *)&NsrDescriptor.StandardIdentifier,
+       (VOID *)&gUdfStandardIdentifiers[TEA_IDENTIFIER],
+       UDF_STANDARD_IDENTIFIER_LENGTH
+       )
+    ) {
+    goto Exit;
+  }
+
+  *Supported = TRUE;
+
+Exit:
+  return Status;
+}
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c 
b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
new file mode 100644
index 0000000..99fada0
--- /dev/null
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
@@ -0,0 +1,349 @@
+/** @file
+  UDF filesystem driver.
+
+Copyright (c) 2014 Paulo Alcantara <pca...@zytor.com><BR>
+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 "Udf.h"
+
+//
+// UDF filesystem driver's Global Variables.
+//
+EFI_DRIVER_BINDING_PROTOCOL gUdfDriverBinding = {
+  UdfDriverBindingSupported,
+  UdfDriverBindingStart,
+  UdfDriverBindingStop,
+  0x0000000BUL,
+  NULL,
+  NULL
+};
+
+UDF_DEVICE_PATH gUdfDriverDevicePath = {
+  {
+    { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } },
+    EFI_UDF_DEVICE_PATH_GUID
+  },
+  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, {
+                              sizeof (EFI_DEVICE_PATH_PROTOCOL), 0
+                              }
+  }
+};
+
+/**
+  Test to see if this driver supports ControllerHandle. Any ControllerHandle
+  than contains a BlockIo and DiskIo protocol or a BlockIo2 protocol can be
+  supported.
+
+  @param[in]  This                Protocol instance pointer.
+  @param[in]  ControllerHandle    Handle of device to test.
+  @param[in]  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
+UdfDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   ControllerHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_DISK_IO_PROTOCOL            *DiskIo;
+
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiDiskIoProtocolGuid,
+                  (VOID **)&DiskIo,
+                  This->DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (Status == EFI_ALREADY_STARTED) {
+    Status = EFI_SUCCESS;
+    goto Exit;
+  }
+
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  gBS->CloseProtocol (
+         ControllerHandle,
+         &gEfiDiskIoProtocolGuid,
+         This->DriverBindingHandle,
+         ControllerHandle
+         );
+
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  NULL,
+                  This->DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+                  );
+
+Exit:
+  return Status;
+}
+
+/**
+  Start this driver on ControllerHandle by opening a Block IO or a Block IO2
+  or both, and Disk IO protocol, reading Device Path, and creating a child
+  handle with a Disk IO and device path protocol.
+
+  @param[in]  This                 Protocol instance pointer.
+  @param[in]  ControllerHandle     Handle of device to bind driver to
+  @param[in]  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
+UdfDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   ControllerHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+{
+  EFI_TPL                         OldTpl;
+  EFI_STATUS                      Status;
+  EFI_BLOCK_IO_PROTOCOL           *BlockIo;
+  EFI_DISK_IO_PROTOCOL            *DiskIo;
+  BOOLEAN                         IsUdfVolume;
+  PRIVATE_UDF_SIMPLE_FS_DATA      *PrivFsData;
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **)&BlockIo,
+                  This->DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiDiskIoProtocolGuid,
+                  (VOID **)&DiskIo,
+                  This->DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status) && Status == EFI_ALREADY_STARTED) {
+    goto Exit;
+  }
+
+  //
+  // Check if media contains a valid UDF volume
+  //
+  Status = IsSupportedUdfVolume (
+                       BlockIo,
+                      DiskIo,
+                      &IsUdfVolume
+                       );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  if (!IsUdfVolume) {
+    Status = EFI_UNSUPPORTED;
+    goto Exit;
+  }
+
+  PrivFsData = AllocateZeroPool (sizeof (PRIVATE_UDF_SIMPLE_FS_DATA));
+  if (!PrivFsData) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  //
+  // Create new child handle
+  //
+  PrivFsData->Signature   = PRIVATE_UDF_SIMPLE_FS_DATA_SIGNATURE;
+  PrivFsData->BlockIo     = BlockIo;
+  PrivFsData->DiskIo      = DiskIo;
+
+  PrivFsData->SimpleFs.Revision   = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
+  PrivFsData->SimpleFs.OpenVolume = UdfOpenVolume;
+
+  PrivFsData->DevicePath   =
+                DuplicateDevicePath (
+                            (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDriverDevicePath
+                             );
+  PrivFsData->Handle       = NULL;
+
+  //
+  // Install new child handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                                     &PrivFsData->Handle,
+                                     &gEfiSimpleFileSystemProtocolGuid,
+                                     &PrivFsData->SimpleFs,
+                                     &gEfiDevicePathProtocolGuid,
+                                     PrivFsData->DevicePath,
+                                     NULL
+                                     );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+Exit:
+  gBS->RestoreTPL (OldTpl);
+
+  return Status;
+}
+
+/**
+  Stop this driver on ControllerHandle. Support stopping 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
+UdfDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
+  IN  EFI_HANDLE                    ControllerHandle,
+  IN  UINTN                         NumberOfChildren,
+  IN  EFI_HANDLE                    *ChildHandleBuffer
+  )
+{
+  UINTN Index;
+  PRIVATE_UDF_SIMPLE_FS_DATA        *PrivFsData;
+  EFI_STATUS                        Status;
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *SimpleFs;
+  EFI_DISK_IO_PROTOCOL              *DiskIo;
+  BOOLEAN                           Done;
+
+  Status = EFI_SUCCESS;
+
+  if (!NumberOfChildren) {
+    gBS->CloseProtocol (
+        ControllerHandle,
+        &gEfiDiskIoProtocolGuid,
+        This->DriverBindingHandle,
+        ControllerHandle
+        );
+    goto Exit;
+  }
+
+  Done = TRUE;
+
+  for (Index = 0; Index < NumberOfChildren; Index++) {
+    gBS->OpenProtocol (
+           ChildHandleBuffer[Index],
+           &gEfiSimpleFileSystemProtocolGuid,
+           (VOID **)&SimpleFs,
+           This->DriverBindingHandle,
+           ControllerHandle,
+           EFI_OPEN_PROTOCOL_GET_PROTOCOL
+           );
+
+    PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (This);
+
+    gBS->CloseProtocol (
+        ControllerHandle,
+        &gEfiDiskIoProtocolGuid,
+        This->DriverBindingHandle,
+        ControllerHandle
+        );
+
+    Status = gBS->UninstallMultipleProtocolInterfaces (
+                                        ChildHandleBuffer[Index],
+                                       &gEfiDevicePathProtocolGuid,
+                                       PrivFsData->DevicePath,
+                                       &gEfiSimpleFileSystemProtocolGuid,
+                                       &PrivFsData->SimpleFs,
+                                       NULL,
+                                       NULL
+                                        );
+    if (EFI_ERROR (Status)) {
+      gBS->OpenProtocol (
+             ControllerHandle,
+             &gEfiDiskIoProtocolGuid,
+             (VOID **)&DiskIo,
+             This->DriverBindingHandle,
+             ChildHandleBuffer[Index],
+             EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+             );
+    } else {
+      FreePool ((VOID *)PrivFsData->DevicePath);
+      FreePool ((VOID *)PrivFsData);
+    }
+
+    if (EFI_ERROR (Status)) {
+      Done = FALSE;
+    }
+  }
+
+  if (!Done) {
+    Status = EFI_DEVICE_ERROR;
+  }
+
+Exit:
+  return Status;
+}
+
+/**
+  The user Entry Point for UDF filesystem driver. 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
+InitializeUdf (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS              Status;
+
+  Status = EfiLibInstallDriverBindingComponentName2 (
+             ImageHandle,
+             SystemTable,
+             &gUdfDriverBinding,
+             ImageHandle,
+             &gUdfComponentName,
+             &gUdfComponentName2
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h 
b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
new file mode 100644
index 0000000..7986445
--- /dev/null
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h
@@ -0,0 +1,879 @@
+/** @file
+  UDF filesystem driver.
+
+Copyright (c) 2014 Paulo Alcantara <pca...@zytor.com><BR>
+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 _UDF_H_
+#define _UDF_H_
+
+#include <Uefi.h>
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/ComponentName.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/DriverBinding.h>
+#include <Protocol/DiskIo.h>
+#include <Protocol/SimpleFileSystem.h>
+
+#include <Guid/FileInfo.h>
+#include <Guid/FileSystemInfo.h>
+#include <Guid/FileSystemVolumeLabelInfo.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>
+
+//
+// As specified in ECMA-167 specification, the logical sector size and logical
+// block size shall be 2048 bytes.
+//
+#define LOGICAL_SECTOR_SIZE                   ((UINT64)0x800ULL)
+#define LOGICAL_BLOCK_SIZE                    ((UINT64)0x800ULL)
+
+#define FIRST_ANCHOR_POINT_LSN                ((UINT64)0x0000000000000100ULL)
+#define BEA_DESCRIPTOR_LSN                    ((UINT64)0x0000000000000013ULL)
+
+#define LOGICAL_VOLUME_IDENTIFIER_LENGTH      128
+
+#define IS_PVD(_Pointer) \
+  (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 1)
+#define IS_AVDP(_Pointer) \
+  (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 2)
+#define IS_PD(_Pointer) \
+  (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 5)
+#define IS_LVD(_Pointer) \
+  (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 6)
+#define IS_TD(_Pointer) \
+  (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 8)
+#define IS_FSD(_Pointer) \
+  (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 256)
+#define IS_FE(_Pointer) \
+  (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 261)
+#define IS_FID(_Pointer) \
+  (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier == 257)
+
+#define IS_FE_DIRECTORY(_Pointer) \
+  (((UDF_FILE_ENTRY *)(_Pointer))->IcbTag.FileType == 4)
+#define IS_FE_STANDARD_FILE(_Pointer) \
+  (((UDF_FILE_ENTRY *)(_Pointer))->IcbTag.FileType == 5)
+
+#define HIDDEN_FILE                           (1 << 0)
+#define DIRECTORY_FILE                        (1 << 1)
+#define DELETED_FILE                          (1 << 2)
+#define PARENT_FILE                           (1 << 3)
+
+#define IS_FID_HIDDEN_FILE(_Pointer) \
+  (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics & \
+   HIDDEN_FILE)
+#define IS_FID_DIRECTORY_FILE(_Pointer) \
+  (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics & \
+   DIRECTORY_FILE)
+#define IS_FID_DELETED_FILE(_Pointer) \
+  (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics & \
+   DELETED_FILE)
+#define IS_FID_PARENT_FILE(_Pointer) \
+  (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics & \
+   PARENT_FILE)
+#define IS_FID_NORMAL_FILE(_Pointer) \
+  ((!IS_FID_DIRECTORY_FILE (_Pointer)) && (!IS_FID_PARENT_FILE (_Pointer)))
+
+#pragma pack(1)
+
+#define UDF_STANDARD_IDENTIFIER_LENGTH   5
+
+typedef struct {
+  UINT8                      
StandardIdentifier[UDF_STANDARD_IDENTIFIER_LENGTH];
+} UDF_STANDARD_IDENTIFIER;
+
+#pragma pack()
+
+enum {
+  BEA_IDENTIFIER   = 0,
+  VSD_IDENTIFIER_0,
+  VSD_IDENTIFIER_1,
+  TEA_IDENTIFIER,
+  STANDARD_IDENTIFIERS_NO,
+};
+
+#pragma pack(1)
+
+//
+// UDF's Volume Structures
+//
+typedef struct {
+  UINT16                TagIdentifier;
+  UINT16                DescriptorVersion;
+  UINT8                 TagChecksum;
+  UINT8                 Reserved;
+  UINT16                TagSerialNumber; // Ignored. Intended for disaster 
recovery.
+  UINT16                DescriptorCRC;
+  UINT16                DescriptorCRCLength;
+  UINT32                TagLocation;
+} UDF_DESCRIPTOR_TAG;
+
+//
+// ECMA 167 1/7.2.1
+//
+typedef struct {
+  UINT8            CharacterSetType;
+  UINT8            CharacterSetInfo[63];
+} UDF_CHAR_SPEC;
+
+//
+// ECMA 167 1/7.4
+//
+typedef struct {
+  UINT8            Flags;
+  UINT8            Identifier[23];
+  UINT8            IdentifierSuffix[8];
+} UDF_ENTITY_ID;
+
+//
+// ECMA 167 1/7.3
+//
+typedef struct {
+  UINT16           TypeAndTimezone;
+  INT16            Year;
+  UINT8            Month;
+  UINT8            Day;
+  UINT8            Hour;
+  UINT8            Minute;
+  UINT8            Second;
+  UINT8            Centiseconds;
+  UINT8            HundredsOfMicroseconds;
+  UINT8            Microseconds;
+} UDF_TIMESTAMP;
+
+//
+// ECMA 167 3/7.1
+//
+typedef struct {
+  UINT32           ExtentLength;
+  UINT32           ExtentLocation;
+} UDF_EXTENT_AD;
+
+//
+// ECMA 167 4/7.1
+//
+typedef struct {
+  UINT32         LogicalBlockNumber;
+  UINT16         PartitionReferenceNumber;
+} UDF_LB_ADDR;
+
+//
+// ECMA 167 4/14.14.2
+//
+typedef struct {
+  UINT32                            ExtentLength;
+  UDF_LB_ADDR                       ExtentLocation;
+  UINT8                             ImplementationUse[6];
+} UDF_LONG_ALLOCATION_DESCRIPTOR;
+
+//
+// ECMA 167 3/9.1
+//
+typedef struct {
+  UINT8                 StructureType;
+  UINT8                 StandardIdentifier[5];
+  UINT8                 StructureVersion;
+  UINT8                 Reserved;
+  UINT8                 StructureData[2040];
+} UDF_NSR_DESCRIPTOR;
+
+typedef struct {
+  UDF_DESCRIPTOR_TAG                      DescriptorTag;
+  UDF_EXTENT_AD                           MainVolumeDescriptorSequenceExtent;
+  UDF_EXTENT_AD                           
ReserveVolumeDescriptorSequenceExtent;
+  UINT8                                   Reserved[480];
+} UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER;
+
+//
+// ECMA 167 3/10.5
+//
+typedef struct {
+  UDF_DESCRIPTOR_TAG          DescriptorTag;
+  UINT32                      VolumeDescriptorSequenceNumber;
+  UINT16                      PartitionFlags;
+  UINT16                      PartitionNumber;
+  UDF_ENTITY_ID               PartitionContents;
+  UINT8                       PartitionContentsUse[128];
+  UINT32                      AccessType;
+  UINT32                      PartitionStartingLocation;
+  UINT32                      PartitionLength;
+  UDF_ENTITY_ID               ImplementationIdentifier;
+  UINT8                       ImplementationUse[128];
+  UINT8                       Reserved[156];
+} UDF_PARTITION_DESCRIPTOR;
+
+//
+// ECMA 167 3/10.6
+//
+typedef struct {
+  UDF_DESCRIPTOR_TAG               DescriptorTag;
+  UINT32                           VolumeDescriptorSequenceNumber;
+  UDF_CHAR_SPEC                    DescriptorCharacterSet;
+  UINT8                            
LogicalVolumeIdentifier[LOGICAL_VOLUME_IDENTIFIER_LENGTH];
+  UINT32                           LogicalBlockSize;
+  UDF_ENTITY_ID                    DomainIdentifier;
+  UDF_LONG_ALLOCATION_DESCRIPTOR   LogicalVolumeContentsUse;
+  UINT32                           MapTableLength;
+  UINT32                           NumberOfPartitionMaps;
+  UDF_ENTITY_ID                    ImplementationIdentifier;
+  UINT8                            ImplementationUse[128];
+  UDF_EXTENT_AD                    IntegritySequenceExtent;
+  UINT8                            PartitionMaps[6];
+} UDF_LOGICAL_VOLUME_DESCRIPTOR;
+
+//
+// ECMA 167 4/14.1
+//
+typedef struct {
+  UDF_DESCRIPTOR_TAG               DescriptorTag;
+  UDF_TIMESTAMP                    RecordingDateAndTime;
+  UINT16                           InterchangeLevel;
+  UINT16                           MaximumInterchangeLevel;
+  UINT32                           CharacterSetList;
+  UINT32                           MaximumCharacterSetList;
+  UINT32                           FileSetNumber;
+  UINT32                           FileSetDescriptorNumber;
+  UDF_CHAR_SPEC                    LogicalVolumeIdentifierCharacterSet;
+  UINT8                            LogicalVolumeIdentifier[128];
+  UDF_CHAR_SPEC                    FileSetCharacterSet;
+  UINT8                            FileSetIdentifier[32];
+  UINT8                            CopyrightFileIdentifier[32];
+  UINT8                            AbstractFileIdentifier[32];
+  UDF_LONG_ALLOCATION_DESCRIPTOR   RootDirectoryIcb;
+  UDF_ENTITY_ID                    DomainIdentifier;
+  UDF_LONG_ALLOCATION_DESCRIPTOR   NextExtent;
+  UDF_LONG_ALLOCATION_DESCRIPTOR   SystemStreamDirectoryIcb;
+  UINT8                            Reserved[32];
+} UDF_FILE_SET_DESCRIPTOR;
+
+//
+// ECMA 167 4/14.14.1
+//
+typedef struct {
+  UINT32                             ExtentLength;
+  UINT32                             ExtentPosition;
+} UDF_SHORT_ALLOCATION_DESCRIPTOR;
+
+//
+// ECMA 167 4/14.3
+//
+typedef struct {
+  UDF_DESCRIPTOR_TAG                DescriptorTag;
+  UINT16                            FileVersionNumber;
+  UINT8                             FileCharacteristics;
+  UINT8                             LengthOfFileIdentifier;
+  UDF_LONG_ALLOCATION_DESCRIPTOR    Icb;
+  UINT16                            LengthOfImplementationUse;
+  UINT8                             Data[2010];
+} UDF_FILE_IDENTIFIER_DESCRIPTOR;
+
+//
+// ECMA 167 4/14.6
+//
+typedef struct {
+  UINT32         PriorRecordNumberOfDirectEntries;
+  UINT16         StrategyType;
+  UINT16         StrategyParameter;
+  UINT16         MaximumNumberOfEntries;
+  UINT8          Reserved;
+  UINT8          FileType;
+  UDF_LB_ADDR    ParentIcbLocation;
+  UINT16         Flags;
+} UDF_ICB_TAG;
+
+//
+// ECMA 167 4/14.9
+//
+// NOTE: The total length of a FE shall not exceed the size of one logical 
block
+// (2048 bytes).
+//
+typedef struct {
+  UDF_DESCRIPTOR_TAG               DescriptorTag;
+  UDF_ICB_TAG                      IcbTag;
+  UINT32                           Uid;
+  UINT32                           Gid;
+  UINT32                           Permissions;
+  UINT16                           FileLinkCount;
+  UINT8                            RecordFormat;
+  UINT8                            RecordDisplayAttributes;
+  UINT32                           RecordLength;
+  UINT64                           InformationLength;
+  UINT64                           LogicalBlocksRecorded;
+  UDF_TIMESTAMP                    AccessTime;
+  UDF_TIMESTAMP                    ModificationTime;
+  UDF_TIMESTAMP                    AttributeTime;
+  UINT32                           CheckPoint;
+  UDF_LONG_ALLOCATION_DESCRIPTOR   ExtendedAttributeIcb;
+  UDF_ENTITY_ID                    ImplementationIdentifier;
+  UINT64                           UniqueId;
+  UINT32                           LengthOfExtendedAttributes;
+  UINT32                           LengthOfAllocationDescriptors;
+  UINT8                            Data[1872]; // L_EAs and L_ADs
+} UDF_FILE_ENTRY;
+
+#pragma pack()
+
+//
+// UDF filesystem driver's private data
+//
+#define PRIVATE_UDF_FILE_DATA_SIGNATURE SIGNATURE_32 ('U', 'd', 'f', 'f')
+
+#define PRIVATE_UDF_FILE_DATA_FROM_THIS(a) \
+  CR ( \
+      a, \
+      PRIVATE_UDF_FILE_DATA, \
+      FileIo, \
+      PRIVATE_UDF_FILE_DATA_SIGNATURE \
+      )
+
+typedef struct {
+  UINTN                                  Signature;
+
+  struct {
+    UINT32                                 StartingLocation;
+    UINT32                                 Length;
+    UINT32                                 AccessType;
+  } Partition;
+  struct {
+    UINT8                                  
Identifier[LOGICAL_VOLUME_IDENTIFIER_LENGTH];
+  } Volume;
+  struct {
+    UDF_FILE_ENTRY                         FileEntry;
+    UDF_FILE_IDENTIFIER_DESCRIPTOR         FileIdentifierDesc;
+  } Root;
+  struct {
+    UDF_FILE_IDENTIFIER_DESCRIPTOR         ParentFileIdentifierDesc;
+    UDF_FILE_ENTRY                         FileEntry;
+    UDF_FILE_IDENTIFIER_DESCRIPTOR         FileIdentifierDesc;
+  } File;
+
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL        *SimpleFs;
+  EFI_BLOCK_IO_PROTOCOL                  *BlockIo;
+  EFI_DISK_IO_PROTOCOL                   *DiskIo;
+  EFI_FILE_PROTOCOL                      FileIo;
+  UINT64                                 FilePosition;
+  UINT64                                 NextEntryOffset;
+  CHAR16                                 *AbsoluteFileName;
+  CHAR16                                 *FileName;
+  BOOLEAN                                IsRootDirectory;
+} PRIVATE_UDF_FILE_DATA;
+
+#define PRIVATE_UDF_SIMPLE_FS_DATA_SIGNATURE SIGNATURE_32 ('U', 'd', 'f', 's')
+
+#define PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS(a) \
+  CR ( \
+      a, \
+      PRIVATE_UDF_SIMPLE_FS_DATA, \
+      SimpleFs, \
+      PRIVATE_UDF_SIMPLE_FS_DATA_SIGNATURE \
+      )
+
+typedef struct {
+  UINTN                             Signature;
+  EFI_BLOCK_IO_PROTOCOL             *BlockIo;
+  EFI_DISK_IO_PROTOCOL              *DiskIo;
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   SimpleFs;
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
+  EFI_HANDLE                        Handle;
+} PRIVATE_UDF_SIMPLE_FS_DATA;
+
+typedef struct {
+  VENDOR_DEVICE_PATH         DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL   End;
+} UDF_DEVICE_PATH;
+
+// C5BD4D42-1A76-4996-8956-73CDA326CD0A
+#define EFI_UDF_DEVICE_PATH_GUID \
+  { 0xC5BD4D42, 0x1A76, 0x4996, \
+    { 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A } \
+  }
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL   gUdfDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL   gUdfComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL  gUdfComponentName2;
+
+//
+// Function Prototypes
+//
+
+/**
+  Open the root directory on a volume.
+
+  @param  This Protocol instance pointer.
+  @param  Root Returns an Open file handle for the root directory
+
+  @retval EFI_SUCCESS          The device was opened.
+  @retval EFI_UNSUPPORTED      This volume does not support the file system.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_ACCESS_DENIED    The service denied access to the file.
+  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of 
resources.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfOpenVolume (
+  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL     *This,
+  OUT EFI_FILE_PROTOCOL                  **Root
+  );
+
+/**
+  Opens a new file relative to the source file's location.
+
+  @param  This       The protocol instance pointer.
+  @param  NewHandle  Returns File Handle for FileName.
+  @param  FileName   Null terminated string. "\", ".", and ".." are supported.
+  @param  OpenMode   Open mode for file.
+  @param  Attributes Only used for EFI_FILE_MODE_CREATE.
+
+  @retval EFI_SUCCESS          The device was opened.
+  @retval EFI_NOT_FOUND        The specified file could not be found on the 
device.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_MEDIA_CHANGED    The media has changed.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_ACCESS_DENIED    The service denied access to the file.
+  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of 
resources.
+  @retval EFI_VOLUME_FULL      The volume is full.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfOpen (
+  IN  EFI_FILE_PROTOCOL                  *This,
+  OUT EFI_FILE_PROTOCOL                  **NewHandle,
+  IN  CHAR16                             *FileName,
+  IN  UINT64                             OpenMode,
+  IN  UINT64                             Attributes
+  );
+
+/**
+  Read data from the file.
+
+  @param  This       Protocol instance pointer.
+  @param  BufferSize On input size of buffer, on output amount of data in 
buffer.
+  @param  Buffer     The buffer in which data is read.
+
+  @retval EFI_SUCCESS          Data was read.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_BUFFER_TO_SMALL  BufferSize is too small. BufferSize contains 
required size.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfRead (
+  IN     EFI_FILE_PROTOCOL  *This,
+  IN OUT UINTN              *BufferSize,
+  OUT    VOID               *Buffer
+  );
+
+/**
+  Close the file handle
+
+  @param  This          Protocol instance pointer.
+
+  @retval EFI_SUCCESS   The file was closed.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfClose (
+  IN EFI_FILE_PROTOCOL    *This
+  );
+
+/**
+  Close and delete the file handle.
+
+  @param  This                     Protocol instance pointer.
+
+  @retval EFI_SUCCESS              The file was closed and deleted.
+  @retval EFI_WARN_DELETE_FAILURE  The handle was closed but the file was not 
deleted.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfDelete (
+  IN EFI_FILE_PROTOCOL  *This
+  );
+
+/**
+  Write data to a file.
+
+  @param  This       Protocol instance pointer.
+  @param  BufferSize On input size of buffer, on output amount of data in 
buffer.
+  @param  Buffer     The buffer in which data to write.
+
+  @retval EFI_SUCCESS          Data was written.
+  @retval EFI_UNSUPPORTED      Writes to Open directory are not supported.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_DEVICE_ERROR     An attempt was made to write to a deleted file.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The device is write protected.
+  @retval EFI_ACCESS_DENIED    The file was open for read only.
+  @retval EFI_VOLUME_FULL      The volume is full.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfWrite (
+  IN     EFI_FILE_PROTOCOL  *This,
+  IN OUT UINTN              *BufferSize,
+  IN     VOID               *Buffer
+  );
+
+/**
+  Get a file's current position
+
+  @param  This            Protocol instance pointer.
+  @param  Position        Byte position from the start of the file.
+
+  @retval EFI_SUCCESS     Position was updated.
+  @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfGetPosition (
+  IN  EFI_FILE_PROTOCOL   *This,
+  OUT UINT64              *Position
+  );
+
+/**
+  Set file's current position
+
+  @param  This            Protocol instance pointer.
+  @param  Position        Byte position from the start of the file.
+
+  @retval EFI_SUCCESS     Position was updated.
+  @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..
+
+**/
+EFI_STATUS
+EFIAPI
+UdfSetPosition (
+  IN EFI_FILE_PROTOCOL             *This,
+  IN UINT64                        Position
+  );
+
+/**
+  Get information about a file.
+
+  @param  This            Protocol instance pointer.
+  @param  InformationType Type of information to return in Buffer.
+  @param  BufferSize      On input size of buffer, on output amount of data in 
buffer.
+  @param  Buffer          The buffer to return data.
+
+  @retval EFI_SUCCESS          Data was returned.
+  @retval EFI_UNSUPPORTED      InformationType is not supported.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The device is write protected.
+  @retval EFI_ACCESS_DENIED    The file was open for read only.
+  @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in 
BufferSize.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfGetInfo (
+  IN     EFI_FILE_PROTOCOL  *This,
+  IN     EFI_GUID           *InformationType,
+  IN OUT UINTN              *BufferSize,
+  OUT    VOID               *Buffer
+  );
+
+/**
+  Set information about a file
+
+  @param  File            Protocol instance pointer.
+  @param  InformationType Type of information in Buffer.
+  @param  BufferSize      Size of buffer.
+  @param  Buffer          The data to write.
+
+  @retval EFI_SUCCESS          Data was set.
+  @retval EFI_UNSUPPORTED      InformationType is not supported.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The device is write protected.
+  @retval EFI_ACCESS_DENIED    The file was open for read only.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfSetInfo (
+  IN EFI_FILE_PROTOCOL*This,
+  IN EFI_GUID         *InformationType,
+  IN UINTN            BufferSize,
+  IN VOID             *Buffer
+  );
+
+/**
+  Flush data back for the file handle.
+
+  @param  This Protocol instance pointer.
+
+  @retval EFI_SUCCESS          Data was flushed.
+  @retval EFI_UNSUPPORTED      Writes to Open directory are not supported.
+  @retval EFI_NO_MEDIA         The device has no media.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The device is write protected.
+  @retval EFI_ACCESS_DENIED    The file was open for read only.
+  @retval EFI_VOLUME_FULL      The volume is full.
+
+**/
+EFI_STATUS
+EFIAPI
+UdfFlush (
+  IN EFI_FILE_PROTOCOL  *This
+  );
+
+EFI_STATUS
+EFIAPI
+FindRootDirectory (
+  IN EFI_BLOCK_IO_PROTOCOL                   *BlockIo,
+  IN EFI_DISK_IO_PROTOCOL                    *DiskIo,
+  OUT UDF_PARTITION_DESCRIPTOR               *PartitionDesc,
+  OUT UDF_LOGICAL_VOLUME_DESCRIPTOR          *LogicalVolDesc,
+  OUT UDF_FILE_ENTRY                         *FileEntry,
+  OUT UDF_FILE_IDENTIFIER_DESCRIPTOR         *FileIdentifierDesc
+  );
+
+EFI_STATUS
+IsSupportedUdfVolume (
+  IN EFI_BLOCK_IO_PROTOCOL                   *BlockIo,
+  IN EFI_DISK_IO_PROTOCOL                    *DiskIo,
+  OUT BOOLEAN                                *Supported
+  );
+
+EFI_STATUS
+FindFileIdentifierDescriptorRootDir (
+  IN EFI_BLOCK_IO_PROTOCOL                   *BlockIo,
+  IN EFI_DISK_IO_PROTOCOL                    *DiskIo,
+  IN UDF_PARTITION_DESCRIPTOR                *PartitionDesc,
+  IN UDF_FILE_SET_DESCRIPTOR                 *FileSetDesc,
+  OUT UDF_FILE_IDENTIFIER_DESCRIPTOR         *FileIdentifierDesc
+  );
+
+/**
+  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
+UdfDriverBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   ControllerHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  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
+UdfDriverBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   ControllerHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  Stop this driver on ControllerHandle. Support stopping 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
+UdfDriverBindingStop (
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
+  IN  EFI_HANDLE                    ControllerHandle,
+  IN  UINTN                         NumberOfChildren,
+  IN  EFI_HANDLE                    *ChildHandleBuffer
+  );
+
+//
+// EFI Component Name Functions
+//
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL 
or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          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 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       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
+UdfComponentNameGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  );
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified 
by
+  Language, then a pointer to the controller name is returned in 
ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not 
currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL 
or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  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[in]       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[in]          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 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   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
+UdfComponentNameGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        
OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  );
+
+#endif // _UDF_H_
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf 
b/MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
new file mode 100644
index 0000000..538a618
--- /dev/null
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
@@ -0,0 +1,63 @@
+## @file
+#  UDF filesystem driver.
+#
+#  Copyright (c) 2014 Paulo Alcantara <pca...@zytor.com><BR>
+#  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]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = UdfDxe
+  FILE_GUID                      = 905f13b0-8f91-4b0a-bd76-e1e78f9422e4
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeUdf
+
+#
+# The following information is for reference only and not required by the 
build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+#  DRIVER_BINDING                = gUdfDriverBinding
+#  COMPONENT_NAME                = gUdfComponentName
+#  COMPONENT_NAME2               = gUdfComponentName2
+#
+
+[Sources]
+  ComponentName.c
+  FileSystemOperations.c
+  Udf.c
+  Udf.h
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+
+[LibraryClasses]
+  DevicePathLib
+  UefiBootServicesTableLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  UefiLib
+  BaseLib
+  UefiDriverEntryPoint
+  DebugLib
+
+
+[Guids]
+  gEfiFileInfoGuid                              ## SOMETIMES_CONSUMES ## 
Protocol
+  gEfiFileSystemInfoGuid                        ## SOMETIMES_CONSUMES ## 
Protocol
+
+[Protocols]
+  gEfiSimpleFileSystemProtocolGuid              ## BY_START
+  gEfiDevicePathProtocolGuid                    ## BY_START
+  gEfiBlockIoProtocolGuid                       ## TO_START
+  gEfiDiskIoProtocolGuid                        ## TO_START
-- 
1.9.3


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to