]> git.proxmox.com Git - mirror_edk2.git/blobdiff - FatPkg/FatPei/FatLiteApi.c
FatPkg: Clean up source files
[mirror_edk2.git] / FatPkg / FatPei / FatLiteApi.c
index bf8158d94f01ea3f165664bdf8b42cd18e41b8e2..b71eaaab2a60051632a6429c8d6a15f8ba07a71a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   FAT recovery PEIM entry point, Ppi Functions and FAT Api functions.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
 \r
 This program and the accompanying materials are licensed and made available\r
 under the terms and conditions of the BSD License which accompanies this\r
@@ -21,12 +21,12 @@ PEI_FAT_PRIVATE_DATA  *mPrivateData = NULL;
   BlockIo installation nofication function. Find out all the current BlockIO\r
   PPIs in the system and add them into private data. Assume there is\r
 \r
-  @param  PeiServices             General purpose services available to every \r
-                                  PEIM. \r
-  @param  NotifyDescriptor        The typedef structure of the notification \r
-                                  descriptor. Not used in this function. \r
-  @param  Ppi                     The typedef structure of the PPI descriptor. \r
-                                  Not used in this function. \r
+  @param  PeiServices             General purpose services available to every\r
+                                  PEIM.\r
+  @param  NotifyDescriptor        The typedef structure of the notification\r
+                                  descriptor. Not used in this function.\r
+  @param  Ppi                     The typedef structure of the PPI descriptor.\r
+                                  Not used in this function.\r
 \r
   @retval EFI_SUCCESS             The function completed successfully.\r
 \r
@@ -43,29 +43,34 @@ BlockIoNotifyEntry (
 /**\r
   Discover all the block I/O devices to find the FAT volume.\r
 \r
-  @param  PrivateData             Global memory map for accessing global \r
-                                  variables. \r
+  @param  PrivateData             Global memory map for accessing global\r
+                                  variables.\r
+  @param  BlockIo2                Boolean to show whether using BlockIo2 or BlockIo\r
 \r
   @retval EFI_SUCCESS             The function completed successfully.\r
 \r
 **/\r
 EFI_STATUS\r
 UpdateBlocksAndVolumes (\r
-  IN OUT PEI_FAT_PRIVATE_DATA            *PrivateData\r
+  IN OUT PEI_FAT_PRIVATE_DATA            *PrivateData,\r
+  IN     BOOLEAN                         BlockIo2\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  EFI_PEI_PPI_DESCRIPTOR        *TempPpiDescriptor;\r
-  UINTN                         BlockIoPpiInstance;\r
-  EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi;\r
-  UINTN                         NumberBlockDevices;\r
-  UINTN                         Index;\r
-  EFI_PEI_BLOCK_IO_MEDIA        Media;\r
-  PEI_FAT_VOLUME                Volume;\r
-  EFI_PEI_SERVICES              **PeiServices;\r
+  EFI_STATUS                     Status;\r
+  EFI_PEI_PPI_DESCRIPTOR         *TempPpiDescriptor;\r
+  UINTN                          BlockIoPpiInstance;\r
+  EFI_PEI_RECOVERY_BLOCK_IO_PPI  *BlockIoPpi;\r
+  EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2Ppi;\r
+  UINTN                          NumberBlockDevices;\r
+  UINTN                          Index;\r
+  EFI_PEI_BLOCK_IO_MEDIA         Media;\r
+  EFI_PEI_BLOCK_IO2_MEDIA        Media2;\r
+  PEI_FAT_VOLUME                 Volume;\r
+  EFI_PEI_SERVICES               **PeiServices;\r
 \r
   PeiServices = (EFI_PEI_SERVICES **) GetPeiServicesTablePointer ();\r
-\r
+  BlockIo2Ppi = NULL;\r
+  BlockIoPpi  = NULL;\r
   //\r
   // Clean up caches\r
   //\r
@@ -80,12 +85,21 @@ UpdateBlocksAndVolumes (
   // Assuming all device Block Io Peims are dispatched already\r
   //\r
   for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_FAT_MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) {\r
-    Status = PeiServicesLocatePpi (\r
-              &gEfiPeiVirtualBlockIoPpiGuid,\r
-              BlockIoPpiInstance,\r
-              &TempPpiDescriptor,\r
-              (VOID **) &BlockIoPpi\r
-              );\r
+    if (BlockIo2) {\r
+      Status = PeiServicesLocatePpi (\r
+                &gEfiPeiVirtualBlockIo2PpiGuid,\r
+                BlockIoPpiInstance,\r
+                &TempPpiDescriptor,\r
+                (VOID **) &BlockIo2Ppi\r
+                );\r
+    } else {\r
+      Status = PeiServicesLocatePpi (\r
+                &gEfiPeiVirtualBlockIoPpiGuid,\r
+                BlockIoPpiInstance,\r
+                &TempPpiDescriptor,\r
+                (VOID **) &BlockIoPpi\r
+                );\r
+    }\r
     if (EFI_ERROR (Status)) {\r
       //\r
       // Done with all Block Io Ppis\r
@@ -93,40 +107,63 @@ UpdateBlocksAndVolumes (
       break;\r
     }\r
 \r
-    Status = BlockIoPpi->GetNumberOfBlockDevices (\r
-                          PeiServices,\r
-                          BlockIoPpi,\r
-                          &NumberBlockDevices\r
-                          );\r
+    if (BlockIo2) {\r
+      Status = BlockIo2Ppi->GetNumberOfBlockDevices (\r
+                              PeiServices,\r
+                              BlockIo2Ppi,\r
+                              &NumberBlockDevices\r
+                              );\r
+    } else {\r
+      Status = BlockIoPpi->GetNumberOfBlockDevices (\r
+                             PeiServices,\r
+                             BlockIoPpi,\r
+                             &NumberBlockDevices\r
+                             );\r
+    }\r
     if (EFI_ERROR (Status)) {\r
       continue;\r
     }\r
 \r
     for (Index = 1; Index <= NumberBlockDevices && PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE; Index++) {\r
 \r
-      Status = BlockIoPpi->GetBlockDeviceMediaInfo (\r
-                            PeiServices,\r
-                            BlockIoPpi,\r
-                            Index,\r
-                            &Media\r
-                            );\r
-      if (EFI_ERROR (Status) || !Media.MediaPresent) {\r
-        continue;\r
+      if (BlockIo2) {\r
+        Status = BlockIo2Ppi->GetBlockDeviceMediaInfo (\r
+                                PeiServices,\r
+                                BlockIo2Ppi,\r
+                                Index,\r
+                                &Media2\r
+                                );\r
+        if (EFI_ERROR (Status) || !Media2.MediaPresent) {\r
+          continue;\r
+        }\r
+        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo2        = BlockIo2Ppi;\r
+        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].InterfaceType   = Media2.InterfaceType;\r
+        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock       = Media2.LastBlock;\r
+        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize       = Media2.BlockSize;\r
+      } else {\r
+        Status = BlockIoPpi->GetBlockDeviceMediaInfo (\r
+                               PeiServices,\r
+                               BlockIoPpi,\r
+                               Index,\r
+                               &Media\r
+                               );\r
+        if (EFI_ERROR (Status) || !Media.MediaPresent) {\r
+          continue;\r
+        }\r
+        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo    = BlockIoPpi;\r
+        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].DevType    = Media.DeviceType;\r
+        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock  = Media.LastBlock;\r
+        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize  = (UINT32) Media.BlockSize;\r
       }\r
 \r
-      PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = (UINT32) Media.BlockSize;\r
-      PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media.LastBlock;\r
-      PrivateData->BlockDevice[PrivateData->BlockDeviceCount].IoAlign   = 0;\r
+      PrivateData->BlockDevice[PrivateData->BlockDeviceCount].IoAlign = 0;\r
       //\r
       // Not used here\r
       //\r
       PrivateData->BlockDevice[PrivateData->BlockDeviceCount].Logical           = FALSE;\r
       PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PartitionChecked  = FALSE;\r
 \r
-      PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo           = BlockIoPpi;\r
       PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PhysicalDevNo     = (UINT8) Index;\r
-      PrivateData->BlockDevice[PrivateData->BlockDeviceCount].DevType           = Media.DeviceType;\r
-\r
       PrivateData->BlockDeviceCount++;\r
     }\r
   }\r
@@ -166,12 +203,12 @@ UpdateBlocksAndVolumes (
   BlockIo installation notification function. Find out all the current BlockIO\r
   PPIs in the system and add them into private data. Assume there is\r
 \r
-  @param  PeiServices             General purpose services available to every \r
-                                  PEIM. \r
-  @param  NotifyDescriptor        The typedef structure of the notification \r
-                                  descriptor. Not used in this function. \r
-  @param  Ppi                     The typedef structure of the PPI descriptor. \r
-                                  Not used in this function. \r
+  @param  PeiServices             General purpose services available to every\r
+                                  PEIM.\r
+  @param  NotifyDescriptor        The typedef structure of the notification\r
+                                  descriptor. Not used in this function.\r
+  @param  Ppi                     The typedef structure of the PPI descriptor.\r
+                                  Not used in this function.\r
 \r
   @retval EFI_SUCCESS             The function completed successfully.\r
 \r
@@ -184,8 +221,11 @@ BlockIoNotifyEntry (
   IN VOID                       *Ppi\r
   )\r
 {\r
-  UpdateBlocksAndVolumes (mPrivateData);\r
-\r
+  if (CompareGuid (NotifyDescriptor->Guid, &gEfiPeiVirtualBlockIo2PpiGuid)) {\r
+    UpdateBlocksAndVolumes (mPrivateData, TRUE);\r
+  } else {\r
+    UpdateBlocksAndVolumes (mPrivateData, FALSE);\r
+  }\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -194,13 +234,13 @@ BlockIoNotifyEntry (
   Installs the Device Recovery Module PPI, Initialize BlockIo Ppi\r
   installation notification\r
 \r
-  @param  FileHandle              Handle of the file being invoked. Type \r
-                                  EFI_PEI_FILE_HANDLE is defined in  \r
-                                  FfsFindNextFile(). \r
-  @param  PeiServices             Describes the list of possible PEI Services. \r
+  @param  FileHandle              Handle of the file being invoked. Type\r
+                                  EFI_PEI_FILE_HANDLE is defined in\r
+                                  FfsFindNextFile().\r
+  @param  PeiServices             Describes the list of possible PEI Services.\r
 \r
-  @retval EFI_SUCCESS             The entry point was executed successfully. \r
-  @retval EFI_OUT_OF_RESOURCES    There is no enough memory to complete the \r
+  @retval EFI_SUCCESS             The entry point was executed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES    There is no enough memory to complete the\r
                                   operations.\r
 \r
 **/\r
@@ -247,7 +287,7 @@ FatPeimEntry (
 \r
   PrivateData->PpiDescriptor.Flags                          = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
   PrivateData->PpiDescriptor.Guid = &gEfiPeiDeviceRecoveryModulePpiGuid;\r
-  PrivateData->PpiDescriptor.Ppi = &PrivateData->DeviceRecoveryPpi;\r
+  PrivateData->PpiDescriptor.Ppi  = &PrivateData->DeviceRecoveryPpi;\r
 \r
   Status = PeiServicesInstallPpi (&PrivateData->PpiDescriptor);\r
   if (EFI_ERROR (Status)) {\r
@@ -258,7 +298,8 @@ FatPeimEntry (
   //\r
   PrivateData->BlockDeviceCount = 0;\r
 \r
-  UpdateBlocksAndVolumes (PrivateData);\r
+  UpdateBlocksAndVolumes (PrivateData, TRUE);\r
+  UpdateBlocksAndVolumes (PrivateData, FALSE);\r
 \r
   //\r
   // PrivateData is allocated now, set it to the module variable\r
@@ -268,14 +309,20 @@ FatPeimEntry (
   //\r
   // Installs Block Io Ppi notification function\r
   //\r
-  PrivateData->NotifyDescriptor.Flags =\r
+  PrivateData->NotifyDescriptor[0].Flags =\r
+    (\r
+      EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK\r
+    );\r
+  PrivateData->NotifyDescriptor[0].Guid    = &gEfiPeiVirtualBlockIoPpiGuid;\r
+  PrivateData->NotifyDescriptor[0].Notify  = BlockIoNotifyEntry;\r
+  PrivateData->NotifyDescriptor[1].Flags  =\r
     (\r
       EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |\r
       EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST\r
     );\r
-  PrivateData->NotifyDescriptor.Guid    = &gEfiPeiVirtualBlockIoPpiGuid;\r
-  PrivateData->NotifyDescriptor.Notify  = BlockIoNotifyEntry;\r
-  return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor);\r
+  PrivateData->NotifyDescriptor[1].Guid    = &gEfiPeiVirtualBlockIo2PpiGuid;\r
+  PrivateData->NotifyDescriptor[1].Notify  = BlockIoNotifyEntry;\r
+  return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor[0]);\r
 }\r
 \r
 \r
@@ -283,18 +330,18 @@ FatPeimEntry (
   Returns the number of DXE capsules residing on the device.\r
 \r
   This function searches for DXE capsules from the associated device and returns\r
-  the number and maximum size in bytes of the capsules discovered. Entry 1 is \r
-  assumed to be the highest load priority and entry N is assumed to be the lowest \r
+  the number and maximum size in bytes of the capsules discovered. Entry 1 is\r
+  assumed to be the highest load priority and entry N is assumed to be the lowest\r
   priority.\r
 \r
-  @param[in]  PeiServices              General-purpose services that are available \r
+  @param[in]  PeiServices              General-purpose services that are available\r
                                        to every PEIM\r
   @param[in]  This                     Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI\r
                                        instance.\r
-  @param[out] NumberRecoveryCapsules   Pointer to a caller-allocated UINTN. On \r
-                                       output, *NumberRecoveryCapsules contains \r
-                                       the number of recovery capsule images \r
-                                       available for retrieval from this PEIM \r
+  @param[out] NumberRecoveryCapsules   Pointer to a caller-allocated UINTN. On\r
+                                       output, *NumberRecoveryCapsules contains\r
+                                       the number of recovery capsule images\r
+                                       available for retrieval from this PEIM\r
                                        instance.\r
 \r
   @retval EFI_SUCCESS        One or more capsules were discovered.\r
@@ -323,7 +370,7 @@ GetNumberRecoveryCapsules (
   //\r
   RecoveryCapsuleCount = 0;\r
   for (Index = 0; Index < PrivateData->VolumeCount; Index++) {\r
-    Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle);\r
+    Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr(PcdRecoveryFileName), &Handle);\r
     if (EFI_ERROR (Status)) {\r
       continue;\r
     }\r
@@ -347,18 +394,18 @@ GetNumberRecoveryCapsules (
   This function gets the size and type of the capsule specified by CapsuleInstance.\r
 \r
   @param[in]  PeiServices       General-purpose services that are available to every PEIM\r
-  @param[in]  This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI \r
+  @param[in]  This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI\r
                                 instance.\r
-  @param[in]  CapsuleInstance   Specifies for which capsule instance to retrieve \r
-                                the information.  This parameter must be between \r
-                                one and the value returned by GetNumberRecoveryCapsules() \r
+  @param[in]  CapsuleInstance   Specifies for which capsule instance to retrieve\r
+                                the information.  This parameter must be between\r
+                                one and the value returned by GetNumberRecoveryCapsules()\r
                                 in NumberRecoveryCapsules.\r
-  @param[out] Size              A pointer to a caller-allocated UINTN in which \r
-                                the size of the requested recovery module is \r
+  @param[out] Size              A pointer to a caller-allocated UINTN in which\r
+                                the size of the requested recovery module is\r
                                 returned.\r
-  @param[out] CapsuleType       A pointer to a caller-allocated EFI_GUID in which \r
-                                the type of the requested recovery capsule is \r
-                                returned.  The semantic meaning of the value \r
+  @param[out] CapsuleType       A pointer to a caller-allocated EFI_GUID in which\r
+                                the type of the requested recovery capsule is\r
+                                returned.  The semantic meaning of the value\r
                                 returned is defined by the implementation.\r
 \r
   @retval EFI_SUCCESS        One or more capsules were discovered.\r
@@ -405,7 +452,7 @@ GetRecoveryCapsuleInfo (
   //\r
   RecoveryCapsuleCount = 0;\r
   for (Index = 0; Index < PrivateData->VolumeCount; Index++) {\r
-    Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle);\r
+    Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr(PcdRecoveryFileName), &Handle);\r
 \r
     if (EFI_ERROR (Status)) {\r
       continue;\r
@@ -428,22 +475,42 @@ GetRecoveryCapsuleInfo (
       // Fill in the Capsule Type GUID according to the block device type\r
       //\r
       if (BlockDeviceNo < PrivateData->BlockDeviceCount) {\r
-        switch (PrivateData->BlockDevice[BlockDeviceNo].DevType) {\r
-        case LegacyFloppy:\r
-          CopyGuid (CapsuleType, &gRecoveryOnFatFloppyDiskGuid);\r
-          break;\r
-\r
-        case IdeCDROM:\r
-        case IdeLS120:\r
-          CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);\r
-          break;\r
-\r
-        case UsbMassStorage:\r
-          CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);\r
-          break;\r
-\r
-        default:\r
-          break;\r
+        if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo2 != NULL) {\r
+          switch (PrivateData->BlockDevice[BlockDeviceNo].InterfaceType) {\r
+          case MSG_ATAPI_DP:\r
+            CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);\r
+            break;\r
+\r
+          case MSG_USB_DP:\r
+            CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);\r
+            break;\r
+\r
+          case MSG_NVME_NAMESPACE_DP:\r
+            CopyGuid (CapsuleType, &gRecoveryOnFatNvmeDiskGuid);\r
+            break;\r
+\r
+          default:\r
+            break;\r
+          }\r
+        }\r
+        if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo != NULL) {\r
+          switch (PrivateData->BlockDevice[BlockDeviceNo].DevType) {\r
+          case LegacyFloppy:\r
+            CopyGuid (CapsuleType, &gRecoveryOnFatFloppyDiskGuid);\r
+            break;\r
+\r
+          case IdeCDROM:\r
+          case IdeLS120:\r
+            CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);\r
+            break;\r
+\r
+          case UsbMassStorage:\r
+            CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);\r
+            break;\r
+\r
+          default:\r
+            break;\r
+          }\r
         }\r
       }\r
 \r
@@ -463,12 +530,12 @@ GetRecoveryCapsuleInfo (
   This function, by whatever mechanism, retrieves a DXE capsule from some device\r
   and loads it into memory. Note that the published interface is device neutral.\r
 \r
-  @param[in]     PeiServices       General-purpose services that are available \r
+  @param[in]     PeiServices       General-purpose services that are available\r
                                    to every PEIM\r
   @param[in]     This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI\r
                                    instance.\r
   @param[in]     CapsuleInstance   Specifies which capsule instance to retrieve.\r
-  @param[out]    Buffer            Specifies a caller-allocated buffer in which \r
+  @param[out]    Buffer            Specifies a caller-allocated buffer in which\r
                                    the requested recovery capsule will be returned.\r
 \r
   @retval EFI_SUCCESS        The capsule was loaded correctly.\r
@@ -513,7 +580,7 @@ LoadRecoveryCapsule (
   //\r
   RecoveryCapsuleCount = 0;\r
   for (Index = 0; Index < PrivateData->VolumeCount; Index++) {\r
-    Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle);\r
+    Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr(PcdRecoveryFileName), &Handle);\r
     if (EFI_ERROR (Status)) {\r
       continue;\r
     }\r
@@ -541,16 +608,16 @@ LoadRecoveryCapsule (
   This function finds the the recovery file named FileName on a specified FAT volume and returns\r
   its FileHandle pointer.\r
 \r
-  @param  PrivateData             Global memory map for accessing global \r
-                                  variables. \r
-  @param  VolumeIndex             The index of the volume. \r
-  @param  FileName                The recovery file name to find. \r
-  @param  Handle                  The output file handle. \r
+  @param  PrivateData             Global memory map for accessing global\r
+                                  variables.\r
+  @param  VolumeIndex             The index of the volume.\r
+  @param  FileName                The recovery file name to find.\r
+  @param  Handle                  The output file handle.\r
 \r
-  @retval EFI_DEVICE_ERROR        Some error occured when operating the FAT \r
-                                  volume. \r
-  @retval EFI_NOT_FOUND           The recovery file was not found. \r
-  @retval EFI_SUCCESS             The recovery file was successfully found on the \r
+  @retval EFI_DEVICE_ERROR        Some error occured when operating the FAT\r
+                                  volume.\r
+  @retval EFI_NOT_FOUND           The recovery file was not found.\r
+  @retval EFI_SUCCESS             The recovery file was successfully found on the\r
                                   FAT volume.\r
 \r
 **/\r
@@ -577,6 +644,7 @@ FindRecoveryFile (
   //\r
   // Construct root directory file\r
   //\r
+  ZeroMem (&Parent, sizeof (PEI_FAT_FILE));\r
   Parent.IsFixedRootDir   = (BOOLEAN) ((PrivateData->Volume[VolumeIndex].FatType == Fat32) ? FALSE : TRUE);\r
   Parent.Attributes       = FAT_ATTR_DIRECTORY;\r
   Parent.CurrentPos       = 0;\r
@@ -593,6 +661,9 @@ FindRecoveryFile (
   //\r
   Status = FatReadNextDirectoryEntry (PrivateData, &Parent, File);\r
   while (Status == EFI_SUCCESS) {\r
+    //\r
+    // Compare whether the file name is recovery file name.\r
+    //\r
     if (EngStriColl (PrivateData, FileName, File->FileName)) {\r
       break;\r
     }\r
@@ -604,6 +675,13 @@ FindRecoveryFile (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  //\r
+  // Get the recovery file, set its file position to 0.\r
+  //\r
+  if (File->StartingCluster != 0) {\r
+    Status = FatSetFilePos (PrivateData, File, 0);\r
+  }\r
+\r
   *Handle = File;\r
 \r
   return EFI_SUCCESS;\r