BOOLEAN InfOpenFile( PHINF InfHandle, PCSTR FileName, PULONG ErrorLine) { FILEINFORMATION Information; ULONG FileId; PCHAR FileBuffer; ULONG FileSize, Count; PINFCACHE Cache; BOOLEAN Success; LONG ret; *InfHandle = NULL; *ErrorLine = (ULONG) - 1; // // Open the .inf file // FileId = FsOpenFile(FileName); if (!FileId) { return FALSE; } // // Query file size // ret = ArcGetFileInformation(FileId, &Information); if ((ret != ESUCCESS) || (Information.EndingAddress.HighPart != 0)) { ArcClose(FileId); return FALSE; } FileSize = Information.EndingAddress.LowPart; // // Allocate buffer to cache the file // FileBuffer = MmHeapAlloc(FileSize + 1); if (!FileBuffer) { ArcClose(FileId); return FALSE; } // // Read file into memory // ret = ArcRead(FileId, FileBuffer, FileSize, &Count); if ((ret != ESUCCESS) || (Count != FileSize)) { ArcClose(FileId); MmHeapFree(FileBuffer); return FALSE; } // // We don't need the file anymore. Close it // ArcClose(FileId); // // Append string terminator // FileBuffer[FileSize] = 0; // // Allocate infcache header // Cache = (PINFCACHE)MmHeapAlloc(sizeof(INFCACHE)); if (!Cache) { MmHeapFree(FileBuffer); return FALSE; } // // Initialize inicache header // RtlZeroMemory(Cache, sizeof(INFCACHE)); // // Parse the inf buffer // Success = InfpParseBuffer(Cache, FileBuffer, FileBuffer + FileSize, ErrorLine); if (!Success) { MmHeapFree(Cache); Cache = NULL; } // // Free file buffer, as it has been parsed // MmHeapFree(FileBuffer); // // Return .inf parsed contents // *InfHandle = (HINF)Cache; return Success; }
extern "C" bool LoadPE(char* filename, char* address, SPEFile* outPEFile) { void* fp = FsOpenFile(filename, 0); outPEFile->dosHeader = (SPEDOSHeader*)address; FsReadFile(fp, (char*)outPEFile->dosHeader, sizeof(SPEDOSHeader)); if (outPEFile->dosHeader->Magic != DOS_HEADER_MAGIC) { CDisplayDriver::PrintString("DOS_HEADER_MAGIC is wrong!"); FsCloseFile(fp); return false; } int dumpsize = outPEFile->dosHeader->HeaderAddress - sizeof(SPEDOSHeader); char* dump = new char[dumpsize]; FsReadFile(fp, dump, dumpsize); delete[] dump; outPEFile->peHeader = (SPEHeader*)(address + outPEFile->dosHeader->HeaderAddress); FsReadFile(fp, (char*)outPEFile->peHeader, sizeof(SPEHeader)); if (outPEFile->peHeader->Magic != PE_HEADER_MAGIC) { CDisplayDriver::PrintString("PE_HEADER_MAGIC is wrong!"); FsCloseFile(fp); return false; } outPEFile->peoHeader = (SPEOptionalHeader*)((char*)outPEFile->peHeader + sizeof(SPEHeader)); FsReadFile(fp, (char*)outPEFile->peoHeader, sizeof(SPEOptionalHeader)); CDisplayDriver::PrintString("%X", outPEFile->peoHeader->SizeOfImage); if (outPEFile->peoHeader->Magic != PE_OPTIONAL_MAGIC_64) { CDisplayDriver::PrintString("PE_OPTIONAL_MAGIC_64 is wrong!"); FsCloseFile(fp); return false; } outPEFile->dataDirectories = (SPEDataDirectories*)((char*)outPEFile->peoHeader + sizeof(SPEOptionalHeader)); FsReadFile(fp, (char*)outPEFile->dataDirectories, sizeof(SPEDataDirectories)); outPEFile->sections = new SPESection*[outPEFile->peHeader->NumberOfSections]; for (unsigned int i = 0; i < outPEFile->peHeader->NumberOfSections; ++i) { SFile* handle = (SFile*)fp; outPEFile->sections[i] = (SPESection*)((char*)outPEFile->dataDirectories + sizeof(SPEDataDirectories) + (i*sizeof(SPESection))); FsReadFile(fp, (char*)outPEFile->sections[i], sizeof(SPESection)); } for (unsigned int i = 0; i < outPEFile->peHeader->NumberOfSections; ++i) { if (outPEFile->sections[i]->SizeOfRawData == 0) { continue; } int dumpsize = outPEFile->sections[i]->PointerToRawData - ((SFile*)fp)->bytesread; char* dump = new char[dumpsize]; FsReadFile(fp, dump, dumpsize); delete[] dump; FsReadFile(fp, (char*)address + outPEFile->sections[i]->VirtualAddress, outPEFile->sections[i]->SizeOfRawData); } outPEFile->exportDirectoryTable = (SPEExportDirectoryTable*)((char*)address + outPEFile->dataDirectories->ExportTable.VirtualAddress); outPEFile->importDirectoryTable = (SPEImportDirectoryTable*)((char*)address + outPEFile->dataDirectories->ImportTable.VirtualAddress); if (*(unsigned long long*)outPEFile->importDirectoryTable) { SPEImportLookupTable* start = (SPEImportLookupTable*)(address + outPEFile->importDirectoryTable->ImportLookupTableRVA); int count = 0; while (*(unsigned long long*)start) { start++; count++; } start = (SPEImportLookupTable*)(address + outPEFile->importDirectoryTable->ImportLookupTableRVA); outPEFile->importLookups = new SPEImportLookupTable*[count]; int i = 0; while (*(unsigned long long*)start) { bool isOrdinal = start->LookupEntry & 0x8000000000000000; if (isOrdinal) { } else { unsigned long long HintNameRVA = start->LookupEntry & ~0x8000000000000000; SPEImportHintNameTable* HintNameTable = (SPEImportHintNameTable*)(address + HintNameRVA); //CDisplayDriver::PrintString("%s", &HintNameTable->Name); count++; } outPEFile->importLookups[i]->LookupEntry = *(unsigned long long*)start; start++; i++; } unsigned long long* startAddr = (unsigned long long*)(address + outPEFile->importDirectoryTable->ImportAddressTableRVA); while (*startAddr) { *startAddr += 0x20000; startAddr++; } } FsCloseFile(fp); return true; }
VOID LoadAndBootBootSector(IN OperatingSystemItem* OperatingSystem, IN USHORT OperatingSystemVersion) { ULONG_PTR SectionId; PCSTR SectionName = OperatingSystem->SystemPartition; CHAR FileName[260]; PFILE FilePointer; ULONG BytesRead; CHAR SettingName[80]; // Find all the message box settings and run them UiShowMessageBoxesInSection(SectionName); // Try to open the operating system section in the .ini file if (!IniOpenSection(SectionName, &SectionId)) { sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", SectionName); UiMessageBox(SettingName); return; } if (!IniReadSettingByName(SectionId, "BootSectorFile", FileName, sizeof(FileName))) { UiMessageBox("Boot sector file not specified for selected OS!"); return; } FilePointer = FsOpenFile(FileName); if (!FilePointer) { strcat(FileName, " not found."); UiMessageBox(FileName); return; } // Read boot sector if (!FsReadFile(FilePointer, 512, &BytesRead, (void*)0x7c00) || (BytesRead != 512)) { UiMessageBox("Unable to read boot sector."); return; } // Check for validity if (*((USHORT*)(0x7c00 + 0x1fe)) != 0xaa55) { UiMessageBox("Invalid boot sector magic (0xaa55)"); return; } UiUnInitialize("Booting..."); // Don't stop the floppy drive motor when we // are just booting a bootsector, or drive, or partition. // If we were to stop the floppy motor then // the BIOS wouldn't be informed and if the // next read is to a floppy then the BIOS will // still think the motor is on and this will // result in a read error. //DiskStopFloppyMotor(); //DisableA20(); ChainLoadBiosBootSectorCode(); }