Search a handle to a device on a specified device path that supports a specified protocol,\r
interface of that protocol on that handle is another output.\r
\r
+\r
+\r
@param Protocol The protocol to search for\r
@param FilePath The specified device path\r
@param Interface Interface of the protocol on the handle\r
// figure out how big the file is.\r
//\r
FileInfo = NULL;\r
- FileInfoSize = sizeof (EFI_FILE_INFO);\r
- while (CoreGrowBuffer (&Status, (VOID **)&FileInfo, FileInfoSize)) {\r
- //\r
- // Automatically allocate buffer of the correct size and make the call\r
- //\r
- Status = FileHandle->GetInfo (\r
- FileHandle,\r
- &gEfiFileInfoGuid,\r
- &FileInfoSize,\r
- FileInfo\r
- );\r
+ FileInfoSize = 0;\r
+ Status = FileHandle->GetInfo (\r
+ FileHandle,\r
+ &gEfiFileInfoGuid,\r
+ &FileInfoSize,\r
+ FileInfo\r
+ );\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ FileInfo = AllocatePool (FileInfoSize);\r
+ if (FileInfo != NULL) {\r
+ Status = FileHandle->GetInfo (\r
+ FileHandle,\r
+ &gEfiFileInfoGuid,\r
+ &FileInfoSize,\r
+ FileInfo\r
+ );\r
+ } else {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
}\r
+ \r
if (!EFI_ERROR (Status)) {\r
//\r
// Allocate space for the file\r
// Close the file since we are done\r
//\r
FileHandle->Close (FileHandle);\r
+ CoreFreePool (FileInfo);\r
} else {\r
Status = EFI_OUT_OF_RESOURCES;\r
}\r
//\r
// Call LoadFile with the correct buffer size\r
//\r
- while (CoreGrowBuffer (&Status, (VOID **)&ImageFileHandle->Source, ImageFileHandle->SourceSize)) {\r
- Status = LoadFile->LoadFile (\r
- LoadFile,\r
- TempFilePath,\r
- BootPolicy,\r
- &ImageFileHandle->SourceSize,\r
- ImageFileHandle->Source\r
- );\r
- //\r
- // If success or other error happens, stop loop\r
- //\r
- if (Status != EFI_BUFFER_TOO_SMALL) {\r
- break;\r
+ ASSERT (ImageFileHandle->SourceSize == 0);\r
+ ASSERT (ImageFileHandle->Source == NULL);\r
+ Status = LoadFile->LoadFile (\r
+ LoadFile,\r
+ TempFilePath,\r
+ BootPolicy,\r
+ &ImageFileHandle->SourceSize,\r
+ ImageFileHandle->Source\r
+ );\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ ImageFileHandle->Source = AllocatePool (ImageFileHandle->SourceSize);\r
+ if (ImageFileHandle->Source == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ Status = LoadFile->LoadFile (\r
+ LoadFile,\r
+ TempFilePath,\r
+ BootPolicy,\r
+ &ImageFileHandle->SourceSize,\r
+ ImageFileHandle->Source\r
+ );\r
}\r
}\r
\r
- if (!EFI_ERROR (Status)) {\r
+ if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {\r
ImageFileHandle->FreeBuffer = TRUE;\r
goto Done;\r
}\r
//\r
// Nothing else to try\r
//\r
- DEBUG ((DEBUG_LOAD | DEBUG_WARN, "CoreOpenImageFile: Device did not support a known load protocol\n"));\r
+ DEBUG ((DEBUG_LOAD|DEBUG_WARN, "CoreOpenImageFile: Device did not support a known load protocol\n"));\r
Status = EFI_NOT_FOUND;\r
\r
Done:\r
-\r
//\r
// If the file was not accessed, clean up\r
//\r
- if (EFI_ERROR (Status)) {\r
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
if (ImageFileHandle->FreeBuffer) {\r
//\r
// Free the source buffer if we allocated it\r
return EFI_SUCCESS;\r
}\r
\r
-/**\r
- Helper function called as part of the code needed\r
- to allocate the proper sized buffer for various\r
- EFI interfaces.\r
-\r
- @param Status Current status\r
- @param Buffer Current allocated buffer, or NULL\r
- @param BufferSize Current buffer size needed\r
-\r
- @retval TRUE if the buffer was reallocated and the caller\r
- should try the API again.\r
- @retval FALSE buffer could not be allocated and the caller\r
- should not try the API again.\r
-\r
-**/\r
-BOOLEAN\r
-CoreGrowBuffer (\r
- IN OUT EFI_STATUS *Status,\r
- IN OUT VOID **Buffer,\r
- IN UINTN BufferSize\r
- )\r
-{\r
- BOOLEAN TryAgain;\r
-\r
- TryAgain = FALSE;\r
- //\r
- // If this is an initial request, buffer will be null with a new buffer size\r
- //\r
- if (*Buffer == NULL) {\r
- *Status = EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- if (BufferSize == 0) {\r
- return TRUE;\r
- }\r
-\r
- //\r
- // If the status code is "buffer too small", resize the buffer\r
- //\r
- if (*Status == EFI_BUFFER_TOO_SMALL) {\r
- if (*Buffer != NULL) {\r
- CoreFreePool (*Buffer);\r
- }\r
-\r
- *Buffer = AllocatePool (BufferSize);\r
- if (*Buffer != NULL) {\r
- TryAgain = TRUE;\r
- } else {\r
- *Status = EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
- //\r
- // If there's an error, free the buffer\r
- //\r
- if ((!TryAgain) && (EFI_ERROR (*Status)) && (*Buffer != NULL)) {\r
- CoreFreePool (*Buffer);\r
- *Buffer = NULL;\r
- }\r
-\r
- return TryAgain;\r
-}\r
-\r
-\r