[FREELDR] In PE loader, use cache to not load twice the start of the file

This is especially important in PXE boot, where a seek backwards requires reloading the file from start.
This commit is contained in:
Hervé Poussineau 2021-01-27 23:41:49 +01:00
parent 9d110db433
commit 5904361a54

View file

@ -781,24 +781,19 @@ PeLdrLoadImage(
TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase); TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);
/* Set to 0 position and fully load the file image */ /* Copy headers from already read data */
Position.QuadPart = 0; RtlCopyMemory(PhysicalBase, HeadersBuffer, min(NtHeaders->OptionalHeader.SizeOfHeaders, sizeof(HeadersBuffer)));
Status = ArcSeek(FileId, &Position, SeekAbsolute); /* If headers are quite big, request next bytes from file */
if (Status != ESUCCESS) if (NtHeaders->OptionalHeader.SizeOfHeaders > sizeof(HeadersBuffer))
{ {
ERR("ArcSeek(File: '%s') failed. Status: 0x%lx\n", FileName, Status); Status = ArcRead(FileId, (PUCHAR)PhysicalBase + sizeof(HeadersBuffer), NtHeaders->OptionalHeader.SizeOfHeaders - sizeof(HeadersBuffer), &BytesRead);
UiMessageBox("Error seeking the start of a file."); if (Status != ESUCCESS)
ArcClose(FileId); {
return FALSE; ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName, Status);
} UiMessageBox("Error reading headers.");
ArcClose(FileId);
Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders, &BytesRead); return FALSE;
if (Status != ESUCCESS) }
{
ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName, Status);
UiMessageBox("Error reading headers.");
ArcClose(FileId);
return FALSE;
} }
/* /*
@ -843,7 +838,7 @@ PeLdrLoadImage(
if (SizeOfRawData != 0) if (SizeOfRawData != 0)
{ {
/* Seek to the correct position */ /* Seek to the correct position */
Position.LowPart = SectionHeader->PointerToRawData; Position.QuadPart = SectionHeader->PointerToRawData;
Status = ArcSeek(FileId, &Position, SeekAbsolute); Status = ArcSeek(FileId, &Position, SeekAbsolute);
TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress); TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);