mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-27 12:15:19 +01:00
Refactor LinuxScan, use in Custom Entries as well
This commit is contained in:
parent
1a3081dc27
commit
9926ff019e
@ -1024,6 +1024,7 @@ STATIC VOID AddDefaultMenu(IN LOADER_ENTRY *Entry)
|
|||||||
Entry->SubScreen = SubScreen;
|
Entry->SubScreen = SubScreen;
|
||||||
// DBG(" Added '%ls': OSType='%d', OSVersion='%s'\n", Entry->Title, Entry->LoaderType, Entry->OSVersion);
|
// DBG(" Added '%ls': OSType='%d', OSVersion='%s'\n", Entry->Title, Entry->LoaderType, Entry->OSVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN AddLoaderEntry(IN CONST XStringW& LoaderPath, IN CONST XStringArray& LoaderOptions,
|
BOOLEAN AddLoaderEntry(IN CONST XStringW& LoaderPath, IN CONST XStringArray& LoaderOptions,
|
||||||
IN CONST XStringW& LoaderTitle,
|
IN CONST XStringW& LoaderTitle,
|
||||||
IN REFIT_VOLUME *Volume, IN XImage *Image,
|
IN REFIT_VOLUME *Volume, IN XImage *Image,
|
||||||
@ -1078,6 +1079,256 @@ BOOLEAN AddLoaderEntry(IN CONST XStringW& LoaderPath, IN CONST XStringArray& Loa
|
|||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC VOID LinuxScan(REFIT_VOLUME *Volume, UINT8 KernelScan, UINT8 Type, XStringW *CustomPath, XImage *CustomImage)
|
||||||
|
{
|
||||||
|
// When used for Regular Entries, all found entries will be added by AddLoaderEntry()
|
||||||
|
// When used for Custom Entries (detected by CustomPath!=NULL), CustomPath+CustomImage will be set to the first entry found and execution will stop
|
||||||
|
// Scanning is adjusted according to Type: OSTYPE_LIN will scan for linux loaders, OSTYPE_LINEFI will scan for linux kernels, unspecified will scan for both
|
||||||
|
UINTN Index;
|
||||||
|
EFI_GUID *PartGUID;
|
||||||
|
|
||||||
|
// check for linux loaders
|
||||||
|
if (Type != OSTYPE_LINEFI) { // OSTYPE_LIN or unspecified
|
||||||
|
//
|
||||||
|
//----- Test common linux name and path like /EFI/ubuntu/grubx64.efi
|
||||||
|
REFIT_DIR_ITER DirIter;
|
||||||
|
EFI_FILE_INFO *DirEntry = NULL;
|
||||||
|
DirIterOpen(Volume->RootDir, L"\\EFI", &DirIter);
|
||||||
|
while (DirIterNext(&DirIter, 1, L"*", &DirEntry)) {
|
||||||
|
if (DirEntry->FileName[0] == '.') {
|
||||||
|
//DBG("Skip dot entries: %ls\n", DirEntry->FileName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XStringW File = SWPrintf("EFI\\%ls\\grubx64.efi", DirEntry->FileName);
|
||||||
|
XStringW OSName = XStringW().takeValueFrom(DirEntry->FileName); // this is folder name, for example "ubuntu"
|
||||||
|
OSName.lowerAscii(); // lowercase for icon name and title (first letter in title will be capitalized later)
|
||||||
|
if (FileExists(Volume->RootDir, File)) {
|
||||||
|
// check if nonstandard icon mapping is needed
|
||||||
|
for (Index = 0; Index < LinuxIconMappingCount; ++Index) {
|
||||||
|
if (StrCmp(OSName.wc_str(),LinuxIconMapping[Index].DirectoryName) == 0) {
|
||||||
|
OSName = XStringW().takeValueFrom(LinuxIconMapping[Index].IconName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!CustomPath) {
|
||||||
|
DBG(" found entry %ls,linux\n", OSName.wc_str());
|
||||||
|
}
|
||||||
|
XStringW LoaderTitle = OSName.subString(0,1); // capitalize first letter for title
|
||||||
|
LoaderTitle.upperAscii();
|
||||||
|
LoaderTitle += OSName.subString(1, OSName.length()) + L" Linux"_XSW;
|
||||||
|
// Very few linux icons exist in IconNames, but these few may be preloaded, so check that first
|
||||||
|
XImage ImageX = ThemeX.GetIcon(L"os_"_XSW + OSName); //will the image be destroyed or rewritten by next image after the cycle end?
|
||||||
|
if (ImageX.isEmpty()) {
|
||||||
|
// no preloaded icon, try to load from dir
|
||||||
|
ImageX.LoadXImage(ThemeX.ThemeDir, L"os_"_XSW + OSName);
|
||||||
|
}
|
||||||
|
if (CustomPath) {
|
||||||
|
*CustomPath = File;
|
||||||
|
if (CustomImage) {
|
||||||
|
*CustomImage = ImageX;
|
||||||
|
}
|
||||||
|
DirIterClose(&DirIter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AddLoaderEntry(File, NullXStringArray, LoaderTitle, Volume,
|
||||||
|
(ImageX.isEmpty() ? NULL : &ImageX), OSTYPE_LIN, OSFLAG_NODEFAULTARGS);
|
||||||
|
} //anyway continue search other entries
|
||||||
|
}
|
||||||
|
DirIterClose(&DirIter);
|
||||||
|
|
||||||
|
// check for non-standard grub path
|
||||||
|
for (Index = 0; Index < LinuxEntryDataCount; ++Index) {
|
||||||
|
if (FileExists(Volume->RootDir, LinuxEntryData[Index].Path)) {
|
||||||
|
XStringW OSIconName = XStringW().takeValueFrom(LinuxEntryData[Index].Icon);
|
||||||
|
OSIconName = OSIconName.subString(0, OSIconName.indexOf(','));
|
||||||
|
XImage ImageX = ThemeX.GetIcon(L"os_"_XSW + OSIconName);
|
||||||
|
if (ImageX.isEmpty()) {
|
||||||
|
ImageX.LoadXImage(ThemeX.ThemeDir, L"os_"_XSW + OSIconName);
|
||||||
|
}
|
||||||
|
if (CustomPath) {
|
||||||
|
*CustomPath = LinuxEntryData[Index].Path;
|
||||||
|
if (CustomImage) {
|
||||||
|
*CustomImage = ImageX;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AddLoaderEntry(LinuxEntryData[Index].Path, NullXStringArray, XStringW().takeValueFrom(LinuxEntryData[Index].Title), Volume,
|
||||||
|
(ImageX.isEmpty() ? NULL : &ImageX), OSTYPE_LIN, OSFLAG_NODEFAULTARGS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (Type != OSTYPE_LIN) { //OSTYPE_LINEFI or unspecified
|
||||||
|
// check for linux kernels
|
||||||
|
PartGUID = FindGPTPartitionGuidInDevicePath(Volume->DevicePath);
|
||||||
|
if ((PartGUID != NULL) && (Volume->RootDir != NULL)) {
|
||||||
|
REFIT_DIR_ITER Iter;
|
||||||
|
EFI_FILE_INFO *FileInfo = NULL;
|
||||||
|
EFI_TIME PreviousTime;
|
||||||
|
XStringW Path;
|
||||||
|
// CHAR16 *Options;
|
||||||
|
// Get the partition UUID and make sure it's lower case
|
||||||
|
CHAR16 PartUUID[40];
|
||||||
|
ZeroMem(&PreviousTime, sizeof(EFI_TIME));
|
||||||
|
snwprintf(PartUUID, sizeof(PartUUID), "%s", strguid(PartGUID));
|
||||||
|
StrToLower(PartUUID);
|
||||||
|
// open the /boot directory (or whatever directory path)
|
||||||
|
DirIterOpen(Volume->RootDir, LINUX_BOOT_PATH, &Iter);
|
||||||
|
|
||||||
|
// Check which kernel scan to use
|
||||||
|
|
||||||
|
// the following options can produce only a single option
|
||||||
|
switch (KernelScan) {
|
||||||
|
case KERNEL_SCAN_FIRST:
|
||||||
|
// First kernel found only
|
||||||
|
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
||||||
|
if (FileInfo != NULL) {
|
||||||
|
if (FileInfo->FileSize == 0) {
|
||||||
|
FreePool(FileInfo);
|
||||||
|
FileInfo = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// get the kernel file path
|
||||||
|
Path.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
||||||
|
// free the file info
|
||||||
|
FreePool(FileInfo);
|
||||||
|
FileInfo = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KERNEL_SCAN_LAST:
|
||||||
|
// Last kernel found only
|
||||||
|
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
||||||
|
if (FileInfo != NULL) {
|
||||||
|
if (FileInfo->FileSize > 0) {
|
||||||
|
// get the kernel file path
|
||||||
|
Path.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
||||||
|
}
|
||||||
|
// free the file info
|
||||||
|
FreePool(FileInfo);
|
||||||
|
FileInfo = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KERNEL_SCAN_NEWEST:
|
||||||
|
// Newest dated kernel only
|
||||||
|
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
||||||
|
if (FileInfo != NULL) {
|
||||||
|
if (FileInfo->FileSize > 0) {
|
||||||
|
// get the kernel file path
|
||||||
|
if ((PreviousTime.Year == 0) || (TimeCmp(&PreviousTime, &(FileInfo->ModificationTime)) < 0)) {
|
||||||
|
Path.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
||||||
|
PreviousTime = FileInfo->ModificationTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// free the file info
|
||||||
|
FreePool(FileInfo);
|
||||||
|
FileInfo = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KERNEL_SCAN_OLDEST:
|
||||||
|
// Oldest dated kernel only
|
||||||
|
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
||||||
|
if (FileInfo != NULL) {
|
||||||
|
if (FileInfo->FileSize > 0) {
|
||||||
|
// get the kernel file path
|
||||||
|
if ((PreviousTime.Year == 0) || (TimeCmp(&PreviousTime, &(FileInfo->ModificationTime)) > 0)) {
|
||||||
|
Path.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
||||||
|
PreviousTime = FileInfo->ModificationTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// free the file info
|
||||||
|
FreePool(FileInfo);
|
||||||
|
FileInfo = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KERNEL_SCAN_MOSTRECENT:
|
||||||
|
// most recent kernel version only
|
||||||
|
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
||||||
|
if (FileInfo != NULL) {
|
||||||
|
if (FileInfo->FileSize > 0) {
|
||||||
|
// get the kernel file path
|
||||||
|
XStringW NewPath = SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
||||||
|
if ( Path < NewPath ) {
|
||||||
|
Path = NewPath;
|
||||||
|
} else {
|
||||||
|
Path.setEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// free the file info
|
||||||
|
FreePool(FileInfo);
|
||||||
|
FileInfo = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KERNEL_SCAN_EARLIEST:
|
||||||
|
// earliest kernel version only
|
||||||
|
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
||||||
|
if (FileInfo != NULL) {
|
||||||
|
if (FileInfo->FileSize > 0) {
|
||||||
|
// get the kernel file path
|
||||||
|
XStringW NewPath = SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
||||||
|
if ( Path > NewPath ) {
|
||||||
|
Path = NewPath;
|
||||||
|
} else {
|
||||||
|
Path.setEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// free the file info
|
||||||
|
FreePool(FileInfo);
|
||||||
|
FileInfo = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KERNEL_SCAN_NONE:
|
||||||
|
default:
|
||||||
|
// No kernel scan
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the produced entry
|
||||||
|
if (Path.notEmpty()) {
|
||||||
|
if (CustomPath) {
|
||||||
|
*CustomPath = Path;
|
||||||
|
DirIterClose(&Iter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
XStringArray Options = LinuxKernelOptions(Iter.DirHandle, Basename(Path.wc_str()) + LINUX_LOADER_PATH.length(), PartUUID, NullXStringArray);
|
||||||
|
// Add the entry
|
||||||
|
AddLoaderEntry(Path, (Options.isEmpty()) ? LINUX_DEFAULT_OPTIONS : Options, L""_XSW, Volume, NULL, OSTYPE_LINEFI, OSFLAG_NODEFAULTARGS);
|
||||||
|
Path.setEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// the following produces multiple entries
|
||||||
|
// custom entries has a different implementation, and does not use this code
|
||||||
|
if (!CustomPath && KernelScan == KERNEL_SCAN_ALL) {
|
||||||
|
// get all the filename matches
|
||||||
|
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
||||||
|
if (FileInfo != NULL) {
|
||||||
|
if (FileInfo->FileSize > 0) {
|
||||||
|
// get the kernel file path
|
||||||
|
Path.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
||||||
|
XStringArray Options = LinuxKernelOptions(Iter.DirHandle, Basename(Path.wc_str()) + LINUX_LOADER_PATH.length(), PartUUID, NullXStringArray);
|
||||||
|
// Add the entry
|
||||||
|
AddLoaderEntry(Path, (Options.isEmpty()) ? LINUX_DEFAULT_OPTIONS : Options, L""_XSW, Volume, NULL, OSTYPE_LINEFI, OSFLAG_NODEFAULTARGS);
|
||||||
|
Path.setEmpty();
|
||||||
|
}
|
||||||
|
// free the file info
|
||||||
|
FreePool(FileInfo);
|
||||||
|
FileInfo = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//close the directory
|
||||||
|
DirIterClose(&Iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//constants
|
//constants
|
||||||
//const XStringW APFSFVBootPath = L"\\00000000-0000-0000-0000-000000000000\\System\\Library\\CoreServices\\boot.efi"_XSW;
|
//const XStringW APFSFVBootPath = L"\\00000000-0000-0000-0000-000000000000\\System\\Library\\CoreServices\\boot.efi"_XSW;
|
||||||
//const XStringW APFSRecBootPath = L"\\00000000-0000-0000-0000-000000000000\\boot.efi"_XSW;
|
//const XStringW APFSRecBootPath = L"\\00000000-0000-0000-0000-000000000000\\boot.efi"_XSW;
|
||||||
@ -1122,9 +1373,8 @@ VOID AddPRSEntry(REFIT_VOLUME *Volume)
|
|||||||
|
|
||||||
VOID ScanLoader(VOID)
|
VOID ScanLoader(VOID)
|
||||||
{
|
{
|
||||||
UINTN VolumeIndex, Index;
|
UINTN VolumeIndex;
|
||||||
REFIT_VOLUME *Volume;
|
REFIT_VOLUME *Volume;
|
||||||
EFI_GUID *PartGUID;
|
|
||||||
|
|
||||||
//DBG("Scanning loaders...\n");
|
//DBG("Scanning loaders...\n");
|
||||||
DbgHeader("ScanLoader");
|
DbgHeader("ScanLoader");
|
||||||
@ -1260,10 +1510,11 @@ VOID ScanLoader(VOID)
|
|||||||
if (!AddLoaderEntry(L"\\EFI\\MICROSOFT\\BOOT\\cdboot.efi"_XSW, NullXStringArray, L"Microsoft EFI cdboot"_XSW, Volume, NULL, OSTYPE_WINEFI, 0)) {
|
if (!AddLoaderEntry(L"\\EFI\\MICROSOFT\\BOOT\\cdboot.efi"_XSW, NullXStringArray, L"Microsoft EFI cdboot"_XSW, Volume, NULL, OSTYPE_WINEFI, 0)) {
|
||||||
AddLoaderEntry(L"\\EFI\\MICROSOF\\BOOT\\CDBOOT.EFI"_XSW, NullXStringArray, L"Microsoft EFI CDBOOT"_XSW, Volume, NULL, OSTYPE_WINEFI, 0);
|
AddLoaderEntry(L"\\EFI\\MICROSOF\\BOOT\\CDBOOT.EFI"_XSW, NullXStringArray, L"Microsoft EFI CDBOOT"_XSW, Volume, NULL, OSTYPE_WINEFI, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ANDX86)
|
#if defined(ANDX86)
|
||||||
if (TRUE) { //gSettings.AndroidScan
|
if (TRUE) { //gSettings.AndroidScan
|
||||||
// check for Android loaders
|
// check for Android loaders
|
||||||
for (Index = 0; Index < AndroidEntryDataCount; ++Index) {
|
for (UINTN Index = 0; Index < AndroidEntryDataCount; ++Index) {
|
||||||
UINTN aIndex, aFound;
|
UINTN aIndex, aFound;
|
||||||
if (FileExists(Volume->RootDir, AndroidEntryData[Index].Path)) {
|
if (FileExists(Volume->RootDir, AndroidEntryData[Index].Path)) {
|
||||||
aFound = 0;
|
aFound = 0;
|
||||||
@ -1283,245 +1534,9 @@ VOID ScanLoader(VOID)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gSettings.LinuxScan) {
|
if (gSettings.LinuxScan) {
|
||||||
// check for linux loaders
|
LinuxScan(Volume, gSettings.KernelScan, 0, NULL, NULL);
|
||||||
//
|
|
||||||
//----- Test common linux name and path like /EFI/ubuntu/grubx64.efi
|
|
||||||
REFIT_DIR_ITER DirIter;
|
|
||||||
EFI_FILE_INFO *DirEntry = NULL;
|
|
||||||
DirIterOpen(Volume->RootDir, L"\\EFI", &DirIter);
|
|
||||||
while (DirIterNext(&DirIter, 1, L"*", &DirEntry)) {
|
|
||||||
if (DirEntry->FileName[0] == '.') {
|
|
||||||
//DBG("Skip dot entries: %ls\n", DirEntry->FileName);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
XStringW File = SWPrintf("EFI\\%ls\\grubx64.efi", DirEntry->FileName);
|
|
||||||
XStringW OSName = XStringW().takeValueFrom(DirEntry->FileName); // this is folder name, for example "ubuntu"
|
|
||||||
OSName.lowerAscii(); // lowercase for icon name and title (first letter in title will be capitalized later)
|
|
||||||
if (FileExists(Volume->RootDir, File)) {
|
|
||||||
// check if nonstandard icon mapping is needed
|
|
||||||
for (Index = 0; Index < LinuxIconMappingCount; ++Index) {
|
|
||||||
if (StrCmp(OSName.wc_str(),LinuxIconMapping[Index].DirectoryName) == 0) {
|
|
||||||
OSName = XStringW().takeValueFrom(LinuxIconMapping[Index].IconName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DBG(" found entry %ls,linux\n", OSName.wc_str());
|
|
||||||
XStringW LoaderTitle = OSName.subString(0,1); // capitalize first letter for title
|
|
||||||
LoaderTitle.upperAscii();
|
|
||||||
LoaderTitle += OSName.subString(1, OSName.length()) + L" Linux"_XSW;
|
|
||||||
// Very few linux icons exist in IconNames, but these few may be preloaded, so check that first
|
|
||||||
XImage ImageX = ThemeX.GetIcon(L"os_"_XSW + OSName); //will the image be destroyed or rewritten by next image after the cycle end?
|
|
||||||
if (ImageX.isEmpty()) {
|
|
||||||
// no preloaded icon, try to load from dir
|
|
||||||
ImageX.LoadXImage(ThemeX.ThemeDir, L"os_"_XSW + OSName);
|
|
||||||
}
|
|
||||||
AddLoaderEntry(File, NullXStringArray, LoaderTitle, Volume,
|
|
||||||
(ImageX.isEmpty() ? NULL : &ImageX), OSTYPE_LINEFI, OSFLAG_NODEFAULTARGS);
|
|
||||||
} //anyway continue search other entries
|
|
||||||
}
|
|
||||||
DirIterClose(&DirIter);
|
|
||||||
|
|
||||||
// check for non-standard grub path
|
|
||||||
for (Index = 0; Index < LinuxEntryDataCount; ++Index) {
|
|
||||||
if (FileExists(Volume->RootDir, LinuxEntryData[Index].Path)) {
|
|
||||||
XStringW OSIconName = XStringW().takeValueFrom(LinuxEntryData[Index].Icon);
|
|
||||||
OSIconName = OSIconName.subString(0, OSIconName.indexOf(','));
|
|
||||||
XImage ImageX = ThemeX.GetIcon(L"os_"_XSW + OSIconName);
|
|
||||||
if (ImageX.isEmpty()) {
|
|
||||||
ImageX.LoadXImage(ThemeX.ThemeDir, L"os_"_XSW + OSIconName);
|
|
||||||
}
|
|
||||||
AddLoaderEntry(LinuxEntryData[Index].Path, NullXStringArray, XStringW().takeValueFrom(LinuxEntryData[Index].Title), Volume,
|
|
||||||
(ImageX.isEmpty() ? NULL : &ImageX), OSTYPE_LINEFI, OSFLAG_NODEFAULTARGS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check for linux kernels
|
|
||||||
PartGUID = FindGPTPartitionGuidInDevicePath(Volume->DevicePath);
|
|
||||||
if ((PartGUID != NULL) && (Volume->RootDir != NULL)) {
|
|
||||||
REFIT_DIR_ITER Iter;
|
|
||||||
EFI_FILE_INFO *FileInfo = NULL;
|
|
||||||
EFI_TIME PreviousTime;
|
|
||||||
XStringW Path;
|
|
||||||
// CHAR16 *Options;
|
|
||||||
// Get the partition UUID and make sure it's lower case
|
|
||||||
CHAR16 PartUUID[40];
|
|
||||||
ZeroMem(&PreviousTime, sizeof(EFI_TIME));
|
|
||||||
snwprintf(PartUUID, sizeof(PartUUID), "%s", strguid(PartGUID));
|
|
||||||
StrToLower(PartUUID);
|
|
||||||
// open the /boot directory (or whatever directory path)
|
|
||||||
DirIterOpen(Volume->RootDir, LINUX_BOOT_PATH, &Iter);
|
|
||||||
// Check which kernel scan to use
|
|
||||||
switch (gSettings.KernelScan) {
|
|
||||||
case KERNEL_SCAN_FIRST:
|
|
||||||
// First kernel found only
|
|
||||||
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize == 0) {
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// get the kernel file path
|
|
||||||
Path.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
XStringArray Options = LinuxKernelOptions(Iter.DirHandle, Basename(Path.wc_str()) + LINUX_LOADER_PATH.length(), PartUUID, NullXStringArray);
|
|
||||||
// Add the entry
|
|
||||||
AddLoaderEntry(Path, (Options.isEmpty()) ? LINUX_DEFAULT_OPTIONS : Options, L""_XSW, Volume, NULL, OSTYPE_LINEFI, OSFLAG_NODEFAULTARGS);
|
|
||||||
Path.setEmpty();
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_LAST:
|
|
||||||
// Last kernel found only
|
|
||||||
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize > 0) {
|
|
||||||
// get the kernel file path
|
|
||||||
Path.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
}
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Path.notEmpty()) {
|
|
||||||
XStringArray Options = LinuxKernelOptions(Iter.DirHandle, Basename(Path.wc_str()) + LINUX_LOADER_PATH.length(), PartUUID, NullXStringArray);
|
|
||||||
// Add the entry
|
|
||||||
AddLoaderEntry(Path, (Options.isEmpty()) ? LINUX_DEFAULT_OPTIONS : Options, L""_XSW, Volume, NULL, OSTYPE_LINEFI, OSFLAG_NODEFAULTARGS);
|
|
||||||
Path.setEmpty();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_NEWEST:
|
|
||||||
// Newest dated kernel only
|
|
||||||
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize > 0) {
|
|
||||||
// get the kernel file path
|
|
||||||
if ((PreviousTime.Year == 0) || (TimeCmp(&PreviousTime, &(FileInfo->ModificationTime)) < 0)) {
|
|
||||||
Path.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
PreviousTime = FileInfo->ModificationTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Path.notEmpty()) {
|
|
||||||
XStringArray Options = LinuxKernelOptions(Iter.DirHandle, Basename(Path.wc_str()) + LINUX_LOADER_PATH.length(), PartUUID, NullXStringArray);
|
|
||||||
// Add the entry
|
|
||||||
AddLoaderEntry(Path, (Options.isEmpty()) ? LINUX_DEFAULT_OPTIONS : Options, L""_XSW, Volume, NULL, OSTYPE_LINEFI, OSFLAG_NODEFAULTARGS);
|
|
||||||
Path.setEmpty();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_OLDEST:
|
|
||||||
// Oldest dated kernel only
|
|
||||||
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize > 0) {
|
|
||||||
// get the kernel file path
|
|
||||||
if ((PreviousTime.Year == 0) || (TimeCmp(&PreviousTime, &(FileInfo->ModificationTime)) > 0)) {
|
|
||||||
Path.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
PreviousTime = FileInfo->ModificationTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Path.notEmpty()) {
|
|
||||||
XStringArray Options = LinuxKernelOptions(Iter.DirHandle, Basename(Path.wc_str()) + LINUX_LOADER_PATH.length(), PartUUID, NullXStringArray);
|
|
||||||
// Add the entry
|
|
||||||
AddLoaderEntry(Path, (Options.isEmpty()) ? LINUX_DEFAULT_OPTIONS : Options, L""_XSW, Volume, NULL, OSTYPE_LINEFI, OSFLAG_NODEFAULTARGS);
|
|
||||||
Path.setEmpty();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_MOSTRECENT:
|
|
||||||
// most recent kernel version only
|
|
||||||
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize > 0) {
|
|
||||||
// get the kernel file path
|
|
||||||
XStringW NewPath = SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
if ( Path < NewPath ) {
|
|
||||||
Path = NewPath;
|
|
||||||
}else{
|
|
||||||
Path.setEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Path.notEmpty()) {
|
|
||||||
XStringArray Options = LinuxKernelOptions(Iter.DirHandle, Basename(Path.wc_str()) + LINUX_LOADER_PATH.length(), PartUUID, NullXStringArray);
|
|
||||||
// Add the entry
|
|
||||||
AddLoaderEntry(Path, (Options.isEmpty()) ? LINUX_DEFAULT_OPTIONS : Options, L""_XSW, Volume, NULL, OSTYPE_LINEFI, OSFLAG_NODEFAULTARGS);
|
|
||||||
Path.setEmpty();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_EARLIEST:
|
|
||||||
// earliest kernel version only
|
|
||||||
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize > 0) {
|
|
||||||
// get the kernel file path
|
|
||||||
XStringW NewPath = SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
if ( Path > NewPath ) {
|
|
||||||
Path = NewPath;
|
|
||||||
}else{
|
|
||||||
Path.setEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Path.notEmpty()) {
|
|
||||||
XStringArray Options = LinuxKernelOptions(Iter.DirHandle, Basename(Path.wc_str()) + LINUX_LOADER_PATH.length(), PartUUID, NullXStringArray);
|
|
||||||
AddLoaderEntry(Path, (Options.isEmpty()) ? LINUX_DEFAULT_OPTIONS : Options, L""_XSW, Volume, NULL, OSTYPE_LINEFI, OSFLAG_NODEFAULTARGS);
|
|
||||||
Path.setEmpty();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_ALL:
|
|
||||||
// get all the filename matches
|
|
||||||
while (DirIterNext(&Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize > 0) {
|
|
||||||
// get the kernel file path
|
|
||||||
Path.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
XStringArray Options = LinuxKernelOptions(Iter.DirHandle, Basename(Path.wc_str()) + LINUX_LOADER_PATH.length(), PartUUID, NullXStringArray);
|
|
||||||
// Add the entry
|
|
||||||
AddLoaderEntry(Path, (Options.isEmpty()) ? LINUX_DEFAULT_OPTIONS : Options, L""_XSW, Volume, NULL, OSTYPE_LINEFI, OSFLAG_NODEFAULTARGS);
|
|
||||||
Path.setEmpty();
|
|
||||||
}
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_NONE:
|
|
||||||
default:
|
|
||||||
// No kernel scan
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//close the directory
|
|
||||||
DirIterClose(&Iter);
|
|
||||||
}
|
|
||||||
} //if linux scan
|
|
||||||
// DBG("search for optical UEFI\n");
|
// DBG("search for optical UEFI\n");
|
||||||
if (Volume->DiskKind == DISK_KIND_OPTICAL) {
|
if (Volume->DiskKind == DISK_KIND_OPTICAL) {
|
||||||
AddLoaderEntry(BOOT_LOADER_PATH, NullXStringArray, L"UEFI optical"_XSW, Volume, NULL, OSTYPE_OTHER, 0);
|
AddLoaderEntry(BOOT_LOADER_PATH, NullXStringArray, L"UEFI optical"_XSW, Volume, NULL, OSTYPE_OTHER, 0);
|
||||||
@ -1555,7 +1570,7 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FindCustomPath && (Custom->Type != OSTYPE_LINEFI)) {
|
if (FindCustomPath && (Custom->Type != OSTYPE_LINEFI) && (Custom->Type != OSTYPE_LIN)) {
|
||||||
// DBG("Custom %lsentry %llu skipped because it didn't have a ", IsSubEntry ? L"sub " : L"", CustomIndex);
|
// DBG("Custom %lsentry %llu skipped because it didn't have a ", IsSubEntry ? L"sub " : L"", CustomIndex);
|
||||||
// if (Custom->Type == 0) {
|
// if (Custom->Type == 0) {
|
||||||
// DBG("Type.\n");
|
// DBG("Type.\n");
|
||||||
@ -1569,10 +1584,12 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
// DBG("Custom %lsentry %llu skipped because it is disabled.\n", IsSubEntry ? L"sub " : L"", CustomIndex);
|
// DBG("Custom %lsentry %llu skipped because it is disabled.\n", IsSubEntry ? L"sub " : L"", CustomIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gSettings.ShowHiddenEntries && OSFLAG_ISSET(Custom->Flags, OSFLAG_HIDDEN)) {
|
if (!gSettings.ShowHiddenEntries && OSFLAG_ISSET(Custom->Flags, OSFLAG_HIDDEN)) {
|
||||||
// DBG("Custom %lsentry %llu skipped because it is hidden.\n", IsSubEntry ? L"sub " : L"", CustomIndex);
|
// DBG("Custom %lsentry %llu skipped because it is hidden.\n", IsSubEntry ? L"sub " : L"", CustomIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 //if someone want to debug this
|
#if 0 //if someone want to debug this
|
||||||
DBG("Custom %lsentry %llu ", IsSubEntry ? L"sub " : L"", CustomIndex);
|
DBG("Custom %lsentry %llu ", IsSubEntry ? L"sub " : L"", CustomIndex);
|
||||||
// if (Custom->Title) {
|
// if (Custom->Title) {
|
||||||
@ -1598,8 +1615,8 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
for (VolumeIndex = 0; VolumeIndex < Volumes.size(); ++VolumeIndex) {
|
for (VolumeIndex = 0; VolumeIndex < Volumes.size(); ++VolumeIndex) {
|
||||||
CUSTOM_LOADER_ENTRY *CustomSubEntry;
|
CUSTOM_LOADER_ENTRY *CustomSubEntry;
|
||||||
LOADER_ENTRY *Entry = NULL;
|
LOADER_ENTRY *Entry = NULL;
|
||||||
XImage Image; // = new XImage;
|
XImage Image = Custom->Image;
|
||||||
XImage DriveImage;
|
XImage DriveImage = Custom->DriveImage;
|
||||||
|
|
||||||
EFI_GUID *Guid = NULL;
|
EFI_GUID *Guid = NULL;
|
||||||
UINT64 VolumeSize;
|
UINT64 VolumeSize;
|
||||||
@ -1618,26 +1635,18 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
/* if ((Volume->DiskKind == DISK_KIND_OPTICAL && (GlobalConfig.DisableFlags & VOLTYPE_OPTICAL)) ||
|
/* if ((Volume->DiskKind == DISK_KIND_OPTICAL && (GlobalConfig.DisableFlags & VOLTYPE_OPTICAL)) ||
|
||||||
(Volume->DiskKind == DISK_KIND_EXTERNAL && (GlobalConfig.DisableFlags & VOLTYPE_EXTERNAL)) ||
|
(Volume->DiskKind == DISK_KIND_EXTERNAL && (GlobalConfig.DisableFlags & VOLTYPE_EXTERNAL)) ||
|
||||||
(Volume->DiskKind == DISK_KIND_INTERNAL && (GlobalConfig.DisableFlags & VOLTYPE_INTERNAL)) ||
|
(Volume->DiskKind == DISK_KIND_INTERNAL && (GlobalConfig.DisableFlags & VOLTYPE_INTERNAL)) ||
|
||||||
(Volume->DiskKind == DISK_KIND_FIREWIRE && (GlobalConfig.DisableFlags & VOLTYPE_FIREWIRE)))
|
(Volume->DiskKind == DISK_KIND_FIREWIRE && (GlobalConfig.DisableFlags & VOLTYPE_FIREWIRE))) {
|
||||||
{
|
|
||||||
DBG("skipped because media is disabled\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
if (((1ull<<Volume->DiskKind) & GlobalConfig.DisableFlags) != 0) {
|
if (((1ull<<Volume->DiskKind) & GlobalConfig.DisableFlags) != 0) {
|
||||||
DBG("skipped because media is disabled\n");
|
DBG("skipped because media is disabled\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if (Custom->VolumeType != 0) {
|
/* if ((Custom->VolumeType != 0) &&
|
||||||
if ((Volume->DiskKind == DISK_KIND_OPTICAL && ((Custom->VolumeType & VOLTYPE_OPTICAL) == 0)) ||
|
((Volume->DiskKind == DISK_KIND_OPTICAL && ((Custom->VolumeType & VOLTYPE_OPTICAL ) == 0)) ||
|
||||||
(Volume->DiskKind == DISK_KIND_EXTERNAL && ((Custom->VolumeType & VOLTYPE_EXTERNAL) == 0)) ||
|
(Volume->DiskKind == DISK_KIND_EXTERNAL && ((Custom->VolumeType & VOLTYPE_EXTERNAL) == 0)) ||
|
||||||
(Volume->DiskKind == DISK_KIND_INTERNAL && ((Custom->VolumeType & VOLTYPE_INTERNAL) == 0)) ||
|
(Volume->DiskKind == DISK_KIND_INTERNAL && ((Custom->VolumeType & VOLTYPE_INTERNAL) == 0)) ||
|
||||||
(Volume->DiskKind == DISK_KIND_FIREWIRE && ((Custom->VolumeType & VOLTYPE_FIREWIRE) == 0))) {
|
(Volume->DiskKind == DISK_KIND_FIREWIRE && ((Custom->VolumeType & VOLTYPE_FIREWIRE) == 0)))) {
|
||||||
DBG("skipped because media is ignored\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
if (Custom->VolumeType != 0 && ((1<<Volume->DiskKind) & Custom->VolumeType) == 0) {
|
if (Custom->VolumeType != 0 && ((1<<Volume->DiskKind) & Custom->VolumeType) == 0) {
|
||||||
DBG("skipped because media is ignored\n");
|
DBG("skipped because media is ignored\n");
|
||||||
@ -1649,12 +1658,11 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for exact volume matches
|
// Check for exact volume matches (devicepath / volumelabel)
|
||||||
if (Custom->Volume) {
|
if (Custom->Volume) {
|
||||||
|
|
||||||
if ((StrStr(Volume->DevicePathString, Custom->Volume) == NULL) &&
|
if ((StrStr(Volume->DevicePathString, Custom->Volume) == NULL) &&
|
||||||
((Volume->VolName == NULL) || (StrStr(Volume->VolName, Custom->Volume) == NULL))) {
|
((Volume->VolName == NULL) || (StrStr(Volume->VolName, Custom->Volume) == NULL))) {
|
||||||
DBG("skipped\n");
|
DBG("skipped because volume does not match\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// NOTE: Sothor - We dont care about legacy OS type // Check if the volume should be of certain os type
|
// NOTE: Sothor - We dont care about legacy OS type // Check if the volume should be of certain os type
|
||||||
@ -1666,22 +1674,22 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
//DBG("skipped because wrong type (%d != %d)\n", OSType, Volume->OSType);
|
//DBG("skipped because wrong type (%d != %d)\n", OSType, Volume->OSType);
|
||||||
//continue;
|
//continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the volume is readable and the entry exists on the volume
|
// Check the volume is readable and the entry exists on the volume
|
||||||
if (Volume->RootDir == NULL) {
|
if (Volume->RootDir == NULL) {
|
||||||
DBG("skipped because filesystem is not readable\n");
|
DBG("skipped because filesystem is not readable\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (StriCmp(CustomPath, MACOSX_LOADER_PATH) == 0 && FileExists(Volume->RootDir, L"\\.IAPhysicalMedia")) {
|
if (StriCmp(CustomPath, MACOSX_LOADER_PATH) == 0 && FileExists(Volume->RootDir, L"\\.IAPhysicalMedia")) {
|
||||||
DBG("skipped standard macOS path because volume is 2nd stage Install Media\n");
|
DBG("skipped standard macOS path because volume is 2nd stage Install Media\n");
|
||||||
continue;
|
continue;
|
||||||
} */
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
Guid = FindGPTPartitionGuidInDevicePath(Volume->DevicePath);
|
Guid = FindGPTPartitionGuidInDevicePath(Volume->DevicePath);
|
||||||
// Open the boot directory to search for kernels
|
|
||||||
if (FindCustomPath) {
|
if (FindCustomPath) {
|
||||||
EFI_FILE_INFO *FileInfo = NULL;
|
|
||||||
EFI_TIME PreviousTime;
|
|
||||||
ZeroMem(&PreviousTime, sizeof(EFI_TIME));
|
|
||||||
// Get the partition UUID and make sure it's lower case
|
// Get the partition UUID and make sure it's lower case
|
||||||
if (Guid == NULL) {
|
if (Guid == NULL) {
|
||||||
DBG("skipped because volume does not have partition uuid\n");
|
DBG("skipped because volume does not have partition uuid\n");
|
||||||
@ -1689,125 +1697,14 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
}
|
}
|
||||||
snwprintf(PartUUID, sizeof(PartUUID), "%s", strguid(Guid));
|
snwprintf(PartUUID, sizeof(PartUUID), "%s", strguid(Guid));
|
||||||
StrToLower(PartUUID);
|
StrToLower(PartUUID);
|
||||||
// open the /boot directory (or whatever directory path)
|
|
||||||
|
// search for standard/nonstandard linux uefi paths, and all kernel scan options that != KERNEL_SCAN_ALL
|
||||||
|
if (Custom->Type == OSTYPE_LIN || Custom->KernelScan != KERNEL_SCAN_ALL) {
|
||||||
|
LinuxScan(Volume, Custom->KernelScan, Custom->Type, &CustomPath, &Image);
|
||||||
|
}
|
||||||
|
if (Custom->Type == OSTYPE_LINEFI) {
|
||||||
|
// Open the boot directory to determine linux loadoptions when found item, or kernels when KERNEL_SCAN_ALL
|
||||||
DirIterOpen(Volume->RootDir, LINUX_BOOT_PATH, Iter);
|
DirIterOpen(Volume->RootDir, LINUX_BOOT_PATH, Iter);
|
||||||
// Check if user wants to find newest kernel only
|
|
||||||
switch (Custom->KernelScan) {
|
|
||||||
case KERNEL_SCAN_FIRST:
|
|
||||||
// First kernel found only
|
|
||||||
while (DirIterNext(Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize == 0) {
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// get the kernel file path
|
|
||||||
CustomPath.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_LAST:
|
|
||||||
// Last kernel found only
|
|
||||||
while (DirIterNext(Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize > 0) {
|
|
||||||
// get the kernel file path
|
|
||||||
CustomPath.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
}
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_NEWEST:
|
|
||||||
// Newest dated kernel only
|
|
||||||
while (DirIterNext(Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize > 0) {
|
|
||||||
// get the kernel file path
|
|
||||||
if ((PreviousTime.Year == 0) || (TimeCmp(&PreviousTime, &(FileInfo->ModificationTime)) < 0)) {
|
|
||||||
CustomPath.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
PreviousTime = FileInfo->ModificationTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_OLDEST:
|
|
||||||
// Oldest dated kernel only
|
|
||||||
while (DirIterNext(Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize > 0) {
|
|
||||||
// get the kernel file path
|
|
||||||
if ((PreviousTime.Year == 0) || (TimeCmp(&PreviousTime, &(FileInfo->ModificationTime)) > 0)) {
|
|
||||||
CustomPath.SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
PreviousTime = FileInfo->ModificationTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_MOSTRECENT:
|
|
||||||
// most recent kernel version only
|
|
||||||
while (DirIterNext(Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize > 0) {
|
|
||||||
// get the kernel file path
|
|
||||||
XStringW NewPath = SWPrintf("%ls\\%ls", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
if ( CustomPath > NewPath ) {
|
|
||||||
CustomPath = NewPath;
|
|
||||||
}else{
|
|
||||||
CustomPath.setEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KERNEL_SCAN_EARLIEST:
|
|
||||||
// earliest kernel version only
|
|
||||||
while (DirIterNext(Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo)) {
|
|
||||||
if (FileInfo != NULL) {
|
|
||||||
if (FileInfo->FileSize > 0) {
|
|
||||||
// get the kernel file path
|
|
||||||
// CHAR16 *NewPath = PoolPrint(L"%s\\%s", LINUX_BOOT_PATH, FileInfo->FileName);
|
|
||||||
XStringW NewPath = SWPrintf("%ls\\%ls", LINUX_BOOT_PATH"\\", FileInfo->FileName);
|
|
||||||
if ( CustomPath < NewPath ) {
|
|
||||||
CustomPath = NewPath;
|
|
||||||
}else{
|
|
||||||
CustomPath.setEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// free the file info
|
|
||||||
FreePool(FileInfo);
|
|
||||||
FileInfo = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Set scan to all just in case
|
|
||||||
Custom->KernelScan = KERNEL_SCAN_ALL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else if (!FileExists(Volume->RootDir, CustomPath)) {
|
} else if (!FileExists(Volume->RootDir, CustomPath)) {
|
||||||
DBG("skipped because path does not exist\n");
|
DBG("skipped because path does not exist\n");
|
||||||
@ -1815,7 +1712,6 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Change to custom image if needed
|
// Change to custom image if needed
|
||||||
Image = Custom->Image;
|
|
||||||
if (Image.isEmpty() && Custom->ImagePath) {
|
if (Image.isEmpty() && Custom->ImagePath) {
|
||||||
Image.LoadXImage(ThemeX.ThemeDir, Custom->ImagePath);
|
Image.LoadXImage(ThemeX.ThemeDir, Custom->ImagePath);
|
||||||
if (Image.isEmpty()) {
|
if (Image.isEmpty()) {
|
||||||
@ -1833,7 +1729,6 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Change to custom drive image if needed
|
// Change to custom drive image if needed
|
||||||
DriveImage = Custom->DriveImage;
|
|
||||||
if (DriveImage.isEmpty() && Custom->DriveImagePath) {
|
if (DriveImage.isEmpty() && Custom->DriveImagePath) {
|
||||||
DriveImage.LoadXImage(ThemeX.ThemeDir, Custom->DriveImagePath);
|
DriveImage.LoadXImage(ThemeX.ThemeDir, Custom->DriveImagePath);
|
||||||
if (DriveImage.isEmpty()) {
|
if (DriveImage.isEmpty()) {
|
||||||
@ -1847,11 +1742,11 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do { // when not scanning for kernels, this loop will execute only once
|
||||||
{
|
|
||||||
// Search for linux kernels
|
|
||||||
XStringArray CustomOptions = Custom->LoadOptions;
|
XStringArray CustomOptions = Custom->LoadOptions;
|
||||||
if (FindCustomPath && (Custom->KernelScan == KERNEL_SCAN_ALL)) {
|
|
||||||
|
// for LINEFI with option KERNEL_SCAN_ALL, use this loop to search for kernels
|
||||||
|
if (FindCustomPath && Custom->Type == OSTYPE_LINEFI && Custom->KernelScan == KERNEL_SCAN_ALL) {
|
||||||
EFI_FILE_INFO *FileInfo = NULL;
|
EFI_FILE_INFO *FileInfo = NULL;
|
||||||
// Get the next kernel path or stop looking
|
// Get the next kernel path or stop looking
|
||||||
if (!DirIterNext(Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo) || (FileInfo == NULL)) {
|
if (!DirIterNext(Iter, 2, LINUX_LOADER_SEARCH_PATH, &FileInfo) || (FileInfo == NULL)) {
|
||||||
@ -1872,11 +1767,13 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
DBG("skipped\n");
|
DBG("skipped\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Check to make sure we should update custom options or not
|
|
||||||
if (FindCustomPath && OSFLAG_ISUNSET(Custom->Flags, OSFLAG_NODEFAULTARGS)) {
|
// Check to make sure if we should update linux custom options or not
|
||||||
|
if (FindCustomPath && Custom->Type == OSTYPE_LINEFI && OSFLAG_ISUNSET(Custom->Flags, OSFLAG_NODEFAULTARGS)) {
|
||||||
// Find the init ram image and select root
|
// Find the init ram image and select root
|
||||||
CustomOptions = LinuxKernelOptions(Iter->DirHandle, Basename(CustomPath.wc_str()) + LINUX_LOADER_PATH.length(), PartUUID, Custom->LoadOptions);
|
CustomOptions = LinuxKernelOptions(Iter->DirHandle, Basename(CustomPath.wc_str()) + LINUX_LOADER_PATH.length(), PartUUID, Custom->LoadOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to make sure that this entry is not hidden or disabled by another custom entry
|
// Check to make sure that this entry is not hidden or disabled by another custom entry
|
||||||
if (!IsSubEntry) {
|
if (!IsSubEntry) {
|
||||||
CUSTOM_LOADER_ENTRY *Ptr;
|
CUSTOM_LOADER_ENTRY *Ptr;
|
||||||
@ -2008,16 +1905,15 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG("match!\n");
|
DBG("match!\n");
|
||||||
// Create an entry for this volume
|
// Create an entry for this volume
|
||||||
Entry = CreateLoaderEntry(CustomPath, CustomOptions, Custom->FullTitle, Custom->Title, Volume,
|
Entry = CreateLoaderEntry(CustomPath, CustomOptions, Custom->FullTitle, Custom->Title, Volume,
|
||||||
(Image.isEmpty() ? NULL : &Image), (DriveImage.isEmpty() ? NULL : &DriveImage),
|
(Image.isEmpty() ? NULL : &Image), (DriveImage.isEmpty() ? NULL : &DriveImage),
|
||||||
Custom->Type, Custom->Flags, Custom->Hotkey, Custom->BootBgColor, Custom->CustomBoot, &Custom->CustomLogo,
|
Custom->Type, Custom->Flags, Custom->Hotkey, Custom->BootBgColor, Custom->CustomBoot, &Custom->CustomLogo,
|
||||||
/*(KERNEL_AND_KEXT_PATCHES *)(((UINTN)Custom) + OFFSET_OF(CUSTOM_LOADER_ENTRY, KernelAndKextPatches))*/ NULL, TRUE);
|
/*(KERNEL_AND_KEXT_PATCHES *)(((UINTN)Custom) + OFFSET_OF(CUSTOM_LOADER_ENTRY, KernelAndKextPatches))*/ NULL, TRUE);
|
||||||
|
|
||||||
if (Entry != NULL) {
|
if (Entry != NULL) {
|
||||||
DBG("Custom settings: %ls.plist will %s be applied\n",
|
DBG("Custom settings: %ls.plist will %s be applied\n", Custom->Settings, Custom->CommonSettings?"not":"");
|
||||||
Custom->Settings, Custom->CommonSettings?"not":"");
|
|
||||||
if (!Custom->CommonSettings) {
|
if (!Custom->CommonSettings) {
|
||||||
Entry->Settings = Custom->Settings;
|
Entry->Settings = Custom->Settings;
|
||||||
}
|
}
|
||||||
@ -2056,12 +1952,12 @@ STATIC VOID AddCustomEntry(IN UINTN CustomIndex,
|
|||||||
else
|
else
|
||||||
MainMenu.AddMenuEntry(Entry, true);
|
MainMenu.AddMenuEntry(Entry, true);
|
||||||
}
|
}
|
||||||
} while (FindCustomPath && (Custom->KernelScan == KERNEL_SCAN_ALL));
|
} while (FindCustomPath && Custom->Type == OSTYPE_LINEFI && Custom->KernelScan == KERNEL_SCAN_ALL); // repeat loop only for kernel scanning
|
||||||
|
|
||||||
// Close the kernel boot directory
|
// Close the kernel boot directory
|
||||||
if (FindCustomPath) {
|
if (FindCustomPath && Custom->Type == OSTYPE_LINEFI) {
|
||||||
DirIterClose(Iter);
|
DirIterClose(Iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2093,17 +1989,12 @@ VOID AddCustomEntries(VOID)
|
|||||||
} else if (OSTYPE_IS_WINDOWS(Custom->Type)) {
|
} else if (OSTYPE_IS_WINDOWS(Custom->Type)) {
|
||||||
AddCustomEntry(i, L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"_XSW, Custom, NULL);
|
AddCustomEntry(i, L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"_XSW, Custom, NULL);
|
||||||
} else if (OSTYPE_IS_LINUX(Custom->Type)) {
|
} else if (OSTYPE_IS_LINUX(Custom->Type)) {
|
||||||
UINTN Index;
|
|
||||||
#if defined(ANDX86)
|
#if defined(ANDX86)
|
||||||
Index = 0;
|
for (UINTN Index = 0; Index < AndroidEntryDataCount; Index++) {
|
||||||
while (Index < AndroidEntryDataCount) {
|
|
||||||
AddCustomEntry(i, AndroidEntryData[Index++].Path, Custom, NULL);
|
AddCustomEntry(i, AndroidEntryData[Index++].Path, Custom, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Index = 0;
|
AddCustomEntry(i, NullXStringW, Custom, NULL);
|
||||||
while (Index < LinuxEntryDataCount) {
|
|
||||||
AddCustomEntry(i, LinuxEntryData[Index++].Path, Custom, NULL);
|
|
||||||
}
|
|
||||||
} else if (Custom->Type == OSTYPE_LINEFI) {
|
} else if (Custom->Type == OSTYPE_LINEFI) {
|
||||||
AddCustomEntry(i, NullXStringW, Custom, NULL);
|
AddCustomEntry(i, NullXStringW, Custom, NULL);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user